x_ite-sog-parser 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -6
- package/dist/x_ite-sog-parser-2.js +378 -347
- package/package.json +3 -2
package/README.md
CHANGED
|
@@ -13,18 +13,16 @@ Include the script after X_ITE:
|
|
|
13
13
|
|
|
14
14
|
```html
|
|
15
15
|
<script defer src="https://cdn.jsdelivr.net/npm/x_ite@VERSION/dist/x_ite.min.js"></script>
|
|
16
|
-
<script defer src="https://cdn.jsdelivr.net/npm/x_ite-sog-parser@1.
|
|
16
|
+
<script defer src="https://cdn.jsdelivr.net/npm/x_ite-sog-parser@1.2.0/dist/x_ite-sog-parser-2.min.js"></script>
|
|
17
17
|
<!-- or as ES module -->
|
|
18
18
|
<script type="module" src="https://cdn.jsdelivr.net/npm/x_ite@VERSION/dist/x_ite.min.mjs"></script>
|
|
19
|
-
<script type="module" src="https://cdn.jsdelivr.net/npm/x_ite-sog-parser@1.
|
|
19
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/x_ite-sog-parser@1.2.0/dist/x_ite-sog-parser-2.min.js"></script>
|
|
20
20
|
```
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
You can also use `.sog` files as source of an Inline node.
|
|
22
|
+
You can now load `.sog` files directly using the `src` attribute, but you can also use `.sog` files as source of an Inline node.
|
|
25
23
|
|
|
26
24
|
```html
|
|
27
|
-
<x3d-canvas
|
|
25
|
+
<x3d-canvas src="room.sog"></x3d-canvas>
|
|
28
26
|
```
|
|
29
27
|
|
|
30
28
|
## NPM
|
|
@@ -2694,472 +2694,503 @@ function unzipSync(data, opts) {
|
|
|
2694
2694
|
return files;
|
|
2695
2695
|
}
|
|
2696
2696
|
|
|
2697
|
-
;// ./
|
|
2697
|
+
;// ./node_modules/x_ite-extension/dist/x_ite-extension.js
|
|
2698
|
+
/******/ // The require scope
|
|
2699
|
+
/******/ var __nested_webpack_require_43__ = {};
|
|
2700
|
+
/******/
|
|
2701
|
+
/************************************************************************/
|
|
2702
|
+
/******/ /* webpack/runtime/define property getters */
|
|
2703
|
+
/******/ (() => {
|
|
2704
|
+
/******/ // define getter functions for harmony exports
|
|
2705
|
+
/******/ __nested_webpack_require_43__.d = (exports, definition) => {
|
|
2706
|
+
/******/ for(var key in definition) {
|
|
2707
|
+
/******/ if(__nested_webpack_require_43__.o(definition, key) && !__nested_webpack_require_43__.o(exports, key)) {
|
|
2708
|
+
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
|
|
2709
|
+
/******/ }
|
|
2710
|
+
/******/ }
|
|
2711
|
+
/******/ };
|
|
2712
|
+
/******/ })();
|
|
2713
|
+
/******/
|
|
2714
|
+
/******/ /* webpack/runtime/hasOwnProperty shorthand */
|
|
2715
|
+
/******/ (() => {
|
|
2716
|
+
/******/ __nested_webpack_require_43__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))
|
|
2717
|
+
/******/ })();
|
|
2718
|
+
/******/
|
|
2719
|
+
/************************************************************************/
|
|
2720
|
+
var __nested_webpack_exports__ = {};
|
|
2721
|
+
/* harmony export */ __nested_webpack_require_43__.d(__nested_webpack_exports__, {
|
|
2722
|
+
/* harmony export */ A: () => (/* binding */ register)
|
|
2723
|
+
/* harmony export */ });
|
|
2724
|
+
function register (callback)
|
|
2725
|
+
{
|
|
2726
|
+
const X3D = window [Symbol .for ("X_ITE.X3D")];
|
|
2727
|
+
|
|
2728
|
+
if (X3D)
|
|
2729
|
+
callback (X3D);
|
|
2730
|
+
else
|
|
2731
|
+
(window [Symbol .for ("X_ITE.extensions")] ??= [ ]) .push (callback);
|
|
2732
|
+
};
|
|
2698
2733
|
|
|
2734
|
+
const __webpack_exports__default = __nested_webpack_exports__.A;
|
|
2699
2735
|
|
|
2700
|
-
const X3D = window [Symbol .for ("X_ITE.X3D")];
|
|
2701
2736
|
|
|
2702
|
-
|
|
2703
|
-
* Parser
|
|
2704
|
-
* Reference: https://github.com/playcanvas/splat-transform/blob/main/src/lib/readers/read-sog.ts
|
|
2705
|
-
*/
|
|
2737
|
+
;// ./src/x_ite-sog-parser-2.js
|
|
2706
2738
|
|
|
2707
|
-
|
|
2739
|
+
|
|
2740
|
+
|
|
2741
|
+
__webpack_exports__default (X3D =>
|
|
2708
2742
|
{
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2743
|
+
/*
|
|
2744
|
+
* Parser
|
|
2745
|
+
* Reference: https://github.com/playcanvas/splat-transform/blob/main/src/lib/readers/read-sog.ts
|
|
2746
|
+
*/
|
|
2713
2747
|
|
|
2714
|
-
|
|
2748
|
+
class SOGParser extends X3D .X3DParser
|
|
2715
2749
|
{
|
|
2716
|
-
|
|
2717
|
-
|
|
2750
|
+
constructor (scene)
|
|
2751
|
+
{
|
|
2752
|
+
super (scene);
|
|
2753
|
+
}
|
|
2718
2754
|
|
|
2719
|
-
|
|
2720
|
-
|
|
2721
|
-
|
|
2722
|
-
|
|
2755
|
+
getEncoding ()
|
|
2756
|
+
{
|
|
2757
|
+
return "ARRAY_BUFFER";
|
|
2758
|
+
}
|
|
2723
2759
|
|
|
2724
|
-
|
|
2725
|
-
|
|
2726
|
-
|
|
2727
|
-
|
|
2760
|
+
setInput (buffer)
|
|
2761
|
+
{
|
|
2762
|
+
this .buffer = buffer;
|
|
2763
|
+
}
|
|
2728
2764
|
|
|
2729
|
-
|
|
2765
|
+
isValid ()
|
|
2766
|
+
{
|
|
2767
|
+
if (this .buffer .byteLength < 4)
|
|
2768
|
+
return false;
|
|
2730
2769
|
|
|
2731
|
-
|
|
2770
|
+
// Check magic.
|
|
2732
2771
|
|
|
2733
|
-
|
|
2734
|
-
return false;
|
|
2772
|
+
const dataView = new DataView (this .buffer);
|
|
2735
2773
|
|
|
2736
|
-
|
|
2774
|
+
if (dataView .getUint32 (0, false) !== 0x504B0304)
|
|
2775
|
+
return false;
|
|
2737
2776
|
|
|
2738
|
-
|
|
2739
|
-
"means_l.webp",
|
|
2740
|
-
"means_u.webp",
|
|
2741
|
-
"scales.webp",
|
|
2742
|
-
"sh0.webp",
|
|
2743
|
-
"quats.webp",
|
|
2744
|
-
"meta.json",
|
|
2745
|
-
];
|
|
2777
|
+
// Check minimum requirement for Gaussian Splats.
|
|
2746
2778
|
|
|
2747
|
-
|
|
2779
|
+
const keys = [
|
|
2780
|
+
"means_l.webp",
|
|
2781
|
+
"means_u.webp",
|
|
2782
|
+
"scales.webp",
|
|
2783
|
+
"sh0.webp",
|
|
2784
|
+
"quats.webp",
|
|
2785
|
+
"meta.json",
|
|
2786
|
+
];
|
|
2748
2787
|
|
|
2749
|
-
|
|
2750
|
-
return false;
|
|
2788
|
+
this .files = unzipSync (new Uint8Array (this .buffer));
|
|
2751
2789
|
|
|
2752
|
-
|
|
2790
|
+
if (!keys .every (key => this .files [key]))
|
|
2791
|
+
return false;
|
|
2753
2792
|
|
|
2754
|
-
|
|
2793
|
+
// Check version.
|
|
2755
2794
|
|
|
2756
|
-
|
|
2757
|
-
return false;
|
|
2795
|
+
const meta = this .parseMeta ();
|
|
2758
2796
|
|
|
2759
|
-
|
|
2760
|
-
|
|
2797
|
+
if (meta .version < 2 || meta .version > 2)
|
|
2798
|
+
return false;
|
|
2761
2799
|
|
|
2762
|
-
|
|
2763
|
-
|
|
2764
|
-
this .sog ()
|
|
2765
|
-
.then (resolve)
|
|
2766
|
-
.catch (reject);
|
|
2767
|
-
}
|
|
2800
|
+
return true;
|
|
2801
|
+
}
|
|
2768
2802
|
|
|
2769
|
-
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2803
|
+
parseIntoScene (resolve, reject)
|
|
2804
|
+
{
|
|
2805
|
+
this .sog ()
|
|
2806
|
+
.then (resolve)
|
|
2807
|
+
.catch (reject);
|
|
2808
|
+
}
|
|
2774
2809
|
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2810
|
+
async sog ()
|
|
2811
|
+
{
|
|
2812
|
+
const
|
|
2813
|
+
browser = this .getBrowser (),
|
|
2814
|
+
scene = this .getScene ();
|
|
2778
2815
|
|
|
2779
|
-
|
|
2816
|
+
scene .setEncoding ("SOG");
|
|
2817
|
+
scene .setProfile (browser .getProfile ("Interchange"));
|
|
2818
|
+
scene .addComponent (browser .getComponent ("X_ITE"));
|
|
2780
2819
|
|
|
2781
|
-
|
|
2782
|
-
transform = scene .createNode ("Transform"),
|
|
2783
|
-
gaussianSplats = scene .createNode ("GaussianSplats"),
|
|
2784
|
-
gaussianCloud = await this .unpackFiles ();
|
|
2820
|
+
await this .getBrowser () .loadComponents (scene);
|
|
2785
2821
|
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2822
|
+
const
|
|
2823
|
+
transform = scene .createNode ("Transform"),
|
|
2824
|
+
gaussianSplats = scene .createNode ("GaussianSplats"),
|
|
2825
|
+
gaussianCloud = await this .unpackFiles ();
|
|
2790
2826
|
|
|
2791
|
-
|
|
2827
|
+
gaussianSplats .positions = gaussianCloud .positions;
|
|
2828
|
+
gaussianSplats .orientations = gaussianCloud .rotations;
|
|
2829
|
+
gaussianSplats .scales = gaussianCloud .scales;
|
|
2830
|
+
gaussianSplats .opacities = gaussianCloud .alphas;
|
|
2792
2831
|
|
|
2793
|
-
|
|
2832
|
+
gaussianSplats .sphericalHarmonicsDegree0Coef0 = gaussianCloud .colors;
|
|
2794
2833
|
|
|
2795
|
-
|
|
2796
|
-
{
|
|
2797
|
-
const {
|
|
2798
|
-
meta: { count, shN: { bands } },
|
|
2799
|
-
} = this .files;
|
|
2834
|
+
// Set spherical harmonics.
|
|
2800
2835
|
|
|
2801
|
-
|
|
2802
|
-
|
|
2803
|
-
|
|
2836
|
+
if (gaussianCloud .shs .length)
|
|
2837
|
+
{
|
|
2838
|
+
const {
|
|
2839
|
+
meta: { count, shN: { bands } },
|
|
2840
|
+
} = this .files;
|
|
2804
2841
|
|
|
2805
|
-
|
|
2806
|
-
|
|
2842
|
+
const
|
|
2843
|
+
shs = gaussianCloud .shs,
|
|
2844
|
+
shDegree = bands;
|
|
2807
2845
|
|
|
2808
|
-
|
|
2846
|
+
this .setSphericalHarmonics (count, shs, shDegree, gaussianSplats)
|
|
2847
|
+
}
|
|
2809
2848
|
|
|
2810
|
-
|
|
2849
|
+
// Add nodes to scene.
|
|
2811
2850
|
|
|
2812
|
-
|
|
2813
|
-
scene .rootNodes .push (transform);
|
|
2851
|
+
transform .rotation = new X3D .Rotation4 (1, 0, 0, Math .PI);
|
|
2814
2852
|
|
|
2815
|
-
|
|
2816
|
-
|
|
2853
|
+
transform .children .push (gaussianSplats);
|
|
2854
|
+
scene .rootNodes .push (transform);
|
|
2817
2855
|
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
const
|
|
2821
|
-
shCoeffs = this .dimForDegree (shDegree),
|
|
2822
|
-
shCoeffs3 = this .dimForDegree (shDegree) * 3,
|
|
2823
|
-
splatShs = Array .from ({ length: shCoeffs }, () => [ ]);
|
|
2856
|
+
return scene;
|
|
2857
|
+
}
|
|
2824
2858
|
|
|
2825
|
-
|
|
2859
|
+
setSphericalHarmonics (numSplats, shs, shDegree, gaussianSplats)
|
|
2826
2860
|
{
|
|
2827
2861
|
const
|
|
2828
|
-
|
|
2829
|
-
|
|
2862
|
+
shCoeffs = this .dimForDegree (shDegree),
|
|
2863
|
+
shCoeffs3 = this .dimForDegree (shDegree) * 3,
|
|
2864
|
+
splatShs = Array .from ({ length: shCoeffs }, () => [ ]);
|
|
2830
2865
|
|
|
2831
|
-
for (let
|
|
2866
|
+
for (let c = 0; c < shCoeffs; ++ c)
|
|
2832
2867
|
{
|
|
2833
|
-
const
|
|
2868
|
+
const
|
|
2869
|
+
c3 = c * 3,
|
|
2870
|
+
splatSh = splatShs [c];
|
|
2871
|
+
|
|
2872
|
+
for (let i = 0; i < numSplats; ++ i)
|
|
2873
|
+
{
|
|
2874
|
+
const offset = shCoeffs3 * i + c3;
|
|
2834
2875
|
|
|
2835
|
-
|
|
2836
|
-
|
|
2876
|
+
for (let j = 0; j < 3; ++ j)
|
|
2877
|
+
splatSh .push (shs [offset + j]);
|
|
2878
|
+
}
|
|
2837
2879
|
}
|
|
2838
|
-
}
|
|
2839
2880
|
|
|
2840
|
-
|
|
2841
|
-
|
|
2881
|
+
// GaussianSplats node only supports up to degree 3.
|
|
2882
|
+
const shDegreeMax = Math .min (shDegree, 3);
|
|
2842
2883
|
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2884
|
+
for (let d = 0, i = 0; d < shDegreeMax; ++ d)
|
|
2885
|
+
{
|
|
2886
|
+
const coefs = this .coefsForDegree (d);
|
|
2846
2887
|
|
|
2847
|
-
|
|
2848
|
-
|
|
2888
|
+
for (let c = 0; c < coefs; ++ c, ++ i)
|
|
2889
|
+
gaussianSplats [`sphericalHarmonicsDegree${d + 1}Coef${c}`] = splatShs [i];
|
|
2890
|
+
}
|
|
2849
2891
|
}
|
|
2850
|
-
}
|
|
2851
2892
|
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
}
|
|
2856
|
-
|
|
2857
|
-
async unpackFiles ()
|
|
2858
|
-
{
|
|
2859
|
-
await this .unpackImages ();
|
|
2860
|
-
|
|
2861
|
-
const
|
|
2862
|
-
positions = this .unpackPositions (),
|
|
2863
|
-
rotations = this .unpackRotations (),
|
|
2864
|
-
scales = this .unpackScales (),
|
|
2865
|
-
[alphas, colors] = this .unpackAlphasAndAColors (),
|
|
2866
|
-
shs = this .unpackSphericalHarmonics ();
|
|
2867
|
-
|
|
2868
|
-
return {
|
|
2869
|
-
positions,
|
|
2870
|
-
rotations,
|
|
2871
|
-
scales,
|
|
2872
|
-
alphas,
|
|
2873
|
-
colors,
|
|
2874
|
-
shs,
|
|
2893
|
+
parseMeta ()
|
|
2894
|
+
{
|
|
2895
|
+
return this .files .meta = JSON .parse (new TextDecoder () .decode (this .files ["meta.json"]));
|
|
2875
2896
|
}
|
|
2876
|
-
}
|
|
2877
|
-
|
|
2878
|
-
async unpackImages ()
|
|
2879
|
-
{
|
|
2880
|
-
return Promise .all (Object .keys (this .files)
|
|
2881
|
-
.filter (key => key .endsWith (".webp"))
|
|
2882
|
-
.map (key => this .unpackImage (key)));
|
|
2883
|
-
}
|
|
2884
2897
|
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
|
|
2888
|
-
bytes = this .files [key],
|
|
2889
|
-
blob = new Blob ([bytes], { type: "image/webp" }),
|
|
2890
|
-
url = URL .createObjectURL (blob),
|
|
2891
|
-
image = await this .loadImage (url),
|
|
2892
|
-
data = this .readPixels (image);
|
|
2893
|
-
|
|
2894
|
-
this .files [key] = image;
|
|
2895
|
-
this .files [key .replace (".webp", "")] = data;
|
|
2898
|
+
async unpackFiles ()
|
|
2899
|
+
{
|
|
2900
|
+
await this .unpackImages ();
|
|
2896
2901
|
|
|
2897
|
-
|
|
2898
|
-
|
|
2902
|
+
const
|
|
2903
|
+
positions = this .unpackPositions (),
|
|
2904
|
+
rotations = this .unpackRotations (),
|
|
2905
|
+
scales = this .unpackScales (),
|
|
2906
|
+
[alphas, colors] = this .unpackAlphasAndAColors (),
|
|
2907
|
+
shs = this .unpackSphericalHarmonics ();
|
|
2908
|
+
|
|
2909
|
+
return {
|
|
2910
|
+
positions,
|
|
2911
|
+
rotations,
|
|
2912
|
+
scales,
|
|
2913
|
+
alphas,
|
|
2914
|
+
colors,
|
|
2915
|
+
shs,
|
|
2916
|
+
}
|
|
2917
|
+
}
|
|
2899
2918
|
|
|
2900
|
-
|
|
2901
|
-
{
|
|
2902
|
-
return new Promise ((resolve, reject) =>
|
|
2919
|
+
async unpackImages ()
|
|
2903
2920
|
{
|
|
2904
|
-
|
|
2921
|
+
return Promise .all (Object .keys (this .files)
|
|
2922
|
+
.filter (key => key .endsWith (".webp"))
|
|
2923
|
+
.map (key => this .unpackImage (key)));
|
|
2924
|
+
}
|
|
2905
2925
|
|
|
2906
|
-
|
|
2926
|
+
async unpackImage (key)
|
|
2927
|
+
{
|
|
2928
|
+
const
|
|
2929
|
+
bytes = this .files [key],
|
|
2930
|
+
blob = new Blob ([bytes], { type: "image/webp" }),
|
|
2931
|
+
url = URL .createObjectURL (blob),
|
|
2932
|
+
image = await this .loadImage (url),
|
|
2933
|
+
data = this .readPixels (image);
|
|
2907
2934
|
|
|
2908
|
-
|
|
2909
|
-
|
|
2935
|
+
this .files [key] = image;
|
|
2936
|
+
this .files [key .replace (".webp", "")] = data;
|
|
2910
2937
|
|
|
2911
|
-
|
|
2912
|
-
}
|
|
2913
|
-
}
|
|
2938
|
+
URL .revokeObjectURL (url);
|
|
2939
|
+
}
|
|
2914
2940
|
|
|
2915
|
-
|
|
2916
|
-
|
|
2917
|
-
|
|
2918
|
-
|
|
2919
|
-
|
|
2920
|
-
framebuffer = gl .createFramebuffer (),
|
|
2921
|
-
width = image .width,
|
|
2922
|
-
height = image .height,
|
|
2923
|
-
data = new Uint8Array (width * height * 4);
|
|
2941
|
+
loadImage (url)
|
|
2942
|
+
{
|
|
2943
|
+
return new Promise ((resolve, reject) =>
|
|
2944
|
+
{
|
|
2945
|
+
const image = new Image ();
|
|
2924
2946
|
|
|
2925
|
-
|
|
2947
|
+
image .onload = () => resolve (image);
|
|
2926
2948
|
|
|
2927
|
-
|
|
2928
|
-
|
|
2929
|
-
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA, width, height, 0, gl .RGBA, gl .UNSIGNED_BYTE, image);
|
|
2930
|
-
gl .pixelStorei (gl .UNPACK_COLORSPACE_CONVERSION_WEBGL, gl .BROWSER_DEFAULT_WEBGL);
|
|
2949
|
+
image .onerror =
|
|
2950
|
+
image .onabort = event => reject (new Error (`Couldn't load WebP image: ${event .type}.`));
|
|
2931
2951
|
|
|
2932
|
-
|
|
2952
|
+
image .src = url;
|
|
2953
|
+
});
|
|
2954
|
+
}
|
|
2933
2955
|
|
|
2934
|
-
|
|
2935
|
-
|
|
2936
|
-
|
|
2956
|
+
readPixels (image)
|
|
2957
|
+
{
|
|
2958
|
+
const
|
|
2959
|
+
gl = this .getBrowser () .getContext (),
|
|
2960
|
+
texture = gl .createTexture (),
|
|
2961
|
+
framebuffer = gl .createFramebuffer (),
|
|
2962
|
+
width = image .width,
|
|
2963
|
+
height = image .height,
|
|
2964
|
+
data = new Uint8Array (width * height * 4);
|
|
2937
2965
|
|
|
2938
|
-
|
|
2966
|
+
// Create texture.
|
|
2939
2967
|
|
|
2940
|
-
|
|
2941
|
-
|
|
2968
|
+
gl .bindTexture (gl .TEXTURE_2D, texture);
|
|
2969
|
+
gl .pixelStorei (gl .UNPACK_COLORSPACE_CONVERSION_WEBGL, gl .NONE);
|
|
2970
|
+
gl .texImage2D (gl .TEXTURE_2D, 0, gl .RGBA, width, height, 0, gl .RGBA, gl .UNSIGNED_BYTE, image);
|
|
2971
|
+
gl .pixelStorei (gl .UNPACK_COLORSPACE_CONVERSION_WEBGL, gl .BROWSER_DEFAULT_WEBGL);
|
|
2942
2972
|
|
|
2943
|
-
|
|
2944
|
-
}
|
|
2973
|
+
// Read pixels from framebuffer.
|
|
2945
2974
|
|
|
2946
|
-
|
|
2947
|
-
|
|
2948
|
-
|
|
2975
|
+
gl .bindFramebuffer (gl .FRAMEBUFFER, framebuffer);
|
|
2976
|
+
gl .framebufferTexture2D (gl .FRAMEBUFFER, gl .COLOR_ATTACHMENT0, gl .TEXTURE_2D, texture, 0);
|
|
2977
|
+
gl .readPixels (0, 0, width, height, gl .RGBA, gl .UNSIGNED_BYTE, data);
|
|
2949
2978
|
|
|
2950
|
-
|
|
2979
|
+
// Clean up.
|
|
2951
2980
|
|
|
2952
|
-
|
|
2953
|
-
|
|
2954
|
-
means_l,
|
|
2955
|
-
means_u,
|
|
2956
|
-
} = this .files;
|
|
2981
|
+
gl .deleteFramebuffer (framebuffer);
|
|
2982
|
+
gl .deleteTexture (texture);
|
|
2957
2983
|
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
array = [ ];
|
|
2984
|
+
return data;
|
|
2985
|
+
}
|
|
2961
2986
|
|
|
2962
|
-
|
|
2987
|
+
unpackPositions ()
|
|
2963
2988
|
{
|
|
2964
|
-
|
|
2989
|
+
const lerp = (a, b, t) => a + t * (b - a);
|
|
2965
2990
|
|
|
2966
|
-
const
|
|
2967
|
-
qx = (means_u [i] << 8) | means_l [i],
|
|
2968
|
-
qy = (means_u [i + 1] << 8) | means_l [i + 1],
|
|
2969
|
-
qz = (means_u [i + 2] << 8) | means_l [i + 2];
|
|
2991
|
+
const unlog = n => Math .sign (n) * (Math .exp (Math .abs (n)) - 1);
|
|
2970
2992
|
|
|
2971
|
-
|
|
2993
|
+
const {
|
|
2994
|
+
meta: { count, means: { mins, maxs }},
|
|
2995
|
+
means_l,
|
|
2996
|
+
means_u,
|
|
2997
|
+
} = this .files;
|
|
2972
2998
|
|
|
2973
2999
|
const
|
|
2974
|
-
|
|
2975
|
-
|
|
2976
|
-
nz = lerp (mins [2], maxs [2], qz / 65535);
|
|
3000
|
+
N = count * 4,
|
|
3001
|
+
array = [ ];
|
|
2977
3002
|
|
|
2978
|
-
|
|
3003
|
+
for (let i = 0; i < N; i += 4)
|
|
3004
|
+
{
|
|
3005
|
+
// 16-bit normalized value per axis (0..65535)
|
|
2979
3006
|
|
|
2980
|
-
|
|
2981
|
-
|
|
2982
|
-
|
|
2983
|
-
|
|
2984
|
-
);
|
|
2985
|
-
}
|
|
3007
|
+
const
|
|
3008
|
+
qx = (means_u [i] << 8) | means_l [i],
|
|
3009
|
+
qy = (means_u [i + 1] << 8) | means_l [i + 1],
|
|
3010
|
+
qz = (means_u [i + 2] << 8) | means_l [i + 2];
|
|
2986
3011
|
|
|
2987
|
-
|
|
2988
|
-
}
|
|
3012
|
+
// Dequantize into *log-domain* nx,ny,nz using per-axis ranges from meta:
|
|
2989
3013
|
|
|
2990
|
-
|
|
2991
|
-
|
|
2992
|
-
|
|
3014
|
+
const
|
|
3015
|
+
nx = lerp (mins [0], maxs [0], qx / 65535),
|
|
3016
|
+
ny = lerp (mins [1], maxs [1], qy / 65535),
|
|
3017
|
+
nz = lerp (mins [2], maxs [2], qz / 65535);
|
|
2993
3018
|
|
|
2994
|
-
|
|
2995
|
-
meta: { count },
|
|
2996
|
-
quats,
|
|
2997
|
-
} = this .files;
|
|
3019
|
+
// Undo the symmetric log transform used at encode time:
|
|
2998
3020
|
|
|
2999
|
-
|
|
3000
|
-
|
|
3001
|
-
|
|
3021
|
+
array .push (
|
|
3022
|
+
unlog (nx),
|
|
3023
|
+
unlog (ny),
|
|
3024
|
+
unlog (nz),
|
|
3025
|
+
);
|
|
3026
|
+
}
|
|
3002
3027
|
|
|
3003
|
-
|
|
3004
|
-
|
|
3005
|
-
const
|
|
3006
|
-
a = toComp (quats [i]),
|
|
3007
|
-
b = toComp (quats [i + 1]),
|
|
3008
|
-
c = toComp (quats [i + 2]);
|
|
3028
|
+
return array;
|
|
3029
|
+
}
|
|
3009
3030
|
|
|
3010
|
-
|
|
3031
|
+
unpackRotations ()
|
|
3032
|
+
{
|
|
3033
|
+
const toComp = c => (c / 255 - 0.5) * 2 / Math .SQRT2;
|
|
3011
3034
|
|
|
3012
|
-
|
|
3035
|
+
const {
|
|
3036
|
+
meta: { count },
|
|
3037
|
+
quats,
|
|
3038
|
+
} = this .files;
|
|
3013
3039
|
|
|
3014
3040
|
const
|
|
3015
|
-
|
|
3016
|
-
|
|
3017
|
-
|
|
3018
|
-
// Place components according to mode; q is ordered [x, y, z, w].
|
|
3041
|
+
N = count * 4,
|
|
3042
|
+
array = [ ];
|
|
3019
3043
|
|
|
3020
|
-
|
|
3044
|
+
for (let i = 0; i < N; i += 4)
|
|
3021
3045
|
{
|
|
3022
|
-
|
|
3023
|
-
|
|
3024
|
-
|
|
3025
|
-
|
|
3026
|
-
default: throw new Error ("Invalid quaternion mode");
|
|
3027
|
-
}
|
|
3028
|
-
}
|
|
3046
|
+
const
|
|
3047
|
+
a = toComp (quats [i]),
|
|
3048
|
+
b = toComp (quats [i + 1]),
|
|
3049
|
+
c = toComp (quats [i + 2]);
|
|
3029
3050
|
|
|
3030
|
-
|
|
3031
|
-
}
|
|
3051
|
+
const mode = quats [i + 3] - 252; // 0..3 → omitted component is w, x, y or z respectively
|
|
3032
3052
|
|
|
3033
|
-
|
|
3034
|
-
{
|
|
3035
|
-
const {
|
|
3036
|
-
meta: { count, scales: { codebook } },
|
|
3037
|
-
scales,
|
|
3038
|
-
} = this .files;
|
|
3053
|
+
// Reconstruct the omitted component so that ||q|| = 1 and w.l.o.g. the omitted one is non-negative.
|
|
3039
3054
|
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3055
|
+
const
|
|
3056
|
+
t = Math .hypot (a, b, c),
|
|
3057
|
+
d = Math .sqrt (Math .max (0, 1 - t));
|
|
3058
|
+
|
|
3059
|
+
// Place components according to mode; q is ordered [x, y, z, w].
|
|
3060
|
+
|
|
3061
|
+
switch (mode)
|
|
3062
|
+
{
|
|
3063
|
+
case 0: array .push (a, b, c, d); break; // omitted = w
|
|
3064
|
+
case 1: array .push (d, b, c, a); break; // omitted = x
|
|
3065
|
+
case 2: array .push (b, d, c, a); break; // omitted = y
|
|
3066
|
+
case 3: array .push (b, c, d, a); break; // omitted = z
|
|
3067
|
+
default: throw new Error ("Invalid quaternion mode");
|
|
3068
|
+
}
|
|
3069
|
+
}
|
|
3043
3070
|
|
|
3044
|
-
|
|
3045
|
-
{
|
|
3046
|
-
array .push (
|
|
3047
|
-
Math .exp (codebook [scales [i]]), // r,g,b are 0..255
|
|
3048
|
-
Math .exp (codebook [scales [i + 1]]),
|
|
3049
|
-
Math .exp (codebook [scales [i + 2]]),
|
|
3050
|
-
);
|
|
3071
|
+
return array;
|
|
3051
3072
|
}
|
|
3052
3073
|
|
|
3053
|
-
|
|
3054
|
-
|
|
3055
|
-
|
|
3056
|
-
|
|
3057
|
-
|
|
3058
|
-
|
|
3059
|
-
meta: { count, sh0: { codebook } },
|
|
3060
|
-
sh0,
|
|
3061
|
-
} = this .files;
|
|
3074
|
+
unpackScales ()
|
|
3075
|
+
{
|
|
3076
|
+
const {
|
|
3077
|
+
meta: { count, scales: { codebook } },
|
|
3078
|
+
scales,
|
|
3079
|
+
} = this .files;
|
|
3062
3080
|
|
|
3063
|
-
|
|
3064
|
-
|
|
3065
|
-
|
|
3066
|
-
alphas = [ ];
|
|
3081
|
+
const
|
|
3082
|
+
N = count * 4,
|
|
3083
|
+
array = [ ];
|
|
3067
3084
|
|
|
3068
|
-
|
|
3069
|
-
|
|
3070
|
-
|
|
3071
|
-
|
|
3072
|
-
|
|
3073
|
-
|
|
3074
|
-
|
|
3085
|
+
for (let i = 0; i < N; i += 4)
|
|
3086
|
+
{
|
|
3087
|
+
array .push (
|
|
3088
|
+
Math .exp (codebook [scales [i]]), // r,g,b are 0..255
|
|
3089
|
+
Math .exp (codebook [scales [i + 1]]),
|
|
3090
|
+
Math .exp (codebook [scales [i + 2]]),
|
|
3091
|
+
);
|
|
3092
|
+
}
|
|
3075
3093
|
|
|
3076
|
-
|
|
3094
|
+
return array;
|
|
3077
3095
|
}
|
|
3078
3096
|
|
|
3079
|
-
|
|
3080
|
-
|
|
3097
|
+
unpackAlphasAndAColors ()
|
|
3098
|
+
{
|
|
3099
|
+
const {
|
|
3100
|
+
meta: { count, sh0: { codebook } },
|
|
3101
|
+
sh0,
|
|
3102
|
+
} = this .files;
|
|
3081
3103
|
|
|
3082
|
-
|
|
3083
|
-
|
|
3084
|
-
|
|
3085
|
-
|
|
3104
|
+
const
|
|
3105
|
+
N = count * 4,
|
|
3106
|
+
array = [ ],
|
|
3107
|
+
alphas = [ ];
|
|
3086
3108
|
|
|
3087
|
-
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3109
|
+
for (let i = 0; i < N; i += 4)
|
|
3110
|
+
{
|
|
3111
|
+
array .push (
|
|
3112
|
+
codebook [sh0 [i]],
|
|
3113
|
+
codebook [sh0 [i + 1]],
|
|
3114
|
+
codebook [sh0 [i + 2]],
|
|
3115
|
+
);
|
|
3093
3116
|
|
|
3094
|
-
|
|
3117
|
+
alphas .push (sh0 [i + 3] / 255);
|
|
3118
|
+
}
|
|
3095
3119
|
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
shCoeffs = coeffs [bands]; // coefficients per color channel
|
|
3120
|
+
return [alphas, array];
|
|
3121
|
+
}
|
|
3099
3122
|
|
|
3100
|
-
|
|
3101
|
-
|
|
3123
|
+
unpackSphericalHarmonics ()
|
|
3124
|
+
{
|
|
3125
|
+
if (!this .files .meta .shN)
|
|
3126
|
+
return [ ];
|
|
3102
3127
|
|
|
3103
|
-
|
|
3104
|
-
|
|
3105
|
-
|
|
3128
|
+
const {
|
|
3129
|
+
meta: { count, shN: { bands, codebook } },
|
|
3130
|
+
shN_labels,
|
|
3131
|
+
shN_centroids,
|
|
3132
|
+
"shN_centroids.webp": { width },
|
|
3133
|
+
} = this .files;
|
|
3106
3134
|
|
|
3107
|
-
|
|
3108
|
-
{
|
|
3109
|
-
// 1. Look up this gaussian's palette entry.
|
|
3135
|
+
const getIndex = (u, v) => u + v * width;
|
|
3110
3136
|
|
|
3111
|
-
const
|
|
3137
|
+
const
|
|
3138
|
+
coeffs = [0, 3, 8, 15],
|
|
3139
|
+
shCoeffs = coeffs [bands]; // coefficients per color channel
|
|
3112
3140
|
|
|
3113
|
-
|
|
3141
|
+
if (!shCoeffs)
|
|
3142
|
+
return [ ];
|
|
3114
3143
|
|
|
3115
|
-
|
|
3144
|
+
const
|
|
3145
|
+
N = count * 4,
|
|
3146
|
+
array = [ ];
|
|
3147
|
+
|
|
3148
|
+
for (let i = 0; i < N; i += 4)
|
|
3116
3149
|
{
|
|
3117
|
-
|
|
3118
|
-
u = (label % 64) * shCoeffs + c,
|
|
3119
|
-
v = Math .floor (label / 64);
|
|
3150
|
+
// 1. Look up this gaussian's palette entry.
|
|
3120
3151
|
|
|
3121
|
-
|
|
3122
|
-
const index = getIndex (u, v) * 4;
|
|
3152
|
+
const label = shN_labels [i] + (shN_labels [i + 1] << 8);
|
|
3123
3153
|
|
|
3124
|
-
|
|
3125
|
-
r = shN_centroids [index],
|
|
3126
|
-
g = shN_centroids [index + 1],
|
|
3127
|
-
b = shN_centroids [index + 2];
|
|
3154
|
+
// 2. For each coefficient, read RGB from the centroids pixel and map through the codebook.
|
|
3128
3155
|
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
|
|
3133
|
-
|
|
3134
|
-
}
|
|
3135
|
-
}
|
|
3156
|
+
for (let c = 0; c < shCoeffs; ++ c)
|
|
3157
|
+
{
|
|
3158
|
+
const
|
|
3159
|
+
u = (label % 64) * shCoeffs + c,
|
|
3160
|
+
v = Math .floor (label / 64);
|
|
3136
3161
|
|
|
3137
|
-
|
|
3138
|
-
|
|
3139
|
-
|
|
3140
|
-
dimForDegree (degree)
|
|
3141
|
-
{
|
|
3142
|
-
return (degree + 1) ** 2 - 1;
|
|
3143
|
-
}
|
|
3162
|
+
// pixel (u, v) in shN_centroids.webp
|
|
3163
|
+
const index = getIndex (u, v) * 4;
|
|
3144
3164
|
|
|
3145
|
-
|
|
3146
|
-
|
|
3147
|
-
|
|
3148
|
-
|
|
3149
|
-
}
|
|
3165
|
+
const
|
|
3166
|
+
r = shN_centroids [index],
|
|
3167
|
+
g = shN_centroids [index + 1],
|
|
3168
|
+
b = shN_centroids [index + 2];
|
|
3150
3169
|
|
|
3151
|
-
|
|
3170
|
+
array .push (
|
|
3171
|
+
codebook [r], // SH AC coefficient for color channel 0
|
|
3172
|
+
codebook [g], // SH AC coefficient for color channel 1
|
|
3173
|
+
codebook [b], // SH AC coefficient for color channel 2
|
|
3174
|
+
);
|
|
3175
|
+
}
|
|
3176
|
+
}
|
|
3152
3177
|
|
|
3153
|
-
|
|
3178
|
+
return array;
|
|
3179
|
+
}
|
|
3154
3180
|
|
|
3155
|
-
|
|
3181
|
+
dimForDegree (degree)
|
|
3182
|
+
{
|
|
3183
|
+
return (degree + 1) ** 2 - 1;
|
|
3184
|
+
}
|
|
3156
3185
|
|
|
3157
|
-
|
|
3158
|
-
{
|
|
3159
|
-
|
|
3186
|
+
coefsForDegree (degree)
|
|
3187
|
+
{
|
|
3188
|
+
return degree * 2 + 3;
|
|
3189
|
+
}
|
|
3190
|
+
}
|
|
3160
3191
|
|
|
3161
|
-
|
|
3162
|
-
}
|
|
3192
|
+
X3D .GoldenGate .addParsers (SOGParser);
|
|
3193
|
+
});
|
|
3163
3194
|
|
|
3164
3195
|
/******/ })()
|
|
3165
3196
|
;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "x_ite-sog-parser",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "3DGS SOG File Format Parser for X_ITE",
|
|
5
5
|
"main": "dist/x_ite-sog-parser-2.js",
|
|
6
6
|
"module": "dist/x_ite-sog-parser-2.js",
|
|
@@ -44,6 +44,7 @@
|
|
|
44
44
|
"globals": "^17.6.0",
|
|
45
45
|
"shell-tools": "^1.1.9",
|
|
46
46
|
"webpack": "^5.107.2",
|
|
47
|
-
"webpack-cli": "^7.0.3"
|
|
47
|
+
"webpack-cli": "^7.0.3",
|
|
48
|
+
"x_ite-extension": "^1.0.0"
|
|
48
49
|
}
|
|
49
50
|
}
|