1 //
2 // Copyright (c) 2008-2017 the Urho3D project.
3 //
4 // Permission is hereby granted, free of charge, to any person obtaining a copy
5 // of this software and associated documentation files (the "Software"), to deal
6 // in the Software without restriction, including without limitation the rights
7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 // copies of the Software, and to permit persons to whom the Software is
9 // furnished to do so, subject to the following conditions:
10 //
11 // The above copyright notice and this permission notice shall be included in
12 // all copies or substantial portions of the Software.
13 //
14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 // THE SOFTWARE.
21 //
22 
23 #pragma once
24 
25 #include "../Container/ArrayPtr.h"
26 #include "../Container/Ptr.h"
27 #include "../Graphics/GraphicsDefs.h"
28 #include "../Graphics/Skeleton.h"
29 #include "../Math/BoundingBox.h"
30 #include "../Resource/Resource.h"
31 
32 namespace Urho3D
33 {
34 
35 class Geometry;
36 class IndexBuffer;
37 class Graphics;
38 class VertexBuffer;
39 
40 /// Vertex buffer morph data.
41 struct VertexBufferMorph
42 {
43     /// Vertex elements.
44     unsigned elementMask_;
45     /// Number of vertices.
46     unsigned vertexCount_;
47     /// Morphed vertices data size as bytes.
48     unsigned dataSize_;
49     /// Morphed vertices. Stored packed as <index, data> pairs.
50     SharedArrayPtr<unsigned char> morphData_;
51 };
52 
53 /// Definition of a model's vertex morph.
54 struct ModelMorph
55 {
56     /// Morph name.
57     String name_;
58     /// Morph name hash.
59     StringHash nameHash_;
60     /// Current morph weight.
61     float weight_;
62     /// Morph data per vertex buffer.
63     HashMap<unsigned, VertexBufferMorph> buffers_;
64 };
65 
66 /// Description of vertex buffer data for asynchronous loading.
67 struct VertexBufferDesc
68 {
69     /// Vertex count.
70     unsigned vertexCount_;
71     /// Vertex declaration.
72     PODVector<VertexElement> vertexElements_;
73     /// Vertex data size.
74     unsigned dataSize_;
75     /// Vertex data.
76     SharedArrayPtr<unsigned char> data_;
77 };
78 
79 /// Description of index buffer data for asynchronous loading.
80 struct IndexBufferDesc
81 {
82     /// Index count.
83     unsigned indexCount_;
84     /// Index size.
85     unsigned indexSize_;
86     /// Index data size.
87     unsigned dataSize_;
88     /// Index data.
89     SharedArrayPtr<unsigned char> data_;
90 };
91 
92 /// Description of a geometry for asynchronous loading.
93 struct GeometryDesc
94 {
95     /// Primitive type.
96     PrimitiveType type_;
97     /// Vertex buffer ref.
98     unsigned vbRef_;
99     /// Index buffer ref.
100     unsigned ibRef_;
101     /// Index start.
102     unsigned indexStart_;
103     /// Index count.
104     unsigned indexCount_;
105 };
106 
107 /// 3D model resource.
108 class URHO3D_API Model : public ResourceWithMetadata
109 {
110     URHO3D_OBJECT(Model, ResourceWithMetadata);
111 
112 public:
113     /// Construct.
114     Model(Context* context);
115     /// Destruct.
116     virtual ~Model();
117     /// Register object factory.
118     static void RegisterObject(Context* context);
119 
120     /// Load resource from stream. May be called from a worker thread. Return true if successful.
121     virtual bool BeginLoad(Deserializer& source);
122     /// Finish resource loading. Always called from the main thread. Return true if successful.
123     virtual bool EndLoad();
124     /// Save resource. Return true if successful.
125     virtual bool Save(Serializer& dest) const;
126 
127     /// Set local-space bounding box.
128     void SetBoundingBox(const BoundingBox& box);
129     /// Set vertex buffers and their morph ranges.
130     bool SetVertexBuffers(const Vector<SharedPtr<VertexBuffer> >& buffers, const PODVector<unsigned>& morphRangeStarts,
131         const PODVector<unsigned>& morphRangeCounts);
132     /// Set index buffers.
133     bool SetIndexBuffers(const Vector<SharedPtr<IndexBuffer> >& buffers);
134     /// Set number of geometries.
135     void SetNumGeometries(unsigned num);
136     /// Set number of LOD levels in a geometry.
137     bool SetNumGeometryLodLevels(unsigned index, unsigned num);
138     /// Set geometry.
139     bool SetGeometry(unsigned index, unsigned lodLevel, Geometry* geometry);
140     /// Set geometry center.
141     bool SetGeometryCenter(unsigned index, const Vector3& center);
142     /// Set skeleton.
143     void SetSkeleton(const Skeleton& skeleton);
144     /// Set bone mappings when model has more bones than the skinning shader can handle.
145     void SetGeometryBoneMappings(const Vector<PODVector<unsigned> >& mappings);
146     /// Set vertex morphs.
147     void SetMorphs(const Vector<ModelMorph>& morphs);
148     /// Clone the model. The geometry data is deep-copied and can be modified in the clone without affecting the original.
149     SharedPtr<Model> Clone(const String& cloneName = String::EMPTY) const;
150 
151     /// Return bounding box.
GetBoundingBox()152     const BoundingBox& GetBoundingBox() const { return boundingBox_; }
153 
154     /// Return skeleton.
GetSkeleton()155     Skeleton& GetSkeleton() { return skeleton_; }
156 
157     /// Return vertex buffers.
GetVertexBuffers()158     const Vector<SharedPtr<VertexBuffer> >& GetVertexBuffers() const { return vertexBuffers_; }
159 
160     /// Return index buffers.
GetIndexBuffers()161     const Vector<SharedPtr<IndexBuffer> >& GetIndexBuffers() const { return indexBuffers_; }
162 
163     /// Return number of geometries.
GetNumGeometries()164     unsigned GetNumGeometries() const { return geometries_.Size(); }
165 
166     /// Return number of LOD levels in geometry.
167     unsigned GetNumGeometryLodLevels(unsigned index) const;
168 
169     /// Return geometry pointers.
GetGeometries()170     const Vector<Vector<SharedPtr<Geometry> > >& GetGeometries() const { return geometries_; }
171 
172     /// Return geometry center points.
GetGeometryCenters()173     const PODVector<Vector3>& GetGeometryCenters() const { return geometryCenters_; }
174 
175     /// Return geometry by index and LOD level. The LOD level is clamped if out of range.
176     Geometry* GetGeometry(unsigned index, unsigned lodLevel) const;
177 
178     /// Return geometry center by index.
GetGeometryCenter(unsigned index)179     const Vector3& GetGeometryCenter(unsigned index) const
180     {
181         return index < geometryCenters_.Size() ? geometryCenters_[index] : Vector3::ZERO;
182     }
183 
184     /// Return geometery bone mappings.
GetGeometryBoneMappings()185     const Vector<PODVector<unsigned> >& GetGeometryBoneMappings() const { return geometryBoneMappings_; }
186 
187     /// Return vertex morphs.
GetMorphs()188     const Vector<ModelMorph>& GetMorphs() const { return morphs_; }
189 
190     /// Return number of vertex morphs.
GetNumMorphs()191     unsigned GetNumMorphs() const { return morphs_.Size(); }
192 
193     /// Return vertex morph by index.
194     const ModelMorph* GetMorph(unsigned index) const;
195     /// Return vertex morph by name.
196     const ModelMorph* GetMorph(const String& name) const;
197     /// Return vertex morph by name hash.
198     const ModelMorph* GetMorph(StringHash nameHash) const;
199     /// Return vertex buffer morph range start.
200     unsigned GetMorphRangeStart(unsigned bufferIndex) const;
201     /// Return vertex buffer morph range vertex count.
202     unsigned GetMorphRangeCount(unsigned bufferIndex) const;
203 
204 private:
205     /// Bounding box.
206     BoundingBox boundingBox_;
207     /// Skeleton.
208     Skeleton skeleton_;
209     /// Vertex buffers.
210     Vector<SharedPtr<VertexBuffer> > vertexBuffers_;
211     /// Index buffers.
212     Vector<SharedPtr<IndexBuffer> > indexBuffers_;
213     /// Geometries.
214     Vector<Vector<SharedPtr<Geometry> > > geometries_;
215     /// Geometry bone mappings.
216     Vector<PODVector<unsigned> > geometryBoneMappings_;
217     /// Geometry centers.
218     PODVector<Vector3> geometryCenters_;
219     /// Vertex morphs.
220     Vector<ModelMorph> morphs_;
221     /// Vertex buffer morph range start.
222     PODVector<unsigned> morphRangeStarts_;
223     /// Vertex buffer morph range vertex count.
224     PODVector<unsigned> morphRangeCounts_;
225     /// Vertex buffer data for asynchronous loading.
226     Vector<VertexBufferDesc> loadVBData_;
227     /// Index buffer data for asynchronous loading.
228     Vector<IndexBufferDesc> loadIBData_;
229     /// Geometry definitions for asynchronous loading.
230     Vector<PODVector<GeometryDesc> > loadGeometries_;
231 };
232 
233 }
234