1+ #include < algorithm>
12#include < bstream.h>
23#include < cstdint>
34#include < format>
45#include " GXGeometryData.hpp"
6+ #include " GenUtil.hpp"
57#include " ImGuiFileDialog/ImGuiFileDialog.h"
68#include " DOM/RoomDOMNode.hpp"
79#include " DOM/ObserverDOMNode.hpp"
1113#include " IconsForkAwesome.h"
1214#include " imgui.h"
1315#include " io/BinIO.hpp"
16+ #include " io/Util.hpp"
1417#include " modes/ActorMode.hpp"
1518#include " scene/ModelViewer.hpp"
1619#include < Bti.hpp>
2124#include " stb_image.h"
2225#include " stb_image_write.h"
2326#include " tiny_obj_loader.h"
27+ #include " tri_stripper.h"
2428
2529enum class SelectedResourceType {
2630 Texture,
@@ -196,7 +200,7 @@ void BinTreeNodeUI(BIN::Model* model, uint32_t index){
196200 BinSelectedResource = &model->mGraphNodes [index];
197201 }
198202 ImGui::Text (ICON_FK_CUBE " Draw Elements" );
199- uint32_t deleteIdx = UINT32_MAX ;
203+ uint16_t deleteIdx = UINT16_MAX ;
200204 for (int i = 0 ; i < model->mGraphNodes [index].mDrawElements .size (); i++){ // model->mGraphNodes[index].mDrawElements
201205 ImGui::Text (std::format (" [Batch {}, Material {}]" , model->mGraphNodes [index].mDrawElements [i].BatchIndex , model->mGraphNodes [index].mDrawElements [i].MaterialIndex ).c_str ());
202206
@@ -213,7 +217,7 @@ void BinTreeNodeUI(BIN::Model* model, uint32_t index){
213217 }
214218 }
215219
216- if (deleteIdx != UINT32_MAX ){
220+ if (deleteIdx != UINT16_MAX ){
217221 model->mGraphNodes [index].mDrawElements .erase (model->mGraphNodes [index].mDrawElements .begin () + deleteIdx);
218222 }
219223
@@ -328,7 +332,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
328332 ImGui::Separator ();
329333 ImGui::BeginChild (" ##binResources" , {180 , 125 });
330334 if (ImGui::TreeNode (ICON_FK_CUBE " Batches" )){
331- uint32_t deleteIdx = UINT32_MAX ;
335+ uint16_t deleteIdx = UINT16_MAX ;
332336 for (auto [idx, batch] : PreviewWidget::GetFurnitureModel ()->mBatches ){
333337 ImGui::Text (" Batch %d" , idx);
334338 if (ImGui::IsItemClicked (0 )){
@@ -342,7 +346,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
342346 ImGui::EndPopup ();
343347 }
344348 }
345- if (deleteIdx != UINT32_MAX ){
349+ if (deleteIdx != UINT16_MAX ){
346350 BinSelectedResource = nullptr ;
347351 SelectedType = SelectedResourceType::None;
348352 PreviewWidget::GetFurnitureModel ()->mBatches .erase (deleteIdx);
@@ -358,7 +362,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
358362 }
359363
360364 if (ImGui::TreeNode (ICON_FK_PAINT_BRUSH " Materials" )){
361- uint32_t deleteIdx = UINT32_MAX ;
365+ uint16_t deleteIdx = UINT16_MAX ;
362366 for (auto [idx, material] : PreviewWidget::GetFurnitureModel ()->mMaterials ){
363367 ImGui::Text (" Material %d" , idx);
364368 if (ImGui::IsItemClicked (0 )){
@@ -372,7 +376,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
372376 ImGui::EndPopup ();
373377 }
374378 }
375- if (deleteIdx != UINT32_MAX ){
379+ if (deleteIdx != UINT16_MAX ){
376380 BinSelectedResource = nullptr ;
377381 SelectedType = SelectedResourceType::None;
378382 PreviewWidget::GetFurnitureModel ()->mMaterials .erase (deleteIdx);
@@ -388,7 +392,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
388392 }
389393
390394 if (ImGui::TreeNode (ICON_FK_PAINT_BRUSH " Samplers" )){
391- uint32_t deleteIdx = UINT32_MAX ;
395+ uint16_t deleteIdx = UINT16_MAX ;
392396 for (auto [idx, sampler] : PreviewWidget::GetFurnitureModel ()->mSamplers ){
393397 ImGui::Text (" Sampler %d" , idx);
394398 if (ImGui::IsItemClicked (0 )){
@@ -402,7 +406,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
402406 ImGui::EndPopup ();
403407 }
404408 }
405- if (deleteIdx != UINT32_MAX ){
409+ if (deleteIdx != UINT16_MAX ){
406410 PreviewWidget::GetFurnitureModel ()->mSamplers .erase (deleteIdx);
407411 for (auto [idx, material] : PreviewWidget::GetFurnitureModel ()->mMaterials ){
408412 if (PreviewWidget::GetFurnitureModel ()->mMaterials [idx].SamplerIndices [0 ] == deleteIdx){
@@ -416,7 +420,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
416420 }
417421
418422 if (ImGui::TreeNode (ICON_FK_PICTURE_O " Textures" )){
419- uint32_t deleteIdx = UINT32_MAX ;
423+ uint16_t deleteIdx = UINT16_MAX ;
420424 for (auto [idx, texture] : PreviewWidget::GetFurnitureModel ()->mTexturesHeaders ){
421425 ImGui::Image (static_cast <uintptr_t >(texture.TextureID ), {16 , 16 });
422426 ImGui::SameLine ();
@@ -441,7 +445,7 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
441445 }
442446 }
443447
444- if (deleteIdx != UINT32_MAX ){
448+ if (deleteIdx != UINT16_MAX ){
445449 PreviewWidget::GetFurnitureModel ()->mTexturesHeaders .erase (deleteIdx);
446450 for (auto [idx, sampler] : PreviewWidget::GetFurnitureModel ()->mSamplers ){
447451 if (PreviewWidget::GetFurnitureModel ()->mSamplers [idx].TextureIndex == deleteIdx){
@@ -611,57 +615,64 @@ void LRoomDOMNode::RenderHierarchyUI(std::shared_ptr<LDOMNodeBase> self, LEditor
611615 std::string modelPath;
612616 if (LUIUtility::RenderFileDialog (" replaceBatchDialog" , modelPath)){// error check should be here oops!
613617 if (BinSelectedResource != nullptr ){
614- tinyobj::attrib_t attributes;
618+
619+ auto batch = reinterpret_cast <BIN::Batch*>(BinSelectedResource);
620+ batch->Primitives .clear ();
621+
622+ tinyobj::attrib_t attributes;
615623 std::vector<tinyobj::shape_t > shapes;
616624 std::vector<tinyobj::material_t > materials;
617625
618626 std::string warn;
619627 std::string err;
620- bool ret = tinyobj::LoadObj (&attributes, &shapes, &materials, &warn, &err, modelPath.c_str (), std::filesystem::path (modelPath).parent_path ().string ().c_str (), true );
621-
622- if (!ret){
628+ bool ret = tinyobj::LoadObj (&attributes, &shapes, &materials, &warn, &err, std::filesystem::path (modelPath).string ().c_str (), std::filesystem::path (modelPath).parent_path ().string ().c_str (), true );
629+ if (!ret){
623630 return ;
624631 }
625632
626- auto batch = reinterpret_cast <BIN::Batch*>(BinSelectedResource) ;
627-
633+ std::vector<Vertex> vertices ;
634+ std::vector<std:: size_t > indices;
628635 for (auto shp : shapes){
629- BIN::Primitive primitive;
630- primitive.Opcode = GXPrimitiveType::Triangles;
631- for (int poly = 0 ; poly < shp.mesh .indices .size () / 3 ; poly++){
632- if (shp.mesh .indices .size () == 0 ) continue ;
633- Vertex vtx0, vtx1, vtx2;
634-
635- int mVtx1 = shp.mesh .indices [(3 *poly)+0 ].vertex_index ;
636- int mVtx2 = shp.mesh .indices [(3 *poly)+1 ].vertex_index ;
637- int mVtx3 = shp.mesh .indices [(3 *poly)+2 ].vertex_index ;
638-
639- int mNrm1 = shp.mesh .indices [(3 *poly)+0 ].normal_index ;
640- int mNrm2 = shp.mesh .indices [(3 *poly)+1 ].normal_index ;
641- int mNrm3 = shp.mesh .indices [(3 *poly)+2 ].normal_index ;
642-
643- int mTcd1 = shp.mesh .indices [(3 *poly)+0 ].texcoord_index ;
644- int mTcd2 = shp.mesh .indices [(3 *poly)+1 ].texcoord_index ;
645- int mTcd3 = shp.mesh .indices [(3 *poly)+2 ].texcoord_index ;
646-
647- vtx0.Position = glm::vec3 (attributes.vertices [mVtx1 * 3 ], attributes.vertices [(mVtx1 * 3 ) + 1 ], attributes.vertices [(mVtx1 * 3 ) + 2 ]);
648- vtx1.Position = glm::vec3 (attributes.vertices [mVtx2 * 3 ], attributes.vertices [(mVtx2 * 3 ) + 1 ], attributes.vertices [(mVtx2 * 3 ) + 2 ]);
649- vtx2.Position = glm::vec3 (attributes.vertices [mVtx3 * 3 ], attributes.vertices [(mVtx3 * 3 ) + 1 ], attributes.vertices [(mVtx3 * 3 ) + 2 ]);
650-
651- vtx0.Normal = glm::vec3 (attributes.normals [mNrm1 * 3 ], attributes.normals [(mNrm1 * 3 ) + 1 ], attributes.normals [(mNrm1 * 3 ) + 2 ]);
652- vtx1.Normal = glm::vec3 (attributes.normals [mNrm2 * 3 ], attributes.normals [(mNrm2 * 3 ) + 1 ], attributes.normals [(mNrm2 * 3 ) + 2 ]);
653- vtx1.Normal = glm::vec3 (attributes.normals [mNrm3 * 3 ], attributes.normals [(mNrm3 * 3 ) + 1 ], attributes.normals [(mNrm3 * 3 ) + 2 ]);
654-
655- vtx0.Texcoord = glm::vec2 (attributes.texcoords [mTcd1 * 2 ], attributes.texcoords [(mTcd1 * 2 ) + 1 ]);
656- vtx1.Texcoord = glm::vec2 (attributes.texcoords [mTcd2 * 2 ], attributes.texcoords [(mTcd2 * 2 ) + 1 ]);
657- vtx2.Texcoord = glm::vec2 (attributes.texcoords [mTcd3 * 2 ], attributes.texcoords [(mTcd3 * 2 ) + 1 ]);
658-
659- primitive.Vertices .push_back (vtx0);
660- primitive.Vertices .push_back (vtx1);
661- primitive.Vertices .push_back (vtx2);
636+ if (shp.mesh .indices .size () == 0 ) continue ;
637+ for (int i = 0 ; i < shp.mesh .indices .size (); i++){
638+ Vertex vtx;
639+ int v = shp.mesh .indices [i].vertex_index ;
640+ int n = shp.mesh .indices [i].normal_index ;
641+ int t = shp.mesh .indices [i].texcoord_index ;
642+ vtx.Position = glm::vec3 (attributes.vertices [v * 3 ], attributes.vertices [(v * 3 ) + 1 ], attributes.vertices [(v * 3 ) + 2 ]);
643+ vtx.Normal = glm::vec3 (attributes.normals [n * 3 ], attributes.normals [(n * 3 ) + 1 ], attributes.normals [(n * 3 ) + 2 ]);
644+ vtx.Texcoord = glm::vec2 (attributes.texcoords [t * 2 ], attributes.texcoords [(t * 2 ) + 1 ]);
645+
646+ auto vtxIdx = std::find_if (vertices.begin (), vertices.end (), [i=vtx](const Vertex& o){
647+ return i.Position == o.Position && i.Normal == o.Normal && i.Texcoord == o.Texcoord ;
648+ });
649+
650+ if (vtxIdx != vertices.end ()){
651+ indices.push_back (vtxIdx - vertices.begin ());
652+ } else {
653+ indices.push_back (vertices.size ());
654+ vertices.push_back (vtx);
655+ }
662656 }
663- batch->Primitives .push_back (primitive);
657+
658+ triangle_stripper::tri_stripper stripify (indices);
659+ triangle_stripper::primitive_vector primitives;
660+ stripify.SetBackwardSearch (false );
661+ stripify.Strip (&primitives);
662+
663+ int indexCount = 0 ;
664+ for (auto p : primitives){
665+ BIN::Primitive primitive;
666+ primitive.Opcode = (p.Type == triangle_stripper::TRIANGLE_STRIP ? GXPrimitiveType::TriangleStrip : GXPrimitiveType::Triangles);
667+ for (int i = 0 ; i < p.Indices .size (); i++){
668+ primitive.Vertices .push_back (vertices[p.Indices [i]]);
669+ }
670+ indexCount += p.Indices .size ();
671+ batch->Primitives .push_back (primitive);
672+ }
673+ LGenUtility::Log << " Stripped count " << indexCount << " Triangle Count " << shp.mesh .indices .size () << std::endl;
664674 }
675+
665676 ImGui::OpenPopup (" ##roomResources" );
666677 }
667678 }
0 commit comments