Cursorposition im 3D-Raum
Es müsste eigendlich möglich sein, sowas zu berechnen.
Man hat ja:
- Cursorposition
- Cameraposition und -blickwinkel
- 3D-Terrain/-Objekte samt Positionen
Durch die Cameraposition und den Blickwinkel kann man ausrechnen, welcher Teil der 3D-Welt im Zentrum des Bildschirm ist. (Einfach von der Cameraposition eine Gerade in Richtung Blickwinkel erechnen und schauen, wo diese Gerade das 3D-Terrain schneidet.)
Jetzt ist es wichtig, ob die 3D-Darstellung persketivisch verzerrst ist, oder nicht, denn
a) ist sie es nicht, dann geben Cursorkoordinaten die Verschiebung zur Gerade an (die Gerade von weiter oben ist gemeint).
b) ist sie es doch, dann muss du einen Weg finden, die Verzerrung in die Berechnung miteinfließen zu lassen.
Greetz Laurin
Man hat ja:
- Cursorposition
- Cameraposition und -blickwinkel
- 3D-Terrain/-Objekte samt Positionen
Durch die Cameraposition und den Blickwinkel kann man ausrechnen, welcher Teil der 3D-Welt im Zentrum des Bildschirm ist. (Einfach von der Cameraposition eine Gerade in Richtung Blickwinkel erechnen und schauen, wo diese Gerade das 3D-Terrain schneidet.)
Jetzt ist es wichtig, ob die 3D-Darstellung persketivisch verzerrst ist, oder nicht, denn
a) ist sie es nicht, dann geben Cursorkoordinaten die Verschiebung zur Gerade an (die Gerade von weiter oben ist gemeint).
b) ist sie es doch, dann muss du einen Weg finden, die Verzerrung in die Berechnung miteinfließen zu lassen.
Greetz Laurin
Now these points of data make a beautiful line.
And we're out of beta. We're releasing on time.
And we're out of beta. We're releasing on time.
So, ich habe jetzt eine halbwegs annehmbare Lösung gefunden.
Ich hab leider nicht wirklich zurückrechnen können, deshalb vergleich ich jetzt einfach alle Koordinaten.
Das heißt:
1. Faces von vorne nach hinten ordnen (sonst klickt man aus versehen die dahinter an)
2. Ausrechnen, wo die auf dem Bildschirm sind
3. Mit den Cursorcoordinaten vergleichen
4. Wenn ein Treffer gefunden wurde -> Schleife verlassen
Das funktioniert zwar im Momnet noch, da ich nicht so viele Flächen habe, aber wenn das mal mehr werden sollte geht das glaub ich nicht mehr so gut.
Hat irgendwer noch eine schnellere Variante?
Ich hab leider nicht wirklich zurückrechnen können, deshalb vergleich ich jetzt einfach alle Koordinaten.
Das heißt:
1. Faces von vorne nach hinten ordnen (sonst klickt man aus versehen die dahinter an)
2. Ausrechnen, wo die auf dem Bildschirm sind
3. Mit den Cursorcoordinaten vergleichen
4. Wenn ein Treffer gefunden wurde -> Schleife verlassen
Das funktioniert zwar im Momnet noch, da ich nicht so viele Flächen habe, aber wenn das mal mehr werden sollte geht das glaub ich nicht mehr so gut.
Hat irgendwer noch eine schnellere Variante?
Ich kenn das Problem, hab aber auch keine grundsätzlich bessere Lösung als Laurin anzubeiten.
Zum Code vielleicht. Ich hab früher mal was mit Darkbasic gemacht. Da die Sprache stark auf 3D setzt, gabs dort ziemlich viel code für so was.
Schau doch mal dort vorbei, da sollte was zu finden sein, was Du vlt. verwenden könntest.
Zum Code vielleicht. Ich hab früher mal was mit Darkbasic gemacht. Da die Sprache stark auf 3D setzt, gabs dort ziemlich viel code für so was.
Schau doch mal dort vorbei, da sollte was zu finden sein, was Du vlt. verwenden könntest.
Das könnte weiterhelfen:
grapy
P ist der Punkt wo man sich im 3D-Raum befindet.
D ist die normalisierte Richtung.
V sind die 3 Punkte eines Dreiecks. (Man muss alle durchlaufen)
T gibt die Entfernung und UV die Position im Dreieck.
P ist der Punkt wo man sich im 3D-Raum befindet.
D ist die normalisierte Richtung.
V sind die 3 Punkte eines Dreiecks. (Man muss alle durchlaufen)
T gibt die Entfernung und UV die Position im Dreieck.
Code: Alles auswählen
Global U.f, V.f, T.f
Procedure RayTriangleIntersect(Px.f, Py.f, Pz.f, Dx.f, Dy.f, Dz.f, V0x.f, V0y.f, V0z.f, V1x.f, V1y.f, V1z.f, V2x.f, V2y.f, V2z.f)
; /* find vectors for two edges sharing vert0 */
E1x.f = V1x.f - V0x.f
E1y.f = V1y.f - V0y.f
E1z.f = V1z.f - V0z.f
E2x.f = V2x.f - V0x.f
E2y.f = V2y.f - V0y.f
E2z.f = V2z.f - V0z.f
; /* begin calculating determinant - also used to calculate U parameter */
Hx.f = (Dy.f * E2z.f) - (E2y.f * Dz.f)
Hy.f = (Dz.f * E2x.f) - (E2z.f * Dx.f)
Hz.f = (Dx.f * E2y.f) - (E2x.f * Dy.f)
; /* if determinant is near zero, ray lies in plane of triangle */
A.f = (E1x.f * Hx.f) + (E1y.f * Hy.f) + (E1z.f * Hz.f)
; /* culling is desired */.
If (A.f < 0.00001)
ProcedureReturn 0
EndIf
; /* calculate distance from vert0 to ray origin */
Sx.f = Px.f - V0x.f
Sy.f = Py.f - V0y.f
Sz.f = Pz.f - V0z.f
; /* calculate U parameter and test bounds */
U.f = (Sx.f * Hx.f) + (Sy.f * Hy.f) + (Sz.f * Hz.f)
If (U.f < 0.0) Or (U.f > A.f)
ProcedureReturn 0
EndIf
; /* prepare to test V parameter */
Qx.f = (Sy.f * E1z.f) - (E1y.f * Sz.f)
Qy.f = (Sz.f * E1x.f) - (E1z.f * Sx.f)
Qz.f = (Sx.f * E1y.f) - (E1x.f * Sy.f)
; /* calculate V parameter and test bounds */
V.f = (Dx.f * Qx.f) + (Dy.f * Qy.f) + (Dz.f * Qz.f)
If (V.f < 0.0) Or ((U.f + V.f) > A.f)
ProcedureReturn 0
EndIf
; /* calculate t, scale parameters, ray intersects triangle */
T.f = (E2x.f * Qx.f) + (E2y.f * Qy.f) + (E2z.f * Qz.f)
F.f = 1.0 / A.f
T.f = T.f * F.f
U.f = U.f * F.f
V.f = V.f * F.f
ProcedureReturn 1
EndProcedureüblicherweise rechnet man zurück von 2d nach 3d, dafür muß man aber an die projektionsmatrize kommen können. Unter OpenGL-GLU gibt es dafür sogar eine vorgefertigte funktion.
Leider hab ich mich nicht soviel mit der pb-ogre beschäftigt, kann also nicht sagen ob das da möglich ist. Wenn nicht, dann sollte man mal vorsichtig bei fred anfragen, ob er da nicht weiterhelfen kann.
Leider hab ich mich nicht soviel mit der pb-ogre beschäftigt, kann also nicht sagen ob das da möglich ist. Wenn nicht, dann sollte man mal vorsichtig bei fred anfragen, ob er da nicht weiterhelfen kann.