Esempio n. 1
0
        /// <summary>
        /// Populates DomNode with data from stream data</summary>
        /// <param name="stream">Stream to read data into</param>
        /// <param name="node">Node to populate</param>
        /// <param name="resolvedUri">URI representing object file</param>
        public static void PopulateDomNode(Stream stream, ref DomNode node, Uri resolvedUri)
        {
            // Parse .obj file
            var obj = new ObjFile();
            obj.Read(stream, resolvedUri);

            if (node == null)
                node = new DomNode(Schema.nodeType.Type);

            // Populate mesh
            var mesh = new DomNode(Schema.meshType.Type);
            mesh.SetAttribute(Schema.meshType.nameAttribute, Path.GetFileName(resolvedUri.LocalPath));

            var vertexArray = new DomNode(Schema.meshType_vertexArray.Type);

            // Populate primitive data
            foreach (Group group in obj.m_groups.Values)
                foreach (FaceSet face in group.FaceSets.Values)
                {
                    var primitive = new DomNode(Schema.vertexArray_primitives.Type);
                    primitive.SetAttribute(Schema.vertexArray_primitives.indicesAttribute, face.Indices.ToArray());
                    primitive.SetAttribute(Schema.vertexArray_primitives.sizesAttribute, face.Sizes.ToArray());
                    primitive.SetAttribute(Schema.vertexArray_primitives.typeAttribute, "POLYGONS");

                    // Populate shader
                    MaterialDef material;
                    obj.m_mtl.Materials.TryGetValue(face.MaterialName, out material);

                    if (material != null)
                    {
                        string texture = null;
                        if (material.TextureName != null)
                            texture = new Uri(resolvedUri, material.TextureName).AbsolutePath;

                        var shader = new DomNode(Schema.shaderType.Type);
                        shader.SetAttribute(Schema.shaderType.nameAttribute, material.Name);
                        shader.SetAttribute(Schema.shaderType.ambientAttribute, material.Ambient);
                        shader.SetAttribute(Schema.shaderType.diffuseAttribute, material.Diffuse);
                        shader.SetAttribute(Schema.shaderType.shininessAttribute, material.Shininess);
                        shader.SetAttribute(Schema.shaderType.specularAttribute, material.Specular);
                        shader.SetAttribute(Schema.shaderType.textureAttribute, texture);

                        primitive.SetChild(Schema.vertexArray_primitives.shaderChild, shader);
                    }

                    // Note: Bindings must be in the order: normal, map1, position
                    DomNode binding;
                    if (face.HasNormals)
                    {
                        binding = new DomNode(Schema.primitives_binding.Type);
                        binding.SetAttribute(Schema.primitives_binding.sourceAttribute, "normal");
                        primitive.GetChildList(Schema.vertexArray_primitives.bindingChild).Add(binding);
                    }

                    if (face.HasTexCoords)
                    {
                        binding = new DomNode(Schema.primitives_binding.Type);
                        binding.SetAttribute(Schema.primitives_binding.sourceAttribute, "map1");
                        primitive.GetChildList(Schema.vertexArray_primitives.bindingChild).Add(binding);
                    }

                    binding = new DomNode(Schema.primitives_binding.Type);
                    binding.SetAttribute(Schema.primitives_binding.sourceAttribute, "position");
                    primitive.GetChildList(Schema.vertexArray_primitives.bindingChild).Add(binding);

                    vertexArray.GetChildList(Schema.meshType_vertexArray.primitivesChild).Add(primitive);
                }

            // Populate array data
            DomNode array;
            if (obj.m_normals.Count > 0)
            {
                array = new DomNode(Schema.vertexArray_array.Type);
                array.SetAttribute(Schema.vertexArray_array.Attribute, obj.m_normals.ToArray());
                array.SetAttribute(Schema.vertexArray_array.countAttribute, obj.m_normals.Count / 3);
                array.SetAttribute(Schema.vertexArray_array.nameAttribute, "normal");
                array.SetAttribute(Schema.vertexArray_array.strideAttribute, 3);

                vertexArray.GetChildList(Schema.meshType_vertexArray.arrayChild).Add(array);
            }

            if (obj.m_texcoords.Count > 0)
            {
                array = new DomNode(Schema.vertexArray_array.Type);
                array.SetAttribute(Schema.vertexArray_array.Attribute, obj.m_texcoords.ToArray());
                array.SetAttribute(Schema.vertexArray_array.countAttribute, obj.m_texcoords.Count / 2);
                array.SetAttribute(Schema.vertexArray_array.nameAttribute, "map1");
                array.SetAttribute(Schema.vertexArray_array.strideAttribute, 2);

                vertexArray.GetChildList(Schema.meshType_vertexArray.arrayChild).Add(array);
            }

            array = new DomNode(Schema.vertexArray_array.Type);
            array.SetAttribute(Schema.vertexArray_array.Attribute, obj.m_positions.ToArray());
            array.SetAttribute(Schema.vertexArray_array.countAttribute, obj.m_positions.Count / 3);
            array.SetAttribute(Schema.vertexArray_array.nameAttribute, "position");
            array.SetAttribute(Schema.vertexArray_array.strideAttribute, 3);

            vertexArray.GetChildList(Schema.meshType_vertexArray.arrayChild).Add(array);

            // Set mesh elements
            mesh.SetChild(Schema.meshType.vertexArrayChild, vertexArray);
            node.SetChild(Schema.nodeType.meshChild, mesh);
        }