@needle-tools/engine 3.6.3 → 3.6.5
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 +14 -0
- package/dist/needle-engine.js +10589 -10562
- package/dist/needle-engine.light.js +10535 -10508
- package/dist/needle-engine.light.min.js +285 -286
- package/dist/needle-engine.light.umd.cjs +285 -286
- package/dist/needle-engine.min.js +285 -286
- package/dist/needle-engine.umd.cjs +286 -287
- package/lib/engine/api.d.ts +1 -0
- package/lib/engine/api.js +1 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/engine_context.d.ts +12 -1
- package/lib/engine/engine_context.js +13 -2
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_create_objects.d.ts +3 -1
- package/lib/engine/engine_create_objects.js +17 -4
- package/lib/engine/engine_create_objects.js.map +1 -1
- package/lib/engine/engine_element.js +11 -4
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_element_loading.js +3 -3
- package/lib/engine/engine_element_loading.js.map +1 -1
- package/lib/engine/engine_license.js +4 -6
- package/lib/engine/engine_license.js.map +1 -1
- package/lib/engine/engine_scenetools.d.ts +5 -4
- package/lib/engine/engine_scenetools.js +2 -67
- package/lib/engine/engine_scenetools.js.map +1 -1
- package/lib/engine/extensions/NEEDLE_components.js +5 -2
- package/lib/engine/extensions/NEEDLE_components.js.map +1 -1
- package/lib/engine-components/AnimationCurve.d.ts +1 -0
- package/lib/engine-components/AnimationCurve.js +24 -3
- package/lib/engine-components/AnimationCurve.js.map +1 -1
- package/lib/engine-components/AnimationUtils.js +69 -3
- package/lib/engine-components/AnimationUtils.js.map +1 -1
- package/lib/engine-components/Component.d.ts +2 -1
- package/lib/engine-components/Component.js +2 -1
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/Gizmos.js +1 -1
- package/lib/engine-components/Gizmos.js.map +1 -1
- package/lib/engine-components/NestedGltf.js +1 -0
- package/lib/engine-components/NestedGltf.js.map +1 -1
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +2 -2
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -1
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js +2 -1
- package/lib/engine-components/postprocessing/Effects/ColorAdjustments.js.map +1 -1
- package/package.json +1 -1
- package/plugins/vite/copyfiles.js +2 -0
- package/plugins/vite/transform-codegen.js +10 -1
- package/src/engine/api.ts +12 -11
- package/src/engine/engine_context.ts +15 -3
- package/src/engine/engine_create_objects.ts +18 -5
- package/src/engine/engine_element.ts +12 -6
- package/src/engine/engine_element_loading.ts +3 -3
- package/src/engine/engine_license.ts +4 -6
- package/src/engine/engine_scenetools.ts +9 -72
- package/src/engine/extensions/NEEDLE_components.ts +7 -2
- package/src/engine-components/AnimationCurve.ts +31 -3
- package/src/engine-components/AnimationUtils.ts +70 -5
- package/src/engine-components/Component.ts +2 -1
- package/src/engine-components/Gizmos.ts +1 -1
- package/src/engine-components/NestedGltf.ts +2 -0
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +2 -2
- package/src/engine-components/postprocessing/Effects/ColorAdjustments.ts +2 -1
|
@@ -42,9 +42,10 @@ export class AnimationCurve {
|
|
|
42
42
|
if (hasNextKeyframe) {
|
|
43
43
|
const nextKf = this.keys[i+1];
|
|
44
44
|
// if the next
|
|
45
|
-
if(nextKf.time < time) continue;
|
|
46
|
-
|
|
47
|
-
|
|
45
|
+
if (nextKf.time < time) continue;
|
|
46
|
+
// tangents are set to Infinity if interpolation is set to constant - in that case we should always return the floored value
|
|
47
|
+
if (!isFinite(kf.outTangent) || !isFinite(nextKf.inTangent)) return kf.value;
|
|
48
|
+
return AnimationCurve.interpolateValue(time, kf, nextKf);
|
|
48
49
|
}
|
|
49
50
|
else {
|
|
50
51
|
return kf.value;
|
|
@@ -53,4 +54,31 @@ export class AnimationCurve {
|
|
|
53
54
|
}
|
|
54
55
|
return this.keys[this.keys.length - 1].value;
|
|
55
56
|
}
|
|
57
|
+
|
|
58
|
+
static interpolateValue(time: number, keyframe1: Keyframe, keyframe2: Keyframe): number {
|
|
59
|
+
const startTime1 = keyframe1.time;
|
|
60
|
+
const startValue1 = keyframe1.value;
|
|
61
|
+
const outTangent1 = keyframe1.outTangent;
|
|
62
|
+
|
|
63
|
+
const startTime2 = keyframe2.time;
|
|
64
|
+
const startValue2 = keyframe2.value;
|
|
65
|
+
const inTangent2 = keyframe2.inTangent;
|
|
66
|
+
|
|
67
|
+
// could be precomputed and stored in the keyframes maybe
|
|
68
|
+
const timeDifference = startTime2 - startTime1;
|
|
69
|
+
const timeDifferenceSquared = timeDifference * timeDifference;
|
|
70
|
+
const timeDifferenceCubed = timeDifferenceSquared * timeDifference;
|
|
71
|
+
|
|
72
|
+
const a = ((outTangent1 + inTangent2) * timeDifference - 2 * (startValue2 - startValue1)) / timeDifferenceCubed;
|
|
73
|
+
const b = (3 * (startValue2 - startValue1) - (inTangent2 + 2 * outTangent1) * timeDifference) / timeDifferenceSquared;
|
|
74
|
+
const c = outTangent1;
|
|
75
|
+
const d = startValue1;
|
|
76
|
+
|
|
77
|
+
const timeDelta = time - startTime1;
|
|
78
|
+
const timeDeltaSquared = timeDelta * timeDelta;
|
|
79
|
+
const timeDeltaCubed = timeDeltaSquared * timeDelta;
|
|
80
|
+
|
|
81
|
+
return a * timeDeltaCubed + b * timeDeltaSquared + c * timeDelta + d;
|
|
82
|
+
}
|
|
83
|
+
|
|
56
84
|
}
|
|
@@ -1,14 +1,79 @@
|
|
|
1
1
|
import { GLTF } from "three/examples/jsm/loaders/GLTFLoader.js";
|
|
2
2
|
import { ContextEvent, ContextRegistry } from "../engine/engine_context_registry";
|
|
3
|
-
import {
|
|
4
|
-
|
|
3
|
+
import { addNewComponent } from "../engine/engine_components";
|
|
4
|
+
import { Animator } from "./Animator";
|
|
5
|
+
import { Animation } from "./Animation";
|
|
6
|
+
import { GameObject } from "./Component";
|
|
7
|
+
import { PlayableDirector } from "./api";
|
|
5
8
|
|
|
6
9
|
ContextRegistry.registerCallback(ContextEvent.ContextCreated, args => {
|
|
7
10
|
const autoplay = args.context.domElement.getAttribute("autoplay");
|
|
8
11
|
if (autoplay !== undefined && (autoplay === "" || autoplay === "true")) {
|
|
9
12
|
if (args.files) {
|
|
10
|
-
for (const file of args.files)
|
|
11
|
-
|
|
13
|
+
for (const file of args.files) {
|
|
14
|
+
const hasAnimation = GameObject.foreachComponent(file.file.scene, comp => {
|
|
15
|
+
if (comp.enabled === false) return undefined;
|
|
16
|
+
if (comp instanceof Animation && comp.playAutomatically || comp instanceof Animator || comp instanceof PlayableDirector && comp.playOnAwake === true) {
|
|
17
|
+
return true;
|
|
18
|
+
}
|
|
19
|
+
else if (comp instanceof Animation) {
|
|
20
|
+
comp.playAutomatically = true;
|
|
21
|
+
return true;
|
|
22
|
+
}
|
|
23
|
+
else if (comp instanceof PlayableDirector) {
|
|
24
|
+
comp.playOnAwake = true;
|
|
25
|
+
return true;
|
|
26
|
+
}
|
|
27
|
+
return undefined;
|
|
28
|
+
}, true);
|
|
29
|
+
if (hasAnimation !== true)
|
|
30
|
+
findAnimations(file.file as GLTF);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
function findAnimations(gltf: GLTF) {
|
|
39
|
+
if (!gltf || !gltf.animations) return;
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
for (let i = 0; i < gltf.animations.length; i++) {
|
|
43
|
+
const animation = gltf.animations[i];
|
|
44
|
+
if (!animation.tracks || animation.tracks.length <= 0) continue;
|
|
45
|
+
for (const t in animation.tracks) {
|
|
46
|
+
const track = animation.tracks[t];
|
|
47
|
+
const objectName = track["__objectName"] ?? track.name.substring(0, track.name.indexOf("."));
|
|
48
|
+
const obj = gltf.scene.getObjectByName(objectName);
|
|
49
|
+
if (!obj) {
|
|
50
|
+
// console.warn("could not find " + objectName, animation, gltf.scene);
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
let animationComponent = findAnimationGameObjectInParent(obj);
|
|
54
|
+
if (!animationComponent) {
|
|
55
|
+
animationComponent = addNewComponent(gltf.scene, new Animation());
|
|
56
|
+
}
|
|
57
|
+
const animations = animationComponent.animations = animationComponent.animations || [];
|
|
58
|
+
animation["name_animator"] = animationComponent.name;
|
|
59
|
+
// console.log(objectName, obj, animator.name, animations.length);
|
|
60
|
+
if (animations.indexOf(animation) < 0) {
|
|
61
|
+
animations.push(animation);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
function findAnimationGameObjectInParent(obj) {
|
|
66
|
+
if (!obj) return;
|
|
67
|
+
const components = obj.userData?.components;
|
|
68
|
+
if (components && components.length > 0) {
|
|
69
|
+
for (let i = 0; i < components.length; i++) {
|
|
70
|
+
const component = components[i];
|
|
71
|
+
// console.log(component);
|
|
72
|
+
if (component instanceof Animator || component instanceof Animation) {
|
|
73
|
+
return obj;;
|
|
74
|
+
}
|
|
75
|
+
}
|
|
12
76
|
}
|
|
77
|
+
return findAnimationGameObjectInParent(obj.parent);
|
|
13
78
|
}
|
|
14
|
-
}
|
|
79
|
+
}
|
|
@@ -63,8 +63,9 @@ export abstract class GameObject extends Object3D implements Object3D, IGameObje
|
|
|
63
63
|
|
|
64
64
|
/** Run a callback for all components of the provided type on the provided object and its children (if recursive is true)
|
|
65
65
|
* @param instance object to run the method on
|
|
66
|
-
* @param cb callback to run on each component
|
|
66
|
+
* @param cb callback to run on each component, "return undefined;" to continue and "return <anything>;" to break the loop
|
|
67
67
|
* @param recursive if true, the method will be run on all children as well
|
|
68
|
+
* @returns the last return value of the callback
|
|
68
69
|
*/
|
|
69
70
|
public static foreachComponent(instance: Object3D, cb: (comp: Component) => any, recursive: boolean = true): any {
|
|
70
71
|
return foreachComponent(instance, cb as (comp: IComponent) => any, recursive);
|
|
@@ -21,7 +21,7 @@ export class BoxGizmo extends Behaviour {
|
|
|
21
21
|
onEnable(): void {
|
|
22
22
|
if (this.isGizmo && !params.showGizmos) return;
|
|
23
23
|
if (!this._gizmoObject) {
|
|
24
|
-
if (this.objectBounds
|
|
24
|
+
if (this.objectBounds) {
|
|
25
25
|
this._gizmoObject = new THREE.BoxHelper(this.gameObject, this.color ?? 0xffff00);
|
|
26
26
|
}
|
|
27
27
|
else {
|
|
@@ -43,6 +43,8 @@ export class NestedGltf extends Behaviour {
|
|
|
43
43
|
res.matrixAutoUpdate = true;
|
|
44
44
|
res.layers.disableAll();
|
|
45
45
|
res.layers.set(this.layer);
|
|
46
|
+
|
|
47
|
+
this.dispatchEvent(new CustomEvent("loaded", { detail: {instance: res, assetReference: this.filePath }}));
|
|
46
48
|
}
|
|
47
49
|
if (debug) console.log("Nested loading done:", this.filePath?.uri ?? this.filePath, res);
|
|
48
50
|
}
|
|
@@ -1299,7 +1299,7 @@ function buildMaterial( material: MeshStandardMaterial, textures, quickLookCompa
|
|
|
1299
1299
|
|
|
1300
1300
|
} else {
|
|
1301
1301
|
|
|
1302
|
-
inputs.push( `${pad}float inputs:roughness = ${material.roughness}` );
|
|
1302
|
+
inputs.push( `${pad}float inputs:roughness = ${material.roughness !== undefined ? material.roughness : 1 }` );
|
|
1303
1303
|
|
|
1304
1304
|
}
|
|
1305
1305
|
|
|
@@ -1311,7 +1311,7 @@ function buildMaterial( material: MeshStandardMaterial, textures, quickLookCompa
|
|
|
1311
1311
|
|
|
1312
1312
|
} else {
|
|
1313
1313
|
|
|
1314
|
-
inputs.push( `${pad}float inputs:metallic = ${material.metalness}` );
|
|
1314
|
+
inputs.push( `${pad}float inputs:metallic = ${material.metalness !== undefined ? material.metalness : 0 }` );
|
|
1315
1315
|
|
|
1316
1316
|
}
|
|
1317
1317
|
|
|
@@ -63,7 +63,8 @@ export class ColorAdjustments extends PostProcessingEffect {
|
|
|
63
63
|
this.postExposure!.onValueChanged = v => {
|
|
64
64
|
if (this.context.renderer.toneMapping === NoToneMapping)
|
|
65
65
|
this.context.renderer.toneMapping = LinearToneMapping;
|
|
66
|
-
this.
|
|
66
|
+
if (this.postExposure.overrideState)
|
|
67
|
+
this.context.renderer.toneMappingExposure = v;
|
|
67
68
|
}
|
|
68
69
|
this.contrast!.onValueChanged = v => {
|
|
69
70
|
brightnesscontrast.contrast = v;
|