@@ -170,6 +170,10 @@ namespace nexo::editor {
170170 const assets::AssetLocation model (modelPath);
171171 const auto modelAssetRef = catalog.getAsset (model).as <assets::Model>();
172172 const ecs::Entity entity = EntityFactory3D::createModel (modelAssetRef, position, scale, rotation);
173+ if (entity == ecs::INVALID_ENTITY) {
174+ LOG (NEXO_WARN, " Failed to load model '{}', skipping" , modelPath);
175+ return ;
176+ }
173177
174178 scene.addEntity (entity);
175179 }
@@ -197,11 +201,19 @@ namespace nexo::editor {
197201 scene::Scene& scene = app.getSceneManager ().getScene (m_sceneId);
198202 const auto & catalog = nexo::assets::AssetCatalog::getInstance ();
199203
200- const assets::AssetLocation fullRoomModel (" my_package::full_room@Demo" );
201- const auto fullRoomAssetRef = catalog.getAsset (fullRoomModel).as <assets::Model>();
202- const auto fullRoom = EntityFactory3D::createModel (
203- fullRoomAssetRef, {0.0 + offset.x , 0.0 + offset.y , 0.0 + offset.z }, {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
204- scene.addEntity (fullRoom);
204+ auto addModel = [&](const std::string& assetPath, const glm::vec3& pos, const glm::vec3& scale,
205+ const glm::vec3& rotation = {0 .0f , 0 .0f , 0 .0f }) {
206+ const auto ref = catalog.getAsset (assets::AssetLocation (assetPath)).as <assets::Model>();
207+ const auto e = EntityFactory3D::createModel (ref, pos, scale, rotation);
208+ if (e == ecs::INVALID_ENTITY) {
209+ LOG (NEXO_WARN, " Failed to load model '{}', skipping" , assetPath);
210+ return ;
211+ }
212+ scene.addEntity (e);
213+ };
214+
215+ addModel (" my_package::full_room@Demo" ,
216+ {0 .0f + offset.x , 0 .0f + offset.y , 0 .0f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
205217
206218 const auto backWall =
207219 EntityFactory3D::createCube ({10 .0f + offset.x , 7 .0f + offset.y , 0 .0f + offset.z }, {0 .5f , 14 .0f , 20 .0f },
@@ -262,40 +274,108 @@ namespace nexo::editor {
262274 scene.addEntity (garlandSpotLight);
263275 }
264276
265- const assets::AssetLocation corkBoardModel (" my_package::cork_board@Demo" );
266- const auto corkBoardAssetRef = catalog.getAsset (corkBoardModel).as <assets::Model>();
267- const auto corkBoard =
268- EntityFactory3D::createModel (corkBoardAssetRef, {9 .63f + offset.x , 5 .59f + offset.y , 0 .0f + offset.z },
269- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
270- scene.addEntity (corkBoard);
271-
272- const assets::AssetLocation frameModel (" my_package::frame@Demo" );
273- const auto frameAssetRef = catalog.getAsset (frameModel).as <assets::Model>();
274- const auto frame =
275- EntityFactory3D::createModel (frameAssetRef, {9 .7f + offset.x , 5 .69f + offset.y , 3 .96f + offset.z },
276- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
277- scene.addEntity (frame);
278-
279- const assets::AssetLocation duckModel (" my_package::duck@Demo" );
280- const auto duckAssetRef = catalog.getAsset (duckModel).as <assets::Model>();
281- const auto duck =
282- EntityFactory3D::createModel (duckAssetRef, {7 .09f + offset.x , 3 .88f + offset.y , -1 .07f + offset.z },
283- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
284- scene.addEntity (duck);
285-
286- const assets::AssetLocation laptopModel (" my_package::laptop@Demo" );
287- const auto laptopAssetRef = catalog.getAsset (laptopModel).as <assets::Model>();
288- const auto laptop =
289- EntityFactory3D::createModel (laptopAssetRef, {7 .05f + offset.x , 4 .0f + offset.y , 0 .0f + offset.z },
290- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
291- scene.addEntity (laptop);
292-
293- const assets::AssetLocation bretzelModel (" my_package::bretzel@Demo" );
294- const auto bretzelAssetRef = catalog.getAsset (bretzelModel).as <assets::Model>();
295- const auto bretzel =
296- EntityFactory3D::createModel (bretzelAssetRef, {7 .4f + offset.x , 4 .04f + offset.y , -2 .98f + offset.z },
297- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 0 .0f , 0 .0f });
298- scene.addEntity (bretzel);
277+ addModel (" my_package::cork_board@Demo" ,
278+ {9 .63f + offset.x , 5 .59f + offset.y , 0 .0f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
279+ addModel (" my_package::frame@Demo" ,
280+ {9 .7f + offset.x , 5 .69f + offset.y , 3 .96f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
281+ addModel (" my_package::duck@Demo" ,
282+ {7 .09f + offset.x , 3 .88f + offset.y , -1 .07f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
283+ addModel (" my_package::laptop@Demo" ,
284+ {7 .05f + offset.x , 4 .0f + offset.y , 0 .0f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
285+ addModel (" my_package::bretzel@Demo" ,
286+ {7 .4f + offset.x , 4 .04f + offset.y , -2 .98f + offset.z }, {1 .0f , 1 .0f , 1 .0f });
287+ }
288+
289+ void EditorScene::physicScene (const glm::vec3& offset) const
290+ {
291+ static std::random_device rd;
292+ static std::mt19937 gen (rd ());
293+ static std::uniform_real_distribution<float > dis (0 .0f , 1 .0f );
294+
295+ // Balls
296+ for (int i = 0 ; i < 50 ; ++i) {
297+ float x = -3 .0f + static_cast <float >(i % 5 ) * 1 .5f ;
298+ float z = static_cast <float >((i % 2 == 0 ) ? 1 : -1 ) * 0 .5f ;
299+ glm::vec3 pos = {x, 62 .0f + static_cast <float >(i), z};
300+ glm::vec4 color = {1 .0f , dis (gen), dis (gen), 1 .0f };
301+ createEntityWithPhysic (pos + offset, {0 .4f , 0 .4f , 0 .4f }, {0 , 0 , 0 }, color, system::ShapeType::Sphere,
302+ JPH::EMotionType::Dynamic);
303+ }
304+
305+ // Background
306+ createEntityWithPhysic ({0 .0f + offset.x , 40 .0f + offset.y , -2 .5f + offset.z }, {44 .0f , 80 .0f , 0 .5f }, {0 , 0 , 0 },
307+ {0 .91f , 0 .91f , 0 .91f , 1 .0f }, system::ShapeType::Box, JPH::EMotionType::Static);
308+
309+ // Funnel
310+ createEntityWithPhysic ({-6 .0f + offset.x , 70 .0f + offset.y , 0 .0f + offset.z }, {10 .0f , 0 .5f , 4 .0f },
311+ {0 , 0 , -45 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }, system::ShapeType::Box,
312+ JPH::EMotionType::Static);
313+ createEntityWithPhysic ({6 .0f + offset.x , 70 .0f + offset.y , 0 .0f + offset.z }, {10 .0f , 0 .5f , 4 .0f }, {0 , 0 , 45 .0f },
314+ {0 .0f , 0 .28f , 0 .47f , 1 .0f }, system::ShapeType::Box, JPH::EMotionType::Static);
315+
316+ // Stairs
317+ std::vector<std::tuple<glm::vec3, glm::vec3, glm::vec3, glm::vec4>> stairs = {
318+ {{3 .0f , 61 .5f , 0 .0f }, {5 .0f , 0 .5f , 4 .0f }, {0 , 0 , -15 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }},
319+ {{11 .0f , 58 .5f , 0 .0f }, {8 .0f , 0 .5f , 4 .0f }, {0 .0f , 0 .0f , 20 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }},
320+ {{3 .0f , 55 .5f , 0 .0f }, {5 .0f , 0 .5f , 4 .0f }, {0 .0f , 0 .0f , -15 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }},
321+ {{10 .0f , 52 .5f , 0 .0f }, {12 .0f , 0 .5f , 4 .0f }, {0 .0f , 0 .0f , 20 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }}};
322+ for (const auto & [pos, size, rotation, color] : stairs) {
323+ createEntityWithPhysic (pos + offset, size, rotation, color, system::ShapeType::Box,
324+ JPH::EMotionType::Static);
325+ }
326+
327+ // Tunnel
328+ std::vector<std::tuple<glm::vec3, glm::vec3, glm::vec3>> tunnels = {
329+ {{-6 .0f , 59 .0f , 0 .0f }, {3 .0f , 11 .0f , 4 .0f }, {0 , 0 , 0 }},
330+ {{-1 .0f , 58 .5f , 0 .0f }, {3 .0f , 8 .0f , 4 .0f }, {0 , 0 , 0 }},
331+ {{-5 .0f , 51 .0f , 0 .0f }, {9 .0f , 0 .5f , 4 .0f }, {0 , 0 , -25 .0f }}};
332+ for (const auto & [pos, size, rotation] : tunnels) {
333+ createEntityWithPhysic (pos + offset, size, rotation, {0 .0f , 0 .28f , 0 .47f , 1 .0f }, system::ShapeType::Box,
334+ JPH::EMotionType::Static);
335+ }
336+
337+ // Dominos
338+ createEntityWithPhysic ({-9 .0f + offset.x , 44 .0f + offset.y , 0 .0f + offset.z }, {20 .9f , 0 .5f , 4 .0f }, {0 , 0 , 0 .0f },
339+ {0 .0f , 0 .28f , 0 .47f , 1 .0f }, system::ShapeType::Box, JPH::EMotionType::Static);
340+ createEntityWithPhysic ({11 .15f + offset.x , 44 .0f + offset.y , 0 .0f + offset.z }, {15 .5f , 0 .5f , 4 .0f },
341+ {0 , 0 , 0 .0f }, {0 .0f , 0 .28f , 0 .47f , 1 .0f }, system::ShapeType::Box,
342+ JPH::EMotionType::Static);
343+
344+ for (int i = 0 ; i < 24 ; ++i) {
345+ if (i == 13 ) continue ;
346+ float x = -18 .4f + static_cast <float >(i) * 1 .6f ;
347+ glm::vec3 pos = {x, 45 .5f , 0 .0f };
348+ float gradientFactor = static_cast <float >(i) / 24 .0f ;
349+ glm::vec4 color =
350+ mix (glm::vec4 (0 .0f , 0 .77f , 0 .95f , 1 .0f ), glm::vec4 (0 .83f , 0 .14f , 0 .67f , 1 .0f ), gradientFactor);
351+ createEntityWithPhysic (pos + offset, {0 .25f , 3 .0f , 3 .0f }, {0 , 0 , 0 }, color, system::ShapeType::Box,
352+ JPH::EMotionType::Dynamic);
353+ }
354+
355+ // Spinner
356+ createEntityWithPhysic ({2 .5f + offset.x , 41 .0f + offset.y , 0 .0f + offset.z }, {0 .5f , 3 .0f , 4 .0f }, {0 , 0 , 0 },
357+ {0 .0f , 1 .0f , 0 .0f , 1 .0f }, system::ShapeType::Box, JPH::EMotionType::Static);
358+
359+ // Fakir
360+ constexpr int totalRows = 20 ;
361+ constexpr float startX = -14 .0f ;
362+
363+ for (int row = 0 ; row < totalRows; ++row) {
364+ constexpr int cols = 10 ;
365+ for (int col = 0 ; col < cols; ++col) {
366+ constexpr float startY = 14 .0f ;
367+ constexpr float spacing = 3 .0f ;
368+ float offsetX = (row % 2 == 0 ) ? 0 .0f : spacing / 2 .0f ;
369+ glm::vec3 pos = {static_cast <float >(col) * spacing + startX + offsetX,
370+ startY + static_cast <float >(row) * 1 .2f , 0 .0f };
371+ auto maxFactor = static_cast <float >(totalRows * cols);
372+ float gradientFactor = static_cast <float >((row + 1 ) * (col + 1 )) / maxFactor;
373+ glm::vec4 color =
374+ mix (glm::vec4 (0 .0f , 0 .77f , 0 .95f , 1 .0f ), glm::vec4 (0 .83f , 0 .14f , 0 .67f , 1 .0f ), gradientFactor);
375+ createEntityWithPhysic (pos + offset, {0 .4f , 6 .0f , 0 .4f }, {90 .0f , 0 , 0 }, color,
376+ system::ShapeType::Cylinder, JPH::EMotionType::Static);
377+ }
378+ }
299379 }
300380
301381 void EditorScene::lightsScene (const glm::vec3& offset) const
@@ -331,42 +411,30 @@ namespace nexo::editor {
331411
332412 const auto & catalog = nexo::assets::AssetCatalog::getInstance ();
333413
334- const assets::AssetLocation rubixCubeModel (" my_package::RubixCube@Models" );
335- const auto rubixCubeAssetRef = catalog.getAsset (rubixCubeModel).as <assets::Model>();
336- auto rubixCube =
337- EntityFactory3D::createModel (rubixCubeAssetRef, {4 .1f + offset.x , 2 .8f + offset.y , -4 .7f + offset.z },
338- {10 .0f , 10 .0f , 10 .0f }, {180 .0f , 0 .0f , 0 .0f });
339- scene.addEntity (rubixCube);
340-
341- const assets::AssetLocation planeModel (" my_package::Plane@Models" );
342- const auto planeAssetRef = catalog.getAsset (planeModel).as <assets::Model>();
343- auto plane = EntityFactory3D::createModel (planeAssetRef, {-5 .0f + offset.x , 0 .5f + offset.y , -5 .0f + offset.z },
344- {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 45 .0f , 0 .0f });
345- scene.addEntity (plane);
346-
347- const assets::AssetLocation cupModel (" my_package::Cup@Models" );
348- const auto cupAssetRef = catalog.getAsset (cupModel).as <assets::Model>();
349- auto cup = EntityFactory3D::createModel (cupAssetRef, {7 .0f + offset.x , 0 .3f + offset.y , 1 .6f + offset.z },
350- {14 .0f , 14 .0f , 14 .0f }, {0 .0f , -105 .0f , 0 .0f });
351- scene.addEntity (cup);
352-
353- const assets::AssetLocation earthModel (" my_package::Earth@Models" );
354- const auto earthAssetRef = catalog.getAsset (earthModel).as <assets::Model>();
355- auto earth = EntityFactory3D::createModel (earthAssetRef, {-0 .4f + offset.x , 2 .1f + offset.y , 7 .0f + offset.z },
356- {0 .5f , 0 .5f , 0 .5f }, {0 .0f , 0 .0f , 0 .0f });
357- scene.addEntity (earth);
358-
359- const assets::AssetLocation plantModel (" my_package::Plant@Models" );
360- const auto plantAssetRef = catalog.getAsset (plantModel).as <assets::Model>();
361- auto plant = EntityFactory3D::createModel (plantAssetRef, {-4 .9f + offset.x , 0 .38f + offset.y , 3 .8f + offset.z },
362- {5 .0f , 5 .0f , 5 .0f }, {0 .0f , 0 .0f , 0 .0f });
363- scene.addEntity (plant);
364-
365- const assets::AssetLocation swordModel (" my_package::Sword@Models" );
366- const auto swordAssetRef = catalog.getAsset (swordModel).as <assets::Model>();
367- auto sword = EntityFactory3D::createModel (swordAssetRef, {-0 .0f + offset.x , 0 .48f + offset.y , 0 .0f + offset.z },
368- {2 .77f , 2 .77f , 2 .77f }, {0 .0f , 0 .0f , 0 .0f });
369- scene.addEntity (sword);
414+ auto addModel = [&](const std::string& assetPath, const glm::vec3& pos, const glm::vec3& scale,
415+ const glm::vec3& rotation = {0 .0f , 0 .0f , 0 .0f }) {
416+ const auto ref = catalog.getAsset (assets::AssetLocation (assetPath)).as <assets::Model>();
417+ const auto e = EntityFactory3D::createModel (ref, pos, scale, rotation);
418+ if (e == ecs::INVALID_ENTITY) {
419+ LOG (NEXO_WARN, " Failed to load model '{}', skipping" , assetPath);
420+ return ;
421+ }
422+ scene.addEntity (e);
423+ };
424+
425+ addModel (" my_package::RubixCube@Models" ,
426+ {4 .1f + offset.x , 2 .8f + offset.y , -4 .7f + offset.z }, {10 .0f , 10 .0f , 10 .0f }, {180 .0f , 0 .0f , 0 .0f });
427+ addModel (" my_package::Plane@Models" ,
428+ {-5 .0f + offset.x , 0 .5f + offset.y , -5 .0f + offset.z }, {1 .0f , 1 .0f , 1 .0f }, {0 .0f , 45 .0f , 0 .0f });
429+ addModel (" my_package::Cup@Models" ,
430+ {7 .0f + offset.x , 0 .3f + offset.y , 1 .6f + offset.z }, {14 .0f , 14 .0f , 14 .0f }, {0 .0f , -105 .0f , 0 .0f });
431+ addModel (" my_package::Earth@Models" ,
432+ {-0 .4f + offset.x , 2 .1f + offset.y , 7 .0f + offset.z }, {0 .5f , 0 .5f , 0 .5f });
433+ addModel (" my_package::Plant@Models" ,
434+ {-4 .9f + offset.x , 0 .38f + offset.y , 3 .8f + offset.z }, {5 .0f , 5 .0f , 5 .0f });
435+
436+ addModel (" my_package::Sword@Models" ,
437+ {-0 .0f + offset.x , 0 .48f + offset.y , 0 .0f + offset.z }, {2 .77f , 2 .77f , 2 .77f });
370438 }
371439
372440 void EditorScene::videoScene (const glm::vec3& offset) const
0 commit comments