From 6823f9602720c110c4779451a3605b510e169437 Mon Sep 17 00:00:00 2001 From: turanszkij Date: Tue, 4 Sep 2018 18:06:10 +0100 Subject: [PATCH] start systemizing --- WickedEngine/wiECS.h | 23 ++- WickedEngine/wiRenderer.cpp | 9 +- WickedEngine/wiSceneSystem.cpp | 326 ++++++++++++++++++--------------- WickedEngine/wiSceneSystem.h | 20 ++ 4 files changed, 223 insertions(+), 155 deletions(-) diff --git a/WickedEngine/wiECS.h b/WickedEngine/wiECS.h index 1b7cb9e7f..3322844ca 100644 --- a/WickedEngine/wiECS.h +++ b/WickedEngine/wiECS.h @@ -115,7 +115,13 @@ namespace wiECS } - // Retrieve a component specified by an entity (if it exists, otherwise nullptr): + // Check if a component exists for a given entity or not: + inline bool Contains(Entity entity) const + { + return lookup.find(entity) != lookup.end(); + } + + // Retrieve a [read/write] component specified by an entity (if it exists, otherwise nullptr): inline T* GetComponent(Entity entity) { auto it = lookup.find(entity); @@ -126,6 +132,17 @@ namespace wiECS return nullptr; } + // Retrieve a [read only] component specified by an entity (if it exists, otherwise nullptr): + inline const T* GetComponent(Entity entity) const + { + const auto it = lookup.find(entity); + if (it != lookup.end()) + { + return &components[it->second]; + } + return nullptr; + } + // Retrieve the number of existing entries: inline size_t GetCount() const { return components.size(); } @@ -133,11 +150,11 @@ namespace wiECS // 0 <= index < GetCount() inline Entity GetEntity(size_t index) const { return entities[index]; } - // Directly index a specific component without indirection: + // Directly index a specific [read/write] component without indirection: // 0 <= index < GetCount() inline T& operator[](size_t index) { return components[index]; } - // Directly index a specific component without indirection: + // Directly index a specific [read only] component without indirection: // 0 <= index < GetCount() inline const T& operator[](size_t index) const { return components[index]; } diff --git a/WickedEngine/wiRenderer.cpp b/WickedEngine/wiRenderer.cpp index 5e23ce6e2..7283aa849 100644 --- a/WickedEngine/wiRenderer.cpp +++ b/WickedEngine/wiRenderer.cpp @@ -3017,22 +3017,19 @@ void wiRenderer::UpdatePerFrameData(float dt) } else if (camera == getCamera()) // the following cullings will be only for the main camera: { - const LightComponent* light = scene.lights.GetComponent(entity); - if (light != nullptr) + if (scene.lights.Contains(entity)) { culling.culledLights.push_back(entity); continue; } - const DecalComponent* decal = scene.decals.GetComponent(entity); - if (decal != nullptr) + if (scene.decals.Contains(entity)) { culling.culledDecals.push_back(entity); continue; } - const EnvironmentProbeComponent* probe = scene.probes.GetComponent(entity); - if (probe != nullptr) + if (scene.probes.Contains(entity)) { culling.culledEnvProbes.push_back(entity); continue; diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp index 0e3a6c581..9000afcf2 100644 --- a/WickedEngine/wiSceneSystem.cpp +++ b/WickedEngine/wiSceneSystem.cpp @@ -695,67 +695,11 @@ namespace wiSceneSystem void Scene::Update(float dt) { - // Update Transform components: - for (size_t i = 0; i < transforms.GetCount(); ++i) - { - TransformComponent& transform = transforms[i]; - transform.UpdateTransform(); - } + RunTransformUpdateSystem(transforms); - // Update Hierarchy: - for (size_t i = 0; i < parents.GetCount(); ++i) - { - const ParentComponent& parentcomponent = parents[i]; - Entity entity = parents.GetEntity(i); + RunHierarchyUpdateSystem(parents, transforms, layers); - TransformComponent* transform_child = transforms.GetComponent(entity); - TransformComponent* transform_parent = transforms.GetComponent(parentcomponent.parentID); - if (transform_child != nullptr && transform_parent != nullptr) - { - XMVECTOR S_local = XMLoadFloat3(&transform_child->scale_local); - XMVECTOR R_local = XMLoadFloat4(&transform_child->rotation_local); - XMVECTOR T_local = XMLoadFloat3(&transform_child->translation_local); - XMMATRIX W = - XMMatrixScalingFromVector(S_local) * - XMMatrixRotationQuaternion(R_local) * - XMMatrixTranslationFromVector(T_local); - - XMMATRIX W_parent = XMLoadFloat4x4(&transform_parent->world); - XMMATRIX B = XMLoadFloat4x4(&parentcomponent.world_parent_inverse_bind); - W = W * B * W_parent; - - XMVECTOR S, R, T; - XMMatrixDecompose(&S, &R, &T, W); - XMStoreFloat3(&transform_child->scale, S); - XMStoreFloat4(&transform_child->rotation, R); - XMStoreFloat3(&transform_child->translation, T); - - transform_child->world_prev = transform_child->world; - XMStoreFloat4x4(&transform_child->world, W); - } - - - LayerComponent* layer_child = layers.GetComponent(entity); - LayerComponent* layer_parent = layers.GetComponent(parentcomponent.parentID); - if (layer_child != nullptr && layer_parent != nullptr) - { - layer_child->layerMask = parentcomponent.layerMask_bind & layer_parent->GetLayerMask(); - } - - } - - // Update Bone components: - for (size_t i = 0; i < bones.GetCount(); ++i) - { - BoneComponent& bone = bones[i]; - Entity entity = bones.GetEntity(i); - const TransformComponent& transform = *transforms.GetComponent(entity); - - XMMATRIX inverseBindPoseMatrix = XMLoadFloat4x4(&bone.inverseBindPoseMatrix); - XMMATRIX world = XMLoadFloat4x4(&transform.world); - XMMATRIX skinningMatrix = inverseBindPoseMatrix * world; - XMStoreFloat4x4(&bone.skinningMatrix, skinningMatrix); - } + RunBoneUpdateSystem(transforms, bones); // Update Physics components: for (size_t i = 0; i < physicscomponents.GetCount(); ++i) @@ -770,84 +714,9 @@ namespace wiSceneSystem } } - // Update Material components: - for (size_t i = 0; i < materials.GetCount(); ++i) - { - MaterialComponent& material = materials[i]; + RunMaterialUpdateSystem(materials, dt); - material.texAnimSleep -= dt * material.texAnimFrameRate; - if (material.texAnimSleep <= 0) - { - material.texMulAdd.z = fmodf(material.texMulAdd.z + material.texAnimDirection.x, 1); - material.texMulAdd.w = fmodf(material.texMulAdd.w + material.texAnimDirection.y, 1); - material.texAnimSleep = 1.0f; - - material.dirty = true; // will trigger constant buffer update! - } - - material.engineStencilRef = STENCILREF_DEFAULT; - if (material.subsurfaceScattering > 0) - { - material.engineStencilRef = STENCILREF_SKIN; - } - - } - - // Update Object components: - for (size_t i = 0; i < objects.GetCount(); ++i) - { - ObjectComponent& object = objects[i]; - Entity entity = objects.GetEntity(i); - CullableComponent& cullable = *cullables.GetComponent(entity); - - cullable.aabb.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(0, 0, 0)); - object.rendertypeMask = 0; - object.dynamic = false; - object.cast_shadow = false; - - if (object.meshID != INVALID_ENTITY) - { - const TransformComponent* transform = transforms.GetComponent(entity); - const MeshComponent* mesh = meshes.GetComponent(object.meshID); - - if (mesh != nullptr && transform != nullptr) - { - cullable.aabb = mesh->aabb.get(transform->world); - - if (mesh->IsSkinned() || mesh->IsDynamicVB()) - { - object.dynamic = true; - } - - for (auto& subset : mesh->subsets) - { - const MaterialComponent* material = materials.GetComponent(subset.materialID); - - if (material != nullptr) - { - if (material->IsTransparent()) - { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT; - } - else - { - object.rendertypeMask |= RENDERTYPE_OPAQUE; - } - - if (material->IsWater()) - { - object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; - - XMVECTOR _refPlane = XMPlaneFromPointNormal(XMLoadFloat3(&transform->translation), XMVectorSet(0, 1, 0, 0)); - XMStoreFloat4(&waterPlane, _refPlane); - } - - object.cast_shadow |= material->cast_shadow; - } - } - } - } - } + RunObjectUpdateSystem(transforms, meshes, materials, objects, cullables, waterPlane); // Update Camera components: for (size_t i = 0; i < cameras.GetCount(); ++i) @@ -1106,7 +975,7 @@ namespace wiSceneSystem } return INVALID_ENTITY; } - wiECS::Entity Scene::Entity_CreateModel( + Entity Scene::Entity_CreateModel( const std::string& name ) { @@ -1124,7 +993,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateMaterial( + Entity Scene::Entity_CreateMaterial( const std::string& name ) { @@ -1138,7 +1007,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateObject( + Entity Scene::Entity_CreateObject( const std::string& name ) { @@ -1158,7 +1027,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateMesh( + Entity Scene::Entity_CreateMesh( const std::string& name ) { @@ -1200,7 +1069,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateForce( + Entity Scene::Entity_CreateForce( const std::string& name, const XMFLOAT3& position ) @@ -1222,7 +1091,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateEnvironmentProbe( + Entity Scene::Entity_CreateEnvironmentProbe( const std::string& name, const XMFLOAT3& position ) @@ -1246,7 +1115,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateDecal( + Entity Scene::Entity_CreateDecal( const std::string& name, const std::string& textureName, const std::string& normalMapName @@ -1279,7 +1148,7 @@ namespace wiSceneSystem return entity; } - wiECS::Entity Scene::Entity_CreateCamera( + Entity Scene::Entity_CreateCamera( const std::string& name, float width, float height, float nearPlane, float farPlane, float fov ) @@ -1326,7 +1195,7 @@ namespace wiSceneSystem parentcomponent->layerMask_bind = layer_child->GetLayerMask(); } } - void Scene::Component_Detach(wiECS::Entity entity) + void Scene::Component_Detach(Entity entity) { const ParentComponent* parent = parents.GetComponent(entity); @@ -1347,7 +1216,7 @@ namespace wiSceneSystem parents.Remove(entity); } } - void Scene::Component_DetachChildren(wiECS::Entity parent) + void Scene::Component_DetachChildren(Entity parent) { for (size_t i = 0; i < parents.GetCount(); ) { @@ -1363,4 +1232,169 @@ namespace wiSceneSystem } } + + + + void RunTransformUpdateSystem(ComponentManager& transforms) + { + for (size_t i = 0; i < transforms.GetCount(); ++i) + { + TransformComponent& transform = transforms[i]; + transform.UpdateTransform(); + } + } + void RunHierarchyUpdateSystem( + const ComponentManager parents, + ComponentManager& transforms, + ComponentManager& layers + ) + { + for (size_t i = 0; i < parents.GetCount(); ++i) + { + const ParentComponent& parentcomponent = parents[i]; + Entity entity = parents.GetEntity(i); + + TransformComponent* transform_child = transforms.GetComponent(entity); + TransformComponent* transform_parent = transforms.GetComponent(parentcomponent.parentID); + if (transform_child != nullptr && transform_parent != nullptr) + { + XMVECTOR S_local = XMLoadFloat3(&transform_child->scale_local); + XMVECTOR R_local = XMLoadFloat4(&transform_child->rotation_local); + XMVECTOR T_local = XMLoadFloat3(&transform_child->translation_local); + XMMATRIX W = + XMMatrixScalingFromVector(S_local) * + XMMatrixRotationQuaternion(R_local) * + XMMatrixTranslationFromVector(T_local); + + XMMATRIX W_parent = XMLoadFloat4x4(&transform_parent->world); + XMMATRIX B = XMLoadFloat4x4(&parentcomponent.world_parent_inverse_bind); + W = W * B * W_parent; + + XMVECTOR S, R, T; + XMMatrixDecompose(&S, &R, &T, W); + XMStoreFloat3(&transform_child->scale, S); + XMStoreFloat4(&transform_child->rotation, R); + XMStoreFloat3(&transform_child->translation, T); + + transform_child->world_prev = transform_child->world; + XMStoreFloat4x4(&transform_child->world, W); + } + + + LayerComponent* layer_child = layers.GetComponent(entity); + LayerComponent* layer_parent = layers.GetComponent(parentcomponent.parentID); + if (layer_child != nullptr && layer_parent != nullptr) + { + layer_child->layerMask = parentcomponent.layerMask_bind & layer_parent->GetLayerMask(); + } + + } + } + void RunBoneUpdateSystem( + const ComponentManager& transforms, + ComponentManager& bones + ) + { + for (size_t i = 0; i < bones.GetCount(); ++i) + { + BoneComponent& bone = bones[i]; + Entity entity = bones.GetEntity(i); + const TransformComponent& transform = *transforms.GetComponent(entity); + + XMMATRIX inverseBindPoseMatrix = XMLoadFloat4x4(&bone.inverseBindPoseMatrix); + XMMATRIX world = XMLoadFloat4x4(&transform.world); + XMMATRIX skinningMatrix = inverseBindPoseMatrix * world; + XMStoreFloat4x4(&bone.skinningMatrix, skinningMatrix); + } + } + void RunMaterialUpdateSystem(ComponentManager& materials, float dt) + { + for (size_t i = 0; i < materials.GetCount(); ++i) + { + MaterialComponent& material = materials[i]; + + material.texAnimSleep -= dt * material.texAnimFrameRate; + if (material.texAnimSleep <= 0) + { + material.texMulAdd.z = fmodf(material.texMulAdd.z + material.texAnimDirection.x, 1); + material.texMulAdd.w = fmodf(material.texMulAdd.w + material.texAnimDirection.y, 1); + material.texAnimSleep = 1.0f; + + material.dirty = true; // will trigger constant buffer update! + } + + material.engineStencilRef = STENCILREF_DEFAULT; + if (material.subsurfaceScattering > 0) + { + material.engineStencilRef = STENCILREF_SKIN; + } + + } + } + void RunObjectUpdateSystem( + const ComponentManager& transforms, + const ComponentManager& meshes, + const ComponentManager& materials, + ComponentManager& objects, + ComponentManager& cullables, + XMFLOAT4& waterPlane + ) + { + for (size_t i = 0; i < objects.GetCount(); ++i) + { + ObjectComponent& object = objects[i]; + Entity entity = objects.GetEntity(i); + CullableComponent& cullable = *cullables.GetComponent(entity); + + cullable.aabb.createFromHalfWidth(XMFLOAT3(0, 0, 0), XMFLOAT3(0, 0, 0)); + object.rendertypeMask = 0; + object.dynamic = false; + object.cast_shadow = false; + + if (object.meshID != INVALID_ENTITY) + { + const TransformComponent* transform = transforms.GetComponent(entity); + const MeshComponent* mesh = meshes.GetComponent(object.meshID); + + if (mesh != nullptr && transform != nullptr) + { + cullable.aabb = mesh->aabb.get(transform->world); + + if (mesh->IsSkinned() || mesh->IsDynamicVB()) + { + object.dynamic = true; + } + + for (auto& subset : mesh->subsets) + { + const MaterialComponent* material = materials.GetComponent(subset.materialID); + + if (material != nullptr) + { + if (material->IsTransparent()) + { + object.rendertypeMask |= RENDERTYPE_TRANSPARENT; + } + else + { + object.rendertypeMask |= RENDERTYPE_OPAQUE; + } + + if (material->IsWater()) + { + object.rendertypeMask |= RENDERTYPE_TRANSPARENT | RENDERTYPE_WATER; + + XMVECTOR _refPlane = XMPlaneFromPointNormal(XMLoadFloat3(&transform->translation), XMVectorSet(0, 1, 0, 0)); + XMStoreFloat4(&waterPlane, _refPlane); + } + + object.cast_shadow |= material->cast_shadow; + } + } + } + } + } + } + + } diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h index d35ddb3d8..c1236b2e5 100644 --- a/WickedEngine/wiSceneSystem.h +++ b/WickedEngine/wiSceneSystem.h @@ -736,5 +736,25 @@ namespace wiSceneSystem void Component_DetachChildren(wiECS::Entity parent); }; + void RunTransformUpdateSystem(wiECS::ComponentManager& transforms); + void RunHierarchyUpdateSystem( + const wiECS::ComponentManager parents, + wiECS::ComponentManager& transforms, + wiECS::ComponentManager& layers + ); + void RunBoneUpdateSystem( + const wiECS::ComponentManager& transforms, + wiECS::ComponentManager& bones + ); + void RunMaterialUpdateSystem(wiECS::ComponentManager& materials, float dt); + void RunObjectUpdateSystem( + const wiECS::ComponentManager& transforms, + const wiECS::ComponentManager& meshes, + const wiECS::ComponentManager& materials, + wiECS::ComponentManager& objects, + wiECS::ComponentManager& cullables, + XMFLOAT4& waterPlane + ); + }