Browse Source

2nd EasyMesh split pass

undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 9 years ago
parent
commit
73cafd5c31
10 changed files with 1086 additions and 1021 deletions
  1. +4
    -2
      src/Makefile.am
  2. +71
    -915
      src/easymesh/easymesh.cpp
  3. +13
    -15
      src/easymesh/easymesh.h
  4. +221
    -0
      src/easymesh/easymeshcsg.cpp
  5. +183
    -0
      src/easymesh/easymeshcursor.cpp
  6. +505
    -0
      src/easymesh/easymeshinternal.cpp
  7. +73
    -85
      src/easymesh/easymeshprimitive.cpp
  8. +4
    -4
      src/easymesh/easymeshtransform.cpp
  9. +3
    -0
      src/lolcore.vcxproj
  10. +9
    -0
      src/lolcore.vcxproj.filters

+ 4
- 2
src/Makefile.am View File

@@ -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 \


+ 71
- 915
src/easymesh/easymesh.cpp
File diff suppressed because it is too large
View File


+ 13
- 15
src/easymesh/easymesh.h View File

@@ -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 */


+ 221
- 0
src/easymesh/easymeshcsg.cpp View File

@@ -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 */

+ 183
- 0
src/easymesh/easymeshcursor.cpp View File

@@ -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 */

+ 505
- 0
src/easymesh/easymeshinternal.cpp View File

@@ -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 */

+ 73
- 85
src/easymesh/easymeshprimitive.cpp View File

@@ -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],


+ 4
- 4
src/easymesh/easymeshtransform.cpp View File

@@ -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;


+ 3
- 0
src/lolcore.vcxproj View File

@@ -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" />


+ 9
- 0
src/lolcore.vcxproj.filters View File

@@ -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">


Loading…
Cancel
Save