Merge pull request #41 from Ybalrid/pr_upgrade_imgui_imguizmo_raytrace

Upgraded dear imgui and ImGuizmo to the latest version
This commit is contained in:
Syoyo Fujita 2018-03-03 00:43:18 +09:00 committed by GitHub
commit c14616d21c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 9351 additions and 4284 deletions

View File

@ -21,7 +21,9 @@
// SOFTWARE. // SOFTWARE.
#include "imgui.h" #include "imgui.h"
#ifndef IMGUI_DEFINE_MATH_OPERATORS
#define IMGUI_DEFINE_MATH_OPERATORS #define IMGUI_DEFINE_MATH_OPERATORS
#endif
#include "imgui_internal.h" #include "imgui_internal.h"
#include "ImGuizmo.h" #include "ImGuizmo.h"
@ -65,6 +67,8 @@ namespace ImGuizmo
//template <typename T> T LERP(T x, T y, float z) { return (x + (y - x)*z); } //template <typename T> T LERP(T x, T y, float z) { return (x + (y - x)*z); }
template <typename T> T Clamp(T x, T y, T z) { return ((x<y) ? y : ((x>z) ? z : x)); } template <typename T> T Clamp(T x, T y, T z) { return ((x<y) ? y : ((x>z) ? z : x)); }
template <typename T> T max(T x, T y) { return (x > y) ? x : y; } template <typename T> T max(T x, T y) { return (x > y) ? x : y; }
template <typename T> T min(T x, T y) { return (x < y) ? x : y; }
template <typename T> bool IsWithin(T x, T y, T z) { return (x>=y) && (x<=z); }
struct matrix_t; struct matrix_t;
struct vec_t struct vec_t
@ -147,7 +151,6 @@ namespace ImGuizmo
vec_t vec_t::operator + (const vec_t& v) const { return makeVect(x + v.x, y + v.y, z + v.z, w + v.w); } vec_t vec_t::operator + (const vec_t& v) const { return makeVect(x + v.x, y + v.y, z + v.z, w + v.w); }
vec_t vec_t::operator * (const vec_t& v) const { return makeVect(x * v.x, y * v.y, z * v.z, w * v.w); } vec_t vec_t::operator * (const vec_t& v) const { return makeVect(x * v.x, y * v.y, z * v.z, w * v.w); }
vec_t vec_t::Abs() const { return makeVect(fabsf(x), fabsf(y), fabsf(z)); } vec_t vec_t::Abs() const { return makeVect(fabsf(x), fabsf(y), fabsf(z)); }
ImVec2 operator+ (const ImVec2& a, const ImVec2& b) { return ImVec2(a.x + b.x, a.y + b.y); }
vec_t Normalized(const vec_t& v) { vec_t res; res = v; res.Normalize(); return res; } vec_t Normalized(const vec_t& v) { vec_t res; res = v; res.Normalize(); return res; }
vec_t Cross(const vec_t& v1, const vec_t& v2) vec_t Cross(const vec_t& v1, const vec_t& v2)
@ -520,6 +523,7 @@ namespace ImGuizmo
vec_t mRayOrigin; vec_t mRayOrigin;
vec_t mRayVector; vec_t mRayVector;
float mRadiusSquareCenter;
ImVec2 mScreenSquareCenter; ImVec2 mScreenSquareCenter;
ImVec2 mScreenSquareMin; ImVec2 mScreenSquareMin;
ImVec2 mScreenSquareMax; ImVec2 mScreenSquareMax;
@ -568,6 +572,8 @@ namespace ImGuizmo
float mY = 0.f; float mY = 0.f;
float mWidth = 0.f; float mWidth = 0.f;
float mHeight = 0.f; float mHeight = 0.f;
float mXMax = 0.f;
float mYMax = 0.f;
}; };
static Context gContext; static Context gContext;
@ -577,7 +583,11 @@ namespace ImGuizmo
static const vec_t directionUnary[3] = { makeVect(1.f, 0.f, 0.f), makeVect(0.f, 1.f, 0.f), makeVect(0.f, 0.f, 1.f) }; static const vec_t directionUnary[3] = { makeVect(1.f, 0.f, 0.f), makeVect(0.f, 1.f, 0.f), makeVect(0.f, 0.f, 1.f) };
static const ImU32 directionColor[3] = { 0xFF0000AA, 0xFF00AA00, 0xFFAA0000 }; static const ImU32 directionColor[3] = { 0xFF0000AA, 0xFF00AA00, 0xFFAA0000 };
static const ImU32 selectionColor = 0xFF1080FF;
// Alpha: 100%: FF, 87%: DE, 70%: B3, 54%: 8A, 50%: 80, 38%: 61, 12%: 1F
static const ImU32 planeBorderColor[3] = { 0xFFAA0000, 0xFF0000AA, 0xFF00AA00 };
static const ImU32 planeColor[3] = { 0x610000AA, 0x6100AA00, 0x61AA0000 };
static const ImU32 selectionColor = 0x8A1080FF;
static const ImU32 inactiveColor = 0x99999999; static const ImU32 inactiveColor = 0x99999999;
static const ImU32 translationLineColor = 0xAAAAAAAA; static const ImU32 translationLineColor = 0xAAAAAAAA;
static const char *translationInfoMask[] = { "X : %5.3f", "Y : %5.3f", "Z : %5.3f", "X : %5.3f Y : %5.3f", "Y : %5.3f Z : %5.3f", "X : %5.3f Z : %5.3f", "X : %5.3f Y : %5.3f Z : %5.3f" }; static const char *translationInfoMask[] = { "X : %5.3f", "Y : %5.3f", "Z : %5.3f", "X : %5.3f Y : %5.3f", "Y : %5.3f Z : %5.3f", "X : %5.3f Z : %5.3f", "X : %5.3f Y : %5.3f Z : %5.3f" };
@ -598,8 +608,6 @@ namespace ImGuizmo
static ImVec2 worldToPos(const vec_t& worldPos, const matrix_t& mat) static ImVec2 worldToPos(const vec_t& worldPos, const matrix_t& mat)
{ {
//ImGuiIO& io = ImGui::GetIO();
vec_t trans; vec_t trans;
trans.TransformPoint(worldPos, mat); trans.TransformPoint(worldPos, mat);
trans *= 0.5f / trans.w; trans *= 0.5f / trans.w;
@ -641,23 +649,38 @@ namespace ImGuizmo
return -(numer / denom); return -(numer / denom);
} }
static bool IsInContextRect( ImVec2 p )
{
return IsWithin( p.x, gContext.mX, gContext.mXMax ) && IsWithin(p.y, gContext.mY, gContext.mYMax );
}
void SetRect(float x, float y, float width, float height) void SetRect(float x, float y, float width, float height)
{ {
gContext.mX = x; gContext.mX = x;
gContext.mY = y; gContext.mY = y;
gContext.mWidth = width; gContext.mWidth = width;
gContext.mHeight = height; gContext.mHeight = height;
gContext.mXMax = gContext.mX + gContext.mWidth;
gContext.mYMax = gContext.mY + gContext.mXMax;
}
void SetDrawlist()
{
gContext.mDrawList = ImGui::GetWindowDrawList();
} }
void BeginFrame() void BeginFrame()
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImGui::Begin("gizmo", NULL, io.DisplaySize, 0, ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus); const ImU32 flags = ImGuiWindowFlags_NoTitleBar | ImGuiWindowFlags_NoResize | ImGuiWindowFlags_NoScrollbar | ImGuiWindowFlags_NoInputs | ImGuiWindowFlags_NoSavedSettings | ImGuiWindowFlags_NoFocusOnAppearing | ImGuiWindowFlags_NoBringToFrontOnFocus;
ImGui::SetNextWindowSize(io.DisplaySize);
ImGui::PushStyleColor(ImGuiCol_WindowBg, 0);
ImGui::Begin("gizmo", NULL, flags);
gContext.mDrawList = ImGui::GetWindowDrawList(); gContext.mDrawList = ImGui::GetWindowDrawList();
ImGui::End(); ImGui::End();
ImGui::PopStyleColor();
} }
bool IsUsing() bool IsUsing()
@ -738,7 +761,8 @@ namespace ImGuizmo
{ {
int colorPlaneIndex = (i + 2) % 3; int colorPlaneIndex = (i + 2) % 3;
colors[i + 1] = (type == (int)(MOVE_X + i)) ? selectionColor : directionColor[i]; colors[i + 1] = (type == (int)(MOVE_X + i)) ? selectionColor : directionColor[i];
colors[i + 4] = (type == (int)(MOVE_XY + i)) ? selectionColor : directionColor[colorPlaneIndex]; colors[i + 4] = (type == (int)(MOVE_XY + i)) ? selectionColor : planeColor[colorPlaneIndex];
colors[i + 4] = (type == MOVE_SCREEN) ? selectionColor : colors[i + 4];
} }
break; break;
case ROTATE: case ROTATE:
@ -751,8 +775,6 @@ namespace ImGuizmo
for (int i = 0; i < 3; i++) for (int i = 0; i < 3; i++)
colors[i + 1] = (type == (int)(SCALE_X + i)) ? selectionColor : directionColor[i]; colors[i + 1] = (type == (int)(SCALE_X + i)) ? selectionColor : directionColor[i];
break; break;
default:
break;
} }
} }
else else
@ -848,7 +870,6 @@ namespace ImGuizmo
static void DrawRotationGizmo(int type) static void DrawRotationGizmo(int type)
{ {
ImDrawList* drawList = gContext.mDrawList; ImDrawList* drawList = gContext.mDrawList;
//ImGuiIO& io = ImGui::GetIO();
// colors // colors
ImU32 colors[7]; ImU32 colors[7];
@ -857,6 +878,7 @@ namespace ImGuizmo
vec_t cameraToModelNormalized = Normalized(gContext.mModel.v.position - gContext.mCameraEye); vec_t cameraToModelNormalized = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
cameraToModelNormalized.TransformVector(gContext.mModelInverse); cameraToModelNormalized.TransformVector(gContext.mModelInverse);
gContext.mRadiusSquareCenter = screenRotateSize * gContext.mHeight;
for (int axis = 0; axis < 3; axis++) for (int axis = 0; axis < 3; axis++)
{ {
ImVec2 circlePos[halfCircleSegmentCount]; ImVec2 circlePos[halfCircleSegmentCount];
@ -870,9 +892,14 @@ namespace ImGuizmo
vec_t pos = makeVect(axisPos[axis], axisPos[(axis+1)%3], axisPos[(axis+2)%3]) * gContext.mScreenFactor; vec_t pos = makeVect(axisPos[axis], axisPos[(axis+1)%3], axisPos[(axis+2)%3]) * gContext.mScreenFactor;
circlePos[i] = worldToPos(pos, gContext.mMVP); circlePos[i] = worldToPos(pos, gContext.mMVP);
} }
drawList->AddPolyline(circlePos, halfCircleSegmentCount, colors[3 - axis], false, 2, true);
float radiusAxis = sqrtf( (ImLengthSqr(worldToPos(gContext.mModel.v.position, gContext.mViewProjection) - circlePos[0]) ));
if(radiusAxis > gContext.mRadiusSquareCenter)
gContext.mRadiusSquareCenter = radiusAxis;
drawList->AddPolyline(circlePos, halfCircleSegmentCount, colors[3 - axis], false, 2);
} }
drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), screenRotateSize * gContext.mHeight, colors[0], 64); drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), gContext.mRadiusSquareCenter, colors[0], 64, 3.f);
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
@ -889,8 +916,8 @@ namespace ImGuizmo
pos *= gContext.mScreenFactor; pos *= gContext.mScreenFactor;
circlePos[i] = worldToPos(pos + gContext.mModel.v.position, gContext.mViewProjection); circlePos[i] = worldToPos(pos + gContext.mModel.v.position, gContext.mViewProjection);
} }
drawList->AddConvexPolyFilled(circlePos, halfCircleSegmentCount, 0x801080FF, true); drawList->AddConvexPolyFilled(circlePos, halfCircleSegmentCount, 0x801080FF);
drawList->AddPolyline(circlePos, halfCircleSegmentCount, 0xFF1080FF, true, 2, true); drawList->AddPolyline(circlePos, halfCircleSegmentCount, 0xFF1080FF, true, 2);
ImVec2 destinationPosOnScreen = circlePos[1]; ImVec2 destinationPosOnScreen = circlePos[1];
char tmps[512]; char tmps[512];
@ -918,9 +945,6 @@ namespace ImGuizmo
ImU32 colors[7]; ImU32 colors[7];
ComputeColors(colors, type, SCALE); ComputeColors(colors, type, SCALE);
// draw screen cirle
drawList->AddCircleFilled(gContext.mScreenSquareCenter, 12.f, colors[0], 32);
// draw // draw
vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f }; vec_t scaleDisplay = { 1.f, 1.f, 1.f, 1.f };
@ -942,18 +966,21 @@ namespace ImGuizmo
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, 0xFF404040, 6.f); drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, 0xFF404040, 3.f);
drawList->AddCircleFilled(worldDirSSpaceNoScale, 10.f, 0xFF404040); drawList->AddCircleFilled(worldDirSSpaceNoScale, 6.f, 0xFF404040);
} }
drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f); drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 3.f);
drawList->AddCircleFilled(worldDirSSpace, 10.f, colors[i + 1]); drawList->AddCircleFilled(worldDirSSpace, 6.f, colors[i + 1]);
if (gContext.mAxisFactor[i] < 0.f) if (gContext.mAxisFactor[i] < 0.f)
DrawHatchedAxis(dirPlaneX * scaleDisplay[i]); DrawHatchedAxis(dirPlaneX * scaleDisplay[i]);
} }
} }
// draw screen cirle
drawList->AddCircleFilled(gContext.mScreenSquareCenter, 6.f, colors[0], 32);
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
//ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection); //ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
@ -985,14 +1012,14 @@ namespace ImGuizmo
ImU32 colors[7]; ImU32 colors[7];
ComputeColors(colors, type, TRANSLATE); ComputeColors(colors, type, TRANSLATE);
// draw screen quad const ImVec2 origin = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
drawList->AddRectFilled(gContext.mScreenSquareMin, gContext.mScreenSquareMax, colors[0], 2.f);
// draw // draw
for (unsigned int i = 0; i < 3; i++) bool belowAxisLimit = false;
bool belowPlaneLimit = false;
for (unsigned int i = 0; i < 3; ++i)
{ {
vec_t dirPlaneX, dirPlaneY; vec_t dirPlaneX, dirPlaneY;
bool belowAxisLimit, belowPlaneLimit;
ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit); ComputeTripodAxisAndVisibility(i, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit);
// draw axis // draw axis
@ -1001,7 +1028,19 @@ namespace ImGuizmo
ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP); ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP);
ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP); ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f); drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 3.f);
// Arrow head begin
ImVec2 dir(origin - worldDirSSpace);
float d = sqrtf(ImLengthSqr(dir));
dir /= d; // Normalize
dir *= 6.0f;
ImVec2 ortogonalDir(dir.y, -dir.x); // Perpendicular vector
ImVec2 a(worldDirSSpace + dir);
drawList->AddTriangleFilled(worldDirSSpace - dir, a + ortogonalDir, a - ortogonalDir, colors[i + 1]);
// Arrow head end
if (gContext.mAxisFactor[i] < 0.f) if (gContext.mAxisFactor[i] < 0.f)
DrawHatchedAxis(dirPlaneX); DrawHatchedAxis(dirPlaneX);
@ -1011,15 +1050,18 @@ namespace ImGuizmo
if (belowPlaneLimit) if (belowPlaneLimit)
{ {
ImVec2 screenQuadPts[4]; ImVec2 screenQuadPts[4];
for (int j = 0; j < 4; j++) for (int j = 0; j < 4; ++j)
{ {
vec_t cornerWorldPos = (dirPlaneX * quadUV[j * 2] + dirPlaneY * quadUV[j * 2 + 1]) * gContext.mScreenFactor; vec_t cornerWorldPos = (dirPlaneX * quadUV[j * 2] + dirPlaneY * quadUV[j * 2 + 1]) * gContext.mScreenFactor;
screenQuadPts[j] = worldToPos(cornerWorldPos, gContext.mMVP); screenQuadPts[j] = worldToPos(cornerWorldPos, gContext.mMVP);
} }
drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4], true); drawList->AddPolyline(screenQuadPts, 4, planeBorderColor[i], true, 1.0f);
drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4]);
} }
} }
drawList->AddCircleFilled(gContext.mScreenSquareCenter, 6.f, colors[0], 32);
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection); ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
@ -1040,17 +1082,28 @@ namespace ImGuizmo
} }
} }
static bool CanActivate()
{
if (ImGui::IsMouseClicked(0) && !ImGui::IsAnyItemHovered() && !ImGui::IsAnyItemActive())
return true;
return false;
}
static void HandleAndDrawLocalBounds(float *bounds, matrix_t *matrix, float *snapValues) static void HandleAndDrawLocalBounds(float *bounds, matrix_t *matrix, float *snapValues)
{ {
ImGuiIO& io = ImGui::GetIO(); ImGuiIO& io = ImGui::GetIO();
ImDrawList* drawList = gContext.mDrawList; ImDrawList* drawList = gContext.mDrawList;
// compute best projection axis // compute best projection axis
vec_t bestAxisWorldDirection; vec_t axesWorldDirections[3];
int bestAxis = gContext.mBoundsBestAxis; vec_t bestAxisWorldDirection = { 0.0f, 0.0f, 0.0f, 0.0f };
int axes[3];
unsigned int numAxes = 1;
axes[0] = gContext.mBoundsBestAxis;
int bestAxis = axes[0];
if (!gContext.mbUsingBounds) if (!gContext.mbUsingBounds)
{ {
numAxes = 0;
float bestDot = 0.f; float bestDot = 0.f;
for (unsigned int i = 0; i < 3; i++) for (unsigned int i = 0; i < 3; i++)
{ {
@ -1058,15 +1111,52 @@ namespace ImGuizmo
dirPlaneNormalWorld.TransformVector(directionUnary[i], gContext.mModelSource); dirPlaneNormalWorld.TransformVector(directionUnary[i], gContext.mModelSource);
dirPlaneNormalWorld.Normalize(); dirPlaneNormalWorld.Normalize();
float dt = Dot(Normalized(gContext.mCameraEye - gContext.mModelSource.v.position), dirPlaneNormalWorld); float dt = fabsf( Dot(Normalized(gContext.mCameraEye - gContext.mModelSource.v.position), dirPlaneNormalWorld) );
if (fabsf(dt) >= bestDot) if ( dt >= bestDot )
{ {
bestDot = fabsf(dt); bestDot = dt;
bestAxis = i; bestAxis = i;
bestAxisWorldDirection = dirPlaneNormalWorld; bestAxisWorldDirection = dirPlaneNormalWorld;
} }
if( dt >= 0.1f )
{
axes[numAxes] = i;
axesWorldDirections[numAxes] = dirPlaneNormalWorld;
++numAxes;
} }
} }
}
if( numAxes == 0 )
{
axes[0] = bestAxis;
axesWorldDirections[0] = bestAxisWorldDirection;
numAxes = 1;
}
else if( bestAxis != axes[0] )
{
unsigned int bestIndex = 0;
for (unsigned int i = 0; i < numAxes; i++)
{
if( axes[i] == bestAxis )
{
bestIndex = i;
break;
}
}
int tempAxis = axes[0];
axes[0] = axes[bestIndex];
axes[bestIndex] = tempAxis;
vec_t tempDirection = axesWorldDirections[0];
axesWorldDirections[0] = axesWorldDirections[bestIndex];
axesWorldDirections[bestIndex] = tempDirection;
}
for (unsigned int axisIndex = 0; axisIndex < numAxes; ++axisIndex)
{
bestAxis = axes[axisIndex];
bestAxisWorldDirection = axesWorldDirections[axisIndex];
// corners // corners
vec_t aabb[4]; vec_t aabb[4];
@ -1089,8 +1179,13 @@ namespace ImGuizmo
{ {
ImVec2 worldBound1 = worldToPos(aabb[i], boundsMVP); ImVec2 worldBound1 = worldToPos(aabb[i], boundsMVP);
ImVec2 worldBound2 = worldToPos(aabb[(i+1)%4], boundsMVP); ImVec2 worldBound2 = worldToPos(aabb[(i+1)%4], boundsMVP);
if( !IsInContextRect( worldBound1 ) || !IsInContextRect( worldBound2 ) )
{
continue;
}
float boundDistance = sqrtf(ImLengthSqr(worldBound1 - worldBound2)); float boundDistance = sqrtf(ImLengthSqr(worldBound1 - worldBound2));
int stepCount = (int)(boundDistance / 10.f); int stepCount = (int)(boundDistance / 10.f);
stepCount = min( stepCount, 1000 );
float stepLength = 1.f / (float)stepCount; float stepLength = 1.f / (float)stepCount;
for (int j = 0; j < stepCount; j++) for (int j = 0; j < stepCount; j++)
{ {
@ -1115,7 +1210,7 @@ namespace ImGuizmo
drawList->AddCircleFilled(midBound, AnchorSmallRadius, smallAnchorColor); drawList->AddCircleFilled(midBound, AnchorSmallRadius, smallAnchorColor);
int oppositeIndex = (i + 2) % 4; int oppositeIndex = (i + 2) % 4;
// big anchor on corners // big anchor on corners
if (!gContext.mbUsingBounds && gContext.mbEnable && overBigAnchor && io.MouseDown[0]) if (!gContext.mbUsingBounds && gContext.mbEnable && overBigAnchor && CanActivate())
{ {
gContext.mBoundsPivot.TransformPoint(aabb[(i + 2) % 4], gContext.mModelSource); gContext.mBoundsPivot.TransformPoint(aabb[(i + 2) % 4], gContext.mModelSource);
gContext.mBoundsAnchor.TransformPoint(aabb[i], gContext.mModelSource); gContext.mBoundsAnchor.TransformPoint(aabb[i], gContext.mModelSource);
@ -1132,7 +1227,7 @@ namespace ImGuizmo
gContext.mBoundsMatrix = gContext.mModelSource; gContext.mBoundsMatrix = gContext.mModelSource;
} }
// small anchor on middle of segment // small anchor on middle of segment
if (!gContext.mbUsingBounds && gContext.mbEnable && overSmallAnchor && io.MouseDown[0]) if (!gContext.mbUsingBounds && gContext.mbEnable && overSmallAnchor && CanActivate())
{ {
vec_t midPointOpposite = (aabb[(i + 2) % 4] + aabb[(i + 3) % 4]) * 0.5f; vec_t midPointOpposite = (aabb[(i + 2) % 4] + aabb[(i + 3) % 4]) * 0.5f;
gContext.mBoundsPivot.TransformPoint(midPointOpposite, gContext.mModelSource); gContext.mBoundsPivot.TransformPoint(midPointOpposite, gContext.mModelSource);
@ -1167,26 +1262,26 @@ namespace ImGuizmo
// for 1 or 2 axes, compute a ratio that's used for scale and snap it based on resulting length // for 1 or 2 axes, compute a ratio that's used for scale and snap it based on resulting length
for (int i = 0; i < 2; i++) for (int i = 0; i < 2; i++)
{ {
int axisIndex = gContext.mBoundsAxis[i]; int axisIndex1 = gContext.mBoundsAxis[i];
if (axisIndex == -1) if (axisIndex1 == -1)
continue; continue;
float ratioAxis = 1.f; float ratioAxis = 1.f;
vec_t axisDir = gContext.mBoundsMatrix.component[axisIndex].Abs(); vec_t axisDir = gContext.mBoundsMatrix.component[axisIndex1].Abs();
float dtAxis = axisDir.Dot(referenceVector); float dtAxis = axisDir.Dot(referenceVector);
float boundSize = bounds[axisIndex + 3] - bounds[axisIndex]; float boundSize = bounds[axisIndex1 + 3] - bounds[axisIndex1];
if (dtAxis > FLT_EPSILON) if (dtAxis > FLT_EPSILON)
ratioAxis = axisDir.Dot(deltaVector) / dtAxis; ratioAxis = axisDir.Dot(deltaVector) / dtAxis;
if (snapValues) if (snapValues)
{ {
float length = boundSize * ratioAxis; float length = boundSize * ratioAxis;
ComputeSnap(&length, snapValues[axisIndex]); ComputeSnap(&length, snapValues[axisIndex1]);
if (boundSize > FLT_EPSILON) if (boundSize > FLT_EPSILON)
ratioAxis = length / boundSize; ratioAxis = length / boundSize;
} }
scale.component[axisIndex] *= ratioAxis; scale.component[axisIndex1] *= ratioAxis;
} }
// transform matrix // transform matrix
@ -1210,6 +1305,10 @@ namespace ImGuizmo
if (!io.MouseDown[0]) if (!io.MouseDown[0])
gContext.mbUsingBounds = false; gContext.mbUsingBounds = false;
if( gContext.mbUsingBounds )
break;
}
} }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@ -1255,7 +1354,7 @@ namespace ImGuizmo
vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.f, 0.f }; vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.f, 0.f };
float dist = deltaScreen.Length(); float dist = deltaScreen.Length();
if (dist >= (screenRotateSize - 0.002f) * gContext.mHeight && dist < (screenRotateSize + 0.002f) * gContext.mHeight) if (dist >= (gContext.mRadiusSquareCenter - 1.0f) && dist < (gContext.mRadiusSquareCenter + 1.0f))
type = ROTATE_SCREEN; type = ROTATE_SCREEN;
const vec_t planNormals[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir}; const vec_t planNormals[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir};
@ -1327,6 +1426,7 @@ namespace ImGuizmo
// move // move
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
ImGui::CaptureMouseFromApp();
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len; vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
@ -1385,8 +1485,9 @@ namespace ImGuizmo
// find new possible way to move // find new possible way to move
vec_t gizmoHitProportion; vec_t gizmoHitProportion;
type = GetMoveType(&gizmoHitProportion); type = GetMoveType(&gizmoHitProportion);
if (io.MouseDown[0] && type != NONE) if (CanActivate() && type != NONE)
{ {
ImGui::CaptureMouseFromApp();
gContext.mbUsing = true; gContext.mbUsing = true;
gContext.mCurrentOperation = type; gContext.mCurrentOperation = type;
const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.up, -gContext.mCameraDir }; const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.up, -gContext.mCameraDir };
@ -1409,8 +1510,9 @@ namespace ImGuizmo
{ {
// find new possible way to scale // find new possible way to scale
type = GetScaleType(); type = GetScaleType();
if (io.MouseDown[0] && type != NONE) if (CanActivate() && type != NONE)
{ {
ImGui::CaptureMouseFromApp();
gContext.mbUsing = true; gContext.mbUsing = true;
gContext.mCurrentOperation = type; gContext.mCurrentOperation = type;
const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.up, gContext.mModel.v.right, -gContext.mCameraDir }; const vec_t movePlanNormal[] = { gContext.mModel.v.up, gContext.mModel.v.dir, gContext.mModel.v.right, gContext.mModel.v.dir, gContext.mModel.v.up, gContext.mModel.v.right, -gContext.mCameraDir };
@ -1429,6 +1531,7 @@ namespace ImGuizmo
// scale // scale
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
ImGui::CaptureMouseFromApp();
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan); const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len; vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor; vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
@ -1498,8 +1601,9 @@ namespace ImGuizmo
applyRotationLocaly = true; applyRotationLocaly = true;
} }
if (io.MouseDown[0] && type != NONE) if (CanActivate() && type != NONE)
{ {
ImGui::CaptureMouseFromApp();
gContext.mbUsing = true; gContext.mbUsing = true;
gContext.mCurrentOperation = type; gContext.mCurrentOperation = type;
const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir }; const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
@ -1523,6 +1627,7 @@ namespace ImGuizmo
// rotation // rotation
if (gContext.mbUsing) if (gContext.mbUsing)
{ {
ImGui::CaptureMouseFromApp();
gContext.mRotationAngle = ComputeAngleOnPlan(); gContext.mRotationAngle = ComputeAngleOnPlan();
if (snap) if (snap)
{ {
@ -1713,7 +1818,7 @@ namespace ImGuizmo
continue; continue;
// draw face with lighter color // draw face with lighter color
gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, directionColor[normalIndex] | 0x808080, true); gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, directionColor[normalIndex] | 0x808080);
} }
} }
}; };

View File

@ -112,6 +112,9 @@ void EditTransform(const Camera& camera, matrix_t& matrix)
namespace ImGuizmo namespace ImGuizmo
{ {
// call inside your own window and before Manipulate() in order to draw gizmo to that window.
IMGUI_API void SetDrawlist();
// call BeginFrame right after ImGui_XXXX_NewFrame(); // call BeginFrame right after ImGui_XXXX_NewFrame();
IMGUI_API void BeginFrame(); IMGUI_API void BeginFrame();

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
#include "OpenGLWindow/X11OpenGLWindow.h" #include "OpenGLWindow/X11OpenGLWindow.h"
#endif #endif
#include <imgui_internal.h>
#include <cstdio> #include <cstdio>
#define IMGUI_B3G_CONTROL (300) #define IMGUI_B3G_CONTROL (300)
@ -122,12 +123,12 @@ void ImGui_ImplBtGui_RenderDrawLists(ImDrawData* draw_data) {
(GLsizei)last_viewport[3]); (GLsizei)last_viewport[3]);
} }
static const char* ImGui_ImplBtGui_GetClipboardText() { static const char* ImGui_ImplBtGui_GetClipboardText(void* user_ctx) {
// @todo // @todo
return NULL; // glfwGetClipboardString(g_Window); return NULL; // glfwGetClipboardString(g_Window);
} }
static void ImGui_ImplBtGui_SetClipboardText(const char* text) { static void ImGui_ImplBtGui_SetClipboardText(void* user_ctx, const char* text) {
// @todo // @todo
return; return;
// glfwSetClipboardString(g_Window, text); // glfwSetClipboardString(g_Window, text);
@ -277,7 +278,7 @@ bool ImGui_ImplBtGui_Init(b3gDefaultOpenGLWindow* window) {
void ImGui_ImplBtGui_Shutdown() { void ImGui_ImplBtGui_Shutdown() {
ImGui_ImplBtGui_InvalidateDeviceObjects(); ImGui_ImplBtGui_InvalidateDeviceObjects();
ImGui::Shutdown(); ImGui::Shutdown(ImGui::GetCurrentContext());
} }
void ImGui_ImplBtGui_NewFrame(int mouse_x, int mouse_y) { void ImGui_ImplBtGui_NewFrame(int mouse_x, int mouse_y) {

File diff suppressed because it is too large Load Diff

View File

@ -53,6 +53,7 @@ THE SOFTWARE.
#include <cstdio> #include <cstdio>
#include <cstdlib> #include <cstdlib>
#include <cstring> #include <cstring>
#include <fstream>
#include <iostream> #include <iostream>
#include <limits> #include <limits>
#include <map> #include <map>
@ -338,6 +339,8 @@ void keyboardCallback(int keycode, int state) {
void mouseMoveCallback(float x, float y) { void mouseMoveCallback(float x, float y) {
if (gMouseLeftDown) { if (gMouseLeftDown) {
if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) { if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) {
gSceneDirty = true;
// RequestRender();
} else { } else {
float w = static_cast<float>(gRenderConfig.width); float w = static_cast<float>(gRenderConfig.width);
float h = static_cast<float>(gRenderConfig.height); float h = static_cast<float>(gRenderConfig.height);
@ -376,11 +379,18 @@ void mouseButtonCallback(int button, int state, float x, float y) {
(void)y; (void)y;
ImGui_ImplBtGui_SetMouseButtonState(button, (state == 1)); ImGui_ImplBtGui_SetMouseButtonState(button, (state == 1));
if (button == 0 && !state)
gMouseLeftDown = false; // prevent sticky trackball after using gizmo
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();
if (io.WantCaptureMouse || io.WantCaptureKeyboard) { if (io.WantCaptureMouse || io.WantCaptureKeyboard) {
return; if (button == 0 && !state) {
if (ImGuizmo::IsUsing()) {
gSceneDirty = true;
RequestRender();
} }
}
} else {
// left button // left button
if (button == 0) { if (button == 0) {
if (state) { if (state) {
@ -390,10 +400,6 @@ void mouseButtonCallback(int button, int state, float x, float y) {
trackball(gPrevQuat, 0.0f, 0.0f, 0.0f, 0.0f); trackball(gPrevQuat, 0.0f, 0.0f, 0.0f, 0.0f);
} }
} else { } else {
gMouseLeftDown = false;
if (ImGuizmo::IsOver() || ImGuizmo::IsUsing()) {
gSceneDirty = true;
RequestRender();
} }
} }
} }
@ -762,10 +768,36 @@ int main(int argc, char **argv) {
} }
} }
if (textures.size() > 0) {
materials[0].diffuse_texid = 0;
}
gAsset.materials = materials; gAsset.materials = materials;
gAsset.default_material = default_material; gAsset.default_material = default_material;
gAsset.textures = textures; gAsset.textures = textures;
#ifdef _DEBUG
// output raw data as RGB ASCII PPM file
if (textures.size() > 0) {
std::ofstream output(
"./"
"debug"
".ppm");
if (output) {
output << "P3\n#sampleOutputDebug\n";
example::Texture &t = textures[0];
output << t.width << ' ' << t.height << "\n#imgSize\n255\n";
for (size_t i{0}; i < t.width * t.height * t.components;
i += t.components) {
for (size_t j{0}; j < 3; ++j)
output << size_t(t.image[i + j]) << '\n';
}
}
}
#endif
for (size_t n = 0; n < meshes.size(); n++) { for (size_t n = 0; n < meshes.size(); n++) {
size_t mesh_id = gAsset.meshes.size(); size_t mesh_id = gAsset.meshes.size();
gAsset.meshes.push_back(meshes[mesh_id]); gAsset.meshes.push_back(meshes[mesh_id]);
@ -872,6 +904,7 @@ int main(int argc, char **argv) {
window->setResizeCallback(resizeCallback); window->setResizeCallback(resizeCallback);
checkErrors("resize"); checkErrors("resize");
ImGui::CreateContext();
ImGui_ImplBtGui_Init(window); ImGui_ImplBtGui_Init(window);
ImGuiIO &io = ImGui::GetIO(); ImGuiIO &io = ImGui::GetIO();