use Syoyo Fujita's Wavefront obj loader. made some performance improvements in debug mode for Visual Studio

use Maya style controls under Windows (need to fix Linux/OSX) use ALT+mouse to rotate, and mouse pick to pick objects
This commit is contained in:
erwincoumans
2013-07-18 15:55:38 -07:00
parent 733f9027fb
commit a5b73e7c76
25 changed files with 496 additions and 1640 deletions

View File

@@ -82,6 +82,10 @@ public:
{ {
return false; return false;
} }
virtual bool keyboardCallback(int key, int state)
{
return false;
}
}; };
#endif #endif

View File

@@ -40,7 +40,7 @@
#include "../btgui/OpenGLWindow/GLRenderToTexture.h" #include "../btgui/OpenGLWindow/GLRenderToTexture.h"
#include "raytrace/RaytracedShadowDemo.h" #include "raytrace/RaytracedShadowDemo.h"
#include "shadows/ShadowMapDemo.h" //#include "shadows/ShadowMapDemo.h"
#include "constraints/ConstraintsDemo.h" #include "constraints/ConstraintsDemo.h"
bool exportFrame=false; bool exportFrame=false;
@@ -126,7 +126,7 @@ GpuDemo::CreateFunc* allDemos[]=
GpuRaytraceScene::MyCreateFunc, GpuRaytraceScene::MyCreateFunc,
ShadowMapDemo::MyCreateFunc, //ShadowMapDemo::MyCreateFunc,
//GpuRigidBodyDemo::MyCreateFunc, //GpuRigidBodyDemo::MyCreateFunc,
@@ -233,6 +233,9 @@ void MyKeyboardCallback(int key, int state)
{ {
exportFrame = true; exportFrame = true;
} }
if (sDemo)
sDemo->keyboardCallback(key,state);
b3DefaultKeyboardCallback(key,state); b3DefaultKeyboardCallback(key,state);
} }
@@ -653,7 +656,8 @@ int main(int argc, char* argv[])
static bool once=true; static bool once=true;
glClearColor(0.3f, 0.3f, 0.3f, 1.0f); //glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
glClearColor(1,1,1,1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
window->setWheelCallback(b3DefaultWheelCallback); window->setWheelCallback(b3DefaultWheelCallback);

View File

@@ -38,14 +38,8 @@ function createProject(vendor)
"**.cpp", "**.cpp",
"**.h", "**.h",
"../Wavefront/string_extra.cpp", "../Wavefront/tiny_obj_loader.cpp",
"../Wavefront/string_extra.h", "../Wavefront/tiny_obj_loader.h",
"../Wavefront/objLoader.cpp",
"../Wavefront/objLoader.h",
"../Wavefront/obj_parser.cpp",
"../Wavefront/obj_parser.h",
"../Wavefront/list.cpp",
"../Wavefront/list.h",
"../../btgui/OpenGLWindow/GLInstancingRenderer.cpp", "../../btgui/OpenGLWindow/GLInstancingRenderer.cpp",

View File

@@ -23,7 +23,7 @@ extern bool enableExperimentalCpuConcaveCollision;
#include "Bullet3Common/b3Matrix3x3.h" #include "Bullet3Common/b3Matrix3x3.h"
#include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexUtility.h" #include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexUtility.h"
#include "OpenGLWindow/ShapeData.h" #include "OpenGLWindow/ShapeData.h"
#include "../../Wavefront/objLoader.h"
#include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h" #include "Bullet3OpenCL/RigidBody/b3GpuRigidBodyPipeline.h"
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h" #include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
@@ -575,129 +575,6 @@ int b3BulletDataExtractor::createPlaneShape( const Bullet3SerializeBullet2::b3Ve
GraphicsShape* b3BulletDataExtractor::createGraphicsShapeFromWavefrontObj(objLoader* obj)
{
b3AlignedObjectArray<GraphicsVertex>* vertices = new b3AlignedObjectArray<GraphicsVertex>;
{
// int numVertices = obj->vertexCount;
// int numIndices = 0;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
/*
for (int v=0;v<obj->vertexCount;v++)
{
vtx.xyzw[0] = obj->vertexList[v]->e[0];
vtx.xyzw[1] = obj->vertexList[v]->e[1];
vtx.xyzw[2] = obj->vertexList[v]->e[2];
b3Vector3 n(vtx.xyzw[0],vtx.xyzw[1],vtx.xyzw[2]);
if (n.length2()>B3_EPSILON)
{
n.normalize();
vtx.normal[0] = n[0];
vtx.normal[1] = n[1];
vtx.normal[2] = n[2];
} else
{
vtx.normal[0] = 0; //todo
vtx.normal[1] = 1;
vtx.normal[2] = 0;
}
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f; //todo
vertices->push_back(vtx);
}
*/
for (int f=0;f<obj->faceCount;f++)
{
obj_face* face = obj->faceList[f];
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
if (face->vertex_count>=3)
{
b3Vector3 normal(0,1,0);
int vtxBaseIndex = vertices->size();
if (face->vertex_count<=4)
{
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2);
GraphicsVertex vtx0;
vtx0.xyzw[0] = obj->vertexList[face->vertex_index[0]]->e[0];
vtx0.xyzw[1] = obj->vertexList[face->vertex_index[0]]->e[1];
vtx0.xyzw[2] = obj->vertexList[face->vertex_index[0]]->e[2];
vtx0.uv[0] = 0.5;
vtx0.uv[1] = 0.5;
GraphicsVertex vtx1;
vtx1.xyzw[0] = obj->vertexList[face->vertex_index[1]]->e[0];
vtx1.xyzw[1] = obj->vertexList[face->vertex_index[1]]->e[1];
vtx1.xyzw[2] = obj->vertexList[face->vertex_index[1]]->e[2];
vtx1.uv[0] = 0.5;
vtx1.uv[1] = 0.5;
GraphicsVertex vtx2;
vtx2.xyzw[0] = obj->vertexList[face->vertex_index[2]]->e[0];
vtx2.xyzw[1] = obj->vertexList[face->vertex_index[2]]->e[1];
vtx2.xyzw[2] = obj->vertexList[face->vertex_index[2]]->e[2];
vtx2.uv[0] = 0.5;
vtx2.uv[1] = 0.5;
b3Vector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]);
b3Vector3 v1(vtx1.xyzw[0],vtx1.xyzw[1],vtx1.xyzw[2]);
b3Vector3 v2(vtx2.xyzw[0],vtx2.xyzw[1],vtx2.xyzw[2]);
normal = (v1-v0).cross(v2-v0);
normal.normalize();
vtx0.normal[0] = normal[0];
vtx0.normal[1] = normal[1];
vtx0.normal[2] = normal[2];
vtx1.normal[0] = normal[0];
vtx1.normal[1] = normal[1];
vtx1.normal[2] = normal[2];
vtx2.normal[0] = normal[0];
vtx2.normal[1] = normal[1];
vtx2.normal[2] = normal[2];
vertices->push_back(vtx0);
vertices->push_back(vtx1);
vertices->push_back(vtx2);
}
if (face->vertex_count==4)
{
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2);
indicesPtr->push_back(vtxBaseIndex+3);
//
GraphicsVertex vtx3;
vtx3.xyzw[0] = obj->vertexList[face->vertex_index[3]]->e[0];
vtx3.xyzw[1] = obj->vertexList[face->vertex_index[3]]->e[1];
vtx3.xyzw[2] = obj->vertexList[face->vertex_index[3]]->e[2];
vtx3.uv[0] = 0.5;
vtx3.uv[1] = 0.5;
vtx3.normal[0] = normal[0];
vtx3.normal[1] = normal[1];
vtx3.normal[2] = normal[2];
vertices->push_back(vtx3);
}
}
}
GraphicsShape* gfxShape = new GraphicsShape;
gfxShape->m_vertices = &vertices->at(0).xyzw[0];
gfxShape->m_numvertices = vertices->size();
gfxShape->m_indices = &indicesPtr->at(0);
gfxShape->m_numIndices = indicesPtr->size();
for (int i=0;i<4;i++)
gfxShape->m_scaling[i] = 1;//bake the scaling into the vertices
return gfxShape;
}
}
GraphicsShape* b3BulletDataExtractor::createGraphicsShapeFromConvexHull(const b3Vector3* tmpPoints, int numPoints) GraphicsShape* b3BulletDataExtractor::createGraphicsShapeFromConvexHull(const b3Vector3* tmpPoints, int numPoints)

View File

