CCSprite3D.h 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  1. /****************************************************************************
  2. Copyright (c) 2014-2017 Chukong Technologies Inc.
  3. http://www.cocos2d-x.org
  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. The above copyright notice and this permission notice shall be included in
  11. all copies or substantial portions of the Software.
  12. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  13. IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  14. FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  15. AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  16. LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  17. OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  18. THE SOFTWARE.
  19. ****************************************************************************/
  20. #ifndef __CCSPRITE3D_H__
  21. #define __CCSPRITE3D_H__
  22. #include <unordered_map>
  23. #include "base/CCVector.h"
  24. #include "base/ccTypes.h"
  25. #include "base/CCProtocols.h"
  26. #include "2d/CCNode.h"
  27. #include "renderer/CCMeshCommand.h"
  28. #include "renderer/CCGLProgramState.h"
  29. #include "3d/CCSkeleton3D.h" // need to include for lua-binding
  30. #include "3d/CCAABB.h"
  31. #include "3d/CCBundle3DData.h"
  32. #include "3d/CCMeshVertexIndexData.h"
  33. NS_CC_BEGIN
  34. /**
  35. * @addtogroup _3d
  36. * @{
  37. */
  38. class Mesh;
  39. class Texture2D;
  40. class MeshSkin;
  41. class AttachNode;
  42. struct NodeData;
  43. /** @brief Sprite3D: A sprite can be loaded from 3D model files, .obj, .c3t, .c3b, then can be drawn as sprite */
  44. class CC_DLL Sprite3D : public Node, public BlendProtocol
  45. {
  46. public:
  47. /**
  48. * Creates an empty sprite3D without 3D model and texture.
  49. *
  50. * @return An autoreleased sprite3D object.
  51. */
  52. static Sprite3D* create();
  53. /** creates a Sprite3D*/
  54. static Sprite3D* create(const std::string &modelPath);
  55. // creates a Sprite3D. It only supports one texture, and overrides the internal texture with 'texturePath'
  56. static Sprite3D* create(const std::string &modelPath, const std::string &texturePath);
  57. /** create 3d sprite asynchronously
  58. * If the 3d model was previously loaded, it will create a new 3d sprite and the callback will be called at once.
  59. * Otherwise it will load the model file in a new thread, and when the 3d sprite is loaded, the callback will be called with the created Sprite3D and a user-defined parameter.
  60. * The callback will be called from the main thread, so it is safe to create any cocos2d object from the callback.
  61. * @param modelPath model to be loaded
  62. * @param callback callback after loading
  63. * @param callbackparam user defined parameter for the callback
  64. */
  65. static void createAsync(const std::string &modelPath, const std::function<void(Sprite3D*, void*)>& callback, void* callbackparam);
  66. static void createAsync(const std::string &modelPath, const std::string &texturePath, const std::function<void(Sprite3D*, void*)>& callback, void* callbackparam);
  67. /**set diffuse texture, set the first if multiple textures exist*/
  68. void setTexture(const std::string& texFile);
  69. void setTexture(Texture2D* texture);
  70. /**get Mesh by index*/
  71. Mesh* getMeshByIndex(int index) const;
  72. /**get Mesh by Name, it returns the first one if there are more than one mesh with the same name */
  73. Mesh* getMeshByName(const std::string& name) const;
  74. /**
  75. * get mesh array by name, returns all meshes with the given name
  76. *
  77. * @lua NA
  78. */
  79. std::vector<Mesh*> getMeshArrayByName(const std::string& name) const;
  80. /**get mesh*/
  81. Mesh* getMesh() const;
  82. /** get mesh count */
  83. ssize_t getMeshCount() const { return _meshes.size(); }
  84. /**get skin*/
  85. CC_DEPRECATED_ATTRIBUTE MeshSkin* getSkin() const;
  86. Skeleton3D* getSkeleton() const { return _skeleton; }
  87. /**get AttachNode by bone name, return nullptr if not exist*/
  88. AttachNode* getAttachNode(const std::string& boneName);
  89. /**remove attach node*/
  90. void removeAttachNode(const std::string& boneName);
  91. /**remove all attach nodes*/
  92. void removeAllAttachNode();
  93. // overrides
  94. virtual void setBlendFunc(const BlendFunc &blendFunc) override;
  95. virtual const BlendFunc &getBlendFunc() const override;
  96. // overrides
  97. /** set GLProgramState, you should bind attributes by yourself */
  98. virtual void setGLProgramState(GLProgramState *glProgramState) override;
  99. /** just remember bind attributes */
  100. virtual void setGLProgram(GLProgram *glprogram) override;
  101. /*
  102. * Get AABB
  103. * If the sprite has animation, it can't be calculated accurately,
  104. * because bone can drive the vertices, we just use the origin vertices
  105. * to calculate the AABB.
  106. */
  107. const AABB& getAABB() const;
  108. /*
  109. * Get AABB Recursively
  110. * Because some times we may have an empty Sprite3D Node as parent, but
  111. * the Sprite3D don't contain any meshes, so getAABB()
  112. * will return a wrong value at that time.
  113. */
  114. AABB getAABBRecursively();
  115. /**
  116. * Executes an action, and returns the action that is executed. For Sprite3D special logic are needed to take care of Fading.
  117. *
  118. * This node becomes the action's target. Refer to Action::getTarget()
  119. * @warning Actions don't retain their target.
  120. *
  121. * @return An Action pointer
  122. */
  123. virtual Action* runAction(Action* action) override;
  124. /**
  125. * Force to write to depth buffer, this is useful if you want to achieve effects like fading.
  126. */
  127. void setForceDepthWrite(bool value) { _forceDepthWrite = value; }
  128. bool isForceDepthWrite() const { return _forceDepthWrite;};
  129. /**
  130. * Returns 2d bounding-box
  131. * Note: the bounding-box is just get from the AABB which as Z=0, so that is not very accurate.
  132. */
  133. virtual Rect getBoundingBox() const override;
  134. // set which face is going to cull, GL_BACK, GL_FRONT, GL_FRONT_AND_BACK, default GL_BACK
  135. void setCullFace(GLenum cullFace);
  136. // set cull face enable or not
  137. void setCullFaceEnabled(bool enable);
  138. /** light mask getter & setter, light works only when _lightmask & light's flag is true, default value of _lightmask is 0xffff */
  139. void setLightMask(unsigned int mask) { _lightMask = mask; }
  140. unsigned int getLightMask() const { return _lightMask; }
  141. /**draw*/
  142. virtual void draw(Renderer *renderer, const Mat4 &transform, uint32_t flags) override;
  143. /** Adds a new material to the sprite.
  144. The Material will be applied to all the meshes that belong to the sprite.
  145. Internally it will call `setMaterial(material,-1)`
  146. */
  147. void setMaterial(Material* material);
  148. /** Adds a new material to a particular mesh of the sprite.
  149. meshIndex is the mesh that will be applied to.
  150. if meshIndex == -1, then it will be applied to all the meshes that belong to the sprite.
  151. */
  152. void setMaterial(Material* material, int meshIndex);
  153. /** Adds a new material to a particular mesh of the sprite.
  154. meshIndex is the mesh that will be applied to.
  155. if meshIndex == -1, then it will be applied to all the meshes that belong to the sprite.
  156. */
  157. Material* getMaterial(int meshIndex) const;
  158. /**
  159. * force set this Sprite3D to 2D render queue
  160. */
  161. void setForce2DQueue(bool force2D);
  162. /**
  163. * Get meshes used in sprite 3d
  164. */
  165. const Vector<Mesh*>& getMeshes() const { return _meshes; }
  166. CC_CONSTRUCTOR_ACCESS:
  167. Sprite3D();
  168. virtual ~Sprite3D();
  169. virtual bool init() override;
  170. bool initWithFile(const std::string &path);
  171. bool initFrom(const NodeDatas& nodedatas, const MeshDatas& meshdatas, const MaterialDatas& materialdatas);
  172. /**load sprite3d from cache, return true if succeed, false otherwise*/
  173. bool loadFromCache(const std::string& path);
  174. /** load file and set it to meshedatas, nodedatas and materialdatas, obj file .mtl file should be at the same directory if exist */
  175. bool loadFromFile(const std::string& path, NodeDatas* nodedatas, MeshDatas* meshdatas, MaterialDatas* materialdatas);
  176. /**
  177. * Visits this Sprite3D's children and draw them recursively.
  178. * Note: all its children will rendered as 3D objects
  179. */
  180. virtual void visit(Renderer *renderer, const Mat4& parentTransform, uint32_t parentFlags) override;
  181. /**generate default material*/
  182. void genMaterial(bool useLight = false);
  183. void createNode(NodeData* nodedata, Node* root, const MaterialDatas& materialdatas, bool singleSprite);
  184. void createAttachSprite3DNode(NodeData* nodedata, const MaterialDatas& materialdatas);
  185. Sprite3D* createSprite3DNode(NodeData* nodedata, ModelData* modeldata, const MaterialDatas& materialdatas);
  186. /**get MeshIndexData by Id*/
  187. MeshIndexData* getMeshIndexData(const std::string& indexId) const;
  188. void addMesh(Mesh* mesh);
  189. void onAABBDirty() { _aabbDirty = true; }
  190. void afterAsyncLoad(void* param);
  191. static AABB getAABBRecursivelyImp(Node *node);
  192. protected:
  193. Skeleton3D* _skeleton; //skeleton
  194. Vector<MeshVertexData*> _meshVertexDatas;
  195. std::unordered_map<std::string, AttachNode*> _attachments;
  196. BlendFunc _blend;
  197. Vector<Mesh*> _meshes;
  198. mutable AABB _aabb; // cache current aabb
  199. mutable Mat4 _nodeToWorldTransform; // cache the matrix
  200. mutable bool _aabbDirty;
  201. unsigned int _lightMask;
  202. bool _shaderUsingLight; // is current shader using light ?
  203. bool _forceDepthWrite; // Always write to depth buffer
  204. bool _usingAutogeneratedGLProgram;
  205. struct AsyncLoadParam
  206. {
  207. std::function<void(Sprite3D*, void*)> afterLoadCallback; // callback after load
  208. void* callbackParam;
  209. bool result; // sprite load result
  210. std::string modelPath;
  211. std::string texPath; //
  212. MeshDatas* meshdatas;
  213. MaterialDatas* materialdatas;
  214. NodeDatas* nodeDatas;
  215. };
  216. AsyncLoadParam _asyncLoadParam;
  217. };
  218. ///////////////////////////////////////////////////////
  219. /**
  220. * Sprite3DCache
  221. * @brief the cache data of Sprite3D, use to speed up Sprite3D::create
  222. */
  223. class CC_DLL Sprite3DCache
  224. {
  225. public:
  226. struct Sprite3DData
  227. {
  228. Vector<MeshVertexData*> meshVertexDatas;
  229. Vector<GLProgramState*> glProgramStates;
  230. NodeDatas* nodedatas;
  231. MaterialDatas* materialdatas;
  232. ~Sprite3DData()
  233. {
  234. if (nodedatas)
  235. delete nodedatas;
  236. if (materialdatas)
  237. delete materialdatas;
  238. meshVertexDatas.clear();
  239. glProgramStates.clear();
  240. }
  241. };
  242. /**get & destroy*/
  243. static Sprite3DCache* getInstance();
  244. static void destroyInstance();
  245. /**
  246. * get the SpriteData struct
  247. *
  248. * @lua NA
  249. */
  250. Sprite3DData* getSpriteData(const std::string& key) const;
  251. /**
  252. * add the SpriteData into Sprite3D by given the specified key
  253. *
  254. * @lua NA
  255. */
  256. bool addSprite3DData(const std::string& key, Sprite3DData* spritedata);
  257. /**remove the SpriteData from Sprite3D by given the specified key*/
  258. void removeSprite3DData(const std::string& key);
  259. /**remove all the SpriteData from Sprite3D*/
  260. void removeAllSprite3DData();
  261. CC_CONSTRUCTOR_ACCESS:
  262. Sprite3DCache();
  263. ~Sprite3DCache();
  264. protected:
  265. static Sprite3DCache* _cacheInstance;
  266. std::unordered_map<std::string, Sprite3DData*> _spriteDatas; //cached sprite data
  267. };
  268. // end of 3d group
  269. /// @}
  270. NS_CC_END
  271. #endif // __SPRITE3D_H_