Beispiel #1
0
        public static void RecenterVRView(bool bRecenter, bool bAnimated = false)
        {
            FContext ctx = OG.Context;

            OG.Context.RegisterNextFrameAction(() => {
                ctx.ResetView(false);
                ctx.Scene.SetSceneScale(1.0f / meter_size);

                //OG.Context.ActiveCamera.

                Frame3f cockpitF = ctx.ActiveCockpit.GetLevelViewFrame(CoordSpace.WorldCoords);
                Frame3f forwardF = cockpitF.Translated(1.2f, 2);

                ctx.ActiveCamera.SetTarget(forwardF.Origin);
                ctx.ActiveCamera.Manipulator().SceneZoom(ctx.Scene, ctx.ActiveCamera, -0.7f, false);

                Vector3f legCenterW = OG.Scan.SO.GetLocalFrame(CoordSpace.WorldCoords).Origin;
                if (size_mode == SizeModes.RealSize)
                {
                    legCenterW += 0.5f * forwardF.Y;
                }

                ctx.ActiveCamera.Manipulator().ScenePanFocus(ctx.Scene, ctx.ActiveCamera, legCenterW, bAnimated);


                //OG.Context.ScaleView(OG.Scan.SO.GetLocalFrame(CoordSpace.WorldCoords).Origin, meter_size);

                //OG.Context.ActiveCamera.Manipulator().SceneTranslate(OG.Scene, 100 * Vector3f.AxisZ, false);
                //OG.Context.ActiveCamera.SetTarget(OG.Context.ActiveCamera.GetPosition() + 100 * Vector3f.AxisZ);
            });
        }
Beispiel #2
0
        public void Place(HUDStandardItem hudItem, float dx, float dy)
        {
            Frame3f initFrame = hudItem.GetObjectFrame();
            Frame3f hudFrame  = HUDUtil.GetSphereFrame(Radius, dx, dy);

            hudItem.SetObjectFrame(
                initFrame.Translated(hudFrame.Origin)
                .Rotated(Quaternionf.FromTo(initFrame.Z, hudFrame.Z)));
        }
Beispiel #3
0
        public static void PlaceInSphere(HUDStandardItem hudItem, float fHUDRadius, Vector3f vHUDCenter, Vector3f vPlaceAt)
        {
            Frame3f initFrame = hudItem.GetObjectFrame();
            Frame3f hudFrame  = GetSphereFrame(fHUDRadius, vHUDCenter, vPlaceAt);

            hudItem.SetObjectFrame(
                initFrame.Translated(hudFrame.Origin)
                .Rotated(Quaternionf.FromTo(initFrame.Z, hudFrame.Z)));
        }
Beispiel #4
0
        public static void PlaceInSphereWithNormal(HUDStandardItem hudItem, float fHUDRadius, float fAngleHorz, float fAngleVert, Vector3f vPointDir)
        {
            Frame3f initFrame = hudItem.GetObjectFrame();
            Frame3f hudFrame  = GetSphereFrame(fHUDRadius, fAngleHorz, fAngleVert);

            hudItem.SetObjectFrame(
                initFrame.Translated(hudFrame.Origin)
                .Rotated(Quaternionf.FromTo(initFrame.Z, vPointDir)));
        }
Beispiel #5
0
        public static void PlaceInSphere(HUDStandardItem hudItem, float fHUDRadius, float fAngleHorz, float fAngleVert)
        {
            Frame3f initFrame = hudItem.GetObjectFrame();
            Frame3f hudFrame  = GetSphereFrame(fHUDRadius, fAngleHorz, fAngleVert);

            hudItem.SetObjectFrame(
                initFrame.Translated(hudFrame.Origin)
                .Rotated(Quaternion.FromToRotation(initFrame.Z, hudFrame.Z)));
        }
Beispiel #6
0
        public static void PlaceInScene(HUDStandardItem hudItem, Vector3f vHUDCenter, Vector3f vPlaceAt)
        {
            Frame3f  initFrame = hudItem.GetObjectFrame();
            Vector3f n         = (vPlaceAt - vHUDCenter).Normalized;
            Frame3f  frame     = new Frame3f(vPlaceAt, n);

            hudItem.SetObjectFrame(
                initFrame.Translated(frame.Origin)
                .Rotated(Quaternionf.FromTo(initFrame.Z, frame.Z)));
        }
