react-three-game 0.0.92 → 0.0.94

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.
Files changed (39) hide show
  1. package/README.md +81 -88
  2. package/dist/helpers/index.d.ts +0 -3
  3. package/dist/helpers/index.js +1 -8
  4. package/dist/index.d.ts +10 -10
  5. package/dist/index.js +7 -6
  6. package/dist/tools/prefabeditor/EditorTree.js +10 -14
  7. package/dist/tools/prefabeditor/EditorUI.js +4 -4
  8. package/dist/tools/prefabeditor/GameEvents.d.ts +6 -12
  9. package/dist/tools/prefabeditor/GameEvents.js +0 -8
  10. package/dist/tools/prefabeditor/InstanceProvider.d.ts +6 -4
  11. package/dist/tools/prefabeditor/InstanceProvider.js +84 -199
  12. package/dist/tools/prefabeditor/PrefabEditor.d.ts +12 -21
  13. package/dist/tools/prefabeditor/PrefabEditor.js +138 -146
  14. package/dist/tools/prefabeditor/PrefabRoot.d.ts +30 -11
  15. package/dist/tools/prefabeditor/PrefabRoot.js +182 -139
  16. package/dist/tools/prefabeditor/assetRuntime.d.ts +9 -13
  17. package/dist/tools/prefabeditor/assetRuntime.js +13 -13
  18. package/dist/tools/prefabeditor/components/BufferGeometryComponent.js +1 -1
  19. package/dist/tools/prefabeditor/components/CameraComponent.js +2 -2
  20. package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +3 -3
  21. package/dist/tools/prefabeditor/components/DirectionalLightComponent.js +2 -2
  22. package/dist/tools/prefabeditor/components/Input.js +5 -9
  23. package/dist/tools/prefabeditor/components/ModelComponent.js +4 -6
  24. package/dist/tools/prefabeditor/components/PointLightComponent.js +2 -2
  25. package/dist/tools/prefabeditor/components/SoundComponent.js +2 -2
  26. package/dist/tools/prefabeditor/components/SpotLightComponent.js +2 -2
  27. package/dist/tools/prefabeditor/components/index.js +0 -2
  28. package/dist/tools/prefabeditor/prefab.d.ts +1 -2
  29. package/dist/tools/prefabeditor/prefab.js +2 -3
  30. package/dist/tools/prefabeditor/prefabStore.d.ts +0 -6
  31. package/dist/tools/prefabeditor/prefabStore.js +1 -33
  32. package/dist/tools/prefabeditor/types.d.ts +1 -0
  33. package/dist/tools/prefabeditor/usePointerEvents.d.ts +3 -3
  34. package/dist/tools/prefabeditor/usePointerEvents.js +5 -5
  35. package/package.json +49 -51
  36. package/dist/tools/prefabeditor/components/PhysicsComponent.d.ts +0 -26
  37. package/dist/tools/prefabeditor/components/PhysicsComponent.js +0 -302
  38. package/dist/tools/prefabeditor/scene.d.ts +0 -70
  39. package/dist/tools/prefabeditor/scene.js +0 -237
