/* * All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or * its licensors. * * For complete copyright and license terms please see the LICENSE at the root of this * distribution (the "License"). All use of this software is governed by the License, * or, if provided, by the license below or the license accompanying this file. Do not * remove or modify any license notices. This file is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * */ // Original file Copyright Crytek GMBH or its affiliates, used under license. #pragma once #include #include #include #include #include #include "Cry_Math.h"//has to go before cry_color.h #include "Cry_Color.h" #include //for memset #include "smartptr.h" #include "I3DEngine.h" #include "ITexture.h" #include "IMaterial.h" #include "IStatObj.h" #include namespace AzFramework { namespace Terrain { class TerrainDataRequests; } } /* This structure represents the brick in the parlance of brickmaps. With brick maps each voxel represents a brick of data. The brick subdivides the voxel into a denser sampling region while allowing for a lower tree height and data structure overhead. */ namespace SVOGI { struct MeshData { MeshData(AZ::EntityId entityId, AZ::Transform transform, AZ::Aabb worldAabb, AZ::Data::Asset meshAsset, _smart_ptr material) : m_entityId(entityId) , m_transform(transform) , m_worldAabb(worldAabb) , m_meshAsset(meshAsset) , m_material(material) {} AZ::Transform m_transform; AZ::EntityId m_entityId; AZ::Aabb m_worldAabb; AZ::Data::Asset m_meshAsset; _smart_ptr m_material; }; using EntityMeshDataMap = AZStd::unordered_map>; const AZ::s32 brickDimension = (16); const AZ::s32 nVoxBloMaxDim = (16); const AZ::s32 nVoxNodMaxDim = 2; template struct DataBrick { AZ_CLASS_ALLOCATOR(DataBrick, AZ::SystemAllocator, 0); T m_data[brickDimension * brickDimension * brickDimension]; DataBrick() { Reset(); } T& operator[](size_t idx) { return m_data[idx]; } const T& operator[](size_t idx) const { return m_data[idx]; } void Reset() { memset(m_data, 0, sizeof(m_data)); } }; struct ObjectInfo { ObjectInfo() { memset(this, 0, sizeof(*this)); } Matrix34 matObjInv; Matrix34 matObj; _smart_ptr m_material; IStatObj* pStatObj; float fObjScale; bool bVegetation; }; // SuperMesh index type typedef AZ_TRAIT_SVOGI_SUPERMESH_INDEX_TYPE SMINDEX; struct SuperTriangle { SuperTriangle() { memset(this, 0, sizeof(*this)); arrVertId[0] = arrVertId[1] = arrVertId[2] = (SMINDEX)~0; } Vec3 vFaceNorm; AZ::u8 nTriArea; AZ::u8 nOpacity; AZ::u8 nHitObjType; SMINDEX arrVertId[3]; AZ::u16 nMatID; }; struct SRayHitVertex { Vec3 v; Vec2 t; ColorB c; }; struct SvoMaterialInfo { SvoMaterialInfo() { memset(this, 0, sizeof(*this)); } _smart_ptr m_material; ITexture* m_texture; ColorB* m_textureColor; AZ::u16 m_textureWidth; AZ::u16 m_textureHeight; bool operator == (const SvoMaterialInfo& other) const { return m_material == other.m_material; } }; struct SuperMesh { SuperMesh(); ~SuperMesh(); void AddSuperTriangle(SRayHitTriangle& htIn); void AddSuperMesh(SuperMesh& smIn, float fVertexOffset); void Clear(); void ReleaseTextures(); AZStd::vector m_triangles; AZStd::vector m_faceNormals; AZStd::vector m_vertices; AZStd::vector m_materials; protected: AZ::s32 AddVertex(const SRayHitVertex& rVert, AZStd::vector& vertsInArea); }; struct GISubVoxels { AZ::Color m_colors[4][4][4]; AZ::Vector3 m_normals[4][4][4]; AZ::VectorFloat m_emittances[4][4][4]; AZ::VectorFloat m_opacities[4][4][4]; }; class Brick : public SuperMesh { public: AZ_CLASS_ALLOCATOR(Brick, AZ::SystemAllocator, 0); Brick(); ~Brick(); void ExtractTriangles(AZStd::vector& objects); void ExtractTerrainTriangles(); void ExtractVisAreaTriangles(); float GetBrickSize() { return (m_brickAabb.GetDepth()); } //Collect Brushes and Vegetation cryEntities. bool CollectLegacyObjects(const AZ::Aabb& nodeBox, AZStd::vector* parrObjects); void ProcessMeshes( const EntityMeshDataMap& insertions, const EntityMeshDataMap& removals, DataBrick& scratch ); bool ProcessTriangles( DataBrick& data , DataBrick& centers ); bool HasBrickData() const; void UpdateBrickData( DataBrick& data, bool increment ); //The Aabb is defined in local coordinates to brick origin. AZ::Aabb m_brickAabb; AZ::Vector3 m_brickOrigin; //Guard against uploading data while writing data at the same time. mutable AZStd::shared_mutex m_brickDataMutex; DataBrick* m_opacities; DataBrick* m_colors; DataBrick* m_normals; //Count the number of samples in each subvoxel calculation to be able to do average updates. DataBrick* m_counts; AZStd::atomic_uint m_lastUploaded; AZStd::atomic_uint m_lastUpdated; bool m_collectedLegacyObjects; bool m_terrainOnly; AZ::s32 m_numLegacyObjects; AZStd::unordered_set m_entityIDs; private: void FreeBrickData(); void FreeTriangleData(); void ClearTriangleData(); //! Does the real work on behalf of ExtractTerrainTriangles() but @terrain is a thread safe //! EBus interface. void ExtractTerrainTrianglesLocked(AzFramework::Terrain::TerrainDataRequests* terrain); }; }