diff --git a/CMakeLists.txt b/CMakeLists.txt index 411310f9..89b62aee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -27,7 +27,12 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules) # Enable testing enable_testing() -set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os ${KOS_CPPFLAGS} ${KOS_INC_PATHS} ${KOS_LIB_PATHS} -std=c++17") + +if(DEFINED ENV{KOS_CPPFLAGS}) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Os ${KOS_CPPFLAGS} ${KOS_INC_PATHS} ${KOS_LIB_PATHS} -DRP3D_NO_EXCEPTIONS -std=c++17 -w -Os -g -ffunction-sections -fdata-sections -Wl,--gc-sections -fstrict-aliasing -ffast-math -fno-unroll-all-loops -fno-optimize-sibling-calls -fschedule-insns2 -fomit-frame-pointer -DUF_NO_EXCEPTIONS -fno-exceptions") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2b") +endif() # Options option(RP3D_COMPILE_TESTBED "Select this if you want to build the testbed application with demos" OFF) diff --git a/README.md b/README.md index be0a7a36..323d5abf 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -This fork fixes some inconsistencies to get it to compile on 32-bit systems. +This fork fixes some inconsistencies to get it to compile on 32-bit systems (such as the Sega Dreamcast), and support for float16/bfloat16 triangle meshes (using C++23's standardized types). --- diff --git a/include/reactphysics3d/collision/TriangleVertexArray.h b/include/reactphysics3d/collision/TriangleVertexArray.h index 046698bb..5a95d79c 100644 --- a/include/reactphysics3d/collision/TriangleVertexArray.h +++ b/include/reactphysics3d/collision/TriangleVertexArray.h @@ -49,10 +49,30 @@ class TriangleVertexArray { public: /// Data type for the vertices in the array - enum class VertexDataType {VERTEX_FLOAT_TYPE, VERTEX_DOUBLE_TYPE}; + enum class VertexDataType { + VERTEX_SHORT_TYPE, + VERTEX_FLOAT_TYPE, + VERTEX_DOUBLE_TYPE, + #if __STDCPP_FLOAT16_T__ + VERTEX_FLOAT16_TYPE, + #endif + #if __STDCPP_BFLOAT16_T__ + VERTEX_BFLOAT16_TYPE, + #endif + }; /// Data type for the vertex normals in the array - enum class NormalDataType {NORMAL_FLOAT_TYPE, NORMAL_DOUBLE_TYPE}; + enum class NormalDataType { + NORMAL_SHORT_TYPE, + NORMAL_FLOAT_TYPE, + NORMAL_DOUBLE_TYPE, + #if __STDCPP_FLOAT16_T__ + NORMAL_FLOAT16_TYPE, + #endif + #if __STDCPP_BFLOAT16_T__ + NORMAL_BFLOAT16_TYPE, + #endif + }; /// Data type for the indices in the array enum class IndexDataType {INDEX_INTEGER_TYPE, INDEX_SHORT_TYPE}; diff --git a/include/reactphysics3d/configuration.h b/include/reactphysics3d/configuration.h index 9f6776f5..ab37f87e 100644 --- a/include/reactphysics3d/configuration.h +++ b/include/reactphysics3d/configuration.h @@ -24,11 +24,12 @@ ********************************************************************************/ #ifndef REACTPHYSICS3D_CONFIGURATION_H -#define REACTPHYSICS3D_CONFIGURATION_H +#define REACTPHYSICS3D_CONFIGURATION_H // Libraries #include #include +#include #include #include #include @@ -55,13 +56,21 @@ #define RP3D_FORCE_INLINE inline #endif -namespace std { - template < typename T > std::string to_string( const T& n ) { - std::ostringstream stm ; - stm << n ; - return stm.str() ; +#if defined(RP3D_DEFINE_TOSTRING) + namespace std { + template < typename T > std::string to_string( const T& n ) { + std::ostringstream stm ; + stm << n ; + return stm.str() ; + } } -} +#endif + +#if defined(RP3D_NO_EXCEPTIONS) + #define THROW(...) abort() +#else + #define THROW(...) throw(__VA_ARGS__) +#endif /// Namespace reactphysics3d namespace reactphysics3d { diff --git a/include/reactphysics3d/containers/Map.h b/include/reactphysics3d/containers/Map.h index aadf9fa6..a3e6de33 100755 --- a/include/reactphysics3d/containers/Map.h +++ b/include/reactphysics3d/containers/Map.h @@ -383,7 +383,7 @@ class Map { } else { assert(false); - throw std::runtime_error("The key and value pair already exists in the map"); + THROW(std::runtime_error("The key and value pair already exists in the map")); } } } @@ -569,7 +569,7 @@ class Map { if (entry == INVALID_INDEX) { assert(false); - throw std::runtime_error("No item with given key has been found in the map"); + THROW(std::runtime_error("No item with given key has been found in the map")); } return mEntries[entry].second; @@ -582,7 +582,7 @@ class Map { if (entry == INVALID_INDEX) { assert(false); - throw std::runtime_error("No item with given key has been found in the map"); + THROW(std::runtime_error("No item with given key has been found in the map")); } return mEntries[entry].second; diff --git a/include/reactphysics3d/utils/DefaultLogger.h b/include/reactphysics3d/utils/DefaultLogger.h index 2a3ab30d..0f43fd5b 100644 --- a/include/reactphysics3d/utils/DefaultLogger.h +++ b/include/reactphysics3d/utils/DefaultLogger.h @@ -361,7 +361,7 @@ class DefaultLogger : public Logger { mFileStream(filePath, std::ios::binary) { if(!mFileStream.is_open()) { - throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); + THROW(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); } // Write the header diff --git a/include/reactphysics3d/utils/Profiler.h b/include/reactphysics3d/utils/Profiler.h index b65a19d6..25b5564f 100644 --- a/include/reactphysics3d/utils/Profiler.h +++ b/include/reactphysics3d/utils/Profiler.h @@ -230,7 +230,7 @@ class Profiler { mFileStream(filePath, std::ios::binary) { if(!mFileStream.is_open()) { - throw(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); + THROW(std::runtime_error("ReactPhysics3D Logger: Unable to open an output stream to file " + mFilePath)); } } diff --git a/src/collision/TriangleVertexArray.cpp b/src/collision/TriangleVertexArray.cpp index 0e738ca5..c27abb83 100644 --- a/src/collision/TriangleVertexArray.cpp +++ b/src/collision/TriangleVertexArray.cpp @@ -28,6 +28,38 @@ #include #include +#if __STDCPP_BFLOAT16_T__ || __STDCPP_FLOAT16_T__ + #include +#endif + +namespace { + uint16_t quantize( float v ) { + union { float f; uint32_t ui; } u = {v}; + uint32_t ui = u.ui; + + int s = (ui >> 16) & 0x8000; + int em = ui & 0x7fffffff; + + int h = (em - (112 << 23) + (1 << 12)) >> 13; + h = (em < (113 << 23)) ? 0 : h; + h = (em >= (143 << 23)) ? 0x7c00 : h; + h = (em > (255 << 23)) ? 0x7e00 : h; + + return (uint16_t)(s | h); + } + float dequantize( uint16_t h ) { + uint32_t s = unsigned(h & 0x8000) << 16; + int em = h & 0x7fff; + int r = (em + (112 << 10)) << 13; + r = (em < (1 << 10)) ? 0 : r; + r += (em >= (31 << 10)) ? (112 << 23) : 0; + + union { float f; uint32_t ui; } u; + u.ui = s | r; + return u.f; + } +} + using namespace reactphysics3d; // Constructor without vertices normals @@ -253,6 +285,28 @@ void TriangleVertexArray::getTriangleVertices(uint32 triangleIndex, Vector3* out outTriangleVertices[k][1] = decimal(vertices[1]); outTriangleVertices[k][2] = decimal(vertices[2]); } + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_SHORT_TYPE) { + const uint16_t* vertices = static_cast(vertexPointer); + outTriangleVertices[k][0] = decimal(::dequantize(vertices[0])); + outTriangleVertices[k][1] = decimal(::dequantize(vertices[1])); + outTriangleVertices[k][2] = decimal(::dequantize(vertices[2])); + } + #if __STDCPP_FLOAT16_T__ + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_FLOAT16_TYPE) { + const std::float16_t* vertices = static_cast(vertexPointer); + outTriangleVertices[k][0] = decimal(vertices[0]); + outTriangleVertices[k][1] = decimal(vertices[1]); + outTriangleVertices[k][2] = decimal(vertices[2]); + } + #endif + #if __STDCPP_BFLOAT16_T__ + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_BFLOAT16_TYPE) { + const std::bfloat16_t* vertices = static_cast(vertexPointer); + outTriangleVertices[k][0] = decimal(vertices[0]); + outTriangleVertices[k][1] = decimal(vertices[1]); + outTriangleVertices[k][2] = decimal(vertices[2]); + } + #endif else { assert(false); } @@ -291,6 +345,28 @@ void TriangleVertexArray::getTriangleVerticesNormals(uint32 triangleIndex, Vecto outTriangleVerticesNormals[k][1] = decimal(normal[1]); outTriangleVerticesNormals[k][2] = decimal(normal[2]); } + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_SHORT_TYPE) { + const uint16_t* normal = static_cast(vertexNormalPointer); + outTriangleVerticesNormals[k][0] = decimal(dequantize(normal[0])); + outTriangleVerticesNormals[k][1] = decimal(dequantize(normal[1])); + outTriangleVerticesNormals[k][2] = decimal(dequantize(normal[2])); + } + #if __STDCPP_FLOAT16_T__ + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_FLOAT16_TYPE) { + const std::float16_t* normal = static_cast(vertexNormalPointer); + outTriangleVerticesNormals[k][0] = decimal(normal[0]); + outTriangleVerticesNormals[k][1] = decimal(normal[1]); + outTriangleVerticesNormals[k][2] = decimal(normal[2]); + } + #endif + #if __STDCPP_BFLOAT16_T__ + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_BFLOAT16_TYPE) { + const std::bfloat16_t* normal = static_cast(vertexNormalPointer); + outTriangleVerticesNormals[k][0] = decimal(normal[0]); + outTriangleVerticesNormals[k][1] = decimal(normal[1]); + outTriangleVerticesNormals[k][2] = decimal(normal[2]); + } + #endif else { assert(false); } @@ -322,6 +398,28 @@ void TriangleVertexArray::getVertex(uint32 vertexIndex, Vector3* outVertex) { (*outVertex)[1] = decimal(vertices[1]); (*outVertex)[2] = decimal(vertices[2]); } + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_SHORT_TYPE) { + const uint16_t* vertices = static_cast(vertexPointer); + (*outVertex)[0] = decimal(dequantize(vertices[0])); + (*outVertex)[1] = decimal(dequantize(vertices[1])); + (*outVertex)[2] = decimal(dequantize(vertices[2])); + } +#if __STDCPP_FLOAT16_T__ + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_FLOAT16_TYPE) { + const std::float16_t* vertices = static_cast(vertexPointer); + (*outVertex)[0] = decimal(vertices[0]); + (*outVertex)[1] = decimal(vertices[1]); + (*outVertex)[2] = decimal(vertices[2]); + } +#endif +#if __STDCPP_BFLOAT16_T__ + else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_BFLOAT16_TYPE) { + const std::bfloat16_t* vertices = static_cast(vertexPointer); + (*outVertex)[0] = decimal(vertices[0]); + (*outVertex)[1] = decimal(vertices[1]); + (*outVertex)[2] = decimal(vertices[2]); + } +#endif else { assert(false); } @@ -352,6 +450,28 @@ void TriangleVertexArray::getNormal(uint32 vertexIndex, Vector3* outNormal) { (*outNormal)[1] = decimal(normal[1]); (*outNormal)[2] = decimal(normal[2]); } + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_SHORT_TYPE) { + const uint16_t* normal = static_cast(vertexNormalPointer); + (*outNormal)[0] = decimal(dequantize(normal[0])); + (*outNormal)[1] = decimal(dequantize(normal[1])); + (*outNormal)[2] = decimal(dequantize(normal[2])); + } +#if __STDCPP_FLOAT16_T__ + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_FLOAT16_TYPE) { + const std::float16_t* normal = static_cast(vertexNormalPointer); + (*outNormal)[0] = decimal(normal[0]); + (*outNormal)[1] = decimal(normal[1]); + (*outNormal)[2] = decimal(normal[2]); + } +#endif +#if __STDCPP_BFLOAT16_T__ + else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_BFLOAT16_TYPE) { + const std::bfloat16_t* normal = static_cast(vertexNormalPointer); + (*outNormal)[0] = decimal(normal[0]); + (*outNormal)[1] = decimal(normal[1]); + (*outNormal)[2] = decimal(normal[2]); + } +#endif else { assert(false); }