angular-three-rapier 4.0.0-next.116 → 4.0.0-next.118

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.
@@ -47,7 +47,32 @@ function interactionGroups(memberships, filters) {
47
47
  function bitmask(groups) {
48
48
  return [groups].flat().reduce((acc, layer) => acc | (1 << layer), 0);
49
49
  }
50
+ /**
51
+ * Injection token for handlers that set collision groups on colliders.
52
+ * Used internally by rigid bodies and attractors to apply interaction groups.
53
+ */
50
54
  const COLLISION_GROUPS_HANDLER = new InjectionToken('COLLISION_GROUPS_HANDLER');
55
+ /**
56
+ * Directive for setting collision/solver groups on a rigid body or collider.
57
+ * This allows filtering which objects can collide with each other.
58
+ *
59
+ * @example
60
+ * ```html
61
+ * <!-- Object in group 0, collides with groups 0 and 1 -->
62
+ * <ngt-object3D rigidBody [interactionGroups]="[[0], [0, 1]]">
63
+ * <ngt-mesh>
64
+ * <ngt-box-geometry />
65
+ * </ngt-mesh>
66
+ * </ngt-object3D>
67
+ *
68
+ * <!-- Object in groups 0 and 1, collides with everything -->
69
+ * <ngt-object3D rigidBody [interactionGroups]="[[0, 1]]">
70
+ * <ngt-mesh>
71
+ * <ngt-sphere-geometry />
72
+ * </ngt-mesh>
73
+ * </ngt-object3D>
74
+ * ```
75
+ */
51
76
  class NgtrInteractionGroups {
52
77
  inputs = input.required({ ...(ngDevMode ? { debugName: "inputs" } : {}), alias: 'interactionGroups' });
53
78
  interactionGroups = computed(() => {
@@ -73,6 +98,22 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
73
98
  args: [{ selector: 'ngt-object3D[interactionGroups]' }]
74
99
  }], ctorParameters: () => [], propDecorators: { inputs: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactionGroups", required: true }] }] } });
75
100
 
101
+ /**
102
+ * Debug visualization component for the physics world.
103
+ * Renders wireframe outlines of all colliders in the physics simulation.
104
+ *
105
+ * This component is automatically rendered when the `debug` option is set to `true`
106
+ * on the `NgtrPhysics` component. It updates every frame to show current collider positions.
107
+ *
108
+ * @example
109
+ * ```html
110
+ * <ngtr-physics [options]="{ debug: true }">
111
+ * <ng-template>
112
+ * <!-- Your physics scene -->
113
+ * </ng-template>
114
+ * </ngtr-physics>
115
+ * ```
116
+ */
76
117
  class NgtrDebug {
77
118
  physics = inject(NgtrPhysics);
78
119
  lineSegmentsRef = viewChild.required('lineSegments');
@@ -120,6 +161,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
120
161
  }]
121
162
  }], ctorParameters: () => [], propDecorators: { lineSegmentsRef: [{ type: i0.ViewChild, args: ['lineSegments', { isSignal: true }] }] } });
122
163
 
164
+ /**
165
+ * Internal directive that manages the physics simulation loop.
166
+ * Handles both "follow" mode (tied to render loop) and "independent" mode (separate loop).
167
+ *
168
+ * This directive is used internally by NgtrPhysics and should not be used directly.
169
+ */
123
170
  class NgtrFrameStepper {
124
171
  ready = input(false, ...(ngDevMode ? [{ debugName: "ready" }] : []));
125
172
  updatePriority = input(0, ...(ngDevMode ? [{ debugName: "updatePriority" }] : []));
@@ -161,20 +208,48 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
161
208
  args: [{ selector: 'ngtr-frame-stepper' }]
162
209
  }], ctorParameters: () => [], propDecorators: { ready: [{ type: i0.Input, args: [{ isSignal: true, alias: "ready", required: false }] }], updatePriority: [{ type: i0.Input, args: [{ isSignal: true, alias: "updatePriority", required: false }] }], stepFn: [{ type: i0.Input, args: [{ isSignal: true, alias: "stepFn", required: true }] }], type: [{ type: i0.Input, args: [{ isSignal: true, alias: "type", required: true }] }] } });
163
210
 
211
+ /**
212
+ * Shared reusable Three.js objects for internal calculations.
213
+ * These are used to avoid creating new objects on every frame,
214
+ * which would cause garbage collection pressure.
215
+ *
216
+ * @internal
217
+ */
218
+ /** Shared quaternion for internal calculations */
164
219
  const _quaternion = new THREE.Quaternion();
220
+ /** Shared euler angles for internal calculations */
165
221
  const _euler = new THREE.Euler();
222
+ /** Shared vector3 for internal calculations */
166
223
  const _vector3 = new THREE.Vector3();
224
+ /** Shared Object3D for internal calculations */
167
225
  const _object3d = new THREE.Object3D();
226
+ /** Shared matrix4 for internal calculations */
168
227
  const _matrix4 = new THREE.Matrix4();
228
+ /** Shared position vector for internal calculations */
169
229
  const _position = new THREE.Vector3();
230
+ /** Shared rotation quaternion for internal calculations */
170
231
  const _rotation = new THREE.Quaternion();
232
+ /** Shared scale vector for internal calculations */
171
233
  const _scale = new THREE.Vector3();
172
234
 
173
235
  /**
174
236
  * Creates a proxy that will create a singleton instance of the given class
175
- * when a property is accessed, and not before.
237
+ * when a property is accessed, and not before. This is useful for lazy initialization
238
+ * of expensive objects like physics worlds.
239
+ *
240
+ * @template SingletonClass - The type of the singleton instance
241
+ * @template CreationFn - The type of the factory function
242
+ * @param createInstance - A function that returns a new instance of the class
243
+ * @returns An object containing the proxy, reset function, and set function
176
244
  *
177
- * @returns A proxy and a reset function, so that the instance can created again
245
+ * @example
246
+ * ```typescript
247
+ * const { proxy, reset } = createSingletonProxy(() => new World(gravity));
248
+ * // Access the world lazily
249
+ * proxy.step();
250
+ * // Reset when done
251
+ * reset();
252
+ * ```
178
253
  */
179
254
  const createSingletonProxy = (
180
255
  /**
@@ -208,9 +283,29 @@ createInstance) => {
208
283
  */
209
284
  return { proxy, reset, set };
210
285
  };
286
+ /**
287
+ * Converts a Rapier quaternion to a Three.js quaternion.
288
+ *
289
+ * @param quaternion - The Rapier quaternion to convert
290
+ * @returns A Three.js Quaternion with the same values
291
+ */
211
292
  function rapierQuaternionToQuaternion({ x, y, z, w }) {
212
293
  return _quaternion.set(x, y, z, w);
213
294
  }
