简体   繁体   English

无法更改 three.js PointCloud 的顶点颜色

[英]Cannot change colour of vertex for three.js PointCloud

I am having trouble changing the colour of a vertex on a mouse click using three.js and Angular.我无法使用 three.js 和 Angular 更改鼠标单击时的顶点颜色。 I have been reading around this and I think I should be setting up vertex colours and then when I intersect against my scene I can use the color array in object.attributes.color.我一直在阅读这个,我认为我应该设置顶点颜色,然后当我与我的场景相交时,我可以使用 object.attributes.color 中的颜色数组。 So this is what I have been attempting to do:所以这就是我一直在尝试做的事情:

createCloud() {
    const vertices = [];
    
    this.data.forEach(line => {
      vertices.push(line.XX , line.YY , line.ZZ);
      this.colours.push(this.originalColour.r, this.originalColour.g, this.originalColour.b);
    });

    this.geometry = new THREE.BufferGeometry();
    this.geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(vertices), 3));
    this.geometry.setAttribute('color', new THREE.BufferAttribute(new Float32Array(this.colours), 3));

    var material = new THREE.PointsMaterial({size: this.pointSize, vertexColors: true});
    this.points = new THREE.Points(this.geometry, material);
    this.geometry.center();
    this.scene.add(this.points);
  }

and then when the mouse is clicked:然后单击鼠标时:

    public onMouseDown(event){  
    
        var mousePosition = new THREE.Vector3();
        mousePosition.setX(2 * (event.clientX / this.container.nativeElement.clientWidth) - 1);
        mousePosition.setY(1 - 2 * (event.clientY / this.container.nativeElement.clientHeight));
    
        this.caster.setFromCamera(mousePosition, this.camera);
        var intersections = this.caster.intersectObjects(this.scene.children, true);
    
        if(intersections && intersections.length > 0){
          
        }
    
        console.log("Mouse is down! " + mousePosition.x + " " + mousePosition.y + " " + intersections.length);

  }

This works fine and when I click on one of the vertices I get intersections populated.这很好用,当我单击其中一个顶点时,我会填充交叉点。 From there all I want to do is access the intersection[0].object.geometry.attributes.color.array[which indexes?].从那里我想做的就是访问交叉点[0].object.geometry.attributes.color.array[哪些索引?]。

Firstly I understand that I should be doing this with parallel arrays between position and color and the indexes between position and color would be the same for any given vertex.首先,我知道我应该使用 position 和颜色之间的并行 arrays 来执行此操作,并且 position 和颜色之间的索引对于任何给定的顶点都是相同的。 those arrays, for my test set, are defined to be:对于我的测试集,那些 arrays 定义为:

length: 3747 itemSize: 3, count: 1249,长度:3747 项目大小:3,计数:1249,

which seems reasonable when you realise that 1249 * 3 = 3747. so with my object having an index of 124 I take a look at my positions array in index 124 * 3 = 372 expecting that to be my x value but it does not match any of the point values held in the point object that has been selected.当您意识到 1249 * 3 = 3747 时,这似乎是合理的。所以我的 object 的索引为 124,我查看索引 124 * 3 = 372 中的位置数组,期望这是我的 x 值,但它不匹配任何已选择的点 object 中保存的点值。

Even more frustrating is that when I attempt to write the code intersection[0].object.geometry.attributes.color.array更令人沮丧的是,当我尝试编写代码时, intersection[0].object.geometry.attributes.color.array

I get an error stating that property (attributes) does not exist on Object3D even though I can see it in the debugger when I step through.我收到一条错误消息,指出 Object3D 上不存在属性(属性),即使我在单步执行时可以在调试器中看到它。 I have also tried intersecting on the THREE.Points object itself but with little difference.我也尝试过在 THREE.Points object 本身上相交,但差别不大。

So does anyone know where I am going wrong here?那么有人知道我在哪里出错了吗?

Had to set the indexes myself by storing the index of the start of each vertex/colour in the attribute arrays and then add it using setIndex on my geometry.必须自己设置索引,方法是将每个顶点/颜色的开始索引存储在属性 arrays 中,然后在我的几何图形上使用 setIndex 添加它。

const vertices = new Float32Array(this.data.length * 3);
    const colours = new Float32Array(this.data.length * 3);
    const indices = new Uint16Array(this.data.length);

    let indexByThree = 0; 
    let index = 0;
    let colorValues: number[] = [this.originalColour.r, this.originalColour.g, this.originalColour.b];

    this.data.forEach(line => {
      let cords: number[] = [line.XX, line.YY, line.ZZ];
      let iArray = [indexByThree];

      vertices.set(cords, indexByThree);
      colours.set(colorValues, indexByThree);      
      indices.set(iArray, index);

      indexByThree += 3;
      index++;
    });
    
    this.geometry = new THREE.BufferGeometry();
    this.geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3));
    this.geometry.setAttribute('color', new THREE.BufferAttribute(colours, 3, true));
    this.geometry.setIndex(new THREE.BufferAttribute(indices, 1));

Watch out as the type of the arrays seem important with the indices array having to be of type Uint16array.注意 arrays 的类型似乎很重要,因为索引数组必须是 Uint16array 类型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM