Exemplo n.º 1
0
        /// <summary>
        /// Creates and returns a mesh file
        /// </summary>
        /// <returns></returns>
        public Mesh GetMeshFile()
        {
            Mesh mesh = new Mesh
            {
                //TODO: bounding box stuff
                // Rigging
                Objects = new MeshObject[meshes.Count]
            };

            // create mesh objects and buffers
            BinaryWriter             vertexBuffer1     = new BinaryWriter(new MemoryStream());
            BinaryWriter             vertexBuffer2     = new BinaryWriter(new MemoryStream()); // there are actually 4 buffers, but only 2 seem to be used
            BinaryWriter             indexBuffer       = new BinaryWriter(new MemoryStream());
            int                      finalBufferOffset = 0;
            int                      meshIndex         = 0;
            Dictionary <string, int> meshGroups        = new Dictionary <string, int>();
            List <MeshRiggingGroup>  riggingGroups     = new List <MeshRiggingGroup>();

            foreach (var tempmesh in meshes)
            {
                MeshObject mo = new MeshObject
                {
                    Name = tempmesh.Name
                };
                if (meshGroups.ContainsKey(mo.Name))
                {
                    meshGroups[mo.Name] += 1;
                }
                else
                {
                    meshGroups.Add(mo.Name, 0);
                }

                mo.SubIndex             = meshGroups[mo.Name];
                mo.BoundingSphereCenter = new Formats.Vector3 {
                    X = tempmesh.BoundingSphere.X, Y = tempmesh.BoundingSphere.Y, Z = tempmesh.BoundingSphere.Z
                };
                mo.BoundingSphereRadius = tempmesh.BoundingSphere.W;

                mo.BoundingBoxMax = new Formats.Vector3 {
                    X = tempmesh.BbMax.X, Y = tempmesh.BbMax.Y, Z = tempmesh.BbMax.Z
                };
                mo.BoundingBoxMin = new Formats.Vector3 {
                    X = tempmesh.BbMin.X, Y = tempmesh.BbMin.Y, Z = tempmesh.BbMin.Z
                };
                mo.OrientedBoundingBoxCenter = new Formats.Vector3 {
                    X = tempmesh.ObbCenter.X, Y = tempmesh.ObbCenter.Y, Z = tempmesh.ObbCenter.Z
                };

                mo.OrientedBoundingBoxSize = new Formats.Vector3 {
                    X = tempmesh.ObbSize.X, Y = tempmesh.ObbSize.Y, Z = tempmesh.ObbSize.Z
                };

                mo.OrientedBoundingBoxTransform.Row1.X = tempmesh.ObbMatrix3X3[0];
                mo.OrientedBoundingBoxTransform.Row1.Y = tempmesh.ObbMatrix3X3[1];
                mo.OrientedBoundingBoxTransform.Row1.Z = tempmesh.ObbMatrix3X3[2];
                mo.OrientedBoundingBoxTransform.Row2.X = tempmesh.ObbMatrix3X3[3];
                mo.OrientedBoundingBoxTransform.Row2.Y = tempmesh.ObbMatrix3X3[4];
                mo.OrientedBoundingBoxTransform.Row2.Z = tempmesh.ObbMatrix3X3[5];
                mo.OrientedBoundingBoxTransform.Row3.X = tempmesh.ObbMatrix3X3[6];
                mo.OrientedBoundingBoxTransform.Row3.Y = tempmesh.ObbMatrix3X3[7];
                mo.OrientedBoundingBoxTransform.Row3.Z = tempmesh.ObbMatrix3X3[8];


                // Create Rigging
                riggingGroups.Add(SsbhRiggingCompiler.CreateRiggingGroup(mo.Name, (int)mo.SubIndex, tempmesh.Influences.ToArray()));

                // set object
                mesh.Objects[meshIndex++] = mo;

                mo.ParentBoneName = tempmesh.ParentBone;
                if (tempmesh.Influences.Count > 0 && (tempmesh.ParentBone == null || tempmesh.ParentBone.Equals("")))
                {
                    mo.RiggingType = RiggingType.Regular;
                }

                int stride1 = 0;
                int stride2 = 0;

                mo.VertexOffset  = (int)vertexBuffer1.BaseStream.Length;
                mo.VertexOffset2 = (int)vertexBuffer2.BaseStream.Length;
                mo.ElementOffset = (uint)indexBuffer.BaseStream.Length;

                // gather strides
                mo.Attributes = new MeshAttribute[tempmesh.VertexData.Count];
                int attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    // For some reason the attribute string doesn't match the attribute's name for Tangent0.
                    var attributeName = keypair.Key.Name;
                    if (keypair.Key.Name == "Tangent0")
                    {
                        attributeName = "map1";
                    }

                    MeshAttribute attr = new MeshAttribute
                    {
                        Name             = attributeName,
                        Index            = keypair.Key.Index,
                        BufferIndex      = keypair.Key.BufferIndex,
                        DataType         = keypair.Key.DataType,
                        BufferOffset     = keypair.Key.BufferIndex == 0 ? stride1 : stride2,
                        AttributeStrings = new MeshAttributeString[] { new MeshAttributeString()
                                                                       {
                                                                           Name = keypair.Key.Name
                                                                       } }
                    };
                    mo.Attributes[attributeIndex++] = attr;

                    if (keypair.Key.BufferIndex == 0)
                    {
                        stride1 += keypair.Key.ComponentCount * keypair.Key.DataType.GetSizeInBytes();
                    }
                    else
                    {
                        stride2 += keypair.Key.ComponentCount * keypair.Key.DataType.GetSizeInBytes();
                    }
                }

                // now that strides are known...
                long buffer1Start = vertexBuffer1.BaseStream.Length;
                long buffer2Start = vertexBuffer2.BaseStream.Length;
                vertexBuffer1.Write(new byte[stride1 * tempmesh.VertexCount]);
                vertexBuffer2.Write(new byte[stride2 * tempmesh.VertexCount]);
                attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    var     attr           = mo.Attributes[attributeIndex++];
                    float[] data           = keypair.Value;
                    var     buffer         = attr.BufferIndex == 0 ? vertexBuffer1 : vertexBuffer2;
                    int     bufferOffset   = (int)(attr.BufferIndex == 0 ? buffer1Start : buffer2Start);
                    int     stride         = (attr.BufferIndex == 0 ? stride1 : stride2);
                    int     componentCount = keypair.Key.ComponentCount;
                    for (int vertexIndex = 0; vertexIndex < tempmesh.VertexCount; vertexIndex++)
                    {
                        buffer.Seek(bufferOffset + stride * vertexIndex + attr.BufferOffset, SeekOrigin.Begin);
                        for (int j = 0; j < componentCount; j++)
                        {
                            WriteType(buffer, attr.DataType, data[vertexIndex * componentCount + j]);
                        }
                    }
                    // seek to end just to make sure
                    buffer.Seek((int)buffer.BaseStream.Length, SeekOrigin.Begin);
                }

                mo.FinalBufferOffset = finalBufferOffset;
                finalBufferOffset   += (4 + stride1) * tempmesh.VertexCount;
                mo.VertexCount       = tempmesh.VertexCount;
                mo.IndexCount        = tempmesh.Indices.Count;
                mo.Stride            = stride1;
                mo.Stride2           = stride2;

                // write index buffer
                if (tempmesh.VertexCount > ushort.MaxValue)
                {
                    mo.DrawElementType = DrawElementType.UnsignedInt;
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write(i);
                    }
                }
                else
                {
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write((ushort)i);
                    }
                }
            }

            mesh.PolygonIndexSize = indexBuffer.BaseStream.Length;
            mesh.BufferSizes      = new int[] { (int)vertexBuffer1.BaseStream.Length, (int)vertexBuffer2.BaseStream.Length, 0, 0 };
            mesh.PolygonBuffer    = ((MemoryStream)indexBuffer.BaseStream).ToArray();
            Console.WriteLine(mesh.PolygonBuffer.Length + " " + indexBuffer.BaseStream.Length);
            mesh.VertexBuffers = new MeshBuffer[]
            {
                new MeshBuffer {
                    Buffer = ((MemoryStream)vertexBuffer1.BaseStream).ToArray()
                },
                new MeshBuffer {
                    Buffer = ((MemoryStream)vertexBuffer2.BaseStream).ToArray()
                },
                new MeshBuffer {
                    Buffer = new byte[0]
                },
                new MeshBuffer {
                    Buffer = new byte[0]
                }
            };

            mesh.RiggingBuffers = riggingGroups.ToArray().OrderBy(o => o.MeshName, StringComparer.Ordinal).ToArray();

            vertexBuffer1.Close();
            vertexBuffer2.Close();
            indexBuffer.Close();

            return(mesh);
        }
