Example #1
0
        public static void Write(BinaryWriter writer, SoftwareModel softwareModel, SoftwareMesh softwareMesh, bool loadColors, bool loadUVs, bool loadNormals)
        {
            List <BufferLayoutElement> elements;

            float[] vertices;
            int[]   indices;
            initData(softwareMesh, loadColors, loadUVs, loadNormals, out elements, out vertices, out indices);

            // name
            writer.Write(softwareMesh.Name);

            // material
            int materialIndex = -1;

            if (softwareMesh.Material != null)
            {
                for (int i = 0; i != softwareModel.Materials.Count; ++i)
                {
                    if (softwareMesh.Material == softwareModel.Materials[i])
                    {
                        materialIndex = i;
                        break;
                    }
                }
            }
            writer.Write(materialIndex);

            // elements
            writer.Write(elements.Count);
            foreach (var element in elements)
            {
                writer.Write((int)element.Type);
                writer.Write((int)element.Usage);
                writer.Write(element.StreamIndex);
                writer.Write(element.UsageIndex);
                writer.Write(element.FloatOffset);
            }

            // vertices
            writer.Write(vertices.Length);
            foreach (var vertex in vertices)
            {
                writer.Write(vertex);
            }

            // indices
            writer.Write(indices.Length);
            foreach (var index in indices)
            {
                writer.Write(index);
            }
        }
        public SoftwareObjectMesh(SoftwareModel model, RMX_Object o)
            : base(model, o)
        {
            if (o.Mesh != null)
            {
                foreach (var mesh in model.Meshes)
                {
                    if (o.Mesh.Name == mesh.Name)
                    {
                        Mesh = mesh;
                        break;
                    }
                }

                if (Mesh == null)
                {
                    Debug.ThrowError("SoftwareObjectMesh", "Failed to find mesh");
                }
            }
            else
            {
                Debug.ThrowError("SoftwareObjectMesh", "RMX_Object be linked to a Mesh object");
            }
        }
Example #3
0
        private static void initData(SoftwareMesh softwareMesh, bool loadColors, bool loadUVs, bool loadNormals, out List <BufferLayoutElement> elements, out float[] vertices, out int[] indices)
        {
            // get position float size
            int posFloatCount  = 0;
            var posElementType = BufferLayoutElementTypes.Vector3;

            switch (softwareMesh.Dimensions)
            {
            case 2:
                posElementType = BufferLayoutElementTypes.Vector2;
                posFloatCount  = 2;
                break;

            case 3:
                posElementType = BufferLayoutElementTypes.Vector3;
                posFloatCount  = 3;
                break;
            }

            // get vertex float size and create layout
            elements = new List <BufferLayoutElement>();
            int vertFloatCount = 0, posCount = 0, colorCount = 0, normalCount = 0, uvCount = 0;

            foreach (var key in softwareMesh.VertexComponentKeys)
            {
                switch (key.Key)
                {
                case VertexComponentKeyTypes.Positions:
                    elements.Add(new BufferLayoutElement(posElementType, BufferLayoutElementUsages.Position, 0, posCount, vertFloatCount));
                    vertFloatCount += posFloatCount;
                    ++posCount;
                    break;
                }
            }

            foreach (var key in softwareMesh.TriangleComponentKeys)
            {
                switch (key.Key)
                {
                case TriangleComponentKeyTypes.ColorComponents:
                    if (loadColors)
                    {
                        elements.Add(new BufferLayoutElement(BufferLayoutElementTypes.Vector4, BufferLayoutElementUsages.Color, 0, colorCount, vertFloatCount));
                        vertFloatCount += 4;
                        ++colorCount;
                    }
                    break;

                case TriangleComponentKeyTypes.NormalComponents:
                    if (loadNormals)
                    {
                        elements.Add(new BufferLayoutElement(BufferLayoutElementTypes.Vector3, BufferLayoutElementUsages.Normal, 0, normalCount, vertFloatCount));
                        vertFloatCount += 3;
                        ++normalCount;
                    }
                    break;

                case TriangleComponentKeyTypes.UVComponents:
                    if (loadUVs)
                    {
                        elements.Add(new BufferLayoutElement(BufferLayoutElementTypes.Vector2, BufferLayoutElementUsages.UV, 0, uvCount, vertFloatCount));
                        vertFloatCount += 2;
                        ++uvCount;
                    }
                    break;
                }
            }

            // create vertex buffer
            var meshProcessor = new HardwareMeshProcessor(softwareMesh, loadColors, loadUVs, loadNormals);

            vertices = new float[meshProcessor.Verticies.Count * vertFloatCount];
            int vi = 0;

            foreach (var vertex in meshProcessor.Verticies)
            {
                int posIndex = 0, colorIndex = 0, normIndex = 0, uvIndex = 0;
                foreach (var element in elements)
                {
                    switch (element.Usage)
                    {
                    case BufferLayoutElementUsages.Position:
                        vertices[vi]     = vertex.Positions[posIndex].X;
                        vertices[vi + 1] = vertex.Positions[posIndex].Y;
                        if (posFloatCount == 3)
                        {
                            vertices[vi + 2] = vertex.Positions[posIndex].Z;
                        }
                        vi += posFloatCount;
                        ++posIndex;
                        break;

                    case BufferLayoutElementUsages.Color:
                        if (loadColors)
                        {
                            vertices[vi]     = vertex.Colors[uvIndex].X;
                            vertices[vi + 1] = vertex.Colors[uvIndex].Y;
                            vi += 4;
                            ++colorIndex;
                        }
                        break;

                    case BufferLayoutElementUsages.Normal:
                        if (loadNormals)
                        {
                            vertices[vi]     = vertex.Normals[normIndex].X;
                            vertices[vi + 1] = vertex.Normals[normIndex].Y;
                            vertices[vi + 2] = vertex.Normals[normIndex].Z;
                            vi += 3;
                            ++normIndex;
                        }
                        break;

                    case BufferLayoutElementUsages.UV:
                        if (loadUVs)
                        {
                            vertices[vi]     = vertex.UVs[uvIndex].X;
                            vertices[vi + 1] = vertex.UVs[uvIndex].Y;
                            vi += 2;
                            ++uvIndex;
                        }
                        break;
                    }
                }
            }

            // create index buffer
            indices = new int[meshProcessor.Triangles.Count * 3];
            int ti = 0;

            foreach (var triangle in meshProcessor.Triangles)
            {
                indices[ti]     = triangle.Verticies[0].Index;
                indices[ti + 1] = triangle.Verticies[1].Index;
                indices[ti + 2] = triangle.Verticies[2].Index;
                ti += 3;
            }
        }
