private IEnumerator AnimateCamera(Vector3 position, Quaternion rotation, Vector3 pivot) { var angle = rotation.AngleTo(_rotation); var totalTimeAngle = (0.1f * angle) / 90; var totalTimeDistance = (pivot - _pivot).Length() * 0.003; var totalTime = (float)Math.Max(totalTimeAngle, totalTimeDistance); Debug.WriteLine($"time angle: {totalTimeAngle} time dist {totalTimeDistance}"); var time = 0.0f; var originalPivot = _pivot; var originalRotation = _rotation; var targetRotation = rotation; var distanceFromOrigin = (_position - _pivot).Length(); while (time < totalTime) { var lerpFactor = time / totalTime; var newPivot = Vector3.Lerp(originalPivot, pivot, lerpFactor); var newRotation = Quaternion.Slerp(originalRotation, targetRotation, lerpFactor); var newUnitPosition = Vector3.Transform(-Vector3.UnitZ, newRotation); var newPosition = newPivot + newUnitPosition * distanceFromOrigin; MoveCamera(newPosition, newRotation, newPivot); time += (float)_coroutines.DeltaTime; yield return(null); } MoveCamera(position, rotation, pivot); }
void SetOrientation(SN.Quaternion o, TimeSpan duration, Action completed = null) { o = Clamp(o); var targetOrientation = CameraLocal ? SN.Quaternion.Inverse(o) : o; if (duration.Ticks > 0) { Animate( rotation, QuaternionRotation3D.QuaternionProperty, new QuaternionAnimation { To = Convert(targetOrientation), Duration = duration, EasingFunction = new CubicEase(), }, completed ); base.SetOrientation(o); } else { base.SetOrientation(o); rotation.Quaternion = Convert(targetOrientation); completed?.Invoke(); } }
public void Render(Renderer renderer) { SFMLRenderer sfmlRenderer = renderer as SFMLRenderer; System.Numerics.Vector3 Location = GetLocation_WorldSpace(); System.Numerics.Quaternion Rotation = GetRotation_WorldSpace(); //TODO: Get the rotation out of this quat System.Numerics.Vector3 Scale = GetScale_WorldSpace(); Transform tf = Transform.Identity; tf.Translate(Location.X, Location.Y); tf.Scale(Scale.X, Scale.Y); RenderStates RS = RenderStates.Default; RS.Transform = tf; SFMLEngine engine = Engine.Instance as SFMLEngine; if (Texture.Loaded) { //Texture.Get<Sprite>().Position = new Vector2f(Location.X, Location.Y); engine?.Window.Draw(Texture.Get <Sprite>(), RS); } }
public void Draw(Vector3 Position, Vector3 Scale, Quaternion Rotation) { if (ColorBuffer == null) { VertexArray.VertexAttrib(COLOR_ATTRIB, Material.DiffuseColor); } Material.Bind(); Material.Shader.SetModelMatrix(Camera.CreateModel(Position, Scale, Rotation) * Matrix); if (Wireframe) { Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Line); } if (!VAO.HasElementBuffer) { VAO.Draw(0, VertBuffer.ElementCount); } else { VAO.DrawElements(ElementType: DrawElementsType.UnsignedInt); } if (Wireframe) { Gl.PolygonMode(MaterialFace.FrontAndBack, PolygonMode.Fill); } Material.Unbind(); }
/// <summary> /// Convert a system.numerics quaternion to waveengine quaternion /// </summary> /// <param name="numerics">Numeric quaternion</param> /// <param name="result">Wave quaternion</param> public static void ToWave(this System.Numerics.Quaternion numerics, out Common.Math.Quaternion result) { result.X = numerics.X; result.Y = numerics.Y; result.Z = numerics.Z; result.W = numerics.W; }
public static void Deconstruct(this System.Numerics.Quaternion Q, out float x, out float y, out float z, out float w) { x = Q.X; y = Q.Y; z = Q.Z; w = Q.W; }
public void Draw(RenderTarget target, RenderStates states) { if (VertexArray == null || VertexArray.Length == 0 || VertexArray.Length % 4 != 0) { return; } System.Numerics.Vector3 Location = GetLocation_WorldSpace(); System.Numerics.Quaternion Rotation = GetRotation_WorldSpace(); //TODO: Get the rotation out of this quat System.Numerics.Vector3 Scale = GetScale_WorldSpace(); Transform tf = Transform.Identity; tf.Translate(Location.X, Location.Y); //tf.Scale(Scale.X, Scale.Y); states.Transform *= tf; if (Texture.Loaded) { states.Texture = Texture.Get <Texture>(); } target.Draw(VertexArray, PrimitiveType, states); }
public static Quaternion ToLookRotation(this Vector3 forward, Vector3 up) { forward = Vector3.Normalize(forward); Vector3 vector = Vector3.Normalize(forward); Vector3 vector2 = Vector3.Normalize(Vector3.Cross(up, vector)); Vector3 vector3 = Vector3.Cross(vector, vector2); var m00 = vector2.X; var m01 = vector2.Y; var m02 = vector2.Z; var m10 = vector3.X; var m11 = vector3.Y; var m12 = vector3.Z; var m20 = vector.X; var m21 = vector.Y; var m22 = vector.Z; float num8 = (m00 + m11) + m22; var quaternion = new Quaternion(); if (num8 > 0f) { var num = (float)Math.Sqrt(num8 + 1f); quaternion.W = num * 0.5f; num = 0.5f / num; quaternion.X = (m12 - m21) * num; quaternion.Y = (m20 - m02) * num; quaternion.Z = (m01 - m10) * num; return(quaternion); } if ((m00 >= m11) && (m00 >= m22)) { var num7 = (float)Math.Sqrt(((1f + m00) - m11) - m22); var num4 = 0.5f / num7; quaternion.X = 0.5f * num7; quaternion.Y = (m01 + m10) * num4; quaternion.Z = (m02 + m20) * num4; quaternion.W = (m12 - m21) * num4; return(quaternion); } if (m11 > m22) { var num6 = (float)Math.Sqrt(((1f + m11) - m00) - m22); var num3 = 0.5f / num6; quaternion.X = (m10 + m01) * num3; quaternion.Y = 0.5f * num6; quaternion.Z = (m21 + m12) * num3; quaternion.W = (m20 - m02) * num3; return(quaternion); } var num5 = (float)Math.Sqrt(((1f + m22) - m00) - m11); var num2 = 0.5f / num5; quaternion.X = (m20 + m02) * num2; quaternion.Y = (m21 + m12) * num2; quaternion.Z = 0.5f * num5; quaternion.W = (m01 - m10) * num2; return(quaternion); }
private void InterpolateKeys(double animationTime, AnimationLayer layer, ref Quaternion rotation, ref Vector3 translation, ref Vector3 scale, PRSKey prsKey, PRSKey nextPrsKey) { var nextTime = (nextPrsKey.Time < prsKey.Time ? (nextPrsKey.Time + Animation.Duration) : nextPrsKey.Time); var blend = ( float )(animationTime / nextTime); if (prsKey.HasRotation) { rotation = Quaternion.Slerp(prsKey.Rotation, nextPrsKey.Rotation, blend); } if (prsKey.HasPosition) { translation = Vector3.Lerp(prsKey.Position * layer.PositionScale, nextPrsKey.Position * layer.PositionScale, blend); } if (prsKey.HasScale) { scale = Vector3.Lerp(prsKey.Scale * layer.ScaleScale, nextPrsKey.Scale * layer.ScaleScale, blend); } }
public Model() { MeshList = new List <Mesh>(); Position = Vector3.Zero; Scale = Vector3.One; Rotation = Quaternion.Identity; }
private int Instantiate(BodyDescription bodyReference, ref Vector3 position, ref Quaternion orientation) { bodyReference.Pose.Position = position; bodyReference.Pose.Orientation = orientation; var index = Simulation.Bodies.Add(bodyReference); _createdObjects.Add(index, BufferPool); return(index); }
void FixedUpdate() { var position = new System.Numerics.Vector3(_myTransform.position.x, _myTransform.position.y, _myTransform.position.z); var rotation = new System.Numerics.Quaternion(_myTransform.rotation.x, _myTransform.rotation.y, _myTransform.rotation.z, _myTransform.rotation.w); ConnectionInstance.Instance.Client.SendCoordinates(position, rotation); }
System.Numerics.Quaternion CalculateQuaternion(DataPoints datapoints, DataPoints targetpoints) { System.Numerics.Quaternion q = new System.Numerics.Quaternion(); System.Numerics.Vector3 cp = System.Numerics.Vector3.Cross(datapoints.points[0].point, targetpoints.points[0].point); q.X = cp.X; q.Y = cp.Y; q.Z = cp.Z; q.W = Mathf.Sqrt(Mathf.Pow(datapoints.points[0].point.Length(), 2) * Mathf.Pow(targetpoints.points[0].point.Length(), 2)) + System.Numerics.Vector3.Dot(datapoints.points[0].point, targetpoints.points[0].point); return(q); }
public static void DrawImGuiQuaternion(string name, object reference) { System.Numerics.Quaternion quatValue = (reference as ReflectionRef <System.Numerics.Quaternion>).Value; var value = new Vector4(quatValue.X, quatValue.Y, quatValue.Z, quatValue.W); ImGui.Text(name); ImGui.NextColumn(); ImGui.DragFloat4($"{name}##hidelabel", ref value, 0.1f); ImGui.NextColumn(); (reference as ReflectionRef <System.Numerics.Quaternion>).Value = new System.Numerics.Quaternion(value.X, value.Y, value.Z, value.W); }
/// <summary> /// Converts a <see cref="CoordinateSystem"/> in \psi basis to a <see cref="SpatialCoordinateSystem"/> in HoloLens basis. /// </summary> /// <param name="coordinateSystem">The <see cref="CoordinateSystem"/> in \psi basis.</param> /// <returns>The <see cref="SpatialCoordinateSystem"/>.</returns> public static SpatialCoordinateSystem TryConvertPsiCoordinateSystemToSpatialCoordinateSystem(this CoordinateSystem coordinateSystem) { var holoLensMatrix = coordinateSystem.RebaseToHoloLensSystemMatrix(); var translation = holoLensMatrix.Translation; holoLensMatrix.Translation = Vector3.Zero; var rotation = Quaternion.CreateFromRotationMatrix(holoLensMatrix); var spatialAnchor = SpatialAnchor.TryCreateRelativeTo(MixedReality.WorldSpatialCoordinateSystem, translation, rotation); return(spatialAnchor?.CoordinateSystem); }
public static float AngleTo(this Quaternion q1, Quaternion q2) { bool IsEqualish(float dot) { return((double)dot > 0.999998986721039); } var dot = Quaternion.Dot(q1, q2); return(IsEqualish(dot) ? 0.0f : (float)((double)Math.Acos(Math.Min(Math.Abs((float)dot), 1f)) * 2.0 * 57.2957801818848)); }
public Camera(IRendererCamera rendererCamera, Vector3 initialPivot, Coroutines coroutines, ILight?cameraLight = null) { _rendererCamera = rendererCamera; _cameraLight = cameraLight; _coroutines = coroutines; _originalPivot = _pivot = initialPivot; _position = _originalPosition = _rendererCamera.Position; _rotation = (_pivot - _position).ToLookRotation(Vector3.UnitY); MoveCamera(_position, _rotation, _pivot); _originalRotation = _rotation; }
public void GetQuaternionFromPose() { var w = Math.Sqrt(Math.Max(0, 1 + Pose.m0 + Pose.m5 + Pose.m10)) / 2; var x = Math.Sqrt(Math.Max(0, 1 + Pose.m0 - Pose.m5 - Pose.m10)) / 2; var y = Math.Sqrt(Math.Max(0, 1 - Pose.m0 + Pose.m5 - Pose.m10)) / 2; var z = Math.Sqrt(Math.Max(0, 1 - Pose.m0 - Pose.m5 + Pose.m10)) / 2; x = Math.Abs(x) * Math.Sign(Pose.m9 - Pose.m6); y = Math.Abs(y) * Math.Sign(Pose.m2 - Pose.m8); z = Math.Abs(z) * Math.Sign(Pose.m4 - Pose.m1); this.Quaternion = new Quaternion((float)x, (float)y, (float)z, (float)w); }
public static Quaternion LookIn(Vector3 dir, Vector3 up) { dir = Vector3.Normalize(dir); var right = Vector3.Normalize(Vector3.Cross(up, dir)); up = Vector3.Cross(dir, right); var matrix = new Matrix4x4( right.X, right.Y, right.Z, 0f, up.X, up.Y, up.Z, 0f, dir.X, dir.Y, dir.Z, 0f, 0f, 0f, 0f, 1f); return(Quaternion.CreateFromRotationMatrix(matrix)); }
private void InterpolationFunction(GameObject rotObj, System.Numerics.Quaternion[] rotations) { //turn the quaternion into a rotation matrix. System.Numerics.Matrix4x4 rotationMatrixFirstPose = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[0]); System.Numerics.Matrix4x4 rotationMatrixSecondPose = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[1]); //System.Numerics.Matrix4x4 rotationMatrixThirdPose = System.Numerics.Matrix4x4.CreateFromQuaternion(rotations[2]); //find the interpolated entry for each entry of the matrix. System.Numerics.Matrix4x4 interpolatedMat = new System.Numerics.Matrix4x4(); Vector3 position = gameObject.transform.position; interpolatedMat.M11 = interpolate(rotationMatrixFirstPose.M11, rotationMatrixSecondPose.M11, 0f, position); interpolatedMat.M12 = interpolate(rotationMatrixFirstPose.M12, rotationMatrixSecondPose.M12, 0f, position); interpolatedMat.M13 = interpolate(rotationMatrixFirstPose.M13, rotationMatrixSecondPose.M13, 0f, position); interpolatedMat.M21 = interpolate(rotationMatrixFirstPose.M21, rotationMatrixSecondPose.M21, 0f, position); interpolatedMat.M22 = interpolate(rotationMatrixFirstPose.M22, rotationMatrixSecondPose.M22, 0f, position); interpolatedMat.M23 = interpolate(rotationMatrixFirstPose.M23, rotationMatrixSecondPose.M23, 0f, position); interpolatedMat.M31 = interpolate(rotationMatrixFirstPose.M31, rotationMatrixSecondPose.M31, 0f, position); interpolatedMat.M32 = interpolate(rotationMatrixFirstPose.M32, rotationMatrixSecondPose.M32, 0f, position); interpolatedMat.M33 = interpolate(rotationMatrixFirstPose.M33, rotationMatrixSecondPose.M33, 0f, position); Debug.Log(interpolatedMat.ToString()); Debug.Log("Cursor" + " " + position); //orthonormalize the interpolated Matrix System.Numerics.Matrix4x4 orthogonalMatrix = matrixOrthogonal(interpolatedMat); //Convert the matrix to quaternion. System.Numerics.Quaternion newPose = System.Numerics.Quaternion.CreateFromRotationMatrix(orthogonalMatrix); //apply the transformation to the joints UnityEngine.Quaternion newPoseQuaternion = new UnityEngine.Quaternion(); newPoseQuaternion.x = newPose.X; newPoseQuaternion.y = newPose.Y; newPoseQuaternion.z = newPose.Z; newPoseQuaternion.w = newPose.W; rotObj.transform.rotation = Quaternion.Lerp(rotObj.transform.rotation, newPoseQuaternion, Time.deltaTime); }
public override void Initialize(ContentArchive content, Camera camera) { _orientations[0] = Quaternion.Identity; _orientations[1] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 0.5f, 0, 0); _orientations[2] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 1.0f, 0, 0); _orientations[3] = Quaternion.CreateFromYawPitchRoll(-(float)Math.PI * 1.5f, 0, 0); camera.Position = new Vector3(-30, 8, -60); camera.Yaw = MathHelper.Pi * 3f / 4; camera.Pitch = 0; Simulation = Simulation.Create(BufferPool, new DemoNarrowPhaseCallbacks(), new DemoPoseIntegratorCallbacks(new Vector3(0f, -9.81f, 0f)) , new CustomPositionLastTimestepper() ); _createdObjects = new QuickList <int>(_numberOfLevels * _numberOfLevels * 10, BufferPool); _movingObjects = new QuickList <Movable>(_numberOfLevels * _numberOfLevels, BufferPool); _boxDescription = CreateBoxDescription(1, 1, 1); _horizontalConveyorDescription = CreateConveyorDescription(_horizontalHalfLenght); _verticalConveyorDescription = CreateConveyorDescription(_verticalHalfLenght); _movingObject = CreateBoxDescription(4, 3, 2); _movingObject.LocalInertia = new BodyInertia(); var angle = _rampDegrees * (float)(Math.PI / 180f); var rampLenght = _floorHeight / (float)Math.Sin(angle); _rampConveyorDescription = CreateConveyorDescription(rampLenght); _rampConveyorDescription.Pose.Orientation = Quaternion.CreateFromYawPitchRoll((float)Math.PI * 0.5f, 0, angle); _rampConveyorDescription.ConveyorSettings.ConveyorVelocity *= 2f; for (int i = 0; i < _numberOfLevels; i++) { var position = new Vector3(0, _floorHeight * i, 0 /* _verticalHalfLenght * i*/); for (int j = 0; j < _numberOfLoops; j++) { CreateLoop(ref position); } // if (i < _numberOfLevels - 1) { CreateRamp(ref position); } } }
private void MoveCamera(Vector3 position, Quaternion rotation, Vector3 pivot, bool animate = false) { if (!animate) { _position = position; _rotation = rotation; _pivot = pivot; _rendererCamera.Move(position, _rotation.Forward(), _rotation.Up()); if (_cameraLight != null) { _cameraLight.Position = position; } } else { _coroutines.StartCoroutine(AnimateCamera(position, rotation, pivot)); } }
public override void Reset( SN.Quaternion orientation, SN.Vector3 position, SN.Vector3 scale, Action completed = null, double duration = 1.0) { if (duration <= 0) { base.Reset(orientation, position, scale, completed, duration); return; } var span = TimeSpan.FromSeconds(duration); SetOrientation(orientation, span, completed); SetPosition(position, span); SetScale(scale, span); }
public static void PlayerMovement(bool[] _inputs) { using (Packet _packet = new Packet((int)ClientPackets.playerMovement)) { _packet.Write(_inputs.Length); foreach (bool _input in _inputs) { _packet.Write(_input); } UnityEngine.Quaternion UEQuat = NGameManager.players[Client.Instance.myId].transform.rotation; System.Numerics.Quaternion NumQuat = new System.Numerics.Quaternion(UEQuat.x, UEQuat.y, UEQuat.z, UEQuat.w); _packet.Write(NumQuat); SendUDPData(_packet); } }
// from https://en.wikipedia.org/wiki/Conversion_between_quaternions_and_Euler_angles public static Vector3 ToEuler(this Quaternion q) { var euler = Vector3.Zero; double sinr_cosp = 2 * (q.W * q.X + q.Y * q.Z); double cosr_cosp = 1 - 2 * (q.X * q.X + q.Y * q.Y); euler.Z = (float)Math.Atan2(sinr_cosp, cosr_cosp); double sinp = 2 * (q.W * q.Y - q.Z * q.X); euler.X = Math.Abs(sinp) >= 1 ? (float)Math.CopySign(Math.PI / 2, sinp) // use 90 degrees if out of range : (float)Math.Asin(sinp); double siny_cosp = 2 * (q.W * q.Z + q.X * q.Y); double cosy_cosp = 1 - 2 * (q.Y * q.Y + q.Z * q.Z); euler.Y = (float)Math.Atan2(siny_cosp, cosy_cosp); return(euler); }
/// <summary>Adds a Quaternion 3B to the packet.</summary> /// <param name="value">The Quaternion to add.</param> /// /// Smallest 3, find the largest absolute of the floats, don't send it, send the smallest 3, /// and give the index for the largest using 2 bits [00, 01, 10, 11] 00 = x, 01 = y, 10 = z, 11 = w /// Use formula x^2 + y^2 + z^2 + w^2 = 1 /// /// Also can use less precise floating point value, instead of 4 bytes per component, use 1 byte /// /// This should decrease the packet size from 16 bytes = 128 bits /// To 2 bit (largest component index) + 3 * 7 bits (smallest 3 components) + 1 bit for negating all components = 24 bits - will send 3 bytes = 24 bits /// only 18.75% of the original packet public void Write(System.Numerics.Quaternion value) { float[] componentsAbs = new float[] { Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W) }; float[] components = new float[] { value.X, value.Y, value.Z, value.W }; int largestAbsIndex = GetLargestComponentIndex(componentsAbs); bool largestCompNegative = components[largestAbsIndex] < 0; bool[] largestAbsIndexBin = ConvertIntMax4ToBin2(largestAbsIndex); byte[] bytesToSend = new byte[3]; byte byteCounter = 0; for (int count = 0; count < 4; count++) { if (count == largestAbsIndex) { continue; } // Writes the 7 bit representation of the float instead of the 32 bit bytesToSend[byteCounter++] = Get7BitFractionalFrom32BitFloat(componentsAbs[count], components[count] < 0); } //Writes the bit indexes of which component not to read fragmented amongst the bits if (largestAbsIndexBin[0]) { bytesToSend[0] += 128; } if (largestAbsIndexBin[1]) { bytesToSend[1] += 128; } if (largestCompNegative) //Should negate the smallest 3 (*-1) components { bytesToSend[2] += 128; } Write(bytesToSend); }
private static bool _TryCastValue(JsonReader reader, Type vtype, out Object value) { value = null; if (reader.TokenType == JsonToken.EndArray) { return(false); } if (reader.TokenType == JsonToken.EndObject) { return(false); } if (reader.TokenType == JsonToken.EndConstructor) { return(false); } if (reader.TokenType == JsonToken.PropertyName) { reader.Read(); } // untangle nullable var ntype = Nullable.GetUnderlyingType(vtype); if (ntype != null) { vtype = ntype; } if (vtype == typeof(String) || vtype == typeof(Boolean) || vtype == typeof(Int16) || vtype == typeof(Int32) || vtype == typeof(Int64) || vtype == typeof(UInt16) || vtype == typeof(UInt32) || vtype == typeof(UInt64) || vtype == typeof(Single) || vtype == typeof(Double)) { value = Convert.ChangeType(reader.Value, vtype, System.Globalization.CultureInfo.InvariantCulture); return(true); } if (vtype.IsEnum) { if (reader.Value is String xstrVal) { value = Enum.Parse(vtype, xstrVal, true); return(true); } if (reader.Value is Int32 int32Val) { value = Enum.ToObject(vtype, int32Val); return(true); } if (reader.Value is Int64 int64Val) { value = Enum.ToObject(vtype, int64Val); return(true); } throw new NotImplementedException(); } if (vtype == typeof(Vector2)) { var l = new List <float>(); DeserializePropertyList <float>(reader, l); value = new Vector2(l[0], l[1]); return(true); } if (vtype == typeof(Vector3)) { var l = new List <float>(); DeserializePropertyList <float>(reader, l); value = new Vector3(l[0], l[1], l[2]); return(true); } if (vtype == typeof(Vector4)) { var l = new List <float>(); DeserializePropertyList <float>(reader, l); value = new Vector4(l[0], l[1], l[2], l[3]); return(true); } if (vtype == typeof(Quaternion)) { var l = new List <float>(); DeserializePropertyList <float>(reader, l); value = new System.Numerics.Quaternion(l[0], l[1], l[2], l[3]); return(true); } if (vtype == typeof(Matrix4x4)) { var l = new List <float>(); DeserializePropertyList <float>(reader, l); value = new Matrix4x4 ( l[0], l[1], l[2], l[3], l[4], l[5], l[6], l[7], l[8], l[9], l[10], l[11], l[12], l[13], l[14], l[15] ); return(true); } if (typeof(JsonSerializable).IsAssignableFrom(vtype)) { var item = Activator.CreateInstance(vtype, true) as JsonSerializable; System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.StartObject); item.Deserialize(reader); System.Diagnostics.Debug.Assert(reader.TokenType == JsonToken.EndObject); value = item; return(true); } if (vtype.IsGenericType) { if (vtype.GetGenericTypeDefinition() == typeof(Dictionary <,>)) { var valType = vtype.GetGenericArguments()[1]; if (valType == typeof(Int32)) { var dict = new Dictionary <string, Int32>(); DeserializePropertyDictionary(reader, dict); value = dict; return(true); } } throw new NotImplementedException($"Can't deserialize {vtype}"); } throw new NotImplementedException($"Can't deserialize {vtype}"); }
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 Vector3 Right(this Quaternion self) { return(Vector3.Transform(Vector3.UnitX, self)); }
public static Vector3 Up(this Quaternion self) { return(Vector3.Transform(Vector3.UnitY, self)); }