64 lines
1.9 KiB
JavaScript
64 lines
1.9 KiB
JavaScript
|
|
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) {
|
|||
|
|
// Don’t lerp anchored parts — they don’t 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.");
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|