Dreamcast fixes, also that experimental float16/quantized uint16_t triangle mesh support

This commit is contained in:
mrq 2023-10-26 22:39:01 -05:00
parent bdc3153f55
commit f61c6c5713
14 changed files with 183 additions and 17 deletions

4
.gitignore vendored
View File

@ -1,3 +1,7 @@
#
/build*/
# Compiled source # # Compiled source #
################### ###################
*.com *.com

View File

@ -1,6 +1,11 @@
# Minimum cmake version required # Minimum cmake version required
cmake_minimum_required(VERSION 3.8) cmake_minimum_required(VERSION 3.8)
if(DEFINED ENV{KOS_CPPFLAGS})
set(CMAKE_C_COMPILER_WORKS 1)
set(CMAKE_CXX_COMPILER_WORKS 1)
endif()
# Project configuration # Project configuration
project(ReactPhysics3D VERSION 0.8.0 LANGUAGES CXX) project(ReactPhysics3D VERSION 0.8.0 LANGUAGES CXX)
@ -24,6 +29,12 @@ set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/CMakeModules)
# Enable testing # Enable testing
enable_testing() enable_testing()
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()
# Options # Options
option(RP3D_COMPILE_TESTBED "Select this if you want to build the testbed application with demos" OFF) 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) option(RP3D_COMPILE_TESTS "Select this if you want to build the unit tests" OFF)

View File

@ -1,3 +1,7 @@
This fork fixes some inconsistencies to get it to compile on 32-bit systems.
---
[![Travis Build Status](https://travis-ci.org/DanielChappuis/reactphysics3d.svg?branch=master)](https://travis-ci.org/DanielChappuis/reactphysics3d) [![Travis Build Status](https://travis-ci.org/DanielChappuis/reactphysics3d.svg?branch=master)](https://travis-ci.org/DanielChappuis/reactphysics3d)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/3ae24e998e304e4da78ec848eade9e3a)](https://www.codacy.com/app/chappuis.daniel/reactphysics3d?utm_source=github.com&utm_medium=referral&utm_content=DanielChappuis/reactphysics3d&utm_campaign=Badge_Grade) [![Codacy Badge](https://api.codacy.com/project/badge/Grade/3ae24e998e304e4da78ec848eade9e3a)](https://www.codacy.com/app/chappuis.daniel/reactphysics3d?utm_source=github.com&utm_medium=referral&utm_content=DanielChappuis/reactphysics3d&utm_campaign=Badge_Grade)
[![codecov.io](https://codecov.io/github/DanielChappuis/reactphysics3d/coverage.svg?branch=master)](https://codecov.io/github/DanielChappuis/reactphysics3d?branch=master) [![codecov.io](https://codecov.io/github/DanielChappuis/reactphysics3d/coverage.svg?branch=master)](https://codecov.io/github/DanielChappuis/reactphysics3d?branch=master)

View File

@ -49,10 +49,30 @@ class TriangleVertexArray {
public: public:
/// Data type for the vertices in the array /// 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 /// 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 /// Data type for the indices in the array
enum class IndexDataType {INDEX_INTEGER_TYPE, INDEX_SHORT_TYPE}; enum class IndexDataType {INDEX_INTEGER_TYPE, INDEX_SHORT_TYPE};

View File

@ -240,7 +240,7 @@ class DynamicAABBTree {
size_t endIndex, List<Pair<int32, int32>>& outOverlappingNodes) const; size_t endIndex, List<Pair<int32, int32>>& outOverlappingNodes) const;
/// Report all shapes overlapping with the AABB given in parameter. /// Report all shapes overlapping with the AABB given in parameter.
void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int>& overlappingNodes) const; void reportAllShapesOverlappingWithAABB(const AABB& aabb, List<int32>& overlappingNodes) const;
/// Ray casting method /// Ray casting method
void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const; void raycast(const Ray& ray, DynamicAABBTreeRaycastCallback& callback) const;

View File

@ -29,12 +29,19 @@
// Libraries // Libraries
#include <limits> #include <limits>
#include <cfloat> #include <cfloat>
#include <cstdint>
#include <utility> #include <utility>
#include <sstream> #include <sstream>
#include <string> #include <string>
#include <reactphysics3d/decimal.h> #include <reactphysics3d/decimal.h>
#include <reactphysics3d/containers/Pair.h> #include <reactphysics3d/containers/Pair.h>
#if defined(RP3D_NO_EXCEPTIONS)
#define THROW(...) abort()
#else
#define THROW(...) throw(__VA_ARGS__)
#endif
// Windows platform // Windows platform
#if defined(WIN32) ||defined(_WIN32) || defined(_WIN64) ||defined(__WIN32__) || defined(__WINDOWS__) #if defined(WIN32) ||defined(_WIN32) || defined(_WIN64) ||defined(__WIN32__) || defined(__WINDOWS__)
#define WINDOWS_OS #define WINDOWS_OS

View File

@ -463,7 +463,7 @@ class Map {
return; return;
} }
else { else {
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"));
} }
} }
} }
@ -666,7 +666,7 @@ class Map {
if (entry == -1) { if (entry == -1) {
assert(false); 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"));
} }
assert(mEntries[entry].keyValue != nullptr); assert(mEntries[entry].keyValue != nullptr);
@ -684,7 +684,7 @@ class Map {
} }
if (entry == -1) { if (entry == -1) {
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"));
} }
assert(mEntries[entry].keyValue != nullptr); assert(mEntries[entry].keyValue != nullptr);

