/// <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); }
public LocalCameraPosition GetPosition() { LocalCameraPosition ret = VidyoLocalCameraGetPositionNative(objPtr); return(ret); }
/// <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); }