Exemplo n.º 1
0
        private void loadFile(string filename)
        {
            loadedFile = new BlenderFile(filename);
            fileTree.Nodes.Clear();
            fileTree.ShowRootLines = true;
            List <TreeNode> nodes = new List <TreeNode>();

            foreach (Structure[] structure in loadedFile.Structures)
            {
                nodes.Add(loadNode(structure));
            }
            TreeNode rawBlocks = new TreeNode("[Raw data blocks]");

            foreach (string s in loadedFile.RawBlockMessages)
            {
                rawBlocks.Nodes.Add(new TreeNode("[" + s.Split(' ')[0] + "]: " + s.Split(' ')[1])
                {
                    Tag = s
                });
            }
            nodes.Add(rawBlocks);
            unfilteredNodeList = nodes.ToArray();
            // the nodes will get added to the TreeView when filterBox_LostFocus() is called
            List <string> temp = new List <string>();

            foreach (TreeNode node in unfilteredNodeList)
            {
                Structure s = node.Tag as Structure;
                if (s != null)
                {
                    string typename = s.TypeName;
                    if (!temp.Contains(typename))
                    {
                        temp.Add(typename);
                    }
                }
                else if (node.Text.StartsWith("[List of"))
                {
                    foreach (TreeNode child in node.Nodes)
                    {
                        if ((s = child.Tag as Structure) != null)
                        {
                            string typename = s.TypeName;
                            if (!temp.Contains(typename))
                            {
                                temp.Add(typename);
                            }
                        }
                    }
                }
            }
            rootNodeTypeNames = temp.ToArray();
            filterBox.AutoCompleteCustomSource = new AutoCompleteStringCollection();
            filterBox.AutoCompleteCustomSource.AddRange(rootNodeTypeNames);
            filterBox.Enabled = true;
            filterBox_LostFocus(this, null);
        }
Exemplo n.º 2
0
    /*! This methode is called from LoadFile() and executes the actual loading
     * Runs in own thread
     */
    private void LoadFileWorker(object sender, DoWorkEventArgs e)
    {
        BlenderFile        b             = new BlenderFile(Path);
        List <BlenderMesh> blenderMeshes = new List <BlenderMesh>();

        blenderObjects = b.readObject();
        blenderMeshes  = b.readMesh();
        unityMeshes    = BlenderFile.createSubmeshesForUnity(blenderMeshes);
        return;
    }
Exemplo n.º 3
0
        /// <summary>
        /// Creates a new <pre>Material</pre> with the given arguments, unless the <pre>Material</pre> was created already.
        /// If the <pre>Material</pre> was already created, returns a reference to the previously created <pre>Material</pre>.
        /// </summary>
        internal static Material GetOrCreateMaterial(BlenderFile file, PopulatedStructure material)
        {
            if (materialDict.Keys.Contains(material.ContainingBlock.OldMemoryAddress))
            {
                return(materialDict[material.ContainingBlock.OldMemoryAddress]);
            }

            Material m = new Material(file, material);

            materialDict.Add(material.ContainingBlock.OldMemoryAddress, m);
            return(m);
        }
Exemplo n.º 4
0
        static void Main(string[] args)
        {
            // gets path from args or user
            string path = getPath(args);

            Console.WriteLine("Processing...");

            BlenderFile reader = new BlenderFile(path);

            // write html file
            writeFile(path, reader);

            // "press any key to continue"
            Console.ReadLine();
        }
Exemplo n.º 5
0
        private void loadModelData(BlenderFile file)
        {
            models            = new List <BlenderModel>();
            transparentModels = new List <BlenderModel>();
            currentLayer      = 1;

            Structure curscene = file.GetStructuresOfType("FileGlobal")[0]["curscene"].Dereference()[0];
            ulong     next     = curscene["base.first"].Value;

            while (next != 0)
            {
                Structure objBase   = file.GetStructuresByAddress(next)[0];
                Structure obj       = objBase["object"].Dereference()[0];
                IField    data      = obj["data"];
                int       SDNAIndex = file.GetBlockByAddress((data as Field <ulong>).Value).SDNAIndex;
                while (file.StructureDNA.StructureList[SDNAIndex].StructureTypeName != "Mesh")
                {
                    ulong nextPointer = (objBase["next"] as Field <ulong>).Value;
                    if (nextPointer == 0)
                    {
                        return; // we've run out of objects in the list, and haven't found any meshes
                    }
                    objBase   = file.GetStructuresByAddress(nextPointer)[0];
                    obj       = objBase["object"].Dereference()[0];
                    data      = obj["data"];
                    SDNAIndex = file.GetBlockByAddress((data as Field <ulong>).Value).SDNAIndex;
                }

                Structure    mesh  = data.Dereference()[0];
                BlenderModel model = new BlenderModel(mesh, obj, GraphicsDevice, file);
                if (model.TextureHasTransparency)
                {
                    transparentModels.Add(model);
                }
                else
                {
                    models.Add(model);
                }

                next = (objBase["next"] as Field <ulong>).Value;
            }
        }
Exemplo n.º 6
0
        internal Scene(BlenderFile file, PopulatedStructure scene)
        {
            Name = new string(scene["id.name"].GetValueAsCharArray()).Split('\0')[0].Substring(2);

            // todo: add lamp importing here
            string[]             validTypeNames = new[] { "Mesh" };
            List <BlenderObject> objects        = new List <BlenderObject>();
            int i = 0;

            ulong next   = scene["base.first"].GetValueAsPointer();
            ulong basact = scene["basact"].GetValueAsPointer(); // this is the address of the Base object

            while (next != 0)
            {
                if (next == basact)
                {
                    activeObjectIndex = i;
                }

                PopulatedStructure objBase = file.GetStructuresByAddress(next)[0];
                PopulatedStructure obj     = file.GetStructuresByAddress(objBase["object"].GetValueAsPointer())[0];
                Field data = obj["data"];
                ulong ptr  = data.GetValueAsPointer(); // this will be 0 for objects of the Empty type
                if (ptr == 0)
                {
                    objects.Add(new BlenderObject(file, obj));
                }
                else
                {
                    int SDNAIndex = file.GetBlockByAddress(ptr).SDNAIndex;
                    if (validTypeNames.Contains(file.StructureDNA.StructureList[SDNAIndex].StructureTypeName))
                    {
                        objects.Add(new BlenderObject(file, obj));
                    }
                }

                next = objBase["next"].GetValueAsPointer();
                i++;
            }
        }
Exemplo n.º 7
0
        internal BlendFile(BlenderFile file)
        {
            Version = file.VersionNumber;

            PopulatedStructure fileGlobal = file.GetStructuresOfType("FileGlobal")[0];

            Filename = new string(fileGlobal["filename"].GetValueAsCharArray()).Split('\0')[0];
            Revision = fileGlobal["revision"].GetValueAsInt();

            ulong curSceneAddr = fileGlobal["curscene"].GetValueAsPointer();

            PopulatedStructure[] scenes = file.GetStructuresOfType("Scene");
            int i = 0;

            Scenes = new Scene[scenes.Length];
            foreach (PopulatedStructure scene in scenes)
            {
                if (scene.ContainingBlock.OldMemoryAddress == curSceneAddr)
                {
                    currentSceneIndex = i;
                }
                Scenes[i++] = new Scene(file, scene);
            }
        }
