diff --git a/main.js b/main.js
index 5bea877..6dea69c 100644
--- a/main.js
+++ b/main.js
@@ -96,184 +96,212 @@ controls.panSpeed = 1.0;
controls.target.set(0, 0, 0);
// Load the PLY file
const loader = new PLYLoader();
-loader.load("./data/01_column.ply", function (plyGeometry) {
- const geometry = new THREE.BufferGeometry();
- geometry.setAttribute(
- "position",
- new THREE.Float32BufferAttribute(
- plyGeometry.attributes.position.array,
- 3
- )
- );
- geometry.setAttribute(
- "color",
- new THREE.Float32BufferAttribute(plyGeometry.attributes.color.array, 3)
- );
- geometry.needsUpdate = true;
-
- const planes = [
- new THREE.Vector4(1, 0, 0, 0),
- new THREE.Vector4(0, 1, 0, 0),
- new THREE.Vector4(0, 0, 1, 0),
- ];
- let dir = new THREE.Vector3(1, 1, 1);
- const material = new THREE.ShaderMaterial({
- transparent: true,
- vertexColors: true,
- clipping: true,
- uniforms: {
- L: { value: 0 },
- R: { value: 100 },
- xPlane: { value: planes[0] },
- yPlane: { value: planes[1] },
- zPlane: { value: planes[2] },
- dir: { value: dir },
- },
- vertexShader: `
- vec3 interpolateColor(float ratio, vec3 color1, vec3 color2) {
- return mix(color1, color2, ratio);
- }
-
- vec3 intensityToRGB(float intensity) {
- if (intensity <= 0.333) {
- return interpolateColor(intensity / 0.333, vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 0.0)); // Blue -> Green
- } else if (intensity <= 0.666) {
- return interpolateColor((intensity - 0.333) / 0.333, vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0)); // Green -> Yellow
- } else {
- return interpolateColor((intensity - 0.666) / 0.334, vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)); // Yellow -> Red
- }
- }
-
- uniform float L;
- uniform float R;
- varying vec3 vColor;
- varying vec3 vPosition;
-
- void main() {
- vPosition = position;
-
- float intensity = color[0];
- vColor = intensityToRGB(intensity);
+const gui = new GUI();
+const selectedName = { name: "Select File" };
+gui.add(selectedName, "name", ["01_column", "02_ground"])
+ .name("GPR Example")
+ .onChange((value) => load(value));
+
+let folderArray = [];
+
+function load(name) {
+ loader.load(`./data/${name}.ply`, function (plyGeometry) {
+ scene.clear();
+ folderArray.forEach((folder) => {
+ // gui.removeFolder(folder);
+ folder.destroy();
+ });
- if (intensity < L - 1e-6 || intensity > R + 1e-6) {
- gl_Position = vec4(0.0, 0.0, 1e10, 1.0);
- } else {
- gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+ const geometry = new THREE.BufferGeometry();
+ geometry.setAttribute(
+ "position",
+ new THREE.Float32BufferAttribute(
+ plyGeometry.attributes.position.array,
+ 3
+ )
+ );
+ geometry.setAttribute(
+ "color",
+ new THREE.Float32BufferAttribute(
+ plyGeometry.attributes.color.array,
+ 3
+ )
+ );
+ geometry.needsUpdate = true;
+
+ const planes = [
+ new THREE.Vector4(1, 0, 0, 0),
+ new THREE.Vector4(0, 1, 0, 0),
+ new THREE.Vector4(0, 0, 1, 0),
+ ];
+ let dir = new THREE.Vector3(1, 1, 1);
+ const material = new THREE.ShaderMaterial({
+ transparent: true,
+ vertexColors: true,
+ clipping: true,
+ uniforms: {
+ L: { value: 0 },
+ R: { value: 100 },
+ xPlane: { value: planes[0] },
+ yPlane: { value: planes[1] },
+ zPlane: { value: planes[2] },
+ dir: { value: dir },
+ },
+ vertexShader: `
+ vec3 interpolateColor(float ratio, vec3 color1, vec3 color2) {
+ return mix(color1, color2, ratio);
}
-
- gl_PointSize = 10.0;
- }
- `,
- fragmentShader: `
- varying vec3 vColor;
- varying vec3 vPosition;
- uniform vec4 xPlane;
- uniform vec4 yPlane;
- uniform vec4 zPlane;
- uniform vec3 dir;
-
- void main() {
- if ((dir.x == 1.0 && dot(vPosition, xPlane.xyz) > xPlane.w) ||
- (dir.x == -1.0 && dot(vPosition, xPlane.xyz) < xPlane.w)) {
- discard;
+
+ vec3 intensityToRGB(float intensity) {
+ if (intensity <= 0.333) {
+ return interpolateColor(intensity / 0.333, vec3(0.0, 0.0, 1.0), vec3(0.0, 1.0, 0.0)); // Blue -> Green
+ } else if (intensity <= 0.666) {
+ return interpolateColor((intensity - 0.333) / 0.333, vec3(0.0, 1.0, 0.0), vec3(1.0, 1.0, 0.0)); // Green -> Yellow
+ } else {
+ return interpolateColor((intensity - 0.666) / 0.334, vec3(1.0, 1.0, 0.0), vec3(1.0, 0.0, 0.0)); // Yellow -> Red
+ }
}
- if ((dir.y == 1.0 && dot(vPosition, yPlane.xyz) > yPlane.w) ||
- (dir.y == -1.0 && dot(vPosition, yPlane.xyz) < yPlane.w)) {
- discard;
+
+ uniform float L;
+ uniform float R;
+ varying vec3 vColor;
+ varying vec3 vPosition;
+
+ void main() {
+ vPosition = position;
+
+ float intensity = color[0];
+ vColor = intensityToRGB(intensity);
+
+ if (intensity < L - 1e-6 || intensity > R + 1e-6) {
+ gl_Position = vec4(0.0, 0.0, 1e10, 1.0);
+ } else {
+ gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
+ }
+
+ gl_PointSize = 4.0;
}
- if ((dir.z == 1.0 && dot(vPosition, zPlane.xyz) > zPlane.w) ||
- (dir.z == -1.0 && dot(vPosition, zPlane.xyz) < zPlane.w)) {
- discard;
+ `,
+ fragmentShader: `
+ varying vec3 vColor;
+ varying vec3 vPosition;
+ uniform vec4 xPlane;
+ uniform vec4 yPlane;
+ uniform vec4 zPlane;
+ uniform vec3 dir;
+
+ void main() {
+ if ((dir.x == 1.0 && dot(vPosition, xPlane.xyz) > xPlane.w) ||
+ (dir.x == -1.0 && dot(vPosition, xPlane.xyz) < xPlane.w)) {
+ discard;
+ }
+ if ((dir.y == 1.0 && dot(vPosition, yPlane.xyz) > yPlane.w) ||
+ (dir.y == -1.0 && dot(vPosition, yPlane.xyz) < yPlane.w)) {
+ discard;
+ }
+ if ((dir.z == 1.0 && dot(vPosition, zPlane.xyz) > zPlane.w) ||
+ (dir.z == -1.0 && dot(vPosition, zPlane.xyz) < zPlane.w)) {
+ discard;
+ }
+
+ gl_FragColor = vec4(vColor, 1.0);
}
+ `,
+ });
- gl_FragColor = vec4(vColor, 1.0);
- }
- `,
- });
-
- document.addEventListener("mousemove", (e) => {
- handleMouseMove(e);
- const lowerValue = parseInt(lowerHandle.style.left);
- const upperValue = parseInt(upperHandle.style.left);
- material.uniforms.L.value = lowerValue / 100;
- material.uniforms.R.value = upperValue / 100;
- });
+ document.addEventListener("mousemove", (e) => {
+ handleMouseMove(e);
+ const lowerValue = parseInt(lowerHandle.style.left);
+ const upperValue = parseInt(upperHandle.style.left);
+ material.uniforms.L.value = lowerValue / 100;
+ material.uniforms.R.value = upperValue / 100;
+ });
- geometry.computeVertexNormals();
- geometry.center();
-
- // Create and add the point cloud to the scene
- const pointCloud = new THREE.Points(geometry, material);
- scene.add(pointCloud);
-
- // Compute the bounding box of the point cloud
- const boundingBox = new THREE.Box3().setFromObject(pointCloud);
- boundingBox.getCenter(camera.position);
-
- // Adjust the camera position
- const size = boundingBox.getSize(new THREE.Vector3());
- const maxDim = Math.max(size.x, size.y, size.z);
- const fov = camera.fov * (Math.PI / 180);
- let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));
- camera.position.set(camera.position.x, camera.position.y, cameraZ * 1.5);
- // Make the camera look at the center of the point cloud
- camera.lookAt(boundingBox.getCenter(new THREE.Vector3()));
-
- // stats setup
- let stats = new Stats();
- document.body.appendChild(stats.dom);
-
- // GUI setup
- const gui = new GUI();
- const planeNames = ["X", "Y", "Z"];
- const planeHelpers = [
- new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0xff0000),
- new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0x00ff00),
- new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0x0000ff),
- ];
- planeHelpers.forEach((planeHelper) => {
- scene.add(planeHelper);
- planeHelper.visible = true;
- });
- planes.forEach((plane, index) => {
- plane.w = boundingBox.max[planeNames[index].toLowerCase()] + 1e-6;
- planeHelpers[index].plane = new THREE.Plane(
- new THREE.Vector3().fromArray(plane.toArray()),
- -plane.w
+ geometry.computeVertexNormals();
+ geometry.center();
+
+ // Create and add the point cloud to the scene
+ const pointCloud = new THREE.Points(geometry, material);
+ scene.add(pointCloud);
+
+ const light = new THREE.HemisphereLight(0xffffff, 0x080808, 4.5);
+ light.position.set(-1.25, 1, 1.25);
+ scene.add(light);
+
+ // Compute the bounding box of the point cloud
+ const boundingBox = new THREE.Box3().setFromObject(pointCloud);
+ boundingBox.getCenter(camera.position);
+
+ // Adjust the camera position
+ const size = boundingBox.getSize(new THREE.Vector3());
+ const maxDim = Math.max(size.x, size.y, size.z);
+ const fov = camera.fov * (Math.PI / 180);
+ let cameraZ = Math.abs(maxDim / 2 / Math.tan(fov / 2));
+ camera.position.set(
+ camera.position.x,
+ camera.position.y,
+ cameraZ * 1.5
);
-
- const planeFolder = gui.addFolder(`plane${planeNames[index]}`);
- planeFolder.add(planeHelpers[index], "visible").name("displayHelper");
- planeFolder
- .add(plane, "w")
- .name("position")
- .min(boundingBox.min[planeNames[index].toLowerCase()] - 1e-6)
- .max(boundingBox.max[planeNames[index].toLowerCase()] + 1e-6)
- .onChange((value) => {
- plane.w = value;
- planeHelpers[index].plane = new THREE.Plane(
- new THREE.Vector3().fromArray(plane.toArray()),
- -value
- );
+ // Make the camera look at the center of the point cloud
+ camera.lookAt(boundingBox.getCenter(new THREE.Vector3()));
+
+ // GUI setup
+ const planeNames = ["X", "Y", "Z"];
+ const planeHelpers = [
+ new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0xff0000),
+ new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0x00ff00),
+ new THREE.PlaneHelper(new THREE.Plane(), 1.3, 0x0000ff),
+ ];
+ planeHelpers.forEach((planeHelper) => {
+ scene.add(planeHelper);
+ planeHelper.visible = true;
+ });
+ planes.forEach((plane, index) => {
+ plane.w = boundingBox.max[planeNames[index].toLowerCase()] + 1e-6;
+ planeHelpers[index].plane = new THREE.Plane(
+ new THREE.Vector3().fromArray(plane.toArray()),
+ -plane.w
+ );
+
+ const planeFolder = gui.addFolder(`plane${planeNames[index]}`);
+ planeFolder
+ .add(planeHelpers[index], "visible")
+ .name("displayHelper");
+ planeFolder
+ .add(plane, "w")
+ .name("position")
+ .min(boundingBox.min[planeNames[index].toLowerCase()] - 1e-6)
+ .max(boundingBox.max[planeNames[index].toLowerCase()] + 1e-6)
+ .onChange((value) => {
+ plane.w = value;
+ planeHelpers[index].plane = new THREE.Plane(
+ new THREE.Vector3().fromArray(plane.toArray()),
+ -value
+ );
+ });
+ planeFolder.add({ mirror: false }, "mirror").onChange((value) => {
+ dir[planeNames[index].toLowerCase()] =
+ -dir[planeNames[index].toLowerCase()];
});
- planeFolder.add({ negated: false }, "negated").onChange((value) => {
- dir[planeNames[index].toLowerCase()] =
- -dir[planeNames[index].toLowerCase()];
+ planeFolder.open();
+ folderArray.push(planeFolder);
});
- planeFolder.open();
});
+}
- // Render loop
- function animate() {
- requestAnimationFrame(animate);
- controls.update();
- stats.begin();
- renderer.render(scene, camera);
- stats.end();
- }
- animate();
-});
-
+// stats setup
+let stats = new Stats();
+document.body.appendChild(stats.dom);
+
+// Render loop
+function animate() {
+ requestAnimationFrame(animate);
+ controls.update();
+ stats.begin();
+ renderer.render(scene, camera);
+ stats.end();
+}
+animate();
// Handle window resize
window.addEventListener("resize", () => {
camera.aspect = window.innerWidth / window.innerHeight;