typegpu
Version:
A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.
1 lines • 32.5 kB
Source Map (JSON)
{"version":3,"sources":["../package.json","../src/shared/symbols.ts","../src/shared/meta.ts","../src/errors.ts","../src/data/matrix.ts","../src/data/ptr.ts"],"names":["version","$internal","$wgslDataType","$gpuValueOf","$getNameForward","isForwarded","value","getName","definition","getMetaData","setName","name","setMetaData","isNamable","metaData","map","prefix","invariant","condition","message","ResolutionError","_ResolutionError","cause","trace","entries","ancestor"],"mappings":"AAGE,+2BAAAA,CAAAA,CAAW,OAAA,CCEN,IAAMC,CAAAA,CAAY,MAAA,CAAO,CAAA,QAAA,EAAWD,CAAO,CAAA,UAAA,CAAY,CAAA,CAIjDE,EAAAA,aAAgB,MAAA,CAAO,CAAA,QAAA,EAAWF,CAAO,CAAA,cAAA,CAAgB,CAAA,CAIzDG,EAAAA,aAAc,MAAA,CAAO,CAAA,QAAA,EAAWH,CAAO,CAAA,YAAA,CAAc,CAAA,CACrDI,CAAAA,aAAkB,MAAA,CAAO,CAAA,QAAA,EAAWJ,CAAO,CAAA,gBAAA,CAAkB,CAAA,CCI1E,SAASK,EAAAA,CAAYC,CAAAA,CAAyD,CAC5E,MAAO,CAAC,iBAAEA,CAAAA,4BAAAA,CAA4CF,CAAe,GACvE,CAEO,SAASG,CAAAA,CAAQC,CAAAA,CAAyC,CAC/D,OAAIH,EAAAA,CAAYG,CAAU,CAAA,CACjBD,CAAAA,CAAQC,CAAAA,CAAWJ,CAAe,CAAC,CAAA,iBAErCK,EAAAA,mBAAYD,CAAU,CAAA,6BAAG,MAClC,CAEO,SAASE,EAAAA,CAAQF,CAAAA,CAAoBG,CAAAA,CAAoB,CAC9DC,EAAAA,CAAYJ,CAAAA,CAAY,CAAE,IAAA,CAAAG,CAAK,CAAC,CAClC,CAYO,SAASE,EAAAA,CAAUP,CAAAA,CAAsC,CAC9D,MAAO,CAAC,iBAAEA,CAAAA,6BAAuB,OACnC,CAEO,SAASG,EAAAA,CACdD,CAAAA,CACsB,CACtB,OAAQ,UAAA,CAAyC,gBAAA,CAAiB,GAAA,CAEhEA,CACF,CACF,CAEO,SAASI,EAAAA,CAAYJ,CAAAA,CAAoBM,CAAAA,CAAkB,CAC/D,UAAA,CAAyC,gBAAA,GAAqB,IAAI,OAAA,CACnE,IAAMC,CAAAA,CAAO,UAAA,CAAyC,gBAAA,CACtDA,CAAAA,CAAI,GAAA,CAAIP,CAAAA,CAAY,CAAE,GAAGO,CAAAA,CAAI,GAAA,CAAIP,CAAU,CAAA,CAAG,GAAGM,CAAS,CAAC,CAC7D,CCpDA,IAAME,CAAAA,CAAS,kBAAA,CAKR,SAASC,CAAAA,CACdC,CAAAA,CACAC,CAAAA,CACmB,CACnB,EAAA,CAAID,CAAAA,CAEF,MAAA,CAKA,MAAM,IAAI,KAAA,CAAMF,CAAM,CAa1B,CASO,IAAMI,EAAAA,CAAN,MAAMC,EAAAA,QAAwB,KAAM,CACzC,WAAA,CACkBC,CAAAA,CACAC,CAAAA,CAChB,CACA,IAAIC,CAAAA,CAAUD,CAAAA,CAAM,GAAA,CAAKE,CAAAA,EAAa,CAAA,EAAA,EAAKA,CAAQ,CAAA,CAAA;AAQU;AAmD3D;ACgaK;AAAA;AAkBA,KAAA;AAAA;AAAA;AAAA;AAmBA,KAAA;AAAA;AAAA;AAAA;AAAA;AAkCA,KAAA;AAAA;AAAA;AAAA;AAIiD,QAAA;AAwBjD,OAAA;AACW,QAAA;AACG,WAAA;AACG,cAAA;AAAA;AA0BtB,OAAA;AAAA;AAEmC,eAAA;AACC,gBAAA;AAAA;AA0BpC,OAAA;AACoC,YAAA;AAAA;AAED,YAAA;AAAA;AA0BnC,OAAA;AACgC,YAAA;AACC,aAAA;AAAA;AAAA;ACvqBnC,OAAA","file":"/Users/iwo/Projects/wigsill/packages/typegpu/dist/chunk-BJSN5UVV.cjs","sourcesContent":["{\n \"name\": \"typegpu\",\n \"private\": true,\n \"version\": \"0.5.9\",\n \"description\": \"A thin layer between JS and WebGPU/WGSL that improves development experience and allows for faster iteration.\",\n \"license\": \"MIT\",\n \"type\": \"module\",\n \"exports\": {\n \"./package.json\": \"./package.json\",\n \".\": \"./src/index.ts\",\n \"./data\": \"./src/data/index.ts\",\n \"./std\": \"./src/std/index.ts\"\n },\n \"publishConfig\": {\n \"directory\": \"dist\",\n \"linkDirectory\": false,\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/index.d.ts\",\n \"exports\": {\n \"./package.json\": \"./dist/package.json\",\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"module\": \"./dist/index.js\",\n \"import\": \"./dist/index.js\",\n \"default\": \"./dist/index.cjs\"\n },\n \"./data\": {\n \"types\": \"./dist/data/index.d.ts\",\n \"module\": \"./dist/data/index.js\",\n \"import\": \"./dist/data/index.js\",\n \"default\": \"./dist/data/index.cjs\"\n },\n \"./std\": {\n \"types\": \"./dist/std/index.d.ts\",\n \"module\": \"./dist/std/index.js\",\n \"import\": \"./dist/std/index.js\",\n \"default\": \"./dist/std/index.cjs\"\n }\n }\n },\n \"sideEffects\": false,\n \"scripts\": {\n \"build\": \"tsup\",\n \"test:types\": \"pnpm tsc --p ./tsconfig.test.json --noEmit\",\n \"prepublishOnly\": \"tgpu-dev-cli prepack\"\n },\n \"engines\": {\n \"node\": \">=12.20.0\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/software-mansion/TypeGPU.git\"\n },\n \"keywords\": [\n \"webgpu\",\n \"wgpu\",\n \"wgsl\",\n \"typescript\",\n \"compute\",\n \"shader\",\n \"shaders\",\n \"gpgpu\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/software-mansion/TypeGPU/issues\"\n },\n \"homepage\": \"https://typegpu.com\",\n \"devDependencies\": {\n \"@ark/attest\": \"^0.46.0\",\n \"@typegpu/tgpu-dev-cli\": \"workspace:*\",\n \"@types/node\": \"^22.13.14\",\n \"@webgpu/types\": \"catalog:\",\n \"arktype\": \"catalog:\",\n \"jiti\": \"^2.4.2\",\n \"tgpu-jit\": \"workspace:*\",\n \"tsup\": \"catalog:\",\n \"typescript\": \"catalog:\",\n \"unplugin-typegpu\": \"workspace:*\",\n \"wesl\": \"0.6.7\",\n \"wgpu-matrix\": \"^3.4.0\"\n },\n \"packageManager\": \"pnpm@10.4.1+sha512.c753b6c3ad7afa13af388fa6d808035a008e30ea9993f58c6663e2bc5ff21679aa834db094987129aa4d488b86df57f7b634981b2f827cdcacc698cc0cfb88af\",\n \"dependencies\": {\n \"tinyest\": \"workspace:~0.1.1\",\n \"typed-binary\": \"^4.3.1\"\n }\n}\n","// The version is inlined during build-time 🎉\n// It helps us identify problems when two versions of\n// TypeGPU are used at the same time.\nimport { version } from '../../package.json';\n\nexport const $internal = Symbol(`typegpu:${version}:$internal`);\n/**\n * A value's data type as seen by the WGSL generator\n */\nexport const $wgslDataType = Symbol(`typegpu:${version}:$wgslDataType`);\n/**\n * The getter to the value of this resource, accessible on the GPU\n */\nexport const $gpuValueOf = Symbol(`typegpu:${version}:$gpuValueOf`);\nexport const $getNameForward = Symbol(`typegpu:${version}:$getNameForward`);\n","import type { Block, FuncParameter } from 'tinyest';\nimport { $getNameForward } from './symbols.ts';\n\nexport interface MetaData {\n name?: string | undefined;\n ast?: {\n v: number;\n params: FuncParameter[];\n body: Block;\n externalNames: string[];\n } | undefined;\n externals?: Record<string, unknown> | undefined;\n}\n\ninterface GlobalWithMeta {\n __TYPEGPU_META__: WeakMap<object, MetaData>;\n}\n\nfunction isForwarded(value: unknown): value is { [$getNameForward]: unknown } {\n return !!(value as { [$getNameForward]?: unknown })?.[$getNameForward];\n}\n\nexport function getName(definition: unknown): string | undefined {\n if (isForwarded(definition)) {\n return getName(definition[$getNameForward]);\n }\n return getMetaData(definition)?.name;\n}\n\nexport function setName(definition: object, name: string): void {\n setMetaData(definition, { name });\n}\n\n/**\n * Can be assigned a name. Not to be confused with\n * being able to HAVE a name.\n * The `$name` function should use `setName` to rename the object itself,\n * or rename the object `$getNameForward` symbol points to instead if applicable.\n */\nexport interface TgpuNamable {\n $name(label: string): this;\n}\n\nexport function isNamable(value: unknown): value is TgpuNamable {\n return !!(value as TgpuNamable)?.$name;\n}\n\nexport function getMetaData(\n definition: unknown,\n): MetaData | undefined {\n return (globalThis as unknown as GlobalWithMeta).__TYPEGPU_META__.get(\n // biome-ignore lint/suspicious/noExplicitAny: it's fine, if it's not an object, the get will return undefined\n definition as any,\n );\n}\n\nexport function setMetaData(definition: object, metaData: object) {\n (globalThis as unknown as GlobalWithMeta).__TYPEGPU_META__ ??= new WeakMap();\n const map = (globalThis as unknown as GlobalWithMeta).__TYPEGPU_META__;\n map.set(definition, { ...map.get(definition), ...metaData });\n}\n","import type { TgpuBuffer } from './core/buffer/buffer.ts';\nimport type { TgpuSlot } from './core/slot/slotTypes.ts';\nimport type { TgpuVertexLayout } from './core/vertexLayout/vertexLayout.ts';\nimport type { AnyData, Disarray } from './data/dataTypes.ts';\nimport type { WgslArray } from './data/wgslTypes.ts';\nimport { getName } from './shared/meta.ts';\nimport type { TgpuBindGroupLayout } from './tgpuBindGroupLayout.ts';\n\nconst prefix = 'Invariant failed';\n\n/**\n * Inspired by: https://github.com/alexreardon/tiny-invariant/blob/master/src/tiny-invariant.ts\n */\nexport function invariant(\n condition: unknown,\n message?: string | (() => string),\n): asserts condition {\n if (condition) {\n // Condition passed\n return;\n }\n\n // In production we strip the message but still throw\n if (process.env.NODE_ENV === 'production') {\n throw new Error(prefix);\n }\n\n // When not in production we allow the message to pass through\n // *This block will be removed in production builds*\n\n const provided = typeof message === 'function' ? message() : message;\n\n // Options:\n // 1. message provided: `${prefix}: ${provided}`\n // 2. message not provided: prefix\n const value = provided ? `${prefix}: ${provided}` : prefix;\n throw new Error(value);\n}\n\n/**\n * An error that happens during resolution of WGSL code.\n * Contains a trace of all ancestor resolvables in\n * which this error originated.\n *\n * @category Errors\n */\nexport class ResolutionError extends Error {\n constructor(\n public readonly cause: unknown,\n public readonly trace: unknown[],\n ) {\n let entries = trace.map((ancestor) => `- ${ancestor}`);\n\n // Showing only the root and leaf nodes.\n if (entries.length > 20) {\n entries = [...entries.slice(0, 11), '...', ...entries.slice(-10)];\n }\n\n super(\n `Resolution of the following tree failed: \\n${entries.join('\\n')}: ${\n cause && typeof cause === 'object' && 'message' in cause\n ? cause.message\n : cause\n }`,\n );\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, ResolutionError.prototype);\n }\n\n appendToTrace(ancestor: unknown): ResolutionError {\n const newTrace = [ancestor, ...this.trace];\n\n return new ResolutionError(this.cause, newTrace);\n }\n}\n\n/**\n * @category Errors\n */\nexport class MissingSlotValueError extends Error {\n constructor(public readonly slot: TgpuSlot<unknown>) {\n super(`Missing value for '${slot}'`);\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, MissingSlotValueError.prototype);\n }\n}\n\n/**\n * @category Errors\n */\nexport class NotUniformError extends Error {\n constructor(value: TgpuBuffer<AnyData>) {\n super(\n `Buffer '${\n getName(value) ?? '<unnamed>'\n }' is not bindable as a uniform. Use .$usage('uniform') to allow it.`,\n );\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, NotUniformError.prototype);\n }\n}\n\nexport class MissingLinksError extends Error {\n constructor(fnLabel: string | undefined, externalNames: string[]) {\n super(\n `The function '${\n fnLabel ?? '<unnamed>'\n }' is missing links to the following external values: ${externalNames}.`,\n );\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, MissingLinksError.prototype);\n }\n}\n\nexport class MissingBindGroupsError extends Error {\n constructor(layouts: Iterable<TgpuBindGroupLayout>) {\n super(\n `Missing bind groups for layouts: '${\n [...layouts].map((layout) => getName(layout) ?? '<unnamed>').join(', ')\n }'. Please provide it using pipeline.with(layout, bindGroup).(...)`,\n );\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, MissingBindGroupsError.prototype);\n }\n}\n\nexport class MissingVertexBuffersError extends Error {\n constructor(layouts: Iterable<TgpuVertexLayout<WgslArray | Disarray>>) {\n super(\n `Missing vertex buffers for layouts: '${\n [...layouts].map((layout) => getName(layout) ?? '<unnamed>').join(', ')\n }'. Please provide it using pipeline.with(layout, buffer).(...)`,\n );\n\n // Set the prototype explicitly.\n Object.setPrototypeOf(this, MissingVertexBuffersError.prototype);\n }\n}\n","import { createDualImpl } from '../shared/generators.ts';\nimport { $repr } from '../shared/repr.ts';\nimport { $internal } from '../shared/symbols.ts';\nimport type { SelfResolvable } from '../types.ts';\nimport { snip } from './dataTypes.ts';\nimport { vec2f, vec3f, vec4f } from './vector.ts';\nimport type {\n AnyWgslData,\n m2x2f,\n m3x3f,\n m4x4f,\n mat2x2,\n Mat2x2f,\n mat3x3,\n Mat3x3f,\n mat4x4,\n Mat4x4f,\n matBase,\n v2f,\n v3f,\n v4f,\n VecKind,\n} from './wgslTypes.ts';\n\n// --------------\n// Implementation\n// --------------\n\ntype vBase = {\n kind: VecKind;\n length: number;\n [n: number]: number;\n};\n\ninterface MatSchemaOptions<TType extends string, ValueType> {\n type: TType;\n rows: 2 | 3 | 4;\n columns: 2 | 3 | 4;\n makeFromElements(...elements: number[]): ValueType;\n}\n\ntype MatConstructor<\n ValueType extends matBase<ColumnType>,\n ColumnType extends vBase,\n> = (...args: (number | ColumnType)[]) => ValueType;\n\nfunction createMatSchema<\n TType extends string,\n ValueType extends matBase<ColumnType>,\n ColumnType extends vBase,\n>(\n options: MatSchemaOptions<TType, ValueType>,\n): { type: TType; [$repr]: ValueType } & MatConstructor<ValueType, ColumnType> {\n const MatSchema = {\n [$internal]: true,\n [$repr]: undefined as unknown as ValueType,\n type: options.type,\n identity: identityFunctions[options.columns],\n translation: options.columns === 4 ? translation4 : undefined,\n scaling: options.columns === 4 ? scaling4 : undefined,\n rotationX: options.columns === 4 ? rotationX4 : undefined,\n rotationY: options.columns === 4 ? rotationY4 : undefined,\n rotationZ: options.columns === 4 ? rotationZ4 : undefined,\n } as unknown as AnyWgslData;\n\n const construct = createDualImpl(\n // CPU implementation\n (...args: (number | ColumnType)[]): ValueType => {\n const elements: number[] = [];\n\n for (const arg of args) {\n if (typeof arg === 'number') {\n elements.push(arg);\n } else {\n for (let i = 0; i < arg.length; ++i) {\n elements.push(arg[i] as number);\n }\n }\n }\n\n if (\n elements.length !== 0 &&\n elements.length !== options.columns * options.rows\n ) {\n throw new Error(\n `'${options.type}' constructor called with invalid number of arguments.`,\n );\n }\n\n for (let i = elements.length; i < options.columns * options.rows; ++i) {\n elements.push(0);\n }\n\n return options.makeFromElements(...elements);\n },\n // GPU implementation\n (...args) =>\n snip(\n `${MatSchema.type}(${args.map((v) => v.value).join(', ')})`,\n MatSchema,\n ),\n MatSchema.type,\n );\n\n return Object.assign(construct, MatSchema) as unknown as {\n type: TType;\n [$repr]: ValueType;\n } & MatConstructor<ValueType, ColumnType>;\n}\n\nabstract class mat2x2Impl<TColumn extends v2f>\n implements mat2x2<TColumn>, SelfResolvable {\n public readonly [$internal] = true;\n public readonly columns: readonly [TColumn, TColumn];\n public readonly length = 4;\n public abstract readonly kind: string;\n [n: number]: number;\n\n constructor(...elements: number[]) {\n this.columns = [\n this.makeColumn(elements[0] as number, elements[1] as number),\n this.makeColumn(elements[2] as number, elements[3] as number),\n ];\n }\n\n abstract makeColumn(e0: number, e1: number): TColumn;\n\n get [0]() {\n return this.columns[0].x;\n }\n\n get [1]() {\n return this.columns[0].y;\n }\n\n get [2]() {\n return this.columns[1].x;\n }\n\n get [3]() {\n return this.columns[1].y;\n }\n\n set [0](value: number) {\n this.columns[0].x = value;\n }\n\n set [1](value: number) {\n this.columns[0].y = value;\n }\n\n set [2](value: number) {\n this.columns[1].x = value;\n }\n\n set [3](value: number) {\n this.columns[1].y = value;\n }\n\n *[Symbol.iterator]() {\n yield this[0];\n yield this[1];\n yield this[2];\n yield this[3];\n }\n\n '~resolve'(): string {\n return `${this.kind}(${\n Array.from({ length: this.length })\n .map((_, i) => this[i])\n .join(', ')\n })`;\n }\n}\nclass mat2x2fImpl extends mat2x2Impl<v2f> implements m2x2f {\n public readonly kind = 'mat2x2f';\n\n makeColumn(e0: number, e1: number): v2f {\n return vec2f(e0, e1);\n }\n}\n\nabstract class mat3x3Impl<TColumn extends v3f>\n implements mat3x3<TColumn>, SelfResolvable {\n public readonly [$internal] = true;\n public readonly columns: readonly [TColumn, TColumn, TColumn];\n public readonly length = 12;\n public abstract readonly kind: string;\n [n: number]: number;\n\n constructor(...elements: number[]) {\n this.columns = [\n this.makeColumn(\n elements[0] as number,\n elements[1] as number,\n elements[2] as number,\n ),\n this.makeColumn(\n elements[3] as number,\n elements[4] as number,\n elements[5] as number,\n ),\n this.makeColumn(\n elements[6] as number,\n elements[7] as number,\n elements[8] as number,\n ),\n ];\n }\n\n abstract makeColumn(x: number, y: number, z: number): TColumn;\n\n get [0]() {\n return this.columns[0].x;\n }\n\n get [1]() {\n return this.columns[0].y;\n }\n\n get [2]() {\n return this.columns[0].z;\n }\n\n get [3]() {\n return 0;\n }\n\n get [4]() {\n return this.columns[1].x;\n }\n\n get [5]() {\n return this.columns[1].y;\n }\n\n get [6]() {\n return this.columns[1].z;\n }\n\n get [7]() {\n return 0;\n }\n\n get [8]() {\n return this.columns[2].x;\n }\n\n get [9]() {\n return this.columns[2].y;\n }\n\n get [10]() {\n return this.columns[2].z;\n }\n\n get [11]() {\n return 0;\n }\n\n set [0](value: number) {\n this.columns[0].x = value;\n }\n\n set [1](value: number) {\n this.columns[0].y = value;\n }\n\n set [2](value: number) {\n this.columns[0].z = value;\n }\n\n set [3](_: number) {}\n\n set [4](value: number) {\n this.columns[1].x = value;\n }\n\n set [5](value: number) {\n this.columns[1].y = value;\n }\n\n set [6](value: number) {\n this.columns[1].z = value;\n }\n\n set [7](_: number) {}\n\n set [8](value: number) {\n this.columns[2].x = value;\n }\n\n set [9](value: number) {\n this.columns[2].y = value;\n }\n\n set [10](value: number) {\n this.columns[2].z = value;\n }\n\n set [11](_: number) {}\n\n *[Symbol.iterator]() {\n for (let i = 0; i < 12; i++) {\n yield this[i] as number;\n }\n }\n\n '~resolve'(): string {\n return `${this.kind}(${this[0]}, ${this[1]}, ${this[2]}, ${this[4]}, ${\n this[5]\n }, ${this[6]}, ${this[8]}, ${this[9]}, ${this[10]})`;\n }\n}\n\nclass mat3x3fImpl extends mat3x3Impl<v3f> implements m3x3f {\n public readonly kind = 'mat3x3f';\n makeColumn(x: number, y: number, z: number): v3f {\n return vec3f(x, y, z);\n }\n}\n\nabstract class mat4x4Impl<TColumn extends v4f>\n implements mat4x4<TColumn>, SelfResolvable {\n public readonly [$internal] = true;\n public readonly columns: readonly [TColumn, TColumn, TColumn, TColumn];\n public abstract readonly kind: string;\n\n constructor(...elements: number[]) {\n this.columns = [\n this.makeColumn(\n elements[0] as number,\n elements[1] as number,\n elements[2] as number,\n elements[3] as number,\n ),\n this.makeColumn(\n elements[4] as number,\n elements[5] as number,\n elements[6] as number,\n elements[7] as number,\n ),\n this.makeColumn(\n elements[8] as number,\n elements[9] as number,\n elements[10] as number,\n elements[11] as number,\n ),\n this.makeColumn(\n elements[12] as number,\n elements[13] as number,\n elements[14] as number,\n elements[15] as number,\n ),\n ];\n }\n\n abstract makeColumn(x: number, y: number, z: number, w: number): TColumn;\n\n public readonly length = 16;\n [n: number]: number;\n\n get [0]() {\n return this.columns[0].x;\n }\n\n get [1]() {\n return this.columns[0].y;\n }\n\n get [2]() {\n return this.columns[0].z;\n }\n\n get [3]() {\n return this.columns[0].w;\n }\n\n get [4]() {\n return this.columns[1].x;\n }\n\n get [5]() {\n return this.columns[1].y;\n }\n\n get [6]() {\n return this.columns[1].z;\n }\n\n get [7]() {\n return this.columns[1].w;\n }\n\n get [8]() {\n return this.columns[2].x;\n }\n\n get [9]() {\n return this.columns[2].y;\n }\n\n get [10]() {\n return this.columns[2].z;\n }\n\n get [11]() {\n return this.columns[2].w;\n }\n\n get [12]() {\n return this.columns[3].x;\n }\n\n get [13]() {\n return this.columns[3].y;\n }\n\n get [14]() {\n return this.columns[3].z;\n }\n\n get [15]() {\n return this.columns[3].w;\n }\n\n set [0](value: number) {\n this.columns[0].x = value;\n }\n\n set [1](value: number) {\n this.columns[0].y = value;\n }\n\n set [2](value: number) {\n this.columns[0].z = value;\n }\n\n set [3](value: number) {\n this.columns[0].w = value;\n }\n\n set [4](value: number) {\n this.columns[1].x = value;\n }\n\n set [5](value: number) {\n this.columns[1].y = value;\n }\n\n set [6](value: number) {\n this.columns[1].z = value;\n }\n\n set [7](value: number) {\n this.columns[1].w = value;\n }\n\n set [8](value: number) {\n this.columns[2].x = value;\n }\n\n set [9](value: number) {\n this.columns[2].y = value;\n }\n\n set [10](value: number) {\n this.columns[2].z = value;\n }\n\n set [11](value: number) {\n this.columns[2].w = value;\n }\n\n set [12](value: number) {\n this.columns[3].x = value;\n }\n\n set [13](value: number) {\n this.columns[3].y = value;\n }\n\n set [14](value: number) {\n this.columns[3].z = value;\n }\n\n set [15](value: number) {\n this.columns[3].w = value;\n }\n\n *[Symbol.iterator]() {\n for (let i = 0; i < 16; i++) {\n yield this[i] as number;\n }\n }\n\n '~resolve'(): string {\n return `${this.kind}(${\n Array.from({ length: this.length })\n .map((_, i) => this[i])\n .join(', ')\n })`;\n }\n}\n\nclass mat4x4fImpl extends mat4x4Impl<v4f> implements m4x4f {\n public readonly kind = 'mat4x4f';\n\n makeColumn(x: number, y: number, z: number, w: number): v4f {\n return vec4f(x, y, z, w);\n }\n}\n\n// ----------\n// Matrix ops\n// ----------\n\n/**\n * Returns a 2-by-2 identity matrix.\n * @returns {m2x2f} The result matrix.\n */\nexport const identity2 = createDualImpl(\n // CPU implementation\n () => mat2x2f(1, 0, 0, 1),\n // GPU implementation\n () => ({\n value: `mat4x4f(\n 1.0, 0.0,\n 0.0, 1.0\n )`,\n dataType: mat2x2f,\n }),\n 'identity2',\n);\n\n/**\n * Returns a 3-by-3 identity matrix.\n * @returns {m3x3f} The result matrix.\n */\nexport const identity3 = createDualImpl(\n // CPU implementation\n () => mat3x3f(1, 0, 0, 0, 1, 0, 0, 0, 1),\n // GPU implementation\n () => ({\n value: `mat4x4f(\n 1.0, 0.0, 0.0,\n 0.0, 1.0, 0.0,\n 0.0, 0.0, 1.0,\n )`,\n dataType: mat3x3f,\n }),\n 'identity3',\n);\n\n/**\n * Returns a 4-by-4 identity matrix.\n * @returns {m4x4f} The result matrix.\n */\nexport const identity4 = createDualImpl(\n // CPU implementation\n () => mat4x4f(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1),\n // GPU implementation\n () => ({\n value: `mat4x4f(\n 1.0, 0.0, 0.0, 0.0,\n 0.0, 1.0, 0.0, 0.0,\n 0.0, 0.0, 1.0, 0.0,\n 0.0, 0.0, 0.0, 1.0\n )`,\n dataType: mat4x4f,\n }),\n 'identity4',\n);\n\nconst identityFunctions = {\n 2: identity2,\n 3: identity3,\n 4: identity4,\n};\n\n/**\n * Creates a 4-by-4 matrix which translates by the given vector v.\n * @param {v3f} vector - The vector by which to translate.\n * @returns {m4x4f} The translation matrix.\n */\nexport const translation4 = createDualImpl(\n // CPU implementation\n (vector: v3f) =>\n // deno-fmt-ignore\n mat4x4f(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0,\n vector.x, vector.y, vector.z, 1,\n ),\n // GPU implementation\n (vector) => ({\n value: `mat4x4f(\n 1, 0, 0, 0,\n 0, 1, 0, 0,\n 0, 0, 1, 0, \n ${vector.value}.x, ${vector.value}.y, ${vector.value}.z, 1\n )`,\n dataType: mat4x4f,\n }),\n 'translation4',\n);\n\n/**\n * Creates a 4-by-4 matrix which scales in each dimension by an amount given by the corresponding entry in the given vector.\n * @param {v3f} vector - A vector of three entries specifying the factor by which to scale in each dimension.\n * @returns {m4x4f} The scaling matrix.\n */\nexport const scaling4 = createDualImpl(\n // CPU implementation\n (vector: v3f) =>\n // deno-fmt-ignore\n mat4x4f(\n vector.x, 0, 0, 0,\n 0, vector.y, 0, 0,\n 0, 0, vector.z, 0,\n 0, 0, 0, 1,\n ),\n // GPU implementation\n (vector) => ({\n value: `mat4x4f(\n ${vector.value}.x, 0, 0, 0,\n 0, ${vector.value}.y, 0, 0,\n 0, 0, ${vector.value}.z, 0, \n 0, 0, 0, 1\n )`,\n dataType: mat4x4f,\n }),\n 'scaling4',\n);\n\n/**\n * Creates a 4-by-4 matrix which rotates around the x-axis by the given angle.\n * @param {number} angle - The angle by which to rotate (in radians).\n * @returns {m4x4f} The rotation matrix.\n */\nexport const rotationX4 = createDualImpl(\n // CPU implementation\n (a: number) =>\n // deno-fmt-ignore\n mat4x4f(\n 1, 0, 0, 0,\n 0, Math.cos(a), Math.sin(a), 0,\n 0, -Math.sin(a), Math.cos(a), 0,\n 0, 0, 0, 1,\n ),\n // GPU implementation\n (a) =>\n snip(\n `mat4x4f(\n 1, 0, 0, 0,\n 0, cos(${a.value}), sin(${a.value}), 0,\n 0, -sin(${a.value}), cos(${a.value}), 0,\n 0, 0, 0, 1\n )`,\n mat4x4f,\n ),\n 'rotationX4',\n);\n\n/**\n * Creates a 4-by-4 matrix which rotates around the y-axis by the given angle.\n * @param {number} angle - The angle by which to rotate (in radians).\n * @returns {m4x4f} The rotation matrix.\n */\nexport const rotationY4 = createDualImpl(\n // CPU implementation\n (a: number) =>\n // deno-fmt-ignore\n mat4x4f(\n Math.cos(a), 0, -Math.sin(a), 0,\n 0, 1, 0, 0,\n Math.sin(a), 0, Math.cos(a), 0,\n 0, 0, 0, 1,\n ),\n // GPU implementation\n (a) =>\n snip(\n `mat4x4f(\n cos(${a.value}), 0, -sin(${a.value}), 0,\n 0, 1, 0, 0,\n sin(${a.value}), 0, cos(${a.value}), 0,\n 0, 0, 0, 1\n )`,\n mat4x4f,\n ),\n 'rotationY4',\n);\n\n/**\n * Creates a 4-by-4 matrix which rotates around the z-axis by the given angle.\n * @param {number} angle - The angle by which to rotate (in radians).\n * @returns {m4x4f} The rotation matrix.\n */\nexport const rotationZ4 = createDualImpl(\n // CPU implementation\n (a: number) =>\n // deno-fmt-ignore\n mat4x4f(\n Math.cos(a), Math.sin(a), 0, 0,\n -Math.sin(a), Math.cos(a), 0, 0,\n 0, 0, 1, 0,\n 0, 0, 0, 1,\n ),\n // GPU implementation\n (a) =>\n snip(\n `mat4x4f(\n cos(${a.value}), sin(${a.value}), 0, 0,\n -sin(${a.value}), cos(${a.value}), 0, 0,\n 0, 0, 1, 0,\n 0, 0, 0, 1\n )`,\n mat4x4f,\n ),\n 'rotationZ4',\n);\n\n// ----------\n// Public API\n// ----------\n\n/**\n * Schema representing mat2x2f - a matrix with 2 rows and 2 columns, with elements of type f32.\n * Also a constructor function for this matrix type.\n *\n * @example\n * const zero2x2 = mat2x2f(); // filled with zeros\n *\n * @example\n * const mat = mat2x2f(0, 1, 2, 3);\n * mat.columns[0] // vec2f(0, 1)\n * mat.columns[1] // vec2f(2, 3)\n *\n * @example\n * const mat = mat2x2f(\n * vec2f(0, 1), // column 0\n * vec2f(1, 2), // column 1\n * );\n *\n * @example\n * const buffer = root.createBuffer(d.mat2x2f, d.mat2x2f(0, 1, 2, 3)); // buffer holding a d.mat2x2f value, with an initial value of ((0, 1), (2, 3))\n */\nexport const mat2x2f = createMatSchema<'mat2x2f', m2x2f, v2f>({\n type: 'mat2x2f',\n rows: 2,\n columns: 2,\n makeFromElements: (...elements: number[]) => new mat2x2fImpl(...elements),\n}) as Mat2x2f;\n\n/**\n * Schema representing mat3x3f - a matrix with 3 rows and 3 columns, with elements of type f32.\n * Also a constructor function for this matrix type.\n *\n * @example\n * const zero3x3 = mat3x3f(); // filled with zeros\n *\n * @example\n * const mat = mat3x3f(0, 1, 2, 3, 4, 5, 6, 7, 8);\n * mat.columns[0] // vec3f(0, 1, 2)\n * mat.columns[1] // vec3f(3, 4, 5)\n * mat.columns[2] // vec3f(6, 7, 8)\n *\n * @example\n * const mat = mat3x3f(\n * vec3f(0, 1, 2), // column 0\n * vec3f(2, 3, 4), // column 1\n * vec3f(5, 6, 7), // column 2\n * );\n *\n * @example\n * const buffer = root.createBuffer(d.mat3x3f, d.mat3x3f()); // buffer holding a d.mat3x3f value, with an initial value of mat3x3f filled with zeros\n */\nexport const mat3x3f = createMatSchema<'mat3x3f', m3x3f, v3f>({\n type: 'mat3x3f',\n rows: 3,\n columns: 3,\n makeFromElements: (...elements: number[]) => new mat3x3fImpl(...elements),\n}) as Mat3x3f;\n\n/**\n * Schema representing mat4x4f - a matrix with 4 rows and 4 columns, with elements of type f32.\n * Also a constructor function for this matrix type.\n *\n * @example\n * const zero4x4 = mat4x4f(); // filled with zeros\n *\n * @example\n * const mat = mat4x4f(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);\n * mat.columns[0] // vec4f(0, 1, 2, 3)\n * mat.columns[1] // vec4f(4, 5, 6, 7)\n * mat.columns[2] // vec4f(8, 9, 10, 11)\n * mat.columns[3] // vec4f(12, 13, 14, 15)\n *\n * @example\n * const mat = mat4x4f(\n * vec4f(0, 1, 2, 3), // column 0\n * vec4f(4, 5, 6, 7), // column 1\n * vec4f(8, 9, 10, 11), // column 2\n * vec4f(12, 13, 14, 15), // column 3\n * );\n *\n * @example\n * const buffer = root.createBuffer(d.mat4x4f, d.mat4x4f()); // buffer holding a d.mat4x4f value, with an initial value of mat4x4f filled with zeros\n */\nexport const mat4x4f = createMatSchema<'mat4x4f', m4x4f, v4f>({\n type: 'mat4x4f',\n rows: 4,\n columns: 4,\n makeFromElements: (...elements: number[]) => new mat4x4fImpl(...elements),\n}) as Mat4x4f;\n\nexport function matToArray(mat: m2x2f | m3x3f | m4x4f): number[] {\n if (mat.kind === 'mat3x3f') {\n return [\n mat[0],\n mat[1],\n mat[2],\n mat[4],\n mat[5],\n mat[6],\n mat[8],\n mat[9],\n mat[10],\n ] as number[];\n }\n\n return Array.from({ length: mat.length }).map((_, idx) => mat[idx] as number);\n}\n","import { $internal } from '../shared/symbols.ts';\nimport type { AnyData } from './dataTypes.ts';\nimport type { Ptr } from './wgslTypes.ts';\n\nexport function ptrFn<T extends AnyData>(\n inner: T,\n): Ptr<'function', T, 'read-write'> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'function',\n access: 'read-write',\n } as Ptr<'function', T, 'read-write'>;\n}\n\nexport function ptrPrivate<T extends AnyData>(\n inner: T,\n): Ptr<'private', T, 'read-write'> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'private',\n access: 'read-write',\n } as Ptr<'private', T, 'read-write'>;\n}\n\nexport function ptrWorkgroup<T extends AnyData>(\n inner: T,\n): Ptr<'workgroup', T, 'read-write'> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'workgroup',\n access: 'read-write',\n } as Ptr<'workgroup', T, 'read-write'>;\n}\n\nexport function ptrStorage<\n T extends AnyData,\n TAccess extends 'read' | 'read-write' = 'read',\n>(inner: T, access: TAccess = 'read' as TAccess): Ptr<'storage', T, TAccess> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'storage',\n access,\n } as Ptr<'storage', T, TAccess>;\n}\n\nexport function ptrUniform<T extends AnyData>(\n inner: T,\n): Ptr<'uniform', T, 'read'> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'uniform',\n access: 'read',\n } as Ptr<'uniform', T, 'read'>;\n}\n\nexport function ptrHandle<T extends AnyData>(\n inner: T,\n): Ptr<'handle', T, 'read'> {\n return {\n [$internal]: true,\n type: 'ptr',\n inner,\n addressSpace: 'handle',\n access: 'read',\n } as Ptr<'handle', T, 'read'>;\n}\n"]}