Example #1
0
        void CompositionTarget_Rendering(object sender, EventArgs e)
        {
            if (_timer.OnInterval())
            {
                CheckCommand();
            }

            _rubikscube.Animator.Start(null);

            _rubikscube.Animator.Update();

            //camera movement

            if (_cameraMove != 0)
            {
                _cameraZ += _cameraMove;
                Vector3D p = new Vector3D(0, 0, _cameraZ);//120); //60;
                p = Ext3D.Transform(p, _cameraRotate); _camera.Position = new Point3D(p.X, p.Y, p.Z);
                //Debug.WriteLine(_camera.Position);
                if (_cameraZ <= _cameraNear || _cameraZ >= _cameraFar)
                {
                    _cameraMove = 0;
                    OnLayoutUpdated();
                }
            }
        }
Example #2
0
        public virtual Matrix3D Rotate(Axis axis, double deltaAngle, bool isFromSaved)
        {
            Quaternion3D rotationQ = Quaternion3D.Identity;

            switch (axis)
            {
            case Axis.X:
                rotationQ *= Quaternion3D.CreateFromAxisAngle(_unitX, deltaAngle);
                break;

            case Axis.Y:
                rotationQ *= Quaternion3D.CreateFromAxisAngle(_unitY, deltaAngle);
                break;

            case Axis.Z:
                rotationQ *= Quaternion3D.CreateFromAxisAngle(_unitZ, deltaAngle);
                break;
            }
            Matrix3D matrix = Ext3D.CreateFromQuaternion(rotationQ);

            if (isFromSaved)
            {
                _transform = matrix * _savedTransform;
            }
            else
            {
                _transform = matrix * _transform;
            }

            return(matrix);
        }
Example #3
0
        public void RotateUnit(Axis axis, double rotation)
        {
            Matrix3D transform = Matrix3D.Identity;

            switch (axis)
            {
            case Axis.X:
                transform = Ext3D.CreateRotationX(rotation);
                break;

            case Axis.Y:
                transform = Ext3D.CreateRotationY(rotation);
                break;

            case Axis.Z:
                transform = Ext3D.CreateRotationZ(rotation);
                break;
            }
            _axisTransform = _axisTransform * transform;
            transform      = _axisTransform;
            transform.Invert();
            _unitX = Ext3D.Transform(Ext3D.UnitX, transform);
            _unitY = Ext3D.Transform(Ext3D.UnitY, transform);
            _unitZ = Ext3D.Transform(Ext3D.UnitZ, transform);
        }
Example #4
0
 public override void Restore()
 {
     base.Restore();
     foreach (CubieFace face in Faces.Values)
     {
         face.Restore();
     }
     _center = Ext3D.Transform(_center, base.Transform);
 }
Example #5
0
        public override Matrix3D Rotate(Axis axis, double deltaAngle, bool isFromSaved)
        {
            Matrix3D matrix = base.Rotate(axis, deltaAngle, isFromSaved);

            _center = Ext3D.Transform(_center, base.Transform);
            foreach (CubieFace face in Faces.Values)
            {
                face.DoTransform(matrix, isFromSaved);
            }
            return(matrix);
        }
Example #6
0
        public override void DoTransform(double deltaAngle)
        {
            //  Debug.WriteLine("start DoTransform");
            foreach (CubicleFace face in AffectedFaces)
            {
                Cubie     cubie     = face.CubieFace.Cubie;
                CubieFace cubieFace = face.CubieFace;
                //cubicle.Cubie.Rotate(BasicOp.Axis, deltaAngle, false);
                Vector3D axis = face.CubieFace.Cubie.UnitX;

                if (Axis == Axis.X)
                {
                    axis = face.CubieFace.Cubie.UnitX;
                }
                else if (Axis == Axis.Y)
                {
                    axis = face.CubieFace.Cubie.UnitY;
                }
                else if (Axis == Axis.Z)
                {
                    axis = face.CubieFace.Cubie.UnitZ;
                }

                Quaternion3D rot       = Quaternion3D.CreateFromAxisAngle(axis, deltaAngle);
                Matrix3D     rotMatrix = Ext3D.CreateFromQuaternion(rot);
                Matrix3D     matrix    = cubie.Transform;// Matrix.Invert(cubie.Transform);
                matrix.Invert();


                Matrix3D rotation = Ext3D.CreateTranslation(Ext3D.Transform(-AxisTranslationFromOrigin, matrix)) * rotMatrix * Ext3D.CreateTranslation(Ext3D.Transform(AxisTranslationFromOrigin, matrix));
                if (IsAxisMoving)
                {
                    Vector3D v1;
                    if (!_axisTranslation.ContainsKey(cubieFace))
                    {
                        Matrix3D m = (cubieFace as ITransform).Transform; m.Invert();
                        v1 = Ext3D.Transform(Axis2TranslationFromOrigin, m);
                        _axisTranslation.Add(cubieFace, v1);
                    }
                    v1 = _axisTranslation[cubieFace];
                    Matrix3D r = rotation; r.Invert();
                    v1 = Ext3D.Transform(v1, r);// Matrix.Invert(rotation));

                    Matrix3D rotationAxis = Ext3D.CreateTranslation(-v1) * rotMatrix * Ext3D.CreateTranslation(v1);
                    rotation = rotationAxis * rotation;

                    _axisTranslation[cubieFace] = v1;
                }
                (cubieFace as ITransform).DoTransform(rotation, false);
            }
        }
Example #7
0
        private void Track(Point currentPosition)
        {
            Vector3D currentPosition3D = currentPosition.ProjectToTrackball(
                _viewport.ActualWidth, _viewport.ActualHeight);
            Vector3D axis  = Vector3D.CrossProduct(_previousPosition3D, currentPosition3D);
            double   angle = Ext3D.AngleBetween(_previousPosition3D, currentPosition3D);

            axis = Ext3D.Transform(axis, _cameraRotate);
            Methods.RotateCameraResult rcr = _camera.RotateCamera(axis, -angle);
            _cameraRotate *= rcr.RotateMatrix;
            _viewMatrix    = rcr.ViewMatrix;
            OnLayoutUpdated();
            _previousPosition3D = currentPosition3D;
        }
Example #8
0
        /// <summary>
        /// Only if deep is true, then HitCubieResult could have some value
        /// </summary>
        /// <param name="pt"></param>
        /// <param name="deep"></param>
        /// <param name="hitResult"></param>
        /// <returns></returns>
        public bool HitTest(Point pt, bool deep, out HitResult hitResult)
        {
            hitResult = null;
            Ray3D ray = Ext3D.Unproject(pt, _viewpoint, _model.Transform, _inverseViewMatrix, _inverseProjectionMatrix);
            //Debug.WriteLine(string.Format("ray: {0}", ray));
            double?d = this.BoundingBox.Intersects(ray);

            if (!deep)
            {
                if (d != null)
                {
                    //Debug.WriteLine(string.Format("first ray: {0}, distance:{1}", ray, (double)d));
                    hitResult = new HitResult()
                    {
                        Distance = (double)d, HitCubicle = null, HitPoint = ray.Origin + (double)d * ray.Direction
                    };
                }
            }
            else
            {
                List <HitResult> results = new List <HitResult>();
                if (d != null)
                {
                    double?d1;
                    foreach (Cubicle cubicle in _cubicles.Values)
                    {
                        Matrix3D localToWorld = _model.Transform; localToWorld.Invert();// *cubicle.Cubie.Transform;
                        ray = Ext3D.Unproject(pt, _viewpoint, localToWorld, _inverseViewMatrix, _inverseProjectionMatrix);
                        //d1 = cubicle.Cubie.BoundingBox.Intersects(ray);
                        d1 = cubicle.BoundingBox.Intersects(ray);
                        if (d1 != null)
                        {
                            HitResult result = new HitResult()
                            {
                                Distance = (double)d1, HitCubicle = cubicle, HitPoint = ray.Origin + (double)d1 * ray.Direction
                            };
                            results.Add(result);
                        }
                    }
                    results.Sort((x, y) => x.Distance.CompareTo(y.Distance));
                    if (results.Count > 0)
                    {
                        hitResult = results[0];
                    }
                }
            }
            return(d != null);
        }
Example #9
0
        void ResetCamera()
        {
            _cameraZ              = _cameraNear; _cameraMove = 0;
            _camera.Position      = new Point3D(0, 0, _cameraNear); //60
            _camera.LookDirection = new Vector3D(0, 0, -1);
            _camera.UpDirection   = new Vector3D(0, 1, 0);
            _camera.FieldOfView   = 80;

            Matrix3D vm = Matrix3D.Identity;

            _cameraRotate = _camera.RotateCamera(new Vector3D(0, 1, 0), Math.PI / 6).RotateMatrix;
            Vector3D axis = new Vector3D(1, 0, 0); axis = Ext3D.Transform(axis, _cameraRotate);

            Methods.RotateCameraResult rcr = _camera.RotateCamera(axis, -Math.PI / 6);
            _cameraRotate *= rcr.RotateMatrix;
            _viewMatrix    = rcr.ViewMatrix;
        }
Example #10
0
        public static RotateCameraResult RotateCamera(this PerspectiveCamera camera, Vector3D axis, double angle)
        {
            axis.Normalize();
            Quaternion3D q = Quaternion3D.CreateFromAxisAngle(axis, angle);
            Matrix3D     m = Ext3D.CreateFromQuaternion(q);

            Vector3D p   = new Vector3D(camera.Position.X, camera.Position.Y, camera.Position.Z);
            Vector3D pos = Ext3D.Transform(p, m);

            camera.Position = new Point3D(pos.X, pos.Y, pos.Z);

            Vector3D d = new Vector3D(camera.LookDirection.X, camera.LookDirection.Y, camera.LookDirection.Z);

            camera.LookDirection = Ext3D.Transform(d, m);
            Vector3D up = new Vector3D(camera.UpDirection.X, camera.UpDirection.Y, camera.UpDirection.Z);

            camera.UpDirection = Ext3D.Transform(up, m);
            return(new RotateCameraResult
            {
                RotateMatrix = m,
                ViewMatrix = CalculateViewMatrix(camera.Position, camera.LookDirection, camera.UpDirection)
            });
        }
