UNPKG

@woosh/meep-engine

Version:

Pure JavaScript game engine. Fully featured and production ready.

88 lines (72 loc) 3.14 kB
import { quat_decode_from_uint32 } from "../../../core/geom/3d/quaternion/quat_decode_from_uint32.js"; import { quat_encode_to_uint32 } from "../../../core/geom/3d/quaternion/quat_encode_to_uint32.js"; import { v3_binary_equality_decode } from "../../../core/geom/vec3/serialization/v3_binary_equality_decode.js"; import { v3_binary_equality_encode } from "../../../core/geom/vec3/serialization/v3_binary_equality_encode.js"; import { BinaryClassSerializationAdapter } from "../../ecs/storage/binary/BinaryClassSerializationAdapter.js"; import { Transform } from "../../ecs/transform/Transform.js"; /** * Decode scratch for {@link TransformReplicationAdapter#deserialize}. Decoders * write into indexed slots; we then publish the final value to each field * via `.set(...)` so the `onChanged` signal fires once with the assembled * value rather than not at all (direct-write) or partially per intermediate. * @type {Float32Array} */ const decode_scratch = new Float32Array(4); /** * Network-replication adapter for {@link Transform}. Mirrors * {@link TransformSerializationAdapter} but uses Float32 for position instead * of Float64, halving the per-component cost (12 B vs 24 B) for a precision * loss that is below visible threshold for typical action-game scales. * * Wire layout (typical 17 B, 13 B if scale is identity): * - position: 3 × Float32 = 12 bytes * - rotation: smallest-three uint32 = 4 bytes * - scale: `v3_binary_equality_encode` = 1 byte (identity) or 13 bytes (full) * * Total: 17 bytes typical, 29 bytes max. * * Distinct from {@link TransformSerializationAdapter} so save-game files keep * Float64 position precision while wire packets stay tight. * * @author Alex Goldring * @copyright Company Named Limited (c) 2025 */ export class TransformReplicationAdapter extends BinaryClassSerializationAdapter { klass = Transform; version = 1; /** * @param {BinaryBuffer} buffer * @param {Transform} value */ serialize(buffer, value) { const position = value.position; const rotation = value.rotation; const scale = value.scale; buffer.writeFloat32(position.x); buffer.writeFloat32(position.y); buffer.writeFloat32(position.z); buffer.writeUint32(quat_encode_to_uint32( rotation.x, rotation.y, rotation.z, rotation.w )); v3_binary_equality_encode(buffer, scale.x, scale.y, scale.z); } /** * @param {BinaryBuffer} buffer * @param {Transform} value */ deserialize(buffer, value) { const positionX = buffer.readFloat32(); const positionY = buffer.readFloat32(); const positionZ = buffer.readFloat32(); const encoded_rotation = buffer.readUint32(); const s = decode_scratch; v3_binary_equality_decode(buffer, s, 0); value.scale.set(s[0], s[1], s[2]); quat_decode_from_uint32(s, 0, encoded_rotation); value.rotation.set(s[0], s[1], s[2], s[3]); value.position.set(positionX, positionY, positionZ); } }