Threejs拖动点

5

我需要生成大量的物体,每个物体都可以单独拖动。这些物体只能限定在平面内(例如矩形或圆形)。 起初,我使用简单的CircleGeometries,在另一个几何体(平面)中放置它们。拖拽它们也非常容易,但是预期的性能对于约20万个物体来说非常差。 然后,我决定使用点/粒子系统。在平面内定位非常好,但我无法将粒子系统的各个点做成可拖动的状态。我在threejs文档中找到了交互式粒子示例,但仍然不知道如何将它们与dragcontrols相结合。 下面是我的代码,用于创建粒子系统并在一个平面上填充这些点:

//Create a plane geometrie, that is later filled with points
var geometry2 = new THREE.CircleGeometry(30,32);
var material2 = new THREE.MeshBasicMaterial( {color: 0x666666, side: THREE.DoubleSide, wireframe:true} );
var mat1 = new THREE.MeshBasicMaterial( {color: 0x00ff00, wireframe:false} );
var plane1 = new THREE.Mesh(geometry2, material2);
geometries.push(plane1);    //push to object for draggable elements
scene.add(plane1);        

var positionsX;

       positionsX = inGeometry.inGeometry(plane1.geometry,  200000); // get positions for points inside plane1

      var geometry = new THREE.Geometry();
      for (var i = 0; i < positionsX.length; i++) {
                geometry.vertices.push(positionsX[i]);  //add positions to vertices

      }
      console.log(geometry);

      //Create Particle system
      var material = new THREE.PointsMaterial({ size:0.02, color: 0xffffff });
      particleSystem = new THREE.Points(geometry, material);
      scene.add(particleSystem);
      console.log(particleSystem);


  var dragGeo = new DragControls(geometries, camera, container); //dragging

请问有人可以帮忙吗? 谢谢


THREE.DragControls()旨在与对象一起使用,而不是几何体的顶点。您需要提供自己的逻辑来管理顶点,使用示例中提供的信息。 - prisoner849
1个回答

13

这只是一个简单的示例,展示如何拖动点:

在此输入图片描述

var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(1.25, 7, 7);
camera.lookAt(scene.position);
var renderer = new THREE.WebGLRenderer({
  antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);

var geometry = new THREE.PlaneBufferGeometry(10, 10, 10, 10);
geometry.rotateX(-Math.PI * 0.5);

var plane = new THREE.Mesh(geometry, new THREE.MeshBasicMaterial({
  wireframe: true,
  color: "red"
}));
scene.add(plane);

var points = new THREE.Points(geometry, new THREE.PointsMaterial({
  size: 0.25,
  color: "yellow"
}));
scene.add(points);

var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 0.25;
var mouse = new THREE.Vector2();
var intersects = null;
var plane = new THREE.Plane();
var planeNormal = new THREE.Vector3();
var currentIndex = null;
var planePoint = new THREE.Vector3();
var dragging = false;

window.addEventListener("mousedown", mouseDown, false);
window.addEventListener("mousemove", mouseMove, false);
window.addEventListener("mouseup", mouseUp, false);

function mouseDown(event) {
  setRaycaster(event);
  getIndex();
  dragging = true;
}

function mouseMove(event) {
  if (dragging && currentIndex !== null) {
    setRaycaster(event);
    raycaster.ray.intersectPlane(plane, planePoint);
    geometry.attributes.position.setXYZ(currentIndex, planePoint.x, planePoint.y, planePoint.z);
    geometry.attributes.position.needsUpdate = true;
  }
}

function mouseUp(event) {
  dragging = false;
  currentIndex = null;
}

function getIndex() {
  intersects = raycaster.intersectObject(points);
  if (intersects.length === 0) {
    currentIndex = null;
    return;
  }
  currentIndex = intersects[0].index;
  setPlane(intersects[0].point);
}

function setPlane(point) {
  planeNormal.subVectors(camera.position, point).normalize();
  plane.setFromNormalAndCoplanarPoint(planeNormal, point);
}

function setRaycaster(event) {
  getMouse(event);
  raycaster.setFromCamera(mouse, camera);
}

function getMouse(event) {
  mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
  mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}

render();

function render() {
  requestAnimationFrame(render);
  renderer.render(scene, camera);
}
body {
  overflow: hidden;
  margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/91/three.min.js"></script>


1
你好,感谢你的回答和示例。我只需要根据我的点大小调整阈值,并将getMouse函数更改为以下内容,以便在我的容器内获取正确的坐标(否则光标会与我的点有偏移)。但是,这只是在我的页面上才会出现这种情况,因为还有其他元素:function getMouse(event) { event.preventDefault(); var rect = container.getBoundingClientRect(); mouse.x = ((event.clientX - rect.left) / rect.width) * 2 - 1; mouse.y = -((event.clientY - rect.top) / rect.height) * 2 + 1; } - HS_hendrix
这在最新版本中似乎不太好用。 - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接