From f047019d550da2ce392000d4769e53206773a06a Mon Sep 17 00:00:00 2001 From: ecker Date: Thu, 26 Oct 2023 22:29:00 -0500 Subject: [PATCH] Dreamcast fixes, also that experimental float16/quantized uint16_t triangle mesh support --- CMakeLists.txt | 11 ++ .../collision/TriangleVertexArray.h | 24 +++- .../collision/broadphase/DynamicAABBTree.h | 2 +- include/reactphysics3d/configuration.h | 14 +- include/reactphysics3d/containers/Map.h | 6 +- .../reactphysics3d/systems/BroadPhaseSystem.h | 6 +- include/reactphysics3d/utils/DefaultLogger.h | 6 +- src/collision/TriangleVertexArray.cpp | 120 ++++++++++++++++++ src/collision/broadphase/DynamicAABBTree.cpp | 6 +- src/collision/shapes/ConcaveMeshShape.cpp | 4 +- src/systems/BroadPhaseSystem.cpp | 2 +- 11 files changed, 180 insertions(+), 21 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c18a8c65..8a15ef31 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,15 @@ # Minimum cmake version required cmake_minimum_required(VERSION 3.8) +set(CMAKE_C_COMPILER_WORKS 1) +set(CMAKE_CXX_COMPILER_WORKS 1) + +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 -fno-exceptions") +else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++2b") +endif() + # Project configuration project(ReactPhysics3D VERSION 0.9.0 LANGUAGES CXX) @@ -24,6 +33,8 @@ 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") + # Options option(RP3D_COMPILE_TESTBED "Select this if you want to build the testbed application with demos" OFF) option(RP3D_COMPILE_TESTS "Select this if you want to build the unit tests" OFF) 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/collision/broadphase/DynamicAABBTree.h b/include/reactphysics3d/collision/broadphase/DynamicAABBTree.h index ac80cfe9..17e2de59 100644 --- a/include/reactphysics3d/collision/broadphase/DynamicAABBTree.h +++ b/include/reactphysics3d/collision/broadphase/DynamicAABBTree.h @@ -245,7 +245,7 @@ class DynamicAABBTree { size_t endIndex, Array>& outOverlappingNodes) const; /// Report all shapes overlapping with the AABB given in parameter. - void reportAllShapesOverlappingWithAABB(const AABB& aabb, Array& overlappingNodes) const; + void reportAllShapesOverlappingWithAABB(const AABB& aabb, Array& overlappingNodes) const; /// Ray casting method void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const; diff --git a/include/reactphysics3d/configuration.h b/include/reactphysics3d/configuration.h index 6f2de958..bd8bda58 100644 --- a/include/reactphysics3d/configuration.h +++ b/include/reactphysics3d/configuration.h @@ -29,6 +29,7 @@ // Libraries #include #include +#include #include #include #include @@ -55,14 +56,21 @@ #define RP3D_FORCE_INLINE inline #endif + +#if defined(RP3D_NO_EXCEPTIONS) + #define THROW(...) abort() +#else + #define THROW(...) throw(__VA_ARGS__) +#endif + /// Namespace reactphysics3d namespace reactphysics3d { // ------------------- Type definitions ------------------- // -using uint = unsigned int; -using uchar = unsigned char; -using ushort = unsigned short; +using uint = uint32_t; +using uchar = uint8_t; +using ushort = uint16_t; using luint = long unsigned int; using int8 = std::int8_t; 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/systems/BroadPhaseSystem.h b/include/reactphysics3d/systems/BroadPhaseSystem.h index d06b5cb3..f9a40a9d 100644 --- a/include/reactphysics3d/systems/BroadPhaseSystem.h +++ b/include/reactphysics3d/systems/BroadPhaseSystem.h @@ -51,10 +51,10 @@ class AABBOverlapCallback : public DynamicAABBTreeOverlapCallback { public: - Array& mOverlappingNodes; + Array& mOverlappingNodes; // Constructor - AABBOverlapCallback(Array& overlappingNodes) : mOverlappingNodes(overlappingNodes) { + AABBOverlapCallback(Array& overlappingNodes) : mOverlappingNodes(overlappingNodes) { } @@ -126,7 +126,7 @@ class BroadPhaseSystem { /// Set with the broad-phase IDs of all collision shapes that have moved (or have been /// created) during the last simulation step. Those are the shapes that need to be tested /// for overlapping in the next simulation step. - Set mMovedShapes; + Set mMovedShapes; /// Reference to the collision detection object CollisionDetectionSystem& mCollisionDetection; diff --git a/include/reactphysics3d/utils/DefaultLogger.h b/include/reactphysics3d/utils/DefaultLogger.h index f4d2e927..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 @@ -385,7 +385,7 @@ class DefaultLogger : public Logger { virtual void write(const time_t& time, const std::string& physicsWorldName, const std::string& message, Level level, Category category, const char* filename, int lineNumber) override { - if (static_cast(level) <= static_cast(maxLevelFlag)) { + if (static_cast(level) <= static_cast(maxLevelFlag)) { mFileStream << formatter->format(time, physicsWorldName, message, level, category, filename, lineNumber) << std::endl; } } @@ -425,7 +425,7 @@ class DefaultLogger : public Logger { virtual void write(const time_t& time, const std::string& physicsWorldName, const std::string& message, Level level, Category category, const char* filename, int lineNumber) override { - if (static_cast(level) <= static_cast(maxLevelFlag)) { + if (static_cast(level) <= static_cast(maxLevelFlag)) { mOutputStream << formatter->format(time, physicsWorldName, message, level, category, filename, lineNumber) << std::endl << std::flush; } } 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); } diff --git a/src/collision/broadphase/DynamicAABBTree.cpp b/src/collision/broadphase/DynamicAABBTree.cpp index 333d922b..835ab984 100644 --- a/src/collision/broadphase/DynamicAABBTree.cpp +++ b/src/collision/broadphase/DynamicAABBTree.cpp @@ -131,7 +131,7 @@ int32 DynamicAABBTree::allocateNode() { } // Release a node -void DynamicAABBTree::releaseNode(int nodeID) { +void DynamicAABBTree::releaseNode(int32 nodeID) { assert(mNbNodes > 0); assert(nodeID >= 0 && nodeID < mNbAllocatedNodes); @@ -217,7 +217,7 @@ bool DynamicAABBTree::updateObject(int32 nodeID, const AABB& newAABB, bool force // Insert a leaf node in the tree. The process of inserting a new leaf node // in the dynamic tree is described in the book "Introduction to Game Physics // with Box2D" by Ian Parberry. -void DynamicAABBTree::insertLeafNode(int nodeID) { +void DynamicAABBTree::insertLeafNode(int32 nodeID) { // If the tree is empty if (mRootNodeID == TreeNode::NULL_TREE_NODE) { @@ -347,7 +347,7 @@ void DynamicAABBTree::insertLeafNode(int nodeID) { } // Remove a leaf node from the tree -void DynamicAABBTree::removeLeafNode(int nodeID) { +void DynamicAABBTree::removeLeafNode(int32 nodeID) { assert(nodeID >= 0 && nodeID < mNbAllocatedNodes); assert(mNodes[nodeID].isLeaf()); diff --git a/src/collision/shapes/ConcaveMeshShape.cpp b/src/collision/shapes/ConcaveMeshShape.cpp index 3c4294c3..65e2c786 100644 --- a/src/collision/shapes/ConcaveMeshShape.cpp +++ b/src/collision/shapes/ConcaveMeshShape.cpp @@ -139,7 +139,7 @@ void ConcaveMeshShape::computeOverlappingTriangles(const AABB& localAABB, Array< aabb.applyScale(Vector3(decimal(1.0) / mScale.x, decimal(1.0) / mScale.y, decimal(1.0) / mScale.z)); // Compute the nodes of the internal AABB tree that are overlapping with the AABB - Array overlappingNodes(allocator, 64); + Array overlappingNodes(allocator, 64); mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes); const uint32 nbOverlappingNodes = static_cast(overlappingNodes.size()); @@ -230,7 +230,7 @@ decimal ConcaveMeshRaycastCallback::raycastBroadPhaseShape(int32 nodeId, const R // Raycast all collision shapes that have been collected void ConcaveMeshRaycastCallback::raycastTriangles() { - Array::Iterator it; + Array::Iterator it; decimal smallestHitFraction = mRay.maxFraction; for (it = mHitAABBNodes.begin(); it != mHitAABBNodes.end(); ++it) { diff --git a/src/systems/BroadPhaseSystem.cpp b/src/systems/BroadPhaseSystem.cpp index 7fa3c06f..eda42f93 100644 --- a/src/systems/BroadPhaseSystem.cpp +++ b/src/systems/BroadPhaseSystem.cpp @@ -214,7 +214,7 @@ void BroadPhaseSystem::computeOverlappingPairs(MemoryManager& memoryManager, Arr RP3D_PROFILE("BroadPhaseSystem::computeOverlappingPairs()", mProfiler); // Get the array of the colliders that have moved or have been created in the last frame - Array shapesToTest = mMovedShapes.toArray(memoryManager.getHeapAllocator()); + Array shapesToTest = mMovedShapes.toArray(memoryManager.getHeapAllocator()); // Ask the dynamic AABB tree to report all collision shapes that overlap with the shapes to test mDynamicAABBTree.reportAllShapesOverlappingWithShapes(shapesToTest, 0, static_cast(shapesToTest.size()), overlappingNodes);