예제 #1
0
        // 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;
            }
        }
예제 #2
0
 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);
 }
예제 #3
0
        public static void TranslateInFrame(TransformableSO so, Vector3f translate, CoordSpace eSpace = CoordSpace.ObjectCoords)
        {
            Frame3f f = so.GetLocalFrame(eSpace);

            f.Origin += translate;
            so.SetLocalFrame(f, eSpace);
        }
예제 #4
0
 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);
     }
 }
예제 #5
0
            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);
            }
예제 #6
0
        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);
        }
예제 #7
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 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);
        }
예제 #8
0
 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);
        }
예제 #10
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 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);
        }