コード例 #1
0
        protected internal override void PostProcess(VoidPtr mdlAddress, VoidPtr dataAddress, StringTable stringTable)
        {
            MDL0Polygon *header = (MDL0Polygon *)dataAddress;

            header->_mdl0Offset   = (int)mdlAddress - (int)dataAddress;
            header->_stringOffset = (int)stringTable[Name] + 4 - (int)dataAddress;
        }
コード例 #2
0
        public PrimitiveManager(MDL0Polygon *polygon, AssetStorage assets, IMatrixNode[] nodes)
        {
            byte *[] pAssetList = new byte *[12];
            byte *[] pOutList   = new byte *[12];
            int      id;

            //This relies on the header being accurate!
            _pointCount = polygon->_numVertices;

            //Grab asset lists in sequential order.
            //This involves checking IDs and creating buffers for the pre-processed data.
            //Also gets data addresses from pre-decoded assets so they can be parsed further
            //All buffers are stored in the _faceData array

            if ((id = polygon->_vertexId) >= 0)
            {
                pAssetList[0] = (byte *)assets.Assets[0][id].Address;
                pOutList[0]   = (byte *)(_faceData[0] = new UnsafeBuffer(2 * _pointCount)).Address;
            }
            //Save vertices for last

            if ((id = polygon->_normalId) >= 0)
            {
                pAssetList[1] = (byte *)assets.Assets[1][id].Address;
                pOutList[1]   = (byte *)(_faceData[1] = new UnsafeBuffer(12 * _pointCount)).Address;
            }

            for (int i = 0, x = 2; i < 2; i++, x++)
            {
                if ((id = ((bshort *)polygon->_colorIds)[i]) >= 0)
                {
                    pAssetList[x] = (byte *)assets.Assets[2][id].Address;
                    pOutList[x]   = (byte *)(_faceData[x] = new UnsafeBuffer(4 * _pointCount)).Address;
                }
            }

            for (int i = 0, x = 4; i < 8; i++, x++)
            {
                if ((id = ((bshort *)polygon->_uids)[i]) >= 0)
                {
                    pAssetList[x] = (byte *)assets.Assets[3][id].Address;
                    pOutList[x]   = (byte *)(_faceData[x] = new UnsafeBuffer(8 * _pointCount)).Address;
                }
            }


            //Compile decode script
            ElementDescriptor desc = new ElementDescriptor(polygon);

            //Extract primitives, using our descriptor and asset lists
            fixed(byte **pOut = pOutList)
            fixed(byte **pAssets = pAssetList)
            ExtractPrimitives((byte *)polygon->PrimitiveData, ref desc, pOut, pAssets);

            //Compile vertex list using influences from node cache
            _vertices = desc.Finish((Vector3 *)pAssetList[0], nodes);
        }
コード例 #3
0
        protected override bool OnInitialize()
        {
            MDL0Polygon *header = Header;
            int          nodeId = header->_nodeId;

            ModelLinker linker = Model._linker;

            //Attach single bind. Doesn't have to be bone node.
            if (nodeId >= 0)
            {
                Influence = linker.NodeCache[nodeId];
            }

            if (header->_defFlags != 0x80)
            {
                Console.WriteLine("OMG!");
            }
            if (header->_defSize != 0xE0)
            {
                Console.WriteLine("OMG!");
            }
            if (header->_dataLen1 != header->_dataLen2)
            {
                Console.WriteLine("DataLen deviation!");
            }
            if (header->_unk3 != 0)
            {
                Console.WriteLine("OMG!");
            }

            if (header != null)
            {
                //Conditional name assignment
                if ((_name == null) && (header->_stringOffset != 0))
                {
                    _name = header->ResourceString;
                }

                //Create primitive manager
                if (_parent != null)
                {
                    _manager = new PrimitiveManager(header, Model._assets, linker.NodeCache);
                }
            }

            return(false);
        }
