Exemplo n.º 1
0
 public void ReadCorrectHeader() => File.OpenRead(FileName).Using(stream =>
 {
     var TestPmo = Pmo.Read(stream);
     Assert.Equal(0x4F4D50, (int)TestPmo.header.MagicCode);
     Assert.Equal(0, (int)TestPmo.header.SkeletonOffset);
     Assert.Equal(0xC0, (int)TestPmo.header.MeshOffset0);
     Assert.Equal(0, (int)TestPmo.header.MeshOffset1);
 });
Exemplo n.º 2
0
        public void ReadCorrectMeshGroup() => File.OpenRead(FileName).Using(stream =>
        {
            var TestPmo = Pmo.Read(stream);

            // mesh header 1
            Assert.Equal("544", TestPmo.Meshes[0].SectionInfo.VertexCount.ToString());
            Assert.Equal("16", TestPmo.Meshes[0].SectionInfo.TriangleStripCount.ToString());
        });
Exemplo n.º 3
0
        private static void Convert(string fileIn, string fileOut)
        {
            MeshGroup p   = FromFbx(fileIn);
            Pmo       pmo = MeshGroup2PMO(p);

            using Stream stream = File.Create(fileOut);
            Pmo.Write(stream, pmo);
            stream.Close();
        }
Exemplo n.º 4
0
        public PmoParser(Pmo pmo, float Scale)
        {
            aPmo            = pmo;
            MeshDescriptors = new List <MeshDescriptor>();
            MeshDescriptor currentMesh = new MeshDescriptor();

            for (int x = 0; x < pmo.Meshes.Count; x++)
            {
                var vertices = new PositionColoredTextured[pmo.Meshes[x].vertices.Count];
                for (var i = 0; i < vertices.Length; i++)
                {
                    Vector4 color;

                    if (Pmo.GetFlags(pmo.Meshes[x].SectionInfo).UniformDiffuseFlag)
                    {
                        byte[] byt = BitConverter.GetBytes(pmo.Meshes[x].SectionInfo_opt2.DiffuseColor);
                        if (BitConverter.IsLittleEndian)
                        {
                            Array.Reverse(byt);
                        }

                        color.X = 0xFF;
                        color.Y = 0xFF;
                        color.Z = 0xFF;
                        color.W = byt[0];
                    }
                    else
                    {
                        color   = pmo.Meshes[x].colors[i];
                        color.Y = 0xFF;
                        color.Z = 0xFF;
                        color.W = 0xFF;
                    }

                    vertices[i].X  = pmo.Meshes[x].vertices[i].X * pmo.header.ModelScale * Scale;
                    vertices[i].Y  = pmo.Meshes[x].vertices[i].Y * pmo.header.ModelScale * Scale;
                    vertices[i].Z  = pmo.Meshes[x].vertices[i].Z * pmo.header.ModelScale * Scale;
                    vertices[i].Tu = pmo.Meshes[x].textureCoordinates[i].X;
                    vertices[i].Tv = pmo.Meshes[x].textureCoordinates[i].Y;
                    vertices[i].R  = (byte)color.W;
                    vertices[i].G  = (byte)color.Z;
                    vertices[i].B  = (byte)color.Y;
                    vertices[i].A  = 0xFF;
                }

                currentMesh = new MeshDescriptor()
                {
                    Vertices     = vertices,
                    Indices      = pmo.Meshes[x].Indices.ToArray(),
                    TextureIndex = pmo.Meshes[x].TextureID,
                    IsOpaque     = true
                };

                MeshDescriptors.Add(currentMesh);
            }
        }
Exemplo n.º 5
0
        public PmoParser(Pmo pmo, float Scale)
        {
            aPmo            = pmo;
            MeshDescriptors = new List <MeshDescriptor>();
            MeshDescriptor currentMesh = new MeshDescriptor();

            for (int x = 0; x < pmo.Meshes.Count; x++)
            {
                var vertices = new PositionColoredTextured[pmo.Meshes[x].vertices.Count];
                for (var i = 0; i < vertices.Length; i++)
                {
                    Vector4 color;

                    if (Pmo.GetFlags(pmo.Meshes[x].SectionInfo).UniformDiffuseFlag)
                    {
                        var colorData = BitConverter.GetBytes(pmo.Meshes[x].SectionInfo_opt2.DiffuseColor);

                        color.X = colorData[0] / 255f;
                        color.Y = colorData[1] / 255f;
                        color.Z = colorData[2] / 255f;
                        color.W = colorData[3] / 255f;
                    }
                    else
                    {
                        color.X = pmo.Meshes[x].colors[i].X / 255f;
                        color.Y = pmo.Meshes[x].colors[i].Y / 255f;
                        color.Z = pmo.Meshes[x].colors[i].Z / 255f;
                        color.W = pmo.Meshes[x].colors[i].W / 255f;
                    }

                    vertices[i].X  = pmo.Meshes[x].vertices[i].X * pmo.header.ModelScale * Scale;
                    vertices[i].Y  = pmo.Meshes[x].vertices[i].Y * pmo.header.ModelScale * Scale;
                    vertices[i].Z  = pmo.Meshes[x].vertices[i].Z * pmo.header.ModelScale * Scale;
                    vertices[i].Tu = pmo.Meshes[x].textureCoordinates[i].X;
                    vertices[i].Tv = pmo.Meshes[x].textureCoordinates[i].Y;
                    vertices[i].R  = color.X;
                    vertices[i].G  = color.Y;
                    vertices[i].B  = color.Z;
                    vertices[i].A  = color.W;
                }

                currentMesh = new MeshDescriptor()
                {
                    Vertices     = vertices,
                    Indices      = pmo.Meshes[x].Indices.ToArray(),
                    TextureIndex = pmo.Meshes[x].TextureID,
                    IsOpaque     = false
                };

                MeshDescriptors.Add(currentMesh);
            }
        }
Exemplo n.º 6
0
 public void ReadBoneHeader() => File.OpenRead(FileName).Using(stream =>
 {
     var TestPmo = Pmo.Read(stream);
     if (TestPmo.header.SkeletonOffset == 0)
     {
         Assert.True(true);
     }
     else
     {
         Assert.Equal((uint)0x4e4f42, TestPmo.skeletonHeader.MagicValue);
         Assert.Equal((uint)0x35, TestPmo.skeletonHeader.BoneCount);
     }
 });
Exemplo n.º 7
0
 public MeshGroupModel(GraphicsDevice g, string name,
                       Pmo map, List <Tm2> texture, int index, Vector3 loc, Vector3 Rot, Vector3 Scl, bool diffMatrix)
 {
     _graphics          = g;
     _model             = map;
     Name               = name;
     Texture            = texture;
     Index              = index;
     IsVisible          = true;
     Location           = loc;
     Rotation           = Rot;
     Scale              = Scl;
     hasDifferentMatrix = diffMatrix;
     InvalidateTextures();
     Invalidate();
 }
Exemplo n.º 8
0
        private static List <Assimp.Animation> PAMtoFBXAnim(Pmo pmo, Pam pam)
        {
            List <Assimp.Animation> animationList = new List <Assimp.Animation>();

            for (int i = 0; i < pam.header.AnimationCount; i++)
            {
                Assimp.Animation anim = new Assimp.Animation();
                anim.Name            = pam.animList[i].AnimEntry.AnimationName;
                anim.DurationInTicks = pam.animList[i].AnimHeader.FrameCount;
                anim.TicksPerSecond  = pam.animList[i].AnimHeader.Framerate;

                //anim.MeshAnimationChannels[0].MeshKeys.Add(new MeshKey(anim.DurationInTicks / 2, new Vector3D(0, 0, 100)));

                for (int b = 0; b < pam.animList[i].AnimHeader.BoneCount; b++)
                {
                    Pam.BoneChannel chann = pam.animList[i].BoneChannels[b];

                    anim.NodeAnimationChannels.Add(new NodeAnimationChannel());
                    anim.NodeAnimationChannels[b].NodeName = pmo.boneList[b].JointName;
                    ChannelData dat = GetChannelKeyframes(chann, anim.DurationInTicks);

                    //AddTranslationAtKeyframe(anim.NodeAnimationChannels[b].PositionKeys, 0, new Vector3D(), anim.TicksPerSecond);
                    // Position

                    /*if(dat.transData != null)
                     * {
                     *  foreach (ChannelTranslationData trans in dat.transData)
                     *  {
                     *      AddTranslationAtKeyframe(anim.NodeAnimationChannels[b].PositionKeys, trans.keyframeID, trans.Translation, anim.TicksPerSecond);
                     *  }
                     * }*/

                    /*if (dat.rotData != null)
                     * {
                     *  // Rotation
                     *  foreach (ChannelRotationData trans in dat.rotData)
                     *  {
                     *      AddRotationAtKeyframe(anim.NodeAnimationChannels[b].RotationKeys, trans.keyframeID, trans.Rotation, anim.TicksPerSecond);
                     *  }
                     * }*/
                }

                animationList.Add(anim);
            }

            return(animationList);
        }
Exemplo n.º 9
0
        private static void Convert(string PMO_Path, string PAM_Path)
        {
            Stream pmoStream = File.OpenRead(PMO_Path);
            Stream pamStream = File.OpenRead(PAM_Path);
            Pmo    pmo       = Pmo.Read(pmoStream);
            Pam    pam       = Pam.Read(pamStream);

            Assimp.Scene            nScene   = GetPMOScene(pmo);
            List <Assimp.Animation> FBXAnims = PAMtoFBXAnim(pmo, pam);

            nScene.Animations.AddRange(FBXAnims);

            pmoStream.Close();
            pamStream.Close();

            using var ctx = new AssimpContext();
            ctx.ExportFile(nScene, "Test.fbx", "fbx");
        }
Exemplo n.º 10
0
        public static (IModelMotion, IKingdomTexture[]) BBSMeshLoader(GraphicsDevice graphics, string FilePath, IModelMotion Model, IKingdomTexture[] Textures)
        {
            const float Scale = 100.0f;
            var         file  = File.OpenRead(FilePath);
            Pmo         pmo   = Pmo.Read(file);

            Model = new PmoParser(pmo, Scale);

            List <Tim2KingdomTexture> BbsTextures = new List <Tim2KingdomTexture>();

            Textures = new IKingdomTexture[pmo.header.TextureCount];

            for (int i = 0; i < pmo.header.TextureCount; i++)
            {
                BbsTextures.Add(new Tim2KingdomTexture(pmo.texturesData[i], graphics));
                Textures[i] = BbsTextures[i];
            }

            return(Model, Textures);
        }
Exemplo n.º 11
0
        public void WritesBackCorrectly()
        {
            Stream input   = File.OpenRead(FileName);
            var    TestPmo = Pmo.Read(input);
            Stream output  = File.Open("Bbs/res/bbs-dummy_TEST.pmo", FileMode.Create);

            Pmo.Write(output, TestPmo);

            input.Position  = 0;
            output.Position = 0;

            // Check all bytes.
            for (int i = 0; i < output.Length; i++)
            {
                if (input.ReadByte() != output.ReadByte())
                {
                    long position = output.Position;
                    Assert.False(true);
                }
            }

            Assert.True(true);
        }
Exemplo n.º 12
0
 public void ReadCorrectTextures() => File.OpenRead(FileName).Using(stream =>
 {
     var TestPmo   = Pmo.Read(stream);
     byte[] buffer = TestPmo.texturesData[0];
     Assert.True(buffer[0] == 0x54 && buffer[1] == 0x49 && buffer[2] == 0x4D && buffer[3] == 0x32);
 });
Exemplo n.º 13
0
 public static IModelMotion FromBBS(Pmo pmo) =>
 pmo != null ? new PmoParser(pmo, 100.0f) : null;
