Ejemplo n.º 1
0
        public bool Render(RenderMode mode, float scale, BCA animation, int frame)
        {
            bool rendered_something = false;

            for (int i = 0; i < m_ModelChunks.Length; i++)
            {
                ModelChunk mdchunk = m_ModelChunks[i];

                if (animation != null && frame > -1)
                {
                    if (mdchunk.Render(mode, scale, animation, frame))
                    {
                        rendered_something = true;
                    }
                }
                else
                {
                    if (mdchunk.Render(mode, scale))
                    {
                        rendered_something = true;
                    }
                }
            }

            return(rendered_something);
        }
Ejemplo n.º 2
0
        private void WriteObject(TextWriter w, ModelChunk model, string fileName)
        {
            w.WriteLine("mtllib {0}.mtl", Path.GetFileNameWithoutExtension(fileName));
            w.WriteLine();
            Vector3    scale;
            Quaternion rotation;
            Vector3    translation;

            Matrix4x4.Decompose(model.Matrix, out scale, out rotation, out translation);

            foreach (var vertex in model.Mesh.Vertices)
            {
                var v = Vector3.Transform(vertex, model.Matrix);  //Matrice invertita
                w.WriteLine(string.Format(CultureInfo.InvariantCulture, "v {0:0.0000} {1:0.0000} {2:0.0000}", v.X, v.Y, v.Z));
            }
            w.WriteLine();
            foreach (var vn in model.Mesh.Normals)
            {
                w.WriteLine(string.Format(CultureInfo.InvariantCulture, "vn {0:0.0000} {1:0.0000} {2:0.0000}", vn.X, vn.Y, vn.Z));
            }
            w.WriteLine();
            foreach (var vt in model.Mesh.UV)
            {
                w.WriteLine(string.Format(CultureInfo.InvariantCulture, "vt {0:0.0000} {1:0.0000} {2:0.0000}", vt.X, 0.0f - vt.Y, 0.0f));
            }
            w.WriteLine();
            w.WriteLine("g " + model.Name);
            // Face indices: S4 starts at 0 - Wavefront OBJ at 1
            foreach (var texture in model.TextureData.Textures)
            {
                var tex = texture.FileName;
                foreach (var c in Path.GetInvalidPathChars())
                {
                    tex = tex.Replace(c, '?');
                }

                foreach (var c in Path.GetInvalidFileNameChars())
                {
                    tex = tex.Replace(c, '?');
                }

                tex = tex.Replace("?", "");
                tex = tex.Replace("�", "");

                w.WriteLine("usemtl " + Path.GetFileNameWithoutExtension(tex));
                w.WriteLine();
                for (int i = texture.FaceCounter; i < (texture.FaceCount + texture.FaceCounter); i++)
                {
                    var   face = model.Mesh.Faces[i];
                    float x    = face.X + 1;
                    float y    = face.Y + 1;
                    float z    = face.Z + 1;
                    w.WriteLine(string.Format(CultureInfo.InvariantCulture, "f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", x, y, z));
                }
                w.WriteLine();
            }
        }
Ejemplo n.º 3
0
 public void DestroyModel()
 {
     if (_model == null)
     {
         return;
     }
     SharpCraft.Instance.RunGlContext(_model.Destroy);
     _model = null;
 }
Ejemplo n.º 4
0
    public Model(byte[] vox)
    {
        // MagicaVox standards: magicNumber = 4 bytes, versionNumber = 4 bytes

        // Set magic number; From byte 0 to byte 3 (4 bytes) -> cant use BitConverter since MagicNumber is big endian
        MagicNumber = "    ";
        StringBuilder builder = new StringBuilder(4);
        for (int i = 0; i < 4; i++) {
            builder[i] = Convert.ToChar(vox[i]);
        }
        MagicNumber = builder.ToString();

        // Set version number; From byte 4 to byte 7 (4 bytes)
        VersionNumber = BitConverter.ToInt32(vox, 4);

        MainChunk = new ModelChunk(vox, 8);
    }
Ejemplo n.º 5
0
        public void ChangeTexture(ModelChunk model, IList <string> textures)
        {
            var texts = model.TextureData.Textures;

            var txt = new List <TextureEntry>();

            for (int i = 0; i < texts.Count; i++)
            {
                txt.Add(new TextureEntry
                {
                    FileName    = textures[i],
                    FileName2   = texts[i].FileName2,
                    FaceCount   = texts[i].FaceCount,
                    FaceCounter = texts[i].FaceCounter
                });
            }

            model.TextureData.Textures = txt;
        }
Ejemplo n.º 6
0
        public void Export(string fileName, ModelChunk model)
        {
            try
            { using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None)) { } }
            catch { fileName = fileName.Replace(model.Name, "invalid_file_name"); }

            using (var fs = new FileStream(fileName, FileMode.Create, FileAccess.Write, FileShare.None))
                using (var w = new StreamWriter(fs))
                {
                    WriteObject(w, model, fileName);
                }
            string mtl = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".mtl");

            using (var fs = new FileStream(mtl, FileMode.Create, FileAccess.Write, FileShare.None))
                using (var w = new StreamWriter(fs))
                {
                    WriteMaterial(w, model);
                }
        }
Ejemplo n.º 7
0
        private void WriteMaterial(TextWriter w, ModelChunk model)
        {
            var ls = new List <string>();

            foreach (var texture in model.TextureData.Textures)
            {
                var tex = texture.FileName;
                foreach (var c in Path.GetInvalidPathChars())
                {
                    tex = tex.Replace(c, '?');
                }

                foreach (var c in Path.GetInvalidFileNameChars())
                {
                    tex = tex.Replace(c, '?');
                }

                tex = tex.Replace("?", "");
                tex = tex.Replace("�", "");

                string name = Path.GetFileNameWithoutExtension(tex);
                if (ls.Contains(name))
                {
                    continue;
                }
                w.WriteLine("newmtl {0}", name);
                w.WriteLine("\tNs 10.0000");
                w.WriteLine("\tNi 1.5000");
                w.WriteLine("\td 1.0000");
                w.WriteLine("\tTr 0.0000");
                w.WriteLine("\tTf 1.0000 1.0000 1.0000");
                w.WriteLine("\tillum 2");
                w.WriteLine("\tKa 0.5880 0.5880 0.5880");
                w.WriteLine("\tKd 0.5880 0.5880 0.5880");
                w.WriteLine("\tKs 0.0000 0.0000 0.0000");
                w.WriteLine("\tKe 0.0000 0.0000 0.0000");
                w.WriteLine("\tmap_Ka {0}", tex);
                w.WriteLine("\tmap_Kd {0}", tex);
                w.WriteLine();
                ls.Add(name);
            }
        }
Ejemplo n.º 8
0
    public Model(byte[] vox)
    {
        // MagicaVox standards: magicNumber = 4 bytes, versionNumber = 4 bytes

        // Set magic number; From byte 0 to byte 3 (4 bytes) -> cant use BitConverter since MagicNumber is big endian
        MagicNumber = "    ";
        StringBuilder builder = new StringBuilder(4);

        for (int i = 0; i < 4; i++)
        {
            builder[i] = Convert.ToChar(vox[i]);
        }
        MagicNumber = builder.ToString();

        // Set version number; From byte 4 to byte 7 (4 bytes)
        VersionNumber = BitConverter.ToInt32(vox, 4);



        MainChunk = new ModelChunk(vox, 8);
    }
Ejemplo n.º 9
0
        protected override void Visit(ModelChunk chunk)
        {
            // TODO: Remove this ModelChunk handling point, make the model directive more generic.

            var modelTokens = new List <RazorDirectiveToken>()
            {
                new RazorDirectiveToken
                {
                    Descriptor = new RazorDirectiveTokenDescriptor {
                        Type = RazorDirectiveTokenType.Type
                    },
                    Value = chunk.ModelType,
                }
            };
            var modelDirective = new RazorSingleLineDirective()
            {
                Name   = "model",
                Tokens = modelTokens,
            };

            _context.Builder.Add(modelDirective);
        }
Ejemplo n.º 10
0
        public void ReplaceModel(string fileName, ModelChunk model, string textureName)
        {
            var VertexList = new List <Vector3>();
            var NormalList = new List <Vector3>();
            var UVList     = new List <Vector2>();
            var FacesList  = new List <Vector3>();

            var obj = new Obj();

            obj.LoadObj(fileName);

            if (obj == null)
            {
                return;
            }

            var _matrix = new Matrix4x4();

            Matrix4x4.Invert(model.Matrix, out _matrix);

            for (int index = 0; index < obj.VertexList.Count; index++)
            {
                VertexList.Add(new Vector3(float.Parse(obj.VertexList[index].X.ToString()),
                                           float.Parse(obj.VertexList[index].Y.ToString()),
                                           float.Parse(obj.VertexList[index].Z.ToString())));
            }

            for (int index = 0; index < obj.NormalList.Count; index++)
            {
                NormalList.Add(new Vector3(float.Parse(obj.NormalList[index].X.ToString()),
                                           float.Parse(obj.NormalList[index].Y.ToString()),
                                           float.Parse(obj.NormalList[index].Z.ToString())));
            }

            for (int index = 0; index < obj.TextureList.Count; index++)
            {
                UVList.Add(new Vector2(float.Parse(obj.TextureList[index].X.ToString()), 0.0f -
                                       float.Parse(obj.TextureList[index].Y.ToString())));
            }

            var vector_temp = new List <Vector3>();

            for (int index = 0; index < VertexList.Count; index++)
            {
                var temp = Vector3.Transform(VertexList[index], _matrix);
                vector_temp.Add(temp);
            }

            for (int index = 0; index < obj.FaceList.Count; index++)
            {
                string   face       = obj.FaceList[index].ToString();
                string[] face_array = face.Split(' ');

                string X = Convert.ToString(face_array[1]);
                string Y = Convert.ToString(face_array[2]);
                string Z = Convert.ToString(face_array[3]);

                string[] _X = X.Split('/');
                string[] _Y = Y.Split('/');
                string[] _Z = Z.Split('/');

                FacesList.Add(new Vector3(Convert.ToInt32(_X[0]) - 1,
                                          Convert.ToInt32(_Y[0]) - 1,
                                          Convert.ToInt32(_Z[0]) - 1));
            }

            var texture = new TextureEntry();

            texture.FaceCount   = obj.FaceList.Count;
            texture.FaceCounter = 0;

            texture.FileName  = string.IsNullOrEmpty(textureName) ? model.TextureData.Textures[0].FileName : textureName;
            texture.FileName2 = model.TextureData.Textures[0].FileName2;

            if (model.TextureData.Textures.Count != 0)
            {
                model.TextureData.Textures[0] = texture;
            }
            else
            {
                model.TextureData.Textures.Add(texture);
            }

            model.Mesh.Vertices = vector_temp;
            model.Mesh.Normals  = NormalList;
            model.Mesh.UV       = UVList;
            model.Mesh.Faces    = FacesList;
        }
Ejemplo n.º 11
0
        public override void OnClick()
        {
            if (loaded)
            {
                return;
            }

            STGenericModel model = new STGenericModel(Label);

            model.Skeleton = new SkeletonFormat();
            for (int i = 0; i < DataParser.Files.Count; i++)
            {
                if (DataParser.Files[i].Hash == File.Hash &&
                    DataParser.Files[i].ChunkEntry.ChunkType == ChunkFileType.Skeleton)
                {
                    if (DataParser.Version == DICT.GameVersion.LM2)
                    {
                        model.Skeleton = LM2.SkeletonChunk.Read(DataParser.Files[i].ChunkEntry.SubData);
                    }
                    if (DataParser.Version == DICT.GameVersion.LM3)
                    {
                        model.Skeleton = LM3.SkeletonChunk.Read(DataParser.Files[i].ChunkEntry.SubData);
                    }
                }
            }

            Dictionary <uint, int> boneHashToID = ((SkeletonFormat)model.Skeleton).BoneHashToID;

            if (DataParser.Version == DICT.GameVersion.LM3)
            {
                var modelList = ModelChunk.Read(File.ChunkEntry.SubData, boneHashToID);

                /*   var materialChunk = File.ChunkEntry.SubData.FirstOrDefault(x => x.ChunkType == ChunkDataType.MaterialData);
                 * var materialLookupChunk = File.ChunkEntry.SubData.FirstOrDefault(x => x.ChunkType == ChunkDataType.MaterialLookupTable);
                 *
                 * var matChunks = MaterialLoaderHelper.CreateMaterialChunkList(materialChunk.Data,
                 *     materialLookupChunk.Data, modelList.SelectMany(x => x.Meshes).ToList());*/

                int index = 0;
                foreach (var mdl in modelList)
                {
                    foreach (var mesh in mdl.Meshes)
                    {
                        var genericMesh = new STGenericMesh();
                        genericMesh.Name = Hashing.CreateHashString(mesh.MeshHeader.Hash);
                        if (Hashing.HashNames.ContainsKey(mesh.MeshHeader.MaterialHash))
                        {
                            genericMesh.Name += $"_{Hashing.CreateHashString(mesh.MeshHeader.MaterialHash)}";
                        }

                        Console.WriteLine($"MESH_HASHM {Hashing.CreateHashString(mesh.MeshHeader.MaterialHash)}");
                        Console.WriteLine($"MESH_HASHV {Hashing.CreateHashString(mesh.MeshHeader.VertexFormatHash)}");

                        genericMesh.Vertices.AddRange(mesh.Vertices);

                        var poly = new STPolygonGroup();
                        poly.Faces = mesh.Faces.ToList();
                        genericMesh.PolygonGroups.Add(poly);
                        model.Meshes.Add(genericMesh);

                        var material = new LMMaterial();
                        poly.Material = material;

                        material.TextureMaps.Add(new STGenericTextureMap()
                        {
                            Name = Hashing.CreateHashString(mesh.Material.DiffuseHash),
                            Type = STTextureType.Diffuse,
                        });
                        index++;
                    }
                }
            }
            else
            {
                var modelList = LM2.ModelChunk.Read(File.ChunkEntry.SubData, boneHashToID);
                foreach (var mdl in modelList)
                {
                    foreach (var mesh in mdl.Meshes)
                    {
                        var genericMesh = new STGenericMesh();
                        genericMesh.Name = Hashing.CreateHashString(mesh.MeshHeader.Hash);
                        if (Hashing.HashNames.ContainsKey(mesh.MeshHeader.MaterialHash))
                        {
                            genericMesh.Name += $"_{Hashing.CreateHashString(mesh.MeshHeader.MaterialHash)}";
                        }

                        genericMesh.Name += $"_{mesh.MeshHeader.VertexFormatHash}_{VertexLoaderExtension.GetStride(mesh.MeshHeader.VertexFormatHash)}";

                        uint vertexStride = VertexLoaderExtension.GetStride(mesh.MeshHeader.VertexFormatHash);

                        if (mesh.Vertices.Count == 0)
                        {
                            continue;
                        }

                        genericMesh.Vertices.AddRange(mesh.Vertices);

                        var poly = new STPolygonGroup();
                        poly.Faces = mesh.Faces.ToList();
                        genericMesh.PolygonGroups.Add(poly);
                        model.Meshes.Add(genericMesh);

                        var material = new LMMaterial();
                        material.IsAmbientMap = mesh.Material.IsAmbientMap;
                        poly.Material         = material;

                        material.TextureMaps.Add(new STGenericTextureMap()
                        {
                            Name = Hashing.CreateHashString(mesh.Material.DiffuseTextureHash),
                            Type = STTextureType.Diffuse,
                        });

                        if (mesh.Material.HasShadowMap)
                        {
                            material.TextureMaps.Add(new STGenericTextureMap()
                            {
                                Name = Hashing.CreateHashString(mesh.Material.ShadowTextureHash),
                                Type = STTextureType.Shadow,
                            });
                        }
                    }
                }
            }


            Tag = new ModelFormat(model);

            foreach (var child in model.CreateTreeHiearchy().Children)
            {
                AddChild(child);
            }

            loaded = true;
        }
Ejemplo n.º 12
0
        public void Import(string fileName, string textureName, string sceneName, string sceneSubname, SceneContainer container)
        {
            var VertexList = new List <Vector3>();
            var NormalList = new List <Vector3>();
            var UVList     = new List <Vector2>();
            var FacesList  = new List <Vector3>();

            var obj = new Obj();

            obj.LoadObj(fileName);

            if (obj == null)
            {
                return;
            }

            var model = new ModelChunk(container);

            for (int index = 0; index < obj.VertexList.Count; index++)
            {
                VertexList.Add(new Vector3(float.Parse(obj.VertexList[index].X.ToString()) / 100,
                                           float.Parse(obj.VertexList[index].Y.ToString()) / 100,
                                           float.Parse(obj.VertexList[index].Z.ToString()) / 100));
            }

            for (int index = 0; index < obj.NormalList.Count; index++)
            {
                NormalList.Add(new Vector3(float.Parse(obj.NormalList[index].X.ToString()) / 100,
                                           float.Parse(obj.NormalList[index].Y.ToString()) / 100,
                                           float.Parse(obj.NormalList[index].Z.ToString()) / 100));
            }

            for (int index = 0; index < obj.TextureList.Count; index++)
            {
                UVList.Add(new Vector2(float.Parse(obj.TextureList[index].X.ToString()) / 100, 0.0f -
                                       float.Parse(obj.TextureList[index].Y.ToString()) / 100));
            }

            for (int index = 0; index < VertexList.Count; index++)
            {
                model.Mesh.Vertices.Add(VertexList[index]);
            }

            for (int index = 0; index < obj.FaceList.Count; index++)
            {
                string   face       = obj.FaceList[index].ToString();
                string[] face_array = face.Split(' ');

                string X = Convert.ToString(face_array[1]);
                string Y = Convert.ToString(face_array[2]);
                string Z = Convert.ToString(face_array[3]);

                string[] _X = X.Split('/');
                string[] _Y = Y.Split('/');
                string[] _Z = Z.Split('/');

                FacesList.Add(new Vector3(Convert.ToInt32(_X[0]) - 1,
                                          Convert.ToInt32(_Y[0]) - 1,
                                          Convert.ToInt32(_Z[0]) - 1));
            }

            var texture = new TextureEntry
            {
                FaceCount   = obj.FaceList.Count,
                FaceCounter = 0,

                FileName  = textureName,
                FileName2 = ""
            };

            if (model.TextureData.Textures.Count != 0)
            {
                model.TextureData.Textures[0] = texture;
            }
            else
            {
                model.TextureData.Textures.Add(texture);
            }

            model.Mesh.Normals = NormalList;
            model.Mesh.UV      = UVList;
            model.Mesh.Faces   = FacesList;
            model.Name         = sceneName;
            model.SubName      = sceneSubname;
            model.Image        = Properties.Resources.model;

            container.Add(model);
        }
Ejemplo n.º 13
0
 private void Visit(ModelChunk chunk)
 {
     ModelType = chunk.ModelType;
 }
Ejemplo n.º 14
0
 public void EditAnimation(ModelChunk model, IList <ModelAnimation> animation) => model.Animation = animation;
Ejemplo n.º 15
0
 public void EditShader(ModelChunk model, Shader shader) => model.Shader = shader;
Ejemplo n.º 16
0
        public void BuildChunkModelNow()
        {
            if (ModelBuilding || !QueuedForModelBuild)
            {
                return;
            }

            ModelBuilding = true;

            //ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>> modelRaw = new ConcurrentDictionary<Shader<ModelBlock>, List<RawQuad>>();

            //List<RawQuad> quads;

            Stopwatch sw = Stopwatch.StartNew(); //this is just a debug thing....

            var air = BlockRegistry.GetBlock <BlockAir>();

            var vertexes = new List <float>();
            var normals  = new List <float>();
            var uvs      = new List <float>();

            object locker = new object();

            //generate the model - fill MODEL_RAW
            Enumerable.Range(0, ChunkHeight).AsParallel().ForAll(y =>
            {
                for (int x = 0; x < ChunkSize; x++)
                {
                    for (int z = 0; z < ChunkSize; z++)
                    {
                        BlockPos worldPos = new BlockPos(x + Pos.WorldSpaceX(), y, z + Pos.WorldSpaceZ());

                        BlockState state = World.GetBlockState(worldPos);
                        if (state.Block == air)
                        {
                            continue;
                        }

                        BlockPos localPos = new BlockPos(x, y, z);

                        ModelBlockRaw mbr = (ModelBlockRaw)state.Model?.RawModel;

                        if (mbr == null)
                        {
                            continue;
                        }

                        if (!state.Block.IsFullCube)
                        {
                            lock (locker)
                                mbr.AppendAllVertexData(vertexes, normals, uvs, localPos);

                            continue;
                        }

                        for (var index = 0; index < FaceSides.AllSides.Count; index++)
                        {
                            FaceSides dir = FaceSides.AllSides[index];

                            BlockPos worldPosO = worldPos.Offset(dir);
                            BlockState stateO  = World.GetBlockState(worldPosO);

                            if (!(stateO.Block == air ||
                                  stateO.Block.HasTransparency && !state.Block.HasTransparency) &&
                                stateO.Block.IsFullCube)
                            {
                                continue;
                            }

                            lock (locker)
                            {
                                mbr.AppendVertexDataForSide(dir, vertexes, normals, uvs, localPos);
                                //mbr.AppendNormalsForSide(dir, normals);
                                //mbr.AppendUvsForSide(dir, uvs);
                            }
                        }
                    }
                }
            });

            sw.Stop();
            Console.WriteLine($"DEBUG: built chunk model [{sw.Elapsed.TotalMilliseconds:F}ms]");

            float[] vtx = vertexes.ToArray(); //this is here because this takes time and I don't want it to slow down the main thread by running it in GlContext
            float[] nrm = normals.ToArray();
            float[] uv  = uvs.ToArray();

            SharpCraft.Instance.RunGlContext(() =>
            {
                if (_model == null)
                {
                    _model = new ModelChunk(vtx, nrm, uv, Block.DefaultShader);
                }
                else
                {
                    _model.OverrideData(vtx, nrm, uv);
                }

                ModelBuilding = false;
            });

            QueuedForModelBuild = false;
        }
Ejemplo n.º 17
0
            public bool loadFile(string filename)
            {
                LuaState vm = new LuaState();

                LuaExt.extendLua(vm);

                try
                {
                    if (vm.doFile(filename) == false)
                    {
                        Warn.print("Unable to open BOB file {0}", filename);
                        return(false);
                    }

                    LuaObject data = vm.findObject("BOB");
                    if (data == null)
                    {
                        Warn.print("Unable to find BOB data in file {0}", filename);
                        return(false);
                    }

                    myVersion = data.get <UInt32>("version");

                    //read the registry
                    LuaObject registry = data.get <LuaObject>("registry");
                    parseRegistry(registry);

                    //read the chunks
                    LuaObject chunks = data.get <LuaObject>("chunks");
                    for (int i = 1; i <= chunks.count(); i++)
                    {
                        LuaObject chunkData = chunks[i];
                        switch (chunkData.get <String>("type"))
                        {
                        case "model":
                            ModelChunk model = new ModelChunk();
                            parseModel(model, chunkData);
                            myChunks.Add(model);
                            break;

                        case "skeleton":
                            SkeletonChunk skeleton = new SkeletonChunk();
                            parseSkeleton(skeleton, chunkData);
                            myChunks.Add(skeleton);
                            break;

                        case "animation":
                            AnimationChunk animation = new AnimationChunk();
                            parseAnimation(animation, chunkData);
                            myChunks.Add(animation);
                            break;

                        case "texture":
                            Warn.print("Skipping .BOB texture");
                            break;

                        case "particle":
                            Warn.print("Skipping .BOB particle system");
                            break;

                        case "audio":
                            Warn.print("Skipping .BOB audio");
                            break;

                        default:
                            Warn.print("Unknown type: {0}", chunkData.get <String>("type"));
                            break;
                        }
                    }
                }
                catch (Exception ex)
                {
                    throw new Exception("Error while loading BOB model from definition file ( " + filename + " ).", ex);
                }
                return(true);
            }
Ejemplo n.º 18
0
        public override void GenerateChunk(Span target, ChunkGeneratorContext context)
        {
            var modelChunk = new ModelChunk(ModelType);

            context.ChunkTreeBuilder.AddChunk(modelChunk, target, topLevel: true);
        }
 protected virtual void Visit(ModelChunk chunk)
 {
     // TODO: Should remove once a more generic directive chunk is created.
 }
