Added animation bounds for rendering animations, redid float format stuff

This commit is contained in:
2025-09-15 11:14:58 -04:00
parent 3e22f8eb9d
commit f49eaa6a37
7 changed files with 71 additions and 36 deletions

View File

@@ -114,39 +114,25 @@ static inline std::string string_to_lowercase(std::string string) {
return string;
}
#define FLOAT_FORMAT_MAX_DECIMALS 9
#define FLOAT_FORMAT_EPSILON 1e-9f
#define FLOAT_FORMAT_MAX_DECIMALS 5
#define FLOAT_FORMAT_EPSILON 1e-5f
static constexpr f32 FLOAT_FORMAT_POW10[] = {
1.f,
10.f,
100.f,
1000.f,
10000.f,
100000.f,
1000000.f,
10000000.f,
100000000.f,
1000000000.f
100000.f
};
static inline s32 f32_decimals_needed(f32 value)
{
f32 integerPart = 0.f;
f32 fractionalPart = modff(value, &integerPart);
fractionalPart = fabsf(fractionalPart);
if (fractionalPart < FLOAT_FORMAT_EPSILON)
return 0;
for (s32 decimalCount = 1; decimalCount <= FLOAT_FORMAT_MAX_DECIMALS; ++decimalCount)
for (s32 decimalCount = 0; decimalCount <= FLOAT_FORMAT_MAX_DECIMALS; ++decimalCount)
{
f32 scaledFraction = fractionalPart * FLOAT_FORMAT_POW10[decimalCount];
if (fabsf(scaledFraction - roundf(scaledFraction)) <
FLOAT_FORMAT_EPSILON * FLOAT_FORMAT_POW10[decimalCount])
{
f32 scale = FLOAT_FORMAT_POW10[decimalCount];
f32 rounded = roundf(value * scale) / scale;
if (fabsf(value - rounded) < FLOAT_FORMAT_EPSILON)
return decimalCount;
}
}
return FLOAT_FORMAT_MAX_DECIMALS;
}

View File

@@ -1612,8 +1612,10 @@ static void _imgui_taskbar(Imgui* self)
static DialogType& dialogType = self->dialog->type;
static bool& dialogIsSelected = self->dialog->isSelected;
static s32& type = self->settings->renderType;
static f32& scale = self->settings->renderScale;
static bool& isUseAnimationBounds = self->settings->renderIsUseAnimationBounds;
static std::string& dialogPath = self->dialog->path;
static std::string& ffmpegPath = self->settings->ffmpegPath;
static std::string& ffmpegPath = self->settings->renderFFmpegPath;
static std::string& format = self->settings->renderFormat;
static std::string& path = self->settings->renderPath;
@@ -1640,8 +1642,10 @@ static void _imgui_taskbar(Imgui* self)
}
_imgui_input_text(IMGUI_RENDER_ANIMATION_FFMPEG_PATH, self, ffmpegPath);
_imgui_input_text(IMGUI_RENDER_ANIMATION_FORMAT, self, format);
_imgui_combo(IMGUI_RENDER_ANIMATION_OUTPUT, self, &type);
_imgui_input_text(IMGUI_RENDER_ANIMATION_FORMAT.copy({type != RENDER_PNG}), self, format);
_imgui_checkbox(IMGUI_RENDER_ANIMATION_IS_USE_ANIMATION_BOUNDS, self, isUseAnimationBounds);
_imgui_input_float(IMGUI_RENDER_ANIMATION_SCALE.copy({!isUseAnimationBounds}), self, scale);
_imgui_end_child(); // IMGUI_RENDER_ANIMATION_CHILD
@@ -1765,7 +1769,7 @@ static void _imgui_taskbar(Imgui* self)
case RENDER_WEBM:
case RENDER_MP4:
{
std::string ffmpegPath = std::string(self->settings->ffmpegPath.c_str());
std::string ffmpegPath = std::string(self->settings->renderFFmpegPath.c_str());
path = path_extension_change(path, RENDER_EXTENSIONS[self->settings->renderType]);
if (ffmpeg_render(ffmpegPath, path, frames, self->preview->canvas.size, self->anm2->fps, (RenderType)type))
@@ -2463,8 +2467,8 @@ static void _imgui_animation_preview(Imgui* self)
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_CENTER_VIEW.copy({pan == vec2()}), self)) pan = vec2();
if (_imgui_button(IMGUI_ANIMATION_PREVIEW_FIT.copy({self->reference->animationID == ID_NONE}), self))
{
vec4 rect = anm2_animation_rect_get(self->anm2, self->reference, self->settings->previewIsRootTransform);
vec4 rect = anm2_animation_rect_get(self->anm2, self->reference, self->settings->previewIsRootTransform);
if (rect != vec4(-1.0f) && (rect.z > 0 && rect.w > 0))
{
f32 scaleX = self->preview->canvas.size.x / rect.z;
@@ -2527,7 +2531,9 @@ static void _imgui_animation_preview(Imgui* self)
_imgui_end_child(); // IMGUI_CANVAS_HELPER_CHILD
ImVec2 previewCursorScreenPos = ImGui::GetCursorScreenPos();
size = ivec2(vec2(ImGui::GetContentRegionAvail()));
if (!self->preview->isRender) size = ivec2(vec2(ImGui::GetContentRegionAvail()));
preview_draw(self->preview);
ImGui::Image(self->preview->canvas.framebuffer, vec2(size));

View File

@@ -1132,7 +1132,7 @@ IMGUI_ITEM(IMGUI_RENDER_ANIMATION,
self.label = "&Render Animation",
self.tooltip = "Renders the current animation preview; output options can be customized.",
self.popup = "Render Animation",
self.popupSize = {600, 150},
self.popupSize = {500, 170},
self.popupType = IMGUI_POPUP_CENTER_WINDOW
);
@@ -1157,7 +1157,7 @@ IMGUI_ITEM(IMGUI_RENDER_ANIMATION_LOCATION_BROWSE,
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_LOCATION,
self.label = "Location",
self.tooltip = "Select the location of the rendered animation.",
self.tooltip = "Select the location of the rendered animation.\nFor PNG images, this should be a directory, otherwise, a filepath.",
self.max = 1024
);
@@ -1187,6 +1187,20 @@ IMGUI_ITEM(IMGUI_RENDER_ANIMATION_FORMAT,
self.max = UCHAR_MAX
);
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_IS_USE_ANIMATION_BOUNDS,
self.label = "Use Animation Bounds",
self.tooltip = "Instead of using the animation preview's bounds, the rendered animation will use the animation's bounds.\nNOTE: If you're looking to make a transparent animation, set the preview background to be transparent\nand toggle off other drawn things.",
self.value = SETTINGS_RENDER_IS_USE_ANIMATION_BOUNDS_DEFAULT,
self.isSameLine = true
);
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_SCALE,
self.label = "Scale",
self.tooltip = "Change the scale the animation will be rendered at.",
self.value = SETTINGS_RENDER_SCALE_DEFAULT,
self.size = {125, 0}
);
IMGUI_ITEM(IMGUI_RENDER_ANIMATION_CONFIRM,
self.label = "Render",
self.tooltip = "Render the animation, with the used settings.",

View File

@@ -242,6 +242,25 @@ void preview_render_start(Preview* self)
self->isPlaying = true;
self->time = 0.0f;
_preview_render_textures_free(self);
self->normalCanvasSize = self->canvas.size;
self->normalCanvasPan = self->settings->previewPan;
self->normalCanvasZoom = self->settings->previewZoom;
if (self->settings->renderIsUseAnimationBounds)
{
vec4 rect = anm2_animation_rect_get(self->anm2, self->reference, self->settings->previewIsRootTransform);
self->canvas.size = ivec2
(
ceilf(rect.z * self->settings->renderScale),
ceilf(rect.w * self->settings->renderScale)
);
vec2 rectCenter = vec2(rect.x + rect.z * 0.5f, rect.y + rect.w * 0.5f);
self->settings->previewPan = -rectCenter * self->settings->renderScale;
self->settings->previewZoom = UNIT_TO_PERCENT(self->settings->renderScale);
}
}
void preview_render_end(Preview* self)
@@ -250,6 +269,10 @@ void preview_render_end(Preview* self)
self->isPlaying = false;
self->isRenderFinished = false;
_preview_render_textures_free(self);
self->canvas.size = self->normalCanvasSize;
self->settings->previewPan = self->normalCanvasPan;
self->settings->previewZoom = self->normalCanvasZoom;
}
void preview_free(Preview* self)

