@playdrop/playdrop-cli 0.7.15 → 0.7.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/config/client-meta.json +1 -1
  2. package/node_modules/@playdrop/ai-client/dist/index.js +461 -444
  3. package/node_modules/@playdrop/ai-client/package.json +1 -1
  4. package/node_modules/@playdrop/api-client/dist/client.js +903 -882
  5. package/node_modules/@playdrop/api-client/dist/core/errors.js +69 -45
  6. package/node_modules/@playdrop/api-client/dist/core/request.js +188 -159
  7. package/node_modules/@playdrop/api-client/dist/domains/admin.js +516 -491
  8. package/node_modules/@playdrop/api-client/dist/domains/ai.js +40 -14
  9. package/node_modules/@playdrop/api-client/dist/domains/apps.js +480 -462
  10. package/node_modules/@playdrop/api-client/dist/domains/asset-packs.js +439 -419
  11. package/node_modules/@playdrop/api-client/dist/domains/assets.js +696 -676
  12. package/node_modules/@playdrop/api-client/dist/domains/auth.js +346 -320
  13. package/node_modules/@playdrop/api-client/dist/domains/comments.js +124 -98
  14. package/node_modules/@playdrop/api-client/dist/domains/free-credits.js +91 -65
  15. package/node_modules/@playdrop/api-client/dist/domains/me.js +71 -45
  16. package/node_modules/@playdrop/api-client/dist/domains/payments.js +407 -386
  17. package/node_modules/@playdrop/api-client/dist/domains/player-meta.js +144 -118
  18. package/node_modules/@playdrop/api-client/dist/domains/search.js +117 -104
  19. package/node_modules/@playdrop/api-client/dist/domains/tags.js +188 -162
  20. package/node_modules/@playdrop/api-client/dist/index.js +993 -552
  21. package/node_modules/@playdrop/api-client/package.json +1 -1
  22. package/node_modules/@playdrop/boxel-three/dist/src/animations.js +84 -62
  23. package/node_modules/@playdrop/boxel-three/dist/src/builders.js +341 -308
  24. package/node_modules/@playdrop/boxel-three/dist/src/context.js +55 -29
  25. package/node_modules/@playdrop/boxel-three/dist/src/exporters/glb.js +856 -858
  26. package/node_modules/@playdrop/boxel-three/dist/src/exporters/image.js +267 -261
  27. package/node_modules/@playdrop/boxel-three/dist/src/index.js +64 -15
  28. package/node_modules/@playdrop/boxel-three/dist/src/instantiate.js +89 -63
  29. package/node_modules/@playdrop/boxel-three/dist/src/nodes.js +81 -56
  30. package/node_modules/@playdrop/boxel-three/dist/src/overlays.js +112 -86
  31. package/node_modules/@playdrop/boxel-three/dist/src/primitives.js +45 -17
  32. package/node_modules/@playdrop/boxel-three/dist/src/scene.js +160 -136
  33. package/node_modules/@playdrop/boxel-three/dist/src/skinned-mesh.js +582 -584
  34. package/node_modules/@playdrop/boxel-three/dist/src/texture-atlas.js +123 -97
  35. package/node_modules/@playdrop/boxel-three/dist/src/textures.js +207 -182
  36. package/node_modules/@playdrop/boxel-three/dist/src/types.js +15 -1
  37. package/node_modules/@playdrop/boxel-three/dist/src/voxels/faces.js +451 -425
  38. package/node_modules/@playdrop/boxel-three/dist/src/voxels/mesher.js +109 -84
  39. package/node_modules/@playdrop/boxel-three/dist/test/export-image.playwright.test.js +127 -106
  40. package/node_modules/@playdrop/boxel-three/dist/test/fixtures/render-worker.js +73 -51
  41. package/node_modules/@playdrop/boxel-three/dist/test/glb-skinned.test.js +97 -79
  42. package/node_modules/@playdrop/boxel-three/dist/test/index.test.js +29 -7
  43. package/node_modules/@playdrop/boxel-three/dist/test/instantiate.test.js +80 -60
  44. package/node_modules/@playdrop/boxel-three/dist/test/overlays.test.js +41 -19
  45. package/node_modules/@playdrop/boxel-three/dist/test/scene-filter.test.js +72 -50
  46. package/node_modules/@playdrop/boxel-three/dist/test/scene-smoke.test.js +84 -62
  47. package/node_modules/@playdrop/boxel-three/dist/test/skinned-mesh.test.js +69 -47
  48. package/node_modules/@playdrop/boxel-three/dist/test/textured-overlay.test.js +129 -109
  49. package/node_modules/@playdrop/boxel-three/dist/test/voxels.test.js +40 -18
  50. package/node_modules/@playdrop/boxel-three/package.json +1 -1
  51. package/node_modules/@playdrop/config/client-meta.json +1 -1
  52. package/node_modules/@playdrop/types/dist/api.js +289 -203
  53. package/node_modules/@playdrop/types/dist/app-capability-filters.js +112 -62
  54. package/node_modules/@playdrop/types/dist/app.js +91 -45
  55. package/node_modules/@playdrop/types/dist/asset-pack.js +37 -5
  56. package/node_modules/@playdrop/types/dist/asset-spec.js +170 -90
  57. package/node_modules/@playdrop/types/dist/asset.js +186 -108
  58. package/node_modules/@playdrop/types/dist/content-license.js +49 -15
  59. package/node_modules/@playdrop/types/dist/creator-public-image.js +60 -32
  60. package/node_modules/@playdrop/types/dist/ecs.js +102 -82
  61. package/node_modules/@playdrop/types/dist/engine-builtins.js +603 -573
  62. package/node_modules/@playdrop/types/dist/entity.js +63 -53
  63. package/node_modules/@playdrop/types/dist/graph.js +116 -80
  64. package/node_modules/@playdrop/types/dist/index.js +47 -20
  65. package/node_modules/@playdrop/types/dist/owned-assets.js +55 -33
  66. package/node_modules/@playdrop/types/dist/player-meta.js +151 -100
  67. package/node_modules/@playdrop/types/dist/realtime.js +27 -7
  68. package/node_modules/@playdrop/types/dist/version.js +182 -124
  69. package/node_modules/@playdrop/types/package.json +1 -1
  70. package/package.json +1 -1
