/// <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);
        }
Exemple #2
0
        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()));
        }
Exemple #6
0
        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);
        }
Exemple #7
0
        /// <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;
            }
        }