This is 2d code which I have posted before but I am sure you can do somethign with it. Look at binding for clues on how to navigate towards a certain area/point. My code is well ropey I only did it to get my head around how to go about doing arbitrary obstacle avoidance and Ive never taken it further. (I get bored easily)
basically for 3d you need to extend the transformation to local space to cope with 3 dimentions. You need 2 calculations 1 for the pitch plane of your object and one for the yaw.. other than that its going to be much the same as for 2d
Const NORMAL =0
Const ALERT = 1
Const COLLIDED = 2
Global drawn ;a global variable simply to determine if the territorial "bind" area has been drawn
;meet bob - a behavioural object
Type bob
Field x#
Field y#
Field heading#
Field rotation#
Field speed#
Field state
Field wander
Field Bind
Field avoid
End Type
;draw a bob to the screen
Function drawbob(abob.bob)
Local x#=abob\x
Local y#=abob\y
Local heading=abob\heading
Local sh#=10*Sin(heading)
Local ch#=10*Cos(heading)
If abob\state=ALERT Then
Color 255,255,100
Else If abob\state = NORMAL
Color 0,255,0
Else If abob\state=COLLIDED
Color 255,0,0
End If
Oval( x-10,y-10,20,20,1)
Color 255,255,255
Line x,y,x+1*sh,y-1*ch
;left side of sensor box
sx1=x-1*ch
sy1=y-1*sh
sx2=sx1+6*sh
sy2=sy1-6*ch
;right side of sensorbox
sx3=x+1*ch
sy3=y+1*sh
sx4=sx3+6*Sh
sy4=sy3-6*Ch
Line sx1,sy1,sx2,sy2
Line sx2,sy2,sx4,sy4
Line sx4,sy4,sx3,sy3
Oval x-15,y-15,30,30,0
End Function
;rotate a bob by an specified ammount
Function rotatebob(abob.bob,ammount#)
abob\heading = abob\heading + ammount
If abob\heading>=360 Then abob\heading=abob\heading-360
If abob\heading<0 Then abob\heading = 360+abob\heading
End Function
;move a bob by its speed relative to its current heading
Function movebob(abob.bob)
rotatebob(abob,abob\rotation)
x#=abob\x
y#=abob\y
heading = abob\heading
x=x+abob\speed*Sin(heading)
y=y-abob\speed*Cos(heading)
abob\x=x
abob\y=y
End Function
;randomly alter the bobs turn rate to change its heading periodicaly
Function wanderbob(abob.bob)
If Not abob\wander Then Return
a=Rand(10)
If a<=3 Then abob\rotation=abob\rotation+1
If a>=8 Then abob\rotation=abob\rotation-1
If abob\rotation>3 Then abob\rotation=3
If abob\rotation<-3 Then abob\rotation=-3
End Function
;"bind" a bob to a rectangular area
;this simulates a desire for a bob to remain close to or within this area
Function Bindbob (abob.bob,ox,oy,width,height)
Local x#=abob\x
Local y#=abob\y
Local heading = abob\heading
Local rotation#= abob\rotation
If Not drawn Then
Color 128,128,128
Rect ox,oy,width,height,0
Color 255,255,255
drawn=1
End If
If Not abob\Bind Then Return
b_left=ox
b_right=ox+width
b_top=oy+height
b_bottom=oy
If x<b_left Then
If y<b_bottom Then
If heading <=90 rotation=rotation +1
If heading >315 rotation=rotation+1
If heading >180 And heading <=315 Then rotation = rotation -1
Else If y>b_top Then
If heading >90 And heading <225 Then rotation = rotation -1
If heading >225 Then rotation = rotation +1
Else
If heading>180 And heading <270 Then rotation=rotation-1
If heading>=270 Then rotation = rotation +1
End If
End If
If x>b_right Then
If y<b_bottom Then
If heading <45 Or heading >=270 Then rotation = rotation -1
If heading >=45 And heading <=180 Then rotation = rotation +1
Else If y>b_top Then
If heading <135 Then rotation = rotation -1
If heading >=135 And heading <270 Then rotation = rotation +1
Else
If heading >90 And heading <=180 Then rotation = rotation +1
If heading <=90 Then rotation =rotation -1
End If
End If
If x<b_right And x>b_left Then
If y>b_top Then
If heading >45 And heading <=180 Then rotation = rotation -1
If heading >180 And heading <=315 Then rotation =rotation +1
End If
If y<b_bottom Then
If heading <135 Then rotation = rotation +1
If heading >225 Then rotation = rotation -1
End If
End If
If rotation<-3 Then rotation=-3
If rotation>3 Then rotation=3
abob\rotation=rotation
End Function
;bobs want to travel in a straight line so
;if they are not continually steered they will "straighten up"
Function dampbob(abob.bob)
rot#=abob\rotation
If abob\speed>1.5 Then abob\speed=1.5
If abob\speed>1 Then abob\speed=abob\speed-0.1
If abob\speed<0.1 Then abob\speed=0.1
If rot <0 Then rot=rot+0.1
If rot >0 Then rot=rot-0.1
If Abs(rot)<0.1 Then rot = 0
abob\rotation=rot
End Function
;make a bob follow another bob
Function seekBob(predator.bob, prey.bob)
Local x#=predator\x
Local y#=predator\y
Local heading#=predator\heading
Local rotation#=predator\rotation
Local tx#,ty#
tx=prey\x-x
ty=prey\y-y
tx2=tx*Cos(180-heading)-ty*Sin(180-heading)
ty2=tx*Sin(180-heading)+ty*Cos(180-heading)
If tx2<0 Then rotation=rotation+1
If tx2>0 Then rotation=rotation-1
If (tx2^2+ty2^2)>900 Then
predator\speed=predator\speed +0.1
Else
predator\speed=predator\speed -0.1
End If
predator\rotation=rotation
End Function
;bobs hate running into other bobs as it gives them a red face
Function avoidbob(abob.bob)
Local x#=abob\x
Local y#=abob\y
Local heading#=abob\heading
Local rotation#=abob\rotation
Local tx#,ty#
Local avoiding.bob
;transform the coords of each bob in to local bobspace
avoiding=Null
count=count+1
For a.bob=Each bob
If a<>abob Then
tx#=(a\x-x)
ty#=(a\y-y)
;tx and ty now represent "a.bob" relative to abob (abobs position is now the origin)
;rotate this point around the origin
tx2=tx*Cos(180-heading)-ty*Sin(180-heading)
ty2=tx*Sin(180-heading)+ty*Cos(180-heading)
If tx2>=-30 And tx2<=30 And ty2>=-30 And ty2<=70 Then
abob\state=ALERT
If Sqr(tx2^2+ty2^2) <20 Then abob\state=COLLIDED
If tx2<0 And ty2>0 Then rotation =rotation-1
If tx2>=0 And ty2>0 Then rotation = rotation +1
;if a bob is avoiding another bob it is focused on its task
;and ignores all other stimulii
abob\wander=0
abob\Bind=0
;abob\seek=0
avoiding=a
If ty2>0 Then
abob\speed=abob\speed-0.1
Else
abob\speed=abob\speed+0.1
End If
End If
End If
;left alone a bob will continue to wander around its territory
If avoiding=Null Then
abob\wander=1
abob\Bind=1
;abob\seek=1
abob\state=NORMAL
If abob\speed<1 abob\speed=abob\speed+0.1
End If
abob\rotation=rotation
Next
End Function
Graphics 800,600,32,2
SetBuffer BackBuffer()
SeedRnd(MilliSecs())
;create one or more bobs
While numbobs=0
numbobs=Input ("number of bobs?:")
If numbobs=0 Then Print" 0 is not allowed"
Wend
Local hunter.bob
Local hunted.bob
target=1
While numbobs>1 And target = 1
target = Rand (numbobs)
Wend
For f=1 To numbobs
a.bob=New bob
a\x=Rand(600)+100
a\y=Rand(400)+100
a\heading=Rand (360)
a\speed=1
a\wander=1
If f=1 Then hunter = a
If f=target Then hunted = a
Next
Bind = 1
wander = 1
avoid = 1
height = 100
width=100
t1=MilliSecs()
t2=MilliSecs()
timer=0
While Not KeyHit(1)
Cls
count=0
Local huntx,hunty
Local preyx,preyy
For a.bob =Each bob
movebob(a)
If wander Then wanderbob(a)
; If a = hunter Then
; seekbob(hunter,hunted)
; huntx=a\x
; hunty=a\y
; Else If a= hunted Then
; preyx=a\x
; preyy=a\y
; End If
If bind Then Bindbob(a,400-width/2,300-height/2,width,height)
If avoid Then avoidbob(a)
dampbob(a)
drawbob(a)
Next
;Text huntx,hunty,"Hunter"
;Text preyx,preyy,"Prey"
drawn=0
If KeyHit(48) Then Bind=Not Bind
If KeyHit(17) Then wander=Not wander
If KeyHit(30) Then avoid=Not avoid
If KeyHit(203) Then width=width+50
If KeyHit(205) Then width=width-50
If KeyHit(200) Then height=height+50
If KeyHit(208) Then height=height-50
If height<=0 Then height = 2
If width<=0 Then width =2
Text 10,10,"(W)Wandering:"+wander
Text 10,25,"(B)Territory Binding:"+Bind
Text 10,40,"(A)Avoidance:"+avoid
Text 10,55,"(Arrow keys)Change Territory size"
Text 10,70,"(Esc)Quit"
t1=t2
t2=MilliSecs()
timer=timer+(t2-t1)
If timer>100 FPS#=1000/Float(t2-t1): timer=0
Text 10,95,FPS
Flip 0
Wend