public static NQuaternion GetDeltaQuaternionWithDirectionVectors(NVector3 a, NVector3 b) { var dot = NVector3.Dot(a, b); if (dot < -0.999999) { var cross = NVector3.Cross(a, b); if (cross.Length() < 0.000001) { cross = NVector3.Cross(NVector3.UnitY, a); } cross = NVector3.Normalize(cross); return(NQuaternion.CreateFromAxisAngle(cross, Pi)); } else if (dot > 0.999999) { return(new NQuaternion(0, 0, 0, 1)); } else { var xyz = NVector3.Cross(a, b); var w = (float)(Math.Sqrt(a.Length() * a.Length() + b.Length() * b.Length()) + dot); return(new NQuaternion(xyz.X, xyz.Y, xyz.Z, w)); } }
private void Update(EvaluationContext context) { var closeCircle = CloseCircle.GetValue(context); var circleOffset = closeCircle ? 1 : 0; var corners = Count.GetValue(context).Clamp(1, 10000); var pointCount = corners + circleOffset; var listCount = corners + 2 * circleOffset; // Separator if (_pointList.NumElements != listCount) { //_points = new T3.Core.DataTypes.Point[count]; _pointList.SetLength(listCount); } var axis = Axis.GetValue(context); var center = Center.GetValue(context); var offset = Offset.GetValue(context); var radius = Radius.GetValue(context); var radiusOffset = RadiusOffset.GetValue(context); var thickness = W.GetValue(context); var thicknessOffset = WOffset.GetValue(context); var angelInRads = StartAngel.GetValue(context) * MathUtils.ToRad + (float)Math.PI / 2; var deltaAngle = -Cycles.GetValue(context) * MathUtils.Pi2 / (pointCount - circleOffset); for (var index = 0; index < pointCount; index++) { var f = corners == 1 ? 1 : (float)index / pointCount; var length = MathUtils.Lerp(radius, radius + radiusOffset, f); var v = Vector3.UnitX * length; var rot = Quaternion.CreateFromAxisAngle(axis, angelInRads); var vInAxis = Vector3.Transform(v, rot) + Vector3.Lerp(center, center + offset, f); var p = new Point { Position = vInAxis, W = MathUtils.Lerp(thickness, thickness + thicknessOffset, f), Orientation = rot }; _pointList[index] = p; angelInRads += deltaAngle; } if (closeCircle) { _pointList[listCount - 1] = Point.Separator(); } ResultList.Value = _pointList; }
internal Content(ContentManager contentManager) { this.contentManager = contentManager; // Efects E_BasicShader = LoadEffect("BasicShader"); E_BlinnPhong = LoadEffect("BlinnPhong"); E_LaserShader = LoadEffect("LaserShader"); E_SkyBox = LoadEffect("SkyBox"); // Models M_SkyBox = LoadModel("SkyBox/Cube", E_SkyBox); M_XWing = LoadModel("XWing/XWing", E_BlinnPhong); M_TIE = LoadModel("TIE/TIE", E_BlinnPhong); M_Trench_Plain = LoadModel("DeathStar/Trench_Plain", E_BlinnPhong); M_Trench_Line = LoadModel("DeathStar/Trench_Line", E_BlinnPhong); M_Trench_Corner = LoadModel("DeathStar/Trench_Corner", E_BlinnPhong); M_Trench_T = LoadModel("DeathStar/Trench_T", E_BlinnPhong); M_Trench_Cross = LoadModel("DeathStar/Trench_Cross", E_BlinnPhong); M_Trench_End = LoadModel("DeathStar/Trench_End", E_BlinnPhong); M_Laser = LoadModel("Laser", E_LaserShader); M_Turret = LoadModel("DeathStar/Turret", E_BlinnPhong); M_SmallTurret = LoadModel("DeathStar/SmallTurret", E_BlinnPhong); // Convex Hulls // Shapes SH_XWing = LoadConvexHull("XWing/XWing", 1f); SH_TIE = LoadShape(new Sphere(8f)); SH_Laser = LoadShape(new Cylinder(Laser.Radius / 2f, Laser.Lenght / 10f)); SH_Turret = LoadShape(new Box(28f, 66f, 28f)); SH_SmallTurret = LoadShape(new Box(1f * 10f, 2.1f * 20f, 1f * 10f)); // DeathStar shapes TypedIndex trenchPlain = LoadShape(new Box(DeathStar.trenchSize, DeathStar.trenchHeight, DeathStar.trenchSize)); TypedIndex trenchLine = LoadShape(new Box(DeathStar.trenchSize, DeathStar.trenchHeight, DeathStar.trenchSize / 1.6f)); TypedIndex trenchQuarter = LoadShape(new Box(DeathStar.trenchSize / 1.6f, DeathStar.trenchHeight, DeathStar.trenchSize / 1.6f)); RigidPose plainPose = new RigidPose(new BEPUVector3(0f, -DeathStar.trenchHeight * 1.8f, 0f)); float colliderYPos = -DeathStar.trenchHeight / 2f; float sideOffset = DeathStar.trenchSize * 3.5f / 8f; BEPUQuaternion d90Rotation = BEPUQuaternion.CreateFromAxisAngle(BEPUVector3.UnitY, (float)Math.PI / 2f); Sh_Trench_Plain = LoadKinematicCompoundShape(new (TypedIndex, RigidPose)[] {
private void Update(EvaluationContext context) { var from = From.GetValue(context); var to = To.GetValue(context); var w = W.GetValue(context); var wOffset = WOffset.GetValue(context); var addSeparator = AddSeparator.GetValue(context); var rot = Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), (float)Math.Atan2(from.X - to.X, from.Y - to.Y)); var array = addSeparator ? _pointListWithSeparator : _pointList; array.TypedElements[0].Position = from; array.TypedElements[0].W = w; array.TypedElements[0].Orientation = rot; array.TypedElements[1].Position = to; array.TypedElements[1].W = w + wOffset; array.TypedElements[1].Orientation = rot; ResultList.Value = array; }
public static NQuaternion MirrorQuat(NQuaternion quatB) { var angle = 2 * Math.Acos(quatB.W); var s2 = Math.Sqrt(1.0 - quatB.W * quatB.W); NVector3 axis; if (s2 < 0.001) { axis.X = quatB.X; axis.Y = quatB.Y; axis.Z = quatB.Z; } else { axis.X = (float)(quatB.X / s2); axis.Y = (float)(quatB.Y / s2); axis.Z = (float)(quatB.Z / s2); } axis.X = -axis.X; return(NQuaternion.CreateFromAxisAngle(axis, (float)-angle)); }
public void AxisAngle_ToQuaternionConversion() { AxisAngle aa; Quaternion q; Vector v; SysVec normV; SysQuat sq; double x, y, z, angle; bool zero; // Test random quaternions for (var i = 0; i < 50; i++) { x = Random(-100, 100); y = Random(-100, 100); z = Random(-100, 100); angle = Random(-720, 720); Trace.WriteLine(""); Trace.WriteLine(x + " " + y + " " + z + " " + angle + " length: " + Geometry.Length(x, y, z)); aa = new AxisAngle(x, y, z, angle); q = aa.ToQuaternion(); // this method will normalize the Quaternion, as neccesary for spatial rotation representation Trace.WriteLine(aa); Trace.WriteLine(q); // TEST 1: compare to System.Numeric.Quaternion normV = new SysVec((float)x, (float)y, (float)z); normV = SysVec.Normalize(normV); sq = SysQuat.CreateFromAxisAngle(normV, (float)(angle * Math.PI / 180.0)); // now this Quaternion SHOULD be normalized... Trace.WriteLine(sq + " length: " + sq.Length()); Assert.AreEqual(q.W, sq.W, 0.000001, "Failed W"); // can't go very precise due to float imprecision in sys quat Assert.AreEqual(q.X, sq.X, 0.000001, "Failed X"); Assert.AreEqual(q.Y, sq.Y, 0.000001, "Failed Y"); Assert.AreEqual(q.Z, sq.Z, 0.000001, "Failed Z"); } // Test all permutations of unitary components quaternions (including zero) for (x = -1; x <= 1; x++) { for (y = -1; y <= 1; y++) { for (z = -1; z <= 1; z++) { for (angle = -720; angle <= 720; angle += 22.5) { Trace.WriteLine(""); Trace.WriteLine(x + " " + y + " " + z + " " + angle + " length: " + Geometry.Length(x, y, z)); // Normalize v = new Vector(x, y, z); v.Normalize(); aa = new AxisAngle(v, angle); q = aa.ToQuaternion(); Trace.WriteLine(aa); Trace.WriteLine(q); zero = aa.IsZero(); if (zero) { Assert.IsTrue(new Quaternion(1, 0, 0, 0).IsSimilar(q), "Failed zero quaternion"); } else { // TEST 1: compare to System.Numeric.Quaternion //sq = SysQuat.CreateFromAxisAngle(new Vector3((float)x, (float)y, (float)z), (float)(angle * Math.PI / 180.0)); // this Quaternion is not a versor (not unit) normV = new SysVec((float)x, (float)y, (float)z); normV = SysVec.Normalize(normV); sq = SysQuat.CreateFromAxisAngle(normV, (float)(angle * Math.PI / 180.0)); // now this Quaternion SHOULD be normalized... Trace.WriteLine(sq + " length: " + sq.Length()); Assert.AreEqual(q.W, sq.W, 0.000001, "Failed W"); // can't go very precise due to float imprecision in sys quat Assert.AreEqual(q.X, sq.X, 0.000001, "Failed X"); Assert.AreEqual(q.Y, sq.Y, 0.000001, "Failed Y"); Assert.AreEqual(q.Z, sq.Z, 0.000001, "Failed Z"); } } } } } }
//private float velocity; protected override void OnUpdateFrame(FrameEventArgs e) { Vector2 mousepos = Vector2.Zero; if (CursorVisible == false) { MouseState ms = OpenTK.Input.Mouse.GetState(); mousepos.X = ms.X - oldms.X; mousepos.Y = ms.Y - oldms.Y; mousepos /= 600; oldms = ms; } camera.Rotation *= Quaternion.CreateFromAxisAngle(new Vector3(0, 1, 0), mousepos.X); camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Right, mousepos.Y); if (Keyboard[Key.Left]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Up, -0.1f); } if (Keyboard[Key.Right]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Up, 0.1f); } if (Keyboard[Key.Up]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Left, 0.1f); } if (Keyboard[Key.Down]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Left, -0.1f); } if (Keyboard[Key.PageUp]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Forward, 0.1f); } if (Keyboard[Key.PageDown]) { camera.Rotation *= Quaternion.CreateFromAxisAngle(camera.Forward, -0.1f); } Vector3 movement = Vector3.Zero; if (Keyboard[Key.W]) { movement += camera.Forward; } if (Keyboard[Key.S]) { movement += camera.Back; } if (Keyboard[Key.A]) { movement += camera.Left; } if (Keyboard[Key.D]) { movement += camera.Right; } movement *= (Keyboard[Key.ShiftLeft] ? 60 : 10) * (float)e.Time; if (Settings.Instance.Physics) { camera.Position = ClampToWorld(camera.Position, movement); } else { camera.Position += movement; } slot = Math.Abs(Mouse.Wheel / 2 % inventory.Length); Title = "Block: " + inventory[slot].Name; base.OnUpdateFrame(e); }