Example #1
0
        public override bool Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == false)
            {
                return(false);
            }

            m_node = GetManipulatorNode(TransformationTypes.Pivot);

            Camera camera = vc.Camera;
            float  s;

            Util.CalcAxisLengths(camera, HitMatrix.Translation, out s);
            Matrix4F view = camera.ViewMatrix;
            Matrix4F vp   = view * camera.ProjectionMatrix;
            Matrix4F wvp  = HitMatrix * vp;

            Ray3F rayL = vc.GetRay(scrPt, wvp);

            m_hitRegion = m_translatorControl.Pick(HitMatrix, view, rayL, HitRayV, s);
            bool picked = m_hitRegion != HitRegion.None;

            return(picked);
        }
Example #2
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);
            }
        }
Example #3
0
        /// <summary>
        /// Creates a ray originating at the given normalized window coordinates and pointing into
        /// the screen, along -Z axis. Normalized window coordinates are in the range [-0.5,0.5]
        /// with +x pointing to the right and +y pointing up.</summary>
        /// <param name="x">The x normalized window coordinate</param>
        /// <param name="y">The y normalized window coordinate</param>
        /// <returns>The ray</returns>
        public Ray3F CreateRay(float x, float y)
        {
            float height, width;

            // Setup ray
            Ray3F ray = new Ray3F();

            // World height on origin's z value
            if (Frustum.IsOrtho)
            {
                width         = Frustum.Right - Frustum.Left;
                height        = Frustum.Top - Frustum.Bottom;
                ray.Origin    = new Vec3F(x * width, y * height, -NearZ);
                ray.Direction = new Vec3F(0, 0, -1);
            }
            else
            {
                height = Frustum.Far * (float)Math.Tan(Frustum.FovY / 2.0f) * 2.0f;
                width  = Frustum.Far * (float)Math.Tan(Frustum.FovX / 2.0f) * 2.0f;

                ray.Origin    = new Vec3F(0, 0, 0);
                ray.Direction = new Vec3F(x * width, y * height, -Frustum.Far);
                float l = ray.Direction.Length;
                ray.Direction = ray.Direction / l;
            }

            return(ray);
        }
Example #4
0
        public override ManipulatorPickResult Pick(ViewControl vc, Point scrPt)
        {
            m_hitRegion = HitRegion.None;
            if (base.Pick(vc, scrPt) == ManipulatorPickResult.Miss)
            {
                return(ManipulatorPickResult.Miss);
            }

            m_node = GetManipulatorNode(TransformationTypes.Pivot);

            Camera   camera = vc.Camera;
            Matrix4F view   = camera.ViewMatrix;
            Matrix4F vp     = view * camera.ProjectionMatrix;
            Matrix4F wvp    = HitMatrix * vp;

            Ray3F rayL = vc.GetRay(scrPt, wvp);

            m_hitRegion = m_translatorControl.Pick(vc, HitMatrix, view, rayL, HitRayV);
            bool picked = m_hitRegion != HitRegion.None;

            if (picked)
            {
                return(ManipulatorPickResult.DeferredBeginDrag);
            }
            return(ManipulatorPickResult.Miss);
        }
Example #5
0
        public static bool RayPick(Matrix4F viewxform, Matrix4F projxfrom, Ray3F rayW, bool skipSelected, out HitRecord hit)
        {
            HitRecord *nativeHits = null;
            int        count;

            //bool skipSelected,
            fixed(float *ptr1 = &viewxform.M11, ptr2 = &projxfrom.M11)
            {
                NativeRayPick(
                    ptr1,
                    ptr2,
                    &rayW,
                    skipSelected,
                    &nativeHits,
                    out count);
            }

            if (count > 0)
            {
                hit = *nativeHits;
            }
            else
            {
                hit = new HitRecord();
            }

            return(count > 0);
        }