Exemplo n.º 8
0
        internal Mesh(PopulatedStructure mesh, BlenderFile file)
        {
            FileBlock materialArray;

            int pointerSize = mesh["mat"].Size;

            Name = new string(mesh["id.name"].GetValueAsCharArray()).Split('\0')[0].Substring(2);
            ulong mat = mesh["mat"].GetValueAsPointer();

            if (mat == 0 || (materialArray = file.GetBlockByAddress(mat)).Size % pointerSize != 0)
            {
                Materials = new Material[0];
            }
            else
            {
                int count = materialArray.Size % pointerSize;
                Materials = new Material[count];
                for (int i = 0; i < count; i++)
                {
                    Materials[i] = Material.GetOrCreateMaterial(
                        file,
                        file.GetStructuresByAddress(
                            pointerSize == 4 ? BitConverter.ToUInt32(materialArray.Data, count * pointerSize) :
                            BitConverter.ToUInt64(materialArray.Data, count * pointerSize)
                            )[0]
                        );
                }
            }
            float[] vectorTemp = mesh["loc"].GetValueAsFloatArray();
            Location   = new Vector3(vectorTemp[0], vectorTemp[1], vectorTemp[2]);
            vectorTemp = mesh["rot"].GetValueAsFloatArray();
            Rotation   = new Vector3(vectorTemp[0], vectorTemp[1], vectorTemp[2]);
            vectorTemp = mesh["size"].GetValueAsFloatArray();
            Size       = new Vector3(vectorTemp[0], vectorTemp[1], vectorTemp[2]);

            MeshBuilder primordialMesh = MeshBuilder.StartMesh(Name);

            // both structures use the same vertex structure
            List <Vector3> verts = new List <Vector3>();
            List <short[]> unconvertedNormals = new List <short[]>();

            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mvert"].GetValueAsPointer()))
            {
                float[] vector = s["co"].GetValueAsFloatArray();
                unconvertedNormals.Add(s["no"].GetValueAsShortArray());
                verts.Add(new Vector3(vector[0], vector[1], vector[2]));
            }
            List <Vector3> normals = convertNormals(unconvertedNormals);

            VertexPositionNormalTexture[] vertices;
            BasicMaterialContent          bmc;

            // todo: not yet sure which format versions of Blender between 2.62 and 2.65 use.
            if (float.Parse(file.VersionNumber) >= 2.66f) // uses edges, loops, and polys (Blender 2.66+)
            {
                vertices = loadNewModel(file, mesh, verts, normals, out bmc);
            }
            else // uses MFace (Blender 2.49-2.61)
            {
                vertices = loadOldModel(file, mesh, verts, normals, out bmc);
            }

            MeshBuilder mb = MeshBuilder.StartMesh(Name);

            foreach (VertexPositionNormalTexture v in vertices)
            {
                mb.CreatePosition(v.Position);
            }
            int uvChannel     = mb.CreateVertexChannel <Vector2>(VertexChannelNames.TextureCoordinate(0));
            int normalChannel = mb.CreateVertexChannel <Vector3>(VertexChannelNames.Normal());
            int j             = 0;

            foreach (VertexPositionNormalTexture v in vertices)
            {
                mb.SetVertexChannelData(uvChannel, v.TextureCoordinate);
                mb.SetVertexChannelData(normalChannel, v.Normal);

                mb.AddTriangleVertex(j++);
            }
        }
