ImageAtlasResource.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. // Copyright (C) 2009-2021, Panagiotis Christopoulos Charitos and contributors.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #include <AnKi/Resource/ImageAtlasResource.h>
  6. #include <AnKi/Resource/ResourceManager.h>
  7. #include <AnKi/Util/Xml.h>
  8. namespace anki
  9. {
  10. ImageAtlasResource::ImageAtlasResource(ResourceManager* manager)
  11. : ResourceObject(manager)
  12. {
  13. }
  14. ImageAtlasResource::~ImageAtlasResource()
  15. {
  16. m_subTexes.destroy(getAllocator());
  17. m_subTexNames.destroy(getAllocator());
  18. }
  19. Error ImageAtlasResource::load(const ResourceFilename& filename, Bool async)
  20. {
  21. XmlDocument doc;
  22. ANKI_CHECK(openFileParseXml(filename, doc));
  23. XmlElement rootel, el;
  24. //
  25. // <imageAtlas>
  26. //
  27. ANKI_CHECK(doc.getChildElement("imageAtlas", rootel));
  28. //
  29. // <image>
  30. //
  31. ANKI_CHECK(rootel.getChildElement("image", el));
  32. CString texFname;
  33. ANKI_CHECK(el.getText(texFname));
  34. ANKI_CHECK(getManager().loadResource<ImageResource>(texFname, m_image, async));
  35. m_size[0] = m_image->getWidth();
  36. m_size[1] = m_image->getHeight();
  37. //
  38. // <subImageMargin>
  39. //
  40. ANKI_CHECK(rootel.getChildElement("subImageMargin", el));
  41. I64 margin = 0;
  42. ANKI_CHECK(el.getNumber(margin));
  43. if(margin >= I(m_image->getWidth()) || margin >= I(m_image->getHeight()) || margin < 0)
  44. {
  45. ANKI_RESOURCE_LOGE("Too big margin %d", I32(margin));
  46. return Error::USER_DATA;
  47. }
  48. m_margin = U32(margin);
  49. //
  50. // <subImages>
  51. //
  52. // Get counts
  53. U32 namesSize = 0;
  54. U32 subTexesCount = 0;
  55. XmlElement subTexesEl, subTexEl;
  56. ANKI_CHECK(rootel.getChildElement("subImages", subTexesEl));
  57. ANKI_CHECK(subTexesEl.getChildElement("subImage", subTexEl));
  58. do
  59. {
  60. ANKI_CHECK(subTexEl.getChildElement("name", el));
  61. CString name;
  62. ANKI_CHECK(el.getText(name));
  63. if(name.getLength() < 1)
  64. {
  65. ANKI_RESOURCE_LOGE("Something wrong with the <name> tag. Probably empty");
  66. return Error::USER_DATA;
  67. }
  68. namesSize += U32(name.getLength()) + 1;
  69. ++subTexesCount;
  70. ANKI_CHECK(subTexEl.getNextSiblingElement("subImage", subTexEl));
  71. } while(subTexEl);
  72. // Allocate
  73. m_subTexNames.create(getAllocator(), namesSize);
  74. m_subTexes.create(getAllocator(), subTexesCount);
  75. // Iterate again and populate
  76. subTexesCount = 0;
  77. char* names = &m_subTexNames[0];
  78. ANKI_CHECK(subTexesEl.getChildElement("subImage", subTexEl));
  79. do
  80. {
  81. ANKI_CHECK(subTexEl.getChildElement("name", el));
  82. CString name;
  83. ANKI_CHECK(el.getText(name));
  84. memcpy(names, &name[0], name.getLength() + 1);
  85. m_subTexes[subTexesCount].m_name = names;
  86. ANKI_CHECK(subTexEl.getChildElement("uv", el));
  87. Vec4 uv;
  88. ANKI_CHECK(el.getNumbers(uv));
  89. m_subTexes[subTexesCount].m_uv = {uv[0], uv[1], uv[2], uv[3]};
  90. names += name.getLength() + 1;
  91. ++subTexesCount;
  92. ANKI_CHECK(subTexEl.getNextSiblingElement("subImage", subTexEl));
  93. } while(subTexEl);
  94. return Error::NONE;
  95. }
  96. Error ImageAtlasResource::getSubImageInfo(CString name, F32 uv[4]) const
  97. {
  98. for(const SubTex& st : m_subTexes)
  99. {
  100. if(st.m_name == name)
  101. {
  102. uv[0] = st.m_uv[0];
  103. uv[1] = st.m_uv[1];
  104. uv[2] = st.m_uv[2];
  105. uv[3] = st.m_uv[3];
  106. return Error::NONE;
  107. }
  108. }
  109. ANKI_RESOURCE_LOGE("Image atlas %s doesn't have sub image named: %s", &getFilename()[0], &name[0]);
  110. return Error::USER_DATA;
  111. }
  112. } // end namespace anki