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
- 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 FP_EQ(a,b) (fabsf(a - b) < 0.0001)
/* Global data */
Engine * g_engine;
@ -54,6 +56,13 @@ static string trim(const string & orig)
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::Engine(const string & path, Video & video)
@ -725,7 +734,7 @@ void Engine::Object::createManagedObject()
m_ode_object->addSphere(m_args);
break;
case OdeWorld::PLANE:
while (m_args->size() < 6)
while (m_args->size() < 4 || m_args->size() == 5)
m_args->push_back(0);
m_ode_object->addPlane(m_args);
break;
@ -745,29 +754,9 @@ void Engine::Object::createManagedObject()
}
/* render a managed object */
/* prerequisite: m_args->size() is big enough */
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)
m_display_list = glGenLists(1);
glNewList(m_display_list, GL_COMPILE);
@ -813,30 +802,70 @@ void Engine::Object::render()
gluSphere(quad, (*m_args)[0], 16, 8);
break;
case OdeWorld::PLANE: {
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};
dVector3 rotated_plane_direction;
dVector3 normal;
dVector3 rotated_x;
dVector3 rotated_y;
dMultiply0(rotated_plane_direction, 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);
float x_o, y_o, z_o;
if (m_args->size() == 6)
{
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) */
const int num_sections = 10;
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
glNormal3fv(rotated_plane_direction);
glNormal3fv(normal);
#else
glNormal3dv(rotated_plane_direction);
glNormal3dv(normal);
#endif
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)
{
int argc = lua_gettop(L);
if (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))
if (argc == 4 || argc == 6)
{
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);
bool valid = true;
for (int i = 0; i < argc; i++)
{
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;
}