30 #include "ext/tinyxml/fife_tinyxml.h"
31 #include "model/model.h"
32 #include "model/structures/layer.h"
33 #include "vfs/fife_boost_filesystem.h"
35 #include "vfs/raw/rawdata.h"
36 #include "util/base/exception.h"
37 #include "util/log/logger.h"
38 #include "util/resource/resource.h"
39 #include "util/resource/resourcemanager.h"
40 #include "view/visual.h"
42 #include "atlasloader.h"
45 static Logger _log(LM_NATIVE_LOADERS);
48 size_t Atlas::getImageCount()
const {
49 return m_subimages.size();
52 ImagePtr& Atlas::getPackedImage() {
56 ImagePtr Atlas::getImage(
const std::string&
id) {
57 SubimageMap::iterator iter = m_subimages.find(
id);
58 if(iter == m_subimages.end())
60 return iter->second.image;
63 ImagePtr Atlas::getImage(uint32_t index) {
64 if(index > getImageCount())
67 SubimageMap::iterator iter = m_subimages.begin();
68 for(uint32_t i = 0; i < index; ++i, ++iter);
69 return iter->second.image;
72 bool Atlas::addImage(
const std::string& imagename,
const AtlasData& data) {
73 return m_subimages.insert(std::pair<std::string, AtlasData>(imagename, data)).second;
76 void Atlas::setPackedImage(
const ImagePtr& image) {
80 const std::string& Atlas::getName()
const {
84 AtlasLoader::AtlasLoader(Model* model, VFS* vfs, ImageManager* imageManager)
85 : m_model(model), m_vfs(vfs), m_imageManager(imageManager) {
88 AtlasLoader::~AtlasLoader() {
91 bool AtlasLoader::isLoadable(
const std::string& filename) {
92 bfs::path atlasPath(filename);
93 std::string atlasFilename = atlasPath.string();
97 RawData* data = m_vfs->open(atlasFilename);
100 if (data->getDataLength() != 0) {
101 atlasFile.
Parse(data->readString(data->getDataLength()).c_str());
103 if (atlasFile.
Error()) {
114 }
catch (NotFound&) {
121 if (root && root->ValueStr() ==
"atlas") {
129 AtlasPtr AtlasLoader::load(
const std::string& filename) {
130 bfs::path atlasPath(filename);
131 bfs::path atlasPathDirectory;
132 m_atlasFilename = atlasPath.string();
134 if (HasParentPath(atlasPath)) {
143 RawData* data = m_vfs->open(m_atlasFilename);
146 if (data->getDataLength() != 0) {
147 doc.
Parse(data->readString(data->getDataLength()).c_str());
159 catch (NotFound& e) {
160 FL_ERR(_log, e.what());
173 if (root && root->ValueStr() ==
"atlas") {
174 const std::string* atlasName = root->
Attribute(std::string(
"name"));
176 const std::string* namespaceId = root->
Attribute(std::string(
"namespace"));
178 namespaceId = atlasName;
182 bfs::path atlasImagePath = atlasPathDirectory / *atlasName;
183 atlas.reset(
new Atlas(atlasImagePath.string()));
189 bool atlasExists = m_imageManager->exists(atlas->getName());
192 atlas->setPackedImage(m_imageManager->create(atlas->getName()));
195 atlas->setPackedImage(m_imageManager->getPtr(atlas->getName()));
202 bool subsExists =
true;
207 imageElem->QueryValueAttribute(
"xpos", ®ion.x);
208 imageElem->QueryValueAttribute(
"ypos", ®ion.y);
209 imageElem->QueryValueAttribute(
"width", ®ion.w);
210 imageElem->QueryValueAttribute(
"height", ®ion.h);
212 const std::string* subimageName = imageElem->Attribute(std::string(
"source"));
215 std::string finalname = *namespaceId +
":" +*subimageName;
218 bool subExists = m_imageManager->exists(finalname);
221 subImage = m_imageManager->create(finalname);
224 subImage = m_imageManager->getPtr(finalname);
228 AtlasData atlas_data = {region, subImage};
229 atlas->addImage(finalname, atlas_data);
232 subsExists = subsExists && atlasExists;
239 if(objElem->ValueStr() ==
"object") {
240 parseObject(atlas.get(), objElem, subsExists);
249 void AtlasLoader::parseObject(Atlas* atlas,
TiXmlElement* root,
bool exists) {
250 const std::string* objectId = root->
Attribute(std::string(
"id"));
251 const std::string* namespaceId = root->
Attribute(std::string(
"namespace"));
254 if (objectId && namespaceId) {
255 const std::string* parentId = root->
Attribute(std::string(
"parent"));
258 Object* parent = m_model->getObject(*parentId, *namespaceId);
261 obj = m_model->createObject(*objectId, *namespaceId, parent);
271 if (m_model->getObject(*objectId, *namespaceId) == NULL) {
273 obj = m_model->createObject(*objectId, *namespaceId);
280 }
else if (!exists) {
281 obj = m_model->getObject(*objectId, *namespaceId);
282 ObjectVisual* objVisual = obj->getVisual<ObjectVisual>();
285 objVisual = ObjectVisual::create(obj);
289 const std::string* sourceId = imageElement->Attribute(std::string(
"source"));
292 std::string source = *namespaceId +
":" + *sourceId;
293 if(!m_imageManager->exists(source)) {
294 throw NotFound(source +
" couldn't be found.");
296 ImagePtr imagePtr = m_imageManager->getPtr(source);
299 int success = imageElement->QueryIntAttribute(
"x_offset", &xOffset);
300 if (success == TIXML_SUCCESS) {
301 imagePtr->setXShift(xOffset);
305 success = imageElement->QueryIntAttribute(
"y_offset", &yOffset);
306 if (success == TIXML_SUCCESS) {
307 imagePtr->setYShift(yOffset);
311 success = imageElement->QueryIntAttribute(
"direction", &direction);
312 if (success == TIXML_SUCCESS) {
314 objVisual->addStaticImage(direction, static_cast<int32_t>(imagePtr->getHandle()));
326 obj->setFilename(m_atlasFilename);
327 ObjectVisual::create(obj);
331 obj->setBlocking(isBlocking!=0);
335 obj->setStatic(isStatic!=0);
337 const std::string* pather = root->
Attribute(std::string(
"pather"));
340 obj->setPather(m_model->getPather(*pather));
343 obj->setPather(m_model->getPather(
"RoutePather"));
348 const std::string* sourceId = imageElement->Attribute(std::string(
"source"));
351 std::string source = *namespaceId +
":" + *sourceId;
352 if(!m_imageManager->exists(source)) {
353 throw NotFound(source +
" couldn't be found.");
355 ImagePtr imagePtr = m_imageManager->getPtr(source);
357 int success = imageElement->QueryIntAttribute(
"x_offset", &xOffset);
359 if (success == TIXML_SUCCESS) {
360 imagePtr->setXShift(xOffset);
364 success = imageElement->QueryIntAttribute(
"y_offset", &yOffset);
366 if (success == TIXML_SUCCESS) {
367 imagePtr->setYShift(yOffset);
371 success = imageElement->QueryIntAttribute(
"direction", &direction);
373 if (success == TIXML_SUCCESS) {
374 ObjectVisual* objVisual = obj->getVisual<ObjectVisual>();
377 objVisual->addStaticImage(direction, static_cast<int32_t>(imagePtr->getHandle()));
386 return new AtlasLoader(model, vfs, imageManager);