mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2026-06-27 03:18:17 +00:00
feat: xmodel preview in ModMan (#835)
* chore: upgrade webwindowed for dynamic assets * chore: make enums in ModMan lowercase * chore: add missing platform wiiu in ModMan * fix: register asset handler on all windows * chore: properly localize game and platform * chore: render example cube as xmodel preview * chore: allow origin * in debug * feat: show preview of xmodels with ModMan * feat: show images in xmodel preview * feat: auto load search paths in ModMan * chore: load objcontainer of loaded zones in ModMan * chore: add iw4x specific recognized zone dirs * chore: show when models are loading * fix: make sure webwindowed handles window and app destruction in correct order * chore: track and properly free threejs resources * chore: add skybox for 3d preview * chore: add small border radius to preview * fix: linting * fix: linux compilation * chore: update package lock
This commit is contained in:
@@ -0,0 +1,84 @@
|
||||
#include "AutoSearchPaths.h"
|
||||
|
||||
#include "IW3/AutoSearchPathsIW3.h"
|
||||
#include "IW4/AutoSearchPathsIW4.h"
|
||||
#include "IW5/AutoSearchPathsIW5.h"
|
||||
#include "T4/AutoSearchPathsT4.h"
|
||||
#include "T5/AutoSearchPathsT5.h"
|
||||
#include "T6/AutoSearchPathsT6.h"
|
||||
#include "Utils/StringUtils.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <filesystem>
|
||||
#include <optional>
|
||||
#include <utility>
|
||||
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
namespace
|
||||
{
|
||||
std::optional<std::string> FindGameRootFolder(const std::string& zoneParentPath, const std::vector<std::string>& zoneDirs)
|
||||
{
|
||||
std::string lowerZoneParentPath(zoneParentPath);
|
||||
utils::MakeStringLowerCase(lowerZoneParentPath);
|
||||
|
||||
for (const auto& dir : zoneDirs)
|
||||
{
|
||||
std::string normalizedDir(dir);
|
||||
utils::MakeStringLowerCase(normalizedDir);
|
||||
|
||||
if (lowerZoneParentPath.ends_with(normalizedDir) && lowerZoneParentPath[lowerZoneParentPath.size() - dir.size() - 1] == '/')
|
||||
return zoneParentPath.substr(0, zoneParentPath.size() - dir.size() - 1);
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::vector<std::string> AutoSearchPaths::GetSearchPathsForZonePath(const std::string& zonePath) const
|
||||
{
|
||||
auto folderName = fs::absolute(fs::path(zonePath)).parent_path().string();
|
||||
std::ranges::replace(folderName, '\\', '/');
|
||||
|
||||
const auto maybeGameRootFolder = FindGameRootFolder(folderName, RecognizedZoneDirs());
|
||||
if (!maybeGameRootFolder)
|
||||
return {folderName};
|
||||
|
||||
std::vector<std::string> result;
|
||||
const fs::path gameRootFolderPath(*maybeGameRootFolder);
|
||||
|
||||
for (const auto& dir : RecognizedZoneDirs())
|
||||
{
|
||||
auto dirPath = fs::weakly_canonical(gameRootFolderPath / dir);
|
||||
|
||||
if (fs::is_directory(dirPath))
|
||||
result.emplace_back(dirPath.string());
|
||||
}
|
||||
|
||||
for (const auto& dir : AdditionalSearchPaths())
|
||||
{
|
||||
auto dirPath = fs::weakly_canonical(gameRootFolderPath / dir);
|
||||
|
||||
if (fs::is_directory(dirPath))
|
||||
result.emplace_back(dirPath.string());
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
AutoSearchPaths* AutoSearchPaths::GetForGame(GameId gameId)
|
||||
{
|
||||
static AutoSearchPaths* autoSearchPaths[]{
|
||||
new AutoSearchPathsIW3(),
|
||||
new AutoSearchPathsIW4(),
|
||||
new AutoSearchPathsIW5(),
|
||||
new AutoSearchPathsT4(),
|
||||
new AutoSearchPathsT5(),
|
||||
new AutoSearchPathsT6(),
|
||||
};
|
||||
static_assert(std::extent_v<decltype(autoSearchPaths)> == static_cast<unsigned>(GameId::COUNT));
|
||||
assert(static_cast<unsigned>(gameId) < static_cast<unsigned>(GameId::COUNT));
|
||||
|
||||
return autoSearchPaths[std::to_underlying(gameId)];
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/IGame.h"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
class AutoSearchPaths
|
||||
{
|
||||
public:
|
||||
AutoSearchPaths() = default;
|
||||
virtual ~AutoSearchPaths() = default;
|
||||
AutoSearchPaths(const AutoSearchPaths& other) = default;
|
||||
AutoSearchPaths(AutoSearchPaths&& other) noexcept = default;
|
||||
AutoSearchPaths& operator=(const AutoSearchPaths& other) = default;
|
||||
AutoSearchPaths& operator=(AutoSearchPaths&& other) noexcept = default;
|
||||
|
||||
std::vector<std::string> GetSearchPathsForZonePath(const std::string& zonePath) const;
|
||||
|
||||
static AutoSearchPaths* GetForGame(GameId gameId);
|
||||
|
||||
protected:
|
||||
virtual const std::vector<std::string>& RecognizedZoneDirs() const = 0;
|
||||
virtual const std::vector<std::string>& AdditionalSearchPaths() const = 0;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "AutoSearchPathsIW3.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW3::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/english",
|
||||
"zone/french",
|
||||
"zone/german",
|
||||
"zone/italian",
|
||||
"zone/spanish",
|
||||
"zone/british",
|
||||
"zone/russian",
|
||||
"zone/polish",
|
||||
"zone/korean",
|
||||
"zone/taiwanese",
|
||||
"zone/japanese",
|
||||
"zone/chinese",
|
||||
"zone/thai",
|
||||
"zone/leet",
|
||||
"zone/czech",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW3::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsIW3 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
#include "AutoSearchPathsIW4.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW4::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/english",
|
||||
"zone/french",
|
||||
"zone/german",
|
||||
"zone/italian",
|
||||
"zone/spanish",
|
||||
"zone/british",
|
||||
"zone/russian",
|
||||
"zone/polish",
|
||||
"zone/korean",
|
||||
"zone/taiwanese",
|
||||
"zone/japanese",
|
||||
"zone/chinese",
|
||||
"zone/thai",
|
||||
"zone/leet",
|
||||
"zone/czech",
|
||||
|
||||
// Iw4x specific
|
||||
"zone/patch",
|
||||
"zone/dlc",
|
||||
"zone/zonebuilder",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW4::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
"iw4x",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsIW4 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
@@ -0,0 +1,32 @@
|
||||
#include "AutoSearchPathsIW5.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW5::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/english",
|
||||
"zone/french",
|
||||
"zone/german",
|
||||
"zone/italian",
|
||||
"zone/spanish",
|
||||
"zone/british",
|
||||
"zone/russian",
|
||||
"zone/polish",
|
||||
"zone/korean",
|
||||
"zone/taiwanese",
|
||||
"zone/japanese",
|
||||
"zone/chinese",
|
||||
"zone/thai",
|
||||
"zone/leet",
|
||||
"zone/czech",
|
||||
"zone/dlc",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsIW5::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsIW5 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "AutoSearchPathsT4.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT4::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/English",
|
||||
"zone/French",
|
||||
"zone/German",
|
||||
"zone/Italian",
|
||||
"zone/Spanish",
|
||||
"zone/British",
|
||||
"zone/Russian",
|
||||
"zone/Polish",
|
||||
"zone/Korean",
|
||||
"zone/Taiwanese",
|
||||
"zone/Japanese",
|
||||
"zone/Chinese",
|
||||
"zone/Thai",
|
||||
"zone/Leet",
|
||||
"zone/Czech",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT4::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsT4 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
@@ -0,0 +1,31 @@
|
||||
#include "AutoSearchPathsT5.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT5::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/Common",
|
||||
"zone/English",
|
||||
"zone/French",
|
||||
"zone/Frenchcan",
|
||||
"zone/German",
|
||||
"zone/Austrian",
|
||||
"zone/Italian",
|
||||
"zone/Spanish",
|
||||
"zone/British",
|
||||
"zone/Russian",
|
||||
"zone/Polish",
|
||||
"zone/Korean",
|
||||
"zone/Japanese",
|
||||
"zone/Czech",
|
||||
"zone/Fulljap",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT5::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsT5 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
@@ -0,0 +1,34 @@
|
||||
#include "AutoSearchPathsT6.h"
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT6::RecognizedZoneDirs() const
|
||||
{
|
||||
static std::vector<std::string> recognizedZoneDirs = {
|
||||
"zone/all",
|
||||
"zone/english",
|
||||
"zone/french",
|
||||
"zone/frenchcan",
|
||||
"zone/german",
|
||||
"zone/austrian",
|
||||
"zone/italian",
|
||||
"zone/spanish",
|
||||
"zone/british",
|
||||
"zone/russian",
|
||||
"zone/polish",
|
||||
"zone/korean",
|
||||
"zone/japanese",
|
||||
"zone/czech",
|
||||
"zone/fulljap",
|
||||
"zone/portuguese",
|
||||
"zone/mexicanspanish",
|
||||
};
|
||||
return recognizedZoneDirs;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AutoSearchPathsT6::AdditionalSearchPaths() const
|
||||
{
|
||||
static std::vector<std::string> additionalSearchPaths = {
|
||||
"main",
|
||||
"sound",
|
||||
};
|
||||
return additionalSearchPaths;
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "Game/AutoSearchPaths.h"
|
||||
|
||||
class AutoSearchPathsT6 final : public AutoSearchPaths
|
||||
{
|
||||
protected:
|
||||
[[nodiscard]] const std::vector<std::string>& RecognizedZoneDirs() const override;
|
||||
[[nodiscard]] const std::vector<std::string>& AdditionalSearchPaths() const override;
|
||||
};
|
||||
Reference in New Issue
Block a user