Added animation bounds for rendering animations, redid float format stuff
This commit is contained in:
28
src/COMMON.h
28
src/COMMON.h
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
|
||||
18
src/imgui.h
18
src/imgui.h
@@ -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.",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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__;
|
||||
|
||||
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user