Align to Vector
Blitz3D Forums/Blitz3D Programming/Align to Vector
| ||
I am designing some spaceflight routines, and I believe I need to use AlignToVector command so that the momentum of the spaceship will continue in the direction it *was* pointing, even after it has turned round. However, I am a little stuck as to how to approach this - the AlignToVector docs just confused me as to how the acual values should be entered. Any tips? |
| ||
I don't see how AlignToVector is necessary for what you describe but I will try to explain the command (I use it in my current project although my understanding is a bit foggy; I got it to work with a little trial and error.) The hard part is understanding the values for the vector you are aligning to. Imagine a line with one point on the origin (ie. coordinate 0,0,0.) That line obviously has another coordinate for the end of the line. Thus that second coordinate describes the line, and those coordinates are the values you use with AlignToVector. |
| ||
That's a bit better. I was still thinking of co-ords, not vectors. I'l retry the above! |
| ||
using Translateentity would be more usefull for Forces |
| ||
I am still struggling with this concept. It shouldn't be so difficult in theory, but in practice...I have shad some very strange effects with entitypitch / turnentity xx,0,0 I understand I will need a pivot which holds the current momentum, and the spaceship should move in the direction of the pivot regardless of facing. According to how fast/heavy etc the ship is moving, the pivot should gradually align itself with the ships' true facing. This is where I think I need AlignToVector - or some complicated trig routines or something... |
| ||
try this instead of aligntovector as it works for pitch and yaw. Alligntovecor only works one one plane well in my experience.tdx#= (oldx-(Entityx(mesh))) tdz#= (oldz-Entityz(mesh)) traveldist#=Sqr#((tdx#*tdx#)+(tdz#*tdz#)) travelyaw#=ATan2(tdx,-tdz) travelpitch#=ATan2((oldy-EntityY(mesh)),traveldist) rotateentity mesh, travelpitch#, travelyaw#,0 set entities oldx,oldy,oldz at end of main loop |
| ||
"I understand I will need a pivot which holds the current momentum, and the spaceship should move in the direction of the pivot regardless of facing." Depending on how realistic you want to get, you'll need to track both momentum and angular momentum. "According to how fast/heavy etc the ship is moving, the pivot should gradually align itself with the ships' true facing." Again, if you're going for realism, there's absolutely no correlation between the direction you're heading and your velocity vectory. Under continuous acceleration in a fixed direction your velocity vector will slowly approach but never match your heading vector. Since hardly anyone will ever do this it's pretty irrelevant. "This is where I think I need AlignToVector - or some complicated trig routines or something..." Not really. Your acceleration can be represented by a pretty simple vector (0,0,a) where a is how big your acceleration is. Put a pivot there and then apply your heading to it; convert its position into global coordinates and add that to your accumulated velocity v = (vx, vy, vz). Your velocity is simply applied to your position in global coordinates rather than local. Note that Newtonian movement in Space is not for the faint-of-heart. Having implemented all this you'll probably find getting anywhere to be next to impossible. And if you take angular momentum into account you'll go completely nuts trying to do anything. It sounds like what you're really trying to do is put "lag" into the controls. If that's the case, I'd suggest keeping a bunch of pivots handy and setting them to your old headings, and then using a pivot that's say 0.5 seconds old to determine your velocity vector. |
| ||
Note that Newtonian movement in Space is not for the faint-of-heart Reminds me of the Elite follow-ups 'Frontier' and 'First Encounters' they were unplayable cos you could never change direction in anything less than what seemed like hours - did'nt seem to effect the enemy ships though - they would happily buzz around you taking pot-shots ! |
| ||
Looks nice and simple, Zilch - I will try that, Thanks! @Podperson - I understand that Force will not affect motion at right angles, but to avoid infinite velocities, I have decided to limit the max speed, and have a constant Reaction against the Thrust Force of the ship (maybe due to micrometeorites etc!) so that the ship will always eventually come to rest in a certain direction unless Thrust is applied in that direction. I am okay with Physics, but have lost all my reference materials, and am just haviing a brainstorm on this particular issue. the Frontier system was far too realistic, and detracted from the actual 'enjoyment' of combat I think. Well, I will give it a try and see what happens. Thanks loads for your help! |
| ||
I tried the above methods,and failed. Zilch's idea either gave obscre reslts with Pitch, or didnt move at all, and the vector method resulted in a ship that woldn't stop moving in various directions. I am really sorry for all the hassle, but I just cannot implement this idea at all. Here is a link to the bare-bones of what I have now. If anyone can help I'd REALLY appreciate it! http://homepage.ntlworld.com/r.chowdhury/ Relevant Folder = Galactic.zip galactic.zip |
| ||
malice, spent a few hours and knocked this together. no comments in it yet....very tired... :D Please let me know how u get on if this helps Graphics3D 800,600 SetBuffer BackBuffer() camera=CreateCamera() MoveEntity camera,0,80,0 RotateEntity camera,90,0,0 light=CreateLight() ship=CreateCube() ScaleEntity ship,1,0.3,5 turn#=0 speed#=0.001 xvector#=0 zvector#=0 While Not KeyHit(1) If KeyDown(203) Then turn=turn+1:RotateEntity ship,0,turn,0 If KeyDown(205) Then turn=turn-1:RotateEntity ship,0,turn,0 If KeyDown(200) And speed<0 Then speed=speed+0.000005:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) If KeyDown(200) And speed>0 Then speed=speed+0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed<0 Then speed=speed-0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed>0 Then speed=speed-0.000005:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) TranslateEntity ship,-xvector,0,zvector UpdateWorld RenderWorld Text 0,0," turn="+turn+" cos(turn)="+Cos(turn)+" speed="+speed+" XVector="+xvector+" ZVector="+zvector Flip Wend End |
| ||
thatmay be just what I was looking for thanks!!! Tried it as-it-is, I will need to incorporate it. I am concerned as to the fact that, as other code, it is only 2-dimensional, but I'll give it a go... Thanks again :) |
| ||
i'm tryin to work out how to incorporate the third vector. i'm a bit stumped. and also please change this in the code i gave you orginal If KeyDown(200) And speed<0 Then speed=speed+0.000005:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) If KeyDown(200) And speed>0 Then speed=speed+0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed<0 Then speed=speed-0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed>0 Then speed=speed-0.000005:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) changed If KeyDown(200) And speed<0 Then speed=speed+0.00001:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) If KeyDown(200) And speed>0 Then speed=speed+0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed<0 Then speed=speed-0.00001:xvector=xvector+(speed*-Sin(turn)):zvector=zvector+(speed*-Cos(turn)) If KeyDown(208) And speed>0 Then speed=speed-0.00001:xvector=xvector-(speed*-Sin(turn)):zvector=zvector-(speed*-Cos(turn)) |
| ||
Thanks a lot, joker. I appreciate it's a real headache! I've got your name down for the credits, though! |
| ||
I Got a working example using the atan2 method. Then I finaly understood Aligntovector command, so I thought I might share a working Aligntovector example. The ship in the example code uses rocket thrust to move. Giving aceleration the longer you press the direction key. This works in 3D, and you can even do loop the loops OK! Global title$="Space Movement Sample" AppTitle title$ Graphics3D 800,600 SetBuffer BackBuffer() Global msecs=MilliSecs() Global you=CreatePivot() PositionEntity you,0,40,-150 Global cam=CreateCamera(you) PositionEntity cam,0,0,0 CameraRange cam,1,20000 CameraClsColor cam,120,120,170 light=CreateLight(2) PositionEntity light,0,200,0 ;-- ground plane= CreatePlane() PositionEntity plane,0,-20,0 EntityPickMode plane,2,0 planetex=gridtex(256,16,4) EntityTexture plane,planetex ScaleTexture planetex,256,256 zero = CreatePivot() PositionEntity zero,0,30,0 ZeroX#=EntityX(zero,1) ZeroY#=EntityY(zero,1) ZeroZ#=EntityZ(zero,1) pole = CreateCylinder(22,1,zero) ScaleEntity pole,1,30,1 EntityColor pole,210,210,10 pole2 = CreateCylinder(22,1,zero) EntityColor pole2,10,210,210 RotateMesh pole2,90,0,0 ScaleMesh pole2,1,1,20 pole3 = CreateCylinder(22,1,zero) EntityColor pole3,10,10,210 RotateMesh pole3,90,90,0 ScaleMesh pole3,20,1,1 ;-- Ship Ship = CreateCone(22,1) RotateMesh Ship,90,0,0 ScaleMesh Ship,4,4,10 EntityColor Ship,250,190,190 wings = CreateCone(22,1,Ship) RotateMesh wings,90,0,0 ScaleMesh wings,14,.4,6 EntityColor wings,250,190,190 Head=CreateSphere(22,Ship) ScaleMesh Head,2,3,4 EntityColor Head,20,255,25 PositionEntity Head,0,1,-1.5 shiptex=Gridtex(64,8,4,155,100,100,100,100,205) EntityTexture ship,shiptex Wingtex=Gridtex(64,4,2,205,100,100,100,100,205) EntityTexture wings,wingtex inertia# =.999 Excel# = .01 Lexcel# = .01 Rexcel# = .01 Lift# = .01 TurnSpeed# = .01; How fast Ship turns to point in Direction of Travel While Not KeyHit(1) If KeyHit( 17) Then wf = Not wf : WireFrame wf ms = MilliSecs() - start Excel# = Excel + MouseZSpeed()*.001 If MouseDown(1) Or KeyDown(200) Then ;back rocket TFormVector 0,0,Excel,Ship,0 ;convert force to global space coords RearRocketForceX#=TFormedX#() RearRocketForceY#=TFormedY#() RearRocketForceZ#=TFormedZ#() Else If KeyDown(208) Then TFormVector 0,0,-Excel*.5,Ship,0 ;reverse (Forward thrusters) RearRocketForceX#=TFormedX#() RearRocketForceY#=TFormedY#() RearRocketForceZ#=TFormedZ#() Else RearRocketForceX#=0 RearRocketForceY#=0 RearRocketForceZ#=0 End If If KeyDown(203) And( Not KeyDown(157)) Then ;rightside rocket (to go left!) TFormVector -LExcel,0,0,Ship,0 RRocketForceX#=TFormedX#() RRocketForceY#=TFormedY#() RRocketForceZ#=TFormedZ#() Else If KeyDown(203) And KeyDown(157) Then TurnEntity Ship,0,1,0 Else RRocketForceX#=0 RRocketForceY#=0 RRocketForceZ#=0 End If If KeyDown(205)And (Not KeyDown(157)) Then ;leftside rocket (to go right!) TFormVector RExcel,0,0,Ship,0 LRocketForceX#=TFormedX#() LRocketForceY#=TFormedY#() LRocketForceZ#=TFormedZ#() Else If KeyDown(205)And KeyDown(157) Then TurnEntity Ship,0,-1,0 Else LRocketForceX#=0 LRocketForceY#=0 LRocketForceZ#=0 End If If MouseDown(2) Then ;lift rocket TFormVector 0,lift,0,Ship,0 LiftRocketForceX#=TFormedX#() LiftRocketForceY#=TFormedY#() LiftRocketForceZ#=TFormedZ#() Else If MouseDown(3) Then ;down rocket TFormVector 0,-lift,0,Ship,0 LiftRocketForceX#=TFormedX#() LiftRocketForceY#=TFormedY#() LiftRocketForceZ#=TFormedZ#() Else LiftRocketForceX#=0 LiftRocketForceY#=0 LiftRocketForceZ#=0 End If ForceX#=RearRocketForceX + RRocketForceX# + LRocketForceX# + LiftRocketForceX# ForceY#=RearRocketForceY + RRocketForceY# + LRocketForceY# + LiftRocketForceY# ForceZ#=RearRocketForceZ + RRocketForceZ# + LRocketForceZ# + LiftRocketForceZ# DeltaX# = ForceX+(DeltaX#*inertia) DeltaY# = ForceY+(DeltaY#*inertia) DeltaZ# = ForceZ+(DeltaZ#*inertia) TranslateEntity Ship, DeltaX#, DeltaY#, DeltaZ#,1 If KeyHit(57) Then ;space bar resets coords to zero pos. CurrentX# = ZeroX CurrentY# = ZeroY CurrentZ# = ZeroZ PositionEntity Ship, CurrentX#, CurrentY#,CurrentZ#,1 RotateEntity Ship,0,0,0,1 DeltaX# = 0 DeltaY# = 0 DeltaZ# = 0 PositionEntity you,0,40,-150 PointEntity you,Ship End If If KeyHit(25) Then follow = Not follow If follow Then EntityParent you,Ship Else EntityParent you,0 PositionEntity you,0,40,-150 End If End If If (DeltaX#<>0) Or (DeltaY#<>0) Or (DeltaZ#<>0) Then AlignToVector ship,deltax,deltay,deltaz,3,TurnSpeed End If RenderWorld Color 255,255,100 Text 10,10, " DeltaX "+DeltaX+" DeltaY "+ DeltaY+" DeltaZ "+ DeltaZ Text 10,30, " Yaw Current "+ Floor(currentYaw) +" Dest "+Destyaw ; debuglog " Yaw Current " + floor(entityYaw(Ship,1)) +" Dest "+Destyaw Text 10,50, " Pitch Current "+ Floor(EntityPitch(Ship,1))+" Dest "+destpitch Color 100,55,255 text 0,530, " Arrow Keys to move using rockets. Ctrl + Left/Right Arrows = Turn ship with no rockets" text 0,550, " Mousebutton 1 = forward - Mousebutton 2 = Lift Rocket - Mousebutton 3 = Down Rocket" text 0,570, " Mousewheel = Speed. Space Bar = Return to Zero. P Key = Toggles Parenting Camera to ship" Flip False Wend End ;This function is for drawing Grid Textures. Function gridtex(s=512,st=5,width=2,colr=0,colg=0,colb=0,backcolr=0,backcolg=0,backcolb=0) tex=CreateTexture(s,s,1) SetBuffer TextureBuffer(tex) Color backcolr,backcolg,backcolb Rect 0,0,s,s,1 a = 0 i#=s/255.0 Repeat If (colr+colg+colb = 0) Then Color a Mod 255,Abs(255-a/i), 255-a;190+Sin(a)*50 DebugLog a Else Color colr,colg,colb End If For w= 0 To width-1 Line a+w,0,a+w,s Line 0,a+w,s,a+w Next a = a + st Until a => s SetBuffer BackBuffer() Return tex End Function |