AlignToVector
BlitzMax Forums/MiniB3D Module/AlignToVector
| ||
Right, rather than derail the 'XEdition' thread I'll start a new topic. The aim - to create a working AlignToVector function. Here's my attempt: Function AlignToVector(vx#,vy#,vz#,axis,rate#=1.0) Local pitch#=Abs(EntityPitch()) Local yaw#=Abs(EntityYaw()) Local roll#=Abs(EntityRoll()) Select axis Case 1 Local dest_yaw#=Abs(ATan2(vz#,vx#)) Local dest_roll#=Abs(ATan2(vy#,vx#)) yaw#=UpdateValue#(yaw#,dest_yaw#,rate#) roll#=UpdateValue#(roll#,dest_roll#,rate#) Case 2 Local dest_pitch#=Abs(ATan2(vz#,vy#)) Local dest_roll#=Abs(-ATan2(vx#,vy#)) pitch#=UpdateValue#(pitch#,dest_pitch#,rate#) roll#=UpdateValue#(roll#,dest_roll#,rate#) Case 3 Local dest_pitch#=Abs(-ATan2(vy#,vz#)) Local dest_yaw#=Abs(-ATan2(vx#,vz#)) pitch#=UpdateValue#(pitch#,dest_pitch#,rate#) yaw#=UpdateValue#(yaw#,dest_yaw#,rate#) End Select Self.RotateEntity pitch#,yaw#,roll# End Function Function UpdateValue#(current#,destination#,rate#) 'rate#=1.0/rate# current#=current#+((destination#-current#)*rate#) Return current# End Function And example code (BMX): Import "../MiniB3D.bmx" Graphics3D 640,480 ' set this to 1, 2 Or 3 axis=1 ' set vector vx#=0.0 vy#=1.0 vz#=0.0 camera=CreateCamera() PositionEntity camera,0,2,-5 RotateEntity camera,15,0,0 light=CreateLight() RotateEntity light,90,0,0 cone=CreateCone() xaxis=CreateCylinder(8,True,cone) RotateMesh xaxis,0,0,90 ScaleMesh xaxis,5.0,0.2,0.2 EntityColor xaxis,127,0,0 yaxis=CreateCylinder(8,True,cone) ScaleMesh yaxis,0.2,5.0,0.2 EntityColor yaxis,0,127,0 zaxis=CreateCylinder(8,True,cone) RotateMesh zaxis,90,0,0 ScaleMesh zaxis,0.2,0.2,5.0 EntityColor zaxis,0,0,127 marker=CreateSphere() ScaleEntity marker,0.2,0.2,0.2 PositionEntity marker,vx#,vy#,vz# ' change color of marker depending on axis selected Select axis Case 1 EntityColor marker,255,0,0 Case 2 EntityColor marker,0,255,0 Case 3 EntityColor marker,0,0,255 End Select While Not KeyDown(KEY_ESCAPE) AlignToVector cone,vx,vy,vz,axis,0.01 RenderWorld glColor3f 255,0,0 Text 0,0,"X" glColor3f 0,255,0 Text 0,20,"Y" glColor3f 0,0,255 Text 0,40,"Z" Flip Wend End Function Text(x,y,text$) ' reset texture matrix glMatrixMode(GL_TEXTURE) glLoadIdentity() ' set active texture to texture 0 so gldrawtext will work correctly glActiveTextureARB(GL_TEXTURE0) glClientActiveTextureARB(GL_TEXTURE0) ' enable texture 2D glEnable(GL_TEXTURE_2D) glDisable(GL_LIGHTING) GLDrawText text$,x,y glEnable(GL_LIGHTING) ' disable texture 2D - needed as gldrawtext enables it, but doesn't disable after use glDisable(GL_TEXTURE_2D) End Function Example code (B3D): Graphics3D 640,480 ; set this to 1, 2 or 3 axis=3 ; set vector vx#=0.0 vy#=1.0 vz#=0.0 camera=CreateCamera() PositionEntity camera,0,2,-5 RotateEntity camera,15,0,0 light=CreateLight() RotateEntity light,90,0,0 cone=CreateCone() xaxis=CreateCylinder(8,True,cone) RotateMesh xaxis,0,0,90 ScaleMesh xaxis,5.0,0.2,0.2 EntityColor xaxis,127,0,0 yaxis=CreateCylinder(8,True,cone) ScaleMesh yaxis,0.2,5.0,0.2 EntityColor yaxis,0,127,0 zaxis=CreateCylinder(8,True,cone) RotateMesh zaxis,90,0,0 ScaleMesh zaxis,0.2,0.2,5.0 EntityColor zaxis,0,0,127 marker=CreateSphere() ScaleEntity marker,0.2,0.2,0.2 PositionEntity marker,vx#,vy#,vz# ; change color of marker depending on axis selected Select axis Case 1 EntityColor marker,255,0,0 Case 2 EntityColor marker,0,255,0 Case 3 EntityColor marker,0,0,255 End Select While Not KeyDown(1) AlignToVector cone,vx,vy,vz,axis,0.01 RenderWorld Color 255,0,0 Text 0,0,"X" Color 0,255,0 Text 0,20,"Y" Color 0,0,255 Text 0,40,"Z" Flip Wend End The bmx version must work the same as the b3d version. The above version works some of the time, but some vector inputs won't work - such as x=0,y=-1,0,z=0.0,axis=2. Also, don't forget that this command can be used twice or three times to combine the axis rotations. |
| ||
Ahhh! Thanks very much Simon. I appreciate you helping us. I can't test it myself but I'm sure antony will pop in to have a look at it. Again, Thank You very much for your help. :) |
| ||
Good start, and thanks for helping out on the cause. We'll have a bump-mapped 3d engine in max oneday. Not sure why yours doesn't work all the time, but if it works some of the time it must be on the right track. Any chance mark will let just you sneak a peak at his aligntovector code to write us a version? No worries if not, just seems like the ideal solution. |
| ||
The aim - to create a working AlignToVector function. Isn't AlignToVector simply a SLERP? Thus, doesn't it stand to reason thst your version doesn't work, because it's using Euler angle, and thus prone to gimbal lockage? |
| ||
When the 'rate' parameter was added to AlignToVector I was curious about what it really meant. Some experimenting suggested it was doing this: 1. The axis to be aligned and the target vector determine a plane. 2. The entity turns about an axis perpendicular to this plane. 3. The rate gives the fraction of the "angle difference" to turn. This last part means that a rate of 0.5 will turn half the way to the target. Graphics3D 500, 400, 0, 2 SetBuffer FrontBuffer() piv = CreatePivot() : TurnEntity piv, 0, 160, 0 For n = 1 To 5 Print EntityYaw( piv ) AlignToVector piv, 0, 0, 1, 3, 0.5 ; turn half the way to the target Next WaitKey : End One possible glitch arises if the original axis and the target vector point in exactly opposite directions. In that case they do not determine a plane and the problem become ill-defined. Try changing 160 to 180 in the example. |
| ||
I just did a small test with some terrain I am working on. The Y axis worked when I got rid of the Abs(). For smooth angular interpolation, you have to use quaternions and perform a slerp routine. |
| ||
Perhaps I'm being thick but the code submitted at the start of the thread doesn't work. Compile Error: To Many Function Parameters |
| ||
Was align to vector ever added to minib3d? It's a very useful function...I used it all the time in blitz3d? Great for AI units in space combat sims. |
| ||
I have written an AlignToVector function for my mod, but I'm not sure if it will work with the standard minib3d version. TMatrix.bmx: |
| ||
something is strange... is there any fix for this? |
| ||
bump :) Looking for a simple AlignToVector (2) that I can port to iminib3d too otherwise I can't get it running on pc/mac as well as the ipad... If its simple maths I can port to C++ no problem but the above uses a different TMatrix... |
| ||
That's somewhat difficult, because I believe you need matrices to do that right. Here is what I tried: Demo: |
| ||
what JoshK said |
| ||
Thanks for the attempt Warner! I tried your code for AlignToVector but it won't align to the normal unfortunately. I'm just not sure why either! I would like to try and get an object to stand on a small sphere like super mario galaxy. Thank you for the demo though, I will keep trying? Whats happening is the character just turns away, is it possible it is mixing up a couple of numbers? Last edited 2010 |
| ||
Define turns away? Is it always flipped along 1 axis, or does it change at some points? OpenGl uses some inverted numbers in it's matrixies which could potentially be a factor depending on how they are applied to the existing matrix for the object... |
| ||
[edit]I think I see what you mean. Here is a slightly modified version: Last edited 2010 |
| ||
Wow that looks like it does the trick! I don't know how to thank you :) |
| ||
No problem, I do hope it suffices for what you need it for. The 'fix' line starts with if 'y < 0'. Could turn out that should be 'if y<=0' instead. Last edited 2010 |