From 112517494847f0c86f58544cbf4c35c9b7712ab1 Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Thu, 1 Nov 2018 13:53:16 -0400 Subject: Refactored code and added library Physics code for models now lives in the shared directory. To get file loading without irrlicht, a single-file header library (lib/tinyobjloader-c) was added. Metatables for generics and physics generics have also been seperated out. --- src/shared/lua_api/phys/bhingeconstraint.cpp | 50 +++++++ src/shared/lua_api/phys/bhingeconstraint.hpp | 2 + src/shared/lua_api/phys/bphysbuffer.cpp | 197 +++++++++++++++++++++++++ src/shared/lua_api/phys/bphysbuffer.hpp | 11 ++ src/shared/lua_api/phys/bphysgeneric.cpp | 212 +++++++++++++++++++++++++++ src/shared/lua_api/phys/bphysgeneric.hpp | 18 +++ src/shared/lua_api/phys/bphysmodel.cpp | 153 +++++++++++++++++++ src/shared/lua_api/phys/bphysmodel.hpp | 11 ++ 8 files changed, 654 insertions(+) create mode 100644 src/shared/lua_api/phys/bhingeconstraint.cpp create mode 100644 src/shared/lua_api/phys/bhingeconstraint.hpp create mode 100644 src/shared/lua_api/phys/bphysbuffer.cpp create mode 100644 src/shared/lua_api/phys/bphysbuffer.hpp create mode 100644 src/shared/lua_api/phys/bphysgeneric.cpp create mode 100644 src/shared/lua_api/phys/bphysgeneric.hpp create mode 100644 src/shared/lua_api/phys/bphysmodel.cpp create mode 100644 src/shared/lua_api/phys/bphysmodel.hpp (limited to 'src/shared/lua_api/phys') diff --git a/src/shared/lua_api/phys/bhingeconstraint.cpp b/src/shared/lua_api/phys/bhingeconstraint.cpp new file mode 100644 index 0000000..168d1b6 --- /dev/null +++ b/src/shared/lua_api/phys/bhingeconstraint.cpp @@ -0,0 +1,50 @@ + +#include +#include +#include +extern "C" { + #include + #include + #include +} +#include +#include +#include + +using namespace irr; +using namespace scene; +using namespace core; +using namespace video; + +extern btDiscreteDynamicsWorld* World; +extern std::list Objects; + +int newbhingeconstraint(lua_State *L){ + return 0; +} + +static const luaL_reg hingeconstraint_m[] = { +// {"delete", delbphysbox},//client side delete needs to delete the visual representation + {0, 0}, +}; + +void bhingeconstraint_register(lua_State* L){ + lua_getglobal(L,"phys");//{} + lua_pushcfunction(L,newbhingeconstraint);//{},newhingeconstraint() + lua_setfield(L,-2,"newhingeconstraint");//{} + + lua_pop(L,1);// + + luaL_newmetatable(L,"phys.hingeconstraint"); + lua_newtable(L);//phys.hingeconstraint,{} + luaL_register(L,NULL,hingeconstraint_m); + //luaL_register(L,NULL,cbphysbox_m);//phys.hingeconstraint,{} + lua_setfield(L,-2,"__index");//phys.physbox + + lua_pop(L,1); + + //printf("When registering physbox, new() is %p\n",newcbphysbox); + //printf("setpos is %p\n",cbphyssetpos); + + lua_pop(L,1); +} diff --git a/src/shared/lua_api/phys/bhingeconstraint.hpp b/src/shared/lua_api/phys/bhingeconstraint.hpp new file mode 100644 index 0000000..4e8d72c --- /dev/null +++ b/src/shared/lua_api/phys/bhingeconstraint.hpp @@ -0,0 +1,2 @@ + +void bhingeconstraint_register(lua_State* L); diff --git a/src/shared/lua_api/phys/bphysbuffer.cpp b/src/shared/lua_api/phys/bphysbuffer.cpp new file mode 100644 index 0000000..f1f20c0 --- /dev/null +++ b/src/shared/lua_api/phys/bphysbuffer.cpp @@ -0,0 +1,197 @@ + +#include +#include +#include +#include +#include +#include +extern "C" { + #include + #include + #include +} +#include +#include +#include +#include +#include "bphysmodel.hpp" +#include "../scene/igeneric.hpp" +#include + +using namespace irr; +using namespace scene; +using namespace core; +using namespace video; + +extern IrrlichtDevice* device; + +extern btDiscreteDynamicsWorld* World; +extern core::list Objects; + +static LBPhysNode* checkisbphysmodel(lua_State* L, int index){ + void* ud = luaL_checkudata(L,index,"phys.physmodel"); + luaL_argcheck(L,ud != NULL, index, "'phys.physmodel' expected"); + return (LBPhysNode*) ud; +} + +//iscenecamera.new(Vector position, Vector lookat, parrent) +// {} {} 0 1 +static int newbphysmodel(lua_State* L){ + printf("Createing bphysbox!\n"); + int nargs = lua_gettop(L); + if(nargs != 3){ + printf("Incorrect # of args to create a physmodel!"); + } + //The model for the mesh + //const char* modelpath = luaL_optstring(L,1,"error"); + + double x,y,z; + popvector3d(L,&x,&y,&z); + printf("Found position for phys model: %f %f %f\n",x,y,z); + + //Find the vector scale + double sx,sy,sz; + popvector3d(L,&sx,&sy,&sz); + printf("Found scale for phys model: %f %f %f\n",sx,sy,sz); + + //find the model path + const char* mpath = luaL_optstring(L,3,"error.obj"); + + printf("I want to use model %s\n", mpath); + + ISceneManager* smgr = device->getSceneManager(); + IMesh* amesh = smgr->getMesh(mpath); + IMeshBuffer* bf = amesh->getMeshBuffer(0); + u32 ni = bf->getIndexCount(); + + btTriangleMesh* trimesh = new btTriangleMesh(); + for(u32 i = 0; i < ni; i+=3){ + vector3df p1 = bf->getPosition(i + 0); + vector3df p2 = bf->getPosition(i + 1); + vector3df p3 = bf->getPosition(i + 2); + btVector3 b1 = btVector3(p1.X,p1.Y,p1.Z); + btVector3 b2 = btVector3(p2.X,p2.Y,p2.Z); + btVector3 b3 = btVector3(p3.X,p3.Y,p3.Z); + trimesh->addTriangle(b1,b2,b3); + } + btCollisionShape* shape = new btConvexTriangleMeshShape(trimesh,true); + core::vector3df scale = core::vector3df(sx,sy,sz); + btVector3 pos = btVector3(x,y,z); + core::vector3df ipos = core::vector3df(x,y,z); + shape->setLocalScaling(btVector3(sx,sy,sz)); + //Find the mass + float mass = luaL_optint(L,4,0); + printf("Found mass for physbox:%f\n",mass); + + + + // Create an Irrlicht cube + scene::ISceneNode* Node = smgr->addMeshSceneNode( + amesh, + (ISceneNode*)0, + (s32)-1, + ipos, + vector3df(0,0,0), + scale + ); + //Node->setScale(scale); + + printf("Added cube scene node and set it's scale\n"); + + //Node->setMaterialFlag(video::EMF_WIREFRAME,true) + //Node->setMaterialFlag(video::EMF_NORMALIZE_NORMALS, true); + Node->setMaterialFlag(video::EMF_LIGHTING,true); + //Node->setMaterialTexture(0, device->getVideoDriver()->getTexture("../data/wall.jpg")); + + printf("Set node's lighting stuff...\n"); + + // Set the initial position of the object + btTransform Transform; + Transform.setIdentity(); + Transform.setOrigin(pos); + + printf("Created transform at pos...\n"); + + // Give it a default MotionState + btDefaultMotionState *MotionState = new btDefaultMotionState(Transform); + + // Create the shape + // btVector3 HalfExtents(sx * 0.5f, sy * 0.5f, sz * 0.5f); + // btCollisionShape *Shape = new btBoxShape(HalfExtents); + + printf("Created collision shape..."); + + // Add mass + btVector3 LocalInertia; + shape->calculateLocalInertia(mass, LocalInertia); + + // Create the rigid body object + btRigidBody *RigidBody = new btRigidBody(mass, MotionState, shape, LocalInertia); + + printf("Created rigidboxy..."); + + // Store a pointer to the irrlicht node so we can update it later + RigidBody->setUserPointer((void *)(Node)); + + printf("Set user pointer"); + + // Add it to the world + World->addRigidBody(RigidBody); + printf("Added to world"); + Objects.push_back(RigidBody); + + //Register it's callback + printf("Everything created, makeing the lua representation\n"); + + //Create it's lua representation + LBPhysNode* pnode = (LBPhysNode*)lua_newuserdata(L, sizeof(LBPhysNode)); + int tref = luaL_ref(L,LUA_REGISTRYINDEX); + //iguielements[lcam] = tref; + lua_rawgeti(L,LUA_REGISTRYINDEX,tref);//Put it back on the stack since luaL_ref pops the object. + + //Set it's metatable + luaL_getmetatable(L, "phys.physmodel"); + lua_setmetatable(L, -2); + + //Create the struct + pnode->n = Node; + pnode->r = RigidBody; + pnode->funcmap = hashmap_new(); + pnode->type = "bphysbox"; + + printf("Done createing lua representation!\n"); + //Free up anything made in this function + //free(label); + + //Put it on top and return it + lua_rawgeti(L,LUA_REGISTRYINDEX,tref); + return 1; +} + + +static const luaL_reg bphysbuffer_f[] = { + //{"new", newbphysmodel}, +// {"gethandeler", guigethandeler}, +// {"sethandeler", guisethandeler}, + {0,0}, +}; + +static const luaL_reg bphysbuffer_m[] = { + //{"setmaterial", iscenesetmaterial}, + //{"getpos", bphysgetpos}, + //{"setpos", bphyssetpos}, +// {"settext", setiguitext}, +// {"remove", removeiguielement}, + {0, 0}, +}; + +void bphysbuffer_register(lua_State* L, IrrlichtDevice* d){ + + device = d; + + luaL_newmetatable(L, "phys.physbuffer");//{m_physbuffer} + lua_newtable(L);//{m_physbuffer},{} + luaL_register(L,"physbuffer",bphysbuffer_m);//{m_physbuffer},{physbuffer} + lua_setfield(L,-2,"__index");//{m_physbuffer} + lua_pop(L,1); +} diff --git a/src/shared/lua_api/phys/bphysbuffer.hpp b/src/shared/lua_api/phys/bphysbuffer.hpp new file mode 100644 index 0000000..cfbf549 --- /dev/null +++ b/src/shared/lua_api/phys/bphysbuffer.hpp @@ -0,0 +1,11 @@ + +#include +#include +extern "C" { + #include + #include + #include +} +#include + +void bphysmodel_register(lua_State* L); diff --git a/src/shared/lua_api/phys/bphysgeneric.cpp b/src/shared/lua_api/phys/bphysgeneric.cpp new file mode 100644 index 0000000..e8ef2b5 --- /dev/null +++ b/src/shared/lua_api/phys/bphysgeneric.cpp @@ -0,0 +1,212 @@ + +extern "C" { + #include + #include + #include +} +#include +#include + +/*** +@module phys +*/ + + +/*Physics things from lua have the form of: +{ + rigidbody = btRigidBody, + node = ISceneNode, +} +*/ + +/*** +Sets the direction of gravity on this object. +@function rigidbody:setgravity({x,y,z}) +@tparam vector3d direction The direction to make gravity point +*/ +//rigidbody:setgravity({x,y,z}) +int setgravity(lua_State *L){ + double x,y,z; + popvector3d(L,&x,&y,&z); + + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + btVector3 v = btVector3(x,y,z); + + r->setGravity(v); + + return 0; +} + +/*** +Gets the direction of gravity on this object. +@function rigidbody:getgravity() +@treturn vector3d The direction of gravity on this object. +*/ +//rigidbody:getgravity() +int getgravity(lua_State *L){ + lua_getfield(L,-1,"rigidbody");//{rigidbody},ud_rigidbody + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2);// + + btVector3 v = r->getGravity(); + pushvector3d(L,v.x(),v.y(),v.z()); + + return 0; +} + +/*** +Apply force at a reletive offset. +@function rigidbody:applyforce(direction, offset = {0,0,0}) +@tparam vector3d direction The direction of the force to apply +@tparam vector3d offset The offset from the center of gravity to apply the force +*/ +//rigidbody:applyforce({x,y,z}[,{rx,ry,rz}]) +int applyforce(lua_State *L){ + double rx,ry,rz; + rx = 0; + ry = 0; + rz = 0; + if(lua_gettop(L) > 2){ + popvector3d(L,&rx,&ry,&rz);//{phys},{x,y,z} + } + + double x,y,z; + popvector3d(L,&x,&y,&z);//{phys} + + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + btVector3 v = btVector3(x,y,z); + btVector3 o = btVector3(rx,ry,rz); + + r->applyForce(v,o); + + return 0; +} + +/*** +Gets the damping applied to this rigidbody +@function rigidbody:getldamping() +@treturn number damping The ammount of damping applied to the object's momentum +*/ +//rigidbody:getldamping() +int getlineardamping(lua_State *L){ + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + double damp = r->getLinearDamping(); + lua_pushnumber(L,damp); + + return 1; +} + +/*** +Gets the angular damping applied to this rigidbody +@function rigidbody:getadamping() +@treturn number damping The ammount of damping applied to angular momentum +*/ +//rigidbody:getadamping() +int getangulardamping(lua_State *L){ + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + double damp = r->getAngularDamping(); + lua_pushnumber(L,damp); + + return 1; +} + +/*** +Gets the velocity of this object +@function rigidbody:getvelocity() +@treturn vector3 The velocity in each direction +*/ +//rigidbody:getvelocity() +int getvelocity(lua_State *L){ + btVector3 vel; + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + + vel = r->getLinearVelocity(); + pushvector3d(L,(double)vel.x(),(double)vel.y(),(double)vel.z()); + + return 1; +} + +/*** +Sets the velocity of this object +@function rigidbody:setvelocity() +@tparam vector3d direction The ammount on each axis to set the velocity of this object. +*/ +//rigidbody:setvelocity({x,y,z}) +int setvelocity(lua_State *L){ + double x,y,z; + popvector3d(L,&x,&y,&z); + btVector3 newvel = btVector3(x,y,z); + + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + r->setLinearVelocity(newvel); + + return 0; +} + +/*** +Activates this object. +If this object was sleeping, it will move again. If you are using +applyforce or setvelocity, you will need to activate() the rigidbody for it +to move. +@function rigidbody:activate() +*/ +//rigidbody:activate() +int activate(lua_State *L){ + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + r->activate(); + + return 0; +} + +/*** +Sets the damping of this object. +@function rigidbody:setdamping(damping,angular_damping) +@tparam number damping The ammount of damping the object should put on it's movement. +@tparam number angular_damping The ammount of damping the object should put on it's angular momentum +*/ +//rigidbody:setdamping(lineardamping, angulardamping) +int setdamping(lua_State *L){ + double adamp,ldamp; + adamp = lua_tonumber(L,-1); + ldamp = lua_tonumber(L,-2); + lua_pop(L,2); + + lua_getfield(L,-1,"rigidbody"); + btRigidBody *r = (btRigidBody*)lua_touserdata(L,-1); + lua_pop(L,2); + + r->setDamping(adamp,ldamp); + + return 0; +} + +extern const luaL_reg brigidbody_m[] = { + {"setgravity", setgravity}, + {"applyforce", applyforce}, + {"getldamping", getlineardamping}, + {"getadamping", getangulardamping}, + {"setdamping", setdamping}, + {"activate", activate}, + {"getvelocity", getvelocity}, + {"setvelocity", setvelocity}, + {NULL, NULL} +}; diff --git a/src/shared/lua_api/phys/bphysgeneric.hpp b/src/shared/lua_api/phys/bphysgeneric.hpp new file mode 100644 index 0000000..6d3ef70 --- /dev/null +++ b/src/shared/lua_api/phys/bphysgeneric.hpp @@ -0,0 +1,18 @@ + +extern "C" { + #include + #include + #include +} + + +int setgravity(lua_State *L); +int applyforce(lua_State *L); +int getlineardamping(lua_State *L); +int getangulardamping(lua_State *L); +int setdamping(lua_State *L); +int activate(lua_State *L); +int getvelocity(lua_State *L); +int setvelocity(lua_State *L); + +extern const luaL_reg brigidbody_m[]; diff --git a/src/shared/lua_api/phys/bphysmodel.cpp b/src/shared/lua_api/phys/bphysmodel.cpp new file mode 100644 index 0000000..e9fecbf --- /dev/null +++ b/src/shared/lua_api/phys/bphysmodel.cpp @@ -0,0 +1,153 @@ + +#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; +} diff --git a/src/shared/lua_api/phys/bphysmodel.hpp b/src/shared/lua_api/phys/bphysmodel.hpp new file mode 100644 index 0000000..50645cc --- /dev/null +++ b/src/shared/lua_api/phys/bphysmodel.hpp @@ -0,0 +1,11 @@ +#ifndef _BPHYSMODEL_HPP_ +#include +#include +extern "C" { + #include + #include + #include +} + +int bphysmodel_register(lua_State* L); +#endif -- cgit v1.2.3-70-g09d2