增加物理结算
This commit is contained in:
1 parent
650d9c0398
commit
c29de7a26b
4 files changed
+96
-39
No files matched your search
@@ -320,6 +320,7 @@
|
||||
let duration = 0; // 当前动画时长
|
||||
let isStaticAnimation = false;
|
||||
const FPS = 30;
|
||||
const MAX_FRAME_DELTA = 0.064;
|
||||
const STATIC_EPSILON = 1e-6;
|
||||
let statusHoldUntil = 0;
|
||||
|
||||
@@ -572,9 +573,13 @@
|
||||
}
|
||||
|
||||
// ---------- 更新动画状态 ----------
|
||||
function updateWorld(sk) {
|
||||
function updateWorld(sk, delta = 0, resetPhysics = false) {
|
||||
if (sk.updateWorldTransform) {
|
||||
if (spine.Physics && spine.Physics.update !== undefined) sk.updateWorldTransform(spine.Physics.update);
|
||||
if (spine.Physics && spine.Physics.update !== undefined) {
|
||||
if (delta > 0 && typeof sk.update === 'function') sk.update(delta);
|
||||
const mode = resetPhysics && spine.Physics.reset !== undefined ? spine.Physics.reset : spine.Physics.update;
|
||||
sk.updateWorldTransform(mode);
|
||||
}
|
||||
else sk.updateWorldTransform();
|
||||
}
|
||||
}
|
||||
@@ -880,7 +885,7 @@
|
||||
});
|
||||
}
|
||||
|
||||
function applyAnimationPose(targetSkeleton, targetState, animation, time) {
|
||||
function applyAnimationPose(targetSkeleton, targetState, animation, time, previousTime) {
|
||||
if (typeof targetState.clearTracks === 'function') targetState.clearTracks();
|
||||
else if (typeof targetState.clearTrack === 'function') targetState.clearTrack(0);
|
||||
if (typeof targetSkeleton.setToSetupPose === 'function') targetSkeleton.setToSetupPose();
|
||||
@@ -888,7 +893,7 @@
|
||||
if (entry) entry.loop = false;
|
||||
targetState.update(Math.max(0, time));
|
||||
targetState.apply(targetSkeleton);
|
||||
updateWorld(targetSkeleton);
|
||||
updateWorld(targetSkeleton, previousTime === undefined ? 0 : Math.max(0, time - previousTime), previousTime === undefined);
|
||||
}
|
||||
|
||||
function mergeBounds(total, next) {
|
||||
@@ -916,7 +921,7 @@
|
||||
probeRenderer = clippingRenderer.createRenderer(spine, context, activeRuntimeDir);
|
||||
probeRenderer.premultipliedAlpha = premultipliedAlpha;
|
||||
for (let index = 0; index < poseCount; index++) {
|
||||
applyPose(index);
|
||||
applyPose(index, index - 1);
|
||||
context.setTransform(1, 0, 0, 1, 0, 0);
|
||||
context.clearRect(0, 0, size, size);
|
||||
context.save();
|
||||
@@ -972,14 +977,14 @@
|
||||
previewStateData.defaultMix = 0;
|
||||
const previewState = new spine.AnimationState(previewStateData);
|
||||
let bounds = null;
|
||||
for (const time of sampleTimes) {
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, time);
|
||||
for (let index = 0; index < sampleTimes.length; index++) {
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, sampleTimes[index], index ? sampleTimes[index - 1] : undefined);
|
||||
bounds = mergeBounds(bounds, getBounds(previewSkeleton));
|
||||
}
|
||||
bounds = bounds || stableFitBounds;
|
||||
if (!bounds || bounds.width <= 0 || bounds.height <= 0) throw new Error(t('viewer.emptySkeletonMsg'));
|
||||
bounds = await measureVisibleBounds(previewSkeleton, bounds, sampleTimes.length, (index) => {
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, sampleTimes[index]);
|
||||
bounds = await measureVisibleBounds(previewSkeleton, bounds, sampleTimes.length, (index, previousIndex) => {
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, sampleTimes[index], previousIndex >= 0 ? sampleTimes[previousIndex] : undefined);
|
||||
}) || bounds;
|
||||
|
||||
const off = document.createElement('canvas');
|
||||
@@ -994,7 +999,7 @@
|
||||
offRenderer = clippingRenderer.createRenderer(spine, octx, activeRuntimeDir);
|
||||
offRenderer.premultipliedAlpha = premultipliedAlpha;
|
||||
for (let index = 0; index < sampleTimes.length; index++) {
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, sampleTimes[index]);
|
||||
applyAnimationPose(previewSkeleton, previewState, animation, sampleTimes[index], index ? sampleTimes[index - 1] : undefined);
|
||||
octx.setTransform(1, 0, 0, 1, 0, 0);
|
||||
octx.clearRect(0, 0, size, size);
|
||||
octx.fillStyle = '#1e1e1e';
|
||||
@@ -1371,10 +1376,12 @@
|
||||
if (skeleton && state) {
|
||||
if (playing) {
|
||||
// Spine 运行时自身处理循环;持续 update 即可。
|
||||
state.update(dt * speed);
|
||||
const frameDelta = Math.min(Math.max(dt, 0), MAX_FRAME_DELTA) * speed;
|
||||
state.update(frameDelta);
|
||||
state.apply(skeleton);
|
||||
updateWorld(skeleton, frameDelta);
|
||||
}
|
||||
updateWorld(skeleton);
|
||||
else updateWorld(skeleton);
|
||||
draw();
|
||||
const entry = currentTrack();
|
||||
if (entry) {
|
||||
@@ -1611,7 +1618,7 @@
|
||||
if (typeof skeleton.setBonesToSetupPose === 'function') skeleton.setBonesToSetupPose();
|
||||
if (typeof skeleton.setSlotsToSetupPose === 'function') skeleton.setSlotsToSetupPose();
|
||||
}
|
||||
updateWorld(skeleton);
|
||||
updateWorld(skeleton, 0, true);
|
||||
updateTimelineDuration(null, true);
|
||||
setStatus(t('viewer.setupPose'));
|
||||
draw();
|
||||
@@ -1693,7 +1700,7 @@
|
||||
}
|
||||
state.update(Math.max(0, time));
|
||||
state.apply(skeleton);
|
||||
updateWorld(skeleton);
|
||||
updateWorld(skeleton, 0, true);
|
||||
draw();
|
||||
updateTimeReadout(time);
|
||||
} catch (e) { /* ignore */ }
|
||||
|
||||
Reference in new issue
Block a user