OctreeCamera::Visibility OctreeCamera::getVisibility( const AxisAlignedBox &bound ) { // Null boxes always invisible if ( bound.isNull() ) return NONE; // Get centre of the box Vector3 centre = bound.getCenter(); // Get the half-size of the box Vector3 halfSize = bound.getHalfSize(); bool all_inside = true; for ( int plane = 0; plane < 6; ++plane ) { // Skip far plane if infinite view frustum if (plane == FRUSTUM_PLANE_FAR && mFarDist == 0) continue; // This updates frustum planes and deals with cull frustum Plane::Side side = getFrustumPlane(plane).getSide(centre, halfSize); if(side == Plane::NEGATIVE_SIDE) return NONE; // We can't return now as the box could be later on the negative side of a plane. if(side == Plane::BOTH_SIDE) all_inside = false; } if ( all_inside ) return FULL; else return PARTIAL; }
//---------------------------------------------------------------------() void Camera::getCameraToViewportBoxVolume(Real screenLeft, Real screenTop, Real screenRight, Real screenBottom, PlaneBoundedVolume* outVolume, bool includeFarPlane) { outVolume->planes.clear(); if (mProjType == PT_PERSPECTIVE) { // Use the corner rays to generate planes Ray ul = getCameraToViewportRay(screenLeft, screenTop); Ray ur = getCameraToViewportRay(screenRight, screenTop); Ray bl = getCameraToViewportRay(screenLeft, screenBottom); Ray br = getCameraToViewportRay(screenRight, screenBottom); Vector3 normal; // top plane normal = ul.getDirection().crossProduct(ur.getDirection()); normal.normalise(); outVolume->planes.push_back( Plane(normal, getDerivedPosition())); // right plane normal = ur.getDirection().crossProduct(br.getDirection()); normal.normalise(); outVolume->planes.push_back( Plane(normal, getDerivedPosition())); // bottom plane normal = br.getDirection().crossProduct(bl.getDirection()); normal.normalise(); outVolume->planes.push_back( Plane(normal, getDerivedPosition())); // left plane normal = bl.getDirection().crossProduct(ul.getDirection()); normal.normalise(); outVolume->planes.push_back( Plane(normal, getDerivedPosition())); } else { // ortho planes are parallel to frustum planes Ray ul = getCameraToViewportRay(screenLeft, screenTop); Ray br = getCameraToViewportRay(screenRight, screenBottom); updateFrustumPlanes(); outVolume->planes.push_back( Plane(mFrustumPlanes[FRUSTUM_PLANE_TOP].normal, ul.getOrigin())); outVolume->planes.push_back( Plane(mFrustumPlanes[FRUSTUM_PLANE_RIGHT].normal, br.getOrigin())); outVolume->planes.push_back( Plane(mFrustumPlanes[FRUSTUM_PLANE_BOTTOM].normal, br.getOrigin())); outVolume->planes.push_back( Plane(mFrustumPlanes[FRUSTUM_PLANE_LEFT].normal, ul.getOrigin())); } // near & far plane applicable to both projection types outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_NEAR)); if (includeFarPlane) outVolume->planes.push_back(getFrustumPlane(FRUSTUM_PLANE_FAR)); }