@needle-tools/engine 2.67.12-pre → 2.67.14-pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +17 -0
- package/dist/needle-engine.js +5104 -5041
- package/dist/needle-engine.min.js +4812 -0
- package/dist/needle-engine.umd.cjs +278 -278
- package/lib/engine/engine_input.js +5 -2
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +5 -0
- package/lib/engine/engine_physics.js +39 -4
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_types.d.ts +1 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine/engine_utils.js +4 -8
- package/lib/engine/engine_utils.js.map +1 -1
- package/lib/engine-components/Animation.d.ts +1 -1
- package/lib/engine-components/Animation.js +3 -3
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/CharacterController.js +2 -2
- package/lib/engine-components/CharacterController.js.map +1 -1
- package/lib/engine-components/Renderer.d.ts +1 -1
- package/lib/engine-components/Renderer.js +15 -4
- package/lib/engine-components/Renderer.js.map +1 -1
- package/lib/engine-components/WebXR.js +12 -2
- package/lib/engine-components/WebXR.js.map +1 -1
- package/lib/engine-components/WebXRController.js +1 -1
- package/lib/engine-components/WebXRController.js.map +1 -1
- package/lib/engine-components/api.d.ts +1 -0
- package/lib/engine-components/api.js +2 -0
- package/lib/engine-components/api.js.map +1 -0
- package/lib/needle-engine.d.ts +1 -0
- package/lib/needle-engine.js +1 -0
- package/lib/needle-engine.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +3 -4
- package/plugins/vite/copyfiles.js +37 -10
- package/plugins/vite/reload.js +2 -1
- package/src/engine/codegen/register_types.js +2 -2
- package/src/engine/engine_input.ts +4 -2
- package/src/engine/engine_physics.ts +41 -4
- package/src/engine/engine_types.ts +1 -0
- package/src/engine/engine_utils.ts +4 -8
- package/src/engine-components/Animation.ts +3 -3
- package/src/engine-components/CharacterController.ts +2 -2
- package/src/engine-components/Renderer.ts +19 -5
- package/src/engine-components/WebXR.ts +12 -3
- package/src/engine-components/WebXRController.ts +1 -1
- package/src/engine-components/api.ts +1 -0
- package/src/needle-engine.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@needle-tools/engine",
|
|
3
|
-
"version": "2.67.
|
|
3
|
+
"version": "2.67.14-pre",
|
|
4
4
|
"description": "Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development, and can be deployed anywhere. It is flexible, extensible, and collaboration and XR come naturally.",
|
|
5
5
|
"main": "dist/needle-engine.umd.cjs",
|
|
6
6
|
"module": "lib/needle-engine.js",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"flatbuffers": "2.0.4",
|
|
60
60
|
"md5": "^2.3.0",
|
|
61
61
|
"peerjs": "1.3.2",
|
|
62
|
-
"simplex-noise": "^4.0.1",
|
|
63
62
|
"postprocessing": "^6.30.1",
|
|
63
|
+
"simplex-noise": "^4.0.1",
|
|
64
64
|
"stats.js": "^0.17.0",
|
|
65
65
|
"three": "npm:@needle-tools/three@^0.146.7",
|
|
66
66
|
"three-mesh-ui": "^6.4.5",
|
|
@@ -75,10 +75,9 @@
|
|
|
75
75
|
"@needle-tools/helper": "^0.4.5",
|
|
76
76
|
"@needle-tools/needle-component-compiler": "1.9.3",
|
|
77
77
|
"@types/three": "0.146.0",
|
|
78
|
-
"copy-files-from-to": "^3.7.0",
|
|
79
78
|
"esbuild": "^0.15.10",
|
|
80
79
|
"esbuild-node-externals": "^1.5.0",
|
|
81
|
-
"fs-extra": "^11.1.
|
|
80
|
+
"fs-extra": "^11.1.1",
|
|
82
81
|
"jsdoc-babel": "^0.5.0",
|
|
83
82
|
"jsdoc-to-markdown": "^7.1.1",
|
|
84
83
|
"madge": "^5.0.1",
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { existsSync } from 'fs';
|
|
2
|
+
import { resolve, join } from 'path'
|
|
3
|
+
import { existsSync, statSync, mkdirSync, readdirSync, copyFileSync, mkdir } from 'fs';
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
/** copy files on build from assets to dist */
|
|
@@ -11,32 +10,60 @@ export const needleCopyFiles = (command, config, userSettings) => {
|
|
|
11
10
|
return;
|
|
12
11
|
}
|
|
13
12
|
|
|
13
|
+
const copyIncludesFromEngine = config?.copyIncludesFromEngine ?? true;
|
|
14
|
+
|
|
14
15
|
return {
|
|
15
16
|
name: 'needle-copy-files',
|
|
16
17
|
apply: 'build',
|
|
17
18
|
async closeBundle() {
|
|
18
19
|
const baseDir = process.cwd();
|
|
20
|
+
const pluginName = "needle-copy-files";
|
|
19
21
|
|
|
20
22
|
const outdirName = "dist";
|
|
21
23
|
const outDir = resolve(baseDir, outdirName);
|
|
22
24
|
if (!existsSync(outDir)) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
+
mkdirSync(outDir);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
if (copyIncludesFromEngine !== false) {
|
|
29
|
+
// copy include from engine
|
|
30
|
+
const engineIncludeDir = resolve(baseDir, 'node_modules', '@needle-tools', 'engine', 'src', 'include');
|
|
31
|
+
if (existsSync(engineIncludeDir)) {
|
|
32
|
+
console.log(`[${pluginName}] - Copy engine include to ${baseDir}/include`)
|
|
33
|
+
const targetDir = resolve(baseDir, 'include');
|
|
34
|
+
copyRecursiveSync(engineIncludeDir, targetDir);
|
|
35
|
+
}
|
|
25
36
|
}
|
|
37
|
+
|
|
26
38
|
// copy assets dir
|
|
27
39
|
const assetsDir = resolve(baseDir, 'assets');
|
|
28
40
|
if (existsSync(assetsDir)) {
|
|
29
|
-
console.log(`Copy assets to ${outdirName}/assets`)
|
|
41
|
+
console.log(`[${pluginName}] - Copy assets to ${outdirName}/assets`)
|
|
30
42
|
const targetDir = resolve(outDir, 'assets');
|
|
31
|
-
|
|
43
|
+
copyRecursiveSync(assetsDir, targetDir);
|
|
32
44
|
}
|
|
33
45
|
// copy include dir
|
|
34
46
|
const includeDir = resolve(baseDir, 'include');
|
|
35
47
|
if (existsSync(includeDir)) {
|
|
36
|
-
console.log(`Copy include to ${outdirName}/include`)
|
|
48
|
+
console.log(`[${pluginName}] - Copy include to ${outdirName}/include`)
|
|
37
49
|
const targetDir = resolve(outDir, 'include');
|
|
38
|
-
|
|
50
|
+
copyRecursiveSync(includeDir, targetDir);
|
|
39
51
|
}
|
|
40
52
|
}
|
|
41
53
|
}
|
|
42
|
-
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function copyRecursiveSync(src, dest) {
|
|
57
|
+
var exists = existsSync(src);
|
|
58
|
+
var stats = exists && statSync(src);
|
|
59
|
+
var isDirectory = exists && stats.isDirectory();
|
|
60
|
+
if (isDirectory) {
|
|
61
|
+
if (!existsSync(dest))
|
|
62
|
+
mkdirSync(dest);
|
|
63
|
+
readdirSync(src).forEach(function (childItemName) {
|
|
64
|
+
copyRecursiveSync(join(src, childItemName), join(dest, childItemName));
|
|
65
|
+
});
|
|
66
|
+
} else {
|
|
67
|
+
copyFileSync(src, dest);
|
|
68
|
+
}
|
|
69
|
+
};
|
package/plugins/vite/reload.js
CHANGED
|
@@ -43,7 +43,8 @@ export const needleReload = (command, config, userSettings) => {
|
|
|
43
43
|
else if (!config.server.watch.ignored) config.server.watch.ignored = [];
|
|
44
44
|
for (const pattern of ignorePatterns)
|
|
45
45
|
config.server.watch.ignored.push(pattern);
|
|
46
|
-
|
|
46
|
+
if(config?.debug === true || userSettings?.debug === true)
|
|
47
|
+
setTimeout(() => console.log("Updated server ignore patterns: ", config.server.watch.ignored), 100);
|
|
47
48
|
},
|
|
48
49
|
handleHotUpdate(args) {
|
|
49
50
|
args.buildDirectory = buildDirectory;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { TypeStore } from "./../engine_typestore"
|
|
2
|
-
|
|
2
|
+
|
|
3
3
|
// Import types
|
|
4
4
|
import { __Ignore } from "../../engine-components/codegen/components";
|
|
5
5
|
import { AlignmentConstraint } from "../../engine-components/AlignmentConstraint";
|
|
@@ -179,7 +179,7 @@ import { XRGrabModel } from "../../engine-components/WebXRGrabRendering";
|
|
|
179
179
|
import { XRGrabRendering } from "../../engine-components/WebXRGrabRendering";
|
|
180
180
|
import { XRRig } from "../../engine-components/WebXRRig";
|
|
181
181
|
import { XRState } from "../../engine-components/XRFlag";
|
|
182
|
-
|
|
182
|
+
|
|
183
183
|
// Register types
|
|
184
184
|
TypeStore.add("__Ignore", __Ignore);
|
|
185
185
|
TypeStore.add("AlignmentConstraint", AlignmentConstraint);
|
|
@@ -478,6 +478,8 @@ export class Input extends EventTarget {
|
|
|
478
478
|
|
|
479
479
|
while (evt.button >= this._pointerPositionDown.length) this._pointerPositionDown.push(new THREE.Vector2());
|
|
480
480
|
this._pointerPositionDown[evt.button].set(evt.clientX, evt.clientY);
|
|
481
|
+
while (evt.button >= this._pointerPositions.length) this._pointerPositions.push(new THREE.Vector2());
|
|
482
|
+
this._pointerPositions[evt.button].set(evt.clientX, evt.clientY);
|
|
481
483
|
|
|
482
484
|
if (evt.button >= this._pointerDownTime.length) this._pointerDownTime.push(0);
|
|
483
485
|
this._pointerDownTime[evt.button] = this.context.time.time;
|
|
@@ -552,8 +554,8 @@ export class Input extends EventTarget {
|
|
|
552
554
|
|
|
553
555
|
const lf = this._pointerPositionsLastFrame[evt.button];
|
|
554
556
|
lf.copy(this._pointerPositions[evt.button]);
|
|
555
|
-
const dx = evt.
|
|
556
|
-
const dy = evt.
|
|
557
|
+
const dx = evt.clientX - lf.x;
|
|
558
|
+
const dy = evt.clientY - lf.y;
|
|
557
559
|
this._pointerPositionsDelta[evt.button].set(dx, dy);
|
|
558
560
|
|
|
559
561
|
this._pointerPositions[evt.button].x = evt.clientX;
|
|
@@ -263,7 +263,10 @@ export class Physics {
|
|
|
263
263
|
const ray = this.getPhysicsRay(this.rapierRay, origin, direction);
|
|
264
264
|
if (!ray) return null;
|
|
265
265
|
|
|
266
|
-
const hit = this.world?.castRay(ray, maxDistance, solid)
|
|
266
|
+
const hit = this.world?.castRay(ray, maxDistance, solid, undefined, undefined, undefined, undefined, (c) => {
|
|
267
|
+
// ignore objects in the IgnoreRaycast=2 layer
|
|
268
|
+
return !c[$componentKey]?.gameObject.layers.isEnabled(2);
|
|
269
|
+
});
|
|
267
270
|
if (hit) {
|
|
268
271
|
const point = ray.pointAt(hit.toi);
|
|
269
272
|
const vec = this.raycastVectorsBuffer.get();
|
|
@@ -274,6 +277,28 @@ export class Physics {
|
|
|
274
277
|
return null;
|
|
275
278
|
}
|
|
276
279
|
|
|
280
|
+
public raycastPhysicsFastAndGetNormal(origin: Vec2 | Vec3, direction: Vec3 | undefined = undefined, maxDistance: number = Infinity, solid: boolean = true)
|
|
281
|
+
: null | { point: Vector3, normal: Vector3, collider: ICollider } {
|
|
282
|
+
|
|
283
|
+
const ray = this.getPhysicsRay(this.rapierRay, origin, direction);
|
|
284
|
+
if (!ray) return null;
|
|
285
|
+
|
|
286
|
+
const hit = this.world?.castRayAndGetNormal(ray, maxDistance, solid, undefined, undefined, undefined, undefined, (c) => {
|
|
287
|
+
// ignore objects in the IgnoreRaycast=2 layer
|
|
288
|
+
return !c[$componentKey]?.gameObject.layers.isEnabled(2);
|
|
289
|
+
});
|
|
290
|
+
if (hit) {
|
|
291
|
+
const point = ray.pointAt(hit.toi);
|
|
292
|
+
const normal = hit.normal;
|
|
293
|
+
const vec = this.raycastVectorsBuffer.get();
|
|
294
|
+
const nor = this.raycastVectorsBuffer.get();
|
|
295
|
+
vec.set(point.x, point.y, point.z);
|
|
296
|
+
nor.set(normal.x, normal.y, normal.z);
|
|
297
|
+
return { point: vec, normal: nor, collider: hit.collider[$componentKey] };
|
|
298
|
+
}
|
|
299
|
+
return null;
|
|
300
|
+
}
|
|
301
|
+
|
|
277
302
|
private getPhysicsRay(ray: RAPIER.Ray, origin: Vec2 | Vec3, direction: Vec3 | undefined = undefined): RAPIER.Ray | null {
|
|
278
303
|
const cam = this.context.mainCamera;
|
|
279
304
|
// if we get origin in 2d space we need to project it to 3d space
|
|
@@ -283,11 +308,13 @@ export class Physics {
|
|
|
283
308
|
return null;
|
|
284
309
|
}
|
|
285
310
|
const vec3 = this.raycastVectorsBuffer.get();
|
|
311
|
+
vec3.x = origin.x;
|
|
312
|
+
vec3.y = origin.y;
|
|
313
|
+
vec3.z = 0;
|
|
286
314
|
// if the origin is in screen space we need to convert it to raycaster space
|
|
287
|
-
if (
|
|
288
|
-
this.context.input.convertScreenspaceToRaycastSpace(
|
|
315
|
+
if (vec3.x > 1 || vec3.y > 1 || vec3.y < -1 || vec3.x < -1) {
|
|
316
|
+
this.context.input.convertScreenspaceToRaycastSpace(vec3);
|
|
289
317
|
}
|
|
290
|
-
vec3.set(origin.x, origin.y, -1);
|
|
291
318
|
vec3.unproject(cam);
|
|
292
319
|
origin = vec3;
|
|
293
320
|
}
|
|
@@ -466,9 +493,15 @@ export class Physics {
|
|
|
466
493
|
if (scale.z < 0)
|
|
467
494
|
scale.z = Math.abs(scale.z);
|
|
468
495
|
|
|
496
|
+
// prevent zero scale - seems normals are flipped otherwise
|
|
497
|
+
if (scale.x == 0) scale.x = 0.0000001;
|
|
498
|
+
if (scale.y == 0) scale.y = 0.0000001;
|
|
499
|
+
if (scale.z == 0) scale.z = 0.0000001;
|
|
500
|
+
|
|
469
501
|
const desc = ColliderDesc.cuboid(scale.x, scale.y, scale.z);
|
|
470
502
|
// const objectLayerMask = collider.gameObject.layers.mask;
|
|
471
503
|
// const mask = objectLayerMask & ~2;
|
|
504
|
+
// TODO: https://rapier.rs/docs/user_guides/javascript/colliders/#collision-groups-and-solver-groups
|
|
472
505
|
// desc.setCollisionGroups(objectLayerMask);
|
|
473
506
|
this.createCollider(collider, desc, center);
|
|
474
507
|
}
|
|
@@ -612,6 +645,10 @@ export class Physics {
|
|
|
612
645
|
col[$componentKey] = collider;
|
|
613
646
|
collider[$bodyKey] = col;
|
|
614
647
|
col.setActiveEvents(ActiveEvents.COLLISION_EVENTS);
|
|
648
|
+
|
|
649
|
+
// const objectLayerMask = collider.gameObject.layers.mask;
|
|
650
|
+
// const mask = objectLayerMask & ~2;
|
|
651
|
+
// col.setCollisionGroups(objectLayerMask);
|
|
615
652
|
this.objects.push(collider);
|
|
616
653
|
this.bodies.push(col);
|
|
617
654
|
return col;
|
|
@@ -172,6 +172,7 @@ export declare interface ICamera extends IComponent {
|
|
|
172
172
|
backgroundColor: RGBAColor | null;
|
|
173
173
|
backgroundBlurriness: number | undefined;
|
|
174
174
|
clearFlags: number;
|
|
175
|
+
cullingMask: number;
|
|
175
176
|
aspect: number;
|
|
176
177
|
fieldOfView?: number;
|
|
177
178
|
screenPointToRay(x: number, y: number, ray?: Ray): Ray;
|
|
@@ -26,14 +26,10 @@ export class CircularBuffer<T> {
|
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
get(): T {
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
else {
|
|
35
|
-
this._cache.push(this._factory());
|
|
36
|
-
}
|
|
29
|
+
const i = this._index % this._maxSize;
|
|
30
|
+
this._index++;
|
|
31
|
+
if (this._cache.length <= i) {
|
|
32
|
+
this._cache[i] = this._factory();
|
|
37
33
|
}
|
|
38
34
|
return this._cache[i];
|
|
39
35
|
}
|
|
@@ -145,7 +145,7 @@ export class Animation extends Behaviour {
|
|
|
145
145
|
return false;
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
-
play(clipOrNumber: AnimationClip | number | string | undefined, options?: PlayOptions): Promise<AnimationAction> | void {
|
|
148
|
+
play(clipOrNumber: AnimationClip | number | string | undefined = 0, options?: PlayOptions): Promise<AnimationAction> | void {
|
|
149
149
|
if (debug) console.log("PLAY", clipOrNumber)
|
|
150
150
|
this.init();
|
|
151
151
|
if (!this.mixer) {
|
|
@@ -171,8 +171,8 @@ export class Animation extends Behaviour {
|
|
|
171
171
|
if (!options) options = {};
|
|
172
172
|
if (!options.minMaxOffsetNormalized) options.minMaxOffsetNormalized = this.minMaxOffsetNormalized;
|
|
173
173
|
if (!options.minMaxSpeed) options.minMaxSpeed = this.minMaxSpeed;
|
|
174
|
-
if (
|
|
175
|
-
if (
|
|
174
|
+
if (options.loop === undefined) options.loop = this.loop;
|
|
175
|
+
if (options.clampWhenFinished === undefined) options.clampWhenFinished = this.clampWhenFinished;
|
|
176
176
|
for (const act of this.actions) {
|
|
177
177
|
if (act.getClip() === clip) {
|
|
178
178
|
return this.internalOnPlay(act, options);
|
|
@@ -120,7 +120,7 @@ export class CharacterControllerInput extends Behaviour {
|
|
|
120
120
|
// if (jumpDown) this._jumpDownTime = this.context.time.time;
|
|
121
121
|
// const jumpUp = this.context.input.isKeyUp(" ");
|
|
122
122
|
|
|
123
|
-
const step = forward ? 1 : 0 + backward ? -1 : 0;
|
|
123
|
+
const step = (forward ? 1 : 0) + (backward ? -1 : 0);
|
|
124
124
|
this._currentSpeed.z += step * this.movementSpeed * this.context.time.deltaTime;
|
|
125
125
|
|
|
126
126
|
// if (!this.controller || this.controller.isGrounded)
|
|
@@ -132,7 +132,7 @@ export class CharacterControllerInput extends Behaviour {
|
|
|
132
132
|
if (this.controller) this.controller.move(this._temp);
|
|
133
133
|
else this.gameObject.position.add(this._temp);
|
|
134
134
|
|
|
135
|
-
const rotation = rotateLeft ? 1 : 0 + rotateRight ? -1 : 0;
|
|
135
|
+
const rotation = (rotateLeft ? 1 : 0) + (rotateRight ? -1 : 0);
|
|
136
136
|
this._currentAngularSpeed.y += Mathf.toRadians(rotation * this.rotationSpeed) * this.context.time.deltaTime;
|
|
137
137
|
if (this.lookForward && Math.abs(this._currentAngularSpeed.y) < .01) {
|
|
138
138
|
const forwardVector = this.context.mainCameraComponent!.forward;
|
|
@@ -639,7 +639,7 @@ export class Renderer extends Behaviour implements IRenderer {
|
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
|
|
642
|
-
|
|
642
|
+
applySettings(go: THREE.Object3D) {
|
|
643
643
|
go.receiveShadow = this.receiveShadows;
|
|
644
644
|
if (this.shadowCastingMode == ShadowCastingMode.On) {
|
|
645
645
|
go.castShadow = true;
|
|
@@ -734,15 +734,16 @@ class InstancingHandler {
|
|
|
734
734
|
public setup(renderer: Renderer, obj: THREE.Object3D, context: Context, handlesArray: InstanceHandle[] | null, args: InstancingSetupArgs, level: number = 0)
|
|
735
735
|
: InstanceHandle[] | null {
|
|
736
736
|
|
|
737
|
+
// make sure setting casting settings are applied so when we add the mesh to the InstancedMesh we can ask for the correct cast shadow setting
|
|
738
|
+
renderer.applySettings(obj);
|
|
737
739
|
const res = this.tryCreateOrAddInstance(obj, context, args);
|
|
738
740
|
if (res) {
|
|
739
741
|
renderer.loadProgressiveTextures(res.instancer.material);
|
|
740
742
|
if (handlesArray === null) handlesArray = [];
|
|
741
743
|
handlesArray.push(res);
|
|
742
|
-
return handlesArray;
|
|
743
744
|
}
|
|
744
745
|
|
|
745
|
-
if (level <= 0 && obj.type !== "Mesh") {
|
|
746
|
+
else if (level <= 0 && obj.type !== "Mesh") {
|
|
746
747
|
const nextLevel = level + 1;
|
|
747
748
|
for (const ch of obj.children) {
|
|
748
749
|
handlesArray = this.setup(renderer, ch, context, handlesArray, args, nextLevel);
|
|
@@ -799,10 +800,8 @@ class InstancingHandler {
|
|
|
799
800
|
let previousMatrix: THREE.Matrix4 = obj.matrixWorld.clone();
|
|
800
801
|
const matrixChangeWrapper = (a: Matrix4, b: Matrix4) => {
|
|
801
802
|
const newMatrixWorld = original(a, b);
|
|
802
|
-
// console.warn("MULT", obj.matrixWorldNeedsUpdate);
|
|
803
803
|
if (obj[NEED_UPDATE_INSTANCE_KEY] || previousMatrix.equals(newMatrixWorld) === false) {
|
|
804
804
|
previousMatrix.copy(newMatrixWorld)
|
|
805
|
-
// handle.setMatrix(newMatrixWorld);
|
|
806
805
|
obj[NEED_UPDATE_INSTANCE_KEY] = true;
|
|
807
806
|
}
|
|
808
807
|
return newMatrixWorld;
|
|
@@ -865,6 +864,13 @@ class InstanceHandle {
|
|
|
865
864
|
|
|
866
865
|
class InstancedMeshRenderer {
|
|
867
866
|
|
|
867
|
+
set castShadow(val: boolean) {
|
|
868
|
+
this.inst.castShadow = val;
|
|
869
|
+
}
|
|
870
|
+
set receiveShadow(val: boolean) {
|
|
871
|
+
this.inst.receiveShadow = val;
|
|
872
|
+
}
|
|
873
|
+
|
|
868
874
|
public name: string = "";
|
|
869
875
|
public geo: THREE.BufferGeometry;
|
|
870
876
|
public material: THREE.Material;
|
|
@@ -915,6 +921,14 @@ class InstancedMeshRenderer {
|
|
|
915
921
|
return null;
|
|
916
922
|
}
|
|
917
923
|
const handle = new InstanceHandle(-1, obj, this);
|
|
924
|
+
|
|
925
|
+
if (obj.castShadow === true && this.inst.castShadow === false) {
|
|
926
|
+
this.inst.castShadow = true;
|
|
927
|
+
}
|
|
928
|
+
if (obj.receiveShadow === true && this.inst.receiveShadow === false) {
|
|
929
|
+
this.inst.receiveShadow = true;
|
|
930
|
+
}
|
|
931
|
+
|
|
918
932
|
this.add(handle);
|
|
919
933
|
return handle;
|
|
920
934
|
}
|
|
@@ -390,10 +390,19 @@ export class WebXR extends Behaviour {
|
|
|
390
390
|
if (this.context.mainCamera) {
|
|
391
391
|
//@ts-ignore
|
|
392
392
|
const cam = xr.getCamera(this.context.mainCamera) as ArrayCamera;
|
|
393
|
-
|
|
394
|
-
|
|
393
|
+
const cull = this.context.mainCameraComponent?.cullingMask;
|
|
394
|
+
if(cull !== undefined){
|
|
395
|
+
for (const c of cam.cameras) {
|
|
396
|
+
c.layers.mask = cull;
|
|
397
|
+
}
|
|
398
|
+
cam.layers.mask = cull;
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
for (const c of cam.cameras) {
|
|
402
|
+
c.layers.enableAll();
|
|
403
|
+
}
|
|
404
|
+
cam.layers.enableAll();
|
|
395
405
|
}
|
|
396
|
-
|
|
397
406
|
this.rig.add(this.context.mainCamera);
|
|
398
407
|
if (this._requestedAR) {
|
|
399
408
|
this.context.scene.add(this.rig);
|
|
@@ -769,7 +769,7 @@ export class WebXRController extends Behaviour {
|
|
|
769
769
|
public raycast(): Intersection[] {
|
|
770
770
|
const opts = new RaycastOptions();
|
|
771
771
|
opts.layerMask = new Layers();
|
|
772
|
-
opts.layerMask.
|
|
772
|
+
opts.layerMask.enableAll();
|
|
773
773
|
opts.layerMask.disable(2);
|
|
774
774
|
opts.ray = this.getRay();
|
|
775
775
|
const hits = this.context.physics.raycast(opts);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ui/PointerEvents"
|
package/src/needle-engine.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { GameObject, Behaviour } from "./engine-components/Component";
|
|
|
11
11
|
export { serializable, serializeable } from "./engine/engine_serialization_decorator";
|
|
12
12
|
export { Collision } from "./engine/engine_types";
|
|
13
13
|
export * from "./engine/api";
|
|
14
|
+
export * from "./engine-components/api";
|
|
14
15
|
export * from "./engine-components/codegen/components";
|
|
15
16
|
export * from "./engine-components/js-extensions/Object3D";
|
|
16
17
|
|