View Issue Details

IDProjectCategoryView StatusLast Update
0003817The Dark ModCodingpublic16.10.2017 20:35
ReporterSteveL Assigned ToSteveL  
PrioritynormalSeveritynormalReproducibilityhave not tried
Status resolvedResolutionfixed 
Product VersionTDM 2.03 
Target VersionTDM 2.03Fixed in VersionTDM 2.03 
Summary0003817: Make decals persist through LOD switches, hiding, shouldering, save/loading
DescriptionReported by Springheel in this post:

I've found one minor undesirable effect of LOD stages on's not a big problem, but maybe something to look at if it's not too difficult....wound decals disappear when the md5mesh is swapped. So if you shoot an arrow at an AI as he's charging you, the blood disappears as he crosses the threshold of the next LOD stage. This is pretty noticeable at closer ranges.
Steps To ReproduceIt happens on ragdolls too, so the easiest way is to KO a guard and then shoot an arrow at his head.
TagsNo tags attached.


related to 0001512 resolvedSteveL Blood decal disappears after dropping body 
related to 0002999 closed Review blood/bleeding code 
related to 0002410 closed Blood stains only affect face 
child of 0003770 resolvedSteveL Make LOD work for AI 




18.08.2014 17:19

reporter   ~0006857

Noticed while working on occluders that a renderModel has space set aside for decals attached to animated meshes. That makes sense now I come to think of it: they need to deform with the animated mesh, so they're not treated like static decals. Evidently, they're not getting preserved through the mesh switch.


21.08.2014 17:10

reporter   ~0006862

The overlays are being removed by renderer method that clears the current model data: R_FreeEntityDefDerivedData, which is being invoked indirectly by the new idAnimated::SwapLODModel routine when it calls the renderer routine FreeModelDef.

Tantalisingly, R_FreeEntityDefDerivedData has parameters that let you specify you don't want the decals and overlays removing. But it doesn't expose those to the game. So this would be fixable with a renderer tweak, but I'll look first whether it can be done in the game code by simply reapplying the blood splats.


21.08.2014 18:22

reporter   ~0006863

The blood splats and other overlays get applied by idEntity::ProjectOverlay.

Not sure what the difference is between an attached decal and an overlay, but the renderer treats them separately. The missing blood splats are overlays.

idEntity::ProjectOverlay uses a randomizing function when it does its stuff to avoid every blood splat looking identical. Need to see whether the game can recover the settings for the particular blood splat from the renderer so they can be re-applied, else it'll mean modifying the renderer code to let the blood splat be preserved unchanged.


22.08.2014 03:40

reporter   ~0006865

Last edited: 22.08.2014 03:41

The difference: In renderer language, a decal is for a static model or worldspawn, an overlay is for animated meshes.

Probably *not* fixable with a renderer tweak after all. The overlay is intimately bound to the mesh surface, both on screen and in the code. The option to keep an overlay when freeing derived data is only available if the model isn't being changed.

Nor can we recover the information needed to set up the blood splat from the renderer. The setup parameters are used only to create the new surface tris. They're not remembered.

Looking like the best bet is to have the entity remember the setup of the last overlay it applied, so it can be reapplied after a model switch. Lots of different animated classes use overlays slightly differently, but the pinch point that all the routes pass through is idEntity::ProjectOverlay.



22.08.2014 07:27

reporter   ~0006866

Simply storing the parameters generated by idEntity::ProjectOverlay doesn't quite do the trick. The AI will have changed position by the time the decal needs reapplying. It puts the decal back close to where it should be surprisingly often, but not often enough.

Need to save the joint-related positions for the decal that're used in idAnimatedEntity::AddLocalDamageEffect, so we can recalculate where it needs to go.


23.08.2014 12:49

reporter   ~0006878

Last edited: 13.09.2014 19:38

In scope: animated entities and static models.
Not in scope: moveables. These don't get decals applied.



13.09.2014 17:43

reporter   ~0006988

Last edited: 13.09.2014 20:04

Deleted several notes that don't apply to latest plan.

Actors and their blood splats are tricky as the splats can hit both head and body, and when the splats come to be reapplied the relative positions will have changed. I see a lot of blood moving round a guard's head with LOD transitions. Heads are especially complicated as a blood splat caused by an arrow in the head is measured from the body's neck joint, not a joint in the head. The collision result specifies the head, but the result gets hacked before being passed to idAnimatedEntity::AddDamageEffect. That's because bindmasters that receive a splat also splash their bindchildren. Not easy to amend that to pass on the original joint info while preserving the bindmaster->bindchild splash relationship, and in any case storing the splat details on the head instead of neck wouldn't help with restoring blood to the neck (or wrist, if the victim happened to have his hand by his face when hit).

Latest plan under test:

== Overlays for animated meshes ==
For each entity splashed (head and body are separate), do a trace to find a local joint as a reference point, and store the detail against that. Should give much more consistent results for splats shared by head and body.

== Decals on static meshes ==
Store details of each impact against the entity that got directly hit (if any), plus the World entity if no direct hit. Restore all from a savegame. Restore just one entity's direct hits after the entity gets unhidden or has its model switched by LOD.



14.09.2014 11:05

reporter   ~0006990

Last edited: 14.09.2014 11:06

That works, with one amendment for overlays: instead of a trace, which is expensive and difficult to get right, we simply find the closest joint to the point of impact and record the position and direction of the splat relative to that joint.

Plan to restore decals and overlays after: (1) LOD switches, (2) hiding (which includes shouldering), and (3) save game loading



