do some preparatory work for improved space station docking animation stuff

git-svn-id: https://pioneer.svn.sourceforge.net/svnroot/pioneer/trunk@540 e632f14b-6550-0410-b89e-a82653faca30
master
tompox 2010-01-31 16:18:37 +00:00
parent 6af3fb8dbd
commit 9c9ec2d472
7 changed files with 579 additions and 440 deletions

View File

@ -188,6 +188,16 @@ define_model('nice_spacestation', {
tags = {'orbital_station'},
angular_velocity = 0.15,
lod_pixels = { 50, 0 },
num_docking_ports = 1,
dock_anim_stage_duration = { 2.0, 3.0, 4.0 },
undock_anim_stage_duration = { 4.0, 3.0, 2.0 },
-- stage will be 1..n for dock_anim, and -1..-n for undock_anim
-- t is where we are in the stage. 0.0 .. 1.0
-- from is the ship position at the end of the previous stage (use for interpolating position)
-- must return 3 vectors for position & orientation: { position, xaxis, yaxis }
ship_dock_anim = function(stage, t, from)
return { v(0,0,0), v(1,0,0), v(0,1,0) }
end,
},
static = function(lod)
-- front
@ -253,7 +263,7 @@ define_model('nice_spacestation', {
end
end
})
--[[
define_model('hoop_spacestation', {
info = {
bounding_radius=500.0,
@ -261,6 +271,7 @@ define_model('hoop_spacestation', {
tags = {'orbital_station'},
angular_velocity = 0.08,
lod_pixels = { 50, 0 },
num_docking_ports = 1,
},
static = function(lod)
-- front
@ -326,12 +337,18 @@ define_model('hoop_spacestation', {
end
end
})
--]]
define_model('basic_groundstation', {
info = {
bounding_radius=60.0,
materials = {'body', 'text'},
tags = {'surface_station'}
tags = {'surface_station'},
num_docking_ports = 2,
dock_anim_stage_duration = {},
undock_anim_stage_duration = {},
ship_dock_anim = function(stage, t, from)
return { v(0,0,0), v(1,0,0), v(0,1,0) }
end,
},
static = function(lod)
set_material('body', .5,.5,.5,1)

View File

@ -6,441 +6,7 @@
#include "perlin.h"
#include "Render.h"
extern "C" {
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
}
#define VEC "Vec"
#define MAT4X4 "Mat4x4"
#define MODEL "Model"
// Copy of:
// LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname)
// with typeerror commented out
void *mylua_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
}
// luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
}
namespace MyLuaVec {
static vector3f *checkVec (lua_State *L, int index);
static vector3f *pushVec(lua_State *L);
}
namespace MyLuaMatrix {
static matrix4x4f *checkMat4x4 (lua_State *L, int index)
{
matrix4x4f *v;
luaL_checktype(L, index, LUA_TUSERDATA);
v = (matrix4x4f *)luaL_checkudata(L, index, MAT4X4);
if (v == NULL) luaL_typerror(L, index, MAT4X4);
return v;
}
static matrix4x4f *pushMat4x4(lua_State *L)
{
matrix4x4f *v = (matrix4x4f *)lua_newuserdata(L, sizeof(matrix4x4f));
luaL_getmetatable(L, MAT4X4);
lua_setmetatable(L, -2);
return v;
}
static int Mat4x4_new_identity(lua_State *L)
{
matrix4x4f *v = pushMat4x4(L);
*v = matrix4x4f::Identity();
return 1;
}
static int Mat4x4_inverse(lua_State *L)
{
matrix4x4f *v = checkMat4x4(L, 1);
matrix4x4f *w = pushMat4x4(L);
*w = v->InverseOf();
return 1;
}
static int Mat4x4_rotate(lua_State *L)
{
float ang = luaL_checknumber(L, 1);
vector3f v = *MyLuaVec::checkVec(L, 2);
v = v.Normalized();
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::RotateMatrix(ang, v.x, v.y, v.z);
return 1;
}
static int Mat4x4_translate(lua_State *L)
{
const vector3f *v = MyLuaVec::checkVec(L, 1);
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::Translation(v->x, v->y, v->z);
return 1;
}
static int Mat4x4_scale(lua_State *L)
{
const vector3f *v = MyLuaVec::checkVec(L, 1);
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::ScaleMatrix(v->x, v->y, v->z);
return 1;
}
static int Mat4x4_new(lua_State *L)
{
int n = lua_gettop(L);
matrix4x4f *v = pushMat4x4(L);
if (n == 0) {
*v = matrix4x4f(0.0);
} else if (n == 3) {
vector3f *v1 = MyLuaVec::checkVec(L, 1);
vector3f *v2 = MyLuaVec::checkVec(L, 2);
vector3f *v3 = MyLuaVec::checkVec(L, 3);
*v = matrix4x4f::MakeRotMatrix(*v1, *v2, *v3);
} else if (n == 4) {
vector3f *v1 = MyLuaVec::checkVec(L, 1);
vector3f *v2 = MyLuaVec::checkVec(L, 2);
vector3f *v3 = MyLuaVec::checkVec(L, 3);
vector3f *v4 = MyLuaVec::checkVec(L, 4);
*v = matrix4x4f::MakeRotMatrix(*v1, *v2, *v3);
(*v)[12] = v4->x;
(*v)[13] = v4->y;
(*v)[14] = v4->z;
} else if (n == 16) {
for (int i=0; i<16; i++) {
(*v)[i] = luaL_checknumber(L, i+1);
}
} else {
luaL_error(L, "bad arguments to mat4x4:new()");
}
return 1;
}
static int Mat4x4_print(lua_State *L)
{
matrix4x4f *v = checkMat4x4(L, 1);
printf("[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n\n",
(*v)[0], (*v)[1], (*v)[2], (*v)[3],
(*v)[4], (*v)[5], (*v)[6], (*v)[7],
(*v)[8], (*v)[9], (*v)[10], (*v)[11],
(*v)[12], (*v)[13], (*v)[14], (*v)[15]);
return 0;
}
static int Mat4x4_add (lua_State *L)
{
matrix4x4f *v1 = checkMat4x4(L, 1);
matrix4x4f *v2 = checkMat4x4(L, 2);
matrix4x4f *sum = pushMat4x4(L);
*sum = (*v1) + (*v2);
return 1;
}
static int Mat4x4_sub (lua_State *L)
{
matrix4x4f *v1 = checkMat4x4(L, 1);
matrix4x4f *v2 = checkMat4x4(L, 2);
matrix4x4f *sum = pushMat4x4(L);
*sum = (*v1) - (*v2);
return 1;
}
static int Mat4x4_mul (lua_State *L)
{
matrix4x4f *m;
vector3f *v;
float num;
if (lua_isnumber(L,1)) {
// number * mat4x4
num = lua_tonumber(L, 1);
m = checkMat4x4(L, 2);
matrix4x4f *out = pushMat4x4(L);
*out = num * (*m);
return 1;
} else if (lua_isnumber(L, 2)) {
// mat4x4 * number
m = checkMat4x4(L, 1);
num = lua_tonumber(L, 2);
matrix4x4f *out = pushMat4x4(L);
*out = num * (*m);
return 1;
} else {
m = checkMat4x4(L, 1);
luaL_checktype(L, 2, LUA_TUSERDATA);
v = (vector3f*)mylua_checkudata(L, 2, VEC);
if (v) {
// mat4x4 * vec
vector3f *out = MyLuaVec::pushVec(L);
*out = (*m) * (*v);
return 1;
} else {
// mat4x4 * mat4x4
matrix4x4f *m2 = (matrix4x4f*)luaL_checkudata(L, 2, MAT4X4);
if (!m2) luaL_typerror(L, 2, MAT4X4);
matrix4x4f *out = pushMat4x4(L);
*out = (*m) * (*m2);
return 1;
}
}
}
static const luaL_reg Mat4x4_methods[] = {
{ "new", Mat4x4_new },
{ "identity", Mat4x4_new_identity },
{ "inverse", Mat4x4_inverse },
{ "rotate", Mat4x4_rotate },
{ "scale", Mat4x4_scale },
{ "translate", Mat4x4_translate },
{ "print", Mat4x4_print },
{ 0, 0 }
};
static const luaL_reg Mat4x4_meta[] = {
// {"__gc", Foo_gc},
// {"__tostring", Foo_tostring},
{"__add", Mat4x4_add},
{"__sub", Mat4x4_sub},
{"__mul", Mat4x4_mul},
{0, 0}
};
int Mat4x4_register (lua_State *L)
{
luaL_openlib(L, MAT4X4, Mat4x4_methods, 0); /* create methods table,
add it to the globals */
luaL_newmetatable(L, MAT4X4); /* create metatable for Mat4x4,
and add it to the Lua registry */
luaL_openlib(L, 0, Mat4x4_meta, 0); /* fill metatable */
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* metatable.__index = methods */
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* hide metatable:
metatable.__metatable = methods */
lua_pop(L, 1); /* drop metatable */
return 1; /* return methods on the stack */
}
} /* namespace MyLuaMatrix */
namespace MyLuaVec {
static vector3f *checkVec (lua_State *L, int index)
{
vector3f *v;
luaL_checktype(L, index, LUA_TUSERDATA);
v = (vector3f *)luaL_checkudata(L, index, VEC);
if (v == NULL) luaL_typerror(L, index, VEC);
return v;
}
static vector3f *pushVec(lua_State *L)
{
vector3f *v = (vector3f *)lua_newuserdata(L, sizeof(vector3f));
luaL_getmetatable(L, VEC);
lua_setmetatable(L, -2);
return v;
}
static int Vec_new(lua_State *L)
{
float x = lua_tonumber(L, 1);
float y = lua_tonumber(L, 2);
float z = lua_tonumber(L, 3);
vector3f *v = pushVec(L);
v->x = x;
v->y = y;
v->z = z;
return 1;
}
static int Vec_newNormalized(lua_State *L)
{
float x = lua_tonumber(L, 1);
float y = lua_tonumber(L, 2);
float z = lua_tonumber(L, 3);
vector3f *v = pushVec(L);
v->x = x;
v->y = y;
v->z = z;
*v = v->Normalized();
return 1;
}
static int Vec_print(lua_State *L)
{
vector3f *v = checkVec(L, 1);
printf("%f,%f,%f\n", v->x, v->y, v->z);
return 0;
}
static int Vec_add (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *sum = pushVec(L);
*sum = (*v1) + (*v2);
return 1;
}
static int Vec_sub (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *sum = pushVec(L);
*sum = (*v1) - (*v2);
return 1;
}
static int Vec_cross (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *out = pushVec(L);
*out = vector3f::Cross(*v1, *v2);
return 1;
}
static int Vec_mul (lua_State *L)
{
vector3f *v;
float m;
if (lua_isnumber(L,1)) {
m = lua_tonumber(L, 1);
v = checkVec(L, 2);
} else {
v = checkVec(L, 1);
m = lua_tonumber(L, 2);
}
vector3f *out = pushVec(L);
*out = m * (*v);
return 1;
}
static int Vec_index (lua_State *L)
{
printf("Fuckme\n");
vector3f *v = checkVec(L, 1);
unsigned int i = luaL_checkint(L, 2);
if (i>i) {
luaL_error(L, "vector index must be in range 0-2");
}
lua_pushnumber(L, (*v)[i]);
return 1;
}
static int Vec_div (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
float d = lua_tonumber(L, 2);
vector3f *out = pushVec(L);
*out = (1.0/d) * (*v1);
return 1;
}
static int Vec_norm (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *out = pushVec(L);
*out = (*v1).Normalized();
return 1;
}
static int Vec_dot (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
lua_pushnumber(L, vector3f::Dot(*v1, *v2));
return 1;
}
static int Vec_len (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->Length());
return 1;
}
static int Vec_getx (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->x);
return 1;
}
static int Vec_gety (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->y);
return 1;
}
static int Vec_getz (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->z);
return 1;
}
static const luaL_reg Vec_methods[] = {
{ "new", Vec_new },
{ "newNormalized", Vec_newNormalized },
{ "print", Vec_print },
{ "dot", Vec_dot },
{ "cross", Vec_cross },
{ "norm", Vec_norm },
{ "len", Vec_len },
{ "x", Vec_getx},
{ "y", Vec_gety},
{ "z", Vec_getz},
{ 0, 0 }
};
static const luaL_reg Vec_meta[] = {
// {"__gc", Foo_gc},
// {"__tostring", Foo_tostring},
{"__add", Vec_add},
{"__sub", Vec_sub},
{"__mul", Vec_mul},
{"__div", Vec_div},
{0, 0}
};
int Vec_register (lua_State *L)
{
luaL_openlib(L, VEC, Vec_methods, 0); /* create methods table,
add it to the globals */
luaL_newmetatable(L, VEC); /* create metatable for Vec,
and add it to the Lua registry */
luaL_openlib(L, 0, Vec_meta, 0); /* fill metatable */
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* metatable.__index = methods */
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* hide metatable:
metatable.__metatable = methods */
lua_pop(L, 1); /* drop metatable */
return 1; /* return methods on the stack */
}
} /* namespace MyLuaVec */
struct RenderState {
/* For the root model this will be identity matrix.
* For sub-models called with call_model() then this will be the
@ -639,6 +205,8 @@ static std::map<std::string, LmrModel*> s_models;
static lua_State *sLua;
static int s_numTrisRendered;
lua_State *LmrGetLuaState() { return sLua; }
void LmrNotifyScreenWidth(float width)
{
s_scrWidth = width;
@ -1180,6 +748,25 @@ float LmrModel::GetFloatAttribute(const char *attr_name) const
return result;
}
int LmrModel::GetIntAttribute(const char *attr_name) const
{
char buf[256];
snprintf(buf, sizeof(buf), "%s_info", m_name.c_str());
lua_getglobal(sLua, buf);
lua_getfield(sLua, -1, attr_name);
int result = luaL_checkint(sLua, -1);
lua_pop(sLua, 2);
return result;
}
void LmrModel::PushAttributeToStack(const char *attr_name) const
{
char buf[256];
snprintf(buf, sizeof(buf), "%s_info", m_name.c_str());
lua_getglobal(sLua, buf);
lua_getfield(sLua, -1, attr_name);
}
void LmrModel::Render(const matrix4x4f &trans, const LmrObjParams *params)
{
RenderState rstate;

View File

@ -3,6 +3,8 @@
#include <map>
#include <vector>
#include <sigc++/sigc++.h>
#include "MyLuaMathTypes.h"
// LMR = Lua Model Renderer
class LmrGeomBuffer;
@ -43,6 +45,8 @@ public:
void GetCollMeshGeometry(LmrCollMesh *mesh, const matrix4x4f &transform, const LmrObjParams *params);
float GetBoundingRadius() const { return m_boundingRadius; }
float GetFloatAttribute(const char *attr_name) const;
int GetIntAttribute(const char *attr_name) const;
void PushAttributeToStack(const char *attr_name) const;
const char *GetName() const { return m_name.c_str(); }
private:
void Build(int lod, const LmrObjParams *params);
@ -70,6 +74,7 @@ int LmrModelGetStatsTris();
void LmrModelClearStatsTris();
void LmrNotifyScreenWidth(float width);
void LmrGetModelsWithTag(const char *tag, std::vector<LmrModel*> &outModels);
lua_State *LmrGetLuaState();
class LmrCollMesh
{

View File

@ -13,7 +13,7 @@ include_HEADERS = Body.h Frame.h GenericSystemView.h glfreetype.h GuiButton.h Gu
NameGenerator.h perlin.h GeoSphere.h GuiBox.h ShipFlavour.h GuiTextLayout.h Mission.h pirates.h Polit.h \
CityOnPlanet.h Shader.h ShipCpanelMultiFuncDisplays.h Projectile.h Render.h Sound.h GuiRepeaterButton.h \
CommodityTradeWidget.h GenericChatForm.h PoliceChatForm.h SysLoc.h PersistSystemData.h GalacticView.h \
Galaxy.h GameMenuView.h GuiTextEntry.h Missile.h HyperspaceCloud.h LmrModel.h
Galaxy.h GameMenuView.h GuiTextEntry.h Missile.h HyperspaceCloud.h LmrModel.h MyLuaMathTypes.h
libgui_a_SOURCES = GuiButton.cpp Gui.cpp GuiFixed.cpp GuiScreen.cpp GuiLabel.cpp GuiToolTip.cpp GuiToggleButton.cpp GuiRadioButton.cpp \
GuiRadioGroup.cpp GuiImageButton.cpp GuiImage.cpp GuiImageRadioButton.cpp GuiMultiStateImageButton.cpp GuiWidget.cpp \
@ -29,10 +29,10 @@ pioneer_SOURCES = main.cpp glfreetype.cpp Body.cpp Space.cpp Ship.cpp Player.cpp
Mission.cpp pirates.cpp Polit.cpp CityOnPlanet.cpp Shader.cpp ShipCpanelMultiFuncDisplays.cpp \
Projectile.cpp Render.cpp Sound.cpp CommodityTradeWidget.cpp GenericChatForm.cpp PoliceChatForm.cpp \
SysLoc.cpp GalacticView.cpp Galaxy.cpp GameMenuView.cpp Missile.cpp HyperspaceCloud.cpp \
LmrModel.cpp
LmrModel.cpp MyLuaMathTypes.cpp
pioneer_LDADD = collider/libcollider.a missions/libmissions.a lua/liblua.a libgui.a
modelviewer_SOURCES = LuaModelViewer.cpp glfreetype.cpp LmrModel.cpp perlin.cpp Render.cpp utils.cpp
modelviewer_SOURCES = LuaModelViewer.cpp glfreetype.cpp LmrModel.cpp perlin.cpp Render.cpp utils.cpp MyLuaMathTypes.cpp
modelviewer_LDADD = collider/libcollider.a lua/liblua.a libgui.a
check_PROGRAMS = tests

423
src/MyLuaMathTypes.cpp Normal file
View File

@ -0,0 +1,423 @@
#include "MyLuaMathTypes.h"
// Copy of:
// LUALIB_API void *luaL_checkudata (lua_State *L, int ud, const char *tname)
// with typeerror commented out
void *mylua_checkudata (lua_State *L, int ud, const char *tname) {
void *p = lua_touserdata(L, ud);
if (p != NULL) { /* value is a userdata? */
if (lua_getmetatable(L, ud)) { /* does it have a metatable? */
lua_getfield(L, LUA_REGISTRYINDEX, tname); /* get correct metatable */
if (lua_rawequal(L, -1, -2)) { /* does it have the correct mt? */
lua_pop(L, 2); /* remove both metatables */
return p;
}
}
}
// luaL_typerror(L, ud, tname); /* else error */
return NULL; /* to avoid warnings */
}
namespace MyLuaMatrix {
matrix4x4f *checkMat4x4 (lua_State *L, int index)
{
matrix4x4f *v;
luaL_checktype(L, index, LUA_TUSERDATA);
v = (matrix4x4f *)luaL_checkudata(L, index, MAT4X4);
if (v == NULL) luaL_typerror(L, index, MAT4X4);
return v;
}
matrix4x4f *pushMat4x4(lua_State *L)
{
matrix4x4f *v = (matrix4x4f *)lua_newuserdata(L, sizeof(matrix4x4f));
luaL_getmetatable(L, MAT4X4);
lua_setmetatable(L, -2);
return v;
}
int Mat4x4_new_identity(lua_State *L)
{
matrix4x4f *v = pushMat4x4(L);
*v = matrix4x4f::Identity();
return 1;
}
static int Mat4x4_inverse(lua_State *L)
{
matrix4x4f *v = checkMat4x4(L, 1);
matrix4x4f *w = pushMat4x4(L);
*w = v->InverseOf();
return 1;
}
static int Mat4x4_rotate(lua_State *L)
{
float ang = luaL_checknumber(L, 1);
vector3f v = *MyLuaVec::checkVec(L, 2);
v = v.Normalized();
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::RotateMatrix(ang, v.x, v.y, v.z);
return 1;
}
static int Mat4x4_translate(lua_State *L)
{
const vector3f *v = MyLuaVec::checkVec(L, 1);
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::Translation(v->x, v->y, v->z);
return 1;
}
static int Mat4x4_scale(lua_State *L)
{
const vector3f *v = MyLuaVec::checkVec(L, 1);
matrix4x4f *out = pushMat4x4(L);
*out = matrix4x4f::ScaleMatrix(v->x, v->y, v->z);
return 1;
}
static int Mat4x4_new(lua_State *L)
{
int n = lua_gettop(L);
matrix4x4f *v = pushMat4x4(L);
if (n == 0) {
*v = matrix4x4f(0.0);
} else if (n == 3) {
vector3f *v1 = MyLuaVec::checkVec(L, 1);
vector3f *v2 = MyLuaVec::checkVec(L, 2);
vector3f *v3 = MyLuaVec::checkVec(L, 3);
*v = matrix4x4f::MakeRotMatrix(*v1, *v2, *v3);
} else if (n == 4) {
vector3f *v1 = MyLuaVec::checkVec(L, 1);
vector3f *v2 = MyLuaVec::checkVec(L, 2);
vector3f *v3 = MyLuaVec::checkVec(L, 3);
vector3f *v4 = MyLuaVec::checkVec(L, 4);
*v = matrix4x4f::MakeRotMatrix(*v1, *v2, *v3);
(*v)[12] = v4->x;
(*v)[13] = v4->y;
(*v)[14] = v4->z;
} else if (n == 16) {
for (int i=0; i<16; i++) {
(*v)[i] = luaL_checknumber(L, i+1);
}
} else {
luaL_error(L, "bad arguments to mat4x4:new()");
}
return 1;
}
static int Mat4x4_print(lua_State *L)
{
matrix4x4f *v = checkMat4x4(L, 1);
printf("[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n[%f,%f,%f,%f]\n\n",
(*v)[0], (*v)[1], (*v)[2], (*v)[3],
(*v)[4], (*v)[5], (*v)[6], (*v)[7],
(*v)[8], (*v)[9], (*v)[10], (*v)[11],
(*v)[12], (*v)[13], (*v)[14], (*v)[15]);
return 0;
}
static int Mat4x4_add (lua_State *L)
{
matrix4x4f *v1 = checkMat4x4(L, 1);
matrix4x4f *v2 = checkMat4x4(L, 2);
matrix4x4f *sum = pushMat4x4(L);
*sum = (*v1) + (*v2);
return 1;
}
static int Mat4x4_sub (lua_State *L)
{
matrix4x4f *v1 = checkMat4x4(L, 1);
matrix4x4f *v2 = checkMat4x4(L, 2);
matrix4x4f *sum = pushMat4x4(L);
*sum = (*v1) - (*v2);
return 1;
}
static int Mat4x4_mul (lua_State *L)
{
matrix4x4f *m;
vector3f *v;
float num;
if (lua_isnumber(L,1)) {
// number * mat4x4
num = lua_tonumber(L, 1);
m = checkMat4x4(L, 2);
matrix4x4f *out = pushMat4x4(L);
*out = num * (*m);
return 1;
} else if (lua_isnumber(L, 2)) {
// mat4x4 * number
m = checkMat4x4(L, 1);
num = lua_tonumber(L, 2);
matrix4x4f *out = pushMat4x4(L);
*out = num * (*m);
return 1;
} else {
m = checkMat4x4(L, 1);
luaL_checktype(L, 2, LUA_TUSERDATA);
v = (vector3f*)mylua_checkudata(L, 2, VEC);
if (v) {
// mat4x4 * vec
vector3f *out = MyLuaVec::pushVec(L);
*out = (*m) * (*v);
return 1;
} else {
// mat4x4 * mat4x4
matrix4x4f *m2 = (matrix4x4f*)luaL_checkudata(L, 2, MAT4X4);
if (!m2) luaL_typerror(L, 2, MAT4X4);
matrix4x4f *out = pushMat4x4(L);
*out = (*m) * (*m2);
return 1;
}
}
}
static const luaL_reg Mat4x4_methods[] = {
{ "new", Mat4x4_new },
{ "identity", Mat4x4_new_identity },
{ "inverse", Mat4x4_inverse },
{ "rotate", Mat4x4_rotate },
{ "scale", Mat4x4_scale },
{ "translate", Mat4x4_translate },
{ "print", Mat4x4_print },
{ 0, 0 }
};
static const luaL_reg Mat4x4_meta[] = {
// {"__gc", Foo_gc},
// {"__tostring", Foo_tostring},
{"__add", Mat4x4_add},
{"__sub", Mat4x4_sub},
{"__mul", Mat4x4_mul},
{0, 0}
};
int Mat4x4_register (lua_State *L)
{
luaL_openlib(L, MAT4X4, Mat4x4_methods, 0); /* create methods table,
add it to the globals */
luaL_newmetatable(L, MAT4X4); /* create metatable for Mat4x4,
and add it to the Lua registry */
luaL_openlib(L, 0, Mat4x4_meta, 0); /* fill metatable */
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* metatable.__index = methods */
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* hide metatable:
metatable.__metatable = methods */
lua_pop(L, 1); /* drop metatable */
return 1; /* return methods on the stack */
}
} /* namespace MyLuaMatrix */
namespace MyLuaVec {
vector3f *checkVec (lua_State *L, int index)
{
vector3f *v;
luaL_checktype(L, index, LUA_TUSERDATA);
v = (vector3f *)luaL_checkudata(L, index, VEC);
if (v == NULL) luaL_typerror(L, index, VEC);
return v;
}
vector3f *pushVec(lua_State *L)
{
vector3f *v = (vector3f *)lua_newuserdata(L, sizeof(vector3f));
luaL_getmetatable(L, VEC);
lua_setmetatable(L, -2);
return v;
}
int Vec_new(lua_State *L)
{
float x = lua_tonumber(L, 1);
float y = lua_tonumber(L, 2);
float z = lua_tonumber(L, 3);
vector3f *v = pushVec(L);
v->x = x;
v->y = y;
v->z = z;
return 1;
}
int Vec_newNormalized(lua_State *L)
{
float x = lua_tonumber(L, 1);
float y = lua_tonumber(L, 2);
float z = lua_tonumber(L, 3);
vector3f *v = pushVec(L);
v->x = x;
v->y = y;
v->z = z;
*v = v->Normalized();
return 1;
}
static int Vec_print(lua_State *L)
{
vector3f *v = checkVec(L, 1);
printf("%f,%f,%f\n", v->x, v->y, v->z);
return 0;
}
static int Vec_add (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *sum = pushVec(L);
*sum = (*v1) + (*v2);
return 1;
}
static int Vec_sub (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *sum = pushVec(L);
*sum = (*v1) - (*v2);
return 1;
}
static int Vec_cross (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
vector3f *out = pushVec(L);
*out = vector3f::Cross(*v1, *v2);
return 1;
}
static int Vec_mul (lua_State *L)
{
vector3f *v;
float m;
if (lua_isnumber(L,1)) {
m = lua_tonumber(L, 1);
v = checkVec(L, 2);
} else {
v = checkVec(L, 1);
m = lua_tonumber(L, 2);
}
vector3f *out = pushVec(L);
*out = m * (*v);
return 1;
}
static int Vec_index (lua_State *L)
{
printf("Fuckme\n");
vector3f *v = checkVec(L, 1);
unsigned int i = luaL_checkint(L, 2);
if (i>i) {
luaL_error(L, "vector index must be in range 0-2");
}
lua_pushnumber(L, (*v)[i]);
return 1;
}
static int Vec_div (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
float d = lua_tonumber(L, 2);
vector3f *out = pushVec(L);
*out = (1.0/d) * (*v1);
return 1;
}
static int Vec_norm (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *out = pushVec(L);
*out = (*v1).Normalized();
return 1;
}
static int Vec_dot (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
vector3f *v2 = checkVec(L, 2);
lua_pushnumber(L, vector3f::Dot(*v1, *v2));
return 1;
}
static int Vec_len (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->Length());
return 1;
}
static int Vec_getx (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->x);
return 1;
}
static int Vec_gety (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->y);
return 1;
}
static int Vec_getz (lua_State *L)
{
vector3f *v1 = checkVec(L, 1);
lua_pushnumber(L, v1->z);
return 1;
}
static const luaL_reg Vec_methods[] = {
{ "new", Vec_new },
{ "newNormalized", Vec_newNormalized },
{ "print", Vec_print },
{ "dot", Vec_dot },
{ "cross", Vec_cross },
{ "norm", Vec_norm },
{ "len", Vec_len },
{ "x", Vec_getx},
{ "y", Vec_gety},
{ "z", Vec_getz},
{ 0, 0 }
};
static const luaL_reg Vec_meta[] = {
// {"__gc", Foo_gc},
// {"__tostring", Foo_tostring},
{"__add", Vec_add},
{"__sub", Vec_sub},
{"__mul", Vec_mul},
{"__div", Vec_div},
{0, 0}
};
int Vec_register (lua_State *L)
{
luaL_openlib(L, VEC, Vec_methods, 0); /* create methods table,
add it to the globals */
luaL_newmetatable(L, VEC); /* create metatable for Vec,
and add it to the Lua registry */
luaL_openlib(L, 0, Vec_meta, 0); /* fill metatable */
lua_pushliteral(L, "__index");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* metatable.__index = methods */
lua_pushliteral(L, "__metatable");
lua_pushvalue(L, -3); /* dup methods table*/
lua_rawset(L, -3); /* hide metatable:
metatable.__metatable = methods */
lua_pop(L, 1); /* drop metatable */
return 1; /* return methods on the stack */
}
} /* namespace MyLuaVec */

30
src/MyLuaMathTypes.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef _MYLUAMATHTYPES_H
#define _MYLUAMATHTYPES_H
extern "C" {
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
}
#include "vector3.h"
#include "matrix4x4.h"
#define VEC "Vec"
#define MAT4X4 "Mat4x4"
namespace MyLuaVec {
int Vec_new(lua_State *L);
int Vec_newNormalized(lua_State *L);
vector3f *checkVec (lua_State *L, int index);
vector3f *pushVec(lua_State *L);
int Vec_register (lua_State *L);
}; /* namespace MyLuaVec */
namespace MyLuaMatrix {
matrix4x4f *checkMat4x4 (lua_State *L, int index);
matrix4x4f *pushMat4x4(lua_State *L);
int Mat4x4_register (lua_State *L);
}; /* namespace MyLuaMatrix */
#endif /* _MYLUAMATHTYPES_H */

View File

@ -13,11 +13,84 @@
#include "Polit.h"
#include "LmrModel.h"
struct SpaceStationType {
LmrModel *model;
const char *modelName;
float angVel;
enum DOCKMETHOD { SURFACE, ORBITAL } dockMethod;
int numDockingPorts;
int numDockingStages;
int numUndockStages;
struct positionOrient_t {
vector3d pos;
vector3d xaxis;
vector3d yaxis;
};
float *dockAnimStageDuration;
float *undockAnimStageDuration;
void _ReadStageDurations(const char *key, int *outNumStages, float **durationArray) {
lua_State *L = LmrGetLuaState();
model->PushAttributeToStack(key);
assert(lua_istable(L, -1));
int num = lua_objlen(L, -1);
*outNumStages = num;
if (num == 0) {
*durationArray = 0;
} else {
*durationArray = new float[num];
for (int i=1; i<=num; i++) {
lua_pushinteger(L, i);
lua_gettable(L, -2);
(*durationArray)[i-1] = lua_tonumber(L, -1);
printf("%f\n", (*durationArray)[i-1]);
lua_pop(L, 1);
}
}
printf("\n");
}
// read from lua model definition
void ReadStageDurations() {
_ReadStageDurations("dock_anim_stage_duration", &numDockingStages, &dockAnimStageDuration);
_ReadStageDurations("undock_anim_stage_duration", &numUndockStages, &undockAnimStageDuration);
}
void GetDockAnimPositionOrient(int stage, float t, const vector3d &from, positionOrient_t &outPosOrient)
{
lua_State *L = LmrGetLuaState();
// It's a function of form function(stage, t, from)
model->PushAttributeToStack("ship_dock_anim");
if (!lua_isfunction(L, -1)) {
fprintf(stderr, "Error: Spacestation model %s needs ship_dock_anim method\n", model->GetName());
Pi::Quit();
}
lua_pushinteger(L, stage);
lua_pushnumber(L, (double)t);
vector3f *_from = MyLuaVec::pushVec(L);
*_from = vector3f(from);
lua_call(L, 3, 1);
assert(lua_istable(L, -1));
lua_pushinteger(L, 1);
lua_gettable(L, -2);
outPosOrient.pos = vector3f(*MyLuaVec::checkVec(L, -1));
lua_pop(L, 1);
lua_pushinteger(L, 2);
lua_gettable(L, -2);
outPosOrient.xaxis = vector3f(*MyLuaVec::checkVec(L, -1));
lua_pop(L, 1);
lua_pushinteger(L, 3);
lua_gettable(L, -2);
outPosOrient.yaxis = vector3f(*MyLuaVec::checkVec(L, -1));
lua_pop(L, 2);
}
};
static bool stationTypesInitted = false;
@ -38,7 +111,11 @@ void SpaceStation::Init()
i != models.end(); ++i) {
SpaceStationType t;
t.modelName = (*i)->GetName();
t.model = LmrLookupModelByName(t.modelName);
t.dockMethod = (SpaceStationType::DOCKMETHOD) is_orbital;
t.numDockingPorts = (*i)->GetIntAttribute("num_docking_ports");
t.ReadStageDurations();
printf("%s: %d docking ports\n", t.modelName, t.numDockingPorts);
if (is_orbital) {
t.angVel = (*i)->GetFloatAttribute("angular_velocity");
orbitalStationTypes.push_back(t);