| @@ -70,8 +70,10 @@ liblolcore_sources = \ | |||
| commandstack.h \ | |||
| easymesh/easymeshbuild.cpp easymesh/easymeshbuild.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/shiny.lolfx easymesh/shinyflat.lolfx \ | |||
| easymesh/shinydebugwireframe.lolfx \ | |||
| @@ -94,20 +94,20 @@ private: | |||
| //------------------------------------------------------------------------- | |||
| //Mesh CSG operations | |||
| //------------------------------------------------------------------------- | |||
| private: | |||
| void MeshCsg(CSGUsage csg_operation); | |||
| public: | |||
| /* [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) */ | |||
| void CsgSub() { MeshCsg(CSGUsage::Substract); } | |||
| void CsgSub(); | |||
| /* [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) */ | |||
| void CsgAnd() { MeshCsg(CSGUsage::And); } | |||
| void CsgAnd(); | |||
| /* [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 | |||
| @@ -127,7 +127,7 @@ public: | |||
| void ToggleQuadWeighting(); | |||
| /* [cmd:tpbn] When active, normal will be computed after the build */ | |||
| void TogglePostBuildNormal(); | |||
| /* [cmd:tpbn] When active, normal will be computed after the build */ | |||
| /* [cmd:tpbn] When active, prevents vertices cleanup */ | |||
| void ToggleVerticeNoCleanup(); | |||
| /* [cmd:sc] Set both color */ | |||
| void SetCurColor(vec4 const &color); | |||
| @@ -142,16 +142,14 @@ public: | |||
| //Internal : Basic triangle/vertex operations | |||
| //------------------------------------------------------------------------- | |||
| 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(VertexData const &vi, VertexData const &vj, float alpha); | |||
| VertexData GetLerpVertex(int i, int j, 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); | |||
| public: | |||
| /* 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 | |||
| * 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; | |||
| p2 = rotmat * p2; uv2 += uvadd; | |||
| 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; | |||
| @@ -85,15 +85,15 @@ void EasyMesh::AppendCylinder(int nsides, float h, float d1, float d2, | |||
| if (smooth) | |||
| { | |||
| 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) | |||
| 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 | |||
| { | |||
| 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) | |||
| 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); | |||
| } | |||
| static int const trilist[] = | |||
| static int const tris[] = | |||
| { | |||
| 0, 1, 2, 2, 4, 6, 3, 8, 1, 9, 4, 8, | |||
| 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 | |||
| }; | |||
| 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 vc = 1.f / ndivisions * (c - a); | |||
| @@ -254,7 +254,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float d) | |||
| while (++k < 3) | |||
| { | |||
| 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; | |||
| if (uv[rid[0]].x < .0f) | |||
| 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); | |||
| 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 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)); | |||
| 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); | |||
| @@ -381,73 +381,73 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||
| //Side vertices | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| @@ -455,19 +455,19 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||
| //Bottom vertices | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| @@ -475,19 +475,19 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) | |||
| //Top vertices | |||
| //-- | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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)); | |||
| 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. | |||
| 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 */ | |||
| 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, | |||
| 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) | |||
| { | |||
| 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 */ | |||
| if (chamf) | |||
| { | |||
| static int const trilist[24] = | |||
| static int const tris[24] = | |||
| { | |||
| 3, 12, 18, 15, 8, 19, 11, 4, 16, 7, 0, 17, | |||
| 2, 23, 13, 14, 22, 9, 10, 21, 5, 6, 20, 1, | |||
| }; | |||
| 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) | |||
| @@ -563,7 +551,7 @@ void EasyMesh::AppendStar(int nbranches, float d1, float d2, | |||
| int vbase = (int)m_vert.Count(); | |||
| 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); | |||
| 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++) | |||
| { | |||
| 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) | |||
| 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) | |||
| SetCurVertColor(BD()->ColorB()); | |||
| //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; | |||
| 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(); | |||
| 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); | |||
| 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++) | |||
| { | |||
| 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; | |||
| // | |||
| 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; | |||
| 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(); | |||
| 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); | |||
| 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++) | |||
| { | |||
| 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) | |||
| SetCurVertColor(BD()->ColorB()); | |||
| InternalAddTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); | |||
| AddTriangle(0, i + 1, ((i + 1) % nsides) + 1, vbase); | |||
| p1 = rotmat * p1; | |||
| 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); | |||
| 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; | |||
| 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) | |||
| SetCurVertColor(BD()->ColorB()); | |||
| 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) | |||
| 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; | |||
| //-- | |||
| InternalAddVertex(vec3(p2.x, z, -p1.y)); | |||
| AddVertex(vec3(p2.x, z, -p1.y)); | |||
| TexCoordPos br = TexCoordPos::BR; | |||
| SetCurVertTexCoord(BD()->TexCoord(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; | |||
| SetCurVertTexCoord(BD()->TexCoord(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; | |||
| SetCurVertTexCoord(BD()->TexCoord(mt, tl, mft)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tl, mft)); | |||
| if (fade) SetCurVertColor(BD()->ColorB()); | |||
| //-- | |||
| InternalAddVertex(vec3(p1.x, z, -p1.y)); | |||
| AddVertex(vec3(p1.x, z, -p1.y)); | |||
| TexCoordPos tr = TexCoordPos::TR; | |||
| SetCurVertTexCoord(BD()->TexCoord(mt, tr, mft)); | |||
| SetCurVertTexCoord2(BD()->TexCoord2(mt, tr, mft)); | |||
| 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); | |||
| } | |||
| @@ -981,7 +969,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float d10, float d20, | |||
| { | |||
| int d = n / 3; | |||
| int e = d % 6; | |||
| InternalAddVertex(p[d]); | |||
| AddVertex(p[d]); | |||
| if (n % 3 == 0) //Top-Bottom logic | |||
| { | |||
| 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; | |||
| int l = -4; | |||
| 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 + 2] + m[l + 2] * 3 + a[l + 2], | |||
| 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; | |||
| for (int i = 0; i < vlen; i++) | |||
| AddDuplicateVertex(m_cursors.Last().m1++); | |||
| AddDupVertex(m_cursors.Last().m1++); | |||
| for (int i = 0; i < tlen; i++) | |||
| 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); | |||
| } | |||
| //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 | |||
| m_indices[i + 1] = vbase; | |||
| m_indices[i + 2] = vbase + 2; | |||
| @@ -103,6 +103,9 @@ | |||
| <ClCompile Include="easymesh\csgbsp.cpp" /> | |||
| <ClCompile Include="easymesh\easymesh.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\easymeshrender.cpp" /> | |||
| <ClCompile Include="easymesh\easymeshtransform.cpp" /> | |||
| @@ -394,6 +394,15 @@ | |||
| <ClCompile Include="easymesh\easymeshtransform.cpp"> | |||
| <Filter>easymesh</Filter> | |||
| </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> | |||
| <ClInclude Include="debug\fps.h"> | |||