Jump to content

  • Log In with Google      Sign In   
  • Create Account

Strange rotation sympton, aabb extents (with video)


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
27 replies to this topic

#21 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 20 March 2013 - 05:51 PM

That sounds okay. The only time you would care about being fully inside is when using hierarchical culling, in which case you could skip any further culling under that node.

Sponsor:

#22 cozzie   Members   -  Reputation: 1776

Like
0Likes
Like

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).



#23 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 21 March 2013 - 06:47 AM

You don't need to count them; any plane intersecting means the box is not fully inside.

#24 cozzie   Members   -  Reputation: 1776

Like
0Likes
Like

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 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 21 March 2013 - 08:53 AM

You just need to think through the logic of this.

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 cozzie   Members   -  Reputation: 1776

Like
0Likes
Like

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 smile.png
 

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 EWClay   Members   -  Reputation: 659

Like
0Likes
Like

Posted 21 March 2013 - 04:39 PM

I can't keep saying this or I'll bore everyone, but you haven't got the logic right.

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 cozzie   Members   -  Reputation: 1776

Like
0Likes
Like

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..






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS