Jump to content
  • Advertisement
Sign in to follow this  
Dark_Light

Off Centre Object In Frustum

This topic is 4812 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

I have built a frustum class and been happily testing it and all has been fine, Until now. I seem to get problems for objects that are not at (0,0,0) World space. The thing is I am passing in the location of objects I wish to test and the tests should take this into account. I am calculating the plains like this!! l_FrustumMatrix = (m_View * m_Projection); //Left m_FrustumSide[5].A = l_FrustumMatrix.M14 + l_FrustumMatrix.M11; m_FrustumSide[5].B = l_FrustumMatrix.M24 + l_FrustumMatrix.M21; m_FrustumSide[5].C = l_FrustumMatrix.M34 + l_FrustumMatrix.M31; m_FrustumSide[5].D = l_FrustumMatrix.M44 + l_FrustumMatrix.M41; //Right m_FrustumSide[4].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M11; m_FrustumSide[4].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M21; m_FrustumSide[4].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M31; m_FrustumSide[4].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M41; //Bottom m_FrustumSide[3].A = l_FrustumMatrix.M14 + l_FrustumMatrix.M12; m_FrustumSide[3].B = l_FrustumMatrix.M24 + l_FrustumMatrix.M22; m_FrustumSide[3].C = l_FrustumMatrix.M34 + l_FrustumMatrix.M32; m_FrustumSide[3].D = l_FrustumMatrix.M44 + l_FrustumMatrix.M42; //Top m_FrustumSide[2].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M12; m_FrustumSide[2].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M22; m_FrustumSide[2].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M32; m_FrustumSide[2].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M42; //Near m_FrustumSide[1].A = l_FrustumMatrix.M13; m_FrustumSide[1].B = l_FrustumMatrix.M23; m_FrustumSide[1].C = l_FrustumMatrix.M33; m_FrustumSide[1].D = l_FrustumMatrix.M43; //Far m_FrustumSide[0].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M13; m_FrustumSide[0].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M23; m_FrustumSide[0].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M33; m_FrustumSide[0].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M43; for (l_Index = 0;l_Index < 6;l_Index ++){ m_FrustumSide[l_Index].Normalize(); } And the Visibility test like this!! public Proximity TestSphere(Vector3 p_Centre,Single p_Radius){ Single l_Distance; Int32 l_Index; for (l_Index = 0;l_Index < 6;l_Index ++){ l_Distance = m_FrustumSide[l_Index].Dot(p_Centre) + m_FrustumSide[l_Index].D; if (l_Distance < -p_Radius){ return Proximity.Outside; }else if (Math.Abs(l_Distance) < p_Radius){ return Proximity.Intersecting; } } return Proximity.Inside; } Just to reiterate this all works when the centre of the object is (0,0,0) No matter where the view points to etc. Thanks in advance for any help

Share this post


Link to post
Share on other sites
Advertisement
I've got a couple of ideas, but first:

1. Could you put the code in [ source ] [ /source ] tags? It's hard to read without indentation.

2. Perhaps you could also post the 'frustum side' class, in particular the 'dot' function.

Share this post


Link to post
Share on other sites
Sure, now i know the tags (:

There is no code for the Dot function.. its c# directx 9
and FrustumSide is an array of plains.




m_FrustumSide = new Plain[6];

l_FrustumMatrix = (m_View * m_Projection);

//Left
m_FrustumSide[5].A = l_FrustumMatrix.M14 + l_FrustumMatrix.M11;
m_FrustumSide[5].B = l_FrustumMatrix.M24 + l_FrustumMatrix.M21;
m_FrustumSide[5].C = l_FrustumMatrix.M34 + l_FrustumMatrix.M31;
m_FrustumSide[5].D = l_FrustumMatrix.M44 + l_FrustumMatrix.M41;

//Right
m_FrustumSide[4].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M11;
m_FrustumSide[4].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M21;
m_FrustumSide[4].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M31;
m_FrustumSide[4].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M41;

//Bottom
m_FrustumSide[3].A = l_FrustumMatrix.M14 + l_FrustumMatrix.M12;
m_FrustumSide[3].B = l_FrustumMatrix.M24 + l_FrustumMatrix.M22;
m_FrustumSide[3].C = l_FrustumMatrix.M34 + l_FrustumMatrix.M32;
m_FrustumSide[3].D = l_FrustumMatrix.M44 + l_FrustumMatrix.M42;

//Top
m_FrustumSide[2].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M12;
m_FrustumSide[2].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M22;
m_FrustumSide[2].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M32;
m_FrustumSide[2].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M42;

//Near
m_FrustumSide[1].A = l_FrustumMatrix.M13;
m_FrustumSide[1].B = l_FrustumMatrix.M23;
m_FrustumSide[1].C = l_FrustumMatrix.M33;
m_FrustumSide[1].D = l_FrustumMatrix.M43;

//Far
m_FrustumSide[0].A = l_FrustumMatrix.M14 - l_FrustumMatrix.M13;
m_FrustumSide[0].B = l_FrustumMatrix.M24 - l_FrustumMatrix.M23;
m_FrustumSide[0].C = l_FrustumMatrix.M34 - l_FrustumMatrix.M33;
m_FrustumSide[0].D = l_FrustumMatrix.M44 - l_FrustumMatrix.M43;

for (l_Index = 0;l_Index < 6;l_Index ++){
m_FrustumSide[l_Index].Normalize();
}






public Proximity TestSphere(Vector3 p_Centre,Single p_Radius){

Single l_Distance;
Int32 l_Index;

for (l_Index = 0;l_Index < 6;l_Index ++){
l_Distance = m_FrustumSide[l_Index].Dot(p_Centre) + m_FrustumSide[l_Index].D;
if (l_Distance < -p_Radius){
return Proximity.Outside;
}else if (Math.Abs(l_Distance) < p_Radius){
return Proximity.Intersecting;
}
}
return Proximity.Inside;
}


Share this post


Link to post
Share on other sites
I'd have to consult the DirectX docs to say for sure, but I'm going to venture a guess. Try changing this:

l_Distance = m_FrustumSide[l_Index].Dot(p_Centre) + m_FrustumSide[l_Index].D;

To:

l_Distance = m_FrustumSide[l_Index].Dot(p_Centre);

I'm thinking that plane.Dot(Vector3) may be of the form:

ax+by+cz+d

And that therefore you don't need to add m_FrustumSide[l_Index].D yourself (and that's what's throwing things off).

Again, without consulting the DirectX docs, this is just a guess on my part.

Share this post


Link to post
Share on other sites
you are correct.

Your sugestion that the dot may be incorrect made me try

l_Distance = m_FrustumSide[l_Index].A * p_Centre.X + m_FrustumSide[l_Index].B * p_Centre.Y + m_FrustumSide[l_Index].C * p_Centre.Z + m_FrustumSide[l_Index].D;

insted of using the .Dot method.

However leaving the D part of also works!! (: (:

Share this post


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

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!