// Copyright (c) 2012-2024 Wojciech Figat. All rights reserved. #pragma once #include "../Actor.h" #include "Engine/Animations/Curve.h" /// /// Spline shape actor that defines spatial curve with utility functions for general purpose usage. /// API_CLASS(Attributes="ActorContextMenu(\"New/Other/Spline\"), ActorToolbox(\"Other\")") class FLAXENGINE_API Spline : public Actor { DECLARE_SCENE_OBJECT(Spline); typedef BezierCurveKeyframe Keyframe; private: bool _loop = false; BoundingBox _localBounds; public: /// /// The spline bezier curve points represented as series of transformations in 3D space (with tangents). Points are stored in local-space of the actor. /// /// Ensure to call UpdateSpline() after editing curve to reflect the changes. BezierCurve Curve; /// /// Whether to use spline as closed loop. In that case, ensure to place start and end at the same location. /// API_PROPERTY(Attributes="EditorOrder(0), EditorDisplay(\"Spline\")") bool GetIsLoop() const; /// /// Whether to use spline as closed loop. In that case, ensure to place start and end at the same location. /// API_PROPERTY() void SetIsLoop(bool value); public: /// /// Evaluates the spline curve at the given time and calculates the point location in 3D (world-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point location (world-space). API_FUNCTION() Vector3 GetSplinePoint(float time) const; /// /// Evaluates the spline curve at the given time and calculates the point location in 3D (local-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point location (local-space). API_FUNCTION() Vector3 GetSplineLocalPoint(float time) const; /// /// Evaluates the spline curve at the given time and calculates the point rotation in 3D (world-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point rotation (world-space). API_FUNCTION() Quaternion GetSplineOrientation(float time) const; /// /// Evaluates the spline curve at the given time and calculates the point rotation in 3D (local-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point rotation (local-space). API_FUNCTION() Quaternion GetSplineLocalOrientation(float time) const; /// /// Evaluates the spline curve at the given time and calculates the point scale in 3D (world-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point scale (world-space). API_FUNCTION() Vector3 GetSplineScale(float time) const; /// /// Evaluates the spline curve at the given time and calculates the point scale in 3D (local-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point scale (local-space). API_FUNCTION() Vector3 GetSplineLocalScale(float time) const; /// /// Evaluates the spline curve at the given time and calculates the transformation in 3D (world-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point transformation (world-space). API_FUNCTION() Transform GetSplineTransform(float time) const; /// /// Evaluates the spline curve at the given time and calculates the transformation in 3D (local-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve point transformation (local-space). API_FUNCTION() Transform GetSplineLocalTransform(float time) const; /// /// Evaluates the spline curve direction (forward vector, aka position 1st derivative) at the given time in 3D (world-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve direction (world-space). API_FUNCTION() Vector3 GetSplineDirection(float time) const; /// /// Evaluates the spline curve direction (forward vector, aka position 1st derivative) at the given time in 3D (local-space). /// /// The time value. Can be negative or larger than curve length (curve will loop or clamp). /// The calculated curve direction (local-space). API_FUNCTION() Vector3 GetSplineLocalDirection(float time) const; /// /// Evaluates the spline curve at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The curve point location (world-space). API_FUNCTION() Vector3 GetSplinePoint(int32 index) const; /// /// Evaluates the spline curve at the given index (local-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The curve point location (local-space). API_FUNCTION() Vector3 GetSplineLocalPoint(int32 index) const; /// /// Evaluates the spline curve at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The curve point transformation (world-space). API_FUNCTION() Transform GetSplineTransform(int32 index) const; /// /// Evaluates the spline curve at the given index (local-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The curve point transformation (local-space). API_FUNCTION() Transform GetSplineLocalTransform(int32 index) const; /// /// Gets the spline curve point tangent at the given index (world-space). /// /// Tangents are stored relative to the curve point but this methods converts them to be in world-space. /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// True if get arrive tangent, otherwise gets leave tangent (in or out). /// The transformation of the tangent to set (world-space). API_FUNCTION() Transform GetSplineTangent(int32 index, bool isIn); /// /// Gets the spline curve point tangent at the given index (local-space). /// /// Tangents are stored relative to the curve point but this methods converts them to be in local-space of the actor. /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// True if get arrive tangent, otherwise gets leave tangent (in or out). /// The transformation of the tangent to set (world-space). API_FUNCTION() Transform GetSplineLocalTangent(int32 index, bool isIn); /// /// Gets the amount of points in the spline. /// API_PROPERTY() int32 GetSplinePointsCount() const; /// /// Gets the total duration of the spline curve (time of the last point). /// API_PROPERTY() float GetSplineDuration() const; /// /// Gets the total length of the spline curve (distance between all the points). /// API_PROPERTY() float GetSplineLength() const; /// /// Gets the length of the spline segment (distance between pair of two points). /// /// The index of the segment end index. Zero-based, smaller than GetSplinePointsCount(). /// The spline segment length. API_FUNCTION() float GetSplineSegmentLength(int32 index) const; /// /// Gets the time of the spline keyframe. /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The spline time. API_FUNCTION() float GetSplineTime(int32 index) const; /// /// Calculates the closest point to the given location and returns the spline time at that point. /// /// The point in world-space to find the spline point that is closest to it. /// The spline time. API_FUNCTION() float GetSplineTimeClosestToPoint(const Vector3& point) const; /// /// Calculates the closest point to the given location. /// /// The point in world-space to find the spline point that is closest to it. /// The spline position. API_FUNCTION() Vector3 GetSplinePointClosestToPoint(const Vector3& point) const; /// /// Gets the spline curve points list (world-space). /// /// The result points collection. API_FUNCTION() void GetSplinePoints(API_PARAM(Out) Array& points) const; /// /// Gets the spline curve points list (local-space). /// /// The result points collection. API_FUNCTION() void GetSplineLocalPoints(API_PARAM(Out) Array& points) const; /// /// Gets the spline curve points list (world-space). /// /// The result points collection. API_FUNCTION() void GetSplinePoints(API_PARAM(Out) Array& points) const; /// /// Gets the spline curve points list (local-space). /// /// The result points collection. API_FUNCTION() void GetSplineLocalPoints(API_PARAM(Out) Array& points) const; public: /// /// Clears the spline to be empty. /// API_FUNCTION() void ClearSpline(); /// /// Removes the spline curve point at the given index. /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// True if update spline after removing the point, otherwise false. API_FUNCTION() void RemoveSplinePoint(int32 index, bool updateSpline = true); /// /// Sets the spline curve at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The location of the point to set (world-space). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplinePoint(int32 index, const Vector3& point, bool updateSpline = true); /// /// Sets the spline curve at the given index (local-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The location of the point to set (local-space). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplineLocalPoint(int32 index, const Vector3& point, bool updateSpline = true); /// /// Sets the spline curve at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The transformation of the point to set (world-space). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplineTransform(int32 index, const Transform& point, bool updateSpline = true); /// /// Sets the spline curve at the given index (local-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The transformation of the point to set (local-space). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplineLocalTransform(int32 index, const Transform& point, bool updateSpline = true); /// /// Sets the spline curve point tangent at the given index (world-space). /// /// Tangents are stored relative to the curve point but this methods converts them to be in world-space. /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The transformation of the tangent to set (world-space). /// True if set arrive tangent, otherwise sets leave tangent (in or out). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplineTangent(int32 index, const Transform& point, bool isIn, bool updateSpline = true); /// /// Sets the spline curve point tangent at the given index (local-space). /// /// Tangents are stored relative to the curve point but this methods converts them to be in local-space of the actor. /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The transformation of the tangent to set (local-space). /// True if set arrive tangent, otherwise sets leave tangent (in or out). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplineLocalTangent(int32 index, const Transform& point, bool isIn, bool updateSpline = true); /// /// Sets the spline curve point time at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The time to set. /// True if update spline after editing the point, otherwise false. API_FUNCTION() void SetSplinePointTime(int32 index, float time, bool updateSpline = true); /// /// Adds the point to the spline curve (at the end). /// /// The location of the point to add to the curve (world-space). /// True if update spline after editing the point, otherwise false. API_FUNCTION() void AddSplinePoint(const Vector3& point, bool updateSpline = true); /// /// Adds the point to the spline curve (at the end). /// /// The location of the point to add to the curve (local-space). /// True if update spline after adding the point, otherwise false. API_FUNCTION() void AddSplineLocalPoint(const Vector3& point, bool updateSpline = true); /// /// Adds the point to the spline curve (at the end). /// /// The transformation of the point to add to the curve (world-space). /// True if update spline after adding the point, otherwise false. API_FUNCTION() void AddSplinePoint(const Transform& point, bool updateSpline = true); /// /// Adds the point to the spline curve (at the end). /// /// The transformation of the point to add to the curve (local-space). /// True if update spline after adding the point, otherwise false. API_FUNCTION() void AddSplineLocalPoint(const Transform& point, bool updateSpline = true); /// /// Inserts the spline curve point at the given index (world-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The time value. /// The location of the point to add to the curve (world-space). /// True if update spline after removing the point, otherwise false. API_FUNCTION() void InsertSplinePoint(int32 index, float time, const Transform& point, bool updateSpline = true); /// /// Inserts the spline curve point at the given index (local-space). /// /// The curve keyframe index. Zero-based, smaller than GetSplinePointsCount(). /// The time value. /// The location of the point to add to the curve (local-space). /// True if update spline after removing the point, otherwise false. API_FUNCTION() void InsertSplineLocalPoint(int32 index, float time, const Transform& point, bool updateSpline = true); /// /// Updates the curve tangent points to make curve linear. /// API_FUNCTION() void SetTangentsLinear(); /// /// Updates the curve tangent points to make curve smooth. /// API_FUNCTION() void SetTangentsSmooth(); public: /// /// Called when spline gets updated (eg. after curve modification). /// API_EVENT() Action SplineUpdated; /// /// Updates the spline after it was modified. Recreates the collision and/or any cached state that depends on the spline type. /// API_FUNCTION() virtual void UpdateSpline(); protected: #if USE_EDITOR // Spline color getter for debug drawing, can be overriden by custom spline types. virtual Color GetSplineColor() { return Color::White; } #endif private: // Internal bindings #if !COMPILE_WITHOUT_CSHARP API_FUNCTION(NoProxy) void GetKeyframes(MArray* data); API_FUNCTION(NoProxy) void SetKeyframes(MArray* data, int32 keySize); #endif public: // [Actor] #if USE_EDITOR void OnDebugDraw() override; void OnDebugDrawSelected() override; #endif void OnTransformChanged() override; void Initialize() override; void Serialize(SerializeStream& stream, const void* otherObj) override; void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) override; };