Beispiel #1
0
        private static void PrintSupported()
        {
            SBConsole.WriteLine("Supported Commands");

            SBConsole.WriteLine("convanim (anim path) (model path) (anim type)");
            SBConsole.WriteLine($"\tSupported Anim Types: {string.Join(", ", MainForm.SupportedAnimExportTypes())}");
        }
Beispiel #2
0
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is MESH mesh)
                {
                    if (mesh.VersionMajor != 1 && mesh.VersionMinor != 10)
                    {
                        SBConsole.WriteLine($"Mesh Version {mesh.VersionMajor}.{mesh.VersionMinor} not supported");
                        return;
                    }
                    if (mesh.UnknownOffset != 0 || mesh.UnknownSize != 0)
                    {
                        SBConsole.WriteLine($"Warning: Unknown Mesh format detected");
                    }

                    SBUltimateModel model = new SBUltimateModel();
                    model.Name           = mesh.ModelName;
                    model.BoundingSphere = new Vector4(mesh.BoundingSphereX, mesh.BoundingSphereY, mesh.BoundingSphereZ, mesh.BoundingSphereRadius);

                    ((SBSceneSSBH)Scene).Model = model;

                    SSBHVertexAccessor accessor = new SSBHVertexAccessor(mesh);
                    {
                        foreach (var meshObject in mesh.Objects)
                        {
                            SBUltimateMesh sbMesh = new SBUltimateMesh();
                            foreach (var attr in meshObject.Attributes)
                            {
                                foreach (var atstring in attr.AttributeStrings)
                                {
                                    UltimateVertexAttribute at;
                                    if (Enum.TryParse(atstring.Name, out at))
                                    {
                                        sbMesh.EnableAttribute(at);
                                    }
                                }
                            }
                            sbMesh.Name       = meshObject.Name;
                            sbMesh.ParentBone = meshObject.ParentBoneName;

                            sbMesh.BoundingSphere = new BoundingSphere(meshObject.BoundingSphereX, meshObject.BoundingSphereY, meshObject.BoundingSphereZ, meshObject.BoundingSphereRadius);
                            sbMesh.AABoundingBox  = new AABoundingBox(new Vector3(meshObject.MinBoundingBoxX, meshObject.MinBoundingBoxY, meshObject.MinBoundingBoxZ),
                                                                      new Vector3(meshObject.MaxBoundingBoxX, meshObject.MaxBoundingBoxY, meshObject.MaxBoundingBoxZ));
                            sbMesh.OrientedBoundingBox = new OrientedBoundingBox(new Vector3(meshObject.OBBCenterX, meshObject.OBBCenterY, meshObject.OBBCenterZ),
                                                                                 new Vector3(meshObject.OBBSizeX, meshObject.OBBSizeY, meshObject.OBBSizeZ),
                                                                                 new Matrix3(meshObject.M11, meshObject.M12, meshObject.M13,
                                                                                             meshObject.M21, meshObject.M22, meshObject.M23,
                                                                                             meshObject.M31, meshObject.M32, meshObject.M33));

                            sbMesh.Indices  = new List <uint>(accessor.ReadIndices(0, meshObject.IndexCount, meshObject));
                            sbMesh.Vertices = CreateVertices(mesh, Scene.Skeleton, meshObject, accessor, sbMesh.Indices.ToArray());
                            model.Meshes.Add(sbMesh);
                        }
                    }
                }
            }
        }
Beispiel #3
0
        public static MODL CreateMODLFile(SBUltimateModel model)
        {
            MODL modl = new MODL();

            modl.ModelEntries = new MODL_Entry[model.Meshes.Count];
            Dictionary <string, int> subindex = new Dictionary <string, int>();
            int i = 0;

            foreach (var mesh in model.Meshes)
            {
                var entry = new MODL_Entry();
                modl.ModelEntries[i++] = entry;

                if (!subindex.ContainsKey(mesh.Name))
                {
                    subindex.Add(mesh.Name, 0);
                }

                entry.MeshName = mesh.Name;
                entry.SubIndex = subindex[mesh.Name];
                if (mesh.Material != null)
                {
                    entry.MaterialName = mesh.Material.Label;
                }
                else
                {
                    SBConsole.WriteLine("Warning: Missing material");
                }
                subindex[mesh.Name]++;
                SBConsole.WriteLine($"Creating modl entry: {entry.MeshName} {entry.SubIndex} {entry.MaterialName}");
            }

            return(modl);
        }
Beispiel #4
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="animPath"></param>
        /// <param name="modelPath"></param>
        /// <param name="output"></param>
        public static void ConvertAnim(string animPath, string modelPath, string output)
        {
            var exporter = MainForm.GetExportableAnimationFromExtension(output);

            if (exporter != null)
            {
                SBConsole.WriteLine($"Converting {animPath} to {Path.ChangeExtension(animPath, output)}");

                var scene = MainForm.LoadScene(modelPath, null);
                if (scene == null)
                {
                    SBConsole.WriteLine("Error Opening Model");
                    return;
                }

                var mod = scene.GetIOModel();

                if (Directory.Exists(animPath))
                {
                    foreach (var v in Directory.GetFiles(animPath))
                    {
                        ConvertAnim(v, Path.ChangeExtension(v, output), SBSkeleton.FromIOSkeleton(mod.Models[0].Skeleton), exporter);
                    }
                }
                else
                {
                    ConvertAnim(animPath, Path.ChangeExtension(animPath, output), SBSkeleton.FromIOSkeleton(mod.Models[0].Skeleton), exporter);
                }
            }
            else
            {
                SBConsole.WriteLine($"Unsupported Extension: {output}");
            }
        }
Beispiel #5
0
        private bool HandleAttribute(XmlReader reader, SBBone bone, string attribute, bool required = true)
        {
            string value = reader.GetAttribute(attribute);
            float  val;

            if (value == null)
            {
                if (required)
                {
                    SBConsole.WriteLine("Expected attribute \"" + attribute + "\"");
                }
                return(false);
            }
            else if (!float.TryParse(value, out val))
            {
                SBConsole.WriteLine("Failed to parse attribute \"" + attribute + "\"");
                return(false);
            }

            if (!WriteValue(bone, attribute, val))
            {
                return(false);
            }

            return(true);
        }
Beispiel #6
0
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is MESH mesh)
                {
                    if (mesh.VersionMajor != 1 && mesh.VersionMinor != 10)
                    {
                        SBConsole.WriteLine($"Mesh Version {mesh.VersionMajor}.{mesh.VersionMinor} not supported");
                        return;
                    }
                    if (mesh.UnknownOffset != 0 || mesh.UnknownSize != 0)
                    {
                        SBConsole.WriteLine($"Warning: Unknown Mesh format detected");
                    }

                    SBUltimateModel model = new SBUltimateModel();
                    model.Name           = mesh.ModelName;
                    model.BoundingSphere = new Vector4(mesh.BoundingSphereX, mesh.BoundingSphereY, mesh.BoundingSphereZ, mesh.BoundingSphereRadius / 2);

                    Vector3 min = new Vector3(mesh.MinBoundingBoxX, mesh.MinBoundingBoxY, mesh.MinBoundingBoxZ);
                    Vector3 max = new Vector3(mesh.MaxBoundingBoxX, mesh.MaxBoundingBoxY, mesh.MaxBoundingBoxZ);

                    model.VolumeCenter = (max + min) / 2;
                    model.VolumeSize   = (max - min) / 2;

                    ((SBSceneSSBH)Scene).Model = model;

                    using (SSBHVertexAccessor accessor = new SSBHVertexAccessor(mesh))
                    {
                        foreach (var meshObject in mesh.Objects)
                        {
                            SBUltimateMesh <UltimateVertex> sbMesh = new SBUltimateMesh <UltimateVertex>();
                            foreach (var attr in meshObject.Attributes)
                            {
                                foreach (var atstring in attr.AttributeStrings)
                                {
                                    MESHAttribute at;
                                    if (Enum.TryParse <MESHAttribute>(atstring.Name, out at))
                                    {
                                        //SBConsole.WriteLine("\tLoaded:" + at.ToString());
                                        sbMesh.ExportAttributes.Add(at);
                                    }
                                }
                            }
                            sbMesh.Name           = meshObject.Name;
                            sbMesh.BoundingSphere = new Vector4(meshObject.BoundingSphereX, meshObject.BoundingSphereY, meshObject.BoundingSphereZ, meshObject.BoundingSphereRadius);
                            sbMesh.ParentBone     = meshObject.ParentBoneName;

                            sbMesh.Indices  = new List <uint>(accessor.ReadIndices(0, meshObject.IndexCount, meshObject));
                            sbMesh.Vertices = CreateVertices(mesh, Scene.Skeleton, meshObject, accessor, sbMesh.Indices.ToArray());
                            model.Meshes.Add(sbMesh);
                        }
                    }
                }
            }
        }
Beispiel #7
0
 /// <summary>
 /// Saves the current framebuffer to specified file path
 /// </summary>
 public void SaveRender(string FileName)
 {
     using (var bitmap = SFGraphics.GLObjects.Framebuffers.Framebuffer.ReadDefaultFramebufferImagePixels(Width, Height, true))
     {
         bitmap.Save(FileName);
         SBConsole.WriteLine($"Viewport render saved to: {FileName}");
     }
 }
Beispiel #8
0
        /// <summary>
        /// converts the rigging to a new skeleton
        /// </summary>
        /// <param name="newSkeleton"></param>
        public void ConvertToSkeleton(SBSkeleton newSkeleton)
        {
            if (Skeleton == null || newSkeleton == null)
            {
                return;
            }
            Dictionary <int, int>    oldToNew           = new Dictionary <int, int>();
            Dictionary <string, int> boneNameToPosition = new Dictionary <string, int>();

            for (int i = 0; i < Skeleton.Bones.Length; i++)
            {
                var boneName = Skeleton.Bones[i].Name;
                if (!boneNameToPosition.ContainsKey(boneName))
                {
                    boneNameToPosition.Add(boneName, i);
                }
            }
            for (int i = 0; i < newSkeleton.Bones.Length; i++)
            {
                if (boneNameToPosition.ContainsKey(newSkeleton.Bones[i].Name))
                {
                    oldToNew.Add(boneNameToPosition[newSkeleton.Bones[i].Name], i);
                }
            }

            // Correct Vertex Rigging
            HashSet <string> mismatchedBones = new HashSet <string>();

            foreach (var mesh in Meshes)
            {
                for (int i = 0; i < mesh.Vertices.Count; i++)
                {
                    var vertex = mesh.Vertices[i];

                    for (int b = 0; b < 4; b++)
                    {
                        if (vertex.BoneWeights[b] > 0 && oldToNew.ContainsKey((int)vertex.BoneIndices[b]))
                        {
                            vertex.BoneIndices[b] = oldToNew[(int)vertex.BoneIndices[b]];
                        }
                        else
                        {
                            var name = newSkeleton.Bones[(int)vertex.BoneIndices[b]].Name;
                            if (!mismatchedBones.Contains(name))
                            {
                                SBConsole.WriteLine($"Warning: missmatched bone {name}");
                                mismatchedBones.Add(name);
                            }
                        }
                    }

                    mesh.Vertices[i] = vertex;
                }
            }

            // accept new skeleton
            Skeleton = newSkeleton;
        }
Beispiel #9
0
        public static void ConvertAnim(string animPath, string output, SBSkeleton skeleton, IExportableAnimation exporter)
        {
            var anim = MainForm.LoadAnimation(animPath, skeleton);

            if (anim == null)
            {
                SBConsole.WriteLine("Error Opening Animation");
                return;
            }
            ConvertAnim(anim, output, skeleton, exporter);
        }
Beispiel #10
0
        public static void Open(string FileName, SBScene Scene)
        {
            SsbhFile File;

            if (Ssbh.TryParseSsbhFile(FileName, out File))
            {
                if (File is Mesh mesh)
                {
                    if (mesh.VersionMajor != 1 && mesh.VersionMinor != 10)
                    {
                        SBConsole.WriteLine($"Mesh Version {mesh.VersionMajor}.{mesh.VersionMinor} not supported");
                        return;
                    }
                    if (mesh.UnknownOffset != 0 || mesh.UnknownSize != 0)
                    {
                        SBConsole.WriteLine($"Warning: Unknown Mesh format detected");
                    }

                    SBUltimateModel model = new SBUltimateModel();
                    model.Name           = mesh.ModelName;
                    model.BoundingSphere = new Vector4(mesh.BoundingSphereCenter.X, mesh.BoundingSphereCenter.Y, mesh.BoundingSphereCenter.Z, mesh.BoundingSphereRadius);

                    ((SBSceneSSBH)Scene).Model = model;

                    SsbhVertexAccessor accessor = new SsbhVertexAccessor(mesh);
                    {
                        foreach (var meshObject in mesh.Objects)
                        {
                            SBUltimateMesh sbMesh = new SBUltimateMesh();
                            sbMesh.EnableAttributes(meshObject);

                            sbMesh.Name       = meshObject.Name;
                            sbMesh.ParentBone = meshObject.ParentBoneName;

                            sbMesh.BoundingSphere = new BoundingSphere(meshObject.BoundingSphereCenter.X, meshObject.BoundingSphereCenter.Y, meshObject.BoundingSphereCenter.Z, meshObject.BoundingSphereRadius);
                            sbMesh.AABoundingBox  = new AABoundingBox(new Vector3(meshObject.BoundingBoxMin.X, meshObject.BoundingBoxMin.Y, meshObject.BoundingBoxMin.Z),
                                                                      new Vector3(meshObject.BoundingBoxMax.X, meshObject.BoundingBoxMax.Y, meshObject.BoundingBoxMax.Z));
                            sbMesh.OrientedBoundingBox = new OrientedBoundingBox(
                                meshObject.OrientedBoundingBoxCenter.ToOpenTK(),
                                meshObject.OrientedBoundingBoxSize.ToOpenTK(),
                                meshObject.OrientedBoundingBoxTransform.ToOpenTK());

                            sbMesh.Indices  = new List <uint>(accessor.ReadIndices(0, meshObject.IndexCount, meshObject));
                            sbMesh.Vertices = CreateVertices(mesh, Scene.Skeleton, meshObject, accessor, sbMesh.Indices.ToArray());
                            model.Meshes.Add(sbMesh);
                        }
                    }
                }
            }
        }
Beispiel #11
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private List <Tuple <double, double> > SimplifyLines(IEnumerable <float> values)
        {
            List <Tuple <double, double> > keys = new List <Tuple <double, double> >();
            int i = 0;

            foreach (var val in values)
            {
                keys.Add(new Tuple <double, double>(i++, val));
            }
            List <Tuple <double, double> > newkeys = new List <Tuple <double, double> >();

            LineSimplification.RamerDouglasPeucker(keys, 0.1, newkeys);
            SBConsole.WriteLine("Simplified " + keys.Count + " to " + newkeys.Count);
            return(newkeys);
        }
Beispiel #12
0
        private SBBone ReadBone(XmlReader reader, SBBone bone)
        {
            SBBone newBone = new SBBone();

            newBone.Transform = Matrix4.Identity;
            if (!reader.ReadToFollowing("SBBone") || reader.NodeType != XmlNodeType.Element || reader.Name != "SBBone")
            {
                SBConsole.WriteLine("Expected bone element");
                return(null);
            }

            string name = reader.GetAttribute("Name");

            if (name != bone.Name)
            {
                SBConsole.WriteLine("Expected bone definition for " + bone.Name +
                                    ", received \"" + name + "\"");
                return(null);
            }

            newBone.Name = bone.Name;
            if (!HandleAttribute(reader, newBone, "TranslateX") ||
                !HandleAttribute(reader, newBone, "TranslateY") ||
                !HandleAttribute(reader, newBone, "TranslateZ") ||
                !HandleAttribute(reader, newBone, "RotationEulerX") ||
                !HandleAttribute(reader, newBone, "RotationEulerY") ||
                !HandleAttribute(reader, newBone, "RotationEulerZ"))
            {
                return(null);
            }

            // Optional attributes
            HandleAttribute(reader, newBone, "ScaleX", false);
            HandleAttribute(reader, newBone, "ScaleY", false);
            HandleAttribute(reader, newBone, "ScaleZ", false);

            foreach (var child in bone.Children)
            {
                SBBone newChild = ReadBone(reader, child);
                if (newChild == null)
                {
                    return(null);
                }
                newBone.AddChild(newChild);
            }

            return(newBone);
        }
Beispiel #13
0
        private void Read(XmlReader reader, SBSkeleton skeleton)
        {
            List <SBBone> roots = new List <SBBone>();

            foreach (var bone in skeleton.Roots)
            {
                SBBone newBone = ReadBone(reader, bone);
                if (newBone == null)
                {
                    SBConsole.WriteLine("Failed to read XML skeleton.");
                    return;
                }
                roots.Add(newBone);
            }

            UpdateSkeleton(skeleton, roots);
        }
Beispiel #14
0
        private bool WriteValue(SBBone bone, string attribute, float value)
        {
            if (attribute.Equals("TranslateX"))
            {
                bone.X = value;
            }
            else if (attribute.Equals("TranslateY"))
            {
                bone.Y = value;
            }
            else if (attribute.Equals("TranslateZ"))
            {
                bone.Z = value;
            }
            else if (attribute.Equals("RotationEulerX"))
            {
                bone.RX = value;
            }
            else if (attribute.Equals("RotationEulerY"))
            {
                bone.RY = value;
            }
            else if (attribute.Equals("RotationEulerZ"))
            {
                bone.RZ = value;
            }
            else if (attribute.Equals("ScaleX"))
            {
                bone.SX = value;
            }
            else if (attribute.Equals("ScaleY"))
            {
                bone.SY = value;
            }
            else if (attribute.Equals("ScaleZ"))
            {
                bone.SZ = value;
            }
            else
            {
                SBConsole.WriteLine("Internal failure");
                return(false);
            }

            return(true);
        }
Beispiel #15
0
        public override void FromIOModel(IOModel iomodel)
        {
            //System.Windows.Forms.MessageBox.Show("Importing Model to DAT not supported");

            // use the existing skeleton always
            iomodel.ConvertToSkeleton((SBSkeleton)Skeleton);

            // single bound vertices are stored in inverse transform positions
            iomodel.InvertSingleBinds();

            // dobjs to import to
            var dobjs = GetMeshObjects();

            foreach (SBHsdMesh m in GetMeshObjects())
            {
                m.DOBJ.Pobj = null;
            }

            var attributeGroup       = MakeRiggedAttributes();
            var singleAttributeGroup = MakeSingleAttributes();

            // get a compressor ready
            // the compressor will handle making the compressed attribute buffers
            POBJ_Generator compressor = new POBJ_Generator();

            // import the iomeshes into their respective dobjs
            foreach (var iomesh in iomodel.Meshes)
            {
                int dobjId = -1;
                int.TryParse(iomesh.Name.Replace("DOBJ_", ""), out dobjId);

                SBConsole.WriteLine(iomesh.Name + " imported:" + (dobjId != -1));

                if (dobjId != -1)
                {
                    var dobj = (SBHsdMesh)dobjs[dobjId];
                    dobj.ImportPOBJs(iomesh, (SBSkeleton)Skeleton, compressor, dobj.ParentBone == "JOBJ_0" ? attributeGroup : singleAttributeGroup);
                }
            }

            // finalizes and remakes the buffer
            compressor.SaveChanges();

            // refresh everything
            RefreshRendering();
        }
Beispiel #16
0
        public void AddKey(float frame, T value, InterpolationType type = InterpolationType.Linear, float TanIn = 0, float TanOut = float.MaxValue)
        {
            if (_keys.ContainsKey(frame))
            {
                SBConsole.WriteLine($"Warning: Two keys cannot share a frame {frame}");
                return;
            }

            SBAnimKey <T> key = new SBAnimKey <T>();

            key.Frame             = frame;
            key.Value             = value;
            key.InTan             = TanIn;
            key.OutTan            = TanOut == float.MaxValue ? TanIn : TanOut;
            key.InterpolationType = type;
            _keys.Add(frame, key);
        }
Beispiel #17
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="iomodel"></param>
        public override void FromIOModel(IOScene iomodel)
        {
            var model = iomodel.Models[0];

            InvertSingleBinds(model);

            // dobjs to import to
            var dobjs = GetMeshObjects();

            // clear pobjs
            foreach (SBHsdMesh m in GetMeshObjects())
            {
                m.DOBJ.Pobj = null;
            }

            var attributeGroup       = MakeRiggedAttributes();
            var singleAttributeGroup = MakeSingleAttributes();

            // get a compressor ready
            // the compressor will handle making the compressed attribute buffers
            POBJ_Generator compressor = new POBJ_Generator();

            // import the iomeshes into their respective dobjs
            foreach (var iomesh in model.Meshes)
            {
                int dobjId = -1;
                int.TryParse(iomesh.Name.Replace("DOBJ_", ""), out dobjId);

                SBConsole.WriteLine(iomesh.Name + " imported:" + (dobjId != -1));

                if (dobjId != -1)
                {
                    var dobj = (SBHsdMesh)dobjs[dobjId];
                    dobj.ImportPOBJs(iomesh, (SBSkeleton)Skeleton, compressor, dobj.ParentBone == "JOBJ_0" ? attributeGroup : singleAttributeGroup);
                }
            }

            // finalizes and remakes the buffer
            compressor.SaveChanges();

            // refresh everything
            RefreshRendering();
        }
Beispiel #18
0
        /// <summary>
        /// Optimized the vertex index size by removing duplicate vertices
        /// </summary>
        public void Optimize()
        {
            Indices.Clear();

            List <IOVertex>             NewVertices   = new List <IOVertex>();
            Dictionary <IOVertex, uint> vertexToIndex = new Dictionary <IOVertex, uint>();

            foreach (var vertex in Vertices)
            {
                if (!vertexToIndex.ContainsKey(vertex))
                {
                    vertexToIndex.Add(vertex, (uint)NewVertices.Count);
                    NewVertices.Add(vertex);
                }
                Indices.Add(vertexToIndex[vertex]);
            }

            SBConsole.WriteLine($"Optimized {Name} {Vertices.Count} -> {NewVertices.Count}");

            Vertices.Clear();
            Vertices.AddRange(NewVertices);
        }
Beispiel #19
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="skeleton"></param>
        /// <returns></returns>
        public static SBSkeleton FromIOSkeleton(IOSkeleton ioskel)
        {
            SBSkeleton skel = new SBSkeleton();

            Dictionary <IOBone, SBBone> iotosb = new Dictionary <IOBone, SBBone>();

            foreach (var iobone in ioskel.BreathFirstOrder())
            {
                SBConsole.WriteLine(iobone.Name + " " + iobone.Scale + " " + iobone.Rotation + " " + iobone.Translation);
                SBBone bone = new SBBone()
                {
                    Name = iobone.Name,
                    SX   = iobone.ScaleX,
                    SY   = iobone.ScaleY,
                    SZ   = iobone.ScaleZ,
                    RX   = iobone.RotationEuler.X,
                    RY   = iobone.RotationEuler.Y,
                    RZ   = iobone.RotationEuler.Z,
                    X    = iobone.TranslationX,
                    Y    = iobone.TranslationY,
                    Z    = iobone.TranslationZ,
                };

                SBConsole.WriteLine(bone.Name + " " + bone.Translation.ToString() + " " + bone.Scale.ToString() + " " + bone.RotationQuaternion.ToString());

                iotosb.Add(iobone, bone);

                if (iobone.Parent == null)
                {
                    skel.AddRoot(bone);
                }
                else
                {
                    bone.Parent = iotosb[iobone.Parent];
                }
            }

            return(skel);
        }
Beispiel #20
0
        public static void ProcessCommands(string[] args)
        {
            switch (args[0])
            {
            case "convanim":
                if (args.Length < 4)
                {
                    SBConsole.WriteLine("Invalid argument count, expected 4");
                    PrintSupported();
                }
                else
                {
                    ConvertAnim(args[1], args[2], args[3]);
                }
                break;

            default:
                SBConsole.WriteLine($"Unknown command {args[0]}");
                PrintSupported();
                break;
            }
        }
Beispiel #21
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="FileName"></param>
        public override void ExportSceneToFile(string FileName)
        {
            if (Model == null)
            {
                return;
            }

            string name       = Path.GetDirectoryName(FileName) + "/" + Path.GetFileNameWithoutExtension(FileName);
            string simpleName = Path.GetFileNameWithoutExtension(FileName);

            SBConsole.WriteLine("Creating MODL...");
            var modl = MODL_Loader.CreateMODLFile((SBUltimateModel)Model);

            modl.ModelFileName     = simpleName;
            modl.SkeletonFileName  = $"{simpleName}.nusktb";
            modl.MeshString        = $"{simpleName}.numshb";
            modl.UnknownFileName   = "";
            modl.MaterialFileNames = new MODL_MaterialName[] { new MODL_MaterialName()
                                                               {
                                                                   MaterialFileName = $"{simpleName}.numatb"
                                                               } };
            SBConsole.WriteLine("Done");
            SSBH.TrySaveSSBHFile(FileName, modl);

            SBConsole.WriteLine($"Creating MESH... {name}.numshb");
            var mesh = MESH_Loader.CreateMESH((SBUltimateModel)Model, (SBSkeleton)Skeleton);

            SBConsole.WriteLine("Done");
            SSBH.TrySaveSSBHFile(name + ".numshb", mesh);

            SBConsole.WriteLine($"Creating SKEL.. {name}.nusktb");
            SKEL_Loader.Save(name + ".nusktb", this);
            SBConsole.WriteLine("Done");

            //SBConsole.WriteLine("Creating MATL...");
        }
Beispiel #22
0
        public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton)
        {
            SBAnimation anim = new SBAnimation();

            HSDRawFile f = new HSDRawFile(FileName);

            foreach (var root in f.Roots)
            {
                if (root == null || root.Data == null)
                {
                    continue;
                }
                anim.Name = root.Name;
                if (root.Data is HSD_AnimJoint joint)
                {
                    var joints = joint.BreathFirstList;

                    int nodeIndex = -1;
                    foreach (var j in joints)
                    {
                        nodeIndex++;
                        if (j.AOBJ == null || j.AOBJ.FObjDesc == null)
                        {
                            continue;
                        }

                        SBConsole.WriteLine(nodeIndex + " " + j.Flags.ToString("X8") + " " + j.AOBJ.Flags.ToString());

                        SBTransformAnimation a = new SBTransformAnimation();
                        if (nodeIndex < skeleton.Bones.Length)
                        {
                            a.Name = skeleton.Bones[nodeIndex].Name;
                        }
                        else
                        {
                            a.Name = "JOBJ_" + nodeIndex;
                        }
                        anim.TransformNodes.Add(a);

                        anim.FrameCount = Math.Max(anim.FrameCount, j.AOBJ.EndFrame);

                        foreach (var fobj in j.AOBJ.FObjDesc.List)
                        {
                            a.Tracks.Add(DecodeFOBJ(fobj.ToFOBJ()));
                        }
                    }
                }
                if (root.Data is HSD_FigaTree tree)
                {
                    anim.FrameCount = tree.FrameCount;
                    int nodeIndex = 0;
                    foreach (var node in tree.Nodes)
                    {
                        SBTransformAnimation a = new SBTransformAnimation();
                        a.Name = skeleton.Bones[nodeIndex++].Name;
                        anim.TransformNodes.Add(a);

                        foreach (var att in node.Tracks)
                        {
                            if (att.FOBJ == null)
                            {
                                continue;
                            }

                            a.Tracks.Add(DecodeFOBJ(att.FOBJ));
                        }
                    }
                }
                if (root.Data is HSD_MatAnimJoint matjoint)
                {
                    var joints = matjoint.BreathFirstList;

                    anim.FrameCount = 0;

                    int nodeIndex = -1;
                    foreach (var j in joints)
                    {
                        if (j.MaterialAnimation == null)
                        {
                            continue;
                        }

                        var matAnims = j.MaterialAnimation.List;

                        foreach (var manim in matAnims)
                        {
                            nodeIndex++;
                            var aobj = manim.AnimationObject;
                            if (aobj != null)
                            {
                                anim.FrameCount = Math.Max(anim.FrameCount, aobj.EndFrame);
                            }

                            var texanim = manim.TextureAnimation;

                            if (texanim == null)
                            {
                                continue;
                            }
                            var texAOBJ = texanim.AnimationObject;

                            if (texAOBJ == null || texAOBJ.FObjDesc == null)
                            {
                                continue;
                            }

                            anim.FrameCount = Math.Max(anim.FrameCount, texAOBJ.EndFrame);

                            //TODO: tex anim is a list
                            if (texanim != null)
                            {
                                SBTextureAnimation textureAnim = new SBTextureAnimation();
                                anim.TextureNodes.Add(textureAnim);
                                textureAnim.MeshName        = "DOBJ_" + nodeIndex;
                                textureAnim.TextureAttibute = texanim.GXTexMapID.ToString();

                                textureAnim.Keys = DecodeFOBJ(texAOBJ.FObjDesc.ToFOBJ()).Keys;

                                for (int i = 0; i < texanim.ImageCount; i++)
                                {
                                    HSD_TOBJ tobj = new HSD_TOBJ();
                                    tobj.ImageData = texanim.ImageBuffers.Array[i].Data;
                                    if (texanim.TlutCount > i)
                                    {
                                        tobj.TlutData = texanim.TlutBuffers.Array[i].Data;
                                    }
                                    var surface = new SBSurface();
                                    surface.Arrays.Add(new MipArray()
                                    {
                                        Mipmaps = new List <byte[]>()
                                        {
                                            tobj.GetDecodedImageData()
                                        }
                                    });
                                    surface.Width          = tobj.ImageData.Width;
                                    surface.Height         = tobj.ImageData.Height;
                                    surface.PixelFormat    = PixelFormat.Bgra;
                                    surface.PixelType      = PixelType.UnsignedByte;
                                    surface.InternalFormat = InternalFormat.Rgba;
                                    textureAnim.Surfaces.Add(surface);
                                }
                            }
                        }
                    }

                    SBConsole.WriteLine(nodeIndex);
                }
            }

            return(anim);
        }
Beispiel #23
0
        public IOModel ImportIOModel(string FileName)
        {
            IOModel    model    = new IOModel();
            SBSkeleton skeleton = new SBSkeleton();

            model.Skeleton = skeleton;

            var test = Fbx.FbxIO.ReadBinary(FileName);

            if (test.Version != Fbx.FbxVersion.v7_4)
            {
                throw new NotSupportedException($"Only FBX version 7.4 is currently supported: Imported version = {test.Version}");
            }

            // global settings
            float Scale = 1;

            // read global settings
            var settings = test.GetNodesByName("GlobalSettings");

            if (settings.Length != 0)
            {
                var prop70 = settings[0].GetNodesByName("Properties70");
                if (prop70.Length != 0)
                {
                    foreach (var property in prop70[0].Nodes)
                    {
                        if (property == null)
                        {
                            continue;
                        }
                        if (property.Properties.Count > 0 && property.Name == "P")
                        {
                            //TODO: this is inaccurate...
                            //if (property.Properties[0].Equals("UnitScaleFactor"))
                            //    Scale = (float)(double)property.Properties[4];
                        }
                    }
                }
            }

            FbxAccessor accessor = new FbxAccessor(FileName);

            //Bones
            var limbs = accessor.GetLimbNodes();

            SBConsole.WriteLine($"Limb Node Count: {limbs.Length}");

            foreach (var limb in limbs)
            {
                skeleton.AddRoot(ConvertLimbToSBBone(limb));
            }
            foreach (var root in skeleton.Roots)
            {
                root.Scale *= Scale;
            }

            // Fast access to bone indices
            Dictionary <string, int> BoneNameToIndex = new Dictionary <string, int>();

            foreach (var b in skeleton.Bones)
            {
                BoneNameToIndex.Add(b.Name, skeleton.IndexOfBone(b));
            }

            // Mesh

            var models = accessor.GetModels();

            SBConsole.WriteLine($"Model Node Count: {models.Count}");

            int YupAxis = accessor.GetOriginalXAxis();

            SBConsole.WriteLine("Yup: " + YupAxis);
            foreach (var mod in models)
            {
                // rotation 90
                Matrix4 transform = (ImportSettings.Rotate90 ? Matrix4.CreateRotationX(-90 * DegToRag) : Matrix4.Identity) * GetModelTransform(mod);

                foreach (var geom in mod.Geometries)
                {
                    IOMesh mesh = new IOMesh();
                    mesh.Name = mod.Name;
                    model.Meshes.Add(mesh);

                    // Create Rigging information
                    Vector4[] BoneIndices = new Vector4[geom.Vertices.Length];
                    Vector4[] BoneWeights = new Vector4[geom.Vertices.Length];
                    foreach (var deformer in geom.Deformers)
                    {
                        //TODO: this shouldn't happen...
                        if (!BoneNameToIndex.ContainsKey(deformer.Name))
                        {
                            continue;
                        }
                        int index = BoneNameToIndex[deformer.Name];

                        for (int i = 0; i < deformer.Indices.Length; i++)
                        {
                            int vertexIndex = deformer.Indices[i];
                            for (int j = 0; j < 4; j++)
                            {
                                if (BoneWeights[vertexIndex][j] == 0)
                                {
                                    BoneIndices[vertexIndex][j] = index;
                                    BoneWeights[vertexIndex][j] = (float)deformer.Weights[i];
                                    break;
                                }
                            }
                        }
                        //SBConsole.WriteLine(deformer.Name + " " + deformer.Weights.Length + " " + deformer.Indices.Length + " " + index);
                    }

                    // Explanation:
                    // negative values are used to indicate a stopping point for the face
                    // so every 3rd index needed to be adjusted
                    for (int i = 0; i < geom.Indices.Length; i += 3)
                    {
                        mesh.Indices.Add((uint)i);
                        mesh.Indices.Add((uint)i + 1);
                        mesh.Indices.Add((uint)i + 2);
                        mesh.Vertices.Add(CreateVertex(transform, geom, i, BoneIndices, BoneWeights, Scale));
                        mesh.Vertices.Add(CreateVertex(transform, geom, i + 1, BoneIndices, BoneWeights, Scale));
                        mesh.Vertices.Add(CreateVertex(transform, geom, i + 2, BoneIndices, BoneWeights, Scale));
                    }

                    mesh.HasPositions = true;

                    //SBConsole.WriteLine(geom.Vertices.Length);
                    foreach (var layer in geom.Layers)
                    {
                        switch (layer.Name)
                        {
                        case "LayerElementNormal":
                        case "LayerElementUV":
                        case "LayerElementColor":
                            break;

                        default:
                            SBConsole.WriteLine(layer.Name + " " + layer.ReferenceInformationType + " " + layer.Data.Length + " " + (layer.ReferenceInformationType.Equals("IndexToDirect") ? layer.Indices.Length.ToString() : ""));
                            break;
                        }
                    }
                    mesh.Optimize();
                }
            }

            return(model);
        }
Beispiel #24
0
        public static void Open(string FilePath, SBScene Scene)
        {
            using (BinaryReader reader = new BinaryReader(new FileStream(FilePath, FileMode.Open)))
            {
                // TODO: Why are there empty streams?
                if (reader.BaseStream.Length == 0)
                {
                    return;
                }

                SBSurface surface = new SBSurface();

                reader.BaseStream.Position = reader.BaseStream.Length - 0xB0;

                int[] mipmapSizes = new int[16];
                for (int i = 0; i < mipmapSizes.Length; i++)
                {
                    mipmapSizes[i] = reader.ReadInt32();
                }

                reader.ReadChars(4); // TNX magic

                string texName = ReadTexName(reader);
                surface.Name = texName;

                surface.Width  = reader.ReadInt32();
                surface.Height = reader.ReadInt32();
                surface.Depth  = reader.ReadInt32();

                var Format = (NUTEX_FORMAT)reader.ReadByte();

                // hack
                surface.IsSRGB = Format.ToString().ToLower().Contains("srgb");

                SBConsole.WriteLine($"Loaded NUTEX: {surface.Name} Format: {Format.ToString()}");

                if (pixelFormatByNuTexFormat.ContainsKey(Format))
                {
                    surface.PixelFormat = pixelFormatByNuTexFormat[Format];
                }
                if (internalFormatByNuTexFormat.ContainsKey(Format))
                {
                    surface.InternalFormat = internalFormatByNuTexFormat[Format];
                }

                reader.ReadByte();

                ushort Padding = reader.ReadUInt16();
                reader.ReadUInt32();

                int    MipCount     = reader.ReadInt32();
                int    Alignment    = reader.ReadInt32();
                int    ArrayCount   = reader.ReadInt32();
                int    ImageSize    = reader.ReadInt32();
                char[] Magic        = reader.ReadChars(4);
                int    MajorVersion = reader.ReadInt16();
                int    MinorVersion = reader.ReadInt16();

                uint blkWidth  = (uint)blkDims[Format].X;
                uint blkHeight = (uint)blkDims[Format].Y;

                uint blockHeight     = Tools.SwitchSwizzler.GetBlockHeight(Tools.SwitchSwizzler.DivRoundUp((uint)surface.Height, blkHeight));
                uint BlockHeightLog2 = (uint)Convert.ToString(blockHeight, 2).Length - 1;
                uint tileMode        = 0;

                uint bpp = GetBpps(Format);

                //TODO: Read mipmaps
                reader.BaseStream.Position = 0;
                int blockHeightShift = 0;
                for (int i = 0; i < 1; i++)
                {
                    int size = mipmapSizes[i];

                    if (i == 0 && size % Alignment != 0)
                    {
                        size += Alignment - (size % Alignment);
                    }

                    byte[] deswiz  = Tools.SwitchSwizzler.Deswizzle((uint)surface.Width, (uint)surface.Height, blkWidth, blkHeight, 0, bpp, tileMode, (int)Math.Max(0, BlockHeightLog2 - blockHeightShift), reader.ReadBytes(ImageSize));
                    byte[] trimmed = new byte[mipmapSizes[0]];
                    Array.Copy(deswiz, 0, trimmed, 0, trimmed.Length);

                    surface.Mipmaps.Add(trimmed);
                }

                Scene.Surfaces.Add(surface);
            }
        }
Beispiel #25
0
        /// <summary>
        /// Load an ultimate mesh from file to the given scene
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="Scene"></param>
        public static void Open(string FileName, SBScene Scene)
        {
            SsbhFile File;

            if (Ssbh.TryParseSsbhFile(FileName, out File))
            {
                if (File is Matl matl)
                {
                    if (matl.MajorVersion != 1 && matl.MinorVersion != 6)
                    {
                        SBConsole.WriteLine($"Warning: Mesh Version {matl.MajorVersion}.{matl.MinorVersion} not supported");
                    }

                    var MaterialProps = typeof(UltimateMaterial).GetProperties();
                    // use dictionary for faster lookup
                    Dictionary <string, PropertyInfo> NameToProperty = new Dictionary <string, PropertyInfo>();
                    foreach (var prop in MaterialProps)
                    {
                        var attrName = prop.Name;
                        if (attrName != null)
                        {
                            NameToProperty.Add(attrName, prop);
                        }
                    }

                    foreach (var entry in matl.Entries)
                    {
                        UltimateMaterial material = new UltimateMaterial();
                        material.Name  = entry.ShaderLabel;
                        material.Label = entry.MaterialLabel;

                        Scene.Materials.Add(material);

                        foreach (var attr in entry.Attributes)
                        {
                            if (NameToProperty.ContainsKey(attr.ParamId.ToString()))
                            {
                                var prop = NameToProperty[attr.ParamId.ToString()];
                                if (prop.PropertyType == typeof(SBMatAttrib <string>))
                                {
                                    material.SetProperty(attr.ParamId.ToString(), attr.DataObject.ToString());
                                }
                                else
                                if (prop.PropertyType == typeof(SBMatAttrib <Vector4>))
                                {
                                    material.SetProperty(attr.ParamId.ToString(), MATLVectorToGLVector((MatlAttribute.MatlVector4)attr.DataObject));
                                }
                                else
                                {
                                    material.SetProperty(attr.ParamId.ToString(), attr.DataObject);
                                }
                            }
                            else
                            {
                                switch (attr.ParamId)
                                {
                                case MatlEnums.ParamId.RasterizerState0:
                                    material.RasterizerState = (MatlAttribute.MatlRasterizerState)attr.DataObject;
                                    break;

                                case MatlEnums.ParamId.BlendState0:
                                    material.BlendState = (MatlAttribute.MatlBlendState)attr.DataObject;
                                    break;

                                default:
                                    //SBConsole.WriteLine("Extra Param: " + attr.ParamID.ToString() + " = " + attr.DataObject.ToString());
                                    material.extraParams.Add(attr.ParamId, attr.DataObject);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #26
0
        /// <summary>
        /// Load an ultimate mesh from file to the given scene
        /// </summary>
        /// <param name="FileName"></param>
        /// <param name="Scene"></param>
        public static void Open(string FileName, SBScene Scene)
        {
            ISSBH_File File;

            if (SSBH.TryParseSSBHFile(FileName, out File))
            {
                if (File is MATL matl)
                {
                    if (matl.MajorVersion != 1 && matl.MinorVersion != 6)
                    {
                        SBConsole.WriteLine($"Warning: Mesh Version {matl.MajorVersion}.{matl.MinorVersion} not supported");
                    }

                    var MaterialProps = typeof(UltimateMaterial).GetProperties();
                    // use dictionary for faster lookup
                    Dictionary <string, PropertyInfo> NameToProperty = new Dictionary <string, PropertyInfo>();
                    foreach (var prop in MaterialProps)
                    {
                        var attrName = (MATLLoaderAttributeName)prop.GetCustomAttribute(typeof(MATLLoaderAttributeName));
                        if (attrName != null)
                        {
                            NameToProperty.Add(attrName.Name, prop);
                        }
                    }

                    foreach (var entry in matl.Entries)
                    {
                        UltimateMaterial material = new UltimateMaterial();
                        material.Name  = entry.MaterialName;
                        material.Label = entry.MaterialLabel;

                        Scene.Materials.Add(material);

                        foreach (var attr in entry.Attributes)
                        {
                            if (NameToProperty.ContainsKey(attr.ParamID.ToString()))
                            {
                                var prop = NameToProperty[attr.ParamID.ToString()];
                                if (prop.PropertyType == typeof(SBMatAttrib <string>))
                                {
                                    ((SBMatAttrib <string>)prop.GetValue(material)).Value = attr.DataObject.ToString();
                                    //foreach (var surface in Scene.Surfaces)
                                    //    if (surface.Name == attr.DataObject.ToString())
                                    //        prop.SetValue(material, surface);
                                }
                                if (prop.PropertyType == typeof(SBMatAttrib <Vector4>))
                                {
                                    ((SBMatAttrib <Vector4>)prop.GetValue(material)).Value = MATLVectorToGLVector((MatlAttribute.MatlVector4)attr.DataObject);
                                }
                                if (prop.PropertyType == typeof(SBMatAttrib <float>))
                                {
                                    ((SBMatAttrib <float>)prop.GetValue(material)).Value = (float)attr.DataObject;
                                }
                                if (prop.PropertyType == typeof(SBMatAttrib <bool>))
                                {
                                    ((SBMatAttrib <bool>)prop.GetValue(material)).Value = (bool)attr.DataObject;
                                }
                            }
                            else
                            {
                                switch (attr.ParamID)
                                {
                                case MatlEnums.ParamId.RasterizerState0:
                                    material.RasterizerState = (MatlAttribute.MatlRasterizerState)attr.DataObject;
                                    break;

                                case MatlEnums.ParamId.BlendState0:
                                    material.BlendState = (MatlAttribute.MatlBlendState)attr.DataObject;
                                    break;

                                default:
                                    SBConsole.WriteLine("Extra Param: " + attr.ParamID.ToString() + " = " + attr.DataObject.ToString());
                                    material.extraParams.Add(attr.ParamID, attr.DataObject);
                                    break;
                                }
                            }
                        }
                    }
                }
            }
        }
Beispiel #27
0
        /// <summary>
        /// Loads the scene from a NUMDLB file
        /// </summary>
        /// <param name="FileName"></param>
        public override void LoadFromFile(string FileName)
        {
            string folderPath = Path.GetDirectoryName(FileName);

            ISSBH_File File;

            if (!SSBH.TryParseSSBHFile(FileName, out File))
            {
                return;
            }

            MODL modl = (MODL)File;

            string meshPath = "";
            string skelPath = "";
            string matlPath = "";

            foreach (string file in Directory.EnumerateFiles(folderPath))
            {
                // load textures
                if (file.EndsWith(".nutexb"))
                {
                    NUTEX_Loader.Open(file, this);
                }

                string fileName = Path.GetFileName(file);
                if (fileName.Equals(modl.SkeletonFileName))
                {
                    skelPath = file;
                }
                if (fileName.Equals(modl.MeshString))
                {
                    meshPath = file;
                }
                if (fileName.Equals(modl.MaterialFileNames[0].MaterialFileName))
                {
                    matlPath = file;
                }
            }
            // import order Skeleton+Textures->Materials->Mesh
            // mesh needs to be loaded after skeleton
            if (skelPath != "")
            {
                SBConsole.WriteLine($"Importing skeleton: {Path.GetFileName(skelPath)}");
                SKEL_Loader.Open(skelPath, this);
            }
            if (matlPath != "")
            {
                SBConsole.WriteLine($"Importing materials: {Path.GetFileName(matlPath)}");
                MATL_Loader.Open(matlPath, this);
            }
            if (meshPath != "")
            {
                SBConsole.WriteLine($"Importing mesh: {Path.GetFileName(meshPath)}");
                MESH_Loader.Open(meshPath, this);

                // set materials
                foreach (var entry in modl.ModelEntries)
                {
                    UltimateMaterial currentMaterial = null;
                    foreach (UltimateMaterial matentry in Materials)
                    {
                        if (matentry.Label.Equals(entry.MaterialName))
                        {
                            currentMaterial = matentry;
                            break;
                        }
                    }
                    if (currentMaterial == null)
                    {
                        continue;
                    }

                    int    subindex = 0;
                    string prevMesh = "";
                    if (Model != null)
                    {
                        foreach (var mesh in Model.Meshes)
                        {
                            if (prevMesh.Equals(mesh.Name))
                            {
                                subindex++;
                            }
                            else
                            {
                                subindex = 0;
                            }
                            prevMesh = mesh.Name;
                            if (subindex == entry.SubIndex && mesh.Name.Equals(entry.MeshName))
                            {
                                mesh.Material = currentMaterial;
                                break;
                            }
                        }
                    }
                }
            }
        }
Beispiel #28
0
        public SBAnimation ImportSBAnimation(string FileName, SBSkeleton skeleton, string jvcPath)
        {
            var sbAnim = new SBAnimation();

            var jointTable = GetJointTable(jvcPath);

            var anim = new Anim();

            using (BinaryReaderExt r = new BinaryReaderExt(new FileStream(FileName, FileMode.Open)))
                anim.Parse(r);

            float scale = Settings.FrameScale;

            sbAnim.FrameCount = (float)(scale * anim.EndTime);

            foreach (var j in anim.Joints)
            {
                if (j.BoneID == -1)
                {
                    continue;
                }

                if (j.BoneID >= jointTable.Length || jointTable[j.BoneID] == -1 || jointTable[j.BoneID] >= skeleton.Bones.Length)
                {
                    continue;
                }

                var bone = skeleton.Bones[jointTable[j.BoneID]];


                SBTransformAnimation node = sbAnim.TransformNodes.Find(e => e.Name == bone.Name);
                if (node == null)
                {
                    node      = new SBTransformAnimation();
                    node.Name = bone.Name;
                    sbAnim.TransformNodes.Add(node);
                }
                //Console.WriteLine(bone.Name);

                if (j.Flag3 == 0x21)
                {
                    foreach (var k in j.Keys)
                    {
                        //Console.WriteLine($"\t{k.Time} {k.X} {k.Y} {k.Z} {k.W}");
                        node.AddKey((float)Math.Ceiling(k.Time * scale), bone.X + k.X, SBTrackType.TranslateX);
                        node.AddKey((float)Math.Ceiling(k.Time * scale), bone.Y + k.Y, SBTrackType.TranslateY);
                        node.AddKey((float)Math.Ceiling(k.Time * scale), bone.Z + k.Z, SBTrackType.TranslateZ);
                    }
                }
                else
                if (j.Flag3 == 0x28)
                {
                    var eul0 = ToQuat(bone.RotationQuaternion, j.Keys[0].W, new Vector3(j.Keys[0].X, j.Keys[0].Y, j.Keys[0].Z));
                    node.AddKey(0, eul0.X, SBTrackType.RotateX, InterpolationType.Step);
                    node.AddKey(0, eul0.Y, SBTrackType.RotateY, InterpolationType.Step);
                    node.AddKey(0, eul0.Z, SBTrackType.RotateZ, InterpolationType.Step);
                    node.AddKey(0, eul0.W, SBTrackType.RotateW, InterpolationType.Step);
                    foreach (var k in j.Keys)
                    {
                        var eul = ToQuat(bone.RotationQuaternion, k.W, new Vector3(k.X, k.Y, k.Z));

                        node.AddKey((float)Math.Ceiling(k.Time * scale), eul.X, SBTrackType.RotateX);
                        node.AddKey((float)Math.Ceiling(k.Time * scale), eul.Y, SBTrackType.RotateY);
                        node.AddKey((float)Math.Ceiling(k.Time * scale), eul.Z, SBTrackType.RotateZ);
                        node.AddKey((float)Math.Ceiling(k.Time * scale), eul.W, SBTrackType.RotateW);
                    }
                }
                else
                {
                    SBConsole.WriteLine("Unknown MOT Track Type " + j.Flag3.ToString("X"));
                }
            }

            sbAnim.ConvertRotationKeysToEuler();

            return(sbAnim);
        }
Beispiel #29
0
        public static SBSurface Import(string FileName)
        {
            SBSurface surface = new SBSurface();

            using (BinaryReaderExt reader = new BinaryReaderExt(new FileStream(FileName, FileMode.Open)))
            {
                DDS_Header header = new DDS_Header();
                header.Read(reader);

                surface.Name   = Path.GetFileNameWithoutExtension(FileName);
                surface.Width  = header.dwWidth;
                surface.Height = header.dwHeight;
                if (header.dwFlags.HasFlag(DDSD.DEPTH))
                {
                    surface.Depth = header.dwDepth;
                }
                else
                {
                    surface.Depth = 1;
                }

                if (header.ddspf.dwFourCC == 0x31545844)
                {
                    surface.InternalFormat = InternalFormat.CompressedRgbaS3tcDxt1Ext;
                }
                else
                if (header.ddspf.dwFourCC == 0x30315844)
                {
                    surface.InternalFormat = DXGItoInternal(header.DXT10Header.dxgiFormat);
                    if (surface.InternalFormat == 0)
                    {
                        System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.DXT10Header.dxgiFormat);

                        return(null);
                    }
                }
                else
                {
                    if (((FourCC_DXGI)header.ddspf.dwFourCC) == FourCC_DXGI.D3DFMT_A32B32G32R32F)
                    {
                        surface.InternalFormat = InternalFormat.Rgba32f;
                        surface.PixelFormat    = PixelFormat.Rgba;
                        surface.PixelType      = PixelType.Float;
                    }
                    else
                    {
                        System.Windows.Forms.MessageBox.Show("DDS format not supported " + header.ddspf.dwFourCC.ToString("X"));
                        return(null);
                    }
                }


                // TODO: read other mips
                int w = surface.Width;
                int h = surface.Height;
                //SBConsole.WriteLine(header.dwCaps.ToString() + " " + header.dwCaps2.ToString() + " " + header.dwFlags.ToString());
                for (int array = 0; array < (header.dwCaps2.HasFlag(DDSCAPS2.CUBEMAP_ALLFACES) ? 6 : 1); array++)
                {
                    w = surface.Width;
                    h = surface.Height;
                    var mip = new MipArray();

                    for (int i = 0; i < (header.dwFlags.HasFlag(DDSD.MIPMAPCOUNT) ? header.dwMipMapCount : 1); i++)
                    {
                        var mipSize = Math.Max(1, ((w + 3) / 4)) * Math.Max(1, ((h + 3) / 4)) * (int)TextureFormatInfo.GetBPP(surface.InternalFormat);

                        if (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat) != 0)
                        {
                            mipSize += (int)(TextureFormatInfo.GetBPP(surface.InternalFormat) - (mipSize % TextureFormatInfo.GetBPP(surface.InternalFormat)));
                        }

                        var data = reader.ReadBytes(mipSize);

                        mip.Mipmaps.Add(data);
                        w /= 2;
                        h /= 2;
                    }

                    surface.Arrays.Add(mip);
                }
                if (reader.Position != reader.BaseStream.Length)
                {
                    SBConsole.WriteLine("Warning: error reading dds " + reader.Position.ToString("X"));
                }
            }



            return(surface);
        }
Beispiel #30
0
        private static void Draw(Camera camera, string Text, Matrix4 Transform, Vector3 Color, Vector2 WindowPosition, int Size = 16, bool Blend = false, bool Center = false, bool RelativeToWorld = true)
        {
            GL.PushAttrib(AttribMask.AllAttribBits);
            GL.Enable(EnableCap.Texture2D);

            if (Blend)
            {
                GL.Enable(EnableCap.Blend);
                GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);
            }

            if (characterShape == null)
            {
                characterShape = new CharacterShape();
            }

            var shader = ShaderManager.GetShader("Text");

            if (shader != null && shader.LinkStatusIsOk)
            {
                shader.UseProgram();

                shader.SetTexture("fontSheet", DefaultTextures.Instance.renderFont, 0);

                shader.SetMatrix4x4("transform", ref Transform);

                shader.SetFloat("letterSize", Size);
                shader.SetVector2("windowSize", new Vector2(camera.RenderHeight, camera.RenderWidth));
                shader.SetVector2("windowPosition", WindowPosition);
                shader.SetBoolToInt("relativeToWorld", RelativeToWorld);

                int offset     = 0;
                int LetterSize = Size - (int)(0.45f * Size);
                if (Center)
                {
                    offset = -(Text.Length * LetterSize) / 2;
                }
                // TODO: drawing each letter individually can be slow
                // maybe build a mesh for them?
                foreach (char c in Text.ToCharArray())
                {
                    shader.SetFloat("letterIndex", c - ' ');

                    shader.SetVector3("letterColor", Color);
                    shader.SetVector2("letterPosition", new Vector2(offset, 0));
                    characterShape.Draw(shader, camera);

                    //Drop shadow
                    shader.SetVector3("letterColor", new Vector3(0, 0, 0));
                    shader.SetVector2("letterPosition", new Vector2(offset + 1, -1));
                    characterShape.Draw(shader, camera);

                    offset += LetterSize;
                }
            }
            else
            {
                SBConsole.WriteLine(shader.GetErrorLog());
            }


            GL.PopAttrib();
        }