mirror of
https://github.com/Almamu/linux-wallpaperengine.git
synced 2025-09-14 13:56:48 +08:00
187 lines
6.4 KiB
C++
187 lines
6.4 KiB
C++
#include "ObjectParser.h"
|
|
#include "ModelParser.h"
|
|
#include "EffectParser.h"
|
|
|
|
#include "ShaderConstantParser.h"
|
|
#include "WallpaperEngine/Data/Model/Object.h"
|
|
#include "WallpaperEngine/Data/Model/Project.h"
|
|
#include "WallpaperEngine/Logging/CLog.h"
|
|
|
|
using namespace WallpaperEngine::Data::Parsers;
|
|
using namespace WallpaperEngine::Data::Model;
|
|
|
|
ObjectUniquePtr ObjectParser::parse (const JSON& it, Project& project) {
|
|
const auto imageIt = it.find ("image");
|
|
const auto soundIt = it.find ("sound");
|
|
const auto particleIt = it.find ("particle");
|
|
const auto textIt = it.find ("text");
|
|
const auto lightIt = it.find ("light");
|
|
const auto basedata = ObjectData {
|
|
.id = it.require <int> ("id", "Object must have an id"),
|
|
.name = it.require <std::string> ("name", "Object must have a name"),
|
|
.dependencies = parseDependencies (it),
|
|
};
|
|
|
|
if (imageIt != it.end () && imageIt->is_string ()) {
|
|
return parseImage (it, project, basedata, *imageIt);
|
|
} else if (soundIt != it.end () && soundIt->is_array ()) {
|
|
return parseSound (it, project, basedata);
|
|
} else if (particleIt != it.end ()) {
|
|
sLog.error ("Particle objects are not supported yet");
|
|
} else if (textIt != it.end ()) {
|
|
sLog.error ("Text objects are not supported yet");
|
|
} else if (lightIt != it.end ()) {
|
|
sLog.error ("Light objects are not supported yet");
|
|
} else {
|
|
// dump the object for now, might want to change later
|
|
sLog.exception ("Unknown object type found: ", it.dump ());
|
|
}
|
|
|
|
return std::make_unique <Object> (basedata);
|
|
}
|
|
|
|
std::vector<int> ObjectParser::parseDependencies (const JSON& it) {
|
|
const auto dependenciesIt = it.find ("dependencies");
|
|
|
|
if (dependenciesIt == it.end () || !dependenciesIt->is_array ()) {
|
|
return {};
|
|
}
|
|
|
|
std::vector<int> result = {};
|
|
|
|
for (const auto& cur : *dependenciesIt) {
|
|
result.push_back (cur);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
SoundUniquePtr ObjectParser::parseSound (const JSON& it, Project& project, ObjectData base) {
|
|
const auto soundIt = it.require ("sound", "Object must have a sound");
|
|
std::vector<std::string> sounds = {};
|
|
|
|
for (const auto& cur : soundIt) {
|
|
sounds.push_back (cur);
|
|
}
|
|
|
|
return std::make_unique <Sound> (
|
|
std::move (base),
|
|
SoundData {
|
|
.playbackmode = it.optional <std::string> ("playbackmode"),
|
|
.sounds = sounds,
|
|
}
|
|
);
|
|
}
|
|
|
|
ImageUniquePtr ObjectParser::parseImage (
|
|
const JSON& it, Project& project, ObjectData base, const std::string& image) {
|
|
const auto& properties = project.properties;
|
|
const auto& effects = it.optional ("effects");
|
|
|
|
return std::make_unique <Image> (
|
|
std::move (base),
|
|
ImageData {
|
|
.origin = it.user ("origin", properties, glm::vec3 (0.0f)),
|
|
.scale = it.user ("scale", properties, glm::vec3 (1.0f)),
|
|
.angles = it.user ("angles", properties, glm::vec3 (0.0)),
|
|
.visible = it.user ("visible", properties, true),
|
|
.alpha = it.user ("alpha", properties, 1.0f),
|
|
.color = it.user ("color", properties, glm::vec3 (1.0f)),
|
|
.alignment = it.optional ("alignment", std::string ("center")),
|
|
.size = it.optional ("size", glm::vec2 (0.0f)),
|
|
.parallaxDepth = it.optional ("parallaxDepth", glm::vec2 (0.0f)),
|
|
.colorBlendMode = it.optional ("colorBlendMode", 0),
|
|
.brightness = it.optional ("brightness", 1.0f),
|
|
.model = ModelParser::load (project, image),
|
|
.effects = effects.has_value () ? parseEffects (*effects, project) : std::vector <ImageEffectUniquePtr> {},
|
|
}
|
|
);
|
|
}
|
|
|
|
std::vector <ImageEffectUniquePtr> ObjectParser::parseEffects (const JSON& it, Project& project) {
|
|
if (!it.is_array ()) {
|
|
return {};
|
|
}
|
|
|
|
std::vector <ImageEffectUniquePtr> result = {};
|
|
|
|
for (const auto& cur : it) {
|
|
result.push_back (parseEffect (cur, project));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ImageEffectUniquePtr ObjectParser::parseEffect (const JSON& it, Project& project) {
|
|
const auto& passsOverrides = it.optional ("passes");
|
|
return std::make_unique <ImageEffect> (ImageEffect {
|
|
.id = it.require <int> ("id", "Image effect must have an id"),
|
|
.name = it.require <std::string> ("name", "Image effect must have a name"),
|
|
.visible = it.user ("visible", project.properties, true),
|
|
.passOverrides = passsOverrides.has_value () ? parseEffectPassOverrides (passsOverrides.value (), project) : std::vector <ImageEffectPassOverrideUniquePtr> {},
|
|
.effect = EffectParser::load (project, it.require ("file", "Image effect must have an effect"))
|
|
});
|
|
}
|
|
|
|
std::vector <ImageEffectPassOverrideUniquePtr> ObjectParser::parseEffectPassOverrides (const JSON& it, Project& project) {
|
|
if (!it.is_array ()) {
|
|
return {};
|
|
}
|
|
|
|
std::vector <ImageEffectPassOverrideUniquePtr> result = {};
|
|
|
|
for (const auto& cur : it) {
|
|
result.push_back (parseEffectPass (cur, project));
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ImageEffectPassOverrideUniquePtr ObjectParser::parseEffectPass (const JSON& it, Project& project) {
|
|
const auto& combos = it.optional ("combos");
|
|
const auto& textures = it.optional ("textures");
|
|
const auto& constants = it.optional ("constantshadervalues");
|
|
|
|
// TODO: PARSE CONSTANT SHADER VALUES AND FIND REFS?
|
|
return std::make_unique <ImageEffectPassOverride> (ImageEffectPassOverride {
|
|
.id = it.optional <int> ("id", -1),
|
|
.combos = combos.has_value () ? parseComboMap (combos.value ()) : ComboMap {},
|
|
.constants = constants.has_value () ? ShaderConstantParser::parse (constants.value (), project) : ShaderConstantMap {},
|
|
.textures = textures.has_value () ? parseTextureMap (textures.value ()) : TextureMap {},
|
|
});
|
|
}
|
|
|
|
TextureMap ObjectParser::parseTextureMap (const JSON& it) {
|
|
if (!it.is_array ()) {
|
|
return {};
|
|
}
|
|
|
|
TextureMap result = {};
|
|
int textureIndex = -1;
|
|
|
|
for (const auto& cur : it) {
|
|
textureIndex ++;
|
|
|
|
if (cur.is_null ()) {
|
|
continue;
|
|
}
|
|
|
|
result.emplace (textureIndex, cur);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
ComboMap ObjectParser::parseComboMap (const JSON& it) {
|
|
if (!it.is_object ()) {
|
|
return {};
|
|
}
|
|
|
|
ComboMap result = {};
|
|
|
|
for (const auto& cur : it.items ()) {
|
|
result.emplace (cur.key (), cur.value ());
|
|
}
|
|
|
|
return result;
|
|
} |