From 26a12876bbeeaccb6e782826f566e4fee9e846b0 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Wed, 19 Sep 2018 18:16:36 +0100 Subject: [PATCH] ecs serializers update + general refactors --- Editor/CameraWindow.cpp | 16 +- Editor/Editor.cpp | 283 +++----- Editor/EnvProbeWindow.cpp | 2 +- Editor/ModelImporter.h | 6 +- Editor/ModelImporter_GLTF.cpp | 65 +- Editor/ModelImporter_OBJ.cpp | 27 +- Editor/Translator.cpp | 42 +- Editor/Translator.h | 2 +- Editor/main.cpp | 2 +- Template_Windows/main.cpp | 2 +- Tests/main.cpp | 2 +- WickedEngine/DeferredRenderableComponent.cpp | 8 +- WickedEngine/ForwardRenderableComponent.cpp | 4 +- .../PathTracingRenderableComponent.cpp | 23 +- WickedEngine/Renderable3DComponent.cpp | 24 +- .../TiledDeferredRenderableComponent.cpp | 8 +- .../TiledForwardRenderableComponent.cpp | 8 +- WickedEngine/wiECS.h | 54 +- WickedEngine/wiEmittedParticle.cpp | 8 +- WickedEngine/wiEmittedParticle.h | 4 +- WickedEngine/wiHairParticle.cpp | 8 +- WickedEngine/wiHairParticle.h | 4 +- WickedEngine/wiImage.cpp | 6 +- WickedEngine/wiIntersectables.cpp | 2 +- WickedEngine/wiIntersectables.h | 11 +- WickedEngine/wiOcean.cpp | 2 +- WickedEngine/wiOcean.h | 2 +- WickedEngine/wiRandom.cpp | 22 +- WickedEngine/wiRandom.h | 11 +- WickedEngine/wiRenderer.cpp | 223 ++++--- WickedEngine/wiRenderer.h | 28 +- WickedEngine/wiSceneSystem.cpp | 82 ++- WickedEngine/wiSceneSystem.h | 49 +- WickedEngine/wiSceneSystem_Serializers.cpp | 625 ++++++++++++++++-- 34 files changed, 1065 insertions(+), 600 deletions(-) diff --git a/Editor/CameraWindow.cpp b/Editor/CameraWindow.cpp index 574d7b2de..69e2f28a3 100644 --- a/Editor/CameraWindow.cpp +++ b/Editor/CameraWindow.cpp @@ -11,7 +11,7 @@ void CameraWindow::ResetCam() camera_transform.ClearTransform(); camera_transform.Translate(XMFLOAT3(0, 2, -10)); camera_transform.UpdateTransform(); - wiRenderer::getCamera()->UpdateCamera(&camera_transform); + wiRenderer::GetCamera().UpdateCamera(&camera_transform); camera_target.ClearTransform(); camera_target.UpdateTransform(); @@ -24,6 +24,8 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) float screenW = (float)wiRenderer::GetDevice()->GetScreenWidth(); float screenH = (float)wiRenderer::GetDevice()->GetScreenHeight(); + camera_transform.MatrixTransform(wiRenderer::GetCamera().GetInvView()); + cameraWindow = new wiWindow(GUI, "Camera Window"); cameraWindow->SetSize(XMFLOAT2(600, 420)); GUI->AddWidget(cameraWindow); @@ -35,10 +37,10 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) farPlaneSlider = new wiSlider(1, 5000, 1000, 100000, "Far Plane: "); farPlaneSlider->SetSize(XMFLOAT2(100, 30)); farPlaneSlider->SetPos(XMFLOAT2(x, y += inc)); - farPlaneSlider->SetValue(wiRenderer::getCamera()->zFarP); + farPlaneSlider->SetValue(wiRenderer::GetCamera().zFarP); farPlaneSlider->OnSlide([&](wiEventArgs args) { Scene& scene = wiRenderer::GetScene(); - CameraComponent& camera = *wiRenderer::getCamera(); + CameraComponent& camera = wiRenderer::GetCamera(); camera.zFarP = args.fValue; camera.UpdateProjection(); }); @@ -47,10 +49,10 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) nearPlaneSlider = new wiSlider(0.01f, 10, 0.1f, 10000, "Near Plane: "); nearPlaneSlider->SetSize(XMFLOAT2(100, 30)); nearPlaneSlider->SetPos(XMFLOAT2(x, y += inc)); - nearPlaneSlider->SetValue(wiRenderer::getCamera()->zNearP); + nearPlaneSlider->SetValue(wiRenderer::GetCamera().zNearP); nearPlaneSlider->OnSlide([&](wiEventArgs args) { Scene& scene = wiRenderer::GetScene(); - CameraComponent& camera = *wiRenderer::getCamera(); + CameraComponent& camera = wiRenderer::GetCamera(); camera.zNearP = args.fValue; camera.UpdateProjection(); }); @@ -61,7 +63,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) fovSlider->SetPos(XMFLOAT2(x, y += inc)); fovSlider->OnSlide([&](wiEventArgs args) { Scene& scene = wiRenderer::GetScene(); - CameraComponent& camera = *wiRenderer::getCamera(); + CameraComponent& camera = wiRenderer::GetCamera(); camera.fov = args.fValue / 180.f * XM_PI; camera.UpdateProjection(); }); @@ -98,7 +100,7 @@ CameraWindow::CameraWindow(wiGUI* gui) :GUI(gui) proxyButton->SetPos(XMFLOAT2(x, y += inc * 2)); proxyButton->OnClick([&](wiEventArgs args) { - CameraComponent& camera = *wiRenderer::getCamera(); + const CameraComponent& camera = wiRenderer::GetCamera(); Scene& scene = wiRenderer::GetScene(); diff --git a/Editor/Editor.cpp b/Editor/Editor.cpp index 1e15ced42..3e116f10c 100644 --- a/Editor/Editor.cpp +++ b/Editor/Editor.cpp @@ -565,8 +565,9 @@ void EditorComponent::Load() wiArchive archive(fileName, true); if (archive.IsOpen()) { - Scene& scene = wiRenderer::GetScene(); + Scene scene; scene.Serialize(archive); + wiRenderer::GetScene().Merge(scene); } } else if (!extension.compare("OBJ")) // wavefront-obj @@ -586,7 +587,7 @@ void EditorComponent::Load() main->activateComponent(this, 10, wiColor::Black); worldWnd->UpdateFromRenderer(); }); - main->activateComponent(loader,10,wiColor::Black); + main->activateComponent(loader, 10, wiColor::Black); ResetHistory(); } }).detach(); @@ -696,9 +697,8 @@ void EditorComponent::Load() ss << "Delete: DELETE button" << endl; ss << "Script Console / backlog: HOME button" << endl; ss << endl; - ss << "You can find sample models in the models directory. Try to load one." << endl; - ss << "You can also import models from .OBJ, .GLTF, .GLB, .WIO files." << endl; - ss << "You can also export models from Blender with the io_export_wicked_wi_bin.py script." << endl; + ss << "You can find sample scenes in the models directory. Try to load one." << endl; + ss << "You can also import models from .OBJ, .GLTF, .GLB files." << endl; ss << "You can find a program configuration file at Editor/config.ini" << endl; ss << "You can find sample LUA scripts in the scripts directory. Try to load one." << endl; ss << "You can find a startup script at Editor/startup.lua (this will be executed on program start)" << endl; @@ -759,7 +759,7 @@ void EditorComponent::FixedUpdate() void EditorComponent::Update(float dt) { Scene& scene = wiRenderer::GetScene(); - CameraComponent& camera = *wiRenderer::getCamera(); + CameraComponent& camera = wiRenderer::GetCamera(); // Follow camera proxy: if (cameraWnd->followCheckBox->IsEnabled() && cameraWnd->followCheckBox->GetCheck()) @@ -867,6 +867,7 @@ void EditorComponent::Update(float dt) XMStoreFloat3(&_move, move_rot); cameraWnd->camera_transform.Translate(_move); cameraWnd->camera_transform.RotateRollPitchYaw(XMFLOAT3(yDif, xDif, 0)); + camera.SetDirty(); } cameraWnd->camera_transform.UpdateTransform(); @@ -885,20 +886,21 @@ void EditorComponent::Update(float dt) else if (wiInputManager::GetInstance()->down(VK_LCONTROL)) { cameraWnd->camera_transform.Translate(XMFLOAT3(0, 0, yDif * 4)); + camera.SetDirty(); } else if(abs(xDif) + abs(yDif) > 0) { cameraWnd->camera_target.RotateRollPitchYaw(XMFLOAT3(yDif*2, xDif*2, 0)); + camera.SetDirty(); } cameraWnd->camera_target.UpdateTransform(); cameraWnd->camera_transform.UpdateParentedTransform(cameraWnd->camera_target); } - camera.UpdateCamera(&cameraWnd->camera_transform); // Begin picking: UINT pickMask = rendererWnd->GetPickType(); - RAY pickRay = wiRenderer::getPickRay((long)currentMouse.x, (long)currentMouse.y); + RAY pickRay = wiRenderer::GetPickRay((long)currentMouse.x, (long)currentMouse.y); { hovered.Clear(); @@ -1083,7 +1085,7 @@ void EditorComponent::Update(float dt) TransformComponent& transform = *scene.transforms.GetComponent(entity); transform.Translate(hovered.position); transform.Scale(XMFLOAT3(4, 4, 4)); - transform.MatrixTransform(XMLoadFloat3x3(&wiRenderer::getCamera()->rotationMatrix)); + transform.MatrixTransform(XMLoadFloat3x3(&wiRenderer::GetCamera().rotationMatrix)); scene.Component_Attach(entity, hovered.entity); } } @@ -1192,7 +1194,6 @@ void EditorComponent::Update(float dt) assert(picked.entity != INVALID_ENTITY); - objectWnd->SetEntity(picked.entity); emitterWnd->SetEntity(picked.entity); hairWnd->SetEntity(picked.entity); @@ -1205,10 +1206,16 @@ void EditorComponent::Update(float dt) if (picked.subsetIndex >= 0) { const ObjectComponent* object = scene.objects.GetComponent(picked.entity); - meshWnd->SetEntity(object->meshID); + if (object != nullptr) // maybe it was deleted... + { + meshWnd->SetEntity(object->meshID); - const MeshComponent* mesh = scene.meshes.GetComponent(object->meshID); - materialWnd->SetEntity(mesh->subsets[picked.subsetIndex].materialID); + const MeshComponent* mesh = scene.meshes.GetComponent(object->meshID); + if (mesh != nullptr && mesh->subsets.size() > picked.subsetIndex) + { + materialWnd->SetEntity(mesh->subsets[picked.subsetIndex].materialID); + } + } } else { @@ -1217,101 +1224,30 @@ void EditorComponent::Update(float dt) } - //// Delete - //if (wiInputManager::GetInstance()->press(VK_DELETE)) - //{ - // wiArchive* archive = AdvanceHistory(); - // *archive << HISTORYOP_DELETE; - // *archive << selected.size(); - // for (auto& x : selected) - // { - // *archive << x->transform->GetID(); + // Delete + if (wiInputManager::GetInstance()->press(VK_DELETE)) + { - // if (x->object != nullptr) - // { - // *archive << true; - // x->object->Serialize(*archive); - // x->object->mesh->Serialize(*archive); - // *archive << x->object->mesh->subsets.size(); - // for (auto& y : x->object->mesh->subsets) - // { - // y.material->Serialize(*archive); - // } + wiArchive* archive = AdvanceHistory(); + *archive << HISTORYOP_DELETE; - // wiRenderer::Remove(x->object); - // SAFE_DELETE(x->object); - // x->transform = nullptr; - // } - // else - // { - // *archive << false; - // } + *archive << selected.size(); + for (auto& x : selected) + { + *archive << x.entity; + } + for (auto& x : selected) + { + scene.Entity_Serialize(*archive, x.entity); + } + for (auto& x : selected) + { + scene.Entity_Remove(x.entity); + savedHierarchy.Remove_KeepSorted(x.entity); + } - // if (x->light != nullptr) - // { - // *archive << true; - // x->light->Serialize(*archive); - - // wiRenderer::Remove(x->light); - // SAFE_DELETE(x->light); - // x->transform = nullptr; - // } - // else - // { - // *archive << false; - // } - - // if (x->decal != nullptr) - // { - // *archive << true; - // x->decal->Serialize(*archive); - - // wiRenderer::Remove(x->decal); - // SAFE_DELETE(x->decal); - // x->transform = nullptr; - // } - // else - // { - // *archive << false; - // } - - // if (x->forceField != nullptr) - // { - // *archive << true; - // x->forceField->Serialize(*archive); - - // wiRenderer::Remove(x->forceField); - // SAFE_DELETE(x->forceField); - // x->transform = nullptr; - // } - // else - // { - // *archive << false; - // } - - // if (x->camera != nullptr) - // { - // *archive << true; - // x->camera->Serialize(*archive); - - // wiRenderer::Remove(x->camera); - // SAFE_DELETE(x->camera); - // x->camera = nullptr; - // } - // else - // { - // *archive << false; - // } - - // EnvironmentProbe* envProbe = dynamic_cast(x->transform); - // if (envProbe != nullptr) - // { - // wiRenderer::Remove(envProbe); - // SAFE_DELETE(envProbe); - // } - // } - // ClearSelected(); - //} + EndTranslate(); + } // Control operations... if (wiInputManager::GetInstance()->down(VK_CONTROL)) @@ -1439,6 +1375,8 @@ void EditorComponent::Update(float dt) __super::Update(dt); renderPath->Update(dt); + + camera.UpdateCamera(&cameraWnd->camera_transform); } void EditorComponent::Render() { @@ -1565,7 +1503,7 @@ void EditorComponent::Compose() return; } - CameraComponent* camera = wiRenderer::getCamera(); + const CameraComponent& camera = wiRenderer::GetCamera(); Scene& scene = wiRenderer::GetScene(); @@ -1577,7 +1515,7 @@ void EditorComponent::Compose() Entity entity = scene.lights.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1625,7 +1563,7 @@ void EditorComponent::Compose() Entity entity = scene.decals.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1660,7 +1598,7 @@ void EditorComponent::Compose() Entity entity = scene.forces.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1695,7 +1633,7 @@ void EditorComponent::Compose() const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1729,7 +1667,7 @@ void EditorComponent::Compose() Entity entity = scene.armatures.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1763,7 +1701,7 @@ void EditorComponent::Compose() Entity entity = scene.emitters.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1797,7 +1735,7 @@ void EditorComponent::Compose() Entity entity = scene.hairs.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - float dist = wiMath::Distance(transform.GetPosition(), camera->Eye) * 0.08f; + float dist = wiMath::Distance(transform.GetPosition(), camera.Eye) * 0.08f; wiImageEffects fx; fx.pos = transform.GetPosition(); @@ -1932,14 +1870,15 @@ void EditorComponent::EndTranslate() { // Save the parent's inverse worldmatrix: XMStoreFloat4x4(&parent->world_parent_inverse_bind, XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform_parent->world))); + + TransformComponent* transform_child = scene.transforms.GetComponent(x.entity); + if (transform_child != nullptr) + { + // Child updated immediately, to that it can be immediately attached to afterwards: + transform_child->UpdateParentedTransform(*transform_parent, parent->world_parent_inverse_bind); + } } - TransformComponent* transform_child = scene.transforms.GetComponent(x.entity); - if (transform_child != nullptr) - { - // Child updated immediately, to that it can be immediately attached to afterwards: - transform_child->UpdateParentedTransform(*transform_parent, parent->world_parent_inverse_bind); - } } } @@ -2010,7 +1949,9 @@ void EditorComponent::ConsumeHistoryOperation(bool undo) *archive >> start >> end; translator.enabled = true; - TransformComponent& transform = *wiRenderer::GetScene().transforms.GetComponent(translator.entityID); + Scene& scene = wiRenderer::GetScene(); + + TransformComponent& transform = *scene.transforms.GetComponent(translator.entityID); transform.ClearTransform(); if (undo) { @@ -2022,85 +1963,35 @@ void EditorComponent::ConsumeHistoryOperation(bool undo) } } break; - //case HISTORYOP_DELETE: - // { - // Model* model = nullptr; - // if (undo) - // { - // model = new Model; - // } + case HISTORYOP_DELETE: + { + Scene& scene = wiRenderer::GetScene(); - // size_t count; - // *archive >> count; - // for (size_t i = 0; i < count; ++i) - // { - // // Entity ID - // uint64_t id; - // *archive >> id; + size_t count; + *archive >> count; + vector deletedEntities(count); + for (size_t i = 0; i < count; ++i) + { + *archive >> deletedEntities[i]; + } + if (undo) + { + for (size_t i = 0; i < count; ++i) + { + scene.Entity_Serialize(*archive); + } + } + else + { + for (size_t i = 0; i < count; ++i) + { + scene.Entity_Remove(deletedEntities[i]); + } + } - // bool tmp; - - // // object - // *archive >> tmp; - // if (tmp) - // { - // if (undo) - // { - // Object* object = new Object; - // object->Serialize(*archive); - // object->SetID(id); - // object->mesh = new Mesh; - // object->mesh->Serialize(*archive); - // size_t subsetCount; - // *archive >> subsetCount; - // for (size_t i = 0; i < subsetCount; ++i) - // { - // object->mesh->subsets[i].material = new Material; - // object->mesh->subsets[i].material->Serialize(*archive); - // } - // object->mesh->CreateRenderData(); - // model->Add(object); - // } - // } - - // // light - // *archive >> tmp; - // if (tmp) - // { - // Light* light = new Light; - // light->Serialize(*archive); - // light->SetID(id); - // model->Add(light); - // } - - // // decal - // *archive >> tmp; - // if (tmp) - // { - // Decal* decal = new Decal; - // decal->Serialize(*archive); - // decal->SetID(id); - // model->Add(decal); - // } - - // // force field - // *archive >> tmp; - // if (tmp) - // { - // ForceField* force = new ForceField; - // force->Serialize(*archive); - // force->SetID(id); - // model->Add(force); - // } - // } - - // if (undo) - // { - // wiRenderer::AddModel(model); - // } - // } - // break; + } + break; case HISTORYOP_SELECTION: { EndTranslate(); diff --git a/Editor/EnvProbeWindow.cpp b/Editor/EnvProbeWindow.cpp index 35e9015e5..b6aeadff1 100644 --- a/Editor/EnvProbeWindow.cpp +++ b/Editor/EnvProbeWindow.cpp @@ -35,7 +35,7 @@ EnvProbeWindow::EnvProbeWindow(wiGUI* gui) : GUI(gui) generateButton->SetPos(XMFLOAT2(x, y += step)); generateButton->OnClick([](wiEventArgs args) { XMFLOAT3 pos; - XMStoreFloat3(&pos, XMVectorAdd(wiRenderer::getCamera()->GetEye(), wiRenderer::getCamera()->GetAt() * 4)); + XMStoreFloat3(&pos, XMVectorAdd(wiRenderer::GetCamera().GetEye(), wiRenderer::GetCamera().GetAt() * 4)); wiRenderer::GetScene().Entity_CreateEnvironmentProbe("editorProbe", pos); }); envProbeWindow->AddWidget(generateButton); diff --git a/Editor/ModelImporter.h b/Editor/ModelImporter.h index 27f3a74df..d76bdc7f3 100644 --- a/Editor/ModelImporter.h +++ b/Editor/ModelImporter.h @@ -1,8 +1,6 @@ #pragma once -#include "wiECS.h" - #include -wiECS::Entity ImportModel_OBJ(const std::string& fileName); -wiECS::Entity ImportModel_GLTF(const std::string& fileName); +void ImportModel_OBJ(const std::string& fileName); +void ImportModel_GLTF(const std::string& fileName); diff --git a/Editor/ModelImporter_GLTF.cpp b/Editor/ModelImporter_GLTF.cpp index 9682e7f68..e1fa360cd 100644 --- a/Editor/ModelImporter_GLTF.cpp +++ b/Editor/ModelImporter_GLTF.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "wiSceneSystem.h" #include "ModelImporter.h" #include "Utility/stb_image.h" @@ -148,7 +149,7 @@ void RegisterTexture2D(tinygltf::Image *image) struct LoaderState { tinygltf::Model gltfModel; - Entity modelEntity; + Scene scene; unordered_map entityMap; vector materialArray; vector meshArray; @@ -163,14 +164,12 @@ void LoadNode(tinygltf::Node* node, Entity parent, LoaderState& state) return; } - Scene& scene = wiRenderer::GetScene(); - Entity entity = INVALID_ENTITY; if(node->mesh >= 0) { - entity = scene.Entity_CreateObject(node->name); - ObjectComponent& object = *scene.objects.GetComponent(entity); + entity = state.scene.Entity_CreateObject(node->name); + ObjectComponent& object = *state.scene.objects.GetComponent(entity); if (node->mesh < state.meshArray.size()) { @@ -178,7 +177,7 @@ void LoadNode(tinygltf::Node* node, Entity parent, LoaderState& state) if (node->skin >= 0) { - MeshComponent& mesh = *scene.meshes.GetComponent(object.meshID); + MeshComponent& mesh = *state.scene.meshes.GetComponent(object.meshID); assert(!mesh.vertex_boneindices.empty()); mesh.armatureID = state.armatureArray[node->skin]; } @@ -198,18 +197,18 @@ void LoadNode(tinygltf::Node* node, Entity parent, LoaderState& state) node->name = ss.str(); } - entity = scene.Entity_CreateCamera(node->name, (float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); + entity = state.scene.Entity_CreateCamera(node->name, (float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); } if (entity == INVALID_ENTITY) { entity = CreateEntity(); - scene.transforms.Create(entity); + state.scene.transforms.Create(entity); } state.entityMap[node] = entity; - TransformComponent& transform = *scene.transforms.GetComponent(entity); + TransformComponent& transform = *state.scene.transforms.GetComponent(entity); if (!node->scale.empty()) { transform.scale_local = XMFLOAT3((float)node->scale[0], (float)node->scale[1], (float)node->scale[2]); @@ -229,7 +228,7 @@ void LoadNode(tinygltf::Node* node, Entity parent, LoaderState& state) if (parent != INVALID_ENTITY) { - scene.Component_Attach(entity, parent); + state.scene.Component_Attach(entity, parent); } if (!node->children.empty()) @@ -241,7 +240,7 @@ void LoadNode(tinygltf::Node* node, Entity parent, LoaderState& state) } } -Entity ImportModel_GLTF(const std::string& fileName) +void ImportModel_GLTF(const std::string& fileName) { string directory, name; wiHelper::SplitPath(fileName, directory, name); @@ -269,22 +268,19 @@ Entity ImportModel_GLTF(const std::string& fileName) } if (!ret) { wiHelper::messageBox(err, "GLTF error!"); - return INVALID_ENTITY; } - Scene& scene = wiRenderer::GetScene(); - - state.modelEntity = scene.Entity_CreateModel(name); - TransformComponent& model_transform = *scene.transforms.GetComponent(state.modelEntity); + Entity rootEntity = CreateEntity(); + state.scene.transforms.Create(rootEntity); // Create materials: for (auto& x : state.gltfModel.materials) { - Entity materialEntity = scene.Entity_CreateMaterial(x.name); + Entity materialEntity = state.scene.Entity_CreateMaterial(x.name); state.materialArray.push_back(materialEntity); - MaterialComponent& material = *scene.materials.GetComponent(materialEntity); + MaterialComponent& material = *state.scene.materials.GetComponent(materialEntity); material.baseColor = XMFLOAT4(1, 1, 1, 1); material.roughness = 1.0f; @@ -500,18 +496,18 @@ Entity ImportModel_GLTF(const std::string& fileName) if (state.materialArray.empty()) { - Entity materialEntity = scene.Entity_CreateMaterial("GLTFImport_defaultMaterial"); + Entity materialEntity = state.scene.Entity_CreateMaterial("GLTFImport_defaultMaterial"); state.materialArray.push_back(materialEntity); } // Create meshes: for (auto& x : state.gltfModel.meshes) { - Entity meshEntity = scene.Entity_CreateMesh(x.name); + Entity meshEntity = state.scene.Entity_CreateMesh(x.name); state.meshArray.push_back(meshEntity); - MeshComponent& mesh = *scene.meshes.GetComponent(meshEntity); + MeshComponent& mesh = *state.scene.meshes.GetComponent(meshEntity); for (auto& prim : x.primitives) { @@ -676,10 +672,10 @@ Entity ImportModel_GLTF(const std::string& fileName) for (auto& skin : state.gltfModel.skins) { Entity armatureEntity = CreateEntity(); - scene.names.Create(armatureEntity) = skin.name; - scene.layers.Create(armatureEntity); - TransformComponent& transform = scene.transforms.Create(armatureEntity); - ArmatureComponent& armature = scene.armatures.Create(armatureEntity); + state.scene.names.Create(armatureEntity) = skin.name; + state.scene.layers.Create(armatureEntity); + TransformComponent& transform = state.scene.transforms.Create(armatureEntity); + ArmatureComponent& armature = state.scene.armatures.Create(armatureEntity); state.armatureArray.push_back(armatureEntity); @@ -706,7 +702,7 @@ Entity ImportModel_GLTF(const std::string& fileName) const tinygltf::Scene &gltfScene = state.gltfModel.scenes[max(0, state.gltfModel.defaultScene)]; for (size_t i = 0; i < gltfScene.nodes.size(); i++) { - LoadNode(&state.gltfModel.nodes[gltfScene.nodes[i]], state.modelEntity, state); + LoadNode(&state.gltfModel.nodes[gltfScene.nodes[i]], rootEntity, state); } // Create armature-bone mappings: @@ -714,7 +710,7 @@ Entity ImportModel_GLTF(const std::string& fileName) for (auto& skin : state.gltfModel.skins) { Entity entity = state.armatureArray[armatureIndex++]; - ArmatureComponent& armature = *scene.armatures.GetComponent(entity); + ArmatureComponent& armature = *state.scene.armatures.GetComponent(entity); const size_t jointCount = skin.joints.size(); @@ -736,8 +732,8 @@ Entity ImportModel_GLTF(const std::string& fileName) for (auto& anim : state.gltfModel.animations) { Entity entity = CreateEntity(); - scene.names.Create(entity) = anim.name; - AnimationComponent& animationcomponent = scene.animations.Create(entity); + state.scene.names.Create(entity) = anim.name; + AnimationComponent& animationcomponent = state.scene.animations.Create(entity); for (auto& channel : anim.channels) { @@ -834,10 +830,17 @@ Entity ImportModel_GLTF(const std::string& fileName) if (transform_to_LH) { - TransformComponent& transform = *scene.transforms.GetComponent(state.modelEntity); + TransformComponent& transform = *state.scene.transforms.GetComponent(rootEntity); transform.scale_local.z = -transform.scale_local.z; transform.SetDirty(); } - return state.modelEntity; + // We parented everything to a root transform, but we actually don't need that after loading model. + // Apply every transformation according to root transform, then remove root all together. + // We could also keep it, but right now, it seems better to delete and have less hierarchy + state.scene.Update(0); + state.scene.Entity_Remove(rootEntity); + + wiRenderer::GetScene().Merge(state.scene); + } diff --git a/Editor/ModelImporter_OBJ.cpp b/Editor/ModelImporter_OBJ.cpp index 4710ada6b..f4a7d9593 100644 --- a/Editor/ModelImporter_OBJ.cpp +++ b/Editor/ModelImporter_OBJ.cpp @@ -1,4 +1,5 @@ #include "stdafx.h" +#include "wiSceneSystem.h" #include "ModelImporter.h" #define TINYOBJLOADER_IMPLEMENTATION @@ -14,15 +15,13 @@ using namespace wiECS; // Transform the data from OBJ space to engine-space: static const bool transform_to_LH = true; -Entity ImportModel_OBJ(const std::string& fileName) +void ImportModel_OBJ(const std::string& fileName) { string directory, name; wiHelper::SplitPath(fileName, directory, name); wiHelper::RemoveExtensionFromFileName(name); - - Scene& scene = wiRenderer::GetScene(); - + Scene scene; tinyobj::attrib_t obj_attrib; vector obj_shapes; @@ -31,13 +30,13 @@ Entity ImportModel_OBJ(const std::string& fileName) bool success = tinyobj::LoadObj(&obj_attrib, &obj_shapes, &obj_materials, &obj_errors, fileName.c_str(), directory.c_str(), true); + if (!obj_errors.empty()) + { + wiBackLog::post(obj_errors.c_str()); + } + if (success) { - Entity modelEntity = scene.Entity_CreateModel(name); - TransformComponent& model_transform = *scene.transforms.GetComponent(modelEntity); - - model_transform.UpdateTransform(); // everything will be attached to this, so values need to be up to date - // Load material library: vector materialLibrary = {}; for (auto& obj_material : obj_materials) @@ -99,8 +98,6 @@ Entity ImportModel_OBJ(const std::string& fileName) ObjectComponent& object = *scene.objects.GetComponent(objectEntity); MeshComponent& mesh = *scene.meshes.GetComponent(meshEntity); - scene.Component_Attach(objectEntity, modelEntity); - object.meshID = meshEntity; unordered_map registered_materialIndices = {}; @@ -189,14 +186,10 @@ Entity ImportModel_OBJ(const std::string& fileName) mesh.CreateRenderData(); } - return modelEntity; + wiRenderer::GetScene().Merge(scene); } - - if (!obj_errors.empty()) + else { - wiBackLog::post(obj_errors.c_str()); wiHelper::messageBox("OBJ import failed! Check backlog for errors!", "Error!"); } - - return INVALID_ENTITY; } diff --git a/Editor/Translator.cpp b/Editor/Translator.cpp index b10d003fa..aef393b1e 100644 --- a/Editor/Translator.cpp +++ b/Editor/Translator.cpp @@ -211,7 +211,7 @@ void Translator::Update() dragEnded = false; XMFLOAT4 pointer = wiInputManager::GetInstance()->getpointer(); - CameraComponent* cam = wiRenderer::getCamera(); + const CameraComponent& cam = wiRenderer::GetCamera(); XMVECTOR pos = transform.GetPositionV(); if (enabled) @@ -219,11 +219,11 @@ void Translator::Update() if (!dragging) { - XMMATRIX P = cam->GetProjection(); - XMMATRIX V = cam->GetView(); + XMMATRIX P = cam.GetProjection(); + XMMATRIX V = cam.GetView(); XMMATRIX W = XMMatrixIdentity(); - dist = wiMath::Distance(transform.GetPosition(), cam->Eye) * 0.05f; + dist = wiMath::Distance(transform.GetPosition(), cam.Eye) * 0.05f; XMVECTOR o, x, y, z, p, xy, xz, yz; @@ -237,13 +237,13 @@ void Translator::Update() yz = o + XMVectorSet(0, 0.5f, 0.5f, 0) * dist; - o = XMVector3Project(o, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - x = XMVector3Project(x, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - y = XMVector3Project(y, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - z = XMVector3Project(z, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - xy = XMVector3Project(xy, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - xz = XMVector3Project(xz, 0, 0, cam->width, cam->height, 0, 1, P, V, W); - yz = XMVector3Project(yz, 0, 0, cam->width, cam->height, 0, 1, P, V, W); + o = XMVector3Project(o, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + x = XMVector3Project(x, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + y = XMVector3Project(y, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + z = XMVector3Project(z, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + xy = XMVector3Project(xy, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + xz = XMVector3Project(xz, 0, 0, cam.width, cam.height, 0, 1, P, V, W); + yz = XMVector3Project(yz, 0, 0, cam.width, cam.height, 0, 1, P, V, W); XMVECTOR oDisV = XMVector3Length(o - p); XMVECTOR xyDisV = XMVector3Length(xy - p); @@ -298,19 +298,19 @@ void Translator::Update() if (state == TRANSLATOR_X) { XMVECTOR axis = XMVectorSet(1, 0, 0, 0); - XMVECTOR wrong = XMVector3Cross(cam->GetAt(), axis); + XMVECTOR wrong = XMVector3Cross(cam.GetAt(), axis); planeNormal = XMVector3Cross(wrong, axis); } else if (state == TRANSLATOR_Y) { XMVECTOR axis = XMVectorSet(0, 1, 0, 0); - XMVECTOR wrong = XMVector3Cross(cam->GetAt(), axis); + XMVECTOR wrong = XMVector3Cross(cam.GetAt(), axis); planeNormal = XMVector3Cross(wrong, axis); } else if (state == TRANSLATOR_Z) { XMVECTOR axis = XMVectorSet(0, 0, 1, 0); - XMVECTOR wrong = XMVector3Cross(cam->GetAt(), axis); + XMVECTOR wrong = XMVector3Cross(cam.GetAt(), axis); planeNormal = XMVector3Cross(wrong, axis); } else if (state == TRANSLATOR_XY) @@ -328,19 +328,19 @@ void Translator::Update() else { // xyz - planeNormal = cam->GetAt(); + planeNormal = cam.GetAt(); } plane = XMPlaneFromPointNormal(pos, XMVector3Normalize(planeNormal)); - RAY ray = wiRenderer::getPickRay((long)pointer.x, (long)pointer.y); + RAY ray = wiRenderer::GetPickRay((long)pointer.x, (long)pointer.y); XMVECTOR rayOrigin = XMLoadFloat3(&ray.origin); XMVECTOR rayDir = XMLoadFloat3(&ray.direction); - XMVECTOR intersection = XMPlaneIntersectLine(plane, rayOrigin, rayOrigin + rayDir*cam->zFarP); + XMVECTOR intersection = XMPlaneIntersectLine(plane, rayOrigin, rayOrigin + rayDir*cam.zFarP); - ray = wiRenderer::getPickRay((long)prevPointer.x, (long)prevPointer.y); + ray = wiRenderer::GetPickRay((long)prevPointer.x, (long)prevPointer.y); rayOrigin = XMLoadFloat3(&ray.origin); rayDir = XMLoadFloat3(&ray.direction); - XMVECTOR intersectionPrev = XMPlaneIntersectLine(plane, rayOrigin, rayOrigin + rayDir*cam->zFarP); + XMVECTOR intersectionPrev = XMPlaneIntersectLine(plane, rayOrigin, rayOrigin + rayDir*cam.zFarP); XMVECTOR deltaV; if (state == TRANSLATOR_X) @@ -433,7 +433,7 @@ void Translator::Update() prevPointer = pointer; } -void Translator::Draw(CameraComponent* camera, GRAPHICSTHREAD threadID) +void Translator::Draw(const CameraComponent& camera, GRAPHICSTHREAD threadID) { Scene& scene = wiRenderer::GetScene(); @@ -448,7 +448,7 @@ void Translator::Draw(CameraComponent* camera, GRAPHICSTHREAD threadID) device->EventBegin("Editor - Translator", threadID); - XMMATRIX VP = camera->GetViewProjection(); + XMMATRIX VP = camera.GetViewProjection(); wiRenderer::MiscCB sb; diff --git a/Editor/Translator.h b/Editor/Translator.h index abf8edf20..46a401e7a 100644 --- a/Editor/Translator.h +++ b/Editor/Translator.h @@ -15,7 +15,7 @@ public: ~Translator(); void Update(); - void Draw(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); + void Draw(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); wiECS::Entity entityID = wiECS::INVALID_ENTITY; diff --git a/Editor/main.cpp b/Editor/main.cpp index 2112fef20..a7e980ab4 100644 --- a/Editor/main.cpp +++ b/Editor/main.cpp @@ -214,7 +214,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int height = HIWORD(lParam); wiRenderer::GetDevice()->SetResolution(width, height); - wiRenderer::getCamera()->CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); + wiRenderer::GetCamera().CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); } } break; diff --git a/Template_Windows/main.cpp b/Template_Windows/main.cpp index 6a7919a9f..4ce57a40f 100644 --- a/Template_Windows/main.cpp +++ b/Template_Windows/main.cpp @@ -178,7 +178,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int height = HIWORD(lParam); wiRenderer::GetDevice()->SetResolution(width, height); - wiRenderer::getCamera()->CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); + wiRenderer::GetCamera().CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); } } break; diff --git a/Tests/main.cpp b/Tests/main.cpp index aff54c571..d10f0ce5f 100644 --- a/Tests/main.cpp +++ b/Tests/main.cpp @@ -167,7 +167,7 @@ LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) int height = HIWORD(lParam); wiRenderer::GetDevice()->SetResolution(width, height); - wiRenderer::getCamera()->CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); + wiRenderer::GetCamera().CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); } } break; diff --git a/WickedEngine/DeferredRenderableComponent.cpp b/WickedEngine/DeferredRenderableComponent.cpp index f0ddae85d..0011dc4d2 100644 --- a/WickedEngine/DeferredRenderableComponent.cpp +++ b/WickedEngine/DeferredRenderableComponent.cpp @@ -99,7 +99,7 @@ void DeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) { wiProfiler::GetInstance().BeginRange("Opaque Scene", wiProfiler::DOMAIN_GPU, threadID); - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); wiImageEffects fx((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y); @@ -109,7 +109,7 @@ void DeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) rtGBuffer.Activate(threadID, 0, 0, 0, 0); { wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); - wiRenderer::DrawWorld(wiRenderer::getCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEFERRED, getHairParticlesEnabled(), true, getLayerMask()); + wiRenderer::DrawWorld(wiRenderer::GetCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEFERRED, getHairParticlesEnabled(), true, getLayerMask()); } wiRenderer::GetDevice()->TransitionBarrier(dsv, ARRAYSIZE(dsv), RESOURCE_STATE_DEPTH_WRITE, RESOURCE_STATE_COPY_SOURCE, threadID); @@ -139,7 +139,7 @@ void DeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) rtGBuffer.Set(threadID); { - wiRenderer::DrawDecals(wiRenderer::getCamera(), threadID); + wiRenderer::DrawDecals(wiRenderer::GetCamera(), threadID); } rtGBuffer.Deactivate(threadID); @@ -149,7 +149,7 @@ void DeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) rtLight.Activate(threadID, rtGBuffer.depth); { wiRenderer::GetDevice()->BindResource(PS, getSSREnabled() ? rtSSR.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_SSR, threadID); - wiRenderer::DrawLights(wiRenderer::getCamera(), threadID); + wiRenderer::DrawLights(wiRenderer::GetCamera(), threadID); } diff --git a/WickedEngine/ForwardRenderableComponent.cpp b/WickedEngine/ForwardRenderableComponent.cpp index 098e28b5d..69c0dc303 100644 --- a/WickedEngine/ForwardRenderableComponent.cpp +++ b/WickedEngine/ForwardRenderableComponent.cpp @@ -81,7 +81,7 @@ void ForwardRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) { wiProfiler::GetInstance().BeginRange("Opaque Scene", wiProfiler::DOMAIN_GPU, threadID); - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); GPUResource* dsv[] = { rtMain.depth->GetTexture() }; wiRenderer::GetDevice()->TransitionBarrier(dsv, ARRAYSIZE(dsv), RESOURCE_STATE_DEPTH_READ, RESOURCE_STATE_DEPTH_WRITE, threadID); @@ -93,7 +93,7 @@ void ForwardRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); wiRenderer::GetDevice()->BindResource(PS, getSSAOEnabled() ? rtSSAO.back().GetTexture() : wiTextureHelper::getInstance()->getWhite(), TEXSLOT_RENDERABLECOMPONENT_SSAO, threadID); wiRenderer::GetDevice()->BindResource(PS, getSSREnabled() ? rtSSR.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_SSR, threadID); - wiRenderer::DrawWorld(wiRenderer::getCamera(), getTessellationEnabled(), threadID, SHADERTYPE_FORWARD, getHairParticlesEnabled(), true, getLayerMask()); + wiRenderer::DrawWorld(wiRenderer::GetCamera(), getTessellationEnabled(), threadID, SHADERTYPE_FORWARD, getHairParticlesEnabled(), true, getLayerMask()); wiRenderer::DrawSky(threadID); } rtMain.Deactivate(threadID); diff --git a/WickedEngine/PathTracingRenderableComponent.cpp b/WickedEngine/PathTracingRenderableComponent.cpp index 9890e4607..684a04f25 100644 --- a/WickedEngine/PathTracingRenderableComponent.cpp +++ b/WickedEngine/PathTracingRenderableComponent.cpp @@ -102,14 +102,21 @@ void PathTracingRenderableComponent::Update(float dt) { const Scene& scene = wiRenderer::GetScene(); - for (size_t i = 0; i < scene.transforms.GetCount(); ++i) + if (wiRenderer::GetCamera().IsDirty()) { - const TransformComponent& transform = scene.transforms[i]; - - if (transform.IsDirty()) + sam = -1; + } + else + { + for (size_t i = 0; i < scene.transforms.GetCount(); ++i) { - sam = -1; - break; + const TransformComponent& transform = scene.transforms[i]; + + if (transform.IsDirty()) + { + sam = -1; + break; + } } } sam++; @@ -132,9 +139,9 @@ void PathTracingRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) { wiProfiler::GetInstance().BeginRange("Traced Scene", wiProfiler::DOMAIN_GPU, threadID); - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); - wiRenderer::DrawTracedScene(wiRenderer::getCamera(), traceResult, threadID); + wiRenderer::DrawTracedScene(wiRenderer::GetCamera(), traceResult, threadID); diff --git a/WickedEngine/Renderable3DComponent.cpp b/WickedEngine/Renderable3DComponent.cpp index f0b0307bc..bff78bee8 100644 --- a/WickedEngine/Renderable3DComponent.cpp +++ b/WickedEngine/Renderable3DComponent.cpp @@ -275,12 +275,12 @@ void Renderable3DComponent::RenderReflections(GRAPHICSTHREAD threadID) if (wiRenderer::IsRequestedReflectionRendering()) { - wiRenderer::UpdateCameraCB(wiRenderer::getRefCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetRefCamera(), threadID); rtReflection.Activate(threadID); { // reverse clipping if underwater XMFLOAT4 water = wiRenderer::GetWaterPlane(); - if (XMVectorGetX(XMPlaneDot(XMLoadFloat4(&water), wiRenderer::getCamera()->GetEye())) < 0) + if (XMVectorGetX(XMPlaneDot(XMLoadFloat4(&water), wiRenderer::GetCamera().GetEye())) < 0) { water.x *= -1; water.y *= -1; @@ -289,7 +289,7 @@ void Renderable3DComponent::RenderReflections(GRAPHICSTHREAD threadID) wiRenderer::SetClipPlane(water, threadID); - wiRenderer::DrawWorld(wiRenderer::getRefCamera(), false, threadID, SHADERTYPE_TEXTURE, getHairParticlesReflectionEnabled(), false, getLayerMask()); + wiRenderer::DrawWorld(wiRenderer::GetRefCamera(), false, threadID, SHADERTYPE_TEXTURE, getHairParticlesReflectionEnabled(), false, getLayerMask()); wiRenderer::DrawSky(threadID); wiRenderer::SetClipPlane(XMFLOAT4(0, 0, 0, 0), threadID); @@ -341,7 +341,7 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende } wiRenderer::GetDevice()->EventEnd(threadID); - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); if (getStereogramEnabled()) { @@ -351,7 +351,7 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende wiProfiler::GetInstance().BeginRange("Secondary Scene", wiProfiler::DOMAIN_GPU, threadID); XMVECTOR sunDirection = XMLoadFloat3(&wiRenderer::GetScene().sunDirection); - if (getLightShaftsEnabled() && XMVectorGetX(XMVector3Dot(sunDirection, wiRenderer::getCamera()->GetAt())) > 0) + if (getLightShaftsEnabled() && XMVectorGetX(XMVector3Dot(sunDirection, wiRenderer::GetCamera().GetAt())) > 0) { wiRenderer::GetDevice()->EventBegin("Light Shafts", threadID); wiRenderer::GetDevice()->UnbindResources(TEXSLOT_ONDEMAND0, TEXSLOT_ONDEMAND_COUNT, threadID); @@ -364,7 +364,7 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende fxs.blendFlag = BLENDMODE_OPAQUE; XMVECTOR sunPos = XMVector3Project(sunDirection * 100000, 0, 0, (float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 1.0f, - wiRenderer::getCamera()->GetProjection(), wiRenderer::getCamera()->GetView(), XMMatrixIdentity()); + wiRenderer::GetCamera().GetProjection(), wiRenderer::GetCamera().GetView(), XMMatrixIdentity()); { XMStoreFloat2(&fxs.sunPos, sunPos); wiImage::Draw(rtSun[0].GetTextureResolvedMSAA(threadID), fxs, threadID); @@ -376,13 +376,13 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende if (getVolumeLightsEnabled()) { rtVolumetricLights.Activate(threadID, 0, 0, 0, 0); - wiRenderer::DrawVolumeLights(wiRenderer::getCamera(), threadID); + wiRenderer::DrawVolumeLights(wiRenderer::GetCamera(), threadID); } if (getEmittedParticlesEnabled()) { rtParticle.Activate(threadID, 0, 0, 0, 0); - wiRenderer::DrawSoftParticles(wiRenderer::getCamera(), false, threadID); + wiRenderer::DrawSoftParticles(wiRenderer::GetCamera(), false, threadID); } rtWaterRipple.Activate(threadID, 0, 0, 0, 0); { @@ -408,7 +408,7 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende RenderTransparentScene(rtSceneCopy, threadID); wiRenderer::DrawTrails(threadID, rtSceneCopy.GetTexture()); - wiRenderer::DrawLightVisualizers(wiRenderer::getCamera(), threadID); + wiRenderer::DrawLightVisualizers(wiRenderer::GetCamera(), threadID); fx.presentFullScreen = true; @@ -439,14 +439,14 @@ void Renderable3DComponent::RenderSecondaryScene(wiRenderTarget& mainRT, wiRende wiRenderer::DrawLensFlares(threadID); } - wiRenderer::DrawDebugWorld(wiRenderer::getCamera(), threadID); + wiRenderer::DrawDebugWorld(wiRenderer::GetCamera(), threadID); } if (getEmittedParticlesEnabled()) { wiRenderer::GetDevice()->UnbindResources(TEXSLOT_ONDEMAND0, 1, threadID); rtParticle.Activate(threadID, 0, 0, 0, 0); - wiRenderer::DrawSoftParticles(wiRenderer::getCamera(), true, threadID); + wiRenderer::DrawSoftParticles(wiRenderer::GetCamera(), true, threadID); } wiProfiler::GetInstance().EndRange(threadID); // Secondary Scene @@ -458,7 +458,7 @@ void Renderable3DComponent::RenderTransparentScene(wiRenderTarget& refractionRT, wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); wiRenderer::GetDevice()->BindResource(PS, refractionRT.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_REFRACTION, threadID); wiRenderer::GetDevice()->BindResource(PS, rtWaterRipple.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_WATERRIPPLES, threadID); - wiRenderer::DrawWorldTransparent(wiRenderer::getCamera(), SHADERTYPE_FORWARD, threadID, false, true, getLayerMask()); + wiRenderer::DrawWorldTransparent(wiRenderer::GetCamera(), SHADERTYPE_FORWARD, threadID, false, true, getLayerMask()); wiProfiler::GetInstance().EndRange(threadID); // Transparent Scene } diff --git a/WickedEngine/TiledDeferredRenderableComponent.cpp b/WickedEngine/TiledDeferredRenderableComponent.cpp index 0ffe0ffa8..7329eb115 100644 --- a/WickedEngine/TiledDeferredRenderableComponent.cpp +++ b/WickedEngine/TiledDeferredRenderableComponent.cpp @@ -27,7 +27,7 @@ void TiledDeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) { wiProfiler::GetInstance().BeginRange("Opaque Scene", wiProfiler::DOMAIN_GPU, threadID); - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); wiImageEffects fx((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y); @@ -37,7 +37,7 @@ void TiledDeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) rtGBuffer.Activate(threadID, 0, 0, 0, 0); { wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); - wiRenderer::DrawWorld(wiRenderer::getCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEFERRED, getHairParticlesEnabled(), true, getLayerMask()); + wiRenderer::DrawWorld(wiRenderer::GetCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEFERRED, getHairParticlesEnabled(), true, getLayerMask()); } @@ -69,7 +69,7 @@ void TiledDeferredRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) rtGBuffer.Set(threadID); { - wiRenderer::DrawDecals(wiRenderer::getCamera(), threadID); + wiRenderer::DrawDecals(wiRenderer::GetCamera(), threadID); } rtGBuffer.Deactivate(threadID); @@ -200,7 +200,7 @@ void TiledDeferredRenderableComponent::RenderTransparentScene(wiRenderTarget& re wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); wiRenderer::GetDevice()->BindResource(PS, refractionRT.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_REFRACTION, threadID); wiRenderer::GetDevice()->BindResource(PS, rtWaterRipple.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_WATERRIPPLES, threadID); - wiRenderer::DrawWorldTransparent(wiRenderer::getCamera(), SHADERTYPE_TILEDFORWARD, threadID, getHairParticlesEnabled(), true, getLayerMask()); + wiRenderer::DrawWorldTransparent(wiRenderer::GetCamera(), SHADERTYPE_TILEDFORWARD, threadID, getHairParticlesEnabled(), true, getLayerMask()); wiProfiler::GetInstance().EndRange(); // Transparent Scene } diff --git a/WickedEngine/TiledForwardRenderableComponent.cpp b/WickedEngine/TiledForwardRenderableComponent.cpp index 1a0e9b85b..13c1bf3f5 100644 --- a/WickedEngine/TiledForwardRenderableComponent.cpp +++ b/WickedEngine/TiledForwardRenderableComponent.cpp @@ -18,7 +18,7 @@ TiledForwardRenderableComponent::~TiledForwardRenderableComponent() void TiledForwardRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) { - wiRenderer::UpdateCameraCB(wiRenderer::getCamera(), threadID); + wiRenderer::UpdateCameraCB(wiRenderer::GetCamera(), threadID); GPUResource* dsv[] = { rtMain.depth->GetTexture() }; wiRenderer::GetDevice()->TransitionBarrier(dsv, ARRAYSIZE(dsv), RESOURCE_STATE_DEPTH_READ, RESOURCE_STATE_DEPTH_WRITE, threadID); @@ -28,7 +28,7 @@ void TiledForwardRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) wiProfiler::GetInstance().BeginRange("Z-Prepass", wiProfiler::DOMAIN_GPU, threadID); rtMain.Activate(threadID, 0, 0, 0, 0, true); // depth prepass { - wiRenderer::DrawWorld(wiRenderer::getCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEPTHONLY, getHairParticlesEnabled(), true, getLayerMask()); + wiRenderer::DrawWorld(wiRenderer::GetCamera(), getTessellationEnabled(), threadID, SHADERTYPE_DEPTHONLY, getHairParticlesEnabled(), true, getLayerMask()); } wiProfiler::GetInstance().EndRange(threadID); @@ -60,7 +60,7 @@ void TiledForwardRenderableComponent::RenderScene(GRAPHICSTHREAD threadID) wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); wiRenderer::GetDevice()->BindResource(PS, getSSAOEnabled() ? rtSSAO.back().GetTexture() : wiTextureHelper::getInstance()->getWhite(), TEXSLOT_RENDERABLECOMPONENT_SSAO, threadID); wiRenderer::GetDevice()->BindResource(PS, getSSREnabled() ? rtSSR.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_SSR, threadID); - wiRenderer::DrawWorld(wiRenderer::getCamera(), getTessellationEnabled(), threadID, SHADERTYPE_TILEDFORWARD, true, true); + wiRenderer::DrawWorld(wiRenderer::GetCamera(), getTessellationEnabled(), threadID, SHADERTYPE_TILEDFORWARD, true, true); wiRenderer::DrawSky(threadID); } rtMain.Deactivate(threadID); @@ -122,7 +122,7 @@ void TiledForwardRenderableComponent::RenderTransparentScene(wiRenderTarget& ref wiRenderer::GetDevice()->BindResource(PS, getReflectionsEnabled() ? rtReflection.GetTexture() : wiTextureHelper::getInstance()->getTransparent(), TEXSLOT_RENDERABLECOMPONENT_REFLECTION, threadID); wiRenderer::GetDevice()->BindResource(PS, refractionRT.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_REFRACTION, threadID); wiRenderer::GetDevice()->BindResource(PS, rtWaterRipple.GetTexture(), TEXSLOT_RENDERABLECOMPONENT_WATERRIPPLES, threadID); - wiRenderer::DrawWorldTransparent(wiRenderer::getCamera(), SHADERTYPE_TILEDFORWARD, threadID, getHairParticlesEnabled(), true); + wiRenderer::DrawWorldTransparent(wiRenderer::GetCamera(), SHADERTYPE_TILEDFORWARD, threadID, getHairParticlesEnabled(), true); wiProfiler::GetInstance().EndRange(threadID); // Transparent Scene } diff --git a/WickedEngine/wiECS.h b/WickedEngine/wiECS.h index 367a93ea9..74aec5b86 100644 --- a/WickedEngine/wiECS.h +++ b/WickedEngine/wiECS.h @@ -2,6 +2,7 @@ #define _ENTITY_COMPONENT_SYSTEM_H_ #include "wiArchive.h" +#include "wiRandom.h" #include #include @@ -12,10 +13,27 @@ namespace wiECS { typedef uint32_t Entity; static const Entity INVALID_ENTITY = 0; + // Runtime can create a new entity with this inline Entity CreateEntity() { - static Entity id = 0; - return ++id; + return wiRandom::getRandom(1, INT_MAX); + } + // This is the safe way to serialize an entity + // seed : ensures that entity will be unique after loading (specify seed = 0 to leave entity as-is) + inline void SerializeEntity(wiArchive& archive, Entity& entity, uint32_t seed) + { + if (archive.IsReadMode()) + { + archive >> entity; + if (entity != INVALID_ENTITY && seed > 0) + { + entity = ((entity << 1) ^ seed) >> 1; + } + } + else + { + archive << entity; + } } template @@ -60,7 +78,7 @@ namespace wiECS for (size_t i = 0; i < other.GetCount(); ++i) { Entity entity = other.entities[i]; - assert(Contains(entity)); + assert(!Contains(entity)); entities.push_back(entity); lookup[entity] = components.size(); components.push_back(std::move(other.components[i])); @@ -70,33 +88,29 @@ namespace wiECS } // Read/Write everything to an archive depending on the archive state - inline void Serialize(wiArchive& archive) + // seed: needed when serializing from disk which might cause discrepancy in entity uniqueness + inline void Serialize(wiArchive& archive, uint32_t seed = 0) { if (archive.IsReadMode()) { + Clear(); // If we deserialize, we start from empty + size_t count; archive >> count; components.resize(count); for (size_t i = 0; i < count; ++i) { - components[i].Serialize(archive); + components[i].Serialize(archive, seed); } entities.resize(count); for (size_t i = 0; i < count; ++i) - { - archive >> entities[i]; - } - - lookup.reserve(count); - for (size_t i = 0; i < count; ++i) { Entity entity; - size_t index; - archive >> entity; - archive >> index; - lookup[entity] = index; + SerializeEntity(archive, entity, seed); + entities[i] = entity; + lookup[entity] = i; } } else @@ -108,12 +122,7 @@ namespace wiECS } for (Entity entity : entities) { - archive << entity; - } - for (auto it : lookup) - { - archive << it.first; - archive << it.second; + SerializeEntity(archive, entity, seed); } } } @@ -121,6 +130,9 @@ namespace wiECS // Create a new component and retrieve a reference to it inline Component& Create(Entity entity) { + // INVALID_ENTITY is not allowed! + assert(entity != INVALID_ENTITY); + // Only one of this component type per entity is allowed! assert(lookup.find(entity) == lookup.end()); diff --git a/WickedEngine/wiEmittedParticle.cpp b/WickedEngine/wiEmittedParticle.cpp index eae92862e..4e61d2762 100644 --- a/WickedEngine/wiEmittedParticle.cpp +++ b/WickedEngine/wiEmittedParticle.cpp @@ -558,7 +558,7 @@ void wiEmittedParticle::UpdateRenderData(const TransformComponent& transform, co } -void wiEmittedParticle::Draw(const MaterialComponent& material, GRAPHICSTHREAD threadID) +void wiEmittedParticle::Draw(const CameraComponent& camera, const MaterialComponent& material, GRAPHICSTHREAD threadID) { GraphicsDevice* device = wiRenderer::GetDevice(); device->EventBegin("EmittedParticle", threadID); @@ -787,13 +787,13 @@ void wiEmittedParticle::CleanUpStatic() } -void wiEmittedParticle::Serialize(wiArchive& archive) +void wiEmittedParticle::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { archive >> _flags; archive >> (uint32_t&)shaderType; - archive >> meshID; + wiECS::SerializeEntity(archive, meshID, seed); archive >> FIXED_TIMESTEP; archive >> size; archive >> random_factor; @@ -815,7 +815,7 @@ void wiEmittedParticle::Serialize(wiArchive& archive) { archive << _flags; archive << (uint32_t)shaderType; - archive << meshID; + wiECS::SerializeEntity(archive, meshID, seed); archive << FIXED_TIMESTEP; archive << size; archive << random_factor; diff --git a/WickedEngine/wiEmittedParticle.h b/WickedEngine/wiEmittedParticle.h index 878e18e98..5015cf35e 100644 --- a/WickedEngine/wiEmittedParticle.h +++ b/WickedEngine/wiEmittedParticle.h @@ -73,7 +73,7 @@ public: // Must have a transform and material component, but mesh is optional void UpdateRenderData(const TransformComponent& transform, const MaterialComponent& material, const MeshComponent* mesh, GRAPHICSTHREAD threadID); - void Draw(const MaterialComponent& material, GRAPHICSTHREAD threadID); + void Draw(const CameraComponent& camera, const MaterialComponent& material, GRAPHICSTHREAD threadID); ParticleCounters GetDebugData() { return debugData; } @@ -127,7 +127,7 @@ public: inline void SetDepthCollisionEnabled(bool value) { if (value) { _flags |= DEPTHCOLLISION; } else { _flags &= ~DEPTHCOLLISION; } } inline void SetSPHEnabled(bool value) { if (value) { _flags |= SPH_FLUIDSIMULATION; } else { _flags &= ~SPH_FLUIDSIMULATION; } } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; } diff --git a/WickedEngine/wiHairParticle.cpp b/WickedEngine/wiHairParticle.cpp index d5034ef36..dca08fa83 100644 --- a/WickedEngine/wiHairParticle.cpp +++ b/WickedEngine/wiHairParticle.cpp @@ -312,7 +312,7 @@ void wiHairParticle::UpdateRenderData(const MeshComponent& mesh, const MaterialC device->EventEnd(threadID); } -void wiHairParticle::Draw(CameraComponent* camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const +void wiHairParticle::Draw(const CameraComponent& camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const { if (strandCount == 0 || cb == nullptr) { @@ -352,12 +352,12 @@ void wiHairParticle::Draw(CameraComponent* camera, const MaterialComponent& mate } -void wiHairParticle::Serialize(wiArchive& archive) +void wiHairParticle::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { archive >> _flags; - archive >> meshID; + wiECS::SerializeEntity(archive, meshID, seed); archive >> strandCount; archive >> segmentCount; archive >> randomSeed; @@ -369,7 +369,7 @@ void wiHairParticle::Serialize(wiArchive& archive) else { archive << _flags; - archive << meshID; + wiECS::SerializeEntity(archive, meshID, seed); archive << strandCount; archive << segmentCount; archive << randomSeed; diff --git a/WickedEngine/wiHairParticle.h b/WickedEngine/wiHairParticle.h index f55a24cb8..0a314d9df 100644 --- a/WickedEngine/wiHairParticle.h +++ b/WickedEngine/wiHairParticle.h @@ -32,7 +32,7 @@ public: static void LoadShaders(); void UpdateRenderData(const MeshComponent& mesh, const MaterialComponent& material, GRAPHICSTHREAD threadID); - void Draw(CameraComponent* camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const; + void Draw(const CameraComponent& camera, const MaterialComponent& material, SHADERTYPE shaderType, bool transparent, GRAPHICSTHREAD threadID) const; static void CleanUpStatic(); static void SetUpStatic(); @@ -57,7 +57,7 @@ public: XMFLOAT4X4 world; AABB aabb; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; } diff --git a/WickedEngine/wiImage.cpp b/WickedEngine/wiImage.cpp index 160390cd1..4c6f5ebba 100644 --- a/WickedEngine/wiImage.cpp +++ b/WickedEngine/wiImage.cpp @@ -418,11 +418,11 @@ void wiImage::Draw(Texture2D* texture, const wiImageEffects& effects,GRAPHICSTHR } else { - faceRot = XMLoadFloat3x3(&wiRenderer::getCamera()->rotationMatrix); + faceRot = XMLoadFloat3x3(&wiRenderer::GetCamera().rotationMatrix); } - XMMATRIX view = wiRenderer::getCamera()->GetView(); - XMMATRIX projection = wiRenderer::getCamera()->GetProjection(); + XMMATRIX view = wiRenderer::GetCamera().GetView(); + XMMATRIX projection = wiRenderer::GetCamera().GetProjection(); // Remove possible jittering from temporal camera: projection.r[2] = XMVectorSetX(projection.r[2], 0); projection.r[2] = XMVectorSetY(projection.r[2], 0); diff --git a/WickedEngine/wiIntersectables.cpp b/WickedEngine/wiIntersectables.cpp index e1365fb21..bab267461 100644 --- a/WickedEngine/wiIntersectables.cpp +++ b/WickedEngine/wiIntersectables.cpp @@ -140,7 +140,7 @@ AABB AABB::Merge(const AABB& a, const AABB& b) { return AABB(wiMath::Min(a.getMin(), b.getMin()), wiMath::Max(a.getMax(), b.getMax())); } -void AABB::Serialize(wiArchive& archive) +void AABB::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { diff --git a/WickedEngine/wiIntersectables.h b/WickedEngine/wiIntersectables.h index 3d81c1a83..e50fd5b8f 100644 --- a/WickedEngine/wiIntersectables.h +++ b/WickedEngine/wiIntersectables.h @@ -2,6 +2,7 @@ #define _INTERSECTABLES_H_ #include "CommonInclude.h" #include "wiArchive.h" +#include "wiECS.h" struct SPHERE; struct RAY; @@ -52,17 +53,9 @@ struct AABB } assert(0); return XMFLOAT3(0, 0, 0); - //corners[0] = min; - //corners[1] = XMFLOAT3(min.x, max.y, min.z); - //corners[2] = XMFLOAT3(min.x, max.y, max.z); - //corners[3] = XMFLOAT3(min.x, min.y, max.z); - //corners[4] = XMFLOAT3(max.x, min.y, min.z); - //corners[5] = XMFLOAT3(max.x, max.y, min.z); - //corners[6] = max; - //corners[7] = XMFLOAT3(max.x, min.y, max.z); } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct SPHERE { diff --git a/WickedEngine/wiOcean.cpp b/WickedEngine/wiOcean.cpp index 58ec92c35..68ec90c34 100644 --- a/WickedEngine/wiOcean.cpp +++ b/WickedEngine/wiOcean.cpp @@ -325,7 +325,7 @@ void wiOcean::UpdateDisplacementMap(float time, GRAPHICSTHREAD threadID) } -void wiOcean::Render(const CameraComponent* camera, float time, GRAPHICSTHREAD threadID) +void wiOcean::Render(const CameraComponent& camera, float time, GRAPHICSTHREAD threadID) { GraphicsDevice* device = wiRenderer::GetDevice(); diff --git a/WickedEngine/wiOcean.h b/WickedEngine/wiOcean.h index 10775e801..fc8bd801b 100644 --- a/WickedEngine/wiOcean.h +++ b/WickedEngine/wiOcean.h @@ -61,7 +61,7 @@ public: ~wiOcean(); void UpdateDisplacementMap(float time, GRAPHICSTHREAD threadID); - void Render(const wiSceneSystem::CameraComponent* camera, float time, GRAPHICSTHREAD threadID); + void Render(const wiSceneSystem::CameraComponent& camera, float time, GRAPHICSTHREAD threadID); wiGraphicsTypes::Texture2D* getDisplacementMap(); wiGraphicsTypes::Texture2D* getGradientMap(); diff --git a/WickedEngine/wiRandom.cpp b/WickedEngine/wiRandom.cpp index 20841e143..08a739e3f 100644 --- a/WickedEngine/wiRandom.cpp +++ b/WickedEngine/wiRandom.cpp @@ -1,17 +1,17 @@ #include "wiRandom.h" +#include -bool wiRandom::initialized = false; - -int wiRandom::getRandom(int minValue, int maxValue) +namespace wiRandom { - if (!initialized) + int wiRandom::getRandom(int minValue, int maxValue) { - srand(unsigned(time(0))); - initialized = true; + static std::random_device rand_dev; + static std::mt19937 generator(rand_dev()); + std::uniform_int_distribution distr(minValue, maxValue); + return distr(generator); + } + int wiRandom::getRandom(int maxValue) + { + return getRandom(0, maxValue); } - return minValue + rand() % (maxValue + 1 - minValue); -} -int wiRandom::getRandom(int maxValue) -{ - return getRandom(0, maxValue); } diff --git a/WickedEngine/wiRandom.h b/WickedEngine/wiRandom.h index d03023db4..b1502a2ab 100644 --- a/WickedEngine/wiRandom.h +++ b/WickedEngine/wiRandom.h @@ -1,13 +1,8 @@ #pragma once -#include -#include -class wiRandom +namespace wiRandom { -private: - static bool initialized; -public: - static int getRandom(int minValue, int maxValue); - static int getRandom(int maxValue); + int getRandom(int minValue, int maxValue); + int getRandom(int maxValue); }; diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 35791ad5e..bca2a2279 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -130,7 +130,7 @@ struct FrameCulling culledEnvProbes.clear(); } }; -unordered_map frameCullings; +unordered_map frameCullings; GFX_STRUCT Instance { @@ -311,7 +311,7 @@ void wiRenderer::SetUpStaticComponents() SAFE_INIT(customsamplers[i]); } - getCamera()->CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); + GetCamera().CreatePerspective((float)wiRenderer::GetInternalResolution().x, (float)wiRenderer::GetInternalResolution().y, 0.1f, 800); SetUpStates(); LoadBuffers(); @@ -2908,14 +2908,12 @@ void wiRenderer::UpdatePerFrameData(float dt) scene.Update(dt * GetGameSpeed()); - *getPrevCamera() = *getCamera(); - // Update Voxelization parameters: if (scene.objects.GetCount() > 0) { // We don't update it if the scene is empty, this even makes it easier to debug const float f = 0.05f / voxelSceneData.voxelsize; - XMFLOAT3 center = XMFLOAT3(floorf(getCamera()->Eye.x * f) / f, floorf(getCamera()->Eye.y * f) / f, floorf(getCamera()->Eye.z * f) / f); + XMFLOAT3 center = XMFLOAT3(floorf(GetCamera().Eye.x * f) / f, floorf(GetCamera().Eye.y * f) / f, floorf(GetCamera().Eye.z * f) / f); if (wiMath::DistanceSquared(center, voxelSceneData.center) > 0) { voxelSceneData.centerChangedThisFrame = true; @@ -2934,7 +2932,7 @@ void wiRenderer::UpdatePerFrameData(float dt) { for (auto& x : frameCullings) { - CameraComponent* camera = x.first; + const CameraComponent* camera = x.first; FrameCulling& culling = x.second; culling.Clear(); @@ -2970,7 +2968,7 @@ void wiRenderer::UpdatePerFrameData(float dt) } // the following cullings will be only for the main camera: - if (camera == getCamera()) + if (camera == &GetCamera()) { // Cull decals: for (size_t i = 0; i < scene.aabb_decals.GetCount(); ++i) @@ -3073,6 +3071,8 @@ void wiRenderer::UpdatePerFrameData(float dt) } + GetPrevCamera() = GetCamera(); + if (GetTemporalAAEnabled()) { const XMFLOAT4& halton = wiMath::GetHaltonSequence(GetDevice()->GetFrameCount() % 256); @@ -3080,9 +3080,9 @@ void wiRenderer::UpdatePerFrameData(float dt) temporalAAJitterPrev = temporalAAJitter; temporalAAJitter.x = jitter * (halton.x * 2 - 1) / (float)GetInternalResolution().x; temporalAAJitter.y = jitter * (halton.y * 2 - 1) / (float)GetInternalResolution().y; - getCamera()->Projection.m[2][0] = temporalAAJitter.x; - getCamera()->Projection.m[2][1] = temporalAAJitter.y; - getCamera()->UpdateCamera(); + GetCamera().Projection.m[2][0] = temporalAAJitter.x; + GetCamera().Projection.m[2][1] = temporalAAJitter.y; + GetCamera().UpdateCamera(); } else { @@ -3090,8 +3090,8 @@ void wiRenderer::UpdatePerFrameData(float dt) temporalAAJitterPrev = XMFLOAT2(0, 0); } - *getRefCamera() = *getCamera(); - getRefCamera()->Reflect(waterPlane); + GetRefCamera() = GetCamera(); + GetRefCamera().Reflect(waterPlane); for (auto& x : waterRipples) { @@ -3151,7 +3151,7 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) } - const FrameCulling& mainCameraCulling = frameCullings[getCamera()]; + const FrameCulling& mainCameraCulling = frameCullings[&GetCamera()]; // Fill Light Array with lights + envprobes + decals in the frustum: { @@ -3160,7 +3160,7 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) static ShaderEntityType* entityArray = (ShaderEntityType*)_mm_malloc(sizeof(ShaderEntityType)*MAX_SHADER_ENTITY_COUNT, 16); static XMMATRIX* matrixArray = (XMMATRIX*)_mm_malloc(sizeof(XMMATRIX)*MATRIXARRAY_COUNT, 16); - const XMMATRIX viewMatrix = getCamera()->GetView(); + const XMMATRIX viewMatrix = GetCamera().GetView(); UINT entityCounter = 0; UINT matrixCounter = 0; @@ -3476,7 +3476,7 @@ void wiRenderer::UpdateRenderData(GRAPHICSTHREAD threadID) { wiHairParticle& hair = scene.hairs[i]; - if (hair.meshID != INVALID_ENTITY && getCamera()->frustum.CheckBox(hair.aabb)) + if (hair.meshID != INVALID_ENTITY && GetCamera().frustum.CheckBox(hair.aabb)) { const MeshComponent* mesh = scene.meshes.GetComponent(hair.meshID); @@ -3529,7 +3529,7 @@ void wiRenderer::OcclusionCulling_Render(GRAPHICSTHREAD threadID) return; } - const FrameCulling& culling = frameCullings[getCamera()]; + const FrameCulling& culling = frameCullings[&GetCamera()]; wiProfiler::GetInstance().BeginRange("Occlusion Culling Render", wiProfiler::DOMAIN_GPU, threadID); @@ -3570,7 +3570,7 @@ void wiRenderer::OcclusionCulling_Render(GRAPHICSTHREAD threadID) const AABB& aabb = *scene.aabb_objects.GetComponent(entity); - if (aabb.intersects(getCamera()->Eye)) + if (aabb.intersects(GetCamera().Eye)) { // camera is inside the instance, mark it as visible in this frame: object.occlusionHistory |= 1; @@ -3582,7 +3582,7 @@ void wiRenderer::OcclusionCulling_Render(GRAPHICSTHREAD threadID) queryID++; // previous frame view*projection because these are drawn against the previous depth buffer: - cb.mTransform = XMMatrixTranspose(aabb.getAsBoxMatrix()*getPrevCamera()->GetViewProjection()); // todo: obb + cb.mTransform = XMMatrixTranspose(aabb.getAsBoxMatrix()*GetPrevCamera().GetViewProjection()); // todo: obb GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &cb, threadID); // render bounding box to later read the occlusion status @@ -3606,7 +3606,7 @@ void wiRenderer::OcclusionCulling_Read() wiProfiler::GetInstance().BeginRange("Occlusion Culling Read", wiProfiler::DOMAIN_CPU); - const FrameCulling& culling = frameCullings[getCamera()]; + const FrameCulling& culling = frameCullings[&GetCamera()]; if (!culling.culledObjects.empty()) { @@ -3684,7 +3684,7 @@ void wiRenderer::DrawWaterRipples(GRAPHICSTHREAD threadID) GetDevice()->EventEnd(threadID); } -void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::DrawDebugWorld(const CameraComponent& camera, GRAPHICSTHREAD threadID) { GraphicsDevice* device = GetDevice(); @@ -3699,7 +3699,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID device->BindGraphicsPSO(PSO_debug[DEBUGRENDERING_LINES], threadID); MiscCB sb; - sb.mTransform = XMMatrixTranspose(camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(camera.GetViewProjection()); sb.mColor = XMFLOAT4(1, 1, 1, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -3767,7 +3767,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID device->BindGraphicsPSO(PSO_debug[DEBUGRENDERING_LINES], threadID); MiscCB sb; - sb.mTransform = XMMatrixTranspose(camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(camera.GetViewProjection()); sb.mColor = XMFLOAT4(1, 1, 1, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -3829,7 +3829,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID for (auto& x : renderableBoxes) { - sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&x.first)*camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&x.first)*camera.GetViewProjection()); sb.mColor = x.second; device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -3895,7 +3895,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID Entity entity = scene.probes.GetEntity(i); const TransformComponent& transform = *scene.transforms.GetComponent(entity); - sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&transform.world)*camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&transform.world)*camera.GetViewProjection()); sb.mColor = XMFLOAT4(0, 1, 1, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -3956,7 +3956,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID } MiscCB sb; - sb.mTransform = XMMatrixTranspose(camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(camera.GetViewProjection()); sb.mColor = XMFLOAT4(1, 1, 1, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -3981,7 +3981,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID MiscCB sb; - sb.mTransform = XMMatrixTranspose(XMMatrixTranslationFromVector(XMLoadFloat3(&voxelSceneData.center)) * camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(XMMatrixTranslationFromVector(XMLoadFloat3(&voxelSceneData.center)) * camera.GetViewProjection()); sb.mColor = XMFLOAT4(1, 1, 1, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -4003,7 +4003,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID const TransformComponent& transform = *scene.transforms.GetComponent(entity); const MeshComponent* mesh = scene.meshes.GetComponent(emitter.meshID); - sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&transform.world)*camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(XMLoadFloat4x4(&transform.world)*camera.GetViewProjection()); sb.mColor = XMFLOAT4(0, 1, 0, 1); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -4051,8 +4051,8 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID { ForceFieldComponent& force = scene.forces[i]; - sb.mTransform = XMMatrixTranspose(camera->GetViewProjection()); - sb.mColor = XMFLOAT4(camera->Eye.x, camera->Eye.y, camera->Eye.z, (float)i); + sb.mTransform = XMMatrixTranspose(camera.GetViewProjection()); + sb.mColor = XMFLOAT4(camera.Eye.x, camera.Eye.y, camera.Eye.z, (float)i); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); switch (force.type) @@ -4094,10 +4094,10 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID for(size_t i = 0; i < scene.cameras.GetCount(); ++i) { - CameraComponent& cam = scene.cameras[i]; + const CameraComponent& cam = scene.cameras[i]; Entity entity = scene.cameras.GetEntity(i); - sb.mTransform = XMMatrixTranspose(cam.GetInvView()*camera->GetViewProjection()); + sb.mTransform = XMMatrixTranspose(cam.GetInvView()*camera.GetViewProjection()); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &sb, threadID); @@ -4110,7 +4110,7 @@ void wiRenderer::DrawDebugWorld(CameraComponent* camera, GRAPHICSTHREAD threadID device->EventEnd(threadID); } -void wiRenderer::DrawSoftParticles(CameraComponent* camera, bool distortion, GRAPHICSTHREAD threadID) +void wiRenderer::DrawSoftParticles(const CameraComponent& camera, bool distortion, GRAPHICSTHREAD threadID) { Scene& scene = GetScene(); @@ -4122,11 +4122,11 @@ void wiRenderer::DrawSoftParticles(CameraComponent* camera, bool distortion, GRA if (distortion && emitter.shaderType == wiEmittedParticle::SOFT_DISTORTION) { - emitter.Draw(material, threadID); + emitter.Draw(camera, material, threadID); } else if (!distortion && (emitter.shaderType == wiEmittedParticle::SOFT || emitter.shaderType == wiEmittedParticle::SIMPLEST || IsWireRender())) { - emitter.Draw(material, threadID); + emitter.Draw(camera, material, threadID); } } @@ -4225,9 +4225,9 @@ void wiRenderer::DrawTrails(GRAPHICSTHREAD threadID, Texture2D* refracRes) //GetDevice()->EventEnd(threadID); } -void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::DrawLights(const CameraComponent& camera, GRAPHICSTHREAD threadID) { - const FrameCulling& culling = frameCullings[camera]; + const FrameCulling& culling = frameCullings[&camera]; const auto& culledLights = culling.culledLights; Scene& scene = GetScene(); @@ -4271,7 +4271,7 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) MiscCB miscCb; miscCb.mColor.x = (float)light.entityArray_index; float sca = light.range + 1; - miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection()); + miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera.GetViewProjection()); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); GetDevice()->Draw(240, 0, threadID); // icosphere @@ -4286,7 +4286,7 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) XMMatrixScaling(coneS*light.range, light.range, coneS*light.range)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); @@ -4302,7 +4302,7 @@ void wiRenderer::DrawLights(CameraComponent* camera, GRAPHICSTHREAD threadID) wiProfiler::GetInstance().EndRange(threadID); GetDevice()->EventEnd(threadID); } -void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::DrawLightVisualizers(const CameraComponent& camera, GRAPHICSTHREAD threadID) { Scene& scene = GetScene(); @@ -4311,7 +4311,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th GetDevice()->BindConstantBuffer(PS, constantBuffers[CBTYPE_VOLUMELIGHT], CB_GETBINDSLOT(VolumeLightCB), threadID); GetDevice()->BindConstantBuffer(VS, constantBuffers[CBTYPE_VOLUMELIGHT], CB_GETBINDSLOT(VolumeLightCB), threadID); - XMMATRIX camrot = XMLoadFloat3x3(&camera->rotationMatrix); + XMMATRIX camrot = XMLoadFloat3x3(&camera.rotationMatrix); for (int type = LightComponent::POINT; type < LightComponent::LIGHTTYPE_COUNT; ++type) @@ -4362,7 +4362,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th XMMatrixScaling(light.radius, light.radius, light.radius)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4375,7 +4375,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th XMMatrixScaling(light.radius, light.radius, light.radius)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4388,7 +4388,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th XMMatrixScaling(light.width * 0.5f, light.height * 0.5f, 0.5f)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4401,7 +4401,7 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th XMMatrixScaling(max(light.width * 0.5f, light.radius), light.radius, light.radius)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position))* - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_VOLUMELIGHT], &lcb, threadID); @@ -4417,9 +4417,9 @@ void wiRenderer::DrawLightVisualizers(CameraComponent* camera, GRAPHICSTHREAD th } -void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::DrawVolumeLights(const CameraComponent& camera, GRAPHICSTHREAD threadID) { - const FrameCulling& culling = frameCullings[camera]; + const FrameCulling& culling = frameCullings[&camera]; const auto& culledLights = culling.culledLights; if (!culledLights.empty()) @@ -4465,7 +4465,7 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread MiscCB miscCb; miscCb.mColor.x = (float)light.entityArray_index; float sca = light.range + 1; - miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera->GetViewProjection()); + miscCb.mTransform = XMMatrixTranspose(XMMatrixScaling(sca, sca, sca)*XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * camera.GetViewProjection()); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); GetDevice()->Draw(240, 0, threadID); // icosphere @@ -4480,7 +4480,7 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread XMMatrixScaling(coneS*light.range, light.range, coneS*light.range)* XMMatrixRotationQuaternion(XMLoadFloat4(&light.rotation))* XMMatrixTranslationFromVector(XMLoadFloat3(&light.position)) * - camera->GetViewProjection() + camera.GetViewProjection() ); GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_MISC], &miscCb, threadID); @@ -4501,7 +4501,9 @@ void wiRenderer::DrawVolumeLights(CameraComponent* camera, GRAPHICSTHREAD thread } void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID) { - const FrameCulling& culling = frameCullings[getCamera()]; + const CameraComponent& camera = GetCamera(); + + const FrameCulling& culling = frameCullings[&camera]; const auto& culledLights = culling.culledLights; Scene& scene = GetScene(); @@ -4525,9 +4527,9 @@ void wiRenderer::DrawLensFlares(GRAPHICSTHREAD threadID) ) * 100000; } - XMVECTOR flarePos = XMVector3Project(POS,0.f,0.f,(float)GetInternalResolution().x,(float)GetInternalResolution().y,0.0f,1.0f,getCamera()->GetRealProjection(),getCamera()->GetView(),XMMatrixIdentity()); + XMVECTOR flarePos = XMVector3Project(POS,0.f,0.f,(float)GetInternalResolution().x,(float)GetInternalResolution().y,0.0f,1.0f, camera.GetRealProjection(), camera.GetView(),XMMatrixIdentity()); - if( XMVectorGetX(XMVector3Dot( XMVectorSubtract(POS,getCamera()->GetEye()),getCamera()->GetAt() ))>0 ) + if( XMVectorGetX(XMVector3Dot( XMVectorSubtract(POS, camera.GetEye()), camera.GetAt() ))>0 ) wiLensFlare::Draw(threadID,flarePos,light.lensFlareRimTextures); } @@ -4610,7 +4612,7 @@ void wiRenderer::DrawForShadowMap(GRAPHICSTHREAD threadID, uint32_t layerMask) const bool all_layers = layerMask == 0xFFFFFFFF; // this can avoid the recursive call per object : GetLayerMask() - const FrameCulling& culling = frameCullings[getCamera()]; + const FrameCulling& culling = frameCullings[&GetCamera()]; const auto& culledLights = culling.culledLights; ViewPort vp; @@ -5310,9 +5312,9 @@ void wiRenderer::RenderMeshes(const XMFLOAT3& eye, const CulledCollection& culle } } -void wiRenderer::DrawWorld(CameraComponent* camera, bool tessellation, GRAPHICSTHREAD threadID, SHADERTYPE shaderType, bool grass, bool occlusionCulling, uint32_t layerMask) +void wiRenderer::DrawWorld(const CameraComponent& camera, bool tessellation, GRAPHICSTHREAD threadID, SHADERTYPE shaderType, bool grass, bool occlusionCulling, uint32_t layerMask) { - const FrameCulling& culling = frameCullings[camera]; + const FrameCulling& culling = frameCullings[&camera]; GetDevice()->EventBegin("DrawWorld", threadID); @@ -5335,7 +5337,7 @@ void wiRenderer::DrawWorld(CameraComponent* camera, bool tessellation, GRAPHICST { const wiHairParticle& hair = scene.hairs[i]; - if (camera->frustum.CheckBox(hair.aabb)) + if (camera.frustum.CheckBox(hair.aabb)) { Entity entity = scene.hairs.GetEntity(i); const MaterialComponent& material = *scene.materials.GetComponent(entity); @@ -5347,16 +5349,16 @@ void wiRenderer::DrawWorld(CameraComponent* camera, bool tessellation, GRAPHICST if (!culling.culledRenderer_opaque.empty()/* || (grass && culling.culledHairParticleSystems.empty())*/) { - RenderMeshes(camera->Eye, culling.culledRenderer_opaque, shaderType, RENDERTYPE_OPAQUE, threadID, tessellation, GetOcclusionCullingEnabled() && occlusionCulling, layerMask); + RenderMeshes(camera.Eye, culling.culledRenderer_opaque, shaderType, RENDERTYPE_OPAQUE, threadID, tessellation, GetOcclusionCullingEnabled() && occlusionCulling, layerMask); } GetDevice()->EventEnd(threadID); } -void wiRenderer::DrawWorldTransparent(CameraComponent* camera, SHADERTYPE shaderType, GRAPHICSTHREAD threadID, bool grass, bool occlusionCulling, uint32_t layerMask) +void wiRenderer::DrawWorldTransparent(const CameraComponent& camera, SHADERTYPE shaderType, GRAPHICSTHREAD threadID, bool grass, bool occlusionCulling, uint32_t layerMask) { - const FrameCulling& culling = frameCullings[camera]; + const FrameCulling& culling = frameCullings[&camera]; GetDevice()->EventBegin("DrawWorldTransparent", threadID); @@ -5379,7 +5381,7 @@ void wiRenderer::DrawWorldTransparent(CameraComponent* camera, SHADERTYPE shader { const wiHairParticle& hair = scene.hairs[i]; - if (camera->frustum.CheckBox(hair.aabb)) + if (camera.frustum.CheckBox(hair.aabb)) { Entity entity = scene.hairs.GetEntity(i); const MaterialComponent& material = *scene.materials.GetComponent(entity); @@ -5391,7 +5393,7 @@ void wiRenderer::DrawWorldTransparent(CameraComponent* camera, SHADERTYPE shader if (!culling.culledRenderer_transparent.empty()) { - RenderMeshes(camera->Eye, culling.culledRenderer_transparent, shaderType, RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER, threadID, false, GetOcclusionCullingEnabled() && occlusionCulling, layerMask); + RenderMeshes(camera.Eye, culling.culledRenderer_transparent, shaderType, RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER, threadID, false, GetOcclusionCullingEnabled() && occlusionCulling, layerMask); } GetDevice()->EventEnd(threadID); @@ -5444,7 +5446,7 @@ void wiRenderer::DrawSun(GRAPHICSTHREAD threadID) GetDevice()->EventEnd(threadID); } -void wiRenderer::DrawDecals(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::DrawDecals(const CameraComponent& camera, GRAPHICSTHREAD threadID) { GraphicsDevice* device = GetDevice(); Scene& scene = GetScene(); @@ -5470,7 +5472,7 @@ void wiRenderer::DrawDecals(CameraComponent* camera, GRAPHICSTHREAD threadID) Entity entity = scene.decals.GetEntity(i); const AABB& aabb = *scene.aabb_decals.GetComponent(entity); - if ((decal.texture != nullptr || decal.normal != nullptr) && camera->frustum.CheckBox(aabb)) + if ((decal.texture != nullptr || decal.normal != nullptr) && camera.frustum.CheckBox(aabb)) { device->BindResource(PS, decal.texture, TEXSLOT_ONDEMAND0, threadID); @@ -5479,7 +5481,7 @@ void wiRenderer::DrawDecals(CameraComponent* camera, GRAPHICSTHREAD threadID) XMMATRIX decalWorld = XMLoadFloat4x4(&decal.world); MiscCB dcbvs; - dcbvs.mTransform = XMMatrixTranspose(decalWorld*camera->GetViewProjection()); + dcbvs.mTransform = XMMatrixTranspose(decalWorld*camera.GetViewProjection()); device->UpdateBuffer(constantBuffers[CBTYPE_MISC], &dcbvs, threadID); DecalCB dcbps; @@ -5489,7 +5491,7 @@ void wiRenderer::DrawDecals(CameraComponent* camera, GRAPHICSTHREAD threadID) dcbps.hasTexNor |= 0x0000001; if (decal.normal != nullptr) dcbps.hasTexNor |= 0x0000010; - XMStoreFloat3(&dcbps.eye, camera->GetEye()); + XMStoreFloat3(&dcbps.eye, camera.GetEye()); dcbps.opacity = decal.GetOpacity(); dcbps.front = decal.front; device->UpdateBuffer(constantBuffers[CBTYPE_DECAL], &dcbps, threadID); @@ -5563,8 +5565,8 @@ void wiRenderer::RefreshEnvProbes(GRAPHICSTHREAD threadID) VP.MaxDepth = 1.0f; GetDevice()->BindViewports(1, &VP, threadID); - const float zNearP = getCamera()->zNearP; - const float zFarP = getCamera()->zFarP; + const float zNearP = GetCamera().zNearP; + const float zFarP = GetCamera().zFarP; // reconstruct envmap array status: bool envmapTaken[envmapCount] = {}; @@ -5981,9 +5983,9 @@ void wiRenderer::ComputeTiledLightCulling(bool deferred, GRAPHICSTHREAD threadID // calculate the per-tile frustums once: static bool frustumsComplete = false; static XMFLOAT4X4 _savedProjection; - if (memcmp(&_savedProjection, &getCamera()->Projection, sizeof(XMFLOAT4X4)) != 0) + if (memcmp(&_savedProjection, &GetCamera().Projection, sizeof(XMFLOAT4X4)) != 0) { - _savedProjection = getCamera()->Projection; + _savedProjection = GetCamera().Projection; frustumsComplete = false; } if(!frustumsComplete || _resolutionChanged) @@ -6047,7 +6049,7 @@ void wiRenderer::ComputeTiledLightCulling(bool deferred, GRAPHICSTHREAD threadID } - const FrameCulling& frameCulling = frameCullings[getCamera()]; + const FrameCulling& frameCulling = frameCullings[&GetCamera()]; DispatchParamsCB dispatchParams; @@ -6805,7 +6807,7 @@ void wiRenderer::BuildSceneBVH(GRAPHICSTHREAD threadID) wiProfiler::GetInstance().EndRange(threadID); // BVH rebuild } -void wiRenderer::DrawTracedScene(CameraComponent* camera, Texture2D* result, GRAPHICSTHREAD threadID) +void wiRenderer::DrawTracedScene(const CameraComponent& camera, Texture2D* result, GRAPHICSTHREAD threadID) { GraphicsDevice* device = wiRenderer::GetDevice(); Scene& scene = GetScene(); @@ -7552,37 +7554,37 @@ void wiRenderer::UpdateFrameCB(GRAPHICSTHREAD threadID) cb.mTemporalAAJitter = temporalAAJitter; cb.mTemporalAAJitterPrev = temporalAAJitterPrev; - auto camera = getCamera(); - auto prevCam = getPrevCamera(); - auto reflCam = getRefCamera(); + const auto& camera = GetCamera(); + const auto& prevCam = GetPrevCamera(); + const auto& reflCam = GetRefCamera(); - cb.mVP = XMMatrixTranspose(camera->GetViewProjection()); - cb.mView = XMMatrixTranspose(camera->GetView()); - cb.mProj = XMMatrixTranspose(camera->GetProjection()); - cb.mCamPos = camera->Eye; + cb.mVP = XMMatrixTranspose(camera.GetViewProjection()); + cb.mView = XMMatrixTranspose(camera.GetView()); + cb.mProj = XMMatrixTranspose(camera.GetProjection()); + cb.mCamPos = camera.Eye; cb.mCamDistanceFromOrigin = XMVectorGetX(XMVector3Length(XMLoadFloat3(&cb.mCamPos))); - cb.mPrevV = XMMatrixTranspose(prevCam->GetView()); - cb.mPrevP = XMMatrixTranspose(prevCam->GetProjection()); - cb.mPrevVP = XMMatrixTranspose(prevCam->GetViewProjection()); - cb.mPrevInvVP = XMMatrixTranspose(prevCam->GetInvViewProjection()); - cb.mReflVP = XMMatrixTranspose(reflCam->GetViewProjection()); - cb.mInvV = XMMatrixTranspose(camera->GetInvView()); - cb.mInvP = XMMatrixTranspose(camera->GetInvProjection()); - cb.mInvVP = XMMatrixTranspose(camera->GetInvViewProjection()); - cb.mAt = camera->At; - cb.mUp = camera->Up; - cb.mZNearP = camera->zNearP; - cb.mZFarP = camera->zFarP; + cb.mPrevV = XMMatrixTranspose(prevCam.GetView()); + cb.mPrevP = XMMatrixTranspose(prevCam.GetProjection()); + cb.mPrevVP = XMMatrixTranspose(prevCam.GetViewProjection()); + cb.mPrevInvVP = XMMatrixTranspose(prevCam.GetInvViewProjection()); + cb.mReflVP = XMMatrixTranspose(reflCam.GetViewProjection()); + cb.mInvV = XMMatrixTranspose(camera.GetInvView()); + cb.mInvP = XMMatrixTranspose(camera.GetInvProjection()); + cb.mInvVP = XMMatrixTranspose(camera.GetInvViewProjection()); + cb.mAt = camera.At; + cb.mUp = camera.Up; + cb.mZNearP = camera.zNearP; + cb.mZFarP = camera.zFarP; cb.mZNearP_Recip = 1.0f / max(0.0001f, cb.mZNearP); cb.mZFarP_Recip = 1.0f / max(0.0001f, cb.mZFarP); cb.mZRange = abs(cb.mZFarP - cb.mZNearP); cb.mZRange_Recip = 1.0f / max(0.0001f, cb.mZRange); - cb.mFrustumPlanesWS[0] = camera->frustum.getLeftPlane(); - cb.mFrustumPlanesWS[1] = camera->frustum.getRightPlane(); - cb.mFrustumPlanesWS[2] = camera->frustum.getTopPlane(); - cb.mFrustumPlanesWS[3] = camera->frustum.getBottomPlane(); - cb.mFrustumPlanesWS[4] = camera->frustum.getNearPlane(); - cb.mFrustumPlanesWS[5] = camera->frustum.getFarPlane(); + cb.mFrustumPlanesWS[0] = camera.frustum.getLeftPlane(); + cb.mFrustumPlanesWS[1] = camera.frustum.getRightPlane(); + cb.mFrustumPlanesWS[2] = camera.frustum.getTopPlane(); + cb.mFrustumPlanesWS[3] = camera.frustum.getBottomPlane(); + cb.mFrustumPlanesWS[4] = camera.frustum.getNearPlane(); + cb.mFrustumPlanesWS[5] = camera.frustum.getFarPlane(); cb.mWorldBoundsMin = scene.bounds.getMin(); cb.mWorldBoundsMax = scene.bounds.getMax(); @@ -7595,14 +7597,14 @@ void wiRenderer::UpdateFrameCB(GRAPHICSTHREAD threadID) GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_FRAME], &cb, threadID); } -void wiRenderer::UpdateCameraCB(CameraComponent* camera, GRAPHICSTHREAD threadID) +void wiRenderer::UpdateCameraCB(const CameraComponent& camera, GRAPHICSTHREAD threadID) { CameraCB cb; - cb.mVP = XMMatrixTranspose(camera->GetViewProjection()); - cb.mView = XMMatrixTranspose(camera->GetView()); - cb.mProj = XMMatrixTranspose(camera->GetProjection()); - cb.mCamPos = camera->Eye; + cb.mVP = XMMatrixTranspose(camera.GetViewProjection()); + cb.mView = XMMatrixTranspose(camera.GetView()); + cb.mProj = XMMatrixTranspose(camera.GetProjection()); + cb.mCamPos = camera.Eye; GetDevice()->UpdateBuffer(constantBuffers[CBTYPE_CAMERA], &cb, threadID); } @@ -7735,8 +7737,9 @@ const XMFLOAT4& wiRenderer::GetWaterPlane() } -RAY wiRenderer::getPickRay(long cursorX, long cursorY) { - const CameraComponent& camera = *getCamera(); +RAY wiRenderer::GetPickRay(long cursorX, long cursorY) +{ + const CameraComponent& camera = GetCamera(); XMMATRIX V = camera.GetView(); XMMATRIX P = camera.GetRealProjection(); XMMATRIX W = XMMatrixIdentity(); @@ -8081,7 +8084,7 @@ void wiRenderer::CreateImpostor(Entity entity, GRAPHICSTHREAD threadID) camera_transform.UpdateTransform(); impostorcamera.UpdateCamera(&camera_transform); impostorcamera.UpdateProjection(); - UpdateCameraCB(&impostorcamera, threadID); + UpdateCameraCB(impostorcamera, threadID); for (MeshComponent::MeshSubset& subset : mesh.subsets) { @@ -8105,7 +8108,7 @@ void wiRenderer::CreateImpostor(Entity entity, GRAPHICSTHREAD threadID) wiRenderer::GenerateMipChain(mesh.impostorTarget.GetTexture(), wiRenderer::MIPGENFILTER_LINEAR, threadID); mesh.impostorTarget.viewPort = savedViewPort; - UpdateCameraCB(getCamera(), threadID); + UpdateCameraCB(GetCamera(), threadID); } void wiRenderer::AddRenderableBox(const XMFLOAT4X4& boxMatrix, const XMFLOAT4& color) @@ -8164,18 +8167,18 @@ void wiRenderer::SetOceanEnabled(bool enabled, const wiOceanParameter& params) } -CameraComponent* wiRenderer::getCamera() +CameraComponent& wiRenderer::GetCamera() { static CameraComponent camera; - return &camera; + return camera; } -CameraComponent* wiRenderer::getPrevCamera() +CameraComponent& wiRenderer::GetPrevCamera() { static CameraComponent camera; - return &camera; + return camera; } -CameraComponent* wiRenderer::getRefCamera() +CameraComponent& wiRenderer::GetRefCamera() { static CameraComponent camera; - return &camera; + return camera; } diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index cadab7e2d..eeb235108 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -370,7 +370,7 @@ public: static void UpdateWorldCB(GRAPHICSTHREAD threadID); static void UpdateFrameCB(GRAPHICSTHREAD threadID); - static void UpdateCameraCB(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); + static void UpdateCameraCB(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); static void SetClipPlane(const XMFLOAT4& clipPlane, GRAPHICSTHREAD threadID); static void SetAlphaRef(float alphaRef, GRAPHICSTHREAD threadID); static void ResetAlphaRef(GRAPHICSTHREAD threadID) { SetAlphaRef(0.75f, threadID); } @@ -381,17 +381,17 @@ public: bool tessellation = false, bool occlusionCulling = false, uint32_t layerMask = 0xFFFFFFFF); static void DrawSky(GRAPHICSTHREAD threadID); static void DrawSun(GRAPHICSTHREAD threadID); - static void DrawWorld(wiSceneSystem::CameraComponent* camera, bool tessellation, GRAPHICSTHREAD threadID, SHADERTYPE shaderType, bool grass, bool occlusionCulling, uint32_t layerMask = 0xFFFFFFFF); + static void DrawWorld(const wiSceneSystem::CameraComponent& camera, bool tessellation, GRAPHICSTHREAD threadID, SHADERTYPE shaderType, bool grass, bool occlusionCulling, uint32_t layerMask = 0xFFFFFFFF); static void DrawForShadowMap(GRAPHICSTHREAD threadID, uint32_t layerMask = 0xFFFFFFFF); - static void DrawWorldTransparent(wiSceneSystem::CameraComponent* camera, SHADERTYPE shaderType, GRAPHICSTHREAD threadID, bool grass, bool occlusionCulling, uint32_t layerMask = 0xFFFFFFFF); - static void DrawDebugWorld(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); - static void DrawSoftParticles(wiSceneSystem::CameraComponent* camera, bool distortion, GRAPHICSTHREAD threadID); + static void DrawWorldTransparent(const wiSceneSystem::CameraComponent& camera, SHADERTYPE shaderType, GRAPHICSTHREAD threadID, bool grass, bool occlusionCulling, uint32_t layerMask = 0xFFFFFFFF); + static void DrawDebugWorld(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); + static void DrawSoftParticles(const wiSceneSystem::CameraComponent& camera, bool distortion, GRAPHICSTHREAD threadID); static void DrawTrails(GRAPHICSTHREAD threadID, wiGraphicsTypes::Texture2D* refracRes); - static void DrawLights(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); - static void DrawLightVisualizers(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); - static void DrawVolumeLights(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); + static void DrawLights(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); + static void DrawLightVisualizers(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); + static void DrawVolumeLights(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); static void DrawLensFlares(GRAPHICSTHREAD threadID); - static void DrawDecals(wiSceneSystem::CameraComponent* camera, GRAPHICSTHREAD threadID); + static void DrawDecals(const wiSceneSystem::CameraComponent& camera, GRAPHICSTHREAD threadID); static void RefreshEnvProbes(GRAPHICSTHREAD threadID); static void VoxelRadiance(GRAPHICSTHREAD threadID); @@ -399,7 +399,7 @@ public: static void ResolveMSAADepthBuffer(wiGraphicsTypes::Texture2D* dst, wiGraphicsTypes::Texture2D* src, GRAPHICSTHREAD threadID); static void BuildSceneBVH(GRAPHICSTHREAD threadID); - static void DrawTracedScene(wiSceneSystem::CameraComponent* camera, wiGraphicsTypes::Texture2D* result, GRAPHICSTHREAD threadID); + static void DrawTracedScene(const wiSceneSystem::CameraComponent& camera, wiGraphicsTypes::Texture2D* result, GRAPHICSTHREAD threadID); enum MIPGENFILTER { @@ -436,11 +436,11 @@ public: static std::deque waterRipples; static void ClearWorld(); - static wiSceneSystem::CameraComponent* getCamera(); - static wiSceneSystem::CameraComponent* getPrevCamera(); - static wiSceneSystem::CameraComponent* getRefCamera(); + static wiSceneSystem::CameraComponent& GetCamera(); + static wiSceneSystem::CameraComponent& GetPrevCamera(); + static wiSceneSystem::CameraComponent& GetRefCamera(); - static RAY getPickRay(long cursorX, long cursorY); + static RAY GetPickRay(long cursorX, long cursorY); struct RayIntersectWorldResult { diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index 1324a7a3d..c7c7e1e86 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -694,6 +694,8 @@ namespace wiSceneSystem } void CameraComponent::UpdateCamera(const TransformComponent* transform) { + SetDirty(false); + XMVECTOR _Eye; XMVECTOR _At; XMVECTOR _Up; @@ -784,7 +786,7 @@ namespace wiSceneSystem RunForceUpdateSystem(transforms, forces); - RunLightUpdateSystem(*wiRenderer::getCamera(), transforms, aabb_lights, lights, sunDirection, sunColor); + RunLightUpdateSystem(wiRenderer::GetCamera(), transforms, aabb_lights, lights, sunDirection, sunColor); RunParticleUpdateSystem(transforms, meshes, emitters, hairs, dt); @@ -817,6 +819,24 @@ namespace wiSceneSystem } void Scene::Merge(Scene& other) { + if (CountEntities() == 0) + { + sunDirection = other.sunDirection; + sunColor = other.sunColor; + horizon = other.horizon; + zenith = other.zenith; + ambient = other.ambient; + fogStart = other.fogStart; + fogEnd = other.fogEnd; + fogHeight = other.fogHeight; + cloudiness = other.cloudiness; + cloudScale = other.cloudScale; + cloudSpeed = other.cloudSpeed; + windDirection = other.windDirection; + windRandomness = other.windRandomness; + windWaveSize = other.windWaveSize; + } + names.Merge(other.names); layers.Merge(other.layers); transforms.Merge(other.transforms); @@ -843,6 +863,36 @@ namespace wiSceneSystem bounds = AABB::Merge(bounds, other.bounds); } + size_t Scene::CountEntities() const + { + // Entities are unique within a ComponentManager, so the most populated ComponentManager + // will actually give us how many entities there are in the scene + size_t entityCount = 0; + entityCount = max(entityCount, names.GetCount()); + entityCount = max(entityCount, layers.GetCount()); + entityCount = max(entityCount, transforms.GetCount()); + entityCount = max(entityCount, prev_transforms.GetCount()); + entityCount = max(entityCount, hierarchy.GetCount()); + entityCount = max(entityCount, materials.GetCount()); + entityCount = max(entityCount, meshes.GetCount()); + entityCount = max(entityCount, objects.GetCount()); + entityCount = max(entityCount, aabb_objects.GetCount()); + entityCount = max(entityCount, rigidbodies.GetCount()); + entityCount = max(entityCount, softbodies.GetCount()); + entityCount = max(entityCount, armatures.GetCount()); + entityCount = max(entityCount, lights.GetCount()); + entityCount = max(entityCount, aabb_lights.GetCount()); + entityCount = max(entityCount, cameras.GetCount()); + entityCount = max(entityCount, probes.GetCount()); + entityCount = max(entityCount, aabb_probes.GetCount()); + entityCount = max(entityCount, forces.GetCount()); + entityCount = max(entityCount, decals.GetCount()); + entityCount = max(entityCount, aabb_decals.GetCount()); + entityCount = max(entityCount, animations.GetCount()); + entityCount = max(entityCount, emitters.GetCount()); + entityCount = max(entityCount, hairs.GetCount()); + return entityCount; + } void Scene::Entity_Remove(Entity entity) { @@ -881,20 +931,6 @@ namespace wiSceneSystem } return INVALID_ENTITY; } - Entity Scene::Entity_CreateModel( - const std::string& name - ) - { - Entity entity = CreateEntity(); - - names.Create(entity) = name; - - layers.Create(entity); - - transforms.Create(entity); - - return entity; - } Entity Scene::Entity_CreateMaterial( const std::string& name ) @@ -1132,13 +1168,13 @@ namespace wiSceneSystem { // Save the parent's inverse worldmatrix: XMStoreFloat4x4(&parentcomponent.world_parent_inverse_bind, XMMatrixInverse(nullptr, XMLoadFloat4x4(&transform_parent->world))); - } - TransformComponent* transform_child = transforms.GetComponent(entity); - if (transform_child != nullptr) - { - // Child updated immediately, to that it can be immediately attached to afterwards: - transform_child->UpdateParentedTransform(*transform_parent, parentcomponent.world_parent_inverse_bind); + TransformComponent* transform_child = transforms.GetComponent(entity); + if (transform_child != nullptr) + { + // Child updated immediately, to that it can be immediately attached to afterwards: + transform_child->UpdateParentedTransform(*transform_parent, parentcomponent.world_parent_inverse_bind); + } } LayerComponent* layer_child = layers.GetComponent(entity); @@ -1738,7 +1774,7 @@ namespace wiSceneSystem } } - aabb.createFromHalfWidth(wiRenderer::getCamera()->Eye, XMFLOAT3(10000, 10000, 10000)); + aabb.createFromHalfWidth(wiRenderer::GetCamera().Eye, XMFLOAT3(10000, 10000, 10000)); } break; case LightComponent::SPOT: @@ -1793,7 +1829,7 @@ namespace wiSceneSystem XMStoreFloat3(&light.right, XMVector3TransformNormal(XMVectorSet(-1, 0, 0, 0), W)); XMStoreFloat3(&light.front, XMVector3TransformNormal(XMVectorSet(0, 0, -1, 0), W)); // area lights have no bounds, just like directional lights (maybe todo) - aabb.createFromHalfWidth(wiRenderer::getCamera()->Eye, XMFLOAT3(10000, 10000, 10000)); + aabb.createFromHalfWidth(wiRenderer::GetCamera().Eye, XMFLOAT3(10000, 10000, 10000)); } } break; diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index 84c21813a..0d8161b2c 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -28,7 +28,7 @@ namespace wiSceneSystem inline void operator=(const std::string& str) { strcpy_s(name, str.c_str()); } inline bool operator==(const std::string& str) const { return strcmp(name, str.c_str()) == 0; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct LayerComponent @@ -37,7 +37,7 @@ namespace wiSceneSystem inline uint32_t GetLayerMask() const { return layerMask; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct TransformComponent @@ -78,7 +78,7 @@ namespace wiSceneSystem void Lerp(const TransformComponent& a, const TransformComponent& b, float t); void CatmullRom(const TransformComponent& a, const TransformComponent& b, const TransformComponent& c, const TransformComponent& d, float t); - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct PreviousFrameTransformComponent @@ -86,7 +86,7 @@ namespace wiSceneSystem // Non-serialized attributes: XMFLOAT4X4 world_prev; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct HierarchyComponent @@ -95,7 +95,7 @@ namespace wiSceneSystem uint32_t layerMask_bind; // saved child layermask at the time of binding XMFLOAT4X4 world_parent_inverse_bind; // saved parent inverse worldmatrix at the time of binding - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct MaterialComponent @@ -187,7 +187,7 @@ namespace wiSceneSystem inline void SetOpacity(float value) { SetDirty(); baseColor.w = value; } inline void SetAlphaRef(float value) { alphaRef = value; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct MeshComponent @@ -249,7 +249,7 @@ namespace wiSceneSystem void FlipCulling(); void FlipNormals(); - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); struct Vertex_POS @@ -408,7 +408,7 @@ namespace wiSceneSystem inline float GetTransparency() const { return 1 - color.w; } inline uint32_t GetRenderTypes() const { return rendertypeMask; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct RigidBodyPhysicsComponent @@ -440,7 +440,7 @@ namespace wiSceneSystem // Non-serialized attributes: int physicsObjectID = -1; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct SoftBodyPhysicsComponent @@ -460,7 +460,7 @@ namespace wiSceneSystem // Non-serialized attributes: int physicsObjectID = -1; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct ArmatureComponent @@ -496,7 +496,7 @@ namespace wiSceneSystem std::vector boneData; std::unique_ptr boneBuffer; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct LightComponent @@ -665,7 +665,7 @@ namespace wiSceneSystem std::vector shadowCam_dirLight; std::vector shadowCam_spotLight; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct CameraComponent @@ -673,6 +673,7 @@ namespace wiSceneSystem enum FLAGS { EMPTY = 0, + DIRTY = 1 << 0, }; uint32_t _flags = EMPTY; @@ -707,7 +708,10 @@ namespace wiSceneSystem inline XMMATRIX GetInvViewProjection() const { return XMLoadFloat4x4(&InvVP); } inline XMMATRIX GetRealProjection() const { return XMLoadFloat4x4(&realProjection); } - void Serialize(wiArchive& archive); + inline void SetDirty(bool value = true) { if (value) { _flags |= DIRTY; } else { _flags &= ~DIRTY; } } + inline bool IsDirty() const { return _flags & DIRTY; } + + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct EnvironmentProbeComponent @@ -732,7 +736,7 @@ namespace wiSceneSystem inline bool IsDirty() const { return _flags & DIRTY; } inline bool IsRealTime() const { return _flags & REALTIME; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct ForceFieldComponent @@ -751,7 +755,7 @@ namespace wiSceneSystem XMFLOAT3 position; XMFLOAT3 direction; - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct DecalComponent @@ -776,7 +780,7 @@ namespace wiSceneSystem inline float GetOpacity() const { return color.w; } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct AnimationComponent @@ -830,7 +834,7 @@ namespace wiSceneSystem inline void Stop() { Pause(); timer = 0.0f; } inline void SetLooped(bool value = true) { if (value) { _flags |= LOOPED; } else { _flags &= ~LOOPED; } } - void Serialize(wiArchive& archive); + void Serialize(wiArchive& archive, uint32_t seed = 0); }; struct Scene @@ -882,17 +886,20 @@ namespace wiSceneSystem void Update(float dt); // Remove everything from the scene that it owns: void Clear(); - // Merge with an other scene (world properties like ambient, etc. are retained as-is). Other scene state is non-retained! + // Merge with an other scene. Other scene state is non-retained! void Merge(Scene& other); + // Count how many entities there are in the scene: + size_t CountEntities() const; // Removes a specific entity from the scene (if it exists): void Entity_Remove(wiECS::Entity entity); // Finds the first entity by the name (if it exists, otherwise returns INVALID_ENTITY): wiECS::Entity Entity_FindByName(const std::string& name); + // Serializes entity and all of its components to archive: + // You can specify entity = INVALID_ENTITY when the entity needs to be created from archive + // You can specify seed = 0 when the archive is guaranteed to be storing persistent and unique entities + void Entity_Serialize(wiArchive& archive, wiECS::Entity entity = wiECS::INVALID_ENTITY, uint32_t seed = 0); - wiECS::Entity Entity_CreateModel( - const std::string& name - ); wiECS::Entity Entity_CreateMaterial( const std::string& name ); diff --git a/WickedEngine/wiSceneSystem_Serializers.cpp b/WickedEngine/wiSceneSystem_Serializers.cpp index 01d9b4046..7ad58a6ad 100644 --- a/WickedEngine/wiSceneSystem_Serializers.cpp +++ b/WickedEngine/wiSceneSystem_Serializers.cpp @@ -1,11 +1,14 @@ #include "wiSceneSystem.h" #include "wiResourceManager.h" #include "wiArchive.h" +#include "wiRandom.h" + +using namespace wiECS; namespace wiSceneSystem { - void NameComponent::Serialize(wiArchive& archive) + void NameComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -19,7 +22,7 @@ namespace wiSceneSystem archive << tmp; } } - void LayerComponent::Serialize(wiArchive& archive) + void LayerComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -30,7 +33,7 @@ namespace wiSceneSystem archive << layerMask; } } - void TransformComponent::Serialize(wiArchive& archive) + void TransformComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -49,27 +52,27 @@ namespace wiSceneSystem archive << translation_local; } } - void PreviousFrameTransformComponent::Serialize(wiArchive& archive) + void PreviousFrameTransformComponent::Serialize(wiArchive& archive, uint32_t seed) { // NOTHING! We just need a serialize function for this to be able serialize with ComponentManager! // This structure has no persistent state! } - void HierarchyComponent::Serialize(wiArchive& archive) + void HierarchyComponent::Serialize(wiArchive& archive, uint32_t seed) { + SerializeEntity(archive, parentID, seed); + if (archive.IsReadMode()) { - archive >> parentID; archive >> layerMask_bind; archive >> world_parent_inverse_bind; } else { - archive << parentID; archive << layerMask_bind; archive << world_parent_inverse_bind; } } - void MaterialComponent::Serialize(wiArchive& archive) + void MaterialComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -143,8 +146,9 @@ namespace wiSceneSystem archive << displacementMapName; } } - void MeshComponent::Serialize(wiArchive& archive) + void MeshComponent::Serialize(wiArchive& archive, uint32_t seed) { + if (archive.IsReadMode()) { archive >> _flags; @@ -160,14 +164,14 @@ namespace wiSceneSystem subsets.resize(subsetCount); for (size_t i = 0; i < subsetCount; ++i) { - archive >> subsets[i].materialID; + SerializeEntity(archive, subsets[i].materialID, seed); archive >> subsets[i].indexOffset; archive >> subsets[i].indexCount; } archive >> tessellationFactor; archive >> impostorDistance; - archive >> armatureID; + SerializeEntity(archive, armatureID, seed); CreateRenderData(); } @@ -184,23 +188,23 @@ namespace wiSceneSystem archive << subsets.size(); for (size_t i = 0; i < subsets.size(); ++i) { - archive << subsets[i].materialID; + SerializeEntity(archive, subsets[i].materialID, seed); archive << subsets[i].indexOffset; archive << subsets[i].indexCount; } archive << tessellationFactor; archive << impostorDistance; - archive << armatureID; + SerializeEntity(archive, armatureID, seed); } } - void ObjectComponent::Serialize(wiArchive& archive) + void ObjectComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { archive >> _flags; - archive >> meshID; + SerializeEntity(archive, meshID, seed); archive >> cascadeMask; archive >> rendertypeMask; archive >> color; @@ -208,13 +212,13 @@ namespace wiSceneSystem else { archive << _flags; - archive << meshID; + SerializeEntity(archive, meshID, seed); archive << cascadeMask; archive << rendertypeMask; archive << color; } } - void RigidBodyPhysicsComponent::Serialize(wiArchive& archive) + void RigidBodyPhysicsComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -237,7 +241,7 @@ namespace wiSceneSystem archive << damping; } } - void SoftBodyPhysicsComponent::Serialize(wiArchive& archive) + void SoftBodyPhysicsComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -256,12 +260,16 @@ namespace wiSceneSystem archive << physicsindices; } } - void ArmatureComponent::Serialize(wiArchive& archive) + void ArmatureComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { archive >> _flags; archive >> boneCollection; + for (Entity& boneID : boneCollection) + { + SerializeEntity(archive, boneID, seed); + } archive >> inverseBindMatrices; archive >> remapMatrix; } @@ -273,7 +281,7 @@ namespace wiSceneSystem archive << remapMatrix; } } - void LightComponent::Serialize(wiArchive& archive) + void LightComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -306,7 +314,7 @@ namespace wiSceneSystem archive << lensFlareNames; } } - void CameraComponent::Serialize(wiArchive& archive) + void CameraComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -316,6 +324,8 @@ namespace wiSceneSystem archive >> zNearP; archive >> zFarP; archive >> fov; + + SetDirty(); } else { @@ -327,7 +337,7 @@ namespace wiSceneSystem archive << fov; } } - void EnvironmentProbeComponent::Serialize(wiArchive& archive) + void EnvironmentProbeComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -340,7 +350,7 @@ namespace wiSceneSystem archive << _flags; } } - void ForceFieldComponent::Serialize(wiArchive& archive) + void ForceFieldComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -357,7 +367,7 @@ namespace wiSceneSystem archive << range; } } - void DecalComponent::Serialize(wiArchive& archive) + void DecalComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -368,7 +378,7 @@ namespace wiSceneSystem archive << _flags; } } - void AnimationComponent::Serialize(wiArchive& archive) + void AnimationComponent::Serialize(wiArchive& archive, uint32_t seed) { if (archive.IsReadMode()) { @@ -381,7 +391,7 @@ namespace wiSceneSystem for (size_t i = 0; i < channelCount; ++i) { archive >> channels[i]._flags; - archive >> channels[i].target; + SerializeEntity(archive, channels[i].target, seed); archive >> (uint32_t&)channels[i].type; archive >> (uint32_t&)channels[i].mode; archive >> channels[i].keyframe_times; @@ -397,7 +407,7 @@ namespace wiSceneSystem for (size_t i = 0; i < channels.size(); ++i) { archive << channels[i]._flags; - archive << channels[i].target; + SerializeEntity(archive, channels[i].target, seed); archive << (uint32_t&)channels[i].type; archive << (uint32_t&)channels[i].mode; archive << channels[i].keyframe_times; @@ -408,29 +418,42 @@ namespace wiSceneSystem void Scene::Serialize(wiArchive& archive) { - names.Serialize(archive); - layers.Serialize(archive); - transforms.Serialize(archive); - prev_transforms.Serialize(archive); - hierarchy.Serialize(archive); - materials.Serialize(archive); - meshes.Serialize(archive); - objects.Serialize(archive); - aabb_objects.Serialize(archive); - rigidbodies.Serialize(archive); - softbodies.Serialize(archive); - armatures.Serialize(archive); - lights.Serialize(archive); - aabb_lights.Serialize(archive); - cameras.Serialize(archive); - probes.Serialize(archive); - aabb_probes.Serialize(archive); - forces.Serialize(archive); - decals.Serialize(archive); - aabb_decals.Serialize(archive); - animations.Serialize(archive); - emitters.Serialize(archive); - hairs.Serialize(archive); + if (archive.IsReadMode()) + { + uint32_t entityCount; + archive >> entityCount; // reserved + } + else + { + archive << CountEntities(); + } + + // With this we will ensure that serialized entities are unique and persistent across the scene: + uint32_t seed = (uint32_t)wiRandom::getRandom(1, INT_MAX); + + names.Serialize(archive, seed); + layers.Serialize(archive, seed); + transforms.Serialize(archive, seed); + prev_transforms.Serialize(archive, seed); + hierarchy.Serialize(archive, seed); + materials.Serialize(archive, seed); + meshes.Serialize(archive, seed); + objects.Serialize(archive, seed); + aabb_objects.Serialize(archive, seed); + rigidbodies.Serialize(archive, seed); + softbodies.Serialize(archive, seed); + armatures.Serialize(archive, seed); + lights.Serialize(archive, seed); + aabb_lights.Serialize(archive, seed); + cameras.Serialize(archive, seed); + probes.Serialize(archive, seed); + aabb_probes.Serialize(archive, seed); + forces.Serialize(archive, seed); + decals.Serialize(archive, seed); + aabb_decals.Serialize(archive, seed); + animations.Serialize(archive, seed); + emitters.Serialize(archive, seed); + hairs.Serialize(archive, seed); if (archive.IsReadMode()) { @@ -469,4 +492,506 @@ namespace wiSceneSystem } + void Scene::Entity_Serialize(wiArchive& archive, Entity entity, uint32_t seed) + { + if (archive.IsReadMode()) + { + archive >> entity; + + // Check for each components if it exists, and if yes, read it: + + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = names.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = layers.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = transforms.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = prev_transforms.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = hierarchy.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = materials.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = meshes.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = objects.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = aabb_objects.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = rigidbodies.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = softbodies.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = armatures.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = lights.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = aabb_lights.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = cameras.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = probes.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = aabb_probes.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = forces.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = decals.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = aabb_decals.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = animations.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = emitters.Create(entity); + component.Serialize(archive, seed); + } + } + { + bool component_exists; + archive >> component_exists; + if (component_exists) + { + auto& component = hairs.Create(entity); + component.Serialize(archive, seed); + } + } + } + else + { + archive << entity; + + // Find existing components one-by-one and write them out: + + { + auto component = names.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = layers.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = transforms.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = prev_transforms.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = hierarchy.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = materials.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = meshes.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = objects.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = aabb_objects.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = rigidbodies.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = softbodies.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = armatures.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = lights.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = aabb_lights.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = cameras.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = probes.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = aabb_probes.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = forces.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = decals.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = aabb_decals.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = animations.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = emitters.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + { + auto component = hairs.GetComponent(entity); + if (component != nullptr) + { + archive << true; + component->Serialize(archive, seed); + } + else + { + archive << false; + } + } + + } + } + }