Align to Vector

Blitz3D Forums/Blitz3D Programming/Align to Vector

_PJ_(Posted 2003) [#1]
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?


jhocking(Posted 2003) [#2]
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.


_PJ_(Posted 2003) [#3]
That's a bit better. I was still thinking of co-ords, not vectors. I'l retry the above!


Neochrome(Posted 2003) [#4]
using Translateentity would be more usefull for Forces


_PJ_(Posted 2003) [#5]
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...


Ziltch(Posted 2003) [#6]
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


podperson(Posted 2003) [#7]
"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.


Ricky Smith(Posted 2003) [#8]

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 !


_PJ_(Posted 2003) [#9]
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!


_PJ_(Posted 2003) [#10]
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


Ross C(Posted 2003) [#11]
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



_PJ_(Posted 2003) [#12]
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 :)


Ross C(Posted 2003) [#13]
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))



_PJ_(Posted 2003) [#14]
Thanks a lot, joker. I appreciate it's a real headache!
I've got your name down for the credits, though!


Ziltch(Posted 2003) [#15]
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