simulationjsv2 0.7.3 → 0.8.0

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.d.ts 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';
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,8 +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
- export declare class VertexCache {
4
+ import { Shader } from './shaders.js';
5
+ export declare class Float32ArrayCache {
6
6
  private vertices;
7
7
  private hasUpdated;
8
8
  constructor();
@@ -10,16 +10,17 @@ export declare class VertexCache {
10
10
  getCache(): Float32Array;
11
11
  updated(): void;
12
12
  shouldUpdate(): boolean;
13
- getVertexCount(): number;
13
+ getVertexCount(stride?: number): number;
14
14
  }
15
- export declare class GlobalInfo {
16
- private device;
15
+ export declare class CachedArray<T> {
16
+ length: number;
17
+ private data;
17
18
  constructor();
18
- setDevice(device: GPUDevice): void;
19
- errorGetDevice(): GPUDevice;
20
- getDevice(): GPUDevice | null;
19
+ add(index: T): void;
20
+ reset(): void;
21
+ clearCache(): void;
22
+ getArray(): T[];
21
23
  }
22
- export declare const globalInfo: GlobalInfo;
23
24
  export declare const updateProjectionMatrix: (mat: Mat4, aspectRatio: number, zNear?: number, zFar?: number) => any;
24
25
  export declare const updateWorldProjectionMatrix: (worldProjMat: Mat4, projMat: Mat4) => void;
25
26
  export declare const updateOrthoProjectionMatrix: (mat: Mat4, screenSize: [number, number]) => Float32Array;
@@ -45,31 +46,13 @@ export declare class SimSceneObjInfo {
45
46
  getObj(): SimulationElement3d;
46
47
  getId(): string | null;
47
48
  }
48
- declare class Logger {
49
- constructor();
50
- private fmt;
51
- log(msg: string): void;
52
- error(msg: string): Error;
53
- warn(msg: string): void;
54
- log_error(msg: string): void;
55
- }
56
- export declare const logger: Logger;
57
49
  export declare function lossyTriangulate<T>(vertices: T[]): (readonly [T, T, T])[];
58
50
  export declare function lossyTriangulateStrip<T>(vertices: T[]): T[];
59
- declare class BufferGenerator {
60
- private instancing;
61
- constructor();
62
- setInstancing(state: boolean): void;
63
- generate(x: number, y: number, z: number, color: Color, uv?: Vector2, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
64
- }
65
- export declare const bufferGenerator: BufferGenerator;
51
+ export declare function createIndexArray(length: number): number[];
66
52
  export declare function vector3ToPixelRatio(vec: Vector3): void;
67
53
  export declare function vector2ToPixelRatio(vec: Vector2): void;
68
- export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, topology: GPUPrimitiveTopology, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
69
54
  export declare function triangulateWireFrameOrder(len: number): number[];
70
- export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
71
- export declare function vectorCompAngle(a: number, b: number): number;
72
- export declare function angleBetween(pos1: Vector3, pos2: Vector3): Vector3;
55
+ export declare function getVertexAndIndexSize(scene: SimSceneObjInfo[]): readonly [number, number];
73
56
  export declare function internalTransitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
74
57
  export declare function posTo2dScreen(pos: Vector3): Vector3;
75
- 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,37 @@ 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;
28
+ export class CachedArray {
29
+ length;
30
+ data;
31
31
  constructor() {
32
- this.device = null;
32
+ this.length = 0;
33
+ this.data = [];
33
34
  }
34
- setDevice(device) {
35
- this.device = device;
35
+ add(index) {
36
+ if (this.length < this.data.length) {
37
+ this.data[this.length - 1] = index;
38
+ }
39
+ else {
40
+ this.data.push(index);
41
+ }
42
+ this.length++;
36
43
  }
37
- errorGetDevice() {
38
- if (!this.device)
39
- throw logger.error('GPUDevice is null');
40
- return this.device;
44
+ reset() {
45
+ this.length = 0;
41
46
  }
42
- getDevice() {
43
- return this.device;
47
+ clearCache() {
48
+ this.reset();
49
+ this.data = [];
50
+ }
51
+ getArray() {
52
+ return this.data;
44
53
  }
45
54
  }
46
- export const globalInfo = new GlobalInfo();
47
55
  export const updateProjectionMatrix = (mat, aspectRatio, zNear = 1, zFar = 500) => {
48
56
  const fov = Math.PI / 4;
49
57
  return mat4.perspective(fov, aspectRatio, zNear, zFar, mat);
@@ -52,7 +60,7 @@ export const updateWorldProjectionMatrix = (worldProjMat, projMat) => {
52
60
  mat4.identity(worldProjMat);
53
61
  const camPos = cloneBuf(camera.getPos());
54
62
  const rotation = camera.getRotation();
55
- vec3.scale(camPos, -1, camPos);
63
+ vec3.negate(camPos, camPos);
56
64
  mat4.rotateZ(worldProjMat, rotation[2], worldProjMat);
57
65
  mat4.rotateY(worldProjMat, rotation[1], worldProjMat);
58
66
  mat4.rotateX(worldProjMat, rotation[0], worldProjMat);
@@ -124,25 +132,6 @@ export class SimSceneObjInfo {
124
132
  return this.id;
125
133
  }
126
134
  }
127
- class Logger {
128
- constructor() { }
129
- fmt(msg) {
130
- return `SimJS: ${msg}`;
131
- }
132
- log(msg) {
133
- console.log(this.fmt(msg));
134
- }
135
- error(msg) {
136
- return new Error(this.fmt(msg));
137
- }
138
- warn(msg) {
139
- console.warn(this.fmt(msg));
140
- }
141
- log_error(msg) {
142
- console.error(this.fmt(msg));
143
- }
144
- }
145
- export const logger = new Logger();
146
135
  // optomized for speed, depending on orientation of vertices as input, shape may not be preserved
147
136
  export function lossyTriangulate(vertices) {
148
137
  const res = [];
@@ -191,25 +180,11 @@ export function lossyTriangulateStrip(vertices) {
191
180
  res.push(vertices[upper]);
192
181
  return res;
193
182
  }
194
- class BufferGenerator {
195
- instancing = false;
196
- constructor() { }
197
- setInstancing(state) {
198
- this.instancing = state;
199
- }
200
- generate(x, y, z, color, uv = vector2(), vertexParamGenerator) {
201
- if (vertexParamGenerator) {
202
- const buf = vertexParamGenerator.createBuffer(x, y, z, color);
203
- if (buf.length !== vertexParamGenerator.bufferSize) {
204
- logger.log_error(`Vertex size for shader group does not match buffer extension size (${buf.length} to expected ${vertexParamGenerator.bufferSize})`);
205
- return [];
206
- }
207
- return buf;
208
- }
209
- return [x, y, z, ...color.toBuffer(), ...uv, this.instancing ? 1 : 0];
210
- }
183
+ export function createIndexArray(length) {
184
+ return Array(length)
185
+ .fill(0)
186
+ .map((_, index) => index);
211
187
  }
212
- export const bufferGenerator = new BufferGenerator();
213
188
  export function vector3ToPixelRatio(vec) {
214
189
  vec[0] *= devicePixelRatio;
215
190
  vec[1] *= devicePixelRatio;
@@ -219,83 +194,6 @@ export function vector2ToPixelRatio(vec) {
219
194
  vec[0] *= devicePixelRatio;
220
195
  vec[1] *= devicePixelRatio;
221
196
  }
222
- export function createPipeline(device, module, bindGroupLayouts, presentationFormat, topology, vertexParams) {
223
- let params = [
224
- {
225
- // position
226
- shaderLocation: 0,
227
- offset: 0,
228
- format: 'float32x4'
229
- },
230
- {
231
- // color
232
- shaderLocation: 1,
233
- offset: colorOffset,
234
- format: 'float32x4'
235
- },
236
- {
237
- // size
238
- shaderLocation: 2,
239
- offset: uvOffset,
240
- format: 'float32x2'
241
- },
242
- {
243
- // drawing instances
244
- shaderLocation: 3,
245
- offset: drawingInstancesOffset,
246
- format: 'float32'
247
- }
248
- ];
249
- let stride = vertexSize;
250
- if (vertexParams) {
251
- params = [];
252
- let offset = 0;
253
- for (let i = 0; i < vertexParams.length; i++) {
254
- params.push({
255
- shaderLocation: i,
256
- offset,
257
- format: vertexParams[i].format
258
- });
259
- offset += vertexParams[i].size;
260
- }
261
- stride = offset;
262
- }
263
- return device.createRenderPipeline({
264
- layout: device.createPipelineLayout({
265
- bindGroupLayouts: bindGroupLayouts
266
- }),
267
- vertex: {
268
- module,
269
- entryPoint: 'vertex_main',
270
- buffers: [
271
- {
272
- arrayStride: stride,
273
- attributes: params
274
- }
275
- ]
276
- },
277
- fragment: {
278
- module,
279
- entryPoint: 'fragment_main',
280
- targets: [
281
- {
282
- format: presentationFormat
283
- }
284
- ]
285
- },
286
- primitive: {
287
- topology
288
- },
289
- multisample: {
290
- count: 4
291
- },
292
- depthStencil: {
293
- depthWriteEnabled: true,
294
- depthCompare: 'less',
295
- format: 'depth24plus'
296
- }
297
- });
298
- }
299
197
  export function triangulateWireFrameOrder(len) {
300
198
  const order = Array(len)
301
199
  .fill(0)
@@ -309,30 +207,15 @@ export function triangulateWireFrameOrder(len) {
309
207
  }
310
208
  return order;
311
209
  }
312
- export function getTotalVertices(scene) {
313
- let total = 0;
210
+ export function getVertexAndIndexSize(scene) {
211
+ let vertexSize = 0;
212
+ let indexSize = 0;
314
213
  for (let i = 0; i < scene.length; i++) {
315
214
  const obj = scene[i].getObj();
316
- total += obj.getVertexCount();
317
- }
318
- return total;
319
- }
320
- export function vectorCompAngle(a, b) {
321
- if (a === 0)
322
- return 0;
323
- else {
324
- if (b === 0)
325
- return 0;
326
- else
327
- return Math.atan2(a, b);
215
+ vertexSize += obj.getVertexCount() * obj.getShader().getBufferLength();
216
+ indexSize += obj.getIndexCount();
328
217
  }
329
- }
330
- export function angleBetween(pos1, pos2) {
331
- const diff = vec3.sub(pos1, pos2);
332
- const angleZ = vectorCompAngle(diff[0], diff[1]);
333
- const angleY = vectorCompAngle(diff[2], diff[0]);
334
- const angleX = vectorCompAngle(diff[2], diff[1]);
335
- return vector3(angleX, angleY, angleZ);
218
+ return [vertexSize, indexSize];
336
219
  }
337
220
  export function internalTransitionValues(onFrame, adjustment, transitionLength, func) {
338
221
  const newAdjustment = () => {
@@ -346,3 +229,50 @@ export function posTo2dScreen(pos) {
346
229
  newPos[1] = camera.getScreenSize()[1] + newPos[1];
347
230
  return newPos;
348
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);
236
+ return device.createRenderPipeline({
237
+ layout: device.createPipelineLayout({
238
+ bindGroupLayouts: shader.getBindGroupLayouts()
239
+ }),
240
+ vertex: {
241
+ module: shaderModule,
242
+ entryPoint: shader.getVertexMain(),
243
+ buffers: [shader.getVertexBuffers()]
244
+ },
245
+ fragment: {
246
+ module: shaderModule,
247
+ entryPoint: 'fragment_main',
248
+ targets: [
249
+ {
250
+ format: presentationFormat,
251
+ blend: {
252
+ color: {
253
+ srcFactor: 'src-alpha',
254
+ dstFactor: 'one-minus-src-alpha'
255
+ },
256
+ alpha: {
257
+ srcFactor: 'src-alpha',
258
+ dstFactor: 'one-minus-src-alpha'
259
+ }
260
+ }
261
+ }
262
+ ]
263
+ },
264
+ primitive: {
265
+ topology: infoObj.topology,
266
+ stripIndexFormat: infoObj.topology.endsWith('strip') ? 'uint32' : undefined,
267
+ cullMode: infoObj.cullMode
268
+ },
269
+ multisample: {
270
+ count: 4
271
+ },
272
+ depthStencil: {
273
+ depthWriteEnabled: !infoObj.transparent,
274
+ depthCompare: 'less',
275
+ format: 'depth24plus'
276
+ }
277
+ });
278
+ }
@@ -0,0 +1,20 @@
1
+ import { Color } from './utils.js';
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 {
19
+ constructor();
20
+ }
@@ -0,0 +1,51 @@
1
+ import { color } from './utils.js';
2
+ export class Material {
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
+ }
51
+ }
@@ -0,0 +1,37 @@
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;
5
+ export declare class Shader {
6
+ private bindGroupLayoutDescriptors;
7
+ private bindGroupLayouts;
8
+ private module;
9
+ private code;
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);
20
+ getCode(): string;
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[];
35
+ }
36
+ export declare const defaultShader: Shader;
37
+ export declare const vertexColorShader: Shader;