示例#1
0
        public Facepoint this[int i]
        {
            get
            {
                switch (i)
                {
                case 0: return(_x);

                case 1: return(_y);

                case 2: return(_z);
                }
                return(null);
            }
            set
            {
                switch (i)
                {
                case 0: _x = value; break;

                case 1: _y = value; break;

                case 2: _z = value; break;
                }
            }
        }
示例#2
0
 public bool Contains(Facepoint f)
 {
     if (_x == f)
     {
         return(true);
     }
     if (_y == f)
     {
         return(true);
     }
     return(false);
 }
示例#3
0
 public PointTriangle(Facepoint x, Facepoint y, Facepoint z)
 {
     _x = x;
     _y = y;
     _z = z;
 }
示例#4
0
 public bool Contains(Facepoint f)
 {
     if (_x == f) return true;
     if (_y == f) return true;
     if (_z == f) return true;
     return false;
 }
示例#5
0
 public Facepoint this[int i]
 {
     get
     {
         switch (i)
         {
             case 0: return _x;
             case 1: return _y;
             case 2: return _z;
         }
         return null;
     }
     set
     {
         switch (i)
         {
             case 0: _x = value; break;
             case 1: _y = value; break;
             case 2: _z = value; break;
         }
     }
 }
示例#6
0
 public PointTriangle(Facepoint x, Facepoint y, Facepoint z)
 {
     _x = x;
     _y = y;
     _z = z;
 }
        //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)
        {
            //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._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();

                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;
                            //if (*pIn++ == 0x60) //Identity matrix...
                            //    Console.WriteLine();
                            pTexMtx[index] = (byte)(*pIn++ / 3);
                            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 = RemapSize;
                                while ((--index >= 0) && (RemapTable[index] != mapEntry)) ;

                                //No match, create new entry
                                //Will be processed into vertices at the end!
                                if (index < 0)
                                {
                                    RemapTable[index = RemapSize++] = 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._points[group._points.Count - 1].Add(f);
                }
            }
        }
        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, false, chkPushCacheHits.Checked);
                Facepoint[] points = new Facepoint[a._object._manager._triangles._elementCount];
                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._elementCount; t++)
                    points[ccw ? t : (t - (t % 3)) + (2 - (t % 3))] = a._facepoints[indices[t]];

                int pc, fc;
                List<PrimitiveGroup> p = triConverter.GroupPrimitives(points, out pc, out fc);

                if (chkAllowIncrease.Checked || pc < a._pointCount)
                {
                    a._pointCount = pc;
                    a._faceCount = fc;
                    a._groups = p;
                }

                form._newPointCount += a._pointCount;
            }
            e.Result = form;
        }
示例#9
0
 public FPoint(Facepoint x)
 {
     _x = x;
 }
示例#10
0
 public PointLine(Facepoint x, Facepoint y)
 {
     _x = x;
     _y = y;
 }
 internal void WriteFacepoint(Facepoint f, PrimitiveGroup g, FacepointAttribute[] desc, ref VoidPtr address, MDL0ObjectNode node)
 {
     foreach (FacepointAttribute d in desc)
         switch (d._attr)
         {
             case GXAttribute.PosNrmMtxId:
                 if (d._type == XFDataFormat.Direct)
                     *(byte*)address++ = (byte)(3 * g._nodes.IndexOf(f.NodeID));
                 break;
             case GXAttribute.Tex0MtxId:
             case GXAttribute.Tex1MtxId:
             case GXAttribute.Tex2MtxId:
             case GXAttribute.Tex3MtxId:
             case GXAttribute.Tex4MtxId:
             case GXAttribute.Tex5MtxId:
             case GXAttribute.Tex6MtxId:
             case GXAttribute.Tex7MtxId:
                 if (d._type == XFDataFormat.Direct)
                     *(byte*)address++ = (byte)(30 + (3 * g._nodes.IndexOf(f.NodeID)));
                 break;
             case GXAttribute.Position:
                 switch (d._type)
                 {
                     case XFDataFormat.Direct:
                         byte* addr = (byte*)address;
                         node.Model._linker._vertices[node._elementIndices[0]].Write(ref addr, f._vertexIndex);
                         address = addr;
                         break;
                     case XFDataFormat.Index8:
                         *(byte*)address++ = (byte)f._vertexIndex;
                         break;
                     case XFDataFormat.Index16:
                         *(bushort*)address = (ushort)f._vertexIndex;
                         address += 2;
                         break;
                 }
                 break;
             case GXAttribute.Normal:
                 switch (d._type)
                 {
                     case XFDataFormat.Direct:
                         byte* addr = (byte*)address;
                         node.Model._linker._normals[node._elementIndices[1]].Write(ref addr, f._normalIndex);
                         address = addr;
                         break;
                     case XFDataFormat.Index8:
                         *(byte*)address++ = (byte)f._normalIndex;
                         break;
                     case XFDataFormat.Index16:
                         *(bushort*)address = (ushort)f._normalIndex;
                         address += 2;
                         break;
                 }
                 break;
             case GXAttribute.Color0:
             case GXAttribute.Color1:
                 switch (d._type)
                 {
                     case XFDataFormat.Direct:
                         int index = (int)d._attr - 11;
                         byte* addr = (byte*)address;
                         node.Model._linker._colors[node._elementIndices[index + 2]].Write(ref addr, f._colorIndices[index]);
                         address = addr;
                         break;
                     case XFDataFormat.Index8:
                         if (_polygon._colorChanged[(int)d._attr - (int)GXAttribute.Color0] && _polygon._colorSet[(int)d._attr - (int)GXAttribute.Color0] != null)
                             *(byte*)address++ = 0;
                         else
                             *(byte*)address++ = (byte)f._colorIndices[(int)d._attr - 11];
                         break;
                     case XFDataFormat.Index16:
                         if (_polygon._colorChanged[(int)d._attr - (int)GXAttribute.Color0] && _polygon._colorSet[(int)d._attr - (int)GXAttribute.Color0] != null)
                             *(bushort*)address = 0;
                         else
                             *(bushort*)address = (ushort)f._colorIndices[(int)d._attr - 11];
                         address += 2;
                         break;
                 }
                 break;
             case GXAttribute.Tex0:
             case GXAttribute.Tex1:
             case GXAttribute.Tex2:
             case GXAttribute.Tex3:
             case GXAttribute.Tex4:
             case GXAttribute.Tex5:
             case GXAttribute.Tex6:
             case GXAttribute.Tex7:
                 switch (d._type)
                 {
                     case XFDataFormat.Direct:
                         int index = (int)d._attr - 13;
                         byte* addr = (byte*)address;
                         node.Model._linker._uvs[node._elementIndices[index + 4]].Write(ref addr, f._UVIndices[index]);
                         address = addr;
                         break;
                     case XFDataFormat.Index8:
                         *(byte*)address++ = (byte)f._UVIndices[(int)d._attr - 13];
                         break;
                     case XFDataFormat.Index16:
                         *(bushort*)address = (ushort)f._UVIndices[(int)d._attr - 13];
                         address += 2;
                         break;
                 }
                 break;
         }
 }
        internal Facepoint[] MergeInternalFaceData(MDL0ObjectNode poly)
        {
            Facepoint[] _facepoints = new Facepoint[_pointCount];

            ushort* pIndex = (ushort*)_indices.Address;
            for (int x = 0; x < 12; x++)
            {
                if (_faceData[x] == null && x != 0)
                    continue;

                switch (x)
                {
                    case 0:
                        for (int i = 0; i < _pointCount; i++)
                            if (_vertices.Count != 0)
                            {
                                Facepoint f = _facepoints[i] = new Facepoint() { _index = i };
                                f._vertexIndex = *pIndex++;
                                if (f._vertexIndex < _vertices.Count && f._vertexIndex >= 0)
                                    f._vertex = _vertices[f._vertexIndex];
                            }
                        break;
                    case 1:
                        Vector3* pIn1 = (Vector3*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                            _facepoints[i]._normalIndex = Array.IndexOf(GetNormals(false), *pIn1++);
                        break;
                    case 2:
                    case 3:
                        RGBAPixel* pIn2 = (RGBAPixel*)_faceData[x].Address;
                        if (Collada._importOptions._useOneNode)
                            for (int i = 0; i < _pointCount; i++)
                                _facepoints[i]._colorIndices[x - 2] = Array.IndexOf(Collada._importOptions._singleColorNodeEntries, *pIn2++);
                        else
                            for (int i = 0; i < _pointCount; i++)
                                _facepoints[i]._colorIndices[x - 2] = Array.IndexOf(((MDL0ObjectNode)_polygon.Model._objList[_newClrObj[x - 2]])._manager.GetColors(x - 2, false), *pIn2++);
                        break;
                    default:
                        Vector2* pIn3 = (Vector2*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                            _facepoints[i]._UVIndices[x - 4] = Array.IndexOf(GetUVs(x - 4, false), *pIn3++);
                        break;
                }
            }
            return _facepoints;
        }
        internal Facepoint[] MergeExternalFaceData(MDL0ObjectNode poly)
        {
            Facepoint[] _facepoints = new Facepoint[_pointCount];

            ushort* pIndex = (ushort*)_indices.Address;
            for (int x = 0; x < 12; x++)
            {
                if (poly._elementIndices[x] < 0 && x != 0)
                    continue;

                switch (x)
                {
                    case 0:
                        Vector3* pIn0 = (Vector3*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                        {
                            Facepoint f = _facepoints[i] = new Facepoint() { _index = i };
                            if (_vertices.Count != 0)
                            {
                                ushort id = *pIndex++;
                                if (id < _vertices.Count && id >= 0)
                                    f._vertex = _vertices[id];
                                f._vertexIndex = f._vertex._facepoints[0]._vertexIndex;
                            }
                        }
                        break;
                    case 1:
                        Vector3* pIn1 = (Vector3*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                            _facepoints[i]._normalIndex = Array.IndexOf(poly._normalNode.Normals, *pIn1++);
                        break;
                    case 2:
                    case 3:
                        RGBAPixel* pIn2 = (RGBAPixel*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                            _facepoints[i]._colorIndices[x - 2] = Array.IndexOf(poly._colorSet[x - 2].Colors, *pIn2++);
                        break;
                    default:
                        Vector2* pIn3 = (Vector2*)_faceData[x].Address;
                        for (int i = 0; i < _pointCount; i++)
                            _facepoints[i]._UVIndices[x - 4] = Array.IndexOf(poly._uvSet[x - 4].Points, *pIn3++);
                        break;
                }
            }
            return _facepoints;
        }
        //This should be done after node indices have been assigned
        public override int OnCalculateSize(bool force)
        {
            //Reset everything!
            _tableLen =
            _primitiveStart =
            _primitiveSize =
            _fpStride = 0;

            MDL0Node model = Model;
            if (model._isImport)
            {
                //Continue checking for single bind
                if (_nodeId == -2 && _matrixNode == null)
                {
                    bool first = true;
                    foreach (Vertex3 v in _manager._vertices)
                    {
                        if (first)
                        {
                            if (v._matrixNode != null)
                                MatrixNode = model._linker.NodeCache[v._matrixNode.NodeIndex];

                            first = false;
                        }
                        v.MatrixNode = null;
                    }
                }
            }

            //Collect vertex node ids
            GenerateNodeCache();

            //Recollect indices of linked nodes
            RecalcIndices();

            //Check that the facepoint descriptor matches the linked nodes
            if (!_rebuild)
                _rebuild = CheckVertexFormat();

            //Rebuild only under certain circumstances
            if (model._rebuildAllObj || model._isImport || _rebuild || _reOptimized)
            {
                int size = (int)MDL0Object.Size;

                if (model._version >= 10)
                    size += 4; //Add extra -1 value

                //Set vertex descriptor
                _descList = _manager.SetVertexDescList(this, model._linker._forceDirectAssets);

                //Add table length
                size += _nodeCache.Length * 2 + 4;
                _tableLen = ((size.Align(0x10) + 0xE0) % 0x20 == 0) ? size.Align(0x10) : size.Align(0x20);

                //Add def length
                size = _primitiveStart = _tableLen + 0xE0;

                //Need to group facepoint data if creating a new model
                if (model._isImport)
                {
                    _triConverter._useStrips = Collada._importOptions._useTristrips;
                    _triConverter._cacheSize = Collada._importOptions._cacheSize;
                    _triConverter._minStripLen = Collada._importOptions._minStripLen;
                    _triConverter._pushCacheHits = Collada._importOptions._pushCacheHits;
                    _triConverter._backwardSearch = Collada._importOptions._backwardSearch;

                    _primGroups.Clear();

                    //Merge vertices and assets into facepoints
                    Facepoint[] facepoints = _manager.MergeInternalFaceData(this);
                    if (_manager._triangles != null)
                    {
                        Facepoint[] points = new Facepoint[_manager._triangles._elementCount];
                        uint[] indices = _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 < _manager._triangles._elementCount; t++)
                            points[ccw ? t : (t - (t % 3)) + (2 - (t % 3))] = facepoints[indices[t]];

                        _primGroups = _triConverter.GroupPrimitives(points, out _numFacepoints, out _numFaces);
                    }
                }

                //Build display list
                foreach (PrimitiveGroup g in _primGroups)
                {
                    if (model._isImport || _reOptimized)
                    {
                        if (g._tristrips.Count != 0)
                            foreach (PointTriangleStrip strip in g._tristrips)
                                _primitiveSize += 3 + strip._points.Count * _fpStride;

                        if (g._triangles.Count != 0)
                            _primitiveSize += 3 + g._triangles.Count * 3 * _fpStride;
                    }
                    else
                        for (int i = 0; i < g._headers.Count; i++)
                            _primitiveSize += 3 + g._points[i].Count * _fpStride;

                    if (Weighted)
                        _primitiveSize += 5 * g._nodes.Count * (HasTexMtx ? 3 : 2); //Add total matrices size
                }

                size += _primitiveSize;
                int align = ((size.Align(0x10)) % 0x20 == 0) ? 0x10 : 0x20;
                size = size.Align(align);
                _primitiveSize = _primitiveSize.Align(align);

                //Texture matrices (0x30) start at 0x00, max 11
                //Pos matrices (0x20) start at 0x78, max 10
                //Normal matrices (0x28) start at 0x400, max 10

                return size;
            }
            else
                return base.OnCalculateSize(force);
        }