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); }); }
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))); }
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))); }
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))); }
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))); }
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))); }
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); } }
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); }
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(); } } }
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); }
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); } }
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); }
// 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); }
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); }