コード例 #4
0
        public static List <Primitive> ExtractPrimitives(MDL0Polygon *polygon)
        {
            List <Primitive> list = new List <Primitive>();

            VoidPtr      dataAddr = polygon->PrimitiveData;
            ElementFlags e        = new ElementFlags(polygon->_elemFlags, polygon->_texFlags);
            //ModelEntrySize e = new ModelEntrySize(polygon->_flags);

            int nodeIndex = 0;

            ushort[]  nodeBuffer = new ushort[16];
            Primitive p;

            while ((p = ExtractPrimitive(ref dataAddr, e, nodeBuffer, ref nodeIndex)) != null)
            {
                list.Add(p);
            }

            return(list);
        }
コード例 #5
0
        public ElementDescriptor(MDL0Polygon *polygon)
        {
            MDL0Header *model = (MDL0Header *)((byte *)polygon + polygon->_mdl0Offset);
            byte *      pData = (byte *)polygon->DefList;
            byte *      pCom;
            ElementDef *pDef;
            int         fmtLo, fmtHi;
            int         grp0, grp1, grp2;
            int         format;

            //Create remap table for vertex weights
            RemapTable = new UnsafeBuffer(polygon->_numVertices * 4);
            RemapSize  = 0;
            Stride     = 0;

            //Read element descriptor from polygon display list
            //Use direct access instead!
            //May change depending on file version

            fmtLo = *(bint *)(pData + 12);
            fmtHi = *(bint *)(pData + 18);
            grp0  = *(bint *)(pData + 34);
            grp1  = *(bint *)(pData + 40);
            grp2  = *(bint *)(pData + 46);

            //grp1 = *(buint*)(pData + 40);
            //grp1 |= (ulong)(*(buint*)(pData + 46)) << 32;


            //Build extract script.
            //What we're doing is assigning extract commands for elements in the polygon, in true order.
            //This allows us to process the polygon blindly, assuming that the definition is accurate.
            //Theoretically, this should offer a significant speed bonus.
            fixed(int *pDefData = Defs)
            fixed(byte *pComData = Commands)
            {
                pCom = pComData;
                pDef = (ElementDef *)pDefData;

                //Pos/Norm weight
                if (Weighted = (fmtLo & 1) != 0)
                {
                    *pCom++ = (byte)DecodeOp.PosWeight;
                    Stride++;
                }

                //Tex matrix
                for (int i = 0; i < 8; i++)
                {
                    if (((fmtLo >> (i + 1)) & 1) != 0)
                    {
                        *pCom++ = (byte)(DecodeOp.TexMtx0 + i);
                        Stride++;
                    }
                }

                //Positions
                format = ((fmtLo >> 9) & 3) - 1;
                if (format >= 0)
                {
                    pDef->Input = (byte)format;
                    pDef->Type  = 0;
                    if (format == 0)
                    {
                        throw new NotSupportedException("Direct mode is not suported for polygons!");
                        //pDef->Scale = (byte)((grp0 >> 4) & 0x1F);
                        //pDef->Output = (byte)(((grp0 >> 1) & 0x7) + ((grp0 & 1) == 0 ? ElementCodec.CodecType.XY : ElementCodec.CodecType.XYZ));
                        //pCom[NumCommands++] = (byte)DecodeOp.ElementDirect;
                    }
                    else
                    {
                        Stride      += format;
                        pDef->Output = 12;
                        *pCom++ = (byte)DecodeOp.ElementIndexed;
                    }
                    pDef++;
                }

                //Normals
                format = ((fmtLo >> 11) & 3) - 1;
                if (format >= 0)
                {
                    pDef->Input = (byte)format;
                    pDef->Type  = 1;
                    if (format == 0)
                    {
                        throw new NotSupportedException("Direct mode is not suported for polygons!");
                        //pDef->Scale = 0; //Implied?
                        //pDef->Output = (byte)(((grp0 >> 10) & 0x7) + ((grp0 & (1 << 10)) == 0 ? ElementCodec.CodecType.XYZ : ElementCodec.CodecType.XYZ));
                        //pCom[NumCommands++] = (byte)DecodeOp.ElementDirect;
                    }
                    else
                    {
                        Stride      += format;
                        pDef->Output = 12;
                        *pCom++ = (byte)DecodeOp.ElementIndexed;
                    }
                    pDef++;
                }

                //Colors
                for (int i = 0; i < 2; i++)
                {
                    format = ((fmtLo >> (i * 2 + 13)) & 3) - 1;
                    if (format >= 0)
                    {
                        pDef->Input = (byte)format;
                        pDef->Type  = (byte)(i + 2);
                        if (format == 0)
                        {
                            throw new NotSupportedException("Direct mode is not suported for polygons!");
                            //pDef->Output = (byte)((grp0 >> (i * 4 + 14)) & 7);
                            //pCom[NumCommands++] = (byte)DecodeOp.ElementDirect;
                        }
                        else
                        {
                            Stride      += format;
                            pDef->Output = 4;
                            *pCom++ = (byte)DecodeOp.ElementIndexed;
                        }
                        pDef++;
                    }
                }

                //UVs
                for (int i = 0; i < 8; i++)
                {
                    format = ((fmtHi >> (i * 2)) & 3) - 1;
                    if (format >= 0)
                    {
                        pDef->Input = (byte)format;
                        pDef->Type  = (byte)(i + 4);
                        if (format == 0)
                        {
                            throw new NotSupportedException("Direct mode is not suported for polygons!");
                            //Needs work!
                            //if (i == 0)
                            //{
                            //    pDef->Output = (byte)(((grp0 >> 22) & 7) + ((grp0 & 22) == 0 ? ElementCodec.CodecType.S : ElementCodec.CodecType.ST));
                            //    pDef->Scale = (byte)((grp0 >> 25) & 0x1F);
                            //}
                            //else
                            //{
                            //    pDef->Output = (byte)((int)((grp1 >> (i * 9 + 1)) & 7) + ((grp1 & ((ulong)1 << (i * 9 + 1))) == 0 ? ElementCodec.CodecType.S : ElementCodec.CodecType.ST));
                            //    pDef->Scale = (byte)((grp1 >> (i * 9 + 4)) & 0x1F);
                            //}
                            //pCom[NumCommands++] = (byte)DecodeOp.ElementDirect;
                        }
                        else
                        {
                            Stride      += format;
                            pDef->Output = 8;
                            *pCom++ = (byte)DecodeOp.ElementIndexed;
                        }
                        pDef++;
                    }
                }

                *pCom = 0;
            }
        }