@@ -15,7 +15,7 @@
#include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h" #include "Bullet3OpenCL/RigidBody/b3GpuNarrowPhase.h"
#include "Bullet3OpenCL/RigidBody/b3Config.h" #include "Bullet3OpenCL/RigidBody/b3Config.h"
#include "GpuRigidBodyDemoInternalData.h" #include "GpuRigidBodyDemoInternalData.h"
#include"../../Wavefront/objLoader.h" #include"../../Wavefront/tiny_obj_loader.h"
#include "Bullet3Common/b3Transform.h" #include "Bullet3Common/b3Transform.h"
#include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexUtility.h" #include "Bullet3OpenCL/NarrowphaseCollision/b3ConvexUtility.h"
@@ -26,77 +26,59 @@
#define CONCAVE_GAPZ 16 #define CONCAVE_GAPZ 16
GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj) GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(std::vector<tinyobj::shape_t>& shapes)
{ {
b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>; b3AlignedObjectArray<GLInstanceVertex>* vertices = new b3AlignedObjectArray<GLInstanceVertex>;
{ {
// int numVertices = obj->vertexCount; // int numVertices = obj->vertexCount;
// int numIndices = 0; // int numIndices = 0;
b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>; b3AlignedObjectArray<int>* indicesPtr = new b3AlignedObjectArray<int>;
/*
for (int v=0;v<obj->vertexCount;v++)
{
vtx.xyzw[0] = obj->vertexList[v]->e[0];
vtx.xyzw[1] = obj->vertexList[v]->e[1];
vtx.xyzw[2] = obj->vertexList[v]->e[2];
b3Vector3 n(vtx.xyzw[0],vtx.xyzw[1],vtx.xyzw[2]);
if (n.length2()>B3_EPSILON)
{
n.normalize();
vtx.normal[0] = n[0];
vtx.normal[1] = n[1];
vtx.normal[2] = n[2];
} else for (int s=0;s<shapes.size();s++)
{ {
vtx.normal[0] = 0; //todo tinyobj::shape_t& shape = shapes[s];
vtx.normal[1] = 1; int faceCount = shape.mesh.indices.size();
vtx.normal[2] = 0;
}
vtx.uv[0] = 0.5f;vtx.uv[1] = 0.5f; //todo
vertices->push_back(vtx);
}
*/
for (int f=0;f<obj->faceCount;f++)
for (int f=0;f<faceCount;f+=3)
{ {
obj_face* face = obj->faceList[f];
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]); //b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
if (face->vertex_count>=3) if (1)
{ {
b3Vector3 normal(0,1,0); b3Vector3 normal(0,1,0);
int vtxBaseIndex = vertices->size(); int vtxBaseIndex = vertices->size();
if (face->vertex_count<=4)
{
indicesPtr->push_back(vtxBaseIndex); indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1); indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2); indicesPtr->push_back(vtxBaseIndex+2);
GLInstanceVertex vtx0; GLInstanceVertex vtx0;
vtx0.xyzw[0] = obj->vertexList[face->vertex_index[0]]->e[0]; vtx0.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f]*3+0];
vtx0.xyzw[1] = obj->vertexList[face->vertex_index[0]]->e[1]; vtx0.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f]*3+1];
vtx0.xyzw[2] = obj->vertexList[face->vertex_index[0]]->e[2]; vtx0.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f]*3+2];
vtx0.xyzw[3] = 0.f;//obj->vertexList[face->vertex_index[0]]->e[2]; vtx0.xyzw[3] = 0.f;
vtx0.uv[0] = 0.5f;//obj->textureList[face->vertex_index[0]]->e[0]; vtx0.uv[0] = 0.5f;//shape.mesh.positions[shape.mesh.indices[f]*3+2];?
vtx0.uv[1] = 0.5f;//obj->textureList[face->vertex_index[0]]->e[1]; vtx0.uv[1] = 0.5f;
GLInstanceVertex vtx1; GLInstanceVertex vtx1;
vtx1.xyzw[0] = obj->vertexList[face->vertex_index[1]]->e[0]; vtx1.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f+1]*3+0];
vtx1.xyzw[1] = obj->vertexList[face->vertex_index[1]]->e[1]; vtx1.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f+1]*3+1];
vtx1.xyzw[2] = obj->vertexList[face->vertex_index[1]]->e[2]; vtx1.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f+1]*3+2];
vtx1.xyzw[3]= 0.f; vtx1.xyzw[3]= 0.f;
vtx1.uv[0] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[0]; vtx1.uv[0] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[0];
vtx1.uv[1] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[1]; vtx1.uv[1] = 0.5f;//obj->textureList[face->vertex_index[1]]->e[1];
GLInstanceVertex vtx2; GLInstanceVertex vtx2;
vtx2.xyzw[0] = obj->vertexList[face->vertex_index[2]]->e[0]; vtx2.xyzw[0] = shape.mesh.positions[shape.mesh.indices[f+2]*3+0];
vtx2.xyzw[1] = obj->vertexList[face->vertex_index[2]]->e[1]; vtx2.xyzw[1] = shape.mesh.positions[shape.mesh.indices[f+2]*3+1];
vtx2.xyzw[2] = obj->vertexList[face->vertex_index[2]]->e[2]; vtx2.xyzw[2] = shape.mesh.positions[shape.mesh.indices[f+2]*3+2];
vtx2.xyzw[3] = 0.f; vtx2.xyzw[3] = 0.f;
vtx2.uv[0] = 0.5f;obj->textureList[face->vertex_index[2]]->e[0]; vtx2.uv[0] = 0.5f;
vtx2.uv[1] = 0.5f;obj->textureList[face->vertex_index[2]]->e[1]; vtx2.uv[1] = 0.5f;
b3Vector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]); b3Vector3 v0(vtx0.xyzw[0],vtx0.xyzw[1],vtx0.xyzw[2]);
@@ -118,28 +100,6 @@ GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
vertices->push_back(vtx1); vertices->push_back(vtx1);
vertices->push_back(vtx2); vertices->push_back(vtx2);
} }
if (face->vertex_count==4)
{
indicesPtr->push_back(vtxBaseIndex);
indicesPtr->push_back(vtxBaseIndex+1);
indicesPtr->push_back(vtxBaseIndex+2);
indicesPtr->push_back(vtxBaseIndex+3);
//
GLInstanceVertex vtx3;
vtx3.xyzw[0] = obj->vertexList[face->vertex_index[3]]->e[0];
vtx3.xyzw[1] = obj->vertexList[face->vertex_index[3]]->e[1];
vtx3.xyzw[2] = obj->vertexList[face->vertex_index[3]]->e[2];
vtx3.uv[0] = 0.5;
vtx3.uv[1] = 0.5;
vtx3.normal[0] = normal[0];
vtx3.normal[1] = normal[1];
vtx3.normal[2] = normal[2];
vertices->push_back(vtx3);
}
} }
} }
@@ -158,40 +118,43 @@ GLInstanceGraphicsShape* createGraphicsShapeFromWavefrontObj(objLoader* obj)
void ConcaveScene::createConcaveMesh(const ConstructionInfo& ci, const char* fileName, const b3Vector3& shift, const b3Vector3& scaling) void ConcaveScene::createConcaveMesh(const ConstructionInfo& ci, const char* fileName, const b3Vector3& shift, const b3Vector3& scaling)
{ {
objLoader* objData = new objLoader();
FILE* f = 0;
char relativeFileName[1024]; char relativeFileName[1024];
const char* prefix[]={"./data/","../data/","../../data/","../../../data/","../../../../data/"};
int prefixIndex=-1;
{ {
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numPrefixes = sizeof(prefix)/sizeof(char*); int numPrefixes = sizeof(prefix)/sizeof(char*);
for (int i=0;i<numPrefixes;i++) for (int i=0;i<numPrefixes;i++)
{ {
FILE* f = 0;
sprintf(relativeFileName,"%s%s",prefix[i],fileName); sprintf(relativeFileName,"%s%s",prefix[i],fileName);
f = fopen(relativeFileName,"r"); f = fopen(relativeFileName,"r");
if (f) if (f)
{ {
fclose(f);
prefixIndex = i;
break; break;
} }
} }
} }
if (f) if (prefixIndex<0)
{
fclose(f);
f=0;
}
else
return; return;
objData->load(relativeFileName);
int index=10; int index=10;
{ {
GLInstanceGraphicsShape* shape = createGraphicsShapeFromWavefrontObj(objData);
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, prefix[prefixIndex]);
GLInstanceGraphicsShape* shape = createGraphicsShapeFromWavefrontObj(shapes);
b3AlignedObjectArray<b3Vector3> verts; b3AlignedObjectArray<b3Vector3> verts;
@@ -239,42 +202,43 @@ void ConcaveScene::createConcaveMesh(const ConstructionInfo& ci, const char* fil
} }
} }
delete objData;
} }
void ConcaveScene::setupScene(const ConstructionInfo& ci) void ConcaveScene::setupScene(const ConstructionInfo& ci)
{ {
if (1) if (0)
{ {
//char* fileName = "data/slopedPlane100.obj"; //char* fileName = "slopedPlane100.obj";
//char* fileName = "data/plane100.obj"; //char* fileName = "plane100.obj";
// char* fileName = "data/plane100.obj"; // char* fileName = "plane100.obj";
//char* fileName = "data/teddy.obj";//"plane.obj"; //char* fileName = "teddy.obj";//"plane.obj";
// char* fileName = "data/sponza_closed.obj";//"plane.obj"; // char* fileName = "sponza_closed.obj";//"plane.obj";
//char* fileName = "data/leoTest1.obj"; //char* fileName = "leoTest1.obj";
char* fileName = "data/samurai_monastry.obj"; char* fileName = "samurai_monastry.obj";
// char* fileName = "data/teddy2_VHACD_CHs.obj"; // char* fileName = "teddy2_VHACD_CHs.obj";
b3Vector3 shift1(0,0,0);//0,230,80);//150,-100,-120); b3Vector3 shift1(0,0,0);//0,230,80);//150,-100,-120);
b3Vector4 scaling(4,4,4,1); b3Vector4 scaling(4,4,4,1);
// createConcaveMesh(ci,"data/plane100.obj",shift1,scaling); // createConcaveMesh(ci,"plane100.obj",shift1,scaling);
//createConcaveMesh(ci,"data/plane100.obj",shift,scaling); //createConcaveMesh(ci,"plane100.obj",shift,scaling);
// b3Vector3 shift2(0,0,0);//0,230,80);//150,-100,-120); // b3Vector3 shift2(0,0,0);//0,230,80);//150,-100,-120);
// createConcaveMesh(ci,"data/teddy.obj",shift2,scaling); // createConcaveMesh(ci,"teddy.obj",shift2,scaling);
// b3Vector3 shift3(130,-150,-75);//0,230,80);//150,-100,-120); // b3Vector3 shift3(130,-150,-75);//0,230,80);//150,-100,-120);
// createConcaveMesh(ci,"data/leoTest1.obj",shift3,scaling); // createConcaveMesh(ci,"leoTest1.obj",shift3,scaling);
createConcaveMesh(ci,"data/samurai_monastry.obj",shift1,scaling); createConcaveMesh(ci,"samurai_monastry.obj",shift1,scaling);
} else } else
{ {
int strideInBytes = 9*sizeof(float); int strideInBytes = 9*sizeof(float);
int numVertices = sizeof(cube_vertices)/strideInBytes; int numVertices = sizeof(cube_vertices)/strideInBytes;
int numIndices = sizeof(cube_indices)/sizeof(int); int numIndices = sizeof(cube_indices)/sizeof(int);
@@ -283,7 +247,7 @@ void ConcaveScene::setupScene(const ConstructionInfo& ci)
int mask=1; int mask=1;
int index=0; int index=0;
{ {
b3Vector4 scaling(400,0.001,400,1); b3Vector4 scaling(400,1.,400,1);
int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling); int colIndex = m_data->m_np->registerConvexHullShape(&cube_vertices[0],strideInBytes,numVertices, scaling);
b3Vector3 position(0,-2,0); b3Vector3 position(0,-2,0);
b3Quaternion orn(0,0,0,1); b3Quaternion orn(0,0,0,1);
@@ -406,42 +370,44 @@ void ConcaveCompoundScene::setupScene(const ConstructionInfo& ci)
void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci) void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
{ {
objLoader* objData = new objLoader();
char* fileName = "data/teddy2_VHACD_CHs.obj"; char* fileName = "teddy2_VHACD_CHs.obj";
//char* fileName = "data/cube_offset.obj"; //char* fileName = "cube_offset.obj";
b3Vector3 shift(0,0,0);//0,230,80);//150,-100,-120); b3Vector3 shift(0,0,0);//0,230,80);//150,-100,-120);
b3Vector4 scaling(1,1,1,1); b3Vector4 scaling(1,1,1,1);
FILE* f = 0; const char* prefix[]={"./data/","../data/","../../data/","../../../data/","../../../../data/"};
int prefixIndex=-1;
char relativeFileName[1024]; char relativeFileName[1024];
{ {
const char* prefix[]={"./","../","../../","../../../","../../../../"};
int numPrefixes = sizeof(prefix)/sizeof(char*); int numPrefixes = sizeof(prefix)/sizeof(char*);
for (int i=0;i<numPrefixes;i++) for (int i=0;i<numPrefixes;i++)
{ {
sprintf(relativeFileName,"%s%s",prefix[i],fileName); sprintf(relativeFileName,"%s%s",prefix[i],fileName);
FILE* f = 0;
f = fopen(relativeFileName,"r"); f = fopen(relativeFileName,"r");
if (f) if (f)
{ {
prefixIndex = i;
fclose(f); fclose(f);
break; break;
} }
} }
} }
if (f) if (prefixIndex<0)
fclose(f);
else
return; return;
objData->load(relativeFileName); std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, relativeFileName, prefix[prefixIndex]);
if (objData->objectCount>0)
if (shapes.size()>0)
{ {
@@ -468,15 +434,15 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
b3AlignedObjectArray<b3GpuChildShape> childShapes; b3AlignedObjectArray<b3GpuChildShape> childShapes;
int numChildShapes = objData->objectCount; int numChildShapes = shapes.size();
for (int i=0;i<numChildShapes;i++) for (int i=0;i<numChildShapes;i++)
// int i=4; // int i=4;
{ {
tinyobj::shape_t& shape = shapes[i];
obj_object* object = objData->objectList[i]; int numVertices = shape.mesh.positions.size()/3;
int numVertices = i==numChildShapes-1? objData->vertexCount-object->vertex_offset : objData->objectList[i+1]->vertex_offset - object->vertex_offset; int numFaces = shape.mesh.indices.size()/3;
int numFaces = i==numChildShapes-1? objData->faceCount - object->face_offset : objData->objectList[i+1]->face_offset-object->face_offset;
@@ -500,38 +466,34 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
int baseIndex = vertexArray.size(); int baseIndex = vertexArray.size();
for (int f=0;f<numFaces;f++) for (int f=0;f<numFaces;f++)
{
obj_face* face = objData->faceList[object->face_offset+f];
if (face->vertex_count==3)
{ {
for (int i=0;i<3;i++) for (int i=0;i<3;i++)
{ {
indexArray.push_back(face->vertex_index[i]);//-object->vertex_offset); indexArray.push_back(baseIndex+shape.mesh.indices[f*3+i]);
}
} else
{
b3Assert(0);
} }
} }
b3Vector3 center(0,0,0); b3Vector3 center(0,0,0);
b3AlignedObjectArray<GLInstanceVertex> tmpVertices; b3AlignedObjectArray<GLInstanceVertex> tmpVertices;
//add transformed graphics vertices and indices //add transformed graphics vertices and indices
b3Vector3 myScaling(1,1,1);//50,50,50);//300,300,300); b3Vector3 myScaling(50,50,50);//300,300,300);
for (int v=0;v<numVertices;v++) for (int v=0;v<numVertices;v++)
{ {
GLInstanceVertex vert; GLInstanceVertex vert;
obj_vector* orgVert = objData->vertexList[object->vertex_offset+v];
vert.uv[0] = 0.5f; vert.uv[0] = 0.5f;
vert.uv[1] = 0.5f; vert.uv[1] = 0.5f;
vert.normal[0]=0.f; vert.normal[0]=0.f;
vert.normal[1]=1.f; vert.normal[1]=1.f;
vert.normal[2]=0.f; vert.normal[2]=0.f;
b3Vector3 vertPos; b3Vector3 vertPos;
vertPos[0] = orgVert->e[0]*myScaling[0]; vertPos[0] = shape.mesh.positions[v*3+0]*myScaling[0];
vertPos[1] = orgVert->e[1]*myScaling[1]; vertPos[1] = shape.mesh.positions[v*3+1]*myScaling[1];
vertPos[2] = orgVert->e[2]*myScaling[2]; vertPos[2] = shape.mesh.positions[v*3+2]*myScaling[2];
vertPos[3] =0.f; vertPos[3] =0.f;
center+=vertPos; center+=vertPos;
} }
@@ -541,16 +503,15 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
for (int v=0;v<numVertices;v++) for (int v=0;v<numVertices;v++)
{ {
GLInstanceVertex vert; GLInstanceVertex vert;
obj_vector* orgVert = objData->vertexList[object->vertex_offset+v];
vert.uv[0] = 0.5f; vert.uv[0] = 0.5f;
vert.uv[1] = 0.5f; vert.uv[1] = 0.5f;
vert.normal[0]=0.f; vert.normal[0]=0.f;
vert.normal[1]=1.f; vert.normal[1]=1.f;
vert.normal[2]=0.f; vert.normal[2]=0.f;
b3Vector3 vertPos; b3Vector3 vertPos;
vertPos[0] = orgVert->e[0]*myScaling[0]; vertPos[0] = shape.mesh.positions[v*3+0]*myScaling[0];
vertPos[1] = orgVert->e[1]*myScaling[1]; vertPos[1] = shape.mesh.positions[v*3+1]*myScaling[1];
vertPos[2] = orgVert->e[2]*myScaling[2]; vertPos[2] = shape.mesh.positions[v*3+2]*myScaling[2];
vertPos[3] =0.f; vertPos[3] =0.f;
// vertPos-=center; // vertPos-=center;
vert.xyzw[0] = vertPos[0]; vert.xyzw[0] = vertPos[0];
@@ -588,17 +549,17 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
}; };
int curColor = 0; int curColor = 0;
for (int i=0;i<ci.arraySizeX;i++) for (int i=0;i<1;i++)//ci.arraySizeX;i++)
{ {
for (int j=0;j<ci.arraySizeY;j++) for (int j=0;j<4;j++)
{ {
for (int k=0;k<ci.arraySizeZ;k++) // for (int k=0;k<ci.arraySizeZ;k++)
int k=0;
{ {
float mass = 1;//j==0? 0.f : 1.f; float mass = 1;//j==0? 0.f : 1.f;
//b3Vector3 position(i*10*ci.gapX,j*ci.gapY,k*10*ci.gapZ); //b3Vector3 position(i*10*ci.gapX,j*ci.gapY,k*10*ci.gapZ);
b3Vector3 position(i*10*ci.gapX,10+j*ci.gapY,k*10*ci.gapZ); b3Vector3 position(i*10*ci.gapX,10+j*10*ci.gapY,k*10*ci.gapZ);
// b3Quaternion orn(0,0,0,1); // b3Quaternion orn(0,0,0,1);
b3Quaternion orn(b3Vector3(0,0,1),1.8); b3Quaternion orn(b3Vector3(0,0,1),1.8);
@@ -616,7 +577,7 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
} }
} }
delete objData;
} }
void ConcaveCompoundScene::createDynamicObjects(const ConstructionInfo& ci) void ConcaveCompoundScene::createDynamicObjects(const ConstructionInfo& ci)

View File

@@ -304,9 +304,28 @@ b3Vector3 GpuRigidBodyDemo::getRayTo(int x,int y)
return rayTo; return rayTo;
} }
bool GpuRigidBodyDemo::keyboardCallback(int key, int state)
{
if (m_data)
{
if (key==B3G_ALT)
{
m_data->m_altPressed = state;
}
if (key==B3G_CONTROL)
{
m_data->m_controlPressed = state;
}
}
return false;
}
bool GpuRigidBodyDemo::mouseMoveCallback(float x,float y) bool GpuRigidBodyDemo::mouseMoveCallback(float x,float y)
{ {
if (m_data->m_altPressed!=0)
return false;
if (m_data->m_pickBody>=0 && m_data->m_pickConstraint>=0) if (m_data->m_pickBody>=0 && m_data->m_pickConstraint>=0)
{ {
m_data->m_rigidBodyPipeline->removeConstraintByUid(m_data->m_pickConstraint); m_data->m_rigidBodyPipeline->removeConstraintByUid(m_data->m_pickConstraint);
@@ -329,9 +348,10 @@ bool GpuRigidBodyDemo::mouseMoveCallback(float x,float y)
} }
bool GpuRigidBodyDemo::mouseButtonCallback(int button, int state, float x, float y) bool GpuRigidBodyDemo::mouseButtonCallback(int button, int state, float x, float y)
{ {
if (state==1) if (state==1)
{ {
if (button==0) if(button==0 && (m_data->m_altPressed==0))
{ {
b3AlignedObjectArray<b3RayInfo> rays; b3AlignedObjectArray<b3RayInfo> rays;
b3AlignedObjectArray<b3RayHit> hitResults; b3AlignedObjectArray<b3RayHit> hitResults;

View File

@@ -43,7 +43,7 @@ public:
b3Vector3 getRayTo(int x,int y); b3Vector3 getRayTo(int x,int y);
virtual bool mouseMoveCallback(float x,float y); virtual bool mouseMoveCallback(float x,float y);
virtual bool mouseButtonCallback(int button, int state, float x, float y); virtual bool mouseButtonCallback(int button, int state, float x, float y);
virtual bool keyboardCallback(int key, int state);
}; };
#endif //GPU_RIGID_BODY_DEMO_H #endif //GPU_RIGID_BODY_DEMO_H

View File

@@ -24,6 +24,9 @@ struct GpuRigidBodyDemoInternalData
int m_pickBody; int m_pickBody;
int m_pickConstraint; int m_pickConstraint;
int m_altPressed;
int m_controlPressed;
int m_pickFixedBody; int m_pickFixedBody;
int m_pickGraphicsShapeIndex; int m_pickGraphicsShapeIndex;
int m_pickGraphicsShapeInstance; int m_pickGraphicsShapeInstance;
@@ -38,7 +41,9 @@ struct GpuRigidBodyDemoInternalData
m_pickFixedBody(-1), m_pickFixedBody(-1),
m_pickGraphicsShapeIndex(-1), m_pickGraphicsShapeIndex(-1),
m_pickGraphicsShapeInstance(-1), m_pickGraphicsShapeInstance(-1),
m_pickBody(-1) m_pickBody(-1),
m_altPressed(0),
m_controlPressed(0)
{ {
} }

View File

@@ -0,0 +1,88 @@
tinyobjloader
=============
http://syoyo.github.io/tinyobjloader/
Tiny but poweful single file wavefront obj loader written in C++. No dependency except for C++ STL. It can parse 10M over polygons with moderate memory and time.
Good for embedding .obj loader to your (global illumination) renderer ;-)
Example
-------
![Rungholt](https://github.com/syoyo/tinyobjloader/blob/master/images/rungholt.jpg?raw=true)
tinyobjloader can successfully load 6M triangles Rungholt scene.
http://graphics.cs.williams.edu/data/meshes.xml
Features
--------
* Group
* Vertex
* Texcoord
* Normal
* Material
* Unknown material attributes are treated as key-value.
Notes
-----
Polygon is converted into triangle.
License
-------
Licensed under 2 clause BSD.
Usage
-----
std::string inputfile = "cornell_box.obj";
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, inputfile.c_str());
if (!err.empty()) {
std::cerr << err << std::endl;
exit(1);
}
std::cout << "# of shapes : " << shapes.size() << std::endl;
for (size_t i = 0; i < shapes.size(); i++) {
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
printf("shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
assert((shapes[i].mesh.indices.size() % 3) == 0);
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
printf(" idx[%ld] = %d\n", f, shapes[i].mesh.indices[f]);
}
printf("shape[%ld].vertices: %ld\n", i, shapes[i].mesh.positions.size());
assert((shapes[i].mesh.positions.size() % 3) == 0);
for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) {
printf(" v[%ld] = (%f, %f, %f)\n", v,
shapes[i].mesh.positions[3*v+0],
shapes[i].mesh.positions[3*v+1],
shapes[i].mesh.positions[3*v+2]);
}
printf("shape[%ld].material.name = %s\n", i, shapes[i].material.name.c_str());
printf(" material.Ka = (%f, %f ,%f)\n", shapes[i].material.ambient[0], shapes[i].material.ambient[1], shapes[i].material.ambient[2]);
printf(" material.Kd = (%f, %f ,%f)\n", shapes[i].material.diffuse[0], shapes[i].material.diffuse[1], shapes[i].material.diffuse[2]);
printf(" material.Ks = (%f, %f ,%f)\n", shapes[i].material.specular[0], shapes[i].material.specular[1], shapes[i].material.specular[2]);
printf(" material.Tr = (%f, %f ,%f)\n", shapes[i].material.transmittance[0], shapes[i].material.transmittance[1], shapes[i].material.transmittance[2]);
printf(" material.Ke = (%f, %f ,%f)\n", shapes[i].material.emission[0], shapes[i].material.emission[1], shapes[i].material.emission[2]);
printf(" material.Ns = %f\n", shapes[i].material.shininess);
printf(" material.map_Ka = %s\n", shapes[i].material.ambient_texname.c_str());
printf(" material.map_Kd = %s\n", shapes[i].material.diffuse_texname.c_str());
printf(" material.map_Ks = %s\n", shapes[i].material.specular_texname.c_str());
printf(" material.map_Ns = %s\n", shapes[i].material.normal_texname.c_str());
std::map<std::string, std::string>::iterator it(shapes[i].material.unknown_parameter.begin());
std::map<std::string, std::string>::iterator itEnd(shapes[i].material.unknown_parameter.end());
for (; it != itEnd; it++) {
printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str());
}
printf("\n");
}

View File

@@ -1,205 +0,0 @@
#include "list.h"
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
// internal helper functions
char list_is_full(list *listo)
{
return(listo->item_count == listo->current_max_size);
}
void list_grow(list *old_listo)
{
int i;
list new_listo;
list_make(&new_listo, old_listo->current_max_size*2, old_listo->growable++);
for(i=0; i<old_listo->current_max_size; i++)
list_add_item(&new_listo, old_listo->items[i] , old_listo->names[i]);
list_free(old_listo);
//copy new structure to old list
old_listo->names = new_listo.names;
old_listo->items = new_listo.items;
old_listo->item_count = new_listo.item_count;
old_listo->current_max_size = new_listo.current_max_size;
old_listo->growable = new_listo.growable;
}
//end helpers
void list_make(list *listo, int start_size, char growable)
{
listo->names = (char**) malloc(sizeof(char*) * start_size);
listo->items = (void**) malloc(sizeof(void*) * start_size);
listo->item_count = 0;
listo->current_max_size = start_size;
listo->growable = growable;
}
int list_add_item(list *listo, void *item, char *name)
{
int name_length;
char *new_name;
if( list_is_full(listo) )
{
if( listo->growable )
list_grow(listo);
else
return -1;
}
listo->names[listo->item_count] = NULL;
if(name != NULL)
{
name_length = strlen(name);
new_name = (char*) malloc(sizeof(char) * name_length + 1);
strncpy(new_name, name, name_length);
listo->names[listo->item_count] = new_name;
}
listo->items[listo->item_count] = item;
listo->item_count++;
return listo->item_count-1;
}
char* list_print_items(list *listo)
{
int i;
for(i=0; i < listo->item_count; i++)
{
printf("%s\n", listo->names[i]);
}
return NULL;
}
void* list_get_index(list *listo, int indx)
{
if(indx < listo->item_count)
return listo->items[indx];
return NULL;
}
void* list_get_item(list *listo, void *item_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(listo->items[i] == item_to_find)
return listo->items[i];
}
return NULL;
}
void* list_get_name(list *listo, char *name_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(strncmp(listo->names[i], name_to_find, strlen(name_to_find)) == 0)
return listo->items[i];
}
return NULL;
}
int list_find(list *listo, char *name_to_find)
{
int i = 0;
for(i=0; i < listo->item_count; i++)
{
if(strncmp(listo->names[i], name_to_find, strlen(name_to_find)) == 0)
return i;
}
return -1;
}
void list_delete_item(list *listo, void *item)
{
int i;
for(i=0; i < listo->item_count; i++)
{
if( listo->items[i] == item )
list_delete_index(listo, i);
}
}
void list_delete_name(list *listo, char *name)
{
int i;
//int j;
//char remove = 0;
// int length_name = strlen(name);
int item_name;
if(name == NULL)
return;
for(i=0; i < listo->item_count; i++)
{
item_name = strlen(name);
if( name != NULL && (strncmp(listo->names[i], name, strlen(name)) == 0) )
list_delete_index(listo, i);
}
}
void list_delete_index(list *listo, int indx)
{
int j;
//remove item
if(listo->names[indx] != NULL)
free(listo->names[indx]);
//restructure
for(j=indx; j < listo->item_count-1; j++)
{
listo->names[j] = listo->names[j+1];
listo->items[j] = listo->items[j+1];
}
listo->item_count--;
return;
}
void list_delete_all(list *listo)
{
int i;
for(i=listo->item_count-1; i>=0; i--)
list_delete_index(listo, i);
}
void list_free(list *listo)
{
list_delete_all(listo);
free(listo->names);
free(listo->items);
}
void list_print_list(list *listo)
{
int i;
printf("count: %i/%i\n", listo->item_count, listo->current_max_size);
for(i=0; i < listo->item_count; i++)
{
printf("list[%i]: %s\n", i, listo->names[i]);
}
}

View File

@@ -1,29 +0,0 @@
#ifndef __LIST_H
#define __LIST_H
typedef struct
{
int item_count;
int current_max_size;
char growable;
void **items;
char **names;
} list;
void list_make(list *listo, int size, char growable);
int list_add_item(list *listo, void *item, char *name);
char* list_print_items(list *listo);
void* list_get_name(list *listo, char *name);
void* list_get_index(list *listo, int indx);
void* list_get_item(list *listo, void *item_to_find);
int list_find(list *listo, char *name_to_find);
void list_delete_index(list *listo, int indx);
void list_delete_name(list *listo, char *name);
void list_delete_item(list *listo, void *item);
void list_delete_all(list *listo);
void list_print_list(list *listo);
void list_free(list *listo);
void test_list();
#endif

107
Demos3/Wavefront/main.cpp Normal file
View File

@@ -0,0 +1,107 @@
#include "tiny_obj_loader.h"
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
static bool
TestLoadObj(
const char* fileName,
bool verbose
)
{
const char* prefix[]={"./data/","../data/","../../data/","../../../data/","../../../../data/"};
char fullPath[1024];
int index=-1;
{
int numPrefixes = sizeof(prefix)/sizeof(char*);
for (int i=0;i<numPrefixes;i++)
{
sprintf(fullPath,"%s%s",prefix[i],fileName);
FILE* f;
f = fopen(fullPath,"r");
if (f)
{
index=i;
fclose(f);
break;
}
}
}
if (index<0)
{
printf("file not found %s\n", fileName);
return false;
}
std::cout << "Loading " << fullPath << std::endl;
std::vector<tinyobj::shape_t> shapes;
std::string err = tinyobj::LoadObj(shapes, fullPath, prefix[index]);
if (!err.empty()) {
std::cerr << err << std::endl;
return false;
}
std::cout << "# of shapes : " << shapes.size() << std::endl;
if (verbose)
{
for (size_t i = 0; i < shapes.size(); i++) {
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
printf("shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
assert((shapes[i].mesh.indices.size() % 3) == 0);
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
printf(" idx[%ld] = %d\n", f, shapes[i].mesh.indices[f]);
}
printf("shape[%ld].vertices: %ld\n", i, shapes[i].mesh.positions.size());
assert((shapes[i].mesh.positions.size() % 3) == 0);
for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) {
printf(" v[%ld] = (%f, %f, %f)\n", v,
shapes[i].mesh.positions[3*v+0],
shapes[i].mesh.positions[3*v+1],
shapes[i].mesh.positions[3*v+2]);
}
printf("shape[%ld].material.name = %s\n", i, shapes[i].material.name.c_str());
printf(" material.Ka = (%f, %f ,%f)\n", shapes[i].material.ambient[0], shapes[i].material.ambient[1], shapes[i].material.ambient[2]);
printf(" material.Kd = (%f, %f ,%f)\n", shapes[i].material.diffuse[0], shapes[i].material.diffuse[1], shapes[i].material.diffuse[2]);
printf(" material.Ks = (%f, %f ,%f)\n", shapes[i].material.specular[0], shapes[i].material.specular[1], shapes[i].material.specular[2]);
printf(" material.Tr = (%f, %f ,%f)\n", shapes[i].material.transmittance[0], shapes[i].material.transmittance[1], shapes[i].material.transmittance[2]);
printf(" material.Ke = (%f, %f ,%f)\n", shapes[i].material.emission[0], shapes[i].material.emission[1], shapes[i].material.emission[2]);
printf(" material.Ns = %f\n", shapes[i].material.shininess);
printf(" material.map_Ka = %s\n", shapes[i].material.ambient_texname.c_str());
printf(" material.map_Kd = %s\n", shapes[i].material.diffuse_texname.c_str());
printf(" material.map_Ks = %s\n", shapes[i].material.specular_texname.c_str());
printf(" material.map_Ns = %s\n", shapes[i].material.normal_texname.c_str());
std::map<std::string, std::string>::iterator it(shapes[i].material.unknown_parameter.begin());
std::map<std::string, std::string>::iterator itEnd(shapes[i].material.unknown_parameter.end());
for (; it != itEnd; it++) {
printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str());
}
printf("\n");
}
}
return true;
}
int main( int argc, char **argv)
{
assert(true == TestLoadObj("cornell_box.obj",true));
assert(true == TestLoadObj("cube.obj",true));
assert(true==TestLoadObj("samurai_monastry.obj",false));
assert(true==TestLoadObj("teddy2_VHACD_CHs.obj",true));
return 0;
}

View File

@@ -1,46 +0,0 @@
#include "objLoader.h"
#include "obj_parser.h"
int objLoader::load(char *filename)
{
int no_error = 1;
no_error = parse_obj_scene(&data, filename);
if(no_error)
{
this->vertexCount = data.vertex_count;
this->normalCount = data.vertex_normal_count;
this->textureCount = data.vertex_texture_count;
this->faceCount = data.face_count;
this->sphereCount = data.sphere_count;
this->planeCount = data.plane_count;
this->lightPointCount = data.light_point_count;
this->lightDiscCount = data.light_disc_count;
this->lightQuadCount = data.light_quad_count;
this->materialCount = data.material_count;
this->vertexList = data.vertex_list;
this->normalList = data.vertex_normal_list;
this->textureList = data.vertex_texture_list;
this->faceList = data.face_list;
this->sphereList = data.sphere_list;
this->planeList = data.plane_list;
this->lightPointList = data.light_point_list;
this->lightDiscList = data.light_disc_list;
this->lightQuadList = data.light_quad_list;
this->objectList = data.object_list;
this->objectCount = data.object_count;
this->materialList = data.material_list;
this->camera = data.camera;
}
return no_error;
}

View File

@@ -1,52 +0,0 @@
#ifndef OBJ_LOADER_H
#define OBJ_LOADER_H
#include "obj_parser.h"
class objLoader
{
public:
objLoader() {}
~objLoader()
{
delete_obj_data(&data);
}
int load(char *filename);
obj_vector **vertexList;
obj_vector **normalList;
obj_vector **textureList;
obj_face **faceList;
obj_sphere **sphereList;
obj_plane **planeList;
obj_light_point **lightPointList;
obj_light_quad **lightQuadList;
obj_light_disc **lightDiscList;
obj_object** objectList;
obj_material **materialList;
int vertexCount;
int normalCount;
int textureCount;
int faceCount;
int sphereCount;
int planeCount;
int lightPointCount;
int lightQuadCount;
int lightDiscCount;
int objectCount;
int materialCount;
obj_camera *camera;
private:
obj_scene_data data;
};
#endif

View File

@@ -1,167 +0,0 @@
// Obj_loader.cpp : Defines the entry point for the console application.
//
#include <stdio.h>
#include "objLoader.h"
void printVector(obj_vector *v)
{
printf("%.2f,", v->e[0] );
printf("%.2f,", v->e[1] );
printf("%.2f ", v->e[2] );
}
int main(int argc, char **argv)
{
objLoader *objData = new objLoader();
objData->load("test.obj");
printf("Number of vertices: %i\n", objData->vertexCount);
printf("Number of vertex normals: %i\n", objData->normalCount);
printf("Number of texture coordinates: %i\n", objData->textureCount);
printf("\n");
printf("Number of faces: %i\n", objData->faceCount);
for(int i=0; i<objData->faceCount; i++)
{
obj_face *o = objData->faceList[i];
printf(" face ");
for(int j=0; j<3; j++)
{
printVector(objData->vertexList[ o->vertex_index[j] ]);
}
printf("\n");
}
printf("\n");
printf("Number of spheres: %i\n", objData->sphereCount);
for(int i=0; i<objData->sphereCount; i++)
{
obj_sphere *o = objData->sphereList[i];
printf(" sphere ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->up_normal_index ]);
printVector(objData->normalList[ o->equator_normal_index ]);
printf("\n");
}
printf("\n");
printf("Number of planes: %i\n", objData->planeCount);
for(int i=0; i<objData->planeCount; i++)
{
obj_plane *o = objData->planeList[i];
printf(" plane ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->normal_index]);
printVector(objData->normalList[ o->rotation_normal_index]);
printf("\n");
}
printf("\n");
printf("Number of point lights: %i\n", objData->lightPointCount);
for(int i=0; i<objData->lightPointCount; i++)
{
obj_light_point *o = objData->lightPointList[i];
printf(" plight ");
printVector(objData->vertexList[ o->pos_index ]);
printf("\n");
}
printf("\n");
printf("Number of disc lights: %i\n", objData->lightDiscCount);
for(int i=0; i<objData->lightDiscCount; i++)
{
obj_light_disc *o = objData->lightDiscList[i];
printf(" dlight ");
printVector(objData->vertexList[ o->pos_index ]);
printVector(objData->normalList[ o->normal_index ]);
printf("\n");
}
printf("\n");
printf("Number of quad lights: %i\n", objData->lightQuadCount);
for(int i=0; i<objData->lightQuadCount; i++)
{
obj_light_quad *o = objData->lightQuadList[i];
printf(" qlight ");
printVector(objData->vertexList[ o->vertex_index[0] ]);
printVector(objData->vertexList[ o->vertex_index[1] ]);
printVector(objData->vertexList[ o->vertex_index[2] ]);
printVector(objData->vertexList[ o->vertex_index[3] ]);
printf("\n");
}
printf("\n");
if(objData->camera != NULL)
{
printf("Found a camera\n");
printf(" position: ");
printVector(objData->vertexList[ objData->camera->camera_pos_index ]);
printf("\n looking at: ");
printVector(objData->vertexList[ objData->camera->camera_look_point_index ]);
printf("\n up normal: ");
printVector(objData->normalList[ objData->camera->camera_up_norm_index ]);
printf("\n");
}
printf("\n");
printf("Number of materials: %i\n", objData->materialCount);
for(int i=0; i<objData->materialCount; i++)
{
obj_material *mtl = objData->materialList[i];
printf(" name: %s", mtl->name);
printf(" amb: %.2f ", mtl->amb[0]);
printf("%.2f ", mtl->amb[1]);
printf("%.2f\n", mtl->amb[2]);
printf(" diff: %.2f ", mtl->diff[0]);
printf("%.2f ", mtl->diff[1]);
printf("%.2f\n", mtl->diff[2]);
printf(" spec: %.2f ", mtl->spec[0]);
printf("%.2f ", mtl->spec[1]);
printf("%.2f\n", mtl->spec[2]);
printf(" reflect: %.2f\n", mtl->reflect);
printf(" trans: %.2f\n", mtl->trans);
printf(" glossy: %i\n", mtl->glossy);
printf(" shiny: %i\n", mtl->shiny);
printf(" refact: %.2f\n", mtl->refract_index);
printf(" texture: %s\n", mtl->texture_filename);
printf("\n");
}
printf("\n");
//vertex, normal, and texture test
if(objData->textureCount > 2 && objData->normalCount > 2 && objData->faceCount > 2)
{
printf("Detailed face data:\n");
for(int i=0; i<3; i++)
{
obj_face *o = objData->faceList[i];
printf(" face ");
for(int j=0; j<3; j++)
{
printf("%i/", o->vertex_index[j] );
printf("%i/", o->texture_index[j] );
printf("%i ", o->normal_index[j] );
}
printf("\n");
}
}
return 0;
}

View File

@@ -1,591 +0,0 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "obj_parser.h"
#include "list.h"
#include "string_extra.h"
#define WHITESPACE " \t\n\r"
void obj_free_half_list(list *listo)
{
list_delete_all(listo);
free(listo->names);
}
int obj_convert_to_list_index(int current_max, int index)
{
if(index == 0) //no index
return -1;
if(index < 0) //relative to current list position
return current_max + index;
return index - 1; //normal counting index
}
void obj_convert_to_list_index_v(int current_max, int *indices)
{
for(int i=0; i<MAX_VERTEX_COUNT; i++)
indices[i] = obj_convert_to_list_index(current_max, indices[i]);
}
void obj_set_material_defaults(obj_material *mtl)
{
mtl->amb[0] = 0.2;
mtl->amb[1] = 0.2;
mtl->amb[2] = 0.2;
mtl->diff[0] = 0.8;
mtl->diff[1] = 0.8;
mtl->diff[2] = 0.8;
mtl->spec[0] = 1.0;
mtl->spec[1] = 1.0;
mtl->spec[2] = 1.0;
mtl->reflect = 0.0;
mtl->trans = 1;
mtl->glossy = 98;
mtl->shiny = 0;
mtl->refract_index = 1;
mtl->texture_filename[0] = '\0';
}
int obj_parse_vertex_index(int *vertex_index, int *texture_index, int *normal_index)
{
char *temp_str;
char *token;
int vertex_count = 0;
while( (token = strtok(NULL, WHITESPACE)) != NULL)
{
if(texture_index != NULL)
texture_index[vertex_count] = 0;
if(normal_index != NULL)
normal_index[vertex_count] = 0;
vertex_index[vertex_count] = atoi( token );
if(contains(token, "//")) //normal only
{
temp_str = strchr(token, '/');
temp_str++;
normal_index[vertex_count] = atoi( ++temp_str );
}
else if(contains(token, "/"))
{
temp_str = strchr(token, '/');
texture_index[vertex_count] = atoi( ++temp_str );
if(contains(temp_str, "/"))
{
temp_str = strchr(temp_str, '/');
normal_index[vertex_count] = atoi( ++temp_str );
}
}
vertex_count++;
}
return vertex_count;
}
obj_object* obj_parse_object(obj_growable_scene_data *scene)
{
obj_object* obj= (obj_object*)malloc(sizeof(obj_object));
obj->vertex_offset = scene->vertex_list.item_count;
obj->face_offset = scene->face_list.item_count;
// get the name
strncpy(obj->name, strtok(NULL, " \t"), OBJECT_NAME_SIZE);
return obj;
}
obj_face* obj_parse_face(obj_growable_scene_data *scene)
{
int vertex_count;
obj_face *face = (obj_face*)malloc(sizeof(obj_face));
vertex_count = obj_parse_vertex_index(face->vertex_index, face->texture_index, face->normal_index);
obj_convert_to_list_index_v(scene->vertex_list.item_count, face->vertex_index);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, face->texture_index);
obj_convert_to_list_index_v(scene->vertex_normal_list.item_count, face->normal_index);
face->vertex_count = vertex_count;
return face;
}
obj_sphere* obj_parse_sphere(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_sphere *obj = (obj_sphere*)malloc(sizeof(obj_sphere));
obj_parse_vertex_index(temp_indices, obj->texture_index, NULL);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, obj->texture_index);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->up_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
obj->equator_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[2]);
return obj;
}
obj_plane* obj_parse_plane(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_plane *obj = (obj_plane*)malloc(sizeof(obj_plane));
obj_parse_vertex_index(temp_indices, obj->texture_index, NULL);
obj_convert_to_list_index_v(scene->vertex_texture_list.item_count, obj->texture_index);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
obj->rotation_normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[2]);
return obj;
}
obj_light_point* obj_parse_light_point(obj_growable_scene_data *scene)
{
obj_light_point *o= (obj_light_point*)malloc(sizeof(obj_light_point));
o->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, atoi( strtok(NULL, WHITESPACE)) );
return o;
}
obj_light_quad* obj_parse_light_quad(obj_growable_scene_data *scene)
{
obj_light_quad *o = (obj_light_quad*)malloc(sizeof(obj_light_quad));
obj_parse_vertex_index(o->vertex_index, NULL, NULL);
obj_convert_to_list_index_v(scene->vertex_list.item_count, o->vertex_index);
return o;
}
obj_light_disc* obj_parse_light_disc(obj_growable_scene_data *scene)
{
int temp_indices[MAX_VERTEX_COUNT];
obj_light_disc *obj = (obj_light_disc*)malloc(sizeof(obj_light_disc));
obj_parse_vertex_index(temp_indices, NULL, NULL);
obj->pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, temp_indices[0]);
obj->normal_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, temp_indices[1]);
return obj;
}
obj_vector* obj_parse_vector()
{
obj_vector *v = (obj_vector*)malloc(sizeof(obj_vector));
v->e[0] = atof( strtok(NULL, WHITESPACE));
v->e[1] = atof( strtok(NULL, WHITESPACE));
v->e[2] = atof( strtok(NULL, WHITESPACE));
return v;
}
obj_vector* obj_parse_vector2()
{
obj_vector *v = (obj_vector*)malloc(sizeof(obj_vector));
v->e[0] = atof( strtok(NULL, WHITESPACE));
v->e[1] = atof( strtok(NULL, WHITESPACE));
v->e[2] = 0.f;
return v;
}
void obj_parse_camera(obj_growable_scene_data *scene, obj_camera *camera)
{
int indices[3];
obj_parse_vertex_index(indices, NULL, NULL);
camera->camera_pos_index = obj_convert_to_list_index(scene->vertex_list.item_count, indices[0]);
camera->camera_look_point_index = obj_convert_to_list_index(scene->vertex_list.item_count, indices[1]);
camera->camera_up_norm_index = obj_convert_to_list_index(scene->vertex_normal_list.item_count, indices[2]);
}
int obj_parse_mtl_file(char *filename, list *material_list)
{
int line_number = 0;
char *current_token;
char current_line[OBJ_LINE_SIZE];
char material_open = 0;
obj_material *current_mtl = NULL;
FILE *mtl_file_stream;
// open scene
mtl_file_stream = fopen( filename, "r");
if(mtl_file_stream == 0)
{
fprintf(stderr, "Warning: cannot find material file: %s (skipping)\n", filename);
return 0;
}
list_make(material_list, 10, 1);
while( fgets(current_line, OBJ_LINE_SIZE, mtl_file_stream) )
{
current_token = strtok( current_line, " \t\n\r");
line_number++;
//skip comments
if( current_token == NULL || strequal(current_token, "//") || strequal(current_token, "#"))
continue;
//start material
else if( strequal(current_token, "newmtl"))
{
material_open = 1;
current_mtl = (obj_material*) malloc(sizeof(obj_material));
obj_set_material_defaults(current_mtl);
// get the name
strncpy(current_mtl->name, strtok(NULL, " \t"), MATERIAL_NAME_SIZE);
list_add_item(material_list, current_mtl, current_mtl->name);
}
//ambient
else if( strequal(current_token, "Ka") && material_open)
{
current_mtl->amb[0] = atof( strtok(NULL, " \t"));
current_mtl->amb[1] = atof( strtok(NULL, " \t"));
current_mtl->amb[2] = atof( strtok(NULL, " \t"));
}
//diff
else if( strequal(current_token, "Kd") && material_open)
{
current_mtl->diff[0] = atof( strtok(NULL, " \t"));
current_mtl->diff[1] = atof( strtok(NULL, " \t"));
current_mtl->diff[2] = atof( strtok(NULL, " \t"));
}
//specular
else if( strequal(current_token, "Ks") && material_open)
{
current_mtl->spec[0] = atof( strtok(NULL, " \t"));
current_mtl->spec[1] = atof( strtok(NULL, " \t"));
current_mtl->spec[2] = atof( strtok(NULL, " \t"));
}
//shiny
else if( strequal(current_token, "Ns") && material_open)
{
current_mtl->shiny = atof( strtok(NULL, " \t"));
}
//transparent
else if( strequal(current_token, "d") && material_open)
{
current_mtl->trans = atof( strtok(NULL, " \t"));
}
//reflection
else if( strequal(current_token, "r") && material_open)
{
current_mtl->reflect = atof( strtok(NULL, " \t"));
}
//glossy
else if( strequal(current_token, "sharpness") && material_open)
{
current_mtl->glossy = atof( strtok(NULL, " \t"));
}
//refract index
else if( strequal(current_token, "Ni") && material_open)
{
current_mtl->refract_index = atof( strtok(NULL, " \t"));
}
// illumination type
else if( strequal(current_token, "illum") && material_open)
{
}
// texture map
else if( strequal(current_token, "map_Ka") && material_open)
{
strncpy(current_mtl->texture_filename, strtok(NULL, " \t"), OBJ_FILENAME_LENGTH);
}
else
{
fprintf(stderr, "Unknown command '%s' in material file %s at line %i:\n\t%s\n",
current_token, filename, line_number, current_line);
//return 0;
}
}
fclose(mtl_file_stream);
return 1;
}
int obj_parse_obj_file(obj_growable_scene_data *growable_data, char *filename)
{
FILE* obj_file_stream;
int current_material = -1;
char *current_token = NULL;
char current_line[OBJ_LINE_SIZE];
int line_number = 0;
// open scene
obj_file_stream = fopen( filename, "r");
if(obj_file_stream == 0)
{
fprintf(stderr, "Error reading file: %s\n", filename);
return 0;
}
/*
extreme_dimensions[0].x = INFINITY; extreme_dimensions[0].y = INFINITY; extreme_dimensions[0].z = INFINITY;
extreme_dimensions[1].x = -INFINITY; extreme_dimensions[1].y = -INFINITY; extreme_dimensions[1].z = -INFINITY;
if(v->x < extreme_dimensions[0].x) extreme_dimensions[0].x = v->x;
if(v->x > extreme_dimensions[1].x) extreme_dimensions[1].x = v->x;
if(v->y < extreme_dimensions[0].y) extreme_dimensions[0].y = v->y;
if(v->y > extreme_dimensions[1].y) extreme_dimensions[1].y = v->y;
if(v->z < extreme_dimensions[0].z) extreme_dimensions[0].z = v->z;
if(v->z > extreme_dimensions[1].z) extreme_dimensions[1].z = v->z;*/
//parser loop
while( fgets(current_line, OBJ_LINE_SIZE, obj_file_stream) )
{
current_token = strtok( current_line, " \t\n\r");
line_number++;
//skip comments
if( current_token == NULL || current_token[0] == '#')
continue;
//parse objects
else if( strequal(current_token, "v") ) //process vertex
{
list_add_item(&growable_data->vertex_list, obj_parse_vector(), NULL);
}
else if( strequal(current_token, "vn") ) //process vertex normal
{
list_add_item(&growable_data->vertex_normal_list, obj_parse_vector(), NULL);
}
else if( strequal(current_token, "vt") ) //process vertex texture
{
list_add_item(&growable_data->vertex_texture_list, obj_parse_vector2(), NULL);
}
else if( strequal(current_token, "f") ) //process face
{
obj_face *face = obj_parse_face(growable_data);
face->material_index = current_material;
list_add_item(&growable_data->face_list, face, NULL);
}
else if( strequal(current_token, "sp") ) //process sphere
{
obj_sphere *sphr = obj_parse_sphere(growable_data);
sphr->material_index = current_material;
list_add_item(&growable_data->sphere_list, sphr, NULL);
}
else if( strequal(current_token, "pl") ) //process plane
{
obj_plane *pl = obj_parse_plane(growable_data);
pl->material_index = current_material;
list_add_item(&growable_data->plane_list, pl, NULL);
}
else if( strequal(current_token, "p") ) //process point
{
//make a small sphere to represent the point?
}
else if( strequal(current_token, "lp") ) //light point source
{
obj_light_point *o = obj_parse_light_point(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_point_list, o, NULL);
}
else if( strequal(current_token, "ld") ) //process light disc
{
obj_light_disc *o = obj_parse_light_disc(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_disc_list, o, NULL);
}
else if( strequal(current_token, "lq") ) //process light quad
{
obj_light_quad *o = obj_parse_light_quad(growable_data);
o->material_index = current_material;
list_add_item(&growable_data->light_quad_list, o, NULL);
}
else if( strequal(current_token, "c") ) //camera
{
growable_data->camera = (obj_camera*) malloc(sizeof(obj_camera));
obj_parse_camera(growable_data, growable_data->camera);
}
else if( strequal(current_token, "usemtl") ) // usemtl
{
current_material = list_find(&growable_data->material_list, strtok(NULL, WHITESPACE));
}
else if( strequal(current_token, "mtllib") ) // mtllib
{
strncpy(growable_data->material_filename, strtok(NULL, WHITESPACE), OBJ_FILENAME_LENGTH);
obj_parse_mtl_file(growable_data->material_filename, &growable_data->material_list);
continue;
}
else if( strequal(current_token, "o") ) //object name
{
obj_object* obj = obj_parse_object(growable_data);
list_add_item(&growable_data->object_list, obj, NULL);
}
else if( strequal(current_token, "s") ) //smoothing
{ }
else if( strequal(current_token, "g") ) // group
{ }
else
{
printf("Unknown command '%s' in scene code at line %i: \"%s\".\n",
current_token, line_number, current_line);
}
}
fclose(obj_file_stream);
return 1;
}
void obj_init_temp_storage(obj_growable_scene_data *growable_data)
{
list_make(&growable_data->vertex_list, 10, 1);
list_make(&growable_data->vertex_normal_list, 10, 1);
list_make(&growable_data->vertex_texture_list, 10, 1);
list_make(&growable_data->face_list, 10, 1);
list_make(&growable_data->sphere_list, 10, 1);
list_make(&growable_data->plane_list, 10, 1);
list_make(&growable_data->light_point_list, 10, 1);
list_make(&growable_data->light_quad_list, 10, 1);
list_make(&growable_data->light_disc_list, 10, 1);
list_make(&growable_data->object_list,10,1);
list_make(&growable_data->material_list, 10, 1);
growable_data->camera = NULL;
}
void obj_free_temp_storage(obj_growable_scene_data *growable_data)
{
obj_free_half_list(&growable_data->vertex_list);
obj_free_half_list(&growable_data->vertex_normal_list);
obj_free_half_list(&growable_data->vertex_texture_list);
obj_free_half_list(&growable_data->face_list);
obj_free_half_list(&growable_data->sphere_list);
obj_free_half_list(&growable_data->plane_list);
obj_free_half_list(&growable_data->light_point_list);
obj_free_half_list(&growable_data->light_quad_list);
obj_free_half_list(&growable_data->light_disc_list);
obj_free_half_list(&growable_data->object_list);
obj_free_half_list(&growable_data->material_list);
}
void delete_obj_data(obj_scene_data *data_out)
{
int i;
for(i=0; i<data_out->vertex_count; i++)
free(data_out->vertex_list[i]);
free(data_out->vertex_list);
for(i=0; i<data_out->vertex_normal_count; i++)
free(data_out->vertex_normal_list[i]);
free(data_out->vertex_normal_list);
for(i=0; i<data_out->vertex_texture_count; i++)
free(data_out->vertex_texture_list[i]);
free(data_out->vertex_texture_list);
for(i=0; i<data_out->face_count; i++)
free(data_out->face_list[i]);
free(data_out->face_list);
for(i=0; i<data_out->sphere_count; i++)
free(data_out->sphere_list[i]);
free(data_out->sphere_list);
for(i=0; i<data_out->plane_count; i++)
free(data_out->plane_list[i]);
free(data_out->plane_list);
for(i=0; i<data_out->light_point_count; i++)
free(data_out->light_point_list[i]);
free(data_out->light_point_list);
for(i=0; i<data_out->light_disc_count; i++)
free(data_out->light_disc_list[i]);
free(data_out->light_disc_list);
for(i=0; i<data_out->light_quad_count; i++)
free(data_out->light_quad_list[i]);
free(data_out->light_quad_list);
for(i=0; i<data_out->object_count; i++)
free(data_out->object_list[i]);
free(data_out->object_list);
for(i=0; i<data_out->material_count; i++)
free(data_out->material_list[i]);
free(data_out->material_list);
free(data_out->camera);
}
void obj_copy_to_out_storage(obj_scene_data *data_out, obj_growable_scene_data *growable_data)
{
data_out->vertex_count = growable_data->vertex_list.item_count;
data_out->vertex_normal_count = growable_data->vertex_normal_list.item_count;
data_out->vertex_texture_count = growable_data->vertex_texture_list.item_count;
data_out->face_count = growable_data->face_list.item_count;
data_out->sphere_count = growable_data->sphere_list.item_count;
data_out->plane_count = growable_data->plane_list.item_count;
data_out->light_point_count = growable_data->light_point_list.item_count;
data_out->light_disc_count = growable_data->light_disc_list.item_count;
data_out->light_quad_count = growable_data->light_quad_list.item_count;
data_out->material_count = growable_data->material_list.item_count;
data_out->vertex_list = (obj_vector**)growable_data->vertex_list.items;
data_out->vertex_normal_list = (obj_vector**)growable_data->vertex_normal_list.items;
data_out->vertex_texture_list = (obj_vector**)growable_data->vertex_texture_list.items;
data_out->face_list = (obj_face**)growable_data->face_list.items;
data_out->sphere_list = (obj_sphere**)growable_data->sphere_list.items;
data_out->plane_list = (obj_plane**)growable_data->plane_list.items;
data_out->light_point_list = (obj_light_point**)growable_data->light_point_list.items;
data_out->light_disc_list = (obj_light_disc**)growable_data->light_disc_list.items;
data_out->light_quad_list = (obj_light_quad**)growable_data->light_quad_list.items;
data_out->object_list = (obj_object**)growable_data->object_list.items;
data_out->object_count = growable_data->object_list.item_count;
data_out->material_list = (obj_material**)growable_data->material_list.items;
data_out->camera = growable_data->camera;
}
int parse_obj_scene(obj_scene_data *data_out, char *filename)
{
obj_growable_scene_data growable_data;
obj_init_temp_storage(&growable_data);
if( obj_parse_obj_file(&growable_data, filename) == 0)
return 0;
//print_vector(NORMAL, "Max bounds are: ", &growable_data->extreme_dimensions[1]);
//print_vector(NORMAL, "Min bounds are: ", &growable_data->extreme_dimensions[0]);
obj_copy_to_out_storage(data_out, &growable_data);
obj_free_temp_storage(&growable_data);
return 1;
}

View File

@@ -1,159 +0,0 @@
#ifndef OBJ_PARSER_H
#define OBJ_PARSER_H
#include "list.h"
#define OBJ_FILENAME_LENGTH 500
#define MATERIAL_NAME_SIZE 255
#define OBJECT_NAME_SIZE 255
#define OBJ_LINE_SIZE 500
#define MAX_VERTEX_COUNT 4 //can only handle quads or triangles
typedef struct obj_face
{
int vertex_index[MAX_VERTEX_COUNT];
int normal_index[MAX_VERTEX_COUNT];
int texture_index[MAX_VERTEX_COUNT];
int vertex_count;
int material_index;
};
typedef struct obj_sphere
{
int pos_index;
int up_normal_index;
int equator_normal_index;
int texture_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_plane
{
int pos_index;
int normal_index;
int rotation_normal_index;
int texture_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_vector
{
double e[3];
};
typedef struct obj_material
{
char name[MATERIAL_NAME_SIZE];
char texture_filename[OBJ_FILENAME_LENGTH];
double amb[3];
double diff[3];
double spec[3];
double reflect;
double refract;
double trans;
double shiny;
double glossy;
double refract_index;
};
typedef struct obj_camera
{
int camera_pos_index;
int camera_look_point_index;
int camera_up_norm_index;
};
typedef struct obj_light_point
{
int pos_index;
int material_index;
};
typedef struct obj_light_disc
{
int pos_index;
int normal_index;
int material_index;
};
typedef struct obj_light_quad
{
int vertex_index[MAX_VERTEX_COUNT];
int material_index;
};
typedef struct obj_object
{
int vertex_offset;
int face_offset;
char name[OBJECT_NAME_SIZE];
};
typedef struct obj_growable_scene_data
{
// vector extreme_dimensions[2];
char scene_filename[OBJ_FILENAME_LENGTH];
char material_filename[OBJ_FILENAME_LENGTH];
list vertex_list;
list vertex_normal_list;
list vertex_texture_list;
list face_list;
list sphere_list;
list plane_list;
list light_point_list;
list light_quad_list;
list light_disc_list;
list material_list;
list object_list;
obj_camera *camera;
};
typedef struct obj_scene_data
{
obj_vector **vertex_list;
obj_vector **vertex_normal_list;
obj_vector **vertex_texture_list;
obj_face **face_list;
obj_sphere **sphere_list;
obj_plane **plane_list;
obj_light_point **light_point_list;
obj_light_quad **light_quad_list;
obj_light_disc **light_disc_list;
obj_material **material_list;
obj_object** object_list;
int object_count;
int vertex_count;
int vertex_normal_count;
int vertex_texture_count;
int face_count;
int sphere_count;
int plane_count;
int light_point_count;
int light_quad_count;
int light_disc_count;
int material_count;
obj_camera *camera;
};
int parse_obj_scene(obj_scene_data *data_out, char *filename);
void delete_obj_data(obj_scene_data *data_out);
#endif

View File

@@ -1,24 +1,23 @@
project "wavefrontObjLoader" project "App_WavefrontObjLoader"
language "C++"
kind "ConsoleApp" kind "ConsoleApp"
-- defines { }
targetdir "../../bin" targetdir "../../bin"
includedirs { includedirs
".", {
".","../../src"
} }
links { "Bullet3Common" }
files { files {
"objTester.cpp", "**.cpp",
"string_extra.cpp", "**.h"
"string_extra.h",
"objLoader.cpp",
"objLoader.h",
"obj_parser.cpp",
"obj_parser.h",
"list.cpp",
"list.h"
} }

View File

@@ -1,16 +0,0 @@
#include "string_extra.h"
#include <string.h>
char strequal(const char *s1, const char *s2)
{
if(strcmp(s1, s2) == 0)
return 1;
return 0;
}
char contains(const char *haystack, const char *needle)
{
if(strstr(haystack, needle) == NULL)
return 0;
return 1;
}

View File

@@ -1,8 +0,0 @@
#ifndef STRING_EXTRA_H
#define STRING_EXTRA_H
char strequal(const char *s1, const char *s2);
char contains(const char *haystack, const char *needle);
#endif

View File

@@ -4,6 +4,7 @@
// Licensed under 2-clause BSD liecense. // Licensed under 2-clause BSD liecense.
// //
// Erwin Coumans: improved performance, especially in debug mode on Visual Studio (25sec -> 4sec)
// //
// version 0.9.5: Parse multiple group name. // version 0.9.5: Parse multiple group name.
// Add support of specifying the base path to load material file. // Add support of specifying the base path to load material file.
@@ -30,12 +31,15 @@
namespace tinyobj { namespace tinyobj {
struct vertex_index { struct vertex_index {
int v_idx, vt_idx, vn_idx; int v_idx, vt_idx, vn_idx, dummy;
vertex_index() {};
vertex_index(int idx) : v_idx(idx), vt_idx(idx), vn_idx(idx) {};
vertex_index(int vidx, int vtidx, int vnidx) : v_idx(vidx), vt_idx(vtidx), vn_idx(vnidx) {};
}; };
struct MyIndices
{
int m_offset;
int m_numIndices;
};
// for std::map // for std::map
static inline bool operator<(const vertex_index& a, const vertex_index& b) static inline bool operator<(const vertex_index& a, const vertex_index& b)
{ {
@@ -46,11 +50,6 @@ static inline bool operator<(const vertex_index& a, const vertex_index& b)
return false; return false;
} }
struct obj_shape {
std::vector<float> v;
std::vector<float> vn;
std::vector<float> vt;
};
static inline bool isSpace(const char c) { static inline bool isSpace(const char c) {
return (c == ' ') || (c == '\t'); return (c == ' ') || (c == '\t');
@@ -119,7 +118,10 @@ static vertex_index parseTriple(
int vnsize, int vnsize,
int vtsize) int vtsize)
{ {
vertex_index vi(-1); vertex_index vi;
vi.vn_idx = -1;
vi.vt_idx = -1;
vi.v_idx= -1;
vi.v_idx = fixIndex(atoi(token), vsize); vi.v_idx = fixIndex(atoi(token), vsize);
token += strcspn(token, "/ \t\r"); token += strcspn(token, "/ \t\r");
@@ -150,6 +152,7 @@ static vertex_index parseTriple(
return vi; return vi;
} }
static unsigned int static unsigned int
updateVertex( updateVertex(
std::map<vertex_index, unsigned int>& vertexCache, std::map<vertex_index, unsigned int>& vertexCache,
@@ -191,15 +194,18 @@ updateVertex(
return idx; return idx;
} }
static bool static bool
exportFaceGroupToShape( exportFaceGroupToShape(
shape_t& shape, shape_t& shape,
const std::vector<float> in_positions, const std::vector<float>& in_positions,
const std::vector<float> in_normals, const std::vector<float>& in_normals,
const std::vector<float> in_texcoords, const std::vector<float>& in_texcoords,
const std::vector<std::vector<vertex_index> >& faceGroup, const std::vector<MyIndices >& faceGroup,
const material_t material, const material_t material,
const std::string name) const std::string name,
std::vector<vertex_index>& allIndices
)
{ {
if (faceGroup.empty()) { if (faceGroup.empty()) {
return false; return false;
@@ -213,19 +219,27 @@ exportFaceGroupToShape(
std::vector<unsigned int> indices; std::vector<unsigned int> indices;
// Flatten vertices and indices // Flatten vertices and indices
for (size_t i = 0; i < faceGroup.size(); i++) { for (size_t i = 0; i < faceGroup.size(); i++)
const std::vector<vertex_index>& face = faceGroup[i]; {
vertex_index i0 = face[0]; const MyIndices& face = faceGroup[i];
vertex_index i1(-1);
vertex_index i2 = face[1];
size_t npolys = face.size(); vertex_index i0 = allIndices[face.m_offset];
vertex_index i1;
i1.vn_idx = -1;
i1.vt_idx = -1;
i1.v_idx= -1;
vertex_index i2 = allIndices[face.m_offset+1];
size_t npolys = face.m_numIndices;//.size();
{
// Polygon -> triangle fan conversion // Polygon -> triangle fan conversion
for (size_t k = 2; k < npolys; k++) { for (size_t k = 2; k < npolys; k++)
{
i1 = i2; i1 = i2;
i2 = face[k]; i2 = allIndices[face.m_offset+k];
unsigned int v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0); unsigned int v0 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i0);
unsigned int v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1); unsigned int v1 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i1);
@@ -235,6 +249,7 @@ exportFaceGroupToShape(
indices.push_back(v1); indices.push_back(v1);
indices.push_back(v2); indices.push_back(v2);
} }
}
} }
@@ -254,6 +269,7 @@ exportFaceGroupToShape(
} }
void InitMaterial(material_t& material) { void InitMaterial(material_t& material) {
material.name = ""; material.name = "";
material.ambient_texname = ""; material.ambient_texname = "";
@@ -454,7 +470,11 @@ LoadObj(
const char* mtl_basepath) const char* mtl_basepath)
{ {
shapes.clear(); shapes.resize(0);
std::vector<vertex_index> allIndices;
allIndices.reserve(1024*1024);
MyIndices face;
std::stringstream err; std::stringstream err;
@@ -465,9 +485,14 @@ LoadObj(
} }
std::vector<float> v; std::vector<float> v;
v.reserve(1024*1024);
std::vector<float> vn; std::vector<float> vn;
vn.reserve(1024*1024);
std::vector<float> vt; std::vector<float> vt;
std::vector<std::vector<vertex_index> > faceGroup; vt.reserve(1024*1024);
//std::vector<std::vector<vertex_index> > faceGroup;
std::vector<MyIndices> faceGroup;
faceGroup.reserve(1024*1024);
std::string name; std::string name;
// material // material
@@ -540,10 +565,13 @@ LoadObj(
token += 2; token += 2;
token += strspn(token, " \t"); token += strspn(token, " \t");
std::vector<vertex_index> face; face.m_offset = allIndices.size();
face.m_numIndices = 0;
while (!isNewLine(token[0])) { while (!isNewLine(token[0])) {
vertex_index vi = parseTriple(token, v.size() / 3, vn.size() / 3, vt.size() / 2); vertex_index vi = parseTriple(token, v.size() / 3, vn.size() / 3, vt.size() / 2);
face.push_back(vi); allIndices.push_back(vi);
face.m_numIndices++;
int n = strspn(token, " \t\r"); int n = strspn(token, " \t\r");
token += n; token += n;
} }
@@ -578,7 +606,7 @@ LoadObj(
std::string err_mtl = LoadMtl(material_map, namebuf, mtl_basepath); std::string err_mtl = LoadMtl(material_map, namebuf, mtl_basepath);
if (!err_mtl.empty()) { if (!err_mtl.empty()) {
faceGroup.clear(); // for safety faceGroup.resize(0); // for safety
return err_mtl; return err_mtl;
} }
continue; continue;
@@ -589,12 +617,12 @@ LoadObj(
// flush previous face group. // flush previous face group.
shape_t shape; shape_t shape;
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name); bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name,allIndices);
if (ret) { if (ret) {
shapes.push_back(shape); shapes.push_back(shape);
} }
faceGroup.clear(); faceGroup.resize(0);
std::vector<std::string> names; std::vector<std::string> names;
while (!isNewLine(token[0])) { while (!isNewLine(token[0])) {
@@ -620,12 +648,12 @@ LoadObj(
// flush previous face group. // flush previous face group.
shape_t shape; shape_t shape;
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name); bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name,allIndices);
if (ret) { if (ret) {
shapes.push_back(shape); shapes.push_back(shape);
} }
faceGroup.clear(); faceGroup.resize(0);
// @todo { multiple object name? } // @todo { multiple object name? }
char namebuf[4096]; char namebuf[4096];
@@ -641,11 +669,11 @@ LoadObj(
} }
shape_t shape; shape_t shape;
bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name); bool ret = exportFaceGroupToShape(shape, v, vn, vt, faceGroup, material, name,allIndices);
if (ret) { if (ret) {
shapes.push_back(shape); shapes.push_back(shape);
} }
faceGroup.clear(); // for safety faceGroup.resize(0); // for safety
return err.str(); return err.str();
} }

View File

@@ -18,8 +18,12 @@ subject to the following restrictions:
bool useShadowMap=true; bool useShadowMap=true;
float shadowMapWidth=4096;//8192, 2048 float shadowMapWidth=4096;//8192, 2048
float shadowMapHeight=4096; float shadowMapHeight=4096;
float shadowMapWorldSize=200;
float WHEEL_MULTIPLIER=3.f;
float MOUSE_MOVE_MULTIPLIER = 0.4f;
#include "OpenGLInclude.h" #include "OpenGLInclude.h"
#include "b3gWindowInterface.h"
#ifndef glDrawElementsInstanced #ifndef glDrawElementsInstanced
#define glDrawElementsInstanced glDrawElementsInstancedARB #define glDrawElementsInstanced glDrawElementsInstancedARB
@@ -124,7 +128,11 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
float m_mouseXpos; float m_mouseXpos;
float m_mouseYpos; float m_mouseYpos;
bool m_mouseInitialized; bool m_mouseInitialized;
int m_mouseButton; int m_leftMouseButton;
int m_rightMouseButton;
int m_altPressed;
int m_controlPressed;
GLuint m_defaultTexturehandle; GLuint m_defaultTexturehandle;
b3AlignedObjectArray<GLuint> m_textureHandles; b3AlignedObjectArray<GLuint> m_textureHandles;
@@ -141,9 +149,12 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
//m_ele(25.f), //m_ele(25.f),
m_ele(25.f), m_ele(25.f),
m_mouseInitialized(false), m_mouseInitialized(false),
m_mouseButton(0), m_leftMouseButton(0),
m_rightMouseButton(0),
m_shadowMap(0), m_shadowMap(0),
m_shadowTexture(0) m_shadowTexture(0),
m_altPressed(0),
m_controlPressed(0)
{ {
@@ -151,18 +162,19 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
void wheelCallback( float deltax, float deltay) void wheelCallback( float deltax, float deltay)
{ {
if (!m_mouseButton) if (!m_leftMouseButton)
{ {
if (b3Fabs(deltax)>b3Fabs(deltay))
{
m_azi -= deltax*0.1f;
if (deltay<0 || m_cameraDistance>1)
{
m_cameraDistance -= deltay*1;
if (m_cameraDistance<1)
m_cameraDistance=1;
} else } else
{ {
//m_cameraDistance -= deltay*0.1;
b3Vector3 fwd = m_cameraTargetPosition-m_cameraPosition; b3Vector3 fwd = m_cameraTargetPosition-m_cameraPosition;
fwd.normalize(); fwd.normalize();
m_cameraTargetPosition += fwd*deltay*0.1; m_cameraTargetPosition += fwd*deltay*WHEEL_MULTIPLIER;
} }
} else } else
{ {
@@ -171,11 +183,11 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
b3Vector3 fwd = m_cameraTargetPosition-m_cameraPosition; b3Vector3 fwd = m_cameraTargetPosition-m_cameraPosition;
b3Vector3 side = m_cameraUp.cross(fwd); b3Vector3 side = m_cameraUp.cross(fwd);
side.normalize(); side.normalize();
m_cameraTargetPosition += side * deltax*0.1; m_cameraTargetPosition += side * deltax*WHEEL_MULTIPLIER;
} else } else
{ {
m_cameraTargetPosition -= m_cameraUp * deltay*0.1; m_cameraTargetPosition -= m_cameraUp * deltay*WHEEL_MULTIPLIER;
} }
} }
@@ -183,18 +195,31 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
void mouseMoveCallback(float x, float y) void mouseMoveCallback(float x, float y)
{ {
if (m_mouseButton) if (m_altPressed)
{ {
float xDelta = x-m_mouseXpos; float xDelta = x-m_mouseXpos;
float yDelta = y-m_mouseYpos; float yDelta = y-m_mouseYpos;
if (m_leftMouseButton)
{
// if (b3Fabs(xDelta)>b3Fabs(yDelta)) // if (b3Fabs(xDelta)>b3Fabs(yDelta))
// { // {
m_azi += xDelta*0.1f; m_azi -= xDelta*MOUSE_MOVE_MULTIPLIER;
// } else // } else
// { // {
m_ele += yDelta*0.1f; m_ele += yDelta*MOUSE_MOVE_MULTIPLIER;
// } // }
} }
if (m_rightMouseButton)
{
m_cameraDistance -= xDelta*0.1;
m_cameraDistance -= yDelta*0.1;
if (m_cameraDistance<1)
m_cameraDistance=1;
if (m_cameraDistance>1000)
m_cameraDistance=1000;
}
}
//printf("m_azi/pitch = %f\n", m_azi); //printf("m_azi/pitch = %f\n", m_azi);
// printf("m_ele/yaw = %f\n", m_ele); // printf("m_ele/yaw = %f\n", m_ele);
@@ -206,14 +231,26 @@ struct InternalDataRenderer : public GLInstanceRendererInternalData
void mouseButtonCallback(int button, int state, float x, float y) void mouseButtonCallback(int button, int state, float x, float y)
{ {
m_mouseButton=state;
if (button==0)
m_leftMouseButton=state;
if (button==2)
m_rightMouseButton=state;
m_mouseXpos = x; m_mouseXpos = x;
m_mouseYpos = y; m_mouseYpos = y;
m_mouseInitialized = true; m_mouseInitialized = true;
} }
void keyboardCallback(unsigned char key, int x, int y) void keyboardCallback(int key, int state)
{ {
// printf("world\n"); if (key==B3G_CONTROL)
{
m_controlPressed=state;
}
if (key==B3G_ALT)
{
m_altPressed = state;
}
} }
}; };
@@ -241,6 +278,8 @@ void b3DefaultMouseMoveCallback( float x, float y)
void b3DefaultKeyboardCallback(int key, int state) void b3DefaultKeyboardCallback(int key, int state)
{ {
if (sData2)
sData2->keyboardCallback(key,state);
} }
@@ -1275,7 +1314,7 @@ void GLInstancingRenderer::renderSceneInternal(int renderMode)
} }
static b3Vector3 lightPos(-5.f,200,-40);//20,15,10);//-13,6,2);// = b3Vector3(0.5f,2,2); static b3Vector3 lightPos(-5.f,200,-40);//20,15,10);//-13,6,2);// = b3Vector3(0.5f,2,2);
// lightPos.y+=0.1f; // lightPos.y+=0.1f;
b3CreateOrtho(-100,100,-100,100,1,300,depthProjectionMatrix);//-14,14,-14,14,1,200, depthProjectionMatrix); b3CreateOrtho(-shadowMapWorldSize,shadowMapWorldSize,-shadowMapWorldSize,shadowMapWorldSize,1,300,depthProjectionMatrix);//-14,14,-14,14,1,200, depthProjectionMatrix);
float depthViewMatrix[4][4]; float depthViewMatrix[4][4];
b3Vector3 center(0,0,0); b3Vector3 center(0,0,0);
b3Vector3 up(0,1,0); b3Vector3 up(0,1,0);

View File

@@ -84,6 +84,7 @@ int getAsciiCodeFromVirtualKeycode(int virtualKeyCode)
case VK_RIGHT:{keycode= B3G_RIGHT_ARROW; break;} case VK_RIGHT:{keycode= B3G_RIGHT_ARROW; break;}
case VK_DOWN:{keycode= B3G_DOWN_ARROW; break;} case VK_DOWN:{keycode= B3G_DOWN_ARROW; break;}
case VK_SHIFT:{keycode=B3G_SHIFT;break;} case VK_SHIFT:{keycode=B3G_SHIFT;break;}
case VK_MENU:{keycode=B3G_ALT;break;}
case VK_CONTROL:{keycode=B3G_CONTROL;break;} case VK_CONTROL:{keycode=B3G_CONTROL;break;}
default: default:
{ {

View File

@@ -38,7 +38,8 @@ enum {
B3G_DELETE, B3G_DELETE,
B3G_BACKSPACE, B3G_BACKSPACE,
B3G_SHIFT, B3G_SHIFT,
B3G_CONTROL B3G_CONTROL,
B3G_ALT
}; };
struct b3gWindowConstructionInfo struct b3gWindowConstructionInfo

View File

@@ -99,7 +99,7 @@
language "C++" language "C++"
include "../Demos3/Wavefront"
if not _OPTIONS["ios"] then if not _OPTIONS["ios"] then
-- include "../demo/gpudemo" -- include "../demo/gpudemo"
@@ -110,6 +110,7 @@
include "../btgui/GwenOpenGLTest" include "../btgui/GwenOpenGLTest"
include "../test/clew" include "../test/clew"
include "../Demos3/GpuGuiInitialize" include "../Demos3/GpuGuiInitialize"
include "../test/OpenCL/BasicInitialize" include "../test/OpenCL/BasicInitialize"
-- include "../test/OpenCL/BroadphaseCollision" -- include "../test/OpenCL/BroadphaseCollision"
-- include "../test/OpenCL/NarrowphaseCollision" -- include "../test/OpenCL/NarrowphaseCollision"