Beispiel #7
0
        public void Place(HUDStandardItem hudItem, float dx, float dy)
        {
            Frame3f initFrame = hudItem.GetObjectFrame();
            Frame3f hudFrame  = VerticalCoordIsAngle ?
                                HUDUtil.GetCylinderFrameFromAngles(Radius, dx, dy) :
                                HUDUtil.GetCylinderFrameFromAngleHeight(Radius, dx, dy);

            hudItem.SetObjectFrame(
                initFrame.Translated(hudFrame.Origin)
                .Rotated(Quaternionf.FromTo(initFrame.Z, hudFrame.Z)));
        }
        /// <summary>
        /// called on click-down
        /// </summary>
        override public void Begin(SceneObject so, Vector2d downPos, Ray3f downRay)
        {
            SORayHit hit;

            if (TargetSO.FindRayIntersection(downRay, out hit) == false)
            {
                return;
            }

            Vector3d scenePos = SceneTransforms.WorldToSceneP(this.Scene, hit.hitPos);

            CurrentHitPosS = new Frame3f(scenePos);

            float fObjectT = (CurrentHitPosS.Origin - ObjectFrameS.Origin).Dot(ObjectFrameS.Y);

            CurrentPlaneFrameS = ObjectFrameS.Translated(fObjectT, 1);

            if (have_set_plane == false)
            {
                sphereIndicator = IndicatorBuilder.MakeSphereIndicator(0, "hit_point",
                                                                       fDimension.Scene(sphere_indicator_size * 0.5),
                                                                       () => { return(CurrentHitPosS); },
                                                                       () => { return(Colorf.Orange); },
                                                                       () => { return(true); });
                Indicators.AddIndicator(sphereIndicator);
                sphereIndicator.RootGameObject.SetName("hit_point");

                planeIndicator = IndicatorBuilder.MakeSectionPlaneIndicator(1, "section_plane",
                                                                            fDimension.Scene(plane_indicator_width),
                                                                            () => { return(CurrentPlaneFrameS); },
                                                                            () => { return(new Colorf(Colorf.LightGreen, 0.5f)); },
                                                                            () => { return(true); });
                Indicators.AddIndicator(planeIndicator);
                planeIndicator.RootGameObject.SetName("section_plane");

                have_set_plane = true;
            }
        }
        protected override void OnPointUpdated(ControlPoint pt, Frame3f prevFrameS, bool isFirst)
        {
            Vector3f basePt  = GetPointPosition(BasePointID, CoordSpace.SceneCoords).Origin;
            Vector3f frontPt = GetPointPosition(FrontPointID, CoordSpace.SceneCoords).Origin;
            Vector3f topPt   = GetPointPosition(TopPointID, CoordSpace.SceneCoords).Origin;

            lastTargetFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);

            Frame3f previewFrameS = lastTargetFrameS;

            // position next to original object
            previewFrameS = previewFrameS.Translated(1.1f * (float)meshBounds.Width * Vector3f.AxisX);

            Vector3f upAxis = (topPt - basePt).Normalized;

            // construct a frame perp to upAxis at midpoint, and project original and current fw points
            Frame3f  upFrame = new Frame3f((topPt + basePt) * 0.5f, upAxis);
            Vector3f origFW  = upFrame.ProjectToPlane(initialFrontPt, 2);

            origFW = (origFW - upFrame.Origin).Normalized;
            Vector3f curFW = upFrame.ProjectToPlane(frontPt, 2);

            curFW = (curFW - upFrame.Origin).Normalized;
            //float angle = MathUtil.PlaneAngleSignedD(origFW, curFW, upAxis);

            start_forward_pt_S   = upFrame.FromFrameP(origFW);
            current_forward_pt_S = upFrame.FromFrameP(curFW);

            // construct rotation that aligns up axis with y-up
            Quaternionf upRotate = Quaternionf.FromTo(upAxis, Vector3f.AxisY);

            previewFrameS.Rotate(upRotate);

            // now rotate so that forward dir points along -Z
            //Quaternionf fwRotate = Quaternionf.AxisAngleD(Vector3f.AxisY, angle);
            //curFW = upRotate * curFW;
            Quaternionf fwRotate = Quaternionf.FromToConstrained(curFW, -Vector3f.AxisZ, Vector3f.AxisY);

            previewFrameS.Rotate(fwRotate);

            previewSO.SetLocalFrame(previewFrameS, CoordSpace.SceneCoords);
            lastPreviewFrameS = previewFrameS;
        }
        override public void Apply()
        {
            float VerticalSpaceFudge = 10.0f;

            DMeshSO TargetMeshSO = TargetSO as DMeshSO;

            Frame3f           curFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            TransformSOChange change    = new TransformSOChange(TargetSO,
                                                                curFrameS, lastPreviewFrameS, CoordSpace.SceneCoords);

            Scene.History.PushChange(change, false);

            Frame3f newFrameS = new Frame3f(SceneTransforms.ObjectToSceneP(TargetSO, meshBounds.Center));
            RepositionPivotChangeOp pivot1 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO);

            Scene.History.PushChange(pivot1, false);

            newFrameS = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            AxisAlignedBox3d bounds         = TargetMeshSO.Mesh.CachedBounds;
            float            h              = (float)bounds.Height;
            Vector3f         o              = newFrameS.Origin;
            Vector3f         translate      = new Vector3f(-o.x, h * 0.5f - o.y + VerticalSpaceFudge, -o.z);
            Frame3f          centeredFrameS = newFrameS.Translated(translate);

            TransformSOChange centerChange = new TransformSOChange(TargetSO,
                                                                   newFrameS, centeredFrameS, CoordSpace.SceneCoords);

            Scene.History.PushChange(centerChange, false);

            newFrameS        = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
            o                = newFrameS.Origin;
            o.y              = 0;
            newFrameS.Origin = o;

            RepositionPivotChangeOp pivot2 = new RepositionPivotChangeOp(newFrameS, TargetMeshSO);

            Scene.History.PushChange(pivot2, false);


            Scene.History.PushInteractionCheckpoint();
        }
        public override void PreRender()
        {
            base.PreRender();

            // for fixed preview orientation, we keep preview "on the right" of scan.
            if (FixedPreviewOrientation && previewSO != null)
            {
                fCamera  cam       = previewSO.GetScene().ActiveCamera;
                Vector3f camRightW = cam.Right();
                Vector3f camRightS = previewSO.GetScene().ToSceneN(camRightW);

                Frame3f  previewF = lastPreviewFrameS;
                Frame3f  targetF  = TargetSO.GetLocalFrame(CoordSpace.SceneCoords);
                Vector3f dv       = previewF.Origin - targetF.Origin;
                dv.y = 0;
                float dist = dv.Length;

                Frame3f rightF = targetF.Translated(dist * camRightS);
                rightF.Rotation = previewF.Rotation;
                previewSO.SetLocalFrame(rightF, CoordSpace.SceneCoords);
            }
        }
