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; }
// 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); }
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); }
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 })); }
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); }
public static Matrix4x4 Inverted(this Matrix4x4 m) { Matrix4x4.Invert(m, out Matrix4x4 inv); return(inv); }
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 }