Ejemplo n.º 20
0
        public BMD(NitroFile file)
        {
            m_File     = file;
            m_FileName = file.m_Name;

            /* if (m_File.m_ID == 741)
             *   lolol = true;
             * else*/
            lolol = false;

            // Keep a list of pointers so it's easier to add/remove entries, space etc.
            m_PointerList = new List <PointerReference>();

            m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0));

            // ModelChunk refers to Bone
            m_NumModelChunks    = m_File.Read32(0x04);
            m_ModelChunksOffset = m_File.Read32(0x08);
            AddPointer(0x08);
            for (int i = 0; i < m_NumModelChunks; i++)
            {
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38));
            }

            // PolyChunk refers to Display List
            m_NumPolyChunks    = m_File.Read32(0x0C);
            m_PolyChunksOffset = m_File.Read32(0x10);
            AddPointer(0x10);
            for (int i = 0; i < m_NumPolyChunks; i++)
            {
                // Offset to Display List within Display List entries
                AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4));
                // Offsets within the Display List 16 byte headers
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04);
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C);
            }
            m_NumTexChunks    = m_File.Read32(0x14);
            m_TexChunksOffset = m_File.Read32(0x18);
            m_TextureIDs      = new Dictionary <string, uint>();
            AddPointer(0x18);
            for (int i = 0; i < m_NumTexChunks; i++)
            {
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0));
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4));
                m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i);
            }
            m_NumPalChunks    = m_File.Read32(0x1C);
            m_PalChunksOffset = m_File.Read32(0x20);
            m_PaletteIDs      = new Dictionary <string, uint>();
            AddPointer(0x20);
            for (int i = 0; i < m_NumPalChunks; i++)
            {
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0));
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4));
                m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i);
            }
            m_NumMatChunks    = m_File.Read32(0x24);
            m_MatChunksOffset = m_File.Read32(0x28);
            AddPointer(0x28);
            for (int i = 0; i < m_NumMatChunks; i++)
            {
                AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0));
            }
            m_BoneMapOffset = m_File.Read32(0x2C);
            AddPointer(0x2C);

            m_Textures    = new Dictionary <string, NitroTexture>();
            m_ModelChunks = new ModelChunk[m_NumModelChunks];

            for (uint c = 0; c < m_NumModelChunks; c++)
            {
                ModelChunk mdchunk = new ModelChunk(this);
                m_ModelChunks[c] = mdchunk;

                uint mdchunkoffset = m_ModelChunksOffset + (c * 64);

                mdchunk.m_ID   = m_File.Read32(mdchunkoffset);
                mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0);

                // transforms part
                {
                    int   xscale = (int)m_File.Read32(mdchunkoffset + 0x10);
                    int   yscale = (int)m_File.Read32(mdchunkoffset + 0x14);
                    int   zscale = (int)m_File.Read32(mdchunkoffset + 0x18);
                    short xrot   = (short)m_File.Read16(mdchunkoffset + 0x1C);
                    short yrot   = (short)m_File.Read16(mdchunkoffset + 0x1E);
                    short zrot   = (short)m_File.Read16(mdchunkoffset + 0x20);
                    int   xtrans = (int)m_File.Read32(mdchunkoffset + 0x24);
                    int   ytrans = (int)m_File.Read32(mdchunkoffset + 0x28);
                    int   ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C);

                    mdchunk.m_Scale       = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f);
                    mdchunk.m_Rotation    = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f);
                    mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f);
                    mdchunk.m_Transform   = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation);

                    // Used when exporting bones
                    mdchunk.m_20_12Scale       = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale };
                    mdchunk.m_4_12Rotation     = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot };
                    mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans };

                    // if the chunk has a parent, apply the parent's transform to the chunk's transform.
                    // we don't need to go further than one level because the paren't transform already
                    // went through its parents' transforms.
                    short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8);
                    if (parent_offset < 0)
                    {
                        int parentchunkid = (int)(c + parent_offset);
                        Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform);
                    }
                    mdchunk.m_ParentOffset = parent_offset;
                }
                // If 0x0A is set to 1 the bone has children, if 0 it doesn't
                mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1);

                mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C));

                uint flags = m_File.Read32(mdchunkoffset + 0x3C);
                mdchunk.m_Billboard = ((flags & 0x1) == 0x1);

                uint numpairs = m_File.Read32(mdchunkoffset + 0x30);
                uint matlist  = m_File.Read32(mdchunkoffset + 0x34);
                uint polylist = m_File.Read32(mdchunkoffset + 0x38);

                mdchunk.m_MatGroups = new MaterialGroup[numpairs];

                for (uint i = 0; i < numpairs; i++)
                {
                    MaterialGroup matgroup = new MaterialGroup();
                    mdchunk.m_MatGroups[i] = matgroup;

                    byte matID  = m_File.Read8(matlist + i);
                    byte polyID = m_File.Read8(polylist + i);

                    uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48));

                    matgroup.m_ID   = matID;
                    matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0);
                    uint texid = m_File.Read32(mchunkoffset + 0x04);
                    uint palid = m_File.Read32(mchunkoffset + 0x08);
                    matgroup.m_TexParams    = m_File.Read32(mchunkoffset + 0x20);
                    matgroup.m_PolyAttribs  = m_File.Read32(mchunkoffset + 0x24);
                    matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28);
                    matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C);

                    if ((matgroup.m_PolyAttribs & 0x30) == 0x10)
                    {
                        matgroup.m_TexEnvMode = TextureEnvMode.Decal;
                    }
                    else
                    {
                        matgroup.m_TexEnvMode = TextureEnvMode.Modulate;
                    }

                    switch (matgroup.m_PolyAttribs & 0xC0)
                    {
                    case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break;

                    case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break;

                    case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break;
                    }

                    matgroup.m_DiffuseColor  = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors);
                    matgroup.m_AmbientColor  = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16));
                    matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors);
                    matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16));

                    switch (matgroup.m_TexParams >> 30)
                    {
                    case 0:
                        matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f);
                        matgroup.m_TexCoordRot   = 0.0f;
                        matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f);
                        break;

                    case 1:
                    {
                        int   sscale = (int)m_File.Read32(mchunkoffset + 0x0C);
                        int   tscale = (int)m_File.Read32(mchunkoffset + 0x10);
                        short trot   = (short)m_File.Read16(mchunkoffset + 0x14);
                        int   strans = (int)m_File.Read32(mchunkoffset + 0x18);
                        int   ttrans = (int)m_File.Read32(mchunkoffset + 0x1C);

                        matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f);
                        matgroup.m_TexCoordRot   = ((float)trot * (float)Math.PI) / 2048.0f;
                        matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f);
                    }
                    break;

                    case 2:
                        goto case 1;

                    case 3:
                        goto case 1;

                    default:
                        break;
                        // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30));
                    }

                    if (texid != 0xFFFFFFFF)
                    {
                        matgroup.m_Texture    = ReadTexture(texid, palid);
                        matgroup.m_TexParams |= matgroup.m_Texture.m_DSTexParam;
                    }
                    else
                    {
                        matgroup.m_Texture = null;
                    }

                    uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4));
                    uint dloffset     = m_File.Read32(pchunkoffset + 0x0C);
                    uint dlsize       = m_File.Read32(pchunkoffset + 0x08);
                    uint numbones     = m_File.Read32(pchunkoffset);
                    uint bonesoffset  = m_File.Read32(pchunkoffset + 0x04);

                    matgroup.m_BoneIDs = new ushort[numbones];
                    for (uint b = 0; b < numbones; b++)
                    {
                        byte idx1 = m_File.Read8(bonesoffset + b);
                        matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1)));
                    }

                    matgroup.m_Geometry = new List <VertexList>();

                    m_CurVertex.m_Position = new Vector3(0, 0, 0);
                    m_CurVertex.m_TexCoord = null;
                    m_CurVertex.m_Normal   = null;

                    if ((matgroup.m_PolyAttribs & 0x8000) != 0x8000)
                    {
                        byte alpha = (byte)((matgroup.m_PolyAttribs >> 16) & 0x1F);
                        alpha           |= (byte)(alpha >> 5);
                        matgroup.m_Alpha = alpha;
                    }

                    if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000)
                    {
                        m_CurVertex.m_Color = Color.FromArgb(matgroup.m_Alpha << 3, matgroup.m_DiffuseColor);
                    }
                    else
                    {
                        m_CurVertex.m_Color = Color.Black;
                    }

                    m_CurVertex.m_MatrixID = 0;

                    uint dlend = dloffset + dlsize;
                    for (uint pos = dloffset; pos < dlend;)
                    {
                        byte cmd1 = m_File.Read8(pos++);
                        byte cmd2 = m_File.Read8(pos++);
                        byte cmd3 = m_File.Read8(pos++);
                        byte cmd4 = m_File.Read8(pos++);

                        ProcessGXCommand(matgroup, cmd1, ref pos);
                        ProcessGXCommand(matgroup, cmd2, ref pos);
                        ProcessGXCommand(matgroup, cmd3, ref pos);
                        ProcessGXCommand(matgroup, cmd4, ref pos);
                    }
                }
            }

            foreach (ModelChunk mdchunk in m_ModelChunks)
            {
                foreach (MaterialGroup matgroup in mdchunk.m_MatGroups)
                {
                    matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length];
                    for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++)
                    {
                        matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform;
                    }
                }
            }

            int index = 0;

            foreach (KeyValuePair <string, uint> entry in m_TextureIDs)
            {
                if (!m_Textures.ContainsKey(entry.Key))
                {
                    Console.WriteLine("NOT IN TEXTURES: " + entry.Key);
                    uint palID = Math.Min(m_PaletteIDs.ElementAt(index).Value, (uint)m_PaletteIDs.Count - 1);
                    ReadTexture(entry.Value, palID);
                }
                index++;
            }
        }
Ejemplo n.º 21
0
        public static SceneContainer ReadFrom(Stream stream)
        {
            var container = new SceneContainer();

            using (var r = new BinaryReader(stream))
            {
                container.Header.Deserialize(stream);

                // CoreLib::Scene::CSceneGroup
                var chunkCount = r.ReadUInt32();

                if (container.Header.Unk2 >= 0.2000000029802322f)
                {
                    r.ReadByte(); // ToDo ReadString
                }
                for (var i = 0; i < chunkCount; i++)
                {
                    var type    = r.ReadEnum <ChunkType>();
                    var name    = r.ReadCString();
                    var subName = r.ReadCString();

                    SceneChunk chunk;
                    switch (type)
                    {
                    case ChunkType.ModelData:
                        chunk = new ModelChunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    case ChunkType.Box:
                        chunk = new BoxChunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    case ChunkType.Bone:
                        chunk = new BoneChunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    case ChunkType.BoneSystem:
                        chunk = new BoneSystemChunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    case ChunkType.Shape:
                        chunk = new ShapeChunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    case ChunkType.SkyDirect1:
                        chunk = new SkyDirect1Chunk(container)
                        {
                            Name    = name,
                            SubName = subName
                        };
                        chunk.Deserialize(stream);
                        container.Add(chunk);
                        break;

                    default:
                        throw new Exception($"Unknown chunk type: 0x{(int)type:X4} StreamPosition: {r.BaseStream.Position}");
                    }
                }
            }

            return(container);
        }
