forked from LeenkxTeam/LNXSDK
		
	
		
			
	
	
		
			136 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
		
		
			
		
	
	
			136 lines
		
	
	
		
			4.2 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
|  | #pragma once
 | ||
|  | 
 | ||
|  | #include <btBulletCollisionCommon.h>
 | ||
|  | #include "LinearMath/btIDebugDraw.h"
 | ||
|  | #include "LinearMath/btVector3.h"
 | ||
|  | 
 | ||
|  | #define HL_NAME(n) bullet_##n
 | ||
|  | #include <hl.h>
 | ||
|  | 
 | ||
|  | // TODO: The Haxe side only assumes f32 at the moment...
 | ||
|  | #ifdef BT_USE_DOUBLE_PRECISION
 | ||
|  | 	#define _HL_FFI_TYPE_btScalar _I64
 | ||
|  | 	static hl_type hl_type_btScalar = hlt_f64; | ||
|  | #else
 | ||
|  | 	#define _HL_FFI_TYPE_btScalar _I32
 | ||
|  | 	static hl_type hl_type_btScalar = hlt_f32; | ||
|  | #endif
 | ||
|  | 
 | ||
|  | class DebugDrawer : public btIDebugDraw | ||
|  | { | ||
|  | 	int m_debugMode = 0; | ||
|  | 
 | ||
|  | public: | ||
|  | 	DebugDrawer() {}; | ||
|  | 	virtual ~DebugDrawer() {}; | ||
|  | 
 | ||
|  | 	virtual void drawLine(const btVector3& from, const btVector3& to, const btVector3& color); | ||
|  | 	virtual void drawContactPoint(const btVector3& PointOnB, const btVector3& normalOnB, btScalar distance, int lifeTime, const btVector3& color); | ||
|  | 	virtual void reportErrorWarning(const char* warningString); | ||
|  | 	virtual void draw3dText(const btVector3& location, const char* textString); | ||
|  | 
 | ||
|  | 	virtual void setDebugMode(int debugMode); | ||
|  | 	virtual int getDebugMode() const; | ||
|  | 
 | ||
|  | 	// Using vclosure* is not really type-safe unfortunately, but Haxe passes
 | ||
|  | 	// closures as vclosure* and we need to use hl_dyn_call() to call them.
 | ||
|  | 	// We cannot use proper function pointers here and wrap the call to hl_dyn_call() in a lambda
 | ||
|  | 	// since the lambda would then need to capture the vclosure and in turn could not be converted
 | ||
|  | 	// to a function pointer (this is not possible for capturing lambdas).
 | ||
|  | 	vclosure* p_drawLine = nullptr; | ||
|  | 	vclosure* p_drawContactPoint = nullptr; | ||
|  | 	vclosure* p_reportErrorWarning = nullptr; | ||
|  | 	vclosure* p_draw3dText = nullptr; | ||
|  | }; | ||
|  | 
 | ||
|  | // To simplify the Haxe interop, we're using a global instance here
 | ||
|  | // instead of passing around an instance in all Haxe extern calls.
 | ||
|  | // Normally you don't need multiple drawer instances anyways...
 | ||
|  | static DebugDrawer* globalDebugDrawerInstance = new DebugDrawer(); | ||
|  | 
 | ||
|  | extern "C" | ||
|  | { | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_worldSetGlobalDebugDrawer)(vbyte* physicsWorld) | ||
|  | 	{ | ||
|  | 		btCollisionWorld *p_world = (btCollisionWorld *)physicsWorld; | ||
|  | 		p_world->setDebugDrawer(globalDebugDrawerInstance); | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_worldSetGlobalDebugDrawer, _BYTES); | ||
|  | 
 | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_setDebugMode)(int debugMode) | ||
|  | 	{ | ||
|  | 		globalDebugDrawerInstance->setDebugMode(debugMode); | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_setDebugMode, _I32); | ||
|  | 
 | ||
|  | 	HL_PRIM int HL_NAME(debugDrawer_getDebugMode)() | ||
|  | 	{ | ||
|  | 		return globalDebugDrawerInstance->getDebugMode(); | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_I32, debugDrawer_getDebugMode, _VOID); | ||
|  | 
 | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_setDrawLine)(vclosure* func) | ||
|  | 	{ | ||
|  | 		// Don't allow to unset p_drawLine, otherwise we'd have to
 | ||
|  | 		// deal with potential threaded-GC issues:
 | ||
|  | 		// - The GC might not like if we set p_drawLine to null before removing the root 
 | ||
|  | 		// - If we remove the root first, the GC might attempt to free memory that's still in use in this function
 | ||
|  | 		if (!func) return; | ||
|  | 
 | ||
|  | 		globalDebugDrawerInstance->p_drawLine = func; | ||
|  | 
 | ||
|  | 		static bool once = true; | ||
|  | 		if (once) | ||
|  | 		{ | ||
|  | 			// Add root after value was assigned to prevent potential issues when registering nullptr to threaded GC
 | ||
|  | 			hl_add_root(&globalDebugDrawerInstance->p_drawLine); | ||
|  | 			once = false; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_setDrawLine, _FUN(_VOID, _DYN _DYN _DYN)); | ||
|  | 
 | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_setDrawContactPoint)(vclosure* func) | ||
|  | 	{ | ||
|  | 		if (!func) return; | ||
|  | 
 | ||
|  | 		globalDebugDrawerInstance->p_drawContactPoint = func; | ||
|  | 
 | ||
|  | 		static bool once = true; | ||
|  | 		if (once) | ||
|  | 		{ | ||
|  | 			hl_add_root(&globalDebugDrawerInstance->p_drawContactPoint); | ||
|  | 			once = false; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_setDrawContactPoint, _FUN(_VOID, _DYN _DYN _HL_FFI_TYPE_btScalar _I32 _DYN)); | ||
|  | 
 | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_setReportErrorWarning)(vclosure* func) | ||
|  | 	{ | ||
|  | 		if (!func) return; | ||
|  | 
 | ||
|  | 		globalDebugDrawerInstance->p_reportErrorWarning = func; | ||
|  | 
 | ||
|  | 		static bool once = true; | ||
|  | 		if (once) | ||
|  | 		{ | ||
|  | 			hl_add_root(&globalDebugDrawerInstance->p_reportErrorWarning); | ||
|  | 			once = false; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_setReportErrorWarning, _FUN(_VOID, _STRING)); | ||
|  | 
 | ||
|  | 	HL_PRIM void HL_NAME(debugDrawer_setDraw3dText)(vclosure* func) | ||
|  | 	{ | ||
|  | 		if (!func) return; | ||
|  | 
 | ||
|  | 		globalDebugDrawerInstance->p_draw3dText = func; | ||
|  | 
 | ||
|  | 		static bool once = true; | ||
|  | 		if (once) | ||
|  | 		{ | ||
|  | 			hl_add_root(&globalDebugDrawerInstance->p_draw3dText); | ||
|  | 			once = false; | ||
|  | 		} | ||
|  | 	} | ||
|  | 	DEFINE_PRIM(_VOID, debugDrawer_setDraw3dText, _FUN(_VOID, _DYN _STRING)); | ||
|  | } |