Also weil es ziemlich genau deiner Problemstellung entspricht, poste ich den Code, den ich in der Ogl Bibliothek für die 2D-Objektselektion verwende und füge gegebenenfalls einige deutsche Kommentare ein:
<!--pas--></span><table border='0' align='center' width='95%' cellpadding='3' cellspacing='1'><tr><td>Delphi-Source </td></tr><tr><td id='CODE'><!--pas1--><pre>// returns the visible objects <span class='reserved'>in</span> a given rectangle <span class='reserved'>function</span> ViewContainsAt(left,top,width,height: GLint; bt: PGLuintTable; max: integer) : integer; // left,top,width,height repräsentieren ein kleines Viereck um den Mauscursor
<span class='reserved'>var</span> l : PObjList; viewport : TVector4i;
<span class='reserved'>begin</span> glSelectBuffer(max, PGLuint(bt)); // Selectionbuffer setzen glRenderMode(GL_SELECT); glInitNames; // Namestack leeren glPushName(<span class='integer'>0</span>); // einen Namen auf den Stack legen glGetIntegerv(GL_VIEWPORT, Addr(viewport)); // Viewportgröße zwischenspeichern
// sämtliche Objekte (<span class='reserved'>in</span> deinem Fall Heightmappatches) im Frustum zeichnen, vor jeder Darstellung mittels glLoadName den // Namen auf dem Namestack aktualisieren l := OglObjList; glMatrixMode(GL_MODELVIEW); glLoadMatrixf(Addr(OglViewMatrix)); FrustumCalculate; // verkleinertes Frustum für schnelle Selektion berechnen <span class='reserved'>while</span> l <> <span class='reserved'>NIL</span> <span class='reserved'>do</span> <span class='reserved'>begin</span> l.me.FillSelectionBuffer; // ganz normale Zeichenroutine, nur dass mit glLoadName ein eindeutiger Name zuvor übergeben wird l := l.next; <span class='reserved'>end</span>;
// ursprünglichen Viewport wiederherstellen OglResizeViewport(ViewPort[<span class='integer'>2</span>], ViewPort[<span class='integer'>3</span>]); result := glRenderMode(GL_RENDER); // result ist die Anzahl der Objekte die beim Zeichnen im Viewport waren // <span class='reserved'>in</span> bt[i*<span class='integer'>4</span>+<span class='integer'>3</span>] steht der eindeutige Name des Objektes i drin <span class='reserved'>end</span>; </pre><!--pas2--></td></tr></table><span class='postcolor'><!--pas3-->
OglResizeViewport ersetzt du in deinem Fall durch folgende Befehle im Code:
glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(OglFieldOfView,OglAspectRatio*Width/Height,OglZNear,OglZFar); // Width und Height sind die Ausdehnung deines Viewports glMatrixMode(GL_MODELVIEW); glLoadMatrixf(Addr(OglViewMatrix)); // entspricht deiner Standardtransformationsmatrix FrustumCalculate; </pre><!--pas2--></td></tr></table><span class='postcolor'><!--pas3-->
FrustumCalculate musst du natürlich durch deine eigene Frustumberechnung ersetzen (oder ganz weglassen, wenn du keine hast). Die ganzen Ogl... Variablen sollten ihre Bedeutung eh über den Namen preisgeben - und die hast du, unter eigenem Namen, wahrscheinlich auch schon in deinem Projekt.
Ich hoffe das hilft dir weiter, es gibt aber, wenn mich nicht alles täuscht, ohnehin ein Selektionstutorial auf dieser Seite.
Mit der exakten Position wirds schwieriger - da musst du sozusagen einen Strahl durch die Position des Mauscursors im Fenster schicken (am Einfachsten erst mal zwei Punkte darauf an unterschiedlichen Z-Koordinaten durch gluUnProject ausrechnen) und dann die Intersektion mit deinem Heightfield berechnen (das bedeutet, dass du die Heigthfieldkoordinaten selbst transformieren musst, damit du die Viewkoordinaten herausbekommst). Für diesen Aufwand wirst du aber auch belohnt: du bekommst die exakte globale 3D-Koordinate auf dem Heightfield (oder irgendeinem anderen Objekt) zurück, mit der du dann machen kannst, was du willst.
Wäre dein Heightmap eine Ebene, würde dies das Ganze sehr vereinfachen, so aber musst du in den sauren Apfel beissen.
Mitglieder in diesem Forum: 0 Mitglieder und 11 Gäste
Du darfst keine neuen Themen in diesem Forum erstellen. Du darfst keine Antworten zu Themen in diesem Forum erstellen. Du darfst deine Beiträge in diesem Forum nicht ändern. Du darfst deine Beiträge in diesem Forum nicht löschen. Du darfst keine Dateianhänge in diesem Forum erstellen.