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);
}