ソースを参照

Support for building Jolt as a shared library on Windows (#513)

Adds a CMake option "COMPILE_AS_SHARED_LIBRARY" to switch the Jolt library to be compiled as a shared library.

This sets two compiler flags:

* JPH_SHARED_LIBRARY is a public define, that instructs all users of the library to import symbols
* JPH_BUILD_SHARED_LIBRARY is a private define, that instructs the Jolt library to export its symbols

These can easily be set as well by custom build tools.

All classes, global variables and functions have been marked with JPH_EXPORT, such that the important symbols get exported. I think I haven't missed anything important, it seems to all be working.

static thread_local variables can't be DLL exported (IMO this is a limitation of the compiler), so I've wrapped a few of these in static functions.

The RTTI macros declare a global function "GetRTTIOfType" which also has to be exported. Therefore I had to extend those declaration macros to take the export macro as a parameter. This is a bit unfortunate, I had hoped that such a duplication wouldn't be necessary.

All other libraries continue to use static linking (or are binaries anyway), so where they use those RTTI macros, they pass in JPH_NO_EXPORT as a no-op.
Jan Krassnigg 2 年 前
コミット
d2f1d97004
100 ファイル変更444 行追加301 行削除
  1. 41 0
      .github/workflows/build.yml
  2. 3 0
      Build/CMakeLists.txt
  3. 1 1
      Jolt/AABBTree/AABBTreeBuilder.h
  4. 1 1
      Jolt/Core/Color.h
  5. 33 0
      Jolt/Core/Core.h
  6. 1 1
      Jolt/Core/Factory.h
  7. 2 2
      Jolt/Core/IssueReporting.h
  8. 1 1
      Jolt/Core/JobSystem.h
  9. 1 1
      Jolt/Core/JobSystemThreadPool.h
  10. 1 1
      Jolt/Core/JobSystemWithBarrier.h
  11. 3 3
      Jolt/Core/LinearCurve.h
  12. 9 9
      Jolt/Core/Memory.h
  13. 1 1
      Jolt/Core/NonCopyable.h
  14. 16 1
      Jolt/Core/Profiler.cpp
  15. 14 5
      Jolt/Core/Profiler.h
  16. 4 3
      Jolt/Core/Profiler.inl
  17. 20 20
      Jolt/Core/RTTI.h
  18. 1 1
      Jolt/Core/Reference.h
  19. 1 1
      Jolt/Core/Semaphore.h
  20. 1 1
      Jolt/Core/StreamIn.h
  21. 1 1
      Jolt/Core/StreamOut.h
  22. 6 6
      Jolt/Core/StringTools.h
  23. 3 3
      Jolt/Core/TempAllocator.h
  24. 1 1
      Jolt/Core/TickCounter.h
  25. 1 1
      Jolt/Geometry/ConvexHullBuilder.h
  26. 1 1
      Jolt/Geometry/ConvexHullBuilder2D.h
  27. 2 2
      Jolt/Geometry/Indexify.h
  28. 1 1
      Jolt/Geometry/OrientedBox.h
  29. 30 2
      Jolt/Jolt.cmake
  30. 0 19
      Jolt/Math/UVec4.cpp
  31. 0 3
      Jolt/Math/UVec4.h
  32. 13 2
      Jolt/Math/UVec4.inl
  33. 1 1
      Jolt/Math/Vec3.h
  34. 8 8
      Jolt/ObjectStream/ObjectStream.h
  35. 1 1
      Jolt/ObjectStream/ObjectStreamBinaryIn.h
  36. 1 1
      Jolt/ObjectStream/ObjectStreamBinaryOut.h
  37. 1 1
      Jolt/ObjectStream/ObjectStreamIn.h
  38. 1 1
      Jolt/ObjectStream/ObjectStreamOut.h
  39. 1 1
      Jolt/ObjectStream/ObjectStreamTextIn.h
  40. 1 1
      Jolt/ObjectStream/ObjectStreamTextOut.h
  41. 37 37
      Jolt/ObjectStream/SerializableObject.h
  42. 21 21
      Jolt/ObjectStream/TypeDeclarations.h
  43. 1 1
      Jolt/Physics/Body/Body.h
  44. 2 2
      Jolt/Physics/Body/BodyCreationSettings.h
  45. 1 1
      Jolt/Physics/Body/BodyInterface.h
  46. 22 2
      Jolt/Physics/Body/BodyManager.cpp
  47. 13 9
      Jolt/Physics/Body/BodyManager.h
  48. 2 2
      Jolt/Physics/Body/MassProperties.h
  49. 1 1
      Jolt/Physics/Body/MotionProperties.h
  50. 2 2
      Jolt/Physics/Character/Character.h
  51. 2 2
      Jolt/Physics/Character/CharacterBase.h
  52. 3 3
      Jolt/Physics/Character/CharacterVirtual.h
  53. 1 1
      Jolt/Physics/Collision/BroadPhase/BroadPhase.h
  54. 1 1
      Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h
  55. 1 1
      Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h
  56. 1 1
      Jolt/Physics/Collision/BroadPhase/BroadPhaseQuery.h
  57. 1 1
      Jolt/Physics/Collision/BroadPhase/QuadTree.h
  58. 1 1
      Jolt/Physics/Collision/CastConvexVsTriangles.h
  59. 1 1
      Jolt/Physics/Collision/CastSphereVsTriangles.h
  60. 1 1
      Jolt/Physics/Collision/CollideConvexVsTriangles.h
  61. 1 1
      Jolt/Physics/Collision/CollideSphereVsTriangles.h
  62. 1 1
      Jolt/Physics/Collision/CollisionDispatch.h
  63. 2 2
      Jolt/Physics/Collision/CollisionGroup.h
  64. 1 1
      Jolt/Physics/Collision/EstimateCollisionResponse.h
  65. 2 2
      Jolt/Physics/Collision/GroupFilter.h
  66. 2 2
      Jolt/Physics/Collision/GroupFilterTable.h
  67. 2 2
      Jolt/Physics/Collision/ManifoldBetweenTwoFaces.h
  68. 1 1
      Jolt/Physics/Collision/NarrowPhaseQuery.h
  69. 2 2
      Jolt/Physics/Collision/PhysicsMaterial.h
  70. 2 2
      Jolt/Physics/Collision/PhysicsMaterialSimple.h
  71. 3 3
      Jolt/Physics/Collision/Shape/BoxShape.h
  72. 3 3
      Jolt/Physics/Collision/Shape/CapsuleShape.h
  73. 4 4
      Jolt/Physics/Collision/Shape/CompoundShape.h
  74. 3 3
      Jolt/Physics/Collision/Shape/ConvexHullShape.h
  75. 3 3
      Jolt/Physics/Collision/Shape/ConvexShape.h
  76. 3 3
      Jolt/Physics/Collision/Shape/CylinderShape.h
  77. 3 3
      Jolt/Physics/Collision/Shape/DecoratedShape.h
  78. 3 3
      Jolt/Physics/Collision/Shape/HeightFieldShape.h
  79. 3 3
      Jolt/Physics/Collision/Shape/MeshShape.h
  80. 3 3
      Jolt/Physics/Collision/Shape/MutableCompoundShape.h
  81. 3 3
      Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h
  82. 3 3
      Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h
  83. 3 3
      Jolt/Physics/Collision/Shape/ScaledShape.h
  84. 4 4
      Jolt/Physics/Collision/Shape/Shape.h
  85. 3 3
      Jolt/Physics/Collision/Shape/SphereShape.h
  86. 3 3
      Jolt/Physics/Collision/Shape/StaticCompoundShape.h
  87. 3 3
      Jolt/Physics/Collision/Shape/TaperedCapsuleShape.h
  88. 3 3
      Jolt/Physics/Collision/Shape/TriangleShape.h
  89. 1 1
      Jolt/Physics/Collision/TransformedShape.h
  90. 3 3
      Jolt/Physics/Constraints/ConeConstraint.h
  91. 3 3
      Jolt/Physics/Constraints/Constraint.h
  92. 1 1
      Jolt/Physics/Constraints/ConstraintManager.h
  93. 1 1
      Jolt/Physics/Constraints/ContactConstraintManager.h
  94. 3 3
      Jolt/Physics/Constraints/DistanceConstraint.h
  95. 3 3
      Jolt/Physics/Constraints/FixedConstraint.h
  96. 3 3
      Jolt/Physics/Constraints/GearConstraint.h
  97. 3 3
      Jolt/Physics/Constraints/HingeConstraint.h
  98. 2 2
      Jolt/Physics/Constraints/MotorSettings.h
  99. 3 3
      Jolt/Physics/Constraints/PathConstraint.h
  100. 2 2
      Jolt/Physics/Constraints/PathConstraintPath.h

+ 41 - 0
.github/workflows/build.yml

@@ -34,6 +34,26 @@ jobs:
       working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}}_${{matrix.clang_version}}
       run: ctest --output-on-failure
 
+  linux-clang-so:
+    runs-on: ubuntu-22.04
+    name: Linux Clang Shared Library
+    strategy:
+        fail-fast: false
+        matrix:
+            build_type: [Debug, Release, Distribution]
+            clang_version: [clang++-14]
+
+    steps:
+    - name: Checkout Code
+      uses: actions/checkout@v3
+    - name: Configure CMake
+      run: cmake -B ${{github.workspace}}/Build/Linux_${{matrix.build_type}}_${{matrix.clang_version}} -DCMAKE_BUILD_TYPE=${{matrix.build_type}} -DCMAKE_CXX_COMPILER=${{matrix.clang_version}} -DCOMPILE_AS_SHARED_LIBRARY=Yes Build
+    - name: Build
+      run: cmake --build ${{github.workspace}}/Build/Linux_${{matrix.build_type}}_${{matrix.clang_version}} -j 2
+    - name: Test
+      working-directory: ${{github.workspace}}/Build/Linux_${{matrix.build_type}}_${{matrix.clang_version}}
+      run: ctest --output-on-failure
+
   linux-gcc:
     runs-on: ubuntu-22.04
     name: Linux GCC
@@ -104,6 +124,27 @@ jobs:
       working-directory: ${{github.workspace}}/Build/VS2022_CL/${{matrix.build_type}}
       run: ./UnitTests.exe
 
+  msvc_cl_dll:
+    runs-on: windows-latest
+    name: Visual Studio CL Shared Library
+    strategy:
+        fail-fast: false
+        matrix:
+            build_type: [Debug, Release, Distribution]
+
+    steps:
+    - name: Checkout Code
+      uses: actions/checkout@v3
+    - name: Add msbuild to PATH
+      uses: microsoft/[email protected]
+    - name: Configure CMake
+      run: cmake -B ${{github.workspace}}/Build/VS2022_CL -G "Visual Studio 17 2022" -A x64 Build -DCOMPILE_AS_SHARED_LIBRARY=Yes
+    - name: Build
+      run: msbuild Build\VS2022_CL\JoltPhysics.sln /property:Configuration=${{matrix.build_type}} -m
+    - name: Test
+      working-directory: ${{github.workspace}}/Build/VS2022_CL/${{matrix.build_type}}
+      run: ./UnitTests.exe
+
   msvc_cl_32_bit:
     runs-on: windows-latest
     name: Visual Studio CL 32-bit

+ 3 - 0
Build/CMakeLists.txt

@@ -14,6 +14,9 @@ option(CROSS_PLATFORM_DETERMINISTIC "Cross platform deterministic" OFF)
 # When turning this option on, the library will be compiled for ARM (aarch64-linux-gnu), requires compiling with clang
 option(CROSS_COMPILE_ARM "Cross compile to aarch64-linux-gnu" OFF)
 
+# When turning this option on, Jolt will be compiled as a shared library and public symbols will be exported.
+option(COMPILE_AS_SHARED_LIBRARY "Compile Jolt as a shared library" OFF)
+
 # When turning this option on, the library will be compiled with interprocedural optimizations enabled, also known as link-time optimizations or link-time code generation.
 # Note that if you turn this on you need to use SET_INTERPROCEDURAL_OPTIMIZATION() or set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ON) to enable LTO specificly for your own project as well.
 # If you don't do this you may get an error: /usr/bin/ld: libJolt.a: error adding symbols: file format not recognized

+ 1 - 1
Jolt/AABBTree/AABBTreeBuilder.h

@@ -32,7 +32,7 @@ struct AABBTreeBuilderStats
 };
 
 /// Helper class to build an AABB tree
-class AABBTreeBuilder
+class JPH_EXPORT AABBTreeBuilder
 {
 public:
 	/// A node in the tree, contains the AABox for the tree and any child nodes or triangles

+ 1 - 1
Jolt/Core/Color.h

@@ -12,7 +12,7 @@ class Color;
 using ColorArg = Color;
 
 /// Class that holds an RGBA color with 8-bits per component
-class [[nodiscard]] Color
+class [[nodiscard]] JPH_EXPORT Color
 {
 public:
 	/// Constructors

+ 33 - 0
Jolt/Core/Core.h

@@ -123,14 +123,45 @@
 	#error Unsupported CPU architecture
 #endif
 
+// If this define is set, Jolt is compiled as a shared library
+#ifdef JPH_SHARED_LIBRARY
+	#ifdef JPH_BUILD_SHARED_LIBRARY
+		// While building the shared library, we must export these symbols
+		#ifdef JPH_PLATFORM_WINDOWS
+			#define JPH_EXPORT __declspec(dllexport)
+		#else
+			#define JPH_EXPORT __attribute__ ((visibility ("default")))
+		#endif
+	#else
+		// When linking against Jolt, we must import these symbols
+		#ifdef JPH_PLATFORM_WINDOWS
+			#define JPH_EXPORT __declspec(dllimport)
+		#else
+			#define JPH_EXPORT __attribute__ ((visibility ("default")))
+		#endif
+	#endif
+#else
+	// If the define is not set, we use static linking and symbols don't need to be imported or exported
+	#define JPH_EXPORT
+#endif
+
+// Macro used by the RTTI macros to not export a function
+#define JPH_NO_EXPORT
+
 // Pragmas to store / restore the warning state and to disable individual warnings
 #ifdef JPH_COMPILER_CLANG
 #define JPH_PRAGMA(x)					_Pragma(#x)
 #define JPH_SUPPRESS_WARNING_PUSH		JPH_PRAGMA(clang diagnostic push)
 #define JPH_SUPPRESS_WARNING_POP		JPH_PRAGMA(clang diagnostic pop)
 #define JPH_CLANG_SUPPRESS_WARNING(w)	JPH_PRAGMA(clang diagnostic ignored w)
+#if __clang_major__ >= 13
+	#define JPH_CLANG_13_PLUS_SUPPRESS_WARNING(w) JPH_CLANG_SUPPRESS_WARNING(w)
+#else
+	#define JPH_CLANG_13_PLUS_SUPPRESS_WARNING(w)
+#endif
 #else
 #define JPH_CLANG_SUPPRESS_WARNING(w)
+#define JPH_CLANG_13_PLUS_SUPPRESS_WARNING(w)
 #endif
 #ifdef JPH_COMPILER_GCC
 #define JPH_PRAGMA(x)					_Pragma(#x)
@@ -177,6 +208,7 @@
 	JPH_CLANG_SUPPRESS_WARNING("-Wdocumentation-unknown-command")								\
 	JPH_CLANG_SUPPRESS_WARNING("-Wctad-maybe-unsupported")										\
 	JPH_CLANG_SUPPRESS_WARNING("-Wdeprecated-copy")												\
+	JPH_CLANG_13_PLUS_SUPPRESS_WARNING("-Wdeprecated-copy-with-dtor")							\
 	JPH_IF_NOT_ANDROID(JPH_CLANG_SUPPRESS_WARNING("-Wimplicit-int-float-conversion"))			\
 																								\
 	JPH_GCC_SUPPRESS_WARNING("-Wcomment")														\
@@ -204,6 +236,7 @@
 	JPH_MSVC_SUPPRESS_WARNING(5219) /* implicit conversion from 'X' to 'Y', possible loss of data  */ \
 	JPH_MSVC_SUPPRESS_WARNING(4826) /* Conversion from 'X *' to 'JPH::uint64' is sign-extended. This may cause unexpected runtime behavior. (32-bit) */ \
 	JPH_MSVC_SUPPRESS_WARNING(5264) /* 'X': 'const' variable is not used */						\
+	JPH_MSVC_SUPPRESS_WARNING(4251) /* class 'X' needs to have DLL-interface to be used by clients of class 'Y' */ \
 	JPH_MSVC2019_SUPPRESS_WARNING(5246) /* the initialization of a subobject should be wrapped in braces */
 
 // OS-specific includes

+ 1 - 1
Jolt/Core/Factory.h

@@ -10,7 +10,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Factory, to create RTTI objects
-class Factory
+class JPH_EXPORT Factory
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Core/IssueReporting.h

@@ -8,7 +8,7 @@ JPH_NAMESPACE_BEGIN
 	
 /// Trace function, needs to be overridden by application. This should output a line of text to the log / TTY.
 using TraceFunction = void (*)(const char *inFMT, ...);
-extern TraceFunction Trace;
+JPH_EXPORT extern TraceFunction Trace;
 
 // Always turn on asserts in Debug mode
 #if defined(_DEBUG) && !defined(JPH_ENABLE_ASSERTS)
@@ -18,7 +18,7 @@ extern TraceFunction Trace;
 #ifdef JPH_ENABLE_ASSERTS
 	/// Function called when an assertion fails. This function should return true if a breakpoint needs to be triggered
 	using AssertFailedFunction = bool(*)(const char *inExpression, const char *inMessage, const char *inFile, uint inLine);
-	extern AssertFailedFunction AssertFailed;
+	JPH_EXPORT extern AssertFailedFunction AssertFailed;
 
 	// Helper functions to pass message on to failed function
 	struct AssertLastParam { };

+ 1 - 1
Jolt/Core/JobSystem.h

@@ -66,7 +66,7 @@ JPH_NAMESPACE_BEGIN
 /// to wait for these in this function after the barrier is finished waiting.
 ///
 /// An example implementation is JobSystemThreadPool. If you don't want to write the Barrier class you can also inherit from JobSystemWithBarrier.
-class JobSystem : public NonCopyable
+class JPH_EXPORT JobSystem : public NonCopyable
 {
 protected:
 	class Job;

+ 1 - 1
Jolt/Core/JobSystemThreadPool.h

@@ -22,7 +22,7 @@ using std::thread;
 /// Note that this is considered an example implementation. It is expected that when you integrate
 /// the physics engine into your own project that you'll provide your own implementation of the
 /// JobSystem built on top of whatever job system your project uses.
-class JobSystemThreadPool final : public JobSystemWithBarrier
+class JPH_EXPORT JobSystemThreadPool final : public JobSystemWithBarrier
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Core/JobSystemWithBarrier.h

@@ -20,7 +20,7 @@ JPH_NAMESPACE_BEGIN
 /// * JobSystem::QueueJob/QueueJobs
 ///
 /// See instructions in JobSystem for more information on how to implement these.
-class JobSystemWithBarrier : public JobSystem
+class JPH_EXPORT JobSystemWithBarrier : public JobSystem
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Core/LinearCurve.h

@@ -13,16 +13,16 @@ class StreamOut;
 class StreamIn;
 
 // A set of points (x, y) that form a linear curve
-class LinearCurve
+class JPH_EXPORT LinearCurve
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(LinearCurve)
+	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, LinearCurve)
 
 	/// A point on the curve
 	class Point
 	{
 	public:
-		JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(Point)
+		JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, Point)
 
 		float			mX = 0.0f;
 		float			mY = 0.0f;

+ 9 - 9
Jolt/Core/Memory.h

@@ -17,13 +17,13 @@ using AlignedAllocateFunction = void *(*)(size_t inSize, size_t inAlignment);
 using AlignedFreeFunction = void (*)(void *inBlock);
 
 // User defined allocation / free functions
-extern AllocateFunction Allocate;
-extern FreeFunction Free;
-extern AlignedAllocateFunction AlignedAllocate;
-extern AlignedFreeFunction AlignedFree;
+JPH_EXPORT extern AllocateFunction Allocate;
+JPH_EXPORT extern FreeFunction Free;
+JPH_EXPORT extern AlignedAllocateFunction AlignedAllocate;
+JPH_EXPORT extern AlignedFreeFunction AlignedFree;
 
 /// Register platform default allocation / free functions
-void RegisterDefaultAllocator();
+JPH_EXPORT void RegisterDefaultAllocator();
 
 /// Macro to override the new and delete functions
 #define JPH_OVERRIDE_NEW_DELETE \
@@ -39,10 +39,10 @@ void RegisterDefaultAllocator();
 #else
 
 // Directly define the allocation functions
-void *Allocate(size_t inSize);
-void Free(void *inBlock);
-void *AlignedAllocate(size_t inSize, size_t inAlignment);
-void AlignedFree(void *inBlock);
+JPH_EXPORT void *Allocate(size_t inSize);
+JPH_EXPORT void Free(void *inBlock);
+JPH_EXPORT void *AlignedAllocate(size_t inSize, size_t inAlignment);
+JPH_EXPORT void AlignedFree(void *inBlock);
 
 // Don't implement allocator registering
 inline void RegisterDefaultAllocator() { }

+ 1 - 1
Jolt/Core/NonCopyable.h

@@ -7,7 +7,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
-class NonCopyable
+class JPH_EXPORT NonCopyable
 {
 public:
 			NonCopyable() = default;

+ 16 - 1
Jolt/Core/Profiler.cpp

@@ -22,7 +22,22 @@ JPH_NAMESPACE_BEGIN
 //////////////////////////////////////////////////////////////////////////////////////////
 
 Profiler *Profiler::sInstance = nullptr;
-thread_local ProfileThread *ProfileThread::sInstance = nullptr;
+
+#ifdef JPH_SHARED_LIBRARY
+	static thread_local ProfileThread *sInstance = nullptr;
+
+	ProfileThread *ProfileThread::sGetInstance()
+	{
+		return sInstance;
+	}
+
+	void ProfileThread::sSetInstance(ProfileThread *inInstance)
+	{
+		sInstance = inInstance;
+	}
+#else
+	thread_local ProfileThread *ProfileThread::sInstance = nullptr;
+#endif
 
 bool ProfileMeasurement::sOutOfSamplesReported = false;
 

+ 14 - 5
Jolt/Core/Profiler.h

@@ -74,7 +74,7 @@ class ProfileSample;
 class ProfileThread;
 
 /// Singleton class for managing profiling information
-class Profiler : public NonCopyable
+class JPH_EXPORT Profiler : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -157,7 +157,7 @@ private:
 };							
 
 // Class that contains the information of a single scoped measurement
-class alignas(16) ProfileSample : public NonCopyable
+class alignas(16) JPH_EXPORT ProfileSample : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -186,11 +186,20 @@ public:
 	ProfileSample				mSamples[cMaxSamples];												///< Buffer of samples
 	uint						mCurrentSample = 0;													///< Next position to write a sample to
 
+#ifdef JPH_SHARED_LIBRARY
+	JPH_EXPORT static void		sSetInstance(ProfileThread *inInstance);
+	JPH_EXPORT static ProfileThread *sGetInstance();
+#else
+	static inline void			sSetInstance(ProfileThread *inInstance)								{ sInstance = inInstance; }
+	static inline ProfileThread *sGetInstance()														{ return sInstance; }
+
+private:
 	static thread_local ProfileThread *sInstance;
+#endif
 };
 
 /// Create this class on the stack to start sampling timing information of a particular scope
-class ProfileMeasurement : public NonCopyable
+class JPH_EXPORT ProfileMeasurement : public NonCopyable
 {	
 public:						
 	/// Constructor
@@ -222,10 +231,10 @@ JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
 #define JPH_PROFILE_END()				do { JPH_PROFILE_THREAD_END(); delete Profiler::sInstance; Profiler::sInstance = nullptr; } while (false)
 
 /// Start instrumenting a thread
-#define JPH_PROFILE_THREAD_START(name)	do { if (Profiler::sInstance) ProfileThread::sInstance = new ProfileThread(name); } while (false)
+#define JPH_PROFILE_THREAD_START(name)	do { if (Profiler::sInstance) ProfileThread::sSetInstance(new ProfileThread(name)); } while (false)
 
 /// End instrumenting a thread
-#define JPH_PROFILE_THREAD_END()		do { delete ProfileThread::sInstance; ProfileThread::sInstance = nullptr; } while (false)
+#define JPH_PROFILE_THREAD_END()		do { delete ProfileThread::sGetInstance(); ProfileThread::sSetInstance(nullptr); } while (false)
 								
 /// Scope profiling measurement
 #define JPH_PROFILE_TAG2(line)			profile##line

+ 4 - 3
Jolt/Core/Profiler.inl

@@ -25,15 +25,16 @@ ProfileThread::~ProfileThread()
 
 ProfileMeasurement::ProfileMeasurement(const char *inName, uint32 inColor)	
 {
-	if (ProfileThread::sInstance == nullptr)
+	ProfileThread *current_thread = ProfileThread::sGetInstance();
+	if (current_thread == nullptr)
 	{
 		// Thread not instrumented
 		mSample = nullptr;
 	}
-	else if (ProfileThread::sInstance->mCurrentSample < ProfileThread::cMaxSamples)
+	else if (current_thread->mCurrentSample < ProfileThread::cMaxSamples)
 	{
 		// Get pointer to write data to
-		mSample = &ProfileThread::sInstance->mSamples[ProfileThread::sInstance->mCurrentSample++];
+		mSample = &current_thread->mSamples[current_thread->mCurrentSample++];
 
 		// Start constructing sample (will end up on stack)
 		mTemp.mName = inName;

+ 20 - 20
Jolt/Core/RTTI.h

@@ -118,7 +118,7 @@ JPH_NAMESPACE_BEGIN
 ///		B *b = DynamicCast<B>(a);
 /// 
 /// does the correct cast
-class RTTI
+class JPH_EXPORT RTTI
 {
 public:
 	/// Function to create an object
@@ -188,10 +188,10 @@ protected:
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_RTTI_NON_VIRTUAL
-#define JPH_DECLARE_RTTI_NON_VIRTUAL(class_name)																	\
+#define JPH_DECLARE_RTTI_NON_VIRTUAL(linkage, class_name)															\
 public:																												\
 	JPH_OVERRIDE_NEW_DELETE																							\
-	friend RTTI *				GetRTTIOfType(class_name *);														\
+	friend linkage RTTI *		GetRTTIOfType(class_name *);														\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
 	static void					sCreateRTTI(RTTI &inRTTI);															\
 
@@ -210,8 +210,8 @@ public:																												\
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_RTTI_OUTSIDE_CLASS
-#define JPH_DECLARE_RTTI_OUTSIDE_CLASS(class_name)																	\
-	RTTI *						GetRTTIOfType(class_name *);														\
+#define JPH_DECLARE_RTTI_OUTSIDE_CLASS(linkage, class_name)															\
+	linkage RTTI *				GetRTTIOfType(class_name *);														\
 	inline const RTTI *			GetRTTI(const class_name *inObject) { return GetRTTIOfType((class_name *)nullptr); }\
 	void						CreateRTTI##class_name(RTTI &inRTTI);												\
 
@@ -228,22 +228,22 @@ public:																												\
 // Same as above, but for classes that have virtual functions
 //////////////////////////////////////////////////////////////////////////////////////////
 
-#define JPH_DECLARE_RTTI_HELPER(class_name, modifier)																\
+#define JPH_DECLARE_RTTI_HELPER(linkage, class_name, modifier)														\
 public:																												\
 	JPH_OVERRIDE_NEW_DELETE																							\
-	friend RTTI *				GetRTTIOfType(class_name *);														\
+	friend linkage RTTI *		GetRTTIOfType(class_name *);														\
 	friend inline const RTTI *	GetRTTI(const class_name *inObject) { return inObject->GetRTTI(); }					\
 	virtual const RTTI *		GetRTTI() const modifier;															\
 	virtual const void *		CastTo(const RTTI *inRTTI) const modifier;											\
 	static void					sCreateRTTI(RTTI &inRTTI);															\
 
 // JPH_DECLARE_RTTI_VIRTUAL - for derived classes with RTTI
-#define JPH_DECLARE_RTTI_VIRTUAL(class_name)																		\
-	JPH_DECLARE_RTTI_HELPER(class_name, override)
+#define JPH_DECLARE_RTTI_VIRTUAL(linkage, class_name)																\
+	JPH_DECLARE_RTTI_HELPER(linkage, class_name, override)
 
 // JPH_IMPLEMENT_RTTI_VIRTUAL
 #define JPH_IMPLEMENT_RTTI_VIRTUAL(class_name)																		\
-	RTTI *						GetRTTIOfType(class_name *)															\
+	RTTI *			GetRTTIOfType(class_name *)																		\
 	{																												\
 		static RTTI rtti(#class_name, sizeof(class_name), []() -> void * { return new class_name; }, [](void *inObject) { delete (class_name *)inObject; }, &class_name::sCreateRTTI); \
 		return &rtti;																								\
@@ -259,16 +259,16 @@ public:																												\
 	void						class_name::sCreateRTTI(RTTI &inRTTI)												\
 
 // JPH_DECLARE_RTTI_VIRTUAL_BASE - for concrete base class that has RTTI
-#define JPH_DECLARE_RTTI_VIRTUAL_BASE(class_name)																	\
-	JPH_DECLARE_RTTI_HELPER(class_name, )
+#define JPH_DECLARE_RTTI_VIRTUAL_BASE(linkage, class_name)															\
+	JPH_DECLARE_RTTI_HELPER(linkage, class_name, )
 
 // JPH_IMPLEMENT_RTTI_VIRTUAL_BASE
 #define JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name)																	\
 	JPH_IMPLEMENT_RTTI_VIRTUAL(class_name)
 
 // JPH_DECLARE_RTTI_ABSTRACT - for derived abstract class that have RTTI
-#define JPH_DECLARE_RTTI_ABSTRACT(class_name)																		\
-	JPH_DECLARE_RTTI_HELPER(class_name, override)
+#define JPH_DECLARE_RTTI_ABSTRACT(linkage, class_name)																\
+	JPH_DECLARE_RTTI_HELPER(linkage, class_name, override)
 
 // JPH_IMPLEMENT_RTTI_ABSTRACT
 #define JPH_IMPLEMENT_RTTI_ABSTRACT(class_name)																		\
@@ -288,8 +288,8 @@ public:																												\
 	void						class_name::sCreateRTTI(RTTI &inRTTI)												\
 
 // JPH_DECLARE_RTTI_ABSTRACT_BASE - for abstract base class that has RTTI
-#define JPH_DECLARE_RTTI_ABSTRACT_BASE(class_name)																	\
-	JPH_DECLARE_RTTI_HELPER(class_name, )
+#define JPH_DECLARE_RTTI_ABSTRACT_BASE(linkage, class_name)															\
+	JPH_DECLARE_RTTI_HELPER(linkage, class_name, )
 
 // JPH_IMPLEMENT_RTTI_ABSTRACT_BASE
 #define JPH_IMPLEMENT_RTTI_ABSTRACT_BASE(class_name)																\
@@ -299,13 +299,13 @@ public:																												\
 // Declare an RTTI class for registering with the factory
 //////////////////////////////////////////////////////////////////////////////////////////
 
-#define JPH_DECLARE_RTTI_FOR_FACTORY(class_name)																	\
-	RTTI *						GetRTTIOfType(class class_name *);
+#define JPH_DECLARE_RTTI_FOR_FACTORY(linkage, class_name)															\
+	linkage RTTI *				GetRTTIOfType(class class_name *);
 
-#define JPH_DECLARE_RTTI_WITH_NAMESPACE_FOR_FACTORY(name_space, class_name)											\
+#define JPH_DECLARE_RTTI_WITH_NAMESPACE_FOR_FACTORY(linkage, name_space, class_name)								\
 	namespace name_space {																							\
 		class class_name; 																							\
-		RTTI *					GetRTTIOfType(class class_name *);													\
+		linkage RTTI *			GetRTTIOfType(class class_name *);													\
 	}
 
 //////////////////////////////////////////////////////////////////////////////////////////

+ 1 - 1
Jolt/Core/Reference.h

@@ -78,7 +78,7 @@ protected:
 };							
 
 /// Pure virtual version of RefTarget
-class RefTargetVirtual
+class JPH_EXPORT RefTargetVirtual
 {
 public:
 	/// Virtual destructor

+ 1 - 1
Jolt/Core/Semaphore.h

@@ -19,7 +19,7 @@ using std::condition_variable;
 
 /// Implements a semaphore
 /// When we switch to C++20 we can use counting_semaphore to unify this
-class Semaphore
+class JPH_EXPORT Semaphore
 {
 public:
 	/// Constructor

+ 1 - 1
Jolt/Core/StreamIn.h

@@ -7,7 +7,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Simple binary input stream
-class StreamIn
+class JPH_EXPORT StreamIn
 {
 public:
 	/// Virtual destructor

+ 1 - 1
Jolt/Core/StreamOut.h

@@ -7,7 +7,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Simple binary output stream
-class StreamOut
+class JPH_EXPORT StreamOut
 {
 public:
 	/// Virtual destructor

+ 6 - 6
Jolt/Core/StringTools.h

@@ -8,7 +8,7 @@ JPH_NAMESPACE_BEGIN
 
 /// Create a formatted text string for debugging purposes.
 /// Note that this function has an internal buffer of 1024 characters, so long strings will be trimmed.
-String StringFormat(const char *inFMT, ...);
+JPH_EXPORT String StringFormat(const char *inFMT, ...);
 
 /// Convert type to string
 template<typename T>
@@ -34,18 +34,18 @@ constexpr uint64 HashString(const char *inString)
 }
 
 /// Replace substring with other string
-void StringReplace(String &ioString, const string_view &inSearch, const string_view &inReplace);
+JPH_EXPORT void StringReplace(String &ioString, const string_view &inSearch, const string_view &inReplace);
 
 /// Convert a delimited string to an array of strings
-void StringToVector(const string_view &inString, Array<String> &outVector, const string_view &inDelimiter = ",", bool inClearVector = true);
+JPH_EXPORT void StringToVector(const string_view &inString, Array<String> &outVector, const string_view &inDelimiter = ",", bool inClearVector = true);
 
 /// Convert an array strings to a delimited string
-void VectorToString(const Array<String> &inVector, String &outString, const string_view &inDelimiter = ",");
+JPH_EXPORT void VectorToString(const Array<String> &inVector, String &outString, const string_view &inDelimiter = ",");
 
 /// Convert a string to lower case
-String ToLower(const string_view &inString);
+JPH_EXPORT String ToLower(const string_view &inString);
 
 /// Converts the lower 4 bits of inNibble to a string that represents the number in binary format
-const char *NibbleToBinary(uint32 inNibble);
+JPH_EXPORT const char *NibbleToBinary(uint32 inNibble);
 
 JPH_NAMESPACE_END

+ 3 - 3
Jolt/Core/TempAllocator.h

@@ -12,7 +12,7 @@ JPH_NAMESPACE_BEGIN
 /// This allocator works as a stack: The blocks must always be freed in the reverse order as they are allocated.
 /// Note that allocations and frees can take place from different threads, but the order is guaranteed though
 /// job dependencies, so it is not needed to use any form of locking.
-class TempAllocator : public NonCopyable
+class JPH_EXPORT TempAllocator : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -28,7 +28,7 @@ public:
 };
 
 /// Default implementation of the temp allocator that allocates a large block through malloc upfront
-class TempAllocatorImpl final : public TempAllocator
+class JPH_EXPORT TempAllocatorImpl final : public TempAllocator
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -94,7 +94,7 @@ private:
 
 /// Implementation of the TempAllocator that just falls back to malloc/free
 /// Note: This can be quite slow when running in the debugger as large memory blocks need to be initialized with 0xcd
-class TempAllocatorMalloc final : public TempAllocator
+class JPH_EXPORT TempAllocatorMalloc final : public TempAllocator
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Core/TickCounter.h

@@ -43,6 +43,6 @@ JPH_INLINE uint64 GetProcessorTickCount()
 #endif // JPH_PLATFORM_WINDOWS_UWP || (JPH_PLATFORM_WINDOWS && JPH_CPU_ARM)
 
 /// Get the amount of ticks per second, note that this number will never be fully accurate as the amound of ticks per second may vary with CPU load, so this number is only to be used to give an indication of time for profiling purposes
-uint64 GetProcessorTicksPerSecond();
+JPH_EXPORT uint64 GetProcessorTicksPerSecond();
 
 JPH_NAMESPACE_END

+ 1 - 1
Jolt/Geometry/ConvexHullBuilder.h

@@ -17,7 +17,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// A convex hull builder that tries to create hulls as accurately as possible. Used for offline processing.
-class ConvexHullBuilder : public NonCopyable
+class JPH_EXPORT ConvexHullBuilder : public NonCopyable
 {
 public:
 	// Forward declare

+ 1 - 1
Jolt/Geometry/ConvexHullBuilder2D.h

@@ -11,7 +11,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// A convex hull builder that tries to create 2D hulls as accurately as possible. Used for offline processing. 
-class ConvexHullBuilder2D : public NonCopyable
+class JPH_EXPORT ConvexHullBuilder2D : public NonCopyable
 {
 public:
 	using Positions = Array<Vec3>; 

+ 2 - 2
Jolt/Geometry/Indexify.h

@@ -11,9 +11,9 @@ JPH_NAMESPACE_BEGIN
 
 /// Take a list of triangles and get the unique set of vertices and use them to create indexed triangles.
 /// Vertices that are less than inVertexWeldDistance apart will be combined to a single vertex.
-void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance = 1.0e-4f);
+JPH_EXPORT void Indexify(const TriangleList &inTriangles, VertexList &outVertices, IndexedTriangleList &outTriangles, float inVertexWeldDistance = 1.0e-4f);
 
 /// Take a list of indexed triangles and unpack them
-void Deindexify(const VertexList &inVertices, const IndexedTriangleList &inTriangles, TriangleList &outTriangles);
+JPH_EXPORT void Deindexify(const VertexList &inVertices, const IndexedTriangleList &inTriangles, TriangleList &outTriangles);
 
 JPH_NAMESPACE_END

+ 1 - 1
Jolt/Geometry/OrientedBox.h

@@ -14,7 +14,7 @@ JPH_NAMESPACE_BEGIN
 class AABox;
 
 /// Oriented box
-class [[nodiscard]] OrientedBox
+class [[nodiscard]] JPH_EXPORT OrientedBox
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 30 - 2
Jolt/Jolt.cmake

@@ -123,7 +123,6 @@ set(JOLT_PHYSICS_SRC_FILES
 	${JOLT_PHYSICS_ROOT}/Math/Real.h
 	${JOLT_PHYSICS_ROOT}/Math/Swizzle.h
 	${JOLT_PHYSICS_ROOT}/Math/Trigonometry.h
-	${JOLT_PHYSICS_ROOT}/Math/UVec4.cpp
 	${JOLT_PHYSICS_ROOT}/Math/UVec4.h
 	${JOLT_PHYSICS_ROOT}/Math/UVec4.inl
 	${JOLT_PHYSICS_ROOT}/Math/UVec8.h
@@ -430,7 +429,36 @@ endif()
 source_group(TREE ${JOLT_PHYSICS_ROOT} FILES ${JOLT_PHYSICS_SRC_FILES})
 
 # Create Jolt lib
-add_library(Jolt STATIC ${JOLT_PHYSICS_SRC_FILES})
+
+if (COMPILE_AS_SHARED_LIBRARY)
+	add_library(Jolt SHARED ${JOLT_PHYSICS_SRC_FILES})
+
+	# Set default visibility to hidden
+	set(CMAKE_CXX_VISIBILITY_PRESET hidden)
+
+	if (MSVC)
+		# MSVC specific option to enable PDB generation
+		set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} /DEBUG:FASTLINK")
+	else()
+		# Clang/GCC option to enable debug symbol generation
+		set(CMAKE_SHARED_LINKER_FLAGS_RELEASE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE} -g")
+	endif()
+
+	# Set linker flags for other build types to be the same as release
+	set(CMAKE_SHARED_LINKER_FLAGS_RELEASEASAN "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+	set(CMAKE_SHARED_LINKER_FLAGS_RELEASEUBSAN "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+	set(CMAKE_SHARED_LINKER_FLAGS_RELEASECOVERAGE "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+	set(CMAKE_SHARED_LINKER_FLAGS_DISTRIBUTION "${CMAKE_SHARED_LINKER_FLAGS_RELEASE}")
+
+	# Public define to instruct user code to import Jolt symbols (rather than use static linking)
+	target_compile_definitions(Jolt PUBLIC JPH_SHARED_LIBRARY)
+
+	# Private define to instruct the library to export symbols for shared linking
+	target_compile_definitions(Jolt PRIVATE JPH_BUILD_SHARED_LIBRARY)
+else()
+	add_library(Jolt STATIC ${JOLT_PHYSICS_SRC_FILES})
+endif()
+
 target_include_directories(Jolt PUBLIC ${PHYSICS_REPO_ROOT})
 target_precompile_headers(Jolt PRIVATE ${JOLT_PHYSICS_ROOT}/Jolt.h)
 target_compile_definitions(Jolt PUBLIC "$<$<CONFIG:Debug>:_DEBUG;JPH_PROFILE_ENABLED;JPH_DEBUG_RENDERER>")

+ 0 - 19
Jolt/Math/UVec4.cpp

@@ -1,19 +0,0 @@
-// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
-// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
-// SPDX-License-Identifier: MIT
-
-#include <Jolt/Jolt.h>
-
-JPH_NAMESPACE_BEGIN
-
-// Table that shifts vector components by 4 - X floats to the left
-const UVec4 UVec4::sFourMinusXShuffle[5] = 
-{
-	UVec4(0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff),
-	UVec4(0x0f0e0d0c, 0xffffffff, 0xffffffff, 0xffffffff),
-	UVec4(0x0b0a0908, 0x0f0e0d0c, 0xffffffff, 0xffffffff),
-	UVec4(0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0xffffffff),
-	UVec4(0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c)
-};
-
-JPH_NAMESPACE_END

+ 0 - 3
Jolt/Math/UVec4.h

@@ -210,9 +210,6 @@ public:
 		Type					mValue;
 		uint32					mU32[4];
 	};
-
-private:
-	static const UVec4			sFourMinusXShuffle[];
 };
 
 static_assert(is_trivial<UVec4>(), "Is supposed to be a trivial type!");

+ 13 - 2
Jolt/Math/UVec4.inl

@@ -546,10 +546,21 @@ UVec4 UVec4::Expand4Byte12() const
 
 UVec4 UVec4::ShiftComponents4Minus(int inCount) const
 {
+#if defined(JPH_USE_SSE4_1) || defined(JPH_USE_NEON)
+	alignas(UVec4) static constexpr uint32 sFourMinusXShuffle[5][4] = 
+	{
+		{ 0xffffffff, 0xffffffff, 0xffffffff, 0xffffffff },
+		{ 0x0f0e0d0c, 0xffffffff, 0xffffffff, 0xffffffff },
+		{ 0x0b0a0908, 0x0f0e0d0c, 0xffffffff, 0xffffffff },
+		{ 0x07060504, 0x0b0a0908, 0x0f0e0d0c, 0xffffffff },
+		{ 0x03020100, 0x07060504, 0x0b0a0908, 0x0f0e0d0c }
+	};
+#endif
+
 #if defined(JPH_USE_SSE4_1)
-	return _mm_shuffle_epi8(mValue, sFourMinusXShuffle[inCount].mValue);
+	return _mm_shuffle_epi8(mValue, *reinterpret_cast<const UVec4::Type *>(sFourMinusXShuffle[inCount]));
 #elif defined(JPH_USE_NEON)
-	uint8x16_t idx = vreinterpretq_u8_u32(sFourMinusXShuffle[inCount].mValue);
+	uint8x16_t idx = vreinterpretq_u8_u32(*reinterpret_cast<const UVec4::Type *>(sFourMinusXShuffle[inCount]));
 	return vreinterpretq_u32_s8(vqtbl1q_s8(vreinterpretq_s8_u32(mValue), idx));
 #else
 	UVec4 result = UVec4::sZero();

+ 1 - 1
Jolt/Math/Vec3.h

@@ -103,7 +103,7 @@ public:
 	static JPH_INLINE Vec3		sUnitSpherical(float inTheta, float inPhi);
 
 	/// A set of vectors uniformly spanning the surface of a unit sphere, usable for debug purposes
-	static const std::vector<Vec3> sUnitSphere;
+	JPH_EXPORT static const std::vector<Vec3> sUnitSphere;
 
 	/// Get random unit vector
 	template <class Random>

+ 8 - 8
Jolt/ObjectStream/ObjectStream.h

@@ -12,7 +12,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Base class for object stream input and output streams.
-class ObjectStream
+class JPH_EXPORT ObjectStream
 {
 public:
 	/// Stream type
@@ -35,7 +35,7 @@ protected:
 };
 
 /// Interface class for reading from an object stream
-class IObjectStreamIn : public ObjectStream
+class JPH_EXPORT IObjectStreamIn : public ObjectStream
 {
 public:
 	///@name Input type specific operations
@@ -69,7 +69,7 @@ public:
 };
 
 /// Interface class for writing to an object stream
-class IObjectStreamOut : public ObjectStream
+class JPH_EXPORT IObjectStreamOut : public ObjectStream
 {
 public:
 	///@name Output type specific operations
@@ -108,11 +108,11 @@ public:
 };
 
 // Define macro to declare functions for a specific primitive type
-#define JPH_DECLARE_PRIMITIVE(name)																	\
-	bool	OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
-	bool	OSReadData(IObjectStreamIn &ioStream, name &outPrimitive);								\
-	void	OSWriteDataType(IObjectStreamOut &ioStream, name *);									\
-	void	OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);
+#define JPH_DECLARE_PRIMITIVE(name)																			\
+	JPH_EXPORT bool	OSIsType(name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
+	JPH_EXPORT bool	OSReadData(IObjectStreamIn &ioStream, name &outPrimitive);								\
+	JPH_EXPORT void	OSWriteDataType(IObjectStreamOut &ioStream, name *);									\
+	JPH_EXPORT void	OSWriteData(IObjectStreamOut &ioStream, const name &inPrimitive);
 
 // This file uses the JPH_DECLARE_PRIMITIVE macro to define all types
 #include <Jolt/ObjectStream/ObjectStreamTypes.h>

+ 1 - 1
Jolt/ObjectStream/ObjectStreamBinaryIn.h

@@ -9,7 +9,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Implementation of ObjectStream binary input stream.
-class ObjectStreamBinaryIn : public ObjectStreamIn
+class JPH_EXPORT ObjectStreamBinaryIn : public ObjectStreamIn
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/ObjectStream/ObjectStreamBinaryOut.h

@@ -9,7 +9,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Implementation of ObjectStream binary output stream.
-class ObjectStreamBinaryOut : public ObjectStreamOut
+class JPH_EXPORT ObjectStreamBinaryOut : public ObjectStreamOut
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/ObjectStream/ObjectStreamIn.h

@@ -17,7 +17,7 @@ JPH_NAMESPACE_BEGIN
 
 /// ObjectStreamIn contains all logic for reading an object from disk. It is the base
 /// class for the text and binary input streams (ObjectStreamTextIn and ObjectStreamBinaryIn).
-class ObjectStreamIn : public IObjectStreamIn
+class JPH_EXPORT ObjectStreamIn : public IObjectStreamIn
 {
 private:
 	struct ClassDescription;

+ 1 - 1
Jolt/ObjectStream/ObjectStreamOut.h

@@ -20,7 +20,7 @@ template <class T> using Queue = std::queue<T, std::deque<T, STLAllocator<T>>>;
 
 /// ObjectStreamOut contains all logic for writing an object to disk. It is the base 
 /// class for the text and binary output streams (ObjectStreamTextOut and ObjectStreamBinaryOut).
-class ObjectStreamOut : public IObjectStreamOut
+class JPH_EXPORT ObjectStreamOut : public IObjectStreamOut
 {
 private:
 	struct ObjectInfo;

+ 1 - 1
Jolt/ObjectStream/ObjectStreamTextIn.h

@@ -9,7 +9,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Implementation of ObjectStream text input stream.
-class ObjectStreamTextIn : public ObjectStreamIn
+class JPH_EXPORT ObjectStreamTextIn : public ObjectStreamIn
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/ObjectStream/ObjectStreamTextOut.h

@@ -9,7 +9,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Implementation of ObjectStream text output stream.
-class ObjectStreamTextOut : public ObjectStreamOut
+class JPH_EXPORT ObjectStreamTextOut : public ObjectStreamOut
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 37 - 37
Jolt/ObjectStream/SerializableObject.h

@@ -13,51 +13,51 @@ JPH_NAMESPACE_BEGIN
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_SERIALIZATION_FUNCTIONS
-#define JPH_DECLARE_SERIALIZATION_FUNCTIONS(prefix, class_name)														\
-	prefix bool			OSReadData(IObjectStreamIn &ioStream, class_name &inInstance);								\
-	prefix bool			OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer);								\
-	prefix bool			OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
-	prefix bool			OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
-	prefix void			OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance);						\
-	prefix void			OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer);						\
-	prefix void			OSWriteDataType(IObjectStreamOut &ioStream, class_name *);									\
-	prefix void			OSWriteDataType(IObjectStreamOut &ioStream, class_name **);
+#define JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, prefix, class_name)											\
+	linkage prefix bool	OSReadData(IObjectStreamIn &ioStream, class_name &inInstance);								\
+	linkage prefix bool	OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer);								\
+	linkage prefix bool	OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
+	linkage prefix bool	OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName);	\
+	linkage prefix void	OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance);						\
+	linkage prefix void	OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer);						\
+	linkage prefix void	OSWriteDataType(IObjectStreamOut &ioStream, class_name *);									\
+	linkage prefix void	OSWriteDataType(IObjectStreamOut &ioStream, class_name **);
 
 // JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS
 #define JPH_IMPLEMENT_SERIALIZATION_FUNCTIONS(class_name)															\
-	bool				OSReadData(IObjectStreamIn &ioStream, class_name &inInstance)								\
+	bool		OSReadData(IObjectStreamIn &ioStream, class_name &inInstance)										\
 	{																												\
 		return ioStream.ReadClassData(#class_name, (void *)&inInstance);											\
 	}																												\
-	bool				OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer)								\
+	bool		OSReadData(IObjectStreamIn &ioStream, class_name *&inPointer)										\
 	{																												\
 		return ioStream.ReadPointerData(JPH_RTTI(class_name), (void **)&inPointer);									\
 	}																												\
-	bool				OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)	\
+	bool		OSIsType(class_name *, int inArrayDepth, EOSDataType inDataType, const char *inClassName)			\
 	{																												\
 		return inArrayDepth == 0 && inDataType == EOSDataType::Instance && strcmp(inClassName, #class_name) == 0;	\
 	}																												\
-	bool				OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName)	\
+	bool		OSIsType(class_name **, int inArrayDepth, EOSDataType inDataType, const char *inClassName)			\
 	{																												\
 		return inArrayDepth == 0 && inDataType == EOSDataType::Pointer && strcmp(inClassName, #class_name) == 0;	\
 	}																												\
-	void				OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance)						\
+	void		OSWriteData(IObjectStreamOut &ioStream, const class_name &inInstance)								\
 	{																												\
 		ioStream.WriteClassData(JPH_RTTI(class_name), (void *)&inInstance);											\
 	}																												\
-	void				OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer)						\
+	void		OSWriteData(IObjectStreamOut &ioStream, class_name *const &inPointer)								\
 	{																												\
 		if (inPointer)																								\
 			ioStream.WritePointerData(GetRTTI(inPointer), (void *)inPointer);										\
 		else 																										\
 			ioStream.WritePointerData(nullptr, nullptr);															\
 	}																												\
-	void				OSWriteDataType(IObjectStreamOut &ioStream, class_name *)									\
+	void		OSWriteDataType(IObjectStreamOut &ioStream, class_name *)											\
 	{																												\
 		ioStream.WriteDataType(EOSDataType::Instance);																\
 		ioStream.WriteName(#class_name);																			\
 	}																												\
-	void				OSWriteDataType(IObjectStreamOut &ioStream, class_name **)									\
+	void		OSWriteDataType(IObjectStreamOut &ioStream, class_name **)											\
 	{																												\
 		ioStream.WriteDataType(EOSDataType::Pointer);																\
 		ioStream.WriteName(#class_name);																			\
@@ -68,10 +68,10 @@ JPH_NAMESPACE_BEGIN
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL
-#define JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(class_name)															\
+#define JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(linkage, class_name)													\
 public:																												\
-	JPH_DECLARE_RTTI_NON_VIRTUAL(class_name)																		\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(friend, class_name)															\
+	JPH_DECLARE_RTTI_NON_VIRTUAL(linkage, class_name)																\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL
 #define JPH_IMPLEMENT_SERIALIZABLE_NON_VIRTUAL(class_name)															\
@@ -83,9 +83,9 @@ public:																												\
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS
-#define JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(class_name)															\
-	JPH_DECLARE_RTTI_OUTSIDE_CLASS(class_name)																		\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(extern, class_name)															\
+#define JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(linkage, class_name)													\
+	JPH_DECLARE_RTTI_OUTSIDE_CLASS(linkage, class_name)																\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, extern, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS
 #define JPH_IMPLEMENT_SERIALIZABLE_OUTSIDE_CLASS(class_name)														\
@@ -97,10 +97,10 @@ public:																												\
 //////////////////////////////////////////////////////////////////////////////////////////
 
 // JPH_DECLARE_SERIALIZABLE_VIRTUAL - Use for concrete, non-base classes
-#define JPH_DECLARE_SERIALIZABLE_VIRTUAL(class_name)																\
+#define JPH_DECLARE_SERIALIZABLE_VIRTUAL(linkage, class_name)														\
 public:																												\
-	JPH_DECLARE_RTTI_VIRTUAL(class_name)																			\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(friend, class_name)															\
+	JPH_DECLARE_RTTI_VIRTUAL(linkage, class_name)																	\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL
 #define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL(class_name)																\
@@ -108,10 +108,10 @@ public:																												\
 	JPH_IMPLEMENT_RTTI_VIRTUAL(class_name)																			\
 
 // JPH_DECLARE_SERIALIZABLE_ABSTRACT - Use for abstract, non-base classes
-#define JPH_DECLARE_SERIALIZABLE_ABSTRACT(class_name)																\
+#define JPH_DECLARE_SERIALIZABLE_ABSTRACT(linkage, class_name)														\
 public:																												\
-	JPH_DECLARE_RTTI_ABSTRACT(class_name)																			\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(friend, class_name)															\
+	JPH_DECLARE_RTTI_ABSTRACT(linkage, class_name)																	\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT
 #define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT(class_name)																\
@@ -119,10 +119,10 @@ public:																												\
 	JPH_IMPLEMENT_RTTI_ABSTRACT(class_name)																			\
 
 // JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE - Use for concrete base classes
-#define JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE(class_name)															\
+#define JPH_DECLARE_SERIALIZABLE_VIRTUAL_BASE(linkage, class_name)													\
 public:																												\
-	JPH_DECLARE_RTTI_VIRTUAL_BASE(class_name)																		\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(friend, class_name)															\
+	JPH_DECLARE_RTTI_VIRTUAL_BASE(linkage, class_name)																\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE
 #define JPH_IMPLEMENT_SERIALIZABLE_VIRTUAL_BASE(class_name)															\
@@ -130,10 +130,10 @@ public:																												\
 	JPH_IMPLEMENT_RTTI_VIRTUAL_BASE(class_name)																		\
 
 // JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE - Use for abstract base class
-#define JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(class_name)															\
+#define JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(linkage, class_name)													\
 public:																												\
-	JPH_DECLARE_RTTI_ABSTRACT_BASE(class_name)																		\
-	JPH_DECLARE_SERIALIZATION_FUNCTIONS(friend, class_name)															\
+	JPH_DECLARE_RTTI_ABSTRACT_BASE(linkage, class_name)																\
+	JPH_DECLARE_SERIALIZATION_FUNCTIONS(linkage, friend, class_name)												\
 
 // JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE
 #define JPH_IMPLEMENT_SERIALIZABLE_ABSTRACT_BASE(class_name)														\
@@ -143,9 +143,9 @@ public:																												\
 /// Classes must be derived from SerializableObject if you want to be able to save pointers or
 /// reference counting pointers to objects of this or derived classes. The type will automatically
 /// be determined during serialization and upon deserialization it will be restored correctly.
-class SerializableObject
+class JPH_EXPORT SerializableObject
 {
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(SerializableObject)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT_BASE(JPH_EXPORT, SerializableObject)
 
 public:
 	/// Constructor

+ 21 - 21
Jolt/ObjectStream/TypeDeclarations.h

@@ -12,27 +12,27 @@
 
 JPH_NAMESPACE_BEGIN
 
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint8);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint16);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(int);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint32);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(uint64);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(float);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(double);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(bool);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(String);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Float3);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Double3);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec3);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(DVec3);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Vec4);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Quat);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(Mat44);
-JPH_DECLARE_RTTI_OUTSIDE_CLASS(DMat44);
-JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(Color);
-JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(AABox);
-JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(Triangle);
-JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(IndexedTriangle);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint8);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint16);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, int);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint32);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, uint64);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, float);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, double);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, bool);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, String);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Float3);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Double3);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Vec3);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, DVec3);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Vec4);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Quat);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, Mat44);
+JPH_DECLARE_RTTI_OUTSIDE_CLASS(JPH_EXPORT, DMat44);
+JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, Color);
+JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, AABox);
+JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, Triangle);
+JPH_DECLARE_SERIALIZABLE_OUTSIDE_CLASS(JPH_EXPORT, IndexedTriangle);
 
 JPH_NAMESPACE_END
 

