# Getting full Vectors from a BufferAttribute?

I’ve seen a few people get confused by `geometry.getAttribute('position').array[i]` returning a number instead of a Vector3. I’m guessing it’s because the legacy `Geometry` used to store vertex positions in `Vec3`s, and the new `BufferGeometry` stores it in a one-dimensional array, so that expectation has changed.

I understand there’s an alternative `geometry.getAttribute('position').getX(i)`, that gives you only the x value of the vertex at position `i`. In order to get the full Vertex data, you need to do this 2 to 4 times and build it yourself. So I think it would be helpful to also have a `.getVectorAt(i)` method that returns the full vector already built for you, ready to use.

``````getVectorAt(index) {
const vectorIndex = index * this.itemSize;

// Build Vec2, 3, or 4, based on itemSize
switch (this.itemSize) {
case 1:
return this.array[ vectorIndex ];
break;
case 2:
return new THREE.Vector2(
this.array[ vectorIndex + 0 ],
this.array[ vectorIndex + 1 ]
);
break;
case 3:
return new THREE.Vector3(
this.array[ vectorIndex + 0 ],
this.array[ vectorIndex + 1 ],
this.array[ vectorIndex + 2 ]
);
break;
case 4:
return new THREE.Vector4(
this.array[ vectorIndex + 0 ],
this.array[ vectorIndex + 1 ],
this.array[ vectorIndex + 2 ],
this.array[ vectorIndex + 3 ]
);
break;
}
}
``````

What are your thoughts on this? I think it would be very helpful, especially for people just getting started with `BufferGeometries` and how to extract vertex data from them.

All `VectorX` classes have `.fromBufferAttribute()` method.
`let v3 = new THREE.Vector3().fromBufferAttribute(geometry.attributes.position, index);`

I like the idea. Maybe enhance the method with a target vector `.getVectorAt(index, target)`?
On the other hand, I bet, if users get a vector this way and change its values, they’ll expect that values will be automatically applied to an attribute. And they’ll be confused again

1 Like

The intended way for loading buffer attribute data into vectors is indeed the `fromBufferAttribute()` interface. I’m not sure how I feel about an alternative API.

2 Likes

Ah, I had no idea `VectorX.fromBufferAttribute()` existed! Thanks for the info.

It is redundant to have 2 methods for the same thing, but it seems a bit backward to have it as a method of Vec3. If I want to get data from my BufferAttribute, I go looking in the BufferAttribute documentation, not in Vector3.

It’s just like `renderer.getClearColor()` is a method of WebGLRenderer, not a method of Color. Wouldn’t you think?

When I remember correctly `fromBufferAttribute()` was added because there was already `fromArray()`.

BTW: A method like `getVectorAt()` would definitely need a `target` parameter in order to avoid any object creation within the method.

1 Like

I think constructing Vectors for every vertex is a big enough performance problem that we don’t want to create APIs that encourage it. But it’s fair to say many users might read the BufferAttribute docs thoroughly and still not know what to do. We could fix that in a couple ways:

1. Add a note in BufferAttribute docs about `VectorN.fromBufferAttribute`
2. Add `attribute.getXYZ( i, target )` methods, similar to the existing `getX` and `getY` methods.

With (2) it would be a little inconsistent that `setXYZ` takes three floats instead of a vector.

2 Likes