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
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 33 34 35 36 37 38 |
public class RayPicker { public Vector3f currentRay; private Matrix4f projectionMatrix; private Matrix4f viewMatrix; private ViewCamera viewCamera; public RayPicker(ViewCamera viewCamera, Matrix4f projectionMatrix) { this.viewCamera = viewCamera; this.projectionMatrix = projectionMatrix; this.viewMatrix = MatrixMath.createViewMatrix(viewCamera); } public void tick() { viewMatrix = MatrixMath.createViewMatrix(viewCamera); currentRay = calculateMouseRay(); } private Vector3f calculateMouseRay() { Vector4f clipCoords = new Vector4f(0, 0, -1, 1); Vector4f eyeCoords = toEyeCoords(clipCoords); return toWorldCoords(eyeCoords); } private Vector3f toWorldCoords(Vector4f eyeCoords) { Matrix4f invertedView = Matrix4f.invert(viewMatrix, null); Vector4f rayWorld = Matrix4f.transform(invertedView, eyeCoords, null); Vector3f mouseRay = new Vector3f(rayWorld.x, rayWorld.y, rayWorld.z); mouseRay.normalise(); return mouseRay; } private Vector4f toEyeCoords(Vector4f clipCoords) { Matrix4f invertedProjection = Matrix4f.invert(projectionMatrix, null); Vector4f eyeCoords = Matrix4f.transform(invertedProjection, clipCoords, null); return new Vector4f(eyeCoords.x, eyeCoords.y, -1, 0); } } |
Quellcode |
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
boolean picked = false; for (float i = 0; i < 10; i+=0.1f) { Vector3f stop = new Vector3f( viewCamera.getCameraPosition().x + level.levelCollisionPicker.currentRay.x * i + 0.5f, viewCamera.getCameraPosition().y + level.levelCollisionPicker.currentRay.y * i + 0.5f, viewCamera.getCameraPosition().z + level.levelCollisionPicker.currentRay.z * i + 0.5f ); Tile pickedTile = level.getTile(stop); if(pickedTile.block != Blocks.air) { rayPickedTile = stop; picked = true; break; } } if(!picked) rayPickedTile = null; |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »MisterSebigunner« (06.06.2017, 19:10) aus folgendem Grund: Quellcode überarbeitet, damit man ein funktionales Ergebnis hat.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Administrator
Da deine Kamera kein Punkt ist, sondern eine Fläche, wäre es sogar sehr schlecht, wenn der Ray von der Mitte der Kamera ausgehen würde, statt von dort, wo sich der Cursor befindet.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Da deine Kamera kein Punkt ist, sondern eine Fläche, wäre es sogar sehr schlecht, wenn der Ray von der Mitte der Kamera ausgehen würde, statt von dort, wo sich der Cursor befindet.
Die Kamera an sich ist normalerweise schon ein "Punkt" (unten im Bild "Camera origin"). Die Bildebene, die mit der Near Clipping Plane identisch ist, schwebt in Blickrichtung irgendwo davor. Die Kameraposition liegt mit jedem Picking Ray auf einer Geraden. Der einzige Nachteil, wenn man die Kameraposition als Startpunkt für den Picking Ray nimmt (statt den Punkt, wo die Bildebene geschnitten wird), ist, dass man dann Objekte anklicken könnte, die von der Near Clipping Plane weggeschnitten werden.
Community-Fossil
Beruf: Teamleiter Mobile Applikationen & Senior Software Engineer
Wenn du wirklich genau das meinst, was da steht, dann nein. Wie ich schon im ersten Post sagte, wäre es fatal, wenn du beim Raypicking von der Mitte der Near-Plane ausgehst. Der Cursor ist schließlich nicht in der Mitte.Bei OpenGL ist der Ursprung doch in der Mitte des Bildes und daher doch mittig auf der Near clipping plane, oder nicht?
Wenn du wirklich genau das meinst, was da steht, dann nein. Wie ich schon im ersten Post sagte, wäre es fatal, wenn du beim Raypicking von der Mitte der Near-Plane ausgehst. Der Cursor ist schließlich nicht in der Mitte.
Er drückt sich einfach ungünstig aus. Er meint den Ray der durch die Clipping Planes geht und im Origin der Kamera startet. Das ist ja in dem Fall das was er möchte.
C-/C++-Quelltext |
|
1 2 3 4 5 6 |
Vector4f tmp = inverseProjection * clipCoords; tmp = tmp / tmp.w tmp = inverseView * tmp ray.origin = eyePos ray.direction = Vector3f(tmp) //einfach die w-Komponente weglassen |
Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »equinox« (06.06.2017, 17:57)
Werbeanzeige