Jump to content

One Last Thing

JoshMK

3,713 views

In this blog I'm going to explain the evolution of the entity and physics system in Leadwerks 3.

 

In Leadwerks Engine 2, physics bodies and character controllers are both separate entity classes. If you want a model to be physically interactive, you parent it to a body entity. If you want a model to walk around with physics, you parent it to a character controller body.

 

In Leadwerks 3 I decided to give physics properties to all entities. This means all entities can use commands like GetVelocity(), AddForce(), SetMass(), etc. However, since character controllers are quite different, and they involve kind of a big chunk of code, I decided to keep the character controller as a separate entity. To make an enemy or NPC, you would create a character controller entity and then parent an animated model to that entity.

 

This was simple enough to do in the editor, but it started getting weird when we added scripts. Scripts for animation would need to be added to the child model, because the character controller would not return any animation lengths or the number of sequences. Scripts to control movement, on the other hand, would have to be attached to the parent character controller, for obvious reasons.

 

Next I tried creating a character controller script that attached to the model itself. This eliminated the extra entity in the hierarchy, and would automatically create a character controller when loaded in the engine, and parent the model to it. I didn't like that this was changing the hierarchy from what the user saw in the editor, and script accessing the character controller would still be based on some wonky assumptions.

 

Finally, I decided to just give the entity class a physicsmode member. This can be one of two values. By default, it is Entity::RigidBodyPhysics. However, you can set it to Entity::CharacterPhysics and the entity itself will act as a character controller! All the character controller functions are now available in the entity class, so you can just load a model, adjust some settings, and send him on his merry way around town:

Model* enemy = Model::Load("Models/Characters/barbarian.mdl");
enemy->SetMass(10);
enemy->SetPhysicsMode(Entity::CharacterPhysics);
enemy->GoToPoint(20,0,0);//model will walk to this position, using AI navigation

 

Pretty cool, eh? (If you wanted to add animation, you'd just go it like below.)

enemy->SetHook(Entity::DrawHook,UpdateEnemyAnimation)

void UpdateEnemyAnimation(Entity* entity)
{
   entity->SetAnimationFrame(Time::GetCurrent()/100.0);
}



32 Comments


Recommended Comments



What about a mode for having no physics body?

 

Not sure whether I like this or not because it seems restrictive... However, I can't really tell until I try it.

Share this comment


Link to comment

It's run on one main thread in the background, which can be split up into 4 or more threads. It's the same way PhysX works, asynchronous.

 

It all had to be set up specially because all the data has to be sent to the simulator, then the thread just goes off on its own, then when its done I pull all the data back from the simulator (for active bodies only).

 

This means while the renderer is running and other game stuff going on, the physics get calculated in the background. If you have enough CPU cores, physics are effectively free. biggrin.png

 

Oh, and you do have access to the cross-platform Thread and Mutex class. ;)

Share this comment


Link to comment

me->GoToPoint(happy);//LE user will be happy, with integrated navigation smile.png

 

 

Suggestion :

I would also like enemy->Explosion(Diameter, smoke, smokecolor, projections)

 

because an explosion is a "standard" feature, and most users will spend xxx time to redo something that could be done once 10x better.

 

also SendHighScore(gamename, playername, score); and GetHighScoreList(gamename) could be cool. ^^ because you host.

Share this comment


Link to comment

I don't think explosion code belongs in the engine, but a script would certainly be appropriate.

Share this comment


Link to comment
I don't think explosion code belongs in the engine, but a script would certainly be appropriate.

 

Ironically enough I think you said the same thing about pathfinding code about 3 years ago. Just saying, times change and what is "standard" changes with it. :)

Share this comment


Link to comment

What about vehicle code? And what level of control is there over waypoint navigation? Are there ease-in/out parameters or some other method to handle abrupt changes in velocity?

Share this comment


Link to comment

I was hoping explosions would be a preset in the particle engine, along with fire, smoke and maybe muzzle flashes. Will the particle engine have editable presets? It would make sense because just like character controllers and tree/character placeholders, pretty much every developer needs these, I think.

Share this comment


Link to comment
What about vehicle code?

Vehicle support will be added after the initial release.

 

I was hoping explosions would be a preset in the particle engine

We can create that easily with a particle emitter prefab. Then everyone has a reusable preset, and people can make new ones.

Share this comment


Link to comment

but a script would certainly be appropriate.

A script is a good idea,because it's allows customisation for those who want advanced specific effects. As long it's easy to call.

 

I have another question about navigation AI. Suppose you have a room with 3 doors, a small width door A, a medium width door B and a large width door C. Inside the room there are 3 cylinder controllers, a small one, a medium one, and a large controller. Of course the small controller can go thru door A,B,C, but the medium controller can only do thru B,C, and the big one only thru C. Just curious, can the navigation Ai handle this ?

Share this comment


Link to comment

I don't think explosion code belongs in the engine, but a script would certainly be appropriate.

I would think a game engine should provide as many as possible features which are needed to make games, especially if those features are used often in various games. Rarely used features can be of course left out, but still give the users a possibility to implement them themselves.

Share this comment


Link to comment

Doesn't worry me if there is no explosion code built into the Engine because I don't make explosion type games. If a Particle Emitter is part of the Engine then surely it is up to the Coder to create explosions via script or someone could sell scripted Assets of explosions.

Share this comment


Link to comment
I have another question about navigation AI. Suppose you have a room with 3 doors, a small width door A, a medium width door B and a large width door C. Inside the room there are 3 cylinder controllers, a small one, a medium one, and a large controller. Of course the small controller can go thru door A,B,C, but the medium controller can only do thru B,C, and the big one only thru C. Just curious, can the navigation Ai handle this ?

Controllers are all the same size, due to their use of the navigation mesh and crowd avoidance. If you were doing something special like a giant boss, I would skip the character controller altogether, because it's a special case and something like that would stay in the same area. It's a limitation, but everything good has constraints.

 

I would think a game engine should provide as many as possible features which are needed to make games, especially if those features are used often in various games.
A prefab or script allows that, without requiring that I hard-code a bunch of special requests into the core engine.

Share this comment


Link to comment

We can create that easily with a particle emitter prefab. Then everyone has a reusable preset, and people can make new ones.

Neat. So we could do something like this?

 

particle->load("chris_explosion4.ptl");

particle->set(ANIMATION_SPEED,5.0f);

particle->initiateatlocation(0.0f,0.0.0f,0.0f);

Share this comment


Link to comment
A prefab or script allows that, without requiring that I hard-code a bunch of special requests into the core engine.

Yes of course it should be done using existing engine commands, and not part of the core engine .lib, but it could be still bundled with the engine, for example as a seperate .lib or C++ file, which the user can use if he wants. For example I find the oildrum and firepit scripts very useful, because they have sounds, particles and everything ready to drag and drop.

 

Like in LE 2.5, there is also a smoke emitter, which uses its own shader and texture. An explosion would probably need a shader too, sounds, textures, breakable physics logic, and damage indication to other objects. In addition to those difficult to implement things, the user could add some camera shaking, consequences of the damage to living objects, sound reflections (echo).

Share this comment


Link to comment

Neat. So we could do something like this?

 

particle->load("chris_explosion4.ptl");

particle->set(ANIMATION_SPEED,5.0f);

particle->initiateatlocation(0.0f,0.0.0f,0.0f);

Change .ptl to .pfb (you can load any entity type from a prefab) and particle->load to particle = Prefab::Load, and that's basically it.

Share this comment


Link to comment

Controllers are all the same size, due to their use of the navigation mesh and crowd avoidance. If you were doing something special like a giant boss, I would skip the character controller altogether, because it's a special case and something like that would stay in the same area. It's a limitation, but everything good has constraints.

 

This sounds more like a shortcut than a "good constraint". This means we're limited to human or very humanoid characters in the game.

 

This screws me up a lot tbh... I don't have any giant robots but I have a lot of things with different sized controllers. If they aren't different sized they would look stupid intersecting with each other or colliding with things that don't exist...

Share this comment


Link to comment

That's just the way Recast works:

https://groups.google.com/forum/?fromgroups=#!searchin/recastnavigation/difference$20sizes/recastnavigation/rQjwgaAs8iQ/GN22UNTvBxIJ

 

Detour assumes that the agent radius is substracted from the walkable

area, which means that you should create different navmesh for each

agent size. Recast can be used to create a navmesh without radius, but

there often are some samplling errors at the edges.

 

-mikko

 

Even if I used multiple navigation meshes, the agents on differently sized nav meshes would have no awareness of each other, and would not have flocking/avoidance behavior.

Share this comment


Link to comment

That's just the way Recast works:

 

Well that is just very sad considering recast claims to be world class....

 

Are we at least able to set this one and only size? or is that completely fixed?

 

I have to really think about this now. I don't know if I can even make my game on LE3 anymore sad.png.

 

Will there be any way to turn off the LE pathfinding?

Share this comment


Link to comment

I don"t worry, recast and detour are opensource so they will just benefit from Josh's future code enhancements.

Anyway he will quickly figure out that STR games have vehicles and vehicles require navmeshs too .... and a trooper, a buggy and a tank are not the same size. All STR can handle it, so Josh's brain will find a way to do it (100% confident) [joke]and also C++ will do 98% of the job ^^[/joke] (sorry could not resist) ;-)

Share this comment


Link to comment

The radius is built into the navmesh data. The actual navigation is calculated with a point with no radius. So the only solution is multiple navmeshes for different sizes, but the characters then wouldn't avoid each other.

 

I don"t worry, recast and detour are opensource so they will just benefit from Josh's future code enhancements.
I'm not going to poke around the innards of Recast. That code is really complex.

 

Will there be any way to turn off the LE pathfinding?
Sure, just don't call the commands set objects to affect the navmesh.

Share this comment


Link to comment

this link confirms you have to generate a navmesh for each controller size http://www.gamedev.n...ast-and-detour/

 

'agents significantly larger than the median should use a different navmesh, built using a larger median radius'

 

also your google link says : "Use Recast to build specialized navmeshes and try to find ways to minimize the data and then compare that the approach of reusing the navmesh. Try to take into account the extra data you need (you need to at least mark which polys are walkable by which agent size)."

or "If you have different sized agents, you should create a navmesh for each of the agent size. The restriction is there to make the navmesh generation easier. There are actually quite a few parameters which affect the shape navmesh: agent radios, agent height, agent climb and max slope."

 

for detour I have to search some more, there must be a solution, like said all STR do it.

 

if there is a way to "mark polys walkable" there is perhaps a way to temporarilly mark manually the polys occupied by all different sized controllers, then generate navmesh to get avoidance by doing intermediate (shortened) path search ? ... (sorry if my sentence looks confused, can't word it better)

 

EDIT: an alternative could be to have a LE3 low level navigation command set that encapsulates recast & detour and allows us to do the above ourself ? But the editor should still be able to generate multiple navmeshs with different resolutions.

Share this comment


Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Add a comment...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...