Example #1
0
        private void ImportModel(GFLXModelImporter importer,
                                 List <STGenericMaterial> importedMaterials, List <STGenericObject> importedMeshes,
                                 STSkeleton skeleton)
        {
            Model.Model.Groups.Clear();
            Model.Model.Meshes.Clear();

            List <string> textures = Model.Textures.ToList();

            foreach (var mat in importedMaterials)
            {
            }

            var meshes = GeneratePolygonGroups(importedMeshes, importedMaterials, textures, importer.Settings);

            //Once mesh groups are merged search for bone nodes
            //The bone section is basically a node tree
            //Which contains nodes for meshes
            //We need to remove the original and replace with new ones
            //Then index these in our mesh groups
            if (importer.ImportNewBones)
            {
                //Clear the original bones and nodes
                Model.Skeleton.bones.Clear();
                Model.Model.Bones.Clear();

                List <int> SkinningIndices = new List <int>();
                foreach (var genericBone in skeleton.bones)
                {
                    var scale = genericBone.Scale;
                    var trans = genericBone.Position;
                    var rot   = genericBone.EulerRotation;

                    Bone bone = new Bone();
                    bone.Name        = genericBone.Text;
                    bone.BoneType    = 0;
                    bone.Parent      = genericBone.parentIndex;
                    bone.Zero        = 0;
                    bone.Visible     = false;
                    bone.Scale       = new GFMDLStructs.Vector3(scale.X, scale.Y, scale.Z);
                    bone.Rotation    = new GFMDLStructs.Vector3(rot.X, rot.Y, rot.Z);
                    bone.Translation = new GFMDLStructs.Vector3(trans.X, trans.Y, trans.Z);
                    bone.RadiusStart = new GFMDLStructs.Vector3(0, 0, 0);
                    bone.RadiusEnd   = new GFMDLStructs.Vector3(0, 0, 0);

                    Model.Model.Bones.Add(bone);
                }
            }

            int originIndex = int.MaxValue;

            //Go through each bone and remove the original mesh node
            List <STBone> bonesToRemove = new List <STBone>();

            for (int i = 0; i < Model.Skeleton.bones.Count; i++)
            {
                //Reset bone as rigid
                var node = (GFLXBone)Model.Skeleton.bones[i];
                node.Bone.RigidCheck = new BoneRigidData()
                {
                    Unknown1 = 0
                };
                if (node.Bone.BoneType == 1)
                {
                    node.Bone.BoneType = 0;
                }

                int index = Model.Skeleton.bones.IndexOf(node);

                if (node.Text == "Origin")
                {
                    originIndex = index;
                }

                //Check if the bone is rigged to any meshes and use skinning
                for (int m = 0; m < meshes.Count; m++)
                {
                    if (meshes[m].vertices.Any(x => x.boneNames.Contains(node.Text)))
                    {
                        node.Bone.BoneType   = 1;
                        node.Bone.RigidCheck = null;
                    }
                }

                if (Model.GenericMeshes.Any(x => x.Text == node.Text))
                {
                    bonesToRemove.Add(node);
                    Model.Model.Bones.Remove(node.Bone);
                }

                /*  if (Model.Model.CollisionGroups?.Count != 0)
                 * {
                 *    var collisionGroups = Model.Model.CollisionGroups;
                 *    for (int c = 0; c < collisionGroups.Count; c++)
                 *    {
                 *        if (collisionGroups[c].BoneIndex == i)
                 *        {
                 *
                 *        }
                 *    }
                 * }*/
            }

            foreach (var bone in bonesToRemove)
            {
                Model.Skeleton.bones.Remove(bone);
            }

            bonesToRemove.Clear();

            Model.Model.CollisionGroups = new List <CollisionGroup>();

            List <int> skinningIndices = Model.GenerateSkinningIndices();

            //Set an empty bone with rigging if there is no rigging
            if (importer.Settings.MeshSettings.Any(x => x.HasBoneIndices) && skinningIndices.Count == 0)
            {
                var node = (GFLXBone)Model.Skeleton.bones[0];
                node.Bone.RigidCheck = null;
                node.Bone.BoneType   = 1;
                skinningIndices.Add(0);
            }

            List <string> unmappedBones = new List <string>();

            foreach (var mesh in meshes)
            {
                var setting = importer.Settings.MeshSettings[meshes.IndexOf(mesh)];

                for (int i = 0; i < mesh.vertices.Count; i++)
                {
                    if (setting.SetNormalsToColorChannel2)
                    {
                        mesh.vertices[i].col2 = new OpenTK.Vector4(
                            mesh.vertices[i].nrm.X * 0.5f + 0.5f,
                            mesh.vertices[i].nrm.Y * 0.5f + 0.5f,
                            mesh.vertices[i].nrm.Z * 0.5f + 0.5f,
                            1);
                    }

                    //Single bind if no bones are mapped but setting is enabled
                    if (setting.HasBoneIndices && mesh.vertices[i].boneNames.Count == 0)
                    {
                        mesh.vertices[i].boneIds.Add(skinningIndices.FirstOrDefault());
                        mesh.vertices[i].boneWeights.Add(1);
                    }

                    if (importer.RotationY != 0)
                    {
                        var transform = OpenTK.Matrix4.CreateRotationX(OpenTK.MathHelper.DegreesToRadians(importer.RotationY));
                        mesh.vertices[i].pos = OpenTK.Vector3.TransformPosition(mesh.vertices[i].pos, transform);
                        mesh.vertices[i].nrm = OpenTK.Vector3.TransformPosition(mesh.vertices[i].nrm, transform);
                    }

                    if (importer.Settings.FlipUVsVertical)
                    {
                        mesh.vertices[i].uv0 = new Vector2(0, 1) - mesh.vertices[i].uv0;
                        mesh.vertices[i].uv1 = new Vector2(0, 1) - mesh.vertices[i].uv1;
                        mesh.vertices[i].uv2 = new Vector2(0, 1) - mesh.vertices[i].uv2;
                    }

                    if (importer.Settings.OptmizeZeroWeights)
                    {
                        float[] weightsA = new float[4];

                        int MaxWeight = 255;
                        for (int j = 0; j < 4; j++)
                        {
                            if (mesh.vertices[i].boneWeights.Count < j + 1)
                            {
                                weightsA[j] = 0;
                                MaxWeight   = 0;
                            }
                            else
                            {
                                int weight = (int)(mesh.vertices[i].boneWeights[j] * 255);
                                if (mesh.vertices[i].boneWeights.Count == j + 1)
                                {
                                    weight = MaxWeight;
                                }

                                if (weight >= MaxWeight)
                                {
                                    weight    = MaxWeight;
                                    MaxWeight = 0;
                                }
                                else
                                {
                                    MaxWeight -= weight;
                                }

                                weightsA[j] = weight / 255f;
                            }
                        }

                        mesh.vertices[i].boneWeights = weightsA.ToList();
                    }

                    for (int j = 0; j < mesh.vertices[i].boneNames?.Count; j++)
                    {
                        string boneName  = mesh.vertices[i].boneNames[j];
                        int    boneIndex = Model.Model.Bones.IndexOf(Model.Model.Bones.Where(p => p.Name == boneName).FirstOrDefault());

                        if (boneIndex != -1 && skinningIndices.IndexOf(boneIndex) != -1)
                        {
                            mesh.vertices[i].boneIds.Add(boneIndex);
                        }
                        else
                        {
                            if (!unmappedBones.Contains(boneName))
                            {
                                unmappedBones.Add(boneName);
                            }
                        }
                    }
                }
            }

            //Adjust materials if necessary
            if (importer.Settings.ResetUVTransform)
            {
                foreach (var mat in Model.GenericMaterials)
                {
                    foreach (var param in mat.ValueParams)
                    {
                        if (param.Key.Contains("UVScale"))
                        {
                            param.Value.Value = 1;
                        }
                        if (param.Key.Contains("UVTranslate"))
                        {
                            param.Value.Value = 0;
                        }
                        if (param.Key.Contains("ColorBaseU"))
                        {
                            param.Value.Value = 0;
                        }
                        if (param.Key.Contains("ColorBaseV"))
                        {
                            param.Value.Value = 0;
                        }
                    }
                }
            }

            //Now add brand new mesh nodes
            foreach (var mesh in meshes)
            {
                int index = meshes.IndexOf(mesh);

                var setting = importer.Settings.MeshSettings[index];

                Bone bone = new Bone();
                bone.Name        = mesh.ObjectName;
                bone.BoneType    = 0;
                bone.Parent      = 0;
                bone.Zero        = 0;
                bone.Visible     = false;
                bone.Scale       = new GFMDLStructs.Vector3(1, 1, 1);
                bone.Rotation    = new GFMDLStructs.Vector3(0, 0, 0);
                bone.Translation = new GFMDLStructs.Vector3(0, 0, 0);
                bone.RadiusStart = new GFMDLStructs.Vector3(0, 0, 0);
                bone.RadiusEnd   = new GFMDLStructs.Vector3(0, 0, 0);
                //     bone.RigidCheck = new BoneRigidData();

                Model.Model.Bones.Add(bone);
                int NodeIndex = Model.Model.Bones.IndexOf(bone);

                //Now create the associated group
                var group = new Group();
                group.Bounding  = Model.GenerateBoundingBox(mesh);
                group.BoneIndex = (uint)NodeIndex;
                group.MeshIndex = (uint)index;
                group.Layer     = 0;
                Model.Model.Groups.Add(group);

                //Now create our mesh data
                var meshData = new Mesh();
                Model.Model.Meshes.Add(meshData);

                if (setting.HasTangents || setting.HasBitangents)
                {
                    try {
                        mesh.CalculateTangentBitangent(false);
                    }
                    catch { }
                }

                //Add attributes based on settings
                IList <MeshAttribute> attributes = new List <MeshAttribute>();
                attributes.Add(new MeshAttribute()
                {
                    VertexType   = (uint)VertexType.Position,
                    BufferFormat = (uint)setting.PositionFormat,
                    ElementCount = 3,
                });

                if (setting.HasNormals)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Normal,
                        BufferFormat = (uint)setting.NormalFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasTangents)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Tangents,
                        BufferFormat = (uint)setting.TangentsFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasTexCoord1)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV1,
                        BufferFormat = (uint)setting.TexCoord1Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord2)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV2,
                        BufferFormat = (uint)setting.TexCoord2Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord3)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV3,
                        BufferFormat = (uint)setting.TexCoord3Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasTexCoord4)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.UV4,
                        BufferFormat = (uint)setting.TexCoord4Format,
                        ElementCount = 2,
                    });
                }
                if (setting.HasColor1)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Color1,
                        BufferFormat = (uint)setting.Color1Format,
                        ElementCount = 4,
                    });
                }
                if (setting.HasColor2)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Color2,
                        BufferFormat = (uint)setting.Color2Format,
                        ElementCount = 4,
                    });
                }

                if (setting.HasBoneIndices)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.BoneID,
                        BufferFormat = (uint)setting.BoneIndexFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasWeights)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.BoneWeight,
                        BufferFormat = (uint)setting.BoneWeightFormat,
                        ElementCount = 4,
                    });
                }

                if (setting.HasBitangents)
                {
                    attributes.Add(new MeshAttribute()
                    {
                        VertexType   = (uint)VertexType.Bitangent,
                        BufferFormat = (uint)setting.BitangentnFormat,
                        ElementCount = 4,
                    });
                }

                meshData.Attributes = attributes;
                meshData.SetData(GFLXMeshBufferHelper.CreateVertexDataBuffer(mesh, skinningIndices, attributes));

                //Lastly add the polygon groups
                foreach (var poly in mesh.PolygonGroups)
                {
                    List <ushort> faces = new List <ushort>();
                    for (int f = 0; f < poly.faces.Count; f++)
                    {
                        faces.Add((ushort)poly.faces[f]);
                    }

                    if (poly.MaterialIndex < 0)
                    {
                        poly.MaterialIndex = 0;
                    }

                    meshData.Polygons = new List <MeshPolygon>();
                    meshData.Polygons.Add(new MeshPolygon()
                    {
                        MaterialIndex = (uint)poly.MaterialIndex,
                        Faces         = faces,
                    });
                }
            }

            if (unmappedBones.Count > 0)
            {
                STErrorDialog.Show($"{unmappedBones.Count} bone(s) are not present in the boneset and are unmapped!",
                                   "GFBMDL Importer", string.Join("\n", unmappedBones.ToArray()));
            }

            Console.WriteLine($"");

            //Generate bounding box
            Model.GenerateBoundingBox();
            ReloadModel(Model.Model);

            Model.UpdateVertexData(true);
        }
Example #2
0
 private void UpdateMesh()
 {
     MeshData.SetData(GFLXMeshBufferHelper.CreateVertexDataBuffer(this));
     ParentModel.UpdateVertexData(true);
 }