Jump to content
The Dark Mod Forums

Benefits from LOD AI?


Springheel
 Share

Recommended Posts

Awesome. Will it work with other animated entities, for example ambient NPCs like this?

 

entityDef atdm:ambient_citywatch
{
"editor_displayFolder" "AI/ambient"
"spawnclass" "idAnimated"
"model" "tdm_ai_citywatch"
"start_anim" "idle"
"anim" "walk1"
"cycle" "3"
}

It's only a model...

Link to comment
Share on other sites

Yes, I think so. The simplest way to set it up would be to do it for all animated articulated figures, else we'd need special case code for one subclass (ai) sitting in the AF animated class. More on this when I've mapped out the existing architecture.

Link to comment
Share on other sites

then when he turns into a human he carries on shuffling like a skeleton until he hits his first path corner. After that, he walks like a human.

 

I was thinking about this further...are you swapping the ModelDef? The skeleton does have separate animations set in its modelDef, but that shouldn't happen if only the md5mesh is being swapped.

Link to comment
Share on other sites

How does looking through the Spyglass affect LOD?

 

It doesn't. In other words, the LOD is based on player distance with accommodation for the spyglass, you can use it to test/verify models are changing, as the image seen will be correct for the player distance, and the "magnification" will let you see what's otherwise to far away to verify.

"The measure of a man's character is what he would do if he knew he never would be found out."

- Baron Thomas Babington Macauley

Link to comment
Share on other sites

It doesn't. In other words, the LOD is based on player distance with accommodation for the spyglass, you can use it to test/verify models are changing, as the image seen will be correct for the player distance, and the "magnification" will let you see what's otherwise to far away to verify.

 

So the magnification is done at render time?

Link to comment
Share on other sites

How does looking through the Spyglass affect LOD?

 

A related question is, how will it affect cutscenes? LOD distance is (currently) calculated from the player origin. Does the player origin move during cutscenes?

 

I was thinking about this further...are you swapping the ModelDef? The skeleton does have separate animations set in its modelDef, but that shouldn't happen if only the md5mesh is being swapped.

 

Yes, I'm swapping the model def. I was going to do more testing before commenting on it, but since you asked: I don't think it'll be possible to swap just the md5mesh. There are several reasons for that, including a warning from Tels not to try it, left in the render model code. The animation code, the performance optimisations (all identical models sharing the same data) and lots more depend on using a set of model defs that don't get tweaked after map start. Fiddling with it would depart far from existing design and would likely break everything. Fortunately, that's not a maintenance disaster. I imagine a set of model defs laid out something like this:

 

model tdm_ai_scientist {
  inherit tdm_ai_proguard
  mesh models/md5/tdm_inventor_scientist.md5mesh

  channel torso ( *Spine_Dummy)
  channel legs ( origin Pelvis Pelvis2 *Hips)

  //replacing animations that don't fit character
  anim idle_nose_wipe models/md5/chars/guards/proguard/idle_armwipe.md5anim
  anim idle_nosewipe_short models/md5/chars/guards/proguard/idle_ponder02.md5anim
  anim idle_spit models/md5/chars/guards/proguard/idle_armwipe.md5anim
  anim idle_eat models/md5/chars/guards/proguard/idle_ponder02.md5anim
}

model tdm_ai_scientist_lod1 {
  inherit tdm_ai_scientist
  mesh models/md5/tdm_inventor_scientist_lod1.md5mesh
}

model tdm_ai_scientist_lod2 {
  inherit tdm_ai_scientist
  mesh models/md5/tdm_inventor_scientist_lod2.md5mesh
}

 

The mapper would still just use "tdm_ai_scientist" when picking a model.

Link to comment
Share on other sites

A related question is, how will it affect cutscenes? LOD distance is (currently) calculated from the player origin. Does the player origin move during cutscenes?

 

Yes, but mainly to keep the player w/in hearing distance of any conversations. Since the player should be kept close to the action, LOD might not affect the characters or props.

Link to comment
Share on other sites

Yes, but mainly to keep the player w/in hearing distance of any conversations. Since the player should be kept close to the action, LOD might not affect the characters or props.

 

That would be good I guess. You want full res during cutscenes.

 

I can confirm the spyglass doesn't move the player closer for LOD purposes. My skellies in that test map are still skellies when zoomed in.

Link to comment
Share on other sites

Yes, I'm swapping the model def. I was going to do more testing before commenting on it, but since you asked: I don't think it'll be possible to swap just the md5mesh.

 

No problem...it's only slightly more work for maintenance but actually increases the flexibility for mappers to do interesting things, like set different animations for different LOD distances.

Link to comment
Share on other sites

Yes, I'm swapping the model def.

Will it be possible to swap animated def with static one? What about completely hiding the model at very long distance? I'm thinking about the grass test map. It had bad performance because of md5. Swapping highpoly animated grass with low poly would increase performance. Swapping it with static model and then completely hiding would could increase it even more.

It's only a model...

Link to comment
Share on other sites

Completely hiding stuff is already built into LOD so that should work. And if modelDefs are being swapped, you should be able to swap in a modelDef that points the grass to an animation with a single frame, essentially static.

Link to comment
Share on other sites

No problem...it's only slightly more work for maintenance but actually increases the flexibility for mappers to do interesting things, like set different animations for different LOD distances.

Good point re flexibility. Who knows, by the time we get to 2.04 there might be demand for a trigger_swapAiModel :)

 

To make my original point a bit clearer, individual AI don't have an md5mesh of their own that you can swap. They have a label that says "I'm one of the entities currently using model def #4826", and that's all that's seen by the animator and the renderer. The game/engine setup turns out to match the .def file setup, which is good design and always comes as a relief to coders who otherwise produce lots of embarrassing bugs when they try anything.

 

Will it be possible to swap animated def with static one? What about completely hiding the model at very long distance? I'm thinking about the grass test map. It had bad performance because of md5. Swapping highpoly animated grass with low poly would increase performance. Swapping it with static model and then completely hiding would could increase it even more.

Completely hiding stuff is already built into LOD so that should work. And if modelDefs are being swapped, you should be able to swap in a modelDef that points the grass to an animation with a single frame, essentially static.

What Springheel said, plus it might be possible to swap in a static model. Well, it's definitely possible, but I'm not sure what would happen to ongoing animations.... whether they'd continue to run in the background and eat processor time even if not producing visible results. But the existing SetModel() method would work perfectly there... It cancels animations when you switch model. I'll keep this option in mind in case it's easy to detect that the new model is static and so cancel animations selectively.

  • Like 1
Link to comment
Share on other sites

Hm.. will LOD stages break custom anims for AI?

 

I've made custom anim AI like this:

1) Make a new special def that inherits the proguard devel def (the one that contains all anims for males.)

2) add my custom anims into this def.

3) make a new AI def that inherits the AI type (a citywatch guard for example), but uses the special def mentioned in 1) instead of the normal one.

 

I suppose this setup will break if AI has LOD stages that do not inherit the custom anim def. Is there some way to do this so that the stup is maximally future-proof?

Clipper

-The mapper's best friend.

Link to comment
Share on other sites

I had thought of this too but forgot to post it. The priest in St. Lucia, for example, has a special modelDef:

 

model tdm_ai_lucia_builderpriest {

inherit tdm_ai_builderpriest

mesh models/md5/chars/builders/priest/builderpriestmesh.md5mesh

 

channel torso ( *Spine_Dummy)

channel legs ( origin Pelvis Pelvis2 *Hips)

 

anim ponder models/md5/chars/guards/proguard/idle_ponder02.md5anim //includes vocal

{

no_random_headturning

 

frame 56 sound_voice priest_hopeful_vocal

}

 

}

 

And then the priest just has a special "model" spawnarg in his entitydef to point to this modelDef.

 

If the default priest is set to use LOD, then when he switches to his LOD1 stage, he'll stop using the special animation. (In this case it's not a huge deal as there is a default "ponder" animation. There are some AI that use unique animations though).

 

I don't have a great solution to this in mind. Maybe don't allow LOD stages to be inherited? That wouldn't cover the priest above though.

Link to comment
Share on other sites

Could there be an automatic check:

1) play anim

2) if anim does not exist for this LOD level, switch to standard model and play anim.

3) if anim does not exist at all, abort anim and continue on path. (Currently, if AI hits path_anim with non-existing anim, the AI will stop patrol completely.)

 

Or a spawnarg that disables LOD stages for AI, and the mapper must remember to disable LOD for AI with custom anims.

 

Automatic system would be of course preferrable, because then the mapper is free of error-hunting.

Clipper

-The mapper's best friend.

Link to comment
Share on other sites

Here's an example of a custom AI from Reputation:

 

 

model tdm_ai_citywatch_lesser_lean {

inherit tdm_ai_proguard

 

mesh models/md5/chars/guards/citywatch/tdm_ai_citywatch_lesser.md5mesh

channel torso ( *Spine_Dummy)

channel legs ( origin Pelvis Pelvis2 *Hips)

 

 

anim lean models/md5/chars/guards/proguard/lean.md5anim

{

prevent_idle_override

frame 1 call overrideLegs

frame 40 footstep

frame 65 sound snd_rustle

frame 361 sound snd_rustle

frame 583 sound snd_rustle

frame 620 footstep

frame 694 sound snd_rustle

frame 730 footstep

}

 

anim lean_loop models/md5/chars/guards/proguard/lean_loop.md5anim

{

prevent_idle_override

frame 1 call overrideLegs

}

 

 

 

}

 

 

"lean" is an animation that is/was unique to this mission. I wouldn't want the AI to be standing when the player was a distance away, and then suddenly snap to leaning when they get within range, so I think the preferable option would be to suppress the LOD switching in these cases. I'm not sure of a really easy way to identify these cases off the top of my head though. Is it realistic to compare the next LOD stage to the current one and not switch if the animations are different?

Link to comment
Share on other sites

We should try to avoid building in special case rules if it's possible. They make the setup more buggy and less flexible.

 

Couldn't these special anims be handled through the normal inheritance method? Like in the example I gave above, the extra LOD model defs are 1-liners that inherit the main model def, including any special animations:

model tdm_ai_scientist {
  inherit tdm_ai_proguard
  mesh models/md5/tdm_inventor_scientist.md5mesh
  channel torso ( *Spine_Dummy)
  channel legs ( origin Pelvis Pelvis2 *Hips)
  //replacing animations that don't fit character
  anim idle_nose_wipe models/md5/chars/guards/proguard/idle_armwipe.md5anim
  anim idle_nosewipe_short models/md5/chars/guards/proguard/idle_ponder02.md5anim
  anim idle_spit models/md5/chars/guards/proguard/idle_armwipe.md5anim
  anim idle_eat models/md5/chars/guards/proguard/idle_ponder02.md5anim
}
model tdm_ai_scientist_lod1 {
  inherit tdm_ai_scientist
  mesh models/md5/tdm_inventor_scientist_lod1.md5mesh
}
model tdm_ai_scientist_lod2 {
  inherit tdm_ai_scientist
  mesh models/md5/tdm_inventor_scientist_lod2.md5mesh
}

 

A mapper or developer wanting a special anim could copy that entire block, rename all three levels, and add the new anims just to the top level couldn't they?

Link to comment
Share on other sites

Quick update on progress: I've sketched out the LOD setup and the AI hierarchy on a diagram, to work out where any new code should go. The only place that makes sense to fix it up is in the code for idAnimatedEntity, which handles all model setting for all entity types lower down the chain. LOD would therefore end up supporting all animated entities not just AI. Because the model def will need to be changed, we should probably use normal LOD spawnargs in the entity def rather than in the model def.

 

