Skip to content

Commit 9c5e375

Browse files
committed
#157 Implement save/load array attribute & test export atlas sprite
1 parent dd116b8 commit 9c5e375

File tree

7 files changed

+144
-5
lines changed

7 files changed

+144
-5
lines changed

Projects/Editor/Source/Editor/AssetEditor/CSpriteEditor.cpp

Lines changed: 94 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,17 @@ This file is part of the "Skylicht Engine".
3232
#include "Editor/CEditor.h"
3333

3434
#include "AssetManager/CAssetImporter.h"
35+
#include "AssetManager/CAssetManager.h"
36+
37+
#include "Graphics2D/SpriteFrame/CSpriteAtlas.h"
38+
39+
#include <filesystem>
40+
41+
#if defined(__APPLE_CC__)
42+
namespace fs = std::__fs::filesystem;
43+
#else
44+
namespace fs = std::filesystem;
45+
#endif
3546

3647
namespace Skylicht
3748
{
@@ -75,16 +86,97 @@ namespace Skylicht
7586
std::string exportPath = path;
7687
ui->addButton(layout, L"Export Sprite")->OnPress = [&, p = exportPath](GUI::CBase* button)
7788
{
78-
89+
exportSprite(p.c_str());
7990
};
8091

8192
group->setExpand(true);
8293
}
8394

95+
void CSpriteEditor::exportSprite(const char* path)
96+
{
97+
if (m_settings == NULL)
98+
return;
99+
100+
std::vector<std::string> folders;
101+
std::vector<std::string> pngs;
102+
103+
CArrayTypeSerializable<CFolderPathProperty>& listFolders = m_settings->ImagesFolder;
104+
for (int i = 0, n = listFolders.getElementCount(); i < n; i++)
105+
{
106+
CFolderPathProperty* value = dynamic_cast<CFolderPathProperty*>(listFolders.getPropertyID(i));
107+
folders.push_back(value->getString());
108+
}
109+
110+
CAssetManager* assetManager = CAssetManager::getInstance();
111+
for (std::string& folder : folders)
112+
{
113+
std::string discovery = assetManager->getAssetFolder() + "/" + folder;
114+
findAllPNG(discovery.c_str(), pngs);
115+
}
116+
117+
CSpriteAtlas* sprite = new CSpriteAtlas(
118+
m_settings->Alpha.get() ? ECF_A8R8G8B8 : ECF_R8G8B8,
119+
m_settings->Width.get(),
120+
m_settings->Height.get());
121+
122+
for (std::string& png : pngs)
123+
{
124+
os::Printer::log(png.c_str());
125+
std::string name = CPath::getFileNameNoExt(png);
126+
sprite->addFrame(name.c_str(), png.c_str());
127+
}
128+
129+
sprite->updateTexture();
130+
131+
int id = 0;
132+
std::string folderPath = assetManager->getAssetFolder() + "/" + CPath::getFolderPath(path);
133+
std::string exportName = CPath::getFileNameNoExt(path);
134+
135+
std::vector<SImage*>& allImages = sprite->getImages();
136+
for (SImage* img : allImages)
137+
{
138+
char name[64];
139+
sprintf(name, "%s/%s_%d.png",
140+
folderPath.c_str(),
141+
exportName.c_str(),
142+
id++);
143+
144+
IImage* i = img->Atlas->getImage();
145+
if (getVideoDriver()->getDriverType() == EDT_DIRECT3D11)
146+
i->swapBG();
147+
148+
getVideoDriver()->writeImageToFile(i, name);
149+
150+
if (getVideoDriver()->getDriverType() == EDT_DIRECT3D11)
151+
i->swapBG();
152+
}
153+
154+
delete sprite;
155+
}
156+
157+
void CSpriteEditor::findAllPNG(const char* path, std::vector<std::string>& pngs)
158+
{
159+
for (const auto& file : fs::directory_iterator(path))
160+
{
161+
std::string path = file.path().generic_u8string();
162+
163+
if (file.is_directory())
164+
{
165+
findAllPNG(path.c_str(), pngs);
166+
}
167+
else
168+
{
169+
std::string ext = CStringImp::toLower(CPath::getFileNameExt(path));
170+
if (ext == "png")
171+
pngs.push_back(path);
172+
}
173+
}
174+
}
175+
84176
SpriteExportSettings* CSpriteEditor::createGetMeshExportSetting(const char* path)
85177
{
86178
SpriteExportSettings* setting = new SpriteExportSettings();
87-
CSerializableLoader::loadSerializable(path, setting);
179+
CSerializableLoader::loadSerializable(path, setting);
88180
return setting;
89181
}
90182

Projects/Editor/Source/Editor/AssetEditor/CSpriteEditor.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ namespace Skylicht
4949

5050
SpriteExportSettings* createGetMeshExportSetting(const char* path);
5151

52+
void exportSprite(const char* path);
53+
54+
void findAllPNG(const char* path, std::vector<std::string>& pngs);
55+
5256
DECLARE_GETTYPENAME(CSpriteEditor);
5357
};
5458
}

Projects/Editor/Source/ResourceSettings/SpriteExportSettings.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ namespace Skylicht
3131
{
3232
SpriteExportSettings::SpriteExportSettings() :
3333
CObjectSerializable("SpriteExportSettings"),
34+
Width(this, "Width", 2048),
35+
Height(this, "Height", 2048),
36+
Alpha(this, "Alpha", true),
3437
ImagesFolder("Images folder", this)
3538
{
3639

Projects/Editor/Source/ResourceSettings/SpriteExportSettings.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,10 @@ namespace Skylicht
3434
class SpriteExportSettings : public CObjectSerializable
3535
{
3636
public:
37+
CIntProperty Width;
38+
CIntProperty Height;
39+
CBoolProperty Alpha;
40+
3741
CArrayTypeSerializable<CFolderPathProperty> ImagesFolder;
3842

3943
public:

Projects/Skylicht/Engine/Source/Graphics2D/SpriteFrame/CSpriteAtlas.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,14 +49,24 @@ namespace Skylicht
4949

5050
virtual ~CSpriteAtlas();
5151

52-
SFrame* addFrame(const char *name, const char *path);
52+
SFrame* addFrame(const char* name, const char* path);
5353

54-
SFrame* getFrame(const char *name);
54+
SFrame* getFrame(const char* name);
5555

5656
SImage* createAtlasRect(int w, int h, core::recti& outRegion);
5757

5858
void updateTexture();
5959

60+
inline std::vector<SFrame*>& getFrames()
61+
{
62+
return m_frames;
63+
}
64+
65+
inline std::vector<SImage*>& getImages()
66+
{
67+
return m_images;
68+
}
69+
6070
inline int getWidth()
6171
{
6272
return m_width;

Projects/Skylicht/Engine/Source/Serializable/CArraySerializable.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,9 +106,14 @@ namespace Skylicht
106106
return NULL;
107107
}
108108

109+
char name[32];
110+
sprintf(name, "[%d]", (int)m_value.size());
111+
109112
addProperty(element);
110113
autoRelease(element);
111114

115+
element->Name = name;
116+
112117
if (OnCreateElement != nullptr)
113118
{
114119
OnCreateElement(element);

Projects/Skylicht/Engine/Source/Serializable/CSerializableLoader.cpp

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,28 @@ namespace Skylicht
4545
if (object->getNumProperty() > 0)
4646
object->deserialize(attr); // for SerializableActivator
4747
else
48-
initProperty(object, attr);
48+
{
49+
if (object->isArray())
50+
{
51+
CArraySerializable* arrayObject = dynamic_cast<CArraySerializable*>(object);
52+
if (arrayObject->haveCreateElementFunction())
53+
{
54+
// create element and deserialize
55+
int numElement = attr->getAttributeCount();
56+
arrayObject->resize(numElement);
57+
arrayObject->deserialize(attr);
58+
}
59+
else
60+
{
61+
// this is array but no create element function
62+
initProperty(object, attr);
63+
}
64+
}
65+
else
66+
{
67+
initProperty(object, attr);
68+
}
69+
}
4970
}
5071
else
5172
{

0 commit comments

Comments
 (0)