View File

@ -51,10 +51,10 @@ class AABBOverlapCallback : public DynamicAABBTreeOverlapCallback {
public: public:
List<int>& mOverlappingNodes; List<int32>& mOverlappingNodes;
// Constructor // Constructor
AABBOverlapCallback(List<int>& overlappingNodes) : mOverlappingNodes(overlappingNodes) { AABBOverlapCallback(List<int32>& 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 /// 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 /// created) during the last simulation step. Those are the shapes that need to be tested
/// for overlapping in the next simulation step. /// for overlapping in the next simulation step.
Set<int> mMovedShapes; Set<int32> mMovedShapes;
/// Reference to the collision detection object /// Reference to the collision detection object
CollisionDetectionSystem& mCollisionDetection; CollisionDetectionSystem& mCollisionDetection;

View File

@ -361,7 +361,7 @@ class DefaultLogger : public Logger {
mFileStream(filePath, std::ios::binary) { mFileStream(filePath, std::ios::binary) {
if(!mFileStream.is_open()) { 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));
} }
// Writer the head // Writer the head

View File

@ -229,7 +229,7 @@ class Profiler {
mFileStream(filePath, std::ios::binary) { mFileStream(filePath, std::ios::binary) {
if(!mFileStream.is_open()) { 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));
} }
} }

View File

@ -28,6 +28,38 @@
#include <reactphysics3d/mathematics/Vector3.h> #include <reactphysics3d/mathematics/Vector3.h>
#include <cassert> #include <cassert>
#if __STDCPP_BFLOAT16_T__ || __STDCPP_FLOAT16_T__
#include <stdfloat>
#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; using namespace reactphysics3d;
// Constructor without vertices normals // Constructor without vertices normals
@ -249,6 +281,28 @@ void TriangleVertexArray::getTriangleVertices(uint triangleIndex, Vector3* outTr
outTriangleVertices[k][1] = decimal(vertices[1]); outTriangleVertices[k][1] = decimal(vertices[1]);
outTriangleVertices[k][2] = decimal(vertices[2]); outTriangleVertices[k][2] = decimal(vertices[2]);
} }
else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_SHORT_TYPE) {
const uint16_t* vertices = static_cast<const uint16_t*>(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<const std::float16_t*>(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<const std::bfloat16_t*>(vertexPointer);
outTriangleVertices[k][0] = decimal(vertices[0]);
outTriangleVertices[k][1] = decimal(vertices[1]);
outTriangleVertices[k][2] = decimal(vertices[2]);
}
#endif
else { else {
assert(false); assert(false);
} }
@ -287,6 +341,28 @@ void TriangleVertexArray::getTriangleVerticesNormals(uint triangleIndex, Vector3
outTriangleVerticesNormals[k][1] = decimal(normal[1]); outTriangleVerticesNormals[k][1] = decimal(normal[1]);
outTriangleVerticesNormals[k][2] = decimal(normal[2]); outTriangleVerticesNormals[k][2] = decimal(normal[2]);
} }
else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_SHORT_TYPE) {
const uint16_t* normal = static_cast<const uint16_t*>(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<const std::float16_t*>(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<const std::bfloat16_t*>(vertexNormalPointer);
outTriangleVerticesNormals[k][0] = decimal(normal[0]);
outTriangleVerticesNormals[k][1] = decimal(normal[1]);
outTriangleVerticesNormals[k][2] = decimal(normal[2]);
}
#endif
else { else {
assert(false); assert(false);
} }
@ -318,6 +394,28 @@ void TriangleVertexArray::getVertex(uint vertexIndex, Vector3* outVertex) {
(*outVertex)[1] = decimal(vertices[1]); (*outVertex)[1] = decimal(vertices[1]);
(*outVertex)[2] = decimal(vertices[2]); (*outVertex)[2] = decimal(vertices[2]);
} }
else if (mVertexDataType == TriangleVertexArray::VertexDataType::VERTEX_SHORT_TYPE) {
const uint16_t* vertices = static_cast<const uint16_t*>(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<const std::float16_t*>(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<const std::bfloat16_t*>(vertexPointer);
(*outVertex)[0] = decimal(vertices[0]);
(*outVertex)[1] = decimal(vertices[1]);
(*outVertex)[2] = decimal(vertices[2]);
}
#endif
else { else {
assert(false); assert(false);
} }
@ -348,6 +446,28 @@ void TriangleVertexArray::getNormal(uint vertexIndex, Vector3* outNormal) {
(*outNormal)[1] = decimal(normal[1]); (*outNormal)[1] = decimal(normal[1]);
(*outNormal)[2] = decimal(normal[2]); (*outNormal)[2] = decimal(normal[2]);
} }
else if (mVertexNormaldDataType == TriangleVertexArray::NormalDataType::NORMAL_SHORT_TYPE) {
const uint16_t* normal = static_cast<const uint16_t*>(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<const std::float16_t*>(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<const std::bfloat16_t*>(vertexNormalPointer);
(*outNormal)[0] = decimal(normal[0]);
(*outNormal)[1] = decimal(normal[1]);
(*outNormal)[2] = decimal(normal[2]);
}
#endif
else { else {
assert(false); assert(false);
} }

View File

@ -118,7 +118,7 @@ int32 DynamicAABBTree::allocateNode() {
} }
// Release a node // Release a node
void DynamicAABBTree::releaseNode(int nodeID) { void DynamicAABBTree::releaseNode(int32 nodeID) {
assert(mNbNodes > 0); assert(mNbNodes > 0);
assert(nodeID >= 0 && nodeID < mNbAllocatedNodes); assert(nodeID >= 0 && nodeID < mNbAllocatedNodes);
@ -204,7 +204,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 // 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 // in the dynamic tree is described in the book "Introduction to Game Physics
// with Box2D" by Ian Parberry. // with Box2D" by Ian Parberry.
void DynamicAABBTree::insertLeafNode(int nodeID) { void DynamicAABBTree::insertLeafNode(int32 nodeID) {
// If the tree is empty // If the tree is empty
if (mRootNodeID == TreeNode::NULL_TREE_NODE) { if (mRootNodeID == TreeNode::NULL_TREE_NODE) {
@ -334,7 +334,7 @@ void DynamicAABBTree::insertLeafNode(int nodeID) {
} }
// Remove a leaf node from the tree // Remove a leaf node from the tree
void DynamicAABBTree::removeLeafNode(int nodeID) { void DynamicAABBTree::removeLeafNode(int32 nodeID) {
assert(nodeID >= 0 && nodeID < mNbAllocatedNodes); assert(nodeID >= 0 && nodeID < mNbAllocatedNodes);
assert(mNodes[nodeID].isLeaf()); assert(mNodes[nodeID].isLeaf());

View File

@ -139,7 +139,7 @@ void ConcaveMeshShape::computeOverlappingTriangles(const AABB& localAABB, List<V
aabb.applyScale(Vector3(decimal(1.0) / mScale.x, decimal(1.0) / mScale.y, decimal(1.0) / mScale.z)); 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 // Compute the nodes of the internal AABB tree that are overlapping with the AABB
List<int> overlappingNodes(allocator); List<int32> overlappingNodes(allocator);
mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes); mDynamicAABBTree.reportAllShapesOverlappingWithAABB(aabb, overlappingNodes);
const uint nbOverlappingNodes = overlappingNodes.size(); const uint nbOverlappingNodes = overlappingNodes.size();
@ -230,7 +230,7 @@ decimal ConcaveMeshRaycastCallback::raycastBroadPhaseShape(int32 nodeId, const R
// Raycast all collision shapes that have been collected // Raycast all collision shapes that have been collected
void ConcaveMeshRaycastCallback::raycastTriangles() { void ConcaveMeshRaycastCallback::raycastTriangles() {
List<int>::Iterator it; List<int32>::Iterator it;
decimal smallestHitFraction = mRay.maxFraction; decimal smallestHitFraction = mRay.maxFraction;
for (it = mHitAABBNodes.begin(); it != mHitAABBNodes.end(); ++it) { for (it = mHitAABBNodes.begin(); it != mHitAABBNodes.end(); ++it) {

View File

@ -211,7 +211,7 @@ void BroadPhaseSystem::computeOverlappingPairs(MemoryManager& memoryManager, Lis
RP3D_PROFILE("BroadPhaseSystem::computeOverlappingPairs()", mProfiler); RP3D_PROFILE("BroadPhaseSystem::computeOverlappingPairs()", mProfiler);
// Get the list of the colliders that have moved or have been created in the last frame // Get the list of the colliders that have moved or have been created in the last frame
List<int> shapesToTest = mMovedShapes.toList(memoryManager.getPoolAllocator()); List<int32> shapesToTest = mMovedShapes.toList(memoryManager.getPoolAllocator());
// Ask the dynamic AABB tree to report all collision shapes that overlap with the shapes to test // Ask the dynamic AABB tree to report all collision shapes that overlap with the shapes to test
mDynamicAABBTree.reportAllShapesOverlappingWithShapes(shapesToTest, 0, shapesToTest.size(), overlappingNodes); mDynamicAABBTree.reportAllShapesOverlappingWithShapes(shapesToTest, 0, shapesToTest.size(), overlappingNodes);