#include "box3d/box3d.h"
#include <emscripten/emscripten.h>
#include <stdbool.h>
#include <stdint.h>
EM_JS(int, boxddd_js_debug_take_error, (uint32_t token), {
const errors = Module.boxdddDebugDrawErrors;
if (!errors) return 0;
const key = token >>> 0;
const error = errors.get(key) | 0;
errors.delete(key);
return error;
});
EM_JS(uint32_t, boxddd_js_debug_shape_create, (uint32_t token, const b3DebugShape* shape), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_shape_create !== 'function') {
setError(1);
return 0;
}
try {
return exports.boxddd_debug_shape_create(token >>> 0, shape >>> 0) >>> 0;
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug shape create failed: ${error}`);
return 0;
}
});
EM_JS(void, boxddd_js_debug_shape_destroy, (uint32_t token, uint32_t handle), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_shape_destroy !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_shape_destroy(token >>> 0, handle >>> 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug shape destroy failed: ${error}`);
}
});
EM_JS(int, boxddd_js_debug_draw_shape,
(uint32_t token, uint32_t handle, const b3WorldTransform* transform, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_shape !== 'function') {
setError(1);
return 0;
}
try {
return exports.boxddd_debug_draw_shape(token >>> 0, handle >>> 0, transform >>> 0, color | 0) ? 1 : 0;
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw shape failed: ${error}`);
return 0;
}
});
EM_JS(void, boxddd_js_debug_draw_segment,
(uint32_t token, const b3Pos* p1, const b3Pos* p2, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_segment !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_segment(token >>> 0, p1 >>> 0, p2 >>> 0, color | 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw segment failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_transform, (uint32_t token, const b3WorldTransform* transform), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_transform !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_transform(token >>> 0, transform >>> 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw transform failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_point,
(uint32_t token, const b3Pos* position, float size, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_point !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_point(token >>> 0, position >>> 0, size, color | 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw point failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_sphere,
(uint32_t token, const b3Pos* center, float radius, b3HexColor color, float alpha), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_sphere !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_sphere(token >>> 0, center >>> 0, radius, color | 0, alpha);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw sphere failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_capsule,
(uint32_t token, const b3Pos* p1, const b3Pos* p2, float radius, b3HexColor color, float alpha), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_capsule !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_capsule(token >>> 0, p1 >>> 0, p2 >>> 0, radius, color | 0, alpha);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw capsule failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_bounds,
(uint32_t token, const b3AABB* aabb, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_bounds !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_bounds(token >>> 0, aabb >>> 0, color | 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw bounds failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_box,
(uint32_t token, const b3Vec3* extents, const b3WorldTransform* transform, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_box !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_box(token >>> 0, extents >>> 0, transform >>> 0, color | 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw box failed: ${error}`);
}
});
EM_JS(void, boxddd_js_debug_draw_string,
(uint32_t token, const b3Pos* position, const char* text, b3HexColor color), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddDebugDrawErrors || (Module.boxdddDebugDrawErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_debug_draw_string !== 'function') {
setError(1);
return;
}
try {
exports.boxddd_debug_draw_string(token >>> 0, position >>> 0, text >>> 0, color | 0);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd debug draw string failed: ${error}`);
}
});
static void* boxddd_create_debug_shape(const b3DebugShape* shape, void* context)
{
uint32_t token = (uint32_t)(uintptr_t)context;
uint32_t handle = boxddd_js_debug_shape_create(token, shape);
return (void*)(uintptr_t)handle;
}
static void boxddd_destroy_debug_shape(void* userShape, void* context)
{
uint32_t token = (uint32_t)(uintptr_t)context;
uint32_t handle = (uint32_t)(uintptr_t)userShape;
if (handle != 0) {
boxddd_js_debug_shape_destroy(token, handle);
}
}
static bool boxddd_draw_shape(void* userShape, b3WorldTransform transform, b3HexColor color, void* context)
{
uint32_t token = (uint32_t)(uintptr_t)context;
uint32_t handle = (uint32_t)(uintptr_t)userShape;
return boxddd_js_debug_draw_shape(token, handle, &transform, color) != 0;
}
static void boxddd_draw_segment(b3Pos p1, b3Pos p2, b3HexColor color, void* context)
{
boxddd_js_debug_draw_segment((uint32_t)(uintptr_t)context, &p1, &p2, color);
}
static void boxddd_draw_transform(b3WorldTransform transform, void* context)
{
boxddd_js_debug_draw_transform((uint32_t)(uintptr_t)context, &transform);
}
static void boxddd_draw_point(b3Pos position, float size, b3HexColor color, void* context)
{
boxddd_js_debug_draw_point((uint32_t)(uintptr_t)context, &position, size, color);
}
static void boxddd_draw_sphere(b3Pos center, float radius, b3HexColor color, float alpha, void* context)
{
boxddd_js_debug_draw_sphere((uint32_t)(uintptr_t)context, ¢er, radius, color, alpha);
}
static void boxddd_draw_capsule(b3Pos p1, b3Pos p2, float radius, b3HexColor color, float alpha, void* context)
{
boxddd_js_debug_draw_capsule((uint32_t)(uintptr_t)context, &p1, &p2, radius, color, alpha);
}
static void boxddd_draw_bounds(b3AABB aabb, b3HexColor color, void* context)
{
boxddd_js_debug_draw_bounds((uint32_t)(uintptr_t)context, &aabb, color);
}
static void boxddd_draw_box(b3Vec3 extents, b3WorldTransform transform, b3HexColor color, void* context)
{
boxddd_js_debug_draw_box((uint32_t)(uintptr_t)context, &extents, &transform, color);
}
static void boxddd_draw_string(b3Pos position, const char* text, b3HexColor color, void* context)
{
boxddd_js_debug_draw_string((uint32_t)(uintptr_t)context, &position, text, color);
}
void boxddd_provider_debug_install_world_def(b3WorldDef* def, uint32_t registryToken)
{
def->createDebugShape = boxddd_create_debug_shape;
def->destroyDebugShape = boxddd_destroy_debug_shape;
def->userDebugShapeContext = (void*)(uintptr_t)registryToken;
}
void boxddd_provider_debug_init_draw(b3DebugDraw* draw, uint32_t drawToken)
{
draw->DrawShapeFcn = boxddd_draw_shape;
draw->DrawSegmentFcn = boxddd_draw_segment;
draw->DrawTransformFcn = boxddd_draw_transform;
draw->DrawPointFcn = boxddd_draw_point;
draw->DrawSphereFcn = boxddd_draw_sphere;
draw->DrawCapsuleFcn = boxddd_draw_capsule;
draw->DrawBoundsFcn = boxddd_draw_bounds;
draw->DrawBoxFcn = boxddd_draw_box;
draw->DrawStringFcn = boxddd_draw_string;
draw->context = (void*)(uintptr_t)drawToken;
}
int boxddd_provider_debug_take_error(uint32_t token)
{
return boxddd_js_debug_take_error(token);
}
EM_JS(int, boxddd_js_query_take_error, (uint32_t token), {
const errors = Module.boxdddQueryErrors;
if (!errors) return 0;
const key = token >>> 0;
const error = errors.get(key) | 0;
errors.delete(key);
return error;
});
EM_JS(int, boxddd_js_query_overlap, (uint32_t token, const b3ShapeId* shape), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddQueryErrors || (Module.boxdddQueryErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_query_overlap !== 'function') {
setError(1);
return 0;
}
try {
return exports.boxddd_query_overlap(token >>> 0, shape >>> 0) ? 1 : 0;
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd query overlap failed: ${error}`);
return 0;
}
});
EM_JS(float, boxddd_js_query_cast,
(uint32_t token, const b3ShapeId* shape, const b3Pos* point, const b3Vec3* normal, float fraction,
const uint64_t* userMaterialId, int triangleIndex, int childIndex), {
const exports = Module.boxdddAppExports;
const setError = (code) => {
const key = token >>> 0;
const errors = Module.boxdddQueryErrors || (Module.boxdddQueryErrors = new Map());
if (!errors.has(key)) errors.set(key, code | 0);
};
if (!exports || typeof exports.boxddd_query_cast !== 'function') {
setError(1);
return 0.0;
}
try {
return exports.boxddd_query_cast(
token >>> 0,
shape >>> 0,
point >>> 0,
normal >>> 0,
fraction,
userMaterialId >>> 0,
triangleIndex | 0,
childIndex | 0
);
} catch (error) {
setError(2);
if (Module.printErr) Module.printErr(`boxddd query cast failed: ${error}`);
return 0.0;
}
});
static bool boxddd_query_overlap(b3ShapeId shapeId, void* context)
{
uint32_t token = (uint32_t)(uintptr_t)context;
return boxddd_js_query_overlap(token, &shapeId) != 0;
}
static float boxddd_query_cast(b3ShapeId shapeId, b3Pos point, b3Vec3 normal, float fraction, uint64_t userMaterialId,
int triangleIndex, int childIndex, void* context)
{
uint32_t token = (uint32_t)(uintptr_t)context;
return boxddd_js_query_cast(token, &shapeId, &point, &normal, fraction, &userMaterialId, triangleIndex, childIndex);
}
int boxddd_provider_query_take_error(uint32_t token)
{
return boxddd_js_query_take_error(token);
}
b3TreeStats boxddd_provider_world_overlap_aabb(b3WorldId worldId, b3AABB aabb, b3QueryFilter filter, uint32_t token)
{
return b3World_OverlapAABB(worldId, aabb, filter, boxddd_query_overlap, (void*)(uintptr_t)token);
}
b3TreeStats boxddd_provider_world_cast_ray(b3WorldId worldId, b3Pos origin, b3Vec3 translation, b3QueryFilter filter, uint32_t token)
{
return b3World_CastRay(worldId, origin, translation, filter, boxddd_query_cast, (void*)(uintptr_t)token);
}