SOURCE

console 命令行工具 X clear

                    
>
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;

    // scene.add(new THREE.AxesHelper(1));

    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]);
        // todo
        // 根据具体数据可能还需要计算一次雷达数据的偏移转换
        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;
}