+ 1 - 1
Jolt/Physics/Body/Body.h

@@ -29,7 +29,7 @@ class BodyCreationSettings;
 /// The functions that get/set the position of the body all indicate if they are relative to the center of mass or to the original position in which the shape was created.
 ///
 /// The linear velocity is also velocity of the center of mass, to correct for this: \f$VelocityCOM = Velocity - AngularVelocity \times ShapeCOM\f$.
-class alignas(JPH_RVECTOR_ALIGNMENT) Body : public NonCopyable
+class alignas(JPH_RVECTOR_ALIGNMENT) JPH_EXPORT Body : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Physics/Body/BodyCreationSettings.h

@@ -25,10 +25,10 @@ enum class EOverrideMassProperties : uint8
 };
 
 /// Settings for constructing a rigid body
-class BodyCreationSettings
+class JPH_EXPORT BodyCreationSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(BodyCreationSettings)
+	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, BodyCreationSettings)
 
 	/// Constructor
 							BodyCreationSettings() = default;

+ 1 - 1
Jolt/Physics/Body/BodyInterface.h

@@ -27,7 +27,7 @@ class TwoBodyConstraint;
 
 /// Class that provides operations on bodies using a body ID. Note that if you need to do multiple operations on a single body, it is more efficient to lock the body once and combine the operations.
 /// All quantities are in world space unless otherwise specified.