Exemplo n.º 9
0
        private VertexPositionNormalTexture[] loadNewModel(BlenderFile file, PopulatedStructure mesh, List <Vector3> verts, List <Vector3> normals, out BasicMaterialContent bmc)
        {
            List <VertexPositionNormalTexture> output = new List <VertexPositionNormalTexture>();

            List <Vector2> edges = new List <Vector2>(); // using x as index1 and y as index2

            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["medge"].GetValueAsPointer()))
            {
                edges.Add(new Vector2(s["v1"].GetValueAsInt(), s["v2"].GetValueAsInt()));
            }
            // a "loop" is a vertex index and an edge index. Groups of these are used to define a "poly", which is a face.
            List <Vector2> loops = new List <Vector2>(); // using x as "v" and y as "e"

            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mloop"].GetValueAsPointer()))
            {
                loops.Add(new Vector2(s["v"].GetValueAsInt(), s["e"].GetValueAsInt()));
            }
            List <Vector2> uvLoops = null;                                                                              // using x as u and y as v

            Vector2[] backupUVs = new[] { new Vector2(0, 0), new Vector2(0, 1), new Vector2(1, 1), new Vector2(1, 0) }; // in case uvLoops is null
            if (mesh["mloopuv"].GetValueAsPointer() != 0)
            {
                uvLoops = new List <Vector2>();
                foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mloopuv"].GetValueAsPointer()))
                {
                    float[] uv = s["uv"].GetValueAsFloatArray();
                    uvLoops.Add(new Vector2(uv[0], uv[1]));
                }
            }
            List <Vector2> polys = new List <Vector2>(); // using x as "loopstart" and y as "totloop" (loop length)

            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mpoly"].GetValueAsPointer()))
            {
                polys.Add(new Vector2(s["loopstart"].GetValueAsInt(), s["totloop"].GetValueAsInt()));
            }
            // assume all faces use same texture for now
            //if(mesh["mtpoly"].GetValueAsPointer() != 0)
            //{
            //    try
            //    {
            //        // todo: sometimes this line fails, probably due to "assume all faces use same texture"
            //        PopulatedStructure image = file.GetStructuresByAddress(file.GetStructuresByAddress(mesh["mtpoly"].GetValueAsPointer())[0]["tpage"].GetValueAsPointer())[0];
            //        if(image["packedfile"].GetValueAsPointer() != 0)
            //        {
            //            byte[] rawImage = file.GetBlockByAddress(file.GetStructuresByAddress(image["packedfile"].GetValueAsPointer())[0]["data"].GetValueAsPointer()).Data;
            //            using(Stream s = new MemoryStream(rawImage))
            //                texture = Texture2D.FromStream(GraphicsDevice, s);
            //        }
            //        else
            //        {
            //            string texturePath = image["name"].ToString().Split('\0')[0].Replace("/", "\\").Replace("\\\\", "\\");
            //            string filePath = file.GetStructuresOfType("FileGlobal")[0]["filename"].ToString();
            //            filePath = filePath.Substring(0, filePath.LastIndexOf('\\'));
            //            using(Stream s = File.Open((filePath + texturePath).Replace("\'", ""), FileMode.Open, FileAccess.Read))
            //                texture = Texture2D.FromStream(GraphicsDevice, s);
            //        }
            //    }
            //    catch
            //    {
            //        texture = defaultTex;
            //    }
            //}
            //else
            //{
            //    texture = new Texture2D(GraphicsDevice, 1, 1);
            //    texture.SetData(new Color[] { Color.Gray });
            //}
            // loops of length 3 are triangles and can be directly added to the vertex list. loops of length 4
            // are quads, and have to be split into two triangles.
            foreach (Vector2 poly in polys)
            {
                Vector2[] faceEdges  = new Vector2[(int)poly.Y];
                Vector2[] faceUVs    = new Vector2[faceEdges.Length];
                int       j          = 0;
                int       loopOffset = (int)poly.X;
                for (int i = loopOffset; i < (int)poly.Y + loopOffset; i++)
                {
                    faceEdges[j] = edges[(int)loops[i].Y];
                    faceUVs[j]   = uvLoops == null ? backupUVs[i - loopOffset] : uvLoops[i];
                    j++;
                }
                Vector3[] faceVerts       = new Vector3[faceEdges.Length];
                Vector3[] faceVertNormals = new Vector3[faceEdges.Length];
                for (int i = 0; i < faceEdges.Length; i++)
                {
                    int index = (int)(loops[loopOffset + i].X == faceEdges[i].X ? faceEdges[i].Y : faceEdges[i].X);
                    faceVerts[i]       = verts[index];
                    faceVertNormals[i] = normals[index];
                }
                if (faceVerts.Length == 3) // already a triangle
                {
                    // push 0 to the end
                    Vector2 temp = faceUVs[0];
                    faceUVs[0] = faceUVs[1];
                    faceUVs[1] = temp;
                    temp       = faceUVs[1];
                    faceUVs[1] = faceUVs[2];
                    faceUVs[2] = temp;

                    for (int i = 2; i >= 0; i--) // 2, 1, 0
                    {
                        output.Add(new VertexPositionNormalTexture(faceVerts[i], faceVertNormals[i], faceUVs[i]));
                    }
                }
                else if (faceVerts.Length == 4) // quad, split into tris
                {
                    // swap 3 with 1 and 2 with 3
                    Vector2 temp = faceUVs[1];
                    faceUVs[1] = faceUVs[3];
                    faceUVs[3] = temp;
                    temp       = faceUVs[2];
                    faceUVs[2] = faceUVs[3];
                    faceUVs[3] = temp;

                    // 2, 1, 0
                    for (int i = 2; i >= 0; i--)
                    {
                        output.Add(new VertexPositionNormalTexture(faceVerts[i], faceVertNormals[i], faceUVs[i]));
                    }

                    // 3, 2, 0
                    for (int i = 3; i >= 1; i--)
                    {
                        output.Add(new VertexPositionNormalTexture(faceVerts[i == 1 ? 0 : i], faceVertNormals[i == 1 ? 0 : i], faceUVs[i == 1 ? 0 : i]));
                    }
                }
            }
            bmc = new BasicMaterialContent();
            return(output.ToArray());
        }
