@d5techs/3dgs-lib 1.4.79 → 1.4.80

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/3dgs-lib.cjs CHANGED
@@ -17885,16 +17885,17 @@ class SelectionVolumeRenderer {
17885
17885
  constructor(renderer, camera) {
17886
17886
  __publicField(this, "renderer");
17887
17887
  __publicField(this, "camera");
17888
- __publicField(this, "pipeline", null);
17888
+ __publicField(this, "frontPipeline", null);
17889
+ __publicField(this, "behindPipeline", null);
17889
17890
  __publicField(this, "uniformBuffer", null);
17890
17891
  __publicField(this, "bindGroup", null);
17891
17892
  __publicField(this, "vertexBuffer", null);
17892
17893
  __publicField(this, "_volume", { type: null, center: [0, 0, 0], dimensions: [2, 2, 2] });
17893
17894
  __publicField(this, "vertexCount", 0);
17894
- __publicField(this, "lineColor", [0.4, 0.9, 1]);
17895
+ __publicField(this, "frontColor", [0.4, 0.9, 1]);
17895
17896
  this.renderer = renderer;
17896
17897
  this.camera = camera;
17897
- this.createPipeline();
17898
+ this.createPipelines();
17898
17899
  this.vertexBuffer = this.renderer.device.createBuffer({
17899
17900
  size: 65536,
17900
17901
  usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
@@ -17914,12 +17915,16 @@ class SelectionVolumeRenderer {
17914
17915
  setDimensions(a, b, c) {
17915
17916
  this._volume.dimensions = [a, b, c];
17916
17917
  }
17917
- createPipeline() {
17918
+ createPipelines() {
17918
17919
  const device = this.renderer.device;
17919
17920
  const shaderCode = (
17920
17921
  /* wgsl */
17921
17922
  `
17922
- struct Uniforms { viewProjection: mat4x4<f32> }
17923
+ struct Uniforms {
17924
+ viewMatrix: mat4x4<f32>,
17925
+ projMatrix: mat4x4<f32>,
17926
+ modelMatrix: mat4x4<f32>,
17927
+ }
17923
17928
  @group(0) @binding(0) var<uniform> uniforms: Uniforms;
17924
17929
 
17925
17930
  struct VI { @location(0) position: vec3<f32>, @location(1) color: vec3<f32> }
@@ -17927,62 +17932,77 @@ class SelectionVolumeRenderer {
17927
17932
 
17928
17933
  @vertex fn vs(i: VI) -> VO {
17929
17934
  var o: VO;
17930
- o.position = uniforms.viewProjection * vec4(i.position, 1.0);
17935
+ let worldPos = uniforms.modelMatrix * vec4(i.position, 1.0);
17936
+ let viewPos = uniforms.viewMatrix * worldPos;
17937
+ o.position = uniforms.projMatrix * viewPos;
17931
17938
  o.color = i.color;
17932
17939
  return o;
17933
17940
  }
17934
17941
  @fragment fn fs(i: VO) -> @location(0) vec4<f32> {
17935
- return vec4(i.color, 0.6);
17942
+ return vec4(i.color, 0.7);
17943
+ }
17944
+ @fragment fn fsBehind(i: VO) -> @location(0) vec4<f32> {
17945
+ return vec4(i.color * 0.35, 0.2);
17936
17946
  }
17937
17947
  `
17938
17948
  );
17939
17949
  const sm = device.createShaderModule({ code: shaderCode });
17940
- this.uniformBuffer = device.createBuffer({ size: 64, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
17950
+ this.uniformBuffer = device.createBuffer({ size: 192, usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST });
17941
17951
  const bgl = device.createBindGroupLayout({
17942
- entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX, buffer: { type: "uniform" } }]
17952
+ entries: [{ binding: 0, visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT, buffer: { type: "uniform" } }]
17943
17953
  });
17944
17954
  this.bindGroup = device.createBindGroup({ layout: bgl, entries: [{ binding: 0, resource: { buffer: this.uniformBuffer } }] });
17945
- this.pipeline = device.createRenderPipeline({
17946
- layout: device.createPipelineLayout({ bindGroupLayouts: [bgl] }),
17947
- vertex: {
17955
+ const layout = device.createPipelineLayout({ bindGroupLayouts: [bgl] });
17956
+ const vertexState = {
17957
+ module: sm,
17958
+ entryPoint: "vs",
17959
+ buffers: [{
17960
+ arrayStride: 24,
17961
+ attributes: [
17962
+ { shaderLocation: 0, offset: 0, format: "float32x3" },
17963
+ { shaderLocation: 1, offset: 12, format: "float32x3" }
17964
+ ]
17965
+ }]
17966
+ };
17967
+ const blendState = {
17968
+ color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha", operation: "add" },
17969
+ alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
17970
+ };
17971
+ this.frontPipeline = device.createRenderPipeline({
17972
+ layout,
17973
+ vertex: vertexState,
17974
+ fragment: {
17948
17975
  module: sm,
17949
- entryPoint: "vs",
17950
- buffers: [{
17951
- arrayStride: 24,
17952
- attributes: [
17953
- { shaderLocation: 0, offset: 0, format: "float32x3" },
17954
- { shaderLocation: 1, offset: 12, format: "float32x3" }
17955
- ]
17956
- }]
17976
+ entryPoint: "fs",
17977
+ targets: [{ format: this.renderer.format, blend: blendState }]
17957
17978
  },
17979
+ primitive: { topology: "line-list", cullMode: "none" },
17980
+ depthStencil: { format: this.renderer.depthFormat, depthWriteEnabled: false, depthCompare: "less-equal" }
17981
+ });
17982
+ this.behindPipeline = device.createRenderPipeline({
17983
+ layout,
17984
+ vertex: vertexState,
17958
17985
  fragment: {
17959
17986
  module: sm,
17960
- entryPoint: "fs",
17961
- targets: [{
17962
- format: this.renderer.format,
17963
- blend: {
17964
- color: { srcFactor: "src-alpha", dstFactor: "one-minus-src-alpha", operation: "add" },
17965
- alpha: { srcFactor: "one", dstFactor: "one-minus-src-alpha", operation: "add" }
17966
- }
17967
- }]
17987
+ entryPoint: "fsBehind",
17988
+ targets: [{ format: this.renderer.format, blend: blendState }]
17968
17989
  },
17969
17990
  primitive: { topology: "line-list", cullMode: "none" },
17970
- depthStencil: { format: this.renderer.depthFormat, depthWriteEnabled: false, depthCompare: "always" }
17991
+ depthStencil: { format: this.renderer.depthFormat, depthWriteEnabled: false, depthCompare: "greater" }
17971
17992
  });
17972
17993
  }
17973
17994
  // ========== Box: 12 edges + grid lines on all 6 faces ==========
17974
- generateBoxVertices() {
17975
- const [cx, cy, cz] = this._volume.center;
17995
+ generateBoxVertices(color) {
17976
17996
  const [lx, ly, lz] = this._volume.dimensions;
17977
17997
  const hx = lx / 2, hy = ly / 2, hz = lz / 2;
17978
- const [r, g, b] = this.lineColor;
17998
+ const [r, g, b] = color;
17979
17999
  const v = [];
17980
18000
  const line = (x12, y12, z12, x2, y2, z2) => {
17981
18001
  v.push(x12, y12, z12, r, g, b, x2, y2, z2, r, g, b);
17982
18002
  };
17983
- const x0 = cx - hx, x1 = cx + hx;
17984
- const y0 = cy - hy, y1 = cy + hy;
17985
- const z0 = cz - hz, z1 = cz + hz;
18003
+ const x0 = -hx, x1 = hx;
18004
+ const y0 = -hy, y1 = hy;
18005
+ const z0 = -hz, z1 = hz;
17986
18006
  line(x0, y0, z0, x1, y0, z0);
17987
18007
  line(x1, y0, z0, x1, y0, z1);
17988
18008
  line(x1, y0, z1, x0, y0, z1);
@@ -18026,25 +18046,24 @@ class SelectionVolumeRenderer {
18026
18046
  return new Float32Array(v);
18027
18047
  }
18028
18048
  // ========== Sphere: latitude + longitude rings ==========
18029
- generateSphereVertices() {
18030
- const [cx, cy, cz] = this._volume.center;
18049
+ generateSphereVertices(color) {
18031
18050
  const radius = this._volume.dimensions[0];
18032
- const [r, g, b] = this.lineColor;
18051
+ const [r, g, b] = color;
18033
18052
  const v = [];
18034
18053
  const addRing = (centerY, ringRadius) => {
18035
18054
  for (let i = 0; i < SEG; i++) {
18036
18055
  const a0 = i / SEG * Math.PI * 2;
18037
18056
  const a1 = (i + 1) / SEG * Math.PI * 2;
18038
18057
  v.push(
18039
- cx + Math.cos(a0) * ringRadius,
18040
- cy + centerY,
18041
- cz + Math.sin(a0) * ringRadius,
18058
+ Math.cos(a0) * ringRadius,
18059
+ centerY,
18060
+ Math.sin(a0) * ringRadius,
18042
18061
  r,
18043
18062
  g,
18044
18063
  b,
18045
- cx + Math.cos(a1) * ringRadius,
18046
- cy + centerY,
18047
- cz + Math.sin(a1) * ringRadius,
18064
+ Math.cos(a1) * ringRadius,
18065
+ centerY,
18066
+ Math.sin(a1) * ringRadius,
18048
18067
  r,
18049
18068
  g,
18050
18069
  b
@@ -18064,15 +18083,15 @@ class SelectionVolumeRenderer {
18064
18083
  const phi0 = i / SEG * Math.PI * 2;
18065
18084
  const phi1 = (i + 1) / SEG * Math.PI * 2;
18066
18085
  v.push(
18067
- cx + Math.cos(phi0) * Math.sin(theta) * radius,
18068
- cy + Math.sin(phi0) * radius,
18069
- cz + Math.cos(phi0) * Math.cos(theta) * radius,
18086
+ Math.sin(phi0) * Math.sin(theta) * radius,
18087
+ Math.cos(phi0) * radius,
18088
+ Math.sin(phi0) * Math.cos(theta) * radius,
18070
18089
  r,
18071
18090
  g,
18072
18091
  b,
18073
- cx + Math.cos(phi1) * Math.sin(theta) * radius,
18074
- cy + Math.sin(phi1) * radius,
18075
- cz + Math.cos(phi1) * Math.cos(theta) * radius,
18092
+ Math.sin(phi1) * Math.sin(theta) * radius,
18093
+ Math.cos(phi1) * radius,
18094
+ Math.sin(phi1) * Math.cos(theta) * radius,
18076
18095
  r,
18077
18096
  g,
18078
18097
  b
@@ -18082,19 +18101,36 @@ class SelectionVolumeRenderer {
18082
18101
  return new Float32Array(v);
18083
18102
  }
18084
18103
  render(pass) {
18085
- if (!this._volume.type || !this.pipeline || !this.bindGroup || !this.vertexBuffer || !this.uniformBuffer) return;
18104
+ if (!this._volume.type || !this.frontPipeline || !this.behindPipeline || !this.bindGroup || !this.vertexBuffer || !this.uniformBuffer) return;
18086
18105
  const device = this.renderer.device;
18087
- const verts = this._volume.type === "box" ? this.generateBoxVertices() : this.generateSphereVertices();
18088
- this.vertexCount = verts.length / 6;
18106
+ const [cx, cy, cz] = this._volume.center;
18107
+ const modelMatrix = new Float32Array(16);
18108
+ modelMatrix[0] = 1;
18109
+ modelMatrix[5] = 1;
18110
+ modelMatrix[10] = 1;
18111
+ modelMatrix[15] = 1;
18112
+ modelMatrix[12] = cx;
18113
+ modelMatrix[13] = cy;
18114
+ modelMatrix[14] = cz;
18115
+ const uniforms = new Float32Array(48);
18116
+ uniforms.set(this.camera.viewMatrix, 0);
18117
+ uniforms.set(this.camera.projectionMatrix, 16);
18118
+ uniforms.set(modelMatrix, 32);
18119
+ device.queue.writeBuffer(this.uniformBuffer, 0, uniforms);
18120
+ const frontVerts = this._volume.type === "box" ? this.generateBoxVertices(this.frontColor) : this.generateSphereVertices(this.frontColor);
18121
+ this.vertexCount = frontVerts.length / 6;
18089
18122
  if (this.vertexCount === 0) return;
18090
18123
  const needed = this.vertexCount * 24;
18091
18124
  if (needed > this.vertexBuffer.size) {
18092
18125
  this.vertexBuffer.destroy();
18093
18126
  this.vertexBuffer = device.createBuffer({ size: needed, usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST });
18094
18127
  }
18095
- device.queue.writeBuffer(this.vertexBuffer, 0, verts.buffer);
18096
- device.queue.writeBuffer(this.uniformBuffer, 0, new Float32Array(this.camera.viewProjectionMatrix));
18097
- pass.setPipeline(this.pipeline);
18128
+ device.queue.writeBuffer(this.vertexBuffer, 0, frontVerts.buffer);
18129
+ pass.setPipeline(this.frontPipeline);
18130
+ pass.setBindGroup(0, this.bindGroup);
18131
+ pass.setVertexBuffer(0, this.vertexBuffer);
18132
+ pass.draw(this.vertexCount);
18133
+ pass.setPipeline(this.behindPipeline);
18098
18134
  pass.setBindGroup(0, this.bindGroup);
18099
18135
  pass.setVertexBuffer(0, this.vertexBuffer);
18100
18136
  pass.draw(this.vertexCount);
@@ -18105,7 +18141,8 @@ class SelectionVolumeRenderer {
18105
18141
  (_b2 = this.uniformBuffer) == null ? void 0 : _b2.destroy();
18106
18142
  this.vertexBuffer = null;
18107
18143
  this.uniformBuffer = null;
18108
- this.pipeline = null;
18144
+ this.frontPipeline = null;
18145
+ this.behindPipeline = null;
18109
18146
  this.bindGroup = null;
18110
18147
  }
18111
18148
  }