Merge remote-tracking branch 'origin/master' into 1.9
This commit is contained in:
@@ -80,7 +80,7 @@ namespace FlaxEditor.Content
|
||||
// Translate asset type name
|
||||
var typeName = TypeName;
|
||||
string[] typeNamespaces = typeName.Split('.');
|
||||
if (typeNamespaces.Length != 0 && typeNamespaces.Length != 0)
|
||||
if (typeNamespaces.Length != 0 && typeNamespaces[typeNamespaces.Length - 1].Length != 0)
|
||||
{
|
||||
typeName = Utilities.Utils.GetPropertyNameUI(typeNamespaces[typeNamespaces.Length - 1]);
|
||||
}
|
||||
|
||||
@@ -208,7 +208,7 @@ namespace FlaxEditor.CustomEditors.Editors
|
||||
else
|
||||
{
|
||||
// Draw info
|
||||
Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? Color.OrangeRed : Color.DarkOrange, TextAlignment.Near, TextAlignment.Center);
|
||||
Render2D.DrawText(style.FontMedium, Type != null ? $"None ({Utilities.Utils.GetPropertyNameUI(Type.ToString())})" : "-", nameRect, isEnabled ? style.ForegroundGrey : style.ForegroundGrey.AlphaMultiplied(0.75f), TextAlignment.Near, TextAlignment.Center);
|
||||
}
|
||||
|
||||
// Draw picker button
|
||||
|
||||
@@ -22,7 +22,7 @@ namespace FlaxEditor.GUI.Dialogs
|
||||
/// <summary>
|
||||
/// The parent window.
|
||||
/// </summary>
|
||||
protected Window _window;
|
||||
protected volatile Window _window;
|
||||
|
||||
/// <summary>
|
||||
/// The dialog result.
|
||||
|
||||
@@ -89,6 +89,9 @@ namespace FlaxEditor.Surface
|
||||
|
||||
private static NodesCache _nodesCache = new NodesCache(IterateNodesCache);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseContextMenuDescriptionPanel => true;
|
||||
|
||||
/// <summary>
|
||||
/// The state machine editing context menu.
|
||||
/// </summary>
|
||||
|
||||
@@ -156,7 +156,7 @@ namespace FlaxEditor.Surface.Archetypes
|
||||
Title = "Lerp",
|
||||
Description = "Performs a linear interpolation",
|
||||
Flags = NodeFlags.AllGraphs,
|
||||
Size = new Float2(110, 60),
|
||||
Size = new Float2(150, 60),
|
||||
ConnectionsHints = ConnectionsHint.Numeric,
|
||||
IndependentBoxes = new[] { 0, 1 },
|
||||
DependentBoxes = new[] { 3 },
|
||||
|
||||
@@ -25,6 +25,9 @@ namespace FlaxEditor.Surface
|
||||
/// <inheritdoc />
|
||||
public override bool CanLivePreviewValueChanges => false;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseContextMenuDescriptionPanel => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string GetTypeName(ScriptType type)
|
||||
{
|
||||
|
||||
@@ -24,6 +24,9 @@ namespace FlaxEditor.Surface
|
||||
/// </summary>
|
||||
public FlaxEditor.Surface.Archetypes.Particles.ParticleEmitterNode RootNode => _rootNode;
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseContextMenuDescriptionPanel => true;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ParticleEmitterSurface(IVisjectSurfaceOwner owner, Action onSave, FlaxEditor.Undo undo)
|
||||
: base(owner, onSave, undo)
|
||||
|
||||
@@ -8,6 +8,7 @@ using System.Reflection;
|
||||
using System.Text;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.CustomEditors.Elements;
|
||||
using FlaxEditor.Options;
|
||||
using FlaxEditor.Scripting;
|
||||
using FlaxEditor.Utilities;
|
||||
using FlaxEngine.Utilities;
|
||||
@@ -71,7 +72,12 @@ namespace FlaxEditor.Surface
|
||||
}
|
||||
|
||||
// By name
|
||||
return string.Compare(x.DisplayName, y.DisplayName, StringComparison.InvariantCulture);
|
||||
if (Editor.Instance.Options.Options.General.ScriptMembersOrder == GeneralOptions.MembersOrder.Alphabetical)
|
||||
{
|
||||
return string.Compare(x.DisplayName, y.DisplayName, StringComparison.InvariantCulture);
|
||||
}
|
||||
// Keep same order
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -492,7 +492,7 @@ namespace FlaxEditor.Surface
|
||||
Focus();
|
||||
return true;
|
||||
}
|
||||
if (_rightMouseDown || (_middleMouseDown && _middleMouseDown))
|
||||
if (_rightMouseDown || _middleMouseDown)
|
||||
{
|
||||
// Start navigating
|
||||
StartMouseCapture();
|
||||
|
||||
@@ -197,6 +197,12 @@ namespace FlaxEditor.Tools.Foliage
|
||||
{
|
||||
PaintEnd();
|
||||
}
|
||||
|
||||
// Increase or decrease brush size with scroll
|
||||
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
|
||||
{
|
||||
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
|
||||
}
|
||||
|
||||
// Perform detailed tracing to find cursor location for the foliage placement
|
||||
var mouseRay = Owner.MouseRay;
|
||||
|
||||
@@ -113,6 +113,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
}
|
||||
|
||||
_createTerrainButton.Clicked += OnCreateNewTerrainClicked;
|
||||
OnSelectionChanged();
|
||||
}
|
||||
|
||||
private void OnSceneLoaded(Scene arg1, Guid arg2)
|
||||
@@ -159,6 +160,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
}
|
||||
|
||||
_noTerrainPanel.Visible = terrain == null;
|
||||
_modes.Visible = !_noTerrainPanel.Visible;
|
||||
}
|
||||
|
||||
private void InitSculptMode()
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
}
|
||||
|
||||
// Increase or decrease brush size with scroll
|
||||
if (Input.GetKey(KeyboardKeys.Shift))
|
||||
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
|
||||
{
|
||||
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
|
||||
}
|
||||
|
||||
@@ -159,7 +159,7 @@ namespace FlaxEditor.Tools.Terrain
|
||||
}
|
||||
|
||||
// Increase or decrease brush size with scroll
|
||||
if (Input.GetKey(KeyboardKeys.Shift))
|
||||
if (Input.GetKey(KeyboardKeys.Shift) && !Input.GetMouseButton(MouseButton.Right))
|
||||
{
|
||||
Mode.CurrentBrush.Size += dt * Mode.CurrentBrush.Size * Input.Mouse.ScrollDelta * 5f;
|
||||
}
|
||||
|
||||
@@ -79,7 +79,7 @@ namespace FlaxEditor.Utilities
|
||||
value = Convert.ToInt32(value);
|
||||
else if (type.Type == typeof(long))
|
||||
value = Convert.ToInt64(value);
|
||||
else if (type.Type == typeof(int))
|
||||
else if (type.Type == typeof(ushort))
|
||||
value = Convert.ToUInt16(value);
|
||||
else if (type.Type == typeof(uint))
|
||||
value = Convert.ToUInt32(value);
|
||||
|
||||
@@ -1612,7 +1612,7 @@ namespace FlaxEditor.Viewport
|
||||
_input.IsPanning = !isAltDown && mbDown && !rbDown;
|
||||
_input.IsRotating = !isAltDown && !mbDown && rbDown;
|
||||
_input.IsMoving = !isAltDown && mbDown && rbDown;
|
||||
_input.IsZooming = wheelInUse && !_input.IsShiftDown;
|
||||
_input.IsZooming = wheelInUse && !(_input.IsShiftDown || (!ContainsFocus && FlaxEngine.Input.GetKey(KeyboardKeys.Shift)));
|
||||
_input.IsOrbiting = isAltDown && lbDown && !mbDown && !rbDown;
|
||||
|
||||
// Control move speed with RMB+Wheel
|
||||
|
||||
@@ -12,6 +12,7 @@ using FlaxEditor.Viewport.Previews;
|
||||
using FlaxEditor.Windows.Assets;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
using Utils = FlaxEditor.Utilities.Utils;
|
||||
|
||||
namespace FlaxEditor.Viewport
|
||||
{
|
||||
@@ -62,6 +63,7 @@ namespace FlaxEditor.Viewport
|
||||
private UpdateDelegate _update;
|
||||
|
||||
private readonly ViewportDebugDrawData _debugDrawData = new ViewportDebugDrawData(32);
|
||||
private readonly List<Actor> _debugDrawActors = new List<Actor>();
|
||||
private PrefabSpritesRenderer _spritesRenderer;
|
||||
private IntPtr _tempDebugDrawContext;
|
||||
|
||||
@@ -623,14 +625,44 @@ namespace FlaxEditor.Viewport
|
||||
DebugDraw.DrawActors(new IntPtr(actors), _debugDrawData.ActorsCount, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Debug draw all actors in prefab
|
||||
|
||||
// Debug draw all actors in prefab and collect actors
|
||||
var viewFlags = Task.ViewFlags;
|
||||
var collectActors = (viewFlags & ViewFlags.PhysicsDebug) != 0 || (viewFlags & ViewFlags.LightsDebug) != 0;
|
||||
_debugDrawActors.Clear();
|
||||
foreach (var child in SceneGraphRoot.ChildNodes)
|
||||
{
|
||||
if (child is not ActorNode actorNode || !actorNode.Actor)
|
||||
continue;
|
||||
DebugDraw.DrawActorsTree(actorNode.Actor);
|
||||
var actor = actorNode.Actor;
|
||||
if (collectActors)
|
||||
Utils.GetActorsTree(_debugDrawActors, actor);
|
||||
DebugDraw.DrawActorsTree(actor);
|
||||
}
|
||||
|
||||
// Draw physics debug
|
||||
if ((viewFlags & ViewFlags.PhysicsDebug) != 0)
|
||||
{
|
||||
foreach (var actor in _debugDrawActors)
|
||||
{
|
||||
if (actor is Collider c && c.IsActiveInHierarchy)
|
||||
{
|
||||
DebugDraw.DrawColliderDebugPhysics(c, renderContext.View);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Draw lights debug
|
||||
if ((viewFlags & ViewFlags.LightsDebug) != 0)
|
||||
{
|
||||
foreach (var actor in _debugDrawActors)
|
||||
{
|
||||
if (actor is Light l && l.IsActiveInHierarchy)
|
||||
DebugDraw.DrawLightDebug(l, renderContext.View);
|
||||
}
|
||||
}
|
||||
|
||||
_debugDrawActors.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Xml;
|
||||
using FlaxEditor.CustomEditors;
|
||||
using FlaxEditor.SceneGraph;
|
||||
using FlaxEditor.Viewport;
|
||||
using FlaxEngine;
|
||||
using FlaxEngine.GUI;
|
||||
|
||||
namespace FlaxEditor.Windows
|
||||
@@ -19,6 +21,8 @@ namespace FlaxEditor.Windows
|
||||
{
|
||||
private IEnumerable<object> undoRecordObjects;
|
||||
|
||||
private readonly Dictionary<Guid, float> _actorScrollValues = new Dictionary<Guid, float>();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override bool UseLayoutData => true;
|
||||
|
||||
@@ -57,9 +61,42 @@ namespace FlaxEditor.Windows
|
||||
Presenter.GetUndoObjects += GetUndoObjects;
|
||||
Presenter.Features |= FeatureFlags.CacheExpandedGroups;
|
||||
|
||||
VScrollBar.ValueChanged += OnScrollValueChanged;
|
||||
Editor.SceneEditing.SelectionChanged += OnSelectionChanged;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override void OnSceneLoaded(Scene scene, Guid sceneId)
|
||||
{
|
||||
base.OnSceneLoaded(scene, sceneId);
|
||||
|
||||
// Clear scroll values if new scene is loaded non additively
|
||||
if (Level.ScenesCount > 1)
|
||||
return;
|
||||
_actorScrollValues.Clear();
|
||||
}
|
||||
|
||||
private void OnScrollValueChanged()
|
||||
{
|
||||
if (Editor.SceneEditing.SelectionCount > 1)
|
||||
return;
|
||||
|
||||
// Clear first 10 scroll values to keep the memory down. Dont need to cache very single value in a scene. We could expose this as a editor setting in the future.
|
||||
if (_actorScrollValues.Count >= 20)
|
||||
{
|
||||
int i = 0;
|
||||
foreach (var e in _actorScrollValues)
|
||||
{
|
||||
if (i >= 10)
|
||||
break;
|
||||
_actorScrollValues.Remove(e.Key);
|
||||
i += 1;
|
||||
}
|
||||
}
|
||||
|
||||
_actorScrollValues[Editor.SceneEditing.Selection[0].ID] = VScrollBar.TargetValue;
|
||||
}
|
||||
|
||||
private IEnumerable<object> GetUndoObjects(CustomEditorPresenter customEditorPresenter)
|
||||
{
|
||||
return undoRecordObjects;
|
||||
@@ -75,6 +112,10 @@ namespace FlaxEditor.Windows
|
||||
undoRecordObjects = Editor.SceneEditing.Selection.ConvertAll(x => x.UndoRecordObject).Distinct();
|
||||
var objects = Editor.SceneEditing.Selection.ConvertAll(x => x.EditableObject).Distinct();
|
||||
Presenter.Select(objects);
|
||||
|
||||
// Set scroll value of window if it exists
|
||||
if (Editor.SceneEditing.SelectionCount == 1)
|
||||
VScrollBar.TargetValue = _actorScrollValues.GetValueOrDefault(Editor.SceneEditing.Selection[0].ID, 0);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -2237,8 +2237,9 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
{
|
||||
// Start playing animation
|
||||
bucket.Index = i;
|
||||
bucket.TimePosition = 0.0f;
|
||||
bucket.BlendInPosition = 0.0f;
|
||||
// Keep bucket time position and blend in time for if blending between two anims in the same slot.
|
||||
bucket.TimePosition = bucket.TimePosition;
|
||||
bucket.BlendInPosition = bucket.BlendInPosition;
|
||||
bucket.BlendOutPosition = 0.0f;
|
||||
bucket.LoopsDone = 0;
|
||||
bucket.LoopsLeft = slot.LoopCount;
|
||||
@@ -2248,6 +2249,12 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
if (bucket.Index == -1 || !slots[bucket.Index].Animation->IsLoaded())
|
||||
{
|
||||
value = tryGetValue(node->GetBox(1), Value::Null);
|
||||
// Reset times if time is left over from playing between different anims in the same slot.
|
||||
if (bucket.BlendInPosition > 0)
|
||||
{
|
||||
bucket.TimePosition = 0;
|
||||
bucket.BlendInPosition = 0;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2256,12 +2263,6 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
auto& slot = slots[bucket.Index];
|
||||
Animation* anim = slot.Animation;
|
||||
ASSERT(slot.Animation && slot.Animation->IsLoaded());
|
||||
if (slot.Reset)
|
||||
{
|
||||
// Start from the begining
|
||||
slot.Reset = false;
|
||||
bucket.TimePosition = 0.0f;
|
||||
}
|
||||
const float deltaTime = slot.Pause ? 0.0f : context.DeltaTime * slot.Speed;
|
||||
const float length = anim->GetLength();
|
||||
const bool loop = bucket.LoopsLeft != 0;
|
||||
@@ -2285,6 +2286,57 @@ void AnimGraphExecutor::ProcessGroupAnimation(Box* boxBase, Node* nodeBase, Valu
|
||||
// Speed is accounted for in the new time pos, so keep sample speed at 1
|
||||
value = SampleAnimation(node, loop, length, 0.0f, bucket.TimePosition, newTimePos, anim, 1);
|
||||
bucket.TimePosition = newTimePos;
|
||||
|
||||
// On animation slot stop
|
||||
if (slot.Reset)
|
||||
{
|
||||
// Blend between last anim and new anim if found, otherwise blend back to input.
|
||||
Animation* sAnim = nullptr;
|
||||
for (int32 i = 0; i < slots.Count(); i++)
|
||||
{
|
||||
if (bucket.Index == i)
|
||||
continue;
|
||||
|
||||
auto& s = slots[i];
|
||||
if (s.Animation && s.Name == slotName)
|
||||
{
|
||||
sAnim = s.Animation;
|
||||
}
|
||||
}
|
||||
float oldTimePos = bucket.BlendOutPosition;
|
||||
bucket.BlendOutPosition += deltaTime;
|
||||
bucket.BlendInPosition = bucket.BlendOutPosition;
|
||||
const float alpha = bucket.BlendOutPosition / slot.BlendOutTime;
|
||||
if (sAnim != nullptr)
|
||||
{
|
||||
auto sValue = SampleAnimation(node, false, sAnim->GetLength(), 0.0f, oldTimePos, bucket.BlendInPosition, sAnim, 1);
|
||||
//value = SampleAnimationsWithBlend(node, false, length, 0.0f, bucket.TimePosition, newTimePos, anim, sAnim, 1, 1, alpha);
|
||||
value = Blend(node, value, sValue, alpha, AlphaBlendMode::HermiteCubic);
|
||||
}
|
||||
else
|
||||
{
|
||||
auto input = tryGetValue(node->GetBox(1), Value::Null);
|
||||
value = Blend(node, value, input, alpha, AlphaBlendMode::HermiteCubic);
|
||||
}
|
||||
|
||||
if (bucket.BlendOutPosition >= slot.BlendOutTime)
|
||||
{
|
||||
// Start from the beginning or the blend in position if next anim found.
|
||||
slot.Animation = nullptr;
|
||||
slot.Reset = false;
|
||||
if (!sAnim)
|
||||
{
|
||||
bucket.TimePosition = 0;
|
||||
bucket.BlendInPosition = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bucket.TimePosition = bucket.BlendInPosition;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (bucket.LoopsLeft == 0 && slot.BlendOutTime > 0.0f && length - slot.BlendOutTime < bucket.TimePosition)
|
||||
{
|
||||
// Blend out
|
||||
|
||||
@@ -196,6 +196,7 @@ bool AudioService::Init()
|
||||
|
||||
LOG(Info, "Audio system initialization... (backend: {0})", AudioBackend::Name());
|
||||
|
||||
EnableHRTF = settings->EnableHRTF;
|
||||
if (AudioBackend::Init())
|
||||
{
|
||||
LOG(Warning, "Failed to initialize audio backend.");
|
||||
|
||||
@@ -313,6 +313,7 @@ void AudioSource::PlayInternal()
|
||||
{
|
||||
AudioBackend::Source::Play(SourceID);
|
||||
_isActuallyPlayingSth = true;
|
||||
_startingToPlay = true;
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
@@ -394,6 +395,30 @@ void AudioSource::Update()
|
||||
AudioBackend::Source::VelocityChanged(SourceID, _velocity);
|
||||
}
|
||||
|
||||
// Reset starting to play value once time is greater than zero
|
||||
if (_startingToPlay && GetTime() > 0.0f)
|
||||
{
|
||||
_startingToPlay = false;
|
||||
}
|
||||
|
||||
if (!UseStreaming() && Math::NearEqual(GetTime(), 0.0f) && _isActuallyPlayingSth && !_startingToPlay)
|
||||
{
|
||||
int32 queuedBuffers;
|
||||
AudioBackend::Source::GetQueuedBuffersCount(this, queuedBuffers);
|
||||
if (queuedBuffers)
|
||||
{
|
||||
if (GetIsLooping())
|
||||
{
|
||||
Stop();
|
||||
Play();
|
||||
}
|
||||
else
|
||||
{
|
||||
Stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Skip other update logic if it's not valid streamable source
|
||||
if (!UseStreaming() || SourceID == 0)
|
||||
return;
|
||||
|
||||
@@ -56,6 +56,7 @@ private:
|
||||
bool _allowSpatialization;
|
||||
|
||||
bool _isActuallyPlayingSth = false;
|
||||
bool _startingToPlay = false;
|
||||
bool _needToUpdateStreamingBuffers = false;
|
||||
States _state = States::Stopped;
|
||||
|
||||
|
||||
@@ -662,13 +662,13 @@ bool FlaxStorage::LoadAssetChunk(FlaxChunk* chunk)
|
||||
if (!failed)
|
||||
{
|
||||
stream->SetPosition(chunk->LocationInFile.Address);
|
||||
if (!stream->HasError())
|
||||
break;
|
||||
}
|
||||
if (!stream->HasError())
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (stream->HasError())
|
||||
if (!stream || stream->HasError())
|
||||
{
|
||||
failed = true;
|
||||
UnlockChunks();
|
||||
|
||||
@@ -94,8 +94,8 @@ namespace FlaxEngine
|
||||
throw new ArgumentOutOfRangeException(nameof(values), "There must be sixteen and only four input values for Matrix2x2.");
|
||||
M11 = values[0];
|
||||
M12 = values[1];
|
||||
M21 = values[3];
|
||||
M22 = values[4];
|
||||
M21 = values[2];
|
||||
M22 = values[3];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -289,7 +289,7 @@ void Quaternion::Billboard(const Float3& objectPosition, const Float3& cameraPos
|
||||
|
||||
Quaternion Quaternion::FromDirection(const Float3& direction)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), Quaternion::Identity);
|
||||
Quaternion orientation;
|
||||
if (Float3::Dot(direction, Float3::Up) >= 0.999f)
|
||||
{
|
||||
|
||||
@@ -57,6 +57,7 @@ using Real = System.Single;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Runtime.CompilerServices;
|
||||
using FlaxEngine.Assertions;
|
||||
|
||||
namespace FlaxEngine
|
||||
{
|
||||
@@ -77,6 +78,7 @@ namespace FlaxEngine
|
||||
{
|
||||
Position = position;
|
||||
Direction = direction;
|
||||
Assert.IsTrue(Direction.IsNormalized, "The Ray Direction was not normalized");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -46,7 +46,7 @@ public:
|
||||
: Position(position)
|
||||
, Direction(direction)
|
||||
{
|
||||
ASSERT(Direction.IsNormalized());
|
||||
CHECK_DEBUG(Direction.IsNormalized());
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
@@ -324,15 +324,14 @@ public:
|
||||
{
|
||||
if (length <= 0)
|
||||
return;
|
||||
if (Base::Length() == 0)
|
||||
auto prev = Base::_data;
|
||||
const auto prevLength = Base::_length;
|
||||
if (prevLength == 0 || prev == nullptr)
|
||||
{
|
||||
Copy(data, length);
|
||||
return;
|
||||
}
|
||||
|
||||
auto prev = Base::_data;
|
||||
const auto prevLength = Base::_length;
|
||||
|
||||
Base::_length = prevLength + length;
|
||||
Base::_data = (T*)Allocator::Allocate(Base::_length * sizeof(T));
|
||||
|
||||
|
||||
@@ -2702,8 +2702,8 @@ void Variant::SetAsset(Asset* asset)
|
||||
SetType(VariantType(VariantType::Asset));
|
||||
if (AsAsset)
|
||||
{
|
||||
asset->OnUnloaded.Unbind<Variant, &Variant::OnAssetUnloaded>(this);
|
||||
asset->RemoveReference();
|
||||
AsAsset->OnUnloaded.Unbind<Variant, &Variant::OnAssetUnloaded>(this);
|
||||
AsAsset->RemoveReference();
|
||||
}
|
||||
AsAsset = asset;
|
||||
if (asset)
|
||||
|
||||
@@ -27,6 +27,8 @@
|
||||
#include "Engine/Render2D/FontAsset.h"
|
||||
#if USE_EDITOR
|
||||
#include "Editor/Editor.h"
|
||||
#include "Engine/Level/Actors/Light.h"
|
||||
#include "Engine/Physics/Colliders/Collider.h"
|
||||
#endif
|
||||
|
||||
// Debug draw service configuration
|
||||
@@ -950,9 +952,26 @@ void DebugDraw::DrawActorsTree(Actor* actor)
|
||||
actor->TreeExecute(function);
|
||||
}
|
||||
|
||||
#if USE_EDITOR
|
||||
void DebugDraw::DrawColliderDebugPhysics(Collider* collider, RenderView& view)
|
||||
{
|
||||
if (!collider)
|
||||
return;
|
||||
|
||||
collider->DrawPhysicsDebug(view);
|
||||
}
|
||||
|
||||
void DebugDraw::DrawLightDebug(Light* light, RenderView& view)
|
||||
{
|
||||
if (!light)
|
||||
return;
|
||||
|
||||
light->DrawLightsDebug(view);
|
||||
}
|
||||
#endif
|
||||
void DebugDraw::DrawAxisFromDirection(const Vector3& origin, const Vector3& direction, float size, float duration, bool depthTest)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_DEBUG(direction.IsNormalized());
|
||||
const auto rot = Quaternion::FromDirection(direction);
|
||||
const Vector3 up = (rot * Vector3::Up);
|
||||
const Vector3 forward = (rot * Vector3::Forward);
|
||||
@@ -978,7 +997,7 @@ void DebugDraw::DrawRay(const Vector3& origin, const Vector3& direction, const C
|
||||
|
||||
void DebugDraw::DrawRay(const Vector3& origin, const Vector3& direction, const Color& color, float length, float duration, bool depthTest)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_DEBUG(direction.IsNormalized());
|
||||
if (isnan(length) || isinf(length))
|
||||
return;
|
||||
DrawLine(origin, origin + (direction * length), color, duration, depthTest);
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
#include "Engine/Core/Math/Color.h"
|
||||
#include "Engine/Core/Types/Span.h"
|
||||
|
||||
struct RenderView;
|
||||
class Collider;
|
||||
class Light;
|
||||
struct RenderContext;
|
||||
class GPUTextureView;
|
||||
class GPUContext;
|
||||
@@ -70,9 +73,23 @@ API_CLASS(Static) class FLAXENGINE_API DebugDraw
|
||||
/// <summary>
|
||||
/// Draws the debug shapes for the given actor and the actor's children
|
||||
/// </summary>
|
||||
/// /// <param name="actor">The actor to start drawing at.</param>
|
||||
/// <param name="actor">The actor to start drawing at.</param>
|
||||
API_FUNCTION() static void DrawActorsTree(Actor* actor);
|
||||
#if USE_EDITOR
|
||||
/// <summary>
|
||||
/// Draws the physics debug shapes for the given collider. Editor Only
|
||||
/// </summary>
|
||||
/// <param name="collider">The collider to draw.</param>
|
||||
/// <param name="view">The render view to draw in.</param>
|
||||
API_FUNCTION() static void DrawColliderDebugPhysics(Collider* collider, RenderView& view);
|
||||
|
||||
/// <summary>
|
||||
/// Draws the light debug shapes for the given light. Editor Only
|
||||
/// </summary>
|
||||
/// <param name="light">The light debug to draw.</param>
|
||||
/// <param name="view">The render view to draw in.</param>
|
||||
API_FUNCTION() static void DrawLightDebug(Light* light, RenderView& view);
|
||||
#endif
|
||||
/// <summary>
|
||||
/// Draws the lines axis from direction.
|
||||
/// </summary>
|
||||
|
||||
@@ -199,6 +199,7 @@ void GameBaseImpl::OnMainWindowClosed()
|
||||
|
||||
// Request engine exit
|
||||
Globals::IsRequestingExit = true;
|
||||
Engine::RequestingExit();
|
||||
}
|
||||
|
||||
void GameBaseImpl::OnPostRender(GPUContext* context, RenderContext& renderContext)
|
||||
|
||||
@@ -70,6 +70,7 @@ Action Engine::LateFixedUpdate;
|
||||
Action Engine::Draw;
|
||||
Action Engine::Pause;
|
||||
Action Engine::Unpause;
|
||||
Action Engine::RequestingExit;
|
||||
Window* Engine::MainWindow = nullptr;
|
||||
|
||||
int32 Engine::Main(const Char* cmdLine)
|
||||
@@ -259,10 +260,12 @@ void Engine::RequestExit(int32 exitCode)
|
||||
{
|
||||
Globals::IsRequestingExit = true;
|
||||
Globals::ExitCode = exitCode;
|
||||
RequestingExit();
|
||||
}
|
||||
#else
|
||||
Globals::IsRequestingExit = true;
|
||||
Globals::ExitCode = exitCode;
|
||||
RequestingExit();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -79,6 +79,11 @@ public:
|
||||
/// </summary>
|
||||
static Action Unpause;
|
||||
|
||||
/// <summary>
|
||||
/// Event called when the engine is requesting exit.
|
||||
/// </summary>
|
||||
API_EVENT() static Action RequestingExit;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -59,9 +59,19 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(Globals);
|
||||
// True if fatal error occurred (engine is exiting)
|
||||
static bool FatalErrorOccurred;
|
||||
|
||||
// True if engine need to be closed
|
||||
// True if engine needs to be closed
|
||||
static bool IsRequestingExit;
|
||||
|
||||
/// <summary>
|
||||
/// True if engine needs to be closed
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE static bool GetIsRequestingExit() { return IsRequestingExit; }
|
||||
|
||||
/// <summary>
|
||||
/// True if fatal error occurred (engine is exiting)
|
||||
/// </summary>
|
||||
API_PROPERTY() FORCE_INLINE static bool GetFatalErrorOccurred() { return FatalErrorOccurred; }
|
||||
|
||||
// Exit code
|
||||
static int32 ExitCode;
|
||||
|
||||
|
||||
@@ -996,37 +996,37 @@ public:
|
||||
/// <summary>
|
||||
/// Called when actor parent gets changed.
|
||||
/// </summary>
|
||||
virtual void OnParentChanged();
|
||||
API_FUNCTION() virtual void OnParentChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when actor transform gets changed.
|
||||
/// </summary>
|
||||
virtual void OnTransformChanged();
|
||||
API_FUNCTION() virtual void OnTransformChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when actor active state gets changed.
|
||||
/// </summary>
|
||||
virtual void OnActiveChanged();
|
||||
API_FUNCTION() virtual void OnActiveChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when actor active in tree state gets changed.
|
||||
/// </summary>
|
||||
virtual void OnActiveInTreeChanged();
|
||||
API_FUNCTION() virtual void OnActiveInTreeChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when order in parent children array gets changed.
|
||||
/// </summary>
|
||||
virtual void OnOrderInParentChanged();
|
||||
API_FUNCTION() virtual void OnOrderInParentChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when actor static flag gets changed.
|
||||
/// </summary>
|
||||
virtual void OnStaticFlagsChanged();
|
||||
API_FUNCTION() virtual void OnStaticFlagsChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when layer gets changed.
|
||||
/// </summary>
|
||||
virtual void OnLayerChanged();
|
||||
API_FUNCTION() virtual void OnLayerChanged();
|
||||
|
||||
/// <summary>
|
||||
/// Called when adding object to the game.
|
||||
|
||||
@@ -506,7 +506,7 @@ void AnimatedModel::StopSlotAnimation(const StringView& slotName, Animation* ani
|
||||
{
|
||||
if (slot.Animation == anim && slot.Name == slotName)
|
||||
{
|
||||
slot.Animation = nullptr;
|
||||
//slot.Animation = nullptr; // TODO: make an immediate version of this method and set the animation to nullptr.
|
||||
slot.Reset = true;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ void Collider::SetContactOffset(float value)
|
||||
|
||||
bool Collider::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
resultHitDistance = MAX_float;
|
||||
if (_shape == nullptr)
|
||||
return false;
|
||||
@@ -80,7 +80,7 @@ bool Collider::RayCast(const Vector3& origin, const Vector3& direction, float& r
|
||||
|
||||
bool Collider::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
if (_shape == nullptr)
|
||||
return false;
|
||||
return PhysicsBackend::RayCastShape(_shape, _transform.Translation, _transform.Orientation, origin, direction, hitInfo, maxDistance);
|
||||
|
||||
@@ -154,10 +154,6 @@ protected:
|
||||
/// </summary>
|
||||
void RemoveStaticActor();
|
||||
|
||||
#if USE_EDITOR
|
||||
virtual void DrawPhysicsDebug(RenderView& view);
|
||||
#endif
|
||||
|
||||
private:
|
||||
void OnMaterialChanged();
|
||||
|
||||
@@ -169,6 +165,10 @@ public:
|
||||
void ClosestPoint(const Vector3& point, Vector3& result) const final;
|
||||
bool ContainsPoint(const Vector3& point) const final;
|
||||
|
||||
#if USE_EDITOR
|
||||
virtual void DrawPhysicsDebug(RenderView& view);
|
||||
#endif
|
||||
|
||||
protected:
|
||||
// [PhysicsColliderActor]
|
||||
void OnEnable() override;
|
||||
|
||||
@@ -235,91 +235,91 @@ bool Physics::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCas
|
||||
|
||||
bool Physics::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->RayCast(origin, direction, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->RayCast(origin, direction, hitInfo, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::RayCastAll(const Vector3& origin, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->RayCastAll(origin, direction, results, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->BoxCast(center, halfExtents, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->BoxCast(center, halfExtents, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::BoxCastAll(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->BoxCastAll(center, halfExtents, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::SphereCast(const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->SphereCast(center, radius, direction, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::SphereCast(const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->SphereCast(center, radius, direction, hitInfo, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::SphereCastAll(const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->SphereCastAll(center, radius, direction, results, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->CapsuleCast(center, radius, height, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->CapsuleCast(center, radius, height, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->CapsuleCastAll(center, radius, height, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->ConvexCast(center, convexMesh, scale, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->ConvexCast(center, convexMesh, scale, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return DefaultScene->ConvexCastAll(center, convexMesh, scale, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
@@ -520,91 +520,91 @@ bool PhysicsScene::LineCastAll(const Vector3& start, const Vector3& end, Array<R
|
||||
|
||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::RayCast(_scene, origin, direction, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::RayCast(_scene, origin, direction, hitInfo, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCastAll(const Vector3& origin, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::RayCastAll(_scene, origin, direction, results, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::BoxCast(_scene, center, halfExtents, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCast(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::BoxCast(_scene, center, halfExtents, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::BoxCastAll(const Vector3& center, const Vector3& halfExtents, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::BoxCastAll(_scene, center, halfExtents, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::SphereCast(_scene, center, radius, direction, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCast(const Vector3& center, const float radius, const Vector3& direction, RayCastHit& hitInfo, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::SphereCast(_scene, center, radius, direction, hitInfo, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::SphereCastAll(const Vector3& center, const float radius, const Vector3& direction, Array<RayCastHit>& results, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::SphereCastAll(_scene, center, radius, direction, results, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::CapsuleCast(_scene, center, radius, height, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCast(const Vector3& center, const float radius, const float height, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::CapsuleCast(_scene, center, radius, height, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::CapsuleCastAll(const Vector3& center, const float radius, const float height, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::CapsuleCastAll(_scene, center, radius, height, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::ConvexCast(_scene, center, convexMesh, scale, direction, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCast(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, RayCastHit& hitInfo, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::ConvexCast(_scene, center, convexMesh, scale, direction, hitInfo, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::ConvexCastAll(const Vector3& center, const CollisionData* convexMesh, const Vector3& scale, const Vector3& direction, Array<RayCastHit>& results, const Quaternion& rotation, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
return PhysicsBackend::ConvexCastAll(_scene, center, convexMesh, scale, direction, results, rotation, maxDistance, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
|
||||
@@ -271,6 +271,7 @@ void PlatformBase::Fatal(const Char* msg, void* context)
|
||||
Globals::FatalErrorOccurred = true;
|
||||
Globals::IsRequestingExit = true;
|
||||
Globals::ExitCode = -1;
|
||||
Engine::RequestingExit();
|
||||
|
||||
// Collect crash info (platform-dependant implementation that might collect stack trace and/or create memory dump)
|
||||
{
|
||||
|
||||
@@ -35,7 +35,7 @@
|
||||
#endif
|
||||
|
||||
#if ENABLE_ASSERTION
|
||||
// Performs hard assertion of the expression. Crashes the engine and inserts debugger break in case of expression fail.
|
||||
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
|
||||
#define ASSERT(expression) \
|
||||
if (!(expression)) \
|
||||
{ \
|
||||
@@ -46,24 +46,40 @@
|
||||
Platform::Assert(#expression, __FILE__, __LINE__); \
|
||||
}
|
||||
#else
|
||||
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
|
||||
#define ASSERT(expression) ((void)0)
|
||||
#endif
|
||||
#if ENABLE_ASSERTION_LOW_LAYERS
|
||||
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
|
||||
#define ASSERT_LOW_LAYER(x) ASSERT(x)
|
||||
#else
|
||||
// Performs a hard assertion of the expression. Crashes the engine and triggers a debugger break if the expression fails.
|
||||
#define ASSERT_LOW_LAYER(x)
|
||||
#endif
|
||||
|
||||
// Performs soft check of the expression. Logs the expression fail to log and returns the function call.
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
|
||||
#define CHECK(expression) \
|
||||
if (!(expression)) \
|
||||
{ \
|
||||
Platform::CheckFailed(#expression, __FILE__, __LINE__); \
|
||||
return; \
|
||||
}
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
|
||||
#define CHECK_RETURN(expression, returnValue) \
|
||||
if (!(expression)) \
|
||||
{ \
|
||||
Platform::CheckFailed(#expression, __FILE__, __LINE__); \
|
||||
return returnValue; \
|
||||
}
|
||||
|
||||
#if ENABLE_ASSERTION
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
|
||||
#define CHECK_DEBUG(expression) CHECK(expression)
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
|
||||
#define CHECK_RETURN_DEBUG(expression, returnValue) CHECK_RETURN(expression, returnValue)
|
||||
#else
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call.
|
||||
#define CHECK_DEBUG(expression) ((void)0)
|
||||
// Performs a soft check of the expression. Logs the expression failure and returns from the function call using the given return value.
|
||||
#define CHECK_RETURN_DEBUG(expression, returnValue) ((void)0)
|
||||
#endif
|
||||
|
||||
@@ -130,7 +130,7 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance. Default value is 0.75.
|
||||
/// Gets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(70), DefaultValue(0.6f), Limit(0, 5, 0.01f), EditorDisplay(\"Terrain\", \"LOD Distribution\")")
|
||||
FORCE_INLINE float GetLODDistribution() const
|
||||
@@ -139,7 +139,7 @@ public:
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance. Default value is 0.75.
|
||||
/// Sets the terrain LODs distribution parameter. Adjusts terrain chunks transitions distances. Use lower value to increase terrain quality or higher value to increase performance.
|
||||
/// </summary>
|
||||
API_PROPERTY() void SetLODDistribution(float value);
|
||||
|
||||
|
||||
@@ -1963,7 +1963,7 @@ bool TerrainPatch::UpdateCollision()
|
||||
|
||||
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
if (_physicsShape == nullptr)
|
||||
return false;
|
||||
Vector3 shapePos;
|
||||
@@ -1974,7 +1974,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
|
||||
|
||||
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, Vector3& resultHitNormal, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
if (_physicsShape == nullptr)
|
||||
return false;
|
||||
Vector3 shapePos;
|
||||
@@ -1992,7 +1992,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
|
||||
|
||||
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, float& resultHitDistance, TerrainChunk*& resultChunk, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
if (_physicsShape == nullptr)
|
||||
return false;
|
||||
Vector3 shapePos;
|
||||
@@ -2030,7 +2030,7 @@ bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, floa
|
||||
|
||||
bool TerrainPatch::RayCast(const Vector3& origin, const Vector3& direction, RayCastHit& hitInfo, float maxDistance) const
|
||||
{
|
||||
ASSERT(direction.IsNormalized());
|
||||
CHECK_RETURN_DEBUG(direction.IsNormalized(), false);
|
||||
if (_physicsShape == nullptr)
|
||||
return false;
|
||||
Vector3 shapePos;
|
||||
|
||||
@@ -77,7 +77,7 @@ namespace FlaxEngine.GUI
|
||||
/// </summary>
|
||||
public void Hide()
|
||||
{
|
||||
_window.Show();
|
||||
_window.Hide();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -17,7 +17,7 @@ MMethod* UICanvas_PostDeserialize = nullptr;
|
||||
MMethod* UICanvas_Enable = nullptr;
|
||||
MMethod* UICanvas_Disable = nullptr;
|
||||
#if USE_EDITOR
|
||||
MMethod* UICanvas_OnActiveInTreeChanged = nullptr;
|
||||
MMethod* UICanvas_ActiveInTreeChanged = nullptr;
|
||||
#endif
|
||||
MMethod* UICanvas_EndPlay = nullptr;
|
||||
MMethod* UICanvas_ParentChanged = nullptr;
|
||||
@@ -49,7 +49,7 @@ UICanvas::UICanvas(const SpawnParams& params)
|
||||
UICanvas_Enable = mclass->GetMethod("Enable");
|
||||
UICanvas_Disable = mclass->GetMethod("Disable");
|
||||
#if USE_EDITOR
|
||||
UICanvas_OnActiveInTreeChanged = mclass->GetMethod("OnActiveInTreeChanged");
|
||||
UICanvas_ActiveInTreeChanged = mclass->GetMethod("ActiveInTreeChanged");
|
||||
#endif
|
||||
UICanvas_EndPlay = mclass->GetMethod("EndPlay");
|
||||
UICanvas_ParentChanged = mclass->GetMethod("ParentChanged");
|
||||
@@ -182,7 +182,7 @@ void UICanvas::OnTransformChanged()
|
||||
|
||||
void UICanvas::OnActiveInTreeChanged()
|
||||
{
|
||||
UICANVAS_INVOKE(OnActiveInTreeChanged);
|
||||
UICANVAS_INVOKE(ActiveInTreeChanged);
|
||||
|
||||
// Base
|
||||
Actor::OnActiveInTreeChanged();
|
||||
|
||||
@@ -777,7 +777,7 @@ namespace FlaxEngine
|
||||
}
|
||||
|
||||
#if FLAX_EDITOR
|
||||
internal void OnActiveInTreeChanged()
|
||||
internal void ActiveInTreeChanged()
|
||||
{
|
||||
if (RenderMode == CanvasRenderMode.ScreenSpace && _editorRoot != null && _guiRoot != null)
|
||||
{
|
||||
|
||||
@@ -156,6 +156,7 @@ namespace Flax.Build.Bindings
|
||||
// Numbers
|
||||
if (float.TryParse(value, out _) || (value[value.Length - 1] == 'f' && float.TryParse(value.Substring(0, value.Length - 1), out _)))
|
||||
{
|
||||
value = value.Replace(".f", ".0f");
|
||||
// If the value type is different than the value (eg. value is int but the field is float) then cast it for the [DefaultValue] attribute
|
||||
if (valueType != null && attribute)
|
||||
return $"({GenerateCSharpNativeToManaged(buildData, valueType, caller)}){value}";
|
||||
@@ -179,7 +180,7 @@ namespace Flax.Build.Bindings
|
||||
foreach (var vectorType in CSharpVectorTypes)
|
||||
{
|
||||
if (value.Length > vectorType.Length + 4 && value.StartsWith(vectorType) && value[vectorType.Length] == '(')
|
||||
return $"typeof({vectorType}), \"{value.Substring(vectorType.Length + 1, value.Length - vectorType.Length - 2).Replace("f", "")}\"";
|
||||
return $"typeof({vectorType}), \"{value.Substring(vectorType.Length + 1, value.Length - vectorType.Length - 2).Replace(".f", ".0").Replace("f", "")}\"";
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
Reference in New Issue
Block a user