Exemplo n.º 14
0
        private static Assimp.Scene GetPMOScene(Pmo pmo)
        {
            Assimp.Scene scene = new Assimp.Scene();
            scene.RootNode = new Assimp.Node("root");

            // Add materials.
            List <Material> matList = new List <Material>();

            for (int t = 0; t < pmo.header.TextureCount; t++)
            {
                Material mat = new Material();
                mat.Clear();
                mat.Name = pmo.textureInfo[t].TextureName;
                scene.Materials.Add(mat);
            }

            // Add skeleton.
            List <Node> Skeleton = new List <Node>();

            for (int b = 0; b < pmo.skeletonHeader.BoneCount; b++)
            {
                Pmo.BoneData bn = pmo.boneList[b];

                Assimp.Matrix4x4 mtx = new Assimp.Matrix4x4();
                mtx.A1 = bn.Transform.M11;
                mtx.A2 = bn.Transform.M12;
                mtx.A3 = bn.Transform.M13;
                mtx.A4 = bn.Transform.M14;
                mtx.B1 = bn.Transform.M21;
                mtx.B2 = bn.Transform.M22;
                mtx.B3 = bn.Transform.M23;
                mtx.B4 = bn.Transform.M24;
                mtx.C1 = bn.Transform.M31;
                mtx.C2 = bn.Transform.M32;
                mtx.C3 = bn.Transform.M33;
                mtx.C4 = bn.Transform.M34;
                mtx.D1 = bn.Transform.M41;
                mtx.D2 = bn.Transform.M42;
                mtx.D3 = bn.Transform.M43;
                mtx.D4 = bn.Transform.M44;

                Assimp.Matrix4x4 nd_mtx = mtx;
                nd_mtx.Transpose();
                if (bn.ParentBoneIndex == 0xFFFF)
                {
                    Node curNode = new Node(bn.JointName);
                    curNode.Transform = nd_mtx;
                    scene.RootNode.Children.Add(curNode);
                    Skeleton.Add(curNode);
                }
                else
                {
                    Node curNode = new Node(bn.JointName, Skeleton[bn.ParentBoneIndex]);

                    nd_mtx.A4 *= 100.0f;
                    nd_mtx.B4 *= 100.0f;
                    nd_mtx.C4 *= 100.0f;

                    curNode.Transform = nd_mtx;
                    Skeleton.Add(curNode);
                    scene.RootNode.FindNode(Skeleton[bn.ParentBoneIndex].Name).Children.Add(curNode);
                }
            }

            // Add meshes.
            for (int i = 0; i < pmo.Meshes.Count; i++)
            {
                Assimp.Mesh    mesh  = new Assimp.Mesh($"Mesh{i}", Assimp.PrimitiveType.Triangle);
                Pmo.MeshChunks chunk = pmo.Meshes[i];

                // Add vertices, vertex color and normals.
                for (int j = 0; j < chunk.vertices.Count; j++)
                {
                    mesh.Vertices.Add(new Assimp.Vector3D(
                                          chunk.vertices[j].X * pmo.header.ModelScale * 100.0f,
                                          chunk.vertices[j].Y * pmo.header.ModelScale * 100.0f,
                                          chunk.vertices[j].Z * pmo.header.ModelScale * 100.0f));

                    mesh.VertexColorChannels[0].Add(new Color4D(1.0f, 1.0f, 1.0f, 1.0f));
                    mesh.Normals.Add(new Vector3D());
                }
                mesh.SetIndices(chunk.Indices.ToArray(), 3);
                mesh.MaterialIndex = chunk.SectionInfo.TextureID;
                scene.Meshes.Add(mesh);

                for (int v = 0; v < chunk.vertices.Count; v++)
                {
                    // Build bone influences.
                    for (int z = 0; z < chunk.SectionInfo_opt1.SectionBoneIndices.Length; z++)
                    {
                        if (chunk.SectionInfo_opt1.SectionBoneIndices[z] != 0xFF)
                        {
                            Pmo.BoneData currentBone = new Pmo.BoneData();

                            int currentIndex = chunk.SectionInfo_opt1.SectionBoneIndices[z];
                            currentBone = pmo.boneList[currentIndex];

                            string           boneName = currentBone.JointName;
                            Assimp.Matrix4x4 mtx      = new Assimp.Matrix4x4();
                            mtx.A1 = currentBone.Transform.M11;
                            mtx.A2 = currentBone.Transform.M12;
                            mtx.A3 = currentBone.Transform.M13;
                            mtx.A4 = currentBone.Transform.M14;
                            mtx.B1 = currentBone.Transform.M21;
                            mtx.B2 = currentBone.Transform.M22;
                            mtx.B3 = currentBone.Transform.M23;
                            mtx.B4 = currentBone.Transform.M24;
                            mtx.C1 = currentBone.Transform.M31;
                            mtx.C2 = currentBone.Transform.M32;
                            mtx.C3 = currentBone.Transform.M33;
                            mtx.C4 = currentBone.Transform.M34;
                            mtx.D1 = currentBone.Transform.M41;
                            mtx.D2 = currentBone.Transform.M42;
                            mtx.D3 = currentBone.Transform.M43;
                            mtx.D4 = currentBone.Transform.M44;
                            Matrix3x3 mtx3 = new Matrix3x3(mtx);

                            mtx.Transpose();

                            mtx.A4 *= 100.0f;
                            mtx.B4 *= 100.0f;
                            mtx.C4 *= 100.0f;


                            mtx3.Transpose();

                            List <VertexWeight> weight = new List <VertexWeight>();

                            VertexWeight vW = new VertexWeight();
                            vW.VertexID = v;

                            float currentWeight = chunk.jointWeights[v].weights[z];

                            switch (chunk.jointWeights[v].coordFormart)
                            {
                            case Pmo.CoordinateFormat.NO_VERTEX:
                                break;

                            case Pmo.CoordinateFormat.NORMALIZED_8_BITS:
                                currentWeight *= 127.0f;
                                currentWeight /= 128.0f;
                                break;

                            case Pmo.CoordinateFormat.NORMALIZED_16_BITS:
                                currentWeight *= 32767.0f;
                                currentWeight /= 32768.0f;
                                break;

                            case Pmo.CoordinateFormat.FLOAT_32_BITS:
                                break;
                            }

                            vW.Weight = currentWeight;
                            weight.Add(vW);

                            Bone tempBone = scene.Meshes[i].Bones.Find(x => x.Name == boneName);
                            int  boneInd  = scene.Meshes[i].Bones.FindIndex(0, x => x.Name == boneName);

                            if (tempBone == null)
                            {
                                Bone bone = new Bone(boneName, mtx3, weight.ToArray());
                                scene.Meshes[i].Bones.Add(bone);
                            }
                            else
                            {
                                scene.Meshes[i].Bones[boneInd].VertexWeights.Add(vW);
                            }
                        }
                    }
                }
            }

            scene.RootNode.MeshIndices.AddRange(Enumerable.Range(0, scene.MeshCount));

            return(scene);
        }
