Beispiel #1
0
        void Update()
        {
            var baseModel       = CreateMatrixFromTranslation(0.0f, 0.0f, 5.0f) * CreateMatrixFromRotation(rotation, 0.0f, 1.0f, 0.0f);
            var baseMv          = viewMatrix * baseModel;
            var modelViewMatrix = baseMv * CreateMatrixFromRotation(rotation, 1.0f, 1.0f, 1.0f);

#if NET
            Matrix4.Invert(Matrix4.Transpose(modelViewMatrix), out uniformBuffer.NormalMatrix);
#else
            uniformBuffer.NormalMatrix = Matrix4.Invert(Matrix4.Transpose(modelViewMatrix));
#endif
            uniformBuffer.ModelviewProjectionMatrix = Matrix4.Transpose(projectionMatrix * modelViewMatrix);

            // Copy uniformBuffer's content into dynamicConstantBuffer.Contents
            int    rawsize = Marshal.SizeOf(typeof(Uniforms));
            var    rawdata = new byte [rawsize];
            IntPtr ptr     = Marshal.AllocHGlobal(rawsize);
            Marshal.StructureToPtr(uniformBuffer, ptr, false);
            Marshal.Copy(ptr, rawdata, 0, rawsize);
            Marshal.FreeHGlobal(ptr);

            Marshal.Copy(rawdata, 0, dynamicConstantBuffer.Contents + rawsize * constantDataBufferIndex, rawsize);

            rotation += 0.01f;
        }
Beispiel #2
0
        // TODO: Tehdäänkö tällä enää mitään?
        /// <summary>
        /// Muuntaa matriisin Jypelin ruutukoordinaateista XNA:n ruutukoordinaatteihin.
        /// </summary>
        /// <param name="matrix"></param>
        /// <param name="screenSize"></param>
        /// <param name="scale"></param>
        /// <returns></returns>
        internal static Matrix ToXnaCoords(ref Matrix matrix, Vector screenSize, Vector scale)
        {
            // Keskitetään sprite ruudulla, mutta toteutetaan alkuperäinen muunnos Jypelin koordinaateissa.
            var centralize = Matrix.CreateTranslation((screenSize - scale) / 2);
            var toXna      = Matrix.CreateScale(1, -1, 1) * Matrix.CreateTranslation(screenSize / 2);

            Matrix.Invert(toXna, out Matrix toJypeli);

            return(centralize * toJypeli * matrix * toXna);
        }
Beispiel #3
0
        public static Plane Transform(Plane plane, Matrix4x4 matrix)
        {
            Matrix4x4 m;

            Matrix4x4.Invert(matrix, out m);

            Plane result;

            float x = plane.Normal.X, y = plane.Normal.Y, z = plane.Normal.Z, w = plane.D;

            result.Normal.X = x * m.M11 + y * m.M12 + z * m.M13 + w * m.M14;
            result.Normal.Y = x * m.M21 + y * m.M22 + z * m.M23 + w * m.M24;
            result.Normal.Z = x * m.M31 + y * m.M32 + z * m.M33 + w * m.M34;

            result.D = x * m.M41 + y * m.M42 + z * m.M43 + w * m.M44;

            return(result);
        }
Beispiel #4
0
        private static Matrix4x4 ComputeInverse_Numerics_Matrix4x4(Matrix4x4 matrix)
        {
            Mat4x4 m = new Mat4x4(
                matrix.MatrixBuffer[0x0], matrix.MatrixBuffer[0x1], matrix.MatrixBuffer[0x2], matrix.MatrixBuffer[0x3],
                matrix.MatrixBuffer[0x4], matrix.MatrixBuffer[0x5], matrix.MatrixBuffer[0x6], matrix.MatrixBuffer[0x7],
                matrix.MatrixBuffer[0x8], matrix.MatrixBuffer[0x9], matrix.MatrixBuffer[0xA], matrix.MatrixBuffer[0xB],
                matrix.MatrixBuffer[0xC], matrix.MatrixBuffer[0xD], matrix.MatrixBuffer[0xE], matrix.MatrixBuffer[0xF]
                );
            Mat4x4 inv;

            Mat4x4.Invert(m, out inv);

            return(new Matrix4x4(new float[] {
                inv.M11, inv.M12, inv.M13, inv.M14,
                inv.M21, inv.M22, inv.M23, inv.M24,
                inv.M31, inv.M32, inv.M33, inv.M34,
                inv.M41, inv.M42, inv.M43, inv.M44
            }));
        }
Beispiel #5
0
        private static Matrix4x4 ComputeInverse_Numerics_Matrix4x4_2(Matrix4x4 matrix)
        {
            Matrix4x4 invMatrix4x4 = (Matrix4x4)matrix.Clone();

            unsafe
            {
                fixed(float *invVecPtr = invMatrix4x4.MatrixBuffer)
                fixed(float *mVecPtr = matrix.MatrixBuffer)
                {
                    Mat4x4 mVec = Unsafe.Read <Mat4x4>(mVecPtr), invVec;

                    if (Mat4x4.Invert(mVec, out invVec) == false)
                    {
                        throw new InvalidOperationException("not invertible");
                    }

                    Unsafe.Write(invVecPtr, invVec);
                }
            }

            return(invMatrix4x4);
        }
        protected override void Initialize()
        {
            AddExportHandler <ObjectSet>(filePath =>
            {
                if (filePath.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase))
                {
                    Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                    FbxExporter.ExportToFile(Data, filePath);
                }

                else
                {
                    var configuration = ConfigurationList.Instance.CurrentConfiguration;

                    var objectDatabase  = configuration?.ObjectDatabase;
                    var textureDatabase = configuration?.TextureDatabase;
                    var boneDatabase    = configuration?.BoneDatabase;

                    Data.Save(filePath, objectDatabase, textureDatabase, boneDatabase);
                }
            });
            AddExportHandler <Scene>(filePath =>
            {
                Data.TryFixParentBoneInfos(SourceConfiguration?.BoneDatabase);
                AssimpExporter.ExportToFile(Data, filePath);
            });
            AddReplaceHandler <ObjectSet>(filePath =>
            {
                var configuration = ConfigurationList.Instance.CurrentConfiguration;

                var objectDatabase  = configuration?.ObjectDatabase;
                var textureDatabase = configuration?.TextureDatabase;

                var objectSet = new ObjectSet();
                objectSet.Load(filePath, objectDatabase, textureDatabase);
                return(objectSet);
            });
            AddReplaceHandler <Scene>(filePath =>
            {
                if (Data.Objects.Count > 1)
                {
                    return(AssimpImporter.ImportFromFile(filePath));
                }

                return(AssimpImporter.ImportFromFileWithSingleObject(filePath));
            });

            AddCustomHandler("Copy object set info to clipboard", () =>
            {
                uint objectSetId = 39;
                uint objectId    = 0xFFFFFFFF;

                var objectDatabase = ConfigurationList.Instance.CurrentConfiguration?.ObjectDatabase;

                if (objectDatabase != null && objectDatabase.ObjectSets.Count > 0)
                {
                    objectSetId = objectDatabase.ObjectSets.Max(x => x.Id) + 1;
                    objectId    = objectDatabase.ObjectSets.SelectMany(x => x.Objects).Max(x => x.Id) + 1;
                }

                else
                {
                    using (var inputDialog = new InputDialog
                    {
                        WindowTitle = "Enter base id for objects",
                        Input = Math.Max(0, Data.Objects.Max(x => x.Id) + 1).ToString()
                    })
                    {
                        while (inputDialog.ShowDialog() == DialogResult.OK)
                        {
                            bool result = uint.TryParse(inputDialog.Input, out objectId);

                            if (!result || objectId == 0xFFFFFFFF)
                            {
                                MessageBox.Show("Please enter a correct id number.", Program.Name, MessageBoxButtons.OK, MessageBoxIcon.Error);
                            }

                            else
                            {
                                break;
                            }
                        }
                    }
                }

                if (objectId == 0xFFFFFFFF)
                {
                    return;
                }

                string baseName = Path.ChangeExtension(Name, null);
                if (Data.Format.IsClassic() && baseName.EndsWith("_obj", StringComparison.OrdinalIgnoreCase))
                {
                    baseName = baseName.Substring(0, baseName.Length - 4);
                }

                var objectSetInfo = new ObjectSetInfo
                {
                    Name            = baseName.ToUpperInvariant(),
                    Id              = objectSetId,
                    FileName        = Name,
                    TextureFileName = baseName + (Data.Format.IsClassic() ? "_tex.bin" : ".txd"),
                    ArchiveFileName = Parent is FarcArchiveNode ? Parent.Name : baseName + ".farc"
                };

                foreach (var obj in Data.Objects)
                {
                    objectSetInfo.Objects.Add(new ObjectInfo
                    {
                        Id   = objectId++,
                        Name = obj.Name.ToUpperInvariant()
                    });
                }

                using (var stringWriter = new StringWriter())
                    using (var xmlWriter = XmlWriter.Create(stringWriter,
                                                            new XmlWriterSettings {
                        Indent = true, OmitXmlDeclaration = true
                    }))
                    {
                        sObjectSetInfoSerializer.Serialize(xmlWriter, objectSetInfo,
                                                           new XmlSerializerNamespaces(new[] { XmlQualifiedName.Empty }));

                        Clipboard.SetText(stringWriter.ToString());
                    }
            });

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Combine all objects into one", () =>
            {
                if (Data.Objects.Count <= 1)
                {
                    return(false);
                }

                var combinedObject = new Object {
                    Name = "Combined object"
                };
                var indexMap = new Dictionary <int, int>();

                foreach (var obj in Data.Objects)
                {
                    if (obj.Skin != null)
                    {
                        if (combinedObject.Skin == null)
                        {
                            combinedObject.Skin = new Skin();
                            combinedObject.Skin.Bones.AddRange(obj.Skin.Bones);
                        }

                        else
                        {
                            for (int i = 0; i < obj.Skin.Bones.Count; i++)
                            {
                                var bone      = obj.Skin.Bones[i];
                                int boneIndex = combinedObject.Skin.Bones.FindIndex(
                                    x => x.Name.Equals(bone.Name, StringComparison.OrdinalIgnoreCase));

                                if (boneIndex == -1)
                                {
                                    indexMap[i] = combinedObject.Skin.Bones.Count;
                                    combinedObject.Skin.Bones.Add(bone);
                                }

                                else
                                {
                                    indexMap[i] = boneIndex;
                                }
                            }

                            foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                            {
                                if (subMesh.BoneIndices?.Length >= 1)
                                {
                                    for (int i = 0; i < subMesh.BoneIndices.Length; i++)
                                    {
                                        subMesh.BoneIndices[i] = ( ushort )indexMap[subMesh.BoneIndices[i]];
                                    }
                                }
                            }
                        }

                        combinedObject.Skin.Blocks.AddRange(obj.Skin.Blocks);
                    }

                    foreach (var subMesh in obj.Meshes.SelectMany(x => x.SubMeshes))
                    {
                        subMesh.MaterialIndex += ( uint )combinedObject.Materials.Count;
                    }

                    combinedObject.Meshes.AddRange(obj.Meshes);
                    combinedObject.Materials.AddRange(obj.Materials);
                }

                Data.Objects.Clear();
                Data.Objects.Add(combinedObject);

                return(true);
            }, Keys.None, CustomHandlerFlags.Repopulate | CustomHandlerFlags.ClearMementos);

            AddCustomHandlerSeparator();

            AddDirtyCustomHandler("Convert all bones to osage", () =>
            {
                foreach (var obj in Data.Objects)
                {
                    var movingBone = obj.Skin?.Bones.FirstOrDefault(x => x.Name == "kl_mune_b_wj");
                    if (movingBone == null)
                    {
                        continue;
                    }

                    var nameMap       = new Dictionary <string, string>();
                    var stringBuilder = new StringBuilder();

                    foreach (var bone in obj.Skin.Bones)
                    {
                        // Ignore bones if they are already OSG or EXP.
                        // Also ignore the moving bone and its parents.

                        // Ignore j_kao_wj for now because it f***s miku's headphones up
                        if (bone.Name == "j_kao_wj")
                        {
                            continue;
                        }

                        var boneToCompare = movingBone;

                        do
                        {
                            if (boneToCompare == bone)
                            {
                                break;
                            }

                            boneToCompare = boneToCompare.Parent;
                        } while (boneToCompare != null);

                        if (boneToCompare == bone)
                        {
                            continue;
                        }

                        if (obj.Skin.Blocks.Any(x =>
                        {
                            switch (x)
                            {
                            case OsageBlock osgBlock:
                                return(osgBlock.Nodes.Any(y => y.Name == bone.Name));

                            case ExpressionBlock expBlock:
                                return(expBlock.Name == bone.Name);

                            default:
                                return(false);
                            }
                        }))
                        {
                            continue;
                        }

                        if (bone.Parent == null)
                        {
                            bone.Parent = movingBone;
                        }

                        Matrix4x4.Invert(bone.InverseBindPoseMatrix, out var bindPoseMatrix);
                        var matrix = Matrix4x4.Multiply(bindPoseMatrix, bone.Parent.InverseBindPoseMatrix);

                        Matrix4x4.Decompose(matrix, out var scale, out var rotation, out var translation);

                        rotation = Quaternion.Normalize(rotation);

                        string newName = bone.Name;

                        if (newName.EndsWith("_wj", StringComparison.OrdinalIgnoreCase))
                        {
                            newName = newName.Remove(newName.Length - 3);
                        }

                        newName += "_ragdoll";

                        nameMap.Add(bone.Name, newName);

                        bone.Name = newName;

                        string baseName = newName;

                        var osageBlock = new OsageBlock
                        {
                            ExternalName = $"c_{baseName}_osg",
                            Name         = $"e_{baseName}",
                            ParentName   = bone.Parent.Name,
                            Position     = translation,
                            Rotation     = rotation.ToEulerAngles(),
                            Scale        = scale
                        };

                        osageBlock.Nodes.Add(new OsageNode {
                            Name = bone.Name, Length = 0.08f
                        });
                        obj.Skin.Blocks.Add(osageBlock);

                        stringBuilder.AppendFormat(
                            "{0}.node.0.coli_r=0.030000\r\n" +
                            "{0}.node.0.hinge_ymax=179.000000\r\n" +
                            "{0}.node.0.hinge_ymin=-179.000000\r\n" +
                            "{0}.node.0.hinge_zmax=179.000000\r\n" +
                            "{0}.node.0.hinge_zmin=-179.000000\r\n" +
                            "{0}.node.0.inertial_cancel=1.000000\r\n" +
                            "{0}.node.0.weight=3.000000\r\n" +
                            "{0}.node.length=1\r\n" +
                            "{0}.root.force=0.010000\r\n" +
                            "{0}.root.force_gain=0.300000\r\n" +
                            "{0}.root.friction=1.000000\r\n" +
                            "{0}.root.init_rot_y=0.000000\r\n" +
                            "{0}.root.init_rot_z=0.000000\r\n" +
                            "{0}.root.rot_y=0.000000\r\n" +
                            "{0}.root.rot_z=0.000000\r\n" +
                            "{0}.root.stiffness=0.100000\r\n" +
                            "{0}.root.wind_afc=0.500000\r\n",
                            osageBlock.ExternalName);
                    }
Beispiel #7
0
 public static Matrix4x4 Inverted(this Matrix4x4 m)
 {
     Matrix4x4.Invert(m, out Matrix4x4 inv);
     return(inv);
 }
Beispiel #8
0
        public new Matrix4x4 GetInverseMatrix()
        {
#if HAVE_NUMERICS
            if (Vector.IsHardwareAccelerated)
            {
                Matrix4x4 invMatrix4x4 = (Matrix4x4)Clone();

                unsafe
                {
                    fixed(float *invVecPtr = invMatrix4x4.MatrixBuffer)
                    fixed(float *mVecPtr = MatrixBuffer)
                    {
                        Mat4x4 mVec = Unsafe.Read <Mat4x4>(mVecPtr), invVec;

                        if (Mat4x4.Invert(mVec, out invVec) == false)
                        {
                            throw new InvalidOperationException("not invertible");
                        }

                        Unsafe.Write(invVecPtr, invVec);
                    }
                }

                return(invMatrix4x4);
            }
#endif

#if ENABLE_GLU_INVERSE
            float[] m   = MatrixBuffer;
            float[] inv = new float[16];

            inv[0x0] = m[0x5] * m[0xA] * m[0xF] - m[0x5] * m[0xB] * m[0xE] - m[0x9] * m[0x6] * m[0xF] + m[0x9] * m[0x7] * m[0xE] + m[0xD] * m[0x6] * m[0xB] - m[0xD] * m[0x7] * m[0xA];
            inv[0x4] = -m[0x4] * m[0xA] * m[0xF] + m[0x4] * m[0xB] * m[0xE] + m[0x8] * m[0x6] * m[0xF] - m[0x8] * m[0x7] * m[0xE] - m[0xC] * m[0x6] * m[0xB] + m[0xC] * m[0x7] * m[0xA];
            inv[0x8] = m[0x4] * m[0x9] * m[0xF] - m[0x4] * m[0xB] * m[0xD] - m[0x8] * m[0x5] * m[0xF] + m[0x8] * m[0x7] * m[0xD] + m[0xC] * m[0x5] * m[0xB] - m[0xC] * m[0x7] * m[0x9];
            inv[0xC] = -m[0x4] * m[0x9] * m[0xE] + m[0x4] * m[0xA] * m[0xD] + m[0x8] * m[0x5] * m[0xE] - m[0x8] * m[0x6] * m[0xD] - m[0xC] * m[0x5] * m[0xA] + m[0xC] * m[0x6] * m[0x9];
            inv[0x1] = -m[0x1] * m[0xA] * m[0xF] + m[0x1] * m[0xB] * m[0xE] + m[0x9] * m[0x2] * m[0xF] - m[0x9] * m[0x3] * m[0xE] - m[0xD] * m[0x2] * m[0xB] + m[0xD] * m[0x3] * m[0xA];
            inv[0x5] = m[0x0] * m[0xA] * m[0xF] - m[0x0] * m[0xB] * m[0xE] - m[0x8] * m[0x2] * m[0xF] + m[0x8] * m[0x3] * m[0xE] + m[0xC] * m[0x2] * m[0xB] - m[0xC] * m[0x3] * m[0xA];
            inv[0x9] = -m[0x0] * m[0x9] * m[0xF] + m[0x0] * m[0xB] * m[0xD] + m[0x8] * m[0x1] * m[0xF] - m[0x8] * m[0x3] * m[0xD] - m[0xC] * m[0x1] * m[0xB] + m[0xC] * m[0x3] * m[0x9];
            inv[0xD] = m[0x0] * m[0x9] * m[0xE] - m[0x0] * m[0xA] * m[0xD] - m[0x8] * m[0x1] * m[0xE] + m[0x8] * m[0x2] * m[0xD] + m[0xC] * m[0x1] * m[0xA] - m[0xC] * m[0x2] * m[0x9];
            inv[0x2] = m[0x1] * m[0x6] * m[0xF] - m[0x1] * m[0x7] * m[0xE] - m[0x5] * m[0x2] * m[0xF] + m[0x5] * m[0x3] * m[0xE] + m[0xD] * m[0x2] * m[0x7] - m[0xD] * m[0x3] * m[0x6];
            inv[0x6] = -m[0x0] * m[0x6] * m[0xF] + m[0x0] * m[0x7] * m[0xE] + m[0x4] * m[0x2] * m[0xF] - m[0x4] * m[0x3] * m[0xE] - m[0xC] * m[0x2] * m[0x7] + m[0xC] * m[0x3] * m[0x6];
            inv[0xA] = m[0x0] * m[0x5] * m[0xF] - m[0x0] * m[0x7] * m[0xD] - m[0x4] * m[0x1] * m[0xF] + m[0x4] * m[0x3] * m[0xD] + m[0xC] * m[0x1] * m[0x7] - m[0xC] * m[0x3] * m[0x5];
            inv[0xE] = -m[0x0] * m[0x5] * m[0xE] + m[0x0] * m[0x6] * m[0xD] + m[0x4] * m[0x1] * m[0xE] - m[0x4] * m[0x2] * m[0xD] - m[0xC] * m[0x1] * m[0x6] + m[0xC] * m[0x2] * m[0x5];
            inv[0x3] = -m[0x1] * m[0x6] * m[0xB] + m[0x1] * m[0x7] * m[0xA] + m[0x5] * m[0x2] * m[0xB] - m[0x5] * m[0x3] * m[0xA] - m[0x9] * m[0x2] * m[0x7] + m[0x9] * m[0x3] * m[0x6];
            inv[0x7] = m[0x0] * m[0x6] * m[0xB] - m[0x0] * m[0x7] * m[0xA] - m[0x4] * m[0x2] * m[0xB] + m[0x4] * m[0x3] * m[0xA] + m[0x8] * m[0x2] * m[0x7] - m[0x8] * m[0x3] * m[0x6];
            inv[0xB] = -m[0x0] * m[0x5] * m[0xB] + m[0x0] * m[0x7] * m[0x9] + m[0x4] * m[0x1] * m[0xB] - m[0x4] * m[0x3] * m[0x9] - m[0x8] * m[0x1] * m[0x7] + m[0x8] * m[0x3] * m[0x5];
            inv[0xF] = m[0x0] * m[0x5] * m[0xA] - m[0x0] * m[0x6] * m[0x9] - m[0x4] * m[0x1] * m[0xA] + m[0x4] * m[0x2] * m[0x9] + m[0x8] * m[0x1] * m[0x6] - m[0x8] * m[0x2] * m[0x5];

            float det = m[0x0] * inv[0x0] + m[0x1] * inv[0x4] + m[0x2] * inv[0x8] + m[0x3] * inv[0xC];

            if (Math.Abs(det) < 1e-6f)
            {
                throw new InvalidOperationException("not invertible");
            }

            det = 1.0f / det;

            Matrix4x4 inverseMatrix = (Matrix4x4)Clone();
            for (int i = 0; i < 16; i++)
            {
                inverseMatrix.MatrixBuffer[i] = inv[i] * det;
            }

            return(inverseMatrix);
#else
            return((Matrix4x4)base.GetInverseMatrix());
#endif
        }