mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Fixed loading of flipped and duplicate images in animations
This commit is contained in:
		| @@ -28,7 +28,7 @@ bool CAnimation::loadFrame(size_t frame, size_t group) | |||||||
| 	if(auto image = getImageImpl(frame, group, false)) | 	if(auto image = getImageImpl(frame, group, false)) | ||||||
| 		return true; | 		return true; | ||||||
|  |  | ||||||
| 	std::shared_ptr<IImage> image = GH.renderHandler().loadImage(source[group][frame], mode); | 	std::shared_ptr<IImage> image = GH.renderHandler().loadImage(getImageLocator(frame, group), mode); | ||||||
|  |  | ||||||
| 	if(image) | 	if(image) | ||||||
| 	{ | 	{ | ||||||
| @@ -109,19 +109,7 @@ CAnimation::~CAnimation() = default; | |||||||
|  |  | ||||||
| void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup) | void CAnimation::duplicateImage(const size_t sourceGroup, const size_t sourceFrame, const size_t targetGroup) | ||||||
| { | { | ||||||
| 	if(!source.count(sourceGroup)) | 	ImageLocator clone(getImageLocator(sourceFrame, sourceGroup)); | ||||||
| 	{ |  | ||||||
| 		logAnim->error("Group %d missing in %s", sourceGroup, name.getName()); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	if(source[sourceGroup].size() <= sourceFrame) |  | ||||||
| 	{ |  | ||||||
| 		logAnim->error("Frame [%d %d] missing in %s", sourceGroup, sourceFrame, name.getName()); |  | ||||||
| 		return; |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
| 	ImageLocator clone(source[sourceGroup][sourceFrame]); |  | ||||||
| 	source[targetGroup].push_back(clone); | 	source[targetGroup].push_back(clone); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -179,8 +167,9 @@ void CAnimation::horizontalFlip(size_t frame, size_t group) | |||||||
| 		// ignore - image not loaded | 		// ignore - image not loaded | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ImageLocator & locator = source.at(group).at(frame); | 	auto locator = getImageLocator(frame, group); | ||||||
| 	locator.horizontalFlip = !locator.horizontalFlip; | 	locator.horizontalFlip = !locator.horizontalFlip; | ||||||
|  | 	source[group][frame] = locator; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CAnimation::verticalFlip(size_t frame, size_t group) | void CAnimation::verticalFlip(size_t frame, size_t group) | ||||||
| @@ -194,8 +183,9 @@ void CAnimation::verticalFlip(size_t frame, size_t group) | |||||||
| 		// ignore - image not loaded | 		// ignore - image not loaded | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| 	ImageLocator & locator = source.at(group).at(frame); | 	auto locator = getImageLocator(frame, group); | ||||||
| 	locator.verticalFlip = !locator.verticalFlip; | 	locator.verticalFlip = !locator.verticalFlip; | ||||||
|  | 	source[group][frame] = locator; | ||||||
| } | } | ||||||
|  |  | ||||||
| void CAnimation::playerColored(PlayerColor player) | void CAnimation::playerColored(PlayerColor player) | ||||||
| @@ -213,3 +203,13 @@ void CAnimation::createFlippedGroup(const size_t sourceGroup, const size_t targe | |||||||
| 		verticalFlip(frame, targetGroup); | 		verticalFlip(frame, targetGroup); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
|  | ImageLocator CAnimation::getImageLocator(size_t frame, size_t group) const | ||||||
|  | { | ||||||
|  | 	const ImageLocator & locator = source.at(group).at(frame); | ||||||
|  |  | ||||||
|  | 	if (!locator.empty()) | ||||||
|  | 		return locator; | ||||||
|  |  | ||||||
|  | 	return ImageLocator(name, frame, group); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -50,6 +50,8 @@ private: | |||||||
| 	void printError(size_t frame, size_t group, std::string type) const; | 	void printError(size_t frame, size_t group, std::string type) const; | ||||||
|  |  | ||||||
| 	std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true); | 	std::shared_ptr<IImage> getImageImpl(size_t frame, size_t group=0, bool verbose=true); | ||||||
|  |  | ||||||
|  | 	ImageLocator getImageLocator(size_t frame, size_t group) const; | ||||||
| public: | public: | ||||||
| 	CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <ImageLocator> > layout, EImageBlitMode mode); | 	CAnimation(const AnimationPath & Name, std::map<size_t, std::vector <ImageLocator> > layout, EImageBlitMode mode); | ||||||
| 	~CAnimation(); | 	~CAnimation(); | ||||||
|   | |||||||
| @@ -49,3 +49,8 @@ bool ImageLocator::operator<(const ImageLocator & other) const | |||||||
| 		return verticalFlip < other.verticalFlip; | 		return verticalFlip < other.verticalFlip; | ||||||
| 	return horizontalFlip < other.horizontalFlip; | 	return horizontalFlip < other.horizontalFlip; | ||||||
| } | } | ||||||
|  |  | ||||||
|  | bool ImageLocator::empty() const | ||||||
|  | { | ||||||
|  | 	return !image.has_value() && !defFile.has_value(); | ||||||
|  | } | ||||||
|   | |||||||
| @@ -22,8 +22,10 @@ struct ImageLocator | |||||||
| 	bool horizontalFlip = false; | 	bool horizontalFlip = false; | ||||||
|  |  | ||||||
| 	ImageLocator() = default; | 	ImageLocator() = default; | ||||||
| 	ImageLocator(const JsonNode & config); |  | ||||||
| 	ImageLocator(const ImagePath & path); |  | ||||||
| 	ImageLocator(const AnimationPath & path, int frame, int group); | 	ImageLocator(const AnimationPath & path, int frame, int group); | ||||||
|  | 	explicit ImageLocator(const JsonNode & config); | ||||||
|  | 	explicit ImageLocator(const ImagePath & path); | ||||||
|  |  | ||||||
| 	bool operator < (const ImageLocator & other) const; | 	bool operator < (const ImageLocator & other) const; | ||||||
|  | 	bool empty() const; | ||||||
| }; | }; | ||||||
|   | |||||||
| @@ -68,7 +68,7 @@ void RenderHandler::initFromJson(AnimationLayoutMap & source, const JsonNode & c | |||||||
| 			JsonNode toAdd; | 			JsonNode toAdd; | ||||||
| 			JsonUtils::inherit(toAdd, base); | 			JsonUtils::inherit(toAdd, base); | ||||||
| 			toAdd["file"].String() = basepath + frame.String(); | 			toAdd["file"].String() = basepath + frame.String(); | ||||||
| 			source[groupID].push_back(toAdd); | 			source[groupID].push_back(ImageLocator(toAdd)); | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -83,7 +83,7 @@ void RenderHandler::initFromJson(AnimationLayoutMap & source, const JsonNode & c | |||||||
| 		JsonNode toAdd; | 		JsonNode toAdd; | ||||||
| 		JsonUtils::inherit(toAdd, base); | 		JsonUtils::inherit(toAdd, base); | ||||||
| 		toAdd["file"].String() = basepath + node["file"].String(); | 		toAdd["file"].String() = basepath + node["file"].String(); | ||||||
| 		source[group][frame] = toAdd; | 		source[group][frame] = ImageLocator(toAdd); | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -141,10 +141,10 @@ std::shared_ptr<IConstImage> RenderHandler::loadImageFromAnimationFileUncached(c | |||||||
| 	if (frame >= layout.at(group).size()) | 	if (frame >= layout.at(group).size()) | ||||||
| 		return loadImageFromSingleFile(ImagePath::builtin("DEFAULT")); | 		return loadImageFromSingleFile(ImagePath::builtin("DEFAULT")); | ||||||
|  |  | ||||||
| 	const auto & config = layout.at(group).at(frame); | 	const auto & locator = layout.at(group).at(frame); | ||||||
| 	if (config.image) | 	if (locator.image) | ||||||
| 	{ | 	{ | ||||||
| 		return loadImageImpl(ImageLocator(config)); | 		return loadImageImpl(locator); | ||||||
| 	} | 	} | ||||||
| 	else | 	else | ||||||
| 	{ | 	{ | ||||||
| @@ -168,7 +168,7 @@ std::shared_ptr<IConstImage> RenderHandler::loadImageImpl(const ImageLocator & l | |||||||
|  |  | ||||||
| 	std::shared_ptr<IConstImage> result; | 	std::shared_ptr<IConstImage> result; | ||||||
|  |  | ||||||
| 	if (!locator.image) | 	if (locator.image) | ||||||
| 		result = loadImageFromSingleFile(*locator.image); | 		result = loadImageFromSingleFile(*locator.image); | ||||||
| 	else if (locator.defFile) | 	else if (locator.defFile) | ||||||
| 		result = loadImageFromAnimationFile(*locator.defFile, locator.defFrame, locator.defGroup); | 		result = loadImageFromAnimationFile(*locator.defFile, locator.defFrame, locator.defGroup); | ||||||
| @@ -228,7 +228,7 @@ void RenderHandler::addImageListEntries(const EntityService * service) | |||||||
| 			if (index >= layout[group].size()) | 			if (index >= layout[group].size()) | ||||||
| 				layout[group].resize(index + 1); | 				layout[group].resize(index + 1); | ||||||
|  |  | ||||||
| 			layout[group][index] = entry; | 			layout[group][index] = ImageLocator(entry); | ||||||
| 		}); | 		}); | ||||||
| 	}); | 	}); | ||||||
| } | } | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user