Exemplo n.º 15
0
        private static Pmp MeshGroupList2PMP(List <MeshGroup> meshGroup)
        {
            Pmp pmp = new Pmp();

            pmp.header.MagicCode    = 0x504D50;
            pmp.header.TextureCount = (ushort)TexList.Count;
            pmp.header.ObjectCount  = (ushort)meshGroup.Count;
            pmp.header.ModelCount   = (ushort)meshGroup.Count;
            pmp.header.Padding      = new int[2];
            pmp.PmoList             = new List <Pmo>();
            pmp.objectInfo          = new List <Pmp.ObjectInfo>();
            pmp.TextureList         = new List <Pmp.PMPTextureInfo>();
            pmp.TextureDataList     = new List <Tm2>();

            Pmo pmo = new Pmo();

            foreach (MeshGroup group in meshGroup)
            {
                List <MeshDescriptor> Descriptors    = group.MeshDescriptors;
                List <int>            textureIndices = new List <int>();

                // Max 65K vertices.
                ushort descriptorVertexCount = 0;
                foreach (MeshDescriptor d in Descriptors)
                {
                    descriptorVertexCount += (ushort)d.Vertices.Length;
                    textureIndices.Add(d.TextureIndex);
                }

                // Mesh data.
                for (int i = 0; i < Descriptors.Count; i++)
                {
                    MeshDescriptor desc  = Descriptors[i];
                    Pmo.MeshChunks chunk = new Pmo.MeshChunks();

                    // Obtain info for PMO Vertex Flag.
                    bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                    Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                    Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                    chunk.SectionInfo             = new Pmo.MeshSection();
                    chunk.SectionInfo.Attribute   = 0;
                    chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                    chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                    chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                    // Set extra flags.
                    if (UsesUniformColor)
                    {
                        var UniformColor = (uint)(desc.Vertices[0].A / 255f);
                        UniformColor += (uint)(desc.Vertices[0].B / 255f) << 8;
                        UniformColor += (uint)(desc.Vertices[0].G / 255f) << 16;
                        UniformColor += (uint)(desc.Vertices[0].R / 255f) << 24;
                        chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                        chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                        chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                    }
                    else
                    {
                        chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                    }
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                    //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, 2);
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, 2);

                    chunk.SectionInfo.VertexSize += 0;                                                                                                                    // Weights.
                    TextureCoordinateFormat       = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8 : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }
                    chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                    VertexFormat = Pmo.CoordinateFormat.NORMALIZED_16_BITS;
                    chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                    if (chunk.SectionInfo.VertexSize % 4 != 0)
                    {
                        chunk.SectionInfo.VertexSize += 2;
                    }


                    for (int v = 0; v < desc.Vertices.Length; v++)
                    {
                        Vector4 Color = new Vector4();
                        Color.X = desc.Vertices[v].R * 256;
                        Color.Y = desc.Vertices[v].G * 256;
                        Color.Z = desc.Vertices[v].B * 256;
                        Color.W = 128;
                        chunk.colors.Add(Color);

                        Vector3 vec;
                        vec.X = desc.Vertices[v].X / 10000.0f;
                        vec.Y = desc.Vertices[v].Y / 10000.0f;
                        vec.Z = desc.Vertices[v].Z / 10000.0f;
                        chunk.vertices.Add(vec);

                        Vector2 Coords;
                        Coords.X = desc.Vertices[v].Tu;
                        Coords.Y = desc.Vertices[v].Tv;
                        chunk.textureCoordinates.Add(Coords);
                    }

                    pmo.Meshes.Add(chunk);
                }

                // Header.
                pmo.header                = new Pmo.Header();
                pmo.header.MagicCode      = 0x4F4D50;
                pmo.header.Number         = 1;
                pmo.header.Group          = 1;
                pmo.header.Version        = 3;
                pmo.header.TextureCount   = (byte)textureIndices.Count; // TODO.
                pmo.header.Flag           = 0x800;
                pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
                pmo.header.VertexCount    = descriptorVertexCount;
                pmo.header.TriangleCount  = pmo.header.VertexCount;
                pmo.header.TriangleCount /= 3;
                pmo.header.ModelScale     = 1.0f;
                pmo.header.BoundingBox    = new float[32];

                // Texture block.
                if (textureIndices.Count > 0)
                {
                    pmo.textureInfo = new Pmo.TextureInfo[textureIndices.Count];

                    for (int t = 0; t < textureIndices.Count; t++)
                    {
                        Tm2 tm = TextureData[textureIndices[t]];
                        pmo.textureInfo[t]             = new Pmo.TextureInfo();
                        pmo.textureInfo[t].TextureName = TexList[textureIndices[t]];
                        pmo.textureInfo[t].Unknown     = new UInt32[4];
                        pmo.texturesData.Add(tm);

                        Pmp.PMPTextureInfo pmpInfo = new Pmp.PMPTextureInfo();
                        pmpInfo.TextureName = pmo.textureInfo[t].TextureName;
                        pmpInfo.Unknown     = new uint[4];
                        pmp.TextureList.Add(pmpInfo);
                    }
                }

                Pmp.ObjectInfo info = new Pmp.ObjectInfo();
                info.PMO_Offset = 0x20 + (0x30 * (uint)meshGroup.Count) + 0;

                pmp.PmoList.Add(pmo);
                pmp.objectInfo.Add(info);
            }

            pmp.TextureDataList = TextureData;

            return(pmp);
        }
