Exemplo n.º 1
0
        ///////////////////////////////////////////////////////////////////////
        //  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);
        }
Exemplo n.º 2
0
        ///////////////////////////////////////////////////////////////////////
        //  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);
        }