Skip to main content
gamedev.net
🔒 Locked

vector math

Started by kill Nov 8, 2000 at 10:01 PM 1 replies 450+ views
Original Post
kill
kill
Hi. I have a number of questions that all follow from each other. 1. I have a unit vector that holds a direction of a mesh. I also have an angle around it. How do I get the up vector based on this angle and vector? 2. If I have two orthogonal unit vectors, how do I rotate one around the other by a certain number of degrees? Thanks.
Friday13
Friday13
1. To get the up-vector you can get the ''side-looking'' vector by taking the cross product of the original vector an its projection to, say, Y-axis (or, if they coincide, to Z-axis). Then, the cross product between the original vector and the ''side-looking'' vector will result in up-vector. The you rotate these two vectors around the original vector to get the final basis.

2. Turning an arbitrary vector around another arbitrary vector takes 5 (five steps): you must transition from the world basis to the ''fulcrum'' vector (takes two turns) so that the world''s Z-axis coincides with the ''fulcrum'', then you turn the ''lever'' vector by your specified angle around that new Z-axis, and then you must return to original basis (two turns back). Actually, it takes too long to explain in details, so here''s a small function that does exactly what you need:


;C-style calling conventions
;Case sensitive
;vector format:
;x dword
;y dword
;z dword
;m dword ;=vector''s absolute length=sqrt(x^2+y^2+z^2), needed to compensate minor precision losses over multiple transformations
;spoils esi, edi

rotate proc fulcrum:DWORD, lever:DWORD, angle:DWORD ;rotates arbitrary vector ''lever'' around arbitrary ''fulcrum by angle deg.
LOCAL r1:DWORD
LOCAL R1:DWORD
LOCAL xs1:DWORD
LOCAL ys1:DWORD
LOCAL xs2:DWORD
LOCAL zs2:DWORD
LOCAL xs3:DWORD
LOCAL ys3:DWORD
LOCAL xs4:DWORD


mov esi,dword ptr [fulcrum]
mov edi,dword ptr [lever]
;
mov eax,dword ptr [esi]
or eax,dword ptr [esi+4]
jz just_turn
fld dword ptr [esi]
fmul dword ptr [esi]
fld dword ptr [esi+4]
fmul dword ptr [esi+4]
faddp st(1),st
fld st
fsqrt
fstp dword ptr [r1]


fld dword ptr [esi+8]
fmul dword ptr [esi+8]
faddp st(1),st
fsqrt


fst dword ptr [R1]
fstp dword ptr [esi+12] ;fulcrum.Modul
;
fld dword ptr [esi+4] ;1 x1
fld dword ptr [edi+4] ;2 y2,x1
fld st ;3 y2,y2,x1
fmul st,st(2) ;3 y2x1,y2,x1
fld dword ptr [esi] ;4 y1,y2x1,y2,x1
fld dword ptr [edi] ;5 x2,y1,y2x1,y2,x1
fld st ;6 x2,x2,y1,y2x1,y2,x1
fmul st,st(2) ;6 x2y1,x2,y1,y2x1,y2,x1
fadd st,st(3) ;6 x2y1-y2x1,x2,y1,y2x1,y2,x1
fdiv dword ptr [r1]
fstp dword ptr [xs1] ;5 x2,y1,y2x1,y2,x1
fstp st(2) ;4 y1,x2,y2,x1
fmulp st(2),st ;3 x2,y2y1,x1
fmulp st(2),st ;2 y2y1,x1x2
fsubrp st(1),st ;(1),st ;1


fdiv dword ptr [r1]
fstp dword ptr [ys1] ;0
;;;;;;;
fld dword ptr [r1] ;1 r1
fld dword ptr [xs1] ;2 xs1,r1
fld st ;3 xs1,xs1,r1
fmul st,st(2) ;3 xs1r1,xs1,r1
fld dword ptr [esi+8] ;4 z1,xs1r1,xs1,r1
fld dword ptr [edi+8] ;5 z2,z1,xs1r1,xs1,r1
fld st ;6 z2,z2,z1,xs1r1,xs1,r1
fmul st,st(2) ;6 z2z1,z2,z1,xs1r1,xs1,r1
fadd st,st(3) ;6 z2z1-xs1r1,z2,z1,xs1r1,xs1,r1


fdiv dword ptr [R1]
fstp dword ptr [zs2] ;5 z2,z1,xs1r1,xs1,r1
fstp st(2) ;4 z1,z2,xs1,r1
fmulp st(2),st ;3 z2,xs1z1,r1
fmulp st(2),st ;2 xs1r1,z2r1
fsubrp st(1),st ;,st ;1
fdiv dword ptr [R1]
fstp dword ptr [xs2] ;0
;;;;;;;
fld dword ptr [angle] ;1
fmul dword ptr [pi_na_180] ;1
fld st ;2
fcos ;2
fxch st(1) ;2
fsin ;2 sin,cos
fld dword ptr [ys1] ;3 ys1,sin,cos
fld st ;4 ys1,ys1,sin,cos
fld dword ptr [xs2] ;5 xs2,ys1,ys1,sin,cos
fld st ;6 xs2,xs2,ys1,ys1,sin,cos
fmul st,st(5) ;6 xs2cos,xs2,ys1,ys1,sin,cos
fxch st(2) ;6 ys1,xs2,xs2cos,ys1,sin,cos
fmul st,st(4) ;6 ys1sin,xs2,xs2cos,ys1,sin,cos
fsubp st(2),st ;5 xs2,xs2cos+ys1sin,ys1,sin,cos
fmulp st(3),st ;4 xs2cos+ys1sin,ys1,xs2sin,cos
fstp dword ptr [xs3] ;3 ys1,xs2sin,cos
fmulp st(2),st ;2
faddp st(1),st ;1
fstp dword ptr [ys3] ;0
;;;;;;
fld dword ptr [r1] ;1 r1
fld dword ptr [xs3] ;2 xs3,r1
fld st ;3 xs3,xs3,r1
fmul st,st(2) ;3 xs3r1,xs3,r1
fld dword ptr [esi+8] ;4 z1,xs3r1,xs3,r1
fld dword ptr [zs2] ;5 zs2,z1,xs3r1,xs3,r1
fld st ;6 zs2,zs2,z1,xs3r1,xs3,r1
fmul st,st(2) ;6 zs2z1,zs2,z1,xs3r1,xs3,r1
fsub st,st(3) ;6 zs2z1+xs3r1,zs2,z1,xs3r1,xs3,r1
fdiv dword ptr [R1]
fstp dword ptr [edi+8] ;5 zs2,z1,xs3r1,xs3,r1
fstp st(2) ;4 z1,zs2,xs3,r1
fmulp st(2),st ;3 zs2,xs3z1,r1
fmulp st(2),st ;2 xs3z1,zs2r1
faddp st(1),st ;2
fdiv dword ptr [R1]
fstp dword ptr [xs4] ;1
;;;;;;
fld dword ptr [esi+4] ;1 x1
fld dword ptr [ys3] ;2 ys3,x1
fld st ;3 ys3,ys3,x1
fmul st,st(2) ;3 ys3x1,ys3,x1
fld dword ptr [esi] ;4 y1,ys3x1,ys3,x1
fld dword ptr [xs4] ;5 xs4,y1,ys3x1,ys3,x1
fld st ;6 xs4,xs4,y1,ys3x1,ys3,x1
fmul st,st(2) ;6 xs4y1,xs4,y1,ys3x1,ys3,x1
fsub st,st(3) ;6 xs4y1+ys3x1,xs4,y1,ys3x1,ys3,x1


fdiv dword ptr [r1]
fstp dword ptr [edi] ;5 xs4,y1,ys3x1,ys3,x1
fstp st(2) ;4 y1,xs4,ys3,x1
fmulp st(2),st ;3 xs4,ys3y1,x1
fmulp st(2),st ;2 ys3y1,x1xs4
faddp st(1),st ;1

fdiv dword ptr [r1]
fstp dword ptr [edi+4] ;0
ret
just_turn:
fld dword ptr [angle] ;1
fmul dword ptr [pi_na_180] ;1
fld st ;2
fcos ;2
fxch st(1) ;2
fsin ;2 sin,cos
fld dword ptr [edi+4] ;3 ys1,sin,cos
fld st ;4 ys1,ys1,sin,cos
fld dword ptr [edi] ;5 xs2,ys1,ys1,sin,cos
fld st ;6 xs2,xs2,ys1,ys1,sin,cos
fmul st,st(5) ;6 xs2cos,xs2,ys1,ys1,sin,cos
fxch st(2) ;6 ys1,xs2,xs2cos,ys1,sin,cos
fmul st,st(4) ;6 ys1sin,xs2,xs2cos,ys1,sin,cos
fsubp st(2),st ;5 xs2,xs2cos+ys1sin,ys1,sin,cos
fmulp st(3),st ;4 xs2cos+ys1sin,ys1,xs2sin,cos
fstp dword ptr [edi] ;3 ys1,xs2sin,cos
fmulp st(2),st ;2
faddp st(1),st ;1
fstp dword ptr [edi+4] ;0
ret
rotate endp
kill
kill
Thanks! This helps a lot. Does anyone have a C/C++ equivalent of this function, though? It''s pretty hard to learn how something works from assembly code

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.