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; }
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); }
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); }
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); }
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; } }
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; } }
public void SetPrimitives(MDL0Polygon *polygon) { }
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); }