Handle initial actor's transparency (bug #4860)

pull/2177/head
Andrei Kortunov 5 years ago
parent 097c649885
commit 629a6be477

@ -28,6 +28,7 @@
Bug #4827: NiUVController is handled incorrectly
Bug #4828: Potion looping effects VFX are not shown for NPCs
Bug #4837: CTD when a mesh with NiLODNode root node with particles is loaded
Bug #4860: Actors outside of processing range visible for one frame after spawning
Feature #2229: Improve pathfinding AI
Feature #3442: Default values for fallbacks from ini file
Feature #3610: Option to invert X axis

@ -1169,8 +1169,46 @@ namespace MWMechanics
if (!anim)
return;
mActors.insert(std::make_pair(ptr, new Actor(ptr, anim)));
CharacterController* ctrl = mActors[ptr]->getCharacterController();
if (updateImmediately)
mActors[ptr]->getCharacterController()->update(0);
ctrl->update(0);
// We should initially hide actors outside of processing range.
// Note: since we update player after other actors, distance will be incorrect during teleportation.
// Do not update visibility if player was teleported, so actors will be visible during teleportation frame.
if (MWBase::Environment::get().getWorld()->getPlayer().wasTeleported())
return;
updateVisibility(ptr, ctrl);
}
void Actors::updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl)
{
MWWorld::Ptr player = MWMechanics::getPlayer();
if (ptr == player)
return;
const float dist = (player.getRefData().getPosition().asVec3() - ptr.getRefData().getPosition().asVec3()).length();
if (dist > mActorsProcessingRange)
{
ptr.getRefData().getBaseNode()->setNodeMask(0);
return;
}
else
ptr.getRefData().getBaseNode()->setNodeMask(MWRender::Mask_Actor);
// Fade away actors on large distance (>90% of actor's processing distance)
float visibilityRatio = 1.0;
float fadeStartDistance = mActorsProcessingRange*0.9f;
float fadeEndDistance = mActorsProcessingRange;
float fadeRatio = (dist - fadeStartDistance)/(fadeEndDistance - fadeStartDistance);
if (fadeRatio > 0)
visibilityRatio -= std::max(0.f, fadeRatio);
visibilityRatio = std::min(1.f, visibilityRatio);
ctrl->setVisibility(visibilityRatio);
}
void Actors::removeActor (const MWWorld::Ptr& ptr)
@ -1479,17 +1517,7 @@ namespace MWMechanics
world->setActorCollisionMode(iter->first, true, !iter->first.getClass().getCreatureStats(iter->first).isDeathAnimationFinished());
ctrl->update(duration);
// Fade away actors on large distance (>90% of actor's processing distance)
float visibilityRatio = 1.0;
float fadeStartDistance = mActorsProcessingRange*0.9f;
float fadeEndDistance = mActorsProcessingRange;
float fadeRatio = (dist - fadeStartDistance)/(fadeEndDistance - fadeStartDistance);
if (fadeRatio > 0)
visibilityRatio -= std::max(0.f, fadeRatio);
visibilityRatio = std::min(1.f, visibilityRatio);
ctrl->setVisibility(visibilityRatio);
updateVisibility(iter->first, ctrl);
}
if (playerCharacter)

@ -19,6 +19,7 @@ namespace MWWorld
namespace MWMechanics
{
class Actor;
class CharacterController;
class CreatureStats;
class Actors
@ -169,6 +170,8 @@ namespace MWMechanics
bool isAttackingOrSpell(const MWWorld::Ptr& ptr) const;
private:
void updateVisibility (const MWWorld::Ptr& ptr, CharacterController* ctrl);
PtrActorMap mActors;
float mTimerDisposeSummonsCorpses;
float mActorsProcessingRange;

Loading…
Cancel
Save