Skip to content

Instantly share code, notes, and snippets.

View donmccurdy's full-sized avatar

Don McCurdy donmccurdy

View GitHub Profile
@donmccurdy
donmccurdy / bin-plugin.js
Last active December 29, 2022 17:06
Example vite/rollup plugin for processing binary files.
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 February 27, 2022 21:59
Create a basic GLB with a single mesh.
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 February 12, 2022 17:22
Compute flat normals in glTF-Transform
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 July 27, 2023 15:48
Divide glTF Document

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 September 21, 2021 17:06
Meshopt Compression and Tabular Data

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 September 14, 2021 22:32
EXT_feature_metadata: Optional and Nullable Values

(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.mjs
Last active December 17, 2022 17:37
Script for formatting Libby highlights as Markdown.
#!/usr/bin/env node
/* SPDX-License-Identifier: MIT */
import { readFileSync, writeFileSync } from 'fs';
const args = process.argv.slice(2);
const srcPath = new URL(args[0], import.meta.url);
const dstPath = new URL(args[1], import.meta.url);
@donmccurdy
donmccurdy / JAVASCRIPT_LIBRARY_TOOLS.md
Last active April 16, 2021 05:36
A minimal set of tools for creating a JavaScript or TypeScript library.

These are the build tools I prefer to use when starting a new JavaScript or TypeScript library. Most libraries I write run both in the browser and in node.js. Each project needs to be lightweight, and to minimize maintenance. And I need build chains for those libraries to pretty much "just work". That last part has become more important over time, as I've maintained more libraries and generally had less time to deal with dependencies and build system issues. For web applications, as opposed to libraries consumed in other projects, these choices may or may not make sense. These are opinionated choices, and will probably change over time.

Almost always:

  • microbundle: Zero-config Rollup bundler, with optional TypeScript support
  • tape: Test runner
  • tap-spec: Clean test output

Occasionally:

@donmccurdy
donmccurdy / THREE_COLORSPACE_MANAGEMENT.md
Last active January 2, 2023 08:07
Color management in three.js