react-three-game 0.0.51 → 0.0.52

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,5 +1,7 @@
1
1
  import type { RigidBodyOptions } from "@react-three/rapier";
2
2
  import { Component } from "./ComponentRegistry";
3
- export type PhysicsProps = RigidBodyOptions;
3
+ export type PhysicsProps = RigidBodyOptions & {
4
+ activeCollisionTypes?: 'all' | undefined;
5
+ };
4
6
  declare const PhysicsComponent: Component;
5
7
  export default PhysicsComponent;
@@ -10,7 +10,7 @@ var __rest = (this && this.__rest) || function (s, e) {
10
10
  return t;
11
11
  };
12
12
  import { jsx as _jsx } from "react/jsx-runtime";
13
- import { RigidBody } from "@react-three/rapier";
13
+ import { RigidBody, useRapier } from "@react-three/rapier";
14
14
  import { useRef, useEffect, useCallback } from 'react';
15
15
  import { FieldRenderer } from "./Input";
16
16
  import { gameEvents, getEntityIdFromRigidBody } from "../GameEvents";
@@ -82,14 +82,24 @@ const physicsFields = [
82
82
  type: 'boolean',
83
83
  label: 'Sensor (Trigger Only)',
84
84
  },
85
+ {
86
+ name: 'activeCollisionTypes',
87
+ type: 'select',
88
+ label: 'Collision Detection',
89
+ options: [
90
+ { value: '', label: 'Default (Dynamic only)' },
91
+ { value: 'all', label: 'All (includes kinematic & fixed)' },
92
+ ],
93
+ },
85
94
  ];
86
95
  function PhysicsComponentEditor({ component, onUpdate }) {
87
96
  return (_jsx(FieldRenderer, { fields: physicsFields, values: component.properties, onChange: (props) => onUpdate(Object.assign(Object.assign({}, component), { properties: Object.assign(Object.assign({}, component.properties), props) })) }));
88
97
  }
89
98
  function PhysicsComponentView({ properties, children, position, rotation, scale, editMode, nodeId, registerRigidBodyRef }) {
90
- const { type, colliders, sensor } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor"]);
99
+ const { type, colliders, sensor, activeCollisionTypes } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "activeCollisionTypes"]);
91
100
  const colliderType = colliders || (type === 'fixed' ? 'trimesh' : 'hull');
92
101
  const rigidBodyRef = useRef(null);
102
+ const { rapier } = useRapier();
93
103
  // Register RigidBody ref when it's available
