Skip to content

Instantly share code, notes, and snippets.

Avatar

Don McCurdy donmccurdy

View GitHub Profile
View esm-package.md

Pure ESM package

The package linked to from here is now pure ESM. It cannot be require()'d from CommonJS.

This means you have the following choices:

  1. Use ESM yourself. (preferred)
    Use import foo from 'foo' instead of const foo = require('foo') to import the package. You also need to put "type": "module" in your package.json and more. Follow the below guide.
  2. If the package is used in an async context, you could use await import(…) from CommonJS instead of require(…).
  3. Stay on the existing version of the package until you can move to ESM.
@donmccurdy
donmccurdy / PUBLIC_CLASS_PROPERTY_ORDER.md
Last active May 5, 2022
Initialization order and public class properties
View PUBLIC_CLASS_PROPERTY_ORDER.md

Initialization order and public class properties

(A)

class Parent {
    constructor() {
        console.log(`${this.type}::constructor`)
    }
}
@donmccurdy
donmccurdy / bin-plugin.js
Last active Apr 7, 2022
Example vite/rollup plugin for processing binary files.
View bin-plugin.js
import { createFilter, normalizePath } from "@rollup/pluginutils";
import fs from "fs/promises";
import crypto from "crypto";
import path from "path";
const PLUGIN_NAME = "bin";
const HASH_LENGTH = 8;
const DEFAULT_PLUGIN_OPTIONS = {
@donmccurdy
donmccurdy / create-basic-glb.js
Created Feb 27, 2022
Create a basic GLB with a single mesh.
View create-basic-glb.js
import { Accessor, Document, Primitive, NodeIO } from '@gltf-transform/core';
const document = new Document();
const prim = document.createPrimitive();
const buffer = document.createBuffer();
const material = document.createMaterial()
.setBaseColorFactor([1.0, 0.0, 0.0, 1.0])
.setMetallicFactor(0.0)
.setRoughnessFactor(1.0);
@donmccurdy
donmccurdy / flat-normals.ts
Last active Feb 12, 2022
Compute flat normals in glTF-Transform
View flat-normals.ts
import { vec3 } from 'gl-matrix';
import { unweld } from '@gltf-transform/functions';
await document.transform(unweld());
for (const mesh of document.getRoot().listMeshes()) {
for (const prim of mesh.listPrimitives()) {
const position = prim.getAttribute('POSITION');
const normal = document.createAccessor()
.setArray(new Float32Array(position.getCount() * 3))
@donmccurdy
donmccurdy / README.md
Last active Sep 21, 2021
Divide glTF Document
View README.md

Divide glTF Document

Example script showing how to use glTF-Transform (https://gltf-transform.donmccurdy.com/) to divide a glTF asset — along an axis — into two GLBs, each occupying half the original bounding box. This is just a rough illustration, and has only been tested against a point cloud containing a single mesh. A production implementation would want to do more than this:

  • support >2 divisions
  • for primitives that lie fully in one division, don't write an empty primitive to the others
  • support triangles, lines, etc.

For input with significant outliers (e.g. noisy point clouds), dividing by the center of the bounding box may give unexpected results.

@donmccurdy
donmccurdy / README.md
Last active Sep 21, 2021
Meshopt Compression and Tabular Data
View README.md

Evaluation: Meshopt Compression with Tabular Data

Summary: Short evaluation of Meshopt compression for use with tabular data. For the purposes of this evaluation, tabular data is defined as a dataset having many observations ("rows"), where each observation consists of one or more property values from a common schema.

Steps

I downloaded the results of the 2015 NYC Tree Census from BigQuery's NYC Street Trees public dataset, also available through NYC Open Data. The 2015 census consists of 683,788 rows and 41 columns, and is about 500 MB when exported as JSON. Much of that data is text, and because meshopt is designed for numeric input we have good reason to believe results for the numeric columns will be "at least as good" as results for the dataset as a whole. For purposes of simpler evaluation and an upper bound on compre

@donmccurdy
donmccurdy / EXT_FEATURE_METADATA_OPTIONAL.md
Last active Sep 14, 2021
EXT_feature_metadata: Optional and Nullable Values
View EXT_FEATURE_METADATA_OPTIONAL.md

(1) Optional Property Column

Already defined in schema.

(2) Optional Property Value

noData: NoData values represent missing data (also known as sentinel values). If omitted, property values are considered to be present for all features — with the exception of variable-length ARRAY elements, which may be left empty without a NoData value.

"classes": {
@donmccurdy
donmccurdy / format_libby_highlights.js
Created Jun 24, 2021
Script for formatting Libby highlights as Markdown.
View format_libby_highlights.js
const fs = require('fs');
const json = require('./name_of_book.json');
let md = '';
let lastChapter = '';
json.highlights.sort((a, b) => a.percent - b.percent);
for (const highlight of json.highlights) {
if (lastChapter !== highlight.chapter) {