@playcanvas/splat-transform 1.9.1 → 1.9.2
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 -1
- package/dist/cli.mjs +1334 -8
- package/dist/cli.mjs.map +1 -1
- package/dist/index.cjs +1319 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1319 -5
- package/dist/index.mjs.map +1 -1
- package/dist/lib/index.d.cts +2 -0
- package/dist/lib/index.d.ts +2 -0
- package/dist/lib/types.d.ts +4 -0
- package/dist/lib/voxel/collision-glb.d.ts +12 -0
- package/dist/lib/voxel/index.d.ts +2 -0
- package/dist/lib/voxel/marching-cubes.d.ts +25 -0
- package/dist/lib/writers/write-voxel.d.ts +7 -1
- package/package.json +2 -1
package/dist/cli.mjs
CHANGED
|
@@ -16439,7 +16439,7 @@ class CompressedChunk {
|
|
|
16439
16439
|
}
|
|
16440
16440
|
}
|
|
16441
16441
|
|
|
16442
|
-
var version = "1.9.
|
|
16442
|
+
var version = "1.9.2";
|
|
16443
16443
|
|
|
16444
16444
|
const generatedByString = `Generated by splat-transform ${version}`;
|
|
16445
16445
|
const chunkProps = [
|
|
@@ -18486,6 +18486,746 @@ const writePly = async (options, fs) => {
|
|
|
18486
18486
|
await writer.close();
|
|
18487
18487
|
};
|
|
18488
18488
|
|
|
18489
|
+
// This file is part of meshoptimizer library and is distributed under the terms of MIT License.
|
|
18490
|
+
// Copyright (C) 2016-2025, by Arseny Kapoulkine (arseny.kapoulkine@gmail.com)
|
|
18491
|
+
var MeshoptSimplifier = (function () {
|
|
18492
|
+
// Built with clang version 19.1.5-wasi-sdk
|
|
18493
|
+
// Built from meshoptimizer 1.0
|
|
18494
|
+
var wasm =
|
|
18495
|
+
'b9H79Tebbbe:6eO9Geueu9Geub9Gbb9Gsuuuuuuuuuuuu99uueu9Gvuuuuub9Gruuuuuuub9Gouuuuuue999Gvuuuuueu9Gzuuuuuuuuuuu99uuuub9Gquuuuuuu99uueu9GPuuuuuuuuuuu99uueu9Gquuuuuuuu99ueu9Gruuuuuu99eu9Gwuuuuuu99ueu9Giuuue999Gluuuueu9Gluuuub9GiuuueuiLQdilvorlwDiqkxmPszbHHbelve9Weiiviebeoweuec:G:Pdkr:Bdxo9TW9T9VV95dbH9F9F939H79T9F9J9H229F9Jt9VV7bbz9TW79O9V9Wt9F79P9T9W29P9M95bw8E9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9OcttV9P9I91tW7bD8A9TW79O9V9Wt9F79P9T9W29P9M959x9Pt9O9v9W9K9HtWbqQ9TW79O9V9Wt9F79P9T9W29P9M959t29V9W9W95bkX9TW79O9V9Wt9F79P9T9W29P9M959qV919UWbxQ9TW79O9V9Wt9F79P9T9W29P9M959q9V9P9Ut7bmX9TW79O9V9Wt9F79P9T9W29P9M959t9J9H2WbPa9TW79O9V9Wt9F9V9Wt9P9T9P96W9wWVtW94SWt9J9O9sW9T9H9Wbs59TW79O9V9Wt9F9NW9UWV9HtW9q9V79Pt9P9V9U9sW9T9H9Wbzl79IV9RbHDwebcekdCXqM;YeQdbk;A1er3ue99euE99Que9:r998Jjjjjbcj;sb9Rgs8Kjjjjbcbhzasc:Cefcbc;Kbz:tjjjb8AdnabaeSmbabaeadcdtzMjjjb8AkdnamcdGTmbalcrfci4cbyd1:jjjbHjjjjbbhHasc:Cefasyd;8egecdtfaHBdbasaecefBd;8ecbhlcbhednadTmbabheadhOinaHaeydbci4fcb86bbaeclfheaOcufgOmbkcbhlabheadhOinaHaeydbgAci4fgCaCRbbgCceaAcrGgAtV86bbaCcu7aA4ceGalfhlaeclfheaOcufgOmbkcualcdtalcFFFFi0Ehekaecbyd1:jjjbHjjjjbbhzasc:Cefasyd;8egecdtfazBdbasaecefBd;8ealcd4alfhOcehHinaHgecethHaeaO6mbkcbhXcuaecdtgOaecFFFFi0Ecbyd1:jjjbHjjjjbbhHasc:Cefasyd;8egAcdtfaHBdbasaAcefBd;8eaHcFeaOz:tjjjbhQdnadTmbaecufhLcbhKindndnaQabaXcdtfgYydbgAc:v;t;h;Ev2aLGgOcdtfgCydbgHcuSmbceheinazaHcdtfydbaASmdaOaefhHaecefheaQaHaLGgOcdtfgCydbgHcu9hmbkkazaKcdtfaABdbaCaKBdbaKhHaKcefhKkaYaHBdbaXcefgXad9hmbkkaQcbyd:m:jjjbH:bjjjbbasasyd;8ecufBd;8ekcbh8AcualcefgecdtaecFFFFi0Ecbyd1:jjjbHjjjjbbhXasc:Cefasyd;8egecdtfaXBdbasaXBdNeasaecefBd;8ecuadcitadcFFFFe0Ecbyd1:jjjbHjjjjbbhEasc:Cefasyd;8egecdtfaEBdbasaEBd:yeasaecefBd;8eascNefabadalcbz:cjjjbcualcdtgealcFFFFi0Eg3cbyd1:jjjbHjjjjbbhAasc:Cefasyd;8egHcdtfaABdbasaHcefBd;8ea3cbyd1:jjjbHjjjjbbhKasc:Cefasyd;8egHcdtfaKBdbasaHcefBd;8eaAaKaialavazasc:Cefz:djjjbalcbyd1:jjjbHjjjjbbh5asc:Cefasyd;8egHcdtfa5BdbasaHcefBd;8ea3cbyd1:jjjbHjjjjbbhHasc:Cefasyd;8egOcdtfaHBdbasaOcefBd;8ea3cbyd1:jjjbHjjjjbbhOasc:Cefasyd;8egCcdtfaOBdbasaCcefBd;8eaHcFeaez:tjjjbh8EaOcFeaez:tjjjbh8FdnalTmbaEcwfhaindnaXa8AgOcefg8AcdtfydbgCaXaOcdtgefydbgHSmbaCaH9RhhaEaHcitfhga8Faefh8Ja8Eaefh8KcbhQindndnagaQcitfydbgLaO9hmba8KaOBdba8JaOBdbxekdnaXaLcdtg8LfgeclfydbgHaeydbgeSmbaEaecitgCfydbaOSmeaHae9Rh8Maecu7aHfhYaaaCfhHcbheinaYaeSmeaecefheaHydbhCaHcwfhHaCaO9hmbkaea8M6meka8Fa8LfgeaOaLaeydbcuSEBdba8KaLaOa8KydbcuSEBdbkaQcefgQah9hmbkka8Aal9hmbkaAhHaKhOa8FhCa8EhQcbheindndnaeaHydbgL9hmbdnaeaOydbgL9hmbaQydbhLdnaCydbgYcu9hmbaLcu9hmba5aefcb86bbxikdnaYcuSmbaLcuSmbaeaYSmbaAaYcdtfydbaAaLcdtfydb9hmba5aefcd86bbxika5aefh8KdnaeaYSmbaeaLSmba8Kce86bbxika8Kcl86bbxdkdnaeaKaLcdtgYfydb9hmbdnaCydbg8KcuSmbaea8KSmbaQydbghcuSmbaeahSmba8FaYfydbggcuSmbagaLSmba8EaYfydbgYcuSmbaYaLSmbdnaAa8KcdtfydbgLaAaYcdtfydb9hmbaLaAahcdtfydbgYSmbaYaAagcdtfydb9hmba5aefcd86bbxlka5aefcl86bbxika5aefcl86bbxdka5aefcl86bbxeka5aefa5aLfRbb86bbkaHclfhHaOclfhOaCclfhCaQclfhQalaecefge9hmbkdnamcaGTmbaEcwfh8Jcbh8Nindndna5a8NfgyRbbg8Pc9:fPibebekdndndnaAa8Ncdtfydbgea8N9hmbdnaqmbcbhgxdkdnazTmbcbhga8NheinagaqazaecdtgefydbfRbbcdGce4VhgaKaefydbgea8N9hmbxikkcbhga8NheinagaqaefRbbcdGce4VhgaKaecdtfydbgea8N9hmbxdkka5aefRbbhexeka8NheindnaXaecdtgafgeclfydbgHaeydbgeSmbaHae9Rh8AaEaecitfh8MaAaafh8Lcbh8Kina8Ma8KcitfydbgYhednindnaXaecdtgLfgeclfydbgHaeydbgeSmbdnaAaEaecitgOfydbcdtfydba8LydbgQ9hmbcehexikaHae9Rhhaecu7aHfhCa8JaOfhHcbheinaCaeSmeaecefheaHydbhOaHcwfhHaAaOcdtfydbaQ9hmbkaeah6hexdkaKaLfydbgeaY9hmbkcbhekagaece7Vhga8Kcefg8Ka8A9hmbkkaKaafydbgea8N9hmbka8PciagceGEhekayae86bbka8Ncefg8Nal9hmbkkdnaqTmbdndnazTmbazheaAhHalhOindnaqaeydbfRbbceGTmba5aHydbfcl86bbkaeclfheaHclfhHaOcufgOmbxdkkaqheaAhHalhOindnaeRbbceGTmba5aHydbfcl86bbkaecefheaHclfhHaOcufgOmbkkaAhealhOa5hHindna5aeydbfRbbcl9hmbaHcl86bbkaeclfheaHcefhHaOcufgOmbkkamceGTmba5healhHindnaeRbbce9hmbaecl86bbkaecefheaHcufgHmbkkcbhIcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbhaasc:Cefasyd;8egecdtfaaBdbasaecefBd;8easc:qefcbBdbas9cb83i1eaaaialavazasc1efz:ejjjbh8RdndnaDmbcbhycbhCxekcbhCawhecbhHindnaeIdbJbbbb9ETmbasaCcdtfaHBdbaCcefhCkaeclfheaDaHcefgH9hmbkcuaCal2gecdtaecFFFFi0Ecbyd1:jjjbHjjjjbbhyasc:Cefasyd;8egecdtfayBdbasaecefBd;8ealTmbdnaCmbcbhCxekarcd4h8KdnazTmbaCcdthhcbhXayhYinaoazaXcdtfydba8K2cdtfhLasheaYhHaChOinaHaLaeydbcdtgQfIdbawaQfIdbNUdbaeclfheaHclfhHaOcufgOmbkaYahfhYaXcefgXal9hmbxdkkaCcdthhcbhXayhYinaoaXa8K2cdtfhLasheaYhHaChOinaHaLaeydbcdtgQfIdbawaQfIdbNUdbaeclfheaHclfhHaOcufgOmbkaYahfhYaXcefgXal9hmbkkcualc8S2gHalc;D;O;f8U0EgQcbyd1:jjjbHjjjjbbheasc:Cefasyd;8egOcdtfaeBdbasaOcefBd;8eaecbaHz:tjjjbh8ScbhDcbh8KdnaCTmbcbhIaQcbyd1:jjjbHjjjjbbh8Kasc:Cefasyd;8egecdtfa8KBdbasaecefBd;8ea8KcbaHz:tjjjb8AcuaCal2gecltgHaecFFFFb0Ecbyd1:jjjbHjjjjbbhDasc:Cefasyd;8egecdtfaDBdbasaecefBd;8eaDcbaHz:tjjjb8AamcjjjjdGTmbcualcltgealcFFFFb0Ecbyd1:jjjbHjjjjbbhIasc:Cefasyd;8egHcdtfaIBdbasaHcefBd;8eaIcbaez:tjjjb8AkdnadTmbcbhLabhHinaaaHclfydbgXcx2fgeIdbaaaHydbgYcx2fgOIdbgR:tg8UaaaHcwfydbghcx2fgQIdlaOIdlg8V:tg8WNaQIdbaR:tg8XaeIdla8V:tg8YN:tg8Zh80aeIdwaOIdwg81:tgBa8XNaQIdwa81:tg83a8UN:tgUh8Xa8Ya83Na8WaBN:tg8Yh8Udna8Za8ZNa8Ya8YNaUaUNMM:rgBJbbbb9EgOTmba8ZaB:vh80aUaB:vh8Xa8YaB:vh8Uka8SaAaYcdtfydbgQc8S2fgea8UaB:rg8Wa8UNNg85aeIdbMUdbaea8Xa8Wa8XNg86Ng87aeIdlMUdlaea80a8Wa80Ng83Ng88aeIdwMUdwaea86a8UNg86aeIdxMUdxaea83a8UNg89aeIdzMUdzaea83a8XNg8:aeIdCMUdCaea8Ua8Wa80a81Na8UaRNa8Va8XNMM:mgZNg83Ng8UaeIdKMUdKaea8Xa83Ng8XaeId3MUd3aea80a83Ng80aeIdaMUdaaea83aZNg83aeId8KMUd8Kaea8WaeIdyMUdya8SaAaXcdtfydbgXc8S2fgea85aeIdbMUdbaea87aeIdlMUdlaea88aeIdwMUdwaea86aeIdxMUdxaea89aeIdzMUdzaea8:aeIdCMUdCaea8UaeIdKMUdKaea8XaeId3MUd3aea80aeIdaMUdaaea83aeId8KMUd8Kaea8WaeIdyMUdya8SaAahcdtfydbgYc8S2fgea85aeIdbMUdbaea87aeIdlMUdlaea88aeIdwMUdwaea86aeIdxMUdxaea89aeIdzMUdzaea8:aeIdCMUdCaea8UaeIdKMUdKaea8XaeId3MUd3aea80aeIdaMUdaaea83aeId8KMUd8Kaea8WaeIdyMUdydnaITmbdnaOTmba8ZaB:vh8ZaUaB:vhUa8YaB:vh8YkaIaQcltfgeaBJbbbZNg8UaUNg8WaeIdlMUdlaea8Ua8ZNg8XaeIdwMUdwaea8Ua8YNg80aeIdbMUdbaea8UaR:ma8YNaUa8VN:ta81a8ZN:tNg8UaeIdxMUdxaIaXcltfgea8WaeIdlMUdlaea8XaeIdwMUdwaea80aeIdbMUdbaea8UaeIdxMUdxaIaYcltfgea8WaeIdlMUdlaea8XaeIdwMUdwaea80aeIdbMUdbaea8UaeIdxMUdxkaHcxfhHaLcifgLad6mbkkdnalTmbJ;n;m;m89J:v:;;w8ZamczGEh8YcbhOaAhQaahHa8SheindnaOaQydb9hmbaecxfgLaLIdbJbbbbMUdbaeczfgLaLIdbJbbbbMUdbaecCfgLaLIdbJbbbbMUdbaea8YaecyfgLIdbg8ZNg8UaeIdbMUdbaeclfgXa8UaXIdbMUdbaecwfgXa8UaXIdbMUdbaecKfgXaXIdbaHIdbg8Xa8UN:tUdbaHcwfIdbh8Waec3fgXaXIdba8UaHclfIdbg80N:tUdbaecafgXaXIdba8Ua8WN:tUdbaec8KfgXIdbhUaLa8Za8UMUdbaXaUa8Ua8Wa8WNa8Xa8XNa80a80NMMNMUdbkaQclfhQaHcxfhHaec8SfhealaOcefgO9hmbkkdnadTmbcbhhabhYinabahcdtfhXcbhHina5aXaHc:G1jjbfydbcdtfydbgOfRbbhedndna5aYaHfydbgQfRbbgLc99fcFeGcpe0mbaec99fcFeGc;:e6mekdnaLcufcFeGce0mba8EaQcdtfydbaO9hmekdnaecufcFeGce0mba8FaOcdtfydbaQ9hmekJbbacJbbacJbbbZaecFeGceSEaLcFeGceSEh88aaaOcx2fgeIdwaaaQcx2fgLIdwgB:tg80:mh86aeIdlaLIdlg83:tg8Z:mh89aeIdbaLIdbgR:tgU:mh8:dnaaaXaHc:K1jjbfydbcdtfydbcx2fgeIdwaB:tg8Va80a80NaUaUNa8Za8ZNMMg8YNa8Va80NaeIdbaR:tg81aUNa8ZaeIdla83:tg85NMMg8Wa80N:tg8Xa8XNa81a8YNa8WaUN:tg8Ua8UNa85a8YNa8Wa8ZN:tg8Wa8WNMM:rg87Jbbbb9ETmba8Xa87:vh8Xa8Wa87:vh8Wa8Ua87:vh8Uka88a8Y:rNg8Ya8XaBNa8UaRNa83a8WNMM:mgZNg87aZNhZa8Xa87Nhna8Wa87Nhca8Ua87Nh9ca8Ya8XNg87a8WNhJa87a8UNh9ea8Ya8WNgTa8UNhSa8Xa87Nh87a8WaTNhTa8Ua8Ya8UNNh9hdnaUa85Na81a89NMg8Xa8XNa8Za8VNa85a86NMg8Ua8UNa80a81Na8Va8:NMg8Wa8WNMM:rg80Jbbbb9ETmba8Xa80:vh8Xa8Wa80:vh8Wa8Ua80:vh8Uka8SaAaQcdtfydbc8S2fgeaeIdba9ha8Ua88a80:rNg80a8UNNMgUMUdbaeaTa8Wa80a8WNg8VNMg81aeIdlMUdlaea87a8Xa80a8XNg8ZNMg85aeIdwMUdwaeaSa8Va8UNMg8VaeIdxMUdxaea9ea8Za8UNMg87aeIdzMUdzaeaJa8Za8WNMg8ZaeIdCMUdCaea9ca8Ua80a8XaBNa8UaRNa83a8WNMMgB:mNg80NMg8UaeIdKMUdKaeaca8Wa80NMg8WaeId3MUd3aeana8Xa80NMg8XaeIdaMUdaaeaZaBa80N:tg80aeId8KMUd8Kaea8YJbbbbMg8YaeIdyMUdya8SaAaOcdtfydbc8S2fgeaUaeIdbMUdbaea81aeIdlMUdlaea85aeIdwMUdwaea8VaeIdxMUdxaea87aeIdzMUdzaea8ZaeIdCMUdCaea8UaeIdKMUdKaea8WaeId3MUd3aea8XaeIdaMUdaaea80aeId8KMUd8Kaea8YaeIdyMUdykaHclfgHcx9hmbkaYcxfhYahcifghad6mbkaCTmbcbhYinJbbbbh8YaaabaYcdtfgeclfydbghcx2fgHIdwaaaeydbggcx2fgOIdwg81:tg8Wa8WNaHIdbaOIdbg85:tg8Xa8XNaHIdlaOIdlg87:tg80a80NMMgRaaaecwfydbgEcx2fgeIdwa81:tg8ZNa8Wa8Wa8ZNa8XaeIdba85:tgUNa80aeIdla87:tgBNMMg8UN:tJbbbbJbbjZaRa8Za8ZNaUaUNaBaBNMMg8VNa8Ua8UN:tg83:va83Jbbbb9BEg83Nh89a8Va8WNa8Za8UN:ta83Nh8:aRaBNa80a8UN:ta83NhZa8Va80NaBa8UN:ta83NhnaRaUNa8Xa8UN:ta83Nhca8Va8XNaUa8UN:ta83Nh9ca8XaBNaUa80N:tg8Ua8UNa80a8ZNaBa8WN:tg8Ua8UNa8WaUNa8Za8XN:tg8Ua8UNMM:rJbbbZNh8UayagaC2g8LcdtfhHayaEaC2g8JcdtfhOayahaC2g8AcdtfhQa81:mhJa87:mh9ea85:mhTcbhLaChXJbbbbhBJbbbbh83JbbbbhRJbbbbh8VJbbbbh81Jbbbbh85Jbbbbh87Jbbbbh88Jbbbbh86inascjdfaLfgecwfa8Ua8:aQIdbaHIdbg8Z:tg80Na89aOIdba8Z:tgUNMg8WNUdbaeclfa8Uana80NaZaUNMg8XNUdbaea8Ua9ca80NacaUNMg80NUdbaecxfa8UaJa8WNa9ea8XNa8ZaTa80NMMMg8ZNUdba8Ua8Wa8XNNa8VMh8Va8Ua8Wa80NNa81Mh81a8Ua8Xa80NNa85Mh85a8Ua8Za8ZNNa8YMh8Ya8Ua8Wa8ZNNaBMhBa8Ua8Xa8ZNNa83Mh83a8Ua80a8ZNNaRMhRa8Ua8Wa8WNNa87Mh87a8Ua8Xa8XNNa88Mh88a8Ua80a80NNa86Mh86aHclfhHaQclfhQaOclfhOaLczfhLaXcufgXmbka8Kagc8S2fgea86aeIdbMUdbaea88aeIdlMUdlaea87aeIdwMUdwaea85aeIdxMUdxaea81aeIdzMUdzaea8VaeIdCMUdCaeaRaeIdKMUdKaea83aeId3MUd3aeaBaeIdaMUdaaea8YaeId8KMUd8Kaea8UaeIdyMUdya8Kahc8S2fgea86aeIdbMUdbaea88aeIdlMUdlaea87aeIdwMUdwaea85aeIdxMUdxaea81aeIdzMUdzaea8VaeIdCMUdCaeaRaeIdKMUdKaea83aeId3MUd3aeaBaeIdaMUdaaea8YaeId8KMUd8Kaea8UaeIdyMUdya8KaEc8S2fgea86aeIdbMUdbaea88aeIdlMUdlaea87aeIdwMUdwaea85aeIdxMUdxaea81aeIdzMUdzaea8VaeIdCMUdCaeaRaeIdKMUdKaea83aeId3MUd3aeaBaeIdaMUdaaea8YaeId8KMUd8Kaea8UaeIdyMUdyaDa8LcltfhXcbhHaChQinaXaHfgeascjdfaHfgOIdbaeIdbMUdbaeclfgLaOclfIdbaLIdbMUdbaecwfgLaOcwfIdbaLIdbMUdbaecxfgeaOcxfIdbaeIdbMUdbaHczfhHaQcufgQmbkaDa8AcltfhXcbhHaChQinaXaHfgeascjdfaHfgOIdbaeIdbMUdbaeclfgLaOclfIdbaLIdbMUdbaecwfgLaOcwfIdbaLIdbMUdbaecxfgeaOcxfIdbaeIdbMUdbaHczfhHaQcufgQmbkaDa8JcltfhXcbhHaChQinaXaHfgeascjdfaHfgOIdbaeIdbMUdbaeclfgLaOclfIdbaLIdbMUdbaecwfgLaOcwfIdbaLIdbMUdbaecxfgeaOcxfIdbaeIdbMUdbaHczfhHaQcufgQmbkaYcifgYad6mbkkcbhOdndnamcwGg9imbJbbbbhRcbh6cbh9kcbh0xekcbh6a3cbyd1:jjjbHjjjjbbh0asc:Cefasyd;8egecdtfa0BdbasaecefBd;8ecua0alabadaAz:fjjjbgQcltaQcjjjjiGEcbyd1:jjjbHjjjjbbh9kasc:Cefasyd;8egecdtfa9kBdbasaecefBd;8ea9kaQa0aaalz:gjjjbJFFuuhRaQTmba9kheaQhHinaeIdbg8UaRaRa8U9EEhRaeclfheaHcufgHmbkaQh6kasydNeh9mdnalTmba9mclfhea9mydbhQa5hHalhLcbhOincbaeydbgXaQ9RaHRbbcpeGEaOfhOaHcefhHaeclfheaXhQaLcufgLmbkaOce4hOkcuadaO9Rcifg9ncx2a9nc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbh9oasc:Cefasyd;8egecdtfa9oBdbasaecefBd;8ecua9ncdta9ncFFFFi0Ecbyd1:jjjbHjjjjbbh9pasc:Cefasyd;8egecdtfa9pBdbasaecefBd;8ea3cbyd1:jjjbHjjjjbbh8Pasc:Cefasyd;8egecdtfa8PBdbasaecefBd;8ealcbyd1:jjjbHjjjjbbh9qasc:Cefasyd;8egecdtfa9qBdbasaecefBd;8eaxaxNa8RJbbjZamclGEgnanN:vh88Jbbbbh86dnadak9nmbdna9nci6mbasyd:yeh9raCclth9sa9ocwfh9tJbbbbh87Jbbbbh86inascNefabadalaAz:cjjjbabhgcbh8Ncbh3inaba3cdtfh8LcbheindnaAagaefydbgOcdtghfydbgQaAa8Laec:W1jjbfydbcdtfydbgHcdtgEfydbgLSmba5aHfRbbgYcv2a5aOfRbbgXfc;a1jjbfRbbg8AaXcv2aYfg8Jc;a1jjbfRbbg8MVcFeGTmbdnaLaQ9nmba8Jc;G1jjbfRbbcFeGmekdnaXcufcFeGce0mbaYTmba8EahfydbaH9hmekdnaXTmbaYcufcFeGce0mba8FaEfydbaO9hmeka9oa8Ncx2fgQaHaOa8McFeGgLEBdlaQaOaHaLEBdbaQaLa8AGcb9hBdwa8Ncefh8Nkaeclfgecx9hmbkdna3cifg3ad9pmbagcxfhga8Ncifa9n9nmekka8NTmdcbh8Jina8SaAa9oa8Jcx2fghydbgLcdtgQfydbggc8S2fgeIdwaaahydlgXcx2fgHIdwg8XNaeIdzaHIdbg80NaeIdaMg8Ua8UMMa8XNaeIdlaHIdlg8ZNaeIdCa8XNaeId3Mg8Ua8UMMa8ZNaeIdba80NaeIdxa8ZNaeIdKMg8Ua8UMMa80NaeId8KMMM:lh8UJbbbbJbbjZaeIdyg8W:va8WJbbbb9BEh8Wdndnahydwg8LmbJFFuuh83xekJbbbbJbbjZa8SaAaXcdtfydbc8S2fgeIdygU:vaUJbbbb9BEaeIdwaaaLcx2fgHIdwgUNaeIdzaHIdbg8YNaeIdaMgBaBMMaUNaeIdlaHIdlgBNaeIdCaUNaeId3MgUaUMMaBNaeIdba8YNaeIdxaBNaeIdKMgUaUMMa8YNaeId8KMMM:lNh83ka8Wa8UNhBdnaCTmba8KaLc8S2fgOIdwa8XNaOIdza80NaOIdaMg8Ua8UMMa8XNaOIdla8ZNaOIdCa8XNaOId3Mg8Ua8UMMa8ZNaOIdba80NaOIdxa8ZNaOIdKMg8Ua8UMMa80NaOId8KMMMh8UayaXaC2gYcdtfhHaDaLaC2gEcltfheaOIdyhUaChOinaHIdbg8Wa8WaUNaecxfIdba8XaecwfIdbNa80aeIdbNa8ZaeclfIdbNMMMg8Wa8WM:tNa8UMh8UaHclfhHaeczfheaOcufgOmbkdndna8LmbJbbbbh8Wxeka8KaXc8S2fgOIdwaaaLcx2fgeIdwg80NaOIdzaeIdbg8ZNaOIdaMg8Wa8WMMa80NaOIdlaeIdlgUNaOIdCa80NaOId3Mg8Wa8WMMaUNaOIdba8ZNaOIdxaUNaOIdKMg8Wa8WMMa8ZNaOId8KMMMh8WayaEcdtfhHaDaYcltfheaOIdyh8YaChOinaHIdbg8Xa8Xa8YNaecxfIdba80aecwfIdbNa8ZaeIdbNaUaeclfIdbNMMMg8Xa8XM:tNa8WMh8WaHclfhHaeczfheaOcufgOmbka8W:lh8WkaBa8U:lMhBa83a8WMh83dndndna5aLfRbbc9:fPddbekaKaQfydbgQaLSmbaAaXcdtfydbhEindndna8EaQcdtgYfydbgecuSmbaAaecdtfydbaESmekdna8FaYfydbgecuSmbaAaecdtfydbaESmekaXheka8KaQc8S2fgOIdwaaaecx2fgHIdwg8XNaOIdzaHIdbg80NaOIdaMg8Ua8UMMa8XNaOIdlaHIdlg8ZNaOIdCa8XNaOId3Mg8Ua8UMMa8ZNaOIdba80NaOIdxa8ZNaOIdKMg8Ua8UMMa80NaOId8KMMMh8UayaeaC2cdtfhHaDaQaC2cltfheaOIdyhUaChOinaHIdbg8Wa8WaUNaecxfIdba8XaecwfIdbNa80aeIdbNa8ZaeclfIdbNMMMg8Wa8WM:tNa8UMh8UaHclfhHaeczfheaOcufgOmbkaBa8U:lMhBaKaYfydbgQaL9hmbkka5aXfRbbci9hmea8LTmeaKaXcdtfydbgQaXSmeindndna8EaQcdtgYfydbgecuSmbaAaecdtfydbagSmekdna8FaYfydbgecuSmbaAaecdtfydbagSmekaLheka8KaQc8S2fgOIdwaaaecx2fgHIdwg8XNaOIdzaHIdbg80NaOIdaMg8Ua8UMMa8XNaOIdlaHIdlg8ZNaOIdCa8XNaOId3Mg8Ua8UMMa8ZNaOIdba80NaOIdxa8ZNaOIdKMg8Ua8UMMa80NaOId8KMMMh8UayaeaC2cdtfhHaDaQaC2cltfheaOIdyhUaChOinaHIdbg8Wa8WaUNaecxfIdba8XaecwfIdbNa80aeIdbNa8ZaeclfIdbNMMMg8Wa8WM:tNa8UMh8UaHclfhHaeczfheaOcufgOmbka83a8U:lMh83aKaYfydbgQaX9hmbxdkkdna8Fa8Ea8EaQfydbaXSEaKaQfydbgYcdtfydbgQcu9hmbaKaXcdtfydbhQka8KaYc8S2fgOIdwaaaQcx2fgeIdwg8XNaOIdzaeIdbg80NaOIdaMg8Ua8UMMa8XNaOIdlaeIdlg8ZNaOIdCa8XNaOId3Mg8Ua8UMMa8ZNaOIdba80NaOIdxa8ZNaOIdKMg8Ua8UMMa80NaOId8KMMMh8UayaQaC2ggcdtfhHaDaYaC2gEcltfheaOIdyhUaChOinaHIdbg8Wa8WaUNaecxfIdba8XaecwfIdbNa80aeIdbNa8ZaeclfIdbNMMMg8Wa8WM:tNa8UMh8UaHclfhHaeczfheaOcufgOmbkdndna8LmbJbbbbh8Wxeka8KaQc8S2fgOIdwaaaYcx2fgeIdwg80NaOIdzaeIdbg8ZNaOIdaMg8Wa8WMMa80NaOIdlaeIdlgUNaOIdCa80NaOId3Mg8Wa8WMMaUNaOIdba8ZNaOIdxaUNaOIdKMg8Wa8WMMa8ZNaOId8KMMMh8WayaEcdtfhHaDagcltfheaOIdyh8YaChOinaHIdbg8Xa8Xa8YNaecxfIdba80aecwfIdbNa8ZaeIdbNaUaeclfIdbNMMMg8Xa8XM:tNa8WMh8WaHclfhHaeczfheaOcufgOmbka8W:lh8WkaBa8U:lMhBa83a8WMh83kaha83aBa83aB9DgeEUdwahaLaXaea8Lcb9hGgeEBdlahaXaLaeEBdba8Jcefg8Ja8N9hmbkascjdfcbcj;qbz:tjjjb8Aa9thea8NhHinascjdfaeydbcA4cF8FGgOcFAaOcFA6EcdtfgOaOydbcefBdbaecxfheaHcufgHmbkcbhecbhHinascjdfaefgOydbhQaOaHBdbaQaHfhHaeclfgecj;qb9hmbkcbhea9thHinascjdfaHydbcA4cF8FGgOcFAaOcFA6EcdtfgOaOydbgOcefBdba9paOcdtfaeBdbaHcxfhHa8Naecefge9hmbkadak9RgOci9Uh9udnalTmbcbhea8PhHinaHaeBdbaHclfhHalaecefge9hmbkkcbh9va9qcbalz:tjjjbh9waOcO9Uh9xa9uce4h9ycbh3cbh8Adnina9oa9pa8Acdtfydbcx2fg8JIdwg8Ua889Emea3a9u9pmeJFFuuh8Wdna9ya8N9pmba9oa9pa9ycdtfydbcx2fIdwJbb;aZNh8Wkdna8Ua8W9ETmba8Ua869ETmba3a9x0mdkdna9waAa8Jydlg8Mcdtg9zfgEydbgQfg9ARbba9waAa8Jydbggcdtg9Bfydbgefg9CRbbVmba5agfRbbh9Ddna9maecdtfgHclfydbgOaHydbgHSmbaOaH9RhLaaaQcx2fhYaaaecx2fhha9raHcitfhecbhHceh8Ldnindna8PaeydbcdtfydbgOaQSmba8PaeclfydbcdtfydbgXaQSmbaOaXSmbaaaXcx2fgXIdbaaaOcx2fgOIdbg8X:tg8UahIdlaOIdlg80:tg8YNahIdba8X:tgBaXIdla80:tg8WN:tg8Za8UaYIdla80:tg83NaYIdba8X:tg8Va8WN:tg80Na8WahIdwaOIdwgU:tg81Na8YaXIdwaU:tg8XN:tg8Ya8WaYIdwaU:tg85Na83a8XN:tg8WNa8XaBNa81a8UN:tgUa8Xa8VNa85a8UN:tg8UNMMa8Za8ZNa8Ya8YNaUaUNMMa80a80Na8Wa8WNa8Ua8UNMMN:rJbbj8:N9FmdkaecwfheaHcefgHaL6h8LaLaH9hmbkka8LceGTmba9ycefh9yxekdndndndna9Dc9:fPdebdkagheinaEydbhOdndna8EaecdtgHfydbgecuSmbaAaecdtfydbaOSmekdna8FaHfydbgecuSmbaAaecdtfydbaOSmeka8Mheka8PaHfaeBdbaKaHfydbgeag9hmbxikkdna8Fa8Ea8Ea9Bfydba8MSEaKa9Bfydbggcdtfydbgecu9hmbaKa9zfydbheka8Pa9Bfa8MBdbaeh8Mka8Pagcdtfa8MBdbka9Cce86bba9Ace86bba8JIdwg8Ua86a86a8U9DEh86a9vcefh9vcecda9DceSEa3fh3ka8Acefg8Aa8N9hmbkka9vTmddnalTmbcbhXcbhhindna8PahcdtgefydbgOahSmbaAaOcdtfydbhgdnahaAaefydb9hgEmba8Sagc8S2fgea8Sahc8S2fgHIdbaeIdbMUdbaeaHIdlaeIdlMUdlaeaHIdwaeIdwMUdwaeaHIdxaeIdxMUdxaeaHIdzaeIdzMUdzaeaHIdCaeIdCMUdCaeaHIdKaeIdKMUdKaeaHId3aeId3MUd3aeaHIdaaeIdaMUdaaeaHId8KaeId8KMUd8KaeaHIdyaeIdyMUdyaITmbaIagcltfgeaIahcltfgHIdbaeIdbMUdbaeaHIdlaeIdlMUdlaeaHIdwaeIdwMUdwaeaHIdxaeIdxMUdxkaCTmba8KaOc8S2fgea8Kahc8S2g8LfgHIdbaeIdbMUdbaeaHIdlaeIdlMUdlaeaHIdwaeIdwMUdwaeaHIdxaeIdxMUdxaeaHIdzaeIdzMUdzaeaHIdCaeIdCMUdCaeaHIdKaeIdKMUdKaeaHId3aeId3MUd3aeaHIdaaeIdaMUdaaeaHId8KaeId8KMUd8KaeaHIdyaeIdyMUdya9saO2hYaDhHaChQinaHaYfgeaHaXfgOIdbaeIdbMUdbaeclfgLaOclfIdbaLIdbMUdbaecwfgLaOcwfIdbaLIdbMUdbaecxfgeaOcxfIdbaeIdbMUdbaHczfhHaQcufgQmbkaEmbJbbbbJbbjZa8Sa8LfgeIdyg8U:va8UJbbbb9BEaeIdwaaagcx2fgHIdwg8UNaeIdzaHIdbg8WNaeIdaMg8Xa8XMMa8UNaeIdlaHIdlg8XNaeIdCa8UNaeId3Mg8Ua8UMMa8XNaeIdba8WNaeIdxa8XNaeIdKMg8Ua8UMMa8WNaeId8KMMM:lNg8Ua87a87a8U9DEh87kaXa9sfhXahcefghal9hmbkcbhHa8EheindnaeydbgOcuSmbdnaHa8PaOcdtgQfydbgO9hmbcuhOa8EaQfydbgQcuSmba8PaQcdtfydbhOkaeaOBdbkaeclfhealaHcefgH9hmbkcbhHa8FheindnaeydbgOcuSmbdnaHa8PaOcdtgQfydbgO9hmbcuhOa8FaQfydbgQcuSmba8PaQcdtfydbhOkaeaOBdbkaeclfhealaHcefgH9hmbkka87a86aCEh87cbhHabhecbhOindnaAa8PaeydbcdtfydbgXcdtfydbgQaAa8PaeclfydbcdtfydbgYcdtfydbgLSmbaQaAa8PaecwfydbcdtfydbggcdtfydbghSmbaLahSmbabaHcdtfgQaXBdbaQcwfagBdbaQclfaYBdbaHcifhHkaecxfheaOcifgOad6mbkdndna9imbaHhdxekdnaHak0mbaHhdxekdnaRa879FmbaHhdxekJFFuuhRcbhdabhecbhOindna9ka0aeydbgQcdtfydbcdtfIdbg8Ua879ETmbaeclf8Pdbh9EabadcdtfgLaQBdbaLclfa9E83dba8UaRaRa8U9EEhRadcifhdkaecxfheaOcifgOaH6mbkkadak0mbxdkkascNefabadalaAz:cjjjbkdndnadak0mbadhhxekdna9imbadhhxekdnaRa889FmbadhhxekcehLinaRJbb;aZNg8Ua88a8Ua889DEh8XJbbbbh8Udna6Tmba9khea6hHinaeIdbg8Wa8Ua8Wa8X9FEa8Ua8Wa8U9EEh8UaeclfheaHcufgHmbkkJFFuuhRcbhhabhecbhHindna9ka0aeydbgOcdtfydbcdtfIdbg8Wa8X9ETmbaeclf8Pdbh9EabahcdtfgQaOBdbaQclfa9E83dba8WaRaRa8W9EEhRahcifhhkaecxfheaHcifgHad6mbkdnaLahad9hVceGmbadhhxdka8Ua86a86a8U9DEh86ahak9nmecbhLahhdaRa889FmbkkdnamcjjjjdGTmba9qcbalz:tjjjbh8LdnahTmbabheahhHina8LaeydbgOfce86bba8LaAaOcdtfydbfce86bbaeclfheaHcufgHmbkkascNefabahalaAz:cjjjbdndndnalTmbcbhQasyd:yehEindna8LaQfRbbTmbdna5aQfRbbgecl0mbceaetcQGmekdnaAaQcdtgXfydbgeaQSmbaaaQcx2fgHaaaecx2fge8Pdb83dbaHcwfaecwfydbBdbxeka8SaQc8S2fgLIdyg9ca9cJL:3;rUNg8UMh88aLIdwg9ha8UMhRaLIdlgxa8UMh8VaLIdbg9Fa8UMhUaLIdag9Ga8UaaaQcx2fggIdwg89N:th81aLId3g9Ha8UagIdlg8:N:th85aLIdKg9IagIdbgZa8UN:th8YJbbbbhcaLIdCg9JJbbbbMh87aLIdzg9KJbbbbMhBaLIdxgWJbbbbMh83dndnaCTmbaQhOinJbbbba88a8KaOc8S2fgHIdyg8U:va8UJbbbb9BEh8UaDaOaC2cltfheaHIdaa88Na81Mh81aHId3a88Na85Mh85aHIdKa88Na8YMh8YaHIdCa88Na87Mh87aHIdza88NaBMhBaHIdxa88Na83Mh83aHIdwa88NaRMhRaHIdla88Na8VMh8VaHIdba88NaUMhUaChHina81aecxfIdbg8ZaecwfIdbg8WNa8UN:th81a85a8ZaeclfIdbg8XNa8UN:th85a87a8Wa8XNa8UN:th87aUaeIdbg80a80Na8UN:thUa8Ya8Za80Na8UN:th8YaBa8Wa80Na8UN:thBa83a8Xa80Na8UN:th83aRa8Wa8WNa8UN:thRa8Va8Xa8XNa8UN:th8VaeczfheaHcufgHmbkaKaOcdtfydbgOaQ9hmbkaITmbaIaQcltfgeIdxhSaeIdwhJaeIdlh9eaeIdbh8UxekJbbbbhSJbbbbhJJbbbbh9eJbbbbh8UkaBaU:vg8Xa8YNa81:ta87aBa83aU:vg8WN:tg81a8Va83a8WN:tg8Z:vg80a8Wa8YNa85:tg8VN:th85aJa8Ua8XN:ta9ea8Ua8WN:tg83a80N:tg87aRaBa8XN:ta81a80N:tgB:vgR:mh81a83a8Z:vgJ:mh9ednJbbbba8Ua8UaU:vgTN:ta83aJN:ta87aRN:tg83:la88J:983:g81Ng8U9ETmba81a85Na9ea8VNaTa8YNaS:tMMa83:vhckaU:la8U9ETmba8Z:la8U9ETmbaB:la8U9ETmbaT:macNa8X:ma81acNa85aB:vMgBNa8W:ma9eacNa80:maBNa8Va8Z:vMMg87Na8Y:maU:vMMMh88a9maXfgeclfydbgHaeydbge9RhYaEaecitfhXJbbbbh8UdnaHaeSg8JmbJbbbbh8UaXheaYhOinaaaeclfydbcx2fgHIdwa89:tg8Wa8WNaHIdbaZ:tg8Wa8WNaHIdla8::tg8Wa8WNMMg8Waaaeydbcx2fgHIdwa89:tg8Xa8XNaHIdbaZ:tg8Xa8XNaHIdla8::tg8Xa8XNMMg8Xa8Ua8Ua8X9DEg8Ua8Ua8W9DEh8UaecwfheaOcufgOmbkkaBa89:tg8Wa8WNa88aZ:tg8Wa8WNa87a8::tg8Wa8WNMMa8U:rg8Ua8UN9EmbaLId8Khcdna8JmbcbhOcehLdninaaaXclfydbcx2fgeIdbaaaXydbcx2fgHIdbg8X:tg8Ua8:aHIdlg80:tg8YNaZa8X:tg83aeIdla80:tg8WN:tg8Za8Ua87a80:tgRNa88a8X:tg8Va8WN:tg80Na8Wa89aHIdwgU:tg81Na8YaeIdwaU:tg8XN:tg8Ya8WaBaU:tg85NaRa8XN:tg8WNa8Xa83Na81a8UN:tgUa8Xa8VNa85a8UN:tg8UNMMa8Za8ZNa8Ya8YNaUaUNMMa80a80Na8Wa8WNa8Ua8UNMMN:rJbbj8:N9FmeaXcwfhXaOcefgOaY6hLaYaO9hmbkkaLceGmekJbbbbJbbjZa9c:va9cJbbbb9BEg8Ua9haBNa9Ka88Na9GMg8Wa8WMMaBNaxa87Na9JaBNa9HMg8Wa8WMMa87Na9Fa88NaWa87Na9IMg8Wa8WMMa88NacMMM:lNa8Ua9ha89Na9KaZNa9GMg8Wa8WMMa89Naxa8:Na9Ja89Na9HMg8Wa8WMMa8:Na9FaZNaWa8:Na9IMg8Wa8WMMaZNacMMM:lNJbb;aZNJ:983:g81M9EmbagaBUdwaga87Udlaga88UdbkaQcefgQal9hmbkaCTmecbhLindna8LaLfRbbTmbaAaLcdtgefydbaL9hmba5aLfhEaaaLcx2fhOaKaefh8JayaLaC2cdtfh8AcbhgincuhQdnaERbbci9hmbaLhQa8JydbgeaLSmbayagcdtgHfhXa8AaHfIdbh8UaLhQinaQhHcuhQdnaXaeaC2cdtfIdba8U9CmbaHcuSmbaHhQa8Kaec8S2fIdya8KaHc8S2fIdy9ETmbaehQkaKaecdtfydbgeaL9hmbkkayagcdtfhXaDagcltfhYaLheinaXaeaC2cdtfJbbbbJbbjZa8KaeaQaQcuSEgHc8S2fIdyg8U:va8UJbbbb9BEaYaHaC2cltfgHIdwaOIdwNaHIdbaOIdbNaHIdlaOIdlNMMaHIdxMNUdbaKaecdtfydbgeaL9hmbkagcefggaC9hmbkkaLcefgLalSmixbkkaCmekcbhCkaiavaoarawaCalaaayazasa8Rasc1efa5a8Laqz:hjjjbkdnamcjjjjlGTmbazmbahTmbcbhQabheina5aeydbgAfRbbc3thLaecwfgKydbhHdndna8EaAcdtgYfydbaeclfgXydbgOSmbcbhCa8FaOcdtfydbaA9hmekcjjjj94hCkaeaLaCVaAVBdba5aOfRbbc3thLdndna8EaOcdtfydbaHSmbcbhCa8FaHcdtfydbaO9hmekcjjjj94hCkaXaLaCVaOVBdba5aHfRbbc3thCdndna8EaHcdtfydbaASmbcbhOa8FaYfydbaH9hmekcjjjj94hOkaKaCaOVaHVBdbaecxfheaQcifgQah6mbkkdnazTmbahTmbahheinabazabydbcdtfydbBdbabclfhbaecufgembkkdnaPTmbaPana86:rNUdbkasyd;8egecdtasc:Ceffc98fhHdninaeTmeaHydbcbyd:m:jjjbH:bjjjbbaHc98fhHaecufhexbkkascj;sbf8Kjjjjbahk;Yieouabydlhvabydbclfcbaicdtz:tjjjbhoadci9UhrdnadTmbdnalTmbaehwadhDinaoalawydbcdtfydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbxdkkaehwadhDinaoawydbcdtfgqaqydbcefBdbawclfhwaDcufgDmbkkdnaiTmbcbhDaohwinawydbhqawaDBdbawclfhwaqaDfhDaicufgimbkkdnadci6mbinaecwfydbhwaeclfydbhDaeydbhidnalTmbalawcdtfydbhwalaDcdtfydbhDalaicdtfydbhikavaoaicdtfgqydbcitfaDBdbavaqydbcitfawBdlaqaqydbcefBdbavaoaDcdtfgqydbcitfawBdbavaqydbcitfaiBdlaqaqydbcefBdbavaoawcdtfgwydbcitfaiBdbavawydbcitfaDBdlawawydbcefBdbaecxfhearcufgrmbkkabydbcbBdbk:todDue99aicd4aifhrcehwinawgDcethwaDar6mbkcuaDcdtgraDcFFFFi0Ecbyd1:jjjbHjjjjbbhwaoaoyd9GgqcefBd9GaoaqcdtfawBdbawcFearz:tjjjbhkdnaiTmbalcd4hlaDcufhxcbhminamhDdnavTmbavamcdtfydbhDkcbadaDal2cdtfgDydlgwawcjjjj94SEgwcH4aw7c:F:b:DD2cbaDydbgwawcjjjj94SEgwcH4aw7c;D;O:B8J27cbaDydwgDaDcjjjj94SEgDcH4aD7c:3F;N8N27axGhwamcdthPdndndnavTmbakawcdtfgrydbgDcuSmeadavaPfydbal2cdtfgsIdbhzcehqinaqhrdnadavaDcdtfydbal2cdtfgqIdbaz9CmbaqIdlasIdl9CmbaqIdwasIdw9BmlkarcefhqakawarfaxGgwcdtfgrydbgDcu9hmbxdkkakawcdtfgrydbgDcuSmbadamal2cdtfgsIdbhzcehqinaqhrdnadaDal2cdtfgqIdbaz9CmbaqIdlasIdl9CmbaqIdwasIdw9BmikarcefhqakawarfaxGgwcdtfgrydbgDcu9hmbkkaramBdbamhDkabaPfaDBdbamcefgmai9hmbkkakcbyd:m:jjjbH:bjjjbbaoaoyd9GcufBd9GdnaeTmbaiTmbcbhDaehwinawaDBdbawclfhwaiaDcefgD9hmbkcbhDaehwindnaDabydbgrSmbawaearcdtfgrydbBdbaraDBdbkawclfhwabclfhbaiaDcefgD9hmbkkk:hrdvuv998Jjjjjbca9Rgoczfcwfcbyd11jjbBdbaocb8Pdj1jjb83izaocwfcbydN1jjbBdbaocb8Pd:m1jjb83ibdnadTmbaicd4hrdnabmbdnalTmbcbhwinaealawcdtfydbar2cdtfhDcbhiinaoczfaifgqaDaifIdbgkaqIdbgxaxak9EEUdbaoaifgqakaqIdbgxaxak9DEUdbaiclfgicx9hmbkawcefgwad9hmbxikkarcdthwcbhDincbhiinaoczfaifgqaeaifIdbgkaqIdbgxaxak9EEUdbaoaifgqakaqIdbgxaxak9DEUdbaiclfgicx9hmbkaeawfheaDcefgDad9hmbxdkkdnalTmbcbhwinabawcx2fgiaealawcdtfydbar2cdtfgDIdbUdbaiaDIdlUdlaiaDIdwUdwcbhiinaoczfaifgqaDaifIdbgkaqIdbgxaxak9EEUdbaoaifgqakaqIdbgxaxak9DEUdbaiclfgicx9hmbkawcefgwad9hmbxdkkarcdthlcbhwaehDinabawcx2fgiaeawar2cdtfgqIdbUdbaiaqIdlUdlaiaqIdwUdwcbhiinaoczfaifgqaDaifIdbgkaqIdbgxaxak9EEUdbaoaifgqakaqIdbgxaxak9DEUdbaiclfgicx9hmbkaDalfhDawcefgwad9hmbkkJbbbbaoIdbaoIdzgx:tgkakJbbbb9DEgkaoIdlaoIdCgm:tgPaPak9DEgkaoIdwaoIdKgP:tgsasak9DEhsdnabTmbadTmbJbbbbJbbjZas:vasJbbbb9BEhkinabakabIdbax:tNUdbabclfgoakaoIdbam:tNUdbabcwfgoakaoIdbaP:tNUdbabcxfhbadcufgdmbkkdnavTmbavaPUdwavamUdlavaxUdbkask:ZlewudnaeTmbcbhvabhoinaoavBdbaoclfhoaeavcefgv9hmbkkdnaiTmbcbhrinadarcdtfhwcbhDinalawaDcdtgvc:G1jjbfydbcdtfydbcdtfydbhodnabalawavfydbcdtfydbgqcdtfgkydbgvaqSmbinakabavgqcdtfgxydbgvBdbaxhkaqav9hmbkkdnabaocdtfgkydbgvaoSmbinakabavgocdtfgxydbgvBdbaxhkaoav9hmbkkdnaqaoSmbabaqaoaqao0Ecdtfaqaoaqao6EBdbkaDcefgDci9hmbkarcifgrai6mbkkdnaembcbskcbhxindnalaxcdtgvfydbax9hmbaxhodnabavfgDydbgvaxSmbaDhqinaqabavgocdtfgkydbgvBdbakhqaoav9hmbkkaDaoBdbkaxcefgxae9hmbkcbhvabhocbhkindndnavalydbgq9hmbdnavaoydbgq9hmbaoakBdbakcefhkxdkaoabaqcdtfydbBdbxekaoabaqcdtfydbBdbkaoclfhoalclfhlaeavcefgv9hmbkakk;Jiilud99duabcbaecltz:tjjjbhvdnalTmbadhoaihralhwinarcwfIdbhDarclfIdbhqavaoydbcltfgkarIdbakIdbMUdbakclfgxaqaxIdbMUdbakcwfgxaDaxIdbMUdbakcxfgkakIdbJbbjZMUdbaoclfhoarcxfhrawcufgwmbkkdnaeTmbavhraehkinarcxfgoIdbhDaocbBdbararIdbJbbbbJbbjZaD:vaDJbbbb9BEgDNUdbarclfgoaDaoIdbNUdbarcwfgoaDaoIdbNUdbarczfhrakcufgkmbkkdnalTmbinavadydbcltfgrcxfgkaicwfIdbarcwfIdb:tgDaDNaiIdbarIdb:tgDaDNaiclfIdbarclfIdb:tgDaDNMMgDakIdbgqaqaD9DEUdbadclfhdaicxfhialcufglmbkkdnaeTmbavcxfhrinabarIdbUdbarczfhrabclfhbaecufgembkkk:moerudnaoTmbaecd4hzdnavTmbaicd4hHavcdthOcbhAindnaPaAfRbbTmbaAhednaDTmbaDaAcdtfydbhekdnasTmbasaefRbbceGmekdnamaAfRbbclSmbabaeaz2cdtfgiaraAcx2fgCIdbakNaxIdbMUdbaiaCIdlakNaxIdlMUdlaiaCIdwakNaxIdwMUdwkadaeaH2cdtfhXaqheawhiavhCinaXaeydbcdtgQfaiIdbalaQfIdb:vUdbaeclfheaiclfhiaCcufgCmbkkawaOfhwaAcefgAao9hmbxdkkdnasmbcbheaDhiindnaPaefRbbTmbaehCdnaDTmbaiydbhCkamaefRbbclSmbabaCaz2cdtfgCarIdbakNaxIdbMUdbaCarclfIdbakNaxIdlMUdlaCarcwfIdbakNaxIdwMUdwkaiclfhiarcxfhraoaecefge9hmbxdkkdnaDTmbindnaPRbbTmbasaDydbgefRbbceGmbamRbbclSmbabaeaz2cdtfgearIdbakNaxIdbMUdbaearclfIdbakNaxIdlMUdlaearcwfIdbakNaxIdwMUdwkaPcefhPaDclfhDamcefhmarcxfhraocufgombxdkkazcdthicbheindnaPaefRbbTmbasaefRbbceGmbamaefRbbclSmbabarIdbakNaxIdbMUdbabclfarclfIdbakNaxIdlMUdbabcwfarcwfIdbakNaxIdwMUdbkarcxfhrabaifhbaoaecefge9hmbkkk8MbabaeadaialavcbcbcbcbcbaoarawaDz:bjjjbk8MbabaeadaialavaoarawaDaqakaxamaPz:bjjjbkRbababaeadaialavaoarawaDaqakaxcjjjjdVamz:bjjjbk:d8Koque99due99duq998Jjjjjbc;Wb9Rgq8Kjjjjbcbhkaqcxfcbc;Kbz:tjjjb8Aaqcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgxBdxaqceBd2axaialavcbcbz:ejjjb8AaqcualcdtalcFFFFi0Egmcbyd1:jjjbHjjjjbbgiBdzaqcdBd2dndnJFF959eJbbjZawJbbjZawJbbjZ9DE:vawJ9VO:d869DEgw:lJbbb9p9DTmbaw:OhPxekcjjjj94hPkadci9Uhsarco9UhzdndnaombaPcd9imekdnalTmbaPcuf:YhwdnaoTmbcbhvaihHaxhOindndnaoavfRbbceGTmbavcjjjjlVhAxekdndnaOclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhAxekcjjjj94hAkaAcqthAdndnaOcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaAaXVhAdndnaOIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaAaXcCtVhAkaHaABdbaHclfhHaOcxfhOalavcefgv9hmbxdkkaxhvaihOalhHindndnavIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhAxekcjjjj94hAkaAcCthAdndnavclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaXcqtaAVhAdndnavcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaOaAaXVBdbavcxfhvaOclfhOaHcufgHmbkkadTmbcbhkaehvcbhOinakaiavclfydbcdtfydbgHaiavcwfydbcdtfydbgA9haiavydbcdtfydbgXaH9haXaA9hGGfhkavcxfhvaOcifgOad6mbkkarci9UhQdndnaz:Z:rJbbbZMgw:lJbbb9p9DTmbaw:Ohvxekcjjjj94hvkaQ:ZhLcbhKc:bwhzdninakaQ9pmeazaP9Rcd9imeavazcufavaz9iEaPcefavaP9kEhYdnalTmbaYcuf:YhwdnaoTmbcbhOaihHaxhvindndnaoaOfRbbceGTmbaOcjjjjlVhAxekdndnavclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhAxekcjjjj94hAkaAcqthAdndnavcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaAaXVhAdndnavIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaAaXcCtVhAkaHaABdbaHclfhHavcxfhvalaOcefgO9hmbxdkkaxhvaihOalhHindndnavIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhAxekcjjjj94hAkaAcCthAdndnavclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaXcqtaAVhAdndnavcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaOaAaXVBdbavcxfhvaOclfhOaHcufgHmbkkcbhOdnadTmbaehvcbhHinaOaiavclfydbcdtfydbgAaiavcwfydbcdtfydbgX9haiavydbcdtfydbgraA9haraX9hGGfhOavcxfhvaHcifgHad6mbkkJbbbbh8Adnas:ZgCaL:taY:Ygwaz:Y:tgENak:Zg3aO:Zg5:tNa3aL:tawaP:Y:tg8ENa5aC:tNMg8FJbbbb9BmbaCa3:ta8EaEa5aL:tNNNa8F:vh8AkdndnaOaQ0mbaOhkaYhPxekaOhsaYhzkdndnaKcl0mbdna8AawMJbbbZMgw:lJbbb9p9DTmbaw:Ohvxdkcjjjj94hvxekaPazfcd9ThvkaKcefgKcs9hmbkkdndndnakmbJbbjZhwcbhicdhvaDmexdkalcd4alfhHcehOinaOgvcethOavaH6mbkcbhOaqcuavcdtgYavcFFFFi0Ecbyd1:jjjbHjjjjbbgKBdCaqciBd2aqamcbyd1:jjjbHjjjjbbgzBdKaqclBd2dndndndnalTmbaPcuf:YhwaoTmecbhOaihAaxhHindndnaoaOfRbbceGTmbaOcjjjjlVhXxekdndnaHclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaXcqthXdndnaHcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:Ohrxekcjjjj94hrkaXarVhXdndnaHIdbawNJbbbZMgC:lJbbb9p9DTmbaC:Ohrxekcjjjj94hrkaXarcCtVhXkaAaXBdbaAclfhAaHcxfhHalaOcefgO9hmbxikkaKcFeaYz:tjjjb8AcbhPcbhvxdkaxhOaihHalhAindndnaOIdbawNJbbbZMgC:lJbbb9p9DTmbaC:OhXxekcjjjj94hXkaXcCthXdndnaOclfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:Ohrxekcjjjj94hrkarcqtaXVhXdndnaOcwfIdbawNJbbbZMgC:lJbbb9p9DTmbaC:Ohrxekcjjjj94hrkaHaXarVBdbaOcxfhOaHclfhHaAcufgAmbkkaKcFeaYz:tjjjbhravcufhocbhPcbhYindndndnaraiaYcdtgKfydbgAcm4aA7c:v;t;h;Ev2gvcs4av7aoGgHcdtfgXydbgOcuSmbcehvinaiaOcdtgOfydbaASmdaHavfhOavcefhvaraOaoGgHcdtfgXydbgOcu9hmbkkaXaYBdbaPhvaPcefhPxekazaOfydbhvkazaKfavBdbaYcefgYal9hmbkcuaPc8S2gOaPc;D;O;f8U0Ehvkcbhraqavcbyd1:jjjbHjjjjbbgvBd3aqcvBd2avcbaOz:tjjjbhOdnadTmbaehiinJbbnnJbbjZazaiydbgAcdtfydbgvazaiclfydbgHcdtfydbgYSavazaicwfydbgXcdtfydbgKSGgoEh8EdnaxaHcx2fgHIdbaxaAcx2fgAIdbg5:tgCaxaXcx2fgXIdlaAIdlg8A:tgwNaXIdba5:tg3aHIdla8A:tg8FN:tgLaLNa8FaXIdwaAIdwgE:tgaNawaHIdwaE:tg8FN:tgwawNa8Fa3NaaaCN:tgCaCNMM:rg3Jbbbb9ETmbaLa3:vhLaCa3:vhCawa3:vhwkaOavc8S2fgvavIdbawa8Ea3:rNg3awNNg8FMUdbavaCa3aCNgaNghavIdlMUdlavaLa3aLNg8ENggavIdwMUdwavaaawNgaavIdxMUdxava8EawNg8JavIdzMUdzava8EaCNg8EavIdCMUdCavawa3aLaENawa5Na8AaCNMM:mg8ANg5NgwavIdKMUdKavaCa5NgCavId3MUd3avaLa5NgLavIdaMUdaava5a8ANg5avId8KMUd8Kava3avIdyMUdydnaombaOaYc8S2fgva8FavIdbMUdbavahavIdlMUdlavagavIdwMUdwavaaavIdxMUdxava8JavIdzMUdzava8EavIdCMUdCavawavIdKMUdKavaCavId3MUd3avaLavIdaMUdaava5avId8KMUd8Kava3avIdyMUdyaOaKc8S2fgva8FavIdbMUdbavahavIdlMUdlavagavIdwMUdwavaaavIdxMUdxava8JavIdzMUdzava8EavIdCMUdCavawavIdKMUdKavaCavId3MUd3avaLavIdaMUdaava5avId8KMUd8Kava3avIdyMUdykaicxfhiarcifgrad6mbkkcbhAaqcuaPcdtgvaPcFFFFi0Egicbyd1:jjjbHjjjjbbgHBdaaqcoBd2aqaicbyd1:jjjbHjjjjbbgiBd8KaqcrBd2aHcFeavz:tjjjbhYdnalTmbazhHinJbbbbJbbjZaOaHydbgXc8S2fgvIdygw:vawJbbbb9BEavIdwaxcwfIdbgwNavIdzaxIdbgCNavIdaMgLaLMMawNavIdlaxclfIdbgLNavIdCawNavId3MgwawMMaLNavIdbaCNavIdxaLNavIdKMgwawMMaCNavId8KMMM:lNhwdndnaYaXcdtgvfgXydbcuSmbaiavfIdbaw9ETmekaXaABdbaiavfawUdbkaHclfhHaxcxfhxalaAcefgA9hmbkkJbbbbhwdnaPTmbinaiIdbgCawawaC9DEhwaiclfhiaPcufgPmbkkakcd4akfhOcehiinaigvcethiavaO6mbkcbhiaqcuavcdtgOavcFFFFi0Ecbyd1:jjjbHjjjjbbgHBdyaHcFeaOz:tjjjbhXdnadTmbavcufhrcbhPcbhxindnazaeaxcdtfgvydbcdtfydbgiazavclfydbcdtfydbgOSmbaiazavcwfydbcdtfydbgvSmbaOavSmbaYavcdtfydbhAdndnaYaOcdtfydbgvaYaicdtfydbgi9pmbavaA9pmbaAhlaihoavhAxekdnaAai9pmbaAav9pmbaihlavhoxekavhlaAhoaihAkabaPcx2fgvaABdbavcwfaoBdbavclfalBdbdnaXaoc:3F;N8N2alc:F:b:DD27aAc;D;O:B8J27arGgOcdtfgvydbgicuSmbcehHinaHhvdnabaicx2fgiydbaA9hmbaiydlal9hmbaiydwaoSmikavcefhHaXaOavfarGgOcdtfgvydbgicu9hmbkkavaPBdbaPcefhPkaxcifgxad6mbkaPci2hikdnaDmbcwhvxdkaw:rhwcwhvkaDawUdbkavcdthvdninavTmeavc98fgvaqcxffydbcbyd:m:jjjbH:bjjjbbxbkkaqc;Wbf8Kjjjjbaik:2ldwue9:8Jjjjjbc;Wb9Rgr8Kjjjjbcbhwarcxfcbc;Kbz:tjjjb8AdnabaeSmbabaeadcdtzMjjjb8AkarcualcdtalcFFFFi0EgDcbyd1:jjjbHjjjjbbgqBdxarceBd2aqcbaialavcbarcxfz:djjjbcualcx2alc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbhkarcxfaryd2gxcdtgmfakBdbaraxcefgPBd2akaialavcbcbz:ejjjb8AarcxfaPcdtfaDcbyd1:jjjbHjjjjbbgvBdbaraxcdfgiBd2arcxfaicdtfcuavalaeadaqz:fjjjbgecltaecjjjjiGEcbyd1:jjjbHjjjjbbgiBdbaiaeavakalz:gjjjbdnadTmbaoaoNhocbhwabhlcbhkindnaiavalydbgecdtfydbcdtfIdbao9ETmbalclf8PdbhsabawcdtfgqaeBdbaqclfas83dbawcifhwkalcxfhlakcifgkad6mbkkaxcifhlamarcxffcwfhkdninalTmeakydbcbyd:m:jjjbH:bjjjbbakc98fhkalcufhlxbkkarc;Wbf8Kjjjjbawk:XCoDud99vue99vuo998Jjjjjbc;Wb9Rgw8KjjjjbdndnarmbcbhDxekawcxfcbc;Kbz:tjjjb8Aawcuadcx2adc;v:Q;v:Qe0Ecbyd1:jjjbHjjjjbbgqBdxawceBd2aqaeadaicbcbz:ejjjb8AawcuadcdtadcFFFFi0Egkcbyd1:jjjbHjjjjbbgxBdzawcdBd2adcd4adfhmceheinaegicetheaiam6mbkcbhPawcuaicdtgsaicFFFFi0Ecbyd1:jjjbHjjjjbbgzBdCawciBd2dndnar:ZgH:rJbbbZMgO:lJbbb9p9DTmbaO:Ohexekcjjjj94hekaicufhAc:bwhDcbhCadhXcbhQinaeaDcufaeaD9iEaPcefaeaP9kEhLdndnadTmbaLcuf:YhOaqhiaxheadhmindndnaiIdbaONJbbbZMgK:lJbbb9p9DTmbaK:OhYxekcjjjj94hYkaYcCthYdndnaiclfIdbaONJbbbZMgK:lJbbb9p9DTmbaK:Oh8Axekcjjjj94h8Aka8AcqtaYVhYdndnaicwfIdbaONJbbbZMgK:lJbbb9p9DTmbaK:Oh8Axekcjjjj94h8AkaeaYa8AVBdbaicxfhiaeclfheamcufgmmbkazcFeasz:tjjjbhEcbh3cbh5indnaEaxa5cdtfydbgYcm4aY7c:v;t;h;Ev2gics4ai7aAGgmcdtfg8AydbgecuSmbaeaYSmbcehiinaEamaifaAGgmcdtfg8AydbgecuSmeaicefhiaeaY9hmbkka8AaYBdba3aecuSfh3a5cefg5ad9hmbxdkkazcFeasz:tjjjb8Acbh3kJbbbbh8EdnaX:ZgKaH:taL:YgOaD:Y:tg8FNaC:Zgaa3:Zgh:tNaaaH:taOaP:Y:tggNahaK:tNMg8JJbbbb9BmbaKaa:taga8FahaH:tNNNa8J:vh8EkaPaLa3ar0giEhPaCa3aiEhCdna3arSmbaLaDaiEgDaP9Rcd9imbdndnaQcl0mbdna8EaOMJbbbZMgO:lJbbb9p9DTmbaO:Ohexdkcjjjj94hexekaPaDfcd9Theka3aXaiEhXaQcefgQcs9hmekkdndnaCmbcihicbhDxekcbhiawakcbyd1:jjjbHjjjjbbg5BdKawclBd2aPcuf:YhKdndnadTmbaqhiaxheadhmindndnaiIdbaKNJbbbZMgO:lJbbb9p9DTmbaO:OhYxekcjjjj94hYkaYcCthYdndnaiclfIdbaKNJbbbZMgO:lJbbb9p9DTmbaO:Oh8Axekcjjjj94h8Aka8AcqtaYVhYdndnaicwfIdbaKNJbbbZMgO:lJbbb9p9DTmbaO:Oh8Axekcjjjj94h8AkaeaYa8AVBdbaicxfhiaeclfheamcufgmmbkazcFeasz:tjjjbhEcbhDcbh3indndndnaEaxa3cdtgLfydbgYcm4aY7c:v;t;h;Ev2gics4ai7aAGgmcdtfg8AydbgecuSmbcehiinaxaecdtgefydbaYSmdamaifheaicefhiaEaeaAGgmcdtfg8Aydbgecu9hmbkka8Aa3BdbaDhiaDcefhDxeka5aefydbhika5aLfaiBdba3cefg3ad9hmbkcuaDc32giaDc;j:KM;jb0EhexekazcFeasz:tjjjb8AcbhDcbhekawaecbyd1:jjjbHjjjjbbgeBd3awcvBd2aecbaiz:tjjjbh8Aavcd4hxdnadTmbdnalTmbaxcdthEa5hYaqhealhmadhAina8AaYydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiamIdbaiIdxMUdxaiamclfIdbaiIdzMUdzaiamcwfIdbaiIdCMUdCaiaiIdKJbbjZMUdKaYclfhYaecxfheamaEfhmaAcufgAmbxdkka5hmaqheadhYina8Aamydbc32fgiaeIdbaiIdbMUdbaiaeclfIdbaiIdlMUdlaiaecwfIdbaiIdwMUdwaiaiIdxJbbbbMUdxaiaiIdzJbbbbMUdzaiaiIdCJbbbbMUdCaiaiIdKJbbjZMUdKamclfhmaecxfheaYcufgYmbkkdnaDTmba8AhiaDheinaiaiIdbJbbbbJbbjZaicKfIdbgO:vaOJbbbb9BEgONUdbaiclfgmaOamIdbNUdbaicwfgmaOamIdbNUdbaicxfgmaOamIdbNUdbaiczfgmaOamIdbNUdbaicCfgmaOamIdbNUdbaic3fhiaecufgembkkcbhYawcuaDcdtgLaDcFFFFi0Egicbyd1:jjjbHjjjjbbgeBdaawcoBd2awaicbyd1:jjjbHjjjjbbgEBd8KaecFeaLz:tjjjbh3dnadTmbJbbjZJbbjZaK:vaPceSEaoNgOaONhKaxcdthxalheinaKaec;81jjbalEgmIdwa8Aa5ydbgAc32fgiIdC:tgOaONamIdbaiIdx:tgOaONamIdlaiIdz:tgOaONMMNaqcwfIdbaiIdw:tgOaONaqIdbaiIdb:tgOaONaqclfIdbaiIdl:tgOaONMMMhOdndna3aAcdtgifgmydbcuSmbaEaifIdbaO9ETmekamaYBdbaEaifaOUdbka5clfh5aqcxfhqaeaxfheadaYcefgY9hmbkkaba3aLzMjjjb8AcrhikaicdthiinaiTmeaic98fgiawcxffydbcbyd:m:jjjbH:bjjjbbxbkkawc;Wbf8KjjjjbaDk:Ydidui99ducbhi8Jjjjjbca9Rglczfcwfcbyd11jjbBdbalcb8Pdj1jjb83izalcwfcbydN1jjbBdbalcb8Pd:m1jjb83ibdndnaembJbbjFhvJbbjFhoJbbjFhrxekadcd4cdthwincbhdinalczfadfgDabadfIdbgvaDIdbgoaoav9EEUdbaladfgDavaDIdbgoaoav9DEUdbadclfgdcx9hmbkabawfhbaicefgiae9hmbkalIdwalIdK:thralIdlalIdC:thoalIdbalIdz:thvkJbbbbavavJbbbb9DEgvaoaoav9DEgvararav9DEk9DeeuabcFeaicdtz:tjjjbhlcbhbdnadTmbindnalaeydbcdtfgiydbcu9hmbaiabBdbabcefhbkaeclfheadcufgdmbkkabk;7idqui998Jjjjjbc;Wb9Rgl8Kjjjjbalcxfcbc;Kbz:tjjjb8Aadcd4adfhvcehoinaogrcethoarav6mbkalcuarcdtgoarcFFFFi0Ecbyd1:jjjbHjjjjbbgvBdxavcFeaoz:tjjjbhwdnadTmbaicd4hDarcufhqcbhkindndnawcbaeakaD2cdtfgrydlgiaicjjjj94SEgocH4ao7c:F:b:DD2cbarydbgxaxcjjjj94SEgocH4ao7c;D;O:B8J27cbarydwgmamcjjjj94SEgrcH4ar7c:3F;N8N27aqGgvcdtfgrydbgocuSmbam::hPai::hsax::hzcehiinaihrdnaeaoaD2cdtfgiIdbaz9CmbaiIdlas9CmbaiIdwaP9BmikarcefhiawavarfaqGgvcdtfgrydbgocu9hmbkkarakBdbakhokabakcdtfaoBdbakcefgkad9hmbkkcbhrdninarc98Smealcxfarfydbcbyd:m:jjjbH:bjjjbbarc98fhrxbkkalc;Wbf8Kjjjjbk9teiucbcbyd:q:jjjbgeabcifc98GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaik;teeeudndnaeabVciGTmbabhixekdndnadcz9pmbabhixekabhiinaiaeydbBdbaiaeydlBdlaiaeydwBdwaiaeydxBdxaeczfheaiczfhiadc9Wfgdcs0mbkkadcl6mbinaiaeydbBdbaeclfheaiclfhiadc98fgdci0mbkkdnadTmbinaiaeRbb86bbaicefhiaecefheadcufgdmbkkabk:3eedudndnabciGTmbabhixekaecFeGc:b:c:ew2hldndnadcz9pmbabhixekabhiinaialBdxaialBdwaialBdlaialBdbaiczfhiadc9Wfgdcs0mbkkadcl6mbinaialBdbaiclfhiadc98fgdci0mbkkdnadTmbinaiae86bbaicefhiadcufgdmbkkabk9teiucbcbyd:q:jjjbgeabcrfc94GfgbBd:q:jjjbdndnabZbcztgd9nmbcuhiabad9RcFFifcz4nbcuSmekaehikaikTeeucbabcbyd:q:jjjbge9Rcifc98GaefgbBd:q:jjjbdnabZbcztge9nmbabae9RcFFifcz4nb8Akkk:Iedbcjwk1eFFuuFFuuFFuuFFuFFFuFFFuFbbbbbbbbebbbdbbbbbbbebbbebbbdbbbbbbbbbbbeeeeebebbebbebebbbeebbbbbbbbbbbbeeeeeebebbeeebeebbbbebebbbbbbbbbbbbbbbbbbc1Dkxebbbdbbb:GNbb'; // embed! wasm
|
|
18496
|
+
|
|
18497
|
+
var wasmpack = new Uint8Array([
|
|
18498
|
+
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,
|
|
18499
|
+
24, 23, 146, 148, 18, 14, 22, 45, 70, 69, 56, 114, 101, 21, 25, 63, 75, 136, 108, 28, 118, 29, 73, 115,
|
|
18500
|
+
]);
|
|
18501
|
+
|
|
18502
|
+
if (typeof WebAssembly !== 'object') {
|
|
18503
|
+
return {
|
|
18504
|
+
supported: false,
|
|
18505
|
+
};
|
|
18506
|
+
}
|
|
18507
|
+
|
|
18508
|
+
var instance;
|
|
18509
|
+
|
|
18510
|
+
var ready = WebAssembly.instantiate(unpack(wasm), {}).then(function (result) {
|
|
18511
|
+
instance = result.instance;
|
|
18512
|
+
instance.exports.__wasm_call_ctors();
|
|
18513
|
+
});
|
|
18514
|
+
|
|
18515
|
+
function unpack(data) {
|
|
18516
|
+
var result = new Uint8Array(data.length);
|
|
18517
|
+
for (var i = 0; i < data.length; ++i) {
|
|
18518
|
+
var ch = data.charCodeAt(i);
|
|
18519
|
+
result[i] = ch > 96 ? ch - 97 : ch > 64 ? ch - 39 : ch + 4;
|
|
18520
|
+
}
|
|
18521
|
+
var write = 0;
|
|
18522
|
+
for (var i = 0; i < data.length; ++i) {
|
|
18523
|
+
result[write++] = result[i] < 60 ? wasmpack[result[i]] : (result[i] - 60) * 64 + result[++i];
|
|
18524
|
+
}
|
|
18525
|
+
return result.buffer.slice(0, write);
|
|
18526
|
+
}
|
|
18527
|
+
|
|
18528
|
+
function assert(cond) {
|
|
18529
|
+
if (!cond) {
|
|
18530
|
+
throw new Error('Assertion failed');
|
|
18531
|
+
}
|
|
18532
|
+
}
|
|
18533
|
+
|
|
18534
|
+
function bytes(view) {
|
|
18535
|
+
return new Uint8Array(view.buffer, view.byteOffset, view.byteLength);
|
|
18536
|
+
}
|
|
18537
|
+
|
|
18538
|
+
function genremap(fun, positions, vertices, stride) {
|
|
18539
|
+
var sbrk = instance.exports.sbrk;
|
|
18540
|
+
var rp = sbrk(vertices * 4);
|
|
18541
|
+
var sp = sbrk(vertices * stride * 4);
|
|
18542
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18543
|
+
heap.set(bytes(positions), sp);
|
|
18544
|
+
fun(rp, sp, vertices, stride * 4);
|
|
18545
|
+
// heap may have grown
|
|
18546
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18547
|
+
var remap = new Uint32Array(vertices);
|
|
18548
|
+
new Uint8Array(remap.buffer).set(heap.subarray(rp, rp + vertices * 4));
|
|
18549
|
+
sbrk(rp - sbrk(0));
|
|
18550
|
+
return remap;
|
|
18551
|
+
}
|
|
18552
|
+
|
|
18553
|
+
function reorder(fun, indices, vertices) {
|
|
18554
|
+
var sbrk = instance.exports.sbrk;
|
|
18555
|
+
var ip = sbrk(indices.length * 4);
|
|
18556
|
+
var rp = sbrk(vertices * 4);
|
|
18557
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18558
|
+
var indices8 = bytes(indices);
|
|
18559
|
+
heap.set(indices8, ip);
|
|
18560
|
+
var unique = fun(rp, ip, indices.length, vertices);
|
|
18561
|
+
// heap may have grown
|
|
18562
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18563
|
+
var remap = new Uint32Array(vertices);
|
|
18564
|
+
new Uint8Array(remap.buffer).set(heap.subarray(rp, rp + vertices * 4));
|
|
18565
|
+
indices8.set(heap.subarray(ip, ip + indices.length * 4));
|
|
18566
|
+
sbrk(ip - sbrk(0));
|
|
18567
|
+
|
|
18568
|
+
for (var i = 0; i < indices.length; ++i) indices[i] = remap[indices[i]];
|
|
18569
|
+
|
|
18570
|
+
return [remap, unique];
|
|
18571
|
+
}
|
|
18572
|
+
|
|
18573
|
+
function maxindex(source) {
|
|
18574
|
+
var result = 0;
|
|
18575
|
+
for (var i = 0; i < source.length; ++i) {
|
|
18576
|
+
var index = source[i];
|
|
18577
|
+
result = result < index ? index : result;
|
|
18578
|
+
}
|
|
18579
|
+
return result;
|
|
18580
|
+
}
|
|
18581
|
+
|
|
18582
|
+
function simplify(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_index_count, target_error, options) {
|
|
18583
|
+
var sbrk = instance.exports.sbrk;
|
|
18584
|
+
var te = sbrk(4);
|
|
18585
|
+
var ti = sbrk(index_count * 4);
|
|
18586
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18587
|
+
var si = sbrk(index_count * 4);
|
|
18588
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18589
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18590
|
+
heap.set(bytes(indices), si);
|
|
18591
|
+
var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, target_index_count, target_error, options, te);
|
|
18592
|
+
// heap may have grown
|
|
18593
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18594
|
+
var target = new Uint32Array(result);
|
|
18595
|
+
bytes(target).set(heap.subarray(ti, ti + result * 4));
|
|
18596
|
+
var error = new Float32Array(1);
|
|
18597
|
+
bytes(error).set(heap.subarray(te, te + 4));
|
|
18598
|
+
sbrk(te - sbrk(0));
|
|
18599
|
+
return [target, error[0]];
|
|
18600
|
+
}
|
|
18601
|
+
|
|
18602
|
+
function simplifyAttr(
|
|
18603
|
+
fun,
|
|
18604
|
+
indices,
|
|
18605
|
+
index_count,
|
|
18606
|
+
vertex_positions,
|
|
18607
|
+
vertex_count,
|
|
18608
|
+
vertex_positions_stride,
|
|
18609
|
+
vertex_attributes,
|
|
18610
|
+
vertex_attributes_stride,
|
|
18611
|
+
attribute_weights,
|
|
18612
|
+
vertex_lock,
|
|
18613
|
+
target_index_count,
|
|
18614
|
+
target_error,
|
|
18615
|
+
options
|
|
18616
|
+
) {
|
|
18617
|
+
var sbrk = instance.exports.sbrk;
|
|
18618
|
+
var te = sbrk(4);
|
|
18619
|
+
var ti = sbrk(index_count * 4);
|
|
18620
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18621
|
+
var sa = sbrk(vertex_count * vertex_attributes_stride);
|
|
18622
|
+
var sw = sbrk(attribute_weights.length * 4);
|
|
18623
|
+
var si = sbrk(index_count * 4);
|
|
18624
|
+
var vl = vertex_lock ? sbrk(vertex_count) : 0;
|
|
18625
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18626
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18627
|
+
heap.set(bytes(vertex_attributes), sa);
|
|
18628
|
+
heap.set(bytes(attribute_weights), sw);
|
|
18629
|
+
heap.set(bytes(indices), si);
|
|
18630
|
+
if (vertex_lock) {
|
|
18631
|
+
heap.set(bytes(vertex_lock), vl);
|
|
18632
|
+
}
|
|
18633
|
+
var result = fun(
|
|
18634
|
+
ti,
|
|
18635
|
+
si,
|
|
18636
|
+
index_count,
|
|
18637
|
+
sp,
|
|
18638
|
+
vertex_count,
|
|
18639
|
+
vertex_positions_stride,
|
|
18640
|
+
sa,
|
|
18641
|
+
vertex_attributes_stride,
|
|
18642
|
+
sw,
|
|
18643
|
+
attribute_weights.length,
|
|
18644
|
+
vl,
|
|
18645
|
+
target_index_count,
|
|
18646
|
+
target_error,
|
|
18647
|
+
options,
|
|
18648
|
+
te
|
|
18649
|
+
);
|
|
18650
|
+
// heap may have grown
|
|
18651
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18652
|
+
var target = new Uint32Array(result);
|
|
18653
|
+
bytes(target).set(heap.subarray(ti, ti + result * 4));
|
|
18654
|
+
var error = new Float32Array(1);
|
|
18655
|
+
bytes(error).set(heap.subarray(te, te + 4));
|
|
18656
|
+
sbrk(te - sbrk(0));
|
|
18657
|
+
return [target, error[0]];
|
|
18658
|
+
}
|
|
18659
|
+
|
|
18660
|
+
function simplifyUpdate(
|
|
18661
|
+
fun,
|
|
18662
|
+
indices,
|
|
18663
|
+
index_count,
|
|
18664
|
+
vertex_positions,
|
|
18665
|
+
vertex_count,
|
|
18666
|
+
vertex_positions_stride,
|
|
18667
|
+
vertex_attributes,
|
|
18668
|
+
vertex_attributes_stride,
|
|
18669
|
+
attribute_weights,
|
|
18670
|
+
vertex_lock,
|
|
18671
|
+
target_index_count,
|
|
18672
|
+
target_error,
|
|
18673
|
+
options
|
|
18674
|
+
) {
|
|
18675
|
+
var sbrk = instance.exports.sbrk;
|
|
18676
|
+
var te = sbrk(4);
|
|
18677
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18678
|
+
var sa = sbrk(vertex_count * vertex_attributes_stride);
|
|
18679
|
+
var sw = sbrk(attribute_weights.length * 4);
|
|
18680
|
+
var si = sbrk(index_count * 4);
|
|
18681
|
+
var vl = vertex_lock ? sbrk(vertex_count) : 0;
|
|
18682
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18683
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18684
|
+
heap.set(bytes(vertex_attributes), sa);
|
|
18685
|
+
heap.set(bytes(attribute_weights), sw);
|
|
18686
|
+
heap.set(bytes(indices), si);
|
|
18687
|
+
if (vertex_lock) {
|
|
18688
|
+
heap.set(bytes(vertex_lock), vl);
|
|
18689
|
+
}
|
|
18690
|
+
var result = fun(
|
|
18691
|
+
si,
|
|
18692
|
+
index_count,
|
|
18693
|
+
sp,
|
|
18694
|
+
vertex_count,
|
|
18695
|
+
vertex_positions_stride,
|
|
18696
|
+
sa,
|
|
18697
|
+
vertex_attributes_stride,
|
|
18698
|
+
sw,
|
|
18699
|
+
attribute_weights.length,
|
|
18700
|
+
vl,
|
|
18701
|
+
target_index_count,
|
|
18702
|
+
target_error,
|
|
18703
|
+
options,
|
|
18704
|
+
te
|
|
18705
|
+
);
|
|
18706
|
+
// heap may have grown
|
|
18707
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18708
|
+
bytes(indices).set(heap.subarray(si, si + result * 4));
|
|
18709
|
+
bytes(vertex_positions).set(heap.subarray(sp, sp + vertex_count * vertex_positions_stride));
|
|
18710
|
+
bytes(vertex_attributes).set(heap.subarray(sa, sa + vertex_count * vertex_attributes_stride));
|
|
18711
|
+
var error = new Float32Array(1);
|
|
18712
|
+
bytes(error).set(heap.subarray(te, te + 4));
|
|
18713
|
+
sbrk(te - sbrk(0));
|
|
18714
|
+
return [result, error[0]];
|
|
18715
|
+
}
|
|
18716
|
+
|
|
18717
|
+
function simplifyScale(fun, vertex_positions, vertex_count, vertex_positions_stride) {
|
|
18718
|
+
var sbrk = instance.exports.sbrk;
|
|
18719
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18720
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18721
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18722
|
+
var result = fun(sp, vertex_count, vertex_positions_stride);
|
|
18723
|
+
sbrk(sp - sbrk(0));
|
|
18724
|
+
return result;
|
|
18725
|
+
}
|
|
18726
|
+
|
|
18727
|
+
function simplifyPoints(
|
|
18728
|
+
fun,
|
|
18729
|
+
vertex_positions,
|
|
18730
|
+
vertex_count,
|
|
18731
|
+
vertex_positions_stride,
|
|
18732
|
+
vertex_colors,
|
|
18733
|
+
vertex_colors_stride,
|
|
18734
|
+
color_weight,
|
|
18735
|
+
target_vertex_count
|
|
18736
|
+
) {
|
|
18737
|
+
var sbrk = instance.exports.sbrk;
|
|
18738
|
+
var ti = sbrk(target_vertex_count * 4);
|
|
18739
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18740
|
+
var sc = sbrk(vertex_count * vertex_colors_stride);
|
|
18741
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18742
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18743
|
+
if (vertex_colors) {
|
|
18744
|
+
heap.set(bytes(vertex_colors), sc);
|
|
18745
|
+
}
|
|
18746
|
+
var result = fun(ti, sp, vertex_count, vertex_positions_stride, sc, vertex_colors_stride, color_weight, target_vertex_count);
|
|
18747
|
+
// heap may have grown
|
|
18748
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18749
|
+
var target = new Uint32Array(result);
|
|
18750
|
+
bytes(target).set(heap.subarray(ti, ti + result * 4));
|
|
18751
|
+
sbrk(ti - sbrk(0));
|
|
18752
|
+
return target;
|
|
18753
|
+
}
|
|
18754
|
+
|
|
18755
|
+
function simplifySloppy(
|
|
18756
|
+
fun,
|
|
18757
|
+
indices,
|
|
18758
|
+
index_count,
|
|
18759
|
+
vertex_positions,
|
|
18760
|
+
vertex_count,
|
|
18761
|
+
vertex_positions_stride,
|
|
18762
|
+
vertex_lock,
|
|
18763
|
+
target_index_count,
|
|
18764
|
+
target_error
|
|
18765
|
+
) {
|
|
18766
|
+
var sbrk = instance.exports.sbrk;
|
|
18767
|
+
var te = sbrk(4);
|
|
18768
|
+
var ti = sbrk(index_count * 4);
|
|
18769
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18770
|
+
var si = sbrk(index_count * 4);
|
|
18771
|
+
var vl = vertex_lock ? sbrk(vertex_count) : 0;
|
|
18772
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18773
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18774
|
+
heap.set(bytes(indices), si);
|
|
18775
|
+
if (vertex_lock) {
|
|
18776
|
+
heap.set(bytes(vertex_lock), vl);
|
|
18777
|
+
}
|
|
18778
|
+
var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, vl, target_index_count, target_error, te);
|
|
18779
|
+
// heap may have grown
|
|
18780
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18781
|
+
var target = new Uint32Array(result);
|
|
18782
|
+
bytes(target).set(heap.subarray(ti, ti + result * 4));
|
|
18783
|
+
var error = new Float32Array(1);
|
|
18784
|
+
bytes(error).set(heap.subarray(te, te + 4));
|
|
18785
|
+
sbrk(te - sbrk(0));
|
|
18786
|
+
return [target, error[0]];
|
|
18787
|
+
}
|
|
18788
|
+
|
|
18789
|
+
function simplifyPrune(fun, indices, index_count, vertex_positions, vertex_count, vertex_positions_stride, target_error) {
|
|
18790
|
+
var sbrk = instance.exports.sbrk;
|
|
18791
|
+
var ti = sbrk(index_count * 4);
|
|
18792
|
+
var sp = sbrk(vertex_count * vertex_positions_stride);
|
|
18793
|
+
var si = sbrk(index_count * 4);
|
|
18794
|
+
var heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18795
|
+
heap.set(bytes(vertex_positions), sp);
|
|
18796
|
+
heap.set(bytes(indices), si);
|
|
18797
|
+
var result = fun(ti, si, index_count, sp, vertex_count, vertex_positions_stride, target_error);
|
|
18798
|
+
// heap may have grown
|
|
18799
|
+
heap = new Uint8Array(instance.exports.memory.buffer);
|
|
18800
|
+
var target = new Uint32Array(result);
|
|
18801
|
+
bytes(target).set(heap.subarray(ti, ti + result * 4));
|
|
18802
|
+
sbrk(ti - sbrk(0));
|
|
18803
|
+
return target;
|
|
18804
|
+
}
|
|
18805
|
+
|
|
18806
|
+
var simplifyOptions = {
|
|
18807
|
+
LockBorder: 1,
|
|
18808
|
+
Sparse: 2,
|
|
18809
|
+
ErrorAbsolute: 4,
|
|
18810
|
+
Prune: 8,
|
|
18811
|
+
Regularize: 16,
|
|
18812
|
+
Permissive: 32,
|
|
18813
|
+
_InternalDebug: 1 << 30, // internal, don't use!
|
|
18814
|
+
};
|
|
18815
|
+
|
|
18816
|
+
return {
|
|
18817
|
+
ready: ready,
|
|
18818
|
+
supported: true,
|
|
18819
|
+
|
|
18820
|
+
compactMesh: function (indices) {
|
|
18821
|
+
assert(
|
|
18822
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
18823
|
+
);
|
|
18824
|
+
assert(indices.length % 3 == 0);
|
|
18825
|
+
|
|
18826
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
18827
|
+
return reorder(instance.exports.meshopt_optimizeVertexFetchRemap, indices32, maxindex(indices) + 1);
|
|
18828
|
+
},
|
|
18829
|
+
|
|
18830
|
+
generatePositionRemap: function (vertex_positions, vertex_positions_stride) {
|
|
18831
|
+
assert(vertex_positions instanceof Float32Array);
|
|
18832
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
18833
|
+
assert(vertex_positions_stride >= 3);
|
|
18834
|
+
|
|
18835
|
+
return genremap(
|
|
18836
|
+
instance.exports.meshopt_generatePositionRemap,
|
|
18837
|
+
vertex_positions,
|
|
18838
|
+
vertex_positions.length / vertex_positions_stride,
|
|
18839
|
+
vertex_positions_stride
|
|
18840
|
+
);
|
|
18841
|
+
},
|
|
18842
|
+
|
|
18843
|
+
simplify: function (indices, vertex_positions, vertex_positions_stride, target_index_count, target_error, flags) {
|
|
18844
|
+
assert(
|
|
18845
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
18846
|
+
);
|
|
18847
|
+
assert(indices.length % 3 == 0);
|
|
18848
|
+
assert(vertex_positions instanceof Float32Array);
|
|
18849
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
18850
|
+
assert(vertex_positions_stride >= 3);
|
|
18851
|
+
assert(target_index_count >= 0 && target_index_count <= indices.length);
|
|
18852
|
+
assert(target_index_count % 3 == 0);
|
|
18853
|
+
assert(target_error >= 0);
|
|
18854
|
+
|
|
18855
|
+
var options = 0;
|
|
18856
|
+
for (var i = 0; i < (flags ? flags.length : 0); ++i) {
|
|
18857
|
+
assert(flags[i] in simplifyOptions);
|
|
18858
|
+
options |= simplifyOptions[flags[i]];
|
|
18859
|
+
}
|
|
18860
|
+
|
|
18861
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
18862
|
+
var result = simplify(
|
|
18863
|
+
instance.exports.meshopt_simplify,
|
|
18864
|
+
indices32,
|
|
18865
|
+
indices.length,
|
|
18866
|
+
vertex_positions,
|
|
18867
|
+
vertex_positions.length / vertex_positions_stride,
|
|
18868
|
+
vertex_positions_stride * 4,
|
|
18869
|
+
target_index_count,
|
|
18870
|
+
target_error,
|
|
18871
|
+
options
|
|
18872
|
+
);
|
|
18873
|
+
result[0] = indices instanceof Uint32Array ? result[0] : new indices.constructor(result[0]);
|
|
18874
|
+
|
|
18875
|
+
return result;
|
|
18876
|
+
},
|
|
18877
|
+
|
|
18878
|
+
simplifyWithAttributes: function (
|
|
18879
|
+
indices,
|
|
18880
|
+
vertex_positions,
|
|
18881
|
+
vertex_positions_stride,
|
|
18882
|
+
vertex_attributes,
|
|
18883
|
+
vertex_attributes_stride,
|
|
18884
|
+
attribute_weights,
|
|
18885
|
+
vertex_lock,
|
|
18886
|
+
target_index_count,
|
|
18887
|
+
target_error,
|
|
18888
|
+
flags
|
|
18889
|
+
) {
|
|
18890
|
+
assert(
|
|
18891
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
18892
|
+
);
|
|
18893
|
+
assert(indices.length % 3 == 0);
|
|
18894
|
+
assert(vertex_positions instanceof Float32Array);
|
|
18895
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
18896
|
+
assert(vertex_positions_stride >= 3);
|
|
18897
|
+
assert(vertex_attributes instanceof Float32Array);
|
|
18898
|
+
assert(vertex_attributes.length == vertex_attributes_stride * (vertex_positions.length / vertex_positions_stride));
|
|
18899
|
+
assert(vertex_attributes_stride >= 0);
|
|
18900
|
+
assert(vertex_lock == null || vertex_lock instanceof Uint8Array);
|
|
18901
|
+
assert(vertex_lock == null || vertex_lock.length == vertex_positions.length / vertex_positions_stride);
|
|
18902
|
+
assert(target_index_count >= 0 && target_index_count <= indices.length);
|
|
18903
|
+
assert(target_index_count % 3 == 0);
|
|
18904
|
+
assert(target_error >= 0);
|
|
18905
|
+
assert(Array.isArray(attribute_weights));
|
|
18906
|
+
assert(vertex_attributes_stride >= attribute_weights.length);
|
|
18907
|
+
assert(attribute_weights.length <= 32);
|
|
18908
|
+
for (var i = 0; i < attribute_weights.length; ++i) {
|
|
18909
|
+
assert(attribute_weights[i] >= 0);
|
|
18910
|
+
}
|
|
18911
|
+
|
|
18912
|
+
var options = 0;
|
|
18913
|
+
for (var i = 0; i < (flags ? flags.length : 0); ++i) {
|
|
18914
|
+
assert(flags[i] in simplifyOptions);
|
|
18915
|
+
options |= simplifyOptions[flags[i]];
|
|
18916
|
+
}
|
|
18917
|
+
|
|
18918
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
18919
|
+
var result = simplifyAttr(
|
|
18920
|
+
instance.exports.meshopt_simplifyWithAttributes,
|
|
18921
|
+
indices32,
|
|
18922
|
+
indices.length,
|
|
18923
|
+
vertex_positions,
|
|
18924
|
+
vertex_positions.length / vertex_positions_stride,
|
|
18925
|
+
vertex_positions_stride * 4,
|
|
18926
|
+
vertex_attributes,
|
|
18927
|
+
vertex_attributes_stride * 4,
|
|
18928
|
+
new Float32Array(attribute_weights),
|
|
18929
|
+
vertex_lock,
|
|
18930
|
+
target_index_count,
|
|
18931
|
+
target_error,
|
|
18932
|
+
options
|
|
18933
|
+
);
|
|
18934
|
+
result[0] = indices instanceof Uint32Array ? result[0] : new indices.constructor(result[0]);
|
|
18935
|
+
|
|
18936
|
+
return result;
|
|
18937
|
+
},
|
|
18938
|
+
|
|
18939
|
+
simplifyWithUpdate: function (
|
|
18940
|
+
indices,
|
|
18941
|
+
vertex_positions,
|
|
18942
|
+
vertex_positions_stride,
|
|
18943
|
+
vertex_attributes,
|
|
18944
|
+
vertex_attributes_stride,
|
|
18945
|
+
attribute_weights,
|
|
18946
|
+
vertex_lock,
|
|
18947
|
+
target_index_count,
|
|
18948
|
+
target_error,
|
|
18949
|
+
flags
|
|
18950
|
+
) {
|
|
18951
|
+
assert(
|
|
18952
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
18953
|
+
);
|
|
18954
|
+
assert(indices.length % 3 == 0);
|
|
18955
|
+
assert(vertex_positions instanceof Float32Array);
|
|
18956
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
18957
|
+
assert(vertex_positions_stride >= 3);
|
|
18958
|
+
assert(vertex_attributes instanceof Float32Array);
|
|
18959
|
+
assert(vertex_attributes.length == vertex_attributes_stride * (vertex_positions.length / vertex_positions_stride));
|
|
18960
|
+
assert(vertex_attributes_stride >= 0);
|
|
18961
|
+
assert(vertex_lock == null || vertex_lock instanceof Uint8Array);
|
|
18962
|
+
assert(vertex_lock == null || vertex_lock.length == vertex_positions.length / vertex_positions_stride);
|
|
18963
|
+
assert(target_index_count >= 0 && target_index_count <= indices.length);
|
|
18964
|
+
assert(target_index_count % 3 == 0);
|
|
18965
|
+
assert(target_error >= 0);
|
|
18966
|
+
assert(Array.isArray(attribute_weights));
|
|
18967
|
+
assert(vertex_attributes_stride >= attribute_weights.length);
|
|
18968
|
+
assert(attribute_weights.length <= 32);
|
|
18969
|
+
for (var i = 0; i < attribute_weights.length; ++i) {
|
|
18970
|
+
assert(attribute_weights[i] >= 0);
|
|
18971
|
+
}
|
|
18972
|
+
|
|
18973
|
+
var options = 0;
|
|
18974
|
+
for (var i = 0; i < (flags ? flags.length : 0); ++i) {
|
|
18975
|
+
assert(flags[i] in simplifyOptions);
|
|
18976
|
+
options |= simplifyOptions[flags[i]];
|
|
18977
|
+
}
|
|
18978
|
+
|
|
18979
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
18980
|
+
var result = simplifyUpdate(
|
|
18981
|
+
instance.exports.meshopt_simplifyWithUpdate,
|
|
18982
|
+
indices32,
|
|
18983
|
+
indices.length,
|
|
18984
|
+
vertex_positions,
|
|
18985
|
+
vertex_positions.length / vertex_positions_stride,
|
|
18986
|
+
vertex_positions_stride * 4,
|
|
18987
|
+
vertex_attributes,
|
|
18988
|
+
vertex_attributes_stride * 4,
|
|
18989
|
+
new Float32Array(attribute_weights),
|
|
18990
|
+
vertex_lock,
|
|
18991
|
+
target_index_count,
|
|
18992
|
+
target_error,
|
|
18993
|
+
options
|
|
18994
|
+
);
|
|
18995
|
+
if (indices !== indices32) {
|
|
18996
|
+
// copy back indices if they were converted to Uint32Array
|
|
18997
|
+
for (var i = 0; i < result[0]; ++i) {
|
|
18998
|
+
indices[i] = indices32[i];
|
|
18999
|
+
}
|
|
19000
|
+
}
|
|
19001
|
+
return result;
|
|
19002
|
+
},
|
|
19003
|
+
|
|
19004
|
+
getScale: function (vertex_positions, vertex_positions_stride) {
|
|
19005
|
+
assert(vertex_positions instanceof Float32Array);
|
|
19006
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
19007
|
+
assert(vertex_positions_stride >= 3);
|
|
19008
|
+
return simplifyScale(
|
|
19009
|
+
instance.exports.meshopt_simplifyScale,
|
|
19010
|
+
vertex_positions,
|
|
19011
|
+
vertex_positions.length / vertex_positions_stride,
|
|
19012
|
+
vertex_positions_stride * 4
|
|
19013
|
+
);
|
|
19014
|
+
},
|
|
19015
|
+
|
|
19016
|
+
simplifyPoints: function (vertex_positions, vertex_positions_stride, target_vertex_count, vertex_colors, vertex_colors_stride, color_weight) {
|
|
19017
|
+
assert(vertex_positions instanceof Float32Array);
|
|
19018
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
19019
|
+
assert(vertex_positions_stride >= 3);
|
|
19020
|
+
assert(target_vertex_count >= 0 && target_vertex_count <= vertex_positions.length / vertex_positions_stride);
|
|
19021
|
+
if (vertex_colors) {
|
|
19022
|
+
assert(vertex_colors instanceof Float32Array);
|
|
19023
|
+
assert(vertex_colors.length % vertex_colors_stride == 0);
|
|
19024
|
+
assert(vertex_colors_stride >= 3);
|
|
19025
|
+
assert(vertex_positions.length / vertex_positions_stride == vertex_colors.length / vertex_colors_stride);
|
|
19026
|
+
return simplifyPoints(
|
|
19027
|
+
instance.exports.meshopt_simplifyPoints,
|
|
19028
|
+
vertex_positions,
|
|
19029
|
+
vertex_positions.length / vertex_positions_stride,
|
|
19030
|
+
vertex_positions_stride * 4,
|
|
19031
|
+
vertex_colors,
|
|
19032
|
+
vertex_colors_stride * 4,
|
|
19033
|
+
color_weight,
|
|
19034
|
+
target_vertex_count
|
|
19035
|
+
);
|
|
19036
|
+
} else {
|
|
19037
|
+
return simplifyPoints(
|
|
19038
|
+
instance.exports.meshopt_simplifyPoints,
|
|
19039
|
+
vertex_positions,
|
|
19040
|
+
vertex_positions.length / vertex_positions_stride,
|
|
19041
|
+
vertex_positions_stride * 4,
|
|
19042
|
+
undefined,
|
|
19043
|
+
0,
|
|
19044
|
+
0,
|
|
19045
|
+
target_vertex_count
|
|
19046
|
+
);
|
|
19047
|
+
}
|
|
19048
|
+
},
|
|
19049
|
+
|
|
19050
|
+
simplifySloppy: function (indices, vertex_positions, vertex_positions_stride, vertex_lock, target_index_count, target_error) {
|
|
19051
|
+
assert(
|
|
19052
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
19053
|
+
);
|
|
19054
|
+
assert(indices.length % 3 == 0);
|
|
19055
|
+
assert(vertex_positions instanceof Float32Array);
|
|
19056
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
19057
|
+
assert(vertex_positions_stride >= 3);
|
|
19058
|
+
assert(vertex_lock == null || vertex_lock instanceof Uint8Array);
|
|
19059
|
+
assert(vertex_lock == null || vertex_lock.length == vertex_positions.length / vertex_positions_stride);
|
|
19060
|
+
assert(target_index_count >= 0 && target_index_count <= indices.length);
|
|
19061
|
+
assert(target_index_count % 3 == 0);
|
|
19062
|
+
assert(target_error >= 0);
|
|
19063
|
+
|
|
19064
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
19065
|
+
var result = simplifySloppy(
|
|
19066
|
+
instance.exports.meshopt_simplifySloppy,
|
|
19067
|
+
indices32,
|
|
19068
|
+
indices.length,
|
|
19069
|
+
vertex_positions,
|
|
19070
|
+
vertex_positions.length / vertex_positions_stride,
|
|
19071
|
+
vertex_positions_stride * 4,
|
|
19072
|
+
vertex_lock,
|
|
19073
|
+
target_index_count,
|
|
19074
|
+
target_error
|
|
19075
|
+
);
|
|
19076
|
+
result[0] = indices instanceof Uint32Array ? result[0] : new indices.constructor(result[0]);
|
|
19077
|
+
|
|
19078
|
+
return result;
|
|
19079
|
+
},
|
|
19080
|
+
|
|
19081
|
+
simplifyPrune: function (indices, vertex_positions, vertex_positions_stride, target_error) {
|
|
19082
|
+
assert(
|
|
19083
|
+
indices instanceof Uint32Array || indices instanceof Int32Array || indices instanceof Uint16Array || indices instanceof Int16Array
|
|
19084
|
+
);
|
|
19085
|
+
assert(indices.length % 3 == 0);
|
|
19086
|
+
assert(vertex_positions instanceof Float32Array);
|
|
19087
|
+
assert(vertex_positions.length % vertex_positions_stride == 0);
|
|
19088
|
+
assert(vertex_positions_stride >= 3);
|
|
19089
|
+
assert(target_error >= 0);
|
|
19090
|
+
|
|
19091
|
+
var indices32 = indices.BYTES_PER_ELEMENT == 4 ? indices : new Uint32Array(indices);
|
|
19092
|
+
var result = simplifyPrune(
|
|
19093
|
+
instance.exports.meshopt_simplifyPrune,
|
|
19094
|
+
indices32,
|
|
19095
|
+
indices.length,
|
|
19096
|
+
vertex_positions,
|
|
19097
|
+
vertex_positions.length / vertex_positions_stride,
|
|
19098
|
+
vertex_positions_stride * 4,
|
|
19099
|
+
target_error
|
|
19100
|
+
);
|
|
19101
|
+
result = indices instanceof Uint32Array ? result : new indices.constructor(result);
|
|
19102
|
+
|
|
19103
|
+
return result;
|
|
19104
|
+
},
|
|
19105
|
+
};
|
|
19106
|
+
})();
|
|
19107
|
+
|
|
19108
|
+
/**
|
|
19109
|
+
* Build a minimal GLB (glTF 2.0 binary) file containing a single triangle mesh.
|
|
19110
|
+
*
|
|
19111
|
+
* The output contains only positions and triangle indices — no normals,
|
|
19112
|
+
* UVs, or materials — suitable for collision meshes.
|
|
19113
|
+
*
|
|
19114
|
+
* @param positions - Vertex positions (3 floats per vertex)
|
|
19115
|
+
* @param indices - Triangle indices (3 per triangle, unsigned 32-bit)
|
|
19116
|
+
* @returns GLB file as a Uint8Array
|
|
19117
|
+
*/
|
|
19118
|
+
function buildCollisionGlb(positions, indices) {
|
|
19119
|
+
const vertexCount = positions.length / 3;
|
|
19120
|
+
const indexCount = indices.length;
|
|
19121
|
+
let minX = Infinity, minY = Infinity, minZ = Infinity;
|
|
19122
|
+
let maxX = -Infinity, maxY = -Infinity, maxZ = -Infinity;
|
|
19123
|
+
for (let i = 0; i < positions.length; i += 3) {
|
|
19124
|
+
const x = positions[i], y = positions[i + 1], z = positions[i + 2];
|
|
19125
|
+
if (x < minX)
|
|
19126
|
+
minX = x;
|
|
19127
|
+
if (y < minY)
|
|
19128
|
+
minY = y;
|
|
19129
|
+
if (z < minZ)
|
|
19130
|
+
minZ = z;
|
|
19131
|
+
if (x > maxX)
|
|
19132
|
+
maxX = x;
|
|
19133
|
+
if (y > maxY)
|
|
19134
|
+
maxY = y;
|
|
19135
|
+
if (z > maxZ)
|
|
19136
|
+
maxZ = z;
|
|
19137
|
+
}
|
|
19138
|
+
const positionsByteLength = positions.byteLength;
|
|
19139
|
+
const indicesByteLength = indices.byteLength;
|
|
19140
|
+
const totalBinSize = positionsByteLength + indicesByteLength;
|
|
19141
|
+
const gltf = {
|
|
19142
|
+
asset: { version: '2.0', generator: 'splat-transform' },
|
|
19143
|
+
scene: 0,
|
|
19144
|
+
scenes: [{ nodes: [0] }],
|
|
19145
|
+
nodes: [{ mesh: 0 }],
|
|
19146
|
+
meshes: [{
|
|
19147
|
+
primitives: [{
|
|
19148
|
+
attributes: { POSITION: 0 },
|
|
19149
|
+
indices: 1
|
|
19150
|
+
}]
|
|
19151
|
+
}],
|
|
19152
|
+
accessors: [
|
|
19153
|
+
{
|
|
19154
|
+
bufferView: 0,
|
|
19155
|
+
componentType: 5126, // FLOAT
|
|
19156
|
+
count: vertexCount,
|
|
19157
|
+
type: 'VEC3',
|
|
19158
|
+
min: [minX, minY, minZ],
|
|
19159
|
+
max: [maxX, maxY, maxZ]
|
|
19160
|
+
},
|
|
19161
|
+
{
|
|
19162
|
+
bufferView: 1,
|
|
19163
|
+
componentType: 5125, // UNSIGNED_INT
|
|
19164
|
+
count: indexCount,
|
|
19165
|
+
type: 'SCALAR'
|
|
19166
|
+
}
|
|
19167
|
+
],
|
|
19168
|
+
bufferViews: [
|
|
19169
|
+
{
|
|
19170
|
+
buffer: 0,
|
|
19171
|
+
byteOffset: 0,
|
|
19172
|
+
byteLength: positionsByteLength,
|
|
19173
|
+
target: 34962 // ARRAY_BUFFER
|
|
19174
|
+
},
|
|
19175
|
+
{
|
|
19176
|
+
buffer: 0,
|
|
19177
|
+
byteOffset: positionsByteLength,
|
|
19178
|
+
byteLength: indicesByteLength,
|
|
19179
|
+
target: 34963 // ELEMENT_ARRAY_BUFFER
|
|
19180
|
+
}
|
|
19181
|
+
],
|
|
19182
|
+
buffers: [{ byteLength: totalBinSize }]
|
|
19183
|
+
};
|
|
19184
|
+
const jsonString = JSON.stringify(gltf);
|
|
19185
|
+
const jsonEncoder = new TextEncoder();
|
|
19186
|
+
const jsonBytes = jsonEncoder.encode(jsonString);
|
|
19187
|
+
// JSON chunk must be padded to 4-byte alignment with spaces (0x20)
|
|
19188
|
+
const jsonPadding = (4 - (jsonBytes.length % 4)) % 4;
|
|
19189
|
+
const jsonChunkLength = jsonBytes.length + jsonPadding;
|
|
19190
|
+
// BIN chunk must be padded to 4-byte alignment with zeros
|
|
19191
|
+
const binPadding = (4 - (totalBinSize % 4)) % 4;
|
|
19192
|
+
const binChunkLength = totalBinSize + binPadding;
|
|
19193
|
+
// GLB layout: header (12) + JSON chunk header (8) + JSON data + BIN chunk header (8) + BIN data
|
|
19194
|
+
const totalLength = 12 + 8 + jsonChunkLength + 8 + binChunkLength;
|
|
19195
|
+
const buffer = new ArrayBuffer(totalLength);
|
|
19196
|
+
const view = new DataView(buffer);
|
|
19197
|
+
const byteArray = new Uint8Array(buffer);
|
|
19198
|
+
let offset = 0;
|
|
19199
|
+
// GLB header
|
|
19200
|
+
view.setUint32(offset, 0x46546C67, true);
|
|
19201
|
+
offset += 4; // magic: "glTF"
|
|
19202
|
+
view.setUint32(offset, 2, true);
|
|
19203
|
+
offset += 4; // version: 2
|
|
19204
|
+
view.setUint32(offset, totalLength, true);
|
|
19205
|
+
offset += 4; // total length
|
|
19206
|
+
// JSON chunk header
|
|
19207
|
+
view.setUint32(offset, jsonChunkLength, true);
|
|
19208
|
+
offset += 4;
|
|
19209
|
+
view.setUint32(offset, 0x4E4F534A, true);
|
|
19210
|
+
offset += 4; // type: "JSON"
|
|
19211
|
+
// JSON chunk data
|
|
19212
|
+
byteArray.set(jsonBytes, offset);
|
|
19213
|
+
offset += jsonBytes.length;
|
|
19214
|
+
for (let i = 0; i < jsonPadding; i++) {
|
|
19215
|
+
byteArray[offset++] = 0x20;
|
|
19216
|
+
}
|
|
19217
|
+
// BIN chunk header
|
|
19218
|
+
view.setUint32(offset, binChunkLength, true);
|
|
19219
|
+
offset += 4;
|
|
19220
|
+
view.setUint32(offset, 0x004E4942, true);
|
|
19221
|
+
offset += 4; // type: "BIN\0"
|
|
19222
|
+
// BIN chunk data: positions then indices
|
|
19223
|
+
byteArray.set(new Uint8Array(positions.buffer, positions.byteOffset, positionsByteLength), offset);
|
|
19224
|
+
offset += positionsByteLength;
|
|
19225
|
+
byteArray.set(new Uint8Array(indices.buffer, indices.byteOffset, indicesByteLength), offset);
|
|
19226
|
+
return byteArray;
|
|
19227
|
+
}
|
|
19228
|
+
|
|
18489
19229
|
/**
|
|
18490
19230
|
* Compute axis-aligned bounding box half-extents for all Gaussians in a DataTable.
|
|
18491
19231
|
*
|
|
@@ -19351,6 +20091,525 @@ class GpuVoxelization {
|
|
|
19351
20091
|
}
|
|
19352
20092
|
}
|
|
19353
20093
|
|
|
20094
|
+
// ============================================================================
|
|
20095
|
+
// Voxel bit helpers
|
|
20096
|
+
// ============================================================================
|
|
20097
|
+
// Bit layout within a 4x4x4 block: bitIdx = lx + ly*4 + lz*16
|
|
20098
|
+
// lo = bits 0-31 (lz 0-1), hi = bits 32-63 (lz 2-3)
|
|
20099
|
+
/**
|
|
20100
|
+
* Test whether a voxel is occupied within a block's bitmask.
|
|
20101
|
+
*
|
|
20102
|
+
* @param lo - Lower 32 bits of the block mask
|
|
20103
|
+
* @param hi - Upper 32 bits of the block mask
|
|
20104
|
+
* @param lx - Local x coordinate (0-3)
|
|
20105
|
+
* @param ly - Local y coordinate (0-3)
|
|
20106
|
+
* @param lz - Local z coordinate (0-3)
|
|
20107
|
+
* @returns True if the voxel is occupied
|
|
20108
|
+
*/
|
|
20109
|
+
function isVoxelSet(lo, hi, lx, ly, lz) {
|
|
20110
|
+
const bitIdx = lx + ly * 4 + lz * 16;
|
|
20111
|
+
if (bitIdx < 32) {
|
|
20112
|
+
return (lo & (1 << bitIdx)) !== 0;
|
|
20113
|
+
}
|
|
20114
|
+
return (hi & (1 << (bitIdx - 32))) !== 0;
|
|
20115
|
+
}
|
|
20116
|
+
// ============================================================================
|
|
20117
|
+
// Occupancy grid from BlockAccumulator
|
|
20118
|
+
// ============================================================================
|
|
20119
|
+
/**
|
|
20120
|
+
* Build a fast-lookup occupancy structure from a BlockAccumulator.
|
|
20121
|
+
* Returns a function that queries whether a voxel at global coordinates
|
|
20122
|
+
* (vx, vy, vz) is occupied.
|
|
20123
|
+
*
|
|
20124
|
+
* @param accumulator - Block data
|
|
20125
|
+
* @returns Lookup function (vx, vy, vz) => boolean
|
|
20126
|
+
*/
|
|
20127
|
+
function buildOccupancyLookup(accumulator) {
|
|
20128
|
+
// Map from "bx,by,bz" encoded as single number to {lo,hi} or solid flag
|
|
20129
|
+
// Block key = bx + by * stride + bz * stride^2 where stride is large enough
|
|
20130
|
+
const mixed = accumulator.getMixedBlocks();
|
|
20131
|
+
const solid = accumulator.getSolidBlocks();
|
|
20132
|
+
// Use a Map<number, number> where value encodes index into mask arrays.
|
|
20133
|
+
// For solid blocks, store -1 as sentinel.
|
|
20134
|
+
const blockMap = new Map();
|
|
20135
|
+
for (let i = 0; i < mixed.morton.length; i++) {
|
|
20136
|
+
blockMap.set(mixed.morton[i], i);
|
|
20137
|
+
}
|
|
20138
|
+
for (let i = 0; i < solid.length; i++) {
|
|
20139
|
+
blockMap.set(solid[i], -1);
|
|
20140
|
+
}
|
|
20141
|
+
const masks = mixed.masks;
|
|
20142
|
+
return (vx, vy, vz) => {
|
|
20143
|
+
if (vx < 0 || vy < 0 || vz < 0)
|
|
20144
|
+
return false;
|
|
20145
|
+
const bx = vx >> 2;
|
|
20146
|
+
const by = vy >> 2;
|
|
20147
|
+
const bz = vz >> 2;
|
|
20148
|
+
const entry = blockMap.get(xyzToMorton(bx, by, bz));
|
|
20149
|
+
if (entry === undefined)
|
|
20150
|
+
return false;
|
|
20151
|
+
if (entry === -1)
|
|
20152
|
+
return true; // solid block
|
|
20153
|
+
const lo = masks[entry * 2];
|
|
20154
|
+
const hi = masks[entry * 2 + 1];
|
|
20155
|
+
return isVoxelSet(lo, hi, vx & 3, vy & 3, vz & 3);
|
|
20156
|
+
};
|
|
20157
|
+
}
|
|
20158
|
+
// ============================================================================
|
|
20159
|
+
// Marching Cubes
|
|
20160
|
+
// ============================================================================
|
|
20161
|
+
/**
|
|
20162
|
+
* Extract a triangle mesh from a BlockAccumulator using marching cubes.
|
|
20163
|
+
*
|
|
20164
|
+
* Each voxel is treated as a cell in the marching cubes grid. Corner values
|
|
20165
|
+
* are binary (0 = empty, 1 = occupied) with a 0.5 threshold. Vertices are
|
|
20166
|
+
* placed at edge midpoints, producing a mesh that follows voxel boundaries.
|
|
20167
|
+
*
|
|
20168
|
+
* @param accumulator - Voxel block data after filtering
|
|
20169
|
+
* @param gridBounds - Grid bounds aligned to block boundaries
|
|
20170
|
+
* @param voxelResolution - Size of each voxel in world units
|
|
20171
|
+
* @returns Mesh with positions and indices
|
|
20172
|
+
*/
|
|
20173
|
+
function marchingCubes(accumulator, gridBounds, voxelResolution) {
|
|
20174
|
+
const isOccupied = buildOccupancyLookup(accumulator);
|
|
20175
|
+
// Collect all voxel coordinates that need processing.
|
|
20176
|
+
// We need to check every cell where at least one corner differs from
|
|
20177
|
+
// the others, which means we need to check occupied voxels and their
|
|
20178
|
+
// immediate neighbors.
|
|
20179
|
+
const mixed = accumulator.getMixedBlocks();
|
|
20180
|
+
const solid = accumulator.getSolidBlocks();
|
|
20181
|
+
// Collect set of all block coordinates that exist
|
|
20182
|
+
const blockSet = new Set();
|
|
20183
|
+
for (let i = 0; i < mixed.morton.length; i++) {
|
|
20184
|
+
blockSet.add(mixed.morton[i]);
|
|
20185
|
+
}
|
|
20186
|
+
for (let i = 0; i < solid.length; i++) {
|
|
20187
|
+
blockSet.add(solid[i]);
|
|
20188
|
+
}
|
|
20189
|
+
// For each block, we process a 4x4x4 region of marching cubes cells.
|
|
20190
|
+
// Each cell at (vx, vy, vz) has corners at (vx..vx+1, vy..vy+1, vz..vz+1).
|
|
20191
|
+
// We only generate triangles for cells that have mixed corners (not all same).
|
|
20192
|
+
// Vertex deduplication: edge ID -> vertex index
|
|
20193
|
+
// Edge ID encodes the voxel coordinate and edge direction
|
|
20194
|
+
const vertexMap = new Map();
|
|
20195
|
+
const positions = [];
|
|
20196
|
+
const indices = [];
|
|
20197
|
+
const originX = gridBounds.min.x;
|
|
20198
|
+
const originY = gridBounds.min.y;
|
|
20199
|
+
const originZ = gridBounds.min.z;
|
|
20200
|
+
// Compute strides from actual grid dimensions (+3 for the -1 boundary
|
|
20201
|
+
// extension, the far edge +1, and one extra for safety).
|
|
20202
|
+
const strideX = Math.round((gridBounds.max.x - gridBounds.min.x) / voxelResolution) + 3;
|
|
20203
|
+
const strideXY = strideX * (Math.round((gridBounds.max.y - gridBounds.min.y) / voxelResolution) + 3);
|
|
20204
|
+
// Get or create a vertex at the midpoint of an edge.
|
|
20205
|
+
// Edge is identified by the lower corner voxel coordinate and axis (0=x, 1=y, 2=z).
|
|
20206
|
+
const getVertex = (vx, vy, vz, axis) => {
|
|
20207
|
+
// Pack (vx, vy, vz, axis) into a single key. Offset by 1 so that
|
|
20208
|
+
// vx = -1 (from the boundary extension) maps to 0, keeping keys non-negative.
|
|
20209
|
+
const key = ((vx + 1) + (vy + 1) * strideX + (vz + 1) * strideXY) * 3 + axis;
|
|
20210
|
+
let idx = vertexMap.get(key);
|
|
20211
|
+
if (idx !== undefined)
|
|
20212
|
+
return idx;
|
|
20213
|
+
idx = positions.length / 3;
|
|
20214
|
+
let px = originX + vx * voxelResolution;
|
|
20215
|
+
let py = originY + vy * voxelResolution;
|
|
20216
|
+
let pz = originZ + vz * voxelResolution;
|
|
20217
|
+
// Place vertex at edge midpoint (binary field -> always at 0.5)
|
|
20218
|
+
if (axis === 0)
|
|
20219
|
+
px += voxelResolution * 0.5;
|
|
20220
|
+
else if (axis === 1)
|
|
20221
|
+
py += voxelResolution * 0.5;
|
|
20222
|
+
else
|
|
20223
|
+
pz += voxelResolution * 0.5;
|
|
20224
|
+
positions.push(px, py, pz);
|
|
20225
|
+
vertexMap.set(key, idx);
|
|
20226
|
+
return idx;
|
|
20227
|
+
};
|
|
20228
|
+
// Process all blocks and their boundary neighbors
|
|
20229
|
+
const allMortons = [];
|
|
20230
|
+
blockSet.forEach(m => allMortons.push(m));
|
|
20231
|
+
for (let bi = 0; bi < allMortons.length; bi++) {
|
|
20232
|
+
const morton = allMortons[bi];
|
|
20233
|
+
const [bx, by, bz] = mortonToXYZ(morton);
|
|
20234
|
+
// Iterate -1..3 to include the boundary layer in the negative
|
|
20235
|
+
// direction. Cells at lx/ly/lz = -1 straddle the block edge and
|
|
20236
|
+
// are needed to close the surface where no neighboring block exists.
|
|
20237
|
+
for (let lz = -1; lz < 4; lz++) {
|
|
20238
|
+
for (let ly = -1; ly < 4; ly++) {
|
|
20239
|
+
for (let lx = -1; lx < 4; lx++) {
|
|
20240
|
+
const vx = bx * 4 + lx;
|
|
20241
|
+
const vy = by * 4 + ly;
|
|
20242
|
+
const vz = bz * 4 + lz;
|
|
20243
|
+
// Determine which block owns this cell
|
|
20244
|
+
const ownerBx = vx >> 2;
|
|
20245
|
+
const ownerBy = vy >> 2;
|
|
20246
|
+
const ownerBz = vz >> 2;
|
|
20247
|
+
if (ownerBx !== bx || ownerBy !== by || ownerBz !== bz) {
|
|
20248
|
+
// Cell belongs to a different block — skip if that
|
|
20249
|
+
// block exists (it will process the cell itself).
|
|
20250
|
+
// Guard negative coords: xyzToMorton assumes non-negative inputs.
|
|
20251
|
+
if (ownerBx >= 0 && ownerBy >= 0 && ownerBz >= 0 &&
|
|
20252
|
+
blockSet.has(xyzToMorton(ownerBx, ownerBy, ownerBz)))
|
|
20253
|
+
continue;
|
|
20254
|
+
}
|
|
20255
|
+
// Get corner values for this cell (8 corners)
|
|
20256
|
+
// Corners: (vx,vy,vz), (vx+1,vy,vz), (vx+1,vy+1,vz), (vx,vy+1,vz),
|
|
20257
|
+
// (vx,vy,vz+1), (vx+1,vy,vz+1), (vx+1,vy+1,vz+1), (vx,vy+1,vz+1)
|
|
20258
|
+
const c0 = isOccupied(vx, vy, vz) ? 1 : 0;
|
|
20259
|
+
const c1 = isOccupied(vx + 1, vy, vz) ? 1 : 0;
|
|
20260
|
+
const c2 = isOccupied(vx + 1, vy + 1, vz) ? 1 : 0;
|
|
20261
|
+
const c3 = isOccupied(vx, vy + 1, vz) ? 1 : 0;
|
|
20262
|
+
const c4 = isOccupied(vx, vy, vz + 1) ? 1 : 0;
|
|
20263
|
+
const c5 = isOccupied(vx + 1, vy, vz + 1) ? 1 : 0;
|
|
20264
|
+
const c6 = isOccupied(vx + 1, vy + 1, vz + 1) ? 1 : 0;
|
|
20265
|
+
const c7 = isOccupied(vx, vy + 1, vz + 1) ? 1 : 0;
|
|
20266
|
+
const cubeIndex = c0 | (c1 << 1) | (c2 << 2) | (c3 << 3) |
|
|
20267
|
+
(c4 << 4) | (c5 << 5) | (c6 << 6) | (c7 << 7);
|
|
20268
|
+
if (cubeIndex === 0 || cubeIndex === 255)
|
|
20269
|
+
continue;
|
|
20270
|
+
const edges = EDGE_TABLE[cubeIndex]; // eslint-disable-line no-use-before-define
|
|
20271
|
+
if (edges === 0)
|
|
20272
|
+
continue;
|
|
20273
|
+
// Compute vertices on active edges
|
|
20274
|
+
// Edge -> vertex mapping using getVertex with (corner voxel coord, axis)
|
|
20275
|
+
const edgeVerts = new Array(12);
|
|
20276
|
+
if (edges & 1)
|
|
20277
|
+
edgeVerts[0] = getVertex(vx, vy, vz, 0); // edge 0: x-axis at (vx, vy, vz)
|
|
20278
|
+
if (edges & 2)
|
|
20279
|
+
edgeVerts[1] = getVertex(vx + 1, vy, vz, 1); // edge 1: y-axis at (vx+1, vy, vz)
|
|
20280
|
+
if (edges & 4)
|
|
20281
|
+
edgeVerts[2] = getVertex(vx, vy + 1, vz, 0); // edge 2: x-axis at (vx, vy+1, vz)
|
|
20282
|
+
if (edges & 8)
|
|
20283
|
+
edgeVerts[3] = getVertex(vx, vy, vz, 1); // edge 3: y-axis at (vx, vy, vz)
|
|
20284
|
+
if (edges & 16)
|
|
20285
|
+
edgeVerts[4] = getVertex(vx, vy, vz + 1, 0); // edge 4: x-axis at (vx, vy, vz+1)
|
|
20286
|
+
if (edges & 32)
|
|
20287
|
+
edgeVerts[5] = getVertex(vx + 1, vy, vz + 1, 1); // edge 5: y-axis at (vx+1, vy, vz+1)
|
|
20288
|
+
if (edges & 64)
|
|
20289
|
+
edgeVerts[6] = getVertex(vx, vy + 1, vz + 1, 0); // edge 6: x-axis at (vx, vy+1, vz+1)
|
|
20290
|
+
if (edges & 128)
|
|
20291
|
+
edgeVerts[7] = getVertex(vx, vy, vz + 1, 1); // edge 7: y-axis at (vx, vy, vz+1)
|
|
20292
|
+
if (edges & 256)
|
|
20293
|
+
edgeVerts[8] = getVertex(vx, vy, vz, 2); // edge 8: z-axis at (vx, vy, vz)
|
|
20294
|
+
if (edges & 512)
|
|
20295
|
+
edgeVerts[9] = getVertex(vx + 1, vy, vz, 2); // edge 9: z-axis at (vx+1, vy, vz)
|
|
20296
|
+
if (edges & 1024)
|
|
20297
|
+
edgeVerts[10] = getVertex(vx + 1, vy + 1, vz, 2); // edge 10: z-axis at (vx+1, vy+1, vz)
|
|
20298
|
+
if (edges & 2048)
|
|
20299
|
+
edgeVerts[11] = getVertex(vx, vy + 1, vz, 2); // edge 11: z-axis at (vx, vy+1, vz)
|
|
20300
|
+
// Emit triangles (reversed winding to face outward)
|
|
20301
|
+
const triRow = TRI_TABLE[cubeIndex]; // eslint-disable-line no-use-before-define
|
|
20302
|
+
for (let t = 0; t < triRow.length; t += 3) {
|
|
20303
|
+
indices.push(edgeVerts[triRow[t]], edgeVerts[triRow[t + 2]], edgeVerts[triRow[t + 1]]);
|
|
20304
|
+
}
|
|
20305
|
+
}
|
|
20306
|
+
}
|
|
20307
|
+
}
|
|
20308
|
+
}
|
|
20309
|
+
return {
|
|
20310
|
+
positions: new Float32Array(positions),
|
|
20311
|
+
indices: new Uint32Array(indices)
|
|
20312
|
+
};
|
|
20313
|
+
}
|
|
20314
|
+
// ============================================================================
|
|
20315
|
+
// Marching Cubes Lookup Tables
|
|
20316
|
+
// ============================================================================
|
|
20317
|
+
// Standard tables from Paul Bourke's polygonising a scalar field.
|
|
20318
|
+
// EDGE_TABLE: 256 entries, each a 12-bit mask of which edges are intersected.
|
|
20319
|
+
// TRI_TABLE: 256 entries, each an array of edge indices forming triangles.
|
|
20320
|
+
const EDGE_TABLE = [
|
|
20321
|
+
0x000, 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
|
|
20322
|
+
0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
|
|
20323
|
+
0x190, 0x099, 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
|
|
20324
|
+
0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
|
|
20325
|
+
0x230, 0x339, 0x033, 0x13a, 0x636, 0x73f, 0x435, 0x53c,
|
|
20326
|
+
0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
|
|
20327
|
+
0x3a0, 0x2a9, 0x1a3, 0x0aa, 0x7a6, 0x6af, 0x5a5, 0x4ac,
|
|
20328
|
+
0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
|
|
20329
|
+
0x460, 0x569, 0x663, 0x76a, 0x066, 0x16f, 0x265, 0x36c,
|
|
20330
|
+
0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
|
|
20331
|
+
0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0x0ff, 0x3f5, 0x2fc,
|
|
20332
|
+
0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
|
|
20333
|
+
0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x055, 0x15c,
|
|
20334
|
+
0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
|
|
20335
|
+
0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0x0cc,
|
|
20336
|
+
0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
|
|
20337
|
+
0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
|
|
20338
|
+
0x0cc, 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
|
|
20339
|
+
0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
|
|
20340
|
+
0x15c, 0x055, 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
|
|
20341
|
+
0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
|
|
20342
|
+
0x2fc, 0x3f5, 0x0ff, 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
|
|
20343
|
+
0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
|
|
20344
|
+
0x36c, 0x265, 0x16f, 0x066, 0x76a, 0x663, 0x569, 0x460,
|
|
20345
|
+
0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
|
|
20346
|
+
0x4ac, 0x5a5, 0x6af, 0x7a6, 0x0aa, 0x1a3, 0x2a9, 0x3a0,
|
|
20347
|
+
0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
|
|
20348
|
+
0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x033, 0x339, 0x230,
|
|
20349
|
+
0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
|
|
20350
|
+
0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x099, 0x190,
|
|
20351
|
+
0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
|
|
20352
|
+
0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x000
|
|
20353
|
+
];
|
|
20354
|
+
const TRI_TABLE = [
|
|
20355
|
+
[],
|
|
20356
|
+
[0, 8, 3],
|
|
20357
|
+
[0, 1, 9],
|
|
20358
|
+
[1, 8, 3, 9, 8, 1],
|
|
20359
|
+
[1, 2, 10],
|
|
20360
|
+
[0, 8, 3, 1, 2, 10],
|
|
20361
|
+
[9, 2, 10, 0, 2, 9],
|
|
20362
|
+
[2, 8, 3, 2, 10, 8, 10, 9, 8],
|
|
20363
|
+
[3, 11, 2],
|
|
20364
|
+
[0, 11, 2, 8, 11, 0],
|
|
20365
|
+
[1, 9, 0, 2, 3, 11],
|
|
20366
|
+
[1, 11, 2, 1, 9, 11, 9, 8, 11],
|
|
20367
|
+
[3, 10, 1, 11, 10, 3],
|
|
20368
|
+
[0, 10, 1, 0, 8, 10, 8, 11, 10],
|
|
20369
|
+
[3, 9, 0, 3, 11, 9, 11, 10, 9],
|
|
20370
|
+
[9, 8, 10, 10, 8, 11],
|
|
20371
|
+
[4, 7, 8],
|
|
20372
|
+
[4, 3, 0, 7, 3, 4],
|
|
20373
|
+
[0, 1, 9, 8, 4, 7],
|
|
20374
|
+
[4, 1, 9, 4, 7, 1, 7, 3, 1],
|
|
20375
|
+
[1, 2, 10, 8, 4, 7],
|
|
20376
|
+
[3, 4, 7, 3, 0, 4, 1, 2, 10],
|
|
20377
|
+
[9, 2, 10, 9, 0, 2, 8, 4, 7],
|
|
20378
|
+
[2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4],
|
|
20379
|
+
[8, 4, 7, 3, 11, 2],
|
|
20380
|
+
[11, 4, 7, 11, 2, 4, 2, 0, 4],
|
|
20381
|
+
[9, 0, 1, 8, 4, 7, 2, 3, 11],
|
|
20382
|
+
[4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1],
|
|
20383
|
+
[3, 10, 1, 3, 11, 10, 7, 8, 4],
|
|
20384
|
+
[1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4],
|
|
20385
|
+
[4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3],
|
|
20386
|
+
[4, 7, 11, 4, 11, 9, 9, 11, 10],
|
|
20387
|
+
[9, 5, 4],
|
|
20388
|
+
[9, 5, 4, 0, 8, 3],
|
|
20389
|
+
[0, 5, 4, 1, 5, 0],
|
|
20390
|
+
[8, 5, 4, 8, 3, 5, 3, 1, 5],
|
|
20391
|
+
[1, 2, 10, 9, 5, 4],
|
|
20392
|
+
[3, 0, 8, 1, 2, 10, 4, 9, 5],
|
|
20393
|
+
[5, 2, 10, 5, 4, 2, 4, 0, 2],
|
|
20394
|
+
[2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8],
|
|
20395
|
+
[9, 5, 4, 2, 3, 11],
|
|
20396
|
+
[0, 11, 2, 0, 8, 11, 4, 9, 5],
|
|
20397
|
+
[0, 5, 4, 0, 1, 5, 2, 3, 11],
|
|
20398
|
+
[2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5],
|
|
20399
|
+
[10, 3, 11, 10, 1, 3, 9, 5, 4],
|
|
20400
|
+
[4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10],
|
|
20401
|
+
[5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3],
|
|
20402
|
+
[5, 4, 8, 5, 8, 10, 10, 8, 11],
|
|
20403
|
+
[9, 7, 8, 5, 7, 9],
|
|
20404
|
+
[9, 3, 0, 9, 5, 3, 5, 7, 3],
|
|
20405
|
+
[0, 7, 8, 0, 1, 7, 1, 5, 7],
|
|
20406
|
+
[1, 5, 3, 3, 5, 7],
|
|
20407
|
+
[9, 7, 8, 9, 5, 7, 10, 1, 2],
|
|
20408
|
+
[10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3],
|
|
20409
|
+
[8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2],
|
|
20410
|
+
[2, 10, 5, 2, 5, 3, 3, 5, 7],
|
|
20411
|
+
[7, 9, 5, 7, 8, 9, 3, 11, 2],
|
|
20412
|
+
[9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11],
|
|
20413
|
+
[2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7],
|
|
20414
|
+
[11, 2, 1, 11, 1, 7, 7, 1, 5],
|
|
20415
|
+
[9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11],
|
|
20416
|
+
[5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0],
|
|
20417
|
+
[11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0],
|
|
20418
|
+
[11, 10, 5, 7, 11, 5],
|
|
20419
|
+
[10, 6, 5],
|
|
20420
|
+
[0, 8, 3, 5, 10, 6],
|
|
20421
|
+
[9, 0, 1, 5, 10, 6],
|
|
20422
|
+
[1, 8, 3, 1, 9, 8, 5, 10, 6],
|
|
20423
|
+
[1, 6, 5, 2, 6, 1],
|
|
20424
|
+
[1, 6, 5, 1, 2, 6, 3, 0, 8],
|
|
20425
|
+
[9, 6, 5, 9, 0, 6, 0, 2, 6],
|
|
20426
|
+
[5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8],
|
|
20427
|
+
[2, 3, 11, 10, 6, 5],
|
|
20428
|
+
[11, 0, 8, 11, 2, 0, 10, 6, 5],
|
|
20429
|
+
[0, 1, 9, 2, 3, 11, 5, 10, 6],
|
|
20430
|
+
[5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11],
|
|
20431
|
+
[6, 3, 11, 6, 5, 3, 5, 1, 3],
|
|
20432
|
+
[0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6],
|
|
20433
|
+
[3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9],
|
|
20434
|
+
[6, 5, 9, 6, 9, 11, 11, 9, 8],
|
|
20435
|
+
[5, 10, 6, 4, 7, 8],
|
|
20436
|
+
[4, 3, 0, 4, 7, 3, 6, 5, 10],
|
|
20437
|
+
[1, 9, 0, 5, 10, 6, 8, 4, 7],
|
|
20438
|
+
[10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4],
|
|
20439
|
+
[6, 1, 2, 6, 5, 1, 4, 7, 8],
|
|
20440
|
+
[1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7],
|
|
20441
|
+
[8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6],
|
|
20442
|
+
[7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9],
|
|
20443
|
+
[3, 11, 2, 7, 8, 4, 10, 6, 5],
|
|
20444
|
+
[5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11],
|
|
20445
|
+
[0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6],
|
|
20446
|
+
[9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6],
|
|
20447
|
+
[8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6],
|
|
20448
|
+
[5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11],
|
|
20449
|
+
[0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7],
|
|
20450
|
+
[6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9],
|
|
20451
|
+
[10, 4, 9, 6, 4, 10],
|
|
20452
|
+
[4, 10, 6, 4, 9, 10, 0, 8, 3],
|
|
20453
|
+
[10, 0, 1, 10, 6, 0, 6, 4, 0],
|
|
20454
|
+
[8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10],
|
|
20455
|
+
[1, 4, 9, 1, 2, 4, 2, 6, 4],
|
|
20456
|
+
[3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4],
|
|
20457
|
+
[0, 2, 4, 4, 2, 6],
|
|
20458
|
+
[8, 3, 2, 8, 2, 4, 4, 2, 6],
|
|
20459
|
+
[10, 4, 9, 10, 6, 4, 11, 2, 3],
|
|
20460
|
+
[0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6],
|
|
20461
|
+
[3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10],
|
|
20462
|
+
[6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1],
|
|
20463
|
+
[9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3],
|
|
20464
|
+
[8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1],
|
|
20465
|
+
[3, 11, 6, 3, 6, 0, 0, 6, 4],
|
|
20466
|
+
[6, 4, 8, 11, 6, 8],
|
|
20467
|
+
[7, 10, 6, 7, 8, 10, 8, 9, 10],
|
|
20468
|
+
[0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10],
|
|
20469
|
+
[10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0],
|
|
20470
|
+
[10, 6, 7, 10, 7, 1, 1, 7, 3],
|
|
20471
|
+
[1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7],
|
|
20472
|
+
[2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9],
|
|
20473
|
+
[7, 8, 0, 7, 0, 6, 6, 0, 2],
|
|
20474
|
+
[7, 3, 2, 6, 7, 2],
|
|
20475
|
+
[2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7],
|
|
20476
|
+
[2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7],
|
|
20477
|
+
[1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11],
|
|
20478
|
+
[11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1],
|
|
20479
|
+
[8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6],
|
|
20480
|
+
[0, 9, 1, 11, 6, 7],
|
|
20481
|
+
[7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0],
|
|
20482
|
+
[7, 11, 6],
|
|
20483
|
+
[7, 6, 11],
|
|
20484
|
+
[3, 0, 8, 11, 7, 6],
|
|
20485
|
+
[0, 1, 9, 11, 7, 6],
|
|
20486
|
+
[8, 1, 9, 8, 3, 1, 11, 7, 6],
|
|
20487
|
+
[10, 1, 2, 6, 11, 7],
|
|
20488
|
+
[1, 2, 10, 3, 0, 8, 6, 11, 7],
|
|
20489
|
+
[2, 9, 0, 2, 10, 9, 6, 11, 7],
|
|
20490
|
+
[6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8],
|
|
20491
|
+
[7, 2, 3, 6, 2, 7],
|
|
20492
|
+
[7, 0, 8, 7, 6, 0, 6, 2, 0],
|
|
20493
|
+
[2, 7, 6, 2, 3, 7, 0, 1, 9],
|
|
20494
|
+
[1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6],
|
|
20495
|
+
[10, 7, 6, 10, 1, 7, 1, 3, 7],
|
|
20496
|
+
[10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8],
|
|
20497
|
+
[0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7],
|
|
20498
|
+
[7, 6, 10, 7, 10, 8, 8, 10, 9],
|
|
20499
|
+
[6, 8, 4, 11, 8, 6],
|
|
20500
|
+
[3, 6, 11, 3, 0, 6, 0, 4, 6],
|
|
20501
|
+
[8, 6, 11, 8, 4, 6, 9, 0, 1],
|
|
20502
|
+
[9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6],
|
|
20503
|
+
[6, 8, 4, 6, 11, 8, 2, 10, 1],
|
|
20504
|
+
[1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6],
|
|
20505
|
+
[4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9],
|
|
20506
|
+
[10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3],
|
|
20507
|
+
[8, 2, 3, 8, 4, 2, 4, 6, 2],
|
|
20508
|
+
[0, 4, 2, 4, 6, 2],
|
|
20509
|
+
[1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8],
|
|
20510
|
+
[1, 9, 4, 1, 4, 2, 2, 4, 6],
|
|
20511
|
+
[8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1],
|
|
20512
|
+
[10, 1, 0, 10, 0, 6, 6, 0, 4],
|
|
20513
|
+
[4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3],
|
|
20514
|
+
[10, 9, 4, 6, 10, 4],
|
|
20515
|
+
[4, 9, 5, 7, 6, 11],
|
|
20516
|
+
[0, 8, 3, 4, 9, 5, 11, 7, 6],
|
|
20517
|
+
[5, 0, 1, 5, 4, 0, 7, 6, 11],
|
|
20518
|
+
[11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5],
|
|
20519
|
+
[9, 5, 4, 10, 1, 2, 7, 6, 11],
|
|
20520
|
+
[6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5],
|
|
20521
|
+
[7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2],
|
|
20522
|
+
[3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6],
|
|
20523
|
+
[7, 2, 3, 7, 6, 2, 5, 4, 9],
|
|
20524
|
+
[9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7],
|
|
20525
|
+
[3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0],
|
|
20526
|
+
[6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8],
|
|
20527
|
+
[9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7],
|
|
20528
|
+
[1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4],
|
|
20529
|
+
[4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10],
|
|
20530
|
+
[7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10],
|
|
20531
|
+
[6, 9, 5, 6, 11, 9, 11, 8, 9],
|
|
20532
|
+
[3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5],
|
|
20533
|
+
[0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11],
|
|
20534
|
+
[6, 11, 3, 6, 3, 5, 5, 3, 1],
|
|
20535
|
+
[1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6],
|
|
20536
|
+
[0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10],
|
|
20537
|
+
[11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5],
|
|
20538
|
+
[6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3],
|
|
20539
|
+
[5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2],
|
|
20540
|
+
[9, 5, 6, 9, 6, 0, 0, 6, 2],
|
|
20541
|
+
[1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8],
|
|
20542
|
+
[1, 5, 6, 2, 1, 6],
|
|
20543
|
+
[1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6],
|
|
20544
|
+
[10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0],
|
|
20545
|
+
[0, 3, 8, 5, 6, 10],
|
|
20546
|
+
[10, 5, 6],
|
|
20547
|
+
[11, 5, 10, 7, 5, 11],
|
|
20548
|
+
[11, 5, 10, 11, 7, 5, 8, 3, 0],
|
|
20549
|
+
[5, 11, 7, 5, 10, 11, 1, 9, 0],
|
|
20550
|
+
[10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1],
|
|
20551
|
+
[11, 1, 2, 11, 7, 1, 7, 5, 1],
|
|
20552
|
+
[0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11],
|
|
20553
|
+
[9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7],
|
|
20554
|
+
[7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2],
|
|
20555
|
+
[2, 5, 10, 2, 3, 5, 3, 7, 5],
|
|
20556
|
+
[8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5],
|
|
20557
|
+
[9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2],
|
|
20558
|
+
[9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2],
|
|
20559
|
+
[1, 3, 5, 3, 7, 5],
|
|
20560
|
+
[0, 8, 7, 0, 7, 1, 1, 7, 5],
|
|
20561
|
+
[9, 0, 3, 9, 3, 5, 5, 3, 7],
|
|
20562
|
+
[9, 8, 7, 5, 9, 7],
|
|
20563
|
+
[5, 8, 4, 5, 10, 8, 10, 11, 8],
|
|
20564
|
+
[5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0],
|
|
20565
|
+
[0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5],
|
|
20566
|
+
[10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4],
|
|
20567
|
+
[2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8],
|
|
20568
|
+
[0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11],
|
|
20569
|
+
[0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5],
|
|
20570
|
+
[9, 4, 5, 2, 11, 3],
|
|
20571
|
+
[2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4],
|
|
20572
|
+
[5, 10, 2, 5, 2, 4, 4, 2, 0],
|
|
20573
|
+
[3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9],
|
|
20574
|
+
[5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2],
|
|
20575
|
+
[8, 4, 5, 8, 5, 3, 3, 5, 1],
|
|
20576
|
+
[0, 4, 5, 1, 0, 5],
|
|
20577
|
+
[8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5],
|
|
20578
|
+
[9, 4, 5],
|
|
20579
|
+
[4, 11, 7, 4, 9, 11, 9, 10, 11],
|
|
20580
|
+
[0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11],
|
|
20581
|
+
[1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11],
|
|
20582
|
+
[3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4],
|
|
20583
|
+
[4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2],
|
|
20584
|
+
[9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3],
|
|
20585
|
+
[11, 7, 4, 11, 4, 2, 2, 4, 0],
|
|
20586
|
+
[11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4],
|
|
20587
|
+
[2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9],
|
|
20588
|
+
[9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7],
|
|
20589
|
+
[3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10],
|
|
20590
|
+
[1, 10, 2, 8, 7, 4],
|
|
20591
|
+
[4, 9, 1, 4, 1, 7, 7, 1, 3],
|
|
20592
|
+
[4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1],
|
|
20593
|
+
[4, 0, 3, 7, 4, 3],
|
|
20594
|
+
[4, 8, 7],
|
|
20595
|
+
[9, 10, 8, 10, 11, 8],
|
|
20596
|
+
[3, 0, 9, 3, 9, 11, 11, 9, 10],
|
|
20597
|
+
[0, 1, 10, 0, 10, 8, 8, 10, 11],
|
|
20598
|
+
[3, 1, 10, 11, 3, 10],
|
|
20599
|
+
[1, 2, 11, 1, 11, 9, 9, 11, 8],
|
|
20600
|
+
[3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9],
|
|
20601
|
+
[0, 2, 11, 8, 0, 11],
|
|
20602
|
+
[3, 2, 11],
|
|
20603
|
+
[2, 3, 8, 2, 8, 10, 10, 8, 9],
|
|
20604
|
+
[9, 10, 2, 0, 9, 2],
|
|
20605
|
+
[2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8],
|
|
20606
|
+
[1, 10, 2],
|
|
20607
|
+
[1, 3, 8, 9, 1, 8],
|
|
20608
|
+
[0, 9, 1],
|
|
20609
|
+
[0, 3, 8],
|
|
20610
|
+
[]
|
|
20611
|
+
];
|
|
20612
|
+
|
|
19354
20613
|
// ============================================================================
|
|
19355
20614
|
// Edge mask constants for 4x4x4 voxel blocks
|
|
19356
20615
|
// ============================================================================
|
|
@@ -19620,9 +20879,10 @@ const writeOctreeFiles = async (fs, jsonFilename, octree) => {
|
|
|
19620
20879
|
* Voxelizes Gaussian splat data and writes the result as a sparse voxel octree.
|
|
19621
20880
|
*
|
|
19622
20881
|
* This function performs GPU-accelerated voxelization of Gaussian splat data
|
|
19623
|
-
* and outputs two files:
|
|
20882
|
+
* and outputs two or three files:
|
|
19624
20883
|
* - `filename` (.voxel.json) - JSON metadata including bounds, resolution, and array sizes
|
|
19625
20884
|
* - Corresponding .voxel.bin - Binary octree data (nodes + leafData as Uint32 arrays)
|
|
20885
|
+
* - Corresponding .collision.glb - Triangle mesh extracted via marching cubes (GLB format, optional)
|
|
19626
20886
|
*
|
|
19627
20887
|
* The binary file layout is:
|
|
19628
20888
|
* - Bytes 0 to (nodeCount * 4 - 1): nodes array (Uint32, little-endian)
|
|
@@ -19641,16 +20901,17 @@ const writeOctreeFiles = async (fs, jsonFilename, octree) => {
|
|
|
19641
20901
|
* dataTable: myDataTable,
|
|
19642
20902
|
* voxelResolution: 0.05,
|
|
19643
20903
|
* opacityCutoff: 0.5,
|
|
20904
|
+
* collisionMesh: true,
|
|
19644
20905
|
* createDevice: async () => myGraphicsDevice
|
|
19645
20906
|
* }, fs);
|
|
19646
20907
|
* ```
|
|
19647
20908
|
*/
|
|
19648
20909
|
const writeVoxel = async (options, fs) => {
|
|
19649
|
-
const { filename, dataTable, voxelResolution = 0.05, opacityCutoff = 0.5, createDevice } = options;
|
|
20910
|
+
const { filename, dataTable, voxelResolution = 0.05, opacityCutoff = 0.5, createDevice, collisionMesh = false, meshSimplify = 0.25 } = options;
|
|
19650
20911
|
if (!createDevice) {
|
|
19651
20912
|
throw new Error('writeVoxel requires a createDevice function for GPU voxelization');
|
|
19652
20913
|
}
|
|
19653
|
-
logger.progress.begin(
|
|
20914
|
+
logger.progress.begin(collisionMesh ? 7 : 5);
|
|
19654
20915
|
const extentsResult = computeGaussianExtents(dataTable);
|
|
19655
20916
|
const bounds = extentsResult.sceneBounds;
|
|
19656
20917
|
logger.progress.step('Building BVH');
|
|
@@ -19822,10 +21083,61 @@ const writeVoxel = async (options, fs) => {
|
|
|
19822
21083
|
gpuVoxelization.destroy();
|
|
19823
21084
|
logger.progress.step('Filtering');
|
|
19824
21085
|
accumulator = filterAndFillBlocks(accumulator);
|
|
21086
|
+
let glbBytes = null;
|
|
21087
|
+
if (collisionMesh) {
|
|
21088
|
+
logger.progress.step('Extracting collision mesh');
|
|
21089
|
+
const rawMesh = marchingCubes(accumulator, gridBounds, voxelResolution);
|
|
21090
|
+
logger.log(`collision mesh (raw): ${rawMesh.positions.length / 3} vertices, ${rawMesh.indices.length / 3} triangles`);
|
|
21091
|
+
if (rawMesh.indices.length < 3) {
|
|
21092
|
+
logger.progress.step('Simplifying collision mesh');
|
|
21093
|
+
logger.log('collision mesh: no triangles generated, skipping GLB output');
|
|
21094
|
+
}
|
|
21095
|
+
else {
|
|
21096
|
+
logger.progress.step('Simplifying collision mesh');
|
|
21097
|
+
await MeshoptSimplifier.ready;
|
|
21098
|
+
const clampedSimplify = Number.isFinite(meshSimplify) ? Math.min(1, Math.max(0, meshSimplify)) : 0.25;
|
|
21099
|
+
const targetIndexCount = Math.max(3, Math.min(rawMesh.indices.length, Math.floor(rawMesh.indices.length * clampedSimplify / 3) * 3));
|
|
21100
|
+
const [simplifiedIndices] = MeshoptSimplifier.simplify(rawMesh.indices, rawMesh.positions, 3, targetIndexCount, voxelResolution, ['ErrorAbsolute']);
|
|
21101
|
+
const vertexRemap = new Map();
|
|
21102
|
+
let newVertexCount = 0;
|
|
21103
|
+
for (let i = 0; i < simplifiedIndices.length; i++) {
|
|
21104
|
+
if (!vertexRemap.has(simplifiedIndices[i])) {
|
|
21105
|
+
vertexRemap.set(simplifiedIndices[i], newVertexCount++);
|
|
21106
|
+
}
|
|
21107
|
+
}
|
|
21108
|
+
const compactPositions = new Float32Array(newVertexCount * 3);
|
|
21109
|
+
for (const [oldIdx, newIdx] of vertexRemap) {
|
|
21110
|
+
compactPositions[newIdx * 3] = rawMesh.positions[oldIdx * 3];
|
|
21111
|
+
compactPositions[newIdx * 3 + 1] = rawMesh.positions[oldIdx * 3 + 1];
|
|
21112
|
+
compactPositions[newIdx * 3 + 2] = rawMesh.positions[oldIdx * 3 + 2];
|
|
21113
|
+
}
|
|
21114
|
+
const compactIndices = new Uint32Array(simplifiedIndices.length);
|
|
21115
|
+
for (let i = 0; i < simplifiedIndices.length; i++) {
|
|
21116
|
+
compactIndices[i] = vertexRemap.get(simplifiedIndices[i]);
|
|
21117
|
+
}
|
|
21118
|
+
const reduction = (1 - simplifiedIndices.length / rawMesh.indices.length) * 100;
|
|
21119
|
+
logger.log(`collision mesh (simplified): ${newVertexCount} vertices, ${simplifiedIndices.length / 3} triangles (${reduction.toFixed(0)}% reduction)`);
|
|
21120
|
+
glbBytes = buildCollisionGlb(compactPositions, compactIndices);
|
|
21121
|
+
}
|
|
21122
|
+
}
|
|
21123
|
+
logger.progress.step('Building octree');
|
|
19825
21124
|
const octree = buildSparseOctree(accumulator, gridBounds, bounds, // Original scene bounds
|
|
19826
21125
|
voxelResolution);
|
|
21126
|
+
logger.log(`octree: depth=${octree.treeDepth}, interior=${octree.numInteriorNodes}, mixed=${octree.numMixedLeaves}`);
|
|
19827
21127
|
logger.progress.step('Writing');
|
|
19828
21128
|
await writeOctreeFiles(fs, filename, octree);
|
|
21129
|
+
if (glbBytes) {
|
|
21130
|
+
const glbFilename = filename.replace('.voxel.json', '.collision.glb');
|
|
21131
|
+
logger.log(`writing '${glbFilename}'...`);
|
|
21132
|
+
await writeFile$1(fs, glbFilename, glbBytes);
|
|
21133
|
+
}
|
|
21134
|
+
const totalBytes = (octree.nodes.length + octree.leafData.length) * 4;
|
|
21135
|
+
if (glbBytes) {
|
|
21136
|
+
logger.log(`total size: octree ${(totalBytes / 1024).toFixed(1)} KB, collision mesh ${(glbBytes.length / 1024).toFixed(1)} KB`);
|
|
21137
|
+
}
|
|
21138
|
+
else {
|
|
21139
|
+
logger.log(`total size: ${(totalBytes / 1024).toFixed(1)} KB`);
|
|
21140
|
+
}
|
|
19829
21141
|
};
|
|
19830
21142
|
|
|
19831
21143
|
/**
|
|
@@ -19958,6 +21270,8 @@ const writeFile = async (writeOptions, fs) => {
|
|
|
19958
21270
|
dataTable,
|
|
19959
21271
|
voxelResolution: options.voxelResolution,
|
|
19960
21272
|
opacityCutoff: options.opacityCutoff,
|
|
21273
|
+
collisionMesh: options.collisionMesh,
|
|
21274
|
+
meshSimplify: options.meshSimplify,
|
|
19961
21275
|
createDevice
|
|
19962
21276
|
}, fs);
|
|
19963
21277
|
break;
|
|
@@ -20483,7 +21797,9 @@ const parseArguments = async () => {
|
|
|
20483
21797
|
'lod-chunk-extent': { type: 'string', short: 'X', default: '16' },
|
|
20484
21798
|
unbundled: { type: 'boolean', short: 'U', default: false },
|
|
20485
21799
|
'voxel-resolution': { type: 'string', short: 'R', default: '0.05' },
|
|
20486
|
-
'opacity-cutoff': { type: 'string', short: 'A', default: '0.
|
|
21800
|
+
'opacity-cutoff': { type: 'string', short: 'A', default: '0.1' },
|
|
21801
|
+
'collision-mesh': { type: 'boolean', short: 'K', default: false },
|
|
21802
|
+
'mesh-simplify': { type: 'string', short: 'T', default: '0.25' },
|
|
20487
21803
|
// per-file options
|
|
20488
21804
|
translate: { type: 'string', short: 't', multiple: true },
|
|
20489
21805
|
rotate: { type: 'string', short: 'r', multiple: true },
|
|
@@ -20570,8 +21886,13 @@ const parseArguments = async () => {
|
|
|
20570
21886
|
lodChunkCount: parseInteger(v['lod-chunk-count']),
|
|
20571
21887
|
lodChunkExtent: parseInteger(v['lod-chunk-extent']),
|
|
20572
21888
|
voxelResolution: parseNumber(v['voxel-resolution']),
|
|
20573
|
-
opacityCutoff: parseNumber(v['opacity-cutoff'])
|
|
21889
|
+
opacityCutoff: parseNumber(v['opacity-cutoff']),
|
|
21890
|
+
collisionMesh: v['collision-mesh'],
|
|
21891
|
+
meshSimplify: parseNumber(v['mesh-simplify'])
|
|
20574
21892
|
};
|
|
21893
|
+
if (!Number.isFinite(options.meshSimplify) || options.meshSimplify < 0 || options.meshSimplify > 1) {
|
|
21894
|
+
throw new Error(`Invalid mesh-simplify value: ${options.meshSimplify}. Must be a finite number between 0 and 1.`);
|
|
21895
|
+
}
|
|
20575
21896
|
for (const t of tokens) {
|
|
20576
21897
|
if (t.kind === 'positional') {
|
|
20577
21898
|
files.push({
|
|
@@ -20778,7 +22099,9 @@ GLOBAL OPTIONS
|
|
|
20778
22099
|
-C, --lod-chunk-count <n> Approximate number of Gaussians per LOD chunk in K. Default: 512
|
|
20779
22100
|
-X, --lod-chunk-extent <n> Approximate size of an LOD chunk in world units (m). Default: 16
|
|
20780
22101
|
-R, --voxel-resolution <n> Voxel size in world units for .voxel.json. Default: 0.05
|
|
20781
|
-
-A, --opacity-cutoff <n> Opacity threshold for solid voxels. Default: 0.
|
|
22102
|
+
-A, --opacity-cutoff <n> Opacity threshold for solid voxels. Default: 0.1
|
|
22103
|
+
-K, --collision-mesh Generate collision mesh (.collision.glb) with voxel output
|
|
22104
|
+
-T, --mesh-simplify <n> Ratio of triangles to keep for collision mesh (0-1). Default: 0.25
|
|
20782
22105
|
|
|
20783
22106
|
EXAMPLES
|
|
20784
22107
|
# Scale then translate
|
|
@@ -20796,9 +22119,12 @@ EXAMPLES
|
|
|
20796
22119
|
# Generate LOD with custom chunk size and node split size
|
|
20797
22120
|
splat-transform -O 0,1,2 -C 1024 -X 32 input.lcc output/lod-meta.json
|
|
20798
22121
|
|
|
20799
|
-
# Generate voxel
|
|
22122
|
+
# Generate voxel data
|
|
20800
22123
|
splat-transform input.ply output.voxel.json
|
|
20801
22124
|
|
|
22125
|
+
# Generate voxel data with collision mesh
|
|
22126
|
+
splat-transform -K input.ply output.voxel.json
|
|
22127
|
+
|
|
20802
22128
|
# Generate voxel data with custom resolution and opacity threshold
|
|
20803
22129
|
splat-transform -R 0.1 -A 0.3 input.ply output.voxel.json
|
|
20804
22130
|
|