Lazy-loading of ImageOperation inside Directives
also fixed cases of drawables not staying centered after adding directives that scale
This commit is contained in:
parent
14e23a17cc
commit
4585c9cafa
@ -844,6 +844,10 @@ shared_ptr<Assets::AssetData> Assets::loadImage(AssetPath const& path) const {
|
|||||||
return {};
|
return {};
|
||||||
StringMap<ImageConstPtr> references;
|
StringMap<ImageConstPtr> references;
|
||||||
StringList referencePaths;
|
StringList referencePaths;
|
||||||
|
|
||||||
|
for (auto& directives : path.directives.list())
|
||||||
|
directives.loadOperations();
|
||||||
|
|
||||||
path.directives.forEach([&](auto const& entry, Directives const& directives) {
|
path.directives.forEach([&](auto const& entry, Directives const& directives) {
|
||||||
addImageOperationReferences(entry.operation, referencePaths);
|
addImageOperationReferences(entry.operation, referencePaths);
|
||||||
}); // TODO: This can definitely be better, was changed quickly to support the new Directives.
|
}); // TODO: This can definitely be better, was changed quickly to support the new Directives.
|
||||||
|
@ -39,11 +39,14 @@ AssetPath AssetPath::split(String const& path) {
|
|||||||
// Sub-paths must immediately follow base paths and must start with a ':',
|
// Sub-paths must immediately follow base paths and must start with a ':',
|
||||||
// after this point any further ':' characters are not special.
|
// after this point any further ':' characters are not special.
|
||||||
if (str[end] == ':') {
|
if (str[end] == ':') {
|
||||||
size_t beg = end;
|
size_t beg = end + 1;
|
||||||
end = str.find_first_of("?", beg);
|
if (beg != str.size()) {
|
||||||
size_t len = end - beg - 1;
|
end = str.find_first_of("?", beg);
|
||||||
if (len)
|
if (end == NPos && beg + 1 != str.size())
|
||||||
components.subPath.emplace(str.substr(beg + 1, len));
|
components.subPath.emplace(str.substr(beg));
|
||||||
|
else if (size_t len = end - beg)
|
||||||
|
components.subPath.emplace(str.substr(beg, len));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (end == NPos)
|
if (end == NPos)
|
||||||
|
@ -24,6 +24,14 @@ Directives::Entry::Entry(Entry const& other) {
|
|||||||
length = other.length;
|
length = other.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImageOperation const& Directives::Entry::loadOperation(Shared const& parent) const {
|
||||||
|
if (operation.is<NullImageOperation>()) {
|
||||||
|
try { operation = imageOperationFromString(string(parent)); }
|
||||||
|
catch (StarException const& e) { operation = ErrorImageOperation{ std::current_exception() }; }
|
||||||
|
}
|
||||||
|
return operation;
|
||||||
|
}
|
||||||
|
|
||||||
StringView Directives::Entry::string(Shared const& parent) const {
|
StringView Directives::Entry::string(Shared const& parent) const {
|
||||||
StringView result = parent.string;
|
StringView result = parent.string;
|
||||||
result = result.utf8().substr(begin, length);
|
result = result.utf8().substr(begin, length);
|
||||||
@ -54,6 +62,15 @@ Directives::Directives(const char* directives) {
|
|||||||
parse(directives);
|
parse(directives);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Directives::loadOperations() const {
|
||||||
|
if (!shared)
|
||||||
|
return;
|
||||||
|
|
||||||
|
MutexLocker lock(shared->mutex, true);
|
||||||
|
for (auto& entry : shared->entries)
|
||||||
|
entry.loadOperation(*shared);
|
||||||
|
}
|
||||||
|
|
||||||
void Directives::parse(String&& directives) {
|
void Directives::parse(String&& directives) {
|
||||||
if (directives.empty())
|
if (directives.empty())
|
||||||
return;
|
return;
|
||||||
@ -63,15 +80,19 @@ void Directives::parse(String&& directives) {
|
|||||||
StringView prefix = "";
|
StringView prefix = "";
|
||||||
view.forEachSplitView("?", [&](StringView split, size_t beg, size_t end) {
|
view.forEachSplitView("?", [&](StringView split, size_t beg, size_t end) {
|
||||||
if (!split.empty()) {
|
if (!split.empty()) {
|
||||||
try {
|
if (beg == 0) {
|
||||||
ImageOperation operation = imageOperationFromString(split);
|
try {
|
||||||
newList.emplace_back(move(operation), beg, end);
|
ImageOperation operation = imageOperationFromString(split);
|
||||||
}
|
newList.emplace_back(move(operation), beg, end);
|
||||||
catch (StarException const& e) {
|
}
|
||||||
if (beg == 0)
|
catch (StarException const& e) {
|
||||||
prefix = split;
|
prefix = split;
|
||||||
else
|
return;
|
||||||
newList.emplace_back(ErrorImageOperation{ std::current_exception() }, beg, end);
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ImageOperation operation = NullImageOperation();
|
||||||
|
newList.emplace_back(move(operation), beg, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -259,10 +280,11 @@ inline Image DirectivesGroup::applyNewImage(Image const& image) const {
|
|||||||
|
|
||||||
void DirectivesGroup::applyExistingImage(Image& image) const {
|
void DirectivesGroup::applyExistingImage(Image& image) const {
|
||||||
forEach([&](auto const& entry, Directives const& directives) {
|
forEach([&](auto const& entry, Directives const& directives) {
|
||||||
if (auto error = entry.operation.ptr<ErrorImageOperation>())
|
ImageOperation const& operation = entry.loadOperation(*directives.shared);
|
||||||
|
if (auto error = operation.ptr<ErrorImageOperation>())
|
||||||
std::rethrow_exception(error->exception);
|
std::rethrow_exception(error->exception);
|
||||||
else
|
else
|
||||||
processImageOperation(entry.operation, image);
|
processImageOperation(operation, image);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "StarHash.hpp"
|
#include "StarHash.hpp"
|
||||||
#include "StarDataStream.hpp"
|
#include "StarDataStream.hpp"
|
||||||
#include "StarStringView.hpp"
|
#include "StarStringView.hpp"
|
||||||
|
#include "StarThread.hpp"
|
||||||
|
|
||||||
namespace Star {
|
namespace Star {
|
||||||
|
|
||||||
@ -17,10 +18,11 @@ class Directives {
|
|||||||
public:
|
public:
|
||||||
struct Shared;
|
struct Shared;
|
||||||
struct Entry {
|
struct Entry {
|
||||||
ImageOperation operation;
|
mutable ImageOperation operation;
|
||||||
size_t begin;
|
size_t begin;
|
||||||
size_t length;
|
size_t length;
|
||||||
|
|
||||||
|
ImageOperation const& loadOperation(Shared const& parent) const;
|
||||||
inline StringView string(Shared const& parent) const;
|
inline StringView string(Shared const& parent) const;
|
||||||
Entry(ImageOperation&& newOperation, size_t begin, size_t end);
|
Entry(ImageOperation&& newOperation, size_t begin, size_t end);
|
||||||
Entry(ImageOperation const& newOperation, size_t begin, size_t end);
|
Entry(ImageOperation const& newOperation, size_t begin, size_t end);
|
||||||
@ -32,6 +34,7 @@ public:
|
|||||||
String string;
|
String string;
|
||||||
StringView prefix;
|
StringView prefix;
|
||||||
size_t hash = 0;
|
size_t hash = 0;
|
||||||
|
mutable Mutex mutex;
|
||||||
|
|
||||||
bool empty() const;
|
bool empty() const;
|
||||||
Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix);
|
Shared(List<Entry>&& givenEntries, String&& givenString, StringView givenPrefix);
|
||||||
@ -42,6 +45,7 @@ public:
|
|||||||
Directives(String&& directives);
|
Directives(String&& directives);
|
||||||
Directives(const char* directives);
|
Directives(const char* directives);
|
||||||
|
|
||||||
|
void loadOperations() const;
|
||||||
void parse(String&& directives);
|
void parse(String&& directives);
|
||||||
String string() const;
|
String string() const;
|
||||||
StringView prefix() const;
|
StringView prefix() const;
|
||||||
|
@ -198,8 +198,11 @@ ImageOperation imageOperationFromString(StringView string) {
|
|||||||
else if (hexLen == 8) {
|
else if (hexLen == 8) {
|
||||||
hexDecode(hexPtr, 8, c, 4);
|
hexDecode(hexPtr, 8, c, 4);
|
||||||
}
|
}
|
||||||
else
|
else if (!which || (ptr != end && ++ptr != end))
|
||||||
throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false);
|
throw ImageOperationException(strf("Improper size for hex string '%s' in imageOperationFromString", StringView(hexPtr, hexLen)), false);
|
||||||
|
else // we're in A of A=B. In vanilla only A=B pairs are evaluated, so only throw an exception if B is also there.
|
||||||
|
return move(operation);
|
||||||
|
|
||||||
|
|
||||||
if (which = !which)
|
if (which = !which)
|
||||||
operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b;
|
operation.colorReplaceMap[*(Vec4B*)&a] = *(Vec4B*)&b;
|
||||||
|
@ -18,6 +18,10 @@ Image scaleBicubic(Image const& srcImage, Vec2F const& scale);
|
|||||||
StringList colorDirectivesFromConfig(JsonArray const& directives);
|
StringList colorDirectivesFromConfig(JsonArray const& directives);
|
||||||
String paletteSwapDirectivesFromConfig(Json const& swaps);
|
String paletteSwapDirectivesFromConfig(Json const& swaps);
|
||||||
|
|
||||||
|
struct NullImageOperation {
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
struct ErrorImageOperation {
|
struct ErrorImageOperation {
|
||||||
std::exception_ptr exception;
|
std::exception_ptr exception;
|
||||||
};
|
};
|
||||||
@ -133,7 +137,7 @@ struct FlipImageOperation {
|
|||||||
Mode mode;
|
Mode mode;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Variant<ErrorImageOperation, HueShiftImageOperation, SaturationShiftImageOperation, BrightnessMultiplyImageOperation, FadeToColorImageOperation,
|
typedef Variant<NullImageOperation, ErrorImageOperation, HueShiftImageOperation, SaturationShiftImageOperation, BrightnessMultiplyImageOperation, FadeToColorImageOperation,
|
||||||
ScanLinesImageOperation, SetColorImageOperation, ColorReplaceImageOperation, AlphaMaskImageOperation, BlendImageOperation,
|
ScanLinesImageOperation, SetColorImageOperation, ColorReplaceImageOperation, AlphaMaskImageOperation, BlendImageOperation,
|
||||||
MultiplyImageOperation, BorderImageOperation, ScaleImageOperation, CropImageOperation, FlipImageOperation> ImageOperation;
|
MultiplyImageOperation, BorderImageOperation, ScaleImageOperation, CropImageOperation, FlipImageOperation> ImageOperation;
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ void StringView::forEachSplitAnyView(StringView chars, SplitCallback callback) c
|
|||||||
while (true) {
|
while (true) {
|
||||||
size_t end = m_view.find_first_of(chars.m_view, beg);
|
size_t end = m_view.find_first_of(chars.m_view, beg);
|
||||||
if (end == NPos) {
|
if (end == NPos) {
|
||||||
callback(m_view.substr(beg), beg, end);
|
callback(m_view.substr(beg), beg, m_view.size() - beg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
callback(m_view.substr(beg, end - beg), beg, end - beg);
|
callback(m_view.substr(beg, end - beg), beg, end - beg);
|
||||||
@ -143,7 +143,7 @@ void StringView::forEachSplitView(StringView pattern, SplitCallback callback) co
|
|||||||
while (true) {
|
while (true) {
|
||||||
size_t end = m_view.find(pattern.m_view, beg);
|
size_t end = m_view.find(pattern.m_view, beg);
|
||||||
if (end == NPos) {
|
if (end == NPos) {
|
||||||
callback(m_view.substr(beg), beg, end);
|
callback(m_view.substr(beg), beg, m_view.size() - beg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
callback(m_view.substr(beg, end - beg), beg, end - beg);
|
callback(m_view.substr(beg, end - beg), beg, end - beg);
|
||||||
|
@ -33,7 +33,7 @@ void ErrorScreen::setMessage(String const& errorMessage) {
|
|||||||
if (!m_paneManager->isDisplayed(m_errorPane)) {
|
if (!m_paneManager->isDisplayed(m_errorPane)) {
|
||||||
m_paneManager->displayPane(PaneLayer::Window, m_errorPane, [this](PanePtr) {
|
m_paneManager->displayPane(PaneLayer::Window, m_errorPane, [this](PanePtr) {
|
||||||
m_accepted = true;
|
m_accepted = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -517,7 +517,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
image = strf("%s:%s.%s", m_backArmorFrameset, frameGroup, bodyStateSeq);
|
image = strf("%s:%s.%s", m_backArmorFrameset, frameGroup, bodyStateSeq);
|
||||||
|
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, Vec2F());
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, Vec2F());
|
||||||
drawable.imagePart().addDirectives(getBackDirectives());
|
drawable.imagePart().addDirectives(getBackDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -550,7 +550,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
} else
|
} else
|
||||||
image = strf("%s:%s.%s", m_backArmFrameset, frameBase(m_state), armStateSeq);
|
image = strf("%s:%s.%s", m_backArmFrameset, frameBase(m_state), armStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
if (dance.isValid())
|
if (dance.isValid())
|
||||||
drawable.rotate(danceStep->backArmRotation);
|
drawable.rotate(danceStep->backArmRotation);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
@ -567,7 +567,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
} else
|
} else
|
||||||
image = strf("%s:%s.%s", m_backSleeveFrameset, frameBase(m_state), armStateSeq);
|
image = strf("%s:%s.%s", m_backSleeveFrameset, frameBase(m_state), armStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
if (dance.isValid())
|
if (dance.isValid())
|
||||||
drawable.rotate(danceStep->backArmRotation);
|
drawable.rotate(danceStep->backArmRotation);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
@ -593,21 +593,21 @@ List<Drawable> Humanoid::render() {
|
|||||||
if (!m_headFrameset.empty() && !m_bodyHidden) {
|
if (!m_headFrameset.empty() && !m_bodyHidden) {
|
||||||
String image = strf("%s:normal", m_headFrameset);
|
String image = strf("%s:normal", m_headFrameset);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_emoteFrameset.empty() && !m_bodyHidden) {
|
if (!m_emoteFrameset.empty() && !m_bodyHidden) {
|
||||||
String image = strf("%s:%s.%s", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq);
|
String image = strf("%s:%s.%s", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getEmoteDirectives());
|
drawable.imagePart().addDirectives(getEmoteDirectives(), true);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_hairFrameset.empty() && !m_bodyHidden) {
|
if (!m_hairFrameset.empty() && !m_bodyHidden) {
|
||||||
String image = strf("%s:normal", m_hairFrameset);
|
String image = strf("%s:normal", m_hairFrameset);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getHairDirectives()).addDirectives(getHelmetMaskDirectives());
|
drawable.imagePart().addDirectives(getHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -620,7 +620,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
else
|
else
|
||||||
image = strf("%s:%s.%s", m_bodyFrameset, frameBase(m_state), bodyStateSeq);
|
image = strf("%s:%s.%s", m_bodyFrameset, frameBase(m_state), bodyStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, {});
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, {});
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -633,7 +633,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
else
|
else
|
||||||
image = strf("%s:%s.%s", m_legsArmorFrameset, frameBase(m_state), bodyStateSeq);
|
image = strf("%s:%s.%s", m_legsArmorFrameset, frameBase(m_state), bodyStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, {});
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, {});
|
||||||
drawable.imagePart().addDirectives(getLegsDirectives());
|
drawable.imagePart().addDirectives(getLegsDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -655,28 +655,28 @@ List<Drawable> Humanoid::render() {
|
|||||||
if (m_state != Duck)
|
if (m_state != Duck)
|
||||||
position[1] += bobYOffset;
|
position[1] += bobYOffset;
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_facialHairFrameset.empty() && !m_bodyHidden) {
|
if (!m_facialHairFrameset.empty() && !m_bodyHidden) {
|
||||||
String image = strf("%s:normal", m_facialHairFrameset);
|
String image = strf("%s:normal", m_facialHairFrameset);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getFacialHairDirectives()).addDirectives(getHelmetMaskDirectives());
|
drawable.imagePart().addDirectives(getFacialHairDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
|
||||||
addDrawable(move(drawable), m_bodyFullbright);
|
addDrawable(move(drawable), m_bodyFullbright);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_facialMaskFrameset.empty() && !m_bodyHidden) {
|
if (!m_facialMaskFrameset.empty() && !m_bodyHidden) {
|
||||||
String image = strf("%s:normal", m_facialMaskFrameset);
|
String image = strf("%s:normal", m_facialMaskFrameset);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getFacialMaskDirectives()).addDirectives(getHelmetMaskDirectives());
|
drawable.imagePart().addDirectives(getFacialMaskDirectives(), true).addDirectives(getHelmetMaskDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_headArmorFrameset.empty()) {
|
if (!m_headArmorFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_headArmorFrameset);
|
String image = strf("%s:normal", m_headArmorFrameset);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, headPosition);
|
||||||
drawable.imagePart().addDirectives(getHeadDirectives());
|
drawable.imagePart().addDirectives(getHeadDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -718,7 +718,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
} else
|
} else
|
||||||
image = strf("%s:%s.%s", m_frontArmFrameset, frameBase(m_state), armStateSeq);
|
image = strf("%s:%s.%s", m_frontArmFrameset, frameBase(m_state), armStateSeq);
|
||||||
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
auto drawable = Drawable::makeImage(move(image), 1.0f / TilePixels, true, position);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
if (dance.isValid())
|
if (dance.isValid())
|
||||||
drawable.rotate(danceStep->frontArmRotation);
|
drawable.rotate(danceStep->frontArmRotation);
|
||||||
addDrawable(drawable, m_bodyFullbright);
|
addDrawable(drawable, m_bodyFullbright);
|
||||||
@ -736,7 +736,7 @@ List<Drawable> Humanoid::render() {
|
|||||||
} else
|
} else
|
||||||
image = strf("%s:%s.%s", m_frontSleeveFrameset, frameBase(m_state), armStateSeq);
|
image = strf("%s:%s.%s", m_frontSleeveFrameset, frameBase(m_state), armStateSeq);
|
||||||
auto drawable = Drawable::makeImage(image, 1.0f / TilePixels, true, position);
|
auto drawable = Drawable::makeImage(image, 1.0f / TilePixels, true, position);
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
if (dance.isValid())
|
if (dance.isValid())
|
||||||
drawable.rotate(danceStep->frontArmRotation);
|
drawable.rotate(danceStep->frontArmRotation);
|
||||||
addDrawable(drawable);
|
addDrawable(drawable);
|
||||||
@ -788,20 +788,20 @@ List<Drawable> Humanoid::renderPortrait(PortraitMode mode) const {
|
|||||||
if (!m_backArmFrameset.empty()) {
|
if (!m_backArmFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_backArmFrameset, personality.armIdle);
|
String image = strf("%s:%s", m_backArmFrameset, personality.armIdle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
if (dressed && !m_backSleeveFrameset.empty()) {
|
if (dressed && !m_backSleeveFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_backSleeveFrameset, personality.armIdle);
|
String image = strf("%s:%s", m_backSleeveFrameset, personality.armIdle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
if (mode != PortraitMode::Bust) {
|
if (mode != PortraitMode::Bust) {
|
||||||
if (dressed && !m_backArmorFrameset.empty()) {
|
if (dressed && !m_backArmorFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_backArmorFrameset, personality.idle);
|
String image = strf("%s:%s", m_backArmorFrameset, personality.idle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
||||||
drawable.imagePart().addDirectives(getBackDirectives());
|
drawable.imagePart().addDirectives(getBackDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -810,28 +810,28 @@ List<Drawable> Humanoid::renderPortrait(PortraitMode mode) const {
|
|||||||
if (!m_headFrameset.empty()) {
|
if (!m_headFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_headFrameset);
|
String image = strf("%s:normal", m_headFrameset);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_emoteFrameset.empty()) {
|
if (!m_emoteFrameset.empty()) {
|
||||||
String image = strf("%s:%s.%s", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq);
|
String image = strf("%s:%s.%s", m_emoteFrameset, emoteFrameBase(m_emoteState), emoteStateSeq);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getEmoteDirectives());
|
drawable.imagePart().addDirectives(getEmoteDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_hairFrameset.empty()) {
|
if (!m_hairFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_hairFrameset);
|
String image = strf("%s:normal", m_hairFrameset);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getHairDirectives()).addDirectives(helmetMaskDirective);
|
drawable.imagePart().addDirectives(getHairDirectives(), true).addDirectives(helmetMaskDirective, true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_bodyFrameset.empty()) {
|
if (!m_bodyFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_bodyFrameset, personality.idle);
|
String image = strf("%s:%s", m_bodyFrameset, personality.idle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -839,14 +839,14 @@ List<Drawable> Humanoid::renderPortrait(PortraitMode mode) const {
|
|||||||
if (dressed && !m_legsArmorFrameset.empty()) {
|
if (dressed && !m_legsArmorFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_legsArmorFrameset, personality.idle);
|
String image = strf("%s:%s", m_legsArmorFrameset, personality.idle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
||||||
drawable.imagePart().addDirectives(getLegsDirectives());
|
drawable.imagePart().addDirectives(getLegsDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dressed && !m_chestArmorFrameset.empty()) {
|
if (dressed && !m_chestArmorFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_chestArmorFrameset, personality.idle);
|
String image = strf("%s:%s", m_chestArmorFrameset, personality.idle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, {});
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -854,21 +854,21 @@ List<Drawable> Humanoid::renderPortrait(PortraitMode mode) const {
|
|||||||
if (!m_facialHairFrameset.empty()) {
|
if (!m_facialHairFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_facialHairFrameset);
|
String image = strf("%s:normal", m_facialHairFrameset);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getFacialHairDirectives()).addDirectives(helmetMaskDirective);
|
drawable.imagePart().addDirectives(getFacialHairDirectives(), true).addDirectives(helmetMaskDirective, true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_facialMaskFrameset.empty()) {
|
if (!m_facialMaskFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_facialMaskFrameset);
|
String image = strf("%s:normal", m_facialMaskFrameset);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getFacialMaskDirectives()).addDirectives(helmetMaskDirective);
|
drawable.imagePart().addDirectives(getFacialMaskDirectives(), true).addDirectives(helmetMaskDirective, true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dressed && !m_headArmorFrameset.empty()) {
|
if (dressed && !m_headArmorFrameset.empty()) {
|
||||||
String image = strf("%s:normal", m_headArmorFrameset);
|
String image = strf("%s:normal", m_headArmorFrameset);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.headOffset);
|
||||||
drawable.imagePart().addDirectives(getHeadDirectives());
|
drawable.imagePart().addDirectives(getHeadDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -876,14 +876,14 @@ List<Drawable> Humanoid::renderPortrait(PortraitMode mode) const {
|
|||||||
if (!m_frontArmFrameset.empty()) {
|
if (!m_frontArmFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_frontArmFrameset, personality.armIdle);
|
String image = strf("%s:%s", m_frontArmFrameset, personality.armIdle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
||||||
drawable.imagePart().addDirectives(getBodyDirectives());
|
drawable.imagePart().addDirectives(getBodyDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dressed && !m_frontSleeveFrameset.empty()) {
|
if (dressed && !m_frontSleeveFrameset.empty()) {
|
||||||
String image = strf("%s:%s", m_frontSleeveFrameset, personality.armIdle);
|
String image = strf("%s:%s", m_frontSleeveFrameset, personality.armIdle);
|
||||||
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
Drawable drawable = Drawable::makeImage(move(image), 1.0f, true, personality.armOffset);
|
||||||
drawable.imagePart().addDirectives(getChestDirectives());
|
drawable.imagePart().addDirectives(getChestDirectives(), true);
|
||||||
addDrawable(move(drawable));
|
addDrawable(move(drawable));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -121,6 +121,8 @@ AssetPath ImageMetadataDatabase::filterProcessing(AssetPath const& path) {
|
|||||||
AssetPath newPath = { path.basePath, path.subPath, {} };
|
AssetPath newPath = { path.basePath, path.subPath, {} };
|
||||||
|
|
||||||
String filtered;
|
String filtered;
|
||||||
|
for (auto& directives : path.directives.list())
|
||||||
|
directives.loadOperations();
|
||||||
path.directives.forEach([&](auto const& entry, Directives const& directives) {
|
path.directives.forEach([&](auto const& entry, Directives const& directives) {
|
||||||
ImageOperation const& operation = entry.operation;
|
ImageOperation const& operation = entry.operation;
|
||||||
if (!(operation.is<HueShiftImageOperation>() ||
|
if (!(operation.is<HueShiftImageOperation>() ||
|
||||||
@ -184,6 +186,8 @@ Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const {
|
|||||||
|
|
||||||
OperationSizeAdjust(Vec2U& size) : imageSize(size), hasError(false) {};
|
OperationSizeAdjust(Vec2U& size) : imageSize(size), hasError(false) {};
|
||||||
|
|
||||||
|
void operator()(NullImageOperation const&) {}
|
||||||
|
|
||||||
void operator()(ErrorImageOperation const&) {}
|
void operator()(ErrorImageOperation const&) {}
|
||||||
|
|
||||||
void operator()(HueShiftImageOperation const&) {}
|
void operator()(HueShiftImageOperation const&) {}
|
||||||
@ -231,6 +235,9 @@ Vec2U ImageMetadataDatabase::calculateImageSize(AssetPath const& path) const {
|
|||||||
|
|
||||||
OperationSizeAdjust osa(imageSize);
|
OperationSizeAdjust osa(imageSize);
|
||||||
|
|
||||||
|
for (auto& directives : path.directives.list())
|
||||||
|
directives.loadOperations();
|
||||||
|
|
||||||
bool complete = path.directives.forEachAbortable([&](auto const& entry, Directives const& directives) -> bool {
|
bool complete = path.directives.forEachAbortable([&](auto const& entry, Directives const& directives) -> bool {
|
||||||
entry.operation.call(osa);
|
entry.operation.call(osa);
|
||||||
return !osa.hasError;
|
return !osa.hasError;
|
||||||
|
@ -656,7 +656,7 @@ List<pair<Drawable, float>> NetworkedAnimator::drawablesWithZLevel(Vec2F const&
|
|||||||
Drawable drawable = find->second.second;
|
Drawable drawable = find->second.second;
|
||||||
auto& imagePart = drawable.imagePart();
|
auto& imagePart = drawable.imagePart();
|
||||||
for (Directives const& directives : baseProcessingDirectives)
|
for (Directives const& directives : baseProcessingDirectives)
|
||||||
imagePart.addDirectives(directives);
|
imagePart.addDirectives(directives, centered);
|
||||||
drawable.transform(partTransformation(partName));
|
drawable.transform(partTransformation(partName));
|
||||||
drawable.transform(globalTransformation());
|
drawable.transform(globalTransformation());
|
||||||
drawable.fullbright = fullbright;
|
drawable.fullbright = fullbright;
|
||||||
|
Loading…
Reference in New Issue
Block a user