From 73cafd5c3104bea9eac0952d724448308dfea836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Benjamin=20=E2=80=98Touky=E2=80=99=20Huet?= Date: Sat, 28 Feb 2015 18:35:55 +0000 Subject: [PATCH] 2nd EasyMesh split pass --- src/Makefile.am | 6 +- src/easymesh/easymesh.cpp | 986 +++-------------------------- src/easymesh/easymesh.h | 28 +- src/easymesh/easymeshcsg.cpp | 221 +++++++ src/easymesh/easymeshcursor.cpp | 183 ++++++ src/easymesh/easymeshinternal.cpp | 505 +++++++++++++++ src/easymesh/easymeshprimitive.cpp | 158 +++-- src/easymesh/easymeshtransform.cpp | 8 +- src/lolcore.vcxproj | 3 + src/lolcore.vcxproj.filters | 9 + 10 files changed, 1086 insertions(+), 1021 deletions(-) create mode 100644 src/easymesh/easymeshcsg.cpp create mode 100644 src/easymesh/easymeshcursor.cpp create mode 100644 src/easymesh/easymeshinternal.cpp diff --git a/src/Makefile.am b/src/Makefile.am index 2d45ba39..cf374032 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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 \ diff --git a/src/easymesh/easymesh.cpp b/src/easymesh/easymesh.cpp index da2745f7..a42bd280 100644 --- a/src/easymesh/easymesh.cpp +++ b/src/easymesh/easymesh.cpp @@ -63,51 +63,6 @@ bool EasyMesh::Compile(char const *command, bool Execute) return res; } -void EasyMesh::MeshConvert() -{ - /* Default material */ - Shader *shader = Shader::Create(LOLFX_RESOURCE_NAME(shiny)); - - /* Push index buffer to GPU */ - IndexBuffer *ibo = new IndexBuffer(m_indices.Count() * sizeof(uint16_t)); - uint16_t *indices = (uint16_t *)ibo->Lock(0, 0); - for (int i = 0; i < m_indices.Count(); ++i) - indices[i] = m_indices[i]; - ibo->Unlock(); - - /* Push vertex buffer to GPU */ - struct Vertex - { - vec3 pos, normal; - u8vec4 color; - vec4 texcoord; - }; - - VertexDeclaration *vdecl = new VertexDeclaration( - VertexStream(VertexUsage::Position, - VertexUsage::Normal, - VertexUsage::Color, - VertexUsage::TexCoord)); - - VertexBuffer *vbo = new VertexBuffer(m_vert.Count() * sizeof(Vertex)); - Vertex *vert = (Vertex *)vbo->Lock(0, 0); - for (int i = 0; i < m_vert.Count(); ++i) - { - vert[i].pos = m_vert[i].m_coord, - vert[i].normal = m_vert[i].m_normal, - vert[i].color = (u8vec4)(m_vert[i].m_color * 255.f); - vert[i].texcoord = m_vert[i].m_texcoord; - } - vbo->Unlock(); - - /* Reference our new data in our submesh */ - m_submeshes.Push(new SubMesh(shader, vdecl)); - m_submeshes.Last()->SetIndexBuffer(ibo); - m_submeshes.Last()->SetVertexBuffer(0, vbo); - - m_state = MeshRender::CanRender; -} - //----------------------------------------------------------------------------- #define EZSET(M0) BD()->CmdStack().GetValue(M0); #define EZDEF_1(T0) T0 m0; EZSET(m0) @@ -136,14 +91,14 @@ void EasyMesh::MeshConvert() //---- #define EZM_CALL_FUNC(...) \ - LOL_CALL(LOL_CAT(EZCALL_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)) + LOL_CALL(LOL_CAT(EZCALL_, LOL_CALL(LOL_COUNT_TO_12, (__VA_ARGS__))), (__VA_ARGS__)) //----------------------------------------------------------------------------- void EasyMesh::ExecuteCmdStack(bool ExecAllStack) { #define DO_EXEC_CMD(MESH_CMD, FUNC_PARAMS) \ case EasyMeshCmdType::MESH_CMD: \ - { EZM_CALL_FUNC FUNC_PARAMS; break; } + { EZM_CALL_FUNC FUNC_PARAMS; break; } BD()->Enable(MeshBuildOperation::CommandExecution); if (ExecAllStack) @@ -156,41 +111,41 @@ void EasyMesh::ExecuteCmdStack(bool ExecAllStack) switch (BD()->CmdStack().GetCmd(BD()->Cmdi())) { - DO_EXEC_CMD(MeshCsg, (MeshCsg, CSGUsage)) - DO_EXEC_CMD(LoopStart, (LoopStart, int)) - DO_EXEC_CMD(LoopEnd, (LoopEnd)) - DO_EXEC_CMD(OpenBrace, (OpenBrace)) - DO_EXEC_CMD(CloseBrace, (CloseBrace)) - DO_EXEC_CMD(ScaleWinding, (ToggleScaleWinding)) - DO_EXEC_CMD(QuadWeighting, (ToggleQuadWeighting)) - DO_EXEC_CMD(PostBuildNormal, (TogglePostBuildNormal)) - DO_EXEC_CMD(PreventVertCleanup, (ToggleVerticeNoCleanup)) - DO_EXEC_CMD(VerticesMerge, (VerticesMerge)) - DO_EXEC_CMD(VerticesSeparate, (VerticesSeparate)) - DO_EXEC_CMD(SetColorA, (SetCurColorA, vec4)) - DO_EXEC_CMD(SetColorB, (SetCurColorB, vec4)) - DO_EXEC_CMD(SetVertColor, (SetVertColor, vec4)) - DO_EXEC_CMD(Translate, (Translate, vec3)) - DO_EXEC_CMD(Rotate, (Rotate, float, vec3)) - DO_EXEC_CMD(RadialJitter, (RadialJitter, float)) - DO_EXEC_CMD(MeshTranform, (DoMeshTransform, MeshTransform, Axis, Axis, float, float, float, bool)) - DO_EXEC_CMD(Scale, (Scale, vec3)) - DO_EXEC_CMD(DupAndScale, (DupAndScale, vec3, bool)) - DO_EXEC_CMD(Chamfer, (Chamfer, float)) - DO_EXEC_CMD(SplitTriangles, (SplitTriangles, int)) - DO_EXEC_CMD(SmoothMesh, (SmoothMesh, int, int, int)) - DO_EXEC_CMD(AppendCylinder, (AppendCylinder, int, float, float, float, bool, bool, bool)) - DO_EXEC_CMD(AppendCapsule, (AppendCapsule, int, float, float)) - DO_EXEC_CMD(AppendTorus, (AppendTorus, int, float, float)) - DO_EXEC_CMD(AppendBox, (AppendBox, vec3, float, bool)) - DO_EXEC_CMD(AppendStar, (AppendStar, int, float, float, bool, bool)) - DO_EXEC_CMD(AppendExpandedStar, (AppendExpandedStar, int, float, float, float)) - DO_EXEC_CMD(AppendDisc, (AppendDisc, int, float, bool)) - DO_EXEC_CMD(AppendSimpleTriangle, (AppendSimpleTriangle, float, bool)) - DO_EXEC_CMD(AppendSimpleQuad, (AppendSimpleQuad, vec2, vec2, float, bool)) - DO_EXEC_CMD(AppendCog, (AppendCog, int, float, float, float, float, float, float, float, float, bool)) - default: - ASSERT(0, "Unknown command pseudo bytecode"); + DO_EXEC_CMD(MeshCsg, (MeshCsg, CSGUsage)) + DO_EXEC_CMD(LoopStart, (LoopStart, int)) + DO_EXEC_CMD(LoopEnd, (LoopEnd)) + DO_EXEC_CMD(OpenBrace, (OpenBrace)) + DO_EXEC_CMD(CloseBrace, (CloseBrace)) + DO_EXEC_CMD(ScaleWinding, (ToggleScaleWinding)) + DO_EXEC_CMD(QuadWeighting, (ToggleQuadWeighting)) + DO_EXEC_CMD(PostBuildNormal, (TogglePostBuildNormal)) + DO_EXEC_CMD(PreventVertCleanup, (ToggleVerticeNoCleanup)) + DO_EXEC_CMD(VerticesMerge, (VerticesMerge)) + DO_EXEC_CMD(VerticesSeparate, (VerticesSeparate)) + DO_EXEC_CMD(SetColorA, (SetCurColorA, vec4)) + DO_EXEC_CMD(SetColorB, (SetCurColorB, vec4)) + DO_EXEC_CMD(SetVertColor, (SetVertColor, vec4)) + DO_EXEC_CMD(Translate, (Translate, vec3)) + DO_EXEC_CMD(Rotate, (Rotate, float, vec3)) + DO_EXEC_CMD(RadialJitter, (RadialJitter, float)) + DO_EXEC_CMD(MeshTranform, (DoMeshTransform, MeshTransform, Axis, Axis, float, float, float, bool)) + DO_EXEC_CMD(Scale, (Scale, vec3)) + DO_EXEC_CMD(DupAndScale, (DupAndScale, vec3, bool)) + DO_EXEC_CMD(Chamfer, (Chamfer, float)) + DO_EXEC_CMD(SplitTriangles, (SplitTriangles, int)) + DO_EXEC_CMD(SmoothMesh, (SmoothMesh, int, int, int)) + DO_EXEC_CMD(AppendCylinder, (AppendCylinder, int, float, float, float, bool, bool, bool)) + DO_EXEC_CMD(AppendCapsule, (AppendCapsule, int, float, float)) + DO_EXEC_CMD(AppendTorus, (AppendTorus, int, float, float)) + DO_EXEC_CMD(AppendBox, (AppendBox, vec3, float, bool)) + DO_EXEC_CMD(AppendStar, (AppendStar, int, float, float, bool, bool)) + DO_EXEC_CMD(AppendExpandedStar, (AppendExpandedStar, int, float, float, float)) + DO_EXEC_CMD(AppendDisc, (AppendDisc, int, float, bool)) + DO_EXEC_CMD(AppendSimpleTriangle, (AppendSimpleTriangle, float, bool)) + DO_EXEC_CMD(AppendSimpleQuad, (AppendSimpleQuad, vec2, vec2, float, bool)) + DO_EXEC_CMD(AppendCog, (AppendCog, int, float, float, float, float, float, float, float, float, bool)) + default: + ASSERT(0, "Unknown command pseudo bytecode"); } } BD()->Disable(MeshBuildOperation::CommandExecution); @@ -209,68 +164,49 @@ void EasyMesh::ExecuteCmdStack(bool ExecAllStack) } //----------------------------------------------------------------------------- -void EasyMesh::LoopStart(int loopnb) +void EasyMesh::MeshConvert() { - 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); - } -} + /* Default material */ + Shader *shader = Shader::Create(LOLFX_RESOURCE_NAME(shiny)); -//----------------------------------------------------------------------------- -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(); - } - } -} + /* Push index buffer to GPU */ + IndexBuffer *ibo = new IndexBuffer(m_indices.Count() * sizeof(uint16_t)); + uint16_t *indices = (uint16_t *)ibo->Lock(0, 0); + for (int i = 0; i < m_indices.Count(); ++i) + indices[i] = m_indices[i]; + ibo->Unlock(); -//----------------------------------------------------------------------------- -void EasyMesh::OpenBrace() -{ - if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) + /* Push vertex buffer to GPU */ + struct Vertex { - BD()->CmdStack().AddCmd(EasyMeshCmdType::OpenBrace); - return; - } + vec3 pos, normal; + u8vec4 color; + vec4 texcoord; + }; - m_cursors.Push((int)m_vert.Count(), (int)m_indices.Count()); -} + VertexDeclaration *vdecl = new VertexDeclaration( + VertexStream(VertexUsage::Position, + VertexUsage::Normal, + VertexUsage::Color, + VertexUsage::TexCoord)); -//----------------------------------------------------------------------------- -void EasyMesh::CloseBrace() -{ - if (BD()->IsEnabled(MeshBuildOperation::CommandRecording)) + VertexBuffer *vbo = new VertexBuffer(m_vert.Count() * sizeof(Vertex)); + Vertex *vert = (Vertex *)vbo->Lock(0, 0); + for (int i = 0; i < m_vert.Count(); ++i) { - BD()->CmdStack().AddCmd(EasyMeshCmdType::CloseBrace); - return; + vert[i].pos = m_vert[i].m_coord, + vert[i].normal = m_vert[i].m_normal, + vert[i].color = (u8vec4)(m_vert[i].m_color * 255.f); + vert[i].texcoord = m_vert[i].m_texcoord; } + vbo->Unlock(); + + /* Reference our new data in our submesh */ + m_submeshes.Push(new SubMesh(shader, vdecl)); + m_submeshes.Last()->SetIndexBuffer(ibo); + m_submeshes.Last()->SetVertexBuffer(0, vbo); - m_cursors.Pop(); + m_state = MeshRender::CanRender; } //----------------------------------------------------------------------------- @@ -291,784 +227,4 @@ bool EasyMesh::SetRender(bool should_render) return false; } -//------------------- -//Mesh Cursor operations -//------------------- - -//----------------------------------------------------------------------------- -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. > - array< int, array< vec3, vec3, vec3 > > triangle_isec; - //keep a track of the intersection point on the triangle. - 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); - - InternalAddVertex(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)); - InternalAddTriangle(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++) - { - AddDuplicateVertex(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 ! -} - -//----------------------------------------------------------------------------- -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; -} - -//----------------------------------------------------------------------------- -void EasyMesh::InternalAddVertex(vec3 const &coord) -{ - m_vert.Push(VertexData(coord, vec3(0.f, 1.f, 0.f), BD()->ColorA())); - m_state = MeshRender::NeedConvert; -} - -//----------------------------------------------------------------------------- -void EasyMesh::AddDuplicateVertex(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::InternalAddQuad(int i1, int i2, int i3, int i4, int base) -{ - 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 << base + i1; - m_indices << base + i2; - m_indices << base + i3; - - m_indices << base + i4; - m_indices << base + i1; - m_indices << base + i3; - } -} - -//----------------------------------------------------------------------------- -void EasyMesh::InternalAddQuadDupVerts(int i1, int i2, int i3, int i4, int base) -{ - int vbase = (int)m_vert.Count(); - AddDuplicateVertex(base + i1); - AddDuplicateVertex(base + i2); - AddDuplicateVertex(base + i3); - AddDuplicateVertex(base + i4); - - InternalAddQuad(0, 1, 2, 3, vbase); -} - -//----------------------------------------------------------------------------- -void EasyMesh::InternalAddTriangle(int i1, int i2, int i3, int base) -{ - m_indices << base + i1; - m_indices << base + i2; - m_indices << base + i3; -} - -//----------------------------------------------------------------------------- -void EasyMesh::InternalAddTriangleDupVerts(int i1, int i2, int i3, int base) -{ - m_indices << (uint16_t)m_vert.Count(); AddDuplicateVertex(base + i1); - m_indices << (uint16_t)m_vert.Count(); AddDuplicateVertex(base + i2); - m_indices << (uint16_t)m_vert.Count(); AddDuplicateVertex(base + i3); -} - -//----------------------------------------------------------------------------- -void EasyMesh::ComputeNormals(int start, int vcount) -{ - - if (BD()->IsEnabled(MeshBuildOperation::CommandExecution) && - BD()->IsEnabled(MeshBuildOperation::PostBuildComputeNormals)) - return; - - array< array > 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 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 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 > new_ids; - array 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(); - AddDuplicateVertex(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 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 tri_done; - array 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 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 */ diff --git a/src/easymesh/easymesh.h b/src/easymesh/easymesh.h index 7429b0cb..e7fa6d0f 100644 --- a/src/easymesh/easymesh.h +++ b/src/easymesh/easymesh.h @@ -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 */ diff --git a/src/easymesh/easymeshcsg.cpp b/src/easymesh/easymeshcsg.cpp new file mode 100644 index 00000000..4f2939bf --- /dev/null +++ b/src/easymesh/easymeshcsg.cpp @@ -0,0 +1,221 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2015 Sam Hocevar +// (c) 2009-2015 Cédric Lecacheur +// (c) 2009-2015 Benjamin "Touky" Huet +// 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 + +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. > + array< int, array< vec3, vec3, vec3 > > triangle_isec; + //keep a track of the intersection point on the triangle. + 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 */ diff --git a/src/easymesh/easymeshcursor.cpp b/src/easymesh/easymeshcursor.cpp new file mode 100644 index 00000000..d799e4be --- /dev/null +++ b/src/easymesh/easymeshcursor.cpp @@ -0,0 +1,183 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2015 Sam Hocevar +// (c) 2009-2015 Cédric Lecacheur +// (c) 2009-2015 Benjamin "Touky" Huet +// 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 + +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 */ diff --git a/src/easymesh/easymeshinternal.cpp b/src/easymesh/easymeshinternal.cpp new file mode 100644 index 00000000..cfd99547 --- /dev/null +++ b/src/easymesh/easymeshinternal.cpp @@ -0,0 +1,505 @@ +// +// Lol Engine +// +// Copyright: (c) 2010-2015 Sam Hocevar +// (c) 2009-2015 Cédric Lecacheur +// (c) 2009-2015 Benjamin "Touky" Huet +// 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 + +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 > 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 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 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 > new_ids; + array 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 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 tri_done; + array 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 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 */ diff --git a/src/easymesh/easymeshprimitive.cpp b/src/easymesh/easymeshprimitive.cpp index 0f2552bf..65042856 100644 --- a/src/easymesh/easymeshprimitive.cpp +++ b/src/easymesh/easymeshprimitive.cpp @@ -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], diff --git a/src/easymesh/easymeshtransform.cpp b/src/easymesh/easymeshtransform.cpp index 1afd9072..b5a33b9b 100644 --- a/src/easymesh/easymeshtransform.cpp +++ b/src/easymesh/easymeshtransform.cpp @@ -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; diff --git a/src/lolcore.vcxproj b/src/lolcore.vcxproj index 38f9cd64..a44c2ecc 100644 --- a/src/lolcore.vcxproj +++ b/src/lolcore.vcxproj @@ -103,6 +103,9 @@ + + + diff --git a/src/lolcore.vcxproj.filters b/src/lolcore.vcxproj.filters index 1a427f03..cb61293e 100644 --- a/src/lolcore.vcxproj.filters +++ b/src/lolcore.vcxproj.filters @@ -394,6 +394,15 @@ easymesh + + easymesh + + + easymesh + + + easymesh +