Skip to content

Commit

Permalink
feat(vector-pools): update AttribPool, add tests, update readme
Browse files Browse the repository at this point in the history
- add AttribPool.setAttribs()
- add opt start index arg for setAttribValues()
- update AttribSpec to include opt. initial values
- fix readme example
- add missing deps
  • Loading branch information
postspectacular committed Apr 7, 2019
1 parent 6d8aad9 commit 33109d0
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 45 deletions.
28 changes: 15 additions & 13 deletions packages/vector-pools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,34 +54,37 @@ import * as v from "@thi.ng/vectors";
import * as tx from "@thi.ng/transducers";

// create an interleaved (AOS layout) attribute buffer w/ default values
const geo = new AttribPool(
const geo = new AttribPool({
// initial size in bytes (or provide ArrayBuffer or @thi.ng/malloc/MemPool)
0x200,
mem: { size: 0x200 },
// num elements
4,
num: 4,
// attrib specs (data mapping layout)
{
pos: { type: GLType.F32, size: 3, default: [0, 0, 0], byteOffset: 0 },
uv: { type: GLType.F32, size: 2, default: [0, 0], byteOffset: 12 },
attribs: {
pos: { type: GLType.F32, size: 3, byteOffset: 0 },
uv: { type: GLType.F32, size: 2, byteOffset: 12 },
col: { type: GLType.F32, size: 3, default: [1, 1, 1], byteOffset: 20 },
id: { type: GLType.U16, size: 1, default: 0, byteOffset: 32 }
id: { type: GLType.U16, size: 1, byteOffset: 32 }
}
);
});

// computed overall stride length
geo.byteStride
// 36

// set attrib values
geo.setAttribValues("pos", [[-5, 0, 0], [5, 0, 0], [5, 5, 0], [-5, 5, 0]]);
geo.setAttribValues("uv", [[0, 0], [1, 0], [1, 1], [0, 1]]);
geo.setAttribs({
pos: { data: [[-5, 0, 0], [5, 0, 0], [5, 5, 0], [-5, 5, 0]]},
uv: { data: [[0, 0], [1, 0], [1, 1], [0, 1]] }
});
// ...or individually
geo.setAttribValues("id", [0, 1, 2, 3]);

// get view of individual attrib val
geo.attribValue("pos", 3)
// Float32Array [ -5, 5, 0 ]

// zero-copy direct manipulation of attrib val
// zero-copy direct manipulation of mapped attrib val
v.mulN(null, geo.attribValue("pos", 3), 2);
// Float32Array [ -10, 10, 0 ]

Expand All @@ -95,7 +98,7 @@ v.mulN(null, geo.attribValue("pos", 3), 2);
// use with transducers, e.g. to map positions to colors
tx.run(
tx.map(([pos, col]) => v.maddN(col, [0.5, 0.5, 0.5], v.normalize(col, pos), 0.5)),
tx.tuples(geo.attribValues("pos"), geo.attribValues("col"))
tx.zip(geo.attribValues("pos"), geo.attribValues("col"))
);

// updated colors
Expand Down Expand Up @@ -140,7 +143,6 @@ const initAttrib = (gl, loc, attrib) => {
initAttrib(gl, attribLocPosition, geo.specs.pos);
initAttrib(gl, attribLocNormal, geo.specs.normal);
initAttrib(gl, attribLocUV, geo.specs.uv);
initAttrib(gl, attribLocID, geo.specs.id);
```

### WASM interop
Expand Down
3 changes: 3 additions & 0 deletions packages/vector-pools/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,10 @@
},
"dependencies": {
"@thi.ng/api": "^6.0.1",
"@thi.ng/binary": "^1.0.5",
"@thi.ng/checks": "^2.1.5",
"@thi.ng/malloc": "^2.0.8",
"@thi.ng/transducers": "^5.3.3",
"@thi.ng/vectors": "^2.5.2"
},
"keywords": [
Expand Down
4 changes: 3 additions & 1 deletion packages/vector-pools/src/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import { ReadonlyVec, StridedVec, Vec } from "@thi.ng/vectors";
export interface AttribSpec {
type: GLType | Type;
size: number;
default?: number | ReadonlyVec;
byteOffset: number;
stride?: number;
default?: number | ReadonlyVec;
data?: ReadonlyVec | ReadonlyVec[];
index?: number;
}

export interface AttribPoolOpts {
Expand Down
41 changes: 30 additions & 11 deletions packages/vector-pools/src/attrib-pool.ts
Original file line number Diff line number Diff line change
@@ -1,19 +1,26 @@
import { assert, IObjectOf, IRelease, TypedArray } from "@thi.ng/api";
import {
assert,
IObjectOf,
IRelease,
TypedArray
} from "@thi.ng/api";
import { align, Pow2 } from "@thi.ng/binary";
import { MemPool, SIZEOF, wrap } from "@thi.ng/malloc";
import { range } from "@thi.ng/transducers";
import { ReadonlyVec, Vec, zeroes } from "@thi.ng/vectors";
import { asNativeType } from "./convert";
import { AttribPoolOpts, AttribSpec } from "./api";
import { asNativeType } from "./convert";

/*
* 0x00 0x08 0x10 0x18
* ^ ^ ^ ^
* WASM mem : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ...
* typedarr : 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ... global offset = 4 (bytes)
* pos (f32) : X X X X Y Y Y Y X ... offset = 0 (bytes), size = 2 (f32)
* uv (f32) : U U U U V V V V ... offset = 8 (bytes), size = 2 (f32)
* col (u16) : R R G G B B A A ... offset = 16 (bytes), size = 4 (u16)
*
* global stride: 24
* stride : 24
*/
export class AttribPool implements IRelease {
attribs: IObjectOf<TypedArray>;
Expand Down Expand Up @@ -77,6 +84,7 @@ export class AttribPool implements IRelease {
this.addr = addr;
}
this.initDefaults(specs);
this.setAttribs(specs);
}

attribValue(id: string, i: number): number | Vec {
Expand Down Expand Up @@ -131,17 +139,17 @@ export class AttribPool implements IRelease {
return this;
}

setAttribValues(id: string, vals: (number | ReadonlyVec)[]) {
setAttribValues(id: string, vals: ReadonlyVec | ReadonlyVec[], index = 0) {
const spec = this.specs[id];
assert(!!spec, `invalid attrib: ${id}`);
const n = vals.length;
const v = vals[0];
this.ensure(index + n);
const stride = spec.stride;
this.ensure(n);
const buf = this.attribs[id];
const v = vals[0];
const isNum = typeof v === "number";
assert(
() => (!isNum && spec.size > 1) || (isNum && spec.size === 1),
(!isNum && spec.size > 1) || (isNum && spec.size === 1),
`incompatible value(s) for attrib: ${id}`
);
if (!isNum) {
Expand All @@ -151,16 +159,27 @@ export class AttribPool implements IRelease {
(<ReadonlyVec>v).length
}`
);
for (let i = 0; i < n; i++) {
buf.set(<ReadonlyVec>vals[i], i * stride);
for (let i = 0, j = index * stride; i < n; i++, j += stride) {
buf.set(<ReadonlyVec>vals[i], j);
}
} else {
for (let i = 0; i < n; i++) {
buf[i * stride] = <number>vals[i];
for (let i = 0, j = index * stride; i < n; i++, j += stride) {
buf[j] = <number>vals[i];
}
}
}

setAttribs(
specs: IObjectOf<
Partial<{ data: ReadonlyVec | ReadonlyVec[]; index: number }>
>
) {
for (let id in specs) {
const spec = specs[id];
spec.data && this.setAttribValues(id, spec.data, spec.index || 0);
}
}

removeAttrib(id: string) {
if (!this.attribs[id]) return false;
delete this.attribs[id];
Expand Down
67 changes: 53 additions & 14 deletions packages/vector-pools/test/attribs.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,65 @@
import { AttribPool } from "../src/attrib-pool";
import { Type } from "@thi.ng/malloc";
// import * as assert from "assert";
import * as assert from "assert";
import { AttribPool } from "../src/attrib-pool";

describe("vector-pools", () => {
it("attribs", () => {
const pool = new AttribPool({
mem: { size: 0x100 },
num: 8,
attribs: {
pos: { type: Type.F32, default: [0, 0], size: 2, byteOffset: 0 },
id: { type: Type.U32, default: 0, size: 1, byteOffset: 8 },
index: { type: Type.U16, default: 0, size: 1, byteOffset: 12 },
col: { type: Type.I8, default: [0, 0, 0, 0], size: 4, byteOffset: 14 },
pos: {
type: Type.F32,
size: 2, // 8 bytes
byteOffset: 0,
data: [[1, 2], [3, 4]]
},
id: {
type: Type.U32,
size: 1, // 4 bytes
byteOffset: 8,
data: [1, 2],
index: 4
},
index: {
type: Type.U16,
size: 1, // 2 bytes
byteOffset: 12,
data: [10, 20]
},
col: {
type: Type.U8,
size: 4, // 4 bytes
byteOffset: 14,
data: [[128, 129, 130, 131], [255, 254, 253, 252]],
index: 6
}
}
});
pool.setAttribValue("pos", 0, [1, 2]);
pool.setAttribValue("id", 0, 1);
pool.setAttribValue("index", 0, 10);
pool.setAttribValue("col", 0, [128, 129, 130, 131]);
pool.setAttribValue("pos", 1, [3, 4]);
pool.setAttribValue("id", 1, 2);
pool.setAttribValue("index", 1, 20);
pool.setAttribValue("col", 1, [255, 254, 253, 252]);
assert.deepEqual(
[...pool.attribValues("pos")],
[[1, 2], [3, 4], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0], [0, 0]]
);
assert.deepEqual(
[...pool.attribValues("id")],
[0, 0, 0, 0, 1, 2, 0, 0]
);
assert.deepEqual(
[...pool.attribValues("index")],
[10, 20, 0, 0, 0, 0, 0, 0]
);
assert.deepEqual(
[...pool.attribValues("col")],
[
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[0, 0, 0, 0],
[128, 129, 130, 131],
[255, 254, 253, 252]
]
);
});
});
6 changes: 0 additions & 6 deletions packages/vector-pools/test/index.ts

This file was deleted.

0 comments on commit 33109d0

Please sign in to comment.