mirror of https://github.com/bkaradzic/bgfx
Merge branch 'master' of https://github.com/bkaradzic/bgfx into svt-example
This commit is contained in:
commit
6882d8e585
|
@ -379,6 +379,9 @@ CODE
|
||||||
- 2018/08/01 (1.63) - renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to ConfigMacOSXBehaviors for consistency.
|
- 2018/08/01 (1.63) - renamed io.OptCursorBlink to io.ConfigCursorBlink [-> io.ConfigInputTextCursorBlink in 1.65], io.OptMacOSXBehaviors to ConfigMacOSXBehaviors for consistency.
|
||||||
- 2018/07/22 (1.63) - changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecisions over time.
|
- 2018/07/22 (1.63) - changed ImGui::GetTime() return value from float to double to avoid accumulating floating point imprecisions over time.
|
||||||
- 2018/07/08 (1.63) - style: renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete).
|
- 2018/07/08 (1.63) - style: renamed ImGuiCol_ModalWindowDarkening to ImGuiCol_ModalWindowDimBg for consistency with other features. Kept redirection enum (will obsolete).
|
||||||
|
- 2018/06/08 (1.62) - examples: the imgui_impl_xxx files have been split to separate platform (Win32, Glfw, SDL2, etc.) from renderer (DX11, OpenGL, Vulkan, etc.).
|
||||||
|
old binding will still work as is, however prefer using the separated bindings as they will be updated to be multi-viewport conformant.
|
||||||
|
when adopting new bindings follow the main.cpp code of your preferred examples/ folder to know which functions to call.
|
||||||
- 2018/06/06 (1.62) - renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish other variants and discourage using the full set.
|
- 2018/06/06 (1.62) - renamed GetGlyphRangesChinese() to GetGlyphRangesChineseFull() to distinguish other variants and discourage using the full set.
|
||||||
- 2018/06/06 (1.62) - TreeNodeEx()/TreeNodeBehavior(): the ImGuiTreeNodeFlags_CollapsingHeader helper now include the ImGuiTreeNodeFlags_NoTreePushOnOpen flag. See Changelog for details.
|
- 2018/06/06 (1.62) - TreeNodeEx()/TreeNodeBehavior(): the ImGuiTreeNodeFlags_CollapsingHeader helper now include the ImGuiTreeNodeFlags_NoTreePushOnOpen flag. See Changelog for details.
|
||||||
- 2018/05/03 (1.61) - DragInt(): the default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more.
|
- 2018/05/03 (1.61) - DragInt(): the default compile-time format string has been changed from "%.0f" to "%d", as we are not using integers internally any more.
|
||||||
|
@ -2534,6 +2537,7 @@ void ImGui::SetActiveID(ImGuiID id, ImGuiWindow* window)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME-NAV: The existence of SetNavID/SetNavIDWithRectRel/SetFocusID is incredibly messy and confusing and needs some explanation or refactoring.
|
||||||
void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
|
void ImGui::SetFocusID(ImGuiID id, ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
@ -2973,7 +2977,7 @@ void ImGui::StartMouseMovingWindow(ImGuiWindow* window)
|
||||||
|
|
||||||
// Handle mouse moving window
|
// Handle mouse moving window
|
||||||
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
|
// Note: moving window with the navigation keys (Square + d-pad / CTRL+TAB + Arrows) are processed in NavUpdateWindowing()
|
||||||
void ImGui::UpdateMouseMovingWindow()
|
void ImGui::UpdateMouseMovingWindowNewFrame()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
if (g.MovingWindow != NULL)
|
if (g.MovingWindow != NULL)
|
||||||
|
@ -3011,6 +3015,56 @@ void ImGui::UpdateMouseMovingWindow()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Initiate moving window, handle left-click and right-click focus
|
||||||
|
void ImGui::UpdateMouseMovingWindowEndFrame()
|
||||||
|
{
|
||||||
|
// Initiate moving window
|
||||||
|
ImGuiContext& g = *GImGui;
|
||||||
|
if (g.ActiveId != 0 || g.HoveredId != 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Unless we just made a window/popup appear
|
||||||
|
if (g.NavWindow && g.NavWindow->Appearing)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Click to focus window and start moving (after we're done with all our widgets)
|
||||||
|
if (g.IO.MouseClicked[0])
|
||||||
|
{
|
||||||
|
if (g.HoveredRootWindow != NULL)
|
||||||
|
{
|
||||||
|
StartMouseMovingWindow(g.HoveredWindow);
|
||||||
|
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar))
|
||||||
|
if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
||||||
|
g.MovingWindow = NULL;
|
||||||
|
}
|
||||||
|
else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL)
|
||||||
|
{
|
||||||
|
FocusWindow(NULL); // Clicking on void disable focus
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// With right mouse button we close popups without changing focus
|
||||||
|
// (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
||||||
|
if (g.IO.MouseClicked[1])
|
||||||
|
{
|
||||||
|
// Find the top-most window between HoveredWindow and the front most Modal Window.
|
||||||
|
// This is where we can trim the popup stack.
|
||||||
|
ImGuiWindow* modal = GetFrontMostPopupModal();
|
||||||
|
bool hovered_window_above_modal = false;
|
||||||
|
if (modal == NULL)
|
||||||
|
hovered_window_above_modal = true;
|
||||||
|
for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
||||||
|
{
|
||||||
|
ImGuiWindow* window = g.Windows[i];
|
||||||
|
if (window == modal)
|
||||||
|
break;
|
||||||
|
if (window == g.HoveredWindow)
|
||||||
|
hovered_window_above_modal = true;
|
||||||
|
}
|
||||||
|
ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static bool IsWindowActiveAndVisible(ImGuiWindow* window)
|
static bool IsWindowActiveAndVisible(ImGuiWindow* window)
|
||||||
{
|
{
|
||||||
return (window->Active) && (!window->Hidden);
|
return (window->Active) && (!window->Hidden);
|
||||||
|
@ -3302,7 +3356,7 @@ void ImGui::NewFrame()
|
||||||
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
g.IO.Framerate = (g.FramerateSecPerFrameAccum > 0.0f) ? (1.0f / (g.FramerateSecPerFrameAccum / (float)IM_ARRAYSIZE(g.FramerateSecPerFrame))) : FLT_MAX;
|
||||||
|
|
||||||
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
// Handle user moving window with mouse (at the beginning of the frame to avoid input lag or sheering)
|
||||||
UpdateMouseMovingWindow();
|
UpdateMouseMovingWindowNewFrame();
|
||||||
UpdateHoveredWindowAndCaptureFlags();
|
UpdateHoveredWindowAndCaptureFlags();
|
||||||
|
|
||||||
// Background darkening/whitening
|
// Background darkening/whitening
|
||||||
|
@ -3353,6 +3407,7 @@ void ImGui::NewFrame()
|
||||||
// This fallback is particularly important as it avoid ImGui:: calls from crashing.
|
// This fallback is particularly important as it avoid ImGui:: calls from crashing.
|
||||||
SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver);
|
SetNextWindowSize(ImVec2(400,400), ImGuiCond_FirstUseEver);
|
||||||
Begin("Debug##Default");
|
Begin("Debug##Default");
|
||||||
|
g.FrameScopePushedImplicitWindow = true;
|
||||||
|
|
||||||
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
#ifdef IMGUI_ENABLE_TEST_ENGINE
|
||||||
ImGuiTestEngineHook_PostNewFrame();
|
ImGuiTestEngineHook_PostNewFrame();
|
||||||
|
@ -3584,9 +3639,6 @@ void ImGui::EndFrame()
|
||||||
return;
|
return;
|
||||||
IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()?");
|
IM_ASSERT(g.FrameScopeActive && "Forgot to call ImGui::NewFrame()?");
|
||||||
|
|
||||||
g.FrameScopeActive = false;
|
|
||||||
g.FrameCountEnded = g.FrameCount;
|
|
||||||
|
|
||||||
// Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
// Notify OS when our Input Method Editor cursor has moved (e.g. CJK inputs using Microsoft IME)
|
||||||
if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f)
|
if (g.IO.ImeSetInputScreenPosFn && ImLengthSqr(g.PlatformImeLastPos - g.PlatformImePos) > 0.0001f)
|
||||||
{
|
{
|
||||||
|
@ -3611,11 +3663,12 @@ void ImGui::EndFrame()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hide implicit/fallback "Debug" window if it hasn't been used
|
// Hide implicit/fallback "Debug" window if it hasn't been used
|
||||||
|
g.FrameScopePushedImplicitWindow = false;
|
||||||
if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed)
|
if (g.CurrentWindow && !g.CurrentWindow->WriteAccessed)
|
||||||
g.CurrentWindow->Active = false;
|
g.CurrentWindow->Active = false;
|
||||||
End();
|
End();
|
||||||
|
|
||||||
// Show CTRL+TAB list
|
// Show CTRL+TAB list window
|
||||||
if (g.NavWindowingTarget)
|
if (g.NavWindowingTarget)
|
||||||
NavUpdateWindowingList();
|
NavUpdateWindowingList();
|
||||||
|
|
||||||
|
@ -3636,49 +3689,12 @@ void ImGui::EndFrame()
|
||||||
g.DragDropWithinSourceOrTarget = false;
|
g.DragDropWithinSourceOrTarget = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initiate moving window
|
// End frame
|
||||||
if (g.ActiveId == 0 && g.HoveredId == 0)
|
g.FrameScopeActive = false;
|
||||||
{
|
g.FrameCountEnded = g.FrameCount;
|
||||||
if (!g.NavWindow || !g.NavWindow->Appearing) // Unless we just made a window/popup appear
|
|
||||||
{
|
|
||||||
// Click to focus window and start moving (after we're done with all our widgets)
|
|
||||||
if (g.IO.MouseClicked[0])
|
|
||||||
{
|
|
||||||
if (g.HoveredRootWindow != NULL)
|
|
||||||
{
|
|
||||||
StartMouseMovingWindow(g.HoveredWindow);
|
|
||||||
if (g.IO.ConfigWindowsMoveFromTitleBarOnly && !(g.HoveredRootWindow->Flags & ImGuiWindowFlags_NoTitleBar))
|
|
||||||
if (!g.HoveredRootWindow->TitleBarRect().Contains(g.IO.MouseClickedPos[0]))
|
|
||||||
g.MovingWindow = NULL;
|
|
||||||
}
|
|
||||||
else if (g.NavWindow != NULL && GetFrontMostPopupModal() == NULL)
|
|
||||||
{
|
|
||||||
FocusWindow(NULL); // Clicking on void disable focus
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// With right mouse button we close popups without changing focus
|
// Initiate moving window + handle left-click and right-click focus
|
||||||
// (The left mouse button path calls FocusWindow which will lead NewFrame->ClosePopupsOverWindow to trigger)
|
UpdateMouseMovingWindowEndFrame();
|
||||||
if (g.IO.MouseClicked[1])
|
|
||||||
{
|
|
||||||
// Find the top-most window between HoveredWindow and the front most Modal Window.
|
|
||||||
// This is where we can trim the popup stack.
|
|
||||||
ImGuiWindow* modal = GetFrontMostPopupModal();
|
|
||||||
bool hovered_window_above_modal = false;
|
|
||||||
if (modal == NULL)
|
|
||||||
hovered_window_above_modal = true;
|
|
||||||
for (int i = g.Windows.Size - 1; i >= 0 && hovered_window_above_modal == false; i--)
|
|
||||||
{
|
|
||||||
ImGuiWindow* window = g.Windows[i];
|
|
||||||
if (window == modal)
|
|
||||||
break;
|
|
||||||
if (window == g.HoveredWindow)
|
|
||||||
hovered_window_above_modal = true;
|
|
||||||
}
|
|
||||||
ClosePopupsOverWindow(hovered_window_above_modal ? g.HoveredWindow : modal);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Sort the window list so that all child windows are after their parent
|
// Sort the window list so that all child windows are after their parent
|
||||||
// We cannot do that on FocusWindow() because childs may not exist yet
|
// We cannot do that on FocusWindow() because childs may not exist yet
|
||||||
|
@ -4902,6 +4918,7 @@ bool ImGui::Begin(const char* name, bool* p_open, ImGuiWindowFlags flags)
|
||||||
// Position child window
|
// Position child window
|
||||||
if (flags & ImGuiWindowFlags_ChildWindow)
|
if (flags & ImGuiWindowFlags_ChildWindow)
|
||||||
{
|
{
|
||||||
|
IM_ASSERT(parent_window->Active);
|
||||||
window->BeginOrderWithinParent = (short)parent_window->DC.ChildWindows.Size;
|
window->BeginOrderWithinParent = (short)parent_window->DC.ChildWindows.Size;
|
||||||
parent_window->DC.ChildWindows.push_back(window);
|
parent_window->DC.ChildWindows.push_back(window);
|
||||||
if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip)
|
if (!(flags & ImGuiWindowFlags_Popup) && !window_pos_set_by_api && !window_is_child_tooltip)
|
||||||
|
@ -5287,11 +5304,12 @@ void ImGui::End()
|
||||||
{
|
{
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
|
|
||||||
if (g.CurrentWindowStack.Size <= 1 && g.FrameScopeActive)
|
if (g.CurrentWindowStack.Size <= 1 && g.FrameScopePushedImplicitWindow)
|
||||||
{
|
{
|
||||||
IM_ASSERT(g.CurrentWindowStack.Size > 1 && "Calling End() too many times!");
|
IM_ASSERT(g.CurrentWindowStack.Size > 1 && "Calling End() too many times!");
|
||||||
return; // FIXME-ERRORHANDLING
|
return; // FIXME-ERRORHANDLING
|
||||||
}
|
}
|
||||||
|
IM_ASSERT(g.CurrentWindowStack.Size > 0);
|
||||||
|
|
||||||
ImGuiWindow* window = g.CurrentWindow;
|
ImGuiWindow* window = g.CurrentWindow;
|
||||||
|
|
||||||
|
@ -5368,7 +5386,7 @@ void ImGui::FocusWindow(ImGuiWindow* window)
|
||||||
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
|
g.NavId = window ? window->NavLastIds[0] : 0; // Restore NavId
|
||||||
g.NavIdIsAlive = false;
|
g.NavIdIsAlive = false;
|
||||||
g.NavLayer = ImGuiNavLayer_Main;
|
g.NavLayer = ImGuiNavLayer_Main;
|
||||||
//printf("[%05d] FocusWindow(\"%s\")\n", g.FrameCount, window ? window->Name : NULL);
|
//IMGUI_DEBUG_LOG("FocusWindow(\"%s\")\n", g.FrameCount, window ? window->Name : NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Passing NULL allow to disable keyboard focus
|
// Passing NULL allow to disable keyboard focus
|
||||||
|
@ -6545,7 +6563,7 @@ void ImGui::OpenPopupEx(ImGuiID id)
|
||||||
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
|
popup_ref.OpenPopupPos = NavCalcPreferredRefPos();
|
||||||
popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;
|
popup_ref.OpenMousePos = IsMousePosValid(&g.IO.MousePos) ? g.IO.MousePos : popup_ref.OpenPopupPos;
|
||||||
|
|
||||||
//printf("[%05d] OpenPopupEx(0x%08X)\n", g.FrameCount, id);
|
//IMGUI_DEBUG_LOG("OpenPopupEx(0x%08X)\n", g.FrameCount, id);
|
||||||
if (g.OpenPopupStack.Size < current_stack_size + 1)
|
if (g.OpenPopupStack.Size < current_stack_size + 1)
|
||||||
{
|
{
|
||||||
g.OpenPopupStack.push_back(popup_ref);
|
g.OpenPopupStack.push_back(popup_ref);
|
||||||
|
@ -7335,7 +7353,7 @@ static void ImGui::NavUpdate()
|
||||||
ImGuiContext& g = *GImGui;
|
ImGuiContext& g = *GImGui;
|
||||||
g.IO.WantSetMousePos = false;
|
g.IO.WantSetMousePos = false;
|
||||||
#if 0
|
#if 0
|
||||||
if (g.NavScoringCount > 0) printf("[%05d] NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
|
if (g.NavScoringCount > 0) IMGUI_DEBUG_LOG("NavScoringCount %d for '%s' layer %d (Init:%d, Move:%d)\n", g.FrameCount, g.NavScoringCount, g.NavWindow ? g.NavWindow->Name : "NULL", g.NavLayer, g.NavInitRequest || g.NavInitResultId != 0, g.NavMoveRequest);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Set input source as Gamepad when buttons are pressed before we map Keyboard (some features differs when used with Gamepad vs Keyboard)
|
// Set input source as Gamepad when buttons are pressed before we map Keyboard (some features differs when used with Gamepad vs Keyboard)
|
||||||
|
|
|
@ -1283,7 +1283,7 @@ struct ImGuiIO
|
||||||
bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows
|
bool KeySuper; // Keyboard modifier pressed: Cmd/Super/Windows
|
||||||
bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys).
|
bool KeysDown[512]; // Keyboard keys that are pressed (ideally left in the "native" order your engine has access to keyboard keys, so you can use your own defines/enums for keys).
|
||||||
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
|
ImWchar InputCharacters[16+1]; // List of characters input (translated by user from keypress+keyboard state). Fill using AddInputCharacter() helper.
|
||||||
float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs (keyboard keys will be auto-mapped and be written here by ImGui::NewFrame, all values will be cleared back to zero in ImGui::EndFrame)
|
float NavInputs[ImGuiNavInput_COUNT]; // Gamepad inputs. Cleared back to zero by EndFrame(). Keyboard keys will be auto-mapped and be written here by NewFrame().
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[]
|
IMGUI_API void AddInputCharacter(ImWchar c); // Add new character into InputCharacters[]
|
||||||
|
|
|
@ -101,6 +101,7 @@ extern IMGUI_API ImGuiContext* GImGui; // Current implicit ImGui context pointe
|
||||||
#else
|
#else
|
||||||
#define IM_NEWLINE "\n"
|
#define IM_NEWLINE "\n"
|
||||||
#endif
|
#endif
|
||||||
|
#define IMGUI_DEBUG_LOG(_FMT,...) printf("[%05d] " _FMT, GImGui->FrameCount, __VA_ARGS__)
|
||||||
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
|
#define IM_STATIC_ASSERT(_COND) typedef char static_assertion_##__line__[(_COND)?1:-1]
|
||||||
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
#define IM_F32_TO_INT8_UNBOUND(_VAL) ((int)((_VAL) * 255.0f + ((_VAL)>=0 ? 0.5f : -0.5f))) // Unsaturated, for display purpose
|
||||||
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
#define IM_F32_TO_INT8_SAT(_VAL) ((int)(ImSaturate(_VAL) * 255.0f + 0.5f)) // Saturated, always output 0..255
|
||||||
|
@ -694,7 +695,8 @@ struct ImGuiTabBarSortItem
|
||||||
struct ImGuiContext
|
struct ImGuiContext
|
||||||
{
|
{
|
||||||
bool Initialized;
|
bool Initialized;
|
||||||
bool FrameScopeActive; // Set by NewFrame(), cleared by EndFrame()/Render()
|
bool FrameScopeActive; // Set by NewFrame(), cleared by EndFrame()
|
||||||
|
bool FrameScopePushedImplicitWindow; // Set by NewFrame(), cleared by EndFrame()
|
||||||
bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
|
bool FontAtlasOwnedByContext; // Io.Fonts-> is owned by the ImGuiContext and will be destructed along with it.
|
||||||
ImGuiIO IO;
|
ImGuiIO IO;
|
||||||
ImGuiStyle Style;
|
ImGuiStyle Style;
|
||||||
|
@ -859,7 +861,7 @@ struct ImGuiContext
|
||||||
ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL)
|
ImGuiContext(ImFontAtlas* shared_font_atlas) : OverlayDrawList(NULL)
|
||||||
{
|
{
|
||||||
Initialized = false;
|
Initialized = false;
|
||||||
FrameScopeActive = false;
|
FrameScopeActive = FrameScopePushedImplicitWindow = false;
|
||||||
Font = NULL;
|
Font = NULL;
|
||||||
FontSize = FontBaseSize = 0.0f;
|
FontSize = FontBaseSize = 0.0f;
|
||||||
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
FontAtlasOwnedByContext = shared_font_atlas ? false : true;
|
||||||
|
@ -1260,7 +1262,8 @@ namespace ImGui
|
||||||
// NewFrame
|
// NewFrame
|
||||||
IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
|
IMGUI_API void UpdateHoveredWindowAndCaptureFlags();
|
||||||
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
|
IMGUI_API void StartMouseMovingWindow(ImGuiWindow* window);
|
||||||
IMGUI_API void UpdateMouseMovingWindow();
|
IMGUI_API void UpdateMouseMovingWindowNewFrame();
|
||||||
|
IMGUI_API void UpdateMouseMovingWindowEndFrame();
|
||||||
|
|
||||||
// Settings
|
// Settings
|
||||||
IMGUI_API void MarkIniSettingsDirty();
|
IMGUI_API void MarkIniSettingsDirty();
|
||||||
|
|
|
@ -488,7 +488,7 @@ bool ImGui::ButtonBehavior(const ImRect& bb, ImGuiID id, bool* out_hovered, bool
|
||||||
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
|
// Set active id so it can be queried by user via IsItemActive(), equivalent of holding the mouse button.
|
||||||
g.NavActivateId = id; // This is so SetActiveId assign a Nav source
|
g.NavActivateId = id; // This is so SetActiveId assign a Nav source
|
||||||
SetActiveID(id, window);
|
SetActiveID(id, window);
|
||||||
if (!(flags & ImGuiButtonFlags_NoNavFocus))
|
if ((nav_activated_by_code || nav_activated_by_inputs) && !(flags & ImGuiButtonFlags_NoNavFocus))
|
||||||
SetFocusID(id, window);
|
SetFocusID(id, window);
|
||||||
g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right) | (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
|
g.ActiveIdAllowNavDirFlags = (1 << ImGuiDir_Left) | (1 << ImGuiDir_Right) | (1 << ImGuiDir_Up) | (1 << ImGuiDir_Down);
|
||||||
}
|
}
|
||||||
|
@ -5862,7 +5862,7 @@ bool ImGui::BeginTabBarEx(ImGuiTabBar* tab_bar, const ImRect& tab_bar_bb, ImG
|
||||||
g.CurrentTabBar.push_back(tab_bar);
|
g.CurrentTabBar.push_back(tab_bar);
|
||||||
if (tab_bar->CurrFrameVisible == g.FrameCount)
|
if (tab_bar->CurrFrameVisible == g.FrameCount)
|
||||||
{
|
{
|
||||||
//printf("[%05d] BeginTabBarEx already called this frame\n", g.FrameCount);
|
//IMGUI_DEBUG_LOG("BeginTabBarEx already called this frame\n", g.FrameCount);
|
||||||
IM_ASSERT(0);
|
IM_ASSERT(0);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -323,14 +323,6 @@ https://beardsvibe.com/ - Multiplayer PVP rhythm game.
|
||||||
|
|
||||||
![coal-burnout](https://beardsvibe.com/scr/0l.png)
|
![coal-burnout](https://beardsvibe.com/scr/0l.png)
|
||||||
|
|
||||||
## Project Aero
|
|
||||||
|
|
||||||
https://www.adobe.com/products/projectaero.html - Project Aero, a powerful new
|
|
||||||
augmented reality (AR) authoring tool that makes it easier for designers to
|
|
||||||
create immersive content.
|
|
||||||
|
|
||||||
![project-aero](https://www.adobe.com/content/dam/acom/en/products/aero/pod2.jpg/_jcr_content/renditions/cq5dam.mobile_640.640.462.jpg)
|
|
||||||
|
|
||||||
## My Talking Tom 2
|
## My Talking Tom 2
|
||||||
|
|
||||||
https://outfit7.com/apps/my-talking-tom-2/ - Many mini games for mobile devices.
|
https://outfit7.com/apps/my-talking-tom-2/ - Many mini games for mobile devices.
|
||||||
|
|
|
@ -1123,13 +1123,12 @@ public:
|
||||||
mtxReflected(reflectMtx, { 0.0f, 0.01f, 0.0f }, { 0.0f, 1.0f, 0.0f });
|
mtxReflected(reflectMtx, { 0.0f, 0.01f, 0.0f }, { 0.0f, 1.0f, 0.0f });
|
||||||
|
|
||||||
// Reflect lights.
|
// Reflect lights.
|
||||||
float reflectedLights[MAX_NUM_LIGHTS][4];
|
|
||||||
for (uint8_t ii = 0; ii < numLights; ++ii)
|
for (uint8_t ii = 0; ii < numLights; ++ii)
|
||||||
{
|
{
|
||||||
bx::vec3MulMtx(reflectedLights[ii], lightPosRadius[ii], reflectMtx);
|
bx::Vec3 reflected = bx::mul(bx::load<bx::Vec3>(lightPosRadius[ii]), reflectMtx);
|
||||||
reflectedLights[ii][3] = lightPosRadius[ii][3];
|
bx::store(&s_uniforms.m_lightPosRadius[ii], reflected);
|
||||||
|
s_uniforms.m_lightPosRadius[ii][3] = lightPosRadius[ii][3];
|
||||||
}
|
}
|
||||||
bx::memCopy(s_uniforms.m_lightPosRadius, reflectedLights, numLights * 4*sizeof(float) );
|
|
||||||
|
|
||||||
// Reflect and submit bunny.
|
// Reflect and submit bunny.
|
||||||
float mtxReflectedBunny[16];
|
float mtxReflectedBunny[16];
|
||||||
|
|
|
@ -1275,7 +1275,8 @@ struct ShadowVolume
|
||||||
bool m_cap;
|
bool m_cap;
|
||||||
};
|
};
|
||||||
|
|
||||||
void shadowVolumeLightTransform(float* __restrict _outLightPos
|
void shadowVolumeLightTransform(
|
||||||
|
float* __restrict _outLightPos
|
||||||
, const float* __restrict _scale
|
, const float* __restrict _scale
|
||||||
, const float* __restrict _rotate
|
, const float* __restrict _rotate
|
||||||
, const float* __restrict _translate
|
, const float* __restrict _translate
|
||||||
|
@ -1315,11 +1316,11 @@ void shadowVolumeLightTransform(float* __restrict _outLightPos
|
||||||
float mtx[16];
|
float mtx[16];
|
||||||
bx::mtxMul(mtx, tmp0, invScale);
|
bx::mtxMul(mtx, tmp0, invScale);
|
||||||
|
|
||||||
float origin[3] = { 0.0f, 0.0f, 0.0f };
|
bx::store(_outLightPos, bx::mul({ 0.0f, 0.0f, 0.0f }, mtx) );
|
||||||
bx::vec3MulMtx(_outLightPos, origin, mtx);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void shadowVolumeCreate(ShadowVolume& _shadowVolume
|
void shadowVolumeCreate(
|
||||||
|
ShadowVolume& _shadowVolume
|
||||||
, Group& _group
|
, Group& _group
|
||||||
, uint16_t _stride
|
, uint16_t _stride
|
||||||
, const float* _mtx
|
, const float* _mtx
|
||||||
|
@ -1708,33 +1709,27 @@ void createNearClipVolume(float* __restrict _outPlanes24f
|
||||||
// -1.0f - behind near plane
|
// -1.0f - behind near plane
|
||||||
const float lightSide = float( (d > delta) - (d < -delta) );
|
const float lightSide = float( (d > delta) - (d < -delta) );
|
||||||
|
|
||||||
float t = bx::tan(bx::toRad(_fovy)*0.5f) * _near;
|
const float t = bx::tan(bx::toRad(_fovy)*0.5f) * _near;
|
||||||
float b = -t;
|
const float b = -t;
|
||||||
float r = t * _aspect;
|
const float r = t * _aspect;
|
||||||
float l = -r;
|
const float l = -r;
|
||||||
|
|
||||||
float cornersV[4][3] =
|
const bx::Vec3 corners[4] =
|
||||||
{
|
{
|
||||||
{ r, t, _near },
|
bx::mul({ r, t, _near }, mtxViewInv),
|
||||||
{ l, t, _near },
|
bx::mul({ l, t, _near }, mtxViewInv),
|
||||||
{ l, b, _near },
|
bx::mul({ l, b, _near }, mtxViewInv),
|
||||||
{ r, b, _near },
|
bx::mul({ r, b, _near }, mtxViewInv),
|
||||||
};
|
};
|
||||||
|
|
||||||
float corners[4][3];
|
|
||||||
bx::vec3MulMtx(corners[0], cornersV[0], mtxViewInv);
|
|
||||||
bx::vec3MulMtx(corners[1], cornersV[1], mtxViewInv);
|
|
||||||
bx::vec3MulMtx(corners[2], cornersV[2], mtxViewInv);
|
|
||||||
bx::vec3MulMtx(corners[3], cornersV[3], mtxViewInv);
|
|
||||||
|
|
||||||
float planeNormals[4][3];
|
float planeNormals[4][3];
|
||||||
for (uint8_t ii = 0; ii < 4; ++ii)
|
for (uint8_t ii = 0; ii < 4; ++ii)
|
||||||
{
|
{
|
||||||
float* outNormal = planeNormals[ii];
|
float* outNormal = planeNormals[ii];
|
||||||
float* outPlane = volumePlanes[ii];
|
float* outPlane = volumePlanes[ii];
|
||||||
|
|
||||||
const bx::Vec3 c0 = bx::load<bx::Vec3>(corners[ii]);
|
const bx::Vec3 c0 = corners[ii];
|
||||||
const bx::Vec3 planeVec = bx::sub(c0, bx::load<bx::Vec3>(corners[(ii-1)&3]) );
|
const bx::Vec3 planeVec = bx::sub(c0, corners[(ii-1)&3]);
|
||||||
const bx::Vec3 light = bx::sub(bx::load<bx::Vec3>(_lightPos), bx::mul(c0, _lightPos[3]) );
|
const bx::Vec3 light = bx::sub(bx::load<bx::Vec3>(_lightPos), bx::mul(c0, _lightPos[3]) );
|
||||||
const bx::Vec3 normal = bx::mul(bx::cross(planeVec, light), lightSide);
|
const bx::Vec3 normal = bx::mul(bx::cross(planeVec, light), lightSide);
|
||||||
|
|
||||||
|
|
|
@ -1076,7 +1076,7 @@ void worldSpaceFrustumCorners(float* _corners24f
|
||||||
const float fh = _far * _projHeight;
|
const float fh = _far * _projHeight;
|
||||||
|
|
||||||
const uint8_t numCorners = 8;
|
const uint8_t numCorners = 8;
|
||||||
const float corners[numCorners][3] =
|
const bx::Vec3 corners[numCorners] =
|
||||||
{
|
{
|
||||||
{ -nw, nh, _near },
|
{ -nw, nh, _near },
|
||||||
{ nw, nh, _near },
|
{ nw, nh, _near },
|
||||||
|
@ -1092,7 +1092,7 @@ void worldSpaceFrustumCorners(float* _corners24f
|
||||||
float (*out)[3] = (float(*)[3])_corners24f;
|
float (*out)[3] = (float(*)[3])_corners24f;
|
||||||
for (uint8_t ii = 0; ii < numCorners; ++ii)
|
for (uint8_t ii = 0; ii < numCorners; ++ii)
|
||||||
{
|
{
|
||||||
bx::vec3MulMtx( (float*)&out[ii], (float*)&corners[ii], _invViewMtx);
|
bx::store(&out[ii], bx::mul(corners[ii], _invViewMtx) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2471,34 +2471,24 @@ public:
|
||||||
// Compute frustum corners for one split in world space.
|
// Compute frustum corners for one split in world space.
|
||||||
worldSpaceFrustumCorners( (float*)frustumCorners[ii], splitSlices[nn], splitSlices[ff], projWidth, projHeight, mtxViewInv);
|
worldSpaceFrustumCorners( (float*)frustumCorners[ii], splitSlices[nn], splitSlices[ff], projWidth, projHeight, mtxViewInv);
|
||||||
|
|
||||||
float min[3] = { 9000.0f, 9000.0f, 9000.0f };
|
bx::Vec3 min = { 9000.0f, 9000.0f, 9000.0f };
|
||||||
float max[3] = { -9000.0f, -9000.0f, -9000.0f };
|
bx::Vec3 max = { -9000.0f, -9000.0f, -9000.0f };
|
||||||
|
|
||||||
for (uint8_t jj = 0; jj < numCorners; ++jj)
|
for (uint8_t jj = 0; jj < numCorners; ++jj)
|
||||||
{
|
{
|
||||||
// Transform to light space.
|
// Transform to light space.
|
||||||
float lightSpaceFrustumCorner[3];
|
const bx::Vec3 xyz = bx::mul(bx::load<bx::Vec3>(frustumCorners[ii][jj]), lightView[0]);
|
||||||
bx::vec3MulMtx(lightSpaceFrustumCorner, frustumCorners[ii][jj], lightView[0]);
|
|
||||||
|
|
||||||
// Update bounding box.
|
// Update bounding box.
|
||||||
min[0] = bx::min(min[0], lightSpaceFrustumCorner[0]);
|
min = bx::min(min, xyz);
|
||||||
max[0] = bx::max(max[0], lightSpaceFrustumCorner[0]);
|
max = bx::max(max, xyz);
|
||||||
min[1] = bx::min(min[1], lightSpaceFrustumCorner[1]);
|
|
||||||
max[1] = bx::max(max[1], lightSpaceFrustumCorner[1]);
|
|
||||||
min[2] = bx::min(min[2], lightSpaceFrustumCorner[2]);
|
|
||||||
max[2] = bx::max(max[2], lightSpaceFrustumCorner[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
float minproj[3];
|
const bx::Vec3 minproj = bx::mulH(min, mtxProj);
|
||||||
float maxproj[3];
|
const bx::Vec3 maxproj = bx::mulH(max, mtxProj);
|
||||||
bx::vec3MulMtxH(minproj, min, mtxProj);
|
|
||||||
bx::vec3MulMtxH(maxproj, max, mtxProj);
|
|
||||||
|
|
||||||
float offsetx, offsety;
|
float scalex = 2.0f / (maxproj.x - minproj.x);
|
||||||
float scalex, scaley;
|
float scaley = 2.0f / (maxproj.y - minproj.y);
|
||||||
|
|
||||||
scalex = 2.0f / (maxproj[0] - minproj[0]);
|
|
||||||
scaley = 2.0f / (maxproj[1] - minproj[1]);
|
|
||||||
|
|
||||||
if (m_settings.m_stabilize)
|
if (m_settings.m_stabilize)
|
||||||
{
|
{
|
||||||
|
@ -2507,8 +2497,8 @@ public:
|
||||||
scaley = quantizer / bx::ceil(quantizer / scaley);
|
scaley = quantizer / bx::ceil(quantizer / scaley);
|
||||||
}
|
}
|
||||||
|
|
||||||
offsetx = 0.5f * (maxproj[0] + minproj[0]) * scalex;
|
float offsetx = 0.5f * (maxproj.x + minproj.x) * scalex;
|
||||||
offsety = 0.5f * (maxproj[1] + minproj[1]) * scaley;
|
float offsety = 0.5f * (maxproj.y + minproj.y) * scaley;
|
||||||
|
|
||||||
if (m_settings.m_stabilize)
|
if (m_settings.m_stabilize)
|
||||||
{
|
{
|
||||||
|
|
|
@ -561,7 +561,7 @@ public:
|
||||||
Aabb aabb;
|
Aabb aabb;
|
||||||
toAabb(aabb, lightPosRadius);
|
toAabb(aabb, lightPosRadius);
|
||||||
|
|
||||||
float box[8][3] =
|
const bx::Vec3 box[8] =
|
||||||
{
|
{
|
||||||
{ aabb.m_min.x, aabb.m_min.y, aabb.m_min.z },
|
{ aabb.m_min.x, aabb.m_min.y, aabb.m_min.z },
|
||||||
{ aabb.m_min.x, aabb.m_min.y, aabb.m_max.z },
|
{ aabb.m_min.x, aabb.m_min.y, aabb.m_max.z },
|
||||||
|
@ -573,31 +573,24 @@ public:
|
||||||
{ aabb.m_max.x, aabb.m_max.y, aabb.m_max.z },
|
{ aabb.m_max.x, aabb.m_max.y, aabb.m_max.z },
|
||||||
};
|
};
|
||||||
|
|
||||||
float xyz[3];
|
bx::Vec3 xyz = bx::mulH(box[0], vp);
|
||||||
bx::vec3MulMtxH(xyz, box[0], vp);
|
bx::Vec3 min = xyz;
|
||||||
float minx = xyz[0];
|
bx::Vec3 max = xyz;
|
||||||
float miny = xyz[1];
|
|
||||||
float maxx = xyz[0];
|
|
||||||
float maxy = xyz[1];
|
|
||||||
float maxz = xyz[2];
|
|
||||||
|
|
||||||
for (uint32_t ii = 1; ii < 8; ++ii)
|
for (uint32_t ii = 1; ii < 8; ++ii)
|
||||||
{
|
{
|
||||||
bx::vec3MulMtxH(xyz, box[ii], vp);
|
xyz = bx::mulH(box[ii], vp);
|
||||||
minx = bx::min(minx, xyz[0]);
|
min = bx::min(min, xyz);
|
||||||
miny = bx::min(miny, xyz[1]);
|
max = bx::max(max, xyz);
|
||||||
maxx = bx::max(maxx, xyz[0]);
|
|
||||||
maxy = bx::max(maxy, xyz[1]);
|
|
||||||
maxz = bx::max(maxz, xyz[2]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Cull light if it's fully behind camera.
|
// Cull light if it's fully behind camera.
|
||||||
if (maxz >= 0.0f)
|
if (max.z >= 0.0f)
|
||||||
{
|
{
|
||||||
float x0 = bx::clamp( (minx * 0.5f + 0.5f) * m_width, 0.0f, (float)m_width);
|
const float x0 = bx::clamp( (min.x * 0.5f + 0.5f) * m_width, 0.0f, (float)m_width);
|
||||||
float y0 = bx::clamp( (miny * 0.5f + 0.5f) * m_height, 0.0f, (float)m_height);
|
const float y0 = bx::clamp( (min.y * 0.5f + 0.5f) * m_height, 0.0f, (float)m_height);
|
||||||
float x1 = bx::clamp( (maxx * 0.5f + 0.5f) * m_width, 0.0f, (float)m_width);
|
const float x1 = bx::clamp( (max.x * 0.5f + 0.5f) * m_width, 0.0f, (float)m_width);
|
||||||
float y1 = bx::clamp( (maxy * 0.5f + 0.5f) * m_height, 0.0f, (float)m_height);
|
const float y1 = bx::clamp( (max.y * 0.5f + 0.5f) * m_height, 0.0f, (float)m_height);
|
||||||
|
|
||||||
if (m_showScissorRects)
|
if (m_showScissorRects)
|
||||||
{
|
{
|
||||||
|
|
|
@ -697,8 +697,8 @@ public:
|
||||||
const bx::Vec3 normal = { 0.0f, 1.0f, 0.0f };
|
const bx::Vec3 normal = { 0.0f, 1.0f, 0.0f };
|
||||||
const bx::Vec3 pos = { 0.0f, -2.0f, 0.0f };
|
const bx::Vec3 pos = { 0.0f, -2.0f, 0.0f };
|
||||||
|
|
||||||
Plane plane;
|
bx::Plane plane;
|
||||||
bx::calcPlane(&plane.m_normal.x, normal, pos);
|
bx::calcPlane(plane, normal, pos);
|
||||||
|
|
||||||
dde.setColor(false
|
dde.setColor(false
|
||||||
|| intersect(&dde, ray, plane)
|
|| intersect(&dde, ray, plane)
|
||||||
|
@ -818,8 +818,7 @@ public:
|
||||||
1.0f
|
1.0f
|
||||||
};
|
};
|
||||||
|
|
||||||
float up[3] = { 0.0f, 4.0f, 0.0f };
|
cylinder.m_end = bx::mul({ 0.0f, 4.0f, 0.0f }, mtx);
|
||||||
bx::vec3MulMtx(&cylinder.m_end.x, up, mtx);
|
|
||||||
dde.setColor(intersect(&dde, ray, cylinder) ? selected : 0xffffffff);
|
dde.setColor(intersect(&dde, ray, cylinder) ? selected : 0xffffffff);
|
||||||
dde.draw(cylinder);
|
dde.draw(cylinder);
|
||||||
|
|
||||||
|
|
|
@ -268,17 +268,12 @@ public:
|
||||||
float mouseXNDC = ( m_mouseState.m_mx / (float)m_width ) * 2.0f - 1.0f;
|
float mouseXNDC = ( m_mouseState.m_mx / (float)m_width ) * 2.0f - 1.0f;
|
||||||
float mouseYNDC = ((m_height - m_mouseState.m_my) / (float)m_height) * 2.0f - 1.0f;
|
float mouseYNDC = ((m_height - m_mouseState.m_my) / (float)m_height) * 2.0f - 1.0f;
|
||||||
|
|
||||||
float pickEye[3];
|
const bx::Vec3 pickEye = bx::mulH({ mouseXNDC, mouseYNDC, 0.0f }, invViewProj);
|
||||||
float mousePosNDC[3] = { mouseXNDC, mouseYNDC, 0.0f };
|
const bx::Vec3 pickAt = bx::mulH({ mouseXNDC, mouseYNDC, 1.0f }, invViewProj);
|
||||||
bx::vec3MulMtxH(pickEye, mousePosNDC, invViewProj);
|
|
||||||
|
|
||||||
float pickAt[3];
|
|
||||||
float mousePosNDCEnd[3] = { mouseXNDC, mouseYNDC, 1.0f };
|
|
||||||
bx::vec3MulMtxH(pickAt, mousePosNDCEnd, invViewProj);
|
|
||||||
|
|
||||||
// Look at our unprojected point
|
// Look at our unprojected point
|
||||||
float pickView[16];
|
float pickView[16];
|
||||||
bx::mtxLookAt(pickView, bx::load<bx::Vec3>(pickEye), bx::load<bx::Vec3>(pickAt) );
|
bx::mtxLookAt(pickView, pickEye, pickAt);
|
||||||
|
|
||||||
// Tight FOV is best for picking
|
// Tight FOV is best for picking
|
||||||
float pickProj[16];
|
float pickProj[16];
|
||||||
|
|
|
@ -220,7 +220,7 @@ public:
|
||||||
const uint32_t abgr = m_mwc.gen();
|
const uint32_t abgr = m_mwc.gen();
|
||||||
for (uint32_t ii = 0; ii < BX_COUNTOF(s_cubeVertices); ++ii)
|
for (uint32_t ii = 0; ii < BX_COUNTOF(s_cubeVertices); ++ii)
|
||||||
{
|
{
|
||||||
bx::vec3MulMtx(&vertex[ii].m_x, &s_cubeVertices[ii].m_x, mtx);
|
bx::store(&vertex[ii].m_x, bx::mul(bx::load<bx::Vec3>(&s_cubeVertices[ii].m_x), mtx) );
|
||||||
vertex[ii].m_abgr = abgr;
|
vertex[ii].m_abgr = abgr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,25 +137,15 @@ void toAabb(Aabb& _aabb, const float* _mtx, const void* _vertices, uint32_t _num
|
||||||
{
|
{
|
||||||
bx::Vec3 min, max;
|
bx::Vec3 min, max;
|
||||||
uint8_t* vertex = (uint8_t*)_vertices;
|
uint8_t* vertex = (uint8_t*)_vertices;
|
||||||
|
min = max = bx::mul(bx::load<bx::Vec3>(vertex), _mtx);
|
||||||
|
|
||||||
float position[3];
|
|
||||||
bx::vec3MulMtx(position, (float*)vertex, _mtx);
|
|
||||||
min.x = max.x = position[0];
|
|
||||||
min.y = max.y = position[1];
|
|
||||||
min.z = max.z = position[2];
|
|
||||||
vertex += _stride;
|
vertex += _stride;
|
||||||
|
|
||||||
for (uint32_t ii = 1; ii < _numVertices; ++ii)
|
for (uint32_t ii = 1; ii < _numVertices; ++ii)
|
||||||
{
|
{
|
||||||
bx::vec3MulMtx(position, (float*)vertex, _mtx);
|
bx::Vec3 pos = bx::mul(bx::load<bx::Vec3>(vertex), _mtx);
|
||||||
vertex += _stride;
|
vertex += _stride;
|
||||||
|
|
||||||
bx::Vec3 pos =
|
|
||||||
{
|
|
||||||
position[0],
|
|
||||||
position[1],
|
|
||||||
position[2],
|
|
||||||
};
|
|
||||||
min = bx::min(pos, min);
|
min = bx::min(pos, min);
|
||||||
max = bx::max(pos, max);
|
max = bx::max(pos, max);
|
||||||
}
|
}
|
||||||
|
@ -347,12 +337,7 @@ void calcMinBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _num
|
||||||
_sphere.m_radius = bx::sqrt(maxDistSq);
|
_sphere.m_radius = bx::sqrt(maxDistSq);
|
||||||
}
|
}
|
||||||
|
|
||||||
void calcPlaneUv(const Plane& _plane, bx::Vec3& _udir, bx::Vec3& _vdir)
|
void buildFrustumPlanes(bx::Plane* _result, const float* _viewProj)
|
||||||
{
|
|
||||||
bx::calcTangentFrame(_udir, _vdir, _plane.m_normal);
|
|
||||||
}
|
|
||||||
|
|
||||||
void buildFrustumPlanes(Plane* _result, const float* _viewProj)
|
|
||||||
{
|
{
|
||||||
const float xw = _viewProj[ 3];
|
const float xw = _viewProj[ 3];
|
||||||
const float yw = _viewProj[ 7];
|
const float yw = _viewProj[ 7];
|
||||||
|
@ -364,76 +349,76 @@ void buildFrustumPlanes(Plane* _result, const float* _viewProj)
|
||||||
const float zz = _viewProj[10];
|
const float zz = _viewProj[10];
|
||||||
const float wz = _viewProj[14];
|
const float wz = _viewProj[14];
|
||||||
|
|
||||||
Plane& near = _result[0];
|
bx::Plane& near = _result[0];
|
||||||
Plane& far = _result[1];
|
bx::Plane& far = _result[1];
|
||||||
Plane& left = _result[2];
|
bx::Plane& left = _result[2];
|
||||||
Plane& right = _result[3];
|
bx::Plane& right = _result[3];
|
||||||
Plane& top = _result[4];
|
bx::Plane& top = _result[4];
|
||||||
Plane& bottom = _result[5];
|
bx::Plane& bottom = _result[5];
|
||||||
|
|
||||||
near.m_normal.x = xw - xz;
|
near.normal.x = xw - xz;
|
||||||
near.m_normal.y = yw - yz;
|
near.normal.y = yw - yz;
|
||||||
near.m_normal.z = zw - zz;
|
near.normal.z = zw - zz;
|
||||||
near.m_dist = ww - wz;
|
near.dist = ww - wz;
|
||||||
|
|
||||||
far.m_normal.x = xw + xz;
|
far.normal.x = xw + xz;
|
||||||
far.m_normal.y = yw + yz;
|
far.normal.y = yw + yz;
|
||||||
far.m_normal.z = zw + zz;
|
far.normal.z = zw + zz;
|
||||||
far.m_dist = ww + wz;
|
far.dist = ww + wz;
|
||||||
|
|
||||||
const float xx = _viewProj[ 0];
|
const float xx = _viewProj[ 0];
|
||||||
const float yx = _viewProj[ 4];
|
const float yx = _viewProj[ 4];
|
||||||
const float zx = _viewProj[ 8];
|
const float zx = _viewProj[ 8];
|
||||||
const float wx = _viewProj[12];
|
const float wx = _viewProj[12];
|
||||||
|
|
||||||
left.m_normal.x = xw - xx;
|
left.normal.x = xw - xx;
|
||||||
left.m_normal.y = yw - yx;
|
left.normal.y = yw - yx;
|
||||||
left.m_normal.z = zw - zx;
|
left.normal.z = zw - zx;
|
||||||
left.m_dist = ww - wx;
|
left.dist = ww - wx;
|
||||||
|
|
||||||
right.m_normal.x = xw + xx;
|
right.normal.x = xw + xx;
|
||||||
right.m_normal.y = yw + yx;
|
right.normal.y = yw + yx;
|
||||||
right.m_normal.z = zw + zx;
|
right.normal.z = zw + zx;
|
||||||
right.m_dist = ww + wx;
|
right.dist = ww + wx;
|
||||||
|
|
||||||
const float xy = _viewProj[ 1];
|
const float xy = _viewProj[ 1];
|
||||||
const float yy = _viewProj[ 5];
|
const float yy = _viewProj[ 5];
|
||||||
const float zy = _viewProj[ 9];
|
const float zy = _viewProj[ 9];
|
||||||
const float wy = _viewProj[13];
|
const float wy = _viewProj[13];
|
||||||
|
|
||||||
top.m_normal.x = xw + xy;
|
top.normal.x = xw + xy;
|
||||||
top.m_normal.y = yw + yy;
|
top.normal.y = yw + yy;
|
||||||
top.m_normal.z = zw + zy;
|
top.normal.z = zw + zy;
|
||||||
top.m_dist = ww + wy;
|
top.dist = ww + wy;
|
||||||
|
|
||||||
bottom.m_normal.x = xw - xy;
|
bottom.normal.x = xw - xy;
|
||||||
bottom.m_normal.y = yw - yy;
|
bottom.normal.y = yw - yy;
|
||||||
bottom.m_normal.z = zw - zy;
|
bottom.normal.z = zw - zy;
|
||||||
bottom.m_dist = ww - wy;
|
bottom.dist = ww - wy;
|
||||||
|
|
||||||
Plane* plane = _result;
|
bx::Plane* plane = _result;
|
||||||
for (uint32_t ii = 0; ii < 6; ++ii)
|
for (uint32_t ii = 0; ii < 6; ++ii)
|
||||||
{
|
{
|
||||||
const float len = bx::length(plane->m_normal);
|
const float len = bx::length(plane->normal);
|
||||||
plane->m_normal = bx::normalize(plane->m_normal);
|
plane->normal = bx::normalize(plane->normal);
|
||||||
float invLen = 1.0f / len;
|
float invLen = 1.0f / len;
|
||||||
plane->m_dist *= invLen;
|
plane->dist *= invLen;
|
||||||
++plane;
|
++plane;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bx::Vec3 intersectPlanes(const Plane& _pa, const Plane& _pb, const Plane& _pc)
|
bx::Vec3 intersectPlanes(const bx::Plane& _pa, const bx::Plane& _pb, const bx::Plane& _pc)
|
||||||
{
|
{
|
||||||
const bx::Vec3 axb = bx::cross(_pa.m_normal, _pb.m_normal);
|
const bx::Vec3 axb = bx::cross(_pa.normal, _pb.normal);
|
||||||
const bx::Vec3 bxc = bx::cross(_pb.m_normal, _pc.m_normal);
|
const bx::Vec3 bxc = bx::cross(_pb.normal, _pc.normal);
|
||||||
const bx::Vec3 cxa = bx::cross(_pc.m_normal, _pa.m_normal);
|
const bx::Vec3 cxa = bx::cross(_pc.normal, _pa.normal);
|
||||||
const bx::Vec3 tmp0 = bx::mul(bxc, _pa.m_dist);
|
const bx::Vec3 tmp0 = bx::mul(bxc, _pa.dist);
|
||||||
const bx::Vec3 tmp1 = bx::mul(cxa, _pb.m_dist);
|
const bx::Vec3 tmp1 = bx::mul(cxa, _pb.dist);
|
||||||
const bx::Vec3 tmp2 = bx::mul(axb, _pc.m_dist);
|
const bx::Vec3 tmp2 = bx::mul(axb, _pc.dist);
|
||||||
const bx::Vec3 tmp3 = bx::add(tmp0, tmp1);
|
const bx::Vec3 tmp3 = bx::add(tmp0, tmp1);
|
||||||
const bx::Vec3 tmp4 = bx::add(tmp3, tmp2);
|
const bx::Vec3 tmp4 = bx::add(tmp3, tmp2);
|
||||||
|
|
||||||
const float denom = bx::dot(_pa.m_normal, bxc);
|
const float denom = bx::dot(_pa.normal, bxc);
|
||||||
const bx::Vec3 result = bx::mul(tmp4, -1.0f/denom);
|
const bx::Vec3 result = bx::mul(tmp4, -1.0f/denom);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
@ -534,9 +519,9 @@ bool intersect(const Ray& _ray, const Obb& _obb, Hit* _hit)
|
||||||
|
|
||||||
bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit)
|
bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit)
|
||||||
{
|
{
|
||||||
Plane plane;
|
bx::Plane plane;
|
||||||
plane.m_normal = _disk.m_normal;
|
plane.normal = _disk.m_normal;
|
||||||
plane.m_dist = -bx::dot(_disk.m_center, _disk.m_normal);
|
plane.dist = -bx::dot(_disk.m_center, _disk.m_normal);
|
||||||
|
|
||||||
Hit tmpHit;
|
Hit tmpHit;
|
||||||
_hit = NULL != _hit ? _hit : &tmpHit;
|
_hit = NULL != _hit ? _hit : &tmpHit;
|
||||||
|
@ -631,21 +616,21 @@ static bool intersect(const Ray& _ray, const Cylinder& _cylinder, bool _capsule,
|
||||||
return intersect(_ray, sphere, _hit);
|
return intersect(_ray, sphere, _hit);
|
||||||
}
|
}
|
||||||
|
|
||||||
Plane plane;
|
bx::Plane plane;
|
||||||
bx::Vec3 pos;
|
bx::Vec3 pos;
|
||||||
|
|
||||||
if (0.0f >= height)
|
if (0.0f >= height)
|
||||||
{
|
{
|
||||||
plane.m_normal = bx::neg(axis);
|
plane.normal = bx::neg(axis);
|
||||||
pos = _cylinder.m_pos;
|
pos = _cylinder.m_pos;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
plane.m_normal = axis;
|
plane.normal = axis;
|
||||||
pos = _cylinder.m_end;
|
pos = _cylinder.m_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
plane.m_dist = -bx::dot(pos, plane.m_normal);
|
plane.dist = -bx::dot(pos, plane.normal);
|
||||||
|
|
||||||
Hit tmpHit;
|
Hit tmpHit;
|
||||||
_hit = NULL != _hit ? _hit : &tmpHit;
|
_hit = NULL != _hit ? _hit : &tmpHit;
|
||||||
|
@ -751,15 +736,15 @@ bool intersect(const Ray& _ray, const Cone& _cone, Hit* _hit)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool intersect(const Ray& _ray, const Plane& _plane, Hit* _hit)
|
bool intersect(const Ray& _ray, const bx::Plane& _plane, Hit* _hit)
|
||||||
{
|
{
|
||||||
float equation = bx::dot(_ray.m_pos, _plane.m_normal) + _plane.m_dist;
|
float equation = bx::dot(_ray.m_pos, _plane.normal) + _plane.dist;
|
||||||
if (0.0f > equation)
|
if (0.0f > equation)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float ndotd = bx::dot(_ray.m_dir, _plane.m_normal);
|
float ndotd = bx::dot(_ray.m_dir, _plane.normal);
|
||||||
if (0.0f < ndotd)
|
if (0.0f < ndotd)
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
|
@ -767,7 +752,7 @@ bool intersect(const Ray& _ray, const Plane& _plane, Hit* _hit)
|
||||||
|
|
||||||
if (NULL != _hit)
|
if (NULL != _hit)
|
||||||
{
|
{
|
||||||
_hit->m_normal = _plane.m_normal;
|
_hit->m_normal = _plane.normal;
|
||||||
|
|
||||||
float tt = -equation/ndotd;
|
float tt = -equation/ndotd;
|
||||||
_hit->m_dist = tt;
|
_hit->m_dist = tt;
|
||||||
|
|
|
@ -47,12 +47,6 @@ struct Obb
|
||||||
float m_mtx[16];
|
float m_mtx[16];
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Plane
|
|
||||||
{
|
|
||||||
bx::Vec3 m_normal;
|
|
||||||
float m_dist;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Ray
|
struct Ray
|
||||||
{
|
{
|
||||||
bx::Vec3 m_pos;
|
bx::Vec3 m_pos;
|
||||||
|
@ -123,10 +117,10 @@ void calcMaxBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _num
|
||||||
void calcMinBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _numVertices, uint32_t _stride, float _step = 0.01f);
|
void calcMinBoundingSphere(Sphere& _sphere, const void* _vertices, uint32_t _numVertices, uint32_t _stride, float _step = 0.01f);
|
||||||
|
|
||||||
/// Returns 6 (near, far, left, right, top, bottom) planes representing frustum planes.
|
/// Returns 6 (near, far, left, right, top, bottom) planes representing frustum planes.
|
||||||
void buildFrustumPlanes(Plane* _planes, const float* _viewProj);
|
void buildFrustumPlanes(bx::Plane* _planes, const float* _viewProj);
|
||||||
|
|
||||||
/// Returns point from 3 intersecting planes.
|
/// Returns point from 3 intersecting planes.
|
||||||
bx::Vec3 intersectPlanes(const Plane& _pa, const Plane& _pb, const Plane& _pc);
|
bx::Vec3 intersectPlanes(const bx::Plane& _pa, const bx::Plane& _pb, const bx::Plane& _pc);
|
||||||
|
|
||||||
/// Make screen space ray from x, y coordinate and inverse view-projection matrix.
|
/// Make screen space ray from x, y coordinate and inverse view-projection matrix.
|
||||||
Ray makeRay(float _x, float _y, const float* _invVp);
|
Ray makeRay(float _x, float _y, const float* _invVp);
|
||||||
|
@ -150,7 +144,7 @@ bool intersect(const Ray& _ray, const Cone& _cone, Hit* _hit = NULL);
|
||||||
bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit = NULL);
|
bool intersect(const Ray& _ray, const Disk& _disk, Hit* _hit = NULL);
|
||||||
|
|
||||||
/// Intersect ray / plane.
|
/// Intersect ray / plane.
|
||||||
bool intersect(const Ray& _ray, const Plane& _plane, Hit* _hit = NULL);
|
bool intersect(const Ray& _ray, const bx::Plane& _plane, Hit* _hit = NULL);
|
||||||
|
|
||||||
/// Intersect ray / sphere.
|
/// Intersect ray / sphere.
|
||||||
bool intersect(const Ray& _ray, const Sphere& _sphere, Hit* _hit = NULL);
|
bool intersect(const Ray& _ray, const Sphere& _sphere, Hit* _hit = NULL);
|
||||||
|
|
|
@ -1654,7 +1654,7 @@ struct DebugDrawEncoderImpl
|
||||||
|
|
||||||
void drawFrustum(const float* _viewProj)
|
void drawFrustum(const float* _viewProj)
|
||||||
{
|
{
|
||||||
Plane planes[6];
|
bx::Plane planes[6];
|
||||||
buildFrustumPlanes(planes, _viewProj);
|
buildFrustumPlanes(planes, _viewProj);
|
||||||
|
|
||||||
bx::Vec3 points[8];
|
bx::Vec3 points[8];
|
||||||
|
|
|
@ -2054,14 +2054,11 @@ int _main_(int _argc, char** _argv)
|
||||||
|
|
||||||
if (view.m_fit)
|
if (view.m_fit)
|
||||||
{
|
{
|
||||||
float wh[3] = { float(view.m_textureInfo.width), float(view.m_textureInfo.height), 0.0f };
|
const bx::Vec3 wh = { float(view.m_textureInfo.width), float(view.m_textureInfo.height), 0.0f };
|
||||||
float result[3];
|
const bx::Vec3 result = bx::round(bx::abs(bx::mul(wh, orientation) ) );
|
||||||
bx::vec3MulMtx(result, wh, orientation);
|
|
||||||
result[0] = bx::round(bx::abs(result[0]) );
|
|
||||||
result[1] = bx::round(bx::abs(result[1]) );
|
|
||||||
|
|
||||||
scale.set(bx::min(float(view.m_width) / result[0]
|
scale.set(bx::min(float(view.m_width) / result.x
|
||||||
, float(view.m_height) / result[1])
|
, float(view.m_height) / result.y)
|
||||||
, 0.1f*view.m_transitionTime
|
, 0.1f*view.m_transitionTime
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue