@needle-tools/engine 4.13.1-beta → 4.13.1-next.9fc3e64

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 (111) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/components.needle.json +1 -1
  3. package/dist/gltf-progressive-CaUGGjVL.umd.cjs +10 -0
  4. package/dist/gltf-progressive-Dbi_Tfhb.js +1528 -0
  5. package/dist/gltf-progressive-DuAR0MQR.min.js +10 -0
  6. package/dist/{needle-engine.bundle-CGtsEhyJ.js → needle-engine.bundle-BZRE5G6O.js} +335 -312
  7. package/dist/{needle-engine.bundle-fbFZTOKP.umd.cjs → needle-engine.bundle-Dqrh7aWw.umd.cjs} +29 -29
  8. package/dist/{needle-engine.bundle-6774fXoY.min.js → needle-engine.bundle-DwybonUg.min.js} +47 -47
  9. package/dist/needle-engine.d.ts +446 -39
  10. package/dist/needle-engine.js +3 -3
  11. package/dist/needle-engine.min.js +1 -1
  12. package/dist/needle-engine.umd.cjs +1 -1
  13. package/lib/engine/engine_context.js +12 -2
  14. package/lib/engine/engine_context.js.map +1 -1
  15. package/lib/engine/engine_physics.d.ts +2 -0
  16. package/lib/engine/engine_physics.js +2 -0
  17. package/lib/engine/engine_physics.js.map +1 -1
  18. package/lib/engine/engine_physics_rapier.d.ts +2 -0
  19. package/lib/engine/engine_physics_rapier.js +2 -0
  20. package/lib/engine/engine_physics_rapier.js.map +1 -1
  21. package/lib/engine/engine_utils.d.ts +1 -0
  22. package/lib/engine/engine_utils.js +1 -0
  23. package/lib/engine/engine_utils.js.map +1 -1
  24. package/lib/engine/engine_utils_screenshot.d.ts +171 -14
  25. package/lib/engine/engine_utils_screenshot.js +65 -0
  26. package/lib/engine/engine_utils_screenshot.js.map +1 -1
  27. package/lib/engine/engine_utils_screenshot.xr.d.ts +1 -1
  28. package/lib/engine/engine_utils_screenshot.xr.js +1 -1
  29. package/lib/engine/extensions/NEEDLE_techniques_webgl.js +3 -0
  30. package/lib/engine/extensions/NEEDLE_techniques_webgl.js.map +1 -1
  31. package/lib/engine/xr/NeedleXRSession.d.ts +5 -0
  32. package/lib/engine/xr/NeedleXRSession.js +5 -0
  33. package/lib/engine/xr/NeedleXRSession.js.map +1 -1
  34. package/lib/engine-components/ContactShadows.d.ts +2 -0
  35. package/lib/engine-components/ContactShadows.js +2 -0
  36. package/lib/engine-components/ContactShadows.js.map +1 -1
  37. package/lib/engine-components/EventList.js +2 -2
  38. package/lib/engine-components/EventList.js.map +1 -1
  39. package/lib/engine-components/Renderer.d.ts +4 -3
  40. package/lib/engine-components/Renderer.js +4 -3
  41. package/lib/engine-components/Renderer.js.map +1 -1
  42. package/lib/engine-components/RigidBody.d.ts +57 -5
  43. package/lib/engine-components/RigidBody.js +57 -5
  44. package/lib/engine-components/RigidBody.js.map +1 -1
  45. package/lib/engine-components/ScreenCapture.d.ts +1 -0
  46. package/lib/engine-components/ScreenCapture.js +1 -0
  47. package/lib/engine-components/ScreenCapture.js.map +1 -1
  48. package/lib/engine-components/SeeThrough.d.ts +70 -5
  49. package/lib/engine-components/SeeThrough.js +70 -5
  50. package/lib/engine-components/SeeThrough.js.map +1 -1
  51. package/lib/engine-components/ShadowCatcher.d.ts +56 -4
  52. package/lib/engine-components/ShadowCatcher.js +56 -4
  53. package/lib/engine-components/ShadowCatcher.js.map +1 -1
  54. package/lib/engine-components/Skybox.d.ts +43 -7
  55. package/lib/engine-components/Skybox.js +43 -7
  56. package/lib/engine-components/Skybox.js.map +1 -1
  57. package/lib/engine-components/VideoPlayer.d.ts +1 -1
  58. package/lib/engine-components/VideoPlayer.js +7 -1
  59. package/lib/engine-components/VideoPlayer.js.map +1 -1
  60. package/lib/engine-components/timeline/PlayableDirector.d.ts +4 -0
  61. package/lib/engine-components/timeline/PlayableDirector.js +4 -0
  62. package/lib/engine-components/timeline/PlayableDirector.js.map +1 -1
  63. package/lib/engine-components/timeline/TimelineModels.d.ts +14 -0
  64. package/lib/engine-components/timeline/TimelineModels.js +4 -0
  65. package/lib/engine-components/timeline/TimelineModels.js.map +1 -1
  66. package/lib/engine-components/utils/OpenURL.d.ts +1 -0
  67. package/lib/engine-components/utils/OpenURL.js +1 -0
  68. package/lib/engine-components/utils/OpenURL.js.map +1 -1
  69. package/lib/engine-components/web/CursorFollow.d.ts +1 -0
  70. package/lib/engine-components/web/CursorFollow.js +1 -0
  71. package/lib/engine-components/web/CursorFollow.js.map +1 -1
  72. package/lib/engine-components/web/ScrollFollow.d.ts +1 -0
  73. package/lib/engine-components/web/ScrollFollow.js +1 -0
  74. package/lib/engine-components/web/ScrollFollow.js.map +1 -1
  75. package/lib/engine-components/webxr/WebARCameraBackground.d.ts +9 -0
  76. package/lib/engine-components/webxr/WebARCameraBackground.js +9 -0
  77. package/lib/engine-components/webxr/WebARCameraBackground.js.map +1 -1
  78. package/lib/engine-components/webxr/WebXR.d.ts +1 -0
  79. package/lib/engine-components/webxr/WebXR.js +1 -0
  80. package/lib/engine-components/webxr/WebXR.js.map +1 -1
  81. package/package.json +3 -3
  82. package/plugins/vite/build-pipeline.js +16 -2
  83. package/src/engine/engine_context.ts +17 -3
  84. package/src/engine/engine_physics.ts +4 -0
  85. package/src/engine/engine_physics_rapier.ts +8 -4
  86. package/src/engine/engine_utils.ts +1 -0
  87. package/src/engine/engine_utils_screenshot.ts +241 -17
  88. package/src/engine/engine_utils_screenshot.xr.ts +1 -1
  89. package/src/engine/extensions/NEEDLE_techniques_webgl.ts +3 -0
  90. package/src/engine/xr/NeedleXRSession.ts +5 -0
  91. package/src/engine-components/ContactShadows.ts +6 -1
  92. package/src/engine-components/EventList.ts +2 -2
  93. package/src/engine-components/Renderer.ts +14 -13
  94. package/src/engine-components/RigidBody.ts +64 -8
  95. package/src/engine-components/ScreenCapture.ts +1 -0
  96. package/src/engine-components/SeeThrough.ts +76 -9
  97. package/src/engine-components/ShadowCatcher.ts +61 -6
  98. package/src/engine-components/Skybox.ts +48 -12
  99. package/src/engine-components/VideoPlayer.ts +7 -1
  100. package/src/engine-components/timeline/PlayableDirector.ts +5 -1
  101. package/src/engine-components/timeline/SignalAsset.ts +1 -1
  102. package/src/engine-components/timeline/TimelineModels.ts +18 -2
  103. package/src/engine-components/utils/OpenURL.ts +1 -0
  104. package/src/engine-components/web/CursorFollow.ts +1 -0
  105. package/src/engine-components/web/ScrollFollow.ts +1 -0
  106. package/src/engine-components/webxr/WebARCameraBackground.ts +12 -3
  107. package/src/engine-components/webxr/WebXR.ts +1 -0
  108. package/dist/gltf-progressive-BURrJW0U.umd.cjs +0 -8
  109. package/dist/gltf-progressive-DHLDFNvQ.min.js +0 -8
  110. package/dist/gltf-progressive-eiJCrjLb.js +0 -1400
  111. package/src/include/three/DragControls.js +0 -232
