Off Centre Object In Frustum
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
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.
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.
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.
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);//Leftm_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;//Rightm_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;//Bottomm_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;//Topm_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;//Nearm_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;//Farm_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;}
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.
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.
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!! (: (:
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!! (: (:
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement