@buoy-gg/three 0.0.0-stage → 7.0.65
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.
- package/LICENSE +58 -0
- package/README.md +50 -2
- package/lib/commonjs/index.js +1 -0
- package/lib/commonjs/loads.js +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/panel.js +1 -0
- package/lib/commonjs/runtime.js +1 -0
- package/lib/commonjs/snapshot.js +1 -0
- package/lib/commonjs/stats.js +1 -0
- package/lib/module/index.js +1 -0
- package/lib/module/loads.js +1 -0
- package/lib/module/panel.js +1 -0
- package/lib/module/runtime.js +1 -0
- package/lib/module/snapshot.js +1 -0
- package/lib/module/stats.js +1 -0
- package/lib/typescript/index.d.ts +31 -0
- package/lib/typescript/loads.d.ts +13 -0
- package/lib/typescript/panel.d.ts +14 -0
- package/lib/typescript/runtime.d.ts +57 -0
- package/lib/typescript/snapshot.d.ts +20 -0
- package/lib/typescript/stats.d.ts +23 -0
- package/lib/web/index.mjs +1 -0
- package/package.json +102 -3
package/LICENSE
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
PROPRIETARY SOFTWARE LICENSE
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2024-present Buoy. All rights reserved.
|
|
4
|
+
|
|
5
|
+
This software and its source code are proprietary and confidential.
|
|
6
|
+
|
|
7
|
+
NOTICE: This is NOT open source software. This software is licensed,
|
|
8
|
+
not sold, and is protected by copyright laws and international treaties.
|
|
9
|
+
|
|
10
|
+
TERMS AND CONDITIONS:
|
|
11
|
+
|
|
12
|
+
1. LICENSE GRANT
|
|
13
|
+
Subject to the terms of this Agreement and payment of applicable fees,
|
|
14
|
+
Buoy grants you a limited, non-exclusive, non-transferable license
|
|
15
|
+
to use the compiled software packages in your applications.
|
|
16
|
+
|
|
17
|
+
2. RESTRICTIONS
|
|
18
|
+
You may NOT:
|
|
19
|
+
- Copy, modify, or distribute the source code
|
|
20
|
+
- Reverse engineer, decompile, or disassemble the software
|
|
21
|
+
- Remove or alter any proprietary notices or labels
|
|
22
|
+
- Sublicense, rent, lease, or lend the software
|
|
23
|
+
- Use the software to create competing products
|
|
24
|
+
- Share access credentials with unauthorized parties
|
|
25
|
+
|
|
26
|
+
3. OWNERSHIP
|
|
27
|
+
React Buoy retains all right, title, and interest in the software,
|
|
28
|
+
including all intellectual property rights. This license does not
|
|
29
|
+
grant you any rights to trademarks or service marks.
|
|
30
|
+
|
|
31
|
+
4. TERMINATION
|
|
32
|
+
This license is effective until terminated. Your rights under this
|
|
33
|
+
license will terminate automatically without notice if you fail to
|
|
34
|
+
comply with any of its terms. Upon termination, you must cease all
|
|
35
|
+
use and destroy all copies of the software.
|
|
36
|
+
|
|
37
|
+
5. DISCLAIMER OF WARRANTIES
|
|
38
|
+
THE SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
|
|
39
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
40
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NONINFRINGEMENT.
|
|
41
|
+
|
|
42
|
+
6. LIMITATION OF LIABILITY
|
|
43
|
+
IN NO EVENT SHALL BUOY BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
|
|
44
|
+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ARISING OUT OF OR IN
|
|
45
|
+
CONNECTION WITH THIS LICENSE OR THE USE OF THE SOFTWARE.
|
|
46
|
+
|
|
47
|
+
7. GOVERNING LAW
|
|
48
|
+
This Agreement shall be governed by and construed in accordance with
|
|
49
|
+
the laws of the United States, without regard to its conflict of
|
|
50
|
+
law provisions.
|
|
51
|
+
|
|
52
|
+
For licensing inquiries and subscription information:
|
|
53
|
+
- Website: https://buoy.gg
|
|
54
|
+
- Email: AustinLovesWorking@gmail.com
|
|
55
|
+
|
|
56
|
+
Unauthorized reproduction or distribution of this software, or any
|
|
57
|
+
portion of it, may result in severe civil and criminal penalties,
|
|
58
|
+
and will be prosecuted to the maximum extent possible under the law.
|
package/README.md
CHANGED
|
@@ -1,3 +1,51 @@
|
|
|
1
|
-
|
|
1
|
+
---
|
|
2
|
+
title: Scene (Beta)
|
|
3
|
+
description: See and edit a three.js scene.
|
|
4
|
+
---
|
|
2
5
|
|
|
3
|
-
|
|
6
|
+
# Scene (Beta)
|
|
7
|
+
|
|
8
|
+
See the tree of objects in your 3D app. Pick a node to draw a box around it. Hide it, move it, turn it, or change its size. You can change a mesh's color too.
|
|
9
|
+
|
|
10
|
+
## Set it up
|
|
11
|
+
|
|
12
|
+
Three.js support is in Beta. Use the `beta` tag once it ships.
|
|
13
|
+
Keep all Buoy packages on the same beta release.
|
|
14
|
+
Install `@buoy-gg/three@beta` with `three` in your web app. Add its module to Buoy's `modules` map.
|
|
15
|
+
|
|
16
|
+
```tsx
|
|
17
|
+
import * as threeTools from '@buoy-gg/three/web';
|
|
18
|
+
import * as perfMonitor from '@buoy-gg/perf-monitor/web';
|
|
19
|
+
import * as assets from '@buoy-gg/assets/web';
|
|
20
|
+
import * as events from '@buoy-gg/events/web';
|
|
21
|
+
import { registerThree } from '@buoy-gg/three/web';
|
|
22
|
+
|
|
23
|
+
const modules = { three: threeTools, 'perf-monitor': perfMonitor, assets, events };
|
|
24
|
+
// Add these modules to your FloatingDevTools or mountBuoy options.
|
|
25
|
+
const stop = registerThree({ renderer, scene, camera, loadingManager });
|
|
26
|
+
// Call stop() when the scene is replaced or torn down.
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
Call `stop()` on hot reload too. Each renderer has its own group. In R3F, call this in an effect with `useThree()`. Pass `gl` as `renderer`. Return `stop` from the effect.
|
|
30
|
+
|
|
31
|
+
The early boot hook can find scenes and renderers. It cannot tell which ones belong together. Use `registerThree` to link them. Load `@buoy-gg/core/web/register` before three.js, as shown in the [web guide](https://buoy.gg/buoy/latest/docs/web/three).
|
|
32
|
+
|
|
33
|
+
## Counts and loads
|
|
34
|
+
|
|
35
|
+
Perf Monitor shows counts after the app renders. WebGL and WebGPU have different fields. A field with no data shows as unknown. Counts are objects, not bytes. A count that keeps rising says "Keeps growing". A cache can cause this too.
|
|
36
|
+
|
|
37
|
+
Buoy does not reset counts or change `autoReset`. With many render passes, counts follow your reset rules. With no new render, the last counts stay on screen.
|
|
38
|
+
|
|
39
|
+
Assets and Events show file loads. Buoy watches `DefaultLoadingManager`. Pass a custom manager to `registerThree` to watch it too. Size and time come from the browser's resource timing. If that data is absent, they stay unknown. Cache hits show when the cache or browser proves a hit.
|
|
40
|
+
|
|
41
|
+
## Scene edits
|
|
42
|
+
|
|
43
|
+
Each tree has at most 500 nodes. Long names are cut short. The panel tells you when it hits the node limit. Turn values use radians. Enter three numbers for a move, turn, or size. Colors use six digit hex, such as `#ff8800`.
|
|
44
|
+
|
|
45
|
+
Each field needs a value. Live changes keep your draft until you press Save.
|
|
46
|
+
|
|
47
|
+
A box marks the picked node's bounds at the time you pick it. Clear it with "Clear box". App code may overwrite an edit on its next frame.
|
|
48
|
+
|
|
49
|
+
Desktop uses this same panel. MCP has `get_three_scene`, `get_three_stats`, and `three_action`. MCP needs a paid account. Read the scene first to get IDs for edits.
|
|
50
|
+
|
|
51
|
+
Workers and WebXR are not supported. For full screen, use a wrapper around the canvas. A bare canvas cannot show Buoy's DOM panel.
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});Object.defineProperty(exports,"MAX_SCENE_NODES",{enumerable:true,get:function(){return _snapshot.MAX_SCENE_NODES}});Object.defineProperty(exports,"ThreeModal",{enumerable:true,get:function(){return _panel.ThreeModal}});Object.defineProperty(exports,"ThreeToolView",{enumerable:true,get:function(){return _panel.ThreeToolView}});exports.createThreeTool=void 0;Object.defineProperty(exports,"disposeThree",{enumerable:true,get:function(){return _runtime.disposeThree}});Object.defineProperty(exports,"getThreeScene",{enumerable:true,get:function(){return _runtime.getThreeScene}});Object.defineProperty(exports,"getThreeStats",{enumerable:true,get:function(){return _runtime.getThreeStats}});Object.defineProperty(exports,"onThreeLoad",{enumerable:true,get:function(){return _loads.onThreeLoad}});Object.defineProperty(exports,"registerThree",{enumerable:true,get:function(){return _runtime.registerThree}});Object.defineProperty(exports,"snapshotScene",{enumerable:true,get:function(){return _snapshot.snapshotScene}});Object.defineProperty(exports,"startThreeCapture",{enumerable:true,get:function(){return _runtime.startThreeCapture}});Object.defineProperty(exports,"subscribeThree",{enumerable:true,get:function(){return _runtime.subscribeThree}});Object.defineProperty(exports,"threeAction",{enumerable:true,get:function(){return _runtime.threeAction}});Object.defineProperty(exports,"threeSyncAdapter",{enumerable:true,get:function(){return _runtime.threeSyncAdapter}});exports.threeToolPreset=void 0;var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _panel=require("./panel");var _jsxRuntime=require("react/jsx-runtime");var _runtime=require("./runtime");var _snapshot=require("./snapshot");var _loads=require("./loads");const threeToolPreset=exports.threeToolPreset=(0,_sharedUi.defineToolPreset)({id:"three",name:"SCENE",description:"See and edit the 3D scene.",slot:"both",icon:({size:e,color:r})=>(0,_jsxRuntime.jsx)(_reactNative.Text,{style:{fontSize:e,color:r??"#F59E0B"},children:"\u25C7"}),component:_panel.ThreeModal});const createThreeTool=exports.createThreeTool=(0,_sharedUi.createToolFactory)(threeToolPreset);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.loadDetails=loadDetails;exports.onThreeLoad=void 0;exports.watchLoadingManager=watchLoadingManager;var _three=require("three");var _assets=require("@buoy-gg/assets");const listeners=new Set;let sequence=0;const onThreeLoad=t=>{listeners.add(t);return()=>{listeners.delete(t)}};exports.onThreeLoad=onThreeLoad;function loadDetails(t,o,s,i){let r;if(typeof performance!=="undefined"&&typeof performance.getEntriesByName==="function"){let c;try{c=typeof document!=="undefined"?new URL(t,document.baseURI).href:t}catch{c=t}r=performance.getEntriesByName(c,"resource").filter(a=>a.responseEnd>=i).pop()}return{url:t,status:o,bytes:r&&r.encodedBodySize>0?r.encodedBodySize:null,durationMs:r?r.duration:null,cacheHit:s===true?true:r&&r.encodedBodySize>0?r.transferSize===0:null}}const managers=new WeakMap;function managerRelease(t){let o=false;return()=>{if(o)return;o=true;const s=t.deref();if(!s)return;const i=managers.get(s);if(i&&--i.users===0){i.stop();managers.delete(s)}}}function watchLoadingManager(t){const o=new WeakRef(t);const s=managers.get(t);if(s){s.users++;return managerRelease(o)}const i=t.itemStart,r=t.itemEnd,c=t.itemError;const a=new Map;function h(e){const n=a.get(e)??[];const f=_three.Cache.get(`image-bitmap:${e}`);n.push({started:performance.now(),cached:_three.Cache.get(`file:${e}`)!==void 0||_three.Cache.get(`image:${e}`)?.complete===true||f!==void 0&&typeof f?.then!=="function"||_three.Cache.get(e)!==void 0,failed:false});a.set(e,n);return i.call(this,e)}function l(e,n){const f=a.get(e);const d=f?.[0];if(!d||d.failed)return;d.failed=n;const u=loadDetails(e,n?"error":"success",d.cached,d.started);try{(0,_assets.recordBrowserAssetLoad)(u)}catch{}const g={id:`three-load-${++sequence}`,source:"three",timestamp:Date.now(),title:n?"Load failed":u.cacheHit?"Cache hit":"Loaded",subtitle:e.slice(0,512),status:u.status,originalEvent:u};listeners.forEach(y=>{try{y(g)}catch{}})}function p(e){l(e,false);const n=a.get(e);n?.shift();if(!n?.length)a.delete(e);return r.call(this,e)}function m(e){l(e,true);return c.call(this,e)}t.itemStart=h;t.itemEnd=p;t.itemError=m;managers.set(t,{users:1,stop:()=>{const e=o.deref();if(e?.itemStart===h)e.itemStart=i;if(e?.itemEnd===p)e.itemEnd=r;if(e?.itemError===m)e.itemError=c;a.clear()}});return managerRelease(o)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"type":"commonjs"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.ThreeModal=ThreeModal;exports.ThreeToolView=ThreeToolView;var _react=require("react");var _reactNative=require("react-native");var _sharedUi=require("@buoy-gg/shared-ui");var _runtime=require("./runtime");var _jsxRuntime=require("react/jsx-runtime");const text={color:_sharedUi.night.color.text,fontSize:13};function Field({label:s,value:n,save:h}){const[x,l]=(0,_react.useState)(n);const[r,a]=(0,_react.useState)(false);(0,_react.useEffect)(()=>{if(!r)l(n)},[n,r]);return(0,_jsxRuntime.jsxs)(_reactNative.View,{style:{flexDirection:"row",gap:8,padding:4},children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:s}),(0,_jsxRuntime.jsx)(_reactNative.TextInput,{testID:`three-edit-${s}`,accessibilityLabel:s,value:x,onChangeText:u=>{l(u);a(true)},style:[text,{borderWidth:1,borderColor:"#666",padding:4,flex:1}]}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`three-save-${s}`,onPress:()=>{h(x);a(false)},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Save"})})]})}function ThreeToolView({scenes:s,dispatch:n,refresh:h}){const[x,l]=(0,_react.useState)(_runtime.getThreeScene);const[r,a]=(0,_react.useState)();const[u,T]=(0,_react.useState)("");(0,_react.useEffect)(()=>s?void 0:(0,_runtime.subscribeThree)(()=>l((0,_runtime.getThreeScene)())),[s]);const f=s??x;const o=async e=>{try{await(n??_runtime.threeAction)(e);T("");if(!s)l((0,_runtime.getThreeScene)())}catch(t){T(t instanceof Error?t.message:"The change failed.")}};const i=f.find(e=>e.id===r?.rendererId)?.nodes.find(e=>e.id===r?.id);return(0,_jsxRuntime.jsxs)(_reactNative.ScrollView,{testID:"three-panel",style:{flex:1,backgroundColor:_sharedUi.night.color.bg},contentContainerStyle:{padding:12,gap:8},children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:[text,{fontSize:18}],children:"Scene"}),!f.length&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"No scene found. Call registerThree in your app."}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"three-refresh",onPress:async()=>{try{if(h)await h();else l((0,_runtime.getThreeScene)());T("")}catch(e){T(e instanceof Error?e.message:"The refresh failed.")}},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Refresh"})}),i&&r&&(0,_jsxRuntime.jsxs)(_reactNative.View,{testID:"three-details",children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:i.name||i.type}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"three-visible",onPress:()=>void o({...r,action:"visible",value:!i.visible}),children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:i.visible?"Hide":"Show"})}),["position","rotation","scale"].map(e=>(0,_jsxRuntime.jsx)(Field,{label:e,value:i[e].join(", "),save:t=>void o({...r,action:e,value:t.split(",").map(d=>d.trim()?Number(d):NaN)})},e)),(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Turn values use radians."}),i.color&&(0,_jsxRuntime.jsx)(Field,{label:"color",value:i.color,save:e=>void o({...r,action:"color",value:e})}),(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:"three-clear-selection",onPress:()=>{void o({...r,action:"clearSelection"});a(void 0)},children:(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Clear box"})})]},`${r.rendererId}:${r.id}`),f.map(e=>(0,_jsxRuntime.jsxs)(_reactNative.View,{children:[(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:e.id}),!e.nodes.length&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Pass a scene to registerThree to link this view."}),e.nodes.map(t=>(0,_jsxRuntime.jsx)(_reactNative.TouchableOpacity,{testID:`three-node-${t.name||t.type}`,onPress:()=>{a({rendererId:e.id,id:t.id});void o({rendererId:e.id,id:t.id,action:"select"})},children:(0,_jsxRuntime.jsxs)(_reactNative.Text,{style:[text,{padding:5,paddingLeft:5+Math.min(20,(()=>{let d=0;let c=t.parent;const p=new Set;while(c&&!p.has(c)){p.add(c);d++;c=e.nodes.find(y=>y.id===c)?.parent??null}return d})())*12}],children:[t.visible?"\u25CF":"\u25CB"," ",t.name||t.type]})},t.id)),e.truncated&&(0,_jsxRuntime.jsx)(_reactNative.Text,{style:text,children:"Tree limit reached. Some nodes are left out."})]},e.id)),!!u&&(0,_jsxRuntime.jsx)(_reactNative.Text,{accessibilityRole:"alert",style:text,children:u})]})}function ThreeModal({visible:s,onClose:n}){return(0,_jsxRuntime.jsx)(_sharedUi.JsModal,{visible:s,onClose:n,header:{title:"Scene"},initialMode:"bottomSheet",disableScrollWrapper:true,children:(0,_jsxRuntime.jsx)(ThreeToolView,{})})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.disposeThree=disposeThree;exports.getThreeScene=getThreeScene;exports.getThreeStats=getThreeStats;exports.registerThree=registerThree;exports.startThreeCapture=startThreeCapture;exports.subscribeThree=subscribeThree;exports.threeAction=threeAction;exports.threeSyncAdapter=void 0;var _three=require("three");var _perfMonitor=require("@buoy-gg/perf-monitor");var _three2=require("@buoy-gg/core/three");var _stats=require("./stats");var _snapshot=require("./snapshot");var _loads=require("./loads");const entries=new Map;const listeners=new Set;let nextId=0;let dirty=false;let timer;let stopBoot;let stopDefault;const changed=()=>{dirty=true};function remove(e){e.stop();e.helper?.deref()?.removeFromParent();e.helper?.deref()?.dispose();entries.delete(e.id);changed()}function add(e,t,n,o){for(const i of entries.values()){if(e&&i.renderer?.deref()===e||t&&i.scene?.deref()===t&&!i.renderer)remove(i)}if(entries.size>=32)remove(entries.values().next().value);const r=`three-${++nextId}`;const s={id:r,renderer:e&&new WeakRef(e),scene:t&&new WeakRef(t),camera:n&&new WeakRef(n),stop:()=>{}};const a=(0,_perfMonitor.registerPerfSeries)(r);const f=e?(0,_stats.observeRenderer)(e,i=>{s.stats=i;a.update(["calls","triangles","geometries","textures","programs"].map(c=>({id:`${r}:${c}`,label:`${r} ${c}`,value:i[c],unit:"count",note:i.note})));changed()}):()=>{};const u=o&&o!==_three.DefaultLoadingManager?(0,_loads.watchLoadingManager)(o):()=>{};s.stop=()=>{f();u();a.dispose()};entries.set(r,s);changed();return()=>{if(entries.get(r)===s)remove(s)}}function registerThree(e){startThreeCapture();return add(e.renderer,e.scene,e.camera,e.loadingManager)}function startThreeCapture(){if(timer)return;stopDefault=(0,_loads.watchLoadingManager)(_three.DefaultLoadingManager);if(typeof window!=="undefined")stopBoot=(0,_three2.subscribeThreeBootEvents)(({type:e,detail:t})=>{if(e!=="observe"||!t||typeof t!=="object")return;const n=t;if(n.isScene&&![...entries.values()].some(o=>o.scene?.deref()===n))add(void 0,n);if(n.info&&typeof n.render==="function"&&![...entries.values()].some(o=>o.renderer?.deref()===n))add(n)});timer=setInterval(()=>{for(const e of entries.values()){if(e.renderer&&!e.renderer.deref()||e.scene&&!e.scene.deref())remove(e)}if(dirty){dirty=false;listeners.forEach(e=>e())}},500)}function disposeThree(){stopBoot?.();stopDefault?.();stopBoot=void 0;stopDefault=void 0;if(timer)clearInterval(timer);timer=void 0;for(const e of entries.values())remove(e)}function subscribeThree(e){listeners.add(e);return()=>{listeners.delete(e)}}function getThreeStats(){return[...entries.values()].map(e=>({id:e.id,stats:e.stats??null}))}function getThreeScene(){return[...entries.values()].map(e=>({id:e.id,...e.scene?.deref()&&(0,_snapshot.snapshotScene)(e.scene.deref())||{nodes:[],truncated:false}}))}function threeAction(e){const t=entries.get(e.rendererId);const n=t?.scene?.deref();if(!t||!n)throw new Error("Scene not found. Refresh the list.");if(e.action==="clearSelection"){t.helper?.deref()?.removeFromParent();t.helper?.deref()?.dispose();t.helper=void 0;return{ok:true}}const o=e.id&&(0,_snapshot.findSceneObject)(n,e.id);if(!o)throw new Error("Object not found in this scene.");switch(e.action){case"select":{t.helper?.deref()?.removeFromParent();t.helper?.deref()?.dispose();o.updateWorldMatrix(true,false);const r=new _three.BoxHelper(o,16776960);r.userData.__buoyThreeHelper=true;n.add(r);t.helper=new WeakRef(r);break}case"visible":if(typeof e.value!=="boolean")throw new Error("Use true or false.");o.visible=e.value;break;case"position":case"rotation":case"scale":{const r=e.value;if(!Array.isArray(r)||r.length!==3||!r.every(s=>typeof s==="number"&&Number.isFinite(s)))throw new Error("Use three finite numbers.");o[e.action].set(r[0],r[1],r[2]);break}case"color":{if(typeof e.value!=="string"||!/^#[0-9a-f]{6}$/i.test(e.value))throw new Error("Use a six digit hex color.");const r=o.material;const s=Array.isArray(r)?r:[r];if(!s.some(a=>a?.color?.isColor))throw new Error("This object has no color.");s.forEach(a=>a?.color?.set(e.value));break}default:throw new Error("Unknown scene action.")}o.updateWorldMatrix(true,false);t.helper?.deref()?.update();changed();return{ok:true}}const threeSyncAdapter=exports.threeSyncAdapter={version:1,getSnapshot:()=>({scenes:getThreeScene(),stats:getThreeStats()}),subscribe:subscribeThree,actions:{getScene:()=>{changed();return getThreeScene()},getStats:getThreeStats,action:e=>threeAction(e)}};const hotHost=globalThis;hotHost.__buoyThreeDispose?.();hotHost.__buoyThreeDispose=disposeThree;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.MAX_SCENE_NODES=void 0;exports.findSceneObject=findSceneObject;exports.snapshotScene=snapshotScene;const MAX_SCENE_NODES=exports.MAX_SCENE_NODES=500;function collectSceneNodes(i,o=MAX_SCENE_NODES){const n=Number.isFinite(o)?Math.max(1,Math.min(MAX_SCENE_NODES,Math.floor(o))):MAX_SCENE_NODES;const r=[];const t=[{node:i,parent:null}];const c=new Set;let s=false;while(t.length&&r.length<n){const{node:e,parent:u}=t.pop();if(c.has(e)||e.userData.__buoyThreeHelper)continue;c.add(e);r.push({node:e,parent:u});const l=n-r.length-t.length;if(e.children.length>l)s=true;for(let a=Math.min(e.children.length,l)-1;a>=0;a--)t.push({node:e.children[a],parent:e.uuid})}return{nodes:r,truncated:s||t.length>0}}function snapshotScene(i,o=MAX_SCENE_NODES){const n=collectSceneNodes(i,o);const r=n.nodes.map(({node:t,parent:c})=>{const s=t.material;const e=(Array.isArray(s)?s[0]:s)?.color;return{id:t.uuid,parent:c,name:t.name.slice(0,160),type:t.type.slice(0,80),visible:t.visible,position:t.position.toArray(),rotation:[t.rotation.x,t.rotation.y,t.rotation.z],scale:t.scale.toArray(),color:e?.isColor?`#${e.getHexString()}`:null}});return{nodes:r,truncated:n.truncated}}function findSceneObject(i,o){return collectSceneNodes(i).nodes.find(({node:n})=>n.uuid===o)?.node}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:true});exports.observeRenderer=observeRenderer;exports.readThreeStats=readThreeStats;const count=e=>typeof e==="number"&&Number.isFinite(e)?e:null;function readThreeStats(e){const{render:s,memory:t,programs:r}=e.info;const o=e.isWebGPURenderer===true;return{kind:o?"WebGPU":"WebGL",calls:count(o?s?.drawCalls:s?.calls),triangles:count(s?.triangles),geometries:count(t?.geometries),textures:count(t?.textures),programs:o?count(t?.programs):Array.isArray(r)?r.length:null}}const renderHooks=new WeakMap;function rendererCleanup(e,s){return()=>{const t=e.deref();if(!t)return;const r=renderHooks.get(t);if(!r||s&&r.token!==s)return;r.deactivate();if(t.render===r.wrapped)t.render=r.original;renderHooks.delete(t)}}function observeRenderer(e,s){const t=new WeakRef(e);rendererCleanup(t)();const r={};const o=e.render;let i=false;let u=true;let c;let l=0;let f=0;function d(){if(i||!u)return;i=true;queueMicrotask(()=>{i=false;const a=t.deref();if(!u||!a)return;const n=readThreeStats(a);const g=Date.now();if(g-f>=1e3){const b=c&&["geometries","textures"].some(h=>{const m=c[h];const w=n[h];return m!==null&&w!==null&&w>m});l=b?l+1:0;c=n;f=g}if(l>=5)n.note="Keeps growing";try{s(n)}catch{}})}function p(...a){const n=o.apply(this,a);if(n&&typeof n.then==="function")n.then(d,()=>{});else d();return n}e.render=p;renderHooks.set(e,{token:r,original:o,wrapped:p,deactivate:()=>{u=false}});return rendererCleanup(t,r)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{Text as o}from"react-native";import{defineToolPreset as t,createToolFactory as s}from"@buoy-gg/shared-ui";import{ThreeModal as h}from"./panel";import{jsx as i}from"react/jsx-runtime";export{registerThree,startThreeCapture,disposeThree,getThreeScene,getThreeStats,threeAction,threeSyncAdapter,subscribeThree}from"./runtime";export{snapshotScene,MAX_SCENE_NODES}from"./snapshot";export{onThreeLoad}from"./loads";export{ThreeToolView,ThreeModal}from"./panel";export const threeToolPreset=t({id:"three",name:"SCENE",description:"See and edit the 3D scene.",slot:"both",icon:({size:e,color:r})=>i(o,{style:{fontSize:e,color:r??"#F59E0B"},children:"\u25C7"}),component:h});export const createThreeTool=s(threeToolPreset);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{Cache as m}from"three";import{recordBrowserAssetLoad as B}from"@buoy-gg/assets";const l=new Set;let L=0;export const onThreeLoad=t=>{l.add(t);return()=>{l.delete(t)}};export function loadDetails(t,o,i,s){let n;if(typeof performance!=="undefined"&&typeof performance.getEntriesByName==="function"){let a;try{a=typeof document!=="undefined"?new URL(t,document.baseURI).href:t}catch{a=t}n=performance.getEntriesByName(a,"resource").filter(c=>c.responseEnd>=s).pop()}return{url:t,status:o,bytes:n&&n.encodedBodySize>0?n.encodedBodySize:null,durationMs:n?n.duration:null,cacheHit:i===true?true:n&&n.encodedBodySize>0?n.transferSize===0:null}}const p=new WeakMap;function y(t){let o=false;return()=>{if(o)return;o=true;const i=t.deref();if(!i)return;const s=p.get(i);if(s&&--s.users===0){s.stop();p.delete(i)}}}export function watchLoadingManager(t){const o=new WeakRef(t);const i=p.get(t);if(i){i.users++;return y(o)}const s=t.itemStart,n=t.itemEnd,a=t.itemError;const c=new Map;function h(e){const r=c.get(e)??[];const f=m.get(`image-bitmap:${e}`);r.push({started:performance.now(),cached:m.get(`file:${e}`)!==void 0||m.get(`image:${e}`)?.complete===true||f!==void 0&&typeof f?.then!=="function"||m.get(e)!==void 0,failed:false});c.set(e,r);return s.call(this,e)}function g(e,r){const f=c.get(e);const d=f?.[0];if(!d||d.failed)return;d.failed=r;const u=loadDetails(e,r?"error":"success",d.cached,d.started);try{B(u)}catch{}const S={id:`three-load-${++L}`,source:"three",timestamp:Date.now(),title:r?"Load failed":u.cacheHit?"Cache hit":"Loaded",subtitle:e.slice(0,512),status:u.status,originalEvent:u};l.forEach(b=>{try{b(S)}catch{}})}function E(e){g(e,false);const r=c.get(e);r?.shift();if(!r?.length)c.delete(e);return n.call(this,e)}function w(e){g(e,true);return a.call(this,e)}t.itemStart=h;t.itemEnd=E;t.itemError=w;p.set(t,{users:1,stop:()=>{const e=o.deref();if(e?.itemStart===h)e.itemStart=s;if(e?.itemEnd===E)e.itemEnd=n;if(e?.itemError===w)e.itemError=a;c.clear()}});return y(o)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{useEffect as w,useState as u}from"react";import{ScrollView as $,Text as n,TextInput as E,TouchableOpacity as y,View as I}from"react-native";import{JsModal as M,night as C}from"@buoy-gg/shared-ui";import{getThreeScene as T,threeAction as N,subscribeThree as L}from"./runtime";import{jsx as t,jsxs as v}from"react/jsx-runtime";const r={color:C.color.text,fontSize:13};function P({label:l,value:d,save:b}){const[g,a]=u(d);const[s,c]=u(false);w(()=>{if(!s)a(d)},[d,s]);return v(I,{style:{flexDirection:"row",gap:8,padding:4},children:[t(n,{style:r,children:l}),t(E,{testID:`three-edit-${l}`,accessibilityLabel:l,value:g,onChangeText:S=>{a(S);c(true)},style:[r,{borderWidth:1,borderColor:"#666",padding:4,flex:1}]}),t(y,{testID:`three-save-${l}`,onPress:()=>{b(g);c(false)},children:t(n,{style:r,children:"Save"})})]})}export function ThreeToolView({scenes:l,dispatch:d,refresh:b}){const[g,a]=u(T);const[s,c]=u();const[S,x]=u("");w(()=>l?void 0:L(()=>a(T())),[l]);const m=l??g;const h=async e=>{try{await(d??N)(e);x("");if(!l)a(T())}catch(i){x(i instanceof Error?i.message:"The change failed.")}};const o=m.find(e=>e.id===s?.rendererId)?.nodes.find(e=>e.id===s?.id);return v($,{testID:"three-panel",style:{flex:1,backgroundColor:C.color.bg},contentContainerStyle:{padding:12,gap:8},children:[t(n,{style:[r,{fontSize:18}],children:"Scene"}),!m.length&&t(n,{style:r,children:"No scene found. Call registerThree in your app."}),t(y,{testID:"three-refresh",onPress:async()=>{try{if(b)await b();else a(T());x("")}catch(e){x(e instanceof Error?e.message:"The refresh failed.")}},children:t(n,{style:r,children:"Refresh"})}),o&&s&&v(I,{testID:"three-details",children:[t(n,{style:r,children:o.name||o.type}),t(y,{testID:"three-visible",onPress:()=>void h({...s,action:"visible",value:!o.visible}),children:t(n,{style:r,children:o.visible?"Hide":"Show"})}),["position","rotation","scale"].map(e=>t(P,{label:e,value:o[e].join(", "),save:i=>void h({...s,action:e,value:i.split(",").map(f=>f.trim()?Number(f):NaN)})},e)),t(n,{style:r,children:"Turn values use radians."}),o.color&&t(P,{label:"color",value:o.color,save:e=>void h({...s,action:"color",value:e})}),t(y,{testID:"three-clear-selection",onPress:()=>{void h({...s,action:"clearSelection"});c(void 0)},children:t(n,{style:r,children:"Clear box"})})]},`${s.rendererId}:${s.id}`),m.map(e=>v(I,{children:[t(n,{style:r,children:e.id}),!e.nodes.length&&t(n,{style:r,children:"Pass a scene to registerThree to link this view."}),e.nodes.map(i=>t(y,{testID:`three-node-${i.name||i.type}`,onPress:()=>{c({rendererId:e.id,id:i.id});void h({rendererId:e.id,id:i.id,action:"select"})},children:v(n,{style:[r,{padding:5,paddingLeft:5+Math.min(20,(()=>{let f=0;let p=i.parent;const D=new Set;while(p&&!D.has(p)){D.add(p);f++;p=e.nodes.find(j=>j.id===p)?.parent??null}return f})())*12}],children:[i.visible?"\u25CF":"\u25CB"," ",i.name||i.type]})},i.id)),e.truncated&&t(n,{style:r,children:"Tree limit reached. Some nodes are left out."})]},e.id)),!!S&&t(n,{accessibilityRole:"alert",style:r,children:S})]})}export function ThreeModal({visible:l,onClose:d}){return t(M,{visible:l,onClose:d,header:{title:"Scene"},initialMode:"bottomSheet",disableScrollWrapper:true,children:t(ThreeToolView,{})})}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{BoxHelper as T,DefaultLoadingManager as m}from"three";import{registerPerfSeries as E}from"@buoy-gg/perf-monitor";import{subscribeThreeBootEvents as k}from"@buoy-gg/core/three";import{observeRenderer as j}from"./stats";import{snapshotScene as A,findSceneObject as M}from"./snapshot";import{watchLoadingManager as g}from"./loads";const s=new Map;const h=new Set;let R=0;let p=false;let a;let v;let b;const d=()=>{p=true};function l(e){e.stop();e.helper?.deref()?.removeFromParent();e.helper?.deref()?.dispose();s.delete(e.id);d()}function w(e,t,n,o){for(const f of s.values()){if(e&&f.renderer?.deref()===e||t&&f.scene?.deref()===t&&!f.renderer)l(f)}if(s.size>=32)l(s.values().next().value);const r=`three-${++R}`;const i={id:r,renderer:e&&new WeakRef(e),scene:t&&new WeakRef(t),camera:n&&new WeakRef(n),stop:()=>{}};const c=E(r);const S=e?j(e,f=>{i.stats=f;c.update(["calls","triangles","geometries","textures","programs"].map(u=>({id:`${r}:${u}`,label:`${r} ${u}`,value:f[u],unit:"count",note:f.note})));d()}):()=>{};const y=o&&o!==m?g(o):()=>{};i.stop=()=>{S();y();c.dispose()};s.set(r,i);d();return()=>{if(s.get(r)===i)l(i)}}export function registerThree(e){startThreeCapture();return w(e.renderer,e.scene,e.camera,e.loadingManager)}export function startThreeCapture(){if(a)return;b=g(m);if(typeof window!=="undefined")v=k(({type:e,detail:t})=>{if(e!=="observe"||!t||typeof t!=="object")return;const n=t;if(n.isScene&&![...s.values()].some(o=>o.scene?.deref()===n))w(void 0,n);if(n.info&&typeof n.render==="function"&&![...s.values()].some(o=>o.renderer?.deref()===n))w(n)});a=setInterval(()=>{for(const e of s.values()){if(e.renderer&&!e.renderer.deref()||e.scene&&!e.scene.deref())l(e)}if(p){p=false;h.forEach(e=>e())}},500)}export function disposeThree(){v?.();b?.();v=void 0;b=void 0;if(a)clearInterval(a);a=void 0;for(const e of s.values())l(e)}export function subscribeThree(e){h.add(e);return()=>{h.delete(e)}}export function getThreeStats(){return[...s.values()].map(e=>({id:e.id,stats:e.stats??null}))}export function getThreeScene(){return[...s.values()].map(e=>({id:e.id,...e.scene?.deref()&&A(e.scene.deref())||{nodes:[],truncated:false}}))}export function threeAction(e){const t=s.get(e.rendererId);const n=t?.scene?.deref();if(!t||!n)throw new Error("Scene not found. Refresh the list.");if(e.action==="clearSelection"){t.helper?.deref()?.removeFromParent();t.helper?.deref()?.dispose();t.helper=void 0;return{ok:true}}const o=e.id&&M(n,e.id);if(!o)throw new Error("Object not found in this scene.");switch(e.action){case"select":{t.helper?.deref()?.removeFromParent();t.helper?.deref()?.dispose();o.updateWorldMatrix(true,false);const r=new T(o,16776960);r.userData.__buoyThreeHelper=true;n.add(r);t.helper=new WeakRef(r);break}case"visible":if(typeof e.value!=="boolean")throw new Error("Use true or false.");o.visible=e.value;break;case"position":case"rotation":case"scale":{const r=e.value;if(!Array.isArray(r)||r.length!==3||!r.every(i=>typeof i==="number"&&Number.isFinite(i)))throw new Error("Use three finite numbers.");o[e.action].set(r[0],r[1],r[2]);break}case"color":{if(typeof e.value!=="string"||!/^#[0-9a-f]{6}$/i.test(e.value))throw new Error("Use a six digit hex color.");const r=o.material;const i=Array.isArray(r)?r:[r];if(!i.some(c=>c?.color?.isColor))throw new Error("This object has no color.");i.forEach(c=>c?.color?.set(e.value));break}default:throw new Error("Unknown scene action.")}o.updateWorldMatrix(true,false);t.helper?.deref()?.update();d();return{ok:true}}export const threeSyncAdapter={version:1,getSnapshot:()=>({scenes:getThreeScene(),stats:getThreeStats()}),subscribe:subscribeThree,actions:{getScene:()=>{d();return getThreeScene()},getStats:getThreeStats,action:e=>threeAction(e)}};const x=globalThis;x.__buoyThreeDispose?.();x.__buoyThreeDispose=disposeThree;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";export const MAX_SCENE_NODES=500;function u(s,r=MAX_SCENE_NODES){const n=Number.isFinite(r)?Math.max(1,Math.min(MAX_SCENE_NODES,Math.floor(r))):MAX_SCENE_NODES;const o=[];const t=[{node:s,parent:null}];const c=new Set;let i=false;while(t.length&&o.length<n){const{node:e,parent:h}=t.pop();if(c.has(e)||e.userData.__buoyThreeHelper)continue;c.add(e);o.push({node:e,parent:h});const l=n-o.length-t.length;if(e.children.length>l)i=true;for(let a=Math.min(e.children.length,l)-1;a>=0;a--)t.push({node:e.children[a],parent:e.uuid})}return{nodes:o,truncated:i||t.length>0}}export function snapshotScene(s,r=MAX_SCENE_NODES){const n=u(s,r);const o=n.nodes.map(({node:t,parent:c})=>{const i=t.material;const e=(Array.isArray(i)?i[0]:i)?.color;return{id:t.uuid,parent:c,name:t.name.slice(0,160),type:t.type.slice(0,80),visible:t.visible,position:t.position.toArray(),rotation:[t.rotation.x,t.rotation.y,t.rotation.z],scale:t.scale.toArray(),color:e?.isColor?`#${e.getHexString()}`:null}});return{nodes:o,truncated:n.truncated}}export function findSceneObject(s,r){return u(s).nodes.find(({node:n})=>n.uuid===r)?.node}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";const i=e=>typeof e==="number"&&Number.isFinite(e)?e:null;export function readThreeStats(e){const{render:s,memory:t,programs:r}=e.info;const o=e.isWebGPURenderer===true;return{kind:o?"WebGPU":"WebGL",calls:i(o?s?.drawCalls:s?.calls),triangles:i(s?.triangles),geometries:i(t?.geometries),textures:i(t?.textures),programs:o?i(t?.programs):Array.isArray(r)?r.length:null}}const d=new WeakMap;function y(e,s){return()=>{const t=e.deref();if(!t)return;const r=d.get(t);if(!r||s&&r.token!==s)return;r.deactivate();if(t.render===r.wrapped)t.render=r.original;d.delete(t)}}export function observeRenderer(e,s){const t=new WeakRef(e);y(t)();const r={};const o=e.render;let u=false;let c=true;let l;let f=0;let g=0;function p(){if(u||!c)return;u=true;queueMicrotask(()=>{u=false;const a=t.deref();if(!c||!a)return;const n=readThreeStats(a);const m=Date.now();if(m-g>=1e3){const x=l&&["geometries","textures"].some(w=>{const b=l[w];const k=n[w];return b!==null&&k!==null&&k>b});f=x?f+1:0;l=n;g=m}if(f>=5)n.note="Keeps growing";try{s(n)}catch{}})}function h(...a){const n=o.apply(this,a);if(n&&typeof n.then==="function")n.then(p,()=>{});else p();return n}e.render=h;d.set(e,{token:r,original:o,wrapped:h,deactivate:()=>{c=false}});return y(t,r)}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ThreeModal } from "./panel";
|
|
2
|
+
export { registerThree, startThreeCapture, disposeThree, getThreeScene, getThreeStats, threeAction, threeSyncAdapter, subscribeThree, } from "./runtime";
|
|
3
|
+
export type { ThreeRegistration, ThreeAction } from "./runtime";
|
|
4
|
+
export { snapshotScene, MAX_SCENE_NODES } from "./snapshot";
|
|
5
|
+
export type { SceneNode, SceneSnapshot } from "./snapshot";
|
|
6
|
+
export { onThreeLoad } from "./loads";
|
|
7
|
+
export { ThreeToolView, ThreeModal } from "./panel";
|
|
8
|
+
export type { ThreeScenes } from "./panel";
|
|
9
|
+
export declare const threeToolPreset: {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
description: string;
|
|
13
|
+
slot: "both";
|
|
14
|
+
icon: ({ size, color }: {
|
|
15
|
+
size: number;
|
|
16
|
+
color?: string;
|
|
17
|
+
}) => import("react").JSX.Element;
|
|
18
|
+
component: typeof ThreeModal;
|
|
19
|
+
};
|
|
20
|
+
export declare const createThreeTool: (options?: (Record<never, never> & import("@buoy-gg/shared-ui").ToolPresetOverrides) | undefined) => {
|
|
21
|
+
id: string;
|
|
22
|
+
name: string;
|
|
23
|
+
description: string;
|
|
24
|
+
slot: "both";
|
|
25
|
+
icon: ({ size, color }: {
|
|
26
|
+
size: number;
|
|
27
|
+
color?: string;
|
|
28
|
+
}) => import("react").JSX.Element;
|
|
29
|
+
component: typeof ThreeModal;
|
|
30
|
+
};
|
|
31
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { type LoadingManager } from "three";
|
|
2
|
+
import type { UnifiedEvent } from "@buoy-gg/events";
|
|
3
|
+
export interface ThreeLoad {
|
|
4
|
+
url: string;
|
|
5
|
+
status: "success" | "error";
|
|
6
|
+
bytes: number | null;
|
|
7
|
+
durationMs: number | null;
|
|
8
|
+
cacheHit: boolean | null;
|
|
9
|
+
}
|
|
10
|
+
export declare const onThreeLoad: (listener: (event: UnifiedEvent) => void) => () => void;
|
|
11
|
+
export declare function loadDetails(url: string, status: ThreeLoad["status"], cacheHit: boolean | null, started: number): ThreeLoad;
|
|
12
|
+
export declare function watchLoadingManager(manager: LoadingManager): () => void;
|
|
13
|
+
//# sourceMappingURL=loads.d.ts.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { getThreeScene, type ThreeAction } from "./runtime";
|
|
2
|
+
export type ThreeScenes = ReturnType<typeof getThreeScene>;
|
|
3
|
+
type Props = {
|
|
4
|
+
scenes?: ThreeScenes;
|
|
5
|
+
dispatch?: (params: ThreeAction) => unknown;
|
|
6
|
+
refresh?: () => unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare function ThreeToolView({ scenes: remote, dispatch, refresh }: Props): import("react").JSX.Element;
|
|
9
|
+
export declare function ThreeModal({ visible, onClose, }: {
|
|
10
|
+
visible: boolean;
|
|
11
|
+
onClose: () => void;
|
|
12
|
+
}): import("react").JSX.Element;
|
|
13
|
+
export {};
|
|
14
|
+
//# sourceMappingURL=panel.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import { type Camera, type LoadingManager, type Object3D } from "three";
|
|
2
|
+
import { type RendererLike, type ThreeStats } from "./stats";
|
|
3
|
+
export interface ThreeRegistration {
|
|
4
|
+
renderer: RendererLike;
|
|
5
|
+
scene: Object3D;
|
|
6
|
+
camera: Camera;
|
|
7
|
+
loadingManager?: LoadingManager;
|
|
8
|
+
}
|
|
9
|
+
export declare function registerThree(options: ThreeRegistration): () => void;
|
|
10
|
+
export declare function startThreeCapture(): void;
|
|
11
|
+
export declare function disposeThree(): void;
|
|
12
|
+
export declare function subscribeThree(listener: () => void): () => void;
|
|
13
|
+
export declare function getThreeStats(): {
|
|
14
|
+
id: string;
|
|
15
|
+
stats: ThreeStats | null;
|
|
16
|
+
}[];
|
|
17
|
+
export declare function getThreeScene(): {
|
|
18
|
+
nodes: import("./snapshot").SceneNode[];
|
|
19
|
+
truncated: boolean;
|
|
20
|
+
id: string;
|
|
21
|
+
}[];
|
|
22
|
+
export type ThreeAction = {
|
|
23
|
+
rendererId: string;
|
|
24
|
+
id?: string;
|
|
25
|
+
action: "select" | "clearSelection" | "visible" | "position" | "rotation" | "scale" | "color";
|
|
26
|
+
value?: unknown;
|
|
27
|
+
};
|
|
28
|
+
export declare function threeAction(params: ThreeAction): {
|
|
29
|
+
ok: boolean;
|
|
30
|
+
};
|
|
31
|
+
export declare const threeSyncAdapter: {
|
|
32
|
+
version: number;
|
|
33
|
+
getSnapshot: () => {
|
|
34
|
+
scenes: {
|
|
35
|
+
nodes: import("./snapshot").SceneNode[];
|
|
36
|
+
truncated: boolean;
|
|
37
|
+
id: string;
|
|
38
|
+
}[];
|
|
39
|
+
stats: {
|
|
40
|
+
id: string;
|
|
41
|
+
stats: ThreeStats | null;
|
|
42
|
+
}[];
|
|
43
|
+
};
|
|
44
|
+
subscribe: typeof subscribeThree;
|
|
45
|
+
actions: {
|
|
46
|
+
getScene: () => {
|
|
47
|
+
nodes: import("./snapshot").SceneNode[];
|
|
48
|
+
truncated: boolean;
|
|
49
|
+
id: string;
|
|
50
|
+
}[];
|
|
51
|
+
getStats: typeof getThreeStats;
|
|
52
|
+
action: (params: unknown) => {
|
|
53
|
+
ok: boolean;
|
|
54
|
+
};
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { Object3D } from "three";
|
|
2
|
+
export interface SceneNode {
|
|
3
|
+
id: string;
|
|
4
|
+
parent: string | null;
|
|
5
|
+
name: string;
|
|
6
|
+
type: string;
|
|
7
|
+
visible: boolean;
|
|
8
|
+
position: number[];
|
|
9
|
+
rotation: number[];
|
|
10
|
+
scale: number[];
|
|
11
|
+
color: string | null;
|
|
12
|
+
}
|
|
13
|
+
export interface SceneSnapshot {
|
|
14
|
+
nodes: SceneNode[];
|
|
15
|
+
truncated: boolean;
|
|
16
|
+
}
|
|
17
|
+
export declare const MAX_SCENE_NODES = 500;
|
|
18
|
+
export declare function snapshotScene(scene: Object3D, limit?: number): SceneSnapshot;
|
|
19
|
+
export declare function findSceneObject(scene: Object3D, id: string): Object3D | undefined;
|
|
20
|
+
//# sourceMappingURL=snapshot.d.ts.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
export interface RendererLike {
|
|
2
|
+
info: {
|
|
3
|
+
render?: Record<string, number>;
|
|
4
|
+
memory?: Record<string, number>;
|
|
5
|
+
programs?: unknown[] | null;
|
|
6
|
+
autoReset?: boolean;
|
|
7
|
+
};
|
|
8
|
+
isWebGPURenderer?: boolean;
|
|
9
|
+
render: (...args: any[]) => any;
|
|
10
|
+
}
|
|
11
|
+
export interface ThreeStats {
|
|
12
|
+
kind: "WebGL" | "WebGPU";
|
|
13
|
+
calls: number | null;
|
|
14
|
+
triangles: number | null;
|
|
15
|
+
geometries: number | null;
|
|
16
|
+
textures: number | null;
|
|
17
|
+
programs: number | null;
|
|
18
|
+
note?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function readThreeStats(renderer: RendererLike): ThreeStats;
|
|
21
|
+
/** A microtask runs after the app's synchronous render passes have finished. */
|
|
22
|
+
export declare function observeRenderer(renderer: RendererLike, onSample: (stats: ThreeStats) => void): () => void;
|
|
23
|
+
//# sourceMappingURL=stats.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use client";var G=Object.defineProperty;var ve=Object.getOwnPropertyDescriptor;var be=Object.getOwnPropertyNames;var ge=Object.prototype.hasOwnProperty;var we=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:true})},X=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of be(t))!ge.call(e,r)&&r!==n&&G(e,r,{get:()=>t[r],enumerable:!(a=ve(t,r))||a.enumerable});return e},Ee=(e,t,n)=>(X(e,t,"default"),n&&X(n,t,"default"));var Yt=(()=>{try{let e=globalThis.Capacitor;if(e&&typeof e.isNativePlatform=="function"&&e.isNativePlatform())return e.DEBUG===true}catch{}return process.env.NODE_ENV!=="production"})();typeof window<"u"&&typeof globalThis.global>"u"&&(globalThis.global=globalThis);var Y={};we(Y,{AccessibilityInfo:()=>Te,ActivityIndicator:()=>Ct,Alert:()=>Pt,Animated:()=>Ce,AppRegistry:()=>Le,AppState:()=>Pe,Appearance:()=>Ae,BackHandler:()=>Ie,Button:()=>At,CheckBox:()=>Ge,Clipboard:()=>Me,DeviceEventEmitter:()=>dt,Dimensions:()=>Ne,Easing:()=>De,FlatList:()=>Xe,I18nManager:()=>Be,Image:()=>Ye,ImageBackground:()=>qe,InteractionManager:()=>$e,Keyboard:()=>Re,KeyboardAvoidingView:()=>Je,LayoutAnimation:()=>We,Linking:()=>je,LogBox:()=>lt,Modal:()=>kt,NativeEventEmitter:()=>Oe,NativeModules:()=>ke,PanResponder:()=>Fe,Picker:()=>Qe,PixelRatio:()=>Ve,Platform:()=>ze,Pressable:()=>St,ProgressBar:()=>Ze,RefreshControl:()=>et,SafeAreaView:()=>tt,ScrollView:()=>ee,SectionList:()=>rt,Share:()=>Ke,StatusBar:()=>nt,StyleSheet:()=>He,Switch:()=>Tt,Text:()=>m,TextInput:()=>Z,Touchable:()=>at,TouchableHighlight:()=>Et,TouchableNativeFeedback:()=>ot,TouchableOpacity:()=>k,TouchableWithoutFeedback:()=>xt,UIManager:()=>_e,Vibration:()=>Ue,View:()=>D,VirtualizedList:()=>it,YellowBox:()=>st,findNodeHandle:()=>Lt,unstable_createElement:()=>Se,useColorScheme:()=>ct,useLocaleContext:()=>ut,useWindowDimensions:()=>pt});Ee(Y,xe);import*as xe from"react-native-web";import{unstable_createElement as Se,NativeModules as ke,AccessibilityInfo as Te,Animated as Ce,Appearance as Ae,AppRegistry as Le,AppState as Pe,BackHandler as Ie,Clipboard as Me,Dimensions as Ne,Easing as De,I18nManager as Be,Keyboard as Re,InteractionManager as $e,LayoutAnimation as We,Linking as je,NativeEventEmitter as Oe,PanResponder as Fe,PixelRatio as Ve,Platform as ze,Share as Ke,StyleSheet as He,UIManager as _e,Vibration as Ue,CheckBox as Ge,FlatList as Xe,Image as Ye,ImageBackground as qe,KeyboardAvoidingView as Je,Picker as Qe,ProgressBar as Ze,RefreshControl as et,SafeAreaView as tt,SectionList as rt,StatusBar as nt,Touchable as at,TouchableNativeFeedback as ot,VirtualizedList as it,YellowBox as st,LogBox as lt,DeviceEventEmitter as dt,useColorScheme as ct,useLocaleContext as ut,useWindowDimensions as pt}from"react-native-web";import*as b from"react-native-web";import{createElement as $,forwardRef as q,useCallback as ft,useRef as ht}from"react";import{useEffect as mt,useState as yt}from"react";import{createPortal as vt}from"react-dom";var bt='-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif';import{jsx as gt}from"react/jsx-runtime";var T=Symbol.for("@buoy-gg/portal-host"),J=e=>{if(!(e instanceof Element))return false;if(e.closest("input, textarea, select"))return true;let t=e.closest("[contenteditable]")?.getAttribute("contenteditable")?.toLowerCase();return t===""||t==="true"||t==="plaintext-only"};function Q(){let e=document;if(e[T])return e[T].host;let t=document.createElement("div");t.dataset.buoyPortalHost="",Object.assign(t.style,{position:"fixed",inset:"0",zIndex:"2147483647",pointerEvents:"none",fontFamily:bt});let n=()=>{let i=document.fullscreenElement,s=i&&i.tagName!=="CANVAS"?i:document.body;t.parentElement!==s&&s.appendChild(t)},a=new Map,r=i=>{(!t.contains(i.target)||!J(i.target))&&a.set(i.code||i.key,{key:i.key,code:i.code,location:i.location,keyCode:i.keyCode,which:i.which,altKey:i.altKey,ctrlKey:i.ctrlKey,metaKey:i.metaKey,shiftKey:i.shiftKey})},o=i=>{a.delete(i.code||i.key)},l=()=>a.clear(),p=()=>{let i=[...a.values()];a.clear();for(let s of i)document.dispatchEvent(new KeyboardEvent("keyup",{...s,bubbles:true}))},f=i=>{J(i.target)&&i.stopPropagation()},c=i=>i.stopPropagation();return n(),document.addEventListener("fullscreenchange",n),document.addEventListener("keydown",r,true),document.addEventListener("keyup",o,true),window.addEventListener("blur",l),t.addEventListener("focusin",p),t.addEventListener("keydown",f),t.addEventListener("keyup",f),t.addEventListener("keypress",f),t.addEventListener("wheel",c,{passive:true}),e[T]={host:t,users:0,dispose:()=>{document.removeEventListener("fullscreenchange",n),document.removeEventListener("keydown",r,true),document.removeEventListener("keyup",o,true),window.removeEventListener("blur",l),t.remove(),delete e[T]}},t}function wt({children:e}){let[t,n]=yt(null);return mt(()=>{let a=Q(),r=document[T];return r.users++,n(a),()=>{--r.users===0&&r.dispose()}},[]),t?vt(gt("div",{"data-buoy-root":"",style:{display:"contents",pointerEvents:"auto"},children:e}),t):null}function w(e){let t=q((a,r)=>{let{accessibilityState:o,accessibilityValue:l,...p}=a;for(let f of["busy","checked","disabled","expanded","selected"])o?.[f]!==void 0&&p[`aria-${f}`]===void 0&&(p[`aria-${f}`]=o[f]);for(let[f,c]of Object.entries({min:"valuemin",max:"valuemax",now:"valuenow",text:"valuetext"}))l?.[f]!==void 0&&p[`aria-${c}`]===void 0&&(p[`aria-${c}`]=l[f]);return $(e,{...p,ref:r})}),n=e.State;return n&&Object.assign(t,{State:n}),t.displayName=e.displayName??e.name??"NativeWebView",t}var D=w(b.View),m=w(b.Text),Z=w(b.TextInput),k=w(b.TouchableOpacity),Et=w(b.TouchableHighlight),xt=w(b.TouchableWithoutFeedback),St=w(b.Pressable),ee=w(b.ScrollView),te=q((e,t)=>{let n=ht(null),a=ft(r=>{if(r){let o=r;for(;o.parentElement&&o.parentElement!==document.body;)o=o.parentElement;o.parentElement===document.body&&(n.current=o,Object.assign(o.style,{position:"relative",zIndex:"2147483647",pointerEvents:"auto"}),Q().appendChild(o))}else n.current&&(document.body.appendChild(n.current),n.current=null);typeof t=="function"?t(r):t&&(t.current=r)},[t]);return $(wt,null,$(b.Modal,{...e,ref:a}))});te.displayName="Modal";var kt=w(te),Tt=w(b.Switch),Ct=w(b.ActivityIndicator),At=w(b.Button),Lt=b.findNodeHandle,Pt={alert(e,t,n,a){if(typeof document>"u")return;let r=document.createElement("dialog");r.dataset.buoyRoot="",r.setAttribute("aria-label",e),r.style.cssText="position:fixed;inset:0;margin:auto;width:min(440px,90vw);padding:24px;border:1px solid #475569;border-radius:14px;background:#17212e;color:#f1f5f9;font:14px system-ui;box-shadow:0 20px 80px #0008;z-index:2147483647";let o=document.createElement("h2");if(o.textContent=e,o.style.cssText="font-size:18px;margin:0 0 12px",r.appendChild(o),t){let c=document.createElement("p");c.textContent=t,c.style.cssText="line-height:1.5;white-space:pre-wrap;margin:0 0 20px",r.appendChild(c)}let l=document.createElement("div");l.style.cssText="display:flex;justify-content:flex-end;flex-wrap:wrap;gap:8px";let p=n?.length?n:[{text:"OK"}],f=()=>{r.close?.(),r.remove()};for(let c of p){let i=document.createElement("button");i.type="button",i.textContent=c.text??"OK",i.style.cssText=`padding:9px 14px;border:1px solid #64748b;border-radius:7px;color:white;background:${c.style==="destructive"?"#a52b38":"#283a4d"};cursor:pointer;font:inherit`,i.onclick=()=>{f(),c.onPress?.()},l.appendChild(i)}r.addEventListener("cancel",c=>{c.preventDefault(),a?.cancelable!==false&&(f(),a?.onDismiss?.())}),r.appendChild(l),document.body.appendChild(r),r.showModal?r.showModal():r.setAttribute("open","")}};import{defineToolPreset as It,createToolFactory as Mt}from"@buoy-gg/shared-ui/web";import{useEffect as re,useState as C}from"react";import{JsModal as Nt,night as ne}from"@buoy-gg/shared-ui/web";import{BoxHelper as Dt,DefaultLoadingManager as ae}from"three";import{registerPerfSeries as Bt}from"@buoy-gg/perf-monitor/web";import{subscribeThreeBootEvents as Rt}from"@buoy-gg/core/web/three";var A=e=>typeof e=="number"&&Number.isFinite(e)?e:null;function $t(e){let{render:t,memory:n,programs:a}=e.info,r=e.isWebGPURenderer===true;return{kind:r?"WebGPU":"WebGL",calls:A(r?t?.drawCalls:t?.calls),triangles:A(t?.triangles),geometries:A(n?.geometries),textures:A(n?.textures),programs:r?A(n?.programs):Array.isArray(a)?a.length:null}}var W=new WeakMap;function oe(e,t){return()=>{let n=e.deref();if(!n)return;let a=W.get(n);!a||t&&a.token!==t||(a.deactivate(),n.render===a.wrapped&&(n.render=a.original),W.delete(n))}}function Wt(e,t){let n=new WeakRef(e);oe(n)();let a={},r=e.render,o=false,l=true,p,f=0,c=0;function i(){o||!l||(o=true,queueMicrotask(()=>{o=false;let d=n.deref();if(!l||!d)return;let u=$t(d),v=Date.now();v-c>=1e3&&(f=p&&["geometries","textures"].some(E=>{let x=p[E],N=u[E];return x!==null&&N!==null&&N>x})?f+1:0,p=u,c=v),f>=5&&(u.note="Keeps growing");try{t(u)}catch{}}))}function s(...d){let u=r.apply(this,d);return u&&typeof u.then=="function"?u.then(i,()=>{}):i(),u}return e.render=s,W.set(e,{token:a,original:r,wrapped:s,deactivate:()=>{l=false}}),oe(n,a)}var jt=500;function ie(e,t=500){let n=Number.isFinite(t)?Math.max(1,Math.min(500,Math.floor(t))):500,a=[],r=[{node:e,parent:null}],o=new Set,l=false;for(;r.length&&a.length<n;){let{node:p,parent:f}=r.pop();if(o.has(p)||p.userData.__buoyThreeHelper)continue;o.add(p),a.push({node:p,parent:f});let c=n-a.length-r.length;p.children.length>c&&(l=true);for(let i=Math.min(p.children.length,c)-1;i>=0;i--)r.push({node:p.children[i],parent:p.uuid})}return{nodes:a,truncated:l||r.length>0}}function se(e,t=500){let n=ie(e,t);return{nodes:n.nodes.map(({node:a,parent:r})=>{let o=a.material,l=(Array.isArray(o)?o[0]:o)?.color;return{id:a.uuid,parent:r,name:a.name.slice(0,160),type:a.type.slice(0,80),visible:a.visible,position:a.position.toArray(),rotation:[a.rotation.x,a.rotation.y,a.rotation.z],scale:a.scale.toArray(),color:l?.isColor?`#${l.getHexString()}`:null}}),truncated:n.truncated}}function Ot(e,t){return ie(e).nodes.find(({node:n})=>n.uuid===t)?.node}import{Cache as B}from"three";import{recordBrowserAssetLoad as Ft}from"@buoy-gg/assets/web";var j=new Set,Vt=0,zt=e=>(j.add(e),()=>{j.delete(e)});function Kt(e,t,n,a){let r;if(typeof performance<"u"&&typeof performance.getEntriesByName=="function"){let o;try{o=typeof document<"u"?new URL(e,document.baseURI).href:e}catch{o=e}r=performance.getEntriesByName(o,"resource").filter(l=>l.responseEnd>=a).pop()}return{url:e,status:t,bytes:r&&r.encodedBodySize>0?r.encodedBodySize:null,durationMs:r?r.duration:null,cacheHit:n===true?true:r&&r.encodedBodySize>0?r.transferSize===0:null}}var R=new WeakMap;function le(e){let t=false;return()=>{if(t)return;t=true;let n=e.deref();if(!n)return;let a=R.get(n);a&&--a.users===0&&(a.stop(),R.delete(n))}}function de(e){let t=new WeakRef(e),n=R.get(e);if(n)return n.users++,le(t);let a=e.itemStart,r=e.itemEnd,o=e.itemError,l=new Map;function p(s){let d=l.get(s)??[],u=B.get(`image-bitmap:${s}`);return d.push({started:performance.now(),cached:B.get(`file:${s}`)!==void 0||B.get(`image:${s}`)?.complete===true||u!==void 0&&typeof u?.then!="function"||B.get(s)!==void 0,failed:false}),l.set(s,d),a.call(this,s)}function f(s,d){let u=l.get(s)?.[0];if(!u||u.failed)return;u.failed=d;let v=Kt(s,d?"error":"success",u.cached,u.started);try{Ft(v)}catch{}let E={id:`three-load-${++Vt}`,source:"three",timestamp:Date.now(),title:d?"Load failed":v.cacheHit?"Cache hit":"Loaded",subtitle:s.slice(0,512),status:v.status,originalEvent:v};j.forEach(x=>{try{x(E)}catch{}})}function c(s){f(s,false);let d=l.get(s);return d?.shift(),d?.length||l.delete(s),r.call(this,s)}function i(s){return f(s,true),o.call(this,s)}return e.itemStart=p,e.itemEnd=c,e.itemError=i,R.set(e,{users:1,stop:()=>{let s=t.deref();s?.itemStart===p&&(s.itemStart=a),s?.itemEnd===c&&(s.itemEnd=r),s?.itemError===i&&(s.itemError=o),l.clear()}}),le(t)}var g=new Map,O=new Set,Ht=0,F=false,L,V,z,P=()=>{F=true};function I(e){e.stop(),e.helper?.deref()?.removeFromParent(),e.helper?.deref()?.dispose(),g.delete(e.id),P()}function K(e,t,n,a){for(let c of g.values())(e&&c.renderer?.deref()===e||t&&c.scene?.deref()===t&&!c.renderer)&&I(c);g.size>=32&&I(g.values().next().value);let r=`three-${++Ht}`,o={id:r,renderer:e&&new WeakRef(e),scene:t&&new WeakRef(t),camera:n&&new WeakRef(n),stop:()=>{}},l=Bt(r),p=e?Wt(e,c=>{o.stats=c,l.update(["calls","triangles","geometries","textures","programs"].map(i=>({id:`${r}:${i}`,label:`${r} ${i}`,value:c[i],unit:"count",note:c.note}))),P()}):()=>{},f=a&&a!==ae?de(a):()=>{};return o.stop=()=>{p(),f(),l.dispose()},g.set(r,o),P(),()=>{g.get(r)===o&&I(o)}}function _t(e){return ce(),K(e.renderer,e.scene,e.camera,e.loadingManager)}function ce(){L||(z=de(ae),typeof window<"u"&&(V=Rt(({type:e,detail:t})=>{if(e!=="observe"||!t||typeof t!="object")return;let n=t;n.isScene&&![...g.values()].some(a=>a.scene?.deref()===n)&&K(void 0,n),n.info&&typeof n.render=="function"&&![...g.values()].some(a=>a.renderer?.deref()===n)&&K(n)})),L=setInterval(()=>{for(let e of g.values())(e.renderer&&!e.renderer.deref()||e.scene&&!e.scene.deref())&&I(e);F&&(F=false,O.forEach(e=>e()))},500))}function ue(){V?.(),z?.(),V=void 0,z=void 0,L&&clearInterval(L),L=void 0;for(let e of g.values())I(e)}function H(e){return O.add(e),()=>{O.delete(e)}}function _(){return[...g.values()].map(e=>({id:e.id,stats:e.stats??null}))}function S(){return[...g.values()].map(e=>({id:e.id,...e.scene?.deref()&&se(e.scene.deref())||{nodes:[],truncated:false}}))}function U(e){let t=g.get(e.rendererId),n=t?.scene?.deref();if(!t||!n)throw new Error("Scene not found. Refresh the list.");if(e.action==="clearSelection")return t.helper?.deref()?.removeFromParent(),t.helper?.deref()?.dispose(),t.helper=void 0,{ok:true};let a=e.id&&Ot(n,e.id);if(!a)throw new Error("Object not found in this scene.");switch(e.action){case"select":{t.helper?.deref()?.removeFromParent(),t.helper?.deref()?.dispose(),a.updateWorldMatrix(true,false);let r=new Dt(a,16776960);r.userData.__buoyThreeHelper=true,n.add(r),t.helper=new WeakRef(r);break}case"visible":if(typeof e.value!="boolean")throw new Error("Use true or false.");a.visible=e.value;break;case"position":case"rotation":case"scale":{let r=e.value;if(!Array.isArray(r)||r.length!==3||!r.every(o=>typeof o=="number"&&Number.isFinite(o)))throw new Error("Use three finite numbers.");a[e.action].set(r[0],r[1],r[2]);break}case"color":{if(typeof e.value!="string"||!/^#[0-9a-f]{6}$/i.test(e.value))throw new Error("Use a six digit hex color.");let r=a.material,o=Array.isArray(r)?r:[r];if(!o.some(l=>l?.color?.isColor))throw new Error("This object has no color.");o.forEach(l=>l?.color?.set(e.value));break}default:throw new Error("Unknown scene action.")}return a.updateWorldMatrix(true,false),t.helper?.deref()?.update(),P(),{ok:true}}var Ut={version:1,getSnapshot:()=>({scenes:S(),stats:_()}),subscribe:H,actions:{getScene:()=>(P(),S()),getStats:_,action:e=>U(e)}},pe=globalThis;pe.__buoyThreeDispose?.();pe.__buoyThreeDispose=ue;import{jsx as h,jsxs as M}from"react/jsx-runtime";var y={color:ne.color.text,fontSize:13};function fe({label:e,value:t,save:n}){let[a,r]=C(t),[o,l]=C(false);return re(()=>{o||r(t)},[t,o]),M(D,{style:{flexDirection:"row",gap:8,padding:4},children:[h(m,{style:y,children:e}),h(Z,{testID:`three-edit-${e}`,accessibilityLabel:e,value:a,onChangeText:p=>{r(p),l(true)},style:[y,{borderWidth:1,borderColor:"#666",padding:4,flex:1}]}),h(k,{testID:`three-save-${e}`,onPress:()=>{n(a),l(false)},children:h(m,{style:y,children:"Save"})})]})}function he({scenes:e,dispatch:t,refresh:n}){let[a,r]=C(S),[o,l]=C(),[p,f]=C("");re(()=>e?void 0:H(()=>r(S())),[e]);let c=e??a,i=async d=>{try{await(t??U)(d),f(""),e||r(S())}catch(u){f(u instanceof Error?u.message:"The change failed.")}},s=c.find(d=>d.id===o?.rendererId)?.nodes.find(d=>d.id===o?.id);return M(ee,{testID:"three-panel",style:{flex:1,backgroundColor:ne.color.bg},contentContainerStyle:{padding:12,gap:8},children:[h(m,{style:[y,{fontSize:18}],children:"Scene"}),!c.length&&h(m,{style:y,children:"No scene found. Call registerThree in your app."}),h(k,{testID:"three-refresh",onPress:async()=>{try{n?await n():r(S()),f("")}catch(d){f(d instanceof Error?d.message:"The refresh failed.")}},children:h(m,{style:y,children:"Refresh"})}),s&&o&&M(D,{testID:"three-details",children:[h(m,{style:y,children:s.name||s.type}),h(k,{testID:"three-visible",onPress:()=>void i({...o,action:"visible",value:!s.visible}),children:h(m,{style:y,children:s.visible?"Hide":"Show"})}),["position","rotation","scale"].map(d=>h(fe,{label:d,value:s[d].join(", "),save:u=>void i({...o,action:d,value:u.split(",").map(v=>v.trim()?Number(v):NaN)})},d)),h(m,{style:y,children:"Turn values use radians."}),s.color&&h(fe,{label:"color",value:s.color,save:d=>void i({...o,action:"color",value:d})}),h(k,{testID:"three-clear-selection",onPress:()=>{i({...o,action:"clearSelection"}),l(void 0)},children:h(m,{style:y,children:"Clear box"})})]},`${o.rendererId}:${o.id}`),c.map(d=>M(D,{children:[h(m,{style:y,children:d.id}),!d.nodes.length&&h(m,{style:y,children:"Pass a scene to registerThree to link this view."}),d.nodes.map(u=>h(k,{testID:`three-node-${u.name||u.type}`,onPress:()=>{l({rendererId:d.id,id:u.id}),i({rendererId:d.id,id:u.id,action:"select"})},children:M(m,{style:[y,{padding:5,paddingLeft:5+Math.min(20,(()=>{let v=0,E=u.parent,x=new Set;for(;E&&!x.has(E);)x.add(E),v++,E=d.nodes.find(N=>N.id===E)?.parent??null;return v})())*12}],children:[u.visible?"\u25CF":"\u25CB"," ",u.name||u.type]})},u.id)),d.truncated&&h(m,{style:y,children:"Tree limit reached. Some nodes are left out."})]},d.id)),!!p&&h(m,{accessibilityRole:"alert",style:y,children:p})]})}function me({visible:e,onClose:t}){return h(Nt,{visible:e,onClose:t,header:{title:"Scene"},initialMode:"bottomSheet",disableScrollWrapper:true,children:h(he,{})})}import{jsx as Gt}from"react/jsx-runtime";var ye=It({id:"three",name:"SCENE",description:"See and edit the 3D scene.",slot:"both",icon:({size:e,color:t})=>Gt(m,{style:{fontSize:e,color:t??"#F59E0B"},children:"\u25C7"}),component:me}),Xt=Mt(ye);export{jt as MAX_SCENE_NODES,me as ThreeModal,he as ThreeToolView,Xt as createThreeTool,ue as disposeThree,S as getThreeScene,_ as getThreeStats,zt as onThreeLoad,_t as registerThree,se as snapshotScene,ce as startThreeCapture,H as subscribeThree,U as threeAction,Ut as threeSyncAdapter,ye as threeToolPreset};
|
package/package.json
CHANGED
|
@@ -1,6 +1,105 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@buoy-gg/three",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "7.0.65",
|
|
4
|
+
"description": "See and edit a three.js scene.",
|
|
5
|
+
"main": "lib/commonjs/index.js",
|
|
6
|
+
"module": "lib/module/index.js",
|
|
7
|
+
"types": "lib/typescript/index.d.ts",
|
|
8
|
+
"react-native": "lib/module/index.js",
|
|
9
|
+
"source": "src/index.tsx",
|
|
10
|
+
"files": [
|
|
11
|
+
"lib"
|
|
12
|
+
],
|
|
13
|
+
"sideEffects": [
|
|
14
|
+
"**/index.*",
|
|
15
|
+
"./lib/web/**/*.mjs",
|
|
16
|
+
"**/autoCapture.*"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@buoy-gg/shared-ui": "^7.0.65",
|
|
20
|
+
"@buoy-gg/perf-monitor": "^7.0.65",
|
|
21
|
+
"@buoy-gg/events": "^7.0.65",
|
|
22
|
+
"@buoy-gg/assets": "^7.0.65",
|
|
23
|
+
"@buoy-gg/core": "^7.0.65"
|
|
24
|
+
},
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "*",
|
|
27
|
+
"three": ">=0.170.0"
|
|
28
|
+
},
|
|
29
|
+
"peerDependenciesMeta": {
|
|
30
|
+
"react-native": {
|
|
31
|
+
"optional": true
|
|
32
|
+
},
|
|
33
|
+
"react-native-web": {
|
|
34
|
+
"optional": true
|
|
35
|
+
},
|
|
36
|
+
"react-dom": {
|
|
37
|
+
"optional": true
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"devDependencies": {
|
|
41
|
+
"@types/react": "^19.1.0",
|
|
42
|
+
"@types/react-native": "^0.73.0",
|
|
43
|
+
"typescript": "~5.8.3",
|
|
44
|
+
"@types/three": "^0.186.0"
|
|
45
|
+
},
|
|
46
|
+
"react-native-builder-bob": {
|
|
47
|
+
"source": "src",
|
|
48
|
+
"output": "lib",
|
|
49
|
+
"targets": [
|
|
50
|
+
"commonjs",
|
|
51
|
+
"module",
|
|
52
|
+
[
|
|
53
|
+
"typescript",
|
|
54
|
+
{
|
|
55
|
+
"project": "tsconfig.build.json"
|
|
56
|
+
}
|
|
57
|
+
]
|
|
58
|
+
]
|
|
59
|
+
},
|
|
60
|
+
"repository": {
|
|
61
|
+
"type": "git",
|
|
62
|
+
"url": "https://github.com/LovesWorking/react-native-buoy.git",
|
|
63
|
+
"directory": "packages/three"
|
|
64
|
+
},
|
|
65
|
+
"bugs": {
|
|
66
|
+
"url": "https://github.com/LovesWorking/react-native-buoy/issues"
|
|
67
|
+
},
|
|
68
|
+
"homepage": "https://buoy.gg/buoy/latest/docs/tools/three",
|
|
69
|
+
"publishConfig": {
|
|
70
|
+
"access": "public",
|
|
71
|
+
"tag": "latest"
|
|
72
|
+
},
|
|
73
|
+
"keywords": [
|
|
74
|
+
"three",
|
|
75
|
+
"devtools"
|
|
76
|
+
],
|
|
77
|
+
"exports": {
|
|
78
|
+
".": {
|
|
79
|
+
"browser": {
|
|
80
|
+
"types": "./lib/typescript/index.d.ts",
|
|
81
|
+
"default": "./lib/web/index.mjs"
|
|
82
|
+
},
|
|
83
|
+
"import": {
|
|
84
|
+
"types": "./lib/typescript/index.d.ts",
|
|
85
|
+
"default": "./lib/module/index.js"
|
|
86
|
+
},
|
|
87
|
+
"require": {
|
|
88
|
+
"types": "./lib/typescript/index.d.ts",
|
|
89
|
+
"default": "./lib/commonjs/index.js"
|
|
90
|
+
}
|
|
91
|
+
},
|
|
92
|
+
"./web": {
|
|
93
|
+
"types": "./lib/typescript/index.d.ts",
|
|
94
|
+
"default": "./lib/web/index.mjs"
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
"scripts": {
|
|
98
|
+
"build": "bob build && pnpm run build:web",
|
|
99
|
+
"typecheck": "tsc --noEmit",
|
|
100
|
+
"clean": "rimraf lib",
|
|
101
|
+
"test": "pnpm run typecheck",
|
|
102
|
+
"postinstall": "echo \"Run pnpm build to compile this package\"",
|
|
103
|
+
"build:web": "node ../../scripts/build-web.mjs three"
|
|
104
|
+
}
|
|
6
105
|
}
|