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:
@@ -82,6 +82,10 @@ public:
|
|||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
virtual bool keyboardCallback(int key, int state)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -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;
|
||||||
@@ -81,7 +81,7 @@ b3AlignedObjectArray<const char*> demoNames;
|
|||||||
int selectedDemo = 0;
|
int selectedDemo = 0;
|
||||||
GpuDemo::CreateFunc* allDemos[]=
|
GpuDemo::CreateFunc* allDemos[]=
|
||||||
{
|
{
|
||||||
// ConcaveCompound2Scene::MyCreateFunc,
|
//ConcaveCompound2Scene::MyCreateFunc,
|
||||||
// GpuConvexScene::MyCreateFunc,
|
// GpuConvexScene::MyCreateFunc,
|
||||||
|
|
||||||
//ConcaveSphereScene::MyCreateFunc,
|
//ConcaveSphereScene::MyCreateFunc,
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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++)
|
for (int s=0;s<shapes.size();s++)
|
||||||
{
|
{
|
||||||
vtx.xyzw[0] = obj->vertexList[v]->e[0];
|
tinyobj::shape_t& shape = shapes[s];
|
||||||
vtx.xyzw[1] = obj->vertexList[v]->e[1];
|
int faceCount = shape.mesh.indices.size();
|
||||||
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++)
|
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]);
|
|
||||||
if (face->vertex_count>=3)
|
|
||||||
{
|
{
|
||||||
b3Vector3 normal(0,1,0);
|
|
||||||
int vtxBaseIndex = vertices->size();
|
//b3Vector3 normal(face.m_plane[0],face.m_plane[1],face.m_plane[2]);
|
||||||
|
if (1)
|
||||||
if (face->vertex_count<=4)
|
|
||||||
{
|
{
|
||||||
|
b3Vector3 normal(0,1,0);
|
||||||
|
int vtxBaseIndex = vertices->size();
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -501,37 +467,33 @@ void ConcaveCompound2Scene::createDynamicObjects(const ConstructionInfo& ci)
|
|||||||
|
|
||||||
for (int f=0;f<numFaces;f++)
|
for (int f=0;f<numFaces;f++)
|
||||||
{
|
{
|
||||||
obj_face* face = objData->faceList[object->face_offset+f];
|
for (int i=0;i<3;i++)
|
||||||
if (face->vertex_count==3)
|
|
||||||
{
|
{
|
||||||
for (int i=0;i<3;i++)
|
indexArray.push_back(baseIndex+shape.mesh.indices[f*3+i]);
|
||||||
{
|
|
||||||
indexArray.push_back(face->vertex_index[i]);//-object->vertex_offset);
|
|
||||||
}
|
|
||||||
} 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)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -23,6 +23,9 @@ struct GpuRigidBodyDemoInternalData
|
|||||||
float m_pickDistance;
|
float m_pickDistance;
|
||||||
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;
|
||||||
@@ -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)
|
||||||
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|||||||
88
Demos3/Wavefront/README.md
Normal file
88
Demos3/Wavefront/README.md
Normal 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
|
||||||
|
-------
|
||||||
|
|
||||||
|

|
||||||
|
|
||||||
|
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");
|
||||||
|
}
|
||||||
@@ -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]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
107
Demos3/Wavefront/main.cpp
Normal 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;
|
||||||
|
}
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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
|
|
||||||
@@ -1,24 +1,23 @@
|
|||||||
|
|
||||||
project "wavefrontObjLoader"
|
project "App_WavefrontObjLoader"
|
||||||
|
|
||||||
language "C++"
|
|
||||||
|
|
||||||
kind "ConsoleApp"
|
|
||||||
targetdir "../../bin"
|
|
||||||
|
|
||||||
includedirs {
|
|
||||||
".",
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
files {
|
kind "ConsoleApp"
|
||||||
"objTester.cpp",
|
|
||||||
"string_extra.cpp",
|
-- defines { }
|
||||||
"string_extra.h",
|
|
||||||
"objLoader.cpp",
|
targetdir "../../bin"
|
||||||
"objLoader.h",
|
|
||||||
"obj_parser.cpp",
|
includedirs
|
||||||
"obj_parser.h",
|
{
|
||||||
"list.cpp",
|
".","../../src"
|
||||||
"list.h"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
links { "Bullet3Common" }
|
||||||
|
|
||||||
|
|
||||||
|
files {
|
||||||
|
"**.cpp",
|
||||||
|
"**.h"
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
@@ -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,28 +219,37 @@ 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];
|
||||||
|
|
||||||
// Polygon -> triangle fan conversion
|
size_t npolys = face.m_numIndices;//.size();
|
||||||
for (size_t k = 2; k < npolys; k++) {
|
|
||||||
i1 = i2;
|
|
||||||
i2 = face[k];
|
|
||||||
|
|
||||||
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 v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);
|
|
||||||
|
|
||||||
indices.push_back(v0);
|
{
|
||||||
indices.push_back(v1);
|
// Polygon -> triangle fan conversion
|
||||||
indices.push_back(v2);
|
for (size_t k = 2; k < npolys; k++)
|
||||||
}
|
{
|
||||||
|
i1 = i2;
|
||||||
|
i2 = allIndices[face.m_offset+k];
|
||||||
|
|
||||||
|
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 v2 = updateVertex(vertexCache, positions, normals, texcoords, in_positions, in_normals, in_texcoords, i2);
|
||||||
|
|
||||||
|
indices.push_back(v0);
|
||||||
|
indices.push_back(v1);
|
||||||
|
indices.push_back(v2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -253,6 +268,7 @@ exportFaceGroupToShape(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void InitMaterial(material_t& material) {
|
void InitMaterial(material_t& material) {
|
||||||
material.name = "";
|
material.name = "";
|
||||||
@@ -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,16 +565,19 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
faceGroup.push_back(face);
|
faceGroup.push_back(face);
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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,12 +669,12 @@ 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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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))
|
|
||||||
|
if (deltay<0 || m_cameraDistance>1)
|
||||||
{
|
{
|
||||||
m_azi -= deltax*0.1f;
|
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,17 +195,30 @@ 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 (b3Fabs(xDelta)>b3Fabs(yDelta))
|
|
||||||
// {
|
if (m_leftMouseButton)
|
||||||
m_azi += xDelta*0.1f;
|
{
|
||||||
// } else
|
// if (b3Fabs(xDelta)>b3Fabs(yDelta))
|
||||||
// {
|
// {
|
||||||
m_ele += yDelta*0.1f;
|
m_azi -= xDelta*MOUSE_MOVE_MULTIPLIER;
|
||||||
// }
|
// } else
|
||||||
|
// {
|
||||||
|
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);
|
||||||
@@ -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);
|
||||||
|
|||||||
@@ -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:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|||||||
Reference in New Issue
Block a user