Beispiel #12
0
        public void ScaleView(Vector3 vCenterW, float fRadiusW)
        {
            //Vector3f camTarget = ActiveCamera.GetTarget();
            //Vector3f localTarget = Scene.WorldFrame.ToFrameP(camTarget);
            Vector3f vDeltaOrig = Scene.SceneFrame.ToFrameP(vCenterW);

            ActiveCamera.Manipulator().ResetSceneOrbit(
                Scene, false, true, true);

            float fCurScale = Scene.GetSceneScale();

            Frame3f cockpitF = ActiveCockpit.GetLevelViewFrame(CoordSpace.WorldCoords);
            float   fScale   = 1.0f / fRadiusW;

            vDeltaOrig *= fScale;
            Frame3f deskF = cockpitF.Translated(1.2f, 2).Translated(-0.5f, 1).Translated(-vDeltaOrig);

            Scene.SceneFrame = deskF;
            Scene.SetSceneScale(fCurScale * fScale);
            Vector3f newTarget = Scene.SceneFrame.Origin + vDeltaOrig;

            ActiveCamera.SetTarget(newTarget);
        }
Beispiel #13
0
        public static void RecenterAboveOrigin(FScene scene, SceneObject so, bool bInteractive)
        {
            Frame3f          curFrameO = so.GetLocalFrame(CoordSpace.ObjectCoords);
            AxisAlignedBox3f bounds    = so.GetLocalBoundingBox();
            Box3f            box       = new Box3f(bounds);

            box = curFrameO.FromFrame(ref box);
            AxisAlignedBox3f boundsS = box.ToAABB();

            Vector3f c  = boundsS.Center - 0.5f * boundsS.Height * Vector3f.AxisY;
            Vector3f dt = -c;

            if (dt.MaxAbs > MathUtil.ZeroTolerancef)
            {
                Frame3f           newFrameO = curFrameO.Translated(dt);
                TransformSOChange change    = new TransformSOChange(so, curFrameO, newFrameO, CoordSpace.ObjectCoords);
                scene.History.PushChange(change, false);
                if (bInteractive)
                {
                    scene.History.PushInteractionCheckpoint();
                }
            }
        }
Beispiel #14
0
        override public List <ISnapSegment> GenerateSegments(SceneObject so)
        {
            List <ISnapSegment> v = new List <ISnapSegment>();

            if (so is BoxSO)
            {
                BoxSO   box = so as BoxSO;
                Frame3f f   = box.GetLocalFrame(CoordSpace.SceneCoords);

                // corners
                float    ext0 = 0.5f * box.ScaledWidth, ext1 = 0.5f * box.ScaledHeight, ext2 = 0.5f * box.ScaledDepth;
                Vector3f extAxis0 = ext0 * f.X, extAxis1 = ext1 * f.Y, extAxis2 = ext2 * f.Z;

                v.Add(new StandardSnapSegment(box)
                {
                    center = f.Translated(-extAxis0 - extAxis1), extent = ext2
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = f.Translated(extAxis0 - extAxis1), extent = ext2
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = f.Translated(extAxis0 + extAxis1), extent = ext2
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = f.Translated(-extAxis0 + extAxis1), extent = ext2
                });

                Frame3f fX = f.Rotated(90.0f, 1);
                v.Add(new StandardSnapSegment(box)
                {
                    center = fX.Translated(-extAxis1 - extAxis2), extent = ext0
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fX.Translated(extAxis1 - extAxis2), extent = ext0
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fX.Translated(extAxis1 + extAxis2), extent = ext0
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fX.Translated(-extAxis1 + extAxis2), extent = ext0
                });

                Frame3f fY = f.Rotated(90.0f, 0);
                v.Add(new StandardSnapSegment(box)
                {
                    center = fY.Translated(-extAxis0 - extAxis2), extent = ext1
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fY.Translated(extAxis0 - extAxis2), extent = ext1
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fY.Translated(extAxis0 + extAxis2), extent = ext1
                });
                v.Add(new StandardSnapSegment(box)
                {
                    center = fY.Translated(-extAxis0 + extAxis2), extent = ext1
                });
            }

            if (base.EnableGeometry)
            {
                base.build_geometry(so, v);
            }

            return(v);
        }
Beispiel #15
0
        public static void SwapUpDirection(FScene scene, List <PrintMeshSO> objects)
        {
            AxisAlignedBox3f sceneBounds  = AxisAlignedBox3f.Empty;
            Vector3f         sharedOrigin = Vector3f.Zero;

            foreach (var meshSO in objects)
            {
                sharedOrigin += meshSO.GetLocalFrame(CoordSpace.SceneCoords).Origin;
                sceneBounds.Contain(meshSO.GetBoundingBox(CoordSpace.SceneCoords).ToAABB());
            }
            sharedOrigin /= objects.Count;

            foreach (var so in objects)
            {
                Frame3f     curF = so.GetLocalFrame(CoordSpace.SceneCoords);
                UpDirection from = so.UpDirection;
                UpDirection to   = (from == UpDirection.YUp) ? UpDirection.ZUp : UpDirection.YUp;

                Quaternionf rotate = Quaternionf.AxisAngleD(Vector3f.AxisX, (to == UpDirection.YUp) ? -90 : 90);
                Frame3f     newF   = curF;
                newF.RotateAround(sharedOrigin, rotate);
                TransformSOChange upChange = new TransformSOChange(so, newF, CoordSpace.SceneCoords)
                {
                    OnApplyF  = (x) => { so.UpDirection = to; },
                    OnRevertF = (x) => { so.UpDirection = from; }
                };
                scene.History.PushChange(upChange, false);
            }

            AxisAlignedBox3f newSceneBounds = AxisAlignedBox3f.Empty;

            foreach (var meshSO in objects)
            {
                newSceneBounds.Contain(meshSO.GetBoundingBox(CoordSpace.SceneCoords).ToAABB());
            }

            Vector3f startBase = sceneBounds.Center; startBase.y = 0;
            Vector3f newBase   = newSceneBounds.Center; newBase.y = newSceneBounds.Min.y;

            Vector3f df = startBase - newBase;

            foreach (var so in objects)
            {
                Frame3f           curF         = so.GetLocalFrame(CoordSpace.SceneCoords);
                Frame3f           newF         = curF.Translated(df);
                TransformSOChange centerChange = new TransformSOChange(so, newF, CoordSpace.SceneCoords);
                scene.History.PushChange(centerChange, false);
            }


            // reposition pivots at base of
            List <Frame3f> setF = new List <Frame3f>();

            foreach (var so in objects)
            {
                Frame3f  objF   = so.GetLocalFrame(CoordSpace.ObjectCoords);
                Vector3f center = so.GetBoundingBox(CoordSpace.SceneCoords).Center;
                center.y = 0;
                Frame3f sceneF = new Frame3f(center);
                setF.Add(sceneF);
            }
            for (int k = 0; k < objects.Count; ++k)
            {
                RepositionPivotChangeOp change = new RepositionPivotChangeOp(setF[k], objects[k], CoordSpace.SceneCoords);
                scene.History.PushChange(change, false);
            }
        }
Beispiel #16
0
        override public bool UpdateCapture(InputEvent e)
        {
            if (eState == CaptureState.ClickType && FindHitGO(e.ray) != null)
            {
                return(true);
            }

            // otherwise we fall into drag state
            eState = CaptureState.DragType;

            if (newPrimitive == null)
            {
                newPrimitive = CreatePrimitive();

                fPrimScale = 1.0f;

                if (newPrimitive is PivotSO)
                {
                    fPrimShift = 0.0f;
                }
                else
                {
                    if (newPrimitive is PrimitiveSO)
                    {
                        if (SavedSettings.Restore("DropPrimButton_scale") != null)
                        {
                            fPrimScale = (float)SavedSettings.Restore("DropPrimButton_scale");
                            newPrimitive.SetLocalScale(fPrimScale * Vector3f.One);
                        }
                    }
                    fPrimShift = newPrimitive.GetLocalBoundingBox().Extents[1] * TargetScene.GetSceneScale();
                }

                // [RMS] this is kind of cheating - we are going to tell this SO
                //   it is part of the scene, but not actually put it in the scene.
                //   This is because sometimes the SO needs to query the scene/camera
                //   (eg for pivot resizing)
                TargetScene.ReparentSceneObject(newPrimitive, false);
                newPrimitive.SetScene(TargetScene);

                lastHitF = UnityUtil.GetGameObjectFrame(TargetScene.RootGameObject, CoordSpace.WorldCoords);
                newPrimitive.SetLocalFrame(lastHitF.Translated(fPrimShift, 1), CoordSpace.WorldCoords);
            }

            // [RMS] only Touch for this??
            if (InputState.IsDevice(e.device, InputDevice.OculusTouch) && newPrimitive is PrimitiveSO)
            {
                Vector2f vStick = e.input.StickDelta2D((int)e.side);
                if (vStick[1] != 0)
                {
                    fPrimScale = fPrimScale * (1.0f + vStick[1] * 0.1f);
                    fPrimScale = MathUtil.Clamp(fPrimScale, 0.01f, 10.0f);
                    newPrimitive.SetLocalScale(fPrimScale * Vector3f.One);
                    fPrimShift = newPrimitive.GetLocalBoundingBox().Extents[1] * TargetScene.GetSceneScale();
                }
            }

            AnyRayHit hit = null;

            if (TargetScene.FindSceneRayIntersection(e.ray, out hit))
            {
                update_position(hit);
                newPrimitive.SetLocalFrame(lastHitF.Translated(fPrimShift, 1), CoordSpace.WorldCoords);
            }

            // [RMS] have to do this because prim is not part of scene yet,
            //   and things like pivots need to be resized
            if (newPrimitive != null)
            {
                newPrimitive.PreRender();
            }

            return(true);
        }
