v1.4.4
This commit is contained in:
commit
9c94d113d3
10260 changed files with 1237388 additions and 0 deletions
273
source/game/StarDrawable.cpp
Normal file
273
source/game/StarDrawable.cpp
Normal file
|
|
@ -0,0 +1,273 @@
|
|||
#include "StarDrawable.hpp"
|
||||
#include "StarColor.hpp"
|
||||
#include "StarJsonExtra.hpp"
|
||||
#include "StarDataStreamExtra.hpp"
|
||||
#include "StarAssets.hpp"
|
||||
#include "StarImageMetadataDatabase.hpp"
|
||||
#include "StarGameTypes.hpp"
|
||||
#include "StarRoot.hpp"
|
||||
|
||||
namespace Star {
|
||||
|
||||
void Drawable::ImagePart::addDirectives(String const& directives, bool keepImageCenterPosition) {
|
||||
if (directives.empty())
|
||||
return;
|
||||
|
||||
if (keepImageCenterPosition) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
Vec2F imageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
image = AssetPath::addDirectives(image, {directives});
|
||||
Vec2F newImageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
|
||||
// If we are trying to maintain the image center, PRE translate the image by
|
||||
// the change in size / 2
|
||||
transformation *= Mat3F::translation((imageSize - newImageSize) / 2);
|
||||
} else {
|
||||
image = AssetPath::addDirectives(image, {directives});
|
||||
}
|
||||
}
|
||||
|
||||
void Drawable::ImagePart::removeDirectives(bool keepImageCenterPosition) {
|
||||
if (keepImageCenterPosition) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
Vec2F imageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
image = AssetPath::removeDirectives(image);
|
||||
Vec2F newImageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
|
||||
// If we are trying to maintain the image center, PRE translate the image by
|
||||
// the change in size / 2
|
||||
transformation *= Mat3F::translation((imageSize - newImageSize) / 2);
|
||||
} else {
|
||||
image = AssetPath::removeDirectives(image);
|
||||
}
|
||||
}
|
||||
|
||||
Drawable Drawable::makeLine(Line2F const& line, float lineWidth, Color const& color, Vec2F const& position) {
|
||||
Drawable drawable;
|
||||
drawable.part = LinePart{move(line), lineWidth};
|
||||
drawable.color = color;
|
||||
drawable.position = position;
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
Drawable Drawable::makePoly(PolyF poly, Color const& color, Vec2F const& position) {
|
||||
Drawable drawable;
|
||||
drawable.part = PolyPart{move(poly)};
|
||||
drawable.color = color;
|
||||
drawable.position = position;
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
Drawable Drawable::makeImage(String image, float pixelSize, bool centered, Vec2F const& position, Color const& color) {
|
||||
Drawable drawable;
|
||||
Mat3F transformation = Mat3F::identity();
|
||||
if (centered) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
Vec2F imageSize = Vec2F(imageMetadata->imageSize(image));
|
||||
transformation.translate(-imageSize / 2);
|
||||
}
|
||||
|
||||
transformation.scale(pixelSize);
|
||||
|
||||
drawable.part = ImagePart{move(image), move(transformation)};
|
||||
drawable.position = position;
|
||||
drawable.color = color;
|
||||
|
||||
return drawable;
|
||||
}
|
||||
|
||||
Drawable::Drawable()
|
||||
: color(Color::White), fullbright(false) {}
|
||||
|
||||
Drawable::Drawable(Json const& json) {
|
||||
if (auto line = json.opt("line")) {
|
||||
part = LinePart{jsonToLine2F(*line), json.getFloat("width")};
|
||||
} else if (auto poly = json.opt("poly")) {
|
||||
part = PolyPart{jsonToPolyF(*poly)};
|
||||
} else if (auto image = json.opt("image")) {
|
||||
auto imageString = image->toString();
|
||||
Mat3F transformation = Mat3F::identity();
|
||||
if (auto transformationConfig = json.opt("transformation")) {
|
||||
transformation = jsonToMat3F(*transformationConfig);
|
||||
} else {
|
||||
if (json.getBool("centered", true)) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
Vec2F imageSize = Vec2F(imageMetadata->imageSize(imageString));
|
||||
transformation.translate(-imageSize / 2);
|
||||
}
|
||||
if (auto rotation = json.optFloat("rotation"))
|
||||
transformation.rotate(*rotation);
|
||||
if (json.getBool("mirrored", false))
|
||||
transformation.scale(Vec2F(-1, 1));
|
||||
if (auto scale = json.optFloat("scale"))
|
||||
transformation.scale(*scale);
|
||||
}
|
||||
|
||||
part = ImagePart{move(imageString), move(transformation)};
|
||||
}
|
||||
position = json.opt("position").apply(jsonToVec2F).value();
|
||||
color = json.opt("color").apply(jsonToColor).value(Color::White);
|
||||
fullbright = json.getBool("fullbright", false);
|
||||
}
|
||||
|
||||
Json Drawable::toJson() const {
|
||||
JsonObject json;
|
||||
if (auto line = part.ptr<LinePart>()) {
|
||||
json.set("line", jsonFromLine2F(line->line));
|
||||
json.set("width", line->width);
|
||||
} else if (auto poly = part.ptr<PolyPart>()) {
|
||||
json.set("poly", jsonFromPolyF(poly->poly));
|
||||
} else if (auto image = part.ptr<ImagePart>()) {
|
||||
json.set("image", image->image);
|
||||
json.set("transformation", jsonFromMat3F(image->transformation));
|
||||
}
|
||||
|
||||
json.set("position", jsonFromVec2F(position));
|
||||
json.set("color", jsonFromColor(color));
|
||||
json.set("fullbright", fullbright);
|
||||
|
||||
return move(json);
|
||||
}
|
||||
|
||||
void Drawable::translate(Vec2F const& translation) {
|
||||
position += translation;
|
||||
}
|
||||
|
||||
void Drawable::rotate(float rotation, Vec2F const& rotationCenter) {
|
||||
if (auto line = part.ptr<LinePart>())
|
||||
line->line.rotate(rotation);
|
||||
else if (auto poly = part.ptr<PolyPart>())
|
||||
poly->poly.rotate(rotation);
|
||||
else if (auto image = part.ptr<ImagePart>())
|
||||
image->transformation.rotate(rotation);
|
||||
|
||||
position = (position - rotationCenter).rotate(rotation) + rotationCenter;
|
||||
}
|
||||
|
||||
void Drawable::scale(float scaling, Vec2F const& scaleCenter) {
|
||||
scale(Vec2F::filled(scaling), scaleCenter);
|
||||
}
|
||||
|
||||
void Drawable::scale(Vec2F const& scaling, Vec2F const& scaleCenter) {
|
||||
if (auto line = part.ptr<LinePart>())
|
||||
line->line.scale(scaling);
|
||||
else if (auto poly = part.ptr<PolyPart>())
|
||||
poly->poly.scale(scaling);
|
||||
else if (auto image = part.ptr<ImagePart>())
|
||||
image->transformation.scale(scaling);
|
||||
|
||||
position = (position - scaleCenter).piecewiseMultiply(scaling) + scaleCenter;
|
||||
}
|
||||
|
||||
void Drawable::transform(Mat3F const& transformation) {
|
||||
Vec2F localTranslation = transformation.transformVec2(Vec2F());
|
||||
Mat3F localTransform = Mat3F::translation(-localTranslation) * transformation;
|
||||
|
||||
if (auto line = part.ptr<LinePart>())
|
||||
line->line.transform(localTransform);
|
||||
else if (auto poly = part.ptr<PolyPart>())
|
||||
poly->poly.transform(localTransform);
|
||||
else if (auto image = part.ptr<ImagePart>())
|
||||
image->transformation = localTransform * image->transformation;
|
||||
|
||||
position = transformation.transformVec2(position);
|
||||
}
|
||||
|
||||
void Drawable::rebase(Vec2F const& newBase) {
|
||||
if (auto line = part.ptr<LinePart>())
|
||||
line->line.translate(position - newBase);
|
||||
else if (auto poly = part.ptr<PolyPart>())
|
||||
poly->poly.translate(position - newBase);
|
||||
else if (auto image = part.ptr<ImagePart>())
|
||||
image->transformation.translate(position - newBase);
|
||||
|
||||
position = newBase;
|
||||
}
|
||||
|
||||
RectF Drawable::boundBox(bool cropImages) const {
|
||||
RectF boundBox = RectF::null();
|
||||
if (auto line = part.ptr<LinePart>()) {
|
||||
boundBox.combine(line->line.min());
|
||||
boundBox.combine(line->line.max());
|
||||
|
||||
} else if (auto poly = part.ptr<PolyPart>()) {
|
||||
boundBox.combine(poly->poly.boundBox());
|
||||
|
||||
} else if (auto image = part.ptr<ImagePart>()) {
|
||||
auto imageMetadata = Root::singleton().imageMetadataDatabase();
|
||||
RectF imageRegion = RectF::null();
|
||||
if (cropImages) {
|
||||
RectU nonEmptyRegion = imageMetadata->nonEmptyRegion(image->image);
|
||||
if (!nonEmptyRegion.isNull())
|
||||
imageRegion = RectF(nonEmptyRegion);
|
||||
} else {
|
||||
imageRegion = RectF::withSize(Vec2F(), Vec2F(imageMetadata->imageSize(image->image)));
|
||||
}
|
||||
|
||||
if (!imageRegion.isNull()) {
|
||||
boundBox.combine(image->transformation.transformVec2(Vec2F(imageRegion.xMin(), imageRegion.yMin())));
|
||||
boundBox.combine(image->transformation.transformVec2(Vec2F(imageRegion.xMax(), imageRegion.yMin())));
|
||||
boundBox.combine(image->transformation.transformVec2(Vec2F(imageRegion.xMin(), imageRegion.yMax())));
|
||||
boundBox.combine(image->transformation.transformVec2(Vec2F(imageRegion.xMax(), imageRegion.yMax())));
|
||||
}
|
||||
}
|
||||
|
||||
if (!boundBox.isNull())
|
||||
boundBox.translate(position);
|
||||
|
||||
return boundBox;
|
||||
}
|
||||
|
||||
DataStream& operator>>(DataStream& ds, Drawable::LinePart& line) {
|
||||
ds >> line.line;
|
||||
ds >> line.width;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator<<(DataStream& ds, Drawable::LinePart const& line) {
|
||||
ds << line.line;
|
||||
ds << line.width;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator>>(DataStream& ds, Drawable::PolyPart& poly) {
|
||||
ds >> poly.poly;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator<<(DataStream& ds, Drawable::PolyPart const& poly) {
|
||||
ds << poly.poly;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator>>(DataStream& ds, Drawable::ImagePart& image) {
|
||||
ds >> image.image;
|
||||
ds >> image.transformation;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator<<(DataStream& ds, Drawable::ImagePart const& image) {
|
||||
ds << image.image;
|
||||
ds << image.transformation;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator>>(DataStream& ds, Drawable& drawable) {
|
||||
ds >> drawable.part;
|
||||
ds >> drawable.position;
|
||||
ds >> drawable.color;
|
||||
ds >> drawable.fullbright;
|
||||
return ds;
|
||||
}
|
||||
|
||||
DataStream& operator<<(DataStream& ds, Drawable const& drawable) {
|
||||
ds << drawable.part;
|
||||
ds << drawable.position;
|
||||
ds << drawable.color;
|
||||
ds << drawable.fullbright;
|
||||
return ds;
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue