diff --git a/Content/Shaders/AtmospherePreCompute.flax b/Content/Shaders/AtmospherePreCompute.flax index b95df915d..012715c7b 100644 --- a/Content/Shaders/AtmospherePreCompute.flax +++ b/Content/Shaders/AtmospherePreCompute.flax @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:339f3706385a693095fa0cb23eccd57f429bf30f11af8a7e87c173a7bcfc74fb -size 11720 +oid sha256:2627c48e40c99c5e87ed81813f67657ac0c5ee1b12cf42e062e8d3bdf77b9f16 +size 11418 diff --git a/Flax.flaxproj b/Flax.flaxproj index f0e0dcc96..d8e86b1ed 100644 --- a/Flax.flaxproj +++ b/Flax.flaxproj @@ -3,7 +3,7 @@ "Version": { "Major": 1, "Minor": 6, - "Build": 6340 + "Build": 6342 }, "Company": "Flax", "Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.", diff --git a/Source/Editor/Content/Items/AssetItem.cs b/Source/Editor/Content/Items/AssetItem.cs index 71f298965..bbff4cb0c 100644 --- a/Source/Editor/Content/Items/AssetItem.cs +++ b/Source/Editor/Content/Items/AssetItem.cs @@ -23,6 +23,11 @@ namespace FlaxEditor.Content /// public string TypeName { get; } + /// + /// Returns true if asset is now loaded. + /// + public bool IsLoaded => FlaxEngine.Content.GetAsset(ID)?.IsLoaded ?? false; + /// /// Initializes a new instance of the class. /// @@ -89,7 +94,19 @@ namespace FlaxEditor.Content /// The asset object. public Asset LoadAsync() { - return FlaxEngine.Content.LoadAsync(ID); + return FlaxEngine.Content.LoadAsync(ID); + } + + /// + /// Reloads the asset (if it's loaded). + /// + public void Reload() + { + var asset = FlaxEngine.Content.GetAsset(ID); + if (asset != null && asset.IsLoaded) + { + asset.Reload(); + } } /// diff --git a/Source/Editor/CustomEditors/Editors/ActorLayerEditor.cs b/Source/Editor/CustomEditors/Editors/ActorLayerEditor.cs index 33f0be334..bf087feda 100644 --- a/Source/Editor/CustomEditors/Editors/ActorLayerEditor.cs +++ b/Source/Editor/CustomEditors/Editors/ActorLayerEditor.cs @@ -27,16 +27,6 @@ namespace FlaxEditor.CustomEditors.Editors element.ComboBox.SelectedIndexChanged += OnSelectedIndexChanged; } - private void GetActorsTree(List list, Actor a) - { - list.Add(a); - int cnt = a.ChildrenCount; - for (int i = 0; i < cnt; i++) - { - GetActorsTree(list, a.GetChild(i)); - } - } - private void OnSelectedIndexChanged(ComboBox comboBox) { int value = comboBox.SelectedIndex; @@ -60,7 +50,7 @@ namespace FlaxEditor.CustomEditors.Editors // Note: this possibly breaks the design a little bit // But it's the easiest way to set value for selected actor and its children with one undo action List actors = new List(32); - GetActorsTree(actors, actor); + Utilities.Utils.GetActorsTree(actors, actor); if (Presenter.Undo != null) { using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change layer")) diff --git a/Source/Editor/CustomEditors/Editors/ActorStaticFlagsEditor.cs b/Source/Editor/CustomEditors/Editors/ActorStaticFlagsEditor.cs index 4d7e4f0ef..f93ac7cdd 100644 --- a/Source/Editor/CustomEditors/Editors/ActorStaticFlagsEditor.cs +++ b/Source/Editor/CustomEditors/Editors/ActorStaticFlagsEditor.cs @@ -10,16 +10,6 @@ namespace FlaxEditor.CustomEditors.Editors /// public sealed class ActorStaticFlagsEditor : EnumEditor { - private void GetActorsTree(List list, Actor a) - { - list.Add(a); - int cnt = a.ChildrenCount; - for (int i = 0; i < cnt; i++) - { - GetActorsTree(list, a.GetChild(i)); - } - } - /// protected override void OnValueChanged() { @@ -40,7 +30,7 @@ namespace FlaxEditor.CustomEditors.Editors // Note: this possibly breaks the design a little bit // But it's the easiest way to set value for selected actor and its children with one undo action List actors = new List(32); - GetActorsTree(actors, actor); + Utilities.Utils.GetActorsTree(actors, actor); if (Presenter.Undo != null && Presenter.Undo.Enabled) { using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change static flags")) diff --git a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs index b8c920266..83ea666d9 100644 --- a/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs +++ b/Source/Editor/SceneGraph/GUI/ActorTreeNode.cs @@ -630,7 +630,7 @@ namespace FlaxEditor.SceneGraph.GUI { // Set all Actors static flags to match parents List childActors = new List(); - GetActorsTree(childActors, actor); + Utilities.Utils.GetActorsTree(childActors, actor); foreach (var child in childActors) { child.StaticFlags = spawnParent.StaticFlags; @@ -676,16 +676,6 @@ namespace FlaxEditor.SceneGraph.GUI return result; } - - private void GetActorsTree(List list, Actor a) - { - list.Add(a); - int cnt = a.ChildrenCount; - for (int i = 0; i < cnt; i++) - { - GetActorsTree(list, a.GetChild(i)); - } - } private bool ValidateDragActor(ActorNode actorNode) { diff --git a/Source/Editor/Utilities/Utils.cs b/Source/Editor/Utilities/Utils.cs index 0f44c9639..d980b0c4a 100644 --- a/Source/Editor/Utilities/Utils.cs +++ b/Source/Editor/Utilities/Utils.cs @@ -192,6 +192,16 @@ namespace FlaxEditor.Utilities return str; } + internal static void GetActorsTree(List list, Actor a) + { + list.Add(a); + int cnt = a.ChildrenCount; + for (int i = 0; i < cnt; i++) + { + GetActorsTree(list, a.GetChild(i)); + } + } + /// /// The colors for the keyframes used by the curve editor. /// diff --git a/Source/Editor/Windows/ContentWindow.ContextMenu.cs b/Source/Editor/Windows/ContentWindow.ContextMenu.cs index 30b864acc..283133688 100644 --- a/Source/Editor/Windows/ContentWindow.ContextMenu.cs +++ b/Source/Editor/Windows/ContentWindow.ContextMenu.cs @@ -98,6 +98,8 @@ namespace FlaxEditor.Windows if (item is AssetItem assetItem) { + if (assetItem.IsLoaded) + cm.AddButton("Reload", assetItem.Reload); cm.AddButton("Copy asset ID", () => Clipboard.Text = JsonSerializer.GetStringID(assetItem.ID)); cm.AddButton("Select actors using this asset", () => Editor.SceneEditing.SelectActorsUsingAsset(assetItem.ID)); cm.AddButton("Show asset references graph", () => Editor.Windows.Open(new AssetReferencesGraphWindow(Editor, assetItem))); diff --git a/Source/Engine/Core/Types/String.cpp b/Source/Engine/Core/Types/String.cpp index 321e3568a..cee60c07c 100644 --- a/Source/Engine/Core/Types/String.cpp +++ b/Source/Engine/Core/Types/String.cpp @@ -34,22 +34,26 @@ String::String(const StringAnsiView& str) void String::Set(const Char* chars, int32 length) { - if (length != _length) + ASSERT(length >= 0); + if (length == _length) { - ASSERT(length >= 0); - Platform::Free(_data); + if (_data == chars) + return; + Platform::MemoryCopy(_data, chars, length * sizeof(Char)); + } + else + { + Char* data = nullptr; if (length != 0) { - _data = (Char*)Platform::Allocate((length + 1) * sizeof(Char), 16); - _data[length] = 0; - } - else - { - _data = nullptr; + data = (Char*)Platform::Allocate((length + 1) * sizeof(Char), 16); + Platform::MemoryCopy(data, chars, length * sizeof(Char)); + data[length] = 0; } + Platform::Free(_data); + _data = data; _length = length; } - Platform::MemoryCopy(_data, chars, length * sizeof(Char)); } void String::Set(const char* chars, int32 length) @@ -359,23 +363,26 @@ StringAnsi::StringAnsi(const StringAnsiView& str) void StringAnsi::Set(const char* chars, int32 length) { - if (length != _length) + ASSERT(length >= 0); + if (length == _length) { - ASSERT(length >= 0); - Platform::Free(_data); + if (_data == chars) + return; + Platform::MemoryCopy(_data, chars, length * sizeof(char)); + } + else + { + char* data = nullptr; if (length != 0) { - _data = (char*)Platform::Allocate((length + 1) * sizeof(char), 16); - _data[length] = 0; - } - else - { - _data = nullptr; + data = (char*)Platform::Allocate((length + 1) * sizeof(char), 16); + Platform::MemoryCopy(data, chars, length * sizeof(char)); + data[length] = 0; } + Platform::Free(_data); + _data = data; _length = length; } - - Platform::MemoryCopy(_data, chars, length * sizeof(char)); } void StringAnsi::Set(const Char* chars, int32 length) diff --git a/Source/Engine/Level/Prefabs/PrefabManager.cpp b/Source/Engine/Level/Prefabs/PrefabManager.cpp index 88d80a41a..a2b148f28 100644 --- a/Source/Engine/Level/Prefabs/PrefabManager.cpp +++ b/Source/Engine/Level/Prefabs/PrefabManager.cpp @@ -102,6 +102,7 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, Dictionary::ScopeCache sceneObjects = ActorsCache::SceneObjectsListCache.Get(); sceneObjects->Resize(objectsCount); CollectionPoolCache::ScopeCache modifier = Cache::ISerializeModifier.Get(); + modifier->EngineBuild = prefab->DataEngineBuild; modifier->IdsMapping.EnsureCapacity(prefab->ObjectsIds.Count() * 4); for (int32 i = 0; i < prefab->ObjectsIds.Count(); i++) { diff --git a/Source/Engine/Level/SceneObjectsFactory.cpp b/Source/Engine/Level/SceneObjectsFactory.cpp index 00fd29be0..f8193c257 100644 --- a/Source/Engine/Level/SceneObjectsFactory.cpp +++ b/Source/Engine/Level/SceneObjectsFactory.cpp @@ -204,7 +204,10 @@ void SceneObjectsFactory::Deserialize(Context& context, SceneObject* obj, ISeria } // Deserialize prefab data (recursive prefab loading to support nested prefabs) + const auto prevVersion = context.Modifier->EngineBuild; + context.Modifier->EngineBuild = prefab->DataEngineBuild; Deserialize(context, obj, *(ISerializable::DeserializeStream*)prefabData); + context.Modifier->EngineBuild = prevVersion; } int32 instanceIndex; diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.cpp b/Source/Engine/Physics/Actors/WheeledVehicle.cpp index bcf94ee05..2ed59c8f6 100644 --- a/Source/Engine/Physics/Actors/WheeledVehicle.cpp +++ b/Source/Engine/Physics/Actors/WheeledVehicle.cpp @@ -215,7 +215,7 @@ void WheeledVehicle::Setup() void WheeledVehicle::DrawPhysicsDebug(RenderView& view) { // Wheels shapes - for (auto& data : _wheelsData) + for (const auto& data : _wheelsData) { int32 wheelIndex = 0; for (; wheelIndex < _wheels.Count(); wheelIndex++) @@ -225,7 +225,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view) } if (wheelIndex == _wheels.Count()) break; - auto& wheel = _wheels[wheelIndex]; + const auto& wheel = _wheels[wheelIndex]; if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger()) { const Vector3 currentPos = wheel.Collider->GetPosition(); @@ -245,7 +245,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view) void WheeledVehicle::OnDebugDrawSelected() { // Wheels shapes - for (auto& data : _wheelsData) + for (const auto& data : _wheelsData) { int32 wheelIndex = 0; for (; wheelIndex < _wheels.Count(); wheelIndex++) @@ -255,7 +255,7 @@ void WheeledVehicle::OnDebugDrawSelected() } if (wheelIndex == _wheels.Count()) break; - auto& wheel = _wheels[wheelIndex]; + const auto& wheel = _wheels[wheelIndex]; if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger()) { const Vector3 currentPos = wheel.Collider->GetPosition(); @@ -314,6 +314,9 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier* DESERIALIZE_MEMBER(Engine, _engine); DESERIALIZE_MEMBER(Differential, _differential); DESERIALIZE_MEMBER(Gearbox, _gearbox); + + // [Deprecated on 13.06.2023, expires on 13.06.2025] + _fixInvalidForwardDir |= modifier->EngineBuild < 6341; } void WheeledVehicle::OnColliderChanged(Collider* c) @@ -334,6 +337,41 @@ void WheeledVehicle::OnPhysicsSceneChanged(PhysicsScene* previous) #endif } +void WheeledVehicle::OnTransformChanged() +{ + RigidBody::OnTransformChanged(); + + // Initially vehicles were using X axis as forward which was kind of bad idea as engine uses Z as forward + // [Deprecated on 13.06.2023, expires on 13.06.2025] + if (_fixInvalidForwardDir) + { + _fixInvalidForwardDir = false; + + // Transform all vehicle children around the vehicle origin to fix the vehicle facing direction + const Quaternion rotationDelta(0.0f, -0.7071068f, 0.0f, 0.7071068f); + const Vector3 origin = GetPosition(); + for (Actor* child : Children) + { + Transform trans = child->GetTransform();; + const Vector3 pivotOffset = trans.Translation - origin; + if (pivotOffset.IsZero()) + { + trans.Orientation *= Quaternion::Invert(trans.Orientation) * rotationDelta * trans.Orientation; + } + else + { + Matrix transWorld, deltaWorld; + Matrix::RotationQuaternion(trans.Orientation, transWorld); + Matrix::RotationQuaternion(rotationDelta, deltaWorld); + Matrix world = transWorld * Matrix::Translation(pivotOffset) * deltaWorld * Matrix::Translation(-pivotOffset); + trans.SetRotation(world); + trans.Translation += world.GetTranslation(); + } + child->SetTransform(trans); + } + } +} + void WheeledVehicle::BeginPlay(SceneBeginData* data) { RigidBody::BeginPlay(data); diff --git a/Source/Engine/Physics/Actors/WheeledVehicle.h b/Source/Engine/Physics/Actors/WheeledVehicle.h index 7e046d1a2..b478006d9 100644 --- a/Source/Engine/Physics/Actors/WheeledVehicle.h +++ b/Source/Engine/Physics/Actors/WheeledVehicle.h @@ -328,6 +328,7 @@ private: EngineSettings _engine; DifferentialSettings _differential; GearboxSettings _gearbox; + bool _fixInvalidForwardDir = false; // [Deprecated on 13.06.2023, expires on 13.06.2025] public: /// @@ -488,6 +489,7 @@ protected: void OnPhysicsSceneChanged(PhysicsScene* previous) override; // [Vehicle] + void OnTransformChanged() override; void BeginPlay(SceneBeginData* data) override; void EndPlay() override; }; diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index a5ead04a6..7203b9b7c 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -508,7 +508,7 @@ void InitVehicleSDK() { VehicleSDKInitialized = true; PxInitVehicleSDK(*PhysX); - PxVehicleSetBasisVectors(PxVec3(0, 1, 0), PxVec3(1, 0, 0)); + PxVehicleSetBasisVectors(PxVec3(0, 1, 0), PxVec3(0, 0, 1)); PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE); } } @@ -1029,7 +1029,7 @@ void PhysicsBackend::EndSimulateScene(void* scene) 5.0f, // fall rate eANALOG_INPUT_STEER_RIGHT } }; - PxVehicleKeySmoothingData keySmoothing = + static constexpr PxVehicleKeySmoothingData keySmoothing = { { 3.0f, // rise rate eANALOG_INPUT_ACCEL @@ -1221,7 +1221,7 @@ void PhysicsBackend::EndSimulateScene(void* scene) // Update wheel collider transformation auto localPose = shape->getLocalPose(); Transform t = wheelData.Collider->GetLocalTransform(); - t.Orientation = Quaternion::Euler(0, state.SteerAngle, state.RotationAngle) * wheelData.LocalOrientation; + t.Orientation = Quaternion::Euler(-state.RotationAngle, state.SteerAngle, 0) * wheelData.LocalOrientation; t.Translation = P2C(localPose.p) / wheelVehicle->GetScale() - t.Orientation * wheelData.Collider->GetCenter(); wheelData.Collider->SetLocalTransform(t); } @@ -2626,6 +2626,7 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor) } PxF32 sprungMasses[PX_MAX_NB_WHEELS]; const float mass = actorPhysX->getMass(); + // TODO: get gravityDirection from scenePhysX->Scene->getGravity() PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses); PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count()); for (int32 i = 0; i < wheels.Count(); i++) @@ -2776,9 +2777,9 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor) // Ackermann steer accuracy PxVehicleAckermannGeometryData ackermann; - ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x); - ackermann.mFrontWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z); - ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z); + ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z); + ackermann.mFrontWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x); + ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x); driveSimData.setAckermannGeometryData(ackermann); // Create vehicle drive diff --git a/Source/Engine/Render2D/Font.h b/Source/Engine/Render2D/Font.h index 3f42fd396..d68f497d6 100644 --- a/Source/Engine/Render2D/Font.h +++ b/Source/Engine/Render2D/Font.h @@ -10,6 +10,7 @@ #include "TextLayoutOptions.h" class FontAsset; +struct FontTextureAtlasSlot; // The default DPI that engine is using #define DefaultDPI 96 @@ -204,6 +205,11 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry); /// The size the character in the texture (in texture coordinates space). /// API_FIELD() Float2 UVSize; + + /// + /// The slot in texture atlas, containing the pixel data of the glyph. + /// + API_FIELD() const FontTextureAtlasSlot* Slot; }; template<> diff --git a/Source/Engine/Render2D/FontManager.cpp b/Source/Engine/Render2D/FontManager.cpp index 578e28409..bb7edf974 100644 --- a/Source/Engine/Render2D/FontManager.cpp +++ b/Source/Engine/Render2D/FontManager.cpp @@ -242,7 +242,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry) // Find atlas for the character texture int32 atlasIndex = 0; - const FontTextureAtlas::Slot* slot = nullptr; + const FontTextureAtlasSlot* slot = nullptr; for (; atlasIndex < Atlases.Count(); atlasIndex++) { // Add the character to the texture @@ -283,6 +283,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry) entry.UV.Y = static_cast(slot->Y + padding); entry.UVSize.X = static_cast(slot->Width - 2 * padding); entry.UVSize.Y = static_cast(slot->Height - 2 * padding); + entry.Slot = slot; return false; } diff --git a/Source/Engine/Render2D/FontTextureAtlas.cpp b/Source/Engine/Render2D/FontTextureAtlas.cpp index 972fe1bcb..724040157 100644 --- a/Source/Engine/Render2D/FontTextureAtlas.cpp +++ b/Source/Engine/Render2D/FontTextureAtlas.cpp @@ -40,7 +40,7 @@ void FontTextureAtlas::Init(uint32 width, uint32 height) uint32 padding = GetPaddingAmount(); _width = width; _height = height; - _root = New(padding, padding, _width - padding, _height - padding); + _root = New(padding, padding, _width - padding, _height - padding); _isDirty = false; // Reserve upload data memory @@ -48,19 +48,19 @@ void FontTextureAtlas::Init(uint32 width, uint32 height) Platform::MemoryClear(_data.Get(), _data.Capacity()); } -FontTextureAtlas::Slot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data) +FontTextureAtlasSlot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data) { // Check for invalid size if (targetWidth == 0 || targetHeight == 0) return nullptr; // Try to find slot for the texture - Slot* slot = nullptr; + FontTextureAtlasSlot* slot = nullptr; const uint32 padding = GetPaddingAmount(); const uint32 allPadding = padding * 2; for (int32 i = 0; i < _freeSlots.Count(); i++) { - Slot* e = _freeSlots[i]; + FontTextureAtlasSlot* e = _freeSlots[i]; if (e->Width == targetWidth + allPadding && e->Height == targetHeight + allPadding) { slot = e; @@ -89,7 +89,7 @@ FontTextureAtlas::Slot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 ta bool FontTextureAtlas::Invalidate(uint32 x, uint32 y, uint32 width, uint32 height) { - Slot* slot = invalidate(_root, x, y, width, height); + FontTextureAtlasSlot* slot = invalidate(_root, x, y, width, height); if (slot) { _freeSlots.Add(slot); @@ -97,7 +97,7 @@ bool FontTextureAtlas::Invalidate(uint32 x, uint32 y, uint32 width, uint32 heigh return slot != nullptr; } -void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array& data) +void FontTextureAtlas::CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array& data) { uint8* start = &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel]; const uint32 padding = GetPaddingAmount(); @@ -148,6 +148,15 @@ void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array& dat } } +byte* FontTextureAtlas::GetSlotData(const FontTextureAtlasSlot* slot, uint32& width, uint32& height, uint32& stride) +{ + const uint32 padding = GetPaddingAmount(); + width = slot->Width - padding * 2; + height = slot->Height - padding * 2; + stride = _width * _bytesPerPixel; + return &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel]; +} + void FontTextureAtlas::copyRow(const RowData& copyRowData) const { const byte* data = copyRowData.SrcData; @@ -238,13 +247,13 @@ bool FontTextureAtlas::HasDataSyncWithGPU() const return _isDirty == false; } -FontTextureAtlas::Slot* FontTextureAtlas::invalidate(Slot* parent, uint32 x, uint32 y, uint32 width, uint32 height) +FontTextureAtlasSlot* FontTextureAtlas::invalidate(FontTextureAtlasSlot* parent, uint32 x, uint32 y, uint32 width, uint32 height) { if (parent->X == x && parent->Y == y && parent->Width == width && parent->Height == height) { return parent; } - Slot* result = parent->Left ? invalidate(parent->Left, x, y, width, height) : nullptr; + FontTextureAtlasSlot* result = parent->Left ? invalidate(parent->Left, x, y, width, height) : nullptr; if (result) return result; return parent->Right ? invalidate(parent->Right, x, y, width, height) : nullptr; diff --git a/Source/Engine/Render2D/FontTextureAtlas.h b/Source/Engine/Render2D/FontTextureAtlas.h index 5d9fa43dd..4bffdaf58 100644 --- a/Source/Engine/Render2D/FontTextureAtlas.h +++ b/Source/Engine/Render2D/FontTextureAtlas.h @@ -8,6 +8,21 @@ #include "Engine/Graphics/Textures/GPUTexture.h" #include "Engine/Utilities/RectPack.h" +/// +/// Contains information about single texture atlas slot. +/// +struct FontTextureAtlasSlot : RectPack +{ + FontTextureAtlasSlot(uint32 x, uint32 y, uint32 width, uint32 height) + : RectPack(x, y, width, height) + { + } + + void OnInsert() + { + } +}; + /// /// Texture resource that contains an atlas of cached font glyphs. /// @@ -29,21 +44,6 @@ private: public: - /// - /// Contains information about single texture atlas slot. - /// - struct Slot : RectPack - { - Slot(uint32 x, uint32 y, uint32 width, uint32 height) - : RectPack(x, y, width, height) - { - } - - void OnInsert() - { - } - }; - /// /// Describes how to handle texture atlas padding /// @@ -74,8 +74,8 @@ private: uint32 _bytesPerPixel; PaddingStyle _paddingStyle; bool _isDirty; - Slot* _root; - Array _freeSlots; + FontTextureAtlasSlot* _root; + Array _freeSlots; public: @@ -157,7 +157,7 @@ public: /// Height of the entry. /// The data. /// The atlas slot occupied by the new entry. - Slot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data); + FontTextureAtlasSlot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array& data); /// /// Invalidates the cached dynamic entry from the atlas. @@ -174,7 +174,17 @@ public: /// /// The slot. /// The data. - void CopyDataIntoSlot(const Slot* slot, const Array& data); + void CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array& data); + + /// + /// Returns glyph's bitmap data of the slot. + /// + /// The slot in atlas. + /// The width of the slot. + /// The height of the slot. + /// The stride of the slot. + /// The pointer to the bitmap data of the given slot. + byte* GetSlotData(const FontTextureAtlasSlot* slot, uint32& width, uint32& height, uint32& stride); /// /// Clears this atlas entries data (doesn't change size/texture etc.). @@ -204,7 +214,7 @@ public: private: - Slot* invalidate(Slot* parent, uint32 x, uint32 y, uint32 width, uint32 height); + FontTextureAtlasSlot* invalidate(FontTextureAtlasSlot* parent, uint32 x, uint32 y, uint32 width, uint32 height); void markAsDirty(); void copyRow(const RowData& copyRowData) const; void zeroRow(const RowData& copyRowData) const; diff --git a/Source/Shaders/AtmospherePreCompute.shader b/Source/Shaders/AtmospherePreCompute.shader index b9a65c09c..e5d23af07 100644 --- a/Source/Shaders/AtmospherePreCompute.shader +++ b/Source/Shaders/AtmospherePreCompute.shader @@ -174,7 +174,7 @@ float4 PS_CopyInscatter1(Quad_VS2PS input) : SV_Target0 { float3 uvw = float3(input.TexCoord, (float(AtmosphereLayer) + 0.5f) / float(AtmosphericFogInscatterAltitudeSampleNum)); float4 ray = AtmosphereDeltaSRTexture.Sample(SamplerLinearClamp, uvw); - float4 mie = AtmosphereDeltaSRTexture.Sample(SamplerLinearClamp, uvw); + float4 mie = AtmosphereDeltaSMTexture.Sample(SamplerLinearClamp, uvw); return float4(ray.xyz, mie.x); }