changed plane construction to accept 4 parameters to specify (a,b,c,d) directly (in addition to 6 parameter mode)

git-svn-id: svn://anubis/anaglym/trunk@147 99a6e188-d820-4881-8870-2d33a10e2619
This commit is contained in:
Josh Holtrop 2009-11-02 18:59:40 +00:00
parent 2081cf7277
commit 2ccff9db76
3 changed files with 85 additions and 51 deletions

1
.todo
View File

@ -1,3 +1,2 @@
- add plane constructor taking 4 parameters for (a,b,c,d)
- support loading and applying textures for managed objects - support loading and applying textures for managed objects
- debug hooks for loading and execution to halt infinite lua loops - debug hooks for loading and execution to halt infinite lua loops

103
Engine.cc
View File

@ -31,6 +31,8 @@ using namespace std;
#define WHITESPACE " \t\r\n\f" #define WHITESPACE " \t\r\n\f"
#define FP_EQ(a,b) (fabsf(a - b) < 0.0001)
/* Global data */ /* Global data */
Engine * g_engine; Engine * g_engine;
@ -54,6 +56,13 @@ static string trim(const string & orig)
return result; return result;
} }
static void cross_product(dVector3 result, dVector3 first, dVector3 second)
{
result[0] = first[1] * second[2] - first[2] * second[1];
result[1] = first[2] * second[0] - first[0] * second[2];
result[2] = first[0] * second[1] - first[1] * second[0];
}
/******** Engine functions ********/ /******** Engine functions ********/
Engine::Engine(const string & path, Video & video) Engine::Engine(const string & path, Video & video)
@ -725,7 +734,7 @@ void Engine::Object::createManagedObject()
m_ode_object->addSphere(m_args); m_ode_object->addSphere(m_args);
break; break;
case OdeWorld::PLANE: case OdeWorld::PLANE:
while (m_args->size() < 6) while (m_args->size() < 4 || m_args->size() == 5)
m_args->push_back(0); m_args->push_back(0);
m_ode_object->addPlane(m_args); m_ode_object->addPlane(m_args);
break; break;
@ -745,29 +754,9 @@ void Engine::Object::createManagedObject()
} }
/* render a managed object */ /* render a managed object */
/* prerequisite: m_args->size() is big enough */
void Engine::Object::render() void Engine::Object::render()
{ {
bool valid = false;
switch (m_geom_type)
{
case OdeWorld::BOX:
if (m_args->size() >= 3) valid = true;
break;
case OdeWorld::SPHERE:
if (m_args->size() >= 1) valid = true;
break;
case OdeWorld::PLANE:
if (m_args->size() >= 6) valid = true;
break;
case OdeWorld::CYLINDER:
if (m_args->size() >= 2) valid = true;
break;
case OdeWorld::CCYLINDER:
if (m_args->size() >= 2) valid = true;
break;
}
if (!valid)
return;
if (m_display_list <= 0) if (m_display_list <= 0)
m_display_list = glGenLists(1); m_display_list = glGenLists(1);
glNewList(m_display_list, GL_COMPILE); glNewList(m_display_list, GL_COMPILE);
@ -813,30 +802,70 @@ void Engine::Object::render()
gluSphere(quad, (*m_args)[0], 16, 8); gluSphere(quad, (*m_args)[0], 16, 8);
break; break;
case OdeWorld::PLANE: { case OdeWorld::PLANE: {
dMatrix3 r; dVector3 normal;
dRFromEulerAngles(r, (*m_args)[3], (*m_args)[4], (*m_args)[5]);
dVector3 default_plane_direction = {0, 0, 1, 0};
dVector3 default_x = {1, 0, 0, 0};
dVector3 default_y = {0, 1, 0, 0};
dVector3 rotated_plane_direction;
dVector3 rotated_x; dVector3 rotated_x;
dVector3 rotated_y; dVector3 rotated_y;
dMultiply0(rotated_plane_direction, default_plane_direction, float x_o, y_o, z_o;
r, 1, 3, 3); if (m_args->size() == 6)
dMultiply0(rotated_x, default_x, r, 1, 3, 3); {
dMultiply0(rotated_y, default_y, r, 1, 3, 3); dMatrix3 r;
dRFromEulerAngles(r, (*m_args)[3], (*m_args)[4], (*m_args)[5]);
dVector3 default_plane_direction = {0, 0, 1, 0};
dVector3 default_x = {1, 0, 0, 0};
dVector3 default_y = {0, 1, 0, 0};
dMultiply0(normal, default_plane_direction,
r, 1, 3, 3);
dMultiply0(rotated_x, default_x, r, 1, 3, 3);
dMultiply0(rotated_y, default_y, r, 1, 3, 3);
x_o = (*m_args)[0];
y_o = (*m_args)[1];
z_o = (*m_args)[2];
}
else
{
normal[0] = (*m_args)[0];
normal[1] = (*m_args)[1];
normal[2] = (*m_args)[2];
float d = (*m_args)[3];
float len = normal[0] * normal[0]
+ normal[1] * normal[1]
+ normal[2] * normal[2];
if (! FP_EQ(len, 1.0)) /* normalize if necessary */
{
len = sqrtf(len);
normal[0] /= len;
normal[1] /= len;
normal[2] /= len;
d /= len;
}
int min_component = 0;
float comp = 10000.0f;
for (int i = 0; i < 3; i++)
{
if (normal[i] < comp)
{
min_component = i;
comp = normal[i];
}
}
dVector3 cross_vec;
for (int i = 0; i < 3; i++)
cross_vec[i] = (i == min_component) ? 1 : 0;
cross_product(rotated_x, normal, cross_vec);
cross_product(rotated_y, normal, rotated_x);
x_o = normal[0] * d;
y_o = normal[1] * d;
z_o = normal[2] * d;
}
/* plane equation: ax + by + cz = d, plane normal: (a, b, c) */ /* plane equation: ax + by + cz = d, plane normal: (a, b, c) */
const int num_sections = 10; const int num_sections = 10;
const float section_size = 100.0f; const float section_size = 100.0f;
float x_o = (*m_args)[0];
float y_o = (*m_args)[1];
float z_o = (*m_args)[2];
#ifdef dSINGLE #ifdef dSINGLE
glNormal3fv(rotated_plane_direction); glNormal3fv(normal);
#else #else
glNormal3dv(rotated_plane_direction); glNormal3dv(normal);
#endif #endif
for (int x = 0; x < num_sections; x++) for (int x = 0; x < num_sections; x++)
{ {

32
ag.cc
View File

@ -378,21 +378,27 @@ namespace ag
static int createPlaneSpecify(lua_State * L, bool is_static) static int createPlaneSpecify(lua_State * L, bool is_static)
{ {
int argc = lua_gettop(L); int argc = lua_gettop(L);
if (argc == 6 && if (argc == 4 || argc == 6)
lua_isnumber(L, 1) &&
lua_isnumber(L, 2) &&
lua_isnumber(L, 3) &&
lua_isnumber(L, 4) &&
lua_isnumber(L, 5) &&
lua_isnumber(L, 6))
{ {
refptr< vector<float> > args = new vector<float>(); bool valid = true;
for (int i = 1; i <= 6; i++) for (int i = 0; i < argc; i++)
args->push_back(lua_tonumber(L, i)); {
addManagedObject(L, is_static, OdeWorld::PLANE, args); if (!lua_isnumber(L, i))
{
valid = false;
break;
}
}
if (valid)
{
refptr< vector<float> > args = new vector<float>();
for (int i = 1; i <= 6; i++)
args->push_back(lua_tonumber(L, i));
addManagedObject(L, is_static, OdeWorld::PLANE, args);
return 1;
}
} }
else lua_pushnil(L);
lua_pushnil(L);
return 1; return 1;
} }