// // Copyright (c) 2008-2017 the Urho3D project. // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal // in the Software without restriction, including without limitation the rights // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // copies of the Software, and to permit persons to whom the Software is // furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN // THE SOFTWARE. // #pragma once #include "../Graphics/Drawable.h" namespace Urho3D { enum TrailType { TT_FACE_CAMERA = 0, TT_BONE }; class IndexBuffer; class VertexBuffer; /// Trail is consisting of series of tails. Two connected points make a tail. struct URHO3D_API TrailPoint { /// Position. Vector3 position_; /// Forward vector. Vector3 forward_; /// Parent position. Trail bone type uses this. Vector3 parentPos_; /// Elapsed length inside the trail. float elapsedLength_; /// Next point to make a tail. TrailPoint* next_; /// Tail time to live. float lifetime_; /// Distance for sorting. float sortDistance_; }; /// Drawable component that creates a tail. class URHO3D_API RibbonTrail : public Drawable { URHO3D_OBJECT(RibbonTrail, Drawable); public: /// Construct. RibbonTrail(Context* context); /// Destruct. virtual ~RibbonTrail(); /// Register object factory. static void RegisterObject(Context* context); /// Process octree raycast. May be called from a worker thread. virtual void ProcessRayQuery(const RayOctreeQuery& query, PODVector& results); /// Handle enabled/disabled state change. virtual void OnSetEnabled(); /// Update before octree reinsertion. Is called from a main thread. virtual void Update(const FrameInfo &frame); /// Calculate distance and prepare batches for rendering. May be called from worker thread(s), possibly re-entrantly. virtual void UpdateBatches(const FrameInfo& frame); /// Prepare geometry for rendering. Called from a worker thread if possible (no GPU update.) virtual void UpdateGeometry(const FrameInfo& frame); /// Return whether a geometry update is necessary, and if it can happen in a worker thread. virtual UpdateGeometryType GetUpdateGeometryType(); /// Set material. void SetMaterial(Material* material); /// Set material attribute. void SetMaterialAttr(const ResourceRef& value); /// Set distance between points. void SetVertexDistance(float length); /// Set width of the tail. Only works for face camera trail type. void SetWidth(float width); /// Set vertex blended color for start of trail. void SetStartColor(const Color& color); /// Set vertex blended scale for end of trail. void SetEndColor(const Color& color); /// Set vertex blended color for start of trail. void SetStartScale(float startScale); /// Set vertex blended scale for end of trail. void SetEndScale(float endScale); /// Set how the trail behave. void SetTrailType(TrailType type); /// Set whether tails are sorted by distance. Default false. void SetSorted(bool enable); /// Set tail time to live. void SetLifetime(float time); /// Set whether trail should be emitting. void SetEmitting(bool emitting); /// Set whether to update when trail emiiter are not visible. void SetUpdateInvisible(bool enable); /// Set number of column for every tails. Can be useful for fixing distortion at high angle. void SetTailColumn(unsigned tailColumn); /// Set animation LOD bias. void SetAnimationLodBias(float bias); /// Mark for bounding box and vertex buffer update. Call after modifying the trails. void Commit(); /// Return material. Material* GetMaterial() const; /// Return material attribute. ResourceRef GetMaterialAttr() const; /// Get distance between points. float GetVertexDistance() const { return vertexDistance_; } /// Get width of the trail. float GetWidth() const { return width_; } /// Get vertex blended color for start of trail. const Color& GetStartColor() const { return startColor_; } /// Get vertex blended color for end of trail. const Color& GetEndColor() const { return endColor_; } /// Get vertex blended scale for start of trail. float GetStartScale() const { return startScale_; } /// Get vertex blended scale for end of trail. float GetEndScale() const { return endScale_; } /// Return whether tails are sorted. bool IsSorted() const { return sorted_; } /// Return tail time to live. float GetLifetime() const {return lifetime_;} /// Return animation LOD bias. float GetAnimationLodBias() const { return animationLodBias_; } /// Return how the trail behave. TrailType GetTrailType() const { return trailType_; } /// Get number of column for tails. unsigned GetTailColumn() const { return tailColumn_; } /// Return whether is currently emitting. bool IsEmitting() const { return emitting_ ; } /// Return whether to update when trail emitter are not visible. bool GetUpdateInvisible() const { return updateInvisible_; } protected: /// Handle node being assigned. virtual void OnSceneSet(Scene* scene); /// Recalculate the world-space bounding box. virtual void OnWorldBoundingBoxUpdate(); /// Mark vertex buffer to need an update. void MarkPositionsDirty(); /// Tails. PODVector points_; /// Tails sorted flag. bool sorted_; /// Animation LOD bias. float animationLodBias_; /// Animation LOD timer. float animationLodTimer_; /// Trail type. TrailType trailType_; private: /// Handle scene post-update event. void HandleScenePostUpdate(StringHash eventType, VariantMap& eventData); /// Resize RibbonTrail vertex and index buffers. void UpdateBufferSize(); /// Rewrite RibbonTrail vertex buffer. void UpdateVertexBuffer(const FrameInfo& frame); /// Update/Rebuild tail mesh only if position changed (called by UpdateBatches()) void UpdateTail(); /// Geometry. SharedPtr geometry_; /// Vertex buffer. SharedPtr vertexBuffer_; /// Index buffer. SharedPtr indexBuffer_; /// Transform matrices for position and orientation. Matrix3x4 transforms_; /// Buffers need resize flag. bool bufferSizeDirty_; /// Vertex buffer needs rewrite flag. bool bufferDirty_; /// Previous position of tail Vector3 previousPosition_; /// Distance between points. Basically is tail length. float vertexDistance_; /// Width of trail. float width_; /// Number of points. unsigned numPoints_; /// Color for start of trails. Color startColor_; /// Color for end of trails. Color endColor_; /// Scale for start of trails. float startScale_; /// End for start of trails. float endScale_; /// Last scene timestep. float lastTimeStep_; // Lifetime float lifetime_; /// Number of columns for every tails. unsigned tailColumn_; /// Rendering framenumber on which was last updated. unsigned lastUpdateFrameNumber_; /// Need update flag. bool needUpdate_; /// Previous offset to camera for determining whether sorting is necessary. Vector3 previousOffset_; /// Trail pointers for sorting. Vector sortedPoints_; /// Force update flag (ignore animation LOD momentarily.) bool forceUpdate_; /// Currently emitting flag. bool emitting_; /// Update when invisible flag. bool updateInvisible_; /// End of trail point for smoother tail disappearance. TrailPoint endTail_; /// The time the tail become end of trail. float startEndTailTime_; }; }