Merge remote-tracking branch 'origin/master' into 1.6
This commit is contained in:
@@ -85,18 +85,18 @@ Keyboard* Input::Keyboard = nullptr;
|
||||
Array<Gamepad*, FixedAllocation<MAX_GAMEPADS>> Input::Gamepads;
|
||||
Action Input::GamepadsChanged;
|
||||
Array<InputDevice*, InlinedAllocation<16>> Input::CustomDevices;
|
||||
Input::CharDelegate Input::CharInput;
|
||||
Input::KeyboardDelegate Input::KeyDown;
|
||||
Input::KeyboardDelegate Input::KeyUp;
|
||||
Input::MouseButtonDelegate Input::MouseDown;
|
||||
Input::MouseButtonDelegate Input::MouseUp;
|
||||
Input::MouseButtonDelegate Input::MouseDoubleClick;
|
||||
Input::MouseWheelDelegate Input::MouseWheel;
|
||||
Input::MouseDelegate Input::MouseMove;
|
||||
Delegate<Char> Input::CharInput;
|
||||
Delegate<KeyboardKeys> Input::KeyDown;
|
||||
Delegate<KeyboardKeys> Input::KeyUp;
|
||||
Delegate<const Float2&, MouseButton> Input::MouseDown;
|
||||
Delegate<const Float2&, MouseButton> Input::MouseUp;
|
||||
Delegate<const Float2&, MouseButton> Input::MouseDoubleClick;
|
||||
Delegate<const Float2&, float> Input::MouseWheel;
|
||||
Delegate<const Float2&> Input::MouseMove;
|
||||
Action Input::MouseLeave;
|
||||
Input::TouchDelegate Input::TouchDown;
|
||||
Input::TouchDelegate Input::TouchMove;
|
||||
Input::TouchDelegate Input::TouchUp;
|
||||
Delegate<const Float2&, int32> Input::TouchDown;
|
||||
Delegate<const Float2&, int32> Input::TouchMove;
|
||||
Delegate<const Float2&, int32> Input::TouchUp;
|
||||
Delegate<StringView> Input::ActionTriggered;
|
||||
Array<ActionConfig> Input::ActionMappings;
|
||||
Array<AxisConfig> Input::AxisMappings;
|
||||
|
||||
@@ -66,72 +66,66 @@ API_CLASS(Static) class FLAXENGINE_API Input
|
||||
static Array<InputDevice*, InlinedAllocation<16>> CustomDevices;
|
||||
|
||||
public:
|
||||
typedef Delegate<Char> CharDelegate;
|
||||
typedef Delegate<KeyboardKeys> KeyboardDelegate;
|
||||
typedef Delegate<const Float2&> MouseDelegate;
|
||||
typedef Delegate<const Float2&, MouseButton> MouseButtonDelegate;
|
||||
typedef Delegate<const Float2&, float> MouseWheelDelegate;
|
||||
typedef Delegate<const Float2&, int32> TouchDelegate;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired on character input.
|
||||
/// </summary>
|
||||
static CharDelegate CharInput;
|
||||
API_EVENT() static Delegate<Char> CharInput;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired on key pressed.
|
||||
/// </summary>
|
||||
static KeyboardDelegate KeyDown;
|
||||
API_EVENT() static Delegate<KeyboardKeys> KeyDown;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired on key released.
|
||||
/// </summary>
|
||||
static KeyboardDelegate KeyUp;
|
||||
API_EVENT() static Delegate<KeyboardKeys> KeyUp;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse button goes down.
|
||||
/// </summary>
|
||||
static MouseButtonDelegate MouseDown;
|
||||
API_EVENT() static Delegate<const Float2&, MouseButton> MouseDown;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse button goes up.
|
||||
/// </summary>
|
||||
static MouseButtonDelegate MouseUp;
|
||||
API_EVENT() static Delegate<const Float2&, MouseButton> MouseUp;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse button double clicks.
|
||||
/// </summary>
|
||||
static MouseButtonDelegate MouseDoubleClick;
|
||||
API_EVENT() static Delegate<const Float2&, MouseButton> MouseDoubleClick;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse wheel is scrolling (wheel delta is normalized).
|
||||
/// </summary>
|
||||
static MouseWheelDelegate MouseWheel;
|
||||
API_EVENT() static Delegate<const Float2&, float> MouseWheel;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse moves.
|
||||
/// </summary>
|
||||
static MouseDelegate MouseMove;
|
||||
API_EVENT() static Delegate<const Float2&> MouseMove;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when mouse leaves window.
|
||||
/// </summary>
|
||||
static Action MouseLeave;
|
||||
API_EVENT() static Action MouseLeave;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when touch action begins.
|
||||
/// </summary>
|
||||
static TouchDelegate TouchDown;
|
||||
API_EVENT() static Delegate<const Float2&, int32> TouchDown;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when touch action moves.
|
||||
/// </summary>
|
||||
static TouchDelegate TouchMove;
|
||||
API_EVENT() static Delegate<const Float2&, int32> TouchMove;
|
||||
|
||||
/// <summary>
|
||||
/// Event fired when touch action ends.
|
||||
/// </summary>
|
||||
static TouchDelegate TouchUp;
|
||||
API_EVENT() static Delegate<const Float2&, int32> TouchUp;
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
|
||||
@@ -1323,6 +1323,20 @@ Actor* Actor::FindActor(const MClass* type) const
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Actor* Actor::FindActor(const MClass* type, const StringView& name) const
|
||||
{
|
||||
CHECK_RETURN(type, nullptr);
|
||||
if (GetClass()->IsSubClassOf(type) && StringUtils::Compare(*_name, *name) == 0)
|
||||
return const_cast<Actor*>(this);
|
||||
for (auto child : Children)
|
||||
{
|
||||
const auto actor = child->FindActor(type, name);
|
||||
if (actor)
|
||||
return actor;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Script* Actor::FindScript(const MClass* type) const
|
||||
{
|
||||
CHECK_RETURN(type, nullptr);
|
||||
|
||||
@@ -259,6 +259,17 @@ namespace FlaxEngine
|
||||
return FindActor(typeof(T)) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type and name in this actor hierarchy (checks this actor and all children hierarchy).
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the object.</param>
|
||||
/// <typeparam name="T">Type of the object.</typeparam>
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
public T FindActor<T>(string name) where T : Actor
|
||||
{
|
||||
return FindActor(typeof(T), name) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Searches for all actors of a specific type in this actor children list.
|
||||
/// </summary>
|
||||
|
||||
@@ -734,6 +734,14 @@ public:
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type) const;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type and name in this actor hierarchy (checks this actor and all children hierarchy).
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the actor to search for. Includes any actors derived from the type.</param>
|
||||
/// <param name="name">The name of the actor.</param>
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
API_FUNCTION() Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const StringView& name) const;
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type in this actor hierarchy (checks this actor and all children hierarchy).
|
||||
/// </summary>
|
||||
@@ -744,6 +752,17 @@ public:
|
||||
return (T*)FindActor(T::GetStaticClass());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type and name in this actor hierarchy (checks this actor and all children hierarchy).
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the actor.</param>
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
template<typename T>
|
||||
FORCE_INLINE T* FindActor(const StringView& name) const
|
||||
{
|
||||
return (T*)FindActor(T::GetStaticClass(), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the script of the given type in this actor hierarchy (checks this actor and all children hierarchy).
|
||||
/// </summary>
|
||||
|
||||
@@ -748,6 +748,20 @@ void FindActorsRecursive(Actor* node, const Tag& tag, Array<Actor*>& result)
|
||||
FindActorsRecursive(child, tag, result);
|
||||
}
|
||||
|
||||
void FindActorsRecursiveByParentTags(Actor* node, const Array<Tag>& tags, Array<Actor*>& result)
|
||||
{
|
||||
for (Tag tag : tags)
|
||||
{
|
||||
if (node->HasTag(tag))
|
||||
{
|
||||
result.Add(node);
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (Actor* child : node->Children)
|
||||
FindActorsRecursiveByParentTags(child, tags, result);
|
||||
}
|
||||
|
||||
Actor* Level::FindActor(const Tag& tag, Actor* root)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
@@ -781,12 +795,43 @@ Array<Actor*> Level::FindActors(const Tag& tag, Actor* root)
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopeLock lock(ScenesLock);
|
||||
for (Scene* scene : Scenes)
|
||||
FindActorsRecursive(scene, tag, result);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Array<Actor*> Level::FindActorsByParentTag(const Tag& parentTag, Actor* root)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
Array<Actor*> result;
|
||||
const Array<Tag> subTags = Tags::GetSubTags(parentTag);
|
||||
|
||||
if (subTags.Count() == 0)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
if (subTags.Count() == 1)
|
||||
{
|
||||
result = FindActors(subTags[0], root);
|
||||
return result;
|
||||
}
|
||||
|
||||
if (root)
|
||||
{
|
||||
FindActorsRecursiveByParentTags(root, subTags, result);
|
||||
}
|
||||
else
|
||||
{
|
||||
ScopeLock lock(ScenesLock);
|
||||
for (Scene* scene : Scenes)
|
||||
FindActorsRecursiveByParentTags(scene, subTags, result);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void Level::callActorEvent(ActorEventType eventType, Actor* a, Actor* b)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
@@ -1266,7 +1311,7 @@ bool Level::SaveSceneToBytes(Scene* scene, rapidjson_flax::StringBuffer& outData
|
||||
}
|
||||
|
||||
// Info
|
||||
LOG(Info, "Scene saved! Time {0} ms", Math::CeilToInt(static_cast<float>((DateTime::NowUTC()- startTime).GetTotalMilliseconds())));
|
||||
LOG(Info, "Scene saved! Time {0} ms", Math::CeilToInt(static_cast<float>((DateTime::NowUTC() - startTime).GetTotalMilliseconds())));
|
||||
|
||||
// Fire event
|
||||
CallSceneEvent(SceneEventType::OnSceneSaved, scene, scene->GetID());
|
||||
@@ -1446,6 +1491,16 @@ Actor* Level::FindActor(const MClass* type)
|
||||
return result;
|
||||
}
|
||||
|
||||
Actor* Level::FindActor(const MClass* type, const StringView& name)
|
||||
{
|
||||
CHECK_RETURN(type, nullptr);
|
||||
Actor* result = nullptr;
|
||||
ScopeLock lock(ScenesLock);
|
||||
for (int32 i = 0; result == nullptr && i < Scenes.Count(); i++)
|
||||
result = Scenes[i]->FindActor(type, name);
|
||||
return result;
|
||||
}
|
||||
|
||||
Script* Level::FindScript(const MClass* type)
|
||||
{
|
||||
CHECK_RETURN(type, nullptr);
|
||||
|
||||
@@ -66,6 +66,17 @@ namespace FlaxEngine
|
||||
{
|
||||
return FindActor(typeof(T)) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find actor of the given type and name in all loaded scenes.
|
||||
/// </summary>
|
||||
/// <param name="name">Name of the object.</param>
|
||||
/// <typeparam name="T">Type of the object.</typeparam>
|
||||
/// <returns>Found actor or null.</returns>
|
||||
public static T FindActor<T>(string name) where T : Actor
|
||||
{
|
||||
return FindActor(typeof(T), name) as T;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find actor with the given ID in all loaded scenes. It's very fast O(1) lookup.
|
||||
|
||||
@@ -363,6 +363,14 @@ public:
|
||||
/// <returns>Found actor or null.</returns>
|
||||
API_FUNCTION() static Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type and name in all the loaded scenes.
|
||||
/// </summary>
|
||||
/// <param name="type">Type of the actor to search for. Includes any actors derived from the type.</param>
|
||||
/// <param name="name">The name of the actor.</param>
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
API_FUNCTION() static Actor* FindActor(API_PARAM(Attributes="TypeReference(typeof(Actor))") const MClass* type, const StringView& name);
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type in all the loaded scenes.
|
||||
/// </summary>
|
||||
@@ -373,6 +381,17 @@ public:
|
||||
return (T*)FindActor(T::GetStaticClass());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the actor of the given type and name in all the loaded scenes.
|
||||
/// </summary>
|
||||
/// <param name="name">The name of the actor.</param>
|
||||
/// <returns>Actor instance if found, null otherwise.</returns>
|
||||
template<typename T>
|
||||
FORCE_INLINE static T* FindActor(const StringView& name)
|
||||
{
|
||||
return (T*)FindActor(T::GetStaticClass(), name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Tries to find the script of the given type in all the loaded scenes.
|
||||
/// </summary>
|
||||
@@ -479,6 +498,14 @@ public:
|
||||
/// <returns>Found actors or empty if none.</returns>
|
||||
API_FUNCTION() static Array<Actor*> FindActors(const Tag& tag, Actor* root = nullptr);
|
||||
|
||||
/// <summary>
|
||||
/// Search actors using a parent parentTag.
|
||||
/// </summary>
|
||||
/// <param name="parentTag">The tag to search actors with subtags belonging to this tag</param>
|
||||
/// <param name="root">The custom root actor to start searching from (hierarchical), otherwise null to search all loaded scenes.</param>
|
||||
/// <returns>Returns all actors that have subtags belonging to the given parent parentTag</returns>
|
||||
API_FUNCTION() static Array<Actor*> FindActorsByParentTag(const Tag& parentTag, Actor* root = nullptr);
|
||||
|
||||
private:
|
||||
// Actor API
|
||||
enum class ActorEventType
|
||||
|
||||
@@ -127,7 +127,7 @@ public:
|
||||
/// <summary>
|
||||
/// Gets the character up vector.
|
||||
/// </summary>
|
||||
API_PROPERTY(Attributes="EditorOrder(240), DefaultValue(typeof(Vector3), \"0,1,0\"), EditorDisplay(\"Character Controller\")")
|
||||
API_PROPERTY(Attributes="EditorOrder(240), DefaultValue(typeof(Vector3), \"0,1,0\"), EditorDisplay(\"Character Controller\"), Limit(-1, 1)")
|
||||
Vector3 GetUpDirection() const;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -218,6 +218,21 @@ void Physics::FlushRequests()
|
||||
PhysicsBackend::FlushRequests();
|
||||
}
|
||||
|
||||
bool Physics::LineCast(const Vector3& start, const Vector3& end, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
return DefaultScene->LineCast(start, end, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::LineCast(const Vector3& start, const Vector3& end, RayCastHit& hitInfo, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
return DefaultScene->LineCast(start, end, hitInfo, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCastHit>& results, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
return DefaultScene->LineCastAll(start, end, results, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool Physics::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
return DefaultScene->RayCast(origin, direction, maxDistance, layerMask, hitTriggers);
|
||||
@@ -461,6 +476,33 @@ void PhysicsScene::CollectResults()
|
||||
_isDuringSimulation = false;
|
||||
}
|
||||
|
||||
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
Vector3 directionToEnd = end - start;
|
||||
const float distanceToEnd = directionToEnd.Length();
|
||||
if (distanceToEnd >= ZeroTolerance)
|
||||
directionToEnd /= distanceToEnd;
|
||||
return PhysicsBackend::RayCast(_scene, start, directionToEnd, distanceToEnd, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::LineCast(const Vector3& start, const Vector3& end, RayCastHit& hitInfo, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
Vector3 directionToEnd = end - start;
|
||||
const float distanceToEnd = directionToEnd.Length();
|
||||
if (distanceToEnd >= ZeroTolerance)
|
||||
directionToEnd /= distanceToEnd;
|
||||
return PhysicsBackend::RayCast(_scene, start, directionToEnd, hitInfo, distanceToEnd, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::LineCastAll(const Vector3& start, const Vector3& end, Array<RayCastHit>& results, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
Vector3 directionToEnd = end - start;
|
||||
const float distanceToEnd = directionToEnd.Length();
|
||||
if (distanceToEnd >= ZeroTolerance)
|
||||
directionToEnd /= distanceToEnd;
|
||||
return PhysicsBackend::RayCastAll(_scene, start, directionToEnd, results, distanceToEnd, layerMask, hitTriggers);
|
||||
}
|
||||
|
||||
bool PhysicsScene::RayCast(const Vector3& origin, const Vector3& direction, const float maxDistance, uint32 layerMask, bool hitTriggers)
|
||||
{
|
||||
return PhysicsBackend::RayCast(_scene, origin, direction, maxDistance, layerMask, hitTriggers);
|
||||
|
||||
@@ -95,6 +95,38 @@ public:
|
||||
API_FUNCTION() static void FlushRequests();
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Performs a line between two points in the scene.
|
||||
/// </summary>
|
||||
/// <param name="start">The start position of the line.</param>
|
||||
/// <param name="end">The end position of the line.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() static bool LineCast(const Vector3& start, const Vector3& end, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a line between two points in the scene.
|
||||
/// </summary>
|
||||
/// <param name="start">The start position of the line.</param>
|
||||
/// <param name="end">The end position of the line.</param>
|
||||
/// <param name="hitInfo">The result hit information. Valid only when method returns true.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() static bool LineCast(const Vector3& start, const Vector3& end, API_PARAM(Out) RayCastHit& hitInfo, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
// <summary>
|
||||
/// Performs a line between two points in the scene, returns all hitpoints infos.
|
||||
/// </summary>
|
||||
/// <param name="start">The origin of the ray.</param>
|
||||
/// <param name="end">The normalized direction of the ray.</param>
|
||||
/// <param name="results">The result hits. Valid only when method returns true.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() static bool LineCastAll(const Vector3& start, const Vector3& end, API_PARAM(Out) Array<RayCastHit, HeapAllocation>& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a raycast against objects in the scene.
|
||||
/// </summary>
|
||||
|
||||
@@ -133,6 +133,38 @@ public:
|
||||
API_FUNCTION() void CollectResults();
|
||||
|
||||
public:
|
||||
/// <summary>
|
||||
/// Performs a line between two points in the scene.
|
||||
/// </summary>
|
||||
/// <param name="start">The start position of the line.</param>
|
||||
/// <param name="end">The end position of the line.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() bool LineCast(const Vector3& start, const Vector3& end, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a line between two points in the scene.
|
||||
/// </summary>
|
||||
/// <param name="start">The start position of the line.</param>
|
||||
/// <param name="end">The end position of the line.</param>
|
||||
/// <param name="hitInfo">The result hit information. Valid only when method returns true.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() bool LineCast(const Vector3& start, const Vector3& end, API_PARAM(Out) RayCastHit& hitInfo, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
// <summary>
|
||||
/// Performs a line between two points in the scene, returns all hitpoints infos.
|
||||
/// </summary>
|
||||
/// <param name="start">The origin of the ray.</param>
|
||||
/// <param name="end">The normalized direction of the ray.</param>
|
||||
/// <param name="results">The result hits. Valid only when method returns true.</param>
|
||||
/// <param name="layerMask">The layer mask used to filter the results.</param>
|
||||
/// <param name="hitTriggers">If set to <c>true</c> triggers will be hit, otherwise will skip them.</param>
|
||||
/// <returns>True if ray hits an matching object, otherwise false.</returns>
|
||||
API_FUNCTION() bool LineCastAll(const Vector3& start, const Vector3& end, API_PARAM(Out) Array<RayCastHit, HeapAllocation>& results, uint32 layerMask = MAX_uint32, bool hitTriggers = true);
|
||||
|
||||
/// <summary>
|
||||
/// Performs a raycast against objects in the scene.
|
||||
/// </summary>
|
||||
|
||||
@@ -1380,7 +1380,7 @@ bool ModelTool::ImportModel(const String& path, ModelData& meshData, Options& op
|
||||
}
|
||||
|
||||
// Automatic LOD generation
|
||||
if (options.GenerateLODs && data.LODs.HasItems() && options.TriangleReduction < 1.0f - ZeroTolerance)
|
||||
if (options.GenerateLODs && options.LODCount > 1 && data.LODs.HasItems() && options.TriangleReduction < 1.0f - ZeroTolerance)
|
||||
{
|
||||
auto lodStartTime = DateTime::NowUTC();
|
||||
meshopt_setAllocator(MeshOptAllocate, MeshOptDeallocate);
|
||||
|
||||
@@ -169,6 +169,16 @@ namespace FlaxEngine.GUI
|
||||
set => Bounds = new Rectangle(value + (_parent != null ? _parent.Bounds.Size * (_anchorMax + _anchorMin) * 0.5f : Float2.Zero) - _bounds.Size * _pivot, _bounds.Size);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Whether to resize the UI Control based on where the pivot is rather than just the top-left.
|
||||
/// </summary>
|
||||
[NoSerialize, HideInEditor]
|
||||
public bool PivotRelative
|
||||
{
|
||||
get => _pivotRelativeSizing;
|
||||
set => _pivotRelativeSizing = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets width of the control.
|
||||
/// </summary>
|
||||
@@ -181,6 +191,11 @@ namespace FlaxEngine.GUI
|
||||
if (Mathf.NearEqual(_bounds.Size.X, value))
|
||||
return;
|
||||
var bounds = new Rectangle(_bounds.Location, value, _bounds.Size.Y);
|
||||
if (_pivotRelativeSizing)
|
||||
{
|
||||
var delta = _bounds.Size.X - value;
|
||||
bounds.Location.X += delta * Pivot.X;
|
||||
}
|
||||
SetBounds(ref bounds);
|
||||
}
|
||||
}
|
||||
@@ -197,6 +212,11 @@ namespace FlaxEngine.GUI
|
||||
if (Mathf.NearEqual(_bounds.Size.Y, value))
|
||||
return;
|
||||
var bounds = new Rectangle(_bounds.Location, _bounds.Size.X, value);
|
||||
if (_pivotRelativeSizing)
|
||||
{
|
||||
var delta = _bounds.Size.Y - value;
|
||||
bounds.Location.Y += delta * Pivot.Y;
|
||||
}
|
||||
SetBounds(ref bounds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,7 @@ namespace FlaxEngine.GUI
|
||||
private bool _isVisible = true;
|
||||
private bool _isEnabled = true;
|
||||
private bool _autoFocus = true;
|
||||
private bool _pivotRelativeSizing = false;
|
||||
private List<int> _touchOvers;
|
||||
private RootControl.UpdateDelegate _tooltipUpdate;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user