Esempio n. 1
0
        private void LoadSkins(BinaryReader reader)
        {
            mSkin = new M2SkinFile(mRootPath, mModelName, 0);
            if (mSkin.Load() == false)
            {
                throw new InvalidOperationException("Unable to load skin file");
            }

            Indices = mSkin.Indices;

            var texLookup    = ReadArrayOf <ushort>(reader, mHeader.OfsTexLookup, mHeader.NTexLookup);
            var renderFlags  = ReadArrayOf <uint>(reader, mHeader.OfsRenderFlags, mHeader.NRenderFlags);
            var uvAnimLookup = ReadArrayOf <short>(reader, mHeader.OfsUvAnimLookup, mHeader.NUvAnimLookup);
            var transLookup  = ReadArrayOf <short>(reader, mHeader.OfsTransLookup, mHeader.NTransLookup);

            foreach (var texUnit in mSkin.TexUnits)
            {
                var mesh = mSkin.SubMeshes[texUnit.submeshIndex];

                int uvIndex;
                if (texUnit.textureAnim >= uvAnimLookup.Length || uvAnimLookup[texUnit.textureAnim] < 0)
                {
                    uvIndex = -1;
                }
                else
                {
                    uvIndex = uvAnimLookup[texUnit.textureAnim];
                }

                var startTriangle = (int)mesh.startTriangle;
                if ((mesh.unk1 & 1) != 0)
                {
                    startTriangle += ushort.MaxValue + 1;
                }

                var textures = new List <Graphics.Texture>();
                switch (texUnit.op_count)
                {
                case 2:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 1]]);
                    break;

                case 3:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 1]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 2]]);
                    break;

                default:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    break;
                }

                var flags     = renderFlags[texUnit.renderFlags];
                var blendMode = flags >> 16;
                var flag      = flags & 0xFFFF;

                if (mRemapBlend && texUnit.shaderId < mBlendMap.Length)
                {
                    blendMode = mBlendMap[texUnit.shaderId];
                }

                blendMode %= 7;

                Passes.Add(new M2RenderPass
                {
                    Textures       = textures,
                    AlphaAnimIndex = transLookup[texUnit.transparency],
                    ColorAnimIndex = texUnit.colorIndex,
                    IndexCount     = mesh.nTriangles,
                    RenderFlag     = flag,
                    BlendMode      = blendMode,
                    StartIndex     = startTriangle,
                    TexAnimIndex   = uvIndex,
                    TexUnitNumber  = texUnit.texUnitNumber
                });
            }

            SortPasses();
        }
Esempio n. 2
0
        private void LoadSkins(BinaryReader reader)
        {
            mSkin = new M2SkinFile(ModelRoot, mModelName, 0);
            if (mSkin.Load() == false)
            {
                throw new InvalidOperationException("Unable to load skin file");
            }

            Indices = mSkin.Indices;

            var texLookup    = ReadArrayOf <ushort>(reader, mHeader.OfsTexLookup, mHeader.NTexLookup);
            var renderFlags  = ReadArrayOf <uint>(reader, mHeader.OfsRenderFlags, mHeader.NRenderFlags);
            var uvAnimLookup = ReadArrayOf <short>(reader, mHeader.OfsUvAnimLookup, mHeader.NUvAnimLookup);

            mSubMeshes = mSkin.SubMeshes.Select(sm => new M2SubMeshInfo
            {
                BoundingSphere =
                    new BoundingSphere(new Vector3(sm.centerBoundingBox.X, -sm.centerBoundingBox.Y, sm.centerBoundingBox.Z), sm.radius),
                NumIndices = sm.nTriangles,
                StartIndex = sm.startTriangle + (((sm.unk1 & 1) != 0) ? (ushort.MaxValue + 1) : 0)
            }).ToArray();

            foreach (var texUnit in mSkin.TexUnits)
            {
                var mesh = mSkin.SubMeshes[texUnit.submeshIndex];

                int uvIndex;
                if (texUnit.textureAnimIndex >= uvAnimLookup.Length || uvAnimLookup[texUnit.textureAnimIndex] < 0)
                {
                    uvIndex = -1;
                }
                else
                {
                    uvIndex = uvAnimLookup[texUnit.textureAnimIndex];
                }

                var startTriangle = (int)mesh.startTriangle;
                if ((mesh.unk1 & 1) != 0)
                {
                    startTriangle += ushort.MaxValue + 1;
                }

                var textures   = new List <Graphics.Texture>();
                var texIndices = new List <int>();
                switch (texUnit.op_count)
                {
                case 2:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 1]]);
                    texIndices.Add(texLookup[texUnit.texture]);
                    texIndices.Add(texLookup[texUnit.texture + 1]);
                    break;

                case 3:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 1]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 2]]);
                    texIndices.Add(texLookup[texUnit.texture]);
                    texIndices.Add(texLookup[texUnit.texture + 1]);
                    texIndices.Add(texLookup[texUnit.texture + 2]);
                    break;

                case 4:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 1]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 2]]);
                    textures.Add(mTextures[texLookup[texUnit.texture + 3]]);
                    texIndices.Add(texLookup[texUnit.texture]);
                    texIndices.Add(texLookup[texUnit.texture + 1]);
                    texIndices.Add(texLookup[texUnit.texture + 2]);
                    texIndices.Add(texLookup[texUnit.texture + 3]);
                    break;

                default:
                    textures.Add(mTextures[texLookup[texUnit.texture]]);
                    texIndices.Add(texLookup[texUnit.texture]);
                    break;
                }

                var flags     = renderFlags[texUnit.renderFlags];
                var blendMode = flags >> 16;
                var flag      = flags & 0xFFFF;

                if (mRemapBlend && texUnit.shaderId < mBlendMap.Length)
                {
                    blendMode = mBlendMap[texUnit.shaderId];
                }

                blendMode %= 7;

                if (blendMode != 0 && blendMode != 1)
                {
                    HasBlendPass = true;
                }
                else
                {
                    HasOpaquePass = true;
                }

                Passes.Add(new M2RenderPass
                {
                    TextureIndices   = texIndices,
                    Textures         = textures,
                    AlphaAnimIndex   = texUnit.transparencyIndex,
                    ColorAnimIndex   = texUnit.colorIndex,
                    IndexCount       = mesh.nTriangles,
                    RenderFlag       = flag,
                    BlendMode        = blendMode,
                    StartIndex       = startTriangle,
                    TexAnimIndex     = uvIndex,
                    TexUnitNumber    = texUnit.texUnitNumber,
                    OpCount          = texUnit.op_count,
                    VertexShaderType = M2ShadersClass.GetVertexShaderTypeOld(texUnit.shaderId, texUnit.op_count),
                    PixelShaderType  = M2ShadersClass.GetPixelShaderTypeOld(texUnit.shaderId, texUnit.op_count),
                });
            }

            SortPasses();
        }