@needle-tools/engine 3.32.21-alpha → 3.32.22-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 +6 -0
- package/dist/needle-engine.js +2856 -2833
- package/dist/needle-engine.light.js +2725 -2702
- package/dist/needle-engine.light.min.js +159 -159
- package/dist/needle-engine.light.umd.cjs +119 -119
- package/dist/needle-engine.min.js +159 -159
- package/dist/needle-engine.umd.cjs +119 -119
- package/lib/engine/extensions/NEEDLE_progressive.d.ts +11 -5
- package/lib/engine/extensions/NEEDLE_progressive.js +51 -34
- package/lib/engine/extensions/NEEDLE_progressive.js.map +1 -1
- package/lib/engine-components/SpriteRenderer.d.ts +4 -1
- package/lib/engine-components/SpriteRenderer.js +24 -4
- package/lib/engine-components/SpriteRenderer.js.map +1 -1
- package/lib/engine-components/ui/Graphic.d.ts +2 -1
- package/lib/engine-components/ui/Graphic.js +8 -2
- package/lib/engine-components/ui/Graphic.js.map +1 -1
- package/lib/engine-components/ui/Image.js +3 -2
- package/lib/engine-components/ui/Image.js.map +1 -1
- package/lib/engine-components-experimental/networking/PlayerSync.js +1 -1
- package/lib/engine-components-experimental/networking/PlayerSync.js.map +1 -1
- package/package.json +1 -1
- package/plugins/types/needleConfig.d.ts +1 -0
- package/plugins/types/userconfig.d.ts +3 -0
- package/plugins/vite/build-pipeline.js +97 -0
- package/plugins/vite/index.js +2 -0
- package/src/engine/extensions/NEEDLE_progressive.ts +61 -43
- package/src/engine-components/SpriteRenderer.ts +28 -7
- package/src/engine-components/ui/Graphic.ts +9 -2
- package/src/engine-components/ui/Image.ts +3 -2
- package/src/engine-components-experimental/networking/PlayerSync.ts +1 -1
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import { exec, spawn } from 'child_process';
|
|
2
|
+
import { getOutputDirectory, loadConfig, tryLoadProjectConfig } from './config.js';
|
|
3
|
+
import { existsSync, readdirSync } from 'fs';
|
|
4
|
+
|
|
5
|
+
// see https://linear.app/needle/issue/NE-3798
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Runs the needle build pipeline as part of the vite build process
|
|
9
|
+
* @param {import('../types').userSettings} userSettings
|
|
10
|
+
* @returns {import('vite').Plugin}
|
|
11
|
+
*/
|
|
12
|
+
export const needleBuildPipeline = async (command, config, userSettings) => {
|
|
13
|
+
// we only want to run compression here if this is a distribution build
|
|
14
|
+
if (command !== "build") return;
|
|
15
|
+
if (userSettings.noBuildPipeline) return;
|
|
16
|
+
|
|
17
|
+
const meta = await loadConfig();
|
|
18
|
+
let shouldRun = false;
|
|
19
|
+
if (meta && meta.developmentBuild === false) {
|
|
20
|
+
shouldRun = true;
|
|
21
|
+
}
|
|
22
|
+
if (!shouldRun) {
|
|
23
|
+
log("Skipping build pipeline because this is a development build");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** @type {Promise<any>|null} */
|
|
28
|
+
let task = null;
|
|
29
|
+
let taskFinished = false;
|
|
30
|
+
let taskSucceeded = false;
|
|
31
|
+
return {
|
|
32
|
+
name: 'needle-buildpipeline',
|
|
33
|
+
enforce: "post",
|
|
34
|
+
apply: 'build',
|
|
35
|
+
buildEnd() {
|
|
36
|
+
// start the compression process once vite is done copying the files
|
|
37
|
+
task = invokeBuildPipeline().then((res) => {
|
|
38
|
+
taskFinished = true;
|
|
39
|
+
taskSucceeded = res;
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
closeBundle() {
|
|
43
|
+
// this is the last hook that is called, so we can wait for the task to finish here
|
|
44
|
+
if (taskFinished) return;
|
|
45
|
+
// delay the final log slightly to give other plugins a chance to log their stuff
|
|
46
|
+
wait(100).then(() => {
|
|
47
|
+
if (!taskFinished) log("Waiting for postprocessing to finish...")
|
|
48
|
+
});
|
|
49
|
+
return task.then(_ => {
|
|
50
|
+
log("finished", taskSucceeded ? "successfully" : "with errors");
|
|
51
|
+
});
|
|
52
|
+
},
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
function log(...args) {
|
|
57
|
+
console.log("[needle-buildpipeline]", ...args);
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* @param {*} opts
|
|
62
|
+
* @returns {Promise<boolean>}
|
|
63
|
+
*/
|
|
64
|
+
async function invokeBuildPipeline(opts) {
|
|
65
|
+
await wait(1000);
|
|
66
|
+
const outputDirectory = getOutputDirectory() + "/assets";
|
|
67
|
+
if (!existsSync(outputDirectory)) {
|
|
68
|
+
log("No output directory found at ", outputDirectory);
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
const files = readdirSync(outputDirectory).filter(f => f.endsWith(".glb") || f.endsWith(".gltf"));
|
|
72
|
+
log(files.length + " file(s) to process");
|
|
73
|
+
|
|
74
|
+
const cmd = "npm run transform --prefix node_modules/@needle-tools/gltf-build-pipeline";
|
|
75
|
+
log("Running command \"" + cmd + "\" at " + process.cwd() + "...");
|
|
76
|
+
const sub = exec(cmd);
|
|
77
|
+
sub.stdout.on('data', data => {
|
|
78
|
+
if (data.length <= 0) return;
|
|
79
|
+
// ensure that it doesnt end with a newline
|
|
80
|
+
if (data.endsWith("\n")) data = data.slice(0, -1);
|
|
81
|
+
console.log(data);
|
|
82
|
+
});
|
|
83
|
+
sub.stderr.on('data', console.error);
|
|
84
|
+
return new Promise((resolve, reject) => {
|
|
85
|
+
sub.on('exit', (code) => {
|
|
86
|
+
resolve(code === 0);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function wait(ms) {
|
|
92
|
+
return new Promise((resolve, reject) => {
|
|
93
|
+
setTimeout(() => {
|
|
94
|
+
resolve();
|
|
95
|
+
}, ms);
|
|
96
|
+
});
|
|
97
|
+
}
|
package/plugins/vite/index.js
CHANGED
|
@@ -43,6 +43,7 @@ export { needleFacebookInstantGames } from "./facebook-instant-games.js";
|
|
|
43
43
|
import { vite_4_4_hack } from "./vite-4.4-hack.js";
|
|
44
44
|
import { needleImportsLogger } from "./imports-logger.js";
|
|
45
45
|
import { needleBuildInfo } from "./buildinfo.js";
|
|
46
|
+
import { needleBuildPipeline } from "./build-pipeline.js";
|
|
46
47
|
|
|
47
48
|
|
|
48
49
|
export * from "./gzip.js";
|
|
@@ -79,6 +80,7 @@ export const needlePlugins = async (command, config, userSettings) => {
|
|
|
79
80
|
vite_4_4_hack(command, config, userSettings),
|
|
80
81
|
needleFacebookInstantGames(command, config, userSettings),
|
|
81
82
|
needleImportsLogger(command, config, userSettings),
|
|
83
|
+
needleBuildPipeline(command, config, userSettings),
|
|
82
84
|
];
|
|
83
85
|
array.push(await editorConnection(command, config, userSettings, array));
|
|
84
86
|
return array;
|
|
@@ -22,6 +22,7 @@ let show_lod0 = false;
|
|
|
22
22
|
if (debug) {
|
|
23
23
|
window.addEventListener("keyup", evt => {
|
|
24
24
|
if (evt.key === "p") {
|
|
25
|
+
console.log("Toggle progressive textures", debug_toggle_maps);
|
|
25
26
|
debug_toggle_maps.forEach((map, material) => {
|
|
26
27
|
Object.entries(map).forEach(([key, value]) => {
|
|
27
28
|
if (show_lod0) {
|
|
@@ -43,51 +44,68 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
43
44
|
return EXTENSION_NAME;
|
|
44
45
|
}
|
|
45
46
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
47
|
+
/** Load a different resolution of a texture (if available)
|
|
48
|
+
* @param context the context
|
|
49
|
+
* @param source the sourceid of the file from which the texture is loaded (this is usually the component's sourceId)
|
|
50
|
+
* @param materialOrTexture the material or texture to load the LOD for (if passing in a material all textures in the material will be loaded)
|
|
51
|
+
* @param level the level of detail to load (0 is the highest resolution) - currently only 0 is supported
|
|
52
|
+
*/
|
|
53
|
+
static assignTextureLOD(context: Context, source: SourceIdentifier | undefined, materialOrTexture: Material | Texture, level: number = 0): Promise<any> {
|
|
54
|
+
if (!materialOrTexture) return Promise.resolve(null);
|
|
55
|
+
|
|
56
|
+
if (materialOrTexture instanceof Material) {
|
|
57
|
+
const material = materialOrTexture;
|
|
58
|
+
const promises: Array<Promise<Texture | null>> = [];
|
|
59
|
+
|
|
60
|
+
if (material instanceof RawShaderMaterial) {
|
|
61
|
+
// iterate uniforms of custom shaders
|
|
62
|
+
for (const slot of Object.keys(material.uniforms)) {
|
|
63
|
+
const val = material.uniforms[slot].value;
|
|
64
|
+
if (val instanceof Texture) {
|
|
65
|
+
const task = this.assignTextureLODForSlot(context, source, val, level, material, slot);
|
|
66
|
+
promises.push(task);
|
|
67
|
+
}
|
|
59
68
|
}
|
|
60
69
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
70
|
+
else {
|
|
71
|
+
for (const slot of Object.keys(material)) {
|
|
72
|
+
const val = material[slot];
|
|
73
|
+
if (val instanceof Texture) {
|
|
74
|
+
const task = this.assignTextureLODForSlot(context, source, val, level, material, slot);
|
|
75
|
+
promises.push(task);
|
|
76
|
+
}
|
|
68
77
|
}
|
|
69
78
|
}
|
|
79
|
+
return PromiseAllWithErrors(promises);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (materialOrTexture instanceof Texture) {
|
|
83
|
+
const texture = materialOrTexture;
|
|
84
|
+
return this.assignTextureLODForSlot(context, source, texture, level, null, null);
|
|
70
85
|
}
|
|
71
86
|
|
|
72
|
-
return
|
|
87
|
+
return Promise.resolve(null);
|
|
73
88
|
}
|
|
74
89
|
|
|
75
|
-
private static assignTextureLODForSlot(context: Context, source: SourceIdentifier | undefined,
|
|
90
|
+
private static assignTextureLODForSlot(context: Context, source: SourceIdentifier | undefined, val: any, level: number, material: Material | null, slot: string | null): Promise<Texture | null> {
|
|
76
91
|
if (val?.isTexture !== true) return Promise.resolve(null);
|
|
77
92
|
|
|
78
|
-
if (debug) console.log("-----------\n", "FIND", material
|
|
93
|
+
if (debug) console.log("-----------\n", "FIND", material?.name, slot, val?.name, val?.userData, val, material);
|
|
79
94
|
|
|
80
|
-
return NEEDLE_progressive.getOrLoadTexture(context, source,
|
|
95
|
+
return NEEDLE_progressive.getOrLoadTexture(context, source, val, level, material, slot).then(t => {
|
|
81
96
|
|
|
82
97
|
if (t?.isTexture === true) {
|
|
83
98
|
|
|
84
|
-
if (debug) console.warn("Assign LOD", material
|
|
99
|
+
if (debug) console.warn("Assign LOD", material?.name, slot, t.name, t["guid"], material, "Prev:", val, "Now:", t, "\n--------------");
|
|
85
100
|
|
|
86
|
-
material[slot] = t;
|
|
87
101
|
t.needsUpdate = true;
|
|
88
|
-
material.needsUpdate = true;
|
|
89
102
|
|
|
90
|
-
if (
|
|
103
|
+
if (material && slot) {
|
|
104
|
+
material[slot] = t;
|
|
105
|
+
material.needsUpdate = true;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
if (debug && material && slot) {
|
|
91
109
|
let debug_map = debug_toggle_maps.get(material);
|
|
92
110
|
if (!debug_map) {
|
|
93
111
|
debug_map = {};
|
|
@@ -146,16 +164,16 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
146
164
|
private static resolved: { [key: string]: Texture } = {};
|
|
147
165
|
private static currentlyLoading: { [key: string]: Promise<Texture | null> } = {};
|
|
148
166
|
|
|
149
|
-
private static async getOrLoadTexture(context: Context, source: SourceIdentifier | undefined,
|
|
167
|
+
private static async getOrLoadTexture(context: Context, source: SourceIdentifier | undefined, current: Texture, _level: number, material: Material | null, slot: string | null): Promise<Texture | null> {
|
|
150
168
|
|
|
151
169
|
const key = current.uuid;
|
|
152
170
|
|
|
153
171
|
let progressiveInfo: ProgressiveTextureSchema | undefined;
|
|
154
172
|
|
|
155
173
|
// See https://github.com/needle-tools/needle-engine-support/issues/133
|
|
156
|
-
if(current.source && current.source[$progressiveTextureExtension])
|
|
174
|
+
if (current.source && current.source[$progressiveTextureExtension])
|
|
157
175
|
progressiveInfo = current.source[$progressiveTextureExtension];
|
|
158
|
-
if(!progressiveInfo) progressiveInfo = NEEDLE_progressive.cache.get(key);
|
|
176
|
+
if (!progressiveInfo) progressiveInfo = NEEDLE_progressive.cache.get(key);
|
|
159
177
|
|
|
160
178
|
if (progressiveInfo) {
|
|
161
179
|
if (debug)
|
|
@@ -171,12 +189,12 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
171
189
|
let res = this.resolved[resolveKey];
|
|
172
190
|
// check if the texture has been disposed or not
|
|
173
191
|
if (res.image?.data || res.source?.data) {
|
|
174
|
-
if (debug) console.log("Texture has already been loaded: " + resolveKey, material
|
|
192
|
+
if (debug) console.log("Texture has already been loaded: " + resolveKey, material?.name, slot, current.name, res);
|
|
175
193
|
res = this.copySettings(current, res);
|
|
176
194
|
return res;
|
|
177
195
|
}
|
|
178
196
|
else if (res) {
|
|
179
|
-
if(debug) console.warn("Texture has been disposed, will load again: " + resolveKey, material
|
|
197
|
+
if (debug) console.warn("Texture has been disposed, will load again: " + resolveKey, material?.name, slot, current.name, res.source.data);
|
|
180
198
|
}
|
|
181
199
|
}
|
|
182
200
|
|
|
@@ -184,7 +202,7 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
184
202
|
try {
|
|
185
203
|
if (this.currentlyLoading[resolveKey] !== undefined) {
|
|
186
204
|
if (debug)
|
|
187
|
-
console.log("Already loading:", material
|
|
205
|
+
console.log("Already loading:", material?.name + "." + slot, resolveKey);
|
|
188
206
|
let res = await this.currentlyLoading[resolveKey];
|
|
189
207
|
if (res)
|
|
190
208
|
res = this.copySettings(current, res);
|
|
@@ -196,19 +214,19 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
196
214
|
addDracoAndKTX2Loaders(loader, context);
|
|
197
215
|
|
|
198
216
|
|
|
199
|
-
if (debug) console.warn("Start loading " + uri, material
|
|
217
|
+
if (debug) console.warn("Start loading " + uri, material?.name, slot, ext.guid);
|
|
200
218
|
if (debug) {
|
|
201
219
|
await delay(Math.random() * 1000);
|
|
202
220
|
}
|
|
203
221
|
|
|
204
222
|
const gltf = await loader.loadAsync(uri);
|
|
205
223
|
const parser = gltf.parser;
|
|
206
|
-
if (debug) console.log("Loading finished " + uri, material
|
|
224
|
+
if (debug) console.log("Loading finished " + uri, material?.name, slot, ext.guid);
|
|
207
225
|
let index = -1;
|
|
208
226
|
let found = false;
|
|
209
|
-
|
|
227
|
+
|
|
210
228
|
if (!gltf.parser.json?.textures) {
|
|
211
|
-
if (debug) console.warn("No textures in glTF " + uri + " - may be a bug", material
|
|
229
|
+
if (debug) console.warn("No textures in glTF " + uri + " - may be a bug", material?.name, slot, ext.guid);
|
|
212
230
|
return resolve(null);
|
|
213
231
|
}
|
|
214
232
|
|
|
@@ -234,7 +252,7 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
234
252
|
}
|
|
235
253
|
this.resolved[resolveKey] = tex as Texture;
|
|
236
254
|
if (debug)
|
|
237
|
-
console.log(material
|
|
255
|
+
console.log(material?.name, slot, "change \"" + current.name + "\" → \"" + tex.name + "\"", uri, index, tex, material, resolveKey);
|
|
238
256
|
resolve(tex);
|
|
239
257
|
});
|
|
240
258
|
this.currentlyLoading[resolveKey] = request;
|
|
@@ -343,7 +361,7 @@ export class NEEDLE_progressive implements GLTFLoaderPlugin {
|
|
|
343
361
|
private static _currentProgressiveLoadingInfo: Map<Context, ProgressiveLoadingInfo[]> = new Map();
|
|
344
362
|
|
|
345
363
|
// called whenever a progressive loading event starts
|
|
346
|
-
private static onProgressiveLoadStart(context: Context, source: SourceIdentifier | undefined, uri: string, material: Material, slot: string): ProgressiveLoadingInfo {
|
|
364
|
+
private static onProgressiveLoadStart(context: Context, source: SourceIdentifier | undefined, uri: string, material: Material | null, slot: string | null): ProgressiveLoadingInfo {
|
|
347
365
|
if (!this._currentProgressiveLoadingInfo.has(context)) {
|
|
348
366
|
this._currentProgressiveLoadingInfo.set(context, []);
|
|
349
367
|
}
|
|
@@ -379,11 +397,11 @@ export class ProgressiveLoadingInfo {
|
|
|
379
397
|
readonly context: Context;
|
|
380
398
|
readonly source: SourceIdentifier | undefined;
|
|
381
399
|
readonly uri: string;
|
|
382
|
-
readonly material?: Material;
|
|
383
|
-
readonly slot?: string;
|
|
400
|
+
readonly material?: Material | null;
|
|
401
|
+
readonly slot?: string | null;
|
|
384
402
|
// TODO: can contain information if the event is a background process / preloading or if the object is currently visible
|
|
385
403
|
|
|
386
|
-
constructor(context: Context, source: SourceIdentifier | undefined, uri: string, material?: Material, slot?: string) {
|
|
404
|
+
constructor(context: Context, source: SourceIdentifier | undefined, uri: string, material?: Material | null, slot?: string | null) {
|
|
387
405
|
this.context = context;
|
|
388
406
|
this.source = source;
|
|
389
407
|
this.uri = uri;
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import * as THREE from "three";
|
|
2
2
|
import { Material, NearestFilter, Texture } from "three";
|
|
3
3
|
|
|
4
|
+
import { Context } from "../engine/engine_context.js";
|
|
4
5
|
import { serializable, serializeable } from "../engine/engine_serialization_decorator.js";
|
|
5
6
|
import { getParam } from "../engine/engine_utils.js";
|
|
7
|
+
import { NEEDLE_progressive } from "../engine/extensions/NEEDLE_progressive.js";
|
|
6
8
|
import { Behaviour } from "./Component.js";
|
|
7
9
|
import { RGBAColor } from "./js-extensions/RGBAColor.js";
|
|
8
10
|
|
|
@@ -70,7 +72,6 @@ class Vec2 {
|
|
|
70
72
|
}
|
|
71
73
|
|
|
72
74
|
export class Sprite {
|
|
73
|
-
|
|
74
75
|
@serializable()
|
|
75
76
|
guid?: string;
|
|
76
77
|
@serializable(Texture)
|
|
@@ -83,6 +84,7 @@ export class Sprite {
|
|
|
83
84
|
vertices!: Array<Vec2>;
|
|
84
85
|
|
|
85
86
|
_geometry?: THREE.BufferGeometry;
|
|
87
|
+
_hasLoadedProgressive: boolean = false;
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
const $spriteTexOwner = Symbol("spriteOwner");
|
|
@@ -101,7 +103,7 @@ export class SpriteData {
|
|
|
101
103
|
@serializable()
|
|
102
104
|
index: number = 0;
|
|
103
105
|
|
|
104
|
-
update() {
|
|
106
|
+
update(context: Context, sourceId: string | undefined, material: Material | undefined) {
|
|
105
107
|
if (!this.spriteSheet) return;
|
|
106
108
|
const index = this.index;
|
|
107
109
|
if (index < 0 || index >= this.spriteSheet.sprites.length)
|
|
@@ -113,6 +115,21 @@ export class SpriteData {
|
|
|
113
115
|
if (tex.minFilter == NearestFilter && tex.magFilter == NearestFilter)
|
|
114
116
|
tex.anisotropy = 1;
|
|
115
117
|
tex.needsUpdate = true;
|
|
118
|
+
|
|
119
|
+
if (!slice._hasLoadedProgressive) {
|
|
120
|
+
slice._hasLoadedProgressive = true;
|
|
121
|
+
const previousTexture = tex;
|
|
122
|
+
NEEDLE_progressive.assignTextureLOD(context, sourceId, tex, 0).then(res => {
|
|
123
|
+
if (res instanceof Texture) {
|
|
124
|
+
slice.texture = res;
|
|
125
|
+
const shouldUpdateInMaterial = material?.["map"] === previousTexture;
|
|
126
|
+
if (shouldUpdateInMaterial) {
|
|
127
|
+
material["map"] = res;
|
|
128
|
+
material.needsUpdate = true;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
});
|
|
132
|
+
}
|
|
116
133
|
}
|
|
117
134
|
}
|
|
118
135
|
|
|
@@ -137,8 +154,11 @@ export class SpriteRenderer extends Behaviour {
|
|
|
137
154
|
if (value === this._spriteSheet) return;
|
|
138
155
|
if (typeof value === "number") {
|
|
139
156
|
const index = Math.floor(value);
|
|
140
|
-
if (
|
|
141
|
-
|
|
157
|
+
// if (value === index)
|
|
158
|
+
this.spriteIndex = index;
|
|
159
|
+
// else if (debug) {
|
|
160
|
+
// console.log("Spritesheet framedrop", index, value);
|
|
161
|
+
// }
|
|
142
162
|
return;
|
|
143
163
|
}
|
|
144
164
|
else {
|
|
@@ -172,7 +192,7 @@ export class SpriteRenderer extends Behaviour {
|
|
|
172
192
|
|
|
173
193
|
awake(): void {
|
|
174
194
|
this._currentSprite = undefined;
|
|
175
|
-
if(debug) {
|
|
195
|
+
if (debug) {
|
|
176
196
|
console.log("Awake", this.name, this, this.sprite);
|
|
177
197
|
}
|
|
178
198
|
}
|
|
@@ -218,6 +238,7 @@ export class SpriteRenderer extends Behaviour {
|
|
|
218
238
|
}
|
|
219
239
|
this.sharedMaterial = mat;
|
|
220
240
|
this._currentSprite = new THREE.Mesh(SpriteUtils.getOrCreateGeometry(sprite), mat);
|
|
241
|
+
NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, mat, 0);
|
|
221
242
|
}
|
|
222
243
|
else {
|
|
223
244
|
this._currentSprite.geometry = SpriteUtils.getOrCreateGeometry(sprite);
|
|
@@ -231,7 +252,7 @@ export class SpriteRenderer extends Behaviour {
|
|
|
231
252
|
this.gameObject.add(this._currentSprite);
|
|
232
253
|
}
|
|
233
254
|
|
|
234
|
-
if(this._currentSprite){
|
|
255
|
+
if (this._currentSprite) {
|
|
235
256
|
this._currentSprite.layers.set(this.layer)
|
|
236
257
|
}
|
|
237
258
|
|
|
@@ -240,6 +261,6 @@ export class SpriteRenderer extends Behaviour {
|
|
|
240
261
|
this.sharedMaterial.transparent = this.transparent;
|
|
241
262
|
}
|
|
242
263
|
this._currentSprite.castShadow = this.castShadows;
|
|
243
|
-
this._spriteSheet?.update();
|
|
264
|
+
this._spriteSheet?.update(this.context, this.sourceId, this.sharedMaterial);
|
|
244
265
|
}
|
|
245
266
|
}
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { Color, LinearSRGBColorSpace, Object3D, SRGBColorSpace, Texture } from 'three';
|
|
2
2
|
import * as ThreeMeshUI from 'three-mesh-ui'
|
|
3
|
+
import type { Options } from 'three-mesh-ui/build/types/core/elements/MeshUIBaseElement.js';
|
|
3
4
|
import SimpleStateBehavior from "three-mesh-ui/examples/behaviors/states/SimpleStateBehavior.js"
|
|
4
5
|
|
|
5
6
|
import { serializable } from '../../engine/engine_serialization_decorator.js';
|
|
7
|
+
import { NEEDLE_progressive } from '../../engine/extensions/NEEDLE_progressive.js';
|
|
6
8
|
import { GameObject } from '../Component.js';
|
|
7
9
|
import { RGBAColor } from "../js-extensions/RGBAColor.js"
|
|
8
10
|
import { BaseUIComponent } from "./BaseUIComponent.js";
|
|
@@ -117,7 +119,7 @@ export class Graphic extends BaseUIComponent implements IGraphic, IRectTransform
|
|
|
117
119
|
}
|
|
118
120
|
}
|
|
119
121
|
|
|
120
|
-
setOptions(opts:
|
|
122
|
+
setOptions(opts: Options) {
|
|
121
123
|
this.makePanel();
|
|
122
124
|
if (this.uiObject) {
|
|
123
125
|
//@ts-ignore
|
|
@@ -218,9 +220,14 @@ export class Graphic extends BaseUIComponent implements IGraphic, IRectTransform
|
|
|
218
220
|
}
|
|
219
221
|
// }
|
|
220
222
|
this.setOptions({ backgroundImage: tex, borderRadius: 0, backgroundOpacity: this.color.alpha, backgroundSize: "stretch" });
|
|
223
|
+
NEEDLE_progressive.assignTextureLOD(this.context, this.sourceId, tex, 0).then(res => {
|
|
224
|
+
if (res instanceof Texture) {
|
|
225
|
+
this.setOptions({ backgroundImage: res });
|
|
226
|
+
}
|
|
227
|
+
});
|
|
221
228
|
}
|
|
222
229
|
else {
|
|
223
|
-
this.setOptions({ backgroundImage:
|
|
230
|
+
this.setOptions({ backgroundImage: undefined, borderRadius: 0, backgroundOpacity: this.color.alpha });
|
|
224
231
|
}
|
|
225
232
|
this.markDirty();
|
|
226
233
|
}
|
|
@@ -40,7 +40,8 @@ export class Image extends MaskableGraphic {
|
|
|
40
40
|
private pixelsPerUnitMultiplier: number = 1;
|
|
41
41
|
|
|
42
42
|
private isBuiltinSprite() {
|
|
43
|
-
|
|
43
|
+
const sprite = this.sprite;
|
|
44
|
+
switch (sprite?.texture?.name) {
|
|
44
45
|
case "InputFieldBackground":
|
|
45
46
|
case "UISprite":
|
|
46
47
|
case "Background":
|
|
@@ -49,7 +50,7 @@ export class Image extends MaskableGraphic {
|
|
|
49
50
|
}
|
|
50
51
|
// this is a hack/workaround for production builds where the name of the sprite is missing
|
|
51
52
|
// need to remove this!!!!
|
|
52
|
-
if (!
|
|
53
|
+
if (!sprite?.texture?.name?.length && sprite?.texture?.image?.width === 32 && sprite?.texture?.image?.height === 32)
|
|
53
54
|
return true;
|
|
54
55
|
return false;
|
|
55
56
|
}
|
|
@@ -276,7 +276,7 @@ export class PlayerState extends Behaviour {
|
|
|
276
276
|
}
|
|
277
277
|
else if (debug) console.warn("PlayerState.start → owner is still undefined but dontDestroy is set to true", this.name);
|
|
278
278
|
}
|
|
279
|
-
else console.log("PlayerState.start → owner is assigned", this.owner);
|
|
279
|
+
else if(debug) console.log("PlayerState.start → owner is assigned", this.owner);
|
|
280
280
|
}, 2000);
|
|
281
281
|
}
|
|
282
282
|
}
|