I've recently written two quite different implementations of firstperson camera that use Quaternions to perform rotations.

Neither worked, they appeared to suffer a common bug (the results onscreen were identical). The only thing they had in common was a code module providing quaternion math functions that I'd written earlier.

For starters, here is the formula for QuatMultiply (gleaned from the net) apon which I based my code - is it correct?

Now, here is my implementation of the above formula. Is it correct?

Does everything here look right?

TIA, Homer.

Neither worked, they appeared to suffer a common bug (the results onscreen were identical). The only thing they had in common was a code module providing quaternion math functions that I'd written earlier.

For starters, here is the formula for QuatMultiply (gleaned from the net) apon which I based my code - is it correct?

```
```

Assuming two input quaternions (A and B), find C = A . B

C.x = | A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y |

C.y = | A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x |

C.z = | A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w |

C.w = | A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z |

Now, here is my implementation of the above formula. Is it correct?

```
```

QuaternionMultiply proc uses esi edi ecx pA, pB, pC

mov esi,pA

mov edi,pB

mov ecx,pC

assume esi:ptr CQuaternion

assume edi:ptr CQuaternion

assume ecx:ptr CQuaternion

;C.x = | A.w*B.x + A.x*B.w + A.y*B.z - A.z*B.y |

fld [esi].fW

fmul [edi].fX

fld [esi].fX

fmul [edi].fW

fadd

fld [esi].fY

fmul [edi].fZ

fadd

fld [esi].fZ

fmul [edi].fY

fsub

fstp [ecx].fX

;C.y = | A.w*B.y - A.x*B.z + A.y*B.w + A.z*B.x |

fld [esi].fW

fmul [edi].fY

fld [esi].fX

fmul [edi].fZ

fsub

fld [esi].fY

fmul [edi].fW

fadd

fld [esi].fZ

fmul [edi].fX

fadd

fstp [ecx].fY

;C.z = | A.w*B.z + A.x*B.y - A.y*B.x + A.z*B.w |

fld [esi].fW

fmul [edi].fZ

fld [esi].fX

fmul [edi].fY

fadd

fld [esi].fY

fmul [edi].fX

fsub

fld [esi].fZ

fmul [edi].fW

fadd

fstp [ecx].fZ

;C.w = | A.w*B.w - A.x*B.x - A.y*B.y - A.z*B.z |

fld [esi].fW

fmul [edi].fW

fld [esi].fX

fmul [edi].fX

fsub

fld [esi].fY

fmul [edi].fY

fsub

fld [esi].fZ

fmul [edi].fZ

fsub

fstp [ecx].fW

assume esi:nothing

assume edi:nothing

assume ecx:nothing

ret

QuaternionMultiply endp

Does everything here look right?

TIA, Homer.

Two other formulas for QuaternionMultiply:

;this one is correct

;this one must work also, not tested though...

;this one is correct

```
```

Cx = Ax*Bw + Ay*Bz - Az*By + Aw*Bx

Cy = - Ax*Bz + Ay*Bw + Az*Bx + Aw*By

Cz = Ax*By - Ay*Bx + Az*Bw + Aw*Bz

Cw = - Ax*Bx - Ay*By - Az*Bz + Aw*Bw

;this one must work also, not tested though...

```
```

Cx = Ax*Bw + Aw*Bx + Az*By + Ay*Bz

Cy = Ay*Bw + Aw*By + Ax*Bz + Az*Bx

Cz = Az*Bw + Aw*Bz + Ay*Bx + Ax*By

Cw = Aw*Bw + Ax*Bx + Ay*By + Az*Bz

Afternoon, EvilHomer2k.

Code seems fine.

Are you sure the sourcecode example you found on Gamedev.net actually works as intended? Reading through the comments on the article shows at least one person had to "fix" the code to make it work correctly.

I've seen Quaternion code for rotating cameras which

Are you still keen on using a Quaternion method, or would this one be easier?

http://www.asmcommunity.net/board/viewtopic.php?t=16454

Cheers,

Scronty

Code seems fine.

Are you sure the sourcecode example you found on Gamedev.net actually works as intended? Reading through the comments on the article shows at least one person had to "fix" the code to make it work correctly.

I've seen Quaternion code for rotating cameras which

*don't*supply GimbalLock, even though Quaternions are supposed to do that easily.Are you still keen on using a Quaternion method, or would this one be easier?

http://www.asmcommunity.net/board/viewtopic.php?t=16454

Cheers,

Scronty

Thanks for the replies.

The first source I tried was the GameDev one, which uses glLookAt to apply the camera perspective. It's a bit long-winded imho.

The second one I tried was from NeHe and applies perspective by concatenating the combined rotation matrix (from Quat) to the model matrix using glMatrixMultf. The code is much shorter, and the camera requires less data, ie we don't need stuff like "vStrafe" anymore.

I too had to "fix" the code to make it work.

Most of the errors were obvious, some were less so.

I made some small optimizations to the procs (when I translate C/C++ to asm literally, some optimizations are glaringly obvious, and I can't stand redundancy in clearcode blocks).

The main errors which were wigging me were both in the Quaternion math as I suspected. The functions to convert quat-->matrix and to multiply quats were both in error - the formulae were bad. Damn the disinformation out there, my code was fine :roll:

I found yet another alternative formula for the Multiply:

NeHe (WORKS)

Cx = Aw*Bx + Ax*Bw + Ay*Bz - Az*By;

Cy = Aw*By + Ay*Bw + Az*Bx - Ax*Bz;

Cz = Aw*Bz + Az*Bw + Ax*By - Ay*Bx;

Cw = Aw*Bw - Ax*Bx - Ay*By - Az*Bz;

Compared to these:

Siekmanski #1 (WORKS)

Cx = Ax*Bw + Ay*Bz - Az*By + Aw*Bx

Cy = - Ax*Bz + Ay*Bw + Az*Bx + Aw*By

Cz = Ax*By - Ay*Bx + Az*Bw + Aw*Bz

Cw = - Ax*Bx - Ay*By - Az*Bz + Aw*Bw

Siekmanski#2 (UNTESTED)

Cx = Ax*Bw + Aw*Bx + Az*By + Ay*Bz

Cy = Ay*Bw + Aw*By + Ax*Bz + Az*Bx

Cz = Az*Bw + Aw*Bz + Ay*Bx + Ax*By

Cw = Aw*Bw + Ax*Bx + Ay*By + Az*Bz

I also found an error in the formula for "CreateMatrix" (convert quat to matrix) , the alternative formula for this (NeHe) works.

My quat camera is working, I'll post the source in the gamecoding forum for suggestions to improve it. At the moment, time has no bearing on camera movement, which needs to be remedied (camera physics 101)

Scronty - I've discovered that quaternions, like matrices, are a tool.

Like matrices, are non commutative.

Like matrices, can perform various transformations.

Like matrices, offer shortcuts to those familiar with the structure.

Like matrices, can cause loads of headaches when applied incorrectly.

I can see how you could gimbal lock with quatrot.

You would however be applying quatrot incorrectly to achieve this.

Nonetheless, it took me three tries to get it right, even with source (in C) on offer.

Third time is a charm :)

Yes Scronty, there's a REALLY good reason why I wanted to get quatrot working, and it's only partly to do with camera.

In a nutshell, I want to implement QuatSlerp, and I intend to test my slerp code by slerping the camera between first and thirdperson views over a second or two of time.

It's possible to slerp between any two complex matrices if you convert them to quats, and the possibilities are interesting to say the least.

The first source I tried was the GameDev one, which uses glLookAt to apply the camera perspective. It's a bit long-winded imho.

The second one I tried was from NeHe and applies perspective by concatenating the combined rotation matrix (from Quat) to the model matrix using glMatrixMultf. The code is much shorter, and the camera requires less data, ie we don't need stuff like "vStrafe" anymore.

I too had to "fix" the code to make it work.

Most of the errors were obvious, some were less so.

I made some small optimizations to the procs (when I translate C/C++ to asm literally, some optimizations are glaringly obvious, and I can't stand redundancy in clearcode blocks).

The main errors which were wigging me were both in the Quaternion math as I suspected. The functions to convert quat-->matrix and to multiply quats were both in error - the formulae were bad. Damn the disinformation out there, my code was fine :roll:

I found yet another alternative formula for the Multiply:

NeHe (WORKS)

Cx = Aw*Bx + Ax*Bw + Ay*Bz - Az*By;

Cy = Aw*By + Ay*Bw + Az*Bx - Ax*Bz;

Cz = Aw*Bz + Az*Bw + Ax*By - Ay*Bx;

Cw = Aw*Bw - Ax*Bx - Ay*By - Az*Bz;

Compared to these:

Siekmanski #1 (WORKS)

Cx = Ax*Bw + Ay*Bz - Az*By + Aw*Bx

Cy = - Ax*Bz + Ay*Bw + Az*Bx + Aw*By

Cz = Ax*By - Ay*Bx + Az*Bw + Aw*Bz

Cw = - Ax*Bx - Ay*By - Az*Bz + Aw*Bw

Siekmanski#2 (UNTESTED)

Cx = Ax*Bw + Aw*Bx + Az*By + Ay*Bz

Cy = Ay*Bw + Aw*By + Ax*Bz + Az*Bx

Cz = Az*Bw + Aw*Bz + Ay*Bx + Ax*By

Cw = Aw*Bw + Ax*Bx + Ay*By + Az*Bz

I also found an error in the formula for "CreateMatrix" (convert quat to matrix) , the alternative formula for this (NeHe) works.

My quat camera is working, I'll post the source in the gamecoding forum for suggestions to improve it. At the moment, time has no bearing on camera movement, which needs to be remedied (camera physics 101)

Scronty - I've discovered that quaternions, like matrices, are a tool.

Like matrices, are non commutative.

Like matrices, can perform various transformations.

Like matrices, offer shortcuts to those familiar with the structure.

Like matrices, can cause loads of headaches when applied incorrectly.

I can see how you could gimbal lock with quatrot.

You would however be applying quatrot incorrectly to achieve this.

Nonetheless, it took me three tries to get it right, even with source (in C) on offer.

Third time is a charm :)

Yes Scronty, there's a REALLY good reason why I wanted to get quatrot working, and it's only partly to do with camera.

In a nutshell, I want to implement QuatSlerp, and I intend to test my slerp code by slerping the camera between first and thirdperson views over a second or two of time.

It's possible to slerp between any two complex matrices if you convert them to quats, and the possibilities are interesting to say the least.