Ejemplo n.º 22
0
        public BMD(NitroFile file)
        {
            m_File = file;
            m_FileName = file.m_Name;

            /* if (m_File.m_ID == 741)
                 lolol = true;
             else*/
            lolol = false;

            // Keep a list of pointers so it's easier to add/remove entries, space etc.
            m_PointerList = new List<PointerReference>();

            m_ScaleFactor = (float)(1 << (int)m_File.Read32(0x0));

            // ModelChunk refers to Bone
            m_NumModelChunks = m_File.Read32(0x04);
            m_ModelChunksOffset = m_File.Read32(0x08);
            AddPointer(0x08);
            for (int i = 0; i < m_NumModelChunks; i++)
            {
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x04));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x34));
                AddPointer((uint)(m_ModelChunksOffset + (i * 64) + 0x38));
            }

            // PolyChunk refers to Display List
            m_NumPolyChunks = m_File.Read32(0x0C);
            m_PolyChunksOffset = m_File.Read32(0x10);
            AddPointer(0x10);
            for (int i = 0; i < m_NumPolyChunks; i++)
            {
                // Offset to Display List within Display List entries
                AddPointer((uint)(m_PolyChunksOffset + (i * 8) + 4));
                // Offsets within the Display List 16 byte headers
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x04);
                AddPointer(m_File.Read32((uint)(m_PolyChunksOffset + (i * 8) + 4)) + 0x0C);
            }
            m_NumTexChunks = m_File.Read32(0x14);
            m_TexChunksOffset = m_File.Read32(0x18);
            m_TextureIDs = new Dictionary<string, uint>();
            AddPointer(0x18);
            for (int i = 0; i < m_NumTexChunks; i++)
            {
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 0));
                AddPointer((uint)(m_TexChunksOffset + (i * 20) + 4));
                m_TextureIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_TexChunksOffset + (20 * i))), 0), (uint)i);
            }
            m_NumPalChunks = m_File.Read32(0x1C);
            m_PalChunksOffset = m_File.Read32(0x20);
            m_PaletteIDs = new Dictionary<string, uint>();
            AddPointer(0x20);
            for (int i = 0; i < m_NumPalChunks; i++)
            {
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 0));
                AddPointer((uint)(m_PalChunksOffset + (i * 16) + 4));
                m_PaletteIDs.Add(m_File.ReadString(m_File.Read32((uint)(m_PalChunksOffset + (16 * i))), 0), (uint)i);
            }
            m_NumMatChunks = m_File.Read32(0x24);
            m_MatChunksOffset = m_File.Read32(0x28);
            AddPointer(0x28);
            for (int i = 0; i < m_NumMatChunks; i++)
            {
                AddPointer((uint)(m_MatChunksOffset + (i * 48) + 0));
            }
            m_BoneMapOffset = m_File.Read32(0x2C);
            AddPointer(0x2C);

            m_Textures = new Dictionary<string, Texture>();
            m_ModelChunks = new ModelChunk[m_NumModelChunks];

            for (uint c = 0; c < m_NumModelChunks; c++)
            {
                ModelChunk mdchunk = new ModelChunk(this);
                m_ModelChunks[c] = mdchunk;

                uint mdchunkoffset = m_ModelChunksOffset + (c * 64);

                mdchunk.m_ID = m_File.Read32(mdchunkoffset);
                mdchunk.m_Name = m_File.ReadString(m_File.Read32(mdchunkoffset + 0x04), 0);

                // transforms part
                {
                    int xscale = (int)m_File.Read32(mdchunkoffset + 0x10);
                    int yscale = (int)m_File.Read32(mdchunkoffset + 0x14);
                    int zscale = (int)m_File.Read32(mdchunkoffset + 0x18);
                    short xrot = (short)m_File.Read16(mdchunkoffset + 0x1C);
                    short yrot = (short)m_File.Read16(mdchunkoffset + 0x1E);
                    short zrot = (short)m_File.Read16(mdchunkoffset + 0x20);
                    int xtrans = (int)m_File.Read32(mdchunkoffset + 0x24);
                    int ytrans = (int)m_File.Read32(mdchunkoffset + 0x28);
                    int ztrans = (int)m_File.Read32(mdchunkoffset + 0x2C);

                    mdchunk.m_Scale = new Vector3((float)xscale / 4096.0f, (float)yscale / 4096.0f, (float)zscale / 4096.0f);
                    mdchunk.m_Rotation = new Vector3(((float)xrot * (float)Math.PI) / 2048.0f, ((float)yrot * (float)Math.PI) / 2048.0f, ((float)zrot * (float)Math.PI) / 2048.0f);
                    mdchunk.m_Translation = new Vector3((float)xtrans / 4096.0f, (float)ytrans / 4096.0f, (float)ztrans / 4096.0f);
                    mdchunk.m_Transform = Helper.SRTToMatrix(mdchunk.m_Scale, mdchunk.m_Rotation, mdchunk.m_Translation);

                    // Used when exporting bones
                    mdchunk.m_20_12Scale = new uint[] { (uint)xscale, (uint)yscale, (uint)zscale };
                    mdchunk.m_4_12Rotation = new ushort[] { (ushort)xrot, (ushort)yrot, (ushort)zrot };
                    mdchunk.m_20_12Translation = new uint[] { (uint)xtrans, (uint)ytrans, (uint)ztrans };

                    // if the chunk has a parent, apply the parent's transform to the chunk's transform.
                    // we don't need to go further than one level because the paren't transform already
                    // went through its parents' transforms.
                    short parent_offset = (short)m_File.Read16(mdchunkoffset + 0x8);
                    if (parent_offset < 0)
                    {
                        int parentchunkid = (int)(c + parent_offset);
                        Matrix4.Mult(ref mdchunk.m_Transform, ref m_ModelChunks[parentchunkid].m_Transform, out mdchunk.m_Transform);
                    }
                    mdchunk.m_ParentOffset = parent_offset;
                }
                // If 0x0A is set to 1 the bone has children, if 0 it doesn't
                mdchunk.m_HasChildren = (m_File.Read16(mdchunkoffset + 0x0A) == 1);

                mdchunk.m_SiblingOffset = (short)(m_File.Read16(mdchunkoffset + 0x0C));

                uint flags = m_File.Read32(mdchunkoffset + 0x3C);
                mdchunk.m_Billboard = ((flags & 0x1) == 0x1);

                uint numpairs = m_File.Read32(mdchunkoffset + 0x30);
                uint matlist = m_File.Read32(mdchunkoffset + 0x34);
                uint polylist = m_File.Read32(mdchunkoffset + 0x38);

                mdchunk.m_MatGroups = new MaterialGroup[numpairs];

                for (uint i = 0; i < numpairs; i++)
                {
                    MaterialGroup matgroup = new MaterialGroup();
                    mdchunk.m_MatGroups[i] = matgroup;

                    byte matID = m_File.Read8(matlist + i);
                    byte polyID = m_File.Read8(polylist + i);

                    uint mchunkoffset = (uint)(m_MatChunksOffset + (matID * 48));

                    matgroup.m_ID = matID;
                    matgroup.m_Name = m_File.ReadString(m_File.Read32(mchunkoffset), 0);
                    uint texid = m_File.Read32(mchunkoffset + 0x04);
                    uint palid = m_File.Read32(mchunkoffset + 0x08);
                    matgroup.m_TexParams = m_File.Read32(mchunkoffset + 0x20);
                    matgroup.m_PolyAttribs = m_File.Read32(mchunkoffset + 0x24);
                    matgroup.m_DifAmbColors = m_File.Read32(mchunkoffset + 0x28);
                    matgroup.m_SpeEmiColors = m_File.Read32(mchunkoffset + 0x2C);

                    if ((matgroup.m_PolyAttribs & 0x30) == 0x10)
                        matgroup.m_TexEnvMode = TextureEnvMode.Decal;
                    else
                        matgroup.m_TexEnvMode = TextureEnvMode.Modulate;

                    switch (matgroup.m_PolyAttribs & 0xC0)
                    {
                        case 0x00: matgroup.m_CullMode = CullFaceMode.FrontAndBack; break;
                        case 0x40: matgroup.m_CullMode = CullFaceMode.Front; break;
                        case 0x80: matgroup.m_CullMode = CullFaceMode.Back; break;
                    }

                    matgroup.m_DiffuseColor = Helper.BGR15ToColor((ushort)matgroup.m_DifAmbColors);
                    matgroup.m_AmbientColor = Helper.BGR15ToColor((ushort)(matgroup.m_DifAmbColors >> 16));
                    matgroup.m_SpecularColor = Helper.BGR15ToColor((ushort)matgroup.m_SpeEmiColors);
                    matgroup.m_EmissionColor = Helper.BGR15ToColor((ushort)(matgroup.m_SpeEmiColors >> 16));

                    switch (matgroup.m_TexParams >> 30)
                    {
                        case 0:
                            matgroup.m_TexCoordScale = new Vector2(1.0f, 1.0f);
                            matgroup.m_TexCoordTrans = new Vector2(0.0f, 0.0f);
                            break;

                        case 1:
                            {
                                int sscale = (int)m_File.Read32(mchunkoffset + 0x0C);
                                int tscale = (int)m_File.Read32(mchunkoffset + 0x10);
                                int strans = (int)m_File.Read32(mchunkoffset + 0x18);
                                int ttrans = (int)m_File.Read32(mchunkoffset + 0x1C);

                                matgroup.m_TexCoordScale = new Vector2((float)sscale / 4096.0f, (float)tscale / 4096.0f);
                                matgroup.m_TexCoordTrans = new Vector2((float)strans / 4096.0f, (float)ttrans / 4096.0f);
                                //matgroup.m_TexCoordTrans = new Vector2(0.0f, 16.0f);
                                /*System.Windows.Forms.MessageBox.Show(String.Format("textransform: scale:{0} trans:{1} rot:{2:X8}",
                                    matgroup.m_TexCoordScale, matgroup.m_TexCoordTrans,
                                    m_File.Read32(mchunkoffset + 0x1C)));*/
                            }
                            break;

                        case 2:
                            goto case 1;

                        case 3:
                            goto case 1;

                        default:
                            break;
                        // throw new Exception(String.Format("BMD: unsupported texture coord transform mode {0}", matgroup.m_TexParams >> 30));
                    }

                    if (texid != 0xFFFFFFFF)
                    {
                        matgroup.m_Texture = ReadTexture(texid, palid);
                        matgroup.m_TexParams |= matgroup.m_Texture.m_Params;
                    }
                    else
                        matgroup.m_Texture = null;

                    uint pchunkoffset = m_File.Read32((uint)(m_PolyChunksOffset + (polyID * 8) + 4));
                    uint dloffset = m_File.Read32(pchunkoffset + 0x0C);
                    uint dlsize = m_File.Read32(pchunkoffset + 0x08);
                    uint numbones = m_File.Read32(pchunkoffset);
                    uint bonesoffset = m_File.Read32(pchunkoffset + 0x04);

                    matgroup.m_BoneIDs = new ushort[numbones];
                    for (uint b = 0; b < numbones; b++)
                    {
                        byte idx1 = m_File.Read8(bonesoffset + b);
                        matgroup.m_BoneIDs[b] = m_File.Read16((uint)(m_BoneMapOffset + (2 * idx1)));
                    }

                    matgroup.m_Geometry = new List<VertexList>();

                    m_CurVertex.m_Position = new Vector3(0, 0, 0);
                    m_CurVertex.m_TexCoord = new Vector2(0, 0);
                    if ((matgroup.m_DifAmbColors & 0x8000) == 0x8000)
                    {
                        byte alpha = (byte)((matgroup.m_PolyAttribs >> 13) & 0xF8);
                        alpha |= (byte)(alpha >> 5);
                        matgroup.m_Alpha = alpha;

                        m_CurVertex.m_Color = Color.FromArgb(alpha, matgroup.m_DiffuseColor);
                    }
                    else
                        m_CurVertex.m_Color = Color.Black;

                    m_CurVertex.m_MatrixID = 0;

                    uint dlend = dloffset + dlsize;
                    for (uint pos = dloffset; pos < dlend; )
                    {
                        byte cmd1 = m_File.Read8(pos++);
                        byte cmd2 = m_File.Read8(pos++);
                        byte cmd3 = m_File.Read8(pos++);
                        byte cmd4 = m_File.Read8(pos++);

                        ProcessGXCommand(matgroup, cmd1, ref pos);
                        ProcessGXCommand(matgroup, cmd2, ref pos);
                        ProcessGXCommand(matgroup, cmd3, ref pos);
                        ProcessGXCommand(matgroup, cmd4, ref pos);
                    }
                }
            }

            foreach (ModelChunk mdchunk in m_ModelChunks)
            {
                foreach (MaterialGroup matgroup in mdchunk.m_MatGroups)
                {
                    matgroup.m_BoneMatrices = new Matrix4[matgroup.m_BoneIDs.Length];
                    for (uint b = 0; b < matgroup.m_BoneIDs.Length; b++)
                        matgroup.m_BoneMatrices[b] = m_ModelChunks[matgroup.m_BoneIDs[b]].m_Transform;
                }
            }
        }
