tela.js 1.2.6 → 1.2.7

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 CHANGED
@@ -78,7 +78,7 @@ loop(({ time, dt }) => {
78
78
  And run it: `node index.mjs` / `bun index.js`
79
79
 
80
80
  > Note: [Attention to running node with ES6 imports module](https://nodejs.org/api/esm.html#modules-ecmascript-modules)
81
-
81
+ > Note: If you're using `bun` and the `Window`, which uses `@kmamal/sdl` as dependency, make sure to run `bun pm trust @kmamal/sdl`.
82
82
 
83
83
  ## Generate images and videos
84
84
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tela.js",
3
- "version": "1.2.6",
3
+ "version": "1.2.7",
4
4
  "author": "Pedroth",
5
5
  "repository": {
6
6
  "type": "git",
@@ -234,10 +234,11 @@ function rasterTriangle({ canvas, camera, elem, w, h, zBuffer, params }) {
234
234
  }
235
235
  const [i, j] = canvas.canvas2grid(x, y);
236
236
  const zBufferIndex = Math.floor(w * i + j);
237
- if (z < zBuffer[zBufferIndex]) {
237
+ if (z < zBuffer[zBufferIndex] && c.alpha >= 1) {
238
238
  zBuffer[zBufferIndex] = z;
239
- return Math.random() < c.alpha ? c : undefined;
239
+ return c;
240
240
  }
241
+ return Math.random() < c.alpha ? c : undefined;
241
242
  }
242
243
  canvas.drawTriangle(intPoints[0], intPoints[1], intPoints[2], shader);
243
244
  }
@@ -7,7 +7,7 @@ import { MAX_8BIT, RAD2DEG } from "../Utils/Constants.js";
7
7
  */
8
8
  export default class Color {
9
9
  constructor(rgb, alpha = 1.0) {
10
- this.rgb = rgb;
10
+ this.rgb = rgb.map(x => Number.isNaN(x) ? 0 : x);
11
11
  this.alpha = alpha;
12
12
  }
13
13
 
@@ -112,4 +112,5 @@ export default class Color {
112
112
  static WHITE = Color.ofRGB(1, 1, 1);
113
113
  static GRAY = Color.ofRGB(0.5, 0.5, 0.5);
114
114
  static GREY = Color.ofRGB(0.5, 0.5, 0.5);
115
+ static BROWN = Color.ofRGB(0.345,0.2235,0.1529);
115
116
  }
@@ -26,10 +26,11 @@ export default class Box {
26
26
  normalToPoint(pointVec) {
27
27
  const epsilon = 1e-3;
28
28
  const n = pointVec.dim;
29
+ const En = Vec.e(n);
29
30
  const grad = [];
30
31
  const d = this.distanceToPoint(pointVec);
31
32
  for (let i = 0; i < n; i++) {
32
- grad.push(this.distanceToPoint(pointVec.add(Vec.e(n)(i).scale(epsilon))) - d)
33
+ grad.push(this.distanceToPoint(pointVec.add(En(i).scale(epsilon))) - d)
33
34
  }
34
35
  let sign = Math.sign(d);
35
36
  sign = sign === 0 ? 1 : sign;
@@ -6,7 +6,7 @@ import { deserialize as deserializeImage } from "../Tela/utils.js";
6
6
  import { generateUniqueID } from "../Utils/Utils.js";
7
7
 
8
8
  export default class Triangle {
9
- constructor({ name, positions, colors, texCoords, normals, texture, emissive, material }) {
9
+ constructor({ name, positions, colors, texCoords, normals, texture, emissive, material, radius }) {
10
10
  this.name = name;
11
11
  this.colors = colors;
12
12
  this.normals = normals;
@@ -15,6 +15,7 @@ export default class Triangle {
15
15
  this.texCoords = texCoords;
16
16
  this.emissive = emissive;
17
17
  this.material = material;
18
+ this.radius = radius;
18
19
  this.edges = [];
19
20
  const n = this.positions.length;
20
21
  for (let i = 0; i < n; i++) {
@@ -25,6 +26,16 @@ export default class Triangle {
25
26
  const v = this.tangents[1];
26
27
  const cross = u.cross(v);
27
28
  this.faceNormal = Number.isFinite(cross) ? Vec3(0, 0, cross) : cross?.normalize();
29
+
30
+ // precompute inverse of matrix [u, v]^T [u, v]
31
+ const a = u.dot(u);
32
+ const b = u.dot(v);
33
+ const c = b;
34
+ const d = v.dot(v);
35
+ const detInv = 1 / (a * d - b * c);
36
+ this.isDegenerate = !Number.isFinite(detInv) || Number.isNaN(detInv)
37
+ this.invU1 = Vec2(d, -b).scale(detInv)
38
+ this.invU2 = Vec2(-c, a).scale(detInv);
28
39
  }
29
40
 
30
41
  getBoundingBox() {
@@ -34,11 +45,26 @@ export default class Triangle {
34
45
  }
35
46
 
36
47
  distanceToPoint(p) {
37
- // TODO
38
- return Number.MAX_VALUE;
48
+ const r = p.sub(this.positions[0]);
49
+ if (this.isDegenerate) return r.length() - this.radius;
50
+ const x = Vec2(this.tangents[0].dot(r), this.tangents[1].dot(r));
51
+ let alpha = Vec2(this.invU1.dot(x), this.invU2.dot(x)).map(x => x < 0 ? 0 : x);
52
+ const sum = alpha.fold((e, x) => e + x, 0)
53
+ if (sum > 1) {
54
+ alpha = alpha.scale(1 / sum);
55
+ }
56
+ const pointOnTriangle = this.positions[0]
57
+ .add(
58
+ this.tangents[0].scale(alpha.x)
59
+ .add(
60
+ this.tangents[1].scale(alpha.y)
61
+ )
62
+ )
63
+ return p.sub(pointOnTriangle).length() - this.radius;
39
64
  }
40
65
 
41
66
  normalToPoint(p) {
67
+ // fixes problem in ray tracing
42
68
  const r = p.sub(this.positions[0]);
43
69
  const dot = this.faceNormal.dot(r);
44
70
  return dot < 1e-3 ? this.faceNormal : this.faceNormal.scale(-1);
@@ -112,6 +138,7 @@ class TriangleBuilder {
112
138
  this._colors = indx.map(() => Color.BLACK);
113
139
  this._positions = indx.map(() => Vec3());
114
140
  this._texCoords = [Vec2(), Vec2(1, 0), Vec2(0, 1)];
141
+ this._radius = 1;
115
142
  this._emissive = false;
116
143
  this._material = Diffuse();
117
144
  }
@@ -121,6 +148,11 @@ class TriangleBuilder {
121
148
  return this;
122
149
  }
123
150
 
151
+ radius(radius) {
152
+ this._radius = radius;
153
+ return this;
154
+ }
155
+
124
156
  positions(v1, v2, v3) {
125
157
  if ([v1, v2, v3].some(x => !x)) return this;
126
158
  this._positions = [v1, v2, v3];
@@ -163,6 +195,7 @@ class TriangleBuilder {
163
195
  build() {
164
196
  const attrs = {
165
197
  name: this._name,
198
+ radius: this._radius,
166
199
  colors: this._colors,
167
200
  normals: this._normals,
168
201
  positions: this._positions,