PUCRS - Faculdade de Informática
Computer Science Course
Computer Graphics Class
OBJ File Reader Library
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.