Example #6
0
        public static HitRecord[] RayPick(Matrix4F viewxform, Matrix4F projxfrom, Ray3F rayW, bool skipSelected)
        {
            HitRecord *nativeHits = null;
            int        count;

            fixed(float *ptr1 = &viewxform.M11, ptr2 = &projxfrom.M11)
            {
                NativeRayPick(
                    ptr1,
                    ptr2,
                    &rayW,
                    skipSelected,
                    &nativeHits,
                    out count);
            }

            var objects = new List <HitRecord>();

            for (int k = 0; k < count; k++)
            {
                objects.Add(*nativeHits);
                nativeHits++;
            }
            return(objects.ToArray());
        }
Example #7
0
        private void TestToStringWithCulture(CultureInfo culture)
        {
            CultureInfo originalCulture = Thread.CurrentThread.CurrentCulture;

            Thread.CurrentThread.CurrentCulture = culture;
            try
            {
                string listSeparator    = culture.TextInfo.ListSeparator;
                string decimalSeparator = culture.NumberFormat.NumberDecimalSeparator;
                var    o = new Ray3F(new Vec3F(1.1f, 2.2f, 3.3f), new Vec3F(4.4f, 5.5f, 6.6f));

                string s = o.ToString(null, null);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                string s2 = o.ToString();
                Assert.AreEqual(s, s2);

                s = o.ToString("G", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);

                s = o.ToString("R", culture);
                TestToStringResults(o, s, listSeparator, decimalSeparator);
            }
            finally
            {
                Thread.CurrentThread.CurrentCulture = originalCulture;
            }
        }
Example #8
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;
            }
        }
Example #9
0
        /// <summary>
        /// Projects the specified x and y, in normalized window coordinates, onto the grid,
        /// and snaps it to the nearest grid vertex if necessary.
        /// Normalized window coordinates are in the range [-0.5,0.5] with +x pointing to the
        /// right and +y pointing up.</summary>
        /// <param name="x">Window x in normalized window coords</param>
        /// <param name="y">Window y in normalized window coords</param>
        /// <param name="camera">Camera</param>
        /// <returns>Projection of x and y onto the grid, in world space.</returns>
        public Vec3F Project(float x, float y, Camera camera)
        {
            Ray3F ray = camera.CreateRay(x, y);

            Matrix4F V = new Matrix4F(camera.ViewMatrix);
            V.Mul(m_invAxisSystem, V);

            if (camera.Frustum.IsOrtho)
            {
                V = new Matrix4F(m_V);
                V.Translation = camera.ViewMatrix.Translation;
            }

            // origin
            Vec3F delta = new Vec3F(0, Height, 0);
            V.Transform(delta, out delta);
            Vec3F o = delta;

            // Up vec
            Vec3F axis = V.YAxis;
            Vec3F projPt = ray.IntersectPlane(axis, -Vec3F.Dot(o, axis));

            // Transform back into world space
            Matrix4F Inv = new Matrix4F();
            Inv.Invert(camera.ViewMatrix);
            Inv.Transform(projPt, out projPt);

            if (Snap)
            {
                projPt = SnapPoint(projPt);
            }
            return projPt;
        }
Example #10
0
        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  rad;

            Util.CalcAxisLengths(camera, HitMatrix.Translation, out rad);
            float tolerance = rad / 10.0f;

            // compute ray in object space  space.
            Matrix4F vp   = camera.ViewMatrix * camera.ProjectionMatrix;
            Matrix4F wvp  = HitMatrix * vp;
            Ray3F    rayL = vc.GetRay(scrPt, wvp);

            Plane3F xplane = new Plane3F(Vec3F.XAxis, Vec3F.ZeroVector);
            Plane3F yplane = new Plane3F(Vec3F.YAxis, Vec3F.ZeroVector);
            Plane3F zplane = new Plane3F(Vec3F.ZAxis, Vec3F.ZeroVector);

            Vec3F pt;
            float xdelta = float.MaxValue;
            float ydelta = float.MaxValue;
            float zdelta = float.MaxValue;

            if (rayL.IntersectPlane(xplane, out pt))
            {
                xdelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(yplane, out pt))
            {
                ydelta = Math.Abs(pt.Length - rad);
            }

            if (rayL.IntersectPlane(zplane, out pt))
            {
                zdelta = Math.Abs(pt.Length - rad);
            }

            if (xdelta < tolerance && xdelta < ydelta && xdelta < zdelta)
            {
                m_hitRegion = HitRegion.XAxis;
            }
            else if (ydelta < tolerance && ydelta < zdelta)
            {
                m_hitRegion = HitRegion.YAxis;
            }
            else if (zdelta < tolerance)
            {
                m_hitRegion = HitRegion.ZAxis;
            }

            return(m_hitRegion != HitRegion.None);
        }
