aboutsummaryrefslogtreecommitdiff
path: root/src/client/lua_api/phys/bphysmodel.cpp
blob: 6307d3adf66feea1db528721435a5486dc0c23bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <memory>
#include <map>
#include <functional>
#include <list>
extern "C" {
	#include <lua.h>
	#include <lauxlib.h>
	#include <lualib.h>
}
#include <btBulletDynamicsCommon.h>
#include <irrlicht.h>
#include "../gameparts.hpp"
#include "cbphysbox.hpp"
#include "bphysmodel.hpp"
#include <client/lua_api/scene/igeneric.hpp>
#include <shared/lua_api/common.hpp>


using namespace irr;
using namespace scene;
using namespace core;
using namespace video;

extern IrrlichtDevice* device;

extern btDiscreteDynamicsWorld* World;
extern std::list<btRigidBody*> 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);
	IMeshBuffer *b = pmesh->getMeshBuffer(0);
	u32 bi = b->getVertexCount();
	btTriangleMesh* trimesh = new btTriangleMesh();
	for(u32 i = 0; i < bi; i+= 3){
		printf("Getting triangle %u of %u\n",i,bi);
		vector3df p1 = b->getPosition(i + 0);
		vector3df p2 = b->getPosition(i + 1);
		vector3df p3 = b->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);
	}
	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, IrrlichtDevice* d){

	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;
}