mirror of https://github.com/bjornbytes/lovr.git
Merge branch 'master' into dev
This commit is contained in:
commit
c1bb47d737
|
@ -303,14 +303,15 @@ endif()
|
|||
set(LOVR 1)
|
||||
link_libraries(${LOVR_LUA})
|
||||
file(GLOB LOVR_PLUGINS ${CMAKE_SOURCE_DIR}/plugins/*)
|
||||
foreach(plugin ${LOVR_PLUGINS})
|
||||
if(IS_DIRECTORY ${plugin} AND EXISTS ${plugin}/CMakeLists.txt)
|
||||
add_subdirectory(${plugin} "${CMAKE_CURRENT_BINARY_DIR}/plugins/lib")
|
||||
get_directory_property(PLUGIN_TARGETS DIRECTORY ${plugin} DEFINITION LOVR_PLUGIN_TARGETS)
|
||||
foreach(PLUGIN_PATH ${LOVR_PLUGINS})
|
||||
if(IS_DIRECTORY ${PLUGIN_PATH} AND EXISTS ${PLUGIN_PATH}/CMakeLists.txt)
|
||||
get_filename_component(PLUGIN "${PLUGIN_PATH}" NAME)
|
||||
add_subdirectory(${PLUGIN_PATH} "${CMAKE_CURRENT_BINARY_DIR}/plugins/${PLUGIN}")
|
||||
get_directory_property(PLUGIN_TARGETS DIRECTORY ${PLUGIN_PATH} DEFINITION LOVR_PLUGIN_TARGETS)
|
||||
if(NOT PLUGIN_TARGETS)
|
||||
get_directory_property(PLUGIN_TARGETS DIRECTORY ${plugin} BUILDSYSTEM_TARGETS)
|
||||
get_directory_property(PLUGIN_TARGETS DIRECTORY ${PLUGIN_PATH} BUILDSYSTEM_TARGETS)
|
||||
endif()
|
||||
set_target_properties(${PLUGIN_TARGETS} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/plugins/lib")
|
||||
set_target_properties(${PLUGIN_TARGETS} PROPERTIES LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/plugins/${PLUGIN}")
|
||||
list(APPEND ALL_PLUGIN_TARGETS ${PLUGIN_TARGETS})
|
||||
endif()
|
||||
endforeach()
|
||||
|
@ -342,6 +343,7 @@ endif()
|
|||
|
||||
set_target_properties(lovr PROPERTIES C_VISIBILITY_PRESET ${LOVR_SYMBOL_VISIBILITY})
|
||||
set_target_properties(lovr PROPERTIES C_STANDARD 11)
|
||||
set_target_properties(lovr PROPERTIES C_STANDARD_REQUIRED ON)
|
||||
target_include_directories(lovr PRIVATE src src/modules src/lib/stdatomic etc)
|
||||
target_link_libraries(lovr
|
||||
${LOVR_GLFW}
|
||||
|
@ -586,6 +588,9 @@ foreach(path ${LOVR_RESOURCES})
|
|||
file(WRITE ${output} "const unsigned char ${identifier}[] = {${data}};\nconst unsigned int ${identifier}_len = sizeof(${identifier});\n")
|
||||
endforeach()
|
||||
|
||||
# Add a custom target that is always out of date so libraries are always moved
|
||||
add_custom_target(move_libraries ALL)
|
||||
|
||||
# Platforms
|
||||
if(WIN32)
|
||||
target_sources(lovr PRIVATE src/core/os_win32.c)
|
||||
|
@ -608,7 +613,7 @@ if(WIN32)
|
|||
|
||||
function(move_dll)
|
||||
if(TARGET ${ARGV0})
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
$<TARGET_FILE_DIR:lovr>/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
|
@ -651,13 +656,13 @@ elseif(APPLE)
|
|||
if(TARGET ${ARGV0})
|
||||
get_target_property(TARGET_TYPE ${ARGV0} TYPE)
|
||||
if(${TARGET_TYPE} STREQUAL "MODULE_LIBRARY")
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
${EXE_DIR}/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_SONAME_FILE:${ARGV0}>
|
||||
${EXE_DIR}/$<TARGET_SONAME_FILE_NAME:${ARGV0}>
|
||||
|
@ -763,12 +768,13 @@ elseif(ANDROID)
|
|||
|
||||
# Copy plugin libraries to lib folder before packaging APK
|
||||
foreach(target ${ALL_PLUGIN_TARGETS})
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${target}>
|
||||
raw/lib/${ANDROID_ABI}/$<TARGET_FILE_NAME:${target}>
|
||||
)
|
||||
endforeach()
|
||||
add_dependencies(buildAPK move_libraries)
|
||||
endif()
|
||||
elseif(UNIX)
|
||||
if(LOVR_USE_LINUX_EGL)
|
||||
|
@ -786,13 +792,13 @@ elseif(UNIX)
|
|||
if(TARGET ${ARGV0})
|
||||
get_target_property(TARGET_TYPE ${ARGV0} TYPE)
|
||||
if(${TARGET_TYPE} STREQUAL "MODULE_LIBRARY")
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_FILE:${ARGV0}>
|
||||
${CMAKE_BINARY_DIR}/bin/$<TARGET_FILE_NAME:${ARGV0}>
|
||||
)
|
||||
else()
|
||||
add_custom_command(TARGET lovr POST_BUILD
|
||||
add_custom_command(TARGET move_libraries POST_BUILD
|
||||
COMMAND ${CMAKE_COMMAND} -E copy
|
||||
$<TARGET_SONAME_FILE:${ARGV0}>
|
||||
${CMAKE_BINARY_DIR}/bin/$<TARGET_SONAME_FILE_NAME:${ARGV0}>
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit 458984d7f59d1ae6dc1b597d94b02e4f7132eaba
|
||||
Subproject commit 885a90f8934d84121344ba8e4aa5159d5b496e08
|
|
@ -67,7 +67,8 @@ function lovr.boot()
|
|||
}
|
||||
|
||||
lovr.filesystem = require('lovr.filesystem')
|
||||
local hasConf, hasMain = lovr.filesystem.isFile('conf.lua'), lovr.filesystem.isFile('main.lua')
|
||||
local main = arg[0] and arg[0]:match('[^\\/]-%.lua$') or 'main.lua'
|
||||
local hasConf, hasMain = lovr.filesystem.isFile('conf.lua'), lovr.filesystem.isFile(main)
|
||||
if not lovr.filesystem.getSource() or not (hasConf or hasMain) then nogame() end
|
||||
|
||||
-- Shift args up in fused mode, instead of consuming one for the source path
|
||||
|
@ -110,7 +111,7 @@ function lovr.boot()
|
|||
|
||||
lovr.handlers = setmetatable({}, { __index = lovr })
|
||||
if not confOk then error(confError) end
|
||||
if hasMain then require 'main' end
|
||||
if hasMain then require(main:gsub('%.lua$', '')) end
|
||||
return lovr.run()
|
||||
end
|
||||
|
||||
|
|
|
@ -134,6 +134,41 @@ static int l_lovrHeadsetGetDisplayFrequency(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrHeadsetGetDisplayFrequencies(lua_State* L) {
|
||||
if (!lovrHeadsetInterface->getDisplayFrequencies) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
uint32_t count = 0;
|
||||
float* frequencies = lovrHeadsetInterface->getDisplayFrequencies(&count);
|
||||
if (!frequencies) {
|
||||
lua_pushnil(L);
|
||||
return 1;
|
||||
}
|
||||
|
||||
lua_settop(L, 0);
|
||||
lua_createtable(L, count, 0);
|
||||
for (uint32_t i = 0; i < count; ++i) {
|
||||
lua_pushnumber(L, frequencies[i]);
|
||||
lua_rawseti(L, 1, i + 1);
|
||||
}
|
||||
|
||||
free(frequencies);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrHeadsetSetDisplayFrequency(lua_State* L) {
|
||||
float frequency = luax_checkfloat(L, 1);
|
||||
bool res = false;
|
||||
if (lovrHeadsetInterface->setDisplayFrequency) {
|
||||
res = lovrHeadsetInterface->setDisplayFrequency(frequency);
|
||||
}
|
||||
lua_pushboolean(L, res);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrHeadsetGetViewCount(lua_State* L) {
|
||||
lua_pushinteger(L, lovrHeadsetInterface->getViewCount());
|
||||
return 1;
|
||||
|
@ -529,6 +564,8 @@ static const luaL_Reg lovrHeadset[] = {
|
|||
{ "getDisplayHeight", l_lovrHeadsetGetDisplayHeight },
|
||||
{ "getDisplayDimensions", l_lovrHeadsetGetDisplayDimensions },
|
||||
{ "getDisplayFrequency", l_lovrHeadsetGetDisplayFrequency },
|
||||
{ "getDisplayFrequencies", l_lovrHeadsetGetDisplayFrequencies },
|
||||
{ "setDisplayFrequency", l_lovrHeadsetSetDisplayFrequency },
|
||||
{ "getViewCount", l_lovrHeadsetGetViewCount },
|
||||
{ "getViewPose", l_lovrHeadsetGetViewPose },
|
||||
{ "getViewAngles", l_lovrHeadsetGetViewAngles },
|
||||
|
|
|
@ -367,6 +367,20 @@ static int l_lovrWorldIsCollisionEnabledBetween(lua_State* L) {
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldGetStepCount(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
int iterations = lovrWorldGetStepCount(world);
|
||||
lua_pushnumber(L, iterations);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int l_lovrWorldSetStepCount(lua_State* L) {
|
||||
World* world = luax_checktype(L, 1, World);
|
||||
int iterations = luaL_checkinteger(L, 2);
|
||||
lovrWorldSetStepCount(world, iterations);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const luaL_Reg lovrWorld[] = {
|
||||
{ "newCollider", l_lovrWorldNewCollider },
|
||||
{ "newBoxCollider", l_lovrWorldNewBoxCollider },
|
||||
|
@ -397,5 +411,7 @@ const luaL_Reg lovrWorld[] = {
|
|||
{ "disableCollisionBetween", l_lovrWorldDisableCollisionBetween },
|
||||
{ "enableCollisionBetween", l_lovrWorldEnableCollisionBetween },
|
||||
{ "isCollisionEnabledBetween", l_lovrWorldIsCollisionEnabledBetween },
|
||||
{ "getStepCount", l_lovrWorldGetStepCount },
|
||||
{ "setStepCount", l_lovrWorldSetStepCount },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
@ -35,10 +35,12 @@ int main(int argc, char** argv) {
|
|||
if (argc > 1 && (!strcmp(argv[1], "--help") || !strcmp(argv[1], "-h"))) {
|
||||
os_open_console();
|
||||
printf(
|
||||
"usage: lovr [options] [<folder>]\n"
|
||||
"usage: lovr [options] [<source>]\n\n"
|
||||
"options:\n"
|
||||
" -h, --help\t\tShow help and exit\n"
|
||||
" -v, --version\t\tShow version and exit\n"
|
||||
" --console\t\tAttach Windows console\n"
|
||||
" --console\t\tAttach Windows console\n\n"
|
||||
"<source> can be a Lua file, a folder, or a zip archive\n"
|
||||
);
|
||||
exit(0);
|
||||
}
|
||||
|
|
|
@ -214,7 +214,7 @@ bool lovrAudioInit(const char* spatializer, uint32_t sampleRate) {
|
|||
// SteamAudio's default frequency-dependent absorption coefficients for air
|
||||
state.absorption[0] = .0002f;
|
||||
state.absorption[1] = .0017f;
|
||||
state.absorption[1] = .0182f;
|
||||
state.absorption[2] = .0182f;
|
||||
|
||||
quat_identity(state.orientation);
|
||||
|
||||
|
|
|
@ -148,6 +148,22 @@ bool lovrFilesystemInit(const char* archive) {
|
|||
if (archive) {
|
||||
state.source[LOVR_PATH_MAX - 1] = '\0';
|
||||
strncpy(state.source, archive, LOVR_PATH_MAX - 1);
|
||||
|
||||
// If the command line parameter is a file, use its containing folder as the source
|
||||
size_t length = strlen(state.source);
|
||||
if (length > 4 && !memcmp(state.source + length - 4, ".lua", 4)) {
|
||||
char* slash = strrchr(state.source, '/');
|
||||
|
||||
if (slash) {
|
||||
*slash = '\0';
|
||||
} else if ((slash = strrchr(state.source, '\\')) != NULL) {
|
||||
*slash = '\0';
|
||||
} else {
|
||||
state.source[0] = '.';
|
||||
state.source[1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (lovrFilesystemMount(state.source, NULL, true, NULL)) {
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -117,6 +117,8 @@ typedef struct HeadsetInterface {
|
|||
HeadsetOrigin (*getOriginType)(void);
|
||||
void (*getDisplayDimensions)(uint32_t* width, uint32_t* height);
|
||||
float (*getDisplayFrequency)(void);
|
||||
float* (*getDisplayFrequencies)(uint32_t* count);
|
||||
bool (*setDisplayFrequency)(float);
|
||||
double (*getDisplayTime)(void);
|
||||
double (*getDeltaTime)(void);
|
||||
uint32_t (*getViewCount)(void);
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "core/maf.h"
|
||||
#include "core/os.h"
|
||||
#include "util.h"
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
|
@ -87,7 +88,9 @@ uintptr_t gpu_vk_get_queue(uint32_t* queueFamilyIndex, uint32_t* queueIndex);
|
|||
X(xrDestroyHandTrackerEXT)\
|
||||
X(xrLocateHandJointsEXT)\
|
||||
X(xrGetHandMeshFB)\
|
||||
X(xrGetDisplayRefreshRateFB)
|
||||
X(xrGetDisplayRefreshRateFB) \
|
||||
X(xrEnumerateDisplayRefreshRatesFB) \
|
||||
X(xrRequestDisplayRefreshRateFB)
|
||||
|
||||
#define XR_DECLARE(fn) static PFN_##fn fn;
|
||||
#define XR_LOAD(fn) xrGetInstanceProcAddr(state.instance, #fn, (PFN_xrVoidFunction*) &fn);
|
||||
|
@ -313,10 +316,14 @@ static bool openxr_init(float supersample, float offset, uint32_t msaa, bool ove
|
|||
for (uint32_t i = 0; i < extensionCount; i++) extensionProperties[i].type = XR_TYPE_EXTENSION_PROPERTIES;
|
||||
xrEnumerateInstanceExtensionProperties(NULL, extensionCount, &extensionCount, extensionProperties);
|
||||
|
||||
#ifdef __ANDROID__
|
||||
bool androidCreateInstanceExtension = false;
|
||||
#endif
|
||||
|
||||
// Extensions without a feature are required
|
||||
struct { const char* name; bool* feature; bool disable; } extensions[] = {
|
||||
#ifdef __ANDROID__
|
||||
{ "XR_KHR_android_create_instance", NULL, false },
|
||||
{ "XR_KHR_android_create_instance", &androidCreateInstanceExtension, false },
|
||||
#endif
|
||||
#ifdef LOVR_VK
|
||||
{ "XR_KHR_vulkan_enable2", NULL, false },
|
||||
|
@ -345,6 +352,7 @@ static bool openxr_init(float supersample, float offset, uint32_t msaa, bool ove
|
|||
XrInstanceCreateInfo info = {
|
||||
.type = XR_TYPE_INSTANCE_CREATE_INFO,
|
||||
#ifdef __ANDROID__
|
||||
// harmless to include even if not available from runtime
|
||||
.next = &(XrInstanceCreateInfoAndroidKHR) {
|
||||
.type = XR_TYPE_INSTANCE_CREATE_INFO_ANDROID_KHR,
|
||||
.applicationVM = activity->vm,
|
||||
|
@ -507,7 +515,7 @@ static bool openxr_init(float supersample, float offset, uint32_t msaa, bool ove
|
|||
{ 0, NULL, "vibrate", XR_ACTION_TYPE_VIBRATION_OUTPUT, 2, hands, "Vibrate" }
|
||||
};
|
||||
|
||||
_Static_assert(COUNTOF(actionInfo) == MAX_ACTIONS, "Unbalanced action table!");
|
||||
static_assert(COUNTOF(actionInfo) == MAX_ACTIONS, "Unbalanced action table!");
|
||||
|
||||
if (!state.features.viveTrackers) {
|
||||
actionInfo[ACTION_TRACKER_POSE].countSubactionPaths = 0;
|
||||
|
@ -994,6 +1002,23 @@ static float openxr_getDisplayFrequency(void) {
|
|||
return frequency;
|
||||
}
|
||||
|
||||
static float* openxr_getDisplayFrequencies(uint32_t* count) {
|
||||
if (!state.features.refreshRate || !count) return NULL;
|
||||
XR(xrEnumerateDisplayRefreshRatesFB(state.session, 0, count, NULL));
|
||||
float *frequencies = malloc(*count * sizeof(float));
|
||||
lovrAssert(frequencies, "Out of Memory");
|
||||
XR(xrEnumerateDisplayRefreshRatesFB(state.session, *count, count, frequencies));
|
||||
return frequencies;
|
||||
}
|
||||
|
||||
static bool openxr_setDisplayFrequency(float frequency) {
|
||||
if (!state.features.refreshRate) return false;
|
||||
XrResult res = xrRequestDisplayRefreshRateFB(state.session, frequency);
|
||||
if (res == XR_ERROR_DISPLAY_REFRESH_RATE_UNSUPPORTED_FB) return false;
|
||||
XR(res);
|
||||
return true;
|
||||
}
|
||||
|
||||
static double openxr_getDisplayTime(void) {
|
||||
return state.frameState.predictedDisplayTime / 1e9;
|
||||
}
|
||||
|
@ -1763,6 +1788,8 @@ HeadsetInterface lovrHeadsetOpenXRDriver = {
|
|||
.getOriginType = openxr_getOriginType,
|
||||
.getDisplayDimensions = openxr_getDisplayDimensions,
|
||||
.getDisplayFrequency = openxr_getDisplayFrequency,
|
||||
.getDisplayFrequencies = openxr_getDisplayFrequencies,
|
||||
.setDisplayFrequency = openxr_setDisplayFrequency,
|
||||
.getDisplayTime = openxr_getDisplayTime,
|
||||
.getDeltaTime = openxr_getDeltaTime,
|
||||
.getViewCount = openxr_getViewCount,
|
||||
|
|
|
@ -191,6 +191,14 @@ void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* u
|
|||
dJointGroupEmpty(world->contactGroup);
|
||||
}
|
||||
|
||||
int lovrWorldGetStepCount(World* world) {
|
||||
return dWorldGetQuickStepNumIterations(world->id);
|
||||
}
|
||||
|
||||
void lovrWorldSetStepCount(World* world, int iterations) {
|
||||
dWorldSetQuickStepNumIterations(world->id, iterations);
|
||||
}
|
||||
|
||||
void lovrWorldComputeOverlaps(World* world) {
|
||||
arr_clear(&world->overlaps);
|
||||
dSpaceCollide(world->space, world, customNearCallback);
|
||||
|
@ -918,6 +926,7 @@ void lovrShapeGetAABB(Shape* shape, float aabb[6]) {
|
|||
}
|
||||
|
||||
SphereShape* lovrSphereShapeCreate(float radius) {
|
||||
lovrCheck(radius > 0.f, "SphereShape radius must be positive");
|
||||
SphereShape* sphere = calloc(1, sizeof(SphereShape));
|
||||
lovrAssert(sphere, "Out of memory");
|
||||
sphere->ref = 1;
|
||||
|
@ -932,6 +941,7 @@ float lovrSphereShapeGetRadius(SphereShape* sphere) {
|
|||
}
|
||||
|
||||
void lovrSphereShapeSetRadius(SphereShape* sphere, float radius) {
|
||||
lovrCheck(radius > 0.f, "SphereShape radius must be positive");
|
||||
dGeomSphereSetRadius(sphere->id, radius);
|
||||
}
|
||||
|
||||
|
@ -954,10 +964,12 @@ void lovrBoxShapeGetDimensions(BoxShape* box, float* x, float* y, float* z) {
|
|||
}
|
||||
|
||||
void lovrBoxShapeSetDimensions(BoxShape* box, float x, float y, float z) {
|
||||
lovrCheck(x > 0.f && y > 0.f && z > 0.f, "BoxShape dimensions must be positive");
|
||||
dGeomBoxSetLengths(box->id, x, y, z);
|
||||
}
|
||||
|
||||
CapsuleShape* lovrCapsuleShapeCreate(float radius, float length) {
|
||||
lovrCheck(radius > 0.f && length > 0.f, "CapsuleShape dimensions must be positive");
|
||||
CapsuleShape* capsule = calloc(1, sizeof(CapsuleShape));
|
||||
lovrAssert(capsule, "Out of memory");
|
||||
capsule->ref = 1;
|
||||
|
@ -974,6 +986,7 @@ float lovrCapsuleShapeGetRadius(CapsuleShape* capsule) {
|
|||
}
|
||||
|
||||
void lovrCapsuleShapeSetRadius(CapsuleShape* capsule, float radius) {
|
||||
lovrCheck(radius > 0.f, "CapsuleShape dimensions must be positive");
|
||||
dGeomCapsuleSetParams(capsule->id, radius, lovrCapsuleShapeGetLength(capsule));
|
||||
}
|
||||
|
||||
|
@ -984,10 +997,12 @@ float lovrCapsuleShapeGetLength(CapsuleShape* capsule) {
|
|||
}
|
||||
|
||||
void lovrCapsuleShapeSetLength(CapsuleShape* capsule, float length) {
|
||||
lovrCheck(length > 0.f, "CapsuleShape dimensions must be positive");
|
||||
dGeomCapsuleSetParams(capsule->id, lovrCapsuleShapeGetRadius(capsule), length);
|
||||
}
|
||||
|
||||
CylinderShape* lovrCylinderShapeCreate(float radius, float length) {
|
||||
lovrCheck(radius > 0.f && length > 0.f, "CylinderShape dimensions must be positive");
|
||||
CylinderShape* cylinder = calloc(1, sizeof(CylinderShape));
|
||||
lovrAssert(cylinder, "Out of memory");
|
||||
cylinder->ref = 1;
|
||||
|
@ -1004,6 +1019,7 @@ float lovrCylinderShapeGetRadius(CylinderShape* cylinder) {
|
|||
}
|
||||
|
||||
void lovrCylinderShapeSetRadius(CylinderShape* cylinder, float radius) {
|
||||
lovrCheck(radius > 0.f, "CylinderShape dimensions must be positive");
|
||||
dGeomCylinderSetParams(cylinder->id, radius, lovrCylinderShapeGetLength(cylinder));
|
||||
}
|
||||
|
||||
|
@ -1014,6 +1030,7 @@ float lovrCylinderShapeGetLength(CylinderShape* cylinder) {
|
|||
}
|
||||
|
||||
void lovrCylinderShapeSetLength(CylinderShape* cylinder, float length) {
|
||||
lovrCheck(length > 0.f, "CylinderShape dimensions must be positive");
|
||||
dGeomCylinderSetParams(cylinder->id, lovrCylinderShapeGetRadius(cylinder), length);
|
||||
}
|
||||
|
||||
|
|
|
@ -42,6 +42,8 @@ World* lovrWorldCreate(float xg, float yg, float zg, bool allowSleep, const char
|
|||
void lovrWorldDestroy(void* ref);
|
||||
void lovrWorldDestroyData(World* world);
|
||||
void lovrWorldUpdate(World* world, float dt, CollisionResolver resolver, void* userdata);
|
||||
int lovrWorldGetStepCount(World* world);
|
||||
void lovrWorldSetStepCount(World* world, int iterations);
|
||||
void lovrWorldComputeOverlaps(World* world);
|
||||
int lovrWorldGetNextOverlap(World* world, Shape** a, Shape** b);
|
||||
int lovrWorldCollide(World* world, Shape* a, Shape* b, float friction, float restitution);
|
||||
|
|
14
src/util.c
14
src/util.c
|
@ -65,15 +65,6 @@ void* arr_alloc(void* data, size_t size) {
|
|||
}
|
||||
|
||||
// Hashmap
|
||||
static uint32_t prevpo2(uint32_t x) {
|
||||
x |= x >> 1;
|
||||
x |= x >> 2;
|
||||
x |= x >> 4;
|
||||
x |= x >> 8;
|
||||
x |= x >> 16;
|
||||
return x - (x >> 1);
|
||||
}
|
||||
|
||||
static void map_rehash(map_t* map) {
|
||||
map_t old = *map;
|
||||
map->size <<= 1;
|
||||
|
@ -110,7 +101,10 @@ static inline uint64_t map_find(map_t* map, uint64_t hash) {
|
|||
}
|
||||
|
||||
void map_init(map_t* map, uint32_t n) {
|
||||
map->size = prevpo2(n) + !n;
|
||||
map->size = 1;
|
||||
while (map->size + (map->size >> 1) < n) {
|
||||
map->size <<= 1;
|
||||
}
|
||||
map->used = 0;
|
||||
map->hashes = NULL;
|
||||
map_rehash(map);
|
||||
|
|
Loading…
Reference in New Issue