Skip to content

Commit c9f53c1

Browse files
committed
Material support, static TMD support
1 parent 83530e1 commit c9f53c1

7 files changed

Lines changed: 222 additions & 23 deletions

File tree

src/CLUTMap.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ void CLUTMap::updateBlocks()
3838
}
3939
}
4040

41-
CLUTMap::CLUTMap(Model& model)
41+
void CLUTMap::applyModel(Model& model)
4242
{
4343
auto texturePage = model.getTexturePage();
4444
auto clutX = model.getClutX();

src/CLUTMap.hpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@ class CLUTMap
2525

2626
std::map<uint32_t, CLUTMapImage> texturePages;
2727

28-
CLUTMap(Model& model);
29-
3028
CLUTMapImage& at(uint32_t id);
3129
CLUTMapImage& operator[](uint32_t id);
3230
void updateBlocks();
31+
void applyModel(Model& model);
3332
};

src/Collada.cpp

Lines changed: 182 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void ColladaExporter::setupXML()
205205
document.InsertEndChild(document.NewDeclaration());
206206
root = document.NewElement("COLLADA");
207207
root->SetAttribute("xmlns", "http://www.collada.org/2008/03/COLLADASchema");
208-
root->SetAttribute("version", "1.5.0");
208+
root->SetAttribute("version", "1.4.1");
209209
document.InsertEndChild(root);
210210
}
211211

@@ -237,12 +237,14 @@ void ColladaExporter::addColorFaces(tinyxml2::XMLElement* node, Mesh& mesh, std:
237237
}
238238

239239
if (colors.empty()) return;
240+
color = colors[0]; // used for material, only one color allowed
240241

241242
buildSource(node, colors, id + "-color");
242243

243244
// triangles element
244245
auto triNode = node->InsertNewChildElement("triangles");
245246
triNode->SetAttribute("count", colors.size() / 3);
247+
triNode->SetAttribute("material", "material-fixedColor");
246248

247249
buildInputShared(triNode, 0, "VERTEX", ("#" + id + "-vertices"));
248250
buildInputShared(triNode, 1, "NORMAL", ("#" + id + "-normal"));
@@ -276,6 +278,7 @@ void ColladaExporter::addTextureFaces(tinyxml2::XMLElement* node, Mesh& mesh, st
276278
// triangles element
277279
auto triNode = node->InsertNewChildElement("triangles");
278280
triNode->SetAttribute("count", uvs.size() / 3);
281+
triNode->SetAttribute("material", "material-textured");
279282

280283
buildInputShared(triNode, 0, "VERTEX", ("#" + id + "-vertices"));
281284
buildInputShared(triNode, 1, "NORMAL", ("#" + id + "-normal"));
@@ -284,6 +287,39 @@ void ColladaExporter::addTextureFaces(tinyxml2::XMLElement* node, Mesh& mesh, st
284287
triNode->InsertNewChildElement("p")->SetText(p.str().c_str());
285288
}
286289

290+
void ColladaExporter::addNoLightFaces(tinyxml2::XMLElement* node, Mesh& mesh, std::string id)
291+
{
292+
std::vector<TexCoord> uvs;
293+
std::stringstream p;
294+
295+
for (Face& face : mesh.faces)
296+
{
297+
if (face.material_type != MaterialType::NO_LIGHT) continue;
298+
299+
p << face.v1 << " " << uvs.size() + 0 << " ";
300+
p << face.v2 << " " << uvs.size() + 1 << " ";
301+
p << face.v3 << " " << uvs.size() + 2 << " ";
302+
303+
uvs.push_back(TexCoord(face.uv1, tim.getSize()));
304+
uvs.push_back(TexCoord(face.uv2, tim.getSize()));
305+
uvs.push_back(TexCoord(face.uv3, tim.getSize()));
306+
}
307+
308+
if (uvs.empty()) return;
309+
310+
buildSource(node, uvs, id + "-texcoord");
311+
312+
// triangles element
313+
auto triNode = node->InsertNewChildElement("triangles");
314+
triNode->SetAttribute("count", uvs.size() / 3);
315+
triNode->SetAttribute("material", "material-rawTextured");
316+
317+
buildInputShared(triNode, 0, "VERTEX", ("#" + id + "-vertices"));
318+
buildInputShared(triNode, 1, "TEXCOORD", ("#" + id + "-texcoord"));
319+
320+
triNode->InsertNewChildElement("p")->SetText(p.str().c_str());
321+
}
322+
287323
void ColladaExporter::buildGeometry()
288324
{
289325
auto node = root->InsertNewChildElement("library_geometries");
@@ -307,7 +343,7 @@ void ColladaExporter::buildGeometry()
307343
// faces
308344
addColorFaces(meshNode, mesh, id);
309345
addTextureFaces(meshNode, mesh, id);
310-
// addNoLightFaces(meshNode, mesh, id); // TODO
346+
addNoLightFaces(meshNode, mesh, id);
311347
}
312348
}
313349

@@ -418,20 +454,44 @@ void ColladaExporter::buildScene()
418454
scene->SetAttribute("id", "scene");
419455
scene->SetAttribute("name", "scene");
420456

421-
rootNode->SetAttribute("id", model.name.string().c_str());
422-
rootNode->SetAttribute("name", model.name.string().c_str());
457+
458+
rootNode->SetAttribute("id", model.name.c_str());
459+
rootNode->SetAttribute("name", model.name.c_str());
423460

424461
// mesh nodes
425462
auto meshNode = rootNode->InsertNewChildElement("node");
426463
meshNode->SetAttribute("id", "mesh");
427464

428465
for (uint32_t i = 0; i < model.meshes.size(); i++)
429466
{
430-
auto subNode = meshNode->InsertNewChildElement("node"); // TODO name
431-
auto instance = subNode->InsertNewChildElement("instance_controller");
467+
auto subNode = meshNode->InsertNewChildElement("node");
468+
subNode->SetAttribute("id", ("object-" + std::to_string(i)).c_str());
469+
subNode->SetAttribute("name", ("object-" + std::to_string(i)).c_str());
432470

471+
auto instance = subNode->InsertNewChildElement("instance_controller");
433472
instance->SetAttribute("url", ("#object-" + std::to_string(i) + "-skin").c_str());
434473
instance->InsertNewChildElement("skeleton")->SetText("#node-0");
474+
475+
auto bindMaterial = instance->InsertNewChildElement("bind_material");
476+
auto tech = bindMaterial->InsertNewChildElement("technique_common");
477+
478+
auto instanceTextured = tech->InsertNewChildElement("instance_material");
479+
instanceTextured->SetAttribute("symbol", "material-textured");
480+
instanceTextured->SetAttribute("target", "#mat-textured");
481+
auto uvInputTextured = instanceTextured->InsertNewChildElement("bind_vertex_input");
482+
uvInputTextured->SetAttribute("semantic", "UVSET0");
483+
uvInputTextured->SetAttribute("input_semantic", "TEXCOORD");
484+
485+
auto instanceRawTextured = tech->InsertNewChildElement("instance_material");
486+
instanceRawTextured->SetAttribute("symbol", "material-rawTextured");
487+
instanceRawTextured->SetAttribute("target", "#mat-rawTextured");
488+
auto uvInputRawTextured = instanceRawTextured->InsertNewChildElement("bind_vertex_input");
489+
uvInputRawTextured->SetAttribute("semantic", "UVSET0");
490+
uvInputRawTextured->SetAttribute("input_semantic", "TEXCOORD");
491+
492+
auto instanceFixedColor = tech->InsertNewChildElement("instance_material");
493+
instanceFixedColor->SetAttribute("symbol", "material-fixedColor");
494+
instanceFixedColor->SetAttribute("target", "#mat-fixedColor");
435495
}
436496

437497
// joint nodes
@@ -440,9 +500,10 @@ void ColladaExporter::buildScene()
440500

441501
std::vector<tinyxml2::XMLElement*> xmlNodes;
442502

443-
for (uint32_t i = 0; i < model.skeleton.size(); i++)
503+
for (uint32_t i = 0; i < model.skeleton.size() || i == 0; i++)
444504
{
445-
auto& entry = model.skeleton[i];
505+
NodeEntry entry{ 0xFF, 0xFF };
506+
if (model.skeleton.size() != 0) entry = model.skeleton[i];
446507
auto parent = entry.parent == 0xFF ? jointsNode : xmlNodes[entry.parent];
447508

448509
auto node = parent->InsertNewChildElement("node");
@@ -534,17 +595,127 @@ void ColladaExporter::buildAnimations()
534595
}
535596
}
536597

