/// <summary> /// Returns a list of game objects which are visible to the specified camera. /// </summary> /// <remarks> /// This function detects only objects which have a collider attached to them. /// </remarks> public static List <GameObject> GetVisibleGameObjects(this Camera camera) { // We need the camera view volume to detect the visible game objects var cameraViewVolume = new CameraViewVolume(); cameraViewVolume.BuildForCamera(camera, camera.farClipPlane); // In order to detect the visible game objects, we will loop through all POTTENTIALLY visible // game objects and check if their AABB lies inside the camera frustum. List <GameObject> pottentiallyVisibleGameObjects = camera.GetPottentiallyVisibleGameObjects(); var visibleGameObjects = new List <GameObject>(pottentiallyVisibleGameObjects.Count); // Set initial capacity to avoid resize foreach (GameObject gameObject in pottentiallyVisibleGameObjects) { // If the game object's world space AABB intersects the camera frustum, it means it is visible Box worldSpaceAABB = gameObject.GetWorldBox(); if (worldSpaceAABB.IsInvalid()) { continue; } if (cameraViewVolume.ContainsWorldSpaceAABB(worldSpaceAABB.ToBounds())) { visibleGameObjects.Add(gameObject); } } // Return the visible objects list to the caller return(visibleGameObjects); }
public static void DrawGridLines(float cellSizeX, float cellSizeZ, Camera camera, Material material, Color color) { CameraViewVolume viewVolume = camera.GetViewVolume(camera.farClipPlane); Bounds volumeAABB = viewVolume.AABB; float minX = volumeAABB.min.x; float minZ = volumeAABB.min.z; float maxX = volumeAABB.max.x; float maxZ = volumeAABB.max.z; float halfCellSizeX = 0.5f * cellSizeX; float halfCellSizeZ = 0.5f * cellSizeZ; int minCellX = Mathf.FloorToInt((minX + halfCellSizeX) / cellSizeX) - 1; int maxCellX = Mathf.FloorToInt((maxX + halfCellSizeX) / cellSizeX) + 1; int minCellZ = Mathf.FloorToInt((minZ + halfCellSizeZ) / cellSizeZ) - 1; int maxCellZ = Mathf.FloorToInt((maxZ + halfCellSizeZ) / cellSizeZ) + 1; material.SetColor("_Color", color); material.SetPass(0); int minCellIndex = minCellX < minCellZ ? minCellX : minCellZ; int maxCellIndex = maxCellX > maxCellZ ? maxCellX : maxCellZ; GL.Begin(GL.LINES); float startZ = minCellIndex * cellSizeZ; float endZ = (maxCellIndex + 1) * cellSizeZ; float startX = minCellIndex * cellSizeX; float endX = (maxCellIndex + 1) * cellSizeX; for (int cell = minCellIndex; cell <= maxCellIndex; ++cell) { Vector3 xOffset = cell * Vector3.right * cellSizeX; GL.Vertex(xOffset + Vector3.forward * startZ); GL.Vertex(xOffset + Vector3.forward * endZ); Vector3 zOffset = cell * Vector3.forward * cellSizeZ; GL.Vertex(zOffset + Vector3.right * startX); GL.Vertex(zOffset + Vector3.right * endX); } /* * float startZ = minCellZ * cellSizeZ; * float endZ = (maxCellZ + 1) * cellSizeZ; * for (int x = minCellX; x <= maxCellX; ++x) * { * Vector3 xOffset = x * Vector3.right * cellSizeX; * GL.Vertex(xOffset + Vector3.forward * startZ); * GL.Vertex(xOffset + Vector3.forward * endZ); * } * * float startX = minCellX * cellSizeX; * float endX = (maxCellX + 1) * cellSizeX; * for (int z = minCellZ; z <= maxCellZ; ++z) * { * Vector3 zOffset = z * Vector3.forward * cellSizeZ; * GL.Vertex(zOffset + Vector3.right * startX); * GL.Vertex(zOffset + Vector3.right * endX); * }*/ GL.End(); }
/// <summary> /// Returns a list of game objects which COULD be visible to the specified camera. Essentially, /// the function gathers the game objects which sit around the camera and which might be visible /// when rendered. /// </summary> /// <remarks> /// This function detects only objects which have a collider attached to them. /// </remarks> private static List <GameObject> GetPottentiallyVisibleGameObjects(this Camera camera) { CameraViewVolume cameraViewVolume = camera.GetViewVolume(); Box viewVolumeBox = Box.FromBounds(cameraViewVolume.AABB); return(EditorScene.Instance.OverlapBox(viewVolumeBox)); }
public static CameraViewVolume GetViewVolume(this Camera camera, float desiredFarClipPlane) { // Create the view volume var viewVolume = new CameraViewVolume(); viewVolume.BuildForCamera(camera, desiredFarClipPlane); // Return the view volume to the caller return(viewVolume); }
public static bool IsGameObjectVisible(this Camera camera, GameObject gameObject) { var cameraViewVolume = new CameraViewVolume(); cameraViewVolume.BuildForCamera(camera, camera.farClipPlane); Box worldSpaceAABB = gameObject.GetWorldBox(); if (worldSpaceAABB.IsInvalid()) { return(false); } return(cameraViewVolume.ContainsWorldSpaceAABB(worldSpaceAABB.ToBounds())); }
public void OnCameraUpdate(Camera camera, bool isDoingPerspectiveSwitch) { Transform cameraTransform = camera.transform; Transform bkTransform = GetBkGameObject().transform; bkTransform.position = cameraTransform.position + cameraTransform.forward * camera.farClipPlane * 0.98f; bkTransform.rotation = cameraTransform.rotation; bkTransform.parent = null; CameraViewVolume viewVolume = camera.GetViewVolume(); bkTransform.localScale = isDoingPerspectiveSwitch ? new Vector3(9999.0f, 9999.0f, 1.0f) : new Vector3(viewVolume.FarPlaneSize.x, viewVolume.FarPlaneSize.y, 1.0f); bkTransform.parent = cameraTransform; Material material = MaterialPool.Instance.GradientCameraBk; material.SetVector("_TopColor", _topColor); material.SetVector("_BottomColor", _bottomColor); material.SetFloat("_GradientOffset", _gradientOffset); material.SetFloat("_Height", bkTransform.localScale.y); }
/// <summary> /// Calculates and returns the edge rays which connect the points of the specified camera /// view volume. /// </summary> public static Ray3D[] CalculateWorldSpaceVolumeEdgeRays(CameraViewVolume cameraViewVolume) { var worldSpaceVolumeEdgeRays = new Ray3D[12]; // Calculate the rays that connect the points on the near plane worldSpaceVolumeEdgeRays[0] = new Ray3D(cameraViewVolume.TopLeftPointOnNearPlane, cameraViewVolume.TopRightPointOnNearPlane - cameraViewVolume.TopLeftPointOnNearPlane); worldSpaceVolumeEdgeRays[1] = new Ray3D(cameraViewVolume.TopRightPointOnNearPlane, cameraViewVolume.BottomRightPointOnNearPlane - cameraViewVolume.TopRightPointOnNearPlane); worldSpaceVolumeEdgeRays[2] = new Ray3D(cameraViewVolume.BottomRightPointOnNearPlane, cameraViewVolume.BottomLeftPointOnNearPlane - cameraViewVolume.BottomRightPointOnNearPlane); worldSpaceVolumeEdgeRays[3] = new Ray3D(cameraViewVolume.BottomLeftPointOnNearPlane, cameraViewVolume.TopLeftPointOnNearPlane - cameraViewVolume.BottomLeftPointOnNearPlane); // Calculate the rays that connect the points on the far plane worldSpaceVolumeEdgeRays[4] = new Ray3D(cameraViewVolume.TopLeftPointOnFarPlane, cameraViewVolume.TopRightPointOnFarPlane - cameraViewVolume.TopLeftPointOnFarPlane); worldSpaceVolumeEdgeRays[5] = new Ray3D(cameraViewVolume.TopRightPointOnFarPlane, cameraViewVolume.BottomRightPointOnFarPlane - cameraViewVolume.TopRightPointOnFarPlane); worldSpaceVolumeEdgeRays[6] = new Ray3D(cameraViewVolume.BottomRightPointOnFarPlane, cameraViewVolume.BottomLeftPointOnFarPlane - cameraViewVolume.BottomRightPointOnFarPlane); worldSpaceVolumeEdgeRays[7] = new Ray3D(cameraViewVolume.BottomLeftPointOnFarPlane, cameraViewVolume.TopLeftPointOnFarPlane - cameraViewVolume.BottomLeftPointOnFarPlane); // Calculate the rays that connect the points between the near and far planes worldSpaceVolumeEdgeRays[8] = new Ray3D(cameraViewVolume.TopLeftPointOnNearPlane, cameraViewVolume.TopLeftPointOnFarPlane - cameraViewVolume.TopLeftPointOnNearPlane); worldSpaceVolumeEdgeRays[9] = new Ray3D(cameraViewVolume.TopRightPointOnNearPlane, cameraViewVolume.TopRightPointOnFarPlane - cameraViewVolume.TopRightPointOnNearPlane); worldSpaceVolumeEdgeRays[10] = new Ray3D(cameraViewVolume.BottomRightPointOnNearPlane, cameraViewVolume.BottomRightPointOnFarPlane - cameraViewVolume.BottomRightPointOnNearPlane); worldSpaceVolumeEdgeRays[11] = new Ray3D(cameraViewVolume.BottomLeftPointOnNearPlane, cameraViewVolume.BottomLeftPointOnFarPlane - cameraViewVolume.BottomLeftPointOnNearPlane); return(worldSpaceVolumeEdgeRays); }
/// <summary> /// Called every frame to perform any necessary updates. /// </summary> private void Update() { if (RuntimeEditorApplication.Instance.UseCustomCamera) { _camera.enabled = false; } // Reset the mouse cursor position in the previous frame in order to make sure we don't // get wild offset values which will cause unwanted effects. if (_applicationJustGainedFocus) { _applicationJustGainedFocus = false; _mouse.ResetCursorPositionInPreviousFrame(); } // Make sure the mouse has its information updated for the current frame update _mouse.UpdateInfoForCurrentFrame(); // Only process input if we are not using a custom camera if (!RuntimeEditorApplication.Instance.UseCustomCamera) { if (_focusOnSelectionShortcut.IsActiveInCurrentFrame()) { FocusOnSelection(); } //added by me if (toolBarController.isFocusing) { FocusOnSelection(); toolBarController.isFocusing = false; } // if (_zoomSettings.IsZoomEnabled) { ApplyCameraZoomBasedOnUserInput(); } PanCameraBasedOnUserInput(); RotateCameraBasedOnUserInput(); MoveCameraBasedOnUserInput(); } if (Camera.orthographic) { Camera.nearClipPlane = 0.000001f; // Adjust the near plane such that it doesn't intersect the grid. Otherwise, it cuts // away from it and it looks painfully ugly :) CameraViewVolume viewVolume = Camera.GetViewVolume(); var nearPlanePoints = new List <Vector3>(); nearPlanePoints.Add(viewVolume.TopLeftPointOnNearPlane); nearPlanePoints.Add(viewVolume.TopRightPointOnNearPlane); nearPlanePoints.Add(viewVolume.BottomLeftPointOnNearPlane); nearPlanePoints.Add(viewVolume.BottomRightPointOnNearPlane); Plane xzGridPlane = RuntimeEditorApplication.Instance.XZGrid.Plane; if (!xzGridPlane.AreAllPointsInFrontOrBehindPlane(nearPlanePoints)) { Vector3 pivotPoint = Vector3.zero; float dot = Vector3.Dot(xzGridPlane.normal, Camera.transform.forward); if (dot > 0.0f) { xzGridPlane.GetFurthestPointInFront(nearPlanePoints, out pivotPoint); } else if (dot < 0.0f) { xzGridPlane.GetFurthestPointBehind(nearPlanePoints, out pivotPoint); } if (dot != 0.0f) { Ray ray = new Ray(pivotPoint, -Camera.transform.forward); float t; if (xzGridPlane.Raycast(ray, out t)) { Vector3 intersectPt = ray.GetPoint(t); float distance = (intersectPt - pivotPoint).magnitude; Camera.nearClipPlane -= distance; } } } } else { Camera.nearClipPlane = _initialNearClipPlane; } _background.OnCameraUpdate(Camera, _isDoingPerspectiveSwitch); if (_transform.hasChanged) { SetObjectVisibilityDirty(); _transform.hasChanged = false; } }