Reicht nur Intersection als Kollisionsabfrage



  • Hi,

    im Titel steht eigentlich schon alles, DirectX bringt von Haus aus die Möglichkeit
    mit eine intersect Abfrage zu machen, für 2d und 3d Objekte, reicht das aus,
    oder braucht man noch andere Techniken der Kollinsionserkennung?



  • adonis schrieb:

    DirectX bringt von Haus aus die Möglichkeit
    mit eine intersect Abfrage zu machen, für 2d und 3d Objekte

    Echt?
    Zeig her!



  • o.O



  • öhm Oo...

    c++

    HRESULT D3DXIntersect(
      LPD3DXBASEMESH pMesh,
      CONST D3DXVECTOR3 * pRayPos,
      CONST D3DXVECTOR3 * pRayDir,
      BOOL * pHit,
      DWORD * pFaceIndex,
      FLOAT * pU,
      FLOAT * pV,
      FLOAT * pDist,
      LPD3DXBUFFER * ppAllHits,
      DWORD * pCountOfHits
    );
    
    HRESULT D3DXIntersectSubset(
      LPD3DXBASEMESH pMesh,
      DWORD AttribId,
      CONST D3DXVECTOR3 * pRayPos,
      CONST D3DXVECTOR3 * pRayDir,
      BOOL * pHit,
      DWORD * pFaceIndex,
      FLOAT * pU,
      FLOAT * pV,
      FLOAT * pDist,
      LPD3DXBUFFER * ppAllHits,
      DWORD * pCountOfHits
    );
    

    gleiche für xna und managed

    Mesh.Intersect Method
    public bool Intersect(Vector3, Vector3);
    public bool Intersect(Vector3, Vector3, out IntersectInformation);
    public bool Intersect(Vector3, Vector3, out IntersectInformation, out IntersectInformation);
    public bool Intersect(Vector3, Vector3, out IntersectInformation);

    Mesh.IntersectSubset Method
    public bool IntersectSubset(int, Vector3, Vector3);
    public bool IntersectSubset(int, Vector3, Vector3, out IntersectInformation);
    public bool IntersectSubset(int, Vector3, Vector3, out IntersectInformation, out IntersectInformation);
    public bool IntersectSubset(int, Vector3, Vector3, out IntersectInformation);



  • Hi,

    nicht zu vergessen:

    D3DXBoxBoundProbe
    D3DXIntersectTri
    

    Ob das ausreicht oder nicht musst du dir selbst beantworten. Die oben genannten Methoden liefern diverse Informationen über die Kollision (oder halt auch nicht) zurück. Für die meisten Anwendungsfälle wird das ausreichend sein, aber damit ist halt keine dynamische Kollisionserkennung möglich wie man sie bei sehr kleinen sich schnell bewegenden Objekten bräuchte. Die oben genannten Funktionen behandeln halt nur diskrete Objekte bzw. Objekte an diskreten Positionen.

    Ciao,
    Stefan



  • Cool, wieder was gelernt ^^



  • Danke, dann mal gucken wann ich Probleme bekomme, um
    sich durch ein Level zu bewegen wirds ja hoffentlichen reichen :).

    Was gibt es sonst noch für Möglichkeiten, denke mal Abstand messen
    zwischen 2 Objekten wäre auch noch eine Möglichkeit oder?



  • Hehe, das ist bloss Raycasting. "Intersection" von 3D Objekten würde für mich bedeuten (abstrakt):

    mesh Intersection(transformed_mesh a, transformed_mesh b)
    // oder
    bool TestIntersect(transformed_mesh a, transformed_mesh b)
    

    Mit Raycasting wirst du nicht weit kommen:

    *---*
           |B  |
           |   |
           |   |
    *------|   |------*
    |A     |   |      |
    |      |   |      |
    *------|   |------*
           |   |
           |   |
           |   |
           *---*
    

    Wie willst du, wenn Objekt A sich "nach vorne" (ich meine im 3D Raum, anhand der Projektionsachse dieses Bildes, also "aus dem Monitor heraus) Bewegt und B schneidet das mit RayCasting erkennen?
    D3DXBoxBoundProbe müsste funktionieren, aber dann weisst du bloss ob sich die Objekte *möglicherweise* schneiden, und selbst wenn eben nicht wo (falls die Information "wo" benötigst).

    Wenn du dann wissen willst ob sie sich wirklich schneiden könntest du zwar mit D3DXIntersectTri weitermachen (jedes Tri von A gegen das mesh B), aber das braucht ganz schnell ganz viel Rechenzeit. Und nichtmal dann weisst du ob nicht vielleicht ein Objekt gänzlich im anderen liegt. Dazu müsstest du dann ein Objekt längs des Bewegungsvektors extrudieren, und ... nech, viel zu aufwändig.

    Collision-Testing macht man üblicherweise mit speziellen "Hulls". Die "Hull" besteht dabei möglichst aus Primitiven wie Kugeln, Boxen, Zylindern und "Kapseln" (Zylinder mit 2 Halbkugelflächen statt Kreisflächen als "Abschluss"). Intersections zwischen solchen Primitiven sind relativ einfach zu testen (=ohne viel Rechenaufwand). Natürlich macht man für komplexere "Hulls" wieder "Hulls", also z.B. eine Kubel die die ganze "Hull" einschliesst - dann testet man erstmal auf diese "äusseren Kugeln", und nur wenn diese sich überhaupt schneiden testet man die "eigentlichen Hulls".



  • Gibts ein Unterschied zwischen hull und boundingbox?
    Komplexe Shapes zu simplifizieren durch Primitives ist klar.

    Aber ich kann doch dann die Methoden benutzen oder?

    Teilweise stellt sich mir auch die Frage, warum muss alles Kollidieren,
    ich renne ja auch nich gegen eine Wand, ich sehe sie, und sie kommt näher,
    ich bleib davor stehen und renne da nich erst gegen.

    oder was ist mit sowas:

    +-------+
    |\  +-+ |
    | \ |\| |
    |  \+-+ |
    |   \   |
    |    \  |
    |     \ |
    |      \|
    +-------+
    

    dürfte hier sicher interessant sein, rauszufinden ob die sich schneiden.

    Leider beschäftigen sich kaum SpieleProgrammierungs Bücher mit dem Thema.
    Obwohl es ja ein wichtiger bestandteil ist. Aber das wird wohl der Grund sein,
    warum die meisten mit sowas anfangen wie, Raumschiff im Weltraum.

    Erstmal reicht mir ja etwas einfaches, will erstmal nur druch einen Raum laufen.
    Dafür wirds ja hoffentlich reichen.



  • Was genau kann ich mir unter einem diskreten Objekt vorstellen?
    Darf es sich nur nicht schnell bewegen oder muss es fix sein?
    Oder ist das was ganz anderes?



  • Hi,

    diskret meint in diesem Zusammenhang, dass die Otto-Normal-Intersection Tests die man überall im Internet findet mit der konkreten Transformation des Objektes arbeiten. Sprich man betrachtet einen konkreten Zeitpunkt und kein Zeitintervall.

    In der Regel reicht das aus, so lange ein Objekte nicht so klein oder so schnell ist, dass es sich von einem Frame zum anderen komplett durch ein anderes hindurchbewegt. Denn dann versagt die diskrete Kollisionsabfrage weil es im Frame n und im Frame n+1 keine Kollision gibt. Lediglich im Zeitraum dazwischen ...

    Wichtig ist das hauptsächlich bei Kollisionsabfragen für Projektile oder in Physiksimulationen.

    Ciao,
    Stefan



  • Lassen sich so schnelle Objekte überhaupt realisieren?
    Projektile sind ja ein bischen sehr schnell, wenn es sich, sagen
    wir von frame 0 zu frame 1 schon 10Meter bewegt hat, wie soll ich darauf
    noch reagieren und das dann noch visualisieren, dann bräucht ich schon
    eine sehr hohe Framerate oder?

    So richtig vorstellen kann ich mir das nicht.

    Oder hab ich da nen Denkfehler?



  • Du musst zwischen "Grafik-Frames" und "Logik-Frames" unterscheiden. Das Thema hatten wir bereits ein paar mal im Forum. Such mal nach Dingen wie "logic tick", "Zeitunabhaengige Bewegung" und dergleichen.

    Jedenfalls, der Trick ist der: du musst dich fragen, kann ein Objekt von einem Logik-Tick sprich "von einem aufruf der game-logik", also Objekte Bewegen, Kollisionserkennung, etc.) zum Naechsten "durch" ein anderes Objekt bewegen. Eben bei Projektilen ist das sehr gut moeglich. Und du kannst dann ja nicht einfach sagen "tja, das Projektil ist von Frame 0 zu Frame 1 von Meter 0 auf Meter 10 gesprungen, also hat es das Objekt bei Meter 5 einfach nicht getroffen, Pech gehabt". Deshalb musst du das Problem irgendwie loesen, und dann brauchst du mehr als nur die Funktionen, die DirectX dir bietet.



  • Hi,

    nein man braucht nicht mehr als DirectX einem bietet. Jedenfalls nicht für solche Probleme. Man muss den Test eben nur gut durchdenken. Im Fall eines Projektils zieht man einfach ein Liniensegment (DirectX Ray Inetrsection Test) von der Position des Projektils im Frame n zu den Position im Frame n+1. Alles was mit diesem Ray kollidiert wird von dem Projektil getroffen.

    Je nach Durchschlagskraft des Projektils bzw. der Dichte des getroffenen Objektes kann man dann auch multiple Treffer bei Durchschuß zulassen.

    Ciao,
    Stefan



  • Für sowas einfaches reicht ein Ray, richtig.
    Blöd wird es nur wenn die zu testenden Shapes beides keine sehr "einfachen" Objekte sind, trotzdem aber sehr schnell bewegt werden.



  • Danke für die Antworten, werd erstmal die Mittel benutzen die mir zur Verfügnung
    stehen. Muss ich mich näher mit beschäftigen, wenn die Mittel nicht ausreichen
    sollten.



  • Oder aber du suchst dir eine Physics-Engine die das alles schon kann 😉



  • Gibt leider noch nich sehr viel für managed directx, probiere
    grad unmanaged dll's einzubinden, scheint ganz gut zu Funktionieren.
    physixsdk, hab ich hier noch rumliegen, vielleicht bekomme ich die ja zum laufen.



  • hustbaer schrieb:

    Hehe, das ist bloss Raycasting.

    Hier wird nur getestet ob ein Strahl ein Mesh schneidet, das mag zwar bei Raycasting von Bedeutung sein, aber Raycasting ist was anderes.


  • Mod

    ein test ob ein ray ein mesh schneidet nennt man allgemein raycasting.


Anmelden zum Antworten