Author Topic: Euler rotation => Quaternion rotation [BB2D]  (Read 12022 times)

0 Members and 1 Guest are viewing this topic.

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
hi!

it is my software render lib again. i have problems when i try to implement a freelook code.
i had these problems in all of my previous software renderer attempts and in my openGL engine i made some months ago.

http://www.dc.freecoder-portal.de/upload/files/Devils%20Child/VirtualGL.zip (479.56 KB)

i know i'm asking for a lot of help, but please help me :)
thanks a lot for a reply!
« Last Edit: July 21, 2007 by Shockwave »

Offline Shockwave

  • good/evil
  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 17414
  • Karma: 498
  • evil/good
    • View Profile
    • My Homepage
Re: Software Renderer (Problem when trying FreeLook)
« Reply #1 on: June 30, 2007 »
It's not working the way that you want yet because of the camera.
Jim put a lot of stuff together about this, you need to build matrices for the camera and objects and then multiply them together.

There are at least three other people here too that have done this so you'll get your answer soon I think.

Your car looks great by the way!

Shockwave ^ Codigos
Challenge Trophies Won:

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Software Renderer (Problem when trying FreeLook)
« Reply #2 on: June 30, 2007 »
hmm i have the same functions as in the real openGL lib:
- vglMatrixIdentity()
- vglMatrixScale(x#, y#, z#)
- vglMatrixRotate(x#, y#, z#)
- vglMatrixTranslate(x#, y#, z#)
you can use these functions just like in openGL. if you put rotation behind scale, the matrices will be multiplicated and optimized internally

i have seen jims source code, of course!
but still, i dont see any differences talking about matrices. except that my matrix system is optimized...

btw: i didnt make the car. i found it on the web

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Software Renderer (Problem when trying FreeLook)
« Reply #3 on: July 01, 2007 »
In your FreeLook sample, you've got Rotate after Translate - surely that will cause it to rotate round the wrong place?

Jim
Challenge Trophies Won:

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Software Renderer (Problem when trying FreeLook)
« Reply #4 on: July 01, 2007 »
rotating after translating makes it look like the non-freelook sample...
also i posted that on my last software-rendering attempt here:
http://www.blitzbasic.com/Community/posts.php?topic=61719
Quote
I see what you mean, it is because the three angles affect each other. When Roll=180, the Yaw works upside down. As long as the three angles are not handled correctly, the function will give strange results.
« Last Edit: July 01, 2007 by Devils Child »

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Software Renderer (Problem when trying FreeLook)
« Reply #5 on: July 02, 2007 »
OK.  The problem is called gimbal lock.  Once you've rotated by two axes it's possible to lose the 3rd axis of orientation altogether.  This is insoluble using Euler rotation angles.  Can you explain what FreeLook is meant to do - what you expect to see when you use it?

Cheers

Jim
Challenge Trophies Won:

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Software Renderer (Problem when trying FreeLook)
« Reply #6 on: July 02, 2007 »
well, actually, i mean this:
Quote
Graphics3D 800, 600, 32, 2
SetBuffer BackBuffer()

;Camera
Cam = CreateCamera()
RotateEntity CreateLight(), 70, 20, 0

;Cubes
Cube1 = CreateCube()
PositionEntity Cube1, -2, 0, 5
Cube2 = CreateCube()
PositionEntity Cube2, 2, 0, 5

SetFont LoadFont("Arial", 30, True)
While Not KeyHit(1)
   ;Cube 1 rotation (WRONG!)
   rot = rot + 2
   RotateEntity Cube1, rot, rot, rot
   ;Cube 2 rotation (RIGHT!)
   TurnEntity Cube2, 2, 2, 2
   RenderWorld
   Text 40, 100, "Wrong:"
   Text 40, 140, "(Like in my software renderer)"
   Text 500, 100, "Right:"
   Rect 400, 0, 1, 600
   Flip
Wend
End

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #7 on: July 15, 2007 »
hm. i waited if someone makes a reply.. anyway: jim, i checked out your software renderer ant noticed that your rotation doesnt look like quaternion either. it looks more like euler.

also i have no idea what the "W" parameter does in a vector assignment..

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #8 on: July 15, 2007 »
The way I deal with this is to store the 3*3 matrix with the object, the 3*3 matrix is 3 vectors that initially point along each axis:

(x0,y0,z0)=(1,0,0)
(x1,y1,z1)=(0,1,0)
(x2,y2,z2)=(0,0,1)

to rotate the object you rotate the vectors around each axis but something I found that surprised me was that if you rotate your vectors as x0,y0,z0    x1,y1,z1    x2,y2,z2    then the object rotates around it's own axis BUT if you rotate your vectors as x0,x1,x2    y0,y1,y2     z0,z1,z2    then the object rotates around the world axis (or is it the other way round).

And by multiplying the object matrix by the camera matrix you can transform from object->world->camera space in one step (you need to calculate the objects origin in camera space too though).

I've never really seen anyone else doing it this way so I don't know if it's unpopular for any reason or not but I like it and it can be made to fit in with quaternions and loaded into opengl matrices with a little bit of messing around.
« Last Edit: July 15, 2007 by Stonemonkey »

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #9 on: July 15, 2007 »
actually, i'm using 4x4 matrices (since the last column of the matrix is not necessairy i use 3x4 matrices)
hmh, blitz3d's rotation looks way better than my rotation

i still cant understand what a 4-float vector is...
my vectors are (x,y,z) ; but some vectors are (x,y,z,w)
the w must be some stuff arround quaternions, so i need to calculate the 'w' value somehow to get quaternions, right?

Offline Tetra

  • DBF Aficionado
  • ******
  • Posts: 2532
  • Karma: 83
  • Pirate Monkey!
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #10 on: July 15, 2007 »
i never got as far as implementing it but here are some linke I found on it that mite be of use

http://dbfinteractive.com/index.php?topic=1843.msg27625#msg27625
Challenge Trophies Won:

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #11 on: July 16, 2007 »
The w in my engine is just 1/z.  It has nothing to do with rotations.  1/z is a very useful thing to have around for wbuffering and perspective correct texturing.  Quaternion rotations might solve your problem, but it's kind of using a sledgehammer to crack a walnut.

Your example code is just showing that
(pitch1,yaw1,roll1)+(pitch2,yaw2,roll2) is not the same as (pitch1+pitch2,yaw1+yaw2,roll1+roll2) which is what you would expect.  To easily do those sums you either need to be working with matrices, axis angles, or quaternions.

Jim
Challenge Trophies Won:

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #12 on: July 16, 2007 »
seems like that if i take the vertex vector like w=1.0/z the whole thing starts to wobble even more.

quaternion rotation should be looking like this:, right?
Code: [Select]
Graphics3D 800, 600, 32, 2
SetBuffer BackBuffer()

;Camera
Cam = CreateCamera()
RotateEntity CreateLight(), 70, 20, 0

;Cubes
Cube = CreateCube()
PositionEntity Cube, 0, 0, 3

SetFont LoadFont("Arial", 30, True)
While Not KeyHit(1)
   TurnEntity Cube, 2, 2, 2
   RenderWorld
   Flip
Wend
End

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #13 on: July 17, 2007 »
Quote
seems like that if i take the vertex vector like w=1.0/z the whole thing starts to wobble even more.[/quute]
I don't understand this.

Quote
quaternion rotation should be looking like this:, right?
Theoretically, yes.  They're tough to implement though.  I should be able to help you out if you want.

I'm still not absolutely sure what problem you are trying to solve.  I can see the obvious differences/problems in your sample code.  Are you trying to use several 3-angle rotations in a row to orient something, and that's what's wrong?  If so, why are you trying to do that?  If you're just trying to point the camera at an object (which is what I understand by 'freelook') then it's simpler than you're making it.

Jim
Challenge Trophies Won:

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #14 on: July 17, 2007 »
actually, i'm not trying to imitate a PointEntity. also i know how that works. i'm rather trying to make my rotation look like in the b3d sample i posted above. this would solve several other problems i'm facing.
i would really appreciate your help, tho :)
btw: my matrix system looks weird, but these over complicated maths there are just matrix rotation/pos/scale and multiplication in one step...

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #15 on: July 17, 2007 »
This is a simplified version of what I use, I came up with it while trying to emulate what B3D does. The directions of rotations are probably different and one of the rotation functions in B3D resets the rotation first which mine doesn't (I find it more useful that way).

Code: [Select]
Type vertex
Field x#,y#,z#
Field rx#,ry#,rz#
Field sx,sy
End Type

Type triangle
Field vertex.vertex[3]
End Type

Type entity
Field x#,y#,z#
Field ux0#,uy0#,uz0#
Field ux1#,uy1#,uz1#
Field ux2#,uy2#,uz2#
Field vertex.vertex[8]
Field vertex_count
Field triangle.triangle[12]
Field triangle_count
End Type


;*******************************************************************************************************************************
;entity creation functions

Function add_vertex(entity_h,x#,y#,z#)
entity.entity=Object.entity(entity_h)
entity\vertex[entity\vertex_count]=New vertex
entity\vertex[entity\vertex_count]\x=x
entity\vertex[entity\vertex_count]\y=y
entity\vertex[entity\vertex_count]\z=z
entity\vertex_count=entity\vertex_count+1
Return Handle(entity\vertex[entity\vertex_count-1])
End Function

Function add_triangle(entity_h,v0_h,v1_h,v2_h)
entity.entity=Object.entity(entity_h)
entity\triangle[entity\triangle_count]=New triangle
entity\triangle[entity\triangle_count]\vertex[0]=Object.vertex(v0_h)
entity\triangle[entity\triangle_count]\vertex[1]=Object.vertex(v1_h)
entity\triangle[entity\triangle_count]\vertex[2]=Object.vertex(v2_h)
entity\triangle_count=entity\triangle_count+1
End Function

Function create_entity()
new_entity.entity=New entity

;set up the initial matrix   (1,0,0),(0,1,0),(0,0,1)
new_entity\ux0=1.0
new_entity\uy1=1.0
new_entity\uz2=1.0
Return Handle(new_entity)
End Function


;*******************************************************************************************************************************
;entity control functions

;rotate the entity relative to it's own axis
Function rotate_entity(entity_h,a#,b#,c#)
entity.entity=Object.entity(entity_h)
    csa#=Cos(-a)
    sna#=Sin(-a)
    csb#=Cos(-b)
    snb#=Sin(-b)
    csc#=Cos(c)
    snc#=Sin(c)
    x#=entity\ux0*csb+entity\ux2*snb
    z#=entity\ux2*csb-entity\ux0*snb
    entity\ux2=z*csa+entity\ux1*sna
    y#=entity\ux1*csa-z*sna
    entity\ux0=x*csc+y*snc
    entity\ux1=y*csc-x*snc
    x=entity\uy0*csb+entity\uy2*snb
    z=entity\uy2*csb-entity\uy0*snb
    entity\uy2=z*csa+entity\uy1*sna
    y=entity\uy1*csa-z*sna
    entity\uy0=x*csc+y*snc
    entity\uy1=y*csc-x*snc
    x=entity\uz0*csb+entity\uz2*snb
    z=entity\uz2*csb-entity\uz0*snb
    entity\uz2=z*csa+entity\uz1*sna
    y=entity\uz1*csa-z*sna
    entity\uz0=x*csc+y*snc
    entity\uz1=y*csc-x*snc
End Function

;rotate the entity relative to the world axis
Function turn_entity(entity_h,a#,b#,c#)
entity.entity=Object.entity(entity_h)
    csa#=Cos(a)
    sna#=Sin(a)
    csb#=Cos(b)
    snb#=Sin(b)
    csc#=Cos(-c)
    snc#=Sin(-c)
    x#=entity\ux0*csb+entity\uz0*snb
    z#=entity\uz0*csb-entity\ux0*snb
    entity\uz0=z*csa+entity\uy0*sna
    y#=entity\uy0*csa-z*sna
    entity\ux0=x*csc+y*snc
    entity\uy0=y*csc-x*snc
    x=entity\ux1*csb+entity\uz1*snb
    z=entity\uz1*csb-entity\ux1*snb
    entity\uz1=z*csa+entity\uy1*sna
    y=entity\uy1*csa-z*sna
    entity\ux1=x*csc+y*snc
    entity\uy1=y*csc-x*snc
    x=entity\ux2*csb+entity\uz2*snb
    z=entity\uz2*csb-entity\ux2*snb
    entity\uz2=z*csa+entity\uy2*sna
    y=entity\uy2*csa-z*sna
    entity\ux2=x*csc+y*snc
    entity\uy2=y*csc-x*snc
End Function

;move the entity to world coordinates
Function position_entity(entity_h,x#,y#,z#)
entity.entity=Object.entity(entity_h)
entity\x=x
entity\y=y
entity\z=z
End Function

;move the entity relative to the world axis
Function translate_entity(entity_h,x#,y#,z#)
entity.entity=Object.entity(entity_h)
entity\x=entity\x+x
entity\y=entity\y+y
entity\z=entity\z+z
End Function

;move the entity relative to it's own axis
Function move_entity(entity_h,x#,y#,z#)
entity.entity=Object.entity(entity_h)
entity\x=entity\x+x*entity\ux0+y*entity\ux1+z*entity\ux2
    entity\y=entity\y+x*entity\uy0+y*entity\uy1+z*entity\uy2
    entity\z=entity\z+x*entity\uz0+y*entity\uz1+z*entity\uz2
End Function

;********************************************************************************************************************************
;entity rendering functions

Function rotate_vertices(entity.entity)
i=0
While i<entity\vertex_count
vertex.vertex=entity\vertex[i]
vertex\rx= vertex\x*entity\ux0 + vertex\y*entity\ux1 + vertex\z*entity\ux2 + entity\x
vertex\ry= vertex\x*entity\uy0 + vertex\y*entity\uy1 + vertex\z*entity\uy2 + entity\y
vertex\rz= vertex\x*entity\uz0 + vertex\y*entity\uz1 + vertex\z*entity\uz2 + entity\z
zr#=640.0/vertex\rz
vertex\sx=320.0+vertex\rx*zr
vertex\sy=240.0-vertex\ry*zr
i=i+1
Wend
End Function

Function draw_triangles(entity.entity)
i=0
While i<entity\triangle_count
triangle.triangle=entity\triangle[i]
v0.vertex=triangle\vertex[0]
v1.vertex=triangle\vertex[1]
v2.vertex=triangle\vertex[2]
If ((v1\sx-v0\sx)*(v2\sy-v0\sy))-((v2\sx-v0\sx)*(v1\sy-v0\sy))>0.0 Then
Line v0\sx,v0\sy,v1\sx,v1\sy
Line v1\sx,v1\sy,v2\sx,v2\sy
Line v2\sx,v2\sy,v0\sx,v0\sy
End If
i=i+1
Wend
End Function

Function draw_entity(entity_h)
entity.entity=Object.entity(entity_h)
rotate_vertices(entity)
draw_triangles(entity)
End Function


;*****************************************************************************************************************************
;main code

Function create_cube(size#)
cube=create_entity()
v0=add_vertex(cube,-size,-size,-size)
v1=add_vertex(cube,-size,-size, size)
v2=add_vertex(cube, size,-size, size)
v3=add_vertex(cube, size,-size,-size)
v4=add_vertex(cube,-size, size,-size)
v5=add_vertex(cube,-size, size, size)
v6=add_vertex(cube, size, size, size)
v7=add_vertex(cube, size, size,-size)
add_triangle cube,v0,v1,v5
add_triangle cube,v5,v4,v0
add_triangle cube,v1,v2,v6
add_triangle cube,v6,v5,v1
add_triangle cube,v2,v3,v7
add_triangle cube,v7,v6,v2
add_triangle cube,v3,v0,v4
add_triangle cube,v4,v7,v3
add_triangle cube,v0,v3,v2
add_triangle cube,v2,v1,v0
add_triangle cube,v4,v5,v6
add_triangle cube,v6,v7,v4
Return cube
End Function


Function main()
Graphics 640,480,32,2
cube=create_cube(100.0)
position_entity cube,0,0,1000
SetBuffer BackBuffer()
Color 255,255,255
While Not(KeyHit(1))
rotate_entity cube,2,2,2
;turn_entity cube,0.1,0,0
;move_entity cube,0,0,10
draw_entity cube
Flip
Cls
Wend
End Function

main()
end

« Last Edit: July 17, 2007 by Stonemonkey »

Offline Devils Child

  • C= 64
  • **
  • Posts: 66
  • Karma: 2
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #16 on: July 17, 2007 »
whats that?

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #17 on: July 17, 2007 »
A wireframe cube.

Offline Jim

  • Founder Member
  • DBF Aficionado
  • ********
  • Posts: 5301
  • Karma: 402
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #18 on: July 17, 2007 »
->Devils Child

Here's a possible fix for you.  Instead of rotating by angles again and again which is causing the problem, create a matrix of the rotation you want, and then apply the matrix to the object's matrix each frame.

Jim
Challenge Trophies Won:

Offline Stonemonkey

  • Pentium
  • *****
  • Posts: 1315
  • Karma: 96
    • View Profile
Re: Euler rotation => Quaternion rotation
« Reply #19 on: July 17, 2007 »
Am I barking up the totally wrong tree here? As I think that's almost what my code does.
« Last Edit: July 17, 2007 by Stonemonkey »