| @@ -70,8 +70,10 @@ liblolcore_sources = \ | |||||
| commandstack.h \ | commandstack.h \ | ||||
| easymesh/easymeshbuild.cpp easymesh/easymeshbuild.h \ | easymesh/easymeshbuild.cpp easymesh/easymeshbuild.h \ | ||||
| easymesh/easymeshrender.cpp easymesh/easymeshrender.h \ | easymesh/easymeshrender.cpp easymesh/easymeshrender.h \ | ||||
| easymesh/easymesh.cpp easymesh/easymeshprimitive.cpp \ | |||||
| easymesh/easymeshtransform.cpp easymesh/easymesh.h \ | |||||
| easymesh/easymesh.cpp \ | |||||
| easymesh/easymeshinternal.cpp easymesh/easymeshcsg.cpp \ | |||||
| easymesh/easymeshprimitive.cpp easymesh/easymeshtransform.cpp \ | |||||
| easymesh/easymeshcursor.cpp easymesh/easymesh.h \ | |||||
| easymesh/csgbsp.cpp easymesh/csgbsp.h \ | easymesh/csgbsp.cpp easymesh/csgbsp.h \ | ||||
| easymesh/shiny.lolfx easymesh/shinyflat.lolfx \ | easymesh/shiny.lolfx easymesh/shinyflat.lolfx \ | ||||
| easymesh/shinydebugwireframe.lolfx \ | easymesh/shinydebugwireframe.lolfx \ | ||||
| @@ -94,20 +94,20 @@ private: | |||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
| //Mesh CSG operations | //Mesh CSG operations | ||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
| private: | |||||
| void MeshCsg(CSGUsage csg_operation); | |||||
| public: | public: | ||||
| /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */ | /* [cmd:csgu] Performs a Union operation as (mesh0_Outside + mesh1_Outside) */ | ||||
| void CsgUnion() { MeshCsg(CSGUsage::Union); } | |||||
| void CsgUnion(); | |||||
| /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */ | /* [cmd:csgs] Performs a Substract operation as (mesh0_Outside + mesh1_Inside-inverted) */ | ||||
| void CsgSub() { MeshCsg(CSGUsage::Substract); } | |||||
| void CsgSub(); | |||||
| /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */ | /* [cmd:csgsl] Performs a Substract operation without keeping the mesh1 part */ | ||||
| void CsgSubL() { MeshCsg(CSGUsage::SubstractLoss); } | |||||
| void CsgSubL(); | |||||
| /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */ | /* [cmd:csga] Performs an And operation as (mesh0_Inside + mesh1_Inside) */ | ||||
| void CsgAnd() { MeshCsg(CSGUsage::And); } | |||||
| void CsgAnd(); | |||||
| /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */ | /* [cmd:csgx] Performs a Xor operation as (m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted) */ | ||||
| void CsgXor() { MeshCsg(CSGUsage::Xor); } | |||||
| void CsgXor(); | |||||
| private: | |||||
| void MeshCsg(CSGUsage csg_operation); | |||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
| //Mesh Cursor operations | //Mesh Cursor operations | ||||
| @@ -127,7 +127,7 @@ public: | |||||
| void ToggleQuadWeighting(); | void ToggleQuadWeighting(); | ||||
| /* [cmd:tpbn] When active, normal will be computed after the build */ | /* [cmd:tpbn] When active, normal will be computed after the build */ | ||||
| void TogglePostBuildNormal(); | void TogglePostBuildNormal(); | ||||
| /* [cmd:tpbn] When active, normal will be computed after the build */ | |||||
| /* [cmd:tpbn] When active, prevents vertices cleanup */ | |||||
| void ToggleVerticeNoCleanup(); | void ToggleVerticeNoCleanup(); | ||||
| /* [cmd:sc] Set both color */ | /* [cmd:sc] Set both color */ | ||||
| void SetCurColor(vec4 const &color); | void SetCurColor(vec4 const &color); | ||||
| @@ -142,16 +142,14 @@ public: | |||||
| //Internal : Basic triangle/vertex operations | //Internal : Basic triangle/vertex operations | ||||
| //------------------------------------------------------------------------- | //------------------------------------------------------------------------- | ||||
| private: | private: | ||||
| void InternalAddVertex(vec3 const &coord); | |||||
| void AddDuplicateVertex(int i); | |||||
| void AddVertex(vec3 const &coord); | |||||
| void AddDupVertex(int i); | |||||
| void AddLerpVertex(int i, int j, float alpha); | void AddLerpVertex(int i, int j, float alpha); | ||||
| void AddLerpVertex(VertexData const &vi, VertexData const &vj, float alpha); | void AddLerpVertex(VertexData const &vi, VertexData const &vj, float alpha); | ||||
| VertexData GetLerpVertex(int i, int j, float alpha); | VertexData GetLerpVertex(int i, int j, float alpha); | ||||
| VertexData GetLerpVertex(VertexData const &vi, VertexData const &vj, float alpha); | VertexData GetLerpVertex(VertexData const &vi, VertexData const &vj, float alpha); | ||||
| void InternalAddQuad(int i1, int i2, int i3, int i4, int base); | |||||
| void InternalAddQuadDupVerts(int i1, int i2, int i3, int i4, int base); | |||||
| void InternalAddTriangle(int i1, int i2, int i3, int base); | |||||
| void InternalAddTriangleDupVerts(int i1, int i2, int i3, int base); | |||||
| void AddQuad(int i1, int i2, int i3, int i4, int base, bool duplicate = false); | |||||
| void AddTriangle(int i1, int i2, int i3, int base, bool duplicate = false); | |||||
| void ComputeNormals(int start, int vcount); | void ComputeNormals(int start, int vcount); | ||||
| public: | public: | ||||
| /* Remove all unused */ | /* Remove all unused */ | ||||
| @@ -0,0 +1,221 @@ | |||||
| // | |||||
| // Lol Engine | |||||
| // | |||||
| // Copyright: (c) 2010-2015 Sam Hocevar <sam@hocevar.net> | |||||
| // (c) 2009-2015 Cédric Lecacheur <jordx@free.fr> | |||||
| // (c) 2009-2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| // | |||||
| // The EasyMesh class | |||||
| // ------------------ | |||||
| // | |||||
| #include <lol/engine-internal.h> | |||||
| namespace lol | |||||
| { | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::CsgUnion() { MeshCsg(CSGUsage::Union); } | |||||
| void EasyMesh::CsgSub() { MeshCsg(CSGUsage::Substract); } | |||||
| void EasyMesh::CsgSubL() { MeshCsg(CSGUsage::SubstractLoss); } | |||||
| void EasyMesh::CsgAnd() { MeshCsg(CSGUsage::And); } | |||||
| void EasyMesh::CsgXor() { MeshCsg(CSGUsage::Xor); } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::MeshCsg(CSGUsage csg_operation) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::MeshCsg); | |||||
| BD()->CmdStack() << csg_operation; | |||||
| return; | |||||
| } | |||||
| //A vertex dictionnary for vertices on the same spot. | |||||
| array< int, int > vertex_dict; | |||||
| //This list keeps track of the triangle that will need deletion at the end. | |||||
| array< int > triangle_to_kill; | |||||
| //Listing for each triangle of the vectors intersecting it. <tri_Id, <Point0, Point1, tri_isec_Normal>> | |||||
| array< int, array< vec3, vec3, vec3 > > triangle_isec; | |||||
| //keep a track of the intersection point on the triangle. <pos, side_id> | |||||
| array< vec3, int > triangle_vertex; | |||||
| for (int k = 0; k < 10; k++) | |||||
| triangle_vertex.Push(vec3(.0f), 0); | |||||
| //bsp infos | |||||
| CsgBsp mesh_bsp_0; | |||||
| CsgBsp mesh_bsp_1; | |||||
| if (m_cursors.Count() == 0) | |||||
| return; | |||||
| //BSP BUILD : We use the brace logic, csg should be used as : "[ exp .... [exp .... csg]]" | |||||
| int cursor_start = (m_cursors.Count() < 2)?(0):(m_cursors[(m_cursors.Count() - 2)].m2); | |||||
| for (int mesh_id = 0; mesh_id < 2; mesh_id++) | |||||
| { | |||||
| ptrdiff_t start_point = (mesh_id == 0) ? (cursor_start) : (m_cursors.Last().m2); | |||||
| ptrdiff_t end_point = (mesh_id == 0) ? (m_cursors.Last().m2) : (m_indices.Count()); | |||||
| CsgBsp &mesh_bsp = (mesh_id == 0) ? (mesh_bsp_0) : (mesh_bsp_1); | |||||
| for (ptrdiff_t i = start_point; i < end_point; i += 3) | |||||
| mesh_bsp.AddTriangleToTree((int)i, m_vert[m_indices[i]].m_coord, | |||||
| m_vert[m_indices[i + 1]].m_coord, | |||||
| m_vert[m_indices[i + 2]].m_coord); | |||||
| } | |||||
| //BSP Usage : let's crunch all triangles on the correct BSP | |||||
| ptrdiff_t indices_count = m_indices.Count(); | |||||
| for (ptrdiff_t mesh_id = 0; mesh_id < 2; mesh_id++) | |||||
| { | |||||
| ptrdiff_t start_point = (mesh_id == 0) ? (cursor_start) : (m_cursors.Last().m2); | |||||
| ptrdiff_t end_point = (mesh_id == 0) ? (m_cursors.Last().m2) : (indices_count); | |||||
| CsgBsp &mesh_bsp = (mesh_id == 0) ? (mesh_bsp_1) : (mesh_bsp_0); | |||||
| array< vec3, int, int, float > vert_list; | |||||
| array< int, int, int, int > tri_list; | |||||
| vec3 n0(.0f); vec3 n1(.0f); | |||||
| vec4 c0(.0f); vec4 c1(.0f); | |||||
| //Reserve some memory | |||||
| vert_list.Reserve(3); | |||||
| tri_list.Reserve(3); | |||||
| for (ptrdiff_t i = start_point; i < end_point; i += 3) | |||||
| { | |||||
| int Result = mesh_bsp.TestTriangleToTree(m_vert[m_indices[i]].m_coord, | |||||
| m_vert[m_indices[i + 1]].m_coord, | |||||
| m_vert[m_indices[i + 2]].m_coord, vert_list, tri_list); | |||||
| ptrdiff_t tri_base_idx = m_indices.Count(); | |||||
| //one split has been done, we need to had the new vertices & the new triangles. | |||||
| if (Result == 1) | |||||
| { | |||||
| triangle_to_kill.Push((int)i); | |||||
| #if 1 | |||||
| ptrdiff_t base_idx = m_vert.Count(); | |||||
| for (ptrdiff_t k = 3; k < vert_list.Count(); k++) | |||||
| { | |||||
| ptrdiff_t P0 = (vert_list[k].m2 < 3) ? (m_indices[i + vert_list[k].m2]) : (base_idx + vert_list[k].m2 - 3); | |||||
| ptrdiff_t P1 = (vert_list[k].m3 < 3) ? (m_indices[i + vert_list[k].m3]) : (base_idx + vert_list[k].m3 - 3); | |||||
| AddVertex(vert_list[k].m1); | |||||
| //Normal : bad calculations there. | |||||
| n0 = m_vert[P0].m_normal; | |||||
| n1 = m_vert[P1].m_normal; | |||||
| SetCurVertNormal(normalize(n0 + (n1 - n0) * vert_list[k].m4)); | |||||
| #if 1 | |||||
| //Color | |||||
| c0 = m_vert[P0].m_color; | |||||
| c1 = m_vert[P1].m_color; | |||||
| vec4 res = c0 + ((c1 - c0) * vert_list[k].m4); | |||||
| SetCurVertColor(res); | |||||
| #else | |||||
| if (mesh_id == 0) | |||||
| SetCurVertColor(vec4(1.0f, .0f, .0f, 1.0f)); | |||||
| else | |||||
| SetCurVertColor(vec4(.0f, 1.0f, 1.0f, 1.0f)); | |||||
| #endif | |||||
| } | |||||
| for (ptrdiff_t k = 0; k < tri_list.Count(); k++) | |||||
| { | |||||
| int P0 = (int)(tri_list[k].m2 < 3) ? (m_indices[i + tri_list[k].m2]) : ((int)base_idx + (tri_list[k].m2 - 3)); | |||||
| int P1 = (int)(tri_list[k].m3 < 3) ? (m_indices[i + tri_list[k].m3]) : ((int)base_idx + (tri_list[k].m3 - 3)); | |||||
| int P2 = (int)(tri_list[k].m4 < 3) ? (m_indices[i + tri_list[k].m4]) : ((int)base_idx + (tri_list[k].m4 - 3)); | |||||
| AddTriangle(P0, P1, P2, 0); | |||||
| } | |||||
| #endif | |||||
| } | |||||
| #if 1 | |||||
| //Main case | |||||
| if (Result >= 0) | |||||
| { | |||||
| for (int k = 0; k < tri_list.Count(); k++) | |||||
| { | |||||
| ptrdiff_t tri_idx = (ptrdiff_t)((tri_list.Count() == 1) ? (i) : ((int)tri_base_idx + k * 3)); | |||||
| //Triangle Kill Test | |||||
| if (//csgu : CSGUnion() -> m0_Outside + m1_Outside | |||||
| (csg_operation == CSGUsage::Union && tri_list[k].m1 == LEAF_BACK) || | |||||
| //csgs : CsgSub() -> m0_Outside + m1_Inside-inverted | |||||
| (csg_operation == CSGUsage::Substract && | |||||
| ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || | |||||
| (mesh_id == 1 && tri_list[k].m1 == LEAF_FRONT))) || | |||||
| //csgs : CsgSubL() -> m0_Outside | |||||
| (csg_operation == CSGUsage::SubstractLoss && | |||||
| ((mesh_id == 0 && tri_list[k].m1 == LEAF_BACK) || mesh_id == 1)) || | |||||
| //csga : CSGAnd() -> m0_Inside + m1_Inside | |||||
| (csg_operation == CSGUsage::And && tri_list[k].m1 == LEAF_FRONT)) | |||||
| { | |||||
| triangle_to_kill.Push((int)tri_idx); | |||||
| } | |||||
| //Triangle Invert Test | |||||
| if (//csgs : CsgSub() -> m0_Outside + m1_Inside-inverted | |||||
| (csg_operation == CSGUsage::Substract && mesh_id == 1 && tri_list[k].m1 == LEAF_BACK) || | |||||
| //csgx : CSGXor() -> m0_Outside/m0_Inside-inverted + m1_Outside/m1_Inside-inverted | |||||
| (csg_operation == CSGUsage::Xor && tri_list[k].m1 == LEAF_BACK)) | |||||
| { | |||||
| //a Xor means we will share vertices with the outside, so duplicate the vertices. | |||||
| //TODO : This operation disconnect all triangle, in some cases, not a good thing. | |||||
| if (csg_operation == CSGUsage::Xor) | |||||
| { | |||||
| for (ptrdiff_t l = 0; l < 3; l++) | |||||
| { | |||||
| AddDupVertex(m_indices[tri_idx + l]); | |||||
| m_indices[tri_idx + l] = (uint16_t)m_vert.Count() - 1; | |||||
| } | |||||
| } | |||||
| m_indices[tri_idx + 1] += m_indices[tri_idx + 2]; | |||||
| m_indices[tri_idx + 2] = m_indices[tri_idx + 1] - m_indices[tri_idx + 2]; | |||||
| m_indices[tri_idx + 1] = m_indices[tri_idx + 1] - m_indices[tri_idx + 2]; | |||||
| ComputeNormals((int)tri_idx, 3); | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| vert_list.Empty(); | |||||
| tri_list.Empty(); | |||||
| } | |||||
| } | |||||
| for (int i = 0; i < m_vert.Count(); i++) | |||||
| if (length(m_vert[i].m_normal) < 1.0f) | |||||
| i = i; | |||||
| int dir = 1; | |||||
| for (int i = 0; i >= 0 && i < triangle_to_kill.Count() - 1; i += dir) | |||||
| { | |||||
| if (triangle_to_kill[i] < triangle_to_kill[i + 1] && dir < 0) | |||||
| dir = 1; | |||||
| if (triangle_to_kill[i] == triangle_to_kill[i + 1]) | |||||
| { | |||||
| triangle_to_kill.Remove(i); | |||||
| dir = -1; | |||||
| } | |||||
| if (triangle_to_kill[i] > triangle_to_kill[i + 1]) | |||||
| { | |||||
| triangle_to_kill[i] += triangle_to_kill[i + 1]; | |||||
| triangle_to_kill[i + 1] = triangle_to_kill[i] - triangle_to_kill[i + 1]; | |||||
| triangle_to_kill[i] = triangle_to_kill[i] - triangle_to_kill[i + 1]; | |||||
| dir = -1; | |||||
| } | |||||
| if (i == 0 && dir == -1) | |||||
| dir = 1; | |||||
| } | |||||
| for (ptrdiff_t i = triangle_to_kill.Count() - 1; i >= 0; i--) | |||||
| m_indices.Remove(triangle_to_kill[i], 3); | |||||
| m_cursors.Last().m1 = (int)m_vert.Count(); | |||||
| m_cursors.Last().m2 = (int)m_indices.Count(); | |||||
| VerticesCleanup(); | |||||
| //DONE for the splitting ! | |||||
| } | |||||
| } /* namespace lol */ | |||||
| @@ -0,0 +1,183 @@ | |||||
| // | |||||
| // Lol Engine | |||||
| // | |||||
| // Copyright: (c) 2010-2015 Sam Hocevar <sam@hocevar.net> | |||||
| // (c) 2009-2015 Cédric Lecacheur <jordx@free.fr> | |||||
| // (c) 2009-2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| // | |||||
| // The EasyMesh class | |||||
| // ------------------ | |||||
| // | |||||
| #include <lol/engine-internal.h> | |||||
| namespace lol | |||||
| { | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::LoopStart(int loopnb) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::LoopStart); | |||||
| BD()->CmdStack() << loopnb; | |||||
| return; | |||||
| } | |||||
| //Loop is only available when executing a command recording | |||||
| else if (BD()->IsEnabled(MeshBuildOperation::CommandExecution)) | |||||
| { | |||||
| //Only register if we're not the current loop command | |||||
| if (!BD()->LoopStack().Count() || BD()->LoopStack().Last().m1 != BD()->Cmdi()) | |||||
| BD()->LoopStack().Push(BD()->Cmdi(), loopnb); | |||||
| } | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::LoopEnd() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::LoopEnd); | |||||
| return; | |||||
| } | |||||
| //Loop is only available when executing a command recording | |||||
| else if (BD()->IsEnabled(MeshBuildOperation::CommandExecution)) | |||||
| { | |||||
| //Only register if we're not the current loop command | |||||
| if (BD()->LoopStack().Count()) | |||||
| { | |||||
| BD()->LoopStack().Last().m2--; | |||||
| if (BD()->LoopStack().Last().m2 > 0) | |||||
| BD()->Cmdi() = BD()->LoopStack().Last().m1 - 1; | |||||
| else | |||||
| BD()->LoopStack().Pop(); | |||||
| } | |||||
| } | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::OpenBrace() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::OpenBrace); | |||||
| return; | |||||
| } | |||||
| m_cursors.Push((int)m_vert.Count(), (int)m_indices.Count()); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::CloseBrace() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::CloseBrace); | |||||
| return; | |||||
| } | |||||
| m_cursors.Pop(); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::ToggleScaleWinding() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::ScaleWinding); | |||||
| return; | |||||
| } | |||||
| BD()->Toggle(MeshBuildOperation::ScaleWinding); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::ToggleQuadWeighting() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::QuadWeighting); | |||||
| return; | |||||
| } | |||||
| BD()->Toggle(MeshBuildOperation::QuadWeighting); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::TogglePostBuildNormal() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::PostBuildNormal); | |||||
| return; | |||||
| } | |||||
| BD()->Toggle(MeshBuildOperation::PostBuildComputeNormals); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::ToggleVerticeNoCleanup() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::PreventVertCleanup); | |||||
| return; | |||||
| } | |||||
| BD()->Toggle(MeshBuildOperation::PreventVertCleanup); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurColor(vec4 const &color) | |||||
| { | |||||
| SetCurColorA(color); | |||||
| SetCurColorB(color); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurColorA(vec4 const &color) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::SetColorA); | |||||
| BD()->CmdStack() << color; | |||||
| return; | |||||
| } | |||||
| BD()->ColorA() = color; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurColorB(vec4 const &color) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::SetColorB); | |||||
| BD()->CmdStack() << color; | |||||
| return; | |||||
| } | |||||
| BD()->ColorB() = color; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetVertColor(vec4 const &color) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::SetVertColor); | |||||
| BD()->CmdStack() << color; | |||||
| return; | |||||
| } | |||||
| for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) | |||||
| m_vert[i].m_color = color; | |||||
| } | |||||
| } /* namespace lol */ | |||||
| @@ -0,0 +1,505 @@ | |||||
| // | |||||
| // Lol Engine | |||||
| // | |||||
| // Copyright: (c) 2010-2015 Sam Hocevar <sam@hocevar.net> | |||||
| // (c) 2009-2015 Cédric Lecacheur <jordx@free.fr> | |||||
| // (c) 2009-2015 Benjamin "Touky" Huet <huet.benjamin@gmail.com> | |||||
| // This program is free software; you can redistribute it and/or | |||||
| // modify it under the terms of the Do What The Fuck You Want To | |||||
| // Public License, Version 2, as published by Sam Hocevar. See | |||||
| // http://www.wtfpl.net/ for more details. | |||||
| // | |||||
| // | |||||
| // The EasyMesh class | |||||
| // ------------------ | |||||
| // | |||||
| #include <lol/engine-internal.h> | |||||
| namespace lol | |||||
| { | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::AddVertex(vec3 const &coord) | |||||
| { | |||||
| m_vert.Push(VertexData(coord, vec3(0.f, 1.f, 0.f), BD()->ColorA())); | |||||
| m_state = MeshRender::NeedConvert; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::AddDupVertex(int i) | |||||
| { | |||||
| m_vert << m_vert[i]; | |||||
| m_state = MeshRender::NeedConvert; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::AddLerpVertex(int i, int j, float alpha) { AddLerpVertex(m_vert[i], m_vert[j], alpha); } | |||||
| void EasyMesh::AddLerpVertex(VertexData const &vi, VertexData const &vj, float alpha) | |||||
| { | |||||
| m_vert.Push(GetLerpVertex(vi, vj, alpha)); | |||||
| m_state = MeshRender::NeedConvert; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| VertexData EasyMesh::GetLerpVertex(int i, int j, float alpha) { return GetLerpVertex(m_vert[i], m_vert[j], alpha); } | |||||
| VertexData EasyMesh::GetLerpVertex(VertexData const &vi, VertexData const &vj, float alpha) | |||||
| { | |||||
| return VertexData( | |||||
| lol::lerp(vi.m_coord, vj.m_coord, alpha), | |||||
| lol::lerp(vi.m_normal, vj.m_normal, alpha), | |||||
| lol::lerp(vi.m_color, vj.m_color, alpha), | |||||
| lol::lerp(vi.m_texcoord, vj.m_texcoord, alpha), | |||||
| ((alpha < .5f) ? (vi.m_bone_id) : (vj.m_bone_id)), /* FIXME ? */ | |||||
| lol::lerp(vi.m_bone_weight, vj.m_bone_weight, alpha)); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::AddQuad(int i1, int i2, int i3, int i4, int base, bool duplicate) | |||||
| { | |||||
| if (duplicate) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::QuadWeighting) && | |||||
| !BD()->IsEnabled(MeshBuildOperation::IgnoreQuadWeighting)) | |||||
| { | |||||
| int i5 = (int)m_vert.Count(); | |||||
| AddLerpVertex(GetLerpVertex(base + i1, base + i3, .5f), | |||||
| GetLerpVertex(base + i2, base + i4, .5f), .5f); | |||||
| m_indices << i1 + base; | |||||
| m_indices << i2 + base; | |||||
| m_indices << i5; | |||||
| m_indices << i2 + base; | |||||
| m_indices << i3 + base; | |||||
| m_indices << i5; | |||||
| m_indices << i4 + base; | |||||
| m_indices << i1 + base; | |||||
| m_indices << i5; | |||||
| m_indices << i5; | |||||
| m_indices << i3 + base; | |||||
| m_indices << i4 + base; | |||||
| } | |||||
| else | |||||
| { | |||||
| m_indices << i1 + base; | |||||
| m_indices << i2 + base; | |||||
| m_indices << i3 + base; | |||||
| m_indices << i4 + base; | |||||
| m_indices << i1 + base; | |||||
| m_indices << i3 + base; | |||||
| } | |||||
| } | |||||
| else | |||||
| { | |||||
| int vbase = (int)m_vert.Count(); | |||||
| AddDupVertex(base + i1); | |||||
| AddDupVertex(base + i2); | |||||
| AddDupVertex(base + i3); | |||||
| AddDupVertex(base + i4); | |||||
| AddQuad(0, 1, 2, 3, vbase); | |||||
| } | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::AddTriangle(int i1, int i2, int i3, int base, bool duplicate) | |||||
| { | |||||
| if (duplicate) | |||||
| { | |||||
| m_indices << base + i1; | |||||
| m_indices << base + i2; | |||||
| m_indices << base + i3; | |||||
| } | |||||
| else | |||||
| { | |||||
| m_indices << (uint16_t)m_vert.Count(); AddDupVertex(base + i1); | |||||
| m_indices << (uint16_t)m_vert.Count(); AddDupVertex(base + i2); | |||||
| m_indices << (uint16_t)m_vert.Count(); AddDupVertex(base + i3); | |||||
| } | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::ComputeNormals(int start, int vcount) | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandExecution) && | |||||
| BD()->IsEnabled(MeshBuildOperation::PostBuildComputeNormals)) | |||||
| return; | |||||
| array< array<vec3> > normals; | |||||
| normals.Resize(m_vert.Count()); | |||||
| for (int i = 0; i < vcount; i += 3) | |||||
| { | |||||
| vec3 v0 = m_vert[m_indices[start + i + 2]].m_coord | |||||
| - m_vert[m_indices[start + i + 0]].m_coord; | |||||
| vec3 v1 = m_vert[m_indices[start + i + 1]].m_coord | |||||
| - m_vert[m_indices[start + i + 0]].m_coord; | |||||
| vec3 n = normalize(cross(v1, v0)); | |||||
| for (int j = 0; j < 3; j++) | |||||
| normals[m_indices[start + i + j]] << n; | |||||
| } | |||||
| for (int i = 0; i < normals.Count(); i++) | |||||
| { | |||||
| if (normals[i].Count() > 0) | |||||
| { | |||||
| //remove doubles | |||||
| for (int j = 0; j < normals[i].Count(); ++j) | |||||
| for (int k = j + 1; k < normals[i].Count(); ++k) | |||||
| if (1.f - dot(normals[i][k], normals[i][j]) < .00001f) | |||||
| normals[i].Remove(k--); | |||||
| vec3 newv = vec3::zero; | |||||
| for (int j = 0; j < normals[i].Count(); ++j) | |||||
| newv += normals[i][j]; | |||||
| m_vert[i].m_normal = normalize(newv / (float)normals[i].Count()); | |||||
| } | |||||
| } | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::VerticesCleanup() | |||||
| { | |||||
| array<int> vert_ids; | |||||
| vert_ids.Resize(m_vert.Count(), 0); | |||||
| //1: Remove triangles with two vertices on each other | |||||
| for (int i = 0; i < m_indices.Count(); i += 3) | |||||
| { | |||||
| bool remove = false; | |||||
| for (int j = 0; !remove && j < 3; ++j) | |||||
| if (length(m_vert[m_indices[i + j]].m_coord - m_vert[m_indices[i + (j + 1) % 3]].m_coord) < .00001f) | |||||
| remove = true; | |||||
| if (remove) | |||||
| { | |||||
| m_indices.RemoveSwap(i, 3); | |||||
| i -= 3; | |||||
| } | |||||
| else | |||||
| { | |||||
| //1.5: Mark all used vertices | |||||
| for (int j = 0; j < 3; ++j) | |||||
| vert_ids[m_indices[i + j]] = 1; | |||||
| } | |||||
| } | |||||
| //2: Remove all unused vertices | |||||
| array<VertexData> old_vert = m_vert; | |||||
| int shift = 0; | |||||
| m_vert.Empty(); | |||||
| for (int i = 0; i < vert_ids.Count(); ++i) | |||||
| { | |||||
| //Unused vertex, update the shift quantity instead of keeping it. | |||||
| if (vert_ids[i] == 0) | |||||
| shift++; | |||||
| else | |||||
| m_vert << old_vert[i]; | |||||
| //Always mark it with the shift quantity | |||||
| vert_ids[i] = shift; | |||||
| } | |||||
| //3: Update the indices | |||||
| for (int i = 0; i < m_indices.Count(); ++i) | |||||
| m_indices[i] -= vert_ids[m_indices[i]]; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::VerticesMerge() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::VerticesMerge); | |||||
| return; | |||||
| } | |||||
| //1: Crunch all vertices in the dictionnary | |||||
| VertexDictionnary vert_dict; | |||||
| for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) | |||||
| vert_dict.RegisterVertex(i, m_vert[i].m_coord); | |||||
| //2: Update the indices | |||||
| for (int i = 0; i < m_indices.Count(); ++i) | |||||
| { | |||||
| int master = vert_dict.FindVertexMaster(m_indices[i]); | |||||
| if (master >= 0) | |||||
| m_indices[i] = master; | |||||
| } | |||||
| //2: Cleanup | |||||
| VerticesCleanup(); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::VerticesSeparate() | |||||
| { | |||||
| if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) | |||||
| { | |||||
| BD()->CmdStack().AddCmd(EasyMeshCmdType::VerticesSeparate); | |||||
| return; | |||||
| } | |||||
| array< array<int> > new_ids; | |||||
| array<int> vert_ids; | |||||
| vert_ids.Resize(m_vert.Count(), 0); | |||||
| //1: Mark all used vertices | |||||
| for (int i = 0; i < m_indices.Count(); ++i) | |||||
| vert_ids[m_indices[i]]++; | |||||
| //2: Update the vertices | |||||
| int vbase = m_cursors.Last().m1; | |||||
| int vcount = (int)m_vert.Count(); | |||||
| new_ids.Resize(vcount); | |||||
| for (int i = vbase; i < vcount; i++) | |||||
| { | |||||
| while (vert_ids[i] > 1) | |||||
| { | |||||
| //Add duplicate | |||||
| new_ids[i] << (int)m_vert.Count(); | |||||
| AddDupVertex(i); | |||||
| vert_ids[i]--; | |||||
| } | |||||
| } | |||||
| //3: Update the indices | |||||
| for (int i = 0; i < m_indices.Count(); ++i) | |||||
| { | |||||
| if (new_ids[m_indices[i]].Count()) | |||||
| { | |||||
| int j = new_ids[m_indices[i]].Pop(); | |||||
| m_indices[i] = j; | |||||
| } | |||||
| } | |||||
| //4: Cleanup | |||||
| VerticesCleanup(); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset) | |||||
| { | |||||
| UNUSED(uv_scale, uv_offset); | |||||
| #if 0 | |||||
| VertexDictionnary vert_dict; | |||||
| array<int> tri_list; | |||||
| tri_list.Reserve(m_indices.Count() - m_cursors.Last().m2); | |||||
| for (int i = m_cursors.Last().m2; i < m_indices.Count(); i++) | |||||
| { | |||||
| vert_dict.RegisterVertex(m_indices[i], m_vert[m_indices[i]].m_coord); | |||||
| tri_list << m_indices[i]; | |||||
| } | |||||
| //full triangle count | |||||
| array<int> tri_done; | |||||
| array<int> tri_check; | |||||
| int tri_count = (m_indices.Count() - m_cursors.Last().m2) / 3; | |||||
| tri_check << tri_list[0]; | |||||
| while (tri_check.Count()) | |||||
| { | |||||
| int cur_tri = tri_check[0]; | |||||
| int v[3] = { tri_list[cur_tri + uv_offset % 3], tri_list[cur_tri + (1 + uv_offset) % 3], tri_list[cur_tri + (2 + uv_offset) % 3] }; | |||||
| vec2 uv[3] = { m_vert[tri_list[cur_tri]].m_texcoord.xy, m_vert[tri_list[cur_tri + 1]].m_texcoord.xy, m_vert[tri_list[cur_tri + 2]].m_texcoord.xy }; | |||||
| for (int j = 0; j < 3; j++) | |||||
| { | |||||
| if (uv[j] != vec2(-1.0f) && uv[j] == uv[(j + 1) % 3]) | |||||
| { | |||||
| uv[0] = vec2(-1.0f); | |||||
| uv[1] = vec2(-1.0f); | |||||
| uv[2] = vec2(-1.0f); | |||||
| break; | |||||
| } | |||||
| } | |||||
| int uv_set = 0; | |||||
| for (int j = 0; j < 3; j++) | |||||
| uv_set += (uv[j].x < 0.f)?(0):(1); | |||||
| //this case shouldn't happen. | |||||
| if (uv_set == 1) | |||||
| { | |||||
| /* | |||||
| for (int j = 0; j < 3; j++) | |||||
| { | |||||
| if (uv[j] != vec2(-1.0f)) | |||||
| { | |||||
| uv[(j + 1) % 2] = uv[j] + vec2(.0f, uv_scale * length(m_vert[v[j]].m1 - m_vert[v[(j + 1) % 3]].m1)); | |||||
| uv_set = 2; | |||||
| break; | |||||
| } | |||||
| } | |||||
| */ | |||||
| } | |||||
| //No UV is set, let's do the arbitrary set and use the basic method. | |||||
| if (uv_set == 0) | |||||
| { | |||||
| float new_dot = FLT_MAX; | |||||
| int base_i = 0; | |||||
| for (int j = 0; j < 3; j++) | |||||
| { | |||||
| float tmp_dot = abs(dot(normalize(m_vert[v[(j + 1) % 3]].m_coord - m_vert[v[j]].m_coord), | |||||
| normalize(m_vert[v[(j + 2) % 3]].m_coord - m_vert[v[j]].m_coord))); | |||||
| if (tmp_dot < new_dot) | |||||
| { | |||||
| base_i = j; | |||||
| new_dot = tmp_dot; | |||||
| } | |||||
| } | |||||
| uv[base_i] = vec2(.0f); | |||||
| uv[(base_i + 1) % 3] = vec2(.0f, uv_scale * length(m_vert[v[base_i]].m_coord - m_vert[v[(base_i + 1) % 3]].m_coord)); | |||||
| uv_set = 2; | |||||
| } | |||||
| //2 points have been set, let's figure the third | |||||
| if (uv_set == 2) | |||||
| { | |||||
| { | |||||
| //invert values so the two set uv are in [0, 1] slots. | |||||
| int new_v[3]; | |||||
| vec2 new_uv[3]; | |||||
| bool ignore_set = false; | |||||
| if (uv[0].x >= 0.f && uv[1].x < 0.f) | |||||
| { | |||||
| new_v[0] = v[2]; new_v[1] = v[0]; new_v[2] = v[1]; | |||||
| new_uv[0] = uv[2]; new_uv[1] = uv[0]; new_uv[2] = uv[1]; | |||||
| } | |||||
| else if (uv[0].x < 0.f && uv[1].x >= 0.f) | |||||
| { | |||||
| new_v[0] = v[1]; new_v[1] = v[2]; new_v[2] = v[0]; | |||||
| new_uv[0] = uv[1]; new_uv[1] = uv[2]; new_uv[2] = uv[0]; | |||||
| } | |||||
| else | |||||
| ignore_set = true; | |||||
| if (!ignore_set) | |||||
| { | |||||
| v[0] = new_v[0]; v[1] = new_v[1]; v[2] = new_v[2]; | |||||
| uv[0] = new_uv[0]; uv[1] = new_uv[1]; uv[2] = new_uv[2]; | |||||
| } | |||||
| } | |||||
| //Do this to be sure the normal is OK. | |||||
| ComputeNormals(cur_tri, 3); | |||||
| vec3 v01 = normalize(m_vert[v[1]].m_coord - m_vert[v[0]].m_coord); | |||||
| vec3 v02 = m_vert[v[2]].m_coord - m_vert[v[0]].m_coord; | |||||
| vec3 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m_normal, v01)); | |||||
| vec2 texu_dir = uv[1] - uv[0]; | |||||
| vec2 texv_dir = vec2(texu_dir.y, texu_dir.x); | |||||
| //Final calculations | |||||
| uv[2] = texu_dir * dot(v01, v02) + texv_dir * dot(v_dir, v02); | |||||
| //Set UV on ALL matching vertices! | |||||
| array<int> matching_vert; | |||||
| for (int i = 0; i < 3; i++) | |||||
| { | |||||
| #if 1 | |||||
| //This marks all same position UV to the same values | |||||
| //Deactivation is a test. | |||||
| matching_vert << v[i]; | |||||
| vert_dict.FindMatchingVertices(v[i], matching_vert); | |||||
| for (int j = 0; j < matching_vert.Count(); j++) | |||||
| if (m_vert[matching_vert[j]].m_texcoord.xy == vec2(-1.0f)) | |||||
| m_vert[matching_vert[j]].m_texcoord = vec4(abs(uv[i]), m_vert[matching_vert[j]].m_texcoord.zw); | |||||
| #else | |||||
| m_vert[v[i]].m_texcoord = abs(uv[i]); | |||||
| #endif | |||||
| } | |||||
| tri_done << cur_tri; | |||||
| tri_check.Remove(0); | |||||
| //Get connected triangles and go from there. | |||||
| for (int j = 0; j < 3; j++) | |||||
| { | |||||
| #if 1 | |||||
| //This finds triangle that are connected to this triangle | |||||
| vert_dict.FindConnectedTriangles(ivec2(v[j], v[(j + 1) % 3]), tri_list, tri_check, &tri_done); | |||||
| #else | |||||
| //This finds triangle that are connected to the vertices of this triangle | |||||
| vert_dict.FindConnectedTriangles(v[j], tri_list, tri_check, &tri_done); | |||||
| #endif | |||||
| } | |||||
| } | |||||
| else if (uv_set == 3) | |||||
| { | |||||
| for (int j = 0; j < 3; j++) | |||||
| { | |||||
| m_vert[tri_list[cur_tri]].m_texcoord = vec4(vec2(-1.0f), m_vert[tri_list[cur_tri]].m_texcoord.zw); | |||||
| m_vert[tri_list[cur_tri + 1]].m_texcoord = vec4(vec2(-1.0f), m_vert[tri_list[cur_tri + 1]].m_texcoord.zw); | |||||
| m_vert[tri_list[cur_tri + 2]].m_texcoord = vec4(vec2(-1.0f), m_vert[tri_list[cur_tri + 2]].m_texcoord.zw); | |||||
| } | |||||
| //uv[0] = vec2(-1.0f); | |||||
| //uv[1] = vec2(-1.0f); | |||||
| //uv[2] = vec2(-1.0f); | |||||
| /* | |||||
| bool tri_present = false; | |||||
| for (int j = 0; j < tri_done.Count(); j++) | |||||
| if (cur_tri == tri_done[j]) | |||||
| tri_present = true; | |||||
| if (!tri_present) | |||||
| tri_done << cur_tri; | |||||
| tri_check.Remove(0); | |||||
| */ | |||||
| } | |||||
| if (tri_check.Count() == 0 && tri_done.Count() != tri_count) | |||||
| { | |||||
| //look for unset triangle | |||||
| for (int i = 0; !tri_check.Count() && i < tri_list.Count(); i += 3) | |||||
| { | |||||
| bool tri_present = false; | |||||
| for (int j = 0; j < tri_done.Count(); j++) | |||||
| if (i == tri_done[j]) | |||||
| tri_present = true; | |||||
| if (!tri_present) | |||||
| tri_check << i; | |||||
| } | |||||
| } | |||||
| } | |||||
| #endif | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetTexCoordData(vec2 const &new_offset, vec2 const &new_scale) | |||||
| { | |||||
| BD()->TexCoordOffset() = new_offset; | |||||
| BD()->TexCoordScale() = new_scale; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetTexCoordData2(vec2 const &new_offset, vec2 const &new_scale) | |||||
| { | |||||
| BD()->TexCoordOffset2() = new_offset; | |||||
| BD()->TexCoordScale2() = new_scale; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurVertNormal(vec3 const &normal) | |||||
| { | |||||
| m_vert[m_vert.Count() - 1].m_normal = normal; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurVertColor(vec4 const &color) | |||||
| { | |||||
| m_vert[m_vert.Count() - 1].m_color = color; | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurVertTexCoord(vec2 const &texcoord) | |||||
| { | |||||
| m_vert[m_vert.Count() - 1].m_texcoord = vec4(texcoord, m_vert[m_vert.Count() - 1].m_texcoord.zw); | |||||
| } | |||||
| //----------------------------------------------------------------------------- | |||||
| void EasyMesh::SetCurVertTexCoord2(vec2 const &texcoord) | |||||
| { | |||||
| m_vert[m_vert.Count() - 1].m_texcoord = vec4(m_vert[m_vert.Count() - 1].m_texcoord.xy, texcoord); | |||||
| } | |||||
| } /* namespace lol */ | |||||
| @@ -65,16 +65,16 @@ void EasyMesh::AppendCylinder(int nsides, float h, float d1, float d2, | |||||
| { | { | ||||
| /* FIXME: normals should be flipped in two-sided mode, but that | /* FIXME: normals should be flipped in two-sided mode, but that | ||||
| * means duplicating the vertices again... */ | * means duplicating the vertices again... */ | ||||
| InternalAddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1); SetCurVertTexCoord2(uv1); | |||||
| InternalAddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2); SetCurVertTexCoord2(uv2); SetCurVertColor(BD()->ColorB()); | |||||
| AddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1); SetCurVertTexCoord2(uv1); | |||||
| AddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2); SetCurVertTexCoord2(uv2); SetCurVertColor(BD()->ColorB()); | |||||
| p1 = rotmat * p1; uv1 += uvadd; | p1 = rotmat * p1; uv1 += uvadd; | ||||
| p2 = rotmat * p2; uv2 += uvadd; | p2 = rotmat * p2; uv2 += uvadd; | ||||
| if (!smooth) | if (!smooth) | ||||
| { | { | ||||
| InternalAddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1); SetCurVertTexCoord2(uv1); | |||||
| InternalAddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2); SetCurVertTexCoord2(uv2); SetCurVertColor(BD()->ColorB()); | |||||
| AddVertex(p1); SetCurVertNormal(n); SetCurVertTexCoord(uv1); SetCurVertTexCoord2(uv1); | |||||
| AddVertex(p2); SetCurVertNormal(n); SetCurVertTexCoord(uv2); SetCurVertTexCoord2(uv2); SetCurVertColor(BD()->ColorB()); | |||||
| } | } | ||||
| n = rotmat * n; | n = rotmat * n; | ||||
| @@ -85,15 +85,15 @@ void EasyMesh::AppendCylinder(int nsides, float h, float d1, float d2, | |||||
| if (smooth) | if (smooth) | ||||
| { | { | ||||
| int j = (i + 1) % nsides; | int j = (i + 1) % nsides; | ||||
| InternalAddQuad(j * 2, j * 2 + 1, i * 2 + 1, i * 2, vbase); | |||||
| AddQuad(j * 2, j * 2 + 1, i * 2 + 1, i * 2, vbase); | |||||
| if (dualside) | if (dualside) | ||||
| InternalAddQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase); | |||||
| AddQuad(i * 2, i * 2 + 1, j * 2 + 1, j * 2, vbase); | |||||
| } | } | ||||
| else | else | ||||
| { | { | ||||
| InternalAddQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase); | |||||
| AddQuad(i * 4 + 2, i * 4 + 3, i * 4 + 1, i * 4, vbase); | |||||
| if (dualside) | if (dualside) | ||||
| InternalAddQuad(i * 4, i * 4 + 1, i * 4 + 3, i * 4 + 2, vbase); | |||||
| AddQuad(i * 4, i * 4 + 1, i * 4 + 3, i * 4 + 2, vbase); | |||||
| } | } | ||||
| } | } | ||||
| @@ -170,7 +170,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) | |||||
| vertices << m * vec3(y, 0.f, x); | vertices << m * vec3(y, 0.f, x); | ||||
| } | } | ||||
| static int const trilist[] = | |||||
| static int const tris[] = | |||||
| { | { | ||||
| 0, 1, 2, 2, 4, 6, 3, 8, 1, 9, 4, 8, | 0, 1, 2, 2, 4, 6, 3, 8, 1, 9, 4, 8, | ||||
| 7, 0, 5, 7, 11, 3, 10, 5, 6, 10, 9, 11, | 7, 0, 5, 7, 11, 3, 10, 5, 6, 10, 9, 11, | ||||
| @@ -180,11 +180,11 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) | |||||
| 7, 10, 11, 5, 10, 7, 8, 11, 9, 3, 11, 8 | 7, 10, 11, 5, 10, 7, 8, 11, 9, 3, 11, 8 | ||||
| }; | }; | ||||
| for (unsigned i = 0; i < sizeof(trilist) / sizeof(*trilist); i += 3) | |||||
| for (unsigned i = 0; i < sizeof(tris) / sizeof(*tris); i += 3) | |||||
| { | { | ||||
| vec3 const &a = vertices[trilist[i]]; | |||||
| vec3 const &b = vertices[trilist[i + 1]]; | |||||
| vec3 const &c = vertices[trilist[i + 2]]; | |||||
| vec3 const &a = vertices[tris[i]]; | |||||
| vec3 const &b = vertices[tris[i + 1]]; | |||||
| vec3 const &c = vertices[tris[i + 2]]; | |||||
| vec3 const vb = 1.f / ndivisions * (b - a); | vec3 const vb = 1.f / ndivisions * (b - a); | ||||
| vec3 const vc = 1.f / ndivisions * (c - a); | vec3 const vc = 1.f / ndivisions * (c - a); | ||||
| @@ -254,7 +254,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) | |||||
| while (++k < 3) | while (++k < 3) | ||||
| { | { | ||||
| int rid[] = { id[k + l], id[(k + 1) % 3 + l], id[(k + 2) % 3 + l] }; | int rid[] = { id[k + l], id[(k + 1) % 3 + l], id[(k + 2) % 3 + l] }; | ||||
| InternalAddVertex(p[rid[0]]); | |||||
| AddVertex(p[rid[0]]); | |||||
| vec2 new_uv; | vec2 new_uv; | ||||
| if (uv[rid[0]].x < .0f) | if (uv[rid[0]].x < .0f) | ||||
| new_uv = vec2((uv[rid[1]].x + uv[rid[2]].x) * .5f, uv[rid[0]].y); | new_uv = vec2((uv[rid[1]].x + uv[rid[2]].x) * .5f, uv[rid[0]].y); | ||||
| @@ -263,7 +263,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) | |||||
| SetCurVertTexCoord(vec2(0.f, 1.f) - new_uv); | SetCurVertTexCoord(vec2(0.f, 1.f) - new_uv); | ||||
| SetCurVertTexCoord2(vec2(0.f, 1.f) - new_uv); | SetCurVertTexCoord2(vec2(0.f, 1.f) - new_uv); | ||||
| } | } | ||||
| InternalAddTriangle(0, 2, 1, (int)m_vert.Count() - 3); | |||||
| AddTriangle(0, 2, 1, (int)m_vert.Count() - 3); | |||||
| } | } | ||||
| } | } | ||||
| @@ -320,13 +320,13 @@ void EasyMesh::AppendTorus(int ndivisions, float d1, float d2) | |||||
| float x2 = x * ca - z * sa; | float x2 = x * ca - z * sa; | ||||
| float z2 = z * ca + x * sa; | float z2 = z * ca + x * sa; | ||||
| InternalAddVertex(vec3(x2, y, z2)); | |||||
| AddVertex(vec3(x2, y, z2)); | |||||
| SetCurVertTexCoord(vec2((float)(i + di) / (float)nidiv, (float)(j + dj) / (float)nidiv)); | SetCurVertTexCoord(vec2((float)(i + di) / (float)nidiv, (float)(j + dj) / (float)nidiv)); | ||||
| SetCurVertTexCoord2(vec2((float)(i + di) / (float)nidiv, (float)(j + dj) / (float)nidiv)); | SetCurVertTexCoord2(vec2((float)(i + di) / (float)nidiv, (float)(j + dj) / (float)nidiv)); | ||||
| } | } | ||||
| InternalAddTriangle(0, 2, 3, (int)m_vert.Count() - 4); | |||||
| InternalAddTriangle(0, 3, 1, (int)m_vert.Count() - 4); | |||||
| AddTriangle(0, 2, 3, (int)m_vert.Count() - 4); | |||||
| AddTriangle(0, 3, 1, (int)m_vert.Count() - 4); | |||||
| } | } | ||||
| ComputeNormals(ibase, (int)m_indices.Count() - ibase); | ComputeNormals(ibase, (int)m_indices.Count() - ibase); | ||||
| @@ -381,73 +381,73 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||||
| //Side vertices | //Side vertices | ||||
| //-- | //-- | ||||
| MeshFaceType mft = MeshFaceType::BoxFront; | MeshFaceType mft = MeshFaceType::BoxFront; | ||||
| InternalAddVertex(vec3(-d.x, -d.y, -d.z - chamf)); | |||||
| AddVertex(vec3(-d.x, -d.y, -d.z - chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x, +d.y, -d.z - chamf)); | |||||
| AddVertex(vec3(-d.x, +d.y, -d.z - chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, +d.y, -d.z - chamf)); | |||||
| AddVertex(vec3(+d.x, +d.y, -d.z - chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, -d.y, -d.z - chamf)); | |||||
| AddVertex(vec3(+d.x, -d.y, -d.z - chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| mft = MeshFaceType::BoxLeft; | mft = MeshFaceType::BoxLeft; | ||||
| InternalAddVertex(vec3(-d.x - chamf, -d.y, +d.z)); | |||||
| AddVertex(vec3(-d.x - chamf, -d.y, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x - chamf, +d.y, +d.z)); | |||||
| AddVertex(vec3(-d.x - chamf, +d.y, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x - chamf, +d.y, -d.z)); | |||||
| AddVertex(vec3(-d.x - chamf, +d.y, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x - chamf, -d.y, -d.z)); | |||||
| AddVertex(vec3(-d.x - chamf, -d.y, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| mft = MeshFaceType::BoxBack; | mft = MeshFaceType::BoxBack; | ||||
| InternalAddVertex(vec3(+d.x, -d.y, +d.z + chamf)); | |||||
| AddVertex(vec3(+d.x, -d.y, +d.z + chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, +d.y, +d.z + chamf)); | |||||
| AddVertex(vec3(+d.x, +d.y, +d.z + chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x, +d.y, +d.z + chamf)); | |||||
| AddVertex(vec3(-d.x, +d.y, +d.z + chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x, -d.y, +d.z + chamf)); | |||||
| AddVertex(vec3(-d.x, -d.y, +d.z + chamf)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| mft = MeshFaceType::BoxRight; | mft = MeshFaceType::BoxRight; | ||||
| InternalAddVertex(vec3(+d.x + chamf, -d.y, -d.z)); | |||||
| AddVertex(vec3(+d.x + chamf, -d.y, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x + chamf, +d.y, -d.z)); | |||||
| AddVertex(vec3(+d.x + chamf, +d.y, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x + chamf, +d.y, +d.z)); | |||||
| AddVertex(vec3(+d.x + chamf, +d.y, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x + chamf, -d.y, +d.z)); | |||||
| AddVertex(vec3(+d.x + chamf, -d.y, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| @@ -455,19 +455,19 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||||
| //Bottom vertices | //Bottom vertices | ||||
| //-- | //-- | ||||
| mft = MeshFaceType::BoxBottom; | mft = MeshFaceType::BoxBottom; | ||||
| InternalAddVertex(vec3(-d.x, -d.y - chamf, +d.z)); | |||||
| AddVertex(vec3(-d.x, -d.y - chamf, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x, -d.y - chamf, -d.z)); | |||||
| AddVertex(vec3(-d.x, -d.y - chamf, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, -d.y - chamf, -d.z)); | |||||
| AddVertex(vec3(+d.x, -d.y - chamf, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, -d.y - chamf, +d.z)); | |||||
| AddVertex(vec3(+d.x, -d.y - chamf, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| @@ -475,19 +475,19 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||||
| //Top vertices | //Top vertices | ||||
| //-- | //-- | ||||
| mft = MeshFaceType::BoxTop; | mft = MeshFaceType::BoxTop; | ||||
| InternalAddVertex(vec3(-d.x, +d.y + chamf, -d.z)); | |||||
| AddVertex(vec3(-d.x, +d.y + chamf, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(-d.x, +d.y + chamf, +d.z)); | |||||
| AddVertex(vec3(-d.x, +d.y + chamf, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, +d.y + chamf, +d.z)); | |||||
| AddVertex(vec3(+d.x, +d.y + chamf, +d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(+d.x, +d.y + chamf, -d.z)); | |||||
| AddVertex(vec3(+d.x, +d.y + chamf, -d.z)); | |||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| @@ -496,12 +496,12 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||||
| //Build the box at the end : The 6 quads on each side of the box. | //Build the box at the end : The 6 quads on each side of the box. | ||||
| for (int i = 0; i < 24; i += 4) | for (int i = 0; i < 24; i += 4) | ||||
| InternalAddQuad(i, i + 1, i + 2, i + 3, vbase); | |||||
| AddQuad(i, i + 1, i + 2, i + 3, vbase); | |||||
| /* The 8 quads at each edge of the box */ | /* The 8 quads at each edge of the box */ | ||||
| if (chamf) | if (chamf) | ||||
| { | { | ||||
| static int const quadlist[48] = | |||||
| static int const quads[48] = | |||||
| { | { | ||||
| 0, 3, 18, 17, 4, 7, 17, 16, 8, 11, 16, 19, 12, 15, 19, 18, | 0, 3, 18, 17, 4, 7, 17, 16, 8, 11, 16, 19, 12, 15, 19, 18, | ||||
| 2, 1, 20, 23, 6, 5, 21, 20, 10, 9, 22, 21, 14, 13, 23, 22, | 2, 1, 20, 23, 6, 5, 21, 20, 10, 9, 22, 21, 14, 13, 23, 22, | ||||
| @@ -509,32 +509,20 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||||
| }; | }; | ||||
| for (int i = 0; i < 48; i += 4) | for (int i = 0; i < 48; i += 4) | ||||
| { | |||||
| if (smooth) | |||||
| InternalAddQuad(quadlist[i], quadlist[i + 1], | |||||
| quadlist[i + 2], quadlist[i + 3], vbase); | |||||
| else | |||||
| InternalAddQuadDupVerts(quadlist[i], quadlist[i + 1], | |||||
| quadlist[i + 2], quadlist[i + 3], vbase); | |||||
| } | |||||
| AddQuad(quads[i], quads[i + 1], quads[i + 2], quads[i + 3], vbase, !smooth); | |||||
| } | } | ||||
| /* The 8 triangles at each corner of the box */ | /* The 8 triangles at each corner of the box */ | ||||
| if (chamf) | if (chamf) | ||||
| { | { | ||||
| static int const trilist[24] = | |||||
| static int const tris[24] = | |||||
| { | { | ||||
| 3, 12, 18, 15, 8, 19, 11, 4, 16, 7, 0, 17, | 3, 12, 18, 15, 8, 19, 11, 4, 16, 7, 0, 17, | ||||
| 2, 23, 13, 14, 22, 9, 10, 21, 5, 6, 20, 1, | 2, 23, 13, 14, 22, 9, 10, 21, 5, 6, 20, 1, | ||||
| }; | }; | ||||
| for (int i = 0; i < 24; i += 3) | for (int i = 0; i < 24; i += 3) | ||||
| { | |||||
| if (smooth) | |||||
| InternalAddTriangle(trilist[i], trilist[i + 1], trilist[i + 2], vbase); | |||||
| else | |||||
| InternalAddTriangleDupVerts(trilist[i], trilist[i + 1], trilist[i + 2], vbase); | |||||
| } | |||||
| AddTriangle(tris[i], tris[i + 1], tris[i + 2], vbase, !smooth); | |||||
| } | } | ||||
| if (!smooth) | if (!smooth) | ||||
| @@ -563,7 +551,7 @@ void EasyMesh::AppendStar(int nbranches, float d1, float d2, | |||||
| int vbase = (int)m_vert.Count(); | int vbase = (int)m_vert.Count(); | ||||
| float maxr = max(r1, r2); | float maxr = max(r1, r2); | ||||
| InternalAddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); | mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); | ||||
| vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f); | vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f); | ||||
| @@ -575,16 +563,16 @@ void EasyMesh::AppendStar(int nbranches, float d1, float d2, | |||||
| for (int i = 0; i < nbranches; i++) | for (int i = 0; i < nbranches; i++) | ||||
| { | { | ||||
| InternalAddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f)); SetCurVertTexCoord2(uv1.xz + vec2(.5f)); | |||||
| AddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f)); SetCurVertTexCoord2(uv1.xz + vec2(.5f)); | |||||
| if (fade2) | if (fade2) | ||||
| SetCurVertColor(BD()->ColorB()); | SetCurVertColor(BD()->ColorB()); | ||||
| InternalAddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f)); SetCurVertTexCoord2(uv2.xz + vec2(.5f)); | |||||
| AddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f)); SetCurVertTexCoord2(uv2.xz + vec2(.5f)); | |||||
| if (fade) | if (fade) | ||||
| SetCurVertColor(BD()->ColorB()); | SetCurVertColor(BD()->ColorB()); | ||||
| //Append quad at the end | //Append quad at the end | ||||
| InternalAddQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches), vbase); | |||||
| AddQuad(0, 2 * i + 1, 2 * i + 2, (2 * i + 3) % (2 * nbranches), vbase); | |||||
| p1 = rotmat * p1; uv1 = rotmat * uv1; | p1 = rotmat * p1; uv1 = rotmat * uv1; | ||||
| p2 = rotmat * p2; uv2 = rotmat * uv2; | p2 = rotmat * p2; uv2 = rotmat * uv2; | ||||
| @@ -615,7 +603,7 @@ void EasyMesh::AppendExpandedStar(int nbranches, float d1, float d2, float extra | |||||
| int vbase = (int)m_vert.Count(); | int vbase = (int)m_vert.Count(); | ||||
| float maxr = lol::max(lol::max(r1, r2), lol::max(r1 + extrar, r2 + extrar)); | float maxr = lol::max(lol::max(r1, r2), lol::max(r1 + extrar, r2 + extrar)); | ||||
| InternalAddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); | mat3 rotmat = mat3::rotate(180.0f / nbranches, 0.f, 1.f, 0.f); | ||||
| vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f), | vec3 p1(r1, 0.f, 0.f), p2(r2, 0.f, 0.f), | ||||
| @@ -631,16 +619,16 @@ void EasyMesh::AppendExpandedStar(int nbranches, float d1, float d2, float extra | |||||
| for (int i = 0; i < nbranches; i++) | for (int i = 0; i < nbranches; i++) | ||||
| { | { | ||||
| InternalAddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f)); SetCurVertTexCoord2(uv1.xz + vec2(.5f)); | |||||
| InternalAddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f)); SetCurVertTexCoord2(uv2.xz + vec2(.5f)); | |||||
| InternalAddVertex(p3); SetCurVertTexCoord(uv3.xz + vec2(.5f)); SetCurVertTexCoord2(uv3.xz + vec2(.5f)); SetCurVertColor(BD()->ColorB()); | |||||
| InternalAddVertex(p4); SetCurVertTexCoord(uv4.xz + vec2(.5f)); SetCurVertTexCoord2(uv4.xz + vec2(.5f)); SetCurVertColor(BD()->ColorB()); | |||||
| AddVertex(p1); SetCurVertTexCoord(uv1.xz + vec2(.5f)); SetCurVertTexCoord2(uv1.xz + vec2(.5f)); | |||||
| AddVertex(p2); SetCurVertTexCoord(uv2.xz + vec2(.5f)); SetCurVertTexCoord2(uv2.xz + vec2(.5f)); | |||||
| AddVertex(p3); SetCurVertTexCoord(uv3.xz + vec2(.5f)); SetCurVertTexCoord2(uv3.xz + vec2(.5f)); SetCurVertColor(BD()->ColorB()); | |||||
| AddVertex(p4); SetCurVertTexCoord(uv4.xz + vec2(.5f)); SetCurVertTexCoord2(uv4.xz + vec2(.5f)); SetCurVertColor(BD()->ColorB()); | |||||
| int j = (i + 1) % nbranches; | int j = (i + 1) % nbranches; | ||||
| // | // | ||||
| InternalAddQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase); | |||||
| InternalAddQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase); | |||||
| InternalAddQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase); | |||||
| AddQuad(0, 4 * i + 1, 4 * i + 2, 4 * j + 1, vbase); | |||||
| AddQuad(4 * i + 1, 4 * i + 3, 4 * i + 4, 4 * i + 2, vbase); | |||||
| AddQuad(4 * j + 1, 4 * i + 2, 4 * i + 4, 4 * j + 3, vbase); | |||||
| p1 = rotmat * p1; uv1 = rotmat * uv1; | p1 = rotmat * p1; uv1 = rotmat * uv1; | ||||
| p2 = rotmat * p2; uv2 = rotmat * uv2; | p2 = rotmat * p2; uv2 = rotmat * uv2; | ||||
| @@ -667,7 +655,7 @@ void EasyMesh::AppendDisc(int nsides, float d, bool fade) | |||||
| int vbase = (int)m_vert.Count(); | int vbase = (int)m_vert.Count(); | ||||
| InternalAddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| AddVertex(vec3(0.f, 0.f, 0.f)); SetCurVertTexCoord(vec2(.5f, .5f)); SetCurVertTexCoord2(vec2(.5f, .5f)); | |||||
| mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f); | mat3 rotmat = mat3::rotate(360.0f / nsides, 0.f, 1.f, 0.f); | ||||
| vec3 p1(r, 0.f, 0.f); | vec3 p1(r, 0.f, 0.f); | ||||
| @@ -675,10 +663,10 @@ void EasyMesh::AppendDisc(int nsides, float d, bool fade) | |||||
| for (int i = 0; i < nsides; i++) | for (int i = 0; i < nsides; i++) | ||||
| { | { | ||||
| InternalAddVertex(p1); SetCurVertTexCoord(uv.xz + vec2(.5f, .5f)); SetCurVertTexCoord2(uv.xz + vec2(.5f, .5f)); | |||||
| AddVertex(p1); SetCurVertTexCoord(uv.xz + vec2(.5f, .5f)); SetCurVertTexCoord2(uv.xz + vec2(.5f, .5f)); | |||||
| if (fade) | if (fade) | ||||
| SetCurVertColor(BD()->ColorB()); | SetCurVertColor(BD()->ColorB()); | ||||
| InternalAddTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); | |||||
| AddTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); | |||||
| p1 = rotmat * p1; | p1 = rotmat * p1; | ||||
| uv = rotmat * uv; | uv = rotmat * uv; | ||||
| } | } | ||||
| @@ -700,17 +688,17 @@ void EasyMesh::AppendSimpleTriangle(float d, bool fade) | |||||
| mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f); | mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f); | ||||
| vec3 p(0.f, 0.f, size); | vec3 p(0.f, 0.f, size); | ||||
| InternalAddVertex(p); SetCurVertTexCoord(vec2(.5f, 0.133975f)); SetCurVertTexCoord2(vec2(.5f, 0.133975f)); | |||||
| AddVertex(p); SetCurVertTexCoord(vec2(.5f, 0.133975f)); SetCurVertTexCoord2(vec2(.5f, 0.133975f)); | |||||
| p = m * p; | p = m * p; | ||||
| InternalAddVertex(p); SetCurVertTexCoord(vec2(0.f, 1.f)); SetCurVertTexCoord2(vec2(0.f, 1.f)); | |||||
| AddVertex(p); SetCurVertTexCoord(vec2(0.f, 1.f)); SetCurVertTexCoord2(vec2(0.f, 1.f)); | |||||
| if (fade) | if (fade) | ||||
| SetCurVertColor(BD()->ColorB()); | SetCurVertColor(BD()->ColorB()); | ||||
| p = m * p; | p = m * p; | ||||
| InternalAddVertex(p); SetCurVertTexCoord(vec2(1.f, 1.f)); SetCurVertTexCoord2(vec2(1.f, 1.f)); | |||||
| AddVertex(p); SetCurVertTexCoord(vec2(1.f, 1.f)); SetCurVertTexCoord2(vec2(1.f, 1.f)); | |||||
| if (fade) | if (fade) | ||||
| SetCurVertColor(BD()->ColorB()); | SetCurVertColor(BD()->ColorB()); | ||||
| InternalAddTriangle(0, 1, 2, (int)m_vert.Count() - 3); | |||||
| AddTriangle(0, 1, 2, (int)m_vert.Count() - 3); | |||||
| } | } | ||||
| //----------------------------------------------------------------------------- | //----------------------------------------------------------------------------- | ||||
| @@ -733,29 +721,29 @@ void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, bool fade) | |||||
| MeshFaceType mft = MeshFaceType::QuadDefault; | MeshFaceType mft = MeshFaceType::QuadDefault; | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(p2.x, z, -p1.y)); | |||||
| AddVertex(vec3(p2.x, z, -p1.y)); | |||||
| TexCoordPos br = TexCoordPos::BR; | TexCoordPos br = TexCoordPos::BR; | ||||
| SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, br, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, br, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, br, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(p2.x, z, -p2.y)); | |||||
| AddVertex(vec3(p2.x, z, -p2.y)); | |||||
| TexCoordPos bl = TexCoordPos::BL; | TexCoordPos bl = TexCoordPos::BL; | ||||
| SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, bl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, bl, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, bl, mft)); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(p1.x, z, -p2.y)); | |||||
| AddVertex(vec3(p1.x, z, -p2.y)); | |||||
| TexCoordPos tl = TexCoordPos::TL; | TexCoordPos tl = TexCoordPos::TL; | ||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tl, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tl, mft)); | ||||
| if (fade) SetCurVertColor(BD()->ColorB()); | if (fade) SetCurVertColor(BD()->ColorB()); | ||||
| //-- | //-- | ||||
| InternalAddVertex(vec3(p1.x, z, -p1.y)); | |||||
| AddVertex(vec3(p1.x, z, -p1.y)); | |||||
| TexCoordPos tr = TexCoordPos::TR; | TexCoordPos tr = TexCoordPos::TR; | ||||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | ||||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | ||||
| if (fade) SetCurVertColor(BD()->ColorB()); | if (fade) SetCurVertColor(BD()->ColorB()); | ||||
| InternalAddQuad(0, 1, 2, 3, (int)m_vert.Count() - 4); | |||||
| AddQuad(0, 1, 2, 3, (int)m_vert.Count() - 4); | |||||
| ComputeNormals((int)m_indices.Count() - 6, 6); | ComputeNormals((int)m_indices.Count() - 6, 6); | ||||
| } | } | ||||
| @@ -981,7 +969,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float d10, float d20, | |||||
| { | { | ||||
| int d = n / 3; | int d = n / 3; | ||||
| int e = d % 6; | int e = d % 6; | ||||
| InternalAddVertex(p[d]); | |||||
| AddVertex(p[d]); | |||||
| if (n % 3 == 0) //Top-Bottom logic | if (n % 3 == 0) //Top-Bottom logic | ||||
| { | { | ||||
| vec2 tmp = (p[d].xz / maxr); | vec2 tmp = (p[d].xz / maxr); | ||||
| @@ -1027,7 +1015,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float d10, float d20, | |||||
| DEF_J_K_Q; | DEF_J_K_Q; | ||||
| int l = -4; | int l = -4; | ||||
| while ((l += 4) < 48) | while ((l += 4) < 48) | ||||
| InternalAddQuad(q[l + 0] + m[l + 0] * 3 + a[l + 0], | |||||
| AddQuad(q[l + 0] + m[l + 0] * 3 + a[l + 0], | |||||
| q[l + 1] + m[l + 1] * 3 + a[l + 1], | q[l + 1] + m[l + 1] * 3 + a[l + 1], | ||||
| q[l + 2] + m[l + 2] * 3 + a[l + 2], | q[l + 2] + m[l + 2] * 3 + a[l + 2], | ||||
| q[l + 3] + m[l + 3] * 3 + a[l + 3], | q[l + 3] + m[l + 3] * 3 + a[l + 3], | ||||
| @@ -241,7 +241,7 @@ void EasyMesh::DupAndScale(vec3 const &s, bool open_brace) | |||||
| int tlen = (int)m_indices.Count() - m_cursors.Last().m2; | int tlen = (int)m_indices.Count() - m_cursors.Last().m2; | ||||
| for (int i = 0; i < vlen; i++) | for (int i = 0; i < vlen; i++) | ||||
| AddDuplicateVertex(m_cursors.Last().m1++); | |||||
| AddDupVertex(m_cursors.Last().m1++); | |||||
| for (int i = 0; i < tlen; i++) | for (int i = 0; i < tlen; i++) | ||||
| m_indices << m_indices[m_cursors.Last().m2++] + vlen; | m_indices << m_indices[m_cursors.Last().m2++] + vlen; | ||||
| @@ -343,9 +343,9 @@ void EasyMesh::SplitTriangles(int pass, VertexDictionnary *vert_dict) | |||||
| vert_dict->RegisterVertex(vbase + j, m_vert[vbase + j].m_coord); | vert_dict->RegisterVertex(vbase + j, m_vert[vbase + j].m_coord); | ||||
| } | } | ||||
| //Add new triangles | //Add new triangles | ||||
| InternalAddTriangle(vbase, m_indices[i + 1], vbase + 1, 0); | |||||
| InternalAddTriangle(vbase + 2, vbase + 1, m_indices[i + 2], 0); | |||||
| InternalAddTriangle(vbase, vbase + 1, vbase + 2, 0); | |||||
| AddTriangle(vbase, m_indices[i + 1], vbase + 1, 0); | |||||
| AddTriangle(vbase + 2, vbase + 1, m_indices[i + 2], 0); | |||||
| AddTriangle(vbase, vbase + 1, vbase + 2, 0); | |||||
| //Change current triangle | //Change current triangle | ||||
| m_indices[i + 1] = vbase; | m_indices[i + 1] = vbase; | ||||
| m_indices[i + 2] = vbase + 2; | m_indices[i + 2] = vbase + 2; | ||||
| @@ -103,6 +103,9 @@ | |||||
| <ClCompile Include="easymesh\csgbsp.cpp" /> | <ClCompile Include="easymesh\csgbsp.cpp" /> | ||||
| <ClCompile Include="easymesh\easymesh.cpp" /> | <ClCompile Include="easymesh\easymesh.cpp" /> | ||||
| <ClCompile Include="easymesh\easymeshbuild.cpp" /> | <ClCompile Include="easymesh\easymeshbuild.cpp" /> | ||||
| <ClCompile Include="easymesh\easymeshcsg.cpp" /> | |||||
| <ClCompile Include="easymesh\easymeshcursor.cpp" /> | |||||
| <ClCompile Include="easymesh\easymeshinternal.cpp" /> | |||||
| <ClCompile Include="easymesh\easymeshprimitive.cpp" /> | <ClCompile Include="easymesh\easymeshprimitive.cpp" /> | ||||
| <ClCompile Include="easymesh\easymeshrender.cpp" /> | <ClCompile Include="easymesh\easymeshrender.cpp" /> | ||||
| <ClCompile Include="easymesh\easymeshtransform.cpp" /> | <ClCompile Include="easymesh\easymeshtransform.cpp" /> | ||||
| @@ -394,6 +394,15 @@ | |||||
| <ClCompile Include="easymesh\easymeshtransform.cpp"> | <ClCompile Include="easymesh\easymeshtransform.cpp"> | ||||
| <Filter>easymesh</Filter> | <Filter>easymesh</Filter> | ||||
| </ClCompile> | </ClCompile> | ||||
| <ClCompile Include="easymesh\easymeshcsg.cpp"> | |||||
| <Filter>easymesh</Filter> | |||||
| </ClCompile> | |||||
| <ClCompile Include="easymesh\easymeshinternal.cpp"> | |||||
| <Filter>easymesh</Filter> | |||||
| </ClCompile> | |||||
| <ClCompile Include="easymesh\easymeshcursor.cpp"> | |||||
| <Filter>easymesh</Filter> | |||||
| </ClCompile> | |||||
| </ItemGroup> | </ItemGroup> | ||||
| <ItemGroup> | <ItemGroup> | ||||
| <ClInclude Include="debug\fps.h"> | <ClInclude Include="debug\fps.h"> | ||||