private SceneRaycastHit GetSceneHitForGridSnap() { Ray pickRay = RTInputDevice.Get.Device.GetRay(RTFocusCamera.Get.TargetCamera); SceneRaycastFilter raycastFilter = new SceneRaycastFilter(); raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh); return(RTScene.Get.Raycast(pickRay, SceneRaycastPrecision.BestFit, raycastFilter)); }
/// <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); }
private bool IdentifySitSurface() { _sitSurface.SurfaceType = SitSurfaceType.Invalid; SceneRaycastFilter raycastFilter = new SceneRaycastFilter(); if (SharedSettings.CanClimbObjects) { raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh); } foreach (var target in _targetParents) { raycastFilter.IgnoreObjects.AddRange(target.GetAllChildrenAndSelf()); } IInputDevice inputDevice = RTInputDevice.Get.Device; SceneRaycastHit raycastHit = RTScene.Get.Raycast(inputDevice.GetRay(RTFocusCamera.Get.TargetCamera), SceneRaycastPrecision.BestFit, raycastFilter); if (!raycastHit.WasAnythingHit) { return(false); } if (raycastHit.WasAnObjectHit && raycastHit.WasGridHit) { if (raycastHit.ObjectHit.HitEnter < raycastHit.GridHit.HitEnter) { _sitSurface.SitPlane = raycastHit.ObjectHit.HitPlane; _sitSurface.SitPoint = raycastHit.ObjectHit.HitPoint; _sitSurface.SurfaceType = SitSurfaceType.Object; } else { _sitSurface.SitPlane = raycastHit.GridHit.HitPlane; _sitSurface.SitPoint = raycastHit.GridHit.HitPoint; _sitSurface.SurfaceType = SitSurfaceType.Grid; } } else if (raycastHit.WasAnObjectHit) { _sitSurface.SitPlane = raycastHit.ObjectHit.HitPlane; _sitSurface.SitPoint = raycastHit.ObjectHit.HitPoint; _sitSurface.SurfaceType = SitSurfaceType.Object; } else if (raycastHit.WasGridHit) { _sitSurface.SitPlane = raycastHit.GridHit.HitPlane; _sitSurface.SitPoint = raycastHit.GridHit.HitPoint; _sitSurface.SurfaceType = SitSurfaceType.Grid; } return(true); }
public static GameObject SpawnInFrontOfCamera(GameObject sourceObject, Camera camera, Config config) { float halfSize = config.ObjectSize * 0.5f; var boundsQConfig = new ObjectBounds.QueryConfig(); boundsQConfig.ObjectTypes = GameObjectTypeHelper.AllCombined; boundsQConfig.NoVolumeSize = Vector3Ex.FromValue(1.0f); Transform cameraTransform = camera.transform; AABB aabb = ObjectBounds.CalcHierarchyWorldAABB(sourceObject, boundsQConfig); if (!aabb.IsValid) { return(null); } Sphere sphere = new Sphere(aabb); Vector3 fromCenterToPos = sourceObject.transform.position - sphere.Center; float zOffset = Mathf.Max(camera.nearClipPlane + sphere.Radius, sphere.Radius / halfSize); Vector3 spherePos = cameraTransform.position + cameraTransform.forward * zOffset; GameObject spawned = GameObject.Instantiate(sourceObject, spherePos + fromCenterToPos, sourceObject.transform.rotation) as GameObject; spawned.SetActive(true); //VRCTS spawned.name = sourceObject.name; OBB spawnedOBB = ObjectBounds.CalcHierarchyWorldOBB(spawned, boundsQConfig); Ray ray = new Ray(camera.transform.position, (spawnedOBB.Center - camera.transform.position).normalized); var raycastFilter = new SceneRaycastFilter(); raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh); raycastFilter.AllowedObjectTypes.Add(GameObjectType.Terrain); raycastFilter.AllowedObjectTypes.Add(GameObjectType.Sprite); var rayHit = RTScene.Get.Raycast(ray, SceneRaycastPrecision.BestFit, raycastFilter); if (rayHit.WasAnObjectHit) { Vector3 oldCenter = spawnedOBB.Center; spawnedOBB.Center = rayHit.ObjectHit.HitPoint; Vector3 offsetVector = spawnedOBB.Center - oldCenter; offsetVector += ObjectSurfaceSnap.CalculateSitOnSurfaceOffset(spawnedOBB, rayHit.ObjectHit.HitPlane, 0.0f); spawned.transform.position += offsetVector; } return(spawned); }
private bool IdentifyGrabSurface() { _grabSurfaceInfo.SurfaceType = GrabSurfaceType.Invalid; SceneRaycastFilter raycastFilter = new SceneRaycastFilter(); raycastFilter.LayerMask = SharedSettings.SurfaceLayers; if ((SharedSettings.SurfaceFlags & ObjectGrabSurfaceFlags.Mesh) != 0) { raycastFilter.AllowedObjectTypes.Add(GameObjectType.Mesh); } if ((SharedSettings.SurfaceFlags & ObjectGrabSurfaceFlags.Terrain) != 0) { raycastFilter.AllowedObjectTypes.Add(GameObjectType.Terrain); } foreach (GrabTarget grabTarget in _grabTargets) { raycastFilter.IgnoreObjects.AddRange(grabTarget.GameObject.GetAllChildrenAndSelf()); } IInputDevice inputDevice = RTInputDevice.Get.Device; SceneRaycastHit raycastHit = RTScene.Get.Raycast(inputDevice.GetRay(RTFocusCamera.Get.TargetCamera), SceneRaycastPrecision.BestFit, raycastFilter); if (!raycastHit.WasAnythingHit) { return(false); } _grabSurfaceInfo.SceneRaycastHit = raycastHit; if (raycastHit.WasAnObjectHit) { _grabSurfaceInfo.AnchorNormal = raycastHit.ObjectHit.HitNormal; _grabSurfaceInfo.AnchorPoint = raycastHit.ObjectHit.HitPoint; _grabSurfaceInfo.AnchorPlane = raycastHit.ObjectHit.HitPlane; GameObjectType hitObjectType = raycastHit.ObjectHit.HitObject.GetGameObjectType(); if (hitObjectType == GameObjectType.Mesh) { _grabSurfaceInfo.SurfaceType = GrabSurfaceType.Mesh; int objectLayer = raycastHit.ObjectHit.HitObject.layer; if (LayerEx.IsLayerBitSet(SharedSettings.SphericalMeshLayers, objectLayer)) { _grabSurfaceInfo.SurfaceType = GrabSurfaceType.SphericalMesh; } else if (LayerEx.IsLayerBitSet(SharedSettings.TerrainMeshLayers, objectLayer)) { _grabSurfaceInfo.SurfaceType = GrabSurfaceType.TerrainMesh; } } else { _grabSurfaceInfo.SurfaceType = GrabSurfaceType.UnityTerrain; } } else if (raycastHit.WasGridHit && (SharedSettings.SurfaceFlags & ObjectGrabSurfaceFlags.Grid) != 0) { _grabSurfaceInfo.AnchorNormal = raycastHit.GridHit.HitNormal; _grabSurfaceInfo.AnchorPoint = raycastHit.GridHit.HitPoint; _grabSurfaceInfo.AnchorPlane = raycastHit.GridHit.HitPlane; _grabSurfaceInfo.SurfaceType = GrabSurfaceType.Grid; } return(true); }
public List <GameObjectRayHit> RaycastAllObjectsSorted(Ray ray, SceneRaycastPrecision rtRaycastPrecision, SceneRaycastFilter raycastFilter) { if (raycastFilter != null && raycastFilter.AllowedObjectTypes.Count == 0) { return(new List <GameObjectRayHit>()); } List <GameObjectRayHit> sortedHits = RaycastAllObjectsSorted(ray, rtRaycastPrecision); if (raycastFilter != null) { raycastFilter.FilterHits(sortedHits); } return(sortedHits); }
public SceneRaycastHit Raycast(Ray ray, SceneRaycastPrecision rtRaycastPrecision, SceneRaycastFilter raycastFilter) { List <GameObjectRayHit> allObjectHits = RaycastAllObjectsSorted(ray, rtRaycastPrecision, raycastFilter); GameObjectRayHit closestObjectHit = allObjectHits.Count != 0 ? allObjectHits[0] : null; XZGridRayHit gridRayHit = RaycastSceneGridIfVisible(ray); return(new SceneRaycastHit(closestObjectHit, gridRayHit)); }