babylon.quarks 0.18.0 → 0.19.0
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/README.md +16 -16
- package/dist/babylon.quarks.cjs +1 -1
- package/dist/babylon.quarks.cjs.map +1 -1
- package/dist/babylon.quarks.esm.js +1 -1
- package/dist/babylon.quarks.esm.js.map +1 -1
- package/dist/babylon.quarks.umd.min.js +1 -1
- package/dist/babylon.quarks.umd.min.js.map +1 -1
- package/dist/types/index.d.ts +1835 -1171
- package/package.json +67 -67
- package/src/BatchedRenderer.ts +213 -14
- package/src/MeshSurfaceEmitter.ts +25 -20
- package/src/ParticleEmitter.ts +34 -10
- package/src/ParticleSystem.ts +467 -203
- package/src/QuarksLoader.ts +68 -15
- package/src/QuarksPrefab.ts +8 -11
- package/src/QuarksUtil.ts +1 -3
- package/src/SpriteBatch.ts +447 -96
- package/src/TrailBatch.ts +361 -164
- package/src/VFXBatch.ts +20 -4
- package/src/envAtlas.ts +136 -0
- package/src/index.ts +34 -29
- package/src/materials/ParticleMaterials.ts +1 -1
- package/src/shaders/index.ts +4 -4
- package/src/shaders/local_particle_physics_vert.wgsl.ts +81 -0
- package/src/shaders/particle_frag.wgsl.ts +64 -0
- package/src/shaders/particle_physics_frag.glsl.ts +56 -1
- package/src/shaders/particle_physics_frag.wgsl.ts +125 -0
- package/src/shaders/particle_vert.wgsl.ts +87 -0
- package/src/shaders/shaderLanguageSupport.ts +54 -0
- package/src/shaders/stretched_bb_particle_vert.wgsl.ts +88 -0
- package/src/shaders/trail_frag.wgsl.ts +23 -0
- package/src/shaders/trail_vert.wgsl.ts +63 -0
package/src/QuarksLoader.ts
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {TransformNode} from '@babylonjs/core/Meshes/transformNode';
|
|
3
|
-
import {Mesh} from '@babylonjs/core/Meshes/mesh';
|
|
4
|
-
import {VertexData} from '@babylonjs/core/Meshes/mesh.vertexData';
|
|
1
|
+
import {Constants} from '@babylonjs/core/Engines/constants';
|
|
5
2
|
import {Texture} from '@babylonjs/core/Materials/Textures/texture';
|
|
6
3
|
import {StandardMaterial} from '@babylonjs/core/Materials/standardMaterial';
|
|
7
|
-
import {Constants} from '@babylonjs/core/Engines/constants';
|
|
8
4
|
import {Matrix, Quaternion, Vector3} from '@babylonjs/core/Maths/math.vector';
|
|
9
|
-
import {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
} from '
|
|
13
|
-
import {
|
|
5
|
+
import {Mesh} from '@babylonjs/core/Meshes/mesh';
|
|
6
|
+
import {VertexData} from '@babylonjs/core/Meshes/mesh.vertexData';
|
|
7
|
+
import {TransformNode} from '@babylonjs/core/Meshes/transformNode';
|
|
8
|
+
import {Scene} from '@babylonjs/core/scene';
|
|
9
|
+
import {Behavior, EmitSubParticleSystem} from 'quarks.core';
|
|
14
10
|
import {ParticleEmitter} from './ParticleEmitter';
|
|
11
|
+
import {ParticleSystem} from './ParticleSystem';
|
|
15
12
|
import {QuarksPrefab} from './QuarksPrefab';
|
|
16
13
|
import {ensureTriangleIndices} from './geometryUtil';
|
|
17
14
|
|
|
@@ -194,7 +191,8 @@ export class QuarksLoader {
|
|
|
194
191
|
if (data.attributes.position?.isInterleavedBufferAttribute) {
|
|
195
192
|
const attr = data.attributes.position;
|
|
196
193
|
const buf = buffers[attr.data];
|
|
197
|
-
if (buf)
|
|
194
|
+
if (buf)
|
|
195
|
+
positions = this.extractInterleavedAttribute(buf.data, buf.stride, attr.offset, attr.itemSize);
|
|
198
196
|
}
|
|
199
197
|
if (data.attributes.uv?.isInterleavedBufferAttribute) {
|
|
200
198
|
const attr = data.attributes.uv;
|
|
@@ -204,7 +202,8 @@ export class QuarksLoader {
|
|
|
204
202
|
if (data.attributes.normal?.isInterleavedBufferAttribute) {
|
|
205
203
|
const attr = data.attributes.normal;
|
|
206
204
|
const buf = buffers[attr.data];
|
|
207
|
-
if (buf)
|
|
205
|
+
if (buf)
|
|
206
|
+
normals = this.extractInterleavedAttribute(buf.data, buf.stride, attr.offset, attr.itemSize);
|
|
208
207
|
}
|
|
209
208
|
}
|
|
210
209
|
} else if (data.attributes) {
|
|
@@ -255,8 +254,43 @@ export class QuarksLoader {
|
|
|
255
254
|
private parseImages(images: any[], baseUrl: string, _meta: LoadedMeta): void {
|
|
256
255
|
(this as any)._images = {};
|
|
257
256
|
for (const img of images) {
|
|
258
|
-
(
|
|
257
|
+
if (img.url) {
|
|
258
|
+
QuarksLoader.warnIfNotAnImageUrl(img.url);
|
|
259
|
+
}
|
|
260
|
+
(this as any)._images[img.uuid] = img.url ? this.resolveImageUrl(baseUrl, img.url) : null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* Flags an image entry that is plainly not an image, which otherwise only
|
|
266
|
+
* shows up as a texture that silently fails to load.
|
|
267
|
+
*
|
|
268
|
+
* The case worth naming: an exporter that could not embed a texture falls
|
|
269
|
+
* back to writing the source asset's path, and a Unity built-in texture
|
|
270
|
+
* reports a virtual path such as `Resources/unity_builtin_extra` that no
|
|
271
|
+
* file backs.
|
|
272
|
+
*/
|
|
273
|
+
private static warnIfNotAnImageUrl(url: string): void {
|
|
274
|
+
if (/^(data|blob):/i.test(url) || /\.(png|jpe?g|webp|gif|bmp|ktx2?|dds|env|basis)(\?|#|$)/i.test(url)) {
|
|
275
|
+
return;
|
|
259
276
|
}
|
|
277
|
+
console.warn(
|
|
278
|
+
`[QuarksLoader] Image "${url}" does not look like an image; its texture will fail to load. ` +
|
|
279
|
+
'This usually means the effect was exported without embedding that texture.'
|
|
280
|
+
);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
/**
|
|
284
|
+
* `img.url` is already absolute for data/blob URIs and full http(s) URLs — common for
|
|
285
|
+
* "portable" exports that embed textures as base64 (see ensurePortableTextureUrl in
|
|
286
|
+
* babylon.quarks-editor). Prepending baseUrl to those turns e.g.
|
|
287
|
+
* "data:image/png;base64,AAAA" into an invalid path like "/some/dir/data:image/png;base64,AAAA".
|
|
288
|
+
*/
|
|
289
|
+
private resolveImageUrl(baseUrl: string, url: string): string {
|
|
290
|
+
if (/^(data|blob):/i.test(url) || /^[a-z][a-z0-9+.-]*:\/\//i.test(url) || url.startsWith('/')) {
|
|
291
|
+
return url;
|
|
292
|
+
}
|
|
293
|
+
return baseUrl + url;
|
|
260
294
|
}
|
|
261
295
|
|
|
262
296
|
private parseTextures(textures: any[], meta: LoadedMeta): void {
|
|
@@ -264,7 +298,13 @@ export class QuarksLoader {
|
|
|
264
298
|
for (const texDef of textures) {
|
|
265
299
|
const imageUrl = images[texDef.image];
|
|
266
300
|
if (imageUrl) {
|
|
267
|
-
const
|
|
301
|
+
const invertY = texDef.invertY !== undefined ? !!texDef.invertY : true;
|
|
302
|
+
const noMipmap = !!texDef.noMipmap;
|
|
303
|
+
const texture = new Texture(imageUrl, this.scene, {
|
|
304
|
+
noMipmap,
|
|
305
|
+
invertY,
|
|
306
|
+
samplingMode: typeof texDef.samplingMode === 'number' ? texDef.samplingMode : undefined,
|
|
307
|
+
});
|
|
268
308
|
if (Array.isArray(texDef.wrap)) {
|
|
269
309
|
texture.wrapU = this.mapWrapMode(texDef.wrap[0]);
|
|
270
310
|
texture.wrapV = this.mapWrapMode(texDef.wrap[1] ?? texDef.wrap[0]);
|
|
@@ -319,6 +359,14 @@ export class QuarksLoader {
|
|
|
319
359
|
matInfo.texture = meta.textures[textureRef] || null;
|
|
320
360
|
}
|
|
321
361
|
|
|
362
|
+
const reflectionAtlasRef = matDef.reflectionAtlas;
|
|
363
|
+
if (reflectionAtlasRef) {
|
|
364
|
+
matInfo.reflectionAtlas = meta.textures[reflectionAtlasRef] || null;
|
|
365
|
+
}
|
|
366
|
+
if (typeof matDef.reflectionLevel === 'number') {
|
|
367
|
+
matInfo.reflectionLevel = matDef.reflectionLevel;
|
|
368
|
+
}
|
|
369
|
+
|
|
322
370
|
// QuarksMaterial (what ParticleSystem.ensureMaterialMeta emits) writes `alphaMode`
|
|
323
371
|
// directly as a Babylon alpha-mode constant; three.js materials (MeshBasicMaterial
|
|
324
372
|
// etc.) instead use `blending` with three.js's own 1..4 numbering, which does NOT
|
|
@@ -451,7 +499,12 @@ export class QuarksLoader {
|
|
|
451
499
|
if (data.position) node.position.set(data.position[0], data.position[1], data.position[2]);
|
|
452
500
|
if (data.scale) node.scaling.set(data.scale[0], data.scale[1], data.scale[2]);
|
|
453
501
|
if (data.quaternion) {
|
|
454
|
-
node.rotationQuaternion = new Quaternion(
|
|
502
|
+
node.rotationQuaternion = new Quaternion(
|
|
503
|
+
data.quaternion[0],
|
|
504
|
+
data.quaternion[1],
|
|
505
|
+
data.quaternion[2],
|
|
506
|
+
data.quaternion[3]
|
|
507
|
+
);
|
|
455
508
|
} else if (data.rotation) {
|
|
456
509
|
node.rotation.set(data.rotation[0], data.rotation[1], data.rotation[2]);
|
|
457
510
|
}
|
package/src/QuarksPrefab.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import {IAnimationData, IPrefab} from 'quarks.core';
|
|
2
1
|
import {TransformNode} from '@babylonjs/core/Meshes/transformNode';
|
|
3
2
|
import {Scene} from '@babylonjs/core/scene';
|
|
4
|
-
import {
|
|
3
|
+
import {IAnimationData, IPrefab} from 'quarks.core';
|
|
5
4
|
import {BatchedRenderer} from './BatchedRenderer';
|
|
5
|
+
import {ParticleEmitter} from './ParticleEmitter';
|
|
6
6
|
|
|
7
7
|
export interface QuarksTimelineClip {
|
|
8
8
|
uuid?: string;
|
|
@@ -50,12 +50,7 @@ export class QuarksPrefab extends TransformNode implements IPrefab {
|
|
|
50
50
|
this._batchedRenderer = renderer;
|
|
51
51
|
}
|
|
52
52
|
|
|
53
|
-
addParticleSystemAnimation(
|
|
54
|
-
emitter: ParticleEmitter,
|
|
55
|
-
startTime = 0,
|
|
56
|
-
duration = 0,
|
|
57
|
-
loop = false
|
|
58
|
-
): AnimationData {
|
|
53
|
+
addParticleSystemAnimation(emitter: ParticleEmitter, startTime = 0, duration = 0, loop = false): AnimationData {
|
|
59
54
|
const animationDuration = duration > 0 ? duration : emitter.system.duration;
|
|
60
55
|
const data: AnimationData = {
|
|
61
56
|
startTime,
|
|
@@ -78,7 +73,7 @@ export class QuarksPrefab extends TransformNode implements IPrefab {
|
|
|
78
73
|
loop = false,
|
|
79
74
|
clipUUID?: string
|
|
80
75
|
): AnimationData {
|
|
81
|
-
const animationDuration = duration > 0 ? duration : clip?.duration ?? 0;
|
|
76
|
+
const animationDuration = duration > 0 ? duration : (clip?.duration ?? 0);
|
|
82
77
|
const data: AnimationData = {
|
|
83
78
|
startTime,
|
|
84
79
|
duration: animationDuration,
|
|
@@ -260,7 +255,7 @@ export class QuarksPrefab extends TransformNode implements IPrefab {
|
|
|
260
255
|
duration: animation.duration,
|
|
261
256
|
type: animation.type,
|
|
262
257
|
targetUUID: (animation.target as any)._quarksUUID ?? animation.target.uniqueId.toString(),
|
|
263
|
-
clipUUID: animation.type === 'three' ? animation.clipUUID ?? animation.clip?.uuid : undefined,
|
|
258
|
+
clipUUID: animation.type === 'three' ? (animation.clipUUID ?? animation.clip?.uuid) : undefined,
|
|
264
259
|
loop: animation.loop,
|
|
265
260
|
})),
|
|
266
261
|
};
|
|
@@ -269,7 +264,9 @@ export class QuarksPrefab extends TransformNode implements IPrefab {
|
|
|
269
264
|
static fromJSON(json: any, scene?: Scene): QuarksPrefab {
|
|
270
265
|
const prefab = new QuarksPrefab(json.name || 'QuarksPrefab', scene);
|
|
271
266
|
if (Array.isArray(json.animationData)) {
|
|
272
|
-
prefab._tempAnimationJSON = json.animationData.filter(
|
|
267
|
+
prefab._tempAnimationJSON = json.animationData.filter(
|
|
268
|
+
(item: any) => item?.type === 'ps' || item?.type === 'three'
|
|
269
|
+
);
|
|
273
270
|
}
|
|
274
271
|
return prefab;
|
|
275
272
|
}
|
package/src/QuarksUtil.ts
CHANGED
|
@@ -1,9 +1,7 @@
|
|
|
1
1
|
import {Node} from '@babylonjs/core/node';
|
|
2
|
-
import {
|
|
2
|
+
import {BatchedRenderer} from './BatchedRenderer';
|
|
3
3
|
import {ParticleEmitter} from './ParticleEmitter';
|
|
4
4
|
import {ParticleSystem} from './ParticleSystem';
|
|
5
|
-
import {BatchedRenderer} from './BatchedRenderer';
|
|
6
|
-
import {IParticleSystem} from 'quarks.core';
|
|
7
5
|
|
|
8
6
|
export class QuarksUtil {
|
|
9
7
|
static runOnAllParticleEmitters(root: Node, callback: (emitter: ParticleEmitter) => void): void {
|