public void Deserialize(BinaryReader from) { // Bezier File Format : // Header ('BZR ') | sizeof(uint) // Version (1.1) | sizeof(uint) // Regular patch count | sizeof(uint) // Quad patch count | sizeof(uint) // Triangle patch count | sizeof(uint) this.Header = from.ReadStructure<BezierMesh.BezierHeader>(); byte[] expectedHeader = {Convert.ToByte(' '), Convert.ToByte('R'), Convert.ToByte('Z'), Convert.ToByte('B')}; if (BitConverter.IsLittleEndian) Array.Reverse(expectedHeader); if (Header.Header != BitConverter.ToInt32(expectedHeader,0) || (Header.Version != 0x0100 && Header.Version != 0x0101)) { throw new ArgumentException("Incorrect input header or unsupported file format version"); } // Part 1. Precomputed Control Points: // Regular Patches: // Bezier control points | 16 * regularPatchCount * sizeof(float3) // Texture coordinates | 16 * regularPatchCount * sizeof(float2) // Normal control points | 16 * regularPatchCount * sizeof(float3) _RegularBezierControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.RegularPatchCount * 16)); _RegularTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.RegularPatchCount * 16)); if (Header.Version == 0x0101) { // Load normals _RegularNormals = new List<Vector3>(from.ReadStructure<Vector3>(Header.RegularPatchCount * 16)); } else { _RegularNormals = new List<Vector3>(); } // Quad Patches: // Bezier control points | 32 * quadPatchCount * sizeof(float3) // Gregory control points | 20 * quadPatchCount * sizeof(float3) // Pm control points | 24 * quadPatchCount * sizeof(float3) // Texture coordinates | 16 * quadPatchCount * sizeof(float2) // Normal control points | 16 * quadPatchCount * sizeof(float3) _QuadBezierControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 32)); _QuadGregoryControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 20)); _QuadPmControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 24)); _QuadTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.QuadPatchCount * 16)); if (Header.Version == 0x0101) { // Load normals _QuadNormals = new List<Vector3>(from.ReadStructure<Vector3>(Header.QuadPatchCount * 16)); } else { _QuadNormals = new List<Vector3>(); } // Triangle Patches: // Gregory control points | 15 * trianglePatchCount * sizeof(float3) // Pm control points | 19 * trianglePatchCount * sizeof(float3) // Texture coordinates | 12 * trianglePatchCount * sizeof(float2) _TriGregoryControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.TriPatchCount * 15)); _TriPmControlPoints = new List<Vector3>(from.ReadStructure<Vector3>(Header.TriPatchCount * 19)); _TriTextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(Header.TriPatchCount * 12)); // Part 2. Stencils: // faceTopologyCount | sizeof(int) // primitiveSize | sizeof(int) // Bezier Stencil | faceTopologyCount * 32 * m_primitiveSize * sizeof(float) // Gregory Stencil | faceTopologyCount * 20 * m_primitiveSize * sizeof(float) // regularFaceTopologyIndex | regularPatchCount * sizeof(uint) // regularVertexIndices | 16 * regularPatchCount * sizeof(uint) // regularStencilIndices | 16 * regularPatchCount * sizeof(uint) // quadVertexCount | quadPatchCount * sizeof(uint) // quadFaceTopologyIndex | quadPatchCount * sizeof(uint) // quadVertexIndices | primitiveSize * quadpatchCount * sizeof(uint) // quadStecilIndices | primitiveSize * quadPatchCount * sizeof(uint) FaceTopologyCount = from.ReadInt32(); PrimitiveSize = from.ReadInt32(); _BezierStencil = new List<float>(from.ReadStructure<float>(FaceTopologyCount * 32 * PrimitiveSize)); _GregoryStencil = new List<float>(from.ReadStructure<float>(FaceTopologyCount * 20 * PrimitiveSize)); _RegularFaceTopologyIndex = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount)); _RegularVertexIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 16)); _RegularStencilIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 16)); _QuadFaceVertexCount = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount)); _QuadFaceTopologyIndex = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount)); _QuadVertexIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * PrimitiveSize)); _QuadStencilIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * PrimitiveSize)); // Part 3. Input Mesh Topology: // Vertex count | sizeof(uint) // Vertices | vertexCount * sizeof(float3) // Tangents/Bitangents | vertexCount * 2 * sizeof(float3) // Valences | vertexCount * sizeof(int) // Texture coordinates | vertexCount * sizeof(float2) // Max valence | sizeof(uint) // Regular face indices | 4 * regularPatchCount * sizeof(uint) // Quad face indices | 4 * irregularpatchCount * sizeof(uint) // Triangle face indices | 3 * trianglePatchCount * sizeof(uint) VertexCount = from.ReadInt32(); _Vertices = new List<Vector3>(from.ReadStructure<Vector3>(VertexCount)); _Tangents = new List<Vector3>(from.ReadStructure<Vector3>(VertexCount * 2)); _Valences = new List<int>(from.ReadStructure<int>(VertexCount)); _TextureCoordinates = new List<Vector2>(from.ReadStructure<Vector2>(VertexCount)); MaxValence = from.ReadInt32(); _RegularFaceIndices = new List<int>(from.ReadStructure<int>(Header.RegularPatchCount * 4)); _QuadFaceIndices = new List<int>(from.ReadStructure<int>(Header.QuadPatchCount * 4)); _TriFaceIndices = new List<int>(from.ReadStructure<int>(Header.TriPatchCount * 3)); #region Calculate the patch corner point indices relative to the patch // For each regular patch (bicubic bezier) set the indices for the // regular that define the face (i.e. the 4 corners) var regularIndices = new int[Header.RegularPatchCount * 4]; for (int k = 0; k < Header.RegularPatchCount; k++) { for (int j = 0; j < 4; j++) { for (int i = 0; i < 16; i++) { if (_RegularVertexIndices[k * 16 + i] == _RegularFaceIndices[k * 4 + j]) { regularIndices[k * 4 + j] = i; } } } } // For an irregular patch (Gregory patch) set the indices for the // patch that define the face (i.e. the 4 corners) var quadIndices = new int[Header.QuadPatchCount * 4]; for (int k = 0; k < Header.QuadPatchCount; k++) { for (int j = 0; j < 4; j++) { for (int i = 0; i < PrimitiveSize; i++) { if (_QuadVertexIndices[k * PrimitiveSize + i] == _QuadFaceIndices[k * 4 + j]) { quadIndices[k * 4 + j] = i; } } } } #endregion #region Compute input mesh indices var indexCount = 6 * Header.RegularPatchCount + 6 * Header.QuadPatchCount + 3 * Header.TriPatchCount; //var indexCount2 = 8 * Header.RegularPatchCount + 8 * Header.QuadPatchCount; var indices = new int[indexCount]; int idx = 0; for (int i = 0; i < Header.RegularPatchCount; i++) { indices[idx++] = _RegularFaceIndices[4 * i + 2]; indices[idx++] = _RegularFaceIndices[4 * i + 0]; indices[idx++] = _RegularFaceIndices[4 * i + 1]; indices[idx++] = _RegularFaceIndices[4 * i + 0]; indices[idx++] = _RegularFaceIndices[4 * i + 2]; indices[idx++] = _RegularFaceIndices[4 * i + 3]; } for (int i = 0; i < Header.QuadPatchCount; i++) { indices[idx++] = _QuadFaceIndices[4 * i + 2]; indices[idx++] = _QuadFaceIndices[4 * i + 0]; indices[idx++] = _QuadFaceIndices[4 * i + 1]; indices[idx++] = _QuadFaceIndices[4 * i + 0]; indices[idx++] = _QuadFaceIndices[4 * i + 2]; indices[idx++] = _QuadFaceIndices[4 * i + 3]; } for (int i = 0; i < Header.TriPatchCount; i++) { indices[idx++] = _TriFaceIndices[4 * i + 2]; indices[idx++] = _TriFaceIndices[4 * i + 0]; indices[idx++] = _TriFaceIndices[4 * i + 1]; } _Indices = new List<int>(indices); #endregion // Calculate the bounding box Vector3 minCorner = _Vertices[0]; Vector3 maxCorner = _Vertices[0]; foreach (var vertex in _Vertices) { if (minCorner.X > vertex.X) minCorner.X = vertex.X; else if (maxCorner.X < vertex.X) maxCorner.X = vertex.X; if (minCorner.Y > vertex.Y) minCorner.Y = vertex.Y; else if (maxCorner.Y < vertex.Y) maxCorner.Y = vertex.Y; if (minCorner.Z > vertex.Z) minCorner.Z = vertex.Z; else if (maxCorner.Z < vertex.Z) maxCorner.Z = vertex.Z; } Center = (minCorner + maxCorner) * 0.5f; }
public void Deserialize(BinaryReader from) { // Bezier File Format : // Header ('BZR ') | sizeof(uint) // Version (1.1) | sizeof(uint) // Regular patch count | sizeof(uint) // Quad patch count | sizeof(uint) // Triangle patch count | sizeof(uint) this.Header = from.ReadStructure <BezierMesh.BezierHeader>(); byte[] expectedHeader = { Convert.ToByte(' '), Convert.ToByte('R'), Convert.ToByte('Z'), Convert.ToByte('B') }; if (BitConverter.IsLittleEndian) { Array.Reverse(expectedHeader); } if (Header.Header != BitConverter.ToInt32(expectedHeader, 0) || (Header.Version != 0x0100 && Header.Version != 0x0101)) { throw new ArgumentException("Incorrect input header or unsupported file format version"); } // Part 1. Precomputed Control Points: // Regular Patches: // Bezier control points | 16 * regularPatchCount * sizeof(float3) // Texture coordinates | 16 * regularPatchCount * sizeof(float2) // Normal control points | 16 * regularPatchCount * sizeof(float3) _RegularBezierControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.RegularPatchCount * 16)); _RegularTextureCoordinates = new List <Vector2>(from.ReadStructure <Vector2>(Header.RegularPatchCount * 16)); if (Header.Version == 0x0101) { // Load normals _RegularNormals = new List <Vector3>(from.ReadStructure <Vector3>(Header.RegularPatchCount * 16)); } else { _RegularNormals = new List <Vector3>(); } // Quad Patches: // Bezier control points | 32 * quadPatchCount * sizeof(float3) // Gregory control points | 20 * quadPatchCount * sizeof(float3) // Pm control points | 24 * quadPatchCount * sizeof(float3) // Texture coordinates | 16 * quadPatchCount * sizeof(float2) // Normal control points | 16 * quadPatchCount * sizeof(float3) _QuadBezierControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 32)); _QuadGregoryControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 20)); _QuadPmControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 24)); _QuadTextureCoordinates = new List <Vector2>(from.ReadStructure <Vector2>(Header.QuadPatchCount * 16)); if (Header.Version == 0x0101) { // Load normals _QuadNormals = new List <Vector3>(from.ReadStructure <Vector3>(Header.QuadPatchCount * 16)); } else { _QuadNormals = new List <Vector3>(); } // Triangle Patches: // Gregory control points | 15 * trianglePatchCount * sizeof(float3) // Pm control points | 19 * trianglePatchCount * sizeof(float3) // Texture coordinates | 12 * trianglePatchCount * sizeof(float2) _TriGregoryControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.TriPatchCount * 15)); _TriPmControlPoints = new List <Vector3>(from.ReadStructure <Vector3>(Header.TriPatchCount * 19)); _TriTextureCoordinates = new List <Vector2>(from.ReadStructure <Vector2>(Header.TriPatchCount * 12)); // Part 2. Stencils: // faceTopologyCount | sizeof(int) // primitiveSize | sizeof(int) // Bezier Stencil | faceTopologyCount * 32 * m_primitiveSize * sizeof(float) // Gregory Stencil | faceTopologyCount * 20 * m_primitiveSize * sizeof(float) // regularFaceTopologyIndex | regularPatchCount * sizeof(uint) // regularVertexIndices | 16 * regularPatchCount * sizeof(uint) // regularStencilIndices | 16 * regularPatchCount * sizeof(uint) // quadVertexCount | quadPatchCount * sizeof(uint) // quadFaceTopologyIndex | quadPatchCount * sizeof(uint) // quadVertexIndices | primitiveSize * quadpatchCount * sizeof(uint) // quadStecilIndices | primitiveSize * quadPatchCount * sizeof(uint) FaceTopologyCount = from.ReadInt32(); PrimitiveSize = from.ReadInt32(); _BezierStencil = new List <float>(from.ReadStructure <float>(FaceTopologyCount * 32 * PrimitiveSize)); _GregoryStencil = new List <float>(from.ReadStructure <float>(FaceTopologyCount * 20 * PrimitiveSize)); _RegularFaceTopologyIndex = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount)); _RegularVertexIndices = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 16)); _RegularStencilIndices = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 16)); _QuadFaceVertexCount = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount)); _QuadFaceTopologyIndex = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount)); _QuadVertexIndices = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * PrimitiveSize)); _QuadStencilIndices = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * PrimitiveSize)); // Part 3. Input Mesh Topology: // Vertex count | sizeof(uint) // Vertices | vertexCount * sizeof(float3) // Tangents/Bitangents | vertexCount * 2 * sizeof(float3) // Valences | vertexCount * sizeof(int) // Texture coordinates | vertexCount * sizeof(float2) // Max valence | sizeof(uint) // Regular face indices | 4 * regularPatchCount * sizeof(uint) // Quad face indices | 4 * irregularpatchCount * sizeof(uint) // Triangle face indices | 3 * trianglePatchCount * sizeof(uint) VertexCount = from.ReadInt32(); _Vertices = new List <Vector3>(from.ReadStructure <Vector3>(VertexCount)); _Tangents = new List <Vector3>(from.ReadStructure <Vector3>(VertexCount * 2)); _Valences = new List <int>(from.ReadStructure <int>(VertexCount)); _TextureCoordinates = new List <Vector2>(from.ReadStructure <Vector2>(VertexCount)); MaxValence = from.ReadInt32(); _RegularFaceIndices = new List <int>(from.ReadStructure <int>(Header.RegularPatchCount * 4)); _QuadFaceIndices = new List <int>(from.ReadStructure <int>(Header.QuadPatchCount * 4)); _TriFaceIndices = new List <int>(from.ReadStructure <int>(Header.TriPatchCount * 3)); #region Calculate the patch corner point indices relative to the patch // For each regular patch (bicubic bezier) set the indices for the // regular that define the face (i.e. the 4 corners) var regularIndices = new int[Header.RegularPatchCount * 4]; for (int k = 0; k < Header.RegularPatchCount; k++) { for (int j = 0; j < 4; j++) { for (int i = 0; i < 16; i++) { if (_RegularVertexIndices[k * 16 + i] == _RegularFaceIndices[k * 4 + j]) { regularIndices[k * 4 + j] = i; } } } } // For an irregular patch (Gregory patch) set the indices for the // patch that define the face (i.e. the 4 corners) var quadIndices = new int[Header.QuadPatchCount * 4]; for (int k = 0; k < Header.QuadPatchCount; k++) { for (int j = 0; j < 4; j++) { for (int i = 0; i < PrimitiveSize; i++) { if (_QuadVertexIndices[k * PrimitiveSize + i] == _QuadFaceIndices[k * 4 + j]) { quadIndices[k * 4 + j] = i; } } } } #endregion #region Compute input mesh indices var indexCount = 6 * Header.RegularPatchCount + 6 * Header.QuadPatchCount + 3 * Header.TriPatchCount; //var indexCount2 = 8 * Header.RegularPatchCount + 8 * Header.QuadPatchCount; var indices = new int[indexCount]; int idx = 0; for (int i = 0; i < Header.RegularPatchCount; i++) { indices[idx++] = _RegularFaceIndices[4 * i + 2]; indices[idx++] = _RegularFaceIndices[4 * i + 0]; indices[idx++] = _RegularFaceIndices[4 * i + 1]; indices[idx++] = _RegularFaceIndices[4 * i + 0]; indices[idx++] = _RegularFaceIndices[4 * i + 2]; indices[idx++] = _RegularFaceIndices[4 * i + 3]; } for (int i = 0; i < Header.QuadPatchCount; i++) { indices[idx++] = _QuadFaceIndices[4 * i + 2]; indices[idx++] = _QuadFaceIndices[4 * i + 0]; indices[idx++] = _QuadFaceIndices[4 * i + 1]; indices[idx++] = _QuadFaceIndices[4 * i + 0]; indices[idx++] = _QuadFaceIndices[4 * i + 2]; indices[idx++] = _QuadFaceIndices[4 * i + 3]; } for (int i = 0; i < Header.TriPatchCount; i++) { indices[idx++] = _TriFaceIndices[4 * i + 2]; indices[idx++] = _TriFaceIndices[4 * i + 0]; indices[idx++] = _TriFaceIndices[4 * i + 1]; } _Indices = new List <int>(indices); #endregion // Calculate the bounding box Vector3 minCorner = _Vertices[0]; Vector3 maxCorner = _Vertices[0]; foreach (var vertex in _Vertices) { if (minCorner.X > vertex.X) { minCorner.X = vertex.X; } else if (maxCorner.X < vertex.X) { maxCorner.X = vertex.X; } if (minCorner.Y > vertex.Y) { minCorner.Y = vertex.Y; } else if (maxCorner.Y < vertex.Y) { maxCorner.Y = vertex.Y; } if (minCorner.Z > vertex.Z) { minCorner.Z = vertex.Z; } else if (maxCorner.Z < vertex.Z) { maxCorner.Z = vertex.Z; } } Center = (minCorner + maxCorner) * 0.5f; }