@galacean/effects-helper 0.0.1-alpha.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 +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.mjs +508 -0
- package/dist/index.mjs.map +1 -0
- package/dist/serialize/geometry.d.ts +24 -0
- package/dist/serialize/index.d.ts +3 -0
- package/dist/serialize/texture.d.ts +12 -0
- package/dist/serialize/utils.d.ts +21 -0
- package/package.json +40 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# Galacean Effects Helper
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './serialize';
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,508 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* Name: @galacean/effects-helper
|
|
3
|
+
* Description: Galacean Effects runtime helper for the web
|
|
4
|
+
* Author: Ant Group CO., Ltd.
|
|
5
|
+
* Contributors: 燃然,意绮
|
|
6
|
+
* Version: v0.0.1-alpha.0
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { spec } from '@galacean/effects';
|
|
10
|
+
|
|
11
|
+
/******************************************************************************
|
|
12
|
+
Copyright (c) Microsoft Corporation.
|
|
13
|
+
|
|
14
|
+
Permission to use, copy, modify, and/or distribute this software for any
|
|
15
|
+
purpose with or without fee is hereby granted.
|
|
16
|
+
|
|
17
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
18
|
+
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
19
|
+
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
20
|
+
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
21
|
+
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
22
|
+
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
23
|
+
PERFORMANCE OF THIS SOFTWARE.
|
|
24
|
+
***************************************************************************** */
|
|
25
|
+
|
|
26
|
+
var __assign = function() {
|
|
27
|
+
__assign = Object.assign || function __assign(t) {
|
|
28
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
29
|
+
s = arguments[i];
|
|
30
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
31
|
+
}
|
|
32
|
+
return t;
|
|
33
|
+
};
|
|
34
|
+
return __assign.apply(this, arguments);
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
function __awaiter(thisArg, _arguments, P, generator) {
|
|
38
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
39
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
40
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
41
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
42
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
43
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
44
|
+
});
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
function __generator(thisArg, body) {
|
|
48
|
+
var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
|
|
49
|
+
return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
|
|
50
|
+
function verb(n) { return function (v) { return step([n, v]); }; }
|
|
51
|
+
function step(op) {
|
|
52
|
+
if (f) throw new TypeError("Generator is already executing.");
|
|
53
|
+
while (g && (g = 0, op[0] && (_ = 0)), _) try {
|
|
54
|
+
if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
|
|
55
|
+
if (y = 0, t) op = [op[0] & 2, t.value];
|
|
56
|
+
switch (op[0]) {
|
|
57
|
+
case 0: case 1: t = op; break;
|
|
58
|
+
case 4: _.label++; return { value: op[1], done: false };
|
|
59
|
+
case 5: _.label++; y = op[1]; op = [0]; continue;
|
|
60
|
+
case 7: op = _.ops.pop(); _.trys.pop(); continue;
|
|
61
|
+
default:
|
|
62
|
+
if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
|
|
63
|
+
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
|
|
64
|
+
if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
|
|
65
|
+
if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
|
|
66
|
+
if (t[2]) _.ops.pop();
|
|
67
|
+
_.trys.pop(); continue;
|
|
68
|
+
}
|
|
69
|
+
op = body.call(thisArg, _);
|
|
70
|
+
} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
|
|
71
|
+
if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function __read(o, n) {
|
|
76
|
+
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
77
|
+
if (!m) return o;
|
|
78
|
+
var i = m.call(o), r, ar = [], e;
|
|
79
|
+
try {
|
|
80
|
+
while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
81
|
+
}
|
|
82
|
+
catch (error) { e = { error: error }; }
|
|
83
|
+
finally {
|
|
84
|
+
try {
|
|
85
|
+
if (r && !r.done && (m = i["return"])) m.call(i);
|
|
86
|
+
}
|
|
87
|
+
finally { if (e) throw e.error; }
|
|
88
|
+
}
|
|
89
|
+
return ar;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
function __spreadArray(to, from, pack) {
|
|
93
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
94
|
+
if (ar || !(i in from)) {
|
|
95
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
96
|
+
ar[i] = from[i];
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
typeof SuppressedError === "function" ? SuppressedError : function (error, suppressed, message) {
|
|
103
|
+
var e = new Error(message);
|
|
104
|
+
return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
function loadMipmaps(textureOptions, dataIndex) {
|
|
108
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
109
|
+
var mipmaps, cube, textureCubeMipmaps, jobs, newMipmaps, images, result, cubeMipmaps, i, mipmap, mipmapPointers, j, pointer;
|
|
110
|
+
return __generator(this, function (_a) {
|
|
111
|
+
switch (_a.label) {
|
|
112
|
+
case 0:
|
|
113
|
+
mipmaps = textureOptions.mipmaps;
|
|
114
|
+
cube = textureOptions.cube;
|
|
115
|
+
textureCubeMipmaps = mipmaps || [cube];
|
|
116
|
+
jobs = textureCubeMipmaps.map(function (mipmap) { return Promise.all(mipmap.map(function (imageLike) {
|
|
117
|
+
if (imageLike instanceof HTMLImageElement) {
|
|
118
|
+
return getImageFileContent(imageLike);
|
|
119
|
+
}
|
|
120
|
+
return Promise.reject('invalid image format');
|
|
121
|
+
})); });
|
|
122
|
+
return [4 /*yield*/, Promise.all(jobs)];
|
|
123
|
+
case 1:
|
|
124
|
+
newMipmaps = _a.sent();
|
|
125
|
+
images = [];
|
|
126
|
+
newMipmaps.forEach(function (mipmap) { return images.push.apply(images, __spreadArray([], __read(mipmap), false)); });
|
|
127
|
+
result = concatArrayBuffers(images);
|
|
128
|
+
cubeMipmaps = [];
|
|
129
|
+
for (i = 0; i < textureCubeMipmaps.length; i++) {
|
|
130
|
+
mipmap = textureCubeMipmaps[i];
|
|
131
|
+
mipmapPointers = [];
|
|
132
|
+
for (j = 0; j < mipmap.length; j++) {
|
|
133
|
+
pointer = mipmapPointers[j] = result.pointers[i * 6 + j];
|
|
134
|
+
pointer[1][0] = dataIndex;
|
|
135
|
+
}
|
|
136
|
+
cubeMipmaps.push(mipmapPointers);
|
|
137
|
+
}
|
|
138
|
+
return [2 /*return*/, {
|
|
139
|
+
data: result.data,
|
|
140
|
+
mipmaps: cubeMipmaps,
|
|
141
|
+
}];
|
|
142
|
+
}
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
function getImageFileContent(image) {
|
|
147
|
+
var _a;
|
|
148
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
149
|
+
var canvas;
|
|
150
|
+
return __generator(this, function (_b) {
|
|
151
|
+
canvas = document.createElement('canvas');
|
|
152
|
+
canvas.width = image.width;
|
|
153
|
+
canvas.height = image.height;
|
|
154
|
+
(_a = canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.drawImage(image, 0, 0);
|
|
155
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
156
|
+
canvas.toBlob(function (blob) {
|
|
157
|
+
if (blob) {
|
|
158
|
+
resolve(blob.arrayBuffer());
|
|
159
|
+
}
|
|
160
|
+
else {
|
|
161
|
+
reject(Error('no canvas blob'));
|
|
162
|
+
}
|
|
163
|
+
}, 'image/png', 1);
|
|
164
|
+
})];
|
|
165
|
+
});
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
function concatBuffers(buffers, bufferInfo, length) {
|
|
169
|
+
var ret = new Uint8Array(length);
|
|
170
|
+
buffers.forEach(function (buffer) {
|
|
171
|
+
var _a = __read(bufferInfo.get(buffer), 3), offset = _a[1], byteLength = _a[2];
|
|
172
|
+
var source = buffer instanceof ArrayBuffer ? new Uint8Array(buffer, 0, byteLength) : new Uint8Array(buffer.buffer, buffer.byteOffset, byteLength);
|
|
173
|
+
ret.set(source, offset);
|
|
174
|
+
});
|
|
175
|
+
return ret.buffer;
|
|
176
|
+
}
|
|
177
|
+
function getBinaryType(arr) {
|
|
178
|
+
if (arr instanceof Uint8Array) {
|
|
179
|
+
return 'u8';
|
|
180
|
+
}
|
|
181
|
+
else if (arr instanceof Int8Array) {
|
|
182
|
+
return 'i8';
|
|
183
|
+
}
|
|
184
|
+
else if (arr instanceof Uint16Array) {
|
|
185
|
+
return 'u16';
|
|
186
|
+
}
|
|
187
|
+
else if (arr instanceof Int16Array) {
|
|
188
|
+
return 'i16';
|
|
189
|
+
}
|
|
190
|
+
else if (arr instanceof Uint32Array) {
|
|
191
|
+
return 'u32';
|
|
192
|
+
}
|
|
193
|
+
else if (arr instanceof Int32Array) {
|
|
194
|
+
return 'i32';
|
|
195
|
+
}
|
|
196
|
+
else if (arr instanceof Float32Array) {
|
|
197
|
+
return 'f32';
|
|
198
|
+
}
|
|
199
|
+
return '';
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* 工具方法,按照 4bytes 对齐方式合并 buffers,如果提供了 pointer,会把原来的 pointer 转化为新的映射
|
|
203
|
+
* 返回的 pointers 数组和传入的 pointers 数组长度一致,并且一一对应
|
|
204
|
+
* @internal
|
|
205
|
+
* @param buffers
|
|
206
|
+
* @param pointers - 如果不提供 pointers,将返回整段 buffers 的 pointer 重映射
|
|
207
|
+
* @param overwrite - 如果为 true,将直接改写参数中的 pointer 值,否则生成新的 pointer 传出
|
|
208
|
+
*/
|
|
209
|
+
function concatArrayBuffers(buffers, pointers, overwrite) {
|
|
210
|
+
var bufferInfo = new Map();
|
|
211
|
+
var offset = 0;
|
|
212
|
+
for (var i = 0; i < buffers.length; i++) {
|
|
213
|
+
var buffer = buffers[i];
|
|
214
|
+
var content = [0, offset, buffer.byteLength];
|
|
215
|
+
var type = getBinaryType(buffer);
|
|
216
|
+
if (type) {
|
|
217
|
+
content[3] = type;
|
|
218
|
+
}
|
|
219
|
+
bufferInfo.set(buffer, content);
|
|
220
|
+
offset += buffer.byteLength;
|
|
221
|
+
// padding 4bytes for f32
|
|
222
|
+
offset = Math.ceil(offset / 4) * 4;
|
|
223
|
+
}
|
|
224
|
+
if (!pointers) {
|
|
225
|
+
pointers = buffers.map(function (buffer, i) {
|
|
226
|
+
return [spec.ValueType.BINARY, [i, 0, buffer.byteLength]];
|
|
227
|
+
});
|
|
228
|
+
}
|
|
229
|
+
var retBuffer = concatBuffers(buffers, bufferInfo, offset);
|
|
230
|
+
var mappedPointers = pointers.map(function (pointer) {
|
|
231
|
+
var _a;
|
|
232
|
+
var content = pointer[1];
|
|
233
|
+
var buffer = buffers[content[0]];
|
|
234
|
+
if (!buffer) {
|
|
235
|
+
throw new Error("buffer index ".concat(content[0], " not found"));
|
|
236
|
+
}
|
|
237
|
+
var originStart = content[1] || 0;
|
|
238
|
+
var byteLength = content[2] || (buffer.byteLength - originStart);
|
|
239
|
+
var info = (_a = bufferInfo.get(buffer)) !== null && _a !== void 0 ? _a : [];
|
|
240
|
+
// @ts-expect-error
|
|
241
|
+
var binaryPointerContent = [0, originStart + info[1], byteLength];
|
|
242
|
+
if (info[3]) {
|
|
243
|
+
binaryPointerContent[3] = info[3];
|
|
244
|
+
}
|
|
245
|
+
if (overwrite) {
|
|
246
|
+
pointer[1] = binaryPointerContent;
|
|
247
|
+
return pointer;
|
|
248
|
+
}
|
|
249
|
+
return [spec.ValueType.BINARY, binaryPointerContent];
|
|
250
|
+
});
|
|
251
|
+
return {
|
|
252
|
+
data: retBuffer,
|
|
253
|
+
pointers: mappedPointers,
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
var TextureSourceTypeImage = 2;
|
|
258
|
+
/**
|
|
259
|
+
* texture 序列化
|
|
260
|
+
* @param textureOptions
|
|
261
|
+
*/
|
|
262
|
+
function serializeTextures(textureOptions) {
|
|
263
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
264
|
+
var imageBufferSet, filesPending, cubesPending, imageMap, cubeMap, _loop_1, i, files, images, resultTextures, bins, tex, i, texture, info, buffer;
|
|
265
|
+
var _this = this;
|
|
266
|
+
return __generator(this, function (_a) {
|
|
267
|
+
switch (_a.label) {
|
|
268
|
+
case 0:
|
|
269
|
+
imageBufferSet = new Map();
|
|
270
|
+
filesPending = [];
|
|
271
|
+
cubesPending = [];
|
|
272
|
+
imageMap = new Map();
|
|
273
|
+
cubeMap = new Map();
|
|
274
|
+
_loop_1 = function (i) {
|
|
275
|
+
var texture = textureOptions[i];
|
|
276
|
+
var sourceFrom = texture.sourceFrom;
|
|
277
|
+
var target = texture.target;
|
|
278
|
+
var image = texture.image;
|
|
279
|
+
if (sourceFrom &&
|
|
280
|
+
sourceFrom.type === TextureSourceTypeImage &&
|
|
281
|
+
sourceFrom.target !== WebGLRenderingContext.TEXTURE_CUBE_MAP) {
|
|
282
|
+
var url_1 = sourceFrom.url;
|
|
283
|
+
var job = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
284
|
+
var result, buffer;
|
|
285
|
+
return __generator(this, function (_a) {
|
|
286
|
+
switch (_a.label) {
|
|
287
|
+
case 0: return [4 /*yield*/, fetch(url_1)];
|
|
288
|
+
case 1:
|
|
289
|
+
result = _a.sent();
|
|
290
|
+
return [4 /*yield*/, result.arrayBuffer()];
|
|
291
|
+
case 2:
|
|
292
|
+
buffer = _a.sent();
|
|
293
|
+
imageMap.set(texture, buffer);
|
|
294
|
+
return [2 /*return*/, buffer];
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}); };
|
|
298
|
+
filesPending.push(job());
|
|
299
|
+
return "continue";
|
|
300
|
+
}
|
|
301
|
+
if (target === WebGLRenderingContext.TEXTURE_CUBE_MAP) {
|
|
302
|
+
var job = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
303
|
+
var result;
|
|
304
|
+
return __generator(this, function (_a) {
|
|
305
|
+
switch (_a.label) {
|
|
306
|
+
case 0: return [4 /*yield*/, loadMipmaps(texture, cubesPending.length)];
|
|
307
|
+
case 1:
|
|
308
|
+
result = _a.sent();
|
|
309
|
+
cubeMap.set(texture, result);
|
|
310
|
+
return [2 /*return*/];
|
|
311
|
+
}
|
|
312
|
+
});
|
|
313
|
+
}); };
|
|
314
|
+
cubesPending.push(job());
|
|
315
|
+
return "continue";
|
|
316
|
+
}
|
|
317
|
+
if (image instanceof HTMLImageElement) {
|
|
318
|
+
var url_2 = image.src;
|
|
319
|
+
if (!imageBufferSet.has(url_2)) {
|
|
320
|
+
imageBufferSet.set(url_2, getImageFileContent(image));
|
|
321
|
+
}
|
|
322
|
+
var job = function () { return __awaiter(_this, void 0, void 0, function () {
|
|
323
|
+
var buffer;
|
|
324
|
+
return __generator(this, function (_a) {
|
|
325
|
+
switch (_a.label) {
|
|
326
|
+
case 0: return [4 /*yield*/, imageBufferSet.get(url_2)];
|
|
327
|
+
case 1:
|
|
328
|
+
buffer = _a.sent();
|
|
329
|
+
imageMap.set(texture, buffer);
|
|
330
|
+
return [2 /*return*/, buffer];
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
}); };
|
|
334
|
+
filesPending.push(job());
|
|
335
|
+
}
|
|
336
|
+
else {
|
|
337
|
+
throw new Error("tex ".concat(i, " image should be HTMLImage or HTMLCanvas"));
|
|
338
|
+
}
|
|
339
|
+
};
|
|
340
|
+
for (i = 0; i < textureOptions.length; i++) {
|
|
341
|
+
_loop_1(i);
|
|
342
|
+
}
|
|
343
|
+
return [4 /*yield*/, Promise.all(cubesPending)];
|
|
344
|
+
case 1:
|
|
345
|
+
_a.sent();
|
|
346
|
+
return [4 /*yield*/, Promise.all(filesPending)];
|
|
347
|
+
case 2:
|
|
348
|
+
files = _a.sent();
|
|
349
|
+
images = Array.from(new Set(files));
|
|
350
|
+
resultTextures = [];
|
|
351
|
+
bins = [];
|
|
352
|
+
for (i = 0; i < textureOptions.length; i++) {
|
|
353
|
+
texture = textureOptions[i];
|
|
354
|
+
if (texture.target === WebGLRenderingContext.TEXTURE_CUBE_MAP) {
|
|
355
|
+
info = cubeMap.get(texture);
|
|
356
|
+
bins.push(info.data);
|
|
357
|
+
tex = __assign(__assign({}, texture), { mipmaps: info.mipmaps, sourceType: 7 });
|
|
358
|
+
if ('cube' in tex) {
|
|
359
|
+
delete tex.cube;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
else {
|
|
363
|
+
buffer = imageMap.get(texture);
|
|
364
|
+
tex = __assign(__assign({}, texture), { source: images.indexOf(buffer) });
|
|
365
|
+
if ('mipmaps' in tex) {
|
|
366
|
+
// @ts-expect-error
|
|
367
|
+
delete tex.mipmaps;
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
if ('sourceFrom' in tex) {
|
|
371
|
+
delete tex.sourceFrom;
|
|
372
|
+
}
|
|
373
|
+
if ('image' in tex) {
|
|
374
|
+
delete tex.image;
|
|
375
|
+
}
|
|
376
|
+
resultTextures.push(tex);
|
|
377
|
+
}
|
|
378
|
+
return [2 /*return*/, {
|
|
379
|
+
version: '1.0',
|
|
380
|
+
images: images,
|
|
381
|
+
bins: bins,
|
|
382
|
+
textures: resultTextures,
|
|
383
|
+
}];
|
|
384
|
+
}
|
|
385
|
+
});
|
|
386
|
+
});
|
|
387
|
+
}
|
|
388
|
+
|
|
389
|
+
/**
|
|
390
|
+
* geometry 序列化
|
|
391
|
+
* @param geometries
|
|
392
|
+
*/
|
|
393
|
+
function serializeGeometries(geometries) {
|
|
394
|
+
var buffers = [];
|
|
395
|
+
var bufferInfo = new Map();
|
|
396
|
+
var offset = 0;
|
|
397
|
+
geometries.forEach(function (options) {
|
|
398
|
+
var _a;
|
|
399
|
+
addBuffer((_a = options.indices) === null || _a === void 0 ? void 0 : _a.data);
|
|
400
|
+
Object.values(options.attributes).forEach(function (attribute) {
|
|
401
|
+
var data = attribute.data;
|
|
402
|
+
addBuffer(data);
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
var resultBuffer = concatBuffers(buffers, bufferInfo, offset);
|
|
406
|
+
var mappedGeometries = geometries.map(function (props) {
|
|
407
|
+
var geometryProps = __assign({}, props);
|
|
408
|
+
if (geometryProps.indices) {
|
|
409
|
+
geometryProps.indices = replaceAttribute(geometryProps.indices);
|
|
410
|
+
}
|
|
411
|
+
geometryProps.attributes = {};
|
|
412
|
+
Object.keys(props.attributes).forEach(function (name) {
|
|
413
|
+
var attribute = props.attributes[name];
|
|
414
|
+
geometryProps.attributes[name] = replaceAttribute(attribute);
|
|
415
|
+
});
|
|
416
|
+
return geometryProps;
|
|
417
|
+
});
|
|
418
|
+
return {
|
|
419
|
+
data: resultBuffer,
|
|
420
|
+
geometries: mappedGeometries,
|
|
421
|
+
version: '1.0',
|
|
422
|
+
};
|
|
423
|
+
function addBuffer(buffer) {
|
|
424
|
+
if (buffer && !buffers.includes(buffer)) {
|
|
425
|
+
buffers.push(buffer);
|
|
426
|
+
bufferInfo.set(buffer, [0, offset, buffer.byteLength, getBinaryType(buffer)]);
|
|
427
|
+
offset += buffer.byteLength;
|
|
428
|
+
// padding 4bytes for f32
|
|
429
|
+
offset = Math.ceil(offset / 4) * 4;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
function replaceAttribute(attr) {
|
|
433
|
+
var source;
|
|
434
|
+
if (attr.data) {
|
|
435
|
+
var info = bufferInfo.get(attr.data);
|
|
436
|
+
if (info) {
|
|
437
|
+
source = { data: [spec.ValueType.BINARY, info] };
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return __assign(__assign({}, attr), source);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
/**
|
|
444
|
+
* geometry 反序列化
|
|
445
|
+
* @param geometryProps
|
|
446
|
+
* @param data
|
|
447
|
+
*/
|
|
448
|
+
function deserializeGeometry(geometryProps, data) {
|
|
449
|
+
var _a, _b;
|
|
450
|
+
var attributes = geometryProps.attributes;
|
|
451
|
+
var ret = __assign({}, geometryProps);
|
|
452
|
+
if (ret.indices) {
|
|
453
|
+
ret.indices = __assign({}, ret.indices);
|
|
454
|
+
if (ret.indices.data) {
|
|
455
|
+
// @ts-expect-error
|
|
456
|
+
ret.indices.data = typedArrayFromBinary(data, (_a = geometryProps.indices) === null || _a === void 0 ? void 0 : _a.data);
|
|
457
|
+
}
|
|
458
|
+
// @ts-expect-error
|
|
459
|
+
}
|
|
460
|
+
else if (ret.index) {
|
|
461
|
+
// FIXME: 兼容编辑器导出的旧版数据
|
|
462
|
+
// @ts-expect-error
|
|
463
|
+
ret.indices = __assign({}, ret.index);
|
|
464
|
+
// @ts-expect-error
|
|
465
|
+
if (ret.indices.data) {
|
|
466
|
+
// @ts-expect-error
|
|
467
|
+
ret.indices.data = typedArrayFromBinary(data, (_b = geometryProps.index) === null || _b === void 0 ? void 0 : _b.data);
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
Object.keys(attributes).forEach(function (name) {
|
|
471
|
+
var attribute = attributes[name];
|
|
472
|
+
var pointer = attribute.data;
|
|
473
|
+
ret.attributes[name] = __assign({}, attribute);
|
|
474
|
+
if (pointer) {
|
|
475
|
+
ret.attributes[name].data = typedArrayFromBinary(data, pointer);
|
|
476
|
+
}
|
|
477
|
+
});
|
|
478
|
+
return ret;
|
|
479
|
+
}
|
|
480
|
+
var ctrlMap = {
|
|
481
|
+
i8: Int8Array,
|
|
482
|
+
u8: Uint8Array,
|
|
483
|
+
i16: Int16Array,
|
|
484
|
+
u16: Uint16Array,
|
|
485
|
+
f32: Float32Array,
|
|
486
|
+
i32: Int32Array,
|
|
487
|
+
u32: Uint32Array,
|
|
488
|
+
};
|
|
489
|
+
/**
|
|
490
|
+
* 重构 TypedArray,返回的 TypedArray 如果修改,会反映到原始的 ArrayBuffer 中
|
|
491
|
+
* @param binaries
|
|
492
|
+
* @param pointer
|
|
493
|
+
*/
|
|
494
|
+
function typedArrayFromBinary(binary, pointer) {
|
|
495
|
+
if (pointer.length != 2 || pointer[0] !== spec.ValueType.BINARY || !(pointer[1] instanceof Array)) {
|
|
496
|
+
// 不是BinaryPointer,可能已经创建,直接返回
|
|
497
|
+
return pointer;
|
|
498
|
+
}
|
|
499
|
+
var _a = __read(pointer[1], 4), index = _a[0], start = _a[1], byteLength = _a[2], type = _a[3];
|
|
500
|
+
if (!type) {
|
|
501
|
+
return binary[index].slice(start, byteLength);
|
|
502
|
+
}
|
|
503
|
+
var CTRL = ctrlMap[type] || Uint8Array;
|
|
504
|
+
return new CTRL(binary[index], start, byteLength / CTRL.BYTES_PER_ELEMENT);
|
|
505
|
+
}
|
|
506
|
+
|
|
507
|
+
export { concatArrayBuffers, concatBuffers, deserializeGeometry, getBinaryType, getImageFileContent, loadMipmaps, serializeGeometries, serializeTextures, typedArrayFromBinary };
|
|
508
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { spec } from '@galacean/effects';
|
|
2
|
+
import type { GeometryProps } from '@galacean/effects';
|
|
3
|
+
export interface GeometrySerializationResult {
|
|
4
|
+
version: '1.0';
|
|
5
|
+
data: ArrayBuffer;
|
|
6
|
+
geometries: spec.GeometryOptionsJSON[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* geometry 序列化
|
|
10
|
+
* @param geometries
|
|
11
|
+
*/
|
|
12
|
+
export declare function serializeGeometries(geometries: GeometryProps[]): GeometrySerializationResult;
|
|
13
|
+
/**
|
|
14
|
+
* geometry 反序列化
|
|
15
|
+
* @param geometryProps
|
|
16
|
+
* @param data
|
|
17
|
+
*/
|
|
18
|
+
export declare function deserializeGeometry(geometryProps: spec.GeometryOptionsJSON, data: ArrayBuffer[]): GeometryProps;
|
|
19
|
+
/**
|
|
20
|
+
* 重构 TypedArray,返回的 TypedArray 如果修改,会反映到原始的 ArrayBuffer 中
|
|
21
|
+
* @param binaries
|
|
22
|
+
* @param pointer
|
|
23
|
+
*/
|
|
24
|
+
export declare function typedArrayFromBinary(binary: ArrayBuffer[], pointer: spec.BinaryPointer): spec.TypedArray | ArrayBuffer;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { Texture2DSourceOptions, TextureCubeSourceOptions, spec } from '@galacean/effects';
|
|
2
|
+
export interface TextureSerializationResult {
|
|
3
|
+
version: '1.0';
|
|
4
|
+
bins?: ArrayBuffer[];
|
|
5
|
+
images: ArrayBuffer[];
|
|
6
|
+
textures: spec.TextureJSONOptions[];
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* texture 序列化
|
|
10
|
+
* @param textureOptions
|
|
11
|
+
*/
|
|
12
|
+
export declare function serializeTextures(textureOptions: (Texture2DSourceOptions | TextureCubeSourceOptions)[]): Promise<TextureSerializationResult>;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { spec } from '@galacean/effects';
|
|
2
|
+
import type { TextureCubeSourceOptionsImage, TextureCubeSourceOptionsImageMipmaps } from '@galacean/effects';
|
|
3
|
+
export declare function loadMipmaps(textureOptions: TextureCubeSourceOptionsImageMipmaps | TextureCubeSourceOptionsImage, dataIndex: number): Promise<{
|
|
4
|
+
data: ArrayBuffer;
|
|
5
|
+
mipmaps: spec.SerializedTextureCubeMipmap[];
|
|
6
|
+
}>;
|
|
7
|
+
export declare function getImageFileContent(image: HTMLImageElement | ImageBitmap | HTMLVideoElement): Promise<ArrayBuffer>;
|
|
8
|
+
export declare function concatBuffers(buffers: (spec.TypedArray | ArrayBuffer)[], bufferInfo: Map<spec.TypedArray | ArrayBuffer, spec.BinaryPointerContent>, length: number): ArrayBuffer;
|
|
9
|
+
export declare function getBinaryType(arr: spec.TypedArray | ArrayBuffer): spec.BinaryType;
|
|
10
|
+
/**
|
|
11
|
+
* 工具方法,按照 4bytes 对齐方式合并 buffers,如果提供了 pointer,会把原来的 pointer 转化为新的映射
|
|
12
|
+
* 返回的 pointers 数组和传入的 pointers 数组长度一致,并且一一对应
|
|
13
|
+
* @internal
|
|
14
|
+
* @param buffers
|
|
15
|
+
* @param pointers - 如果不提供 pointers,将返回整段 buffers 的 pointer 重映射
|
|
16
|
+
* @param overwrite - 如果为 true,将直接改写参数中的 pointer 值,否则生成新的 pointer 传出
|
|
17
|
+
*/
|
|
18
|
+
export declare function concatArrayBuffers(buffers: (spec.TypedArray | ArrayBuffer)[], pointers?: spec.BinaryPointer[], overwrite?: boolean): {
|
|
19
|
+
data: ArrayBuffer;
|
|
20
|
+
pointers: spec.BinaryPointer[];
|
|
21
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@galacean/effects-helper",
|
|
3
|
+
"version": "0.0.1-alpha.0",
|
|
4
|
+
"description": "Galacean Effects runtime helper for the web",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist"
|
|
9
|
+
],
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": "./dist/index.mjs",
|
|
13
|
+
"types": "./dist/index.d.ts"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
"contributors": [
|
|
17
|
+
{
|
|
18
|
+
"name": "燃然"
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
"name": "意绮"
|
|
22
|
+
}
|
|
23
|
+
],
|
|
24
|
+
"author": "Ant Group CO., Ltd.",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"publishConfig": {
|
|
27
|
+
"access": "public",
|
|
28
|
+
"registry": "https://registry.npmjs.org"
|
|
29
|
+
},
|
|
30
|
+
"devDependencies": {
|
|
31
|
+
"@galacean/effects": "0.0.1-alpha.0"
|
|
32
|
+
},
|
|
33
|
+
"scripts": {
|
|
34
|
+
"prebuild": "pnpm clean",
|
|
35
|
+
"build": "pnpm build:declaration && pnpm build:module",
|
|
36
|
+
"build:module": "rollup -c",
|
|
37
|
+
"build:declaration": "tsc -d --declarationDir dist --emitDeclarationOnly",
|
|
38
|
+
"clean": "rimraf dist && rimraf '*+(.tsbuildinfo)'"
|
|
39
|
+
}
|
|
40
|
+
}
|