Exemplo n.º 16
0
        public PmoParser(Pmo pmo, float Scale)
        {
            aPmo            = pmo;
            MeshDescriptors = new List <MeshDescriptor>();
            MeshDescriptor currentMesh = new MeshDescriptor();

            for (int x = 0; x < pmo.Meshes.Count; x++)
            {
                var vertices = new PositionColoredTextured[pmo.Meshes[x].vertices.Count];
                for (var i = 0; i < vertices.Length; i++)
                {
                    Vector4 color;

                    color.X = pmo.Meshes[x].colors[i].X / 128.0f;
                    color.Y = pmo.Meshes[x].colors[i].Y / 128.0f;
                    color.Z = pmo.Meshes[x].colors[i].Z / 128.0f;
                    color.W = pmo.Meshes[x].colors[i].W / 128.0f;

                    vertices[i].X  = pmo.Meshes[x].vertices[i].X * pmo.header.ModelScale * Scale;
                    vertices[i].Y  = pmo.Meshes[x].vertices[i].Y * pmo.header.ModelScale * Scale;
                    vertices[i].Z  = pmo.Meshes[x].vertices[i].Z * pmo.header.ModelScale * Scale;
                    vertices[i].Tu = pmo.Meshes[x].textureCoordinates[i].X;
                    vertices[i].Tv = pmo.Meshes[x].textureCoordinates[i].Y;
                    vertices[i].R  = color.X;
                    vertices[i].G  = color.Y;
                    vertices[i].B  = color.Z;
                    vertices[i].A  = color.W;
                }

                currentMesh = new MeshDescriptor()
                {
                    Vertices     = vertices,
                    Indices      = pmo.Meshes[x].Indices.ToArray(),
                    TextureIndex = pmo.Meshes[x].TextureID,
                    IsOpaque     = false
                };

                MeshDescriptors.Add(currentMesh);
            }

            if (pmo.header.SkeletonOffset != 0)
            {
                List <Matrix4x4> matrices = new List <Matrix4x4>();
                List <Mdlx.Bone> skeleton = new List <Mdlx.Bone>();

                foreach (Pmo.BoneData boneData in pmo.boneList)
                {
                    Matrix4x4 mtx    = boneData.Transform;
                    Matrix4x4 mtx_nd = Matrix4x4.Transpose(mtx);

                    matrices.Add(mtx_nd);

                    Mdlx.Bone otherBone = new Mdlx.Bone();
                    otherBone.Index        = boneData.BoneIndex;
                    otherBone.Parent       = (boneData.ParentBoneIndex == 0xFFFF) ? 0 : boneData.ParentBoneIndex;
                    otherBone.TranslationX = mtx_nd.Translation.X;
                    otherBone.TranslationY = mtx_nd.Translation.Y;
                    otherBone.TranslationZ = mtx_nd.Translation.Z;
                    otherBone.TranslationW = mtx_nd.M14;
                    otherBone.RotationX    = mtx_nd.M21;
                    otherBone.RotationY    = mtx_nd.M22;
                    otherBone.RotationZ    = mtx_nd.M23;
                    otherBone.RotationW    = mtx_nd.M24;
                    otherBone.ScaleX       = mtx_nd.M31;
                    otherBone.ScaleY       = mtx_nd.M32;
                    otherBone.ScaleZ       = mtx_nd.M33;
                    otherBone.ScaleW       = mtx_nd.M34;

                    skeleton.Add(otherBone);
                }

                Bones       = skeleton;
                InitialPose = matrices.ToArray();
                CurrentPose = InitialPose;
            }
        }
