382 lines
31 KiB
JavaScript
382 lines
31 KiB
JavaScript
// This file is part of meshoptimizer library and is distributed under the terms of MIT License.
|
|||
|
|
// Copyright (C) 2016-2026, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
||
|
|
var MeshoptClusterizer = (function () {
|
||
|
|
// Built with clang version 22.1.0-wasi-sdk
|
||
|
|
// Built from meshoptimizer 1.1
|
||
|
|
var wasm =
|
||
|
|
'b9H79Tebbbe:neP9Geueu9Geub9Gbb9Giuuueu9Gmuuuuuuuuuuu9999eu9Gouuuuuueu9Gruuuuuuub9Gxuuuuuuuuuuuueu9Gxuuuuuuuuuuu99eu9GPuuuuuuuuuuuuu99b9Gouuuuuub9Gwuuuuuuuub9Gvuuuuub9GluuuubiQXdilvorwDqokoqxmbiibeilve9Weiiviebeoweuecj:Gdkr;Zeqo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bb8A9TW79O9V9Wt9F9I919P29K9nW79O2Wt79c9V919U9KbeY9TW79O9V9Wt9F9I919P29K9nW79O2Wt7S2W94bd39TW79O9V9Wt9F9I919P29K9nW79O2Wt79t9W9Ht9P9H2bo39TW79O9V9Wt9F9J9V9T9W91tWJ2917tWV9c9V919U9K7bw39TW79O9V9Wt9F9J9V9T9W91tW9nW79O2Wt9c9V919U9K7bkE9TW79O9V9Wt9F9J9V9T9W91tW9t9W9OWVW9c9V919U9K7bxL9TW79O9V9Wt9F9V9Wt9P9T9P96W9nW79O2WtbPl79IV9RbsDwebcekdOAq;W:leXdbkIbabaec9:fgefcufae9Ugeabci9Uadfcufad9Ugbaeab0Ek:88JDPue99eux99due99euo99iu8Jjjjjbc:WD9Rgm8KjjjjbdndnalmbcbhPxekamc:Cwfcbc;Kbz:rjjjb8AcuaocdtgsaocFFFFi0Ehzcbyd;0:G:cjbhHdndnalcb9imbaoal9nmbamazaHHjjjjbbgHBd:CwamceBd;8wamazcbyd;0:G:cjbHjjjjbbgOBd:GwamcdBd;8wamcualcdtalcFFFFi0Ecbyd;0:G:cjbHjjjjbbgABd:KwamciBd;8waihzalhsinaHazydbcdtfcbBdbazclfhzascufgsmbkaihzalhsinaHazydbcdtfgCaCydbcefBdbazclfhzascufgsmbkaihzalhCcbhXindnaHazydbcdtgQfgsydbcb9imbaOaQfaXBdbasasydbgQcjjjj94VBdbaQaXfhXkazclfhzaCcufgCmbkalci9UhLdnalci6mbcbhzaihsinascwfydbhCasclfydbhXaOasydbcdtfgQaQydbgQcefBdbaAaQcdtfazBdbaOaXcdtfgXaXydbgXcefBdbaAaXcdtfazBdbaOaCcdtfgCaCydbgCcefBdbaAaCcdtfazBdbascxfhsaLazcefgz9hmbkkaihzalhsindnaHazydbcdtgCfgXydbgQcu9kmbaXaQcFFFFrGgQBdbaOaCfgCaCydbaQ9RBdbkazclfhzascufgsmbxdkkamazaHHjjjjbbgHBd:CwamceBd;8wamazcbyd;0:G:cjbHjjjjbbgOBd:GwamcdBd;8wamcualcdtalcFFFFi0Ecbyd;0:G:cjbHjjjjbbgABd:KwamciBd;8waHcbasz:rjjjbhXaihzalhsinaXazydbcdtfgCaCydbcefBdbazclfhzascufgsmbkalci9UhLdnaoTmbcbhzaOhsaXhCaohQinasazBdbasclfhsaCydbazfhzaCclfhCaQcufgQmbkkdnalci6mbcbhzaihsinascwfydbhCasclfydbhQaOasydbcdtfgKaKydbgKcefBdbaAaKcdtfazBdbaOaQcdtfgQaQydbgQcefBdbaAaQcdtfazBdbaOaCcdtfgCaCydbgCcefBdbaAaCcdtfazBdbascxfhsaLazcefgz9hmbkkaoTmbcbhzaohsinaOazfgCaCydbaXazfydb9RBdbazclfhzascufgsmbkkamaLcbyd;0:G:cjbHjjjjbbgzBd:OwamclBd;8wazcbaLz:rjjjbhYamcuaLcK2alcjjjjd0Ecbyd;0:G:cjbHjjjjbbg8ABd:SwamcvBd;8wJbbbbhEdnalci6g3mbarcd4hKaihsa8AhzaLhrJbbbbh5inavasclfydbaK2cdtfgCIdlh8EavasydbaK2cdtfgXIdlhEavascwfydbaK2cdtfgQIdlh8FaCIdwhaaXIdwhhaQIdwhgazaCIdbg8JaXIdbg8KMaQIdbg8LMJbbnn:vUdbazclfaXIdlaCIdlMaQIdlMJbbnn:vUdbaQIdwh8MaCIdwh8NaXIdwhyazcxfa8EaE:tg8Eagah:tggNaaah:tgaa8FaE:tghN:tgEJbbbbJbbjZa8Ja8K:tg8FahNa8Ea8La8K:tg8KN:tghahNaEaENaaa8KNa8FagN:tgEaENMMg8K:rg8E:va8KJbbbb9BEg8KNUdbazczfaEa8KNUdbazcCfaha8KNUdbazcwfa8Maya8NMMJbbnn:vUdba5a8EMh5ascxfhsazcKfhzarcufgrmbka5aL:Z:vJbbbZNhEkamcuaLcdtalcFFFF970Ecbyd;0:G:cjbHjjjjbbgCBd:WwamcoBd;8waq:Zhhdna3mbcbhzaChsinasazBdbasclfhsaLazcefgz9hmbkkaEahNhhamcuaLcltalcFFFFd0Ecbyd;0:G:cjbHjjjjbbg8PBd:0wamcrBd;8wcba8Pa8AaCaLcbz:djjjb8AJFFuuh8MJFFuuh8NJFFuuhydnalci6mbJFFuuhya8AhzaLhsJFFuuh8NJFFuuh8MinazcwfIdbgEa8Ma8MaE9EEh8MazclfIdbgEa8Na8NaE9EEh8NazIdbgEayayaE9EEhyazcKfhzascufgsmbkkah:rhEamaocetgzcuaocu9kEcbyd;0:G:cjbHjjjjbbgCBd:4wdndnaoal9nmbaihzalhsinaCazydbcetfcFFi87ebazclfhzascufgsmbxdkkaCcFeazz:rjjjb8AkaEJbbbZNh8JcuhIdnalci6mbcbhsJFFuuhEa8AhzcuhIinazcwfIdba8M:tghahNazIdbay:tghahNazclfIdba8N:tghahNMM:rghaEaIcuSahaE9DVgXEhEasaIaXEhIazcKfhzaLascefgs9hmbkkamczfcbcjwz:rjjjb8Aam9cb83iwam9cb83ibaxa8JNh8RJbbjZak:th8Lcbh8SJbbbbhRJbbbbh8UJbbbbh8VJbbbbh8WJbbbbh8XJbbbbh8Ycbh8ZcbhPinJbbbbhEdna8STmbJbbjZa8S:Z:vhEkJbbbbhhdna8Ya8YNa8Wa8WNa8Xa8XNMMg8KJbbbb9BmbJbbjZa8K:r:vhhka8VaENh8Ka8UaENh5aRaENh8EaIhLdndndndndna8SaPVTmbamydwg80Tmea8YahNh8Fa8XahNhaa8WahNhgaeamydbcdtfh81cbh3JFFuuhEcvhQcuhLindnaHa81a3cdtfydbcdtgzfydbgvTmbaAaOazfydbcdtfhsindndnaCaiasydbgKcx2fgzclfydbgrcetf8Vebcs4aCazydbgXcetf8Vebcs4faCazcwfydbglcetf8Vebcs4fgombcbhzxekcehzaHaXcdtfydbgXceSmbcehzaHarcdtfydbgrceSmbcehzaHalcdtfydbglceSmbdnarcdSaXcdSfalcdSfcd6mbaocefhzxekaocdfhzkdnazaQ9kmba8AaKcK2fgXIdwa8K:tghahNaXIdba8E:tghahNaXIdla5:tghahNMM:ra8J:va8LNJbbjZMJ9VO:d86JbbjZaXIdCa8FNaXIdxagNaaaXIdzNMMakN:tghahJ9VO:d869DENghaEazaQ6ahaE9DVgXEhEaKaLaXEhLazaQaXEhQkasclfhsavcufgvmbkka3cefg3a809hmbkkaLcu9hmekama8KUd:ODama5Ud:KDama8EUd:GDamcuBd:qDamcFFF;7rBdjDa8Pcba8AaYamc:GDfamc:qDfamcjDfz:ejjjbamyd:qDhLdndnaxJbbbb9ETmba8SaD6mbaLcuSmeceh3amIdjDa8R9EmixdkaLcu9hmekdna8STmbabaPcltfgHam8Piw83dwaHam8Pib83
|
||
|
|
|
||
|
|
var wasmpack = new Uint8Array([
|
||
|
|
32, 0, 65, 2, 1, 106, 34, 33, 3, 128, 11, 4, 13, 64, 6, 253, 10, 7, 15, 116, 127, 5, 8, 12, 40, 16, 19, 54, 20, 9, 27, 255, 113, 17, 42, 67,
|
||
|
|
24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115,
|
||
|
|
]);
|
||
|
|
|
||
|
|
if (typeof WebAssembly !== 'object') {
|
||
|
|
return {
|
||
|
|
supported: false,
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
var instance;
|
||
|
|
|
||
|
|
var ready = WebAssembly.instantiate(unpack(wasm), {}).then(function (result) {
|
||
|
|
instance = result.instance;
|
||
|
|
instance.exports.__wasm_call_ctors();
|
||
|
|
});
|
||
|
|
|
||
|
|
function unpack(data) {
|
||
|
|
var result = new Uint8Array(data.length);
|
||
|
|
for (var i = 0; i < data.length; ++i) {
|
||
|
|
var ch = data.charCodeAt(i);
|
||
|
|
result[i] = ch > 96 ? ch - 97 : ch > 64 ? ch - 39 : ch + 4;
|
||
|
|
}
|
||
|
|
var write = 0;
|
||
|
|
for (var i = 0; i < data.length; ++i) {
|
||
|
|
result[write++] = result[i] < 60 ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i];
|
||
|
|
}
|
||
|
|
return result.buffer.slice(0, write);
|
||
|
|
}
|
||
|
|
|
||
|
|
function assert(cond) {
|
||
|
|
if (!cond) {
|
||
|
|
throw new Error('Assertion failed');
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
function bytes(view) {
|
||
|
|
return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
||
|
|
}
|
||
|
|
|
||
|
|
var BOUNDS_SIZE = 48;
|
||
|
|
var MESHLET_SIZE = 16;
|
||
|
|
|
||
|
|
function extractMeshlet(buffers, index) {
|
||
|
|
var vertex_offset = buffers.meshlets[index * 4 + 0];
|
||
|
|
var triangle_offset = buffers.meshlets[index * 4 + 1];
|
||
|
|
var vertex_count = buffers.meshlets[index * 4 + 2];
|
||
|
|
var triangle_count = buffers.meshlets[index * 4 + 3];
|
||
|
|
|
||
|
|
return {
|
||
|
|
vertices: buffers.vertices.subarray(vertex_offset, vertex_offset + vertex_count),
|
||
|
|
triangles: buffers.triangles.subarray(triangle_offset, triangle_offset + triangle_count * 3),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function buildMeshlets(
|
||
|
|
fun,
|
||
|
|
indices,
|
||
|
|
vertex_positions,
|
||
|
|
vertex_count,
|
||
|
|
vertex_positions_stride,
|
||
|
|
max_vertices,
|
||
|
|
min_triangles,
|
||
|
|
max_triangles,
|
||
|
|
parama,
|
||
|
|
paramb
|
||
|
|
) {
|
||
|
|
var sbrk = instance.exports.sbrk;
|
||
|
|
var max_meshlets = instance.exports.meshopt_buildMeshletsBound(indices.length, max_vertices, min_triangles);
|
||
|
|
|
||
|
|
// allocate memory
|
||
|
|
var meshletsp = sbrk(max_meshlets * MESHLET_SIZE);
|
||
|
|
var meshlet_verticesp = sbrk(indices.length * 4);
|
||
|
|
var meshlet_trianglesp = sbrk(indices.length);
|
||
|
|
|
||
|
|
var indicesp = sbrk(indices.byteLength);
|
||
|
|
var verticesp = sbrk(vertex_positions.byteLength);
|
||
|
|
|
||
|
|
// copy input data to wasm memory
|
||
|
|
var heap = new Uint8Array(instance.exports.memory.buffer);
|
||
|
|
heap.set(bytes(indices), indicesp);
|
||
|
|
heap.set(bytes(vertex_positions), verticesp);
|
||
|
|
|
||
|
|
var count = fun(
|
||
|
|
meshletsp,
|
||
|
|
meshlet_verticesp,
|
||
|
|
meshlet_trianglesp,
|
||
|
|
indicesp,
|
||
|
|
indices.length,
|
||
|
|
verticesp,
|
||
|
|
vertex_count,
|
||
|
|
vertex_positions_stride,
|
||
|
|
max_vertices,
|
||
|
|
min_triangles,
|
||
|
|
max_triangles,
|
||
|
|
parama,
|
||
|
|
paramb
|
||
|
|
);
|
||
|
|
|
||
|
|
// heap might (will?) have grown -> re-acquire
|
||
|
|
heap = new Uint8Array(instance.exports.memory.buffer);
|
||
|
|
|
||
|
|
var meshletBytes = heap.subarray(meshletsp, meshletsp + count * MESHLET_SIZE);
|
||
|
|
var meshlets = new Uint32Array(meshletBytes.buffer, meshletBytes.byteOffset, meshletBytes.byteLength / 4).slice();
|
||
|
|
|
||
|
|
for (var i = 0; i < count; ++i) {
|
||
|
|
var vertex_offset = meshlets[i * 4 + 0];
|
||
|
|
var triangle_offset = meshlets[i * 4 + 1];
|
||
|
|
var vertex_count = meshlets[i * 4 + 2];
|
||
|
|
var triangle_count = meshlets[i * 4 + 3];
|
||
|
|
|
||
|
|
instance.exports.meshopt_optimizeMeshlet(
|
||
|
|
meshlet_verticesp + vertex_offset * 4,
|
||
|
|
meshlet_trianglesp + triangle_offset,
|
||
|
|
triangle_count,
|
||
|
|
vertex_count
|
||
|
|
);
|
||
|
|
}
|
||
|
|
|
||
|
|
var used_vertices = count ? meshlets[(count - 1) * 4 + 0] + meshlets[(count - 1) * 4 + 2] : 0;
|
||
|
|
var used_triangles = count ? meshlets[(count - 1) * 4 + 1] + meshlets[(count - 1) * 4 + 3] * 3 : 0;
|
||
|
|
|
||
|
|
var result = {
|
||
|
|
meshlets: meshlets,
|
||
|
|
vertices: new Uint32Array(heap.buffer, meshlet_verticesp, used_vertices).slice(),
|
||
|
|
triangles: new Uint8Array(heap.buffer, meshlet_trianglesp, used_triangles).slice(),
|
||
|
|
meshletCount: count,
|
||
|
|
};
|
||
|
|
|
||
|
|
// reset memory
|
||
|
|
sbrk(meshletsp - sbrk(0));
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
function extractBounds(boundsp) {
|
||
|
|
var bounds_floats = new Float32Array(instance.exports.memory.buffer, boundsp, BOUNDS_SIZE / 4);
|
||
|
|
|
||
|
|
// see meshopt_Bounds in meshoptimizer.h for layout
|
||
|
|
return {
|
||
|
|
centerX: bounds_floats[0],
|
||
|
|
centerY: bounds_floats[1],
|
||
|
|
centerZ: bounds_floats[2],
|
||
|
|
radius: bounds_floats[3],
|
||
|
|
coneApexX: bounds_floats[4],
|
||
|
|
coneApexY: bounds_floats[5],
|
||
|
|
coneApexZ: bounds_floats[6],
|
||
|
|
coneAxisX: bounds_floats[7],
|
||
|
|
coneAxisY: bounds_floats[8],
|
||
|
|
coneAxisZ: bounds_floats[9],
|
||
|
|
coneCutoff: bounds_floats[10],
|
||
|
|
};
|
||
|
|
}
|
||
|
|
|
||
|
|
function computeMeshletBounds(buffers, vertex_positions, vertex_count, vertex_positions_stride) {
|
||
|
|
var sbrk = instance.exports.sbrk;
|
||
|
|
|
||
|
|
var results = [];
|
||
|
|
|
||
|
|
// allocate memory that's constant for all meshlets
|
||
|
|
var verticesp = sbrk(vertex_positions.byteLength);
|
||
|
|
var meshlet_verticesp = sbrk(buffers.vertices.byteLength);
|
||
|
|
var meshlet_trianglesp = sbrk(buffers.triangles.byteLength);
|
||
|
|
var resultp = sbrk(BOUNDS_SIZE);
|
||
|
|
|
||
|
|
// copy vertices to wasm memory
|
||
|
|
var heap = new Uint8Array(instance.exports.memory.buffer);
|
||
|
|
heap.set(bytes(vertex_positions), verticesp);
|
||
|
|
heap.set(bytes(buffers.vertices), meshlet_verticesp);
|
||
|
|
heap.set(bytes(buffers.triangles), meshlet_trianglesp);
|
||
|
|
|
||
|
|
for (var i = 0; i < buffers.meshletCount; ++i) {
|
||
|
|
var vertex_offset = buffers.meshlets[i * 4 + 0];
|
||
|
|
var triangle_offset = buffers.meshlets[i * 4 + 1];
|
||
|
|
var triangle_count = buffers.meshlets[i * 4 + 3];
|
||
|
|
|
||
|
|
instance.exports.meshopt_computeMeshletBounds(
|
||
|
|
resultp,
|
||
|
|
meshlet_verticesp + vertex_offset * 4,
|
||
|
|
meshlet_trianglesp + triangle_offset,
|
||
|
|
triangle_count,
|
||
|
|
verticesp,
|
||
|
|
vertex_count,
|
||
|
|
vertex_positions_stride
|
||
|
|
);
|
||
|
|
|
||
|
|
results.push(extractBounds(resultp));
|
||
|
|
}
|
||
|
|
|
||
|
|
// reset memory
|
||
|
|
sbrk(verticesp - sbrk(0));
|
||
|
|
|
||
|
|
return results;
|
||
|
|
}
|
||
|
|
|
||
|
|
function computeClusterBounds(indices, vertex_positions, vertex_count, vertex_positions_stride) {
|
||
|
|
var sbrk = instance.exports.sbrk;
|
||
|
|
|
||
|
|
// allocate memory
|
||
|
|
var resultp = sbrk(BOUNDS_SIZE);
|
||
|
|
var indicesp = sbrk(indices.byteLength);
|
||
|
|
var verticesp = sbrk(vertex_positions.byteLength);
|
||
|
|
|
||
|
|
// copy input data to wasm memory
|
||
|
|
var heap = new Uint8Array(instance.exports.memory.buffer);
|
||
|
|
heap.set(bytes(indices), indicesp);
|
||
|
|
heap.set(bytes(vertex_positions), verticesp);
|
||
|
|
|
||
|
|
instance.exports.meshopt_computeClusterBounds(resultp, indicesp, indices.length, verticesp, vertex_count, vertex_positions_stride);
|
||
|
|
|
||
|
|
var result = extractBounds(resultp);
|
||
|
|
|
||
|
|
// reset memory
|
||
|
|
sbrk(resultp - sbrk(0));
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
function computeSphereBounds(positions, count, positions_stride, radii, radii_stride) {
|
||
|
|
var sbrk = instance.exports.sbrk;
|
||
|
|
|
||
|
|
// allocate memory
|
||
|
|
var resultp = sbrk(BOUNDS_SIZE);
|
||
|
|
var positionsp = sbrk(positions.byteLength);
|
||
|
|
var radiip = radii ? sbrk(radii.byteLength) : 0;
|
||
|
|
|
||
|
|
// copy input data to wasm memory
|
||
|
|
var heap = new Uint8Array(instance.exports.memory.buffer);
|
||
|
|
heap.set(bytes(positions), positionsp);
|
||
|
|
if (radii) {
|
||
|
|
heap.set(bytes(radii), radiip);
|
||
|
|
}
|
||
|
|
|
||
|
|
instance.exports.meshopt_computeSphereBounds(resultp, positionsp, count, positions_stride, radiip, radii ? radii_stride : 0);
|
||
|
|
|
||
|
|
var result = extractBounds(resultp);
|
||
|
|
|
||
|
|
// reset memory
|
||
|
|
sbrk(resultp - sbrk(0));
|
||
|
|
|
||
|
|
return result;
|
||
|
|
}
|
||
|
|
|
||
|
|
return {
|
||
|
|
ready: ready,
|
||
|
|
supported: true,
|
||
|
|
buildMeshlets: function (indices, vertex_positions, vertex_positions_stride, max_vertices, max_triangles, cone_weight) {
|
||
|
|
assert(indices.length % 3 == 0);
|
||
|
|
assert(vertex_positions instanceof Float32Array);
|
||
|
|
assert(vertex_positions.length % vertex_positions_stride == 0);
|
||
|
|
assert(vertex_positions_stride >= 3);
|
||
|
|
assert(max_vertices >= 3 && max_vertices <= 256);
|
||
|
|
assert(max_triangles >= 1 && max_triangles <= 512);
|
||
|
|
|
||
|
|
cone_weight = cone_weight || 0.0;
|
||
|
|
|
||
|
|
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
||
|
|
|
||
|
|
return buildMeshlets(
|
||
|
|
instance.exports.meshopt_buildMeshletsFlex,
|
||
|
|
indices32,
|
||
|
|
vertex_positions,
|
||
|
|
vertex_positions.length / vertex_positions_stride,
|
||
|
|
vertex_positions_stride * 4,
|
||
|
|
max_vertices,
|
||
|
|
max_triangles,
|
||
|
|
max_triangles,
|
||
|
|
cone_weight,
|
||
|
|
0.0
|
||
|
|
);
|
||
|
|
},
|
||
|
|
buildMeshletsFlex: function (
|
||
|
|
indices,
|
||
|
|
vertex_positions,
|
||
|
|
vertex_positions_stride,
|
||
|
|
max_vertices,
|
||
|
|
min_triangles,
|
||
|
|
max_triangles,
|
||
|
|
cone_weight,
|
||
|
|
split_factor
|
||
|
|
) {
|
||
|
|
assert(indices.length % 3 == 0);
|
||
|
|
assert(vertex_positions instanceof Float32Array);
|
||
|
|
assert(vertex_positions.length % vertex_positions_stride == 0);
|
||
|
|
assert(vertex_positions_stride >= 3);
|
||
|
|
assert(max_vertices >= 3 && max_vertices <= 256);
|
||
|
|
assert(min_triangles >= 1 && max_triangles <= 512);
|
||
|
|
assert(min_triangles <= max_triangles);
|
||
|
|
|
||
|
|
cone_weight = cone_weight || 0.0;
|
||
|
|
split_factor = split_factor || 0.0;
|
||
|
|
|
||
|
|
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
||
|
|
|
||
|
|
return buildMeshlets(
|
||
|
|
instance.exports.meshopt_buildMeshletsFlex,
|
||
|
|
indices32,
|
||
|
|
vertex_positions,
|
||
|
|
vertex_positions.length / vertex_positions_stride,
|
||
|
|
vertex_positions_stride * 4,
|
||
|
|
max_vertices,
|
||
|
|
min_triangles,
|
||
|
|
max_triangles,
|
||
|
|
cone_weight,
|
||
|
|
split_factor
|
||
|
|
);
|
||
|
|
},
|
||
|
|
buildMeshletsSpatial: function (indices, vertex_positions, vertex_positions_stride, max_vertices, min_triangles, max_triangles, fill_weight) {
|
||
|
|
assert(indices.length % 3 == 0);
|
||
|
|
assert(vertex_positions instanceof Float32Array);
|
||
|
|
assert(vertex_positions.length % vertex_positions_stride == 0);
|
||
|
|
assert(vertex_positions_stride >= 3);
|
||
|
|
assert(max_vertices >= 3 && max_vertices <= 256);
|
||
|
|
assert(min_triangles >= 1 && max_triangles <= 512);
|
||
|
|
assert(min_triangles <= max_triangles);
|
||
|
|
|
||
|
|
fill_weight = fill_weight || 0.0;
|
||
|
|
|
||
|
|
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
||
|
|
|
||
|
|
return buildMeshlets(
|
||
|
|
instance.exports.meshopt_buildMeshletsSpatial,
|
||
|
|
indices32,
|
||
|
|
vertex_positions,
|
||
|
|
vertex_positions.length / vertex_positions_stride,
|
||
|
|
vertex_positions_stride * 4,
|
||
|
|
max_vertices,
|
||
|
|
min_triangles,
|
||
|
|
max_triangles,
|
||
|
|
fill_weight
|
||
|
|
);
|
||
|
|
},
|
||
|
|
extractMeshlet: function (buffers, index) {
|
||
|
|
assert(index >= 0 && index < buffers.meshletCount);
|
||
|
|
|
||
|
|
return extractMeshlet(buffers, index);
|
||
|
|
},
|
||
|
|
computeClusterBounds: function (indices, vertex_positions, vertex_positions_stride) {
|
||
|
|
assert(indices.length % 3 == 0);
|
||
|
|
assert(indices.length / 3 <= 512);
|
||
|
|
assert(vertex_positions instanceof Float32Array);
|
||
|
|
assert(vertex_positions.length % vertex_positions_stride == 0);
|
||
|
|
assert(vertex_positions_stride >= 3);
|
||
|
|
|
||
|
|
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
||
|
|
|
||
|
|
return computeClusterBounds(indices32, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4);
|
||
|
|
},
|
||
|
|
computeMeshletBounds: function (buffers, vertex_positions, vertex_positions_stride) {
|
||
|
|
assert(vertex_positions instanceof Float32Array);
|
||
|
|
assert(vertex_positions.length % vertex_positions_stride == 0);
|
||
|
|
assert(vertex_positions_stride >= 3);
|
||
|
|
|
||
|
|
return computeMeshletBounds(buffers, vertex_positions, vertex_positions.length / vertex_positions_stride, vertex_positions_stride * 4);
|
||
|
|
},
|
||
|
|
computeSphereBounds: function (positions, positions_stride, radii, radii_stride) {
|
||
|
|
assert(positions instanceof Float32Array);
|
||
|
|
assert(positions.length % positions_stride == 0);
|
||
|
|
assert(positions_stride >= 3);
|
||
|
|
assert(!radii || radii instanceof Float32Array);
|
||
|
|
assert(!radii || radii.length % radii_stride == 0);
|
||
|
|
assert(!radii || radii_stride >= 1);
|
||
|
|
assert(!radii || positions.length / positions_stride == radii.length / radii_stride);
|
||
|
|
|
||
|
|
radii_stride = radii_stride || 0;
|
||
|
|
|
||
|
|
return computeSphereBounds(positions, positions.length / positions_stride, positions_stride * 4, radii, radii_stride * 4);
|
||
|
|
},
|
||
|
|
};
|
||
|
|
})();
|
||
|
|
|
||
|
|
export { MeshoptClusterizer };
|