Przeglądaj źródła

Improved searching for the Asset folder (#1454)

This means that it is no longer needed to copy the Assets folder to the build folder
Jorrit Rouwe 6 miesięcy temu
rodzic
commit
53c5190a8b

+ 0 - 5
Build/CMakeLists.txt

@@ -426,9 +426,4 @@ if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
 			endif()
 		endif()
 	endif()
-
-	# Copy the assets folder
-	if (TARGET_PERFORMANCE_TEST OR TEST_FRAMEWORK_AVAILABLE)
-		add_custom_command(TARGET Jolt PRE_BUILD COMMAND ${CMAKE_COMMAND} -E copy_directory ${PHYSICS_REPO_ROOT}/Assets/ $<TARGET_FILE_DIR:Jolt>/Assets/)
-	endif()
 endif()

+ 1 - 1
PerformanceTest/ConvexVsMeshScene.h

@@ -25,7 +25,7 @@ public:
 		return "ConvexVsMesh";
 	}
 
-	virtual bool			Load() override
+	virtual bool			Load(const String &inAssetPath) override
 	{
 		const int n = 100;
 		const float cell_size = 3.0f;

+ 1 - 1
PerformanceTest/LargeMeshScene.h

@@ -25,7 +25,7 @@ public:
 		return "LargeMeshScene";
 	}
 
-	virtual bool			Load() override
+	virtual bool			Load(const String &inAssetPath) override
 	{
 		// Create mesh shape creation settings
 		mMeshCreationSettings.mMotionType = EMotionType::Static;

+ 31 - 1
PerformanceTest/PerformanceTest.cpp

@@ -30,6 +30,7 @@ JPH_SUPPRESS_WARNINGS_STD_BEGIN
 #include <chrono>
 #include <memory>
 #include <cstdarg>
+#include <filesystem>
 JPH_SUPPRESS_WARNINGS_STD_END
 
 using namespace JPH;
@@ -224,8 +225,37 @@ int main(int argc, char** argv)
 	// Output scene we're running
 	Trace("Running scene: %s", scene->GetName());
 
+	// Find the asset path
+	bool found = false;
+	filesystem::path asset_path(argv[0]);
+	filesystem::path root_path = asset_path.root_path();
+	while (asset_path != root_path)
+	{
+		asset_path = asset_path.parent_path();
+		if (filesystem::exists(asset_path / "Assets"))
+		{
+			found = true;
+			break;
+		}
+	}
+	if (!found) // Note that argv[0] can be a relative path like './PerformanceTest' so we also scan up using '..'
+		for (int i = 0; i < 5; ++i)
+		{
+			asset_path /= "..";
+			if (filesystem::exists(asset_path / "Assets"))
+			{
+				found = true;
+				break;
+			}
+		}
+	if (!found)
+		asset_path = "Assets";
+	else
+		asset_path /= "Assets";
+	asset_path /= "";
+
 	// Load the scene
-	if (!scene->Load())
+	if (!scene->Load(String(asset_path.string())))
 		return 1;
 
 	// Create mapping table from object layer to broadphase layer

+ 3 - 3
PerformanceTest/PerformanceTestScene.h

@@ -9,17 +9,17 @@ class PerformanceTestScene
 {
 public:
 	// Virtual destructor
-	virtual					~PerformanceTestScene()							{ }
+	virtual					~PerformanceTestScene()								{ }
 
 	// Get name of test for debug purposes
 	virtual const char *	GetName() const = 0;
 
 	// Load assets for the scene
-	virtual bool			Load()											{ return true; }
+	virtual bool			Load([[maybe_unused]] const String &inAssetPath)	{ return true; }
 
 	// Start a new test by adding objects to inPhysicsSystem
 	virtual void			StartTest(PhysicsSystem &inPhysicsSystem, EMotionQuality inMotionQuality) = 0;
 
 	// Stop a test and remove objects from inPhysicsSystem
-	virtual void			StopTest(PhysicsSystem &inPhysicsSystem)		{ }
+	virtual void			StopTest(PhysicsSystem &inPhysicsSystem)			{ }
 };

+ 4 - 4
PerformanceTest/RagdollScene.h

@@ -28,10 +28,10 @@ public:
 		return mNumPilesPerAxis == 1? "RagdollSinglePile" : "Ragdoll";
 	}
 
-	virtual bool			Load() override
+	virtual bool			Load(const String &inAssetPath) override
 	{
 		// Load ragdoll
-		if (!ObjectStreamIn::sReadObject("Assets/Human.tof", mRagdollSettings))
+		if (!ObjectStreamIn::sReadObject((inAssetPath + "Human.tof").c_str(), mRagdollSettings))
 		{
 			cerr << "Unable to load ragdoll" << endl;
 			return false;
@@ -46,7 +46,7 @@ public:
 		mRagdollSettings->CalculateConstraintIndexToBodyIdxPair();
 
 		// Load animation
-		if (!ObjectStreamIn::sReadObject("Assets/Human/dead_pose1.tof", mAnimation))
+		if (!ObjectStreamIn::sReadObject((inAssetPath + "Human/dead_pose1.tof").c_str(), mAnimation))
 		{
 			cerr << "Unable to load animation" << endl;
 			return false;
@@ -57,7 +57,7 @@ public:
 		mAnimation->Sample(0.0f, mPose);
 
 		// Read the background scene
-		if (!ObjectStreamIn::sReadObject("Assets/terrain2.bof", mBackground))
+		if (!ObjectStreamIn::sReadObject((inAssetPath + "terrain2.bof").c_str(), mBackground))
 		{
 			cerr << "Unable to load terrain" << endl;
 			return false;

+ 38 - 1
TestFramework/Utils/AssetStream.cpp

@@ -6,9 +6,46 @@
 #include <Utils/AssetStream.h>
 #include <Utils/Log.h>
 
+JPH_SUPPRESS_WARNINGS_STD_BEGIN
+#include <filesystem>
+#ifdef JPH_PLATFORM_LINUX
+#include <unistd.h>
+#endif
+JPH_SUPPRESS_WARNINGS_STD_END
+
 String AssetStream::sGetAssetsBasePath()
 {
-	return "Assets/";
+	static String result = []() {
+		// Start with the application path
+	#ifdef JPH_PLATFORM_WINDOWS
+		char application_path[MAX_PATH] = { 0 };
+		GetModuleFileName(nullptr, application_path, MAX_PATH);
+	#elif defined(JPH_PLATFORM_LINUX)
+		char application_path[PATH_MAX] = { 0 };
+		int count = readlink("/proc/self/exe", application_path, PATH_MAX);
+		if (count > 0)
+			application_path[count] = 0;
+	#else
+		#error Unsupported platform
+	#endif
+
+		// Find the asset path
+		filesystem::path asset_path(application_path);
+		while (!asset_path.empty())
+		{
+			filesystem::path parent_path = asset_path.parent_path();
+			if (parent_path == asset_path)
+				break;
+			asset_path = parent_path;
+			if (filesystem::exists(asset_path / "Assets"))
+				break;
+		}
+		asset_path /= "Assets";
+		asset_path /= "";
+		return String(asset_path.string());
+	}();
+
+	return result;
 }
 
 AssetStream::AssetStream(const char *inFileName, std::ios_base::openmode inOpenMode) :