-class BodyInterface : public NonCopyable
+class JPH_EXPORT BodyInterface : public NonCopyable
 {
 public:
 	/// Initialize the interface (should only be called by PhysicsSystem)

+ 22 - 2
Jolt/Physics/Body/BodyManager.cpp

@@ -20,8 +20,28 @@
 JPH_NAMESPACE_BEGIN
 
 #ifdef JPH_ENABLE_ASSERTS
-	thread_local bool BodyManager::sOverrideAllowActivation = false;
-	thread_local bool BodyManager::sOverrideAllowDeactivation = false;
+	static thread_local bool sOverrideAllowActivation = false;
+	static thread_local bool sOverrideAllowDeactivation = false;
+
+	bool BodyManager::sGetOverrideAllowActivation()
+	{
+		return sOverrideAllowActivation;
+	}
+
+	void BodyManager::sSetOverrideAllowActivation(bool inValue)
+	{
+		sOverrideAllowActivation = inValue;
+	}
+
+	bool BodyManager::sGetOverrideAllowDeactivation()
+	{
+		return sOverrideAllowDeactivation;
+	}
+
+	void BodyManager::sSetOverrideAllowDeactivation(bool inValue)
+	{
+		sOverrideAllowDeactivation = inValue;
+	}
 #endif
 
 // Helper class that combines a body and its motion properties

+ 13 - 9
Jolt/Physics/Body/BodyManager.h

@@ -26,7 +26,7 @@ using BodyVector = Array<Body *>;
 using BodyIDVector = Array<BodyID>;
 
 /// Class that contains all bodies
-class BodyManager : public NonCopyable
+class JPH_EXPORT BodyManager : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -209,17 +209,17 @@ public:
 	public:
 		inline GrantActiveBodiesAccess(bool inAllowActivation, bool inAllowDeactivation)
 		{
-			JPH_ASSERT(!sOverrideAllowActivation);
-			sOverrideAllowActivation = inAllowActivation;
+			JPH_ASSERT(!sGetOverrideAllowActivation());
+			sSetOverrideAllowActivation(inAllowActivation);
 
-			JPH_ASSERT(!sOverrideAllowDeactivation);
-			sOverrideAllowDeactivation = inAllowDeactivation;
+			JPH_ASSERT(!sGetOverrideAllowDeactivation());
+			sSetOverrideAllowDeactivation(inAllowDeactivation);
 		}
 
 		inline ~GrantActiveBodiesAccess()
 		{
-			sOverrideAllowActivation = false;
-			sOverrideAllowDeactivation = false;
+			sSetOverrideAllowActivation(false);
+			sSetOverrideAllowDeactivation(false);
 		}
 	};
 #endif
