@ume-group/contracts 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (57) hide show
  1. package/README.md +37 -0
  2. package/dist/adserving.d.ts +150 -0
  3. package/dist/adserving.d.ts.map +1 -0
  4. package/dist/adserving.js +8 -0
  5. package/dist/campaigns.d.ts +37 -0
  6. package/dist/campaigns.d.ts.map +1 -0
  7. package/dist/campaigns.js +8 -0
  8. package/dist/gausst.d.ts +236 -0
  9. package/dist/gausst.d.ts.map +1 -0
  10. package/dist/gausst.js +307 -0
  11. package/dist/gausst.test.d.ts +2 -0
  12. package/dist/gausst.test.d.ts.map +1 -0
  13. package/dist/gausst.test.js +71 -0
  14. package/dist/index.d.ts +1531 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +1112 -0
  17. package/dist/layer2/index.d.ts +9 -0
  18. package/dist/layer2/index.d.ts.map +1 -0
  19. package/dist/layer2/index.js +10 -0
  20. package/dist/layer2/shaders.d.ts +185 -0
  21. package/dist/layer2/shaders.d.ts.map +1 -0
  22. package/dist/layer2/shaders.js +604 -0
  23. package/dist/layer2/webcam-utils.d.ts +113 -0
  24. package/dist/layer2/webcam-utils.d.ts.map +1 -0
  25. package/dist/layer2/webcam-utils.js +147 -0
  26. package/dist/layer2/webcam-utils.test.d.ts +2 -0
  27. package/dist/layer2/webcam-utils.test.d.ts.map +1 -0
  28. package/dist/layer2/webcam-utils.test.js +18 -0
  29. package/dist/layer2.d.ts +558 -0
  30. package/dist/layer2.d.ts.map +1 -0
  31. package/dist/layer2.js +376 -0
  32. package/dist/layer2.test.d.ts +2 -0
  33. package/dist/layer2.test.d.ts.map +1 -0
  34. package/dist/layer2.test.js +65 -0
  35. package/dist/perspective.d.ts +28 -0
  36. package/dist/perspective.d.ts.map +1 -0
  37. package/dist/perspective.js +157 -0
  38. package/dist/segmentation/MediaPipeSegmenter.d.ts +201 -0
  39. package/dist/segmentation/MediaPipeSegmenter.d.ts.map +1 -0
  40. package/dist/segmentation/MediaPipeSegmenter.js +434 -0
  41. package/dist/segmentation/index.d.ts +5 -0
  42. package/dist/segmentation/index.d.ts.map +1 -0
  43. package/dist/segmentation/index.js +4 -0
  44. package/dist/webcam/GarbageMatteDragManager.d.ts +63 -0
  45. package/dist/webcam/GarbageMatteDragManager.d.ts.map +1 -0
  46. package/dist/webcam/GarbageMatteDragManager.js +183 -0
  47. package/dist/webcam/WebcamStreamManager.d.ts +103 -0
  48. package/dist/webcam/WebcamStreamManager.d.ts.map +1 -0
  49. package/dist/webcam/WebcamStreamManager.js +356 -0
  50. package/dist/webcam/index.d.ts +5 -0
  51. package/dist/webcam/index.d.ts.map +1 -0
  52. package/dist/webcam/index.js +2 -0
  53. package/openapi/admetise.yaml +632 -0
  54. package/openapi/includu.yaml +621 -0
  55. package/openapi/integration.yaml +372 -0
  56. package/openapi/shared/schemas.yaml +227 -0
  57. package/package.json +53 -0
