Closed mandre96 closed 4 months ago
`export default class ClipBox extends THREE.Object3D {
private static _counter = 0;
private _dimension = new THREE.Vector3(1, 1, 1);
private _material:THREE.Material;
private _box:THREE.Mesh;
private _frame:THREE.LineSegments;
private _planeFrame:THREE.LineSegments;
private _clipBox: IClipBox;
public get clipBox(): IClipBox {
return this._clipBox;
}
constructor() {
super();
ClipBox._counter += 1;
this.name = "clip_volume_" + ClipBox._counter;
//Creates Geometry
const boxGeometry = new THREE.BoxGeometry(1, 1, 1);
boxGeometry.computeBoundingBox();
const boxFrameGeometry = this.generateBoxFrameGeometry();
const planeFrameGeometry = this.generatePlaneFrameGeometry();
this._material = new THREE.MeshBasicMaterial( {
color: 0x00ff00,
transparent: true,
opacity: 0.3,
depthTest: true,
depthWrite: false} );
//Box Mesh
this._box = new THREE.Mesh(boxGeometry, this._material);
this._box.geometry.computeBoundingBox();
this.add(this._box);
//Box Frame
this._frame = new THREE.LineSegments( boxFrameGeometry, new THREE.LineBasicMaterial({color: 0x000000}));
this.add(this._frame);
this._planeFrame = new THREE.LineSegments( planeFrameGeometry, new THREE.LineBasicMaterial({color: 0xff0000}));
this.add(this._planeFrame);
// set default thickness
this.setScaleZ(0.1);
const mat = this._box.matrix.clone();
const inverse = mat.invert();
this._clipBox = {box: this._box.geometry.boundingBox!, inverse:inverse , matrix:this._box.matrix, position: this.position};
//console.log(this._clipBox);
}`
The LargeCloudManagerClass sets it
` public setClipMode(value:ClipMode) { for (let index = 0; index < this._largeScaleClouds.length; index++) { const potreeCloud = this._largeScaleClouds[index]; potreeCloud.material.clipMode = value } }
/**
Using the keyboard keys to test it on Controls class:
`else if (key == 'v') { //this._volumeTool.togglePolygonMode(); this._dunaApplication.largePointCloudManager.setClipMode(ClipMode.CLIP_OUTSIDE); } else if (key == 't') { //this._areaTool.togglePolygonMode(); this._dunaApplication.largePointCloudManager.setClipMode(ClipMode.HIGHLIGHT_INSIDE); } else if (key == 'n') { //this._dunaApplication.togglePointPickLabels(); this._dunaApplication.largePointCloudManager.setClipMode(ClipMode.CLIP_HORIZONTALLY); } else if (key == 'b') { //this._areaTool.polygonEdges = 7; this._dunaApplication.largePointCloudManager.setClipMode(ClipMode.CLIP_VERTICALLY); } else if (key == ',') { clip = new ClipBox(); clip.position.set(100, 100, 50); clip.setScaleX(100); clip.setScaleY(100); clip.setScaleZ(100); this._dunaApplication.scene.add(clip)
this._dunaApplication.largePointCloudManager.setClipBoxes([clip.clipBox]);
}`
In case anyone has the same problem, after a very long time a i figured ou it was a inverse matrix error. Here is a complete class for using a scalable clipbox attached to a potree cloud. Cheers!
`import { IClipBox, PointCloudOctree } from '@pnext/three-loader'; import * as THREE from 'three'; import { TransformControls } from 'three/examples/jsm/controls/TransformControls'; import Controls from '../Controls'; import Utils from '../utils/Utils';
export default class ClipBox extends THREE.Object3D { private _pointCloud: PointCloudOctree; private _controls: Controls; private _box: THREE.Mesh; private _frame: THREE.LineSegments; private _planeFrame: THREE.LineSegments; private _transform: TransformControls;
//Events private _onChange!: (event: THREE.Event) => void; private _onDraggingChanged!: (event: THREE.Event) => void;
public get transform(): TransformControls { return this._transform; }
private _clipBox: IClipBox;
public get box(): THREE.Mesh { return this._box; }
public get clipBox(): IClipBox { return this._clipBox; }
private _material: THREE.Material;
constructor(pointCloud: PointCloudOctree, camera: THREE.Camera, renderer: THREE.Renderer, controls: Controls ) { super(); this._transform = new TransformControls(camera, renderer.domElement); this._pointCloud = pointCloud; this._controls = controls; //Creates Geometry const boxGeometry = new THREE.BoxGeometry(1, 1, 1); boxGeometry.computeBoundingBox();
this._material = new THREE.MeshBasicMaterial({
color: 0x00fff0,
transparent: true,
opacity: 0.2,
depthTest: true,
depthWrite: false,
});
//Box Mesh
this._box = new THREE.Mesh(boxGeometry, this._material);
this._box.geometry.computeBoundingBox();
this.add(this._box);
//Create Frames
this._frame = new THREE.LineSegments(this.generateBoxFrameGeometry(), new THREE.LineBasicMaterial({ color: 0xffff00 }));
this._box.add(this._frame);
this._planeFrame = new THREE.LineSegments(this.generatePlaneFrameGeometry(), new THREE.LineBasicMaterial({ color: 0xff0000 }));
this._box.add(this._planeFrame);
//calculate point cloud total bounding box
const bbox = this.computeCloudBoundingBox();
// make a BoxGeometry of the same size as Box3
const dimensions = new THREE.Vector3().subVectors(bbox.max, bbox.min);
//Scale it
this._box.scale.set(dimensions.x, dimensions.y, dimensions.z);
this._box.updateMatrix();
const matrix = new THREE.Matrix4().setPosition(dimensions.addVectors(bbox.min, bbox.max).multiplyScalar(0.5));
this._box.applyMatrix4(matrix);
const inverse = this._box.matrix.clone().invert();
//creates the clipbox object
this._clipBox = { box: this._box.geometry.boundingBox!, inverse: inverse, matrix: this._box.matrix, position: this._box.position };
//attach transform scale control
this._transform.attach(this._box);
this._transform.setMode('scale');
this._transform.setSize(0.5);
this.add(this.transform);
//Activates event listeners
this.activateEventListeners();
//activate clipbox
this._pointCloud.material.setClipBoxes([this._clipBox]);
}
private onChange(event: THREE.Event) { this.updateClipbox(); }
private onDraggingChanged(event: THREE.Event) { this._controls.controls.enabled = !event.value; }
private activateEventListeners() { this._onChange = this.onChange.bind(this); this._onDraggingChanged = this.onDraggingChanged.bind(this);
//Updates IClipbox on Transfrom change
this._transform.addEventListener('change', this._onChange);
//Disables Controls on dragging
this._transform.addEventListener('dragging-changed', this._onDraggingChanged);
}
public dispose() { this._transform.removeEventListener('change', this._onChange); this._transform.removeEventListener('dragging-changed', this._onDraggingChanged); }
private generatePlaneFrameGeometry(): THREE.BufferGeometry { const vertices = []; const planeFrameGeometry = new THREE.BufferGeometry(); // middle line vertices.push(new THREE.Vector3(-0.5, -0.5, 0.0)); vertices.push(new THREE.Vector3(-0.5, 0.5, 0.0)); vertices.push(new THREE.Vector3(0.5, 0.5, 0.0)); vertices.push(new THREE.Vector3(0.5, -0.5, 0.0)); vertices.push(new THREE.Vector3(-0.5, 0.5, 0.0)); vertices.push(new THREE.Vector3(0.5, 0.5, 0.0)); vertices.push(new THREE.Vector3(-0.5, -0.5, 0.0)); vertices.push(new THREE.Vector3(0.5, -0.5, 0.0));
planeFrameGeometry.setFromPoints(vertices);
return planeFrameGeometry;
}
private generateBoxFrameGeometry(): THREE.BufferGeometry { const boxFrameGeometry = new THREE.BufferGeometry(); const vertices = []; // bottom vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5)); // top vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, -0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5)); // sides vertices.push(new THREE.Vector3(-0.5, -0.5, 0.5)); vertices.push(new THREE.Vector3(-0.5, 0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, 0.5)); vertices.push(new THREE.Vector3(0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(0.5, 0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, -0.5, -0.5)); vertices.push(new THREE.Vector3(-0.5, 0.5, -0.5));
boxFrameGeometry.setFromPoints(vertices);
return boxFrameGeometry;
}
public setPosition(position: THREE.Vector3) { this._box.position.set(position.x, position.y, position.z);
this.updateClipbox();
}
public setScale(scale: THREE.Vector3) { this._box.scale.set(scale.x, scale.y, scale.z); this.updateClipbox(); }
private updateClipbox() { this._box.updateMatrix(); const inverse = this._box.matrix.clone().invert(); this._clipBox = { box: this._box.geometry.boundingBox!, inverse: inverse, matrix: this._box.matrix, position: this._box.position }; this._pointCloud.material.setClipBoxes([this._clipBox]); }
/**
Toggles transform visibility */ public toggleTransform(activated: boolean) { this._box.visible = activated; this._frame.visible = activated; this._planeFrame.visible = activated; this._transform.visible = activated; this._transform.enabled = activated; }
/**
/**
private computeCloudBoundingBox() { let pointcloudBox = this._pointCloud.pcoGeometry.tightBoundingBox ? this._pointCloud.pcoGeometry.tightBoundingBox : this._pointCloud.boundingBox; let boxWorld = Utils.computeTransformedBoundingBox(pointcloudBox, this._pointCloud.matrixWorld); return boxWorld }
/**
}`
Hello, I have not been able to use the IClipBox class successfully, even though I have implemented it properly.
When I set the clipbox on the point cloud material, it clips the entire cloud.
If I set the clip mode to HIGHLIGHT_INSIDE, nothing happens either.
Is there an example that works? Is this feature fully functional?
Image of HIGHLIGHT_INSIDE not working:
https://freeimage.host/i/J9vqlUX