#include #include #include #include #include #include #include extern "C" { #include #include #include } #include #include "bphysmodel.hpp" #include #include #include #include extern btDiscreteDynamicsWorld* World; extern std::list Objects; //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, objdata, data_len, TINYOBJ_FLAG_TRIANGULATE); printf("Finished parsing tinyobj\n"); if(err != TINYOBJ_SUCCESS){ printf("Tinyobj failed to load model:%s\n",ppath); } //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(); for(size_t i = 0; i < attrib.num_vertices; i++){ //0 - x, so num_vertices - 1 //__mingw_printf("Looking at vertice %llu/%u\n",i,attrib.num_vertices); //DO NOT MULTIPLY THIS BY SIEZEOF(FLOAT) float *vs = attrib.vertices + (3*i);//3 floats per vertex //printf("Got start\n"); float v1 = vs[0]; //printf("Got 1\n"); float v2 = vs[1]; //printf("Got 2\n"); float v3 = vs[2]; //printf("Got all 3 vertexees\n"); //printf("Adding vertex: (%f %f %f)\n",v1, v2, v3); trimesh->findOrAddVertex(btVector3(v1,v2,v3),true); } 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]; trimesh->addTriangleIndices(i1.v_idx,i2.v_idx,i3.v_idx); } printf("Finished adding triangle indicies\n"); //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); 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; }