Ejemplo n.º 1
0
 //�Public�Methods�(1)
 /// <summary>
 /// Copy data to other NSBMD material
 /// </summary>
 /// <param name="other">Other NSBMD material.</param>
 public void CopyTo(NsbmdMaterial other)
 {
     other.texname = texname;
     other.texoffset = texoffset;
     other.texsize = texsize;
     other.format = format;
     other.color0 = color0;
     other.width = width;
     other.height = height;
     other.texdata = texdata;
     other.spdata = spdata;
 }
Ejemplo n.º 2
0
 //�Public�Methods�(1)
 /// <summary>
 /// Copy data to other NSBMD material
 /// </summary>
 /// <param name="other">Other NSBMD material.</param>
 public NsbmdMaterial CopyTo(NsbmdMaterial other1)
 {
     NsbmdMaterial other = other1;
     other.texname = texname;
     other.texoffset = texoffset;
     other.texsize = texsize;
     other.format = format;
     other.color0 = color0;
     other.width = width;
     other.height = height;
     other.texdata = texdata;
     other.spdata = spdata;
     other.MaterialName = MaterialName;
     return other;
 }
Ejemplo n.º 3
0
        //�Public�Methods�(1)�

        /// <summary>
        /// Copy data to other NSBMD material
        /// </summary>
        /// <param name="other">Other NSBMD material.</param>
        public NsbmdMaterial CopyTo(NsbmdMaterial other1)
        {
            NsbmdMaterial other = other1;

            other.texname      = texname;
            other.texoffset    = texoffset;
            other.texsize      = texsize;
            other.format       = format;
            other.color0       = color0;
            other.width        = width;
            other.height       = height;
            other.texdata      = texdata;
            other.spdata       = spdata;
            other.MaterialName = MaterialName;
            return(other);
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable<NsbmdMaterial> ReadTex0(Stream stream, int blockoffset, out int ptexnum, out int ppalnum, out List<NSBMDTexture> texs, out List<NSBMDPalette> pals)
        {
            EndianBinaryReader reader = new EndianBinaryReader(stream, Endianness.LittleEndian);
            UInt32 blocksize, blockptr, blocklimit;
            int texnum;
            UInt32 texdataoffset;
            int texdatasize;
            UInt32 sptexoffset; // for 4x4 compressed texels only
            int sptexsize; // for 4x4 compressed texels only
            UInt32 spdataoffset; // for 4x4 compressed texels only
            int palnum;
            UInt32 paldefoffset;
            UInt32 paldataoffset;
            int paldatasize;
            NsbmdMaterial[] material = null;
            int i, j;
            texs = new List<NSBMDTexture>();
            pals = new List<NSBMDPalette>();

            blockptr = (uint)(blockoffset + 4); // already read the block ID, so skip 4 bytes
            blocksize = reader.ReadUInt32(); // block size
            blocklimit = (uint)(blocksize + blockoffset);
            Console.WriteLine("DEBUG: blockoffset = {0}, blocksize = {1}", blockoffset, blocksize);

            stream.Skip(4); // skip 4 padding 0s
            texdatasize = reader.ReadUInt16() << 3; // total texture data size div8
            stream.Skip(6); // skip 6 bytes
            texdataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            stream.Skip(4); // skip 4 padding 0s
            sptexsize = reader.ReadUInt16() << 3; // for format 5 4x4-texel, data size div8
            stream.Skip(6); // skip 6 bytesmhm
            sptexoffset = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, data offset
            spdataoffset = (uint)(reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, palette info

            stream.Skip(4); // skip 4 bytes
            paldatasize = reader.ReadUInt16() << 3; // total palette data size div8
            stream.Skip(2); // skip 2 bytes
            paldefoffset = (uint)(reader.ReadUInt32() + blockoffset);
            paldataoffset = (uint)(reader.ReadUInt32() + blockoffset);

            //	printf( "texdataoffset = %08x texdatasize = %08x\n", texdataoffset, texdatasize );
            //	printf( "sptexoffset = %08x sptexsize = %08x spdataoffset = %08x\n", sptexoffset, sptexsize, spdataoffset );
            //	printf( "paldataoffset = %08x paldatasize = %08x\n", paldataoffset, paldatasize );

            ////////////////////////////////////////////////
            // texture definition

            stream.Skip(1); // skip dummy '0'
            texnum = reader.ReadByte(); // no of texture
            blockptr = (uint)stream.Position;
            stream.Seek(paldefoffset, SeekOrigin.Begin);
            stream.Skip(1); // skip dummy '0'
            palnum = reader.ReadByte(); // no of palette
            stream.Seek(blockptr, SeekOrigin.Begin);

            Console.WriteLine("texnum = {0}, palnum = {1}", texnum, palnum);

            // allocate memory for material, great enough to hold all texture and palette
            material = new NsbmdMaterial[(texnum > palnum ? texnum : palnum)];
            for (i = 0; i < material.Length; i++)
                material[i] = new NsbmdMaterial();

            stream.Skip(14 + (texnum * 4)); // go straight to texture info

            for (i = 0; i < texnum; i++)
            {
                UInt32 offset;
                int param;
                int format;
                int width;
                int height;

                var mat = material[i];

                offset = (uint)(reader.ReadUInt16() << 3);
                param = reader.ReadUInt16(); // texture parameter
                stream.Skip(4); // skip 4 bytes

                format = (param >> 10) & 7; // format 0..7, see DSTek
                width = 8 << ((param >> 4) & 7);
                height = 8 << ((param >> 7) & 7);
                mat.color0 = (param >> 13) & 1;

                if (format == 5)
                    mat.texoffset = offset + sptexoffset; // 4x4-Texel Compressed Texture
                else
                    mat.texoffset = offset + texdataoffset;

                mat.format = format;
                mat.width = width;
                mat.height = height;
                NSBMDTexture t = new NSBMDTexture();
                t.format = format;
                t.width = width;
                t.height = height;
                t.color0 = (param >> 13) & 1;
                texs.Add(t);
            }

            ////////////////////////////////////////////
            // copy texture names
            for (i = 0; i < texnum; i++)
            {
                material[i].texname = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                texs[i].texname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each texture's size
            for (i = 0; i < texnum; i++)
            {
                int[] bpp = { 0, 8, 2, 4, 8, 2, 8, 16 };

                var mat = material[i];
                mat.texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
                Console.WriteLine("tex {0} '{1}': offset = {2} size = {3} [W,H] = [{4}, {5}]",
                                  i, mat.texname, mat.texoffset, mat.texsize, mat.width, mat.height);
                texs[i].texsize = (uint)(mat.width * mat.height * bpp[mat.format] / 8);
            }

            ////////////////////////////////////////////////
            // palette definition
            stream.Seek(paldefoffset + 2, SeekOrigin.Begin); // skip palnum, already read
            stream.Seek(14 + (palnum * 4), SeekOrigin.Current); // go straight to palette info
            for (i = 0; i < palnum; i++)
            {
                uint curOffset = (uint)((reader.ReadUInt16() << 3) + paldataoffset);
                stream.Seek(2, SeekOrigin.Current); // skip 2 bytes
                material[i].paloffset = curOffset;
                NSBMDPalette t = new NSBMDPalette();
                t.paloffset = curOffset;
                pals.Add(t);
            }

            ////////////////////////////////////////////////
            // copy palette names
            for (i = 0; i < palnum; i++)
            {
                var mat = material[i];
                mat.palname = Utils.ReadNSBMDString(reader);
                reader.BaseStream.Position -= 16;
                pals[i].palname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each palette's size
            // assume the palettes are stored sequentially
            /*for (i = 0; i < palnum - 1; i++)
            {
                int r;
                var mat = material[i];
                r = i;
                try { while (material[r].paloffset == mat.paloffset) r++; }
                catch { }
                // below is RotA stupid way to calculate the size of palette: next's offset - current's offset
                // it works most of the time
                if (r != palnum)
                {
                    mat.palsize = material[r].paloffset - mat.paloffset;
                    pals[i].palsize = material[r].paloffset - mat.paloffset;
                }
                else
                {
                    mat.palsize = blocklimit - mat.paloffset;
                    pals[i].palsize = blocklimit - mat.paloffset;
                }
                //printf("pal '%s' size = %d\n", mat->palname, mat->palsize);
            }
            material[i].palsize = blocklimit - material[i].paloffset;
            pals[i].palsize = blocklimit - material[i].paloffset;*/
            List<int> offsets = new List<int>();
            for (int k = 0; k < pals.Count; k++)
            {
                if (!offsets.Contains((int)pals[k].paloffset))
                {
                    offsets.Add((int)pals[k].paloffset);
                }
            }
            offsets.Add((int)blocklimit);
            offsets.Sort();
            for (int k = 0; k < pals.Count; k++)
            {
                int pallength;
                int l = -1;
                do
                {
                    l++;
                }
                while (offsets[l] - pals[k].paloffset <= 0);//nsbtx.PalInfo.infoBlock.PalInfo[i + j].Palette_Offset - nsbtx.PalInfo.infoBlock.PalInfo[i].Palette_Offset == 0)
                pallength = offsets[l] - (int)pals[k].paloffset;
                //RGBA[] c_ = pals[k].paldata;
                //List<RGBA> c = new List<RGBA>();
                //c.AddRange(pals[k].paldata.Take(pallength / 2));
                //pals[k].paldata = c.ToArray();
                pals[k].palsize = (uint)pallength;
                material[k].palsize = (uint)pallength;
            }

            ////////////////////////////////////////////////
            // traverse each texture
            for (i = 0; i < texnum; i++)
            {
                var mat = material[i];
                stream.Seek(mat.texoffset, SeekOrigin.Begin);

                ////////////////////////////////////////////////
                // read texture into memory
                byte[] by = reader.ReadBytes((int)mat.texsize);
                mat.texdata = by;
                texs[i].texdata = by;

                Console.WriteLine("DEBUG: texoffset = {0}, texsize = {1}", mat.texoffset, mat.texsize);

                ////////////////////////////////////////////////
                // additional data for format 5 4x4 compressed texels
                if (mat.format == 5)
                {
                    UInt32 r = mat.texsize / 2;//>> 1;
                    stream.Seek(spdataoffset + (mat.texoffset - sptexoffset) / 2, SeekOrigin.Begin);

                    by = reader.ReadBytes((int)r);
                    mat.spdata = by;
                    texs[i].spdata = by;
                    Console.WriteLine("DEBUG: 4x4-texel spdataoffset = {0}, spdatasize = {1}", spdataoffset, r);

                    //spdataoffset += r;
                }
            }

            ////////////////////////////////////////////////
            // traverse each palette
            for (i = 0; i < palnum; i++)
            {
                try
                {
                    NsbmdMaterial mat = material[i];
                    var palentry = mat.palsize >> 1;

                    RGBA[] rgbq = new RGBA[palentry];

                    Console.WriteLine("DEBUG: converting pal '{0}', palentry = {1}", mat.palname, palentry);

                    stream.Seek(mat.paloffset, SeekOrigin.Begin);
                    for (j = 0; j < palentry; j++)
                    {
                        UInt16 p = reader.ReadUInt16();
                        rgbq[j].R = (byte)(((p >> 0) & 0x1f) << 3); // red
                        rgbq[j].G = (byte)(((p >> 5) & 0x1f) << 3); // green
                        rgbq[j].B = (byte)(((p >> 10) & 0x1f) << 3); // blue
                        //rgbq[j].RotA = (p&0x8000) ? 0xff : 0;
                        rgbq[j].A = (p & 0x8000) == 0 ? (byte)0xff : (byte)0;//0xff; // alpha
                    }
                    mat.paldata = rgbq;
                    pals[i].paldata = rgbq;
                }
                catch
                {
                }
            }

            ptexnum = texnum;
            ppalnum = palnum;

            return material;
        }
Ejemplo n.º 5
0
        private MKDS_Course_Editor.Export3DTools.Group Process3DCommandRipper(byte[] polydata, NsbmdMaterial m, int jointID, bool color)
        {
            MKDS_Course_Editor.Export3DTools.Group group = new MKDS_Course_Editor.Export3DTools.Group();
            Vector3 item = new Vector3(float.NaN, 0f, 0f);
            System.Drawing.Color white = System.Drawing.Color.White;
            Vector2 vector2 = new Vector2(float.NaN, 0f);
            List<Vector3> list = new List<Vector3>();
            List<Vector3> list2 = new List<Vector3>();
            List<Vector2> list3 = new List<Vector2>();
            int num = -1;
            if (polydata != null)
            {
                int index = 0;
                int length = polydata.Length;
                int[] numArray = new int[4];
                float[] numArray4 = new float[3];
                float[] v = numArray4;
                numArray4 = new float[3];
                float[] numArray3 = numArray4;
                int gCurrentVertex = NsbmdGlRenderer.gCurrentVertex;
                if (this.Model.Objects.Count > 0)
                {
                    CurrentMatrix = MatrixStack[stackID].Clone();
                }
                else
                {
                    CurrentMatrix.LoadIdentity();
                }
                if (this.Model.Objects.Count > 1)
                {
                }
                while (index < length)
                {
                    int num7 = 0;
                    while (num7 < 4)
                    {
                        if (index >= length)
                        {
                            numArray[num7] = 0xff;
                        }
                        else
                        {
                            numArray[num7] = polydata[index];
                            index++;
                        }
                        num7++;
                    }
                    for (num7 = 0; (num7 < 4) && (index < length); num7++)
                    {
                        int num6;
                        int num8;
                        int num9;
                        int num10;
                        MTX44 mtx;
                        int num11;
                        int num12;
                        int num13;
                        int num26;
                        switch (numArray[num7])
                        {
                            case 0x70:
                                {
                                    index += 12;
                                    continue;
                                }
                            case 0x71:
                                {
                                    index += 8;
                                    continue;
                                }
                            case 0x72:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x60:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 80:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0:
                            case 1:
                            case 2:
                            case 3:
                            case 4:
                            case 5:
                            case 6:
                            case 7:
                            case 8:
                            case 9:
                            case 10:
                            case 11:
                            case 12:
                            case 13:
                            case 14:
                            case 15:
                            case 0x1d:
                            case 30:
                            case 0x1f:
                            case 0x2c:
                            case 0x2d:
                            case 0x2e:
                            case 0x2f:
                            case 0x11:
                                {
                                    continue;
                                }
                            case 0x10:
                                {
                                    num8 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    continue;
                                }
                            case 0x12:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x13:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 20:
                                {
                                    stackID = Utils.Read4BytesAsInt32(polydata, index) & 0x1f;
                                    index += 4;
                                    MatrixStack[stackID].CopyValuesTo(CurrentMatrix);
                                    continue;
                                }
                            case 0x15:
                                {
                                    CurrentMatrix.LoadIdentity();
                                    continue;
                                }
                            case 0x16:
                                {
                                    num9 = 0;
                                    while (num9 < 0x10)
                                    {
                                        CurrentMatrix[num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f;
                                        index += 4;
                                        num9++;
                                    }
                                    continue;
                                }
                            case 0x17:
                                num9 = 0;
                                goto Label_039C;

                            case 0x18:
                                mtx = new MTX44();
                                mtx.LoadIdentity();
                                num9 = 0;
                                goto Label_03E8;

                            case 0x19:
                                mtx = new MTX44();
                                mtx.LoadIdentity();
                                num9 = 0;
                                goto Label_0466;

                            case 0x1a:
                                mtx = new MTX44();
                                mtx.LoadIdentity();
                                num9 = 0;
                                goto Label_04E3;

                            case 0x1b:
                                {
                                    num11 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num12 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num13 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    CurrentMatrix.Scale((((float)num11) / 4096f) / this.Model.modelScale, (((float)num12) / 4096f) / this.Model.modelScale, (((float)num13) / 4096f) / this.Model.modelScale);
                                    continue;
                                }
                            case 0x1c:
                                {
                                    num11 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num12 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num13 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    CurrentMatrix.translate((((float)sign(num11, 0x20)) / 4096f) / this.Model.modelScale, (((float)sign(num12, 0x20)) / 4096f) / this.Model.modelScale, (((float)sign(num13, 0x20)) / 4096f) / this.Model.modelScale);
                                    continue;
                                }
                            case 0x20:
                                {
                                    long num14 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    if (gOptColoring)
                                    {
                                        long num15 = num14 & 0x1fL;
                                        long num16 = (num14 >> 5) & 0x1fL;
                                        long num17 = (num14 >> 10) & 0x1fL;
                                        if (color)
                                        {
                                            white = System.Drawing.Color.FromArgb((int)(((float)m.Alpha) / 31f), (int)(((float)num15) / 31f), (int)(((float)num16) / 31f), (int)(((float)num17) / 31f));
                                        }
                                    }
                                    continue;
                                }
                            case 0x21:
                                {
                                    long num18 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    long num19 = num18 & 0x3ffL;
                                    if ((num19 & 0x200L) != 0L)
                                    {
                                        num19 |= -1024L;
                                    }
                                    long num20 = (num18 >> 10) & 0x3ffL;
                                    if ((num20 & 0x200L) != 0L)
                                    {
                                        num20 |= -1024L;
                                    }
                                    long num21 = (num18 >> 20) & 0x3ffL;
                                    if ((num21 & 0x200L) != 0L)
                                    {
                                        num21 |= -1024L;
                                    }
                                    item = new Vector3(((float)num19) / 512f, ((float)num20) / 512f, ((float)num21) / 512f);
                                    continue;
                                }
                            case 0x22:
                                {
                                    long num22 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    long num23 = num22 & 0xffffL;
                                    if ((num23 & 0x8000L) != 0L)
                                    {
                                        num23 |= -65536L;
                                    }
                                    long num24 = (num22 >> 0x10) & 0xffffL;
                                    if ((num24 & 0x8000L) != 0L)
                                    {
                                        num24 |= -65536L;
                                    }
                                    vector2 = new Vector2(((m.scaleS / ((float)m.width)) * (((float)num23) / 16f)) / ((float)(m.flipS + 1)), (-(m.scaleT / ((float)m.height)) * (((float)num24) / 16f)) / ((float)(m.flipT + 1)));
                                    continue;
                                }
                            case 0x23:
                                {
                                    int num25 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num11 = sign(num25 & 0xffff, 0x10);
                                    num12 = sign((num25 >> 0x10) & 0xffff, 0x10);
                                    num25 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num13 = sign(num25 & 0xffff, 0x10);
                                    v[0] = ((float)num11) / 4096f;
                                    v[1] = ((float)num12) / 4096f;
                                    v[2] = ((float)num13) / 4096f;
                                    if (stackID == -1)
                                    {
                                        goto Label_08E2;
                                    }
                                    numArray3 = CurrentMatrix.MultVector(v);
                                    list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                    list2.Add(item);
                                    list3.Add(vector2);
                                    goto Label_090F;
                                }
                            case 0x24:
                                num26 = Utils.Read4BytesAsInt32(polydata, index);
                                index += 4;
                                num11 = sign(num26 & 0x3ff, 10);
                                num12 = sign((num26 >> 10) & 0x3ff, 10);
                                num13 = sign((num26 >> 20) & 0x3ff, 10);
                                v[0] = ((float)num11) / 64f;
                                v[1] = ((float)num12) / 64f;
                                v[2] = ((float)num13) / 64f;
                                if (stackID == -1)
                                {
                                    goto Label_09E1;
                                }
                                numArray3 = CurrentMatrix.MultVector(v);
                                list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                list2.Add(item);
                                list3.Add(vector2);
                                goto Label_0A0E;

                            case 0x25:
                                {
                                    int num27 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num11 = sign(num27 & 0xffff, 0x10);
                                    num12 = sign((num27 >> 0x10) & 0xffff, 0x10);
                                    v[0] = ((float)num11) / 4096f;
                                    v[1] = ((float)num12) / 4096f;
                                    if (stackID == -1)
                                    {
                                        goto Label_0ABF;
                                    }
                                    numArray3 = CurrentMatrix.MultVector(v);
                                    list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                    list2.Add(item);
                                    list3.Add(vector2);
                                    goto Label_0AEC;
                                }
                            case 0x26:
                                {
                                    int num28 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num11 = sign(num28 & 0xffff, 0x10);
                                    num13 = sign((num28 >> 0x10) & 0xffff, 0x10);
                                    v[0] = ((float)num11) / 4096f;
                                    v[2] = ((float)num13) / 4096f;
                                    if (stackID == -1)
                                    {
                                        goto Label_0B9D;
                                    }
                                    numArray3 = CurrentMatrix.MultVector(v);
                                    list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                    list2.Add(item);
                                    list3.Add(vector2);
                                    goto Label_0BCA;
                                }
                            case 0x27:
                                {
                                    int num29 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    num12 = sign(num29 & 0xffff, 0x10);
                                    num13 = sign((num29 >> 0x10) & 0xffff, 0x10);
                                    v[1] = ((float)num12) / 4096f;
                                    v[2] = ((float)num13) / 4096f;
                                    if (stackID == -1)
                                    {
                                        goto Label_0C7B;
                                    }
                                    numArray3 = CurrentMatrix.MultVector(v);
                                    list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                    list2.Add(item);
                                    list3.Add(vector2);
                                    goto Label_0CA8;
                                }
                            case 40:
                                num26 = Utils.Read4BytesAsInt32(polydata, index);
                                index += 4;
                                num11 = sign(num26 & 0x3ff, 10);
                                num12 = sign((num26 >> 10) & 0x3ff, 10);
                                num13 = sign((num26 >> 20) & 0x3ff, 10);
                                v[0] += ((float)num11) / 4096f;
                                v[1] += ((float)num12) / 4096f;
                                v[2] += ((float)num13) / 4096f;
                                if (stackID == -1)
                                {
                                    goto Label_0DAA;
                                }
                                numArray3 = CurrentMatrix.MultVector(v);
                                list.Add(new Vector3(numArray3[0], numArray3[1], numArray3[2]));
                                list2.Add(item);
                                list3.Add(vector2);
                                goto Label_0DD7;

                            case 0x29:
                                {
                                    num8 = Utils.Read4BytesAsInt32(polydata, index);
                                    index += 4;
                                    continue;
                                }
                            case 0x2a:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x2b:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x30:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x31:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 50:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x33:
                                {
                                    index += 4;
                                    continue;
                                }
                            case 0x34:
                                {
                                    index += 0x80;
                                    continue;
                                }
                            case 0x40:
                                num6 = Utils.Read4BytesAsInt32(polydata, index);
                                index += 4;
                                num = num6;
                                switch (num6)
                                {
                                    case 0:
                                        goto Label_0E92;

                                    case 1:
                                        goto Label_0E97;

                                    case 2:
                                        goto Label_0E9C;

                                    case 3:
                                        goto Label_0EA1;
                                }
                                throw new Exception();

                            case 0x41:
                                switch (num)
                                {
                                    case 0:
                                        goto Label_0ED1;

                                    case 1:
                                        goto Label_0EF6;

                                    case 2:
                                        goto Label_0F1B;

                                    case 3:
                                        goto Label_0F40;
                                }
                                goto Label_0F67;

                            default:
                                {
                                    continue;
                                }
                        }
                    Label_0358:
                        num10 = 0;
                        while (num10 < 3)
                        {
                            CurrentMatrix[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f;
                            index += 4;
                            num9++;
                        }
                        num9++;
                    Label_039C:
                        if (num9 < 4)
                        {
                            goto Label_0358;
                        }
                        continue;
                    Label_03C1:
                        mtx[num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f;
                        index += 4;
                        num9++;
                    Label_03E8:
                        if (num9 < 0x10)
                        {
                            goto Label_03C1;
                        }
                        CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix);
                        continue;
                    Label_0425:
                        num10 = 0;
                        while (num10 < 3)
                        {
                            mtx[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f;
                            index += 4;
                            num9++;
                        }
                        num9++;
                    Label_0466:
                        if (num9 < 4)
                        {
                            goto Label_0425;
                        }
                        CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix);
                        continue;
                    Label_04A2:
                        num10 = 0;
                        while (num10 < 3)
                        {
                            mtx[num10, num9] = ((float)Utils.Read4BytesAsInt32(polydata, index)) / 4096f;
                            index += 4;
                            num9++;
                        }
                        num9++;
                    Label_04E3:
                        if (num9 < 3)
                        {
                            goto Label_04A2;
                        }
                        CurrentMatrix.MultMatrix(mtx).CopyValuesTo(CurrentMatrix);
                        continue;
                    Label_08E2:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_090F:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_09E1:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_0A0E:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_0ABF:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_0AEC:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_0B9D:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_0BCA:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_0C7B:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_0CA8:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_0DAA:
                        list.Add(new Vector3(v[0], v[1], v[2]));
                        list2.Add(item);
                        list3.Add(vector2);
                    Label_0DD7:
                        if (this.writevertex)
                        {
                        }
                        continue;
                    Label_0E92:
                        num6 = 4;
                        continue;
                    Label_0E97:
                        num6 = 7;
                        continue;
                    Label_0E9C:
                        num6 = 5;
                        continue;
                    Label_0EA1:
                        num6 = 8;
                        continue;
                    Label_0ED1:
                        group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.Triangle, list2.ToArray(), list3.ToArray(), list.ToArray()));
                        goto Label_0F67;
                    Label_0EF6:
                        group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.Quad, list2.ToArray(), list3.ToArray(), list.ToArray()));
                        goto Label_0F67;
                    Label_0F1B:
                        group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.TriangleStrip, list2.ToArray(), list3.ToArray(), list.ToArray()));
                        goto Label_0F67;
                    Label_0F40:
                        group.Add(new MKDS_Course_Editor.Export3DTools.Polygon(PolygonType.QuadStrip, list2.ToArray(), list3.ToArray(), list.ToArray()));
                    Label_0F67:
                        list2.Clear();
                        list.Clear();
                        list3.Clear();
                        gCurrentVertex--;
                        if ((gCurrentVertex < 0) && gOptVertexMode)
                        {
                            return group;
                        }
                    }
                }
            }
            return group;
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Process polygon 3d commands.
        /// </summary>
        /// <param name="polydata">Data of specific polygon.</param>
        private void Process3DCommand(byte[] polydata, NsbmdMaterial m, int jointID, bool color)
        {
            Gl.glMatrixMode(Gl.GL_MODELVIEW);
            Gl.glLoadIdentity();
            HelixToolkit.MaterialHelper.CreateMaterial(new System.Windows.Media.ImageBrush());

            md.Add(new HelixToolkit.MeshBuilder());
            IList<System.Windows.Media.Media3D.Point3D> poi = new List<System.Windows.Media.Media3D.Point3D>();
            IList<System.Windows.Media.Media3D.Vector3D> nor = new List<System.Windows.Media.Media3D.Vector3D>();
            IList<System.Windows.Point> tex = new List<System.Windows.Point>();
            int typ = -1;
            if (polydata == null)
                return;
            int commandptr = 0;
            int commandlimit = polydata.Length;
            int[] command = new int[4];
            int cur_vertex, mode, i;
            float[] vtx_state = { 0.0f, 0.0f, 0.0f };
            float[] vtx_trans = { 0.0f, 0.0f, 0.0f };
            cur_vertex = gCurrentVertex; // for vertex_mode
            if (Model.Objects.Count > 0)
            {
                CurrentMatrix = MatrixStack[stackID].Clone();
            }
            else
            {
                CurrentMatrix.LoadIdentity();
            }
            if (Model.Objects.Count > 1)
            {
                //CurrentMatrix.Scale(Model.modelScale, Model.modelScale, Model.modelScale);
            }
            while (commandptr < commandlimit)
            {
                for (i = 0; i < 4; ++i)
                {
                    if (commandptr >= commandlimit)
                        command[i] = 0xFF;
                    else
                    {
                        command[i] = polydata[commandptr];
                        commandptr++;
                    }
                }

                for (i = 0; i < 4 && commandptr < commandlimit; i++)
                {
                    switch (command[i])
                    {
                        case 0: // No Operation (for padding packed GXFIFO commands)
                            break;
                        case 0x10:
                            {
                                int param = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                switch (param)
                                {
                                    case 0:
                                        // Gl.glMatrixMode(Gl.GL_PROJECTION_MATRIX);
                                        break;
                                    case 1:
                                        // Gl.glMatrixMode(Gl.GL_MODELVIEW_MATRIX);
                                        break;
                                    case 2:
                                        break;
                                    case 3:
                                        // Gl.glMatrixMode(Gl.GL_TEXTURE_MATRIX);
                                        break;
                                }
                                break;
                            }
                        case 0x11: break;
                        case 0x12: commandptr += 4; break;
                        case 0x13: commandptr += 4; break;
                        case 0x14:
                            /*
                                  MTX_RESTORE - Restore Current Matrix from Stack (W)
                                  Sets C=[N]. The stack pointer S is not used, and is left unchanged.
                                  Parameter Bit0-4:  Stack Address (0..30) (31 causes overflow in GXSTAT.15)
                                  Parameter Bit5-31: Not used
                                */

                            stackID = Utils.Read4BytesAsInt32(polydata, commandptr) & 0x1F;// & 0x0000001F;
                            commandptr += 4;
                            MatrixStack[stackID].CopyValuesTo(CurrentMatrix);
                            break;
                        case 0x15:
                            {
                                CurrentMatrix.LoadIdentity();
                                break;
                            }
                        case 0x16:
                            {
                                for (int j = 0; j < 16; j++)
                                {
                                    CurrentMatrix[j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f;
                                    commandptr += 4;
                                }
                                break;
                            }
                        case 0x17:
                            {
                                for (int j = 0; j < 4; j++)
                                {
                                    for (int k = 0; k < 3; j++)
                                    {
                                        CurrentMatrix[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f;
                                        commandptr += 4;
                                    }
                                }
                                break;
                            }
                        case 0x18:
                            {
                                MTX44 f = new MTX44();
                                f.LoadIdentity();
                                for (int j = 0; j < 16; j++)
                                {
                                    f[j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f;
                                    commandptr += 4;
                                }
                                CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix);
                                break;
                            }
                        case 0x19:
                            {
                                MTX44 f = new MTX44();
                                f.LoadIdentity();
                                for (int j = 0; j < 4; j++)
                                {
                                    for (int k = 0; k < 3; j++)
                                    {
                                        f[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f;
                                        commandptr += 4;
                                    }
                                }
                                CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix);
                                break;
                            }
                        case 0x1A:
                            {
                                MTX44 f = new MTX44();
                                f.LoadIdentity();
                                for (int j = 0; j < 3; j++)
                                {
                                    for (int k = 0; k < 3; j++)
                                    {
                                        f[k, j] = (float)Utils.Read4BytesAsInt32(polydata, commandptr) / 4096f;
                                        commandptr += 4;
                                    }
                                }
                                CurrentMatrix.MultMatrix(f).CopyValuesTo(CurrentMatrix);
                                break;
                            }
                        case 0x1b:
                            /*
                                  MTX_SCALE - Multiply Current Matrix by Scale Matrix (W)
                                  Sets C=M*C. Parameters: 3, m[0..2] (MTX_SCALE doesn't change Vector Matrix)
                                */
                            {
                                int x, y, z;
                                x = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                y = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                z = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                //CurrentMatrix[0] = (float)sign(x, 32) / SCALE_IV;
                                //CurrentMatrix[5] = (float)sign(y, 32) / SCALE_IV;
                                //CurrentMatrix[10] = (float)sign(z, 32) / SCALE_IV;
                                //CurrentMatrix.SetValues(scale(CurrentMatrix.Floats, x, y, z));
                                CurrentMatrix.Scale((float)x / SCALE_IV / Model.modelScale, (float)y / SCALE_IV / Model.modelScale, (float)z / SCALE_IV / Model.modelScale);
                                //CurrentMatrix.Scale((float)sign(x, 32) / SCALE_IV, (float)sign(y, 32) / SCALE_IV, (float)sign(z, 32) / SCALE_IV);
                                break;
                            }
                        case 0x1c:
                            /*
                                  MTX_TRANS - Mult. Curr. Matrix by Translation Matrix (W)
                                  Sets C=M*C. Parameters: 3, m[0..2] (x,y,z position)
                                */
                            {
                                int x, y, z;
                                x = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                y = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                z = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                CurrentMatrix.translate((float)sign(x, 32) / SCALE_IV / Model.modelScale, (float)sign(y, 32) / SCALE_IV / Model.modelScale, (float)sign(z, 32) / SCALE_IV / Model.modelScale);
                                break;
                            }
                        case 0x20: // Directly Set Vertex Color (W)
                            {
                                Int64 rgb, r, g, b;

                                rgb = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                if (gOptColoring)
                                {
                                    r = (rgb >> 0) & 0x1F;
                                    g = (rgb >> 5) & 0x1F;
                                    b = (rgb >> 10) & 0x1F;
                                    if (color)
                                    {
                                        Gl.glColor4f(((float)r) / 31.0f, ((float)g) / 31.0f, ((float)b) / 31.0f, m.Alpha / 31.0f);
                                    }
                                }
                            }
                            break;

                        case 0x21:
                            /*
                                  Set Normal Vector (W)
                                  0-9   X-Component of Normal Vector (1bit sign + 9bit fractional part)
                                  10-19 Y-Component of Normal Vector (1bit sign + 9bit fractional part)
                                  20-29 Z-Component of Normal Vector (1bit sign + 9bit fractional part)
                                  30-31 Not used
                                */
                            {
                                Int64 xyz, x, y, z;

                                xyz = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = (xyz >> 0) & 0x3FF;
                                if ((x & 0x200) != 0)
                                    x |= -1024;
                                y = (xyz >> 10) & 0x3FF;
                                if ((y & 0x200) != 0) y |= -1024;
                                z = (xyz >> 20) & 0x3FF;
                                if ((z & 0x200) != 0) z |= -1024;
                                Gl.glNormal3f(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f);
                                if (writevertex)
                                {
                                    //normals.Add(new float[] { ((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f });
                                    //mod.Normals.Add(new System.Windows.Media.Media3D.Vector3D(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f))
                                    nor.Add(new System.Windows.Media.Media3D.Vector3D(((float)x) / 512.0f, ((float)y) / 512.0f, ((float)z) / 512.0f));
                                }
                                break;
                            }
                        case 0x22:
                            /*
                                  Set Texture Coordinates (W)
                                  Parameter 1, Bit 0-15   S-Coordinate (X-Coordinate in Texture Source)
                                  Parameter 1, Bit 16-31  T-Coordinate (Y-Coordinate in Texture Source)
                                  Both values are 1bit sign + 11bit integer + 4bit fractional part.
                                  A value of 1.0 (=1 SHL 4) equals to one Texel.
                                */
                            {
                                Int64 st, s, t;

                                st = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                s = (st >> 0) & 0xffff;
                                if ((s & 0x8000) != 0) s |= unchecked((int)0xFFFF0000);//-65536;
                                t = (st >> 16) & 0xffff;
                                if ((t & 0x8000) != 0) t |= unchecked((int)0xFFFF0000);//-65536;
                                Gl.glTexCoord2f(((float)s) / 16.0f, ((float)t) / 16.0f);

                                if (writevertex)
                                {
                                    //mod.TextureCoordinates.Add(new System.Windows.Point((float)s/1024f,(float)t/1024f));
                                    tex.Add(new System.Windows.Point(((float)m.scaleS / (float)m.width) * ((float)s / 16f) / (m.flipS + 1), -((float)m.scaleT / (float)m.height) * ((float)t / 16f) / (m.flipT + 1)));
                                }
                                break;
                            }
                        case 0x23:
                            /*
                                  VTX_16 - Set Vertex XYZ Coordinates (W)
                                  Parameter 1, Bit 0-15   X-Coordinate (signed, with 12bit fractional part)
                                  Parameter 1, Bit 16-31  Y-Coordinate (signed, with 12bit fractional part)
                                  Parameter 2, Bit 0-15   Z-Coordinate (signed, with 12bit fractional part)
                                  Parameter 2, Bit 16-31  Not used
                                */
                            {
                                int parameter, x, y, z;

                                parameter = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = sign((parameter >> 0) & 0xFFFF, 16);
                                //if ((x & 0x8000) != 0) x |= unchecked((int)0xFFFF0000);//-65536;
                                y = sign((parameter >> 16) & 0xFFFF, 16);
                                //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536;

                                parameter = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                z = sign(parameter & 0xFFFF, 16);
                                // if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536;

                                vtx_state[0] = ((float)x) / SCALE_IV;
                                vtx_state[1] = ((float)y) / SCALE_IV;
                                vtx_state[2] = ((float)z) / SCALE_IV;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x24:
                            /*
                                  VTX_10 - Set Vertex XYZ Coordinates (W)
                                  Parameter 1, Bit 0-9    X-Coordinate (signed, with 6bit fractional part)
                                  Parameter 1, Bit 10-19  Y-Coordinate (signed, with 6bit fractional part)
                                  Parameter 1, Bit 20-29  Z-Coordinate (signed, with 6bit fractional part)
                                  Parameter 1, Bit 30-31  Not used
                                */
                            {
                                int xyz, x, y, z;

                                xyz = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = sign((xyz >> 0) & 0x3FF, 10);
                                // if ((x & 0x200) != 0) x |=  unchecked((int)0xFFFFFC00);//-1024;
                                y = sign((xyz >> 10) & 0x3FF, 10);
                                //if ((y & 0x200) != 0) y |=  unchecked((int)0xFFFFFC00);//-1024;
                                z = sign((xyz >> 20) & 0x3FF, 10);
                                // if ((z & 0x200) != 0) z |= unchecked((int)0xFFFFFC00);//-1024;

                                vtx_state[0] = (float)x / 64.0f;
                                vtx_state[1] = (float)y / 64.0f;
                                vtx_state[2] = (float)z / 64.0f;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x25:
                            /*
                                  VTX_XY - Set Vertex XY Coordinates (W)
                                  Parameter 1, Bit 0-15   X-Coordinate (signed, with 12bit fractional part)
                                  Parameter 1, Bit 16-31  Y-Coordinate (signed, with 12bit fractional part)
                                */
                            {
                                int xy, x, y;

                                xy = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = sign((xy >> 0) & 0xFFFF, 16);
                                //if ((x & 0x8000) != 0) x |=  unchecked((int)0xFFFF0000);//-65536;
                                y = sign((xy >> 16) & 0xFFFF, 16);
                                //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536;

                                vtx_state[0] = ((float)x) / SCALE_IV;
                                vtx_state[1] = ((float)y) / SCALE_IV;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x26:
                            /*
                                  VTX_XZ - Set Vertex XZ Coordinates (W)
                                  Parameter 1, Bit 0-15   X-Coordinate (signed, with 12bit fractional part)
                                  Parameter 1, Bit 16-31  Z-Coordinate (signed, with 12bit fractional part)
                                */
                            {
                                int xz, x, z;

                                xz = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = sign((xz >> 0) & 0xFFFF, 16);
                                // if ((x & 0x8000) != 0) x |= unchecked((int)0xFFFF0000);//-65536;
                                z = sign((xz >> 16) & 0xFFFF, 16);
                                // if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536;

                                vtx_state[0] = ((float)x) / SCALE_IV;
                                vtx_state[2] = ((float)z) / SCALE_IV;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    // vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x27:
                            /*
                                  VTX_YZ - Set Vertex YZ Coordinates (W)
                                  Parameter 1, Bit 0-15   Y-Coordinate (signed, with 12bit fractional part)
                                  Parameter 1, Bit 16-31  Z-Coordinate (signed, with 12bit fractional part)
                                */
                            {
                                int yz, y, z;
                                yz = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                y = sign((yz >> 0) & 0xFFFF, 16);
                                //if ((y & 0x8000) != 0) y |= unchecked((int)0xFFFF0000);//-65536;
                                z = sign((yz >> 16) & 0xFFFF, 16);
                                //if ((z & 0x8000) != 0) z |= unchecked((int)0xFFFF0000);//-65536;

                                vtx_state[1] = ((float)y) / SCALE_IV;
                                vtx_state[2] = ((float)z) / SCALE_IV;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    //vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x28:
                            /*
                                  VTX_DIFF - Set Relative Vertex Coordinates (W)
                                  Parameter 1, Bit 0-9    X-Difference (signed, with 9bit fractional part)
                                  Parameter 1, Bit 10-19  Y-Difference (signed, with 9bit fractional part)
                                  Parameter 1, Bit 20-29  Z-Difference (signed, with 9bit fractional part)
                                  Parameter 1, Bit 30-31  Not used
                                */
                            {
                                int xyz, x, y, z;
                                xyz = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;

                                x = sign((xyz >> 0) & 0x3FF, 10);
                                //if ((x & 0x200) != 0) x |= unchecked((int)0xFFFFFC00);//-1024;
                                y = sign((xyz >> 10) & 0x3FF, 10);
                                //if ((y & 0x200) != 0) y |= unchecked((int)0xFFFFFC00);
                                z = sign((xyz >> 20) & 0x3FF, 10);
                                //if ((z & 0x200) != 0) z |= unchecked((int)0xFFFFFC00);

                                vtx_state[0] += ((float)x) / SCALE_IV;
                                vtx_state[1] += ((float)y) / SCALE_IV;
                                vtx_state[2] += ((float)z) / SCALE_IV;
                                if (stackID != -1)
                                {
                                    vtx_trans = CurrentMatrix.MultVector(vtx_state);
                                    Gl.glVertex3fv(vtx_trans);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_trans);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_trans[0], vtx_trans[1], vtx_trans[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if (nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity, 0));
                                        }
                                    }
                                }
                                else
                                {
                                    Gl.glVertex3fv(vtx_state);
                                    if (writevertex)
                                    {
                                        //vertex.Add(vtx_state);
                                        //mod.Positions.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        poi.Add(new System.Windows.Media.Media3D.Point3D(vtx_state[0], vtx_state[1], vtx_state[2]));
                                        if (poi.Count > tex.Count && tex.Count != 0)
                                        {
                                            tex.Add(tex[tex.Count - 1]);//new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        else if (tex.Count == 0)
                                        {
                                            tex.Add(new System.Windows.Point(double.NegativeInfinity, double.PositiveInfinity));
                                        }
                                        if (poi.Count > nor.Count && nor.Count != 0)
                                        {
                                            nor.Add(nor[nor.Count - 1]);
                                        }
                                        else if(nor.Count == 0)
                                        {
                                            nor.Add(new System.Windows.Media.Media3D.Vector3D(double.NegativeInfinity, double.PositiveInfinity,0));
                                        }
                                    }
                                }
                                if (writevertex)
                                {
                                    // vertex_normal.Add((normals.Count == 0 ? -1 : normals.Count));
                                }
                                break;
                            }
                        case 0x29:
                            {
                                int param = Utils.Read4BytesAsInt32(polydata, commandptr);
                                commandptr += 4;
                                /*int light = (param >> 0) & 0x10;
                                int polygonMode = (param >> 4) & 0x4;
                                switch (polygonMode)
                                {
                                    case 0:
                                        mode = Gl.GL_MODULATE;
                                        break;
                                    case 1:
                                        mode = Gl.GL_DECAL;
                                        break;
                                    case 2:
                                        mode = Gl.GL_SHADOW_AMBIENT_SGIX;
                                        break;
                                    case 3:
                                        mode = Gl.GL_QUAD_STRIP;
                                        break;
                                    default:
                                        //return ;// FALSE;
                                        throw new Exception();
                                        break;
                                }*/
                                break;
                            }
                        case 0x2A: commandptr += 4; break;
                        case 0x2B: commandptr += 4; break;

                        // lighting commands
                        case 0x30: commandptr += 4; break;
                        case 0x31: commandptr += 4; break;
                        case 0x32: commandptr += 4; break;
                        case 0x33:
                            {

                                commandptr += 4;
                                break;
                            }
                        case 0x34: commandptr += 128; break;
                        case 0x40: // Start of Vertex List (W)
                            {
                                mode = Utils.Read4BytesAsInt32(polydata, commandptr);
                                //mode = mode & 0x3;
                                commandptr += 4;
                                typ = mode;
                                switch (mode)
                                {
                                    case 0:
                                        mode = Gl.GL_TRIANGLES;
                                        break;
                                    case 1:
                                        mode = Gl.GL_QUADS;
                                        break;
                                    case 2:
                                        mode = Gl.GL_TRIANGLE_STRIP;
                                        break;
                                    case 3:
                                        mode = Gl.GL_QUAD_STRIP;
                                        break;
                                    default:
                                        //return ;// FALSE;
                                        throw new Exception();
                                        break;
                                }

                                Gl.glBegin(mode);
                                break;
                            }
                        case 0x41: // End of Vertex List (W)
                            Gl.glEnd();
                            //mod.TriangleIndices.Add(nr);
                            //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]);
                            //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]);
                            //mod.Positions.Add(mod.Positions[mod.Positions.Count - 1]);
                            //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]);
                            //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]);
                            //mod.Normals.Add(mod.Normals[mod.Normals.Count - 1]);
                            if (writevertex)
                            {
                                switch (typ)
                                {
                                    case 0:
                                        {
                                            for (int j = 0; j < poi.Count / 3; j++)
                                            {
                                                //IList<System.Windows.Media.Media3D.Point3D> pol = new List<System.Windows.Media.Media3D.Point3D>();
                                                //pol.Add(poi[j * 3]);
                                                //pol.Add(poi[j * 3 + 1]);
                                                //pol.Add(poi[j * 3 + 2]);
                                                /*IList<System.Windows.Media.Media3D.Vector3D> norm = new List<System.Windows.Media.Media3D.Vector3D>();
                                                if (norm.Count > j + 1)
                                                {
                                                    norm.Add(nor[j]);
                                                }
                                                IList<System.Windows.Point> text = new List<System.Windows.Point>();
                                                if (tex.Count > j+1)
                                                {
                                                    text.Add(tex[j]);
                                                }*/
                                                //if (tex.Count > j + 1)
                                                //{
                                                //    md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2], tex[j], tex[j], tex[j]);
                                                //}
                                                //else
                                                if (tex.Count > j * 3 + 2)
                                                {
                                                    md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2], tex[j * 3], tex[j * 3 + 1], tex[j * 3 + 2]);
                                                }
                                                else
                                                {
                                                    md[md.Count - 1].AddTriangle(poi[j * 3], poi[j * 3 + 1], poi[j * 3 + 2]);
                                                }
                                            }
                                            /*for (int j = 0; j < tex.Count; j++)
                                            {
                                                md[md.Count - 1].TextureCoordinates.Add(tex[j]);
                                            }
                                            for (int j = 0; j < nor.Count; j++)
                                            {
                                                md[md.Count - 1].Normals.Add(nor[j]);
                                            }*/
                                            /*HelixToolkit.Mesh3D mb = new HelixToolkit.Mesh3D();
                                            for (int j = 0; j < poi.Count; j += 3)
                                            {
                                                mb.Vertices.Add(poi[j]);
                                                mb.Vertices.Add(poi[j+1]);
                                                mb.Vertices.Add(poi[j+2]);
                                                mb.AddFace(new int[] { j, j + 1, j + 2 });
                                            }
                                            HelixToolkit.MeshBuilder b = new HelixToolkit.MeshBuilder();
                                            b.Append(mb.ToMeshGeometry3D());
                                            //b.AddTriangles(poi, nor, tex);
                                            md[mo].Append(b);*/
                                            break;
                                        }
                                    case 1:
                                        {
                                            for (int j = 0; j < poi.Count / 4; j++)
                                            {
                                                //IList<System.Windows.Media.Media3D.Point3D> pol = new List<System.Windows.Media.Media3D.Point3D>();
                                                //pol.Add(poi[j * 4]);
                                                //pol.Add(poi[j * 4 + 1]);
                                                //pol.Add(poi[j * 4 + 2]);
                                                //pol.Add(poi[j * 4 + 3]);
                                                /*IList<System.Windows.Media.Media3D.Vector3D> norm = new List<System.Windows.Media.Media3D.Vector3D>();
                                                if (norm.Count > j + 1)
                                                {
                                                    norm.Add(nor[j]);
                                                }
                                                IList<System.Windows.Point> text = new List<System.Windows.Point>();
                                                if (tex.Count > j + 1)
                                                {
                                                    text.Add(tex[j]);
                                                }
                                                md[md.Count - 1].AddQuads(pol, norm, text);//.AddPolygon(pol);*/
                                                //if (tex.Count > j + 1)
                                                //{
                                                //    md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3], tex[j], tex[j], tex[j], tex[j]);
                                                //}
                                                //else
                                                if (tex.Count > j * 4 + 3)
                                                {
                                                    md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3], tex[j * 4], tex[j * 4 + 1], tex[j * 4 + 2], tex[j * 4 + 3]);
                                                }
                                                else
                                                {
                                                    md[md.Count - 1].AddQuad(poi[j * 4], poi[j * 4 + 1], poi[j * 4 + 2], poi[j * 4 + 3]);
                                                }
                                            }
                                            /*for (int j = 0; j < tex.Count; j++)
                                            {
                                                md[md.Count - 1].TextureCoordinates.Add(tex[j]);
                                            }
                                            for (int j = 0; j < nor.Count; j++)
                                            {
                                                md[md.Count - 1].Normals.Add(nor[j]);
                                            }*/
                                            /* HelixToolkit.Mesh3D mb = new HelixToolkit.Mesh3D();
                                             for (int j = 0; j < poi.Count; j += 4)
                                             {
                                                 mb.Vertices.Add(poi[j]);
                                                 mb.Vertices.Add(poi[j + 1]);
                                                 mb.Vertices.Add(poi[j + 2]);
                                                 mb.Vertices.Add(poi[j + 3]);
                                                 mb.AddFace(new int[] { j, j + 1, j + 2, j+3 });
                                             }
                                             HelixToolkit.MeshBuilder b = new HelixToolkit.MeshBuilder();
                                             b.Append(mb.ToMeshGeometry3D());
                                             //b.AddTriangles(poi, nor, tex);
                                             md[mo].Append(b);*/
                                            break;
                                        }
                                    case 2:
                                        {
                                            while (poi.Count > nor.Count)
                                            {
                                                nor.Add(nor[nor.Count - 1]);
                                            }
                                            while (poi.Count > tex.Count)
                                            {
                                                tex.Add(tex[tex.Count - 1]);
                                            }
                                            md[md.Count - 1].AddTriangles(poi, nor, tex);
                                            //md[mo].AddTriangleStrip(poi, nor, tex);
                                            break;
                                        }
                                    case 3:
                                        {
                                            while (poi.Count > nor.Count)
                                            {
                                                nor.Add(nor[nor.Count - 1]);
                                            }
                                            while (poi.Count > tex.Count)
                                            {
                                                tex.Add(tex[tex.Count - 1]);
                                            }
                                            md[md.Count - 1].AddQuads(poi, nor, tex);
                                            //md.AddQuads(poi, nor, tex);
                                            break;
                                        }
                                    default:
                                        //return ;// FALSE;
                                        break;
                                }
                            }
                            nor.Clear();
                            tex.Clear();
                            poi.Clear();
                            //nr++;
                            // for vertex mode, display at maximum certain number of vertex-list
                            // decrease cur_vertex so that when we reach 0, stop rendering any further
                            cur_vertex--;
                            if (cur_vertex < 0 && gOptVertexMode)
                                return; //TRUE;
                            break;
                        case 0x50: commandptr += 4; break;
                        case 0x60: commandptr += 4; break;
                        case 0x70: commandptr += 12; break;
                        case 0x71: commandptr += 8; break;
                        case 0x72: commandptr += 4; break;
                        default:
                            break;
                        //return FALSE;
                    }
                }
            }
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Make texture for model.
        /// </summary>
        /// <param name="mod">NSBMD Model</param>
        private void MakeTexture(int i, NsbmdMaterial m)
        {
            try
            {
                if (m.format == 0) // format 0 is no texture
                {
                    //matt.Add(new System.Windows.Media.ImageBrush());
                    return;
                }
                var mat = m;
                if (mat == null || (mat.paldata == null && mat.format != 7))
                {
                    //matt.Add(new System.Windows.Media.ImageBrush());
                    return;
                }
                int pixelnum = mat.width * mat.height;

                var image = new RGBA[pixelnum];

                switch (mat.format)
                {
                    // No Texture
                    case 0:
                        //puts( "ERROR: format 0" );
                        //mattt.Add(new System.Windows.Media.ImageBrush());
                        return;
                    // A3I5 Translucent Texture (3bit Alpha, 5bit Color Index)
                    case 1:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            int index = mat.texdata[j] & 0x1f;
                            int alpha = (mat.texdata[j] >> 5);// & 7;
                            alpha = ((alpha * 4) + (alpha / 2)) * 8;// << 3;
                            image[j] = mat.paldata[index];
                            image[j].A = (byte)alpha;
                        }

                        break;
                    // 4-Color Palette Texture
                    case 2:
                        if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                        for (int j = 0; j < pixelnum; j++)
                        {
                            uint index = mat.texdata[j / 4];
                            index = (index >> ((j % 4) << 1)) & 3;
                            image[j] = mat.paldata[index];
                        }
                        break;
                    // 16-Color Palette Texture
                    case 3:
                        if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                        for (int j = 0; j < pixelnum; j++)
                        {
                            var matindex = j / 2;
                            if (mat.texdata.Length < matindex)
                                continue;
                            int index = mat.texdata[matindex];
                            index = (index >> ((j % 2) << 2)) & 0x0f;
                            if (mat.paldata == null)
                                continue;
                            if (index < 0 || index >= mat.paldata.Length)
                                continue;
                            if (j < 0 || j >= pixelnum)
                                continue;
                            image[j] = mat.paldata[index];
                        }
                        break;
                    // 256-Color Palette Texture
                    case 4:
                        if (mat.color0 != 0) mat.paldata[0] = RGBA.Transparent; // made palette entry 0 transparent
                        // made palette entry 0 transparent
                        for (int j = 0; j < pixelnum; j++)
                        {
                            image[j] = mat.paldata[mat.texdata[j]];
                        }
                        break;
                    // 4x4-Texel Compressed Texture
                    case 5:
                        convert_4x4texel_b(mat.texdata, mat.width, mat.height, mat.spdata, mat.paldata, image);
                        break;
                    // A5I3 Translucent Texture (5bit Alpha, 3bit Color Index)
                    case 6:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            int index = mat.texdata[j] & 0x7;
                            int alpha = (mat.texdata[j] >> 3);
                            alpha *= 8; //((alpha * 4) + (alpha / 2)) << 3;
                            image[j] = mat.paldata[index];
                            image[j].A = (byte)alpha;
                        }
                        break;
                    // Direct Color Texture
                    case 7:
                        for (int j = 0; j < pixelnum; j++)
                        {
                            //UInt16 p = (ushort)(mat.texdata[j * 2] + (mat.texdata[j * 2 + 1] << 8));
                            //image[j].R = (byte)(((p >> 0) & 0x1f) << 3);
                            //image[j].G = (byte)(((p >> 5) & 0x1f) << 3);
                            //image[j].B = (byte)(((p >> 10) & 0x1f) << 3);
                            //image[j].A = (byte)(((p & 0x8000) != 0) ? 0xff : 0);
                            image[j] = RGBA.fromColor(Tinke.Convertir.BGR555(mat.texdata[j * 2], mat.texdata[j * 2 + 1]));
                            UInt16 p = (ushort)(mat.texdata[j * 2] + (mat.texdata[j * 2 + 1] << 8));
                            image[j].A = (byte)(((p & 0x8000) != 0) ? 0xff : 0);
                        }
                        break;
                }

                Console.WriteLine("convert matid = {0}", i);
                Console.WriteLine("\ttex '{0}': {1} [{2},{3}] texsize = {4}", mat.texname, TEXTURE_FORMATS[mat.format], mat.width,
                                  mat.height, mat.texsize);
                Console.WriteLine("\tpal '{0}': pixelnum = {1}, repeat = {2}", mat.palname, pixelnum, mat.repeat);

                var imageBytesList = new List<byte>();
                //System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(mat.width, mat.height);
                for (int k = 0; k < image.Length; ++k)
                {
                    //bitmap.SetPixel(k - ((k / (mat.width)) * (mat.width)), k / (mat.width), image[k].ToColor());
                    imageBytesList.Add(image[k].R);
                    imageBytesList.Add(image[k].G);
                    imageBytesList.Add(image[k].B);
                    //if (image[k].A != 0)
                    //{
                    //	imageBytesList.Add((byte)(image[k].A - (255 - (((mat.Alpha + 1) * 8) - 1))));
                    //}
                    //else
                    //{
                        imageBytesList.Add((byte)(image[k].A));
                    //}
                }

                var imageBytes = imageBytesList.ToArray();

                /*System.Windows.Media.ImageBrush br = new System.Windows.Media.ImageBrush(CreateBitmapSourceFromBitmap(bitmap));
                br.Viewbox = new System.Windows.Rect(0, 0, mat.width, mat.height);
                br.ViewboxUnits = System.Windows.Media.BrushMappingMode.Absolute;
                br.Viewport = new System.Windows.Rect(0, 0, 1, 1);
                br.ViewportUnits = System.Windows.Media.BrushMappingMode.Absolute;
                br.Stretch = System.Windows.Media.Stretch.None;
                if (mat.flipS == 1 && mat.flipT == 1)
                {
                    br.TileMode = System.Windows.Media.TileMode.FlipXY;
                }
                else if (mat.flipS == 1)
                {
                    br.TileMode = System.Windows.Media.TileMode.FlipX;
                }
                else if (mat.flipT == 1)
                {
                    br.TileMode = System.Windows.Media.TileMode.FlipY;
                }
                else if (mat.repeatS == 1 || mat.repeatT == 1)
                {
                    br.TileMode = System.Windows.Media.TileMode.Tile;
                }
                else
                {
                    br.TileMode = System.Windows.Media.TileMode.None;
                }
                br.Opacity = (double)(((mat.Alpha + 1) * 8) - 1) / 1.0d;
                matt.Add(br);*/
                //ttt
                Gl.glBindTexture(Gl.GL_TEXTURE_2D, i + 1 + matstart);
                Gl.glTexImage2D(Gl.GL_TEXTURE_2D, 0, Gl.GL_RGBA, mat.width, mat.height, 0, Gl.GL_RGBA,
                                Gl.GL_UNSIGNED_BYTE,
                                imageBytes);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MIN_FILTER, Gl.GL_NEAREST);
                Gl.glTexParameteri(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_MAG_FILTER, Gl.GL_NEAREST);

                if (mat.flipS == 1 && mat.repeatS == 1)
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_MIRRORED_REPEAT);
                }
                else if (mat.repeatS == 1)
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_REPEAT);
                }
                else
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_S, Gl.GL_CLAMP);
                }
                if (mat.flipT == 1 && mat.repeatT == 1)
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_MIRRORED_REPEAT);
                }
                else if (mat.repeatT == 1)
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_REPEAT);
                }
                else
                {
                    Gl.glTexParameterf(Gl.GL_TEXTURE_2D, Gl.GL_TEXTURE_WRAP_T, Gl.GL_CLAMP);
                }
            }
            catch
            {
                //matt.Add(new System.Windows.Media.ImageBrush());
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Load materials in stream.
        /// </summary>
        /// <param name="stream">Stream to use.</param>
        /// <returns>Material definitions.</returns>
        public static IEnumerable<NsbmdMaterial> ReadTex0(Stream stream, int blockoffset, out int ptexnum, out int ppalnum)
        {
            BinaryReader reader = new BinaryReader(stream);
            UInt32 blocksize, blockptr, blocklimit;
            int texnum;
            UInt32 texdataoffset;
            int texdatasize;
            UInt32 sptexoffset; // for 4x4 compressed texels only
            int sptexsize; // for 4x4 compressed texels only
            UInt32 spdataoffset; // for 4x4 compressed texels only
            int palnum;
            UInt32 paldefoffset;
            UInt32 paldataoffset;
            int paldatasize;
            NsbmdMaterial[] material = null;
            int i, j;

            blockptr = (uint) (blockoffset + 4); // already read the block ID, so skip 4 bytes
            blocksize = reader.ReadUInt32(); // block size
            blocklimit = (uint) (blocksize + blockoffset);
            Console.WriteLine("DEBUG: blockoffset = {0}, blocksize = {1}", blockoffset, blocksize);

            stream.Skip(4); // skip 4 padding 0s
            texdatasize = reader.ReadUInt16() << 3; // total texture data size div8
            stream.Skip(6); // skip 6 bytes
            texdataoffset = (uint) (reader.ReadUInt32() + blockoffset);

            stream.Skip(4); // skip 4 padding 0s
            sptexsize = reader.ReadUInt16() << 3; // for format 5 4x4-texel, data size div8
            stream.Skip(6); // skip 6 bytesmhm
            sptexoffset = (uint) (reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, data offset
            spdataoffset = (uint) (reader.ReadUInt32() + blockoffset); // for format 5 4x4-texel, palette info

            stream.Skip(4); // skip 4 bytes
            paldatasize = reader.ReadUInt16() << 3; // total palette data size div8
            stream.Skip(2); // skip 2 bytes
            paldefoffset = (uint) (reader.ReadUInt32() + blockoffset);
            paldataoffset = (uint) (reader.ReadUInt32() + blockoffset);

            //	printf( "texdataoffset = %08x texdatasize = %08x\n", texdataoffset, texdatasize );
            //	printf( "sptexoffset = %08x sptexsize = %08x spdataoffset = %08x\n", sptexoffset, sptexsize, spdataoffset );
            //	printf( "paldataoffset = %08x paldatasize = %08x\n", paldataoffset, paldatasize );

            ////////////////////////////////////////////////
            // texture definition

            stream.Skip(1); // skip dummy '0'
            texnum = reader.ReadByte(); // no of texture
            blockptr = (uint) stream.Position;
            stream.Seek(paldefoffset, SeekOrigin.Begin);
            stream.Skip(1); // skip dummy '0'
            palnum = reader.ReadByte(); // no of palette
            stream.Seek(blockptr, SeekOrigin.Begin);

            Console.WriteLine("texnum = {0}, palnum = {1}", texnum, palnum);

            // allocate memory for material, great enough to hold all texture and palette
            material = new NsbmdMaterial[(texnum > palnum ? texnum : palnum)];
            for (i = 0; i < material.Length; ++i)
                material[i] = new NsbmdMaterial();

            stream.Skip(14 + (texnum*4)); // go straight to texture info

            for (i = 0; i < texnum; i++)
            {
                UInt32 offset;
                int param;
                int format;
                int width;
                int height;

                var mat = material[i];

                offset = (uint) (reader.ReadUInt16() << 3);
                param = reader.ReadUInt16(); // texture parameter
                stream.Skip(4); // skip 4 bytes

                format = (param >> 10) & 7; // format 0..7, see DSTek
                width = 8 << ((param >> 4) & 7);
                height = 8 << ((param >> 7) & 7);
                mat.color0 = (param >> 13) & 1;

                if (format == 5)
                    mat.texoffset = offset + sptexoffset; // 4x4-Texel Compressed Texture
                else
                    mat.texoffset = offset + texdataoffset;

                mat.format = format;
                mat.width = width;
                mat.height = height;
            }

            ////////////////////////////////////////////
            // copy texture names
            for (i = 0; i < texnum; i++)
            {
                material[i].texname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each texture's size
            for (i = 0; i < texnum; i++)
            {
                int[] bpp = {0, 8, 2, 4, 8, 2, 8, 16};

                var mat = material[i];
                mat.texsize = (uint) (mat.width*mat.height*bpp[mat.format]/8);
                Console.WriteLine("tex {0} '{1}': offset = {2} size = {3} [W,H] = [{4}, {5}]",
                                  i, mat.texname, mat.texoffset, mat.texsize, mat.width, mat.height);
            }

            ////////////////////////////////////////////////
            // palette definition
            stream.Seek(paldefoffset + 2, SeekOrigin.Begin); // skip palnum, already read
            stream.Seek(14 + (palnum*4), SeekOrigin.Current); // go straight to palette info
            for (i = 0; i < palnum; i++)
            {
                uint curOffset = (uint) ((reader.ReadUInt16() << 3) + paldataoffset);
                stream.Seek(2, SeekOrigin.Current); // skip 2 bytes
                material[i].paloffset = curOffset;
            }

            ////////////////////////////////////////////////
            // copy palette names
            for (i = 0; i < palnum; i++)
            {
                var mat = material[i];
                mat.palname = Utils.ReadNSBMDString(reader);
            }

            ////////////////////////////////////////////////
            // calculate each palette's size
            // assume the palettes are stored sequentially
            for (i = 0; i < palnum - 1; i++)
            {
                var mat = material[i];
                var r = i + 1;
                while (material[r].paloffset == mat.paloffset) r++;
                // below is RotA stupid way to calculate the size of palette: next's offset - current's offset
                // it works most of the time
                if (r != palnum)
                    mat.palsize = material[r].paloffset - mat.paloffset;
                else
                    mat.palsize = blocklimit - mat.paloffset;
                //printf("pal '%s' size = %d\n", mat->palname, mat->palsize);
            }
            material[i].palsize = blocklimit - material[i].paloffset;

            ////////////////////////////////////////////////
            // traverse each texture
            for (i = 0; i < texnum; i++)
            {
                var mat = material[i];
                stream.Seek(mat.texoffset, SeekOrigin.Begin);

                ////////////////////////////////////////////////
                // read texture into memory
                mat.texdata = reader.ReadBytes((int) mat.texsize);

                Console.WriteLine("DEBUG: texoffset = {0}, texsize = {1}", mat.texoffset, mat.texsize);

                ////////////////////////////////////////////////
                // additional data for format 5 4x4 compressed texels
                if (true) //(mat.format == 5)
                {
                    UInt32 r = mat.texsize >> 1;
                    stream.Seek(spdataoffset, SeekOrigin.Begin);

                    mat.spdata = reader.ReadBytes((int) r);

                    Console.WriteLine("DEBUG: 4x4-texel spdataoffset = {0}, spdatasize = {1}", spdataoffset, r);

                    spdataoffset += r;
                }
            }

            ////////////////////////////////////////////////
            // traverse each palette
            for (i = 0; i < palnum; i++)
            {
                try
                {
                    NsbmdMaterial mat = material[i];
                    var palentry = mat.palsize >> 1;

                    RGBA[] rgbq = new RGBA[palentry];

                    Console.WriteLine("DEBUG: converting pal '{0}', palentry = {1}", mat.palname, palentry);

                    stream.Seek(mat.paloffset, SeekOrigin.Begin);
                    for (j = 0; j < palentry; j++)
                    {
                        UInt16 p = reader.ReadUInt16();
                        rgbq[j].R = (byte) (((p >> 0) & 0x1f) << 3); // red
                        rgbq[j].G = (byte) (((p >> 5) & 0x1f) << 3); // green
                        rgbq[j].B = (byte) (((p >> 10) & 0x1f) << 3); // blue
                        //rgbq[j].RotA = (p&0x8000) ? 0xff : 0;
                        rgbq[j].A = 0xff; // alpha
                    }
                    mat.paldata = rgbq;
                }
                catch
                {
                }
            }

            ptexnum = texnum;
            ppalnum = palnum;

            return material;
        }