Beispiel #17
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);
        }
Beispiel #18
0
        override public List <ISnapPoint> GeneratePoints(SceneObject so)
        {
            List <ISnapPoint> v = new List <ISnapPoint>();

            if (so is CylinderSO)
            {
                CylinderSO cyl = so as CylinderSO;
                Frame3f    f   = Frame3f.Identity;
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    IsSurface = false, frame = f
                });
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(cyl.Height * 0.5f * f.Y)
                });
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(-cyl.Height * 0.5f * f.Y)
                });

                // face-centers
                float fR = cyl.Radius;
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(fR * f.X).Rotated(-90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(-fR * f.X).Rotated(90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(fR * f.Z).Rotated(90.0f, 0)
                });
                v.Add(new SOFrameSnapPoint(cyl)
                {
                    frame = f.Translated(-fR * f.Z).Rotated(-90.0f, 0)
                });
            }
            else if (so is BoxSO)
            {
                BoxSO   box = so as BoxSO;
                Frame3f f   = Frame3f.Identity;

                // object center
                v.Add(new SOFrameSnapPoint(box)
                {
                    IsSurface = false, frame = f
                });

                // face centers
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(box.Height * 0.5f * f.Y)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-box.Height * 0.5f * f.Y).Rotated(180.0f, 0)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(box.Width * 0.5f * f.X).Rotated(-90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-box.Width * 0.5f * f.X).Rotated(90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(box.Depth * 0.5f * f.Z).Rotated(90.0f, 0)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-box.Depth * 0.5f * f.Z).Rotated(-90.0f, 0)
                });

                // corners
                Vector3f extAxis0 = 0.5f * box.Width * f.X;
                Vector3f extAxis1 = 0.5f * box.Height * f.Y;
                Vector3f extAxis2 = 0.5f * box.Depth * f.Z;
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-extAxis0 - extAxis1 - extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(extAxis0 - extAxis1 - extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(extAxis0 + extAxis1 - extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-extAxis0 + extAxis1 - extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-extAxis0 - extAxis1 + extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(extAxis0 - extAxis1 + extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(extAxis0 + extAxis1 + extAxis2)
                });
                v.Add(new SOFrameSnapPoint(box)
                {
                    frame = f.Translated(-extAxis0 + extAxis1 + extAxis2)
                });
            }
            else if (so is SphereSO)
            {
                SphereSO sphere = so as SphereSO;
                Frame3f  f      = Frame3f.Identity;
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f
                });

                // sphere face-centers
                float fR = sphere.Radius;
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(fR * f.Y)
                });
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(-fR * f.Y).Rotated(180.0f, 0)
                });
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(fR * f.X).Rotated(-90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(-fR * f.X).Rotated(90.0f, 2)
                });
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(fR * f.Z).Rotated(90.0f, 0)
                });
                v.Add(new SOFrameSnapPoint(sphere)
                {
                    frame = f.Translated(-fR * f.Z).Rotated(-90.0f, 0)
                });
            }

            if (base.EnableGeometry)
            {
                base.build_geometry(so, v);
            }

            return(v);
        }