react-three-game 0.0.107 → 0.0.109

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 (49) hide show
  1. package/README.md +12 -5
  2. package/dist/editor.d.ts +22 -0
  3. package/dist/editor.js +15 -0
  4. package/dist/plugins/crashcat/CrashcatPhysicsComponent.js +75 -47
  5. package/dist/plugins/crashcat/CrashcatRagdoll.d.ts +58 -0
  6. package/dist/plugins/crashcat/CrashcatRagdoll.js +410 -0
  7. package/dist/plugins/crashcat/CrashcatRuntime.js +19 -15
  8. package/dist/plugins/crashcat/index.d.ts +1 -0
  9. package/dist/plugins/crashcat/index.js +1 -0
  10. package/dist/tools/assetviewer/page.js +4 -4
  11. package/dist/tools/prefabeditor/EditorContext.d.ts +36 -0
  12. package/dist/tools/prefabeditor/EditorContext.js +17 -0
  13. package/dist/tools/prefabeditor/EditorTree.js +6 -3
  14. package/dist/tools/prefabeditor/EditorTreeMenus.d.ts +2 -1
  15. package/dist/tools/prefabeditor/EditorTreeMenus.js +18 -6
  16. package/dist/tools/prefabeditor/EditorUI.js +1 -1
  17. package/dist/tools/prefabeditor/GameEvents.d.ts +1 -0
  18. package/dist/tools/prefabeditor/PrefabEditor.d.ts +5 -37
  19. package/dist/tools/prefabeditor/PrefabEditor.js +41 -43
  20. package/dist/tools/prefabeditor/PrefabRoot.d.ts +5 -27
  21. package/dist/tools/prefabeditor/PrefabRoot.js +133 -78
  22. package/dist/tools/prefabeditor/SceneContext.d.ts +28 -0
  23. package/dist/tools/prefabeditor/SceneContext.js +14 -0
  24. package/dist/tools/prefabeditor/assetRuntime.d.ts +4 -0
  25. package/dist/tools/prefabeditor/components/ComponentRegistry.d.ts +16 -1
  26. package/dist/tools/prefabeditor/components/ModelComponent.js +1 -1
  27. package/dist/tools/prefabeditor/components/PrefabRefComponent.d.ts +3 -0
  28. package/dist/tools/prefabeditor/components/PrefabRefComponent.js +72 -0
  29. package/dist/tools/prefabeditor/components/TextComponent.js +8 -5
  30. package/dist/tools/prefabeditor/components/TransformComponent.js +1 -1
  31. package/dist/tools/prefabeditor/components/index.d.ts +1 -0
  32. package/dist/tools/prefabeditor/components/index.js +10 -0
  33. package/dist/tools/prefabeditor/components/runtime.d.ts +4 -0
  34. package/dist/tools/prefabeditor/components/runtime.js +372 -0
  35. package/dist/tools/prefabeditor/modelPrefab.d.ts +3 -0
  36. package/dist/tools/prefabeditor/modelPrefab.js +44 -11
  37. package/dist/tools/prefabeditor/prefab.d.ts +5 -4
  38. package/dist/tools/prefabeditor/prefab.js +47 -29
  39. package/dist/tools/prefabeditor/prefabStore.d.ts +1 -1
  40. package/dist/tools/prefabeditor/prefabStore.js +5 -1
  41. package/dist/tools/prefabeditor/runtimeUtils.d.ts +10 -0
  42. package/dist/tools/prefabeditor/runtimeUtils.js +30 -0
  43. package/dist/tools/prefabeditor/utils.d.ts +7 -8
  44. package/dist/tools/prefabeditor/utils.js +63 -36
  45. package/dist/viewer.d.ts +22 -0
  46. package/dist/viewer.js +14 -0
  47. package/package.json +22 -20
  48. package/dist/index.d.ts +0 -40
  49. package/dist/index.js +0 -32
@@ -9,12 +9,12 @@ var __rest = (this && this.__rest) || function (s, e) {
9
9
  }
10
10
  return t;
11
11
  };
