Reputation: 672
I have an .obj file
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 1 0
vn 0 0 1
vn 0 1 0
vn 0 0 1
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
And I need to create THREE.Mesh. I do
var geometry = new THREE.BufferGeometry();
geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));
geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));
geometry.addAttribute('uv', new THREE.BufferAttribute(uvs, 2));
geometry.setIndex(new THREE.BufferAttribute(indices, 1));
var mesh = new THREE.Mesh(geometry, material);
I suppose I need to have follow data in arrays:
var vertices = [1, 2, 3, 4, 5, 6, 7, 8, 9];
var normals = [0, 0, 1, 0, 1, 0, 0, 0, 1];
var uvs = [0, 1, 1, 0]
var indices = // ... ?
I don't understand what do I need to store in indices array?
Upvotes: 0
Views: 780
Reputation: 2237
Here is my example on how it should look like. The definition of the faces shows, that there are no vertices, which have the same texture AND normals indices. So, other as in normal Geometry
, we cannot reuse any vertices, because in BufferGeometry
a index defined in the indices
array apply to vertices, uvs, and normals array. (I think, that's what @gaitat tried to explain.)
v 1 2 3
v 4 5 6
v 7 8 9
vt 0 1
vt 0.5 0.5
vt 1 0
vn 0 0 1
vn 0 1 0
vn 1 0 0
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/3 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 4,5,6, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,4,5]; // itemSize: 1
Edit: In the example above, the second vertex of the first face (2/2/2
) is indexed with 1
. So, we will get the second item set from vertices, uvs, and normals array: 4,5,6
0.5,0.5
0,1,0
. The second vertex of the second face (2/2/3
) is indexed with 4
. So, we will get 5th item set from each array: 4,5,6
0.5,0.5
1,0,0
. The vertex position and uvs of both are the same but the normals are different, so they cannot be reused. Because the index array stores only one index for all and not three for each vertex position, uv, and normal.
f 1/1/1 2/2/2 3/3/3
f 1/1/2 2/2/2 1/2/3
var vertices = [1,2,3, 4,5,6, 7,8,9, 1,2,3, 1,2,1]; // itemSize: 3
var uvs = [0,1, 0.5,0.5, 1,0, 0,1, 0.5,0.5]; // itemSize: 2
var normals = [0,0,1, 0,1,0, 1,0,0, 0,1,0, 1,0,0]; // itemSize: 3
var indices = [0,1,2, 3,1,5]; // itemSize: 1
In this example, the second vertices of both faces are the same (2/2/2
). In this case, the values can be reused. The arrays are shorter and the index of the vertex in the second face is 1
, too.
Upvotes: 1
Reputation: 12642
For this particular example:
var indices = [1, 2, 3, 1, 2, 1];
which would create a degenerate triangle as index 1 appears twice for same (i.e. second) triangle.
There are several ways to define face elements in the .obj format:
f v1 v2 v3 .... // vertex indices
f v1/vt1 v2/vt2 v3/vt3 ... // adding texture indices
f v1/vt1/vn1 v2/vt2/vn2 v3/vt3/vn3 ... // adding normal indices
f v1//vn1 v2//vn2 v3//vn3 ... // eliminating texture indices
As buffers use vertex indices for their attributes you would pick the first number (value1) out of your triplet value1/value2/value3 and form your indices
array.
Upvotes: 1