Example #1
0
        private static float ReadValue(ref VoidPtr addr, WiiVertexComponentType type, float divisor)
        {
            switch (type)
            {
            case WiiVertexComponentType.UInt8:
                addr += 1;
                return(((byte *)addr)[-1] / divisor);

            case WiiVertexComponentType.Int8:
                addr += 1;
                return(((sbyte *)addr)[-1] / divisor);

            case WiiVertexComponentType.UInt16:
                addr += 2;
                return(((bushort *)addr)[-1] / divisor);

            case WiiVertexComponentType.Int16:
                addr += 2;
                return(((bshort *)addr)[-1] / divisor);

            case WiiVertexComponentType.Float:
                addr += 4;
                return(((bfloat *)addr)[-1]);
            }
            return(0.0f);
        }
Example #2
0
        public static UnsafeBuffer Decode(VoidPtr data, byte divisor, uint length, WiiVertexComponentType componentType,
                                          bool UVs, int isSpecial)
        {
            float          scale   = VQuant.DeQuantTable[divisor];
            int            type    = isSpecial * 5 + (UVs ? 0 : 10) + (int)componentType;
            ElementDecoder decoder = ElementCodec.Decoders[type];

            int bytesPerVal = (UVs ? isSpecial + 1 : isSpecial + 2) * (componentType < WiiVertexComponentType.UInt16
                ? 1
                : componentType < WiiVertexComponentType.Float
                    ? 2
                    : 4);

            int count = (int)(length / bytesPerVal);

            UnsafeBuffer buffer = new UnsafeBuffer(count * (UVs ? 8 : 12));

            byte *pIn = (byte *)data, pOut = (byte *)buffer.Address;

            for (int i = 0; i < count; i++)
            {
                decoder(ref pIn, ref pOut, scale);
            }

            return(buffer);
        }