295
+ /**
296
+ * Converts an Angular Three vector representation to a Rapier Vector3.
297
+ * Supports arrays, numbers (uniform scale), and objects with x, y, z properties.
298
+ *
299
+ * @param v - The vector to convert (can be [x, y, z], a number, or {x, y, z})
300
+ * @returns A Rapier Vector3 instance
301
+ *
302
+ * @example
303
+ * ```typescript
304
+ * vector3ToRapierVector([1, 2, 3]); // RapierVector3(1, 2, 3)
305
+ * vector3ToRapierVector(5); // RapierVector3(5, 5, 5)
306
+ * vector3ToRapierVector({ x: 1, y: 2, z: 3 }); // RapierVector3(1, 2, 3)
307
+ * ```
308
+ */
214
309
  function vector3ToRapierVector(v) {
215
310
  if (Array.isArray(v)) {
216
311
  return new Vector3(v[0], v[1], v[2]);
@@ -220,6 +315,19 @@ function vector3ToRapierVector(v) {
220
315
  }
221
316
  return new Vector3(v.x, v.y, v.z);
222
317
  }
318
+ /**
319
+ * Converts an Angular Three quaternion representation to a Rapier Quaternion.
320
+ * Supports arrays and objects with x, y, z, w properties.
321
+ *
322
+ * @param v - The quaternion to convert (can be [x, y, z, w] or {x, y, z, w})
323
+ * @returns A Rapier Quaternion instance
324
+ *
325
+ * @example
326
+ * ```typescript
327
+ * quaternionToRapierQuaternion([0, 0, 0, 1]); // Identity quaternion
328
+ * quaternionToRapierQuaternion({ x: 0, y: 0, z: 0, w: 1 }); // Identity quaternion
329
+ * ```
330
+ */
223
331
  function quaternionToRapierQuaternion(v) {
224
332
  if (Array.isArray(v)) {
225
333
  return new Quaternion(v[0], v[1], v[2], v[3]);
@@ -280,6 +388,21 @@ function getColliderArgsFromGeometry(geometry, colliders) {
280
388
  }
281
389
  return { args: [], offset: new THREE.Vector3() };
282
390
  }
391
+ /**
392
+ * Creates collider options by traversing child meshes of an object and generating
393
+ * appropriate collider configurations based on their geometries.
394
+ *
395
+ * @param object - The parent Object3D to traverse for meshes
396
+ * @param options - The rigid body options containing collider type and other settings
397
+ * @param ignoreMeshColliders - Whether to skip meshes that are children of mesh colliders
398
+ * @returns Array of collider configurations with shape, args, position, rotation, and scale
399
+ *
400
+ * @example
401
+ * ```typescript
402
+ * const colliderOptions = createColliderOptions(rigidBodyObject, { colliders: 'cuboid' });
403
+ * // Returns array of collider configs for each mesh child
404
+ * ```
405
+ */
283
406
  function createColliderOptions(object, options, ignoreMeshColliders = true) {
284
407
  const childColliderOptions = [];
285
408
  object.updateWorldMatrix(true, false);
@@ -338,7 +461,23 @@ const defaultOptions$1 = {
338
461
  timeStep: 1 / 60,
339
462
  debug: false,
340
463
  };
464
+ /**
465
+ * Directive for providing a fallback template when Rapier fails to load.
466
+ *
467
+ * @example
468
+ * ```html
469
+ * <ngtr-physics>
470
+ * <ng-template>
471
+ * <!-- Physics scene content -->
472
+ * </ng-template>
473
+ * <ng-template rapierFallback let-error="error">
474
+ * <p>Failed to load physics: {{ error }}</p>
475
+ * </ng-template>
476
+ * </ngtr-physics>
477
+ * ```
478
+ */
341
479
  class NgtrPhysicsFallback {
480
+ /** Type guard for template context */
342
481
  static ngTemplateContextGuard(_, ctx) {
343
482
  return true;
344
483
  }
@@ -349,7 +488,29 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
349
488
  type: Directive,
350
489
  args: [{ selector: 'ng-template[rapierFallback]' }]
351
490
  }] });
491
+ /**
492
+ * Main physics component that creates and manages a Rapier physics world.
493
+ * Wrap your 3D scene content in this component to enable physics simulation.
494
+ *
495
+ * The component lazily loads the Rapier WASM module and provides the physics
496
+ * context to all child components.
497
+ *
498
+ * @example
499
+ * ```html
500
+ * <ngtr-physics [options]="{ gravity: [0, -9.81, 0], debug: true }">
501
+ * <ng-template>
502
+ * <ngt-object3D rigidBody>
503
+ * <ngt-mesh>
504
+ * <ngt-box-geometry />
505
+ * <ngt-mesh-standard-material />
506
+ * </ngt-mesh>
507
+ * </ngt-object3D>
508
+ * </ng-template>
509
+ * </ngtr-physics>
510
+ * ```
511
+ */
352
512
  class NgtrPhysics {
513
+ /** Physics configuration options */
353
514
  options = input(defaultOptions$1, { ...(ngDevMode ? { debugName: "options" } : {}), transform: mergeInputs(defaultOptions$1) });
354
515
  content = contentChild.required(TemplateRef);
355
516
  fallbackContent = contentChild(NgtrPhysicsFallback, { ...(ngDevMode ? { debugName: "fallbackContent" } : {}), read: TemplateRef });
@@ -365,27 +526,59 @@ class NgtrPhysics {
365
526
  lengthUnit = pick(this.options, 'lengthUnit');
366
527
  timeStep = pick(this.options, 'timeStep');
367
528
  interpolate = pick(this.options, 'interpolate');
529
+ /** Whether the physics simulation is paused */
368
530
  paused = pick(this.options, 'paused');
369
531
  debug = pick(this.options, 'debug');
532
+ /** The default collider type for automatic collider generation */
370
533
  colliders = pick(this.options, 'colliders');
371
534
  vGravity = vector3(this.options, 'gravity');
372
535
  store = injectStore();
373
536
  rapierConstruct = signal(null, ...(ngDevMode ? [{ debugName: "rapierConstruct" }] : []));
374
537
  rapierError = signal(null, ...(ngDevMode ? [{ debugName: "rapierError" }] : []));
538
+ /** The loaded Rapier module, null if not yet loaded */
375
539
  rapier = this.rapierConstruct.asReadonly();
376
540
  ready = computed(() => !!this.rapier(), ...(ngDevMode ? [{ debugName: "ready" }] : []));
541
+ /** Singleton proxy to the Rapier physics world */
377
542
  worldSingleton = computed(() => {
378
543
  const rapier = this.rapier();
379
544
  if (!rapier)
380
545
  return null;
381
546
  return createSingletonProxy(() => new rapier.World(untracked(this.vGravity)));
382
547
  }, ...(ngDevMode ? [{ debugName: "worldSingleton" }] : []));
548
+ /** Map of rigid body states indexed by handle */
383
549
  rigidBodyStates = new Map();
550
+ /** Map of collider states indexed by handle */
384
551
  colliderStates = new Map();
552
+ /** Map of rigid body event handlers indexed by handle */
385
553
  rigidBodyEvents = new Map();
554
+ /** Map of collider event handlers indexed by handle */
386
555
  colliderEvents = new Map();
556
+ /** Callbacks to run before each physics step */
387
557
  beforeStepCallbacks = new Set();
558
+ /** Callbacks to run after each physics step */
388
559
  afterStepCallbacks = new Set();
560
+ /** Callbacks to filter contact pairs */
561
+ filterContactPairCallbacks = new Set();
562
+ /** Callbacks to filter intersection pairs */
563
+ filterIntersectionPairCallbacks = new Set();
564
+ hooks = {
565
+ filterContactPair: (...args) => {
566
+ for (const callback of this.filterContactPairCallbacks) {
567
+ const result = callback(...args);
568
+ if (result !== null)
569
+ return result;
570
+ }
571
+ return null;
572
+ },
573
+ filterIntersectionPair: (...args) => {
574
+ for (const callback of this.filterIntersectionPairCallbacks) {
575
+ const result = callback(...args);
576
+ if (result === false)
577
+ return false;
578
+ }
579
+ return true;
580
+ },
581
+ };
389
582
  eventQueue = computed(() => {
390
583
  const rapier = this.rapier();
391
584
  if (!rapier)
@@ -412,6 +605,13 @@ class NgtrPhysics {
412
605
  }
413
606
  });
414
607
  }
608
+ /**
609
+ * Steps the physics simulation forward by the given delta time.
610
+ * This is called automatically by the frame stepper, but can be called manually
611
+ * if you need custom control over the simulation timing.
612
+ *
613
+ * @param delta - Time in seconds since the last step
614
+ */
415
615
  step(delta) {
416
616
  if (!this.paused()) {
417
617
  this.internalStep(delta);
@@ -454,7 +654,8 @@ class NgtrPhysics {
454
654
  callback(world);
455
655
  });
456
656
  world.timestep = innerDelta;
457
- world.step(eventQueue);
657
+ const hasHooks = this.filterContactPairCallbacks.size > 0 || this.filterIntersectionPairCallbacks.size > 0;
658
+ world.step(eventQueue, hasHooks ? this.hooks : undefined);
458
659
  // Trigger afterStep callbacks
459
660
  this.afterStepCallbacks.forEach((callback) => {
460
661
  callback(world);
@@ -699,6 +900,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
699
900
  const colliderDefaultOptions = {
700
901
  contactSkin: 0,
701
902
  };
903
+ /**
904
+ * Base directive for creating colliders in the physics simulation.
905
+ * This directive can be used to create any type of collider by specifying the shape.
906
+ *
907
+ * For convenience, use the specific collider directives like `NgtrCuboidCollider`,
908
+ * `NgtrBallCollider`, etc., which provide type-safe arguments.
909
+ *
910
+ * @example
911
+ * ```html
912
+ * <ngt-object3D [collider]="'cuboid'" [args]="[1, 1, 1]" [position]="[0, 5, 0]" />
913
+ * ```
914
+ */
702
915
  class NgtrAnyCollider {
703
916
  position = input([0, 0, 0], ...(ngDevMode ? [{ debugName: "position" }] : []));
704
917
  rotation = input(...(ngDevMode ? [undefined, { debugName: "rotation" }] : []));
@@ -989,12 +1202,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
989
1202
  type: Directive,
990
1203
  args: [{ selector: 'ngt-object3D[collider]' }]
991
1204
  }], ctorParameters: () => [], propDecorators: { position: [{ type: i0.Input, args: [{ isSignal: true, alias: "position", required: false }] }], rotation: [{ type: i0.Input, args: [{ isSignal: true, alias: "rotation", required: false }] }], scale: [{ type: i0.Input, args: [{ isSignal: true, alias: "scale", required: false }] }], quaternion: [{ type: i0.Input, args: [{ isSignal: true, alias: "quaternion", required: false }] }], userData: [{ type: i0.Input, args: [{ isSignal: true, alias: "userData", required: false }] }], name: [{ type: i0.Input, args: [{ isSignal: true, alias: "name", required: false }] }], options: [{ type: i0.Input, args: [{ isSignal: true, alias: "options", required: false }] }], shape: [{ type: i0.Input, args: [{ isSignal: true, alias: "collider", required: false }] }, { type: i0.Output, args: ["colliderChange"] }], args: [{ type: i0.Input, args: [{ isSignal: true, alias: "args", required: false }] }, { type: i0.Output, args: ["argsChange"] }], collisionEnter: [{ type: i0.Output, args: ["collisionEnter"] }], collisionExit: [{ type: i0.Output, args: ["collisionExit"] }], intersectionEnter: [{ type: i0.Output, args: ["intersectionEnter"] }], intersectionExit: [{ type: i0.Output, args: ["intersectionExit"] }], contactForce: [{ type: i0.Output, args: ["contactForce"] }] } });
1205
+ /** Maps rigid body type strings to Rapier body type enum values */
992
1206
  const RIGID_BODY_TYPE_MAP = {
993
1207
  fixed: 1,
994
1208
  dynamic: 0,
995
1209
  kinematicPosition: 2,
996
1210
  kinematicVelocity: 3,
997
1211
  };
1212
+ /**
1213
+ * Default options for rigid bodies.
1214
+ * These values are used when specific options are not provided.
1215
+ */
998
1216
  const rigidBodyDefaultOptions = {
999
1217
  canSleep: true,
1000
1218
  linearVelocity: [0, 0, 0],
@@ -1005,6 +1223,38 @@ const rigidBodyDefaultOptions = {
1005
1223
  softCcdPrediction: 0,
1006
1224
  contactSkin: 0,
1007
1225
  };
1226
+ /**
1227
+ * Component that creates a rigid body in the physics simulation.
1228
+ * Rigid bodies can be dynamic (simulated), fixed (static), or kinematic (user-controlled).
1229
+ *
1230
+ * Child meshes automatically generate colliders based on their geometry.
1231
+ * The collider type can be controlled via the `colliders` option.
1232
+ *
1233
+ * @example
1234
+ * ```html
1235
+ * <!-- Dynamic rigid body with automatic colliders -->
1236
+ * <ngt-object3D rigidBody [position]="[0, 5, 0]">
1237
+ * <ngt-mesh>
1238
+ * <ngt-box-geometry />
1239
+ * <ngt-mesh-standard-material />
1240
+ * </ngt-mesh>
1241
+ * </ngt-object3D>
1242
+ *
1243
+ * <!-- Fixed (static) rigid body -->
1244
+ * <ngt-object3D rigidBody="fixed" [position]="[0, -1, 0]">
1245
+ * <ngt-mesh>
1246
+ * <ngt-plane-geometry [args]="[100, 100]" />
1247
+ * </ngt-mesh>
1248
+ * </ngt-object3D>
1249
+ *
1250
+ * <!-- Kinematic rigid body -->
1251
+ * <ngt-object3D rigidBody="kinematicPosition" #kinematicBody="rigidBody">
1252
+ * <ngt-mesh>
1253
+ * <ngt-sphere-geometry />
1254
+ * </ngt-mesh>
1255
+ * </ngt-object3D>
1256
+ * ```
1257
+ */
1008
1258
  class NgtrRigidBody {
1009
1259
  type = input.required({ ...(ngDevMode ? { debugName: "type" } : {}), alias: 'rigidBody',
1010
1260
  transform: (value) => {
@@ -1333,248 +1583,470 @@ const ANY_COLLIDER_HOST_DIRECTIVE = {
1333
1583
  inputs: ['options', 'name', 'scale', 'position', 'quaternion', 'rotation', 'userData'],
1334
1584
  outputs: ['collisionEnter', 'collisionExit', 'intersectionEnter', 'intersectionExit', 'contactForce'],
1335
1585
  };
1586
+ /**
1587
+ * Creates a cuboid (box) collider with specified half-extents.
1588
+ *
1589
+ * @example
1590
+ * ```html
1591
+ * <ngt-object3D [cuboidCollider]="[1, 0.5, 2]" [position]="[0, 0, 0]" />
1592
+ * ```
1593
+ */
1336
1594
  class NgtrCuboidCollider {
1337
1595
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'cuboidCollider' });
1596
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1597
+ collider = this.anyCollider.collider;
1338
1598
  constructor() {
1339
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1340
- anyCollider.setShape('cuboid');
1599
+ this.anyCollider.setShape('cuboid');
1341
1600
  effect(() => {
1342
- anyCollider.setArgs(this.args());
1601
+ this.anyCollider.setArgs(this.args());
1343
1602
  });
1344
1603
  }
1345
1604
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCuboidCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1346
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCuboidCollider, isStandalone: true, selector: "ngt-object3D[cuboidCollider]", inputs: { args: { classPropertyName: "args", publicName: "cuboidCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1605
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCuboidCollider, isStandalone: true, selector: "ngt-object3D[cuboidCollider]", inputs: { args: { classPropertyName: "args", publicName: "cuboidCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["cuboidCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1347
1606
  }
1348
1607
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCuboidCollider, decorators: [{
1349
1608
  type: Directive,
1350
- args: [{ selector: 'ngt-object3D[cuboidCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1609
+ args: [{
1610
+ selector: 'ngt-object3D[cuboidCollider]',
1611
+ exportAs: 'cuboidCollider',
1612
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1613
+ }]
1351
1614
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "cuboidCollider", required: true }] }] } });
1615
+ /**
1616
+ * Creates a capsule collider with specified half-height and radius.
1617
+ *
1618
+ * @example
1619
+ * ```html
1620
+ * <ngt-object3D [capsuleCollider]="[0.5, 0.25]" [position]="[0, 1, 0]" />
1621
+ * ```
1622
+ */
1352
1623
  class NgtrCapsuleCollider {
1353
1624
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'capsuleCollider' });
1625
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1626
+ collider = this.anyCollider.collider;
1354
1627
  constructor() {
1355
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1356
- anyCollider.setShape('capsule');
1628
+ this.anyCollider.setShape('capsule');
1357
1629
  effect(() => {
1358
- anyCollider.setArgs(this.args());
1630
+ this.anyCollider.setArgs(this.args());
1359
1631
  });
1360
1632
  }
1361
1633
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCapsuleCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1362
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCapsuleCollider, isStandalone: true, selector: "ngt-object3D[capsuleCollider]", inputs: { args: { classPropertyName: "args", publicName: "capsuleCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1634
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCapsuleCollider, isStandalone: true, selector: "ngt-object3D[capsuleCollider]", inputs: { args: { classPropertyName: "args", publicName: "capsuleCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["capsuleCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1363
1635
  }
1364
1636
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCapsuleCollider, decorators: [{
1365
1637
  type: Directive,
1366
- args: [{ selector: 'ngt-object3D[capsuleCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1638
+ args: [{
1639
+ selector: 'ngt-object3D[capsuleCollider]',
1640
+ exportAs: 'capsuleCollider',
1641
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1642
+ }]
1367
1643
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "capsuleCollider", required: true }] }] } });
1644
+ /**
1645
+ * Creates a spherical (ball) collider with specified radius.
1646
+ *
1647
+ * @example
1648
+ * ```html
1649
+ * <ngt-object3D [ballCollider]="[0.5]" [position]="[0, 2, 0]" />
1650
+ * ```
1651
+ */
1368
1652
  class NgtrBallCollider {
1369
1653
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'ballCollider' });
1654
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1655
+ collider = this.anyCollider.collider;
1370
1656
  constructor() {
1371
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1372
- anyCollider.setShape('ball');
1657
+ this.anyCollider.setShape('ball');
1373
1658
  effect(() => {
1374
- anyCollider.setArgs(this.args());
1659
+ this.anyCollider.setArgs(this.args());
1375
1660
  });
1376
1661
  }
1377
1662
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrBallCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1378
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrBallCollider, isStandalone: true, selector: "ngt-object3D[ballCollider]", inputs: { args: { classPropertyName: "args", publicName: "ballCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1663
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrBallCollider, isStandalone: true, selector: "ngt-object3D[ballCollider]", inputs: { args: { classPropertyName: "args", publicName: "ballCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["ballCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1379
1664
  }
1380
1665
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrBallCollider, decorators: [{
1381
1666
  type: Directive,
1382
- args: [{ selector: 'ngt-object3D[ballCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1667
+ args: [{
1668
+ selector: 'ngt-object3D[ballCollider]',
1669
+ exportAs: 'ballCollider',
1670
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1671
+ }]
1383
1672
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "ballCollider", required: true }] }] } });
1673
+ /**
1674
+ * Creates a convex hull collider from an array of vertices.
1675
+ * The convex hull is computed from the provided points.
1676
+ *
1677
+ * @example
1678
+ * ```html
1679
+ * <ngt-object3D [convexHullCollider]="[vertices]" />
1680
+ * ```
1681
+ */
1384
1682
  class NgtrConvexHullCollider {
1385
1683
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'convexHullCollider' });
1684
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1685
+ collider = this.anyCollider.collider;
1386
1686
  constructor() {
1387
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1388
- anyCollider.setShape('convexHull');
1687
+ this.anyCollider.setShape('convexHull');
1389
1688
  effect(() => {
1390
- anyCollider.setArgs(this.args());
1689
+ this.anyCollider.setArgs(this.args());
1391
1690
  });
1392
1691
  }
1393
1692
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConvexHullCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1394
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConvexHullCollider, isStandalone: true, selector: "ngt-object3D[convexHullCollider]", inputs: { args: { classPropertyName: "args", publicName: "convexHullCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1693
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConvexHullCollider, isStandalone: true, selector: "ngt-object3D[convexHullCollider]", inputs: { args: { classPropertyName: "args", publicName: "convexHullCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["convexHullCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1395
1694
  }
1396
1695
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConvexHullCollider, decorators: [{
1397
1696
  type: Directive,
1398
- args: [{ selector: 'ngt-object3D[convexHullCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1697
+ args: [{
1698
+ selector: 'ngt-object3D[convexHullCollider]',
1699
+ exportAs: 'convexHullCollider',
1700
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1701
+ }]
1399
1702
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "convexHullCollider", required: true }] }] } });
1703
+ /**
1704
+ * Creates a heightfield collider for terrain-like surfaces.
1705
+ * The heightfield is defined by a grid of height values.
1706
+ *
1707
+ * @example
1708
+ * ```html
1709
+ * <ngt-object3D [heightfieldCollider]="[width, height, heights, scale]" />
1710
+ * ```
1711
+ */
1400
1712
  class NgtrHeightfieldCollider {
1401
1713
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'heightfieldCollider' });
1714
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1715
+ collider = this.anyCollider.collider;
1402
1716
  constructor() {
1403
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1404
- anyCollider.setShape('heightfield');
1717
+ this.anyCollider.setShape('heightfield');
1405
1718
  effect(() => {
1406
- anyCollider.setArgs(this.args());
1719
+ this.anyCollider.setArgs(this.args());
1407
1720
  });
1408
1721
  }
1409
1722
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrHeightfieldCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1410
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrHeightfieldCollider, isStandalone: true, selector: "ngt-object3D[heightfieldCollider]", inputs: { args: { classPropertyName: "args", publicName: "heightfieldCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1723
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrHeightfieldCollider, isStandalone: true, selector: "ngt-object3D[heightfieldCollider]", inputs: { args: { classPropertyName: "args", publicName: "heightfieldCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["heightfieldCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1411
1724
  }
1412
1725
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrHeightfieldCollider, decorators: [{
1413
1726
  type: Directive,
1414
- args: [{ selector: 'ngt-object3D[heightfieldCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1727
+ args: [{
1728
+ selector: 'ngt-object3D[heightfieldCollider]',
1729
+ exportAs: 'heightfieldCollider',
1730
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1731
+ }]
1415
1732
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "heightfieldCollider", required: true }] }] } });
1733
+ /**
1734
+ * Creates a triangle mesh collider for exact collision shapes.
1735
+ * Note: Trimesh colliders are computationally expensive and should be used sparingly.
1736
+ *
1737
+ * @example
1738
+ * ```html
1739
+ * <ngt-object3D [trimeshCollider]="[vertices, indices]" />
1740
+ * ```
1741
+ */
1416
1742
  class NgtrTrimeshCollider {
1417
1743
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'trimeshCollider' });
1744
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1745
+ collider = this.anyCollider.collider;
1418
1746
  constructor() {
1419
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1420
- anyCollider.setShape('trimesh');
1747
+ this.anyCollider.setShape('trimesh');
1421
1748
  effect(() => {
1422
- anyCollider.setArgs(this.args());
1749
+ this.anyCollider.setArgs(this.args());
1423
1750
  });
1424
1751
  }
