   Optimized obb-frustum
  Yesterday, after reading  this  and this, I decided to upgrade some old frustum culling code. Not that there is anything wrong with my old “classic” culling but the algorithm in that paper just seems a bit more effective and as they say less naïve. Anyway the problem is that it works fine for AABB, at least I haven't found any problems with it yet, but not for OOBB.According to the paper the only thing you have to do for it to work with OOBBs is projecting the frustum plane normals onto the OOBBs local coordinate axises and use this projected normal when selecting the p and n vertices.So it pretty much looks like this:Construct the OOBB min/max vertices from the OOBB center and extents. Ignoring the orientation, otherwise the selection of n/p vertices wont work right? (of course I have tried both)Foreach frustum plane{   Project plane normal.    projnorm= (x-axis DOT normal, y-axis DOT normal, z-axis DOT normal)   Use the projected normal's xyz-sign to select the right n and p vertices.   Test for intersection. Compute the p-vertex distance to the frustum plane, if negative return false. Else compute the n-vertex distance to the plane and if negative set a flag for intersecting.}return intersecting or trueIn other words exactly as shown in the paper and the lighthouse page.My OBB consists of center, extents and orientation and my frustum consists of 6 planes (normals and d-value, pointing inwards). Both the OBB and the frustum are in worldspace.And the case when this fails is if I have a OBB rotated 45deg around th y-axis (up) and place it behind the frustum near-plane with one corner inside the frustum (in front of the near plane).Maybe I have been poking to long at this, going blind from all debugging data and drawing boxes... Anyway my question is. Have they left something out that is so obvious that it doesn't have to be mentioned and I simply don't realize it? And has anyone actually seen a working implementation of this, I can only find AABB examples?   
Quote:Original post by CalexusSo it pretty much looks like this:Foreach frustum plane{   Project plane normal.    projnorm= (x-axis DOT normal, y-axis DOT normal, z-axis DOT normal)   Use the projected normal's xyz-sign to select the right n and p vertices.   Test for intersection. Compute the p-vertex distance to the frustum plane, if negative return false. Else compute the n-vertex distance to the plane and if negative set a flag for intersecting.}return intersecting or trueI'm not sure how you compute the n and p -vertices here? With OBB's it's a bit different than just choosing obbMinVertex.x or obbMaxVertex.x based on a sign of the dot product. With AABBs that works, but with OBB's just combining the individual components of obbMinVertex and obbMaxVertex won't produce vertices that are any of 8 corner vertices of the OBB. Just double-checking your logic here.Also, my convention of the direction of the plane normal seems to be different than yours. In my system, the normals of the frustum planes point outwards from the frustum polyhedron. In your test code, it seems to assume the opposite. Of course that's just a convention, but I'd check that things go as you assume.Anyways, here's a paste of the function from my library:bool OBBToFrustumIntersect(const OBB &obb, const FrustumVolume &frustum){// Do a SAT test along each frustum axis.// A frustum consists of six planes. Note that as near and far planes are parallel, we could optimize // one iteration away.for(int i = 0; i < 6; i++) {// Find the negative and positive far points of the OBB to the current frustum plane.float x = Dot(obb.axes[0], frustum.planes.normal) >= 0.f ? obb.halfDistances[0] : -obb.halfDistances[0];float y = Dot(obb.axes[1], frustum.planes.normal) >= 0.f ? obb.halfDistances[1] : -obb.halfDistances[1];float z = Dot(obb.axes[2], frustum.planes.normal) >= 0.f ? obb.halfDistances[2] : -obb.halfDistances[2];// There are eight half-diagonal vectors on an OBB. (A half-diagonal is a vector from OBB center to one of its// corner vertices). Compute the half-diagonal vector that points most in the same direction than the plane normal.const float3 diag = x*obb.axes[0] + y*obb.axes[1] + z*obb.axes[2];// nPoint is now the corner point of the OBB that lies "the most" inside the frustum, // its projection on the plane normal extends the most to the negative direction of that normal.const float3 nPoint = obb.center - diag;//const float3 pPoint = obb.center + diag;if (Dot(nPoint, frustum.planes.normal) + frustum.planes.d >= 0.f)return false; // OBB outside frustum.// If we would like to check whether the OBB is fully inside the frustum, need to compute// Dot(pPoint, frustum.planes.normal) + frustum.planes.d. If it's < 0 for all planes, OBB is totally// inside the frustum and doesn't intersect any of the frustum planes.}return true; // OBB inside the frustum or part of the OBB intersects the frustum.}I've precomputed some values of the OBBs. obb.halfDistances are effectively the half-lenghts of the OBB along each of its local main axes. obb.axes areunitary direction vectors that point in world space towards each of the main axes of the OBB.I was not able to directly spot the exact problem in your pseudo, but the fact that you have "Construct the OOBB min/max vertices from the OOBB center and extents." outside the loop is something that I thought a bit odd. If this means that you're just computing the 8 corner points of the OBB, then that's alright. Otherwise, I'd understand that you'd effectively be treating your OBB like an AABB.Hopefully my version of the code gives you another perspective on the method!;  there's a lot cleaner way to test oriented bounding box against frustum planesif box is defined by it's center  and 3 direction vectors spanning the box [vx,vy,vz] then you can test this box against plane like thiscalculate d = distance from box center to the planecalculate sx= absolute value of length of projection of vx on planes normalcalculate sy= absolute value of length of projection of vy on planes normalcalculate sz= absolute value of length of projection of vz on planes normalif d>sx+sy+sz then box is fully on one side of planeif d<-sx-sy-sz box is fully on other side of planeotherwise it intersects plane