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."); } } }