1425
1752
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrTrimeshCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1426
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrTrimeshCollider, isStandalone: true, selector: "ngt-object3D[trimeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "trimeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1753
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrTrimeshCollider, isStandalone: true, selector: "ngt-object3D[trimeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "trimeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["trimeshCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1427
1754
  }
1428
1755
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrTrimeshCollider, decorators: [{
1429
1756
  type: Directive,
1430
- args: [{ selector: 'ngt-object3D[trimeshCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1757
+ args: [{
1758
+ selector: 'ngt-object3D[trimeshCollider]',
1759
+ exportAs: 'trimeshCollider',
1760
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1761
+ }]
1431
1762
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "trimeshCollider", required: true }] }] } });
1763
+ /**
1764
+ * Creates a polyline collider from connected line segments.
1765
+ *
1766
+ * @example
1767
+ * ```html
1768
+ * <ngt-object3D [polylineCollider]="[vertices, indices]" />
1769
+ * ```
1770
+ */
1432
1771
  class NgtrPolylineCollider {
1433
1772
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'polylineCollider' });
1773
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1774
+ collider = this.anyCollider.collider;
1434
1775
  constructor() {
1435
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1436
- anyCollider.setShape('polyline');
1776
+ this.anyCollider.setShape('polyline');
1437
1777
  effect(() => {
1438
- anyCollider.setArgs(this.args());
1778
+ this.anyCollider.setArgs(this.args());
1439
1779
  });
1440
1780
  }