Example #11
0
        protected override void OnDragOver(DragEventArgs drgevent)
        {
            base.OnDragOver(drgevent);
            if (DesignView.Context == null ||
                m_ghosts.Count == 0)
            {
                return;
            }


            Point clientPoint = PointToClient(new Point(drgevent.X, drgevent.Y));
            Ray3F rayw        = GetWorldRay(clientPoint);

            bool shiftPressed = Control.ModifierKeys == Keys.Shift;

            DomNode   hitnode = null;
            HitRecord?hit     = null;

            if (shiftPressed)
            {
                Matrix4F    v    = Camera.ViewMatrix;
                Matrix4F    p    = Camera.ProjectionMatrix;
                HitRecord[] hits = GameEngine.RayPick(v, p, rayw, false);
                foreach (HitRecord ht in hits)
                {
                    hitnode = GameEngine.GetAdapterFromId(ht.instanceId).Cast <DomNode>();

                    bool skip = false;
                    // ignore ghosts
                    foreach (DomNode node in m_ghosts)
                    {
                        if (hitnode == node || hitnode.IsDescendantOf(node))
                        {
                            skip = true;
                            break;
                        }
                    }
                    if (skip)
                    {
                        continue;
                    }
                    hit = ht;
                    break;
                }
            }

            ISnapFilter snapFilter = Globals.MEFContainer.GetExportedValue <ISnapFilter>();
            bool        snap       = (shiftPressed && hit.HasValue);

            foreach (DomNode ghost in m_ghosts)
            {
                HitRecord?hr = (snap && (snapFilter == null || snapFilter.CanSnapTo(ghost, hitnode))) ? hit : null;
                ProjectGhost(ghost, rayw, hr);
            }

            GameLoop.Update();
            GameLoop.Render();
        }
        public static Ray3F GetRay(this Point scrPt, Matrix4F mtrx, Size controlSize)
        {
            Vec3F min = Unproject(new Vec3F(scrPt.X, scrPt.Y, 0), mtrx, controlSize);
            Vec3F max = Unproject(new Vec3F(scrPt.X, scrPt.Y, 1), mtrx, controlSize);
            Vec3F dir = Vec3F.Normalize(max - min);
            Ray3F ray = new Ray3F(min, dir);

            return(ray);
        }
Example #13
0
        /// <summary>
        /// compute ray in  given space starting from
        /// screen space x,y.
        /// The space of the computed ray depends on the value of mtrx:
        ///               world * view * projection // ray in local space (object space).
        ///               view * projection  // ray in world space.
        ///               projection   // ray in view space.
        /// </summary>
        public Ray3F GetRay(Point scrPt, Matrix4F mtrx)
        {
            Vec3F min = Unproject(new Vec3F(scrPt.X, scrPt.Y, 0), mtrx);
            Vec3F max = Unproject(new Vec3F(scrPt.X, scrPt.Y, 1), mtrx);
            Vec3F dir = Vec3F.Normalize(max - min);
            Ray3F ray = new Ray3F(min, dir);

            return(ray);
        }
Example #14
0
        public bool Intersect(Ray3F r)
        {
            float tmin;
            float tmax;
            Vec3F pos;
            Vec3F norm;
            bool  result = Intersect(r, out tmin, out tmax, out pos, out norm);

            return(result);
        }
