# Getting full Vectors from a BufferAttribute?

**URL:** <https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344>\
**Category:** Discussion\
**Created:** [December 3, 2021, 6:54pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344 "2021-12-03T18:54:26Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![marquizzo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/marquizzo/32/25192_2.png) [@marquizzo](https://discourse.threejs.org/u/marquizzo)\
**Post date:** [December 3, 2021, 6:54pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/1 "2021-12-03T18:54:27Z")

</div>

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)`](https://github.com/mrdoob/three.js/blob/e1ead8c5c2eb2395942f5e7d9af7240befc5d729/src/core/BufferAttribute.js#L283-L287), 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.

```javascript
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.

---

<div class="post-metadata">

**Author:** ![prisoner849](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/prisoner849/32/535_2.png) [@prisoner849](https://discourse.threejs.org/u/prisoner849)\
**Post date:** [December 3, 2021, 7:10pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/2 "2021-12-03T19:10:32Z")

</div>

> [@marquizzo](#):
>
> In order to get the full Vertex data, you need to do this 2 to 4 times and build it yourself.

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 🤔

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [December 3, 2021, 7:35pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/3 "2021-12-03T19:35:52Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![marquizzo](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/marquizzo/32/25192_2.png) [@marquizzo](https://discourse.threejs.org/u/marquizzo)\
**Post date:** [December 3, 2021, 7:53pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/4 "2021-12-03T19:53:04Z")

</div>

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](https://threejs.org/docs/#api/en/core/BufferAttribute), not in Vector3.

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

---

<div class="post-metadata">

**Author:** ![Mugen87](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/mugen87/32/5645_2.png) [@Mugen87](https://discourse.threejs.org/u/Mugen87)\
**Post date:** [December 3, 2021, 8:00pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/5 "2021-12-03T20:00:50Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![donmccurdy](https://yyz1.discourse-cdn.com/flex035/user_avatar/discourse.threejs.org/donmccurdy/32/33209_2.png) [@donmccurdy](https://discourse.threejs.org/u/donmccurdy)\
**Post date:** [December 3, 2021, 8:03pm UTC](https://discourse.threejs.org/t/getting-full-vectors-from-a-bufferattribute/32344/6 "2021-12-03T20:03:21Z")

</div>

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](https://threejs.org/docs/?q=Bufferattr#api/en/core/BufferAttribute) 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.