Exemplo n.º 10
0
        private VertexPositionNormalTexture[] loadOldModel(BlenderFile file, PopulatedStructure mesh, List <Vector3> verts, List <Vector3> normals, out BasicMaterialContent bmc)
        {
            // I believe this function has a bug when used on a mesh that has unconnected chunks of vertices;
            // however the only file I currently have that exhibits this problem decompresses to 240MB when I use the HTML
            // renderer tool, so I can't feasibly poke through the data to see what's going wrong.

            List <VertexPositionNormalTexture> output = new List <VertexPositionNormalTexture>();

            bmc = new BasicMaterialContent();

            List <int[]>     faces  = new List <int[]>();
            List <float[, ]> tFaces = new List <float[, ]>();

            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mface"].GetValueAsPointer()))
            {
                faces.Add(new[] { s["v1"].GetValueAsInt(), s["v2"].GetValueAsInt(), s["v3"].GetValueAsInt(), s["v4"].GetValueAsInt() });
            }
            foreach (PopulatedStructure s in file.GetStructuresByAddress(mesh["mtface"].GetValueAsPointer()))
            {
                tFaces.Add((float[, ])s["uv"].GetValueAsMultidimensionalArray());
            }

            // assume all faces use same texture
            PopulatedStructure image = file.GetStructuresByAddress(file.GetStructuresByAddress(mesh["mtface"].GetValueAsPointer())[0]["tpage"].GetValueAsPointer())[0];

            if (image["packedfile"].GetValueAsPointer() != 0)
            {
                byte[] rawImage = file.GetBlockByAddress(file.GetStructuresByAddress(image["packedfile"].GetValueAsPointer())[0]["data"].GetValueAsPointer()).Data;
                string filename = Name + "_" + new string(image["id.name"].GetValueAsCharArray()).Split('\0')[0].Substring(2);
                using (BinaryWriter s = new BinaryWriter(File.Open(filename, FileMode.Create)))
                    s.Write(rawImage);
                bmc.Texture = new ExternalReference <TextureContent>(filename);
            }
            else
            {
                try
                {
                    string texturePath = image["name"].ToString().Split('\0')[0].Replace("/", "\\").Replace("\\\\", "\\");
                    string filePath    = file.GetStructuresOfType("FileGlobal")[0]["filename"].ToString();
                    filePath = filePath.Substring(0, filePath.LastIndexOf('\\'));
                    File.Copy((filePath + texturePath).Replace("\'", ""), Name + "_" + new string(image["id.name"].GetValueAsCharArray()).Split('\0')[0].Substring(2));
                }
                catch
                {
                    //texture = defaultTex;
                }
            }

            int j = 0;

            foreach (int[] face in faces)
            {
                Vector3[] faceVerts       = new Vector3[face.Length];
                Vector3[] faceVertNormals = new Vector3[face.Length];
                Vector2[] faceUVs         = new Vector2[face.Length];
                for (int i = 0; i < face.Length; i++)
                {
                    faceVerts[i]       = verts[face[i]];
                    faceVertNormals[i] = normals[face[i]];
                    faceUVs[i]         = new Vector2(tFaces[j][i, 0], tFaces[j][i, 1]);
                }
                j++;

                // 2, 1, 0
                for (int i = 2; i >= 0; i--)
                {
                    output.Add(new VertexPositionNormalTexture(faceVerts[i], faceVertNormals[i], faceUVs[i]));
                }

                // 3, 2, 0
                for (int i = 3; i >= 1; i--)
                {
                    output.Add(new VertexPositionNormalTexture(faceVerts[i == 1 ? 0 : i], faceVertNormals[i == 1 ? 0 : i], faceUVs[i == 1 ? 0 : i]));
                }
            }

            return(output.ToArray());
        }
