Beispiel #1
0
        private void exportBtn_Click(object sender, EventArgs e)
        {
            if (objSaveDialog.ShowDialog() == DialogResult.OK)
            {
                string OBJfilename = objSaveDialog.FileName;
                string MTLfilename = objSaveDialog.FileName.Split('.')[0] + ".mtl";

                if (modelsListTree.SelectedNode.Level == 1)
                {
                    if (modelsListTree.SelectedNode.Parent.Index == 0)       //Level model
                    {
                        RatchetModel_General selectedModel = DataStore.spawnableModels[modelsListTree.SelectedNode.Index];
                        SpawnableToObj(ref selectedModel, OBJfilename, MTLfilename);
                        Console.WriteLine("OBJ file created: " + OBJfilename);
                        Console.WriteLine("MTL file created: " + MTLfilename);
                    }
                    else if (modelsListTree.SelectedNode.Parent.Index == 3)    //Terrain
                    {
                        RatchetModel_Terrain model = DataStore.terrainModel;
                        terrainMeshToObj(ref model, OBJfilename, MTLfilename);
                        Console.WriteLine("OBJ file created: " + OBJfilename);
                        Console.WriteLine("MTL file created: " + MTLfilename);
                    }
                    else
                    {
                        MessageBox.Show("Not currently supported");
                    }
                }
            }
        }
        private void glControl1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Left)
            {
                GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

                glControl1.MakeCurrent();
                GL.UseProgram(pgm2ID);

                GL.EnableVertexAttribArray(0);

                camX.Text = cPosition.X.ToString();
                camY.Text = cPosition.Y.ToString();
                camZ.Text = cPosition.Z.ToString();

                Matrix4 View      = Matrix4.LookAt(cPosition, cTarget, Vector3.UnitZ);
                Matrix4 worldView = View * projection;


                if (modReady && mobyCheck.Checked)
                {
                    GL.ClearColor(0, 0, 0, 0);
                    foreach (RatchetMoby mob in DataStore.mobs)
                    {
                        objModel = DataStore.spawnableModels.Find(x => x.modelID == mob.modelID);
                        int insx = mobList.IndexOf((uint)objModel.modelID);
                        if (insx != -1)
                        {
                            int     mobNum   = DataStore.mobs.IndexOf(mob);
                            byte[]  cols     = BitConverter.GetBytes(mobNum);
                            Matrix4 modTrans = Matrix4.CreateTranslation(mob.x, mob.y, mob.z);
                            Matrix4 modScale = Matrix4.CreateScale(objModel.size * mob.size);
                            Matrix4 xRot     = Matrix4.CreateRotationX(mob.rot1);
                            Matrix4 yRot     = Matrix4.CreateRotationY(mob.rot2);
                            Matrix4 zRot     = Matrix4.CreateRotationZ(mob.rot3);
                            Matrix4 modRot   = xRot * yRot * zRot;
                            mvp = modScale * modRot * modTrans * worldView;  //Has to be done in this order to work correctly
                            GL.UniformMatrix4(MatrixID, false, ref mvp);

                            GL.BindBuffer(BufferTarget.ArrayBuffer, mobVerts[insx]);
                            GL.BindBuffer(BufferTarget.ElementArrayBuffer, mobInds[insx]);

                            //Verts
                            GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, 0);

                            GL.Uniform4(pgmID_rcID, new Vector4(cols[0] / 255f, cols[1] / 255f, cols[2] / 255f, 1));
                            GL.DrawElements(PrimitiveType.Triangles, objModel.indiceBuff.Count(), DrawElementsType.UnsignedShort, 0);
                        }
                    }
                    Byte4 pixel = new Byte4();
                    GL.ReadPixels(glControl1.PointToClient(Cursor.Position).X, glControl1.Height - glControl1.PointToClient(Cursor.Position).Y, 1, 1, OpenTK.Graphics.OpenGL.PixelFormat.Rgba, PixelType.UnsignedByte, ref pixel);
                    if (pixel.A == 0)
                    {
                        mainForm.objViewer.selectList(pixel.ToUInt32());
                    }
                    GL.ClearColor(Color.SkyBlue);
                }
                glControl1.Invalidate();
            }
        }
Beispiel #3
0
        private void modelsListTree_AfterSelect(object sender, TreeViewEventArgs e)
        {
            if (e.Node.Level == 1 && e.Node.Tag != null)
            { //Check that we're actually on a model
                switch ((ModelType)e.Node.Tag)
                {
                case ModelType.Spawnable:
                    if (e.Node.Name.IndexOf("Mission_") != -1)
                    {
                        selectedModel = DataStore.missions[int.Parse(e.Node.Name.Substring(8))].spawnableModels[e.Node.Index];
                    }
                    else
                    {
                        selectedModel = DataStore.spawnableModels[e.Node.Index];
                    }
                    break;

                case ModelType.Level:
                    selectedModel = DataStore.levelModels[e.Node.Index];
                    break;

                case ModelType.Scenery:
                    selectedModel = DataStore.sceneryModels[e.Node.Index];
                    break;

                case ModelType.Terrain:
                    RatchetModel_Terrain terrModel = DataStore.terrainModel;
                    modelDataList.Items.Clear();
                    modelDataList.Items.Add("RENDERING DISABLED");
                    modelDataList.Items.Add("Faces: " + terrModel.indiceBuff.Count.ToString("X"));
                    modelDataList.Items.Add("Vertices: " + terrModel.vertBuff.Count.ToString("X"));
                    break;
                }
                inval();
            }
            else
            {
                modelDataList.Items.Clear();
            }
        }
        public static void parseMap(string path, string fileName)
        {
            FileStream fs = File.OpenRead(path + "/" + fileName);

            FileStream vfs = null;

            if (File.Exists(path + "/vram.ps3"))
            {
                vfs = File.OpenRead(path + "/vram.ps3");
            }

            FileStream gpf = null;

            if (File.Exists(path + "/gameplay_ntsc"))
            {
                gpf = File.OpenRead(path + "/gameplay_ntsc");
            }

            uint racNum = 0;

            ushort magic = BAToUInt16(ReadBlock(fs, 0xB0, 2), 0);

            switch (magic)
            {
            case 0x7533:
                racNum = 1;
                break;

            case 0xEA9C:
                racNum = 2;
                break;

            case 0x0000:
            case 0x755D:
                racNum = 3;
                break;
            }
            Console.WriteLine("Game determined to be ratchet" + racNum.ToString());

            List <MobyPropertyVariables> pVarConfigs = new List <MobyPropertyVariables>();
            string jsonString = File.ReadAllText(String.Format("./Config/Rac{0}/MobyPropertyVariables.json", racNum));

            pVarConfigs       = JsonConvert.DeserializeObject <List <MobyPropertyVariables> >(jsonString);
            DataStore.pVarMap = pVarConfigs;

            #region GameplayHeader
            GameplayHeader gameplayHeader = new GameplayHeader(gpf, racNum);

            DataStore.gameplayHeader = gameplayHeader;

            #endregion

            #region pVars
            List <byte[]> pVars;
            uint          numpVars;
            byte[]        pVarHeadBlock;
            uint          pVarSectionLength;
            byte[]        pVarBlock;
            switch (racNum)
            {
            case 1:
            case 2:
            case 3:
                pVars             = new List <byte[]>();
                numpVars          = (gameplayHeader.pVarPointer - gameplayHeader.pVarListPointer) / 8;
                pVarHeadBlock     = ReadBlock(gpf, gameplayHeader.pVarListPointer, numpVars * 8);
                pVarSectionLength = 0;
                for (uint i = 0; i < numpVars; i++)
                {
                    pVarSectionLength += BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                }
                pVarBlock = ReadBlock(gpf, gameplayHeader.pVarPointer, pVarSectionLength);
                for (uint i = 0; i < numpVars; i++)
                {
                    uint   mobpVarsStart = BAToUInt32(pVarHeadBlock, (i * 8));
                    uint   mobpVarsCount = BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                    byte[] mobpVars      = new byte[mobpVarsCount];
                    mobpVars = getBytes(pVarBlock, (int)mobpVarsStart, (int)mobpVarsCount);
                    pVars.Add(mobpVars);
                }
                DataStore.pVarList = pVars;
                break;
            }
            #endregion pVars

            #region Mobies

            uint   mobyCount = BAToUInt32(ReadBlock(gpf, gameplayHeader.mobyPointer, 4), 0);
            byte[] mobyBlock = ReadBlock(gpf, gameplayHeader.mobyPointer + 0x10, mobyCount * gameplayHeader.mobyElemSize);

            for (uint i = 0; i < mobyCount; i++)
            {
                RatchetMoby mob = new RatchetMoby(racNum, mobyBlock, i);
                DataStore.mobs.Add(mob);
            }
            #endregion

            DataStore.splines = new List <Spline>();

            uint   splineCount       = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer, 4), 0);
            uint   splineOffset      = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 4, 4), 0);
            uint   splineSectionSize = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 8, 4), 0);
            byte[] splineHeadBlock   = ReadBlock(gpf, gameplayHeader.splinePointer + 0x10, splineCount * 4);
            byte[] splineBlock       = ReadBlock(gpf, gameplayHeader.splinePointer + splineOffset, splineSectionSize);
            for (uint i = 0; i < splineCount; i++)
            {
                uint offset = BAToUInt32(splineHeadBlock, (i * 4));
                DataStore.splines.Add(new Spline(splineBlock, offset));
            }


            gpf.Close();

            EngineHeader engineHeader = new EngineHeader(fs, 1);
            DataStore.engineHeader = engineHeader;

            //Load UYA Spawnable Models
            #region Spawnables
            uint   spawnablesCount = BAToUInt32(ReadBlock(fs, engineHeader.spawnablesPointer, 4), 0);
            byte[] idBlock         = ReadBlock(fs, engineHeader.spawnablesPointer + 4, spawnablesCount * 8);

            for (int x = 0; x < spawnablesCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Spawnable;

                model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                if (model.offset != 0)
                {
                    uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                    if (modelHeadSize > 0)
                    {
                        byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                        uint   objectPtr = BAToUInt32(headBlock, 0);
                        model.animationsCount = headBlock[0x0C];
                        //(0x04)null
                        //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                        //(0x0c)[animation count][unknown][unknown][unknown]
                        //(0x10)Pointer to list
                        //(0x14)Pointer to skeleton joints (0x40 structure)
                        //(0x18)Pointer to skeleton somethings (0x16 structure)
                        //(0x1C)Pointer to left arm animations (Ratchet)
                        //(0x20)null
                        model.size = BAToFloat(headBlock, 0x24);
                        uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                        uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                        uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                        uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                        uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                        uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                        model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                        //(0x1A)count
                        //(0x1C)count
                        //(0x1E)null


                        //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                        model.animPointer = new List <uint>();
                        for (uint i = 0; i < model.animationsCount; i++)
                        {
                            model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                        }

                        uint   texElemSize = 0x10;
                        byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                        model.textureConfig = new List <RatchetTexture_Model>();
                        model.faceCount     = 0;
                        for (uint t = 0; t < texCount; t++)
                        {
                            RatchetTexture_Model modTex = new RatchetTexture_Model();
                            modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                            modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                            modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                            model.textureConfig.Add(modTex);
                            model.faceCount += modTex.size;
                        }


                        //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                        uint   vertElemSize = 0x28;
                        uint   vertBuffSize = model.vertexCount * vertElemSize;
                        byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                        model.vertBuff = new List <float>();
                        for (uint i = 0; i < model.vertexCount; i++)
                        {
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                        }

                        //Flip endianness of index array
                        byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                        model.indiceBuff = new List <ushort>();
                        for (uint i = 0; i < model.faceCount; i++)
                        {
                            model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                        }
                    }
                }
                DataStore.spawnableModels.Add(model);
            }
            #endregion

            //Load UYA Level Models
            #region Level Models
            uint   levelElemSize = 0x40;
            byte[] levelBlock    = ReadBlock(fs, engineHeader.levelModelsPointer, engineHeader.levelModelsCount * levelElemSize);

            for (uint x = 0; x < engineHeader.levelModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Level;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(levelBlock, (x * levelElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(levelBlock, (x * levelElemSize) + 0x14);
                uint indicePointer = BAToUInt32(levelBlock, (x * levelElemSize) + 0x18);
                uint texPointer    = BAToUInt32(levelBlock, (x * levelElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(levelBlock, (x * levelElemSize) + 0x24);
                ushort texCount = BAToUInt16(levelBlock, (x * levelElemSize) + 0x28);
                model.modelID = BAToShort(levelBlock, (x * levelElemSize) + 0x30);

                model.offset    = (uint)(x * 0x40) + engineHeader.levelModelsPointer;
                model.modelType = ModelType.Level;

                uint   texElemSize = 0x18;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x0C);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.levelModels.Add(model);
            }
            #endregion

            //Load UYA Scenery Models
            #region Scenery Models
            uint   sceneElemSize = 0x40;
            byte[] sceneBlock    = ReadBlock(fs, engineHeader.sceneryModelsPointer, engineHeader.sceneryModelsCount * sceneElemSize);

            for (uint x = 0; x < engineHeader.sceneryModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Scenery;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x14);
                uint indicePointer = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x18);
                uint texPointer    = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x24);
                ushort texCount = BAToUInt16(sceneBlock, (x * sceneElemSize) + 0x28);
                model.modelID = BAToShort(sceneBlock, (x * sceneElemSize) + 0x30);

                uint   texElemSize = 0x10;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.sceneryModels.Add(model);
                //Console.WriteLine("Scenery Model Added: 0x" + model.modelID.ToString("X4"));
            }
            #endregion

            //Load Terrain
            #region Terrain
            {
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = engineHeader.terrainPointer;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(fs, engineHeader.terrainPointer, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(fs, headPointer, headCount * terrainElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)    //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(fs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID          = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start       = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size        = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;
                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);
                                model.textureConfig.Add(tex);
                            }

                            byte[] vertBlock = ReadBlock(fs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(fs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(fs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv

                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);     //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);     //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);     //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);     //color a
                            }

                            byte[] indiceBuff = ReadBlock(fs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }
                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount      = vertCount;
                model.faceCount        = prevFaceCount;
                DataStore.terrainModel = model;
            }
            #endregion

            //Load Level Objects
            #region Level objects
            byte[] levelObjectBlock = ReadBlock(fs, engineHeader.levelObjectPointer, engineHeader.levelObjectCount * 0x70);
            DataStore.levelObjects = new List <LevelObject>();
            for (uint i = 0; i < engineHeader.levelObjectCount; i++)
            {
                LevelObject levObj = new LevelObject(levelObjectBlock, i);
                DataStore.levelObjects.Add(levObj);
            }
            #endregion

            //Load Scenery Objects
            #region Scenery objects
            byte[] sceneryObjectBlock = ReadBlock(fs, engineHeader.sceneryObjectsPointer, engineHeader.sceneryObjectsCount * 0x70);
            DataStore.sceneryObjects = new List <LevelObject>();
            for (uint i = 0; i < engineHeader.sceneryObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(sceneryObjectBlock, i);
                DataStore.sceneryObjects.Add(levObj);
            }
            #endregion

            //Load Textures
            #region Textures
            RatchetTexture_General texture = new RatchetTexture_General();
            for (int x = 0; x < engineHeader.UYATextureCount; x++)
            {
                texture.texHeader = ReadBlock(fs, engineHeader.texturesPointer + (uint)(0x24 * x), 0x24);
                uint nextTexturePointer    = x < engineHeader.UYATextureCount - 1 ? ReadUInt32(ReadBlock(fs, engineHeader.texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
                texture.ID      = x;
                texture.width   = BAToShort(texture.texHeader, 0x18);
                texture.height  = BAToShort(texture.texHeader, 0x1A);
                texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                texture.reverseRGB = false;
                DataStore.textures.Add(texture);
                //Console.WriteLine("Texture : " + x + " Width: " + texture.width + " Height: " + texture.height);
            }
            #endregion



            //Terrain Collision
            #region Terrain Collision
            float div = 1024f;

            uint collisionVertCount = 0;

            uint   collisionStart  = engineHeader.collisionPointer + BAToUInt32(ReadBlock(fs, engineHeader.collisionPointer + 0x00, 4), 0);
            uint   collisionLength = engineHeader.collisionPointer + collisionStart + BAToUInt32(ReadBlock(fs, engineHeader.collisionPointer + 0x04, 4), 0);
            byte[] collision       = ReadBlock(fs, collisionStart, collisionLength);

            List <float> collisionVertexBuff = new List <float>();
            List <uint>  collisionIndiceBuff = new List <uint>();

            ushort zShift = BAToUInt16(collision, 0);
            ushort zCount = BAToUInt16(collision, 2);

            for (uint z = 0; z < zCount; z++)
            {
                uint yOffset = BAToUInt32(collision, (z * 4) + 0x04);
                if (yOffset != 0)
                {
                    ushort yShift = BAToUInt16(collision, yOffset + 0);
                    ushort yCount = BAToUInt16(collision, yOffset + 2);
                    for (uint y = 0; y < yCount; y++)
                    {
                        uint xOffset = BAToUInt32(collision, yOffset + (y * 4) + 0x04);
                        if (xOffset != 0)
                        {
                            ushort xShift = BAToUInt16(collision, xOffset + 0);
                            ushort xCount = BAToUInt16(collision, xOffset + 2);
                            for (uint x = 0; x < xCount; x++)
                            {
                                uint   vOffset     = BAToUInt32(collision, xOffset + (x * 4) + 4);
                                ushort faceCount   = BAToUInt16(collision, vOffset);
                                byte   vertexCount = collision[vOffset + 2];
                                byte   rCount      = collision[vOffset + 3];

                                if (vOffset != 0)
                                {
                                    byte[] collisionType = new byte[vertexCount];
                                    //Console.WriteLine("Facecount: " + faceCount.ToString("X2") + "VertCount: " + vertexCount.ToString("X2"));
                                    for (uint f = 0; f < faceCount; f++)
                                    {
                                        uint   fOffset = vOffset + ((uint)12 * vertexCount) + 4 + (f * 4);
                                        byte[] fArray  = new byte[4];
                                        Array.Copy(collision, fOffset, fArray, 0, 4);

                                        collisionType[fArray[0]] = fArray[3];
                                        collisionType[fArray[1]] = fArray[3];
                                        collisionType[fArray[2]] = fArray[3];

                                        uint f1 = collisionVertCount + fArray[0];
                                        uint f2 = collisionVertCount + fArray[1];
                                        uint f3 = collisionVertCount + fArray[2];
                                        collisionIndiceBuff.Add(f1);
                                        collisionIndiceBuff.Add(f2);
                                        collisionIndiceBuff.Add(f3);
                                        if (f < rCount)
                                        {
                                            uint rOffset = vOffset + 4 + (uint)(12 * vertexCount) + (uint)(4 * faceCount) + f;
                                            uint f4      = collisionVertCount + collision[rOffset];
                                            collisionIndiceBuff.Add(f1);
                                            collisionIndiceBuff.Add(f3);
                                            collisionIndiceBuff.Add(f4);
                                            collisionType[collision[rOffset]] = fArray[3];
                                        }
                                    }

                                    for (uint v = 0; v < vertexCount; v++)
                                    {
                                        uint  pOffset = vOffset + (12 * v) + 4;
                                        float pX      = BAToFloat(collision, pOffset + 0) / div + 4 * (xShift + x + 0.5f);
                                        float pY      = BAToFloat(collision, pOffset + 4) / div + 4 * (yShift + y + 0.5f);
                                        float pZ      = BAToFloat(collision, pOffset + 8) / div + 4 * (zShift + z + 0.5f);
                                        collisionVertexBuff.Add(pX);
                                        collisionVertexBuff.Add(pY);
                                        collisionVertexBuff.Add(pZ);
                                        switch (collisionType[v])
                                        {
                                        case 0x1F:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x08:
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0C:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x01:
                                            //This
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x3F:
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0B:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x0A:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.5f);
                                            break;

                                        case 0x28:
                                            collisionVertexBuff.Add(0.25f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x5F:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.25f);
                                            collisionVertexBuff.Add(0.0f);
                                            break;

                                        case 0x09:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.25f);
                                            break;

                                        case 0x00:
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(0.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            break;

                                        case 0x6C:
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.5f);
                                            collisionVertexBuff.Add(0.5f);
                                            break;

                                        default:
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            collisionVertexBuff.Add(1.0f);
                                            break;
                                        }
                                        collisionVertCount++;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            DataStore.collVertBuff = collisionVertexBuff;
            DataStore.collIndBuff  = collisionIndiceBuff;
            #endregion

            #region Chunks
            List <int> chunkIds = new List <int>();
            for (int chunkIndex = 0; chunkIndex < 5; chunkIndex++)
            {
                if (File.Exists(path + "/chunk" + chunkIndex + ".ps3"))
                {
                    chunkIds.Add(chunkIndex);
                }
            }

            foreach (int chunkId in chunkIds)
            {
                FileStream cfs = File.OpenRead(path + "/chunk" + chunkId + ".ps3");
                Console.WriteLine("Loading chunk " + chunkId);
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = 0x10;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(cfs, 0x10, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(cfs, headPointer, headCount * terrainElemSize);

                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)   //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(cfs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID    = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size  = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;

                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);

                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(cfs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(cfs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(cfs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }



                            byte[] indiceBuff = ReadBlock(cfs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            //Console.WriteLine(localFaceCount.ToString("X8"));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }

                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount = vertCount;
                model.faceCount   = prevFaceCount;
                DataStore.chunks.Add(model);
            }
            #endregion

            //TODO: textureConfig - Menus

            //TODO: textureConfig - 2D GFX

            //TODO: Sprites


            //Load the remaining unknown or unhandled data
            #region Remaining Data

            /*
             * DataStore.mapRenderDefintions = getSection(fs, 0x04);
             * DataStore.Ptr_08 = getSection(fs, 0x08);
             * DataStore.Ptr_0C = getSection(fs, 0x0C);
             * DataStore.skyBox = getSection(fs, 0x10);
             * DataStore.collisionMap = getSection(fs, 0x14);
             * DataStore.campaignPlayerAnimations = getSection(fs, 0x18);
             * DataStore.Ptr_40 = getSection(fs, 0x40);
             * DataStore.Ptr_44 = getSection(fs, 0x44);
             * DataStore.soundsConfig = getSection(fs, 0x48);
             * DataStore.Ptr_4C = getSection(fs, 0x4C);
             * DataStore.Ptr_50 = getSection(fs, 0x50);
             * DataStore.lighting = getSection(fs, 0x5C);
             * DataStore.lightingConfig = getSection(fs, 0x64);
             * DataStore.textureConfigMenu = getSection(fs, 0x68);
             * DataStore.textureConfig2DGFX = getSection(fs, 0x70);
             * DataStore.spriteDef = getSection(fs, 0x74);
             */
            #endregion

            #region raw Data //need to properly handle these eventually
            //DataStore.terrainModel.rawData = getSection(fs, 0x3C);
            //rawLevelModelBlock = getSection(fs, 0x1C);
            //rawSceneryModelBlock = getSection(fs, 0x2C);
            #endregion

            fs.Close();

            Console.WriteLine("Engine data loaded with new engine parser for UYA.");
        }
Beispiel #5
0
        public static void parseMap(string path, string fileName)
        {
            FileStream fs = File.OpenRead(path + "/" + fileName);

            FileStream vfs = null;

            if (File.Exists(path + "/vram.ps3"))
            {
                vfs = File.OpenRead(path + "/vram.ps3");
            }

            FileStream gpf = null;

            if (File.Exists(path + "/gameplay_ntsc"))
            {
                gpf = File.OpenRead(path + "/gameplay_ntsc");
            }

            loadMobyPvarMap();


            uint racNum = 4;

            #region GameplayHeader
            GameplayHeader gameplayHeader = new GameplayHeader(gpf, racNum);
            DataStore.gameplayHeader = gameplayHeader;

            #endregion

            #region pVars
            List <byte[]> pVars;
            uint          numpVars;
            byte[]        pVarHeadBlock;
            uint          pVarSectionLength;
            byte[]        pVarBlock;
            switch (racNum)
            {
            case 4:
                pVars             = new List <byte[]>();
                numpVars          = (gameplayHeader.pVarPointer - gameplayHeader.pVarListPointer) / 8;
                pVarHeadBlock     = ReadBlock(gpf, gameplayHeader.pVarListPointer, numpVars * 8);
                pVarSectionLength = 0;
                for (uint i = 0; i < numpVars; i++)
                {
                    pVarSectionLength += BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                }
                pVarBlock = ReadBlock(gpf, gameplayHeader.pVarPointer, pVarSectionLength);
                for (uint i = 0; i < numpVars; i++)
                {
                    uint   mobpVarsStart = BAToUInt32(pVarHeadBlock, (i * 8));
                    uint   mobpVarsCount = BAToUInt32(pVarHeadBlock, (i * 8) + 0x04);
                    byte[] mobpVars      = new byte[mobpVarsCount];
                    mobpVars = getBytes(pVarBlock, (int)mobpVarsStart, (int)mobpVarsCount);
                    pVars.Add(mobpVars);
                }
                DataStore.pVarList = pVars;
                break;
            }
            #endregion pVars

            #region Mobies

            uint   mobyCount = BAToUInt32(ReadBlock(gpf, gameplayHeader.mobyPointer, 4), 0);
            byte[] mobyBlock = ReadBlock(gpf, gameplayHeader.mobyPointer + 0x10, mobyCount * gameplayHeader.mobyElemSize);

            for (uint i = 0; i < mobyCount; i++)
            {
                RatchetMoby mob = new RatchetMoby(racNum, mobyBlock, i);
                DataStore.mobs.Add(mob);
            }
            #endregion

            DataStore.splines = new List <Spline>();

            uint   splineCount       = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer, 4), 0);
            uint   splineOffset      = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 4, 4), 0);
            uint   splineSectionSize = BAToUInt32(ReadBlock(gpf, gameplayHeader.splinePointer + 8, 4), 0);
            byte[] splineHeadBlock   = ReadBlock(gpf, gameplayHeader.splinePointer + 0x10, splineCount * 4);
            byte[] splineBlock       = ReadBlock(gpf, gameplayHeader.splinePointer + splineOffset, splineSectionSize);
            for (uint i = 0; i < splineCount; i++)
            {
                uint offset = BAToUInt32(splineHeadBlock, (i * 4));
                DataStore.splines.Add(new Spline(splineBlock, offset));
            }


            #region EngineHeader
            byte[] engineHeader = ReadBlock(fs, 0, 0x90);

            //Data from header
            uint spawnablesPointer = BAToUInt32(engineHeader, 0x00);
            //(0x04)Map render definitions
            //(0x08)null
            //(0x0C)null
            //(0x14)Skybox
            //(0x18)Collisionmap
            uint levelModelsPointer            = BAToUInt32(engineHeader, 0x20);
            uint levelModelsCount              = BAToUInt32(engineHeader, 0x24);
            uint levelModelsPlacementPointer   = BAToUInt32(engineHeader, 0x28);
            uint levelObjectsCount             = BAToUInt32(engineHeader, 0x2C);
            uint sceneryModelsPointer          = BAToUInt32(engineHeader, 0x34);
            uint sceneryModelsCount            = BAToUInt32(engineHeader, 0x38);
            uint sceneryModelsPlacementPointer = BAToUInt32(engineHeader, 0x3C);
            uint sceneryObjectsCount           = BAToUInt32(engineHeader, 0x40);
            uint terrainPointer = BAToUInt32(engineHeader, 0x48);
            //(0x44) ??
            //(0x54)Sound config (Menus + terrain)
            uint texturesPointer = BAToUInt32(engineHeader, 0x60);
            uint textureCount    = BAToUInt32(engineHeader, 0x64);
            //(0x68)Lighting pointer
            uint lightingLevel          = BAToUInt32(engineHeader, 0x6C);
            uint textureConfigMenuCount = BAToUInt32(engineHeader, 0x78);
            //(0x7C)textureConfig2DGFX
            //(0x80)Sprite def
            //(0x88) sound config (spawnables + everything else)

            EngineHeader engHead = new EngineHeader(fs, 4);
            DataStore.engineHeader = engHead;
            #endregion

            //Load DL Spawnable Models
            #region Spawnables
            uint   spawnablesCount = BAToUInt32(ReadBlock(fs, spawnablesPointer, 4), 0);
            byte[] idBlock         = ReadBlock(fs, spawnablesPointer + 4, spawnablesCount * 8);

            for (int x = 0; x < spawnablesCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Spawnable;

                model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                if (model.offset != 0)
                {
                    uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                    if (modelHeadSize > 0)
                    {
                        byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                        uint   objectPtr = BAToUInt32(headBlock, 0);
                        model.animationsCount = headBlock[0x0C];
                        //(0x04)null
                        //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                        //(0x0c)[animation count][unknown][unknown][unknown]
                        //(0x10)Pointer to list
                        //(0x14)Pointer to skeleton joints (0x40 structure)
                        //(0x18)Pointer to skeleton somethings (0x16 structure)
                        //(0x1C)Pointer to left arm animations (Ratchet)
                        //(0x20)null
                        model.size = BAToFloat(headBlock, 0x24);
                        uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                        uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                        uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                        uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                        uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                        uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                        model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                        //(0x1A)count
                        //(0x1C)count
                        //(0x1E)null


                        //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                        model.animPointer = new List <uint>();
                        for (uint i = 0; i < model.animationsCount; i++)
                        {
                            model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                        }

                        uint   texElemSize = 0x10;
                        byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                        model.textureConfig = new List <RatchetTexture_Model>();
                        model.faceCount     = 0;
                        for (uint t = 0; t < texCount; t++)
                        {
                            RatchetTexture_Model modTex = new RatchetTexture_Model();
                            modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                            modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                            modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                            model.textureConfig.Add(modTex);
                            model.faceCount += modTex.size;
                        }


                        //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                        uint   vertElemSize = 0x28;
                        uint   vertBuffSize = model.vertexCount * vertElemSize;
                        byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                        model.vertBuff = new List <float>();
                        for (uint i = 0; i < model.vertexCount; i++)
                        {
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                            model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                        }

                        //Flip endianness of index array
                        byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                        model.indiceBuff = new List <ushort>();
                        for (uint i = 0; i < model.faceCount; i++)
                        {
                            model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                        }
                    }
                }
                DataStore.spawnableModels.Add(model);
            }
            #endregion

            //Load DL Level Models
            #region Level Models
            uint   levelElemSize = 0x40;
            byte[] levelBlock    = ReadBlock(fs, levelModelsPointer, levelModelsCount * levelElemSize);

            for (uint x = 0; x < levelModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Level;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(levelBlock, (x * levelElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(levelBlock, (x * levelElemSize) + 0x14);
                uint indicePointer = BAToUInt32(levelBlock, (x * levelElemSize) + 0x18);
                uint texPointer    = BAToUInt32(levelBlock, (x * levelElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(levelBlock, (x * levelElemSize) + 0x24);
                ushort texCount = BAToUInt16(levelBlock, (x * levelElemSize) + 0x28);
                model.modelID = BAToShort(levelBlock, (x * levelElemSize) + 0x30);

                model.offset    = (uint)(x * 0x40) + levelModelsPointer;
                model.modelType = ModelType.Level;

                uint   texElemSize = 0x18;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x0C);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.levelModels.Add(model);
            }
            #endregion

            //Load DL Scenery Models
            #region Scenery Models
            uint   sceneElemSize = 0x40;
            byte[] sceneBlock    = ReadBlock(fs, sceneryModelsPointer, sceneryModelsCount * sceneElemSize);

            for (uint x = 0; x < sceneryModelsCount; x++)
            {
                RatchetModel_General model = new RatchetModel_General();
                model.modelType = ModelType.Scenery;
                model.size      = 0.5f;

                uint vertPointer   = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x10);
                uint UVPointer     = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x14);
                uint indicePointer = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x18);
                uint texPointer    = BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x1C);
                model.vertexCount = (ushort)BAToUInt32(sceneBlock, (x * sceneElemSize) + 0x24);
                ushort texCount = BAToUInt16(sceneBlock, (x * sceneElemSize) + 0x28);
                model.modelID = BAToShort(sceneBlock, (x * sceneElemSize) + 0x30);

                uint   texElemSize = 0x10;
                byte[] texBlock    = ReadBlock(fs, texPointer, texCount * texElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.faceCount     = 0;
                for (uint t = 0; t < texCount; t++)
                {
                    RatchetTexture_Model dlt = new RatchetTexture_Model();
                    dlt.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x00);
                    dlt.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                    dlt.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                    model.textureConfig.Add(dlt);
                    model.faceCount += dlt.size;
                }

                //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                uint   vertElemSize = 0x18;
                uint   vertBuffSize = model.vertexCount * vertElemSize;
                byte[] vertBlock    = ReadBlock(fs, vertPointer, vertBuffSize);

                uint   UVElemsize = 0x08;
                uint   UVBuffSize = model.vertexCount * UVElemsize;
                byte[] UVBlock    = ReadBlock(fs, UVPointer, UVBuffSize);


                model.vertBuff = new List <float>();
                for (uint i = 0; i < model.vertexCount; i++)
                {
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00)); //vertx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04)); //verty
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08)); //vertz
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C)); //normx
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10)); //normy
                    model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14)); //normz

                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x00));     //UVu
                    model.vertBuff.Add(BAToFloat(UVBlock, (i * UVElemsize) + 0x04));     //UVv
                }

                //Flip endianness of index array
                byte[] indiceBuff = ReadBlock(fs, indicePointer, model.faceCount * sizeof(ushort));
                model.indiceBuff = new List <ushort>();
                for (uint i = 0; i < model.faceCount; i++)
                {
                    model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                }

                DataStore.sceneryModels.Add(model);
                //Console.WriteLine("Scenery Model Added: 0x" + model.modelID.ToString("X4"));
            }
            #endregion

            //Load Terrain
            #region Terrain
            {
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = terrainPointer;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(fs, terrainPointer, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(fs, headPointer, headCount * terrainElemSize);
                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)    //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(fs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID          = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start       = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size        = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;
                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);
                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(fs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(fs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(fs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }

                            byte[] indiceBuff = ReadBlock(fs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }
                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount      = vertCount;
                model.faceCount        = prevFaceCount;
                DataStore.terrainModel = model;
            }
            #endregion

            #region Chunks
            List <int> chunkIds = new List <int>();
            for (int chunkIndex = 0; chunkIndex < 5; chunkIndex++)
            {
                if (File.Exists(path + "/chunk" + chunkIndex + ".ps3"))
                {
                    chunkIds.Add(chunkIndex);
                }
            }

            foreach (int chunkId in chunkIds)
            {
                FileStream cfs = File.OpenRead(path + "/chunk" + chunkId + ".ps3");
                Console.WriteLine("Loading chunk " + chunkId);
                uint terrainElemSize = 0x30;
                uint texElemSize     = 0x10;
                uint vertElemSize    = 0x1c;
                uint UVElemSize      = 0x08;
                uint ColorElemSize   = 0x04;

                RatchetModel_Terrain model = new RatchetModel_Terrain();
                model.offset    = 0x10;
                model.modelID   = 1111;
                model.modelType = ModelType.Terrain;
                byte[] terrainHeadBlock = ReadBlock(cfs, 0x10, 0x60);

                uint   headPointer = BAToUInt32(terrainHeadBlock, 0x0);
                ushort headCount   = BAToUInt16(terrainHeadBlock, 0x06);

                byte[] terrainBlock = ReadBlock(cfs, headPointer, headCount * terrainElemSize);

                model.textureConfig = new List <RatchetTexture_Model>();
                model.vertBuff      = new List <float>();
                model.indiceBuff    = new List <uint>();
                uint vertCount         = 0;
                uint prevVertCount     = 0;
                uint prevFaceCount     = 0;
                uint prevHeadCount     = 0;
                uint prevPrevFaceCount = 0;

                for (uint i = 0; i < 4; i++)   //I have yet to see any level have more than two of these, but the header theoretically has space for 4
                {
                    uint vertPointer   = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x08);
                    uint colPointer    = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x18);
                    uint UVPointer     = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x28);
                    uint indicePointer = BAToUInt32(terrainHeadBlock, (i * sizeof(uint)) + 0x38);

                    prevFaceCount = 0;
                    if (vertPointer != 0 && UVPointer != 0 && indicePointer != 0)    //Check that there's data at the pointers
                    {
                        //Loop throught the heads, and stop when the overflow counter increases
                        for (uint ii = prevHeadCount; ii < headCount && i == BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x22); ii++)
                        {
                            uint   localFaceCount = 0;
                            uint   texPointer     = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x10);
                            uint   texCount       = BAToUInt32(terrainBlock, (ii * terrainElemSize) + 0x14);
                            ushort vertStart      = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x18);
                            ushort headVertCount  = BAToUInt16(terrainBlock, (ii * terrainElemSize) + 0x1A);
                            vertCount += headVertCount;

                            byte[] texBlock = ReadBlock(cfs, texPointer, texElemSize * texCount);
                            for (uint iii = 0; iii < texCount; iii++)
                            {
                                RatchetTexture_Model tex = new RatchetTexture_Model();
                                tex.ID    = BAToUInt32(texBlock, (iii * texElemSize) + 0x00);
                                tex.start = BAToUInt32(texBlock, (iii * texElemSize) + 0x04) + prevPrevFaceCount;
                                tex.size  = BAToUInt32(texBlock, (iii * texElemSize) + 0x08) + prevPrevFaceCount;

                                localFaceCount += BAToUInt32(texBlock, (iii * texElemSize) + 0x08);

                                model.textureConfig.Add(tex);
                            }


                            byte[] vertBlock = ReadBlock(cfs, vertPointer + vertStart * vertElemSize, headVertCount * vertElemSize);
                            byte[] colBlock  = ReadBlock(cfs, colPointer + vertStart * ColorElemSize, headVertCount * ColorElemSize);
                            byte[] UVBlock   = ReadBlock(cfs, UVPointer + vertStart * UVElemSize, headVertCount * UVElemSize);

                            for (uint iii = 0; iii < headVertCount; iii++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x00)); //vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x04)); //verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x08)); //vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x0C)); //normx
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x10)); //normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (iii * vertElemSize) + 0x14)); //normz

                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x00));     //UVu
                                model.vertBuff.Add(BAToFloat(UVBlock, (iii * UVElemSize) + 0x04));     //UVv


                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x00] / 255f);    //color r
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x01] / 255f);    //color g
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x02] / 255f);    //color b
                                model.vertBuff.Add(colBlock[(iii * ColorElemSize) + 0x03] / 255f);    //color a
                            }



                            byte[] indiceBuff = ReadBlock(cfs, indicePointer + prevFaceCount * sizeof(ushort), localFaceCount * sizeof(ushort));
                            //Console.WriteLine(localFaceCount.ToString("X8"));
                            for (uint iii = 0; iii < localFaceCount; iii++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, iii * sizeof(ushort)) + prevVertCount);
                            }

                            prevFaceCount += localFaceCount;
                            prevHeadCount  = ii + 1;
                        }
                        prevVertCount     = vertCount;
                        prevPrevFaceCount = prevFaceCount;
                    }
                }
                model.vertexCount = vertCount;
                model.faceCount   = prevFaceCount;
                DataStore.chunks.Add(model);
            }
            #endregion


            //Load Level Model Placement
            byte[] levelObjectBlock = ReadBlock(fs, levelModelsPlacementPointer, levelObjectsCount * 0x70);
            DataStore.levelObjects = new List <LevelObject>();
            for (uint i = 0; i < levelObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(levelObjectBlock, i);
                DataStore.levelObjects.Add(levObj);
            }

            //Load Scenery Model Placement
            byte[] sceneryObjectBlock = ReadBlock(fs, sceneryModelsPlacementPointer, sceneryObjectsCount * 0x70);
            DataStore.sceneryObjects = new List <LevelObject>();
            for (uint i = 0; i < sceneryObjectsCount; i++)
            {
                LevelObject levObj = new LevelObject(sceneryObjectBlock, i);
                DataStore.sceneryObjects.Add(levObj);
            }

            /*
             * //Load Level Model Placement
             #region Level Model Placement
             * for (int x = 0; x < UYALevelObjectsCount; x++)
             * {
             *  UYALevelObjectConfig levelObject = new UYALevelObjectConfig();
             *  byte[] objectBlock = ReadBlock(fs, levelModelsPlacementPointer + (uint)(0x70 * x), 0x70);
             *
             *  levelObject.v1 = BAToQuaternion(objectBlock, 0x00);
             *  levelObject.v2 = BAToQuaternion(objectBlock, 0x10);
             *  levelObject.v3 = BAToQuaternion(objectBlock, 0x20);
             *  levelObject.off = BAToQuaternion(objectBlock, 0x30);
             *  levelObject.size = BAToFloat(objectBlock, 0x3C);
             *  levelObject.off_40 = BAToUInt32(objectBlock, 0x40);
             *  levelObject.off_44 = BAToUInt32(objectBlock, 0x44);
             *  levelObject.off_48 = BAToUInt32(objectBlock, 0x48);
             *  levelObject.off_4C = BAToUInt32(objectBlock, 0x4C);
             *  levelObject.ID = (ushort)BAToShort(objectBlock, 0x52);
             *  levelObject.off_54 = BAToUInt32(objectBlock, 0x54);
             *  levelObject.off_58 = BAToUInt32(objectBlock, 0x58);
             *  levelObject.off_5C = BAToUInt32(objectBlock, 0x5C);
             *  levelObject.ptr_60 = BAToUInt32(objectBlock, 0x60);
             *  levelObject.off_64 = BAToUInt32(objectBlock, 0x64);
             *  levelObject.off_68 = BAToUInt32(objectBlock, 0x68);
             *  levelObject.off_6C = BAToUInt32(objectBlock, 0x6C);
             *  if (x + 1 < UYALevelObjectsCount)
             *      levelObject.unknown_data_block = ReadBlock(fs, levelObject.ptr_60, (BAToUInt32(ReadBlock(fs, levelModelsPlacementPointer + (uint)(0x70 * (x + 1)) + 0x60, 4), 0x00) - levelObject.ptr_60));
             *  else
             *      levelObject.unknown_data_block = ReadBlock(fs, levelObject.ptr_60, FindNextLargest(engineHeader, 0x24) - levelObject.ptr_60);
             *  UYALevelObjects.Add(levelObject);
             * }
             #endregion
             *
             * //Load Scenery Models Placement
             #region Scenery Model Placement
             * for (int x = 0; x < UYASceneryObjectsCount; x++)
             * {
             *  UYASceneryObjectConfig sceneryObject = new UYASceneryObjectConfig();
             *  byte[] objectBlock = ReadBlock(fs, sceneryModelsPlacementPointer + (uint)(0x70 * x), 0x70);
             *
             *  sceneryObject.v1 = BAToQuaternion(objectBlock, 0x00);
             *  sceneryObject.v2 = BAToQuaternion(objectBlock, 0x10);
             *  sceneryObject.v3 = BAToQuaternion(objectBlock, 0x20);
             *  sceneryObject.off = BAToQuaternion(objectBlock, 0x30);
             *  sceneryObject.size = BAToFloat(objectBlock, 0x3C);
             *  sceneryObject.off_40 = BAToUInt32(objectBlock, 0x40);
             *  sceneryObject.off_44 = BAToUInt32(objectBlock, 0x44);
             *  sceneryObject.off_48 = BAToUInt32(objectBlock, 0x48);
             *  sceneryObject.off_4C = BAToUInt32(objectBlock, 0x4C);
             *  sceneryObject.ID = (ushort)BAToShort(objectBlock, 0x52);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x54);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x58);
             *  sceneryObject.off_54 = BAToUInt32(objectBlock, 0x5C);
             *  sceneryObject.off_60 = BAToUInt32(objectBlock, 0x60);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x64);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x68);
             *  sceneryObject.off_64 = BAToUInt32(objectBlock, 0x6C);
             *
             *  UYASceneryObjects.Add(sceneryObject);
             * }
             #endregion
             */
            //Load Textures
            #region Textures
            RatchetTexture_General texture = new RatchetTexture_General();
            for (int x = 0; x < textureCount; x++)
            {
                texture.texHeader = ReadBlock(fs, texturesPointer + (uint)(0x24 * x), 0x24);
                uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
                texture.ID      = x;
                texture.width   = BAToShort(texture.texHeader, 0x18);
                texture.height  = BAToShort(texture.texHeader, 0x1A);
                texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                texture.reverseRGB = false;
                DataStore.textures.Add(texture);
                //Console.WriteLine("Texture : " + x + " Width: " + texture.width + " Height: " + texture.height);
            }
            #endregion

            //TODO: textureConfig - Menus

            //TODO: textureConfig - 2D GFX

            //TODO: Sprites


            //Load the remaining unknown or unhandled data
            #region Remaining Data

            DataStore.mapRenderDefintions = getSection(fs, 0x04);
            DataStore.Ptr_08             = getSection(fs, 0x08);
            DataStore.Ptr_0C             = getSection(fs, 0x0C);
            DataStore.skyBox             = getSection(fs, 0x14);
            DataStore.collisionMap       = getSection(fs, 0x18);
            DataStore.Ptr_44             = getSection(fs, 0x44);
            DataStore.soundsConfig       = getSection(fs, 0x54);
            DataStore.Ptr_4C             = getSection(fs, 0x4C);
            DataStore.Ptr_50             = getSection(fs, 0x50);
            DataStore.lighting           = getSection(fs, 0x68);
            DataStore.lightingConfig     = getSection(fs, 0x6C);
            DataStore.textureConfigMenu  = getSection(fs, 0x74);
            DataStore.textureConfig2DGFX = getSection(fs, 0x7C);
            DataStore.spriteDef          = getSection(fs, 0x80);

            #endregion

            #region raw Data //need to properly handle these eventually
            DataStore.terrainModel.rawData = getSection(fs, 0x48);
            //rawLevelModelBlock = getSection(fs, 0x1C);
            //rawSceneryModelBlock = getSection(fs, 0x2C);
            #endregion

            #region Missions
            MissionParser.parseMissions(path);
            #endregion

            fs.Close();
            gpf.Close();


            Console.WriteLine("Engine data loaded with new engine parser for DL.");
        }