1441
1781
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrPolylineCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1442
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrPolylineCollider, isStandalone: true, selector: "ngt-object3D[polylineCollider]", inputs: { args: { classPropertyName: "args", publicName: "polylineCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1782
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrPolylineCollider, isStandalone: true, selector: "ngt-object3D[polylineCollider]", inputs: { args: { classPropertyName: "args", publicName: "polylineCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["polylineCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1443
1783
  }
1444
1784
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrPolylineCollider, decorators: [{
1445
1785
  type: Directive,
1446
- args: [{ selector: 'ngt-object3D[polylineCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1786
+ args: [{
1787
+ selector: 'ngt-object3D[polylineCollider]',
1788
+ exportAs: 'polylineCollider',
1789
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1790
+ }]
1447
1791
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "polylineCollider", required: true }] }] } });
1792
+ /**
1793
+ * Creates a cuboid collider with rounded corners.
1794
+ *
1795
+ * @example
1796
+ * ```html
1797
+ * <ngt-object3D [roundCuboidCollider]="[1, 0.5, 2, 0.1]" />
1798
+ * ```
1799
+ */
1448
1800
  class NgtrRoundCuboidCollider {
1449
1801
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'roundCuboidCollider' });
1802
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1803
+ collider = this.anyCollider.collider;
1450
1804
  constructor() {
1451
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1452
- anyCollider.setShape('roundCuboid');
1805
+ this.anyCollider.setShape('roundCuboid');
1453
1806
  effect(() => {
1454
- anyCollider.setArgs(this.args());
1807
+ this.anyCollider.setArgs(this.args());
1455
1808
  });
1456
1809
  }
1457
1810
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundCuboidCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1458
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundCuboidCollider, isStandalone: true, selector: "ngt-object3D[roundCuboidCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundCuboidCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1811
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundCuboidCollider, isStandalone: true, selector: "ngt-object3D[roundCuboidCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundCuboidCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["roundCuboidCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1459
1812
  }
1460
1813
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundCuboidCollider, decorators: [{
1461
1814
  type: Directive,
1462
- args: [{ selector: 'ngt-object3D[roundCuboidCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1815
+ args: [{
1816
+ selector: 'ngt-object3D[roundCuboidCollider]',
1817
+ exportAs: 'roundCuboidCollider',
1818
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1819
+ }]
1463
1820
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "roundCuboidCollider", required: true }] }] } });
1821
+ /**
1822
+ * Creates a cylinder collider with specified half-height and radius.
1823
+ *
1824
+ * @example
1825
+ * ```html
1826
+ * <ngt-object3D [cylinderCollider]="[1, 0.5]" />
1827
+ * ```
1828
+ */
1464
1829
  class NgtrCylinderCollider {
1465
1830
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'cylinderCollider' });
1831
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1832
+ collider = this.anyCollider.collider;
1466
1833
  constructor() {
1467
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1468
- anyCollider.setShape('cylinder');
1834
+ this.anyCollider.setShape('cylinder');
1469
1835
  effect(() => {
1470
- anyCollider.setArgs(this.args());
1836
+ this.anyCollider.setArgs(this.args());
1471
1837
  });
1472
1838
  }
1473
1839
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCylinderCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1474
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCylinderCollider, isStandalone: true, selector: "ngt-object3D[cylinderCollider]", inputs: { args: { classPropertyName: "args", publicName: "cylinderCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1840
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrCylinderCollider, isStandalone: true, selector: "ngt-object3D[cylinderCollider]", inputs: { args: { classPropertyName: "args", publicName: "cylinderCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["cylinderCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1475
1841
  }
1476
1842
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrCylinderCollider, decorators: [{
1477
1843
  type: Directive,
1478
- args: [{ selector: 'ngt-object3D[cylinderCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1844
+ args: [{
1845
+ selector: 'ngt-object3D[cylinderCollider]',
1846
+ exportAs: 'cylinderCollider',
1847
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1848
+ }]
1479
1849
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "cylinderCollider", required: true }] }] } });
1850
+ /**
1851
+ * Creates a cylinder collider with rounded edges.
1852
+ *
1853
+ * @example
1854
+ * ```html
1855
+ * <ngt-object3D [roundCylinderCollider]="[1, 0.5, 0.05]" />
1856
+ * ```
1857
+ */
1480
1858
  class NgtrRoundCylinderCollider {
1481
1859
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'roundCylinderCollider' });
1860
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1861
+ collider = this.anyCollider.collider;
1482
1862
  constructor() {
1483
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1484
- anyCollider.setShape('roundCylinder');
1863
+ this.anyCollider.setShape('roundCylinder');
1485
1864
  effect(() => {
1486
- anyCollider.setArgs(this.args());
1865
+ this.anyCollider.setArgs(this.args());
1487
1866
  });
1488
1867
  }
1489
1868
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundCylinderCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1490
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundCylinderCollider, isStandalone: true, selector: "ngt-object3D[roundCylinderCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundCylinderCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1869
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundCylinderCollider, isStandalone: true, selector: "ngt-object3D[roundCylinderCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundCylinderCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["roundCylinderCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1491
1870
  }
1492
1871
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundCylinderCollider, decorators: [{
1493
1872
  type: Directive,
1494
- args: [{ selector: 'ngt-object3D[roundCylinderCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1873
+ args: [{
1874
+ selector: 'ngt-object3D[roundCylinderCollider]',
1875
+ exportAs: 'roundCylinderCollider',
1876
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1877
+ }]
1495
1878
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "roundCylinderCollider", required: true }] }] } });
1879
+ /**
1880
+ * Creates a cone collider with specified half-height and base radius.
1881
+ *
1882
+ * @example
1883
+ * ```html
1884
+ * <ngt-object3D [coneCollider]="[1, 0.5]" />
1885
+ * ```
1886
+ */
1496
1887
  class NgtrConeCollider {
1497
1888
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'coneCollider' });
1889
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1890
+ collider = this.anyCollider.collider;
1498
1891
  constructor() {
1499
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1500
- anyCollider.setShape('cone');
1892
+ this.anyCollider.setShape('cone');
1501
1893
  effect(() => {
1502
- anyCollider.setArgs(this.args());
1894
+ this.anyCollider.setArgs(this.args());
1503
1895
  });
1504
1896
  }
1505
1897
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConeCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1506
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConeCollider, isStandalone: true, selector: "ngt-object3D[coneCollider]", inputs: { args: { classPropertyName: "args", publicName: "coneCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1898
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConeCollider, isStandalone: true, selector: "ngt-object3D[coneCollider]", inputs: { args: { classPropertyName: "args", publicName: "coneCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["coneCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1507
1899
  }
1508
1900
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConeCollider, decorators: [{
1509
1901
  type: Directive,
1510
- args: [{ selector: 'ngt-object3D[coneCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1902
+ args: [{
1903
+ selector: 'ngt-object3D[coneCollider]',
1904
+ exportAs: 'coneCollider',
1905
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1906
+ }]
1511
1907
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "coneCollider", required: true }] }] } });
1908
+ /**
1909
+ * Creates a cone collider with rounded edges.
1910
+ *
1911
+ * @example
1912
+ * ```html
1913
+ * <ngt-object3D [roundConeCollider]="[1, 0.5, 0.05]" />
1914
+ * ```
1915
+ */
1512
1916
  class NgtrRoundConeCollider {
1513
1917
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'roundConeCollider' });
1918
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1919
+ collider = this.anyCollider.collider;
1514
1920
  constructor() {
1515
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1516
- anyCollider.setShape('roundCone');
1921
+ this.anyCollider.setShape('roundCone');
1517
1922
  effect(() => {
1518
- anyCollider.setArgs(this.args());
1923
+ this.anyCollider.setArgs(this.args());
1519
1924
  });
1520
1925
  }
1521
1926
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConeCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1522
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConeCollider, isStandalone: true, selector: "ngt-object3D[roundConeCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConeCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1927
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConeCollider, isStandalone: true, selector: "ngt-object3D[roundConeCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConeCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["roundConeCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1523
1928
  }
