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(); } } }
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); }
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); }
public override void Restore() { base.Restore(); foreach (CubieFace face in Faces.Values) { face.Restore(); } _center = Ext3D.Transform(_center, base.Transform); }
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); }
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); } }
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; }
/// <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); }
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; }
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) }); }
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); }
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); }