// // 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 "../Container/ArrayPtr.h" #include "../Container/Ptr.h" #include "../Graphics/GraphicsDefs.h" #include "../Graphics/Skeleton.h" #include "../Math/BoundingBox.h" #include "../Resource/Resource.h" namespace Atomic { class Geometry; class IndexBuffer; class Graphics; class VertexBuffer; /// Vertex buffer morph data. struct VertexBufferMorph { /// Vertex elements. unsigned elementMask_; /// Number of vertices. unsigned vertexCount_; /// Morphed vertices data size as bytes. unsigned dataSize_; /// Morphed vertices. Stored packed as pairs. SharedArrayPtr morphData_; }; /// Definition of a model's vertex morph. struct ModelMorph { /// Morph name. String name_; /// Morph name hash. StringHash nameHash_; /// Current morph weight. float weight_; /// Morph data per vertex buffer. HashMap buffers_; }; /// Description of vertex buffer data for asynchronous loading. struct VertexBufferDesc { /// Vertex count. unsigned vertexCount_; /// Vertex declaration. PODVector vertexElements_; /// Vertex data size. unsigned dataSize_; /// Vertex data. SharedArrayPtr data_; }; /// Description of index buffer data for asynchronous loading. struct IndexBufferDesc { /// Index count. unsigned indexCount_; /// Index size. unsigned indexSize_; /// Index data size. unsigned dataSize_; /// Index data. SharedArrayPtr data_; }; /// Description of a geometry for asynchronous loading. struct GeometryDesc { /// Primitive type. PrimitiveType type_; /// Vertex buffer ref. unsigned vbRef_; /// Index buffer ref. unsigned ibRef_; /// Index start. unsigned indexStart_; /// Index count. unsigned indexCount_; }; // ATOMIC BEGIN static const unsigned MODEL_VERSION = 1; // ATOMIC END /// 3D model resource. class ATOMIC_API Model : public ResourceWithMetadata { ATOMIC_OBJECT(Model, ResourceWithMetadata); public: /// Construct. Model(Context* context); /// Destruct. virtual ~Model(); /// Register object factory. static void RegisterObject(Context* context); /// Load resource from stream. May be called from a worker thread. Return true if successful. virtual bool BeginLoad(Deserializer& source); /// Finish resource loading. Always called from the main thread. Return true if successful. virtual bool EndLoad(); /// Save resource. Return true if successful. virtual bool Save(Serializer& dest) const; /// Set local-space bounding box. void SetBoundingBox(const BoundingBox& box); /// Set vertex buffers and their morph ranges. bool SetVertexBuffers(const Vector >& buffers, const PODVector& morphRangeStarts, const PODVector& morphRangeCounts); /// Set index buffers. bool SetIndexBuffers(const Vector >& buffers); /// Set number of geometries. void SetNumGeometries(unsigned num); /// Set number of LOD levels in a geometry. bool SetNumGeometryLodLevels(unsigned index, unsigned num); /// Set geometry. bool SetGeometry(unsigned index, unsigned lodLevel, Geometry* geometry); /// Set geometry center. bool SetGeometryCenter(unsigned index, const Vector3& center); /// Set skeleton. void SetSkeleton(const Skeleton& skeleton); /// Set bone mappings when model has more bones than the skinning shader can handle. void SetGeometryBoneMappings(const Vector >& mappings); /// Set vertex morphs. void SetMorphs(const Vector& morphs); /// Clone the model. The geometry data is deep-copied and can be modified in the clone without affecting the original. SharedPtr Clone(const String& cloneName = String::EMPTY) const; /// Return bounding box. const BoundingBox& GetBoundingBox() const { return boundingBox_; } /// Return skeleton. Skeleton& GetSkeleton() { return skeleton_; } /// Return vertex buffers. const Vector >& GetVertexBuffers() const { return vertexBuffers_; } /// Return index buffers. const Vector >& GetIndexBuffers() const { return indexBuffers_; } /// Return number of geometries. unsigned GetNumGeometries() const { return geometries_.Size(); } /// Return number of LOD levels in geometry. unsigned GetNumGeometryLodLevels(unsigned index) const; /// Return geometry pointers. const Vector > >& GetGeometries() const { return geometries_; } /// Return geometry center points. const PODVector& GetGeometryCenters() const { return geometryCenters_; } /// Return geometry by index and LOD level. The LOD level is clamped if out of range. Geometry* GetGeometry(unsigned index, unsigned lodLevel) const; /// Return geometry center by index. const Vector3& GetGeometryCenter(unsigned index) const { return index < geometryCenters_.Size() ? geometryCenters_[index] : Vector3::ZERO; } /// Return geometery bone mappings. const Vector >& GetGeometryBoneMappings() const { return geometryBoneMappings_; } /// Return vertex morphs. const Vector& GetMorphs() const { return morphs_; } /// Return number of vertex morphs. unsigned GetNumMorphs() const { return morphs_.Size(); } /// Return vertex morph by index. const ModelMorph* GetMorph(unsigned index) const; /// Return vertex morph by name. const ModelMorph* GetMorph(const String& name) const; /// Return vertex morph by name hash. const ModelMorph* GetMorph(StringHash nameHash) const; /// Return vertex buffer morph range start. unsigned GetMorphRangeStart(unsigned bufferIndex) const; /// Return vertex buffer morph range vertex count. unsigned GetMorphRangeCount(unsigned bufferIndex) const; // ATOMIC BEGIN bool SetGeometryName(unsigned index, const String& name); const String& GetGeometryName(unsigned index) const; const Vector& GetGeometryNames() const { return geometryNames_; } // ATOMIC END private: /// Bounding box. BoundingBox boundingBox_; /// Skeleton. Skeleton skeleton_; /// Vertex buffers. Vector > vertexBuffers_; /// Index buffers. Vector > indexBuffers_; /// Geometries. Vector > > geometries_; /// Geometry bone mappings. Vector > geometryBoneMappings_; /// Geometry centers. PODVector geometryCenters_; /// Vertex morphs. Vector morphs_; /// Vertex buffer morph range start. PODVector morphRangeStarts_; /// Vertex buffer morph range vertex count. PODVector morphRangeCounts_; /// Vertex buffer data for asynchronous loading. Vector loadVBData_; /// Index buffer data for asynchronous loading. Vector loadIBData_; /// Geometry definitions for asynchronous loading. Vector > loadGeometries_; // ATOMIC BEGIN Vector geometryNames_; // ATOMIC END }; }