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

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

1

21.01.2012, 17:18

Raycasting

Hallo. Ich komme einfach nicht weiter. Nachdem ich es nun geschafft habe einen Ball-Socketjoint zu erstellen muss ich ihn nurnoch am angeklickten Objekt Positionieren. Da kam mir RayCast in den Sinn, um zu prüfen, welches Objekt angeklicht ist. Ich verwende dafür eine Newtonfunktion namens NewtonWorldRayCast. 2 Parameter sind mir da wichtig:

Quellcode

1
2
const dFloat *p0 - pointer to the first element of an array of at least three floats containing the beginning of the ray in global space.
const dFloat *p1 - pointer to the first element of an array of at least three floats containing the end of the ray in global space.

Ich benutze folgenden Code um die zwei Variablen auszurechnen:

C-/C++-Quelltext

1
2
3
4
5
6
D3DXVECTOR3 v1,v2;
POINT Pos;
GetCursorPos(&Pos);
float x = ((float) Pos.x) / 1366;
float y = ((float) Pos.y) / 768;
ScreenToWorld(2 * x - 1, 1 - 2 * y, ViewMatrix, ProjectionMatrix, v1, v2);

Die Funktion ScreenToWorld:

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void ScreenToWorld(int X, int Y, Matrix mView, Matrix mProj, D3DXVECTOR3 &v1, D3DXVECTOR3 &v2)
{
    Matrix mViewProj;
    mViewProj = mView * mProj;

        Matrix Inverse;
        Matrix invProj, invView;

    invView = MatrixInvert(mView);
    invProj = MatrixInvert(mProj);
    Inverse = MatrixInvert(mViewProj);

// Matrix in D3DXMATRIX
    D3DXMATRIX inv = D3DXMATRIX(Inverse.m11,Inverse.m12,Inverse.m13,Inverse.m14,Inverse.m21,Inverse.m22,Inverse.m23,Inverse.m24,
Inverse.m31,Inverse.m32,Inverse.m33,Inverse.m34,Inverse.m41,Inverse.m42,Inverse.m43,Inverse.m44);

    D3DXVECTOR3 nearPoint(X, Y, 0);
    D3DXVECTOR3 farPoint (X, Y, 1);
    D3DXVec3TransformCoord(&v1, &nearPoint, &inv);
    D3DXVec3TransformCoord(&v2, &farPoint,  &inv);
}

v1 ist dann p0 und v2 ist p1 in der NewtonFunktion. Nunja leider geht das nicht. Was genau nicht geht ist schwer zu sagen, aber egal welches Objekt ich anklicke, Newton sagt nicht das es im Strahl liegt.
Habe ich vll einen Rechenfehler?
In dem NewtonTutorial ist das ganze mit OpenGL wer den Code sehen will:

C-/C++-Quelltext

1
2
3
4
5
6
dVector p0 (ScreenToWorld(dVector (cursorPosit1.m_x, cursorPosit1.m_y, 0.0f, 0.0f)));
            dVector p1 (ScreenToWorld(dVector (cursorPosit1.m_x, cursorPosit1.m_y, 1.0f, 0.0f)));

            
            pickedParam = 1.1f;
            NewtonWorldRayCast(nWorld, &p0[0], &p1[0], RayCastFilter, NULL, RayCastPrefilter);

ScreenToWorld

C-/C++-Quelltext

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
33
34
35
36
37
38
39
40
dVector ScreenToWorld (const dVector& screen)
{
    //Where the values will be stored
    GLint viewport[4]; 

    //Retrieves the viewport and stores it in the variable
    glGetIntegerv(GL_VIEWPORT, viewport); 

    //Where the 16 doubles of the matrix are to be stored
    GLdouble modelview[16]; 

    //Retrieve the matrix
    glGetDoublev(GL_MODELVIEW_MATRIX, modelview); 

    GLdouble projection[16]; 
    glGetDoublev(GL_PROJECTION_MATRIX, projection);

    GLdouble winX = 0.0;
    GLdouble winY = 0.0;
    GLdouble winZ = 0.0; //The coordinates to pass in

    winX = screen.m_x; //Store the x cord
    winY = screen.m_y; //Store the y cord
    winZ = screen.m_z; //Store the Z cord

    //Now windows coordinates start with (0,0) being at the top left 
    //whereas OpenGL cords start lower left so we have to do this to convert it: 
    //Remember we got viewport value before 
    winY = (dFloat)viewport[3] - winY; 

    GLdouble objx;
    GLdouble objy;
    GLdouble objz;

    // use the real GL view port
    glGetIntegerv(GL_VIEWPORT, viewport); 
    gluUnProject (winX, winY, winZ, modelview, projection, viewport, &objx, &objy, &objz);

    return dVector (dFloat(objx), dFloat(objy), dFloat(objz));
}

Danke im Voraus

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

2

21.01.2012, 18:31

Keiner eine Idee? Soll ich es anderst posten? Was soll ich machen damit ihr mehr Info's habt? Bin leider kein Hellseher ;)

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Sacaldur

Community-Fossil

Beiträge: 2 301

Wohnort: Berlin

Beruf: FIAE

  • Private Nachricht senden

3

21.01.2012, 19:07

warte doch einfach, bis jemand kommt, der sich auch schonmal mit der Thematik beschäftigt hat und dir dadurch auch helfen kann
auch wenn wochenende ist, ist weniger als 1 Stunde ein ziemlich kurzer Zeitraum...
Spieleentwickler in Berlin? (Thema in diesem Forum)
---
Es ist ja keine Schande etwas falsch zu machen, als Programmierer tu ich das täglich, [...].

FSA

Community-Fossil

  • »FSA« ist der Autor dieses Themas
  • Private Nachricht senden

4

22.01.2012, 13:18

So, nach einer langen Nacht und viel Cola habe ich das Problem gelöst. Ich habe einfach vergessen die Kameraposition mit einzurechen, deswegen war der Strahl immer an der gleichen Position *Kopf->Tisch* :dash:

Zitat

Der RCCSWU (RandomCamelCaseSomtimesWithUndersquare) Stil bricht auch mal mit den veraltet strukturierten Denkmustern und erlaubt dem Entwickler seine Kreativität zu entfalten.

Werbeanzeige