Hi again all
Sorry if this gets too frequent but i had such a good experience last time when asking a question, that I choose to get in touch again.
I now need a function to always rotate a object to it's line of travel.
i am creating in a 3d world and using physics by setting linear velocity.
All is really going good, but i can't figure out how to use "SetObject3DPhysicsAngularVelocity".
As the objects can collide and move around it must update and rotate accordingly to its line of travel.
Please help me get the angular velocity correct and finally get these boids moving smoothly.
I am a novice in coding, all tips and tricks are more then welcome ! c",)
/////////////////////////////////////////////////
// Spesial thanks to:
// Daniel, "TheCodingTrain" - Youtube.
// Virtual Nomad & PartTimeCoder - Agk forum.
/////////////////////////////////////////////////
// Boids for App Game Kit by RotaMafia
// show all errors
SetErrorMode(2)
// set window properties
SetWindowTitle( "boids" )
SetWindowSize( 1024, 768, 0 )
SetWindowAllowResize( 1 ) // allow the user to resize the window
// set display properties
SetVirtualResolution( 1024, 768 ) // doesn't have to match the window
SetOrientationAllowed( 1, 1, 1, 1 ) // allow both portrait and landscape on mobile devices
SetSyncRate( 30, 0 ) // 30fps instead of 60 to save battery
SetScissor( 0,0,0,0 ) // use the maximum available screen space, no black borders
UseNewDefaultFonts( 1 )
// blue fog
SetFogMode(1)
SetFogColor(0,50,200)
SetFogRange(150,1000)
SetSunActive(1)
SetAmbientColor(0,20,100)
// 3d world setup
Create3DPhysicsWorld()
//setphysicsdebugon()
Set3DPhysicsGravity(0.0, 0.0, 0.0)
// fibonacci sphere
#constant pi = 3.14159
#constant sequence# = 25 // sequence 25 for good spreadout (can be anything)
// camera setup
global camx
global camy
global camangx
global camangy
global camx#
global camy#
global camz#
SetCameraPosition(1,0,100,-200)
SetCameraLookAt ( 1, 0 ,0 ,0,0)
// max number of boids
global maxboids = 100 // defult: 100
// display dream motion
global disp = 0 // attached not visible
// variables to multiplie with
global alignmentforce as float
global cohersionforce as float
global separationforce as float
global borderforce as float
// boids stats
global dim attached [ maxboids ]
global dim boid [ maxboids ] as boids
type boids
//objects ref name
object as integer
state as integer
velocity as float
//next position
boidsxvelocity as float
boidsyvelocity as float
boidszvelocity as float
//cohersion
grp_cohersionx as float
grp_cohersiony as float
grp_cohersionz as float
cohersionx as float
cohersiony as float
cohersionz as float
grp_cohersiondist as float
grp_cohersioncount as float
//alignment
grp_alignmentx as float
grp_alignmenty as float
grp_alignmentz as float
alignmentx as float
alignmenty as float
alignmentz as float
grp_alignmentdist as float
grp_alignmentcount as float
// separation
grp_separationx as float
grp_separationy as float
grp_separationz as float
separationx as float
separationy as float
separationz as float
grp_separationdist as float
grp_separationcount as float
// borders
borderx as float
bordery as float
borderz as float
borderdist as float
endtype
// senses & intelligence
global spheresize as float
global viewrange as float
global separationrange as float
global maxlinearvelocity as float
global travledistance as float
spheresize = 50 // start sphere size defult: 50
viewrange = 20 // range of each boids view defult: 20
separationrange = viewrange // separation detection range defult: 20
maxlinearvelocity = 30 // boids max velocity aka speed defult: 30
travledistance = 90 // set how far boids can travle from center defult: 90
// create boids in a sphere formation
_createboids()
// loop
do
// run function for all boids
for i = 1 to maxboids
_cohersion(i)
_alignment(i)
_separation(i)
_borders(i)
_adjustment(i)
_calculaterute(i)
_calculatespeed(i)
_move(i)
_reset(i)
next i
// move cam function
_movecam()
// game world update
Step3DPhysicsWorld()
print("Fps "+str(ScreenFPS(),1))
Sync()
loop
// cohersion
function _cohersion(selected as integer)
for i = 1 to maxboids
if i <> selected
boid[selected].grp_cohersiondist = distance3D(GetobjectWorldX(boid[selected].object),GetobjectWorldY(boid[selected].object),GetobjectWorldZ(boid[selected].object),GetobjectWorldX(boid[i].object),GetobjectWorldY(boid[i].object),GetobjectWorldZ(boid[i].object))
if boid[selected].grp_cohersiondist < viewrange and boid[selected].grp_cohersioncount < maxboids //and boid[selected].grp_cohersiondist > separationrange
inc boid[selected].grp_cohersionx , GetobjectWorldX( boid[i].object )-GetobjectWorldX( boid[selected].object ) // / boid[selected].grp_cohersiondist //(GetVector3X( boid[selected].currvec3 )-boid[i].boidsxvelocity )
inc boid[selected].grp_cohersiony , GetobjectWorldY( boid[i].object )-GetobjectWorldY( boid[selected].object ) // / boid[selected].grp_cohersiondist //(GetVector3Y( boid[selected].currvec3 )-boid[i].boidsyvelocity )
inc boid[selected].grp_cohersionz , GetobjectWorldZ( boid[i].object )-GetobjectWorldZ( boid[selected].object ) // / boid[selected].grp_cohersiondist //(GetVector3Z( boid[selected].currvec3 )-boid[i].boidszvelocity )
boid[selected].grp_cohersioncount = boid[selected].grp_cohersioncount + 1.0
endif
endif
next i
// add up all
if boid[selected].grp_cohersioncount > 0.0
inc boid[selected].cohersionx , boid[selected].grp_cohersionx / boid[selected].grp_cohersioncount
inc boid[selected].cohersiony , boid[selected].grp_cohersiony / boid[selected].grp_cohersioncount
inc boid[selected].cohersionz , boid[selected].grp_cohersionz / boid[selected].grp_cohersioncount
endif
endfunction
// alignment
function _alignment(selected as integer)
for i = 1 to maxboids
if i <> selected
boid[selected].grp_alignmentdist = distance3D(GetobjectWorldX(boid[selected].object),GetobjectWorldY(boid[selected].object),GetobjectWorldZ(boid[selected].object),GetobjectWorldX(boid[i].object),GetobjectWorldY(boid[i].object),GetobjectWorldZ(boid[i].object))
if boid[selected].grp_alignmentdist < viewrange and boid[selected].grp_alignmentcount < maxboids
inc boid[selected].grp_alignmentx , GetObject3DPhysicsLinearVelocityX(boid[i].object)
inc boid[selected].grp_alignmenty , GetObject3DPhysicsLinearVelocityY(boid[i].object)
inc boid[selected].grp_alignmentz , GetObject3DPhysicsLinearVelocityZ(boid[i].object)
boid[selected].grp_alignmentcount = boid[selected].grp_alignmentcount + 1.0
endif
endif
next i
// add up all
if boid[selected].grp_alignmentcount > 0.0
inc boid[selected].alignmentx , boid[selected].grp_alignmentx / boid[selected].grp_alignmentcount
inc boid[selected].alignmenty , boid[selected].grp_alignmenty / boid[selected].grp_alignmentcount
inc boid[selected].alignmentz , boid[selected].grp_alignmentz / boid[selected].grp_alignmentcount
endif
endfunction
// separation
function _separation(selected as integer)
for i = 1 to maxboids
if i <> selected
boid[selected].grp_separationdist = distance3D(GetobjectWorldX(boid[selected].object),GetobjectWorldY(boid[selected].object),GetobjectWorldZ(boid[selected].object),GetobjectWorldX(boid[i].object),GetobjectWorldY(boid[i].object),GetobjectWorldZ(boid[i].object))
if boid[selected].grp_separationdist < separationrange and boid[selected].grp_separationcount < maxboids
inc boid[selected].grp_separationx ,GetObjectWorldX( boid[selected].object )-GetObjectWorldX( boid[i].object ) / boid[selected].grp_separationdist
inc boid[selected].grp_separationy ,GetObjectWorldY( boid[selected].object )-GetObjectWorldY( boid[i].object ) / boid[selected].grp_separationdist
inc boid[selected].grp_separationz ,GetObjectWorldZ( boid[selected].object )-GetObjectWorldZ( boid[i].object ) / boid[selected].grp_separationdist
boid[selected].grp_separationcount = boid[selected].grp_separationcount + 1.0
endif
endif
next i
// add up all
if boid[selected].grp_separationcount > 0.0
inc boid[selected].separationx , boid[selected].grp_separationx / boid[selected].grp_separationcount
inc boid[selected].separationy , boid[selected].grp_separationy / boid[selected].grp_separationcount
inc boid[selected].separationz , boid[selected].grp_separationz / boid[selected].grp_separationcount
endif
endfunction
// borders
function _borders(selected as integer)
for i = 1 to maxboids
if i <> selected
boid[selected].borderdist = distance3D(0,0,0,GetobjectWorldX(boid[selected].object),GetobjectWorldY(boid[selected].object),GetobjectWorldZ(boid[selected].object))
if boid[selected].borderdist > travledistance
inc boid[selected].borderx , (GetObject3DPhysicsLinearVelocityX(boid[selected].object) * boid[selected].velocity) - GetobjectWorldX(boid[selected].object)
inc boid[selected].bordery , (GetObject3DPhysicsLinearVelocityY(boid[selected].object) * boid[selected].velocity) - GetobjectWorldY(boid[selected].object)
inc boid[selected].borderz , (GetObject3DPhysicsLinearVelocityZ(boid[selected].object) * boid[selected].velocity) - GetobjectWorldZ(boid[selected].object)
endif
endif
next i
endfunction
function _adjustment(selected as integer)
// force multiplier adjustment
alignmentforce = 1.0
cohersionforce = 1.0
separationforce = 1.0
borderforce = 1.0
// cohersion
boid[selected].cohersionx = boid[selected].cohersionx * cohersionforce
boid[selected].cohersiony = boid[selected].cohersiony * cohersionforce
boid[selected].cohersionz = boid[selected].cohersionz * cohersionforce
// alignment
boid[selected].alignmentx = boid[selected].alignmentx * alignmentforce
boid[selected].alignmenty = boid[selected].alignmenty * alignmentforce
boid[selected].alignmentz = boid[selected].alignmentz * alignmentforce
// separation
boid[selected].separationx = boid[selected].separationx * separationforce
boid[selected].separationy = boid[selected].separationy * separationforce
boid[selected].separationz = boid[selected].separationz * separationforce
// borders
boid[selected].borderx = boid[selected].borderx * borderforce
boid[selected].bordery = boid[selected].bordery * borderforce
boid[selected].borderz = boid[selected].borderz * borderforce
endfunction
// calculate rute
function _calculaterute(selected as integer)
// include all velocitys
inc boid[selected].boidsxvelocity , ( GetObject3DPhysicsLinearVelocityX(boid[selected].object) + boid[selected].separationx + boid[selected].cohersionx + boid[selected].alignmentx + boid[selected].borderx )
inc boid[selected].boidsyvelocity , ( GetObject3DPhysicsLinearVelocityY(boid[selected].object) + boid[selected].separationy + boid[selected].cohersiony + boid[selected].alignmenty + boid[selected].bordery )
inc boid[selected].boidszvelocity , ( GetObject3DPhysicsLinearVelocityZ(boid[selected].object) + boid[selected].separationz + boid[selected].cohersionz + boid[selected].alignmentz + boid[selected].borderz )
endfunction
// calculate speed
function _calculatespeed(selected as integer)
// calculate speed
boid[selected].velocity = distance3D(boid[selected].boidsxvelocity,boid[selected].boidsyvelocity,boid[selected].boidszvelocity,GetobjectWorldX(boid[selected].object),GetobjectWorldY(boid[selected].object),GetobjectWorldZ(boid[selected].object))
if boid[selected].velocity < 5 then boid[selected].velocity = 5
if boid[selected].velocity > maxlinearvelocity*2 then boid[selected].velocity=maxlinearvelocity
endfunction
// move calculate rute & calculate speed
function _move (selected as integer)
// set new velocity
SetObject3DPhysicsLinearVelocity( boid[selected].object,boid[selected].boidsxvelocity , boid[selected].boidsyvelocity , boid[selected].boidszvelocity , boid[selected].velocity )
// keep steady (so the fixed disp object don't look too weird)
SetObject3DPhysicsAngularVelocity( boid[selected].object,boid[selected].boidsxvelocity , boid[selected].boidsyvelocity , boid[selected].boidszvelocity , 0 ) `<- please help me figure out how to make them rotate with it's line of direction :)
// rotate attached object
if disp = 1
SetObjectLookAt(attached[selected],boid[selected].boidsxvelocity , boid[selected].boidsyvelocity , boid[selected].boidszvelocity, 0 )
endif
endfunction
// reste all states
function _reset(selected as integer)
// new move point
boid[selected].boidsxvelocity = 0
boid[selected].boidsyvelocity = 0
boid[selected].boidszvelocity = 0
// cohersion
boid[selected].grp_cohersionx = 0
boid[selected].grp_cohersiony = 0
boid[selected].grp_cohersionz = 0
boid[selected].cohersionx = 0
boid[selected].cohersiony = 0
boid[selected].cohersionz = 0
boid[selected].grp_cohersioncount = 0
boid[selected].grp_cohersiondist = 0
// alignment
boid[selected].grp_alignmentx = 0
boid[selected].grp_alignmenty = 0
boid[selected].grp_alignmentz = 0
boid[selected].alignmentx = 0
boid[selected].alignmenty = 0
boid[selected].alignmentz = 0
boid[selected].grp_alignmentdist = 0
boid[selected].grp_alignmentcount = 0
//separation
boid[selected].grp_separationx = 0
boid[selected].grp_separationy = 0
boid[selected].grp_separationz = 0
boid[selected].separationx = 0
boid[selected].separationy = 0
boid[selected].separationz = 0
boid[selected].grp_separationdist = 0
boid[selected].grp_separationcount = 0
// borders
boid[selected].borderx = 0
boid[selected].bordery = 0
boid[selected].borderz = 0
boid[selected].borderdist = 0
endfunction
// create boids in a sphere formation
function _createboids()
for i = 1 to maxboids
// calculate sphere position foreache boid
y# = 1.0 - (i/(maxboids-1.0)) * 2.0
radius# = SQRT(1-y#*y#)
theta# = pi * sequence# * i
y# = y# * spheresize
x# = SIN(theta#) * radius# * spheresize
z# = COS(theta#) * radius# * spheresize
// Psst: this is also great for creating points around
// the boids. Then create raycast between the boid and
// created points. This way you can "let the boid see!".
// With this the boid will avoid obsticals.
// I have a working function for this if you can't get
// it working. Just didn't include it.
// create and place
boid[i].object = createobjectbox(1,2,4)
SetObjectPosition(boid[i].object, x#, y#, z# )
// create and attach object to rotate
attached[i] = createobjectbox(1,2,4)
SetObjectColor(attached[i],0,25,25,255)
SetObjectColor(attached[i],random(20,255),random(20,255),random(20,255),255)
FixObjectToObject(attached[i],boid[i].object)
SetObjectVisible(attached[i],0)
SetObjectFogMode(attached[i],1)
// set physic settings
Create3DPhysicsDynamicBody( boid[i].object )
SetObject3DPhysicsCanSleep( boid[i].object, 0 )
SetObject3DPhysicsMass( boid[i].object, 0.5 )
SetObjectCollisionMode( boid[i].object, 0 )
SetObject3DPhysicsMaxLinearVelocity( boid[i].object, maxlinearvelocity )
SetObject3DPhysicsLinearVelocity( boid[i].object,0-GetobjectWorldX( boid[i].object ) ,0-GetobjectWorldY( boid[i].object ) ,0-GetobjectWorldZ( boid[i].object ) ,maxlinearvelocity )
SetObjectVisible(boid[i].object,1)
SetObjectFogMode(boid[i].object,1)
next i
endfunction
// move camera function
Function _movecam()
// cam controls
camspeed = 5 // cam speed
if disp = 0 then print("Move camera with W,S,A,D,Q,E")
if ( GetRawKeyState( 87 ) ) then MoveCameraLocalZ( 1, camspeed )
if ( GetRawKeyState( 83 ) ) then MoveCameraLocalZ( 1, -camspeed )
if ( GetRawKeyState( 68 ) ) then MoveCameraLocalX( 1, camspeed )
if ( GetRawKeyState( 65 ) ) then MoveCameraLocalX( 1, -camspeed )
if ( GetRawKeyState( 69 ) ) then MoveCameraLocalY( 1, camspeed )
if ( GetRawKeyState( 81 ) ) then MoveCameraLocalY( 1, -camspeed )
// decrese or increse max linear velocity
if disp = 0 then print("Press PLUSS or MINUS to adjust max linear velocity")
if ( GetRawKeyState( 107 ) )
maxlinearvelocity = maxlinearvelocity + 0.5
print(maxlinearvelocity)
elseif ( GetRawKeyState( 109 ) )
if maxlinearvelocity > 1
maxlinearvelocity = maxlinearvelocity - 0.5
print(maxlinearvelocity)
endif
endif
// display dream motion
if disp = 0 then print("Press SPACE to see dream motion")
if ( GetRawKeyPressed( 32 ) ) and disp = 0
for i = 1 to maxboids
SetObjectVisible(boid[i].object,0)
SetObjectVisible(attached[i],1)
next i
disp = 1
elseif ( GetRawKeyPressed( 32 ) ) and disp = 1
for i = 1 to maxboids
SetObjectVisible(boid[i].object,1)
SetObjectVisible(attached[i],0)
next i
disp = 0
endif
// rotate the camera w/mouse
if disp = 0 then print("Hold any MOUSE BUTTON to move camera")
if ( GetRawMouseLeftPressed() or GetRawMouseRightPressed() )
camx = GetPointerX()
camy = GetPointerY()
camangx = GetCameraAngleX(1)
camangy = GetCameraAngleY(1)
endif
if ( GetRawMouseLeftState() = 1 or GetRawMouseRightState() = 1)
camv1 = (GetPointerX() - camx)/camspeed
camv2 = (GetPointerY() - camy)/camspeed
camv3 = camangx + camv2
if ( camv3 > 89 ) then camv3 = 89
if ( camv3 < -89 ) then camv3 = -89
SetCameraRotation( 1, camv3, camangy + camv1, 0 )
endif
endfunction
// distance tool from GameCreators forum library
function distance3D(x1#,y1#,z1#,x2#,y2#,z2#)
dx#=x1#-x2#
dy#=y1#-y2#
dz#=z1#-z2#
distance#=sqrt(dx#*dx#+dy#*dy#+dz#*dz#)
endfunction distance#
P.S. Made out of several tutorials on YouTube. Especially Daniel's tutorials at "The Coding Train".
But this is all my code. Feel free to explore and use as you wish and maybe you can figure it out
"I, for one love finding stuff like this. Let us share the fun"