0

I want to create my own model format. For that purpose I am trying to create custom geometry. I can import geometry properly. Bur face normals doesn't get rendered even I add them to geometry.

Here is input file:

# Coordinates
    0e+0 0e+0 0e+0
    1e+0 0e+0 0e+0
    1e+0 0e+0 1e+0
    0e+0 0e+0 1e+0
    0e+0 1e+0 0e+0
    1e+0 1e+0 0e+0
    1e+0 1e+0 1e+0
    0e+0 1e+0 1e+0
# Normals
0e+0 0e+0 -1e+0
0e+0 -1e+0 0e+0
0e+0 0e+0 1e+0
0e+0 1e+0 0e+0
1e+0 0e+0 0e+0
-1e+0 0e+0 0e+0

# Connectivity List
1 2 6 5
1 2 3 4
3 4 8 7
6 5 8 7
2 6 7 3
1 5 8 4

Here is the way I import it.

    var geometry = new THREE.Geometry();

    //Add all positions to geometry
    for (var g=0;g<coordinates.length;g++){
        geometry.vertices.push(coordinates[g]);

    }

    for(var l=0;l<connectivity.length;l++){

        //sml file have rectangular faces but three js uses triangular faces (THREE.Face4 is deprecated) so converting 4 vertex faces to 3 verex faces 
        var index0= connectivity[l][3]-1;
        var index1= connectivity[l][4]-1;
        var index2= connectivity[l][5]-1;
        var index3= connectivity[l][6]-1;

        //If normals is exist thenaddthem to face array too

        if(normals.length==connectivity.length){

            console.log("Normals are exist");

            var face0=  new THREE.Face3(index0,index1,index2); 
            face0.normal.set(normals[l]);

            geometry.faces.push(face0);

            var face1=  new THREE.Face3(index2,index3,index0);
            face1.normal.set(normals[l]);

            geometry.faces.push(face1); 

        } else{

            console.log("Normals are not exist");

            var face0=  new THREE.Face3(index0,index1,index2);
            geometry.faces.push(face0);
            var face1= new THREE.Face3(index2,index3,index0);

            geometry.faces.push(face1); 
        }
    }

    geometry.computeBoundingBox();
    // geometry.compteVertexNormals();
    geometry.computeFaceNormals();

At the code I am converting quads to triangles in face (connectivity list) array while FACE4 is deprecated by thee.js. And I am assigning same normal to both triangles that sharing same quad.

Here is how this box is rendered:

Box Render

Am I missing something?

Rabbid76
  • 202,892
  • 27
  • 131
  • 174
user3160302
  • 227
  • 1
  • 4
  • 11
  • Did I get it correctly, that no matter, if you have a list of face normals or you don't, then you compute face normals anyway? I'm asking because of this line at the end of the code snippet `geometry.computeFaceNormals();`. – prisoner849 Oct 02 '17 at 15:59
  • yes, I should put a condition before that line. But it is not related to my current problem. Thanks anyway :) – user3160302 Oct 02 '17 at 17:40
  • `.computeFaceNormals()` automatically computes normals for faces in your geometry, when called. Also, in your condition block, you do the same thing twice - creating of two faces. The only difference there is that you add normals, so maybe it would be better to put creation of faces out of condition block and leave addition of normals in it, when condition is `true`. – prisoner849 Oct 02 '17 at 19:07
  • 1
    @prisoner849 Good catch. :) – TheJim01 Oct 03 '17 at 12:38

1 Answers1

0

The following lines do not use the correct syntax.

face0.normal.set(normals[l]);
...
face1.normal.set(normals[l]);

Face3.normal is a Vector3, and Vector3.set takes 3 parameters.

If normals[l] has x, y, and z properties:

face0.normal.set(normals[l].x, normals[l].y, normals[l].z);

will set it correctly.

Alternately, you can pass the normal as a Vector3 into the Face3 constructor. See the docs here for more info.

Based on new info:

Since normals[l] is already a Vector3, you should use Vector3.copy instead of set:

face0.normal.copy(normals[l]);

That said, since it is a Vector3, you should really just include it in the constructor, as I mentioned above.

TheJim01
  • 8,411
  • 1
  • 30
  • 54
  • Or use `.copy()` method of `THREE.Vector3()` to set a normal. – prisoner849 Oct 02 '17 at 16:07
  • 1
    @prisoner849 You may be right, that is if `normals[l]` is already a `Vector3`. We unfortunately, can't tell from the code provided. That did make me notice `geometry.vertices.push(coordinates[g]);`, so hopefully `coordinates[g]` is also a `Vector3`. – TheJim01 Oct 02 '17 at 17:23
  • Yes both of them is already vector3. I didn't included them while it is a long script. – user3160302 Oct 02 '17 at 17:38
  • Yeah, I agree ) Reasonable thought ) – prisoner849 Oct 02 '17 at 19:08
  • it didn't work. I think the issue is not related about setting faces of geometry. because when I export the geometry with my own exporter I can see face data that is extracted from geometry. – user3160302 Oct 02 '17 at 19:48