1524
1929
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConeCollider, decorators: [{
1525
1930
  type: Directive,
1526
- args: [{ selector: 'ngt-object3D[roundConeCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1931
+ args: [{
1932
+ selector: 'ngt-object3D[roundConeCollider]',
1933
+ exportAs: 'roundConeCollider',
1934
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1935
+ }]
1527
1936
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "roundConeCollider", required: true }] }] } });
1937
+ /**
1938
+ * Creates a convex mesh collider from vertices and indices.
1939
+ *
1940
+ * @example
1941
+ * ```html
1942
+ * <ngt-object3D [convexMeshCollider]="[vertices, indices]" />
1943
+ * ```
1944
+ */
1528
1945
  class NgtrConvexMeshCollider {
1529
1946
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'convexMeshCollider' });
1947
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1948
+ collider = this.anyCollider.collider;
1530
1949
  constructor() {
1531
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1532
- anyCollider.setShape('convexMesh');
1950
+ this.anyCollider.setShape('convexMesh');
1533
1951
  effect(() => {
1534
- anyCollider.setArgs(this.args());
1952
+ this.anyCollider.setArgs(this.args());
1535
1953
  });
1536
1954
  }
1537
1955
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConvexMeshCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1538
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConvexMeshCollider, isStandalone: true, selector: "ngt-object3D[convexMeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "convexMeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1956
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrConvexMeshCollider, isStandalone: true, selector: "ngt-object3D[convexMeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "convexMeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["convexMeshCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1539
1957
  }
1540
1958
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrConvexMeshCollider, decorators: [{
1541
1959
  type: Directive,
1542
- args: [{ selector: 'ngt-object3D[convexMeshCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1960
+ args: [{
1961
+ selector: 'ngt-object3D[convexMeshCollider]',
1962
+ exportAs: 'convexMeshCollider',
1963
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1964
+ }]
1543
1965
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "convexMeshCollider", required: true }] }] } });
1966
+ /**
1967
+ * Creates a convex hull collider with rounded edges.
1968
+ *
1969
+ * @example
1970
+ * ```html
1971
+ * <ngt-object3D [roundConvexHullCollider]="[vertices, indices, 0.05]" />
1972
+ * ```
1973
+ */
1544
1974
  class NgtrRoundConvexHullCollider {
1545
1975
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'roundConvexHullCollider' });
1976
+ anyCollider = inject(NgtrAnyCollider, { host: true });
1977
+ collider = this.anyCollider.collider;
1546
1978
  constructor() {
1547
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1548
- anyCollider.setShape('roundConvexHull');
1979
+ this.anyCollider.setShape('roundConvexHull');
1549
1980
  effect(() => {
1550
- anyCollider.setArgs(this.args());
1981
+ this.anyCollider.setArgs(this.args());
1551
1982
  });
1552
1983
  }
1553
1984
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConvexHullCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1554
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConvexHullCollider, isStandalone: true, selector: "ngt-object3D[roundConvexHullCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConvexHullCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1985
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConvexHullCollider, isStandalone: true, selector: "ngt-object3D[roundConvexHullCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConvexHullCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["roundConvexHullCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1555
1986
  }
1556
1987
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConvexHullCollider, decorators: [{
1557
1988
  type: Directive,
1558
- args: [{ selector: 'ngt-object3D[roundConvexHullCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
1989
+ args: [{
1990
+ selector: 'ngt-object3D[roundConvexHullCollider]',
1991
+ exportAs: 'roundConvexHullCollider',
1992
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
1993
+ }]
1559
1994
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "roundConvexHullCollider", required: true }] }] } });
1995
+ /**
1996
+ * Creates a convex mesh collider with rounded edges.
1997
+ *
1998
+ * @example
1999
+ * ```html
2000
+ * <ngt-object3D [roundConvexMeshCollider]="[vertices, indices, 0.05]" />
2001
+ * ```
2002
+ */
1560
2003
  class NgtrRoundConvexMeshCollider {
1561
2004
  args = input.required({ ...(ngDevMode ? { debugName: "args" } : {}), alias: 'roundConvexMeshCollider' });
2005
+ anyCollider = inject(NgtrAnyCollider, { host: true });
2006
+ collider = this.anyCollider.collider;
1562
2007
  constructor() {
1563
- const anyCollider = inject(NgtrAnyCollider, { host: true });
1564
- anyCollider.setShape('roundConvexMesh');
2008
+ this.anyCollider.setShape('roundConvexMesh');
1565
2009
  effect(() => {
1566
- anyCollider.setArgs(this.args());
2010
+ this.anyCollider.setArgs(this.args());
1567
2011
  });
1568
2012
  }
1569
2013
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConvexMeshCollider, deps: [], target: i0.ɵɵFactoryTarget.Directive });
1570
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConvexMeshCollider, isStandalone: true, selector: "ngt-object3D[roundConvexMeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConvexMeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
2014
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.0.6", type: NgtrRoundConvexMeshCollider, isStandalone: true, selector: "ngt-object3D[roundConvexMeshCollider]", inputs: { args: { classPropertyName: "args", publicName: "roundConvexMeshCollider", isSignal: true, isRequired: true, transformFunction: null } }, exportAs: ["roundConvexMeshCollider"], hostDirectives: [{ directive: NgtrAnyCollider, inputs: ["options", "options", "name", "name", "scale", "scale", "position", "position", "quaternion", "quaternion", "rotation", "rotation", "userData", "userData"], outputs: ["collisionEnter", "collisionEnter", "collisionExit", "collisionExit", "intersectionEnter", "intersectionEnter", "intersectionExit", "intersectionExit", "contactForce", "contactForce"] }], ngImport: i0 });
1571
2015
  }
1572
2016
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: NgtrRoundConvexMeshCollider, decorators: [{
1573
2017
  type: Directive,
1574
- args: [{ selector: 'ngt-object3D[roundConvexMeshCollider]', hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE] }]
2018
+ args: [{
2019
+ selector: 'ngt-object3D[roundConvexMeshCollider]',
2020
+ exportAs: 'roundConvexMeshCollider',
2021
+ hostDirectives: [ANY_COLLIDER_HOST_DIRECTIVE],
2022
+ }]
1575
2023
  }], ctorParameters: () => [], propDecorators: { args: [{ type: i0.Input, args: [{ isSignal: true, alias: "roundConvexMeshCollider", required: true }] }] } });
1576
2024
 
1577
2025
  const defaultOptions = rigidBodyDefaultOptions;
2026
+ /**
2027
+ * Component for creating multiple rigid bodies from a single InstancedMesh.
2028
+ * This is highly efficient for scenes with many identical physics objects.
2029
+ *
2030
+ * Each instance gets its own rigid body but shares the same geometry for rendering.
2031
+ * The component automatically syncs instance matrices with physics simulation.
2032
+ *
2033
+ * @example
2034
+ * ```html
2035
+ * <ngt-object3D [instancedRigidBodies]="instances">
2036
+ * <ngt-instanced-mesh [count]="instances.length" castShadow receiveShadow>
2037
+ * <ngt-sphere-geometry [args]="[0.5]" />
2038
+ * <ngt-mesh-standard-material color="orange" />
2039
+ * </ngt-instanced-mesh>
2040
+ * </ngt-object3D>
2041
+ * ```
2042
+ *
2043
+ * ```typescript
2044
+ * instances = Array.from({ length: 100 }, (_, i) => ({
2045
+ * key: i,
2046
+ * position: [Math.random() * 10, Math.random() * 10, 0] as [number, number, number],
2047
+ * }));
2048
+ * ```
2049
+ */
1578
2050
  class NgtrInstancedRigidBodies {
1579
2051
  position = input([0, 0, 0], ...(ngDevMode ? [{ debugName: "position" }] : []));
1580
2052
  rotation = input(...(ngDevMode ? [undefined, { debugName: "rotation" }] : []));
@@ -1817,10 +2289,27 @@ function createJoint(jointDataFn) {
1817
2289
  };
1818
2290
  }
1819
2291
  /**
1820
- * A fixed joint ensures that two rigid-bodies don't move relative to each other.
2292
+ * Creates a fixed joint that prevents any relative movement between two rigid bodies.
1821
2293
  * Fixed joints are characterized by one local frame (represented by an isometry) on each rigid-body.
1822
2294
  * The fixed-joint makes these frames coincide in world-space.
1823
2295
  *
2296
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2297
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2298
+ * @param options - Joint configuration with data and optional injector
2299
+ * @returns Signal containing the created joint or null
2300
+ *
2301
+ * @example
2302
+ * ```typescript
2303
+ * fixedJoint(bodyA, bodyB, {
2304
+ * data: {
2305
+ * body1Anchor: [0, 0, 0],
2306
+ * body1LocalFrame: [0, 0, 0, 1],
2307
+ * body2Anchor: [0, 0, 0],
2308
+ * body2LocalFrame: [0, 0, 0, 1]
2309
+ * }
2310
+ * });
2311
+ * ```
2312
+ *
1824
2313
  * @category Hooks - Joints
1825
2314
  */