@@ -300,10 +300,14 @@ private:
 	const BroadPhaseLayerInterface *mBroadPhaseLayerInterface = nullptr;
 
 #ifdef JPH_ENABLE_ASSERTS
+	static bool						sGetOverrideAllowActivation();
+	static void						sSetOverrideAllowActivation(bool inValue);
+
+	static bool						sGetOverrideAllowDeactivation();
+	static void						sSetOverrideAllowDeactivation(bool inValue);
+
 	/// Debug system that tries to limit changes to active bodies during the PhysicsSystem::Update()
 	bool							mActiveBodiesLocked = false;
-	static thread_local bool		sOverrideAllowActivation;
-	static thread_local bool		sOverrideAllowDeactivation;
 #endif
 };
 

+ 2 - 2
Jolt/Physics/Body/MassProperties.h

@@ -12,10 +12,10 @@ class StreamIn;
 class StreamOut;
 
 /// Describes the mass and inertia properties of a body. Used during body construction only.
-class MassProperties
+class JPH_EXPORT MassProperties
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(MassProperties)
+	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, MassProperties)
 
 	/// Using eigendecomposition, decompose the inertia tensor into a diagonal matrix D and a right-handed rotation matrix R so that the inertia tensor is \f$R \: D \: R^{-1}\f$.
 	/// @see https://en.wikipedia.org/wiki/Moment_of_inertia section 'Principal axes'

+ 1 - 1
Jolt/Physics/Body/MotionProperties.h

@@ -16,7 +16,7 @@ JPH_NAMESPACE_BEGIN
 class StateRecorder;
 
 /// The Body class only keeps track of state for static bodies, the MotionProperties class keeps the additional state needed for a moving Body. It has a 1-on-1 relationship with the body.
-class MotionProperties
+class JPH_EXPORT MotionProperties
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Physics/Character/Character.h

@@ -10,7 +10,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Contains the configuration of a character
-class CharacterSettings : public CharacterBaseSettings
+class JPH_EXPORT CharacterSettings : public CharacterBaseSettings
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -32,7 +32,7 @@ public:
 /// This object usually represents the player or a humanoid AI. It uses a single rigid body, 
 /// usually with a capsule shape to simulate movement and collision for the character.
 /// The character is a keyframed object, the application controls it by setting the velocity.
-class Character : public CharacterBase
+class JPH_EXPORT Character : public CharacterBase
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Physics/Character/CharacterBase.h

@@ -17,7 +17,7 @@ class PhysicsSystem;
 class StateRecorder;
 
 /// Base class for configuration of a character
-class CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
+class JPH_EXPORT CharacterBaseSettings : public RefTarget<CharacterBaseSettings>
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -42,7 +42,7 @@ public:
 };
 
 /// Base class for character class
-class CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
+class JPH_EXPORT CharacterBase : public RefTarget<CharacterBase>, public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Character/CharacterVirtual.h

@@ -16,7 +16,7 @@ JPH_NAMESPACE_BEGIN
 class CharacterVirtual;
 
 /// Contains the configuration of a character
-class CharacterVirtualSettings : public CharacterBaseSettings
+class JPH_EXPORT CharacterVirtualSettings : public CharacterBaseSettings
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE
@@ -52,7 +52,7 @@ public:
 };
 
 /// This class receives callbacks when a virtual character hits something.
-class CharacterContactListener
+class JPH_EXPORT CharacterContactListener
 {
 public:
 	/// Destructor
@@ -92,7 +92,7 @@ public:
 /// The advantage of this is that you can determine when the character moves in the frame (usually this has to happen at a very particular point in the frame)
 /// but the downside is that other objects don't see this virtual character. In order to make this work it is recommended to pair a CharacterVirtual with a Character that
 /// moves along. This Character should be keyframed (or at least have no gravity) and move along with the CharacterVirtual so that other rigid bodies can collide with it.
-class CharacterVirtual : public CharacterBase
+class JPH_EXPORT CharacterVirtual : public CharacterBase
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhase.h

@@ -22,7 +22,7 @@ struct BodyPair;
 using BodyPairCollector = CollisionCollector<BodyPair, CollisionCollectorTraitsCollideShape>;
 
 /// Used to do coarse collision detection operations to quickly prune out bodies that will not collide.
-class BroadPhase : public BroadPhaseQuery
+class JPH_EXPORT BroadPhase : public BroadPhaseQuery
 {
 public:
 	/// Initialize the broadphase.

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhaseBruteForce.h

@@ -10,7 +10,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Test BroadPhase implementation that does not do anything to speed up the operations. Can be used as a reference implementation.
-class BroadPhaseBruteForce final : public BroadPhase
+class JPH_EXPORT BroadPhaseBruteForce final : public BroadPhase
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhaseQuadTree.h

@@ -11,7 +11,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Fast SIMD based quad tree BroadPhase that is multithreading aware and tries to do a minimal amount of locking.
-class BroadPhaseQuadTree final : public BroadPhase
+class JPH_EXPORT BroadPhaseQuadTree final : public BroadPhase
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/BroadPhaseQuery.h

@@ -25,7 +25,7 @@ using CollideShapeBodyCollector = CollisionCollector<BodyID, CollisionCollectorT
 
 /// Interface to the broadphase that can perform collision queries. These queries will only test the bounding box of the body to quickly determine a potential set of colliding bodies.
 /// The shapes of the bodies are not tested, if you want this then you should use the NarrowPhaseQuery interface.
-class BroadPhaseQuery : public NonCopyable
+class JPH_EXPORT BroadPhaseQuery : public NonCopyable
 {
 public:
 	/// Virtual destructor

+ 1 - 1
Jolt/Physics/Collision/BroadPhase/QuadTree.h

@@ -17,7 +17,7 @@ JPH_NAMESPACE_BEGIN
 /// Internal tree structure in broadphase, is essentially a quad AABB tree.
 /// Tree is lockless (except for UpdatePrepare/Finalize() function), modifying objects in the tree will widen the aabbs of parent nodes to make the node fit.
 /// During the UpdatePrepare/Finalize() call the tree is rebuilt to achieve a tight fit again.
-class QuadTree : public NonCopyable
+class JPH_EXPORT QuadTree : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Collision/CastConvexVsTriangles.h

@@ -10,7 +10,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Collision detection helper that casts a convex object vs one or more triangles
-class CastConvexVsTriangles
+class JPH_EXPORT CastConvexVsTriangles
 {
 public:
 	/// Constructor

+ 1 - 1
Jolt/Physics/Collision/CastSphereVsTriangles.h

@@ -9,7 +9,7 @@
 JPH_NAMESPACE_BEGIN
 
 /// Collision detection helper that casts a sphere vs one or more triangles
-class CastSphereVsTriangles
+class JPH_EXPORT CastSphereVsTriangles
 {
 public:
 	/// Constructor

+ 1 - 1
Jolt/Physics/Collision/CollideConvexVsTriangles.h

@@ -14,7 +14,7 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Collision detection helper that collides a convex object vs one or more triangles
-class CollideConvexVsTriangles
+class JPH_EXPORT CollideConvexVsTriangles
 {
 public:
 	/// Constructor

+ 1 - 1
Jolt/Physics/Collision/CollideSphereVsTriangles.h

@@ -13,7 +13,7 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Collision detection helper that collides a sphere vs one or more triangles
-class CollideSphereVsTriangles
+class JPH_EXPORT CollideSphereVsTriangles
 {
 public:
 	/// Constructor

+ 1 - 1
Jolt/Physics/Collision/CollisionDispatch.h

@@ -15,7 +15,7 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Dispatch function, main function to handle collisions between shapes
-class CollisionDispatch
+class JPH_EXPORT CollisionDispatch
 {
 public:
 	/// Collide 2 shapes and pass any collision on to ioCollector

+ 2 - 2
Jolt/Physics/Collision/CollisionGroup.h

@@ -16,10 +16,10 @@ class StreamOut;
 /// - Both don't have a group filter
 /// - The first group filter says that the objects can collide
 /// - Or if there's no filter for the first object, the second group filter says the objects can collide
-class CollisionGroup
+class JPH_EXPORT CollisionGroup
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(CollisionGroup)
+	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, CollisionGroup)
 
 	using GroupID			= uint32;
 	using SubGroupID		= uint32;

+ 1 - 1
Jolt/Physics/Collision/EstimateCollisionResponse.h

@@ -43,6 +43,6 @@ struct CollisionEstimationResult
 /// @param inCombinedRestitution The combined restitution of body 1 and body 2 (see ContactSettings::mCombinedRestitution)
 /// @param inMinVelocityForRestitution Minimal velocity required for restitution to be applied (see PhysicsSettings::mMinVelocityForRestitution)
 /// @param inNumIterations Number of iterations to use for the impulse estimation (see PhysicsSettings::mNumVelocitySteps, note you can probably use a lower number for a decent estimate). If you set the number of iterations to 1 then no friction will be calculated.
-void EstimateCollisionResponse(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, CollisionEstimationResult &outResult, float inCombinedFriction, float inCombinedRestitution, float inMinVelocityForRestitution = 1.0f, uint inNumIterations = 10);
+JPH_EXPORT void EstimateCollisionResponse(const Body &inBody1, const Body &inBody2, const ContactManifold &inManifold, CollisionEstimationResult &outResult, float inCombinedFriction, float inCombinedRestitution, float inMinVelocityForRestitution = 1.0f, uint inNumIterations = 10);
 
 JPH_NAMESPACE_END

+ 2 - 2
Jolt/Physics/Collision/GroupFilter.h

@@ -14,10 +14,10 @@ class StreamIn;
 class StreamOut;
 
 /// Abstract class that checks if two CollisionGroups collide
-class GroupFilter : public SerializableObject, public RefTarget<GroupFilter>
+class JPH_EXPORT GroupFilter : public SerializableObject, public RefTarget<GroupFilter>
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT(GroupFilter)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT(JPH_EXPORT, GroupFilter)
 
 	/// Virtual destructor
 	virtual						~GroupFilter() override = default;

+ 2 - 2
Jolt/Physics/Collision/GroupFilterTable.h

@@ -32,9 +32,9 @@ JPH_NAMESPACE_BEGIN
 /// . is a bit we don't need to store because the table is symmetric, we take care that group 2 > group 1 always by swapping the elements if needed
 ///
 /// The total number of bits we need to store is (N * (N - 1)) / 2
-class GroupFilterTable final : public GroupFilter
+class JPH_EXPORT GroupFilterTable final : public GroupFilter
 {
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(GroupFilterTable)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, GroupFilterTable)
 
 private:
 	using GroupID = CollisionGroup::GroupID;

+ 2 - 2
Jolt/Physics/Collision/ManifoldBetweenTwoFaces.h

@@ -17,7 +17,7 @@ JPH_NAMESPACE_BEGIN
 #ifdef JPH_DEBUG_RENDERER
 /// @param inCenterOfMass Center of mass position of body 1
 #endif
-void PruneContactPoints(Vec3Arg inPenetrationAxis, ContactPoints &ioContactPointsOn1, ContactPoints &ioContactPointsOn2
+JPH_EXPORT void PruneContactPoints(Vec3Arg inPenetrationAxis, ContactPoints &ioContactPointsOn1, ContactPoints &ioContactPointsOn2
 #ifdef JPH_DEBUG_RENDERER
 	, RVec3Arg inCenterOfMass
 #endif
@@ -35,7 +35,7 @@ void PruneContactPoints(Vec3Arg inPenetrationAxis, ContactPoints &ioContactPoint
 #ifdef JPH_DEBUG_RENDERER
 /// @param inCenterOfMass Center of mass position of body 1
 #endif
-void ManifoldBetweenTwoFaces(Vec3Arg inContactPoint1, Vec3Arg inContactPoint2, Vec3Arg inPenetrationAxis, float inSpeculativeContactDistanceSq, const ConvexShape::SupportingFace &inShape1Face, const ConvexShape::SupportingFace &inShape2Face, ContactPoints &outContactPoints1, ContactPoints &outContactPoints2
+JPH_EXPORT void ManifoldBetweenTwoFaces(Vec3Arg inContactPoint1, Vec3Arg inContactPoint2, Vec3Arg inPenetrationAxis, float inSpeculativeContactDistanceSq, const ConvexShape::SupportingFace &inShape1Face, const ConvexShape::SupportingFace &inShape2Face, ContactPoints &outContactPoints1, ContactPoints &outContactPoints2
 #ifdef JPH_DEBUG_RENDERER
 	, RVec3Arg inCenterOfMass
 #endif

+ 1 - 1
Jolt/Physics/Collision/NarrowPhaseQuery.h

@@ -19,7 +19,7 @@ class RayCastResult;
 
 /// Class that provides an interface for doing precise collision detection against the broad and then the narrow phase.
 /// Unlike a BroadPhaseQuery, the NarrowPhaseQuery will test against shapes and will return collision information against triangles, spheres etc.
-class NarrowPhaseQuery : public NonCopyable
+class JPH_EXPORT NarrowPhaseQuery : public NonCopyable
 {
 public:
 	/// Initialize the interface (should only be called by PhysicsSystem)

+ 2 - 2
Jolt/Physics/Collision/PhysicsMaterial.h

@@ -19,10 +19,10 @@ class StreamOut;
 /// to decide which sound or particle effects to play.
 ///
 /// If you inherit from this material, don't forget to create a suitable default material in sDefault
-class PhysicsMaterial : public SerializableObject, public RefTarget<PhysicsMaterial>
+class JPH_EXPORT PhysicsMaterial : public SerializableObject, public RefTarget<PhysicsMaterial>
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(PhysicsMaterial)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, PhysicsMaterial)
 
 	/// Virtual destructor
 	virtual									~PhysicsMaterial() override = default;

+ 2 - 2
Jolt/Physics/Collision/PhysicsMaterialSimple.h

@@ -9,10 +9,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Sample implementation of PhysicsMaterial that just holds the needed properties directly
-class PhysicsMaterialSimple : public PhysicsMaterial
+class JPH_EXPORT PhysicsMaterialSimple : public PhysicsMaterial
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(PhysicsMaterialSimple)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, PhysicsMaterialSimple)
 
 	/// Constructor
 											PhysicsMaterialSimple() = default;

+ 3 - 3
Jolt/Physics/Collision/Shape/BoxShape.h

@@ -10,10 +10,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a BoxShape
-class BoxShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT BoxShapeSettings final : public ConvexShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(BoxShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, BoxShapeSettings)
 
 	/// Default constructor for deserialization
 							BoxShapeSettings() = default;
@@ -30,7 +30,7 @@ public:
 };
 
 /// A box, centered around the origin
-class BoxShape final : public ConvexShape
+class JPH_EXPORT BoxShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/CapsuleShape.h

@@ -9,9 +9,9 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a CapsuleShape
-class CapsuleShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT CapsuleShapeSettings final : public ConvexShapeSettings
 {
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(CapsuleShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, CapsuleShapeSettings)
 
 	/// Default constructor for deserialization
 							CapsuleShapeSettings() = default;
@@ -33,7 +33,7 @@ class CapsuleShapeSettings final : public ConvexShapeSettings
 };
 
 /// A capsule, implemented as a line segment with convex radius
-class CapsuleShape final : public ConvexShape
+class JPH_EXPORT CapsuleShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 4 - 4
Jolt/Physics/Collision/Shape/CompoundShape.h

@@ -14,10 +14,10 @@ class CollideShapeSettings;
 class OrientedBox;
 
 /// Base class settings to construct a compound shape
-class CompoundShapeSettings : public ShapeSettings
+class JPH_EXPORT CompoundShapeSettings : public ShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT(CompoundShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT(JPH_EXPORT, CompoundShapeSettings)
 
 	/// Constructor. Use AddShape to add the parts.
 									CompoundShapeSettings() = default;
@@ -30,7 +30,7 @@ public:
 
 	struct SubShapeSettings
 	{
-		JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(SubShapeSettings)
+		JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, SubShapeSettings)
 
 		RefConst<ShapeSettings>		mShape;													///< Sub shape (either this or mShapePtr needs to be filled up)
 		RefConst<Shape>				mShapePtr;												///< Sub shape (either this or mShape needs to be filled up)
@@ -45,7 +45,7 @@ public:
 };
 
 /// Base class for a compound shape
-class CompoundShape : public Shape
+class JPH_EXPORT CompoundShape : public Shape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/ConvexHullShape.h

@@ -14,10 +14,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a ConvexHullShape
-class ConvexHullShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT ConvexHullShapeSettings final : public ConvexShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(ConvexHullShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ConvexHullShapeSettings)
 
 	/// Default constructor for deserialization
 							ConvexHullShapeSettings() = default;
@@ -37,7 +37,7 @@ public:
 };
 
 /// A convex hull
-class ConvexHullShape final : public ConvexShape
+class JPH_EXPORT ConvexHullShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/ConvexShape.h

@@ -14,10 +14,10 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Class that constructs a ConvexShape (abstract)
-class ConvexShapeSettings : public ShapeSettings
+class JPH_EXPORT ConvexShapeSettings : public ShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT(ConvexShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT(JPH_EXPORT, ConvexShapeSettings)
 
 	/// Constructor
 									ConvexShapeSettings() = default;
@@ -32,7 +32,7 @@ public:
 };
 
 /// Base class for all convex shapes. Defines a virtual interface.
-class ConvexShape : public Shape
+class JPH_EXPORT ConvexShape : public Shape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/CylinderShape.h

@@ -10,10 +10,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a CylinderShape
-class CylinderShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT CylinderShapeSettings final : public ConvexShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(CylinderShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, CylinderShapeSettings)
 
 	/// Default constructor for deserialization
 							CylinderShapeSettings() = default;
@@ -31,7 +31,7 @@ public:
 };
 
 /// A cylinder
-class CylinderShape final : public ConvexShape
+class JPH_EXPORT CylinderShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/DecoratedShape.h

@@ -9,9 +9,9 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a DecoratedShape
-class DecoratedShapeSettings : public ShapeSettings
+class JPH_EXPORT DecoratedShapeSettings : public ShapeSettings
 {
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(DecoratedShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, DecoratedShapeSettings)
 
 	/// Default constructor for deserialization
 									DecoratedShapeSettings() = default;
@@ -25,7 +25,7 @@ class DecoratedShapeSettings : public ShapeSettings
 };
 
 /// Base class for shapes that decorate another shape with extra functionality (e.g. scale, translation etc.)
-class DecoratedShape : public Shape
+class JPH_EXPORT DecoratedShape : public Shape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/HeightFieldShape.h

@@ -35,10 +35,10 @@ namespace HeightFieldShapeConstants
 };
 
 /// Class that constructs a HeightFieldShape
-class HeightFieldShapeSettings final : public ShapeSettings
+class JPH_EXPORT HeightFieldShapeSettings final : public ShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(HeightFieldShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, HeightFieldShapeSettings)
 
 	/// Default constructor for deserialization
 									HeightFieldShapeSettings() = default;
@@ -89,7 +89,7 @@ public:
 };
 
 /// A height field shape. Cannot be used as a dynamic object.
-class HeightFieldShape final : public Shape
+class JPH_EXPORT HeightFieldShape final : public Shape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/MeshShape.h

@@ -19,10 +19,10 @@ class ConvexShape;
 class CollideShapeSettings;
 
 /// Class that constructs a MeshShape
-class MeshShapeSettings final : public ShapeSettings
+class JPH_EXPORT MeshShapeSettings final : public ShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(MeshShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, MeshShapeSettings)
 
 	/// Default constructor for deserialization
 									MeshShapeSettings() = default;
@@ -52,7 +52,7 @@ public:
 /// A mesh shape, consisting of triangles. Mesh shapes are mostly used for static geometry.
 /// They can be used by dynamic or kinematic objects but only if they don't collide with other mesh or heightfield shapes as those collisions are currently not supported.
 /// Note that if you make a mesh shape a dynamic or kinematic object, you need to provide a mass yourself as mesh shapes don't need to form a closed hull so don't have a well defined volume from which the mass can be calculated.
-class MeshShape final : public Shape
+class JPH_EXPORT MeshShape final : public Shape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/MutableCompoundShape.h

@@ -11,10 +11,10 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Class that constructs a MutableCompoundShape.
-class MutableCompoundShapeSettings final : public CompoundShapeSettings
+class JPH_EXPORT MutableCompoundShapeSettings final : public CompoundShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(MutableCompoundShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, MutableCompoundShapeSettings)
 
 	// See: ShapeSettings
 	virtual ShapeResult				Create() const override;
@@ -27,7 +27,7 @@ public:
 /// Note: If you're using MutableCompoundShapes and are querying data while modifying the shape you'll have a race condition. 
 /// In this case it is best to create a new MutableCompoundShape and set the new shape on the body using BodyInterface::SetShape. If a 
 /// query is still working on the old shape, it will have taken a reference and keep the old shape alive until the query finishes.
-class MutableCompoundShape final : public CompoundShape
+class JPH_EXPORT MutableCompoundShape final : public CompoundShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/OffsetCenterOfMassShape.h

@@ -11,10 +11,10 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Class that constructs an OffsetCenterOfMassShape
-class OffsetCenterOfMassShapeSettings final : public DecoratedShapeSettings
+class JPH_EXPORT OffsetCenterOfMassShapeSettings final : public DecoratedShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(OffsetCenterOfMassShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, OffsetCenterOfMassShapeSettings)
 
 	/// Constructor
 									OffsetCenterOfMassShapeSettings() = default;
@@ -32,7 +32,7 @@ public:
 };
 
 /// This shape will shift the center of mass of a child shape, it can e.g. be used to lower the center of mass of an unstable object like a boat to make it stable
-class OffsetCenterOfMassShape final : public DecoratedShape
+class JPH_EXPORT OffsetCenterOfMassShape final : public DecoratedShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/RotatedTranslatedShape.h

@@ -12,10 +12,10 @@ JPH_NAMESPACE_BEGIN
 class CollideShapeSettings;
 
 /// Class that constructs a RotatedTranslatedShape
-class RotatedTranslatedShapeSettings final : public DecoratedShapeSettings
+class JPH_EXPORT RotatedTranslatedShapeSettings final : public DecoratedShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(RotatedTranslatedShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, RotatedTranslatedShapeSettings)
 
 	/// Constructor
 									RotatedTranslatedShapeSettings() = default;
@@ -35,7 +35,7 @@ public:
 
 /// A rotated translated shape will rotate and translate a child shape.
 /// Shifts the child object so that it is centered around the center of mass.
-class RotatedTranslatedShape final : public DecoratedShape
+class JPH_EXPORT RotatedTranslatedShape final : public DecoratedShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/ScaledShape.h

@@ -12,9 +12,9 @@ class SubShapeIDCreator;
 class CollideShapeSettings;
 
 /// Class that constructs a ScaledShape
-class ScaledShapeSettings final : public DecoratedShapeSettings
+class JPH_EXPORT ScaledShapeSettings final : public DecoratedShapeSettings
 {
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(ScaledShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ScaledShapeSettings)
 
 	/// Default constructor for deserialization
 									ScaledShapeSettings() = default;
@@ -32,7 +32,7 @@ class ScaledShapeSettings final : public DecoratedShapeSettings
 };
 
 /// A shape that scales a child shape in local space of that shape. The scale can be non-uniform and can even turn it inside out when one or three components of the scale are negative.
-class ScaledShape final : public DecoratedShape
+class JPH_EXPORT ScaledShape final : public DecoratedShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 4 - 4
Jolt/Physics/Collision/Shape/Shape.h

@@ -131,10 +131,10 @@ static_assert(size(sSubShapeTypeNames) == NumSubShapeTypes);
 /// in a form that is optimized for collision detection. After this, the ShapeSettings object is no longer needed
 /// and can be destroyed. Each shape class has a derived class of the ShapeSettings object to store shape specific
 /// data.
-class ShapeSettings : public SerializableObject, public RefTarget<ShapeSettings>
+class JPH_EXPORT ShapeSettings : public SerializableObject, public RefTarget<ShapeSettings>
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT(ShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT(JPH_EXPORT, ShapeSettings)
 
 	using ShapeResult = Result<Ref<Shape>>;
 
@@ -149,7 +149,7 @@ protected:
 };
 
 /// Function table for functions on shapes
-class ShapeFunctions
+class JPH_EXPORT ShapeFunctions
 {
 public:
 	/// Construct a shape
@@ -166,7 +166,7 @@ private:
 };
 
 /// Base class for all shapes (collision volume of a body). Defines a virtual interface for collision detection.
-class Shape : public RefTarget<Shape>, public NonCopyable
+class JPH_EXPORT Shape : public RefTarget<Shape>, public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/SphereShape.h

@@ -9,10 +9,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a SphereShape
-class SphereShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT SphereShapeSettings final : public ConvexShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(SphereShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, SphereShapeSettings)
 
 	/// Default constructor for deserialization
 							SphereShapeSettings() = default;
@@ -28,7 +28,7 @@ public:
 
 /// A sphere, centered around the origin.
 /// Note that it is implemented as a point with convex radius.
-class SphereShape final : public ConvexShape
+class JPH_EXPORT SphereShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/StaticCompoundShape.h

@@ -14,10 +14,10 @@ class CollideShapeSettings;
 class TempAllocator;
 
 /// Class that constructs a StaticCompoundShape. Note that if you only want a compound of 1 shape, use a RotatedTranslatedShape instead.
-class StaticCompoundShapeSettings final : public CompoundShapeSettings
+class JPH_EXPORT StaticCompoundShapeSettings final : public CompoundShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(StaticCompoundShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, StaticCompoundShapeSettings)
 
 	// See: ShapeSettings
 	virtual ShapeResult				Create() const override;
@@ -29,7 +29,7 @@ public:
 /// A compound shape, sub shapes can be rotated and translated.
 /// Sub shapes cannot be modified once the shape is constructed.
 /// Shifts all child objects so that they're centered around the center of mass.
-class StaticCompoundShape final : public CompoundShape
+class JPH_EXPORT StaticCompoundShape final : public CompoundShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/TaperedCapsuleShape.h

@@ -12,9 +12,9 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a TaperedCapsuleShape
-class TaperedCapsuleShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT TaperedCapsuleShapeSettings final : public ConvexShapeSettings
 {
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(TaperedCapsuleShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, TaperedCapsuleShapeSettings)
 
 	/// Default constructor for deserialization
 							TaperedCapsuleShapeSettings() = default;
@@ -37,7 +37,7 @@ class TaperedCapsuleShapeSettings final : public ConvexShapeSettings
 };
 
 /// A capsule with different top and bottom radii
-class TaperedCapsuleShape final : public ConvexShape
+class JPH_EXPORT TaperedCapsuleShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Collision/Shape/TriangleShape.h

@@ -9,10 +9,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Class that constructs a TriangleShape
-class TriangleShapeSettings final : public ConvexShapeSettings
+class JPH_EXPORT TriangleShapeSettings final : public ConvexShapeSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(TriangleShapeSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, TriangleShapeSettings)
 
 	/// Default constructor for deserialization
 							TriangleShapeSettings() = default;
@@ -31,7 +31,7 @@ public:
 };
 
 /// A single triangle, not the most efficient way of creating a world filled with triangles but can be used as a query shape for example.
-class TriangleShape final : public ConvexShape
+class JPH_EXPORT TriangleShape final : public ConvexShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Collision/TransformedShape.h

@@ -22,7 +22,7 @@ class RayCastResult;
 /// This structure can be obtained from a body (e.g. after a broad phase query) under lock protection.
 /// The lock can then be released and collision detection operations can be safely performed since
 /// the class takes a reference on the shape and does not use anything from the body anymore.
-class TransformedShape
+class JPH_EXPORT TransformedShape
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/ConeConstraint.h

@@ -11,10 +11,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Cone constraint settings, used to create a cone constraint
-class ConeConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT ConeConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(ConeConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ConeConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void				SaveBinaryState(StreamOut &inStream) const override;
@@ -66,7 +66,7 @@ protected:
 /// Where J is the Jacobian.
 ///
 /// Note that this is the exact same equation as used in AngleConstraintPart if we use t2 x t1 as the world space axis
-class ConeConstraint final : public TwoBodyConstraint
+class JPH_EXPORT ConeConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/Constraint.h

@@ -61,10 +61,10 @@ enum class EConstraintSpace
 };
 
 /// Class used to store the configuration of a constraint. Allows run-time creation of constraints.
-class ConstraintSettings : public SerializableObject, public RefTarget<ConstraintSettings>
+class JPH_EXPORT ConstraintSettings : public SerializableObject, public RefTarget<ConstraintSettings>
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(ConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, ConstraintSettings)
 
 	using ConstraintResult = Result<Ref<ConstraintSettings>>;
 
@@ -95,7 +95,7 @@ protected:
 };
 
 /// Base class for all physics constraints. A constraint removes one or more degrees of freedom for a rigid body.
-class Constraint : public RefTarget<Constraint>, public NonCopyable
+class JPH_EXPORT Constraint : public RefTarget<Constraint>, public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Constraints/ConstraintManager.h

@@ -20,7 +20,7 @@ class DebugRenderer;
 using Constraints = Array<Ref<Constraint>>;
 
 /// A constraint manager manages all constraints of the same type
-class ConstraintManager : public NonCopyable
+class JPH_EXPORT ConstraintManager : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 1 - 1
Jolt/Physics/Constraints/ContactConstraintManager.h

@@ -24,7 +24,7 @@ JPH_NAMESPACE_BEGIN
 struct PhysicsSettings;
 class PhysicsUpdateContext;
 
-class ContactConstraintManager : public NonCopyable
+class JPH_EXPORT ContactConstraintManager : public NonCopyable
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/DistanceConstraint.h

@@ -10,10 +10,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Distance constraint settings, used to create a distance constraint
-class DistanceConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT DistanceConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(DistanceConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, DistanceConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void				SaveBinaryState(StreamOut &inStream) const override;
@@ -49,7 +49,7 @@ protected:
 };
 
 /// This constraint is a stiff spring that holds 2 points at a fixed distance from each other
-class DistanceConstraint final : public TwoBodyConstraint
+class JPH_EXPORT DistanceConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/FixedConstraint.h

@@ -11,10 +11,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Fixed constraint settings, used to create a fixed constraint
-class FixedConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT FixedConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(FixedConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, FixedConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void				SaveBinaryState(StreamOut &inStream) const override;
@@ -45,7 +45,7 @@ protected:
 
 /// A fixed constraint welds two bodies together removing all degrees of freedom between them.
 /// This variant uses euler angles for the rotation constraint.
-class FixedConstraint final : public TwoBodyConstraint
+class JPH_EXPORT FixedConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/GearConstraint.h

@@ -10,10 +10,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Gear constraint settings
-class GearConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT GearConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(GearConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, GearConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void				SaveBinaryState(StreamOut &inStream) const override;
@@ -49,7 +49,7 @@ protected:
 
 /// A gear constraint constrains the rotation of body1 to the rotation of body 2 using a gear.
 /// Note that this constraint needs to be used in conjunction with a two hinge constraints.
-class GearConstraint final : public TwoBodyConstraint
+class JPH_EXPORT GearConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 3 - 3
Jolt/Physics/Constraints/HingeConstraint.h

@@ -13,10 +13,10 @@
 JPH_NAMESPACE_BEGIN
 
 /// Hinge constraint settings, used to create a hinge constraint
-class HingeConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT HingeConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(HingeConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, HingeConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void				SaveBinaryState(StreamOut &inStream) const override;
@@ -55,7 +55,7 @@ protected:
 };
 
 /// A hinge constraint constrains 2 bodies on a single point and allows only a single axis of rotation
-class HingeConstraint final : public TwoBodyConstraint
+class JPH_EXPORT HingeConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Physics/Constraints/MotorSettings.h

@@ -21,10 +21,10 @@ enum class EMotorState
 
 /// Class that contains the settings for a constraint motor.
 /// See the main page of the API documentation for more information on how to configure a motor.
-class MotorSettings
+class JPH_EXPORT MotorSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(MotorSettings)
+	JPH_DECLARE_SERIALIZABLE_NON_VIRTUAL(JPH_EXPORT, MotorSettings)
 
 	/// Constructor
 							MotorSettings() = default;

+ 3 - 3
Jolt/Physics/Constraints/PathConstraint.h

@@ -26,10 +26,10 @@ enum class EPathRotationConstraintType
 };
 
 /// Path constraint settings, used to constrain the degrees of freedom between two bodies to a path
-class PathConstraintSettings final : public TwoBodyConstraintSettings
+class JPH_EXPORT PathConstraintSettings final : public TwoBodyConstraintSettings
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_VIRTUAL(PathConstraintSettings)
+	JPH_DECLARE_SERIALIZABLE_VIRTUAL(JPH_EXPORT, PathConstraintSettings)
 
 	// See: ConstraintSettings::SaveBinaryState
 	virtual void					SaveBinaryState(StreamOut &inStream) const override;
@@ -64,7 +64,7 @@ protected:
 };
 
 /// Path constraint, used to constrain the degrees of freedom between two bodies to a path
-class PathConstraint final : public TwoBodyConstraint
+class JPH_EXPORT PathConstraint final : public TwoBodyConstraint
 {
 public:
 	JPH_OVERRIDE_NEW_DELETE

+ 2 - 2
Jolt/Physics/Constraints/PathConstraintPath.h

@@ -17,10 +17,10 @@ class DebugRenderer;
 #endif // JPH_DEBUG_RENDERER
 
 /// The path for a path constraint. It allows attaching two bodies to each other while giving the second body the freedom to move along a path relative to the first.
-class PathConstraintPath : public SerializableObject, public RefTarget<PathConstraintPath>
+class JPH_EXPORT PathConstraintPath : public SerializableObject, public RefTarget<PathConstraintPath>
 {
 public:
-	JPH_DECLARE_SERIALIZABLE_ABSTRACT(PathConstraintPath)
+	JPH_DECLARE_SERIALIZABLE_ABSTRACT(JPH_EXPORT, PathConstraintPath)
 
 	using PathResult = Result<Ref<PathConstraintPath>>;
 

この差分においてかなりの量のファイルが変更されているため、一部のファイルを表示していません