simulationjsv2 0.7.4 → 0.8.1

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/dist/index.js CHANGED
@@ -2,4 +2,6 @@ export * from './simulation.js';
2
2
  export * from './graphics.js';
3
3
  export * from './utils.js';
4
4
  export * from './types.js';
5
+ export * from './shaders.js';
6
+ export * from './materials.js';
5
7
  export { vec2, vec3, vec4, mat3, mat4 } from 'wgpu-matrix';
@@ -1,9 +1,8 @@
1
1
  /// <reference types="@webgpu/types" />
2
- import { VertexParamGeneratorInfo, Mat4, Vector2, Vector3, VertexParamInfo } from './types.js';
3
- import { Color } from './utils.js';
2
+ import { Mat4, Vector2, Vector3 } from './types.js';
4
3
  import { SimulationElement3d } from './graphics.js';
5
4
  import { Shader } from './shaders.js';
6
- export declare class VertexCache {
5
+ export declare class Float32ArrayCache {
7
6
  private vertices;
8
7
  private hasUpdated;
9
8
  constructor();
@@ -11,24 +10,16 @@ export declare class VertexCache {
11
10
  getCache(): Float32Array;
12
11
  updated(): void;
13
12
  shouldUpdate(): boolean;
14
- getVertexCount(): number;
13
+ getVertexCount(stride?: number): number;
15
14
  }
16
- export declare class GlobalInfo {
17
- private device;
18
- constructor();
19
- setDevice(device: GPUDevice): void;
20
- errorGetDevice(): GPUDevice;
21
- getDevice(): GPUDevice | null;
22
- }
23
- export declare const globalInfo: GlobalInfo;
24
15
  export declare class CachedArray<T> {
25
- private length;
16
+ length: number;
26
17
  private data;
27
18
  constructor();
28
19
  add(index: T): void;
29
20
  reset(): void;
30
21
  clearCache(): void;
31
- toArray(): T[];
22
+ getArray(): T[];
32
23
  }
33
24
  export declare const updateProjectionMatrix: (mat: Mat4, aspectRatio: number, zNear?: number, zFar?: number) => any;
34
25
  export declare const updateWorldProjectionMatrix: (worldProjMat: Mat4, projMat: Mat4) => void;
@@ -55,41 +46,13 @@ export declare class SimSceneObjInfo {
55
46
  getObj(): SimulationElement3d;
56
47
  getId(): string | null;
57
48
  }
58
- declare class Logger {
59
- constructor();
60
- private fmt;
61
- log(msg: string): void;
62
- error(msg: string): Error;
63
- warn(msg: string): void;
64
- log_error(msg: string): void;
65
- }
66
- export declare const logger: Logger;
67
49
  export declare function lossyTriangulate<T>(vertices: T[]): (readonly [T, T, T])[];
68
50
  export declare function lossyTriangulateStrip<T>(vertices: T[]): T[];
69
- declare class BufferGenerator {
70
- private instancing;
71
- constructor();
72
- setInstancing(state: boolean): void;
73
- generate(x: number, y: number, z: number, color: Color, uv?: Vector2, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
74
- }
75
- export declare const bufferGenerator: BufferGenerator;
51
+ export declare function createIndexArray(length: number): number[];
76
52
  export declare function vector3ToPixelRatio(vec: Vector3): void;
77
53
  export declare function vector2ToPixelRatio(vec: Vector2): void;
78
- export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, topology: GPUPrimitiveTopology, transparent: boolean, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
79
54
  export declare function triangulateWireFrameOrder(len: number): number[];
80
- export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
81
- export declare function vectorCompAngle(a: number, b: number): number;
82
- export declare function angleBetween(pos1: Vector3, pos2: Vector3): Vector3;
55
+ export declare function getVertexAndIndexSize(scene: SimSceneObjInfo[]): readonly [number, number];
83
56
  export declare function internalTransitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
84
57
  export declare function posTo2dScreen(pos: Vector3): Vector3;
85
- export declare function createShaderModule(shader: Shader): GPUShaderModule;
86
- export declare function createDefaultPipelines(shader: Shader): {
87
- triangleList: GPURenderPipeline;
88
- triangleStrip: GPURenderPipeline;
89
- lineStrip: GPURenderPipeline;
90
- triangleListTransparent: GPURenderPipeline;
91
- triangleStripTransparent: GPURenderPipeline;
92
- lineStripTransparent: GPURenderPipeline;
93
- };
94
- export default function createUniformBindGroup(shader: Shader, buffers: GPUBuffer[]): GPUBindGroup;
95
- export {};
58
+ export declare function createPipeline(device: GPUDevice, info: string, shader: Shader): GPURenderPipeline;
@@ -1,9 +1,8 @@
1
1
  import { mat4, vec3 } from 'wgpu-matrix';
2
- import { BUF_LEN, colorOffset, drawingInstancesOffset, uvOffset, vertexSize } from './constants.js';
3
- import { cloneBuf, transitionValues, vector2, vector3 } from './utils.js';
2
+ import { cloneBuf, transitionValues } from './utils.js';
4
3
  import { camera } from './simulation.js';
5
4
  import { settings } from './settings.js';
6
- export class VertexCache {
5
+ export class Float32ArrayCache {
7
6
  vertices;
8
7
  hasUpdated = true;
9
8
  constructor() {
@@ -22,28 +21,10 @@ export class VertexCache {
22
21
  shouldUpdate() {
23
22
  return this.hasUpdated;
24
23
  }
25
- getVertexCount() {
26
- return this.vertices.length / BUF_LEN;
24
+ getVertexCount(stride = 1) {
25
+ return this.vertices.length / stride;
27
26
  }
28
27
  }
29
- export class GlobalInfo {
30
- device;
31
- constructor() {
32
- this.device = null;
33
- }
34
- setDevice(device) {
35
- this.device = device;
36
- }
37
- errorGetDevice() {
38
- if (!this.device)
39
- throw logger.error('GPUDevice is null');
40
- return this.device;
41
- }
42
- getDevice() {
43
- return this.device;
44
- }
45
- }
46
- export const globalInfo = new GlobalInfo();
47
28
  export class CachedArray {
48
29
  length;
49
30
  data;
@@ -67,8 +48,8 @@ export class CachedArray {
67
48
  this.reset();
68
49
  this.data = [];
69
50
  }
70
- toArray() {
71
- return this.data.slice(0, this.length);
51
+ getArray() {
52
+ return this.data;
72
53
  }
73
54
  }
74
55
  export const updateProjectionMatrix = (mat, aspectRatio, zNear = 1, zFar = 500) => {
@@ -79,7 +60,7 @@ export const updateWorldProjectionMatrix = (worldProjMat, projMat) => {
79
60
  mat4.identity(worldProjMat);
80
61
  const camPos = cloneBuf(camera.getPos());
81
62
  const rotation = camera.getRotation();
82
- vec3.scale(camPos, -1, camPos);
63
+ vec3.negate(camPos, camPos);
83
64
  mat4.rotateZ(worldProjMat, rotation[2], worldProjMat);
84
65
  mat4.rotateY(worldProjMat, rotation[1], worldProjMat);
85
66
  mat4.rotateX(worldProjMat, rotation[0], worldProjMat);
@@ -151,25 +132,6 @@ export class SimSceneObjInfo {
151
132
  return this.id;
152
133
  }
153
134
  }
154
- class Logger {
155
- constructor() { }
156
- fmt(msg) {
157
- return `SimJS: ${msg}`;
158
- }
159
- log(msg) {
160
- console.log(this.fmt(msg));
161
- }
162
- error(msg) {
163
- return new Error(this.fmt(msg));
164
- }
165
- warn(msg) {
166
- console.warn(this.fmt(msg));
167
- }
168
- log_error(msg) {
169
- console.error(this.fmt(msg));
170
- }
171
- }
172
- export const logger = new Logger();
173
135
  // optomized for speed, depending on orientation of vertices as input, shape may not be preserved
174
136
  export function lossyTriangulate(vertices) {
175
137
  const res = [];
@@ -218,25 +180,11 @@ export function lossyTriangulateStrip(vertices) {
218
180
  res.push(vertices[upper]);
219
181
  return res;
220
182
  }
221
- class BufferGenerator {
222
- instancing = false;
223
- constructor() { }
224
- setInstancing(state) {
225
- this.instancing = state;
226
- }
227
- generate(x, y, z, color, uv = vector2(), vertexParamGenerator) {
228
- if (vertexParamGenerator) {
229
- const buf = vertexParamGenerator.createBuffer(x, y, z, color);
230
- if (buf.length !== vertexParamGenerator.bufferSize) {
231
- logger.log_error(`Vertex size for shader group does not match buffer extension size (${buf.length} to expected ${vertexParamGenerator.bufferSize})`);
232
- return [];
233
- }
234
- return buf;
235
- }
236
- return [x, y, z, ...color.toBuffer(), ...uv, this.instancing ? 1 : 0];
237
- }
183
+ export function createIndexArray(length) {
184
+ return Array(length)
185
+ .fill(0)
186
+ .map((_, index) => index);
238
187
  }
239
- export const bufferGenerator = new BufferGenerator();
240
188
  export function vector3ToPixelRatio(vec) {
241
189
  vec[0] *= devicePixelRatio;
242
190
  vec[1] *= devicePixelRatio;
@@ -246,63 +194,56 @@ export function vector2ToPixelRatio(vec) {
246
194
  vec[0] *= devicePixelRatio;
247
195
  vec[1] *= devicePixelRatio;
248
196
  }
249
- export function createPipeline(device, module, bindGroupLayouts, presentationFormat, topology, transparent, vertexParams) {
250
- let params = [
251
- {
252
- // position
253
- shaderLocation: 0,
254
- offset: 0,
255
- format: 'float32x4'
256
- },
257
- {
258
- // color
259
- shaderLocation: 1,
260
- offset: colorOffset,
261
- format: 'float32x4'
262
- },
263
- {
264
- // size
265
- shaderLocation: 2,
266
- offset: uvOffset,
267
- format: 'float32x2'
268
- },
269
- {
270
- // drawing instances
271
- shaderLocation: 3,
272
- offset: drawingInstancesOffset,
273
- format: 'float32'
274
- }
275
- ];
276
- let stride = vertexSize;
277
- if (vertexParams) {
278
- params = [];
279
- let offset = 0;
280
- for (let i = 0; i < vertexParams.length; i++) {
281
- params.push({
282
- shaderLocation: i,
283
- offset,
284
- format: vertexParams[i].format
285
- });
286
- offset += vertexParams[i].size;
287
- }
288
- stride = offset;
197
+ export function triangulateWireFrameOrder(len) {
198
+ const order = Array(len)
199
+ .fill(0)
200
+ .map((_, index) => index);
201
+ let front = 0;
202
+ let back = len - 1;
203
+ while (front < back) {
204
+ order.push(front, back);
205
+ front++;
206
+ back--;
289
207
  }
208
+ return order;
209
+ }
210
+ export function getVertexAndIndexSize(scene) {
211
+ let vertexSize = 0;
212
+ let indexSize = 0;
213
+ for (let i = 0; i < scene.length; i++) {
214
+ const obj = scene[i].getObj();
215
+ vertexSize += obj.getVertexCount() * obj.getShader().getBufferLength();
216
+ indexSize += obj.getIndexCount();
217
+ }
218
+ return [vertexSize, indexSize];
219
+ }
220
+ export function internalTransitionValues(onFrame, adjustment, transitionLength, func) {
221
+ const newAdjustment = () => {
222
+ if (settings.transformAdjustments)
223
+ adjustment();
224
+ };
225
+ return transitionValues(onFrame, newAdjustment, transitionLength, func);
226
+ }
227
+ export function posTo2dScreen(pos) {
228
+ const newPos = cloneBuf(pos);
229
+ newPos[1] = camera.getScreenSize()[1] + newPos[1];
230
+ return newPos;
231
+ }
232
+ export function createPipeline(device, info, shader) {
233
+ const shaderModule = shader.getModule();
234
+ const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
235
+ const infoObj = JSON.parse(info);
290
236
  return device.createRenderPipeline({
291
237
  layout: device.createPipelineLayout({
292
- bindGroupLayouts: bindGroupLayouts
238
+ bindGroupLayouts: shader.getBindGroupLayouts()
293
239
  }),
294
240
  vertex: {
295
- module,
296
- entryPoint: 'vertex_main',
297
- buffers: [
298
- {
299
- arrayStride: stride,
300
- attributes: params
301
- }
302
- ]
241
+ module: shaderModule,
242
+ entryPoint: shader.getVertexMain(),
243
+ buffers: [shader.getVertexBuffers()]
303
244
  },
304
245
  fragment: {
305
- module,
246
+ module: shaderModule,
306
247
  entryPoint: 'fragment_main',
307
248
  targets: [
308
249
  {
@@ -321,98 +262,17 @@ export function createPipeline(device, module, bindGroupLayouts, presentationFor
321
262
  ]
322
263
  },
323
264
  primitive: {
324
- topology
265
+ topology: infoObj.topology,
266
+ stripIndexFormat: infoObj.topology.endsWith('strip') ? 'uint32' : undefined,
267
+ cullMode: infoObj.cullMode
325
268
  },
326
269
  multisample: {
327
270
  count: 4
328
271
  },
329
272
  depthStencil: {
330
- depthWriteEnabled: !transparent,
273
+ depthWriteEnabled: !infoObj.transparent,
331
274
  depthCompare: 'less',
332
275
  format: 'depth24plus'
333
276
  }
334
277
  });
335
278
  }
336
- export function triangulateWireFrameOrder(len) {
337
- const order = Array(len)
338
- .fill(0)
339
- .map((_, index) => index);
340
- let front = 0;
341
- let back = len - 1;
342
- while (front < back) {
343
- order.push(front, back);
344
- front++;
345
- back--;
346
- }
347
- return order;
348
- }
349
- export function getTotalVertices(scene) {
350
- let total = 0;
351
- for (let i = 0; i < scene.length; i++) {
352
- const obj = scene[i].getObj();
353
- total += obj.getVertexCount();
354
- }
355
- return total;
356
- }
357
- export function vectorCompAngle(a, b) {
358
- if (a === 0)
359
- return 0;
360
- else {
361
- if (b === 0)
362
- return 0;
363
- else
364
- return Math.atan2(a, b);
365
- }
366
- }
367
- export function angleBetween(pos1, pos2) {
368
- const diff = vec3.sub(pos1, pos2);
369
- const angleZ = vectorCompAngle(diff[0], diff[1]);
370
- const angleY = vectorCompAngle(diff[2], diff[0]);
371
- const angleX = vectorCompAngle(diff[2], diff[1]);
372
- return vector3(angleX, angleY, angleZ);
373
- }
374
- export function internalTransitionValues(onFrame, adjustment, transitionLength, func) {
375
- const newAdjustment = () => {
376
- if (settings.transformAdjustments)
377
- adjustment();
378
- };
379
- return transitionValues(onFrame, newAdjustment, transitionLength, func);
380
- }
381
- export function posTo2dScreen(pos) {
382
- const newPos = cloneBuf(pos);
383
- newPos[1] = camera.getScreenSize()[1] + newPos[1];
384
- return newPos;
385
- }
386
- export function createShaderModule(shader) {
387
- const device = globalInfo.errorGetDevice();
388
- return device.createShaderModule({
389
- code: shader.getCode()
390
- });
391
- }
392
- export function createDefaultPipelines(shader) {
393
- const device = globalInfo.errorGetDevice();
394
- const bindGroupLayout = device.createBindGroupLayout(shader.getBindGroupLayoutDescriptor());
395
- const shaderModule = createShaderModule(shader);
396
- const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
397
- return {
398
- triangleList: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list', false),
399
- triangleStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip', false),
400
- lineStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip', false),
401
- triangleListTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list', true),
402
- triangleStripTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip', true),
403
- lineStripTransparent: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip', true)
404
- };
405
- }
406
- export default function createUniformBindGroup(shader, buffers) {
407
- const device = globalInfo.errorGetDevice();
408
- const bindGroupLayout = shader.getBindGroupLayout();
409
- return device.createBindGroup({
410
- layout: bindGroupLayout,
411
- entries: buffers.map((buffer, index) => ({
412
- binding: index,
413
- resource: {
414
- buffer
415
- }
416
- }))
417
- });
418
- }
@@ -1,3 +1,20 @@
1
+ import { Color } from './utils.js';
1
2
  export declare class Material {
3
+ protected color: Color;
4
+ protected vertexColors: Color[];
5
+ protected isVertexColors: boolean;
6
+ constructor();
7
+ hasVertexColors(): boolean;
8
+ getVertexColors(): Color[];
9
+ getColor(): Color;
10
+ addVertexColor(color: Color): void;
11
+ setVertexColors(colors: Color[]): void;
12
+ isTransparent(): boolean;
13
+ setColor(color: Color): void;
14
+ }
15
+ export declare class BasicMaterial extends Material {
16
+ constructor(color: Color);
17
+ }
18
+ export declare class VertexColorMaterial extends Material {
2
19
  constructor();
3
20
  }
package/dist/materials.js CHANGED
@@ -1,3 +1,51 @@
1
+ import { color } from './utils.js';
1
2
  export class Material {
2
- constructor() { }
3
+ color;
4
+ vertexColors;
5
+ isVertexColors;
6
+ constructor() {
7
+ this.color = color();
8
+ this.vertexColors = [];
9
+ this.isVertexColors = false;
10
+ }
11
+ hasVertexColors() {
12
+ return this.isVertexColors;
13
+ }
14
+ getVertexColors() {
15
+ return this.vertexColors;
16
+ }
17
+ getColor() {
18
+ return this.color;
19
+ }
20
+ addVertexColor(color) {
21
+ this.vertexColors.push(color);
22
+ }
23
+ setVertexColors(colors) {
24
+ this.vertexColors = colors;
25
+ }
26
+ isTransparent() {
27
+ if (this.isVertexColors) {
28
+ for (let i = 0; i < this.vertexColors.length; i++) {
29
+ if (this.vertexColors[i].isTransparent())
30
+ return true;
31
+ }
32
+ return false;
33
+ }
34
+ return this.color.isTransparent();
35
+ }
36
+ setColor(color) {
37
+ this.color = color;
38
+ }
39
+ }
40
+ export class BasicMaterial extends Material {
41
+ constructor(color) {
42
+ super();
43
+ this.color = color;
44
+ }
45
+ }
46
+ export class VertexColorMaterial extends Material {
47
+ constructor() {
48
+ super();
49
+ this.isVertexColors = true;
50
+ }
3
51
  }
package/dist/shaders.d.ts CHANGED
@@ -1,11 +1,37 @@
1
1
  /// <reference types="@webgpu/types" />
2
+ import { SimulationElement3d } from './graphics.js';
3
+ import { BindGroupGenerator, BufferInfo, BufferWriter, Vector3, VertexBufferWriter, VertexParamInfo } from './types.js';
4
+ export declare const uniformBufferSize: number;
2
5
  export declare class Shader {
3
- private bindGroupLayoutDescriptor;
4
- private bindGroupLayout;
6
+ private bindGroupLayoutDescriptors;
7
+ private bindGroupLayouts;
8
+ private module;
5
9
  private code;
6
- constructor(code: string, descriptor: GPUBindGroupLayoutDescriptor);
10
+ private fragmentMain;
11
+ private vertexMain;
12
+ private vertexBuffers;
13
+ private bufferLength;
14
+ private bufferWriter;
15
+ private vertexBufferWriter;
16
+ private bindGroupGenerator;
17
+ private buffers;
18
+ private bufferInfos;
19
+ constructor(code: string, descriptors: GPUBindGroupLayoutDescriptor[], vertexParams: VertexParamInfo[], bufferInfos: BufferInfo[], bufferWriter: BufferWriter, bindGroupGenerator: BindGroupGenerator, vertexBufferWriter: VertexBufferWriter, vertexMain?: string, fragmentMain?: string);
7
20
  getCode(): string;
8
- getBindGroupLayout(): GPUBindGroupLayout;
9
- getBindGroupLayoutDescriptor(): GPUBindGroupLayoutDescriptor;
21
+ getBufferLength(): number;
22
+ getVertexBuffers(): GPUVertexBufferLayout;
23
+ getBindGroupLayouts(): GPUBindGroupLayout[];
24
+ getBindGroupLayoutDescriptors(): GPUBindGroupLayoutDescriptor[];
25
+ getBufferInfo(): BufferInfo[];
26
+ getBufferWriter(): BufferWriter;
27
+ getVertexBufferWriter(): VertexBufferWriter;
28
+ getBindGroupGenerator(): BindGroupGenerator;
29
+ getModule(): GPUShaderModule;
30
+ getVertexMain(): string;
31
+ getFragmentMain(): string;
32
+ setVertexInfo(element: SimulationElement3d, buffer: Float32Array, vertex: Vector3, vertexIndex: number, offset: number): void;
33
+ writeBuffers(el: SimulationElement3d): void;
34
+ getBindGroups(el: SimulationElement3d): GPUBindGroup[];
10
35
  }
11
36
  export declare const defaultShader: Shader;
37
+ export declare const vertexColorShader: Shader;