@@ -32,6 +32,7 @@ declare type ScreenshotImageMimeType = "image/webp" | "image/png" | "image/jpeg"
32
32
  * const dataUrl = screenshot();
33
33
  * saveImage(dataUrl, "screenshot.png");
34
34
  * ```
35
+ *
35
36
  */
36
37
  export function screenshot(context?: Context, width?: number, height?: number, mimeType: ScreenshotImageMimeType = "image/webp", camera?: Camera | null): string | null {
37
38
  return screenshot2({ context, width, height, mimeType, camera });
@@ -106,12 +107,30 @@ export declare type ScreenshotOptionsBlob = ScreenshotOptions & {
106
107
  }
107
108
 
108
109
  export declare type ScreenshotOptionsShare = ScreenshotOptions & {
110
+ /**
111
+ * Set `{ type: "share" }` to share the screenshot using the Web Share API. The promise will resolve with the blob of the screenshot and whether it was shared successfully or not. Note that the Web Share API is only available in secure contexts (HTTPS) and on some platforms.
112
+ */
109
113
  type: "share",
114
+ /**
115
+ * The filename to use when sharing the screenshot. If not provided, a default filename will be used.
116
+ */
110
117
  filename?: string,
118
+ /**
119
+ * The mime type of the shared file. If not provided, the mime type will be inferred from the screenshot options or default to "image/png".
120
+ */
111
121
  file_type?: ScreenshotImageMimeType,
112
122
 
123
+ /**
124
+ * The title to use when sharing the screenshot. This is optional and may not be supported by all platforms.
125
+ */
113
126
  title?: string,
127
+ /**
128
+ * The text to use when sharing the screenshot. This is optional and may not be supported by all platforms.
129
+ */
114
130
  text?: string,
131
+ /**
132
+ * The URL to use when sharing the screenshot. This is optional and may not be supported by all platforms.
133
+ */
115
134
  url?: string,
116
135
  }
117
136
 
@@ -120,36 +139,241 @@ declare type ScreenshotOptionsShareReturnType = {
120
139
  shared: boolean,
121
140
  }
122
141
 
123
- /**
124
- * Take a screenshot from the current scene and return a {@link Texture}. This can applied to a surface in 3D space.
125
- * @param opts Provide `{ type: "texture" }` to get a texture instead of a data url.
142
+ /**
143
+ * Take a screenshot from the current scene and return a {@link Texture}. This can be applied to a surface in 3D space.
144
+ * @param opts Provide `{ type: "texture" }` to get a texture instead of a data url.
126
145
  * @returns The texture of the screenshot. Returns null if the screenshot could not be taken.
146
+ * @category Utilities
147
+ * @example
148
+ * ```ts
149
+ * // Create a texture from the current view
150
+ * const screenshotTexture = screenshot2({ type: "texture", width: 512, height: 512 });
151
+ * if (screenshotTexture) {
152
+ * myMaterial.map = screenshotTexture;
153
+ * myMaterial.needsUpdate = true;
154
+ * }
155
+ *
156
+ * // Update an existing texture
157
+ * const existingTexture = new Texture();
158
+ * screenshot2({ type: "texture", target: existingTexture, transparent: true });
159
+ * ```
127
160
  */
128
161
  export function screenshot2(opts: ScreenshotOptionsTexture): Texture | null;
162
+
129
163
  /**
130
- * Take a screenshot from the current scene.
131
- * @param opts
132
- * @returns The data url of the screenshot. Returns null if the screenshot could not be taken.
133
- * ```ts
134
- * const res = screenshot2({
135
- * width: 1024,
164
+ * Take a screenshot from the current scene and return a data URL string.
165
+ *
166
+ * @param opts Screenshot options. All properties are optional.
167
+ * @returns The data URL of the screenshot (e.g., "data:image/png;base64,..."). Returns null if the screenshot could not be taken.
168
+ * @category Utilities
169
+ *
170
+ * @example Basic screenshot
171
+ * ```ts
172
+ * // Take a simple screenshot with default settings
173
+ * const dataUrl = screenshot2({});
174
+ * console.log(dataUrl); // "data:image/webp;base64,..."
175
+ * ```
176
+ *
177
+ * @example High-resolution screenshot with transparent background
178
+ * ```ts
179
+ * const dataUrl = screenshot2({
180
+ * width: 2048,
181
+ * height: 2048,
182
+ * mimeType: "image/png",
183
+ * transparent: true,
184
+ * trim: true, // Remove transparent edges
185
+ * });
186
+ * ```
187
+ *
188
+ * @example Screenshot with custom background color
189
+ * ```ts
190
+ * import { Color } from "three";
191
+ *
192
+ * const dataUrl = screenshot2({
193
+ * width: 1024,
194
+ * height: 1024,
195
+ * background: new Color(0x00ff00), // Green background
196
+ * });
197
+ * ```
198
+ *
199
+ * @example Download screenshot automatically
200
+ * ```ts
201
+ * screenshot2({
202
+ * width: 1920,
203
+ * height: 1080,
204
+ * mimeType: "image/jpeg",
205
+ * download_filename: "my-scene.jpg",
206
+ * });
207
+ * ```
208
+ *
209
+ * @example Manual download using saveImage
210
+ * ```ts
211
+ * const dataUrl = screenshot2({
212
+ * width: 1024,
213
+ * height: 1024,
214
+ * mimeType: "image/webp",
215
+ * transparent: true,
216
+ * });
217
+ * if (dataUrl) {
218
+ * saveImage(dataUrl, "screenshot.webp");
219
+ * }
220
+ * ```
221
+ *
222
+ * @example Screenshot from specific camera
223
+ * ```ts
224
+ * const myCamera = this.gameObject.getComponent(Camera);
225
+ * const dataUrl = screenshot2({
226
+ * camera: myCamera,
227
+ * width: 1024,
136
228
  * height: 1024,
137
- * mimeType: "image/webp",
138
- * transparent: true,
139
- * })
140
- * // use saveImage to download the image
141
- * saveImage(res, "screenshot.webp");
229
+ * });
142
230
  * ```
143
231
  */
144
232
  export function screenshot2(opts: ScreenshotOptionsDataUrl): string | null;
145
233
 
146
234
  /**
147
- * Take a screenshot asynchronously from the current scene.
148
- * @returns A promise that resolves with the blob of the screenshot. Returns null if the screenshot could not be taken.
149
- * @param {ScreenshotOptionsBlob} opts Set `{ type: "blob" }` to get a blob instead of a data url.
235
+ * Take a screenshot asynchronously and return a Blob. This is useful when you need to process or upload the image data.
236
+ *
237
+ * @param opts Set `{ type: "blob" }` to get a blob instead of a data url. All other {@link ScreenshotOptions} are also available.
238
+ * @returns A Promise that resolves with the Blob of the screenshot. Returns null if the screenshot could not be taken.
239
+ * @category Utilities
240
+ *
241
+ * @example Upload screenshot to server
242
+ * ```ts
243
+ * const blob = await screenshot2({ type: "blob", mimeType: "image/png" });
244
+ * if (blob) {
245
+ * const formData = new FormData();
246
+ * formData.append("screenshot", blob, "screenshot.png");
247
+ * await fetch("/api/upload", { method: "POST", body: formData });
248
+ * }
249
+ * ```
250
+ *
251
+ * @example Save blob to file (browser download)
252
+ * ```ts
253
+ * const blob = await screenshot2({
254
+ * type: "blob",
255
+ * width: 1920,
256
+ * height: 1080,
257
+ * transparent: true
258
+ * });
259
+ * if (blob) {
260
+ * const url = URL.createObjectURL(blob);
261
+ * saveImage(url, "screenshot.png");
262
+ * URL.revokeObjectURL(url); // Clean up
263
+ * }
264
+ * ```
150
265
  */
151
266
  export function screenshot2(opts: ScreenshotOptionsBlob): Promise<Blob | null>;
267
+
268
+ /**
269
+ * Take a screenshot and share it using the Web Share API (mobile-friendly).
270
+ *
271
+ * **Note**: The Web Share API is only available in secure contexts (HTTPS) and may not be supported on all platforms/browsers.
272
+ *
273
+ * @param opts Set `{ type: "share" }` to share the screenshot. Additional options like `filename`, `title`, `text`, and `url` can be provided.
274
+ * @returns A Promise that resolves with an object containing the blob and whether it was successfully shared.
275
+ * @category Utilities
276
+ *
277
+ * @example Share screenshot on mobile
278
+ * ```ts
279
+ * const result = await screenshot2({
280
+ * type: "share",
281
+ * filename: "my-creation.png",
282
+ * title: "Check out my 3D scene!",
283
+ * text: "I created this with Needle Engine",
284
+ * url: "https://engine.needle.tools",
285
+ * mimeType: "image/png",
286
+ * });
287
+ *
288
+ * if (result.shared) {
289
+ * console.log("Screenshot shared successfully!");
290
+ * } else {
291
+ * console.log("User cancelled or sharing not supported");
292
+ * }
293
+ * ```
294
+ *
295
+ * @example Share with fallback
296
+ * ```ts
297
+ * const result = await screenshot2({
298
+ * type: "share",
299
+ * filename: "screenshot.webp",
300
+ * file_type: "image/webp",
301
+ * });
302
+ *
303
+ * if (!result.shared && result.blob) {
304
+ * // Fallback: download the image instead
305
+ * const url = URL.createObjectURL(result.blob);
306
+ * saveImage(url, "screenshot.webp");
307
+ * URL.revokeObjectURL(url);
308
+ * }
309
+ * ```
310
+ */
152
311
  export function screenshot2(opts: ScreenshotOptionsShare): Promise<ScreenshotOptionsShareReturnType>;
312
+
313
+ /**
314
+ * Take a screenshot from the current scene with advanced options.
315
+ *
316
+ * This is the main screenshot function in Needle Engine with support for multiple output formats:
317
+ * - **Data URL** (default): Returns a base64-encoded string suitable for img src attributes
318
+ * - **Texture**: Returns a Three.js Texture that can be applied to materials
319
+ * - **Blob**: Returns a Blob for uploading or processing (async)
320
+ * - **Share**: Uses the Web Share API to share the screenshot (async, mobile-friendly)
321
+ *
322
+ * @param opts Screenshot options. Use the `type` property to specify output format. See {@link ScreenshotOptions} for all available options.
323
+ * @returns Depending on the `type` option:
324
+ * - Data URL (string) when `type` is undefined or not specified
325
+ * - Texture when `type: "texture"`
326
+ * - Promise<Blob | null> when `type: "blob"`
327
+ * - Promise<{blob, shared}> when `type: "share"`
328
+ *
329
+ * Returns null (or Promise resolving to null) if the screenshot could not be taken.
330
+ *
331
+ * @category Utilities
332
+ *
333
+ * @example WebXR / AR Screenshots
334
+ * ```ts
335
+ * // Screenshots work automatically in WebXR sessions
336
+ * // The camera feed will be composited with your 3D content
337
+ * const dataUrl = screenshot2({
338
+ * width: 1920,
339
+ * height: 1080
340
+ * });
341
+ * ```
342
+ *
343
+ * **Note for AR Screenshots**: To include the device camera feed in AR screenshots, you need to request camera access.
344
+ * This is done automatically when you use {@link WebARCameraBackground} component in your scene.
345
+ * If you're not using WebARCameraBackground, you can request camera access manually:
346
+ * ```ts
347
+ * export class MyComponent extends Behaviour {
348
+ * onBeforeXR(mode: XRSessionMode, args: XRSessionInit): void {
349
+ * if (mode === "immersive-ar") {
350
+ * args.optionalFeatures = args.optionalFeatures || [];
351
+ * args.optionalFeatures.push('camera-access');
352
+ * }
353
+ * }
354
+ * }
355
+ * ```
356
+ * Without camera access, AR screenshots will only show your 3D content without the real-world background.
357
+ *
358
+ * @example Combining multiple options
359
+ * ```ts
360
+ * // High-res transparent screenshot with custom camera
361
+ * const myCamera = this.gameObject.getComponent(Camera);
362
+ * const texture = screenshot2({
363
+ * type: "texture",
364
+ * camera: myCamera,
365
+ * width: 2048,
366
+ * height: 2048,
367
+ * transparent: true,
368
+ * trim: true,
369
+ * render_events: true, // Ensure reflection probes are updated
370
+ * });
371
+ * ```
372
+ *
373
+ * @see {@link screenshot} for a simpler alternative with fewer options
374
+ * @see {@link saveImage} for downloading data URLs
375
+ * @see {@link ScreenshotOptions} for all available options
376
+ */
153
377
  export function screenshot2(opts: ScreenshotOptionsDataUrl | ScreenshotOptionsTexture | ScreenshotOptionsBlob | ScreenshotOptionsShare)
154
378
  : Texture | string | null | Promise<Blob | null> | Promise<ScreenshotOptionsShareReturnType> {
155
379
 
@@ -5,7 +5,7 @@ import { isDevEnvironment, showBalloonError } from "./debug/index.js";
5
5
  // Adapted from WebARCameraBackground
6
6
 
7
7
  /**
8
- * Assigns the camera feed to a texture - this must be called during the render loop
8
+ * Assigns the camera feed to a texture - this must be called during the render loop.
9
9
  */
10
10
  export function updateTextureFromXRFrame(renderer: WebGLRenderer, target: Texture): boolean {
11
11
 
@@ -621,6 +621,9 @@ function createUniformProperties(material: CustomShader) {
621
621
  case "_Color":
622
622
  defineProperty("color", key);
623
623
  break;
624
+ case "_map":
625
+ defineProperty("map", key);
626
+ break;
624
627
  // case "_Metallic":
625
628
  // defineProperty("metalness", key);
626
629
  // break;
@@ -279,7 +279,12 @@ const $initialFov = Symbol("initial-fov");
279
279
  * The XRRig can be accessed via the `rig` property
280
280
  * Set a custom XRRig via `NeedleXRSession.addRig(...)` or `NeedleXRSession.removeRig(...)`
281
281
  * By default the active XRRig with the highest priority in the scene is used
282
+ *
283
+ * ### Screenshots in XR
284
+ * Screenshots work automatically during XR sessions, including AR camera feed compositing. See {@link screenshot2} for more information.
285
+ *
282
286
  * @category XR
287
+ * @see {@link screenshot2} for taking screenshots in XR sessions
283
288
  */
284
289
  export class NeedleXRSession implements INeedleXRSession {
285
290
 
@@ -13,6 +13,9 @@ import { HideFlags, IGameObject, Vec3 } from "../engine/engine_types.js";
13
13
  import { getParam } from "../engine/engine_utils.js"
14
14
  import { setCustomVisibility } from "../engine/js-extensions/Layers.js";
15
15
  import { Behaviour, GameObject } from "./Component.js";
16
+ import type { Light } from "./Light.js";
17
+ import type { Renderer } from "./Renderer.js";
18
+ import type { ShadowCatcher } from "./ShadowCatcher.js";
16
19
 
17
20
  const debug = getParam("debugcontactshadows");
18
21
 
@@ -45,7 +48,8 @@ type FitParameters = {
45
48
 
46
49
  /**
47
50
  * [ContactShadows](https://engine.needle.tools/docs/api/ContactShadows) renders proximity-based soft shadows on flat surfaces.
48
- * Ideal for products or objects that need visual grounding without real-time shadows.
51
+ * Ideal for products or objects that need visual grounding without real-time shadows.
52
+ * Produces soft, blurred shadows that hug the ground, giving a sense of contact and depth.
49
53
  *
50
54
  * ![](https://cloud.needle.tools/-/media/87bPTNXHcsbV-An-oSEvHQ.gif)
51
55
  *
@@ -72,6 +76,7 @@ type FitParameters = {
72
76
  * @summary Display contact shadows on the ground
73
77
  * @category Rendering
74
78
  * @group Components
79
+ * @see {@link ShadowCatcher} for real-time shadows from lights (more accurate, higher performance cost)
75
80
  * @see {@link Light} for real-time shadow casting
76
81
  * @see {@link Renderer} for material/rendering control
77
82
  * @link https://engine.needle.tools/samples/contact-shadows for a demo of contact shadows
@@ -175,10 +175,10 @@ export class EventList<TArgs extends any = any> implements IEventList {
175
175
  // remap the arguments to the new instance (e.g. if an object is passed as an argument to the event list and this object has been cloned we want to remap it to the clone)
176
176
  const newArguments = method.arguments?.map(arg => {
177
177
  if (arg instanceof Object && arg.uuid) {
178
- return ctx[arg.uuid];
178
+ return ctx[arg.uuid].clone;
179
179
  }
180
180
  else if ((arg as IComponent)?.isComponent) {
181
- return ctx[(arg as IComponent).guid];
181
+ return ctx[(arg as IComponent).guid].clone;
182
182
  }
183
183
  return arg;
184
184
  });
@@ -200,22 +200,24 @@ class SharedMaterialArray implements ISharedMaterials {
200
200
  }
201
201
 
202
202
  /**
203
- * [Renderer](https://engine.needle.tools/docs/api/Renderer) controls rendering properties of meshes including materials,
204
- * lightmaps, reflection probes, and GPU instancing.
203
+ * The [Renderer](https://engine.needle.tools/docs/api/Renderer) component controls rendering properties of meshes including materials,
204
+ * lightmaps, reflection probes, and GPU instancing.
205
205
  *
206
- * **Materials:**
207
- * Access materials via `sharedMaterials` array. Changes affect all instances.
208
- * Use material cloning for per-instance variations.
206
+ * **Materials:**
207
+ * Access materials via `sharedMaterials` array. Changes affect all instances.
208
+ * Use material cloning for per-instance variations.
209
209
  *
210
- * **Instancing:**
211
- * Enable GPU instancing for improved performance with many identical objects.
212
- * Use `Renderer.setInstanced(obj, true)` or `enableInstancing` property.
210
+ * **Instancing:**
211
+ * Enable GPU instancing for improved performance with many identical objects.
212
+ * Use `Renderer.setInstanced(obj, true)` or `enableInstancing` property.
213
213
  *
214
- * **Lightmaps:**
215
- * Baked lighting is automatically applied when exported from Unity.
216
- * Access via the associated {@link RendererLightmap} component.
214
+ * **Lightmaps:**
215
+ * Baked lighting is automatically applied when exported from Unity or Blender.
216
+ * Access via the associated {@link RendererLightmap} component.
217
+ *
218
+ * [![](https://cloud.needle.tools/-/media/Vk944XVswtPEuxlNPLMxPQ.gif)](https://engine.needle.tools/samples/multiple-lightmaps/)
217
219
  *
218
- * **Debug options:**
220
+ * **Debug options:**
219
221
  * - `?debugrenderer` - Log renderer info
220
222
  * - `?wireframe` - Show wireframe rendering
221
223
  * - `?noinstancing` - Disable GPU instancing
@@ -235,7 +237,6 @@ class SharedMaterialArray implements ISharedMaterials {
235
237
  * @group Components
236
238
  * @see {@link ReflectionProbe} for environment reflections
237
239
  * @see {@link Light} for scene lighting
238
- * @see {@link LODGroup} for level of detail
239
240
  */
240
241
  export class Renderer extends Behaviour implements IRenderer {
241
242
 
@@ -2,14 +2,18 @@ import { Matrix4, Object3D, Quaternion, Vector3, Vector3Like } from "three";
2
2
 
3
3
  import { isDevEnvironment } from "../engine/debug/index.js";
4
4
  import { MODULES } from "../engine/engine_modules.js";
5
+ import type { Physics } from "../engine/engine_physics.js";
5
6
  import { CollisionDetectionMode, RigidbodyConstraints } from "../engine/engine_physics.types.js";
7
+ import type { RapierPhysics } from "../engine/engine_physics_rapier.js";
6
8
  import { serializable } from "../engine/engine_serialization_decorator.js";
7
9
  import { Context, FrameEvent } from "../engine/engine_setup.js";
8
- import { getWorldPosition } from "../engine/engine_three_utils.js";
9
10
  import type { IRigidbody, Vec3 } from "../engine/engine_types.js";
10
11
  import { validate } from "../engine/engine_util_decorator.js";
11
12
  import { delayForFrames, Watch } from "../engine/engine_utils.js";
13
+ import type { CharacterController } from "./CharacterController.js";
14
+ import type { BoxCollider, CapsuleCollider, Collider,MeshCollider, SphereCollider } from "./Collider.js";
12
15
  import { Behaviour } from "./Component.js";
16
+ import type { Joint } from "./Joints.js";
13
17
 
14
18
  class TransformWatch {
15
19
 
@@ -134,15 +138,67 @@ class TransformWatch {
134
138
  }
135
139
 
136
140
  /**
137
- * A Rigidbody is used together with a Collider to create physical interactions between objects in the scene.
141
+ * Rigidbody component for realistic physics simulation and dynamic interactions.
142
+ * Used together with a {@link Collider} to enable physical behavior like gravity, collisions,
143
+ * forces, and constraints. Powered by the Rapier physics engine.
138
144
  *
139
- * - Example: https://samples.needle.tools/physics-basic
140
- * - Example: https://samples.needle.tools/physics-playground
141
- * - Example: https://samples.needle.tools/physics-&-animation
142
- *
143
- * @summary Rigidbody for physical interactions
144
- * @category Physics
145
+ * ![](https://cloud.needle.tools/-/media/slYWnXyaxdlrCqu8GP_lFQ.gif)
146
+ *
147
+ * **Key features:**
148
+ * - Dynamic, kinematic, or static body types
149
+ * - Automatic or manual mass calculation
150
+ * - Gravity, drag, and angular drag control
151
+ * - Position and rotation constraints (locking axes)
152
+ * - Force, impulse, and velocity manipulation
153
+ * - Sleep/wake optimization for performance
154
+ * - Continuous collision detection (CCD) support
155
+ *
156
+ * @example Basic dynamic rigidbody
157
+ * ```ts
158
+ * const rb = this.gameObject.getComponent(Rigidbody);
159
+ * rb.useGravity = true;
160
+ * rb.mass = 2.0;
161
+ * rb.drag = 0.5;
162
+ * ```
163
+ *
164
+ * @example Apply force to move object
165
+ * ```ts
166
+ * const rb = this.gameObject.getComponent(Rigidbody);
167
+ * rb.applyForce(new Vector3(0, 10, 0)); // Upward force
168
+ * rb.applyImpulse(new Vector3(5, 0, 0)); // Instant velocity change
169
+ * ```
170
+ *
171
+ * @example Kinematic rigidbody (manually controlled)
172
+ * ```ts
173
+ * const rb = this.gameObject.getComponent(Rigidbody);
174
+ * rb.isKinematic = true; // Not affected by forces
175
+ * rb.teleport({ x: 0, y: 5, z: 0 }); // Move without physics
176
+ * ```
177
+ *
178
+ * @example Lock rotation on Y axis (useful for characters)
179
+ * ```ts
180
+ * const rb = this.gameObject.getComponent(Rigidbody);
181
+ * rb.lockRotationY = true;
182
+ * // Or use constraints for multiple axes:
183
+ * rb.constraints = RigidbodyConstraints.FreezeRotationY | RigidbodyConstraints.FreezePositionZ;
184
+ * ```
185
+ *
186
+ * @summary Enables physics simulation with forces, gravity, and collisions
187
+ * @category Physics
145
188
  * @group Components
189
+ * @see {@link BoxCollider} for box-shaped colliders
190
+ * @see {@link SphereCollider} for sphere-shaped colliders
191
+ * @see {@link CapsuleCollider} for capsule-shaped colliders
192
+ * @see {@link MeshCollider} for mesh-based colliders
193
+ * @see {@link Collider} for collider base class
194
+ * @see {@link CharacterController} for character movement
195
+ * @see {@link Joint} for connecting bodies
196
+ * @see {@link RapierPhysics} for physics engine implementation
197
+ * @see {@link Physics} for raycasting and physics utilities
198
+ * @link https://engine.needle.tools/samples/physics-basic/
199
+ * @link https://engine.needle.tools/samples/physics-playground/
200
+ * @link https://engine.needle.tools/samples/physics-&-animation/
201
+ * @link https://rapier.rs/docs/user_guides/javascript/rigid_bodies
146
202
  */
147
203
  export class Rigidbody extends Behaviour implements IRigidbody {
148
204
 
@@ -100,6 +100,7 @@ export declare type ScreenCaptureOptions = {
100
100
  *
101
101
  * @summary Share screen, camera or microphone in a networked room
102
102
  * @category Networking
103
+ * @category Multimedia
103
104
  * @group Components
104
105
  * @see {@link VideoPlayer} for displaying the received stream
105
106
  * @see {@link Voip} for voice-only communication
@@ -6,9 +6,11 @@ import { serializable } from "../engine/engine_serialization_decorator.js";
6
6
  import { getTempVector } from "../engine/engine_three_utils.js";
7
7
  import { getParam } from "../engine/engine_utils.js";
8
8
  import { USDObject, USDZExporterContext } from "./api.js";
9
+ import type { Camera } from "./Camera.js";
9
10
  import { Behaviour } from "./Component.js";
10
11
  import { IUSDExporterExtension } from "./export/usdz/Extension.js";
11
12
  import { USDZExporter } from "./export/usdz/USDZExporter.js";
13
+ import type { OrbitControls } from "./OrbitControls.js";
12
14
  import { Renderer } from "./Renderer.js";
13
15
 
14
16
  const debugSeeThrough = getParam("debugseethrough");
@@ -32,17 +34,82 @@ let i = 0;
32
34
 
33
35
 
34
36
  /**
35
- * Makes the object fade out when it is obscuring the reference point from the camera. This component can be put on any object in the scene. It will affect all Renderer components on the same object and child objects.
36
- *
37
- * Useful for e.g. making walls transparent when the camera is outside or hiding object's that would otherwise block the view.
38
- *
39
- * Requires a Renderer component on the same object or a child object.
40
- *
41
- * - Example https://see-through-walls-z23hmxbz1kjfjn.needle.run/
42
- *
43
- * @summary Makes objects fade out when obscuring a reference point from the camera
37
+ * Automatically fades objects to transparent when they obscure a reference point from the camera's view.
38
+ * Perfect for architectural visualization, third-person games, or any scenario where objects should
39
+ * become see-through when blocking the view of important content.
40
+ *
41
+ * [![](https://cloud.needle.tools/-/media/1gbMOJLgTlXOug_g6xeKfg.gif)](https://engine.needle.tools/samples/see-through)
42
+ *
43
+ * **How it works:**
44
+ * - Monitors the angle between the camera, this object, and a reference point
45
+ * - When the object blocks the view to the reference point, it fades out
46
+ * - Automatically affects all {@link Renderer} components on this object and children
47
+ * - Supports both transparent fading and alpha hash (dithered) fading
48
+ *
49
+ * **Key Features:**
50
+ * - Smooth fade transitions with configurable duration
51
+ * - Optional alpha hash for maintaining opaque rendering (better performance)
52
+ * - Automatic or manual update modes
53
+ * - Disables raycasting when faded (objects become click-through)
54
+ * - Preserves original material properties when re-enabled
55
+ *
56
+ * **Configuration:**
57
+ * - `referencePoint` - Object to keep visible (defaults to scene root)
58
+ * - `fadeDuration` - Transition speed (default: 0.05 seconds)
59
+ * - `minAlpha` - Minimum opacity when faded (default: 0 = fully transparent)
60
+ * - `useAlphaHash` - Use dithered transparency instead of true transparency (default: true)
61
+ *
62
+ * **Performance:**
63
+ * - Materials are cloned once per renderer to avoid affecting shared materials
64
+ * - Updates direction calculation every 20 frames by default (configurable via `autoUpdate`)
65
+ * - Use `needsUpdate = true` to force immediate recalculation
66
+ *
67
+ * **Requirements:**
68
+ * Requires at least one {@link Renderer} component on the same object or child objects.
69
+ *
70
+ * @example Make walls transparent when blocking view
71
+ * ```ts
72
+ * // Add to walls or obstacles
73
+ * const seeThrough = wall.addComponent(SeeThrough);
74
+ * seeThrough.referencePoint = player; // Keep player visible
75
+ * seeThrough.fadeDuration = 0.2; // Smooth fade
76
+ * seeThrough.minAlpha = 0.2; // Slightly visible when faded
77
+ * ```
78
+ *
79
+ * @example Third-person camera with see-through objects
80
+ * ```ts
81
+ * const character = GameObject.findByName("Character");
82
+ * const obstacles = GameObject.findByTag("Obstacle");
83
+ *
84
+ * for (const obstacle of obstacles) {
85
+ * const st = obstacle.addComponent(SeeThrough);
86
+ * st.referencePoint = character;
87
+ * st.useAlphaHash = true; // Better performance
88
+ * }
89
+ * ```
90
+ *
91
+ * @example Manual control of see-through effect
92
+ * ```ts
93
+ * const seeThrough = this.gameObject.getComponent(SeeThrough);
94
+ * if (seeThrough) {
95
+ * seeThrough.autoUpdate = false; // Disable automatic fading
96
+ *
97
+ * // Manually control transparency
98
+ * seeThrough.updateAlpha(0.5, 0.3); // Fade to 50% over 0.3 seconds
99
+ *
100
+ * // Or use override for precise control
101
+ * seeThrough.overrideAlpha = 0.8; // Force 80% opacity
102
+ * }
103
+ * ```
104
+ *
105
+ * @summary Fades objects when they obscure the camera's view of a reference point
44
106
  * @category Rendering
45
107
  * @group Components
108
+ * @see {@link Renderer} for material/rendering control (required)
109
+ * @see {@link Camera} for camera setup and configuration
110
+ * @see {@link OrbitControls} for camera controls in similar use cases
111
+ * @link https://see-through-walls-z23hmxbz1kjfjn.needle.run/ for live demo
112
+ * @link https://engine.needle.tools/samples/see-through for sample project
46
113
  */
47
114
  export class SeeThrough extends Behaviour {
48
115