예제 #1
0
        void IManipulator.Render(ViewControl vc)
        {
            TerrainGob   terrain    = m_terrainEditor.TerrainEditorControl.SelectedTerrain;
            TerrainBrush brush      = m_terrainEditor.TerrainEditorControl.SelectedBrush;
            TerrainMap   terrainMap = m_terrainEditor.TerrainEditorControl.SelectedTerrainMap;

            if (brush == null || (!brush.CanApplyTo(terrain) && !brush.CanApplyTo(terrainMap)))
            {
                return;
            }

            Vec2F drawscale = new Vec2F(1.0f, 1.0f);

            if (brush.CanApplyTo(terrainMap))
            {
                ImageData mapImg = terrainMap.GetSurface();
                ImageData hmImg  = terrain.GetSurface();
                drawscale.X = (float)hmImg.Width / (float)mapImg.Width;
                drawscale.Y = (float)hmImg.Height / (float)mapImg.Height;
            }

            Point scrPt = vc.PointToClient(Control.MousePosition);

            if (!vc.ClientRectangle.Contains(scrPt))
            {
                return;
            }
            Ray3F rayw = vc.GetWorldRay(scrPt);

            TerrainGob.RayPickRetVal retval;
            if (terrain.RayPick(rayw, out retval))
            {
                terrain.DrawBrush(brush, drawscale, retval.hitpos);
            }
        }
예제 #2
0
        private void ApplyBrush(ViewControl vc, System.Drawing.Point scrPt)
        {
            TerrainGob   terrain    = m_terrainEditor.TerrainEditorControl.SelectedTerrain;
            TerrainBrush brush      = m_terrainEditor.TerrainEditorControl.SelectedBrush;
            TerrainMap   terrainMap = m_terrainEditor.TerrainEditorControl.SelectedTerrainMap;

            if (brush == null || (!brush.CanApplyTo(terrain) && !brush.CanApplyTo(terrainMap)))
            {
                return;
            }

            Ray3F rayw = vc.GetWorldRay(scrPt);

            TerrainGob.RayPickRetVal retval;
            if (terrain.RayPick(rayw, out retval))
            {
                TerrainOp op = null;
                if (brush.CanApplyTo(terrain))
                {
                    Point pt = terrain.WorldToSurfaceSpace(retval.hitpos);
                    brush.Apply(terrain, pt.X, pt.Y, out op);
                }
                else if (brush.CanApplyTo(terrainMap))
                {
                    Point pt = terrainMap.WorldToSurfaceSpace(retval.hitpos);
                    brush.Apply(terrainMap, pt.X, pt.Y, out op);
                }
                m_tmpOps.Add(op);
                m_terrainOpList.Add(new WeakReference(op));
                m_memUsage += op.SizeInBytes;
            }
        }
예제 #3
0
        public bool Pick(ViewControl vc, Point scrPt)
        {
            m_highlightMaterialGUID = ~0ul;
            m_highlight.Clear();

            var ray   = vc.GetWorldRay(scrPt);
            var endPt = ray.Origin + vc.Camera.FarZ * ray.Direction;

            var nativeVC = vc as GUILayer.IViewContext;

            if (nativeVC == null)
            {
                return(false);
            }

            // do an intersection test here, and find the material under the cursor
            var pick = XLEBridgeUtils.Picking.RayPick(
                nativeVC, ray, XLEBridgeUtils.Picking.Flags.Objects);

            if (pick != null && pick.Length > 0)
            {
                m_highlightMaterialGUID = pick[0].materialGuid;
                m_highlight.Add(pick[0].documentId, pick[0].instanceId);

                using (var placements = nativeVC.SceneManager.GetPlacementsEditor())
                {
                    m_highlight.DoFixup(placements);
                }
            }

            return(true);
        }
