public override List <ISnapPoint> GeneratePoints(SceneObject so) { List <ISnapPoint> v = new List <ISnapPoint>(); if (so is PolyCurveSO) { PolyCurveSO curveSO = so as PolyCurveSO; DCurve3 curve = curveSO.Curve; Frame3f f = Frame3f.Identity; Frame3f startFrame = new Frame3f((Vector3f)curve.Start, -(Vector3f)curve.Tangent(0), 1); v.Add(new SOFrameSnapPoint(curveSO) { frame = f.FromFrame(startFrame) }); Frame3f endFrame = new Frame3f((Vector3f)curve.End, (Vector3f)curve.Tangent(curve.VertexCount - 1), 1); v.Add(new SOFrameSnapPoint(curveSO) { frame = f.FromFrame(endFrame) }); } if (base.EnableGeometry) { base.build_geometry(so, v); } return(v); }
/// <summary> /// input objectF is in Object (local) coords of so, apply all intermediate /// transforms to get it to Scene coords /// </summary> public static Frame3f ObjectToScene(SceneObject so, Frame3f objectF) { Frame3f sceneF = objectF; SceneObject curSO = so; while (curSO != null) { Frame3f curF = curSO.GetLocalFrame(CoordSpace.ObjectCoords); Vector3f scale = curSO.GetLocalScale(); Util.gDevAssert(curSO == so || IsUniformScale(scale)); sceneF.Scale(scale); sceneF = curF.FromFrame(ref sceneF); SOParent parent = curSO.Parent; if (parent is FScene) { return(sceneF); } curSO = (parent as SceneObject); } if (curSO == null) { DebugUtil.Error("SceneTransforms.ObjectToScene: found null parent SO!"); } return(sceneF); }
public static void SetBasePoint(FScene scene, DMeshSO so, Frame3f baseFrameS, bool bInteractive) { Frame3f curFrameS = so.GetLocalFrame(CoordSpace.SceneCoords); Frame3f relFrameS = baseFrameS.ToFrame(curFrameS); baseFrameS.AlignAxis(2, -Vector3f.AxisY); baseFrameS.Translate(-baseFrameS.Origin); Frame3f newFrameS = baseFrameS.FromFrame(relFrameS); TransformSOChange change = new TransformSOChange(so, curFrameS, newFrameS, CoordSpace.SceneCoords); change.Tags.Add("SetBasePoint"); scene.History.PushChange(change, false); Frame3f pivotS = Frame3f.Identity; // WHAT why is it the scene pivot ?! //Frame3f pivotL = SceneTransforms.SceneToObject(so, pivotS); RepositionPivotChangeOp pivotChange = new RepositionPivotChangeOp(pivotS, so); scene.History.PushChange(pivotChange, false); if (bInteractive) { scene.History.PushInteractionCheckpoint(); } }
public void update(Frame3f handF) { curHandF = handF; // [RMS] this function updates the position of object based on hand frame // Not clear how this should work, there are lots of options... // [1] scaled relative motion of hand inherited by object (lags ray though) //Vector3f dt = startHandF.ToFrameP(handF.Origin); //dt *= 10.0f; //Frame3f fNew = new Frame3f(startObjFW); //fNew.Origin += dt; // [2] object stays on ray, inherits a bit of xform // - resulting orientation is weird. works well for rotate in-place around ray, // but up/down/left/right tilts are impossible w/o moving object Frame3f fNew = handF.FromFrame(this.startObjRelF); if (RotationSpeed != 1.0f) { fNew.Rotation = Quaternionf.Slerp(startObjFW.Rotation, fNew.Rotation, RotationSpeed); } if (TranslationSpeed != 1.0f) { fNew.Origin = Vector3f.Lerp(startObjFW.Origin, fNew.Origin, TranslationSpeed); } // [3] object stays on ray but no rotation // - weird if you rotate left/right, because distance stays same but it // keeps pointing in same direction // - we have gizmo for this kind of translation. //Frame3 fNew = handF.FromFrame(this.startObjRelF); //fNew.Rotation = startObjFW.Rotation; // [4] object stays in place, rotate by hand rotation // - pretty hard to control, but would be good for approx orienting... // - definitely needs damping!! //Frame3 fNew = startObjFW; //Quaternion relative = handF.Rotation * Quaternion.Inverse(startHandF.Rotation); //fNew.Rotation = relative * fNew.Rotation; // apply stick rotation DOESN"T WORK //Quaternion stickY = Quaternion.AngleAxis(stickDelta[1], startHandF.X); //fNew.Rotation = fNew.Rotation * stickY; // shift in/out along hand-ray by Z fNew.Origin += StickSpeed * stickDelta[1] * handF.Z * so.GetScene().GetSceneScale(); curHandTargetF = fNew; curUseTargetF = new Frame3f(curHandTargetF); // update so so.SetLocalFrame(curUseTargetF, CoordSpace.WorldCoords); }
public static void SetSOLocalFrame(SceneObject so, CoordSpace eSpace, Frame3f newFrame) { if (eSpace == CoordSpace.SceneCoords) { // scene frames should not be scaled by scene scale, but we want to set as world // coords, so we need to apply it now if (so.GetScene().GetSceneScale() != 1.0f) { newFrame = newFrame.Scaled(so.GetScene().GetSceneScale()); } Frame3f sceneW = UnityUtil.GetGameObjectFrame(so.GetScene().RootGameObject, CoordSpace.WorldCoords); Frame3f objW = sceneW.FromFrame(newFrame); UnityUtil.SetGameObjectFrame(so.RootGameObject, objW, CoordSpace.WorldCoords); } else { UnityUtil.SetGameObjectFrame(so.RootGameObject, newFrame, eSpace); } }
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(); } } }
/// <summary> /// input objectF is in Object (local) coords of so, apply all intermediate /// transforms to get it to Scene coords /// </summary> public static Frame3f ObjectToScene(TransformableSO so, Frame3f objectF) { Frame3f sceneF = objectF; TransformableSO curSO = so; while (curSO != null) { Frame3f curF = curSO.GetLocalFrame(CoordSpace.ObjectCoords); Vector3f scale = curSO.GetLocalScale(); sceneF.Scale(scale); sceneF = curF.FromFrame(sceneF); SOParent parent = curSO.Parent; if (parent is FScene) { return(sceneF); } curSO = (parent as TransformableSO); } if (curSO == null) { DebugUtil.Error("SceneTransforms.TransformTo: found null parent SO!"); } return(sceneF); }
public override Capture UpdateCapture(InputState input, CaptureData data) { if ((data.which == CaptureSide.Left && input.bLeftShoulderReleased) || (data.which == CaptureSide.Right && input.bRightShoulderReleased) || (data.which == CaptureSide.Left && input.bRightShoulderPressed) || (data.which == CaptureSide.Right && input.bLeftShoulderPressed)) { cockpit.ActiveCamera.SetTargetVisible(false); return(Capture.End); } // [RMS] this is a hack to release input for shoulder+trigger gestures if ((data.which == CaptureSide.Left && input.bLeftTriggerPressed) || (data.which == CaptureSide.Right && input.bRightTriggerPressed)) { cockpit.ActiveCamera.SetTargetVisible(false); return(Capture.End); } cockpit.ActiveCamera.SetTargetVisible(false); GrabHandInfo hi = (GrabHandInfo)data.custom_data; Frame3f StartF = Frame3f.Identity; Frame3f CurF = Frame3f.Identity; if (data.which == CaptureSide.Left) { StartF = hi.leftStartF; CurF = input.LeftHandFrame; } else if (data.which == CaptureSide.Right) { StartF = hi.rightStartF; CurF = input.RightHandFrame; } /* orbit-style variant, does not work yet * // translation is just controller world-movement * Vector3f translation = CurF.Origin - StartF.Origin; * * // We figure out orbit by rotating cur & start frames such that the axis we * // want to measure around is that world axis. This produces more stable angles * // as the controller twists * * Frame3f YAlignedStartF = StartF; YAlignedStartF.AlignAxis(1, Vector3f.AxisY); * Frame3f YAlignedCurF = CurF; YAlignedCurF.AlignAxis(1, Vector3f.AxisY); * float fAngleX = (float)MathUtil.PlaneAngleSignedD(YAlignedStartF.X, YAlignedCurF.X, Vector3f.AxisY); * * Frame3f XAlignedStartF = StartF; XAlignedStartF.AlignAxis(0, Vector3f.AxisX); * Frame3f XAlignedCurF = CurF; XAlignedCurF.AlignAxis(0, Vector3f.AxisX); * float fAngleY = (float)MathUtil.PlaneAngleSignedD(XAlignedStartF.Y, XAlignedCurF.Y, Vector3f.AxisX); */ Frame3f relStartF = StartF.ToFrame(hi.startCamF); Frame3f curF = CurF.FromFrame(relStartF); // apply camera xforms //cockpit.ActiveCamera.Manipulator().SetCurrentSceneState(cockpit.Scene, hi.camState); //cockpit.ActiveCamera.Manipulator().SceneOrbitAround(cockpit.Scene, // CurF.Origin, -RotationSpeed * fAngleX, RotationSpeed * fAngleY); //cockpit.ActiveCamera.Manipulator().SceneTumbleAround(cockpit.Scene, // CurF.Origin, RotationSpeed * fAngleX, RotationSpeed * fAngleY); //cockpit.ActiveCamera.Manipulator().SceneRotateAround(cockpit.Scene, relF.Rotation, CurF.Origin); cockpit.ActiveCamera.Manipulator().SceneSetFrame(cockpit.Scene, curF); //cockpit.ActiveCamera.Manipulator().SceneTranslate(cockpit.Scene, TranslationSpeed * translation); return(Capture.Continue); }
// 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); }
public static void PlaceInViewPlane(HUDStandardItem hudItem, Vector3f vPosition, Frame3f viewFrame) { Frame3f objFrame = hudItem.GetObjectFrame().Translated(vPosition); hudItem.SetObjectFrame(viewFrame.FromFrame(objFrame)); }