private void b_DoWork(object sender, DoWorkEventArgs e) { if (e == null) { return; } ObjectOptimizerForm form = e.Argument as ObjectOptimizerForm; form._newPointCount = 0; foreach (ObjectOptimization a in form._results) { if (a == null || a._object == null || a._object._manager == null || a._object._manager._triangles == null || a._facepoints == null) { return; } TriangleConverter triConverter = new TriangleConverter(chkUseStrips.Checked, (uint)numCacheSize.Value, (uint)numMinStripLen.Value, chkPushCacheHits.Checked); Facepoint[] points = new Facepoint[a._object._manager._triangles._indices.Length]; uint[] indices = a._object._manager._triangles._indices; bool ccw = Collada._importOptions._forceCCW; //Indices are written in reverse for each triangle, //so they need to be set to a triangle in reverse if not CCW for (int t = 0; t < a._object._manager._triangles._indices.Length; t++) { points[ccw ? t : t - t % 3 + (2 - t % 3)] = a._facepoints[indices[t]]; } List <PrimitiveGroup> p = triConverter.GroupPrimitives(points, out int pc, out int fc); if (chkAllowIncrease.Checked || pc < a._pointCount) { a._pointCount = pc; a._faceCount = fc; a._groups = p; } form._newPointCount += a._pointCount; } e.Result = form; }
//Decode a single primitive using command list public void Run( ref byte *pIn, byte **pAssets, byte **pOut, int count, PrimitiveGroup group, ref ushort *indices, IMatrixNode[] nodeTable, bool[] textureMatrixIdentity) { //pIn is the address in the primitives //pOut is address of the face data buffers //pAssets is the address of the raw asset buffers int weight = 0; int index = 0, outSize; DecodeOp o; ElementDef *pDef; byte * p; byte[] pTexMtx = new byte[8]; byte *tIn, tOut; group._facePoints.Add(new List <Facepoint>()); //Iterate commands in list fixed(ushort *pNode = Nodes) { fixed(int *pDefData = Defs) { fixed(byte *pCmd = Commands) { for (int i = 0; i < count; i++) { pDef = (ElementDef *)pDefData; p = pCmd; Facepoint f = new Facepoint(); Continue: o = (DecodeOp)(*p++); switch (o) { //Process weight using cache case DecodeOp.PosWeight: weight = pNode[*pIn++ / 3]; goto Continue; case DecodeOp.TexMtx0: case DecodeOp.TexMtx1: case DecodeOp.TexMtx2: case DecodeOp.TexMtx3: case DecodeOp.TexMtx4: case DecodeOp.TexMtx5: case DecodeOp.TexMtx6: case DecodeOp.TexMtx7: index = (int)o - (int)DecodeOp.TexMtx0; byte value = *pIn++; if (value % 3 != 0) { Console.WriteLine("Raw texture matrix value is 0x{0}", value.ToString()); } else { value /= 3; if (value < 10) { textureMatrixIdentity[index] = true; //Console.WriteLine("Texture matrix value is {0}", value.ToString()); } else if (value >= 20) { Console.WriteLine("Texture matrix value is {0}", value.ToString()); } else { pTexMtx[index] = (byte)(value - 10); textureMatrixIdentity[index] = false; } } goto Continue; case DecodeOp.ElementDirect: ElementCodec.Decoders[pDef->Output](ref pIn, ref pOut[pDef->Type], VQuant.DeQuantTable[pDef->Scale]); goto Continue; case DecodeOp.ElementIndexed: //Get asset index if (pDef->Format == 2) { index = *(bushort *)pIn; pIn += 2; } else { index = *pIn++; } switch (pDef->Type) { case 0: f._vertexIndex = index; break; case 1: f._normalIndex = index; break; case 2: case 3: f._colorIndices[pDef->Type - 2] = index; break; default: f._UVIndices[pDef->Type - 4] = index; break; } if (pDef->Type == 0) //Special processing for vertices { //Match weight and index with remap table int mapEntry = (weight << 16) | index; //Find matching index, starting at end of list //Lower index until a match is found at that index or index is less than 0 index = RemapTable.Count; while (--index >= 0 && RemapTable[index] != mapEntry) { ; } //No match, create new entry //Will be processed into vertices at the end! if (index < 0) { index = RemapTable.Count; RemapTable.Add(mapEntry); _points.Add(new List <Facepoint>()); } //Write index *indices++ = (ushort)index; _points[index].Add(f); } else { //Copy data from buffer outSize = pDef->Output; //Input data from asset cache tIn = pAssets[pDef->Type] + index * outSize; tOut = pOut[pDef->Type]; if (tIn != null && tOut != null) { //Copy data to output while (outSize-- > 0) { *tOut++ = *tIn++; } //Increment element output pointer pOut[pDef->Type] = tOut; } } pDef++; goto Continue; default: break; //End } @group._facePoints[@group._facePoints.Count - 1].Add(f); } } } } }
//Decode a single primitive using command list public void Run(ref byte *pIn, byte **pAssets, byte **pOut, int count, PrimitiveGroup group, ref ushort *indices, IMatrixNode[] nodeTable) { int weight = 0; //Vector3 Position = new Vector3(); //Vector3 Normal = new Vector3(); //Vector2[] UV = new Vector2[8]; //RGBAPixel[] Color = new RGBAPixel[2]; int index = 0, outSize; DecodeOp o; ElementDef *pDef; byte * p; //byte[] pTexMtx = new byte[8]; byte *tIn, tOut; group._points.Add(new List <Facepoint>()); //Iterate commands in list fixed(ushort *pNode = Nodes) fixed(int *pDefData = Defs) fixed(byte *pCmd = Commands) { for (int i = 0; i < count; i++) { pDef = (ElementDef *)pDefData; p = pCmd; Facepoint f = new Facepoint(); Top: o = (DecodeOp)(*p++); switch (o) { //Process weight using cache case DecodeOp.PosWeight: weight = pNode[*pIn++ / 3]; if (weight < nodeTable.Length) { f.Node = nodeTable[weight]; } goto Top; case DecodeOp.TexMtx0: case DecodeOp.TexMtx1: case DecodeOp.TexMtx2: case DecodeOp.TexMtx3: case DecodeOp.TexMtx4: case DecodeOp.TexMtx5: case DecodeOp.TexMtx6: case DecodeOp.TexMtx7: //index = (int)o - (int)DecodeOp.TexMtx0; if (*pIn++ == 0x60) //Identity matrix... { Console.WriteLine("wtf"); } //pTexMtx[index] = (byte)(*pIn++ / 3); goto Top; case DecodeOp.ElementDirect: ElementCodec.Decoders[pDef->Output] (ref pIn, ref pOut[pDef->Type], VQuant.DeQuantTable[pDef->Scale]); goto Top; case DecodeOp.ElementIndexed: //Get asset index if (pDef->Format == 2) { index = *(bushort *)pIn; pIn += 2; } else { index = *pIn++; } switch (pDef->Type) { case 0: f.VertexIndex = index; break; case 1: f.NormalIndex = index; break; case 2: case 3: f.ColorIndex[pDef->Type - 2] = index; break; default: f.UVIndex[pDef->Type - 4] = index; break; } if (pDef->Type == 0) //Special processing for vertices { //Match weight and index with remap table int mapEntry = (weight << 16) | index; int *pTmp = (int *)RemapTable.Address; //Find matching index, starting at end of list //Do nothing while the index lowers index = RemapSize; while ((--index >= 0) && (pTmp[index] != mapEntry)) { ; } //No match, create new entry //Will be processed into vertices at the end! if (index < 0) { pTmp[index = RemapSize++] = mapEntry; } //Write index //*(ushort*)pOut[pDef->Type] = (ushort)index; //pOut[pDef->Type] += 2; *indices++ = (ushort)index; } else { //Copy data from buffer outSize = pDef->Output; //Input data from asset cache tIn = pAssets[pDef->Type] + (index * outSize); tOut = pOut[pDef->Type]; //Copy data to output while (outSize-- > 0) { *tOut++ = *tIn++; } //Increment element output pointer pOut[pDef->Type] = tOut; } pDef++; goto Top; //Can't use this until it works faster. Merges all data into vertices. // if (pDef->Type == 0) // { // tOut = (byte*)&Position; // goto Apply; // } // else if (pDef->Type == 1) // { // tOut = (byte*)&Normal; // goto Apply; // } // else if (pDef->Type < 4) // { // fixed (RGBAPixel* color = &Color[pDef->Type - 2]) // tOut = (byte*)color; // goto Apply; // } // else // { // fixed (Vector2* uv = &UV[pDef->Type - 4]) // tOut = (byte*)uv; // goto Apply; // } //Apply: // //Copy data from buffer // outSize = pDef->Output; // //Input data from asset cache // tIn = pAssets[pDef->Type] + (index * outSize); // //Copy data to output // while (outSize-- > 0) // *tOut++ = *tIn++; // pDef++; // goto Top; default: break; //End } ////Remap as whole vertex ////Match vertex with remap table //VertData mapEntry = new VertData(Position, weight, Normal, Color, UV); //VertData* pTmp = (VertData*)RemapTable.Address; ////Find matching index, starting at end of list //index = RemapSize; //while ((--index >= 0) && (pTmp[index] != mapEntry)); ////No match, create new entry //if (index < 0) // pTmp[index = RemapSize++] = mapEntry; ////Write index //*pOut++ = (ushort)index; group._points[group._points.Count - 1].Add(f); } } }