Beispiel #1
0
        /// <summary>
        /// Export Animation
        /// </summary>
        /// <param name="filePath"></param>
        /// <param name="skeleton"></param>
        /// <param name="animation"></param>
        public void Export(string filePath, GenericSkeleton skeleton, GenericAnimation animation)
        {
            using (StreamWriter w = new StreamWriter(new FileStream(filePath, FileMode.Create)))
            {
                w.WriteLine("version 1");

                if (skeleton != null)
                {
                    w.WriteLine("nodes");
                    foreach (GenericBone bone in skeleton.Bones)
                    {
                        w.WriteLine($" {skeleton.IndexOf(bone)} \"{bone.Name}\" {bone.ParentIndex}");
                    }
                    w.WriteLine("end");
                    w.WriteLine("skeleton");

                    for (int i = 0; i < animation.FrameCount; i++)
                    {
                        animation.UpdateSkeleton(i, skeleton);
                        w.WriteLine("time " + i);
                        foreach (GenericBone bone in skeleton.Bones)
                        {
                            GenericBone b = new GenericBone();
                            b.Transform = bone.GetTransform(true);
                            w.WriteLine($" {skeleton.IndexOf(bone)} {b.Position.X} {b.Position.Y} {b.Position.Z} {b.Rotation.X} {b.Rotation.Y} {b.Rotation.Z}");
                        }
                    }
                    w.WriteLine("end");
                }
            }
        }
Beispiel #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="skeleton"></param>
        /// <param name="animation"></param>
        /// <returns></returns>
        public bool ExportAnimation(GenericSkeleton skeleton, GenericAnimation animation)
        {
            var path = FileTools.GetSaveFile(animation.Name, GetAnimationExportFilter());

            if (path != null && skeleton != null)
            {
                var ext = System.IO.Path.GetExtension(path).ToLower();
                foreach (var v in AnimationExporters)
                {
                    if (v.Extension().Equals(ext))
                    {
                        v.Export(path, skeleton, animation);
                        return(true);
                    }
                }
            }
            return(false);
        }
Beispiel #3
0
        private GenericVertex SingleBind(GenericVertex vert, GenericSkeleton s)
        {
            Vector3 p = Vector3.Zero;
            Vector3 n = Vector3.Zero;

            for (int i = 0; i < 1; i++)
            {
                if (vert.Weights[i] > 0)
                {
                    n += Vector3.TransformNormal(vert.Nrm, s.GetWorldTransform((int)vert.Bones[i]));   // * vert.Weights[i];
                    p += Vector3.TransformPosition(vert.Pos, s.GetWorldTransform((int)vert.Bones[i])); // * vert.Weights[i];
                }
            }

            vert.Pos = p;
            vert.Nrm = n;
            return(vert);
        }
Beispiel #4
0
        private static GenericSkeleton ReadSkel(string path)
        {
            GenericSkeleton skel = new GenericSkeleton();

            using (DataReader r = new DataReader(path))
            {
                r.BigEndian = false;

                r.Seek(0x10);
                var count  = r.ReadInt16();
                var count2 = r.ReadInt16();
                var count3 = r.ReadInt32();

                var boneInfoOffset       = r.Position + r.ReadUInt32();
                var boneParentInfoOffset = r.Position + r.ReadUInt32();
                var hashOffset           = r.Position + r.ReadUInt32();
                // various hash table offsets

                for (uint i = 0; i < count; i++)
                {
                    GenericBone b = new GenericBone();

                    r.Seek(boneInfoOffset + 48 * i);
                    var rot = new OpenTK.Quaternion(r.ReadSingle(), r.ReadSingle(), r.ReadSingle(), r.ReadSingle()).Inverted();
                    rot.Normalize();
                    b.QuaternionRotation = rot;
                    b.Position           = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    r.ReadSingle();
                    b.Scale = new OpenTK.Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());
                    r.ReadSingle();

                    r.Seek(boneParentInfoOffset + 2 * i);
                    b.ParentIndex = r.ReadInt16();

                    r.Seek(hashOffset + 4 * i);
                    b.Name = "B_" + r.ReadInt32().ToString("X8");

                    skel.Bones.Add(b);
                }
            }
            return(skel);
        }
Beispiel #5
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="pos"></param>
        /// <param name="skel"></param>
        /// <param name="weights"></param>
        /// <param name="bones"></param>
        /// <param name="nunoBoneToBone"></param>
        /// <param name="normal"></param>
        /// <returns></returns>
        private Vector3 Weight(Vector3 pos, GenericSkeleton skel, Vector4 weights, Vector4 bones, Dictionary <int, int> nunoBoneToBone, bool normal = false)
        {
            Vector3 temp = Vector3.Zero;

            if (normal)
            {
                temp += Vector3.TransformNormal(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.X])) * weights.X;
                temp += Vector3.TransformNormal(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.Y])) * weights.Y;
                temp += Vector3.TransformNormal(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.Z])) * weights.Z;
                temp += Vector3.TransformNormal(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.W])) * weights.W;
            }
            else
            {
                temp += Vector3.TransformPosition(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.X])) * weights.X;
                temp += Vector3.TransformPosition(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.Y])) * weights.Y;
                temp += Vector3.TransformPosition(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.Z])) * weights.Z;
                temp += Vector3.TransformPosition(pos, skel.GetWorldTransform(nunoBoneToBone[(int)bones.W])) * weights.W;
            }
            return(temp);
        }
Beispiel #6
0
        private void RigMe(Vector3 position, GenericSkeleton skel, Dictionary <int, int> nuno, out Vector4 bone, out Vector4 weight)
        {
            weight = new Vector4();
            bone   = new Vector4();

            foreach (var v in nuno)
            {
                var t = skel.GetWorldTransform(v.Value);
                var p = Vector3.TransformPosition(Vector3.Zero, t);

                var dis = Vector3.Distance(position, p);
                for (int i = 0; i < 4; i++)
                {
                    if (dis < weight[i] || weight[i] == 0)
                    {
                        weight[i] = dis;
                        bone[i]   = v.Value;
                        break;
                    }
                }
            }
            weight = weight.Normalized();
        }
Beispiel #7
0
        public GenericModel ToGenericModel()
        {
            GenericSkeleton skel = new GenericSkeleton();

            foreach (var node in Nodes)
            {
                GenericBone bone = new GenericBone()
                {
                    Name        = node.Name,
                    Position    = node.Position,
                    Rotation    = node.Rotation,
                    Scale       = node.Scale,
                    ParentIndex = node.ParentIndex
                };
                skel.Bones.Add(bone);
            }

            GenericModel m = new GenericModel();

            m.Skeleton = skel;

            // Textures
            var tindex = 0;

            foreach (var tex in Textures)
            {
                if (m.TextureBank.ContainsKey(tex.Name))
                {
                    tex.Name += "_" + tindex++;
                }
                m.TextureBank.Add(tex.Name, tex);
            }

            int index = -1;

            foreach (var meshObject in MeshObjects)
            {
                index++;
                Dictionary <int, List <GenericVertex> > MaterialToVertexBank = new Dictionary <int, List <GenericVertex> >();
                //Console.WriteLine($"{meshObject.Key} {skel.Bones[meshObject.Value.SingleBind].Name}");
                foreach (var d in meshObject.Value.Primitives)
                {
                    if (!MaterialToVertexBank.ContainsKey(d.Material))
                    {
                        MaterialToVertexBank.Add(d.Material, new List <GenericVertex>());
                    }

                    var vertices = MaterialToVertexBank[d.Material];

                    switch (d.PrimitiveType)
                    {
                    case 0x02:     // Triangle
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        break;

                    case 0x03:     // Quad
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[0], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[1], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[3], skel));
                        vertices.Add(GetVertex(meshObject.Value, d.Vertices[2], skel));
                        break;

                    case 0x04:     // Triangle Strip
                        var verts = new List <GenericVertex>();

                        foreach (var dv in d.Vertices)
                        {
                            verts.Add(GetVertex(meshObject.Value, dv, skel));
                        }
                        Tools.TriangleConverter.StripToList(verts, out verts);

                        vertices.AddRange(verts);
                        break;

                    default:
                        throw new Exception("Unsupported Primitive Type " + d.PrimitiveType.ToString("X"));
                    }
                }

                foreach (var v in MaterialToVertexBank)
                {
                    GenericMesh mesh = new GenericMesh();
                    mesh.Name = meshObject.Key;
                    if (MaterialToVertexBank.Count > 1)
                    {
                        mesh.Name += "_" + m.Meshes.Count;// Textures[Materials[Materials1[v.Key].MaterialIndex].TextureIndex].Name;
                    }
                    GenericMaterial mat = new GenericMaterial();

                    mesh.MaterialName = "material_" + m.MaterialBank.Count;

                    m.MaterialBank.Add(mesh.MaterialName, mat);

                    var mat1Index = Materials1[v.Key].MaterialIndex;
                    mat1Index = Math.Min(mat1Index, Materials.Count - 1);
                    var textureIndex = Materials[mat1Index].TextureIndex;
                    mat.TextureDiffuse = Textures[textureIndex].Name;

                    m.Meshes.Add(mesh);

                    mesh.Vertices.AddRange(v.Value);

                    //Console.WriteLine(mesh.Name + " " + v.Key + " " + Materials[v.Key].TextureIndex + " " + Textures.Count + " " + Materials.Count);

                    mesh.Optimize();
                }
            }


            return(m);
        }
