From 6ae68bc6cc92f7f5ccbe84c7288af42a1eb027b3 Mon Sep 17 00:00:00 2001 From: Wojtek Figat Date: Fri, 13 Mar 2026 17:49:11 +0100 Subject: [PATCH] Add PhysX and NvCloth to Web --- Source/Engine/Physics/Physics.Build.cs | 8 +- .../NvCloth/compiler/cmake/web/CMakeLists.txt | 39 ++++++ .../NvCloth/compiler/cmake/web/NvCloth.cmake | 68 ++++++++++ .../include/NvCloth/ps/web/PsWebIntrinsics.h | 111 ++++++++++++++++ .../include/foundation/web/PxWebIntrinsics.h | 125 ++++++++++++++++++ .../Web/Binaries/ThirdParty/x86/libNvCloth.a | 3 + .../Web/Binaries/ThirdParty/x86/libPhysX.a | 3 + .../x86/libPhysXCharacterKinematic.a | 3 + .../Binaries/ThirdParty/x86/libPhysXCommon.a | 3 + .../Binaries/ThirdParty/x86/libPhysXCooking.a | 3 + .../ThirdParty/x86/libPhysXExtensions.a | 3 + .../ThirdParty/x86/libPhysXFoundation.a | 3 + .../Binaries/ThirdParty/x86/libPhysXPvdSDK.a | 3 + .../Binaries/ThirdParty/x86/libPhysXVehicle.a | 3 + .../ThirdParty/x86/libPhysXVehicle2.a | 3 + Source/ThirdParty/PhysX/PhysX.Build.cs | 20 +-- Source/ThirdParty/PhysX/foundation/PxHash.h | 2 +- Source/ThirdParty/PhysX/foundation/PxMath.h | 2 +- .../Flax.Build/Deps/Dependencies/NvCloth.cs | 19 ++- .../Flax.Build/Deps/Dependencies/PhysX.cs | 18 ++- Source/Tools/Flax.Build/Deps/Dependency.cs | 4 +- .../Flax.Build/Platforms/Web/EmscriptenSdk.cs | 6 + 22 files changed, 430 insertions(+), 22 deletions(-) create mode 100644 Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/CMakeLists.txt create mode 100644 Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/NvCloth.cmake create mode 100644 Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/include/NvCloth/ps/web/PsWebIntrinsics.h create mode 100644 Source/Platforms/Web/Binaries/Data/NvCloth/PxShared/include/foundation/web/PxWebIntrinsics.h create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libNvCloth.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysX.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCharacterKinematic.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCommon.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCooking.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXExtensions.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXFoundation.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXPvdSDK.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle.a create mode 100644 Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle2.a diff --git a/Source/Engine/Physics/Physics.Build.cs b/Source/Engine/Physics/Physics.Build.cs index f31afcffa..a16798349 100644 --- a/Source/Engine/Physics/Physics.Build.cs +++ b/Source/Engine/Physics/Physics.Build.cs @@ -39,12 +39,6 @@ public class Physics : EngineModule { base.Setup(options); - if (options.Platform.Target == TargetPlatform.Web) // TODO: build PhysX for Web - { - options.PrivateDefinitions.Add("COMPILE_WITH_EMPTY_PHYSICS"); - return; - } - SetupPhysicsBackend(this, options); if (WithCooking) @@ -58,7 +52,7 @@ public class Physics : EngineModule if (WithPhysX) { options.PrivateDependencies.Add("PhysX"); - if (WithCloth && options.Platform.Target != TargetPlatform.PS4) // TODO: build nvcloth for ps4 with vs2017 + if (WithCloth) options.PrivateDependencies.Add("NvCloth"); } else diff --git a/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/CMakeLists.txt b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/CMakeLists.txt new file mode 100644 index 000000000..c4ef01d85 --- /dev/null +++ b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/CMakeLists.txt @@ -0,0 +1,39 @@ +cmake_minimum_required(VERSION 3.3) +MESSAGE("[NvCloth]cmake/web/CMakeList.txt") +include(../common/CMakeLists.txt) + +IF(NOT DEFINED TARGET_BUILD_PLATFORM) # Not defined, default to web + SET(TARGET_BUILD_PLATFORM "web") +ENDIF() + +SET(PLATFORM_LIST web) + +IF(NOT ${TARGET_BUILD_PLATFORM} IN_LIST PLATFORM_LIST) + MESSAGE(FATAL_ERROR "Invalid platform:" ${TARGET_BUILD_PLATFORM}) +ENDIF() + +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions -ffunction-sections -fdata-sections -fstrict-aliasing -Wstrict-aliasing=2") + +# Enable SIMD +SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -msimd128 -msse4.2 -mno-nontrapping-fptoint") + +SET(CMAKE_SHARED_LINKER_FLAGS "") + +# Build debug info for all configurations +SET(CMAKE_CXX_FLAGS_DEBUG "-O0 -g2") +SET(CMAKE_CXX_FLAGS_CHECKED "-g2 -O2") +SET(CMAKE_CXX_FLAGS_PROFILE "-O3 -g") +SET(CMAKE_CXX_FLAGS_RELEASE "-O3") + +# Disable cuda and dx for all projects on web +SET(PHYSX_WEB_COMPILE_DEFS DISABLE_COMPUTE_PHYSX) +SET(PHYSX_WEB_DEBUG_COMPILE_DEFS _DEBUG;PX_DEBUG=1;PX_CHECKED=1;PX_NVTX=0;PX_SUPPORT_PVD=0) +SET(PHYSX_SWWEB_CHECKED_COMPILE_DEFS NDEBUG;PX_CHECKED=1;PX_NVTX=0;PX_SUPPORT_PVD=0) +SET(PHYSX_WEB_PROFILE_COMPILE_DEFS NDEBUG;PX_PROFILE=1;PX_NVTX=0;PX_SUPPORT_PVD=0) +SET(PHYSX_WEB_RELEASE_COMPILE_DEFS NDEBUG;PX_SUPPORT_PVD=0) + +SET(PX_SELECT_COMPONENTS PxFoundation) +FIND_PACKAGE(PxShared REQUIRED) + +# Include all of the projects +INCLUDE(NvCloth.cmake) diff --git a/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/NvCloth.cmake b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/NvCloth.cmake new file mode 100644 index 000000000..021886234 --- /dev/null +++ b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/compiler/cmake/web/NvCloth.cmake @@ -0,0 +1,68 @@ +# +# Build NvCloth (PROJECT not SOLUTION) +# + +MESSAGE("[NvCloth]cmake/web/NvCloth.cmake") + +SET(GW_DEPS_ROOT $ENV{GW_DEPS_ROOT}) +FIND_PACKAGE(PxShared REQUIRED) + +# No Cuda nor DX11 +SET(NV_CLOTH_ENABLE_CUDA 0) +SET(NV_CLOTH_ENABLE_DX11 0) + +#FIND_PACKAGE(nvToolsExt REQUIRED) + +SET(NVCLOTH_PLATFORM_INCLUDES + ${NVTOOLSEXT_INCLUDE_DIRS} + PRIVATE ${CUDA_INCLUDE_DIRS} +) + +SET(NVCLOTH_PLATFORM_SOURCE_FILES + ${PROJECT_ROOT_DIR}/src/ps/unix/PsUnixAtomic.cpp + ${PROJECT_ROOT_DIR}/src/ps/unix/PsUnixFPU.h +) + +IF(PX_STATIC_LIBRARIES) + SET(NVCLOTH_API_COMPILE_DEFS NV_CLOTH_IMPORT=;PX_CALL_CONV=;) +ELSE() + SET(NVCLOTH_API_COMPILE_DEFS NV_CLOTH_IMPORT=PX_DLL_EXPORT;) +ENDIF() + +# Use generator expressions to set config specific preprocessor definitions +SET(NVCLOTH_COMPILE_DEFS + ${NVCLOTH_API_COMPILE_DEFS} + NV_CLOTH_ENABLE_DX11=0 + + # Common to all configurations + ${PHYSX_WEB_COMPILE_DEFS};PX_PHYSX_CORE_EXPORTS + + $<$:${PHYSX_WEB_DEBUG_COMPILE_DEFS};PX_PHYSX_DLL_NAME_POSTFIX=DEBUG;> + $<$:${PHYSX_WEB_CHECKED_COMPILE_DEFS};PX_PHYSX_DLL_NAME_POSTFIX=CHECKED;> + $<$:${PHYSX_WEB_PROFILE_COMPILE_DEFS};PX_PHYSX_DLL_NAME_POSTFIX=PROFILE;> + $<$:${PHYSX_WEB_RELEASE_COMPILE_DEFS};> +) +LIST(APPEND NVCLOTH_COMPILE_DEFS + NV_CLOTH_ENABLE_CUDA=0 +) + +IF(PX_STATIC_LIBRARIES) + SET(NVCLOTH_LIBTYPE STATIC) +ELSE() + SET(NVCLOTH_LIBTYPE SHARED) +ENDIF() + +# include common NvCloth settings +INCLUDE(../common/NvCloth.cmake) + +TARGET_LINK_LIBRARIES(NvCloth PUBLIC ${CUDA_CUDA_LIBRARY}) + +SET_TARGET_PROPERTIES(NvCloth PROPERTIES + LINK_FLAGS_DEBUG "" + LINK_FLAGS_CHECKED "" + LINK_FLAGS_PROFILE "" + LINK_FLAGS_RELEASE "" +) + +SET_TARGET_PROPERTIES(NvCloth PROPERTIES POSITION_INDEPENDENT_CODE TRUE) +MESSAGE("[NvCloth]cmake/web/NvCloth.cmake END") diff --git a/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/include/NvCloth/ps/web/PsWebIntrinsics.h b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/include/NvCloth/ps/web/PsWebIntrinsics.h new file mode 100644 index 000000000..e9ceb7ef9 --- /dev/null +++ b/Source/Platforms/Web/Binaries/Data/NvCloth/NvCloth/include/NvCloth/ps/web/PsWebIntrinsics.h @@ -0,0 +1,111 @@ +#ifndef PX_FOUNDATION_PS_WEB_INTRINSICS_H +#define PX_FOUNDATION_PS_WEB_INTRINSICS_H + +#include "NvCloth/ps/Ps.h" + +// this file is for internal intrinsics - that is, intrinsics that are used in +// cross platform code but do not appear in the API + +#if !PX_WEB + #error "This file should only be included by Web builds!!" +#endif + +#include + +/** \brief NVidia namespace */ +namespace nv +{ +/** \brief nvcloth namespace */ +namespace cloth +{ +namespace ps +{ + +/* + * Implements a memory barrier + */ +PX_FORCE_INLINE void PxMemoryBarrier() +{ + __sync_synchronize(); +} + +/*! +Returns the index of the highest set bit. Not valid for zero arg. +*/ +PX_FORCE_INLINE uint32_t PxHighestSetBitUnsafe(uint32_t v) +{ + // http://graphics.stanford.edu/~seander/bithacks.html + static const uint32_t MultiplyDeBruijnBitPosition[32] = + { + 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30, + 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31 + }; + + v |= v >> 1; // first round up to one less than a power of 2 + v |= v >> 2; + v |= v >> 4; + v |= v >> 8; + v |= v >> 16; + + return MultiplyDeBruijnBitPosition[(uint32_t)(v * 0x07C4ACDDU) >> 27]; +} + +/*! +Returns the index of the highest set bit. Undefined for zero arg. +*/ +PX_FORCE_INLINE uint32_t PxLowestSetBitUnsafe(uint32_t v) +{ + // http://graphics.stanford.edu/~seander/bithacks.html + static const uint32_t MultiplyDeBruijnBitPosition[32] = + { + 0, 1, 28, 2, 29, 14, 24, 3, 30, 22, 20, 15, 25, 17, 4, 8, + 31, 27, 13, 23, 21, 19, 16, 7, 26, 12, 18, 6, 11, 5, 10, 9 + }; + int32_t w = v; + return MultiplyDeBruijnBitPosition[(uint32_t)((w & -w) * 0x077CB531U) >> 27]; +} + +/*! +Returns the number of leading zeros in v. Returns 32 for v=0. +*/ +PX_FORCE_INLINE uint32_t PxCountLeadingZeros(uint32_t v) +{ + int32_t result = 0; + uint32_t testBit = (1<<31); + while ((v & testBit) == 0 && testBit != 0) + { + result++; + testBit >>= 1; + } + return result; +} + +/*! +Prefetch aligned cache size around \c ptr+offset. +*/ +PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0) +{ + __builtin_prefetch((char* PX_RESTRICT)(const_cast(ptr)) + offset, 0, 3); +} + +/*! +Prefetch \c count bytes starting at \c ptr. +*/ +PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1) +{ + const char* cp = (char*)const_cast(ptr); + uint64_t p = size_t(ptr); + uint64_t startLine = p >> 6, endLine = (p + count - 1) >> 6; + uint64_t lines = endLine - startLine + 1; + do + { + PxPrefetchLine(cp); + cp += 64; + } while(--lines); +} + +} // namespace ps +} // namespace cloth +} // namespace nv + +#endif diff --git a/Source/Platforms/Web/Binaries/Data/NvCloth/PxShared/include/foundation/web/PxWebIntrinsics.h b/Source/Platforms/Web/Binaries/Data/NvCloth/PxShared/include/foundation/web/PxWebIntrinsics.h new file mode 100644 index 000000000..dd67d0baa --- /dev/null +++ b/Source/Platforms/Web/Binaries/Data/NvCloth/PxShared/include/foundation/web/PxWebIntrinsics.h @@ -0,0 +1,125 @@ +#ifndef PX_FOUNDATION_PX_WEB_INTRINSICS_H +#define PX_FOUNDATION_PX_WEB_INTRINSICS_H + +#include "foundation/Px.h" +#include "foundation/PxSharedAssert.h" + +#if !PX_WEB + #error "This file should only be included by Web builds!!" +#endif + +#include +#include + +#include "nn/cstd/cstd_CMath.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +namespace intrinsics +{ + //! \brief platform-specific absolute value + PX_CUDA_CALLABLE PX_FORCE_INLINE float abs(float a) { return ::fabsf(a); } + + //! \brief platform-specific select float + PX_CUDA_CALLABLE PX_FORCE_INLINE float fsel(float a, float b, float c) { return (a >= 0.0f) ? b : c; } + + //! \brief platform-specific sign + PX_CUDA_CALLABLE PX_FORCE_INLINE float sign(float a) { return (a >= 0.0f) ? 1.0f : -1.0f; } + + //! \brief platform-specific reciprocal + PX_CUDA_CALLABLE PX_FORCE_INLINE float recip(float a) { return 1.0f/a; } + + //! \brief platform-specific reciprocal estimate + PX_CUDA_CALLABLE PX_FORCE_INLINE float recipFast(float a) { return 1.0f/a; } + + //! \brief platform-specific square root + PX_CUDA_CALLABLE PX_FORCE_INLINE float sqrt(float a) { return ::sqrtf(a); } + + //! \brief platform-specific reciprocal square root + PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrt(float a) { return 1.0f/::sqrtf(a); } + + //! \brief platform-specific reciprocal square root estimate + PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrtFast(float a) { return 1.0f/::sqrtf(a); } + + //! \brief platform-specific sine + PX_CUDA_CALLABLE PX_FORCE_INLINE float sin(float a) { return ::sinf(a); } + + //! \brief platform-specific cosine + PX_CUDA_CALLABLE PX_FORCE_INLINE float cos(float a) { return ::cosf(a); } + + //! \brief platform-specific minimum + PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMin(float a, float b) { return ab ? a : b; } + + //! \brief platform-specific finiteness check + PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(float a) + { +#ifdef __CUDACC__ + return isfinite(a) ? true : false; +#else + return !nn::cstd::IsNan(a) && !nn::cstd::IsInf(a); +#endif + } + + //! \brief platform-specific finiteness check + PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(double a) + { +#ifdef __CUDACC__ + return isfinite(a) ? true : false; +#else + return !nn::cstd::IsNan(a) && !nn::cstd::IsInf(a); +#endif + } + + /*! + Sets \c count bytes starting at \c dst to zero. + */ + PX_FORCE_INLINE void* memZero(void* PX_RESTRICT dest, uint32_t count) + { + return memset(dest, 0, count); + } + + /*! + Sets \c count bytes starting at \c dst to \c c. + */ + PX_FORCE_INLINE void* memSet(void* PX_RESTRICT dest, int32_t c, uint32_t count) + { + return memset(dest, c, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. + */ + PX_FORCE_INLINE void* memCopy(void* PX_RESTRICT dest, const void* PX_RESTRICT src, uint32_t count) + { + return memcpy(dest, src, count); + } + + /*! + Copies \c count bytes from \c src to \c dst. Supports overlapping regions. + */ + PX_FORCE_INLINE void* memMove(void* PX_RESTRICT dest, const void* PX_RESTRICT src, uint32_t count) + { + return memmove(dest, src, count); + } + + /*! + Set 128B to zero starting at \c dst+offset. Must be aligned. + */ + PX_FORCE_INLINE void memZero128(void* PX_RESTRICT dest, uint32_t offset = 0) + { + PX_SHARED_ASSERT(((size_t(dest)+offset) & 0x7f) == 0); + memSet((char* PX_RESTRICT)dest+offset, 0, 128); + } + +} // namespace intrinsics +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libNvCloth.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libNvCloth.a new file mode 100644 index 000000000..5b6dd6a57 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libNvCloth.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e784a3e56413727920e5348a3584b12a17fbfa3c129c8b5bcb41bcb2ee05653d +size 345152 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysX.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysX.a new file mode 100644 index 000000000..4b5fd1854 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysX.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:55e3fcddd4e2e58a96c9601a15efe40ed9ac3e8cac1132dfefef9435ccfd528b +size 10611180 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCharacterKinematic.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCharacterKinematic.a new file mode 100644 index 000000000..61a4f5c55 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCharacterKinematic.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f436871c4a434d52a2301171ac6d44e5c0b42768e455fa5b9b13b0b70fdbf497 +size 514156 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCommon.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCommon.a new file mode 100644 index 000000000..ab844f3e8 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCommon.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ba42cac0b02c91577361dd3169f7c882bb42a381f83d050d7e82d261202b4824 +size 8588392 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCooking.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCooking.a new file mode 100644 index 000000000..962499b14 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXCooking.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3a817e06c4d6a3425287a128b72a004e1c43eef02971f6f2a8fe4af438dddf21 +size 23636 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXExtensions.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXExtensions.a new file mode 100644 index 000000000..3e95f59be --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXExtensions.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7859dedaa52badbfa6306f3d1d0fcc32692d21c8aa41efe91ed14da66ccc46be +size 10378010 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXFoundation.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXFoundation.a new file mode 100644 index 000000000..b6bff55ff --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXFoundation.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6f7f94aa6e98e98a6aced80c8517cda41c2aafdf0e0a8bba6d3df4953ab46c5c +size 124626 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXPvdSDK.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXPvdSDK.a new file mode 100644 index 000000000..1051c8cec --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXPvdSDK.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:3ab61d6b8b3abc22f22e2ef89cb44c71da5ca95bfc8de5f2e3f8ce16171f4628 +size 1069702 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle.a new file mode 100644 index 000000000..000ea0d8e --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fdf01ff4335efbd41f25f1df440c829cb4497a6f787cf8627b59fae12728f2e4 +size 2861234 diff --git a/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle2.a b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle2.a new file mode 100644 index 000000000..f1a02ddb0 --- /dev/null +++ b/Source/Platforms/Web/Binaries/ThirdParty/x86/libPhysXVehicle2.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ef152376ba924e2a30f4cc4c24e8d5be0fb7cdac030e2625378b50bc25b0b78 +size 306594 diff --git a/Source/ThirdParty/PhysX/PhysX.Build.cs b/Source/ThirdParty/PhysX/PhysX.Build.cs index 3aa705b4b..924254cd3 100644 --- a/Source/ThirdParty/PhysX/PhysX.Build.cs +++ b/Source/ThirdParty/PhysX/PhysX.Build.cs @@ -89,27 +89,29 @@ public class PhysX : EngineDepsModule else { options.PublicDefinitions.Add("PX_PHYSX_STATIC_LIB"); + if (options.Platform.Target != TargetPlatform.Web) + archPostFix = "_static" + archPostFix; - AddLib(options, depsRoot, string.Format("PhysX_static{0}", archPostFix)); - AddLib(options, depsRoot, string.Format("PhysXCharacterKinematic_static{0}", archPostFix)); - AddLib(options, depsRoot, string.Format("PhysXCommon_static{0}", archPostFix)); - AddLib(options, depsRoot, string.Format("PhysXExtensions_static{0}", archPostFix)); - AddLib(options, depsRoot, string.Format("PhysXFoundation_static{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysX{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXCharacterKinematic{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXCommon{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXExtensions{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXFoundation{0}", archPostFix)); if (usePhysicsCooking) { - AddLib(options, depsRoot, string.Format("PhysXCooking_static{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXCooking{0}", archPostFix)); } if (usePVD) { - AddLib(options, depsRoot, string.Format("PhysXPvdSDK_static{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXPvdSDK{0}", archPostFix)); } if (useVehicle) { - AddLib(options, depsRoot, string.Format("PhysXVehicle_static{0}", archPostFix)); - //AddLib(options, depsRoot, string.Format("PhysXVehicle2_static{0}", archPostFix)); + AddLib(options, depsRoot, string.Format("PhysXVehicle{0}", archPostFix)); + //AddLib(options, depsRoot, string.Format("PhysXVehicle2{0}", archPostFix)); } } } diff --git a/Source/ThirdParty/PhysX/foundation/PxHash.h b/Source/ThirdParty/PhysX/foundation/PxHash.h index 43ea55215..c85756b0a 100644 --- a/Source/ThirdParty/PhysX/foundation/PxHash.h +++ b/Source/ThirdParty/PhysX/foundation/PxHash.h @@ -86,7 +86,7 @@ PX_FORCE_INLINE uint32_t PxComputeHash(const uint64_t key) return uint32_t(UINT32_MAX & k); } -#if PX_APPLE_FAMILY +#if PX_APPLE_FAMILY || PX_EMSCRIPTEN // hash for size_t, to make gcc happy PX_INLINE uint32_t PxComputeHash(const size_t key) { diff --git a/Source/ThirdParty/PhysX/foundation/PxMath.h b/Source/ThirdParty/PhysX/foundation/PxMath.h index cff5b1795..8b071fa32 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMath.h +++ b/Source/ThirdParty/PhysX/foundation/PxMath.h @@ -45,7 +45,7 @@ #pragma warning(pop) #endif -#if (PX_LINUX_FAMILY && !PX_ARM_FAMILY) +#if (PX_LINUX_FAMILY && !PX_ARM_FAMILY && !PX_EMSCRIPTEN) // Force linking against nothing newer than glibc v2.17 to remain compatible with platforms with older glibc versions __asm__(".symver expf,expf@GLIBC_2.2.5"); __asm__(".symver powf,powf@GLIBC_2.2.5"); diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/NvCloth.cs b/Source/Tools/Flax.Build/Deps/Dependencies/NvCloth.cs index f3c3ff210..3b4e0163f 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/NvCloth.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/NvCloth.cs @@ -70,6 +70,10 @@ namespace Flax.Deps.Dependencies case TargetPlatform.Linux: Build(options, platform, architecture); break; + case TargetPlatform.Web: + Utilities.DirectoryCopy(Path.Combine(GetBinariesFolder(options, platform), "Data", "NvCloth"), root, true, true); + Build(options, platform, TargetArchitecture.x86); + break; } } } @@ -147,6 +151,15 @@ namespace Flax.Deps.Dependencies envVars.Add("CC", "clang-" + Configuration.LinuxClangMinVer); envVars.Add("CXX", "clang++-" + Configuration.LinuxClangMinVer); break; + case TargetPlatform.Web: + cmakeArgs += " -DTARGET_BUILD_PLATFORM=web"; + cmakeArgs += $" -DCMAKE_TOOLCHAIN_FILE=\"{EmscriptenSdk.Instance.CMakeToolchainPath}\""; + cmakeName = "web"; + binariesPrefix = "lib"; + + // Disable SIMD and fix missing symbols during linking + Utilities.ReplaceInFile(Path.Combine(nvCloth, "src/NvSimd/NvSimdTypes.h"), "(__x86_64__) || PX_EMSCRIPTEN", "(__x86_64__) // || PX_EMSCRIPTEN"); + break; default: throw new InvalidPlatformException(platform); } var cmakeFolder = Path.Combine(nvCloth, "compiler", "cmake", cmakeName); @@ -169,13 +182,15 @@ namespace Flax.Deps.Dependencies Log.Info($"Building {File.ReadAllLines(Path.Combine(root, "README.md"))[0].Trim()} to {platform} {architecture}"); // Generate project files + var config = "Release"; SetupDirectory(buildFolder, false); + SetupDirectory(Path.Combine(root, "PxShared/src/foundation/include"), false); Utilities.FileDelete(Path.Combine(cmakeFolder, "CMakeCache.txt")); cmakeArgs += $" -DPX_STATIC_LIBRARIES=1 -DPX_OUTPUT_DLL_DIR=\"{Path.Combine(buildFolder, "bin")}\" -DPX_OUTPUT_LIB_DIR=\"{Path.Combine(buildFolder, "lib")}\" -DPX_OUTPUT_EXE_DIR=\"{Path.Combine(buildFolder, "bin")}\""; - RunCmake(cmakeFolder, platform, architecture, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + cmakeArgs, envVars); + RunCmake(cmakeFolder, platform, architecture, $" -DCMAKE_BUILD_TYPE={config} -DBUILD_SHARED_LIBS=OFF " + cmakeArgs, envVars); // Run build - BuildCmake(cmakeFolder, envVars); + BuildCmake(cmakeFolder, config, envVars); // Deploy binaries var libs = new[] diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs b/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs index 18bb4e69f..b06862ffa 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs @@ -185,6 +185,11 @@ namespace Flax.Deps.Dependencies binariesPrefix = "lib"; envVars.Add("IPHONEOS_DEPLOYMENT_TARGET", Configuration.iOSMinVer); break; + case TargetPlatform.Web: + binariesSubDir = "web32"; + binariesPrefix = "lib"; + envVars.Add("CMAKE_TOOLCHAIN_FILE", EmscriptenSdk.Instance.CMakeToolchainPath); + break; default: throw new InvalidPlatformException(targetPlatform); } @@ -206,7 +211,6 @@ namespace Flax.Deps.Dependencies envVars.Add("CC", "clang-" + Configuration.LinuxClangMinVer); envVars.Add("CC_FOR_BUILD", "clang-" + Configuration.LinuxClangMinVer); envVars.Add("CXX", "clang++-" + Configuration.LinuxClangMinVer); - envVars.Add("CMAKE_BUILD_PARALLEL_LEVEL", CmakeBuildParallel); break; case TargetPlatform.Mac: break; default: throw new InvalidPlatformException(BuildPlatform); @@ -259,6 +263,8 @@ namespace Flax.Deps.Dependencies }; var dstBinaries = GetThirdPartyFolder(options, targetPlatform, architecture); var srcBinaries = Path.Combine(root, "physx", "bin", binariesSubDir, configuration); + if (targetPlatform == TargetPlatform.Web) + srcBinaries = Path.Combine(root, "physx", "compiler", binariesSubDir, "sdk_source_bin"); switch (BuildPlatform) { case TargetPlatform.Windows: @@ -267,6 +273,9 @@ namespace Flax.Deps.Dependencies case TargetPlatform.Android: Utilities.Run("cmake", "--build .", null, Path.Combine(root, "physx\\compiler\\android-" + configuration), Utilities.RunOptions.ConsoleLogOutput, envVars); break; + case TargetPlatform.Web: + Utilities.Run("cmake", "--build .", null, Path.Combine(root, "physx\\compiler\\" + preset), Utilities.RunOptions.DefaultTool, envVars); + break; default: VCEnvironment.BuildSolution(Path.Combine(solutionFilesRoot, preset, "PhysXSDK.sln"), configuration, buildPlatform, msBuildProps, msBuild); break; @@ -287,6 +296,8 @@ namespace Flax.Deps.Dependencies foreach (var physXLib in defaultPhysXLibs) { var filename = suppressBitsPostfix ? string.Format("{0}{1}_static", binariesPrefix, physXLib) : string.Format("{0}{1}_static_{2}", binariesPrefix, physXLib, bits); + if (targetPlatform == TargetPlatform.Web) + filename = binariesPrefix + physXLib; filename += binariesExtension; Utilities.FileCopy(Path.Combine(srcBinaries, filename), Path.Combine(dstBinaries, filename)); @@ -429,6 +440,11 @@ namespace Flax.Deps.Dependencies Build(options, "ios64", platform, TargetArchitecture.ARM64); break; } + case TargetPlatform.Web: + { + Build(options, "web32", platform, TargetArchitecture.x86); + break; + } } } } diff --git a/Source/Tools/Flax.Build/Deps/Dependency.cs b/Source/Tools/Flax.Build/Deps/Dependency.cs index 11e719ea1..de78ff7ce 100644 --- a/Source/Tools/Flax.Build/Deps/Dependency.cs +++ b/Source/Tools/Flax.Build/Deps/Dependency.cs @@ -97,6 +97,7 @@ namespace Flax.Deps TargetPlatform.PS5, TargetPlatform.Android, TargetPlatform.Switch, + TargetPlatform.Web, }; case TargetPlatform.Linux: return new[] @@ -127,6 +128,7 @@ namespace Flax.Deps case TargetPlatform.Windows: return new[] { + TargetArchitecture.x86, TargetArchitecture.x64, TargetArchitecture.ARM64, }; @@ -562,7 +564,7 @@ namespace Flax.Deps } case TargetPlatform.Web: { - cmdLine = string.Format("CMakeLists.txt -DCMAKE_TOOLCHAIN_FILE=\"{0}/emscripten/cmake/Modules/Platform/Emscripten.cmake\"", EmscriptenSdk.Instance.EmscriptenPath); + cmdLine = $"CMakeLists.txt -DCMAKE_TOOLCHAIN_FILE=\"{EmscriptenSdk.Instance.CMakeToolchainPath}\""; if (BuildPlatform == TargetPlatform.Windows) cmdLine += " -G \"Ninja\""; break; diff --git a/Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs b/Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs index 946fc0c87..0a632c333 100644 --- a/Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs +++ b/Source/Tools/Flax.Build/Platforms/Web/EmscriptenSdk.cs @@ -30,6 +30,11 @@ namespace Flax.Build.Platforms /// public string EmscriptenPath; + /// + /// Full path to the CMake toolchain file (eg. '%EMSDK%\upstream\emscripten\cmake\Modules\Platform\Emscripten.cmake'). + /// + public string CMakeToolchainPath; + /// /// Initializes a new instance of the class. /// @@ -52,6 +57,7 @@ namespace Flax.Build.Platforms { RootPath = sdkPath; EmscriptenPath = Path.Combine(sdkPath, "upstream"); + CMakeToolchainPath = Path.Combine(EmscriptenPath, "emscripten/cmake/Modules/Platform/Emscripten.cmake"); var versionPath = Path.Combine(EmscriptenPath, "emscripten", "emscripten-version.txt"); if (File.Exists(versionPath)) {