@needle-tools/engine 2.24.0-pre → 2.25.0-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.
@@ -1,3 +1,4 @@
1
+ import { Context } from "./engine_setup";
1
2
 
2
3
  export const arContainerClassName = "ar";
3
4
  export const quitARClassName = "quit-ar";
@@ -17,15 +18,23 @@ export class AROverlayHandler {
17
18
  registeredCloseEventElements: Element[] = [];
18
19
 
19
20
  private _createdAROnlyElements: Array<any> = [];
21
+ private _reparentedObjects: Array<{ el: Element, previousParent: HTMLElement | null }> = [];
20
22
 
21
23
  requestEndAR() {
22
24
  this.onRequestedEndAR();
23
25
  }
24
26
 
25
- onBegin(overlayContainer: HTMLElement, session: THREE.XRSession) {
27
+ onBegin(context: Context, overlayContainer: HTMLElement, session: THREE.XRSession) {
26
28
  this.currentSession = session;
27
29
  this.arContainer = overlayContainer;
28
- if (!this.arContainer) return;
30
+
31
+ const arElements = context.domElement.querySelectorAll(`.${arContainerClassName}`);
32
+ arElements.forEach(el => {
33
+ if (!el) return;
34
+ if (el === this.arContainer) return;
35
+ this._reparentedObjects.push({ el: el, previousParent: el.parentElement });
36
+ this.arContainer?.appendChild(el);
37
+ });
29
38
 
30
39
  const quit_Elements = overlayContainer.getElementsByClassName(quitARClassName);
31
40
  if (!quit_Elements || quit_Elements.length <= 0) {
@@ -42,7 +51,7 @@ export class AROverlayHandler {
42
51
  }
43
52
  }
44
53
 
45
- onEnd() {
54
+ onEnd(_context: Context) {
46
55
  // if (this.arContainer)
47
56
  // this.arContainer.classList.remove("ar-session-active");
48
57
  for (const created of this._createdAROnlyElements) {
@@ -50,6 +59,13 @@ export class AROverlayHandler {
50
59
  created.remove();
51
60
  }
52
61
  }
62
+
63
+
64
+ for (const prev of this._reparentedObjects) {
65
+ const el = prev.el as HTMLElement;
66
+ prev.previousParent?.appendChild(el);
67
+ }
68
+ this._reparentedObjects.length = 0;
53
69
  }
54
70
 
55
71
  findOrCreateARContainer(element: HTMLElement): HTMLElement {
@@ -3,20 +3,51 @@ import { Context } from "./engine_setup"
3
3
  import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
4
4
  import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js';
5
5
  import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
6
+ import { getParam } from "./engine_utils";
7
+
8
+ const debug = getParam("debugdecoders");
6
9
 
7
10
  let dracoLoader: DRACOLoader;
8
11
  let ktx2Loader: KTX2Loader;
9
12
 
13
+ export function setDracoDecoderPath(path: string | undefined) {
14
+ if (path !== undefined && typeof path === "string") {
15
+ if (!dracoLoader)
16
+ dracoLoader = new DRACOLoader();
17
+ if (debug) console.log("Setting draco decoder path to", path);
18
+ dracoLoader.setDecoderPath(path);
19
+ }
20
+ }
21
+
22
+ export function setDracoDecoderType(type: string | undefined) {
23
+ if (type !== undefined && typeof type === "string") {
24
+ if (!dracoLoader)
25
+ dracoLoader = new DRACOLoader();
26
+ if (debug) console.log("Setting draco decoder type to", type);
27
+ dracoLoader.setDecoderConfig({ type: type });
28
+ }
29
+ }
30
+
31
+ export function setKtx2TranscoderPath(path: string) {
32
+ if (path !== undefined && typeof path === "string") {
33
+ if (!ktx2Loader)
34
+ ktx2Loader = new KTX2Loader();
35
+ if (debug) console.log("Setting ktx2 transcoder path to", path);
36
+ ktx2Loader.setTranscoderPath(path);
37
+ }
38
+ }
10
39
 
11
- export function addDracoAndKTX2Loaders(loader: GLTFLoader, context : Context) {
40
+ export function addDracoAndKTX2Loaders(loader: GLTFLoader, context: Context) {
12
41
  if (!dracoLoader) {
13
42
  dracoLoader = new DRACOLoader();
14
43
  dracoLoader.setDecoderPath('./include/draco/');
15
44
  dracoLoader.setDecoderConfig({ type: 'js' });
45
+ if(debug) console.log("Setting draco decoder path to", './include/draco/');
16
46
  }
17
47
  if (!ktx2Loader) {
18
48
  ktx2Loader = new KTX2Loader();
19
49
  ktx2Loader.setTranscoderPath('./include/ktx2/');
50
+ if(debug) console.log("Setting ktx2 transcoder path to", './include/ktx2/');
20
51
  if (context.renderer)
21
52
  ktx2Loader.detectSupport(context.renderer);
22
53
  }
@@ -603,7 +603,8 @@ export class Context {
603
603
  const evts = this.coroutines[evt];
604
604
  for (let i = 0; i < evts.length; i++) {
605
605
  const evt = evts[i];
606
- if (!evt.comp || evt.comp.destroyed || !evt.main) {
606
+ const remove = !evt.comp || evt.comp.destroyed || !evt.main || evt.comp["enabled"] === false;
607
+ if (remove) {
607
608
  evts.splice(i, 1);
608
609
  --i;
609
610
  continue;
@@ -9,6 +9,7 @@ export class EXT_texture_exr {
9
9
 
10
10
  this.parser = parser;
11
11
  this.name = "EXT_texture_exr";
12
+ if(debug) console.log(parser);
12
13
 
13
14
  }
14
15
 
@@ -161,20 +161,36 @@ export class AnimationTrackHandler extends TrackHandler {
161
161
  }
162
162
  }
163
163
 
164
- if (!foundPositionTrack) {
165
- const indexOfProperty = clip.tracks[0].name.lastIndexOf(".");
166
- const trackName = clip.tracks[0].name.substring(0, indexOfProperty) + ".position";
167
- const track = new THREE.VectorKeyframeTrack(trackName, [0, clip.duration], [0, 0, 0, 0, 0, 0]);
168
- clip.tracks.push(track);
169
- this.createPositionInterpolant(clip, clipModel, track);
170
- }
171
164
 
172
- if (!foundRotationTrack) {
173
- const indexOfProperty = clip.tracks[0].name.lastIndexOf(".");
174
- const trackName = clip.tracks[0].name.substring(0, indexOfProperty) + ".quaternion";
175
- const track = new THREE.QuaternionKeyframeTrack(trackName, [0, clip.duration], [0, 0, 0, 1, 0, 0, 0, 1]);
176
- clip.tracks.push(track);
177
- this.createRotationInterpolant(clip, clipModel, track);
165
+ // ensure we always have a position and rotation track so we can apply offsets in interpolator
166
+ // TODO: this currently assumes that there is only one root always that has offsets so it only does create the interpolator for the first track which might be incorrect. In general it would probably be better if we would not create additional tracks but apply the offsets for these objects elsewhere!?
167
+
168
+ if (!foundPositionTrack || !foundRotationTrack) {
169
+ const root = this.mixer?.getRoot() as THREE.Object3D;
170
+ const track = clip.tracks[0];
171
+ const indexOfProperty = track.name.lastIndexOf(".");
172
+ const baseName = track.name.substring(0, indexOfProperty);
173
+ const objName = baseName.substring(baseName.lastIndexOf(".") + 1);
174
+ const targetObj = root.getObjectByName(objName);
175
+ if (targetObj) {
176
+ if (!foundPositionTrack) {
177
+ const trackName = baseName + ".position";
178
+ if (debug) console.warn("Create position track", objName, targetObj);
179
+ // apply initial local position so it doesnt get flipped or otherwise changed
180
+ const pos = targetObj.position;
181
+ const track = new THREE.VectorKeyframeTrack(trackName, [0, clip.duration], [pos.x, pos.y, pos.z, pos.x, pos.y, pos.z]);
182
+ clip.tracks.push(track);
183
+ this.createPositionInterpolant(clip, clipModel, track);
184
+ }
185
+ else if(!foundRotationTrack){
186
+ const trackName = clip.tracks[0].name.substring(0, indexOfProperty) + ".quaternion";
187
+ if (debug) console.warn("Create quaternion track", objName, targetObj);
188
+ const rot = targetObj.quaternion;
189
+ const track = new THREE.QuaternionKeyframeTrack(trackName, [0, clip.duration], [rot.x, rot.y, rot.z, rot.w, rot.x, rot.y, rot.z, rot.w]);
190
+ clip.tracks.push(track);
191
+ this.createRotationInterpolant(clip, clipModel, track);
192
+ }
193
+ }
178
194
  }
179
195
  }
180
196
 
@@ -36,4 +36,11 @@ for (const method of Object.getOwnPropertyNames(GameObject)) {
36
36
  Needle[method] = GameObject[method];
37
37
  break;
38
38
  }
39
- }
39
+ }
40
+
41
+ // make three accessible
42
+ import * as THREE from "three";
43
+ if(!globalThis["THREE"]) {
44
+ globalThis["THREE"] = THREE;
45
+ }
46
+ else console.warn("Threejs is already imported");