Merge branch 'main' into environments

This commit is contained in:
MihailRis 2026-07-26 23:56:00 +03:00
commit f9bc401236
134 changed files with 3186 additions and 883 deletions

View file

@ -26,6 +26,11 @@ Font::Font(
pages(std::move(pages)),
glyphs(std::move(glyphs)),
fontFile(std::move(fontFile)) {
if (this->fontFile.has_value()) {
if (auto fontPtr = this->fontFile->lock()) {
monospace = fontPtr->isMonospace();
}
}
}
Font::~Font() = default;
@ -34,6 +39,10 @@ int Font::getYOffset() const {
return yoffset;
}
bool Font::isMonospace() const {
return monospace;
}
int Font::getLineHeight() const {
return lineHeight;
}
@ -53,7 +62,7 @@ bool Font::isPrintableChar(uint codepoint) const {
int FontMetrics::calcWidth(std::wstring_view text, size_t offset, size_t length) const {
auto font = this->font.has_value() ? this->font->lock() : nullptr;
if (font == nullptr) {
if (font == nullptr || font->isMonospace()) {
return std::min(text.length() - offset, length) * _glyphInterval;
}
int totalWidth = 0;
@ -153,6 +162,8 @@ static inline void draw_text(
const FontStylesScheme* styles,
size_t styleMapOffset
) {
bool is3d = std::is_same<Batch, Batch3D>();
static FontStylesScheme defStyles {{{}}, {0}};
if (styles == nullptr) {
@ -185,13 +196,26 @@ static inline void draw_text(
float advance = baseAdvance;
if (auto glyph = font.getGlyph(c)) {
yOffset = glyph->yOffset;
advance = glyph->xAdvance;
advance = glyph->xAdvance /
static_cast<float>(font.getLineHeight()) * 2.0f *
baseAdvance;
}
uint charpage = c >> 8;
if (charpage == page){
batch.texture(font.getPage(charpage));
draw_glyph(
batch, pos, glm::vec2(x, y - yOffset / static_cast<float>(font.getLineHeight())), c, right, up, interval, style
batch,
pos,
glm::vec2(
x,
y - yOffset * (is3d ? -1 : 1) /
static_cast<float>(font.getLineHeight())
),
c,
right,
up,
interval,
style
);
}
else if (charpage > page && charpage < next){

View file

@ -39,6 +39,7 @@ public:
);
~Font();
bool isMonospace() const;
int getLineHeight() const;
int getYOffset() const;
@ -94,6 +95,7 @@ private:
int lineHeight;
int yoffset;
int glyphInterval;
bool monospace = true;
std::vector<std::unique_ptr<Texture>> pages;
std::vector<Glyph> glyphs;
std::optional<std::weak_ptr<vector_fonts::FontFile>> fontFile;

View file

@ -9,8 +9,8 @@ class Font;
struct FontMetrics {
std::optional<std::weak_ptr<Font>> font;
int lineHeight;
int yoffset;
int lineHeight = 0;
int yoffset = 0;
int _glyphInterval = 8;
~FontMetrics();

View file

@ -1,5 +1,7 @@
#include "ImageData.hpp"
#include "debug/Logger.hpp"
#include <glm/glm.hpp>
#include <assert.h>
#include <stdexcept>
@ -7,6 +9,8 @@
#include <cmath>
#include <algorithm>
static debug::Logger logger("image-data");
ImageData::ImageData(ImageFormat format, uint width, uint height)
: format(format), width(width), height(height) {
size_t pixsize;
@ -106,47 +110,83 @@ std::unique_ptr<ImageData> ImageData::cropped(int x, int y, int width, int heigh
return subImage;
}
static bool clip_line(int& x1, int& y1, int& x2, int& y2, int width, int height) {
const int left = 0;
const int right = width;
const int bottom = 0;
const int top = height;
static bool clip_line(
int& x0, int& y0, int& x1, int& y1, int width, int height
) {
if (width <= 0 || height <= 0) {
return false;
}
constexpr int INSIDE = 0;
constexpr int LEFT = 1;
constexpr int RIGHT = 2;
constexpr int BOTTOM = 4;
constexpr int TOP = 8;
int dx = x2 - x1;
int dy = y2 - y1;
const int xmin = 0;
const int ymin = 0;
const int xmax = width - 1;
const int ymax = height - 1;
float t0 = 0.0f;
float t1 = 1.0f;
auto outcode = [&](int x, int y) {
int code = INSIDE;
auto clip = [](int p, int q, float& t0, float& t1) {
if (p == 0) {
return q >= 0;
}
float t = static_cast<float>(q) / p;
if (p < 0) {
if (t > t1) return false;
if (t > t0) t0 = t;
} else {
if (t < t0) return false;
if (t < t1) t1 = t;
}
return true;
if (x < xmin)
code |= LEFT;
else if (x > xmax)
code |= RIGHT;
if (y < ymin)
code |= BOTTOM;
else if (y > ymax)
code |= TOP;
return code;
};
if (!clip(-dx, x1 - left, t0, t1)) return false;
if (!clip( dx, right - x1, t0, t1)) return false;
if (!clip(-dy, y1 - bottom, t0, t1)) return false;
if (!clip( dy, top - y1, t0, t1)) return false;
int c0 = outcode(x0, y0);
int c1 = outcode(x1, y1);
if (t1 < 1.0f) {
x2 = x1 + static_cast<int>(std::round(t1 * dx));
y2 = y1 + static_cast<int>(std::round(t1 * dy));
while (true) {
if (!(c0 | c1)) {
return true;
}
if (c0 & c1) {
return false;
}
const int out = c0 ? c0 : c1;
double x = 0.0;
double y = 0.0;
if (out & TOP) {
y = ymax;
x = x0 + (x1 - x0) * static_cast<double>(ymax - y0) / (y1 - y0);
} else if (out & BOTTOM) {
y = ymin;
x = x0 + (x1 - x0) * static_cast<double>(ymin - y0) / (y1 - y0);
} else if (out & RIGHT) {
x = xmax;
y = y0 + (y1 - y0) * static_cast<double>(xmax - x0) / (x1 - x0);
} else { // LEFT
x = xmin;
y = y0 + (y1 - y0) * static_cast<double>(xmin - x0) / (x1 - x0);
}
if (out == c0) {
x0 = std::clamp(static_cast<int>(std::lround(x)), xmin, xmax);
y0 = std::clamp(static_cast<int>(std::lround(y)), ymin, ymax);
c0 = outcode(x0, y0);
} else {
x1 = std::clamp(static_cast<int>(std::lround(x)), xmin, xmax);
y1 = std::clamp(static_cast<int>(std::lround(y)), ymin, ymax);
c1 = outcode(x1, y1);
}
}
if (t0 > 0.0f) {
x1 = x1 + static_cast<int>(std::round(t0 * dx));
y1 = y1 + static_cast<int>(std::round(t0 * dy));
}
return true;
}
static bool is_point_outside(int x, int y, int width, int height) {
return x < 0 || y < 0 || x >= width || y >= height;
}
template<uint channels>
@ -155,11 +195,24 @@ static void draw_line(ImageData& image, int x1, int y1, int x2, int y2, const gl
uint width = image.getWidth();
uint height = image.getHeight();
glm::ivec4 init {x1, y1, x2, y2};
if ((x1 < 0 || x1 >= width || x2 < 0 || x2 >= width ||
y1 < 0 || y1 >= height || y2 < 0 || y2 >= height) &&
!clip_line(x1, y1, x2, y2, width, height)) {
return;
}
// spam info for bug report
if (is_point_outside(x1, y1, width, height) || is_point_outside(x2, y2, width, height)) {
logger.warning() << "clip_line fault: [" << init.x << ", " << init.y
<< "] - [" << init.z << ", " << init.w << "] --> ["
<< x1 << ", " << y1 << "] - [" << x2 << ", " << y2
<< "]";
x1 = glm::clamp(x1, 0, static_cast<int>(width) - 1);
y1 = glm::clamp(y1, 0, static_cast<int>(height) - 1);
x2 = glm::clamp(x2, 0, static_cast<int>(width) - 1);
y2 = glm::clamp(y2, 0, static_cast<int>(height) - 1);
}
int dx = std::abs(x2 - x1);
int dy = -std::abs(y2 - y1);

View file

@ -22,6 +22,7 @@
#include "voxels/Block.hpp"
#include "voxels/Chunk.hpp"
#include "voxels/Chunks.hpp"
#include "voxels/blocks_agent.hpp"
#include "window/Camera.hpp"
#include "world/Level.hpp"
#include "WorldRenderer.hpp"
@ -98,7 +99,7 @@ void Decorator::updateAcoustics(const Camera& camera) {
auto& chunks = *player.chunks;
const auto& start = camera.position;
float rayLength = 40.0f;
float length = 40.0f;
auto& blocks = level.content.getIndices()->blocks;
@ -107,7 +108,7 @@ void Decorator::updateAcoustics(const Camera& camera) {
float averageDistance = 0.0f;
float averageAbsorption = 0.0f;
float speedOfSound = 300.0f;
float minDistance = rayLength;
float minDistance = length;
for (int i = 0; i < rays; i++) {
float u1 = random.randFloat();
float u2 = random.randFloat();
@ -121,12 +122,13 @@ void Decorator::updateAcoustics(const Camera& camera) {
glm::vec3 end;
glm::ivec3 norm;
glm::ivec3 iend;
auto vox = chunks.rayCast(start, dir, rayLength, end, norm, iend);
blocks_agent::RaycastSettings raycast {};
auto vox = chunks.rayCast(start, dir, length, end, norm, iend, raycast);
if (vox == nullptr) {
continue;
}
auto distance = glm::distance(start, end);
if (distance >= rayLength * 0.98f) {
if (distance >= length * 0.98f) {
continue;
}
if (distance < minDistance) {
@ -149,7 +151,7 @@ void Decorator::updateAcoustics(const Camera& camera) {
averageAbsorption /= hit;
}
float decayTime = 20.0f * (averageDistance / rayLength);
float decayTime = 20.0f * (averageDistance / length);
float escapeRatio = static_cast<float>(rays - hit) / static_cast<float>(rays);
acoustics.reverbGain = glm::pow(hit / static_cast<float>(rays), 3.0f);

View file

@ -58,7 +58,10 @@ void TextsRenderer::renderNote(
}
opacity = preset.xrayOpacity;
}
auto& font = assets.require<Font>(FONT_DEFAULT);
auto specifiedFont = assets.get<Font>(preset.font);
auto& font =
specifiedFont ? *specifiedFont : assets.require<Font>(FONT_DEFAULT);
glm::vec3 xvec = note.getAxisX();
glm::vec3 yvec = note.getAxisY();
@ -76,7 +79,10 @@ void TextsRenderer::renderNote(
yvec = camera.up;
}
float scale =
(1.0f - preset.perspective) * glm::pow(glm::distance(camera.position, pos), 1.0f-preset.perspective);
(1.0f - preset.perspective) *
glm::pow(
glm::distance(camera.position, pos), 1.0f - preset.perspective
);
xvec *= 1.0f + scale;
yvec *= 1.0f + scale;
}
@ -118,6 +124,7 @@ void TextsRenderer::renderNote(
}
auto color = preset.color;
batch.setColor(glm::vec4(color.r, color.g, color.b, color.a * opacity));
font.draw(
batch,
text,

View file

@ -13,7 +13,7 @@ InlineFrame::~InlineFrame() = default;
void InlineFrame::setSrc(const std::string& src) {
this->src = src;
if (document) {
scripting::on_ui_close(document.get(), nullptr);
scripting::on_ui_close(*document, nullptr);
document = nullptr;
root = nullptr;
}
@ -31,7 +31,7 @@ void InlineFrame::setDocument(const std::shared_ptr<UiDocument>& document) {
root->setSize(size);
gui.postRunnable([this]() {
scripting::on_ui_open(this->document.get(), {});
scripting::on_ui_open(*this->document, {});
});
}

View file

@ -207,6 +207,9 @@ uint Label::getLinesNumber() const {
void Label::draw(const DrawContext& pctx, const Assets& assets) {
auto batch = pctx.getBatch2D();
auto font = assets.getShared<Font>(fontName);
if (font == nullptr) {
return;
}
cache.prepare(
font,
font->getMetrics(),

View file

@ -353,7 +353,9 @@ void TextBox::draw(const DrawContext& pctx, const Assets& assets) {
void TextBox::drawBackground(const DrawContext& pctx, const Assets& assets) {
auto font = assets.getShared<Font>(label->getFontName());
rawTextCache.prepare(font, font->getMetrics(), label->getSize().x);
if (font != nullptr) {
rawTextCache.prepare(font, font->getMetrics(), label->getSize().x);
}
glm::vec2 pos = calcPos();