-Added some more math functions -fixed many memory leaks -added AABB and BVHTree support to collision.d *BVHTree has only incrementally adding entities implemented by now (and bad BottomUp algorithm) *ECS Systems use two trees, one for static and one for dynamic entities, dynamic BVH is builded every frame from scratch by now -BrickBreaker now uses BVHTree to collision detection *balls only use tree for checks (they aren't adding to tree) -fixed bug leading to crash
257 lines
No EOL
7.9 KiB
D
257 lines
No EOL
7.9 KiB
D
module ecs_utils.utils;
|
|
|
|
extern(C):
|
|
|
|
import ecs_utils.math.vector;
|
|
|
|
enum PI = 3.141592653589793238462643383279502884197169399375105820;
|
|
|
|
extern(C) float sqrtf(float x) @nogc nothrow @system;
|
|
extern(C) float acosf(float x) @nogc nothrow @system;
|
|
extern(C) float sinf(float x) @nogc nothrow @system;
|
|
extern(C) float cosf(float x) @nogc nothrow @system;
|
|
extern(C) float powf(float x, float y) @nogc nothrow @system;
|
|
extern(C) float fabs(float x) @nogc nothrow @system;
|
|
extern(C) float log2f(float arg) @nogc nothrow @system;
|
|
|
|
|
|
int randomRange(int min, int max) nothrow @nogc @trusted
|
|
{
|
|
int range = max - min;
|
|
return rand() % range - min;
|
|
}
|
|
|
|
float randomf() nothrow @nogc @trusted
|
|
{
|
|
const float scale = 1.0 / 32_767.0;
|
|
return cast(float)(rand() & 0x007FFF) * scale;
|
|
}
|
|
|
|
/*
|
|
float randomRangef(float min, float max)
|
|
{
|
|
//int range = max - min;
|
|
return rand()%4096;
|
|
}*/
|
|
|
|
float mix(float x, float y, float a)
|
|
{
|
|
//return x*a + y*(a-1);
|
|
//return x*a + y*a - y;
|
|
return x*(a+y) - y;
|
|
}
|
|
|
|
float rsqrt(float number)
|
|
{
|
|
long i;
|
|
float x2, y;
|
|
const float threehalfs = 1.5F;
|
|
|
|
x2 = number * 0.5F;
|
|
y = number;
|
|
i = * cast( long * ) &y; // evil floating point bit level hacking
|
|
i = 0x5f3759df - ( i >> 1 ); // what the fuck?
|
|
y = * cast( float * ) &i;
|
|
y = y * ( threehalfs - ( x2 * y * y ) ); // 1st iteration
|
|
|
|
return y;
|
|
}
|
|
|
|
vec2 randomCircularSample() nothrow @nogc @trusted
|
|
{
|
|
float angle = 2 * PI * randomf;
|
|
float radius = sqrtf(randomf);
|
|
float s = sinf(angle);
|
|
float c = cosf(angle);
|
|
return vec2(c,s)*radius;
|
|
}
|
|
|
|
version(GNU)
|
|
{
|
|
public import core.stdc.stdio : printf;
|
|
pragma(inline, true) T[n] staticArray(T, size_t n)(auto ref T[n] a)
|
|
{
|
|
return a;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
extern(C) int printf(scope const char* format, ...) @nogc nothrow @system;
|
|
public import std.array : staticArray;
|
|
}
|
|
extern(C) int rand() nothrow @nogc @trusted;
|
|
|
|
version(D_BetterC)
|
|
{
|
|
version(LDC)
|
|
{
|
|
extern(C) bool _d_enter_cleanup(void*)
|
|
{
|
|
return true;
|
|
}
|
|
|
|
extern(C) void _d_leave_cleanup(void*)
|
|
{
|
|
|
|
}
|
|
|
|
extern(C) void _d_array_slice_copy(void* dst, size_t dstlen, void* src, size_t srclen, size_t elemsz)
|
|
{
|
|
import ldc.intrinsics : llvm_memcpy;
|
|
llvm_memcpy!size_t(dst, src, dstlen * elemsz, 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
version(Android)
|
|
{
|
|
alias pthread_key_t = uint;
|
|
|
|
extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow;
|
|
extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow;
|
|
extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow;
|
|
extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow;
|
|
}
|
|
|
|
version(WebAssembly)
|
|
{
|
|
alias pthread_key_t = uint;
|
|
|
|
extern (C) int pthread_key_create(pthread_key_t *, void* function(void *)) @nogc nothrow;
|
|
extern (C) int pthread_key_delete(pthread_key_t) @nogc nothrow;
|
|
extern (C) void* pthread_getspecific(pthread_key_t) @nogc nothrow;
|
|
extern (C) int pthread_setspecific(pthread_key_t, const void *) @nogc nothrow;
|
|
|
|
enum EMSCRIPTEN_RESULT_SUCCESS = 0;
|
|
enum EMSCRIPTEN_RESULT_DEFERRED = 1;
|
|
enum EMSCRIPTEN_RESULT_NOT_SUPPORTED = -1;
|
|
enum EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED = -2;
|
|
enum EMSCRIPTEN_RESULT_INVALID_TARGET = -3;
|
|
enum EMSCRIPTEN_RESULT_UNKNOWN_TARGET = -4;
|
|
enum EMSCRIPTEN_RESULT_INVALID_PARAM = -5;
|
|
enum EMSCRIPTEN_RESULT_FAILED = -6;
|
|
enum EMSCRIPTEN_RESULT_NO_DATA = -7;
|
|
enum EMSCRIPTEN_RESULT_TIMED_OUT = -8;
|
|
|
|
alias EMSCRIPTEN_FULLSCREEN_SCALE = int;
|
|
enum EMSCRIPTEN_FULLSCREEN_SCALE_DEFAULT = 0;
|
|
enum EMSCRIPTEN_FULLSCREEN_SCALE_STRETCH = 1;
|
|
enum EMSCRIPTEN_FULLSCREEN_SCALE_ASPECT = 2;
|
|
enum EMSCRIPTEN_FULLSCREEN_SCALE_CENTER = 3;
|
|
|
|
alias EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE = int;
|
|
enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_NONE = 0;
|
|
enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_STDDEF = 1;
|
|
enum EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE_HIDEF = 2;
|
|
|
|
alias EMSCRIPTEN_FULLSCREEN_FILTERING = int;
|
|
enum EMSCRIPTEN_FULLSCREEN_FILTERING_DEFAULT = 0;
|
|
enum EMSCRIPTEN_FULLSCREEN_FILTERING_NEAREST = 1;
|
|
enum EMSCRIPTEN_FULLSCREEN_FILTERING_BILINEAR = 2;
|
|
|
|
alias em_canvasresized_callback_func = extern(C) bool function (int eventType, const void *reserved, void *userData);
|
|
|
|
struct EmscriptenFullscreenStrategy {
|
|
EMSCRIPTEN_FULLSCREEN_SCALE scaleMode;
|
|
EMSCRIPTEN_FULLSCREEN_CANVAS_SCALE canvasResolutionScaleMode;
|
|
EMSCRIPTEN_FULLSCREEN_FILTERING filteringMode;
|
|
em_canvasresized_callback_func canvasResizedCallback;
|
|
void *canvasResizedCallbackUserData;
|
|
}
|
|
|
|
extern (C) const (char)* emscripten_result_to_string(int result) {
|
|
if (result == EMSCRIPTEN_RESULT_SUCCESS) return "EMSCRIPTEN_RESULT_SUCCESS";
|
|
if (result == EMSCRIPTEN_RESULT_DEFERRED) return "EMSCRIPTEN_RESULT_DEFERRED";
|
|
if (result == EMSCRIPTEN_RESULT_NOT_SUPPORTED) return "EMSCRIPTEN_RESULT_NOT_SUPPORTED";
|
|
if (result == EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED) return "EMSCRIPTEN_RESULT_FAILED_NOT_DEFERRED";
|
|
if (result == EMSCRIPTEN_RESULT_INVALID_TARGET) return "EMSCRIPTEN_RESULT_INVALID_TARGET";
|
|
if (result == EMSCRIPTEN_RESULT_UNKNOWN_TARGET) return "EMSCRIPTEN_RESULT_UNKNOWN_TARGET";
|
|
if (result == EMSCRIPTEN_RESULT_INVALID_PARAM) return "EMSCRIPTEN_RESULT_INVALID_PARAM";
|
|
if (result == EMSCRIPTEN_RESULT_FAILED) return "EMSCRIPTEN_RESULT_FAILED";
|
|
if (result == EMSCRIPTEN_RESULT_NO_DATA) return "EMSCRIPTEN_RESULT_NO_DATA";
|
|
return "Unknown EMSCRIPTEN_RESULT!";
|
|
}
|
|
|
|
extern (C) alias em_callback_func = void function();
|
|
extern (C) alias em_arg_callback_func = void function(void*);
|
|
extern (C) void emscripten_set_main_loop(em_callback_func func, int fps, int simulate_infinite_loop);
|
|
extern (C) void emscripten_set_main_loop_arg(em_arg_callback_func func, void *arg, int fps, int simulate_infinite_loop);
|
|
extern (C) int emscripten_set_main_loop_timing(int mode, int value);
|
|
extern (C) void emscripten_cancel_main_loop();
|
|
extern (C) int emscripten_request_fullscreen_strategy(const char *target, bool deferUntilInEventHandler, const EmscriptenFullscreenStrategy *fullscreenStrategy);
|
|
extern (C) int emscripten_enter_soft_fullscreen(const char *target, const EmscriptenFullscreenStrategy *fullscreenStrategy);
|
|
extern (C) void emscripten_main_thread_process_queued_calls();
|
|
extern (C) void emscripten_pause_main_loop();
|
|
extern (C) void emscripten_resume_main_loop();
|
|
|
|
alias int time_t;
|
|
alias int clockid_t;
|
|
enum CLOCK_REALTIME = 0;
|
|
|
|
struct timespec
|
|
{
|
|
time_t tv_sec;
|
|
int tv_nsec;
|
|
}
|
|
|
|
extern(C) int clock_gettime(clockid_t, timespec*) @nogc nothrow @system;
|
|
|
|
struct Time
|
|
{
|
|
|
|
|
|
static long getUSecTime()
|
|
{
|
|
time_t time;
|
|
timespec spec;
|
|
|
|
clock_gettime(CLOCK_REALTIME, &spec);
|
|
|
|
//time = spec.tv_sec;
|
|
return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000;
|
|
|
|
/*LARGE_INTEGER time, freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
QueryPerformanceCounter(&time);
|
|
return time.QuadPart / (freq.QuadPart / 1000_000);*/
|
|
}
|
|
}
|
|
}
|
|
else version(Windows)
|
|
{
|
|
import core.stdc.stdio : printf;
|
|
import core.sys.windows.windows;
|
|
struct Time
|
|
{
|
|
static long getUSecTime()
|
|
{
|
|
LARGE_INTEGER time, freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
QueryPerformanceCounter(&time);
|
|
return time.QuadPart / (freq.QuadPart / 1000_000);
|
|
}
|
|
}
|
|
}
|
|
else version(Posix)
|
|
{
|
|
import core.stdc.stdio : printf;
|
|
import core.sys.posix.time;
|
|
struct Time
|
|
{
|
|
static long getUSecTime()
|
|
{
|
|
time_t time;
|
|
timespec spec;
|
|
|
|
clock_gettime(CLOCK_REALTIME, &spec);
|
|
|
|
//time = spec.tv_sec;
|
|
return spec.tv_sec * 1000_000 + spec.tv_nsec / 1000;//time / 1000_000;
|
|
|
|
/*LARGE_INTEGER time, freq;
|
|
QueryPerformanceFrequency(&freq);
|
|
QueryPerformanceCounter(&time);
|
|
return time.QuadPart / (freq.QuadPart / 1000_000);*/
|
|
}
|
|
}
|
|
} |