// restore structs public virtual void RestoreTransform(TransformableSO so, TypedAttribSet attributes) { TypedAttribSet transform = find_struct(attributes, IOStrings.TransformStruct); if (transform == null) { throw new Exception("SOFactory.RestoreTransform: Transform struct not found!"); } Frame3f f = Frame3f.Identity; if (check_key_or_debug_print(transform, IOStrings.APosition)) { Vector3f vPosition = (Vector3f)transform[IOStrings.APosition]; f.Origin = vPosition; } if (check_key_or_debug_print(transform, IOStrings.AOrientation)) { Quaternionf vRotation = (g3.Quaternionf)transform[IOStrings.AOrientation]; f.Rotation = vRotation; } so.SetLocalFrame(f, CoordSpace.ObjectCoords); if (check_key_or_debug_print(transform, IOStrings.AOrientation)) { Vector3f vScale = (Vector3f)transform[IOStrings.AScale]; so.RootGameObject.transform.localScale = vScale; } }
public override OpStatus Revert() { // [RMS] parentSO may not be GC'd immediately, but GO be null as // soon as Scene.RemoveSeceneObject() is called if (parentSO.IsAlive && (parentSO.Target as SceneObject).RootGameObject != null) { TransformableSO tso = (parentSO.Target as TransformableSO); tso.SetLocalFrame(parentBefore, CoordSpace.SceneCoords); if (tso.SupportsScaling) { tso.SetLocalScale(parentScaleBefore); } } else { for (int i = 0; i < childSOs.Count; ++i) { childSOs[i].SetLocalFrame(before[i], CoordSpace.SceneCoords); if (childSOs[i].SupportsScaling) { childSOs[i].SetLocalScale(scaleBefore[i]); } } } return(OpStatus.Success); }
public static void TranslateInFrame(TransformableSO so, Vector3f translate, CoordSpace eSpace = CoordSpace.ObjectCoords) { Frame3f f = so.GetLocalFrame(eSpace); f.Origin += translate; so.SetLocalFrame(f, eSpace); }
private void OnTargetModified(TransformableSO so) { if (IsValid) { TransformableSO from = Source as TransformableSO; TransformableSO to = Target as TransformableSO; Frame3f FrameS = SceneTransforms.ObjectToScene(to, relativeF); from.SetLocalFrame(FrameS, CoordSpace.SceneCoords); } }
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 * cockpit.Scene.GetSceneScale(); curHandTargetF = fNew; curUseTargetF = new Frame3f(curHandTargetF); // update so so.SetLocalFrame(curUseTargetF, CoordSpace.WorldCoords); }
public virtual TransformableSO BuildSO(Func <DCurve3, TransformableSO> SOBuilderF, SOMaterial material, float scale = 1.0f) { Vector3d vCenter = curve.GetBoundingBox().Center; DCurve3 shifted = new DCurve3(curve); for (int i = 0; i < shifted.VertexCount; ++i) { shifted[i] -= vCenter; } Frame3f shiftedFrame = new Frame3f((Vector3f)vCenter, Quaternionf.Identity); TransformableSO so = SOBuilderF(shifted); so.SetLocalFrame(shiftedFrame, CoordSpace.WorldCoords); return(so); }
// extracts MeshFilter object from input GameObject and passes it to a custom constructor // function MakeSOFunc (if null, creates basic MeshSO). Then optionally adds to Scene, // preserving existing 3D position if desired (default true) public static TransformableSO ImportExistingUnityMesh(GameObject go, FScene scene, bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true, Func <Mesh, SOMaterial, TransformableSO> MakeSOFunc = null) { MeshFilter meshF = go.GetComponent <MeshFilter>(); if (meshF == null) { throw new Exception("SceneUtil.ImportExistingUnityMesh: gameObject is not a mesh!!"); } Vector3f scale = go.GetLocalScale(); Mesh useMesh = meshF.mesh; // makes a copy AxisAlignedBox3f bounds = useMesh.bounds; // bounds.Center is wrt local frame of input go // ie offset from origin in local coordinates // if we want to move frame to center of mesh, we have to re-center it at origin // in local coordinates if (bRecenterFrame) { UnityUtil.TranslateMesh(useMesh, -bounds.Center.x, -bounds.Center.y, -bounds.Center.z); useMesh.RecalculateBounds(); } TransformableSO newSO = (MakeSOFunc != null) ? MakeSOFunc(useMesh, scene.DefaultMeshSOMaterial) : new MeshSO().Create(useMesh, scene.DefaultMeshSOMaterial); if (bAddToScene) { scene.AddSceneObject(newSO, false); } if (bKeepWorldPosition) { // compute world rotation/location. If we re-centered the mesh, we need // to offset by the transform we applied above in local coordinates // (hence we have to rotate & scale) if (go.transform.parent != null) { throw new Exception("UnitySceneUtil.ImportExistingUnityMesh: Not handling case where GO has a parent transform"); } Frame3f goFrameW = UnityUtil.GetGameObjectFrame(go, CoordSpace.WorldCoords); Vector3f originW = goFrameW.Origin; if (bRecenterFrame) { originW += goFrameW.Rotation * (scale * bounds.Center); // offset initial frame to be at center of mesh } // convert world frame and offset to scene coordinates Frame3f goFrameS = scene.ToSceneFrame(goFrameW); Vector3f boundsCenterS = scene.ToSceneP(originW); // translate new object to position in scene Frame3f curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.Origin += boundsCenterS; newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply rotation (around current origin) curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.RotateAround(curF.Origin, goFrameS.Rotation); newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply local scale newSO.SetLocalScale(scale); } return(newSO); }
public override OpStatus Apply() { so.SetLocalFrame(after, CoordSpace.SceneCoords); return(OpStatus.Success); }
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); } if (((e.device & InputDevice.AnySpatialDevice) != 0) && 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); }
// extracts all MeshFilter objects from input GameObject and appends them, then passes to // function MakeSOFunc (if null, creates basic MeshSO). Then optionally adds to Scene, // preserving existing 3D position if desired (default true) public static TransformableSO ImportExistingUnityGO(GameObject go, FScene scene, bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true, Func <DMesh3, SOMaterial, TransformableSO> MakeSOFunc = null) { List <MeshFilter> filters = new List <MeshFilter>(); List <GameObject> children = new List <GameObject>() { go }; UnityUtil.CollectAllChildren(go, children); foreach (var cgo in children) { if (cgo.GetComponent <MeshFilter>() != null) { filters.Add(cgo.GetComponent <MeshFilter>()); } } if (filters.Count == 0) { throw new Exception("SceneUtil.ImportExistingUnityGO: no meshes!!"); } DMesh3 CombineMesh = new DMesh3(MeshComponents.VertexNormals | MeshComponents.VertexColors); MeshEditor editor = new MeshEditor(CombineMesh); int gid = 0; foreach (MeshFilter mesh in filters) { fMesh uMesh = new fMesh(mesh.sharedMesh); using (var imesh = uMesh.CreateCachedIMesh()) { editor.AppendMesh(imesh, ++gid); } } Vector3f scale = go.GetLocalScale(); AxisAlignedBox3d bounds = CombineMesh.CachedBounds; // bounds.Center is wrt local frame of input go // ie offset from origin in local coordinates // if we want to move frame to center of mesh, we have to re-center it at origin // in local coordinates if (bRecenterFrame) { MeshTransforms.Translate(CombineMesh, -bounds.Center.x, -bounds.Center.y, -bounds.Center.z); } TransformableSO newSO = (MakeSOFunc != null) ? MakeSOFunc(CombineMesh, scene.DefaultMeshSOMaterial) : new DMeshSO().Create(CombineMesh, scene.DefaultMeshSOMaterial); if (bAddToScene) { scene.AddSceneObject(newSO, false); } if (bKeepWorldPosition) { // compute world rotation/location. If we re-centered the mesh, we need // to offset by the transform we applied above in local coordinates // (hence we have to rotate & scale) if (go.transform.parent != null) { throw new Exception("UnitySceneUtil.ImportExistingUnityGO: Not handling case where GO has a parent transform"); } Frame3f goFrameW = UnityUtil.GetGameObjectFrame(go, CoordSpace.WorldCoords); Vector3f originW = goFrameW.Origin; if (bRecenterFrame) { originW += goFrameW.Rotation * (scale * (Vector3f)bounds.Center); // offset initial frame to be at center of mesh } // convert world frame and offset to scene coordinates Frame3f goFrameS = scene.ToSceneFrame(goFrameW); Vector3f boundsCenterS = scene.ToSceneP(originW); // translate new object to position in scene Frame3f curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.Origin += boundsCenterS; newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply rotation (around current origin) curF = newSO.GetLocalFrame(CoordSpace.SceneCoords); curF.RotateAround(curF.Origin, goFrameS.Rotation); newSO.SetLocalFrame(curF, CoordSpace.SceneCoords); // apply local scale newSO.SetLocalScale(scale); } return(newSO); }