Ejemplo n.º 23
0
        private bool f_import_scene()
        {
            if (container == null)
            {
                return(false);
            }

            var file = new OpenFileDialog();

            file.Multiselect = true;
            file.Filter      = ".scn_part|*.scn_part";

            if (file.ShowDialog() == DialogResult.OK)
            {
                for (int i = 0; i < file.FileNames.Length; i++)
                {
                    using (var fs = new FileStream(file.FileName, FileMode.Open, FileAccess.Read, FileShare.None))
                        using (var br = new BinaryReader(fs))
                        {
                            SceneChunk chunk = null;

                            var    type    = br.ReadEnum <ChunkType>();
                            string name    = br.ReadCString();
                            string subname = br.ReadCString();

                            switch (type)
                            {
                            case ChunkType.Bone:
                                chunk = new BoneChunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.bone
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            case ChunkType.BoneSystem:
                                chunk = new BoneSystemChunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.bone_system
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            case ChunkType.Box:
                                chunk = new BoxChunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.box
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            case ChunkType.ModelData:
                                chunk = new ModelChunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.model
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            case ChunkType.Shape:
                                chunk = new ShapeChunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.shape
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            case ChunkType.SkyDirect1:
                                chunk = new SkyDirect1Chunk(container)
                                {
                                    Name    = name,
                                    SubName = subname,
                                    Image   = Properties.Resources.sky
                                };

                                chunk.Deserialize(fs);
                                container.Add(chunk);
                                break;

                            default:
                                return(false);
                            }
                        }
                }
                return(true);
            }
            return(false);
        }
Ejemplo n.º 24
0
            public bool parseModel(ModelChunk m, LuaObject data)
            {
                parseChunkHeader(m, data);

                String pt = data.get <String>("primativeType");

                switch (pt)
                {
                case "TRI": m.primativeType = PrimitiveType.Triangles; break;

                case "TRISTRIP": m.primativeType = PrimitiveType.TriangleStrip; break;
                }

                String vf = data.get <String>("vertexFormat");

                switch (vf)
                {
                case "V3N3T2": m.vertexFormat = ModelChunk.VertexFormat.V3N3T2; break;

                case "V3N3T2B4W4": m.vertexFormat = ModelChunk.VertexFormat.V3N3T2B4W4; break;
                }

                String iff = data.get <String>("indexFormat");

                switch (iff)
                {
                case "UInt16": m.indexType = ModelChunk.IndexFormat.USHORT; break;

                case "UInt32": m.indexType = ModelChunk.IndexFormat.UINT; break;
                }

                m.vertexCount = data.get <UInt32>("vertexCount");
                m.indexCount  = data.get <UInt32>("indexCount");

                LuaObject meshData = data.get <LuaObject>("meshes");

                for (int i = 1; i <= meshData.count(); i++)
                {
                    Mesh mesh = new Mesh();
                    if (parseMesh(mesh, meshData[i]) == true)
                    {
                        m.myMeshes.Add(mesh);
                    }
                }

                LuaObject materialData = data.get <LuaObject>("materials");

                for (int i = 1; i <= materialData.count(); i++)
                {
                    Material material = new Material();
                    if (parseMaterial(material, materialData[i]) == true)
                    {
                        m.myMaterials.Add(material);
                    }
                }

                LuaObject vertData = data.get <LuaObject>("verts");

                switch (m.vertexFormat)
                {
                case ModelChunk.VertexFormat.V3N3T2:
                {
                    m.verts   = new List <Vector3>();
                    m.normals = new List <Vector3>();
                    m.uvs     = new List <Vector2>();

                    int i = 1;
                    for (int vert = 0; vert < m.vertexCount; vert++)
                    {
                        m.verts.Add(new Vector3(vertData[i++], vertData[i++], vertData[i++]));
                        m.normals.Add(new Vector3(vertData[i++], vertData[i++], vertData[i++]));
                        m.uvs.Add(new Vector2(vertData[i++], vertData[i++]));
                    }
                    break;
                }

                case ModelChunk.VertexFormat.V3N3T2B4W4:
                {
                    m.verts       = new List <Vector3>();
                    m.normals     = new List <Vector3>();
                    m.uvs         = new List <Vector2>();
                    m.boneIdx     = new List <Vector4>();
                    m.boneWeights = new List <Vector4>();

                    int i = 1;
                    for (int vert = 0; vert < m.vertexCount; vert++)
                    {
                        m.verts.Add(new Vector3(vertData[i++], vertData[i++], vertData[i++]));
                        m.normals.Add(new Vector3(vertData[i++], vertData[i++], vertData[i++]));
                        m.uvs.Add(new Vector2(vertData[i++], vertData[i++]));
                        m.boneIdx.Add(new Vector4(vertData[i++], vertData[i++], vertData[i++], vertData[i++]));
                        m.boneWeights.Add(new Vector4(vertData[i++], vertData[i++], vertData[i++], vertData[i++]));
                    }
                    break;
                }
                }

                LuaObject indexData = data.get <LuaObject>("indexes");

                switch (m.indexType)
                {
                case ModelChunk.IndexFormat.USHORT:
                {
                    m.indexShort = new List <UInt16>();
                    int i = 1;
                    for (int idx = 0; idx < m.indexCount; idx++)
                    {
                        m.indexShort.Add((UInt16)((float)indexData[i++]));
                    }
                    break;
                }

                case ModelChunk.IndexFormat.UINT:
                {
                    m.indexInt = new List <UInt32>();
                    int i = 1;
                    for (int idx = 0; idx < m.indexCount; idx++)
                    {
                        m.indexInt.Add((UInt32)((float)indexData[i++]));
                    }
                    break;
                }
                }

                return(true);
            }