steering behaviour/avoidance(opensteer)plugin

Posted By: Wjbender

steering behaviour/avoidance(opensteer)plugin - 07/20/12 19:41

im working on a plugin to exspose functions
for use in steering behaviour and collision avoidance
so far i have a few functions up and running and a experemental
example.. stil need to break it down into lower level
functions and add as much as possible.. will upload
sometime when i have the time the first (infant stage)
of my opensteer plugin with a demo showing seeking persuing and avoiding
behaviour ....
Posted By: 3run

Re: steering behaviour/avoidance(opensteer)plugin - 07/20/12 23:56

man, that would be really helpfull! I love your work mate! thank you for your stuff which you share with community! you help people alot!! laugh
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 07/23/12 07:32

I know the OpenSteer project, it seems to be a very efficient simulation package, so have luck for the job! It includes a great crowd or group movement simulation with path or leader following and flocking. I hope once I will understand those things laugh
Of course, it is also ported to Unity, maybe it could help you but it is in C# (I haven't tested): http://arges-systems.com/blog/2011/05/02/unitysteer-2-2-released/ Links are at the end of the article.

( My personal future plan is to extend my tile based hierarchical pathfinder with this vehicle movement system used also in Company of Heroes: http://www.gamasutra.com/view/feature/131505/toward_more_realistic_pathfinding.php?print=1 )
Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 07/26/12 12:35

Opensteer so far seems cool for me and so far its been easy to
expose the functions ,i test a little as i add functions..lately i have combined
opensteer avoidance functions with cmove colision boxes works okay.
Thanks for support you guys ,as soon as the source is up
you will find that anyone can extend/alter with ease .
Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 07/27/12 12:58

source and test script

download available ,dont expect much yet...
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 07/27/12 17:11

nice job, good start!
it's really smooth how they avoid each other during movement towards target, and the controlled character too.
good luck for the further work!
Posted By: 3run

Re: steering behaviour/avoidance(opensteer)plugin - 07/28/12 12:46

Mate, I simply love it! laugh So fast and so smooth! laugh Thank you very much!!
Posted By: Puppeteer

Re: steering behaviour/avoidance(opensteer)plugin - 08/26/12 11:59

If you set the cmoves to ignore_models you can see that your solution still has a lot of dead scenarios.
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 08/31/12 10:01

hi,
I just converted the scripts to A7, because sometimes I cannot use my A8 capable pc, only an ancient laptop... works fine with a bit different character movement and added animation.

test.c
Code:
#include <acknex.h>
#include <default.c>
#include "entmove.c"

///////////////////////
var opst_getmaxforce(ENTITY* ent);
var opst_getspeed(ENTITY* ent);
var opst_getradius(ENTITY* ent);
var opst_getmass(ENTITY* ent);
int possible_collision_neigbours(ENTITY* ent,var time);
void opst_addent(ENTITY* ent);
void opst_persuit(ENTITY* follower_ent,ENTITY* target_ent,var time,var maxprediction);
void opst_avoid_neigbours(ENTITY* ent,var time);
void opst_seekpos(ENTITY* ent,VECTOR* pos,var time);
void opst_setmaxforce(ENTITY* ent,var maxforce);
void opst_setspeed(ENTITY* ent,var speed);
void opst_setradius(ENTITY* ent,var radius);
void opst_setmass(ENTITY* ent,var mass);
void opst_setmaxspeed(ENTITY* ent,var speed);
void opst_brake(ENTITY* ent,var rate,var time);
VECTOR* opst_predictfuturepos(ENTITY* ent,var predictiontime);
VECTOR* opst_getvelocity(ENTITY* ent);
void opst_setpos(ENTITY* ent,VECTOR* pos);
////////////////////////

VECTOR* opst_getforwardvec(ENTITY* ent);
VECTOR* opst_toavoidcloseneighbors(ENTITY* ent,var minseperationdist);
VECTOR* opst_toavoidneighbors(ENTITY* ent,var mintimetocollision);
VECTOR* opst_forpursuit(ENTITY* follower_ent,ENTITY* target_ent,var predictiontime);
VECTOR* opst_forseek(ENTITY* ent,VECTOR* pos);
void opst_applysteerforce(ENTITY* ent,VECTOR* force,var time);
int opst_iszerovec(VECTOR* force);
VECTOR* opst_incforwardvec(ENTITY* ent,VECTOR* steerforce,VECTOR* otherforce);

VECTOR* opst_getfacedir(ENTITY*  ent);

var anim;
ENTITY* seeker_ent;

action seeker()
{
	while(!me){wait(1);}
	
	VECTOR* tpos;
	random_seed(0);
	
	tpos.x=random(1000);
	tpos.y=random(1000);
	tpos.z=0;
//	set(me,PASSABLE);
	
	opst_addent(me);
	opst_setmaxspeed(me,10);
	opst_setradius(me,60);
	opst_setmaxforce(me,1.5);

	VECTOR* steer;

	while(1)
	{
		
		if(vec_dist(vector(me.x,me.y,me.z),vector(tpos.x,tpos.y,me.z))<=50)
		{
			tpos.x=random(1000);
			tpos.y=random(1000);
			tpos.z=0;
		}	
	
		VECTOR* forward=opst_getforwardvec(me);

		VECTOR* avoid=opst_toavoidneighbors(me,1);	
		VECTOR* seek =opst_forseek(me,tpos);

  		if(!opst_iszerovec(avoid))
  		{
  			steer=opst_incforwardvec(me,steer,avoid);
		}
		else
		{
 			steer=opst_incforwardvec(me,steer,seek);
		}
		opst_applysteerforce(me,steer,time_step);
		
   //	opst_seekpos(me,tpos,1*time_step);
		
		ent_faceto(my,opst_getfacedir(me),99999*time_step);
		
		c_move(me,vector(opst_getspeed(me)*time_step,0,0),NULL,GLIDE);
		opst_setpos(me,vector(me.x,me.y,me.z));
		
		draw_point3d(opst_getfacedir(me),COLOR_GREEN,100,5);
		
		draw_point3d(tpos,COLOR_RED,100,5);
		
		draw_point3d(opst_predictfuturepos(me,5),COLOR_WHITE,100,5);
		
		my.skill1+=opst_getspeed(me)*time_step;
		my.skill1%= 100;
		ent_animate(me,"walk",my.skill1, ANM_CYCLE);
		wait(1);
	}
}

action persuier()
{
	while(!me){wait(1);}
//	set(me,PASSABLE);
	
	opst_addent(me);
	opst_setmaxspeed(me,10);
	opst_setradius(me,60);
	opst_setmaxforce(me,1.5);
	
	VECTOR* steer;
	while(1)
	{
		if(vec_dist(vector(me.x,me.y,me.z),vector(seeker_ent.x,seeker_ent.y,me.z))<=50)
		{
			opst_brake(me,1,1*time_step);
		}	
		draw_point3d(opst_predictfuturepos(seeker_ent,20),vector(0,255,255),100,5);

		VECTOR* forward=opst_getforwardvec(me);

		VECTOR* avoid=opst_toavoidneighbors(me,1);	
		//VECTOR* avoid=opst_toavoidneighbors(me,5);
		//VECTOR* pursuit=opst_forseek(me,opst_predictfuturepos(seeker_ent,20));
		//VECTOR* pursuit=opst_forpursuit(me,seeker_ent,20);
		VECTOR* pursuit=opst_forpursuit(me,seeker_ent,1);

  		if(!opst_iszerovec(avoid))
  		{
  			steer=opst_incforwardvec(me,steer,avoid);
		}
		else
		{
 			steer=opst_incforwardvec(me,steer,pursuit);
		}
		opst_applysteerforce(me,steer,time_step);
		
		ent_faceto(my,opst_getfacedir(me),99999*time_step);
		c_move(me,vector(opst_getspeed(me)*time_step,0,0),NULL,GLIDE);
		
		opst_setpos(me,vector(me.x,me.y,me.z));

		draw_point3d(opst_getfacedir(me),COLOR_GREEN,100,5);
		
		draw_point3d(opst_predictfuturepos(me,5),COLOR_WHITE,100,5);

		my.skill1+=opst_getspeed(me)*time_step;
		my.skill1%= 100;
		ent_animate(me,"walk",my.skill1, ANM_CYCLE);
		wait(1);
	}
}

action spectator()
{
	while(!me){wait(1);}
//	set(me,PASSABLE);
	
	opst_addent(me);
	opst_setmaxspeed(me,10);
	opst_setradius(me,60);
//	opst_setmaxforce(me,2);
	
	while(1)
	{
		VECTOR mypos;
//		ent_rotate(me,-mouse_force.x*100*time_step,0,0);	// A7 remove		
//		camera.tilt=clamp(camera.tilt,-45,45);
//		camera.tilt+=mouse_force.y*30*time_step;
		
		if(key_w)c_move(me,vector(10*time_step,0,0),NULL,GLIDE);
		if(key_s)c_move(me,vector(-10*time_step,0,0),NULL,GLIDE);
//		if(key_a)c_move(me,vector(0,10*time_step,0),NULL,GLIDE);
//		if(key_d)c_move(me,vector(0,-10*time_step,0),NULL,GLIDE);
		if(key_a)c_rotate(me,vector(10*time_step,0,0),GLIDE);
		if(key_d)c_rotate(me,vector(-10*time_step,0,0),GLIDE);
		
	//	camera.pan=my.pan;
	//	camera.x=me.x;
	//	camera.y=me.y;
	//	camera.z=me.z+30;

		opst_setpos(me,vector(me.x,me.y,me.z));
		
		my.skill1+=5*time_step;
		my.skill1%= 100;
		if(key_any) {ent_animate(me,"walk",my.skill1, ANM_CYCLE);}
		else {ent_animate(me,"idle",my.skill1, ANM_CYCLE);}
		
		wait(1);
	}
}

void main()
{
	level_load(NULL);
	wait(4) ;
	seeker_ent=ent_create("blueguard.mdl",nullvector,seeker);
	vec_set(sky_color,COLOR_BLACK);
	
	int n;
	for(n=0;n<10;n++)
	ent_create("redguard.mdl",vector(100+n*80,0,0),persuier);
	
	ent_create("blueguard.mdl",vector(0,-100,0),spectator);

	vec_set(camera.x,vector(1023,-590,1067));
 	camera.arc=90;
 	camera.tilt=-53;
 	camera.pan=135;
 	camera.clip_near=1;

// fps_min=60;
// fps_max=60;

	//def_move();
	//def_move();
	def_debug();

}


entmove.c for A7
Code:
//////////////////////////////////////////////////////////////
// entmove.c - entity position and angle manipulation functions
// (c) oP group - jcl 2010 - modified by sivan 2012 for A7
//////////////////////////////////////////////////////////////
#ifndef entmove_c
#define entmove_c

// rotate an entity relative to its own orientation 
function ent_rotate(ENTITY* ent,speed_pan,speed_tilt,speed_roll)
{
	me = ent;
	proc_kill(5);
	
	while(speed_pan || speed_tilt || speed_roll) {
		ang_rotate(ent.pan,vector(
			speed_pan*time_step,
			speed_tilt*time_step,
			speed_roll*time_step));
		wait(1);
	}
}

// rotate an entity according to its skill1,2,3 values
action ent_rotor()
{
	if (!my.skill1 && !my.skill2 && !my.skill3)
		ent_rotate(me,2,0,0); // no skills -> just pan
	else
		ent_rotate(me,my.skill1,my.skill2,my.skill3);
}


//////////////////////////////////////////////////////////////////
// turn towards an absolute target angle with given angular speed
// use wait_for_my(ent_turnto) for determining when the angle is reached
function ent_turnto(ENTITY* ent,ANGLE* to,var aspeed)
{
	me = ent;
	proc_kill(5);
	
// store the "to" angle for the wait loop - it could be a temporary vector!	
	ANGLE atarget;
	vec_set(atarget,to);
	 
	while(aspeed) {
// calculate the difference between the current and the target angle	
		ANGLE adiff;
		ang_diff(adiff,atarget,ent.pan);
// check if we're already there
		if(vec_length(adiff) <= aspeed*time_step) {
			vec_set(ent.pan,atarget);
			return;
		}
// scale the difference angle by the angular speed, 
// and add it to the entity angle
		vec_normalize(adiff,aspeed*time_step);
		ang_add(ent.pan,adiff);
		wait(1);
	}
}

// turn towards a target position with given speed
// use wait_for_my(ent_turnto) for determining when the angle is reached
function ent_faceto(ENTITY* ent,VECTOR* pos,var aspeed)
{
	if(!ent || !pos) return;
	VECTOR* diff = vec_diff(NULL,pos,ent.x);
	vec_to_angle(diff,diff);
	ent_turnto(ent,diff,aspeed);
}


//////////////////////////////////////////////////////////////////
// move to an absolute position with given speed
// use wait_for_my(ent_moveto) for determining when the position is reached
function ent_moveto(ENTITY* ent,VECTOR* pos,var speed)
{
	me = ent;
	proc_kill(5);
	
// store the "pos" vector for the wait loop - it could be a temporary vector!	
	VECTOR vpos;
	vec_set(vpos,pos);

	while(speed) {
// calculate the difference between the current and the target position	
		VECTOR diff;
		vec_diff(diff,vpos,ent.x);
// check if we're already there
		if(vec_length(diff) <= speed*time_step) {
			vec_set(ent.x,vpos);
			return;
		}
// scale the difference vector by the speed, 
// and add it to the entity position
		vec_normalize(diff,speed*time_step);
		vec_add(ent.x,diff);
		wait(1);
	}
}

// move to a relative position with given speed
// use wait_for_my(ent_moveto) for determining when the position is reached
function ent_moveby(ENTITY* ent,VECTOR* pos,var speed)
{
	if(!ent || !pos) return;
	ent_moveto(ent,vec_add(pos,my.x),speed);
}


//////////////////////////////////////////////////////////////////
// place an entity on the floor below
function ent_placefloor(ENTITY* ent)
{
// get the entity's feet distance	
	VECTOR vMin;
	vec_for_min(vMin,ent);
	vMin.z *= ent.scale_z;
// find the ground below the entity origin	
	ENTITY* old=me; me=ent;
	c_trace(
		vector(ent.x,ent.y,ent.z+10),
		vector(ent.x,ent.y,ent.z-1000),
		IGNORE_ME | IGNORE_PASSABLE | IGNORE_SPRITES);
	me=old;	
// place the lowest part (vMin.z) on the ground (hit.z)
	if(HIT_TARGET) ent.z = hit.z-vMin.z;
}

// let an entity move along a closed path with given speed
function ent_movepath(ENTITY* ent,char* pathname,var speed,var mode)
{
	me = ent;
	proc_kill(5);
	
	var vLastPos[3],vDir[3];
	vec_set(vLastPos,ent.x);
	var dist = 0;
	if (pathname) path_set(ent,pathname);
	while(speed) 
	{
// place the entity along the path
		path_spline(ent,ent.x,dist);
		dist += speed*time_step;
// adjust the entity to the floor
		if(mode&1)
			ent_placefloor(ent);
// let the entity look ahead in movement direction
		if(mode&2) {
			vec_diff(vDir,ent.x,vLastPos);
			vec_to_angle(ent.pan,vDir);
			vec_set(vLastPos,ent.x);
		}
		wait(1);
	}
}

#endif

Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 09/13/12 16:14

Hi guys .. A little busy and havent worked on my projects
but to reply this is not a complete solution there are other
functions to be added like steer to evade etc etc and
the demo was simply my testbed for functions i have
done ...feel free to alter or use my source this plugin
and navmesh plugin ..when i find time i shall add and
upload again...sivan havent tested or checked your
conversion sincei dont have a7 but im sure its good
and many thanks to you and 3run and others for
all your help and support you guys rock ..cherrs
Posted By: Random

Re: steering behaviour/avoidance(opensteer)plugin - 09/13/12 20:01

Haha. Looks a littlebit like the one I made; Link

But I have to say that yours is the better one (and a plugin) ^^
Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 06/08/13 19:03

Anyone intrested to see further development for this old project of mine ?
Posted By: 3run

Re: steering behaviour/avoidance(opensteer)plugin - 06/09/13 19:34

Wjbender@ hi there mate, I'm interested! laugh
Posted By: Random

Re: steering behaviour/avoidance(opensteer)plugin - 06/09/13 20:14

I would also be very interested ^^
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 06/10/13 07:38

I'm also interested in it - but was unable to set up your source in VC++2010 frown

as I read about it, opensteer is rather a presentation of a theory, or a simulation, made by the guy who found out the whole system, than a directly usable plugin for games, because the character quantity is max a few tens (okay, in many cases it is enough), and obstacle avoidance is very basic, and costs a lot of preformance (I just saw the demo with a few circle obstacles, no complex environments). but it has a couple of modified versions, which are probably used in games, I'll try to find some open source ones.

another cool library is the RVO2 http://gamma.cs.unc.edu/RVO2/ ,which is based on ORCA http://gamma.cs.unc.edu/ORCA/ . it deals with crowd simulation, producing collision and oscillation free movement without communication among agents. it could be used to manage NPC crowds in games e.g. in a city environment. used in Warhammer 40k. open source but not free to use in commercial games.
Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 06/10/13 10:15

Hi sivan , yes i have rvo2 2d and rvo 3d 2 but if i dive inro rvo i would have to request permission from the university of north carolina , perhaps i might just get it who knows...

I also have jsbsim for flight dynamics simulation but okay thats a project im net getting into now..
The main reason i went for opensteer first is its license ..

Yes they say that they cant guarantee it being functionaly stable but i have not seen any demo that proves it not to be good enough for small uses..although yes i understand what you are getting at.
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 06/10/13 14:04

yes, RVO2 licensing is a problem.
opensteer is basically cool, I just don't know how it can be practically adjusted to a game environment, or suited to which game type in its current form. probably okay for open levels with a few trees and impassable blocks, but maybe there are some 3rd party extensions available. and definitely a good way to learn the flocking rules.
Posted By: Wjbender

Re: steering behaviour/avoidance(opensteer)plugin - 06/10/13 14:28

Well yes it is oriented towards agent to agent avoidance and not enviroment avoidance although the circular objects could be used for rts buildings but in general i would say agent to agent restrained to a path , i saw a demo that used bitmaps for a vehicle to move on a track with obsticles .. I am not sure it would be a very usefull plugin more than agent to agent and perhaps vehicles on a terrain..
Without polygonal collision shapes it could be a waste of my time
Posted By: sivan

Re: steering behaviour/avoidance(opensteer)plugin - 06/10/13 15:05

comparing to recast/detour, it is surely much less reliable to deal with laugh
Posted By: bpc31

Re: steering behaviour/avoidance(opensteer)plugin - 06/20/13 03:07

I would love to see a mod of this to be used for racing game ui! I want cars to flock towards a single node then have them continue to next node as they pass the first. In other words following a single path but they're all randomly offset from the path or node. That would be cool! Anyone done anything like this?
© 2024 lite-C Forums