public override bool Pick(ViewControl vc, Point scrPt) { m_hitRegion = HitRegion.None; if (base.Pick(vc, scrPt) == false) { return(false); } Camera camera = vc.Camera; Matrix4F view = camera.ViewMatrix; Matrix4F vp = view * camera.ProjectionMatrix; Matrix4F wvp = HitMatrix * vp; Ray3F rayL = vc.GetRay(scrPt, wvp); float s = Util.CalcAxisScale(vc.Camera, HitMatrix.Translation, AxisLength, vc.Height); // There's only one hot-spot for this manipulator: // a square at the manipulator origin. Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f); Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f); AABB box = new AABB(min, max); float centerCubeScale = s * CenterCubeSize; Matrix4F centerCubeXform = new Matrix4F(); centerCubeXform.Scale(centerCubeScale); centerCubeXform.Invert(centerCubeXform); Ray3F ray = rayL; ray.Transform(centerCubeXform); if (box.Intersect(ray)) { m_hitRegion = HitRegion.XYSquare; return(true); } m_hitRegion = HitRegion.None; return(false); }
public override ManipulatorPickResult Pick(ViewControl vc, Point scrPt) { m_hitRegion = HitRegion.None; if (base.Pick(vc, scrPt) == ManipulatorPickResult.Miss) { return(ManipulatorPickResult.Miss); } Camera camera = vc.Camera; float s = Util.CalcAxisScale(vc.Camera, HitMatrix.Translation, AxisLength, vc.Height); Matrix4F vp = camera.ViewMatrix * camera.ProjectionMatrix; Matrix4F wvp = HitMatrix * vp; // get ray in object space space. Ray3F rayL = vc.GetRay(scrPt, wvp); m_scale = new Vec3F(1, 1, 1); m_hitScale = s; Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f); Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f); AABB box = new AABB(min, max); Matrix4F boxScale = new Matrix4F(); Matrix4F boxTrans = new Matrix4F(); Matrix4F BoxMtrx = new Matrix4F(); float handleScale = s * AxisHandle; // +X axis boxScale.Scale(new Vec3F(s, handleScale, handleScale)); boxTrans.Translation = new Vec3F(s / 2, 0, 0); BoxMtrx = boxScale * boxTrans; Ray3F ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.XAxis; return(ManipulatorPickResult.DeferredBeginDrag); } // -X boxTrans.Translation = new Vec3F(-s / 2, 0, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.NegXAxis; return(ManipulatorPickResult.DeferredBeginDrag); } // y axis boxScale.Scale(new Vec3F(handleScale, s, handleScale)); boxTrans.Translation = new Vec3F(0, s / 2, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.YAxis; return(ManipulatorPickResult.DeferredBeginDrag); } // -Y boxTrans.Translation = new Vec3F(0, -s / 2, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.NegYAxis; return(ManipulatorPickResult.DeferredBeginDrag); } // z axis boxScale.Scale(new Vec3F(handleScale, handleScale, s)); boxTrans.Translation = new Vec3F(0, 0, s / 2); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.ZAxis; return(ManipulatorPickResult.DeferredBeginDrag); } // -Z boxTrans.Translation = new Vec3F(0, 0, -s / 2); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.NegZAxis; return(ManipulatorPickResult.DeferredBeginDrag); } return(ManipulatorPickResult.Miss); }
public override bool Pick(ViewControl vc, Point scrPt) { m_hitRegion = HitRegion.None; if (base.Pick(vc, scrPt) == false) { return(false); } Camera camera = vc.Camera; float s; Util.CalcAxisLengths(camera, HitMatrix.Translation, out s); Matrix4F vp = camera.ViewMatrix * camera.ProjectionMatrix; Matrix4F wvp = HitMatrix * vp; // get ray in object space space. Ray3F rayL = vc.GetRay(scrPt, wvp); m_scale = new Vec3F(1, 1, 1); m_hitScale = s; float rectScale = s * FreeRectRatio; Vec3F topRight = rectScale * (new Vec3F(1, 1, 0)); Vec3F topLeft = rectScale * (new Vec3F(-1, 1, 0)); Vec3F bottomLeft = rectScale * (new Vec3F(-1, -1, 0)); Vec3F bottomRight = rectScale * (new Vec3F(1, -1, 0)); Matrix4F planeXform = Util.CreateBillboard(HitMatrix.Translation, camera.WorldEye, camera.Up, camera.LookAt); Matrix4F wvpPlane = planeXform * vp; // create ray in plane's local space. Ray3F rayP = vc.GetRay(scrPt, wvpPlane); Plane3F plane = new Plane3F(topRight, topLeft, bottomLeft); Vec3F p; bool intersect = rayP.IntersectPlane(plane, out p); if (intersect) { bool inside = p.X > topLeft.X && p.X <topRight.X && p.Y> bottomLeft.Y && p.Y < topLeft.Y; if (inside) { m_hitRegion = HitRegion.FreeRect; return(true); } } Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f); Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f); AABB box = new AABB(min, max); Matrix4F boxScale = new Matrix4F(); Matrix4F boxTrans = new Matrix4F(); Matrix4F BoxMtrx = new Matrix4F(); float handleScale = s * HandleRatio; // X axis boxScale.Scale(new Vec3F(s, handleScale, handleScale)); boxTrans.Translation = new Vec3F(s / 2, 0, 0); BoxMtrx = boxScale * boxTrans; Ray3F ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.XAxis; return(true); } // y axis boxScale.Scale(new Vec3F(handleScale, s, handleScale)); boxTrans.Translation = new Vec3F(0, s / 2, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.YAxis; return(true); } // z axis boxScale.Scale(new Vec3F(handleScale, handleScale, s)); boxTrans.Translation = new Vec3F(0, 0, s / 2); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.ZAxis; return(true); } return(false); }
public override bool Pick(ViewControl vc, Point scrPt) { m_hitRegion = HitRegion.None; if (base.Pick(vc, scrPt) == false) { return(false); } Camera camera = vc.Camera; float s = Util.CalcAxisScale(vc.Camera, HitMatrix.Translation, AxisLength, vc.Height); Matrix4F vp = camera.ViewMatrix * camera.ProjectionMatrix; Matrix4F wvp = HitMatrix * vp; // get ray in object space space. Ray3F rayL = vc.GetRay(scrPt, wvp); m_scale = new Vec3F(1, 1, 1); m_hitScale = s; Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f); Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f); AABB box = new AABB(min, max); float centerCubeScale = s * CenterCubeSize; Matrix4F centerCubeXform = new Matrix4F(); centerCubeXform.Scale(centerCubeScale); centerCubeXform.Invert(centerCubeXform); Ray3F ray = rayL; ray.Transform(centerCubeXform); if (box.Intersect(ray)) { m_hitRegion = HitRegion.CenterCube; return(true); } Matrix4F boxScale = new Matrix4F(); Matrix4F boxTrans = new Matrix4F(); Matrix4F BoxMtrx = new Matrix4F(); float handleScale = s * AxisHandle; // X axis boxScale.Scale(new Vec3F(s, handleScale, handleScale)); boxTrans.Translation = new Vec3F(s / 2, 0, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.XAxis; return(true); } // y axis boxScale.Scale(new Vec3F(handleScale, s, handleScale)); boxTrans.Translation = new Vec3F(0, s / 2, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.YAxis; return(true); } // z axis boxScale.Scale(new Vec3F(handleScale, handleScale, s)); boxTrans.Translation = new Vec3F(0, 0, s / 2); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.ZAxis; return(true); } return(false); }
public HitRegion Pick(ViewControl vc, Matrix4F world, Matrix4F view, Ray3F rayL, Ray3F rayV) { float s = Util.CalcAxisScale(vc.Camera, world.Translation, Manipulator.AxisLength, vc.Height); m_hitRegion = HitRegion.None; m_hitRayV = rayV; m_hitMatrix.Set(world); m_hitWorldView = world * view; float sl = s * SquareLength; // test xy square. Vec3F p1 = new Vec3F(0, 0, 0); Vec3F p2 = new Vec3F(sl, 0, 0); Vec3F p3 = new Vec3F(sl, sl, 0); Vec3F p4 = new Vec3F(0, sl, 0); Plane3F plane = new Plane3F(p1, p2, p3); Vec3F p; if (rayL.IntersectPlane(plane, out p)) { // test point in 2d rectangle. if (p.X > p1.X && p.X < p2.X && p.Y > p1.Y && p.Y < p4.Y) { m_hitRegion = HitRegion.XYSquare; return(m_hitRegion); } } // test xz square p1 = new Vec3F(0, 0, 0); p2 = new Vec3F(sl, 0, 0); p3 = new Vec3F(sl, 0, sl); p4 = new Vec3F(0, 0, sl); plane = new Plane3F(p1, p2, p3); if (rayL.IntersectPlane(plane, out p)) { // test point in 2d rectangle. if (p.X > p1.X && p.X < p2.X && p.Z > p1.Z && p.Z < p4.Z) { m_hitRegion = HitRegion.XZSquare; return(m_hitRegion); } } // test yz square p1 = new Vec3F(0, 0, 0); p2 = new Vec3F(0, 0, sl); p3 = new Vec3F(0, sl, sl); p4 = new Vec3F(0, sl, 0); plane = new Plane3F(p1, p2, p3); if (rayL.IntersectPlane(plane, out p)) { // test point in 2d rectangle. if (p.Z > p1.Z && p.Z < p2.Z && p.Y > p1.Z && p.Y < p4.Y) { m_hitRegion = HitRegion.YZSquare; return(m_hitRegion); } } Vec3F min = new Vec3F(-0.5f, -0.5f, -0.5f); Vec3F max = new Vec3F(0.5f, 0.5f, 0.5f); AABB box = new AABB(min, max); Matrix4F boxScale = new Matrix4F(); Matrix4F boxTrans = new Matrix4F(); Matrix4F BoxMtrx = new Matrix4F(); // X axis boxScale.Scale(new Vec3F(s, s * ConeDiameter, s * ConeDiameter)); boxTrans.Translation = new Vec3F(s / 2, 0, 0); BoxMtrx = boxScale * boxTrans; Ray3F ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.XAxis; return(m_hitRegion); } // y axis boxScale.Scale(new Vec3F(s * ConeDiameter, s, s * ConeDiameter)); boxTrans.Translation = new Vec3F(0, s / 2, 0); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.YAxis; return(m_hitRegion); } // z axis boxScale.Scale(new Vec3F(s * ConeDiameter, s * ConeDiameter, s)); boxTrans.Translation = new Vec3F(0, 0, s / 2); BoxMtrx = boxScale * boxTrans; ray = rayL; BoxMtrx.Invert(BoxMtrx); ray.Transform(BoxMtrx); if (box.Intersect(ray)) { m_hitRegion = HitRegion.ZAxis; } return(m_hitRegion); }
/// <summary> /// Dispatches untyped items. Replaces DispatchNotTyped(). To get the same behavior as /// the old DispatchNotTyped(), set the TypeFilter property to null prior to calling.</summary> /// <param name="traverseList">The traverse list</param> /// <param name="camera">The camera</param> protected void DispatchTraverseList(ICollection <TraverseNode> traverseList, Camera camera) { // Prepare for geometric picking -- create the ray in world space and reset geometric hit-list. // First create the ray in viewing coordinates and transform to world coordinates. float nx = (m_x / (float)m_width) - 0.5f; //normalized x float ny = 0.5f - (m_y / (float)m_height); //normalized y Ray3F rayWorld = camera.CreateRay(nx, ny); Matrix4F worldToView = camera.ViewMatrix; Matrix4F viewToWorld = new Matrix4F(); viewToWorld.Invert(worldToView); rayWorld.Transform(viewToWorld); ClearHitList(); // for geometric picking. will be cleared for each HitRecord. List <uint> userData = new List <uint>(1); // Dispatch traverse list int index = 0; foreach (TraverseNode node in traverseList) { // First test for filtering. IRenderObject renderObject = node.RenderObject; if (FilterByType(renderObject)) { IIntersectable intersectable = renderObject.GetIntersectable(); IGeometricPick geometricPick = intersectable as IGeometricPick; if (geometricPick != null) { // Picking by geometry. Matrix4F objToWorld = new Matrix4F(node.Transform); Matrix4F worldToObj = new Matrix4F(); worldToObj.Invert(objToWorld); Matrix4F viewToObj = Matrix4F.Multiply(viewToWorld, worldToObj); if (m_frustumPick) { //The pick frustum is in view space. Transform to world space then object space. Frustum frustumObj = new Frustum(m_viewFrust0); frustumObj.Transform(viewToObj); //Multi-pick. Get everything in the pick frustum (m_viewFrust0). Vec3F eyeObj; worldToObj.Transform(camera.Eye, out eyeObj); userData.Clear(); if (geometricPick.IntersectFrustum(frustumObj, eyeObj, node.RenderState, userData)) { // Prepare a multi-pick HitRecord, as if OpenGL had calculated this. HitRecord hit = new HitRecord( node.GraphPath, renderObject, objToWorld, userData.ToArray()); m_geoHitList.Add(hit); } } else { //Single pick. We care about distance from camera eye. //Make a copy of the ray in world-space and tranform it to object space. Ray3F rayObj = rayWorld; //remember, Ray3F is a value type, not a reference type. rayObj.Transform(worldToObj); // Do the intersection test in object space. userData.Clear(); Vec3F intersectionPt, surfaceNormal; Vec3F nearestVert; bool intersected; intersected = geometricPick.IntersectRay( rayObj, camera, node.RenderState, objToWorld, this, out intersectionPt, out nearestVert, out surfaceNormal, userData); if (intersected) { // Transform to world space and then to screen space. objToWorld.Transform(intersectionPt, out intersectionPt); objToWorld.Transform(nearestVert, out nearestVert); // Prepare a single-pick HitRecord, as if OpenGL had calculated this. HitRecord hit = new HitRecord( node.GraphPath, renderObject, objToWorld, userData.ToArray()); // This is the one difference from OpenGL pick. We have the world pt already. hit.WorldIntersection = intersectionPt; hit.NearestVert = nearestVert; // Another difference is that it's possible to get the surface normal. if (surfaceNormal != Vec3F.ZeroVector) { objToWorld.TransformNormal(surfaceNormal, out surfaceNormal); surfaceNormal.Normalize(); hit.Normal = surfaceNormal; } m_geoHitList.Add(hit); } } } else { // Picking by "rendering", using OpenGL pick. PushMatrix(node.Transform, false); Gl.glPushName(index); IRenderPick pickInterface = renderObject as IRenderPick; if (pickInterface != null) { pickInterface.PickDispatch(node.GraphPath, node.RenderState, this, camera); } else { renderObject.Dispatch(node.GraphPath, node.RenderState, this, camera); } Gl.glPopName(); PopMatrix(); } } index++; } }