
Security News
Attackers Are Hunting High-Impact Node.js Maintainers in a Coordinated Social Engineering Campaign
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.
angular-three-rapier
Advanced tools
angular-three-rapierThis library provides Rapier physics integration for Angular Three. Rapier is a fast, cross-platform physics engine written in Rust with JavaScript bindings.
All public APIs are documented with JSDoc comments. Your IDE will provide inline documentation, parameter hints, and examples as you code.
npm install angular-three-rapier @dimforge/rapier3d-compat
# yarn add angular-three-rapier @dimforge/rapier3d-compat
# pnpm add angular-three-rapier @dimforge/rapier3d-compat
Make sure to already have
angular-threeinstalled
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import { extend, NgtArgs } from 'angular-three';
import { NgtrPhysics, NgtrRigidBody } from 'angular-three-rapier';
import * as THREE from 'three';
extend(THREE);
@Component({
selector: 'app-box',
template: `
<ngt-object3D rigidBody [position]="[0, 5, 0]">
<ngt-mesh>
<ngt-box-geometry />
<ngt-mesh-standard-material color="hotpink" />
</ngt-mesh>
</ngt-object3D>
`,
imports: [NgtrRigidBody],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class Box {}
@Component({
selector: 'app-ground',
template: `
<ngt-object3D rigidBody="fixed" [position]="[0, -1, 0]">
<ngt-mesh>
<ngt-box-geometry *args="[20, 1, 20]" />
<ngt-mesh-standard-material color="gray" />
</ngt-mesh>
</ngt-object3D>
`,
imports: [NgtrRigidBody, NgtArgs],
schemas: [CUSTOM_ELEMENTS_SCHEMA],
})
export class Ground {}
@Component({
template: `
<ngtr-physics [options]="{ gravity: [0, -9.81, 0] }">
<ng-template>
<app-box />
<app-ground />
</ng-template>
</ngtr-physics>
`,
imports: [NgtrPhysics, Box, Ground],
})
export class SceneGraph {}
| Property | Description | Default |
|---|---|---|
gravity | Gravity vector [x, y, z] | [0, -9.81, 0] |
colliders | Default collider type for rigid bodies | 'cuboid' |
paused | Whether physics simulation is paused | false |
timeStep | Fixed timestep for physics simulation | 1/60 |
debug | Enable debug visualization | false |
interpolate | Enable transform interpolation | true |
updateLoop | Update loop type: 'follow' or 'independent' | 'follow' |
Use ngt-object3D with the rigidBody attribute. The rigid body type is specified as the attribute value:
<!-- Dynamic (default when empty) -->
<ngt-object3D rigidBody [position]="[0, 5, 0]">
<ngt-mesh>...</ngt-mesh>
</ngt-object3D>
<!-- Fixed (static) -->
<ngt-object3D rigidBody="fixed" [position]="[0, -1, 0]">
<ngt-mesh>...</ngt-mesh>
</ngt-object3D>
<!-- Kinematic -->
<ngt-object3D rigidBody="kinematicPosition">
<ngt-mesh>...</ngt-mesh>
</ngt-object3D>
'' or 'dynamic' - Affected by forces and collisions'fixed' - Static, immovable body'kinematicPosition' - Controlled by position, affects dynamic bodies'kinematicVelocity' - Controlled by velocity, affects dynamic bodies<ngt-object3D
rigidBody
[options]="{
colliders: 'ball',
ccd: true,
gravityScale: 0.5,
linearVelocity: [0, 10, 0],
angularVelocity: [0, 1, 0]
}"
>
...
</ngt-object3D>
<ngt-object3D
rigidBody
(collisionEnter)="onCollisionEnter($event)"
(collisionExit)="onCollisionExit($event)"
(intersectionEnter)="onIntersectionEnter($event)"
(intersectionExit)="onIntersectionExit($event)"
(contactForce)="onContactForce($event)"
(sleep)="onSleep()"
(wake)="onWake()"
>
...
</ngt-object3D>
Colliders use ngt-object3D with specific collider attributes. By default, rigid bodies auto-generate colliders from child meshes.
<!-- Ball collider -->
<ngt-object3D [ballCollider]="[0.5]" [position]="[0, 2, 0]" />
<!-- Cuboid collider (half-extents) -->
<ngt-object3D [cuboidCollider]="[1, 0.5, 2]" [position]="[0, 0, 0]" />
<!-- Capsule collider (half-height, radius) -->
<ngt-object3D [capsuleCollider]="[0.5, 0.25]" [position]="[0, 1, 0]" />
<!-- Cylinder collider (half-height, radius) -->
<ngt-object3D [cylinderCollider]="[1, 0.5]" />
<!-- Cone collider (half-height, radius) -->
<ngt-object3D [coneCollider]="[1, 0.5]" />
| Directive | Args | Description |
|---|---|---|
NgtrBallCollider | [radius] | Sphere shape |
NgtrCuboidCollider | [halfW, halfH, halfD] | Box shape |
NgtrCapsuleCollider | [halfHeight, radius] | Capsule shape |
NgtrCylinderCollider | [halfHeight, radius] | Cylinder shape |
NgtrConeCollider | [halfHeight, radius] | Cone shape |
NgtrConvexHullCollider | [vertices] | Convex hull |
NgtrTrimeshCollider | [vertices, indices] | Triangle mesh |
NgtrHeightfieldCollider | [width, height, heights, scale] | Terrain heightfield |
NgtrRoundCuboidCollider | [halfW, halfH, halfD, radius] | Rounded box |
NgtrRoundCylinderCollider | [halfH, radius, borderRadius] | Rounded cylinder |
NgtrRoundConeCollider | [halfH, radius, borderRadius] | Rounded cone |
<ngt-object3D rigidBody [options]="{ colliders: false }">
<!-- Manual colliders only -->
<ngt-object3D [ballCollider]="[0.5]" />
</ngt-object3D>
Generate colliders from mesh geometry:
<ngt-object3D rigidBody [options]="{ colliders: false }">
<ngt-object3D [meshCollider]="'trimesh'">
<ngt-mesh>
<ngt-torus-geometry />
<ngt-mesh-standard-material />
</ngt-mesh>
</ngt-object3D>
</ngt-object3D>
Create joints between rigid bodies using injectable functions:
import { Component, viewChild } from '@angular/core';
import {
NgtrRigidBody,
sphericalJoint,
revoluteJoint,
prismaticJoint,
fixedJoint,
ropeJoint,
springJoint,
} from 'angular-three-rapier';
@Component({
template: `
<ngt-object3D rigidBody="fixed" #bodyA="rigidBody">...</ngt-object3D>
<ngt-object3D rigidBody #bodyB="rigidBody">...</ngt-object3D>
`,
})
export class JointExample {
bodyA = viewChild.required<NgtrRigidBody>('bodyA');
bodyB = viewChild.required<NgtrRigidBody>('bodyB');
// Spherical joint (ball-and-socket)
joint = sphericalJoint(
() => this.bodyA().rigidBody(),
() => this.bodyB().rigidBody(),
{
data: {
body1Anchor: [0, -0.5, 0],
body2Anchor: [0, 0.5, 0],
},
},
);
// Revolute joint (hinge) with limits
hingeJoint = revoluteJoint(
() => this.bodyA().rigidBody(),
() => this.bodyB().rigidBody(),
{
data: {
body1Anchor: [0, 0, 0],
body2Anchor: [0, 1, 0],
axis: [0, 1, 0],
limits: [-Math.PI / 2, Math.PI / 2],
},
},
);
// Prismatic joint (slider)
sliderJoint = prismaticJoint(
() => this.bodyA().rigidBody(),
() => this.bodyB().rigidBody(),
{
data: {
body1Anchor: [0, 0, 0],
body2Anchor: [2, 0, 0],
axis: [1, 0, 0],
limits: [-1, 1],
},
},
);
// Rope joint (max distance constraint)
rope = ropeJoint(
() => this.bodyA().rigidBody(),
() => this.bodyB().rigidBody(),
{
data: {
body1Anchor: [0, 0, 0],
body2Anchor: [0, 0, 0],
length: 5,
},
},
);
// Spring joint
spring = springJoint(
() => this.bodyA().rigidBody(),
() => this.bodyB().rigidBody(),
{
data: {
body1Anchor: [0, 0, 0],
body2Anchor: [0, 0, 0],
restLength: 2,
stiffness: 100,
damping: 10,
},
},
);
}
For efficient physics with many identical objects:
import { NgtArgs } from 'angular-three';
import { NgtrInstancedRigidBodies } from 'angular-three-rapier';
@Component({
template: `
<ngt-object3D [instancedRigidBodies]="instances">
<ngt-instanced-mesh [count]="instances.length" castShadow>
<ngt-sphere-geometry *args="[0.5]" />
<ngt-mesh-standard-material color="orange" />
</ngt-instanced-mesh>
</ngt-object3D>
`,
imports: [NgtrInstancedRigidBodies, NgtArgs],
})
export class Spheres {
instances = Array.from({ length: 100 }, (_, i) => ({
key: i,
position: [Math.random() * 10, Math.random() * 10, 0] as [number, number, number],
}));
}
Filter collisions between objects:
import { interactionGroups } from 'angular-three-rapier';
// Member of group 0, collides with groups 0 and 1
const groups = interactionGroups([0], [0, 1]);
<!-- Using directive -->
<ngt-object3D rigidBody [interactionGroups]="[[0], [0, 1]]">...</ngt-object3D>
import { beforePhysicsStep, afterPhysicsStep } from 'angular-three-rapier';
@Component({...})
export class MyComponent {
constructor() {
beforePhysicsStep((world) => {
// Run before each physics step
});
afterPhysicsStep((world) => {
// Run after each physics step
});
}
}
Enable debug rendering via physics options:
<ngtr-physics [options]="{ debug: true }">
<ng-template>
<!-- your physics objects -->
</ng-template>
</ngtr-physics>
Apply gravitational or magnetic forces:
import { NgtrAttractor } from 'angular-three-rapier/addons';
<!-- Attractor with default options -->
<ngt-object3D attractor />
<!-- Attractor with custom options -->
<ngt-object3D [attractor]="{ strength: 10, range: 20, type: 'linear' }" />
<!-- Repeller (negative strength) -->
<ngt-object3D [attractor]="{ strength: -10, range: 15 }" [position]="[5, 0, 0]" />
<!-- Newtonian gravity -->
<ngt-object3D
[attractor]="{
strength: 1000,
range: 50,
type: 'newtonian',
gravitationalConstant: 0.01
}"
/>
FAQs
Physics Rapier for Angular Three
We found that angular-three-rapier demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Multiple high-impact npm maintainers confirm they have been targeted in the same social engineering campaign that compromised Axios.

Security News
Axios compromise traced to social engineering, showing how attacks on maintainers can bypass controls and expose the broader software supply chain.

Security News
Node.js has paused its bug bounty program after funding ended, removing payouts for vulnerability reports but keeping its security process unchanged.