예제 #4
0
        public override bool MouseDown(object sender, MouseEventArgs e)
        {
            if (InputScheme.ActiveControlScheme.IsControllingCamera(KeysInterop.ToAtf(Control.ModifierKeys), MouseEventArgsInterop.ToAtf(e)))
            {
                m_lastMousePointX = e.Location.X;
                m_lastMousePointY = e.Location.Y;
                m_dragging        = true;
                return(true);
            }

            if (Control.ModifierKeys.HasFlag(Keys.Control) && !Control.ModifierKeys.HasFlag(Keys.Shift) && e.Button == MouseButtons.Left)
            {
                // "control + l click" repositions the "focus" point of the camera
                //      -- it's just incredibly useful to be able to manually set the point, because it
                //          allows the user to specify both the speed of the movement of the camera and
                //          the orbit of the camera in a natural way
                //
                // We could expand "ActiveControlScheme" to allow this key binding to be rebound...
                // but just using fixed binding for now.
                // This is a very important key combination (it's just really useful to be able to move
                // the focus around quickly) -- so it should be accessable with any easy combination from
                // anywhere!

                ViewControl           c  = sender as ViewControl;
                GUILayer.IViewContext vc = sender as GUILayer.IViewContext;
                if (c != null && vc != null)
                {
                    // We can use XLEBridgeUtils to do the ray test. This will
                    // execute the native code (which in turn performs the intersection
                    // on the GPU)
                    // Note that we're using the more complex picking interface because
                    // we want to use explicitly pass "Camera" (rather than
                    // getting it from the view control)
                    var hit = XLEBridgeUtils.Picking.RayPick(
                        GUILayer.EngineDevice.GetInstance(),
                        vc.SceneManager, vc.TechniqueContext,
                        c.GetWorldRay(e.Location), XLEBridgeUtils.Utils.AsCameraDesc(Camera), c.ClientSize,
                        XLEBridgeUtils.Picking.Flags.AllWorldObjects);
                    if (hit != null && hit.Length > 0)
                    {
                        Vec3F transformedPt;
                        Camera.AxisSystem.Transform(hit[0].hitPt, out transformedPt);
                        Camera.Set(Camera.Eye, transformedPt, Camera.Up);
                    }
                }

                return(true);
            }

            return(base.MouseDown(sender, e));
        }
예제 #5
0
        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;
                        }
                    }
                }
            }
        }
예제 #6
0
        private bool HitTest(out Vec3F result, Point pt, ViewControl vc)
        {
            var ray  = vc.GetWorldRay(pt);
            var pick = XLEBridgeUtils.Picking.RayPick(
                vc as GUILayer.IViewContext, ray, XLEBridgeUtils.Picking.Flags.Terrain);

            if (pick != null && pick.Length > 0)
            {
                result = pick[0].hitPt;
                return(true);
            }

            result = new Vec3F(0.0f, 0.0f, 0.0f);
            return(false);
        }
예제 #7
0
        public void OnEndDrag(ViewControl vc, Point scrPt)
        {
            var ray   = vc.GetWorldRay(scrPt);
            var endPt = ray.Origin + vc.Camera.FarZ * ray.Direction;

            // do an intersection test here, and find the material under the cursor
            var pick = XLEBridgeUtils.Picking.RayPick(
                vc as GUILayer.IViewContext, ray, XLEBridgeUtils.Picking.Flags.Objects);

            if (pick != null && pick.Length > 0)
            {
                Context.PreviewModelName    = pick[0].modelName;
                Context.PreviewModelBinding = pick[0].materialGuid;
                Context.MaterialName        = pick[0].materialName;
            }

            m_highlightMaterialGUID = ~0ul;
            m_highlight.Clear();
        }
예제 #8
0
        bool IManipulator.Pick(ViewControl vc, System.Drawing.Point scrPt)
        {
            TerrainGob   terrain = m_terrainEditor.TerrainEditorControl.SelectedTerrain;
            TerrainBrush brush   = m_terrainEditor.TerrainEditorControl.SelectedBrush;

            if (terrain != null && brush != null)
            {
                FlattenBrush fbrush = brush as FlattenBrush;
                if (fbrush != null)
                {
                    Ray3F rayw = vc.GetWorldRay(scrPt);
                    TerrainGob.RayPickRetVal retval;
                    if (terrain.RayPick(rayw, out retval))
                    {
                        Point     pt = terrain.WorldToSurfaceSpace(retval.hitpos);
                        ImageData hm = terrain.GetSurface();
                        fbrush.Height = hm.GetPixelFloat(pt.X, pt.Y);
                    }
                }
                return(true);
            }
            return(false);
        }
        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();
                        }
                    }
                }
            }
        }