|
|
@@ -88,7 +88,7 @@ namespace bs
|
|
|
{ }
|
|
|
|
|
|
Skeleton::Skeleton(BONE_DESC* bones, UINT32 numBones)
|
|
|
- : mNumBones(numBones), mBoneTransforms(bs_newN<Matrix4>(numBones)), mInvBindPoses(bs_newN<Matrix4>(numBones))
|
|
|
+ : mNumBones(numBones), mBoneTransforms(bs_newN<Transform>(numBones)), mInvBindPoses(bs_newN<Matrix4>(numBones))
|
|
|
, mBoneInfo(bs_newN<SkeletonBoneInfo>(numBones))
|
|
|
{
|
|
|
for(UINT32 i = 0; i < numBones; i++)
|
|
|
@@ -170,9 +170,6 @@ namespace bs
|
|
|
localPose.scales[i] = Vector3::ONE;
|
|
|
}
|
|
|
|
|
|
- bool* hasAnimCurve = bs_stack_alloc<bool>(mNumBones);
|
|
|
- bs_zero_out(hasAnimCurve, mNumBones);
|
|
|
-
|
|
|
// Note: For a possible performance improvement consider keeping an array of only active (non-disabled) bones and
|
|
|
// just iterate over them without mask checks. Possibly also a list of active curve mappings to avoid those checks
|
|
|
// as well.
|
|
|
@@ -209,6 +206,8 @@ namespace bs
|
|
|
if (!mask.isEnabled(k))
|
|
|
continue;
|
|
|
|
|
|
+ bool hasAnimCurve = false;
|
|
|
+
|
|
|
const AnimationCurveMapping& mapping = state.boneToCurveMapping[k];
|
|
|
UINT32 curveIdx = mapping.position;
|
|
|
if (curveIdx != (UINT32)-1)
|
|
|
@@ -217,7 +216,7 @@ namespace bs
|
|
|
localPose.positions[k] += curve.evaluate(state.time, state.positionCaches[curveIdx], state.loop) * normWeight;
|
|
|
|
|
|
localPose.hasOverride[k] = false;
|
|
|
- hasAnimCurve[k] = true;
|
|
|
+ hasAnimCurve = true;
|
|
|
}
|
|
|
|
|
|
curveIdx = mapping.scale;
|
|
|
@@ -227,7 +226,7 @@ namespace bs
|
|
|
localPose.scales[k] *= curve.evaluate(state.time, state.scaleCaches[curveIdx], state.loop) * normWeight;
|
|
|
|
|
|
localPose.hasOverride[k] = false;
|
|
|
- hasAnimCurve[k] = true;
|
|
|
+ hasAnimCurve = true;
|
|
|
}
|
|
|
|
|
|
if (layer.additive)
|
|
|
@@ -246,7 +245,7 @@ namespace bs
|
|
|
|
|
|
localPose.rotations[k] *= value;
|
|
|
localPose.hasOverride[k] = false;
|
|
|
- hasAnimCurve[k] = true;
|
|
|
+ hasAnimCurve = true;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
@@ -262,9 +261,18 @@ namespace bs
|
|
|
|
|
|
localPose.rotations[k] += value;
|
|
|
localPose.hasOverride[k] = false;
|
|
|
- hasAnimCurve[k] = true;
|
|
|
+ hasAnimCurve = true;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // If no animation for this bone, apply its default transform
|
|
|
+ // (Even if this bone isn't used for the skin, the child bones need to inherit this transform)
|
|
|
+ if(!hasAnimCurve)
|
|
|
+ {
|
|
|
+ localPose.positions[k] = mBoneTransforms[k].getPosition();
|
|
|
+ localPose.rotations[k] = mBoneTransforms[k].getRotation();
|
|
|
+ localPose.scales[k] = mBoneTransforms[k].getScale();
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
@@ -291,15 +299,6 @@ namespace bs
|
|
|
pose[i] = Matrix4::TRS(localPose.positions[i], localPose.rotations[i], localPose.scales[i]);
|
|
|
}
|
|
|
|
|
|
- // Apply default local tranform to non-animated bones (so that any potential child bones are transformed properly)
|
|
|
- for(UINT32 i = 0; i < mNumBones; i++)
|
|
|
- {
|
|
|
- if(hasAnimCurve[i])
|
|
|
- continue;
|
|
|
-
|
|
|
- pose[i] = mBoneTransforms[i] * pose[i];
|
|
|
- }
|
|
|
-
|
|
|
// Calculate global poses
|
|
|
// Note: For a possible performance improvement consider sorting bones in such order so that parents (and overrides)
|
|
|
// always come before children, we no isGlobal check is needed.
|
|
|
@@ -329,7 +328,6 @@ namespace bs
|
|
|
pose[i] = pose[i] * mInvBindPoses[i];
|
|
|
|
|
|
bs_stack_free(isGlobal);
|
|
|
- bs_stack_free(hasAnimCurve);
|
|
|
}
|
|
|
|
|
|
UINT32 Skeleton::getRootBoneIndex() const
|