Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

Stefan

Alter Hase

  • »Stefan« ist der Autor dieses Themas

Beiträge: 668

Wohnort: Innsbruck

  • Private Nachricht senden

1

30.05.2004, 00:44

Objekte mit Maus auswählen!?

Hallo,

ich habe eine isometrische Ansicht mit d3d! Darauf befinden sich Objekte, die ich mit der Maus auswählen möchte! Die Landschaft + den Objekten sind alle mit den Weltkoordinaten angegeben! Solange die Maus auch in Weltkoordinaten angeben ist und den gleichen z-Achsen Abstand hat, wie alle anderen Objekte ist es für mich kein Problem eine Kollisionsabfrage zu machen, nur kann man jetzt eben auch noch zoomen und die Maus bleibt auf der selben Höhe und nur die Obejekte verändern sich! Da es sonst komisch aussieht, wenn die Maus ebenfalls kleiner wird. Nur leider funktioniert die Kollisionsabfrage dann auch nicht mehr! Ich habe bereits bei google gesucht, nur leider habe ich noch nichts wircklich hilfreiches gefunden, ich hoffe ihr könnt mir zeigen wie ich das machen muss! thx


cya,
Stefan

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

2

30.05.2004, 12:05

Willst wohl nen Editor schreiben ;) .Also die Maus ist ja 2D, die Welt 3D. Wenn man sich dann die ZAchse als Linie vorstellt muss man ja nur noch die Linie-Dreieck Funktion nutzen.

Stefan

Alter Hase

  • »Stefan« ist der Autor dieses Themas

Beiträge: 668

Wohnort: Innsbruck

  • Private Nachricht senden

3

30.05.2004, 12:14

ja, benötige ich auch für meinen Editor, aber zuerst einmal nur für das Spiel, dabei möchte ich das der Spieler einfach mal mit der Maus Objekte die am Boden verstreut herum liegen aufheben kann!
Also danke mal für deine Antwort, nur hab ich leider überhaupt keine Ahnung wie das im Code aussehen sollte und die Linie-Dreieck Funktion kenne ich auch noch nicht....



cya,
Stefan

Nox

Supermoderator

Beiträge: 5 272

Beruf: Student

  • Private Nachricht senden

4

30.05.2004, 12:25

Benutz die aus Galactica.

Anonymous

unregistriert

5

30.05.2004, 19:52

Die Sache ist ja das der sichtbare Bereich wie eine abgeschnitte Pyramide aussieht, also wenn du ganz links bist und einen Strahl nach hinten schickst, muss der eine Richtung mehr nach rechts haben und nicht gerade nach hinten im Raum bzw. auf der Z-Achse

folgene Funktion verwende ich bei meinem Leveleditor zum herausfinden des Startpunktes und der Richtung des zu "sendenden" Strahls.....
(ist größtenteils aus dem SDK-Sample von DirectX 9.0b übernommen)

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
void MousePick(tbVector3 &vPickRayOrig, tbVector3 &vPickRayDir)
{
    tbVector3 vPickRayDir, vPickRayOrig;
    // Get the pick ray from the mouse position
    D3DXMATRIXA16 matProj;
    tbDirect3D::GetDevice()->GetTransform( D3DTS_PROJECTION, &matProj );

    POINT ptCursor;
    GetCursorPos( &ptCursor );
    //ScreenToClient(&ptCursor );

    // Compute the vector of the pick ray in screen space
    D3DXVECTOR3 v;
    v.x =  ( ( ( 2.0f * (ptCursor.x - m_sRVSize.left) ) / 
        ((float)m_sRVSize.right-m_sRVSize.left)  ) - 1 ) / matProj._11;
    v.y = -( ( ( 2.0f * (ptCursor.y - m_sRVSize.top) ) / 
        ((float)m_sRVSize.bottom-m_sRVSize.top) ) - 1 ) / matProj._22;
    v.z =  1.0f;


    tbMatrix m(tbMatrixInvert(g_mCamera));

    
    // Transform the screen space pick ray into 3D space
    vPickRayOrig.x = m.m41;
    vPickRayOrig.y = m.m42;
    vPickRayOrig.z = m.m43;
    
    vPickRayDir.x  = v.x*m.m11 + v.y*m.m21 + v.z*m.m31;
    vPickRayDir.y  = v.x*m.m12 + v.y*m.m22 + v.z*m.m32;
    vPickRayDir.z  = v.x*m.m13 + v.y*m.m23 + v.z*m.m33;
}


natürlich musst du dafür dann auch die Variable <m_sRVSize> richtig setzen, dass mache ich immer in meiner Move-Funktion da ich nur ein bestimmtes, verschiebbares, Dialog-Fenster und kein Vollbild für die 3D-Darstellung nutze....

Quellcode

1
2
tagRECT     m_sRVSize;
GetDlgItem(IDC_RENDERVIEW)->GetWindowRect(&m_sRVSize);


und die Variable <g_mCamera> ist bei mir die Camera-Matrix (immer aktuallisiert in der entsprechenden Funktion - hier <Render>)


Zum Abfragen ob ein Strahl ein Dreieck trifft und welches benutzt du die Funktion <tbLineHitsModel>,
zum Beispiel so

Quellcode

1
2
3
tbLineHitsModel(*pvPickRayOrig, *pvPickRayOrig + (2000 * *pvPickRayDir),
                        p3DModell, mMatrix, mInvMatrix,
                        0.0f, &vOutPos));


