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

# Conflicts:
#	Source/Engine/Platform/StringUtils.h
This commit is contained in:
Wojtek Figat
2024-10-11 18:07:41 +02:00
37 changed files with 642 additions and 107 deletions

View File

@@ -10,15 +10,12 @@ jobs:
# Editor
editor-linux:
name: Editor (Linux, Development x64)
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
steps:
- name: Checkout repo
uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f .github/workflows/build_linux_sources.list /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan
uses: ./.github/actions/vulkan
@@ -41,7 +38,7 @@ jobs:
# Game
game-linux:
name: Game (Linux, Release x64)
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
steps:
- name: Checkout repo
uses: actions/checkout@v3

View File

@@ -1,4 +0,0 @@
deb http://archive.ubuntu.com/ubuntu/ focal main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ focal-updates main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ focal-security main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ focal-backports main restricted universe multiverse

View File

@@ -76,7 +76,7 @@ jobs:
# Linux
package-linux-editor:
name: Editor (Linux)
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -86,9 +86,6 @@ jobs:
git lfs pull
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f .github/workflows/build_linux_sources.list /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan
uses: ./.github/actions/vulkan
@@ -110,7 +107,7 @@ jobs:
path: Output/FlaxEditorLinux.zip
package-linux-game:
name: Game (Linux)
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -120,9 +117,6 @@ jobs:
git lfs pull
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f .github/workflows/build_linux_sources.list /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Setup Vulkan
uses: ./.github/actions/vulkan

View File

@@ -10,7 +10,7 @@ jobs:
# Tests on Linux
tests-linux:
name: Tests (Linux)
runs-on: "ubuntu-20.04"
runs-on: "ubuntu-24.04"
steps:
- name: Checkout repo
uses: actions/checkout@v3
@@ -28,9 +28,6 @@ jobs:
git lfs pull
- name: Install dependencies
run: |
sudo rm -f /etc/apt/sources.list.d/*
sudo cp -f .github/workflows/build_linux_sources.list /etc/apt/sources.list
sudo apt-get update
sudo apt-get install libx11-dev libxcursor-dev libxinerama-dev build-essential gettext libtool libtool-bin libpulse-dev libasound2-dev libjack-dev portaudio19-dev
- name: Build
run: |

View File

@@ -4,7 +4,7 @@
"Major": 1,
"Minor": 9,
"Revision": 0,
"Build": 6604
"Build": 6605
},
"Company": "Flax",
"Copyright": "Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.",

View File

@@ -32,6 +32,14 @@ namespace FlaxEditor.Content
/// <inheritdoc />
public override EditorWindow Open(Editor editor, ContentItem item)
{
#if PLATFORM_WINDOWS
CreateProcessSettings settings = new CreateProcessSettings
{
ShellExecute = true,
FileName = item.Path
};
Platform.CreateProcess(ref settings);
#endif
return null;
}

View File

@@ -241,6 +241,15 @@ namespace FlaxEditor.GUI
/// <param name="value">The keyframe value.</param>
public abstract void SetKeyframeValue(int index, object value);
/// <summary>
/// Sets the existing keyframe value (as boxed object).
/// </summary>
/// <param name="index">The keyframe index.</param>
/// <param name="value">The keyframe value.</param>
/// <param name="tangentIn">The keyframe 'In' tangent value (boxed).</param>
/// <param name="tangentOut">The keyframe 'Out' tangent value (boxed).</param>
public abstract void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut);
/// <summary>
/// Gets the keyframe point (in keyframes space).
/// </summary>

View File

@@ -1289,6 +1289,18 @@ namespace FlaxEditor.GUI
OnEdited();
}
/// <inheritdoc />
public override void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut)
{
var k = _keyframes[index];
k.Value = (T)value;
_keyframes[index] = k;
UpdateKeyframes();
UpdateTooltips();
OnEdited();
}
/// <inheritdoc />
public override Float2 GetKeyframePoint(int index, int component)
{
@@ -2011,6 +2023,20 @@ namespace FlaxEditor.GUI
OnEdited();
}
/// <inheritdoc />
public override void SetKeyframeValue(int index, object value, object tangentIn, object tangentOut)
{
var k = _keyframes[index];
k.Value = (T)value;
k.TangentIn = (T)tangentIn;
k.TangentOut = (T)tangentOut;
_keyframes[index] = k;
UpdateKeyframes();
UpdateTooltips();
OnEdited();
}
/// <inheritdoc />
public override Float2 GetKeyframePoint(int index, int component)
{

View File

@@ -139,6 +139,8 @@ namespace FlaxEditor.GUI.Docking
/// <inheritdoc />
protected override void OnLastTabRemoved()
{
if (ChildPanelsCount > 0)
return;
// Close window
_window?.Close();
}

View File

@@ -0,0 +1,203 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using FlaxEditor.Gizmo;
using FlaxEditor.GUI.Timeline.Tracks;
using FlaxEditor.GUI.Timeline.Undo;
using FlaxEditor.SceneGraph;
using FlaxEngine;
namespace FlaxEditor.GUI.Timeline
{
/// <summary>
/// Gizmo for editing position curve. Managed by the <see cref="SceneAnimationTimeline"/>.
/// </summary>
sealed class EditCurveTrackGizmo : TransformGizmoBase
{
public const float KeyframeSize = 10.0f;
public const float TangentSize = 6.0f;
private readonly SceneAnimationTimeline _timeline;
private CurvePropertyTrack _track;
private int _keyframe = -1;
private int _item = -1;
private byte[] _curveEditingStartData;
public int Keyframe => _keyframe;
public int Item => _item;
public EditCurveTrackGizmo(IGizmoOwner owner, SceneAnimationTimeline timeline)
: base(owner)
{
_timeline = timeline;
}
public void SelectKeyframe(CurvePropertyTrack track, int keyframe, int item)
{
_track = track;
_keyframe = keyframe;
_item = item;
}
public override BoundingSphere FocusBounds
{
get
{
if (_track == null)
return BoundingSphere.Empty;
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
var keyframes = curve.Keyframes;
var k = keyframes[_keyframe];
if (_item == 1)
k.Value += k.TangentIn;
else if (_item == 2)
k.Value += k.TangentOut;
return new BoundingSphere(k.Value, KeyframeSize);
}
}
protected override int SelectionCount => _track != null ? 1 : 0;
protected override SceneGraphNode GetSelectedObject(int index)
{
return null;
}
protected override Transform GetSelectedTransform(int index)
{
if (_track == null)
return Transform.Identity;
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
var keyframes = curve.Keyframes;
var k = keyframes[_keyframe];
if (_item == 1)
k.Value += k.TangentIn;
else if (_item == 2)
k.Value += k.TangentOut;
return new Transform(k.Value);
}
protected override void GetSelectedObjectsBounds(out BoundingBox bounds, out bool navigationDirty)
{
bounds = BoundingBox.Empty;
navigationDirty = false;
if (_track == null)
return;
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
var keyframes = curve.Keyframes;
var k = keyframes[_keyframe];
if (_item == 1)
k.Value += k.TangentIn;
else if (_item == 2)
k.Value += k.TangentOut;
bounds = new BoundingBox(k.Value - KeyframeSize, k.Value + KeyframeSize);
}
protected override bool IsSelected(SceneGraphNode obj)
{
return false;
}
protected override void OnStartTransforming()
{
base.OnStartTransforming();
// Start undo
_curveEditingStartData = EditTrackAction.CaptureData(_track);
}
protected override void OnEndTransforming()
{
base.OnEndTransforming();
// End undo
var after = EditTrackAction.CaptureData(_track);
if (!Utils.ArraysEqual(_curveEditingStartData, after))
_track.Timeline.AddBatchedUndoAction(new EditTrackAction(_track.Timeline, _track, _curveEditingStartData, after));
_curveEditingStartData = null;
}
protected override void OnApplyTransformation(ref Vector3 translationDelta, ref Quaternion rotationDelta, ref Vector3 scaleDelta)
{
base.OnApplyTransformation(ref translationDelta, ref rotationDelta, ref scaleDelta);
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
var keyframes = curve.Keyframes;
var k = keyframes[_keyframe];
if (_item == 0)
k.Value += translationDelta;
else if (_item == 1)
k.TangentIn += translationDelta;
else if (_item == 2)
k.TangentOut += translationDelta;
curve.SetKeyframeValue(_keyframe, k.Value, k.TangentIn, k.TangentOut);
}
public override void Pick()
{
if (_track == null)
return;
var selectRay = Owner.MouseRay;
var curve = (BezierCurveEditor<Vector3>)_track.Curve;
var keyframes = curve.Keyframes;
for (var i = 0; i < keyframes.Count; i++)
{
var k = keyframes[i];
var sphere = new BoundingSphere(k.Value, KeyframeSize);
if (sphere.Intersects(ref selectRay))
{
SelectKeyframe(_track, i, 0);
return;
}
if (!k.TangentIn.IsZero)
{
var t = k.Value + k.TangentIn;
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
if (box.Intersects(ref selectRay))
{
SelectKeyframe(_track, i, 1);
return;
}
}
if (!k.TangentOut.IsZero)
{
var t = k.Value + k.TangentOut;
var box = BoundingBox.FromSphere(new BoundingSphere(t, TangentSize));
if (box.Intersects(ref selectRay))
{
SelectKeyframe(_track, i, 2);
return;
}
}
}
}
public override void Update(float dt)
{
base.Update(dt);
// Deactivate when track gets deselected
if (_track != null && !_timeline.SelectedTracks.Contains(_track))
Owner.Gizmos.Active = Owner.Gizmos.Get<TransformGizmo>();
}
public override void OnActivated()
{
base.OnActivated();
ActiveMode = Mode.Translate;
}
public override void OnDeactivated()
{
// Clear selection
_track = null;
_keyframe = -1;
_item = -1;
base.OnDeactivated();
}
}
}

View File

@@ -1,11 +1,12 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using FlaxEngine;
using FlaxEditor.Content;
using FlaxEditor.Gizmo;
using FlaxEditor.GUI.Drag;
using FlaxEditor.GUI.Timeline.Tracks;
using FlaxEditor.SceneGraph;
using FlaxEngine;
namespace FlaxEditor.GUI.Timeline
{
@@ -25,6 +26,7 @@ namespace FlaxEditor.GUI.Timeline
}
private SceneAnimationPlayer _player;
private EditCurveTrackGizmo _curveTrackGizmo;
private bool _showSelected3dTrack = true;
internal Guid _id;
@@ -239,6 +241,19 @@ namespace FlaxEditor.GUI.Timeline
}
}
private void SelectKeyframeGizmo(CurvePropertyTrack track, int keyframe, int item)
{
var mainGizmo = Editor.Instance.MainTransformGizmo;
if (!mainGizmo.IsActive)
return; // Skip when using vertex painting or terrain or foliage tools
if (_curveTrackGizmo == null)
{
_curveTrackGizmo = new EditCurveTrackGizmo(mainGizmo.Owner, this);
}
_curveTrackGizmo.SelectKeyframe(track, keyframe, item);
_curveTrackGizmo.Activate();
}
/// <inheritdoc />
public override void OnPlay()
{
@@ -289,8 +304,17 @@ namespace FlaxEditor.GUI.Timeline
UpdatePlaybackState();
// Draw all selected 3D position tracks as Bezier curve in editor viewport
if (ShowSelected3dTrack)
if (!VisibleInHierarchy || !EnabledInHierarchy)
{
// Disable curve transform gizmo to normal gizmo
if (_curveTrackGizmo != null && _curveTrackGizmo.IsActive)
_curveTrackGizmo.Owner.Gizmos.Get<TransformGizmo>().Activate();
}
else if (ShowSelected3dTrack)
{
bool select = FlaxEngine.Input.GetMouseButtonDown(MouseButton.Left);
Ray selectRay = Editor.Instance.MainTransformGizmo.Owner.MouseRay;
const float coveredAlpha = 0.1f;
foreach (var track in SelectedTracks)
{
if (
@@ -302,31 +326,44 @@ namespace FlaxEditor.GUI.Timeline
{
var curve = (BezierCurveEditor<Vector3>)curveTrack.Curve;
var keyframes = curve.Keyframes;
var selectedKeyframe = _curveTrackGizmo?.Keyframe ?? -1;
var selectedItem = _curveTrackGizmo?.Item ?? -1;
for (var i = 0; i < keyframes.Count; i++)
{
var k = keyframes[i];
DebugDraw.DrawSphere(new BoundingSphere(k.Value, 10.0f), Color.Red);
DebugDraw.DrawSphere(new BoundingSphere(k.Value, 9.5f), new Color(1, 0, 0, 0.1f), 0, false);
var selected = selectedKeyframe == i && selectedItem == 0;
var sphere = new BoundingSphere(k.Value, EditCurveTrackGizmo.KeyframeSize);
DebugDraw.DrawSphere(sphere, selected ? Color.Yellow : Color.Red);
sphere.Radius *= 0.95f;
DebugDraw.DrawSphere(sphere, new Color(1, 0, 0, coveredAlpha), 0, false);
if (select && sphere.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 0);
if (!k.TangentIn.IsZero)
{
selected = selectedKeyframe == i && selectedItem == 1;
var t = k.Value + k.TangentIn;
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(0.1f), 0, false);
var box = BoundingBox.FromSphere(new BoundingSphere(t, 6.0f));
DebugDraw.DrawBox(box, Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(0.1f), 0, false);
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(coveredAlpha), 0, false);
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
if (select && box.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 2);
}
if (!k.TangentOut.IsZero)
{
selected = selectedKeyframe == i && selectedItem == 2;
var t = k.Value + k.TangentOut;
DebugDraw.DrawLine(k.Value, t, Color.Yellow);
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(0.1f), 0, false);
var box = BoundingBox.FromSphere(new BoundingSphere(t, 6.0f));
DebugDraw.DrawBox(box, Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(0.1f), 0, false);
DebugDraw.DrawLine(k.Value, t, Color.Yellow.AlphaMultiplied(coveredAlpha), 0, false);
var box = BoundingBox.FromSphere(new BoundingSphere(t, EditCurveTrackGizmo.TangentSize));
DebugDraw.DrawBox(box, selected ? Color.Yellow : Color.AliceBlue);
DebugDraw.DrawBox(box, Color.AliceBlue.AlphaMultiplied(coveredAlpha), 0, false);
if (select && box.Intersects(ref selectRay))
SelectKeyframeGizmo(curveTrack, i, 2);
}
if (i != 0)
@@ -341,6 +378,18 @@ namespace FlaxEditor.GUI.Timeline
}
}
/// <inheritdoc />
public override void OnDestroy()
{
if (_curveTrackGizmo != null)
{
_curveTrackGizmo.Destroy();
_curveTrackGizmo = null;
}
base.OnDestroy();
}
/// <inheritdoc />
protected override void OnShowViewContextMenu(ContextMenu.ContextMenu menu)
{

View File

@@ -12,15 +12,17 @@ namespace FlaxEditor.Gizmo
[HideInEditor]
public abstract class GizmoBase
{
private IGizmoOwner _owner;
/// <summary>
/// Gets the gizmo owner.
/// </summary>
public IGizmoOwner Owner { get; }
public IGizmoOwner Owner => _owner;
/// <summary>
/// Gets a value indicating whether this gizmo is active.
/// </summary>
public bool IsActive => Owner.Gizmos.Active == this;
public bool IsActive => _owner.Gizmos.Active == this;
/// <summary>
/// Gets a value indicating whether this gizmo is using mouse currently (eg. user moving objects).
@@ -39,8 +41,8 @@ namespace FlaxEditor.Gizmo
protected GizmoBase(IGizmoOwner owner)
{
// Link
Owner = owner;
Owner.Gizmos.Add(this);
_owner = owner;
_owner.Gizmos.Add(this);
}
/// <summary>
@@ -94,5 +96,25 @@ namespace FlaxEditor.Gizmo
public virtual void Draw(ref RenderContext renderContext)
{
}
/// <summary>
/// Activates thi gizmo mode.
/// </summary>
public void Activate()
{
_owner.Gizmos.Active = this;
}
/// <summary>
/// Removes the gizmo from the owner.
/// </summary>
public void Destroy()
{
if (_owner != null)
{
_owner.Gizmos.Remove(this);
_owner = null;
}
}
}
}

View File

@@ -950,7 +950,7 @@ namespace FlaxEditor.Modules
MainWindow = null;
// Capture project icon screenshot (not in play mode and if editor was used for some time)
if (!Editor.StateMachine.IsPlayMode && Time.TimeSinceStartup >= 5.0f)
if (!Editor.StateMachine.IsPlayMode && Time.TimeSinceStartup >= 5.0f && GPUDevice.Instance?.RendererType != RendererType.Null)
{
Editor.Log("Capture project icon screenshot");
_projectIconScreenshotTimeout = Time.TimeSinceStartup + 0.8f; // wait 800ms for a screenshot task

View File

@@ -13,6 +13,37 @@ using namespace pugi;
Array<ProjectInfo*> ProjectInfo::ProjectsCache;
struct XmlCharAsChar
{
#if PLATFORM_TEXT_IS_CHAR16
Char* Str = nullptr;
XmlCharAsChar(const pugi::char_t* str)
{
if (!str)
return;
int32 length = 0;
while (str[length])
length++;
Str = (Char*)Platform::Allocate(length * sizeof(Char), sizeof(Char));
for (int32 i = 0; i <= length; i++)
Str[i] = (Char)str[i];
}
~XmlCharAsChar()
{
Platform::Free(Str);
}
#else
const Char* Str;
XmlCharAsChar(const pugi::char_t* str)
: Str(str)
{
}
#endif
};
void ShowProjectLoadError(const Char* errorMsg, const String& projectRootFolder)
{
Platform::Error(String::Format(TEXT("Failed to load project. {0}\nPath: '{1}'"), errorMsg, projectRootFolder));
@@ -28,14 +59,14 @@ Vector3 GetVector3FromXml(const xml_node& parent, const PUGIXML_CHAR* name, cons
const auto z = node.child_value(PUGIXML_TEXT("Z"));
if (x && y && z)
{
Vector3 v;
if (!StringUtils::Parse(x, &v.X) && !StringUtils::Parse(y, &v.Y) && !StringUtils::Parse(z, &v.Z))
XmlCharAsChar xs(x), ys(y), zs(z);
Float3 v;
if (!StringUtils::Parse(xs.Str, &v.X) && !StringUtils::Parse(ys.Str, &v.Y) && !StringUtils::Parse(zs.Str, &v.Z))
{
return v;
return (Vector3)v;
}
}
}
return defaultValue;
}
@@ -44,8 +75,9 @@ int32 GetIntFromXml(const xml_node& parent, const PUGIXML_CHAR* name, const int3
const auto node = parent.child_value(name);
if (node)
{
XmlCharAsChar s(node);
int32 v;
if (!StringUtils::Parse(node, &v))
if (!StringUtils::Parse(s.Str, &v))
{
return v;
}

View File

@@ -97,6 +97,9 @@ namespace FlaxEditor.Windows.Assets
[EditorDisplay(null, "1920x1080 (Full HD)")]
_1920x1080,
[EditorDisplay(null, "2560x1440 (2K)")]
_2560x1440,
[EditorDisplay(null, "3840x2160 (4K)")]
_3840x2160,
@@ -173,6 +176,7 @@ namespace FlaxEditor.Windows.Assets
case ResolutionModes._640x480: return new Int2(640, 480);
case ResolutionModes._1280x720: return new Int2(1280, 720);
case ResolutionModes._1920x1080: return new Int2(1920, 1080);
case ResolutionModes._2560x1440: return new Int2(2560, 1440);
case ResolutionModes._3840x2160: return new Int2(3840, 2160);
case ResolutionModes._7680x4320: return new Int2(7680, 4320);
case ResolutionModes.Custom: return new Int2(Width, Height);
@@ -456,8 +460,12 @@ namespace FlaxEditor.Windows.Assets
_window.Editor.StateMachine.CurrentState.UpdateFPS();
for (int i = 0; i < _stagingTextures.Length; i++)
{
_stagingTextures[i].Texture.ReleaseGPU();
Object.Destroy(ref _stagingTextures[i].Texture);
var texture = _stagingTextures[i].Texture;
if (texture)
{
texture.ReleaseGPU();
Object.Destroy(ref texture);
}
}
if (_progress != null)
{

View File

@@ -553,14 +553,14 @@ namespace FlaxEditor.Windows
});
_defaultViewportScaling.Add(new ViewportScaleOptions
{
Label = "1920x1080 Resolution",
Label = "1920x1080 Resolution (Full HD)",
ScaleType = ViewportScaleType.Resolution,
Size = new Int2(1920, 1080),
Active = false,
});
_defaultViewportScaling.Add(new ViewportScaleOptions
{
Label = "2560x1440 Resolution",
Label = "2560x1440 Resolution (2K)",
ScaleType = ViewportScaleType.Resolution,
Size = new Int2(2560, 1440),
Active = false,

View File

@@ -80,12 +80,12 @@ public:
public:
bool operator==(const Color32& other) const
{
return R == other.R && G == other.G && B == other.B && A == other.A;
return Raw == other.Raw;
}
bool operator!=(const Color32& other) const
{
return R != other.R || G != other.G || B != other.B || A != other.A;
return Raw != other.Raw;
}
Color32 operator+(const Color32& b) const
@@ -138,7 +138,7 @@ public:
// Returns true if color is fully transparent (all components are equal zero).
bool IsTransparent() const
{
return R + G + B + A == 0;
return Raw == 0;
}
// Returns true if color has opacity channel in use (different from 255).
@@ -222,7 +222,7 @@ namespace Math
{
FORCE_INLINE static bool NearEqual(const Color32& a, const Color32& b)
{
return a == b;
return a.Raw == b.Raw;
}
}

View File

@@ -173,8 +173,8 @@ public:
/// <summary>
/// Frequency of shadow updates at the maximum distance from the view at which shadows are still rendered. This value is multiplied by ShadowsUpdateRate and allows scaling the update rate in-between the shadow range. For example, if light is near view, it will get normal shadow updates but will reduce this rate when far from view. See ShadowsUpdateRate to learn more.
/// </summary>
API_FIELD(Attributes="EditorOrder(105), EditorDisplay(\"Shadow\", \"Update Rate At Distance\"), Limit(0.0f, 1.0f)")
float ShadowsUpdateRateAtDistance = 0.5f;
API_FIELD(Attributes="EditorOrder(101), EditorDisplay(\"Shadow\", \"Update Rate At Distance\"), Limit(0.0f, 1.0f)")
float ShadowsUpdateRateAtDistance = 1.0f;
/// <summary>
/// Defines the resolution of the shadow map texture used to draw objects projection from light-point-of-view. Higher values increase shadow quality at cost of performance.

View File

@@ -52,7 +52,7 @@ public:
/// <summary>
/// Gets the joint mode flags. Controls joint behaviour.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(DistanceJointFlag.MinDistance | DistanceJointFlag.MaxDistance)")
API_PROPERTY(Attributes="EditorOrder(100), EditorDisplay(\"Joint\"), DefaultValue(DistanceJointFlag.MinDistance | DistanceJointFlag.MaxDistance)")
FORCE_INLINE DistanceJointFlag GetFlags() const
{
return _flags;

View File

@@ -80,7 +80,7 @@ public:
/// <summary>
/// Gets the joint mode flags. Controls joint behaviour.
/// </summary>
API_PROPERTY(Attributes="EditorOrder(100), DefaultValue(HingeJointFlag.Limit | HingeJointFlag.Drive)")
API_PROPERTY(Attributes="EditorOrder(100), EditorDisplay(\"Joint\"), DefaultValue(HingeJointFlag.Limit | HingeJointFlag.Drive)")
FORCE_INLINE HingeJointFlag GetFlags() const
{
return _flags;

View File

@@ -186,8 +186,8 @@ API_ENUM() enum class ArchitectureType
#ifndef PLATFORM_ARCH_ARM64
#define PLATFORM_ARCH_ARM64 0
#endif
#ifndef PLATFORM_WCHAR_IS_CHAR16
#define PLATFORM_WCHAR_IS_CHAR16 0
#ifndef PLATFORM_TEXT_IS_CHAR16
#define PLATFORM_TEXT_IS_CHAR16 0
#endif
#ifndef PLATFORM_DEBUG_BREAK
#define PLATFORM_DEBUG_BREAK

View File

@@ -196,12 +196,12 @@ public:
static int32 HexDigit(Char c);
// Parses text to unsigned integer value. Returns true if failed to convert the value.
template<typename CharType>
static bool ParseHex(const CharType* str, int32 length, uint32* result)
template<typename T>
static bool ParseHex(const T* str, int32 length, uint32* result)
{
uint32 sum = 0;
const CharType* p = str;
const CharType* end = str + length;
const T* p = str;
const T* end = str + length;
if (*p == '0' && *(p + 1) == 'x')
p += 2;
while (*p && p < end)
@@ -221,10 +221,10 @@ public:
}
// Parses text to unsigned integer value. Returns true if failed to convert the value.
template<typename CharType>
static bool ParseHex(const CharType* str, uint32* result)
template<typename T>
static bool ParseHex(const T* str, uint32* result)
{
return ParseHex(str, Length(str), result);
return StringUtils::ParseHex(str, StringUtils::Length(str), result);
}
// Parses text to the unsigned integer value. Returns true if failed to convert the value.
@@ -247,7 +247,7 @@ public:
static bool Parse(const T* str, uint32 length, uint32* result)
{
uint64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (uint32)tmp;
return b;
}
@@ -255,7 +255,7 @@ public:
static bool Parse(const T* str, uint32 length, uint16* result)
{
uint64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (uint16)tmp;
return b;
}
@@ -263,7 +263,7 @@ public:
static bool Parse(const T* str, uint32 length, uint8* result)
{
uint64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (uint8)tmp;
return b;
}
@@ -296,7 +296,7 @@ public:
static bool Parse(const T* str, uint32 length, int32* result)
{
int64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (int32)tmp;
return b;
}
@@ -304,7 +304,7 @@ public:
static bool Parse(const T* str, uint32 length, int16* result)
{
int64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (int16)tmp;
return b;
}
@@ -312,7 +312,7 @@ public:
static bool Parse(const T* str, uint32 length, int8* result)
{
int64 tmp;
const bool b = Parse(str, length, &tmp);
const bool b = StringUtils::Parse(str, length, &tmp);
*result = (int8)tmp;
return b;
}
@@ -321,7 +321,7 @@ public:
template<typename T, typename U>
static bool Parse(const T* str, U* result)
{
return Parse(str, Length(str), result);
return StringUtils::Parse(str, StringUtils::Length(str), result);
}
// Parses text to the scalar value. Returns true if failed to convert the value.

View File

@@ -330,6 +330,7 @@ public:
for (auto it = Lights.Begin(); it.IsNotEnd(); ++it)
{
auto& atlasLight = it->Value;
atlasLight.StaticState = ShadowAtlasLight::Unused;
atlasLight.Cache.StaticValid = false;
for (int32 i = 0; i < atlasLight.TilesCount; i++)
atlasLight.Tiles[i].ClearDynamic();
@@ -370,7 +371,8 @@ public:
for (auto& e : Lights)
{
auto& atlasLight = e.Value;
if (atlasLight.StaticState == ShadowAtlasLight::CopyStaticShadow && atlasLight.Bounds.Intersects(bounds))
if ((atlasLight.StaticState == ShadowAtlasLight::CopyStaticShadow || atlasLight.StaticState == ShadowAtlasLight::NoStaticGeometry)
&& atlasLight.Bounds.Intersects(bounds))
{
// Invalidate static shadow
atlasLight.Cache.StaticValid = false;
@@ -719,8 +721,14 @@ bool ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
}
switch (atlasLight.StaticState)
{
case ShadowAtlasLight::CopyStaticShadow:
case ShadowAtlasLight::NoStaticGeometry:
// Light was modified so attempt to find the static shadow again
if (!atlasLight.Cache.StaticValid && atlasLight.HasStaticShadowContext)
{
atlasLight.StaticState = ShadowAtlasLight::WaitForGeometryCheck;
break;
}
case ShadowAtlasLight::CopyStaticShadow:
case ShadowAtlasLight::FailedToInsertTiles:
// Skip collecting static draws
atlasLight.HasStaticShadowContext = false;
@@ -728,7 +736,7 @@ bool ShadowsPass::SetupLight(ShadowsCustomBuffer& shadows, RenderContext& render
}
if (atlasLight.HasStaticShadowContext)
{
// If rendering finds any static draws then it's set to true
// If rendering finds any static draws then it will be set to true
for (auto& tile : atlasLight.Tiles)
tile.HasStaticGeometry = false;
}
@@ -1367,7 +1375,7 @@ void ShadowsPass::RenderShadowMaps(RenderContextBatch& renderContextBatch)
const ShadowsCustomBuffer* shadowsPtr = renderContext.Buffers->FindCustomBuffer<ShadowsCustomBuffer>(TEXT("Shadows"), false);
if (shadowsPtr == nullptr || shadowsPtr->Lights.IsEmpty() || shadowsPtr->LastFrameUsed != Engine::FrameCount)
return;
PROFILE_GPU_CPU("ShadowMaps");
PROFILE_GPU_CPU("Shadow Maps");
const ShadowsCustomBuffer& shadows = *shadowsPtr;
GPUContext* context = GPUDevice::Instance->GetMainContext();
context->ResetSR();
@@ -1384,9 +1392,29 @@ void ShadowsPass::RenderShadowMaps(RenderContextBatch& renderContextBatch)
for (auto& e : shadows.Lights)
{
ShadowAtlasLight& atlasLight = e.Value;
if (atlasLight.StaticState != ShadowAtlasLight::UpdateStaticShadow || !atlasLight.HasStaticShadowContext || atlasLight.ContextCount == 0)
if (!atlasLight.HasStaticShadowContext || atlasLight.ContextCount == 0)
continue;
int32 contextIndex = 0;
if (atlasLight.StaticState == ShadowAtlasLight::WaitForGeometryCheck)
{
// Check for any static geometry to use in static shadow map
for (int32 tileIndex = 0; tileIndex < atlasLight.TilesCount; tileIndex++)
{
ShadowAtlasLightTile& tile = atlasLight.Tiles[tileIndex];
contextIndex++; // Skip dynamic context
auto& shadowContextStatic = renderContextBatch.Contexts[atlasLight.ContextIndex + contextIndex++];
if (!shadowContextStatic.List->DrawCallsLists[(int32)DrawCallsListType::Depth].IsEmpty() || !shadowContextStatic.List->ShadowDepthDrawCallsList.IsEmpty())
{
tile.HasStaticGeometry = true;
}
}
}
if (atlasLight.StaticState != ShadowAtlasLight::UpdateStaticShadow)
continue;
contextIndex = 0;
for (int32 tileIndex = 0; tileIndex < atlasLight.TilesCount; tileIndex++)
{
ShadowAtlasLightTile& tile = atlasLight.Tiles[tileIndex];

View File

@@ -661,7 +661,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
if (sourceWidth != width || sourceHeight != height)
{
// During resizing we need to keep texture aspect ratio
const bool keepAspectRatio = false; // TODO: expose as import option
const bool keepAspectRatio = options.KeepAspectRatio;
if (keepAspectRatio)
{
const float aspectRatio = static_cast<float>(sourceWidth) / sourceHeight;
@@ -727,8 +727,10 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
}
bool keepAsIs = false;
if (!options.FlipY &&
!options.InvertGreenChannel &&
if (!options.FlipY &&
!options.FlipX &&
!options.InvertGreenChannel &&
!options.ReconstructZChannel &&
options.Compress &&
type == ImageType::DDS &&
mipLevels == sourceMipLevels &&
@@ -787,7 +789,7 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
SET_CURRENT_IMG(tmpImg);
}
// Check flip/rotate source image
// Check flip/rotate Y source image
if (!keepAsIs && options.FlipY)
{
auto& tmpImg = GET_TMP_IMG();
@@ -801,6 +803,20 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
SET_CURRENT_IMG(tmpImg);
}
// Check flip/rotate X source image
if (!keepAsIs && options.FlipX)
{
auto& tmpImg = GET_TMP_IMG();
DirectX::TEX_FR_FLAGS flags = DirectX::TEX_FR_FLIP_HORIZONTAL;
result = FlipRotate(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(), flags, tmpImg);
if (FAILED(result))
{
errorMsg = String::Format(TEXT("Cannot rotate/flip texture, error: {0:x}"), static_cast<uint32>(result));
return true;
}
SET_CURRENT_IMG(tmpImg);
}
// Check if invert green channel
if (!keepAsIs && options.InvertGreenChannel)
{
@@ -829,6 +845,43 @@ bool TextureTool::ImportTextureDirectXTex(ImageType type, const StringView& path
SET_CURRENT_IMG(timage);
}
// Reconstruct Z Channel
if (!keepAsIs & options.ReconstructZChannel)
{
auto& timage = GET_TMP_IMG();
bool isunorm = (DirectX::FormatDataType(sourceDxgiFormat) == DirectX::FORMAT_TYPE_UNORM) != 0;
result = TransformImage(currentImage->GetImages(), currentImage->GetImageCount(), currentImage->GetMetadata(),
[&](DirectX::XMVECTOR* outPixels, const DirectX::XMVECTOR* inPixels, size_t w, size_t y)
{
static const DirectX::XMVECTORU32 s_selectz = { { { DirectX::XM_SELECT_0, DirectX::XM_SELECT_0, DirectX::XM_SELECT_1, DirectX::XM_SELECT_0 } } };
UNREFERENCED_PARAMETER(y);
for (size_t j = 0; j < w; ++j)
{
const DirectX::XMVECTOR value = inPixels[j];
DirectX::XMVECTOR z;
if (isunorm)
{
DirectX::XMVECTOR x2 = DirectX::XMVectorMultiplyAdd(value, DirectX::g_XMTwo, DirectX::g_XMNegativeOne);
x2 = DirectX::XMVectorSqrt(DirectX::XMVectorSubtract(DirectX::g_XMOne, DirectX::XMVector2Dot(x2, x2)));
z = DirectX::XMVectorMultiplyAdd(x2, DirectX::g_XMOneHalf, DirectX::g_XMOneHalf);
}
else
{
z = DirectX::XMVectorSqrt(DirectX::XMVectorSubtract(DirectX::g_XMOne, DirectX::XMVector2Dot(value, value)));
}
outPixels[j] = DirectX::XMVectorSelect(value, z, s_selectz);
}
}, timage);
if (FAILED(result))
{
errorMsg = String::Format(TEXT("Cannot reconstruct z channel in texture, error: {0:x}"), static_cast<uint32>(result));
return true;
}
SET_CURRENT_IMG(timage);
}
// Generate mip maps chain
if (!keepAsIs && useMipLevels && options.GenerateMipMaps)
{

View File

@@ -73,12 +73,21 @@ void TextureTool::Options::Serialize(SerializeStream& stream, const void* otherO
stream.JKEY("FlipY");
stream.Bool(FlipY);
stream.JKEY("FlipX");
stream.Bool(FlipX);
stream.JKEY("InvertGreenChannel");
stream.Bool(InvertGreenChannel);
stream.JKEY("ReconstructZChannel");
stream.Bool(ReconstructZChannel);
stream.JKEY("Resize");
stream.Bool(Resize);
stream.JKEY("KeepAspectRatio");
stream.Bool(KeepAspectRatio);
stream.JKEY("PreserveAlphaCoverage");
stream.Bool(PreserveAlphaCoverage);
@@ -133,8 +142,11 @@ void TextureTool::Options::Deserialize(DeserializeStream& stream, ISerializeModi
sRGB = JsonTools::GetBool(stream, "sRGB", sRGB);
GenerateMipMaps = JsonTools::GetBool(stream, "GenerateMipMaps", GenerateMipMaps);
FlipY = JsonTools::GetBool(stream, "FlipY", FlipY);
FlipX = JsonTools::GetBool(stream, "FlipX", FlipX);
InvertGreenChannel = JsonTools::GetBool(stream, "InvertGreenChannel", InvertGreenChannel);
ReconstructZChannel = JsonTools::GetBool(stream, "ReconstructZChannel", ReconstructZChannel);
Resize = JsonTools::GetBool(stream, "Resize", Resize);
KeepAspectRatio = JsonTools::GetBool(stream, "KeepAspectRatio", KeepAspectRatio);
PreserveAlphaCoverage = JsonTools::GetBool(stream, "PreserveAlphaCoverage", PreserveAlphaCoverage);
PreserveAlphaCoverageReference = JsonTools::GetFloat(stream, "PreserveAlphaCoverageReference", PreserveAlphaCoverageReference);
TextureGroup = JsonTools::GetInt(stream, "TextureGroup", TextureGroup);

View File

@@ -53,14 +53,22 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool
API_FIELD(Attributes="EditorOrder(60)")
bool GenerateMipMaps = true;
// True if flip Y coordinate of the texture.
// True if flip Y coordinate of the texture (Flips over X axis).
API_FIELD(Attributes="EditorOrder(70)")
bool FlipY = false;
// True if flip X coordinate of the texture (Flips over Y axis).
API_FIELD(Attributes="EditorOrder(71)")
bool FlipX = false;
// True if to invert the green channel on a normal map. Good for OpenGL to DirectX conversion.
API_FIELD(Attributes = "EditorOrder(71)")
API_FIELD(Attributes = "EditorOrder(72)")
bool InvertGreenChannel = false;
// Rebuild Z (blue) channel assuming X/Y are normals.
API_FIELD(Attributes = "EditorOrder(73)")
bool ReconstructZChannel = false;
// Texture size scale. Allows increasing or decreasing the imported texture resolution. Default is 1.
API_FIELD(Attributes="EditorOrder(80), Limit(0.0001f, 1000.0f, 0.01f)")
float Scale = 1.0f;
@@ -73,6 +81,10 @@ API_CLASS(Namespace="FlaxEngine.Tools", Static) class FLAXENGINE_API TextureTool
API_FIELD(Attributes="EditorOrder(100)")
bool Resize = false;
// Keeps the aspect ratio when resizing.
API_FIELD(Attributes="EditorOrder(101), VisibleIf(nameof(Resize))")
bool KeepAspectRatio = false;
// The width of the imported texture. If Resize property is set to true then texture will be resized during the import to this value during the import, otherwise it will be ignored.
API_FIELD(Attributes="HideInEditor")
int32 SizeX = 1024;

View File

@@ -458,7 +458,7 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu
{
if (!options.InternalLoad.IsBinded() || options.InternalLoad(textureData))
return true;
if (options.FlipY)
if (options.FlipY || options.FlipX)
{
// TODO: impl this
errorMsg = TEXT("Flipping images imported from Internal source is not supported by stb.");
@@ -489,7 +489,7 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu
if (sourceWidth != width || sourceHeight != height)
{
// During resizing we need to keep texture aspect ratio
const bool keepAspectRatio = false; // TODO: expose as import option
const bool keepAspectRatio = options.KeepAspectRatio; // TODO: expose as import option
if (keepAspectRatio)
{
const float aspectRatio = static_cast<float>(sourceWidth) / sourceHeight;
@@ -536,6 +536,22 @@ bool TextureTool::ImportTextureStb(ImageType type, const StringView& path, Textu
return true;
}
if (options.FlipX)
{
// TODO: impl this
LOG(Warning, "Option 'Flip X' is not supported");
}
if (options.InvertGreenChannel)
{
// TODO: impl this
LOG(Warning, "Option 'Invert Green Channel' is not supported");
}
if (options.ReconstructZChannel)
{
// TODO: impl this
LOG(Warning, "Option 'Reconstruct Z Channel' is not supported");
}
// Generate mip maps chain
if (useMipLevels && options.GenerateMipMaps)
{

View File

@@ -60,6 +60,51 @@ namespace FlaxEngine.GUI
return false;
}
/// <summary>
/// Gets the text block or the nearest text block of the character at the given index.
/// </summary>
/// <param name="index">The character index.</param>
/// <param name="result">The result text block descriptor.</param>
/// <param name="snapToNext">If true, the when the index is between two text blocks, it will return the next block.</param>
/// <returns>True if a text block is found, otherwise false.</returns>
public bool GetNearestTextBlock(int index, out TextBlock result, bool snapToNext = false)
{
var textBlocksSpan = CollectionsMarshal.AsSpan(_textBlocks);
int blockCount = _textBlocks.Count;
for (int i = 0; i < blockCount; i++)
{
ref TextBlock currentBlock = ref textBlocksSpan[i];
if (currentBlock.Range.Contains(index))
{
result = currentBlock;
return true;
}
if (i < blockCount - 1)
{
ref TextBlock nextBlock = ref textBlocksSpan[i + 1];
if (index >= currentBlock.Range.EndIndex && index < nextBlock.Range.StartIndex)
{
result = snapToNext ? nextBlock : currentBlock;
return true;
}
}
}
// Handle case when index is outside all text ranges
if (index >= 0 && blockCount > 0)
{
result = (index <= textBlocksSpan[0].Range.StartIndex) ? textBlocksSpan[0] : textBlocksSpan[blockCount - 1];
return true;
}
// If no text block is found
result = new TextBlock();
return false;
}
/// <summary>
/// Updates the text blocks.
/// </summary>
@@ -221,6 +266,35 @@ namespace FlaxEngine.GUI
return base.OnMouseDoubleClick(location, button);
}
/// <inheritdoc />
protected override void SetSelection(int start, int end, bool withScroll = true)
{
int snappedStart = start;
int snappedEnd = end;
if (start != -1 && end != -1)
{
bool movingBack = (_selectionStart != -1 && _selectionEnd != -1) && (end < _selectionEnd || start < _selectionStart);
GetNearestTextBlock(start, out TextBlock startTextBlock, !movingBack);
GetNearestTextBlock(end, out TextBlock endTextBlock, !movingBack);
snappedStart = startTextBlock.Range.Contains(start) ? start : (movingBack ? startTextBlock.Range.EndIndex - 1 : startTextBlock.Range.StartIndex);
snappedEnd = endTextBlock.Range.Contains(end) ? end : (movingBack ? endTextBlock.Range.EndIndex - 1 : endTextBlock.Range.StartIndex);
snappedStart = movingBack ? Math.Min(start, snappedStart) : Math.Max(start, snappedStart);
snappedEnd = movingBack ? Math.Min(end, snappedEnd) : Math.Max(end, snappedEnd);
// Don't snap if selection is right in the end of the text
if (start == _text.Length)
snappedStart = _text.Length;
if (end == _text.Length)
snappedEnd = _text.Length;
}
base.SetSelection(snappedStart, snappedEnd, withScroll);
}
/// <inheritdoc />
public override void DrawSelf()
{
@@ -289,8 +363,8 @@ namespace FlaxEngine.GUI
// Selection
if (hasSelection && textBlock.Style.BackgroundSelectedBrush != null && textBlock.Range.Intersect(ref selection))
{
var leftEdge = selection.StartIndex <= textBlock.Range.StartIndex ? textBlock.Bounds.UpperLeft : font.GetCharPosition(_text, selection.StartIndex);
var rightEdge = selection.EndIndex >= textBlock.Range.EndIndex ? textBlock.Bounds.UpperRight : font.GetCharPosition(_text, selection.EndIndex);
var leftEdge = selection.StartIndex <= textBlock.Range.StartIndex ? textBlock.Bounds.UpperLeft : GetCharPosition(selection.StartIndex, out _);
var rightEdge = selection.EndIndex >= textBlock.Range.EndIndex ? textBlock.Bounds.UpperRight : GetCharPosition(selection.EndIndex, out _);
float height = font.Height;
float alpha = Mathf.Min(1.0f, Mathf.Cos(_animateTime * BackgroundSelectedFlashSpeed) * 0.5f + 1.3f);
alpha *= alpha;

View File

@@ -397,6 +397,7 @@ namespace MF
// Loop
playerMF.Time.Ticks %= player.Duration.Ticks;
playerMF.Seek = 1;
player.PlayAudio();
}
else
{

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -37,7 +37,6 @@ public class assimp : DepsModule
case TargetPlatform.Linux:
case TargetPlatform.Mac:
options.OutputFiles.Add(Path.Combine(depsRoot, "libassimp.a"));
options.OutputFiles.Add(Path.Combine(depsRoot, "libIrrXML.a"));
break;
default: throw new InvalidPlatformException(options.Platform.Target);
}

View File

@@ -1,6 +1,6 @@
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.IO;
using Flax.Build;
@@ -122,13 +122,19 @@ namespace Flax.Deps.Dependencies
}
case TargetPlatform.Linux:
{
var envVars = new Dictionary<string, string>
{
{ "CC", "clang-13" },
{ "CC_FOR_BUILD", "clang-13" },
{ "CXX", "clang++-13" },
};
// Build for Linux
RunCmake(root, platform, TargetArchitecture.x64, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError);
RunCmake(root, platform, TargetArchitecture.x64, " -DCMAKE_BUILD_TYPE=Release -DBUILD_SHARED_LIBS=OFF " + globalConfig, envVars);
Utilities.Run("make", null, null, root, Utilities.RunOptions.ThrowExceptionOnError, envVars);
configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h");
var depsFolder = GetThirdPartyFolder(options, platform, TargetArchitecture.x64);
Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a"));
Utilities.FileCopy(Path.Combine(root, "lib", "libIrrXML.a"), Path.Combine(depsFolder, "libIrrXML.a"));
break;
}
case TargetPlatform.Mac:
@@ -141,7 +147,7 @@ namespace Flax.Deps.Dependencies
configHeaderFilePath = Path.Combine(root, "include", "assimp", "config.h");
var depsFolder = GetThirdPartyFolder(options, platform, architecture);
Utilities.FileCopy(Path.Combine(root, "lib", "libassimp.a"), Path.Combine(depsFolder, "libassimp.a"));
Utilities.FileCopy(Path.Combine(root, "lib", "libIrrXML.a"), Path.Combine(depsFolder, "libIrrXML.a"));
Utilities.Run("make", "clean", null, root, Utilities.RunOptions.ThrowExceptionOnError);
}
break;
}