Exemple #1
0
        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);
                }
            }
        }