Compare commits

...

5 Commits

Author SHA1 Message Date
Martin Gerhardy b879def00a UI: applied coding guidelines 2022-05-26 17:36:41 +02:00
Martin Gerhardy 384df5885b UI: removed vector interface 2022-05-26 17:15:03 +02:00
Martin Gerhardy a44c21ce84 VOXEDIT: show the view matrix manipulator in edit mode, too 2022-05-26 09:58:47 +02:00
Martin Gerhardy 004509d77f MAKE: fixed update-imguizmo target 2022-05-24 21:11:20 +02:00
Martin Gerhardy 8cee533420 VOXELFORMAT: helper method to access the parent MeshExt structure 2022-05-24 21:02:36 +02:00
9 changed files with 704 additions and 749 deletions

View File

@ -116,7 +116,6 @@ update-backward:
update-imguizmo:
$(call UPDATE_GIT,imguizmo,https://github.com/CedricGuillemet/ImGuizmo.git)
cp $(UPDATEDIR)/imguizmo.sync/ImGuizmo.* src/modules/ui/imgui/dearimgui
dos2unix src/modules/ui/imgui/dearimgui/ImSeq*
dos2unix src/modules/ui/imgui/dearimgui/ImGuizmo*
update-im-neo-sequencer:

View File

@ -2669,6 +2669,13 @@ namespace IMGUIZMO_NAMESPACE
}
}
void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor)
{
// Scale is always local or matrix will be skewed when applying world scale or oriented matrix
ComputeContext(view, projection, matrix, (operation & SCALE) ? LOCAL : mode);
ViewManipulate(view, length, position, size, backgroundColor);
}
void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor)
{
static bool isDraging = false;

View File

@ -210,6 +210,9 @@ namespace IMGUIZMO_NAMESPACE
//
IMGUI_API void ViewManipulate(float* view, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
// use this version if you did not call Manipulate before and you are just using ViewManipulate
IMGUI_API void ViewManipulate(float* view, const float* projection, OPERATION operation, MODE mode, float* matrix, float length, ImVec2 position, ImVec2 size, ImU32 backgroundColor);
IMGUI_API void SetID(int id);
// return true if the cursor is over the operation's gizmo

View File

@ -1,17 +1,19 @@
//
// Created by Matty on 2022-01-28.
//
#include "core/StandardLib.h"
#define IMGUI_DEFINE_MATH_OPERATORS
#include "imgui_neo_sequencer.h"
#include "imgui_internal.h"
#include "imgui_neo_internal.h"
#include "imgui_neo_sequencer.h"
#include <stack>
#include <iostream>
#include <unordered_map>
namespace ImGui {
struct ImGuiNeoSequencerInternalData {
ImVec2 StartCursor = {0, 0}; // Cursor in TL corner of whole widget
ImVec2 TopBarStartCursor = {0, 0}; // Cursor on top, below Zoom slider
@ -35,11 +37,14 @@ namespace ImGui {
uint32_t CurrentFrame = 0;
bool HoldingCurrentFrame = false; // Are we draging current frame?
ImVec4 CurrentFrameColor; // Color of current frame, we have to save it because we render on EndNeoSequencer, but process at BeginneoSequencer
ImVec4 CurrentFrameColor; // Color of current frame, we have to save it because we render on EndNeoSequencer, but
// process at BeginneoSequencer
bool HoldingZoomSlider = false;
};
using Map = std::unordered_map<ImGuiID, ImGuiNeoSequencerInternalData>;
static ImGuiNeoSequencerStyle style; // NOLINT(cert-err58-cpp)
// Global context stuff
@ -57,32 +62,34 @@ namespace ImGui {
static ImVector<ImGuiColorMod> sequencerColorStack;
// Data of all sequencers, this is main c++ part and I should create C alternative or use imgui ImVector or something
static std::unordered_map<ImGuiID, ImGuiNeoSequencerInternalData> sequencerData;
static Map sequencerData;
static uint32_t idCounter = 0;
static char idBuffer[16];
///////////// STATIC HELPERS ///////////////////////
static float getPerFrameWidth(ImGuiNeoSequencerInternalData &context) {
return GetPerFrameWidth(context.Size.x, context.ValuesWidth, context.EndFrame, context.StartFrame,
context.Zoom);
return GetPerFrameWidth(context.Size.x, context.ValuesWidth, context.EndFrame, context.StartFrame, context.Zoom);
}
static float getKeyframePositionX(uint32_t frame, ImGuiNeoSequencerInternalData &context) {
const auto perFrameWidth = getPerFrameWidth(context);
const float perFrameWidth = getPerFrameWidth(context);
return (float)(frame - context.OffsetFrame) * perFrameWidth;
}
static float getWorkTimelineWidth(ImGuiNeoSequencerInternalData &context) {
const auto perFrameWidth = getPerFrameWidth(context);
const float perFrameWidth = getPerFrameWidth(context);
return context.Size.x - context.ValuesWidth - perFrameWidth;
}
// Dont pull frame from context, its used for dragging
static ImRect getCurrentFrameBB(uint32_t frame, ImGuiNeoSequencerInternalData &context) {
const auto& imStyle = GetStyle();
const auto width = style.CurrentFramePointerSize * GetIO().FontGlobalScale;
const auto cursor =
const ImGuiStyle &imStyle = GetStyle();
const float width = style.CurrentFramePointerSize * GetIO().FontGlobalScale;
const ImVec2 cursor =
context.TopBarStartCursor + ImVec2{context.ValuesWidth + imStyle.FramePadding.x - width / 2.0f, 0};
const auto currentFrameCursor = cursor + ImVec2{ getKeyframePositionX(frame, context), 0 };
const ImVec2 currentFrameCursor = cursor + ImVec2{getKeyframePositionX(frame, context), 0};
float pointerHeight = style.CurrentFramePointerSize * 2.5f;
ImRect rect{currentFrameCursor, currentFrameCursor + ImVec2{width, pointerHeight * GetIO().FontGlobalScale}};
@ -91,21 +98,20 @@ namespace ImGui {
}
static void processCurrentFrame(uint32_t *frame, ImGuiNeoSequencerInternalData &context) {
auto pointerRect = getCurrentFrameBB(*frame, context);
ImRect pointerRect = getCurrentFrameBB(*frame, context);
pointerRect.Min -= ImVec2{2.0f, 2.0f};
pointerRect.Max += ImVec2{2.0f, 2.0f};
const auto& imStyle = GetStyle();
const ImGuiStyle &imStyle = GetStyle();
const auto timelineXmin = context.TopBarStartCursor.x + context.ValuesWidth + imStyle.FramePadding.x;
const float timelineXmin = context.TopBarStartCursor.x + context.ValuesWidth + imStyle.FramePadding.x;
const ImVec2 timelineXRange = {
timelineXmin, //min
timelineXmin + context.Size.x - context.ValuesWidth
};
const ImVec2 timelineXRange = {timelineXmin, // min
timelineXmin + context.Size.x - context.ValuesWidth};
if (!ItemAdd(pointerRect, 0))
if (!ItemAdd(pointerRect, 0)) {
return;
}
context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointer);
@ -115,18 +121,18 @@ namespace ImGui {
if (context.HoldingCurrentFrame) {
if (IsMouseDragging(ImGuiMouseButton_Left, 0.0f)) {
const auto mousePosX = GetMousePos().x;
const auto v = mousePosX - timelineXRange.x;// Subtract min
const float mousePosX = GetMousePos().x;
const float v = mousePosX - timelineXRange.x; // Subtract min
const auto normalized = v / getWorkTimelineWidth(context); //Divide by width to remap to 0 - 1 range
const float normalized = v / getWorkTimelineWidth(context); // Divide by width to remap to 0 - 1 range
const auto clamped = ImClamp(normalized, 0.0f, 1.0f);
const float clamped = ImClamp(normalized, 0.0f, 1.0f);
const auto viewSize = (float)(context.EndFrame - context.StartFrame) / context.Zoom;
const float viewSize = (float)(context.EndFrame - context.StartFrame) / context.Zoom;
const auto frameViewVal = (float)context.StartFrame + (clamped * (float)viewSize);
const float frameViewVal = (float)context.StartFrame + (clamped * (float)viewSize);
const auto finalFrame = (uint32_t)round(frameViewVal) + context.OffsetFrame;
const unsigned int finalFrame = (uint32_t)round(frameViewVal) + context.OffsetFrame;
context.CurrentFrameColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerPressed);
@ -153,108 +159,81 @@ namespace ImGui {
}
static bool createKeyframe(uint32_t *frame) {
const auto& imStyle = GetStyle();
auto& context = sequencerData[currentSequencer];
const ImGuiStyle &imStyle = GetStyle();
Map::mapped_type &context = sequencerData[currentSequencer];
const auto timelineOffset = getKeyframePositionX(*frame, context);
const float timelineOffset = getKeyframePositionX(*frame, context);
const auto pos = ImVec2{ context.StartValuesCursor.x + imStyle.FramePadding.x, context.ValuesCursor.y } +
const ImVec2 pos = ImVec2{context.StartValuesCursor.x + imStyle.FramePadding.x, context.ValuesCursor.y} +
ImVec2{timelineOffset + context.ValuesWidth, 0};
const auto bbPos = pos - ImVec2{ currentTimelineHeight / 2, 0 };
const ImVec2 bbPos = pos - ImVec2{currentTimelineHeight / 2, 0};
const ImRect bb = {bbPos, bbPos + ImVec2{currentTimelineHeight, currentTimelineHeight}};
if (!ItemAdd(bb, 0))
if (!ItemAdd(bb, 0)) {
return false;
}
const auto drawList = ImGui::GetWindowDrawList();
ImDrawList *drawList = ImGui::GetWindowDrawList();
drawList->AddCircleFilled(pos + ImVec2{ 0, currentTimelineHeight / 2.f }, currentTimelineHeight / 3.0f,
IsItemHovered() ?
ColorConvertFloat4ToU32(
GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_KeyframeHovered)) :
ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_Keyframe)),
drawList->AddCircleFilled(
pos + ImVec2{0, currentTimelineHeight / 2.f}, currentTimelineHeight / 3.0f,
IsItemHovered() ? ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_KeyframeHovered))
: ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_Keyframe)),
4);
return true;
}
static uint32_t idCounter = 0;
static char idBuffer[16];
const char* generateID() {
static const char *generateID() {
idBuffer[0] = '#';
idBuffer[1] = '#';
memset(idBuffer + 2, 0, 14);
snprintf(idBuffer + 2, 14, "%o", idCounter++);
core_memset(idBuffer + 2, 0, 14);
SDL_snprintf(idBuffer + 2, 14, "%o", idCounter++);
return &idBuffer[0];
}
void resetID() {
static void resetID() {
idCounter = 0;
}
static void renderCurrentFrame(ImGuiNeoSequencerInternalData &context) {
const auto bb = getCurrentFrameBB(context.CurrentFrame, context);
const ImRect bb = getCurrentFrameBB(context.CurrentFrame, context);
const auto drawList = ImGui::GetWindowDrawList();
ImDrawList *drawList = ImGui::GetWindowDrawList();
RenderNeoSequencerCurrentFrame(
GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerLine),
context.CurrentFrameColor,
bb,
context.Size.y - context.TopBarSize.y,
style.CurrentFrameLineWidth,
drawList
);
RenderNeoSequencerCurrentFrame(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_FramePointerLine),
context.CurrentFrameColor, bb, context.Size.y - context.TopBarSize.y,
style.CurrentFrameLineWidth, drawList);
}
static void processAndRenderZoom(ImGuiNeoSequencerInternalData &context, bool allowEditingLength, uint32_t *start,
uint32_t *end) {
const auto& imStyle = GetStyle();
const ImGuiStyle &imStyle = GetStyle();
ImGuiWindow *window = GetCurrentWindow();
const auto zoomHeight = GetFontSize() * style.ZoomHeightScale;
const float zoomHeight = GetFontSize() * style.ZoomHeightScale;
auto* drawList = GetWindowDrawList();
ImDrawList *drawList = GetWindowDrawList();
// Input width
const auto inputWidth = CalcTextSize("123456").x;
const float inputWidth = CalcTextSize("123456").x;
const auto inputWidthWithPadding = inputWidth + imStyle.ItemSpacing.x;
const float inputWidthWithPadding = inputWidth + imStyle.ItemSpacing.x;
const auto cursor = allowEditingLength ? context.StartCursor + ImVec2{ inputWidthWithPadding, 0 }
: context.StartCursor;
const ImVec2 cursor =
allowEditingLength ? context.StartCursor + ImVec2{inputWidthWithPadding, 0} : context.StartCursor;
const auto size = allowEditingLength ?
context.Size.x - 2 * inputWidthWithPadding :
context.Size.x;
const float size = allowEditingLength ? context.Size.x - 2 * inputWidthWithPadding : context.Size.x;
const ImRect bb{cursor, cursor + ImVec2{size, zoomHeight}};
const ImVec2 frameNumberBorderSize{inputWidth - imStyle.FramePadding.x, zoomHeight};
//const ImVec2 startFrameTextCursor{context.StartCursor + ImVec2{imStyle.FramePadding.x, 0}};
// Text number borders
//drawList->AddRect(startFrameTextCursor, startFrameTextCursor + frameNumberBorderSize,ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_TimelineBorder)));
const auto zoomBarEndWithSpacing = ImVec2{ bb.Max.x + imStyle.ItemSpacing.x, context.StartCursor.y };
/*
drawList->AddRect(zoomBarEndWithSpacing,
zoomBarEndWithSpacing + frameNumberBorderSize,ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_TimelineBorder)));
*/
const ImVec2 zoomBarEndWithSpacing = ImVec2{bb.Max.x + imStyle.ItemSpacing.x, context.StartCursor.y};
int32_t startFrameVal = (int32_t)*start;
int32_t endFrameVal = (int32_t)*end;
if (allowEditingLength) {
auto prevWindowCursor = window->DC.CursorPos;
ImVec2 prevWindowCursor = window->DC.CursorPos;
PushItemWidth(inputWidth);
InputScalar("##input_start_frame", ImGuiDataType_U32, &startFrameVal, NULL, NULL, NULL,
@ -269,56 +248,49 @@ namespace ImGui {
window->DC.CursorPos = prevWindowCursor;
}
if (startFrameVal < 0)
if (startFrameVal < 0) {
startFrameVal = (int32_t)*start;
}
if (endFrameVal < 0)
if (endFrameVal < 0) {
endFrameVal = (int32_t)*end;
}
if (endFrameVal <= startFrameVal)
if (endFrameVal <= startFrameVal) {
endFrameVal = (int32_t)*end;
}
*start = startFrameVal;
*end = endFrameVal;
//drawList->AddText(startFrameTextCursor + ImVec2{frameNumberBorderSize.x, 0} - ImVec2{numberTextWidth,0},IM_COL32_WHITE,numberText);
// drawList->AddText(startFrameTextCursor + ImVec2{frameNumberBorderSize.x, 0} -
// ImVec2{numberTextWidth,0},IM_COL32_WHITE,numberText);
// Background
drawList->AddRectFilled(bb.Min, bb.Max,
ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarBg)),
10.0f);
drawList->AddRectFilled(
bb.Min, bb.Max, ColorConvertFloat4ToU32(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarBg)), 10.0f);
const auto baseWidth = bb.GetSize().x -
const float baseWidth =
bb.GetSize().x -
imStyle.ItemInnerSpacing.x; // There is just half spacing applied, doing it normally makes big gap on sides
const auto sliderHeight = bb.GetSize().y - imStyle.ItemInnerSpacing.y;
const auto sliderWidth = baseWidth / context.Zoom;
const auto sliderMin = bb.Min + imStyle.ItemInnerSpacing / 2.0f;
//const auto sliderMax = bb.Max - imStyle.ItemInnerSpacing / 2.0f;
const auto sliderMaxWidth = baseWidth;
const auto totalFrames = (*end - *start);
const auto singleFrameWidthOffset = sliderMaxWidth / (float)totalFrames;
const auto zoomSliderOffset = singleFrameWidthOffset * (float)context.OffsetFrame;
const auto sliderStart = sliderMin + ImVec2{ zoomSliderOffset, 0 };
const float sliderHeight = bb.GetSize().y - imStyle.ItemInnerSpacing.y;
const float sliderWidth = baseWidth / context.Zoom;
const ImVec2 sliderMin = bb.Min + imStyle.ItemInnerSpacing / 2.0f;
const float sliderMaxWidth = baseWidth;
const unsigned int totalFrames = (*end - *start);
const float singleFrameWidthOffset = sliderMaxWidth / (float)totalFrames;
const float zoomSliderOffset = singleFrameWidthOffset * (float)context.OffsetFrame;
const ImVec2 sliderStart = sliderMin + ImVec2{zoomSliderOffset, 0};
const float sideSize = sliderHeight;
const ImRect finalSliderBB{sliderStart, sliderStart + ImVec2{sliderWidth, sliderHeight}};
const ImRect finalSliderInteractBB = {finalSliderBB.Min + ImVec2{sideSize, 0},
finalSliderBB.Max - ImVec2{sideSize, 0}};
const auto resBG = ItemAdd(bb, 0);
const bool resBG = ItemAdd(bb, 0);
const auto viewWidth = (uint32_t)((float)totalFrames / context.Zoom);
const uint32_t viewWidth = (uint32_t)((float)totalFrames / context.Zoom);
if (resBG) {
if (IsItemHovered()) {
@ -326,7 +298,7 @@ namespace ImGui {
const float currentScroll = GetIO().MouseWheel;
context.Zoom = ImClamp(context.Zoom + currentScroll, 1.0f, (float)viewWidth);
const auto newZoomWidth = (uint32_t)((float)totalFrames / context.Zoom);
const uint32_t newZoomWidth = (uint32_t)((float)totalFrames / context.Zoom);
if (*start + context.OffsetFrame + newZoomWidth > *end)
context.OffsetFrame = ImMax(0U, totalFrames - viewWidth);
@ -334,28 +306,23 @@ namespace ImGui {
if (context.HoldingZoomSlider) {
if (IsMouseDragging(ImGuiMouseButton_Left, 0.01f)) {
const auto currentX = GetMousePos().x;
const float currentX = GetMousePos().x;
const float v = currentX - bb.Min.x; // Subtract min
const float normalized = v / bb.GetWidth(); // Divide by width to remap to 0 - 1 range
const float sliderWidthNormalized = 1.0f / context.Zoom;
const float singleFrameWidthOffsetNormalized = singleFrameWidthOffset / bb.GetWidth();
const auto v = currentX - bb.Min.x;// Subtract min
const auto normalized = v / bb.GetWidth(); //Divide by width to remap to 0 - 1 range
const auto sliderWidthNormalized = 1.0f / context.Zoom;
const auto singleFrameWidthOffsetNormalized = singleFrameWidthOffset / bb.GetWidth();
uint32_t finalFrame = (uint32_t)((float)(normalized - sliderWidthNormalized / 2.0f) / singleFrameWidthOffsetNormalized);
uint32_t finalFrame =
(uint32_t)((float)(normalized - sliderWidthNormalized / 2.0f) / singleFrameWidthOffsetNormalized);
if (normalized - sliderWidthNormalized / 2.0f < 0.0f) {
finalFrame = 0;
}
if (normalized + sliderWidthNormalized / 2.0f > 1.0f) {
finalFrame = totalFrames - viewWidth;
}
context.OffsetFrame = finalFrame;
}
@ -369,14 +336,13 @@ namespace ImGui {
}
}
const auto res = ItemAdd(finalSliderInteractBB, 0);
const bool res = ItemAdd(finalSliderInteractBB, 0);
const auto viewStart = *start + (uint32_t)context.OffsetFrame;
const auto viewEnd = viewStart + viewWidth;
const unsigned int viewStart = *start + (uint32_t)context.OffsetFrame;
const unsigned int viewEnd = viewStart + viewWidth;
if (res) {
auto sliderColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarSlider);
ImVec4 sliderColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarSlider);
if (IsItemHovered()) {
sliderColor = GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_ZoomBarSliderHovered);
@ -385,18 +351,14 @@ namespace ImGui {
// Render bar
drawList->AddRectFilled(finalSliderBB.Min, finalSliderBB.Max, ColorConvertFloat4ToU32(sliderColor), 10.0f);
const auto sliderCenter = finalSliderBB.GetCenter();
const ImVec2 sliderCenter = finalSliderBB.GetCenter();
char overlayTextBuffer[128];
SDL_snprintf(overlayTextBuffer, sizeof(overlayTextBuffer), "%d - %d", viewStart, viewEnd);
snprintf(overlayTextBuffer, sizeof(overlayTextBuffer), "%d - %d", viewStart, viewEnd);
const auto overlaySize = CalcTextSize(overlayTextBuffer);
const ImVec2 overlaySize = CalcTextSize(overlayTextBuffer);
drawList->AddText(sliderCenter - overlaySize / 2.0f, IM_COL32_WHITE, overlayTextBuffer);
}
}
////////////////////////////////////
const ImVec4 &GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol idx) {
return GetNeoSequencerStyle().Colors[idx];
@ -406,83 +368,78 @@ namespace ImGui {
return style;
}
bool
BeginNeoSequencer(const char* idin, uint32_t* frame, uint32_t* startFrame, uint32_t* endFrame, const ImVec2& size,
bool BeginNeoSequencer(const char *idin, uint32_t *frame, uint32_t *startFrame, uint32_t *endFrame, const ImVec2 &size,
ImGuiNeoSequencerFlags flags) {
IM_ASSERT(!inSequencer && "Called when while in other NeoSequencer, that won't work, call End!");
IM_ASSERT(*startFrame < *endFrame && "Start frame must be smaller than end frame");
//ImGuiContext &g = *GImGui;
ImGuiWindow *window = GetCurrentWindow();
const auto& imStyle = GetStyle();
//auto &neoStyle = GetNeoSequencerStyle();
const ImGuiStyle &imStyle = GetStyle();
if (inSequencer)
if (inSequencer) {
return false;
}
if (window->SkipItems)
if (window->SkipItems) {
return false;
}
const auto drawList = GetWindowDrawList();
ImDrawList *drawList = GetWindowDrawList();
const auto cursor = GetCursorScreenPos();
const auto area = ImGui::GetContentRegionAvail();
//const auto cursorBasePos = GetCursorScreenPos() + window->Scroll;
//const ImRect clip = { cursorBasePos, cursorBasePos + window->ContentRegionRect.GetSize() };
const ImVec2 cursor = GetCursorScreenPos();
const ImVec2 area = ImGui::GetContentRegionAvail();
PushID(idin);
const auto id = window->IDStack[window->IDStack.size() - 1];
const ImGuiID id = window->IDStack[window->IDStack.size() - 1];
inSequencer = true;
auto& context = sequencerData[id];
Map::mapped_type &context = sequencerData[id];
auto realSize = ImFloor(size);
if (realSize.x <= 0.0f)
ImVec2 realSize = ImFloor(size);
if (realSize.x <= 0.0f) {
realSize.x = ImMax(4.0f, area.x);
if (realSize.y <= 0.0f)
}
if (realSize.y <= 0.0f) {
realSize.y = ImMax(4.0f, context.FilledHeight);
}
const bool showZoom = !(flags & ImGuiNeoSequencerFlags_HideZoom);
context.StartCursor = cursor;
// If Zoom is shown, we offset it by height of Zoom bar + padding
context.TopBarStartCursor = showZoom ? cursor +
ImVec2{ 0, GetFontSize() * style.ZoomHeightScale + imStyle.FramePadding.y }
: cursor;
context.TopBarStartCursor =
showZoom ? cursor + ImVec2{0, GetFontSize() * style.ZoomHeightScale + imStyle.FramePadding.y} : cursor;
context.StartFrame = *startFrame;
context.EndFrame = *endFrame;
context.Size = realSize;
currentSequencer = window->IDStack[window->IDStack.size() - 1];
currentSequencer = id;
RenderNeoSequencerBackground(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_Bg), context.StartCursor,
context.Size,
drawList, style.SequencerRounding);
context.Size, drawList, style.SequencerRounding);
RenderNeoSequencerTopBarBackground(GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_TopBarBg),
context.TopBarStartCursor, context.TopBarSize,
drawList, style.SequencerRounding);
context.TopBarStartCursor, context.TopBarSize, drawList,
style.SequencerRounding);
RenderNeoSequencerTopBarOverlay(context.Zoom, context.ValuesWidth, context.StartFrame, context.EndFrame,
context.OffsetFrame,
context.TopBarStartCursor, context.TopBarSize, drawList,
context.OffsetFrame, context.TopBarStartCursor, context.TopBarSize, drawList,
style.TopBarShowFrameLines, style.TopBarShowFrameTexts);
if (showZoom)
if (showZoom) {
processAndRenderZoom(context, flags & ImGuiNeoSequencerFlags_AllowLengthChanging, startFrame, endFrame);
}
context.TopBarSize = ImVec2(context.Size.x, style.TopBarHeight);
if (context.TopBarSize.y <= 0.0f)
if (context.TopBarSize.y <= 0.0f) {
context.TopBarSize.y = CalcTextSize("100").y + imStyle.FramePadding.y * 2.0f;
}
if (context.Size.y < context.FilledHeight)
if (context.Size.y < context.FilledHeight) {
context.Size.y = context.FilledHeight;
}
context.FilledHeight = context.TopBarSize.y + style.TopBarSpacing +
(showZoom ? imStyle.FramePadding.y + style.ZoomHeightScale + GetFontSize() : 0.0f);
@ -499,8 +456,7 @@ namespace ImGui {
IM_ASSERT(inSequencer && "Called end sequencer when BeginSequencer didnt return true or wasn't called at all!");
IM_ASSERT(sequencerData.count(currentSequencer) != 0 && "Ended sequencer has no context!");
auto& context = sequencerData[currentSequencer];
//auto &imStyle = GetStyle();
Map::mapped_type &context = sequencerData[currentSequencer];
renderCurrentFrame(context);
@ -508,7 +464,7 @@ namespace ImGui {
const ImVec2 min = {0, 0};
context.Size.y = context.FilledHeight;
const auto max = context.Size;
const ImVec2 max = context.Size;
ItemSize({min, max});
PopID();
@ -523,59 +479,50 @@ namespace ImGui {
return EndNeoTimeLine();
}
static bool groupBehaviour(const ImGuiID id, bool* open, const ImVec2 labelSize) {
auto& context = sequencerData[currentSequencer];
static bool groupBehaviour(const ImGuiID id, bool *open, const ImVec2 &labelSize) {
Map::mapped_type &context = sequencerData[currentSequencer];
ImGuiWindow *window = GetCurrentWindow();
const bool closable = open != nullptr;
auto drawList = ImGui::GetWindowDrawList();
ImDrawList *drawList = ImGui::GetWindowDrawList();
const float arrowWidth = drawList->_Data->FontSize;
const ImVec2 arrowSize = {arrowWidth, arrowWidth};
const ImRect arrowBB = {
context.ValuesCursor,
context.ValuesCursor + arrowSize
};
const ImRect arrowBB = {context.ValuesCursor, context.ValuesCursor + arrowSize};
const ImVec2 groupBBMin = {context.ValuesCursor + ImVec2{arrowSize.x, 0.0f}};
const ImRect groupBB = {
groupBBMin,
groupBBMin + labelSize
};
const ImRect groupBB = {groupBBMin, groupBBMin + labelSize};
const ImGuiID arrowID = window->GetID(generateID());
const auto addArrowRes = ItemAdd(arrowBB, arrowID);
const bool addArrowRes = ItemAdd(arrowBB, arrowID);
if (addArrowRes) {
if (IsItemClicked() && closable)
if (IsItemClicked() && closable) {
(*open) = !(*open);
}
}
const auto addGroupRes = ItemAdd(groupBB, id);
const bool addGroupRes = ItemAdd(groupBB, id);
if (addGroupRes) {
if (IsItemClicked()) {
context.SelectedTimeline = context.SelectedTimeline == id ? 0 : id;
}
}
const float width = groupBB.Max.x - arrowBB.Min.x;
context.ValuesWidth = std::max(context.ValuesWidth, width); // Make left panel wide enough
context.ValuesWidth = core_max(context.ValuesWidth, width); // Make left panel wide enough
return addGroupRes && addArrowRes;
}
static bool timelineBehaviour(const ImGuiID id, const ImVec2 labelSize) {
auto& context = sequencerData[currentSequencer];
//ImGuiWindow *window = GetCurrentWindow();
static bool timelineBehaviour(const ImGuiID id, const ImVec2 &labelSize) {
Map::mapped_type &context = sequencerData[currentSequencer];
const ImRect groupBB = {
context.ValuesCursor,
context.ValuesCursor + labelSize
};
const ImRect groupBB{context.ValuesCursor, context.ValuesCursor + labelSize};
const auto addGroupRes = ItemAdd(groupBB, id);
const bool addGroupRes = ItemAdd(groupBB, id);
if (addGroupRes) {
if (IsItemClicked()) {
context.SelectedTimeline = context.SelectedTimeline == id ? 0 : id;
}
}
const float width = groupBB.Max.x - groupBB.Min.x;
context.ValuesWidth = std::max(context.ValuesWidth, width); // Make left panel wide enough
context.ValuesWidth = core_max(context.ValuesWidth, width); // Make left panel wide enough
return addGroupRes;
}
@ -586,24 +533,22 @@ namespace ImGui {
const bool closable = open != nullptr;
auto& context = sequencerData[currentSequencer];
const auto& imStyle = GetStyle();
Map::mapped_type &context = sequencerData[currentSequencer];
const ImGuiStyle &imStyle = GetStyle();
ImGuiWindow *window = GetCurrentWindow();
const ImGuiID id = window->GetID(label);
auto labelSize = CalcTextSize(label);
ImVec2 labelSize = CalcTextSize(label);
labelSize.y += imStyle.FramePadding.y * 2 + style.ItemSpacing.y * 2;
labelSize.x += imStyle.FramePadding.x * 2 + style.ItemSpacing.x * 2 +
(float)currentTimelineDepth * style.DepthItemSpacing;
labelSize.x +=
imStyle.FramePadding.x * 2 + style.ItemSpacing.x * 2 + (float)currentTimelineDepth * style.DepthItemSpacing;
bool isGroup = flags & ImGuiNeoTimelineFlags_Group && closable;
bool addRes = false;
if (isGroup) {
labelSize.x += imStyle.ItemSpacing.x + GetFontSize();
addRes = groupBehaviour(id, open, labelSize);
}
else {
} else {
addRes = timelineBehaviour(id, labelSize);
}
@ -615,21 +560,19 @@ namespace ImGui {
context.FilledHeight += currentTimelineHeight;
if (addRes) {
RenderNeoTimelane(id == context.SelectedTimeline,
context.ValuesCursor + ImVec2{ context.ValuesWidth, 0 },
RenderNeoTimelane(id == context.SelectedTimeline, context.ValuesCursor + ImVec2{context.ValuesWidth, 0},
ImVec2{context.Size.x - context.ValuesWidth, currentTimelineHeight},
GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol_SelectedTimeline));
ImVec4 color = GetStyleColorVec4(ImGuiCol_Text);
if (IsItemHovered()) color.w *= 0.7f;
if (IsItemHovered()) {
color.w *= 0.7f;
}
RenderNeoTimelineLabel(label,
context.ValuesCursor + imStyle.FramePadding +
ImVec2{(float)currentTimelineDepth * style.DepthItemSpacing, 0},
labelSize,
color,
isGroup,
isGroup && (*open));
labelSize, color, isGroup, isGroup && (*open));
}
for (uint32_t i = 0; i < keyframeCount; i++) {
@ -639,40 +582,26 @@ namespace ImGui {
context.ValuesCursor.x += imStyle.FramePadding.x + (float)currentTimelineDepth * style.DepthItemSpacing;
context.ValuesCursor.y += currentTimelineHeight;
const auto result = !closable || (*open);
const bool result = !closable || (*open);
if (result) {
currentTimelineDepth++;
}
else {
} else {
finishPreviousTimeline(context);
}
return result;
}
void EndNeoTimeLine() {
auto& context = sequencerData[currentSequencer];
Map::mapped_type &context = sequencerData[currentSequencer];
finishPreviousTimeline(context);
currentTimelineDepth--;
}
bool NeoBeginCreateKeyframe(uint32_t *frame) {
return false;
}
#ifdef __cplusplus
bool BeginNeoTimeline(const char* label, std::vector<uint32_t>& keyframes, bool* open) {
std::vector<uint32_t*> c_keyframes{ keyframes.size() };
for (uint32_t i = 0; i < keyframes.size(); i++)
c_keyframes[i] = &keyframes[i];
return BeginNeoTimeline(label, c_keyframes.data(), c_keyframes.size(), open);
}
#endif
void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, ImU32 col) {
ImGuiColorMod backup;
backup.Col = idx;
@ -698,7 +627,7 @@ namespace ImGui {
}
}
}
} // namespace ImGui
ImGuiNeoSequencerStyle::ImGuiNeoSequencerStyle() {
Colors[ImGuiNeoSequencerCol_Bg] = ImVec4{0.31f, 0.31f, 0.31f, 1.00f};
@ -722,5 +651,4 @@ ImGuiNeoSequencerStyle::ImGuiNeoSequencerStyle() {
Colors[ImGuiNeoSequencerCol_ZoomBarSliderHovered] = ImVec4{0.98f, 0.98f, 0.98f, 0.80f};
Colors[ImGuiNeoSequencerCol_ZoomBarSliderEnds] = ImVec4{0.59f, 0.59f, 0.59f, 0.90f};
Colors[ImGuiNeoSequencerCol_ZoomBarSliderEndsHovered] = ImVec4{0.93f, 0.93f, 0.93f, 0.93f};
}

View File

@ -2,37 +2,31 @@
// Created by Matty on 2022-01-28.
//
#ifndef IMGUI_NEO_SEQUENCER_H
#define IMGUI_NEO_SEQUENCER_H
#pragma once
#include "imgui.h"
#include <vector>
typedef int ImGuiNeoSequencerFlags;
typedef int ImGuiNeoSequencerCol;
typedef int ImGuiNeoTimelineFlags;
// Flags for ImGui::BeginNeoSequencer()
enum ImGuiNeoSequencerFlags_
{
enum ImGuiNeoSequencerFlags_ {
ImGuiNeoSequencerFlags_None = 0,
ImGuiNeoSequencerFlags_AllowLengthChanging = 1 << 0,
ImGuiNeoSequencerFlags_AllowSelection = 1 << 1,
ImGuiNeoSequencerFlags_HideZoom = 1 << 2,
ImGuiNeoSequencerFlags_ZoomBottomOverlay = 1 << 3,
};
// Flags for ImGui::BeginNeoTimeline()
enum ImGuiNeoTimelineFlags_
{
enum ImGuiNeoTimelineFlags_ {
ImGuiNeoTimelineFlags_None = 0,
ImGuiNeoTimelineFlags_AllowFrameChanging = 1 << 0,
ImGuiNeoTimelineFlags_Group = 1 << 1,
};
enum ImGuiNeoSequencerCol_
{
enum ImGuiNeoSequencerCol_ {
ImGuiNeoSequencerCol_Bg,
ImGuiNeoSequencerCol_TopBarBg,
ImGuiNeoSequencerCol_SelectedTimeline,
@ -73,6 +67,7 @@ struct ImGuiNeoSequencerStyle {
};
namespace ImGui {
IMGUI_API const ImVec4 &GetStyleNeoSequencerColorVec4(ImGuiNeoSequencerCol idx);
IMGUI_API ImGuiNeoSequencerStyle &GetNeoSequencerStyle();
@ -80,22 +75,20 @@ namespace ImGui {
IMGUI_API void PushNeoSequencerStyleColor(ImGuiNeoSequencerCol idx, const ImVec4 &col);
IMGUI_API void PopNeoSequencerStyleColor(int count = 1);
IMGUI_API bool BeginNeoSequencer(const char* id, uint32_t * frame, uint32_t * startFrame, uint32_t * endFrame,const ImVec2& size = ImVec2(0, 0),ImGuiNeoSequencerFlags flags = ImGuiNeoSequencerFlags_None);
IMGUI_API void EndNeoSequencer(); //Call only when BeginNeoSequencer() returns true!!
IMGUI_API bool BeginNeoSequencer(const char *id, uint32_t *frame, uint32_t *startFrame, uint32_t *endFrame,
const ImVec2 &size = ImVec2(0, 0),
ImGuiNeoSequencerFlags flags = ImGuiNeoSequencerFlags_None);
// Call only when BeginNeoSequencer() returns true!!
IMGUI_API void EndNeoSequencer();
IMGUI_API bool BeginNeoGroup(const char *label, bool *open = nullptr);
IMGUI_API void EndNeoGroup();
IMGUI_API bool BeginNeoTimeline(const char* label,uint32_t ** keyframes, uint32_t keyframeCount, bool * open = nullptr, ImGuiNeoTimelineFlags flags = ImGuiNeoTimelineFlags_None);
IMGUI_API void EndNeoTimeLine(); //Call only when BeginNeoTimeline() returns true!!
IMGUI_API bool BeginNeoTimeline(const char *label, uint32_t **keyframes, uint32_t keyframeCount, bool *open = nullptr,
ImGuiNeoTimelineFlags flags = ImGuiNeoTimelineFlags_None);
// Call only when BeginNeoTimeline() returns true!!
IMGUI_API void EndNeoTimeLine();
IMGUI_API bool NeoBeginCreateKeyframe(uint32_t *frame);
#ifdef __cplusplus
// C++ helper
IMGUI_API bool BeginNeoTimeline(const char* label,std::vector<uint32_t> & keyframes ,bool * open = nullptr);
#endif
}
#endif //IMGUI_NEO_SEQUENCER_H
} // namespace ImGui

View File

@ -25,6 +25,19 @@
namespace voxelformat {
MeshFormat::MeshExt* MeshFormat::getParent(const voxelformat::SceneGraph &sceneGraph, MeshFormat::Meshes &meshes, int nodeId) {
if (!sceneGraph.hasNode(nodeId)) {
return nullptr;
}
const int parent = sceneGraph.node(nodeId).parent();
for (MeshExt &me : meshes) {
if (me.nodeId == parent) {
return &me;
}
}
return nullptr;
}
glm::vec3 MeshFormat::getScale() {
const float scale = core::Var::getSafe(cfg::VoxformatScale)->floatVal();

View File

@ -31,6 +31,8 @@ protected:
const glm::vec3 &scale = glm::vec3(1.0f), bool quad = false, bool withColor = true,
bool withTexCoords = true) = 0;
static MeshExt* getParent(const voxelformat::SceneGraph &sceneGraph, Meshes &meshes, int nodeId);
static glm::vec3 getScale();
// checks if the winding needs flipping if the scale values are negative
static bool flipWinding(const glm::vec3 &scale);

View File

@ -6,8 +6,8 @@
#include "IconsForkAwesome.h"
#include "core/ArrayLength.h"
#include "core/collection/DynamicArray.h"
#include "ui/imgui/dearimgui/imgui_neo_sequencer.h"
#include "ui/imgui/dearimgui/imgui.h"
#include "ui/imgui/dearimgui/imgui_neo_sequencer.h"
#include "voxedit-util/SceneManager.h"
#include "voxelformat/SceneGraph.h"
#include "voxelformat/SceneGraphNode.h"
@ -43,7 +43,10 @@ void AnimationTimeline::update(const char *sequencerTitle, ImGuiID dockIdMainDow
for (voxelformat::SceneGraphKeyFrame &kf : modelNode.keyFrames()) {
keys.push_back(&kf.frame);
}
if (ImGui::BeginNeoTimeline(modelNode.name().c_str(), keys.data(), keys.size(), nullptr)) {
const char *label = modelNode.name().c_str();
uint32_t **keyframes = keys.data();
const uint32_t keyframeCount = keys.size();
if (ImGui::BeginNeoTimeline(label, keyframes, keyframeCount, nullptr, ImGuiNeoTimelineFlags_None)) {
sceneMgr().setCurrentFrame(currentFrame);
ImGui::EndNeoTimeLine();
}

View File

@ -214,9 +214,6 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const
return;
}
const EditMode editMode = sceneMgr().editMode();
if (editMode != EditMode::Scene) {
return;
}
ImGuiIO &io = ImGui::GetIO();
@ -251,6 +248,7 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const
ImGuizmo::SetDrawlist();
ImGuizmo::SetRect(ImGui::GetWindowPos().x, ImGui::GetWindowPos().y + headerSize, size.x, size.y);
ImGuizmo::SetOrthographic(camera.mode() == video::CameraMode::Orthogonal);
if (editMode == EditMode::Scene) {
const float step = (float)core::Var::getSafe(cfg::VoxEditGridsize)->intVal();
const float snap[]{step, step, step};
const uint32_t keyFrame = node.keyFrameForFrame(sceneMgr().currentFrame());
@ -260,6 +258,7 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const
ImGuizmo::Manipulate(glm::value_ptr(camera.viewMatrix()), glm::value_ptr(camera.projectionMatrix()),
(ImGuizmo::OPERATION)operation, mode, glm::value_ptr(transformMatrix),
glm::value_ptr(deltaMatrix), _guizmoSnap->boolVal() ? snap : nullptr);
if (editMode == EditMode::Scene) {
if (ImGuizmo::IsUsing()) {
_guizmoActivated = true;
sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, false);
@ -267,10 +266,18 @@ void Viewport::renderGizmo(video::Camera &camera, const float headerSize, const
sceneMgr().nodeUpdateTransform(-1, transformMatrix, &deltaMatrix, keyFrame, true);
_guizmoActivated = false;
}
}
}
glm::mat4 viewMatrix = camera.viewMatrix();
if (editMode == EditMode::Scene) {
ImGuizmo::ViewManipulate(glm::value_ptr(viewMatrix), camera.targetDistance(), ImGui::GetWindowPos(),
ImVec2(128, 128), 0);
} else {
glm::mat4 transformMatrix = glm::mat4(1.0f); // not used
ImGuizmo::ViewManipulate(glm::value_ptr(viewMatrix), glm::value_ptr(camera.projectionMatrix()),
(ImGuizmo::OPERATION)operation, mode, glm::value_ptr(transformMatrix), camera.targetDistance(), ImGui::GetWindowPos(),
ImVec2(128, 128), 0);
}
if (viewMatrix != camera.viewMatrix()) {
glm::vec3 scale;
glm::vec3 translation;