bluecore/engine/ScriptSystem_RigidBody.cpp

543 wiersze
11 KiB
C++

#include "RigidBodySimulation.h"
#include "ScriptSystem_Math.h"
namespace BlueCore
{
//------------------------------------------------------------------------------
static weak_ptr<RigidBodySimulation> gRigidBodySimulation;
//------------------------------------------------------------------------------
static SQInteger _rigidbody_getposition(HSQUIRRELVM v)
{
RigidBody *body = 0;
Vector3 position;
if (sq_gettop(v) == 1)
{
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
}
if (body)
{
position = body->getPosition();
_pushvector(v, position.x, position.y, position.z);
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_getrotation(HSQUIRRELVM v)
{
RigidBody *body = 0;
Quaternion q;
if (sq_gettop(v) == 1)
{
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
}
if (body)
{
q = body->getOrientation();
_pushquaternion(v, q.w, q.x, q.y, q.z);
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_getangularvelocity(HSQUIRRELVM v)
{
RigidBody *body = 0;
Vector3 velocity;
if (sq_gettop(v) == 1)
{
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
}
if (body)
{
velocity = body->getAngularVelocity();
_pushvector(v, velocity.x, velocity.y, velocity.z);
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_getlinearvelocity(HSQUIRRELVM v)
{
RigidBody *body = 0;
Vector3 velocity;
if (sq_gettop(v) == 1)
{
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
}
if (body)
{
velocity = body->getLinearVelocity();
_pushvector(v, velocity.x, velocity.y, velocity.z);
return 1;
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_setposition(HSQUIRRELVM v)
{
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
Vector3 position;
int argc = sq_gettop(v);
if (argc == 2)
{
_getvectorvalues(v, 2, position.x, position.y, position.z);
}
else if (argc == 4)
{
sq_getfloat(v, 2, &position.x);
sq_getfloat(v, 3, &position.y);
sq_getfloat(v, 4, &position.z);
}
body->setPosition(position);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_setlinearvelocity(HSQUIRRELVM v)
{
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
Vector3 velocity;
int argc = sq_gettop(v);
if (argc == 2)
{
_getvectorvalues(v, 2, velocity.x, velocity.y, velocity.z);
}
else if (argc == 4)
{
sq_getfloat(v, 2, &velocity.x);
sq_getfloat(v, 3, &velocity.y);
sq_getfloat(v, 4, &velocity.z);
}
body->setLinearVelocity(velocity);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_setrotation(HSQUIRRELVM v)
{
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
Quaternion q;
int argc = sq_gettop(v);
if (argc == 2)
{
_getquaternionvalues(v, 2, q.w, q.x, q.y, q.z);
}
else if (argc == 5)
{
sq_getfloat(v, 2, &q.w);
sq_getfloat(v, 3, &q.x);
sq_getfloat(v, 4, &q.y);
sq_getfloat(v, 5, &q.z);
}
body->setOrientation(q);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_applylocalforce(HSQUIRRELVM v)
{
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
int argc = sq_gettop(v);
if (argc == 2)
{
Vector3 force;
_getvectorvalues(v, 2, force.x, force.y, force.z);
body->applyLocalForce(force);
}
else if (argc == 3)
{
Vector3 force, point;
_getvectorvalues(v, 2, force.x, force.y, force.z);
_getvectorvalues(v, 3, point.x, point.y, point.z);
body->applyLocalForce(force, point);
}
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_applyglobalforce(HSQUIRRELVM v)
{
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
int argc = sq_gettop(v);
if (argc == 2)
{
Vector3 force;
_getvectorvalues(v, 2, force.x, force.y, force.z);
body->applyGlobalForce(force);
}
else if (argc == 3)
{
Vector3 force, point;
_getvectorvalues(v, 2, force.x, force.y, force.z);
_getvectorvalues(v, 3, point.x, point.y, point.z);
body->applyGlobalForce(force, point);
}
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_addcollisionmesh(HSQUIRRELVM v)
{
SQInteger argc = sq_gettop(v);
if (argc < 3)
{
sq_pushinteger(v, 0);
return 1;
}
RigidBody *body = 0;
const SQChar *meshname = 0;
SQFloat density = 1.0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
sq_getstring(v, 2, &meshname);
sq_getfloat(v, 3, &density);
if (body)
{
sq_pushinteger(v, body->addCollisionMesh(meshname, density) );
}
else
sq_pushinteger(v, 0);
return 1;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_setcollisionmeshposition(HSQUIRRELVM v)
{
int argc = sq_gettop(v);
// need at least geom + vector
if (argc < 3)
return 0;
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
SQInteger geom = 0;
sq_getinteger(v, 2, &geom);
Vector3 position;
if (argc == 3)
{
_getvectorvalues(v, 3, position.x, position.y, position.z);
}
else if (argc == 5)
{
sq_getfloat(v, 3, &position.x);
sq_getfloat(v, 4, &position.y);
sq_getfloat(v, 5, &position.z);
}
body->setCollisionMeshPosition(geom, position);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_disablecollisionmesh(HSQUIRRELVM v)
{
int argc = sq_gettop(v);
// need at least geom
if (argc < 2)
return 0;
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
SQInteger geom = 0;
sq_getinteger(v, 2, &geom);
body->disableCollisionMesh(geom);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_enablecollisionmesh(HSQUIRRELVM v)
{
int argc = sq_gettop(v);
// need at least geom
if (argc < 2)
return 0;
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
SQInteger geom = 0;
sq_getinteger(v, 2, &geom);
body->enableCollisionMesh(geom);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_setcollisionmeshrotation(HSQUIRRELVM v)
{
int argc = sq_gettop(v);
// need at least geom + quaternion
if (argc < 3)
return 0;
RigidBody *body = 0;
sq_getinstanceup(v, 1, ( void ** ) &body, 0);
if (body)
{
SQInteger geom = 0;
sq_getinteger(v, 2, &geom);
Quaternion rotation;
if (argc == 3)
{
_getquaternionvalues(v, 3, rotation.w, rotation.x, rotation.y,
rotation.z);
}
else if (argc == 4)
{
Vector3 axis;
SQFloat angle;
_getvectorvalues(v, 3, axis.x, axis.y, axis.z);
sq_getfloat(v, 5, &angle);
rotation = Quaternion(axis, angle);
}
else if (argc == 5)
{
SQFloat h, a, b;
sq_getfloat(v, 3, &h);
sq_getfloat(v, 4, &a);
sq_getfloat(v, 5, &b);
rotation = Quaternion(h, a, b);
}
body->setCollisionMeshRotation(geom, rotation);
}
return 0;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_releasehook(SQUserPointer p, SQInteger size)
{
if (gRigidBodySimulation.valid())
{
RigidBody *self = ( RigidBody* ) p;
gRigidBodySimulation->deleteRigidBody(self);
}
return 1;
}
//------------------------------------------------------------------------------
static SQInteger _rigidbody_constructor(HSQUIRRELVM v)
{
RigidBody *body = gRigidBodySimulation->createRigidBody();
if (SQ_FAILED(sq_setinstanceup(v, 1, body) ) )
{
gRigidBodySimulation->deleteRigidBody(body);
return 0;
}
HSQOBJECT obj;
sq_getstackobj(v, 2, &obj);
body->setCollisionHandler(obj);
sq_setreleasehook(v, 1, _rigidbody_releasehook);
return 0;
}
//------------------------------------------------------------------------------
void setupScriptSystem_RigidBody(ScriptSystem *scriptsystem,
RigidBodySimulation *simulation)
{
gRigidBodySimulation = simulation;
HSQUIRRELVM vm = scriptsystem->getVM();
sq_pushroottable(vm);
sq_pushstring(vm, "RigidBody", -1);
if (SQ_SUCCEEDED(sq_newclass(vm, SQFalse) ) )
{
// register rigidbody functions
sq_pushstring(vm, "constructor", -1);
sq_newclosure(vm, _rigidbody_constructor, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "setPosition", -1);
sq_newclosure(vm, _rigidbody_setposition, 0);
//sq_setparamscheck( vm, 2, "xx" );
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getPosition", -1);
sq_newclosure(vm, _rigidbody_getposition, 0);
sq_setparamscheck(vm, 1, "x");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "setRotation", -1);
sq_newclosure(vm, _rigidbody_setrotation, 0);
//sq_setparamscheck( vm, 2, "xx" );
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getRotation", -1);
sq_newclosure(vm, _rigidbody_getrotation, 0);
sq_setparamscheck(vm, 1, "x");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getLinearVelocity", -1);
sq_newclosure(vm, _rigidbody_getlinearvelocity, 0);
sq_setparamscheck(vm, 1, "x");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "setLinearVelocity", -1);
sq_newclosure(vm, _rigidbody_setlinearvelocity, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getAngularVelocity", -1);
sq_newclosure(vm, _rigidbody_getangularvelocity, 0);
sq_setparamscheck(vm, 1, "x");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "applyLocalForce", -1);
sq_newclosure(vm, _rigidbody_applylocalforce, 0);
//sq_setparamscheck (vm, 3, "xxx");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "applyGlobalForce", -1);
sq_newclosure(vm, _rigidbody_applyglobalforce, 0);
sq_setparamscheck(vm, 3, "xxx");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "addCollisionMesh", -1);
sq_newclosure(vm, _rigidbody_addcollisionmesh, 0);
sq_setparamscheck(vm, 3, "xsn");
sq_newslot(vm, -3, false);
sq_pushstring(vm, "setCollisionMeshPosition", -1);
sq_newclosure(vm, _rigidbody_setcollisionmeshposition, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "setCollisionMeshRotation", -1);
sq_newclosure(vm, _rigidbody_setcollisionmeshrotation, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getCollisionMeshPosition", -1);
sq_newclosure(vm, _rigidbody_setcollisionmeshposition, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "getCollisionMeshRotation", -1);
sq_newclosure(vm, _rigidbody_setcollisionmeshrotation, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "disableCollisionMesh", -1);
sq_newclosure(vm, _rigidbody_disablecollisionmesh, 0);
sq_newslot(vm, -3, false);
sq_pushstring(vm, "enableCollisionMesh", -1);
sq_newclosure(vm, _rigidbody_enablecollisionmesh, 0);
sq_newslot(vm, -3, false);
sq_newslot(vm, -3, false);
}
sq_poptop(vm);
}
} // namespace BlueCore