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