Example #11
0
        public double TestAngle(Point pt, HitResult prevHit, Axis axis)
        {
            Ray3D ray = Ext3D.Unproject(pt, _viewpoint, _model.Transform, _inverseViewMatrix, _inverseProjectionMatrix);
            //Plane yz = new Plane(-1, 0, 0, prevHit.HitPoint.X);
            //Point3 pyz; double? d = yz.Intersects(ray); Debug.WriteLine(string.Format("second ray: {0}: distance: {1}", ray, (double)d));

            //Debug.WriteLine(string.Format("second ray: {0}", ray));
            double angle = 0;

            switch (axis)
            {
            case Axis.X:
                Plane3D yz = new Plane3D(new Vector3D(-1, 0, 0), prevHit.HitPoint.X); Point3D oyz = new Point3D(prevHit.HitPoint.X, 0, 0);
                Point3D pyz; yz.Intersect(ray, out pyz); Vector3D from = prevHit.HitPoint - oyz; Vector3D to = pyz - oyz;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitX, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;

            case Axis.Z:
                Plane3D xy = new Plane3D(new Vector3D(0, 0, -1), prevHit.HitPoint.Z); Point3D oxy = new Point3D(0, 0, prevHit.HitPoint.Z);
                Point3D pxy; xy.Intersect(ray, out pxy); from = prevHit.HitPoint - oxy; to = pxy - oxy;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitZ, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;

            case Axis.Y:
                Plane3D zx = new Plane3D(new Vector3D(0, -1, 0), prevHit.HitPoint.Y); Point3D ozx = new Point3D(0, prevHit.HitPoint.Y, 0);
                Point3D pzx; zx.Intersect(ray, out pzx); from = prevHit.HitPoint - ozx; to = pzx - ozx;


                angle = Ext3D.AngleBetween(from, to);
                if (Vector3D.DotProduct(Ext3D.UnitY, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }

                break;
            }

            /*
             * if (angle < 2)
             *  angle = null;
             * else
             * {
             *  Debug.WriteLine(string.Format("axis: {0}, angle:{1}", axis, angle));
             * }
             */
            return(angle);
        }
Example #12
0
        public double?TestAngle(Point pt, HitResult prevHit, out Axis axis)
        {
            HitResult hitResult;
            bool      hit   = HitTest(pt, true, out hitResult);
            double?   angle = null;

            axis = Axis.X;
            if (hit)
            {
                Vector3D from, to;
                angle = 0;

                axis = Axis.Z;
                Point3D oxy     = new Point3D(0, 0, prevHit.HitPoint.Z); from = prevHit.HitPoint - oxy; to = new Point3D(hitResult.HitPoint.X, hitResult.HitPoint.Y, prevHit.HitPoint.Z) - oxy;
                double  xyAngle = Ext3D.AngleBetween(from, to);

                angle = xyAngle;
                if (Vector3D.DotProduct(Ext3D.UnitZ, Vector3D.CrossProduct(from, to)) < 0)
                {
                    angle = -angle;
                }


                //plane yz, where x = prevHit.X, Axis.X
                Point3D oyz     = new Point3D(prevHit.HitPoint.X, 0, 0); from = prevHit.HitPoint - oyz; to = new Point3D(prevHit.HitPoint.X, hitResult.HitPoint.Y, hitResult.HitPoint.Z) - oyz;
                double  yzAngle = Ext3D.AngleBetween(from, to);
                if (System.Math.Abs(yzAngle) > System.Math.Abs((double)angle))
                {
                    angle = yzAngle;
                    axis  = Axis.X;
                    if (Vector3D.DotProduct(Ext3D.UnitX, Vector3D.CrossProduct(from, to)) < 0)
                    {
                        angle = -angle;
                    }
                }

                //plane zx, where y = prevHit.Y, Axis.Y
                Point3D ozx     = new Point3D(0, prevHit.HitPoint.Y, 0); from = prevHit.HitPoint - ozx; to = new Point3D(hitResult.HitPoint.X, prevHit.HitPoint.Y, hitResult.HitPoint.Z) - ozx;
                double  zxAngle = Ext3D.AngleBetween(from, to);
                if (System.Math.Abs(zxAngle) > System.Math.Abs((double)angle))
                {
                    angle = zxAngle;
                    axis  = Axis.Y;
                    if (Vector3D.DotProduct(Ext3D.UnitY, Vector3D.CrossProduct(from, to)) < 0)
                    {
                        angle = -angle;
                    }
                }

                double threshold = Angle.DegreesToRadians(1.0);

                if (angle != null)
                {
                    //Debug.WriteLine(string.Format("angle: {0}, threshold:{1}", angle, threshold));
                    if (System.Math.Abs((double)angle) < threshold)
                    {
                        //Debug.WriteLine("non null to null");
                        angle = null;
                    }
                }
                //else
                //Debug.WriteLine("null angle");
            }
            return(angle);
        }