**0**

# Strange rotation sympton, aabb extents (with video)

###
#22
Members - Reputation: **1764**

Posted 21 March 2013 - 04:29 AM

Thanks, if I understand correct I now loop through all planes, till I find a plane where both extents of the OBB are outside a plane.

If so I return OUTSIDE. If all planes are processed and it's not fully outside, I return INTERSECT. Meaning that it could be either fully inside or partially inside/ intersecting with at least 1 plane.

To get this information I think I need to keep track of how many planes return inside based on d being > s.

If it's 6 in the end, the OBB is fully inside. Is this correct?

If so, I'll decide to implement it right away or later on when I'm introducing hierarchical culling (planned to do that not far from now).

###
#24
Members - Reputation: **1764**

Posted 21 March 2013 - 07:29 AM

OK, then I'm not sure if I get it.

Original approach:

loop through planes

if d > s, return inside

if d < -s, return outside

if not returned after 6 planes

return intersect

When I do this, the result is only correct for 1 of the 6 planes (1st one processed). If I take out "if d > s return inside", the result is as aspected. But then I don't know if it's fully inside or intersecting (only returns outside or intersect at the end).

What I don't get is how I could then differ between inside or intersect (putting back if d > s return inside will stop checking the rest of the planes to early).

###
#25
Members - Reputation: **659**

Posted 21 March 2013 - 08:53 AM

If the box is fully outside any plane, no further planes need to be tested and you can return OUTSIDE immediately.

Any plane intersecting means the box is not fully inside, but you can't return INTERSECT until all the planes have been tested because one of them might still cull the box.

###
#26
Members - Reputation: **1764**

Posted 21 March 2013 - 01:44 PM

Thanks, I understand the logic and just debugged quite a bit again.

I saved the result per plane for 3 situations (without stopping the loop), fully inside, outside and intersecting.

Mesh fully inside = OK:

Plane: 0

d > s: Return INSIDE

Plane: 1

d > s: Return INSIDE

Plane: 2

d > s: Return INSIDE

Plane: 3

d > s: Return INSIDE

Plane: 4

d > s: Return INSIDE

Plane: 5

d > s: Return INSIDE

'Live" it will stop after the 1st plane returning fully INSIDE.

Mesh intersecting = Not OK

Plane: 0

d > s: Return INSIDE

Plane: 1

Plane: 2

d > s: Return INSIDE

Plane: 3

d > s: Return INSIDE

Plane: 4

d > s: Return INSIDE

Plane: 5

d > s: Return INSIDE

'Live' it will stop after the 1st plane returning fully INSIDE, although it isn't, based on the 2nd plane.

Mesh fully outside = Not OK

The results is that only 1 plane returns 'outside'.

Plane: 0

d > s: Return INSIDE

Plane: 1

d > s: Return INSIDE

Plane: 2

d < -s: Return OUTSIDE

Plane: 3

d > s: Return INSIDE

Plane: 4

d > s: Return INSIDE

Plane: 5

d > s: Return INSIDE

Will be debugging more

Most likely it has to do with calculating 's', since it's always 4.9 or 5.0f, which is strange..

**Edited by cozzie, 21 March 2013 - 02:39 PM.**

###
#27
Members - Reputation: **659**

Posted 21 March 2013 - 04:39 PM

The only value you can return from inside the loop is OUTSIDE, when a plane rejects the box. If any plane intersected the box return INTERSECT after checking all the planes. Otherwise return INSIDE.

You seem to expect all planes to return outside if the box is outside the frustum. That's not right. It only takes one to reject it.

###
#28
Members - Reputation: **1764**

Posted 21 March 2013 - 04:53 PM

Sorry, I was blind staring on this approach:

"If the box centre is c, the box axes are ax, ay, az, and the sizes on each axis are sx, sy, sz, then:

d = dot(c, plane)

s = abs(dot(ax, plane)) * sx + abs(dot(ay, plane)) * sy + abs(dot(az, plane)) * sz

If d > s not culled

If d < -s culled

Otherwise intersects."

Got it all working now, with the code below.

Just drawn it out (litterly with a pretty ugly drawing ) to make sure I get it:

- if the OBB is behind/ in negative halfspace of a plane, directly return outside

(since the OBB cannot be behind more then one plane)

- because the OBB can intersect with more then one plane, I just mark that I found a plane where it intersected

- in the end I check if there were any planes that intersected, if so, return intersected

- if there were no planes intersecting and it didn't return outside, then it's definately fully inside

- it's not possible to determine if it's completely inside without checking all planes

- even if I didn't want a different result for intersecting and fully inside, I would need to go through all planes

(unless the object is behind one of the planes)

int CD3dcam::OBBInFrustum(BOUNDINGBOX *pBoundingBox, D3DXMATRIX *pWorldMatrix) { int _result = 99; mAx = D3DXVECTOR3(pWorldMatrix->_11, pWorldMatrix->_12, pWorldMatrix->_13); mAy = D3DXVECTOR3(pWorldMatrix->_21, pWorldMatrix->_22, pWorldMatrix->_23); mAz = D3DXVECTOR3(pWorldMatrix->_31, pWorldMatrix->_32, pWorldMatrix->_33); float d, s; for(int i=0;i<6;++i) { d = D3DXPlaneDotCoord(&mFrustumPlane[i], &pBoundingBox->OBBcenter); s = fabs (D3DXVec3Dot(&mAx, &D3DXVECTOR3(mFrustumPlane[i].a, mFrustumPlane[i].b, mFrustumPlane[i].c)) * pBoundingBox->OBBsize.x / 2.0f) + fabs (D3DXVec3Dot(&mAy, &D3DXVECTOR3(mFrustumPlane[i].a, mFrustumPlane[i].b, mFrustumPlane[i].c)) * pBoundingBox->OBBsize.y / 2.0f) + fabs (D3DXVec3Dot(&mAz, &D3DXVECTOR3(mFrustumPlane[i].a, mFrustumPlane[i].b, mFrustumPlane[i].c)) * pBoundingBox->OBBsize.z / 2.0f); if(d < -s) return OUTSIDE; if(d+ -s < 0) _result = INTERSECT; } if(_result == INTERSECT) return INTERSECT; else return INSIDE; }

There's possibly some optimization possible, but finally it all works

Thanks for all the help and blind staring now and then..