Needle Engine

Changes between version 3.2.3-alpha and 3.2.4-alpha
Files changed (35) hide show
  1. src/engine/engine_fileloader.js +2 -2
  2. plugins/vite/license.js +2 -2
  3. src/engine/codegen/register_types.js +2 -2
  4. src/engine-components/Animation.ts +17 -19
  5. src/engine-components/Animator.ts +4 -5
  6. src/engine-components/AnimatorController.ts +16 -17
  7. src/engine-components/api.ts +2 -0
  8. src/engine/api.ts +5 -1
  9. src/engine-components/AudioListener.ts +4 -4
  10. src/engine-components/AudioSource.ts +8 -8
  11. src/engine-components/AvatarLoader.ts +15 -16
  12. src/engine-components/AxesHelper.ts +1 -1
  13. src/engine-components/BasicIKConstraint.ts +2 -2
  14. src/engine-components/BoxHelperComponent.ts +13 -13
  15. src/engine-components/Component.ts +61 -62
  16. src/engine-components/DragControls.ts +42 -43
  17. src/engine/engine_addressables.ts +6 -7
  18. src/engine/engine_context.ts +31 -28
  19. src/engine/engine_gameobject.ts +21 -21
  20. src/engine/engine_gizmos.ts +5 -6
  21. src/engine/engine_gltf_builtin_components.ts +9 -10
  22. src/engine/engine_input.ts +17 -18
  23. src/engine/engine_license.ts +2 -2
  24. src/engine/engine_mainloop_utils.ts +5 -5
  25. src/engine/engine_networking_auto.ts +1 -1
  26. src/engine/engine_networking_files.ts +10 -11
  27. src/engine/engine_three_utils.ts +37 -37
  28. src/engine/extensions/NEEDLE_components.ts +7 -6
  29. src/engine/extensions/NEEDLE_lighting_settings.ts +15 -6
  30. src/engine/extensions/NEEDLE_techniques_webgl.ts +29 -30
  31. src/needle-engine.ts +5 -8
  32. src/engine-components/ParticleSystemModules.ts +1483 -1483
  33. src/engine-components-experimental/networking/PlayerSync.ts +17 -4
  34. src/engine-components/ui/Utils.ts +4 -4
  35. src/engine-components-experimental/api.ts +1 -0
src/engine/engine_fileloader.js CHANGED
@@ -1,6 +1,6 @@
1
- import * as THREE from "three";
1
+ import { FileLoader } from "three";
2
2
 
3
- export const loader = new THREE.FileLoader();
3
+ export const loader = new FileLoader();
4
4
 
