Beispiel #1
0
        /// <summary>
        /// Check if the given bounding box is occluded.
        /// </summary>
        /// <param name="box">A bounding box in local (non deformed) coordinates.</param>
        /// <returns>Returns 'True' if the given bounding box is occluded by the bounding boxes previously added as occluders by <see cref="AddOccluder"/></returns>
        public bool IsOccluded(Box3d box)
        {
            if (!UseHorizonCulling || LocalCameraPosition.z > TerrainQuadRoot.ZMax)
            {
                return(false);
            }

            var corners = new Vector2d[4];
            var plane   = LocalCameraPosition.XY();

            corners[0] = LocalCameraDirection * (new Vector2d(box.xmin, box.ymin) - plane);
            corners[1] = LocalCameraDirection * (new Vector2d(box.xmin, box.ymax) - plane);
            corners[2] = LocalCameraDirection * (new Vector2d(box.xmax, box.ymin) - plane);
            corners[3] = LocalCameraDirection * (new Vector2d(box.xmax, box.ymax) - plane);

            if (corners[0].y <= 0.0 || corners[1].y <= 0.0 || corners[2].y <= 0.0 || corners[3].y <= 0.0)
            {
                return(false);
            }

            var dz = box.zmax - LocalCameraPosition.z;

            corners[0] = new Vector2d(corners[0].x, dz) / corners[0].y;
            corners[1] = new Vector2d(corners[1].x, dz) / corners[1].y;
            corners[2] = new Vector2d(corners[2].x, dz) / corners[2].y;
            corners[3] = new Vector2d(corners[3].x, dz) / corners[3].y;

            var xmin = Math.Min(Math.Min(corners[0].x, corners[1].x), Math.Min(corners[2].x, corners[3].x)) * 0.33 + 0.5;
            var xmax = Math.Max(Math.Max(corners[0].x, corners[1].x), Math.Max(corners[2].x, corners[3].x)) * 0.33 + 0.5;
            var zmax = Math.Max(Math.Max(corners[0].y, corners[1].y), Math.Max(corners[2].y, corners[3].y));

            var imin = Math.Max((int)Math.Floor(xmin * HORIZON_SIZE), 0);
            var imax = Math.Min((int)Math.Ceiling(xmax * HORIZON_SIZE), HORIZON_SIZE - 1);

            for (int i = imin; i <= imax; ++i)
            {
                if (zmax > Horizon[i])
                {
                    return(false);
                }
            }

            return(imax >= imin);
        }
Beispiel #2
0
        public LocalCameraPosition GetPosition()
        {
            LocalCameraPosition ret = VidyoLocalCameraGetPositionNative(objPtr);

            return(ret);
        }
Beispiel #3
0
        /// <summary>
        /// Adds the given bounding box as an occluder. The bounding boxes must be added in front to back order.
        /// </summary>
        /// <param name="occluder">A bounding box in local (non deformed) coordinates.</param>
        /// <returns>Returns 'True' if the given bounding box is occluded by the bounding boxes previously added as occluders by this method.</returns>
        public bool AddOccluder(Box3d occluder)
        {
            if (!UseHorizonCulling || LocalCameraPosition.z > TerrainQuadRoot.ZMax)
            {
                return(false);
            }

            var corners = new Vector2d[4];
            var plane   = LocalCameraPosition.XY();

            corners[0] = LocalCameraDirection * (new Vector2d(occluder.xmin, occluder.ymin) - plane);
            corners[1] = LocalCameraDirection * (new Vector2d(occluder.xmin, occluder.ymax) - plane);
            corners[2] = LocalCameraDirection * (new Vector2d(occluder.xmax, occluder.ymin) - plane);
            corners[3] = LocalCameraDirection * (new Vector2d(occluder.xmax, occluder.ymax) - plane);

            if (corners[0].y <= 0.0 || corners[1].y <= 0.0 || corners[2].y <= 0.0 || corners[3].y <= 0.0)
            {
                // Skips bounding boxes that are not fully behind the "near plane" of the reference frame used for horizon occlusion culling
                return(false);
            }

            var dzmin = occluder.zmin - LocalCameraPosition.z;
            var dzmax = occluder.zmax - LocalCameraPosition.z;

            var bounds = new Vector3d[4];

            bounds[0] = new Vector3d(corners[0].x, dzmin, dzmax) / corners[0].y;
            bounds[1] = new Vector3d(corners[1].x, dzmin, dzmax) / corners[1].y;
            bounds[2] = new Vector3d(corners[2].x, dzmin, dzmax) / corners[2].y;
            bounds[3] = new Vector3d(corners[3].x, dzmin, dzmax) / corners[3].y;

            var xmin = Math.Min(Math.Min(bounds[0].x, bounds[1].x), Math.Min(bounds[2].x, bounds[3].x)) * 0.33 + 0.5;
            var xmax = Math.Max(Math.Max(bounds[0].x, bounds[1].x), Math.Max(bounds[2].x, bounds[3].x)) * 0.33 + 0.5;
            var zmin = Math.Min(Math.Min(bounds[0].y, bounds[1].y), Math.Min(bounds[2].y, bounds[3].y));
            var zmax = Math.Max(Math.Max(bounds[0].z, bounds[1].z), Math.Max(bounds[2].z, bounds[3].z));

            var imin = Math.Max((int)Math.Floor(xmin * HORIZON_SIZE), 0);
            var imax = Math.Min((int)Math.Ceiling(xmax * HORIZON_SIZE), HORIZON_SIZE - 1);

            // First checks if the bounding box projection is below the current horizon line
            var occluded = (imax >= imin);

            for (int i = imin; i <= imax; ++i)
            {
                if (zmax > Horizon[i])
                {
                    occluded = false;

                    break;
                }
            }

            if (!occluded)
            {
                // If it is not, updates the horizon line with the projection of this bounding box
                imin = Math.Max((int)Math.Ceiling(xmin * HORIZON_SIZE), 0);
                imax = Math.Min((int)Math.Floor(xmax * HORIZON_SIZE), HORIZON_SIZE - 1);

                for (int i = imin; i <= imax; ++i)
                {
                    Horizon[i] = (float)Math.Max(Horizon[i], zmin);
                }
            }

            return(occluded);
        }