@needle-tools/engine 3.3.0-alpha → 3.5.0-alpha
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 +19 -0
- package/dist/needle-engine.js +62620 -61118
- package/dist/needle-engine.min.js +434 -410
- package/dist/needle-engine.umd.cjs +435 -411
- package/lib/engine/api.d.ts +1 -0
- package/lib/engine/api.js +1 -0
- package/lib/engine/api.js.map +1 -1
- package/lib/engine/codegen/register_types.js +50 -2
- package/lib/engine/codegen/register_types.js.map +1 -1
- package/lib/engine/engine_context.d.ts +1 -1
- package/lib/engine/engine_context.js +21 -15
- package/lib/engine/engine_context.js.map +1 -1
- package/lib/engine/engine_context_registry.d.ts +5 -3
- package/lib/engine/engine_context_registry.js +10 -2
- package/lib/engine/engine_context_registry.js.map +1 -1
- package/lib/engine/engine_element.js.map +1 -1
- package/lib/engine/engine_element_loading.js +2 -3
- package/lib/engine/engine_element_loading.js.map +1 -1
- package/lib/engine/engine_gameobject.d.ts +1 -1
- package/lib/engine/engine_gameobject.js +4 -2
- package/lib/engine/engine_gameobject.js.map +1 -1
- package/lib/engine/engine_input.d.ts +2 -2
- package/lib/engine/engine_physics.d.ts +20 -93
- package/lib/engine/engine_physics.js +20 -892
- package/lib/engine/engine_physics.js.map +1 -1
- package/lib/engine/engine_physics.types.js.map +1 -1
- package/lib/engine/engine_physics_rapier.d.ts +103 -0
- package/lib/engine/engine_physics_rapier.js +1003 -0
- package/lib/engine/engine_physics_rapier.js.map +1 -0
- package/lib/engine/engine_three_utils.js +2 -2
- package/lib/engine/engine_three_utils.js.map +1 -1
- package/lib/engine/engine_types.d.ts +50 -1
- package/lib/engine/engine_types.js +8 -0
- package/lib/engine/engine_types.js.map +1 -1
- package/lib/engine-components/Animation.js +4 -0
- package/lib/engine-components/Animation.js.map +1 -1
- package/lib/engine-components/Collider.js +6 -6
- package/lib/engine-components/Collider.js.map +1 -1
- package/lib/engine-components/Joints.js +2 -2
- package/lib/engine-components/Joints.js.map +1 -1
- package/lib/engine-components/RigidBody.d.ts +0 -1
- package/lib/engine-components/RigidBody.js +24 -30
- package/lib/engine-components/RigidBody.js.map +1 -1
- package/lib/engine-components/codegen/components.d.ts +25 -1
- package/lib/engine-components/codegen/components.js +25 -1
- package/lib/engine-components/codegen/components.js.map +1 -1
- package/lib/engine-components/export/usdz/Extension.d.ts +4 -4
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.d.ts +86 -0
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js +858 -0
- package/lib/engine-components/export/usdz/ThreeUSDZExporter.js.map +1 -0
- package/lib/engine-components/export/usdz/USDZExporter.d.ts +6 -3
- package/lib/engine-components/export/usdz/USDZExporter.js +34 -11
- package/lib/engine-components/export/usdz/USDZExporter.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/Animation.d.ts +15 -15
- package/lib/engine-components/export/usdz/extensions/Animation.js +24 -29
- package/lib/engine-components/export/usdz/extensions/Animation.js.map +1 -1
- package/lib/engine-components/export/usdz/extensions/DocumentExtension.d.ts +5 -0
- package/lib/engine-components/export/usdz/extensions/DocumentExtension.js +7 -0
- package/lib/engine-components/export/usdz/extensions/DocumentExtension.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/USDZText.d.ts +47 -0
- package/lib/engine-components/export/usdz/extensions/USDZText.js +114 -0
- package/lib/engine-components/export/usdz/extensions/USDZText.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Actions.d.ts +30 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Actions.js +89 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Actions.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.d.ts +23 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js +114 -0
- package/lib/engine-components/export/usdz/extensions/behavior/Behaviour.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.d.ts +102 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js +458 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehaviourComponents.js.map +1 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.d.ts +111 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js +409 -0
- package/lib/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.js.map +1 -0
- package/lib/engine-components/postprocessing/PostProcessingHandler.js.map +1 -1
- package/lib/engine-components/ui/BaseUIComponent.d.ts +2 -0
- package/lib/engine-components/ui/BaseUIComponent.js +6 -0
- package/lib/engine-components/ui/BaseUIComponent.js.map +1 -1
- package/lib/engine-components/ui/Canvas.d.ts +11 -1
- package/lib/engine-components/ui/Canvas.js +72 -3
- package/lib/engine-components/ui/Canvas.js.map +1 -1
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/Image.js +4 -4
- package/lib/engine-components/ui/Image.js.map +1 -1
- package/lib/engine-components/ui/Interfaces.d.ts +11 -0
- package/lib/engine-components/ui/Interfaces.js +11 -0
- package/lib/engine-components/ui/Interfaces.js.map +1 -1
- package/lib/engine-components/ui/Layout.d.ts +65 -3
- package/lib/engine-components/ui/Layout.js +304 -3
- package/lib/engine-components/ui/Layout.js.map +1 -1
- package/lib/engine-components/ui/RectTransform.d.ts +8 -7
- package/lib/engine-components/ui/RectTransform.js +66 -36
- package/lib/engine-components/ui/RectTransform.js.map +1 -1
- package/lib/engine-components/utils/LookAt.d.ts +7 -1
- package/lib/engine-components/utils/LookAt.js +43 -6
- package/lib/engine-components/utils/LookAt.js.map +1 -1
- package/lib/engine-components/webxr/WebXRImageTracking.d.ts +4 -3
- package/lib/engine-components/webxr/WebXRImageTracking.js +81 -25
- package/lib/engine-components/webxr/WebXRImageTracking.js.map +1 -1
- package/lib/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/plugins/vite/config.js +2 -1
- package/plugins/vite/defines.js +30 -0
- package/plugins/vite/dependency-watcher.js +173 -0
- package/plugins/vite/editor-connection.js +37 -39
- package/plugins/vite/index.js +5 -1
- package/plugins/vite/reload.js +16 -3
- package/src/engine/api.ts +1 -0
- package/src/engine/codegen/register_types.js +50 -2
- package/src/engine/engine_context.ts +32 -23
- package/src/engine/engine_context_registry.ts +13 -6
- package/src/engine/engine_element.ts +2 -1
- package/src/engine/engine_element_loading.ts +2 -3
- package/src/engine/engine_gameobject.ts +3 -2
- package/src/engine/engine_input.ts +2 -2
- package/src/engine/engine_physics.ts +25 -1020
- package/src/engine/engine_physics.types.ts +1 -3
- package/src/engine/engine_physics_rapier.ts +1127 -0
- package/src/engine/engine_three_utils.ts +2 -2
- package/src/engine/engine_types.ts +66 -4
- package/src/engine-components/Animation.ts +4 -0
- package/src/engine-components/Collider.ts +6 -6
- package/src/engine-components/Joints.ts +2 -2
- package/src/engine-components/RigidBody.ts +24 -31
- package/src/engine-components/codegen/components.ts +25 -1
- package/src/engine-components/export/usdz/Extension.ts +4 -5
- package/src/engine-components/export/usdz/ThreeUSDZExporter.ts +1312 -0
- package/src/engine-components/export/usdz/USDZExporter.ts +39 -17
- package/src/engine-components/export/usdz/extensions/Animation.ts +37 -45
- package/src/engine-components/export/usdz/extensions/DocumentExtension.ts +10 -0
- package/src/engine-components/export/usdz/extensions/USDZText.ts +142 -0
- package/src/engine-components/export/usdz/extensions/behavior/Actions.ts +99 -0
- package/src/engine-components/export/usdz/extensions/behavior/Behaviour.ts +181 -0
- package/src/engine-components/export/usdz/extensions/behavior/BehaviourComponents.ts +545 -0
- package/src/engine-components/export/usdz/extensions/behavior/BehavioursBuilder.ts +459 -0
- package/src/engine-components/postprocessing/PostProcessingHandler.ts +1 -1
- package/src/engine-components/ui/BaseUIComponent.ts +7 -1
- package/src/engine-components/ui/Canvas.ts +80 -5
- package/src/engine-components/ui/Graphic.ts +2 -0
- package/src/engine-components/ui/Image.ts +3 -3
- package/src/engine-components/ui/Interfaces.ts +30 -6
- package/src/engine-components/ui/Layout.ts +303 -4
- package/src/engine-components/ui/RectTransform.ts +67 -41
- package/src/engine-components/utils/LookAt.ts +60 -7
- package/src/engine-components/webxr/WebXRImageTracking.ts +100 -27
- package/lib/engine-components/export/usdz/types.d.ts +0 -34
- package/lib/engine-components/export/usdz/types.js +0 -2
- package/lib/engine-components/export/usdz/types.js.map +0 -1
- package/src/engine-components/export/usdz/types.ts +0 -39
|
@@ -0,0 +1,459 @@
|
|
|
1
|
+
import { Object3D } from "three";
|
|
2
|
+
import { USDDocument, USDObject, USDWriter, makeNameSafeForUSD } from "../../ThreeUSDZExporter";
|
|
3
|
+
|
|
4
|
+
import { BehaviorExtension } from "./Behaviour";
|
|
5
|
+
|
|
6
|
+
// TODO: rename to usdz element
|
|
7
|
+
export interface IBehaviorElement {
|
|
8
|
+
id: string;
|
|
9
|
+
writeTo(document: USDDocument, writer: USDWriter);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export class BehaviorModel {
|
|
13
|
+
|
|
14
|
+
static global_id: number = 0;
|
|
15
|
+
id: string;
|
|
16
|
+
trigger: IBehaviorElement | IBehaviorElement[];
|
|
17
|
+
action: IBehaviorElement;
|
|
18
|
+
exclusive: boolean = false;
|
|
19
|
+
|
|
20
|
+
makeExclusive(exclusive: boolean): BehaviorModel {
|
|
21
|
+
this.exclusive = exclusive;
|
|
22
|
+
return this;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
constructor(id: string, trigger: IBehaviorElement | IBehaviorElement[], action: IBehaviorElement) {
|
|
26
|
+
this.id = "Behavior_" + makeNameSafeForUSD(id) + "_" + BehaviorModel.global_id++;
|
|
27
|
+
this.trigger = trigger;
|
|
28
|
+
this.action = action;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
writeTo(_ext: BehaviorExtension, document: USDDocument, writer: USDWriter) {
|
|
32
|
+
if (!this.trigger || !this.action) return;
|
|
33
|
+
writer.beginBlock(`def Preliminary_Behavior "${this.id}"`);
|
|
34
|
+
writer.appendLine(`rel actions = <${this.action.id}>`);
|
|
35
|
+
writer.appendLine(`uniform bool exclusive = ${this.exclusive}`);
|
|
36
|
+
let triggerString = "";
|
|
37
|
+
if (Array.isArray(this.trigger)) {
|
|
38
|
+
triggerString = "[";
|
|
39
|
+
for (let i = 0; i < this.trigger.length; i++) {
|
|
40
|
+
const tr = this.trigger[i];
|
|
41
|
+
triggerString += "<" + tr.id + ">";
|
|
42
|
+
if (i + 1 < this.trigger.length) triggerString += ", ";
|
|
43
|
+
}
|
|
44
|
+
triggerString += "]";
|
|
45
|
+
}
|
|
46
|
+
else
|
|
47
|
+
triggerString = `<${this.trigger.id}>`;
|
|
48
|
+
|
|
49
|
+
writer.appendLine(`rel triggers = ${triggerString} `);
|
|
50
|
+
writer.appendLine();
|
|
51
|
+
if (Array.isArray(this.trigger)) {
|
|
52
|
+
for (const trigger of this.trigger) {
|
|
53
|
+
trigger.writeTo(document, writer);
|
|
54
|
+
writer.appendLine();
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
else
|
|
58
|
+
this.trigger.writeTo(document, writer);
|
|
59
|
+
writer.appendLine();
|
|
60
|
+
this.action.writeTo(document, writer);
|
|
61
|
+
writer.closeBlock();
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
type Target = USDObject | USDObject[] | Object3D | Object3D[];
|
|
67
|
+
|
|
68
|
+
/** called to resolve target objects to usdz paths */
|
|
69
|
+
function resolve(targetObject: Target, document: USDDocument): string {
|
|
70
|
+
let result: string = "";
|
|
71
|
+
if (Array.isArray(targetObject)) {
|
|
72
|
+
let str = "[ ";
|
|
73
|
+
for (let i = 0; i < targetObject.length; i++) {
|
|
74
|
+
let obj = targetObject[i];
|
|
75
|
+
if (typeof obj === "string")
|
|
76
|
+
str += obj;
|
|
77
|
+
else if ( typeof obj === "object") {
|
|
78
|
+
//@ts-ignore
|
|
79
|
+
if (obj.isObject3D) {
|
|
80
|
+
//@ts-ignore
|
|
81
|
+
obj = document.findById(obj.uuid);
|
|
82
|
+
}
|
|
83
|
+
const res = (obj as any).getPath?.call(obj) as string;
|
|
84
|
+
str += res;
|
|
85
|
+
}
|
|
86
|
+
if (i + 1 < targetObject.length) str += ", ";
|
|
87
|
+
}
|
|
88
|
+
str += " ]";
|
|
89
|
+
result = str;
|
|
90
|
+
}
|
|
91
|
+
else if (typeof targetObject === "object") {
|
|
92
|
+
//@ts-ignore
|
|
93
|
+
if (targetObject.isObject3D) {
|
|
94
|
+
//@ts-ignore
|
|
95
|
+
targetObject = document.findById(targetObject.uuid);
|
|
96
|
+
}
|
|
97
|
+
result = (targetObject as any).getPath?.call(targetObject) as string;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// in three there's now a new "Scenes" parent and "Scene" xform that's injected;
|
|
101
|
+
// we need to add this to our path here so that we have full paths
|
|
102
|
+
result = result.replace(document.name, document.name + "/Scenes/Scene");
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export class TriggerModel implements IBehaviorElement {
|
|
107
|
+
static global_id: number = 0;
|
|
108
|
+
|
|
109
|
+
id: string;
|
|
110
|
+
targetId?: string | Target;
|
|
111
|
+
tokenId?: string;
|
|
112
|
+
type?: string;
|
|
113
|
+
|
|
114
|
+
constructor(targetId?: string | Target, id?: string) {
|
|
115
|
+
if (targetId) this.targetId = targetId;
|
|
116
|
+
if (id) this.id = id;
|
|
117
|
+
else this.id = "Trigger_" + TriggerModel.global_id++;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
writeTo(document: USDDocument, writer: USDWriter) {
|
|
121
|
+
writer.beginBlock(`def Preliminary_Trigger "${this.id}"`);
|
|
122
|
+
if (this.targetId) {
|
|
123
|
+
if (typeof this.targetId !== "string") this.targetId = resolve(this.targetId, document);
|
|
124
|
+
writer.appendLine(`rel affectedObjects = ` + this.targetId);
|
|
125
|
+
}
|
|
126
|
+
if (this.tokenId)
|
|
127
|
+
writer.appendLine(`token info:id = "${this.tokenId}"`);
|
|
128
|
+
if (this.type)
|
|
129
|
+
writer.appendLine(`token type = "${this.type}"`);
|
|
130
|
+
writer.closeBlock();
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export class TriggerBuilder {
|
|
135
|
+
|
|
136
|
+
static sceneStartTrigger(): TriggerModel {
|
|
137
|
+
const trigger = new TriggerModel();
|
|
138
|
+
trigger.targetId = undefined;
|
|
139
|
+
trigger.tokenId = "SceneTransition";
|
|
140
|
+
trigger.type = "enter";
|
|
141
|
+
return trigger;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
static tapTrigger(targetObject: Target): TriggerModel {
|
|
145
|
+
const trigger = new TriggerModel(targetObject);
|
|
146
|
+
trigger.tokenId = "TapGesture";
|
|
147
|
+
return trigger;
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
static isTapTrigger(trigger?: TriggerModel) {
|
|
151
|
+
return trigger?.tokenId === "TapGesture";
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
export class GroupActionModel implements IBehaviorElement {
|
|
156
|
+
|
|
157
|
+
static global_id: number = 0;
|
|
158
|
+
static getId(): number {
|
|
159
|
+
return this.global_id++;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
id: string;
|
|
163
|
+
actions: IBehaviorElement[];
|
|
164
|
+
loops: number = 0;
|
|
165
|
+
performCount: number = 1;
|
|
166
|
+
type: string = "serial";
|
|
167
|
+
|
|
168
|
+
constructor(id: string, actions: IBehaviorElement[]) {
|
|
169
|
+
this.id = id;
|
|
170
|
+
this.actions = actions;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
addAction(el: IBehaviorElement): GroupActionModel {
|
|
174
|
+
this.actions.push(el);
|
|
175
|
+
return this;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
makeParallel(): GroupActionModel {
|
|
179
|
+
this.type = "parallel";
|
|
180
|
+
return this;
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
makeSequence(): GroupActionModel {
|
|
184
|
+
this.type = "serial";
|
|
185
|
+
return this;
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
makeLooping() {
|
|
189
|
+
this.loops = 1;
|
|
190
|
+
return this;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
makeRepeat(count: number) {
|
|
194
|
+
this.performCount = count;
|
|
195
|
+
return this;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
writeTo(document: USDDocument, writer: USDWriter) {
|
|
199
|
+
writer.beginBlock(`def Preliminary_Action "${this.id}"`);
|
|
200
|
+
writer.beginArray("rel actions");
|
|
201
|
+
for (const act of this.actions) {
|
|
202
|
+
if (!act) continue;
|
|
203
|
+
writer.appendLine("<" + act.id + ">,");
|
|
204
|
+
}
|
|
205
|
+
writer.closeArray();
|
|
206
|
+
writer.appendLine();
|
|
207
|
+
|
|
208
|
+
writer.appendLine(`token info:id = "Group"`);
|
|
209
|
+
writer.appendLine(`bool loops = ${this.loops} `);
|
|
210
|
+
writer.appendLine(`int performCount = ${this.performCount} `);
|
|
211
|
+
writer.appendLine(`token type = "${this.type}"`);
|
|
212
|
+
writer.appendLine();
|
|
213
|
+
|
|
214
|
+
for (const act of this.actions) {
|
|
215
|
+
if (!act) continue;
|
|
216
|
+
act.writeTo(document, writer);
|
|
217
|
+
writer.appendLine();
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
writer.closeBlock();
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
export enum MotionType {
|
|
225
|
+
pop = 0,
|
|
226
|
+
blink = 1,
|
|
227
|
+
bounce = 2,
|
|
228
|
+
flip = 3,
|
|
229
|
+
float = 4,
|
|
230
|
+
jiggle = 5,
|
|
231
|
+
pulse = 6,
|
|
232
|
+
spin = 7,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
export enum Space {
|
|
236
|
+
Relative = "relative",
|
|
237
|
+
Absolute = "absolute"
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
export class ActionModel implements IBehaviorElement {
|
|
241
|
+
|
|
242
|
+
private static global_id: number = 0;
|
|
243
|
+
|
|
244
|
+
id: string;
|
|
245
|
+
tokenId?: string;
|
|
246
|
+
affectedObjects?: string | Target;
|
|
247
|
+
easeType?: string;;
|
|
248
|
+
motionType?: string;
|
|
249
|
+
duration?: number;
|
|
250
|
+
moveDistance?: number;
|
|
251
|
+
style?: string;
|
|
252
|
+
type?: string;
|
|
253
|
+
front?: Vec3;
|
|
254
|
+
up?: Vec3;
|
|
255
|
+
start?: number;
|
|
256
|
+
animationSpeed?: number;
|
|
257
|
+
reversed?: boolean;
|
|
258
|
+
pingPong?: boolean;
|
|
259
|
+
xFormTarget?: Target | string;
|
|
260
|
+
|
|
261
|
+
clone(): ActionModel {
|
|
262
|
+
const copy = new ActionModel();
|
|
263
|
+
const id = copy.id;
|
|
264
|
+
Object.assign(copy, this);
|
|
265
|
+
copy.id = id;
|
|
266
|
+
return copy;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
constructor(affectedObjects?: string | Target, id?: string) {
|
|
270
|
+
if (affectedObjects) this.affectedObjects = affectedObjects;
|
|
271
|
+
if (id) this.id = id;
|
|
272
|
+
/*else if (affectedObjects) {
|
|
273
|
+
this.id = "Action_" + sanitizeId(affectedObjects);
|
|
274
|
+
}
|
|
275
|
+
else */
|
|
276
|
+
else
|
|
277
|
+
this.id = "Action";
|
|
278
|
+
this.id += "_" + ActionModel.global_id++;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
writeTo(document: USDDocument, writer: USDWriter) {
|
|
282
|
+
writer.beginBlock(`def Preliminary_Action "${this.id}"`);
|
|
283
|
+
if (this.affectedObjects) {
|
|
284
|
+
if (typeof this.affectedObjects !== "string") this.affectedObjects = resolve(this.affectedObjects, document);
|
|
285
|
+
writer.appendLine('rel affectedObjects = ' + this.affectedObjects);
|
|
286
|
+
}
|
|
287
|
+
if (typeof this.duration === "number")
|
|
288
|
+
writer.appendLine(`double duration = ${this.duration} `);
|
|
289
|
+
if (this.easeType)
|
|
290
|
+
writer.appendLine(`token easeType = "${this.easeType}"`);
|
|
291
|
+
if (this.tokenId)
|
|
292
|
+
writer.appendLine(`token info:id = "${this.tokenId}"`);
|
|
293
|
+
if (this.motionType)
|
|
294
|
+
writer.appendLine(`token motionType = "${this.motionType}"`);
|
|
295
|
+
if (typeof this.moveDistance === "number")
|
|
296
|
+
writer.appendLine(`double moveDistance = ${this.moveDistance} `);
|
|
297
|
+
if (this.style)
|
|
298
|
+
writer.appendLine(`token style = "${this.style}"`);
|
|
299
|
+
if (this.type)
|
|
300
|
+
writer.appendLine(`token type = "${this.type}"`);
|
|
301
|
+
if (this.front)
|
|
302
|
+
writer.appendLine(`vector3d front = (${this.front.x}, ${this.front.y}, ${this.front.z})`);
|
|
303
|
+
if (this.up)
|
|
304
|
+
writer.appendLine(`vector3d upVector = (${this.up.x}, ${this.up.y}, ${this.up.z})`);
|
|
305
|
+
if (typeof this.start === "number") {
|
|
306
|
+
writer.appendLine(`double start = ${this.start} `);
|
|
307
|
+
}
|
|
308
|
+
if (typeof this.animationSpeed === "number") {
|
|
309
|
+
writer.appendLine(`double animationSpeed = ${this.animationSpeed} `);
|
|
310
|
+
}
|
|
311
|
+
if (typeof this.reversed === "boolean") {
|
|
312
|
+
writer.appendLine(`bool reversed = ${this.reversed}`)
|
|
313
|
+
}
|
|
314
|
+
if (typeof this.pingPong === "boolean") {
|
|
315
|
+
writer.appendLine(`bool reverses = ${this.pingPong}`)
|
|
316
|
+
}
|
|
317
|
+
if (this.xFormTarget) {
|
|
318
|
+
if (typeof this.xFormTarget !== "string")
|
|
319
|
+
this.xFormTarget = resolve(this.xFormTarget, document);
|
|
320
|
+
writer.appendLine(`rel xformTarget = ${this.xFormTarget}`)
|
|
321
|
+
}
|
|
322
|
+
writer.closeBlock();
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
class Vec3 {
|
|
327
|
+
x: number = 0;
|
|
328
|
+
y: number = 0;
|
|
329
|
+
z: number = 0;
|
|
330
|
+
|
|
331
|
+
constructor(x: number, y: number, z: number) {
|
|
332
|
+
this.x = x;
|
|
333
|
+
this.y = y;
|
|
334
|
+
this.z = z;
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
static get up(): Vec3 {
|
|
338
|
+
return new Vec3(0, 1, 0);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
static get right(): Vec3 {
|
|
342
|
+
return new Vec3(1, 0, 0);
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
static get forward(): Vec3 {
|
|
346
|
+
return new Vec3(0, 0, 1);
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
static get back(): Vec3 {
|
|
350
|
+
return new Vec3(0, 0, -1);
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
static get zero(): Vec3 {
|
|
354
|
+
return new Vec3(0, 0, 0);
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
export class ActionBuilder {
|
|
359
|
+
|
|
360
|
+
static sequence(...params: IBehaviorElement[]) {
|
|
361
|
+
const group = new GroupActionModel("group_" + GroupActionModel.getId(), params);
|
|
362
|
+
return group.makeSequence();
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
static parallel(...params: IBehaviorElement[]) {
|
|
366
|
+
const group = new GroupActionModel("group_" + GroupActionModel.getId(), params);
|
|
367
|
+
return group.makeParallel();
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
static fadeAction(targetObject: Target, duration: number, show: boolean): ActionModel {
|
|
371
|
+
const act = new ActionModel(targetObject);
|
|
372
|
+
act.tokenId = "Visibility";
|
|
373
|
+
act.type = show ? "show" : "hide";
|
|
374
|
+
act.duration = duration;
|
|
375
|
+
|
|
376
|
+
act.style = "basic";
|
|
377
|
+
act.motionType = "none";
|
|
378
|
+
act.moveDistance = 0;
|
|
379
|
+
act.easeType = "none";
|
|
380
|
+
return act;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* creates an action that plays an animation
|
|
385
|
+
* @param start offset in seconds!
|
|
386
|
+
* @param duration in seconds! 0 means play to end
|
|
387
|
+
*/
|
|
388
|
+
static startAnimationAction(targetObject: Target, start: number, duration: number = 0, animationSpeed: number = 1, reversed: boolean = false, pingPong: boolean = false): IBehaviorElement {
|
|
389
|
+
const act = new ActionModel(targetObject);
|
|
390
|
+
act.tokenId = "StartAnimation";
|
|
391
|
+
act.start = start;
|
|
392
|
+
// start is time in seconds, the documentation is not right here
|
|
393
|
+
act.duration = duration;
|
|
394
|
+
// duration of 0 is play to end
|
|
395
|
+
act.animationSpeed = animationSpeed;
|
|
396
|
+
act.reversed = reversed;
|
|
397
|
+
act.pingPong = pingPong;
|
|
398
|
+
if (reversed) {
|
|
399
|
+
act.start -= duration;
|
|
400
|
+
//console.warn("Reversed animation does currently not work. The resulting file will most likely not playback.", act.id, targetObject);
|
|
401
|
+
}
|
|
402
|
+
if (pingPong) {
|
|
403
|
+
act.pingPong = false;
|
|
404
|
+
const back = act.clone();
|
|
405
|
+
back.reversed = !reversed;
|
|
406
|
+
back.start = act.start;
|
|
407
|
+
if (back.reversed) {
|
|
408
|
+
back.start -= duration;
|
|
409
|
+
}
|
|
410
|
+
const group = ActionBuilder.sequence(act, back);
|
|
411
|
+
return group;
|
|
412
|
+
}
|
|
413
|
+
return act;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
static waitAction(duration: number): ActionModel {
|
|
417
|
+
const act = new ActionModel();
|
|
418
|
+
act.tokenId = "Wait";
|
|
419
|
+
act.duration = duration;
|
|
420
|
+
return act;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
static lookAtCameraAction(targets: Target, duration: number = 9999999999999, front?: Vec3, up?: Vec3): ActionModel {
|
|
424
|
+
const act = new ActionModel(targets);
|
|
425
|
+
act.tokenId = "LookAtCamera";
|
|
426
|
+
act.duration = duration;
|
|
427
|
+
act.front = front ?? Vec3.forward;
|
|
428
|
+
// 0,0,0 is a special case for "free look"
|
|
429
|
+
// 0,1,0 is for "y-locked look-at"
|
|
430
|
+
act.up = up ?? Vec3.up;
|
|
431
|
+
return act;
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
static emphasize(targets: Target, duration: number, motionType: MotionType = MotionType.bounce, moveDistance: number = 1, style: string = "basic") {
|
|
435
|
+
const act = new ActionModel(targets);
|
|
436
|
+
act.tokenId = "Emphasize";
|
|
437
|
+
act.duration = duration;
|
|
438
|
+
act.style = style ?? "basic";
|
|
439
|
+
act.motionType = MotionType[motionType];
|
|
440
|
+
act.moveDistance = moveDistance;
|
|
441
|
+
return act;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
static transformAction(targets: Target, transformTarget: Target, duration: number, transformType: Space, easeType: string = "inout") {
|
|
445
|
+
const act = new ActionModel(targets);
|
|
446
|
+
act.tokenId = "Transform";
|
|
447
|
+
act.duration = duration;
|
|
448
|
+
act.type = transformType;
|
|
449
|
+
act.easeType = easeType;
|
|
450
|
+
if (Array.isArray(transformTarget)) {
|
|
451
|
+
console.error("Transform target must not be an array", transformTarget);
|
|
452
|
+
}
|
|
453
|
+
act.xFormTarget = transformTarget;
|
|
454
|
+
return act;
|
|
455
|
+
}
|
|
456
|
+
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
export { Vec3 as USDVec3 }
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { HalfFloatType
|
|
1
|
+
import { HalfFloatType } from "three";
|
|
2
2
|
import { Context } from "../../engine/engine_setup";
|
|
3
3
|
import { getParam, isMobileDevice } from "../../engine/engine_utils";
|
|
4
4
|
import { BloomEffect, BrightnessContrastEffect, ChromaticAberrationEffect, DepthDownsamplingPass, DepthOfFieldEffect, Effect, EffectComposer, EffectPass, HueSaturationEffect, NormalPass, Pass, PixelationEffect, RenderPass, SelectiveBloomEffect, SSAOEffect, VignetteEffect } from "postprocessing";
|
|
@@ -4,7 +4,7 @@ import { Behaviour, GameObject } from "../Component";
|
|
|
4
4
|
import { EventSystem } from "./EventSystem";
|
|
5
5
|
import { showGizmos } from '../../engine/engine_default_parameters';
|
|
6
6
|
import { AxesHelper, Object3D } from 'three';
|
|
7
|
-
import { IGraphic } from './Interfaces';
|
|
7
|
+
import { ICanvas, IGraphic } from './Interfaces';
|
|
8
8
|
import { ShadowCastingMode } from '../Renderer';
|
|
9
9
|
export const includesDir = "./include";
|
|
10
10
|
|
|
@@ -50,6 +50,12 @@ export class BaseUIComponent extends Behaviour {
|
|
|
50
50
|
return this._root;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
+
protected get Canvas() {
|
|
54
|
+
const cv = this.Root as any as ICanvas;
|
|
55
|
+
if (cv?.isCanvas) return cv;
|
|
56
|
+
return null;
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
// private _intermediate?: Object3D;
|
|
54
60
|
protected _parentComponent?: BaseUIComponent | null = undefined;
|
|
55
61
|
|
|
@@ -3,12 +3,14 @@ import { serializable } from "../../engine/engine_serialization_decorator";
|
|
|
3
3
|
import { FrameEvent } from "../../engine/engine_setup";
|
|
4
4
|
import { BaseUIComponent, UIRootComponent } from "./BaseUIComponent";
|
|
5
5
|
import { GameObject } from "../Component";
|
|
6
|
-
import { Object3D } from "three";
|
|
6
|
+
import { Matrix4, Object3D } from "three";
|
|
7
7
|
import { RectTransform } from "./RectTransform";
|
|
8
|
-
import { ICanvas } from "./Interfaces";
|
|
8
|
+
import { ICanvas, ILayoutGroup, IRectTransform } from "./Interfaces";
|
|
9
9
|
import { Camera } from "../Camera";
|
|
10
10
|
import { EventSystem } from "./EventSystem";
|
|
11
11
|
import * as ThreeMeshUI from 'three-mesh-ui'
|
|
12
|
+
import { getParam } from "../../engine/engine_utils";
|
|
13
|
+
import { LayoutGroup } from "./Layout";
|
|
12
14
|
|
|
13
15
|
export enum RenderMode {
|
|
14
16
|
ScreenSpaceOverlay = 0,
|
|
@@ -17,8 +19,14 @@ export enum RenderMode {
|
|
|
17
19
|
Undefined = -1,
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
const debugLayout = getParam("debuguilayout");
|
|
23
|
+
|
|
20
24
|
export class Canvas extends UIRootComponent implements ICanvas {
|
|
21
25
|
|
|
26
|
+
get isCanvas() {
|
|
27
|
+
return true;
|
|
28
|
+
}
|
|
29
|
+
|
|
22
30
|
get screenspace(): any {
|
|
23
31
|
return this.renderMode !== RenderMode.WorldSpace;
|
|
24
32
|
}
|
|
@@ -122,6 +130,10 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
122
130
|
super.awake();
|
|
123
131
|
}
|
|
124
132
|
|
|
133
|
+
start() {
|
|
134
|
+
this.onUpdateRenderMode();
|
|
135
|
+
}
|
|
136
|
+
|
|
125
137
|
onEnable() {
|
|
126
138
|
super.onEnable();
|
|
127
139
|
this._updateRenderSettingsRoutine = undefined;
|
|
@@ -149,6 +161,28 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
149
161
|
private _boundRenderSettingsChanged = this.onRenderSettingsChanged.bind(this);
|
|
150
162
|
|
|
151
163
|
private previousParent: Object3D | null = null;
|
|
164
|
+
private _lastMatrixWorld: Matrix4 | null = null;
|
|
165
|
+
private _rectTransforms: IRectTransform[] = [];
|
|
166
|
+
|
|
167
|
+
registerTransform(rt: IRectTransform) {
|
|
168
|
+
this._rectTransforms.push(rt);
|
|
169
|
+
}
|
|
170
|
+
unregisterTransform(rt: IRectTransform) {
|
|
171
|
+
const index = this._rectTransforms.indexOf(rt);
|
|
172
|
+
if (index !== -1) {
|
|
173
|
+
this._rectTransforms.splice(index, 1);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
private _layoutGroups: Map<Object3D, ILayoutGroup> = new Map();
|
|
178
|
+
registerLayoutGroup(group: ILayoutGroup) {
|
|
179
|
+
const obj = group.gameObject;
|
|
180
|
+
this._layoutGroups.set(obj, group)
|
|
181
|
+
}
|
|
182
|
+
unregisterLayoutGroup(group: ILayoutGroup) {
|
|
183
|
+
const obj = group.gameObject;
|
|
184
|
+
this._layoutGroups.delete(obj);
|
|
185
|
+
}
|
|
152
186
|
|
|
153
187
|
onBeforeRenderRoutine = () => {
|
|
154
188
|
if (this.renderOnTop) {
|
|
@@ -158,6 +192,7 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
158
192
|
}
|
|
159
193
|
else {
|
|
160
194
|
this.onUpdateRenderMode();
|
|
195
|
+
this.handleLayoutUpdates();
|
|
161
196
|
// TODO: we might need to optimize this. This is here to make sure the TMUI text clipping matrices are correct. Ideally the text does use onBeforeRender and apply the clipping matrix there so we dont have to force update all the matrices here
|
|
162
197
|
this.shadowComponent?.updateMatrixWorld(true);
|
|
163
198
|
this.shadowComponent?.updateWorldMatrix(true, true);
|
|
@@ -171,11 +206,40 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
171
206
|
this.context.renderer.autoClear = false;
|
|
172
207
|
this.context.renderer.clearDepth();
|
|
173
208
|
this.onUpdateRenderMode(true);
|
|
209
|
+
this.handleLayoutUpdates();
|
|
174
210
|
this.shadowComponent?.updateMatrixWorld(true);
|
|
211
|
+
// this.handleLayoutUpdates();
|
|
175
212
|
EventSystem.ensureUpdateMeshUI(ThreeMeshUI, this.context);
|
|
176
213
|
this.context.renderer.render(this.gameObject, this.context.mainCamera);
|
|
177
214
|
this.context.renderer.autoClear = true;
|
|
178
215
|
}
|
|
216
|
+
this._lastMatrixWorld?.copy(this.gameObject.matrixWorld);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
private handleLayoutUpdates() {
|
|
220
|
+
if (this._lastMatrixWorld === null) {
|
|
221
|
+
this._lastMatrixWorld = new Matrix4();
|
|
222
|
+
}
|
|
223
|
+
const matrixWorldChanged = !this._lastMatrixWorld.equals(this.gameObject.matrixWorld);
|
|
224
|
+
if (debugLayout && matrixWorldChanged) console.log("Canvas Layout changed", this.context.time.frameCount, this.name);
|
|
225
|
+
|
|
226
|
+
// TODO: optimize this, we should only need to update a subhierarchy of the parts where layout has changed
|
|
227
|
+
let didLog = false;
|
|
228
|
+
for (const ch of this._rectTransforms) {
|
|
229
|
+
if (matrixWorldChanged) ch.markDirty();
|
|
230
|
+
let layout = this._layoutGroups.get(ch.gameObject);
|
|
231
|
+
if(ch.isDirty && !layout){
|
|
232
|
+
layout = ch.gameObject.getComponentInParent(LayoutGroup) as LayoutGroup;
|
|
233
|
+
}
|
|
234
|
+
if (ch.isDirty || layout?.isDirty) {
|
|
235
|
+
if (debugLayout && !didLog) {
|
|
236
|
+
console.log("CANVAS UPDATE ### " + ch.name + " ##################################### " + this.context.time.frame);
|
|
237
|
+
// didLog = true;
|
|
238
|
+
}
|
|
239
|
+
layout?.updateLayout();
|
|
240
|
+
ch.updateTransform();
|
|
241
|
+
}
|
|
242
|
+
}
|
|
179
243
|
}
|
|
180
244
|
|
|
181
245
|
applyRenderSettings() {
|
|
@@ -205,6 +269,7 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
205
269
|
private _lastWidth: number = -1;
|
|
206
270
|
private _lastHeight: number = -1;
|
|
207
271
|
|
|
272
|
+
|
|
208
273
|
private onUpdateRenderMode(force: boolean = false) {
|
|
209
274
|
if (!force) {
|
|
210
275
|
if (this._renderMode === this._activeRenderMode && this._lastWidth === this.context.domWidth && this._lastHeight === this.context.domHeight) {
|
|
@@ -241,6 +306,13 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
241
306
|
canvas.quaternion.identity();
|
|
242
307
|
|
|
243
308
|
const rect = this.gameObject.getComponent(RectTransform)!;
|
|
309
|
+
let hasChanged = false;
|
|
310
|
+
if (rect.sizeDelta.x !== this.context.domWidth) {
|
|
311
|
+
hasChanged = true;
|
|
312
|
+
}
|
|
313
|
+
if (rect.sizeDelta.y !== this.context.domHeight) {
|
|
314
|
+
hasChanged = true;
|
|
315
|
+
}
|
|
244
316
|
|
|
245
317
|
const vFOV = camera.fieldOfView! * Math.PI / 180;
|
|
246
318
|
const h = 2 * Math.tan(vFOV / 2) * Math.abs(plane);
|
|
@@ -248,9 +320,12 @@ export class Canvas extends UIRootComponent implements ICanvas {
|
|
|
248
320
|
canvas.scale.y = h / this.context.domHeight;
|
|
249
321
|
// Set scale.z, otherwise small offsets in screenspace mode have different visual results based on export scale and other settings
|
|
250
322
|
canvas.scale.z = .01;
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
323
|
+
|
|
324
|
+
if (hasChanged) {
|
|
325
|
+
rect.sizeDelta.x = this.context.domWidth;
|
|
326
|
+
rect.sizeDelta.y = this.context.domHeight;
|
|
327
|
+
rect?.markDirty();
|
|
328
|
+
}
|
|
254
329
|
|
|
255
330
|
|
|
256
331
|
// this.context.scene.add(this.gameObject)
|
|
@@ -9,6 +9,8 @@ import { onChange, scheduleAction } from "./Utils"
|
|
|
9
9
|
import { GameObject } from '../Component';
|
|
10
10
|
import SimpleStateBehavior from "three-mesh-ui/examples/behaviors/states/SimpleStateBehavior"
|
|
11
11
|
import { Outline } from './Outline';
|
|
12
|
+
import { BehaviorExtension, UsdzBehaviour } from '../../engine-components/export/usdz/extensions/behavior/Behaviour';
|
|
13
|
+
import { USDObject } from '../../engine-components/export/usdz/ThreeUSDZExporter';
|
|
12
14
|
|
|
13
15
|
const _colorStateObject: { backgroundColor: Color, backgroundOpacity: number } = {
|
|
14
16
|
backgroundColor: new Color(1, 1, 1),
|
|
@@ -49,9 +49,9 @@ export class Image extends MaskableGraphic {
|
|
|
49
49
|
if(this.sprite?.texture?.name === "Knob") {
|
|
50
50
|
opts.borderRadius = 999;
|
|
51
51
|
}
|
|
52
|
-
opts.borderColor = new Color(.4, .4, .4);
|
|
53
|
-
opts.borderOpacity = this.color.alpha;
|
|
54
|
-
opts.borderWidth = .3;
|
|
52
|
+
// opts.borderColor = new Color(.4, .4, .4);
|
|
53
|
+
// opts.borderOpacity = this.color.alpha;
|
|
54
|
+
// opts.borderWidth = .3;
|
|
55
55
|
}
|
|
56
56
|
|
|
57
57
|
}
|