@genocode/render 0.0.0-stage → 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Jan Piorek
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -1,3 +1,9 @@
1
- # Temporary Holding Version
1
+ # @genocode/render
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Draws [GenoCode](https://github.com/genocode-org/GenoCode) creatures, textures and backgrounds:
4
+ in the browser with three.js (`CreatureView`), or into an image without a browser (`rasterize`),
5
+ with the same shapes, camera and lights.
6
+
7
+ While the version is 0.x, any minor release may change the API.
8
+
9
+ MIT licensed.
@@ -0,0 +1,15 @@
1
+ import type { LaidShape, ShapeName } from "@genocode/core";
2
+ import { BufferGeometry } from "three";
3
+ export type Detail = "high" | "low";
4
+ /**
5
+ * The geometry for a shape. Mirrored shapes need their triangles wound the other way, so that
6
+ * their outsides still face outwards after the mirroring in their placement.
7
+ */
8
+ export declare function shapeGeometry(shape: ShapeName, mirrored: boolean, detail?: Detail): BufferGeometry;
9
+ export interface Bounds {
10
+ centre: [number, number, number];
11
+ radius: number;
12
+ }
13
+ /** A sphere around all the shapes, from the corners of each shape's 1×1×1 box. */
14
+ export declare function creatureBounds(shapes: readonly LaidShape[]): Bounds;
15
+ //# sourceMappingURL=geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.d.ts","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EAEL,cAAc,EAIf,MAAM,OAAO,CAAC;AAEf,MAAM,MAAM,MAAM,GAAG,MAAM,GAAG,KAAK,CAAC;AAuCpC;;;GAGG;AACH,wBAAgB,aAAa,CAC3B,KAAK,EAAE,SAAS,EAChB,QAAQ,EAAE,OAAO,EACjB,MAAM,GAAE,MAAe,GACtB,cAAc,CAQhB;AAED,MAAM,WAAW,MAAM;IACrB,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,kFAAkF;AAClF,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,GAAG,MAAM,CAyBnE"}
@@ -0,0 +1,79 @@
1
+ // The six shapes, exactly as docs/LANGUAGE.md section 12 defines them: each fits a 1×1×1 box
2
+ // centred on the turtle, with its length along the heading (+z).
3
+ import { BoxGeometry, BufferGeometry, CylinderGeometry, SphereGeometry, TorusGeometry, } from "three";
4
+ function make(shape, detail) {
5
+ const high = detail === "high";
6
+ switch (shape) {
7
+ case "cube":
8
+ return new BoxGeometry(1, 1, 1);
9
+ case "ball":
10
+ return new SphereGeometry(0.5, high ? 32 : 16, high ? 20 : 10);
11
+ case "tube":
12
+ // three's cylinders run along y; turning them about x points them along +z.
13
+ return new CylinderGeometry(0.5, 0.5, 1, high ? 32 : 16, 1).rotateX(Math.PI / 2);
14
+ case "cone":
15
+ return new CylinderGeometry(0, 0.5, 1, high ? 32 : 16, 1).rotateX(Math.PI / 2);
16
+ case "ring":
17
+ return new TorusGeometry(0.4, 0.1, high ? 12 : 8, high ? 48 : 24);
18
+ case "donut":
19
+ return new TorusGeometry(1 / 3, 1 / 6, high ? 16 : 10, high ? 48 : 24);
20
+ }
21
+ }
22
+ /** The same geometry with each triangle's corners in the opposite order, for mirrored shapes. */
23
+ function flipWinding(g) {
24
+ const flipped = g.clone();
25
+ const index = flipped.getIndex();
26
+ if (index) {
27
+ const a = index.array;
28
+ for (let i = 0; i < a.length; i += 3) {
29
+ const t = a[i + 1];
30
+ a[i + 1] = a[i + 2];
31
+ a[i + 2] = t;
32
+ }
33
+ index.needsUpdate = true;
34
+ }
35
+ return flipped;
36
+ }
37
+ const cache = new Map();
38
+ /**
39
+ * The geometry for a shape. Mirrored shapes need their triangles wound the other way, so that
40
+ * their outsides still face outwards after the mirroring in their placement.
41
+ */
42
+ export function shapeGeometry(shape, mirrored, detail = "high") {
43
+ const key = `${shape}/${mirrored}/${detail}`;
44
+ let g = cache.get(key);
45
+ if (!g) {
46
+ g = mirrored ? flipWinding(shapeGeometry(shape, false, detail)) : make(shape, detail);
47
+ cache.set(key, g);
48
+ }
49
+ return g;
50
+ }
51
+ /** A sphere around all the shapes, from the corners of each shape's 1×1×1 box. */
52
+ export function creatureBounds(shapes) {
53
+ if (shapes.length === 0)
54
+ return { centre: [0, 0, 0], radius: 1 };
55
+ const lo = [Infinity, Infinity, Infinity];
56
+ const hi = [-Infinity, -Infinity, -Infinity];
57
+ for (const s of shapes) {
58
+ const m = s.matrix;
59
+ for (const x of [-0.5, 0.5]) {
60
+ for (const y of [-0.5, 0.5]) {
61
+ for (const z of [-0.5, 0.5]) {
62
+ for (let i = 0; i < 3; i++) {
63
+ const v = m[i] * x + m[4 + i] * y + m[8 + i] * z + m[12 + i];
64
+ lo[i] = Math.min(lo[i], v);
65
+ hi[i] = Math.max(hi[i], v);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
71
+ const centre = [
72
+ (lo[0] + hi[0]) / 2,
73
+ (lo[1] + hi[1]) / 2,
74
+ (lo[2] + hi[2]) / 2,
75
+ ];
76
+ const radius = Math.max(1e-3, Math.hypot(hi[0] - lo[0], hi[1] - lo[1], hi[2] - lo[2]) / 2);
77
+ return { centre, radius };
78
+ }
79
+ //# sourceMappingURL=geometry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"geometry.js","sourceRoot":"","sources":["../src/geometry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { creatureBounds, shapeGeometry, type Bounds, type Detail } from "./geometry.js";
2
+ export { backgroundRamp, DEFAULT_BACKGROUND, FIELD_OF_VIEW, frameCamera, LIGHTS, type CameraPlacement, } from "./look.js";
3
+ export { rasterize, type Image, type RasterOptions } from "./software.js";
4
+ export { CreatureView, Thumbnails } from "./webgl.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,KAAK,MAAM,EAAE,KAAK,MAAM,EAAE,MAAM,eAAe,CAAC;AACxF,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,MAAM,EACN,KAAK,eAAe,GACrB,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAE,KAAK,KAAK,EAAE,KAAK,aAAa,EAAE,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,7 @@
1
+ // Draws GenoCode creatures: in the browser with three.js (CreatureView), or into an image without
2
+ // a browser (rasterize), with the same shapes, camera and lights.
3
+ export { creatureBounds, shapeGeometry } from "./geometry.js";
4
+ export { backgroundRamp, DEFAULT_BACKGROUND, FIELD_OF_VIEW, frameCamera, LIGHTS, } from "./look.js";
5
+ export { rasterize } from "./software.js";
6
+ export { CreatureView, Thumbnails } from "./webgl.js";
7
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,kGAAkG;AAClG,kEAAkE;AAElE,OAAO,EAAE,cAAc,EAAE,aAAa,EAA4B,MAAM,eAAe,CAAC;AACxF,OAAO,EACL,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,WAAW,EACX,MAAM,GAEP,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,SAAS,EAAkC,MAAM,eAAe,CAAC;AAC1E,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC"}
package/dist/look.d.ts ADDED
@@ -0,0 +1,39 @@
1
+ import { type Colour, type Value } from "@genocode/core";
2
+ import type { Bounds } from "./geometry.js";
3
+ export declare const FIELD_OF_VIEW = 40;
4
+ export interface CameraPlacement {
5
+ position: [number, number, number];
6
+ target: [number, number, number];
7
+ near: number;
8
+ far: number;
9
+ }
10
+ /** Looks at the creature's face (the turtle starts facing +z, towards the viewer), from a little above. */
11
+ export declare function frameCamera(bounds: Bounds, aspect: number): CameraPlacement;
12
+ /** Directions point towards the light, in world space. */
13
+ export declare const LIGHTS: {
14
+ ambient: number;
15
+ key: {
16
+ direction: [number, number, number];
17
+ strength: number;
18
+ };
19
+ fill: {
20
+ direction: [number, number, number];
21
+ strength: number;
22
+ };
23
+ };
24
+ /** Shininess (the specular exponent) for a shape's sharpness, 0–1. */
25
+ export declare function shininess(sharpness: number): number;
26
+ export type Rgb = [number, number, number];
27
+ /** The background when a creature has none: a dark blue, lighter towards the top. */
28
+ export declare const DEFAULT_BACKGROUND: {
29
+ bottom: Rgb;
30
+ top: Rgb;
31
+ };
32
+ export declare function colourRgb(c: Colour): Rgb;
33
+ /**
34
+ * Turns a background's fill into a vertical ramp of colours, sampled at `rows` points from the
35
+ * bottom (0) to the top (1). Patterns aren't drawn yet (roadmap phase 7), so they fall back to the
36
+ * default background tinted with their hue.
37
+ */
38
+ export declare function backgroundRamp(fill: Value | undefined, rows: number): Rgb[];
39
+ //# sourceMappingURL=look.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look.d.ts","sourceRoot":"","sources":["../src/look.ts"],"names":[],"mappings":"AAGA,OAAO,EAAyB,KAAK,MAAM,EAAE,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAChF,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,eAAO,MAAM,aAAa,KAAK,CAAC;AAEhC,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACnC,MAAM,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;CACb;AAED,2GAA2G;AAC3G,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,eAAe,CAY3E;AAED,0DAA0D;AAC1D,eAAO,MAAM,MAAM;IACjB,OAAO;IACP,GAAG;QAAI,SAAS;QAAwB,QAAQ;;IAChD,IAAI;QAAI,SAAS;QAA4B,QAAQ;;CACtD,CAAC;AAEF,sEAAsE;AACtE,wBAAgB,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAEnD;AAOD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;AAE3C,qFAAqF;AACrF,eAAO,MAAM,kBAAkB,EAAE;IAAE,MAAM,EAAE,GAAG,CAAC;IAAC,GAAG,EAAE,GAAG,CAAA;CAGvD,CAAC;AAEF,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,CAExC;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,EAAE,IAAI,EAAE,MAAM,GAAG,GAAG,EAAE,CAO3E"}
package/dist/look.js ADDED
@@ -0,0 +1,77 @@
1
+ // What both renderers share, so a creature looks the same in the browser and in `genie render`:
2
+ // camera framing, lights, and how backgrounds are drawn.
3
+ import { sampleGradient, toRgb } from "@genocode/core";
4
+ export const FIELD_OF_VIEW = 40;
5
+ /** Looks at the creature's face (the turtle starts facing +z, towards the viewer), from a little above. */
6
+ export function frameCamera(bounds, aspect) {
7
+ const half = (FIELD_OF_VIEW * Math.PI) / 360;
8
+ // The narrower of the two directions decides how far back the camera goes.
9
+ const fit = Math.min(Math.sin(half), Math.sin(Math.atan(Math.tan(half) * aspect)));
10
+ const distance = (bounds.radius / fit) * 1.1;
11
+ const [x, y, z] = bounds.centre;
12
+ return {
13
+ position: [x, y + bounds.radius * 0.3, z + distance],
14
+ target: [x, y, z],
15
+ near: Math.max(distance - bounds.radius * 2, distance / 1000),
16
+ far: distance + bounds.radius * 4,
17
+ };
18
+ }
19
+ /** Directions point towards the light, in world space. */
20
+ export const LIGHTS = {
21
+ ambient: 0.35,
22
+ key: { direction: normalise([1, 2, 3]), strength: 0.85 },
23
+ fill: { direction: normalise([-2, -0.5, 1]), strength: 0.3 },
24
+ };
25
+ /** Shininess (the specular exponent) for a shape's sharpness, 0–1. */
26
+ export function shininess(sharpness) {
27
+ return 4 + sharpness * 124;
28
+ }
29
+ function normalise(v) {
30
+ const l = Math.hypot(...v);
31
+ return [v[0] / l, v[1] / l, v[2] / l];
32
+ }
33
+ /** The background when a creature has none: a dark blue, lighter towards the top. */
34
+ export const DEFAULT_BACKGROUND = {
35
+ bottom: [0.03, 0.04, 0.08],
36
+ top: [0.13, 0.16, 0.26],
37
+ };
38
+ export function colourRgb(c) {
39
+ return toRgb(c);
40
+ }
41
+ /**
42
+ * Turns a background's fill into a vertical ramp of colours, sampled at `rows` points from the
43
+ * bottom (0) to the top (1). Patterns aren't drawn yet (roadmap phase 7), so they fall back to the
44
+ * default background tinted with their hue.
45
+ */
46
+ export function backgroundRamp(fill, rows) {
47
+ const out = [];
48
+ for (let i = 0; i < rows; i++) {
49
+ const t = rows === 1 ? 0 : i / (rows - 1);
50
+ out.push(backgroundAt(fill, t));
51
+ }
52
+ return out;
53
+ }
54
+ function mixRgb(a, b, t) {
55
+ return [a[0] + (b[0] - a[0]) * t, a[1] + (b[1] - a[1]) * t, a[2] + (b[2] - a[2]) * t];
56
+ }
57
+ function backgroundAt(fill, t) {
58
+ const fallback = mixRgb(DEFAULT_BACKGROUND.bottom, DEFAULT_BACKGROUND.top, t);
59
+ if (fill === undefined || typeof fill !== "object")
60
+ return fallback;
61
+ switch (fill.type) {
62
+ case "colour":
63
+ return colourRgb(fill);
64
+ case "gradient":
65
+ // Blended in HSV, the short way round the hue circle, as the language defines.
66
+ return colourRgb(sampleGradient(fill, t));
67
+ case "pattern": {
68
+ if (fill.kind === null)
69
+ return fallback;
70
+ const tint = toRgb({ type: "colour", h: fill.hue, s: 0.6, v: 0.35, a: 1 });
71
+ return mixRgb(fallback, tint, 0.5 + 0.3 * t);
72
+ }
73
+ default:
74
+ return fallback;
75
+ }
76
+ }
77
+ //# sourceMappingURL=look.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"look.js","sourceRoot":"","sources":["../src/look.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import { type LaidShape, type Value } from "@genocode/core";
2
+ export interface RasterOptions {
3
+ width: number;
4
+ height: number;
5
+ /** The background's fill (a colour, gradient or pattern); the default background if left out. */
6
+ background?: Value | undefined;
7
+ /** Samples per pixel along each side, for smoother edges. Default 2. */
8
+ supersample?: number;
9
+ }
10
+ export interface Image {
11
+ width: number;
12
+ height: number;
13
+ /** RGBA, 8 bits per channel, rows from the top. */
14
+ data: Uint8ClampedArray;
15
+ }
16
+ export declare function rasterize(shapes: readonly LaidShape[], options: RasterOptions): Image;
17
+ //# sourceMappingURL=software.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"software.d.ts","sourceRoot":"","sources":["../src/software.ts"],"names":[],"mappings":"AAGA,OAAO,EAAS,KAAK,SAAS,EAAE,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAInE,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,iGAAiG;IACjG,UAAU,CAAC,EAAE,KAAK,GAAG,SAAS,CAAC;IAC/B,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,mDAAmD;IACnD,IAAI,EAAE,iBAAiB,CAAC;CACzB;AA2CD,wBAAgB,SAAS,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,OAAO,EAAE,aAAa,GAAG,KAAK,CAyIrF"}
@@ -0,0 +1,184 @@
1
+ // A small software renderer: draws a creature into an RGBA image without a browser, for
2
+ // `genie render`, thumbnails and tests. It uses the same shapes, camera and lights as the WebGL view.
3
+ import { toRgb } from "@genocode/core";
4
+ import { creatureBounds, shapeGeometry } from "./geometry.js";
5
+ import { backgroundRamp, FIELD_OF_VIEW, frameCamera, LIGHTS, shininess } from "./look.js";
6
+ function sub(a, b) {
7
+ return [a[0] - b[0], a[1] - b[1], a[2] - b[2]];
8
+ }
9
+ function dot(a, b) {
10
+ return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];
11
+ }
12
+ function cross(a, b) {
13
+ return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];
14
+ }
15
+ function normalise(a) {
16
+ const l = Math.hypot(a[0], a[1], a[2]) || 1;
17
+ return [a[0] / l, a[1] / l, a[2] / l];
18
+ }
19
+ /** The inverse transpose of a placement's 3×3 part, which carries normals. Row-major result. */
20
+ function normalMatrix(m) {
21
+ // Columns of the 3×3 part.
22
+ const a = [m[0], m[1], m[2]];
23
+ const b = [m[4], m[5], m[6]];
24
+ const c = [m[8], m[9], m[10]];
25
+ const bc = cross(b, c);
26
+ const ca = cross(c, a);
27
+ const ab = cross(a, b);
28
+ const det = dot(a, bc);
29
+ if (det === 0 || !Number.isFinite(det))
30
+ return undefined;
31
+ // The inverse's rows are bc, ca, ab over det; its transpose's columns are those, i.e. rows of N.
32
+ return [
33
+ bc[0] / det,
34
+ ca[0] / det,
35
+ ab[0] / det,
36
+ bc[1] / det,
37
+ ca[1] / det,
38
+ ab[1] / det,
39
+ bc[2] / det,
40
+ ca[2] / det,
41
+ ab[2] / det,
42
+ ];
43
+ }
44
+ export function rasterize(shapes, options) {
45
+ const ss = Math.max(1, Math.round(options.supersample ?? 2));
46
+ const W = options.width * ss;
47
+ const H = options.height * ss;
48
+ const colour = new Float32Array(W * H * 3);
49
+ const depth = new Float32Array(W * H); // 1 / distance; bigger is nearer, 0 is empty
50
+ const ramp = backgroundRamp(options.background, H);
51
+ for (let y = 0; y < H; y++) {
52
+ const c = ramp[H - 1 - y];
53
+ for (let x = 0; x < W; x++)
54
+ colour.set(c, (y * W + x) * 3);
55
+ }
56
+ const cam = frameCamera(creatureBounds(shapes), options.width / options.height);
57
+ const eye = cam.position;
58
+ const forward = normalise(sub(cam.target, eye));
59
+ const right = normalise(cross(forward, [0, 1, 0]));
60
+ const up = cross(right, forward);
61
+ const focal = H / 2 / Math.tan((FIELD_OF_VIEW * Math.PI) / 360);
62
+ const lights = [LIGHTS.key, LIGHTS.fill];
63
+ const opaque = shapes.filter((s) => s.colour.a >= 0.999);
64
+ const seeThrough = shapes
65
+ .filter((s) => s.colour.a < 0.999 && s.colour.a > 0)
66
+ .map((s) => ({ s, d: dot(sub([s.matrix[12], s.matrix[13], s.matrix[14]], eye), forward) }))
67
+ .sort((p, q) => q.d - p.d)
68
+ .map((p) => p.s);
69
+ for (const shape of [...opaque, ...seeThrough]) {
70
+ const m = shape.matrix;
71
+ const nm = normalMatrix(m);
72
+ if (!nm)
73
+ continue;
74
+ const geometry = shapeGeometry(shape.shape, false, "low");
75
+ const pos = geometry.getAttribute("position").array;
76
+ const nor = geometry.getAttribute("normal").array;
77
+ const index = geometry.getIndex()?.array;
78
+ const count = pos.length / 3;
79
+ const base = toRgb(shape.colour);
80
+ const alpha = shape.colour.a;
81
+ const exponent = shininess(shape.sharpness);
82
+ // Per corner: screen x, screen y, 1/distance, and lit colour.
83
+ const sx = new Float32Array(count);
84
+ const sy = new Float32Array(count);
85
+ const iz = new Float32Array(count);
86
+ const lit = new Float32Array(count * 3);
87
+ for (let v = 0; v < count; v++) {
88
+ const px = pos[v * 3];
89
+ const py = pos[v * 3 + 1];
90
+ const pz = pos[v * 3 + 2];
91
+ const world = [
92
+ m[0] * px + m[4] * py + m[8] * pz + m[12],
93
+ m[1] * px + m[5] * py + m[9] * pz + m[13],
94
+ m[2] * px + m[6] * py + m[10] * pz + m[14],
95
+ ];
96
+ const nx = nor[v * 3];
97
+ const ny = nor[v * 3 + 1];
98
+ const nz = nor[v * 3 + 2];
99
+ const n = normalise([
100
+ nm[0] * nx + nm[1] * ny + nm[2] * nz,
101
+ nm[3] * nx + nm[4] * ny + nm[5] * nz,
102
+ nm[6] * nx + nm[7] * ny + nm[8] * nz,
103
+ ]);
104
+ const rel = sub(world, eye);
105
+ const dist = dot(rel, forward);
106
+ iz[v] = dist > cam.near * 0.5 ? 1 / dist : 0;
107
+ sx[v] = W / 2 + (dot(rel, right) / dist) * focal;
108
+ sy[v] = H / 2 - (dot(rel, up) / dist) * focal;
109
+ const toEye = normalise(sub(eye, world));
110
+ let diffuse = LIGHTS.ambient;
111
+ let specular = 0;
112
+ for (const l of lights) {
113
+ diffuse += l.strength * Math.max(0, dot(n, l.direction));
114
+ if (shape.shine > 0) {
115
+ const half = normalise([
116
+ l.direction[0] + toEye[0],
117
+ l.direction[1] + toEye[1],
118
+ l.direction[2] + toEye[2],
119
+ ]);
120
+ specular += l.strength * shape.shine * Math.pow(Math.max(0, dot(n, half)), exponent);
121
+ }
122
+ }
123
+ for (let k = 0; k < 3; k++)
124
+ lit[v * 3 + k] = base[k] * diffuse + specular;
125
+ }
126
+ const triangles = index ? index.length / 3 : count / 3;
127
+ for (let t = 0; t < triangles; t++) {
128
+ const a = index ? index[t * 3] : t * 3;
129
+ const b = index ? index[t * 3 + 1] : t * 3 + 1;
130
+ const c = index ? index[t * 3 + 2] : t * 3 + 2;
131
+ if (iz[a] === 0 || iz[b] === 0 || iz[c] === 0)
132
+ continue; // behind the camera
133
+ const area = (sx[b] - sx[a]) * (sy[c] - sy[a]) - (sy[b] - sy[a]) * (sx[c] - sx[a]);
134
+ if (area === 0 || !Number.isFinite(area))
135
+ continue;
136
+ const x0 = Math.max(0, Math.floor(Math.min(sx[a], sx[b], sx[c])));
137
+ const x1 = Math.min(W - 1, Math.ceil(Math.max(sx[a], sx[b], sx[c])));
138
+ const y0 = Math.max(0, Math.floor(Math.min(sy[a], sy[b], sy[c])));
139
+ const y1 = Math.min(H - 1, Math.ceil(Math.max(sy[a], sy[b], sy[c])));
140
+ for (let y = y0; y <= y1; y++) {
141
+ const py = y + 0.5;
142
+ for (let x = x0; x <= x1; x++) {
143
+ const px = x + 0.5;
144
+ const wa = ((sx[b] - px) * (sy[c] - py) - (sy[b] - py) * (sx[c] - px)) / area;
145
+ const wb = ((sx[c] - px) * (sy[a] - py) - (sy[c] - py) * (sx[a] - px)) / area;
146
+ const wc = 1 - wa - wb;
147
+ if (wa < 0 || wb < 0 || wc < 0)
148
+ continue;
149
+ const z = wa * iz[a] + wb * iz[b] + wc * iz[c];
150
+ const at = y * W + x;
151
+ if (z <= depth[at])
152
+ continue;
153
+ const ka = (wa * iz[a]) / z;
154
+ const kb = (wb * iz[b]) / z;
155
+ const kc = (wc * iz[c]) / z;
156
+ for (let k = 0; k < 3; k++) {
157
+ const value = ka * lit[a * 3 + k] + kb * lit[b * 3 + k] + kc * lit[c * 3 + k];
158
+ colour[at * 3 + k] =
159
+ alpha >= 0.999 ? value : colour[at * 3 + k] * (1 - alpha) + value * alpha;
160
+ }
161
+ if (alpha >= 0.999)
162
+ depth[at] = z;
163
+ }
164
+ }
165
+ }
166
+ }
167
+ const data = new Uint8ClampedArray(options.width * options.height * 4);
168
+ for (let y = 0; y < options.height; y++) {
169
+ for (let x = 0; x < options.width; x++) {
170
+ const out = (y * options.width + x) * 4;
171
+ for (let k = 0; k < 3; k++) {
172
+ let sum = 0;
173
+ for (let dy = 0; dy < ss; dy++) {
174
+ for (let dx = 0; dx < ss; dx++)
175
+ sum += colour[((y * ss + dy) * W + x * ss + dx) * 3 + k];
176
+ }
177
+ data[out + k] = Math.round(Math.min(1, Math.max(0, sum / (ss * ss))) * 255);
178
+ }
179
+ data[out + 3] = 255;
180
+ }
181
+ }
182
+ return { width: options.width, height: options.height, data };
183
+ }
184
+ //# sourceMappingURL=software.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"software.js","sourceRoot":"","sources":["../src/software.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,sGAAsG;AAEtG,OAAO,EAAE,KAAK,EAA8B,MAAM,gBAAgB,CAAC;AACnE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC9D,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,EAAE,SAAS,EAAY,MAAM,WAAW,CAAC;AAoBpG,SAAS,GAAG,CAAC,CAAK,EAAE,CAAK;IACvB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AACD,SAAS,GAAG,CAAC,CAAK,EAAE,CAAK;IACvB,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;AACjD,CAAC;AACD,SAAS,KAAK,CAAC,CAAK,EAAE,CAAK;IACzB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC3F,CAAC;AACD,SAAS,SAAS,CAAC,CAAK;IACtB,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;IAC5C,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;AACxC,CAAC;AAED,gGAAgG;AAChG,SAAS,YAAY,CAAC,CAAoB;IACxC,2BAA2B;IAC3B,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,CAAC,CAAC;IAChC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,CAAC,CAAE,EAAE,CAAC,CAAC,EAAE,CAAE,CAAC,CAAC;IACjC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAO,EAAE,CAAO,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAO,EAAE,CAAO,CAAC,CAAC;IACnC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAO,EAAE,CAAO,CAAC,CAAC;IACnC,MAAM,GAAG,GAAG,GAAG,CAAC,CAAO,EAAE,EAAE,CAAC,CAAC;IAC7B,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC;QAAE,OAAO,SAAS,CAAC;IACzD,iGAAiG;IACjG,OAAO;QACL,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;QACX,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG;KACZ,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,MAA4B,EAAE,OAAsB;IAC5E,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,EAAE,CAAC;IAC7B,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,GAAG,EAAE,CAAC;IAC9B,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAC3C,MAAM,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,6CAA6C;IAEpF,MAAM,IAAI,GAAG,cAAc,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC;IACnD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;QAC3B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;YAAE,MAAM,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC7D,CAAC;IAED,MAAM,GAAG,GAAG,WAAW,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAChF,MAAM,GAAG,GAAG,GAAG,CAAC,QAAQ,CAAC;IACzB,MAAM,OAAO,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC;IAChD,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;IACnD,MAAM,EAAE,GAAG,KAAK,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IACjC,MAAM,KAAK,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,aAAa,GAAG,IAAI,CAAC,EAAE,CAAC,GAAG,GAAG,CAAC,CAAC;IAChE,MAAM,MAAM,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC;IAEzC,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC;IACzD,MAAM,UAAU,GAAG,MAAM;SACtB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,KAAK,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC;SACnD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,CAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAE,EAAE,CAAC,CAAC,MAAM,CAAC,EAAE,CAAE,CAAC,EAAE,GAAG,CAAC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC;SAC7F,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;SACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEnB,KAAK,MAAM,KAAK,IAAI,CAAC,GAAG,MAAM,EAAE,GAAG,UAAU,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,KAAK,CAAC,MAAM,CAAC;QACvB,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC;QAC3B,IAAI,CAAC,EAAE;YAAE,SAAS;QAClB,MAAM,QAAQ,GAAG,aAAa,CAAC,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;QAC1D,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC;QACpD,MAAM,GAAG,GAAG,QAAQ,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,KAAK,CAAC;QAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,EAAE,KAAK,CAAC;QACzC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC;QAC7B,MAAM,IAAI,GAAQ,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QAC7B,MAAM,QAAQ,GAAG,SAAS,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;QAE5C,8DAA8D;QAC9D,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,EAAE,GAAG,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;QACnC,MAAM,GAAG,GAAG,IAAI,YAAY,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;YAC3B,MAAM,KAAK,GAAO;gBAChB,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAE;gBAC7C,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAE;gBAC7C,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAE,GAAG,EAAE,GAAG,CAAC,CAAC,EAAE,CAAE;aAC/C,CAAC;YACF,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC;YACvB,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;YAC3B,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;YAC3B,MAAM,CAAC,GAAG,SAAS,CAAC;gBAClB,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE;gBACvC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE;gBACvC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE;aACxC,CAAC,CAAC;YACH,MAAM,GAAG,GAAG,GAAG,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;YAC/B,EAAE,CAAC,CAAC,CAAC,GAAG,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7C,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;YACjD,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,IAAI,CAAC,GAAG,KAAK,CAAC;YAC9C,MAAM,KAAK,GAAG,SAAS,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;YACzC,IAAI,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC;YAC7B,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,OAAO,IAAI,CAAC,CAAC,QAAQ,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;gBACzD,IAAI,KAAK,CAAC,KAAK,GAAG,CAAC,EAAE,CAAC;oBACpB,MAAM,IAAI,GAAG,SAAS,CAAC;wBACrB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;wBACzB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;wBACzB,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC;qBAC1B,CAAC,CAAC;oBACH,QAAQ,IAAI,CAAC,CAAC,QAAQ,GAAG,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAC;gBACvF,CAAC;YACH,CAAC;YACD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE;gBAAE,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,CAAE,GAAG,OAAO,GAAG,QAAQ,CAAC;QAC7E,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;QACvD,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;YACnC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YACxC,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChD,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YAChD,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;gBAAE,SAAS,CAAC,oBAAoB;YAC7E,MAAM,IAAI,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC;YAC3F,IAAI,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBAAE,SAAS;YACnD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACrE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACxE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACrE,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,EAAE,EAAE,CAAC,CAAC,CAAE,CAAC,CAAC,CAAC,CAAC;YACxE,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;gBACnB,KAAK,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;oBAC9B,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAC;oBACnB,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;oBAClF,MAAM,EAAE,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,CAAC,CAAC,GAAG,IAAI,CAAC;oBAClF,MAAM,EAAE,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC;oBACvB,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,EAAE,GAAG,CAAC;wBAAE,SAAS;oBACzC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC;oBAClD,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;oBACrB,IAAI,CAAC,IAAI,KAAK,CAAC,EAAE,CAAE;wBAAE,SAAS;oBAC9B,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;oBAC7B,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;oBAC7B,MAAM,EAAE,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAE,CAAC,GAAG,CAAC,CAAC;oBAC7B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;wBAC3B,MAAM,KAAK,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,GAAG,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;wBACjF,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAC;4BAChB,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,CAAE,GAAG,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,KAAK,GAAG,KAAK,CAAC;oBAC/E,CAAC;oBACD,IAAI,KAAK,IAAI,KAAK;wBAAE,KAAK,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;gBACpC,CAAC;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,IAAI,GAAG,IAAI,iBAAiB,CAAC,OAAO,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,MAAM,GAAG,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC;YACxC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;gBAC3B,IAAI,GAAG,GAAG,CAAC,CAAC;gBACZ,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC;oBAC/B,KAAK,IAAI,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE,EAAE;wBAAE,GAAG,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,CAAC,CAAE,CAAC;gBAC5F,CAAC;gBACD,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;YAC9E,CAAC;YACD,IAAI,CAAC,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC;QACtB,CAAC;IACH,CAAC;IACD,OAAO,EAAE,KAAK,EAAE,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;AAChE,CAAC"}
@@ -0,0 +1,36 @@
1
+ import { type LaidShape, type Value } from "@genocode/core";
2
+ import { PerspectiveCamera, WebGLRenderer } from "three";
3
+ export declare class CreatureView {
4
+ private readonly canvas;
5
+ readonly renderer: WebGLRenderer;
6
+ readonly camera: PerspectiveCamera;
7
+ private readonly look;
8
+ private readonly controls;
9
+ private readonly resizeObserver;
10
+ private frameRequested;
11
+ constructor(canvas: HTMLCanvasElement);
12
+ /** Replaces the creature on show. With `keepView`, the camera stays where the viewer left it. */
13
+ setCreature(shapes: readonly LaidShape[], keepView?: boolean): void;
14
+ /** Shows a background's fill: a colour, a gradient, or (until patterns exist) a tinted default. */
15
+ setBackground(fill: Value | undefined): void;
16
+ /** Frames the whole creature, seen from the front and a little above. */
17
+ resetView(): void;
18
+ private resize;
19
+ private requestFrame;
20
+ dispose(): void;
21
+ }
22
+ /**
23
+ * Draws creatures into small 2D canvases, such as the tiles of a breeding grid, with one shared
24
+ * WebGL renderer: browsers only allow a few WebGL canvases at once. Shapes are drawn with less
25
+ * detail than in `CreatureView`, which is plenty at tile size and much quicker.
26
+ */
27
+ export declare class Thumbnails {
28
+ private readonly renderer;
29
+ private readonly camera;
30
+ private readonly look;
31
+ constructor();
32
+ /** Draws a creature and its background to fill `target`, at the target's own pixel size. */
33
+ draw(target: HTMLCanvasElement, shapes: readonly LaidShape[], background: Value | undefined): void;
34
+ dispose(): void;
35
+ }
36
+ //# sourceMappingURL=webgl.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgl.d.ts","sourceRoot":"","sources":["../src/webgl.ts"],"names":[],"mappings":"AAIA,OAAO,EAAS,KAAK,SAAS,EAAkB,KAAK,KAAK,EAAE,MAAM,gBAAgB,CAAC;AACnF,OAAO,EAUL,iBAAiB,EAIjB,aAAa,EAEd,MAAM,OAAO,CAAC;AAqJf,qBAAa,YAAY;IAQX,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPnC,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,MAAM,oBAAsD;IACrE,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAiB;IAChD,OAAO,CAAC,cAAc,CAAS;IAE/B,YAA6B,MAAM,EAAE,iBAAiB,EASrD;IAED,iGAAiG;IACjG,WAAW,CAAC,MAAM,EAAE,SAAS,SAAS,EAAE,EAAE,QAAQ,UAAQ,GAAG,IAAI,CAIhE;IAED,mGAAmG;IACnG,aAAa,CAAC,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,IAAI,CAG3C;IAED,yEAAyE;IACzE,SAAS,IAAI,IAAI,CAShB;IAED,OAAO,CAAC,MAAM;IAUd,OAAO,CAAC,YAAY;IAWpB,OAAO,IAAI,IAAI,CAKd;CACF;AAED;;;;GAIG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsD;IAC7E,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAE5C,cAEC;IAED,4FAA4F;IAC5F,IAAI,CACF,MAAM,EAAE,iBAAiB,EACzB,MAAM,EAAE,SAAS,SAAS,EAAE,EAC5B,UAAU,EAAE,KAAK,GAAG,SAAS,GAC5B,IAAI,CAYN;IAED,OAAO,IAAI,IAAI,CAGd;CACF"}
package/dist/webgl.js ADDED
@@ -0,0 +1,234 @@
1
+ // Shows creatures in the browser with three.js: one instanced mesh per kind of shape, with each
2
+ // shape's colour, alpha, shine and sharpness carried per instance. `CreatureView` is the full,
3
+ // interactive view; `Thumbnails` draws many small pictures with one renderer.
4
+ import { toRgb } from "@genocode/core";
5
+ import { AmbientLight, CanvasTexture, Color, DirectionalLight, Group, InstancedBufferAttribute, InstancedMesh, Matrix4, MeshPhongMaterial, PerspectiveCamera, Scene, SRGBColorSpace, Vector3, WebGLRenderer, } from "three";
6
+ import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js";
7
+ import { creatureBounds, shapeGeometry } from "./geometry.js";
8
+ import { backgroundRamp, FIELD_OF_VIEW, frameCamera, LIGHTS, } from "./look.js";
9
+ /** Adds per-instance shine (x), sharpness (y) and alpha (z) to the Phong material. */
10
+ function addInstanceLook(shader) {
11
+ shader.vertexShader = shader.vertexShader
12
+ .replace("#include <common>", "#include <common>\nattribute vec3 instanceLook;\nvarying vec3 vLook;")
13
+ .replace("#include <begin_vertex>", "#include <begin_vertex>\nvLook = instanceLook;");
14
+ shader.fragmentShader = shader.fragmentShader
15
+ .replace("#include <common>", "#include <common>\nvarying vec3 vLook;")
16
+ .replace("#include <color_fragment>", "#include <color_fragment>\ndiffuseColor.a *= vLook.z;")
17
+ .replace("#include <lights_phong_fragment>", [
18
+ "BlinnPhongMaterial material;",
19
+ "material.diffuseColor = diffuseColor.rgb;",
20
+ "material.specularColor = vec3( vLook.x );",
21
+ "material.specularShininess = 4.0 + vLook.y * 124.0;",
22
+ "material.specularStrength = 1.0;",
23
+ ].join("\n"));
24
+ }
25
+ function makeMaterial(transparent) {
26
+ const material = new MeshPhongMaterial({
27
+ color: 0xffffff,
28
+ transparent,
29
+ depthWrite: !transparent,
30
+ });
31
+ material.onBeforeCompile = addInstanceLook;
32
+ // Keeps three from sharing the compiled program with plain Phong materials.
33
+ material.customProgramCacheKey = () => "genocode-instance-look";
34
+ return material;
35
+ }
36
+ /** Light strengths in three are scaled by π compared with the software renderer's. */
37
+ const LIGHT_SCALE = Math.PI;
38
+ /** The scene both views draw: lights, the creature's shapes and the background. */
39
+ class CreatureScene {
40
+ scene = new Scene();
41
+ creature = new Group();
42
+ opaque = makeMaterial(false);
43
+ seeThrough = makeMaterial(true);
44
+ shapes = [];
45
+ constructor() {
46
+ this.scene.add(this.creature);
47
+ this.scene.add(new AmbientLight(0xffffff, LIGHTS.ambient * LIGHT_SCALE));
48
+ for (const l of [LIGHTS.key, LIGHTS.fill]) {
49
+ const light = new DirectionalLight(0xffffff, l.strength * LIGHT_SCALE);
50
+ light.position.set(...l.direction);
51
+ this.scene.add(light);
52
+ }
53
+ this.setBackground(undefined);
54
+ }
55
+ setCreature(shapes, detail) {
56
+ for (const child of [...this.creature.children]) {
57
+ this.creature.remove(child);
58
+ const mesh = child;
59
+ mesh.geometry.dispose(); // each mesh has its own copy, carrying its instance attributes
60
+ mesh.dispose();
61
+ }
62
+ this.shapes = shapes;
63
+ const groups = new Map();
64
+ for (const s of shapes) {
65
+ if (s.colour.a <= 0)
66
+ continue;
67
+ const key = `${s.shape}/${s.mirrored}/${s.colour.a < 0.999}`;
68
+ if (!groups.has(key))
69
+ groups.set(key, []);
70
+ groups.get(key).push(s);
71
+ }
72
+ const matrix = new Matrix4();
73
+ const colour = new Color();
74
+ for (const [key, members] of groups) {
75
+ const [shape, mirrored, transparent] = key.split("/");
76
+ const mesh = new InstancedMesh(shapeGeometry(shape, mirrored === "true", detail), transparent === "true" ? this.seeThrough : this.opaque, members.length);
77
+ const look = new Float32Array(members.length * 3);
78
+ members.forEach((s, i) => {
79
+ matrix.fromArray(s.matrix);
80
+ mesh.setMatrixAt(i, matrix);
81
+ const [r, g, b] = toRgb(s.colour);
82
+ mesh.setColorAt(i, colour.setRGB(r, g, b, SRGBColorSpace));
83
+ look[i * 3] = s.shine;
84
+ look[i * 3 + 1] = s.sharpness;
85
+ look[i * 3 + 2] = s.colour.a;
86
+ });
87
+ mesh.geometry = mesh.geometry.clone();
88
+ mesh.geometry.setAttribute("instanceLook", new InstancedBufferAttribute(look, 3));
89
+ mesh.computeBoundingSphere();
90
+ this.creature.add(mesh);
91
+ }
92
+ }
93
+ /** A background's fill: a colour, a gradient, or (until patterns exist) a tinted default. */
94
+ setBackground(fill) {
95
+ const rows = 256;
96
+ const ramp = backgroundRamp(fill, rows);
97
+ const canvas = document.createElement("canvas");
98
+ canvas.width = 1;
99
+ canvas.height = rows;
100
+ const ctx = canvas.getContext("2d");
101
+ const image = ctx.createImageData(1, rows);
102
+ ramp.forEach((c, i) => {
103
+ const row = rows - 1 - i;
104
+ image.data.set([c[0] * 255, c[1] * 255, c[2] * 255, 255], row * 4);
105
+ });
106
+ ctx.putImageData(image, 0, 0);
107
+ const texture = new CanvasTexture(canvas);
108
+ texture.colorSpace = SRGBColorSpace;
109
+ const old = this.scene.background;
110
+ this.scene.background = texture;
111
+ if (old && "dispose" in old)
112
+ old.dispose();
113
+ }
114
+ /** Points the camera at the whole creature, from the front and a little above. */
115
+ frame(camera, aspect) {
116
+ const placement = frameCamera(creatureBounds(this.shapes), aspect);
117
+ camera.position.set(...placement.position);
118
+ camera.near = placement.near / 4;
119
+ camera.far = placement.far * 4;
120
+ camera.aspect = aspect;
121
+ camera.lookAt(...placement.target);
122
+ camera.updateProjectionMatrix();
123
+ return placement;
124
+ }
125
+ dispose() {
126
+ this.setCreature([], "low");
127
+ this.opaque.dispose();
128
+ this.seeThrough.dispose();
129
+ }
130
+ }
131
+ export class CreatureView {
132
+ canvas;
133
+ renderer;
134
+ camera = new PerspectiveCamera(FIELD_OF_VIEW, 1, 0.1, 1000);
135
+ look = new CreatureScene();
136
+ controls;
137
+ resizeObserver;
138
+ frameRequested = false;
139
+ constructor(canvas) {
140
+ this.canvas = canvas;
141
+ this.renderer = new WebGLRenderer({ canvas, antialias: true, preserveDrawingBuffer: true });
142
+ this.renderer.setPixelRatio(window.devicePixelRatio);
143
+ this.controls = new OrbitControls(this.camera, canvas);
144
+ this.controls.enableDamping = true;
145
+ this.controls.addEventListener("change", () => this.requestFrame());
146
+ this.resizeObserver = new ResizeObserver(() => this.resize());
147
+ this.resizeObserver.observe(canvas);
148
+ this.resize();
149
+ }
150
+ /** Replaces the creature on show. With `keepView`, the camera stays where the viewer left it. */
151
+ setCreature(shapes, keepView = false) {
152
+ this.look.setCreature(shapes, "high");
153
+ if (!keepView)
154
+ this.resetView();
155
+ this.requestFrame();
156
+ }
157
+ /** Shows a background's fill: a colour, a gradient, or (until patterns exist) a tinted default. */
158
+ setBackground(fill) {
159
+ this.look.setBackground(fill);
160
+ this.requestFrame();
161
+ }
162
+ /** Frames the whole creature, seen from the front and a little above. */
163
+ resetView() {
164
+ const aspect = this.canvas.clientWidth / Math.max(1, this.canvas.clientHeight);
165
+ const placement = this.look.frame(this.camera, aspect);
166
+ this.controls.target.set(...placement.target);
167
+ this.controls.minDistance = 0;
168
+ this.controls.maxDistance =
169
+ new Vector3(...placement.position).distanceTo(this.controls.target) * 8;
170
+ this.controls.update();
171
+ this.requestFrame();
172
+ }
173
+ resize() {
174
+ const w = this.canvas.clientWidth;
175
+ const h = this.canvas.clientHeight;
176
+ if (w === 0 || h === 0)
177
+ return;
178
+ this.renderer.setSize(w, h, false);
179
+ this.camera.aspect = w / h;
180
+ this.camera.updateProjectionMatrix();
181
+ this.requestFrame();
182
+ }
183
+ requestFrame() {
184
+ if (this.frameRequested)
185
+ return;
186
+ this.frameRequested = true;
187
+ requestAnimationFrame(() => {
188
+ this.frameRequested = false;
189
+ // Damping keeps the view moving for a moment after the mouse lets go.
190
+ if (this.controls.update())
191
+ this.requestFrame();
192
+ this.renderer.render(this.look.scene, this.camera);
193
+ });
194
+ }
195
+ dispose() {
196
+ this.resizeObserver.disconnect();
197
+ this.controls.dispose();
198
+ this.look.dispose();
199
+ this.renderer.dispose();
200
+ }
201
+ }
202
+ /**
203
+ * Draws creatures into small 2D canvases, such as the tiles of a breeding grid, with one shared
204
+ * WebGL renderer: browsers only allow a few WebGL canvases at once. Shapes are drawn with less
205
+ * detail than in `CreatureView`, which is plenty at tile size and much quicker.
206
+ */
207
+ export class Thumbnails {
208
+ renderer;
209
+ camera = new PerspectiveCamera(FIELD_OF_VIEW, 1, 0.1, 1000);
210
+ look = new CreatureScene();
211
+ constructor() {
212
+ this.renderer = new WebGLRenderer({ antialias: true, preserveDrawingBuffer: true });
213
+ }
214
+ /** Draws a creature and its background to fill `target`, at the target's own pixel size. */
215
+ draw(target, shapes, background) {
216
+ const w = target.width;
217
+ const h = target.height;
218
+ if (w === 0 || h === 0)
219
+ return;
220
+ this.renderer.setSize(w, h, false);
221
+ this.look.setCreature(shapes, "low");
222
+ this.look.setBackground(background);
223
+ this.look.frame(this.camera, w / h);
224
+ this.renderer.render(this.look.scene, this.camera);
225
+ const ctx = target.getContext("2d");
226
+ ctx.clearRect(0, 0, w, h);
227
+ ctx.drawImage(this.renderer.domElement, 0, 0, w, h);
228
+ }
229
+ dispose() {
230
+ this.look.dispose();
231
+ this.renderer.dispose();
232
+ }
233
+ }
234
+ //# sourceMappingURL=webgl.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgl.js","sourceRoot":"","sources":["../src/webgl.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,37 @@
1
1
  {
2
2
  "name": "@genocode/render",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.2.0",
4
+ "description": "Draws GenoCode creatures, textures and backgrounds with three.js.",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/genocode-org/GenoCode.git",
9
+ "directory": "packages/render"
10
+ },
11
+ "homepage": "https://github.com/genocode-org/GenoCode#readme",
12
+ "bugs": "https://github.com/genocode-org/GenoCode/issues",
13
+ "type": "module",
14
+ "main": "./dist/index.js",
15
+ "types": "./dist/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "types": "./dist/index.d.ts",
19
+ "default": "./dist/index.js"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist",
24
+ "README.md",
25
+ "LICENSE"
26
+ ],
27
+ "dependencies": {
28
+ "@genocode/core": "^0.2.0",
29
+ "three": "0.160.0"
30
+ },
31
+ "devDependencies": {
32
+ "@types/three": "0.160.0"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ }
37
+ }