1 | #include "BsApplication.h" |
2 | #include "BsEngineConfig.h" |
3 | #include "Resources/BsResources.h" |
4 | #include "Resources/BsBuiltinResources.h" |
5 | #include "BsBuiltinResourcesHelper.h" |
6 | #include "FileSystem/BsFileSystem.h" |
7 | #include "FileSystem/BsPath.h" |
8 | #include "FileSystem/BsDataStream.h" |
9 | #include "Resources/BsResourceManifest.h" |
10 | #include "ThirdParty/json.hpp" |
11 | #include "Utility/BsShapeMeshes3D.h" |
12 | #include "Mesh/BsMesh.h" |
13 | #include "Renderer/BsRendererMeshData.h" |
14 | #include "Image/BsTexture.h" |
15 | #include "RenderAPI/BsVertexDataDesc.h" |
16 | #include "Serialization/BsFileSerializer.h" |
17 | #include "Importer/BsImporter.h" |
18 | #include "Importer/BsTextureImportOptions.h" |
19 | |
20 | namespace bs |
21 | { |
22 | static constexpr const char* TIMESTAMP_NAME = u8"Timestamp.asset" ; |
23 | static constexpr const char* MANIFEST_NAME = u8"ResourceManifest.asset" ; |
24 | static constexpr const char* DEPENDENCIES_JSON_NAME = u8"ShaderDependencies.json" ; |
25 | static constexpr const char* DATA_LIST_JSON = u8"DataList.json" ; |
26 | static constexpr const char* GUI_SKIN_JSON = u8"GUISkin.json" ; |
27 | |
28 | static Path sInputFolder; |
29 | static Path sOutputFolder; |
30 | static Path sManifestPath; |
31 | static SPtr<ResourceManifest> sManifest; |
32 | |
33 | void processAssets(bool, bool, time_t); |
34 | } |
35 | |
36 | int main(int argc, char * argv[]) |
37 | { |
38 | using namespace bs; |
39 | |
40 | if(argc < 3) |
41 | return 2; |
42 | |
43 | START_UP_DESC desc; |
44 | desc.renderAPI = BS_RENDER_API_MODULE; |
45 | desc.renderer = BS_RENDERER_MODULE; |
46 | desc.audio = BS_AUDIO_MODULE; |
47 | desc.physics = BS_PHYSICS_MODULE; |
48 | |
49 | desc.importers.push_back("bsfFreeImgImporter" ); |
50 | desc.importers.push_back("bsfFBXImporter" ); |
51 | desc.importers.push_back("bsfFontImporter" ); |
52 | desc.importers.push_back("bsfSL" ); |
53 | |
54 | desc.primaryWindowDesc.videoMode = VideoMode (64, 64); |
55 | desc.primaryWindowDesc.fullscreen = false; |
56 | desc.primaryWindowDesc.title = "bsf importer" ; |
57 | desc.primaryWindowDesc.hidden = true; |
58 | |
59 | Application::startUp(desc); |
60 | |
61 | sInputFolder = argv[1]; |
62 | sOutputFolder = argv[2]; |
63 | sManifestPath = sOutputFolder + MANIFEST_NAME; |
64 | |
65 | bool generateGenerated = true; |
66 | bool forceImport = false; |
67 | for(int i = 3; i < argc; i++) |
68 | { |
69 | if(strcmp(argv[i], "--editor" ) == 0) |
70 | generateGenerated = false; |
71 | else if(strcmp(argv[i], "--force" ) == 0) |
72 | forceImport = true; |
73 | } |
74 | |
75 | if (FileSystem::exists(sInputFolder)) |
76 | { |
77 | time_t lastUpdateTime; |
78 | UINT32 modifications = BuiltinResourcesHelper::checkForModifications( |
79 | sInputFolder, |
80 | sOutputFolder + TIMESTAMP_NAME, |
81 | lastUpdateTime); |
82 | |
83 | if(forceImport) |
84 | modifications = 2; |
85 | |
86 | // Check if manifest needs to be rebuilt |
87 | if (modifications == 0 && !FileSystem::exists(sManifestPath)) |
88 | modifications = 1; |
89 | |
90 | if (modifications > 0) |
91 | { |
92 | const bool fullReimport = modifications == 2; |
93 | |
94 | sManifest = ResourceManifest::create("BuiltinResources" ); |
95 | gResources().registerResourceManifest(sManifest); |
96 | |
97 | processAssets(generateGenerated, fullReimport, lastUpdateTime); |
98 | BuiltinResourcesHelper::writeTimestamp(sOutputFolder + TIMESTAMP_NAME); |
99 | |
100 | ResourceManifest::save(sManifest, sManifestPath, sOutputFolder); |
101 | |
102 | Application::shutDown(); |
103 | return 1; |
104 | } |
105 | } |
106 | |
107 | Application::shutDown(); |
108 | return 0; |
109 | } |
110 | |
111 | namespace bs |
112 | { |
113 | void generateTextures() |
114 | { |
115 | SPtr<PixelData> blackPixelData = PixelData::create(2, 2, 1, PF_RGBA8); |
116 | blackPixelData->setColorAt(Color::Black, 0, 0); |
117 | blackPixelData->setColorAt(Color::Black, 0, 1); |
118 | blackPixelData->setColorAt(Color::Black, 1, 0); |
119 | blackPixelData->setColorAt(Color::Black, 1, 1); |
120 | |
121 | SPtr<Texture> blackTexture = Texture::_createPtr(blackPixelData); |
122 | |
123 | SPtr<PixelData> whitePixelData = PixelData::create(2, 2, 1, PF_RGBA8); |
124 | whitePixelData->setColorAt(Color::White, 0, 0); |
125 | whitePixelData->setColorAt(Color::White, 0, 1); |
126 | whitePixelData->setColorAt(Color::White, 1, 0); |
127 | whitePixelData->setColorAt(Color::White, 1, 1); |
128 | |
129 | SPtr<Texture> whiteTexture = Texture::_createPtr(whitePixelData); |
130 | |
131 | SPtr<PixelData> normalPixelData = PixelData::create(2, 2, 1, PF_RGBA8); |
132 | |
133 | Color encodedNormal(0.5f, 0.5f, 1.0f); |
134 | normalPixelData->setColorAt(encodedNormal, 0, 0); |
135 | normalPixelData->setColorAt(encodedNormal, 0, 1); |
136 | normalPixelData->setColorAt(encodedNormal, 1, 0); |
137 | normalPixelData->setColorAt(encodedNormal, 1, 1); |
138 | |
139 | SPtr<Texture> normalTexture = Texture::_createPtr(normalPixelData); |
140 | |
141 | // Save all textures |
142 | Path outputDir = sOutputFolder + BuiltinResources::TEXTURE_FOLDER; |
143 | |
144 | auto saveTexture = [&](const Path& path, const SPtr<Texture>& texture, const String& uuid) |
145 | { |
146 | HResource textureResource = gResources()._createResourceHandle(texture, UUID(uuid)); |
147 | |
148 | gResources().save(textureResource, path, true); |
149 | sManifest->registerResource(textureResource.getUUID(), path); |
150 | }; |
151 | |
152 | Path whitePath = outputDir + BuiltinResources::TEXTURE_WHITE_FILE; |
153 | saveTexture(whitePath, whiteTexture, "1f7d0e3f-d81b-42ee-9d31-cb6c6fc55824" ); |
154 | |
155 | Path blackPath = outputDir + BuiltinResources::TEXTURE_BLACK_FILE; |
156 | saveTexture(blackPath, blackTexture, "149a5c05-9570-4915-9dbd-69acf88b865b" ); |
157 | |
158 | Path normalPath = outputDir + BuiltinResources::TEXTURE_NORMAL_FILE; |
159 | saveTexture(normalPath, normalTexture, "afb29163-1ef0-4440-9cfb-c1ebb3b3d452" ); |
160 | } |
161 | |
162 | void generateMeshes() |
163 | { |
164 | SPtr<VertexDataDesc> vertexDesc = bs_shared_ptr_new<VertexDataDesc>(); |
165 | vertexDesc->addVertElem(VET_FLOAT3, VES_POSITION); |
166 | vertexDesc->addVertElem(VET_FLOAT2, VES_TEXCOORD); |
167 | vertexDesc->addVertElem(VET_FLOAT3, VES_NORMAL); |
168 | vertexDesc->addVertElem(VET_FLOAT4, VES_TANGENT); |
169 | vertexDesc->addVertElem(VET_COLOR, VES_COLOR); |
170 | |
171 | UINT32 boxNumVertices = 0; |
172 | UINT32 boxNumIndices = 0; |
173 | ShapeMeshes3D::getNumElementsAABox(boxNumVertices, boxNumIndices); |
174 | SPtr<MeshData> boxMeshData = MeshData::create(boxNumVertices, boxNumIndices, vertexDesc); |
175 | AABox box(Vector3(-0.5f, -0.5f, -0.5f), Vector3(0.5f, 0.5f, 0.5f)); |
176 | |
177 | ShapeMeshes3D::solidAABox(box, boxMeshData, 0, 0); |
178 | SPtr<Mesh> boxMesh = Mesh::_createPtr(RendererMeshData::convert(boxMeshData)); |
179 | |
180 | UINT32 sphereNumVertices = 0; |
181 | UINT32 sphereNumIndices = 0; |
182 | ShapeMeshes3D::getNumElementsSphere(3, sphereNumVertices, sphereNumIndices); |
183 | SPtr<MeshData> sphereMeshData = bs_shared_ptr_new<MeshData>(sphereNumVertices, sphereNumIndices, vertexDesc); |
184 | |
185 | ShapeMeshes3D::solidSphere(Sphere(Vector3::ZERO, 1.0f), sphereMeshData, 0, 0, 3); |
186 | SPtr<Mesh> sphereMesh = Mesh::_createPtr(RendererMeshData::convert(sphereMeshData)); |
187 | |
188 | UINT32 coneNumVertices = 0; |
189 | UINT32 coneNumIndices = 0; |
190 | ShapeMeshes3D::getNumElementsCone(10, coneNumVertices, coneNumIndices); |
191 | SPtr<MeshData> coneMeshData = bs_shared_ptr_new<MeshData>(coneNumVertices, coneNumIndices, vertexDesc); |
192 | |
193 | ShapeMeshes3D::solidCone(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, coneMeshData, 0, 0); |
194 | SPtr<Mesh> coneMesh = Mesh::_createPtr(RendererMeshData::convert(coneMeshData)); |
195 | |
196 | UINT32 cylinderNumVertices = 0; |
197 | UINT32 cylinderNumIndices = 0; |
198 | ShapeMeshes3D::getNumElementsCylinder(10, cylinderNumVertices, cylinderNumIndices); |
199 | SPtr<MeshData> cylinderMeshData = bs_shared_ptr_new<MeshData>(cylinderNumVertices, cylinderNumIndices, vertexDesc); |
200 | |
201 | ShapeMeshes3D::solidCylinder(Vector3::ZERO, Vector3::UNIT_Y, 1.0f, 1.0f, Vector2::ONE, cylinderMeshData, 0, 0); |
202 | SPtr<Mesh> cylinderMesh = Mesh::_createPtr(RendererMeshData::convert(cylinderMeshData)); |
203 | |
204 | UINT32 quadNumVertices = 8; |
205 | UINT32 quadNumIndices = 12; |
206 | ShapeMeshes3D::getNumElementsQuad(quadNumVertices, quadNumIndices); |
207 | SPtr<MeshData> quadMeshData = bs_shared_ptr_new<MeshData>(quadNumVertices, quadNumIndices, vertexDesc); |
208 | |
209 | std::array<Vector3, 2> axes = {{ Vector3::UNIT_X, Vector3::UNIT_Z }}; |
210 | std::array<float, 2> sizes = {{ 1.0f, 1.0f }}; |
211 | Rect3 rect(Vector3::ZERO, axes, sizes); |
212 | ShapeMeshes3D::solidQuad(rect, quadMeshData, 0, 0); |
213 | SPtr<Mesh> quadMesh = Mesh::_createPtr(RendererMeshData::convert(quadMeshData)); |
214 | |
215 | UINT32 discNumVertices = 0; |
216 | UINT32 discNumIndices = 0; |
217 | ShapeMeshes3D::getNumElementsDisc(10, discNumVertices, discNumIndices); |
218 | SPtr<MeshData> discMeshData = bs_shared_ptr_new<MeshData>(discNumVertices, discNumIndices, vertexDesc); |
219 | |
220 | ShapeMeshes3D::solidDisc(Vector3::ZERO, 1.0f, Vector3::UNIT_Y, discMeshData, 0, 0); |
221 | SPtr<Mesh> discMesh = Mesh::_createPtr(RendererMeshData::convert(discMeshData)); |
222 | |
223 | // Save all meshes |
224 | const Path outputDir = sOutputFolder + BuiltinResources::MESH_FOLDER; |
225 | |
226 | auto saveMesh = [&](const Path& path, const SPtr<Mesh>& mesh, const String& uuid) |
227 | { |
228 | HResource meshResource = gResources()._createResourceHandle(mesh, UUID(uuid)); |
229 | |
230 | gResources().save(meshResource, path, true); |
231 | sManifest->registerResource(meshResource.getUUID(), path); |
232 | }; |
233 | |
234 | Path boxPath = outputDir + BuiltinResources::MESH_BOX_FILE; |
235 | saveMesh(boxPath, boxMesh, "bc1d20ca-7fe6-489b-8b5c-dbf798badc95" ); |
236 | |
237 | Path spherePath = outputDir + BuiltinResources::MESH_SPHERE_FILE; |
238 | saveMesh(spherePath, sphereMesh, "040642f3-04d6-419e-9dba-f7824161c205" ); |
239 | |
240 | Path conePath = outputDir + BuiltinResources::MESH_CONE_FILE; |
241 | saveMesh(conePath, coneMesh, "b8cf6db5-1736-47ac-852f-82ecd88b4d46" ); |
242 | |
243 | Path cylinderPath = outputDir + BuiltinResources::MESH_CYLINDER_FILE; |
244 | saveMesh(cylinderPath, cylinderMesh, "e6b2b797-4e72-7e49-61ba-4e7275bd561d" ); |
245 | |
246 | Path quadPath = outputDir + BuiltinResources::MESH_QUAD_FILE; |
247 | saveMesh(quadPath, quadMesh, "06592bf3-f82a-472e-a034-26a98225fbe1" ); |
248 | |
249 | Path discPath = outputDir + BuiltinResources::MESH_DISC_FILE; |
250 | saveMesh(discPath, discMesh, "6f496313-344a-495c-83e8-152e3053c52d" ); |
251 | } |
252 | |
253 | SPtr<GUISkin> generateGUISkin() |
254 | { |
255 | using nlohmann::json; |
256 | |
257 | const Path skinFolder = sOutputFolder + BuiltinResources::SKIN_FOLDER + BuiltinResources::SPRITE_FOLDER; |
258 | BuiltinResourceGUIElementStyleLoader loader(sOutputFolder, skinFolder); |
259 | |
260 | Path guiSkinPath = sInputFolder + GUI_SKIN_JSON; |
261 | SPtr<DataStream> guiSkinStream = FileSystem::openFile(guiSkinPath); |
262 | json guiSkinJSON = json::parse(guiSkinStream->getAsString().c_str()); |
263 | |
264 | SPtr<GUISkin> skin = GUISkin::_createPtr(); |
265 | |
266 | for(auto& entry : guiSkinJSON) |
267 | { |
268 | std::string name = entry["name" ]; |
269 | |
270 | GUIElementStyle style = BuiltinResourcesHelper::loadGUIStyleFromJSON(entry, loader); |
271 | skin->setStyle(name.c_str(), style); |
272 | } |
273 | |
274 | return skin; |
275 | } |
276 | |
277 | void processAssets(bool generateGenerated, bool forceImport, time_t lastUpdateTime) |
278 | { |
279 | using nlohmann::json; |
280 | |
281 | // Hidden dependency: Textures need to be generated before shaders as they may use the default textures |
282 | if(generateGenerated) |
283 | { |
284 | generateTextures(); |
285 | generateMeshes(); |
286 | } |
287 | |
288 | const Path dataListsFilePath = sInputFolder + DATA_LIST_JSON; |
289 | SPtr<DataStream> dataListStream = FileSystem::openFile(dataListsFilePath); |
290 | json dataListJSON = json::parse(dataListStream->getAsString().c_str()); |
291 | |
292 | json skinJSON = dataListJSON["Skin" ]; |
293 | json animatedSpritesJSON = dataListJSON["AnimatedSprites" ]; |
294 | json cursorsJSON = dataListJSON["Cursors" ]; |
295 | json iconsJSON = dataListJSON["Icons" ]; |
296 | json spriteIconsJSON = dataListJSON["SpriteIcons" ]; |
297 | json spriteIcons3DJSON = dataListJSON["SpriteIcons3D" ]; |
298 | json includesJSON = dataListJSON["Includes" ]; |
299 | json shadersJSON = dataListJSON["Shaders" ]; |
300 | json fontsJSON = dataListJSON["Fonts" ]; |
301 | json guiSkinJSON = dataListJSON["GUISkin" ]; |
302 | json splashScreenJSON = dataListJSON["SplashScreen" ]; |
303 | |
304 | const Path rawSkinFolder = sInputFolder + BuiltinResources::SKIN_FOLDER; |
305 | const Path rawAnimatedSpritesFolder = sInputFolder + BuiltinResources::ANIMATED_SPRITES_FOLDER; |
306 | const Path rawCursorFolder = sInputFolder + BuiltinResources::CURSOR_FOLDER; |
307 | const Path rawIconFolder = sInputFolder + BuiltinResources::ICON_FOLDER; |
308 | const Path rawIcon3DFolder = sInputFolder + BuiltinResources::ICON3D_FOLDER; |
309 | const Path rawShaderFolder = sInputFolder + BuiltinResources::SHADER_FOLDER; |
310 | const Path rawShaderIncludeFolder = sInputFolder + BuiltinResources::SHADER_INCLUDE_FOLDER; |
311 | |
312 | // Update DataList.json if needed |
313 | bool updatedDataLists = false; |
314 | |
315 | if(!cursorsJSON.is_null()) |
316 | { |
317 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
318 | rawCursorFolder, |
319 | BuiltinResourcesHelper::AssetType::Normal, |
320 | cursorsJSON); |
321 | } |
322 | |
323 | if(!iconsJSON.is_null()) |
324 | { |
325 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
326 | rawIconFolder, |
327 | BuiltinResourcesHelper::AssetType::Normal, |
328 | iconsJSON); |
329 | } |
330 | |
331 | if(!spriteIconsJSON.is_null()) |
332 | { |
333 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
334 | rawIconFolder, |
335 | BuiltinResourcesHelper::AssetType::Sprite, |
336 | spriteIconsJSON); |
337 | } |
338 | |
339 | if(!spriteIcons3DJSON.is_null()) |
340 | { |
341 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
342 | rawIcon3DFolder, |
343 | BuiltinResourcesHelper::AssetType::Sprite, |
344 | spriteIcons3DJSON); |
345 | } |
346 | |
347 | if(!includesJSON.is_null()) |
348 | { |
349 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
350 | rawShaderIncludeFolder, |
351 | BuiltinResourcesHelper::AssetType::Normal, |
352 | includesJSON); |
353 | } |
354 | |
355 | if(!shadersJSON.is_null()) |
356 | { |
357 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
358 | rawShaderFolder, |
359 | BuiltinResourcesHelper::AssetType::Normal, |
360 | shadersJSON); |
361 | } |
362 | |
363 | if(!skinJSON.is_null()) |
364 | { |
365 | updatedDataLists |= BuiltinResourcesHelper::updateJSON( |
366 | rawSkinFolder, |
367 | BuiltinResourcesHelper::AssetType::Sprite, |
368 | skinJSON); |
369 | } |
370 | |
371 | dataListStream->close(); |
372 | |
373 | if(updatedDataLists) |
374 | { |
375 | FileSystem::remove(dataListsFilePath); |
376 | |
377 | if(!skinJSON.is_null()) |
378 | dataListJSON["Skin" ] = skinJSON; |
379 | |
380 | if(!animatedSpritesJSON.is_null()) |
381 | dataListJSON["AnimatedSprites" ] = animatedSpritesJSON; |
382 | |
383 | if(!cursorsJSON.is_null()) |
384 | dataListJSON["Cursors" ] = cursorsJSON; |
385 | |
386 | if(!iconsJSON.is_null()) |
387 | dataListJSON["Icons" ] = iconsJSON; |
388 | |
389 | if(!spriteIconsJSON.is_null()) |
390 | dataListJSON["SpriteIcons" ] = spriteIconsJSON; |
391 | |
392 | if(!spriteIcons3DJSON.is_null()) |
393 | dataListJSON["SpriteIcons3D" ] = spriteIcons3DJSON; |
394 | |
395 | if(!includesJSON.is_null()) |
396 | dataListJSON["Includes" ] = includesJSON; |
397 | |
398 | if(!shadersJSON.is_null()) |
399 | dataListJSON["Shaders" ] = shadersJSON; |
400 | |
401 | if(!fontsJSON.is_null()) |
402 | dataListJSON["Fonts" ] = fontsJSON; |
403 | |
404 | if(!guiSkinJSON.is_null()) |
405 | dataListJSON["GUISkin" ] = guiSkinJSON; |
406 | |
407 | if(!splashScreenJSON.is_null()) |
408 | dataListJSON["SplashScreen" ] = splashScreenJSON; |
409 | |
410 | String jsonString = dataListJSON.dump(4).c_str(); |
411 | dataListStream = FileSystem::createAndOpenFile(dataListsFilePath); |
412 | dataListStream->writeString(jsonString); |
413 | dataListStream->close(); |
414 | } |
415 | |
416 | const Path skinFolder = sOutputFolder + BuiltinResources::SKIN_FOLDER; |
417 | const Path animatedSpriteFolder = sOutputFolder + BuiltinResources::ANIMATED_SPRITES_FOLDER; |
418 | const Path cursorFolder = sOutputFolder + BuiltinResources::CURSOR_FOLDER; |
419 | const Path iconFolder = sOutputFolder + BuiltinResources::ICON_FOLDER; |
420 | const Path icon3DFolder = sOutputFolder + BuiltinResources::ICON3D_FOLDER; |
421 | const Path shaderFolder = sOutputFolder + BuiltinResources::SHADER_FOLDER; |
422 | const Path shaderIncludeFolder = sOutputFolder + BuiltinResources::SHADER_INCLUDE_FOLDER; |
423 | const Path shaderDependenciesFile = sInputFolder + DEPENDENCIES_JSON_NAME; |
424 | |
425 | // If forcing import, clear all data folders since everything will be recreated anyway |
426 | if(forceImport) |
427 | { |
428 | if(FileSystem::exists(cursorFolder)) |
429 | FileSystem::remove(cursorFolder); |
430 | |
431 | if(FileSystem::exists(iconFolder)) |
432 | FileSystem::remove(iconFolder); |
433 | |
434 | if(FileSystem::exists(icon3DFolder)) |
435 | FileSystem::remove(icon3DFolder); |
436 | |
437 | if(FileSystem::exists(shaderIncludeFolder)) |
438 | FileSystem::remove(shaderIncludeFolder); |
439 | |
440 | if(FileSystem::exists(shaderFolder)) |
441 | FileSystem::remove(shaderFolder); |
442 | |
443 | if(FileSystem::exists(skinFolder)) |
444 | FileSystem::remove(skinFolder); |
445 | |
446 | if(FileSystem::exists(animatedSpriteFolder)) |
447 | FileSystem::remove(animatedSpriteFolder); |
448 | |
449 | FileSystem::remove(shaderDependenciesFile); |
450 | } |
451 | |
452 | // Read shader dependencies JSON |
453 | json shaderDependenciesJSON; |
454 | if(FileSystem::exists(shaderDependenciesFile)) |
455 | { |
456 | SPtr<DataStream> stream = FileSystem::openFile(shaderDependenciesFile); |
457 | shaderDependenciesJSON = json::parse(stream->getAsString().c_str()); |
458 | stream->close(); |
459 | } |
460 | |
461 | // Import cursors |
462 | if(!cursorsJSON.is_null()) |
463 | { |
464 | BuiltinResourcesHelper::updateManifest( |
465 | cursorFolder, |
466 | cursorsJSON, |
467 | sManifest, |
468 | BuiltinResourcesHelper::AssetType::Normal); |
469 | |
470 | Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( |
471 | cursorsJSON, |
472 | rawCursorFolder, |
473 | lastUpdateTime, |
474 | forceImport); |
475 | |
476 | BuiltinResourcesHelper::importAssets( |
477 | cursorsJSON, |
478 | importFlags, |
479 | rawCursorFolder, |
480 | cursorFolder, |
481 | sManifest, |
482 | BuiltinResourcesHelper::AssetType::Normal); |
483 | } |
484 | |
485 | // Import icons |
486 | if(!iconsJSON.is_null()) |
487 | { |
488 | BuiltinResourcesHelper::updateManifest( |
489 | iconFolder, |
490 | iconsJSON, |
491 | sManifest, |
492 | BuiltinResourcesHelper::AssetType::Normal); |
493 | |
494 | Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( |
495 | iconsJSON, |
496 | rawIconFolder, |
497 | lastUpdateTime, |
498 | forceImport); |
499 | |
500 | BuiltinResourcesHelper::importAssets( |
501 | iconsJSON, |
502 | importFlags, |
503 | rawIconFolder, |
504 | iconFolder, |
505 | sManifest, |
506 | BuiltinResourcesHelper::AssetType::Normal); |
507 | } |
508 | |
509 | // Import sprite icons |
510 | if(!spriteIconsJSON.is_null()) |
511 | { |
512 | BuiltinResourcesHelper::updateManifest( |
513 | iconFolder, |
514 | spriteIconsJSON, |
515 | sManifest, |
516 | BuiltinResourcesHelper::AssetType::Sprite); |
517 | |
518 | Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( |
519 | spriteIconsJSON, |
520 | rawIconFolder, |
521 | lastUpdateTime, |
522 | forceImport); |
523 | |
524 | BuiltinResourcesHelper::importAssets( |
525 | spriteIconsJSON, |
526 | importFlags, |
527 | rawIconFolder, |
528 | iconFolder, |
529 | sManifest, |
530 | BuiltinResourcesHelper::AssetType::Sprite); |
531 | } |
532 | |
533 | // Import 3D sprite icons |
534 | if(!spriteIcons3DJSON.is_null()) |
535 | { |
536 | BuiltinResourcesHelper::updateManifest( |
537 | icon3DFolder, |
538 | spriteIcons3DJSON, |
539 | sManifest, |
540 | BuiltinResourcesHelper::AssetType::Sprite); |
541 | |
542 | Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( |
543 | spriteIcons3DJSON, |
544 | rawIcon3DFolder, |
545 | lastUpdateTime, |
546 | forceImport); |
547 | |
548 | BuiltinResourcesHelper::importAssets( |
549 | spriteIcons3DJSON, |
550 | importFlags, |
551 | rawIcon3DFolder, |
552 | icon3DFolder, |
553 | sManifest, |
554 | BuiltinResourcesHelper::AssetType::Sprite, |
555 | nullptr, false, true); |
556 | } |
557 | |
558 | // Import shaders |
559 | if(!shadersJSON.is_null() && !includesJSON.is_null()) |
560 | { |
561 | BuiltinResourcesHelper::updateManifest( |
562 | shaderIncludeFolder, |
563 | includesJSON, |
564 | sManifest, |
565 | BuiltinResourcesHelper::AssetType::Normal); |
566 | |
567 | BuiltinResourcesHelper::updateManifest( |
568 | shaderFolder, |
569 | shadersJSON, |
570 | sManifest, |
571 | BuiltinResourcesHelper::AssetType::Normal); |
572 | |
573 | Vector<bool> includeImportFlags = BuiltinResourcesHelper::generateImportFlags( |
574 | includesJSON, |
575 | rawShaderIncludeFolder, |
576 | lastUpdateTime, |
577 | forceImport); |
578 | |
579 | Vector<bool> shaderImportFlags = BuiltinResourcesHelper::generateImportFlags( |
580 | shadersJSON, |
581 | rawShaderFolder, |
582 | lastUpdateTime, |
583 | forceImport, |
584 | &shaderDependenciesJSON, |
585 | rawShaderIncludeFolder); |
586 | |
587 | // Hidden dependency: Includes must be imported before shaders, but import flags for shaders must be generated |
588 | // before includes are imported, since the process checks if imports changed |
589 | BuiltinResourcesHelper::importAssets( |
590 | includesJSON, |
591 | includeImportFlags, |
592 | rawShaderIncludeFolder, |
593 | shaderIncludeFolder, |
594 | sManifest, |
595 | BuiltinResourcesHelper::AssetType::Normal, |
596 | nullptr, |
597 | true); |
598 | |
599 | |
600 | BuiltinResourcesHelper::importAssets( |
601 | shadersJSON, |
602 | shaderImportFlags, |
603 | rawShaderFolder, |
604 | shaderFolder, |
605 | sManifest, |
606 | BuiltinResourcesHelper::AssetType::Normal, |
607 | &shaderDependenciesJSON, |
608 | true); |
609 | } |
610 | |
611 | // Import GUI sprites |
612 | if(!skinJSON.is_null()) |
613 | { |
614 | BuiltinResourcesHelper::updateManifest( |
615 | skinFolder, |
616 | skinJSON, |
617 | sManifest, |
618 | BuiltinResourcesHelper::AssetType::Sprite); |
619 | |
620 | Vector<bool> skinImportFlags = BuiltinResourcesHelper::generateImportFlags( |
621 | skinJSON, |
622 | rawSkinFolder, |
623 | lastUpdateTime, |
624 | forceImport); |
625 | |
626 | BuiltinResourcesHelper::importAssets( |
627 | skinJSON, |
628 | skinImportFlags, |
629 | rawSkinFolder, |
630 | skinFolder, |
631 | sManifest, |
632 | BuiltinResourcesHelper::AssetType::Sprite); |
633 | } |
634 | |
635 | // Import animated sprites |
636 | if(!animatedSpritesJSON.is_null()) |
637 | { |
638 | BuiltinResourcesHelper::updateManifest( |
639 | animatedSpriteFolder, |
640 | animatedSpritesJSON, |
641 | sManifest, |
642 | BuiltinResourcesHelper::AssetType::Sprite); |
643 | |
644 | Vector<bool> importFlags = BuiltinResourcesHelper::generateImportFlags( |
645 | animatedSpritesJSON, |
646 | rawAnimatedSpritesFolder, |
647 | lastUpdateTime, |
648 | forceImport); |
649 | |
650 | BuiltinResourcesHelper::importAssets( |
651 | animatedSpritesJSON, |
652 | importFlags, |
653 | rawAnimatedSpritesFolder, |
654 | animatedSpriteFolder, |
655 | sManifest, |
656 | BuiltinResourcesHelper::AssetType::Sprite); |
657 | } |
658 | |
659 | // Update shader dependencies JSON |
660 | { |
661 | String jsonString = shaderDependenciesJSON.dump(4).c_str(); |
662 | |
663 | dataListStream = FileSystem::createAndOpenFile(shaderDependenciesFile); |
664 | dataListStream->writeString(jsonString); |
665 | dataListStream->close(); |
666 | } |
667 | |
668 | // Import fonts |
669 | if(!fontsJSON.is_null()) |
670 | { |
671 | for (auto& entry : fontsJSON) |
672 | { |
673 | std::string path = entry["Path" ]; |
674 | std::string name = entry["Name" ]; |
675 | std::string uuidStr = entry["UUID" ]; |
676 | const bool antialiasing = entry["Antialiasing" ]; |
677 | |
678 | json fontSizesJSON = entry["Sizes" ]; |
679 | Vector<UINT32> fontSizes; |
680 | for (auto& sizeEntry : fontSizesJSON) |
681 | fontSizes.push_back(sizeEntry); |
682 | |
683 | String inputName(path.data(), path.size()); |
684 | String outputName(name.data(), name.size()); |
685 | UUID UUID(String(uuidStr.data(), uuidStr.size())); |
686 | |
687 | const Path fontSourcePath = sInputFolder + inputName; |
688 | |
689 | BuiltinResourcesHelper::importFont(fontSourcePath, outputName, sOutputFolder, fontSizes, antialiasing, UUID, |
690 | sManifest); |
691 | } |
692 | } |
693 | |
694 | // Generate & save GUI skin |
695 | if(!guiSkinJSON.is_null()) |
696 | { |
697 | std::string name = guiSkinJSON["Path" ]; |
698 | std::string uuidStr = guiSkinJSON["UUID" ]; |
699 | |
700 | String fileName(name.data(), name.size()); |
701 | UUID UUID(String(uuidStr.data(), uuidStr.size())); |
702 | |
703 | const SPtr<GUISkin> skin = generateGUISkin(); |
704 | const Path outputPath = sOutputFolder + (fileName + u8".asset" ); |
705 | |
706 | HResource skinResource = gResources()._createResourceHandle(skin, UUID); |
707 | |
708 | gResources().save(skinResource, outputPath, true); |
709 | sManifest->registerResource(skinResource.getUUID(), outputPath); |
710 | } |
711 | |
712 | // Generate & save splash screen |
713 | if(!splashScreenJSON.is_null()) |
714 | { |
715 | std::string name = splashScreenJSON["Path" ]; |
716 | String fileName(name.data(), name.size()); |
717 | |
718 | Path inputPath = sInputFolder + fileName; |
719 | Path outputPath = sOutputFolder + (fileName + ".asset" ); |
720 | |
721 | auto textureIO = gImporter().createImportOptions<TextureImportOptions>(inputPath); |
722 | textureIO->cpuCached = true; |
723 | textureIO->generateMips = false; |
724 | HTexture splashTexture = gImporter().import<Texture>(inputPath, textureIO); |
725 | |
726 | SPtr<PixelData> splashPixelData = splashTexture->getProperties().allocBuffer(0, 0); |
727 | splashTexture->readCachedData(*splashPixelData); |
728 | |
729 | FileEncoder fe(outputPath); |
730 | fe.encode(splashPixelData.get()); |
731 | } |
732 | } |
733 | } |