@threlte/rapier 1.1.4 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- <script>import { T, useFrame } from '@threlte/core';
1
+ <script>import { T, useTask } from '@threlte/core';
2
2
  import { Group, Vector3 } from 'three';
3
3
  import { useRapier } from '../../hooks/useRapier';
4
4
  export let strength = 1;
@@ -13,14 +13,15 @@ const calcForceByType = {
13
13
  linear: (s, m2, r, d, G) => s * (d / r),
14
14
  newtonian: (s, m2, r, d, G) => (G * s * m2) / Math.pow(d, 2)
15
15
  };
16
+ const impulseVector = new Vector3();
17
+ const bodyV3 = new Vector3();
16
18
  function applyImpulseToBodiesInRange() {
17
- const impulseVector = new Vector3();
18
19
  obj.getWorldPosition(gravitySource);
19
20
  world.forEachRigidBody((body) => {
20
21
  const { x, y, z } = body.translation();
21
- const bodyV3 = new Vector3(x, y, z);
22
- const distance = gravitySource.distanceTo(bodyV3);
23
- if (distance < range) {
22
+ bodyV3.set(x, y, z);
23
+ const distance = gravitySource.distanceToSquared(bodyV3);
24
+ if (distance < range ** 2) {
24
25
  let force = calcForceByType[gravityType](strength, body.mass(), range, distance, gravitationalConstant);
25
26
  // Prevent wild forces when Attractors collide
26
27
  force = force === Infinity ? strength : force;
@@ -29,7 +30,7 @@ function applyImpulseToBodiesInRange() {
29
30
  }
30
31
  });
31
32
  }
32
- useFrame(() => {
33
+ useTask(() => {
33
34
  applyImpulseToBodiesInRange();
34
35
  });
35
36
  </script>
@@ -1,5 +1,5 @@
1
1
  import { Props, type Events, type Slots } from '@threlte/core'
2
- import { SvelteComponentTyped } from 'svelte'
2
+ import { SvelteComponent } from 'svelte'
3
3
  import type { Group } from 'three'
4
4
  import type { GravityType } from '../../types/types'
5
5
 
@@ -35,7 +35,7 @@ type AttractorEvents = Events<Group>
35
35
 
36
36
  type AttractorSlots = Slots<Group>
37
37
 
38
- export default class Attractor extends SvelteComponentTyped<
38
+ export default class Attractor extends SvelteComponent<
39
39
  AttractorProps,
40
40
  AttractorEvents,
41
41
  AttractorSlots
@@ -57,10 +57,10 @@ export type MassDef = Density | Mass | MassProperties | NoMassProperties
57
57
  type MassProps<TMassDef extends MassDef> = TMassDef extends Density
58
58
  ? Density
59
59
  : TMassDef extends MassProperties
60
- ? MassProperties
61
- : TMassDef extends Mass
62
- ? Mass
63
- : NoMassProperties
60
+ ? MassProperties
61
+ : TMassDef extends Mass
62
+ ? Mass
63
+ : NoMassProperties
64
64
 
65
65
  // ------------------ COLLIDER ------------------
66
66
 
@@ -1,5 +1,5 @@
1
1
  <script>import { ActiveCollisionTypes, CoefficientCombineRule, Collider, ColliderDesc } from '@dimforge/rapier3d-compat';
2
- import { createRawEventDispatcher, SceneGraphObject, useFrame } from '@threlte/core';
2
+ import { createRawEventDispatcher, SceneGraphObject, useTask } from '@threlte/core';
3
3
  import { onDestroy, onMount, tick } from 'svelte';
4
4
  import { Object3D, Quaternion, Vector3 } from 'three';
5
5
  import { useCollisionGroups } from '../../hooks/useCollisionGroups';
@@ -109,10 +109,10 @@ export const refresh = () => {
109
109
  * If the Collider isAttached (i.e. NOT child of a RigidBody), update the
110
110
  * transforms on every frame.
111
111
  */
112
- const { start, stop } = useFrame(() => {
112
+ const { start, stop } = useTask(() => {
113
113
  refresh();
114
114
  }, {
115
- autostart: !hasRigidBodyParent && type === 'dynamic'
115
+ autoStart: !hasRigidBodyParent && type === 'dynamic'
116
116
  });
117
117
  $: {
118
118
  if (!hasRigidBodyParent && type === 'dynamic')
@@ -89,10 +89,10 @@ export type MassDef = Density | Mass | MassProperties | NoMassProperties
89
89
  type MassProps<TMassDef extends MassDef> = TMassDef extends Density
90
90
  ? Density
91
91
  : TMassDef extends MassProperties
92
- ? MassProperties
93
- : TMassDef extends Mass
94
- ? Mass
95
- : NoMassProperties
92
+ ? MassProperties
93
+ : TMassDef extends Mass
94
+ ? Mass
95
+ : NoMassProperties
96
96
 
97
97
  // ------------------ COLLIDER ------------------
98
98
 
@@ -1,11 +1,11 @@
1
- <script>import { T, useFrame } from '@threlte/core';
1
+ <script>import { T, useTask } from '@threlte/core';
2
2
  import { onDestroy } from 'svelte';
3
3
  import { BufferAttribute, BufferGeometry } from 'three';
4
4
  import { useRapier } from '../../hooks/useRapier';
5
5
  const { world, debug } = useRapier();
6
6
  const geometry = new BufferGeometry();
7
7
  debug.set(true);
8
- useFrame(() => {
8
+ useTask(() => {
9
9
  const buffers = world.debugRender();
10
10
  const vertices = new BufferAttribute(buffers.vertices, 3);
11
11
  const colors = new BufferAttribute(buffers.colors, 4);
@@ -58,7 +58,7 @@ export type RigidBodyProps = {
58
58
  enabledRotations?: Boolean3Array
59
59
 
60
60
  /**
61
- * Allow rotation of this rigid-body only along specific axes.
61
+ * Allow translations of this rigid-body only along specific axes.
62
62
  */
63
63
  enabledTranslations?: Boolean3Array
64
64
 
@@ -20,13 +20,13 @@ export let rawQueryPipeline = undefined;
20
20
  export let rawPhysicsPipeline = undefined;
21
21
  export let rawSerializationPipeline = undefined;
22
22
  export let rawDebugRenderPipeline = undefined;
23
- export let order = undefined;
23
+ export let stage = undefined;
24
24
  const rapierContext = createRapierContext({ x: gravity[0], y: gravity[1], z: gravity[2] }, rawIntegrationParameters, rawIslands, rawBroadPhase, rawNarrowPhase, rawBodies, rawColliders, rawImpulseJoints, rawMultibodyJoints, rawCCDSolver, rawQueryPipeline, rawPhysicsPipeline, rawSerializationPipeline, rawDebugRenderPipeline);
25
25
  setContext('threlte-rapier-context', rapierContext);
26
26
  $: if (gravity !== undefined) {
27
27
  rapierContext.world.gravity = { x: gravity[0], y: gravity[1], z: gravity[2] };
28
28
  }
29
- useFrameHandler(rapierContext, order);
29
+ useFrameHandler(rapierContext, stage);
30
30
  onDestroy(async () => {
31
31
  await tick();
32
32
  rapierContext.world.free();
@@ -1,22 +1,7 @@
1
- import { SvelteComponentTyped } from "svelte";
1
+ import { SvelteComponent } from "svelte";
2
+ import type { WorldProps } from './World.svelte';
2
3
  declare const __propDef: {
3
- props: {
4
- gravity?: [x: number, y: number, z: number] | undefined;
5
- rawIntegrationParameters?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIntegrationParameters | undefined;
6
- rawIslands?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawIslandManager | undefined;
7
- rawBroadPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawBroadPhase | undefined;
8
- rawNarrowPhase?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawNarrowPhase | undefined;
9
- rawBodies?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawRigidBodySet | undefined;
10
- rawColliders?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawColliderSet | undefined;
11
- rawImpulseJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawImpulseJointSet | undefined;
12
- rawMultibodyJoints?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawMultibodyJointSet | undefined;
13
- rawCCDSolver?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawCCDSolver | undefined;
14
- rawQueryPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawQueryPipeline | undefined;
15
- rawPhysicsPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawPhysicsPipeline | undefined;
16
- rawSerializationPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawSerializationPipeline | undefined;
17
- rawDebugRenderPipeline?: import("@dimforge/rapier3d-compat/rapier_wasm3d").RawDebugRenderPipeline | undefined;
18
- order?: number | undefined;
19
- };
4
+ props: WorldProps;
20
5
  events: {
21
6
  [evt: string]: CustomEvent<any>;
22
7
  };
@@ -27,6 +12,6 @@ declare const __propDef: {
27
12
  export type InnerWorldProps = typeof __propDef.props;
28
13
  export type InnerWorldEvents = typeof __propDef.events;
29
14
  export type InnerWorldSlots = typeof __propDef.slots;
30
- export default class InnerWorld extends SvelteComponentTyped<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
15
+ export default class InnerWorld extends SvelteComponent<InnerWorldProps, InnerWorldEvents, InnerWorldSlots> {
31
16
  }
32
17
  export {};
@@ -27,11 +27,11 @@ export let rawPhysicsPipeline = undefined;
27
27
  export let rawSerializationPipeline = undefined;
28
28
  export let rawDebugRenderPipeline = undefined;
29
29
  /**
30
- * The property order is passed to the useFrame handler.
31
- * Use this to control when the rapier physics engine is updating the scene.
32
- * @default undefined
33
- */
34
- export let order = undefined;
30
+ * This is passed to the useTask handler.
31
+ * Use this to control when the rapier physics engine is updating the scene.
32
+ * @default undefined
33
+ */
34
+ export let stage = undefined;
35
35
  let error = false;
36
36
  const init = async () => {
37
37
  if ($initialized)
@@ -63,7 +63,7 @@ onMount(init);
63
63
  {rawPhysicsPipeline}
64
64
  {rawSerializationPipeline}
65
65
  {rawDebugRenderPipeline}
66
- {order}
66
+ {stage}
67
67
  >
68
68
  <slot />
69
69
  </InnerWorld>
@@ -13,8 +13,9 @@ import type {
13
13
  RawRigidBodySet,
14
14
  RawSerializationPipeline
15
15
  } from '@dimforge/rapier3d-compat/raw'
16
- import { SvelteComponentTyped } from 'svelte'
16
+ import { SvelteComponent } from 'svelte'
17
17
  import type { Vector3 } from 'three'
18
+ import type { Key, Stage } from '@threlte/core'
18
19
 
19
20
  export type WorldProps = {
20
21
  gravity?: Parameters<Vector3['set']>
@@ -31,7 +32,7 @@ export type WorldProps = {
31
32
  rawPhysicsPipeline?: RawPhysicsPipeline
32
33
  rawSerializationPipeline?: RawSerializationPipeline
33
34
  rawDebugRenderPipeline?: RawDebugRenderPipeline
34
- order?: number
35
+ stage?: Key | Stage
35
36
  }
36
37
 
37
- export default class World extends SvelteComponentTyped<WorldProps> {}
38
+ export default class World extends SvelteComponent<WorldProps> {}
@@ -1,2 +1,3 @@
1
+ import { type Stage, type Key } from '@threlte/core';
1
2
  import type { RapierContext } from '../types/types';
2
- export declare const useFrameHandler: (ctx: RapierContext, order?: number) => void;
3
+ export declare const useFrameHandler: (ctx: RapierContext, stage?: Stage | Key) => void;
@@ -1,5 +1,5 @@
1
- import { Collider, EventQueue } from '@dimforge/rapier3d-compat';
2
- import { useFrame } from '@threlte/core';
1
+ import { EventQueue } from '@dimforge/rapier3d-compat';
2
+ import { useTask } from '@threlte/core';
3
3
  import { derived } from 'svelte/store';
4
4
  import { Object3D, Quaternion, Vector3 } from 'three';
5
5
  const tempObject = new Object3D();
@@ -23,9 +23,9 @@ const getEventDispatchers = (ctx, collider1, collider2) => {
23
23
  rigidBodyDispatcher2
24
24
  };
25
25
  };
26
- export const useFrameHandler = (ctx, order) => {
26
+ export const useFrameHandler = (ctx, stage) => {
27
27
  const eventQueue = new EventQueue(false);
28
- const { start, started, stop } = useFrame((_, delta) => {
28
+ const { start, started, stop } = useTask((delta) => {
29
29
  // if (!eventQueue) return
30
30
  const { world } = ctx;
31
31
  // Set timestep to current delta, to allow for variable frame rates
@@ -122,6 +122,12 @@ export const useFrameHandler = (ctx, order) => {
122
122
  return;
123
123
  }
124
124
  const { colliderDispatcher1, colliderDispatcher2, rigidBodyDispatcher1, rigidBodyDispatcher2 } = getEventDispatchers(ctx, collider1, collider2);
125
+ if (!colliderDispatcher1 &&
126
+ !colliderDispatcher2 &&
127
+ !rigidBodyDispatcher1 &&
128
+ !rigidBodyDispatcher2) {
129
+ return;
130
+ }
125
131
  const rigidBody1 = collider1.parent();
126
132
  const rigidBody2 = collider2.parent();
127
133
  if (started) {
@@ -225,7 +231,7 @@ export const useFrameHandler = (ctx, order) => {
225
231
  });
226
232
  }
227
233
  });
228
- }, { order });
234
+ }, { stage });
229
235
  // replacing the original pause and resume functions as well as the paused property
230
236
  ctx.pause = () => stop();
231
237
  ctx.resume = () => start();
@@ -1,5 +1,5 @@
1
- import { ActiveEvents, Collider, ColliderDesc, World, RigidBody } from '@dimforge/rapier3d-compat';
2
- import { Mesh, Quaternion, Vector3 } from 'three';
1
+ import { ActiveEvents, ColliderDesc } from '@dimforge/rapier3d-compat';
2
+ import { Quaternion, Vector3 } from 'three';
3
3
  const offset = new Vector3();
4
4
  const worldPosition = new Vector3();
5
5
  const worldQuaternion = new Quaternion();
@@ -1,4 +1,4 @@
1
- import { Euler, Object3D, Quaternion, Vector3 } from 'three';
1
+ import { Euler, Quaternion, Vector3 } from 'three';
2
2
  const tempPosition = new Vector3();
3
3
  const tempQuaternion = new Quaternion();
4
4
  const tempRotation = new Euler();
@@ -1,4 +1,4 @@
1
- <script>import { createRawEventDispatcher, T, useFrame } from '@threlte/core';
1
+ <script>import { createRawEventDispatcher, T, useTask } from '@threlte/core';
2
2
  import { Vector2, Vector3 } from 'three';
3
3
  import Collider from '../components/Colliders/Collider.svelte';
4
4
  import CollisionGroups from '../components/CollisionGroups/CollisionGroups.svelte';
@@ -29,10 +29,8 @@ $: {
29
29
  grounded = true;
30
30
  }
31
31
  $: grounded ? dispatch('groundenter') : dispatch('groundexit');
32
- useFrame(() => {
33
- if (!rigidBody)
34
- return;
35
- t.fromArray([0, 0, 0]);
32
+ const { start } = useTask(() => {
33
+ t.set(0, 0, 0);
36
34
  if (keys.down)
37
35
  t.x += 1;
38
36
  if (keys.up)
@@ -53,18 +51,24 @@ useFrame(() => {
53
51
  t.y = linVel.y;
54
52
  rigidBody.setLinvel(t, true);
55
53
  });
54
+ $: if (rigidBody)
55
+ start();
56
56
  const onKeyDown = (e) => {
57
- switch (e.key) {
58
- case 'ArrowDown':
57
+ switch (e.key.toLowerCase()) {
58
+ case 's':
59
+ case 'arrowdown':
59
60
  keys.down = true;
60
61
  break;
61
- case 'ArrowUp':
62
+ case 'w':
63
+ case 'arrowup':
62
64
  keys.up = true;
63
65
  break;
64
- case 'ArrowLeft':
66
+ case 'a':
67
+ case 'arrowleft':
65
68
  keys.left = true;
66
69
  break;
67
- case 'ArrowRight':
70
+ case 'd':
71
+ case 'arrowright':
68
72
  keys.right = true;
69
73
  break;
70
74
  case ' ':
@@ -76,17 +80,21 @@ const onKeyDown = (e) => {
76
80
  }
77
81
  };
78
82
  const onKeyUp = (e) => {
79
- switch (e.key) {
80
- case 'ArrowDown':
83
+ switch (e.key.toLowerCase()) {
84
+ case 's':
85
+ case 'arrowdown':
81
86
  keys.down = false;
82
87
  break;
83
- case 'ArrowUp':
88
+ case 'w':
89
+ case 'arrowup':
84
90
  keys.up = false;
85
91
  break;
86
- case 'ArrowLeft':
92
+ case 'a':
93
+ case 'arrowleft':
87
94
  keys.left = false;
88
95
  break;
89
- case 'ArrowRight':
96
+ case 'd':
97
+ case 'arrowright':
90
98
  keys.right = false;
91
99
  break;
92
100
  default:
@@ -95,7 +103,10 @@ const onKeyUp = (e) => {
95
103
  };
96
104
  </script>
97
105
 
98
- <svelte:window on:keydown|preventDefault={onKeyDown} on:keyup|preventDefault={onKeyUp} />
106
+ <svelte:window
107
+ on:keydown|preventDefault={onKeyDown}
108
+ on:keyup|preventDefault={onKeyUp}
109
+ />
99
110
 
100
111
  <T.Group {position}>
101
112
  <RigidBody
@@ -105,7 +116,10 @@ const onKeyUp = (e) => {
105
116
  type={'dynamic'}
106
117
  >
107
118
  <CollisionGroups groups={playerCollisionGroups}>
108
- <Collider shape={'capsule'} args={[height / 2 - radius, radius]} />
119
+ <Collider
120
+ shape={'capsule'}
121
+ args={[height / 2 - radius, radius]}
122
+ />
109
123
  </CollisionGroups>
110
124
 
111
125
  <CollisionGroups groups={groundCollisionGroups}>
@@ -1,4 +1,4 @@
1
- import { SvelteComponentTyped } from "svelte";
1
+ import { SvelteComponent } from "svelte";
2
2
  import { Vector3 } from 'three';
3
3
  import type { CollisionGroupsBitMask } from '../types/types';
4
4
  declare const __propDef: {
@@ -21,6 +21,6 @@ declare const __propDef: {
21
21
  export type BasicPlayerControllerProps = typeof __propDef.props;
22
22
  export type BasicPlayerControllerEvents = typeof __propDef.events;
23
23
  export type BasicPlayerControllerSlots = typeof __propDef.slots;
24
- export default class BasicPlayerController extends SvelteComponentTyped<BasicPlayerControllerProps, BasicPlayerControllerEvents, BasicPlayerControllerSlots> {
24
+ export default class BasicPlayerController extends SvelteComponent<BasicPlayerControllerProps, BasicPlayerControllerEvents, BasicPlayerControllerSlots> {
25
25
  }
26
26
  export {};
@@ -1,3 +1,4 @@
1
+ /// <reference types="svelte" />
1
2
  import type { Collider, ColliderHandle, RigidBody, RigidBodyHandle, TempContactManifold, Vector } from '@dimforge/rapier3d-compat';
2
3
  import type { createRawEventDispatcher } from '@threlte/core';
3
4
  import type { Writable } from 'svelte/store';
package/package.json CHANGED
@@ -1,40 +1,62 @@
1
1
  {
2
2
  "name": "@threlte/rapier",
3
- "version": "1.1.4",
3
+ "version": "2.0.1",
4
4
  "author": "Grischa Erbe <hello@legrisch.com> (https://legrisch.com)",
5
5
  "license": "MIT",
6
+ "description": "Components and hooks to use the Rapier physics engine in Threlte",
6
7
  "devDependencies": {
7
8
  "@dimforge/rapier3d-compat": "^0.11.2",
8
- "@sveltejs/adapter-auto": "^2.0.0",
9
- "@sveltejs/kit": "^1.20.4",
10
- "@sveltejs/package": "^2.1.0",
11
- "@types/node": "^18.0.3",
12
- "@types/three": "^0.158.3",
13
- "@typescript-eslint/eslint-plugin": "^5.45.0",
14
- "@typescript-eslint/parser": "^5.45.0",
15
- "@yushijinhun/three-minifier-rollup": "^0.3.1",
16
- "eslint": "^8.28.0",
17
- "eslint-config-prettier": "^8.5.0",
18
- "eslint-plugin-svelte": "^2.30.0",
19
- "prettier": "^2.8.8",
20
- "prettier-plugin-svelte": "^2.10.1",
21
- "publint": "^0.1.12",
22
- "rimraf": "^5.0.1",
23
- "svelte-check": "^3.4.3",
24
- "svelte-preprocess": "^5.0.4",
25
- "svelte2tsx": "^0.6.19",
26
- "tslib": "^2.4.1",
27
- "type-fest": "^2.13.0",
28
- "typescript": "^5.0.0",
29
- "vite": "^4.3.6",
30
- "@threlte/core": "7.0.4"
9
+ "@sveltejs/adapter-auto": "^3.1.1",
10
+ "@sveltejs/kit": "^2.4.3",
11
+ "@sveltejs/package": "^2.2.6",
12
+ "@sveltejs/vite-plugin-svelte": "^3.0.0",
13
+ "@types/node": "^20.11.6",
14
+ "@types/three": "^0.160.0",
15
+ "@typescript-eslint/eslint-plugin": "^6.19.1",
16
+ "@typescript-eslint/parser": "^6.19.1",
17
+ "@yushijinhun/three-minifier-rollup": "^0.4.0",
18
+ "eslint": "^8.56.0",
19
+ "eslint-config-prettier": "^9.1.0",
20
+ "eslint-plugin-svelte": "^2.35.1",
21
+ "prettier": "^3.2.4",
22
+ "prettier-plugin-svelte": "^3.1.2",
23
+ "publint": "^0.2.7",
24
+ "rimraf": "^5.0.5",
25
+ "svelte": "^4.2.9",
26
+ "svelte-check": "^3.6.3",
27
+ "svelte-preprocess": "^5.1.3",
28
+ "svelte2tsx": "^0.7.0",
29
+ "three": "^0.160.1",
30
+ "tslib": "^2.6.2",
31
+ "type-fest": "^4.10.1",
32
+ "typescript": "^5.3.3",
33
+ "vite": "^5.0.12",
34
+ "@threlte/core": "7.3.1"
31
35
  },
32
36
  "peerDependencies": {
37
+ "@dimforge/rapier3d-compat": ">=0.11",
33
38
  "svelte": ">=4",
34
- "three": ">=0.133",
35
- "@dimforge/rapier3d-compat": ">=0.11"
39
+ "three": ">=0.152"
36
40
  },
37
41
  "type": "module",
42
+ "keywords": [
43
+ "threlte",
44
+ "rapier",
45
+ "svelte",
46
+ "three",
47
+ "three.js",
48
+ "3d",
49
+ "physics"
50
+ ],
51
+ "homepage": "https://threlte.xyz",
52
+ "repository": {
53
+ "type": "git",
54
+ "url": "https://github.com/threlte/threlte.git",
55
+ "directory": "packages/rapier"
56
+ },
57
+ "bugs": {
58
+ "url": "https://github.com/threlte/threlte/issues"
59
+ },
38
60
  "exports": {
39
61
  ".": {
40
62
  "types": "./dist/index.d.ts",
@@ -47,6 +69,7 @@
47
69
  "dist"
48
70
  ],
49
71
  "scripts": {
72
+ "dev": "vite dev",
50
73
  "package": "svelte-kit sync && svelte-package && node ./scripts/cleanupPackage.js && publint",
51
74
  "check": "svelte-check --tsconfig ./tsconfig.json",
52
75
  "check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",