@@ -1,288 +1,294 @@
1
- import { createBoxelScene } from '../scene.js';
2
- import { createBoxelSceneGraph } from './glb.js';
3
- import { buildEntitySkinnedMesh } from '../skinned-mesh.js';
4
- import { buildAnimations } from '../animations.js';
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var image_exports = {};
19
+ __export(image_exports, {
20
+ renderBoxelToDataURL: () => renderBoxelToDataURL
21
+ });
22
+ module.exports = __toCommonJS(image_exports);
23
+ var import_scene = require("../scene.js");
24
+ var import_glb = require("./glb.js");
25
+ var import_skinned_mesh = require("../skinned-mesh.js");
26
+ var import_animations = require("../animations.js");
5
27
  function findNodeById(root, id) {
6
- if (root.id === id)
7
- return root;
8
- for (const child of root.children) {
9
- const found = findNodeById(child, id);
10
- if (found)
11
- return found;
12
- }
13
- return null;
28
+ if (root.id === id)
29
+ return root;
30
+ for (const child of root.children) {
31
+ const found = findNodeById(child, id);
32
+ if (found)
33
+ return found;
34
+ }
35
+ return null;
14
36
  }
15
37
  const DIRECTION_VECTORS = {
16
- preview: [1.2, 1.4, 1.3],
17
- headshot: [-0.35, 0.05, 1.0],
18
- top: [0, 1, 0],
19
- bottom: [0, -1, 0],
20
- front: [0, 0, 1],
21
- back: [0, 0, -1],
22
- left: [-1, 0, 0],
23
- right: [1, 0, 0],
38
+ preview: [1.2, 1.4, 1.3],
39
+ headshot: [-0.35, 0.05, 1],
40
+ top: [0, 1, 0],
41
+ bottom: [0, -1, 0],
42
+ front: [0, 0, 1],
43
+ back: [0, 0, -1],
44
+ left: [-1, 0, 0],
45
+ right: [1, 0, 0]
24
46
  };
25
47
  const UP_VECTORS = {
26
- top: [0, 0, -1],
27
- bottom: [0, 0, 1],
48
+ top: [0, 0, -1],
49
+ bottom: [0, 0, 1]
28
50
  };
29
51
  const CAMERA_DISTANCE_FACTOR = 1.25;
30
52
  const DEFAULT_MIN_DISTANCE = 2.5;
31
53
  const HEADSHOT_MIN_DISTANCE = 2;
32
54
  const HEADSHOT_RADIUS_PADDING = 1.3;
33
- const HEAD_NODE_IDS = ['head', 'Head'];
55
+ const HEAD_NODE_IDS = ["head", "Head"];
34
56
  const HEADSHOT_VERTICAL_OFFSET_RATIO = 2 / 3;
35
- const AMBIENT_LIGHT_COLOR = 0xb4c6fc;
57
+ const AMBIENT_LIGHT_COLOR = 11847420;
36
58
  const AMBIENT_LIGHT_INTENSITY = 2.2;
37
- const DIRECTIONAL_LIGHT_COLOR = 0xf8fafc;
59
+ const DIRECTIONAL_LIGHT_COLOR = 16317180;
38
60
  const DIRECTIONAL_LIGHT_INTENSITY = 1.3;
