# Very fast Schools of fish

This topic is 5052 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

I've been playing metroid prime recently (i only got the game a few days ago). And i was looking at that pond, where you first get to the tallon overworld, you know, right by the waterfall. I was looking at the fish, and how they move. I was wondering if there was a really fast way of generating schools of fish (or paranas, of birds, or anything), which would allow you to make them, without burning the CPU budget. What i was thinking about, is we first do a bit of calculation (maybe once a second) We find out how large the school is We also find the closest objects. (ie. those which can be collided with, before the next update.) We also find out a cource which will take the school away from those objects, and closer to the goal (whatever the goal is). Once we've done that, We go, and for each fish, we calculate what direction they should go in. To do this we do the followikng things. We get a random byte. We take the msb of that byte to determine which direction it should go in (right or left) We get how powerful that direction is based on a 7 bit precomputed (hardcoded) table. In that table, most of the entries only hav einsignificant changes (ie. +- 1 degree), but a few have ubrupt cahanges (ie. table[128] could have + 90 degrees). Also the general speed of each fish increases and decreases, but not by much. (a couple of bits worth maybe). We also generate a force in the direction of the middle of the school. its amplitude gets greater as it gets further away form the center. We also generate a force, in the direction of the path. Its ampliturte gets greater, as the fish (average, as a school) gets further away. We then mix those, along with the random movement, in order to get the fishes new movememnt vector. Now for the path, we make a superfish entity, which is a fsm. Its states are basically "FindEat" "Findfood" "Curious" "Sleep" and "Run" "Findeat" occures when the school (at the furthest point) is close enough to something edible (a dead fish, algea, anything). Findfood basically gets the fish to randomly move, until it gets close enough to food, until it just moves in. "Curious" Basically circles around one object, that they havent seen before (like the player, an eniemy, or basically anything new,) "Sleep" Basically has no path. And the general speed of everything decreases to a crawl. "Run" Basically plots a path away from an object, and the speed increases, away from the object. As the fsm changes states, it changes the coefficients, which makes each force more or less powerful. depending on state. I've been thinking of two different things. either with the fsm. or just changing peramiters liniarly. Now the fsm, would basically be doing a few different things. The entire school has a tiredness index. It also has a fear index and a hunger index. Tiredness and hunger go up all the time. Slowly. Fear goes up when something happens suddenly. And if happens quickly. Especially if its asleep at the time. When the fi goes up above a certain threshold, it automatically switches to the run state. When its running, it doesn't change states, until its fi is low enough. (below a second, much lower threshhold). The fi decays slowly. When the tiredness index goes above a threshhold, then it goes to sleep. When it gets hungry enough, it goes to find something to eat, and as soon as it sees food, it eats. The other intepritation, is that it uses a series of equasions, to change a set of coefficients which change how the flock reacts. It'd be ... different to try, and it'd still have a few if's. But i'd be a nice little fuzzy logic implementation. Any thoughts? Implementations? From, Nice coder [Edited by - Nice Coder on January 6, 2005 5:04:11 AM]

##### Share on other sites
hey,
not quite the same as your describing but you can try this:
a bit of source included.
fish swim around and eat food.

look up 'boids' in google, i just added 'attact' vectors for mates,food and preditors.

so yeah, the random byte idea is probably not the best way to go, even though it may be faster.

##### Share on other sites
I'm looking into boids now, thanks.

the point of it, is to get a really fast algorithm, so you could have swarms of millions of carnivorous fish. Or wasps, or anything really.

From,
Nice coder

##### Share on other sites
I;m getting errors with your boids implementation.

I either get a "Cannot start graphics engine", in directX mode, or a null pointer error in opengl mode.

This is after the config screen.

From,
Nice coder

