/// <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); }
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); }