Example #15
0
        /// <summary>
        /// compute ray in world space starting from
        /// screen space x,y.
        /// </summary>
        public Ray3F GetWorldRay(Point scrPt)
        {
            Matrix4F vp  = Camera.ViewMatrix * Camera.ProjectionMatrix;
            Vec3F    min = Unproject(new Vec3F(scrPt.X, scrPt.Y, 0), vp);
            Vec3F    max = Unproject(new Vec3F(scrPt.X, scrPt.Y, 1), vp);
            Vec3F    dir = Vec3F.Normalize(max - min);
            Ray3F    ray = new Ray3F(min, dir);

            return(ray);
        }
        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;
                        }
                    }
                }
            }
        }
Example #17
0
 private void TestToStringResults(Ray3F o, string s, string listSeparator, string decimalSeparator)
 {
     string[] results = s.Split(new[] { listSeparator }, StringSplitOptions.RemoveEmptyEntries);
     Assert.AreEqual(results.Length, 6);
     foreach (string oneFloatString in results)
     {
         Assert.True(oneFloatString.Contains(decimalSeparator));
     }
     Assert.AreEqual(float.Parse(results[0]), o.Origin.X);
     Assert.AreEqual(float.Parse(results[1]), o.Origin.Y);
     Assert.AreEqual(float.Parse(results[2]), o.Origin.Z);
     Assert.AreEqual(float.Parse(results[3]), o.Direction.X);
     Assert.AreEqual(float.Parse(results[4]), o.Direction.Y);
     Assert.AreEqual(float.Parse(results[5]), o.Direction.Z);
 }
Example #18
0
        private static float CalcAngle(Vec3F origin, Plane3F plane, Ray3F ray0, Ray3F ray1, float snapAngle)
        {
            float theta = 0;
            Vec3F p0;
            Vec3F p1;

            if (ray0.IntersectPlane(plane, out p0) &&
                ray1.IntersectPlane(plane, out p1))
            {
                Vec3F v0 = Vec3F.Normalize(p0 - origin);
                Vec3F v1 = Vec3F.Normalize(p1 - origin);
                theta = CalcAngle(v0, v1, plane.Normal, snapAngle);
            }
            return(theta);
        }
Example #19
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || !CanManipulate(m_node))
            {
                return;
            }

            Matrix4F proj = vc.Camera.ProjectionMatrix;
            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt, proj);

            Vec3F translate = m_translatorControl.OnDragging(rayV);

            Vec3F localTranslation;

            m_worldToLocal.TransformVector(translate, out localTranslation);
            m_node.Pivot = m_originalPivot + localTranslation;
        }
Example #20
0
        public bool RayPick(Ray3F rayw, out RayPickRetVal retval)
        {
            INativeObject nobj      = this.As <INativeObject>();
            IntPtr        retvalPtr = IntPtr.Zero;
            IntPtr        rayptr    = new IntPtr(&rayw);

            nobj.InvokeFunction("RayPick", rayptr, out retvalPtr);
            if (retvalPtr != IntPtr.Zero)
            {
                retval = *(RayPickRetVal *)retvalPtr;
            }
            else
            {
                retval = new RayPickRetVal();
            }

            return(retval.picked);
        }
        private bool CalculateTerrainIntersection(ViewControl vc, Ray3F ray, GUILayer.IntersectionTestSceneWrapper testScene, out Vec3F result)
        {
            var nativeVC = vc as NativeDesignControl;

            if (nativeVC == null)
            {
                result = Vec3F.ZeroVector; return(false);
            }

            var pick = XLEBridgeUtils.Picking.RayPick(nativeVC.Adapter, ray, XLEBridgeUtils.Picking.Flags.Terrain);

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

            result = Vec3F.ZeroVector;
            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;

            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);
        }
Example #23
0
        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);

            m_hitRegion = m_translatorControl.Pick(vc, HitMatrix, view, rayL, HitRayV);

            bool picked = m_hitRegion != HitRegion.None;

            return(picked);
        }
Example #24
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);
        }
