Skip to content

Commit

Permalink
docs: add docs for cannon (WIP)
Browse files Browse the repository at this point in the history
  • Loading branch information
nartc committed Sep 22, 2024
1 parent 749b97b commit 824ef24
Show file tree
Hide file tree
Showing 6 changed files with 444 additions and 1 deletion.
4 changes: 4 additions & 0 deletions apps/astro-docs/astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,9 @@ export default defineConfig({
{ label: 'Introduction', slug: 'cannon/introduction' },
{ label: 'How it works', slug: 'cannon/how-it-works' },
{ label: 'Debug', slug: 'cannon/debug' },
{ label: 'Physics', slug: 'cannon/physics' },
{ label: 'Body Functions', slug: 'cannon/bodies' },
{ label: 'Constraint Functions', slug: 'cannon/constraints' },
],
},
{
Expand All @@ -182,6 +185,7 @@ export default defineConfig({
items: [
{ label: 'Introduction', slug: 'postprocessing/introduction' },
{ label: 'How it works', slug: 'postprocessing/how-it-works' },
{ label: 'EffectComposer', slug: 'postprocessing/effect-composer' },
],
},
{
Expand Down
135 changes: 135 additions & 0 deletions apps/astro-docs/src/content/docs/cannon/bodies.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
---
title: Body Functions
description: Detailed explanation of the Body functions in Angular Three Cannon
---

Angular Three Cannon provides various body functions to create different types of physics bodies. These functions are used to add physical properties to your 3D objects.

## Available Body Functions

All body functions are available from `angular-three-cannon/body`:

```angular-ts
import {
injectBox,
injectSphere,
injectPlane,
injectCylinder,
injectHeightfield,
injectParticle,
injectConvexPolyhedron,
injectTrimesh,
injectCompound
} from 'angular-three-cannon/body';
```

## Usage

The general pattern for using these functions is:

```angular-ts
import { Component, ElementRef, viewChild } from '@angular/core';
import { injectBox } from 'angular-three-cannon/body';
import { NgtMesh } from 'angular-three';
@Component({
selector: 'app-physics-box',
standalone: true,
template: `
<ngt-mesh #mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
`,
})
export class PhysicsBox {
mesh = viewChild.required<ElementRef<THREE.Mesh>>('mesh');
boxBody = injectBox(
() => ({
mass: 1,
position: [0, 5, 0],
args: [1, 1, 1],
}),
this.mesh
);
}
```

## Body Functions

| Function | Description | Specific Options |
|----------|-------------|------------------|
| `injectBox` | Creates a box-shaped body | `args: [width, height, depth]` |
| `injectSphere` | Creates a spherical body | `args: [radius]` |
| `injectPlane` | Creates an infinite plane | No specific options |
| `injectCylinder` | Creates a cylindrical body | `args: [radiusTop, radiusBottom, height, numSegments]` |
| `injectHeightfield` | Creates a heightfield body | `args: [data, options]` |
| `injectParticle` | Creates a particle (point mass) | No specific options |
| `injectConvexPolyhedron` | Creates a convex polyhedron | `args: [vertices, faces]` |
| `injectTrimesh` | Creates a triangular mesh body | `args: [vertices, indices]` |
| `injectCompound` | Creates a compound body | `shapes: Array<{ type, args, position?, rotation? }>` |

## Common Options

All body functions accept a set of common options:

| Option | Type | Description |
|--------|------|-------------|
| `mass` | number | The mass of the body (0 for static bodies) |
| `position` | [x: number, y: number, z: number] | Initial position of the body |
| `rotation` | [x: number, y: number, z: number] | Initial rotation of the body (in radians) |
| `velocity` | [x: number, y: number, z: number] | Initial velocity of the body |
| `angularVelocity` | [x: number, y: number, z: number] | Initial angular velocity of the body |
| `linearDamping` | number | Linear damping of the body (0 = no damping, 1 = full damping) |
| `angularDamping` | number | Angular damping of the body |
| `fixedRotation` | boolean | If true, body will not rotate |
| `collisionFilterGroup` | number | The collision group the body belongs to |
| `collisionFilterMask` | number | Which groups this body can collide with |
| `trigger` | boolean | If true, body acts as a trigger (no collision response) |
| `onCollide` | function | Callback function when collision occurs |
| `onCollideBegin` | function | Callback function when collision begins |
| `onCollideEnd` | function | Callback function when collision ends |

## Advanced Usage

You can dynamically update body properties using the returned API:

```angular-ts
import { Component, ElementRef, viewChild, signal } from '@angular/core';
import { injectBox } from 'angular-three-cannon/body';
import { NgtMesh } from 'angular-three';
@Component({
selector: 'app-physics-box',
standalone: true,
template: `
<ngt-mesh #mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
<button (click)="jump()">Jump</button>
`,
})
export class PhysicsBox {
mesh = viewChild.required<ElementRef<THREE.Mesh>>('mesh');
boxBody = injectBox(
() => ({
mass: 1,
position: [0, 5, 0],
args: [1, 1, 1],
}),
this.mesh
);
jump() {
const api = this.boxBody();
if (api) {
api.applyImpulse([0, 5, 0], [0, 0, 0]);
}
}
}
```

This example shows how to apply an impulse to make the box "jump" when a button is clicked.
155 changes: 155 additions & 0 deletions apps/astro-docs/src/content/docs/cannon/constraints.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
---
title: Constraint Functions
description: Detailed explanation of the Constraint functions in Angular Three Cannon
---

Angular Three Cannon provides various constraint functions to create different types of physical constraints between bodies. These functions are used to limit and control the relative movement of physics bodies.

## Available Constraint Functions

All constraint functions are available from `angular-three-cannon/constraint`:

```angular-ts
import {
injectPointToPoint,
injectConeTwist,
injectDistance,
injectLock,
injectHinge
} from 'angular-three-cannon/constraint';
```

## Usage

The general pattern for using these functions is:

```angular-ts
import { Component, ElementRef, viewChild } from '@angular/core';
import { injectHinge } from 'angular-three-cannon/constraint';
import { NgtMesh } from 'angular-three';
@Component({
selector: 'app-hinge-constraint',
standalone: true,
template: `
<ngt-mesh #bodyA>
<!-- Mesh for body A -->
</ngt-mesh>
<ngt-mesh #bodyB>
<!-- Mesh for body B -->
</ngt-mesh>
`,
})
export class HingeConstraint {
bodyA = viewChild.required<ElementRef<THREE.Mesh>>('bodyA');
bodyB = viewChild.required<ElementRef<THREE.Mesh>>('bodyB');
hingeConstraint = injectHinge(
this.bodyA,
this.bodyB,
{
pivotA: [1, 0, 0],
pivotB: [-1, 0, 0],
axisA: [0, 1, 0],
axisB: [0, 1, 0],
}
);
}
```

## Constraint Functions

| Function | Description | Specific Options |
|----------|-------------|------------------|
| `injectPointToPoint` | Creates a point-to-point constraint | `pivotA`, `pivotB` |
| `injectConeTwist` | Creates a cone twist constraint | `pivotA`, `pivotB`, `axisA`, `axisB` |
| `injectDistance` | Creates a distance constraint | `distance` |
| `injectLock` | Creates a lock constraint | `maxForce` |
| `injectHinge` | Creates a hinge constraint | `pivotA`, `pivotB`, `axisA`, `axisB` |

## Common Options

All constraint functions accept two bodies as the first two arguments, followed by an options object. Common options include:

| Option | Type | Description |
|--------|------|-------------|
| `pivotA` | [x: number, y: number, z: number] | The pivot point for body A in local space |
| `pivotB` | [x: number, y: number, z: number] | The pivot point for body B in local space |
| `axisA` | [x: number, y: number, z: number] | The axis for body A (for certain constraints) |
| `axisB` | [x: number, y: number, z: number] | The axis for body B (for certain constraints) |
| `maxForce` | number | The maximum force that can be applied to maintain the constraint |

## Specific Options

### PointToPoint Constraint
- No additional specific options

### ConeTwist Constraint
- `angle`: number - The maximum cone angle in radians
- `twistAngle`: number - The maximum twist angle in radians

### Distance Constraint
- `distance`: number - The fixed distance between the bodies

### Lock Constraint
- No additional specific options

### Hinge Constraint
- `collideConnected`: boolean - Whether the connected bodies should collide with each other

## Advanced Usage

You can dynamically control constraints using the returned API:

```angular-ts
import { Component, ElementRef, viewChild, signal } from '@angular/core';
import { injectHinge } from 'angular-three-cannon/constraint';
import { NgtMesh } from 'angular-three';
@Component({
selector: 'app-hinge-constraint',
standalone: true,
template: `
<ngt-mesh #bodyA>
<!-- Mesh for body A -->
</ngt-mesh>
<ngt-mesh #bodyB>
<!-- Mesh for body B -->
</ngt-mesh>
<button (click)="toggleMotor()">Toggle Motor</button>
`,
})
export class HingeConstraint {
bodyA = viewChild.required<ElementRef<THREE.Mesh>>('bodyA');
bodyB = viewChild.required<ElementRef<THREE.Mesh>>('bodyB');
motorEnabled = signal(false);
hingeConstraint = injectHinge(
this.bodyA,
this.bodyB,
{
pivotA: [1, 0, 0],
pivotB: [-1, 0, 0],
axisA: [0, 1, 0],
axisB: [0, 1, 0],
}
);
toggleMotor() {
const api = this.hingeConstraint();
if (api) {
if (this.motorEnabled()) {
api.disableMotor();
} else {
api.enableMotor();
api.setMotorSpeed(1);
api.setMotorMaxForce(10);
}
this.motorEnabled.update(value => !value);
}
}
}
```

This example demonstrates how to toggle a motor on a hinge constraint, showing the advanced control you have over constraints during runtime.
2 changes: 1 addition & 1 deletion apps/astro-docs/src/content/docs/cannon/debug.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class SceneGraph {}

### Passing options to `NgtcDebug`

We can pas options to `NgtcDebug` by passing in an object to the `debug` input
We can pass options to `NgtcDebug` by passing in an object to the `debug` input

```angular-ts
@Component({
Expand Down
73 changes: 73 additions & 0 deletions apps/astro-docs/src/content/docs/cannon/physics.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
---
title: NgtcPhysics
description: Detailed explanation of the NgtcPhysics component and its options
---

The `NgtcPhysics` component is the core of Angular Three Cannon. It sets up the physics world and manages the simulation. All physics-enabled objects should be children of this component.

## Usage

```angular-ts
import { NgtcPhysics } from 'angular-three-cannon';
import { Component, signal } from '@angular/core';
@Component({
standalone: true,
imports: [NgtcPhysics],
template: `
<ngtc-physics [options]="{ gravity: [0, -9.81, 0], iterations: 5 }">
<!-- physics-enabled objects go here -->
</ngtc-physics>
`,
})
export class PhysicsScene {}
```

## Options

The `NgtcPhysics` component accepts an `options` input with the following properties:

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `allowSleep` | boolean | `false` | If true, allows bodies to fall asleep for better performance |
| `axisIndex` | number | `0` | Axis index for broadphase optimization |
| `broadphase` | string | `'Naive'` | Broadphase algorithm to use. Options: 'Naive', 'SAP' |
| `defaultContactMaterial` | object | `{ contactEquationStiffness: 1e6 }` | Default contact material properties |
| `frictionGravity` | number[] \| null | `null` | Gravity to use for friction calculations |
| `gravity` | number[] | `[0, -9.81, 0]` | Gravity force applied to all bodies |
| `iterations` | number | `5` | Number of solver iterations per step |
| `quatNormalizeFast` | boolean | `false` | If true, uses fast quaternion normalization |
| `quatNormalizeSkip` | number | `0` | Number of steps to skip before normalizing quaternions |
| `size` | number | `1000` | Maximum number of physics bodies |
| `solver` | string | `'GS'` | Constraint solver to use. Options: 'GS' (Gauss-Seidel) |
| `tolerance` | number | `0.001` | Solver tolerance |
| `isPaused` | boolean | `false` | If true, pauses the physics simulation |
| `maxSubSteps` | number | `10` | Maximum number of sub-steps per frame |
| `shouldInvalidate` | boolean | `true` | If true, forces a re-render after each physics step |
| `stepSize` | number | `1/60` | Fixed time step size |

## Advanced Usage

You can dynamically update physics options using Angular Signals:

```angular-ts
import { Component, signal } from '@angular/core';
import { NgtcPhysics } from 'angular-three-cannon';
@Component({
standalone: true,
imports: [NgtcPhysics],
template: `
<ngtc-physics [options]="{ gravity: gravity() }">
<!-- physics-enabled objects -->
</ngtc-physics>
`,
})
export class PhysicsScene {
gravity = signal([0, -9.81, 0]);
toggleGravity() {
this.gravity.update((current) => [0, current[1] * -1, 0]);
}
}
```
Loading

0 comments on commit 824ef24

Please sign in to comment.