Skip to main content
GameDev.net gamedev.net
🔒 Locked

3D Steering Behavior

Started by HanzDog Oct 21, 2009 at 11:30 PM 12 replies 6.3k views
Original Post
HanzDog
HanzDog
How do you like it?
Johnkol
Johnkol

That is superb stuff!! That looks so optimized! I am trying to do something similar. I am implementing the flock behavior based off Craig Reynold's paper. I was able to achieve it in 2d, however in 3d space I have a few bugs. Can you tell me how you are calculating the visibility of each of the boids in 3d space? Is it using a solid angle? Any help would be greatly appreciated! Thank you!
alexjc
alexjc
Indeed, looks very cool!

What's the context of the video?
Join us in Vienna for the nucl.ai Conference 2015, on July 20-22... Don't miss it!
swiftcoder
swiftcoder
Very nice! Would love to know what the eventual goal is?
Tristam MacDonald. Ex-BigTech Software Engineer. Future farmer. [https://trist.am]
HanzDog
HanzDog
Quote:
Original post by Johnkol

That is superb stuff!! That looks so optimized! I am trying to do something similar. I am implementing the flock behavior based off Craig Reynold's paper. I was able to achieve it in 2d, however in 3d space I have a few bugs. Can you tell me how you are calculating the visibility of each of the boids in 3d space? Is it using a solid angle? Any help would be greatly appreciated! Thank you!


I used a 3D Tile map. Each Tiles has some information about boids (kind of Boid's ID, Tile ID etc..). World is consist of this 3D Tile Map. So If You can know Boid's position, You can know Tile ID that can be matched boid's Pos.

For Example::

int nNewX = (nX + (int)m_fHalfWidthLength) / (int)m_fWidthLength;
int nNewY = (nY + (int)m_fHalfVertLength) / (int)m_fVertLength;
int nNewZ = (nZ + (int)m_fHalfHeightLength) / (int)m_fHeightLength;

// nX -> Pos X, nY -> Pos Y, nZ -> Pos Z
// m_fHalfWidthLength -> World Length Harf size
// m_fWidthLength -> world Length

int nnn = (nNewZ * m_nWidthNum) + (nNewY * m_nWidthNum * m_nHeightNum )
+ nNewX;


"nnn" is the Id of Tile Array.

This way alawys used in Old 2D World Game. And I just expand to 3D World.


Can you understand? English is not my mother tongue.. so It is hard to explain
using english for me.

sorry sorry.
Emergent
Emergent
@HanzDog: Nice! I'm impressed by the sheer number of agents. This is running on the CPU (not GPU)?

@Johnkol: I obviously can't say how precisely HanzDog did it, but I can tell you how I would.

1. Visibility: If player i has position pi and player j has position pj, then player j is visible from player i iff

dot(pj-pi, vi) > ||pj-pi|| ||vi|| cos(thetamax)
and
||pj-pi|| < Rmax

where vi is the heading vector for the ith agent and thetamax, Rmax are the angle and radius of the visibility cone.

2. Turning

2a. Method 1:

If h is the desired heading angle, v is the current velocity, and defining

d = h - v
u = d - dot(d,v)/dot(v,v) v

then the differential equation

dv/dt = f(||u||) u

describes the vector v turning continuously to face h, where f is any positive function. For instance,

f(||u||) = 1

describes proportional control (steer at a rate proportional to how far from the desired heading you are), and,

f(||u||) = w/||u||

for some positive constant 'w' describes bang-bang control (steer at a constant rate 'w').

I would simulate this ODE with a simple predictor-corrector scheme. E.g., use basic Euler integration, but occasionally renormalize 'v' so it has the correct length.

2b. The axis of rotation is given by the cross product of h and v. Rotate v by an appropriate amount about this axis. This is basically the exact version of 2a.
Johnkol
Johnkol

Thanks a bunch HanzDog and Emergent!! Currently I have multiple flocks having different properties working in 3d space. For the time being I am using a simple distance check (spherical area) for determining the neighbors. Will be trying to implement the different visibilities for the AI characters today. I will update my progress. Once again thank you for the help.
kirkd
kirkd
Very nice! I notice at around 0:56 to 0:57 that the boids form a very granular or nodular formation. One of the larger clumps in the middle of the screen breaks apart into about 4 to 6 smaller clusters. Any idea what is going on there?

Impressive demo.

-Kirk

Johnkol
Johnkol
@Emergent

Thanks a lot!! I got the visibility cone to work! Awesome stuff! This is exactly what I was looking for. Thank you very much. The flock behavior is almost there. Tweaking the values now.
HanzDog
HanzDog
Thanks a lot Everyone.

Lately, I'm looking for job. But It is little Hard..

Because I have only console game career and almost game company in my country

prefers online game developer. Ah~! So sad!

Anyway, I have a plan to upload my code. If I get a job, I must open my dumb code.


//Johnkol
I recommend "Game Programming AI by example". Maybe It's very useful to you. ^^
litebox
litebox

@HanzDog: Nice! I'm impressed by the sheer number of agents. This is running on the CPU (not GPU)?

@Johnkol: I obviously can't say how precisely HanzDog did it, but I can tell you how I would.

1. Visibility: If player i has position pi and player j has position pj, then player j is visible from player i iff

dot(pj-pi, vi) > ||pj-pi|| ||vi|| cos(thetamax)
and
||pj-pi|| < Rmax

where vi is the heading vector for the ith agent and thetamax, Rmax are the angle and radius of the visibility cone.

2. Turning

2a. Method 1:

If h is the desired heading angle, v is the current velocity, and defining

d = h - v
u = d - dot(d,v)/dot(v,v) v

then the differential equation

dv/dt = f(||u||) u

describes the vector v turning continuously to face h, where f is any positive function. For instance,

f(||u||) = 1

describes proportional control (steer at a rate proportional to how far from the desired heading you are), and,

f(||u||) = w/||u||

for some positive constant 'w' describes bang-bang control (steer at a constant rate 'w').

I would simulate this ODE with a simple predictor-corrector scheme. E.g., use basic Euler integration, but occasionally renormalize 'v' so it has the correct length.

2b. The axis of rotation is given by the cross product of h and v. Rotate v by an appropriate amount about this axis. This is basically the exact version of 2a.



Hi, I do steering behavior in 3D too, and I only have one problem: I can't calculate right rotations for my flying objects.
If I understand from your post, I need find cross product via old velocity-vector (v) and new velocity-vector (h), and use it for rotation quaternion?
[attachment=1847:flock.jpg]
Emergent
Emergent

Hi, I do steering behavior in 3D too, and I only have one problem: I can't calculate right rotations for my flying objects.
If I understand from your post, I need find cross product via old velocity-vector (v) and new velocity-vector (h), and use it for rotation quaternion?
[attachment=1847:flock.jpg]


The vectors 'v' and 'h' aren't really "new" and "old" velocities; instead, 'v' is the velocity you actually have, 'h' is the velocity you want to get to eventually, and the controller I described will make 'v' gradually move towards 'h.' In the case of the proportional controller, this only happens asymptotically.

Also, in the model I gave, I was representing each agent as a particle with a velocity, but it appears from your picture that what you probably want is a rigid body model (since your agents are not longitudinally symmetric), which is just a tiny bit more involved. I might have time later to post one.
litebox
litebox
I see... I realize bird's flock, now they have position and velocity (velocity [font=Arial, sans-serif][size=2]composed of all steering behaviors that influences on one unit[/font]). So I only add newly calculated velocity to current position. I calculate direction of unit like this:

float angle = atan2(velocity.y, velocity.x) * RAD2DEG;


This gives me only direction in XY-plane. I need add another one - rotation about [color=#1C2837][size=2]longitudinally - when bird is turning, it must rotate for realistic turn. And I don't know what I can use for it calculation.
I might have time later to post one.


Thanks, it would be great.

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.