コード例 #6
0
        public ElementDescriptor(MDL0Polygon *polygon)
        {
            byte *      pData = (byte *)polygon->DefList;
            byte *      pCom;
            ElementDef *pDef;

            CPElementSpec UVATGroups;
            int           format; //1 for direct, 2 for byte, 3 for short

            //Create remap table for vertex weights
            RemapTable = new UnsafeBuffer(polygon->_numVertices * 4);
            RemapSize  = 0;
            Stride     = 0;

            NodeIds   = new List <ushort>();
            Addresses = new List <uint>();

            //Read element descriptor from polygon display list
            MDL0PolygonDefs *Definitons = (MDL0PolygonDefs *)polygon->DefList;

            int fmtLo = (int)Definitons->VtxFmtLo;
            int fmtHi = (int)Definitons->VtxFmtHi;

            UVATGroups = new CPElementSpec(
                (uint)Definitons->UVATA,
                (uint)Definitons->UVATB,
                (uint)Definitons->UVATC);

            //Build extract script.
            //What we're doing is assigning extract commands for elements in the polygon, in true order.
            //This allows us to process the polygon blindly, assuming that the definition is accurate.
            //Theoretically, this should offer a significant speed bonus.
            fixed(int *pDefData = Defs)
            fixed(byte *pComData = Commands)
            {
                pCom = pComData;
                pDef = (ElementDef *)pDefData;

                //Pos/Norm weight
                if (Weighted = (fmtLo & 1) != 0)
                {
                    //Set the first command as the weight
                    *pCom++ = (byte)DecodeOp.PosWeight;
                    Stride++; //Increment stride by a byte (the length of the facepoints)
                }

                //Tex matrix
                for (int i = 0; i < 8; i++)
                {
                    if (((fmtLo >> (i + 1)) & 1) != 0)
                    {
                        //Set the command for each texture matrix
                        *pCom++ = (byte)(DecodeOp.TexMtx0 + i);
                        Stride++; //Increment stride by a byte (the length of the facepoints)
                    }
                }

                //Positions
                format = ((fmtLo >> 9) & 3) - 1;
                if (format >= 0)
                {
                    //Set the definitions input
                    pDef->Format = (byte)format;
                    //Set the type to Positions
                    pDef->Type = 0;
                    if (format == 0)
                    {
                        pDef->Scale = (byte)UVATGroups.PositionDef.Scale;
                        //pDef->Output =
                        *pCom++ = (byte)DecodeOp.ElementDirect;
                    }
                    else
                    {
                        Stride      += format; //Add to stride (the length of the facepoints)
                        pDef->Output = 12;     //Set the output
                        *pCom++ = (byte)DecodeOp.ElementIndexed;
                    }
                    pDef++;
                }

                //Normals
                format = ((fmtLo >> 11) & 3) - 1;
                if (format >= 0)
                {
                    //Set the definitions input
                    pDef->Format = (byte)format;
                    //Set the type to Normals
                    pDef->Type = 1;
                    if (format == 0)
                    {
                        pDef->Scale = (byte)UVATGroups.NormalDef.Scale;
                        //pDef->Output =
                        *pCom++ = (byte)DecodeOp.ElementDirect;
                    }
                    else
                    {
                        Stride      += format; //Add to stride (the length of the facepoints)
                        pDef->Output = 12;     //Set the output
                        *pCom++ = (byte)DecodeOp.ElementIndexed;
                    }
                    pDef++;
                }

                //Colors
                for (int i = 0; i < 2; i++)
                {
                    format = ((fmtLo >> (i * 2 + 13)) & 3) - 1;
                    if (format >= 0)
                    {
                        //Set the definitions input
                        pDef->Format = (byte)format;
                        //Set the type to Colors
                        pDef->Type = (byte)(i + 2);
                        if (format == 0)
                        {
                            //pDef->Output =
                            pDef->Scale = 0;
                            *pCom++ = (byte)DecodeOp.ElementDirect;
                        }
                        else
                        {
                            Stride      += format; //Add to stride (the length of the facepoints)
                            pDef->Output = 4;      //Set the output
                            *pCom++ = (byte)DecodeOp.ElementIndexed;
                        }
                        pDef++;
                    }
                }

                //UVs
                for (int i = 0; i < 8; i++)
                {
                    format = ((fmtHi >> (i * 2)) & 3) - 1;
                    if (format >= 0)
                    {
                        //Set the definitions input
                        pDef->Format = (byte)format;
                        //Set the type to UVs
                        pDef->Type = (byte)(i + 4);
                        if (format == 0)
                        {
                            //pDef->Output =
                            pDef->Scale = (byte)UVATGroups.GetUVDef(i).Scale;
                            *pCom++ = (byte)DecodeOp.ElementDirect;
                        }
                        else
                        {
                            Stride      += format; //Add to stride (the length of the facepoints)
                            pDef->Output = 8;      //Set the output
                            *pCom++ = (byte)DecodeOp.ElementIndexed;
                        }
                        pDef++;
                    }
                }
                *pCom = 0;
            }
        }
コード例 #7
0
 public void SetPrimitives(MDL0Polygon *polygon)
 {
 }
コード例 #8
0
        public void GetPrimitives(MDL0Polygon *header, MDL0PolygonNode polygon)
        {
            AssetStorage assets = Model._assets;

            IMatrixNode[] influences = Model._linker.NodeCache;
            byte *[]      pAssetList = new byte *[12]; int id;

            //Sync Data
            if ((id = header->_vertexId) >= 0)
            {
                pAssetList[0] = (byte *)assets.Assets[0][id].Address;
            }

            if ((id = header->_normalId) >= 0)
            {
                pAssetList[1] = (byte *)assets.Assets[1][id].Address;
            }

            for (int i = 0, x = 2; i < 2; i++, x++)
            {
                if ((id = ((bshort *)header->_colorIds)[i]) >= 0)
                {
                    pAssetList[x] = (byte *)assets.Assets[2][id].Address;
                }
            }

            for (int i = 0, x = 4; i < 8; i++, x++)
            {
                if ((id = ((bshort *)header->_uids)[i]) >= 0)
                {
                    pAssetList[x] = (byte *)assets.Assets[3][id].Address;
                }
            }

            //Set definition
            _elemDef             = new ElementDefinition();
            _elemDef.Weighted    = polygon.VertexFormat.HasPosMatrix;
            _elemDef.PositionFmt = polygon.VertexFormat.PosFormat;
            _elemDef.Normals     = (_elemDef.NormalFmt = polygon.VertexFormat.NormalFormat) != XFDataFormat.None;
            for (int i = 0; i < 2; i++)
            {
                _elemDef.Colors[i] = (_elemDef.ColorFmt[i] = polygon.VertexFormat.GetColorFormat(i)) != XFDataFormat.None;
            }
            for (int i = 0; i < 8; i++)
            {
                _elemDef.UVs[i] = (_elemDef.UVFmt[i] = polygon.VertexFormat.GetUVFormat(i)) != XFDataFormat.None;
            }
            for (int i = 0; i < 8; i++)
            {
                _elemDef.TexMatrices[i] = polygon.VertexFormat.GetHasTexMatrix(i);
            }

            List <FacePoint> facePoints = new List <FacePoint>();

            //Create script using definition for decoding and rendering
            _script = new PrimitiveScript(_elemDef);

            //Create remap table for vertex weights
            RemapTable = new UnsafeBuffer(header->_numVertices * 4);
            RemapSize  = 0;

            //Extract primitives using script
            byte *pData = (byte *)header->PrimitiveData;
            int   count; GLPrimitiveType type;
            int   ind = 0;

            _facePoints = new UnsafeBuffer((_facePointCount = header->_numVertices) * 86);
            FacePoint *points = (FacePoint *)_facePoints.Address;

Top:
            switch ((WiiPrimitiveType)(*pData++))
            {
            //Fill weight cache
            case WiiPrimitiveType.PosMtx:
                //Get node ID
                ushort node = *(bushort *)pData;
                //Get cache index
                int index = (*(bushort *)(pData + 2) & 0xFFF) / 12;

                //Assign node ID to cache, using index
                fixed(ushort *n = _script.Nodes)
                n[index] = node;

                pData += 4;
                goto Top;

            case WiiPrimitiveType.NorMtx:     //Same as PosMtx
            case WiiPrimitiveType.TexMtx:
            case WiiPrimitiveType.LightMtx:
                pData += 4;     //Skip
                goto Top;

            case WiiPrimitiveType.Quads: type = GLPrimitiveType.Quads; break;

            case WiiPrimitiveType.Triangles: type = GLPrimitiveType.Triangles; break;

            case WiiPrimitiveType.TriangleFan: type = GLPrimitiveType.TriangleFan; break;

            case WiiPrimitiveType.TriangleStrip: type = GLPrimitiveType.TriangleStrip; break;

            case WiiPrimitiveType.Lines: type = GLPrimitiveType.Lines; break;

            case WiiPrimitiveType.LineStrip: type = GLPrimitiveType.LineStrip; break;

            case WiiPrimitiveType.Points: type = GLPrimitiveType.Points; break;

            default: goto Next;     //No more primitives.
            }

            count = *(bushort *)pData; pData += 2;
            Primitive2 prim = new Primitive2()
            {
                _type = type, _elements = count
            };

            prim._indices = new int[count];

            //Extract facepoints
            fixed(byte **pAssets = pAssetList)
            for (int i = 0; i < count; i++)
            {
                points[ind]      = ExtractFacepoint(ref pData, pAssets);
                prim._indices[i] = (ushort)ind++;
            }

            _primitives.Add(prim);

            goto Top; //Move on to next primitive

            Next : _vertices = Finish((Vector3 *)pAssetList[0], influences);
        }