aboutsummaryrefslogtreecommitdiff
path: root/src/client/lua_api/phys/cbphysmodel.cpp
blob: 51ff2d8c6a933a2868fcabc6fb1fe548b67e0687 (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
130
131
132
133
134
135
#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 "cbphysmodel.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);
	printf("We have %d mesh buffers\n",pmesh->getMeshBufferCount());
	u32 meshcount = pmesh->getMeshBufferCount();
	btTriangleMesh* trimesh = new btTriangleMesh();
	for(u32 meshnum = 0; meshnum < meshcount; meshnum++){
		IMeshBuffer *b = pmesh->getMeshBuffer(meshnum);
		//assert(b->getVertexType() == video::EVT_STANDARD);
		u32 bi = b->getIndexCount();
		u16 *indices = b->getIndices();
		for(u32 i = 0; i < bi; i+= 3){
			printf("Getting triangle %u of %u\n",i,bi);
			u16 i1 = indices[i];
			u16 i2 = indices[i + 1];
			u16 i3 = indices[i + 2];
			vector3df p1 = b->getPosition(i1);
			vector3df p2 = b->getPosition(i2);
			vector3df p3 = b->getPosition(i3);
			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 cbphysmodel_register(lua_State* L){
	//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;
}