|
JLI Spieleprogrammierung
|
Vorheriges Thema anzeigen :: Nächstes Thema anzeigen |
Autor |
Nachricht |
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 09.07.2007, 12:23 Titel: Vektor Projektionen |
|
|
Hi,
ich habe ein kleines Mathe Problem in meiner Engine. Es geht um das projizieren und Deprojizieren (heißt das so? auf engl. heißts auf jeden Fall unproject) von Vektoren. D.h., ich möchte einen Vektor aus dem 3D-Raum in Bildschirmkoordinaten und zurück konvertieren. Das Erstere ist kein Problem, dazu hab ich folgende Funktion in meiner Engine: CPP: | ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// desc: calculate the screen coordinates of a specified position
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
template<typename T> inline dxr::maths::point<T> dxr::maths::vecProject( const dxr::maths::vector<T>& vec,
const dxr::maths::matrix<T>& viewProjMat,
const T& scrWidth, const T& scrHeight )
{
// get the transformed vecotr
const vector<T> tmp( vec * viewProjMat );
// return the screem coordinates of the vector
return point<T>( scrWidth*static_cast<T>(0.5) + tmp.x*scrWidth*static_cast<T>(0.5),
scrHeight*static_cast<T>(0.5) - tmp.y*scrHeight*static_cast<T>(0.5) );
} |
Das zweite aber (Bildschirmkoordinaten 3d-Koord., also eigtl das Ganze nur rückwärts) macht mir einige Probleme... Es wäre auf jeden Fall einfach wenn man einen festen Viewport hätte, da aber die Kamera rotieren und sich bewegen kann und so muss man die Viewmatrix und die Projectionmatrix mitberücksichtigen. Kann mir einer von euch den Algorithmus kurz erläutern? Thx
btw: es gibt in der D3DX-Bibliothek die Funktionen D3DXVec3Project und D3DXVec3Unproject, nur bringt mir das nicht viel, da ich ja nicht nur die Funktion haben will, sondern auch die Technik verstehen will.
Gruß DXer |
|
Nach oben |
|
|
Jonathan_Klein Living Legend
Alter: 37 Anmeldedatum: 17.02.2003 Beiträge: 3433 Wohnort: Siegerland Medaillen: Keine
|
Verfasst am: 09.07.2007, 15:34 Titel: |
|
|
von 2d auf 3d Projezieren hat das Problem, das es keinen eindeutigen Punkt gibt. Du würdest als Lösung also einen Strahl enthalten, der von er Kamera durch den Bildschirm in die Szene geht. Wenn du noch einen Tiefenwert hast, könntest du halt die Position am Strahl ausrechnen und so einen eindeutigen Punkt bekommen.
Um so Strahlen auszurechnen hatte ich mal bei meinem Raytracer was, allerdings bin ich mir fast sicher, das es auch einen schnellen Weg mithilfe der Matrizen gibt. Meiner war nämlich, naja, selber hergeleitet und eine unoptimierte, recht elementare geometrische Überlegung. _________________ https://jonathank.de/games/ |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 09.07.2007, 15:52 Titel: |
|
|
stimmt, das mit dem Z-Wert hatte ich vergessen zu erwähnen. Ich hab den Prototypen der Funktion so gemacht, dass der Benutzer zusätzlich zu den Koordinaten einen gewünschten z-Wert übergibt. Der letztendliche Vektor sollte an diesen Z-Wert ausgerichtet werden (wozu man auch die Proj-Matrix braucht). Ein kleines Beispiel:
Bei einer Auflösung von 640 * 480 und einer Ausdehnung von -1.0 bis +1.0 (bei Z = 0) entsprechen:
Code: | punkt(160, 240) -> (übergebener Z-Wert = 0) -> vektor(0.5, 0.0, 0.0)
punkt(160, 240) -> (übergebener Z-Wert = 1) -> vektor(0.75, 0.0, 1.0) |
Gruß DXer |
|
Nach oben |
|
|
Dr. Best Senior JLI'ler
Alter: 34 Anmeldedatum: 17.06.2004 Beiträge: 269 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 10.07.2007, 01:45 Titel: |
|
|
Hab den Thread jetzt nicht komplett gelesen, aber ich denke dieser Codeschnippsel aus meiner Engine dürfte hilfreich für dich sein:
CPP: | C3DVector ProjSpacePos(ScreenPosX,ScreenPosY),1.0f);
CCamera* pCamera=pUltimate3D->GetCamera(iCamera);
if(!pCamera){
return false;
}
// Compute the projection space position (z is assumed to be 1)
D3DVIEWPORT8 Viewport=pCamera->GetViewport();
D3DXMATRIX ProjTransformation=*pCamera->GetProjTransformation();
ProjSpacePos.x=(((2.0f*ProjSpacePos.x)/Viewport.Width)-1.0f)/ProjTransformation._11;
ProjSpacePos.y=-(((2.0f*ProjSpacePos.y)/Viewport.Height)-1.0f)/ProjTransformation._22;
ProjSpacePos.z=1.0f;
// Calculate the inverse world to projection space transformation
D3DXMATRIX InvViewTransformation=(*pCamera->GetViewTransformation());
float Determinant;
D3DXMatrixInverse(&InvViewTransformation,&Determinant,&InvViewTransformation);
if(Determinant==0.0f){
return false;
}
// Transform the projection space position back to world space
ProjSpacePos*=InvViewTransformation;
// Subtract the camera position
ProjSpacePos-=C3DVector(pCamera->GetPosition());
// Normalize the vector
ProjSpacePos.Normalize(); |
Der Code ist für sich natürlich unvollständig, aber ich schätze du verstehst was gemeint ist . ProjSpacePos enthält am Ende des Codes einen normierten World-Space-Richtungsvektor der von der Kameraposition aus in Richtung der angegebenen Bildschirmkoordinate zeigt. _________________
Ich bin da, wer noch? |
|
Nach oben |
|
|
DirectXer Dark JLI'ler
Anmeldedatum: 05.02.2005 Beiträge: 1201 Wohnort: Köln Medaillen: Keine
|
Verfasst am: 10.07.2007, 11:04 Titel: |
|
|
ah thx, das hat mir den richtigen ansatz gezeigt
danke schön!
Gruß DXer |
|
Nach oben |
|
|
|
|
Du kannst keine Beiträge in dieses Forum schreiben. Du kannst auf Beiträge in diesem Forum nicht antworten. Du kannst deine Beiträge in diesem Forum nicht bearbeiten. Du kannst deine Beiträge in diesem Forum nicht löschen. Du kannst an Umfragen in diesem Forum nicht mitmachen.
|
Powered by phpBB © 2001, 2005 phpBB Group Deutsche Übersetzung von phpBB.de
|