543 lignes
11 KiB
C++
543 lignes
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
|