#1 05.12.2011 08:50:24

Gewuerzgurke
Member
Registriert: 15.09.2008
Beiträge: 47
Web-Seite

D3DXVec3Project erzeugt Fehler

Hallo,
bei bir erzeugt die Funktion D3DXVec3Project einen Fehler, sobald die X, Y oder Z-Koordinate des Punktes gleich der X,Y oder Z-Komponente der Kameraposition, die ich in D3DXMatrixLookAtLH angebe, ist. Ich verwende die Header von http://www.clootie.ru.

Hatte sonst schon jemand dieses Problem?

Offline

 

#2 05.12.2011 14:24:27

Gnietschow
ProMember
Ort: Berlin
Registriert: 20.06.2007
Beiträge: 237

Re: D3DXVec3Project erzeugt Fehler

Ich hab noch nie mit der Funktion gearbeitet, aber ich denke mal das ist korrekt. Schließlich kann die Kameraposition nicht direkt auf die normalisierten Gerätekoordinaten abgebildet werden, da der Punkt ja überall auf dem Bildschirm liegen könnte. Denke mal das ist ein Division durch 0 Problem bei der Projektion. Normalerweise sollte man auch keine Punkte außerhalb des View Frustums projizieren. Wozu brauchst du das denn?


Es gibt 10 Gruppen von Menschen - die die das Binärsystem verstehen und die anderen.  :-)
Vegetarier essen meinem Essen das Essen weg ;)
-------------------------------------------------------------------------------------------------------------------
Der Community-Hub für Videospiele: gameloop.io

Offline

 

#3 05.12.2011 17:09:45

Gewuerzgurke
Member
Registriert: 15.09.2008
Beiträge: 47
Web-Seite

Re: D3DXVec3Project erzeugt Fehler

Also, meine Kameraposition sieht so aus:

Code: delphi

 viewparams.b   := d3dpp.backbufferwidth / d3dpp.backbufferheight;
 viewparams.a   := d3dx_pi / 180 * 90;
 viewparams.pos := d3dxvector3(0,0,-1);
 viewparams.dir := d3dxvector3(0,0,0);
 viewparams.up  := d3dxvector3(0,1,0);

 d3dxmatrixlookatlh(viewparams.matview,viewparams.pos,viewparams.dir,viewparams.up);
 d3ddev9.settransform(d3dts_view, viewparams.matview);
 d3dxmatrixperspectivefovlh(viewparams.matproj,viewparams.a,viewparams.b,0.01,100);
 d3ddev9.settransform(d3dts_projection, viewparams.matproj);

 // Test mit unterschiedlichen Koordinaten:
 pos3d.x := 0.1;   pos3d.y := 0.5;  pos3d.z := 0;    // Kein Fehler
 pos3d.x := 0;   pos3d.y := 0.5;  pos3d.z := 0;    // Fehler
 pos3d.x := 0.00000000000000000000000000000000000001;   pos3d.y := 0.5;  pos3d.z := 0;    // Fehler
 pos3d.x := 0.000000000000000000000001;   pos3d.y := 0.5;  pos3d.z := 0;    // Kein Fehler
 pos3d.x := 0.1;   pos3d.y := 0.5;  pos3d.z := -1;    // Fehler

 d3dxvec3project(pos2d,pos3d,viewport,viewparams^.matproj,viewparams^.matview,viewparams^.matworld);             // Das record ViewParams wird hier als Pointer übergeben - ich kann mir aber nicht vorstellen, dass das der Fehler ist (Werde ich aber testen).

Immer wenn eine Koordinate gleich oder fast gleich mit der - des "Auges" ist, kommt der Fehler. Dort steht dann etwas, wie "Exception-Klasse >> External: ? <<".

Das ärgerliche: Weil es nicht nur bei exakter Gleicheit passiert, sondern auch bei Abweichungen im Bereich 10^-38, kann ich das nicht einfach mit einer Sicherheitsabfrage, verbunden mit einer minimalen Verschiebung des Punktes, lösen. Man müsste irgendwie herausfinden, wie weit dieser Abweichungsbereich unter welchen Bedingungen ist...

Die Punkte liegen übrigens im ganz regulären Sichtbereich. Ich werde mal testen, ob sich normale Bildpunkte dort abbilden lassen, aber eigentlich müssten sie das... roll

Beitrag geändert von Gewuerzgurke (05.12.2011 17:18:08)

Offline

 

#4 05.12.2011 18:06:49

Gnietschow
ProMember
Ort: Berlin
Registriert: 20.06.2007
Beiträge: 237

Re: D3DXVec3Project erzeugt Fehler

Zitat:

Die Punkte liegen übrigens im ganz regulären Sichtbereich

Ich denke du vergisst hierbei das die Projektionen zwischen Near und Farplane liegen sollten. Wenn du zu nah an die eigentliche Augenposition herankommst (also dich vor die Nearplane begibst) wird der projektive Divisor am Ende der Rechnung zu 0 und das geht dann nicht.

Zitat:

sondern auch bei Abweichungen im Bereich 10^-38

In diesen Bereichen solltest du nicht mehr auf single vertrauen, da ist die Genauigkeit einfach nicht mehr gegeben und könnte auch einfach auf 0 gerundet werden. Allgemein ist die Gleitkommagenauigkeit von single immer ein Punkt den man beachten sollte, sobald man versucht sehr genau zu rechnen. (da ist schon bei 0,0000001 oder so Ende mit schönen glatten Zahlen)


