Ejemplo n.º 1
0
        /// <summary>
        /// Called form the 'Update' function whenever the input device is moved. This function
        /// will snap the target object to the surface hovered by the mouse cursor.
        /// </summary>
        private void OnInputDeviceMoved(IInputDevice inputDevice)
        {
            // We will need to perform a raycast to check what lies underneath the mouse cursor.
            // In order to do this, we will first create a raycast filter instance to specify
            // additional information for the raycast...
            SceneRaycastFilter raycastFilter = new SceneRaycastFilter();

            raycastFilter.LayerMask = _objectSurfaceLayers;                                 // The ray can hit only objects belonging to these layers
            raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh);                      // Allow the ray to hit mesh objects
            raycastFilter.AllowedObjectTypes.Add(GameObjectType.Terrain);                   // Allow the ray to hit terrain objects
            raycastFilter.IgnoreObjects.AddRange(_targetHierarchy.GetAllChildrenAndSelf()); // The ray can not hit the target object (i.e. the object we are snapping)

            // Perform the raycast. If nothing is hit, just return.
            SceneRaycastHit raycastHit = RTScene.Get.Raycast(inputDevice.GetRay(RTFocusCamera.Get.TargetCamera), SceneRaycastPrecision.BestFit, raycastFilter);

            if (!raycastHit.WasAnythingHit)
            {
                return;
            }

            // If we reach this point we know that something was hit. We just need to find out what and based
            // on what was hit, we need to fill the necessary information in the snap config instance. Basically,
            // we need to specify surface inf such as the surface normal, hit point, the object that acts as the
            // snap surface etc. This info is extracted from the raycast hit instance differently depending on
            // whether we hit a game object or the scene grid.
            if (raycastHit.WasAnObjectHit)
            {
                // We hit an object. Get its type and return if it's not a mesh or terrain.
                GameObjectType objectType = raycastHit.ObjectHit.HitObject.GetGameObjectType();
                if (objectType != GameObjectType.Mesh && objectType != GameObjectType.Terrain)
                {
                    return;
                }

                // We are dealing with a mesh or terrain object. Extract the surface info from the 'ObjectHit'
                // field of the raycast hit instance.
                _snapConfig.SurfaceHitNormal = raycastHit.ObjectHit.HitNormal;
                _snapConfig.SurfaceHitPlane  = raycastHit.ObjectHit.HitPlane;
                _snapConfig.SurfaceHitPoint  = raycastHit.ObjectHit.HitPoint;
                _snapConfig.SurfaceObject    = raycastHit.ObjectHit.HitObject;
                _snapConfig.SurfaceType      = objectType == GameObjectType.Mesh ? ObjectSurfaceSnap.Type.Mesh : ObjectSurfaceSnap.Type.UnityTerrain;
            }
            else
            {
                // The scene grid was hit. Extract the surface info from the 'GridHit'
                // field of the raycast hit instance.
                _snapConfig.SurfaceHitNormal = raycastHit.GridHit.HitNormal;
                _snapConfig.SurfaceHitPlane  = raycastHit.GridHit.HitPlane;
                _snapConfig.SurfaceHitPoint  = raycastHit.GridHit.HitPoint;
                _snapConfig.SurfaceType      = ObjectSurfaceSnap.Type.SceneGrid;
            }

            // Call 'ObjectSurfaceSnap.SnapHierarchy' on the target hierarchy and pass the snap config data along.
            // Note: The function requires that we first set the position of the hierarchy to the surface hit point.
            _targetHierarchy.transform.position = _snapConfig.SurfaceHitPoint;
            ObjectSurfaceSnap.SnapHierarchy(_targetHierarchy, _snapConfig);
        }
Ejemplo n.º 2
0
        private void SnapTargetsToSurface()
        {
            if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Invalid)
            {
                return;
            }

            ObjectSurfaceSnap.SnapConfig snapConfig = new ObjectSurfaceSnap.SnapConfig();
            snapConfig.SurfaceHitPoint  = _grabSurfaceInfo.AnchorPoint;
            snapConfig.SurfaceHitNormal = _grabSurfaceInfo.AnchorNormal;
            snapConfig.SurfaceHitPlane  = _grabSurfaceInfo.AnchorPlane;
            snapConfig.SurfaceObject    = _grabSurfaceInfo.SceneRaycastHit.WasAnObjectHit ? _grabSurfaceInfo.SceneRaycastHit.ObjectHit.HitObject : null;

            snapConfig.SurfaceType = ObjectSurfaceSnap.Type.UnityTerrain;
            if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Mesh)
            {
                snapConfig.SurfaceType = ObjectSurfaceSnap.Type.Mesh;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.Grid)
            {
                snapConfig.SurfaceType = ObjectSurfaceSnap.Type.SceneGrid;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.SphericalMesh)
            {
                snapConfig.SurfaceType = ObjectSurfaceSnap.Type.SphericalMesh;
            }
            else if (_grabSurfaceInfo.SurfaceType == GrabSurfaceType.TerrainMesh)
            {
                snapConfig.SurfaceType = ObjectSurfaceSnap.Type.TerrainMesh;
            }

            foreach (GrabTarget grabTarget in _grabTargets)
            {
                if (grabTarget.GameObject == null)
                {
                    continue;
                }
                grabTarget.Transform.position = _grabSurfaceInfo.AnchorPoint + grabTarget.AnchorVector;

                ObjectLayerGrabSettings layerGrabSettings = SharedSettings.GetLayerGrabSettings(grabTarget.GameObject.layer);
                if (layerGrabSettings.IsActive)
                {
                    snapConfig.AlignAxis         = layerGrabSettings.AlignAxis;
                    snapConfig.AlignmentAxis     = layerGrabSettings.AlignmentAxis;
                    snapConfig.OffsetFromSurface = layerGrabSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface;
                }
                else
                {
                    snapConfig.AlignAxis         = SharedSettings.AlignAxis;
                    snapConfig.AlignmentAxis     = SharedSettings.AlignmentAxis;
                    snapConfig.OffsetFromSurface = SharedSettings.DefaultOffsetFromSurface + grabTarget.OffsetFromSurface;
                }

                ObjectSurfaceSnap.SnapResult snapResult = ObjectSurfaceSnap.SnapHierarchy(grabTarget.GameObject, snapConfig);
                if (snapResult.Success)
                {
                    grabTarget.SittingPlane = snapResult.SittingPlane;
                    grabTarget.SittingPoint = snapResult.SittingPoint;
                }
            }
        }