Exemplo n.º 2
0
        /// <summary>
        /// Creates and returns a mesh file
        /// </summary>
        /// <returns></returns>
        public Mesh GetMeshFile()
        {
            Mesh mesh = new Mesh
            {
                //TODO: bounding box stuff
                // Rigging
                Objects = new MeshObject[meshes.Count]
            };

            // create mesh objects and buffers
            BinaryWriter             vertexBuffer1     = new BinaryWriter(new MemoryStream());
            BinaryWriter             vertexBuffer2     = new BinaryWriter(new MemoryStream()); // there are actually 4 buffers, but only 2 seem to be used
            BinaryWriter             indexBuffer       = new BinaryWriter(new MemoryStream());
            int                      finalBufferOffset = 0;
            int                      meshIndex         = 0;
            Dictionary <string, int> meshGroups        = new Dictionary <string, int>();
            List <MeshRiggingGroup>  riggingGroups     = new List <MeshRiggingGroup>();

            foreach (var tempmesh in meshes)
            {
                MeshObject mo = new MeshObject
                {
                    Name = tempmesh.Name
                };
                if (meshGroups.ContainsKey(mo.Name))
                {
                    meshGroups[mo.Name] += 1;
                }
                else
                {
                    meshGroups.Add(mo.Name, 0);
                }

                mo.SubMeshIndex         = meshGroups[mo.Name];
                mo.BoundingSphereX      = tempmesh.BoundingSphere.X;
                mo.BoundingSphereY      = tempmesh.BoundingSphere.Y;
                mo.BoundingSphereZ      = tempmesh.BoundingSphere.Z;
                mo.BoundingSphereRadius = tempmesh.BoundingSphere.W;

                mo.MaxBoundingBoxX = tempmesh.BbMax.X;
                mo.MaxBoundingBoxY = tempmesh.BbMax.Y;
                mo.MaxBoundingBoxZ = tempmesh.BbMax.Z;
                mo.MinBoundingBoxX = tempmesh.BbMin.X;
                mo.MinBoundingBoxY = tempmesh.BbMin.Y;
                mo.MinBoundingBoxZ = tempmesh.BbMin.Z;

                mo.ObbCenterX = tempmesh.ObbCenter.X;
                mo.ObbCenterY = tempmesh.ObbCenter.Y;
                mo.ObbCenterZ = tempmesh.ObbCenter.Z;

                mo.ObbSizeX = tempmesh.ObbSize.X;
                mo.ObbSizeY = tempmesh.ObbSize.Y;
                mo.ObbSizeZ = tempmesh.ObbSize.Z;

                mo.M11 = tempmesh.ObbMatrix3X3[0];
                mo.M12 = tempmesh.ObbMatrix3X3[1];
                mo.M13 = tempmesh.ObbMatrix3X3[2];
                mo.M21 = tempmesh.ObbMatrix3X3[3];
                mo.M22 = tempmesh.ObbMatrix3X3[4];
                mo.M23 = tempmesh.ObbMatrix3X3[5];
                mo.M31 = tempmesh.ObbMatrix3X3[6];
                mo.M32 = tempmesh.ObbMatrix3X3[7];
                mo.M33 = tempmesh.ObbMatrix3X3[8];


                // Create Rigging
                riggingGroups.Add(SsbhRiggingCompiler.CreateRiggingGroup(mo.Name, (int)mo.SubMeshIndex, tempmesh.Influences.ToArray()));

                // set object
                mesh.Objects[meshIndex++] = mo;

                mo.ParentBoneName = tempmesh.ParentBone;
                if (tempmesh.Influences.Count > 0 && (tempmesh.ParentBone == null || tempmesh.ParentBone.Equals("")))
                {
                    mo.HasRigging = 1;
                }

                int stride1 = 0;
                int stride2 = 0;

                mo.VertexOffset  = (int)vertexBuffer1.BaseStream.Length;
                mo.VertexOffset2 = (int)vertexBuffer2.BaseStream.Length;
                mo.ElementOffset = (uint)indexBuffer.BaseStream.Length;

                // gather strides
                mo.Attributes = new MeshAttribute[tempmesh.VertexData.Count];
                int attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    MeshAttribute attr = new MeshAttribute
                    {
                        Name             = GetAttributeName(keypair.Key),
                        Index            = GetAttributeIndex(keypair.Key),
                        BufferIndex      = GetBufferIndex(keypair.Key),
                        DataType         = GetAttributeDataType(keypair.Key),
                        BufferOffset     = (GetBufferIndex(keypair.Key) == 0) ? stride1 : stride2,
                        AttributeStrings = new MeshAttributeString[] { new MeshAttributeString()
                                                                       {
                                                                           Name = keypair.Key.ToString()
                                                                       } }
                    };
                    mo.Attributes[attributeIndex++] = attr;

                    if (GetBufferIndex(keypair.Key) == 0)
                    {
                        stride1 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key);
                    }
                    else
                    {
                        stride2 += GetAttributeSize(keypair.Key) * GetAttributeDataSize(keypair.Key);
                    }
                }

                // now that strides are known...
                long buffer1Start = vertexBuffer1.BaseStream.Length;
                long buffer2Start = vertexBuffer2.BaseStream.Length;
                vertexBuffer1.Write(new byte[stride1 * tempmesh.VertexCount]);
                vertexBuffer2.Write(new byte[stride2 * tempmesh.VertexCount]);
                attributeIndex = 0;
                foreach (var keypair in tempmesh.VertexData)
                {
                    var     attr         = mo.Attributes[attributeIndex++];
                    float[] data         = keypair.Value;
                    var     buffer       = attr.BufferIndex == 0 ? vertexBuffer1 : vertexBuffer2;
                    int     bufferOffset = (int)(attr.BufferIndex == 0 ? buffer1Start : buffer2Start);
                    int     stride       = (attr.BufferIndex == 0 ? stride1 : stride2);
                    int     size         = GetAttributeSize(keypair.Key);
                    for (int vertexIndex = 0; vertexIndex < tempmesh.VertexCount; vertexIndex++)
                    {
                        buffer.Seek(bufferOffset + stride * vertexIndex + attr.BufferOffset, SeekOrigin.Begin);
                        for (int j = 0; j < size; j++)
                        {
                            WriteType(buffer, attr.DataType, data[vertexIndex * size + j]);
                        }
                    }
                    // seek to end just to make sure
                    buffer.Seek((int)buffer.BaseStream.Length, SeekOrigin.Begin);
                }

                mo.FinalBufferOffset = finalBufferOffset;
                finalBufferOffset   += (4 + stride1) * tempmesh.VertexCount;
                mo.VertexCount       = tempmesh.VertexCount;
                mo.IndexCount        = tempmesh.Indices.Count;
                mo.Stride            = stride1;
                mo.Stride2           = stride2;

                // write index buffer
                if (tempmesh.VertexCount > ushort.MaxValue)
                {
                    mo.DrawElementType = 1;
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write(i);
                    }
                }
                else
                {
                    foreach (var i in tempmesh.Indices)
                    {
                        indexBuffer.Write((ushort)i);
                    }
                }
            }

            mesh.PolygonIndexSize = indexBuffer.BaseStream.Length;
            mesh.BufferSizes      = new int[] { (int)vertexBuffer1.BaseStream.Length, (int)vertexBuffer2.BaseStream.Length, 0, 0 };
            mesh.PolygonBuffer    = ((MemoryStream)indexBuffer.BaseStream).ToArray();
            Console.WriteLine(mesh.PolygonBuffer.Length + " " + indexBuffer.BaseStream.Length);
            mesh.VertexBuffers = new MeshBuffer[]
            {
                new MeshBuffer {
                    Buffer = ((MemoryStream)vertexBuffer1.BaseStream).ToArray()
                },
                new MeshBuffer {
                    Buffer = ((MemoryStream)vertexBuffer2.BaseStream).ToArray()
                },
                new MeshBuffer {
                    Buffer = new byte[0]
                },
                new MeshBuffer {
                    Buffer = new byte[0]
                }
            };

            mesh.RiggingBuffers = riggingGroups.ToArray().OrderBy(o => o.Name, StringComparer.Ordinal).ToArray();

            vertexBuffer1.Close();
            vertexBuffer2.Close();
            indexBuffer.Close();

            return(mesh);
        }