12
- import { getComponentAssetRefs, getComponentDef } from './components/ComponentRegistry';
12
+ import { getComponentAssetRefs, getComponentDef, } from "./components/ComponentRegistry";
13
13
  function clonePrefabValue(value) {
14
14
  if (Array.isArray(value)) {
15
- return value.map(item => clonePrefabValue(item));
15
+ return value.map((item) => clonePrefabValue(item));
16
16
  }
17
- if (value && typeof value === 'object') {
17
+ if (value && typeof value === "object") {
18
18
  const clone = {};
19
19
  Object.entries(value).forEach(([key, entry]) => {
20
20
  clone[key] = clonePrefabValue(entry);
@@ -25,7 +25,7 @@ function clonePrefabValue(value) {
25
25
  }
26
26
  function createComponentMap(components) {
27
27
  const componentMap = {
28
- transform: createComponentData('Transform'),
28
+ transform: createComponentData("Transform"),
29
29
  };
30
30
  Object.entries(components).forEach(([key, component]) => {
31
31
  componentMap[key] = createComponentData(component.type, component.properties);
@@ -33,10 +33,10 @@ function createComponentMap(components) {
33
33
  return componentMap;
34
34
  }
35
35
  function getNodeNameFromPath(path, name) {
36
- return name !== null && name !== void 0 ? name : path.replace(/^.*[\/]/, '').replace(/\.[^.]+$/, '');
36
+ return name !== null && name !== void 0 ? name : path.replace(/^.*[\/]/, "").replace(/\.[^.]+$/, "");
37
37
  }
38
38
  function getAssetManifestKey(assetRefCounts) {
39
- return Object.keys(assetRefCounts).sort().join('|');
39
+ return Object.keys(assetRefCounts).sort().join("|");
40
40
  }
41
41
  function sameStringArrays(left, right) {
42
42
  if (left.length !== right.length)
@@ -46,7 +46,7 @@ function sameStringArrays(left, right) {
46
46
  function getAssetRefs(node) {
47
47
  var _a;
48
48
  const refs = [];
49
- Object.values((_a = node === null || node === void 0 ? void 0 : node.components) !== null && _a !== void 0 ? _a : {}).forEach(component => {
49
+ Object.values((_a = node === null || node === void 0 ? void 0 : node.components) !== null && _a !== void 0 ? _a : {}).forEach((component) => {
50
50
  var _a;
51
51
  if (!(component === null || component === void 0 ? void 0 : component.type))
52
52
  return;
@@ -57,13 +57,13 @@ function getAssetRefs(node) {
57
57
  return refs.sort();
58
58
  }
59
59
  function addAssetRefs(assetRefCounts, refs) {
60
- refs.forEach(ref => {
60
+ refs.forEach((ref) => {
61
61
  var _a;
62
62
  assetRefCounts[ref] = ((_a = assetRefCounts[ref]) !== null && _a !== void 0 ? _a : 0) + 1;
63
63
  });
64
64
  }
65
65
  function removeAssetRefs(assetRefCounts, refs) {
66
- refs.forEach(ref => {
66
+ refs.forEach((ref) => {
67
67
  var _a;
68
68
  const nextCount = ((_a = assetRefCounts[ref]) !== null && _a !== void 0 ? _a : 0) - 1;
69
69
  if (nextCount > 0) {
@@ -75,13 +75,15 @@ function removeAssetRefs(assetRefCounts, refs) {
75
75
  }
76
76
  function createAssetRefCounts(nodesById) {
77
77
  const assetRefCounts = {};
78
- Object.values(nodesById).forEach(node => addAssetRefs(assetRefCounts, getAssetRefs(node)));
78
+ Object.values(nodesById).forEach((node) => {
79
+ addAssetRefs(assetRefCounts, getAssetRefs(node));
80
+ });
79
81
  return assetRefCounts;
80
82
  }
81
83
  function denormalizeNode(id, nodesById, childIdsById) {
82
84
  var _a;
83
85
  const node = nodesById[id];
84
- return Object.assign(Object.assign({}, node), { children: ((_a = childIdsById[id]) !== null && _a !== void 0 ? _a : []).map(childId => denormalizeNode(childId, nodesById, childIdsById)) });
86
+ return Object.assign(Object.assign({}, node), { children: ((_a = childIdsById[id]) !== null && _a !== void 0 ? _a : []).map((childId) => denormalizeNode(childId, nodesById, childIdsById)) });
85
87
  }
86
88
  export function createDefaultComponentProperties(type) {
87
89
  var _a, _b;
@@ -90,32 +92,34 @@ export function createDefaultComponentProperties(type) {
90
92
  export function createComponentData(type, properties) {
91
93
  return {
92
94
  type,
93
- properties: properties ? clonePrefabValue(properties) : createDefaultComponentProperties(type),
95
+ properties: properties
96
+ ? clonePrefabValue(properties)
97
+ : createDefaultComponentProperties(type),
94
98
  };
95
99
  }
96
100
  export function createNode(name, components = {}, options) {
97
101
  var _a;
98
102
  return Object.assign({ id: (_a = options === null || options === void 0 ? void 0 : options.id) !== null && _a !== void 0 ? _a : crypto.randomUUID(), name, components: createComponentMap(components) }, ((options === null || options === void 0 ? void 0 : options.children) ? { children: options.children } : null));
99
103
  }
100
- export function createEmptyNode(name = 'New Node') {
104
+ export function createEmptyNode(name = "New Node") {
101
105
  return createNode(name);
102
106
  }
103
107
  export function createEmptyPrefab() {
104
108
  return {
105
109
  id: crypto.randomUUID(),
106
- name: 'New Prefab',
107
- root: createNode('Root', {}, { id: crypto.randomUUID(), children: [] }),
110
+ name: "New Prefab",
111
+ root: createNode("Root", {}, { id: crypto.randomUUID(), children: [] }),
108
112
  };
109
113
  }
110
114
  export function createModelNode(filename, name) {
111
115
  return createNode(getNodeNameFromPath(filename, name), {
112
116
  model: {
113
- type: 'Model',
117
+ type: "Model",
114
118
  properties: {
115
119
  filename,
116
120
  instanced: false,
117
121
  repeat: false,
118
- repeatAxes: [{ axis: 'x', count: 1, offset: 1 }],
122
+ repeatAxes: [{ axis: "x", count: 1, offset: 1 }],
119
123
  },
120
124
  },
121
125
  });
@@ -123,12 +127,20 @@ export function createModelNode(filename, name) {
123
127
  export function createImageNode(texturePath, name) {
124
128
  return createNode(getNodeNameFromPath(texturePath, name), {
125
129
  geometry: {
126
- type: 'Geometry',
127
- properties: { geometryType: 'plane', args: [1, 1] },
130
+ type: "Geometry",
131
+ properties: { geometryType: "plane", args: [1, 1] },
128
132
  },
129
133
  material: {
130
- type: 'Material',
131
- properties: { color: '#ffffff', texture: texturePath },
134
+ type: "Material",
135
+ properties: { color: "#ffffff", texture: texturePath },
136
+ },
137
+ });
138
+ }
139
+ export function createPackedPrefabNode(url) {
140
+ return createNode("Packed Prefab", {
141
+ prefabref: {
142
+ type: "PrefabRef",
143
+ properties: { url },
132
144
  },
133
145
  });
134
146
  }
@@ -151,10 +163,12 @@ export function normalizePrefab(prefab) {
151
163
  }
152
164
  export function createPrefabPatch(state, patch, nextAssetRefCounts = state.assetRefCounts) {
153
165
  const assetRefsChanged = nextAssetRefCounts !== state.assetRefCounts;
154
- return Object.assign(Object.assign({}, patch), (assetRefsChanged ? {
155
- assetRefCounts: nextAssetRefCounts,
156
- assetManifestKey: getAssetManifestKey(nextAssetRefCounts),
157
- } : null));
166
+ return Object.assign(Object.assign({}, patch), (assetRefsChanged
167
+ ? {
168
+ assetRefCounts: nextAssetRefCounts,
169
+ assetManifestKey: getAssetManifestKey(nextAssetRefCounts),
170
+ }
171
+ : null));
158
172
  }
159
173
  export function denormalizePrefab(state) {
160
174
  return {
@@ -175,9 +189,11 @@ export function insertSubtree(node, parentId, nodesById, childIdsById, parentIdB
175
189
  var _a;
176
190
  const { children } = node, nodeRecord = __rest(node, ["children"]);
177
191
  nodesById[node.id] = nodeRecord;
178
- childIdsById[node.id] = (_a = children === null || children === void 0 ? void 0 : children.map(child => child.id)) !== null && _a !== void 0 ? _a : [];
192
+ childIdsById[node.id] = (_a = children === null || children === void 0 ? void 0 : children.map((child) => child.id)) !== null && _a !== void 0 ? _a : [];
179
193
  parentIdById[node.id] = parentId;
180
- children === null || children === void 0 ? void 0 : children.forEach(child => insertSubtree(child, node.id, nodesById, childIdsById, parentIdById));
194
+ children === null || children === void 0 ? void 0 : children.forEach((child) => {
195
+ insertSubtree(child, node.id, nodesById, childIdsById, parentIdById);
196
+ });
181
197
  }
182
198
  export function cloneSubtree(id, parentId, source, nodesById, childIdsById, parentIdById) {
183
199
  var _a, _b;
@@ -189,7 +205,7 @@ export function cloneSubtree(id, parentId, source, nodesById, childIdsById, pare
189
205
  nodesById[clonedId] = clonedNode;
190
206
  parentIdById[clonedId] = parentId;
191
207
  const clonedChildIds = ((_b = source.childIdsById[id]) !== null && _b !== void 0 ? _b : [])
192
- .map(childId => cloneSubtree(childId, clonedId, source, nodesById, childIdsById, parentIdById))
208
+ .map((childId) => cloneSubtree(childId, clonedId, source, nodesById, childIdsById, parentIdById))
193
209
  .filter((childId) => Boolean(childId));
194
210
  childIdsById[clonedId] = clonedChildIds;
195
211
  return clonedId;
@@ -217,7 +233,9 @@ export function updateAssetRefsForNodeChange(assetRefCounts, currentNode, nextNo
217
233
  export function collectSubtreeAssetRefs(node) {
218
234
  var _a;
219
235
  const refs = getAssetRefs(node);
220
- (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach(child => refs.push(...collectSubtreeAssetRefs(child)));
236
+ (_a = node.children) === null || _a === void 0 ? void 0 : _a.forEach((child) => {
237
+ refs.push(...collectSubtreeAssetRefs(child));
238
+ });
221
239
  return refs;
222
240
  }
223
241
  export function collectAssetRefsForIds(ids, nodesById) {
@@ -15,7 +15,7 @@ export type PrefabStoreApi = StoreApi<PrefabStoreState>;
15
15
  export declare function PrefabStoreProvider({ store, children, }: {
16
16
  store: PrefabStoreApi;
17
17
  children: ReactNode;
18
- }): import("react").FunctionComponentElement<import("react").ProviderProps<PrefabStoreApi | null>>;
18
+ }): import("react").FunctionComponentElement<import("react").FragmentProps> | import("react").FunctionComponentElement<import("react").ProviderProps<PrefabStoreApi | null>>;
19
19
  export declare function usePrefabStoreApi(): PrefabStoreApi;
20
20
  export declare function usePrefabStore<T>(selector: (state: PrefabStoreState) => T): T;
21
21
  export declare function usePrefabRootId(): string;
@@ -1,4 +1,4 @@
1
- import { createContext, createElement, useContext } from "react";
1
+ import { Fragment, createContext, createElement, useContext } from "react";
2
2
  import { subscribeWithSelector } from "zustand/middleware";
3
3
  import { useStore } from "zustand";
4
4
  import { createStore } from "zustand/vanilla";
@@ -45,6 +45,10 @@ function insertSubtreeIntoGraph(node, parentId, next) {
45
45
  addAssetRefs(next.assetRefCounts, collectSubtreeAssetRefs(node));
46
46
  }
47
47
  export function PrefabStoreProvider({ store, children, }) {
48
+ const parentStore = useContext(PrefabStoreContext);
49
+ if (parentStore === store) {
50
+ return createElement(Fragment, null, children);
51
+ }
48
52
  return createElement(PrefabStoreContext.Provider, { value: store }, children);
49
53
  }
50
54
  export function usePrefabStoreApi() {
@@ -0,0 +1,10 @@
1
+ import { Matrix4 } from "three";
2
+ export declare function isExternalPath(path: string): boolean;
3
+ export declare function withBasePath(basePath: string | undefined, path: string): string;
4
+ export declare function decompose(m: Matrix4): {
5
+ position: [number, number, number];
6
+ rotation: [number, number, number];
7
+ scale: [number, number, number];
8
+ };
9
+ /** Build a local Matrix4 from position/rotation/scale arrays. */
10
+ export declare function composeTransform(position?: [number, number, number], rotation?: [number, number, number], scale?: [number, number, number]): Matrix4;
@@ -0,0 +1,30 @@
1
+ import { Euler, Matrix4, Quaternion, Vector3 } from "three";
2
+ export function isExternalPath(path) {
3
+ return (path.startsWith("data:") ||
4
+ path.startsWith("http://") ||
5
+ path.startsWith("https://"));
6
+ }
7
+ export function withBasePath(basePath, path) {
8
+ if (!path)
9
+ return (basePath !== null && basePath !== void 0 ? basePath : "").replace(/\/$/, "");
10
+ if (isExternalPath(path))
11
+ return path;
12
+ const normalizedBasePath = (basePath !== null && basePath !== void 0 ? basePath : "").replace(/\/$/, "");
13
+ return path.startsWith("/") ? `${normalizedBasePath}${path}` : `${normalizedBasePath}/${path}`;
14
+ }
15
+ export function decompose(m) {
16
+ const p = new Vector3();
17
+ const q = new Quaternion();
18
+ const s = new Vector3();
19
+ m.decompose(p, q, s);
20
+ const e = new Euler().setFromQuaternion(q);
21
+ return {
22
+ position: [p.x, p.y, p.z],
23
+ rotation: [e.x, e.y, e.z],
24
+ scale: [s.x, s.y, s.z],
25
+ };
26
+ }
27
+ /** Build a local Matrix4 from position/rotation/scale arrays. */
28
+ export function composeTransform(position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1]) {
29
+ return new Matrix4().compose(new Vector3(...position), new Quaternion().setFromEuler(new Euler(...rotation)), new Vector3(...scale));
30
+ }
@@ -1,5 +1,6 @@
1
1
  import { GameObject, Prefab } from "./types";
2
- import { Matrix4, Object3D, Vector3 } from 'three';
2
+ import { Matrix4, Object3D, Vector3 } from "three";
3
+ export { composeTransform, decompose, isExternalPath, withBasePath } from "./runtimeUtils";
3
4
  export interface ExportGLBOptions {
4
5
  filename?: string;
5
6
  }
@@ -7,6 +8,11 @@ export interface ExportGLBOptions {
7
8
  export declare function saveJson(data: Prefab, filename: string): Promise<void>;
8
9
  /** Load scene JSON from a file */
9
10
  export declare function loadJson(): Promise<Prefab | undefined>;
11
+ /** Load scene JSON from a file, also returning the original filename */
12
+ export declare function loadJsonFile(): Promise<{
13
+ prefab: Prefab;
14
+ filename: string;
15
+ } | undefined>;
10
16
  /**
11
17
  * Export a Three.js scene or object to GLB binary data
12
18
  */
@@ -16,13 +22,6 @@ export declare function exportGLBData(sceneRoot: Object3D): Promise<ArrayBuffer>
16
22
  */
17
23
  export declare function exportGLB(sceneRoot: Object3D, options?: ExportGLBOptions): Promise<ArrayBuffer>;
18
24
  export declare function focusCameraOnObject(object: Object3D, camera: Object3D, target: Vector3, update?: () => void): void;
19
- export declare function decompose(m: Matrix4): {
20
- position: [number, number, number];
21
- rotation: [number, number, number];
22
- scale: [number, number, number];
23
- };
24
- /** Build a local Matrix4 from position/rotation/scale arrays. */
25
- export declare function composeTransform(position?: [number, number, number], rotation?: [number, number, number], scale?: [number, number, number]): Matrix4;
26
25
  /** Compute the parent world matrix for a node using the normalized store data */
27
26
  export declare function computeParentWorldMatrix(state: {
28
27
  nodesById: Record<string, {
@@ -8,17 +8,21 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
8
8
  });
9
9
  };
10
10
  import { findComponent } from "./types";
11
- import { GLTFExporter } from 'three/examples/jsm/exporters/GLTFExporter.js';
12
- import { Box3, Euler, Matrix4, PerspectiveCamera, Quaternion, Vector3 } from 'three';
11
+ import { composeTransform } from "./runtimeUtils";
12
+ import { GLTFExporter } from "three/examples/jsm/exporters/GLTFExporter.js";
13
+ import { Box3, Matrix4, PerspectiveCamera, Quaternion, Vector3, } from "three";
14
+ export { composeTransform, decompose, isExternalPath, withBasePath } from "./runtimeUtils";
13
15
  /** Save scene JSON, showing a Save As dialog when supported */
14
16
  export function saveJson(data, filename) {
15
17
  return __awaiter(this, void 0, void 0, function* () {
16
18
  const json = JSON.stringify(data, null, 2);
17
- if ('showSaveFilePicker' in window) {
19
+ if ("showSaveFilePicker" in window) {
18
20
  try {
19
21
  const handle = yield window.showSaveFilePicker({
20
- suggestedName: `${filename || 'scene'}.json`,
21
- types: [{ description: 'JSON', accept: { 'application/json': ['.json'] } }],
22
+ suggestedName: `${filename || "scene"}.json`,
23
+ types: [
24
+ { description: "JSON", accept: { "application/json": [".json"] } },
25
+ ],
22
26
  });
23
27
  const writable = yield handle.createWritable();
24
28
  yield writable.write(json);
@@ -26,38 +30,70 @@ export function saveJson(data, filename) {
26
30
  return;
27
31
  }
28
32
  catch (e) {
29
- if ((e === null || e === void 0 ? void 0 : e.name) === 'AbortError')
33
+ if ((e === null || e === void 0 ? void 0 : e.name) === "AbortError")
30
34
  return; // user cancelled
31
35
  }
32
36
  }
33
37
  // Fallback for browsers without File System Access API
34
- const a = document.createElement('a');
38
+ const a = document.createElement("a");
35
39
  a.href = "data:text/json;charset=utf-8," + encodeURIComponent(json);
36
- a.download = `${filename || 'scene'}.json`;
40
+ a.download = `${filename || "scene"}.json`;
37
41
  a.click();
38
42
  });
39
43
  }
40
44
  /** Load scene JSON from a file */
41
45
  export function loadJson() {
42
- return new Promise(resolve => {
43
- const input = document.createElement('input');
44
- input.type = 'file';
45
- input.accept = '.json,application/json';
46
- input.onchange = e => {
46
+ return new Promise((resolve) => {
47
+ const input = document.createElement("input");
48
+ input.type = "file";
49
+ input.accept = ".json,application/json";
50
+ input.onchange = (e) => {
47
51
  var _a;
48
52
  const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
49
53
  if (!file)
50
54
  return resolve(undefined);
51
55
  const reader = new FileReader();
52
- reader.onload = e => {
56
+ reader.onload = (e) => {
53
57
  var _a;
54
58
  try {
55
59
  const text = (_a = e.target) === null || _a === void 0 ? void 0 : _a.result;
56
- if (typeof text === 'string')
60
+ if (typeof text === "string")
57
61
  resolve(JSON.parse(text));
58
62
  }
59
63
  catch (err) {
60
- console.error('Error parsing scene JSON:', err);
64
+ console.error("Error parsing scene JSON:", err);
65
+ resolve(undefined);
66
+ }
67
+ };
68
+ reader.readAsText(file);
69
+ };
70
+ input.click();
71
+ });
72
+ }
73
+ /** Load scene JSON from a file, also returning the original filename */
74
+ export function loadJsonFile() {
75
+ return new Promise((resolve) => {
76
+ const input = document.createElement("input");
77
+ input.type = "file";
78
+ input.accept = ".json,application/json";
79
+ input.onchange = (e) => {
80
+ var _a;
81
+ const file = (_a = e.target.files) === null || _a === void 0 ? void 0 : _a[0];
82
+ if (!file)
83
+ return resolve(undefined);
84
+ const reader = new FileReader();
85
+ reader.onload = (ev) => {
86
+ var _a;
87
+ try {
88
+ const text = (_a = ev.target) === null || _a === void 0 ? void 0 : _a.result;
89
+ if (typeof text === "string")
90
+ resolve({
91
+ prefab: JSON.parse(text),
92
+ filename: file.name,
93
+ });
94
+ }
95
+ catch (err) {
96
+ console.error("Error parsing scene JSON:", err);
61
97
  resolve(undefined);
62
98
  }
63
99
  };
@@ -79,12 +115,12 @@ export function exportGLBData(sceneRoot) {
79
115
  */
80
116
  export function exportGLB(sceneRoot_1) {
81
117
  return __awaiter(this, arguments, void 0, function* (sceneRoot, options = {}) {
82
- const { filename = 'scene.glb' } = options;
118
+ const { filename = "scene.glb" } = options;
83
119
  const data = yield exportGLBData(sceneRoot);
84
120
  if (filename) {
85
- const blob = new Blob([data], { type: 'application/octet-stream' });
121
+ const blob = new Blob([data], { type: "application/octet-stream" });
86
122
  const url = URL.createObjectURL(blob);
87
- const a = document.createElement('a');
123
+ const a = document.createElement("a");
88
124
  a.href = url;
89
125
  a.download = filename;
90
126
  a.click();
@@ -110,30 +146,21 @@ export function focusCameraOnObject(object, camera, target, update) {
110
146
  const radius = Math.max(size.length() * 0.5, 1);
111
147
  const forward = new Vector3(0, 0, 1).applyQuaternion(quaternion).normalize();
112
148
  const worldUp = new Vector3(0, 1, 0);
113
- const elevatedDirection = forward.clone().addScaledVector(worldUp, 0.65).normalize();
149
+ const elevatedDirection = forward
150
+ .clone()
151
+ .addScaledVector(worldUp, 0.65)
152
+ .normalize();
114
153
  const distance = camera instanceof PerspectiveCamera
115
- ? Math.max(radius / Math.tan((camera.fov * Math.PI) / 360) * 1.8, radius * 3.5)
154
+ ? Math.max((radius / Math.tan((camera.fov * Math.PI) / 360)) * 1.8, radius * 3.5)
116
155
  : radius * 4.5;
117
- const nextPosition = center.clone().add(elevatedDirection.multiplyScalar(distance));
156
+ const nextPosition = center
157
+ .clone()
158
+ .add(elevatedDirection.multiplyScalar(distance));
118
159
  camera.position.copy(nextPosition);
119
160
  camera.lookAt(center);
120
161
  target.copy(center);
121
162
  update === null || update === void 0 ? void 0 : update();
122
163
  }
123
- export function decompose(m) {
124
- const p = new Vector3(), q = new Quaternion(), s = new Vector3();
125
- m.decompose(p, q, s);
126
- const e = new Euler().setFromQuaternion(q);
127
- return {
128
- position: [p.x, p.y, p.z],
129
- rotation: [e.x, e.y, e.z],
130
- scale: [s.x, s.y, s.z],
131
- };
132
- }
133
- /** Build a local Matrix4 from position/rotation/scale arrays. */
134
- export function composeTransform(position = [0, 0, 0], rotation = [0, 0, 0], scale = [1, 1, 1]) {
135
- return new Matrix4().compose(new Vector3(...position), new Quaternion().setFromEuler(new Euler(...rotation)), new Vector3(...scale));
136
- }
137
164
  /** Compute the parent world matrix for a node using the normalized store data */
138
165
  export function computeParentWorldMatrix(state, targetId) {
139
166
  var _a;
@@ -0,0 +1,22 @@
1
+ import { registerRuntimeComponents } from "./tools/prefabeditor/components/runtime";
2
+ export { registerRuntimeComponents };
3
+ export { default as GameCanvas } from "./shared/GameCanvas";
4
+ export type { GameCanvasProps } from "./shared/GameCanvas";
5
+ export { ground } from "./helpers";
6
+ export type { GroundOptions, Vec3 } from "./helpers";
7
+ export { sound as soundManager } from "./helpers/SoundManager";
8
+ export { default as PrefabRoot } from "./tools/prefabeditor/PrefabRoot";
9
+ export type { PrefabRootProps } from "./tools/prefabeditor/PrefabRoot";
10
+ export { PrefabEditorMode, SceneContext, useScene } from "./tools/prefabeditor/SceneContext";
11
+ export type { PrefabNode, Scene } from "./tools/prefabeditor/SceneContext";
12
+ export type { AssetRuntime, NodeApi, LiveRef } from "./tools/prefabeditor/assetRuntime";
13
+ export { useAssetRuntime, useNode, useNodeHandle, useNodeObject } from "./tools/prefabeditor/assetRuntime";
14
+ export { gameEvents, useClickEvent, useGameEvent } from "./tools/prefabeditor/GameEvents";
15
+ export type { ClickEventPayload, ContactEventPayload, GameEventHandler, GameEventMap } from "./tools/prefabeditor/GameEvents";
16
+ export { registerComponent } from "./tools/prefabeditor/components/ComponentRegistry";
17
+ export type { Component, ComponentViewProps } from "./tools/prefabeditor/components/ComponentRegistry";
18
+ export { denormalizePrefab, createModelNode, createImageNode } from "./tools/prefabeditor/prefab";
19
+ export type { Prefab, GameObject, ComponentData } from "./tools/prefabeditor/types";
20
+ export { findComponent, findComponentEntry, hasComponent } from "./tools/prefabeditor/types";
21
+ export { loadModel, loadSound, loadTexture } from "./tools/dragdrop/modelLoader";
22
+ export type { LoadedModel, LoadedModels, ModelLoadResult, LoadedSound, LoadedSounds, SoundLoadResult, LoadedTexture, LoadedTextures, TextureLoadResult, ProgressCallback, } from "./tools/dragdrop/modelLoader";
package/dist/viewer.js ADDED
@@ -0,0 +1,14 @@
1
+ import { registerRuntimeComponents } from "./tools/prefabeditor/components/runtime";
2
+ registerRuntimeComponents();
3
+ export { registerRuntimeComponents };
4
+ export { default as GameCanvas } from "./shared/GameCanvas";
5
+ export { ground } from "./helpers";
6
+ export { sound as soundManager } from "./helpers/SoundManager";
7
+ export { default as PrefabRoot } from "./tools/prefabeditor/PrefabRoot";
8
+ export { PrefabEditorMode, SceneContext, useScene } from "./tools/prefabeditor/SceneContext";
9
+ export { useAssetRuntime, useNode, useNodeHandle, useNodeObject } from "./tools/prefabeditor/assetRuntime";
10
+ export { gameEvents, useClickEvent, useGameEvent } from "./tools/prefabeditor/GameEvents";
11
+ export { registerComponent } from "./tools/prefabeditor/components/ComponentRegistry";
12
+ export { denormalizePrefab, createModelNode, createImageNode } from "./tools/prefabeditor/prefab";
13
+ export { findComponent, findComponentEntry, hasComponent } from "./tools/prefabeditor/types";
14
+ export { loadModel, loadSound, loadTexture } from "./tools/dragdrop/modelLoader";
package/package.json CHANGED
@@ -1,15 +1,17 @@
1
1
  {
2
2
  "name": "react-three-game",
3
- "version": "0.0.107",
3
+ "version": "0.0.109",
4
4
  "description": "high performance 3D game engine built in React",
5
- "main": "dist/index.js",
6
- "module": "dist/index.js",
7
- "types": "dist/index.d.ts",
8
5
  "exports": {
9
- ".": {
10
- "types": "./dist/index.d.ts",
11
- "import": "./dist/index.js",
12
- "default": "./dist/index.js"
6
+ "./viewer": {
7
+ "types": "./dist/viewer.d.ts",
8
+ "import": "./dist/viewer.js",
9
+ "default": "./dist/viewer.js"
10
+ },
11
+ "./editor": {
12
+ "types": "./dist/editor.d.ts",
13
+ "import": "./dist/editor.js",
14
+ "default": "./dist/editor.js"
13
15
  },
14
16
  "./plugins": {
15
17
  "types": "./dist/plugins/index.d.ts",
@@ -57,18 +59,18 @@
57
59
  }
58
60
  },
59
61
  "devDependencies": {
60
- "@react-three/drei": "^10.7.7",
61
- "@react-three/fiber": "^9.5.0",
62
- "@types/react": "^19.2.9",
63
- "@types/react-dom": "^19.2.3",
64
- "@types/three": "^0.182.0",
65
- "concurrently": "^9.2.1",
66
- "crashcat": "^0.0.4",
67
- "react": "^19.2.4",
68
- "react-dom": "^19.2.4",
69
- "three": "^0.184.0",
70
- "typescript": "^5.9.3",
71
- "vite": "^7.3.1"
62
+ "@react-three/drei": ">=10.7.7",
63
+ "@react-three/fiber": ">=9.6.0",
64
+ "@types/react": ">=19.2.9",
65
+ "@types/react-dom": ">=19.2.3",
66
+ "@types/three": ">=0.184.0",
67
+ "concurrently": ">=9.2.1",
68
+ "crashcat": ">=0.0.4",
69
+ "react": ">=19.2.5",
70
+ "react-dom": ">=19.2.5",
71
+ "three": ">=0.184.0",
72
+ "typescript": ">=6.0.3",
73
+ "vite": ">=8.0.10"
72
74
  },
73
75
  "dependencies": {
74
76
  "zustand": "^5.0.12"
package/dist/index.d.ts DELETED
@@ -1,40 +0,0 @@
1
- export { default as GameCanvas } from './shared/GameCanvas';
2
- export type { GameCanvasProps } from './shared/GameCanvas';
3
- export { ground } from './helpers';
4
- export type { GroundOptions, Vec3 } from './helpers';
5
- export { sound as soundManager } from './helpers/SoundManager';
6
- export { default as PrefabEditor } from './tools/prefabeditor/PrefabEditor';
7
- export { PrefabEditorMode } from './tools/prefabeditor/PrefabRoot';
8
- export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
9
- export { useEditorContext, useEditorRef } from './tools/prefabeditor/PrefabEditor';
10
- export type { EditorContextType } from './tools/prefabeditor/PrefabEditor';
11
- export { usePrefabStore, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
12
- export type { PrefabStoreApi, PrefabStoreState } from './tools/prefabeditor/prefabStore';
13
- export { denormalizePrefab } from './tools/prefabeditor/prefab';
14
- export { gameEvents, useClickEvent, useGameEvent } from './tools/prefabeditor/GameEvents';
15
- export type { ClickEventPayload, ContactEventPayload, GameEventHandler, GameEventMap } from './tools/prefabeditor/GameEvents';
16
- export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
17
- export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from './tools/prefabeditor/components/Input';
18
- export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
19
- export type { ExportGLBOptions } from './tools/prefabeditor/utils';
20
- export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
21
- export { decomposeModelToPrefabNodes } from './tools/prefabeditor/modelPrefab';
22
- export type { DecomposeModelOptions } from './tools/prefabeditor/modelPrefab';
23
- export type { PrefabEditorProps, PrefabNode, PrefabEditorRef, } from './tools/prefabeditor/PrefabEditor';
24
- export type { PrefabRootProps } from './tools/prefabeditor/PrefabRoot';
25
- export type { AssetRuntime, NodeApi, LiveRef } from './tools/prefabeditor/assetRuntime';
26
- export { useAssetRuntime, useNode, useNodeHandle, useNodeObject } from './tools/prefabeditor/assetRuntime';
27
- export type { Scene } from './tools/prefabeditor/PrefabRoot';
28
- export { useScene } from './tools/prefabeditor/PrefabRoot';
29
- export type { Component, ComponentViewProps } from './tools/prefabeditor/components/ComponentRegistry';
30
- export type { FieldDefinition, FieldType } from './tools/prefabeditor/components/Input';
31
- export { MaterialOverridesProvider, useMaterialOverrides } from './tools/prefabeditor/components/MaterialComponent';
32
- export type { MaterialOverrides } from './tools/prefabeditor/components/MaterialComponent';
33
- export type { Prefab, GameObject, ComponentData } from './tools/prefabeditor/types';
34
- export { findComponent, findComponentEntry, hasComponent } from './tools/prefabeditor/types';
35
- export { float, positionLocal, sin, time, uniform, vec3, } from 'three/tsl';
36
- export { loadFiles } from './tools/dragdrop/DragDropLoader';
37
- export type { AssetLoadOptions } from './tools/dragdrop/DragDropLoader';
38
- export { loadModel, loadSound, loadTexture } from './tools/dragdrop/modelLoader';
39
- export type { LoadedModel, LoadedModels, ModelLoadResult, LoadedSound, LoadedSounds, SoundLoadResult, LoadedTexture, LoadedTextures, TextureLoadResult, ProgressCallback, } from './tools/dragdrop/modelLoader';
40
- export { ModelListViewer, SoundListViewer, ModelPicker, SoundPicker, TextureListViewer, TexturePicker, SingleModelViewer, SingleSoundViewer, SingleTextureViewer, SharedCanvas, } from './tools/assetviewer/page';
package/dist/index.js DELETED
@@ -1,32 +0,0 @@
1
- // Core
2
- export { default as GameCanvas } from './shared/GameCanvas';
3
- // Helpers
4
- export { ground } from './helpers';
5
- export { sound as soundManager } from './helpers/SoundManager';
6
- // Prefab Editor
7
- export { default as PrefabEditor } from './tools/prefabeditor/PrefabEditor';
8
- export { PrefabEditorMode } from './tools/prefabeditor/PrefabRoot';
9
- export { default as PrefabRoot } from './tools/prefabeditor/PrefabRoot';
10
- export { useEditorContext, useEditorRef } from './tools/prefabeditor/PrefabEditor';
11
- export { usePrefabStore, usePrefabStoreApi } from './tools/prefabeditor/prefabStore';
12
- // Prefab Editor - Data API
13
- export { denormalizePrefab } from './tools/prefabeditor/prefab';
14
- export { gameEvents, useClickEvent, useGameEvent } from './tools/prefabeditor/GameEvents';
15
- // Prefab Editor - Component Registry
16
- export { registerComponent } from './tools/prefabeditor/components/ComponentRegistry';
17
- // Prefab Editor - Input Components
18
- export { FieldRenderer, FieldGroup, ListEditor, Label, Vector3Input, Vector3Field, NumberField, ColorInput, ColorField, StringInput, StringField, BooleanInput, BooleanField, SelectInput, SelectField, } from './tools/prefabeditor/components/Input';
19
- // Prefab Editor - Utils
20
- export { loadJson, saveJson, exportGLB, exportGLBData, regenerateIds, computeParentWorldMatrix, } from './tools/prefabeditor/utils';
21
- export { createModelNode, createImageNode, } from './tools/prefabeditor/prefab';
22
- export { decomposeModelToPrefabNodes } from './tools/prefabeditor/modelPrefab';
23
- export { useAssetRuntime, useNode, useNodeHandle, useNodeObject } from './tools/prefabeditor/assetRuntime';
24
- export { useScene } from './tools/prefabeditor/PrefabRoot';
25
- export { MaterialOverridesProvider, useMaterialOverrides } from './tools/prefabeditor/components/MaterialComponent';
26
- export { findComponent, findComponentEntry, hasComponent } from './tools/prefabeditor/types';
27
- export { float, positionLocal, sin, time, uniform, vec3, } from 'three/tsl';
28
- // Asset Loading
29
- export { loadFiles } from './tools/dragdrop/DragDropLoader';
30
- export { loadModel, loadSound, loadTexture } from './tools/dragdrop/modelLoader';
31
- // Asset Viewer
32
- export { ModelListViewer, SoundListViewer, ModelPicker, SoundPicker, TextureListViewer, TexturePicker, SingleModelViewer, SingleSoundViewer, SingleTextureViewer, SharedCanvas, } from './tools/assetviewer/page';