2017-08-07 43 views
0

我想用threejs r86(最新的主版本)巨大的圖形可視化,用於顯示600,000個節點,我發現一種方法來繪製它們比使用THREE.points網格更快,但知道我需要他們可拖動,經過多次搜索後,我發現光線投射找到最接近鼠標點的對象,但我有一個問題,因爲所有的點都只是一個對象,不能單獨更改。如何拖動Threejs點

function Graph3(Nodes, Edges) { 
this.renderer = new THREE.WebGLRenderer({ alpha: true}); 
var width = window.innerWidth , height = window.innerHeight; 
this.renderer.setSize(width, height, false); 
document.body.appendChild(this.renderer.domElement); 
this.scene = new THREE.Scene(), 
this.camera = new THREE.PerspectiveCamera(100, width/height, 0.1, 3000), 
this.controls = new THREE.OrbitControls(this.camera); 
this.controls.enableKeys = true; 
this.controls.enableRotate = false; 

var material, geometry; 
self = this; 
material = new THREE.LineBasicMaterial({color: '#ccc'}); 

geometry = new THREE.Geometry(); 
geometry.vertices = Nodes.map(function(item){return new THREE.Vector3(item.pos.x,item.pos.y,item.pos.z);}); 
// this.vertices = geometry.vertices; 


this.line = new THREE.LineSegments(geometry, material); 
this.scene.add(this.line); 

var Node = new THREE.Group(); 

material = new THREE.PointsMaterial({ color:0x000060 ,size:1 }); 

this.particles = new THREE.Mesh(geometry,material) 
this.particles = new THREE.Points(geometry, material); 
this.scene.add(this.particles); 

dragControls = new THREE.DragControls([this.particles], this.camera/*,this.scene*/, this.renderer.domElement); 

this.camera.position.z = 200; 

var raycaster = new THREE.Raycaster(); 
var mouse = new THREE.Vector2(); 

document.addEventListener('click', function (event) { 

    // calculate mouse position in normalized device coordinates 
    // (-1 to +1) for both components 

    mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
    mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 
    console.log(mouse); 

}, false); 


stats = new Stats(); 
document.body.appendChild(stats.dom); 

this.animate = function() 
{ 

    raycaster.setFromCamera(mouse, self.camera); 
    var intersections = raycaster.intersectObject(self.particles); 
    intersection = (intersections.length) > 0 ? intersections[ 0 ] : null; 

    if (intersection !== null) { 
     console.log(intersection); 
    } 

    requestAnimationFrame(self.animate); 
    stats.update(); 

    self.renderer.render(self.scene, self.camera); 
} 
this.animate();} 

我能夠改變所有的點與dragControls但不能seperatly移動它們 我已經找到EventsControls.js文件,它幫助我們處理事件,但我不能用它

回答

0

感謝您在上一個問題中提供幫助。 我在2d平面(z = 0)中製作點,我可以使用bufferGeometry和RawShaderMaterial製作它們,但現在我有另一個拖動它們的問題,raycaster是如何做的?它需要vec3的位置,但我已經改變了它的性能目的。

var Geo = new THREE.BufferGeometry(); 

      var position = new Float32Array(NodeCount * 2); 
      var colors = new Float32Array(NodeCount * 3); 
      var sizes = new Float32Array(NodeCount); 

      for (var i = 0; i < NodeCount; i++) { 

       position[ 2*i ]  = (Math.random() - 0.5) * 10; 
       position[ 2*i + 1 ] = (Math.random() - 0.5) * 10; 


       colors[ 3*i ] = Math.random(); 
       colors[3*i+1] = Math.random(); 
       colors[3*i+2] = Math.random(); 

       // sizes 

       sizes[i] = Math.random() * 5 ; 

      } 

      Geo.addAttribute('position', new THREE.BufferAttribute(position, 2)); 
      Geo.addAttribute('color', new THREE.BufferAttribute(colors, 3)); 
      Geo.addAttribute('size', new THREE.BufferAttribute(sizes, 1)); 



      points = new THREE.Points(Geo, new THREE.RawShaderMaterial({ 
       vertexShader:` 
       precision highp float; 

       uniform mat4 modelViewMatrix; 
       uniform mat4 projectionMatrix; 
       uniform vec3 cameraPosition; 
       attribute vec2 position; /// reason of problem 

       varying vec3 vColor; 
       attribute vec3 color; 
       attribute float size; 

       void main() { 
        vColor = color; 

        gl_PointSize = size; 
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position , 0, 1); 
       }`, 
       fragmentShader:` 
       precision highp float; 
       varying vec3 vColor; 
       void main() { 
        gl_FragColor = vec4(vColor, 1.0) ; 
       }` 
      })); 
      scene.add(points); 

和我raycaster的使用:

function mouseDown(e) { 
       e.preventDefault(); 

       var mouse = new THREE.Vector2(); 
       mouse.x = (event.clientX/window.innerWidth) * 2 - 1; 
       mouse.y = - (event.clientY/window.innerHeight) * 2 + 1; 
//    mouse.z = 0; 
       raycaster.setFromCamera(mouse, camera); 
       raycaster.far = camera.position.z + 3; 
       const intersect = raycaster.intersectObject(points); 
       console.log(intersect); 
       if (intersect.length > 0) { 
        controls.enabled = false; 
        console.log(intersect); 
        selection = intersect[0].index; 
       } 
      } 

     function mouseUp(e) { 
      controls.enabled = true; 
      var vector = new THREE.Vector3(); 
      vector.x = ((event.clientX/window.innerWidth) * 2 - 1); 
      vector.y = (- (event.clientY/window.innerHeight) * 2 + 1); 
      vector.z = 1.0; 
      console.log(camera.position.z); 
      vector.unproject(camera); 

      var dir = vector.sub(camera.position).normalize(); 

      var distance = - camera.position.z/dir.z; 

      var temp = camera.position.clone().add(dir.multiplyScalar(distance)); 
      var pos = points.geometry.attributes.position; 
      pos.setXY(selection, temp.x, temp.y); 
      pos.updateRange.offset = selection; // where to start updating 
      pos.updateRange.count = 1; // how many vertices to update 
      pos.needsUpdate = true; 
      selection = undefined; 
     }