@@ -1,302 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
13
- import { BallCollider, CapsuleCollider, CuboidCollider, RigidBody, useRapier } from "@react-three/rapier";
14
- import { useCallback, useEffect, useRef, useState } from 'react';
15
- import { useAssetRuntime, useEntityRuntime } from "../assetRuntime";
16
- import { gameEvents, getEntityIdFromRigidBody } from "../GameEvents";
17
- import { usePrefabNode, usePrefabStore } from "../prefabStore";
18
- import { BooleanField, FieldGroup, NumberField, SelectField, StringField, Vector3Field } from "./Input";
19
- import { findComponent, getNodeUserData } from "../types";
20
- import { colors } from "../styles";
21
- export function isPhysicsProps(v) {
22
- return (v === null || v === void 0 ? void 0 : v.type) === "fixed" || (v === null || v === void 0 ? void 0 : v.type) === "dynamic" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicPosition" || (v === null || v === void 0 ? void 0 : v.type) === "kinematicVelocity";
23
- }
24
- const enabledAxesFallback = [true, true, true];
25
- const manualColliderShapeFallback = 'cuboid';
26
- const colliderSizeFallback = [1, 1, 1];
27
- const colliderRadiusFallback = 0.5;
28
- const capsuleRadiusFallback = 0.35;
29
- const capsuleHalfHeightFallback = 0.45;
30
- const EDIT_MODE_DEBUG_REFRESH_THROTTLE_MS = 120;
31
- function isManualColliderShape(value) {
32
- return value === 'cuboid' || value === 'ball' || value === 'capsule';
33
- }
34
- function hasNodeColliderSource(node) {
35
- return Boolean(findComponent(node, 'Geometry')
36
- || findComponent(node, 'BufferGeometry')
37
- || findComponent(node, 'Model'));
38
- }
39
- function subtreeHasColliderSource(nodeId, nodesById, childIdsById) {
40
- var _a;
41
- if (!nodeId)
42
- return false;
43
- const pending = [nodeId];
44
- while (pending.length > 0) {
45
- const currentId = pending.pop();
46
- if (!currentId)
47
- continue;
48
- const currentNode = nodesById[currentId];
49
- if (hasNodeColliderSource(currentNode)) {
50
- return true;
51
- }
52
- pending.push(...((_a = childIdsById[currentId]) !== null && _a !== void 0 ? _a : []));
53
- }
54
- return false;
55
- }
56
- function renderManualCollider({ shape, sensor, colliderSize, colliderRadius, capsuleRadius, capsuleHalfHeight, }) {
57
- if (shape === 'ball') {
58
- return _jsx(BallCollider, { args: [colliderRadius], sensor: sensor });
59
- }
60
- if (shape === 'capsule') {
61
- return _jsx(CapsuleCollider, { args: [capsuleHalfHeight, capsuleRadius], sensor: sensor });
62
- }
63
- return _jsx(CuboidCollider, { args: colliderSize.map(value => value / 2), sensor: sensor });
64
- }
65
- function LockedAxisField({ label, name, values, onChange, }) {
66
- const enabledAxes = Array.isArray(values[name])
67
- ? values[name]
68
- : enabledAxesFallback;
69
- const axisLabels = ['X', 'Y', 'Z'];
70
- const toggleAxisLock = (index) => {
71
- const nextEnabledAxes = [...enabledAxes];
72
- nextEnabledAxes[index] = !nextEnabledAxes[index];
73
- onChange({ [name]: nextEnabledAxes });
74
- };
75
- return (_jsxs("div", { children: [_jsxs("div", { style: {
76
- display: 'flex',
77
- alignItems: 'center',
78
- justifyContent: 'space-between',
79
- marginBottom: 4,
80
- }, children: [_jsx("span", { style: {
81
- display: 'block',
82
- fontSize: '10px',
83
- color: colors.textMuted,
84
- textTransform: 'uppercase',
85
- letterSpacing: '0.05em',
86
- fontWeight: 500,
87
- }, children: label }), _jsx("span", { style: {
88
- fontSize: '10px',
89
- color: colors.textDim,
90
- }, children: "Active means locked" })] }), _jsx("div", { style: { display: 'flex', gap: 4 }, children: axisLabels.map((axisLabel, index) => {
91
- const isLocked = !enabledAxes[index];
92
- return (_jsx("button", { type: "button", onClick: () => toggleAxisLock(index), style: {
93
- flex: 1,
94
- minHeight: 22,
95
- backgroundColor: isLocked ? colors.dangerBg : colors.bgInput,
96
- border: `1px solid ${isLocked ? colors.dangerBorder : colors.border}`,
97
- borderRadius: 0,
98
- padding: '2px 6px',
99
- color: isLocked ? colors.danger : colors.textMuted,
100
- fontSize: '11px',
101
- fontFamily: 'monospace',
102
- cursor: 'pointer',
103
- }, children: axisLabel }, axisLabel));
104
- }) })] }));
105
- }
106
- function PhysicsComponentEditor({ node, component, onUpdate }) {
107
- const nodeId = node === null || node === void 0 ? void 0 : node.id;
108
- const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
109
- const manualColliderShape = isManualColliderShape(component.properties.manualColliderShape)
110
- ? component.properties.manualColliderShape
111
- : manualColliderShapeFallback;
112
- return (_jsxs(FieldGroup, { children: [_jsx(SelectField, { name: "type", label: "Type", values: component.properties, onChange: onUpdate, options: [
113
- { value: 'dynamic', label: 'Dynamic' },
114
- { value: 'fixed', label: 'Fixed' },
115
- { value: 'kinematicPosition', label: 'Kinematic Position' },
116
- { value: 'kinematicVelocity', label: 'Kinematic Velocity' },
117
- ] }), hasAutomaticColliderSource ? (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "colliders", label: "Collider", values: component.properties, onChange: onUpdate, options: [
118
- { value: 'hull', label: 'Hull (convex)' },
119
- { value: 'trimesh', label: 'Trimesh (exact)' },
120
- { value: 'cuboid', label: 'Cuboid (box)' },
121
- { value: 'ball', label: 'Ball (sphere)' },
122
- { value: 'capsule', label: 'Capsule' },
123
- ] }), component.properties.colliders === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })) : (_jsxs(_Fragment, { children: [_jsx(SelectField, { name: "manualColliderShape", label: "Shape", values: Object.assign(Object.assign({}, component.properties), { manualColliderShape }), onChange: onUpdate, options: [
124
- { value: 'cuboid', label: 'Cuboid (box)' },
125
- { value: 'ball', label: 'Ball (sphere)' },
126
- { value: 'capsule', label: 'Capsule' },
127
- ] }), manualColliderShape === 'cuboid' ? (_jsx(Vector3Field, { name: "colliderSize", label: "Collider Size", values: component.properties, onChange: onUpdate, fallback: colliderSizeFallback })) : null, manualColliderShape === 'ball' ? (_jsx(NumberField, { name: "colliderRadius", label: "Collider Radius", values: component.properties, onChange: onUpdate, fallback: colliderRadiusFallback, min: 0.01, step: 0.01 })) : null, manualColliderShape === 'capsule' ? (_jsxs(_Fragment, { children: [_jsx(NumberField, { name: "capsuleRadius", label: "Capsule Radius", values: component.properties, onChange: onUpdate, fallback: capsuleRadiusFallback, min: 0.01, step: 0.01 }), _jsx(NumberField, { name: "capsuleHalfHeight", label: "Capsule Half Height", values: component.properties, onChange: onUpdate, fallback: capsuleHalfHeightFallback, min: 0.01, step: 0.01 })] })) : null] })), _jsx(NumberField, { name: "mass", label: "Mass", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1, min: 0 }), _jsx(NumberField, { name: "restitution", label: "Restitution (Bounciness)", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, max: 1, step: 0.1 }), _jsx(NumberField, { name: "friction", label: "Friction", values: component.properties, onChange: onUpdate, fallback: 0.5, min: 0, step: 0.1 }), _jsx(NumberField, { name: "linearDamping", label: "Linear Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "angularDamping", label: "Angular Damping", values: component.properties, onChange: onUpdate, fallback: 0, min: 0, step: 0.1 }), _jsx(NumberField, { name: "gravityScale", label: "Gravity Scale", values: component.properties, onChange: onUpdate, fallback: 1, step: 0.1 }), _jsx(Vector3Field, { name: "linearVelocity", label: "Linear Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(Vector3Field, { name: "angularVelocity", label: "Angular Velocity", values: component.properties, onChange: onUpdate, fallback: [0, 0, 0] }), _jsx(LockedAxisField, { label: "Lock Movement", name: "enabledTranslations", values: component.properties, onChange: onUpdate }), _jsx(LockedAxisField, { label: "Lock Rotations", name: "enabledRotations", values: component.properties, onChange: onUpdate }), _jsx(BooleanField, { name: "sensor", label: "Sensor (Trigger Only)", values: component.properties, onChange: onUpdate, fallback: false }), _jsx(BooleanField, { name: "emitCollisionEnterEvent", label: "Emit Collision Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionEnterEvent ? (_jsx(StringField, { name: "collisionEnterEventName", label: "Collision Enter Event", values: component.properties, onChange: onUpdate, placeholder: "target:hit" })) : null, _jsx(BooleanField, { name: "emitCollisionExitEvent", label: "Emit Collision Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitCollisionExitEvent ? (_jsx(StringField, { name: "collisionExitEventName", label: "Collision Exit Event", values: component.properties, onChange: onUpdate, placeholder: "target:reset" })) : null, _jsx(BooleanField, { name: "emitSensorEnterEvent", label: "Emit Sensor Enter", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorEnterEvent ? (_jsx(StringField, { name: "sensorEnterEventName", label: "Sensor Enter Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:enter" })) : null, _jsx(BooleanField, { name: "emitSensorExitEvent", label: "Emit Sensor Exit", values: component.properties, onChange: onUpdate, fallback: false }), component.properties.emitSensorExitEvent ? (_jsx(StringField, { name: "sensorExitEventName", label: "Sensor Exit Event", values: component.properties, onChange: onUpdate, placeholder: "sensor:exit" })) : null, _jsx(SelectField, { name: "activeCollisionTypes", label: "Collision Detection", values: component.properties, onChange: onUpdate, options: [
128
- { value: '', label: 'Default (Dynamic only)' },
129
- { value: 'all', label: 'All (includes kinematic & fixed)' },
130
- ] })] }));
131
- }
132
- function PhysicsComponentView({ properties, children, position, rotation, scale }) {
133
- var _a, _b, _c;
134
- const { registerRigidBodyRef } = useAssetRuntime();
135
- const { editMode, nodeId, getObject } = useEntityRuntime();
136
- const gameObject = usePrefabNode(nodeId);
137
- const hasAutomaticColliderSource = usePrefabStore(state => subtreeHasColliderSource(nodeId, state.nodesById, state.childIdsById));
138
- const nodeName = (_b = (_a = gameObject === null || gameObject === void 0 ? void 0 : gameObject.name) === null || _a === void 0 ? void 0 : _a.trim()) !== null && _b !== void 0 ? _b : '';
139
- const userData = Object.assign(Object.assign({ prefabNodeId: (_c = gameObject === null || gameObject === void 0 ? void 0 : gameObject.id) !== null && _c !== void 0 ? _c : nodeId }, (nodeName ? { prefabNodeName: nodeName } : {})), getNodeUserData(gameObject));
140
- const { type, colliders, sensor, manualColliderShape = manualColliderShapeFallback, activeCollisionTypes, linearVelocity = [0, 0, 0], angularVelocity = [0, 0, 0], colliderSize = colliderSizeFallback, colliderRadius = colliderRadiusFallback, capsuleRadius = capsuleRadiusFallback, capsuleHalfHeight = capsuleHalfHeightFallback, emitSensorEnterEvent = false, sensorEnterEventName, emitSensorExitEvent = false, sensorExitEventName, emitCollisionEnterEvent = false, collisionEnterEventName, emitCollisionExitEvent = false, collisionExitEventName, enabledTranslations = enabledAxesFallback, enabledRotations = enabledAxesFallback } = properties, otherProps = __rest(properties, ["type", "colliders", "sensor", "manualColliderShape", "activeCollisionTypes", "linearVelocity", "angularVelocity", "colliderSize", "colliderRadius", "capsuleRadius", "capsuleHalfHeight", "emitSensorEnterEvent", "sensorEnterEventName", "emitSensorExitEvent", "sensorExitEventName", "emitCollisionEnterEvent", "collisionEnterEventName", "emitCollisionExitEvent", "collisionExitEventName", "enabledTranslations", "enabledRotations"]);
141
- const colliderType = colliders || (type === 'fixed' ? 'trimesh' : 'hull');
142
- const resolvedManualColliderShape = isManualColliderShape(manualColliderShape)
143
- ? manualColliderShape
144
- : manualColliderShapeFallback;
145
- const usesAutomaticColliderSource = hasAutomaticColliderSource && colliderType !== 'capsule';
146
- const manualColliderShapeToRender = hasAutomaticColliderSource
147
- ? 'capsule'
148
- : resolvedManualColliderShape;
149
- const rigidBodyRef = useRef(null);
150
- const [editRefreshVersion, setEditRefreshVersion] = useState(0);
151
- const lastEditRefreshAtRef = useRef(0);
152
- const linearVelocityKey = linearVelocity.join(',');
153
- const angularVelocityKey = angularVelocity.join(',');
154
- const transformSignature = `${position === null || position === void 0 ? void 0 : position.join(',')}_${rotation === null || rotation === void 0 ? void 0 : rotation.join(',')}_${scale === null || scale === void 0 ? void 0 : scale.join(',')}`;
155
- const rbKey = `${type || 'dynamic'}_${colliderType}_${resolvedManualColliderShape}_${colliderSize.join(',')}_${colliderRadius}_${capsuleRadius}_${capsuleHalfHeight}_${editMode ? editRefreshVersion : 0}`;
156
- const handleRigidBodyRef = useCallback((rigidBody) => {
157
- rigidBodyRef.current = rigidBody;
158
- if (!nodeId)
159
- return;
160
- registerRigidBodyRef(nodeId, rigidBody);
161
- }, [nodeId, registerRigidBodyRef]);
162
- // Try to get rapier context - will be null if not inside <Physics>
163
- let rapier = null;
164
- try {
165
- const rapierContext = useRapier();
166
- rapier = rapierContext.rapier;
167
- }
168
- catch (e) {
169
- // Not inside Physics context - that's ok, just won't have rapier features
170
- }
171
- // Configure active collision types for kinematic/sensor bodies
172
- useEffect(() => {
173
- if (activeCollisionTypes === 'all' && rigidBodyRef.current && rapier) {
174
- const rb = rigidBodyRef.current;
175
- // Apply to all colliders on this rigid body
176
- for (let i = 0; i < rb.numColliders(); i++) {
177
- const collider = rb.collider(i);
178
- collider.setActiveCollisionTypes(rapier.ActiveCollisionTypes.DEFAULT |
179
- rapier.ActiveCollisionTypes.KINEMATIC_FIXED |
180
- rapier.ActiveCollisionTypes.KINEMATIC_KINEMATIC);
181
- }
182
- }
183
- }, [activeCollisionTypes, rapier, type, colliders]);
184
- useEffect(() => {
185
- if (!editMode) {
186
- return;
187
- }
188
- const now = Date.now();
189
- const delay = Math.max(0, EDIT_MODE_DEBUG_REFRESH_THROTTLE_MS - (now - lastEditRefreshAtRef.current));
190
- if (delay === 0) {
191
- lastEditRefreshAtRef.current = now;
192
- setEditRefreshVersion(version => version + 1);
193
- return;
194
- }
195
- const timeoutId = setTimeout(() => {
196
- lastEditRefreshAtRef.current = Date.now();
197
- setEditRefreshVersion(version => version + 1);
198
- }, delay);
199
- return () => clearTimeout(timeoutId);
200
- }, [editMode, transformSignature]);
201
- // Seed authored velocities when the body instance changes or the authored values change.
202
- useEffect(() => {
203
- if (!rigidBodyRef.current)
204
- return;
205
- rigidBodyRef.current.setLinvel({
206
- x: linearVelocity[0],
207
- y: linearVelocity[1],
208
- z: linearVelocity[2],
209
- }, true);
210
- }, [rbKey, linearVelocityKey]);
211
- useEffect(() => {
212
- if (!rigidBodyRef.current)
213
- return;
214
- rigidBodyRef.current.setAngvel({
215
- x: angularVelocity[0],
216
- y: angularVelocity[1],
217
- z: angularVelocity[2],
218
- }, true);
219
- }, [rbKey, angularVelocityKey]);
220
- const dispatchPhysicsEvent = useCallback((eventType, payload) => {
221
- var _a, _b, _c;
222
- if (!nodeId)
223
- return;
224
- const trimmedEventType = eventType === null || eventType === void 0 ? void 0 : eventType.trim();
225
- if (!trimmedEventType)
226
- return;
227
- const targetEntityId = getEntityIdFromRigidBody(payload.other.rigidBody);
228
- gameEvents.emit(trimmedEventType, {
229
- sourceEntityId: nodeId,
230
- sourceNodeId: nodeId,
231
- sourceObject: getObject(),
232
- sourceRigidBody: rigidBodyRef.current,
233
- targetEntityId,
234
- targetNodeId: targetEntityId,
235
- targetObject: (_b = (_a = payload.other.rigidBodyObject) !== null && _a !== void 0 ? _a : payload.other.colliderObject) !== null && _b !== void 0 ? _b : null,
236
- targetRigidBody: (_c = payload.other.rigidBody) !== null && _c !== void 0 ? _c : null,
237
- rapierEvent: payload,
238
- });
239
- }, [getObject, nodeId]);
240
- const handleIntersectionEnter = useCallback((payload) => {
241
- if (!emitSensorEnterEvent)
242
- return;
243
- dispatchPhysicsEvent(sensorEnterEventName, payload);
244
- }, [dispatchPhysicsEvent, emitSensorEnterEvent, sensorEnterEventName]);
245
- const handleIntersectionExit = useCallback((payload) => {
246
- if (!emitSensorExitEvent)
247
- return;
248
- dispatchPhysicsEvent(sensorExitEventName, payload);
249
- }, [dispatchPhysicsEvent, emitSensorExitEvent, sensorExitEventName]);
250
- const handleCollisionEnter = useCallback((payload) => {
251
- if (!emitCollisionEnterEvent)
252
- return;
253
- dispatchPhysicsEvent(collisionEnterEventName, payload);
254
- }, [collisionEnterEventName, dispatchPhysicsEvent, emitCollisionEnterEvent]);
255
- const handleCollisionExit = useCallback((payload) => {
256
- if (!emitCollisionExitEvent)
257
- return;
258
- dispatchPhysicsEvent(collisionExitEventName, payload);
259
- }, [collisionExitEventName, dispatchPhysicsEvent, emitCollisionExitEvent]);
260
- const rigidBodyProps = Object.assign({ ref: handleRigidBodyRef, type, colliders: usesAutomaticColliderSource ? colliderType : false, position,
261
- rotation,
262
- scale,
263
- sensor,
264
- enabledTranslations,
265
- enabledRotations, name: nodeName, userData: Object.assign({ entityId: nodeId }, userData), onIntersectionEnter: emitSensorEnterEvent ? handleIntersectionEnter : undefined, onIntersectionExit: emitSensorExitEvent ? handleIntersectionExit : undefined, onCollisionEnter: emitCollisionEnterEvent ? handleCollisionEnter : undefined, onCollisionExit: emitCollisionExitEvent ? handleCollisionExit : undefined }, otherProps);
266
- const rigidBodyContent = (_jsxs(_Fragment, { children: [!usesAutomaticColliderSource ? renderManualCollider({
267
- shape: manualColliderShapeToRender,
268
- sensor,
269
- colliderSize,
270
- colliderRadius,
271
- capsuleRadius,
272
- capsuleHalfHeight,
273
- }) : null, children] }));
274
- return (_jsx(RigidBody, Object.assign({}, rigidBodyProps, { children: rigidBodyContent }), rbKey));
275
- }
276
- const PhysicsComponent = {
277
- name: 'Physics',
278
- Editor: PhysicsComponentEditor,
279
- View: PhysicsComponentView,
280
- defaultProperties: {
281
- type: 'dynamic',
282
- colliders: 'hull',
283
- manualColliderShape: manualColliderShapeFallback,
284
- colliderSize: colliderSizeFallback,
285
- colliderRadius: colliderRadiusFallback,
286
- capsuleRadius: capsuleRadiusFallback,
287
- capsuleHalfHeight: capsuleHalfHeightFallback,
288
- linearVelocity: [0, 0, 0],
289
- angularVelocity: [0, 0, 0],
290
- enabledTranslations: [true, true, true],
291
- enabledRotations: [true, true, true],
292
- emitSensorEnterEvent: false,
293
- sensorEnterEventName: '',
294
- emitSensorExitEvent: false,
295
- sensorExitEventName: '',
296
- emitCollisionEnterEvent: false,
297
- collisionEnterEventName: '',
298
- emitCollisionExitEvent: false,
299
- collisionExitEventName: '',
300
- }
301
- };
302
- export default PhysicsComponent;
@@ -1,70 +0,0 @@
1
- import type { Object3D } from "three";
2
- import type { GameObject } from "./types";
3
- export interface SpawnOptions {
4
- name?: string;
5
- parentId?: string;
6
- select?: boolean;
7
- }
8
- export type EntityData = Omit<GameObject, "children">;
9
- export type PropertyPath = string | Array<string | number>;
10
- export interface EntityComponent<TProperties = Record<string, any>> {
11
- readonly key: string;
12
- readonly type: string;
13
- get: <TValue = unknown>(path?: PropertyPath) => TValue | undefined;
14
- set: (path: PropertyPath, value: unknown) => void;
15
- update: (update: (properties: TProperties) => TProperties) => void;
16
- }
17
- export interface Entity {
18
- readonly id: string;
19
- readonly name: string | undefined;
20
- readonly enabled: boolean;
21
- readonly parent: Entity | null;
22
- readonly children: Entity[];
23
- readonly object: Object3D | null;
24
- readonly rigidBody: any;
25
- set: (data: EntityData) => void;
26
- update: (update: (node: EntityData) => EntityData) => void;
27
- getComponent: <TProperties = Record<string, any>>(name: string) => EntityComponent<TProperties> | null;
28
- addComponent: (type: string, properties?: Record<string, any>) => EntityComponent | null;
29
- removeComponent: (name: string) => void;
30
- destroy: () => void;
31
- }
32
- export type EntityUpdate = (node: EntityData) => EntityData;
33
- export type SceneUpdates = Record<string, EntityUpdate>;
34
- export interface Scene {
35
- readonly rootId: string;
36
- find: (id: string) => Entity | null;
37
- get: (id: string) => Entity;
38
- create: (name: string, components?: Record<string, {
39
- type: string;
40
- properties?: Record<string, any>;
41
- }>, options?: SpawnOptions) => Entity;
42
- update: {
43
- (id: string, update: EntityUpdate): void;
44
- (updates: SceneUpdates): void;
45
- };
46
- add: (node: GameObject, options?: SpawnOptions) => Entity;
47
- remove: (id: string) => void;
48
- /**
49
- * Coalesce many entity / component updates into a single store revision.
50
- * Entity `update`/`set`, `EntityComponent` `set`/`update`, `addComponent`,
51
- * and `removeComponent` calls inside the callback are buffered and flushed
52
- * as one batched write. `add`, `remove`, and `destroy` (structural tree ops)
53
- * still commit immediately.
54
- */
55
- batch: (fn: () => void) => void;
56
- }
57
- interface SceneAdapter {
58
- getRootId: () => string;
59
- getNode: (id: string) => EntityData | null;
60
- getChildIds: (id: string) => string[];
61
- getParentId: (id: string) => string | null;
62
- updateNode: (id: string, update: (node: EntityData) => EntityData) => void;
63
- updateNodes: (updates: Record<string, (node: EntityData) => EntityData>) => void;
64
- addNode: (node: GameObject, options?: SpawnOptions) => string;
65
- removeNode: (id: string) => void;
66
- getObject?: (id: string) => Object3D | null;
67
- getRigidBody?: (id: string) => any;
68
- }
69
- export declare function createScene(adapter: SceneAdapter): Scene;
70
- export {};
@@ -1,237 +0,0 @@
1
- var __rest = (this && this.__rest) || function (s, e) {
2
- var t = {};
3
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
4
- t[p] = s[p];
5
- if (s != null && typeof Object.getOwnPropertySymbols === "function")
6
- for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
7
- if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
8
- t[p[i]] = s[p[i]];
9
- }
10
- return t;
11
- };
12
- import { findComponentEntry } from "./types";
13
- import { createComponentData, createNode as createPrefabNode } from "./prefab";
14
- function missingNode(id) {
15
- throw new Error(`Scene node not found: ${id}`);
16
- }
17
- function normalizePath(path) {
18
- if (!path)
19
- return [];
20
- return Array.isArray(path) ? path : path.split(".").filter(Boolean);
21
- }
22
- function getValueAtPath(value, path) {
23
- const segments = normalizePath(path);
24
- let current = value;
25
- for (const segment of segments) {
26
- if (current == null || typeof current !== "object") {
27
- return undefined;
28
- }
29
- current = current[segment];
30
- }
31
- return current;
32
- }
33
- function setValueAtPath(value, path, nextValue) {
34
- const segments = normalizePath(path);
35
- if (segments.length === 0) {
36
- return nextValue;
37
- }
38
- const cloneBranch = (current, index) => {
39
- const segment = segments[index];
40
- const source = current == null ? undefined : current;
41
- const container = Array.isArray(source)
42
- ? [...source]
43
- : source && typeof source === "object"
44
- ? Object.assign({}, source) : typeof segment === "number"
45
- ? []
46
- : {};
47
- if (index === segments.length - 1) {
48
- container[segment] = nextValue;
49
- return container;
50
- }
51
- const child = source && typeof source === "object"
52
- ? source[segment]
53
- : undefined;
54
- container[segment] = cloneBranch(child, index + 1);
55
- return container;
56
- };
57
- return cloneBranch(value, 0);
58
- }
59
- export function createScene(adapter) {
60
- let batchBuffer = null;
61
- function routeUpdate(id, update) {
62
- if (batchBuffer) {
63
- const prev = batchBuffer.get(id);
64
- batchBuffer.set(id, prev ? (node) => update(prev(node)) : update);
65
- return;
66
- }
67
- adapter.updateNode(id, update);
68
- }
69
- function routeUpdates(updates) {
70
- if (batchBuffer) {
71
- for (const id in updates)
72
- routeUpdate(id, updates[id]);
73
- return;
74
- }
75
- adapter.updateNodes(updates);
76
- }
77
- function batch(fn) {
78
- if (batchBuffer) {
79
- fn();
80
- return;
81
- }
82
- batchBuffer = new Map();
83
- try {
84
- fn();
85
- if (batchBuffer.size > 0) {
86
- const updates = {};
87
- for (const [id, update] of batchBuffer)
88
- updates[id] = update;
89
- adapter.updateNodes(updates);
90
- }
91
- }
92
- finally {
93
- batchBuffer = null;
94
- }
95
- }
96
- const getNode = (id) => {
97
- if (!adapter.getNode(id))
98
- missingNode(id);
99
- return createNode(id);
100
- };
101
- function createComponent(entityId, componentKey, componentType) {
102
- return {
103
- key: componentKey,
104
- type: componentType,
105
- get(path) {
106
- var _a;
107
- const node = adapter.getNode(entityId);
108
- const component = (_a = node === null || node === void 0 ? void 0 : node.components) === null || _a === void 0 ? void 0 : _a[componentKey];
109
- if (!component) {
110
- return undefined;
111
- }
112
- return getValueAtPath(component.properties, path);
113
- },
114
- set(path, value) {
115
- routeUpdate(entityId, node => {
116
- var _a;
117
- const component = (_a = node.components) === null || _a === void 0 ? void 0 : _a[componentKey];
118
- if (!component) {
119
- return node;
120
- }
121
- return Object.assign(Object.assign({}, node), { components: Object.assign(Object.assign({}, node.components), { [componentKey]: Object.assign(Object.assign({}, component), { properties: setValueAtPath(component.properties, path, value) }) }) });
122
- });
123
- },
124
- update(update) {
125
- routeUpdate(entityId, node => {
126
- var _a;
127
- const component = (_a = node.components) === null || _a === void 0 ? void 0 : _a[componentKey];
128
- if (!component) {
129
- return node;
130
- }
131
- const nextProperties = update(component.properties);
132
- if (nextProperties === component.properties) {
133
- return node;
134
- }
135
- return Object.assign(Object.assign({}, node), { components: Object.assign(Object.assign({}, node.components), { [componentKey]: Object.assign(Object.assign({}, component), { properties: nextProperties }) }) });
136
- });
137
- },
138
- };
139
- }
140
- function createNode(id) {
141
- return {
142
- id,
143
- get name() {
144
- var _a;
145
- return (_a = adapter.getNode(id)) === null || _a === void 0 ? void 0 : _a.name;
146
- },
147
- get enabled() {
148
- var _a;
149
- return !((_a = adapter.getNode(id)) === null || _a === void 0 ? void 0 : _a.disabled);
150
- },
151
- get parent() {
152
- const parentId = adapter.getParentId(id);
153
- return parentId ? createNode(parentId) : null;
154
- },
155
- get children() {
156
- return adapter.getChildIds(id).map(createNode);
157
- },
158
- get object() {
159
- var _a, _b;
160
- return (_b = (_a = adapter.getObject) === null || _a === void 0 ? void 0 : _a.call(adapter, id)) !== null && _b !== void 0 ? _b : null;
161
- },
162
- get rigidBody() {
163
- var _a, _b;
164
- return (_b = (_a = adapter.getRigidBody) === null || _a === void 0 ? void 0 : _a.call(adapter, id)) !== null && _b !== void 0 ? _b : null;
165
- },
166
- set(data) {
167
- routeUpdate(id, () => data);
168
- },
169
- update(update) {
170
- routeUpdate(id, update);
171
- },
172
- getComponent(name) {
173
- const node = adapter.getNode(id);
174
- if (!node)
175
- return null;
176
- const entry = findComponentEntry(node, name);
177
- if (!entry)
178
- return null;
179
- const [componentKey, component] = entry;
180
- return createComponent(id, componentKey, component.type);
181
- },
182
- addComponent(type, properties) {
183
- const key = type.toLowerCase();
184
- routeUpdate(id, node => (Object.assign(Object.assign({}, node), { components: Object.assign(Object.assign({}, node.components), { [key]: createComponentData(type, properties) }) })));
185
- return createComponent(id, key, type);
186
- },
187
- removeComponent(name) {
188
- routeUpdate(id, node => {
189
- var _a;
190
- const entry = findComponentEntry(node, name);
191
- if (!entry)
192
- return node;
193
- const [key] = entry;
194
- const _b = (_a = node.components) !== null && _a !== void 0 ? _a : {}, _c = key, _ = _b[_c], rest = __rest(_b, [typeof _c === "symbol" ? _c : _c + ""]);
195
- return Object.assign(Object.assign({}, node), { components: rest });
196
- });
197
- },
198
- destroy() {
199
- adapter.removeNode(id);
200
- },
201
- };
202
- }
203
- function update(idOrUpdates, mutate) {
204
- if (typeof idOrUpdates === "string") {
205
- if (!mutate) {
206
- return;
207
- }
208
- routeUpdate(idOrUpdates, mutate);
209
- return;
210
- }
211
- if (Object.keys(idOrUpdates).length === 0) {
212
- return;
213
- }
214
- routeUpdates(idOrUpdates);
215
- }
216
- return {
217
- get rootId() {
218
- return adapter.getRootId();
219
- },
220
- find(id) {
221
- return adapter.getNode(id) ? createNode(id) : null;
222
- },
223
- get: getNode,
224
- create(name, components, options) {
225
- const node = createPrefabNode(name, components);
226
- return createNode(adapter.addNode(node, options));
227
- },
228
- update,
229
- add(node, options) {
230
- return createNode(adapter.addNode(node, options));
231
- },
232
- remove(id) {
233
- adapter.removeNode(id);
234
- },
235
- batch,
236
- };
237
- }