Exemplo n.º 1
0
        public override ITransformGizmo Build(FScene scene, List <SceneObject> targets)
        {
            if (targets.Count != 1)
            {
                return(null);
            }
            LengthenPivotSO pivotSO = targets[0] as LengthenPivotSO;

            if (pivotSO == null)
            {
                return(null);
            }

            // [TODO] lost this functionality when we removed OriginalFrameS.
            //
            //Frame3f frameS = pivotSO.OriginalFrameS;
            Frame3f frameS = pivotSO.GetLocalFrame(CoordSpace.SceneCoords);

            MoveLengthenPivotGizmo gizmo = new MoveLengthenPivotGizmo();

            gizmo.ScenePositionF = (ray) => {
                DistLine3Ray3 dist = new DistLine3Ray3(ray, new Line3d(frameS.Origin, -frameS.Y));
                dist.Compute();
                // [RMS] disabling clamp here because we don't know original "start" point now
                //if (dist.LineParameter < 0)
                //    return dist.Line.Origin;
                //else
                return(dist.LineClosest);
            };

            gizmo.WidgetScale = WidgetScale;
            gizmo.Create(scene, targets);
            return(gizmo);
        }
Exemplo n.º 2
0
        // try to compute a stable ray/plane intersection. when origin is at < +/- an altitude threshold,
        // use ray/line distance with view-perp line, instead of actual intersection
        public static Vector3f SafeRayPlaneIntersection(Ray3f ray, Vector3f forwardDir,
                                                        Vector3f planeOrigin, Vector3f planeNormal, float fAngleThresh = 10.0f)
        {
            // determine if we are in unstable condition
            float fOriginAngleDeg = (float)Math.Abs(
                planeNormal.AngleD((planeOrigin - ray.Origin).Normalized));
            bool bOriginUnstable = Math.Abs(fOriginAngleDeg - 90.0f) < fAngleThresh;

            // we use ray/plane intersect if stable
            Frame3f  planeF   = new Frame3f(planeOrigin, planeNormal);
            Vector3f planeHit = planeF.RayPlaneIntersection(ray.Origin, ray.Direction, 2);

            if (bOriginUnstable == false)
            {
                return(planeHit);
            }

            // if unstable, find "right" direction in plane (ie perp to forward dir, which
            //  may just be ray dir), then intersection is ray/axis closest point
            Vector3f fwDirInPlane   = (forwardDir - planeNormal.Dot(forwardDir)).Normalized;
            Vector3f perpDirInPlane = Quaternionf.AxisAngleD(planeNormal, 90.0f) * fwDirInPlane;
            float    fAxisDist      = (float)DistLine3Ray3.MinDistanceLineParam(ray, new Line3d(planeOrigin, perpDirInPlane));

            return(planeOrigin + fAxisDist * perpDirInPlane);
        }
Exemplo n.º 3
0
        public void UpdateDraw_Ray(Ray3f ray, int nStep)
        {
            // scene xform may have changed during steps (eg view rotation), so we
            // need to reconstruct our local frame
            Frame3f primCurW = scene.ToWorldFrame(primStartS);

            // step 1: find radius in plane
            // step 2: find height from plane
            float fY = MinDimension;

            if (nStep == 0)
            {
                Vector3f forwardDir = ray.Direction;
                Vector3f plane_hit  = VRUtil.SafeRayPlaneIntersection(ray, forwardDir, primCurW.Origin, primCurW.Y);
                plane_hit_local = primCurW.ToFrameP(plane_hit);
            }
            else if (nStep == 1)
            {
                Vector3f plane_hit = primCurW.FromFrameP(plane_hit_local);
                Line3d   l         = new Line3d(plane_hit, primCurW.Y);
                fY = (float)DistLine3Ray3.MinDistanceLineParam(ray, l);
            }

            // figure out possible dimensions, clamp to ranges
            float planeX   = MathUtil.SignedClamp(plane_hit_local[0], MinDimension, MaxDimension);
            float planeZ   = MathUtil.SignedClamp(plane_hit_local[2], MinDimension, MaxDimension);
            float fR_plane = MathUtil.Clamp(plane_hit_local.Length, MinDimension / 2, MaxDimension / 2);

            fY = MathUtil.SignedClamp(fY, MinDimension, MaxDimension);

            // update frame
            primitive.Frame = primCurW;

            // update dimensions
            bool  bIsCorner = (primitive.Center == CenterModes.Corner);
            float fScale    = 1.0f;     // object is not in scene coordinates!

            if (primitive.Type == MeshPrimitivePreview.PrimType.Cylinder)
            {
                primitive.Width  = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth  = primitive.Width;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Box)
            {
                primitive.Width  = (bIsCorner) ? planeX * fScale : 2 * planeX * fScale;
                primitive.Depth  = (bIsCorner) ? planeZ * fScale : 2 * planeZ * fScale;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Sphere)
            {
                primitive.Width  = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth  = primitive.Width;
                primitive.Height = Mathf.Sign(fY) * primitive.Width;
            }
            else
            {
                throw new NotImplementedException("DrawPrimitivesTool.UpdateDraw_Ray - type not supported");
            }
        }
Exemplo n.º 4
0
        public void UpdateDraw_Spatial(Ray3f ray, Frame3f handFrame, int nStep)
        {
            // scene xform may have changed during steps (eg view rotation), so we
            // need to reconstruct our local frame
            Frame3f primCurW = scene.ToWorldFrame(primStartS);

            // try snap points
            SnapResult snap      = Snaps.FindHitSnapPoint(ray);
            bool       bHaveSnap = (snap != null);
            Frame3f    snapF     = (bHaveSnap) ? scene.ToWorldFrame(snap.FrameS) : Frame3f.Identity;

            // step 1: find radius in plane
            if (nStep == 0)
            {
                if (bHaveSnap)
                {
                    plane_hit_local = primCurW.ToFrameP(
                        primCurW.ProjectToPlane(snapF.Origin, 1));
                }
                else
                {
                    Vector3f forwardDir = ray.Direction;
                    Vector3f plane_hit  = VRUtil.SafeRayPlaneIntersection(ray, forwardDir, primCurW.Origin, primCurW.Y);
                    plane_hit_local = primCurW.ToFrameP(plane_hit);
                }
            }
            float fX       = MathUtil.SignedClamp(plane_hit_local[0], MinDimension, MaxDimension);
            float fY       = MinDimension;
            float fZ       = MathUtil.SignedClamp(plane_hit_local[2], MinDimension, MaxDimension);
            float fR_plane = MathUtil.Clamp(plane_hit_local.Length, MinDimension / 2, MaxDimension / 2);

            // step 2: find height from plane
            if (nStep == 1)
            {
                Vector3f plane_hit = primCurW.FromFrameP(plane_hit_local);
                Line3d   l         = new Line3d(plane_hit, primCurW.Y);
                if (bHaveSnap)
                {
                    fY = (float)l.Project(snapF.Origin);
                }
                else
                {
                    Vector3f handTip   = handFrame.Origin + SceneGraphConfig.HandTipOffset * handFrame.Z;
                    float    fHandDist = (float)l.DistanceSquared(handTip);
                    if (fHandDist < fR_plane * 1.5f)
                    {
                        fY = (float)l.Project(handTip);
                    }
                    else
                    {
                        fY = (float)DistLine3Ray3.MinDistanceLineParam(ray, l);
                    }
                }
            }

            // figure out possible dimensions, clamp to ranges
            fY = MathUtil.SignedClamp(fY, MinDimension, MaxDimension);

            // update frame
            primitive.Frame = primCurW;

            // update dimensions
            bool  bIsCorner = (primitive.Center == CenterModes.Corner);
            float fScale    = 1.0f;     // object is not in scene coordinates!

            if (primitive.Type == MeshPrimitivePreview.PrimType.Cylinder)
            {
                primitive.Width = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth = primitive.Width;
                //primitive.Depth = Mathf.Sign(fZ) * primitive.Width;
                //primitive.Width = Mathf.Sign(fX) * primitive.Width;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Box)
            {
                primitive.Width  = (bIsCorner) ? fX : 2 * fX * fScale;
                primitive.Depth  = (bIsCorner) ? fZ : 2 * fZ * fScale;
                primitive.Height = fY * fScale;
            }
            else if (primitive.Type == MeshPrimitivePreview.PrimType.Sphere)
            {
                primitive.Width = (bIsCorner) ? fR_plane * fScale : 2 * fR_plane * fScale;
                primitive.Depth = primitive.Height = primitive.Width;
                //primitive.Depth = Mathf.Sign(fZ) * primitive.Width;
                //primitive.Width = Mathf.Sign(fX) * primitive.Width;
                //primitive.Height = Mathf.Sign(fY) * primitive.Width;
            }
            else
            {
                throw new NotImplementedException("SnapDrawPrimitivesTool.UpdateDraw_Ray - type not supported");
            }
        }