Example #25
0
        protected override IList <object> Pick(MouseEventArgs e)
        {
            bool          multiSelect = DragOverThreshold;
            List <object> paths       = new List <object>();

            Picking.HitRecord[] hits;

            if (multiSelect)
            {// frustum pick
                RectangleF rect    = MakeRect(FirstMousePoint, CurrentMousePoint);
                var        frustum = XLEBridgeUtils.Utils.MakeFrustumMatrix(Utils.AsCameraDesc(Camera), rect, ClientSize);
                hits = Picking.FrustumPick(
                    GameEngine.GetEngineDevice(),
                    Adapter.SceneManager, Adapter.TechniqueContext,
                    frustum, Utils.AsCameraDesc(Camera), ClientSize,
                    Picking.Flags.Objects | Picking.Flags.Helpers);
            }
            else
            {// ray pick
                Ray3F rayW = GetWorldRay(CurrentMousePoint);
                hits = Picking.RayPick(
                    GameEngine.GetEngineDevice(),
                    Adapter.SceneManager, Adapter.TechniqueContext,
                    rayW, Utils.AsCameraDesc(Camera), ClientSize,
                    Picking.Flags.Terrain | Picking.Flags.Objects | 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 <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 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);
        }
Example #26
0
        /// <summary>
        /// Projects the ghost</summary>
        private void ProjectGhost(DomNode ghost,
                                  Ray3F rayw,
                                  HitRecord?hit)
        {
            ITransformable xformnode = ghost.Cast <ITransformable>();
            IBoundable     bnode     = ghost.As <IBoundable>();
            AABB           box       = bnode.BoundingBox;

            Vec3F pt;

            if (hit.HasValue && hit.Value.hasNormal)
            {
                Vec3F rad     = box.Radius;
                Vec3F norm    = hit.Value.normal;
                Vec3F absNorm = Vec3F.Abs(norm);
                Vec3F offset  = Vec3F.ZeroVector;

                if (absNorm.X > absNorm.Y)
                {
                    if (absNorm.X > absNorm.Z)
                    {
                        offset.X = norm.X > 0 ? rad.X : -rad.X;
                    }
                    else
                    {
                        offset.Z = norm.Z > 0 ? rad.Z : -rad.Z;
                    }
                }
                else
                {
                    if (absNorm.Y > absNorm.Z)
                    {
                        offset.Y = norm.Y > 0 ? rad.Y : -rad.Y;
                    }
                    else
                    {
                        offset.Z = norm.Z > 0 ? rad.Z : -rad.Z;
                    }
                }
                Vec3F localCenter = box.Center - xformnode.Translation;
                pt = hit.Value.hitPt + (offset - localCenter);
            }
            else
            {
                float offset = 6.0f * box.Radius.Length;
                pt = rayw.Origin + offset * rayw.Direction;
            }

            if (ViewType == ViewTypes.Front)
            {
                pt.Z = 0.0f;
            }
            else if (ViewType == ViewTypes.Top)
            {
                pt.Y = 0.0f;
            }
            else if (ViewType == ViewTypes.Left)
            {
                pt.X = 0.0f;
            }
            xformnode.Translation = pt;
        }
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_cancelDrag || m_hitRegion == HitRegion.None || NodeList.Count == 0)
            {
                return;
            }

            bool hitAxis = m_hitRegion == HitRegion.XAxis ||
                           m_hitRegion == HitRegion.YAxis ||
                           m_hitRegion == HitRegion.ZAxis;


            Matrix4F view = vc.Camera.ViewMatrix;
            Matrix4F proj = vc.Camera.ProjectionMatrix;
            Matrix4F vp   = view * proj;

            // create ray in world space.
            Ray3F rayW = vc.GetRay(scrPt, vp);

            // 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)
            {
                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 < NodeList.Count; i++)
                {
                    ITransformable node               = 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);

                    HitRecord[] hits    = GameEngine.RayPick(view, proj, rayW, true);
                    bool        cansnap = false;
                    HitRecord   target  = new HitRecord();
                    if (hits.Length > 0)
                    {
                        // find hit record.
                        foreach (var hit in hits)
                        {
                            if (m_snapFilter.CanSnapTo(node, GameEngine.GetAdapterFromId(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 < NodeList.Count; i++)
                {
                    ITransformable node = 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;
                }
            }
        }
Example #28
0
        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);
        }
Example #29
0
        public override void OnDragging(ViewControl vc, Point scrPt)
        {
            if (m_hitRegion == HitRegion.None || m_activeOp == null || m_activeOp.NodeList.Count == 0)
            {
                return;
            }

            Matrix4F view = vc.Camera.ViewMatrix;
            // compute world * view
            Matrix4F wv = new Matrix4F();

            wv.Mul(HitMatrix, view);

            // create ray in view space.
            Ray3F rayV = vc.GetRay(scrPt, vc.Camera.ProjectionMatrix);

            Vec3F xAxis  = wv.XAxis;
            Vec3F yAxis  = wv.YAxis;
            Vec3F zAxis  = wv.ZAxis;
            Vec3F origin = wv.Translation;

            m_scale = new Vec3F(1, 1, 1);
            float scale = 1;
            float a1, a2;

            switch (m_hitRegion)
            {
            case HitRegion.XAxis:
            case HitRegion.NegXAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                Vec3F axis       = (a1 > a2 ? yAxis : zAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), xAxis);
                if (m_hitRegion == HitRegion.NegXAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.X = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.X;
            }

            break;

            case HitRegion.YAxis:
            case HitRegion.NegYAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, zAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                Vec3F axis       = (a1 > a2 ? zAxis : xAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), yAxis);
                if (m_hitRegion == HitRegion.NegYAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.Y = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Y;
            }
            break;

            case HitRegion.ZAxis:
            case HitRegion.NegZAxis:
            {
                a1 = Math.Abs(Vec3F.Dot(HitRayV.Direction, xAxis));
                a2 = Math.Abs(Vec3F.Dot(HitRayV.Direction, yAxis));
                Vec3F axis       = (a1 > a2 ? xAxis : yAxis);
                Vec3F p0         = HitRayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                Vec3F p1         = rayV.IntersectPlane(axis, -Vec3F.Dot(axis, origin));
                float dragAmount = Vec3F.Dot((p1 - p0), zAxis);
                if (m_hitRegion == HitRegion.NegZAxis)
                {
                    dragAmount *= -1;
                }
                m_scale.Z = 1.0f + dragAmount / m_hitScale;
                scale     = m_scale.Z;
            }
            break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (m_isUniformScaling)
            {
                m_scale = new Vec3F(scale, scale, scale);
            }


            // scale
            for (int i = 0; i < m_activeOp.NodeList.Count; i++)
            {
                ITransformable node = m_activeOp.NodeList[i];
                node.Scale = Vec3F.Mul(m_originalScales[i], m_scale);

                Matrix4F mtrx = TransformUtils.CalcTransform(
                    Vec3F.ZeroVector,
                    node.Rotation,
                    node.Scale,
                    m_pivotOffset[i]);
                node.Translation = m_originalTranslations[i] + mtrx.Translation;
            }
        }
Example #30
0
        protected override IList <object> Pick(MouseEventArgs e)
        {
            bool          multiSelect = DragOverThreshold;
            List <object> paths       = new List <object>();

            HitRecord[] hits;


            if (multiSelect)
            {// frustum pick
                RectangleF rect = MakeRect(FirstMousePoint, CurrentMousePoint);
                hits = GameEngine.FrustumPick(SurfaceId, Camera.ViewMatrix, Camera.ProjectionMatrix, rect);
            }
            else
            {// ray pick
                Ray3F rayW = GetWorldRay(CurrentMousePoint);
                hits = GameEngine.RayPick(Camera.ViewMatrix, Camera.ProjectionMatrix, rayW, false);
            }

            // create unique list of hits
            HashSet <ulong>  instanceSet = new HashSet <ulong>();
            List <HitRecord> uniqueHits  = new List <HitRecord>();

            // build 'path' objects for each hit record.
            foreach (HitRecord hit in hits)
            {
                bool added = instanceSet.Add(hit.instanceId);
                if (added)
                {
                    uniqueHits.Add(hit);
                }
            }

            HitRecord firstHit = new HitRecord();


            // build 'path' objects for each hit record.
            foreach (HitRecord hit in uniqueHits)
            {
                NativeObjectAdapter nobj = GameEngine.GetAdapterFromId(hit.instanceId);
                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);
        }