|
@@ -71,7 +71,8 @@ AnimatedModel::AnimatedModel(Context* context) :
|
|
|
boneBoundingBoxDirty_(true),
|
|
boneBoundingBoxDirty_(true),
|
|
|
isMaster_(true),
|
|
isMaster_(true),
|
|
|
loading_(false),
|
|
loading_(false),
|
|
|
- assignBonesPending_(false)
|
|
|
|
|
|
|
+ assignBonesPending_(false),
|
|
|
|
|
+ forceAnimationUpdate_(false)
|
|
|
{
|
|
{
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -209,9 +210,17 @@ void AnimatedModel::Update(const FrameInfo& frame)
|
|
|
// If headless, retain the current animation distance (should be 0)
|
|
// If headless, retain the current animation distance (should be 0)
|
|
|
if (frame.camera_ && abs((int)frame.frameNumber_ - (int)viewFrameNumber_) > 1)
|
|
if (frame.camera_ && abs((int)frame.frameNumber_ - (int)viewFrameNumber_) > 1)
|
|
|
{
|
|
{
|
|
|
- // First check for no update at all when invisible
|
|
|
|
|
|
|
+ // First check for no update at all when invisible. In that case reset LOD timer to ensure update
|
|
|
|
|
+ // next time the model is in view
|
|
|
if (!updateInvisible_)
|
|
if (!updateInvisible_)
|
|
|
|
|
+ {
|
|
|
|
|
+ if (animationDirty_)
|
|
|
|
|
+ {
|
|
|
|
|
+ animationLodTimer_ = -1.0f;
|
|
|
|
|
+ forceAnimationUpdate_ = true;
|
|
|
|
|
+ }
|
|
|
return;
|
|
return;
|
|
|
|
|
+ }
|
|
|
float distance = frame.camera_->GetDistance(node_->GetWorldPosition());
|
|
float distance = frame.camera_->GetDistance(node_->GetWorldPosition());
|
|
|
// If distance is greater than draw distance, no need to update at all
|
|
// If distance is greater than draw distance, no need to update at all
|
|
|
if (drawDistance_ > 0.0f && distance > drawDistance_)
|
|
if (drawDistance_ > 0.0f && distance > drawDistance_)
|
|
@@ -266,6 +275,13 @@ void AnimatedModel::UpdateBatches(const FrameInfo& frame)
|
|
|
|
|
|
|
|
void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
|
|
void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
|
|
|
{
|
|
{
|
|
|
|
|
+ // Late update in case the model came into view and animation was dirtied in the meanwhile
|
|
|
|
|
+ if (forceAnimationUpdate_)
|
|
|
|
|
+ {
|
|
|
|
|
+ UpdateAnimation(frame);
|
|
|
|
|
+ forceAnimationUpdate_ = false;
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
if (morphsDirty_)
|
|
if (morphsDirty_)
|
|
|
UpdateMorphs();
|
|
UpdateMorphs();
|
|
|
|
|
|
|
@@ -275,7 +291,7 @@ void AnimatedModel::UpdateGeometry(const FrameInfo& frame)
|
|
|
|
|
|
|
|
UpdateGeometryType AnimatedModel::GetUpdateGeometryType()
|
|
UpdateGeometryType AnimatedModel::GetUpdateGeometryType()
|
|
|
{
|
|
{
|
|
|
- if (morphsDirty_)
|
|
|
|
|
|
|
+ if (morphsDirty_ || forceAnimationUpdate_)
|
|
|
return UPDATE_MAIN_THREAD;
|
|
return UPDATE_MAIN_THREAD;
|
|
|
else if (skinningDirty_)
|
|
else if (skinningDirty_)
|
|
|
return UPDATE_WORKER_THREAD;
|
|
return UPDATE_WORKER_THREAD;
|
|
@@ -1124,7 +1140,7 @@ void AnimatedModel::UpdateAnimation(const FrameInfo& frame)
|
|
|
// If using animation LOD, accumulate time and see if it is time to update
|
|
// If using animation LOD, accumulate time and see if it is time to update
|
|
|
if (animationLodBias_ > 0.0f && animationLodDistance_ > 0.0f)
|
|
if (animationLodBias_ > 0.0f && animationLodDistance_ > 0.0f)
|
|
|
{
|
|
{
|
|
|
- // Check for first time update
|
|
|
|
|
|
|
+ // Perform the first update always regardless of LOD timer
|
|
|
if (animationLodTimer_ >= 0.0f)
|
|
if (animationLodTimer_ >= 0.0f)
|
|
|
{
|
|
{
|
|
|
animationLodTimer_ += animationLodBias_ * frame.timeStep_ * ANIMATION_LOD_BASESCALE;
|
|
animationLodTimer_ += animationLodBias_ * frame.timeStep_ * ANIMATION_LOD_BASESCALE;
|