Dann musst Du nur noch den Treffer herausfinden, der am nächsten zum Strahlen-Ursprung liegt, das mache ich dann in einer For-Schleife die alle Objekte durchgeht und sich bei einem Treffer die Entfernung merkt bzw. mit einer lokalen Variablen (Entfernung des letzten Treffers) vergleicht und dann je nachdem merkt.
< tbVector3LengthSq(*pvPickRayOrig-vOutPos) >
Natürlich merkt die Funktion sich auch die Nummer des Objekts das am nächsten war, so kann ich dann später direkt drauf zugreifen, da ich alle Objekte in einem Array habe.

So damit solltest Du es jetzt auf jeden Fall hinbekommen,
denke ich zumindest.....

Stefan

Alter Hase

  • »Stefan« ist der Autor dieses Themas

Beiträge: 668

Wohnort: Innsbruck

  • Private Nachricht senden

6

31.05.2004, 14:48

@Fabster
danke dir für die sehr ausführliche Antwort!
Also ich hab es leider noch nicht ausprobiert, aber ich habe nochmals die Funktion von Glactica ausprobiert, aber ich versteh die noch nicht ganz, also die Funktion sieht ja so aus:


Quellcode

1
2
3
4
5
6
BOOL tbLineHitsTriangle(const tbVector3& vLineA,
                            const tbVector3& vLineB,
                            const tbVector3& vTriangleA,
                            const tbVector3& vTriangleB,
                            const tbVector3& vTriangleC,
                            tbVector3* pvOut)


Uns jetzt setzte ich follgende Werte für die Parameter ein:

Quellcode

1
2
3
4
5
6
7
8
9
if(tbLineHitsTriangle(vPositionMaus,
                        tbVector3(vPositionMaus.x, vPositionMaus.y, 50),
                        tbVector3( 0.0f, 0.0f,5.0f),
                        tbVector3(100.0f, 0.0f, 5.0f),
                        tbVector3( 0.0f,-100.0f,5.0f),
                        NULL                        ))


        Kollision();


Also wenn ich jetzt das Dreieck mit der Maus berühre, was ich ja mit den 3 Vektoren angeben habe, schreibt er mir eine Kollision, nur geht die Kollision in x- und -y Richtung ins Unendliche! Muss ich die ersten 2 Parameter anderst angeben, oder an was könnte das liegen? thx



cya,
Stefan

Anonymous

unregistriert

7

31.05.2004, 15:19

Zitat

nur geht die Kollision in x- und -y Richtung ins Unendliche! Muss ich die ersten 2 Parameter anderst angeben, oder an was könnte das liegen?


Also ich weiss jetzt nicht so ganze was du meinst,
weil wenn Du die Funktion wirklich so aufrufst fragst Du ja den Punkt der Kollision gar nicht ab,

welche Variable geht also ins Unendliche ?

Du müsstest statt <NULL> einen Zeiger auf einen tbVector3 angeben, der enthält dann später den genauen Punkt der Kollision.....

Stefan

Alter Hase

  • »Stefan« ist der Autor dieses Themas

Beiträge: 668

Wohnort: Innsbruck

  • Private Nachricht senden

8

31.05.2004, 17:19

Also ich dachte mir ich könnte den letzten Parameter den Wert NULL übergeben, da ich ja nur benötige, ob überhaupt eine Kollision stattfindet! Wo die Kollision ist, benötige ich doch eigentlich nicht, oder?
Also ich habe ja ein Dreieck erzeugt in der Funktion, das vom Ursprung(also Bildschirmmitte) nach rechts geht und 100 Einheiten nach unten!
Wenn ich jetzt an diese Stelle mit der Maus fahre, müsste er mir doch sagen, das hier eine Kollision stattfindet, macht er auch, nur wenn ich jetzt weiter als 100 Einheiten unter dem Ursprung fahre, zeigt er mir immer noch eine Kollision an, das selbe auch in x-Achsen Richtung! Dort wo das Dreieck schon aus sein müsste! Deshalb frage ich mich was ich anderst angeben muss!?
thx



cya,
Stefan

Anonymous

unregistriert

9

01.06.2004, 17:37

Ach okay, ich hab deine Msg einfach falsch verstanden ich dachte du meintest der ermittelte KollisionsVektor hätte total unrealistische x und y koordinaten, also welche die quasi ins "unendliche gehen"...

also das Problem hatte ich oben schonmal beschrieben :
(nur hatte ich mich da mit links-rechts vertan ;) )

Zitat von »"Fabster"«

Die Sache ist ja das der sichtbare Bereich wie eine abgeschnitte Pyramide aussieht, also wenn du ganz links bist und einen Strahl nach hinten schickst, muss der eine Richtung mehr nach links haben und nicht gerade nach hinten im Raum bzw. auf der Z-Achse


der zweite Parameter bei deinem Funktionsaufruf darf also nicht lauten :

Quellcode

1
tbVector3(vPositionMaus.x, vPositionMaus.y, 50)


sondern in etwa so :

Quellcode

1
vPositionMaus.x + (vRichtungMaus*2000)


denn du musst die extra berechnete Richtung der Strahls mit einbeziehen
(die Konstante 2000 hab ich genommen weil du dann halt noch recht tief prüfen kannst, kommt natürlich auf deine "Far-Clipping-Plane" an...)

Werbeanzeige