// Transform by quaternion public void PlaneTransformTest2() { Plane <float> target = new Plane <float>(1, 2, 3, 4); target = Plane.Normalize(target); Matrix4X4 <float> m = Matrix4X4.CreateRotationX(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationY(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationZ(MathHelper.ToRadians(30.0f)); Quaternion <float> q = Quaternion <float> .CreateFromRotationMatrix(m); Plane <float> expected = new Plane <float>(); float x = target.Normal.X, y = target.Normal.Y, z = target.Normal.Z, w = target.Distance; expected.Normal = new Vector3D <float>( x * m.M11 + y * m.M21 + z * m.M31 + w * m.M41, x * m.M12 + y * m.M22 + z * m.M32 + w * m.M42, x * m.M13 + y * m.M23 + z * m.M33 + w * m.M43); expected.Distance = x * m.M14 + y * m.M24 + z * m.M34 + w * m.M44; Plane <float> actual; actual = Plane.Transform(target, q); Assert.True(MathHelper.Equal(expected, actual), "Plane<float>.Transform did not return the expected value."); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); this.Children.Modify(list => { IObject3D lastChild = list.First(); list.Clear(); list.Add(lastChild); var offset = Offset; for (int i = 1; i < Count; i++) { var rotateRadians = MathHelper.DegreesToRadians(Rotate); if (ScaleOffset) { offset *= Scale; } var next = lastChild.Clone(); offset = Vector3.Transform(offset, Matrix4X4.CreateRotationZ(rotateRadians)); next.Matrix *= Matrix4X4.CreateTranslation(offset); if (RotatePart) { next.Matrix = next.ApplyAtBoundsCenter(Matrix4X4.CreateRotationZ(rotateRadians)); } next.Matrix = next.ApplyAtBoundsCenter(Matrix4X4.CreateScale(Scale)); list.Add(next); lastChild = next; } }); }
public void RotateAbsolute(double x, double y, double z) { Matrix4X4 M1 = Matrix4X4.Identity; Matrix4X4 M2 = Matrix4X4.Identity; Matrix4X4 M3 = Matrix4X4.Identity; Matrix4X4 M4 = Matrix4X4.Identity; Vector3 save1; // save the old position save1.x = AxisToWorld[3, 0]; save1.y = AxisToWorld[3, 1]; save1.z = AxisToWorld[3, 2]; M1 = Matrix4X4.CreateRotationX(x); M2 = Matrix4X4.CreateRotationY(y); M3 = Matrix4X4.CreateRotationZ(z); // 1 * 2 * 3 M4 = M2 * M1; AxisToWorld = M3 * M4; // stuff the old position back in AxisToWorld[3, 0] = save1.x; AxisToWorld[3, 1] = save1.y; AxisToWorld[3, 2] = save1.z; AxisToWorld = Matrix4X4.Invert(WorldToAxis); }
static void AddRevolveStrip(IVertexSource vertexSource, Mesh mesh, double startAngle, double endAngle) { Vector3 lastPosition = Vector3.Zero; foreach (var vertexData in vertexSource.Vertices()) { if (vertexData.IsStop) { break; } if (vertexData.IsMoveTo) { lastPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); } if (vertexData.IsLineTo) { Vector3 currentPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); mesh.CreateFace(new Vector3[] { Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationZ(endAngle)), Vector3Ex.Transform(currentPosition, Matrix4X4.CreateRotationZ(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationZ(startAngle)), Vector3Ex.Transform(lastPosition, Matrix4X4.CreateRotationZ(endAngle)), }); lastPosition = currentPosition; } } }
public static Vector3 MapMoveToSphere(Vector2 screenCenter, WorldView world, double trackBallRadius, Vector2 startPosition, Vector2 endPosition, bool rotateOnZ) { if (rotateOnZ) { var deltaFromScreenCenter = screenCenter - endPosition; var angleToTravel = screenCenter.GetDeltaAngle(startPosition, endPosition); // now rotate that position about z in the direction of the screen vector var positionOnRotationSphere = Vector3.Transform(new Vector3(1, 0, 0), Matrix4X4.CreateRotationZ(angleToTravel / 2)); return(positionOnRotationSphere); } else { var deltaFromStartPixels = endPosition - startPosition; var deltaOnSurface = new Vector2(deltaFromStartPixels.X / trackBallRadius, deltaFromStartPixels.Y / trackBallRadius); var lengthOnSurfaceRadi = deltaOnSurface.Length; // get this rotation on the surface of the sphere about y var positionAboutY = Vector3.Transform(new Vector3(0, 0, 1), Matrix4X4.CreateRotationY(lengthOnSurfaceRadi)); // get the angle that this distance travels around the sphere var angleToTravel = Math.Atan2(deltaOnSurface.Y, deltaOnSurface.X); // now rotate that position about z in the direction of the screen vector var positionOnRotationSphere = Vector3.Transform(positionAboutY, Matrix4X4.CreateRotationZ(angleToTravel)); return(positionOnRotationSphere); } }
public TumbleCubeControl(InteractionLayer interactionLayer, ThemeConfig theme) : base(100 * GuiWidget.DeviceScale, 100 * GuiWidget.DeviceScale) { this.theme = theme; this.interactionLayer = interactionLayer; // this data needs to be made on the ui thread UiThread.RunOnIdle(() => { TextureFace(0, "Top"); TextureFace(2, "Left", Matrix4X4.CreateRotationZ(MathHelper.Tau / 4)); TextureFace(4, "Right", Matrix4X4.CreateRotationZ(-MathHelper.Tau / 4)); TextureFace(6, "Bottom", Matrix4X4.CreateRotationZ(MathHelper.Tau / 2)); TextureFace(8, "Back", Matrix4X4.CreateRotationZ(MathHelper.Tau / 2)); TextureFace(10, "Front"); cube.MarkAsChanged(); connections.Add(new ConnectedFaces(2, 1, 1, 5, 2, 4)); connections.Add(new ConnectedFaces(0, -1, 4, 3, 5, 0)); connections.Add(new ConnectedFaces(0, 1, 5, 3, 4, 0)); connections.Add(new ConnectedFaces(2, -1, 1, 4, 2, 5)); connections.Add(new ConnectedFaces(1, 1, 2, 3, 1, 0)); connections.Add(new ConnectedFaces(1, -1, 1, 3, 2, 0)); cubeTraceData = cube.CreateTraceData(); }); MouseLeave += (s, e) => { ResetTextures(); }; }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); using (RebuildLock()) { var aabb = this.GetAxisAlignedBoundingBox(); var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(Math.Sqrt(2), 0); path.LineTo(0, Height); var mesh = VertexSourceToMesh.Revolve(path, 4); mesh.Transform(Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(45)) * Matrix4X4.CreateScale(Width / 2, Depth / 2, 1)); Mesh = mesh; if (aabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, aabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); }
private void Rebuild(UndoBuffer undoBuffer) { this.DebugDepth("Rebuild"); using (RebuildLock()) { var startingAabb = this.GetAxisAlignedBoundingBox(); // remove whatever rotation has been applied (they go in reverse order) Matrix = Matrix4X4.Identity; // add the current rotation Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationX(MathHelper.DegreesToRadians(RotationXDegrees))); Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(RotationYDegrees))); Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(RotationZDegrees))); if (startingAabb.ZSize > 0) { // If the part was already created and at a height, maintain the height. PlatingHelper.PlaceMeshAtHeight(this, startingAabb.minXYZ.Z); } } Invalidate(new InvalidateArgs(this, InvalidateType.Matrix, null)); }
// Transform by matrix public void PlaneTransformTest1() { Plane <float> target = new Plane <float>(1, 2, 3, 4); target = Plane.Normalize(target); Matrix4X4 <float> m = Matrix4X4.CreateRotationX(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationY(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationZ(MathHelper.ToRadians(30.0f)); m.M41 = 10.0f; m.M42 = 20.0f; m.M43 = 30.0f; Plane <float> expected = new Plane <float>(); Matrix4X4 <float> inv; Matrix4X4.Invert(m, out inv); Matrix4X4 <float> itm = Matrix4X4.Transpose(inv); float x = target.Normal.X, y = target.Normal.Y, z = target.Normal.Z, w = target.Distance; expected.Normal = new Vector3D <float>( x * itm.M11 + y * itm.M21 + z * itm.M31 + w * itm.M41, x * itm.M12 + y * itm.M22 + z * itm.M32 + w * itm.M42, x * itm.M13 + y * itm.M23 + z * itm.M33 + w * itm.M43); expected.Distance = x * itm.M14 + y * itm.M24 + z * itm.M34 + w * itm.M44; Plane <float> actual; actual = Plane.Transform(target, m); Assert.True(MathHelper.Equal(expected, actual), "Plane<float>.Transform did not return the expected value."); }
static void Main() { Matrix4X4 rotateAboutZ = Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(2)); CsgObject tPBinoculars = TPBinoculars(); OpenSCadOutput.Save(tPBinoculars, "TPBinoculars.scad"); }
public void Can_Rotate_Point_Around_Z() { var point = new Point(0, 1, 0); var halfQuarter = Matrix4X4.CreateRotationZ(Math.PI / 4); var fullQuarter = Matrix4X4.CreateRotationZ(Math.PI / 2); (halfQuarter * point).ShouldBe(new Point(-Math.Sqrt(2) / 2, Math.Sqrt(2) / 2, 0)); (fullQuarter * point).ShouldBe(new Point(-1, 0, 0)); }
public static void MoveMeshGroupToOpenPosition(int meshGroupToMoveIndex, List <PlatingMeshGroupData> perMeshInfo, List <MeshGroup> allMeshGroups, List <ScaleRotateTranslate> meshTransforms) { MeshGroup meshGroupToMove = allMeshGroups[meshGroupToMoveIndex]; // find a place to put it that doesn't hit anything AxisAlignedBoundingBox meshToMoveBounds = meshGroupToMove.GetAxisAlignedBoundingBox(meshTransforms[meshGroupToMoveIndex].TotalTransform); // add in a few mm so that it will not be touching meshToMoveBounds.minXYZ -= new Vector3(2, 2, 0); meshToMoveBounds.maxXYZ += new Vector3(2, 2, 0); double ringDist = Math.Min(meshToMoveBounds.XSize, meshToMoveBounds.YSize); double currentDist = 0; double angle = 0; double angleIncrement = MathHelper.Tau / 64; Matrix4X4 transform; while (true) { Matrix4X4 positionTransform = Matrix4X4.CreateTranslation(currentDist, 0, 0); positionTransform *= Matrix4X4.CreateRotationZ(angle); Vector3 newPosition = Vector3.Transform(Vector3.Zero, positionTransform); transform = Matrix4X4.CreateTranslation(newPosition); AxisAlignedBoundingBox testBounds = meshToMoveBounds.NewTransformed(transform); bool foundHit = false; for (int i = 0; i < allMeshGroups.Count; i++) { MeshGroup meshToTest = allMeshGroups[i]; if (meshToTest != meshGroupToMove) { AxisAlignedBoundingBox existingMeshBounds = meshToTest.GetAxisAlignedBoundingBox(meshTransforms[i].TotalTransform); AxisAlignedBoundingBox intersection = AxisAlignedBoundingBox.Intersection(testBounds, existingMeshBounds); if (intersection.XSize > 0 && intersection.YSize > 0) { foundHit = true; break; } } } if (!foundHit) { break; } angle += angleIncrement; if (angle >= MathHelper.Tau) { angle = 0; currentDist += ringDist; } } ScaleRotateTranslate moved = meshTransforms[meshGroupToMoveIndex]; moved.translation *= transform; meshTransforms[meshGroupToMoveIndex] = moved; }
public override async Task Rebuild() { var rebuildLock = this.RebuildLock(); SourceContainer.Visible = true; await ApplicationController.Instance.Tasks.Execute( "Advanced Array".Localize(), null, (reporter, cancellationToken) => { this.DebugDepth("Rebuild"); var sourceContainer = SourceContainer; this.Children.Modify(list => { list.Clear(); list.Add(sourceContainer); var lastChild = sourceContainer.Children.First(); list.Add(lastChild.Clone()); var offset = Offset; var count = Count.Value(this); var rotate = Rotate.Value(this); var scale = Scale.Value(this); for (int i = 1; i < count; i++) { var rotateRadians = MathHelper.DegreesToRadians(rotate); if (ScaleOffset) { offset *= scale; } var next = lastChild.Clone(); offset = Vector3Ex.Transform(offset, Matrix4X4.CreateRotationZ(rotateRadians)); next.Matrix *= Matrix4X4.CreateTranslation(offset); if (RotatePart) { next.Matrix = next.ApplyAtBoundsCenter(Matrix4X4.CreateRotationZ(rotateRadians)); } next.Matrix = next.ApplyAtBoundsCenter(Matrix4X4.CreateScale(scale)); list.Add(next); lastChild = next; } }); ProcessIndexExpressions(); SourceContainer.Visible = false; UiThread.RunOnIdle(() => { rebuildLock.Dispose(); Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Children)); }); return Task.CompletedTask; }); }
public void GetRotation(ref Vector3 pOutVector) { Vector3 UpVector = new Vector3(0, 1, 0);; Vector3 ForwardVector = new Vector3(0, 0, 1); UpVector = Vector3.Transform(UpVector, AxisToWorld); ForwardVector = Vector3.Transform(ForwardVector, AxisToWorld); pOutVector.z = Math.Atan2(UpVector.x, UpVector.y); // DebugStream("It looks like z is now " << RadToDeg(pOutVector->z)); Matrix4X4 ZMatrix = Matrix4X4.CreateRotationZ(-pOutVector.z); UpVector = Vector3.Transform(UpVector, ZMatrix); ForwardVector = Vector3.Transform(ForwardVector, ZMatrix); // DebugStream("It looks like z is now " << RadToDeg(atan2(UpVector.x, UpVector.y))); pOutVector.y = -Math.Atan2(ForwardVector.x, ForwardVector.z); // DebugStream("It looks like y is now " << RadToDeg(pOutVector->y)); Matrix4X4 YMatrix = Matrix4X4.CreateRotationY(-pOutVector.y); UpVector = Vector3.Transform(UpVector, YMatrix); ForwardVector = Vector3.Transform(ForwardVector, YMatrix); // DebugStream("It looks like y is now " << RadToDeg(-atan2(ForwardVector.x, ForwardVector.z))); pOutVector.x = -Math.Atan2(UpVector.z, UpVector.y); // DebugStream("It looks like x is now " << RadToDeg(pOutVector->x)); //CMatrix XMatrix; //XMatrix.Rotate(0, -pOutVector->x, ROTATE_FAST); //XMatrix.TransformVector(&UpVector); //XMatrix.TransformVector(&ForwardVector); // DebugStream("It looks like x is now " << RadToDeg(-atan2(UpVector.z, UpVector.y))); #if _DEBUG CMatrix Test; CVector3D TestV, HoldV; TestV.Set((double)(rand() % 1024), (double)(rand() % 1024), (double)(rand() % 1024)); HoldV = TestV; Test.PrepareMatrix(0.f, 0.f, 0.f, pOutVector->x, pOutVector->y, pOutVector->z); WorldToAxis.TransformVector(&TestV); Test.TransformVector(&TestV); #endif }
public static Matrix4X4 GetXYInViewRotation(this WorldView world, Vector3 center) { var positions = new Vector3[] { center + new Vector3(1, 0, 0), center + new Vector3(0, 1, 0), center + new Vector3(-1, 0, 0), center + new Vector3(0, -1, 0), }; double bestX = double.NegativeInfinity; int indexX = 0; // get the closest z on the bottom in view space for (int cornerIndex = 0; cornerIndex < 4; cornerIndex++) { Vector3 axisSide = positions[cornerIndex]; Vector3 axisSideScreenSpace = world.WorldToScreenSpace(axisSide); if (axisSideScreenSpace.X > bestX) { indexX = cornerIndex; bestX = axisSideScreenSpace.X; } } var transform = Matrix4X4.Identity; switch (indexX) { case 0: // transform = Matrix4X4.CreateRotationZ(0); break; case 1: transform = Matrix4X4.CreateRotationZ(MathHelper.Tau / 4); break; case 2: transform = Matrix4X4.CreateRotationZ(-MathHelper.Tau / 2); break; case 3: transform = Matrix4X4.CreateRotationZ(MathHelper.Tau * 3 / 4); break; } return(transform); }
public void Vector3TransformByQuaternionTest() { Vector3D <float> v = new Vector3D <float>(1.0f, 2.0f, 3.0f); Matrix4X4 <float> m = Matrix4X4.CreateRotationX <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationY <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationZ <float>(MathHelper.ToRadians(30.0f)); Quaternion <float> q = Quaternion <float> .CreateFromRotationMatrix(m); Vector3D <float> expected = Vector3D.Transform(v, m); Vector3D <float> actual = Vector3D.Transform(v, q); Assert.True(MathHelper.Equal(expected, actual), "Vector3D<float>f.Transform did not return the expected value."); }
private static void ValidateViewOnlyTexturing(IObject3D item) { // if there is no view only texture or the item is locked if (InteractionLayer.ViewOnlyTexture == null || item.Mesh.Faces.Count == 0) { return; } // if the item is not currently be processed if (!item.RebuildLocked) { item.Mesh.FaceTextures.TryGetValue(0, out FaceTextureData faceTexture); bool viewOnlyTexture = faceTexture?.image == InteractionLayer.ViewOnlyTexture; // if not persistable and has view only texture, remove the view only texture if it has it if (item.WorldPersistable() && viewOnlyTexture) { // make sure it does not have the view only texture using (item.RebuildLock()) { item.Mesh.RemoveTexture(ViewOnlyTexture, 0); } } else if (!item.WorldPersistable() && !viewOnlyTexture && !item.RebuildLocked) { // add a view only texture if it does not have one // make a copy of the mesh and texture it Task.Run(() => { // make sure it does have the view only texture var aabb = item.Mesh.GetAxisAlignedBoundingBox(); var matrix = Matrix4X4.CreateScale(.5, .5, 1); matrix *= Matrix4X4.CreateRotationZ(MathHelper.Tau / 8); // make sure it has it's own copy of the mesh using (item.RebuildLock()) { item.Mesh = item.Mesh.Copy(CancellationToken.None); item.Mesh.PlaceTexture(ViewOnlyTexture, matrix); } }); } } }
public override void SetPosition(IObject3D selectedItem) { Vector3 boxCenter = GetControlCenter(selectedItem); double distBetweenPixelsWorldSpace = InteractionContext.World.GetWorldUnitsPerScreenPixelAtPosition(boxCenter); GetCornerPosition(selectedItem, out int cornerIndexOut); Matrix4X4 centerMatrix = Matrix4X4.Identity; switch (RotationAxis) { case 0: if (cornerIndexOut == 1 || cornerIndexOut == 3) { centerMatrix *= Matrix4X4.CreateRotationX(MathHelper.DegreesToRadians(90)); } else { centerMatrix *= Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(-90)); } centerMatrix *= Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(90) * cornerIndexOut); break; case 1: if (cornerIndexOut == 1 || cornerIndexOut == 3) { centerMatrix *= Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(-90)); } else { centerMatrix *= Matrix4X4.CreateRotationX(MathHelper.DegreesToRadians(90)); } centerMatrix *= Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(90) * cornerIndexOut); break; case 2: centerMatrix *= Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(90) * cornerIndexOut); break; } centerMatrix *= Matrix4X4.CreateScale(distBetweenPixelsWorldSpace) * Matrix4X4.CreateTranslation(boxCenter); TotalTransform = centerMatrix; }
public void Vector3TransformNormalTest() { Vector3D <float> v = new Vector3D <float>(1.0f, 2.0f, 3.0f); Matrix4X4 <float> m = Matrix4X4.CreateRotationX <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationY <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationZ <float>(MathHelper.ToRadians(30.0f)); m.M41 = 10.0f; m.M42 = 20.0f; m.M43 = 30.0f; Vector3D <float> expected = new Vector3D <float>(2.19198728f, 1.53349364f, 2.61602545f); Vector3D <float> actual; actual = Vector3D.TransformNormal(v, m); Assert.True(MathHelper.Equal(expected, actual), "Vector3D<float>f.TransformNormal did not return the expected value."); }
public void QuaternionFromRotationMatrixWithScaledMatrixTest2() { float angle = MathHelper.ToRadians(180.0f); Matrix4X4 <float> matrix = Matrix4X4.CreateRotationX <float>(angle) * Matrix4X4.CreateRotationZ <float>(angle); Quaternion <float> expected = Quaternion <float> .CreateFromAxisAngle(Vector3D <float> .UnitZ, angle) * Quaternion <float> .CreateFromAxisAngle(Vector3D <float> .UnitX, angle); Quaternion <float> actual = Quaternion <float> .CreateFromRotationMatrix(matrix); Assert.True(MathHelper.EqualRotation(expected, actual), $"Quaternion<float>.CreateFromRotationMatrix did not return the expected value: expected {expected} actual {actual}"); // make sure convert back to matrix is same as we passed matrix. Matrix4X4 <float> m2 = Matrix4X4.CreateFromQuaternion <float>(actual); Assert.True(MathHelper.Equal(matrix, m2), $"Quaternion<float>.CreateFromQuaternion did not return the expected value: matrix {matrix} m2 {m2}"); }
public void Vector2TransformNormalTest() { Vector2D <float> v = new Vector2D <float>(1.0f, 2.0f); Matrix4X4 <float> m = Matrix4X4.CreateRotationX <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationY <float>(MathHelper.ToRadians(30.0f)) * Matrix4X4.CreateRotationZ <float>(MathHelper.ToRadians(30.0f)); m.M41 = 10.0f; m.M42 = 20.0f; m.M43 = 30.0f; Vector2D <float> expected = new Vector2D <float>(0.3169873f, 2.18301272f); Vector2D <float> actual; actual = Vector2D.TransformNormal(v, m); Assert.True(MathHelper.Equal(expected, actual), "Vector2f.Tranform did not return the expected value."); }
public void QuaternionFromRotationMatrixTest4() { for (float angle = 0.0f; angle < 720.0f; angle += 10.0f) { Matrix4X4 <float> matrix = Matrix4X4.CreateRotationZ <float>(angle); Quaternion <float> expected = Quaternion <float> .CreateFromAxisAngle(Vector3D <float> .UnitZ, angle); Quaternion <float> actual = Quaternion <float> .CreateFromRotationMatrix(matrix); Assert.True(MathHelper.EqualRotation(expected, actual), $"Quaternion<float>.CreateFromRotationMatrix angle:{angle} did not return the expected value: expected {expected} actual {actual}"); // make sure convert back to matrix is same as we passed matrix. Matrix4X4 <float> m2 = Matrix4X4.CreateFromQuaternion <float>(actual); Assert.True(MathHelper.Equal(matrix, m2), $"Quaternion<float>.CreateFromQuaternion angle:{angle} did not return the expected value: matrix {matrix} m2 {m2}"); } }
//used to transform the sweepers vertices prior to rendering public void WorldTransform(List <Vector3> sweeper) { //create the world transformation matrix Matrix4X4 matTransform = Matrix4X4.Identity; //scale matTransform *= Matrix4X4.CreateScale(m_dScale, m_dScale, 1); //rotate matTransform *= Matrix4X4.CreateRotationZ(m_dRotation); //and translate matTransform *= Matrix4X4.CreateTranslation(m_vPosition.X, m_vPosition.Y, 0); //now transform the ships vertices for (int i = 0; i < sweeper.Count; i++) { sweeper[i] = sweeper[i].Transform(matTransform); } }
public TumbleCubeControl(InteractionLayer interactionLayer) : base(100 * GuiWidget.DeviceScale, 100 * GuiWidget.DeviceScale) { this.interactionLayer = interactionLayer; // this data needs to be made on the ui thread UiThread.RunOnIdle(() => { cube.CleanAndMergeMesh(CancellationToken.None); TextureFace(cube.Faces[0], "Top"); TextureFace(cube.Faces[1], "Left", Matrix4X4.CreateRotationZ(MathHelper.Tau / 4)); TextureFace(cube.Faces[2], "Right", Matrix4X4.CreateRotationZ(-MathHelper.Tau / 4)); TextureFace(cube.Faces[3], "Bottom", Matrix4X4.CreateRotationZ(MathHelper.Tau / 2)); TextureFace(cube.Faces[4], "Back", Matrix4X4.CreateRotationZ(MathHelper.Tau / 2)); TextureFace(cube.Faces[5], "Front"); cube.MarkAsChanged(); cubeTraceData = cube.CreateTraceData(); }); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); using (RebuildLock()) { using (new CenterAndHeightMaintainer(this)) { var path = new VertexStorage(); path.MoveTo(0, 0); path.LineTo(Math.Sqrt(2), 0); path.LineTo(0, Height); var mesh = VertexSourceToMesh.Revolve(path, 4); mesh.Transform(Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(45)) * Matrix4X4.CreateScale(Width / 2, Depth / 2, 1)); Mesh = mesh; } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Mesh)); return(Task.CompletedTask); }
public override Task Rebuild() { this.DebugDepth("Rebuild"); using (RebuildLock()) { using (new CenterAndHeightMantainer(this)) { var startingAabb = this.GetAxisAlignedBoundingBox(); // remove whatever rotation has been applied (they go in reverse order) Matrix = Matrix4X4.Identity; // add the current rotation Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationX(MathHelper.DegreesToRadians(RotationXDegrees))); Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationY(MathHelper.DegreesToRadians(RotationYDegrees))); Matrix = this.ApplyAtPosition(startingAabb.Center, Matrix4X4.CreateRotationZ(MathHelper.DegreesToRadians(RotationZDegrees))); } } Parent?.Invalidate(new InvalidateArgs(this, InvalidateType.Matrix)); return(Task.CompletedTask); }
private Vector3 MapMoveToSphere(Vector2 screenPoint, bool rotateOnZ) { if (rotateOnZ) { var deltaFromScreenCenter = world.ScreenCenter - screenPoint; var angleToTravel = world.ScreenCenter.GetDeltaAngle(mouseDownPosition, screenPoint); // now rotate that position about z in the direction of the screen vector var positionOnRotationSphere = Vector3.Transform(new Vector3(1, 0, 0), Matrix4X4.CreateRotationZ(angleToTravel / 2)); return(positionOnRotationSphere); } else { var deltaFromStartPixels = screenPoint - mouseDownPosition; var deltaOnSurface = new Vector2(deltaFromStartPixels.X / rotationTrackingRadiusPixels, deltaFromStartPixels.Y / rotationTrackingRadiusPixels); var lengthOnSurfaceRadi = deltaOnSurface.Length; // get this rotation on the surface of the sphere about y var positionAboutY = Vector3.Transform(new Vector3(0, 0, 1), Matrix4X4.CreateRotationY(lengthOnSurfaceRadi)); // get the angle that this distance travels around the sphere var angleToTravel = Math.Atan2(deltaOnSurface.Y, deltaOnSurface.X); // now rotate that position about z in the direction of the screen vector var positionOnRotationSphere = Vector3.Transform(positionAboutY, Matrix4X4.CreateRotationZ(angleToTravel)); return(positionOnRotationSphere); } }
private void DrawObject(IObject3D object3D, List <Object3DView> transparentMeshes, DrawEventArgs e) { var selectedItem = scene.SelectedItem; foreach (var item in object3D.VisibleMeshes()) { // check for correct persistable rendering if (InteractionLayer.ViewOnlyTexture != null && item.Mesh.Faces.Count > 0) { ImageBuffer faceTexture = null; //item.Mesh.FaceTexture.TryGetValue((item.Mesh.Faces[0], 0), out faceTexture); bool hasPersistableTexture = faceTexture == InteractionLayer.ViewOnlyTexture; if (item.WorldPersistable()) { if (hasPersistableTexture) { // make sure it does not have the view only texture item.Mesh.RemoveTexture(ViewOnlyTexture, 0); } } else { if (!hasPersistableTexture) { // make sure it does have the view only texture var aabb = item.Mesh.GetAxisAlignedBoundingBox(); var matrix = Matrix4X4.CreateScale(.5, .5, 1); matrix *= Matrix4X4.CreateRotationZ(MathHelper.Tau / 8); item.Mesh.PlaceTexture(ViewOnlyTexture, matrix); } } } Color drawColor = this.GetItemColor(item, selectedItem); bool hasTransparentTextures = item.Mesh.FaceTextures.Any(ft => ft.Value.image.HasTransparency); if ((drawColor.alpha == 255 && !hasTransparentTextures) || (item == scene.DebugItem)) { // Render as solid GLHelper.Render(item.Mesh, drawColor, item.WorldMatrix(), sceneContext.ViewState.RenderType, item.WorldMatrix() * World.ModelviewMatrix, darkWireframe, () => Invalidate()); } else if (drawColor != Color.Transparent) { // Queue for transparency transparentMeshes.Add(new Object3DView(item, drawColor)); } bool isSelected = selectedItem != null && (selectedItem.DescendantsAndSelf().Any((i) => i == item) || selectedItem.Parents <ModifiedMeshObject3D>().Any((mw) => mw == item)); // Invoke all item Drawables foreach (var drawable in itemDrawables.Where(d => d.DrawStage != DrawStage.Last && d.Enabled)) { drawable.Draw(this, item, isSelected, e, Matrix4X4.Identity, this.World); } // turn lighting back on after rendering selection outlines GL.Enable(EnableCap.Lighting); } }
public static Mesh Revolve(IVertexSource source, int angleSteps = 30, double angleStart = 0, double angleEnd = MathHelper.Tau) { angleSteps = Math.Max(angleSteps, 3); angleStart = MathHelper.Range0ToTau(angleStart); angleEnd = MathHelper.Range0ToTau(angleEnd); // convert to clipper polygons and scale so we can ensure good shapes Polygons polygons = source.CreatePolygons(); // ensure good winding and consistent shapes // clip against x=0 left and right // mirror left material across the origin // union mirrored left with right material // convert the data back to PathStorage VertexStorage cleanedPath = polygons.CreateVertexStorage(); Mesh mesh = new Mesh(); var hasStartAndEndFaces = angleStart > 0.000001; hasStartAndEndFaces |= angleEnd < MathHelper.Tau - 0.000001; // check if we need to make closing faces if (hasStartAndEndFaces) { // make a face for the start CachedTesselator teselatedSource = new CachedTesselator(); Mesh extrudedVertexSource = TriangulateFaces(source, teselatedSource); extrudedVertexSource.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); extrudedVertexSource.Transform(Matrix4X4.CreateRotationZ(angleStart)); mesh.CopyFaces(extrudedVertexSource); } // make the outside shell double angleDelta = (angleEnd - angleStart) / angleSteps; double currentAngle = angleStart; if (!hasStartAndEndFaces) { angleSteps--; } for (int i = 0; i < angleSteps; i++) { AddRevolveStrip(cleanedPath, mesh, currentAngle, currentAngle + angleDelta); currentAngle += angleDelta; } if (!hasStartAndEndFaces) { if (((angleEnd - angleStart) < .0000001 || (angleEnd - MathHelper.Tau - angleStart) < .0000001) && (angleEnd - currentAngle) > .0000001) { // make sure we close the shape exactly AddRevolveStrip(cleanedPath, mesh, currentAngle, angleStart); } } else // add the end face { // make a face for the end CachedTesselator teselatedSource = new CachedTesselator(); Mesh extrudedVertexSource = TriangulateFaces(source, teselatedSource); extrudedVertexSource.Transform(Matrix4X4.CreateRotationX(MathHelper.Tau / 4)); extrudedVertexSource.Transform(Matrix4X4.CreateRotationZ(currentAngle)); extrudedVertexSource.ReverseFaceEdges(); mesh.CopyFaces(extrudedVertexSource); } // return the completed mesh return(mesh); }
static void AddRevolveStrip(IVertexSource vertexSource, Mesh mesh, double startAngle, double endAngle) { CreateOption createOption = CreateOption.CreateNew; SortOption sortOption = SortOption.WillSortLater; Vector3 lastPosition = Vector3.Zero; foreach (var vertexData in vertexSource.Vertices()) { if (vertexData.IsStop) { break; } if (vertexData.IsMoveTo) { lastPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); } if (vertexData.IsLineTo) { Vector3 currentPosition = new Vector3(vertexData.position.X, 0, vertexData.position.Y); IVertex lastStart = mesh.CreateVertex(Vector3.Transform(lastPosition, Matrix4X4.CreateRotationZ(startAngle)), createOption, sortOption); IVertex lastEnd = mesh.CreateVertex(Vector3.Transform(lastPosition, Matrix4X4.CreateRotationZ(endAngle)), createOption, sortOption); IVertex currentStart = mesh.CreateVertex(Vector3.Transform(currentPosition, Matrix4X4.CreateRotationZ(startAngle)), createOption, sortOption); IVertex currentEnd = mesh.CreateVertex(Vector3.Transform(currentPosition, Matrix4X4.CreateRotationZ(endAngle)), createOption, sortOption); mesh.CreateFace(new IVertex[] { lastStart, lastEnd, currentEnd, currentStart }, createOption); lastPosition = currentPosition; } } }