/// <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> /// Compares vertices /// </summary> /// <param name="v0"></param> /// <param name="v1"></param> /// <returns></returns> bool CompareVertexPair(MeshVertex v0, MeshVertex v1, float toleranceSquared) { if (Vector3.DistanceSquared(v0.Position, v1.Position) > toleranceSquared) { return(false); } if (Vector3.DistanceSquared(v0.Tangent, v1.Tangent) > toleranceSquared) { return(false); } if (Vector3.DistanceSquared(v0.Binormal, v1.Binormal) > toleranceSquared) { return(false); } if (Vector3.DistanceSquared(v0.Normal, v1.Normal) > toleranceSquared) { return(false); } if (Vector2.DistanceSquared(v0.TexCoord0, v1.TexCoord0) > toleranceSquared) { return(false); } //if ( Vector2.DistanceSquared( v0.TexCoord1 , v1.TexCoord1 ) > toleranceSquared ) return false; if (v0.Color0 != v1.Color0) { return(false); } //if ( v0.Color1 != v1.Color1 ) return false; if (Vector4.DistanceSquared(v0.SkinWeights, v1.SkinWeights) > toleranceSquared) { return(false); } if (v0.SkinIndices != v1.SkinIndices) { return(false); } return(true); }
private void ReadStream(Stream stream) { using (BinaryReader reader = new BinaryReader(stream)) { var fileHeader = reader.ReadFourCC(); var formarVersion = reader.Read <int>(); /* * FourCC texture section ("TEX0") * int number of textures * (string,string)[] material & texture names */ var textureSection = reader.ReadFourCC(); var countTexture = reader.Read <int>(); List <MaterialRef> materialTexture = new List <MaterialRef>(); for (int i = 0; i < countTexture; i++) { var Name = reader.ReadString(); var texture = reader.ReadString(); materialTexture.Add(new MaterialRef() { Name = Name, Texture = texture }); } Materials = materialTexture; /* * FourCC indices section ("IDX0") * int number of indices * int number of vertices * int[] indices data */ var indicesSection = reader.ReadFourCC(); IndexCount = reader.Read <int>(); VertexCount = reader.Read <int>(); var indicesData = new int[IndexCount]; for (int i = 0; i < IndexCount; i++) { indicesData[i] = reader.Read <int>(); } indexBuffer = IndexBuffer.Create(rs.Game.GraphicsDevice, indicesData); /* * FourCC subset section ("SBST") * int number of subsets * (int,int,int)[] start index, index count, Material Index */ var subsetSection = reader.ReadFourCC(); var countSubsets = reader.Read <int>(); Subsets = new List <MeshSubset>(); for (int i = 0; i < countSubsets; i++) { var startIndex = reader.Read <int>(); var indexCount = reader.Read <int>(); var materialIndex = reader.Read <int>(); Subsets.Add(new MeshSubset() { StartPrimitive = startIndex, PrimitiveCount = indexCount, MaterialIndex = materialIndex, }); } /* * FourCC animated data section ("ANIM") * int number of frames * float frame rate (frames per second) * */ var animDataSection = reader.ReadFourCC(); var countFrames = reader.Read <int>(); var frameRate = reader.Read <float>(); /* * FourCC frame data section ("FRM0") * int reserved (must be 0) * vertex[] vertex data: * - Vector3 - position * - Vector2 - texture coordinates * - Vector3 - normal * - Vector3 - tangent * - Vector3 - binormal * - Half4 - color */ framesList = new List <List <MeshVertex> >(); for (int i = 0; i < countFrames; i++) { var frameDataSection = reader.ReadFourCC(); var reserved = reader.Read <int>(); List <MeshVertex> vertexDataList = new List <MeshVertex>(); for (int j = 0; j < VertexCount; j++) { MeshVertex vertexData = new MeshVertex(); vertexData.Position = reader.Read <Vector3>(); vertexData.TexCoord0 = reader.Read <Vector2>(); vertexData.Normal = reader.Read <Vector3>(); vertexData.Tangent = reader.Read <Vector3>(); vertexData.Binormal = reader.Read <Vector3>(); vertexData.Color0 = new Color(reader.Read <Half4>()); vertexDataList.Add(vertexData); } framesList.Add(vertexDataList); } // fill vertex buffer for first iteration IsSkinned = framesList[currentFrame].Any(v => v.SkinIndices != Int4.Zero); vertexBuffer = new VertexBuffer(rs.Game.GraphicsDevice, typeof(MeshVertex), VertexCount); } }
/*----------------------------------------------------------------------------------------- * * 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; } } }