Files
bo3-js/js/instances/LerpedBasePart.js

64 lines
1.9 KiB
JavaScript
Raw Normal View History

2025-10-12 18:03:20 +02:00
import * as THREE from "three";
import { BasePart } from "./BasePart.js";
export class LerpedBasePart extends BasePart { // Extends BasePart to add smooth interpolation for networked parts
constructor() {
super();
this.ClassName = "LerpedBasePart"; // 👈 Roblox-style ClassName
this._lastReplicatedState = null;
this._nextReplicatedState = null;
}
// Called when replication data arrives from the server
OnReplicated() {
// Keep old state to interpolate from
this._lastReplicatedState = this._nextReplicatedState;
// Store new replication state
this._nextReplicatedState = {
pos: this.Position.clone(),
quat: new THREE.Quaternion().setFromEuler(this.Orientation),
time: performance.now(),
};
// Apply anchored state from server
this._applyAnchoredState?.();
this.updateSizes(); // In case Size changed
}
// Smooth visual updates
updateVisual(dt) {
// Dont lerp anchored parts — they dont move
if (this.Anchored) {
this.mesh.position.copy(this.Position);
this.mesh.quaternion.setFromEuler(this.Orientation);
return;
}
if (this._nextReplicatedState && this._lastReplicatedState) {
// Interpolate between last and next states
const now = performance.now();
const t = Math.min(
(now - this._lastReplicatedState.time) / 100, // ~10Hz replication → 100ms
1
);
this.mesh.position.lerpVectors(
this._lastReplicatedState.pos,
this._nextReplicatedState.pos,
t
);
this.mesh.quaternion.slerpQuaternions(
this._lastReplicatedState.quat,
this._nextReplicatedState.quat,
t
);
} else {
// Fallback to default behavior
this.mesh.position.copy(this.body.position);
this.mesh.quaternion.copy(this.body.quaternion);
console.warn("LerpedBasePart: No replication data yet, using physics state.");
}
}
}