• Advertisement
Sign in to follow this  

Strange rotation sympton, aabb extents (with video)

This topic is 1765 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement