543 lines
12 KiB
C++
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
|