Example #1
0
        void AppendIndex(int index, ObjLine line)
        {
            string[] indices = line.Tokens[index].Split('/');

            // Required: Position
            int positionIndex = int.Parse(indices[0], CultureInfo.InvariantCulture) - positionsIndexOffset;
            int texCoordIndex = -1;
            int normalIndex   = -1;

            // Optional: Texture coordinate
            if (indices.Length > 1 && indices[1].Equals(string.Empty) == false)
            {
                texCoordIndex = int.Parse(indices[1]) - textureCoordinatesIndexOffset;
            }

            // Optional: Normal
            if (indices.Length > 2 && indices[2].Equals(string.Empty) == false)
            {
                normalIndex = int.Parse(indices[2]) - normalsIndexOffset;
            }

            // Build vertex
            var vertex = new PositionNormalTextured {
                Position = positions[positionIndex]
            };

            if (texCoordIndex >= 0)
            {
                vertex.TextureCoordinates = textureCoordinates[texCoordIndex];
            }

            if (normalIndex >= 0)
            {
                vertex.Normal = normals[normalIndex];
            }

            // check if the vertex does not already exists
            string hash = vertex.ToString();
            int    vertexIndex;

            if (!registeredVertices.TryGetValue(hash, out vertexIndex))
            {
                stagingVertices.Add(vertex);
                vertexIndex = stagingVertices.Count - 1;
                registeredVertices.Add(hash, vertexIndex);
            }

            stagingIndices.Add(vertexIndex);
        }
Example #2
0
        void ParseMesh(ModelMesh modelMesh, BabylonScene scene, BabylonSkeleton skeleton)
        {
            var proxyID   = ProxyMesh.CreateBabylonMesh(modelMesh.Name, scene);
            int indexName = 0;

            foreach (var part in modelMesh.MeshParts)
            {
                var material = exportedMaterials.First(m => m.Name == part.Effect.GetHashCode().ToString());

                var indices = new ushort[part.PrimitiveCount * 3];
                part.IndexBuffer.GetData(part.StartIndex * 2, indices, 0, indices.Length);

                if (part.VertexBuffer.VertexDeclaration.VertexStride > PositionNormalTextured.Stride)
                {
                    var mesh     = new Mesh <PositionNormalTexturedWeights>(material);
                    var vertices = new PositionNormalTexturedWeights[part.NumVertices];

                    part.VertexBuffer.GetData(part.VertexOffset * part.VertexBuffer.VertexDeclaration.VertexStride, vertices, 0, vertices.Length, part.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                    }

                    mesh.AddPart(indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }
                else
                {
                    var mesh     = new Mesh <PositionNormalTextured>(material);
                    var vertices = new PositionNormalTextured[part.NumVertices];
                    part.VertexBuffer.GetData(part.VertexOffset * PositionNormalTextured.Stride, vertices, 0, vertices.Length, PositionNormalTextured.Stride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                    }

                    mesh.AddPart(indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }

                indexName++;
            }
        }
        /// <summary>
        /// Creates a new <see cref="Mesh"/> representing a textured sphere with spherical mapping.
        /// </summary>
        /// <param name="device">The <see cref="Device"/> to create the mesh in</param>
        /// <param name="radius">The radius of the sphere.</param>
        /// <param name="slices">The number of vertical slices to divide the sphere into.</param>
        /// <param name="stacks">The number of horizontal stacks to divide the sphere into.</param>
        /// <remarks>The sphere is formed like the one created by <see cref="Mesh.CreateSphere"/>.</remarks>
        public static Mesh Sphere(Device device, float radius, int slices, int stacks)
        {
            #region Sanity checks
            if (device == null)
            {
                throw new ArgumentNullException(nameof(device));
            }
            if (slices <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(slices));
            }
            if (stacks <= 0)
            {
                throw new ArgumentOutOfRangeException(nameof(stacks));
            }
            #endregion

            int numVertexes = (slices + 1) * (stacks + 1);
            int numFaces    = slices * stacks * 2;
            int indexCount  = numFaces * 3;

            var mesh = new Mesh(device, numFaces, numVertexes, MeshFlags.Managed, PositionNormalTextured.Format);

            #region Build sphere vertexes
            var vertexes  = new PositionNormalTextured[mesh.VertexCount];
            int vertIndex = 0;
            for (int slice = 0; slice <= slices; slice++)
            {
                float alphaY = (float)slice / slices * (float)Math.PI * 2.0f; // Angle around Y-axis
                for (int stack = 0; stack <= stacks; stack++)
                {
                    if (slice == slices)
                    {
                        vertexes[vertIndex] = vertexes[stack];
                    }
                    else
                    {
                        var   pnt    = new PositionNormalTextured();
                        float alphaZ = ((stack - stacks * 0.5f) / stacks) * (float)Math.PI * 1.0f; // Angle around Z-axis
                        pnt.X  = (float)(Math.Cos(alphaY) * radius) * (float)Math.Cos(alphaZ);
                        pnt.Z  = (float)(Math.Sin(alphaY) * radius) * (float)Math.Cos(alphaZ);
                        pnt.Y  = (float)(Math.Sin(alphaZ) * radius);
                        pnt.Nx = pnt.X / radius;
                        pnt.Ny = pnt.Y / radius;
                        pnt.Nz = pnt.Z / radius;
                        pnt.Tv = 0.5f - (float)(Math.Asin(pnt.Y / radius) / Math.PI);
                        vertexes.SetValue(pnt, vertIndex);
                    }
                    vertexes[vertIndex++].Tu = (float)slice / slices;
                }
            }
            #endregion

            BufferHelper.WriteVertexBuffer(mesh, vertexes);

            #region Build index buffer
            var indexes = new short[indexCount];
            int i       = 0;
            for (short x = 0; x < slices; x++)
            {
                var leftVertex  = (short)((stacks + 1) * x);
                var rightVertex = (short)(leftVertex + stacks + 1);
                for (int y = 0; y < stacks; y++)
                {
                    indexes[i++] = rightVertex;
                    indexes[i++] = leftVertex;
                    indexes[i++] = (short)(leftVertex + 1);
                    indexes[i++] = rightVertex;
                    indexes[i++] = (short)(leftVertex + 1);
                    indexes[i++] = (short)(rightVertex + 1);
                    leftVertex++;
                    rightVertex++;
                }
            }
            #endregion

            BufferHelper.WriteIndexBuffer(mesh, indexes);

            return(mesh);
        }
Example #4
0
        void ParseMesh(ModelMesh modelMesh, BabylonScene scene, BabylonSkeleton skeleton, bool rightToLeft)
        {
            var proxyID = ProxyMesh.CreateBabylonMesh(modelMesh.Name, scene);
            int indexName = 0;

            foreach (var part in modelMesh.MeshParts)
            {
                var material = exportedMaterials.First(m => m.Name == part.Effect.GetHashCode().ToString());

                var indices = new ushort[part.PrimitiveCount * 3];
                part.IndexBuffer.GetData(part.StartIndex * 2, indices, 0, indices.Length);

                if (rightToLeft)
                {
                    for (int ib = 0; ib < indices.Length; ib += 3) // reverse winding of triangles
                    {
                        ushort ti = indices[ib];
                        indices[ib] = indices[ib + 2];
                        indices[ib + 2] = ti;
                    }
                }

                if (part.VertexBuffer.VertexDeclaration.VertexStride >= PositionNormalTexturedWeights.Stride)
                {
                    var mesh = new Mesh<PositionNormalTexturedWeights>(material);
                    var vertices = new PositionNormalTexturedWeights[part.NumVertices];

                    part.VertexBuffer.GetData(part.VertexOffset * part.VertexBuffer.VertexDeclaration.VertexStride, vertices, 0, vertices.Length, part.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                        if (rightToLeft)
                        {
                            vertices[index].Position.Z = -vertices[index].Position.Z;
                            vertices[index].Normal.Z = -vertices[index].Normal.Z;
                        }
                    }

                    mesh.AddPart(modelMesh.Name+"#"+indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }
                else
                {
                    if (part.VertexBuffer.VertexDeclaration.VertexStride < PositionNormalTextured.Stride) return; // Error: Not a PositionNormalTextured mesh!
                    var mesh = new Mesh<PositionNormalTextured>(material);
                    var vertices = new PositionNormalTextured[part.NumVertices];
                    part.VertexBuffer.GetData(part.VertexOffset * part.VertexBuffer.VertexDeclaration.VertexStride, vertices, 0, vertices.Length, part.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                        if (rightToLeft)
                        {
                            vertices[index].Position.Z = -vertices[index].Position.Z;
                            vertices[index].Normal.Z = -vertices[index].Normal.Z;
                        }
                    }

                    mesh.AddPart(modelMesh.Name + "#" + indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }

                indexName++;
            }
        }
Example #5
0
        void ParseMesh(ModelMesh modelMesh, BabylonScene scene, BabylonSkeleton skeleton)
        {
            var proxyID = ProxyMesh.CreateBabylonMesh(modelMesh.Name, scene);
            int indexName = 0;

            foreach (var part in modelMesh.MeshParts)
            {
                var material = exportedMaterials.First(m => m.Name == part.Effect.GetHashCode().ToString());

                var indices = new ushort[part.PrimitiveCount * 3];
                part.IndexBuffer.GetData(part.StartIndex * 2, indices, 0, indices.Length);

                if (part.VertexBuffer.VertexDeclaration.VertexStride >= PositionNormalTexturedWeights.Stride)
                {
                    var mesh = new Mesh<PositionNormalTexturedWeights>(material);
                    var vertices = new PositionNormalTexturedWeights[part.NumVertices];

                    part.VertexBuffer.GetData(part.VertexOffset * part.VertexBuffer.VertexDeclaration.VertexStride, vertices, 0, vertices.Length, part.VertexBuffer.VertexDeclaration.VertexStride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                    }

                    mesh.AddPart(indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }
                else
                {
                    var mesh = new Mesh<PositionNormalTextured>(material);
                    var vertices = new PositionNormalTextured[part.NumVertices];
                    part.VertexBuffer.GetData(part.VertexOffset * PositionNormalTextured.Stride, vertices, 0, vertices.Length, PositionNormalTextured.Stride);

                    for (int index = 0; index < vertices.Length; index++)
                    {
                        vertices[index].TextureCoordinates.Y = 1.0f - vertices[index].TextureCoordinates.Y;
                    }

                    mesh.AddPart(indexName.ToString(), vertices.ToList(), indices.Select(i => (int)i).ToList());
                    mesh.CreateBabylonMesh(scene, proxyID, skeleton);
                }

                indexName++;
            }
        }
        public Mesh(PositionNormalTextured[] vertices, int[] indices)
        {
            this.vertices = vertices;

            this.indices = new uint[indices.Length];
            for (int c = 0; c < indices.Length; c++)
            {
                this.indices[c] = (uint)indices[c];
            }

            Vector3[] points = new Vector3[vertices.Length];
            for (int i = 0; i < vertices.Length; ++i)
                points[i] = vertices[i].Position;
            boundingSphere = SharpDX.BoundingSphere.FromPoints(points);
        }
        private void LoadMeshFrom3ds(string filename, float scale)
        {
            // Force garbage collection to ensure that unmanaged resources are released.
            // Temporary workaround until unmanaged resource leak is identified
            GC.Collect();

            int i;

            ushort sectionID;
            uint sectionLength;

            string name = "";
            string material = "";
            int triangleCount = 0;
            int vertexCount = 0;
            List<PositionNormalTextured> vertexList = new List<PositionNormalTextured>();
            List<int> indexList = new List<int>();
            List<int> attribList = new List<int>();
            //List<int[]> applyLists = new List<int[]>();
            //List<int> applyListsIndex = new List<int>();
            List<string> materialNames = new List<string>();
            int currentMaterialIndex = -1;
            Material currentMaterial = new Material();
            int attributeID = 0;

            int count = 0;
            UInt16 lastID = 0;
            bool exit = false;
            bool normalMapFound = false;

            float offsetX = 0;
            float offsetY = 0;
            float offsetZ = 0;
            List<ObjectNode> objects = new List<ObjectNode>();
            ObjectNode currentObject = null;
            List<int> objHierarchy = new List<int>();
            List<string> objNames = new List<string>();
            Dictionary<string, ObjectNode> objectTable = new Dictionary<string, ObjectNode>();

            int dummyCount = 0;

            using (Stream fs = new FileStream(filename, FileMode.Open))
            {
                BinaryReader br = new BinaryReader(fs);
                long length = fs.Length - 1;
                int startMapIndex = 0;
                int startTriangleIndex = 0;
                while (br.BaseStream.Position < length && !exit) //Loop to scan the whole file
                {
                    sectionID = br.ReadUInt16();
                    sectionLength = br.ReadUInt32();

                    switch (sectionID)
                    {

                        //This section the begining of the file
                        case 0x4d4d:
                            break;

                        // This section marks the edit section containing the 3d models (3d3d get it? very punny!)
                        case 0x3d3d:
                            break;

                        // Object section contains meshes, etc.
                        case 0x4000:
                            name = "";
                            Byte b;
                            do
                            {
                                b = br.ReadByte();
                                if (b > 0)
                                {
                                    name += (char)b;
                                }

                            } while (b != '\0');

                            currentObject = new ObjectNode();
                            currentObject.Name = name;
                            objects.Add(currentObject);
                            if (!objectTable.ContainsKey(currentObject.Name))
                            {
                                objectTable.Add(currentObject.Name, currentObject);
                            }

                            break;

                        // Marks the start of a mesh section
                        case 0x4100:
                            startMapIndex = vertexList.Count;
                            startTriangleIndex = indexList.Count / 3;
                            break;

                        // This section has the vertex list.. Maps to Vertext buffer in Direct3d
                        case 0x4110:
                            vertexCount = br.ReadUInt16();

                            for (i = 0; i < vertexCount; i++)
                            {
                                float x = br.ReadSingle() - offsetX;
                                float y = br.ReadSingle() - offsetY;
                                float z = br.ReadSingle() - offsetZ;

                                PositionNormalTextured vert = new PositionNormalTextured(x * scale, z * scale, y * scale, 0, 0, 0, 0, 0);
                                vertexList.Add(vert);
                            }
                            break;

                        // This section is a tiangle index list. Maps to Index Buffer in Direct3d
                        case 0x4120:
                            {
                                int triCount = br.ReadUInt16();
                                triangleCount += triCount;

                                for (i = 0; i < triCount; i++)
                                {
                                    int aa = br.ReadUInt16() + startMapIndex;
                                    int bb = br.ReadUInt16() + startMapIndex;
                                    int cc = br.ReadUInt16() + startMapIndex;
                                    indexList.Add(cc);
                                    indexList.Add(bb);
                                    indexList.Add(aa);
                                    UInt16 flags = br.ReadUInt16();
                                }
                            }
                            break;

                        // Material for face from start face to triCount
                        case 0x4130:
                            {
                                material = "";
                                i = 0;
                                byte b1;
                                do
                                {
                                    b1 = br.ReadByte();
                                    if (b1 > 0)
                                    {
                                        material += (char)b1;
                                    }

                                    i++;
                                } while (b1 != '\0');
                                int triCount = br.ReadUInt16();
                                int[] applyList = new int[triCount];

                                attributeID = GetMaterialID(material, materialNames);

                                for (i = 0; i < triCount; i++)
                                {
                                    applyList[i] = br.ReadUInt16() + startTriangleIndex;
                                }
                                currentObject.ApplyLists.Add(applyList);
                                currentObject.ApplyListsIndex.Add(attributeID);

                            }
                            break;

                        // Section for UV texture maps
                        case 0x4140:
                            count = br.ReadUInt16();
                            for (i = 0; i < count; i++)
                            {
                                PositionNormalTextured vert = vertexList[startMapIndex + i];
                                Vector2 texCoord = new Vector2(br.ReadSingle(), FlipV ? (1.0f - br.ReadSingle()) : (br.ReadSingle()));
                                vertexList[startMapIndex + i] = new PositionNormalTextured(vert.Position, Vector3.Zero, texCoord);
                            }
                            break;

                        // Section for Smoothing Groups
                        //case 0x4150:
                        //    count = br.ReadUInt16();
                        //    for (i = 0; i < count; i++)
                        //    {
                        //        CustomVertex.PositionNormalTextured vert = vertexList[startMapIndex + i];
                        //        vertexList[startMapIndex + i] = new CustomVertex.PositionNormalTextured(vert.Position, new Vector3(0,0,0), br.ReadSingle(), FlipV ? (1.0f -  br.ReadSingle() ) : (br.ReadSingle()));
                        //    }
                        //    break;
                        case 0x4160:
                            float[] mat = new float[12];
                            for (i = 0; i < 12; i++)
                            {
                                mat[i] = br.ReadSingle();
                            }
                            //offsetX = mat[9];
                            //offsetY = mat[11];
                            //offsetZ = mat[10];

                            if (objectTable.ContainsKey(name))
                            {
                                objectTable[name].LocalMat = new Matrix3d(
                                    mat[0], mat[1], mat[2], 0,
                                    mat[3], mat[4], mat[5], 0,
                                    mat[6], mat[7], mat[8], 0,
                                    mat[9], mat[10], mat[11], 1);

                                objectTable[name].LocalMat.Invert();

                                //objectTable[name].PivotPoint = new Vector3(mat[9]*mat[0],mat[10]*mat[1],mat[11]*mat[2]);
                            }

                            break;
                        // Materials library section
                        case 0xAFFF:
                            break;
                        // Material Name
                        case 0xA000:
                            {
                                string matName = "";
                                i = 0;
                                byte b2;
                                do
                                {
                                    b2 = br.ReadByte();
                                    if (b2 > 0)
                                    {
                                        matName += (char)b2;
                                    }

                                    i++;
                                } while (b2 != '\0');
                                materialNames.Add(matName);

                                if (currentMaterialIndex > -1)
                                {
                                    addMaterial(currentMaterial);
                                }

                                currentMaterialIndex++;

                                currentMaterial = new Material();
                                currentMaterial.Diffuse = System.Drawing.Color.White;
                                currentMaterial.Ambient = System.Drawing.Color.White;
                                currentMaterial.Specular = System.Drawing.Color.Black;
                                currentMaterial.SpecularSharpness = 30.0f;
                                currentMaterial.Opacity = 1.0f;
                            }
                            break;

                        // Ambient color
                        case 0xA010:
                            currentMaterial.Ambient = LoadColorChunk(br);
                            break;

                        // Diffuse color
                        case 0xA020:
                            currentMaterial.Diffuse = LoadColorChunk(br);
                            break;

                        // Specular color
                        case 0xA030:
                            currentMaterial.Specular = LoadColorChunk(br);
                            break;

                        // Specular power
                        case 0xA040:
                            // This is just a reasonable guess at the mapping from percentage to
                            // specular exponent used by 3D Studio.
                            currentMaterial.SpecularSharpness = 1.0f + 2 * LoadPercentageChunk(br);

                            // Minimum sharpness of 10 enforced here because of bad specular exponents
                            // in ISS model.
                            // TODO: Fix ISS and permit lower specular exponents here
                            currentMaterial.SpecularSharpness = Math.Max(10.0f, currentMaterial.SpecularSharpness);
                            break;

                        //Texture map file
                        case 0xA200:
                            break;

                        // Texture file name
                        case 0xA300:
                            {
                                string textureFilename = "";
                                i = 0;
                                byte b2;
                                do
                                {
                                    b2 = br.ReadByte();
                                    if (b2 > 0)
                                    {
                                        textureFilename += (char)b2;
                                    }

                                    i++;
                                } while (b2 != '\0');
                                string path = filename.Substring(0, filename.LastIndexOf('\\') + 1);
                                try
                                {
                                    Texture11 tex = LoadTexture(path + textureFilename);

                                    if (tex != null)
                                    {
                                        meshTextures.Add(tex);
                                        meshFilenames.Add(textureFilename);

                                        // The ISS model has black for the diffuse color; to work around this
                                        // we'll set the diffuse color to white when there's a texture present.
                                        // The correct fix is to modify the 3ds model of ISS.
                                        currentMaterial.Diffuse = System.Drawing.Color.White;
                                    }
                                    else
                                    {
                                        meshTextures.Add(null);
                                    }
                                }
                                catch
                                {
                                    meshTextures.Add(null);
                                }
                            }
                            break;

                        // Bump map
                        case 0xA230:
                            {
                                float percentage = LoadPercentageChunk(br);

                                int nameId = br.ReadUInt16();
                                uint nameBlockLength = br.ReadUInt32();
                                string textureFilename = "";
                                i = 0;
                                byte b2;
                                do
                                {
                                    b2 = br.ReadByte();
                                    if (b2 > 0)
                                    {
                                        textureFilename += (char)b2;
                                    }

                                    i++;
                                } while (b2 != '\0');

                                string path = filename.Substring(0, filename.LastIndexOf('\\') + 1);
                                try
                                {
                                    Texture11 tex = LoadTexture(path + textureFilename);

                                    if (tex != null)
                                    {
                                        meshNormalMaps.Add(tex);
                                        meshFilenames.Add(textureFilename);

                                        // Indicate that we have a normal map so that we know to generate tangent vectors for the mesh
                                        normalMapFound = true;
                                    }
                                    else
                                    {
                                        meshNormalMaps.Add(null);
                                    }

                                }
                                catch
                                {
                                    meshNormalMaps.Add(null);
                                }
                            }

                            break;

                        // Specular map
                        case 0xA204:
                            {
                                float strength = LoadPercentageChunk(br);

                                int nameId = br.ReadUInt16();
                                uint nameBlockLength = br.ReadUInt32();
                                string textureFilename = "";
                                i = 0;
                                byte b2;
                                do
                                {
                                    b2 = br.ReadByte();
                                    if (b2 > 0)
                                    {
                                        textureFilename += (char)b2;
                                    }

                                    i++;
                                } while (b2 != '\0');

                                string path = filename.Substring(0, filename.LastIndexOf('\\') + 1);
                                try
                                {
                                    Texture11 tex = LoadTexture(path + textureFilename);
                                    if (tex != null)
                                    {
                                        meshSpecularTextures.Add(tex);
                                        meshFilenames.Add(textureFilename);

                                        // Set the current specular color from the specular texture strength
                                        int gray = (int)(255.99f * strength / 100.0f);
                                        currentMaterial.Specular = System.Drawing.Color.FromArgb(255, gray, gray, gray);
                                    }
                                    else
                                    {
                                        meshSpecularTextures.Add(null);
                                    }
                                }
                                catch
                                {
                                    meshSpecularTextures.Add(null);
                                }
                            }

                            break;
                        case 0xB000:
                            break;
                        case 0xB002:
                            break;
                        case 0xB010:
                            {
                                name = "";
                                i = 0;
                                byte b1;
                                do
                                {
                                    b1 = br.ReadByte();
                                    if (b1 > 0)
                                    {
                                        name += (char)b1;
                                    }

                                    i++;
                                } while (b1 != '\0');
                                int dum1 = (int)br.ReadUInt16();
                                int dum2 = (int)br.ReadUInt16();
                                int level = (int)br.ReadUInt16();

                                if (level == 65535)
                                {
                                    level = -1;
                                }
                                if (name.StartsWith("$"))
                                {
                                    dummyCount++;

                                }
                                else
                                {
                                    objNames.Add(name);
                                }
                                objHierarchy.Add(level);

                                if (objectTable.ContainsKey(name))
                                {

                                    objectTable[name].Level = level;
                                }
                            }
                            break;
                        case 0xB011:
                            {
                                name = "";
                                i = 0;
                                byte b1;
                                do
                                {
                                    b1 = br.ReadByte();
                                    if (b1 > 0)
                                    {
                                        name += (char)b1;
                                    }

                                    i++;
                                } while (b1 != '\0');
                                objNames.Add( "$$$" + name);
                            }
                            break;
                        case 0xB013:
                            //pivot point
                            float[] points = new float[3];
                            for (i = 0; i < 3; i++)
                            {
                                points[i] = br.ReadSingle();
                            }

                            if (objectTable.ContainsKey(name))
                            {
                                   objectTable[name].PivotPoint = -new Vector3(points[0], points[1], points[2]);
                            }
                            break;
                        case 0xB020:
                            {
                                float[] pos = new float[8];
                                for (i = 0; i < 8; i++)
                                {
                                    pos[i] = br.ReadSingle();
                                }

                            }
                            break;

                        // If we don't recognize a section then jump over it. Subract the header from the section length
                        default:
                            br.BaseStream.Seek(sectionLength - 6, SeekOrigin.Current);
                            break;
                    }
                    lastID = sectionID;
                }
                br.Close();
                if (currentMaterialIndex > -1)
                {
                    addMaterial(currentMaterial);
                }
            }

            ////debug

            //for ( i = 0; i < 99; i++)
            //{
            //    System.Diagnostics.Debug.WriteLine(objNames[i]);
            //}

            //foreach (ObjectNode node in objects)
            //{
            //    System.Diagnostics.Debug.WriteLine(node.Name);
            //}

            ////debug

            // Generate vertex normals

            // Vertex normals are computed by averaging the normals of all faces
            // with an angle between them less than the crease angle. By setting
            // the crease angle to 0 degrees, the model will have a faceted appearance.
            // Right now, the smooth flag selects between one of two crease angles,
            // but some smoothing is always applied.
            float creaseAngleRad = MathUtil.DegreesToRadians(Smooth ? 70.0f : 45.0f);

            Vector3[] vertexNormals = CalculateVertexNormalsMerged(vertexList, indexList, creaseAngleRad);
            List<PositionNormalTextured> newVertexList = new List<PositionNormalTextured>();
            int newVertexCount = triangleCount * 3;

            for (int vertexIndex = 0; vertexIndex < newVertexCount; ++vertexIndex)
            {
                PositionNormalTextured v = vertexList[indexList[vertexIndex]];
                v.Normal = vertexNormals[vertexIndex];
                newVertexList.Add(v);
            }

            // Use the triangle mesh and material assignments to create a single
            // index list for the mesh.
            List<uint> newIndexList = new List<uint>();

            foreach (ObjectNode node in objects)
            {

                List<Mesh.Group> materialGroups = new List<Mesh.Group>();
                for (i = 0; i < node.ApplyLists.Count; i++)
                {
                    int matId = node.ApplyListsIndex[i];
                    int startIndex = newIndexList.Count;
                    foreach (int triangleIndex in node.ApplyLists[i])
                    {
                        newIndexList.Add((uint)(triangleIndex * 3));
                        newIndexList.Add((uint)(triangleIndex * 3 + 1));
                        newIndexList.Add((uint)(triangleIndex * 3 + 2));
                    }

                    var group = new Mesh.Group();
                    group.startIndex = startIndex;
                    group.indexCount = node.ApplyLists[i].Length * 3;
                    group.materialIndex = matId;
                    materialGroups.Add(group);
                }
                node.DrawGroup = materialGroups;
            }

            // Turn objects into tree
            Stack<ObjectNode> nodeStack = new Stack<ObjectNode>();

            List<ObjectNode> nodeTreeRoot = new List<ObjectNode>();

            ObjectNode rootDummy = new ObjectNode();
            rootDummy.Name = "Root";
            rootDummy.Parent = null;
            rootDummy.Level = -1;
            rootDummy.DrawGroup = null;

            int currentLevel = -1;

            nodeStack.Push(rootDummy);
            nodeTreeRoot.Add(rootDummy);

            for (i = 0; i < objHierarchy.Count; i++)
            {
                int level = objHierarchy[i];

                if (level <= currentLevel)
                {
                    // pop out all the nodes to intended parent
                    while (level <= nodeStack.Peek().Level && nodeStack.Count > 1)
                    {
                        nodeStack.Pop();
                    }
                    currentLevel = level;

                }

                if (objNames[i].StartsWith("$$$"))
                {
                    ObjectNode dummy = new ObjectNode();
                    dummy.Name = objNames[i].Replace("$$$", "");
                    dummy.Parent = nodeStack.Peek();
                    dummy.Parent.Children.Add(dummy);
                    dummy.Level = currentLevel = level;
                    dummy.DrawGroup = null;
                    nodeStack.Push(dummy);
                }
                else
                {
                    objectTable[objNames[i]].Level = currentLevel = level;
                    objectTable[objNames[i]].Parent = nodeStack.Peek();
                    objectTable[objNames[i]].Parent.Children.Add(objectTable[objNames[i]]);
                    nodeStack.Push(objectTable[objNames[i]]);
                }
            }

            if (objHierarchy.Count == 0)
            {
                foreach (ObjectNode node in objects)
                {
                    rootDummy.Children.Add(node);
                    node.Parent = rootDummy;
                }
            }

            if (normalMapFound)
            {
                // If we've got a normal map, we want to generate tangent vectors for the mesh

                // Mapping of vertices to geometry is extremely straightforward now, but this could
                // change when a mesh optimization step is introduced.
                var tangentIndexList = new List<uint>();
                for (uint tangentIndex = 0; tangentIndex < newVertexCount; ++tangentIndex)
                {
                    tangentIndexList.Add(tangentIndex);
                }

                Vector3[] tangents = CalculateVertexTangents(newVertexList, tangentIndexList, creaseAngleRad);

                // Copy the tangents in the vertex data list
                var vertices = new PositionNormalTexturedTangent[newVertexList.Count];
                int vertexIndex = 0;
                foreach (PositionNormalTextured v in newVertexList)
                {
                    PositionNormalTexturedTangent tvertex = new PositionNormalTexturedTangent(v.Position, v.Normal, new Vector2(v.Tu, v.Tv), tangents[vertexIndex]);
                    vertices[vertexIndex] = tvertex;
                    ++vertexIndex;
                }
                mesh = new Mesh(vertices, newIndexList.ToArray());
            }
            else
            {
                mesh = new Mesh(newVertexList.ToArray(), newIndexList.ToArray());
            }

            Objects = nodeTreeRoot;
            mesh.setObjects(nodeTreeRoot);
            mesh.commitToDevice(RenderContext11.PrepDevice);

            dirty = false;

            GC.Collect();
        }
        public Mesh(PositionNormalTextured[] vertices, uint[] indices)
        {
            this.vertices = vertices;
            this.indices = indices;

            var points = new Vector3[vertices.Length];
            for (var i = 0; i < vertices.Length; ++i)
                points[i] = vertices[i].Position;
            boundingSphere = BoundingSphere.FromPoints(points);
        }
Example #9
0
        public SkyFace(string textureName, SkyFaceSide faceSide)
        {
            this.vertexBuffer = VertexBuffer.CreateGeneric <PositionNormalTextured>(
                GameEngine.Device,
                4,
                Usage.WriteOnly,
                PositionNormalTextured.Format,
                Pool.Managed,
                null);

            this.corners = this.vertexBuffer.Lock <PositionNormalTextured>(0, 0, LockFlags.None);
            PositionNormalTextured[] data = new PositionNormalTextured[4];

            switch (faceSide)
            {
            case SkyFaceSide.Top:
                //Y always 100;
                //back x -100; front X +100;
                //back Z -100; front Z +100
                data[0].X  = -100f;
                data[0].Y  = 100f;
                data[0].Z  = -100f;
                data[0].U  = 0f;
                data[0].V  = 1f;
                data[0].Nx = 0f;
                data[0].Ny = -1f;
                data[0].Nz = 0f;
                data[1].X  = 100f;
                data[1].Y  = 100f;
                data[1].Z  = -100f;
                data[1].U  = 0f;
                data[1].V  = 0f;
                data[1].Nx = 0f;
                data[1].Ny = -1f;
                data[1].Nz = 0f;
                data[2].X  = -100f;
                data[2].Y  = 100f;
                data[2].Z  = 100f;
                data[2].U  = 1f;
                data[2].V  = 1f;
                data[2].Nx = 0;
                data[2].Ny = -1f;
                data[2].Nz = 0f;
                data[3].X  = 100f;
                data[2].Y  = 100f;
                data[3].Z  = 100f;
                data[3].U  = 1f;
                data[3].V  = 0f;
                data[3].Nx = 0f;
                data[3].Ny = -1f;
                data[3].Nz = 0f;
                break;

            case SkyFaceSide.Bottom:
                data[0].X  = -100.0f;    // nw
                data[0].Y  = -100.0f;
                data[0].Z  = 100.0f;
                data[0].U  = 0.0f;
                data[0].V  = 0.0f;
                data[0].Nx = 0.0f;
                data[0].Ny = 1.0f;
                data[0].Nz = 0.0f;
                data[1].X  = 100.0f;    // ne
                data[1].Y  = -100.0f;
                data[1].Z  = 100.0f;
                data[1].U  = 1.0f;
                data[1].V  = 1.0f;
                data[1].Nx = 0.0f;
                data[1].Ny = 1.0f;
                data[1].Nz = 0.0f;
                data[2].X  = -100.0f;    // sw
                data[2].Y  = -100.0f;
                data[2].Z  = -100.0f;
                data[2].U  = 1.0f;
                data[2].V  = 0.0f;
                data[2].Nx = 0.0f;
                data[2].Ny = 1.0f;
                data[2].Nz = 0.0f;
                data[3].X  = 100.0f;    // se
                data[3].Y  = -100.0f;
                data[3].Z  = -100.0f;
                data[3].U  = 0.0f;
                data[3].V  = 1.0f;
                data[3].Nx = 0.0f;
                data[3].Ny = 1.0f;
                data[3].Nz = 0.0f;
                break;

            case SkyFaceSide.Left:
                data[0].X  = -100.0f;    // upper south
                data[0].Y  = 100.0f;
                data[0].Z  = -100.0f;
                data[0].U  = 0.0f;
                data[0].V  = 0.0f;
                data[0].Nx = 1.0f;
                data[0].Ny = 0.0f;
                data[0].Nz = 0.0f;
                data[1].X  = -100.0f;    // upper north
                data[1].Y  = 100.0f;
                data[1].Z  = 100.0f;
                data[1].U  = 1.0f;
                data[1].V  = 0.0f;
                data[1].Nx = 1.0f;
                data[1].Ny = 0.0f;
                data[1].Nz = 0.0f;
                data[2].X  = -100.0f;    // lower south
                data[2].Y  = -100.0f;
                data[2].Z  = -100.0f;
                data[2].U  = 0.0f;
                data[2].V  = 1.0f;
                data[2].Nx = 1.0f;
                data[2].Ny = 0.0f;
                data[2].Nz = 0.0f;
                data[3].X  = -100.0f;    // lower north
                data[3].Y  = -100.0f;
                data[3].Z  = 100.0f;
                data[3].U  = 1.0f;
                data[3].V  = 1.0f;
                data[3].Nx = 1.0f;
                data[3].Ny = 0.0f;
                data[3].Nz = 0.0f;
                break;

            case SkyFaceSide.Right:
                data[0].X  = 100.0f;    // upper ne
                data[0].Y  = 100.0f;
                data[0].Z  = 100.0f;
                data[0].U  = 0.0f;
                data[0].V  = 0.0f;
                data[0].Nx = -1.0f;
                data[0].Ny = 0.0f;
                data[0].Nz = 0.0f;
                data[1].X  = 100.0f;    // upper se
                data[1].Y  = 100.0f;
                data[1].Z  = -100.0f;
                data[1].U  = 1.0f;
                data[1].V  = 0.0f;
                data[1].Nx = -1.0f;
                data[1].Ny = 0.0f;
                data[1].Nz = 0.0f;
                data[2].X  = 100.0f;    // lower ne
                data[2].Y  = -100.0f;
                data[2].Z  = 100.0f;
                data[2].U  = 0.0f;
                data[2].V  = 1.0f;
                data[2].Nx = -1.0f;
                data[2].Ny = 0.0f;
                data[2].Nz = 0.0f;
                data[3].X  = 100.0f;    // lower se
                data[3].Y  = -100.0f;
                data[3].Z  = -100.0f;
                data[3].U  = 1.0f;
                data[3].V  = 1.0f;
                data[3].Nx = -1.0f;
                data[3].Ny = 0.0f;
                data[3].Nz = 0.0f;
                break;

            case SkyFaceSide.Front:
                data[0].X  = -100.0f;    // upper nw
                data[0].Y  = 100.0f;
                data[0].Z  = 100.0f;
                data[0].U  = 0.0f;
                data[0].V  = 0.0f;
                data[0].Nx = 0.0f;
                data[0].Ny = 0.0f;
                data[0].Nz = -1.0f;
                data[1].X  = 100.0f;    // upper ne
                data[1].Y  = 100.0f;
                data[1].Z  = 100.0f;
                data[1].U  = 1.0f;
                data[1].V  = 0.0f;
                data[1].Nx = 0.0f;
                data[1].Ny = 0.0f;
                data[1].Nz = -1.0f;
                data[2].X  = -100.0f;    // lower nw
                data[2].Y  = -100.0f;
                data[2].Z  = 100.0f;
                data[2].U  = 0.0f;
                data[2].V  = 1.0f;
                data[2].Nx = 0.0f;
                data[2].Ny = 0.0f;
                data[2].Nz = -1.0f;
                data[3].X  = 100.0f;    // lower ne
                data[3].Y  = -100.0f;
                data[3].Z  = 100.0f;
                data[3].U  = 1.0f;
                data[3].V  = 1.0f;
                data[3].Nx = 0.0f;
                data[3].Ny = 0.0f;
                data[3].Nz = -1.0f;
                break;

            case SkyFaceSide.Back:
                data[0].X  = 100.0f;    // upper se
                data[0].Y  = 100.0f;
                data[0].Z  = -100.0f;
                data[0].U  = 0.0f;
                data[0].V  = 0.0f;
                data[0].Nx = 0.0f;
                data[0].Ny = 0.0f;
                data[0].Nz = -1.0f;
                data[1].X  = -100.0f;    // upper sw
                data[1].Y  = 100.0f;
                data[1].Z  = -100.0f;
                data[1].U  = 1.0f;
                data[1].V  = 0.0f;
                data[1].Nx = 0.0f;
                data[1].Ny = 0.0f;
                data[1].Nz = -1.0f;
                data[2].X  = 100.0f;    // lower se
                data[2].Y  = -100.0f;
                data[2].Z  = -100.0f;
                data[2].U  = 0.0f;
                data[2].V  = 1.0f;
                data[2].Nx = 0.0f;
                data[2].Ny = 0.0f;
                data[2].Nz = -1.0f;
                data[3].X  = -100.0f;    // lower sw
                data[3].Y  = -100.0f;
                data[3].Z  = -100.0f;
                data[3].U  = 1.0f;
                data[3].V  = 1.0f;
                data[3].Nx = 0.0f;
                data[3].Ny = 0.0f;
                data[3].Nz = -1.0f;
                break;
            }

            this.corners.Write(data);
            this.vertexBuffer.Unlock();
            this.texture = new Texture(GameEngine.Device, textureName);
            this.valid   = true;
        }