Пример #1
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);
        }