bluecore/engine/ScriptSystem_RigidBody.cpp

543 lines
12 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