598+
void ColladaExporter::buildImages()
599+
{
600+
auto libImages = root->InsertNewChildElement("library_images");
601+
602+
auto image = libImages->InsertNewChildElement("image");
603+
image->SetAttribute("id", "texture");
604+
image->SetAttribute("name", "texture");
605+
auto initFrom = image->InsertNewChildElement("init_from");
606+
607+
initFrom->SetText(model.texture->string().c_str());
608+
}
609+
610+
void ColladaExporter::buildEffect1(tinyxml2::XMLElement* libEffects)
611+
{
612+
auto effect = libEffects->InsertNewChildElement("effect");
613+
effect->SetAttribute("id", "fx-textured");
614+
auto profile = effect->InsertNewChildElement("profile_COMMON");
615+
616+
auto texParam = profile->InsertNewChildElement("newparam");
617+
texParam->SetAttribute("sid", "tex");
618+
auto surface = texParam->InsertNewChildElement("surface");
619+
surface->SetAttribute("type", "2D");
620+
surface->InsertNewChildElement("init_from")->SetText("texture");
621+
622+
auto samplerParam = profile->InsertNewChildElement("newparam");
623+
samplerParam->SetAttribute("sid", "texture-sampler");
624+
auto sampler = samplerParam->InsertNewChildElement("sampler2D");
625+
sampler->InsertNewChildElement("source")->SetText("tex");
626+
627+
auto technique = profile->InsertNewChildElement("technique");
628+
technique->SetAttribute("sid", "COMMON");
629+
630+
auto shader = technique->InsertNewChildElement("lambert");
631+
auto diffuse = shader->InsertNewChildElement("diffuse");
632+
auto diffuseTexture = diffuse->InsertNewChildElement("texture");
633+
diffuseTexture->SetAttribute("texcoord", "UVSET0");
634+
diffuseTexture->SetAttribute("texture", "texture-sampler");
635+
}
636+
637+
void ColladaExporter::buildEffect2(tinyxml2::XMLElement* libEffects)
638+
{
639+
auto effect = libEffects->InsertNewChildElement("effect");
640+
effect->SetAttribute("id", "fx-rawTextured");
641+
auto profile = effect->InsertNewChildElement("profile_COMMON");
642+
643+
auto texParam = profile->InsertNewChildElement("newparam");
644+
texParam->SetAttribute("sid", "tex");
645+
auto surface = texParam->InsertNewChildElement("surface");
646+
surface->SetAttribute("type", "2D");
647+
surface->InsertNewChildElement("init_from")->SetText("texture");
648+
649+
auto samplerParam = profile->InsertNewChildElement("newparam");
650+
samplerParam->SetAttribute("sid", "texture-sampler");
651+
auto sampler = samplerParam->InsertNewChildElement("sampler2D");
652+
sampler->InsertNewChildElement("source")->SetText("tex");
653+
654+
auto technique = profile->InsertNewChildElement("technique");
655+
technique->SetAttribute("sid", "COMMON");
656+
657+
auto shader = technique->InsertNewChildElement("lambert");
658+
auto diffuse = shader->InsertNewChildElement("diffuse");
659+
auto diffuseTexture = diffuse->InsertNewChildElement("texture");
660+
diffuseTexture->SetAttribute("texcoord", "UVSET0");
661+
diffuseTexture->SetAttribute("texture", "texture-sampler");
662+
}
663+
664+
void ColladaExporter::buildEffect3(tinyxml2::XMLElement* libEffects)
665+
{
666+
auto effect = libEffects->InsertNewChildElement("effect");
667+
effect->SetAttribute("id", "fx-fixedColor");
668+
auto profile = effect->InsertNewChildElement("profile_COMMON");
669+
auto technique = profile->InsertNewChildElement("technique");
670+
technique->SetAttribute("sid", "COMMON");
671+
672+
auto shader = technique->InsertNewChildElement("lambert");
673+
auto diffuse = shader->InsertNewChildElement("diffuse");
674+
diffuse->InsertNewChildElement("color")->SetText(
675+
(std::to_string(color.r / 255.0f) + " " + std::to_string(color.g / 255.0f) + " " + std::to_string(color.b / 255.0f) + " 1").c_str());
676+
}
677+
678+
void ColladaExporter::buildEffects()
679+
{
680+
auto libEffects = root->InsertNewChildElement("library_effects");
681+
buildEffect1(libEffects);
682+
buildEffect2(libEffects);
683+
buildEffect3(libEffects);
684+
}
685+
686+
void ColladaExporter::buildMaterials() {
687+
auto libMaterials = root->InsertNewChildElement("library_materials");
688+
689+
auto matTexture = libMaterials->InsertNewChildElement("material");
690+
matTexture->SetAttribute("id", "mat-textured");
691+
matTexture->SetAttribute("name", "mat-textured");
692+
matTexture->InsertNewChildElement("instance_effect")->SetAttribute("url", "#fx-textured");
693+
694+
695+
auto matRawTexture = libMaterials->InsertNewChildElement("material");
696+
matRawTexture->SetAttribute("id", "mat-rawTextured");
697+
matRawTexture->SetAttribute("name", "mat-rawTextured");
698+
matRawTexture->InsertNewChildElement("instance_effect")->SetAttribute("url", "#fx-rawTextured");
699+
700+
701+
auto matFixedColor = libMaterials->InsertNewChildElement("material");
702+
matFixedColor->SetAttribute("id", "mat-fixedColor");
703+
matFixedColor->SetAttribute("name", "mat-fixedColor");
704+
matFixedColor->InsertNewChildElement("instance_effect")->SetAttribute("url", "#fx-fixedColor");
705+
}
706+
537707
void ColladaExporter::buildXML()
538708
{
539709
buildAssetNode();
540-
// library_texture
541-
// library_material
542-
// library_effects
543710

544711
buildGeometry();
545712
buildControllers();
546713
buildAnimations();
547714

715+
buildImages();
716+
buildEffects();
717+
buildMaterials();
718+
548719
buildScene();
549720
}
550721

src/Collada.hpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,27 @@ class ColladaExporter
1313
Model& model;
1414
AbstractTIM& tim;
1515

16+
Color color{};
17+
1618
private:
1719
void setupXML();
1820
void buildAssetNode();
1921
void addColorFaces(tinyxml2::XMLElement* node, Mesh& mesh, std::string id);
2022
void addTextureFaces(tinyxml2::XMLElement* node, Mesh& mesh, std::string id);
23+
void addNoLightFaces(tinyxml2::XMLElement* node, Mesh& mesh, std::string id);
2124

2225
void buildGeometry();
2326
void buildControllers();
27+
void buildImages();
2428
void buildXML();
2529
void buildScene();
2630
void buildAnimations();
31+
void buildEffects();
32+
void buildMaterials();
33+
34+
void buildEffect1(tinyxml2::XMLElement* libEffects);
35+
void buildEffect2(tinyxml2::XMLElement* libEffects);
36+
void buildEffect3(tinyxml2::XMLElement* libEffects);
2737

2838
public:
2939
ColladaExporter(Model& model, AbstractTIM& tim);

src/Model.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ Model::Model(filepath mesh, std::optional<filepath> nodes, std::optional<filepat
245245
: texture(texture)
246246
{
247247
std::streamoff length = std::filesystem::file_size(mesh);
248+
name = mesh.filename().string();
248249

249250
if (nodes) loadNodes(nodes.value()); // load nodes before mesh, since animations need to know about the bone count
250251
loadMesh(mesh);
@@ -273,11 +274,13 @@ void Model::loadMesh(filepath path)
273274
}
274275

275276
loadTMD(*tmdPtr);
276-
if (mtnPtr != NULL)
277+
if (mtnPtr != NULL && skeleton.size() != 0)
277278
{
278279
ReadBuffer b(mtnPtr);
279280
anims = std::make_unique<MMDAnimations>(b, skeleton.size());
280281
}
282+
else
283+
anims = std::make_unique<MMDAnimations>();
281284
}
282285

283286
uint32_t Model::getTexturePage() const

src/Model.hpp

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ class Model
262262
void loadNodes(filepath path);
263263

264264
public:
265-
std::filesystem::path name;
265+
std::string name;
266266
std::vector<Mesh> meshes;
267267
std::unique_ptr<MMDAnimations> anims;
268268
std::vector<NodeEntry> skeleton;
@@ -276,7 +276,7 @@ class Model
276276

277277
// Model(std::filesystem::path name, std::vector<Mesh> meshes, std::unique_ptr<MMDAnimations> anims) : name(name),
278278
// meshes(meshes), anims(std::move(anims)) {}
279-
Model(filepath mesh, std::optional<filepath> nodes, std::optional<filepath> texture);
279+
Model(filepath mesh, std::optional<filepath> nodes = {}, std::optional<filepath> texture = {});
280280
};
281281

282282
/*
@@ -341,4 +341,19 @@ ETCHI/MAHI.TMD ->
341341
ETCNA/ABOX.TMD -> OMOC08 MAP Image 2
342342
ETCNA/BIGBOX.TMD -> OMOC08 MAP Image 2
343343
344+
BTL_REL.BIN@0x0D20 ->
345+
VS_REL.BIN@0x0D20 ->
346+
STD_REL.BIN@0x0D20 ->
347+
348+
BTL_REL.BIN@0x1D58 ->
349+
VS_REL.BIN@0x1D58 ->
350+
STD_REL.BIN@0x1D58 ->
351+
352+
BTL_REL.BIN@0x2220 ->
353+
VS_REL.BIN@0x2220 ->
354+
STD_REL.BIN@0x2220 ->
355+
356+
BTL_REL.BIN@0x2848 ->
357+
VS_REL.BIN@0x2848 ->
358+
STD_REL.BIN@0x2848 ->
344359
*/

0 commit comments

Comments
 (0)