41 template <
typename T,
typename U = T>
43 std::shared_ptr<T> _find(
const std::vector<std::shared_ptr<T>>&
list,
const size_t id,
44 size_t (U::*getID)()
const = &T::getID)
46 auto i = std::find_if(
list.begin(),
list.end(), [
id, getID](
auto x) { return id == ((*x).*getID)(); });
47 return i ==
list.end() ? std::shared_ptr<T>{} : *i;
50 template <
typename T,
typename U = T>
51 std::shared_ptr<T> _remove(
std::vector<std::shared_ptr<T>>&
list,
const size_t id,
52 size_t (U::*getID)()
const = &T::getID)
54 auto i = std::find_if(
list.begin(),
list.end(), [
id, getID](
auto x) { return id == ((*x).*getID)(); });
56 return std::shared_ptr<T>{};
67 : _animationParameters(animationParameters)
68 , _geometryParameters(geometryParameters)
69 , _volumeParameters(volumeParameters)
70 , _fieldParameters(fieldParameters)
80 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
81 std::shared_lock<std::shared_timed_mutex> rhsLock(rhs.
_modelMutex);
104 size_t sizeInBytes = 0;
106 sizeInBytes += modelDescriptor->getModel().getSizeInBytes();
118 auto& model = modelDescriptor->getModel();
120 throw std::runtime_error(
"Empty models not supported.");
124 model.setBVHFlags(defaultBVHFlags);
125 model.buildBoundingBox();
129 model.commitGeometry();
132 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
133 modelDescriptor->setModelID(
_modelID++);
137 if (modelDescriptor->getInstances().empty())
138 modelDescriptor->addInstance({
true,
true, modelDescriptor->getTransformation()});
144 return modelDescriptor->getModelID();
154 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
158 model->callOnRemoved();
163 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
167 model->markForRemoval();
189 if (!modelDescriptor->getModel().empty())
196 auto clipPlane = std::make_shared<ClipPlane>(
plane);
221 auto modelDescriptor = loader.importFromBlob(std::move(blob), cb, propCopy);
222 if (!modelDescriptor)
223 throw std::runtime_error(
"No model returned by loader");
224 *modelDescriptor = params;
226 return modelDescriptor;
235 auto modelDescriptor = loader.importFromStorage(path, cb, propCopy);
236 if (!modelDescriptor)
237 throw std::runtime_error(
"No model returned by loader");
238 *modelDescriptor = params;
240 return modelDescriptor;
245 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
247 functor(modelDescriptor->getModel());
252 CORE_INFO(
"Building default Cornell Box scene");
256 const Vector3f WHITE = {1.f, 1.f, 1.f};
259 {0.f, 0.f, 0.f}, {1.f, 0.f, 0.f},
268 const uint16_t indices[6][6] = {
277 const Vector3f colors[6] = {{0.8f, 0.8f, 0.8f}, {1.f, 0.f, 0.f}, {0.8f, 0.8f, 0.8f},
278 {0.f, 1.f, 0.f}, {0.8f, 0.8f, 0.8f}, {0.8f, 0.8f, 0.8f}};
280 size_t materialId = 0;
281 for (
size_t i = 1; i < 6; ++i)
284 auto material = model->createMaterial(materialId,
"wall_" + std::to_string(materialId));
285 material->setDiffuseColor(colors[i]);
286 material->setSpecularColor(WHITE);
287 material->setSpecularExponent(10.f);
288 material->setReflectionIndex(i == 4 ? 0.2f : 0.f);
289 material->setGlossiness(i == 4 ? 0.9f : 1.f);
290 material->setOpacity(1.f);
292 auto& triangleMesh = model->getTriangleMeshes()[materialId];
293 for (
size_t j = 0; j < 6; ++j)
295 const auto position = positions[indices[i][j]];
296 triangleMesh.vertices.push_back(position);
298 triangleMesh.indices.push_back(
Vector3ui(0, 1, 2));
299 triangleMesh.indices.push_back(
Vector3ui(3, 4, 5));
305 auto material = model->createMaterial(materialId,
"sphere");
306 material->setOpacity(0.5f);
307 material->setRefractionIndex(1.05f);
308 material->setReflectionIndex(0.1f);
309 material->setDiffuseColor(WHITE);
310 material->setSpecularColor(WHITE);
311 material->setSpecularExponent(100.f);
313 model->addSphere(materialId, {{0.25f, 0.26f, 0.30f}, 0.25f});
319 auto material = model->createMaterial(materialId,
"cylinder");
320 material->setDiffuseColor({0.1f, 0.1f, 0.8f});
321 material->setSpecularColor(WHITE);
322 material->setSpecularExponent(10.f);
324 model->addCylinder(materialId, {{0.25f, 0.126f, 0.75f}, {0.75f, 0.126f, 0.75f}, 0.125f});
330 auto material = model->createMaterial(materialId,
"cone");
331 material->setReflectionIndex(0.8f);
332 material->setSpecularColor(WHITE);
333 material->setSpecularExponent(10.f);
335 model->addCone(materialId, {{0.75f, 0.01f, 0.25f}, {0.75f, 0.5f, 0.25f}, 0.15f, 0.f});
358 for (
size_t materialId = 0; materialId < 10; ++materialId)
360 auto material = model->createMaterial(materialId,
"Material");
361 material->setOpacity(0.75f);
362 material->setRefractionIndex(1.5f);
363 material->setReflectionIndex(0.5f);
364 material->setDiffuseColor({materialId * 0.1f, 0.f, 1.f - materialId * 0.1f});
365 material->setSpecularColor({1.f, 1.f, 1.f});
366 material->setSpecularExponent(100.f);
368 material->setEmission(materialId % 2 == 0 ? 0.5f : 0.f);
369 material->setCastUserData(
true);
371 model->addSphere(materialId, {{-50.f + materialId * 10.f, 0.f, 0.f}, 5.f});
372 model->addCylinder(materialId,
373 {{-50.f + materialId * 10.f, 0.f, 0.f}, {-50.f + materialId * 10.f, 20.f, 0.f}, 2.5f});
374 model->addCone(materialId,
375 {{-50.f + materialId * 10.f, 0.f, 0.f}, {-50.f + materialId * 10.f, -20.f, 0.f}, 2.5f, 0.f});
379 addModel(std::make_shared<ModelDescriptor>(std::move(model),
"Demo scene"));
387 modelDescriptors->getModel().setMaterialsColorMap(colorMap);
406 catch (
const std::runtime_error& e)
408 CORE_DEBUG(
"Cannot load environment map: " << e.what());
429 std::unique_lock<std::shared_timed_mutex> lock(
_modelMutex);
433 const auto& modelBounds = modelDescriptor->getModel().getBounds();
437 const auto modelHalfSize = modelBounds.getSize() / 2.0;
439 Transformation finalTransformation = modelTransformation * modelDescriptor->getTransformation();
442 for (
const auto& instance : modelDescriptor->getInstances())
444 finalTransformation = modelTransformation * instance.getTransformation();
461 const auto path = fs::path(envMap).parent_path();
462 const auto basename = (path / fs::path(envMap).stem()).
string();
464 const std::string irradianceMap = basename + IRRADIANCE_MAP +
".hdr";
465 const std::string radianceMap = basename + RADIANCE_MAP +
".hdr";
466 const std::string brdfLUT = basename + BRDF_LUT +
".hdr";
468 if (fs::exists(irradianceMap) && fs::exists(radianceMap) && fs::exists(brdfLUT))
void _updateValue(T &member, const T &newValue, const bool triggerCallback=true)
void markModified(const bool triggerCallback=true)
void merge(const Box< T > &aabb)
const std::set< BVHFlag > & getDefaultBVHFlags() const
const Loader & getSuitableLoader(const std::string &filename, const std::string &filetype, const std::string &loaderName) const
PLATFORM_API size_t getModelID() const
Get the value of _modelID.
The ModelParams class represents the parameters needed for initializing a model instance.
PLATFORM_API const std::string & getLoaderName() const
getLoaderName gets the loader name of the model
PLATFORM_API const PropertyMap & getLoaderProperties() const
getLoaderProperties gets the loader properties of the model
The abstract Model class holds the geometry attached to an asset of the scene (mesh,...
void setProperty(const Property &newProperty)
Scene object This object contains collections of geometries, materials and light sources that are use...
ModelDescriptors _modelDescriptors
PLATFORM_API size_t addModel(ModelDescriptorPtr model)
Adds a model to the scene.
virtual PLATFORM_API ModelPtr createModel() const =0
Factory method to create an engine-specific model.
PLATFORM_API bool setEnvironmentMap(const std::string &envMap)
Set a new environment map as the background image.
PLATFORM_API void computeBounds()
Compute the bounds of the geometry handled by the scene.
std::shared_timed_mutex _modelMutex
PLATFORM_API size_t getNumModels() const
Get the current number of models in the scene.
PLATFORM_API ModelDescriptorPtr loadModel(Blob &&blob, const ModelParams ¶ms, LoaderProgress cb)
Load a model from the given blob.
LoaderRegistry _loaderRegistry
PLATFORM_API size_t getSizeInBytes() const
Get the current size in bytes of the loaded geometry.
PLATFORM_API size_t addClipPlane(const Plane &plane)
Add a clip plane to the scene.
GeometryParameters & _geometryParameters
std::string _environmentMap
virtual PLATFORM_API void commit()
Called after scene-related changes have been made before rendering the scene.
LightManager _lightManager
PLATFORM_API void removeClipPlane(const size_t id)
Remove a clip plane by its ID, or no-op if not found.
PLATFORM_API void buildDefault()
Builds a default scene made of a Cornell box, a reflective cube, and a transparent sphere.
PLATFORM_API void visitModels(const std::function< void(Model &)> &functor)
Apply the given functor to every model in the scene.
PLATFORM_API void setMaterialsColorMap(MaterialsColorMap colorMap)
Initializes materials for all models in the scene.
PLATFORM_API ModelDescriptorPtr getModel(const size_t id) const
Get a model descriptor given its ID.
PLATFORM_API void copyFrom(const Scene &rhs)
Copy the scene from another scene.
PLATFORM_API auto acquireReadAccess() const
virtual bool supportsConcurrentSceneUpdates() const
Check whether this scene supports scene updates from any thread.
MaterialPtr _backgroundMaterial
void _loadIBLMaps(const std::string &envMap)
PLATFORM_API bool hasEnvironmentMap() const
Check if an environment map is currently set in the scene.
PLATFORM_API ClipPlanePtr getClipPlane(const size_t id) const
Get a clip plane by its ID.
PLATFORM_API bool removeModel(const size_t id)
Removes a model from the scene.
PLATFORM_API Scene(AnimationParameters &animationParameters, GeometryParameters &geometryParameters, VolumeParameters &volumeParameters, FieldParameters &fieldParameters)
Creates a scene object responsible for handling models, simulations and light sources.
PLATFORM_API bool empty() const
Checks whether the scene is empty.
glm::vec< 3, uint32_t > Vector3ui
std::shared_ptr< ClipPlane > ClipPlanePtr
std::shared_ptr< ModelDescriptor > ModelDescriptorPtr
std::array< double, 4 > Plane