View File

@@ -34,6 +34,9 @@ struct Preview
Settings* settings = nullptr;
s32 animationOverlayID = ID_NONE;
Canvas canvas;
vec2 normalCanvasSize{};
vec2 normalCanvasPan{};
f32 normalCanvasZoom{};
bool isPlaying = false;
bool isRender = false;
bool isRenderFinished = false;

View File

@@ -21,9 +21,9 @@
#define SETTINGS_TEMPORARY_EXTENSION ".tmp"
#ifdef _WIN32
#define SETTINGS_FFMPEG_PATH_VALUE_DEFAULT "C:\\ffmpeg\\bin\\ffmpeg.exe"
#define SETTINGS_RENDER_FFMPEG_PATH_VALUE_DEFAULT "C:\\ffmpeg\\bin\\ffmpeg.exe"
#else
#define SETTINGS_FFMPEG_PATH_VALUE_DEFAULT "/usr/bin/ffmpeg"
#define SETTINGS_RENDER_FFMPEG_PATH_VALUE_DEFAULT "/usr/bin/ffmpeg"
#endif
#define SETTINGS_LIST \
@@ -143,10 +143,13 @@
X(tool, TOOL, TYPE_INT, TOOL_PAN) \
X(toolColor, TOOL_COLOR, TYPE_VEC4, {1.0,1.0,1.0,1.0}) \
\
X(renderType, RENDER_TYPE, TYPE_INT, RENDER_PNG) \
X(renderPath, RENDER_PATH, TYPE_STRING, ".") \
X(renderFormat, RENDER_FORMAT, TYPE_STRING, "{}.png") \
X(ffmpegPath, FFMPEG_PATH, TYPE_STRING, SETTINGS_FFMPEG_PATH_VALUE_DEFAULT)
X(renderType, RENDER_TYPE, TYPE_INT, RENDER_PNG) \
X(renderPath, RENDER_PATH, TYPE_STRING, ".") \
X(renderFormat, RENDER_FORMAT, TYPE_STRING, "{}.png") \
X(renderIsUseAnimationBounds,RENDER_IS_USE_ANIMATION_BOUNDS,TYPE_BOOL, true) \
X(renderIsTransparent, RENDER_IS_TRANSPARENT, TYPE_BOOL, true) \
X(renderScale, RENDER_SCALE, TYPE_FLOAT, 1.0f) \
X(renderFFmpegPath, RENDER_FFMPEG_PATH, TYPE_STRING, SETTINGS_RENDER_FFMPEG_PATH_VALUE_DEFAULT)
#define X(name, symbol, type, ...) \
const inline DATATYPE_TO_CTYPE(type) SETTINGS_##symbol##_DEFAULT = __VA_ARGS__;

View File

@@ -43,6 +43,6 @@ Alternatively, if you have subscribed to the mod, you can find the latest releas
[h3]Happy animating![/h3]
[img]https://files.catbox.moe/4auc1c.gif[/img]
</description>
<version>1.1</version>
<version>1.2</version>
<visibility>Public</visibility>
</metadata>