Beispiel #6
0
        public static void parseMissions(string path)
        {
            List <int> missionIds = new List <int>();

            //Because its unlikely there will be more than 50 missions in a map
            //We use a list because some missions might be missing/cut so we cant simply break the loop
            for (int fileIndex = 0; fileIndex < 50; fileIndex++)
            {
                if (File.Exists(path + "/gameplay_mission_classes[" + fileIndex + "].ps3"))
                {
                    missionIds.Add(fileIndex);
                }
            }


            foreach (int missionIndex in missionIds)
            {
                RatchetMission mission = new RatchetMission();
                FileStream     fs      = File.OpenRead(path + "/gameplay_mission_classes[" + missionIndex + "].ps3");
                FileStream     vfs     = File.OpenRead(path + "/gameplay_mission_classes[" + missionIndex + "].vram");
                Console.WriteLine("Loading mission " + missionIndex);

                byte[] header          = ReadBlock(fs, 0, 0x0c);
                uint   spawnablesCount = BAToUInt32(ReadBlock(fs, 0x00, 4), 0);

                byte[] idBlock = ReadBlock(fs, 0x10, spawnablesCount * 8);

                #region Spawnables
                mission.spawnableModels = new List <RatchetModel_General>();
                for (int x = 0; x < spawnablesCount; x++)
                {
                    RatchetModel_General model = new RatchetModel_General();
                    model.modelType = ModelType.Spawnable;

                    model.modelID = BAToShort(idBlock, (uint)(x * 8) + 2);
                    model.offset  = BAToUInt32(idBlock, (uint)(x * 8) + 4);

                    if (model.offset != 0)
                    {
                        uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);

                        if (modelHeadSize > 0)
                        {
                            byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                            uint   objectPtr = BAToUInt32(headBlock, 0);
                            model.animationsCount = headBlock[0x0C];
                            //(0x04)null
                            //(0x08)[count for 0x14 and 0x18][unknown][unknown][unknown]
                            //(0x0c)[animation count][unknown][unknown][unknown]
                            //(0x10)Pointer to list
                            //(0x14)Pointer to skeleton joints (0x40 structure)
                            //(0x18)Pointer to skeleton somethings (0x16 structure)
                            //(0x1C)Pointer to left arm animations (Ratchet)
                            //(0x20)null
                            model.size = BAToFloat(headBlock, 0x24);
                            uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                            uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                            uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                            uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                            uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                            uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                            model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                            //(0x1A)count
                            //(0x1C)count
                            //(0x1E)null


                            //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                            model.animPointer = new List <uint>();
                            for (uint i = 0; i < model.animationsCount; i++)
                            {
                                model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                            }

                            uint   texElemSize = 0x10;
                            byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                            model.textureConfig = new List <RatchetTexture_Model>();
                            model.faceCount     = 0;
                            for (uint t = 0; t < texCount; t++)
                            {
                                RatchetTexture_Model modTex = new RatchetTexture_Model();
                                modTex.ID    = BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                                modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                                modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                                model.textureConfig.Add(modTex);
                                model.faceCount += modTex.size;
                            }


                            //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                            uint   vertElemSize = 0x28;
                            uint   vertBuffSize = model.vertexCount * vertElemSize;
                            byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                            model.vertBuff = new List <float>();
                            for (uint i = 0; i < model.vertexCount; i++)
                            {
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                                model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                            }

                            //Flip endianness of index array
                            byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                            model.indiceBuff = new List <ushort>();
                            for (uint i = 0; i < model.faceCount; i++)
                            {
                                model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                            }
                        }
                    }
                    mission.spawnableModels.Add(model);
                }
                #endregion

                #region Textures
                int  textureCount    = (int)BAToUInt32(ReadBlock(fs, 0x04, 4), 0);
                uint texturesPointer = BAToUInt32(ReadBlock(fs, 0x08, 4), 0);
                mission.textures = new List <RatchetTexture_General>();
                RatchetTexture_General texture = new RatchetTexture_General();
                for (int x = 0; x < textureCount; x++)
                {
                    texture.texHeader = ReadBlock(fs, texturesPointer + (uint)(0x24 * x), 0x24);
                    uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturesPointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
                    uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
                    texture.ID      = x;
                    texture.width   = BAToShort(texture.texHeader, 0x18);
                    texture.height  = BAToShort(texture.texHeader, 0x1A);
                    texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

                    texture.reverseRGB = false;
                    mission.textures.Add(texture);
                }
                #endregion
                DataStore.missions.Add(mission);
                fs.Close();
            }
        }
        private void sceneryButton_Click(object sender, EventArgs e)
        {
            sceneryList    = new List <uint>();
            sceneryTexList = new List <uint>();
            foreach (LevelObject levObj in DataStore.sceneryObjects)
            {
                if (!sceneryList.Contains(levObj.modelID))
                {
                    objModel = DataStore.sceneryModels.Find(x => x.modelID == levObj.modelID);

                    if (objModel.vertBuff != null)
                    {
                        sceneryList.Add(levObj.modelID);
                    }
                }
            }
            int levCount = sceneryList.Count();

            sceneryVerts = new int[levCount];
            sceneryInds  = new int[levCount];

            GL.GenBuffers(levCount, sceneryVerts);
            GL.GenBuffers(levCount, sceneryInds);

            for (int i = 0; i < sceneryList.Count(); i++)
            {
                objModel = DataStore.sceneryModels.Find(x => x.modelID == sceneryList[i]);
                if (objModel.vertBuff != null)
                {
                    int     vertCnt = objModel.vertBuff.Count;
                    float[] vertArr = objModel.vertBuff.ToArray();
                    GL.BindBuffer(BufferTarget.ArrayBuffer, sceneryVerts[i]);
                    GL.BufferData(BufferTarget.ArrayBuffer, vertCnt * sizeof(float), vertArr, BufferUsageHint.StaticDraw);

                    int      indCnt = objModel.indiceBuff.Count;
                    UInt16[] indArr = objModel.indiceBuff.ToArray();
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, sceneryInds[i]);
                    GL.BufferData(BufferTarget.ElementArrayBuffer, indCnt * sizeof(UInt16), indArr, BufferUsageHint.StaticDraw);

                    foreach (RatchetTexture_Model tex in objModel.textureConfig)
                    {
                        if (!sceneryTexList.Contains(tex.ID))
                        {
                            sceneryTexList.Add(tex.ID);
                        }
                    }
                }
            }

            int texCount = sceneryTexList.Count;

            sceneryTexIDArr = new int[texCount];
            GL.GenTextures(texCount, sceneryTexIDArr);
            for (int ii = 0; ii < texCount; ii++)
            {
                Bitmap file = getTextureImage((int)sceneryTexList[ii]);

                if (file != null)
                {
                    GL.BindTexture(TextureTarget.Texture2D, sceneryTexIDArr[ii]);

                    BitmapData data = file.LockBits(new System.Drawing.Rectangle(0, 0, file.Width, file.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
                    GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.Rgba, data.Width, data.Height, 0, OpenTK.Graphics.OpenGL.PixelFormat.Bgra, PixelType.UnsignedByte, data.Scan0);
                    file.UnlockBits(data);

                    //The DDS files have built in mipmaps, should probably use those instead
                    GL.GenerateMipmap(GenerateMipmapTarget.Texture2D);
                }
                else
                {
                    Console.WriteLine("Error loading texture: File was null");
                }
            }
            sceneryCheck.Checked = true;
            sceneryReady         = true;
            glControl1.Invalidate();
        }
        private void glControl1_Paint(object sender, PaintEventArgs e)
        {
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
            GL.ClearColor(Color.SkyBlue);
            glControl1.MakeCurrent();
            GL.UseProgram(pgm2ID);

            GL.EnableVertexAttribArray(0);


            camX.Text = cPosition.X.ToString();
            camY.Text = cPosition.Y.ToString();
            camZ.Text = cPosition.Z.ToString();

            Matrix4 View      = Matrix4.LookAt(cPosition, cTarget, Vector3.UnitZ);
            Matrix4 worldView = View * projection;

            if (splineCheck.Checked)
            {
                GL.UniformMatrix4(MatrixID, false, ref worldView);
                foreach (Spline spline in DataStore.splines)
                {
                    spline.getVBO();
                    GL.DrawArrays(PrimitiveType.LineStrip, 0, spline.vertexBuffer.Length / 3);
                }
            }


            GL.EnableVertexAttribArray(1);

            if (modReady && mobyCheck.Checked == true)
            {
                foreach (RatchetMoby mob in DataStore.mobs)
                {
                    objModel = DataStore.spawnableModels.Find(x => x.modelID == mob.modelID);
                    int insx = mobList.IndexOf((uint)objModel.modelID);
                    if (insx != -1)
                    {
                        Matrix4 modTrans = Matrix4.CreateTranslation(mob.x, mob.y, mob.z);
                        Matrix4 modScale = Matrix4.CreateScale(objModel.size * mob.size);
                        Matrix4 xRot     = Matrix4.CreateRotationX(mob.rot1);
                        Matrix4 yRot     = Matrix4.CreateRotationY(mob.rot2);
                        Matrix4 zRot     = Matrix4.CreateRotationZ(mob.rot3);
                        Matrix4 modRot   = xRot * yRot * zRot;
                        mvp = modScale * modRot * modTrans * worldView;  //Has to be done in this order to work correctly
                        GL.UniformMatrix4(MatrixID, false, ref mvp);

                        GL.BindBuffer(BufferTarget.ArrayBuffer, mobVerts[insx]);
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, mobInds[insx]);

                        //Verts
                        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, 0);
                        //UV's
                        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 6);


                        //Bind textures one by one, applying it to the relevant vertices based on the index array
                        foreach (RatchetTexture_Model tex in objModel.textureConfig)
                        {
                            int indx = modTexList.IndexOf(tex.ID);
                            GL.BindTexture(TextureTarget.Texture2D, mobTexIDArr[indx]);

                            if (DataStore.selectedMoby == mob)
                            {
                                GL.Uniform4(pgmID_rcID, new Vector4(1, 1, 1, 1));
                                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                                GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedShort, (int)tex.start * sizeof(ushort));

                                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                            }
                            GL.Uniform4(pgmID_rcID, new Vector4(mob.r / 255f, mob.g / 255f, mob.b / 255f, 0.5f));
                            GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedShort, (int)tex.start * sizeof(ushort));
                        }
                    }
                }
            }
            if (levelReady && levelCheck.Checked == true)
            {
                foreach (LevelObject levObj in DataStore.levelObjects)
                {
                    objModel = DataStore.levelModels.Find(x => x.modelID == levObj.modelID);
                    int insx = levelList.IndexOf((uint)objModel.modelID);
                    if (insx != -1)
                    {
                        mvp = levObj.mat * worldView;  //Has to be done in this order to work correctly
                        GL.UniformMatrix4(MatrixID, false, ref mvp);

                        GL.BindBuffer(BufferTarget.ArrayBuffer, levelVerts[insx]);
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, levelInds[insx]);

                        //Verts
                        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, 0);
                        //UV's
                        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 6);


                        //Bind textures one by one, applying it to the relevant vertices based on the index array
                        foreach (RatchetTexture_Model tex in objModel.textureConfig)
                        {
                            int indx = levelTexList.IndexOf(tex.ID);
                            GL.BindTexture(TextureTarget.Texture2D, levelbTexIDArr[indx]);

                            if (DataStore.selectedLevelObject == levObj)
                            {
                                GL.Uniform4(pgmID_rcID, new Vector4(1, 1, 1, 1));
                                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                                GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedShort, (int)tex.start * sizeof(ushort));
                                GL.Uniform4(pgmID_rcID, new Vector4(0, 0, 0, 0));
                                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                            }


                            GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedShort, (int)tex.start * sizeof(ushort));
                        }
                    }
                }
            }

            if (sceneryReady && sceneryCheck.Checked == true)
            {
                foreach (LevelObject sceneryObj in DataStore.sceneryObjects)
                {
                    objModel = DataStore.sceneryModels.Find(x => x.modelID == sceneryObj.modelID);

                    int insx = sceneryList.IndexOf((uint)objModel.modelID);
                    if (insx != -1)
                    {
                        mvp = sceneryObj.mat * worldView;  //Has to be done in this order to work correctly
                        GL.UniformMatrix4(MatrixID, false, ref mvp);


                        GL.BindBuffer(BufferTarget.ArrayBuffer, sceneryVerts[insx]);
                        GL.BindBuffer(BufferTarget.ElementArrayBuffer, sceneryInds[insx]);

                        //Verts
                        GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 8, 0);
                        //UV's
                        GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 8, sizeof(float) * 6);


                        //Bind textures one by one, applying it to the relevant vertices based on the index array
                        foreach (RatchetTexture_Model tex in objModel.textureConfig)
                        {
                            int indx = sceneryTexList.IndexOf(tex.ID);
                            GL.BindTexture(TextureTarget.Texture2D, sceneryTexIDArr[indx]);
                            GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedShort, (int)tex.start * sizeof(ushort));
                        }
                    }
                }
            }

            if (collReady && collCheck.Checked)
            {
                GL.UseProgram(colorOnlyShaderID);
                mvp = worldView;

                GL.UniformMatrix4(MatrixID, false, ref mvp);

                GL.BindBuffer(BufferTarget.ArrayBuffer, collVBO);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, collInd);

                //Verts
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 6, 0);
                //Colors
                GL.VertexAttribPointer(1, 3, VertexAttribPointerType.Float, false, sizeof(float) * 6, sizeof(float) * 3);

                GL.UseProgram(pgmID);
                GL.UniformMatrix4(MatrixID, false, ref mvp);
                GL.Uniform4(pgmID_rcID, new Vector4(1, 1, 1, 1));
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                GL.DrawElements(PrimitiveType.Triangles, DataStore.collIndBuff.Count, DrawElementsType.UnsignedInt, 0);

                GL.UseProgram(colorOnlyShaderID);
                GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                GL.DrawElements(PrimitiveType.Triangles, DataStore.collIndBuff.Count, DrawElementsType.UnsignedInt, 0);
            }

            if (ready && terrainCheck.Checked)
            {
                GL.UseProgram(pgmID);
                mvp = worldView;

                GL.UniformMatrix4(MatrixID, false, ref mvp);

                GL.EnableVertexAttribArray(2);

                GL.BindBuffer(BufferTarget.ArrayBuffer, VBO);
                GL.BindBuffer(BufferTarget.ElementArrayBuffer, indexBufferID);

                //Verts
                GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 12, 0);
                //UV's
                GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 12, sizeof(float) * 6);
                //Colors
                GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, sizeof(float) * 12, sizeof(float) * 8);


                //Bind textures one by one, applying it to the relevant vertices based on the index array
                foreach (RatchetTexture_Model tex in selectedModel.textureConfig)
                {
                    int indx = texList.IndexOf(tex.ID);
                    GL.BindTexture(TextureTarget.Texture2D, texIDarr[indx]);

                    if (false)
                    {
                        GL.Uniform4(pgmID_rcID, new Vector4(1, 1, 1, 1));
                        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line);
                        GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedInt, (int)tex.start * sizeof(uint));
                    }

                    GL.Uniform4(pgmID_rcID, new Vector4(0, 0, 0, 0));
                    GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                    GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedInt, (int)tex.start * sizeof(uint));
                }

                GL.DisableVertexAttribArray(2);
            }


            if (chunksReady && chunkCheck.Checked)
            {
                for (int i = 0; i < DataStore.chunks.Count; i++)
                {
                    RatchetModel_Terrain chunk = DataStore.chunks[i];

                    GL.UseProgram(pgmID);
                    mvp = worldView;

                    GL.UniformMatrix4(MatrixID, false, ref mvp);

                    GL.EnableVertexAttribArray(2);

                    GL.BindBuffer(BufferTarget.ArrayBuffer, chunkVerts[i]);
                    GL.BindBuffer(BufferTarget.ElementArrayBuffer, chunkInds[i]);

                    //Verts
                    GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(float) * 12, 0);
                    //UV's
                    GL.VertexAttribPointer(1, 2, VertexAttribPointerType.Float, false, sizeof(float) * 12, sizeof(float) * 6);
                    //Colors
                    GL.VertexAttribPointer(2, 4, VertexAttribPointerType.Float, false, sizeof(float) * 12, sizeof(float) * 8);


                    //Bind textures one by one, applying it to the relevant vertices based on the index array
                    foreach (RatchetTexture_Model tex in chunk.textureConfig)
                    {
                        int indx = chunkTexList.IndexOf(tex.ID);
                        GL.BindTexture(TextureTarget.Texture2D, chunkTexIDArr[indx]);

                        GL.Uniform4(pgmID_rcID, new Vector4(0, 0, 0, 0));
                        GL.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill);
                        GL.DrawElements(PrimitiveType.Triangles, (int)tex.size, DrawElementsType.UnsignedInt, (int)tex.start * sizeof(uint));
                    }

                    GL.DisableVertexAttribArray(2);
                }
            }


            GL.DisableVertexAttribArray(1);
            GL.DisableVertexAttribArray(0);
            glControl1.SwapBuffers();
        }
    public static void parseMoby(string path, string fileName)
    {
        FileStream fs = File.OpenRead(path + "/" + fileName);

        Console.WriteLine("Loading file " + path + "/" + fileName);

        #region Moby Textures
        uint texturePointer     = BAToUInt32(ReadBlock(fs, 0x08, 4), 0);
        uint textureDataPointer = BAToUInt32(ReadBlock(fs, 0x0C, 4), 0);
        uint textureCount       = BAToUInt32(ReadBlock(fs, 0x04, 4), 0);

        MemoryStream vfs = new MemoryStream(ReadBlock(fs, textureDataPointer, (uint)fs.Length - textureDataPointer));

        Console.WriteLine("Texture Count: " + textureCount);

        for (int x = 0; x < textureCount; x++)
        {
            RatchetTexture_General texture = new RatchetTexture_General();
            texture.texHeader = ReadBlock(fs, texturePointer + (uint)(0x24 * x), 0x24);
            uint nextTexturePointer    = x < textureCount - 1 ? ReadUInt32(ReadBlock(fs, texturePointer + (uint)(0x24 * (x + 1)), 0x4), 0) : vfs != null ? (uint)vfs.Length : 0;
            uint currentTexturePointer = ReadUInt32(texture.texHeader, 0);
            //Console.WriteLine("Parsing texture " + x + " " + currentTexturePointer.ToString("X") + " " + nextTexturePointer.ToString("X"));
            texture.ID      = x;
            texture.width   = BAToShort(texture.texHeader, 0x18);
            texture.height  = BAToShort(texture.texHeader, 0x1A);
            texture.texData = vfs != null?ReadBlock(vfs, currentTexturePointer, nextTexturePointer - currentTexturePointer) : null;

            texture.reverseRGB = false;
            DataStore.textures.Add(texture);
        }
        #endregion

        #region Moby Model
        uint mobyCount = BAToUInt32(ReadBlock(fs, 0x00, 4), 0);

        byte[] pointerBlock = ReadBlock(fs, 0x10, (mobyCount * 0x0C));

        //Used for mapping textures to models
        int modelIndex = 0;

        for (int x = 0; x < mobyCount; x++)
        {
            RatchetModel_General model = new RatchetModel_General();
            model.modelID = (short)BAToUInt32(pointerBlock, (uint)(x * 0x0C) + 0x04);
            Console.WriteLine("Model ID: " + model.modelID.ToString("X"));
            model.offset = BAToUInt32(pointerBlock, (uint)(x * 0x0C));
            // Console.WriteLine("Model: " + model.modelID.ToString("X4") + " Offset: " + model.offset.ToString("X"));

            if (model.offset != 0)
            {
                uint modelHeadSize = BAToUInt32(ReadBlock(fs, model.offset, 4), 0);
                if (modelHeadSize > 0)
                {
                    byte[] headBlock = ReadBlock(fs, model.offset, modelHeadSize + 0x20); //Head + objectDetails
                    uint   objectPtr = BAToUInt32(headBlock, 0);
                    model.animationsCount = headBlock[0x0C];

                    model.size = BAToFloat(headBlock, 0x24);
                    uint texCount          = BAToUInt32(headBlock, objectPtr + 0x00);
                    uint otherCount        = BAToUInt32(headBlock, objectPtr + 0x04);
                    uint texBlockPointer   = BAToUInt32(headBlock, objectPtr + 0x08);
                    uint otherBlockPointer = BAToUInt32(headBlock, objectPtr + 0x0C);
                    uint vertPointer       = BAToUInt32(headBlock, objectPtr + 0x10);
                    uint indexPointer      = BAToUInt32(headBlock, objectPtr + 0x14);
                    model.vertexCount = BAToUInt16(headBlock, objectPtr + 0x18);
                    //(0x1A)count
                    //(0x1C)count
                    //(0x1E)null

                    model.modelType = ModelType.Spawnable;
                    //model.rawData = getModelDataRaw(model.modelType, model.modelID, path + "/" + fileName);

                    model.animPointer = new List <uint>();
                    for (uint i = 0; i < model.animationsCount; i++)
                    {
                        model.animPointer.Add(BAToUInt32(headBlock, (i * sizeof(uint)) + 0x48));
                    }

                    uint   texElemSize = 0x10;
                    byte[] texBlock    = ReadBlock(fs, model.offset + texBlockPointer, texCount * texElemSize);
                    model.textureConfig = new List <RatchetTexture_Model>();
                    model.faceCount     = 0;
                    for (uint t = 0; t < texCount; t++)
                    {
                        RatchetTexture_Model modTex = new RatchetTexture_Model();
                        modTex.ID    = (uint)BAToUInt32(texBlock, (t * texElemSize) + 0x0);
                        modTex.start = BAToUInt32(texBlock, (t * texElemSize) + 0x04);
                        modTex.size  = BAToUInt32(texBlock, (t * texElemSize) + 0x08);
                        model.textureConfig.Add(modTex);
                        model.faceCount += modTex.size;
                    }


                    //Flip endianness of vertex array float[vert_x, vert_y, vert_z, norm_x, norm_y, norm_z, uv_u, uv_v, reserved reserved]
                    uint   vertElemSize = 0x28;
                    uint   vertBuffSize = model.vertexCount * vertElemSize;
                    byte[] vertBlock    = ReadBlock(fs, model.offset + vertPointer, vertBuffSize);
                    model.vertBuff = new List <float>();
                    for (uint i = 0; i < model.vertexCount; i++)
                    {
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x00));    //Vertx
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x04));    //Verty
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x08));    //Vertz
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x0C));    //Nomrx
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x10));    //Normy
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x14));    //Normz
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x18));    //UVu
                        model.vertBuff.Add(BAToFloat(vertBlock, (i * vertElemSize) + 0x1C));    //UVv
                    }
                    if (model.vertBuff != null)
                    {
                        modelIndex++;
                    }
                    //Flip endianness of index array
                    byte[] indiceBuff = ReadBlock(fs, model.offset + indexPointer, model.faceCount * sizeof(ushort));
                    model.indiceBuff = new List <ushort>();
                    for (uint i = 0; i < model.faceCount; i++)
                    {
                        model.indiceBuff.Add(BAToUInt16(indiceBuff, i * sizeof(ushort)));
                    }
                }
            }
            DataStore.spawnableModels.Add(model);
        }
        #endregion
    }