Exemplo n.º 11
0
        // There's a good number of additional fields relating to game properties; as well as logic bricks.
        // Might be interesting to someone, but not especially interesting to me.

        internal BlenderObject(BlenderFile file, PopulatedStructure obj)
        {
        }
Exemplo n.º 12
0
 /// <summary>
 /// Creates a new HtmlWriter.
 /// </summary>
 /// <param name="path">Output path.</param>
 /// <param name="friendlyFileName">Input file's friendly name ("cow.blend").</param>
 public HtmlWriter(BlenderFile parsedFile, string path, string friendlyFileName)
 {
     this.path       = path;
     friendly        = friendlyFileName;
     this.parsedFile = parsedFile;
 }
Exemplo n.º 13
0
        private static void writeFile(string path, BlenderFile reader)
        {
            new HtmlWriter(reader, path.Substring(path.LastIndexOf('\\') + 1, path.LastIndexOf('.') - path.LastIndexOf('\\') - 1) + ".html", path.Substring(path.LastIndexOf('\\') + 1, path.LastIndexOf('.') - path.LastIndexOf('\\') - 1) + ".html").WriteBlendFileToHtml();

            Console.WriteLine("Processing complete. Output in " + path.Substring(path.LastIndexOf('\\') + 1, path.LastIndexOf('.') - path.LastIndexOf('\\') - 1) + ".html.");
        }
Exemplo n.º 14
0
        public BlenderModel(Structure mesh, Structure obj, GraphicsDevice GraphicsDevice, BlenderFile file)
        {
            // If I was less sloppy, I would have used casts to generics instead of the raw dynamic Value on IField,
            // but I'm lazy and this code is soon to go away anyway.
            if(defaultTex == null)
            {
                defaultTex = new Texture2D(GraphicsDevice, 1, 1);
                defaultTex.SetData(new Color[] { Color.Gray });
            }

            this.GraphicsDevice = GraphicsDevice;

            // both structures use the same vertex structure
            List<Vector3> verts = new List<Vector3>();
            List<short[]> unconvertedNormals = new List<short[]>();
            foreach(Structure s in mesh["mvert"].Dereference())
            {
                float[] vector = s["co"].Value;
                unconvertedNormals.Add(s["no"].Value);
                verts.Add(new Vector3(vector[0], vector[1], vector[2]));
            }

            List<Vector3> normals = convertNormals(unconvertedNormals);
            VertexPositionNormalTexture[] vertices;
            Texture2D texture;
            // todo: not yet sure which format versions of Blender between 2.62 and 2.65 use.
            if(float.Parse(file.VersionNumber) >= 2.66f) // uses edges, loops, and polys (Blender 2.66+)
                vertices = loadNewModel(file, mesh, verts, normals, out texture);
            else // uses MFace (Blender 2.49-2.61)
                vertices = loadOldModel(file, mesh, verts, normals, out texture);

            VertexPositionColor[] normalVerts = new VertexPositionColor[normals.Count * 2];
            for(int i = 0; i < verts.Count * 2; i += 2)
            {
                normalVerts[i] = new VertexPositionColor(verts[i / 2], Color.MidnightBlue);
                normalVerts[i + 1] = new VertexPositionColor(verts[i / 2] + normals[i / 2] * 0.25f, Color.MidnightBlue);
            }

            float[] posVector = obj["loc"].Value;
            this.Position = new Vector3(posVector[0], posVector[1], posVector[2]);
            float[] scaleVector = obj["size"].Value;
            this.Scale = new Vector3(scaleVector[0], scaleVector[1], scaleVector[2]);
            float[] rotVector = obj["rot"].Value;
            this.Rotation = Quaternion.CreateFromYawPitchRoll(rotVector[1], rotVector[0], rotVector[2]);
            this.Vertices = vertices;
            this.NormalVerts = normalVerts;
            this.VertexBuffer = new VertexBuffer(GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, this.Vertices.Length, BufferUsage.None);
            this.NormalBuffer = new VertexBuffer(GraphicsDevice, VertexPositionColor.VertexDeclaration, this.NormalVerts.Length, BufferUsage.None);
            this.Texture = texture;
            this.Name = new string(obj["id.name"].Value).Split('\0')[0].Substring(2); // remove null term, remove first two characters

            // LSB on represents layer 1, next bit is layer 2, etc
            this.Layer = obj["lay"].Value;

            // the "mat" field is a pointer to a pointer (technically, a pointer to an array of pointers)
            // I'm not sure what to do with multiple materials, so just use the first one
            ulong blockaddr = mesh["mat"].Value;
            if(blockaddr != 0)
            {
                Structure mat = file.GetStructuresByAddress(BitConverter.ToUInt32(file.GetBlockByAddress(blockaddr).Data, 0))[0];
                this.TextureHasTransparency = mat["game.alpha_blend"].Value != 0;

                int mode = mat["mode"].Value;
                this.LightingEnabled = (mode & 4) == 0; // as far as I can tell, this is where "shadeless" is stored.
            }
            else
                this.LightingEnabled = true;
        }
Exemplo n.º 15
0
        private VertexPositionNormalTexture[] loadOldModel(BlenderFile file, Structure mesh, List<Vector3> verts, List<Vector3> normals, out Texture2D texture)
        {
            // I believe this function has a bug when used on a mesh that has unconnected chunks of vertices;
            // however the only file I currently have that exhibits this problem decompresses to 240MB when I use the HTML
            // renderer tool, so I can't feasibly poke through the data to see what's going wrong.

            List<VertexPositionNormalTexture> output = new List<VertexPositionNormalTexture>();

            List<int[]> faces = new List<int[]>();
            List<float[][]> tFaces = new List<float[][]>();
            foreach(Structure s in mesh["mface"].Dereference())
                faces.Add(new int[] { s["v1"].Value, s["v2"].Value, s["v3"].Value, s["v4"].Value });
            foreach(Structure s in mesh["mtface"].Dereference())
                tFaces.Add((float[][])s["uv"].Value);

            // assume all faces use same texture
            Structure image = mesh["mtface"].Dereference()[0]["tpage"].Dereference()[0];
            if(image["packedfile"].Value != 0)
            {
                byte[] rawImage = file.GetBlockByAddress(image["packedfile"].Dereference()[0]["data"].Value).Data;
                using(Stream s = new MemoryStream(rawImage))
                    texture = Texture2D.FromStream(GraphicsDevice, s);
            }
            else
            {
                try
                {
                    string texturePath = image["name"].ToString().Split('\0')[0].Replace("/", "\\").Replace("\\\\", "\\");
                    string filePath = file.GetStructuresOfType("FileGlobal")[0]["filename"].ToString();
                    filePath = filePath.Substring(0, filePath.LastIndexOf('\\'));
                    using(Stream s = File.Open((filePath + texturePath).Replace("\'", ""), FileMode.Open, FileAccess.Read))
                        texture = Texture2D.FromStream(GraphicsDevice, s);
                }
                catch
                {
                    texture = defaultTex;
                }
            }

            int j = 0;
            foreach(int[] face in faces)
            {
                Vector3[] faceVerts = new Vector3[face.Length];
                Vector3[] faceVertNormals = new Vector3[face.Length];
                Vector2[] faceUVs = new Vector2[face.Length];
                for(int i = 0; i < face.Length; i++)
                {
                    faceVerts[i] = verts[face[i]];
                    faceVertNormals[i] = normals[face[i]];
                    faceUVs[i] = new Vector2(tFaces[j][i][0], tFaces[j][i][1]);
                }
                j++;

                // 2, 1, 0
                for(int i = 2; i >= 0; i--)
                    output.Add(new VertexPositionNormalTexture(faceVerts[i], faceVertNormals[i], faceUVs[i]));

                // 3, 2, 0
                for(int i = 3; i >= 1; i--)
                    output.Add(new VertexPositionNormalTexture(faceVerts[i == 1 ? 0 : i], faceVertNormals[i == 1 ? 0 : i], faceUVs[i == 1 ? 0 : i]));
            }

            return output.ToArray();
        }
Exemplo n.º 16
0
 private Material(BlenderFile file, PopulatedStructure material)
 {
 }