public override void UpdateDataFromPhysicsEngine() { if (MotionType.Value == MotionTypeEnum.Dynamic && rigidBody != null) { var position = Physics2DUtility.Convert(rigidBody.Position); var rotation = -rigidBody.Rotation; var oldT = Transform.Value; Matrix3F.FromRotateByZ(rotation, out var mat3); var rot2 = mat3.ToQuaternion(); //var rot2 = new Angles( 0, 0, MathEx.RadianToDegree( rot ) ); var newT = new Transform(new Vector3(position.X, position.Y, oldT.Position.Z), rot2, oldT.Scale); try { updatePropertiesWithoutUpdatingBody = true; Transform = newT; LinearVelocity = Physics2DUtility.Convert(rigidBody.LinearVelocity); AngularVelocity = MathEx.RadianToDegree(rigidBody.AngularVelocity); } finally { updatePropertiesWithoutUpdatingBody = false; } } }
public override void UpdateDataFromPhysicsEngine() { if (ConstraintRigid != null) { Transform rigidBodyTransform; { var rigidBody = ConstraintRigid.BodyA; var position = Physics2DUtility.Convert(rigidBody.Position); var rotation = -rigidBody.Rotation; var oldT = Transform.Value; Matrix3F.FromRotateByZ(rotation, out var mat3); var rot2 = mat3.ToQuaternion(); //var rot2 = new Angles( 0, 0, MathEx.RadianToDegree( rot ) ); rigidBodyTransform = new Transform(new Vector3(position.X, position.Y, oldT.Position.Z), rot2); } { var transformA = rigidBodyTransform.ToMatrix4() * ConstraintAFrame; transformA.Decompose(out Vector3 translation, out Matrix3 rotation, out Vector3 scale); var oldT = Transform.Value; var newT = new Transform(translation, rotation.ToQuaternion(), oldT.Scale); SetTransformWithoutUpdatingConstraint(newT); } } }
public void ToMatrix3(out Matrix3F result) { float x2 = X + X; float y2 = Y + Y; float z2 = Z + Z; float xx = X * x2; float xy = X * y2; float xz = X * z2; float yy = Y * y2; float yz = Y * z2; float zz = Z * z2; float wx = W * x2; float wy = W * y2; float wz = W * z2; result.Item0.X = 1.0f - (yy + zz); result.Item0.Y = xy + wz; result.Item0.Z = xz - wy; result.Item1.X = xy - wz; result.Item1.Y = 1.0f - (xx + zz); result.Item1.Z = yz + wx; result.Item2.X = xz + wy; result.Item2.Y = yz - wx; result.Item2.Z = 1.0f - (xx + yy); //return new Mat3( 1.0f - ( yy + zz ), xy + wz, xz - wy, // xy - wz, 1.0f - ( xx + zz ), yz + wx, // xz + wy, yz - wx, 1.0f - ( xx + yy ) ); }
private void _UpdateViewMatrix() { var zaxis = -_lookDirection; zaxis.Normalize(); var xaxis = Vector3F.CrossProduct(_upDirection, zaxis); xaxis.Normalize(); var yaxis = Vector3F.CrossProduct(zaxis, xaxis); var positionVec = (Vector3F)_position; var cx = -Vector3F.DotProduct(xaxis, positionVec); var cy = -Vector3F.DotProduct(yaxis, positionVec); var cz = -Vector3F.DotProduct(zaxis, positionVec); _viewMatrix = new Matrix3F( xaxis.X, yaxis.X, zaxis.X, 0, xaxis.Y, yaxis.Y, zaxis.Y, 0, xaxis.Z, yaxis.Z, zaxis.Z, 0, cx, cy, cz, 1); _OnTransformChanged(); }
static void Main(string[] args) { List <IJoint> joints = Robot6DOF.Get6DOFRobot(2, 2, 2, 2, 2, 2); Transform3D base_axis = new Transform3D(new Vector3F(0, 0, 0), new Vector3F(0, 0, 0)); Transform3D tf3d = base_axis; tf3d.RotationMat = Matrix3F.GetUnitMatrix(); joints[0].Transform = new Vector3F(0, 0, Math.PI * 4 / 6); joints[1].Transform = new Vector3F(0, Math.PI * 5 / 6, 0); joints[2].Transform = new Vector3F(0, Math.PI / 6, 0); joints[3].Transform = new Vector3F(0, 0, Math.PI / 6); joints[4].Transform = new Vector3F(0, Math.PI / 3, 0); joints[5].Transform = new Vector3F(0, 0, Math.PI / 4); foreach (IJoint jo in joints) { tf3d = jo.GetEndPointState(tf3d); } Console.WriteLine("6DOF"); Vector3F2 transform = Robot6DOF.Inverse6DOF(ref joints, tf3d); Console.WriteLine("The endpoint position is {0}, euler rotation is {1}", tf3d.Position - base_axis.Position, tf3d.Rotation); Console.WriteLine("Robot Joint Transform: {0}", transform.ToString()); Console.ReadLine(); }
private void TestToStringWithCulture(CultureInfo culture) { CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture; Thread.CurrentThread.CurrentCulture = culture; try { string listSeparator = culture.TextInfo.ListSeparator; string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator; var o = new Matrix3F( 1.1f, 2.2f, 3.3f, 4.4f, 5.5f, 6.6f, 7.7f, 8.8f, 9.9f); string s = o.ToString(null, null); TestToStringResults(o, s, listSeparator, decimalSeparator); string s2 = o.ToString(); Assert.AreEqual(s, s2); s = o.ToString("G", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); s = o.ToString("R", culture); TestToStringResults(o, s, listSeparator, decimalSeparator); } finally { Thread.CurrentThread.CurrentCulture = originalCulture; } }
public static void Convert(ref Matrix3F mat, out OgreMatrix3 result) { result.mat0 = mat.Item0; result.mat1 = mat.Item1; result.mat2 = mat.Item2; result.Transpose(); }
public void Matrix3() { string fs = @"#version 330 uniform mat3 exampleMat3; out vec3 FragColor; void main() { FragColor = vec3(exampleMat3[0].y, exampleMat3[2].x, 0.0); }"; using (GraphicsWindow window = Device.CreateWindow(1, 1)) using (Framebuffer framebuffer = TestUtility.CreateFramebuffer(window.Context)) using (ShaderProgram sp = Device.CreateShaderProgram(ShaderSources.PassThroughVertexShader(), fs)) using (VertexArray va = TestUtility.CreateVertexArray(window.Context, sp.VertexAttributes["position"].Location)) { Matrix3F m3 = new Matrix3F( 0.0f, 0.0f, 1.0f, 1.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); Uniform <Matrix3F> exampleMat3 = (Uniform <Matrix3F>)sp.Uniforms["exampleMat3"]; Assert.AreEqual("exampleMat3", exampleMat3.Name); Assert.AreEqual(UniformType.FloatMatrix33, exampleMat3.Datatype); Assert.AreEqual(new Matrix3F(), exampleMat3.Value); exampleMat3.Value = m3; Assert.AreEqual(m3, exampleMat3.Value); window.Context.Framebuffer = framebuffer; window.Context.Draw(PrimitiveType.Points, 0, 1, new DrawState(TestUtility.CreateRenderStateWithoutDepthTest(), sp, va), new SceneState()); TestUtility.ValidateColor(framebuffer.ColorAttachments[0], 255, 255, 0); } }
public bool Intersects(ref BoxF box) { Matrix3F transposedAxis; box.Axis.GetTranspose(out transposedAxis); //Vec3 diff = origin - box.center; Vector3F diff; Vector3F.Subtract(ref Origin, ref box.Center, out diff); //Vec3 localSpherePosition = inverseBoxAxis * diff; Vector3F localSpherePosition; Matrix3F.Multiply(ref transposedAxis, ref diff, out localSpherePosition); float distanceSquared = 0; for (int n = 0; n < 3; n++) { if (localSpherePosition[n] > box.Extents[n]) { float z = localSpherePosition[n] - box.Extents[n]; distanceSquared += z * z; } else if (localSpherePosition[n] < -box.Extents[n]) { float z = -box.Extents[n] - localSpherePosition[n]; distanceSquared += z * z; } } return(distanceSquared <= Radius * Radius); }
public override void OnHotSpotDragEnd(HotSpotBase hotSpot, VisionViewBase view) { base.OnHotSpotDragEnd(hotSpot, view); if (hotSpot == _hotSpotWindSpeed) { Vector3F vNewSpeed = _hotSpotWindSpeed.CurrentPosition; Vector3F vOldSpeed = _hotSpotWindSpeed.StartPosition; if (WindInLocalSpace) { Matrix3F rot = Matrix3F.Transpose(RotationMatrix); vNewSpeed = Matrix3F.Transform(rot, vNewSpeed); vOldSpeed = Matrix3F.Transform(rot, vOldSpeed); } WindSpeed = vOldSpeed; // set old value for the action EditorManager.Actions.Add(SetPropertyAction.CreateSetPropertyAction(this, "WindSpeed", vNewSpeed)); // send an action which sets the property from old value to new one } else if (hotSpot == _hotSpotLightSamplingOffset) { Vector3F vNewOffset = _hotSpotLightSamplingOffset.CurrentPosition; Vector3F vOldOffset = _hotSpotLightSamplingOffset.StartPosition; LightSamplingOffset = vOldOffset; // set old value for the action EditorManager.Actions.Add(SetPropertyAction.CreateSetPropertyAction(this, "LightSamplingOffset", vNewOffset)); // send an action which sets the property from old value to new one } }
private void TestToStringResults(Matrix3F o, string s, string listSeparator, string decimalSeparator) { string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries); Assert.AreEqual(results.Length, 9); for (int i = 0; i < 9; i++) { Assert.True(results[i].Contains(decimalSeparator)); float result = float.Parse(results[i]); Assert.AreEqual(result, o[i]); } }
/// <summary> /// Converts the current instance of <see cref="Matrix2F"/> into the equivalent <see cref="Matrix3F"/> structure. /// </summary> /// <param name="result">When the method completes, contains the equivalent <see cref="Matrix3F"/> structure.</param> public void ToMatrix3F(out Matrix3F result) { result.Item0.X = Item0.X; result.Item0.Y = Item0.Y; result.Item0.Z = 0; result.Item1.X = Item1.X; result.Item1.Y = Item1.Y; result.Item1.Z = 0; result.Item2.X = 0; result.Item2.Y = 0; result.Item2.Z = 1; }
private void _OnTransformChanged() { _totalTransform = _viewMatrix * _projectionMatrix; if (_totalTransform.HasInverse) { var totalTransformReverse = _totalTransform; totalTransformReverse.Invert(); _totalTransformReverse = totalTransformReverse; } if (!_isLocked) { PropertyChanged(this, EventArgs.Empty); } }
public void MeshInSpaceAnimationController_CalculateBoneTransforms(NeoAxis.Component_MeshInSpaceAnimationController sender, NeoAxis.Component_SkeletonAnimationTrack.CalculateBoneTransformsItem[] result) { //to enable this event handler in the editor change "When Enable" property to "Simulation | Instance | Editor". //component: Character/Mesh In Space/C# Script/Event Handler CalculateBoneTransforms. var boneIndex = sender.GetBoneIndex("chest"); if (boneIndex != -1) { ref var item = ref result[boneIndex]; //calculate bone offset var angle = new Degree(60) * Math.Sin(Time.Current); var offset = Matrix3F.FromRotateByY((float)angle.InRadians()).ToQuaternion(); //update the bone item.Rotation *= offset; }
private void _UpdateProjectionMatrix() { switch (_type) { case CameraType.Perspective: _projectionMatrix = _GeneratePerspectiveMatrix(); break; case CameraType.Orthographic: _projectionMatrix = _GenerateOrthographicMatrix(); break; } _OnTransformChanged(); }
private Matrix3F _GeneratePerspectiveMatrix() { var mat = new Matrix3F(); var tanHalfFovy = (float)Math.Tan(MathUtil.DegreesToRadians(_fieldOfView / 2)); var deep = _farPlaneDistance - _nearPlaneDistance; mat.M11 = 1 / (_aspect * tanHalfFovy); mat.M22 = 1 / tanHalfFovy; mat.M33 = float.IsInfinity(_farPlaneDistance) ? -1 : -(_farPlaneDistance + _nearPlaneDistance) / deep; mat.M44 = 0; mat.M34 = -1; mat.OffsetZ = float.IsInfinity(_farPlaneDistance) ? -2 * _nearPlaneDistance : -2 * _farPlaneDistance * _nearPlaneDistance / deep; return(mat); }
static bool HasTransformMatrixNegParity(Matrix3F m) { return(Vector3F.Dot(Vector3F.Cross(m.Item0, m.Item1), m.Item2) < 0.0f ? true : false); }
public void GetLightingCubemapRotationMatrix(out Matrix3F result) { Matrix3.FromRotateByZ(LightingCubemapRotation.Value.InRadians()).ToMatrix3F(out result); }
// static SimpleTypes() { //string RegisterType(typeof(string), delegate(string value) { if (value == null) { return(""); //throw new Exception( "GetSimpleTypeValue: string type, value = null" ); } return(value); }, ""); //bool RegisterType(typeof(bool), delegate(string value) { string lower = value.ToLower(); if (value == "1" || lower == "yes" || lower == "true") { return(true); } else if (value == "0" || lower == "no" || lower == "false") { return(false); } else { return(bool.Parse(value)); } }, false); //sbyte RegisterType(typeof(sbyte), delegate(string value) { return(sbyte.Parse(value)); }, 0); //byte RegisterType(typeof(byte), delegate(string value) { return(byte.Parse(value)); }, 0); //char RegisterType(typeof(char), delegate(string value) { return(char.Parse(value)); }, 0); //short RegisterType(typeof(short), delegate(string value) { return(short.Parse(value)); }, 0); //ushort RegisterType(typeof(ushort), delegate(string value) { return(ushort.Parse(value)); }, 0); //int RegisterType(typeof(int), delegate(string value) { return(int.Parse(value)); }, 0); //uint RegisterType(typeof(uint), delegate(string value) { return(uint.Parse(value)); }, (uint)0); //long RegisterType(typeof(long), delegate(string value) { return(long.Parse(value)); }, (long)0); //ulong RegisterType(typeof(ulong), delegate(string value) { return(ulong.Parse(value)); }, (ulong)0); //float RegisterType(typeof(float), delegate(string value) { return(float.Parse(value)); }, 0.0f); //double RegisterType(typeof(double), delegate(string value) { return(double.Parse(value)); }, 0.0); //decimal RegisterType(typeof(decimal), delegate(string value) { return(decimal.Parse(value)); }, (decimal)0.0); //Vec2 RegisterType(typeof(Vector2F), delegate(string value) { return(Vector2F.Parse(value)); }, Vector2F.Zero); //Range RegisterType(typeof(RangeF), delegate(string value) { return(RangeF.Parse(value)); }, RangeF.Zero); //Vec3 RegisterType(typeof(Vector3F), delegate(string value) { return(Vector3F.Parse(value)); }, Vector3F.Zero); //Vec4 RegisterType(typeof(Vector4F), delegate(string value) { return(Vector4F.Parse(value)); }, Vector4F.Zero); //Bounds RegisterType(typeof(BoundsF), delegate(string value) { return(BoundsF.Parse(value)); }, BoundsF.Zero); //Quat RegisterType(typeof(QuaternionF), delegate(string value) { return(QuaternionF.Parse(value)); }, QuaternionF.Identity); //ColorValue RegisterType(typeof(ColorValue), delegate(string value) { return(ColorValue.Parse(value)); }, ColorValue.Zero); //ColorValuePowered RegisterType(typeof(ColorValuePowered), delegate(string value) { return(ColorValuePowered.Parse(value)); }, ColorValuePowered.Zero); //ColorPacked RegisterType(typeof(ColorByte), delegate(string value) { return(ColorByte.Parse(value)); }, ColorByte.Zero); //SphereDir RegisterType(typeof(SphericalDirectionF), delegate(string value) { return(SphericalDirectionF.Parse(value)); }, SphericalDirectionF.Zero); //Vec2I RegisterType(typeof(Vector2I), delegate(string value) { return(Vector2I.Parse(value)); }, Vector2I.Zero); //Vec3I RegisterType(typeof(Vector3I), delegate(string value) { return(Vector3I.Parse(value)); }, Vector3I.Zero); //Vec4I RegisterType(typeof(Vector4I), delegate(string value) { return(Vector4I.Parse(value)); }, Vector4I.Zero); //Rect RegisterType(typeof(RectangleF), delegate(string value) { return(RectangleF.Parse(value)); }, RectangleF.Zero); //RectI RegisterType(typeof(RectangleI), delegate(string value) { return(RectangleI.Parse(value)); }, RectangleI.Zero); //Degree RegisterType(typeof(DegreeF), delegate(string value) { return(DegreeF.Parse(value)); }, DegreeF.Zero); //Radian RegisterType(typeof(RadianF), delegate(string value) { return(RadianF.Parse(value)); }, RadianF.Zero); //Vec2D RegisterType(typeof(Vector2), delegate(string value) { return(Vector2.Parse(value)); }, Vector2.Zero); //RangeD RegisterType(typeof(Range), delegate(string value) { return(Range.Parse(value)); }, Range.Zero); //RangeI RegisterType(typeof(RangeI), delegate(string value) { return(RangeI.Parse(value)); }, RangeI.Zero); //Vec3D RegisterType(typeof(Vector3), delegate(string value) { return(Vector3.Parse(value)); }, Vector3.Zero); //Vec4D RegisterType(typeof(Vector4), delegate(string value) { return(Vector4.Parse(value)); }, Vector4.Zero); //BoundsD RegisterType(typeof(Bounds), delegate(string value) { return(Bounds.Parse(value)); }, Bounds.Zero); //QuatD RegisterType(typeof(Quaternion), delegate(string value) { return(Quaternion.Parse(value)); }, Quaternion.Identity); //SphereDirD RegisterType(typeof(SphericalDirection), delegate(string value) { return(SphericalDirection.Parse(value)); }, SphericalDirection.Zero); //RectD RegisterType(typeof(Rectangle), delegate(string value) { return(Rectangle.Parse(value)); }, Rectangle.Zero); //DegreeD RegisterType(typeof(Degree), delegate(string value) { return(Degree.Parse(value)); }, Degree.Zero); //RadianD RegisterType(typeof(Radian), delegate(string value) { return(Radian.Parse(value)); }, Radian.Zero); //Angles RegisterType(typeof(AnglesF), delegate(string value) { return(AnglesF.Parse(value)); }, AnglesF.Zero); //AnglesD RegisterType(typeof(Angles), delegate(string value) { return(Angles.Parse(value)); }, Angles.Zero); //Mat2F RegisterType(typeof(Matrix2F), delegate(string value) { return(Matrix2F.Parse(value)); }, Matrix2F.Zero); //Mat2D RegisterType(typeof(Matrix2), delegate(string value) { return(Matrix2.Parse(value)); }, Matrix2.Zero); //Mat3F RegisterType(typeof(Matrix3F), delegate(string value) { return(Matrix3F.Parse(value)); }, Matrix3F.Zero); //Mat3D RegisterType(typeof(Matrix3), delegate(string value) { return(Matrix3.Parse(value)); }, Matrix3.Zero); //Mat4F RegisterType(typeof(Matrix4F), delegate(string value) { return(Matrix4F.Parse(value)); }, Matrix4F.Zero); //Mat4D RegisterType(typeof(Matrix4), delegate(string value) { return(Matrix4.Parse(value)); }, Matrix4.Zero); //PlaneF RegisterType(typeof(PlaneF), delegate(string value) { return(PlaneF.Parse(value)); }, PlaneF.Zero); //PlaneD RegisterType(typeof(Plane), delegate(string value) { return(Plane.Parse(value)); }, Plane.Zero); //Transform RegisterType(typeof(Transform), delegate(string value) { return(Transform.Parse(value)); }, Transform.Identity); //UIMeasureValueDouble RegisterType(typeof(UIMeasureValueDouble), delegate(string value) { return(UIMeasureValueDouble.Parse(value)); }, new UIMeasureValueDouble()); //UIMeasureValueVec2 RegisterType(typeof(UIMeasureValueVector2), delegate(string value) { return(UIMeasureValueVector2.Parse(value)); }, new UIMeasureValueVector2()); //UIMeasureValueRect RegisterType(typeof(UIMeasureValueRectangle), delegate(string value) { return(UIMeasureValueRectangle.Parse(value)); }, new UIMeasureValueRectangle()); RegisterType(typeof(RangeVector3F), delegate(string value) { return(RangeVector3F.Parse(value)); }, RangeVector3F.Zero); RegisterType(typeof(RangeColorValue), delegate(string value) { return(RangeColorValue.Parse(value)); }, RangeColorValue.Zero); //no Parse methods. This is complex structures. This is not simple types? or just can't parse? //Box //Capsule //Cone //Line3 //Line2 //Ray //Frustum? RegisterConvertDoubleToFloatTypes(); }
/// <summary> /// Overridden function to create the shape instance /// </summary> /// <returns></returns> public override ShapeBase CreateShapeInstance() { PathShape shape = new PathShape("Circle Path"); shape.Position = EditorManager.Scene.CurrentShapeSpawnPosition; shape.Closed = true; // Magic number: http://www.tinaja.com/glib/ellipse4.pdf float fMagic = 0.551784f; float fRadius = 200.0f * EditorManager.Settings.GlobalUnitScaling; Vector3F rotCenter = shape.Position; Vector3F rotAngle = new Vector3F(0.0f, 0.0f, 0.0f); Matrix3F rotMatrix = new Matrix3F(); rotMatrix.FromEuler(rotAngle.X, rotAngle.Y, rotAngle.Z); PathNodeShape node; for (int i = 0; i < 4; i++) { node = new PathNodeShape(); node.Position = shape.Position; node.y -= fRadius; node.TangentIn = new Vector3F(node.TangentIn.X - fRadius * fMagic, 0.0f, 0.0f); node.TangentOut = new Vector3F(node.TangentOut.X + fRadius * fMagic, 0.0f, 0.0f); node.Position = shape.Position + rotMatrix * (node.Position - rotCenter); node.TangentIn = rotMatrix * (node.TangentIn); node.TangentOut = rotMatrix * (node.TangentOut); node.InType = PathNodeShape.PathNodeInOutType.Custom; node.OutType = PathNodeShape.PathNodeInOutType.Custom; node.ShapeName = "node" + i; node.SetParent(shape); rotAngle.X += 90.0f; rotMatrix.FromEuler(rotAngle.X, rotAngle.Y, rotAngle.Z); } return shape; }
/// <summary> /// Calculates the rotation matrix representing the given Euler angles and in the correct order</summary> /// <returns>Rotation matrix</returns> public Matrix3F CalculateMatrix() { Matrix3F M = new Matrix3F(); Matrix3F temp = new Matrix3F(); switch (m_Order) { case EulerAngleOrder.XYZ: if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } break; case EulerAngleOrder.XZY: if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } break; case EulerAngleOrder.YXZ: if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } break; case EulerAngleOrder.YZX: if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } break; case EulerAngleOrder.ZXY: if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } break; case EulerAngleOrder.ZYX: if (m_Angles.Z != 0) { temp.RotZ(m_Angles.Z); M.Mul(M, temp); } if (m_Angles.Y != 0) { temp.RotY(m_Angles.Y); M.Mul(M, temp); } if (m_Angles.X != 0) { temp.RotX(m_Angles.X); M.Mul(M, temp); } break; default: throw new Exception("Illegal euler rotation order "); } return M; }
/// <summary> /// Given an object's current Euler angles and a surface normal, will calculate /// the Euler angles necessary to rotate the object so that it's up-vector is /// aligned with the surface normal. /// </summary> /// <param name="originalEulers">From an IRenderableNode.Rotation, for example.</param> /// <param name="surfaceNormal">a unit vector that the object should be rotate-snapped to</param> /// <param name="upAxis">y or z is up?</param> /// <returns>The resulting angles to be assigned to IRenderableNode.Rotation</returns> /// <remarks> /// Note that QuatF was attempted to be used, but I could not get it to work reliably /// with the Matrix3F.GetEulerAngles(). Numerical instability? The basis vector /// method below works well except for when the target surface is 90 degrees different /// than the starting up vector in which case the rotation around the up vector is lost /// (gimbal lock) but the results are always valid in the sense that the up vector /// is aligned with the surface normal. --Ron Little /// </remarks> public static Vec3F RotateToVector(Vec3F originalEulers, Vec3F surfaceNormal, AxisSystemType upAxis) { // get basis vectors for the current rotation Matrix3F rotMat = new Matrix3F(); rotMat.Rotation(originalEulers); Vec3F a1 = rotMat.XAxis; Vec3F a2 = rotMat.YAxis; Vec3F a3 = rotMat.ZAxis; // calculate destination basis vectors Vec3F b1, b2, b3; if (upAxis == AxisSystemType.YIsUp) { // a2 is the current up vector. b2 is the final up vector. // now, find either a1 or a3, whichever is most orthogonal to surface b2 = new Vec3F(surfaceNormal); float a1DotS = Vec3F.Dot(a1, surfaceNormal); float a3DotS = Vec3F.Dot(a3, surfaceNormal); if (Math.Abs(a1DotS) < Math.Abs(a3DotS)) { b1 = new Vec3F(a1); b3 = Vec3F.Cross(b1, b2); b1 = Vec3F.Cross(b2, b3); } else { b3 = new Vec3F(a3); b1 = Vec3F.Cross(b2, b3); b3 = Vec3F.Cross(b1, b2); } } else { // a3 is the current up vector. b3 is the final up vector. // now, find either a1 or a2, whichever is most orthogonal to surface b3 = new Vec3F(surfaceNormal); float a1DotS = Vec3F.Dot(a1, surfaceNormal); float a2DotS = Vec3F.Dot(a2, surfaceNormal); if (Math.Abs(a1DotS) < Math.Abs(a2DotS)) { b1 = new Vec3F(a1); b2 = Vec3F.Cross(b3, b1); b1 = Vec3F.Cross(b2, b3); } else { b2 = new Vec3F(a2); b1 = Vec3F.Cross(b2, b3); b2 = Vec3F.Cross(b3, b1); } } // in theory, this isn't necessary, but in practice... b1.Normalize(); b2.Normalize(); b3.Normalize(); // construct new rotation matrix and extract euler angles rotMat.XAxis = b1; rotMat.YAxis = b2; rotMat.ZAxis = b3; Vec3F newEulers = new Vec3F(); rotMat.GetEulerAngles(out newEulers.X, out newEulers.Y, out newEulers.Z); return newEulers; }
/// <summary> /// Given an object's current Euler angles and a surface normal, will calculate /// the Euler angles necessary to rotate the object so that it's up-vector is /// aligned with the surface normal. /// </summary> /// <param name="originalEulers">From an IRenderableNode.Rotation, for example.</param> /// <param name="surfaceNormal">a unit vector that the object should be rotate-snapped to</param> /// <param name="upAxis">y or z is up?</param> /// <returns>The resulting angles to be assigned to IRenderableNode.Rotation</returns> /// <remarks> /// Note that QuatF was attempted to be used, but I could not get it to work reliably /// with the Matrix3F.GetEulerAngles(). Numerical instability? The basis vector /// method below works well except for when the target surface is 90 degrees different /// than the starting up vector in which case the rotation around the up vector is lost /// (gimbal lock) but the results are always valid in the sense that the up vector /// is aligned with the surface normal. --Ron Little /// </remarks> public static Vec3F RotateToVector(Vec3F originalEulers, Vec3F surfaceNormal, AxisSystemType upAxis) { // get basis vectors for the current rotation Matrix3F rotMat = new Matrix3F(); rotMat.Rotation(originalEulers); Vec3F a1 = rotMat.XAxis; Vec3F a2 = rotMat.YAxis; Vec3F a3 = rotMat.ZAxis; // calculate destination basis vectors Vec3F b1, b2, b3; if (upAxis == AxisSystemType.YIsUp) { // a2 is the current up vector. b2 is the final up vector. // now, find either a1 or a3, whichever is most orthogonal to surface b2 = new Vec3F(surfaceNormal); float a1DotS = Vec3F.Dot(a1, surfaceNormal); float a3DotS = Vec3F.Dot(a3, surfaceNormal); if (Math.Abs(a1DotS) < Math.Abs(a3DotS)) { b1 = new Vec3F(a1); b3 = Vec3F.Cross(b1, b2); b1 = Vec3F.Cross(b2, b3); } else { b3 = new Vec3F(a3); b1 = Vec3F.Cross(b2, b3); b3 = Vec3F.Cross(b1, b2); } } else { // a3 is the current up vector. b3 is the final up vector. // now, find either a1 or a2, whichever is most orthogonal to surface b3 = new Vec3F(surfaceNormal); float a1DotS = Vec3F.Dot(a1, surfaceNormal); float a2DotS = Vec3F.Dot(a2, surfaceNormal); if (Math.Abs(a1DotS) < Math.Abs(a2DotS)) { b1 = new Vec3F(a1); b2 = Vec3F.Cross(b3, b1); b1 = Vec3F.Cross(b2, b3); } else { b2 = new Vec3F(a2); b1 = Vec3F.Cross(b2, b3); b2 = Vec3F.Cross(b3, b1); } } // in theory, this isn't necessary, but in practice... b1.Normalize(); b2.Normalize(); b3.Normalize(); // construct new rotation matrix and extract euler angles rotMat.XAxis = b1; rotMat.YAxis = b2; rotMat.ZAxis = b3; Vec3F newEulers = new Vec3F(); rotMat.GetEulerAngles(out newEulers.X, out newEulers.Y, out newEulers.Z); return(newEulers); }
public void GetRotationMatrix(out Matrix3F result) { Matrix3.FromRotateByZ(Rotation.Value.InRadians()).ToMatrix3F(out result); }
public static QuaternionF LookAt(Vector3F direction, Vector3F up) { return(Matrix3F.LookAt(direction, up).ToQuaternion()); }
public EnvironmentTextureData(Component_Image texture) { this.texture = texture; this.rotation = Matrix3F.Identity; this.multiplier = Vector3F.One; }
public EnvironmentTextureData(Component_Image texture, ref Matrix3F rotation, ref Vector3F multiplier) { this.texture = texture; this.rotation = rotation; this.multiplier = multiplier; }
public static QuaternionF FromRotateByZ(RadianF angle) { Matrix3F.FromRotateByZ(angle, out var mat); return(mat.ToQuaternion()); }
public static void FromRotateByZ(RadianF angle, out QuaternionF result) { Matrix3F.FromRotateByZ(angle, out var mat); mat.ToQuaternion(out result); }