diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems b/WickedEngine/WickedEngine_SHARED.vcxitems index 916c8d764..e2471c055 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems +++ b/WickedEngine/WickedEngine_SHARED.vcxitems @@ -254,6 +254,7 @@ + @@ -354,6 +355,8 @@ + + @@ -692,6 +695,7 @@ + diff --git a/WickedEngine/WickedEngine_SHARED.vcxitems.filters b/WickedEngine/WickedEngine_SHARED.vcxitems.filters index c95387e59..8e344751e 100644 --- a/WickedEngine/WickedEngine_SHARED.vcxitems.filters +++ b/WickedEngine/WickedEngine_SHARED.vcxitems.filters @@ -61,6 +61,9 @@ {052d6b54-4254-4260-ba34-79b6fb943b4a} + + {f9156b5b-9cc8-436c-9faa-536f7dce4f27} + @@ -1131,6 +1134,15 @@ ENGINE\Scripting\LuaBindings + + ENGINE\System + + + ENGINE\System + + + ENGINE\System + @@ -1925,6 +1937,9 @@ ENGINE\Scripting\LuaBindings + + ENGINE\System + diff --git a/WickedEngine/wiECS.h b/WickedEngine/wiECS.h new file mode 100644 index 000000000..4038aedcd --- /dev/null +++ b/WickedEngine/wiECS.h @@ -0,0 +1,234 @@ +#ifndef _ENTITY_COMPONENT_SYSTEM_H_ +#define _ENTITY_COMPONENT_SYSTEM_H_ + +#include +#include +#include +#include + +namespace wiECS +{ + typedef uint64_t Entity; + + template + class ComponentManager + { + public: + + // reservedCount : how much components can be held initially before growing the container + ComponentManager(size_t reservedCount = 0) + { + components.reserve(reservedCount); + entities.reserve(reservedCount); + lookup.reserve(reservedCount); + indices.reserve(reservedCount); + } + + // The iterator is an indirection to the components. Components will be moved around to remain compacted, but iterator will always be able to reference a component. + struct iterator + { + size_t value = ~0; + + inline iterator operator=(iterator other) { value = other.value; return *this; } + inline bool operator==(iterator other) const { return value == other.value; } + inline bool operator!=(iterator other) const { return value != other.value; } + inline iterator& operator++() { value++; return *this; } + inline iterator operator++(int v) { iterator temp = *this; ++*this; return temp; } + inline iterator& operator--() { value--; return *this; } + inline iterator operator--(int v) { iterator temp = *this; --*this; return temp; } + }; + + // Clear the whole container, invalidate all iterators + inline void Clear() + { + components.clear(); + entities.clear(); + lookup.clear(); + indices.clear(); + dead.clear(); + } + + // Get the beginning of the iteration sequence (iterator is safe but uses indirection): + inline iterator Begin() const + { + iterator it; + it.value = 0; + return it; + } + + // Get the end of the iteration sequence (iterator is safe but uses indirection): + inline iterator End() const + { + iterator it; + it.value = indices.size(); + return it; + } + + // Check if an iterator is referencing a component or not (iterator is safe but uses indirection): + inline bool IsValid(iterator it) const + { + return it.value < indices.size() && indices[it.value] < components.size(); + } + + // Check if an iterator is referencing a specific entity or not (iterator is safe but uses indirection): + inline bool IsValid(iterator it, Entity entity) const + { + assert(entities.size() == components.size()); + return IsValid(it) && entities[indices[it.value]] == entity; + } + + // Create a new component and retrieve iterator (iterator is safe but uses indirection): + inline iterator Create(Entity entity) + { + // Only one of this component type per entity is allowed! + assert(!IsValid(Find(entity))); + + iterator it; + + if (dead.empty()) + { + // There are no dead elements, so we must have the same amount of components as indices: + assert(components.size() == indices.size()); + + // Any new component and index will just be pushed onto the end: + it.value = components.size(); + indices.push_back(it.value); + } + else + { + // We have dead elements, which means components was popped, but indices only swapped, so there must be less components than indices: + assert(components.size() < indices.size()); + + // Essentially we pop the last dead iterator and update its value to the new component (that will always be pushed to the end of components): + it = dead.back(); + dead.pop_back(); + indices[it.value] = components.size(); + } + + // Entity count must always be the same as the number of coponents! + assert(entities.size() == components.size()); + assert(lookup.size() == components.size()); + + // New components are always pushed to the end: + components.push_back(T()); + + // Also push corresponding entity: + entities.push_back(entity); + + // Update the entity lookup table: + lookup[entity] = it; + + return it; + } + + // Remove a component of a certain entity if it exists (referencing by Entity involves multiple indirection): + inline void Remove(Entity entity) + { + iterator it = Find(entity); + if (IsValid(it)) + { + Remove(it); + } + } + + // Remove a component referenced by a certain iterator (iterator is safe but uses indirection): + inline void Remove(iterator it) + { + // Iterator should be valid: + assert(IsValid(it)); + + // Directly index into components and entities array: + const size_t index = indices[it.value]; + + // Remove the corresponding entry from the lookup table: + const Entity entity = entities[index]; + lookup.erase(entity); + + // Swap out the dead element with the last one, and shrink the container: + components[index] = std::move(components.back()); // try to use move instead of copy + components.pop_back(); + entities[index] = entities.back(); + entities.pop_back(); + + // Because the last element of the container was moved to the position of the removed element, we update its iterator accordingly: + indices[components.size()] = index; + + //The current iterator is marked as dead: + indices[it.value] = ~0; + dead.push_back(it); + } + + // Swap two components' data that are referenced by iterators (iterator is safe but uses indirection): + inline void Swap(iterator a, iterator b) + { + const size_t index_a = indices[a.value]; + const size_t index_b = indices[b.value]; + + const size_t index_tmp = index_a; + const Entity entity_tmp = entities[index_a]; + const T component_tmp = std::move(components[index_a]); + + indices[a.value] = index_b; + entities[index_a] = entities[index_b]; + components[index_a] = std::move(components[index_b]); + + indices[b.value] = index_tmp; + entities[index_b] = entity_tmp; + components[index_b] = std::move(component_tmp); + } + + // Find a specific component of a certain entity if exists (referencing by Entity involves multiple indirection): + inline iterator Find(Entity entity) const + { + auto it = lookup.find(entity); + if (it != lookup.end()) + { + return it->second; + } + + return End(); + } + + // Retrieve a component specified by an iterator (iterator is safe but uses indirection): + inline T& GetComponent(iterator it) + { + assert(IsValid(it)); + return components[indices[it.value]]; + } + // Retrieve an entity specified by an iterator (iterator is safe but uses indirection): + inline Entity GetEntity(iterator it) const + { + assert(IsValid(it)); + return entities[indices[it.value]]; + } + + // Retrieve the number of existing entries: + inline size_t GetCount() const { return components.size(); } + + // Directly index a specific component without indirection: + // 0 <= index < GetCount() + inline T& GetComponent(size_t index) const { return components[index]; } + + // Directly index a specific component without indirection: + // 0 <= index < GetCount() + inline Entity GetEntity(size_t index) const { return entities[index]; } + + // Directly index a specific component without indirection: + // 0 <= index < GetCount() + inline T& operator[](size_t index) { return components[index]; } + + private: + // This is a linear array of alive components: + std::vector components; + // This is a linear array of entities corresponding to each alive component: + std::vector entities; + // This is a lookup table for entities: + std::unordered_map lookup; + // This is the indirection of iterator->component index: + std::vector indices; + // The indices will also contain dead elements, and those are saved here: + std::vector dead; + }; +} + +#endif // _ENTITY_COMPONENT_SYSTEM_H_ diff --git a/WickedEngine/wiRenderer.h b/WickedEngine/wiRenderer.h index c088bf85d..f641a8c87 100644 --- a/WickedEngine/wiRenderer.h +++ b/WickedEngine/wiRenderer.h @@ -34,14 +34,12 @@ namespace wiSceneComponents struct ForceField; } -class Lines; class Cube; class Translator; class wiParticle; class wiEmittedParticle; class wiHairParticle; class wiSprite; -class wiSPTree; class TaskThread; class PHYSICS; class wiRenderTarget; diff --git a/WickedEngine/wiSceneSystem.cpp b/WickedEngine/wiSceneSystem.cpp new file mode 100644 index 000000000..7743c383f --- /dev/null +++ b/WickedEngine/wiSceneSystem.cpp @@ -0,0 +1,53 @@ +#include "wiSceneSystem.h" + +namespace wiSceneSystem +{ + void Scene::Update(float dt) + { + // Update Transform components: + for (size_t i = 0; i < transforms.GetCount(); ++i) + { + auto& transform = transforms[i]; + + const bool parented = transforms.IsValid(transform.parent_ref); + + if (transform.dirty || parented) + { + transform.dirty = false; + + XMVECTOR scale_local = XMLoadFloat3(&transform.scale_local); + XMVECTOR rotation_local = XMLoadFloat4(&transform.rotation_local); + XMVECTOR translation_local = XMLoadFloat3(&transform.translation_local); + XMMATRIX world = + XMMatrixScalingFromVector(scale_local) * + XMMatrixRotationQuaternion(rotation_local) * + XMMatrixTranslationFromVector(translation_local); + + if (parented) + { + auto& parent = transforms.GetComponent(transform.parent_ref); + XMMATRIX world_parent = XMLoadFloat4x4(&parent.world); + XMMATRIX bindMatrix = XMLoadFloat4x4(&transform.world_parent_bind); + world = world * bindMatrix * world_parent; + } + + transform.world_prev = transform.world; + XMStoreFloat4x4(&transform.world, world); + } + + } + + // Update Bone components: + for (size_t i = 0; i < bones.GetCount(); ++i) + { + auto& bone = bones[i]; + auto& transform = transforms.GetComponent(bone.transform_ref); + + XMMATRIX inverseBindPoseMatrix = XMLoadFloat4x4(&bone.inverseBindPoseMatrix); + XMMATRIX world = XMLoadFloat4x4(&transform.world); + XMMATRIX skinningMatrix = inverseBindPoseMatrix * world; + XMStoreFloat4x4(&bone.skinningMatrix, skinningMatrix); + } + + } +} diff --git a/WickedEngine/wiSceneSystem.h b/WickedEngine/wiSceneSystem.h new file mode 100644 index 000000000..45b871bc4 --- /dev/null +++ b/WickedEngine/wiSceneSystem.h @@ -0,0 +1,510 @@ +#pragma once +#include "CommonInclude.h" +#include "wiEnums.h" +#include "wiImageEffects.h" +#include "wiIntersectables.h" +#include "ShaderInterop.h" +#include "wiFrustum.h" + +#include "wiECS.h" +#include "wiSceneSystem_Decl.h" + +#include + +namespace wiSceneSystem +{ + + struct Node + { + uint32_t layerMask = ~0; + std::string name; + }; + + struct Transform + { + wiECS::ComponentManager::iterator parent_ref; + + XMFLOAT3 scale_local = XMFLOAT3(1, 1, 1); + XMFLOAT4 rotation_local = XMFLOAT4(0, 0, 0, 1); + XMFLOAT3 translation_local = XMFLOAT3(0, 0, 0); + + bool dirty = true; + XMFLOAT4X4 world; // uninitialized on purpose + XMFLOAT4X4 world_prev; // uninitialized on purpose + XMFLOAT4X4 world_parent_bind; // uninitialized on purpose + }; + + struct Material + { + wiECS::ComponentManager::iterator node_ref; + + bool dirty = true; + + STENCILREF engineStencilRef; + uint8_t userStencilRef; + BLENDMODE blendFlag; + + XMFLOAT4 baseColor; // + alpha (.w) + XMFLOAT4 texMulAdd; + float roughness; + float reflectance; + float metalness; + float emissive; + float refractionIndex; + float subsurfaceScattering; + float normalMapStrength; + float parallaxOcclusionMapping; + + float alphaRef; + + bool cast_shadow; + bool planar_reflections; + bool water; + + std::string baseColorMapName; + wiGraphicsTypes::Texture2D* baseColorMap = nullptr; + + std::string surfaceMapName; + wiGraphicsTypes::Texture2D* surfaceMap = nullptr; + + std::string normalMapName; + wiGraphicsTypes::Texture2D* normalMap = nullptr; + + std::string displacementMapName; + wiGraphicsTypes::Texture2D* displacementMap = nullptr; + + wiGraphicsTypes::GPUBuffer* constantBuffer = nullptr; + + inline void SetUserStencilRef(uint8_t value) + { + assert(value < 128); + userStencilRef = value & 0x0F; + } + inline UINT GetStencilRef() + { + return (userStencilRef << 4) | static_cast(engineStencilRef); + } + + wiGraphicsTypes::Texture2D* GetBaseColorMap() const; + wiGraphicsTypes::Texture2D* GetNormalMap() const; + wiGraphicsTypes::Texture2D* GetSurfaceMap() const; + wiGraphicsTypes::Texture2D* GetDisplacementMap() const; + }; + + struct Mesh + { + struct Vertex_FULL + { + XMFLOAT4 pos; //pos, wind + XMFLOAT4 nor; //normal, unused + XMFLOAT4 tex; //tex, matIndex, unused + XMFLOAT4 ind; //bone indices + XMFLOAT4 wei; //bone weights + + Vertex_FULL() { + pos = XMFLOAT4(0, 0, 0, 0); + nor = XMFLOAT4(0, 0, 0, 1); + tex = XMFLOAT4(0, 0, 0, 0); + ind = XMFLOAT4(0, 0, 0, 0); + wei = XMFLOAT4(0, 0, 0, 0); + }; + Vertex_FULL(const XMFLOAT3& newPos) { + pos = XMFLOAT4(newPos.x, newPos.y, newPos.z, 1); + nor = XMFLOAT4(0, 0, 0, 1); + tex = XMFLOAT4(0, 0, 0, 0); + ind = XMFLOAT4(0, 0, 0, 0); + wei = XMFLOAT4(0, 0, 0, 0); + } + }; + struct Vertex_POS + { + XMFLOAT3 pos; + uint32_t normal_wind_matID; + + Vertex_POS() :pos(XMFLOAT3(0.0f, 0.0f, 0.0f)), normal_wind_matID(0) {} + Vertex_POS(const Vertex_FULL& vert) + { + pos.x = vert.pos.x; + pos.y = vert.pos.y; + pos.z = vert.pos.z; + MakeFromParams(XMFLOAT3(vert.nor.x, vert.nor.y, vert.nor.z), vert.pos.w, static_cast(vert.tex.z)); + } + inline XMVECTOR LoadPOS() const + { + return XMLoadFloat3(&pos); + } + inline XMVECTOR LoadNOR() const + { + return XMLoadFloat3(&GetNor_FULL()); + } + inline void MakeFromParams(const XMFLOAT3& normal) + { + normal_wind_matID = normal_wind_matID & 0xFF000000; // reset only the normals + + normal_wind_matID |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0; + normal_wind_matID |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8; + normal_wind_matID |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16; + } + inline void MakeFromParams(const XMFLOAT3& normal, float wind, uint32_t materialIndex) + { + assert(materialIndex < 16); // subset materialIndex is packed onto 4 bits + + normal_wind_matID = 0; + + normal_wind_matID |= (uint32_t)((normal.x * 0.5f + 0.5f) * 255.0f) << 0; + normal_wind_matID |= (uint32_t)((normal.y * 0.5f + 0.5f) * 255.0f) << 8; + normal_wind_matID |= (uint32_t)((normal.z * 0.5f + 0.5f) * 255.0f) << 16; + normal_wind_matID |= ((uint32_t)(wind * 15.0f) & 0x0000000F) << 24; + normal_wind_matID |= (materialIndex & 0x0000000F) << 28; + } + inline XMFLOAT3 GetNor_FULL() const + { + XMFLOAT3 nor_FULL(0, 0, 0); + + nor_FULL.x = (float)((normal_wind_matID >> 0) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor_FULL.y = (float)((normal_wind_matID >> 8) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + nor_FULL.z = (float)((normal_wind_matID >> 16) & 0x000000FF) / 255.0f * 2.0f - 1.0f; + + return nor_FULL; + } + inline float GetWind() const + { + return (float)((normal_wind_matID >> 24) & 0x0000000F) / 15.0f; + } + inline uint32_t GetMaterialIndex() const + { + return (normal_wind_matID >> 28) & 0x0000000F; + } + + static const wiGraphicsTypes::FORMAT FORMAT = wiGraphicsTypes::FORMAT::FORMAT_R32G32B32A32_FLOAT; + }; + struct Vertex_TEX + { + XMHALF2 tex; + + Vertex_TEX() :tex(XMHALF2(0.0f, 0.0f)) {} + Vertex_TEX(const Vertex_FULL& vert) + { + tex = XMHALF2(vert.tex.x, vert.tex.y); + } + + static const wiGraphicsTypes::FORMAT FORMAT = wiGraphicsTypes::FORMAT::FORMAT_R16G16_FLOAT; + }; + struct Vertex_BON + { + uint64_t ind; + uint64_t wei; + + Vertex_BON() + { + ind = 0; + wei = 0; + } + Vertex_BON(const Vertex_FULL& vert) + { + ind = 0; + wei = 0; + + ind |= (uint64_t)vert.ind.x << 0; + ind |= (uint64_t)vert.ind.y << 16; + ind |= (uint64_t)vert.ind.z << 32; + ind |= (uint64_t)vert.ind.w << 48; + + wei |= (uint64_t)(vert.wei.x * 65535.0f) << 0; + wei |= (uint64_t)(vert.wei.y * 65535.0f) << 16; + wei |= (uint64_t)(vert.wei.z * 65535.0f) << 32; + wei |= (uint64_t)(vert.wei.w * 65535.0f) << 48; + } + inline XMFLOAT4 GetInd_FULL() const + { + XMFLOAT4 ind_FULL(0, 0, 0, 0); + + ind_FULL.x = (float)((ind >> 0) & 0x0000FFFF); + ind_FULL.y = (float)((ind >> 16) & 0x0000FFFF); + ind_FULL.z = (float)((ind >> 32) & 0x0000FFFF); + ind_FULL.w = (float)((ind >> 48) & 0x0000FFFF); + + return ind_FULL; + } + inline XMFLOAT4 GetWei_FULL() const + { + XMFLOAT4 wei_FULL(0, 0, 0, 0); + + wei_FULL.x = (float)((wei >> 0) & 0x0000FFFF) / 65535.0f; + wei_FULL.y = (float)((wei >> 16) & 0x0000FFFF) / 65535.0f; + wei_FULL.z = (float)((wei >> 32) & 0x0000FFFF) / 65535.0f; + wei_FULL.w = (float)((wei >> 48) & 0x0000FFFF) / 65535.0f; + + return wei_FULL; + } + }; + + std::vector vertices_FULL; + std::vector vertices_POS; // position(xyz), normal+wind(w as uint) + std::vector vertices_TEX; // texcoords + std::vector vertices_BON; // bone indices, bone weights + std::vector vertices_Transformed_POS; // for soft body simulation + std::vector vertices_Transformed_PRE; // for soft body simulation + std::vector indices; + std::vector physicsverts; + std::vector physicsindices; + std::vector physicalmapGP; + + struct MeshSubset + { + wiECS::ComponentManager material_ref; + UINT indexBufferOffset; + + std::vector subsetIndices; + + MeshSubset(); + ~MeshSubset(); + }; + std::vector subsets; + + wiGraphicsTypes::GPUBuffer* indexBuffer; + wiGraphicsTypes::GPUBuffer* vertexBuffer_POS; + wiGraphicsTypes::GPUBuffer* vertexBuffer_TEX; + wiGraphicsTypes::GPUBuffer* vertexBuffer_BON; + wiGraphicsTypes::GPUBuffer* streamoutBuffer_POS; + wiGraphicsTypes::GPUBuffer* streamoutBuffer_PRE; + + // Dynamic vertexbuffers write into a global pool, these will be the offsets into that: + UINT bufferOffset_POS; + UINT bufferOffset_PRE; + + wiGraphicsTypes::INDEXBUFFER_FORMAT indexFormat; + + bool renderable = true; + bool doubleSided = false; + bool renderDataComplete = false; + + AABB aabb; + + wiECS::ComponentManager::iterator armature_ref; + + }; + + struct Object + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + wiECS::ComponentManager::iterator mesh_ref; + + bool renderable; + int cascadeMask = 0; // which shadow cascades to skip (0: skip none, 1: skip first, etc...) + AABB aabb; + XMFLOAT4 color; + + // occlusion result history bitfield (32 bit->32 frame history) + uint32_t occlusionHistory; + // occlusion query pool index + int occlusionQueryID; + }; + + struct Bone + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + + XMFLOAT4X4 inverseBindPoseMatrix; + XMFLOAT4X4 skinningMatrix; + }; + + struct Armature + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + + std::vector::iterator> bone_refs; + + GFX_STRUCT ShaderBoneType + { + XMFLOAT4A pose0; + XMFLOAT4A pose1; + XMFLOAT4A pose2; + + void Create(const XMFLOAT4X4& matIn) + { + pose0 = XMFLOAT4A(matIn._11, matIn._21, matIn._31, matIn._41); + pose1 = XMFLOAT4A(matIn._12, matIn._22, matIn._32, matIn._42); + pose2 = XMFLOAT4A(matIn._13, matIn._23, matIn._33, matIn._43); + } + + ALIGN_16 + }; + std::vector boneData; + wiGraphicsTypes::GPUBuffer boneBuffer; + + // This will be used to eg. mirror the whole skin, without modifying the armature transform itself + // It will affect the skin only, so the mesh vertices should be mirrored as well to work correctly! + XMFLOAT4X4 skinningRemap; + }; + + struct Light + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + + enum LightType { + DIRECTIONAL = ENTITY_TYPE_DIRECTIONALLIGHT, + POINT = ENTITY_TYPE_POINTLIGHT, + SPOT = ENTITY_TYPE_SPOTLIGHT, + SPHERE = ENTITY_TYPE_SPHERELIGHT, + DISC = ENTITY_TYPE_DISCLIGHT, + RECTANGLE = ENTITY_TYPE_RECTANGLELIGHT, + TUBE = ENTITY_TYPE_TUBELIGHT, + LIGHTTYPE_COUNT, + }; + + XMFLOAT4 color; + XMFLOAT4 enerDis; + bool volumetrics = false; + bool noHalo; + bool shadow; + std::vector lensFlareRimTextures; + std::vector lensFlareNames; + + static wiGraphicsTypes::Texture2D* shadowMapArray_2D; + static wiGraphicsTypes::Texture2D* shadowMapArray_Cube; + static wiGraphicsTypes::Texture2D* shadowMapArray_Transparent; + int shadowMap_index; + int entityArray_index; + + std::vector shadowMaterices; + + float shadowBias; + + // area light props: + float radius, width, height; + }; + + struct Camera + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + + XMFLOAT4X4 View, Projection, VP; + XMFLOAT3 Eye, At, Up; + float width, height; + float zNearP, zFarP; + float fov; + Frustum frustum; + XMFLOAT4X4 InvView, InvProjection, InvVP; + XMFLOAT4X4 realProjection; // because reverse zbuffering projection complicates things... + + XMVECTOR GetEye() const + { + return XMLoadFloat3(&Eye); + } + XMVECTOR GetAt() const + { + return XMLoadFloat3(&At); + } + XMVECTOR GetUp() const + { + return XMLoadFloat3(&Up); + } + XMVECTOR GetRight() const + { + return XMVector3Cross(GetAt(), GetUp()); + } + XMMATRIX GetView() const + { + return XMLoadFloat4x4(&View); + } + XMMATRIX GetInvView() const + { + return XMLoadFloat4x4(&InvView); + } + XMMATRIX GetProjection() const + { + return XMLoadFloat4x4(&Projection); + } + XMMATRIX GetInvProjection() const + { + return XMLoadFloat4x4(&InvProjection); + } + XMMATRIX GetViewProjection() const + { + return XMLoadFloat4x4(&VP); + } + XMMATRIX GetInvViewProjection() const + { + return XMLoadFloat4x4(&InvVP); + } + }; + + struct EnvironmentProbe + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + int textureIndex = -1; + bool realTime = false; + bool isUpToDate = false; + }; + + struct ForceField + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + }; + + struct Decal + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + wiECS::ComponentManager::iterator material_ref; + + XMFLOAT4 atlasMulAdd = XMFLOAT4(0, 0, 0, 0); + }; + + struct Model + { + wiECS::ComponentManager::iterator node_ref; + wiECS::ComponentManager::iterator transform_ref; + + std::vector::iterator> material_refs; + std::vector::iterator> mesh_refs; + std::vector::iterator> object_refs; + std::vector::iterator> armature_refs; + std::vector::iterator> light_refs; + std::vector::iterator> probe_refs; + std::vector::iterator> force_refs; + std::vector::iterator> decal_refs; + std::vector::iterator> camera_refs; + }; + + struct Scene + { + wiECS::ComponentManager nodes; + wiECS::ComponentManager transforms; + wiECS::ComponentManager materials; + wiECS::ComponentManager meshes; + wiECS::ComponentManager objects; + wiECS::ComponentManager bones; + wiECS::ComponentManager armatures; + wiECS::ComponentManager lights; + wiECS::ComponentManager cameras; + wiECS::ComponentManager probes; + wiECS::ComponentManager forces; + wiECS::ComponentManager decals; + wiECS::ComponentManager models; + + XMFLOAT3 horizon = XMFLOAT3(0.0f, 0.0f, 0.0f); + XMFLOAT3 zenith = XMFLOAT3(0.00f, 0.00f, 0.0f); + XMFLOAT3 ambient = XMFLOAT3(0.2f, 0.2f, 0.2f); + XMFLOAT3 fogSEH = XMFLOAT3(100, 1000, 0); + XMFLOAT4 water = XMFLOAT4(0, 0, 0, 0); + float cloudiness = 0.0f; + float cloudScale = 0.0003f; + float cloudSpeed = 0.1f; + XMFLOAT3 windDirection = XMFLOAT3(0, 0, 0); + float windRandomness = 5; + float windWaveSize = 1; + + void Update(float dt); + }; + +} + diff --git a/WickedEngine/wiSceneSystem_Decl.h b/WickedEngine/wiSceneSystem_Decl.h new file mode 100644 index 000000000..2cc13066e --- /dev/null +++ b/WickedEngine/wiSceneSystem_Decl.h @@ -0,0 +1,20 @@ +#pragma once + + +namespace wiSceneSystem +{ + struct Node; + struct Transform; + struct Material; + struct Mesh; + struct Object; + struct Bone; + struct Armature; + struct Light; + struct Camera; + struct EnvironmentProbe; + struct ForceField; + struct Decal; + struct Model; + struct Scene; +}