@codefluss/plugin-configurator-3d 0.0.2-alpha.1 → 0.0.2-alpha.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,329 +0,0 @@
1
- declare const _default: {
2
- en: {
3
- plugin: {
4
- name: string;
5
- description: string;
6
- };
7
- properties: {
8
- "model.url": {
9
- label: string;
10
- placeholder: string;
11
- description: string;
12
- };
13
- "model.scale": {
14
- label: string;
15
- description: string;
16
- };
17
- "model.position": {
18
- label: string;
19
- placeholder: string;
20
- description: string;
21
- };
22
- "model.rotation": {
23
- label: string;
24
- placeholder: string;
25
- description: string;
26
- };
27
- "pois.enabled": {
28
- label: string;
29
- description: string;
30
- };
31
- "camera.fov": {
32
- label: string;
33
- description: string;
34
- };
35
- "camera.enableOrbit": {
36
- label: string;
37
- description: string;
38
- };
39
- "camera.enableZoom": {
40
- label: string;
41
- description: string;
42
- };
43
- "camera.enablePan": {
44
- label: string;
45
- description: string;
46
- };
47
- "camera.near": {
48
- label: string;
49
- description: string;
50
- };
51
- "camera.far": {
52
- label: string;
53
- description: string;
54
- };
55
- "lighting.ambientIntensity": {
56
- label: string;
57
- description: string;
58
- };
59
- };
60
- categories: {
61
- content: string;
62
- style: string;
63
- layout: string;
64
- advanced: string;
65
- };
66
- };
67
- de: {
68
- plugin: {
69
- name: string;
70
- description: string;
71
- };
72
- properties: {
73
- "model.url": {
74
- label: string;
75
- placeholder: string;
76
- description: string;
77
- };
78
- "model.scale": {
79
- label: string;
80
- description: string;
81
- };
82
- "model.position": {
83
- label: string;
84
- placeholder: string;
85
- description: string;
86
- };
87
- "model.rotation": {
88
- label: string;
89
- placeholder: string;
90
- description: string;
91
- };
92
- "pois.enabled": {
93
- label: string;
94
- description: string;
95
- };
96
- "camera.fov": {
97
- label: string;
98
- description: string;
99
- };
100
- "camera.enableOrbit": {
101
- label: string;
102
- description: string;
103
- };
104
- "camera.enableZoom": {
105
- label: string;
106
- description: string;
107
- };
108
- "camera.enablePan": {
109
- label: string;
110
- description: string;
111
- };
112
- "camera.near": {
113
- label: string;
114
- description: string;
115
- };
116
- "camera.far": {
117
- label: string;
118
- description: string;
119
- };
120
- "lighting.ambientIntensity": {
121
- label: string;
122
- description: string;
123
- };
124
- };
125
- categories: {
126
- content: string;
127
- style: string;
128
- layout: string;
129
- advanced: string;
130
- };
131
- };
132
- fr: {
133
- plugin: {
134
- name: string;
135
- description: string;
136
- };
137
- properties: {
138
- "model.url": {
139
- label: string;
140
- placeholder: string;
141
- description: string;
142
- };
143
- "model.scale": {
144
- label: string;
145
- description: string;
146
- };
147
- "model.position": {
148
- label: string;
149
- placeholder: string;
150
- description: string;
151
- };
152
- "model.rotation": {
153
- label: string;
154
- placeholder: string;
155
- description: string;
156
- };
157
- "pois.enabled": {
158
- label: string;
159
- description: string;
160
- };
161
- "camera.fov": {
162
- label: string;
163
- description: string;
164
- };
165
- "camera.enableOrbit": {
166
- label: string;
167
- description: string;
168
- };
169
- "camera.enableZoom": {
170
- label: string;
171
- description: string;
172
- };
173
- "camera.enablePan": {
174
- label: string;
175
- description: string;
176
- };
177
- "camera.near": {
178
- label: string;
179
- description: string;
180
- };
181
- "camera.far": {
182
- label: string;
183
- description: string;
184
- };
185
- "lighting.ambientIntensity": {
186
- label: string;
187
- description: string;
188
- };
189
- };
190
- categories: {
191
- content: string;
192
- style: string;
193
- layout: string;
194
- advanced: string;
195
- };
196
- };
197
- es: {
198
- plugin: {
199
- name: string;
200
- description: string;
201
- };
202
- properties: {
203
- "model.url": {
204
- label: string;
205
- placeholder: string;
206
- description: string;
207
- };
208
- "model.scale": {
209
- label: string;
210
- description: string;
211
- };
212
- "model.position": {
213
- label: string;
214
- placeholder: string;
215
- description: string;
216
- };
217
- "model.rotation": {
218
- label: string;
219
- placeholder: string;
220
- description: string;
221
- };
222
- "pois.enabled": {
223
- label: string;
224
- description: string;
225
- };
226
- "camera.fov": {
227
- label: string;
228
- description: string;
229
- };
230
- "camera.enableOrbit": {
231
- label: string;
232
- description: string;
233
- };
234
- "camera.enableZoom": {
235
- label: string;
236
- description: string;
237
- };
238
- "camera.enablePan": {
239
- label: string;
240
- description: string;
241
- };
242
- "camera.near": {
243
- label: string;
244
- description: string;
245
- };
246
- "camera.far": {
247
- label: string;
248
- description: string;
249
- };
250
- "lighting.ambientIntensity": {
251
- label: string;
252
- description: string;
253
- };
254
- };
255
- categories: {
256
- content: string;
257
- style: string;
258
- layout: string;
259
- advanced: string;
260
- };
261
- };
262
- it: {
263
- plugin: {
264
- name: string;
265
- description: string;
266
- };
267
- properties: {
268
- "model.url": {
269
- label: string;
270
- placeholder: string;
271
- description: string;
272
- };
273
- "model.scale": {
274
- label: string;
275
- description: string;
276
- };
277
- "model.position": {
278
- label: string;
279
- placeholder: string;
280
- description: string;
281
- };
282
- "model.rotation": {
283
- label: string;
284
- placeholder: string;
285
- description: string;
286
- };
287
- "pois.enabled": {
288
- label: string;
289
- description: string;
290
- };
291
- "camera.fov": {
292
- label: string;
293
- description: string;
294
- };
295
- "camera.enableOrbit": {
296
- label: string;
297
- description: string;
298
- };
299
- "camera.enableZoom": {
300
- label: string;
301
- description: string;
302
- };
303
- "camera.enablePan": {
304
- label: string;
305
- description: string;
306
- };
307
- "camera.near": {
308
- label: string;
309
- description: string;
310
- };
311
- "camera.far": {
312
- label: string;
313
- description: string;
314
- };
315
- "lighting.ambientIntensity": {
316
- label: string;
317
- description: string;
318
- };
319
- };
320
- categories: {
321
- content: string;
322
- style: string;
323
- layout: string;
324
- advanced: string;
325
- };
326
- };
327
- };
328
- export default _default;
329
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/locales/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAMA,wBAME"}
@@ -1,24 +0,0 @@
1
- import{jsxs as e,jsx as t,Fragment as r}from"react/jsx-runtime";import{useState as a,useEffect as n,useRef as i}from"react";import{Canvas as o,useFrame as s,useThree as l}from"@react-three/fiber";import{Environment as c,OrbitControls as d}from"@react-three/drei";import{useStore as m}from"zustand";import{InstanceProvider as h,POIMarker as f}from"@codefluss/threejs-shared";import{createConfiguratorInstance as u}from"./index.mjs";import*as g from"three";const p=/* @__PURE__ */new Map;function b({instanceId:r,data:i,isEditorMode:s}){const[l]=a(()=>{const e=u(r);return p.set(r,e),e}),d=m(l,e=>e.isReady),f=m(l,e=>e.isLoading),g=m(l,e=>e.loadingProgress);return n(()=>{if(i.model?.url){const e=l.getState();if(e.gltf)return;e.loadModel(i.model.url)}else{l.getState().setFallbackGeometry(i.model?.fallbackGeometry||"box")}},[i.model?.url,i.model?.fallbackGeometry,l]),n(()=>()=>{l.getState().dispose(),p.delete(r)},[r,l]),/* @__PURE__ */e("div",{style:{width:"100%",height:"100%",position:"relative"},children:[f&&/* @__PURE__ */t(w,{progress:g}),
2
- /* @__PURE__ */t(h,{instanceId:r,createStore:()=>l,children:/* @__PURE__ */e(o,{shadows:!0,camera:{position:[5,5,5],fov:i.camera?.fov||50,near:i.camera?.near||.1,far:i.camera?.far||2e3},frameloop:"demand",gl:{preserveDrawingBuffer:!0,antialias:!0,powerPreference:"high-performance"},children:[
3
- /* @__PURE__ */t("color",{attach:"background",args:["#f0f0f0"]}),
4
- /* @__PURE__ */t("ambientLight",{intensity:i.lighting?.ambientIntensity||.5}),
5
- /* @__PURE__ */t("directionalLight",{position:i.lighting?.directionalPosition||[10,10,5],intensity:i.lighting?.directionalIntensity||1,castShadow:i.lighting?.enableShadows}),d&&/* @__PURE__ */t(y,{store:l,data:i}),d&&i.pois?.enabled&&/* @__PURE__ */t(v,{store:l}),
6
- /* @__PURE__ */t(x,{store:l,enabled:!1!==i.camera?.enableOrbit,enableZoom:!1!==i.camera?.enableZoom,enablePan:!1!==i.camera?.enablePan}),
7
- /* @__PURE__ */t(c,{preset:"city"})]},r)}),s&&d&&/* @__PURE__ */t(M,{instanceId:r,store:l})]})}function y({store:r,data:a}){const o=m(r,e=>e.gltf),l=m(r,e=>e.fallbackGeometry),c=i(null);if(s(({invalidate:e})=>{c.current&&a.model&&(c.current.position.set(...a.model.position||[0,0,0]),c.current.rotation.set(...a.model.rotation||[0,0,0]),c.current.scale.setScalar(a.model.scale||1),e())}),n(()=>{if(!o||!c.current)return;const e=(new g.Box3).setFromObject(c.current),t=e.getCenter(new g.Vector3),n=e.getSize(new g.Vector3),i=Math.max(n.x,n.y,n.z),s=(a.camera?.fov||50)*Math.PI/180,l=2.5*(i/(2*Math.tan(s/2)));r.setState({cameraTarget:[t.x,t.y,t.z],cameraDistance:l})},[o,a.camera?.fov,r]),!o)return null;if(o?.scene)/* @__PURE__ */
8
- return t("primitive",{ref:c,object:o.scene});const d=l||"box",h=/* @__PURE__ */t("meshStandardMaterial",{color:"#4a90e2",metalness:.3,roughness:.4});switch(d){case"box":default:/* @__PURE__ */
9
- return e("mesh",{ref:c,children:[
10
- /* @__PURE__ */t("boxGeometry",{args:[2,2,2]}),h]});case"sphere":/* @__PURE__ */
11
- return e("mesh",{ref:c,children:[
12
- /* @__PURE__ */t("sphereGeometry",{args:[1.5,32,32]}),h]});case"cylinder":/* @__PURE__ */
13
- return e("mesh",{ref:c,children:[
14
- /* @__PURE__ */t("cylinderGeometry",{args:[1,1,2,32]}),h]});case"torus":/* @__PURE__ */
15
- return e("mesh",{ref:c,children:[
16
- /* @__PURE__ */t("torusGeometry",{args:[1,.4,16,32]}),h]})}}function x({store:e,enabled:r,enableZoom:a,enablePan:o}){const s=i(null),{camera:c,invalidate:h}=l(),f=m(e,e=>e.cameraTarget),u=m(e,e=>e.cameraDistance);return n(()=>{if(!f||!u)return;const e=Math.PI/4,t=Math.PI/6,r=f[0]+u*Math.cos(t)*Math.cos(e),a=f[1]+u*Math.sin(t),n=f[2]+u*Math.cos(t)*Math.sin(e);c.position.set(r,a,n),c.lookAt(f[0],f[1],f[2]),s.current&&(s.current.target.set(...f),s.current.update()),h()},[f,u,c,h]),/* @__PURE__ */t(d,{ref:s,enabled:r,enableZoom:a,enablePan:o,onChange:()=>h()})}function v({store:e}){const a=m(e,e=>e.pois);/* @__PURE__ */
17
- return t(r,{children:a.map(e=>/* @__PURE__ */t(f,{...e},e.id))})}function w({progress:r}){/* @__PURE__ */
18
- return t("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)",zIndex:10},children:/* @__PURE__ */e("div",{style:{textAlign:"center",color:"white"},children:[
19
- /* @__PURE__ */t("div",{style:{width:200,height:4,background:"#333",borderRadius:2,overflow:"hidden"},children:/* @__PURE__ */t("div",{style:{width:`${r}%`,height:"100%",background:"#4CAF50",transition:"width 0.3s"}})}),
20
- /* @__PURE__ */e("p",{style:{marginTop:10,fontSize:14},children:[Math.round(r),"%"]})]})})}function M({instanceId:r,store:a}){const n=m(a,e=>e.setMaterialVariant),i=m(a,e=>e.setCameraPreset),o=m(a,e=>e.materialVariants),s=m(a,e=>e.cameraPresets);/* @__PURE__ */
21
- return e("div",{style:{position:"absolute",top:10,left:10,background:"white",padding:10,borderRadius:8,boxShadow:"0 2px 10px rgba(0,0,0,0.1)"},children:[o.length>0&&/* @__PURE__ */e("div",{style:{marginBottom:10},children:[
22
- /* @__PURE__ */t("label",{style:{fontSize:12,fontWeight:"bold"},children:"Materials:"}),o.map(e=>/* @__PURE__ */t("button",{onClick:()=>n(e.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:e.name},e.id))]}),s.length>0&&/* @__PURE__ */e("div",{children:[
23
- /* @__PURE__ */t("label",{style:{fontSize:12,fontWeight:"bold"},children:"Camera:"}),s.map(e=>/* @__PURE__ */t("button",{onClick:()=>i(e.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:e.name},e.id))]})]})}export{b as default};
24
- //# sourceMappingURL=model-viewer-Bh6JoFYA.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"model-viewer-Bh6JoFYA.mjs","sources":["../src/components/model-viewer.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from 'react';\nimport { Canvas, useFrame, useThree } from '@react-three/fiber';\nimport { OrbitControls, Environment } from '@react-three/drei';\nimport { useStore } from 'zustand';\nimport { InstanceProvider, POIMarker } from '@codefluss/threejs-shared';\nimport { createConfiguratorInstance } from '../store/configurator-store';\nimport type { ModelViewerProps } from '../types';\nimport type { StoreApi } from 'zustand/vanilla';\nimport type { ConfiguratorStore } from '../types';\nimport * as THREE from 'three';\n\nconst configuratorStores = new Map<string, StoreApi<ConfiguratorStore>>();\n\nexport default function ModelViewer({ instanceId, data, isEditorMode }: ModelViewerProps) {\n const [store] = useState(() => {\n // Always create a fresh store for this instance\n const newStore = createConfiguratorInstance(instanceId);\n configuratorStores.set(instanceId, newStore);\n return newStore;\n });\n\n const isReady = useStore(store, (state) => state.isReady);\n const isLoading = useStore(store, (state) => state.isLoading);\n const loadingProgress = useStore(store, (state) => state.loadingProgress);\n\n // Load model\n useEffect(() => {\n if (data.model?.url) {\n const state = store.getState();\n if (state.gltf) return; // Already loaded\n\n state.loadModel(data.model.url);\n } else {\n // Fallback to built-in geometry\n const state = store.getState();\n state.setFallbackGeometry(data.model?.fallbackGeometry || 'box');\n }\n }, [data.model?.url, data.model?.fallbackGeometry, store]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n const state = store.getState();\n state.dispose();\n configuratorStores.delete(instanceId);\n };\n }, [instanceId, store]);\n\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {isLoading && <LoadingOverlay progress={loadingProgress} />}\n\n <InstanceProvider instanceId={instanceId} createStore={() => store}>\n <Canvas\n key={instanceId}\n shadows\n camera={{\n position: [5, 5, 5],\n fov: data.camera?.fov || 50,\n near: data.camera?.near || 0.1,\n far: data.camera?.far || 2000\n }}\n frameloop=\"demand\"\n gl={{\n preserveDrawingBuffer: true,\n antialias: true,\n powerPreference: \"high-performance\"\n }}\n >\n <color attach=\"background\" args={['#f0f0f0']} />\n\n <ambientLight intensity={data.lighting?.ambientIntensity || 0.5} />\n <directionalLight\n position={data.lighting?.directionalPosition || [10, 10, 5]}\n intensity={data.lighting?.directionalIntensity || 1}\n castShadow={data.lighting?.enableShadows}\n />\n\n {isReady && <Model store={store} data={data} />}\n {isReady && data.pois?.enabled && <POIMarkers store={store} />}\n\n <CameraController\n store={store}\n enabled={data.camera?.enableOrbit !== false}\n enableZoom={data.camera?.enableZoom !== false}\n enablePan={data.camera?.enablePan !== false}\n />\n <Environment preset=\"city\" />\n </Canvas>\n </InstanceProvider>\n\n {isEditorMode && isReady && <EditorControls instanceId={instanceId} store={store} />}\n </div>\n );\n}\n\nfunction Model({ store, data }: { store: StoreApi<ConfiguratorStore>; data: ModelViewerProps['data'] }) {\n const gltf = useStore(store, (state) => state.gltf);\n const fallbackGeometry = useStore(store, (state) => state.fallbackGeometry);\n const ref = useRef<THREE.Group>(null);\n\n useFrame(({ invalidate }) => {\n if (!ref.current || !data.model) return;\n ref.current.position.set(...(data.model.position || [0, 0, 0]));\n ref.current.rotation.set(...(data.model.rotation || [0, 0, 0]));\n ref.current.scale.setScalar(data.model.scale || 1);\n invalidate(); // Trigger re-render for frameloop=\"demand\"\n });\n\n // Auto-focus and auto-zoom on model load\n useEffect(() => {\n if (!gltf || !ref.current) return;\n\n // Calculate bounding box\n const box = new THREE.Box3().setFromObject(ref.current);\n const center = box.getCenter(new THREE.Vector3());\n const size = box.getSize(new THREE.Vector3());\n\n // Get the max dimension to determine zoom\n const maxDim = Math.max(size.x, size.y, size.z);\n const fov = data.camera?.fov || 50;\n const fovRad = (fov * Math.PI) / 180;\n\n // Calculate camera distance to fit the object\n const cameraDistance = maxDim / (2 * Math.tan(fovRad / 2));\n\n // Add padding (2.5x for better framing and full visibility)\n const finalDistance = cameraDistance * 2.5;\n\n // Store camera info for OrbitControls\n store.setState({\n cameraTarget: [center.x, center.y, center.z] as [number, number, number],\n cameraDistance: finalDistance\n });\n }, [gltf, data.camera?.fov, store]);\n\n if (!gltf) return null;\n\n if (gltf?.scene) {\n return <primitive ref={ref} object={gltf.scene} />;\n }\n\n // Fallback geometry when no GLTF model is loaded\n const geometry = fallbackGeometry || 'box';\n const material = (\n <meshStandardMaterial\n color=\"#4a90e2\"\n metalness={0.3}\n roughness={0.4}\n />\n );\n\n switch (geometry) {\n case 'box':\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n case 'sphere':\n return (\n <mesh ref={ref}>\n <sphereGeometry args={[1.5, 32, 32]} />\n {material}\n </mesh>\n );\n case 'cylinder':\n return (\n <mesh ref={ref}>\n <cylinderGeometry args={[1, 1, 2, 32]} />\n {material}\n </mesh>\n );\n case 'torus':\n return (\n <mesh ref={ref}>\n <torusGeometry args={[1, 0.4, 16, 32]} />\n {material}\n </mesh>\n );\n default:\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n }\n}\n\nfunction CameraController({\n store,\n enabled,\n enableZoom,\n enablePan\n}: {\n store: StoreApi<ConfiguratorStore>;\n enabled: boolean;\n enableZoom: boolean;\n enablePan: boolean;\n}) {\n const controlsRef = useRef<any>(null);\n const { camera, invalidate } = useThree();\n const cameraTarget = useStore(store, (state) => state.cameraTarget);\n const cameraDistance = useStore(store, (state) => state.cameraDistance);\n\n useEffect(() => {\n if (!cameraTarget || !cameraDistance) return;\n\n // Calculate camera position (angle: 45 degrees horizontal, 30 degrees vertical)\n const angleH = Math.PI / 4; // 45 degrees\n const angleV = Math.PI / 6; // 30 degrees\n\n const x = cameraTarget[0] + cameraDistance * Math.cos(angleV) * Math.cos(angleH);\n const y = cameraTarget[1] + cameraDistance * Math.sin(angleV);\n const z = cameraTarget[2] + cameraDistance * Math.cos(angleV) * Math.sin(angleH);\n\n camera.position.set(x, y, z);\n camera.lookAt(cameraTarget[0], cameraTarget[1], cameraTarget[2]);\n\n // Update OrbitControls target\n if (controlsRef.current) {\n controlsRef.current.target.set(...cameraTarget);\n controlsRef.current.update();\n }\n\n invalidate();\n }, [cameraTarget, cameraDistance, camera, invalidate]);\n\n return (\n <OrbitControls\n ref={controlsRef}\n enabled={enabled}\n enableZoom={enableZoom}\n enablePan={enablePan}\n onChange={() => invalidate()}\n />\n );\n}\n\nfunction POIMarkers({ store }: { store: StoreApi<ConfiguratorStore> }) {\n const pois = useStore(store, (state) => state.pois);\n\n return (\n <>\n {pois.map((poi) => (\n <POIMarker key={poi.id} {...poi} />\n ))}\n </>\n );\n}\n\nfunction LoadingOverlay({ progress }: { progress: number }) {\n return (\n <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)', zIndex: 10 }}>\n <div style={{ textAlign: 'center', color: 'white' }}>\n <div style={{ width: 200, height: 4, background: '#333', borderRadius: 2, overflow: 'hidden' }}>\n <div style={{ width: `${progress}%`, height: '100%', background: '#4CAF50', transition: 'width 0.3s' }} />\n </div>\n <p style={{ marginTop: 10, fontSize: 14 }}>{Math.round(progress)}%</p>\n </div>\n </div>\n );\n}\n\nfunction EditorControls({ instanceId: _, store }: { instanceId: string; store: StoreApi<ConfiguratorStore> }) {\n const setMaterialVariant = useStore(store, (s) => s.setMaterialVariant);\n const setCameraPreset = useStore(store, (s) => s.setCameraPreset);\n const materialVariants = useStore(store, (s) => s.materialVariants);\n const cameraPresets = useStore(store, (s) => s.cameraPresets);\n\n return (\n <div style={{ position: 'absolute', top: 10, left: 10, background: 'white', padding: 10, borderRadius: 8, boxShadow: '0 2px 10px rgba(0,0,0,0.1)' }}>\n {materialVariants.length > 0 && (\n <div style={{ marginBottom: 10 }}>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Materials:</label>\n {materialVariants.map(v => (\n <button key={v.id} onClick={() => setMaterialVariant(v.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {v.name}\n </button>\n ))}\n </div>\n )}\n {cameraPresets.length > 0 && (\n <div>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Camera:</label>\n {cameraPresets.map(p => (\n <button key={p.id} onClick={() => setCameraPreset(p.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {p.name}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"names":["configuratorStores","Map","ModelViewer","instanceId","data","isEditorMode","store","useState","newStore","createConfiguratorInstance","set","isReady","useStore","state","isLoading","loadingProgress","useEffect","model","url","getState","gltf","loadModel","setFallbackGeometry","fallbackGeometry","dispose","delete","jsxs","style","width","height","position","children","jsx","LoadingOverlay","progress","InstanceProvider","createStore","Canvas","shadows","camera","fov","near","far","frameloop","gl","preserveDrawingBuffer","antialias","powerPreference","attach","args","intensity","lighting","ambientIntensity","directionalPosition","directionalIntensity","castShadow","enableShadows","Model","pois","enabled","POIMarkers","CameraController","enableOrbit","enableZoom","enablePan","Environment","preset","EditorControls","ref","useRef","useFrame","invalidate","current","rotation","scale","setScalar","box","THREE","Box3","setFromObject","center","getCenter","Vector3","size","getSize","maxDim","Math","max","x","y","z","fovRad","PI","finalDistance","tan","setState","cameraTarget","cameraDistance","scene","object","geometry","material","color","metalness","roughness","controlsRef","useThree","angleH","angleV","cos","sin","lookAt","target","update","OrbitControls","onChange","Fragment","map","poi","POIMarker","id","inset","display","alignItems","justifyContent","background","zIndex","textAlign","borderRadius","overflow","transition","marginTop","fontSize","round","_","setMaterialVariant","s","setCameraPreset","materialVariants","cameraPresets","top","left","padding","boxShadow","length","marginBottom","fontWeight","v","onClick","margin","name","p"],"mappings":"ucAaA,MAAMA,qBAAyBC,IAE/B,SAAwBC,GAAYC,WAAEA,EAAAC,KAAYA,EAAAC,aAAMA,IACtD,MAAOC,GAASC,EAAS,KAEvB,MAAMC,EAAWC,EAA2BN,GAE5C,OADAH,EAAmBU,IAAIP,EAAYK,GAC5BA,IAGHG,EAAUC,EAASN,EAAQO,GAAUA,EAAMF,SAC3CG,EAAYF,EAASN,EAAQO,GAAUA,EAAMC,WAC7CC,EAAkBH,EAASN,EAAQO,GAAUA,EAAME,iBAyBzD,OAtBAC,EAAU,KACR,GAAIZ,EAAKa,OAAOC,IAAK,CACnB,MAAML,EAAQP,EAAMa,WACpB,GAAIN,EAAMO,KAAM,OAEhBP,EAAMQ,UAAUjB,EAAKa,MAAMC,IAC7B,KAAO,CAESZ,EAAMa,WACdG,oBAAoBlB,EAAKa,OAAOM,kBAAoB,MAC5D,GACC,CAACnB,EAAKa,OAAOC,IAAKd,EAAKa,OAAOM,iBAAkBjB,IAGnDU,EAAU,IACD,KACSV,EAAMa,WACdK,UACNxB,EAAmByB,OAAOtB,IAE3B,CAACA,EAAYG,mBAGdoB,EAAC,MAAA,CAAIC,MAAO,CAAEC,MAAO,OAAQC,OAAQ,OAAQC,SAAU,YACpDC,SAAA,CAAAjB,kBAAakB,EAACC,EAAA,CAAeC,SAAUnB;iBAEvCoB,EAAA,CAAiBhC,aAAwBiC,YAAa,IAAM9B,EAC3DyB,wBAAAL,EAACW,EAAA,CAECC,SAAO,EACPC,OAAQ,CACNT,SAAU,CAAC,EAAG,EAAG,GACjBU,IAAKpC,EAAKmC,QAAQC,KAAO,GACzBC,KAAMrC,EAAKmC,QAAQE,MAAQ,GAC3BC,IAAKtC,EAAKmC,QAAQG,KAAO,KAE3BC,UAAU,SACVC,GAAI,CACFC,uBAAuB,EACvBC,WAAW,EACXC,gBAAiB,oBAGnBhB,SAAA;eAAAC,EAAC,SAAMgB,OAAO,aAAaC,KAAM,CAAC;iBAEjC,eAAA,CAAaC,UAAW9C,EAAK+C,UAAUC,kBAAoB;eAC5DpB,EAAC,mBAAA,CACCF,SAAU1B,EAAK+C,UAAUE,qBAAuB,CAAC,GAAI,GAAI,GACzDH,UAAW9C,EAAK+C,UAAUG,sBAAwB,EAClDC,WAAYnD,EAAK+C,UAAUK,gBAG5B7C,kBAAWqB,EAACyB,EAAA,CAAMnD,QAAcF,SAChCO,GAAWP,EAAKsD,MAAMC,0BAAYC,GAAWtD;eAE9C0B,EAAC6B,EAAA,CACCvD,QACAqD,SAAsC,IAA7BvD,EAAKmC,QAAQuB,YACtBC,YAAwC,IAA5B3D,EAAKmC,QAAQwB,WACzBC,WAAsC,IAA3B5D,EAAKmC,QAAQyB;eAE1BhC,EAACiC,EAAA,CAAYC,OAAO,WAjCf/D,KAqCRE,GAAgBM,kBAAWqB,EAACmC,EAAA,CAAehE,aAAwBG,YAG1E,CAEA,SAASmD,GAAMnD,MAAEA,EAAAF,KAAOA,IACtB,MAAMgB,EAAOR,EAASN,EAAQO,GAAUA,EAAMO,MACxCG,EAAmBX,EAASN,EAAQO,GAAUA,EAAMU,kBACpD6C,EAAMC,EAAoB,MAqChC,GAnCAC,EAAS,EAAGC,iBACLH,EAAII,SAAYpE,EAAKa,QAC1BmD,EAAII,QAAQ1C,SAASpB,OAAQN,EAAKa,MAAMa,UAAY,CAAC,EAAG,EAAG,IAC3DsC,EAAII,QAAQC,SAAS/D,OAAQN,EAAKa,MAAMwD,UAAY,CAAC,EAAG,EAAG,IAC3DL,EAAII,QAAQE,MAAMC,UAAUvE,EAAKa,MAAMyD,OAAS,GAChDH,OAIFvD,EAAU,KACR,IAAKI,IAASgD,EAAII,QAAS,OAG3B,MAAMI,GAAM,IAAIC,EAAMC,MAAOC,cAAcX,EAAII,SACzCQ,EAASJ,EAAIK,UAAU,IAAIJ,EAAMK,SACjCC,EAAOP,EAAIQ,QAAQ,IAAIP,EAAMK,SAG7BG,EAASC,KAAKC,IAAIJ,EAAKK,EAAGL,EAAKM,EAAGN,EAAKO,GAEvCC,GADMvF,EAAKmC,QAAQC,KAAO,IACV8C,KAAKM,GAAM,IAM3BC,EAAiC,KAHhBR,GAAU,EAAIC,KAAKQ,IAAIH,EAAS,KAMvDrF,EAAMyF,SAAS,CACbC,aAAc,CAAChB,EAAOQ,EAAGR,EAAOS,EAAGT,EAAOU,GAC1CO,eAAgBJ,KAEjB,CAACzE,EAAMhB,EAAKmC,QAAQC,IAAKlC,KAEvBc,EAAM,OAAO,KAElB,GAAIA,GAAM8E;AACR,SAAQ,YAAA,CAAU9B,MAAU+B,OAAQ/E,EAAK8E,QAI3C,MAAME,EAAW7E,GAAoB,MAC/B8E,iBACJrE,EAAC,uBAAA,CACCsE,MAAM,UACNC,UAAW,GACXC,UAAW,KAIf,OAAQJ,GACN,IAAK,MA4BL;AACE,OACE1E,EAAC,QAAK0C,MACJrC,SAAA;eAAAC,EAAC,eAAYiB,KAAM,CAAC,EAAG,EAAG,KACzBoD,KAzBP,IAAK;AACH,OACE3E,EAAC,QAAK0C,MACJrC,SAAA;eAAAC,EAAC,kBAAeiB,KAAM,CAAC,IAAK,GAAI,MAC/BoD,KAGP,IAAK;AACH,OACE3E,EAAC,QAAK0C,MACJrC,SAAA;eAAAC,EAAC,oBAAiBiB,KAAM,CAAC,EAAG,EAAG,EAAG,MACjCoD,KAGP,IAAK;AACH,OACE3E,EAAC,QAAK0C,MACJrC,SAAA;eAAAC,EAAC,iBAAciB,KAAM,CAAC,EAAG,GAAK,GAAI,MACjCoD,KAWX,CAEA,SAASxC,GAAiBvD,MACxBA,EAAAqD,QACAA,EAAAI,WACAA,EAAAC,UACAA,IAOA,MAAMyC,EAAcpC,EAAY,OAC1B9B,OAAEA,EAAAgC,WAAQA,GAAemC,IACzBV,EAAepF,EAASN,EAAQO,GAAUA,EAAMmF,cAChDC,EAAiBrF,EAASN,EAAQO,GAAUA,EAAMoF,gBAyBxD,OAvBAjF,EAAU,KACR,IAAKgF,IAAiBC,EAAgB,OAGtC,MAAMU,EAASrB,KAAKM,GAAK,EACnBgB,EAAStB,KAAKM,GAAK,EAEnBJ,EAAIQ,EAAa,GAAKC,EAAiBX,KAAKuB,IAAID,GAAUtB,KAAKuB,IAAIF,GACnElB,EAAIO,EAAa,GAAKC,EAAiBX,KAAKwB,IAAIF,GAChDlB,EAAIM,EAAa,GAAKC,EAAiBX,KAAKuB,IAAID,GAAUtB,KAAKwB,IAAIH,GAEzEpE,EAAOT,SAASpB,IAAI8E,EAAGC,EAAGC,GAC1BnD,EAAOwE,OAAOf,EAAa,GAAIA,EAAa,GAAIA,EAAa,IAGzDS,EAAYjC,UACdiC,EAAYjC,QAAQwC,OAAOtG,OAAOsF,GAClCS,EAAYjC,QAAQyC,UAGtB1C,KACC,CAACyB,EAAcC,EAAgB1D,EAAQgC,mBAGxCvC,EAACkF,EAAA,CACC9C,IAAKqC,EACL9C,UACAI,aACAC,YACAmD,SAAU,IAAM5C,KAGtB,CAEA,SAASX,GAAWtD,MAAEA,IACpB,MAAMoD,EAAO9C,EAASN,EAAQO,GAAUA,EAAM6C;AAE9C,SACE0D,EAAA,CACGrF,SAAA2B,EAAK2D,IAAKC,kBACTtF,EAACuF,EAAA,IAA2BD,GAAZA,EAAIE,MAI5B,CAEA,SAASvF,GAAeC,SAAEA;AACxB,OACEF,EAAC,MAAA,CAAIL,MAAO,CAAEG,SAAU,WAAY2F,MAAO,EAAGC,QAAS,OAAQC,WAAY,SAAUC,eAAgB,SAAUC,WAAY,kBAAmBC,OAAQ,IACpJ/F,0BAAC,MAAA,CAAIJ,MAAO,CAAEoG,UAAW,SAAUzB,MAAO,SACxCvE,SAAA;eAAAC,EAAC,MAAA,CAAIL,MAAO,CAAEC,MAAO,IAAKC,OAAQ,EAAGgG,WAAY,OAAQG,aAAc,EAAGC,SAAU,UAClFlG,wBAAAC,EAAC,MAAA,CAAIL,MAAO,CAAEC,MAAO,GAAGM,KAAaL,OAAQ,OAAQgG,WAAY,UAAWK,WAAY;eAE1FxG,EAAC,KAAEC,MAAO,CAAEwG,UAAW,GAAIC,SAAU,IAAOrG,SAAA,CAAAuD,KAAK+C,MAAMnG,GAAU,WAIzE,CAEA,SAASiC,GAAiBhE,WAAYmI,EAAAhI,MAAGA,IACvC,MAAMiI,EAAqB3H,EAASN,EAAQkI,GAAMA,EAAED,oBAC9CE,EAAkB7H,EAASN,EAAQkI,GAAMA,EAAEC,iBAC3CC,EAAmB9H,EAASN,EAAQkI,GAAMA,EAAEE,kBAC5CC,EAAgB/H,EAASN,EAAQkI,GAAMA,EAAEG;AAE/C,SACG,MAAA,CAAIhH,MAAO,CAAEG,SAAU,WAAY8G,IAAK,GAAIC,KAAM,GAAIhB,WAAY,QAASiB,QAAS,GAAId,aAAc,EAAGe,UAAW,8BAClHhH,SAAA,CAAA2G,EAAiBM,OAAS,kBACzBtH,EAAC,MAAA,CAAIC,MAAO,CAAEsH,aAAc,IAC1BlH,SAAA;eAAAC,EAAC,QAAA,CAAML,MAAO,CAAEyG,SAAU,GAAIc,WAAY,QAAUnH,SAAA,eACnD2G,EAAiBrB,IAAI8B,kBACpBnH,EAAC,SAAA,CAAkBoH,QAAS,IAAMb,EAAmBY,EAAE3B,IAAK7F,MAAO,CAAE+F,QAAS,QAASoB,QAAS,UAAWO,OAAQ,QAASjB,SAAU,IACnIrG,SAAAoH,EAAEG,MADQH,EAAE3B,QAMpBmB,EAAcK,OAAS,kBACtBtH,EAAC,MAAA,CACCK,SAAA;eAAAC,EAAC,QAAA,CAAML,MAAO,CAAEyG,SAAU,GAAIc,WAAY,QAAUnH,SAAA,YACnD4G,EAActB,IAAIkC,kBACjBvH,EAAC,SAAA,CAAkBoH,QAAS,IAAMX,EAAgBc,EAAE/B,IAAK7F,MAAO,CAAE+F,QAAS,QAASoB,QAAS,UAAWO,OAAQ,QAASjB,SAAU,IAChIrG,SAAAwH,EAAED,MADQC,EAAE/B,UAQ3B"}
@@ -1,2 +0,0 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("react/jsx-runtime"),t=require("react"),r=require("@react-three/fiber"),n=require("@react-three/drei"),s=require("zustand"),a=require("@codefluss/threejs-shared"),o=require("./index.js");function i(e){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(e)for(const r in e)if("default"!==r){const n=Object.getOwnPropertyDescriptor(e,r);Object.defineProperty(t,r,n.get?n:{enumerable:!0,get:()=>e[r]})}return t.default=e,Object.freeze(t)}const l=i(require("three")),c=new Map;function d({store:n,data:a}){const o=s.useStore(n,e=>e.gltf),i=s.useStore(n,e=>e.fallbackGeometry),c=t.useRef(null);if(r.useFrame(({invalidate:e})=>{c.current&&a.model&&(c.current.position.set(...a.model.position||[0,0,0]),c.current.rotation.set(...a.model.rotation||[0,0,0]),c.current.scale.setScalar(a.model.scale||1),e())}),t.useEffect(()=>{if(!o||!c.current)return;const e=(new l.Box3).setFromObject(c.current),t=e.getCenter(new l.Vector3),r=e.getSize(new l.Vector3),s=Math.max(r.x,r.y,r.z),i=(a.camera?.fov||50)*Math.PI/180,d=2.5*(s/(2*Math.tan(i/2)));n.setState({cameraTarget:[t.x,t.y,t.z],cameraDistance:d})},[o,a.camera?.fov,n]),!o)return null;if(o?.scene)return e.jsx("primitive",{ref:c,object:o.scene});const d=i||"box",u=e.jsx("meshStandardMaterial",{color:"#4a90e2",metalness:.3,roughness:.4});switch(d){case"box":default:return e.jsxs("mesh",{ref:c,children:[e.jsx("boxGeometry",{args:[2,2,2]}),u]});case"sphere":return e.jsxs("mesh",{ref:c,children:[e.jsx("sphereGeometry",{args:[1.5,32,32]}),u]});case"cylinder":return e.jsxs("mesh",{ref:c,children:[e.jsx("cylinderGeometry",{args:[1,1,2,32]}),u]});case"torus":return e.jsxs("mesh",{ref:c,children:[e.jsx("torusGeometry",{args:[1,.4,16,32]}),u]})}}function u({store:a,enabled:o,enableZoom:i,enablePan:l}){const c=t.useRef(null),{camera:d,invalidate:u}=r.useThree(),h=s.useStore(a,e=>e.cameraTarget),f=s.useStore(a,e=>e.cameraDistance);return t.useEffect(()=>{if(!h||!f)return;const e=Math.PI/4,t=Math.PI/6,r=h[0]+f*Math.cos(t)*Math.cos(e),n=h[1]+f*Math.sin(t),s=h[2]+f*Math.cos(t)*Math.sin(e);d.position.set(r,n,s),d.lookAt(h[0],h[1],h[2]),c.current&&(c.current.target.set(...h),c.current.update()),u()},[h,f,d,u]),e.jsx(n.OrbitControls,{ref:c,enabled:o,enableZoom:i,enablePan:l,onChange:()=>u()})}function h({store:t}){const r=s.useStore(t,e=>e.pois);return e.jsx(e.Fragment,{children:r.map(t=>e.jsx(a.POIMarker,{...t},t.id))})}function f({progress:t}){return e.jsx("div",{style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:"rgba(0,0,0,0.5)",zIndex:10},children:e.jsxs("div",{style:{textAlign:"center",color:"white"},children:[e.jsx("div",{style:{width:200,height:4,background:"#333",borderRadius:2,overflow:"hidden"},children:e.jsx("div",{style:{width:`${t}%`,height:"100%",background:"#4CAF50",transition:"width 0.3s"}})}),e.jsxs("p",{style:{marginTop:10,fontSize:14},children:[Math.round(t),"%"]})]})})}function m({instanceId:t,store:r}){const n=s.useStore(r,e=>e.setMaterialVariant),a=s.useStore(r,e=>e.setCameraPreset),o=s.useStore(r,e=>e.materialVariants),i=s.useStore(r,e=>e.cameraPresets);return e.jsxs("div",{style:{position:"absolute",top:10,left:10,background:"white",padding:10,borderRadius:8,boxShadow:"0 2px 10px rgba(0,0,0,0.1)"},children:[o.length>0&&e.jsxs("div",{style:{marginBottom:10},children:[e.jsx("label",{style:{fontSize:12,fontWeight:"bold"},children:"Materials:"}),o.map(t=>e.jsx("button",{onClick:()=>n(t.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:t.name},t.id))]}),i.length>0&&e.jsxs("div",{children:[e.jsx("label",{style:{fontSize:12,fontWeight:"bold"},children:"Camera:"}),i.map(t=>e.jsx("button",{onClick:()=>a(t.id),style:{display:"block",padding:"4px 8px",margin:"4px 0",fontSize:11},children:t.name},t.id))]})]})}exports.default=function({instanceId:i,data:l,isEditorMode:g}){const[x]=t.useState(()=>{const e=o.createConfiguratorInstance(i);return c.set(i,e),e}),b=s.useStore(x,e=>e.isReady),p=s.useStore(x,e=>e.isLoading),j=s.useStore(x,e=>e.loadingProgress);return t.useEffect(()=>{if(l.model?.url){const e=x.getState();if(e.gltf)return;e.loadModel(l.model.url)}else{x.getState().setFallbackGeometry(l.model?.fallbackGeometry||"box")}},[l.model?.url,l.model?.fallbackGeometry,x]),t.useEffect(()=>()=>{x.getState().dispose(),c.delete(i)},[i,x]),e.jsxs("div",{style:{width:"100%",height:"100%",position:"relative"},children:[p&&e.jsx(f,{progress:j}),e.jsx(a.InstanceProvider,{instanceId:i,createStore:()=>x,children:e.jsxs(r.Canvas,{shadows:!0,camera:{position:[5,5,5],fov:l.camera?.fov||50,near:l.camera?.near||.1,far:l.camera?.far||2e3},frameloop:"demand",gl:{preserveDrawingBuffer:!0,antialias:!0,powerPreference:"high-performance"},children:[e.jsx("color",{attach:"background",args:["#f0f0f0"]}),e.jsx("ambientLight",{intensity:l.lighting?.ambientIntensity||.5}),e.jsx("directionalLight",{position:l.lighting?.directionalPosition||[10,10,5],intensity:l.lighting?.directionalIntensity||1,castShadow:l.lighting?.enableShadows}),b&&e.jsx(d,{store:x,data:l}),b&&l.pois?.enabled&&e.jsx(h,{store:x}),e.jsx(u,{store:x,enabled:!1!==l.camera?.enableOrbit,enableZoom:!1!==l.camera?.enableZoom,enablePan:!1!==l.camera?.enablePan}),e.jsx(n.Environment,{preset:"city"})]},i)}),g&&b&&e.jsx(m,{instanceId:i,store:x})]})};
2
- //# sourceMappingURL=model-viewer-DQiZ9csY.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"model-viewer-DQiZ9csY.js","sources":["../src/components/model-viewer.tsx"],"sourcesContent":["\"use client\";\n\nimport { useEffect, useRef, useState } from 'react';\nimport { Canvas, useFrame, useThree } from '@react-three/fiber';\nimport { OrbitControls, Environment } from '@react-three/drei';\nimport { useStore } from 'zustand';\nimport { InstanceProvider, POIMarker } from '@codefluss/threejs-shared';\nimport { createConfiguratorInstance } from '../store/configurator-store';\nimport type { ModelViewerProps } from '../types';\nimport type { StoreApi } from 'zustand/vanilla';\nimport type { ConfiguratorStore } from '../types';\nimport * as THREE from 'three';\n\nconst configuratorStores = new Map<string, StoreApi<ConfiguratorStore>>();\n\nexport default function ModelViewer({ instanceId, data, isEditorMode }: ModelViewerProps) {\n const [store] = useState(() => {\n // Always create a fresh store for this instance\n const newStore = createConfiguratorInstance(instanceId);\n configuratorStores.set(instanceId, newStore);\n return newStore;\n });\n\n const isReady = useStore(store, (state) => state.isReady);\n const isLoading = useStore(store, (state) => state.isLoading);\n const loadingProgress = useStore(store, (state) => state.loadingProgress);\n\n // Load model\n useEffect(() => {\n if (data.model?.url) {\n const state = store.getState();\n if (state.gltf) return; // Already loaded\n\n state.loadModel(data.model.url);\n } else {\n // Fallback to built-in geometry\n const state = store.getState();\n state.setFallbackGeometry(data.model?.fallbackGeometry || 'box');\n }\n }, [data.model?.url, data.model?.fallbackGeometry, store]);\n\n // Cleanup on unmount\n useEffect(() => {\n return () => {\n const state = store.getState();\n state.dispose();\n configuratorStores.delete(instanceId);\n };\n }, [instanceId, store]);\n\n return (\n <div style={{ width: '100%', height: '100%', position: 'relative' }}>\n {isLoading && <LoadingOverlay progress={loadingProgress} />}\n\n <InstanceProvider instanceId={instanceId} createStore={() => store}>\n <Canvas\n key={instanceId}\n shadows\n camera={{\n position: [5, 5, 5],\n fov: data.camera?.fov || 50,\n near: data.camera?.near || 0.1,\n far: data.camera?.far || 2000\n }}\n frameloop=\"demand\"\n gl={{\n preserveDrawingBuffer: true,\n antialias: true,\n powerPreference: \"high-performance\"\n }}\n >\n <color attach=\"background\" args={['#f0f0f0']} />\n\n <ambientLight intensity={data.lighting?.ambientIntensity || 0.5} />\n <directionalLight\n position={data.lighting?.directionalPosition || [10, 10, 5]}\n intensity={data.lighting?.directionalIntensity || 1}\n castShadow={data.lighting?.enableShadows}\n />\n\n {isReady && <Model store={store} data={data} />}\n {isReady && data.pois?.enabled && <POIMarkers store={store} />}\n\n <CameraController\n store={store}\n enabled={data.camera?.enableOrbit !== false}\n enableZoom={data.camera?.enableZoom !== false}\n enablePan={data.camera?.enablePan !== false}\n />\n <Environment preset=\"city\" />\n </Canvas>\n </InstanceProvider>\n\n {isEditorMode && isReady && <EditorControls instanceId={instanceId} store={store} />}\n </div>\n );\n}\n\nfunction Model({ store, data }: { store: StoreApi<ConfiguratorStore>; data: ModelViewerProps['data'] }) {\n const gltf = useStore(store, (state) => state.gltf);\n const fallbackGeometry = useStore(store, (state) => state.fallbackGeometry);\n const ref = useRef<THREE.Group>(null);\n\n useFrame(({ invalidate }) => {\n if (!ref.current || !data.model) return;\n ref.current.position.set(...(data.model.position || [0, 0, 0]));\n ref.current.rotation.set(...(data.model.rotation || [0, 0, 0]));\n ref.current.scale.setScalar(data.model.scale || 1);\n invalidate(); // Trigger re-render for frameloop=\"demand\"\n });\n\n // Auto-focus and auto-zoom on model load\n useEffect(() => {\n if (!gltf || !ref.current) return;\n\n // Calculate bounding box\n const box = new THREE.Box3().setFromObject(ref.current);\n const center = box.getCenter(new THREE.Vector3());\n const size = box.getSize(new THREE.Vector3());\n\n // Get the max dimension to determine zoom\n const maxDim = Math.max(size.x, size.y, size.z);\n const fov = data.camera?.fov || 50;\n const fovRad = (fov * Math.PI) / 180;\n\n // Calculate camera distance to fit the object\n const cameraDistance = maxDim / (2 * Math.tan(fovRad / 2));\n\n // Add padding (2.5x for better framing and full visibility)\n const finalDistance = cameraDistance * 2.5;\n\n // Store camera info for OrbitControls\n store.setState({\n cameraTarget: [center.x, center.y, center.z] as [number, number, number],\n cameraDistance: finalDistance\n });\n }, [gltf, data.camera?.fov, store]);\n\n if (!gltf) return null;\n\n if (gltf?.scene) {\n return <primitive ref={ref} object={gltf.scene} />;\n }\n\n // Fallback geometry when no GLTF model is loaded\n const geometry = fallbackGeometry || 'box';\n const material = (\n <meshStandardMaterial\n color=\"#4a90e2\"\n metalness={0.3}\n roughness={0.4}\n />\n );\n\n switch (geometry) {\n case 'box':\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n case 'sphere':\n return (\n <mesh ref={ref}>\n <sphereGeometry args={[1.5, 32, 32]} />\n {material}\n </mesh>\n );\n case 'cylinder':\n return (\n <mesh ref={ref}>\n <cylinderGeometry args={[1, 1, 2, 32]} />\n {material}\n </mesh>\n );\n case 'torus':\n return (\n <mesh ref={ref}>\n <torusGeometry args={[1, 0.4, 16, 32]} />\n {material}\n </mesh>\n );\n default:\n return (\n <mesh ref={ref}>\n <boxGeometry args={[2, 2, 2]} />\n {material}\n </mesh>\n );\n }\n}\n\nfunction CameraController({\n store,\n enabled,\n enableZoom,\n enablePan\n}: {\n store: StoreApi<ConfiguratorStore>;\n enabled: boolean;\n enableZoom: boolean;\n enablePan: boolean;\n}) {\n const controlsRef = useRef<any>(null);\n const { camera, invalidate } = useThree();\n const cameraTarget = useStore(store, (state) => state.cameraTarget);\n const cameraDistance = useStore(store, (state) => state.cameraDistance);\n\n useEffect(() => {\n if (!cameraTarget || !cameraDistance) return;\n\n // Calculate camera position (angle: 45 degrees horizontal, 30 degrees vertical)\n const angleH = Math.PI / 4; // 45 degrees\n const angleV = Math.PI / 6; // 30 degrees\n\n const x = cameraTarget[0] + cameraDistance * Math.cos(angleV) * Math.cos(angleH);\n const y = cameraTarget[1] + cameraDistance * Math.sin(angleV);\n const z = cameraTarget[2] + cameraDistance * Math.cos(angleV) * Math.sin(angleH);\n\n camera.position.set(x, y, z);\n camera.lookAt(cameraTarget[0], cameraTarget[1], cameraTarget[2]);\n\n // Update OrbitControls target\n if (controlsRef.current) {\n controlsRef.current.target.set(...cameraTarget);\n controlsRef.current.update();\n }\n\n invalidate();\n }, [cameraTarget, cameraDistance, camera, invalidate]);\n\n return (\n <OrbitControls\n ref={controlsRef}\n enabled={enabled}\n enableZoom={enableZoom}\n enablePan={enablePan}\n onChange={() => invalidate()}\n />\n );\n}\n\nfunction POIMarkers({ store }: { store: StoreApi<ConfiguratorStore> }) {\n const pois = useStore(store, (state) => state.pois);\n\n return (\n <>\n {pois.map((poi) => (\n <POIMarker key={poi.id} {...poi} />\n ))}\n </>\n );\n}\n\nfunction LoadingOverlay({ progress }: { progress: number }) {\n return (\n <div style={{ position: 'absolute', inset: 0, display: 'flex', alignItems: 'center', justifyContent: 'center', background: 'rgba(0,0,0,0.5)', zIndex: 10 }}>\n <div style={{ textAlign: 'center', color: 'white' }}>\n <div style={{ width: 200, height: 4, background: '#333', borderRadius: 2, overflow: 'hidden' }}>\n <div style={{ width: `${progress}%`, height: '100%', background: '#4CAF50', transition: 'width 0.3s' }} />\n </div>\n <p style={{ marginTop: 10, fontSize: 14 }}>{Math.round(progress)}%</p>\n </div>\n </div>\n );\n}\n\nfunction EditorControls({ instanceId: _, store }: { instanceId: string; store: StoreApi<ConfiguratorStore> }) {\n const setMaterialVariant = useStore(store, (s) => s.setMaterialVariant);\n const setCameraPreset = useStore(store, (s) => s.setCameraPreset);\n const materialVariants = useStore(store, (s) => s.materialVariants);\n const cameraPresets = useStore(store, (s) => s.cameraPresets);\n\n return (\n <div style={{ position: 'absolute', top: 10, left: 10, background: 'white', padding: 10, borderRadius: 8, boxShadow: '0 2px 10px rgba(0,0,0,0.1)' }}>\n {materialVariants.length > 0 && (\n <div style={{ marginBottom: 10 }}>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Materials:</label>\n {materialVariants.map(v => (\n <button key={v.id} onClick={() => setMaterialVariant(v.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {v.name}\n </button>\n ))}\n </div>\n )}\n {cameraPresets.length > 0 && (\n <div>\n <label style={{ fontSize: 12, fontWeight: 'bold' }}>Camera:</label>\n {cameraPresets.map(p => (\n <button key={p.id} onClick={() => setCameraPreset(p.id)} style={{ display: 'block', padding: '4px 8px', margin: '4px 0', fontSize: 11 }}>\n {p.name}\n </button>\n ))}\n </div>\n )}\n </div>\n );\n}\n"],"names":["configuratorStores","Map","Model","store","data","gltf","useStore","state","fallbackGeometry","ref","useRef","useFrame","invalidate","current","model","position","set","rotation","scale","setScalar","useEffect","box","THREE","Box3","setFromObject","center","getCenter","Vector3","size","getSize","maxDim","Math","max","x","y","z","fovRad","camera","fov","PI","finalDistance","tan","setState","cameraTarget","cameraDistance","scene","jsx","object","geometry","material","color","metalness","roughness","jsxs","children","args","CameraController","enabled","enableZoom","enablePan","controlsRef","useThree","angleH","angleV","cos","sin","lookAt","target","update","OrbitControls","onChange","POIMarkers","pois","Fragment","map","poi","POIMarker","id","LoadingOverlay","progress","style","inset","display","alignItems","justifyContent","background","zIndex","textAlign","width","height","borderRadius","overflow","transition","marginTop","fontSize","round","EditorControls","instanceId","_","setMaterialVariant","s","setCameraPreset","materialVariants","cameraPresets","top","left","padding","boxShadow","length","marginBottom","fontWeight","v","onClick","margin","name","p","isEditorMode","useState","newStore","createConfiguratorInstance","isReady","isLoading","loadingProgress","url","getState","loadModel","setFallbackGeometry","dispose","delete","InstanceProvider","createStore","Canvas","shadows","near","far","frameloop","gl","preserveDrawingBuffer","antialias","powerPreference","attach","intensity","lighting","ambientIntensity","directionalPosition","directionalIntensity","castShadow","enableShadows","enableOrbit","Environment","preset"],"mappings":"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"}
@@ -1,7 +0,0 @@
1
- /**
2
- * Configurator 3D Plugin - SSR Renderer Exports
3
- */
4
- export { ConfiguratorRenderer } from './components/configurator-renderer';
5
- export type { ConfiguratorRendererProps } from './components/configurator-renderer';
6
- export type { Configurator3DData, CameraPreset, MaterialVariant, } from './types';
7
- //# sourceMappingURL=renderer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAC1E,YAAY,EAAE,yBAAyB,EAAE,MAAM,oCAAoC,CAAC;AAEpF,YAAY,EACX,kBAAkB,EAClB,YAAY,EACZ,eAAe,GACf,MAAM,SAAS,CAAC"}
@@ -1,9 +0,0 @@
1
- import { ConfiguratorStore } from '../types';
2
- /**
3
- * Configurator Store Factory
4
- *
5
- * Creates isolated 3D configurator instance per plugin instance
6
- * Handles GLTF loading, POI system, material variants, and camera presets
7
- */
8
- export declare function createConfiguratorInstance(instanceId: string): import('zustand').StoreApi<ConfiguratorStore>;
9
- //# sourceMappingURL=configurator-store.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"configurator-store.d.ts","sourceRoot":"","sources":["../../src/store/configurator-store.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,iBAAiB,EAAiC,MAAM,UAAU,CAAC;AAGjF;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,UAAU,EAAE,MAAM,iDAiQ5D"}
@@ -1,129 +0,0 @@
1
- import { GLTF } from 'three/addons/loaders/GLTFLoader.js';
2
- import { POI } from '@codefluss/threejs-shared';
3
- /**
4
- * Camera Preset Interface
5
- */
6
- export interface CameraPreset {
7
- id: string;
8
- name: string;
9
- position: [number, number, number];
10
- target: [number, number, number];
11
- fov?: number;
12
- }
13
- /**
14
- * Material Variant Interface
15
- */
16
- export interface MaterialVariant {
17
- id: string;
18
- name: string;
19
- materialName: string;
20
- properties: {
21
- color?: string;
22
- metalness?: number;
23
- roughness?: number;
24
- emissive?: string;
25
- emissiveIntensity?: number;
26
- map?: string;
27
- };
28
- }
29
- /**
30
- * Configurator 3D Data Interface
31
- */
32
- export interface Configurator3DData {
33
- model?: {
34
- url?: string;
35
- scale?: number;
36
- position?: [number, number, number];
37
- rotation?: [number, number, number];
38
- fallbackGeometry?: 'box' | 'sphere' | 'cylinder' | 'torus';
39
- description?: string;
40
- keywords?: string[];
41
- };
42
- pois?: {
43
- enabled?: boolean;
44
- markers?: POI[];
45
- };
46
- materials?: {
47
- enabled?: boolean;
48
- variants?: MaterialVariant[];
49
- activeVariant?: string;
50
- };
51
- camera?: {
52
- presets?: CameraPreset[];
53
- activePreset?: string;
54
- enableOrbit?: boolean;
55
- enableZoom?: boolean;
56
- enablePan?: boolean;
57
- fov?: number;
58
- near?: number;
59
- far?: number;
60
- };
61
- lighting?: {
62
- ambientIntensity?: number;
63
- directionalIntensity?: number;
64
- directionalPosition?: [number, number, number];
65
- enableShadows?: boolean;
66
- };
67
- layout?: {
68
- height?: string;
69
- position?: 'relative' | 'absolute' | 'fixed' | 'sticky';
70
- };
71
- }
72
- /**
73
- * Configurator Store Interface
74
- */
75
- export interface ConfiguratorStore {
76
- instanceId: string;
77
- gltf: GLTF | null;
78
- fallbackGeometry?: 'box' | 'sphere' | 'cylinder' | 'torus';
79
- isLoading: boolean;
80
- loadingProgress: number;
81
- error: string | null;
82
- isReady: boolean;
83
- pois: POI[];
84
- activePOI: string | null;
85
- materialVariants: MaterialVariant[];
86
- activeMaterialVariant: string | null;
87
- cameraPresets: CameraPreset[];
88
- activeCameraPreset: string | null;
89
- cameraTarget?: [number, number, number];
90
- cameraDistance?: number;
91
- loadModel: (url: string, onProgress?: (progress: number) => void) => Promise<GLTF>;
92
- setFallbackGeometry: (geometry: 'box' | 'sphere' | 'cylinder' | 'torus') => void;
93
- addPOI: (poi: Omit<POI, 'id'>) => string;
94
- updatePOI: (id: string, updates: Partial<POI>) => void;
95
- removePOI: (id: string) => void;
96
- setActivePOI: (id: string | null) => void;
97
- setMaterialVariant: (variantId: string) => void;
98
- addMaterialVariant: (variant: MaterialVariant) => void;
99
- setCameraPreset: (presetId: string) => void;
100
- addCameraPreset: (preset: CameraPreset) => void;
101
- dispose: () => void;
102
- }
103
- /**
104
- * Component Props
105
- */
106
- export interface Configurator3DComponentProps {
107
- data: Configurator3DData;
108
- elementId: string;
109
- isEditorMode?: boolean;
110
- dependencies: any;
111
- }
112
- export interface ModelViewerProps {
113
- instanceId: string;
114
- data: Configurator3DData;
115
- isEditorMode: boolean;
116
- }
117
- export interface POIEditorProps {
118
- instanceId: string;
119
- onPOISelect?: (poiId: string) => void;
120
- }
121
- export interface MaterialEditorProps {
122
- instanceId: string;
123
- onVariantSelect?: (variantId: string) => void;
124
- }
125
- export interface CameraEditorProps {
126
- instanceId: string;
127
- onPresetSelect?: (presetId: string) => void;
128
- }
129
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/types/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oCAAoC,CAAC;AAC/D,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,2BAA2B,CAAC;AAErD;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE;QACV,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,KAAK,CAAC,EAAE;QACN,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QACpC,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;QAC3D,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAC;KACrB,CAAC;IACF,IAAI,CAAC,EAAE;QACL,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,OAAO,CAAC,EAAE,GAAG,EAAE,CAAC;KACjB,CAAC;IACF,SAAS,CAAC,EAAE;QACV,OAAO,CAAC,EAAE,OAAO,CAAC;QAClB,QAAQ,CAAC,EAAE,eAAe,EAAE,CAAC;QAC7B,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;QACzB,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,OAAO,CAAC;QACtB,UAAU,CAAC,EAAE,OAAO,CAAC;QACrB,SAAS,CAAC,EAAE,OAAO,CAAC;QACpB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,GAAG,CAAC,EAAE,MAAM,CAAC;KACd,CAAC;IACF,QAAQ,CAAC,EAAE;QACT,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,oBAAoB,CAAC,EAAE,MAAM,CAAC;QAC9B,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;QAC/C,aAAa,CAAC,EAAE,OAAO,CAAC;KACzB,CAAC;IACF,MAAM,CAAC,EAAE;QACP,MAAM,CAAC,EAAE,MAAM,CAAC;QAChB,QAAQ,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,OAAO,GAAG,QAAQ,CAAC;KACzD,CAAC;CACH;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,IAAI,GAAG,IAAI,CAAC;IAClB,gBAAgB,CAAC,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,CAAC;IAC3D,SAAS,EAAE,OAAO,CAAC;IACnB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,OAAO,CAAC;IAGjB,IAAI,EAAE,GAAG,EAAE,CAAC;IACZ,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAGzB,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,qBAAqB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGrC,aAAa,EAAE,YAAY,EAAE,CAAC;IAC9B,kBAAkB,EAAE,MAAM,GAAG,IAAI,CAAC;IAGlC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,cAAc,CAAC,EAAE,MAAM,CAAC;IAGxB,SAAS,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAGnF,mBAAmB,EAAE,CAAC,QAAQ,EAAE,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,KAAK,IAAI,CAAC;IAGjF,MAAM,EAAE,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,KAAK,MAAM,CAAC;IACzC,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,CAAC;IACvD,SAAS,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,YAAY,EAAE,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC;IAG1C,kBAAkB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IAChD,kBAAkB,EAAE,CAAC,OAAO,EAAE,eAAe,KAAK,IAAI,CAAC;IAGvD,eAAe,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C,eAAe,EAAE,CAAC,MAAM,EAAE,YAAY,KAAK,IAAI,CAAC;IAGhD,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB;AAED;;GAEG;AACH,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,kBAAkB,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,YAAY,EAAE,GAAG,CAAC;CACnB;AAED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,MAAM,CAAC;IACnB,IAAI,EAAE,kBAAkB,CAAC;IACzB,YAAY,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,cAAc;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;CAC/C;AAED,MAAM,WAAW,iBAAiB;IAChC,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C"}