From 80588c1ce4b50960414f3d8ec2bec2f36a65fc6f Mon Sep 17 00:00:00 2001 From: Joel Wetzell Date: Sat, 15 Mar 2025 09:54:58 -0500 Subject: [PATCH] add decoder for zone collision detection submodule --- src/decoders/index.ts | 4 +++ .../motion/zone-collision-detection.ts | 32 +++++++++++++++++ src/decoders/motion/zone-object.ts | 21 +++++++++++ src/models.ts | 13 +++++++ tests/decode.test.js | 35 +++++++++++++++++++ 5 files changed, 105 insertions(+) create mode 100644 src/decoders/motion/zone-collision-detection.ts create mode 100644 src/decoders/motion/zone-object.ts diff --git a/src/decoders/index.ts b/src/decoders/index.ts index 90416bf..c96275a 100644 --- a/src/decoders/index.ts +++ b/src/decoders/index.ts @@ -4,6 +4,8 @@ import OrientationEuler from './motion/orientation-euler'; import OrientationQuaternion from './motion/orientation-quaternion'; import TrackedPointAccelVelocity from './motion/tracked-point-accel-velocity'; import TrackedPointPosition from './motion/tracked-point-position'; +import ZoneCollisionDetection from './motion/zone-collision-detection'; +import ZoneObject from './motion/zone-object'; import RTTrPHeader from './rttrp'; export const Decoders = { @@ -14,4 +16,6 @@ export const Decoders = { TrackedPointAccelVelocity, OrientationQuaternion, OrientationEuler, + ZoneCollisionDetection, + ZoneObject, }; diff --git a/src/decoders/motion/zone-collision-detection.ts b/src/decoders/motion/zone-collision-detection.ts new file mode 100644 index 0000000..4d01700 --- /dev/null +++ b/src/decoders/motion/zone-collision-detection.ts @@ -0,0 +1,32 @@ +import { Decoders } from '..'; +import { ZoneCollisionDetection, ZoneObject } from '../../models'; + +export default (bytes: Uint8Array, isLittleEndian: boolean = false): ZoneCollisionDetection => { + const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength); + + const type = view.getUint8(0); + if (type !== 0x22) { + throw new Error('Zone Collision Detection module must have a type of 0x22'); + } + + const size = view.getUint16(1, isLittleEndian); + if (size !== bytes.byteLength) { + throw new Error('Zone Collision Detection module size mismatch'); + } + const numberOfZones = view.getUint8(3); + + const zones: ZoneObject[] = []; + let zoneObjectOffset = 4; + + for (let index = 0; index < numberOfZones; index++) { + const zone = Decoders.ZoneObject(bytes.subarray(zoneObjectOffset)); + zones.push(zone); + zoneObjectOffset += zone.size; + } + return { + type, + size, + numberOfZones, + zones, + }; +}; diff --git a/src/decoders/motion/zone-object.ts b/src/decoders/motion/zone-object.ts new file mode 100644 index 0000000..19b57c2 --- /dev/null +++ b/src/decoders/motion/zone-object.ts @@ -0,0 +1,21 @@ +import { ZoneObject } from '../../models'; +const textDecoder = new TextDecoder('utf-8'); +export default (bytes: Uint8Array): ZoneObject => { + const size = bytes[0]; + if (bytes.byteLength < size) { + throw new Error('Zone Object size does not have enough actual bytes'); + } + + const moduleBytes = bytes.subarray(0, size); + + const nameLength = moduleBytes[1]; + if (moduleBytes.byteLength - 2 !== nameLength) { + throw new Error('Zone Object name length does not match actual moduleBytes length'); + } + const name = textDecoder.decode(moduleBytes.subarray(2)); + return { + size, + nameLength, + name, + }; +}; diff --git a/src/models.ts b/src/models.ts index 7cccc4e..83a5883 100644 --- a/src/models.ts +++ b/src/models.ts @@ -76,3 +76,16 @@ export type OrientationEuler = { r2: number; r3: number; }; + +export type ZoneCollisionDetection = { + type: number; + size: number; + numberOfZones: number; + zones: ZoneObject[]; +}; + +export type ZoneObject = { + size: number; + nameLength: number; + name: string; +}; diff --git a/tests/decode.test.js b/tests/decode.test.js index ebb4f95..3061d14 100644 --- a/tests/decode.test.js +++ b/tests/decode.test.js @@ -131,6 +131,41 @@ const goodTests = [ }, decoder: Decoders.TrackedPointAccelVelocity, }, + { + description: 'Zone Collision Detection', + bytes: new Uint8Array([ + 0x22, 0x00, 0x14, 0x02, 0x08, 0x06, 0x7a, 0x6f, 0x6e, 0x65, 0x20, 0x31, 0x08, 0x06, 0x7a, 0x6f, 0x6e, 0x65, 0x20, + 0x32, + ]), + expected: { + type: 0x22, + size: 20, + numberOfZones: 2, + zones: [ + { + size: 0x08, + nameLength: 0x06, + name: 'zone 1', + }, + { + size: 0x08, + nameLength: 0x06, + name: 'zone 2', + }, + ], + }, + decoder: Decoders.ZoneCollisionDetection, + }, + { + description: 'Zone Object', + bytes: new Uint8Array([0x08, 0x06, 0x7a, 0x6f, 0x6e, 0x65, 0x20, 0x31]), + expected: { + size: 0x08, + nameLength: 0x06, + name: 'zone 1', + }, + decoder: Decoders.ZoneObject, + }, ]; describe('RTTrP Bytes Decoding', () => {