Avatar billede martinskou Nybegynder
09. november 2001 - 21:07 Der er 7 kommentarer

Skæring mellem trekant og frustum

Hvordan tjeker jeg at en trekant ligger delvis inden mit view-frustum?

Jeg har en funktion somm får fat i frustum (ExtractFrustum()) fra opengl, og en funktion som checker om et punkt er i frustum (PointInFrustum(x,y,z)).

Hvordan checker jeg at blot noget af trekanten med hjørnerne A,B,C ligger indenfor frustum (så den skal tegnes)??
Avatar billede zerohero Nybegynder
10. november 2001 - 16:40 #1
Kender du en funktion som kan fortælle mig om en trekant bliver vist eller ej... Jeg mener når man anvender gl_cull_face og eksempelvis glcullface(gl_front), hvordan kan jeg så få at vide om en trekant bliver renderet eller ej... håber du forstår, hvad jeg mener (Jeg vil gerne give dig points)...
Avatar billede martinskou Nybegynder
11. november 2001 - 10:14 #2
Jeg tror ikke det er noget som man kan få af vide gennem OpenGL. Men det er faktisk såden en funktion som jeg også står og mangler.
Avatar billede martinskou Nybegynder
11. november 2001 - 11:13 #3
Men check lige denne link, manden her en funktion som tester om en cube er i synsfeltet!

http://www.markmorley.com/opengl/frustumculling.html
Avatar billede jpk Nybegynder
11. november 2001 - 15:46 #4
Du kan jo tjekke hver af trekantens 3 punkter
Avatar billede martinskou Nybegynder
12. november 2001 - 08:29 #5
Nope. Alle tre punkter kan sagtens ligge udenfor frustum, selvom en del af trekanten er synlig.
Avatar billede jpk Nybegynder
12. november 2001 - 10:12 #6
Følgende kode anvender DirectX, men jeg er sikker på der findes ekvivalente funktioner i OpenGL...
Her tjekkes ikke på hver enkelt 3-kant, men på en bounding box. Det kan være du kan bruge det til noget.

How it works, every frame I get the D3DVIEWPORT in my HeartBeat function
of my camera and store it.  If I want to check if a BoundingBox is onscreen
or not, I just use my function
BoundingBoxIntersectsFrustum(D3DXVECTOR3 pMin, D3DXVECTOR3) which returns
true if partially or inside the view frustum, or false if totally
outside.  I hope this helps people like it did ME!


enum POINTLOC
{
LEFT,
RIGHT,
ABOVE,
BELOW,
BACK,
FRONT,
INSIDE
};


D3DVIEWPORT8  vp;
D3DXMATRIX  view, proj, world;
POINTLOC  PointToScreen(D3DXVECTOR3 Point3D);


void CCamera::HeartBeat()
{
GetViewport(&vp);
GetTransform(D3DTS_VIEW, &view);
GetTransform(D3DTS_PROJECTION, &proj);
GetTransform(D3DTS_WORLD, &world);
}


POINTLOC CCamera::PointToScreen(D3DXVECTOR3 Point3D)
{
D3DXVECTOR3 Out;
D3DXVec3Project((D3DXVECTOR3*)&Out, &Point3D, &vp, &proj, &view, &world);
if (Out.x < vp.X) return LEFT;
if (Out.y < vp.Y) return ABOVE;
if (Out.x > vp.Width) return RIGHT;
if (Out.y > vp.Height) return BELOW;
if (Out.z < vp.MinZ) return FRONT;
if (Out.z > vp.MaxZ) return BACK;
else return INSIDE;
}


bool CCamera::BoundingBoxIntersectsFrustum(D3DXVECTOR3 pMin, D3DXVECTOR3
pMax)
{
POINTLOC results[8];
// Check Front Top Left
results[0] = PointToScreen(D3DXVECTOR3(pMin.x, pMin.y, pMin.z));
// Check Front Top Right
results[1] = PointToScreen(D3DXVECTOR3(pMax.x, pMin.y, pMin.z));
// Check Front Bottom Left
results[2] = PointToScreen(D3DXVECTOR3(pMin.x, pMax.y, pMin.z));
// Check From Bottom Right
results[3] = PointToScreen(D3DXVECTOR3(pMax.x, pMax.y, pMin.z));
// Check the BACK of the box now
// Check Back Top Left
results[4] = PointToScreen(D3DXVECTOR3(pMin.x, pMin.y, pMax.z));
// Check Back Top Right
results[5] = PointToScreen(D3DXVECTOR3(pMax.x, pMin.y, pMax.z));
// Check Back Bottom Left
results[6] = PointToScreen(D3DXVECTOR3(pMin.x, pMax.y, pMax.z));
// Check Back Bottom Right
results[7] = PointToScreen(D3DXVECTOR3(pMax.x, pMax.y, pMax.z));
// Check if ALL points are visible, if so, this makes it REAL easy
int Encounted = 0;
// Handle the Easiest first, any indea and draw the Bounding Box
for (int i = 0; i < 8; i++)
{
  if (results[i] == INSIDE) return true;
}
// Check if everything is to the right of the screen
for (i = 0; i < 8; i++)
{
  if (results[i] == RIGHT) Encounted++;
}
if (Encounted == 8) return false;
// Check if everything is to the left of the screen
Encounted = 0;
for (i = 0; i < 8; i++)
{
  if (results[i] == LEFT) Encounted++;
}
if (Encounted == 8) return false;
// Check if everything is to the top of the screen
Encounted = 0;
for (i = 0; i < 8; i++)
{
  if (results[i] == ABOVE) Encounted++;
}
if (Encounted == 8) return false;
// Check if everything is BELOW the screen
Encounted = 0;
for (i = 0; i < 8; i++)
{
  if (results[i] == BELOW) Encounted++;
}
if (Encounted == 8) return false;
// Check if everything is BEHIND the screen
Encounted = 0;
for (i = 0; i < 8; i++)
{
  if (results[i] == BACK) Encounted++;
}
if (Encounted == 8) return false;
// Check if everything is BEYOND the screen
Encounted = 0;
for (i = 0; i < 8; i++)
{
  if (results[i] == FRONT) Encounted++;
}
if (Encounted == 8) return false;
return true;
}
Avatar billede jpk Nybegynder
03. april 2002 - 14:13 #7
Har du fundet en løsning på problemet?
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester