JLI Spieleprogrammierung Foren-Übersicht JLI Spieleprogrammierung

 
 FAQFAQ   SuchenSuchen   MitgliederlisteMitgliederliste   BenutzergruppenBenutzergruppen 
 medals.phpMedaillen   RegistrierenRegistrieren   ProfilProfil   Einloggen, um private Nachrichten zu lesenEinloggen, um private Nachrichten zu lesen   LoginLogin 

Unterschied zwischen Koll.-Routinen Poly -- Line

 
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen  
Autor Nachricht
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 13.01.2004, 15:48    Titel: Unterschied zwischen Koll.-Routinen Poly -- Line Antworten mit Zitat

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.... Sad
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 17.01.2004, 18:04    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
KI
JLI Master


Alter: 39
Anmeldedatum: 04.07.2003
Beiträge: 965
Wohnort: Aachen
Medaillen: Keine

BeitragVerfasst am: 17.01.2004, 20:27    Titel: Antworten mit Zitat

In der MSDN wird die Funktionsweise des Cull Beispiels aus dem SDK nochmal genau erklärt.
Vielleicht hilft es dir wenn du da mal vorbeischauen würdest

EDIT: zumindest meine ich etwas dazu gelesen zu haben.
ich such mal...

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/directx9_c/directx/graphics/tutorialsandsamples/samples/cull.asp

ausführlich ist allerdings was anders.
Nach oben
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 18.01.2004, 20:13    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Fallen
JLI MVP
JLI MVP


Alter: 40
Anmeldedatum: 08.03.2003
Beiträge: 2860
Wohnort: Münster
Medaillen: 1 (mehr...)

BeitragVerfasst am: 19.01.2004, 08:55    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden E-Mail senden Website dieses Benutzers besuchen
Chewie
Super JLI'ler



Anmeldedatum: 17.07.2003
Beiträge: 382

Medaillen: Keine

BeitragVerfasst am: 19.01.2004, 16:45    Titel: Antworten mit Zitat

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
Benutzer-Profile anzeigen Private Nachricht senden
Beiträge der letzten Zeit anzeigen:   
Neues Thema eröffnen   Neue Antwort erstellen    JLI Spieleprogrammierung Foren-Übersicht -> DirectX, OpenGL Alle Zeiten sind GMT
Seite 1 von 1

 
Gehe zu:  
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

Impressum