void m_selectionContext_SelectionChanged(object sender, EventArgs e) { var domNodes = m_selectionContext.Selection.AsIEnumerable <DomNode>(); var roots = DomNode.GetRoots(domNodes); var sel = GameEngine.GlobalSelection; sel.Clear(); foreach (var node in roots) { if (node.Is <ITransformableGroup>()) { foreach (var adapter in node.Subtree.AsIEnumerable <NativeObjectAdapter>()) { sel.Add(adapter.DocumentId, adapter.InstanceId); } } else { var adapter = node.As <NativeObjectAdapter>(); if (adapter != null) { sel.Add(adapter.DocumentId, adapter.InstanceId); } } } using (var placements = GameEngine.GetEditorSceneManager().GetPlacementsEditor()) sel.DoFixup(placements); InvalidateViews(); }
public override void OnDragging(ViewControl vc, Point scrPt) { if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0) { return; } // create ray in view space. Ray3F rayV = vc.GetWorldRay(scrPt); using (var intersectionScene = GameEngine.GetEditorSceneManager().GetIntersectionScene()) { Vec3F intersectionPt; if (!CalculateTerrainIntersection(vc, rayV, intersectionScene, out intersectionPt)) { return; } if (m_pendingStartPt) { m_startPt = intersectionPt; m_pendingStartPt = false; } else { bool clampToSurface = Control.ModifierKeys == Keys.Shift; Vec3F translate = new Vec3F(intersectionPt.X - m_startPt.X, intersectionPt.Y - m_startPt.Y, 0.0f); 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 newWorldPos = m_originalTranslations[i] + translate; float terrainHeight = 0.0f; if (GUILayer.EditorInterfaceUtils.GetTerrainHeight( out terrainHeight, intersectionScene, newWorldPos.X, newWorldPos.Y)) { newWorldPos.Z = terrainHeight + (clampToSurface ? 0.0f : m_originalHeights[i]); Vec3F localTranslation; parentWorldToLocal.TransformVector(newWorldPos, out localTranslation); node.Translation = localTranslation; } } } } }
protected override void OnDragOver(DragEventArgs drgevent) { base.OnDragOver(drgevent); if (DesignView.Context == null || m_ghosts.Count == 0) { return; } // Just do an intersection against the terrain to // calculate basic insertion position Vec3F terrainHit; if (GetInsertionPosition(out terrainHit, PointToClient(new Point(drgevent.X, drgevent.Y)))) { ISnapSettings snapSettings = (ISnapSettings)DesignView; foreach (var ghost in m_ghosts) { var gameObject = ghost.As <ITransformable>(); if (gameObject != null) { gameObject.Translation = terrainHit; // When if terrain alignment mode, we need to query the terrain collision model // for a terrain normal associated with this point. The if (snapSettings.TerrainAlignment == TerrainAlignmentMode.TerrainUp) { using (var intersectionScene = GameEngine.GetEditorSceneManager().GetIntersectionScene()) { float terrainHeight; GUILayer.Vector3 terrainNormal; if (GUILayer.EditorInterfaceUtils.GetTerrainHeightAndNormal( out terrainHeight, out terrainNormal, intersectionScene, terrainHit.X, terrainHit.Y)) { gameObject.Rotation = TransformUtils.RotateToVector( gameObject.Rotation, new Vec3F(terrainNormal.X, terrainNormal.Y, terrainNormal.Z), Sce.Atf.Rendering.Dom.AxisSystemType.ZIsUp); } } } } } DesignView.InvalidateViews(); } }
void m_selectionContext_SelectionChanged(object sender, EventArgs e) { IEnumerable <DomNode> domNodes = m_selectionContext.Selection.AsIEnumerable <DomNode>(); IEnumerable <DomNode> roots = DomNode.GetRoots(domNodes); IEnumerable <NativeObjectAdapter> nativeObjects = roots.AsIEnumerable <NativeObjectAdapter>(); var sel = GameEngine.GlobalSelection; sel.Clear(); foreach (var adapter in nativeObjects) { sel.Add(adapter.DocumentId, adapter.InstanceId); } using (var placements = GameEngine.GetEditorSceneManager().GetPlacementsEditor()) sel.DoFixup(placements); InvalidateViews(); }
public override void OnBeginDrag() { if (m_hitRegion == HitRegion.None) { return; } Clear(); // cached values. var op = new ManipulatorActiveOperation( "Move Across Terrain", DesignView.Context.As <ISelectionContext>(), (ITransformable node) => (node.TransformationType & TransformationTypes.Translation) != 0, Control.ModifierKeys == m_duplicateKey); m_originalTranslations = new Vec3F[op.NodeList.Count]; m_originalHeights = new float[op.NodeList.Count]; using (var intersectionScene = GameEngine.GetEditorSceneManager().GetIntersectionScene()) { for (int k = 0; k < op.NodeList.Count; k++) { Path <DomNode> path = new Path <DomNode>(op.NodeList[k].Cast <DomNode>().GetPath()); Matrix4F localToWorld = TransformUtils.CalcPathTransform(path, path.Count - 1); m_originalTranslations[k] = localToWorld.Translation; float heightAboveTerrain = 0.0f; float terrainHeight = 0.0f; if (GUILayer.EditorInterfaceUtils.GetTerrainHeight( out terrainHeight, intersectionScene, m_originalTranslations[k].X, m_originalTranslations[k].Y)) { heightAboveTerrain = m_originalTranslations[k].Z - terrainHeight; } m_originalHeights[k] = heightAboveTerrain; } } m_pendingStartPt = true; m_activeOp = op; }
public NativeDesignControl(DesignView designView) : base(designView) { if (s_marqueePen == null) { s_marqueePen = new Pen(Color.FromArgb(30, 30, 30), 2); s_marqueePen.DashPattern = new float[] { 3, 3 }; } m_renderState = new RenderState(); m_renderState.RenderFlag = GlobalRenderFlags.Solid | GlobalRenderFlags.Textured | GlobalRenderFlags.Lit | GlobalRenderFlags.Shadows; m_renderState.WireFrameColor = Color.DarkBlue; m_renderState.SelectionColor = Color.FromArgb(66, 255, 161); BackColor = SystemColors.ControlDark; m_renderState.OnChanged += (sender, e) => Invalidate(); Adapter = new DesignControlAdapter( this, Camera, GameEngine.GetEditorSceneManager(), GameEngine.GlobalSelection, GameEngine.GetSavedResources()); Adapter.AddRenderCallback((GUILayer.SimpleRenderingContext context) => RenderManipulators(context, designView)); Adapter.AddRenderCallback((GUILayer.SimpleRenderingContext context) => RenderExtras(context, designView)); }
public override void OnDragging(ViewControl vc, Point scrPt) { if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0) { return; } // create ray in view space. Ray3F rayV = vc.GetWorldRay(scrPt); using (var intersectionScene = GameEngine.GetEditorSceneManager().GetIntersectionScene()) { PickResult intersectionPt; if (!CalculateTerrainIntersection(vc, rayV, intersectionScene, out intersectionPt)) { return; } if (m_pendingStartPt) { m_startPt = intersectionPt._pt.Value; m_pendingStartPt = false; } else { ISnapSettings snapSettings = (ISnapSettings)DesignView; bool clampToSurface = Control.ModifierKeys == Keys.Shift; var pt = intersectionPt._pt.Value; Vec3F translate = new Vec3F(pt.X - m_startPt.X, pt.Y - m_startPt.Y, 0.0f); 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 newWorldPos = m_originalTranslations[i] + translate; float terrainHeight = 0.0f; GUILayer.Vector3 terrainNormal; if (GUILayer.EditorInterfaceUtils.GetTerrainHeightAndNormal( out terrainHeight, out terrainNormal, intersectionScene, newWorldPos.X, newWorldPos.Y)) { newWorldPos.Z = terrainHeight + (clampToSurface ? 0.0f : m_originalHeights[i]); Vec3F localTranslation; parentWorldToLocal.TransformVector(newWorldPos, out localTranslation); node.Translation = localTranslation; // There are two ways to orient the "up" vector of the object. // One way is to decompose the 3x3 rotation matrix into a up vector + a rotation around // that vector. Then we retain the rotation, and just move the up vector. // Another way is to take the 3x3 matrix, and adjust it's up vector. Then just perform // the Gram–Schmidt algorithm to re-orthogonalize it. // We'll use the code from the SCEE level editor. This isn't the ideal math (there's a // lot of room for floating point creep) but it should work. var currentUp = node.Transform.ZAxis; if (snapSettings.TerrainAlignment == TerrainAlignmentMode.TerrainUp) { node.Rotation = TransformUtils.RotateToVector( node.Rotation, new Vec3F(terrainNormal.X, terrainNormal.Y, terrainNormal.Z), AxisSystemType.ZIsUp); } else if (snapSettings.TerrainAlignment == TerrainAlignmentMode.WorldUp) { // Prevent the change if the normal is already very close to straight up if (Math.Abs(currentUp.X - 0.0f) > 1e-4f || Math.Abs(currentUp.Y - 0.0f) > 1e-4f || Math.Abs(currentUp.Z - 1.0f) > 1e-4f) { node.Rotation = TransformUtils.RotateToVector( node.Rotation, new Vec3F(0.0f, 0.0f, 1.0f), AxisSystemType.ZIsUp); } } node.UpdateTransform(); } } } } }