94
104
  useEffect(() => {
95
105
  if (nodeId && registerRigidBodyRef && rigidBodyRef.current) {
@@ -101,6 +111,19 @@ function PhysicsComponentView({ properties, children, position, rotation, scale,
101
111
  }
102
112
  };
103
113
  }, [nodeId, registerRigidBodyRef]);
114
+ // Configure active collision types for kinematic/sensor bodies
115
+ useEffect(() => {
116
+ if (activeCollisionTypes === 'all' && rigidBodyRef.current) {
117
+ const rb = rigidBodyRef.current;
118
+ // Apply to all colliders on this rigid body
119
+ for (let i = 0; i < rb.numColliders(); i++) {
120
+ const collider = rb.collider(i);
121
+ collider.setActiveCollisionTypes(rapier.ActiveCollisionTypes.DEFAULT |
122
+ rapier.ActiveCollisionTypes.KINEMATIC_FIXED |
123
+ rapier.ActiveCollisionTypes.KINEMATIC_KINEMATIC);
124
+ }
125
+ }
126
+ }, [activeCollisionTypes, rapier, type, colliders]);
104
127
  // Event handlers for physics interactions
105
128
  const handleIntersectionEnter = useCallback((payload) => {
106
129
  if (!nodeId)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.51",
3
+ "version": "0.0.52",
4
4
  "description": "Batteries included React Three Fiber game engine",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -22,7 +22,7 @@ Agents can programmatically generate 3D assets:
22
22
  ```tsx
23
23
  import { useRef, useEffect } from 'react';
24
24
  import { PrefabEditor, exportGLBData } from 'react-three-game';
25
- import type { PrefabEditorRef } from 'react-three-game';
25
+ import type { PrefabEditorRef } from 'react-three-game'
26
26
 
27
27
  const jsonPrefab = {
28
28
  root: {
@@ -116,7 +116,7 @@ Scenes are defined as JSON prefabs with a root node containing children:
116
116
  | Transform | `Transform` | `position: [x,y,z]`, `rotation: [x,y,z]` (radians), `scale: [x,y,z]` |
117
117
  | Geometry | `Geometry` | `geometryType`: box/sphere/plane/cylinder, `args`: dimension array |
118
118
  | Material | `Material` | `color`, `texture?`, `metalness?`, `roughness?`, `repeat?`, `repeatCount?` |
119
- | Physics | `Physics` | `type`: dynamic/fixed/kinematicPosition/kinematicVelocity, `mass?`, `restitution?`, `friction?`, `linearDamping?`, `angularDamping?`, `gravityScale?`, plus any Rapier RigidBody props - [See advanced physics guide](./rules/ADVANCED_PHYSICS.md) |
119
+ | Physics | `Physics` | `type`: dynamic/fixed/kinematicPosition/kinematicVelocity, `mass?`, `restitution?`, `friction?`, `linearDamping?`, `angularDamping?`, `gravityScale?`, `sensor?`, `activeCollisionTypes?: 'all'` (enable kinematic/fixed collision detection), plus any Rapier RigidBody props - [See advanced physics guide](./rules/ADVANCED_PHYSICS.md) |
120
120
  | Model | `Model` | `filename` (GLB/FBX path), `instanced?` for GPU batching |
121
121
  | SpotLight | `SpotLight` | `color`, `intensity`, `angle`, `penumbra`, `distance?`, `castShadow?` |
122
122
  | DirectionalLight | `DirectionalLight` | `color`, `intensity`, `castShadow?`, `targetOffset?: [x,y,z]` |
@@ -414,6 +414,8 @@ Physics components automatically emit these events:
414
414
  | `collision:enter` | A collision starts | `{ sourceEntityId, targetEntityId, targetRigidBody }` |
415
415
  | `collision:exit` | A collision ends | `{ sourceEntityId, targetEntityId, targetRigidBody }` |
416
416
 
417
+ **Collision filtering**: By default, kinematic/fixed bodies don't detect each other. For kinematic sensors or projectiles to detect walls/floors, add `"activeCollisionTypes": "all"` to the Physics properties.
418
+
417
419
  See [Advanced Physics](./rules/ADVANCED_PHYSICS.md) for sensor setup and collision handling patterns.
418
420
 
419
421
  ### TypeScript: Typed Custom Events
@@ -49,7 +49,8 @@ Complete reference for `Physics` component properties:
49
49
  | `enabledTranslations` | `[bool, bool, bool]` | `[true, true, true]` | Lock per axis (X, Y, Z) |
50
50
  | `enabledRotations` | `[bool, bool, bool]` | `[true, true, true]` | Lock rotation per axis |
51
51
  | `ccd` | `boolean` | `false` | Continuous collision detection (fast objects) |
52
- | `sensor` | `boolean` | `false` | Trigger only, no collision response (see Sensors & Events) |
52
+ | `sensor` | `boolean` | `false` | Trigger only, no collision response |
53
+ | `activeCollisionTypes` | `'all'` | - | Enable kinematic/fixed collision detection (default: dynamic only) |
53
54
  | `collisionGroups` | `number` | - | Rapier collision groups bitfield |
54
55
  | `solverGroups` | `number` | - | Rapier solver groups bitfield |
55
56
 
@@ -367,6 +368,21 @@ Set `sensor: true` in the Physics component:
367
368
  }
368
369
  ```
369
370
 
371
+ **Kinematic/Fixed Collision Detection**: By default, sensors only detect `dynamic` bodies. For kinematic sensors (like bullets) or to detect kinematic players, add `"activeCollisionTypes": "all"`:
372
+
373
+ ```json
374
+ {
375
+ "physics": {
376
+ "type": "Physics",
377
+ "properties": {
378
+ "type": "kinematicPosition",
379
+ "sensor": true,
380
+ "activeCollisionTypes": "all" // Detects walls, floors, kinematic bodies
381
+ }
382
+ }
383
+ }
384
+ ```
385
+
370
386
  ### Physics Event Payload
371
387
 
372
388
  All physics events include:
@@ -1,4 +1,4 @@
1
- import { RigidBody, RapierRigidBody } from "@react-three/rapier";
1
+ import { RigidBody, RapierRigidBody, useRapier } from "@react-three/rapier";
2
2
  import type { RigidBodyOptions, CollisionPayload, IntersectionEnterPayload, IntersectionExitPayload } from "@react-three/rapier";
3
3
  import type { ReactNode } from 'react';
4
4
  import { useRef, useEffect, useCallback } from 'react';
@@ -7,7 +7,9 @@ import { FieldRenderer, FieldDefinition } from "./Input";
7
7
  import { ComponentData } from "../types";
8
8
  import { gameEvents, getEntityIdFromRigidBody } from "../GameEvents";
9
9
 
10
- export type PhysicsProps = RigidBodyOptions;
10
+ export type PhysicsProps = RigidBodyOptions & {
11
+ activeCollisionTypes?: 'all' | undefined;
12
+ };
11
13
 
12
14
  const physicsFields: FieldDefinition[] = [
13
15
  {
@@ -77,6 +79,15 @@ const physicsFields: FieldDefinition[] = [
77
79
  type: 'boolean',
78
80
  label: 'Sensor (Trigger Only)',
79
81
  },
82
+ {
83
+ name: 'activeCollisionTypes',
84
+ type: 'select',
85
+ label: 'Collision Detection',
86
+ options: [
87
+ { value: '', label: 'Default (Dynamic only)' },
88
+ { value: 'all', label: 'All (includes kinematic & fixed)' },
89
+ ],
90
+ },
80
91
  ];
81
92
 
82
93
  function PhysicsComponentEditor({ component, onUpdate }: { component: ComponentData; onUpdate: (newComp: any) => void }) {
@@ -101,9 +112,10 @@ interface PhysicsViewProps {
101
112
  }
102
113
 
103
114
  function PhysicsComponentView({ properties, children, position, rotation, scale, editMode, nodeId, registerRigidBodyRef }: PhysicsViewProps) {
104
- const { type, colliders, sensor, ...otherProps } = properties;
115
+ const { type, colliders, sensor, activeCollisionTypes, ...otherProps } = properties;
105
116
  const colliderType = colliders || (type === 'fixed' ? 'trimesh' : 'hull');
106
117
  const rigidBodyRef = useRef<RapierRigidBody>(null);
118
+ const { rapier } = useRapier();
107
119
 
108
120
  // Register RigidBody ref when it's available
109
121
  useEffect(() => {
@@ -117,6 +129,22 @@ function PhysicsComponentView({ properties, children, position, rotation, scale,
117
129
  };
118
130
  }, [nodeId, registerRigidBodyRef]);
119
131
 
132
+ // Configure active collision types for kinematic/sensor bodies
133
+ useEffect(() => {
134
+ if (activeCollisionTypes === 'all' && rigidBodyRef.current) {
135
+ const rb = rigidBodyRef.current;
136
+ // Apply to all colliders on this rigid body
137
+ for (let i = 0; i < rb.numColliders(); i++) {
138
+ const collider = rb.collider(i);
139
+ collider.setActiveCollisionTypes(
140
+ rapier.ActiveCollisionTypes.DEFAULT |
141
+ rapier.ActiveCollisionTypes.KINEMATIC_FIXED |
142
+ rapier.ActiveCollisionTypes.KINEMATIC_KINEMATIC
143
+ );
144
+ }
145
+ }
146
+ }, [activeCollisionTypes, rapier, type, colliders]);
147
+
120
148
  // Event handlers for physics interactions
121
149
  const handleIntersectionEnter = useCallback((payload: IntersectionEnterPayload) => {
122
150
  if (!nodeId) return;