#include "RigidBodySimulation.h" #include "ScriptSystem_Math.h" namespace BlueCore { //------------------------------------------------------------------------------ static weak_ptr 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