瀏覽代碼

Added VertexDictionnary object to manage vertices with same coord && connected vertices.

Added UVs system with and UVs generation test (not very conclusive)
legacy
Benjamin ‘Touky’ Huet touky 13 年之前
父節點
當前提交
e4cf8211e4
共有 9 個檔案被更改,包括 711 行新增289 行删除
  1. +398
    -205
      src/easymesh/easymesh.cpp
  2. +64
    -4
      src/easymesh/easymesh.h
  3. +6
    -0
      src/easymesh/shiny.lolfx
  4. +5
    -76
      src/easymesh/shinydebugUV.lolfx
  5. +5
    -2
      src/video.cpp
  6. +36
    -1
      test/MeshViewer.cpp
  7. +3
    -0
      test/MeshViewer.vcxproj
  8. +11
    -1
      test/MeshViewerBuffer.txt
  9. +183
    -0
      test/shinyfur.lolfx

+ 398
- 205
src/easymesh/easymesh.cpp 查看文件

@@ -45,28 +45,33 @@ LOLFX_RESOURCE_DECLARE(shiny_SK);
namespace lol namespace lol
{ {


//-----------------------------------------------------------------------------
EasyMesh::EasyMesh() EasyMesh::EasyMesh()
: m_color(0), m_color2(0), m_ignore_winding_on_scale(0) : m_color(0), m_color2(0), m_ignore_winding_on_scale(0)
{ {
m_cursors.Push(0, 0); m_cursors.Push(0, 0);
} }


//-----------------------------------------------------------------------------
bool EasyMesh::Compile(char const *command) bool EasyMesh::Compile(char const *command)
{ {
EasyMeshCompiler mc(*this); EasyMeshCompiler mc(*this);
return mc.ParseString(command); return mc.ParseString(command);
} }


//-----------------------------------------------------------------------------
void EasyMesh::OpenBrace() void EasyMesh::OpenBrace()
{ {
m_cursors.Push(m_vert.Count(), m_indices.Count()); m_cursors.Push(m_vert.Count(), m_indices.Count());
} }


//-----------------------------------------------------------------------------
void EasyMesh::CloseBrace() void EasyMesh::CloseBrace()
{ {
m_cursors.Pop(); m_cursors.Pop();
} }


//-----------------------------------------------------------------------------
void EasyMesh::MeshConvert(Shader* provided_shader) void EasyMesh::MeshConvert(Shader* provided_shader)
{ {
for (int i = 0; i < DebugRenderMode::Max; i++) for (int i = 0; i < DebugRenderMode::Max; i++)
@@ -88,6 +93,7 @@ void EasyMesh::MeshConvert(Shader* provided_shader)
m_gpu.shader << Shader::Create(LOLFX_RESOURCE_NAME(shinydebugUV)); m_gpu.shader << Shader::Create(LOLFX_RESOURCE_NAME(shinydebugUV));


m_gpu.modelview << m_gpu.shader.Last()->GetUniformLocation("in_ModelView"); m_gpu.modelview << m_gpu.shader.Last()->GetUniformLocation("in_ModelView");
m_gpu.invmodelview << m_gpu.shader.Last()->GetUniformLocation("in_Inv_ModelView");
m_gpu.view << m_gpu.shader.Last()->GetUniformLocation("in_View"); m_gpu.view << m_gpu.shader.Last()->GetUniformLocation("in_View");
m_gpu.invview << m_gpu.shader.Last()->GetUniformLocation("in_Inv_View"); m_gpu.invview << m_gpu.shader.Last()->GetUniformLocation("in_Inv_View");
m_gpu.proj << m_gpu.shader.Last()->GetUniformLocation("in_Proj"); m_gpu.proj << m_gpu.shader.Last()->GetUniformLocation("in_Proj");
@@ -95,23 +101,49 @@ void EasyMesh::MeshConvert(Shader* provided_shader)
m_gpu.damage << m_gpu.shader.Last()->GetUniformLocation("in_Damage"); m_gpu.damage << m_gpu.shader.Last()->GetUniformLocation("in_Damage");
m_gpu.lights << m_gpu.shader.Last()->GetUniformLocation("u_Lights"); m_gpu.lights << m_gpu.shader.Last()->GetUniformLocation("u_Lights");
m_gpu.coord << m_gpu.shader.Last()->GetAttribLocation("in_Vertex", m_gpu.coord << m_gpu.shader.Last()->GetAttribLocation("in_Vertex",
VertexUsage::Position, 0);
VertexUsage::Position, 0);
m_gpu.norm << m_gpu.shader.Last()->GetAttribLocation("in_Normal", m_gpu.norm << m_gpu.shader.Last()->GetAttribLocation("in_Normal",
VertexUsage::Normal, 0); VertexUsage::Normal, 0);
m_gpu.color << m_gpu.shader.Last()->GetAttribLocation("in_Color", m_gpu.color << m_gpu.shader.Last()->GetAttribLocation("in_Color",
VertexUsage::Color, 0);
VertexUsage::Color, 0);
#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
#elif VERTEX_USEAGE == VU_TEX_UV
//UV SUPPORT --
m_gpu.tex_coord << m_gpu.shader.Last()->GetAttribLocation("in_TexCoord",
VertexUsage::TexCoord, 0);
#endif
} }


#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
#elif VERTEX_USEAGE == VU_TEX_UV
//UV SUPPORT --
m_gpu.vdecl = new VertexDeclaration(
VertexStream<vec3,vec3,u8vec4,vec2>(VertexUsage::Position,
VertexUsage::Normal,
VertexUsage::Color,
VertexUsage::TexCoord));

Array<vec3,vec3,u8vec4,vec2> vertexlist;
for (int i = 0; i < m_vert.Count(); i++)
vertexlist.Push(m_vert[i].m1,
m_vert[i].m2,
(u8vec4)(m_vert[i].m3 * 255.f),
m_vert[i].m4);
#else
//-- VANILLA --
m_gpu.vdecl = new VertexDeclaration( m_gpu.vdecl = new VertexDeclaration(
VertexStream<vec3,vec3,u8vec4>(VertexUsage::Position, VertexStream<vec3,vec3,u8vec4>(VertexUsage::Position,
VertexUsage::Normal,
VertexUsage::Color));
VertexUsage::Normal,
VertexUsage::Color));


Array<vec3,vec3,u8vec4> vertexlist; Array<vec3,vec3,u8vec4> vertexlist;
for (int i = 0; i < m_vert.Count(); i++) for (int i = 0; i < m_vert.Count(); i++)
vertexlist.Push(m_vert[i].m1, vertexlist.Push(m_vert[i].m1,
m_vert[i].m2, m_vert[i].m2,
(u8vec4)(m_vert[i].m3 * 255.f)); (u8vec4)(m_vert[i].m3 * 255.f));
#endif


Array<uint16_t> indexlist; Array<uint16_t> indexlist;
for (int i = 0; i < m_indices.Count(); i += 3) for (int i = 0; i < m_indices.Count(); i += 3)
@@ -135,6 +167,7 @@ void EasyMesh::MeshConvert(Shader* provided_shader)
m_gpu.indexcount = indexlist.Count(); m_gpu.indexcount = indexlist.Count();
} }


//-----------------------------------------------------------------------------
void EasyMesh::Render(mat4 const &model, float damage) void EasyMesh::Render(mat4 const &model, float damage)
{ {
DebugRenderMode d = Video::GetDebugRenderMode(); DebugRenderMode d = Video::GetDebugRenderMode();
@@ -155,13 +188,22 @@ void EasyMesh::Render(mat4 const &model, float damage)
m_gpu.shader[d]->SetUniform(m_gpu.lights[d], light_data); m_gpu.shader[d]->SetUniform(m_gpu.lights[d], light_data);


m_gpu.shader[d]->SetUniform(m_gpu.modelview[d], modelview); m_gpu.shader[d]->SetUniform(m_gpu.modelview[d], modelview);
m_gpu.shader[d]->SetUniform(m_gpu.invmodelview[d], inverse(modelview));
m_gpu.shader[d]->SetUniform(m_gpu.view[d], Scene::GetDefault()->GetViewMatrix()); m_gpu.shader[d]->SetUniform(m_gpu.view[d], Scene::GetDefault()->GetViewMatrix());
m_gpu.shader[d]->SetUniform(m_gpu.invview[d], inverse(Scene::GetDefault()->GetViewMatrix())); m_gpu.shader[d]->SetUniform(m_gpu.invview[d], inverse(Scene::GetDefault()->GetViewMatrix()));
m_gpu.shader[d]->SetUniform(m_gpu.proj[d], Scene::GetDefault()->GetProjMatrix()); m_gpu.shader[d]->SetUniform(m_gpu.proj[d], Scene::GetDefault()->GetProjMatrix());
m_gpu.shader[d]->SetUniform(m_gpu.normalmat[d], normalmat); m_gpu.shader[d]->SetUniform(m_gpu.normalmat[d], normalmat);
m_gpu.shader[d]->SetUniform(m_gpu.damage[d], damage); m_gpu.shader[d]->SetUniform(m_gpu.damage[d], damage);
m_gpu.vdecl->Bind(); m_gpu.vdecl->Bind();
#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
#elif VERTEX_USEAGE == VU_TEX_UV
//UV SUPPORT --
m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord[d], m_gpu.norm[d], m_gpu.color[d], m_gpu.tex_coord[d]);
#else
//-- VANILLA --
m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord[d], m_gpu.norm[d], m_gpu.color[d]); m_gpu.vdecl->SetStream(m_gpu.vbo, m_gpu.coord[d], m_gpu.norm[d], m_gpu.color[d]);
#endif
m_gpu.ibo->Bind(); m_gpu.ibo->Bind();
m_gpu.vdecl->DrawIndexedElements(MeshPrimitive::Triangles, m_gpu.vdecl->DrawIndexedElements(MeshPrimitive::Triangles,
0, 0, m_gpu.vertexcount, 0, 0, m_gpu.vertexcount,
@@ -170,60 +212,162 @@ void EasyMesh::Render(mat4 const &model, float damage)
m_gpu.vdecl->Unbind(); m_gpu.vdecl->Unbind();
} }



//------------------- //-------------------
// "Collisions" functions // "Collisions" functions
//------------------- //-------------------
#define VX_ALONE -2 #define VX_ALONE -2
#define VX_MASTER -1 #define VX_MASTER -1


//-----------------------------------------------------------------------------
//helpers func to retrieve a vertex. //helpers func to retrieve a vertex.
int FindVertexInDict(int search_idx, Array< int, int > const &vertex_dict)
int VertexDictionnary::FindVertexMaster(const int search_idx)
{ {
//Resolve current vertex idx in the dictionnary (if exist) //Resolve current vertex idx in the dictionnary (if exist)
for (int j = 0; j < vertex_dict.Count(); j++)
if (vertex_dict[j].m1 == search_idx)
return j;
return -1;
for (int j = 0; j < vertex_list.Count(); j++)
if (vertex_list[j].m1 == search_idx)
return vertex_list[j].m3;
return VDictType::DoesNotExist;
} }


//helpers func to retrieve a triangle.
int FindTriangleInDict(int search_idx, Array< int, Array< vec3, vec3, vec3 > > const &triangle_isec)
//-----------------------------------------------------------------------------
//retrieve a list of matching vertices, doesn't include search_idx.
bool VertexDictionnary::FindMatchingVertices(const int search_idx, Array<int> &matching_ids)
{ {
//Resolve current vertex idx in the dictionnary (if exist)
for (int j = 0; j < triangle_isec.Count(); j++)
if (triangle_isec[j].m1 == search_idx)
return j;
return -1;
int cur_mast = FindVertexMaster(search_idx);

if (cur_mast == VDictType::DoesNotExist || cur_mast == VDictType::Alone)
return false;

if (cur_mast == VDictType::Master)
cur_mast = search_idx;
else
matching_ids << vertex_list[cur_mast].m1;

for (int j = 0; j < vertex_list.Count(); j++)
if (vertex_list[j].m3 == cur_mast && vertex_list[j].m1 != search_idx)
matching_ids << vertex_list[cur_mast].m1;

return (matching_ids.Count() > 0);
} }


//-----------------------------------------------------------------------------
//Will return connected vertices (through triangles), if returned vertex has matching ones, it only returns the master.
bool VertexDictionnary::FindConnectedVertices(const int search_idx, const Array<int> &tri_list, Array<int> &connected_vert, Array<int> const *ignored_tri)
{
Array<int> connected_tri;
FindConnectedTriangles(search_idx, tri_list, connected_tri, ignored_tri);

for (int i = 0; i < connected_tri.Count(); i++)
{
for (int j = 0; j < 3; j++)
{
int v_indice = tri_list[connected_tri[j] + j];
if (v_indice != search_idx)
{
int found_master = FindVertexMaster(tri_list[connected_tri[j] + j]);
if (found_master == VDictType::Alone || found_master == VDictType::Master)
connected_vert << v_indice;
else
connected_vert << found_master;
}
}
}
return (connected_vert.Count() > 0);
}
//-----------------------------------------------------------------------------
bool VertexDictionnary::FindConnectedTriangles(const int search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
{
return FindConnectedTriangles(ivec3(search_idx, search_idx, search_idx), tri_list, connected_tri, ignored_tri);
}
//-----------------------------------------------------------------------------
bool VertexDictionnary::FindConnectedTriangles(const ivec2 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
{
return FindConnectedTriangles(ivec3(search_idx, search_idx.x), tri_list, connected_tri, ignored_tri);
}
//-----------------------------------------------------------------------------
bool VertexDictionnary::FindConnectedTriangles(const ivec3 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri)
{
int needed_validation = 0;
Array<int> vert_list[3];
for (int i = 0; i < 3; i++)
{
//Small optim since above func will use this one
if ((i == 1 && search_idx[0] == search_idx[1]) ||
(i == 2 && (search_idx[0] == search_idx[2] || search_idx[1] == search_idx[2])))
continue;
else
{
//increment the validation info, hence empty list aren't taken into account.
needed_validation++;
vert_list[i] << search_idx[i];
FindMatchingVertices(search_idx[i], vert_list[i]);
}
}

for (int i = 0; i < tri_list.Count(); i += 3)
{
if (ignored_tri)
{
bool should_pass = false;
for (int j = 0; !should_pass && j < ignored_tri->Count(); j++)
if ((*ignored_tri)[j] == i)
should_pass = true;
if (should_pass)
continue;
}
int found_validation = 0;
for (int j = 0; j < 3; j++)
{
bool validated = false;
for (int k = 0; !validated && k < vert_list[j].Count(); k++)
for (int l = 0; !validated && l < 3; l++)
if (vert_list[j][k] == tri_list[i + l])
validated = true;
found_validation += (validated)?(1):(0);
}
//triangle is validated store it
if (found_validation == needed_validation)
connected_tri << i;
}

return (connected_tri.Count() > 0);
}

//-----------------------------------------------------------------------------
//Will update the given list with all the vertices on the same spot. //Will update the given list with all the vertices on the same spot.
void EasyMesh::UpdateVertexDict(Array< int, int > &vertex_dict)
void VertexDictionnary::AddVertex(const int vert_id, const vec3 vert_coord)
{ {
for (int j = 0; j < vertex_list.Count(); j++)
if (vertex_list[j].m1 == vert_id)
return;

//First, build the vertex Dictionnary //First, build the vertex Dictionnary
for (int i = 0; i < m_vert.Count(); i++)
int i = 0;
for (; i < master_list.Count(); i++)
{ {
int CurIdx = FindVertexInDict(i, vertex_dict);
int cur_mast = master_list[i];
int cur_id = vertex_list[cur_mast].m1;
vec3 cur_loc = vertex_list[cur_mast].m2;
int &cur_type = vertex_list[cur_mast].m3;


//go through all vertices and do the match-up.
if (CurIdx == -1)
if (cur_id == vert_id)
return;

if (sqlength(cur_loc - vert_coord) < CSG_EPSILON)
{ {
for (int j = i + 1; j < m_vert.Count(); j++)
{
if (sqlength(m_vert[i].m1 - m_vert[j].m1) < CSG_EPSILON)
{
if (CurIdx == -1)
{
CurIdx = vertex_dict.Count();
vertex_dict.Push(i, VX_MASTER);
}
vertex_dict.Push(j, CurIdx);
}
}
if (cur_type == VDictType::Alone)
cur_type = VDictType::Master;
vertex_list.Push(vert_id, vert_coord, cur_mast);
return;
} }
} }

//We're here because we couldn't find any matching vertex
master_list.Push(vertex_list.Count());
vertex_list.Push(vert_id, vert_coord, VDictType::Alone);
} }


//-----------------------------------------------------------------------------
void EasyMesh::MeshCsg(CSGUsage csg_operation) void EasyMesh::MeshCsg(CSGUsage csg_operation)
{ {
//A vertex dictionnary for vertices on the same spot. //A vertex dictionnary for vertices on the same spot.
@@ -399,206 +543,50 @@ void EasyMesh::MeshCsg(CSGUsage csg_operation)
m_cursors.Last().m1 = m_vert.Count(); m_cursors.Last().m1 = m_vert.Count();
m_cursors.Last().m2 = m_indices.Count(); m_cursors.Last().m2 = m_indices.Count();


#if 0
UpdateVertexDict(vertex_dict);

for (int t0 = 0; t0 < m_indices.Count(); t0 += 3)
{
for (int t1 = t0 + 3; t1 < m_indices.Count(); t1 += 3)
{
int CommonVertices = 0;
//Search for common vertices, if > 1 the two triangle share a side, so no split is required.
for (int k = 0; k < 3; k++)
{
int ref_master = FindVertexInDict(m_indices[t0 + k], vertex_dict);
if (ref_master != -1)
{
if (vertex_dict[ref_master].m2 != VX_MASTER)
ref_master = vertex_dict[ref_master].m2;
for (int l = 0; l < 3; l++)
{
int test_master = FindVertexInDict(m_indices[t1 + l], vertex_dict);
if (test_master != -1)
{
if (vertex_dict[test_master].m2 != VX_MASTER)
test_master = vertex_dict[test_master].m2;
if (test_master == ref_master)
{
CommonVertices++;
break;
}
}
}
}
}

if (CommonVertices < 2)
{
vec3 iP0, iP1;
//Build the triangle intersection list
if (TriangleIsectTriangle(m_vert[m_indices[t0]].m1, m_vert[m_indices[t0 + 1]].m1, m_vert[m_indices[t0 + 2]].m1,
m_vert[m_indices[t1]].m1, m_vert[m_indices[t1 + 1]].m1, m_vert[m_indices[t1 + 2]].m1,
iP0, iP1))
{
int CurIdx = FindTriangleInDict(t0, triangle_isec);
if (CurIdx == -1)
{
CurIdx = triangle_isec.Count();
triangle_isec.Push(t0, Array<vec3, vec3, vec3>());
}
triangle_isec[CurIdx].m2.Push(iP0, iP1, vec3(.0f));
CurIdx = FindTriangleInDict(t1, triangle_isec);
if (CurIdx == -1)
{
CurIdx = triangle_isec.Count();
triangle_isec.Push(t1, Array<vec3, vec3, vec3>());
}
triangle_isec[CurIdx].m2.Push(iP0, iP1, vec3(.0f));
}
}
}
}

/* seems to be counter-productive in some rare cases. */
/*
//Every intersection has been found, let's remove those that exist twice.
for(int i = 0; i < triangle_isec.Count(); i++)
{
for(int j = 0; j < triangle_isec[i].m2.Count(); j++)
{
for(int k = j + 1; k < triangle_isec[i].m2.Count(); k++)
{
//if the two Dir-vector are parallel & the fist Dir-vector is parallel to the (P0, P1)-vector, this is the same intersection, so kill it.
if (abs(dot(normalize(triangle_isec[i].m2[j].m2 - triangle_isec[i].m2[j].m1),
normalize(triangle_isec[i].m2[k].m2 - triangle_isec[i].m2[k].m1)))
>= 1.0 &&
abs(dot(normalize(triangle_isec[i].m2[j].m2 - triangle_isec[i].m2[j].m1),
normalize(triangle_isec[i].m2[k].m1 - triangle_isec[i].m2[j].m1)))
>= 1.0 )
triangle_isec[i].m2.Remove(k--);
}
}
}
*/

//Now, the triangle intersection tab should be nice and cosy, so we can start actually cutting some triangles.
vec3 isecV[2] = { vec3(.0f), vec3(.0f) };
int isecI[2] = { -1, -1 };
int v_idx0 = 0; int v_idx1 = 0;
int new_v_idx[2] = { 0, 0 };
vec3 n0(.0f); vec3 n1(.0f);
vec4 c0(.0f); vec4 c1(.0f);
for(int i = 0; i < triangle_isec.Count(); i++)
{
int tri_idx = triangle_isec[i].m1;
for(int j = 0; j < triangle_isec[i].m2.Count(); j++)
{
//Get intersection on actual triangle sides.
if (RayIsectTriangleSide(m_vert[m_indices[tri_idx]].m1, m_vert[m_indices[tri_idx + 1]].m1, m_vert[m_indices[tri_idx + 2]].m1,
triangle_isec[i].m2[j].m1, triangle_isec[i].m2[j].m2,
isecV[0], isecI[0], isecV[1], isecI[1]))
{
//Check if the found intersections point are in the triangle. If not, ignore.
//Cases are :
// 1) at least one dot is negative (one point in the triangle).
// 2) the two dot are positive but the intersection point are on all parts of the triangle, and therefore negative.
//If one of the point is on one side, some calculations tweak are needed.
//If the two points are on the triangle sides, just go with it.
bool should_proceed_with_cutting = true;
//find out if points are on one of the side
int p0_tri_idx = ((sqlength(triangle_isec[i].m2[j].m1 - isecV[0]) < CSG_EPSILON)?(0):(
(sqlength(triangle_isec[i].m2[j].m1 - isecV[1]) < CSG_EPSILON)?(1):(-1)));
int p1_tri_idx = ((sqlength(triangle_isec[i].m2[j].m2 - isecV[0]) < CSG_EPSILON)?(0):(
(sqlength(triangle_isec[i].m2[j].m2 - isecV[1]) < CSG_EPSILON)?(1):(-1)));
if (p0_tri_idx < 0 || p1_tri_idx < 0)
{
float dot0 = (p0_tri_idx >= 0)?(1.0f):(dot(triangle_isec[i].m2[j].m1 - isecV[0],
triangle_isec[i].m2[j].m1 - isecV[1]));
float dot1 = (p1_tri_idx >= 0)?(1.0f):(dot(triangle_isec[i].m2[j].m2 - isecV[0],
triangle_isec[i].m2[j].m2 - isecV[1]));
float dot2 = dot(triangle_isec[i].m2[j].m1 - isecV[(p0_tri_idx == -1)?(0):(1 - p0_tri_idx)],
triangle_isec[i].m2[j].m2 - isecV[(p1_tri_idx == -1)?(0):(1 - p1_tri_idx)]);
should_proceed_with_cutting = (((dot0 < .0f) || dot1 < .0f) || (dot0 > .0f && dot1 > .0f && dot2 < .0f));
}
if (should_proceed_with_cutting)
{
//Add the new vertices
int b_idx = 0;
for(int k = 0; k < 2; k++)
{
if (b_idx == isecI[k])
b_idx++;

new_v_idx[k] = m_vert.Count();
AddVertex(isecV[k]);
//bad calculations of normal there.
n0 = m_vert[m_indices[tri_idx + isecI[k]]].m2;
n1 = m_vert[m_indices[tri_idx + (isecI[k] + 1) % 3]].m2;
SetCurVertNormal(normalize((n0 + n1) * .5f));
//color
#if 0
c0 = m_vert[m_indices[tri_idx + isecI[k]]].m3;
c1 = m_vert[m_indices[tri_idx + (isecI[k] + 1) % 3]].m3;
SetCurVertColor((c0 + c1) * .5f);
#else
SetCurVertColor(vec4(1.0f, 0.0f, 0.0f, 1.0f));
#endif
}

//small trick, b_idx is the side index that has no intersection.
v_idx0 = (b_idx == 1)?(1):(0);
v_idx1 = (b_idx == 1)?(0):(1);

//Add the new triangles
AppendTriangle(m_indices[tri_idx + b_idx], new_v_idx[v_idx0], new_v_idx[v_idx1], 0);
AppendTriangle(m_indices[tri_idx + ((b_idx + 2) % 3)], new_v_idx[v_idx1], new_v_idx[v_idx0], 0);
//Replace the current triangle by on of the new one, instead of erasing it.
m_indices[tri_idx + ((b_idx + 2) % 3)] = new_v_idx[v_idx0];

if (j + 1 < triangle_isec[i].m2.Count())
{
triangle_isec[i].m2.Remove(j--);
//add the two new triangle to the checklist.
triangle_isec.Push(m_indices.Count() - 6, triangle_isec[i].m2);
triangle_isec.Push(m_indices.Count() - 3, triangle_isec[i].m2);
}
}
}
}
}
#endif
//DONE for the splitting ! //DONE for the splitting !
} }




//-------------------

//-----------------------------------------------------------------------------
void EasyMesh::ToggleScaleWinding() void EasyMesh::ToggleScaleWinding()
{ {
m_ignore_winding_on_scale = !m_ignore_winding_on_scale; m_ignore_winding_on_scale = !m_ignore_winding_on_scale;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetCurColor(vec4 const &color) void EasyMesh::SetCurColor(vec4 const &color)
{ {
m_color = color; m_color = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetCurColor2(vec4 const &color) void EasyMesh::SetCurColor2(vec4 const &color)
{ {
m_color2 = color; m_color2 = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::AddVertex(vec3 const &coord) void EasyMesh::AddVertex(vec3 const &coord)
{ {
//TODO : m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, ivec2(0), vec2(0));
#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, ivec2(0), vec2(0));
#elif VERTEX_USEAGE == VU_TEX_UV
//-- UV SUPPORT --
m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color, vec2(-1));
#else
//-- VANILLA --
m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color); m_vert.Push(coord, vec3(0.f, 1.f, 0.f), m_color);
#endif
} }


//-----------------------------------------------------------------------------
void EasyMesh::AddDuplicateVertex(int i) void EasyMesh::AddDuplicateVertex(int i)
{ {
m_vert << m_vert[i]; m_vert << m_vert[i];
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendQuad(int i1, int i2, int i3, int i4, int base) void EasyMesh::AppendQuad(int i1, int i2, int i3, int i4, int base)
{ {
m_indices << base + i1; m_indices << base + i1;
@@ -610,6 +598,7 @@ void EasyMesh::AppendQuad(int i1, int i2, int i3, int i4, int base)
m_indices << base + i3; m_indices << base + i3;
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base) void EasyMesh::AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base)
{ {
m_indices << m_vert.Count(); AddDuplicateVertex(base + i1); m_indices << m_vert.Count(); AddDuplicateVertex(base + i1);
@@ -621,6 +610,7 @@ void EasyMesh::AppendQuadDuplicateVerts(int i1, int i2, int i3, int i4, int base
m_indices << m_vert.Count(); AddDuplicateVertex(base + i3); m_indices << m_vert.Count(); AddDuplicateVertex(base + i3);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendTriangle(int i1, int i2, int i3, int base) void EasyMesh::AppendTriangle(int i1, int i2, int i3, int base)
{ {
m_indices << base + i1; m_indices << base + i1;
@@ -628,6 +618,7 @@ void EasyMesh::AppendTriangle(int i1, int i2, int i3, int base)
m_indices << base + i3; m_indices << base + i3;
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base) void EasyMesh::AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
{ {
m_indices << m_vert.Count(); AddDuplicateVertex(base + i1); m_indices << m_vert.Count(); AddDuplicateVertex(base + i1);
@@ -635,6 +626,7 @@ void EasyMesh::AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base)
m_indices << m_vert.Count(); AddDuplicateVertex(base + i3); m_indices << m_vert.Count(); AddDuplicateVertex(base + i3);
} }


//-----------------------------------------------------------------------------
void EasyMesh::ComputeNormals(int start, int vcount) void EasyMesh::ComputeNormals(int start, int vcount)
{ {
for (int i = 0; i < vcount; i += 3) for (int i = 0; i < vcount; i += 3)
@@ -650,32 +642,209 @@ void EasyMesh::ComputeNormals(int start, int vcount)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::ComputeTexCoord(float uv_scale, int uv_offset)
{
#if VERTEX_USEAGE == VU_TEX_UV
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.AddVertex(m_indices[i], m_vert[m_indices[i]].m1);
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]].m4, m_vert[tri_list[cur_tri + 1]].m4, m_vert[tri_list[cur_tri + 2]].m4 };
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]].m1 - m_vert[v[j]].m1),
normalize(m_vert[v[(j + 2) % 3]].m1 - m_vert[v[j]].m1)));
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]].m1 - m_vert[v[(base_i + 1) % 3]].m1));
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]].m1 - m_vert[v[0]].m1);
vec3 v02 = m_vert[v[2]].m1 - m_vert[v[0]].m1;
vec3 v_dir = normalize(cross(m_vert[m_indices[cur_tri]].m2, 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]].m4 == vec2(-1.0f))
m_vert[matching_vert[j]].m4 = abs(uv[i]);
#else
m_vert[v[i]].m4 = 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 0
//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)
{
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::SetVertColor(vec4 const &color) void EasyMesh::SetVertColor(vec4 const &color)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
m_vert[i].m3 = color; m_vert[i].m3 = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetCurVertNormal(vec3 const &normal) void EasyMesh::SetCurVertNormal(vec3 const &normal)
{ {
m_vert[m_vert.Count() - 1].m2 = normal; m_vert[m_vert.Count() - 1].m2 = normal;
} }


//-----------------------------------------------------------------------------
void EasyMesh::SetCurVertColor(vec4 const &color) void EasyMesh::SetCurVertColor(vec4 const &color)
{ {
m_vert[m_vert.Count() - 1].m3 = color; m_vert[m_vert.Count() - 1].m3 = color;
} }


//-----------------------------------------------------------------------------
void EasyMesh::Translate(vec3 const &v) void EasyMesh::Translate(vec3 const &v)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
m_vert[i].m1 += v; m_vert[i].m1 += v;
} }


//-----------------------------------------------------------------------------
void EasyMesh::RotateX(float t) { Rotate(t, vec3(1, 0, 0)); } void EasyMesh::RotateX(float t) { Rotate(t, vec3(1, 0, 0)); }
void EasyMesh::RotateY(float t) { Rotate(t, vec3(0, 1, 0)); } void EasyMesh::RotateY(float t) { Rotate(t, vec3(0, 1, 0)); }
void EasyMesh::RotateZ(float t) { Rotate(t, vec3(0, 0, 1)); } void EasyMesh::RotateZ(float t) { Rotate(t, vec3(0, 0, 1)); }


//-----------------------------------------------------------------------------
void EasyMesh::Rotate(float t, vec3 const &axis) void EasyMesh::Rotate(float t, vec3 const &axis)
{ {
mat3 m = mat3::rotate(t, axis); mat3 m = mat3::rotate(t, axis);
@@ -686,6 +855,7 @@ void EasyMesh::Rotate(float t, vec3 const &axis)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::RadialJitter(float r) void EasyMesh::RadialJitter(float r)
{ {
Array<int> Welded; Array<int> Welded;
@@ -730,6 +900,7 @@ void EasyMesh::RadialJitter(float r)
ComputeNormals(m_cursors.Last().m2, m_indices.Count() - m_cursors.Last().m2); ComputeNormals(m_cursors.Last().m2, m_indices.Count() - m_cursors.Last().m2);
} }


//-----------------------------------------------------------------------------
void EasyMesh::TaperX(float y, float z, float xoff) void EasyMesh::TaperX(float y, float z, float xoff)
{ {
/* FIXME: this code breaks normals! */ /* FIXME: this code breaks normals! */
@@ -740,6 +911,7 @@ void EasyMesh::TaperX(float y, float z, float xoff)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::TaperY(float x, float z, float yoff) void EasyMesh::TaperY(float x, float z, float yoff)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
@@ -749,6 +921,7 @@ void EasyMesh::TaperY(float x, float z, float yoff)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::TaperZ(float x, float y, float zoff) void EasyMesh::TaperZ(float x, float y, float zoff)
{ {
for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++) for (int i = m_cursors.Last().m1; i < m_vert.Count(); i++)
@@ -758,6 +931,7 @@ void EasyMesh::TaperZ(float x, float y, float zoff)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::Scale(vec3 const &s) void EasyMesh::Scale(vec3 const &s)
{ {
vec3 const invs = vec3(1) / s; vec3 const invs = vec3(1) / s;
@@ -780,10 +954,12 @@ void EasyMesh::Scale(vec3 const &s)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::MirrorX() { DupAndScale(vec3(-1, 1, 1)); } void EasyMesh::MirrorX() { DupAndScale(vec3(-1, 1, 1)); }
void EasyMesh::MirrorY() { DupAndScale(vec3(1, -1, 1)); } void EasyMesh::MirrorY() { DupAndScale(vec3(1, -1, 1)); }
void EasyMesh::MirrorZ() { DupAndScale(vec3(1, 1, -1)); } void EasyMesh::MirrorZ() { DupAndScale(vec3(1, 1, -1)); }


//-----------------------------------------------------------------------------
void EasyMesh::DupAndScale(vec3 const &s) void EasyMesh::DupAndScale(vec3 const &s)
{ {
int vlen = m_vert.Count() - m_cursors.Last().m1; int vlen = m_vert.Count() - m_cursors.Last().m1;
@@ -801,6 +977,7 @@ void EasyMesh::DupAndScale(vec3 const &s)
m_cursors.Last().m2 -= tlen; m_cursors.Last().m2 -= tlen;
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2, void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
int dualside, int smooth) int dualside, int smooth)
{ {
@@ -853,6 +1030,7 @@ void EasyMesh::AppendCylinder(int nsides, float h, float r1, float r2,
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendCapsule(int ndivisions, float h, float r) void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
{ {
int ibase = m_indices.Count(); int ibase = m_indices.Count();
@@ -949,6 +1127,7 @@ void EasyMesh::AppendCapsule(int ndivisions, float h, float r)
ComputeNormals(ibase, m_indices.Count() - ibase); ComputeNormals(ibase, m_indices.Count() - ibase);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSphere(int ndivisions, vec3 const &size) void EasyMesh::AppendSphere(int ndivisions, vec3 const &size)
{ {
OpenBrace(); OpenBrace();
@@ -957,6 +1136,7 @@ void EasyMesh::AppendSphere(int ndivisions, vec3 const &size)
CloseBrace(); CloseBrace();
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendTorus(int ndivisions, float r1, float r2) void EasyMesh::AppendTorus(int ndivisions, float r1, float r2)
{ {
int ibase = m_indices.Count(); int ibase = m_indices.Count();
@@ -990,21 +1170,25 @@ void EasyMesh::AppendTorus(int ndivisions, float r1, float r2)
ComputeNormals(ibase, m_indices.Count() - ibase); ComputeNormals(ibase, m_indices.Count() - ibase);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendBox(vec3 const &size, float chamf) void EasyMesh::AppendBox(vec3 const &size, float chamf)
{ {
AppendBox(size, chamf, false); AppendBox(size, chamf, false);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSmoothChamfBox(vec3 const &size, float chamf) void EasyMesh::AppendSmoothChamfBox(vec3 const &size, float chamf)
{ {
AppendBox(size, chamf, true); AppendBox(size, chamf, true);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendFlatChamfBox(vec3 const &size, float chamf) void EasyMesh::AppendFlatChamfBox(vec3 const &size, float chamf)
{ {
AppendBox(size, chamf, false); AppendBox(size, chamf, false);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth) void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
{ {
if (chamf < 0.0f) if (chamf < 0.0f)
@@ -1100,6 +1284,7 @@ void EasyMesh::AppendBox(vec3 const &size, float chamf, bool smooth)
ComputeNormals(ibase, m_indices.Count() - ibase); ComputeNormals(ibase, m_indices.Count() - ibase);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendStar(int nbranches, float r1, float r2, void EasyMesh::AppendStar(int nbranches, float r1, float r2,
int fade, int fade2) int fade, int fade2)
{ {
@@ -1131,6 +1316,7 @@ void EasyMesh::AppendStar(int nbranches, float r1, float r2,
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendExpandedStar(int nbranches, float r1, void EasyMesh::AppendExpandedStar(int nbranches, float r1,
float r2, float extrar) float r2, float extrar)
{ {
@@ -1165,6 +1351,7 @@ void EasyMesh::AppendExpandedStar(int nbranches, float r1,
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendDisc(int nsides, float r, int fade) void EasyMesh::AppendDisc(int nsides, float r, int fade)
{ {
int vbase = m_vert.Count(); int vbase = m_vert.Count();
@@ -1184,6 +1371,7 @@ void EasyMesh::AppendDisc(int nsides, float r, int fade)
} }
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleTriangle(float size, int fade) void EasyMesh::AppendSimpleTriangle(float size, int fade)
{ {
mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f); mat3 m = mat3::rotate(120.f, 0.f, 1.f, 0.f);
@@ -1202,11 +1390,13 @@ void EasyMesh::AppendSimpleTriangle(float size, int fade)
AppendTriangle(0, 1, 2, m_vert.Count() - 3); AppendTriangle(0, 1, 2, m_vert.Count() - 3);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleQuad(float size, int fade) void EasyMesh::AppendSimpleQuad(float size, int fade)
{ {
AppendSimpleQuad(vec2(size * .5f), vec2(size * -.5f), 0.f, fade); AppendSimpleQuad(vec2(size * .5f), vec2(size * -.5f), 0.f, fade);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade) void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade)
{ {
AddVertex(vec3(p2.x, z, -p1.y)); AddVertex(vec3(p2.x, z, -p1.y));
@@ -1222,6 +1412,7 @@ void EasyMesh::AppendSimpleQuad(vec2 p1, vec2 p2, float z, int fade)
ComputeNormals(m_indices.Count() - 6, 6); ComputeNormals(m_indices.Count() - 6, 6);
} }


//-----------------------------------------------------------------------------
void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20, void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,
float r1, float r2, float r12, float r22, float r1, float r2, float r12, float r22,
float sidemul, int offset) float sidemul, int offset)
@@ -1297,6 +1488,7 @@ void EasyMesh::AppendCog(int nbsides, float h, float r10, float r20,
ComputeNormals(ibase, m_indices.Count() - ibase); ComputeNormals(ibase, m_indices.Count() - ibase);
} }


//-----------------------------------------------------------------------------
void EasyMesh::Chamfer(float f) void EasyMesh::Chamfer(float f)
{ {
int vlen = m_vert.Count() - m_cursors.Last().m1; int vlen = m_vert.Count() - m_cursors.Last().m1;
@@ -1320,6 +1512,7 @@ void EasyMesh::Chamfer(float f)
vertices[m_indices[i]]++; vertices[m_indices[i]]++;


for (int i = 0; i < ilen / 3; i++) for (int i = 0; i < ilen / 3; i++)

{ {
#if 0 #if 0
if (vertices[m_indices[i * 3]] > 1) if (vertices[m_indices[i * 3]] > 1)


+ 64
- 4
src/easymesh/easymesh.h 查看文件

@@ -15,6 +15,12 @@
// ------------------ // ------------------
// //


#define VU_BONES 2
#define VU_TEX_UV 1
#define VU_VANILLA 0

#define VERTEX_USEAGE VU_VANILLA

#if !defined __EASYMESH_EASYMESH_H__ #if !defined __EASYMESH_EASYMESH_H__
#define __EASYMESH_EASYMESH_H__ #define __EASYMESH_EASYMESH_H__


@@ -38,6 +44,39 @@ struct CSGUsage
inline operator Value() { return m_value; } inline operator Value() { return m_value; }
}; };


/* A safe enum for VertexDictionnary operations. */
struct VDictType
{
enum Value
{
DoesNotExist=-3,
Alone=-2,
Master=-1
}
m_value;

inline VDictType(Value v) : m_value(v) {}
inline operator Value() { return m_value; }
};

//a class whose goal is to keep a list of the adjacent vertices for mesh operations purposes
class VertexDictionnary
{
public:
int FindVertexMaster(const int search_idx);
bool FindMatchingVertices(const int search_idx, Array<int> &matching_ids);
bool FindConnectedVertices(const int search_idx, const Array<int> &tri_list, Array<int> &connected_vert, Array<int> const *ignored_tri = NULL);
bool FindConnectedTriangles(const int search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
bool FindConnectedTriangles(const ivec2 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
bool FindConnectedTriangles(const ivec3 &search_idx, const Array<int> &tri_list, Array<int> &connected_tri, Array<int> const *ignored_tri = NULL);
void AddVertex(int vert_id, vec3 vert_coord);
void Clear() { vertex_list.Empty(); }
private:
//<VertexId, VertexLocation, VertexMasterId>
Array<int, vec3, int> vertex_list;
//List of the master_ vertices
Array<int> master_list;
};


class EasyMesh class EasyMesh
{ {
@@ -81,6 +120,8 @@ private:
void AppendTriangle(int i1, int i2, int i3, int base); void AppendTriangle(int i1, int i2, int i3, int base);
void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base); void AppendTriangleDuplicateVerts(int i1, int i2, int i3, int base);
void ComputeNormals(int start, int vcount); void ComputeNormals(int start, int vcount);
public:
void ComputeTexCoord(float uv_scale, int uv_offset);
void SetVertColor(vec4 const &color); void SetVertColor(vec4 const &color);


void SetCurVertNormal(vec3 const &normal); void SetCurVertNormal(vec3 const &normal);
@@ -141,11 +182,21 @@ public:
private: private:
vec4 m_color, m_color2; vec4 m_color, m_color2;
Array<uint16_t> m_indices; Array<uint16_t> m_indices;
//TODO : <coord, norm, color, bone_id, bone_weight>
//TODO : Array<vec3, vec3, vec4, ivec2, vec2> m_vert;
#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
//TODO : <COORD, NORM, COLOR, BONE_ID, BONE_WEIGHT>
Array<vec3, vec3, vec4, ivec2, vec2> m_vert;
//TODO : More bone blend support than 2 ? //TODO : More bone blend support than 2 ?
//<coord, norm, color>
#elif VERTEX_USEAGE == VU_TEX_UV
//TODO : -- UV SUPPORT --
//TODO : <COORD, NORM, COLOR, UV>
Array<vec3, vec3, vec4, vec2> m_vert;
#else
//-- VANILLA --
//<COORD, NORM, COLOR>
Array<vec3, vec3, vec4> m_vert; Array<vec3, vec3, vec4> m_vert;
#endif

//<vert count, indices count> //<vert count, indices count>
Array<int, int> m_cursors; Array<int, int> m_cursors;
//When this flag is up, negative scaling will not invert faces. //When this flag is up, negative scaling will not invert faces.
@@ -156,8 +207,17 @@ private:
{ {
/* FIXME: very naughty way of handling debug render modes */ /* FIXME: very naughty way of handling debug render modes */
Array<Shader *>shader; Array<Shader *>shader;
#if VERTEX_USEAGE == VU_BONES
//TODO : -- BONE SUPPORT --
Array<ShaderAttrib> coord, norm, color, bone_id, bone_weight;
#elif VERTEX_USEAGE == VU_TEX_UV
//-- UV SUPPORT --
Array<ShaderAttrib> coord, norm, color, tex_coord;
#else
//-- VANILLA --
Array<ShaderAttrib> coord, norm, color; Array<ShaderAttrib> coord, norm, color;
Array<ShaderUniform> modelview, view, invview, proj, normalmat, damage, lights;
#endif
Array<ShaderUniform> modelview, invmodelview, view, invview, proj, normalmat, damage, lights;


VertexDeclaration *vdecl; VertexDeclaration *vdecl;
VertexBuffer *vbo; VertexBuffer *vbo;


+ 6
- 0
src/easymesh/shiny.lolfx 查看文件

@@ -45,6 +45,12 @@ varying vec3 pass_TNormal;
varying vec4 pass_Color; varying vec4 pass_Color;


#if 0 #if 0
//Cos(45) = 0.70710678118
//1.0 - Cos(45) = 0.29289321881

const float cos_45 = 0.70710678118;
const float inv_cos_45 = 0.29289321881;

//Cube Light //Cube Light
vec4 in_Light3_Pos = vec4(-10.0, 10.0, 5.0, 1.0); vec4 in_Light3_Pos = vec4(-10.0, 10.0, 5.0, 1.0);
vec3 in_Light3_Size_Inner = vec3(3.0, 1.0, 3.0); vec3 in_Light3_Size_Inner = vec3(3.0, 1.0, 3.0);


+ 5
- 76
src/easymesh/shinydebugUV.lolfx 查看文件

@@ -5,6 +5,7 @@
attribute vec3 in_Vertex; attribute vec3 in_Vertex;
attribute vec3 in_Normal; attribute vec3 in_Normal;
attribute vec4 in_Color; attribute vec4 in_Color;
attribute vec2 in_TexCoord;


uniform mat4 in_ModelView; uniform mat4 in_ModelView;
uniform mat4 in_View; uniform mat4 in_View;
@@ -14,6 +15,7 @@ uniform mat3 in_NormalMat;
varying vec4 pass_Vertex; /* View space */ varying vec4 pass_Vertex; /* View space */
varying vec3 pass_TNormal; varying vec3 pass_TNormal;
varying vec4 pass_Color; varying vec4 pass_Color;
varying vec2 pass_TexCoord;


void main(void) void main(void)
{ {
@@ -23,6 +25,7 @@ void main(void)
pass_Vertex = vertex; pass_Vertex = vertex;
pass_TNormal = tnorm; pass_TNormal = tnorm;
pass_Color = in_Color; pass_Color = in_Color;
pass_TexCoord = in_TexCoord;


gl_Position = in_Proj * vertex; gl_Position = in_Proj * vertex;
} }
@@ -43,85 +46,11 @@ uniform vec4 u_Lights[8 * 2];
varying vec4 pass_Vertex; /* View space */ varying vec4 pass_Vertex; /* View space */
varying vec3 pass_TNormal; varying vec3 pass_TNormal;
varying vec4 pass_Color; varying vec4 pass_Color;

#if 0
//Cube Light
vec4 in_Light3_Pos = vec4(-10.0, 10.0, 5.0, 1.0);
vec3 in_Light3_Size_Inner = vec3(3.0, 1.0, 3.0);
vec3 in_Light3_Size_Outer = vec3(15.0, 15.0, 15.0);
vec3 in_Light3_diffuse = vec3(0.4, 1.0, 0.4);
#endif
varying vec2 pass_TexCoord;


void main(void) void main(void)
{ {
/* Material properties */
vec3 specular_reflect = vec3(0.8, 0.75, 0.4);
float specular_power = 60.0;

/* World properties */
vec3 ambient = vec3(0.1, 0.1, 0.1);
vec3 specular = vec3(0.0, 0.0, 0.0);
vec3 diffuse = vec3(0.0, 0.0, 0.0);

/* Light precalculations */
vec3 v = normalize(-pass_Vertex.xyz);

/* Apply lighting */
for (int i = 0; i < 8; i++)
{
vec4 pos = u_Lights[i * 2];
vec4 color = u_Lights[i * 2 + 1];
vec3 s, r;

if (pos.w > 0.0)
{
/* Point light -- no attenuation yet */
s = normalize((in_View * pos).xyz - pass_Vertex.xyz);
r = reflect(-s, pass_TNormal);
}
else
{
/* Directional light */
s = normalize(-pos.xyz);
r = reflect(s, pass_TNormal);
}

float sdotn = max(dot(s, pass_TNormal), 0.0);
diffuse += color.xyz * sdotn;
if (sdotn > 0.0)
specular += color.xyz * specular_reflect
* pow(max(dot(r, v), 0.0), specular_power);
}

#if 0
//Light calculation for cube light
vec3 specular_color = vec3(1.0, 1.0, 0.6);
vec3 Local_Vertex = (in_Inv_View * pass_Vertex).xyz - (in_Light3_Pos).xyz;
vec3 Proj_Vertex = clamp(Local_Vertex.xyz, -in_Light3_Size_Inner, in_Light3_Size_Inner);
vec3 new_LightDir = Local_Vertex - Proj_Vertex;

vec3 light_radius = max(vec3(0.0,0.0,0.0), vec3(1.0,1.0,1.0) - abs(new_LightDir / in_Light3_Size_Outer));
float light_radius_mod = min(light_radius.x, min(light_radius.y, light_radius.z));

if (length(new_LightDir) == 0.0)
sdotn = 1.0;
else
{
new_LightDir = normalize((in_View * vec4(Proj_Vertex + in_Light3_Pos.xyz,1.0)).xyz - pass_Vertex.xyz);
sdotn = max(dot(new_LightDir, pass_TNormal), 0.0);
r = reflect(-new_LightDir, pass_TNormal);
if (sdotn > 0.0 && light_radius_mod > 0.0)
specular += specular_color * min(specular_reflect, light_radius_mod)
* pow(max(dot(r, v), 0.0), specular_power);
}
diffuse += in_Light3_diffuse * min(sdotn, light_radius_mod);
//----------
#endif

vec3 light = ambient + diffuse + specular;

vec4 real_color = mix(pass_Color, vec4(1.2, 1.2, 1.2, 1.0), in_Damage);
gl_FragColor = real_color * vec4(light, 1.0);
gl_FragColor = vec4(mod(pass_TexCoord.x, 1.0f), 0.2, mod(pass_TexCoord.y, 1.0), 1.0) * length(normalize(pass_Color.xyz)) * length(normalize(pass_TNormal));
} }


[vert.hlsl] [vert.hlsl]


+ 5
- 2
src/video.cpp 查看文件

@@ -254,14 +254,17 @@ void Video::SetDebugRenderMode(DebugRenderMode d)
#elif defined HAVE_GLES_2X #elif defined HAVE_GLES_2X
glEnable(GL_CULL_FACE); glEnable(GL_CULL_FACE);
#else #else
glEnable(GL_CULL_FACE);
if (VideoData::render_mode == d && glIsEnabled(GL_CULL_FACE) == GL_TRUE)
glDisable(GL_CULL_FACE);
else
glEnable(GL_CULL_FACE);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif #endif
break; break;
} }
case DebugRenderMode::Wireframe: case DebugRenderMode::Wireframe:
{ {
if (VideoData::render_mode == DebugRenderMode::Wireframe)
if (VideoData::render_mode == d)
{ {
#if defined USE_D3D9 || defined _XBOX #if defined USE_D3D9 || defined _XBOX
#else #else


+ 36
- 1
test/MeshViewer.cpp 查看文件

@@ -21,6 +21,8 @@
using namespace std; using namespace std;
using namespace lol; using namespace lol;


LOLFX_RESOURCE_DECLARE(shinyfur);

#define IPT_CAM_RESET "Cam_Center" #define IPT_CAM_RESET "Cam_Center"
#define IPT_CAM_FORWARD "Cam_Forward" #define IPT_CAM_FORWARD "Cam_Forward"
#define IPT_CAM_BACKWARD "Cam_Backward" #define IPT_CAM_BACKWARD "Cam_Backward"
@@ -43,6 +45,8 @@ using namespace lol;
#define IPT_MESH_ROT_UP "Mesh_Rot_Up" #define IPT_MESH_ROT_UP "Mesh_Rot_Up"
#define IPT_MESH_ROT_DOWN "Mesh_Rot_Down" #define IPT_MESH_ROT_DOWN "Mesh_Rot_Down"


#define WITH_FUR 0

class MeshViewer : public WorldEntity class MeshViewer : public WorldEntity
{ {
public: public:
@@ -270,6 +274,24 @@ public:
String cmd = f.ReadString(); String cmd = f.ReadString();
f.Close(); f.Close();


for (int i = 0; i < cmd.Count() - 1; i++)
{
if (cmd[i] == '/' && cmd[i + 1] == '/')
{
int j = i;
for (; j < cmd.Count(); j++)
{
if (cmd[j] == '\r' || cmd[j] == '\n')
break;
}
String new_cmd = cmd.Sub(0, i);
if (j < cmd.Count())
new_cmd += cmd.Sub(j, cmd.Count() - j);
cmd = new_cmd;
i--;
}
}

if (cmd.Count() if (cmd.Count()
&& (!m_cmdlist.Count() || cmd != m_cmdlist.Last())) && (!m_cmdlist.Count() || cmd != m_cmdlist.Last()))
{ {
@@ -277,7 +299,10 @@ public:


//Create a new mesh //Create a new mesh
m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f)); m_meshes.Push(EasyMesh(), false, .0f, vec3(.0f));
m_meshes.Last().m1.Compile(cmd.C());
if (!m_meshes.Last().m1.Compile(cmd.C()))
m_meshes.Pop();
else
m_meshes.Last().m1.ComputeTexCoord(0.2f, 2);
} }
} }
} }
@@ -304,7 +329,12 @@ public:
{ {
if (!m_meshes[i].m2) if (!m_meshes[i].m2)
{ {
//Fur support
#if WITH_FUR
m_meshes[i].m1.MeshConvert(Shader::Create(LOLFX_RESOURCE_NAME(shinyfur)));
#else
m_meshes[i].m1.MeshConvert(); m_meshes[i].m1.MeshConvert();
#endif
m_meshes[i].m2 = true; m_meshes[i].m2 = true;
} }
} }
@@ -330,7 +360,12 @@ public:
mat4::scale(vec3(vec2(m_meshes[i].m3), 1.0f)) * mat4::scale(vec3(vec2(m_meshes[i].m3), 1.0f)) *
default_proj * default_proj *
m_fov_compensation); m_fov_compensation);
#if WITH_FUR
for (int j=0; j < 40; j++)
m_meshes[i].m1.Render(m_mat, 0.1 * j);
#else
m_meshes[i].m1.Render(m_mat); m_meshes[i].m1.Render(m_mat);
#endif
Video::Clear(ClearMask::Depth); Video::Clear(ClearMask::Depth);
} }
} }


+ 3
- 0
test/MeshViewer.vcxproj 查看文件

@@ -47,6 +47,9 @@
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild> <ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
</None> </None>
</ItemGroup> </ItemGroup>
<ItemGroup>
<LolFxCompile Include="shinyfur.lolfx" />
</ItemGroup>
<PropertyGroup Label="Globals"> <PropertyGroup Label="Globals">
<ProjectGuid>{7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}</ProjectGuid> <ProjectGuid>{7CE9FE12-E4AB-4A22-90D4-2C15F0C30D4E}</ProjectGuid>
<ConfigurationType>Application</ConfigurationType> <ConfigurationType>Application</ConfigurationType>


+ 11
- 1
test/MeshViewerBuffer.txt 查看文件

@@ -1 +1,11 @@
[sc#2f2 ab 2 2 2 t .8 .8 .8 rx 20 ry 20 [sc#22f ab 2 2 2 tx 0 csgu]]
[sc#88f ab 4 4 4]
//[sc#ff2 asph 2 4 4 4]
//[sc#ff2 acap 2 4 4]
//[sc#ff2 ac 12 4 4 4 0 0]
//[sc#ff2 asph 2 10 10 10]
//[sc#400 asph 2 10 10 10 t 2 2 2 csgs]
//[sc#88f afcb 10 10 10 .25 tx 0 sc 0.1]
//[sc#22f afcb 10 10 10 .25 t 2 2 2 csgs]
//[sc#fff afcb 7 7 7 .25]
//[sc#ff2 afcb 7 7 7 .25 t 1 1 1]

+ 183
- 0
test/shinyfur.lolfx 查看文件

@@ -0,0 +1,183 @@

[vert.glsl]
#version 120

attribute vec3 in_Vertex;
attribute vec3 in_Normal;
attribute vec4 in_Color;

uniform mat4 in_ModelView;
uniform mat4 in_View;
uniform mat4 in_Proj;
uniform mat3 in_NormalMat;
uniform float in_Damage;

varying vec4 pass_Vertex; /* View space */
varying vec3 pass_TNormal;
varying vec4 pass_Color;

void main(void)
{
vec4 vertex = vec4(in_Vertex + (in_Normal * in_Damage), 1.0);
float dam_perc = in_Damage / (0.1 * 40);
vec3 vGravity = vec3(0.0, -0.981, 0.0) * 2.0;
float k = pow(dam_perc, 3);
vertex = in_ModelView * vertex + in_View * vec4(vGravity * k, 1.0);
vec3 tnorm = normalize(in_NormalMat * in_Normal);

pass_Vertex = vertex;
pass_TNormal = tnorm;
pass_Color = in_Color;

gl_Position = in_Proj * vertex;
}

[frag.glsl]
#version 120

#if defined GL_ES
precision highp float;
#endif

uniform mat4 in_View;
uniform mat4 in_Inv_View;
uniform mat4 in_Inv_ModelView;
uniform float in_Damage;

//Light list
uniform vec4 u_Lights[8 * 2];

varying vec4 pass_Vertex; /* View space */
varying vec3 pass_TNormal;
varying vec4 pass_Color;

void main(void)
{
/* Material properties */
vec3 specular_reflect = vec3(0.8, 0.75, 0.4);
float specular_power = 60.0;

/* World properties */
vec3 ambient = vec3(0.7, 0.7, 0.7);
vec3 specular = vec3(0.0, 0.0, 0.0);
vec3 diffuse = vec3(0.0, 0.0, 0.0);

/* Light precalculations */
vec3 v = normalize(-pass_Vertex.xyz);

/* Apply lighting */
for (int i = 0; i < 8; i++)
{
vec4 pos = u_Lights[i * 2];
vec4 color = u_Lights[i * 2 + 1];
vec3 s, r;

if (pos.w > 0.0)
{
/* Point light -- no attenuation yet */
s = normalize((in_View * pos).xyz - pass_Vertex.xyz);
r = reflect(-s, pass_TNormal);
}
else
{
/* Directional light */
s = normalize(-pos.xyz);
r = reflect(s, pass_TNormal);
}

float sdotn = max(dot(s, pass_TNormal), 0.0);
diffuse += color.xyz * sdotn;
if (sdotn > 0.0)
specular += color.xyz * specular_reflect
* pow(max(dot(r, v), 0.0), specular_power);
}

vec3 light = ambient + diffuse + specular;

vec4 world_vertex = in_Inv_ModelView * pass_Vertex;
vec4 world_normal = in_Inv_ModelView * vec4(pass_TNormal, 1.0);

float dam_perc = in_Damage / (0.1 * 40);
float PI = 3.14159265358979323846264;
dam_perc = (sin(PI * (dam_perc - 0.5)) * 0.5 + 0.5);
dam_perc *= dam_perc;
dam_perc = 1.0 - dam_perc;
float mod = 2.0;
float transp = dam_perc;
/*
abs(sin(world_vertex.x * mod) * dam_perc * 0.5 + 0.5) *
abs(sin(world_vertex.y * mod) * dam_perc * 0.5 + 0.5) *
abs(sin(world_vertex.z * mod) * dam_perc * 0.5 + 0.5)
*/

//vec4 real_color = mix(pass_Color, vec4(1.2, 1.2, 1.2, 1.0), in_Damage);
// - in_Damage
gl_FragColor = pass_Color * vec4(light, (in_Damage == 0)?(1.0):(transp));
}

[vert.hlsl]

void main(float3 in_Vertex : POSITION,
float3 in_Normal : NORMAL,
float4 in_Color : COLOR,
uniform float4x4 in_ModelView,
uniform float4x4 in_Model,
uniform float4x4 in_Proj,
uniform float3x3 in_NormalMat,
out float4 pass_Vertex : TEXCOORD0,
out float3 pass_TNormal : TEXCOORD1,
out float4 pass_Color : COLOR,
out float4 out_Position : POSITION)
{
float4 eye = mul(in_ModelView, float4(in_Vertex, 1.0));
float3 tnorm = normalize(mul(in_NormalMat, in_Normal));

pass_Vertex = eye;
pass_TNormal = tnorm;
#ifdef _XBOX
pass_Color = in_Color.abgr;
#else
pass_Color = in_Color;
#endif

out_Position = mul(in_Proj, eye);
}

[frag.hlsl]

void main(float4 pass_Vertex : TEXCOORD0,
float3 pass_TNormal : TEXCOORD1,
float4 pass_Color : COLOR,
uniform float in_Damage,
out float4 out_FragColor : COLOR)
{
float3 in_LightDir = float3(0.3, 0.3, 0.7);

/* Material properties */
float3 specular_reflect = float3(0.8, 0.75, 0.4);
float specular_power = 60.0;

/* World properties */
float ambient_mul = 0.5;
float3 ambient_color = float3(0.25, 0.2, 0.35);
float3 diffuse_color = float3(1.0, 1.0, 0.6);
float3 specular_color = float3(1.0, 1.0, 0.6);

float3 s = normalize(in_LightDir); /* normalize(pass_Vertex - lightpos); */
float3 v = normalize(-pass_Vertex.xyz);
float3 r = reflect(-s, pass_TNormal);

float3 ambient = ambient_color;
float sdotn = max(dot(s, pass_TNormal), 0.0);
float3 diffuse = diffuse_color * sdotn;
float3 specular = float3(0.0, 0.0, 0.0);
if (sdotn > 0.0)
specular = specular_color * specular_reflect
* pow(max(dot(r, v), 0.0), specular_power);
float3 light = ambient + diffuse + specular;

float4 real_color = in_Damage * float4(1.2, 1.2, 1.2, 1.0)
+ (1.0 - in_Damage) * pass_Color;
out_FragColor = real_color * float4(light, 1.0);
}


Loading…
取消
儲存