Example #3
0
        private static Vector2[] ExtractPoints(VoidPtr address, int count, WiiVertexComponentType type, float divisor)
        {
            Vector2[] points = new Vector2[count];

            fixed(Vector2 *p = points)
            {
                float *dPtr = (float *)p;

                for (int i = 0; i < count; i++)
                {
                    *dPtr++ = ReadValue(ref address, type, divisor);
                    *dPtr++ = ReadValue(ref address, type, divisor);
                }
            }

            return(points);
        }
        private void Evaluate(bool removeZ)
        {
            float* fPtr;
            int bestScale = 0;
            bool sign;

            Vector3 min = new Vector3(float.MaxValue), max = new Vector3(float.MinValue);
            float* pMin = (float*)&min, pMax = (float*)&max;
            float vMin = float.MaxValue, vMax = float.MinValue, vDist;
            float val;

            //Currently, remapping provides to benefit for vertices/normals
            //Maybe when merging is supported this will change

            _remap = new Remapper();
            //if (_srcElements == 3)
            //    _remap.Remap<Vector3>(new MemoryList<Vector3>(_pData, _srcCount), null);
            //if (_srcElements == 2)
            //    _remap.Remap<Vector2>(new MemoryList<Vector2>(_pData, _srcCount), null);

            int[] imp = null;
            int impLen = _srcCount;

            //Remapping is useless if there is no savings
            if (_remap._impTable != null && _remap._impTable.Length < _srcCount)
            {
                imp = _remap._impTable;
                impLen = imp.Length;
            }

            _min = new Vector3(float.MaxValue);
            _max = new Vector3(float.MinValue);
            _dstCount = impLen;
            _type = 0;

            //Get extents
            fPtr = _pData;
            for (int i = 0; i < impLen; i++)
            {
                if (imp != null)
                    fPtr = &_pData[imp[i] * _srcElements];
                for (int x = 0; x < _srcElements; x++)
                {
                    val = *fPtr++;
                    if (val < pMin[x]) pMin[x] = val;
                    if (val > pMax[x]) pMax[x] = val;
                    if (val < vMin) vMin = val;
                    if (val > vMax) vMax = val;
                }
            }

            _min = min;
            _max = max;
            if (removeZ && (_srcElements == 3) && (min._z == 0) && (max._z == 0))
                _dstElements = 2;
            else
                _dstElements = _srcElements;

            _hasZ = _dstElements > 2;

            vDist = Math.Max(Math.Abs(vMin), Math.Abs(vMax));

            if (!_forceFloat)
            {
                //Is signed? If so, increase type
                if (sign = (vMin < 0))
                    _type++;

                int divisor = 0;
                float rMin = 0.0f, rMax;
                for (int i = 0; i < 2; i++)
                {
                    float bestError = _maxError;
                    float scale, maxVal;

                    if (i == 0)
                        if (sign)
                        { rMax = 127.0f; rMin = -128.0f; }
                        else
                            rMax = 255.0f;
                    else
                        if (sign)
                        { rMax = 32767.0f; rMin = -32768.0f; }
                        else
                            rMax = 65535.0f;

                    maxVal = rMax / vDist;
                    while ((divisor < 32) && ((scale = VQuant.QuantTable[divisor]) <= maxVal))
                    {
                        float worstError = float.MinValue;

                        fPtr = _pData;
                        for (int y = 0; y < impLen; y++)
                        {
                            if (imp != null)
                                fPtr = &_pData[imp[i] * _srcElements];
                            for (int z = 0; z < _srcElements; z++)
                            {
                                if ((val = *fPtr++) == 0)
                                    continue;

                                val *= scale;
                                if (val > rMax) val = rMax;
                                else if (val < rMin) val = rMin;

                                int step = (int)((val * scale));
                                //int step = (int)((val * scale) + (val > 0 ? 0.5f : -0.5f));
                                float error = Math.Abs((step / scale) - val);

                                if (error > worstError)
                                    worstError = error;

                                if (error > bestError)
                                    goto Check;
                            }
                        }

                        //for (fPtr = sPtr; fPtr < fCeil; )
                    //{
                    //    if ((val = *fPtr++) == 0)
                    //        continue;

                        //    val *= scale;
                    //    if (val > rMax) val = rMax;
                    //    else if (val < rMin) val = rMin;

                        //    int step = (int)((val * scale);// + (val > 0 ? 0.5f : -0.5f));
                    //    float error = Math.Abs((step / scale) - val);

                        //    if (error > worstError)
                    //        worstError = error;

                        //    if (error > bestError)
                    //        break;
                    //}

                    Check:

                        if (worstError < bestError)
                        {
                            bestScale = divisor;
                            bestError = worstError;
                            if (bestError == 0)
                                goto Next;
                        }

                        divisor++;
                    }

                    if (bestError < _maxError)
                        goto Next;

                    _type += 2;
                }
            }

            _type = WiiVertexComponentType.Float;
            _scale = 0;

            Next:

            _scale = bestScale;
            _dstStride = _dstElements << ((int)_type >> 1);
            _dataLen = _dstCount * _dstStride;

            _quantScale = VQuant.QuantTable[_scale];
            GetEncoder();
        }
Example #5
0
        private static Vector3[] ExtractVertices(VoidPtr address, int count, bool isXYZ, WiiVertexComponentType type, float divisor)
        {
            Vector3[] verts = new Vector3[count];
            fixed(Vector3 *p = verts)
            {
                float *dPtr = (float *)p;

                for (int i = 0; i < count; i++)
                {
                    *dPtr++ = ReadValue(ref address, type, divisor);
                    *dPtr++ = ReadValue(ref address, type, divisor);
                    if (isXYZ)
                    {
                        *dPtr++ = ReadValue(ref address, type, divisor);
                    }
                    else
                    {
                        *dPtr++ = 0.0f;
                    }
                }
            }

            return(verts);
        }
