Hey guys, I'd like to create a swarm of rigidbodies around another body. What would be a nice way to achieve this?
Now I have got something like
for(b : bodies in the swarm){
b->applyCentralImpulse(force/(distance*distance));
}
Which creates an okay pulling motion, but it just crashes through the swarm.. they don't stick, they just swing back and forth and it's very unstable. I'm not sure how to solve this. Any suggestions?
Create a swarm around an object
-
- Posts: 4
- Joined: Sat Mar 16, 2013 10:43 pm
Re: Create a swarm around an object
Does it have to be an interactive swarm or just a visual ? If it is just a visual then I can think of a number of ways for the effect. Perhaps it you give a description of what the end result should be close to we can work it out.
-
- Posts: 25
- Joined: Sat Dec 29, 2012 7:20 pm
Re: Create a swarm around an object
The effect I'd like is pretty much this: http://youtu.be/pt_n_V_Yl9Y?t=1m28s . I failed to do this so far because I can't figure out how to get to slow down.
Problem:
Begin:
After a bit of attraction:
And some later:
Rinse, repeat . I want them to cluster at the attractor, not blow past it. And this is when the object is on a collision course with it. If it's not, it'll just fly right over.
Problem:
Begin:
Code: Select all
-------------------[attractor]-------------------[object]
Code: Select all
-------------------[attractor]-----[object]--------------
Code: Select all
[object]------------[attractor]---------------------------
-
- Posts: 4
- Joined: Sat Mar 16, 2013 10:43 pm
Re: Create a swarm around an object
That video has comments that state how they did it....
So, there you go.We use a kinematic object, with no contact response to detect which objects reside inside the blast radius.
In the internal physics tick callback we check whether one of the affected bodies is the kinematic object. If it is, we apply an impulse to it based on the distance to the center. In case of the explosions the impulse is applied to the object relative to the contactpoints (using ApplyImpulse). That didn't work very well for the attractors (instable), so we applied the impulse to the center of the object (using ApplyCentralImpulse).
-
- Posts: 25
- Joined: Sat Dec 29, 2012 7:20 pm
Re: Create a swarm around an object
I'm doing that now, but I can't get the swinging motion to dissapear.
Here's some sample code of what I'm doing now.
I understand why the swining motion is there, I'm creating it, but I'm not sure what a nice way is to stop the swinging from happening. (The swinging I described in my first post, if it's not clear I'll gladly clarify)
Here's some sample code of what I'm doing now.
Code: Select all
void Planet::update(float const dt, Player& player, motor::Scene& scene, btDynamicsWorld& physics){
for(auto& city : cities){
for(auto& h : city->get_houses()){
if(h->is_being_beamed){
auto const player_position = player.get_model()->get_position();
// auto const player_physical_body = player->get_model()->get_physical_body();
auto const house_position = h->get_position();
auto const house_physical_body = h->get_physical_body();
float const distance = length(player_position - house_position);
auto const unit_vector = normalized(player_position - house_position);
// ! Quadratic falloff attraction
auto const gravitational_attract = [&](float const power) -> moggle::vector3<float> {
auto const force = unit_vector * (power/(distance*distance)) * dt;
return force.slice<0, 3>();
};
// ! inverse-quadratic falloff (i.e. pulls harder when things are further away)
auto const inverse_gravitational_attract = [&](float const power){
auto const force = unit_vector * (power*distance) * dt;
return force.slice<0, 3>();
};
auto const attract = inverse_gravitational_attract;
// gravitational_attract can use a power of 10000000000
// float const power = 10000000000;
// inverse one can use a far lower power
float const power = 100;
float const ideal_distance = 15.0f;
if(distance > ideal_distance){
house_physical_body->applyCentralImpulse(convert<btVector3>(attract(power)));
}
}
}
}
}
-
- Posts: 72
- Joined: Wed Feb 24, 2010 9:49 pm
Re: Create a swarm around an object
Perhaps you can apply linear damping to the bodies as they get near to where they need to stick.
Of course you can tweak the damping coefficient and how exactly you apply it, but you get the idea.
Code: Select all
if(distance > ideal_distance){
house_physical_body->applyCentralImpulse(convert<btVector3>(attract(power)));
house_physical_body->setDamping(0, 0);
} else {
house_physical_body->setDamping(0.5f, 0);
}
-
- Posts: 25
- Joined: Sat Dec 29, 2012 7:20 pm
Re: Create a swarm around an object
Ah yes thanks! That was what I was looking for. How stupid. Thanks man!