/////////////////////////////////////////////////////////////////////// // CParser::ParseVertexAndIndexData private bool ParseVertexAndIndexData(BinaryReader br) { bool bSuccess = false; if (Geometry == null) { return(false); } for (int i = 0; i < Geometry.NNumLods; i++) { if (Geometry.PLods == null) { return(false); } SLod lod = Geometry.PLods[i]; if (lod == null) { return(false); } for (int j = 0; j < lod.NNumDrawCalls; j++) { if (lod.PDrawCalls == null) { return(false); } SDrawCall pDrawCall = lod.PDrawCalls[j]; if (pDrawCall == null) { return(false); } int uiVertexDataSize = pDrawCall.NNumVertices * pDrawCall.PRenderState.SVertexDecl.UiVertexSize; int uiIndexDataSize = pDrawCall.NNumIndices * (pDrawCall.B32BitIndices ? 4 : 2); if (GetRemainingLength() >= uiVertexDataSize + uiIndexDataSize) { // vertex data if (m_stream.Position % 4 != 0) { return(false); } pDrawCall.PVertexData = br.ReadBytes(uiVertexDataSize); // index data if (m_stream.Position % 4 != 0) { return(false); } pDrawCall.PIndexData = br.ReadBytes(uiIndexDataSize); ParseUntilAligned(br); } //else // CCore::SetError("CParser::ParseVertexAndIndexData, premature end-of-file\n"); } } bSuccess = true; //else // CCore::SetError("CParser::ParseVertexAndIndexData, premature end-of-file\n"); return(bSuccess); }
/////////////////////////////////////////////////////////////////////// // CParser::Parse3dGeometry private bool Parse3dGeometry(BinaryReader br) { bool bSuccess = false; // start with SLods if (GetRemainingLength() >= c_nSizeOfInt) { Geometry.NNumLods = br.ReadInt32(); //if (GetRemainingLength() >= Geometry.NNumLods * Marshal.SizeOf<SLod>()) if (GetRemainingLength() >= Geometry.NNumLods * 24) { // read SLod structs // reads NNumDrawCalls and m_nNumBones, the pointers are actually just 0 in the serialized file and get assigend upon parsing Geometry.PLods = new SLod[Geometry.NNumLods]; for (int i = 0; i < Geometry.NNumLods; i++) { //Geometry.PLods[i] = ReadStruct<SLod>(); // I'm deviating here from the c++ parser bc they work with pointers // but since the serialized pointer data is just null bytes that's fine SLod lod = new SLod(); lod.NNumDrawCalls = br.ReadInt32(); br.ReadBytes(8); // CDrawCallPointer lod.NNumBones = br.ReadInt32(); br.ReadBytes(8); // CBonePointer Geometry.PLods[i] = lod; } // read SDrawCalls for (int i = 0; i < Geometry.NNumLods; i++) { SLod plod = Geometry.PLods[i]; //if (GetRemainingLength() >= plod.NNumDrawCalls * Marshal.SizeOf<SDrawCall>()) if (GetRemainingLength() >= plod.NNumDrawCalls * 40) { plod.PDrawCalls = new SDrawCall[plod.NNumDrawCalls]; for (int j = 0; j < plod.NNumDrawCalls; j++) { //plod.PDrawCalls[j] = ReadStruct<SDrawCall>(); // again I'm deviating here from the c++ parser bc they work with pointers // read the class manually SDrawCall drawCall = new SDrawCall(); br.ReadBytes(8); // CRenderStatePointer m_pRenderState drawCall.NRenderStateIndex = br.ReadInt32(); drawCall.NNumVertices = br.ReadInt32(); br.ReadBytes(8); // CBytePointer m_pVertexData drawCall.NNumIndices = br.ReadInt32(); drawCall.B32BitIndices = br.ReadBytes(4).First() != 0x00; br.ReadBytes(8); // CBytePointer m_pIndexData plod.PDrawCalls[j] = drawCall; // read bones if (plod.NNumBones > 0) { plod.PBones = new SBone[plod.NNumBones]; for (int k = 0; k < plod.NNumBones; i++) { plod.PBones[k] = br.BaseStream.ReadStruct <SBone>(); } } } // assign draw calls' render state pointers for (int ndrawcall = 0; ndrawcall < plod.NNumDrawCalls; ndrawcall++) { SDrawCall pDrawCall = plod.PDrawCalls[ndrawcall]; pDrawCall.PRenderState = Geometry.P3dRenderStateMain[pDrawCall.NRenderStateIndex]; } } } bSuccess = true; } } //else // CCore::SetError("CParser::Parse3dGeometry, premature end-of-file\n"); return(bSuccess); }