PUCRS - Faculdade de Informática 

Computer Science Course

Computer Graphics Class


OBJ File Reader Library

by Márcio Serolli Pinho (pinho@inf.pucrs.br)



This page aims to describe the OBJ file reader libray. This library is part of the SmallVR toolkit, but can be used as an standalone library.


The OBJ file format was designed by Alias Wavefront to describe 3D geometry. For more information on this format go to Wosit Website

These version of o use the library was tested with DEVCPP, but it is easy to port it to another C++ compiler. To display  the object image the libray uses OpenGL library.

In order to use the library  you should download it here, unzip the file and open the "Leitura_De_Obj.dev" project file.  
To recompile the library you should open the "OBJ_Lib.dev".  This project creates thje "OBJ_Lib.a" file that contains the library code.

The easiest way to use the library 
in your application is to open the "Leitura_De_Obj.dev" and add you source files in the project. If you need to create a new project you have to link  the OpenGL libraries and the "OBJ_Lib.a" file in your new project.

The 
OBJ_Lib.a contains the SmVR_COBJLoader class, responsible for loading and render a 3D object. This class is also able to detect object collisions. For thes task it user the RAPID library.

The SmVR_COBJLoader class

In order to load an OBJ file you need to instantiate an object from the SmVR_COBJLoader class is defined in "SmVR_COBJLoader.h" file that you must include wherever you need to use the class.
These class has methods to load, render a check for collision between objects. The following sections describe all these 3 methods.

Loading a 3D file

To load a 3D file you just need to instantiate an object from SmVR_COBJLoader class and call the Load method, passing the file name on its call.

When you instatiate the object you can pass a parameter to indicate if you want or not to use the collision detection. As it consumes "some" memory, you should use this feature only if it is really necessary.

#include "SmVR_COBJLoader.h"

// Declares 5 pointers to
SmVR_COBJLoader objects
SmVR_COBJLoader *Objetos[5];
int Colisao;
char name[100];

     Colision = 1;   // = 0 -> we don't need colision detection
                     // = 1 -> we don't need colision detection
 
     // Instantiates the object [0]
     Objetos[0] = new SmVR_COBJLoader(Colisao);

     // load the file "
couch.obj"
     strcpy(name, "couch.obj");

     if (!Objetos[0]->Load(name))
     {
         printf ("Fail reading '%s' object\n", nome);
         system ("pause");
         exit(1);
     }
     else
     {
          printf ("Object '%s' read !\n", nome);                   
     }

Most .OBJ files has a material file describing visual properties of the object, like colors and textures. The default extension for this file is MTL.
For the texture files the only image format supported by this library is the JPG. So, if your textures are in different formats(like, TIFF, GIF or BMP) you must to convert theses files to JPGs and then modify the MTL files.

Displaying an Object

In order to display an object on screen you must call the Render Method. To apply transformations on the 3D object you can use the Opengl geometric transformation rotines (glScale, glTranslate, glRotate).

If in any case the displayed image doesn't seems to be correct, this can be a problem with the orientation of face normals. In these cases you can try to call the InvertNormalOrientation method. You sould do this right after loading the object.
If the problem still remains, turn the cull face removal off using glEnable ( GL_CULL_FACE ).

The sample code presented bellow
shows how to render an object previously loaded with SmVR_COBJLoader class.

    glPushMatrix();
        // Apply the proper transformations
        glColor3f(1.0f,1.0f,1.0f);
        glTranslatef ( 0.0f, -2.0f, 0.0f );
        // render the object
    
    Objetos[2]->Render();       
    glPopMatrix();


Collision Detection Test


To check if there is a collision between 2 objects you should call the function 
IsColliding presented bellow, passing the reference for those objects and the transformation matrices applied to them.  The function returns 1 if there is a collision and 0 otherwise.

int IsColliding(SmVR_COBJLoader *Obj1, SmVR_Matrix M1, SmVR_COBJLoader *Obj2, SmVR_Matrix M2)
{
   return Obj1->Collided(Obj2, M1, M2,0);   
}

To get these transformation matrices, you need to call glGetFloatv function just after render the object. See the sample code bellow.

SmVR_Matrix Data0, Data1;

glPushMatrix();

        glTranslatef ( -3.0f, 0.0f, 0.0f );
        glRotatef(-90,0,1,0);
        Objetos[0]->Render();
        // Save the necessary data for collision detection
        glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)Data0 );
glPopMatrix();

glPushMatrix();
        glTranslatef ( PosX, 0.0f, PosZ );       
        glRotatef(180,0,1,0);
        Objetos[1]->Render();
        
// Save the necessary data for collision detection
        glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)Data1 );
glPopMatrix();


int ret = IsColliding(Objetos[0], Data0, Objetos[1], Data1);
if (ret)
      printf ("Objects 0 and 1 are collinding.\r");
else printf ("There is no collision between objects 0 and 1.\r"); 


The implementation of the collision detection test is based on the RAPID library.

ATTENTION: When you use collision detection you CAN NOT use the glScale for the object !!


Sample 3D Objects

In order to get some free objects for testing, we suggest these websites:

http://www.3dlands.com

http://www.inf.pucrs.br/~pinho/OBJ

http://www.amazing3d.com/modfree.shtml

http://www.3dmodelz.com

http://www.andi3d.com/

http://www.lotr-elves.com/rhadeyasden/

http://www.max-realms.com/

END.