Since the r125 update and the replacement of all geometry
with buffergeometry
a lot of my projects are now dead. The massive re-writing of all code put me off quite a bit. I am now attempting to learn this new buffergeometry
and get things going again, mainly on reading and constructing a 3DObject file.
The file has easy to read sections consisting of VERTICES
, TEXTURE VERTICES
(uv), VERTEX NORMALS
, FACES
, and FACE NORMALS
. The FACES
consist of a few attributes, including the number of verts its connected to (which can be 3 and up) followed by number pairs that are the vertex index and uv index the face is connected to.
Back when geometry
was "simple", I would push new THREE.Vector3()
to the geo.vertices
, then push triangles fanning out from the first index, and in some cases push in the norms. Now I try the following:
while(pieces[0]!="VERTICES")
{
i++;
pieces = jedata[i].split(" ");
}
var cnt = parseInt(pieces[1]);
var geo = new THREE.BufferGeometry();
var verts = [];
var norms = [];
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].split(" ");
verts.push(-parseFloat(pieces[1]),parseFloat(pieces[3]),parseFloat(pieces[2]));
}
geo.setAttribute("position",new THREE.Float32BufferAttribute(verts,3));
i+=cnt;
while(pieces[0]!="VERTEX")
{
i++;
pieces = jedata[i].split(" ");
}
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].trim().split(" ");
norms.push(-parseFloat(pieces[1]),parseFloat(pieces[3]),parseFloat(pieces[2]));
}
geo.setAttribute("normal",new THREE.Float32BufferAttribute(norms,3));
How would I go about setting faces to this buffergeometry
in the fan pattern I set in the "simpler" geometry.faces
?
// OLD WAY OF ADDING FACES
while(pieces[0]!="FACES")
{
i++;
pieces = jedata[i].split(" ");
}
cnt = parseInt(pieces[1]);
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].trim().split(" ");
var faces = [];
var vcnt = pieces[7];
for(var k=0; k<vcnt*2; k+=2)
{
faces.push(parseInt(pieces[k+8]));
}
for(var k=1; k<faces.length-1; k++)
{ // Fan out from the first vertex index
geo.faces.push(new THREE.Face3(faces[0],faces[k],faces[k+1]));
}
}
geo.computeFaceNormals();
UPDATE
I have made a rather crude workaround that sort of works, except that there is now at least double the vertex data in the object, and the lighting is not quite working as it should. What I did was to collect the VERTICES
and their VERTEX NORMALS
as XYZ, then sort the VERTICES
according to their order in FACES
, and then feed them into setAttribute
.
while(pieces[0]!="VERTICES")
{
i++;
pieces = jedata[i].split(" ");
}
var cnt = parseInt(pieces[1]);
var geo = new THREE.BufferGeometry();
var verts = [];
var norms = [];
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].split(" ");
verts[j] = [-parseFloat(pieces[1]),parseFloat(pieces[3]),parseFloat(pieces[2])];
}
i+=cnt;
while(pieces[0]!="VERTEX")
{
i++;
pieces = jedata[i].split(" ");
}
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].trim().split(" ");
norms[j] = [-parseFloat(pieces[1]),parseFloat(pieces[3]),parseFloat(pieces[2])];
}
i+=cnt;
while(pieces[0]!="FACES")
{
i++;
pieces = jedata[i].split(" ");
}
cnt = parseInt(pieces[1]);
while(pieces[0]!="0:")
{
i++;
pieces = jedata[i].split(" ");
}
var tris = [];
var trisn = [];
for(var j = 0; j < cnt; j++)
{
pieces = jedata[i+j].trim().split(" ");
var faces = [];
var vcnt = pieces[7];
for(var k=0; k<vcnt*2; k+=2)
{
faces.push(parseInt(pieces[k+8]));
}
for(var k=1; k<faces.length-1; k++)
{
tris.push(verts[faces[0]][0],verts[faces[0]][1],verts[faces[0]][2],
verts[faces[k]][0],verts[faces[k]][1],verts[faces[k]][2],
verts[faces[k+1]][0],verts[faces[k+1]][1],verts[faces[k+1]][2]);
trisn.push(norms[faces[0]][0],norms[faces[0]][1],norms[faces[0]][2],
norms[faces[k]][0],norms[faces[k]][1],norms[faces[k]][2],
norms[faces[k+1]][0],norms[faces[k+1]][1],norms[faces[k+1]][2]);
}
}
geo.setAttribute("position",new THREE.Float32BufferAttribute(tris,3));
geo.setAttribute("normal",new THREE.Float32BufferAttribute(trisn,3));
As you can see, most of the lighting have seams across them, but there is absolutely no lighting on the floor or the far right wall. It is not that the normal is inverted because then one would see right through to the next rooms (there is another floor below).