Kollision Maus/Terrain berechnen [gelöst]
@NTQ
Hab gesehen das du 2005 mal ein Paar Proceduren zur Vektorrechnung gemacht hast. Kann man das nicht auf mein Problem beziehen?
Gruß
Scarabol
PS
Hier der Link
http://www.purebasic.fr/german/viewtopic.php?t=3452
Hab gesehen das du 2005 mal ein Paar Proceduren zur Vektorrechnung gemacht hast. Kann man das nicht auf mein Problem beziehen?
Gruß
Scarabol
PS
Hier der Link
http://www.purebasic.fr/german/viewtopic.php?t=3452
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
- Froggerprogger
- Badmin
- Beiträge: 855
- Registriert: 08.09.2004 20:02
Wäre das Terrain eine Ebene, wäre vieles leichter, man könnte dann den Schnittpunkt sogar ohne 'Sehstrahl' direkt berechnen. Für das Terrain mit Sehstrahl bräuchte man eine Funktion, die zu einem x/y-Wert den z-Wert der Terrainoberfläche liefert.
So grob aus Erinnerung:
Wird ein Terrain nicht durch eine Höhenmap geliefert ? D.h. wenn ich die Höhe an einem x/y-Weltkoordinatenpunkt abfrage, dann suche ich die entsprechenden x'/y'-Koordinaten der Höhenmap und interpoliere linear zwischen x'/y' und x'+1/y'+1 für die Höhe an Zwischenpunkten (oder machen das moderne Terrains schon mit 3D-Splines??). Man kann das Interpolieren auch weglassen, dann kann es aber Probleme an scharfen Kanten (hohen Gradienten in der Heightmap) geben. Also ist es für dich möglich eine Funktion folgender Bauart zu basteln ?
Angenommen eine solche Funktion haben wir. Dann fallen mir ein paar weitere Fragen ein:
Gibt es hierfür nicht eigentlich anstelle der Winkel so einen LookAt-Vektor ? Dann bräuchte man diesen Winkelkram nicht.
Weitere Frage: Genügt es dir, den Schnittpunkt mit dem Terrain zu haben (also den Zielpunkt) ? Denn danach muss ja noch die Figur in die entsprechende Richtung bewegt werden. Bewegt man diese Figur eigentlich nur in x/y-Richtung und sie stellt sich automatisch auf die richtige Höhe ?
Nach Antworten auf diese Fragen, erscheint mir der Rest zumindest lösbar.

So grob aus Erinnerung:
Wird ein Terrain nicht durch eine Höhenmap geliefert ? D.h. wenn ich die Höhe an einem x/y-Weltkoordinatenpunkt abfrage, dann suche ich die entsprechenden x'/y'-Koordinaten der Höhenmap und interpoliere linear zwischen x'/y' und x'+1/y'+1 für die Höhe an Zwischenpunkten (oder machen das moderne Terrains schon mit 3D-Splines??). Man kann das Interpolieren auch weglassen, dann kann es aber Probleme an scharfen Kanten (hohen Gradienten in der Heightmap) geben. Also ist es für dich möglich eine Funktion folgender Bauart zu basteln ?
Code: Alles auswählen
Procedure.d GetTerrainZ(x.d, y.d) ; returns world-coord-z of terrainsurface for given world-coords x and y
Also x,y,z in Weltkoordinaten?1. Wo sich der Spieler befindet
Sind das zwei Winkel? Einer für horizontale, einer für vertikale Neigung? Welche Drehrichtung ? und im Bereich ]-pi,pi] oder [0,2pi[ ?2. Welchen Winkel die Kamera zu Achse Null (Norden) hat
Gibt es hierfür nicht eigentlich anstelle der Winkel so einen LookAt-Vektor ? Dann bräuchte man diesen Winkelkram nicht.
Also x,y,z in Weltkoordinaten?3. Wo sich die Kamera befindet
Also x,y-Koordinaten in Screenpixeln ?4. Die Mauskoordinaten hab ich natürlich auch Wink
Weitere Frage: Genügt es dir, den Schnittpunkt mit dem Terrain zu haben (also den Zielpunkt) ? Denn danach muss ja noch die Figur in die entsprechende Richtung bewegt werden. Bewegt man diese Figur eigentlich nur in x/y-Richtung und sie stellt sich automatisch auf die richtige Höhe ?
Nach Antworten auf diese Fragen, erscheint mir der Rest zumindest lösbar.
!UD2
Die Höhe läßt sich leicht herausfinden mit TerrainHeight(x,y) das laufen wäre also nicht das Problem.
Ich kann mich irren, aber ich bezweifle dass das finden eines angeklickten Punktes auf dem Ogre Terrain von PB aus möglich ist, mir würde jdenfall keine Lösung einfallen die ohne die konkreten Polygondaten auskommt.
Ich kann mich irren, aber ich bezweifle dass das finden eines angeklickten Punktes auf dem Ogre Terrain von PB aus möglich ist, mir würde jdenfall keine Lösung einfallen die ohne die konkreten Polygondaten auskommt.
Hallo Froggerprogger,
Keine Ahnung was du mit "Bereich ]-pi,pi] oder [0,2pi[ ?" meinst aber falls es ums Bogenmaß geht kann ich die Werte ebenfalls liefern.
Und zum Letzten: Ja Ja
Gruß
Scarabol
JaZitat:
1. Wo sich der Spieler befindet
Also x,y,z in Weltkoordinaten?
Ich hab den X-Winkel (Norden = 0), den Y Winkel (waagerecht = 0), LookAt-Vektor ist die Position des Entity. Die Winkel sind im Gradmaß aber auch im Bogenmaß verfügbar.Zitat:
2. Welchen Winkel die Kamera zu Achse Null (Norden) hat
Sind das zwei Winkel? Einer für horizontale, einer für vertikale Neigung? Welche Drehrichtung ? und im Bereich ]-pi,pi] oder [0,2pi[ ?
Gibt es hierfür nicht eigentlich anstelle der Winkel so einen LookAt-Vektor ? Dann bräuchte man diesen Winkelkram nicht.
Keine Ahnung was du mit "Bereich ]-pi,pi] oder [0,2pi[ ?" meinst aber falls es ums Bogenmaß geht kann ich die Werte ebenfalls liefern.
JaZitat:
3. Wo sich die Kamera befindet
Also x,y,z in Weltkoordinaten?
JaZitat:
4. Die Mauskoordinaten hab ich natürlich auch Wink
Also x,y-Koordinaten in Screenpixeln ?
Und zum Letzten: Ja Ja
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
@Zaphod
Die genauen Polygondaten lassen sich zwar nicht auslesen, aber nachrechnen wie in folgendem Thread geschrieben.
http://www.purebasic.fr/german/viewtopic.php?t=11842
Also hat man schon die genauen Daten der Polygone und sollte die Berechnung durchführen können.
Gruß
Scarabol
Die genauen Polygondaten lassen sich zwar nicht auslesen, aber nachrechnen wie in folgendem Thread geschrieben.
http://www.purebasic.fr/german/viewtopic.php?t=11842
Also hat man schon die genauen Daten der Polygone und sollte die Berechnung durchführen können.
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
- Froggerprogger
- Badmin
- Beiträge: 855
- Registriert: 08.09.2004 20:02
Man benötigt noch den Camera-Top-Vektor bzw. den Rotate-Winkel der Cam. Also den Winkel, der angibt mit welchem Winkel die Kamera um die Sichtachse gedreht ist. In PB scheint es keinen Befehl GetCameraTop oder GetCameraRotate zu geben, und der Funktion CameraRotate übergibt man den Wert, um den gedreht wird, nicht den absoluten Wert. Ein Mitspeichern der kumulierten Werte könnte daher irgendwann ungenau werden. Einfachste Lösung wäre, wenn du niemals CameraRotate nutzt, und daher 'oben' im Screen auch 'oben' in der Welt ist. Ist dem so ?
!UD2
Erstmal nein, aber ich versteh deine Aussage nicht so ganz.
"Man benötigt noch den [...] den Rotate-Winkel der Cam"
Hab ich doch schon dreimal geschrieben das ich den Winkel habe.
"und der Funktion CameraRotate übergibt man den Wert, um den gedreht wird, nicht den absoluten Wert"
???
Gruß
Scarabol
"Man benötigt noch den [...] den Rotate-Winkel der Cam"
Hab ich doch schon dreimal geschrieben das ich den Winkel habe.
"und der Funktion CameraRotate übergibt man den Wert, um den gedreht wird, nicht den absoluten Wert"
???
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
- Froggerprogger
- Badmin
- Beiträge: 855
- Registriert: 08.09.2004 20:02
Die Kamera kann sich ja um 3 Achsen drehen: Einmal links/rechts und hoch/runter. Damit legt man ja bereits die Sichtlinie fest. Alternativ kann man dies durch setzen des LookAt erreichen. Dabei bleibt aber immer oben im Screen oben in der Welt, also Wolken sind oben, der Boden unten.
Nun lässt sich aber die Kamera noch entlang der Sichtlinie herumdrehen, also bspw. so, dass z.B. der linke Bildschirmrand in den Himmel zeigt. Vergleichbar damit, dass man seinen Kopf nach rechts neigt. Dabei bleibt der LookAt unverändert.
Du schreibst:
Bei OpenGL gibt es hierfür noch einen Vektor, der anzeigt, wohin 'oben' im Screen in der Welt zeigt, bei PB habe ich nichts dergleichen finden können.
Wenn du das nirgendwo explizit änderst ist immer oben im Screen gleich oben in der Welt und die Sache ist wieder vereinfacht. Denn dann lässt sich aus "lookatpos - campos" der Sichtlinienvektor berechnen, anhand der x/y-Mausklickkoordinaten und dem FOV-Winkel die Winkeldrehungen in waagerechter und vertikaler Richtung und somit dann sofort die Linie, entlang derer nach Terrainkollisionen gesucht werden soll.
Man spart sich dann das Rechnen, dass bsp. ein Klick "links mittig" im Screen in der Welt nach "oben" geht, wenn die Camera nach rechts geneigt ist.
Nun lässt sich aber die Kamera noch entlang der Sichtlinie herumdrehen, also bspw. so, dass z.B. der linke Bildschirmrand in den Himmel zeigt. Vergleichbar damit, dass man seinen Kopf nach rechts neigt. Dabei bleibt der LookAt unverändert.
Du schreibst:
Ich interpretiere das als X-Winkel: In welche Himmelsrichtung wird geschaut, Y-Winkel: Wird nach oben oder unten geschaut. Fehlt: Wie stark ist das Bild nach links oder rechts entlang der Sichtlinie gekippt ?X-Winkel (Norden = 0), den Y Winkel (waagerecht = 0)
Bei OpenGL gibt es hierfür noch einen Vektor, der anzeigt, wohin 'oben' im Screen in der Welt zeigt, bei PB habe ich nichts dergleichen finden können.
Wenn du das nirgendwo explizit änderst ist immer oben im Screen gleich oben in der Welt und die Sache ist wieder vereinfacht. Denn dann lässt sich aus "lookatpos - campos" der Sichtlinienvektor berechnen, anhand der x/y-Mausklickkoordinaten und dem FOV-Winkel die Winkeldrehungen in waagerechter und vertikaler Richtung und somit dann sofort die Linie, entlang derer nach Terrainkollisionen gesucht werden soll.
Man spart sich dann das Rechnen, dass bsp. ein Klick "links mittig" im Screen in der Welt nach "oben" geht, wenn die Camera nach rechts geneigt ist.
!UD2
Jo sorry hatte ein Brett vorm Kopf da es wie du schon sagtest die Funktion zwar gibt aber ich sie nicht eingebaut habe und auch niemals benutzen werde. (Siehe Bild auf der ersten Seite)
Gruß
Scarabol
Gruß
Scarabol
Abgeschlossen Projekte:
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
Schreibmaschine, Bildschirmlupe, Wings3DtoOgreMeshConverter
Watch: PureArea
PB-V: 4
WinXP
- Froggerprogger
- Badmin
- Beiträge: 855
- Registriert: 08.09.2004 20:02
Hier ist ein lauffähiges Beispiel (basierend auf Terrain.pb aus den PB-Examples).
Kopiere es einfach in den Purebasic\Examples\Sources-Ordner und starte es.
Die Mathematik wurde doch erst recht knifflig, da man Rotationen um beliebige Achsen durchführen musste. Dann aber fiel mir ein viel einfacherer Weg ein um den entsprechenden 'Zielstrahl' (pointerDir) zu berechnen, der dann entlangbeschritten wird um den Schnittpunkt mit dem Terrain zu bestimmen.
Kopiere es einfach in den Purebasic\Examples\Sources-Ordner und starte es.
Die Mathematik wurde doch erst recht knifflig, da man Rotationen um beliebige Achsen durchführen musste. Dann aber fiel mir ein viel einfacherer Weg ein um den entsprechenden 'Zielstrahl' (pointerDir) zu berechnen, der dann entlangbeschritten wird um den Schnittpunkt mit dem Terrain zu bestimmen.
Code: Alles auswählen
; TerrainCollision.pb
;
; Example how to translate 2D-screencoordinates into a 3D-worldposition given by the first hit with the terrain
;
; If you want to use RotateCamera, you would have to change this example (setting up the up-vector again
; and recalculate some values supposed to be constant in this examples)
;
; To start this example copy it to the PureBasic\Examples\Sources - directory to let it reference the requested resources
;
; by Froggerprogger, 01.04.07
#CameraSpeed = 5
#Deg2Rad = #Pi / 180.0
#Rad2Deg = 1.0 / #Deg2Rad
; declared as global to get them from within Screen3DRequester
Global ScreenWidth, ScreenHeight
IncludeFile "Screen3DRequester.pb"
Define.f KeyX, KeyY, MouseX, MouseY
; a structure for a 3D-float-vector
Structure Vec3D
x.f
y.f
z.f
EndStructure
; some vector-math
Procedure.f Vec_ScalarProd(*v1.Vec3D, *v2.Vec3D) ; <v1, v2>
ProcedureReturn *v1\x * *v2\x + *v1\y * *v2\y + *v1\z * *v2\z
EndProcedure
Procedure.f Vec_Abs(*v1.Vec3D) ; |v1|
Protected z.f
z = Sqr(*v1\x * *v1\x + *v1\y * *v1\y + *v1\z * *v1\z)
ProcedureReturn z
EndProcedure
Procedure Vec_ScalarMul(*v1.Vec3D, f.f, *v.Vec3D = 0) ; v1 = f * v1
If *v = 0
*v = *v1
EndIf
*v\x = *v1\x * f
*v\y = *v1\y * f
*v\z = *v1\z * f
EndProcedure
Procedure Vec_VectorProd(*v1.Vec3D, *v2.Vec3D, *v.Vec3D) ; v = v1 x v2
*v\x = *v1\y * *v2\z - *v1\z * *v2\y
*v\y = *v1\z * *v2\x - *v1\x * *v2\z
*v\z = *v1\x * *v2\y - *v1\y * *v2\x
EndProcedure
Procedure Vec_Add(*v1.Vec3D, *v2.Vec3D, *v.Vec3D) ; v = v1 + v2
*v\x = *v1\x + *v2\x
*v\y = *v1\y + *v2\y
*v\z = *v1\z + *v2\z
EndProcedure
Procedure Vec_Sub(*v1.Vec3D, *v2.Vec3D, *v.Vec3D) ; v = v1 - v2
*v\x = *v1\x - *v2\x
*v\y = *v1\y - *v2\y
*v\z = *v1\z - *v2\z
EndProcedure
Procedure Vec_Copy(*v1.Vec3D, *v.Vec3D) ; v = v1
*v\x = *v1\x
*v\y = *v1\y
*v\z = *v1\z
EndProcedure
Procedure Vec_Set(x.f, y.f, z.f, *v.Vec3D) ; v = (x,y,z)
*v\x = x
*v\y = y
*v\z = z
EndProcedure
playerPos.Vec3D ; player's position (same as lookAt)
startPos.Vec3D ; player's startposition when automoving
targetPos.Vec3D ; player' targetposition when automoving
camOffset.Vec3D ; the camera's offset from which to look at the player
camPos.Vec3D ; the cameras position (playerPos + camOffset)
camDir.Vec3D ; the direction of the camera (playerPos - camPos)
up.Vec3D ; the camera's up-position
Vec_Set(0, 1, 0, @up)
pointerDir.Vec3D ; the line from camPos through the mousecursor
lVector.Vec3D ; (normalized) vector showing to the screen's left side orthogonal on camDir
tVector.Vec3D ; (normalized) vector showing to the screen's top orthogonal on camDir
screenHit.Vec3D ; the point where the surface given by lVector and tVector through playerPos is hit
scalar_lVectorCamDir.f ; <lVector, camDir> (precalculated for speed-up)
scalar_tVectorCamDir.f ; <tVector, camDir> (precalculated for speed-up)
vecprod_lVectorCamDir.Vec3D ; lVector x camDir (precalculated for speed-up)
vecprod_tVectorCamDir.Vec3D ; tVector x camDir (precalculated for speed-up)
factorPerPixel.f ; the factor for lVector and tVector for each screen-pixel
searchDepth.f ; searching for terrain-collision up to searchDepth times the player-distance
searchStep.f ; searching through depth with this stepsize
Vec_Set(200, 100, 200, @camOffset)
fov.f = 80 * #Deg2Rad ; the field of view to use
searchDepth = 4.0
searchStep = 0.01
animationSpeed.l ; ms for player to reach target
animationSpeed = 2000
targetReachtime.l ; time when to reach target
initialized.l = #False
If InitEngine3D()
Add3DArchive("Data\" , #PB_3DArchive_FileSystem)
InitSprite()
InitKeyboard()
InitMouse()
If Screen3DRequester()
AmbientColor(RGB(255,255,255))
CreateMaterial (0, LoadTexture(0, "Terrain_Texture.jpg"))
AddMaterialLayer(0, LoadTexture(1, "Terrain_Detail.jpg"), 1)
CreateTerrain("Terrain.png", MaterialID(0), 1, 1, 1, 4)
CreateCamera(0, 0, 0, 100, 100)
CameraLocate(0, 128, 25, 128)
CameraFOV(0, fov)
SkyDome("Clouds.jpg",10)
; load player-entity
LoadMesh (0, "Robot.mesh")
CreateMaterial(1, LoadTexture(1, "r2skin.jpg"))
CreateEntity(0, MeshID(0), MaterialID(1), 0, 0, 0)
ResizeEntity(0, 0.2, 0.2, 0.2)
; loads another mini-entity as 'bullet' for the animation
CreateEntity(1, MeshID(0), MaterialID(1), 0, 0, 0)
ResizeEntity(1, 0.1, 0.1, 0.1)
; set the initial playerposition
playerPos\x = 100
playerPos\z = 100
playerPos\y = TerrainHeight(playerPos\x, playerPos\z)
; start
Repeat
Screen3DEvents()
If ExamineKeyboard()
If KeyboardPushed(#PB_Key_Left)
KeyX = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Right)
KeyX = #CameraSpeed
Else
KeyX = 0
EndIf
If KeyboardPushed(#PB_Key_Up)
KeyY = -#CameraSpeed
ElseIf KeyboardPushed(#PB_Key_Down)
KeyY = #CameraSpeed
Else
KeyY = 0
EndIf
EndIf
If ExamineMouse()
MouseX + MouseDeltaX()
If MouseX > ScreenWidth
MouseX = ScreenWidth
ElseIf MouseX < 0
MouseX = 0
EndIf
MouseY + MouseDeltaY()
If MouseY > ScreenHeight
MouseY = ScreenHeight
ElseIf MouseY < 0
MouseY = 0
EndIf
EndIf
If initialized = #False
; set up some values that do not change for a fixed cam-offset
Vec_Add(@playerPos, @camOffset, @camPos) ; needed by the following
; set the cameraDir
Vec_Sub(@playerPos, @camPos, @camDir)
; set the lVector = norm(up x camDir)
Vec_VectorProd(@up, @camDir, @lVector)
abs.f = Vec_Abs(@lVector)
Vec_ScalarMul(@lVector, 1.0/abs, @lVector)
; set the tVector = camDir x lVector
Vec_VectorProd(@camDir, @lVector, @tVector)
abs.f = Vec_Abs(@tVector)
Vec_ScalarMul(@tVector, 1/abs)
; get the distance of cam to entity
dist.f = Vec_Abs(@camDir)
; set the factor per pixel
factorPerPixel = Tan(fov/2) * dist * 2.0 / ScreenHeight
; set the horizontal/vertical ranges
vRange.f = factorPerPixel * ScreenHeight/2.0
hRange.f = factorPerPixel * ScreenWidth/2.0
initialized = #True
EndIf
If MouseButton(#PB_MouseButton_Left)
; get the horizontal ratio
hRatio.f = (MouseX - ScreenWidth/2.0) / (ScreenWidth / 2.0)
; get the vertical ratio
vRatio.f = (MouseY - ScreenHeight/2.0) / (ScreenHeight / 2.0)
; build screenHit = playerPos - hRange * hRatio * lVector - vRange * vRatio * tVector
t1.Vec3D
Vec_ScalarMul(@lVector, hRange * hRatio, @t1)
t2.Vec3D
Vec_ScalarMul(@tVector, vRange * vRatio, @t2)
Vec_Sub(@playerPos, @t1, @screenHit)
Vec_Sub(@screenHit, @t2, @screenHit)
; pointerDir = screenHit - camPos
Vec_Sub(@screenHit, @camPos, @pointerDir)
; set pointerDir's length to dist
abs.f = Vec_Abs(@pointerDir)
Vec_ScalarMul(@pointerDir, dist/abs)
; scan the line until hit terrain
t.f = 0
While t < searchDepth
; get x and y along line: camPos + t * pointerDir
x.f = camPos\x + t*pointerDir\x
y.f = camPos\y + t*pointerDir\y
z.f = camPos\z + t*pointerDir\z
If y < TerrainHeight(x, z) Or y < 0
targetPos\x = x - searchStep * pointerDir\x
targetPos\y = y - searchStep * pointerDir\y
targetPos\z = z - searchStep * pointerDir\z
Vec_Copy(@playerPos, @startPos)
targetReachtime = ElapsedMilliseconds() + animationSpeed
Break
EndIf
t + searchStep
Wend
EndIf
If targetReachtime > ElapsedMilliseconds()
playerPos\x = targetPos\x - (targetReachtime - ElapsedMilliseconds()) * (targetPos\x - startPos\x) / animationSpeed
playerPos\z = targetPos\z - (targetReachtime - ElapsedMilliseconds()) * (targetPos\z - startPos\z) / animationSpeed
Else
playerPos\x + KeyX
playerPos\z + KeyY
EndIf
playerPos\y = TerrainHeight(playerPos\x, playerPos\z)
EntityLocate(0, playerPos\x, playerPos\y, playerPos\z)
; place the camera relative to the entity and look at player
Vec_Add(@playerPos, @camOffset, @camPos)
CameraLocate(0, camPos\x, camPos\y, camPos\z)
CameraLookAt(0, playerPos\x, playerPos\y, playerPos\z)
;EntityLocate(1, camPos\x + animationVal * pointerDir\x, camPos\y + animationVal * pointerDir\y, camPos\z + animationVal * pointerDir\z)
EntityLocate(1, targetPos\x, TerrainHeight(targetPos\x, targetPos\z), targetPos\z)
RenderWorld()
Screen3DStats()
StartDrawing(ScreenOutput())
Circle(MouseX, MouseY, 5, $0000FF)
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(0, 0, "hAngle : " + StrF(hAngle) + " vAngle : " + StrF(vAngle, 2))
DrawText(0, 20, "camPos (x y z): " + StrF(camPos\x) + "/" + StrF(camPos\y) + "/" + StrF(camPos\z))
DrawText(0, 40, "camDir (x y z): " + StrF(camDir\x) + "/" + StrF(camDir\y) + "/" + StrF(camDir\z))
DrawText(0, 60, "lVector (x y z): " + StrF(lVector\x) + "/" + StrF(lVector\y) + "/" + StrF(lVector\z))
DrawText(0, 80, "tVector (x y z): " + StrF(tVector\x) + "/" + StrF(tVector\y) + "/" + StrF(tVector\z))
DrawText(0, 100, "pointerDir (x y z): " + StrF(pointerDir\x) + "/" + StrF(pointerDir\y) + "/" + StrF(pointerDir\z))
DrawText(0, 120, "t1 (x y z): " + StrF(t1\x) + "/" + StrF(t1\y) + "/" + StrF(t1\z))
DrawText(0, 140, "screenHit (x y z): " + StrF(screenHit\x) + "/" + StrF(screenHit\y) + "/" + StrF(screenHit\z))
DrawText(0, 160, "hRange/vRange: " + StrF(hRange) + "/" + StrF(vRange, 2))
DrawText(0, 180, "EntityPos (x y z) : " + StrF(EntityX(1)) + "/" + StrF(EntityY(1)) + "/" + StrF(EntityZ(1)))
StopDrawing()
FlipBuffers()
Until KeyboardPushed(#PB_Key_Escape) Or Quit = 1
EndIf
Else
MessageRequester("Error", "The 3D Engine can't be initialized",0)
EndIf
End!UD2