0

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));

The results: Supposed to be a solid structure.

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));

Lighting is a bit off 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).

Edward
  • 495
  • 1
  • 6
  • 20
  • Keep in mind that WebGL only renders triangles, so a face with 4+ vertices will not work. You would first need to split the quad into 2 triangles, so face 1 would consist of vertices `[1, 2, 3]` and face 2 would be `[1, 4, 2]`. Additionally, [see this answer for clockwise and counter-clockwise vertex order](https://stackoverflow.com/questions/15041517/what-is-a-clockwise-face-in-opengl), which is also something to consider. – M - Sep 03 '21 at 23:42
  • @Marquizzo And how would I go about making a "clockwise face" if `geo.faces` is deprecated? I tried `setIndex` in the same way I `geo.faces.push` but then no part of the model showed up. This, of course, assuming that the 3DObject file did not store the `VERTICES` number in the correct order in the `FACES` section. – Edward Sep 04 '21 at 17:56
  • Why not use three.js r124 and the `misc_exporter_gltf.html` example to load your scene and export it in a standard format? Then use the current release and load it. – WestLangley Sep 06 '21 at 10:31
  • @WestLangley Sounds like an idea, although loading two different versions sounds like a bit of a load... The alternative would be to try and `php` a converter to OBJ. Just need to figure out a good method to put the textures on the correct faces when I get that far. – Edward Sep 06 '21 at 10:47

0 Answers0