Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
Hallo,
kann mir jemand sagen wie ich den Mittelpunkt meiner aktuellen Szene berechnen kann?
Ich brauche die Y, Y und Z-Koordinaten des Punktes in der Mitte meiner Szene.
Registriert: Sa Mai 04, 2002 19:48 Beiträge: 3830 Wohnort: Tespe (nahe Hamburg)
Liegt entweder an der frühen Stunde oder ich erfasse die Frage nicht ganz... 0/0/0... oder welches Zentrum meinst Du? Schließlich wirst Du dort im Normalfall von ausgehend die Objekte platzieren. Definiere also nochmal genau, was Du unter dem "Mittelpunkt der Szene" verstehst.
_________________ "Light travels faster than sound. This is why some people appear bright, before you can hear them speak..."
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
Wenn ich eine erste Szene aufbaue deren Mittelpunkt in 0/0/0 liegt und diese dann um beliebig viele Einheiten in eine beliebige Richtung verschiebe, dann liegt der neue Mittelpunkt meiner Szene nicht mehr in 0/0/0. Diesen Punkt habe ich ja verschoben.
Ich habe versucht den Mittelpunkt aus dem Frustum zu berechnen, bin aber bisher erfolglos geblieben.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Normal solltest du den Mittelpunkt deine Szene direkt aus der Modelview Matrix entnehmen können. Transformationen werden da ja meines wissens direkt drin abgespeichert. Bin mir aber nicht 100% sicher. Auch vorrausgesetzt, dass ich das verstanden habe.
Registriert: Sa Nov 13, 2004 11:00 Beiträge: 229 Wohnort: Steinhude
wie Lossy schon gesagt hat, werden die Verschiebung direkt in der Modelviewmatrix abgespeichert, und zwar in der letzten Spalte.
Dabei OGL die Matrizen iirc spaltenweise abgespeichert werden, entsprichen somit die letzen 4 werte der Matrix der Positionsangabe in der reihenfolge x, y, z, w (wobei w in der regel 1 sein sollte und dann ignoriert werden kann)
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
Ich dachte, dass man aus dem Frustum errechnen kann wo dessen Mittelpunkt ist. Da man beim Frustum-Culling ja erkennen kann ob eine angegebene Koordinate im Frustum liegt sollte man doch auch herausfinden können, wo dessen Mittelpunkt ist.
Registriert: So Sep 26, 2004 05:57 Beiträge: 190 Wohnort: Linz
Die Frustum kannst du dir vorstellen wie ein 3D-Objekt welches du einmal definierst, und dann beliebig im Raum herum schiebst (oder um genau zu sein den Raum herum schiebst und das Objekt still steht). Das 3D-Objekt ist hierbei eine Pyramide deren Spitze _immer_ im 0-Punkt liegt.
Das herum schieben des Raumes machst du mit der Modelview Matrix, also steht dort auch drinnen wo du bist. Jedoch wurde bisher (soweit ich das überflogen hab) noch nicht erwähnt, dass du ja den Raum verschiebst und die Kamera still steht, jedoch dadurch die Kamera im Verhältnis zum Raum genau in die entgegengesetzte Richtung bewegt wird.
Also wenn 2 Personen - nenen wir sie Betrachter und Weltmittelpunkt :-) - an einem Punkt stehen, und dann geht der Weltmittelpunkt 10 Meter nach rechts, dann steht der Betrachter 10 Meter links vom Weltmittelpunkt.
=> Letzte Spalte der Modelview Matrix nehmen und invertieren, dann hast du deine Kameraposition.
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
erst einaml vielen Dank für die Anregungen, aber die helfen mir nicht wirklich weiter.
Wenn ich eine Szene aufbaue mit einem Haus und einem Baum und gebe diesen Objekten jetzt Koordinaten, sieht das so aus (vereinfacht):
Baum := 0, 0, 0
Haus := 10, 0, 20
Der Baum steht also links vor dem Haus. Wenn ich mit gluLookAt (0, 10, -20. 0, 0, 0, 0, 1, 0) arbeite, steht das Haus im Mittelpunkt der Szene und ich schaue von oben darauf herunter.
Wenn ich diese Szene jetzt um zehn Einheiten nach rechts verschiebe, haben mein Baum und das Haus immer noch die selben Koordinaten, werden aber weiter rechts gezeichnet.
Ich könnte jetzt natürlich versuchen nachzuhalten um wieviele Einheiten ich verdreht und verschoben habe um immer wieder auf den eigentlichen Mittelpunkt der Szene zurückkommen zu können aber das finde ich zu aufwendig und fehleranfällig.
Ich brauche also eine Funktion die mir den augenblicklichen Mittelpunkt meiner sichtbaren Szene zurückgibt.
Da ich beim FrustumCulling sagen kann ob ein Punkt 1000,-100,20000 oder 0,0,0 oder ... zur Zeit sichtbar ist oder nicht, müsste ich doch auch aus den beim FrustumCulling zur Verfügung stehenden Informationen genau den Mittelpunkt des durch das Frustum beschriebenen Quaders errechnen können. Das möchte ich gerne tun.
Registriert: So Feb 06, 2005 17:29 Beiträge: 187
Programmiersprache: C, C++
Vielleicht sitz ich ja gerade aufm Schlauch, aber ich hab keine Ahnung, wie du dir das mit dem Frustum vorstellst
Zitat:
Ich könnte jetzt natürlich versuchen nachzuhalten um wieviele Einheiten ich verdreht und verschoben habe um immer wieder auf den eigentlichen Mittelpunkt der Szene zurückkommen zu können aber das finde ich zu aufwendig und fehleranfällig.
Na, aufwendig ist es nicht, nur vielleicht nicht optimal ...
Ich wundere mich nur die ganze Zeit schon, wofür den Mittelpunkt überhaupt brauchst?
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
Ich habe eine Liste von Objekten. Diese Objekte haben Namen, Koordinaten, Längen, Breiten, Farben, Texturen, usw.
Diese Objekte zusammen bilden eine Struktur, die ich dem Benutzer am Bildschirm anzeige. Der Benutzer kann beliebig mit der Maus die Struktur verschieben, drehen, zoomen und noch einige Sachen mehr. Wenn ich die Szene das erste mal aufbaue, mache ich das mit gluLookAt. Damit ist ein bekannter Punkt in der Mitte der Szene angebracht. Jetzt kann ich verschieben, drehen, ...
Danach weiss ich nicht, an welcher Bildschirkoordinate sich ein bestimmter Punkt befindet.
Wenn der Benutzer jetzt auf ein Objekt in der Liste klickt, soll dieses Objekt markiert dargestellt werden. Das ist kein Problem, wenn sich das Objekt im sichtbaren Bereich befindet. Mit der Funktion IsPointWithin meiner Frustum-Klasse kann ich genau das feststellen. Ist der Punkt im sichtbaren Bereich, markiere ich ihn. Ist er nicht im sichtbaren Bereich, will ich diesen Punkt zuerst in die Bildschirmmitte holen und dann markieren. Dafür brauche ich die Koordinate des Punkts, der jetzt den Mittelpunkt meiner sichtbaren Szene darstellt.
Ist z.B. zuerst der Punkt 0,0,0 in der Bildschirmmitte und ich bewege den dann um 1000000 (ist ein bisschen übertriebn, ich weiß) Einheiten nach rechts, dann ist danach der Punkt -1000000,0,0 in der Bildschirmmitte. Diesen Punkt will ich herausfinden...
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
Tschuldigung, dass ich mal wieder Tomaten auf den Augen und Brei im Hirn hatte!
Du hast recht: die Matrix gibt die gewünschten Infos her. Ich muss aber nicht die invertierte, sondern die normale Modelview Matrix nehmen. Dann habe ich den Benutzerstandort. Wenn ich dann den Z-Wert so verändere dass die Szene vor mir steht, habe ich es.
Registriert: Do Jun 09, 2005 13:48 Beiträge: 117 Wohnort: Sankt Augustin
nach einigen hin und her bin ich doch noch auf die Lösung gekommen:
gluUnProject
Da gibt es eine Funktion die genau das mach was ich möchte und keiner sagt es mir...
so was.
aber das kann ja mal passieren.
Code:
function OpenGLPos (FglDC: HDC; FglRC: HGLRC; winX,winY,winZ:double): TGLVector;
var
viewport: TGLVectori4;
modelview: TGLMatrixd4;
projection: TGLMatrixd4;
rX, rY, rZ:double;
begin
InitVector (result,0,0,0);
// Achtung:
// wenn mehrere fenster offen sind und die drehung bei mindestens einem
// fenster eingeschaltet ist, wird nicht immer auf den richtigen rendering-
// bzw. device context zugegriffen
if wglMakeCurrent(FglDC,FglRC)then
begin
glGetDoublev(GL_MODELVIEW_MATRIX,@modelview );// Get the Current Modelview matrix.
glGetDoublev(GL_PROJECTION_MATRIX,@projection );// Get the Current Projection Matrix.
glGetIntegerv(GL_VIEWPORT,@viewport );// Get the Current Viewport.
gluUnProject(winX, winY, winZ,
modelview, projection, viewport,// Get the vector for the current position
rX, rY, rZ);// determined by parameters.
InitVector (result, rX, rY, rZ);// And Return it from the function.
end;
end;
winZ muss eigentlich nicht an diese funktion übergeben werden aber in meinem speziellen fall habe ich diese variable vor dem Aufruf von OpenGLPos ermittelt. Man kann sie aber aus der Parameterleiste herausnehmen und folgendermaßen zuweisen:
Code:
if wglMakeCurrent(FglDC,FglRC)then
begin
glGetIntegerv(GL_VIEWPORT,@viewport );// Get the Current Viewport
winX :=round(viewport[2]/2);// zentrum des viewports horizontal
winY :=round(viewport[3]/2);// zentrum des viewports vertikal
//glReadPixels(round(winX), Round(winY), 1, 1,
// GL_DEPTH_COMPONENT,
// GL_FLOAT, @winZ ); //Read the Depth value at the current X and Y position
// wenn sich an der position xinX,winY kein objekt befindet, gibt
// glReadPixels 1 zurück. das bedeutet, dass von OpenGLPos die gesamte
// tiefe des tiefenpuffers zurückgegeben wird. da das netz aber nicht zu
// weit vom betrachter weg sein soll, reduziere ich winZ etwas und
// glReadPixels wird überflüssig.
winZ :=0.999;
Ihr müsst natürlich die Kommentarzeichen vor glReadPixels entfernen und die Zuweisung von "winZ := 0.999" entfernen.
Registriert: Do Dez 05, 2002 10:35 Beiträge: 4234 Wohnort: Dortmund
Andyh hat geschrieben:
gluUnProject
Da gibt es eine Funktion die genau das mach was ich möchte und keiner sagt es mir...
Na ja. Wir können es dir natürlich auch nur so beantworten wie wir es verstanden haben. Und wenn wir falsch liegen, dann musst du uns natürlich berichtigen. Wie auch immer du das dann anstellst.
Aber es freut mich ja zu sehen, dass du dich in das Thema verbissen hast und es auch ohne Hilfe hinbekommen hast.
Mitglieder in diesem Forum: 0 Mitglieder und 4 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.