package/dist/gausst.js ADDED
@@ -0,0 +1,307 @@
1
+ /**
2
+ * Gausst Coordinate System Utilities
3
+ *
4
+ * Implements the coordinate system from Patent US8761580B2 and the
5
+ * legacy Gausst Maya plugin (gausstCamera.cpp).
6
+ *
7
+ * This system enables accurate camera matching between physical tracked
8
+ * cameras and virtual 3D scenes.
9
+ *
10
+ * Key features:
11
+ * - 35mm full-frame equivalent film gate (1.417" × 0.945")
12
+ * - FOV ↔ focal length conversion
13
+ * - Gausst rotation order: Tilt → Pan (negated) → Roll (negated)
14
+ * - Video plane sizing at distance
15
+ */
16
+ // =============================================================================
17
+ // Constants (from legacy gausstCamera.cpp)
18
+ // =============================================================================
19
+ export const GAUSST = {
20
+ // 35mm full-frame equivalent film gate
21
+ // From: MDistance(1.417, MDistance::uiUnit()) horizontal
22
+ // From: MDistance(.945, MDistance::uiUnit()) vertical
23
+ HORIZONTAL_APERTURE: 1.417, // inches (≈36mm)
24
+ VERTICAL_APERTURE: 0.945, // inches (≈24mm)
25
+ // Default values from legacy plugin
26
+ DEFAULT_FOCAL_LENGTH: 35, // mm
27
+ VIDEO_PLANE_DISTANCE: 500, // Maya units
28
+ DEFAULT_OVERSCAN: 1.3,
29
+ // Conversion constants
30
+ DEG_TO_RAD: Math.PI / 180,
31
+ RAD_TO_DEG: 180 / Math.PI,
32
+ MM_PER_INCH: 25.4,
33
+ // Default camera position (eye level, standing human)
34
+ DEFAULT_CAMERA_POSITION: [0, 1.6, 0],
35
+ DEFAULT_FOV: 60
36
+ };
37
+ // =============================================================================
38
+ // FOV ↔ Focal Length Conversions
39
+ // =============================================================================
40
+ /**
41
+ * Convert field of view (degrees) to focal length (mm)
42
+ *
43
+ * Formula from legacy gausstCamera.h:
44
+ * focalLength = ((aperture / 2) / tan(fieldOfView / 2)) * 25.4
45
+ *
46
+ * @param fovDegrees - Horizontal field of view in degrees
47
+ * @param apertureInches - Horizontal film aperture in inches (default: 35mm equivalent)
48
+ * @returns Focal length in millimeters
49
+ *
50
+ * @example
51
+ * fovToFocalLength(60) // ≈ 31mm
52
+ * fovToFocalLength(90) // ≈ 18mm
53
+ * fovToFocalLength(45) // ≈ 43mm
54
+ */
55
+ export function fovToFocalLength(fovDegrees, apertureInches = GAUSST.HORIZONTAL_APERTURE) {
56
+ const fovRadians = fovDegrees * GAUSST.DEG_TO_RAD;
57
+ return ((apertureInches / 2) / Math.tan(fovRadians / 2)) * GAUSST.MM_PER_INCH;
58
+ }
59
+ /**
60
+ * Convert focal length (mm) to field of view (degrees)
61
+ *
62
+ * Inverse of fovToFocalLength
63
+ *
64
+ * @param focalLengthMM - Focal length in millimeters
65
+ * @param apertureInches - Horizontal film aperture in inches (default: 35mm equivalent)
66
+ * @returns Horizontal field of view in degrees
67
+ *
68
+ * @example
69
+ * focalLengthToFov(35) // ≈ 54.4°
70
+ * focalLengthToFov(50) // ≈ 39.6°
71
+ * focalLengthToFov(24) // ≈ 73.7°
72
+ */
73
+ export function focalLengthToFov(focalLengthMM, apertureInches = GAUSST.HORIZONTAL_APERTURE) {
74
+ const fovRadians = 2 * Math.atan((apertureInches / 2 * GAUSST.MM_PER_INCH) / focalLengthMM);
75
+ return fovRadians * GAUSST.RAD_TO_DEG;
76
+ }
77
+ // =============================================================================
78
+ // Rotation Utilities
79
+ // =============================================================================
80
+ /**
81
+ * Convert Gausst rotation (tilt, pan, roll) to Euler angles for Three.js
82
+ *
83
+ * From legacy gausstCamera.cpp moveTheCamera():
84
+ * - Maya rotation order: tilt, pan, roll
85
+ * - Pan and Roll are NEGATED before application
86
+ * - Three.js equivalent: 'YXZ' Euler order
87
+ *
88
+ * @param tiltDeg - Tilt (pitch) in degrees - rotation around X axis
89
+ * @param panDeg - Pan (yaw) in degrees - rotation around Y axis (will be negated)
90
+ * @param rollDeg - Roll in degrees - rotation around Z axis (will be negated)
91
+ * @returns Object with euler values and order for Three.js
92
+ *
93
+ * @example
94
+ * const { x, y, z, order } = gausst RotationToEuler(10, 20, 5);
95
+ * mesh.rotation.set(x, y, z);
96
+ * mesh.rotation.order = order;
97
+ */
98
+ export function gausstRotationToEuler(tiltDeg, panDeg, rollDeg) {
99
+ return {
100
+ x: tiltDeg * GAUSST.DEG_TO_RAD, // Tilt (unchanged)
101
+ y: -panDeg * GAUSST.DEG_TO_RAD, // Pan (NEGATED)
102
+ z: -rollDeg * GAUSST.DEG_TO_RAD, // Roll (NEGATED)
103
+ order: 'YXZ'
104
+ };
105
+ }
106
+ /**
107
+ * Convert Three.js Euler angles back to Gausst rotation
108
+ *
109
+ * Inverse of gausst RotationToEuler - extracts tilt, pan, roll from Euler
110
+ * Assumes the object uses 'YXZ' rotation order
111
+ *
112
+ * @param x - Euler X rotation in radians
113
+ * @param y - Euler Y rotation in radians
114
+ * @param z - Euler Z rotation in radians
115
+ * @returns Gausst rotation as [tilt, pan, roll] in degrees
116
+ */
117
+ export function eulerToGausstRotation(x, y, z) {
118
+ return [
119
+ x * GAUSST.RAD_TO_DEG, // Tilt
120
+ -y * GAUSST.RAD_TO_DEG, // Pan (negate back)
121
+ -z * GAUSST.RAD_TO_DEG // Roll (negate back)
122
+ ];
123
+ }
124
+ // =============================================================================
125
+ // Video Plane Calculations
126
+ // =============================================================================
127
+ /**
128
+ * Calculate video plane dimensions at a given distance from camera
129
+ *
130
+ * From legacy gausstCamera.cpp draw():
131
+ * horizontalSize = videoPolygonDistance * horizontalFilmApertureValue * 25.4f / focalLengthValue;
132
+ * verticalSize = videoPolygonDistance * verticalFilmApertureValue * 25.4f / focalLengthValue;
133
+ *
134
+ * @param distance - Distance from camera in world units
135
+ * @param focalLengthMM - Focal length in millimeters
136
+ * @param horizontalAperture - Horizontal film aperture in inches
137
+ * @param verticalAperture - Vertical film aperture in inches
138
+ * @returns Width and height of video plane at that distance
139
+ *
140
+ * @example
141
+ * // Video plane at 10m with 35mm lens
142
+ * const { width, height } = getVideoPlaneSize(10, 35);
143
+ * // width ≈ 10.27m, height ≈ 6.85m
144
+ */
145
+ export function getVideoPlaneSize(distance, focalLengthMM, horizontalAperture = GAUSST.HORIZONTAL_APERTURE, verticalAperture = GAUSST.VERTICAL_APERTURE) {
146
+ const width = (distance * horizontalAperture * GAUSST.MM_PER_INCH) / focalLengthMM;
147
+ const height = (distance * verticalAperture * GAUSST.MM_PER_INCH) / focalLengthMM;
148
+ return { width, height };
149
+ }
150
+ /**
151
+ * Calculate video plane dimensions using FOV instead of focal length
152
+ *
153
+ * @param distance - Distance from camera in world units
154
+ * @param fovDegrees - Horizontal field of view in degrees
155
+ * @returns Width and height of video plane at that distance
156
+ */
157
+ export function getVideoPlaneSizeFromFov(distance, fovDegrees) {
158
+ const focalLength = fovToFocalLength(fovDegrees);
159
+ return getVideoPlaneSize(distance, focalLength);
160
+ }
161
+ // =============================================================================
162
+ // Position Conversions
163
+ // =============================================================================
164
+ /**
165
+ * Convert tracking packet position to world coordinates
166
+ *
167
+ * From legacy gausstCamera.cpp moveTheCamera():
168
+ * Xpos = convert4bytesToFloat(&theBuffer[6]) / 1000;
169
+ * (Position comes as mm × 100, divide by 1000 to get meters)
170
+ *
171
+ * @param packetValue - Raw value from tracking packet (mm × 100)
172
+ * @returns Position in meters
173
+ */
174
+ export function trackingPacketToMeters(packetValue) {
175
+ return packetValue / 100000; // mm×100 → meters
176
+ }
177
+ /**
178
+ * Convert meters to tracking packet format
179
+ *
180
+ * @param meters - Position in meters
181
+ * @returns Raw value for tracking packet (mm × 100)
182
+ */
183
+ export function metersToTrackingPacket(meters) {
184
+ return Math.round(meters * 100000);
185
+ }
186
+ // =============================================================================
187
+ // Aspect Ratio Utilities
188
+ // =============================================================================
189
+ /**
190
+ * Get the default aspect ratio from Gausst film gate
191
+ *
192
+ * @returns Aspect ratio (width / height)
193
+ */
194
+ export function getGausstAspectRatio() {
195
+ return GAUSST.HORIZONTAL_APERTURE / GAUSST.VERTICAL_APERTURE;
196
+ }
197
+ /**
198
+ * Calculate vertical FOV from horizontal FOV using Gausst aspect ratio
199
+ *
200
+ * @param horizontalFovDeg - Horizontal field of view in degrees
201
+ * @returns Vertical field of view in degrees
202
+ */
203
+ export function horizontalToVerticalFov(horizontalFovDeg) {
204
+ const aspectRatio = getGausstAspectRatio();
205
+ const hFovRad = horizontalFovDeg * GAUSST.DEG_TO_RAD;
206
+ const vFovRad = 2 * Math.atan(Math.tan(hFovRad / 2) / aspectRatio);
207
+ return vFovRad * GAUSST.RAD_TO_DEG;
208
+ }
209
+ /**
210
+ * Calculate horizontal FOV from vertical FOV using Gausst aspect ratio
211
+ *
212
+ * @param verticalFovDeg - Vertical field of view in degrees
213
+ * @returns Horizontal field of view in degrees
214
+ */
215
+ export function verticalToHorizontalFov(verticalFovDeg) {
216
+ const aspectRatio = getGausstAspectRatio();
217
+ const vFovRad = verticalFovDeg * GAUSST.DEG_TO_RAD;
218
+ const hFovRad = 2 * Math.atan(Math.tan(vFovRad / 2) * aspectRatio);
219
+ return hFovRad * GAUSST.RAD_TO_DEG;
220
+ }
221
+ // =============================================================================
222
+ // Three.js Integration Helpers
223
+ // =============================================================================
224
+ /**
225
+ * Apply Gausst rotation directly to a Three.js Object3D
226
+ *
227
+ * This is the primary function for setting rotation on 3D objects
228
+ * using the Gausst coordinate system.
229
+ *
230
+ * @param object - Three.js Object3D (mesh, camera, group, etc.)
231
+ * @param tiltDeg - Tilt (pitch) in degrees
232
+ * @param panDeg - Pan (yaw) in degrees
233
+ * @param rollDeg - Roll in degrees
234
+ *
235
+ * @example
236
+ * import * as THREE from 'three';
237
+ * const mesh = new THREE.Mesh(geometry, material);
238
+ * applyGausstRotation(mesh, 10, 45, 0); // 10° tilt, 45° pan
239
+ */
240
+ export function applyGausstRotation(object, tiltDeg, panDeg, rollDeg) {
241
+ const euler = gausstRotationToEuler(tiltDeg, panDeg, rollDeg);
242
+ object.rotation.order = euler.order;
243
+ object.rotation.set(euler.x, euler.y, euler.z);
244
+ }
245
+ /**
246
+ * Configure a Three.js PerspectiveCamera with Gausst parameters
247
+ *
248
+ * @param camera - Three.js PerspectiveCamera
249
+ * @param fovDegrees - Horizontal field of view in degrees
250
+ * @param position - Camera position [x, y, z] in meters
251
+ * @param lookAt - Look-at target [x, y, z] in meters
252
+ *
253
+ * @example
254
+ * const camera = new THREE.PerspectiveCamera();
255
+ * configureGausstCamera(camera, 60, [0, 1.6, 0], [0, 1.6, -10]);
256
+ */
257
+ export function configureGausstCamera(camera, fovDegrees, position, lookAt) {
258
+ // Note: Three.js PerspectiveCamera.fov is VERTICAL FOV
259
+ camera.fov = horizontalToVerticalFov(fovDegrees);
260
+ camera.position.set(...position);
261
+ camera.lookAt(...lookAt);
262
+ camera.updateProjectionMatrix();
263
+ }
264
+ // =============================================================================
265
+ // Validation Utilities
266
+ // =============================================================================
267
+ /**
268
+ * Validate FOV is within reasonable bounds
269
+ *
270
+ * @param fovDegrees - Field of view to validate
271
+ * @returns true if valid, false otherwise
272
+ */
273
+ export function isValidFov(fovDegrees) {
274
+ return fovDegrees > 1 && fovDegrees < 179;
275
+ }
276
+ /**
277
+ * Validate focal length is within reasonable bounds
278
+ *
279
+ * @param focalLengthMM - Focal length to validate
280
+ * @returns true if valid, false otherwise
281
+ */
282
+ export function isValidFocalLength(focalLengthMM) {
283
+ return focalLengthMM > 1 && focalLengthMM < 1000;
284
+ }
285
+ /**
286
+ * Clamp FOV to valid range
287
+ *
288
+ * @param fovDegrees - FOV to clamp
289
+ * @returns Clamped FOV
290
+ */
291
+ export function clampFov(fovDegrees) {
292
+ return Math.max(1, Math.min(179, fovDegrees));
293
+ }
294
+ /**
295
+ * Clamp rotation to reasonable range (-180 to 180)
296
+ *
297
+ * @param degrees - Rotation in degrees
298
+ * @returns Normalized rotation in -180 to 180 range
299
+ */
300
+ export function normalizeRotation(degrees) {
301
+ let normalized = degrees % 360;
302
+ if (normalized > 180)
303
+ normalized -= 360;
304
+ if (normalized < -180)
305
+ normalized += 360;
306
+ return normalized;
307
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=gausst.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gausst.test.d.ts","sourceRoot":"","sources":["../src/gausst.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,71 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { GAUSST, fovToFocalLength, focalLengthToFov, gausstRotationToEuler, eulerToGausstRotation, normalizeRotation, isValidFov, clampFov, horizontalToVerticalFov, verticalToHorizontalFov } from './gausst';
3
+ describe('fovToFocalLength', () => {
4
+ it('converts 60° FOV to ~31.19mm', () => {
5
+ const result = fovToFocalLength(60);
6
+ expect(result).toBeCloseTo(31.19, 1);
7
+ });
8
+ });
9
+ describe('fovToFocalLength / focalLengthToFov round-trip', () => {
10
+ it('recovers original FOV within 0.001°', () => {
11
+ const originalFov = 72.5;
12
+ const focal = fovToFocalLength(originalFov);
13
+ const recovered = focalLengthToFov(focal);
14
+ expect(recovered).toBeCloseTo(originalFov, 3);
15
+ });
16
+ });
17
+ describe('gausstRotationToEuler', () => {
18
+ it('negates pan and roll, keeps tilt', () => {
19
+ const tilt = 10;
20
+ const pan = 20;
21
+ const roll = 5;
22
+ const result = gausstRotationToEuler(tilt, pan, roll);
23
+ expect(result.x).toBeCloseTo(tilt * GAUSST.DEG_TO_RAD, 10);
24
+ expect(result.y).toBeCloseTo(-pan * GAUSST.DEG_TO_RAD, 10);
25
+ expect(result.z).toBeCloseTo(-roll * GAUSST.DEG_TO_RAD, 10);
26
+ expect(result.order).toBe('YXZ');
27
+ });
28
+ });
29
+ describe('gausstRotationToEuler / eulerToGausstRotation round-trip', () => {
30
+ it('recovers original tilt, pan, roll', () => {
31
+ const tilt = 15;
32
+ const pan = -30;
33
+ const roll = 7.5;
34
+ const euler = gausstRotationToEuler(tilt, pan, roll);
35
+ const [rTilt, rPan, rRoll] = eulerToGausstRotation(euler.x, euler.y, euler.z);
36
+ expect(rTilt).toBeCloseTo(tilt, 10);
37
+ expect(rPan).toBeCloseTo(pan, 10);
38
+ expect(rRoll).toBeCloseTo(roll, 10);
39
+ });
40
+ });
41
+ describe('normalizeRotation', () => {
42
+ it('normalizes boundary cases', () => {
43
+ expect(normalizeRotation(181)).toBeCloseTo(-179, 10);
44
+ expect(normalizeRotation(360)).toBeCloseTo(0, 10);
45
+ expect(normalizeRotation(-270)).toBeCloseTo(90, 10);
46
+ });
47
+ });
48
+ describe('isValidFov', () => {
49
+ it('rejects boundaries, accepts valid range', () => {
50
+ expect(isValidFov(1)).toBe(false);
51
+ expect(isValidFov(179)).toBe(false);
52
+ expect(isValidFov(60)).toBe(true);
53
+ expect(isValidFov(0)).toBe(false);
54
+ });
55
+ });
56
+ describe('clampFov', () => {
57
+ it('clamps to [1, 179]', () => {
58
+ expect(clampFov(200)).toBe(179);
59
+ expect(clampFov(0)).toBe(1);
60
+ expect(clampFov(-50)).toBe(1);
61
+ expect(clampFov(90)).toBe(90);
62
+ });
63
+ });
64
+ describe('horizontalToVerticalFov / verticalToHorizontalFov round-trip', () => {
65
+ it('recovers original horizontal FOV within 0.001°', () => {
66
+ const hFov = 65;
67
+ const vFov = horizontalToVerticalFov(hFov);
68
+ const recovered = verticalToHorizontalFov(vFov);
69
+ expect(recovered).toBeCloseTo(hFov, 3);
70
+ });
71
+ });