Example #4
0
        public HardwareMeshProcessor(SoftwareMesh mesh, bool loadColors, bool loadUVs, bool loadNormals)
        {
            this.mesh = mesh;

            // get vertex component types
            positions = new List <Vector3[]>();
            foreach (var key in mesh.VertexComponentKeys)
            {
                switch (key.Key)
                {
                case VertexComponentKeyTypes.Positions:
                    var vertexComponents = mesh.VetexComponents[key.Value];
                    if (vertexComponents.GetType() == typeof(Vector3[]))
                    {
                        positions.Add((Vector3[])vertexComponents);
                    }
                    else if (vertexComponents.GetType() == typeof(Vector2[]))
                    {
                        var verts    = (Vector2[])vertexComponents;
                        var newVerts = new Vector3[verts.Length];
                        for (int i = 0; i != verts.Length; ++i)
                        {
                            newVerts[i] = new Vector3(verts[i].X, verts[i].Y, 0);
                        }
                        positions.Add(newVerts);
                    }
                    else
                    {
                        Debug.ThrowError("HardwareMeshProcessor", "Unsuported VectorComponent type");
                    }
                    break;
                }
            }

            // get triangle component types
            if (loadColors)
            {
                colorComponents = new List <TriangleColorComponent[]>();
            }
            if (loadNormals)
            {
                normalComponents = new List <TriangleNormalComponent[]>();
            }
            if (loadUVs)
            {
                uvComponents = new List <TriangleUVComponent[]>();
            }
            foreach (var key in mesh.TriangleComponentKeys)
            {
                switch (key.Key)
                {
                case TriangleComponentKeyTypes.ColorComponents:
                    if (loadColors)
                    {
                        colorComponents.Add((TriangleColorComponent[])mesh.TriangleComponents[key.Value]);
                    }
                    break;

                case TriangleComponentKeyTypes.NormalComponents:
                    if (loadNormals)
                    {
                        normalComponents.Add((TriangleNormalComponent[])mesh.TriangleComponents[key.Value]);
                    }
                    break;

                case TriangleComponentKeyTypes.UVComponents:
                    if (loadUVs)
                    {
                        uvComponents.Add((TriangleUVComponent[])mesh.TriangleComponents[key.Value]);
                    }
                    break;
                }
            }

            // create triangles with there own verticies
            Verticies = new LinkedList <VertexProcessor>();
            Triangles = new List <TriangleProcessor>();
            foreach (var triangle in mesh.Triangles)
            {
                var newTriangle = new TriangleProcessor(triangle, this, loadColors, loadUVs, loadNormals);
            }

            // process (remove duplicate verticies from triangles)
            const float tolerance = .002f;
            int         count = Triangles.Count - 1, count2 = Triangles.Count;

            for (int i = 0; i != count; ++i)
            {
                for (int vi = 0; vi != 3; ++vi)
                {
                    var vertex = Triangles[i].Verticies[vi];
                    for (int i2 = i + 1; i2 != count2; ++i2)
                    {
                        for (int vi2 = 0; vi2 != 3; ++vi2)
                        {
                            var vertex2 = Triangles[i2].Verticies[vi2];
                            if (vertex == vertex2)
                            {
                                continue;
                            }

                            // position tolerance
                            bool canRemoveVertex = true;
                            for (int pi = 0; pi != vertex.Positions.Length; ++pi)
                            {
                                if (!vertex.Positions[pi].AproxEqualsBox(vertex2.Positions[pi], tolerance))
                                {
                                    canRemoveVertex = false;
                                    break;
                                }
                            }

                            // color tolerance
                            if (canRemoveVertex && loadColors)
                            {
                                for (int pi = 0; pi != vertex.Colors.Length; ++pi)
                                {
                                    if (!vertex.Colors[pi].AproxEqualsBox(vertex2.Colors[pi], tolerance))
                                    {
                                        canRemoveVertex = false;
                                        break;
                                    }
                                }
                            }

                            // normal tolerance
                            if (canRemoveVertex && loadNormals)
                            {
                                for (int pi = 0; pi != vertex.Normals.Length; ++pi)
                                {
                                    if (!vertex.Normals[pi].AproxEqualsBox(vertex2.Normals[pi], tolerance))
                                    {
                                        canRemoveVertex = false;
                                        break;
                                    }
                                }
                            }

                            // uv tolerance
                            if (canRemoveVertex && loadUVs)
                            {
                                for (int pi = 0; pi != vertex.UVs.Length; ++pi)
                                {
                                    if (!vertex.UVs[pi].AproxEqualsBox(vertex2.UVs[pi], tolerance))
                                    {
                                        canRemoveVertex = false;
                                        break;
                                    }
                                }
                            }

                            // remove vertex
                            if (canRemoveVertex)
                            {
                                Verticies.Remove(vertex2);
                                Triangles[i2].Verticies[vi2] = vertex;
                            }
                        }
                    }
                }
            }

            // process (set vertex indicies)
            int index = 0;

            foreach (var vertex in Verticies)
            {
                vertex.Index = index;
                ++index;
            }
        }