Beispiel #8
0
        private GenericVertex GetVertex(MeshObject mesh, VertexGroup g, GenericSkeleton skeleton)
        {
            // Rigging
            Vector4 boneIndices = new Vector4(mesh.SingleBind, 0, 0, 0);
            Vector4 weight      = new Vector4(1, 0, 0, 0);

            var Position = Vector3.Zero;

            if (g.PositionIndex < mesh.Positions.Count)
            {
                Position = mesh.Positions[g.PositionIndex];
            }

            var bone = skeleton.Bones.Find(e => e.Name.Equals(mesh.Name));

            if (bone != null)
            {
                boneIndices = new Vector4(skeleton.Bones.IndexOf(bone), 0, 0, 0);
                Position    = Vector3.TransformPosition(Position, skeleton.GetWorldTransform(bone));
            }


            foreach (var singleBind in mesh.SingleBinds)
            {
                if (g.PositionIndex >= singleBind.PositionIndex && g.PositionIndex < singleBind.PositionIndex + singleBind.PositionCount)
                {
                    boneIndices = new Vector4(singleBind.BoneIndex, 0, 0, 0);
                    break;
                }
            }
            int mbOffset = 0;

            foreach (var multiBind in mesh.DoubleBinds)
            {
                for (int i = mbOffset; i < mbOffset + multiBind.Count; i++)
                {
                    var w = mesh.DoubleWeights[i];
                    if (g.PositionIndex >= w.PositionIndex && g.PositionIndex < w.PositionIndex + w.PositionCount)
                    {
                        boneIndices = new Vector4(multiBind.Bone1, multiBind.Bone2, 0, 0);
                        weight      = new Vector4(w.Weight, 1 - w.Weight, 0, 0);
                        break;
                    }
                }
                mbOffset += multiBind.Count;
            }

            mbOffset = 0;
            foreach (var multiBind in mesh.MultiBinds)
            {
                if (g.PositionIndex >= multiBind.PositionIndex && g.PositionIndex < multiBind.PositionIndex + multiBind.PositionCount)
                {
                    boneIndices = new Vector4(0);
                    weight      = new Vector4(0);
                    for (int i = mbOffset; i < mbOffset + multiBind.Count; i++)
                    {
                        boneIndices[i - mbOffset] = mesh.MultiWeights[i].BoneIndex;
                        weight[i - mbOffset]      = mesh.MultiWeights[i].Weight;
                    }
                    break;
                }
                mbOffset += multiBind.Count;
            }

            var uv = Vector2.Zero;

            var Normal = Vector3.Zero;
            var Color  = Vector4.One;

            if (mesh.Normals.Count > 0 && g.NormalIndex < mesh.Normals.Count)
            {
                Normal = mesh.Normals[g.NormalIndex];
            }

            if (mesh.Colors.Count > 0)
            {
                Normal = mesh.Colors[g.NormalIndex].Xyz;
            }

            if (g.UVIndex >= 0 && mesh.UVs.Count > 0 && g.UVIndex < mesh.UVs.Count)
            {
                uv = mesh.UVs[g.UVIndex];
            }

            return(new GenericVertex()
            {
                Pos = Position,
                Nrm = Normal, // TODO: single bind normal
                Clr = Color,
                UV0 = uv,
                Bones = boneIndices,
                Weights = weight
            });
        }
Beispiel #9
0
        public GenericModel ToGenericModel()
        {
            var model = new GenericModel();
            var skel  = new GenericSkeleton();

            model.Skeleton = skel;

            Level5_Resource resourceFile = null;
            var             textureList  = new List <GenericTexture>();

            foreach (var f in Files)
            {
                //Console.WriteLine(f.Key);
                if (f.Key.EndsWith("RES.bin"))
                {
                    resourceFile = new Level5_Resource(f.Value);
                    model.Name   = resourceFile.ModelName;
                }
                if (f.Key.EndsWith(".mbn"))
                {
                    skel.Bones.Add(Level5_MBN.ToBone(f.Value));
                }
                if (f.Key.EndsWith(".prm"))
                {
                    model.Meshes.Add(Level5_PRM.ToGenericMesh(f.Value));
                }
                if (f.Key.EndsWith(".atr"))
                {
                }
                if (f.Key.EndsWith(".xi"))
                {
                    var tex = Level5_XI.ToGenericTexture(f.Value);
                    tex.Name = f.Key;
                    textureList.Add(tex);
                }
            }

            if (resourceFile == null)
            {
                return(model);
            }


            // add materials
            foreach (var mat in resourceFile.Materials)
            {
                GenericMaterial material = new GenericMaterial();
                material.TextureDiffuse = mat.TexName;
                model.MaterialBank.Add(mat.Name, material);
            }

            // add textures
            for (int i = 0; i < textureList.Count; i++)
            {
                model.TextureBank.Add(resourceFile.TextureNames[i], textureList[i]);
            }

            // fix bones
            foreach (var bone in skel.Bones)
            {
                bone.Name = resourceFile.GetResourceName((uint)bone.ID);
                bone.ID   = 0;
            }
            foreach (var bone in skel.Bones)
            {
                if (bone.ParentIndex == 0)
                {
                    bone.ParentIndex = -1;
                }
                else
                {
                    var parentName = resourceFile.GetResourceName((uint)bone.ParentIndex);
                    bone.ParentIndex = skel.Bones.FindIndex(e => e.Name.Equals(parentName));
                }
            }
            var boneIndex = 0;

            foreach (var bone in skel.Bones)
            {
                if (bone.Name.Equals(""))
                {
                    bone.Name = "Bone_" + boneIndex++;
                }
            }

            foreach (var mesh in model.Meshes)
            {
                for (int i = 0; i < mesh.VertexCount; i++)
                {
                    var     vertex   = mesh.Vertices[i];
                    Vector4 newBones = new Vector4();
                    for (int j = 0; j < 4; j++)
                    {
                        if (vertex.Weights[j] > 0)
                        {
                            var hash = BitConverter.ToUInt32(BitConverter.GetBytes(vertex.Bones[j]), 0);
                            newBones[j] = skel.Bones.FindIndex(e => e.Name == resourceFile.GetResourceName(hash));
                        }
                    }
                    vertex.Bones     = newBones;
                    mesh.Vertices[i] = vertex;
                }
            }

            return(model);
        }