project, clip and test bbox
| 281 | |
| 282 | // project, clip and test bbox |
| 283 | bool Occlusion::TestBBox(const Matrix4& trans, const Vector3* minMax, ClipFlags clip) const |
| 284 | { |
| 285 | Matrix4 camTransform = GScene->ScaledInvTransform() * trans; |
| 286 | |
| 287 | // first of all check center of object (VZero) |
| 288 | // if this is not occluded, whole object must be checked/rendered |
| 289 | |
| 290 | // calculate 8 bbox corners in camera coordinates |
| 291 | |
| 292 | const float minZRequired = GScene->GetCamera()->ClipNear() * 10; |
| 293 | |
| 294 | Vector3 min(+1e10, +1e10, +1e10), max(-1e10, -1e10, -1e10); |
| 295 | Vector3 cCorners[2][2][2]; |
| 296 | Vector3 sCorners[2][2][2]; |
| 297 | for (int lr = 0; lr < 2; lr++) |
| 298 | { |
| 299 | for (int ud = 0; ud < 2; ud++) |
| 300 | { |
| 301 | for (int fb = 0; fb < 2; fb++) |
| 302 | { |
| 303 | // get bbox corner in model coordinates |
| 304 | Vector3 mCorner = MinMaxCorner(minMax, lr, ud, fb); |
| 305 | Vector3& cCorner = cCorners[lr][ud][fb]; |
| 306 | Vector3& sCorner = sCorners[lr][ud][fb]; |
| 307 | |
| 308 | // convert to camera coordinates |
| 309 | cCorner.SetFastTransform(camTransform, mCorner); |
| 310 | // some point is very close - we have to draw it |
| 311 | if (cCorner.Z() < minZRequired) |
| 312 | { |
| 313 | return true; |
| 314 | } |
| 315 | |
| 316 | // calculate screen space |
| 317 | float invZ = 1 / cCorner.Z(); |
| 318 | sCorner[0] = cCorner.X() * invZ; |
| 319 | sCorner[1] = cCorner.Y() * invZ; |
| 320 | sCorner[2] = cCorner.Z(); |
| 321 | |
| 322 | saturateMin(min[0], sCorner[0]), saturateMax(max[0], sCorner[0]); |
| 323 | saturateMin(min[1], sCorner[1]), saturateMax(max[1], sCorner[1]); |
| 324 | saturateMin(min[2], sCorner[2]); // we are not interested in min. z |
| 325 | // saturateMax(max[2],sCorner[2]); |
| 326 | } |
| 327 | } |
| 328 | } |
| 329 | // check rectangle min.x,min.y .. max.x,maxy , with z min.z |
| 330 | // check |
| 331 | // render all 6 faces - will check only 3 faces (back face culling) |
| 332 | // if any point is visible, whole object must be rendered |
| 333 | // calculate screen space conservative minmax |
| 334 | // use minimal z, get minmax x,y |
| 335 | |
| 336 | return TestProjectedBBox(min, max); |
| 337 | } |
| 338 | |
| 339 | // render projected triangle to debug window |
| 340 | void Occlusion::DebugPoly(const OcclusionPoly& poly, DebugPixel color) const |
no test coverage detected