Example #6
0
        private void Evaluate(bool removeZ)
        {
            float *fPtr;
            int    bestScale = 0;
            bool   sign;

            Vector3 min = new Vector3(float.MaxValue), max = new Vector3(float.MinValue);
            float * pMin = (float *)&min, pMax = (float *)&max;
            float   vMin = float.MaxValue, vMax = float.MinValue, vDist;
            float   val;

            //Currently, remapping provides to benefit for vertices/normals
            //Maybe when merging is supported this will change

            _remap = new Remapper();
            //if (_srcElements == 3)
            //    _remap.Remap<Vector3>(new MemoryList<Vector3>(_pData, _srcCount), null);
            //if (_srcElements == 2)
            //    _remap.Remap<Vector2>(new MemoryList<Vector2>(_pData, _srcCount), null);

            int[] imp    = null;
            int   impLen = _srcCount;

            //Remapping is useless if there is no savings
            if (_remap._impTable != null && _remap._impTable.Length < _srcCount)
            {
                imp    = _remap._impTable;
                impLen = imp.Length;
            }

            _min      = new Vector3(float.MaxValue);
            _max      = new Vector3(float.MinValue);
            _dstCount = impLen;
            _type     = 0;

            //Get extents
            fPtr = _pData;
            for (int i = 0; i < impLen; i++)
            {
                if (imp != null)
                {
                    fPtr = &_pData[imp[i] * _srcElements];
                }
                for (int x = 0; x < _srcElements; x++)
                {
                    val = *fPtr++;
                    if (val < pMin[x])
                    {
                        pMin[x] = val;
                    }
                    if (val > pMax[x])
                    {
                        pMax[x] = val;
                    }
                    if (val < vMin)
                    {
                        vMin = val;
                    }
                    if (val > vMax)
                    {
                        vMax = val;
                    }
                }
            }

            _min = min;
            _max = max;
            if (removeZ && (_srcElements == 3) && (min._z == 0) && (max._z == 0))
            {
                _dstElements = 2;
            }
            else
            {
                _dstElements = _srcElements;
            }

            _hasZ = _dstElements > 2;

            vDist = Math.Max(Math.Abs(vMin), Math.Abs(vMax));

            if (!_forceFloat)
            {
                //Is signed? If so, increase type
                if (sign = (vMin < 0))
                {
                    _type++;
                }

                int   divisor = 0;
                float rMin = 0.0f, rMax;
                for (int i = 0; i < 2; i++)
                {
                    float bestError = _maxError;
                    float scale, maxVal;

                    if (i == 0)
                    {
                        if (sign)
                        {
                            rMax = 127.0f; rMin = -128.0f;
                        }
                        else
                        {
                            rMax = 255.0f;
                        }
                    }
                    else
                    if (sign)
                    {
                        rMax = 32767.0f; rMin = -32768.0f;
                    }
                    else
                    {
                        rMax = 65535.0f;
                    }

                    maxVal = rMax / vDist;
                    while ((divisor < 32) && ((scale = VQuant.QuantTable[divisor]) <= maxVal))
                    {
                        float worstError = float.MinValue;

                        fPtr = _pData;
                        for (int y = 0; y < impLen; y++)
                        {
                            if (imp != null)
                            {
                                fPtr = &_pData[imp[i] * _srcElements];
                            }
                            for (int z = 0; z < _srcElements; z++)
                            {
                                if ((val = *fPtr++) == 0)
                                {
                                    continue;
                                }

                                val *= scale;
                                if (val > rMax)
                                {
                                    val = rMax;
                                }
                                else if (val < rMin)
                                {
                                    val = rMin;
                                }

                                int step = (int)((val * scale));
                                //int step = (int)((val * scale) + (val > 0 ? 0.5f : -0.5f));
                                float error = Math.Abs((step / scale) - val);

                                if (error > worstError)
                                {
                                    worstError = error;
                                }

                                if (error > bestError)
                                {
                                    goto Check;
                                }
                            }
                        }

                        //for (fPtr = sPtr; fPtr < fCeil; )
                        //{
                        //    if ((val = *fPtr++) == 0)
                        //        continue;

                        //    val *= scale;
                        //    if (val > rMax) val = rMax;
                        //    else if (val < rMin) val = rMin;

                        //    int step = (int)((val * scale);// + (val > 0 ? 0.5f : -0.5f));
                        //    float error = Math.Abs((step / scale) - val);

                        //    if (error > worstError)
                        //        worstError = error;

                        //    if (error > bestError)
                        //        break;
                        //}

Check:

                        if (worstError < bestError)
                        {
                            bestScale = divisor;
                            bestError = worstError;
                            if (bestError == 0)
                            {
                                goto Next;
                            }
                        }

                        divisor++;
                    }

                    if (bestError < _maxError)
                    {
                        goto Next;
                    }

                    _type += 2;
                }
            }

            _type  = WiiVertexComponentType.Float;
            _scale = 0;

Next:

            _scale     = bestScale;
            _dstStride = _dstElements << ((int)_type >> 1);
            _dataLen   = _dstCount * _dstStride;

            _quantScale = VQuant.QuantTable[_scale];
            GetEncoder();
        }