1826
2315
  const fixedJoint = createJoint((rapier, data) => rapier.JointData.fixed(vector3ToRapierVector(data.body1Anchor), quaternionToRapierQuaternion(data.body1LocalFrame), vector3ToRapierVector(data.body2Anchor), quaternionToRapierQuaternion(data.body2LocalFrame)));
@@ -1830,10 +2319,21 @@ const fixedJoint = createJoint((rapier, data) => rapier.JointData.fixed(vector3T
1830
2319
  */
1831
2320
  const injectFixedJoint = fixedJoint;
1832
2321
  /**
1833
- * The spherical joint ensures that two points on the local-spaces of two rigid-bodies always coincide (it prevents any relative
1834
- * translational motion at this points). This is typically used to simulate ragdolls arms, pendulums, etc.
1835
- * They are characterized by one local anchor on each rigid-body. Each anchor represents the location of the
1836
- * points that need to coincide on the local-space of each rigid-body.
2322
+ * Creates a spherical (ball-and-socket) joint that ensures two anchor points always coincide.
2323
+ * This prevents any relative translational motion at these points while allowing rotation.
2324
+ * Typically used to simulate ragdoll arms, pendulums, etc.
2325
+ *
2326
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2327
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2328
+ * @param options - Joint configuration with data and optional injector
2329
+ * @returns Signal containing the created joint or null
2330
+ *
2331
+ * @example
2332
+ * ```typescript
2333
+ * sphericalJoint(bodyA, bodyB, {
2334
+ * data: { body1Anchor: [0, -0.5, 0], body2Anchor: [0, 0.5, 0] }
2335
+ * });
2336
+ * ```
1837
2337
  *
1838
2338
  * @category Hooks - Joints
1839
2339
  */
@@ -1844,9 +2344,26 @@ const sphericalJoint = createJoint((rapier, data) => rapier.JointData.spherical(
1844
2344
  */
1845
2345
  const injectSphericalJoint = sphericalJoint;
1846
2346
  /**
1847
- * The revolute joint prevents any relative movement between two rigid-bodies, except for relative
1848
- * rotations along one axis. This is typically used to simulate wheels, fans, etc.
1849
- * They are characterized by one local anchor as well as one local axis on each rigid-body.
2347
+ * Creates a revolute (hinge) joint that allows rotation only around one axis.
2348
+ * Prevents any other relative movement between two rigid bodies.
2349
+ * Typically used to simulate wheels, doors, fans, etc.
2350
+ *
2351
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2352
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2353
+ * @param options - Joint configuration with data (including optional limits) and optional injector
2354
+ * @returns Signal containing the created joint or null
2355
+ *
2356
+ * @example
2357
+ * ```typescript
2358
+ * revoluteJoint(bodyA, bodyB, {
2359
+ * data: {
2360
+ * body1Anchor: [0, 0, 0],
2361
+ * body2Anchor: [0, 1, 0],
2362
+ * axis: [0, 1, 0],
2363
+ * limits: [-Math.PI / 2, Math.PI / 2]
2364
+ * }
2365
+ * });
2366
+ * ```
1850
2367
  *
1851
2368
  * @category Hooks - Joints
1852
2369
  */
@@ -1864,9 +2381,26 @@ const revoluteJoint = createJoint((rapier, data) => {
1864
2381
  */
1865
2382
  const injectRevoluteJoint = revoluteJoint;
1866
2383
  /**
1867
- * The prismatic joint prevents any relative movement between two rigid-bodies, except for relative translations along one axis.
1868
- * It is characterized by one local anchor as well as one local axis on each rigid-body. In 3D, an optional
1869
- * local tangent axis can be specified for each rigid-body.
2384
+ * Creates a prismatic (slider) joint that allows translation only along one axis.
2385
+ * Prevents any other relative movement between two rigid bodies.
2386
+ * Typically used to simulate pistons, sliding doors, etc.
2387
+ *
2388
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2389
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2390
+ * @param options - Joint configuration with data (including optional limits) and optional injector
2391
+ * @returns Signal containing the created joint or null
2392
+ *
2393
+ * @example
2394
+ * ```typescript
2395
+ * prismaticJoint(bodyA, bodyB, {
2396
+ * data: {
2397
+ * body1Anchor: [0, 0, 0],
2398
+ * body2Anchor: [2, 0, 0],
2399
+ * axis: [1, 0, 0],
2400
+ * limits: [-1, 1]
2401
+ * }
2402
+ * });
2403
+ * ```
1870
2404
  *
1871
2405
  * @category Hooks - Joints
1872
2406
  */
@@ -1884,7 +2418,25 @@ const prismaticJoint = createJoint((rapier, data) => {
1884
2418
  */
1885
2419
  const injectPrismaticJoint = prismaticJoint;
1886
2420
  /**
1887
- * The rope joint limits the max distance between two bodies.
2421
+ * Creates a rope joint that limits the maximum distance between two anchor points.
2422
+ * The bodies can move freely as long as the distance doesn't exceed the specified length.
2423
+ *
2424
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2425
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2426
+ * @param options - Joint configuration with data and optional injector
2427
+ * @returns Signal containing the created joint or null
2428
+ *
2429
+ * @example
2430
+ * ```typescript
2431
+ * ropeJoint(bodyA, bodyB, {
2432
+ * data: {
2433
+ * body1Anchor: [0, 0, 0],
2434
+ * body2Anchor: [0, 0, 0],
2435
+ * length: 5
2436
+ * }
2437
+ * });
2438
+ * ```
2439
+ *
1888
2440
  * @category Hooks - Joints
1889
2441
  */
1890
2442
  const ropeJoint = createJoint((rapier, data) => rapier.JointData.rope(data.length, vector3ToRapierVector(data.body1Anchor), vector3ToRapierVector(data.body2Anchor)));
@@ -1894,7 +2446,27 @@ const ropeJoint = createJoint((rapier, data) => rapier.JointData.rope(data.lengt
1894
2446
  */
1895
2447
  const injectRopeJoint = ropeJoint;
1896
2448
  /**
1897
- * The spring joint applies a force proportional to the distance between two objects.
2449
+ * Creates a spring joint that applies a force proportional to the distance between two anchor points.
2450
+ * The spring tries to maintain its rest length through spring forces.
2451
+ *
2452
+ * @param bodyA - First rigid body (can be RigidBody, ElementRef, or getter function)
2453
+ * @param bodyB - Second rigid body (can be RigidBody, ElementRef, or getter function)
2454
+ * @param options - Joint configuration with data and optional injector
2455
+ * @returns Signal containing the created joint or null
2456
+ *
2457
+ * @example
2458
+ * ```typescript
2459
+ * springJoint(bodyA, bodyB, {
2460
+ * data: {
2461
+ * body1Anchor: [0, 0, 0],
2462
+ * body2Anchor: [0, 0, 0],
2463
+ * restLength: 2,
2464
+ * stiffness: 100,
2465
+ * damping: 10
2466
+ * }
2467
+ * });
2468
+ * ```
2469
+ *
1898
2470
  * @category Hooks - Joints
1899
2471
  */
1900
2472
  const springJoint = createJoint((rapier, data) => {
@@ -1906,6 +2478,25 @@ const springJoint = createJoint((rapier, data) => {
1906
2478
  */
1907
2479
  const injectSpringJoint = springJoint;
1908
2480
 
2481
+ /**
2482
+ * Component that generates colliders based on child mesh geometries.
2483
+ * Use this when you want specific collider generation for a group of meshes
2484
+ * within a rigid body.
2485
+ *
2486
+ * This is useful when you want different parts of a complex object to have
2487
+ * different collider types than the parent rigid body's automatic colliders.
2488
+ *
2489
+ * @example
2490
+ * ```html
2491
+ * <ngt-object3D rigidBody [options]="{ colliders: false }">
2492
+ * <ngt-object3D [meshCollider]="'trimesh'">
2493
+ * <ngt-mesh>
2494
+ * <ngt-torus-geometry />
2495
+ * </ngt-mesh>
2496
+ * </ngt-object3D>
2497
+ * </ngt-object3D>
2498
+ * ```
2499
+ */
1909
2500
  class NgtrMeshCollider {
1910
2501
  colliders = input.required({ ...(ngDevMode ? { debugName: "colliders" } : {}), alias: 'meshCollider' });
1911
2502
  objectRef = inject(ElementRef);
@@ -1966,6 +2557,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImpor
1966
2557
  }]
1967
2558
  }], ctorParameters: () => [], propDecorators: { colliders: [{ type: i0.Input, args: [{ isSignal: true, alias: "meshCollider", required: true }] }] } });
1968
2559
 
2560
+ /**
2561
+ * Registers a callback to be executed before each physics world step.
2562
+ * Useful for applying forces, updating kinematic bodies, or other pre-step logic.
2563
+ *
2564
+ * The callback is automatically unregistered when the component is destroyed.
2565
+ *
2566
+ * @param callback - Function to call before each physics step, receives the Rapier World
2567
+ * @param injector - Optional injector for dependency injection context
2568
+ *
2569
+ * @example
2570
+ * ```typescript
2571
+ * beforePhysicsStep((world) => {
2572
+ * // Apply custom forces or update kinematic bodies
2573
+ * const body = world.getRigidBody(handle);
2574
+ * body?.applyImpulse({ x: 0, y: 10, z: 0 }, true);
2575
+ * });
2576
+ * ```
2577
+ */
1969
2578
  function beforePhysicsStep(callback, injector) {
1970
2579
  return assertInjector(beforePhysicsStep, injector, () => {
1971
2580
  const physics = inject(NgtrPhysics);
@@ -1975,6 +2584,25 @@ function beforePhysicsStep(callback, injector) {
1975
2584
  });
1976
2585
  });
1977
2586
  }
2587
+ /**
2588
+ * Registers a callback to be executed after each physics world step.
2589
+ * Useful for reading physics state, updating visuals, or other post-step logic.
2590
+ *
2591
+ * The callback is automatically unregistered when the component is destroyed.
2592
+ *
2593
+ * @param callback - Function to call after each physics step, receives the Rapier World
2594
+ * @param injector - Optional injector for dependency injection context
2595
+ *
2596
+ * @example
2597
+ * ```typescript
2598
+ * afterPhysicsStep((world) => {
2599
+ * // Read physics state after simulation
2600
+ * const body = world.getRigidBody(handle);
2601
+ * const position = body?.translation();
2602
+ * console.log('Body position:', position);
2603
+ * });
2604
+ * ```
2605
+ */
1978
2606
  function afterPhysicsStep(callback, injector) {
1979
2607
  return assertInjector(afterPhysicsStep, injector, () => {
1980
2608
  const physics = inject(NgtrPhysics);
@@ -1984,10 +2612,59 @@ function afterPhysicsStep(callback, injector) {
1984
2612
  });
1985
2613
  });
1986
2614
  }
2615
+ /**
2616
+ * Registers a callback to filter contact pairs.
2617
+ *
2618
+ * The callback determines if contact computation should happen between two colliders,
2619
+ * and how the constraints solver should behave for these contacts.
2620
+ *
2621
+ * This will only be executed if at least one of the involved colliders contains the
2622
+ * `ActiveHooks.FILTER_CONTACT_PAIRS` flag in its active hooks.
2623
+ *
2624
+ * @param callback - Function that returns:
2625
+ * - `SolverFlags.COMPUTE_IMPULSE` (1) - Process the collision normally
2626
+ * - `SolverFlags.EMPTY` (0) - Skip computing impulses (colliders pass through)
2627
+ * - `null` - Skip this hook; let the next registered hook decide
2628
+ *
2629
+ * When multiple hooks are registered, they are called in order until one returns a non-null value.
2630
+ */
2631
+ function filterContactPair(callback, injector) {
2632
+ return assertInjector(filterContactPair, injector, () => {
2633
+ const physics = inject(NgtrPhysics);
2634
+ physics.filterContactPairCallbacks.add(callback);
2635
+ inject(DestroyRef).onDestroy(() => {
2636
+ physics.filterContactPairCallbacks.delete(callback);
2637
+ });
2638
+ });
2639
+ }
2640
+ /**
2641
+ * Registers a callback to filter intersection pairs.
2642
+ *
2643
+ * The callback determines if intersection computation should happen between two colliders
2644
+ * (where at least one is a sensor).
2645
+ *
2646
+ * This will only be executed if at least one of the involved colliders contains the
2647
+ * `ActiveHooks.FILTER_INTERSECTION_PAIR` flag in its active hooks.
2648
+ *
2649
+ * @param callback - Function that returns:
2650
+ * - `true` - Allow the intersection to be detected
2651
+ * - `false` - Block the intersection (no intersection events will fire)
2652
+ *
2653
+ * When multiple hooks are registered, the first hook that returns `false` blocks the intersection.
2654
+ */
2655
+ function filterIntersectionPair(callback, injector) {
2656
+ return assertInjector(filterIntersectionPair, injector, () => {
2657
+ const physics = inject(NgtrPhysics);
2658
+ physics.filterIntersectionPairCallbacks.add(callback);
2659
+ inject(DestroyRef).onDestroy(() => {
2660
+ physics.filterIntersectionPairCallbacks.delete(callback);
2661
+ });
2662
+ });
2663
+ }
1987
2664
 
1988
2665
  /**
1989
2666
  * Generated bundle index. Do not edit.
1990
2667
  */
1991
2668
 
1992
- export { COLLISION_GROUPS_HANDLER, NgtrAnyCollider, NgtrBallCollider, NgtrCapsuleCollider, NgtrConeCollider, NgtrConvexHullCollider, NgtrConvexMeshCollider, NgtrCuboidCollider, NgtrCylinderCollider, NgtrHeightfieldCollider, NgtrInstancedRigidBodies, NgtrInteractionGroups, NgtrMeshCollider, NgtrPhysics, NgtrPhysicsFallback, NgtrPolylineCollider, NgtrRigidBody, NgtrRoundConeCollider, NgtrRoundConvexHullCollider, NgtrRoundConvexMeshCollider, NgtrRoundCuboidCollider, NgtrRoundCylinderCollider, NgtrTrimeshCollider, afterPhysicsStep, beforePhysicsStep, fixedJoint, injectFixedJoint, injectPrismaticJoint, injectRevoluteJoint, injectRopeJoint, injectSphericalJoint, injectSpringJoint, interactionGroups, prismaticJoint, revoluteJoint, rigidBodyDefaultOptions, ropeJoint, sphericalJoint, springJoint };
2669
+ export { COLLISION_GROUPS_HANDLER, NgtrAnyCollider, NgtrBallCollider, NgtrCapsuleCollider, NgtrConeCollider, NgtrConvexHullCollider, NgtrConvexMeshCollider, NgtrCuboidCollider, NgtrCylinderCollider, NgtrHeightfieldCollider, NgtrInstancedRigidBodies, NgtrInteractionGroups, NgtrMeshCollider, NgtrPhysics, NgtrPhysicsFallback, NgtrPolylineCollider, NgtrRigidBody, NgtrRoundConeCollider, NgtrRoundConvexHullCollider, NgtrRoundConvexMeshCollider, NgtrRoundCuboidCollider, NgtrRoundCylinderCollider, NgtrTrimeshCollider, afterPhysicsStep, beforePhysicsStep, filterContactPair, filterIntersectionPair, fixedJoint, injectFixedJoint, injectPrismaticJoint, injectRevoluteJoint, injectRopeJoint, injectSphericalJoint, injectSpringJoint, interactionGroups, prismaticJoint, revoluteJoint, rigidBodyDefaultOptions, ropeJoint, sphericalJoint, springJoint };
1993
2670
  //# sourceMappingURL=angular-three-rapier.mjs.map