##### Share on other sites
----------------LOG BEGIN------------------E:ERROR  [C:\dev\engine\dxengine\dxEngine.cpp:95] (0xde0710:Unkown)DXEngine::WinInit-> Could not create device:D3DERR_INVALIDCALL----------------LOG BEGIN------------------E:ERROR  [C:\dev\engine\dxengine\dxEngine.cpp:95] (0xde0710:Unkown)DXEngine::WinInit-> Could not create device:D3DERR_INVALIDCALL----------------LOG BEGIN------------------E:ERROR  [C:\dev\engine\oglengine\oglEngine.cpp:101] (0xde0710:OpenGLEngine)OpenGLEngine::WinInit-> The Requested Fullscreen Mode Is Not Supported By Your Video Card----------------LOG BEGIN------------------WARNING [C:\dev\engine\oglengine\oglEngine.cpp:197] OpenGLEngine::WinInit->GL_ARB_multitexture is unsupported!WARNING [C:\dev\engine\oglengine\oglEngine.cpp:218] OpenGLEngine::WinInit->GL_ARB_vertex_program unsupported!loaded 3ds databasenames in mesh list:list[0]=UnitCubemesh #03ds mesh name:UnitCubenVertices: 8nTextVerts:0nFaces:12WARNING [C:\dev\engine\oglengine\oglModel.cpp:153] OpenGLModel::Load3DS->#texture coordinates != #verticesloaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10list[10]=object11mesh #03ds mesh name:objectnVertices: 2128nTextVerts:2128nFaces:4214mesh #13ds mesh name:object2nVertices: 154nTextVerts:154nFaces:192mesh #23ds mesh name:object3nVertices: 154nTextVerts:154nFaces:192mesh #33ds mesh name:object4nVertices: 208nTextVerts:208nFaces:264mesh #43ds mesh name:object5nVertices: 208nTextVerts:208nFaces:264mesh #53ds mesh name:object6nVertices: 118nTextVerts:118nFaces:144mesh #63ds mesh name:object7nVertices: 118nTextVerts:118nFaces:144mesh #73ds mesh name:object8nVertices: 316nTextVerts:316nFaces:408mesh #83ds mesh name:object9nVertices: 442nTextVerts:442nFaces:576mesh #93ds mesh name:object10nVertices: 41nTextVerts:41nFaces:64mesh #103ds mesh name:object11nVertices: 41nTextVerts:41nFaces:64loaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10mesh #03ds mesh name:objectnVertices: 2192nTextVerts:2192nFaces:4220mesh #13ds mesh name:object2nVertices: 586nTextVerts:586nFaces:768mesh #23ds mesh name:object3nVertices: 154nTextVerts:154nFaces:192mesh #33ds mesh name:object4nVertices: 154nTextVerts:154nFaces:192mesh #43ds mesh name:object5nVertices: 122nTextVerts:122nFaces:160mesh #53ds mesh name:object6nVertices: 122nTextVerts:122nFaces:160mesh #63ds mesh name:object7nVertices: 550nTextVerts:550nFaces:720mesh #73ds mesh name:object8nVertices: 352nTextVerts:352nFaces:456mesh #83ds mesh name:object9nVertices: 41nTextVerts:41nFaces:64mesh #93ds mesh name:object10nVertices: 41nTextVerts:41nFaces:64loaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10list[10]=object11list[11]=object12list[12]=object13mesh #03ds mesh name:objectnVertices: 2099nTextVerts:2099nFaces:4176mesh #13ds mesh name:object2nVertices: 45nTextVerts:45nFaces:64mesh #23ds mesh name:object3nVertices: 45nTextVerts:45nFaces:64mesh #33ds mesh name:object4nVertices: 41nTextVerts:41nFaces:64mesh #43ds mesh name:object5nVertices: 41nTextVerts:41nFaces:64mesh #53ds mesh name:object6nVertices: 70nTextVerts:70nFaces:128mesh #63ds mesh name:object7nVertices: 70nTextVerts:70nFaces:128mesh #73ds mesh name:object8nVertices: 89nTextVerts:89nFaces:128mesh #83ds mesh name:object9nVertices: 89nTextVerts:89nFaces:128mesh #93ds mesh name:object10nVertices: 45nTextVerts:45nFaces:64mesh #103ds mesh name:object11nVertices: 45nTextVerts:45nFaces:64mesh #113ds mesh name:object12nVertices: 45nTextVerts:45nFaces:64mesh #123ds mesh name:object13nVertices: 45nTextVerts:45nFaces:64loaded 3ds databasenames in mesh list:list[0]=Sphere01mesh #03ds mesh name:Sphere01nVertices: 482nTextVerts:0nFaces:960WARNING [C:\dev\engine\oglengine\oglModel.cpp:153] OpenGLModel::Load3DS->#texture coordinates != #vertices----------------LOG BEGIN------------------WARNING [C:\dev\engine\oglengine\oglEngine.cpp:197] OpenGLEngine::WinInit->GL_ARB_multitexture is unsupported!WARNING [C:\dev\engine\oglengine\oglEngine.cpp:218] OpenGLEngine::WinInit->GL_ARB_vertex_program unsupported!loaded 3ds databasenames in mesh list:list[0]=UnitCubemesh #03ds mesh name:UnitCubenVertices: 8nTextVerts:0nFaces:12WARNING [C:\dev\engine\oglengine\oglModel.cpp:153] OpenGLModel::Load3DS->#texture coordinates != #verticesloaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10list[10]=object11mesh #03ds mesh name:objectnVertices: 2128nTextVerts:2128nFaces:4214mesh #13ds mesh name:object2nVertices: 154nTextVerts:154nFaces:192mesh #23ds mesh name:object3nVertices: 154nTextVerts:154nFaces:192mesh #33ds mesh name:object4nVertices: 208nTextVerts:208nFaces:264mesh #43ds mesh name:object5nVertices: 208nTextVerts:208nFaces:264mesh #53ds mesh name:object6nVertices: 118nTextVerts:118nFaces:144mesh #63ds mesh name:object7nVertices: 118nTextVerts:118nFaces:144mesh #73ds mesh name:object8nVertices: 316nTextVerts:316nFaces:408mesh #83ds mesh name:object9nVertices: 442nTextVerts:442nFaces:576mesh #93ds mesh name:object10nVertices: 41nTextVerts:41nFaces:64mesh #103ds mesh name:object11nVertices: 41nTextVerts:41nFaces:64loaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10mesh #03ds mesh name:objectnVertices: 2192nTextVerts:2192nFaces:4220mesh #13ds mesh name:object2nVertices: 586nTextVerts:586nFaces:768mesh #23ds mesh name:object3nVertices: 154nTextVerts:154nFaces:192mesh #33ds mesh name:object4nVertices: 154nTextVerts:154nFaces:192mesh #43ds mesh name:object5nVertices: 122nTextVerts:122nFaces:160mesh #53ds mesh name:object6nVertices: 122nTextVerts:122nFaces:160mesh #63ds mesh name:object7nVertices: 550nTextVerts:550nFaces:720mesh #73ds mesh name:object8nVertices: 352nTextVerts:352nFaces:456mesh #83ds mesh name:object9nVertices: 41nTextVerts:41nFaces:64mesh #93ds mesh name:object10nVertices: 41nTextVerts:41nFaces:64loaded 3ds databasenames in mesh list:list[0]=objectlist[1]=object2list[2]=object3list[3]=object4list[4]=object5list[5]=object6list[6]=object7list[7]=object8list[8]=object9list[9]=object10list[10]=object11list[11]=object12list[12]=object13mesh #03ds mesh name:objectnVertices: 2099nTextVerts:2099nFaces:4176mesh #13ds mesh name:object2nVertices: 45nTextVerts:45nFaces:64mesh #23ds mesh name:object3nVertices: 45nTextVerts:45nFaces:64mesh #33ds mesh name:object4nVertices: 41nTextVerts:41nFaces:64mesh #43ds mesh name:object5nVertices: 41nTextVerts:41nFaces:64mesh #53ds mesh name:object6nVertices: 70nTextVerts:70nFaces:128mesh #63ds mesh name:object7nVertices: 70nTextVerts:70nFaces:128mesh #73ds mesh name:object8nVertices: 89nTextVerts:89nFaces:128mesh #83ds mesh name:object9nVertices: 89nTextVerts:89nFaces:128mesh #93ds mesh name:object10nVertices: 45nTextVerts:45nFaces:64mesh #103ds mesh name:object11nVertices: 45nTextVerts:45nFaces:64mesh #113ds mesh name:object12nVertices: 45nTextVerts:45nFaces:64mesh #123ds mesh name:object13nVertices: 45nTextVerts:45nFaces:64loaded 3ds databasenames in mesh list:list[0]=Sphere01mesh #03ds mesh name:Sphere01nVertices: 482nTextVerts:0nFaces:960WARNING [C:\dev\engine\oglengine\oglModel.cpp:153] OpenGLModel::Load3DS->#texture coordinates != #vertices

This is Log.txt

From, Nice coder

##### Share on other sites
Ah, I think thats because your gfx card doesn't support multi-texturing? Perhaps?
Or I just suck.
But you could take a look at the source code and get some help anyway hopefully :)

##### Share on other sites
Would it be possible to do the swarm calculations on the GPU? Each fish could be represented as a vertex, and then the vertex program could perform some perterbation on the location of the fish, causing it to appear to be animated. It would be fast as hell and wouldn't burn up any of the CPU.

##### Share on other sites
Nice idea!

I've seen vidio cards being used for prosessing before...

But the real issue, is: Would it take longer getting the data to the card, then what it would take just to process it?

From,
Nice coder

1. 1
2. 2
Rutin
19
3. 3
4. 4
5. 5

• 9
• 9
• 9
• 14
• 12
• ### Forum Statistics

• Total Topics
633298
• Total Posts
3011256
• ### Who's Online (See full list)

There are no registered users currently online

×