poppygl 0.0.14 → 0.0.16
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/dist/index.d.ts +37 -1
- package/dist/index.js +251 -32
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -35,6 +35,13 @@ interface GridOptions {
|
|
|
35
35
|
y: number;
|
|
36
36
|
z: number;
|
|
37
37
|
}>;
|
|
38
|
+
infiniteGrid?: boolean;
|
|
39
|
+
cellSize?: number;
|
|
40
|
+
sectionSize?: number;
|
|
41
|
+
fadeDistance?: number;
|
|
42
|
+
fadeStrength?: number;
|
|
43
|
+
gridColor?: readonly [number, number, number];
|
|
44
|
+
sectionColor?: readonly [number, number, number];
|
|
38
45
|
}
|
|
39
46
|
interface GLTFResources {
|
|
40
47
|
buffers: Uint8Array[];
|
|
@@ -80,6 +87,20 @@ declare function resolveRenderOptions(options?: RenderOptionsInput): RenderOptio
|
|
|
80
87
|
|
|
81
88
|
declare function createGrid(options?: GridOptions): DrawCall;
|
|
82
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Creates an infinite grid that matches the appearance of the 3d-viewer reference.
|
|
92
|
+
* This grid uses a special rendering approach with procedural generation and fading.
|
|
93
|
+
*/
|
|
94
|
+
declare function createInfiniteGrid(options?: GridOptions): DrawCall & {
|
|
95
|
+
isInfiniteGrid: boolean;
|
|
96
|
+
cellSize: number;
|
|
97
|
+
sectionSize: number;
|
|
98
|
+
fadeDistance: number;
|
|
99
|
+
fadeStrength: number;
|
|
100
|
+
gridColor: readonly [number, number, number];
|
|
101
|
+
sectionColor: readonly [number, number, number];
|
|
102
|
+
};
|
|
103
|
+
|
|
83
104
|
type GLTF = any;
|
|
84
105
|
declare function createSceneFromGLTF(gltf: GLTF, resources: GLTFResources): GLTFScene;
|
|
85
106
|
|
|
@@ -130,6 +151,21 @@ declare class SoftwareRenderer {
|
|
|
130
151
|
drawMesh(mesh: DrawCall, camera: Camera, light: LightSettings, material: Material, cullBackFaces?: boolean, gammaOut?: boolean): void;
|
|
131
152
|
}
|
|
132
153
|
|
|
154
|
+
/**
|
|
155
|
+
* Draws an infinite grid with fade-out effect matching 3d-viewer appearance
|
|
156
|
+
*/
|
|
157
|
+
declare function drawInfiniteGrid(software_renderer: SoftwareRenderer, params: {
|
|
158
|
+
camera: Camera;
|
|
159
|
+
grid_y?: number;
|
|
160
|
+
cell_size?: number;
|
|
161
|
+
section_size?: number;
|
|
162
|
+
fade_distance?: number;
|
|
163
|
+
fade_strength?: number;
|
|
164
|
+
grid_color?: readonly [number, number, number];
|
|
165
|
+
section_color?: readonly [number, number, number];
|
|
166
|
+
gamma_out?: boolean;
|
|
167
|
+
}): void;
|
|
168
|
+
|
|
133
169
|
declare const pureImageFactory: ImageFactory;
|
|
134
170
|
|
|
135
171
|
declare function encodePNGToBuffer(image: BitmapLike): Promise<Buffer>;
|
|
@@ -145,4 +181,4 @@ declare function renderGLTFToPNGBuffer(gltfPathOrString: string, options?: Rende
|
|
|
145
181
|
|
|
146
182
|
declare function renderSceneFromGLTF(scene: GLTFScene, options?: RenderOptionsInput, imageFactory?: ImageFactory): RenderResult;
|
|
147
183
|
|
|
148
|
-
export { type BitmapLike, type Camera, DEFAULT_LIGHT_DIR, DEFAULT_RENDER_OPTIONS, type DrawCall, type FetchLike, type GLTFResources, type GLTFScene, type GridOptions, type ImageFactory, type LightSettings, type LoadGLTFWithResourcesFromURLOptions, type Material, type MutableRGBA, type RGBA, type RenderGLTFToPNGBufferFromGLBBufferOptions, type RenderGLTFToPNGBufferFromURLOptions, type RenderOptions, type RenderOptionsInput, type RenderResult, SoftwareRenderer, bufferFromDataURI, buildCamera, computeSmoothNormals, computeWorldAABB, createGrid, createSceneFromGLTF, createUint8Bitmap, decodeImageFromBuffer, encodePNGToBuffer, getDefaultRenderOptions, isJPG, isPNG, loadGLTFWithResourcesFromURL, pureImageFactory, renderDrawCalls, renderGLTFToPNGBuffer, renderGLTFToPNGBufferFromGLBBuffer, renderGLTFToPNGBufferFromURL, renderSceneFromGLTF, resolveRenderOptions };
|
|
184
|
+
export { type BitmapLike, type Camera, DEFAULT_LIGHT_DIR, DEFAULT_RENDER_OPTIONS, type DrawCall, type FetchLike, type GLTFResources, type GLTFScene, type GridOptions, type ImageFactory, type LightSettings, type LoadGLTFWithResourcesFromURLOptions, type Material, type MutableRGBA, type RGBA, type RenderGLTFToPNGBufferFromGLBBufferOptions, type RenderGLTFToPNGBufferFromURLOptions, type RenderOptions, type RenderOptionsInput, type RenderResult, SoftwareRenderer, bufferFromDataURI, buildCamera, computeSmoothNormals, computeWorldAABB, createGrid, createInfiniteGrid, createSceneFromGLTF, createUint8Bitmap, decodeImageFromBuffer, drawInfiniteGrid, encodePNGToBuffer, getDefaultRenderOptions, isJPG, isPNG, loadGLTFWithResourcesFromURL, pureImageFactory, renderDrawCalls, renderGLTFToPNGBuffer, renderGLTFToPNGBufferFromGLBBuffer, renderGLTFToPNGBufferFromURL, renderSceneFromGLTF, resolveRenderOptions };
|
package/dist/index.js
CHANGED
|
@@ -604,6 +604,151 @@ function resolveRenderOptions(options = {}) {
|
|
|
604
604
|
};
|
|
605
605
|
}
|
|
606
606
|
|
|
607
|
+
// lib/render/drawInfiniteGrid.ts
|
|
608
|
+
import { mat4 as mat44, vec4 as vec43 } from "gl-matrix";
|
|
609
|
+
function computeGridLineIntensity(params) {
|
|
610
|
+
const rx = params.world_x / params.cell_size;
|
|
611
|
+
const rz = params.world_z / params.cell_size;
|
|
612
|
+
const fract_x = rx - Math.floor(rx + 0.5);
|
|
613
|
+
const fract_z = rz - Math.floor(rz + 0.5);
|
|
614
|
+
const grid_x = Math.abs(fract_x);
|
|
615
|
+
const grid_z = Math.abs(fract_z);
|
|
616
|
+
const pixel_size_in_world = params.dist / Math.min(params.screen_width, params.screen_height);
|
|
617
|
+
const fwidth_x = pixel_size_in_world / params.cell_size;
|
|
618
|
+
const fwidth_z = pixel_size_in_world / params.cell_size;
|
|
619
|
+
const line_x = grid_x / (fwidth_x + 1e-4);
|
|
620
|
+
const line_z = grid_z / (fwidth_z + 1e-4);
|
|
621
|
+
const line = Math.min(line_x, line_z);
|
|
622
|
+
return 1 - Math.min(line * params.line_thickness_multiplier, 1);
|
|
623
|
+
}
|
|
624
|
+
function computeGridFadeAlpha(params) {
|
|
625
|
+
const fade_start = params.fade_distance;
|
|
626
|
+
const fade_end = params.fade_distance * params.fade_strength;
|
|
627
|
+
return 1 - Math.min(
|
|
628
|
+
1,
|
|
629
|
+
Math.max(0, (params.dist - fade_start) / (fade_end - fade_start))
|
|
630
|
+
);
|
|
631
|
+
}
|
|
632
|
+
function drawInfiniteGrid(software_renderer, params) {
|
|
633
|
+
const grid_y = params.grid_y ?? 0;
|
|
634
|
+
const cell_size = params.cell_size ?? 1;
|
|
635
|
+
const section_size = params.section_size ?? 10;
|
|
636
|
+
const fade_distance = params.fade_distance ?? 100;
|
|
637
|
+
const fade_strength = params.fade_strength ?? 1.5;
|
|
638
|
+
const grid_color = params.grid_color ?? [0.93, 0.93, 0.93];
|
|
639
|
+
const section_color = params.section_color ?? [0.8, 0.8, 1];
|
|
640
|
+
const gamma_out = params.gamma_out ?? true;
|
|
641
|
+
const camera = params.camera;
|
|
642
|
+
const view = camera.view;
|
|
643
|
+
const proj = camera.proj;
|
|
644
|
+
const inv_view = mat44.create();
|
|
645
|
+
mat44.invert(inv_view, view);
|
|
646
|
+
const cam_pos_x = inv_view[12];
|
|
647
|
+
const cam_pos_y = inv_view[13];
|
|
648
|
+
const cam_pos_z = inv_view[14];
|
|
649
|
+
const vp = mat44.create();
|
|
650
|
+
mat44.multiply(vp, proj, view);
|
|
651
|
+
const inv_vp = mat44.create();
|
|
652
|
+
mat44.invert(inv_vp, vp);
|
|
653
|
+
for (let y = 0; y < software_renderer.height; y++) {
|
|
654
|
+
for (let x = 0; x < software_renderer.width; x++) {
|
|
655
|
+
const ndc_x = x / (software_renderer.width - 1) * 2 - 1;
|
|
656
|
+
const ndc_y = 1 - y / (software_renderer.height - 1) * 2;
|
|
657
|
+
const near_point = vec43.fromValues(ndc_x, ndc_y, -1, 1);
|
|
658
|
+
const far_point = vec43.fromValues(ndc_x, ndc_y, 1, 1);
|
|
659
|
+
vec43.transformMat4(near_point, near_point, inv_vp);
|
|
660
|
+
vec43.transformMat4(far_point, far_point, inv_vp);
|
|
661
|
+
near_point[0] /= near_point[3];
|
|
662
|
+
near_point[1] /= near_point[3];
|
|
663
|
+
near_point[2] /= near_point[3];
|
|
664
|
+
far_point[0] /= far_point[3];
|
|
665
|
+
far_point[1] /= far_point[3];
|
|
666
|
+
far_point[2] /= far_point[3];
|
|
667
|
+
const ray_dir_x = far_point[0] - near_point[0];
|
|
668
|
+
const ray_dir_y = far_point[1] - near_point[1];
|
|
669
|
+
const ray_dir_z = far_point[2] - near_point[2];
|
|
670
|
+
if (Math.abs(ray_dir_y) < 1e-6) continue;
|
|
671
|
+
const t = (grid_y - near_point[1]) / ray_dir_y;
|
|
672
|
+
if (t < 0 || t > 1) continue;
|
|
673
|
+
const world_x = near_point[0] + t * ray_dir_x;
|
|
674
|
+
const world_z = near_point[2] + t * ray_dir_z;
|
|
675
|
+
const world_pt = vec43.fromValues(world_x, grid_y, world_z, 1);
|
|
676
|
+
const clip_pt = vec43.create();
|
|
677
|
+
vec43.transformMat4(clip_pt, world_pt, vp);
|
|
678
|
+
const ndc_z = clip_pt[2] / clip_pt[3];
|
|
679
|
+
const depth_01 = ndc_z * 0.5 + 0.5;
|
|
680
|
+
const di = y * software_renderer.width + x;
|
|
681
|
+
if (depth_01 >= software_renderer.depth[di]) continue;
|
|
682
|
+
const dx = world_x - cam_pos_x;
|
|
683
|
+
const dy = grid_y - cam_pos_y;
|
|
684
|
+
const dz = world_z - cam_pos_z;
|
|
685
|
+
const dist = Math.sqrt(dx * dx + dy * dy + dz * dz);
|
|
686
|
+
const alpha = computeGridFadeAlpha({
|
|
687
|
+
dist,
|
|
688
|
+
fade_distance,
|
|
689
|
+
fade_strength
|
|
690
|
+
});
|
|
691
|
+
if (alpha <= 0) continue;
|
|
692
|
+
const g1 = computeGridLineIntensity({
|
|
693
|
+
world_x,
|
|
694
|
+
world_z,
|
|
695
|
+
cell_size,
|
|
696
|
+
dist,
|
|
697
|
+
screen_width: software_renderer.width,
|
|
698
|
+
screen_height: software_renderer.height,
|
|
699
|
+
line_thickness_multiplier: 0.8
|
|
700
|
+
});
|
|
701
|
+
const g2 = computeGridLineIntensity({
|
|
702
|
+
world_x,
|
|
703
|
+
world_z,
|
|
704
|
+
cell_size: section_size,
|
|
705
|
+
dist,
|
|
706
|
+
screen_width: software_renderer.width,
|
|
707
|
+
screen_height: software_renderer.height,
|
|
708
|
+
line_thickness_multiplier: 0.5
|
|
709
|
+
// Thicker section lines
|
|
710
|
+
});
|
|
711
|
+
const grid_strength = Math.max(g1, g2);
|
|
712
|
+
if (grid_strength <= 0) continue;
|
|
713
|
+
const final_r = grid_color[0] * (1 - g2) + section_color[0] * g2;
|
|
714
|
+
const final_g = grid_color[1] * (1 - g2) + section_color[1] * g2;
|
|
715
|
+
const final_b = grid_color[2] * (1 - g2) + section_color[2] * g2;
|
|
716
|
+
const final_alpha = grid_strength * alpha;
|
|
717
|
+
if (final_alpha <= 0.01) continue;
|
|
718
|
+
let out_r = final_r;
|
|
719
|
+
let out_g = final_g;
|
|
720
|
+
let out_b = final_b;
|
|
721
|
+
if (gamma_out) {
|
|
722
|
+
out_r = srgbEncodeLinear01(clamp(out_r, 0, 1));
|
|
723
|
+
out_g = srgbEncodeLinear01(clamp(out_g, 0, 1));
|
|
724
|
+
out_b = srgbEncodeLinear01(clamp(out_b, 0, 1));
|
|
725
|
+
} else {
|
|
726
|
+
out_r = clamp(out_r, 0, 1);
|
|
727
|
+
out_g = clamp(out_g, 0, 1);
|
|
728
|
+
out_b = clamp(out_b, 0, 1);
|
|
729
|
+
}
|
|
730
|
+
const dst_idx = (y * software_renderer.width + x) * 4;
|
|
731
|
+
const dst_r = (software_renderer.buffer[dst_idx + 0] ?? 0) / 255;
|
|
732
|
+
const dst_g = (software_renderer.buffer[dst_idx + 1] ?? 0) / 255;
|
|
733
|
+
const dst_b = (software_renderer.buffer[dst_idx + 2] ?? 0) / 255;
|
|
734
|
+
const dst_a = (software_renderer.buffer[dst_idx + 3] ?? 0) / 255;
|
|
735
|
+
const one_minus_a = 1 - final_alpha;
|
|
736
|
+
const blend_r = out_r * final_alpha + dst_r * one_minus_a;
|
|
737
|
+
const blend_g = out_g * final_alpha + dst_g * one_minus_a;
|
|
738
|
+
const blend_b = out_b * final_alpha + dst_b * one_minus_a;
|
|
739
|
+
const blend_a = final_alpha + dst_a * one_minus_a;
|
|
740
|
+
software_renderer.setPixel(
|
|
741
|
+
x,
|
|
742
|
+
y,
|
|
743
|
+
clamp(blend_r, 0, 1) * 255 | 0,
|
|
744
|
+
clamp(blend_g, 0, 1) * 255 | 0,
|
|
745
|
+
clamp(blend_b, 0, 1) * 255 | 0,
|
|
746
|
+
clamp(blend_a, 0, 1) * 255 | 0
|
|
747
|
+
);
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
|
|
607
752
|
// lib/render/renderDrawCalls.ts
|
|
608
753
|
function renderDrawCalls(drawCalls, optionsInput = {}, imageFactory = createUint8Bitmap) {
|
|
609
754
|
const options = resolveRenderOptions(optionsInput);
|
|
@@ -632,31 +777,36 @@ function renderDrawCalls(drawCalls, optionsInput = {}, imageFactory = createUint
|
|
|
632
777
|
renderer.clear([0, 0, 0, 0]);
|
|
633
778
|
}
|
|
634
779
|
const allDrawCalls = [...drawCalls];
|
|
780
|
+
let infiniteGridOptions = null;
|
|
635
781
|
if (options.grid) {
|
|
636
782
|
const userGridOptions = typeof options.grid === "boolean" ? {} : options.grid;
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
...defaultGridOptions
|
|
656
|
-
...userGridOptions
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
783
|
+
if (userGridOptions.infiniteGrid) {
|
|
784
|
+
infiniteGridOptions = userGridOptions;
|
|
785
|
+
} else {
|
|
786
|
+
const aabb = computeWorldAABB(drawCalls);
|
|
787
|
+
const sizeX = aabb.max[0] - aabb.min[0];
|
|
788
|
+
const sizeZ = aabb.max[2] - aabb.min[2];
|
|
789
|
+
const maxSize = Math.max(sizeX, sizeZ);
|
|
790
|
+
const defaultSize = Math.ceil(maxSize * 1.2 / 2) * 2;
|
|
791
|
+
const defaultOffset = {
|
|
792
|
+
x: (aabb.min[0] + aabb.max[0]) / 2,
|
|
793
|
+
y: aabb.min[1],
|
|
794
|
+
z: (aabb.min[2] + aabb.max[2]) / 2
|
|
795
|
+
};
|
|
796
|
+
const defaultGridOptions = {
|
|
797
|
+
size: defaultSize > 0 ? defaultSize : 10,
|
|
798
|
+
offset: defaultOffset
|
|
799
|
+
};
|
|
800
|
+
const finalGridOptions = {
|
|
801
|
+
...defaultGridOptions,
|
|
802
|
+
...userGridOptions,
|
|
803
|
+
offset: {
|
|
804
|
+
...defaultGridOptions.offset,
|
|
805
|
+
...userGridOptions.offset
|
|
806
|
+
}
|
|
807
|
+
};
|
|
808
|
+
allDrawCalls.push(createGrid(finalGridOptions));
|
|
809
|
+
}
|
|
660
810
|
}
|
|
661
811
|
const opaqueDraws = allDrawCalls.filter(
|
|
662
812
|
(dc) => (dc.material.alphaMode ?? "OPAQUE") === "OPAQUE"
|
|
@@ -685,12 +835,79 @@ function renderDrawCalls(drawCalls, optionsInput = {}, imageFactory = createUint
|
|
|
685
835
|
};
|
|
686
836
|
renderGroup(opaqueDraws);
|
|
687
837
|
renderGroup(maskDraws);
|
|
838
|
+
if (infiniteGridOptions) {
|
|
839
|
+
const aabb = computeWorldAABB(drawCalls);
|
|
840
|
+
const modelCenterY = (aabb.min[1] + aabb.max[1]) / 2;
|
|
841
|
+
const gridY = infiniteGridOptions.offset?.y ?? modelCenterY;
|
|
842
|
+
drawInfiniteGrid(renderer, {
|
|
843
|
+
camera,
|
|
844
|
+
grid_y: gridY,
|
|
845
|
+
cell_size: infiniteGridOptions.cellSize,
|
|
846
|
+
section_size: infiniteGridOptions.sectionSize,
|
|
847
|
+
fade_distance: infiniteGridOptions.fadeDistance,
|
|
848
|
+
fade_strength: infiniteGridOptions.fadeStrength,
|
|
849
|
+
grid_color: infiniteGridOptions.gridColor,
|
|
850
|
+
section_color: infiniteGridOptions.sectionColor,
|
|
851
|
+
gamma_out: options.gamma
|
|
852
|
+
});
|
|
853
|
+
}
|
|
688
854
|
renderGroup(blendDraws);
|
|
689
855
|
return { bitmap: renderer.bitmap, camera, options };
|
|
690
856
|
}
|
|
691
857
|
|
|
858
|
+
// lib/gltf/createInfiniteGrid.ts
|
|
859
|
+
import { mat4 as mat45 } from "gl-matrix";
|
|
860
|
+
function createInfiniteGrid(options = {}) {
|
|
861
|
+
const cellSize = options.cellSize ?? 1;
|
|
862
|
+
const sectionSize = options.sectionSize ?? 10;
|
|
863
|
+
const fadeDistance = options.fadeDistance ?? 100;
|
|
864
|
+
const fadeStrength = options.fadeStrength ?? 1.5;
|
|
865
|
+
const gridColor = options.gridColor ?? [0.93, 0.93, 0.93];
|
|
866
|
+
const sectionColor = options.sectionColor ?? [0.8, 0.8, 1];
|
|
867
|
+
const size = 1e3;
|
|
868
|
+
const positions = new Float32Array([
|
|
869
|
+
-size,
|
|
870
|
+
0,
|
|
871
|
+
-size,
|
|
872
|
+
size,
|
|
873
|
+
0,
|
|
874
|
+
-size,
|
|
875
|
+
size,
|
|
876
|
+
0,
|
|
877
|
+
size,
|
|
878
|
+
-size,
|
|
879
|
+
0,
|
|
880
|
+
size
|
|
881
|
+
]);
|
|
882
|
+
const indices = new Uint32Array([0, 1, 2, 0, 2, 3]);
|
|
883
|
+
const model = mat45.create();
|
|
884
|
+
const offset = options.offset ?? {};
|
|
885
|
+
mat45.fromTranslation(model, [offset.x ?? 0, offset.y ?? 0, offset.z ?? 0]);
|
|
886
|
+
return {
|
|
887
|
+
positions,
|
|
888
|
+
indices,
|
|
889
|
+
normals: null,
|
|
890
|
+
uvs: null,
|
|
891
|
+
model,
|
|
892
|
+
material: {
|
|
893
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
894
|
+
baseColorTexture: null,
|
|
895
|
+
alphaMode: "BLEND"
|
|
896
|
+
},
|
|
897
|
+
mode: 4,
|
|
898
|
+
// triangles
|
|
899
|
+
isInfiniteGrid: true,
|
|
900
|
+
cellSize,
|
|
901
|
+
sectionSize,
|
|
902
|
+
fadeDistance,
|
|
903
|
+
fadeStrength,
|
|
904
|
+
gridColor,
|
|
905
|
+
sectionColor
|
|
906
|
+
};
|
|
907
|
+
}
|
|
908
|
+
|
|
692
909
|
// lib/gltf/createSceneFromGLTF.ts
|
|
693
|
-
import { mat4 as
|
|
910
|
+
import { mat4 as mat46 } from "gl-matrix";
|
|
694
911
|
var COMPONENT_INFO = {
|
|
695
912
|
5120: {
|
|
696
913
|
name: "BYTE",
|
|
@@ -888,17 +1105,17 @@ function readIndices(ctx, accessorIndex) {
|
|
|
888
1105
|
}
|
|
889
1106
|
function nodeLocalMatrix(node) {
|
|
890
1107
|
if (node.matrix) {
|
|
891
|
-
const m2 =
|
|
1108
|
+
const m2 = mat46.create();
|
|
892
1109
|
for (let i = 0; i < 16; i++) m2[i] = node.matrix[i];
|
|
893
1110
|
return m2;
|
|
894
1111
|
}
|
|
895
1112
|
const translation = node.translation || [0, 0, 0];
|
|
896
1113
|
const rotation = node.rotation || [0, 0, 0, 1];
|
|
897
1114
|
const scale = node.scale || [1, 1, 1];
|
|
898
|
-
const m =
|
|
899
|
-
const tmp =
|
|
900
|
-
|
|
901
|
-
|
|
1115
|
+
const m = mat46.create();
|
|
1116
|
+
const tmp = mat46.create();
|
|
1117
|
+
mat46.fromRotationTranslationScale(tmp, rotation, translation, scale);
|
|
1118
|
+
mat46.copy(m, tmp);
|
|
902
1119
|
return m;
|
|
903
1120
|
}
|
|
904
1121
|
function getMaterial(gltf, textures, images, materialIndex) {
|
|
@@ -936,8 +1153,8 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
936
1153
|
const node = nodes[nodeIndex];
|
|
937
1154
|
if (!node) return;
|
|
938
1155
|
const local = nodeLocalMatrix(node);
|
|
939
|
-
const world =
|
|
940
|
-
|
|
1156
|
+
const world = mat46.create();
|
|
1157
|
+
mat46.multiply(world, parentMatrix, local);
|
|
941
1158
|
if (Number.isInteger(node.mesh)) {
|
|
942
1159
|
const mesh = meshes[node.mesh];
|
|
943
1160
|
if (mesh) {
|
|
@@ -975,7 +1192,7 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
975
1192
|
traverse(childIndex, world);
|
|
976
1193
|
}
|
|
977
1194
|
}
|
|
978
|
-
const identity =
|
|
1195
|
+
const identity = mat46.create();
|
|
979
1196
|
for (const rootIndex of scene.nodes || []) {
|
|
980
1197
|
traverse(rootIndex, identity);
|
|
981
1198
|
}
|
|
@@ -1379,9 +1596,11 @@ export {
|
|
|
1379
1596
|
computeSmoothNormals,
|
|
1380
1597
|
computeWorldAABB,
|
|
1381
1598
|
createGrid,
|
|
1599
|
+
createInfiniteGrid,
|
|
1382
1600
|
createSceneFromGLTF,
|
|
1383
1601
|
createUint8Bitmap,
|
|
1384
1602
|
decodeImageFromBuffer,
|
|
1603
|
+
drawInfiniteGrid,
|
|
1385
1604
|
encodePNGToBuffer,
|
|
1386
1605
|
getDefaultRenderOptions,
|
|
1387
1606
|
isJPG,
|