Merge remote-tracking branch 'origin/master' into 1.6

# Conflicts:
#	Flax.flaxproj
#	Source/Editor/Content/Items/AssetItem.cs
This commit is contained in:
2023-06-13 15:41:07 +02:00
19 changed files with 175 additions and 98 deletions
Binary file not shown.
+1 -1
View File
@@ -3,7 +3,7 @@
"Version": { "Version": {
"Major": 1, "Major": 1,
"Minor": 6, "Minor": 6,
"Build": 6340 "Build": 6342
}, },
"Company": "Flax", "Company": "Flax",
"Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.", "Copyright": "Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.",
+18 -1
View File
@@ -23,6 +23,11 @@ namespace FlaxEditor.Content
/// </summary> /// </summary>
public string TypeName { get; } public string TypeName { get; }
/// <summary>
/// Returns true if asset is now loaded.
/// </summary>
public bool IsLoaded => FlaxEngine.Content.GetAsset(ID)?.IsLoaded ?? false;
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="AssetItem"/> class. /// Initializes a new instance of the <see cref="AssetItem"/> class.
/// </summary> /// </summary>
@@ -89,7 +94,19 @@ namespace FlaxEditor.Content
/// <returns>The asset object.</returns> /// <returns>The asset object.</returns>
public Asset LoadAsync() public Asset LoadAsync()
{ {
return FlaxEngine.Content.LoadAsync<BinaryAsset>(ID); return FlaxEngine.Content.LoadAsync<Asset>(ID);
}
/// <summary>
/// Reloads the asset (if it's loaded).
/// </summary>
public void Reload()
{
var asset = FlaxEngine.Content.GetAsset(ID);
if (asset != null && asset.IsLoaded)
{
asset.Reload();
}
} }
/// <summary> /// <summary>
@@ -27,16 +27,6 @@ namespace FlaxEditor.CustomEditors.Editors
element.ComboBox.SelectedIndexChanged += OnSelectedIndexChanged; element.ComboBox.SelectedIndexChanged += OnSelectedIndexChanged;
} }
private void GetActorsTree(List<Actor> 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) private void OnSelectedIndexChanged(ComboBox comboBox)
{ {
int value = comboBox.SelectedIndex; int value = comboBox.SelectedIndex;
@@ -60,7 +50,7 @@ namespace FlaxEditor.CustomEditors.Editors
// Note: this possibly breaks the design a little bit // 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 // But it's the easiest way to set value for selected actor and its children with one undo action
List<Actor> actors = new List<Actor>(32); List<Actor> actors = new List<Actor>(32);
GetActorsTree(actors, actor); Utilities.Utils.GetActorsTree(actors, actor);
if (Presenter.Undo != null) if (Presenter.Undo != null)
{ {
using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change layer")) using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change layer"))
@@ -10,16 +10,6 @@ namespace FlaxEditor.CustomEditors.Editors
/// </summary> /// </summary>
public sealed class ActorStaticFlagsEditor : EnumEditor public sealed class ActorStaticFlagsEditor : EnumEditor
{ {
private void GetActorsTree(List<Actor> list, Actor a)
{
list.Add(a);
int cnt = a.ChildrenCount;
for (int i = 0; i < cnt; i++)
{
GetActorsTree(list, a.GetChild(i));
}
}
/// <inheritdoc /> /// <inheritdoc />
protected override void OnValueChanged() protected override void OnValueChanged()
{ {
@@ -40,7 +30,7 @@ namespace FlaxEditor.CustomEditors.Editors
// Note: this possibly breaks the design a little bit // 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 // But it's the easiest way to set value for selected actor and its children with one undo action
List<Actor> actors = new List<Actor>(32); List<Actor> actors = new List<Actor>(32);
GetActorsTree(actors, actor); Utilities.Utils.GetActorsTree(actors, actor);
if (Presenter.Undo != null && Presenter.Undo.Enabled) if (Presenter.Undo != null && Presenter.Undo.Enabled)
{ {
using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change static flags")) using (new UndoMultiBlock(Presenter.Undo, actors.ToArray(), "Change static flags"))
+1 -11
View File
@@ -630,7 +630,7 @@ namespace FlaxEditor.SceneGraph.GUI
{ {
// Set all Actors static flags to match parents // Set all Actors static flags to match parents
List<Actor> childActors = new List<Actor>(); List<Actor> childActors = new List<Actor>();
GetActorsTree(childActors, actor); Utilities.Utils.GetActorsTree(childActors, actor);
foreach (var child in childActors) foreach (var child in childActors)
{ {
child.StaticFlags = spawnParent.StaticFlags; child.StaticFlags = spawnParent.StaticFlags;
@@ -676,16 +676,6 @@ namespace FlaxEditor.SceneGraph.GUI
return result; return result;
} }
private void GetActorsTree(List<Actor> 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) private bool ValidateDragActor(ActorNode actorNode)
{ {
+10
View File
@@ -192,6 +192,16 @@ namespace FlaxEditor.Utilities
return str; return str;
} }
internal static void GetActorsTree(List<Actor> list, Actor a)
{
list.Add(a);
int cnt = a.ChildrenCount;
for (int i = 0; i < cnt; i++)
{
GetActorsTree(list, a.GetChild(i));
}
}
/// <summary> /// <summary>
/// The colors for the keyframes used by the curve editor. /// The colors for the keyframes used by the curve editor.
/// </summary> /// </summary>
@@ -98,6 +98,8 @@ namespace FlaxEditor.Windows
if (item is AssetItem assetItem) 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("Copy asset ID", () => Clipboard.Text = JsonSerializer.GetStringID(assetItem.ID));
cm.AddButton("Select actors using this asset", () => Editor.SceneEditing.SelectActorsUsingAsset(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))); cm.AddButton("Show asset references graph", () => Editor.Windows.Open(new AssetReferencesGraphWindow(Editor, assetItem)));
+28 -21
View File
@@ -34,22 +34,26 @@ String::String(const StringAnsiView& str)
void String::Set(const Char* chars, int32 length) void String::Set(const Char* chars, int32 length)
{ {
if (length != _length) ASSERT(length >= 0);
if (length == _length)
{ {
ASSERT(length >= 0); if (_data == chars)
Platform::Free(_data); return;
Platform::MemoryCopy(_data, chars, length * sizeof(Char));
}
else
{
Char* data = nullptr;
if (length != 0) if (length != 0)
{ {
_data = (Char*)Platform::Allocate((length + 1) * sizeof(Char), 16); data = (Char*)Platform::Allocate((length + 1) * sizeof(Char), 16);
_data[length] = 0; Platform::MemoryCopy(data, chars, length * sizeof(Char));
} data[length] = 0;
else
{
_data = nullptr;
} }
Platform::Free(_data);
_data = data;
_length = length; _length = length;
} }
Platform::MemoryCopy(_data, chars, length * sizeof(Char));
} }
void String::Set(const char* chars, int32 length) 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) void StringAnsi::Set(const char* chars, int32 length)
{ {
if (length != _length) ASSERT(length >= 0);
if (length == _length)
{ {
ASSERT(length >= 0); if (_data == chars)
Platform::Free(_data); return;
Platform::MemoryCopy(_data, chars, length * sizeof(char));
}
else
{
char* data = nullptr;
if (length != 0) if (length != 0)
{ {
_data = (char*)Platform::Allocate((length + 1) * sizeof(char), 16); data = (char*)Platform::Allocate((length + 1) * sizeof(char), 16);
_data[length] = 0; Platform::MemoryCopy(data, chars, length * sizeof(char));
} data[length] = 0;
else
{
_data = nullptr;
} }
Platform::Free(_data);
_data = data;
_length = length; _length = length;
} }
Platform::MemoryCopy(_data, chars, length * sizeof(char));
} }
void StringAnsi::Set(const Char* chars, int32 length) void StringAnsi::Set(const Char* chars, int32 length)
@@ -102,6 +102,7 @@ Actor* PrefabManager::SpawnPrefab(Prefab* prefab, Actor* parent, Dictionary<Guid
CollectionPoolCache<ActorsCache::SceneObjectsListType>::ScopeCache sceneObjects = ActorsCache::SceneObjectsListCache.Get(); CollectionPoolCache<ActorsCache::SceneObjectsListType>::ScopeCache sceneObjects = ActorsCache::SceneObjectsListCache.Get();
sceneObjects->Resize(objectsCount); sceneObjects->Resize(objectsCount);
CollectionPoolCache<ISerializeModifier, Cache::ISerializeModifierClearCallback>::ScopeCache modifier = Cache::ISerializeModifier.Get(); CollectionPoolCache<ISerializeModifier, Cache::ISerializeModifierClearCallback>::ScopeCache modifier = Cache::ISerializeModifier.Get();
modifier->EngineBuild = prefab->DataEngineBuild;
modifier->IdsMapping.EnsureCapacity(prefab->ObjectsIds.Count() * 4); modifier->IdsMapping.EnsureCapacity(prefab->ObjectsIds.Count() * 4);
for (int32 i = 0; i < prefab->ObjectsIds.Count(); i++) for (int32 i = 0; i < prefab->ObjectsIds.Count(); i++)
{ {
@@ -204,7 +204,10 @@ void SceneObjectsFactory::Deserialize(Context& context, SceneObject* obj, ISeria
} }
// Deserialize prefab data (recursive prefab loading to support nested prefabs) // 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); Deserialize(context, obj, *(ISerializable::DeserializeStream*)prefabData);
context.Modifier->EngineBuild = prevVersion;
} }
int32 instanceIndex; int32 instanceIndex;
@@ -215,7 +215,7 @@ void WheeledVehicle::Setup()
void WheeledVehicle::DrawPhysicsDebug(RenderView& view) void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
{ {
// Wheels shapes // Wheels shapes
for (auto& data : _wheelsData) for (const auto& data : _wheelsData)
{ {
int32 wheelIndex = 0; int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++) for (; wheelIndex < _wheels.Count(); wheelIndex++)
@@ -225,7 +225,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
} }
if (wheelIndex == _wheels.Count()) if (wheelIndex == _wheels.Count())
break; break;
auto& wheel = _wheels[wheelIndex]; const auto& wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger()) if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{ {
const Vector3 currentPos = wheel.Collider->GetPosition(); const Vector3 currentPos = wheel.Collider->GetPosition();
@@ -245,7 +245,7 @@ void WheeledVehicle::DrawPhysicsDebug(RenderView& view)
void WheeledVehicle::OnDebugDrawSelected() void WheeledVehicle::OnDebugDrawSelected()
{ {
// Wheels shapes // Wheels shapes
for (auto& data : _wheelsData) for (const auto& data : _wheelsData)
{ {
int32 wheelIndex = 0; int32 wheelIndex = 0;
for (; wheelIndex < _wheels.Count(); wheelIndex++) for (; wheelIndex < _wheels.Count(); wheelIndex++)
@@ -255,7 +255,7 @@ void WheeledVehicle::OnDebugDrawSelected()
} }
if (wheelIndex == _wheels.Count()) if (wheelIndex == _wheels.Count())
break; break;
auto& wheel = _wheels[wheelIndex]; const auto& wheel = _wheels[wheelIndex];
if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger()) if (wheel.Collider && wheel.Collider->GetParent() == this && !wheel.Collider->GetIsTrigger())
{ {
const Vector3 currentPos = wheel.Collider->GetPosition(); const Vector3 currentPos = wheel.Collider->GetPosition();
@@ -314,6 +314,9 @@ void WheeledVehicle::Deserialize(DeserializeStream& stream, ISerializeModifier*
DESERIALIZE_MEMBER(Engine, _engine); DESERIALIZE_MEMBER(Engine, _engine);
DESERIALIZE_MEMBER(Differential, _differential); DESERIALIZE_MEMBER(Differential, _differential);
DESERIALIZE_MEMBER(Gearbox, _gearbox); DESERIALIZE_MEMBER(Gearbox, _gearbox);
// [Deprecated on 13.06.2023, expires on 13.06.2025]
_fixInvalidForwardDir |= modifier->EngineBuild < 6341;
} }
void WheeledVehicle::OnColliderChanged(Collider* c) void WheeledVehicle::OnColliderChanged(Collider* c)
@@ -334,6 +337,41 @@ void WheeledVehicle::OnPhysicsSceneChanged(PhysicsScene* previous)
#endif #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) void WheeledVehicle::BeginPlay(SceneBeginData* data)
{ {
RigidBody::BeginPlay(data); RigidBody::BeginPlay(data);
@@ -328,6 +328,7 @@ private:
EngineSettings _engine; EngineSettings _engine;
DifferentialSettings _differential; DifferentialSettings _differential;
GearboxSettings _gearbox; GearboxSettings _gearbox;
bool _fixInvalidForwardDir = false; // [Deprecated on 13.06.2023, expires on 13.06.2025]
public: public:
/// <summary> /// <summary>
@@ -488,6 +489,7 @@ protected:
void OnPhysicsSceneChanged(PhysicsScene* previous) override; void OnPhysicsSceneChanged(PhysicsScene* previous) override;
// [Vehicle] // [Vehicle]
void OnTransformChanged() override;
void BeginPlay(SceneBeginData* data) override; void BeginPlay(SceneBeginData* data) override;
void EndPlay() override; void EndPlay() override;
}; };
@@ -508,7 +508,7 @@ void InitVehicleSDK()
{ {
VehicleSDKInitialized = true; VehicleSDKInitialized = true;
PxInitVehicleSDK(*PhysX); PxInitVehicleSDK(*PhysX);
PxVehicleSetBasisVectors(PxVec3(0, 1, 0), PxVec3(1, 0, 0)); PxVehicleSetBasisVectors(PxVec3(0, 1, 0), PxVec3(0, 0, 1));
PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE); PxVehicleSetUpdateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE);
} }
} }
@@ -1029,7 +1029,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
5.0f, // fall rate eANALOG_INPUT_STEER_RIGHT 5.0f, // fall rate eANALOG_INPUT_STEER_RIGHT
} }
}; };
PxVehicleKeySmoothingData keySmoothing = static constexpr PxVehicleKeySmoothingData keySmoothing =
{ {
{ {
3.0f, // rise rate eANALOG_INPUT_ACCEL 3.0f, // rise rate eANALOG_INPUT_ACCEL
@@ -1221,7 +1221,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
// Update wheel collider transformation // Update wheel collider transformation
auto localPose = shape->getLocalPose(); auto localPose = shape->getLocalPose();
Transform t = wheelData.Collider->GetLocalTransform(); 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(); t.Translation = P2C(localPose.p) / wheelVehicle->GetScale() - t.Orientation * wheelData.Collider->GetCenter();
wheelData.Collider->SetLocalTransform(t); wheelData.Collider->SetLocalTransform(t);
} }
@@ -2626,6 +2626,7 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
} }
PxF32 sprungMasses[PX_MAX_NB_WHEELS]; PxF32 sprungMasses[PX_MAX_NB_WHEELS];
const float mass = actorPhysX->getMass(); const float mass = actorPhysX->getMass();
// TODO: get gravityDirection from scenePhysX->Scene->getGravity()
PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses); PxVehicleComputeSprungMasses(wheels.Count(), offsets, centerOfMassOffset.p, mass, 1, sprungMasses);
PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count()); PxVehicleWheelsSimData* wheelsSimData = PxVehicleWheelsSimData::allocate(wheels.Count());
for (int32 i = 0; i < wheels.Count(); i++) for (int32 i = 0; i < wheels.Count(); i++)
@@ -2776,9 +2777,9 @@ void* PhysicsBackend::CreateVehicle(WheeledVehicle* actor)
// Ackermann steer accuracy // Ackermann steer accuracy
PxVehicleAckermannGeometryData ackermann; PxVehicleAckermannGeometryData ackermann;
ackermann.mAxleSeparation = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_LEFT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x); 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).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eFRONT_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).z - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).z); ackermann.mRearWidth = Math::Abs(wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_RIGHT).x - wheelsSimData->getWheelCentreOffset(PxVehicleDrive4WWheelOrder::eREAR_LEFT).x);
driveSimData.setAckermannGeometryData(ackermann); driveSimData.setAckermannGeometryData(ackermann);
// Create vehicle drive // Create vehicle drive
+6
View File
@@ -10,6 +10,7 @@
#include "TextLayoutOptions.h" #include "TextLayoutOptions.h"
class FontAsset; class FontAsset;
struct FontTextureAtlasSlot;
// The default DPI that engine is using // The default DPI that engine is using
#define DefaultDPI 96 #define DefaultDPI 96
@@ -204,6 +205,11 @@ DECLARE_SCRIPTING_TYPE_MINIMAL(FontCharacterEntry);
/// The size the character in the texture (in texture coordinates space). /// The size the character in the texture (in texture coordinates space).
/// </summary> /// </summary>
API_FIELD() Float2 UVSize; API_FIELD() Float2 UVSize;
/// <summary>
/// The slot in texture atlas, containing the pixel data of the glyph.
/// </summary>
API_FIELD() const FontTextureAtlasSlot* Slot;
}; };
template<> template<>
+2 -1
View File
@@ -242,7 +242,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry)
// Find atlas for the character texture // Find atlas for the character texture
int32 atlasIndex = 0; int32 atlasIndex = 0;
const FontTextureAtlas::Slot* slot = nullptr; const FontTextureAtlasSlot* slot = nullptr;
for (; atlasIndex < Atlases.Count(); atlasIndex++) for (; atlasIndex < Atlases.Count(); atlasIndex++)
{ {
// Add the character to the texture // Add the character to the texture
@@ -283,6 +283,7 @@ bool FontManager::AddNewEntry(Font* font, Char c, FontCharacterEntry& entry)
entry.UV.Y = static_cast<float>(slot->Y + padding); entry.UV.Y = static_cast<float>(slot->Y + padding);
entry.UVSize.X = static_cast<float>(slot->Width - 2 * padding); entry.UVSize.X = static_cast<float>(slot->Width - 2 * padding);
entry.UVSize.Y = static_cast<float>(slot->Height - 2 * padding); entry.UVSize.Y = static_cast<float>(slot->Height - 2 * padding);
entry.Slot = slot;
return false; return false;
} }
+17 -8
View File
@@ -40,7 +40,7 @@ void FontTextureAtlas::Init(uint32 width, uint32 height)
uint32 padding = GetPaddingAmount(); uint32 padding = GetPaddingAmount();
_width = width; _width = width;
_height = height; _height = height;
_root = New<Slot>(padding, padding, _width - padding, _height - padding); _root = New<FontTextureAtlasSlot>(padding, padding, _width - padding, _height - padding);
_isDirty = false; _isDirty = false;
// Reserve upload data memory // Reserve upload data memory
@@ -48,19 +48,19 @@ void FontTextureAtlas::Init(uint32 width, uint32 height)
Platform::MemoryClear(_data.Get(), _data.Capacity()); Platform::MemoryClear(_data.Get(), _data.Capacity());
} }
FontTextureAtlas::Slot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array<byte>& data) FontTextureAtlasSlot* FontTextureAtlas::AddEntry(uint32 targetWidth, uint32 targetHeight, const Array<byte>& data)
{ {
// Check for invalid size // Check for invalid size
if (targetWidth == 0 || targetHeight == 0) if (targetWidth == 0 || targetHeight == 0)
return nullptr; return nullptr;
// Try to find slot for the texture // Try to find slot for the texture
Slot* slot = nullptr; FontTextureAtlasSlot* slot = nullptr;
const uint32 padding = GetPaddingAmount(); const uint32 padding = GetPaddingAmount();
const uint32 allPadding = padding * 2; const uint32 allPadding = padding * 2;
for (int32 i = 0; i < _freeSlots.Count(); i++) 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) if (e->Width == targetWidth + allPadding && e->Height == targetHeight + allPadding)
{ {
slot = e; 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) 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) if (slot)
{ {
_freeSlots.Add(slot); _freeSlots.Add(slot);
@@ -97,7 +97,7 @@ bool FontTextureAtlas::Invalidate(uint32 x, uint32 y, uint32 width, uint32 heigh
return slot != nullptr; return slot != nullptr;
} }
void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array<byte>& data) void FontTextureAtlas::CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array<byte>& data)
{ {
uint8* start = &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel]; uint8* start = &_data[slot->Y * _width * _bytesPerPixel + slot->X * _bytesPerPixel];
const uint32 padding = GetPaddingAmount(); const uint32 padding = GetPaddingAmount();
@@ -148,6 +148,15 @@ void FontTextureAtlas::CopyDataIntoSlot(const Slot* slot, const Array<byte>& 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 void FontTextureAtlas::copyRow(const RowData& copyRowData) const
{ {
const byte* data = copyRowData.SrcData; const byte* data = copyRowData.SrcData;
@@ -238,13 +247,13 @@ bool FontTextureAtlas::HasDataSyncWithGPU() const
return _isDirty == false; 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) if (parent->X == x && parent->Y == y && parent->Width == width && parent->Height == height)
{ {
return parent; 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) if (result)
return result; return result;
return parent->Right ? invalidate(parent->Right, x, y, width, height) : nullptr; return parent->Right ? invalidate(parent->Right, x, y, width, height) : nullptr;
+30 -20
View File
@@ -8,6 +8,21 @@
#include "Engine/Graphics/Textures/GPUTexture.h" #include "Engine/Graphics/Textures/GPUTexture.h"
#include "Engine/Utilities/RectPack.h" #include "Engine/Utilities/RectPack.h"
/// <summary>
/// Contains information about single texture atlas slot.
/// </summary>
struct FontTextureAtlasSlot : RectPack<FontTextureAtlasSlot>
{
FontTextureAtlasSlot(uint32 x, uint32 y, uint32 width, uint32 height)
: RectPack<FontTextureAtlasSlot>(x, y, width, height)
{
}
void OnInsert()
{
}
};
/// <summary> /// <summary>
/// Texture resource that contains an atlas of cached font glyphs. /// Texture resource that contains an atlas of cached font glyphs.
/// </summary> /// </summary>
@@ -29,21 +44,6 @@ private:
public: public:
/// <summary>
/// Contains information about single texture atlas slot.
/// </summary>
struct Slot : RectPack<Slot>
{
Slot(uint32 x, uint32 y, uint32 width, uint32 height)
: RectPack<Slot>(x, y, width, height)
{
}
void OnInsert()
{
}
};
/// <summary> /// <summary>
/// Describes how to handle texture atlas padding /// Describes how to handle texture atlas padding
/// </summary> /// </summary>
@@ -74,8 +74,8 @@ private:
uint32 _bytesPerPixel; uint32 _bytesPerPixel;
PaddingStyle _paddingStyle; PaddingStyle _paddingStyle;
bool _isDirty; bool _isDirty;
Slot* _root; FontTextureAtlasSlot* _root;
Array<Slot*> _freeSlots; Array<FontTextureAtlasSlot*> _freeSlots;
public: public:
@@ -157,7 +157,7 @@ public:
/// <param name="targetHeight">Height of the entry.</param> /// <param name="targetHeight">Height of the entry.</param>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
/// <returns>The atlas slot occupied by the new entry.</returns> /// <returns>The atlas slot occupied by the new entry.</returns>
Slot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array<byte>& data); FontTextureAtlasSlot* AddEntry(uint32 targetWidth, uint32 targetHeight, const Array<byte>& data);
/// <summary> /// <summary>
/// Invalidates the cached dynamic entry from the atlas. /// Invalidates the cached dynamic entry from the atlas.
@@ -174,7 +174,17 @@ public:
/// </summary> /// </summary>
/// <param name="slot">The slot.</param> /// <param name="slot">The slot.</param>
/// <param name="data">The data.</param> /// <param name="data">The data.</param>
void CopyDataIntoSlot(const Slot* slot, const Array<byte>& data); void CopyDataIntoSlot(const FontTextureAtlasSlot* slot, const Array<byte>& data);
/// <summary>
/// Returns glyph's bitmap data of the slot.
/// </summary>
/// <param name="slot">The slot in atlas.</param>
/// <param name="width">The width of the slot.</param>
/// <param name="height">The height of the slot.</param>
/// <param name="stride">The stride of the slot.</param>
/// <returns>The pointer to the bitmap data of the given slot.</returns>
byte* GetSlotData(const FontTextureAtlasSlot* slot, uint32& width, uint32& height, uint32& stride);
/// <summary> /// <summary>
/// Clears this atlas entries data (doesn't change size/texture etc.). /// Clears this atlas entries data (doesn't change size/texture etc.).
@@ -204,7 +214,7 @@ public:
private: 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 markAsDirty();
void copyRow(const RowData& copyRowData) const; void copyRow(const RowData& copyRowData) const;
void zeroRow(const RowData& copyRowData) const; void zeroRow(const RowData& copyRowData) const;
+1 -1
View File
@@ -174,7 +174,7 @@ float4 PS_CopyInscatter1(Quad_VS2PS input) : SV_Target0
{ {
float3 uvw = float3(input.TexCoord, (float(AtmosphereLayer) + 0.5f) / float(AtmosphericFogInscatterAltitudeSampleNum)); float3 uvw = float3(input.TexCoord, (float(AtmosphereLayer) + 0.5f) / float(AtmosphericFogInscatterAltitudeSampleNum));
float4 ray = AtmosphereDeltaSRTexture.Sample(SamplerLinearClamp, uvw); float4 ray = AtmosphereDeltaSRTexture.Sample(SamplerLinearClamp, uvw);
float4 mie = AtmosphereDeltaSRTexture.Sample(SamplerLinearClamp, uvw); float4 mie = AtmosphereDeltaSMTexture.Sample(SamplerLinearClamp, uvw);
return float4(ray.xyz, mie.x); return float4(ray.xyz, mie.x);
} }