#include #include #include #include #include #include #include extern "C" { #include #include #include } #include #include "bphysmodel.hpp" #include #include extern btDiscreteDynamicsWorld* World; extern std::list Objects; //newbphysmodel("graphicfile","physicfile",mass,[,{position}][,{lookat}]) static int newbphysmodel(lua_State* L){ printf("Creating bphysmodel\n"); int nargs = lua_gettop(L); double lx,ly,lz; double x,y,z; if(nargs > 4){ //"graphicsfile","physicsfile",{position},{lookat} popvector3d(L,&lx,&ly,&lz); } if(nargs > 3){ //"graphicsfile","physicsfile",{position} popvector3d(L,&x,&y,&z); } //"graphicsfile","physicsfile" double mass = lua_tonumber(L,-1); const char *ppath = lua_tostring(L,-2); //const char *gpath = lua_tostring(L,-3); lua_pop(L,3); //ISceneManager *smgr = device->getSceneManager(); //printf("bphysnode, creating the scene node\n"); ////Create the scene node //IMesh *gmesh = smgr->getMesh(gpath); //ISceneNode *node = smgr->addMeshSceneNode(gmesh,0,-1,vector3df(x,y,z)); printf("bphysnode, createing the physics body\n"); //Create the physics body //IMesh *pmesh = smgr->getMesh(ppath); //printf("We have %d mesh buffers\n",pmesh->getMeshBufferCount()); tinyobj_attrib_t attrib; tinyobj_shape_t *shapes = NULL; size_t meshcount; tinyobj_material_t *materials = NULL; size_t num_materials; size_t data_len = 0; FILE *objfile = fopen(ppath,"rb"); fseek(objfile,0,SEEK_END); data_len = ftell(objfile); fseek(objfile,0,SEEK_SET); char *objdata = (char*)malloc(sizeof(char)*data_len); fread(objdata, sizeof(char), data_len, objfile); fclose(objfile); int err = tinyobj_parse_obj(&attrib, &shapes, &meshcount, &materials, &num_materials, objdata, data_len, 0); if(err != TINYOBJ_SUCCESS){ printf("Tinyobj failed to load model:%s\n",ppath); } //u32 meshcount = pmesh->getMeshBufferCount(); btTriangleMesh* trimesh = new btTriangleMesh(); size_t numverts = attrib.num_face_num_verts; //size_t stride = 9; //9 = 3 position floats + 3 normal floats + 3 color floats size_t face_offset = 0; for(size_t i = 0; i < numverts; i++){ for(size_t j = 0; j < (size_t)attrib.face_num_verts[i] / 3; j++){ float v[3][3]; //this tri tinyobj_vertex_index_t idx0, idx1, idx2; idx0 = attrib.faces[face_offset + 3 * j + 0]; idx1 = attrib.faces[face_offset + 3 * j + 1]; idx2 = attrib.faces[face_offset + 3 * j + 2]; for(short k = 0; k < 3; k++){ int f0, f1, f2; f0 = idx0.v_idx; f1 = idx1.v_idx; f2 = idx2.v_idx; v[0][k] = attrib.vertices[3 * (size_t)f0 + k]; v[1][k] = attrib.vertices[3 * (size_t)f1 + k]; v[2][k] = attrib.vertices[3 * (size_t)f2 + k]; } btVector3 b1,b2,b3; b1 = btVector3(v[0][0],v[0][1],v[0][2]); b2 = btVector3(v[1][0],v[1][1],v[1][2]); b3 = btVector3(v[2][0],v[2][1],v[2][2]); trimesh->addTriangle(b1,b2,b3); } face_offset += (size_t)attrib.face_num_verts[i]; } printf("Done building trimesh\n"); btCollisionShape *shape = new btBvhTriangleMeshShape(trimesh,true); btTransform tr; tr.setIdentity(); tr.setOrigin(btVector3(x,y,z)); printf("Created default motion shape\n"); btDefaultMotionState *ms = new btDefaultMotionState(btTransform(tr)); btVector3 li; shape->calculateLocalInertia(mass, li); btRigidBody *rb = new btRigidBody(mass,ms,shape,li); //rb->setUserPointer((void*) node); World->addRigidBody(rb); Objects.push_back(rb); printf("Rigid body finished\n"); //Create the lua representation lua_newtable(L); lua_pushlightuserdata(L,rb); lua_setfield(L,-2,"rigidbody"); //lua_pushlightuserdata(L,node); //lua_setfield(L,-2,"node"); luaL_getmetatable(L,"phys.physmodel"); lua_setmetatable(L,-2); printf("finished creating the lua representation\n"); return 1; } static const luaL_reg bphysmodel_f[] = { {"newphysmodel", newbphysmodel}, {0,0}, }; static const luaL_reg bphysmodel_m[] = { {0, 0}, }; int bphysmodel_register(lua_State* L){ //device = d; //printf("bphysmodel registered\n"); luaL_newmetatable(L, "phys.physmodel");//{} luaL_register(L,NULL,bphysmodel_m); //luaL_register(L,NULL,igeneric_m); //Inherit all the things to do with scene nodes lua_getglobal(L,"phys"); luaL_register(L,NULL,bphysmodel_f); return 1; }