Exemplo n.º 17
0
 public void ReadCorrectTextureBlock() => File.OpenRead(FileName).Using(stream =>
 {
     var TestPmo = Pmo.Read(stream);
     Assert.Equal("Dummy_tex02", TestPmo.textureInfo[0].TextureName);
     Assert.Equal(0x2300, (int)TestPmo.textureInfo[0].TextureOffset);
 });
Exemplo n.º 18
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }
                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4;                                                            // VertexColor
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices


                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 2;
                    Color.Y = desc.Vertices[index].G * 2;
                    Color.Z = desc.Vertices[index].B * 2;
                    Color.W = desc.Vertices[index].A * 2;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.TextureCount   = (ushort)TextureData.Count; // TODO.
            pmo.header.Unk0A          = 0x80;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            return(pmo);
        }
Exemplo n.º 19
0
        private static Pmo MeshGroup2PMO(MeshGroup meshGroup)
        {
            Pmo pmo = new Pmo();

            List <MeshDescriptor> Descriptors = meshGroup.MeshDescriptors;

            // Max 65K vertices.
            uint descriptorVertexCount = 0;
            uint indicesVertexCount    = 0;

            foreach (MeshDescriptor d in Descriptors)
            {
                descriptorVertexCount += (uint)d.Vertices.Length;
                indicesVertexCount    += (uint)d.Indices.Length;
            }

            // Mesh data.
            for (int i = 0; i < Descriptors.Count; i++)
            {
                MeshDescriptor desc        = Descriptors[i];
                int[]          vertIndices = desc.Indices;
                Pmo.MeshChunks chunk       = new Pmo.MeshChunks();

                // Obtain info for PMO Vertex Flag.
                bool UsesUniformColor = UsesUniformDiffuseFlag(desc);
                Pmo.CoordinateFormat TextureCoordinateFormat = GetTextureCoordinateFormat(desc);
                Pmo.CoordinateFormat VertexFormat            = GetVertexFormat(desc);

                chunk.SectionInfo             = new Pmo.MeshSection();
                chunk.SectionInfo.Attribute   = 0;
                chunk.SectionInfo.VertexCount = (ushort)desc.Vertices.Length;
                chunk.SectionInfo.TextureID   = (byte)desc.TextureIndex;
                chunk.SectionInfo.VertexFlags = 0x30000000; // 0011 000 0 0 00 000 0 000 0 00 00 11 00 000 01

                // Set extra flags.
                if (UsesUniformColor)
                {
                    var UniformColor = (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].A * 256f));
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].B * 256f)) << 8;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].G * 256f)) << 16;
                    UniformColor += (uint)(Math.Min(byte.MaxValue, desc.Vertices[0].R * 256f)) << 24;
                    chunk.SectionInfo.VertexFlags       = BitsUtil.Int.SetBit(chunk.SectionInfo.VertexFlags, 24, true);
                    chunk.SectionInfo_opt2              = new Pmo.MeshSectionOptional2();
                    chunk.SectionInfo_opt2.DiffuseColor = UniformColor;
                }
                else
                {
                    chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 2, 3, (uint)0x7);
                }
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, (uint)TextureCoordinateFormat);
                //chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, (uint)VertexFormat);

                uint texFormat = 3;
                uint posFormat = 3;

                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 0, 2, texFormat);
                chunk.SectionInfo.VertexFlags = BitsUtil.Int.SetBits(chunk.SectionInfo.VertexFlags, 7, 2, posFormat);

                chunk.SectionInfo.VertexSize += 0;                                                                                                                     // Weights.
                TextureCoordinateFormat       = (Pmo.CoordinateFormat)texFormat;
                chunk.SectionInfo.VertexSize += (TextureCoordinateFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)8  : (byte)((int)TextureCoordinateFormat * 2); // Texture Coordinates
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                chunk.SectionInfo.VertexSize += UsesUniformColor ? (byte)0 : (byte)4; // VertexColor

                VertexFormat = (Pmo.CoordinateFormat)posFormat;
                chunk.SectionInfo.VertexSize += (VertexFormat == Pmo.CoordinateFormat.FLOAT_32_BITS) ? (byte)12 : (byte)((int)VertexFormat * 3); // Vertices
                if (chunk.SectionInfo.VertexSize % 4 != 0)
                {
                    chunk.SectionInfo.VertexSize += 2;
                }

                for (int v = 0; v < desc.Indices.Length; v++)
                {
                    int index = vertIndices[v];

                    Vector4 Color = new Vector4();
                    Color.X = desc.Vertices[index].R * 256;
                    Color.Y = desc.Vertices[index].G * 256;
                    Color.Z = desc.Vertices[index].B * 256;
                    Color.W = 128;
                    chunk.colors.Add(Color);

                    Vector3 vec;
                    vec.X = desc.Vertices[index].X / 10000.0f;
                    vec.Y = desc.Vertices[index].Y / 10000.0f;
                    vec.Z = desc.Vertices[index].Z / 10000.0f;
                    chunk.vertices.Add(vec);

                    Vector2 Coords;
                    Coords.X = desc.Vertices[index].Tu;
                    Coords.Y = desc.Vertices[index].Tv;
                    chunk.textureCoordinates.Add(Coords);
                }

                pmo.Meshes.Add(chunk);
            }

            // Header.
            pmo.header                = new Pmo.Header();
            pmo.header.MagicCode      = 0x4F4D50;
            pmo.header.Number         = 1;
            pmo.header.Group          = 1;
            pmo.header.Version        = 3;
            pmo.header.TextureCount   = (byte)TextureData.Count; // TODO.
            pmo.header.Flag           = 0x800;
            pmo.header.MeshOffset0    = 0xA0 + ((uint)pmo.header.TextureCount * 0x20);
            pmo.header.VertexCount    = (ushort)indicesVertexCount;
            pmo.header.TriangleCount  = (ushort)indicesVertexCount;
            pmo.header.TriangleCount /= 3;
            pmo.header.ModelScale     = 1.0f;
            pmo.header.BoundingBox    = new float[32];

            // Texture block.
            if (TextureData.Count > 0)
            {
                pmo.textureInfo = new Pmo.TextureInfo[TextureData.Count];

                for (int t = 0; t < TextureData.Count; t++)
                {
                    Tm2 tm = TextureData[t];
                    pmo.textureInfo[t]             = new Pmo.TextureInfo();
                    pmo.textureInfo[t].TextureName = TexList[t];
                    pmo.textureInfo[t].Unknown     = new UInt32[4];
                    pmo.texturesData.Add(TextureData[t]);
                }
            }

            //pmo.header.SkeletonOffset = pmo.header.MeshOffset0 + 0;
            pmo.skeletonHeader = new Pmo.SkeletonHeader();
            pmo.boneList       = new Pmo.BoneData[0];

            /*pmo.skeletonHeader.MagicValue = 0x4E4F42;
             * pmo.skeletonHeader.BoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.SkinnedBoneCount = (ushort)BoneData.Count;
             * pmo.skeletonHeader.nStdBone = 2;
             *
             * pmo.boneList = new Pmo.BoneData[BoneData.Count];
             *
             * for(int b = 0; b < pmo.boneList.Length; b++)
             * {
             *  Pmo.BoneData bn = new Pmo.BoneData();
             *  bn.BoneIndex = (ushort)b;
             *
             *  Assimp.Node curNode = new Assimp.Node();
             *  ushort p = 0;
             *  foreach(var nd in NodeData)
             *  {
             *      p++;
             *      if(nd.Name == BoneData[b].Name)
             *      {
             *          curNode = nd;
             *          p--;
             *          break;
             *      }
             *  }
             *
             *  bn.ParentBoneIndex = p;
             *  bn.JointName = BoneData[b].Name;
             *
             *  Matrix4x4 mtx = new Matrix4x4();
             *  mtx.M11 = BoneData[b].OffsetMatrix.A1;
             *  mtx.M12 = BoneData[b].OffsetMatrix.A2;
             *  mtx.M13 = BoneData[b].OffsetMatrix.A3;
             *  mtx.M14 = BoneData[b].OffsetMatrix.A4;
             *  mtx.M21 = BoneData[b].OffsetMatrix.B1;
             *  mtx.M22 = BoneData[b].OffsetMatrix.B2;
             *  mtx.M23 = BoneData[b].OffsetMatrix.B3;
             *  mtx.M24 = BoneData[b].OffsetMatrix.B4;
             *  mtx.M31 = BoneData[b].OffsetMatrix.C1;
             *  mtx.M32 = BoneData[b].OffsetMatrix.C2;
             *  mtx.M33 = BoneData[b].OffsetMatrix.C3;
             *  mtx.M34 = BoneData[b].OffsetMatrix.C4;
             *  mtx.M41 = BoneData[b].OffsetMatrix.D1;
             *  mtx.M42 = BoneData[b].OffsetMatrix.D2;
             *  mtx.M43 = BoneData[b].OffsetMatrix.D3;
             *  mtx.M44 = BoneData[b].OffsetMatrix.D4;
             *
             *  bn.Transform = mtx;
             *  bn.InverseTransform = mtx;
             *  pmo.boneList[b] = bn;
             * }*/

            return(pmo);
        }