#include #include #include #include #include #include #include extern "C" { #include #include #include } #include #include #include #include "bphysmodel.hpp" #include #include #include #include extern btDiscreteDynamicsWorld* World; extern std::list Objects; //btRigidBody* load_obj(tinyobj_attrib_t attrib, tinyobj_shape_t *shapes, size_t num){ //btTriangleMesh *trimesh = new btTriangleMesh(); //} static void get_file_data(void* ctx, const char* filename, int is_mtl, const char *obj_filename, char **data, size_t *len){ FILE *objfile = fopen(filename,"rb"); fseek(objfile,0,SEEK_END); *len = (size_t)ftell(objfile); //printf("model data is %d long\n",(int)data_len); fseek(objfile,0,SEEK_SET); *data = (char*)malloc(sizeof(char) * *len); fread(*data , sizeof(char), *len, objfile); fclose(objfile); } //TODO: This will break in the future, see github.com/syoyo/tinyobjloader-c/issues/16 //"physicfile",mass[,position][,lookat] :: ud_rigidbody void makebphysmodel(lua_State *L){ //printf("making bphysmodel\n"); int nargs = lua_gettop(L); double lx,ly,lz; double x,y,z; if(nargs > 3){ //"physicsfile",{position},{lookat} popvector3d(L,&lx,&ly,&lz); } if(nargs > 2){ //"physicsfile",{position} popvector3d(L,&x,&y,&z); } //printf("got arguments for bphysmodel\n"); //"physicsfile" double mass = lua_tonumber(L,-1); const char *ppath = lua_tostring(L,-2); lua_pop(L,2); 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); //printf("model data is %d long\n",(int)data_len); fseek(objfile,0,SEEK_SET); char *objdata = (char*)malloc(sizeof(char)*data_len); fread(objdata, sizeof(char), data_len, objfile); fclose(objfile); //printf("About to tinyobj_parse_obj\n"); int err = tinyobj_parse_obj( &attrib, &shapes, &meshcount, &materials, &num_materials, ppath, get_file_data, (void*)NULL, TINYOBJ_FLAG_TRIANGULATE ); //printf("Finished parsing tinyobj\n"); if(err != TINYOBJ_SUCCESS){ printf("Tinyobj failed to load model:%s\n",ppath); } //for(size_t s = 0; s < meshcount; s++){ //btRigidBody *rb = load_obj(attrib,shapes,s); //} //u32 meshcount = pmesh->getMeshBufferCount(); //__mingw_printf("attrib.num_vertices: %u\n",attrib.num_vertices); //__mingw_printf("attrib.num_faces: %u\n",attrib.num_faces); btTriangleMesh* trimesh = new btTriangleMesh(); btVector3 vertexes[attrib.num_vertices]; for(size_t i = 0; i < attrib.num_vertices; i++){ //0 - x, so num_vertices - 1 float *vs = attrib.vertices + (3*i);//3 floats per vertex //For some reason irrlicht and bullet disagree with which direction +x is, //negate the x in the physics engine so the graphical stuff lines up //with the physics stuff float v1 = -vs[0]; float v2 = vs[1]; float v3 = vs[2]; vertexes[i] = btVector3(v1,v2,v3); //printf("Adding vertex %lld at (%f,%f,%f)\n",i,v1,v2,v3); } //printf("Finished finding or adding vertexes\n"); for(size_t i = 0; i < attrib.num_faces - 1; i+= 3){ //0 - y to num_faces - 1 tinyobj_vertex_index_t i1,i2,i3; i1 = attrib.faces[i]; i2 = attrib.faces[i+1]; i3 = attrib.faces[i+2]; btVector3 v1,v2,v3; v1 = vertexes[i1.v_idx]; v2 = vertexes[i2.v_idx]; v3 = vertexes[i3.v_idx]; trimesh->addTriangle(vertexes[i1.v_idx],vertexes[i2.v_idx],vertexes[i3.v_idx],false);//Some triangles are "the wrong way round", //printf("Adding triangle:(%d,%d,%d)\n",i1.v_idx,i2.v_idx,i3.v_idx); trimesh->addTriangle(vertexes[i3.v_idx],vertexes[i2.v_idx],vertexes[i1.v_idx],true);//double-side all triangles } //printf("Finished adding triangle indicies\n"); //printf("Done building trimesh\n"); //btConvexTriangleMeshShape *shape = new btConvexTriangleMeshShape(trimesh); btGImpactShapeInterface *shape = new btGImpactMeshShape(trimesh); shape->updateBound(); //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(tr); btVector3 li; shape->calculateLocalInertia(mass, li); btRigidBody *rb = new btRigidBody(mass,ms,shape,li); World->addRigidBody(rb); Objects.push_back(rb); //printf("Rigid body finished\n"); lua_pushlightuserdata(L,rb);//ud_rigidbody } //newbphysmodel("graphicfile","physicfile",mass[,position][,lookat]) :: ud_rigidbody 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); }else{ lx = 1; ly = 1; lz = 1; } if(nargs > 3){ //"graphicsfile","physicsfile",{position} popvector3d(L,&x,&y,&z); }else{ x = 0; y = 0; z = 0; } //"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);// lua_pushstring(L,ppath);//"phys_path" lua_pushnumber(L,mass);//"phys_path",double_mass pushvector3d(L,x,y,z);//"phys_path",double_mass,{position} pushvector3d(L,lx,ly,lz);//"phys_path",double_mass,{position},{lookat} //printf("Starting makeing bphysmodel\n"); makebphysmodel(L);//ud_rigidbody //printf("Done making bphysmodel\n"); btRigidBody *rb = (btRigidBody*)lua_touserdata(L,-1); //printf("bphysnode, createing the physics body\n"); //Create the lua representation lua_newtable(L);//{} lua_pushlightuserdata(L,rb);//{},ud_rigidbody lua_setfield(L,-2,"collider");//{collider=ud_rigidbody} lua_pushstring(L,"rigidbody");//{collider=ud_rigidbody},"rigidbody" lua_setfield(L,-2,"type");//{rb} //printf("Added collider to lua rep.\n"); //Add it to the global list of colliders lua_getglobal(L,"phys");//{rb},{phys} lua_getfield(L,-1,"colliders");//{rb},{phys},{phys.colliders} lua_pushlightuserdata(L,rb);//{rb},{phys},{phys.colliders},ud_collider lua_pushvalue(L,-4);//{rb},{phys},{phys.colliders},ud_collider,{rb} lua_settable(L,-3);//{rb},{phys},{phys.colliders} lua_pop(L,2);//{rb} //printf("Added collider to phys.colliders\n"); //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");//{m_physmodel} lua_newtable(L);//{m_physmodel},{} luaL_register(L,NULL,bcollider_m); luaL_register(L,NULL,bphysmodel_m); luaL_register(L,NULL,brigidbody_m); lua_setfield(L,-2,"__index");//{m_physmodel} lua_pop(L,1);// //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); lua_pop(L,1); return 0; }