5
5
  export async function loadFileAsync(url) {
6
6
  return new Promise((resolve, reject) => {
plugins/vite/license.js CHANGED
@@ -7,11 +7,11 @@
7
7
  name: "needle-license",
8
8
  enforce: 'pre',
9
9
  async transform(src, id) {
10
- if (id.includes("engine/engine_license.ts")) {
10
+ if (id.includes("engine/engine_license") || id.includes("needle-tools_engine.js")) {
11
11
  const needleConfig = await loadConfig();
12
12
  if (needleConfig) {
13
13
  if (needleConfig.hasProLicense !== undefined && typeof needleConfig.hasProLicense === "boolean") {
14
- src = src.replace("const HAS_LICENSE = false;", "const HAS_LICENSE = " + needleConfig.hasProLicense + ";");
14
+ src = src.replace("NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE = false;", "NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE = " + needleConfig.hasProLicense + ";");
15
15
  return { code: src, map: null }
16
16
  }
17
17
  }
src/engine/codegen/register_types.js CHANGED
@@ -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";
@@ -184,7 +184,7 @@
184
184
  import { XRGrabRendering } from "../../engine-components/WebXRGrabRendering";
185
185
  import { XRRig } from "../../engine-components/WebXRRig";
186
186
  import { XRState } from "../../engine-components/XRFlag";
187
-
187
+
188
188
  // Register types
189
189
  TypeStore.add("__Ignore", __Ignore);
190
190
  TypeStore.add("AlignmentConstraint", AlignmentConstraint);
src/engine-components/Animation.ts CHANGED
@@ -1,9 +1,7 @@
1
1
  import { Behaviour } from "./Component";
2
- import * as THREE from 'three'
3
- import { AnimationAction, AnimationClip, Vector2 } from "three";
2
+ import { AnimationAction, AnimationClip, AnimationMixer, LoopOnce, LoopRepeat } from "three";
4
3
  import { MixerEvent } from "./Animator";
5
4
  import { serializable } from "../engine/engine_serialization_decorator";
6
- import { InstancingUtil } from "../engine/engine_instancing";
7
5
  import { Mathf } from "../engine/engine_math";
8
6
  import { Vec2 } from "../engine/engine_types";
9
7
  import { getParam } from "../engine/engine_utils";
@@ -63,7 +61,7 @@
63
61
  this.animations = animations;
64
62
  }
65
63
 
66
- set animations(animations: THREE.AnimationClip[]) {
64
+ set animations(animations: AnimationClip[]) {
67
65
  if (debug) console.log("assign animations", animations);
68
66
  this.gameObject.animations = animations;
69
67
  }
@@ -74,29 +72,29 @@
74
72
  /**
75
73
  * @deprecated Currently unsupported
76
74
  */
77
- get currentAction(): THREE.AnimationAction | null {
75
+ get currentAction(): AnimationAction | null {
78
76
  return this._currentActions[0];
79
77
  }
80
78
 
81
79
  /**
82
80
  * @deprecated Currently unsupported
83
81
  */
84
- get currentActions(): THREE.AnimationAction[] {
82
+ get currentActions(): AnimationAction[] {
85
83
  return this._currentActions;
86
84
  }
87
85
 
88
- private mixer: THREE.AnimationMixer | undefined = undefined;
89
- get actions(): Array<THREE.AnimationAction> {
86
+ private mixer: AnimationMixer | undefined = undefined;
87
+ get actions(): Array<AnimationAction> {
90
88
  return this._actions;
91
89
  }
92
- set actions(val: Array<THREE.AnimationAction>) {
90
+ set actions(val: Array<AnimationAction>) {
93
91
  this._actions = val;
94
92
  }
95
- private _actions: Array<THREE.AnimationAction> = [];
93
+ private _actions: Array<AnimationAction> = [];
96
94
 
97
- // private _currentAction: THREE.AnimationAction | null = null;
95
+ // private _currentAction: AnimationAction | null = null;
98
96
 
99
- private _currentActions: THREE.AnimationAction[] = [];
97
+ private _currentActions: AnimationAction[] = [];
100
98
  private _handles: AnimationHandle[] = [];
101
99
 
102
100
  awake() {
@@ -133,7 +131,7 @@
133
131
  // InstancingUtil.markDirty(this.gameObject);
134
132
  }
135
133
 
136
- getAction(name: string): THREE.AnimationAction | undefined | null {
134
+ getAction(name: string): AnimationAction | undefined | null {
137
135
  return this.actions?.find(a => a.getClip().name === name);
138
136
  }
139
137
 
@@ -210,8 +208,8 @@
210
208
  if (options?.startTime !== undefined) action.time = options.startTime;
211
209
 
212
210
  if (options?.loop !== undefined)
213
- action.loop = options.loop ? THREE.LoopRepeat : THREE.LoopOnce;
214
- else action.loop = THREE.LoopOnce;
211
+ action.loop = options.loop ? LoopRepeat : LoopOnce;
212
+ else action.loop = LoopOnce;
215
213
  action.play();
216
214
  if (debug)
217
215
  console.log("PLAY", action.getClip().name, action)
@@ -239,14 +237,14 @@
239
237
  this._didInit = true;
240
238
  if (!this.gameObject) return;
241
239
  this.actions = [];
242
- this.mixer = new THREE.AnimationMixer(this.gameObject);
240
+ this.mixer = new AnimationMixer(this.gameObject);
243
241
  }
244
242
  }
245
243
 
246
244
 
247
245
  class AnimationHandle {
248
- mixer: THREE.AnimationMixer;
249
- action: THREE.AnimationAction;
246
+ mixer: AnimationMixer;
247
+ action: AnimationAction;
250
248
  promise: Promise<AnimationAction> | null = null;
251
249
  resolve: Function | null = null;
252
250
  reject: Function | null = null;
@@ -258,7 +256,7 @@
258
256
  private _finishedCallback?: any;
259
257
  private _resolvedOrRejectedCallback?: (AnimationHandle) => void;
260
258
 
261
- constructor(action: THREE.AnimationAction, mixer: THREE.AnimationMixer, opts?: PlayOptions, cb?: (handle: AnimationHandle) => void) {
259
+ constructor(action: AnimationAction, mixer: AnimationMixer, opts?: PlayOptions, cb?: (handle: AnimationHandle) => void) {
262
260
  this.action = action;
263
261
  this.mixer = mixer;
264
262
  this._resolvedOrRejectedCallback = cb;
src/engine-components/Animator.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { Behaviour } from "./Component";
2
- import * as THREE from 'three'
3
- import { LoopOnce, AnimationActionLoopStyles, AnimationAction } from "three";
4
- import { getParam, deepClone } from "../engine/engine_utils";
2
+ import { AnimationActionLoopStyles, AnimationAction, AnimationMixer } from "three";
3
+ import { getParam } from "../engine/engine_utils";
5
4
  import { AnimatorControllerModel } from "../engine/extensions/NEEDLE_animator_controller_model";
6
5
  import { AnimatorController } from "./AnimatorController";
7
6
  import { serializable } from "../engine/engine_serialization_decorator";
@@ -12,9 +11,9 @@
12
11
 
13
12
  export declare class MixerEvent {
14
13
  type: string;
15
- action: THREE.AnimationAction;
14
+ action: AnimationAction;
16
15
  loopDelta: number;
17
- target: THREE.AnimationMixer;
16
+ target: AnimationMixer;
18
17
  }
19
18
 
20
19
  export declare class PlayOptions {
src/engine-components/AnimatorController.ts CHANGED
@@ -1,9 +1,8 @@
1
1
  import { Animator } from "./Animator";
2
2
  import { AnimatorConditionMode, AnimatorControllerModel, AnimatorControllerParameterType, AnimatorStateInfo, Condition, createMotion, State, StateMachineBehaviour } from "../engine/extensions/NEEDLE_animator_controller_model";
3
- import { AnimationAction, AnimationClip, AnimationMixer, AxesHelper, Euler, KeyframeTrack, LoopOnce, LoopRepeat, Matrix4, Object3D, Quaternion, Vector3 } from "three";
3
+ import { AnimationAction, AnimationClip, AnimationMixer, AxesHelper, Euler, KeyframeTrack, LoopOnce, Object3D, Quaternion, Vector3 } from "three";
4
4
  import { deepClone, getParam } from "../engine/engine_utils";
5
5
  import { Context } from "../engine/engine_setup";
6
- import * as THREE from "three";
7
6
  import { TypeStore } from "../engine/engine_typestore";
8
7
  import { assign } from "../engine/engine_serialization_core";
9
8
  import { Mathf } from "../engine/engine_math";
@@ -110,7 +109,7 @@
110
109
  get context(): Context | undefined | null { return this.animator?.context; }
111
110
 
112
111
 
113
- // applyRootMotion(obj: THREE.Object3D) {
112
+ // applyRootMotion(obj: Object3D) {
114
113
  // // this.internalApplyRootMotion(obj);
115
114
  // }
116
115
 
@@ -160,7 +159,7 @@
160
159
  }
161
160
 
162
161
 
163
- private _mixer!: THREE.AnimationMixer;
162
+ private _mixer!: AnimationMixer;
164
163
  private _activeState?: State;
165
164
 
166
165
  constructor(model: AnimatorControllerModel) {
@@ -541,10 +540,10 @@
541
540
  private rootMotionHandler?: RootMotionHandler;
542
541
 
543
542
 
544
- // private findRootBone(obj: THREE.Object3D): THREE.Object3D | null {
543
+ // private findRootBone(obj: Object3D): Object3D | null {
545
544
  // if (this.animationRoot) return this.animationRoot;
546
545
  // if (obj.type === "Bone") {
547
- // this.animationRoot = obj as THREE.Bone;
546
+ // this.animationRoot = obj as Bone;
548
547
  // return this.animationRoot;
549
548
  // }
550
549
  // if (obj.children) {
@@ -601,16 +600,16 @@
601
600
 
602
601
  class RootMotionAction {
603
602
 
604
- private static lastObjPosition: { [key: string]: THREE.Vector3 } = {};
605
- static lastObjRotation: { [key: string]: THREE.Quaternion } = {};
603
+ private static lastObjPosition: { [key: string]: Vector3 } = {};
604
+ static lastObjRotation: { [key: string]: Quaternion } = {};
606
605
 
607
606
  // we remove the first keyframe rotation from the space rotation when updating
608
- private static firstKeyframeRotation: { [key: string]: THREE.Quaternion } = {};
607
+ private static firstKeyframeRotation: { [key: string]: Quaternion } = {};
609
608
  // this is used to rotate the space on clip end / start (so the transform direction is correct)
610
- private static spaceRotation: { [key: string]: THREE.Quaternion } = {};
611
- private static effectiveSpaceRotation: { [key: string]: THREE.Quaternion } = {};
609
+ private static spaceRotation: { [key: string]: Quaternion } = {};
610
+ private static effectiveSpaceRotation: { [key: string]: Quaternion } = {};
612
611
 
613
- private static clipOffsetRotation: { [key: string]: THREE.Quaternion } = {};
612
+ private static clipOffsetRotation: { [key: string]: Quaternion } = {};
614
613
 
615
614
 
616
615
  set action(val: AnimationAction) {
@@ -631,14 +630,14 @@
631
630
  positionChange: Vector3 = new Vector3();
632
631
  rotationChange: Quaternion = new Quaternion();
633
632
 
634
- constructor(context: Context, root: THREE.Object3D, clip: AnimationClip, positionTrack: KeyframeTrack | null, rotationTrack: KeyframeTrack | null) {
633
+ constructor(context: Context, root: Object3D, clip: AnimationClip, positionTrack: KeyframeTrack | null, rotationTrack: KeyframeTrack | null) {
635
634
  // console.log(this, positionTrack, rotationTrack);
636
635
  this.context = context;
637
636
  this.root = root;
638
637
  this.clip = clip;
639
638
 
640
639
  if (!RootMotionAction.firstKeyframeRotation[clip.uuid])
641
- RootMotionAction.firstKeyframeRotation[clip.uuid] = new THREE.Quaternion();
640
+ RootMotionAction.firstKeyframeRotation[clip.uuid] = new Quaternion();
642
641
  if (rotationTrack) {
643
642
  const values = rotationTrack.values;
644
643
  RootMotionAction.firstKeyframeRotation[clip.uuid]
@@ -672,7 +671,7 @@
672
671
 
673
672
  if (debugRootMotion)
674
673
  {
675
- const euler = new THREE.Euler().setFromQuaternion(lastRotation);
674
+ const euler = new Euler().setFromQuaternion(lastRotation);
676
675
  console.log("START", this.clip.name, Mathf.toDegrees(euler.y));
677
676
  }
678
677
  }
@@ -799,13 +798,13 @@
799
798
 
800
799
  private controller: AnimatorController;
801
800
  private handler: RootMotionAction[] = [];
802
- private root!: THREE.Object3D;
801
+ private root!: Object3D;
803
802
 
804
803
  constructor(controller: AnimatorController) {
805
804
  this.controller = controller;
806
805
  }
807
806
 
808
- createClip(mixer: AnimationMixer, root: THREE.Object3D, clip: AnimationClip): AnimationAction {
807
+ createClip(mixer: AnimationMixer, root: Object3D, clip: AnimationClip): AnimationAction {
809
808
  this.root = root;
810
809
  let rootName = "";
811
810
  if (root && "name" in root) {
src/engine-components/api.ts CHANGED
@@ -1,1 +1,3 @@
1
+ export * from "./codegen/components";
2
+ export * from "./js-extensions/Object3D";
1
3
  export * from "./ui/PointerEvents"
src/engine/api.ts CHANGED
@@ -3,9 +3,12 @@
3
3
  export * from "./engine_context_registry";
4
4
  export * from "./extensions/extensions"
5
5
  export { InstancingUtil } from "./engine_instancing";
6
+ export * from "./engine_types"
6
7
  export * from "./engine_gameobject";
7
8
  export * from "./engine_components";
8
9
  export * from "./engine_components_internal";
10
+ export * from "./engine_input"
11
+ export * from "./engine_coroutine"
9
12
  export { AssetReference, ImageReference } from "./engine_addressables";
10
13
  export { Context, FrameEvent } from "./engine_setup";
11
14
  export * from "./debug/debug";
@@ -14,7 +17,8 @@
14
17
  export * from "./engine_scenetools";
15
18
  export * from "./engine_math"
16
19
  export * from "./js-extensions"
17
- export { hasProLicense } from "./engine_license"
20
+ export { hasProLicense } from "./engine_license";
21
+ export { syncField } from "./engine_networking_auto";
18
22
 
19
23
  export {
20
24
  // url params
src/engine-components/AudioListener.ts CHANGED
@@ -1,18 +1,18 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
- import * as THREE from "three";
2
+ import { AudioListener as ThreeAudioListener } from "three";
3
3
  import { AudioSource } from "./AudioSource";
4
4
  import { Camera } from "./Camera";
5
5
 
6
6
 
7
7
  export class AudioListener extends Behaviour {
8
8
 
9
- get listener(): THREE.AudioListener {
9
+ get listener(): ThreeAudioListener {
10
10
  if (this._listener == null)
11
- this._listener = new THREE.AudioListener();
11
+ this._listener = new ThreeAudioListener();
12
12
  return this._listener;
13
13
  }
14
14
 
15
- private _listener: THREE.AudioListener | null = null;
15
+ private _listener: ThreeAudioListener | null = null;
16
16
 
17
17
  awake() {
18
18
  AudioSource.registerWaitForAllowAudio(() => {
src/engine-components/AudioSource.ts CHANGED
@@ -1,10 +1,10 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
- import * as THREE from "three";
3
2
  import { PositionalAudioHelper } from 'three/examples/jsm/helpers/PositionalAudioHelper.js';
4
3
  import { AudioListener } from "./AudioListener";
5
4
  import * as utils from "../engine/engine_utils";
6
5
  import { serializable } from "../engine/engine_serialization_decorator";
7
- import { Application, ApplicationEvents } from "../engine/engine_application";
6
+ import { ApplicationEvents } from "../engine/engine_application";
7
+ import { AudioLoader, PositionalAudio } from "three";
8
8
 
9
9
 
10
10
  const debug = utils.getParam("debugaudio");
@@ -146,20 +146,20 @@
146
146
  playInBackground: boolean = true;
147
147
 
148
148
  private _loop: boolean = false;
149
- private sound: THREE.PositionalAudio | null = null;
149
+ private sound: PositionalAudio | null = null;
150
150
  private helper: PositionalAudioHelper | null = null;
151
151
  private wasPlaying = false;
152
- private audioLoader: THREE.AudioLoader | null = null;
152
+ private audioLoader: AudioLoader | null = null;
153
153
  private shouldPlay: boolean = false;
154
154
  // set this from audio context time, used to set clip offset when setting "time" property
155
155
  // there is maybe a better way to set a audio clip current time?!
156
156
  private _lastClipStartedLoading: string | null = null;
157
157
 
158
- public get Sound(): THREE.PositionalAudio | null {
158
+ public get Sound(): PositionalAudio | null {
159
159
  if (!this.sound && AudioSource._userInteractionRegistered) {
160
160
  const listener = GameObject.getComponent(this.context.mainCamera, AudioListener) ?? GameObject.findObjectOfType(AudioListener, this.context);
161
161
  if (listener?.listener) {
162
- this.sound = new THREE.PositionalAudio(listener.listener);
162
+ this.sound = new PositionalAudio(listener.listener);
163
163
  this.gameObject.add(this.sound);
164
164
  }
165
165
  }
@@ -170,7 +170,7 @@
170
170
 
171
171
 
172
172
  awake() {
173
- this.audioLoader = new THREE.AudioLoader();
173
+ this.audioLoader = new AudioLoader();
174
174
  if (this.playOnAwake) this.shouldPlay = true;
175
175
  }
176
176
 
@@ -294,7 +294,7 @@
294
294
  console.log(this.clip);
295
295
  if (this.clip.endsWith(".mp3") || this.clip.endsWith(".wav")) {
296
296
  if (!this.audioLoader)
297
- this.audioLoader = new THREE.AudioLoader();
297
+ this.audioLoader = new AudioLoader();
298
298
  this.shouldPlay = true;
299
299
  if (this._lastClipStartedLoading === this.clip) {
300
300
  if (debug) console.log("Is currently loading:", this._lastClipStartedLoading, this)
src/engine-components/AvatarLoader.ts CHANGED
@@ -1,28 +1,27 @@
1
- import { GLTF, GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
2
- import * as THREE from "three";
1
+ import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
3
2
  import * as utils from "../engine/engine_utils"
4
- // import * as object from "../engine/engine_gltf_builtin_components";
5
3
  import * as loaders from "../engine/engine_loaders"
6
4
  import { Context } from "../engine/engine_setup";
7
5
  import { GameObject } from "./Component";
8
6
  import { download_file } from "../engine/engine_web_api";
9
7
  import { getLoader } from "../engine/engine_gltf";
10
8
  import { InstantiateOptions } from "../engine/engine_gameobject";
9
+ import { Box3, Object3D, Vector3 } from "three";
11
10
 
12
11
  const debug = utils.getParam("debugavatar");
13
12
 
14
13
  export class AvatarModel {
15
- root: THREE.Object3D;
16
- head: THREE.Object3D;
17
- leftHand: THREE.Object3D | null;
18
- rigthHand: THREE.Object3D | null;
14
+ root: Object3D;
15
+ head: Object3D;
16
+ leftHand: Object3D | null;
17
+ rigthHand: Object3D | null;
19
18
 
20
19
 
21
20
  get isValid(): boolean {
22
21
  return this.head !== null && this.head !== undefined;
23
22
  }
24
23
 
25
- constructor(root: THREE.Object3D, head: THREE.Object3D, leftHand: THREE.Object3D | null, rigthHand: THREE.Object3D | null) {
24
+ constructor(root: Object3D, head: Object3D, leftHand: Object3D | null, rigthHand: Object3D | null) {
26
25
  this.root = root;
27
26
  this.head = head;
28
27
  this.leftHand = leftHand;
@@ -40,14 +39,14 @@
40
39
  // private loader: GLTFLoader | null;
41
40
  // private avatarModelCache: Map<string, AvatarModel | null> = new Map<string, AvatarModel | null>();
42
41
 
43
- public async getOrCreateNewAvatarInstance(context: Context, avatarId: string | THREE.Object3D): Promise<AvatarModel | null> {
42
+ public async getOrCreateNewAvatarInstance(context: Context, avatarId: string | Object3D): Promise<AvatarModel | null> {
44
43
 
45
44
  if (!avatarId) {
46
45
  console.error("Can not create avatar: failed to provide id or root object");
47
46
  return null;
48
47
  }
49
48
 
50
- let root: THREE.Object3D | null = null;
49
+ let root: Object3D | null = null;
51
50
  if (typeof avatarId === "string") {
52
51
  root = await this.loadAvatar(context, avatarId);
53
52
  if (!root) {
@@ -77,7 +76,7 @@
77
76
  }
78
77
 
79
78
 
80
- private async loadAvatar(context: Context, avatarId: string): Promise<THREE.Object3D | null> {
79
+ private async loadAvatar(context: Context, avatarId: string): Promise<Object3D | null> {
81
80
 
82
81
  console.assert(avatarId !== undefined && avatarId !== null && typeof avatarId === "string", "Avatar id must not be null");
83
82
  if (avatarId.length <= 0) return null;
@@ -146,9 +145,9 @@
146
145
  }
147
146
 
148
147
  // TODO this should be burned to the ground once 🤞 we have proper extras that define object relations.
149
- private findAvatar(obj: THREE.Object3D): AvatarModel {
148
+ private findAvatar(obj: Object3D): AvatarModel {
150
149
 
151
- const root: THREE.Object3D = obj;
150
+ const root: Object3D = obj;
152
151
  let searchIn = root;
153
152
  // some GLTFs have a "scene" root it seems, others don't, we skip the root here if there's only one child
154
153
  if (searchIn.children.length == 1)
@@ -163,8 +162,8 @@
163
162
  head = root;
164
163
 
165
164
  // normalize size, if the object isn't properly setup the scale might be totally off
166
- const boundsSize = new THREE.Vector3();
167
- new THREE.Box3().setFromObject(head).getSize(boundsSize);
165
+ const boundsSize = new Vector3();
166
+ new Box3().setFromObject(head).getSize(boundsSize);
168
167
  const maxAxis = Math.max(boundsSize.x, boundsSize.y, boundsSize.z);
169
168
  console.warn("[Custom Avatar] " + "Normalizing head scale, it's too big: " + maxAxis + " meters! Should be < 0.3m");
170
169
  if (maxAxis > 0.3) {
@@ -177,7 +176,7 @@
177
176
  }
178
177
 
179
178
 
180
- private findAvatarPart(obj: THREE.Object3D, searchString: string[]): THREE.Object3D | null {
179
+ private findAvatarPart(obj: Object3D, searchString: string[]): Object3D | null {
181
180
 
182
181
  const name = obj.name.toLowerCase();
183
182
  let matchesAll = true;
src/engine-components/AxesHelper.ts CHANGED
@@ -11,7 +11,7 @@
11
11
  @serializable()
12
12
  public isGizmo:boolean = true;
13
13
 
14
- private _axes: THREE.AxesHelper | null = null;
14
+ private _axes: _AxesHelper | null = null;
15
15
 
16
16
  onEnable(): void {
17
17
  if (this.isGizmo && !params.showGizmos) return;
src/engine-components/BasicIKConstraint.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { Behaviour, GameObject } from "./Component";
2
2
  import * as utils from "./../engine/engine_three_utils";
3
- import * as THREE from "three"
3
+ import { Vector3 } from "three";
4
4
 
5
5
  export class BasicIKConstraint extends Behaviour {
6
6
 
@@ -33,7 +33,7 @@
33
33
  let hintDir = utils.getWorldPosition(this.hint).clone();
34
34
  hintDir.sub(center);
35
35
 
36
- let offsetDir = new THREE.Vector3();
36
+ let offsetDir = new Vector3();
37
37
  offsetDir.crossVectors(hintDir, dir0);
38
38
  offsetDir.crossVectors(dir0, offsetDir);
39
39
  offsetDir.normalize();
src/engine-components/BoxHelperComponent.ts CHANGED
@@ -1,28 +1,28 @@
1
1
  import { Behaviour } from "./Component";
2
- import * as THREE from "three";
3
2
  import { getParam } from "../engine/engine_utils";
4
3
  import { CreateWireCube, Gizmos } from "../engine/engine_gizmos";
5
4
  import { getWorldPosition, getWorldScale } from "../engine/engine_three_utils";
5
+ import { Box3, Color, ColorRepresentation, LineSegments, Object3D, Vector3 } from "three";
6
6
 
7
7
  const gizmos = getParam("gizmos");
8
8
  const debug = getParam("debugboxhelper");
9
9
 
10
10
  export class BoxHelperComponent extends Behaviour {
11
11
 
12
- private box: THREE.Box3 | null = null;
13
- private static testBox: THREE.Box3 = new THREE.Box3();
12
+ private box: Box3 | null = null;
13
+ private static testBox: Box3 = new Box3();
14
14
  private _lastMatrixUpdateFrame: number = -1;
15
- private static _position: THREE.Vector3 = new THREE.Vector3();
16
- private static _size: THREE.Vector3 = new THREE.Vector3(.01, .01, .01);
15
+ private static _position: Vector3 = new Vector3();
16
+ private static _size: Vector3 = new Vector3(.01, .01, .01);
17
17
 
18
- public isInBox(obj: THREE.Object3D, scaleFactor?: number): boolean | undefined {
18
+ public isInBox(obj: Object3D, scaleFactor?: number): boolean | undefined {
19
19
  if (!obj) return undefined;
20
20
 
21
21
  // if (!obj.geometry.boundingBox) obj.geometry.computeBoundingBox();
22
22
  // if (!obj.geometry.boundingBox) return undefined;
23
23
 
24
24
  if (!this.box) {
25
- this.box = new THREE.Box3();
25
+ this.box = new Box3();
26
26
  }
27
27
 
28
28
 
@@ -56,14 +56,14 @@
56
56
  return intersects;
57
57
  }
58
58
 
59
- public intersects(box: THREE.Box3): boolean {
59
+ public intersects(box: Box3): boolean {
60
60
  if (!box) return false;
61
61
  return this.updateBox(false).intersectsBox(box);
62
62
  }
63
63
 
64
- public updateBox(force: boolean = false): THREE.Box3 {
64
+ public updateBox(force: boolean = false): Box3 {
65
65
  if (!this.box) {
66
- this.box = new THREE.Box3();
66
+ this.box = new Box3();
67
67
  }
68
68
  if (force || this.context.time.frameCount != this._lastMatrixUpdateFrame) {
69
69
  const firstUpdate = this._lastMatrixUpdateFrame < 0;
@@ -77,8 +77,8 @@
77
77
  }
78
78
 
79
79
 
80
- private _helper: THREE.LineSegments | null = null;
81
- private _color: THREE.Color | null = null;
80
+ private _helper: LineSegments | null = null;
81
+ private _color: Color | null = null;
82
82
 
83
83
  awake(): void {
84
84
  this._helper = null;
@@ -86,7 +86,7 @@
86
86
  this.box = null;
87
87
  }
88
88
 
89
- public showHelper(col: THREE.ColorRepresentation | null = null, force: boolean = false) {
89
+ public showHelper(col: ColorRepresentation | null = null, force: boolean = false) {
90
90
  if (!gizmos && !force) return;
91
91
  if (this._helper) {
92
92
  if (col)
src/engine-components/Component.ts CHANGED
@@ -1,15 +1,14 @@
1
- import * as THREE from "three";
2
1
  import { Mathf } from "../engine/engine_math";
3
2
  import * as threeutils from "../engine/engine_three_utils";
4
3
  import { activeInHierarchyFieldName } from "../engine/engine_constants";
5
4
  import { Context, FrameEvent } from "../engine/engine_setup";
6
5
  import * as main from "../engine/engine_mainloop_utils";
7
- import { Object3D } from "three";
8
6
  import { syncDestroy, syncInstantiate } from "../engine/engine_networking_instantiate";
9
- import { ConstructorConcrete, SourceIdentifier, IComponent, IGameObject, Constructor, GuidsMap, UIDProvider, Collision, ICollider } from "../engine/engine_types";
7
+ import { ConstructorConcrete, SourceIdentifier, IComponent, IGameObject, Constructor, GuidsMap, Collision, ICollider } from "../engine/engine_types";
10
8
  import { addNewComponent, destroyComponentInstance, findObjectOfType, findObjectsOfType, getComponent, getComponentInChildren, getComponentInParent, getComponents, getComponentsInChildren, getComponentsInParent, getOrAddComponent, moveComponentInstance, removeComponent } from "../engine/engine_components";
11
9
  import { findByGuid, destroy, InstantiateOptions, instantiate, HideFlags, foreachComponent, markAsInstancedRendered, isActiveInHierarchy, isActiveSelf, isUsingInstancing, setActive, isDestroyed } from "../engine/engine_gameobject";
12
10
 
11
+ import { Euler, Object3D, Quaternion, Scene, Vector3 } from "three";
13
12
 
14
13
  // export interface ISerializationCallbackReceiver {
15
14
  // onBeforeSerialize?(): object | void;
@@ -19,7 +18,7 @@
19
18
  // onDeserialize?(key: string, value: any): any | void;
20
19
  // }
21
20
 
22
- abstract class GameObject extends THREE.Object3D implements THREE.Object3D, IGameObject {
21
+ abstract class GameObject extends Object3D implements Object3D, IGameObject {
23
22
 
24
23
  guid: string | undefined;
25
24
 
@@ -27,13 +26,13 @@
27
26
  abstract destroy();
28
27
 
29
28
  // The actual implementation / prototype of threejs is modified in js-extensions/Object3D
30
- abstract get transform(): THREE.Object3D;
29
+ abstract get transform(): Object3D;
31
30
 
32
- public static isDestroyed(go: THREE.Object3D): boolean {
31
+ public static isDestroyed(go: Object3D): boolean {
33
32
  return isDestroyed(go);
34
33
  }
35
34
 
36
- public static setActive(go: THREE.Object3D, active: boolean, processStart: boolean = true) {
35
+ public static setActive(go: Object3D, active: boolean, processStart: boolean = true) {
37
36
  if (!go) return;
38
37
  setActive(go, active);
39
38
 
@@ -44,29 +43,29 @@
44
43
  }
45
44
 
46
45
  /** If the object is active (same as go.visible) */
47
- public static isActiveSelf(go: THREE.Object3D): boolean {
46
+ public static isActiveSelf(go: Object3D): boolean {
48
47
  return isActiveSelf(go);
49
48
  }
50
49
 
51
50
  /** If the object is active in the hierarchy (e.g. if any parent is invisible or not in the scene it will be false)
52
51
  * @param go object to check
53
52
  */
54
- public static isActiveInHierarchy(go: THREE.Object3D): boolean {
53
+ public static isActiveInHierarchy(go: Object3D): boolean {
55
54
  return isActiveInHierarchy(go);
56
55
  }
57
56
 
58
- public static markAsInstancedRendered(go: THREE.Object3D, instanced: boolean) {
57
+ public static markAsInstancedRendered(go: Object3D, instanced: boolean) {
59
58
  markAsInstancedRendered(go, instanced);
60
59
  }
61
60
 
62
- public static isUsingInstancing(instance: THREE.Object3D): boolean { return isUsingInstancing(instance); }
61
+ public static isUsingInstancing(instance: Object3D): boolean { return isUsingInstancing(instance); }
63
62
 
64
63
  /** Run a callback for all components of the provided type on the provided object and its children (if recursive is true)
65
64
  * @param instance object to run the method on
66
65
  * @param cb callback to run on each component
67
66
  * @param recursive if true, the method will be run on all children as well
68
67
  */
69
- public static foreachComponent(instance: THREE.Object3D, cb: (comp: Component) => any, recursive: boolean = true): any {
68
+ public static foreachComponent(instance: Object3D, cb: (comp: Component) => any, recursive: boolean = true): any {
70
69
  return foreachComponent(instance, cb as (comp: IComponent) => any, recursive);
71
70
  }
72
71
 
@@ -90,7 +89,7 @@
90
89
  /** Destroys a object on all connected clients (if you are in a networked session)
91
90
  * @param instance object to destroy
92
91
  */
93
- public static destroySynced(instance: THREE.Object3D | Component, context?: Context, recursive: boolean = true) {
92
+ public static destroySynced(instance: Object3D | Component, context?: Context, recursive: boolean = true) {
94
93
  if (!instance) return;
95
94
  const go = instance as GameObject;
96
95
  context = context ?? Context.Current;
@@ -101,14 +100,14 @@
101
100
  * @param instance object to destroy
102
101
  * @param recursive if true, all children will be destroyed as well
103
102
  */
104
- public static destroy(instance: THREE.Object3D | Component, recursive: boolean = true, isRoot: boolean = true) {
103
+ public static destroy(instance: Object3D | Component, recursive: boolean = true, isRoot: boolean = true) {
105
104
  return destroy(instance, recursive, isRoot);
106
105
  }
107
106
 
108
107
  /**
109
108
  * Add an object to parent and also ensure all components are being registered
110
109
  */
111
- public static add(instance: THREE.Object3D | null | undefined, parent: THREE.Object3D, context?: Context) {
110
+ public static add(instance: Object3D | null | undefined, parent: Object3D, context?: Context) {
112
111
  if (!instance || !parent) return;
113
112
  if (instance === parent) {
114
113
  console.warn("Can not add object to self", instance);
@@ -137,7 +136,7 @@
137
136
  /**
138
137
  * Removes the object from its parent and deactivates all of its components
139
138
  */
140
- public static remove(instance: THREE.Object3D | null | undefined) {
139
+ public static remove(instance: Object3D | null | undefined) {
141
140
  if (!instance) return;
142
141
  instance.parent?.remove(instance);
143
142
  setActive(instance, false);
@@ -148,7 +147,7 @@
148
147
  }
149
148
 
150
149
  /** Invokes a method on all components including children (if a method with that name exists) */
151
- public static invokeOnChildren(go: THREE.Object3D | null | undefined, functionName: string, ...args: any) {
150
+ public static invokeOnChildren(go: Object3D | null | undefined, functionName: string, ...args: any) {
152
151
  this.invoke(go, functionName, true, args);
153
152
  }
154
153
 
@@ -156,7 +155,7 @@
156
155
  * @param go object to invoke the method on all components
157
156
  * @param functionName name of the method to invoke
158
157
  */
159
- public static invoke(go: THREE.Object3D | null | undefined, functionName: string, children: boolean = false, ...args: any) {
158
+ public static invoke(go: Object3D | null | undefined, functionName: string, children: boolean = false, ...args: any) {
160
159
  if (!go) return;
161
160
  this.foreachComponent(go, c => {
162
161
  const fn = c[functionName];
@@ -172,7 +171,7 @@
172
171
  * @param type type of the component to add
173
172
  * @param callAwake if true, the component will be added and awake will be called immediately
174
173
  */
175
- public static addNewComponent<T>(go: GameObject | THREE.Object3D, type: ConstructorConcrete<T>, callAwake: boolean = true): T {
174
+ public static addNewComponent<T>(go: IGameObject | Object3D, type: ConstructorConcrete<T>, callAwake: boolean = true): T {
176
175
  const instance = new type();
177
176
  //@ts-ignore
178
177
  addNewComponent(go, instance, callAwake);
@@ -185,7 +184,7 @@
185
184
  * @param go component to move the component to
186
185
  * @param instance component to move to the GO
187
186
  */
188
- public static addComponent(go: GameObject, instance: Component): void {
187
+ public static addComponent(go: IGameObject, instance: Component): void {
189
188
  return this.moveComponent(go, instance);
190
189
  }
191
190
 
@@ -194,7 +193,7 @@
194
193
  * @param go component to move the component to
195
194
  * @param instance component to move to the GO
196
195
  */
197
- public static moveComponent(go: GameObject, instance: Component): void {
196
+ public static moveComponent(go: IGameObject, instance: Component): void {
198
197
  if (instance.gameObject == null) {
199
198
  throw new Error("Did you mean to create a new component? Use addNewComponent");
200
199
  }
@@ -209,12 +208,12 @@
209
208
  return instance;
210
209
  }
211
210
 
212
- public static getOrAddComponent<T>(go: GameObject | THREE.Object3D, typeName: ConstructorConcrete<T>): T {
211
+ public static getOrAddComponent<T>(go: IGameObject | Object3D, typeName: ConstructorConcrete<T>): T {
213
212
  return getOrAddComponent<any>(go, typeName);
214
213
  }
215
214
 
216
215
  /** Gets a component on the provided object */
217
- public static getComponent<T>(go: GameObject | THREE.Object3D | null, typeName: Constructor<T> | null): T | null {
216
+ public static getComponent<T>(go: IGameObject | Object3D | null, typeName: Constructor<T> | null): T | null {
218
217
  if (go === null) return null;
219
218
  // if names are minified we could also use the type store and work with strings everywhere
220
219
  // not ideal, but I dont know a good/sane way to do this otherwise
@@ -223,49 +222,49 @@
223
222
  return getComponent(go, typeName as any);
224
223
  }
225
224
 
226
- public static getComponents<T>(go: GameObject | THREE.Object3D | null, typeName: Constructor<T>, arr: T[] | null = null): T[] {
225
+ public static getComponents<T>(go: IGameObject | Object3D | null, typeName: Constructor<T>, arr: T[] | null = null): T[] {
227
226
  if (go === null) return arr ?? [];
228
227
  return getComponents(go, typeName, arr);
229
228
  }
230
229
 
231
- public static findByGuid(guid: string, hierarchy: THREE.Object3D): GameObject | Component | null | undefined {
230
+ public static findByGuid(guid: string, hierarchy: Object3D): GameObject | Component | null | undefined {
232
231
  const res = findByGuid(guid, hierarchy);
233
232
  return res as GameObject | Component | null | undefined;
234
233
  }
235
234
 
236
- public static findObjectOfType<T>(typeName: Constructor<T>, context?: Context | THREE.Object3D, includeInactive: boolean = true): T | null {
235
+ public static findObjectOfType<T>(typeName: Constructor<T>, context?: Context | Object3D, includeInactive: boolean = true): T | null {
237
236
  return findObjectOfType(typeName, context ?? Context.Current, includeInactive);
238
237
  }
239
238
 
240
- public static findObjectsOfType<T>(typeName: Constructor<T>, context?: Context | THREE.Object3D): Array<T> {
239
+ public static findObjectsOfType<T>(typeName: Constructor<T>, context?: Context | Object3D): Array<T> {
241
240
  const arr = [];
242
241
  findObjectsOfType(typeName, arr, context);
243
242
  return arr;
244
243
  }
245
244
 
246
- public static getComponentInChildren<T>(go: GameObject | THREE.Object3D, typeName: Constructor<T>): T | null {
245
+ public static getComponentInChildren<T>(go: IGameObject | Object3D, typeName: Constructor<T>): T | null {
247
246
  return getComponentInChildren(go, typeName);
248
247
  }
249
248
 
250
- public static getComponentsInChildren<T>(go: GameObject | THREE.Object3D, typeName: Constructor<T>, arr: T[] | null = null): Array<T> {
249
+ public static getComponentsInChildren<T>(go: IGameObject | Object3D, typeName: Constructor<T>, arr: T[] | null = null): Array<T> {
251
250
  return getComponentsInChildren<T>(go, typeName, arr ?? undefined) as T[]
252
251
  }
253
252
 
254
- public static getComponentInParent<T>(go: GameObject | THREE.Object3D, typeName: Constructor<T>): T | null {
253
+ public static getComponentInParent<T>(go: IGameObject | Object3D, typeName: Constructor<T>): T | null {
255
254
  return getComponentInParent(go, typeName);
256
255
  }
257
256
 
258
- public static getComponentsInParent<T>(go: GameObject | THREE.Object3D, typeName: Constructor<T>, arr: Array<T> | null = null): Array<T> {
257
+ public static getComponentsInParent<T>(go: IGameObject | Object3D, typeName: Constructor<T>, arr: Array<T> | null = null): Array<T> {
259
258
  return getComponentsInParent(go, typeName, arr);
260
259
  }
261
260
 
262
- public static getAllComponents(go: GameObject | THREE.Object3D): Behaviour[] {
261
+ public static getAllComponents(go: IGameObject | Object3D): Behaviour[] {
263
262
  const componentsList = go.userData?.components;
264
263
  const newList = [...componentsList];
265
264
  return newList;
266
265
  }
267
266
 
268
- public static *iterateComponents(go: GameObject | THREE.Object3D) {
267
+ public static *iterateComponents(go: IGameObject | Object3D) {
269
268
  const list = go?.userData?.components;
270
269
  if (list && Array.isArray(list)) {
271
270
  for (let i = 0; i < list.length; i++) {
@@ -300,7 +299,7 @@
300
299
  set context(context: Context) {
301
300
  this.__context = context;
302
301
  }
303
- get scene(): THREE.Scene { return this.context.scene; }
302
+ get scene(): Scene { return this.context.scene; }
304
303
 
305
304
  get layer(): number {
306
305
  return this.gameObject?.userData?.layer;
@@ -367,7 +366,7 @@
367
366
  gameObject!: GameObject;
368
367
  guid: string = "invalid";
369
368
  sourceId?: SourceIdentifier;
370
- // transform: THREE.Object3D = nullObject;
369
+ // transform: Object3D = nullObject;
371
370
 
372
371
  /** called on a component with a map of old to new guids (e.g. when instantiate generated new guids and e.g. timeline track bindings needs to remape them) */
373
372
  resolveGuids?(guidsMap: GuidsMap): void;
@@ -521,24 +520,24 @@
521
520
 
522
521
  // TODO move this to threeutils
523
522
  // we need a copy for modifying the values to local space
524
- private static _worldPositionBuffer: THREE.Vector3 = new THREE.Vector3();
525
- private static _worldQuaternionBuffer: THREE.Quaternion = new THREE.Quaternion();
526
- private static _worldEulerBuffer: THREE.Euler = new THREE.Euler();
523
+ private static _worldPositionBuffer: Vector3 = new Vector3();
524
+ private static _worldQuaternionBuffer: Quaternion = new Quaternion();
525
+ private static _worldEulerBuffer: Euler = new Euler();
527
526
 
528
- private _worldPosition: THREE.Vector3 | undefined = undefined;
529
- private _worldQuaternion: THREE.Quaternion | undefined = undefined;
530
- private static _tempQuaternionBuffer2: THREE.Quaternion = new THREE.Quaternion();
531
- private _worldEuler: THREE.Euler | undefined = undefined;
532
- private _worldRotation: THREE.Vector3 | undefined = undefined;
527
+ private _worldPosition: Vector3 | undefined = undefined;
528
+ private _worldQuaternion: Quaternion | undefined = undefined;
529
+ private static _tempQuaternionBuffer2: Quaternion = new Quaternion();
530
+ private _worldEuler: Euler | undefined = undefined;
531
+ private _worldRotation: Vector3 | undefined = undefined;
533
532
 
534
- get worldPosition(): THREE.Vector3 {
535
- if (!this._worldPosition) this._worldPosition = new THREE.Vector3();
533
+ get worldPosition(): Vector3 {
534
+ if (!this._worldPosition) this._worldPosition = new Vector3();
536
535
  threeutils.getWorldPosition(this.gameObject, this._worldPosition);
537
536
  // this.gameObject.getWorldPosition(this._worldPosition);
538
537
  return this._worldPosition;
539
538
  }
540
539
 
541
- set worldPosition(val: THREE.Vector3) {
540
+ set worldPosition(val: Vector3) {
542
541
  threeutils.setWorldPosition(this.gameObject, val);
543
542
  }
544
543
 
@@ -548,11 +547,11 @@
548
547
  }
549
548
 
550
549
 
551
- get worldQuaternion(): THREE.Quaternion {
552
- if (!this._worldQuaternion) this._worldQuaternion = new THREE.Quaternion();
550
+ get worldQuaternion(): Quaternion {
551
+ if (!this._worldQuaternion) this._worldQuaternion = new Quaternion();
553
552
  return threeutils.getWorldQuaternion(this.gameObject, this._worldQuaternion);
554
553
  }
555
- set worldQuaternion(val: THREE.Quaternion) {
554
+ set worldQuaternion(val: Quaternion) {
556
555
  threeutils.setWorldQuaternion(this.gameObject, val);
557
556
  }
558
557
  setWorldQuaternion(x: number, y: number, z: number, w: number) {
@@ -562,23 +561,23 @@
562
561
 
563
562
 
564
563
  // world euler (in radians)
565
- get worldEuler(): THREE.Euler {
566
- if (!this._worldEuler) this._worldEuler = new THREE.Euler();
564
+ get worldEuler(): Euler {
565
+ if (!this._worldEuler) this._worldEuler = new Euler();
567
566
  this._worldEuler.setFromQuaternion(this.worldQuaternion);
568
567
  return this._worldEuler;
569
568
  }
570
569
 
571
570
  // world euler (in radians)
572
- set worldEuler(val: THREE.Euler) {
573
- if (!this._worldQuaternion) this._worldQuaternion = new THREE.Quaternion();
571
+ set worldEuler(val: Euler) {
572
+ if (!this._worldQuaternion) this._worldQuaternion = new Quaternion();
574
573
  this._worldQuaternion?.setFromEuler(val);
575
574
  this.worldQuaternion = this._worldQuaternion;
576
575
  }
577
576
 
578
577
  // returns rotation in degrees
579
- get worldRotation(): THREE.Vector3 {
578
+ get worldRotation(): Vector3 {
580
579
  const rot = this.worldEuler;
581
- if (!this._worldRotation) this._worldRotation = new THREE.Vector3();
580
+ if (!this._worldRotation) this._worldRotation = new Vector3();
582
581
  const wr = this._worldRotation;
583
582
  wr.set(rot.x, rot.y, rot.z);
584
583
  wr.x = Mathf.toDegrees(wr.x);
@@ -587,7 +586,7 @@
587
586
  return wr;
588
587
  }
589
588
 
590
- set worldRotation(val: THREE.Vector3) {
589
+ set worldRotation(val: Vector3) {
591
590
  this.setWorldRotation(val.x, val.y, val.z, true);
592
591
  }
593
592
 
@@ -602,16 +601,16 @@
602
601
  this.worldQuaternion = Component._worldQuaternionBuffer;
603
602
  }
604
603
 
605
- private static _forward: THREE.Vector3 = new THREE.Vector3();
606
- public get forward(): THREE.Vector3 {
604
+ private static _forward: Vector3 = new Vector3();
605
+ public get forward(): Vector3 {
607
606
  return Component._forward.set(0, 0, -1).applyQuaternion(this.worldQuaternion);
608
607
  }
609
- private static _right: THREE.Vector3 = new THREE.Vector3();
610
- public get right(): THREE.Vector3 {
608
+ private static _right: Vector3 = new Vector3();
609
+ public get right(): Vector3 {
611
610
  return Component._right.set(1, 0, 0).applyQuaternion(this.worldQuaternion);
612
611
  }
613
- private static _up: THREE.Vector3 = new THREE.Vector3();
614
- public get up(): THREE.Vector3 {
612
+ private static _up: Vector3 = new Vector3();
613
+ public get up(): Vector3 {
615
614
  return Component._up.set(0, 1, 0).applyQuaternion(this.worldQuaternion);
616
615
  }
617
616
 
src/engine-components/DragControls.ts CHANGED
@@ -1,19 +1,18 @@
1
- import { Behaviour, GameObject } from "./Component";
2
- // import { DragControls as Control } from "../include/three/DragControls";
1
+ import { GameObject } from "./Component";
3
2
  import { SyncedTransform } from "./SyncedTransform";
4
- import * as THREE from "three";
5
- import { IPointerClickHandler, IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler, PointerEventData } from "./ui/PointerEvents";
3
+ import { IPointerDownHandler, IPointerEnterHandler, IPointerExitHandler, IPointerUpHandler, PointerEventData } from "./ui/PointerEvents";
6
4
  import { Context } from "../engine/engine_setup";
7
5
  import { Interactable, UsageMarker } from "./Interactable";
8
6
  import { Rigidbody } from "./RigidBody";
9
7
  import { WebXR } from "./WebXR";
10
8
  import { Avatar_POI } from "./avatar/Avatar_Brain_LookAt";
11
9
  import { RaycastOptions } from "../engine/engine_physics";
12
- import { getWorldPosition, getWorldQuaternion, setWorldPosition } from "../engine/engine_three_utils";
10
+ import { getWorldPosition, setWorldPosition } from "../engine/engine_three_utils";
13
11
  import { KeyCode } from "../engine/engine_input";
14
12
  import { nameofFactory } from "../engine/engine_utils";
15
13
  import { InstancingUtil } from "../engine/engine_instancing";
16
14
  import { OrbitControls } from "./OrbitControls";
15
+ import { BufferGeometry, Camera, Color, Line, LineBasicMaterial, Matrix4, Mesh, MeshBasicMaterial, Object3D, Plane, Ray, Raycaster, SphereGeometry, Vector2, Vector3 } from "three";
17
16
 
18
17
  const debug = false;
19
18
 
@@ -23,8 +22,8 @@
23
22
  }
24
23
 
25
24
  interface SelectArgs {
26
- selected: THREE.Object3D;
27
- attached: THREE.Object3D | GameObject | null;
25
+ selected: Object3D;
26
+ attached: Object3D | GameObject | null;
28
27
  }
29
28
 
30
29
 
@@ -41,7 +40,7 @@
41
40
 
42
41
  public transformSelf: boolean = true;
43
42
  // public transformGroup: boolean = true;
44
- // public targets: THREE.Object3D[] | null = null;
43
+ // public targets: Object3D[] | null = null;
45
44
 
46
45
  // private controls: Control | null = null;
47
46
  private orbit: OrbitControls | null = null;
@@ -53,7 +52,7 @@
53
52
  super();
54
53
  this.selectStartEventListener = [];
55
54
  this.selectEndEventListener = [];
56
- this._dragDelta = new THREE.Vector2();
55
+ this._dragDelta = new Vector2();
57
56
  }
58
57
 
59
58
  addDragEventListener(type: DragEvents, cb: (ctrls: DragControls, args: SelectArgs) => void | Function) {
@@ -74,10 +73,10 @@
74
73
  this.orbit = GameObject.findObjectOfType(OrbitControls, this.context);
75
74
  }
76
75
 
77
- private static lastHovered: THREE.Object3D;
76
+ private static lastHovered: Object3D;
78
77
  private _draggingRigidbodies: Rigidbody[] = [];
79
78
 
80
- private allowEdit(_obj: THREE.Object3D | null = null) {
79
+ private allowEdit(_obj: Object3D | null = null) {
81
80
  return this.context.connection.allowEditing;
82
81
  }
83
82
 
@@ -160,7 +159,7 @@
160
159
 
161
160
  private _isDragging: boolean = false;
162
161
  private _marker: UsageMarker | null = null;
163
- private _dragDelta!: THREE.Vector2;
162
+ private _dragDelta!: Vector2;
164
163
  private _didDrag: boolean = false;
165
164
  private _activePointerId?: number;
166
165
 
@@ -177,14 +176,14 @@
177
176
  if (!dc || dc !== this) return;
178
177
 
179
178
 
180
- let object: THREE.Object3D = evt.object;
179
+ let object: Object3D = evt.object;
181
180
 
182
181
  if (this.transformSelf) {
183
182
  object = this.gameObject;
184
183
  }
185
184
 
186
185
  // raise event
187
- const args: { selected: THREE.Object3D, attached: THREE.Object3D | null } = { selected: object, attached: object };
186
+ const args: { selected: Object3D, attached: Object3D | null } = { selected: object, attached: object };
188
187
  for (const listener of this.selectStartEventListener) {
189
188
  listener(this, args);
190
189
  }
@@ -285,54 +284,54 @@
285
284
  return this._selected !== null && this._selected !== undefined;
286
285
  }
287
286
 
288
- public get selected(): THREE.Object3D | null {
287
+ public get selected(): Object3D | null {
289
288
  return this._selected;
290
289
  }
291
290
 
292
- private _selected: THREE.Object3D | null = null;
291
+ private _selected: Object3D | null = null;
293
292
  private _context: Context | null = null;
294
- private _camera: THREE.Camera;;
295
- private _cameraPlane: THREE.Plane = new THREE.Plane();
293
+ private _camera: Camera;
294
+ private _cameraPlane: Plane = new Plane();
296
295
 
297
296
  private _hasGroundPlane: boolean = false;
298
- private _groundPlane: THREE.Plane = new THREE.Plane();
299
- private _groundOffset: THREE.Vector3 = new THREE.Vector3();
297
+ private _groundPlane: Plane = new Plane();
298
+ private _groundOffset: Vector3 = new Vector3();
300
299
  private _groundOffsetFactor: number = 0;
301
300
  private _groundDistance: number = 0;
302
- private _groundPlanePoint: THREE.Vector3 = new THREE.Vector3();
301
+ private _groundPlanePoint: Vector3 = new Vector3();
303
302
 
304
- private _raycaster = new THREE.Raycaster();
305
- private _cameraPlaneOffset = new THREE.Vector3();
306
- private _intersection = new THREE.Vector3();
307
- private _worldPosition = new THREE.Vector3();
308
- private _inverseMatrix = new THREE.Matrix4();
303
+ private _raycaster = new Raycaster();
304
+ private _cameraPlaneOffset = new Vector3();
305
+ private _intersection = new Vector3();
306
+ private _worldPosition = new Vector3();
307
+ private _inverseMatrix = new Matrix4();
309
308
  private _rbs: Rigidbody[] = [];
310
309
 
311
- private _groundLine: THREE.Line;
312
- private _groundMarker: THREE.Object3D;
313
- private static geometry = new THREE.BufferGeometry().setFromPoints([new THREE.Vector3(0, 0, 0), new THREE.Vector3(0, -1, 0)]);
310
+ private _groundLine: Line;
311
+ private _groundMarker: Object3D;
312
+ private static geometry = new BufferGeometry().setFromPoints([new Vector3(0, 0, 0), new Vector3(0, -1, 0)]);
314
313
 
315
- constructor(camera: THREE.Camera) {
314
+ constructor(camera: Camera) {
316
315
  this._camera = camera;
317
316
 
318
- const line = new THREE.Line(DragHelper.geometry);
319
- const mat = line.material as THREE.LineBasicMaterial;
320
- mat.color = new THREE.Color(.4, .4, .4);
317
+ const line = new Line(DragHelper.geometry);
318
+ const mat = line.material as LineBasicMaterial;
319
+ mat.color = new Color(.4, .4, .4);
321
320
  line.layers.set(2);
322
321
  line.name = 'line';
323
322
  line.scale.y = 1;
324
323
  // line.matrixAutoUpdate = false;
325
324
  this._groundLine = line;
326
325
 
327
- const geometry = new THREE.SphereGeometry(.5, 22, 22);
328
- const material = new THREE.MeshBasicMaterial({ color: mat.color });
329
- const sphere = new THREE.Mesh(geometry, material);
326
+ const geometry = new SphereGeometry(.5, 22, 22);
327
+ const material = new MeshBasicMaterial({ color: mat.color });
328
+ const sphere = new Mesh(geometry, material);
330
329
  sphere.visible = false;
331
330
  sphere.layers.set(2);
332
331
  this._groundMarker = sphere;
333
332
  }
334
333
 
335
- setSelected(newSelected: THREE.Object3D | null, context: Context) {
334
+ setSelected(newSelected: Object3D | null, context: Context) {
336
335
  if (this._selected && context) {
337
336
  for (const rb of this._rbs) {
338
337
  rb.wakeUp();
@@ -376,7 +375,7 @@
376
375
  }
377
376
  }
378
377
 
379
- private _groundOffsetVector = new THREE.Vector3(0, 1, 0);
378
+ private _groundOffsetVector = new Vector3(0, 1, 0);
380
379
  private _requireUpdateGroundPlane = true;
381
380
  private _didDragOnGroundPlaneLastFrame: boolean = false;
382
381
 
@@ -429,7 +428,7 @@
429
428
  this._requireUpdateGroundPlane = false;
430
429
  if (this._hasGroundPlane) {
431
430
  // const wp = getWorldPosition(this._selected);
432
- // const ray = new THREE.Ray(wp, new THREE.Vector3(0, -1, 0));
431
+ // const ray = new Ray(wp, new Vector3(0, -1, 0));
433
432
 
434
433
  if (this._raycaster.ray.intersectPlane(this._groundPlane, this._intersection)) {
435
434
  const y = this._intersection.y;
@@ -466,7 +465,7 @@
466
465
  }
467
466
  }
468
467
 
469
- private onUpdateWorldPosition(wp: THREE.Vector3, pointOnPlane: THREE.Vector3 | null, heightOnly: boolean) {
468
+ private onUpdateWorldPosition(wp: Vector3, pointOnPlane: Vector3 | null, heightOnly: boolean) {
470
469
  if (!this._selected) return;
471
470
  if (heightOnly) {
472
471
  const cur = getWorldPosition(this._selected);
@@ -503,7 +502,7 @@
503
502
  private onUpdateGroundPlane() {
504
503
  if (!this._selected || !this._context) return;
505
504
  const wp = getWorldPosition(this._selected);
506
- const ray = new THREE.Ray(new THREE.Vector3(0, .1, 0).add(wp), new THREE.Vector3(0, -1, 0));
505
+ const ray = new Ray(new Vector3(0, .1, 0).add(wp), new Vector3(0, -1, 0));
507
506
  const opts = new RaycastOptions();
508
507
  opts.ignore = [this._selected];
509
508
  const hits = this._context.physics.raycastFromRay(ray, opts);
@@ -512,7 +511,7 @@
512
511
  if (!hit.face || this.contains(this._selected, hit.object)) {
513
512
  continue;
514
513
  }
515
- const normal = new THREE.Vector3(0, 1, 0); // hit.face.normal
514
+ const normal = new Vector3(0, 1, 0); // hit.face.normal
516
515
  this._groundPlane.setFromNormalAndCoplanarPoint(normal, hit.point);
517
516
  break;
518
517
  }
@@ -536,7 +535,7 @@
536
535
  }
537
536
  }
538
537
 
539
- private contains(obj: THREE.Object3D, toSearch: THREE.Object3D): boolean {
538
+ private contains(obj: Object3D, toSearch: Object3D): boolean {
540
539
  if (obj === toSearch) return true;
541
540
  if (obj.children) {
542
541
  for (const child of obj.children) {
src/engine/engine_addressables.ts CHANGED
@@ -1,11 +1,10 @@
1
1
  import { getParam, resolveUrl } from "../engine/engine_utils";
2
- // import { loadSync, parseSync } from "./engine_scenetools";
3
2
  import { SerializationContext, TypeSerializer } from "./engine_serialization_core";
4
3
  import { Context } from "./engine_setup";
5
- import { Group, Object3D, Scene, Texture } from "three";
4
+ import { Group, Object3D, Texture } from "three";
6
5
  import { processNewScripts } from "./engine_mainloop_utils";
7
6
  import { registerPrefabProvider, syncInstantiate } from "./engine_networking_instantiate";
8
- import { download, hash } from "./engine_web_api";
7
+ import { download } from "./engine_web_api";
9
8
  import { getLoader } from "./engine_gltf";
10
9
  import { SourceIdentifier } from "./engine_types";
11
10
  import { destroy, instantiate, InstantiateOptions, isDestroyed } from "./engine_gameobject";
@@ -185,11 +184,11 @@
185
184
  }
186
185
  }
187
186
 
188
- async instantiate(parent?: THREE.Object3D | InstantiateOptions) {
187
+ async instantiate(parent?: Object3D | InstantiateOptions) {
189
188
  return this.onInstantiate(parent, false);
190
189
  }
191
190
 
192
- async instantiateSynced(parent?: THREE.Object3D | InstantiateOptions, saveOnServer: boolean = true) {
191
+ async instantiateSynced(parent?: Object3D | InstantiateOptions, saveOnServer: boolean = true) {
193
192
  return this.onInstantiate(parent, true, saveOnServer);
194
193
  }
195
194
 
@@ -211,7 +210,7 @@
211
210
  }
212
211
  }
213
212
 
214
- private async onInstantiate(parent?: THREE.Object3D | InstantiateOptions, networked: boolean = false, saveOnServer?: boolean) {
213
+ private async onInstantiate(parent?: Object3D | InstantiateOptions, networked: boolean = false, saveOnServer?: boolean) {
215
214
  const context = Context.Current;
216
215
  if (!parent) parent = context.scene;
217
216
  if (this.mustLoad) {
@@ -282,7 +281,7 @@
282
281
  * and call destroy on the player marker root
283
282
  * @returns the scene root object if the asset was a glb/gltf
284
283
  */
285
- private tryGetActualGameObjectRoot(asset: any): THREE.Object3D | null {
284
+ private tryGetActualGameObjectRoot(asset: any): Object3D | null {
286
285
  if (asset && asset.scene) {
287
286
  // some exporters produce additional root objects
288
287
  const scene = asset.scene as Group;
src/engine/engine_context.ts CHANGED
@@ -1,5 +1,8 @@
1
- import { Camera, Clock, DepthTexture, PerspectiveCamera, WebGLRenderer, WebGLRenderTarget } from 'three'
2
- import * as THREE from 'three'
1
+ import { BufferGeometry, Camera, Clock, Color, DepthTexture, Group,
2
+ Material, NearestFilter, NoToneMapping, Object3D, PCFSoftShadowMap,
3
+ PerspectiveCamera, RGBAFormat, Scene, sRGBEncoding,
4
+ Texture, WebGLRenderer, WebGLRenderTarget
5
+ } from 'three'
3
6
  import { Input } from './engine_input';
4
7
  import { Physics } from './engine_physics';
5
8
  import { Time } from './engine_time';
@@ -50,7 +53,7 @@
50
53
  name?: string;
51
54
  alias?: string;
52
55
  domElement: HTMLElement | null;
53
- renderer?: THREE.WebGLRenderer = undefined;
56
+ renderer?: WebGLRenderer = undefined;
54
57
  hash?: string;
55
58
 
56
59
  constructor(domElement: HTMLElement | null) {
@@ -74,7 +77,7 @@
74
77
  ImmersiveAR = "immersive-ar",
75
78
  }
76
79
 
77
- export declare type OnBeforeRenderCallback = (renderer: THREE.WebGLRenderer, scene: THREE.Scene, camera: THREE.Camera, geometry: THREE.BufferGeometry, material: THREE.Material, group: THREE.Group) => void
80
+ export declare type OnBeforeRenderCallback = (renderer: WebGLRenderer, scene: Scene, camera: Camera, geometry: BufferGeometry, material: Material, group: Group) => void
78
81
 
79
82
 
80
83
  export function registerComponent(script: IComponent, context?: Context) {
@@ -175,8 +178,8 @@
175
178
  }
176
179
  private _currentFrameEvent: FrameEvent = FrameEvent.Undefined;
177
180
 
178
- scene: THREE.Scene;
179
- renderer: THREE.WebGLRenderer;
181
+ scene: Scene;
182
+ renderer: WebGLRenderer;
180
183
  composer: EffectComposer | null = null;
181
184
 
182
185
  // all scripts
@@ -191,7 +194,7 @@
191
194
  scripts_WithCorroutines: IComponent[] = [];
192
195
  coroutines: { [FrameEvent: number]: Array<CoroutineData> } = {}
193
196
 
194
- get mainCamera(): THREE.Camera | null {
197
+ get mainCamera(): Camera | null {
195
198
  if (this.mainCameraComponent) {
196
199
  const cam = this.mainCameraComponent as ICamera;
197
200
  if (!cam.cam)
@@ -251,21 +254,21 @@
251
254
 
252
255
  // some tonemapping other than "NONE" is required for adjusting exposure with EXR environments
253
256
  this.renderer.toneMappingExposure = 1; // range [0...inf] instead of the usual -15..15
254
- this.renderer.toneMapping = THREE.NoToneMapping; // could also set to LinearToneMapping, ACESFilmicToneMapping
257
+ this.renderer.toneMapping = NoToneMapping; // could also set to LinearToneMapping, ACESFilmicToneMapping
255
258
 
256
- this.renderer.setClearColor(new THREE.Color('lightgrey'), 0);
259
+ this.renderer.setClearColor(new Color('lightgrey'), 0);
257
260
  // @ts-ignore
258
261
  this.renderer.antialias = true;
259
262
  // @ts-ignore
260
263
  this.renderer.alpha = false;
261
264
  this.renderer.shadowMap.enabled = true;
262
- this.renderer.shadowMap.type = THREE.PCFSoftShadowMap;
265
+ this.renderer.shadowMap.type = PCFSoftShadowMap;
263
266
  this.renderer.setSize(this.domWidth, this.domHeight);
264
- this.renderer.outputEncoding = THREE.sRGBEncoding;
267
+ this.renderer.outputEncoding = sRGBEncoding;
265
268
  this.renderer.physicallyCorrectLights = true;
266
269
  }
267
270
 
268
- this.scene = new THREE.Scene();
271
+ this.scene = new Scene();
269
272
 
270
273
  ContextRegistry.register(this);
271
274
 
@@ -328,7 +331,7 @@
328
331
  }
329
332
  }
330
333
 
331
- updateAspect(camera: THREE.PerspectiveCamera, width?: number, height?: number) {
334
+ updateAspect(camera: PerspectiveCamera, width?: number, height?: number) {
332
335
  if (!camera) return;
333
336
  if (width === undefined)
334
337
  width = this.domWidth;
@@ -410,7 +413,7 @@
410
413
  if (index >= 0) this._cameraStack.splice(index, 1);
411
414
  this._cameraStack.push(cam);
412
415
  this.mainCameraComponent = cam;
413
- const camera = cam.cam as THREE.PerspectiveCamera;
416
+ const camera = cam.cam as PerspectiveCamera;
414
417
  if (camera.isPerspectiveCamera)
415
418
  this.updateAspect(camera);
416
419
  (this.mainCameraComponent as ICamera)?.applyClearFlagsIfIsActiveCamera();
@@ -434,7 +437,7 @@
434
437
  private _onBeforeRenderListeners: { [key: string]: OnBeforeRenderCallback[] } = {};
435
438
 
436
439
  /** use this to subscribe to onBeforeRender events on threejs objects */
437
- addBeforeRenderListener(target: THREE.Object3D, callback: OnBeforeRenderCallback) {
440
+ addBeforeRenderListener(target: Object3D, callback: OnBeforeRenderCallback) {
438
441
  if (!this._onBeforeRenderListeners[target.uuid]) {
439
442
  this._onBeforeRenderListeners[target.uuid] = [];
440
443
  const onBeforeRenderCallback = (renderer, scene, camera, geometry, material, group) => {
@@ -450,7 +453,7 @@
450
453
  this._onBeforeRenderListeners[target.uuid].push(callback);
451
454
  }
452
455
 
453
- removeBeforeRenderListener(target: THREE.Object3D, callback: OnBeforeRenderCallback) {
456
+ removeBeforeRenderListener(target: Object3D, callback: OnBeforeRenderCallback) {
454
457
  if (this._onBeforeRenderListeners[target.uuid]) {
455
458
  const arr = this._onBeforeRenderListeners[target.uuid];
456
459
  const idx = arr.indexOf(callback);
@@ -473,11 +476,11 @@
473
476
  this._requireColorTexture = val;
474
477
  }
475
478
 
476
- get depthTexture(): THREE.DepthTexture | null {
479
+ get depthTexture(): DepthTexture | null {
477
480
  return this._renderTarget?.depthTexture || null;
478
481
  }
479
482
 
480
- get opaqueColorTexture(): THREE.Texture | null {
483
+ get opaqueColorTexture(): Texture | null {
481
484
  return this._renderTarget?.texture || null;
482
485
  }
483
486
 
@@ -822,17 +825,17 @@
822
825
  if (!this.mainCamera) return;
823
826
  if (!this._requireDepthTexture && !this._requireColorTexture) return;
824
827
  if (!this._renderTarget) {
825
- this._renderTarget = new THREE.WebGLRenderTarget(this.domWidth, this.domHeight);
828
+ this._renderTarget = new WebGLRenderTarget(this.domWidth, this.domHeight);
826
829
  if (this._requireDepthTexture) {
827
830
  const dt = new DepthTexture(this.domWidth, this.domHeight);;
828
831
  this._renderTarget.depthTexture = dt;
829
832
  }
830
833
  if (this._requireColorTexture) {
831
- this._renderTarget.texture = new THREE.Texture();
834
+ this._renderTarget.texture = new Texture();
832
835
  this._renderTarget.texture.generateMipmaps = false;
833
- this._renderTarget.texture.minFilter = THREE.NearestFilter;
834
- this._renderTarget.texture.magFilter = THREE.NearestFilter;
835
- this._renderTarget.texture.format = THREE.RGBAFormat;
836
+ this._renderTarget.texture.minFilter = NearestFilter;
837
+ this._renderTarget.texture.magFilter = NearestFilter;
838
+ this._renderTarget.texture.format = RGBAFormat;
836
839
  }
837
840
  }
838
841
  const rt = this._renderTarget;
@@ -909,24 +912,24 @@
909
912
  }
910
913
 
911
914
 
912
- // const scene = new THREE.Scene();
915
+ // const scene = new Scene();
913
916
  // const useComposer = utils.getParam("postfx");
914
917
  // const renderer = new WebGLRenderer({ antialias: true });
915
918
  // const composer = useComposer ? new EffectComposer(renderer) : undefined;
916
919
 
917
- // renderer.setClearColor(new THREE.Color('lightgrey'), 0)
920
+ // renderer.setClearColor(new Color('lightgrey'), 0)
918
921
  // renderer.antialias = true;
919
922
  // renderer.alpha = false;
920
923
  // renderer.shadowMap.enabled = true;
921
- // renderer.shadowMap.type = THREE.PCFSoftShadowMap;
924
+ // renderer.shadowMap.type = PCFSoftShadowMap;
922
925
  // renderer.setSize(window.innerWidth, window.innerHeight);
923
- // renderer.outputEncoding = THREE.sRGBEncoding;
926
+ // renderer.outputEncoding = sRGBEncoding;
924
927
  // renderer.physicallyCorrectLights = true;
925
928
  // document.body.appendChild(renderer.domElement);
926
929
 
927
930
  // // generation pushes loading requests in this array
928
931
  // const sceneData: {
929
- // mainCamera: THREE.Camera | undefined
932
+ // mainCamera: Camera | undefined
930
933
  // } = {
931
934
  // preparing: [],
932
935
  // resolving: [],
src/engine/engine_gameobject.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { BufferGeometry, InstancedBufferGeometry, Material, Mesh, Object3D, Texture } from "three";
1
+ import { Bone, Object3D, Quaternion, SkinnedMesh, Vector3 } from "three";
2
2
  import { processNewScripts } from "./engine_mainloop_utils";
3
3
  import { InstantiateIdProvider } from "./engine_networking_instantiate";
4
4
  import { Context, registerComponent } from "./engine_setup";
@@ -36,9 +36,9 @@
36
36
  parent?: string | undefined | Object3D;
37
37
  /** for duplicatable parenting */
38
38
  keepWorldPosition?: boolean
39
- position?: THREE.Vector3 | undefined;
40
- rotation?: THREE.Quaternion | undefined;
41
- scale?: THREE.Vector3 | undefined;
39
+ position?: Vector3 | undefined;
40
+ rotation?: Quaternion | undefined;
41
+ scale?: Vector3 | undefined;
42
42
 
43
43
  visible?: boolean | undefined;
44
44
 
@@ -88,14 +88,14 @@
88
88
  return go[activeInHierarchyFieldName] || isUsingInstancing(go);
89
89
  }
90
90
 
91
- export function markAsInstancedRendered(go: THREE.Object3D, instanced: boolean) {
91
+ export function markAsInstancedRendered(go: Object3D, instanced: boolean) {
92
92
  go[$isUsingInstancing] = instanced;
93
93
  }
94
94
 
95
- export function isUsingInstancing(instance: THREE.Object3D): boolean { return InstancingUtil.isUsingInstancing(instance); }
95
+ export function isUsingInstancing(instance: Object3D): boolean { return InstancingUtil.isUsingInstancing(instance); }
96
96
 
97
97
 
98
- export function findByGuid(guid: string, hierarchy: THREE.Object3D): GameObject | IComponent | null | undefined {
98
+ export function findByGuid(guid: string, hierarchy: Object3D): GameObject | IComponent | null | undefined {
99
99
  return tryFindObject(guid, hierarchy, true, true);
100
100
  }
101
101
 
@@ -159,7 +159,7 @@
159
159
 
160
160
  declare type ForEachComponentCallback = (comp: Component) => any;
161
161
 
162
- export function foreachComponent(instance: THREE.Object3D, cb: ForEachComponentCallback, recursive: boolean = true): any {
162
+ export function foreachComponent(instance: Object3D, cb: ForEachComponentCallback, recursive: boolean = true): any {
163
163
  return internalForEachComponent(instance, cb, recursive);
164
164
  }
165
165
 
@@ -198,8 +198,8 @@
198
198
  }
199
199
 
200
200
  declare class NewGameObjectReferenceInfo {
201
- original: THREE.Object3D;
202
- clone: THREE.Object3D;
201
+ original: Object3D;
202
+ clone: Object3D;
203
203
  }
204
204
 
205
205
  export function instantiate(instance: GameObject | Object3D | null, opts: InstantiateOptions | null = null): GameObject | null {
@@ -210,7 +210,7 @@
210
210
  // if x is defined assume this is a vec3 - this is just to not break everything at once and stay a little bit backwards compatible
211
211
  if (opts["x"] !== undefined) {
212
212
  options = new InstantiateOptions();
213
- options.position = opts as unknown as THREE.Vector3;
213
+ options.position = opts as unknown as Vector3;
214
214
  }
215
215
  else {
216
216
  // if (opts instanceof InstantiateOptions)
@@ -276,12 +276,12 @@
276
276
 
277
277
 
278
278
  function internalInstantiate(
279
- context: Context, instance: GameObject | THREE.Object3D, opts: InstantiateOptions | null,
279
+ context: Context, instance: GameObject | Object3D, opts: InstantiateOptions | null,
280
280
  componentsList: Array<Component>,
281
281
  newGameObjectsMap: { [key: string]: NewGameObjectReferenceInfo },
282
282
  skinnedMeshesMap: { [key: string]: NewGameObjectReferenceInfo }
283
283
  )
284
- : GameObject | THREE.Object3D | null {
284
+ : GameObject | Object3D | null {
285
285
  if (!instance) return null;
286
286
  // prepare, remove things that dont work out of the box
287
287
  // e.g. user data we want to manually clone
@@ -290,7 +290,7 @@
290
290
  instance.userData = {};
291
291
  const children = instance.children;
292
292
  instance.children = [];
293
- let clone: THREE.Object3D | GameObject;
293
+ let clone: Object3D | GameObject;
294
294
  clone = instance.clone(false);
295
295
  apply(clone);
296
296
  // if(instance[$originalGuid])
@@ -408,9 +408,9 @@
408
408
  ) {
409
409
  for (const key in skinnedMeshes) {
410
410
  const val = skinnedMeshes[key];
411
- const original = val.original as THREE.SkinnedMesh;
411
+ const original = val.original as SkinnedMesh;
412
412
  const originalSkeleton = original.skeleton;
413
- const clone = val.clone as THREE.SkinnedMesh;
413
+ const clone = val.clone as SkinnedMesh;
414
414
  // clone.updateWorldMatrix(true, true);
415
415
  if (!originalSkeleton) {
416
416
  console.warn("Skinned mesh has no skeleton?", val);
@@ -426,16 +426,16 @@
426
426
  // clone.bindMatrix.multiplyScalar(.025);
427
427
  // console.assert(originalSkeleton.uuid !== clonedSkeleton.uuid);
428
428
  // console.assert(originalBones.length === clonedSkeleton.bones.length);
429
- const bones: Array<THREE.Bone> = [];
429
+ const bones: Array<Bone> = [];
430
430
  clonedSkeleton.bones = bones;
431
431
  for (let i = 0; i < originalBones.length; i++) {
432
432
  const bone = originalBones[i];
433
433
  const newBoneInfo = newObjectsMap[bone.uuid];
434
- const clonedBone = newBoneInfo.clone as THREE.Bone;
434
+ const clonedBone = newBoneInfo.clone as Bone;
435
435
  // console.log("NEW BONE: ", clonedBone, "BEFORE", newBoneInfo.original);
436
436
  bones.push(clonedBone);
437
437
  }
438
- // clone.skeleton = new THREE.Skeleton(bones);
438
+ // clone.skeleton = new Skeleton(bones);
439
439
  // clone.skeleton.update();
440
440
  // clone.pose();
441
441
  // clone.scale.set(1,1,1);
@@ -443,7 +443,7 @@
443
443
  // console.log("ORIG", original, "CLONE", clone);
444
444
  }
445
445
  for (const key in skinnedMeshes) {
446
- const clone = skinnedMeshes[key].clone as THREE.SkinnedMesh;
446
+ const clone = skinnedMeshes[key].clone as SkinnedMesh;
447
447
  clone.skeleton.update();
448
448
  // clone.skeleton.calculateInverses();
449
449
  clone.bind(clone.skeleton, clone.bindMatrix);
@@ -532,7 +532,7 @@
532
532
 
533
533
  }
534
534
 
535
- function postProcessNewInstance(copy: THREE.Object3D, key: string, value: IComponent | Object3D | any, newObjectsMap: { [key: string]: NewGameObjectReferenceInfo }) {
535
+ function postProcessNewInstance(copy: Object3D, key: string, value: IComponent | Object3D | any, newObjectsMap: { [key: string]: NewGameObjectReferenceInfo }) {
536
536
  if (value === null || value === undefined) return;
537
537
  if ((value as IComponent).isComponent === true) {
538
538
  const originalGameObjectReference = value["gameObject"];
src/engine/engine_gizmos.ts CHANGED
@@ -1,7 +1,6 @@
1
- import * as THREE from 'three';
2
1
  import { BufferAttribute, Line, BoxGeometry, EdgesGeometry, Color, LineSegments, LineBasicMaterial, Object3D, Mesh, SphereGeometry, ColorRepresentation, Vector3, Box3, Quaternion, CylinderGeometry } from 'three';
3
2
  import { Context } from './engine_setup';
4
- import { setWorldPosition, setWorldPositionXYZ } from './engine_three_utils';
3
+ import { setWorldPositionXYZ } from './engine_three_utils';
5
4
  import { Vec3, Vec4 } from './engine_types';
6
5
 
7
6
  const _tmp = new Vector3();
@@ -109,12 +108,12 @@
109
108
  }
110
109
 
111
110
  const box: BoxGeometry = new BoxGeometry(1, 1, 1);
112
- export function CreateWireCube(col: THREE.ColorRepresentation | null = null): THREE.LineSegments {
111
+ export function CreateWireCube(col: ColorRepresentation | null = null): LineSegments {
113
112
  const color = new Color(col ?? 0xdddddd);
114
- // const material = new THREE.MeshBasicMaterial();
115
- // material.color = new THREE.Color(col ?? 0xdddddd);
113
+ // const material = new MeshBasicMaterial();
114
+ // material.color = new Color(col ?? 0xdddddd);
116
115
  // material.wireframe = true;
117
- // const box = new THREE.Mesh(box, material);
116
+ // const box = new Mesh(box, material);
118
117
  // box.name = "BOX_GIZMO";
119
118
  const edges = new EdgesGeometry(box);
120
119
  const line = new LineSegments(edges, new LineBasicMaterial({ color: color }));
src/engine/engine_gltf_builtin_components.ts CHANGED
@@ -1,7 +1,5 @@
1
1
  import "./codegen/register_types";
2
2
  import { TypeStore } from "./engine_typestore";
3
- import * as THREE from "three";
4
- // import { GameObject } from "../engine-components/Component";
5
3
  import { InstantiateIdProvider } from "./engine_networking_instantiate"
6
4
  import { Context } from "./engine_setup";
7
5
  import { deserializeObject, serializeObject } from "./engine_serialization";
@@ -15,6 +13,7 @@
15
13
  import { getParam } from "./engine_utils";
16
14
  import { LogType, showBalloonMessage } from "./debug/debug";
17
15
  import { isLocalNetwork } from "./engine_networking_utils";
16
+ import { Object3D } from "three";
18
17
 
19
18
 
20
19
  const debug = debugExtension;
@@ -43,7 +42,7 @@
43
42
 
44
43
  export async function createBuiltinComponents(context: Context, gltfId: SourceIdentifier, gltf, seed: number | null | UIDProvider = null, extension?: NEEDLE_components) {
45
44
  if (!gltf) return;
46
- const lateResolve: Array<(gltf: THREE.Object3D) => {}> = [];
45
+ const lateResolve: Array<(gltf: Object3D) => {}> = [];
47
46
 
48
47
  let idProvider: UIDProvider | null = seed as UIDProvider;
49
48
  if (typeof idProvider === "number") {
@@ -145,15 +144,15 @@
145
144
  declare class DeserializeData {
146
145
  instance: any;
147
146
  compData: IGltfbuiltinComponent;
148
- obj: THREE.Object3D;
147
+ obj: Object3D;
149
148
  }
150
149
 
151
- declare type LateResolveCallback = (gltf: THREE.Object3D) => void;
150
+ declare type LateResolveCallback = (gltf: Object3D) => void;
152
151
 
153
152
  const unknownComponentsBuffer: Array<string> = [];
154
153
 
155
154
 
156
- async function onCreateBuiltinComponents(context: SerializationContext, obj: THREE.Object3D,
155
+ async function onCreateBuiltinComponents(context: SerializationContext, obj: Object3D,
157
156
  deserialize: DeserializeData[], lateResolve: LateResolveCallback[]) {
158
157
  if (!obj) return;
159
158
 
@@ -324,13 +323,13 @@
324
323
  // function tryResolveType(type, entry): any | undefined {
325
324
  // switch (type) {
326
325
  // case "Vector2":
327
- // return new THREE.Vector2(entry.x, entry.y);
326
+ // return new Vector2(entry.x, entry.y);
328
327
  // case "Vector3":
329
- // return new THREE.Vector3(entry.x, entry.y, entry.z);
328
+ // return new Vector3(entry.x, entry.y, entry.z);
330
329
  // case "Vector4":
331
- // return new THREE.Vector4(entry.x, entry.y, entry.z, entry.w);
330
+ // return new Vector4(entry.x, entry.y, entry.z, entry.w);
332
331
  // case "Quaternion":
333
- // return new THREE.Quaternion(entry.x, entry.y, entry.z, entry.w);
332
+ // return new Quaternion(entry.x, entry.y, entry.z, entry.w);
334
333
  // }
335
334
  // return undefined;
336
335
  // }
src/engine/engine_input.ts CHANGED
@@ -1,4 +1,3 @@
1
- import * as THREE from 'three';
2
1
  import { Vector2 } from 'three';
3
2
  import { showBalloonMessage, showBalloonWarning } from './debug/debug';
4
3
  import { assign } from './engine_serialization_core';
@@ -58,8 +57,8 @@
58
57
  _doubleClickTimeThreshold = .2;
59
58
  _longPressTimeThreshold = 1;
60
59
 
61
- get mousePosition(): THREE.Vector2 { return this._pointerPositions[0]; };
62
- get mousePositionRC(): THREE.Vector2 { return this._pointerPositionsRC[0]; }
60
+ get mousePosition(): Vector2 { return this._pointerPositions[0]; };
61
+ get mousePositionRC(): Vector2 { return this._pointerPositionsRC[0]; }
63
62
  get mouseDown(): boolean { return this._pointerDown[0]; }
64
63
  get mouseUp(): boolean { return this._pointerUp[0]; }
65
64
  get mouseClick(): boolean { return this._pointerClick[0]; }
@@ -91,19 +90,19 @@
91
90
  return count;
92
91
  }
93
92
 
94
- getPointerPosition(i: number): THREE.Vector2 | null {
93
+ getPointerPosition(i: number): Vector2 | null {
95
94
  if (i >= this._pointerPositions.length) return null;
96
95
  return this._pointerPositions[i];
97
96
  }
98
- getPointerPositionLastFrame(i: number): THREE.Vector2 | null {
97
+ getPointerPositionLastFrame(i: number): Vector2 | null {
99
98
  if (i >= this._pointerPositionsLastFrame.length) return null;
100
99
  return this._pointerPositionsLastFrame[i];
101
100
  }
102
- getPointerPositionDelta(i: number): THREE.Vector2 | null {
101
+ getPointerPositionDelta(i: number): Vector2 | null {
103
102
  if (i >= this._pointerPositionsDelta.length) return null;
104
103
  return this._pointerPositionsDelta[i];
105
104
  }
106
- getPointerPositionRC(i: number): THREE.Vector2 | null {
105
+ getPointerPositionRC(i: number): Vector2 | null {
107
106
  if (i >= this._pointerPositionsRC.length) return null;
108
107
  return this._pointerPositionsRC[i];
109
108
  }
@@ -213,11 +212,11 @@
213
212
  private _pointerClick: boolean[] = [false];
214
213
  private _pointerDoubleClick: boolean[] = [false];
215
214
  private _pointerPressed: boolean[] = [false];
216
- private _pointerPositions: THREE.Vector2[] = [new THREE.Vector2()];
217
- private _pointerPositionsLastFrame: THREE.Vector2[] = [new THREE.Vector2()];
218
- private _pointerPositionsDelta: THREE.Vector2[] = [new THREE.Vector2()];
219
- private _pointerPositionsRC: THREE.Vector2[] = [new THREE.Vector2()];
220
- private _pointerPositionDown: THREE.Vector2[] = [new THREE.Vector2()];
215
+ private _pointerPositions: Vector2[] = [new Vector2()];
216
+ private _pointerPositionsLastFrame: Vector2[] = [new Vector2()];
217
+ private _pointerPositionsDelta: Vector2[] = [new Vector2()];
218
+ private _pointerPositionsRC: Vector2[] = [new Vector2()];
219
+ private _pointerPositionDown: Vector2[] = [new Vector2()];
221
220
  private _pointerDownTime: number[] = [];
222
221
  private _pointerUpTime: number[] = [];
223
222
  private _pointerUpTimestamp: number[] = [];
@@ -505,9 +504,9 @@
505
504
  while (evt.button >= this._pointerTypes.length) this._pointerTypes.push(evt.pointerType);
506
505
  this._pointerTypes[evt.button] = evt.pointerType;
507
506
 
508
- while (evt.button >= this._pointerPositionDown.length) this._pointerPositionDown.push(new THREE.Vector2());
507
+ while (evt.button >= this._pointerPositionDown.length) this._pointerPositionDown.push(new Vector2());
509
508
  this._pointerPositionDown[evt.button].set(evt.clientX, evt.clientY);
510
- while (evt.button >= this._pointerPositions.length) this._pointerPositions.push(new THREE.Vector2());
509
+ while (evt.button >= this._pointerPositions.length) this._pointerPositions.push(new Vector2());
511
510
  this._pointerPositions[evt.button].set(evt.clientX, evt.clientY);
512
511
 
513
512
  if (evt.button >= this._pointerDownTime.length) this._pointerDownTime.push(0);
@@ -577,9 +576,9 @@
577
576
 
578
577
  private updatePointerPosition(evt: PointerEventArgs) {
579
578
  // console.log("MOVE");
580
- while (evt.button >= this._pointerPositions.length) this._pointerPositions.push(new THREE.Vector2());
581
- while (evt.button >= this._pointerPositionsLastFrame.length) this._pointerPositionsLastFrame.push(new THREE.Vector2());
582
- while (evt.button >= this._pointerPositionsDelta.length) this._pointerPositionsDelta.push(new THREE.Vector2());
579
+ while (evt.button >= this._pointerPositions.length) this._pointerPositions.push(new Vector2());
580
+ while (evt.button >= this._pointerPositionsLastFrame.length) this._pointerPositionsLastFrame.push(new Vector2());
581
+ while (evt.button >= this._pointerPositionsDelta.length) this._pointerPositionsDelta.push(new Vector2());
583
582
 
584
583
  const lf = this._pointerPositionsLastFrame[evt.button];
585
584
  lf.copy(this._pointerPositions[evt.button]);
@@ -593,7 +592,7 @@
593
592
  // we want to have the position 01 on the canvas for raycasting
594
593
  const px = evt.clientX;
595
594
  const py = evt.clientY;
596
- while (evt.button >= this._pointerPositionsRC.length) this._pointerPositionsRC.push(new THREE.Vector2());
595
+ while (evt.button >= this._pointerPositionsRC.length) this._pointerPositionsRC.push(new Vector2());
597
596
  const rc = this._pointerPositionsRC[evt.button];
598
597
  rc.set(px, py);
599
598
  this.convertScreenspaceToRaycastSpace(rc);
src/engine/engine_license.ts CHANGED
@@ -7,10 +7,10 @@
7
7
 
8
8
  // This is modified by a bundler (e.g. vite)
9
9
  // Do not edit manually
10
- const HAS_LICENSE = false;
10
+ const NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE = false;
11
11
 
12
12
  export function hasProLicense() {
13
- return HAS_LICENSE;
13
+ return NEEDLE_ENGINE_COMMERCIAL_USE_LICENSE;
14
14
  }
15
15
 
16
16
 
src/engine/engine_mainloop_utils.ts CHANGED
@@ -230,7 +230,7 @@
230
230
  }
231
231
  }
232
232
 
233
- function updateIsActiveInHierarchyRecursiveRuntime(go: THREE.Object3D, activeInHierarchy: boolean, allowEventCall: boolean, level: number = 0) {
233
+ function updateIsActiveInHierarchyRecursiveRuntime(go: Object3D, activeInHierarchy: boolean, allowEventCall: boolean, level: number = 0) {
234
234
  if (level > 1000) {
235
235
  console.warn("Hierarchy is too deep (> 1000 level) - will abort updating active state");
236
236
  return false;
@@ -307,7 +307,7 @@
307
307
 
308
308
  // let isRunning = false;
309
309
  // // Prevent: https://github.com/needle-tools/needle-tiny/issues/641
310
- // const temporyChildArrayBuffer: Array<Array<THREE.Object3D>> = [];
310
+ // const temporyChildArrayBuffer: Array<Array<Object3D>> = [];
311
311
  // export function* iterateChildrenSafe(obj: Object3D) {
312
312
  // if (!obj || !obj.children) yield null;
313
313
  // // if(isRunning) return;
@@ -322,9 +322,9 @@
322
322
  // temporyChildArrayBuffer.push(arr);
323
323
  // }
324
324
 
325
- export function updateActiveInHierarchyWithoutEventCall(go: THREE.Object3D) {
325
+ export function updateActiveInHierarchyWithoutEventCall(go: Object3D) {
326
326
  let activeInHierarchy = true;
327
- let current: THREE.Object3D | null = go;
327
+ let current: Object3D | null = go;
328
328
  let foundScene: boolean = false;
329
329
  while (current) {
330
330
  if (!current) break;
@@ -342,7 +342,7 @@
342
342
  go[constants.activeInHierarchyFieldName] = activeInHierarchy && foundScene;
343
343
  }
344
344
 
345
- function perComponent(go: THREE.Object3D, evt: (comp: IComponent) => void) {
345
+ function perComponent(go: Object3D, evt: (comp: IComponent) => void) {
346
346
  if (go.userData?.components) {
347
347
  for (const comp of go.userData.components) {
348
348
  evt(comp);
src/engine/engine_networking_auto.ts CHANGED
@@ -210,7 +210,7 @@
210
210
  * (for example a networked color is sent as a number and may be converted to a color in the receiver again)
211
211
  * Parameters: (newValue, previousValue)
212
212
  */
213
- export const syncField = function(onFieldChanged: string | FieldChangedCallbackFn) {
213
+ export const syncField = function(onFieldChanged?: string | FieldChangedCallbackFn) {
214
214
 
215
215
  return function (target: any, propertyKey: string) {
216
216
 
src/engine/engine_networking_files.ts CHANGED
@@ -1,6 +1,4 @@
1
1
  import { Context } from "../engine/engine_setup";
2
- // import { loadSync, parseSync } from "../engine/engine_scenetools";
3
- import * as THREE from "three";
4
2
  import * as web from "../engine/engine_web_api";
5
3
  import { NetworkConnection } from "../engine/engine_networking";
6
4
  import { generateSeed, InstantiateIdProvider } from "../engine/engine_networking_instantiate";
@@ -11,6 +9,7 @@
11
9
  import { IGameObject } from "./engine_types";
12
10
  import { findByGuid } from "./engine_gameobject";
13
11
  import { ContextEvent, ContextRegistry } from "./engine_context_registry";
12
+ import { BoxGeometry, BoxHelper, Mesh, MeshBasicMaterial, Object3D, Vector3 } from "three";
14
13
 
15
14
  export enum File_Event {
16
15
  File_Spawned = "file-spawned",
@@ -21,15 +20,15 @@
21
20
  file_name: string;
22
21
  file_hash: string;
23
22
  file_size: number;
24
- position: THREE.Vector3 | null;
23
+ position: Vector3 | null;
25
24
  seed: number;
26
25
  sender: string;
27
26
  serverUrl: string;
28
27
  parentGuid?: string;
29
28
 
30
- boundsSize?: THREE.Vector3;
29
+ boundsSize?: Vector3;
31
30
 
32
- constructor(connectionId: string, seed: number, guid: string, name: string, hash: string, size: number, position: THREE.Vector3 | null, serverUrl: string) {
31
+ constructor(connectionId: string, seed: number, guid: string, name: string, hash: string, size: number, position: Vector3 | null, serverUrl: string) {
33
32
  this.seed = seed;
34
33
  this.guid = guid;
35
34
  this.file_name = name;
@@ -129,7 +128,7 @@
129
128
 
130
129
  // add object to proper parent
131
130
  if (evt.parentGuid) {
132
- const parent = findByGuid(evt.parentGuid, context.scene) as THREE.Object3D;
131
+ const parent = findByGuid(evt.parentGuid, context.scene) as Object3D;
133
132
  if ("add" in parent) parent.add(obj);
134
133
  }
135
134
  if (!obj.parent)
@@ -182,16 +181,16 @@
182
181
  }
183
182
 
184
183
 
185
- const previews: { [key: string]: THREE.Object3D } = {};
184
+ const previews: { [key: string]: Object3D } = {};
186
185
 
187
186
  function addPreview(evt: FileSpawnModel, context: Context) {
188
- const sphere = new THREE.BoxGeometry();
189
- const object = new THREE.Mesh(sphere, new THREE.MeshBasicMaterial({ color: 0x00ff00 }));
190
- const box = new THREE.BoxHelper(object, 0x555555);
187
+ const sphere = new BoxGeometry();
188
+ const object = new Mesh(sphere, new MeshBasicMaterial({ color: 0x00ff00 }));
189
+ const box = new BoxHelper(object, 0x555555);
191
190
  previews[evt.guid] = box;
192
191
  context.scene.add(box);
193
192
  if (evt.parentGuid) {
194
- const parent = findByGuid(evt.parentGuid, context.scene) as THREE.Object3D;
193
+ const parent = findByGuid(evt.parentGuid, context.scene) as Object3D;
195
194
  if (parent)
196
195
  parent.add(box);
197
196
  }
src/engine/engine_three_utils.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import * as THREE from "three";
2
2
  import { Mathf } from "./engine_math"
3
- import { WebGLRenderer, Vector3, Quaternion, Uniform, Texture, Material, ShaderMaterial, CanvasTexture, AnimationAction, Camera, PerspectiveCamera } from "three";
3
+ import { WebGLRenderer, Vector3, Quaternion, Uniform, Texture, Material, ShaderMaterial, CanvasTexture, AnimationAction, Camera, PerspectiveCamera, Object3D, Euler, PlaneGeometry, Scene, Mesh } from "three";
4
4
  import { CircularBuffer } from "./engine_utils";
5
5
 
6
6
 
@@ -12,16 +12,16 @@
12
12
  }
13
13
 
14
14
  const flipYQuat: Quaternion = new Quaternion().setFromAxisAngle(new Vector3(0, 1, 0), Math.PI);
15
- export function lookAtInverse(obj: THREE.Object3D, target: Vector3) {
15
+ export function lookAtInverse(obj: Object3D, target: Vector3) {
16
16
 
17
17
  obj.lookAt(target);
18
18
  obj.quaternion.multiply(flipYQuat);
19
19
  }
20
20
 
21
21
 
22
- const _worldPositions = new CircularBuffer(() => new THREE.Vector3(), 100);
22
+ const _worldPositions = new CircularBuffer(() => new Vector3(), 100);
23
23
 
24
- export function getWorldPosition(obj: THREE.Object3D, vec: THREE.Vector3 | null = null, updateParents: boolean = true): THREE.Vector3 {
24
+ export function getWorldPosition(obj: Object3D, vec: Vector3 | null = null, updateParents: boolean = true): Vector3 {
25
25
  const wp = vec ?? _worldPositions.get();
26
26
  if (!obj) return wp.set(0, 0, 0);
27
27
  if (!obj.parent) return wp.copy(obj.position);
@@ -33,7 +33,7 @@
33
33
  return wp;
34
34
  }
35
35
 
36
- export function setWorldPosition(obj: THREE.Object3D, val: THREE.Vector3) {
36
+ export function setWorldPosition(obj: Object3D, val: Vector3) {
37
37
  if (!obj) return;
38
38
  const wp = _worldPositions.get();
39
39
  if (val !== wp)
@@ -43,25 +43,25 @@
43
43
  obj.position.set(wp.x, wp.y, wp.z);
44
44
  }
45
45
 
46
- export function setWorldPositionXYZ(obj: THREE.Object3D, x: number, y: number, z: number) {
46
+ export function setWorldPositionXYZ(obj: Object3D, x: number, y: number, z: number) {
47
47
  const wp = _worldPositions.get();
48
48
  wp.set(x, y, z);
49
49
  setWorldPosition(obj, wp);
50
50
  }
51
51
 
52
52
 
53
- const _worldQuaternionBuffer: THREE.Quaternion = new THREE.Quaternion();
54
- const _worldQuaternion: THREE.Quaternion = new THREE.Quaternion();
55
- const _tempQuaternionBuffer2: THREE.Quaternion = new THREE.Quaternion();
53
+ const _worldQuaternionBuffer: Quaternion = new Quaternion();
54
+ const _worldQuaternion: Quaternion = new Quaternion();
55
+ const _tempQuaternionBuffer2: Quaternion = new Quaternion();
56
56
 
57
- export function getWorldQuaternion(obj: THREE.Object3D, target: THREE.Quaternion | null = null): THREE.Quaternion {
57
+ export function getWorldQuaternion(obj: Object3D, target: Quaternion | null = null): Quaternion {
58
58
  if (!obj) return _worldQuaternion.set(0, 0, 0, 1);
59
59
  const quat = target ?? _worldQuaternion;
60
60
  if (!obj.parent) return quat.copy(obj.quaternion);
61
61
  obj.getWorldQuaternion(quat);
62
62
  return quat;
63
63
  }
64
- export function setWorldQuaternion(obj: THREE.Object3D, val: THREE.Quaternion) {
64
+ export function setWorldQuaternion(obj: Object3D, val: Quaternion) {
65
65
  if (!obj) return;
66
66
  if (val !== _worldQuaternionBuffer)
67
67
  _worldQuaternionBuffer.copy(val);
@@ -74,22 +74,22 @@
74
74
  obj.quaternion.set(q.x, q.y, q.z, q.w);
75
75
  // console.error("quaternion world to local is not yet implemented");
76
76
  }
77
- export function setWorldQuaternionXYZW(obj: THREE.Object3D, x: number, y: number, z: number, w: number) {
77
+ export function setWorldQuaternionXYZW(obj: Object3D, x: number, y: number, z: number, w: number) {
78
78
  _worldQuaternionBuffer.set(x, y, z, w);
79
79
  setWorldQuaternion(obj, _worldQuaternionBuffer);
80
80
  }
81
81
 
82
- const _worldScale: THREE.Vector3 = new THREE.Vector3();
83
- const _worldScale2: THREE.Vector3 = new THREE.Vector3();
82
+ const _worldScale: Vector3 = new Vector3();
83
+ const _worldScale2: Vector3 = new Vector3();
84
84
 
85
- export function getWorldScale(obj: THREE.Object3D, vec: THREE.Vector3 | null = null): THREE.Vector3 {
85
+ export function getWorldScale(obj: Object3D, vec: Vector3 | null = null): Vector3 {
86
86
  if (!obj) return _worldScale.set(0, 0, 0);
87
87
  if (!obj.parent) return _worldScale.copy(obj.scale);
88
88
  obj.getWorldScale(vec ?? _worldScale);
89
89
  return vec ?? _worldScale;
90
90
  }
91
91
 
92
- export function setWorldScale(obj: THREE.Object3D, vec: THREE.Vector3) {
92
+ export function setWorldScale(obj: Object3D, vec: Vector3) {
93
93
  if (!obj) return;
94
94
  if (!obj.parent) {
95
95
  obj.scale.copy(vec);
@@ -102,35 +102,35 @@
102
102
  obj.scale.copy(tempVec);
103
103
  }
104
104
 
105
- const _forward = new THREE.Vector3();
106
- const _forwardQuat = new THREE.Quaternion();
107
- export function forward(obj: THREE.Object3D): THREE.Vector3 {
105
+ const _forward = new Vector3();
106
+ const _forwardQuat = new Quaternion();
107
+ export function forward(obj: Object3D): Vector3 {
108
108
  getWorldQuaternion(obj, _forwardQuat);
109
109
  return _forward.set(0, 0, 1).applyQuaternion(_forwardQuat);
110
110
  }
111
111
 
112
112
 
113
113
 
114
- const _worldEulerBuffer: THREE.Euler = new THREE.Euler();
115
- const _worldEuler: THREE.Euler = new THREE.Euler();
116
- const _worldRotation: THREE.Vector3 = new THREE.Vector3();
114
+ const _worldEulerBuffer: Euler = new Euler();
115
+ const _worldEuler: Euler = new Euler();
116
+ const _worldRotation: Vector3 = new Vector3();
117
117
 
118
118
 
119
119
 
120
120
  // world euler (in radians)
121
- export function getWorldEuler(obj: THREE.Object3D): THREE.Euler {
121
+ export function getWorldEuler(obj: Object3D): Euler {
122
122
  obj.getWorldQuaternion(_worldQuaternion);
123
123
  _worldEuler.setFromQuaternion(_worldQuaternion);
124
124
  return _worldEuler;
125
125
  }
126
126
 
127
127
  // world euler (in radians)
128
- export function setWorldEuler(obj: THREE.Object3D, val: THREE.Euler) {
128
+ export function setWorldEuler(obj: Object3D, val: Euler) {
129
129
  setWorldQuaternion(obj, _worldQuaternion.setFromEuler(val));;
130
130
  }
131
131
 
132
132
  // returns rotation in degrees
133
- export function getWorldRotation(obj: THREE.Object3D): THREE.Vector3 {
133
+ export function getWorldRotation(obj: Object3D): Vector3 {
134
134
  const rot = getWorldEuler(obj);
135
135
  const wr = _worldRotation;
136
136
  wr.set(rot.x, rot.y, rot.z);
@@ -140,11 +140,11 @@
140
140
  return wr;
141
141
  }
142
142
 
143
- export function setWorldRotation(obj: THREE.Object3D, val: THREE.Vector3) {
143
+ export function setWorldRotation(obj: Object3D, val: Vector3) {
144
144
  setWorldRotationXYZ(obj, val.x, val.y, val.z, true);
145
145
  }
146
146
 
147
- export function setWorldRotationXYZ(obj: THREE.Object3D, x: number, y: number, z: number, degrees: boolean = true) {
147
+ export function setWorldRotationXYZ(obj: Object3D, x: number, y: number, z: number, degrees: boolean = true) {
148
148
  if (degrees) {
149
149
  x = Mathf.toRadians(x);
150
150
  y = Mathf.toRadians(y);
@@ -159,18 +159,18 @@
159
159
 
160
160
 
161
161
 
162
- // from https://github.com/mrdoob/three.js/pull/10995#issuecomment-287614722
163
- export function logHierarchy(root: THREE.Object3D | null | undefined, collapsible: boolean = true) {
162
+ // from https://github.com/mrdoob/js/pull/10995#issuecomment-287614722
163
+ export function logHierarchy(root: Object3D | null | undefined, collapsible: boolean = true) {
164
164
  if (!root) return;
165
165
  if (collapsible) {
166
- (function printGraph(obj: THREE.Object3D) {
166
+ (function printGraph(obj: Object3D) {
167
167
  console.groupCollapsed((obj.name ? obj.name : '(no name : ' + obj.type + ')') + ' %o', obj);
168
168
  obj.children.forEach(printGraph);
169
169
  console.groupEnd();
170
170
  }(root));
171
171
 
172
172
  } else {
173
- root.traverse(function (obj: THREE.Object3D) {
173
+ root.traverse(function (obj: Object3D) {
174
174
  var s = '|___';
175
175
  var obj2 = obj;
176
176
  while (obj2.parent !== null) {
@@ -198,10 +198,10 @@
198
198
 
199
199
 
200
200
  export class Graphics {
201
- private static planeGeometry = new THREE.PlaneGeometry(2, 2, 1, 1);
201
+ private static planeGeometry = new PlaneGeometry(2, 2, 1, 1);
202
202
  private static renderer = new WebGLRenderer({ antialias: false });
203
- private static perspectiveCam = new THREE.PerspectiveCamera();
204
- private static scene = new THREE.Scene();
203
+ private static perspectiveCam = new PerspectiveCamera();
204
+ private static scene = new Scene();
205
205
  private static readonly vertex = `
206
206
  varying vec2 vUv;
207
207
  void main(){
@@ -230,7 +230,7 @@
230
230
  fragmentShader: fragment
231
231
  });
232
232
  }
233
- private static readonly mesh = new THREE.Mesh(this.planeGeometry, this.blipMaterial);
233
+ private static readonly mesh = new Mesh(this.planeGeometry, this.blipMaterial);
234
234
 
235
235
  static copyTexture(texture: Texture, blitMaterial?: ShaderMaterial) {
236
236
  const material = blitMaterial ?? this.blipMaterial;
@@ -292,12 +292,12 @@
292
292
  }
293
293
 
294
294
  /**@obsolete use Graphics.copyTexture */
295
- export function copyTexture(texture: THREE.Texture): THREE.Texture {
295
+ export function copyTexture(texture: Texture): Texture {
296
296
  return Graphics.copyTexture(texture);
297
297
  }
298
298
 
299
299
  /**@obsolete use Graphics.textureToCanvas */
300
- export function textureToCanvas(texture: THREE.Texture, force: boolean = false): HTMLCanvasElement | null {
300
+ export function textureToCanvas(texture: Texture, force: boolean = false): HTMLCanvasElement | null {
301
301
  return Graphics.textureToCanvas(texture, force);
302
302
  }
303
303
 
src/engine/extensions/NEEDLE_components.ts CHANGED
@@ -6,6 +6,7 @@
6
6
  import { resolveReferences } from "./extension_utils";
7
7
  import { apply } from "../../engine-components/js-extensions/Object3D";
8
8
  import { getLoader } from "../engine_gltf";
9
+ import { Object3D } from "three";
9
10
 
10
11
  export const debug = debugExtension
11
12
  const componentsArrayExportKey = "$___Export_Components";
@@ -17,11 +18,11 @@
17
18
  }
18
19
 
19
20
  class ExportData {
20
- node: THREE.Object3D;
21
+ node: Object3D;
21
22
  nodeIndex: number;
22
23
  nodeDef: any;
23
24
 
24
- constructor(node: THREE.Object3D, nodeIndex: number, nodeDef: any) {
25
+ constructor(node: Object3D, nodeIndex: number, nodeDef: any) {
25
26
  this.node = node;
26
27
  this.nodeIndex = nodeIndex;
27
28
  this.nodeDef = nodeDef;
@@ -78,7 +79,7 @@
78
79
  }
79
80
 
80
81
  // https://github.com/mrdoob/three.js/blob/efbfc67edc7f65cfcc61a389ffc5fd43ea702bc6/examples/jsm/exporters/GLTFExporter.js#L532
81
- serializeUserData(node: THREE.Object3D, _nodeDef: any) {
82
+ serializeUserData(node: Object3D, _nodeDef: any) {
82
83
  const components = node.userData?.components;
83
84
  if (!components || components.length <= 0) return;
84
85
  // delete components before serializing user data to avoid circular references
@@ -86,7 +87,7 @@
86
87
  node[componentsArrayExportKey] = components;
87
88
  }
88
89
 
89
- afterSerializeUserData(node: THREE.Object3D, _nodeDef) {
90
+ afterSerializeUserData(node: Object3D, _nodeDef) {
90
91
  if (node.type === "Scene") {
91
92
  if (debug)
92
93
  console.log("DONE", JSON.stringify(_nodeDef));
@@ -102,7 +103,7 @@
102
103
  // console.log(_nodeDef, _nodeDef.mesh);
103
104
  }
104
105
 
105
- writeNode(node: THREE.Object3D, nodeDef) {
106
+ writeNode(node: Object3D, nodeDef) {
106
107
  let nodeIndex = this.writer.json.nodes.length;
107
108
  console.log(node.name, nodeIndex, node.uuid);
108
109
  const context = new ExportData(node, nodeIndex, nodeDef);
@@ -198,7 +199,7 @@
198
199
  await Promise.all(loadComponents);
199
200
  }
200
201
 
201
- private async createComponents(obj: THREE.Object3D, data: ExtensionData) {
202
+ private async createComponents(obj: Object3D, data: ExtensionData) {
202
203
  if (!data) return;
203
204
  const componentData = data[builtinComponentKeyName];
204
205
  if (componentData) {
src/engine/extensions/NEEDLE_lighting_settings.ts CHANGED
@@ -43,11 +43,20 @@
43
43
  if (ext) {
44
44
  if (debug)
45
45
  console.log("Apply \"" + this.name + "\", src: \"" + this.sourceId + "\"", ext);
46
- // add a component to the root of the scene
47
- const lightSettings = new Object3D();
48
- lightSettings.name = "Needle LightSettings";
49
- _result.scene.add(lightSettings);
50
- const settings = GameObject.addNewComponent(lightSettings, SceneLightSettings, false);
46
+ let settings: SceneLightSettings | undefined = undefined;
47
+ // If the result scene has only one child we add the LightingSettingsComponent to that child
48
+ if (_result.scene.children.length === 1) {
49
+ // add a component to the root of the scene
50
+ settings = GameObject.addNewComponent(_result.scene.children[0], SceneLightSettings, false);
51
+ }
52
+ // if the scene already has multiple children we add it as a new object
53
+ else
54
+ {
55
+ const lightSettings = new Object3D();
56
+ lightSettings.name = "Needle LightSettings";
57
+ _result.scene.add(lightSettings);
58
+ settings = GameObject.addNewComponent(lightSettings, SceneLightSettings, false);
59
+ }
51
60
  settings.sourceId = this.sourceId;
52
61
  settings.ambientIntensity = ext.ambientIntensity;
53
62
  settings.ambientLight = new Color().fromArray(ext.ambientLight);
@@ -109,7 +118,7 @@
109
118
  }
110
119
  if (this.ambientMode == AmbientMode.Flat) {
111
120
  if (this.ambientLight && !this._ambientLightObj) {
112
- this._ambientLightObj = new AmbientLight(this.ambientLight, Math.PI * this.ambientIntensity);
121
+ this._ambientLightObj = new AmbientLight(this.ambientLight, this.ambientIntensity);
113
122
  }
114
123
  if (this._ambientLightObj) {
115
124
  this.gameObject.add(this._ambientLightObj)
src/engine/extensions/NEEDLE_techniques_webgl.ts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { GLTFLoaderPlugin, GLTFParser } from "three/examples/jsm/loaders/GLTFLoader";
2
- import * as THREE from 'three';
3
2
  import { FindShaderTechniques, whiteDefaultTexture, ToUnityMatrixArray, SetUnitySphericalHarmonics } from '../engine_shaders';
4
- import { IUniform, RawShaderMaterial, Vector4 } from 'three';
3
+ import { AlwaysDepth, BackSide, Camera, DoubleSide, EqualDepth, FrontSide, GreaterDepth, GreaterEqualDepth, IUniform, LessDepth, LessEqualDepth, LinearEncoding, Material, Matrix4, NotEqualDepth, Object3D, RawShaderMaterial, Vector3, Vector4 } from 'three';
5
4
  import { Context } from '../engine_setup';
6
5
  import { getParam } from "../engine_utils";
7
6
  import * as SHADERDATA from "../shaders/shaderData"
@@ -37,13 +36,13 @@
37
36
  }
38
37
 
39
38
  class ObjectRendererData {
40
- objectToWorldMatrix: THREE.Matrix4 = new THREE.Matrix4();
41
- worldToObjectMatrix: THREE.Matrix4 = new THREE.Matrix4();
39
+ objectToWorldMatrix: Matrix4 = new Matrix4();
40
+ worldToObjectMatrix: Matrix4 = new Matrix4();
42
41
 
43
42
  objectToWorld: Array<Vector4> = new Array<Vector4>();
44
43
  worldToObject: Array<Vector4> = new Array<Vector4>();
45
44
 
46
- updateFrom(obj: THREE.Object3D) {
45
+ updateFrom(obj: Object3D) {
47
46
  this.objectToWorldMatrix.copy(obj.matrixWorld);
48
47
  ToUnityMatrixArray(this.objectToWorldMatrix, this.objectToWorld);
49
48
 
@@ -132,7 +131,7 @@
132
131
  this.uniforms["unity_SpecCube0"] = { value: envTexture };
133
132
  SetUnitySphericalHarmonics(this.uniforms, array);
134
133
  const hdr = Math.sqrt(Math.PI * .5);
135
- this.uniforms["unity_SpecCube0_HDR"] = { value: new THREE.Vector4(hdr, hdr, hdr, hdr) };
134
+ this.uniforms["unity_SpecCube0_HDR"] = { value: new Vector4(hdr, hdr, hdr, hdr) };
136
135
  // this.needsUpdate = true;
137
136
  // this.uniformsNeedUpdate = true;
138
137
  if (debug) console.log("Set environment lighting", this.uniforms);
@@ -143,20 +142,20 @@
143
142
  private _objToWorldName = "hlslcc_mtx4x4unity_ObjectToWorld";
144
143
  private _worldToObjectName = "hlslcc_mtx4x4unity_WorldToObject";
145
144
 
146
- private static viewProjection: THREE.Matrix4 = new THREE.Matrix4();
145
+ private static viewProjection: Matrix4 = new Matrix4();
147
146
  private static _viewProjectionValues: Array<Vector4> = [];
148
147
  private _viewProjectionName = "hlslcc_mtx4x4unity_MatrixVP";
149
148
 
150
- private static viewMatrix: THREE.Matrix4 = new THREE.Matrix4();
149
+ private static viewMatrix: Matrix4 = new Matrix4();
151
150
  private static _viewMatrixValues: Array<Vector4> = [];
152
151
  private _viewMatrixName = "hlslcc_mtx4x4unity_MatrixV";
153
152
 
154
153
  private static _worldSpaceCameraPosName = "_WorldSpaceCameraPos";
155
- private static _worldSpaceCameraPos: THREE.Vector3 = new THREE.Vector3();
154
+ private static _worldSpaceCameraPos: Vector3 = new Vector3();
156
155
 
157
- private static _mainLightColor: THREE.Vector4 = new THREE.Vector4();
158
- private static _mainLightPosition: THREE.Vector3 = new THREE.Vector3();
159
- private static _lightData: THREE.Vector4 = new THREE.Vector4();
156
+ private static _mainLightColor: Vector4 = new Vector4();
157
+ private static _mainLightPosition: Vector3 = new Vector3();
158
+ private static _lightData: Vector4 = new Vector4();
160
159
 
161
160
  private _rendererData = new ObjectRendererData();
162
161
 
@@ -184,7 +183,7 @@
184
183
  this.onUpdateUniforms(camera, obj);
185
184
  }
186
185
 
187
- onUpdateUniforms(camera?: THREE.Camera, obj?: any) {
186
+ onUpdateUniforms(camera?: Camera, obj?: any) {
188
187
 
189
188
  const context = Context.Current;
190
189
 
@@ -309,7 +308,7 @@
309
308
  this.identifier = identifier;
310
309
  }
311
310
 
312
- loadMaterial(index: number): Promise<THREE.Material> | null {
311
+ loadMaterial(index: number): Promise<Material> | null {
313
312
 
314
313
  const mat = this.parser.json.materials[index];
315
314
  if (!mat) {
@@ -328,7 +327,7 @@
328
327
  const technique: SHADERDATA.Technique = shaders.techniques[techniqueIndex];
329
328
  if (!technique) return null;
330
329
 
331
- return new Promise<THREE.Material>(async (resolve, reject) => {
330
+ return new Promise<Material>(async (resolve, reject) => {
332
331
  const bundle = await FindShaderTechniques(shaders, technique.program!);
333
332
  const frag = bundle?.fragmentShader;
334
333
  const vert = bundle?.vertexShader;
@@ -342,7 +341,7 @@
342
341
  const techniqueUniforms = technique.uniforms;
343
342
 
344
343
  if (vert.includes("_Time"))
345
- uniforms["_Time"] = { value: new THREE.Vector4(0, 0, 0, 0) };
344
+ uniforms["_Time"] = { value: new Vector4(0, 0, 0, 0) };
346
345
 
347
346
  for (const u in techniqueUniforms) {
348
347
  const uniformName = u;
@@ -350,7 +349,7 @@
350
349
  // const typeName = UniformType[uniformValues.type];
351
350
  switch (uniformName) {
352
351
  case "_TimeParameters":
353
- const timeUniform = new THREE.Vector4();
352
+ const timeUniform = new Vector4();
354
353
  uniforms[uniformName] = { value: timeUniform };
355
354
  break;
356
355
 
@@ -422,7 +421,7 @@
422
421
  if (texIndex >= 0) {
423
422
  const tex = await this.parser.getDependency("texture", texIndex);
424
423
  if (tex) {
425
- tex.encoding = THREE.LinearEncoding;
424
+ tex.encoding = LinearEncoding;
426
425
  tex.needsUpdate = true;
427
426
  }
428
427
  uniforms[key] = { value: tex };
@@ -436,7 +435,7 @@
436
435
  }
437
436
  }
438
437
  if (Array.isArray(val) && val.length === 4) {
439
- uniforms[key] = { value: new THREE.Vector4(val[0], val[1], val[2], val[3]) };
438
+ uniforms[key] = { value: new Vector4(val[0], val[1], val[2], val[3]) };
440
439
  continue;
441
440
  }
442
441
  uniforms[key] = { value: val };
@@ -460,16 +459,16 @@
460
459
  const culling = uniforms["_Cull"]?.value;
461
460
  switch (culling) {
462
461
  case CullMode.Off:
463
- material.side = THREE.DoubleSide;
462
+ material.side = DoubleSide;
464
463
  break;
465
464
  case CullMode.Front:
466
- material.side = THREE.BackSide;
465
+ material.side = BackSide;
467
466
  break;
468
467
  case CullMode.Back:
469
- material.side = THREE.FrontSide;
468
+ material.side = FrontSide;
470
469
  break;
471
470
  default:
472
- material.side = THREE.FrontSide;
471
+ material.side = FrontSide;
473
472
  break;
474
473
  }
475
474
 
@@ -477,31 +476,31 @@
477
476
  switch (zTest) {
478
477
  case ZTestMode.Equal:
479
478
  material.depthTest = true;
480
- material.depthFunc = THREE.EqualDepth;
479
+ material.depthFunc = EqualDepth;
481
480
  break;
482
481
  case ZTestMode.NotEqual:
483
482
  material.depthTest = true;
484
- material.depthFunc = THREE.NotEqualDepth;
483
+ material.depthFunc = NotEqualDepth;
485
484
  break;
486
485
  case ZTestMode.Less:
487
486
  material.depthTest = true;
488
- material.depthFunc = THREE.LessDepth;
487
+ material.depthFunc = LessDepth;
489
488
  break;
490
489
  case ZTestMode.LEqual:
491
490
  material.depthTest = true;
492
- material.depthFunc = THREE.LessEqualDepth;
491
+ material.depthFunc = LessEqualDepth;
493
492
  break;
494
493
  case ZTestMode.Greater:
495
494
  material.depthTest = true;
496
- material.depthFunc = THREE.GreaterDepth;
495
+ material.depthFunc = GreaterDepth;
497
496
  break;
498
497
  case ZTestMode.GEqual:
499
498
  material.depthTest = true;
500
- material.depthFunc = THREE.GreaterEqualDepth;
499
+ material.depthFunc = GreaterEqualDepth;
501
500
  break;
502
501
  case ZTestMode.Always:
503
502
  material.depthTest = false;
504
- material.depthFunc = THREE.AlwaysDepth;
503
+ material.depthFunc = AlwaysDepth;
505
504
  break;
506
505
  }
507
506
 
src/needle-engine.ts CHANGED
@@ -6,19 +6,16 @@
6
6
 
7
7
  import "./engine-components/CameraUtils"
8
8
 
9
-
10
- export { GameObject, Behaviour } from "./engine-components/Component";
11
- export { serializable, serializeable } from "./engine/engine_serialization_decorator";
12
- export { Collision } from "./engine/engine_types";
13
9
  export * from "./engine/api";
14
10
  export * from "./engine-components/api";
15
- export * from "./engine-components/codegen/components";
16
- export * from "./engine-components/js-extensions/Object3D";
11
+ export * from "./engine-components-experimental/api";
17
12
 
18
-
19
13
  // make accessible for external javascript
20
14
  import { Context } from "./engine/engine_setup";
21
15
  const Needle = { Context: Context };
16
+ if (globalThis["Needle"] !== undefined) {
17
+ console.warn("Needle Engine is already imported");
18
+ }
22
19
  globalThis["Needle"] = Needle;
23
20
  function registerGlobal(obj: object) {
24
21
  for (const key in obj) {
@@ -47,7 +44,7 @@
47
44
 
48
45
  // make three accessible
49
46
  import * as THREE from "three";
50
- if(!globalThis["THREE"]) {
47
+ if (!globalThis["THREE"]) {
51
48
  globalThis["THREE"] = THREE;
52
49
  }
53
50
  else console.warn("Threejs is already imported");
src/engine-components/ParticleSystemModules.ts CHANGED
@@ -1,1484 +1,1484 @@
1
- import { Color, Matrix4, Object3D, PointLightShadow, Quaternion, Vector3, Vector2, Euler, Vector4, DirectionalLightHelper } from "three";
2
- import { Mathf } from "../engine/engine_math";
3
- import { serializable } from "../engine/engine_serialization";
4
- import { RGBAColor } from "./js-extensions/RGBAColor";
5
- import { AnimationCurve } from "./AnimationCurve";
6
- import { Vec2, Vec3 } from "../engine/engine_types";
7
- import { Context } from "../engine/engine_setup";
8
- import { EmitterShape, FrameOverLife, Particle, ShapeJSON } from "three.quarks";
9
- import { createNoise4D, NoiseFunction4D } from 'simplex-noise';
10
- import { Gizmos } from "../engine/engine_gizmos";
11
- import { getParam } from "../engine/engine_utils";
12
-
13
- const debug = getParam("debugparticles");
14
-
15
- declare type Color4 = { r: number, g: number, b: number, a: number };
16
- declare type ColorKey = { time: number, color: Color4 };
17
- declare type AlphaKey = { time: number, alpha: number };
18
-
19
- export interface IParticleSystem {
20
- get currentParticles(): number;
21
- get maxParticles(): number;
22
- get time(): number;
23
- get deltaTime(): number;
24
- get duration(): number;
25
- readonly main: MainModule;
26
- get container(): Object3D;
27
- get worldspace(): boolean;
28
- get worldPos(): Vector3;
29
- get worldQuaternion(): Quaternion;
30
- get worldQuaternionInverted(): Quaternion;
31
- get worldScale(): Vector3;
32
- get matrixWorld(): Matrix4;
33
- }
34
-
35
-
36
- export enum ParticleSystemRenderMode {
37
- Billboard = 0,
38
- Stretch = 1,
39
- HorizontalBillboard = 2,
40
- VerticalBillboard = 3,
41
- Mesh = 4,
42
- // None = 5,
43
- }
44
-
45
-
46
- export class Gradient {
47
- @serializable()
48
- alphaKeys!: Array<AlphaKey>;
49
- @serializable()
50
- colorKeys!: Array<ColorKey>;
51
-
52
- get duration(): number {
53
- return 1;
54
- }
55
-
56
- evaluate(time: number, target: RGBAColor) {
57
-
58
- // target.r = this.colorKeys[0].color.r;
59
- // target.g = this.colorKeys[0].color.g;
60
- // target.b = this.colorKeys[0].color.b;
61
- // target.alpha = this.alphaKeys[0].alpha;
62
- // return;
63
-
64
- let closestAlpha: AlphaKey | undefined = undefined;
65
- let closestAlphaIndex = 0;
66
- let closestColor: ColorKey | null = null;
67
- let closestColorIndex = 0;
68
- for (let i = 0; i < this.alphaKeys.length; i++) {
69
- const key = this.alphaKeys[i];
70
- if (key.time < time || !closestAlpha) {
71
- closestAlpha = key;
72
- closestAlphaIndex = i;
73
- }
74
- }
75
- for (let i = 0; i < this.colorKeys.length; i++) {
76
- const key = this.colorKeys[i];
77
- if (key.time < time || !closestColor) {
78
- closestColor = key;
79
- closestColorIndex = i;
80
- }
81
- }
82
- if (closestColor) {
83
- const hasNextColor = closestColorIndex + 1 < this.colorKeys.length;
84
- if (hasNextColor) {
85
- const nextColor = this.colorKeys[closestColorIndex + 1];
86
- const t = Mathf.remap(time, closestColor.time, nextColor.time, 0, 1);
87
- target.r = Mathf.lerp(closestColor.color.r, nextColor.color.r, t);
88
- target.g = Mathf.lerp(closestColor.color.g, nextColor.color.g, t);
89
- target.b = Mathf.lerp(closestColor.color.b, nextColor.color.b, t);
90
- }
91
- else {
92
- target.r = closestColor.color.r;
93
- target.g = closestColor.color.g;
94
- target.b = closestColor.color.b;
95
- }
96
- }
97
- if (closestAlpha) {
98
- const hasNextAlpha = closestAlphaIndex + 1 < this.alphaKeys.length;
99
- if (hasNextAlpha) {
100
- const nextAlpha = this.alphaKeys[closestAlphaIndex + 1];
101
- const t = Mathf.remap(time, closestAlpha.time, nextAlpha.time, 0, 1);
102
- target.alpha = Mathf.lerp(closestAlpha.alpha, nextAlpha.alpha, t);
103
- }
104
- else {
105
- target.alpha = closestAlpha.alpha;
106
- }
107
- }
108
- return target;
109
- }
110
- }
111
-
112
- export enum ParticleSystemCurveMode {
113
- Constant = 0,
114
- Curve = 1,
115
- TwoCurves = 2,
116
- TwoConstants = 3
117
- }
118
-
119
- export enum ParticleSystemGradientMode {
120
- Color = 0,
121
- Gradient = 1,
122
- TwoColors = 2,
123
- TwoGradients = 3,
124
- RandomColor = 4,
125
- }
126
-
127
- export enum ParticleSystemSimulationSpace {
128
- Local = 0,
129
- World = 1,
130
- Custom = 2
131
- }
132
-
133
- export enum ParticleSystemShapeType {
134
- Sphere = 0,
135
- SphereShell = 1,
136
- Hemisphere = 2,
137
- HemisphereShell = 3,
138
- Cone = 4,
139
- Box = 5,
140
- Mesh = 6,
141
- ConeShell = 7,
142
- ConeVolume = 8,
143
- ConeVolumeShell = 9,
144
- Circle = 10,
145
- CircleEdge = 11,
146
- SingleSidedEdge = 12,
147
- MeshRenderer = 13,
148
- SkinnedMeshRenderer = 14,
149
- BoxShell = 15,
150
- BoxEdge = 16,
151
- Donut = 17,
152
- Rectangle = 18,
153
- Sprite = 19,
154
- SpriteRenderer = 20
155
- }
156
-
157
- export enum ParticleSystemShapeMultiModeValue {
158
- Random = 0,
159
- Loop = 1,
160
- PingPong = 2,
161
- BurstSpread = 3,
162
- }
163
-
164
- export class MinMaxCurve {
165
- @serializable()
166
- mode!: ParticleSystemCurveMode;
167
- @serializable()
168
- constant!: number;
169
- @serializable()
170
- constantMin!: number;
171
- @serializable()
172
- constantMax!: number;
173
- @serializable(AnimationCurve)
174
- curve?: AnimationCurve;
175
- @serializable(AnimationCurve)
176
- curveMin?: AnimationCurve;
177
- @serializable(AnimationCurve)
178
- curveMax?: AnimationCurve;
179
- @serializable()
180
- curveMultiplier?: number;
181
-
182
- evaluate(t01: number, lerpFactor?: number): number {
183
- const t = lerpFactor === undefined ? Math.random() : lerpFactor;
184
- switch (this.mode) {
185
- case ParticleSystemCurveMode.Constant:
186
- return this.constant;
187
- case ParticleSystemCurveMode.Curve:
188
- t01 = Mathf.clamp01(t01);
189
- return this.curve!.evaluate(t01) * this.curveMultiplier!;
190
- case ParticleSystemCurveMode.TwoCurves:
191
- const t1 = t01 * this.curveMin!.duration;
192
- const t2 = t01 * this.curveMax!.duration;
193
- return Mathf.lerp(this.curveMin!.evaluate(t1), this.curveMax!.evaluate(t2), t % 1) * this.curveMultiplier!;
194
- case ParticleSystemCurveMode.TwoConstants:
195
- return Mathf.lerp(this.constantMin, this.constantMax, t % 1)
196
- default:
197
- this.curveMax!.evaluate(t01) * this.curveMultiplier!;
198
- break;
199
- }
200
- return 0;
201
- }
202
-
203
- getMax(): number {
204
- switch (this.mode) {
205
- case ParticleSystemCurveMode.Constant:
206
- return this.constant;
207
- case ParticleSystemCurveMode.Curve:
208
- return this.getMaxFromCurve(this.curve!) * this.curveMultiplier!;
209
- case ParticleSystemCurveMode.TwoCurves:
210
- return Math.max(this.getMaxFromCurve(this.curveMin), this.getMaxFromCurve(this.curveMax)) * this.curveMultiplier!;
211
- case ParticleSystemCurveMode.TwoConstants:
212
- return Math.max(this.constantMin, this.constantMax);
213
- default:
214
- return 0;
215
- }
216
- }
217
-
218
- private getMaxFromCurve(curve?: AnimationCurve) {
219
- if (!curve) return 0;
220
- let maxNumber = Number.MIN_VALUE;
221
- for (let i = 0; i < curve!.keys.length; i++) {
222
- const key = curve!.keys[i];
223
- if (key.value > maxNumber) {
224
- maxNumber = key.value;
225
- }
226
- }
227
- return maxNumber;
228
- }
229
- }
230
-
231
- export class MinMaxGradient {
232
- mode!: ParticleSystemGradientMode;
233
- @serializable(RGBAColor)
234
- color!: RGBAColor;
235
- @serializable(RGBAColor)
236
- colorMin!: RGBAColor;
237
- @serializable(RGBAColor)
238
- colorMax!: RGBAColor;
239
- @serializable(Gradient)
240
- gradient!: Gradient;
241
- @serializable(Gradient)
242
- gradientMin!: Gradient;
243
- @serializable(Gradient)
244
- gradientMax!: Gradient;
245
-
246
- private static _temp: RGBAColor = new RGBAColor(0, 0, 0, 1);
247
- private static _temp2: RGBAColor = new RGBAColor(0, 0, 0, 1);
248
-
249
- evaluate(t01: number, lerpFactor?: number): RGBAColor {
250
- const t = lerpFactor === undefined ? Math.random() : lerpFactor;
251
- switch (this.mode) {
252
- case ParticleSystemGradientMode.Color:
253
- return this.color;
254
- case ParticleSystemGradientMode.Gradient:
255
- this.gradient.evaluate(t01, MinMaxGradient._temp);
256
- return MinMaxGradient._temp
257
- case ParticleSystemGradientMode.TwoColors:
258
- const col1 = MinMaxGradient._temp.lerpColors(this.colorMin, this.colorMax, t);
259
- return col1;
260
- case ParticleSystemGradientMode.TwoGradients:
261
- this.gradientMin.evaluate(t01, MinMaxGradient._temp);
262
- this.gradientMax.evaluate(t01, MinMaxGradient._temp2);
263
- return MinMaxGradient._temp.lerp(MinMaxGradient._temp2, t);
264
-
265
- }
266
- // console.warn("Not implemented", ParticleSystemGradientMode[this.mode]);
267
- MinMaxGradient._temp.set(0xff00ff)
268
- MinMaxGradient._temp.alpha = 1;
269
- return MinMaxGradient._temp;
270
- }
271
- }
272
-
273
- declare type ParticleSystemScalingMode = {
274
- Hierarchy: number;