public void Precalc(Polygon poly) { //Manage data buffer size and adjust accordingly int dataSize = _elements * poly._script.Stride; if (_data != null) { if (dataSize != _data.Length) { _data.Dispose(); } else { goto Next; } } _data = new UnsafeBuffer(dataSize); Next: //Fill buffer with raw data byte *pOut = (byte *)_data.Address; FacePoint *pFacePoint = (FacePoint *)poly._facePoints.Address; for (int i = 0; i < _elements; i++) { poly._script.Run(poly, &pFacePoint[_indices[i]], ref pOut); } }
public void Run(Polygon poly, FacePoint *point, ref byte *pOut) { Vertex3 v = poly._vertices[point->VertexId]; ScriptCommand o; int index; fixed(byte *c = _commands) { ScriptCommand *cmd = (ScriptCommand *)c; Top: switch (o = *cmd++) { case ScriptCommand.None: break; case ScriptCommand.Position: *(Vector3 *)pOut = v.Position; pOut += 12; goto Top; case ScriptCommand.WeightedPosition: *(Vector3 *)pOut = v.WeightedPosition; pOut += 12; goto Top; case ScriptCommand.Normal: *(Vector3 *)pOut = point->Normal; pOut += 12; goto Top; case ScriptCommand.WeightedNormal: *(Vector3 *)pOut = v.Inf != null ? v.Inf.Matrix * point->Normal : point->Normal; pOut += 12; goto Top; case ScriptCommand.Color0: case ScriptCommand.Color1: index = (int)(o - ScriptCommand.Color0); *(RGBAPixel *)pOut = ((RGBAPixel *)point->Color)[index]; pOut += 4; goto Top; //The rest are UVs default: index = (int)(o - ScriptCommand.UV0); *(Vector2 *)pOut = ((Vector2 *)point->UVs)[index]; pOut += 8; goto Top; } } }
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); }