39
61
  const DIRECTIONAL_LIGHT_MIN_HEIGHT_OFFSET = 2;
40
62
  const SHADOW_MAP_SIZE = 2048;
41
- const SHADOW_BIAS = -0.00012;
42
- const SHADOW_NORMAL_BIAS = 0.006;
63
+ const SHADOW_BIAS = -12e-5;
64
+ const SHADOW_NORMAL_BIAS = 6e-3;
43
65
  const SUPER_SAMPLE_RATIO = 2;
44
- export async function renderBoxelToDataURL(options) {
45
- const { THREE: three, renderer, entity, mode = 'hierarchical', animationId, width, height, direction = 'preview', background = null, } = options;
46
- const sizeTarget = new three.Vector2();
47
- renderer.getSize(sizeTarget);
48
- const previousWidth = sizeTarget.x;
49
- const previousHeight = sizeTarget.y;
50
- const previousPixelRatio = renderer.getPixelRatio();
51
- const previousShadowEnabled = renderer.shadowMap.enabled;
52
- const previousShadowType = renderer.shadowMap.type;
53
- const previousShadowAutoUpdate = renderer.shadowMap.autoUpdate;
54
- const clearColor = renderer.getClearColor(new three.Color());
55
- const clearAlpha = renderer.getClearAlpha();
56
- const targetWidth = width ?? (previousWidth || 1024);
57
- const targetHeight = height ?? (previousHeight || 1024);
58
- renderer.setPixelRatio(SUPER_SAMPLE_RATIO);
59
- renderer.setSize(targetWidth, targetHeight, false);
60
- renderer.shadowMap.enabled = true;
61
- renderer.shadowMap.autoUpdate = true;
62
- renderer.shadowMap.type = three.PCFSoftShadowMap;
63
- if (background === null) {
64
- renderer.setClearColor(0x000000, 0);
65
- }
66
- else if (background !== undefined) {
67
- const color = new three.Color(background);
68
- renderer.setClearColor(color, 1);
69
- }
70
- let disposeScene;
71
- let root;
72
- let animations = [];
73
- let nodeLookup = null;
74
- if (mode === 'hierarchical') {
75
- const scene = createBoxelScene({ THREE: three, entity });
76
- disposeScene = scene.dispose;
77
- root = scene.root;
78
- animations = scene.animations;
79
- nodeLookup = new Map();
80
- scene.nodes.forEach(meta => {
81
- nodeLookup.set(meta.id, meta.object);
82
- });
66
+ async function renderBoxelToDataURL(options) {
67
+ const { THREE: three, renderer, entity, mode = "hierarchical", animationId, width, height, direction = "preview", background = null } = options;
68
+ const sizeTarget = new three.Vector2();
69
+ renderer.getSize(sizeTarget);
70
+ const previousWidth = sizeTarget.x;
71
+ const previousHeight = sizeTarget.y;
72
+ const previousPixelRatio = renderer.getPixelRatio();
73
+ const previousShadowEnabled = renderer.shadowMap.enabled;
74
+ const previousShadowType = renderer.shadowMap.type;
75
+ const previousShadowAutoUpdate = renderer.shadowMap.autoUpdate;
76
+ const clearColor = renderer.getClearColor(new three.Color());
77
+ const clearAlpha = renderer.getClearAlpha();
78
+ const targetWidth = width ?? (previousWidth || 1024);
79
+ const targetHeight = height ?? (previousHeight || 1024);
80
+ renderer.setPixelRatio(SUPER_SAMPLE_RATIO);
81
+ renderer.setSize(targetWidth, targetHeight, false);
82
+ renderer.shadowMap.enabled = true;
83
+ renderer.shadowMap.autoUpdate = true;
84
+ renderer.shadowMap.type = three.PCFSoftShadowMap;
85
+ if (background === null) {
86
+ renderer.setClearColor(0, 0);
87
+ } else if (background !== void 0) {
88
+ const color = new three.Color(background);
89
+ renderer.setClearColor(color, 1);
90
+ }
91
+ let disposeScene;
92
+ let root;
93
+ let animations = [];
94
+ let nodeLookup = null;
95
+ if (mode === "hierarchical") {
96
+ const scene2 = (0, import_scene.createBoxelScene)({ THREE: three, entity });
97
+ disposeScene = scene2.dispose;
98
+ root = scene2.root;
99
+ animations = scene2.animations;
100
+ nodeLookup = /* @__PURE__ */ new Map();
101
+ scene2.nodes.forEach((meta) => {
102
+ nodeLookup.set(meta.id, meta.object);
103
+ });
104
+ } else if (mode === "skinned") {
105
+ const skinned = (0, import_skinned_mesh.buildEntitySkinnedMesh)({ THREE: three, entity });
106
+ const group = new three.Group();
107
+ group.add(skinned.mesh);
108
+ disposeScene = () => {
109
+ skinned.dispose();
110
+ };
111
+ root = group;
112
+ nodeLookup = /* @__PURE__ */ new Map();
113
+ skinned.boneMap.forEach((bone, nodeId) => nodeLookup.set(nodeId, bone));
114
+ animations = (0, import_animations.buildAnimations)(three, entity, nodeLookup);
115
+ } else {
116
+ const sceneGraph = (0, import_glb.createBoxelSceneGraph)({ THREE: three, model: entity, mode });
117
+ disposeScene = sceneGraph.dispose;
118
+ root = sceneGraph.root;
119
+ animations = sceneGraph.animations;
120
+ nodeLookup = sceneGraph.nodeLookup;
121
+ }
122
+ const scene = new three.Scene();
123
+ scene.background = background === null ? null : background === void 0 ? null : new three.Color(background);
124
+ scene.add(root);
125
+ root.traverse((obj) => {
126
+ const mesh = obj;
127
+ if (mesh.isMesh) {
128
+ mesh.castShadow = true;
129
+ mesh.receiveShadow = true;
83
130
  }
84
- else if (mode === 'skinned') {
85
- const skinned = buildEntitySkinnedMesh({ THREE: three, entity });
86
- const group = new three.Group();
87
- group.add(skinned.mesh);
88
- disposeScene = () => {
89
- skinned.dispose();
90
- };
91
- root = group;
92
- nodeLookup = new Map();
93
- skinned.boneMap.forEach((bone, nodeId) => nodeLookup.set(nodeId, bone));
94
- animations = buildAnimations(three, entity, nodeLookup);
131
+ });
132
+ const ambient = new three.AmbientLight(AMBIENT_LIGHT_COLOR, AMBIENT_LIGHT_INTENSITY);
133
+ const directional = new three.DirectionalLight(DIRECTIONAL_LIGHT_COLOR, DIRECTIONAL_LIGHT_INTENSITY);
134
+ directional.castShadow = true;
135
+ directional.shadow.mapSize.set(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
136
+ directional.shadow.bias = SHADOW_BIAS;
137
+ directional.shadow.normalBias = SHADOW_NORMAL_BIAS;
138
+ scene.add(ambient);
139
+ scene.add(directional);
140
+ let dataUrl = "";
141
+ const requestedAnimationId = typeof animationId === "string" && animationId.trim().length > 0 ? animationId.trim() : null;
142
+ const normalizedRequestedAnimationId = requestedAnimationId?.toLowerCase();
143
+ let sampleClip = null;
144
+ if (requestedAnimationId) {
145
+ sampleClip = animations.find((entry) => entry.id === requestedAnimationId || entry.id.toLowerCase() === normalizedRequestedAnimationId) ?? null;
146
+ if (!sampleClip) {
147
+ throw new Error(`Animation "${requestedAnimationId}" was not found for this entity.`);
95
148
  }
96
- else {
97
- const sceneGraph = createBoxelSceneGraph({ THREE: three, model: entity, mode });
98
- disposeScene = sceneGraph.dispose;
99
- root = sceneGraph.root;
100
- animations = sceneGraph.animations;
101
- nodeLookup = sceneGraph.nodeLookup;
149
+ } else if ((direction === "preview" || direction === "headshot") && animations.length > 0) {
150
+ const idleAnimation = animations.find((entry) => entry.id.toLowerCase().includes("idle"));
151
+ if (idleAnimation) {
152
+ sampleClip = idleAnimation;
102
153
  }
103
- const scene = new three.Scene();
104
- scene.background = background === null ? null : background === undefined ? null : new three.Color(background);
105
- scene.add(root);
106
- root.traverse(obj => {
107
- const mesh = obj;
108
- if (mesh.isMesh) {
109
- mesh.castShadow = true;
110
- mesh.receiveShadow = true;
154
+ }
155
+ let mixer = null;
156
+ if (sampleClip) {
157
+ mixer = new three.AnimationMixer(root);
158
+ const action = mixer.clipAction(sampleClip.clip);
159
+ action.play();
160
+ action.paused = true;
161
+ const firstKeyframe = sampleClip.channels.reduce((min, channel) => {
162
+ const times = channel.track.times;
163
+ if (!times || times.length === 0) {
164
+ return min;
165
+ }
166
+ const firstTime = times[0];
167
+ return Number.isFinite(firstTime) && firstTime < min ? firstTime : min;
168
+ }, Number.POSITIVE_INFINITY);
169
+ const sampleTime = Number.isFinite(firstKeyframe) ? firstKeyframe : 0;
170
+ mixer.setTime(sampleTime);
171
+ mixer.update(0);
172
+ }
173
+ try {
174
+ root.updateMatrixWorld(true);
175
+ const bounds = new three.Box3().setFromObject(root);
176
+ const sphere = bounds.getBoundingSphere(new three.Sphere());
177
+ const center = sphere.center.clone();
178
+ let radius = sphere.radius || 1;
179
+ let headCenter = null;
180
+ if (direction === "headshot" && nodeLookup) {
181
+ const headObject = HEAD_NODE_IDS.map((id) => nodeLookup.get(id)).find(Boolean);
182
+ if (headObject) {
183
+ let headBounds;
184
+ if (mode === "skinned" && headObject.type === "Bone") {
185
+ const headNode = findNodeById(entity.geometry.root, headObject.name);
186
+ if (headNode?.size) {
187
+ headObject.updateMatrixWorld(true);
188
+ const nodeCenter = headNode.center ?? [0, 0, 0];
189
+ const halfSize = headNode.size.map((s) => s / 2);
190
+ const localMin = new three.Vector3(nodeCenter[0] - halfSize[0], nodeCenter[1] - halfSize[1], nodeCenter[2] - halfSize[2]);
191
+ const localMax = new three.Vector3(nodeCenter[0] + halfSize[0], nodeCenter[1] + halfSize[1], nodeCenter[2] + halfSize[2]);
192
+ localMin.applyMatrix4(headObject.matrixWorld);
193
+ localMax.applyMatrix4(headObject.matrixWorld);
194
+ headBounds = new three.Box3(localMin, localMax);
195
+ } else {
196
+ headBounds = new three.Box3().setFromObject(headObject);
197
+ }
198
+ } else {
199
+ headBounds = new three.Box3().setFromObject(headObject);
111
200
  }
112
- });
113
- const ambient = new three.AmbientLight(AMBIENT_LIGHT_COLOR, AMBIENT_LIGHT_INTENSITY);
114
- const directional = new three.DirectionalLight(DIRECTIONAL_LIGHT_COLOR, DIRECTIONAL_LIGHT_INTENSITY);
115
- directional.castShadow = true;
116
- directional.shadow.mapSize.set(SHADOW_MAP_SIZE, SHADOW_MAP_SIZE);
117
- directional.shadow.bias = SHADOW_BIAS;
118
- directional.shadow.normalBias = SHADOW_NORMAL_BIAS;
119
- scene.add(ambient);
120
- scene.add(directional);
121
- let dataUrl = '';
122
- const requestedAnimationId = typeof animationId === 'string' && animationId.trim().length > 0 ? animationId.trim() : null;
123
- const normalizedRequestedAnimationId = requestedAnimationId?.toLowerCase();
124
- let sampleClip = null;
125
- if (requestedAnimationId) {
126
- sampleClip =
127
- animations.find(entry => entry.id === requestedAnimationId ||
128
- entry.id.toLowerCase() === normalizedRequestedAnimationId) ?? null;
129
- if (!sampleClip) {
130
- throw new Error(`Animation "${requestedAnimationId}" was not found for this entity.`);
201
+ if (!headBounds.isEmpty()) {
202
+ headCenter = headBounds.getCenter(new three.Vector3());
203
+ center.copy(headCenter);
204
+ const headSphere = headBounds.getBoundingSphere(new three.Sphere());
205
+ const headRadius = headSphere.radius || radius;
206
+ radius = Math.max(headRadius * HEADSHOT_RADIUS_PADDING, headRadius);
207
+ center.y -= radius * HEADSHOT_VERTICAL_OFFSET_RATIO;
131
208
  }
209
+ }
132
210
  }
133
- else if ((direction === 'preview' || direction === 'headshot') && animations.length > 0) {
134
- const idleAnimation = animations.find(entry => entry.id.toLowerCase().includes('idle'));
135
- if (idleAnimation) {
136
- sampleClip = idleAnimation;
137
- }
211
+ const camera = new three.PerspectiveCamera(50, targetWidth / targetHeight, 0.1, Math.max(1e3, radius * 10));
212
+ const dir = DIRECTION_VECTORS[direction] ?? DIRECTION_VECTORS.preview;
213
+ const target = new three.Vector3().fromArray(dir).normalize();
214
+ const minDistance = direction === "headshot" ? HEADSHOT_MIN_DISTANCE : DEFAULT_MIN_DISTANCE;
215
+ let distance = Math.max(radius * CAMERA_DISTANCE_FACTOR, minDistance);
216
+ const basePosition = center.clone().add(target.clone().multiplyScalar(distance));
217
+ if (direction === "headshot" && headCenter) {
218
+ const deltaY = headCenter.y - center.y;
219
+ if (Math.abs(deltaY) >= distance) {
220
+ distance = Math.abs(deltaY) + 0.1;
221
+ }
222
+ const horizontalMagnitude = Math.sqrt(Math.max(0, distance * distance - deltaY * deltaY));
223
+ const horizontalDir = new three.Vector3(target.x, 0, target.z);
224
+ if (horizontalDir.lengthSq() > 0) {
225
+ horizontalDir.normalize().multiplyScalar(horizontalMagnitude);
226
+ camera.position.set(center.x + horizontalDir.x, headCenter.y, center.z + horizontalDir.z);
227
+ } else {
228
+ camera.position.set(center.x, headCenter.y, center.z);
229
+ }
230
+ } else {
231
+ camera.position.copy(basePosition);
138
232
  }
139
- let mixer = null;
140
- if (sampleClip) {
141
- mixer = new three.AnimationMixer(root);
142
- const action = mixer.clipAction(sampleClip.clip);
143
- action.play();
144
- action.paused = true;
145
- const firstKeyframe = sampleClip.channels.reduce((min, channel) => {
146
- const times = channel.track.times;
147
- if (!times || times.length === 0) {
148
- return min;
149
- }
150
- const firstTime = times[0];
151
- return Number.isFinite(firstTime) && firstTime < min ? firstTime : min;
152
- }, Number.POSITIVE_INFINITY);
153
- const sampleTime = Number.isFinite(firstKeyframe) ? firstKeyframe : 0;
154
- mixer.setTime(sampleTime);
155
- mixer.update(0);
233
+ camera.aspect = targetWidth / targetHeight;
234
+ camera.updateProjectionMatrix();
235
+ camera.lookAt(center);
236
+ const up = UP_VECTORS[direction];
237
+ if (up) {
238
+ camera.up.set(up[0], up[1], up[2]);
239
+ } else {
240
+ camera.up.set(0, 1, 0);
156
241
  }
157
- try {
158
- root.updateMatrixWorld(true);
159
- const bounds = new three.Box3().setFromObject(root);
160
- const sphere = bounds.getBoundingSphere(new three.Sphere());
161
- const center = sphere.center.clone();
162
- let radius = sphere.radius || 1;
163
- let headCenter = null;
164
- if (direction === 'headshot' && nodeLookup) {
165
- const headObject = HEAD_NODE_IDS.map(id => nodeLookup.get(id)).find(Boolean);
166
- if (headObject) {
167
- let headBounds;
168
- // For skinned meshes (bones), use node definition to avoid bone hierarchy inflation
169
- if (mode === 'skinned' && headObject.type === 'Bone') {
170
- const headNode = findNodeById(entity.geometry.root, headObject.name);
171
- if (headNode?.size) {
172
- // Calculate bounds from node definition
173
- headObject.updateMatrixWorld(true);
174
- const nodeCenter = headNode.center ?? [0, 0, 0];
175
- const halfSize = headNode.size.map(s => s / 2);
176
- // Create local bounds
177
- const localMin = new three.Vector3(nodeCenter[0] - halfSize[0], nodeCenter[1] - halfSize[1], nodeCenter[2] - halfSize[2]);
178
- const localMax = new three.Vector3(nodeCenter[0] + halfSize[0], nodeCenter[1] + halfSize[1], nodeCenter[2] + halfSize[2]);
179
- // Transform to world space
180
- localMin.applyMatrix4(headObject.matrixWorld);
181
- localMax.applyMatrix4(headObject.matrixWorld);
182
- headBounds = new three.Box3(localMin, localMax);
183
- }
184
- else {
185
- // Fallback to setFromObject if no size defined
186
- headBounds = new three.Box3().setFromObject(headObject);
187
- }
188
- }
189
- else {
190
- // For hierarchical mode, use setFromObject as before
191
- headBounds = new three.Box3().setFromObject(headObject);
192
- }
193
- if (!headBounds.isEmpty()) {
194
- headCenter = headBounds.getCenter(new three.Vector3());
195
- center.copy(headCenter);
196
- const headSphere = headBounds.getBoundingSphere(new three.Sphere());
197
- const headRadius = headSphere.radius || radius;
198
- radius = Math.max(headRadius * HEADSHOT_RADIUS_PADDING, headRadius);
199
- center.y -= radius * HEADSHOT_VERTICAL_OFFSET_RATIO;
200
- }
201
- }
202
- }
203
- const camera = new three.PerspectiveCamera(50, targetWidth / targetHeight, 0.1, Math.max(1000, radius * 10));
204
- const dir = DIRECTION_VECTORS[direction] ?? DIRECTION_VECTORS.preview;
205
- const target = new three.Vector3().fromArray(dir).normalize();
206
- const minDistance = direction === 'headshot' ? HEADSHOT_MIN_DISTANCE : DEFAULT_MIN_DISTANCE;
207
- let distance = Math.max(radius * CAMERA_DISTANCE_FACTOR, minDistance);
208
- const basePosition = center.clone().add(target.clone().multiplyScalar(distance));
209
- if (direction === 'headshot' && headCenter) {
210
- const deltaY = headCenter.y - center.y;
211
- if (Math.abs(deltaY) >= distance) {
212
- distance = Math.abs(deltaY) + 0.1;
213
- }
214
- const horizontalMagnitude = Math.sqrt(Math.max(0, distance * distance - deltaY * deltaY));
215
- const horizontalDir = new three.Vector3(target.x, 0, target.z);
216
- if (horizontalDir.lengthSq() > 0) {
217
- horizontalDir.normalize().multiplyScalar(horizontalMagnitude);
218
- camera.position.set(center.x + horizontalDir.x, headCenter.y, center.z + horizontalDir.z);
219
- }
220
- else {
221
- camera.position.set(center.x, headCenter.y, center.z);
222
- }
223
- }
224
- else {
225
- camera.position.copy(basePosition);
226
- }
227
- camera.aspect = targetWidth / targetHeight;
228
- camera.updateProjectionMatrix();
229
- camera.lookAt(center);
230
- const up = UP_VECTORS[direction];
231
- if (up) {
232
- camera.up.set(up[0], up[1], up[2]);
233
- }
234
- else {
235
- camera.up.set(0, 1, 0);
236
- }
237
- const lightPosition = camera.position.clone();
238
- lightPosition.y = Math.max(lightPosition.y, center.y + DIRECTIONAL_LIGHT_MIN_HEIGHT_OFFSET);
239
- directional.position.copy(lightPosition);
240
- directional.target.position.copy(center);
241
- directional.target.updateMatrixWorld();
242
- const shadowCamera = directional.shadow.camera;
243
- const cameraRange = Math.max(10, radius * 4);
244
- shadowCamera.left = -cameraRange;
245
- shadowCamera.right = cameraRange;
246
- shadowCamera.top = cameraRange;
247
- shadowCamera.bottom = -cameraRange;
248
- shadowCamera.near = 0.1;
249
- shadowCamera.far = Math.max(50, radius * 8);
250
- shadowCamera.updateProjectionMatrix();
251
- scene.add(directional.target);
252
- renderer.render(scene, camera);
253
- if (typeof document !== 'undefined') {
254
- const captureCanvas = document.createElement('canvas');
255
- captureCanvas.width = targetWidth;
256
- captureCanvas.height = targetHeight;
257
- const ctx = captureCanvas.getContext('2d');
258
- if (!ctx) {
259
- dataUrl = renderer.domElement.toDataURL('image/png');
260
- }
261
- else {
262
- ctx.clearRect(0, 0, targetWidth, targetHeight);
263
- ctx.drawImage(renderer.domElement, 0, 0, targetWidth, targetHeight);
264
- dataUrl = captureCanvas.toDataURL('image/png');
265
- }
266
- }
267
- else {
268
- dataUrl = renderer.domElement.toDataURL('image/png');
269
- }
270
- scene.remove(directional.target);
242
+ const lightPosition = camera.position.clone();
243
+ lightPosition.y = Math.max(lightPosition.y, center.y + DIRECTIONAL_LIGHT_MIN_HEIGHT_OFFSET);
244
+ directional.position.copy(lightPosition);
245
+ directional.target.position.copy(center);
246
+ directional.target.updateMatrixWorld();
247
+ const shadowCamera = directional.shadow.camera;
248
+ const cameraRange = Math.max(10, radius * 4);
249
+ shadowCamera.left = -cameraRange;
250
+ shadowCamera.right = cameraRange;
251
+ shadowCamera.top = cameraRange;
252
+ shadowCamera.bottom = -cameraRange;
253
+ shadowCamera.near = 0.1;
254
+ shadowCamera.far = Math.max(50, radius * 8);
255
+ shadowCamera.updateProjectionMatrix();
256
+ scene.add(directional.target);
257
+ renderer.render(scene, camera);
258
+ if (typeof document !== "undefined") {
259
+ const captureCanvas = document.createElement("canvas");
260
+ captureCanvas.width = targetWidth;
261
+ captureCanvas.height = targetHeight;
262
+ const ctx = captureCanvas.getContext("2d");
263
+ if (!ctx) {
264
+ dataUrl = renderer.domElement.toDataURL("image/png");
265
+ } else {
266
+ ctx.clearRect(0, 0, targetWidth, targetHeight);
267
+ ctx.drawImage(renderer.domElement, 0, 0, targetWidth, targetHeight);
268
+ dataUrl = captureCanvas.toDataURL("image/png");
269
+ }
270
+ } else {
271
+ dataUrl = renderer.domElement.toDataURL("image/png");
271
272
  }
272
- finally {
273
- if (mixer) {
274
- mixer.stopAllAction();
275
- }
276
- scene.remove(root);
277
- scene.remove(ambient);
278
- scene.remove(directional);
279
- disposeScene();
280
- renderer.setSize(previousWidth || targetWidth, previousHeight || targetHeight, false);
281
- renderer.setPixelRatio(previousPixelRatio || 1);
282
- renderer.shadowMap.enabled = previousShadowEnabled;
283
- renderer.shadowMap.type = previousShadowType;
284
- renderer.shadowMap.autoUpdate = previousShadowAutoUpdate;
285
- renderer.setClearColor(clearColor, clearAlpha);
273
+ scene.remove(directional.target);
274
+ } finally {
275
+ if (mixer) {
276
+ mixer.stopAllAction();
286
277
  }
287
- return dataUrl;
278
+ scene.remove(root);
279
+ scene.remove(ambient);
280
+ scene.remove(directional);
281
+ disposeScene();
282
+ renderer.setSize(previousWidth || targetWidth, previousHeight || targetHeight, false);
283
+ renderer.setPixelRatio(previousPixelRatio || 1);
284
+ renderer.shadowMap.enabled = previousShadowEnabled;
285
+ renderer.shadowMap.type = previousShadowType;
286
+ renderer.shadowMap.autoUpdate = previousShadowAutoUpdate;
287
+ renderer.setClearColor(clearColor, clearAlpha);
288
+ }
289
+ return dataUrl;
288
290
  }
291
+ // Annotate the CommonJS export names for ESM import in node:
292
+ 0 && (module.exports = {
293
+ renderBoxelToDataURL
294
+ });
@@ -1,15 +1,64 @@
1
- export * from './types.js';
2
- export { createBoxelScene, createBoxelNodeScene } from './scene.js';
3
- export { attachBoxelOverlays } from './overlays.js';
4
- export * from './primitives.js';
5
- export * from './context.js';
6
- export * from './textures.js';
7
- export * from './builders.js';
8
- export * from './voxels/mesher.js';
9
- export * from './voxels/faces.js';
10
- export { exportModelToGLB, createBoxelSceneGraph } from './exporters/glb.js';
11
- export { renderBoxelToDataURL } from './exporters/image.js';
12
- export { __testing as __boxelThreeTesting } from './exporters/glb.js';
13
- export * from './texture-atlas.js';
14
- export * from './skinned-mesh.js';
15
- export * from './instantiate.js';
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+ var src_exports = {};
20
+ __export(src_exports, {
21
+ __boxelThreeTesting: () => import_glb2.__testing,
22
+ attachBoxelOverlays: () => import_overlays.attachBoxelOverlays,
23
+ createBoxelNodeScene: () => import_scene.createBoxelNodeScene,
24
+ createBoxelScene: () => import_scene.createBoxelScene,
25
+ createBoxelSceneGraph: () => import_glb.createBoxelSceneGraph,
26
+ exportModelToGLB: () => import_glb.exportModelToGLB,
27
+ renderBoxelToDataURL: () => import_image.renderBoxelToDataURL
28
+ });
29
+ module.exports = __toCommonJS(src_exports);
30
+ __reExport(src_exports, require("./types.js"), module.exports);
31
+ var import_scene = require("./scene.js");
32
+ var import_overlays = require("./overlays.js");
33
+ __reExport(src_exports, require("./primitives.js"), module.exports);
34
+ __reExport(src_exports, require("./context.js"), module.exports);
35
+ __reExport(src_exports, require("./textures.js"), module.exports);
36
+ __reExport(src_exports, require("./builders.js"), module.exports);
37
+ __reExport(src_exports, require("./voxels/mesher.js"), module.exports);
38
+ __reExport(src_exports, require("./voxels/faces.js"), module.exports);
39
+ var import_glb = require("./exporters/glb.js");
40
+ var import_image = require("./exporters/image.js");
41
+ var import_glb2 = require("./exporters/glb.js");
42
+ __reExport(src_exports, require("./texture-atlas.js"), module.exports);
43
+ __reExport(src_exports, require("./skinned-mesh.js"), module.exports);
44
+ __reExport(src_exports, require("./instantiate.js"), module.exports);
45
+ // Annotate the CommonJS export names for ESM import in node:
46
+ 0 && (module.exports = {
47
+ __boxelThreeTesting,
48
+ attachBoxelOverlays,
49
+ createBoxelNodeScene,
50
+ createBoxelScene,
51
+ createBoxelSceneGraph,
52
+ exportModelToGLB,
53
+ renderBoxelToDataURL,
54
+ ...require("./types.js"),
55
+ ...require("./primitives.js"),
56
+ ...require("./context.js"),
57
+ ...require("./textures.js"),
58
+ ...require("./builders.js"),
59
+ ...require("./voxels/mesher.js"),
60
+ ...require("./voxels/faces.js"),
61
+ ...require("./texture-atlas.js"),
62
+ ...require("./skinned-mesh.js"),
63
+ ...require("./instantiate.js")
64
+ });