@needle-tools/engine 2.31.1-pre → 2.32.0-pre
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +9 -0
- package/dist/needle-engine.d.ts +111 -111
- package/dist/needle-engine.js +72 -72
- package/dist/needle-engine.js.map +3 -3
- package/dist/needle-engine.min.js +17 -17
- package/dist/needle-engine.min.js.map +3 -3
- package/lib/engine/debug/error_overlay.js +4 -4
- package/lib/engine/debug/error_overlay.js.map +1 -1
- package/lib/engine/engine_input.d.ts +87 -102
- package/lib/engine/engine_input.js +173 -99
- package/lib/engine/engine_input.js.map +1 -1
- package/lib/engine/engine_mainloop_utils.d.ts +2 -1
- package/lib/engine/engine_mainloop_utils.js +5 -2
- package/lib/engine/engine_mainloop_utils.js.map +1 -1
- package/lib/engine/engine_physics.d.ts +5 -1
- package/lib/engine/engine_physics.js +72 -22
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_setup.js +7 -3
- package/lib/engine/engine_setup.js.map +1 -1
- package/lib/engine-components/Component.d.ts +10 -3
- package/lib/engine-components/Component.js +98 -40
- package/lib/engine-components/Component.js.map +1 -1
- package/lib/engine-components/Rigidbody.d.ts +7 -4
- package/lib/engine-components/Rigidbody.js +43 -26
- package/lib/engine-components/Rigidbody.js.map +1 -1
- package/package.json +1 -1
- package/src/engine/debug/error_overlay.ts +3 -3
- package/src/engine/engine_input.ts +179 -103
- package/src/engine/engine_mainloop_utils.ts +6 -2
- package/src/engine/engine_physics.ts +86 -24
- package/src/engine/engine_setup.ts +8 -3
- package/src/engine-components/Component.ts +109 -40
- package/src/engine-components/RigidBody.ts +51 -29
|
@@ -79,9 +79,12 @@ abstract class GameObject extends THREE.Object3D implements THREE.Object3D {
|
|
|
79
79
|
|
|
80
80
|
guid: string | undefined;
|
|
81
81
|
|
|
82
|
-
public static setActive(go: THREE.Object3D, active: boolean) {
|
|
82
|
+
public static setActive(go: THREE.Object3D, active: boolean, processStart: boolean = true) {
|
|
83
83
|
if (!go) return;
|
|
84
84
|
go.visible = active;
|
|
85
|
+
main.updateActiveInHierarchyWithoutEventCall(go);
|
|
86
|
+
if (active && processStart)
|
|
87
|
+
main.processStart(Context.Current, go);
|
|
85
88
|
}
|
|
86
89
|
|
|
87
90
|
public static isActiveSelf(go: THREE.Object3D): boolean {
|
|
@@ -838,8 +841,13 @@ class Component implements EventTarget {
|
|
|
838
841
|
|
|
839
842
|
onCollisionEnter?(col: Collision);
|
|
840
843
|
onCollisionExit?(col: Collision);
|
|
844
|
+
onCollisionExitRaw?(col: Collision);
|
|
841
845
|
onCollisionStay?(col: Collision);
|
|
842
846
|
|
|
847
|
+
onTriggerEnter?(col: Collision);
|
|
848
|
+
onTriggerStay?(col: Collision);
|
|
849
|
+
onTriggerExit?(col: Collision);
|
|
850
|
+
|
|
843
851
|
startCoroutine(routine: Generator, evt: FrameEvent = FrameEvent.Update): Generator {
|
|
844
852
|
return this.context.registerCoroutineUpdate(this, routine, evt);
|
|
845
853
|
}
|
|
@@ -900,6 +908,7 @@ class Component implements EventTarget {
|
|
|
900
908
|
this.__didEnable = false;
|
|
901
909
|
this._collisionExitRoutine = undefined;
|
|
902
910
|
this.onDisable();
|
|
911
|
+
this._collisions?.clear();
|
|
903
912
|
}
|
|
904
913
|
|
|
905
914
|
constructor() {
|
|
@@ -907,55 +916,115 @@ class Component implements EventTarget {
|
|
|
907
916
|
}
|
|
908
917
|
|
|
909
918
|
private _collisionExitRoutine: any;
|
|
910
|
-
private _collisions: Map<Object3D, { col: Collision, frame: number }> | null = null;
|
|
919
|
+
private _collisions: Map<Object3D, { col: Collision, frame: number, exitFrame?: number }> | null = null;
|
|
920
|
+
|
|
921
|
+
private _triggerExitRoutine: any;
|
|
922
|
+
private _triggerCollisions: Map<Object3D, { col: Collision, frame: number, exitFrame?: number }> | null = null;
|
|
923
|
+
|
|
924
|
+
get collisionsCount() { return this._collisions?.size ?? 0; }
|
|
911
925
|
|
|
912
926
|
private __internalResetsCachedPhysicsData() {
|
|
913
927
|
this._collisionExitRoutine = null;
|
|
914
928
|
this._collisions = null;
|
|
929
|
+
this._triggerExitRoutine = null;
|
|
930
|
+
this._triggerCollisions = null;
|
|
915
931
|
}
|
|
916
932
|
|
|
917
|
-
__internalHandleCollision(col: Collision) {
|
|
918
|
-
if (
|
|
919
|
-
|
|
920
|
-
|
|
921
|
-
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
|
|
933
|
+
__internalHandleCollision(col: Collision, isTriggerCollision: boolean) {
|
|
934
|
+
if (isTriggerCollision) {
|
|
935
|
+
if (!this.onTriggerEnter && !this.onTriggerStay && !this.onTriggerExit) return;
|
|
936
|
+
}
|
|
937
|
+
else {
|
|
938
|
+
if (!this.onCollisionEnter && !this.onCollisionStay && !this.onCollisionExit) return;
|
|
939
|
+
}
|
|
940
|
+
|
|
941
|
+
const otherObject = col.gameObject;
|
|
942
|
+
|
|
943
|
+
// lazily create the maps
|
|
944
|
+
if (isTriggerCollision && !this._triggerCollisions) this._triggerCollisions = new Map();
|
|
945
|
+
else if (!this._collisions) this._collisions = new Map();
|
|
946
|
+
|
|
947
|
+
// select the correct map
|
|
948
|
+
const collection = isTriggerCollision ? this._triggerCollisions! : this._collisions!;
|
|
949
|
+
|
|
950
|
+
if (collection.has(otherObject)) {
|
|
951
|
+
const cur = collection.get(otherObject)!;
|
|
952
|
+
// console.log("STAY", this.name, this.context.time.frameCount)
|
|
953
|
+
// cur.exitFrame = undefined;
|
|
954
|
+
cur.frame = this.context.time.frameCount;
|
|
955
|
+
cur.col = col;
|
|
956
|
+
if (isTriggerCollision)
|
|
957
|
+
this.onTriggerStay?.(col);
|
|
958
|
+
else
|
|
925
959
|
this.onCollisionStay?.call(this, col);
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
960
|
+
}
|
|
961
|
+
else {
|
|
962
|
+
// console.log("START", this.name);
|
|
963
|
+
const entry = { col, frame: this.context.time.frameCount };
|
|
964
|
+
collection.set(otherObject, entry);
|
|
965
|
+
if (isTriggerCollision)
|
|
966
|
+
this.onTriggerEnter?.(col);
|
|
967
|
+
else
|
|
930
968
|
this.onCollisionEnter?.call(this, col);
|
|
931
|
-
}
|
|
932
969
|
}
|
|
933
970
|
}
|
|
934
971
|
|
|
935
|
-
|
|
936
|
-
if(
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
|
|
943
|
-
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
948
|
-
//
|
|
949
|
-
//
|
|
950
|
-
|
|
951
|
-
|
|
952
|
-
|
|
953
|
-
//
|
|
954
|
-
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
972
|
+
__internalHandleExitCollisionEvent(obj: Object3D, isTriggerCollision: boolean) {
|
|
973
|
+
if (isTriggerCollision) {
|
|
974
|
+
if (!this._triggerCollisions) return;
|
|
975
|
+
}
|
|
976
|
+
else {
|
|
977
|
+
if (!this._collisions) return;
|
|
978
|
+
}
|
|
979
|
+
|
|
980
|
+
const collection = isTriggerCollision ? this._triggerCollisions! : this._collisions!;
|
|
981
|
+
|
|
982
|
+
const collision = collection.get(obj);
|
|
983
|
+
if (!collision) return;
|
|
984
|
+
collision.exitFrame = this.context.time.frameCount;
|
|
985
|
+
// console.log("EXIT col", this.name, this.context.time.frameCount);
|
|
986
|
+
// if (this.onCollisionExit !== undefined)
|
|
987
|
+
this.__waitForCollisionExit(isTriggerCollision);
|
|
988
|
+
if (!isTriggerCollision)
|
|
989
|
+
this.onCollisionExitRaw?.call(this, collision.col);
|
|
990
|
+
// this._collisions.delete(obj);
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
private __waitForCollisionExit(isTriggerCollision: boolean) {
|
|
994
|
+
const routine = isTriggerCollision ? this._triggerExitRoutine : this._collisionExitRoutine;
|
|
995
|
+
if (routine) return;
|
|
996
|
+
|
|
997
|
+
const collection = isTriggerCollision ? this._triggerCollisions! : this._collisions!;
|
|
998
|
+
const self = this;
|
|
999
|
+
const frames = 10;
|
|
1000
|
+
function* delayedExitRoutine() {
|
|
1001
|
+
while (collection && collection.size > 0) {
|
|
1002
|
+
for (let other of collection.keys()) {
|
|
1003
|
+
const entry = collection!.get(other)!;
|
|
1004
|
+
if (entry.frame !== undefined && self.context.time.frameCount - entry.frame >= frames) {
|
|
1005
|
+
// console.log("EXIT real", self.name, entry.col.gameObject.name, collection);
|
|
1006
|
+
collection!.delete(other);
|
|
1007
|
+
if (isTriggerCollision)
|
|
1008
|
+
self.onTriggerExit?.(entry.col);
|
|
1009
|
+
else
|
|
1010
|
+
self.onCollisionExit?.call(self, entry.col);
|
|
1011
|
+
}
|
|
1012
|
+
}
|
|
1013
|
+
for (let i = 0; i < frames; i++)
|
|
1014
|
+
yield;
|
|
1015
|
+
}
|
|
1016
|
+
if (isTriggerCollision)
|
|
1017
|
+
self._triggerExitRoutine = undefined;
|
|
1018
|
+
else
|
|
1019
|
+
self._collisionExitRoutine = null;
|
|
1020
|
+
// console.log("DONE", self.name);
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
const newRoutine = this.startCoroutine(delayedExitRoutine(), FrameEvent.OnAfterRender);
|
|
1024
|
+
if (isTriggerCollision)
|
|
1025
|
+
this._triggerExitRoutine = newRoutine;
|
|
1026
|
+
else
|
|
1027
|
+
this._collisionExitRoutine = newRoutine
|
|
959
1028
|
}
|
|
960
1029
|
|
|
961
1030
|
|
|
@@ -1046,7 +1115,7 @@ class Component implements EventTarget {
|
|
|
1046
1115
|
private static _forward: THREE.Vector3 = new THREE.Vector3(0, 0, 1);
|
|
1047
1116
|
public get forward(): THREE.Vector3 {
|
|
1048
1117
|
|
|
1049
|
-
return Component._forward.set(0, 0, 1).applyQuaternion(this.worldQuaternion);
|
|
1118
|
+
return Component._forward.set(0, 0, -1).applyQuaternion(this.worldQuaternion);
|
|
1050
1119
|
}
|
|
1051
1120
|
|
|
1052
1121
|
|
|
@@ -5,6 +5,7 @@ import * as THREE from 'three'
|
|
|
5
5
|
import { getWorldPosition } from "../engine/engine_three_utils";
|
|
6
6
|
import { serializeable } from "../engine/engine_serialization_decorator";
|
|
7
7
|
import { Watch } from "../engine/engine_utils";
|
|
8
|
+
import { Vector3 } from "three";
|
|
8
9
|
|
|
9
10
|
export class Rigidbody extends Behaviour {
|
|
10
11
|
|
|
@@ -51,7 +52,7 @@ export class Rigidbody extends Behaviour {
|
|
|
51
52
|
private _dirty: boolean = false;
|
|
52
53
|
|
|
53
54
|
private _positionWatch?: Watch;
|
|
54
|
-
|
|
55
|
+
private _matrixWatch?: Watch;
|
|
55
56
|
private _setMatrix: THREE.Matrix4;
|
|
56
57
|
|
|
57
58
|
constructor() {
|
|
@@ -64,11 +65,13 @@ export class Rigidbody extends Behaviour {
|
|
|
64
65
|
this.currentVelocity = new THREE.Vector3();
|
|
65
66
|
this._smoothedVelocity = new THREE.Vector3();
|
|
66
67
|
this.lastWorldPosition = getWorldPosition(this.gameObject).clone();
|
|
68
|
+
this._matrixWatch = undefined;
|
|
69
|
+
this._positionWatch = undefined;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
start() {
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
+
// start() {
|
|
73
|
+
// this.setBodyFromGameObject();
|
|
74
|
+
// }
|
|
72
75
|
|
|
73
76
|
onEnable() {
|
|
74
77
|
if (this._body) {
|
|
@@ -88,22 +91,13 @@ export class Rigidbody extends Behaviour {
|
|
|
88
91
|
this._positionWatch.subscribeWrite(_ => {
|
|
89
92
|
if (!this.context.physics.isUpdating && !this._ignoreChange) {
|
|
90
93
|
this._dirty = true;
|
|
94
|
+
this._setMatrix.copy(this.gameObject.matrix);
|
|
91
95
|
this._setMatrix.setPosition(this.gameObject.position);
|
|
92
96
|
}
|
|
93
97
|
})
|
|
94
|
-
|
|
95
|
-
// this._matrixWatch = onChange(this.gameObject.matrix, "elements", (newValue, oldValue) => {
|
|
96
|
-
// if (newValue !== oldValue) {
|
|
97
|
-
// if (!this.context.physics.isUpdating && !this._ignoreChange) {
|
|
98
|
-
// this.dirty = true;
|
|
99
|
-
// this._setMatrix.copy(this.gameObject.matrix);
|
|
100
|
-
// }
|
|
101
|
-
// }
|
|
102
|
-
// });
|
|
103
98
|
}
|
|
104
99
|
|
|
105
100
|
onDisable(): void {
|
|
106
|
-
// this._matrixWatch?.u();
|
|
107
101
|
if (this._body)
|
|
108
102
|
this.context.physics.removeBody(this.gameObject, this._body, false);
|
|
109
103
|
}
|
|
@@ -113,27 +107,23 @@ export class Rigidbody extends Behaviour {
|
|
|
113
107
|
this.context.physics.removeBody(this.gameObject, this._body);
|
|
114
108
|
}
|
|
115
109
|
|
|
116
|
-
|
|
110
|
+
onBeforeRender() {
|
|
111
|
+
this._ignoreChange = true;
|
|
112
|
+
this.updateVelocity();
|
|
113
|
+
|
|
117
114
|
if (this._dirty) {
|
|
118
|
-
this._ignoreChange = true;
|
|
119
115
|
this._dirty = false;
|
|
120
|
-
// // console.log("RESET");
|
|
121
116
|
this._setMatrix.decompose(this.gameObject.position, this.gameObject.quaternion, this.gameObject.scale);
|
|
122
117
|
this.setBodyFromGameObject();
|
|
123
|
-
this._ignoreChange = false;
|
|
124
118
|
}
|
|
125
|
-
|
|
126
|
-
onBeforeRender() {
|
|
127
|
-
this._ignoreChange = true;
|
|
128
|
-
this.updateVelocity();
|
|
129
|
-
// this._ignoreChange = true;
|
|
130
|
-
// this._setMatrix.decompose(this.gameObject.position, this.gameObject.quaternion, this.gameObject.scale);
|
|
131
|
-
// this.setBodyFromGameObject();
|
|
119
|
+
|
|
132
120
|
this._ignoreChange = false;
|
|
133
121
|
}
|
|
134
122
|
|
|
135
123
|
initialize() {
|
|
136
|
-
if (this._body)
|
|
124
|
+
if (this._body) {
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
137
127
|
const options = new BodyOptions();
|
|
138
128
|
options.drag = this.drag;
|
|
139
129
|
options.angularDrag = this.angularDrag;
|
|
@@ -149,8 +139,14 @@ export class Rigidbody extends Behaviour {
|
|
|
149
139
|
this.body?.wakeUp();
|
|
150
140
|
}
|
|
151
141
|
|
|
152
|
-
public applyForce(vec: THREE.Vector3, rel
|
|
153
|
-
|
|
142
|
+
public applyForce(vec: THREE.Vector3, rel?: THREE.Vector3) {
|
|
143
|
+
const force = new CANNON.Vec3(vec.x, vec.y, vec.z);
|
|
144
|
+
force.scale(1 / this.context.time.deltaTime, force);
|
|
145
|
+
this.body?.applyForce(force, rel ? new CANNON.Vec3(rel.x, rel.y, rel.z) : undefined);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
public setForce(x: number, y: number, z: number) {
|
|
149
|
+
this.body?.force.set(x, y, z);
|
|
154
150
|
}
|
|
155
151
|
|
|
156
152
|
public getVelocity(): THREE.Vector3 {
|
|
@@ -159,13 +155,39 @@ export class Rigidbody extends Behaviour {
|
|
|
159
155
|
return Rigidbody.tempPosition.set(0, 0, 0);
|
|
160
156
|
}
|
|
161
157
|
|
|
162
|
-
public setVelocity(x: number, y: number, z: number) {
|
|
158
|
+
public setVelocity(x: number | Vector3, y: number, z: number) {
|
|
163
159
|
if (!this.body) return;
|
|
160
|
+
if (x instanceof Vector3) {
|
|
161
|
+
const vec = x;
|
|
162
|
+
x = vec.x;
|
|
163
|
+
y = vec.y;
|
|
164
|
+
z = vec.z;
|
|
165
|
+
}
|
|
164
166
|
this.body.velocity.x = x / this.context.time.deltaTime;
|
|
165
167
|
this.body.velocity.y = y / this.context.time.deltaTime;
|
|
166
168
|
this.body.velocity.z = z / this.context.time.deltaTime;
|
|
167
169
|
}
|
|
168
170
|
|
|
171
|
+
public getTorque(): THREE.Vector3 {
|
|
172
|
+
if (this.body)
|
|
173
|
+
return Rigidbody.tempPosition.set(this.body?.torque.x, this.body?.torque.y, this.body?.torque.z);
|
|
174
|
+
return Rigidbody.tempPosition.set(0, 0, 0);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
public setTorque(x: number | Vector3, y: number, z: number) {
|
|
178
|
+
if (!this.body) return;
|
|
179
|
+
if (x instanceof Vector3) {
|
|
180
|
+
const vec = x;
|
|
181
|
+
x = vec.x;
|
|
182
|
+
y = vec.y;
|
|
183
|
+
z = vec.z;
|
|
184
|
+
}
|
|
185
|
+
this.body.torque.x = x / this.context.time.deltaTime;
|
|
186
|
+
this.body.torque.y = y / this.context.time.deltaTime;
|
|
187
|
+
this.body.torque.z = z / this.context.time.deltaTime;
|
|
188
|
+
|
|
189
|
+
}
|
|
190
|
+
|
|
169
191
|
public get smoothedVelocity() { return this._smoothedVelocity; }
|
|
170
192
|
|
|
171
193
|
public setAngularVelocity(x: number, y: number, z: number) {
|