I'm about to start working my way through the rest for the code that normally happens when an animated model gets switched, working out what needs to happen during a LOD switch and what needs to be left out (like cancelling the current anim).

 

Can you guys tell me what makes a model compatible with another model so that they can share animations? I'm guessing number of joints has to match but I have no idea whether joints have names or whether those need to match, or whether size of bones matters. Or what happens if you attach an incompatible animation to a model.

 

Another question: is it just md5meshes or are there other types of animated model?

Link to comment
Share on other sites

@Steve.

That looks okay to do, but those meshes probably do not exist now. The eventual LOD-stage filenames could be different.

 

How to get it to be future proof? So that I would not need to update the mission when the LOD update comes to TDM. If I cannot take this into account now, the mission will break when the LOD comes in. This is because then AI that used to have a normal mesh all the time suddenly gets LOD meshes, which don't have the anims. Then AI who is in the LOD mesh, will halt as they cannot play anims.

 

What I can do now so that it will not break later?

Clipper

-The mapper's best friend.

Link to comment
Share on other sites

I see what you mean.... it'll be a problem for your set-up if the default proguard suddenly gets LOD, so that your special AI that inherits it starts to swap his modified model def for a different one that won't have your modifications.

 

One way to have make it fully backwards-compatible would be to have new defs for LOD AI instead of changing old ones. But that means existing maps won't benefit from the changes.

 

Is there a way we can have the best of both worlds? I guess I've arrived at your question now. Hmm, food for thought.

Link to comment
Share on other sites

Is there a way we can have the best of both worlds? I guess I've arrived at your question now. Hmm, food for thought.

 

I gave it some thought now and I think it just needs manual repair of broken FMs.

 

We must be mindful that LOD will require that all missions that have custom anims are updated. That is, the small lines pointing to the LOD meshes are added.

Luckily the amount of affected missions is less than 5, because custom anims are rare... So it is probably not a biggie. We just need some kind of handy way to test that the mission works. When AI does not have an anim, no error message is given and the AI just halt and never move again on their patrol. It is somewhat difficult to detect.

 

LOD AI is certainly a worthy addition. Like Tels always said: "Sometimes, you must break some eggs to make an omelet."

;)

Clipper

-The mapper's best friend.

Link to comment
Share on other sites

Thanks for the encouragement :) If you are right and we can't support existing maps without changing some, then I will gladly donate testing time plus I'll use a script to find all custom anims in published maps.

 

What I can do now so that it will not break later?

 

One thing you can do is disable lod entirely on your entity by adding spawnargs dist_check_period 0 and hide_distance 0. With both those at 0, the entity will never get touched by LOD, no matter what gets added to a inherited def later.

Link to comment
Share on other sites

I'm guessing number of joints has to match but I have no idea whether joints have names or whether those need to match, or whether size of bones matters. Or what happens if you attach an incompatible animation to a model.

Joint names are listed in both md5.mesh and md5.anim. They need to match exactly, otherwise you'll get an error message during map load.

It's only a model...

Link to comment
Share on other sites

Join the conversation

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

Guest
Reply to this topic...

×   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.

 Share


  • Recent Status Updates

    • jaxa

      Embracer Group is Buying Square Enix Montréal, Eidos, and Crystal Dynamics for “Only” 300 Million USD: https://wccftech.com/embracer-group-square-enix-montreal-eidos-crystal-dynamics/
      · 1 reply
    • duzenko

      Do we want fur in TDM? Like https://duzenko.github.io/webgl/
      · 6 replies
    • Epifire

      Sometimes life throws a curveball - other times it straight up tries to take you outta the game. Been one thing after another lately but I ain't goin without a fight!
      · 2 replies
    • duzenko

      My Uber rating (as a passenger) is 4.71. Is there still hope or should I just kill myself? What's yours?
      · 3 replies
    • kano

      Did I mention how absolutely grateful I am that TDM didn't get (and can never be) assimilated by a huge company like Microsoft, as is what happened to Minecraft?
      · 3 replies
×
×
  • Create New...