示例#1
0
        public static Frame3f GetSOLocalFrame(SceneObject so, CoordSpace eSpace)
        {
            if (eSpace == CoordSpace.SceneCoords)
            {
                // new code maps object frame up to scene
                // [TODO] this is not the most efficient approach! can at least get the object
                //   frame directly, and avoid first local-to-obj xform
                Frame3f objF   = Frame3f.Identity;
                Frame3f result = SceneTransforms.ObjectToScene(so, objF);

                // [RMS] old code that mapped up to world, and then down to scene
                //   Problem with this code is that it is unstable - if scene-to-world xform changes,
                //   then scene frame will numerically change. Which is a problem.
                //Frame3f sceneW = UnityUtil.GetGameObjectFrame(so.GetScene().RootGameObject, CoordSpace.WorldCoords);
                //Frame3f objW = UnityUtil.GetGameObjectFrame(so.RootGameObject, CoordSpace.WorldCoords);
                //Frame3f result = sceneW.ToFrame(objW);
                //// world coords have scene scale applied, we don't want that in scene coords
                //if (so.GetScene().GetSceneScale() != 1.0f)
                //    result = result.Scaled(1.0f / so.GetScene().GetSceneScale());

                return(result);
            }
            else
            {
                return(UnityUtil.GetGameObjectFrame(so.RootGameObject, eSpace));
            }
        }
示例#2
0
        // same as LocalFrame, but LocalFrame may be tilted up/down, which we want to undo
        public virtual Frame3f GetLevelViewFrame(CoordSpace eSpace)
        {
            // otherwise we can't just set y to 0...
            Debug.Assert(eSpace == CoordSpace.WorldCoords);
            Frame3f viewF  = UnityUtil.GetGameObjectFrame(ActiveCamera.GameObject(), eSpace);
            float   fAngle = VRUtil.PlaneAngleSigned(Vector3f.AxisZ, viewF.Z, 1);

            return(new Frame3f(viewF.Origin, Quaternionf.AxisAngleD(Vector3f.AxisY, fAngle)));
        }
示例#3
0
 public static Frame3f GetSOLocalFrame(SceneObject so, CoordSpace eSpace)
 {
     if (eSpace == CoordSpace.SceneCoords)
     {
         Frame3f sceneW = UnityUtil.GetGameObjectFrame(so.GetScene().RootGameObject, CoordSpace.WorldCoords);
         Frame3f objW   = UnityUtil.GetGameObjectFrame(so.RootGameObject, CoordSpace.WorldCoords);
         Frame3f result = sceneW.ToFrame(objW);
         // world coords have scene scale applied, we don't want that in scene coords
         if (so.GetScene().GetSceneScale() != 1.0f)
         {
             result = result.Scaled(1.0f / so.GetScene().GetSceneScale());
         }
         return(result);
     }
     else
     {
         return(UnityUtil.GetGameObjectFrame(so.RootGameObject, eSpace));
     }
 }
示例#4
0
 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);
     }
 }
示例#5
0
 // cockpit frame is oriented such that
 //    +X is right
 //    +Y is up
 //    +Z is into scene
 // note that for most unity mesh objects are created on the XZ plane, and so you
 // need to rotate world_y to point to -cockpit_z, ie Quaternion.FromToRotation (Vector3.up, -cockpitF.Z)
 public virtual Frame3f GetLocalFrame(CoordSpace eSpace)
 {
     return(UnityUtil.GetGameObjectFrame(gameobject, eSpace));
 }
示例#6
0
 public virtual Frame3f GetLocalFrame()
 {
     return(UnityUtil.GetGameObjectFrame(go, CoordSpace.ObjectCoords));
 }
示例#7
0
 public virtual Frame3f GetWorldFrame()
 {
     return(UnityUtil.GetGameObjectFrame(go, CoordSpace.WorldCoords));
 }
示例#8
0
        // 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 SceneObject ImportExistingUnityMesh(GameObject go, FScene scene,
                                                          bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true,
                                                          Func <Mesh, SOMaterial, SceneObject> MakeSOFunc = null)
        {
            MeshFilter meshF = go.GetComponent <MeshFilter>();

            if (meshF == null)
            {
                throw new Exception("SceneUtil.ImportExistingUnityMesh: gameObject is not a mesh!!");
            }

            Vector3f scale = go.GetLocalScale();

            // [RMS] why don't we bake transform into mesh ??! then we could handle non-uniform scaling...
            if (SceneTransforms.IsUniformScale(scale) == false)
            {
                throw new Exception("UnitySceneUtil.ImportExistingUnityMesh: nonuniform scaling is not supported...");
            }

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

            SceneObject 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);
        }
示例#9
0
        // 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 SceneObject ImportExistingUnityGO(GameObject go, FScene scene,
                                                        bool bAddToScene = true, bool bKeepWorldPosition = true, bool bRecenterFrame = true,
                                                        Func <DMesh3, SOMaterial, SceneObject> 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);
            }

            SceneObject newSO = (MakeSOFunc != null) ?
                                MakeSOFunc(CombineMesh, scene.DefaultMeshSOMaterial)
                : new DMeshSO().Create(CombineMesh, scene.DefaultMeshSOMaterial);

            newSO.Name = go.name;

            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);
        }
示例#10
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);
        }
示例#11
0
        // utility functions

        public Frame3f GetObjectFrame()
        {
            return(UnityUtil.GetGameObjectFrame(RootGameObject, CoordSpace.ObjectCoords));
        }