Wenn dir das unverständlich vorkommt könntest du die Projektion auch einmal von Hand ausführen. Also deinen Vektor (x,y,z,1) nacheinander durch die World-, View-, Projectionmatrix schicken und am Ende durch die w-Komponente teilen. Da wirst du dann sehen, wo es klemmt smile


Es gibt 10 Gruppen von Menschen - die die das Binärsystem verstehen und die anderen.  :-)
Vegetarier essen meinem Essen das Essen weg ;)
-------------------------------------------------------------------------------------------------------------------
Der Community-Hub für Videospiele: gameloop.io

Offline

 

#5 05.12.2011 18:26:22

Gewuerzgurke
Member
Registriert: 15.09.2008
Beiträge: 47
Web-Seite

Re: D3DXVec3Project erzeugt Fehler

Also für Single-Werte gillt: Es gibt 6-7 signifikante Stellen, aber diese können auch erst an der 10ten Nachkommastelle beginnen. Deswegen ist die kleinste darstellbare Zahl > 0 gleich 1,401298464*10^-45 (ich habe mal dieses Tool geschrieben, mit dem man sich die Funktionsweise von Single-Werten vor Augen führen kann: http://www.mitjastachowiak.de/?/Projects/HexEdit). Aber das tut nichts zur Sache - bei Addition und Subtraktion geht es nur um die signifikanten Stellen...

Ich hab' jetzt mal versucht, die Kameraposition auf (0|0|-1000) zu setzen: kein Erfolg. Das sieht für mich nach einem Bug in der Funktion aus... Aber komisch, dass niemand sonst das Problem zu haben scheint. Vielleicht versuche ich mal einen anderen Header...

Offline

 

#6 05.12.2011 18:40:41

Gewuerzgurke
Member
Registriert: 15.09.2008
Beiträge: 47
Web-Seite

Re: D3DXVec3Project erzeugt Fehler

Hey, stimmt, vielleicht programmiere ich die Funktion wirklich nach. Also ich sage:
Pos2D = Pos3D;
Pos2D = Pos2D * matWorld;
Pos2D = Pos2D * matView;
Pos2D = Pos2D * matProject;
- ist das so richtig? -

Aber was muss ich mit dem ViewPort machen?

Und wie wird in DirectX ein Vektor mit einer Matrix multipliziert? Der Vektor hat ja nur 3 Dimensionen, die Matrix ist 4x4 - muss ich den Verktor mir 0 oder mit 1 ergänzen? Und gibt es vielleicht einfach schon eine Funktion, die das macht?

Diese Fragen Stellen sich mir noch, bevor ich anfangen kann... Kann mir ja jemand weiterhelfen?

Beitrag geändert von Gewuerzgurke (05.12.2011 18:41:17)

Offline

 

#7 05.12.2011 19:20:04

Gnietschow
ProMember
Ort: Berlin
Registriert: 20.06.2007
Beiträge: 237

Re: D3DXVec3Project erzeugt Fehler

Zitat:

Aber das tut nichts zur Sache - bei Addition und Subtraktion geht es nur um die signifikanten Stellen...

Du hast aber viele Multiplikationen und auch eine Division wink


Zu deinem letzten Post:

Der Viewport müsste mit in die Projectionmatrix eingehen, wodurch du ihn dann nicht mehr direkt brauchst.

Schau dir mal in der Doku D3DXVec4Transform an. Damit multiplizierst du einen 4D-Vektor mit einer Matrix. Dein initialer Vektor mit dem du durch die Matrizen gehst muss mit einer 1 erweitert sein, also Pos3D = (x,y,z,1).

Beitrag geändert von Gnietschow (05.12.2011 19:21:35)


Es gibt 10 Gruppen von Menschen - die die das Binärsystem verstehen und die anderen.  :-)
Vegetarier essen meinem Essen das Essen weg ;)
-------------------------------------------------------------------------------------------------------------------
Der Community-Hub für Videospiele: gameloop.io

Offline

 

#8 06.12.2011 11:09:25

Gewuerzgurke
Member
Registriert: 15.09.2008
Beiträge: 47
Web-Seite

Re: D3DXVec3Project erzeugt Fehler

So, diese Funktion geht:

Code: delphi

procedure D3DXVec3Project(var Pos2D : TD3DXVector3; Pos3D : TD3DXVector3; ViewPort : PD3DViewPort9; matProj,matView,matWorld : TD3DXMatrix);
var pos4d : td3dxvector4;
begin
 pos4d := d3dxvector4(pos3d.x,pos3d.y,pos3d.z,1);
 d3dxvec4transform(pos4d,pos4d,matworld);
 d3dxvec4transform(pos4d,pos4d,matview);
 d3dxvec4transform(pos4d,pos4d,matproj);
 pos2d.x := viewport^.width * (pos4d.x + 1) / 2;
 pos2d.y := viewport^.height * (1 - pos4d.y) / 2;
 pos2d.z := 1;
end; 

Man muss jetzt den Viewport als Pointer (Wobei das glaub' ich überflüssig ist) übergeben, aber das ist ja kein Problem.

Vielen Dang für Deine Hilfe smile

Beitrag geändert von Gewuerzgurke (08.12.2011 16:52:30)

Offline

 

Brett Fußzeile

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson