environment probes closes #803
This commit is contained in:
parent
9b3acfaa73
commit
035a46ff41
7 changed files with 348 additions and 14 deletions
|
@ -1745,7 +1745,12 @@ public:
|
|||
save(*file);
|
||||
m_is_universe_changed = false;
|
||||
fs.close(*file);
|
||||
if (save_path) m_universe_path = path;
|
||||
|
||||
if (save_path)
|
||||
{
|
||||
m_universe_path = path;
|
||||
m_universe->setPath(path);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -2407,6 +2412,7 @@ public:
|
|||
{
|
||||
destroyUniverse();
|
||||
createUniverse(false);
|
||||
m_universe->setPath(m_universe_path);
|
||||
load(file);
|
||||
}
|
||||
|
||||
|
|
|
@ -164,7 +164,8 @@ namespace Lumix
|
|||
}
|
||||
else
|
||||
{
|
||||
return m_data[m_data.insert(Pair(key, Value()))].m_value;
|
||||
ASSERT(false);
|
||||
return m_data[0].m_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "engine/array.h"
|
||||
#include "engine/associative_array.h"
|
||||
#include "engine/delegate_list.h"
|
||||
#include "engine/path.h"
|
||||
#include "engine/quat.h"
|
||||
#include "engine/string.h"
|
||||
#include "engine/vec.h"
|
||||
|
@ -55,6 +56,8 @@ public:
|
|||
float getScale(Entity entity);
|
||||
const Vec3& getPosition(Entity entity) const;
|
||||
const Quat& getRotation(Entity entity) const;
|
||||
Lumix::Path getPath() const { return m_path; }
|
||||
void setPath(const Lumix::Path& path) { m_path = path; }
|
||||
|
||||
DelegateList<void(Entity)>& entityTransformed() { return m_entity_moved; }
|
||||
DelegateList<void(Entity)>& entityCreated() { return m_entity_created; }
|
||||
|
@ -91,6 +94,7 @@ private:
|
|||
DelegateList<void(const ComponentUID&)> m_component_destroyed;
|
||||
DelegateList<void(const ComponentUID&)> m_component_added;
|
||||
int m_first_free_slot;
|
||||
Lumix::Path m_path;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
#include "engine/lumix.h"
|
||||
#include "editor/asset_browser.h"
|
||||
#include "editor/ieditor_command.h"
|
||||
#include "editor/platform_interface.h"
|
||||
#include "editor/property_grid.h"
|
||||
#include "editor/render_interface.h"
|
||||
#include "editor/studio_app.h"
|
||||
#include "editor/utils.h"
|
||||
#include "editor/world_editor.h"
|
||||
#include "engine/crc32.h"
|
||||
#include "engine/fs/disk_file_device.h"
|
||||
#include "engine/fs/file_system.h"
|
||||
|
@ -10,19 +18,11 @@
|
|||
#include "engine/path_utils.h"
|
||||
#include "engine/resource_manager.h"
|
||||
#include "engine/resource_manager_base.h"
|
||||
#include "editor/asset_browser.h"
|
||||
#include "editor/ieditor_command.h"
|
||||
#include "editor/platform_interface.h"
|
||||
#include "editor/property_grid.h"
|
||||
#include "editor/studio_app.h"
|
||||
#include "editor/utils.h"
|
||||
#include "editor/world_editor.h"
|
||||
#include "engine/engine.h"
|
||||
#include "engine/plugin_manager.h"
|
||||
#include "engine/property_register.h"
|
||||
#include "engine/property_descriptor.h"
|
||||
#include "game_view.h"
|
||||
#include "editor/render_interface.h"
|
||||
#include "import_asset_dialog.h"
|
||||
#include "renderer/frame_buffer.h"
|
||||
#include "renderer/material.h"
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include "shader_compiler.h"
|
||||
#include "terrain_editor.h"
|
||||
#include <cmath>
|
||||
#include <crnlib.h>
|
||||
#include <SDL.h>
|
||||
|
||||
|
||||
|
@ -51,6 +52,8 @@ static const uint32 CAMERA_HASH = crc32("camera");
|
|||
static const uint32 POINT_LIGHT_HASH = crc32("point_light");
|
||||
static const uint32 GLOBAL_LIGHT_HASH = crc32("global_light");
|
||||
static const uint32 RENDERABLE_HASH = crc32("renderable");
|
||||
static const uint32 RENDERER_HASH = crc32("renderer");
|
||||
static const uint32 ENVIRONMENT_PROBE_HASH = crc32("environment_probe");
|
||||
static const uint32 MATERIAL_HASH = crc32("MATERIAL");
|
||||
static const uint32 SHADER_HASH = crc32("SHADER");
|
||||
static const uint32 TEXTURE_HASH = crc32("TEXTURE");
|
||||
|
@ -707,6 +710,218 @@ struct ShaderPlugin : public AssetBrowser::IPlugin
|
|||
};
|
||||
|
||||
|
||||
struct EnvironmentProbePlugin : public PropertyGrid::IPlugin
|
||||
{
|
||||
explicit EnvironmentProbePlugin(StudioApp& app)
|
||||
: m_app(app)
|
||||
{
|
||||
auto* world_editor = app.getWorldEditor();
|
||||
auto& plugin_manager = world_editor->getEngine().getPluginManager();
|
||||
Renderer* renderer = static_cast<Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
auto& allocator = world_editor->getAllocator();
|
||||
Lumix::Path pipeline_path("pipelines/game_view.lua");
|
||||
m_pipeline = Pipeline::create(*renderer, pipeline_path, allocator);
|
||||
m_pipeline->load();
|
||||
}
|
||||
|
||||
|
||||
~EnvironmentProbePlugin()
|
||||
{
|
||||
Pipeline::destroy(m_pipeline);
|
||||
}
|
||||
|
||||
|
||||
bool saveCubemap(ComponentUID cmp, const Array<uint8>& data, int texture_size)
|
||||
{
|
||||
crn_uint32 size;
|
||||
crn_comp_params comp_params;
|
||||
comp_params.m_width = texture_size;
|
||||
comp_params.m_height = texture_size;
|
||||
comp_params.m_file_type = cCRNFileTypeDDS;
|
||||
comp_params.m_format = cCRNFmtDXT1;
|
||||
comp_params.m_quality_level = cCRNMinQualityLevel;
|
||||
comp_params.m_dxt_quality = cCRNDXTQualitySuperFast;
|
||||
comp_params.m_dxt_compressor_type = cCRNDXTCompressorRYG;
|
||||
comp_params.m_pProgress_func = nullptr;
|
||||
comp_params.m_pProgress_func_data = nullptr;
|
||||
comp_params.m_num_helper_threads = 3;
|
||||
comp_params.m_faces = 6;
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
comp_params.m_pImages[i][0] = (Lumix::uint32*)&data[i * texture_size * texture_size * 4];
|
||||
}
|
||||
crn_mipmap_params mipmap_params;
|
||||
mipmap_params.m_mode = cCRNMipModeGenerateMips;
|
||||
|
||||
void* compressed_data = crn_compress(comp_params, mipmap_params, size);
|
||||
if (!compressed_data)
|
||||
{
|
||||
g_log_error.log("Editor") << "Failed to compress the probe.";
|
||||
return false;
|
||||
}
|
||||
|
||||
Lumix::FS::OsFile file;
|
||||
const char* base_path = m_app.getWorldEditor()->getEngine().getDiskFileDevice()->getBasePath();
|
||||
uint64 universe_guid = m_app.getWorldEditor()->getUniverse()->getPath().getHash();
|
||||
Lumix::StaticString<Lumix::MAX_PATH_LENGTH> path(base_path, "universes/", universe_guid);
|
||||
if (!PlatformInterface::makePath(path)) g_log_error.log("Editor") << "Failed to create " << path;
|
||||
path << "/probes/";
|
||||
if (!PlatformInterface::makePath(path)) g_log_error.log("Editor") << "Failed to create " << path;
|
||||
path << cmp.index << ".dds";
|
||||
auto& allocator = m_app.getWorldEditor()->getAllocator();
|
||||
if (!file.open(path, Lumix::FS::Mode::CREATE_AND_WRITE, allocator))
|
||||
{
|
||||
g_log_error.log("Editor") << "Failed to create " << path;
|
||||
crn_free_block(compressed_data);
|
||||
return false;
|
||||
}
|
||||
|
||||
file.write((const char*)compressed_data, size);
|
||||
file.close();
|
||||
crn_free_block(compressed_data);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void flipY(uint32* data, int texture_size)
|
||||
{
|
||||
for (int y = 0; y < texture_size / 2; ++y)
|
||||
{
|
||||
for (int x = 0; x < texture_size; ++x)
|
||||
{
|
||||
uint32 t = data[x + y * texture_size];
|
||||
data[x + y * texture_size] = data[x + (texture_size - y - 1) * texture_size];
|
||||
data[x + (texture_size - y - 1) * texture_size] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void flipX(uint32* data, int texture_size)
|
||||
{
|
||||
for (int y = 0; y < texture_size; ++y)
|
||||
{
|
||||
uint32* tmp = (uint32*)&data[y * texture_size];
|
||||
for (int x = 0; x < texture_size / 2; ++x)
|
||||
{
|
||||
uint32 t = tmp[x];
|
||||
tmp[x] = tmp[texture_size - x - 1];
|
||||
tmp[texture_size - x - 1] = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void generateCubemap(ComponentUID cmp)
|
||||
{
|
||||
static const int TEXTURE_SIZE = 1024;
|
||||
|
||||
Universe* universe = m_app.getWorldEditor()->getUniverse();
|
||||
if (!universe->getPath().isValid())
|
||||
{
|
||||
g_log_error.log("Editor") << "Universe must be saved before environment probe can be generated.";
|
||||
return;
|
||||
}
|
||||
|
||||
WorldEditor* world_editor = m_app.getWorldEditor();
|
||||
Engine& engine = world_editor->getEngine();
|
||||
auto& plugin_manager = engine.getPluginManager();
|
||||
IAllocator& allocator = engine.getAllocator();
|
||||
Lumix::Array<Lumix::uint8> data(allocator);
|
||||
data.resize(6 * TEXTURE_SIZE * TEXTURE_SIZE * 4);
|
||||
|
||||
bgfx::TextureHandle texture =
|
||||
bgfx::createTexture2D(TEXTURE_SIZE, TEXTURE_SIZE, 1, bgfx::TextureFormat::RGBA8, BGFX_TEXTURE_READ_BACK);
|
||||
|
||||
Vec3 probe_position = universe->getPosition(cmp.entity);
|
||||
auto* scene = static_cast<RenderScene*>(universe->getScene(crc32("renderer")));
|
||||
ComponentIndex original_camera = scene->getCameraInSlot("main");
|
||||
|
||||
if(original_camera != INVALID_COMPONENT) scene->setCameraSlot(original_camera, "");
|
||||
Entity camera_entity = universe->createEntity({ 0, 0, 0 }, { 0, 0, 0, 1 });
|
||||
ComponentIndex camera_cmp = scene->createComponent(CAMERA_HASH, camera_entity);
|
||||
scene->setCameraSlot(camera_cmp, "main");
|
||||
scene->setCameraFOV(camera_cmp, 90);
|
||||
|
||||
m_pipeline->setScene(scene);
|
||||
m_pipeline->setViewport(0, 0, TEXTURE_SIZE, TEXTURE_SIZE);
|
||||
|
||||
Renderer* renderer = static_cast<Renderer*>(plugin_manager.getPlugin("renderer"));
|
||||
|
||||
Vec3 dirs[] = {{-1, 0, 0}, {1, 0, 0}, {0, -1, 0}, {0, 1, 0}, {0, 0, -1}, {0, 0, 1}};
|
||||
Vec3 ups[] = {{0, 1, 0}, {0, 1, 0}, {0, 0, 1}, {0, 0, -1}, {0, 1, 0}, {0, 1, 0}};
|
||||
Vec3 ups_opengl[] = { { 0, -1, 0 },{ 0, -1, 0 },{ 0, 0, 1 },{ 0, 0, -1 },{ 0, -1, 0 },{ 0, -1, 0 } };
|
||||
|
||||
renderer->frame(); // submit
|
||||
renderer->frame(); // wait for gpu
|
||||
|
||||
bool is_opengl = renderer->isOpenGL();
|
||||
for (int i = 0; i < 6; ++i)
|
||||
{
|
||||
Matrix mtx = Matrix::IDENTITY;
|
||||
mtx.setTranslation(probe_position);
|
||||
Vec3 side = crossProduct(is_opengl ? ups_opengl[i] : ups[i], dirs[i]);
|
||||
mtx.setZVector(dirs[i]);
|
||||
mtx.setYVector(is_opengl ? ups_opengl[i] : ups[i]);
|
||||
mtx.setXVector(side);
|
||||
universe->setMatrix(camera_entity, mtx);
|
||||
m_pipeline->render();
|
||||
|
||||
renderer->viewCounterAdd();
|
||||
bgfx::touch(renderer->getViewCounter());
|
||||
bgfx::setViewName(renderer->getViewCounter(), "probe_blit");
|
||||
auto* default_framebuffer = m_pipeline->getFramebuffer("default");
|
||||
bgfx::TextureHandle color_renderbuffer = default_framebuffer->getRenderbufferHandle(0);
|
||||
bgfx::blit(renderer->getViewCounter(), texture, 0, 0, color_renderbuffer);
|
||||
|
||||
renderer->viewCounterAdd();
|
||||
bgfx::setViewName(renderer->getViewCounter(), "probe_read");
|
||||
bgfx::readTexture(texture, &data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4]);
|
||||
bgfx::touch(renderer->getViewCounter());
|
||||
renderer->frame(); // submit
|
||||
renderer->frame(); // wait for gpu
|
||||
|
||||
if (is_opengl) continue;
|
||||
|
||||
uint32* tmp = (uint32*)&data[i * TEXTURE_SIZE * TEXTURE_SIZE * 4];
|
||||
if (i == 2 || i == 3)
|
||||
{
|
||||
flipY(tmp, TEXTURE_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
flipX(tmp, TEXTURE_SIZE);
|
||||
}
|
||||
}
|
||||
saveCubemap(cmp, data, TEXTURE_SIZE);
|
||||
bgfx::destroyTexture(texture);
|
||||
|
||||
scene->destroyComponent(camera_cmp, CAMERA_HASH);
|
||||
universe->destroyEntity(camera_entity);
|
||||
if (original_camera != INVALID_COMPONENT) scene->setCameraSlot(original_camera, "main");
|
||||
|
||||
scene->reloadEnvironmentProbe(cmp.index);
|
||||
}
|
||||
|
||||
|
||||
void onGUI(PropertyGrid& grid, ComponentUID cmp) override
|
||||
{
|
||||
if (cmp.type != ENVIRONMENT_PROBE_HASH) return;
|
||||
|
||||
auto* scene = static_cast<RenderScene*>(cmp.scene);
|
||||
auto* texture = scene->getEnvironmentProbeTexture(cmp.index);
|
||||
ImGui::LabelText("Path", "%s", texture->getPath().c_str());
|
||||
if (ImGui::Button("View")) m_app.getAssetBrowser()->selectResource(texture->getPath());
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Generate")) generateCubemap(cmp);
|
||||
}
|
||||
|
||||
|
||||
StudioApp& m_app;
|
||||
Pipeline* m_pipeline;
|
||||
};
|
||||
|
||||
|
||||
struct EmitterPlugin : public PropertyGrid::IPlugin
|
||||
{
|
||||
explicit EmitterPlugin(StudioApp& app)
|
||||
|
@ -1503,6 +1718,9 @@ LUMIX_STUDIO_ENTRY(renderer)
|
|||
auto* emitter_plugin = LUMIX_NEW(allocator, EmitterPlugin)(app);
|
||||
app.getPropertyGrid()->addPlugin(*emitter_plugin);
|
||||
|
||||
auto* env_probe_plugin = LUMIX_NEW(allocator, EnvironmentProbePlugin)(app);
|
||||
app.getPropertyGrid()->addPlugin(*env_probe_plugin);
|
||||
|
||||
auto* terrain_plugin = LUMIX_NEW(allocator, TerrainPlugin)(app);
|
||||
app.getPropertyGrid()->addPlugin(*terrain_plugin);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "engine/mtjd/generic_job.h"
|
||||
#include "engine/mtjd/job.h"
|
||||
#include "engine/mtjd/manager.h"
|
||||
#include "engine/path_utils.h"
|
||||
#include "engine/profiler.h"
|
||||
#include "engine/resource_manager.h"
|
||||
#include "engine/resource_manager_base.h"
|
||||
|
@ -33,6 +34,7 @@
|
|||
#include "renderer/shader.h"
|
||||
#include "renderer/terrain.h"
|
||||
#include "renderer/texture.h"
|
||||
#include "renderer/texture_manager.h"
|
||||
|
||||
#include "engine/universe/universe.h"
|
||||
#include <cmath>
|
||||
|
@ -59,7 +61,9 @@ static const uint32 GLOBAL_LIGHT_HASH = crc32("global_light");
|
|||
static const uint32 CAMERA_HASH = crc32("camera");
|
||||
static const uint32 TERRAIN_HASH = crc32("terrain");
|
||||
static const uint32 BONE_ATTACHMENT_HASH = crc32("bone_attachment");
|
||||
static const uint32 ENVIRONMENT_PROBE_HASH = crc32("environment_probe");
|
||||
static const uint32 MATERIAL_HASH = crc32("MATERIAL");
|
||||
static const uint32 TEXTURE_HASH = crc32("TEXTURE");
|
||||
static const uint32 MODEL_HASH = crc32("MODEL");
|
||||
static bool is_opengl = false;
|
||||
|
||||
|
@ -115,6 +119,12 @@ struct Camera
|
|||
};
|
||||
|
||||
|
||||
struct EnvironmentProbe
|
||||
{
|
||||
Texture* texture;
|
||||
};
|
||||
|
||||
|
||||
struct BoneAttachment
|
||||
{
|
||||
Entity entity;
|
||||
|
@ -196,6 +206,7 @@ public:
|
|||
, m_particle_emitters(m_allocator)
|
||||
, m_point_lights_map(m_allocator)
|
||||
, m_bone_attachments(m_allocator)
|
||||
, m_environment_probes(m_allocator)
|
||||
{
|
||||
is_opengl = renderer.isOpenGL();
|
||||
m_is_updating_attachments = false;
|
||||
|
@ -241,6 +252,12 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
for (int i = 0, c = m_environment_probes.size(); i < c; ++i)
|
||||
{
|
||||
auto& probe = m_environment_probes.at(i);
|
||||
if (probe.texture) probe.texture->getResourceManager().get(TEXTURE_HASH)->unload(*probe.texture);
|
||||
}
|
||||
|
||||
CullingSystem::destroy(*m_culling_system);
|
||||
}
|
||||
|
||||
|
@ -674,6 +691,51 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void serializeEnvironmentProbes(OutputBlob& serializer)
|
||||
{
|
||||
int32 count = m_environment_probes.size();
|
||||
serializer.write(count);
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
auto& probe = m_environment_probes.at(i);
|
||||
Entity entity = m_environment_probes.getKey(i);
|
||||
serializer.write(entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void deserializeEnvironmentProbes(InputBlob& serializer)
|
||||
{
|
||||
int32 count;
|
||||
serializer.read(count);
|
||||
for (int i = 0, c = m_environment_probes.size(); i < c; ++i)
|
||||
{
|
||||
auto& probe = m_environment_probes.at(i);
|
||||
if (probe.texture)
|
||||
{
|
||||
probe.texture->getResourceManager().get(TEXTURE_HASH)->unload(*probe.texture);
|
||||
}
|
||||
}
|
||||
|
||||
m_environment_probes.clear();
|
||||
m_environment_probes.reserve(count);
|
||||
auto* texture_manager = m_engine.getResourceManager().get(TEXTURE_HASH);
|
||||
uint64 universe_guid = m_universe.getPath().getHash();
|
||||
StaticString<Lumix::MAX_PATH_LENGTH> probe_dir("universes/", universe_guid, "/probes/");
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
Entity entity;
|
||||
serializer.read(entity);
|
||||
EnvironmentProbe probe;
|
||||
StaticString<Lumix::MAX_PATH_LENGTH> path_str(probe_dir, entity, ".dds");
|
||||
Path path(path_str);
|
||||
probe.texture = static_cast<Texture*>(texture_manager->load(path));
|
||||
m_environment_probes.insert(entity, probe);
|
||||
m_universe.addComponent(entity, ENVIRONMENT_PROBE_HASH, this, entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void deserializeBoneAttachments(InputBlob& serializer, int version)
|
||||
{
|
||||
if (version <= (int)RenderSceneVersion::BONE_ATTACHMENTS) return;
|
||||
|
@ -786,6 +848,7 @@ public:
|
|||
serializeTerrains(serializer);
|
||||
serializeParticleEmitters(serializer);
|
||||
serializeBoneAttachments(serializer);
|
||||
serializeEnvironmentProbes(serializer);
|
||||
}
|
||||
|
||||
void deserializeRenderParams(InputBlob& serializer)
|
||||
|
@ -1036,6 +1099,7 @@ public:
|
|||
deserializeRenderParams(serializer);
|
||||
}
|
||||
deserializeBoneAttachments(serializer, version);
|
||||
if (version > (int)RenderSceneVersion::ENVIRONMENT_PROBES) deserializeEnvironmentProbes(serializer);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1048,6 +1112,16 @@ public:
|
|||
}
|
||||
|
||||
|
||||
void destroyEnvironmentProbe(ComponentIndex component)
|
||||
{
|
||||
Entity entity = (Entity)component;
|
||||
auto& probe = m_environment_probes[entity];
|
||||
if (probe.texture) probe.texture->getResourceManager().get(TEXTURE_HASH)->unload(*probe.texture);
|
||||
m_environment_probes.erase(entity);
|
||||
m_universe.destroyComponent(entity, ENVIRONMENT_PROBE_HASH, this, component);
|
||||
}
|
||||
|
||||
|
||||
void destroyRenderable(ComponentIndex component)
|
||||
{
|
||||
m_renderable_destroyed.invoke(component);
|
||||
|
@ -3275,6 +3349,20 @@ public:
|
|||
return m_global_lights[getGlobalLightIndex(cmp)].m_entity;
|
||||
}
|
||||
|
||||
void reloadEnvironmentProbe(ComponentIndex cmp) override
|
||||
{
|
||||
auto& probe = m_environment_probes[cmp];
|
||||
auto* texture_manager = m_engine.getResourceManager().get(TEXTURE_HASH);
|
||||
if (probe.texture) texture_manager->unload(*probe.texture);
|
||||
uint64 universe_guid = m_universe.getPath().getHash();
|
||||
StaticString<Lumix::MAX_PATH_LENGTH> path("universes/", universe_guid, "/probes/", cmp, ".dds");
|
||||
probe.texture = static_cast<Texture*>(texture_manager->load(Path(path)));
|
||||
}
|
||||
|
||||
Texture* getEnvironmentProbeTexture(ComponentIndex cmp) const
|
||||
{
|
||||
return m_environment_probes[cmp].texture;
|
||||
}
|
||||
|
||||
ComponentIndex getCameraInSlot(const char* slot) override
|
||||
{
|
||||
|
@ -3782,6 +3870,18 @@ public:
|
|||
}
|
||||
|
||||
|
||||
ComponentIndex createEnvironmentProbe(Entity entity)
|
||||
{
|
||||
EnvironmentProbe probe;
|
||||
auto* texture_manager = m_engine.getResourceManager().get(TEXTURE_HASH);
|
||||
probe.texture = static_cast<Texture*>(texture_manager->load(Path("models/editor/default_probe.dds")));
|
||||
m_environment_probes.insert(entity, probe);
|
||||
|
||||
m_universe.addComponent(entity, ENVIRONMENT_PROBE_HASH, this, entity);
|
||||
return entity;
|
||||
}
|
||||
|
||||
|
||||
ComponentIndex createBoneAttachment(Entity entity)
|
||||
{
|
||||
BoneAttachment& attachment = m_bone_attachments.emplace();
|
||||
|
@ -3859,6 +3959,7 @@ private:
|
|||
Array<GlobalLight> m_global_lights;
|
||||
Array<Camera> m_cameras;
|
||||
Array<BoneAttachment> m_bone_attachments;
|
||||
AssociativeArray<Entity, EnvironmentProbe> m_environment_probes;
|
||||
Array<Terrain*> m_terrains;
|
||||
Universe& m_universe;
|
||||
Renderer& m_renderer;
|
||||
|
@ -3917,13 +4018,11 @@ static struct
|
|||
{PARTICLE_EMITTER_PLANE_HASH,
|
||||
&RenderSceneImpl::createParticleEmitterPlane,
|
||||
&RenderSceneImpl::destroyParticleEmitterPlane},
|
||||
{BONE_ATTACHMENT_HASH, &RenderSceneImpl::createBoneAttachment, &RenderSceneImpl::destroyBoneAttachment}
|
||||
{BONE_ATTACHMENT_HASH, &RenderSceneImpl::createBoneAttachment, &RenderSceneImpl::destroyBoneAttachment},
|
||||
{ENVIRONMENT_PROBE_HASH, &RenderSceneImpl::createEnvironmentProbe, &RenderSceneImpl::destroyEnvironmentProbe}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ComponentIndex RenderSceneImpl::createComponent(uint32 type, Entity entity)
|
||||
{
|
||||
for (auto& i : COMPONENT_INFOS)
|
||||
|
|
|
@ -26,6 +26,7 @@ struct RayCastModelHit;
|
|||
class Renderer;
|
||||
class Shader;
|
||||
class Terrain;
|
||||
class Texture;
|
||||
class Universe;
|
||||
template <typename T> class Array;
|
||||
template <typename T> class DelegateList;
|
||||
|
@ -46,6 +47,7 @@ enum class RenderSceneVersion : int32
|
|||
GRASS_TYPE_DISTANCE,
|
||||
ORTHO_CAMERA,
|
||||
BONE_ATTACHMENTS,
|
||||
ENVIRONMENT_PROBES,
|
||||
|
||||
LATEST,
|
||||
INVALID = -1,
|
||||
|
@ -390,6 +392,9 @@ public:
|
|||
virtual float getPointLightSpecularIntensity(ComponentIndex cmp) = 0;
|
||||
virtual void setPointLightSpecularIntensity(ComponentIndex cmp, float color) = 0;
|
||||
|
||||
virtual Texture* getEnvironmentProbeTexture(ComponentIndex cmp) const = 0;
|
||||
virtual void reloadEnvironmentProbe(ComponentIndex cmp) = 0;
|
||||
|
||||
protected:
|
||||
virtual ~RenderScene() {}
|
||||
};
|
||||
|
|
|
@ -164,6 +164,7 @@ static void registerProperties(IAllocator& allocator)
|
|||
PropertyRegister::registerComponentType("point_light", "Point light");
|
||||
PropertyRegister::registerComponentType("terrain", "Terrain");
|
||||
PropertyRegister::registerComponentType("bone_attachment", "Bone attachment");
|
||||
PropertyRegister::registerComponentType("environment_probe", "Environment probe");
|
||||
|
||||
PropertyRegister::registerComponentDependency("particle_emitter_fade", "particle_emitter");
|
||||
PropertyRegister::registerComponentDependency("particle_emitter_force", "particle_emitter");
|
||||
|
|
Loading…
Reference in a new issue