public override void OnDragging(ViewControl vc, Point scrPt) { if (m_cancelDrag || m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0) { return; } var nativeVC = vc as NativeDesignControl; if (nativeVC == null) { return; } bool hitAxis = m_hitRegion == HitRegion.XAxis || m_hitRegion == HitRegion.YAxis || m_hitRegion == HitRegion.ZAxis; Matrix4F proj = vc.Camera.ProjectionMatrix; // create ray in view space. Ray3F rayV = vc.GetRay(scrPt, proj); Vec3F translate = m_translatorControl.OnDragging(rayV); ISnapSettings snapSettings = (ISnapSettings)DesignView; bool snapToGeom = Control.ModifierKeys == m_snapGeometryKey; if (snapToGeom) { Matrix4F view = vc.Camera.ViewMatrix; Matrix4F vp = view * proj; // create ray in world space. Ray3F rayW = vc.GetRay(scrPt, vp); Vec3F manipPos = HitMatrix.Translation; Vec3F manipMove; if (hitAxis) { //Make rayw to point toward moving axis and starting // from manipulator’s world position. rayW.Direction = Vec3F.Normalize(translate); rayW.Origin = manipPos; manipMove = Vec3F.ZeroVector; m_cancelDrag = true; //stop further snap-to's } else { manipMove = rayW.ProjectPoint(manipPos) - manipPos; } for (int i = 0; i < m_activeOp.NodeList.Count; i++) { ITransformable node = m_activeOp.NodeList[i]; Vec3F snapOffset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); Path <DomNode> path = new Path <DomNode>(Adapters.Cast <DomNode>(node).GetPath()); Matrix4F parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2); Vec3F orgPosW; parentLocalToWorld.Transform(m_originalValues[i], out orgPosW); Matrix4F parentWorldToLocal = new Matrix4F(); parentWorldToLocal.Invert(parentLocalToWorld); rayW.MoveToIncludePoint(orgPosW + snapOffset + manipMove); var hits = XLEBridgeUtils.Picking.RayPick( nativeVC.Adapter, rayW, XLEBridgeUtils.Picking.Flags.Terrain | XLEBridgeUtils.Picking.Flags.Objects | XLEBridgeUtils.Picking.Flags.IgnoreSelection); bool cansnap = false; var target = new XLEBridgeUtils.Picking.HitRecord(); if (hits != null && hits.Length > 0) { // find hit record. foreach (var hit in hits) { if (m_snapFilter.CanSnapTo(node, m_nativeIdMapping.GetAdapter(hit.documentId, hit.instanceId))) { target = hit; cansnap = true; break; } } } if (cansnap) { Vec3F pos; if (target.hasNearestVert && snapSettings.SnapVertex) { pos = target.nearestVertex; } else { pos = target.hitPt; } pos -= snapOffset; parentWorldToLocal.Transform(ref pos); Vec3F diff = pos - node.Transform.Translation; node.Translation += diff; bool rotateOnSnap = snapSettings.RotateOnSnap && target.hasNormal && (node.TransformationType & TransformationTypes.Rotation) != 0; if (rotateOnSnap) { Vec3F localSurfaceNormal; parentWorldToLocal.TransformNormal(target.normal, out localSurfaceNormal); node.Rotation = TransformUtils.RotateToVector( m_originalRotations[i], localSurfaceNormal, AxisSystemType.YIsUp); } } } } else { IGrid grid = DesignView.Context.Cast <IGame>().Grid; bool snapToGrid = Control.ModifierKeys == m_snapGridKey && grid.Visible && vc.Camera.ViewType == ViewTypes.Perspective; float gridHeight = grid.Height; // translate. for (int i = 0; i < m_activeOp.NodeList.Count; i++) { ITransformable node = m_activeOp.NodeList[i]; Path <DomNode> path = new Path <DomNode>(Adapters.Cast <DomNode>(node).GetPath()); Matrix4F parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2); Matrix4F parentWorldToLocal = new Matrix4F(); parentWorldToLocal.Invert(parentLocalToWorld); Vec3F localTranslation; parentWorldToLocal.TransformVector(translate, out localTranslation); Vec3F trans = m_originalValues[i] + localTranslation; if (snapToGrid) { if (grid.Snap) { trans = grid.SnapPoint(trans); } else { trans.Y = gridHeight; } } node.Translation = trans; } } }
protected override IList<object> Pick(MouseEventArgs e) { bool multiSelect = DragOverThreshold; List<object> paths = new List<object>(); XLEBridgeUtils.Picking.HitRecord[] hits; if(multiSelect) {// frustum pick RectangleF rect = MakeRect(FirstMousePoint, CurrentMousePoint); var frustum = XLEBridgeUtils.Utils.MakeFrustumMatrix(Camera, rect, ClientSize); hits = XLEBridgeUtils.Picking.FrustumPick( GameEngine.GetEngineDevice(), SceneManager, TechniqueContext, frustum, Camera, ClientSize, XLEBridgeUtils.Picking.Flags.Objects | XLEBridgeUtils.Picking.Flags.Helpers); } else {// ray pick Ray3F rayW = GetWorldRay(CurrentMousePoint); hits = XLEBridgeUtils.Picking.RayPick( GameEngine.GetEngineDevice(), SceneManager, TechniqueContext, rayW, Camera, ClientSize, XLEBridgeUtils.Picking.Flags.Terrain | XLEBridgeUtils.Picking.Flags.Objects | XLEBridgeUtils.Picking.Flags.Helpers); } if (hits==null) return new List<object>(); // create unique list of hits HashSet<ulong> instanceSet = new HashSet<ulong>(); var uniqueHits = new List<XLEBridgeUtils.Picking.HitRecord>(); // build 'path' objects for each hit record. foreach (var hit in hits) { bool added = instanceSet.Add(hit.instanceId); if (added) uniqueHits.Add(hit); } var firstHit = new XLEBridgeUtils.Picking.HitRecord(); // build 'path' objects for each hit record. foreach (var hit in uniqueHits) { var nativeIdMapping = Globals.MEFContainer.GetExportedValue<INativeIdMapping>(); var nobj = nativeIdMapping.GetAdapter(hit.documentId, hit.instanceId).As<DomNodeAdapter>(); if (nobj == null) continue; DomNode dom = nobj.DomNode; object hitPath = Util.AdaptDomPath(dom); object obj = DesignView.PickFilter.Filter(hitPath, e); if (obj != null) { if (paths.Count == 0) { firstHit = hit; } var newPath = obj as AdaptablePath<object> ?? Util.AdaptDomPath((DomNode)obj); paths.Add(newPath); } } if (multiSelect == false && paths.Count > 0) { var path = paths[0]; ISelectionContext selection = DesignView.Context.As<ISelectionContext>(); ILinear linear = path.As<ILinear>(); if (linear != null && Control.ModifierKeys == System.Windows.Forms.Keys.Shift && selection.SelectionContains(path)) { ITransactionContext trans = DesignView.Context.As<ITransactionContext>(); trans.DoTransaction( delegate { linear.InsertPoint(firstHit.index, firstHit.hitPt.X, firstHit.hitPt.Y, firstHit.hitPt.Z); }, "insert control point".Localize() ); } } return paths; }
public override void OnDragging(ViewControl vc, Point scrPt) { if (m_cancelDrag || m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0) return; bool hitAxis = m_hitRegion == HitRegion.XAxis || m_hitRegion == HitRegion.YAxis || m_hitRegion == HitRegion.ZAxis; Matrix4F proj = vc.Camera.ProjectionMatrix; // create ray in view space. Ray3F rayV = vc.GetRay(scrPt, proj); Vec3F translate = m_translatorControl.OnDragging(rayV); ISnapSettings snapSettings = (ISnapSettings)DesignView; bool snapToGeom = Control.ModifierKeys == m_snapGeometryKey; if (snapToGeom) { Matrix4F view = vc.Camera.ViewMatrix; Matrix4F vp = view * proj; // create ray in world space. Ray3F rayW = vc.GetRay(scrPt, vp); Vec3F manipPos = HitMatrix.Translation; Vec3F manipMove; if (hitAxis) { //Make rayw to point toward moving axis and starting // from manipulator’s world position. rayW.Direction = Vec3F.Normalize(translate); rayW.Origin = manipPos; manipMove = Vec3F.ZeroVector; m_cancelDrag = true; //stop further snap-to's } else { manipMove = rayW.ProjectPoint(manipPos) - manipPos; } for (int i = 0; i < m_activeOp.NodeList.Count; i++) { ITransformable node = m_activeOp.NodeList[i]; Vec3F snapOffset = TransformUtils.CalcSnapFromOffset(node, snapSettings.SnapFrom); Path<DomNode> path = new Path<DomNode>(Adapters.Cast<DomNode>(node).GetPath()); Matrix4F parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2); Vec3F orgPosW; parentLocalToWorld.Transform(m_originalValues[i], out orgPosW); Matrix4F parentWorldToLocal = new Matrix4F(); parentWorldToLocal.Invert(parentLocalToWorld); rayW.MoveToIncludePoint(orgPosW + snapOffset + manipMove); var hits = XLEBridgeUtils.Picking.RayPick( vc, rayW, XLEBridgeUtils.Picking.Flags.Terrain | XLEBridgeUtils.Picking.Flags.Objects | XLEBridgeUtils.Picking.Flags.IgnoreSelection); bool cansnap = false; var target = new XLEBridgeUtils.Picking.HitRecord(); if (hits != null && hits.Length > 0) { // find hit record. foreach (var hit in hits) { if (m_snapFilter.CanSnapTo(node, m_nativeIdMapping.GetAdapter(hit.documentId, hit.instanceId))) { target = hit; cansnap = true; break; } } } if (cansnap) { Vec3F pos; if (target.hasNearestVert && snapSettings.SnapVertex) { pos = target.nearestVertex; } else { pos = target.hitPt; } pos -= snapOffset; parentWorldToLocal.Transform(ref pos); Vec3F diff = pos - node.Transform.Translation; node.Translation += diff; bool rotateOnSnap = snapSettings.RotateOnSnap && target.hasNormal && (node.TransformationType & TransformationTypes.Rotation) != 0; if (rotateOnSnap) { Vec3F localSurfaceNormal; parentWorldToLocal.TransformNormal(target.normal, out localSurfaceNormal); node.Rotation = TransformUtils.RotateToVector( m_originalRotations[i], localSurfaceNormal, AxisSystemType.YIsUp); } } } } else { IGrid grid = DesignView.Context.Cast<IGame>().Grid; bool snapToGrid = Control.ModifierKeys == m_snapGridKey && grid.Visible && vc.Camera.ViewType == ViewTypes.Perspective; float gridHeight = grid.Height; // translate. for (int i = 0; i < m_activeOp.NodeList.Count; i++) { ITransformable node = m_activeOp.NodeList[i]; Path<DomNode> path = new Path<DomNode>(Adapters.Cast<DomNode>(node).GetPath()); Matrix4F parentLocalToWorld = TransformUtils.CalcPathTransform(path, path.Count - 2); Matrix4F parentWorldToLocal = new Matrix4F(); parentWorldToLocal.Invert(parentLocalToWorld); Vec3F localTranslation; parentWorldToLocal.TransformVector(translate, out localTranslation); Vec3F trans = m_originalValues[i] + localTranslation; if(snapToGrid) { if(grid.Snap) trans = grid.SnapPoint(trans); else trans.Y = gridHeight; } node.Translation = trans; } } }