hello everyone,

I was wondering if there was any D3DX function similar to D3DXMatrixLookAtLH, I mean, that you send a vector pointing somewhere in the scenery and a vector setting from where you're looking at, and the function returns you a matrix or a quaternion with the rotations needed to "look" at the point, from where the eye is, no matter how far the point is located.

The thing is, I have a point in the scenery, and I can get the rotation in X, Y and Z with trigonometric functions and with its position, but it'd be easier to have a function that does that for me, like LookAtLH, the problem with that function is that when the point is above or below the eye, taking into account the Up vector, the result matrix isn't valid, and I can't change the Up vector, as you do when rotating the camera for example, because the viewer should be static.

thanks in advanced for your help,

gallo

I was wondering if there was any D3DX function similar to D3DXMatrixLookAtLH, I mean, that you send a vector pointing somewhere in the scenery and a vector setting from where you're looking at, and the function returns you a matrix or a quaternion with the rotations needed to "look" at the point, from where the eye is, no matter how far the point is located.

The thing is, I have a point in the scenery, and I can get the rotation in X, Y and Z with trigonometric functions and with its position, but it'd be easier to have a function that does that for me, like LookAtLH, the problem with that function is that when the point is above or below the eye, taking into account the Up vector, the result matrix isn't valid, and I can't change the Up vector, as you do when rotating the camera for example, because the viewer should be static.

thanks in advanced for your help,

gallo

There's several solutions that spring to mind.

One is to build your own View matrix, rather than using D3DXMatrixLookAtLH.

Another is to call that function once to build a view matrix for a fixed view, say "straight ahead", and then to concatenate it with a rotation matrix that represents the 3D orientation, and then apply the resulting matrix as your view matrix.

I have written 6DOF camera code in the past, I had no problems using both these solutions.

Yes, the D3DXMatrixLookat function has a couple of mathematical anomolies.

They occur at 90 degrees vertical inclination and declination.

Please search for information on 'avoiding gimbal lock' if you want to find alternatives.

One is to build your own View matrix, rather than using D3DXMatrixLookAtLH.

Another is to call that function once to build a view matrix for a fixed view, say "straight ahead", and then to concatenate it with a rotation matrix that represents the 3D orientation, and then apply the resulting matrix as your view matrix.

I have written 6DOF camera code in the past, I had no problems using both these solutions.

Yes, the D3DXMatrixLookat function has a couple of mathematical anomolies.

They occur at 90 degrees vertical inclination and declination.

Please search for information on 'avoiding gimbal lock' if you want to find alternatives.

hello, well I didn't find any thing very near to what I was looking for, so I wrote the proc by my self, but now I have a little problem, here is the code:

now, an example of the problem is that when I send as second parameter a vector which points back, the resulting quaternion is:

as you see, the w part is near zero, but it isn't and it should be zero, so, when I use this on a project, frame after frame it will affect the position of something that's being rotated by the resulting quaternion. I don't know if there's some way to correct this, because is not only for the case when the position vector is pointing back but everywhere. I tried to trace the error and it's on a

I hope there's some way to overcome this problem, please help me,

thanks in advanced,

gallo.

.data

float_1 REAL4 1.0

.code

QuaternionLookAt proc pQuaternion:LPVOID,pPos:LPVOID

local front:D3DXVECTOR3

local pos:D3DXVECTOR3

local axis:D3DXVECTOR3

local angle:FLOAT

mov front.x,0

mov front.y,0

m2m front.z,float_1

invoke D3DXVec3Normalize,addr pos,pPos

invoke D3DXVec3Cross,addr axis,addr front,addr pos

invoke D3DXVec3Normalize,addr axis,addr axis

invoke D3DXVec3Length,addr axis

fldz

fcompp

fstsw ax

test ah,01000000b ;==

jz @F

m2m axis.x,float_1

mov axis.y,0

mov axis.z,0

@@:

invoke D3DXVec3Dot,addr front,addr pos

;arccos

fld st(0)

fmul st(0),st(0)

fld1

fsubr

fsqrt

fxch st(1)

fpatan

fstp angle

invoke D3DXQuaternionRotationAxis,pQuaternion,addr axis,angle

ret

QuaternionLookAt endp

now, an example of the problem is that when I send as second parameter a vector which points back, the resulting quaternion is:

(LPD3DXQUATERNION) pQuaternion

x 1.00000

y 0.000000

z 0.000000

w -4.37114e-008

as you see, the w part is near zero, but it isn't and it should be zero, so, when I use this on a project, frame after frame it will affect the position of something that's being rotated by the resulting quaternion. I don't know if there's some way to correct this, because is not only for the case when the position vector is pointing back but everywhere. I tried to trace the error and it's on a

*fsincos*made on the procedure D3DXQuaternionRotationAxis, and it happens as well in the D3DXMatrixRotationAxis; and, even in the procedure D3DXQuaternionRotationYawPitchRoll, when you set rotation parameters to (0,pi,0), you'll get a not very precise result.I hope there's some way to overcome this problem, please help me,

thanks in advanced,

gallo.

There may be two options in my opinion to resolve this problem.

1- If you are currently setting the precision control of the FPU to 24 bits (REAL4), switching it to 53 bits (REAL8) could help as long as you don't store intermediate results as REAL4 too often during the computation.

2- If the above is not applicable or does not resolve the problem, the only option may be to check the final result for an excessively low value and change it to 0 when advisable. That could be performed either on the FPU, or on the ALU with "integer" instructions even though the result may be stored as a float.

The following is an example of how the latter could be done, assuming that "w" is a REAL4 in memory.

If you haven't done so already and you need a better understanding of floats, see Chapter 2 in the FPU tutorial at

http://www.ray.masmcode.com/tutorial/index.html

Raymond

1- If you are currently setting the precision control of the FPU to 24 bits (REAL4), switching it to 53 bits (REAL8) could help as long as you don't store intermediate results as REAL4 too often during the computation.

2- If the above is not applicable or does not resolve the problem, the only option may be to check the final result for an excessively low value and change it to 0 when advisable. That could be performed either on the FPU, or on the ALU with "integer" instructions even though the result may be stored as a float.

The following is an example of how the latter could be done, assuming that "w" is a REAL4 in memory.

`mov eax,w`

rol eax,9 ;transfer the biased exponent bits to AL

.if al < 6Ch ;compare to approx. 10^{-7}

;use 6Fh for approx. 10^{-6}

mov w,0

.endif

If you haven't done so already and you need a better understanding of floats, see Chapter 2 in the FPU tutorial at

http://www.ray.masmcode.com/tutorial/index.html

Raymond