/// <summary> /// /// </summary> /// <param name="v0"></param> /// <param name="v1"></param> /// <returns></returns> int ClassifyVertexPair(MeshVertex v0, MeshVertex v1) { int res = 0; if (v0.Position.X < v1.Position.X) { res |= 0x1; } if (v0.Position.Y < v1.Position.Y) { res |= 0x2; } if (v0.Position.Z < v1.Position.Z) { res |= 0x4; } return(res); }
/// <summary> /// Inserts node to oct tree /// </summary> int InsertVertex(ref OctNode node, MeshVertex v, float tolerance) { if (node == null) { node = new OctNode(); node.index = Vertices.Count; Vertices.Add(v); return(node.index); } if (CompareVertexPair(Vertices[node.index], v, tolerance)) { return(node.index); } int r = ClassifyVertexPair(Vertices[node.index], v); return(InsertVertex(ref node.nodes[r], v, tolerance * tolerance)); }
/// <summary> /// Merges vertices /// </summary> public void MergeVertices(float tolerance) { OctNode root = null; List <MeshVertex> oldVertices = new List <MeshVertex>(Vertices); Vertices.Clear(); for (int i = 0; i < Triangles.Count; i++) { MeshVertex v0 = oldVertices[Triangles[i].Index0]; MeshVertex v1 = oldVertices[Triangles[i].Index1]; MeshVertex v2 = oldVertices[Triangles[i].Index2]; int i0 = InsertVertex(ref root, v0, tolerance); int i1 = InsertVertex(ref root, v1, tolerance); int i2 = InsertVertex(ref root, v2, tolerance); int mtrl = Triangles[i].MaterialIndex; Triangles[i] = new MeshTriangle(i0, i1, i2, mtrl); } }
/*----------------------------------------------------------------------------------------- * * Tangent space : * * -----------------------------------------------------------------------------------------*/ /// <summary> /// Computes tangent frame /// </summary> public void ComputeTangentFrame() { for (int i = 0; i < TriangleCount; i++) { var tri = Triangles[i]; var inds = new[] { tri.Index0, tri.Index1, tri.Index2 }; for (uint j = 0; j < 3; j++) { MeshVertex vert0 = Vertices[inds[(0 + j) % 3]]; MeshVertex vert1 = Vertices[inds[(1 + j) % 3]]; MeshVertex vert2 = Vertices[inds[(2 + j) % 3]]; Vector3 v0 = vert1.Position - vert0.Position; Vector3 v1 = vert2.Position - vert0.Position; Vector2 t0 = vert1.TexCoord0 - vert0.TexCoord0; Vector2 t1 = vert2.TexCoord0 - vert0.TexCoord0; { // X : float det = t0.X * t1.Y - t1.X * t0.Y; float dett = v0.X * t1.Y - v1.X * t0.Y; float detb = t0.X * v1.X - t1.X * v0.X; //if (Math.Abs(det)<float.Epsilon) Log.Warning("Tri is too small"); vert0.Tangent.X = dett / det; vert0.Binormal.X = detb / det; } { // Y : float det = t0.X * t1.Y - t1.X * t0.Y; float dett = v0.Y * t1.Y - v1.Y * t0.Y; float detb = t0.X * v1.Y - t1.X * v0.Y; //if (Math.Abs(det)<float.Epsilon) Log.Warning("Tri is too small"); vert0.Tangent.Y = dett / det; vert0.Binormal.Y = detb / det; } { // Z : float det = t0.X * t1.Y - t1.X * t0.Y; float dett = v0.Z * t1.Y - v1.Z * t0.Y; float detb = t0.X * v1.Z - t1.X * v0.Z; //if (Math.Abs(det)<float.Epsilon) Log.Warning("Tri is too small"); vert0.Tangent.Z = dett / det; vert0.Binormal.Z = detb / det; } //vert0.Normal = Vector3.Cross(v1, v0); if (vert0.Tangent.Length() > float.Epsilon * 8) { vert0.Tangent.Normalize(); } if (vert0.Binormal.Length() > float.Epsilon * 8) { vert0.Binormal.Normalize(); } if (vert0.Normal.Length() > float.Epsilon * 8) { vert0.Normal.Normalize(); } //vert0.Tangent.Normalize() ; //vert0.Binormal.Normalize() ; //vert0.Normal.Normalize() ; Vector3 temp; temp = Vector3.Cross(vert0.Tangent, vert0.Normal); vert0.Tangent = Vector3.Cross(vert0.Normal, temp); temp = Vector3.Cross(vert0.Binormal, vert0.Normal); vert0.Binormal = Vector3.Cross(vert0.Normal, temp); //*/ // assign vertex Vertices[inds[(0 + j) % 3]] = vert0; } } }
/// <summary> /// /// </summary> /// <param name="vertex"></param> /// <returns></returns> public abstract TVertex Convert(MeshVertex vertex);