static bool Overlaps(Transform rayOrigin, Collider trigger) { var radius = DirectSelection.GetPointerLength(rayOrigin); var colliders = Physics.OverlapSphere(rayOrigin.position, radius, -1, QueryTriggerInteraction.Collide); foreach (var collider in colliders) { if (collider == trigger) { return(true); } } return(false); }
static bool Overlaps(Transform rayOrigin, Collider trigger) { var radius = DirectSelection.GetPointerLength(rayOrigin); var totalColliders = Physics.OverlapSphereNonAlloc(rayOrigin.position, radius, s_CachedColliders, -1, QueryTriggerInteraction.Collide); for (var colliderIndex = 0; colliderIndex < totalColliders; colliderIndex++) { if (s_CachedColliders[colliderIndex] == trigger) { return(true); } } return(false); }
void Awake() { Nested.evr = this; // Set this once for the convenience of all nested classes ClearDeveloperConsoleIfNecessary(); m_DirectSelection = new DirectSelection(); m_Interfaces = new Interfaces(); m_Menus = new Menus(); m_MiniWorlds = new MiniWorlds(); m_Rays = new Rays(); m_Tools = new Tools(); m_UI = new UI(); m_Viewer = new Viewer(); m_Vacuumables = new Vacuumables(); m_HierarchyModule = AddModule <HierarchyModule>(); m_ProjectFolderModule = AddModule <ProjectFolderModule>(); VRView.cameraRig.parent = transform; // Parent the camera rig under EditorVR VRView.cameraRig.hideFlags = defaultHideFlags; if (VRSettings.loadedDeviceName == "OpenVR") { // Steam's reference position should be at the feet and not at the head as we do with Oculus VRView.cameraRig.localPosition = Vector3.zero; } var hmdOnlyLayerMask = 0; if (m_PreviewCameraPrefab) { var go = ObjectUtils.Instantiate(m_PreviewCameraPrefab); m_CustomPreviewCamera = go.GetComponentInChildren <IPreviewCamera>(); if (m_CustomPreviewCamera != null) { VRView.customPreviewCamera = m_CustomPreviewCamera.previewCamera; m_CustomPreviewCamera.vrCamera = VRView.viewerCamera; hmdOnlyLayerMask = m_CustomPreviewCamera.hmdOnlyLayerMask; m_Interfaces.ConnectInterfaces(m_CustomPreviewCamera); } } VRView.cullingMask = UnityEditor.Tools.visibleLayers | hmdOnlyLayerMask; m_DeviceInputModule = AddModule <DeviceInputModule>(); m_DeviceInputModule.InitializePlayerHandle(); m_DeviceInputModule.CreateDefaultActionMapInputs(); m_DeviceInputModule.processInput = ProcessInput; m_DeviceInputModule.updatePlayerHandleMaps = m_Tools.UpdatePlayerHandleMaps; m_UI.Initialize(); m_KeyboardModule = AddModule <KeyboardModule>(); m_DragAndDropModule = AddModule <DragAndDropModule>(); m_InputModule.rayEntered += m_DragAndDropModule.OnRayEntered; m_InputModule.rayExited += m_DragAndDropModule.OnRayExited; m_InputModule.dragStarted += m_DragAndDropModule.OnDragStarted; m_InputModule.dragEnded += m_DragAndDropModule.OnDragEnded; m_TooltipModule = AddModule <TooltipModule>(); m_Interfaces.ConnectInterfaces(m_TooltipModule); m_InputModule.rayEntered += m_TooltipModule.OnRayEntered; m_InputModule.rayExited += m_TooltipModule.OnRayExited; m_PixelRaycastModule = AddModule <PixelRaycastModule>(); m_PixelRaycastModule.ignoreRoot = transform; m_PixelRaycastModule.raycastCamera = m_UI.eventCamera; m_HighlightModule = AddModule <HighlightModule>(); m_ActionsModule = AddModule <ActionsModule>(); m_LockModule = AddModule <LockModule>(); m_LockModule.updateAlternateMenu = (rayOrigin, o) => m_Menus.SetAlternateMenuVisibility(rayOrigin, o != null); m_SelectionModule = AddModule <SelectionModule>(); m_SelectionModule.selected += m_Rays.SetLastSelectionRayOrigin; // when a selection occurs in the selection tool, call show in the alternate menu, allowing it to show/hide itself. m_SelectionModule.getGroupRoot = GetGroupRoot; m_SpatialHashModule = AddModule <SpatialHashModule>(); m_SpatialHashModule.shouldExcludeObject = go => go.GetComponentInParent <EditorVR>(); m_SpatialHashModule.Setup(); m_IntersectionModule = AddModule <IntersectionModule>(); m_Interfaces.ConnectInterfaces(m_IntersectionModule); m_IntersectionModule.Setup(m_SpatialHashModule.spatialHash); m_Menus.mainMenuTools = m_Tools.allTools.Where(t => !m_Tools.IsPermanentTool(t)).ToList(); // Don't show tools that can't be selected/toggled m_WorkspaceModule = AddModule <WorkspaceModule>(); m_WorkspaceModule.workspaceCreated += m_Vacuumables.OnWorkspaceCreated; m_WorkspaceModule.workspaceCreated += m_MiniWorlds.OnWorkspaceCreated; m_WorkspaceModule.workspaceCreated += (workspace) => { m_DeviceInputModule.UpdatePlayerHandleMaps(); }; m_WorkspaceModule.workspaceDestroyed += m_Vacuumables.OnWorkspaceDestroyed; m_WorkspaceModule.workspaceDestroyed += (workspace) => { m_Interfaces.DisconnectInterfaces(workspace); }; m_WorkspaceModule.workspaceDestroyed += m_MiniWorlds.OnWorkspaceDestroyed; UnityBrandColorScheme.sessionGradient = UnityBrandColorScheme.GetRandomGradient(); m_SceneObjectModule = AddModule <SceneObjectModule>(); m_SceneObjectModule.shouldPlaceObject = (obj, targetScale) => { foreach (var miniWorld in m_MiniWorlds.worlds) { if (!miniWorld.Contains(obj.position)) { continue; } var referenceTransform = miniWorld.referenceTransform; obj.transform.parent = null; obj.position = referenceTransform.position + Vector3.Scale(miniWorld.miniWorldTransform.InverseTransformPoint(obj.position), miniWorld.referenceTransform.localScale); obj.rotation = referenceTransform.rotation * Quaternion.Inverse(miniWorld.miniWorldTransform.rotation) * obj.rotation; obj.localScale = Vector3.Scale(Vector3.Scale(obj.localScale, referenceTransform.localScale), miniWorld.miniWorldTransform.lossyScale); return(false); } return(true); }; m_Viewer.AddPlayerModel(); m_Rays.CreateAllProxies(); // In case we have anything selected at start, set up manipulators, inspector, etc. EditorApplication.delayCall += OnSelectionChanged; }
internal void UpdateMiniWorlds() { if (m_MiniWorldIgnoreListDirty) { UpdateMiniWorldIgnoreList(); m_MiniWorldIgnoreListDirty = false; } var objectsGrabber = evr.GetNestedModule <DirectSelection>().objectsGrabber; var sceneObjectModule = evr.GetModule <SceneObjectModule>(); var viewer = evr.GetNestedModule <Viewer>(); // Update MiniWorldRays foreach (var ray in m_Rays) { var miniWorldRayOrigin = ray.Key; var miniWorldRay = ray.Value; if (!miniWorldRay.proxy.active) { miniWorldRay.tester.active = false; continue; } var miniWorld = miniWorldRay.miniWorld; var inverseScale = miniWorld.miniWorldTransform.lossyScale.Inverse(); if (float.IsInfinity(inverseScale.x) || float.IsNaN(inverseScale.x)) // Extreme scales cause transform errors { continue; } // Transform into reference space var originalRayOrigin = miniWorldRay.originalRayOrigin; var referenceTransform = miniWorld.referenceTransform; var miniWorldTransform = miniWorld.miniWorldTransform; miniWorldRayOrigin.position = referenceTransform.TransformPoint(miniWorldTransform.InverseTransformPoint(originalRayOrigin.position)); miniWorldRayOrigin.rotation = referenceTransform.rotation * Quaternion.Inverse(miniWorldTransform.rotation) * originalRayOrigin.rotation; miniWorldRayOrigin.localScale = Vector3.Scale(inverseScale, referenceTransform.localScale); // Set miniWorldRayOrigin active state based on whether controller is inside corresponding MiniWorld var originalPointerPosition = originalRayOrigin.position + originalRayOrigin.forward * DirectSelection.GetPointerLength(originalRayOrigin); var isContained = miniWorld.Contains(originalPointerPosition); miniWorldRay.tester.active = isContained; miniWorldRayOrigin.gameObject.SetActive(isContained); var directSelectInput = (DirectSelectInput)miniWorldRay.directSelectInput; var dragObjects = miniWorldRay.dragObjects; if (dragObjects == null) { var heldObjects = objectsGrabber.GetHeldObjects(miniWorldRayOrigin); if (heldObjects != null) { // Only one ray can grab an object, otherwise PlaceObject is called on each trigger release // This does not prevent TransformTool from doing two-handed scaling var otherRayHasObject = false; foreach (var otherRay in m_Rays.Values) { if (otherRay != miniWorldRay && otherRay.dragObjects != null) { otherRayHasObject = true; } } if (!otherRayHasObject) { miniWorldRay.dragObjects = heldObjects; var scales = new Vector3[heldObjects.Length]; var dragGameObjects = new GameObject[heldObjects.Length]; for (var i = 0; i < heldObjects.Length; i++) { var dragObject = heldObjects[i]; scales[i] = dragObject.transform.localScale; dragGameObjects[i] = dragObject.gameObject; } var totalBounds = ObjectUtils.GetBounds(dragGameObjects); var maxSizeComponent = totalBounds.size.MaxComponent(); if (!Mathf.Approximately(maxSizeComponent, 0f)) { miniWorldRay.previewScaleFactor = Vector3.one * (k_PreviewScale * Viewer.GetViewerScale() / maxSizeComponent); } miniWorldRay.originalScales = scales; } } } // Transfer objects to and from original ray and MiniWorld ray (e.g. outside to inside mini world) if (isContained != miniWorldRay.wasContained) { var pointerLengthDiff = DirectSelection.GetPointerLength(miniWorldRayOrigin) - DirectSelection.GetPointerLength(originalRayOrigin); var from = isContained ? originalRayOrigin : miniWorldRayOrigin; var to = isContained ? miniWorldRayOrigin : originalRayOrigin; if (isContained || miniWorldRay.dragObjects == null) { objectsGrabber.TransferHeldObjects(from, to, pointerLengthDiff * Vector3.forward); } } // Transfer objects between MiniWorlds if (dragObjects == null) { if (isContained) { foreach (var kvp in m_Rays) { var otherRayOrigin = kvp.Key; var otherRay = kvp.Value; var otherObjects = otherRay.dragObjects; if (otherRay != miniWorldRay && !otherRay.wasContained && otherObjects != null) { dragObjects = otherObjects; miniWorldRay.dragObjects = otherObjects; miniWorldRay.originalScales = otherRay.originalScales; miniWorldRay.previewScaleFactor = otherRay.previewScaleFactor; otherRay.dragObjects = null; var heldObjects = objectsGrabber.GetHeldObjects(otherRayOrigin); if (heldObjects != null) { objectsGrabber.TransferHeldObjects(otherRayOrigin, miniWorldRayOrigin, Vector3.zero); // Set the new offset to zero because the object will have moved (this could be improved by taking original offset into account) } break; } } } } if (isContained && !miniWorldRay.wasContained) { Rays.HideRay(originalRayOrigin, true); Rays.LockRay(originalRayOrigin, this); } if (!isContained && miniWorldRay.wasContained) { Rays.UnlockRay(originalRayOrigin, this); Rays.ShowRay(originalRayOrigin, true); } if (dragObjects == null) { miniWorldRay.wasContained = isContained; continue; } var previewScaleFactor = miniWorldRay.previewScaleFactor; var positionOffsets = miniWorldRay.originalPositionOffsets; var rotationOffsets = miniWorldRay.originalRotationOffsets; var originalScales = miniWorldRay.originalScales; if (directSelectInput.select.isHeld) { if (isContained) { // Scale the object back to its original scale when it re-enters the MiniWorld if (!miniWorldRay.wasContained) { for (var i = 0; i < dragObjects.Length; i++) { var dragObject = dragObjects[i]; dragObject.localScale = originalScales[i]; MathUtilsExt.SetTransformOffset(miniWorldRayOrigin, dragObject, positionOffsets[i], rotationOffsets[i]); } // Add the object (back) to TransformTool objectsGrabber.GrabObjects(miniWorldRay.node, miniWorldRayOrigin, directSelectInput, dragObjects); } } else { // Check for player head for (var i = 0; i < dragObjects.Length; i++) { var dragObject = dragObjects[i]; if (dragObject.CompareTag(k_VRPlayerTag)) { objectsGrabber.DropHeldObjects(miniWorldRayOrigin); // Drop player at edge of MiniWorld miniWorldRay.dragObjects = null; dragObjects = null; break; } } if (dragObjects == null) { continue; } if (miniWorldRay.wasContained) { var containedInOtherMiniWorld = false; foreach (var world in m_Worlds) { if (miniWorld != world && world.Contains(originalPointerPosition)) { containedInOtherMiniWorld = true; } } // Don't switch to previewing the objects we are dragging if we are still in another mini world if (!containedInOtherMiniWorld) { for (var i = 0; i < dragObjects.Length; i++) { var dragObject = dragObjects[i]; // Store the original scale in case the object re-enters the MiniWorld originalScales[i] = dragObject.localScale; dragObject.localScale = Vector3.Scale(dragObject.localScale, previewScaleFactor); } // Drop from TransformTool to take control of object objectsGrabber.DropHeldObjects(miniWorldRayOrigin, out positionOffsets, out rotationOffsets); foreach (var kvp in m_Rays) { var otherRay = kvp.Value; if (otherRay.originalRayOrigin == miniWorldRay.originalRayOrigin) { otherRay.originalPositionOffsets = positionOffsets; otherRay.originalRotationOffsets = rotationOffsets; otherRay.originalScales = originalScales; otherRay.wasHeld = true; } } } for (var i = 0; i < dragObjects.Length; i++) { var dragObject = dragObjects[i]; var rotation = originalRayOrigin.rotation; var position = originalRayOrigin.position + rotation * Vector3.Scale(previewScaleFactor, positionOffsets[i]); MathUtilsExt.LerpTransform(dragObject, position, rotation * rotationOffsets[i]); } } } // Release the current object if the trigger is no longer held if (directSelectInput.select.wasJustReleased) { var rayPosition = originalRayOrigin.position; for (var i = 0; i < dragObjects.Length; i++) { var dragObject = dragObjects[i]; // If the user has pulled an object out of the MiniWorld, use PlaceObject to grow it back to its original scale if (!isContained) { if (viewer.IsOverShoulder(originalRayOrigin)) { sceneObjectModule.DeleteSceneObject(dragObject.gameObject); } else { dragObject.localScale = originalScales[i]; var rotation = originalRayOrigin.rotation; dragObject.position = rayPosition + rotation * positionOffsets[i]; dragObject.rotation = rotation * rotationOffsets[i]; } } } miniWorldRay.dragObjects = null; miniWorldRay.wasHeld = false; } miniWorldRay.wasContained = isContained; } } }