Пример #1
0
        public void BeginDraw_Ray(Ray3f ray, AnyRayHit rayHit, int nStep)
        {
            CreateNewPrimitive();

            Vector3f hitPos = rayHit.hitPos;

            // try snap points
            SnapResult snap = Snaps.FindHitSnapPoint(ray);

            if (snap != null)
            {
                Frame3f snapF = scene.ToWorldFrame(snap.FrameS);
                hitPos = snapF.Origin;
            }

            Frame3f sceneW = scene.SceneFrame;

            if (rayHit.hitSO == null)
            {
                primStartW        = sceneW;
                primStartW.Origin = hitPos;
            }
            else
            {
                if (scene.Context.TransformManager.ActiveFrameType == FrameType.WorldFrame)
                {
                    primStartW        = sceneW;
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PivotSO)
                {
                    primStartW        = (rayHit.hitSO as PivotSO).GetLocalFrame(CoordSpace.WorldCoords);
                    primStartW.Origin = hitPos;
                }
                else if (rayHit.hitSO is PrimitiveSO)
                {
                    // align with object frame as much as possible, given that we still want
                    //  to use hit normal...
                    Frame3f objFrame  = (rayHit.hitSO as PrimitiveSO).GetLocalFrame(CoordSpace.WorldCoords);
                    int     nBestAxis = MathUtil.MostParallelAxis(objFrame, rayHit.hitNormal);
                    int     nPerp     = (nBestAxis + 1) % 3;
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(0, objFrame.GetAxis(nPerp), primStartW.Y);
                }
                else
                {
                    primStartW = new Frame3f(hitPos, rayHit.hitNormal, 1);
                    primStartW.ConstrainedAlignAxis(1, sceneW.Y, primStartW.Y);
                }
            }
            primitive.Frame = primStartW;
            primStartS      = scene.ToSceneFrame(primStartW);
        }
Пример #2
0
        // returns snapped world-frame, or input frame if no snap
        public Frame3f UpdateSnapW(Frame3f fSourceFrameW, SnapSet Snaps)
        {
            FScene scene        = targetSO.GetScene();
            float  fSnapRadiusW = VRUtil.GetVRRadiusForVisualAngle(fSourceFrameW.Origin,
                                                                   scene.ActiveCamera.GetPosition(), SnapThreshVisualAngleDeg);
            float fSnapRadiusS = fSnapRadiusW / scene.GetSceneScale();

            // fSourceFrameW in Scene coordinates
            Frame3f fSourceS = scene.ToSceneFrame(fSourceFrameW);

            SnapResult best_snap    = null;
            float      fNearest     = float.MaxValue;
            Frame3f    fBestSourceL = Frame3f.Identity;

            // snapframes are stored in local coords relative to object
            foreach (Frame3f fPointFrameL in snapFramesL)
            {
                // convert local-coord snap frame into scene coords
                Frame3f fPointFrameS = fSourceS.FromFrame(fPointFrameL);

                SnapResult snap = Snaps.FindNearestSnapPointS(fPointFrameS, fSnapRadiusS);
                if (snap != null)
                {
                    float d = ((Vector3f)snap.FrameS.Origin - fPointFrameS.Origin).Length;
                    if (d < fNearest)
                    {
                        fNearest     = d;
                        fBestSourceL = fPointFrameL;
                        best_snap    = snap;
                    }
                }
            }

            snapState.UpdateState(best_snap, fBestSourceL);
            if (snapState.IsSnapped)
            {
                SnapResult useSnap    = snapState.ActiveSnapTarget;
                Frame3f    useSourceL = (Frame3f)snapState.ActiveSnapData;

                if (SnapOrientation)
                {
                    // compute min-rotation frame, then align origins
                    Frame3f fAlignedSourceS =
                        Frame3f.SolveMinRotation(fSourceS, useSnap.FrameS);
                    Frame3f  fPointFrameS = fAlignedSourceS.FromFrame(useSourceL);
                    Vector3f deltaS       = (Vector3f)useSnap.FrameS.Origin - fPointFrameS.Origin;
                    snapFrameS = fAlignedSourceS.Translated(deltaS);


                    //// this is tricky...we have an object-space frame useSourceL, which
                    ////  we want to snap to a scene-space frame usePoint.FrameS. So we need
                    ////  to shift origin of that frame by -useSourceL_in_FrameS!
                    //snapFrameS = usePoint.FrameS.Translated(
                    //    -usePoint.FrameS.FromFrameV(useSourceL.Origin));
                }
                else
                {
                    // translation-only snap - find shift in scene space, apply to input source frame
                    Frame3f  fPointFrameS = fSourceS.FromFrame(useSourceL);
                    Vector3f deltaS       = (Vector3f)useSnap.FrameS.Origin - fPointFrameS.Origin;
                    snapFrameS = fSourceS.Translated(deltaS);
                }

                // now convert to world frame for return
                return(scene.ToWorldFrame(snapFrameS));
            }

            return(fSourceFrameW);
        }
Пример #3
0
        public override bool UpdateCapture(ITransformable target, Ray3f worldRay)
        {
            // find hit
            SnapResult snap = Targets.FindHitSnapPoint(worldRay);

            snapState.UpdateState(snap);

            if (snapState.IsSnapped)
            {
                SnapResult useSnap   = snapState.ActiveSnapTarget;
                Frame3f    hitFrameS = Frame3f.Identity;
                if (useSnap != null)
                {
                    hitFrameS = new Frame3f(useSnap.FrameS);
                }

                Frame3f targetF = originalTargetS; // target.GetLocalFrame(CoordSpace.WorldCoords);
                Frame3f pivotF  = hitFrameS;
                targetF.Origin = pivotF.Origin;

                if (parent.CurrentFrameMode == FrameType.WorldFrame)
                {
                    targetF.Rotation = Quaternion.identity;
                }
                else
                {
                    targetF.Rotation = pivotF.Rotation;
                }

                Vector3f deltaInT = targetF.FromFrameV(SourceFrameL.Origin);
                targetF.Origin -= deltaInT;   // why is this minus?

                target.SetLocalFrame(targetF, CoordSpace.SceneCoords);
            }
            else
            {
                Func <SceneObject, bool> filter = null;
                if (TargetObjects != null && TargetObjects.Count > 0)
                {
                    filter = (x) => { return(TargetObjects.Contains(x) == false); }
                }
                ;

                AnyRayHit hit;
                if (scene.FindSceneRayIntersection(worldRay, out hit, true, filter))
                {
                    Vector3f hitPosS  = scene.ToSceneP(hit.hitPos);
                    Vector3f hitNormS = scene.ToSceneN(hit.hitNormal);

                    Frame3f targetF = originalTargetS;
                    targetF.Origin = hitPosS;
                    targetF.AlignAxis(1, hitNormS);

                    if (parent.CurrentFrameMode == FrameType.WorldFrame)
                    {
                        targetF.Rotation = Quaternion.identity;
                    }

                    Vector3f deltaInT = targetF.FromFrameV(SourceFrameL.Origin);
                    targetF.Origin -= deltaInT;   // why is this minus?
                    target.SetLocalFrame(targetF, CoordSpace.SceneCoords);
                }
                else
                {
                    target.SetLocalFrame(originalTargetS, CoordSpace.SceneCoords);
                }
            }

            return(true);
        }
Пример #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");
            }
        }