Quantcast
Channel: beginners - openFrameworks
Viewing all articles
Browse latest Browse all 4929

How to properly calculate normals of the box?

$
0
0

@cuinjune wrote:

Hi, I'm trying to draw a custom box shape using ofMesh for a practice.

So I added 8 vertices and 36 indices to mesh to create a minimal box shape.

And since I didn't know how to calculate normals properly, I found one from googling but the resulting box looks weird and not natural.

The one on the left is what I created using ofMesh and the one on the right is ofBoxPrimitive.

The image below shows vertices of the box I want to draw.

And here's my code.

in ofApp.h

ofMesh mesh;
ofBoxPrimitive box;
ofLight light;
float size;

in ofApp.cpp

//--------------------------------------------------------------
void ofApp::setup(){

ofSetBackgroundColor(0, 0, 0);

mesh.setMode(OF_PRIMITIVE_TRIANGLES);
mesh.enableIndices();
mesh.enableNormals();

size = 200;
float sizeHalf = size/2;

mesh.addVertex(ofVec3f( sizeHalf, -sizeHalf,  sizeHalf)); // v0
mesh.addVertex(ofVec3f(-sizeHalf, -sizeHalf,  sizeHalf)); // v1
mesh.addVertex(ofVec3f(-sizeHalf,  sizeHalf,  sizeHalf)); // v2
mesh.addVertex(ofVec3f( sizeHalf,  sizeHalf,  sizeHalf)); // v3
mesh.addVertex(ofVec3f( sizeHalf,  sizeHalf, -sizeHalf)); // v4
mesh.addVertex(ofVec3f( sizeHalf, -sizeHalf, -sizeHalf)); // v5
mesh.addVertex(ofVec3f(-sizeHalf, -sizeHalf, -sizeHalf)); // v6
mesh.addVertex(ofVec3f(-sizeHalf,  sizeHalf, -sizeHalf)); // v7

//Front
mesh.addIndex(0);
mesh.addIndex(1);
mesh.addIndex(2);

mesh.addIndex(2);
mesh.addIndex(3);
mesh.addIndex(0);

//Right
mesh.addIndex(0);
mesh.addIndex(3);
mesh.addIndex(4);

mesh.addIndex(4);
mesh.addIndex(5);
mesh.addIndex(0);

//Top
mesh.addIndex(0);
mesh.addIndex(5);
mesh.addIndex(6);

mesh.addIndex(6);
mesh.addIndex(1);
mesh.addIndex(0);

//Left
mesh.addIndex(7);
mesh.addIndex(6);
mesh.addIndex(1);

mesh.addIndex(1);
mesh.addIndex(2);
mesh.addIndex(7);

//Bottom
mesh.addIndex(7);
mesh.addIndex(2);
mesh.addIndex(3);

mesh.addIndex(3);
mesh.addIndex(4);
mesh.addIndex(7);

//Back
mesh.addIndex(7);
mesh.addIndex(6);
mesh.addIndex(5);

mesh.addIndex(5);
mesh.addIndex(4);
mesh.addIndex(7);

//calculate and add normals
for (int i = 0; i < mesh.getNumIndices(); i += 3)
{
    ofVec3f v0 = mesh.getVertex(mesh.getIndex(i));
    ofVec3f v1 = mesh.getVertex(mesh.getIndex(i+1));
    ofVec3f v2 = mesh.getVertex(mesh.getIndex(i+2));

    ofVec3f normal = ((v1 - v0).cross(v2 - v0)).normalize();

    mesh.addNormal(v0 + normal);
    mesh.addNormal(v1 + normal);
    mesh.addNormal(v2 + normal);
}
for (int i = 0; i < mesh.getNumVertices(); ++i)
{
    mesh.setNormal(i, mesh.getNormal(i).normalize());
}

//ofBoxPrimitive (make it be the same as the mesh above)
box.set(size);
box.setResolution(1);

//lights
ofEnableLighting();
ofEnableDepthTest();
light.setup();
light.enable();
light.setPosition(ofGetWidth()/2,ofGetHeight()/2, 1000);

}

//--------------------------------------------------------------
void ofApp::draw(){

ofSetColor(255, 255, 255);

ofPushMatrix();
ofTranslate(ofGetWidth()/2 - 150, ofGetHeight()/2);
ofDrawBitmapString("Custom Box", -50, -200);
ofRotate(220, 0.5, 0.5, 1);
mesh.draw();
ofPopMatrix();

ofPushMatrix();
ofTranslate(ofGetWidth()/2 + 150, ofGetHeight()/2);
ofDrawBitmapString("ofBoxPrimitive", -50, -200);
ofRotate(300, 1, 0.5, 1);
box.draw();
ofPopMatrix();

}

I also tried another normal calculating code written by other OF user but it made the box look even weirder.
(source: https://gist.github.com/patriciogonzalezvivo/5473484)

void setNormals( ofMesh &mesh ){

//The number of the vertices
int nV = mesh.getNumVertices();

//The number of the triangles
int nT = mesh.getNumIndices() / 3;

vector<ofPoint> norm( nV ); //Array for the normals

//Scan all the triangles. For each triangle add its
//normal to norm's vectors of triangle's vertices
for (int t=0; t<nT; t++) {

    //Get indices of the triangle t
    int i1 = mesh.getIndex( 3 * t );
    int i2 = mesh.getIndex( 3 * t + 1 );
    int i3 = mesh.getIndex( 3 * t + 2 );

    //Get vertices of the triangle
    const ofPoint &v1 = mesh.getVertex( i1 );
    const ofPoint &v2 = mesh.getVertex( i2 );
    const ofPoint &v3 = mesh.getVertex( i3 );

    //Compute the triangle's normal
    ofPoint dir = ( (v2 - v1).crossed( v3 - v1 ) ).normalized();

    //Accumulate it to norm array for i1, i2, i3
    norm[ i1 ] += dir;
    norm[ i2 ] += dir;
    norm[ i3 ] += dir;
}

//Normalize the normal's length
for (int i=0; i<nV; i++) {
    norm[i].normalize();
}

//Set the normals to mesh
mesh.clearNormals();
mesh.addNormals( norm );

}

Can anyone please teach me how to properly calculate normals so I can draw a box that looks like ofBoxPrimitive?

Posts: 1

Participants: 1

Read full topic


Viewing all articles
Browse latest Browse all 4929

Trending Articles