예제 #1
0
        // 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;
                }
            });
        }
예제 #3
0
        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;
                }
            }
        }
예제 #5
0
        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);
            }
        }
예제 #6
0
        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();
            };
        }
예제 #7
0
        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));
        }
예제 #8
0
        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));
        }
예제 #9
0
        // 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");
        }
예제 #11
0
        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));
        }
예제 #12
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;
				});
		}
예제 #14
0
        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
        }
예제 #15
0
        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);
        }
예제 #16
0
        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.");
        }
예제 #17
0
        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);
                        }
                    });
                }
            }
        }
예제 #18
0
        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;
        }
예제 #19
0
        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.");
        }
예제 #20
0
        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}");
        }
예제 #21
0
        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.");
        }
예제 #22
0
        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}");
            }
        }
예제 #23
0
        //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);
            }
        }
예제 #24
0
        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();
            });
        }
예제 #25
0
        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);
        }
예제 #26
0
        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);
            }
        }
예제 #28
0
        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);
            }
        }
예제 #29
0
        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);
        }
예제 #30
0
        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;
                }
            }
        }