Skip to content

Instantly share code, notes, and snippets.

@PixelToast

PixelToast/phys.cpp

Created Aug 18, 2017
Embed
What would you like to do?
Bullet API in dart
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include "dart_api.h"
#include "dart_native_api.h"
#include <btBulletDynamicsCommon.h>
Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool* auto_setup_scope);
struct HandleException {
explicit HandleException(Dart_Handle handle) : handle(handle) {}
Dart_Handle handle;
};
static Dart_Handle handleError(Dart_Handle handle) {
if (Dart_IsError(handle)) throw HandleException(handle);
return handle;
}
template<typename T, void destruct(T*)> T* constructWeak(Dart_NativeArguments arguments) {
auto s = new T();
Dart_NewWeakPersistentHandle(
handleError(Dart_GetNativeArgument(arguments, 0)),
static_cast<T*>(s),
sizeof(s),
[](
void* isolate_callback_data,
Dart_WeakPersistentHandle handle,
void* peer
){
destruct(static_cast<T*>(peer));
}
);
Dart_SetReturnValue(arguments, Dart_NewInteger(reinterpret_cast<int64_t>(s)));
return s;
}
template<void code(Dart_NativeArguments arguments)> void safeHandle(Dart_NativeArguments arguments) {
try {
code(arguments);
} catch (HandleException& handle) {
Dart_PropagateError(handle.handle);
}
}
double doubleFromArgs(Dart_NativeArguments arguments, int index) {
double x;
handleError(Dart_GetNativeDoubleArgument(arguments, index, &x));
return x;
}
int64_t intFromArgs(Dart_NativeArguments arguments, int index) {
int64_t x;
handleError(Dart_GetNativeIntegerArgument(arguments, index, &x));
return x;
}
template<typename T> T* ptrFromArg(Dart_NativeArguments arguments, int index) {
int64_t i;
handleError(Dart_GetNativeIntegerArgument(arguments, index, &i));
return reinterpret_cast<T*>(i);
};
struct WorldState {
btBroadphaseInterface* broadphase = nullptr;
btDefaultCollisionConfiguration* collisionConfiguration = nullptr;
btCollisionDispatcher* dispatcher = nullptr;
btDiscreteDynamicsWorld* dynamicsWorld = nullptr;
btSequentialImpulseConstraintSolver* solver = nullptr;
};
struct CollisionShape {
btCollisionShape* shape = nullptr;
};
struct MotionState {
btMotionState* state;
};
struct RigidBody {
btRigidBody* body;
};
std::string vec3str(btVector3 v) {
return std::to_string(v.x()) + "," + std::to_string(v.y()) + "," + std::to_string(v.z());
}
DART_EXPORT Dart_Handle phys_Init(Dart_Handle parent_library) {
if (Dart_IsError(parent_library)) return parent_library;
Dart_Handle result_code =
Dart_SetNativeResolver(parent_library, ResolveName, nullptr);
if (Dart_IsError(result_code)) return result_code;
return Dart_Null();
}
btVector3 vec3FromArgs(Dart_NativeArguments arguments, int index) {
return btVector3(
doubleFromArgs(arguments, index),
doubleFromArgs(arguments, index + 1),
doubleFromArgs(arguments, index + 2)
);
}
btQuaternion quatFromArgs(Dart_NativeArguments arguments, int index) {
return btQuaternion(
doubleFromArgs(arguments, index),
doubleFromArgs(arguments, index + 1),
doubleFromArgs(arguments, index + 2),
doubleFromArgs(arguments, index + 3)
);
}
void d_world_destruct(WorldState* state) {
delete state->dynamicsWorld;
delete state->solver;
delete state->collisionConfiguration;
delete state->dispatcher;
delete state->broadphase;
delete state;
}
void d_world_construct(Dart_NativeArguments arguments) {
constructWeak<WorldState, d_world_destruct>(arguments);
}
void d_world_init_lazy(Dart_NativeArguments arguments) {
auto w = ptrFromArg<WorldState>(arguments, 1);
w->broadphase = new btDbvtBroadphase();
w->collisionConfiguration = new btDefaultCollisionConfiguration();
w->dispatcher = new btCollisionDispatcher(w->collisionConfiguration);
w->solver = new btSequentialImpulseConstraintSolver;
w->dynamicsWorld = new btDiscreteDynamicsWorld(w->dispatcher, w->broadphase, w->solver, w->collisionConfiguration);
}
void d_world_set_gravity(Dart_NativeArguments arguments) {
auto w = ptrFromArg<WorldState>(arguments, 1);
w->dynamicsWorld->setGravity(vec3FromArgs(arguments, 2));
}
void d_world_add_rigid_body(Dart_NativeArguments arguments) {
auto w = ptrFromArg<WorldState>(arguments, 1);
auto body = ptrFromArg<RigidBody>(arguments, 2);
w->dynamicsWorld->addRigidBody(body->body);
}
void d_world_step(Dart_NativeArguments arguments) {
auto w = ptrFromArg<WorldState>(arguments, 1);
w->dynamicsWorld->stepSimulation(doubleFromArgs(arguments, 2), intFromArgs(arguments, 3));
}
void shape_destruct(CollisionShape* collisionShape) {
delete collisionShape->shape;
delete collisionShape;
}
void d_shape_construct(Dart_NativeArguments arguments) {
auto collisionshape = constructWeak<CollisionShape, shape_destruct>(arguments);
collisionshape->shape = new btEmptyShape();
}
void d_shape_static_plane_construct(Dart_NativeArguments arguments) {
auto collisionshape = constructWeak<CollisionShape, shape_destruct>(arguments);
//collisionshape->shape = new btStaticPlaneShape(vec3FromArgs(arguments, 1), doubleFromArgs(arguments, 4));
collisionshape->shape = new btStaticPlaneShape(btVector3(0, 1, 0), 1);
}
void d_shape_sphere_construct(Dart_NativeArguments arguments) {
auto collisionshape = constructWeak<CollisionShape, shape_destruct>(arguments);
collisionshape->shape = new btSphereShape(doubleFromArgs(arguments, 1));
}
void d_shape_calc_inertia(Dart_NativeArguments arguments) {
auto collisionshape = ptrFromArg<CollisionShape>(arguments, 1);
auto out = Dart_GetNativeArgument(arguments, 3);
btVector3 inertia(0.0, 0.0, 0.0);
collisionshape->shape->calculateLocalInertia(doubleFromArgs(arguments, 2), inertia);
handleError(Dart_ListSetAt(out, 0, Dart_NewDouble(inertia.x())));
handleError(Dart_ListSetAt(out, 1, Dart_NewDouble(inertia.y())));
handleError(Dart_ListSetAt(out, 2, Dart_NewDouble(inertia.z())));
}
void motion_state_destruct(MotionState* motionState) {
delete motionState->state;
delete motionState;
}
void d_motion_state_construct(Dart_NativeArguments arguments) {
auto motionState = constructWeak<MotionState, motion_state_destruct>(arguments);
motionState->state = new btDefaultMotionState(
btTransform(quatFromArgs(arguments, 4), vec3FromArgs(arguments, 1))
);
}
void d_motion_state_get_pos(Dart_NativeArguments arguments) {
auto motionState = ptrFromArg<MotionState>(arguments, 1);
auto out = Dart_GetNativeArgument(arguments, 2);
btTransform transform;
motionState->state->getWorldTransform(transform);
auto origin = transform.getOrigin();
handleError(Dart_ListSetAt(out, 0, Dart_NewDouble(origin.x())));
handleError(Dart_ListSetAt(out, 1, Dart_NewDouble(origin.y())));
handleError(Dart_ListSetAt(out, 2, Dart_NewDouble(origin.z())));
}
void d_motion_state_set_pos(Dart_NativeArguments arguments) {
auto motionState = ptrFromArg<MotionState>(arguments, 1);
auto out = Dart_GetNativeArgument(arguments, 2);
btTransform transform;
motionState->state->getWorldTransform(transform);
transform.setOrigin(btVector3(
doubleFromArgs(arguments, 1),
doubleFromArgs(arguments, 2),
doubleFromArgs(arguments, 3)
));
motionState->state->setWorldTransform(transform);
}
void d_motion_state_get_angle(Dart_NativeArguments arguments) {
auto motionState = ptrFromArg<MotionState>(arguments, 1);
auto out = Dart_GetNativeArgument(arguments, 2);
btTransform transform;
motionState->state->getWorldTransform(transform);
auto origin = transform.getOrigin();
handleError(Dart_ListSetAt(out, 0, Dart_NewDouble(origin.x())));
handleError(Dart_ListSetAt(out, 1, Dart_NewDouble(origin.y())));
handleError(Dart_ListSetAt(out, 2, Dart_NewDouble(origin.z())));
}
void d_motion_state_set_angle(Dart_NativeArguments arguments) {
auto motionState = ptrFromArg<MotionState>(arguments, 1);
auto out = Dart_GetNativeArgument(arguments, 2);
btTransform transform;
motionState->state->getWorldTransform(transform);
transform.setOrigin(btVector3(
doubleFromArgs(arguments, 1),
doubleFromArgs(arguments, 2),
doubleFromArgs(arguments, 3)
));
motionState->state->setWorldTransform(transform);
}
void rigid_body_destruct(RigidBody* motionState) {
delete motionState->body;
delete motionState;
}
void d_rigid_body_construct(Dart_NativeArguments arguments) {
auto rigidBody = constructWeak<RigidBody, rigid_body_destruct>(arguments);
auto mass = doubleFromArgs(arguments, 1);
auto motionState = ptrFromArg<MotionState>(arguments, 2);
auto collisionShape = ptrFromArg<CollisionShape>(arguments, 3);
auto inertia = vec3FromArgs(arguments, 4);
auto restitution = doubleFromArgs(arguments, 7);
auto friction = doubleFromArgs(arguments, 8);
btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(
mass, motionState->state, collisionShape->shape, inertia
);
fallRigidBodyCI.m_restitution = restitution;
fallRigidBodyCI.m_friction = friction;
rigidBody->body = new btRigidBody(fallRigidBodyCI);
}
Dart_NativeFunction ResolveName(Dart_Handle name, int argc, bool* auto_setup_scope) {
if (!Dart_IsString(name)) return nullptr;
Dart_NativeFunction result = nullptr;
const char* cname;
auto cres = Dart_StringToCString(name, &cname);
if (Dart_IsError(cres)) Dart_PropagateError(cres);
if (strcmp("world_construct", cname) == 0) result = safeHandle<d_world_construct>;
if (strcmp("world_init_lazy", cname) == 0) result = safeHandle<d_world_init_lazy>;
if (strcmp("world_set_gravity", cname) == 0) result = safeHandle<d_world_set_gravity>;
if (strcmp("world_add_rigid_body", cname) == 0) result = safeHandle<d_world_add_rigid_body>;
if (strcmp("world_step", cname) == 0) result = safeHandle<d_world_step>;
if (strcmp("shape_construct", cname) == 0) result = safeHandle<d_shape_construct>;
if (strcmp("shape_static_plane_construct", cname) == 0) result = safeHandle<d_shape_static_plane_construct>;
if (strcmp("shape_sphere_construct", cname) == 0) result = safeHandle<d_shape_sphere_construct>;
if (strcmp("shape_calc_inertia", cname) == 0) result = safeHandle<d_shape_calc_inertia>;
if (strcmp("motion_state_construct", cname) == 0) result = safeHandle<d_motion_state_construct>;
if (strcmp("motion_state_get_pos", cname) == 0) result = safeHandle<d_motion_state_get_pos>;
if (strcmp("motion_state_set_pos", cname) == 0) result = safeHandle<d_motion_state_set_pos>;
if (strcmp("motion_state_get_angle", cname) == 0) result = safeHandle<d_motion_state_get_angle>;
if (strcmp("motion_state_set_angle", cname) == 0) result = safeHandle<d_motion_state_set_angle>;
if (strcmp("rigid_body_construct", cname) == 0) result = safeHandle<d_rigid_body_construct>;
return result;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment