console
var pointCloud, camera, scene, renderer, controls;
const rect = document.getElementById('selection')
const selectBoxData = {
active: false,
start: { x: 0, y: 0 },
end: { x: 0, y: 0 },
};
init();
render();
function init() {
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(
30,
window.innerWidth / window.innerHeight,
0.01,
10000
);
camera.position.set(0, 0, 200);
scene.add(camera);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.minDistance = 0.1;
controls.maxDistance = 10000;
const loader = new THREE.PCDLoader();
loader.load("//cv-assets.oss-cn-beijing.aliyuncs.com/assets/pcd/000950.pcd", function (points) {
console.log("points load done");
pointCloud = points;
points.geometry.rotateZ(Math.PI);
const material = points.material;
material.color.setHex(0x6cff8e)
material.needsUpdate = true;
material.transparent = true;
material.opacity = 0.5;
material.blending = THREE.AdditiveBlending;
scene.add(points);
});
window.addEventListener("resize", onWindowResize);
window.addEventListener("pointerdown", handleMouseDown);
window.addEventListener("pointermove", handleMouseMove);
window.addEventListener("pointerup", handleMouseUp);
window.addEventListener("keydown", handleKeyPress);
window.addEventListener("keyup", handleKeyRelease);
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
function getRectSelectionPoints() {
const x = Math.min(selectBoxData.start.x, selectBoxData.end.x)
const y = Math.min(selectBoxData.start.y, selectBoxData.end.y)
const w = Math.abs(selectBoxData.start.x - selectBoxData.end.x)
const h = Math.abs(selectBoxData.start.y - selectBoxData.end.y)
camera.updateMatrixWorld();
const posArr = pointCloud.geometry.getAttribute("position").array;
var indices = [];
var points = [];
var p = new THREE.Vector3();
const hw = window.innerWidth / 2;
const hh = window.innerHeight / 2;
for (var i = 0; i < posArr.length / 3; i++) {
p.set(posArr[i * 3], posArr[i * 3 + 1], posArr[i * 3 + 2]);
p.project(camera);
const px = p.x * hw + hw;
const py = -(p.y * hh) + hh;
if (px >= x && px <= x + w && py >= y && py <= y + h && p.z > 0) {
indices.push(i);
points.push(
posArr[i * 3],
posArr[i * 3 + 1],
posArr[i * 3 + 2]
);
}
}
console.log(points.length / 3)
addActivePointsGroup(points);
return points;
}
function addActivePointsGroup(points) {
const geometry = new THREE.BufferGeometry();
geometry.setAttribute(
"position",
new THREE.Float32BufferAttribute(points, 3)
);
const material = new THREE.PointsMaterial({
size: 0.003,
color: 0xff0000,
});
const pc = new THREE.Points(geometry, material);
scene.add(pc);
}
function updateRectStyle() {
if (selectBoxData.active) {
rect.style.display = 'block';
rect.style.width = Math.abs(selectBoxData.start.x - selectBoxData.end.x) + 'px'
rect.style.height = Math.abs(selectBoxData.start.y - selectBoxData.end.y) + 'px'
rect.style.left = Math.min(selectBoxData.start.x , selectBoxData.end.x) + 'px'
rect.style.top = Math.min(selectBoxData.start.y , selectBoxData.end.y) + 'px'
} else {
rect.style.display = 'none';
rect.style.width = '0';
rect.style.height = '0';
rect.style.left = '0';
rect.style.top = '0';
}
}
function handleMouseDown(event) {
if (!event.shiftKey) {
return;
}
event.preventDefault();
event.stopPropagation();
selectBoxData.start = {
x: event.offsetX,
y: event.offsetY,
};
selectBoxData.end = {
x: event.offsetX,
y: event.offsetY,
};
selectBoxData.active = true;
updateRectStyle()
}
function handleMouseMove(event) {
if (!selectBoxData.active) {
return
}
selectBoxData.end = {
x: event.offsetX,
y: event.offsetY,
};
updateRectStyle()
}
function handleMouseUp(event) {
if (!selectBoxData.active) {
return
}
getRectSelectionPoints()
selectBoxData.active = false;
selectBoxData.start = { x: 0, y: 0 };
selectBoxData.end = { x: 0, y: 0 };
controls.enabled = true;
updateRectStyle()
}
function handleKeyPress(event) {
console.log(event.key)
if (event.key == "Shift") {
controls.enabled = false;
}
}
function handleKeyRelease(event) {
if (event.key == "Shift") {
controls.enabled = true;
}
}
<div id="info">
旋转:鼠标左键
<br>
移动:鼠标右键
<br>
划选:Shift(先按下) + 鼠标左键
<br>
<span style="color:red;">
第一次划选前先点一下画面,激活iframe按键监听
</span>
</div>
<div id="selection" ></div>
<script src="https://cdn.jsdelivr.net/npm/three@0.138.3/build/three.min.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/controls/OrbitControls.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/three@0.138.3/examples/js/loaders/PCDLoader.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/dat.gui@0.7.9/build/dat.gui.min.js"></script>
body {
margin: 0;
}
canvas {
display: block;
}
#info {
position: absolute;
padding: 12px;
background: rgba(255,255,255,.2);
color: rgba(255,255,255,.7);
font-size: 14px;
left:0;
bottom: 0;
}
#selection {
position: absolute;
z-index: 999;
pointer-events: none;
border: 1px solid yellowgreen;
background: rgba(255,0,0,0.3);
display: none;
}