Skip to content

Commit 4c65450

Browse files
committed
Assimp: Fix loading out-of-folder textures
Hopefully no reversions with the blender plugin
1 parent 22b2cbf commit 4c65450

File tree

5 files changed

+38
-11
lines changed

5 files changed

+38
-11
lines changed

source/librii/assimp/LRAssimp.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,7 @@ std::vector<Mesh> ReadMeshes(const aiScene& scn,
122122
// Old code, taken from Material.hpp
123123
namespace {
124124
struct ImpSampler {
125+
std::string name;
125126
std::string path;
126127
u32 uv_channel;
127128
};
@@ -160,7 +161,8 @@ ImpMaterial ReadImp(const aiMaterial& mat) {
160161
const auto [path, uvindex, mapmode] = GetTexture(&mat, t, j);
161162

162163
ImpSampler impSamp{
163-
.path = getFileShort(path.C_Str()),
164+
.name = getFileShort(path.C_Str()),
165+
.path = {path.C_Str()},
164166
.uv_channel = uvindex,
165167
};
166168
impMat.samplers.push_back(impSamp);
@@ -192,10 +194,12 @@ static inline glm::mat4 getMat4(const aiMatrix4x4& mtx) {
192194
} // namespace
193195
Material ReadMaterial(const aiMaterial& mat) {
194196
auto imp = ReadImp(mat);
195-
std::string tex = imp.samplers.empty() ? "" : imp.samplers[0].path;
197+
std::string tex = imp.samplers.empty() ? "" : imp.samplers[0].name;
198+
std::string tex_path_hint = imp.samplers.empty() ? "" : imp.samplers[0].path;
196199
return {
197200
.name = const_cast<aiMaterial&>(mat).GetName().C_Str(),
198201
.texture = tex,
202+
.texture_path_hint = tex_path_hint,
199203
};
200204
}
201205
std::vector<Material> ReadMaterials(const aiScene& scn) {

source/librii/assimp/LRAssimp.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,9 @@ struct Material {
109109

110110
// Dramatic simplification
111111
std::string texture;
112+
113+
// (OPTIONAL) Full absolute/relative path on disk to a .png file typically
114+
std::string texture_path_hint;
112115
};
113116

114117
struct Node {

source/librii/assimp2rhst/Importer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,7 @@ Result<librii::rhst::SceneTree> AssImporter::Import(const Settings& settings) {
205205
mr.name = new_mats[i];
206206

207207
mr.texture_name = pMat->texture;
208+
mr.texture_path_hint = pMat->texture_path_hint;
208209
}
209210

210211
// TODO: Handle material limitations for samplers..

source/librii/rhst/RHST.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,19 @@ struct PixelEngine {
209209
};
210210

211211
struct ProtoSampler {
212+
// TODO(rii): I would rather see raw texture bytes referenced, to be honest.
213+
// (maybe a texture array with entries of each `std::vector<u8>
214+
// encoded_texture`, texture format, width, height, etc?)
215+
//
216+
// - The blender plugin handles texture encoding, and it wouldn't be too much
217+
// effort to make the assimp code do so too! RHST need not be general beyond
218+
// GC/Wii, and GC/Wii has consistent texture hardware support.
219+
//
220+
// - Encoding can be done with gctex fairly easily. There's some nuance for
221+
// mipmap encoding; this is handled by the `librii::texture` wrapper
222+
//
212223
std::string texture_name = "";
224+
213225
WrapMode wrap_u = WrapMode::Repeat;
214226
WrapMode wrap_v = WrapMode::Repeat;
215227

@@ -463,8 +475,12 @@ struct ProtoMaterial {
463475

464476
std::vector<ProtoSampler> samplers;
465477

478+
// TODO: Remove legacy support! Assimp should be swapped over to sampler
479+
// config method.
480+
466481
// Legacy support
467482
std::string texture_name = "";
483+
std::string texture_path_hint = ""; // For Assimp route
468484
WrapMode wrap_u = WrapMode::Repeat;
469485
WrapMode wrap_v = WrapMode::Repeat;
470486
bool min_filter = true;

source/plugins/rhst/RHSTImporter.cpp

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1073,7 +1073,8 @@ void import_texture(std::string tex, libcube::Texture* pdata,
10731073
return;
10741074
}
10751075
}
1076-
rsl::error("Cannot find texture {}", tex.c_str());
1076+
auto path_ = file_path.string();
1077+
rsl::error("Cannot find texture {} (initial path: {})", tex.c_str(), path_);
10771078
// 32x32 (32bpp)
10781079
const auto dummy_width = 32;
10791080
const auto dummy_height = 32;
@@ -1093,17 +1094,21 @@ bool CompileRHST(librii::rhst::SceneTree& rhst, libcube::Scene& scene,
10931094
std::function<void(std::string, std::string)> info,
10941095
std::function<void(std::string_view, float)> progress,
10951096
std::optional<MipGen> mips, bool tristrip, bool verbose) {
1096-
std::set<std::string> textures_needed;
1097+
std::map<std::string, std::string /*path_hint (OPTIONAL)*/> textures_needed;
10971098

10981099
for (auto& mat : rhst.materials) {
10991100
if (mat.samplers.empty()) {
1101+
// For Assimp importer
1102+
// TODO: Remove this and move to the sampler-only workflow
11001103
if (!mat.texture_name.empty()) {
1101-
textures_needed.emplace(mat.texture_name);
1104+
textures_needed.emplace(mat.texture_name, mat.texture_path_hint);
11021105
}
11031106
} else {
11041107
for (auto& sam : mat.samplers) {
1108+
// Asssimp importer won't specify samplers; this is only the Blender
1109+
// plugin route?
11051110
if (!sam.texture_name.empty()) {
1106-
textures_needed.emplace(sam.texture_name);
1111+
textures_needed.emplace(sam.texture_name, "");
11071112
}
11081113
}
11091114
}
@@ -1127,19 +1132,17 @@ bool CompileRHST(librii::rhst::SceneTree& rhst, libcube::Scene& scene,
11271132
}
11281133

11291134
for (auto& tex : textures_needed) {
1130-
rsl::info("Importing texture: {}", tex.c_str());
1135+
rsl::info("Importing texture: {}", tex.first.c_str());
11311136

11321137
auto& data = scene.getTextures().add();
1133-
data.setName(getFileShort(tex));
1138+
data.setName(getFileShort(tex.first));
11341139
}
1135-
// Favor PNG, and the current directory
1136-
auto file_path = std::filesystem::path(path);
11371140

11381141
std::vector<std::future<void>> futures;
11391142

11401143
for (int i = 0; i < scene.getTextures().size(); ++i) {
11411144
libcube::Texture* data = &scene.getTextures()[i];
1142-
1145+
std::filesystem::path file_path = textures_needed[data->getName()];
11431146
futures.push_back(std::async(std::launch::async, [=] {
11441147
import_texture(data->getName(), data, file_path, mips);
11451148
}));

0 commit comments

Comments
 (0)