18.09.2014 11:01

reporter   ~0007016

Last edited: 18.09.2014 18:32

Update: This is working perfectly for animated meshes. One outstanding problem remains with func statics and fire arrows blasts. The reappllied decal is approx half the size of the original. Not sure yet why that should be.

EDIT: Problem was caused by idGameLocal::ProjectDecal halving its "size" parameter before using it.



18.09.2014 19:52

reporter   ~0007017

Last edited: 18.09.2014 20:06

Committed at rv 6106 (code), rv13999 (game dll)


IdleAnimationTask.cpp (unrelated, removing a temporary comment left in by me in error.)



22.09.2014 21:11

reporter   ~0007033

Reopening for a bug fix.

Dropping a body without adequate space causes a console error. That's because CGrabber::FitsInWorld tests whether the body will fit by unhiding it, triggering a decal restore, but then hides it again if it won't fit, so there's no render model to receive the decals.


22.09.2014 21:28

reporter   ~0007035

This could have been fixed by having idEntity::Hide unset the flag that says to reapply decals on the next Think(). Fixed instead by having ReapplYDecals() abort the operation if there's no current render model. That'll cover any other parts of the code that Show() then Hide() a model before it has chance to Think().


22.09.2014 21:45

reporter   ~0007036

Committed at rv6114



26.09.2014 17:36

reporter   ~0007037

Last edited: 26.09.2014 17:36

Commit # 3 at rv6115

Tweak to idAnimatedEntity::SwapLODModel. Do not attempt to reapply the overlay if the joints couldn't be preserved through the LOD switch. Preventative bugfix in case we ever add LOD stages with simplified skeletons.



04.10.2014 17:50

reporter   ~0007051

Last edited: 04.10.2014 17:50

Commit # 4 at rv6120. Changed a const pointer declaration to a non-const one because the pointer is used to delete the object it points to. For some reason that compiled ok on MSVC (!!!) but gcc correctly choked on it.



23.11.2014 09:01

reporter   ~0007159

Last edited: 30.11.2014 00:07

Further report of ProjectOverlay causing a fatal error when dropping a body:

Waiting for confirmation whether this code predates fix at rev 6114 above

Edit: closing again pending further testing after the branch that gave this result gets merged back in. I've not been able to rep it in 100s of tests, and it's not clear whether the code used for the build included the fix.

Issue History

Date Modified Username Field Change
17.08.2014 09:43 SteveL New Issue
17.08.2014 09:43 SteveL Status new => assigned
17.08.2014 09:43 SteveL Assigned To => SteveL
17.08.2014 09:44 SteveL Relationship added child of 0003770
18.08.2014 17:19 SteveL Note Added: 0006857
21.08.2014 17:10 SteveL Note Added: 0006862
21.08.2014 18:22 SteveL Note Added: 0006863
22.08.2014 03:40 SteveL Note Added: 0006865
22.08.2014 03:41 SteveL Note Edited: 0006865
22.08.2014 07:27 SteveL Note Added: 0006866
23.08.2014 12:49 SteveL Note Added: 0006878
23.08.2014 13:04 SteveL Note Edited: 0006878
23.08.2014 14:58 SteveL Note Edited: 0006878
23.08.2014 18:12 SteveL Relationship added parent of 0003829
23.08.2014 18:12 SteveL Relationship replaced related to 0003829
23.08.2014 19:40 SteveL Relationship added related to 0001512
23.08.2014 19:44 SteveL Relationship deleted related to 0003829
13.09.2014 17:43 SteveL Note Added: 0006988
13.09.2014 17:43 SteveL Note Edited: 0006988
13.09.2014 19:38 SteveL Note Edited: 0006878
13.09.2014 19:59 SteveL Note Edited: 0006988
13.09.2014 20:04 SteveL Note Edited: 0006988
14.09.2014 11:05 SteveL Note Added: 0006990
14.09.2014 11:06 SteveL Note Edited: 0006990
16.09.2014 20:03 SteveL Summary Lost decals on LOD AI switches => Make decals persist through LOD switches, hiding, shouldering, save/loading
18.09.2014 11:01 SteveL Note Added: 0007016
18.09.2014 18:32 SteveL Note Edited: 0007016
18.09.2014 19:52 SteveL Note Added: 0007017
18.09.2014 19:54 SteveL Status assigned => resolved
18.09.2014 19:54 SteveL Fixed in Version => TDM 2.03
18.09.2014 19:54 SteveL Resolution open => fixed
18.09.2014 20:06 SteveL Note Edited: 0007017
22.09.2014 21:11 SteveL Note Added: 0007033
22.09.2014 21:11 SteveL Status resolved => assigned
22.09.2014 21:28 SteveL Note Added: 0007035
22.09.2014 21:45 SteveL Note Added: 0007036
22.09.2014 21:45 SteveL Status assigned => resolved
26.09.2014 17:36 SteveL Note Added: 0007037
26.09.2014 17:36 SteveL Note Edited: 0007037
04.10.2014 17:50 SteveL Note Added: 0007051
04.10.2014 17:50 SteveL Note Edited: 0007051
23.11.2014 09:01 SteveL Note Added: 0007159
23.11.2014 09:01 SteveL Status resolved => assigned
30.11.2014 00:07 SteveL Note Edited: 0007159
30.11.2014 00:07 SteveL Status assigned => resolved
16.10.2017 20:33 nbohr1more Relationship added related to 0002999
16.10.2017 20:35 nbohr1more Relationship added related to 0002410