poppygl 0.0.29 → 0.0.30

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.
Files changed (2) hide show
  1. package/dist/index.js +84 -3
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -512,6 +512,77 @@ function srgbDecodeToLinear01(srgb) {
512
512
  // lib/utils/clamp.ts
513
513
  var clamp = (value, min, max) => Math.max(min, Math.min(max, value));
514
514
 
515
+ // lib/render/clipMeshToNearPlane.ts
516
+ function clipMeshToNearPlane(mesh, mvp) {
517
+ const count = mesh.positions.length / 3;
518
+ const distances = new Float64Array(count);
519
+ let needsClipping = false;
520
+ for (let i = 0; i < count; i++) {
521
+ const distance = (mvp[2] + mvp[3]) * mesh.positions[i * 3] + (mvp[6] + mvp[7]) * mesh.positions[i * 3 + 1] + (mvp[10] + mvp[11]) * mesh.positions[i * 3 + 2] + mvp[14] + mvp[15];
522
+ distances[i] = distance;
523
+ if (!(distance >= 0)) needsClipping = true;
524
+ }
525
+ if (!needsClipping) return mesh;
526
+ const positions = Array.from(mesh.positions);
527
+ const normals = mesh.normals ? Array.from(mesh.normals) : null;
528
+ const uvs = mesh.uvs ? Array.from(mesh.uvs) : null;
529
+ const colors = mesh.colors ? Array.from(mesh.colors) : null;
530
+ const indices = [];
531
+ const sourceIndices = mesh.indices ?? Uint32Array.from({ length: count }, (_, i) => i);
532
+ const intersections = /* @__PURE__ */ new Map();
533
+ const intersect = (a, b) => {
534
+ if (a > b) [a, b] = [b, a];
535
+ if (distances[a] === 0) return a;
536
+ if (distances[b] === 0) return b;
537
+ const key = `${a}:${b}`;
538
+ const cached = intersections.get(key);
539
+ if (cached !== void 0) return cached;
540
+ const t = distances[a] / (distances[a] - distances[b]);
541
+ const index = positions.length / 3;
542
+ const interpolate = (values, size) => {
543
+ if (!values) return;
544
+ for (let k = 0; k < size; k++) {
545
+ const start = values[a * size + k];
546
+ values.push(start + t * (values[b * size + k] - start));
547
+ }
548
+ };
549
+ interpolate(positions, 3);
550
+ interpolate(normals, 3);
551
+ interpolate(uvs, 2);
552
+ interpolate(colors, 3);
553
+ intersections.set(key, index);
554
+ return index;
555
+ };
556
+ for (let i = 0; i < sourceIndices.length; i += 3) {
557
+ const triangle = [
558
+ sourceIndices[i],
559
+ sourceIndices[i + 1],
560
+ sourceIndices[i + 2]
561
+ ];
562
+ if (triangle.some((vertex) => !Number.isFinite(distances[vertex]))) continue;
563
+ const polygon = [];
564
+ for (let j = 0; j < 3; j++) {
565
+ const a = triangle[j];
566
+ const b = triangle[(j + 1) % 3];
567
+ const aInside = distances[a] >= 0;
568
+ const bInside = distances[b] >= 0;
569
+ if (aInside) polygon.push(a);
570
+ if (aInside !== bInside) polygon.push(intersect(a, b));
571
+ }
572
+ for (let j = 1; j + 1 < polygon.length; j++) {
573
+ indices.push(polygon[0], polygon[j], polygon[j + 1]);
574
+ }
575
+ }
576
+ return {
577
+ ...mesh,
578
+ positions: new Float32Array(positions),
579
+ normals: normals ? new Float32Array(normals) : null,
580
+ uvs: uvs ? new Float32Array(uvs) : null,
581
+ colors: colors ? new Float32Array(colors) : null,
582
+ indices: new Uint32Array(indices)
583
+ };
584
+ }
585
+
515
586
  // lib/render/SoftwareRenderer.ts
516
587
  var SoftwareRenderer = class {
517
588
  width;
@@ -682,15 +753,15 @@ var SoftwareRenderer = class {
682
753
  return out;
683
754
  }
684
755
  drawMesh(mesh, camera, light, material, cullBackFaces = true, gammaOut = true) {
685
- const { positions, normals, uvs, indices, model, colors } = mesh;
756
+ let { positions, normals, uvs, indices, model, colors } = mesh;
686
757
  const view = camera.view;
687
758
  const proj = camera.proj;
688
759
  const mvp = mat43.create();
689
760
  mat43.multiply(mvp, proj, mat43.multiply(mat43.create(), view, model));
690
761
  const normalMat = mat3.create();
691
762
  mat3.normalFromMat4(normalMat, model);
692
- const vertexCount = positions.length / 3 | 0;
693
- const idx = indices ?? (() => {
763
+ let vertexCount = positions.length / 3 | 0;
764
+ let idx = indices ?? (() => {
694
765
  const a = new Uint32Array(vertexCount);
695
766
  for (let i = 0; i < vertexCount; i++) a[i] = i;
696
767
  return a;
@@ -699,6 +770,16 @@ var SoftwareRenderer = class {
699
770
  if (!useNormals) {
700
771
  useNormals = computeSmoothNormals(positions, idx);
701
772
  }
773
+ const clipped = clipMeshToNearPlane(
774
+ { ...mesh, normals: useNormals, indices: idx },
775
+ mvp
776
+ );
777
+ positions = clipped.positions;
778
+ useNormals = clipped.normals;
779
+ uvs = clipped.uvs;
780
+ colors = clipped.colors;
781
+ idx = clipped.indices;
782
+ vertexCount = positions.length / 3;
702
783
  const vScreen = new Array(vertexCount);
703
784
  const vInvW = new Float32Array(vertexCount);
704
785
  const vNDCz = new Float32Array(vertexCount);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "poppygl",
3
3
  "main": "dist/index.js",
4
- "version": "0.0.29",
4
+ "version": "0.0.30",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/tscircuit/poppygl.git"