Beispiel #10
0
    //Passing it by reference to avoid making a copy
    public static void SpawnableToObj(ref RatchetModel_General model, string OBJfilename, string MTLfilename)
    {
        StreamWriter OBJfs = new StreamWriter(OBJfilename);
        StreamWriter MTLfs = new StreamWriter(MTLfilename);


        OBJfs.WriteLine("o Object_" + model.modelID.ToString("X4"));
        if (model.textureConfig != null)
        {
            OBJfs.WriteLine("mtllib " + MTLfilename.Split('\\').Last());
        }


        List <uint> usedMtls = new List <uint>(); //To prevent it from making double mtl entries

        for (int i = 0; i < model.textureConfig.Count; i++)
        {
            uint modelTextureID = model.textureConfig[i].ID;
            if (!usedMtls.Contains(modelTextureID))
            {
                MTLfs.WriteLine("newmtl mtl_" + modelTextureID);
                MTLfs.WriteLine("Ns 1000");
                MTLfs.WriteLine("Ka 1.000000 1.000000 1.000000");
                MTLfs.WriteLine("Kd 1.000000 1.000000 1.000000");
                MTLfs.WriteLine("Ni 1.000000");
                MTLfs.WriteLine("d 0.000000");
                MTLfs.WriteLine("illum 1");
                MTLfs.WriteLine("map_Kd tex_" + model.textureConfig[i].ID + ".png");
                usedMtls.Add(modelTextureID);
            }
        }
        MTLfs.Close();


        //Vertices, normals, UV's
        float[] vertData = model.vertBuff.ToArray();
        for (int x = 0; x < model.vertexCount; x++)
        {
            float px = vertData[(x * 0x08) + 0x0];
            float py = vertData[(x * 0x08) + 0x1];
            float pz = vertData[(x * 0x08) + 0x2];
            float nx = vertData[(x * 0x08) + 0x3];
            float ny = vertData[(x * 0x08) + 0x4];
            float nz = vertData[(x * 0x08) + 0x5];
            float tu = vertData[(x * 0x08) + 0x6];
            float tv = 1f - vertData[(x * 0x08) + 0x7];
            OBJfs.WriteLine("v " + px.ToString("G") + " " + py.ToString("G") + " " + pz.ToString("G"));
            OBJfs.WriteLine("vn " + nx.ToString("G") + " " + ny.ToString("G") + " " + nz.ToString("G"));
            OBJfs.WriteLine("vt " + tu.ToString("G") + " " + tv.ToString("G"));
        }


        //Faces
        int tCnt = 0;

        ushort[] inds = model.indiceBuff.ToArray();
        for (int i = 0; i < model.indiceBuff.Count / 3; i++)
        {
            if (model.textureConfig != null && tCnt < model.textureConfig.Count)
            {
                if (i * 3 >= model.textureConfig[tCnt].start)
                {
                    OBJfs.WriteLine("usemtl mtl_" + model.textureConfig[tCnt].ID.ToString(""));
                    OBJfs.WriteLine("g Texture_" + model.textureConfig[tCnt].ID.ToString(""));
                    tCnt++;
                }
            }
            int f1 = inds[i * 3 + 0] + 1;
            int f2 = inds[i * 3 + 1] + 1;
            int f3 = inds[i * 3 + 2] + 1;
            OBJfs.WriteLine("f " + (f1 + "/" + f1 + "/" + f1) + " " + (f2 + "/" + f2 + "/" + f2) + " " + (f3 + "/" + f3 + "/" + f3));
            //OBJfs.WriteLine("f " + (f3 + "/" + f3 + "/" + f3) + " " + (f2 + "/" + f2 + "/" + f2) + " " + (f1 + "/" + f1 + "/" + f1));
        }
        OBJfs.Close();
    }