 |
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 13.01.2004, 15:48 Titel: Unterschied zwischen Koll.-Routinen Poly -- Line |
|
|
ist zwar relativ viel code, aber ich wüsste nur gerne, worin der unterschied liegt, bzw. was die zweite funktion macht...und ob es sinnvoll (in bezug auf performance, etc.) ist sie zu implementieren. die ist übrigens direkt aus dem sample 'Cull'.
hier mal die erste funktion:
die ist von mir, funktioniert noch nicht ganz, soll aber generell mal testen, ob der punkt die vom poly aufgespannte ebene schneidet, dann entlang der edges des polys ebenen aufziehen und die relation des schnittpunktes zu den ebenen checken.
Code: |
MLE_API bool mleLineHitsTriangle(D3DXVECTOR3* pvEdgeA,
D3DXVECTOR3* pvEdgeB,
D3DXVECTOR3* pvTriA,
D3DXVECTOR3* pvTriB,
D3DXVECTOR3* pvTriC,
D3DXVECTOR3* pvOut) // =NULL
{
D3DXVECTOR3 vIntersection;
D3DXPLANE Plane;
// die ebene des dreiecks berechnen
D3DXPlaneFromPoints(&Plane, pvTriA, pvTriB, pvTriC);
// wenn sie die ebene nicht schneidet, kann sie das dreieck nicht schneiden
if (D3DXPlaneIntersectLine(&vIntersection, &Plane, pvEdgeA, pvEdgeB) == NULL)
return false;
D3DXVECTOR3 vTemp, vDir, vPlaneNorm;
vPlaneNorm.x = Plane.a;
vPlaneNorm.y = Plane.b;
vPlaneNorm.z = Plane.c;
//normalvektor der ebene aus normalvektor des planes und erstem edge errechnen
vDir = *pvTriA - *pvTriB;
D3DXVec3Cross(&vTemp, &vDir, &vPlaneNorm);
// eine ebene entlang der edge erstellen
D3DXPlaneFromPointNormal(&Plane, pvTriA, &vTemp);
// punkt in ebenengleichung einsetzen, wenn < 0 liegt der punkt hinter der ebenen -> ausserhalb des dreiecks
if (D3DXPlaneDotCoord(&Plane, &vIntersection) < 0.0f)
return false;
// 2.te ebene
vDir = *pvTriB - *pvTriC;
D3DXVec3Cross(&vTemp, &vDir, &vPlaneNorm);
D3DXPlaneFromPointNormal(&Plane, pvTriB, &vTemp);
if (D3DXPlaneDotCoord(&Plane, &vIntersection) < 0.0f)
return false;
// 3.te ebene
vDir = *pvTriC - *pvTriA;
D3DXVec3Cross(&vTemp, &vDir, &vPlaneNorm);
D3DXPlaneFromPointNormal(&Plane, pvTriC, &vTemp);
if (D3DXPlaneDotCoord(&Plane, &vIntersection) < 0.0f)
return false;
// alles tests fertig, die linie scheidet das polygon!
if (pvOut != NULL)
*pvOut = vIntersection;
return true;
} |
und hier die 2.te funktion (aus dem sample) um die es mir eigentlich geht:
Code: |
//-----------------------------------------------------------------------------
// Name: EdgeIntersectsFace()
// Desc: Determine if the edge bounded by the two vectors in pEdges intersects
// the quadrilateral described by the four vectors in pFacePoints.
// Note: pPlane could be derived from pFacePoints using
// D3DXPlaneFromPoints, but it is precomputed in advance for greater
// speed.
//-----------------------------------------------------------------------------
BOOL EdgeIntersectsFace( D3DXVECTOR3* pEdges, D3DXVECTOR3* pFacePoints,
D3DXPLANE* pPlane )
{
// If both edge points are on the same side of the plane, the edge does
// not intersect the face
FLOAT fDist1;
FLOAT fDist2;
fDist1 = pPlane->a * pEdges[0].x + pPlane->b * pEdges[0].y +
pPlane->c * pEdges[0].z + pPlane->d;
fDist2 = pPlane->a * pEdges[1].x + pPlane->b * pEdges[1].y +
pPlane->c * pEdges[1].z + pPlane->d;
if( fDist1 > 0 && fDist2 > 0 ||
fDist1 < 0 && fDist2 < 0 )
{
return FALSE;
}
// Find point of intersection between edge and face plane (if they're
// parallel, edge does not intersect face and D3DXPlaneIntersectLine
// returns NULL)
D3DXVECTOR3 ptIntersection;
if( NULL == D3DXPlaneIntersectLine( &ptIntersection, pPlane, &pEdges[0], &pEdges[1] ) )
return FALSE;
// Project onto a 2D plane to make the pt-in-poly test easier
FLOAT fAbsA = (pPlane->a > 0 ? pPlane->a : -pPlane->a);
FLOAT fAbsB = (pPlane->b > 0 ? pPlane->b : -pPlane->b);
FLOAT fAbsC = (pPlane->c > 0 ? pPlane->c : -pPlane->c);
D3DXVECTOR2 facePoints[4];
D3DXVECTOR2 point;
if( fAbsA > fAbsB && fAbsA > fAbsC )
{
// Plane is mainly pointing along X axis, so use Y and Z
for( INT i = 0; i < 4; i++)
{
facePoints[i].x = pFacePoints[i].y;
facePoints[i].y = pFacePoints[i].z;
}
point.x = ptIntersection.y;
point.y = ptIntersection.z;
}
else if( fAbsB > fAbsA && fAbsB > fAbsC )
{
// Plane is mainly pointing along Y axis, so use X and Z
for( INT i = 0; i < 4; i++)
{
facePoints[i].x = pFacePoints[i].x;
facePoints[i].y = pFacePoints[i].z;
}
point.x = ptIntersection.x;
point.y = ptIntersection.z;
}
else
{
// Plane is mainly pointing along Z axis, so use X and Y
for( INT i = 0; i < 4; i++)
{
facePoints[i].x = pFacePoints[i].x;
facePoints[i].y = pFacePoints[i].y;
}
point.x = ptIntersection.x;
point.y = ptIntersection.y;
}
// If point is on the outside of any of the face edges, it is
// outside the face.
// We can do this by taking the determinant of the following matrix:
// | x0 y0 1 |
// | x1 y1 1 |
// | x2 y2 1 |
// where (x0,y0) and (x1,y1) are points on the face edge and (x2,y2)
// is our test point. If this value is positive, the test point is
// "to the left" of the line. To determine whether a point needs to
// be "to the right" or "to the left" of the four lines to qualify as
// inside the face, we need to see if the faces are specified in
// clockwise or counter-clockwise order (it could be either, since the
// edge could be penetrating from either side). To determine this, we
// do the same test to see if the third point is "to the right" or
// "to the left" of the line formed by the first two points.
// See http://forum.swarthmore.edu/dr.math/problems/scott5.31.96.html
FLOAT x0, x1, x2, y0, y1, y2;
x0 = facePoints[0].x;
y0 = facePoints[0].y;
x1 = facePoints[1].x;
y1 = facePoints[1].y;
x2 = facePoints[2].x;
y2 = facePoints[2].y;
BOOL bClockwise = FALSE;
if( x1*y2 - y1*x2 - x0*y2 + y0*x2 + x0*y1 - y0*x1 < 0 )
bClockwise = TRUE;
x2 = point.x;
y2 = point.y;
for( INT i = 0; i < 4; i++ )
{
x0 = facePoints[i].x;
y0 = facePoints[i].y;
if( i < 3 )
{
x1 = facePoints[i+1].x;
y1 = facePoints[i+1].y;
}
else
{
x1 = facePoints[0].x;
y1 = facePoints[0].y;
}
if( ( x1*y2 - y1*x2 - x0*y2 + y0*x2 + x0*y1 - y0*x1 > 0 ) == bClockwise )
return FALSE;
}
// If we get here, the point is inside all four face edges,
// so it's inside the face.
return TRUE;
} |
keinen schimmer was da abgeht....  |
|
Nach oben |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 17.01.2004, 18:04 Titel: |
|
|
na kommt schon, leude...irgendwer muß doch schon mal eine poly-line kollision eingebaut haben.
ich hab jetzt die funktion 'Intersect' aus dem Pick-Sample hergenommen, welche überprüft, ob ein endloser strahl ein polygon schneidet. weil ich ja eine linie checken will, hab mir gedacht, ich ruf anfangs noch D3DXPlaneIntersectLine() auf, weil wenn die linie die ebene des polys schneidet und der strahl (der linie) das poly selbst, ist sicher eine kollision aufgetreten.
aber es haut nicht hin. selbst wenn die ebene die linie nicht schneidet, krieg ich bei D3DXPlaneIntersectLine() eine collision, kann es sein, dass die funktion auch nur den strahl den die linie beschreibt gegen die ebene checkt?
Ich kack jetzt schon so lang damit herum, HELFT MIR!
hier noch meine momentane funktion:
Code: |
MLE_API bool mleLineHitsTriangle2(const D3DXVECTOR3& pvLineA,
const D3DXVECTOR3& pvLineB,
const D3DXVECTOR3& pvTriA,
const D3DXVECTOR3& pvTriB,
const D3DXVECTOR3& pvTriC,
D3DXVECTOR3* pvOut) // =NULL
{
D3DXVECTOR3 vOut;
D3DXPLANE Plane;
// die ebene des dreiecks berechnen
D3DXPlaneFromPoints(&Plane, &pvTriA, &pvTriB, &pvTriC);
// wenn sie die ebene nicht schneidet, kann sie das dreieck nicht schneiden
if (D3DXPlaneIntersectLine(&vOut, &Plane, &pvLineA, &pvLineB) == NULL)
return false;
// der richtungsvektor der linie
D3DXVECTOR3 vDir = pvLineB - pvLineA;
// Find vectors for two edges sharing vert0
D3DXVECTOR3 edge1 = pvTriB - pvTriA;
D3DXVECTOR3 edge2 = pvTriC - pvTriA;
// Begin calculating determinant - also used to calculate U parameter
D3DXVECTOR3 pvec;
D3DXVec3Cross(&pvec, &vDir, &edge2);
// If determinant is near zero, ray lies in plane of triangle
float det = D3DXVec3Dot(&edge1, &pvec);
D3DXVECTOR3 tvec;
if(det > 0)
{
tvec = pvLineA - pvTriA;
}
else
{
tvec = pvTriA - pvLineA;
det = -det;
}
if( det < 0.0001f )
return false;
// Calculate U parameter and test bounds
vOut.x = D3DXVec3Dot(&tvec, &pvec);
if(vOut.x < 0.0f || vOut.x > det)
return false;
// Prepare to test V parameter
D3DXVECTOR3 qvec;
D3DXVec3Cross(&qvec, &tvec, &edge1);
// Calculate V parameter and test bounds
vOut.y = D3DXVec3Dot(&vDir, &qvec);
if(vOut.y < 0.0f || vOut.x + vOut.y > det)
return false;
// Calculate t, scale parameters, ray intersects triangle
vOut.z = D3DXVec3Dot(&edge2, &qvec);
float fInvDet = 1.0f / det;
vOut.z *= fInvDet;
vOut.x *= fInvDet;
vOut.y *= fInvDet;
if (pvOut != NULL)
*pvOut = vOut;
return true;
}
|
|
|
Nach oben |
|
 |
KI JLI Master

Alter: 39 Anmeldedatum: 04.07.2003 Beiträge: 965 Wohnort: Aachen Medaillen: Keine
|
|
Nach oben |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 18.01.2004, 20:13 Titel: |
|
|
jo, danke fürs suchen, aber die doku ist beim sample auch dabei und hilft genau gar nicht. ausserdem ist das cull sample sowiese fürn arsch, und es stehen so nette sachen da, wie:
The culling code shown here is written in a straightforward way for readability. It is not optimized for performance.
die funktion aus dem pick sample ist schon viel netter, aber wie gesagt, nur 'ray-triangle', und die beschi** D3DXPlaneIntersectLine() funktion macht irgendwas, nur nicht die linie gegen die ebene checken. |
|
Nach oben |
|
 |
Fallen JLI MVP


Alter: 40 Anmeldedatum: 08.03.2003 Beiträge: 2860 Wohnort: Münster Medaillen: 1 (mehr...)
|
Verfasst am: 19.01.2004, 08:55 Titel: |
|
|
In der Hilfe steht das hier:
Zitat: | If the line is parallel to the plane, NULL is returned. |
Da scheint nicht zu stehen das NULL auch dann zurückgegeben wird wenn kein Schnitt vorliegt.
Zitat: | The return value for this function is the same value returned in the pOut parameter. |
Was bedeutet das er bei dir immer einen Wert zurückgibt der nicht falsch ist. _________________ "I have a Core2Quad at 3.2GHz, 4GB of RAM at 1066 and an Nvidia 8800 GTS 512 on Vista64 and this game runs like ass whereas everything else I own runs like melted butter over a smokin' hot 18 year old catholic schoolgirl's arse." |
|
Nach oben |
|
 |
Chewie Super JLI'ler
Anmeldedatum: 17.07.2003 Beiträge: 382
Medaillen: Keine
|
Verfasst am: 19.01.2004, 16:45 Titel: |
|
|
bin mittlerweile auch schon draufgekommen....die funktion testet wirklich den endlosen strahl gegeben durch 2 punkte...nicht die endliche linie.
ich dachte in englisch ist line eine linie und ray ein strahl...aber ein endlicher teil eines strahls heißt dann 'line segment'.
ich glaub ich weiß aber schon wie ichs machen werde...erstmal testen, ob die punkte nicht auf der selben seite der (poly-)ebene liegen und dann den strahl gegen das poly testen...so sollts funken. |
|
Nach oben |
|
 |
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|