poppygl 0.0.13 → 0.0.15
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 +38 -1
- package/dist/index.js +299 -49
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ declare const createUint8Bitmap: ImageFactory;
|
|
|
13
13
|
interface Material {
|
|
14
14
|
baseColorFactor: [number, number, number, number];
|
|
15
15
|
baseColorTexture: BitmapLike | null;
|
|
16
|
+
alphaMode?: "OPAQUE" | "MASK" | "BLEND";
|
|
17
|
+
alphaCutoff?: number;
|
|
16
18
|
}
|
|
17
19
|
interface DrawCall {
|
|
18
20
|
positions: Float32Array;
|
|
@@ -33,6 +35,13 @@ interface GridOptions {
|
|
|
33
35
|
y: number;
|
|
34
36
|
z: number;
|
|
35
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];
|
|
36
45
|
}
|
|
37
46
|
interface GLTFResources {
|
|
38
47
|
buffers: Uint8Array[];
|
|
@@ -78,6 +87,20 @@ declare function resolveRenderOptions(options?: RenderOptionsInput): RenderOptio
|
|
|
78
87
|
|
|
79
88
|
declare function createGrid(options?: GridOptions): DrawCall;
|
|
80
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
|
+
|
|
81
104
|
type GLTF = any;
|
|
82
105
|
declare function createSceneFromGLTF(gltf: GLTF, resources: GLTFResources): GLTFScene;
|
|
83
106
|
|
|
@@ -128,6 +151,20 @@ declare class SoftwareRenderer {
|
|
|
128
151
|
drawMesh(mesh: DrawCall, camera: Camera, light: LightSettings, material: Material, cullBackFaces?: boolean, gammaOut?: boolean): void;
|
|
129
152
|
}
|
|
130
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
|
+
cell_size?: number;
|
|
160
|
+
section_size?: number;
|
|
161
|
+
fade_distance?: number;
|
|
162
|
+
fade_strength?: number;
|
|
163
|
+
grid_color?: readonly [number, number, number];
|
|
164
|
+
section_color?: readonly [number, number, number];
|
|
165
|
+
gamma_out?: boolean;
|
|
166
|
+
}): void;
|
|
167
|
+
|
|
131
168
|
declare const pureImageFactory: ImageFactory;
|
|
132
169
|
|
|
133
170
|
declare function encodePNGToBuffer(image: BitmapLike): Promise<Buffer>;
|
|
@@ -143,4 +180,4 @@ declare function renderGLTFToPNGBuffer(gltfPathOrString: string, options?: Rende
|
|
|
143
180
|
|
|
144
181
|
declare function renderSceneFromGLTF(scene: GLTFScene, options?: RenderOptionsInput, imageFactory?: ImageFactory): RenderResult;
|
|
145
182
|
|
|
146
|
-
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 };
|
|
183
|
+
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
|
@@ -544,6 +544,13 @@ var SoftwareRenderer = class {
|
|
|
544
544
|
let g = baseColor[1] * lit;
|
|
545
545
|
let b = baseColor[2] * lit;
|
|
546
546
|
let a = baseColor[3];
|
|
547
|
+
const alphaMode = material.alphaMode ?? "OPAQUE";
|
|
548
|
+
const alphaCutoff = material.alphaCutoff ?? 0.5;
|
|
549
|
+
if (alphaMode === "MASK" && a < alphaCutoff) continue;
|
|
550
|
+
const shouldWriteDepth = alphaMode !== "BLEND";
|
|
551
|
+
if (shouldWriteDepth) {
|
|
552
|
+
depth[di] = z01;
|
|
553
|
+
}
|
|
547
554
|
if (gammaOut) {
|
|
548
555
|
r = srgbEncodeLinear01(clamp(r, 0, 1));
|
|
549
556
|
g = srgbEncodeLinear01(clamp(g, 0, 1));
|
|
@@ -553,13 +560,29 @@ var SoftwareRenderer = class {
|
|
|
553
560
|
g = clamp(g, 0, 1);
|
|
554
561
|
b = clamp(b, 0, 1);
|
|
555
562
|
}
|
|
563
|
+
const dstIdx = (y * this.width + x) * 4;
|
|
564
|
+
const dstR = (this.buffer[dstIdx + 0] ?? 0) / 255;
|
|
565
|
+
const dstG = (this.buffer[dstIdx + 1] ?? 0) / 255;
|
|
566
|
+
const dstB = (this.buffer[dstIdx + 2] ?? 0) / 255;
|
|
567
|
+
const dstA = (this.buffer[dstIdx + 3] ?? 0) / 255;
|
|
568
|
+
let outR = r;
|
|
569
|
+
let outG = g;
|
|
570
|
+
let outB = b;
|
|
571
|
+
let outA = a;
|
|
572
|
+
if (alphaMode === "BLEND" && a < 1) {
|
|
573
|
+
const oneMinusA = 1 - a;
|
|
574
|
+
outR = r * a + dstR * oneMinusA;
|
|
575
|
+
outG = g * a + dstG * oneMinusA;
|
|
576
|
+
outB = b * a + dstB * oneMinusA;
|
|
577
|
+
outA = a + dstA * oneMinusA;
|
|
578
|
+
}
|
|
556
579
|
this.setPixel(
|
|
557
580
|
x,
|
|
558
581
|
y,
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
clamp(
|
|
582
|
+
clamp(outR, 0, 1) * 255 | 0,
|
|
583
|
+
clamp(outG, 0, 1) * 255 | 0,
|
|
584
|
+
clamp(outB, 0, 1) * 255 | 0,
|
|
585
|
+
clamp(outA, 0, 1) * 255 | 0
|
|
563
586
|
);
|
|
564
587
|
}
|
|
565
588
|
}
|
|
@@ -581,6 +604,142 @@ function resolveRenderOptions(options = {}) {
|
|
|
581
604
|
};
|
|
582
605
|
}
|
|
583
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 cell_size = params.cell_size ?? 1;
|
|
634
|
+
const section_size = params.section_size ?? 10;
|
|
635
|
+
const fade_distance = params.fade_distance ?? 100;
|
|
636
|
+
const fade_strength = params.fade_strength ?? 1.5;
|
|
637
|
+
const grid_color = params.grid_color ?? [0.93, 0.93, 0.93];
|
|
638
|
+
const section_color = params.section_color ?? [0.8, 0.8, 1];
|
|
639
|
+
const gamma_out = params.gamma_out ?? true;
|
|
640
|
+
const camera = params.camera;
|
|
641
|
+
const view = camera.view;
|
|
642
|
+
const proj = camera.proj;
|
|
643
|
+
const inv_view = mat44.create();
|
|
644
|
+
mat44.invert(inv_view, view);
|
|
645
|
+
const cam_pos_x = inv_view[12];
|
|
646
|
+
const cam_pos_y = inv_view[13];
|
|
647
|
+
const cam_pos_z = inv_view[14];
|
|
648
|
+
const vp = mat44.create();
|
|
649
|
+
mat44.multiply(vp, proj, view);
|
|
650
|
+
const inv_vp = mat44.create();
|
|
651
|
+
mat44.invert(inv_vp, vp);
|
|
652
|
+
for (let y = 0; y < software_renderer.height; y++) {
|
|
653
|
+
for (let x = 0; x < software_renderer.width; x++) {
|
|
654
|
+
const ndc_x = x / (software_renderer.width - 1) * 2 - 1;
|
|
655
|
+
const ndc_y = 1 - y / (software_renderer.height - 1) * 2;
|
|
656
|
+
const near_point = vec43.fromValues(ndc_x, ndc_y, -1, 1);
|
|
657
|
+
const far_point = vec43.fromValues(ndc_x, ndc_y, 1, 1);
|
|
658
|
+
vec43.transformMat4(near_point, near_point, inv_vp);
|
|
659
|
+
vec43.transformMat4(far_point, far_point, inv_vp);
|
|
660
|
+
near_point[0] /= near_point[3];
|
|
661
|
+
near_point[1] /= near_point[3];
|
|
662
|
+
near_point[2] /= near_point[3];
|
|
663
|
+
far_point[0] /= far_point[3];
|
|
664
|
+
far_point[1] /= far_point[3];
|
|
665
|
+
far_point[2] /= far_point[3];
|
|
666
|
+
const ray_dir_x = far_point[0] - near_point[0];
|
|
667
|
+
const ray_dir_y = far_point[1] - near_point[1];
|
|
668
|
+
const ray_dir_z = far_point[2] - near_point[2];
|
|
669
|
+
if (Math.abs(ray_dir_y) < 1e-6) continue;
|
|
670
|
+
const t = -near_point[1] / ray_dir_y;
|
|
671
|
+
if (t < 0 || t > 1) continue;
|
|
672
|
+
const world_x = near_point[0] + t * ray_dir_x;
|
|
673
|
+
const world_z = near_point[2] + t * ray_dir_z;
|
|
674
|
+
const dx = world_x - cam_pos_x;
|
|
675
|
+
const dz = world_z - cam_pos_z;
|
|
676
|
+
const dist = Math.sqrt(dx * dx + dz * dz);
|
|
677
|
+
const alpha = computeGridFadeAlpha({
|
|
678
|
+
dist,
|
|
679
|
+
fade_distance,
|
|
680
|
+
fade_strength
|
|
681
|
+
});
|
|
682
|
+
if (alpha <= 0) continue;
|
|
683
|
+
const g1 = computeGridLineIntensity({
|
|
684
|
+
world_x,
|
|
685
|
+
world_z,
|
|
686
|
+
cell_size,
|
|
687
|
+
dist,
|
|
688
|
+
screen_width: software_renderer.width,
|
|
689
|
+
screen_height: software_renderer.height,
|
|
690
|
+
line_thickness_multiplier: 0.8
|
|
691
|
+
});
|
|
692
|
+
const g2 = computeGridLineIntensity({
|
|
693
|
+
world_x,
|
|
694
|
+
world_z,
|
|
695
|
+
cell_size: section_size,
|
|
696
|
+
dist,
|
|
697
|
+
screen_width: software_renderer.width,
|
|
698
|
+
screen_height: software_renderer.height,
|
|
699
|
+
line_thickness_multiplier: 0.5
|
|
700
|
+
// Thicker section lines
|
|
701
|
+
});
|
|
702
|
+
const grid_strength = Math.max(g1, g2);
|
|
703
|
+
if (grid_strength <= 0) continue;
|
|
704
|
+
const final_r = grid_color[0] * (1 - g2) + section_color[0] * g2;
|
|
705
|
+
const final_g = grid_color[1] * (1 - g2) + section_color[1] * g2;
|
|
706
|
+
const final_b = grid_color[2] * (1 - g2) + section_color[2] * g2;
|
|
707
|
+
const final_alpha = grid_strength * alpha;
|
|
708
|
+
if (final_alpha <= 0.01) continue;
|
|
709
|
+
let out_r = final_r;
|
|
710
|
+
let out_g = final_g;
|
|
711
|
+
let out_b = final_b;
|
|
712
|
+
if (gamma_out) {
|
|
713
|
+
out_r = srgbEncodeLinear01(clamp(out_r, 0, 1));
|
|
714
|
+
out_g = srgbEncodeLinear01(clamp(out_g, 0, 1));
|
|
715
|
+
out_b = srgbEncodeLinear01(clamp(out_b, 0, 1));
|
|
716
|
+
} else {
|
|
717
|
+
out_r = clamp(out_r, 0, 1);
|
|
718
|
+
out_g = clamp(out_g, 0, 1);
|
|
719
|
+
out_b = clamp(out_b, 0, 1);
|
|
720
|
+
}
|
|
721
|
+
const dst_idx = (y * software_renderer.width + x) * 4;
|
|
722
|
+
const dst_r = (software_renderer.buffer[dst_idx + 0] ?? 0) / 255;
|
|
723
|
+
const dst_g = (software_renderer.buffer[dst_idx + 1] ?? 0) / 255;
|
|
724
|
+
const dst_b = (software_renderer.buffer[dst_idx + 2] ?? 0) / 255;
|
|
725
|
+
const dst_a = (software_renderer.buffer[dst_idx + 3] ?? 0) / 255;
|
|
726
|
+
const one_minus_a = 1 - final_alpha;
|
|
727
|
+
const blend_r = out_r * final_alpha + dst_r * one_minus_a;
|
|
728
|
+
const blend_g = out_g * final_alpha + dst_g * one_minus_a;
|
|
729
|
+
const blend_b = out_b * final_alpha + dst_b * one_minus_a;
|
|
730
|
+
const blend_a = final_alpha + dst_a * one_minus_a;
|
|
731
|
+
software_renderer.setPixel(
|
|
732
|
+
x,
|
|
733
|
+
y,
|
|
734
|
+
clamp(blend_r, 0, 1) * 255 | 0,
|
|
735
|
+
clamp(blend_g, 0, 1) * 255 | 0,
|
|
736
|
+
clamp(blend_b, 0, 1) * 255 | 0,
|
|
737
|
+
clamp(blend_a, 0, 1) * 255 | 0
|
|
738
|
+
);
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
|
|
584
743
|
// lib/render/renderDrawCalls.ts
|
|
585
744
|
function renderDrawCalls(drawCalls, optionsInput = {}, imageFactory = createUint8Bitmap) {
|
|
586
745
|
const options = resolveRenderOptions(optionsInput);
|
|
@@ -609,51 +768,133 @@ function renderDrawCalls(drawCalls, optionsInput = {}, imageFactory = createUint
|
|
|
609
768
|
renderer.clear([0, 0, 0, 0]);
|
|
610
769
|
}
|
|
611
770
|
const allDrawCalls = [...drawCalls];
|
|
771
|
+
let infiniteGridOptions = null;
|
|
612
772
|
if (options.grid) {
|
|
613
773
|
const userGridOptions = typeof options.grid === "boolean" ? {} : options.grid;
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
const sizeZ = aabb.max[2] - aabb.min[2];
|
|
617
|
-
const maxSize = Math.max(sizeX, sizeZ);
|
|
618
|
-
const defaultSize = Math.ceil(maxSize * 1.2 / 2) * 2;
|
|
619
|
-
const defaultOffset = {
|
|
620
|
-
x: (aabb.min[0] + aabb.max[0]) / 2,
|
|
621
|
-
y: aabb.min[1],
|
|
622
|
-
z: (aabb.min[2] + aabb.max[2]) / 2
|
|
623
|
-
};
|
|
624
|
-
const defaultGridOptions = {
|
|
625
|
-
size: defaultSize > 0 ? defaultSize : 10,
|
|
626
|
-
offset: defaultOffset
|
|
627
|
-
};
|
|
628
|
-
const finalGridOptions = {
|
|
629
|
-
...defaultGridOptions,
|
|
630
|
-
...userGridOptions,
|
|
631
|
-
offset: {
|
|
632
|
-
...defaultGridOptions.offset,
|
|
633
|
-
...userGridOptions.offset
|
|
634
|
-
}
|
|
635
|
-
};
|
|
636
|
-
allDrawCalls.push(createGrid(finalGridOptions));
|
|
637
|
-
}
|
|
638
|
-
for (const dc of allDrawCalls) {
|
|
639
|
-
if (dc.mode === 1) {
|
|
640
|
-
renderer.drawLines(dc, camera, options.gamma);
|
|
774
|
+
if (userGridOptions.infiniteGrid) {
|
|
775
|
+
infiniteGridOptions = userGridOptions;
|
|
641
776
|
} else {
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
777
|
+
const aabb = computeWorldAABB(drawCalls);
|
|
778
|
+
const sizeX = aabb.max[0] - aabb.min[0];
|
|
779
|
+
const sizeZ = aabb.max[2] - aabb.min[2];
|
|
780
|
+
const maxSize = Math.max(sizeX, sizeZ);
|
|
781
|
+
const defaultSize = Math.ceil(maxSize * 1.2 / 2) * 2;
|
|
782
|
+
const defaultOffset = {
|
|
783
|
+
x: (aabb.min[0] + aabb.max[0]) / 2,
|
|
784
|
+
y: aabb.min[1],
|
|
785
|
+
z: (aabb.min[2] + aabb.max[2]) / 2
|
|
786
|
+
};
|
|
787
|
+
const defaultGridOptions = {
|
|
788
|
+
size: defaultSize > 0 ? defaultSize : 10,
|
|
789
|
+
offset: defaultOffset
|
|
790
|
+
};
|
|
791
|
+
const finalGridOptions = {
|
|
792
|
+
...defaultGridOptions,
|
|
793
|
+
...userGridOptions,
|
|
794
|
+
offset: {
|
|
795
|
+
...defaultGridOptions.offset,
|
|
796
|
+
...userGridOptions.offset
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
allDrawCalls.push(createGrid(finalGridOptions));
|
|
650
800
|
}
|
|
651
801
|
}
|
|
802
|
+
const opaqueDraws = allDrawCalls.filter(
|
|
803
|
+
(dc) => (dc.material.alphaMode ?? "OPAQUE") === "OPAQUE"
|
|
804
|
+
);
|
|
805
|
+
const maskDraws = allDrawCalls.filter(
|
|
806
|
+
(dc) => (dc.material.alphaMode ?? "OPAQUE") === "MASK"
|
|
807
|
+
);
|
|
808
|
+
const blendDraws = allDrawCalls.filter(
|
|
809
|
+
(dc) => (dc.material.alphaMode ?? "OPAQUE") === "BLEND"
|
|
810
|
+
);
|
|
811
|
+
const renderGroup = (dcs) => {
|
|
812
|
+
for (const dc of dcs) {
|
|
813
|
+
if (dc.mode === 1) {
|
|
814
|
+
renderer.drawLines(dc, camera, options.gamma);
|
|
815
|
+
} else {
|
|
816
|
+
renderer.drawMesh(
|
|
817
|
+
dc,
|
|
818
|
+
camera,
|
|
819
|
+
{ dir: options.lightDir, ambient: options.ambient },
|
|
820
|
+
dc.material,
|
|
821
|
+
options.cull,
|
|
822
|
+
options.gamma
|
|
823
|
+
);
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
};
|
|
827
|
+
if (infiniteGridOptions) {
|
|
828
|
+
drawInfiniteGrid(renderer, {
|
|
829
|
+
camera,
|
|
830
|
+
cell_size: infiniteGridOptions.cellSize,
|
|
831
|
+
section_size: infiniteGridOptions.sectionSize,
|
|
832
|
+
fade_distance: infiniteGridOptions.fadeDistance,
|
|
833
|
+
fade_strength: infiniteGridOptions.fadeStrength,
|
|
834
|
+
grid_color: infiniteGridOptions.gridColor,
|
|
835
|
+
section_color: infiniteGridOptions.sectionColor,
|
|
836
|
+
gamma_out: options.gamma
|
|
837
|
+
});
|
|
838
|
+
}
|
|
839
|
+
renderGroup(opaqueDraws);
|
|
840
|
+
renderGroup(maskDraws);
|
|
841
|
+
renderGroup(blendDraws);
|
|
652
842
|
return { bitmap: renderer.bitmap, camera, options };
|
|
653
843
|
}
|
|
654
844
|
|
|
845
|
+
// lib/gltf/createInfiniteGrid.ts
|
|
846
|
+
import { mat4 as mat45 } from "gl-matrix";
|
|
847
|
+
function createInfiniteGrid(options = {}) {
|
|
848
|
+
const cellSize = options.cellSize ?? 1;
|
|
849
|
+
const sectionSize = options.sectionSize ?? 10;
|
|
850
|
+
const fadeDistance = options.fadeDistance ?? 100;
|
|
851
|
+
const fadeStrength = options.fadeStrength ?? 1.5;
|
|
852
|
+
const gridColor = options.gridColor ?? [0.93, 0.93, 0.93];
|
|
853
|
+
const sectionColor = options.sectionColor ?? [0.8, 0.8, 1];
|
|
854
|
+
const size = 1e3;
|
|
855
|
+
const positions = new Float32Array([
|
|
856
|
+
-size,
|
|
857
|
+
0,
|
|
858
|
+
-size,
|
|
859
|
+
size,
|
|
860
|
+
0,
|
|
861
|
+
-size,
|
|
862
|
+
size,
|
|
863
|
+
0,
|
|
864
|
+
size,
|
|
865
|
+
-size,
|
|
866
|
+
0,
|
|
867
|
+
size
|
|
868
|
+
]);
|
|
869
|
+
const indices = new Uint32Array([0, 1, 2, 0, 2, 3]);
|
|
870
|
+
const model = mat45.create();
|
|
871
|
+
const offset = options.offset ?? {};
|
|
872
|
+
mat45.fromTranslation(model, [offset.x ?? 0, offset.y ?? 0, offset.z ?? 0]);
|
|
873
|
+
return {
|
|
874
|
+
positions,
|
|
875
|
+
indices,
|
|
876
|
+
normals: null,
|
|
877
|
+
uvs: null,
|
|
878
|
+
model,
|
|
879
|
+
material: {
|
|
880
|
+
baseColorFactor: [1, 1, 1, 1],
|
|
881
|
+
baseColorTexture: null,
|
|
882
|
+
alphaMode: "BLEND"
|
|
883
|
+
},
|
|
884
|
+
mode: 4,
|
|
885
|
+
// triangles
|
|
886
|
+
isInfiniteGrid: true,
|
|
887
|
+
cellSize,
|
|
888
|
+
sectionSize,
|
|
889
|
+
fadeDistance,
|
|
890
|
+
fadeStrength,
|
|
891
|
+
gridColor,
|
|
892
|
+
sectionColor
|
|
893
|
+
};
|
|
894
|
+
}
|
|
895
|
+
|
|
655
896
|
// lib/gltf/createSceneFromGLTF.ts
|
|
656
|
-
import { mat4 as
|
|
897
|
+
import { mat4 as mat46 } from "gl-matrix";
|
|
657
898
|
var COMPONENT_INFO = {
|
|
658
899
|
5120: {
|
|
659
900
|
name: "BYTE",
|
|
@@ -851,17 +1092,17 @@ function readIndices(ctx, accessorIndex) {
|
|
|
851
1092
|
}
|
|
852
1093
|
function nodeLocalMatrix(node) {
|
|
853
1094
|
if (node.matrix) {
|
|
854
|
-
const m2 =
|
|
1095
|
+
const m2 = mat46.create();
|
|
855
1096
|
for (let i = 0; i < 16; i++) m2[i] = node.matrix[i];
|
|
856
1097
|
return m2;
|
|
857
1098
|
}
|
|
858
1099
|
const translation = node.translation || [0, 0, 0];
|
|
859
1100
|
const rotation = node.rotation || [0, 0, 0, 1];
|
|
860
1101
|
const scale = node.scale || [1, 1, 1];
|
|
861
|
-
const m =
|
|
862
|
-
const tmp =
|
|
863
|
-
|
|
864
|
-
|
|
1102
|
+
const m = mat46.create();
|
|
1103
|
+
const tmp = mat46.create();
|
|
1104
|
+
mat46.fromRotationTranslationScale(tmp, rotation, translation, scale);
|
|
1105
|
+
mat46.copy(m, tmp);
|
|
865
1106
|
return m;
|
|
866
1107
|
}
|
|
867
1108
|
function getMaterial(gltf, textures, images, materialIndex) {
|
|
@@ -877,7 +1118,14 @@ function getMaterial(gltf, textures, images, materialIndex) {
|
|
|
877
1118
|
texImg = images[imageIndex] || null;
|
|
878
1119
|
}
|
|
879
1120
|
}
|
|
880
|
-
|
|
1121
|
+
const alphaMode = typeof material.alphaMode === "string" ? material.alphaMode : "OPAQUE";
|
|
1122
|
+
const alphaCutoff = typeof material.alphaCutoff === "number" ? material.alphaCutoff : 0.5;
|
|
1123
|
+
return {
|
|
1124
|
+
baseColorFactor: factor,
|
|
1125
|
+
baseColorTexture: texImg,
|
|
1126
|
+
alphaMode,
|
|
1127
|
+
alphaCutoff
|
|
1128
|
+
};
|
|
881
1129
|
}
|
|
882
1130
|
function createSceneFromGLTF(gltf, resources) {
|
|
883
1131
|
const ctx = { gltf, buffers: resources.buffers };
|
|
@@ -892,8 +1140,8 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
892
1140
|
const node = nodes[nodeIndex];
|
|
893
1141
|
if (!node) return;
|
|
894
1142
|
const local = nodeLocalMatrix(node);
|
|
895
|
-
const world =
|
|
896
|
-
|
|
1143
|
+
const world = mat46.create();
|
|
1144
|
+
mat46.multiply(world, parentMatrix, local);
|
|
897
1145
|
if (Number.isInteger(node.mesh)) {
|
|
898
1146
|
const mesh = meshes[node.mesh];
|
|
899
1147
|
if (mesh) {
|
|
@@ -931,7 +1179,7 @@ function createSceneFromGLTF(gltf, resources) {
|
|
|
931
1179
|
traverse(childIndex, world);
|
|
932
1180
|
}
|
|
933
1181
|
}
|
|
934
|
-
const identity =
|
|
1182
|
+
const identity = mat46.create();
|
|
935
1183
|
for (const rootIndex of scene.nodes || []) {
|
|
936
1184
|
traverse(rootIndex, identity);
|
|
937
1185
|
}
|
|
@@ -1335,9 +1583,11 @@ export {
|
|
|
1335
1583
|
computeSmoothNormals,
|
|
1336
1584
|
computeWorldAABB,
|
|
1337
1585
|
createGrid,
|
|
1586
|
+
createInfiniteGrid,
|
|
1338
1587
|
createSceneFromGLTF,
|
|
1339
1588
|
createUint8Bitmap,
|
|
1340
1589
|
decodeImageFromBuffer,
|
|
1590
|
+
drawInfiniteGrid,
|
|
1341
1591
|
encodePNGToBuffer,
|
|
1342
1592
|
getDefaultRenderOptions,
|
|
1343
1593
|
isJPG,
|