|
|
@@ -1,8 +1,30 @@
|
|
|
-// https://github.com/CedricGuillemet/ImGuizmo
|
|
|
+// The MIT License(MIT)
|
|
|
+//
|
|
|
+// Copyright(c) 2016 Cedric Guillemet
|
|
|
+//
|
|
|
+// Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
+// of this software and associated documentation files(the "Software"), to deal
|
|
|
+// in the Software without restriction, including without limitation the rights
|
|
|
+// to use, copy, modify, merge, publish, distribute, sublicense, and / or sell
|
|
|
+// copies of the Software, and to permit persons to whom the Software is
|
|
|
+// furnished to do so, subject to the following conditions :
|
|
|
+//
|
|
|
+// The above copyright notice and this permission notice shall be included in all
|
|
|
+// copies or substantial portions of the Software.
|
|
|
+//
|
|
|
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.IN NO EVENT SHALL THE
|
|
|
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
|
+// SOFTWARE.
|
|
|
|
|
|
namespace ImGuizmo
|
|
|
{
|
|
|
- const float ZPI = 3.14159265358979323846f;
|
|
|
+ static const float ZPI = 3.14159265358979323846f;
|
|
|
+ static const float RAD2DEG = (180.f / ZPI);
|
|
|
+ static const float DEG2RAD = (ZPI / 180.f);
|
|
|
|
|
|
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
// utility and math
|
|
|
@@ -47,8 +69,8 @@ namespace ImGuizmo
|
|
|
w += (v.w - w) * t;
|
|
|
}
|
|
|
|
|
|
- void set(float v) { x = y = z = w = v; }
|
|
|
- void set(float _x, float _y, float _z = 0.f, float _w = 0.f) { x = _x; y = _y; z = _z; w = _w; }
|
|
|
+ void Set(float v) { x = y = z = w = v; }
|
|
|
+ void Set(float _x, float _y, float _z = 0.f, float _w = 0.f) { x = _x; y = _y; z = _z; w = _w; }
|
|
|
|
|
|
vec_t& operator -= (const vec_t& v) { x -= v.x; y -= v.y; z -= v.z; w -= v.w; return *this; }
|
|
|
vec_t& operator += (const vec_t& v) { x += v.x; y += v.y; z += v.z; w += v.w; return *this; }
|
|
|
@@ -65,7 +87,7 @@ namespace ImGuizmo
|
|
|
float Length() const { return sqrtf(x*x + y*y + z*z); };
|
|
|
float LengthSq() const { return (x*x + y*y + z*z); };
|
|
|
vec_t Normalize() { (*this) *= (1.f / Length()); return (*this); }
|
|
|
- vec_t Normalize(const vec_t& v) { this->set(v.x, v.y, v.z, v.w); this->Normalize(); return (*this); }
|
|
|
+ vec_t Normalize(const vec_t& v) { this->Set(v.x, v.y, v.z, v.w); this->Normalize(); return (*this); }
|
|
|
|
|
|
void Cross(const vec_t& v)
|
|
|
{
|
|
|
@@ -107,41 +129,12 @@ namespace ImGuizmo
|
|
|
const float& operator [] (size_t index) const { return ((float*)&x)[index]; }
|
|
|
};
|
|
|
|
|
|
- vec_t vect(float _x, float _y, float _z = 0.f, float _w = 0.f)
|
|
|
- {
|
|
|
- vec_t res;
|
|
|
- res.x = _x;
|
|
|
- res.y = _y;
|
|
|
- res.z = _z;
|
|
|
- res.w = _w;
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- vec_t vect(int _x, int _y, int _z = 0, int _w = 0)
|
|
|
- {
|
|
|
- vec_t res;
|
|
|
- res.x = float(_x);
|
|
|
- res.y = float(_y);
|
|
|
- res.z = float(_z);
|
|
|
- res.w = float(_w);
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- vec_t vect(float v)
|
|
|
- {
|
|
|
- vec_t res;
|
|
|
- res.x = v;
|
|
|
- res.y = v;
|
|
|
- res.z = v;
|
|
|
- res.w = v;
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- vec_t vec_t::operator * (float f) const { return vect(x * f, y * f, z * f, w *f); }
|
|
|
- vec_t vec_t::operator - () const { return vect(-x, -y, -z, -w); }
|
|
|
- vec_t vec_t::operator - (const vec_t& v) const { return vect(x - v.x, y - v.y, z - v.z, w - v.w); }
|
|
|
- vec_t vec_t::operator + (const vec_t& v) const { return vect(x + v.x, y + v.y, z + v.z, w + v.w); }
|
|
|
- vec_t vec_t::operator * (const vec_t& v) const { return vect(x * v.x, y * v.y, z * v.z, w * v.w); }
|
|
|
+ vec_t makeVect(float _x, float _y, float _z = 0.f, float _w = 0.f) { vec_t res; res.x = _x; res.y = _y; res.z = _z; res.w = _w; return res; }
|
|
|
+ vec_t vec_t::operator * (float f) const { return makeVect(x * f, y * f, z * f, w *f); }
|
|
|
+ vec_t vec_t::operator - () const { return makeVect(-x, -y, -z, -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); }
|
|
|
|
|
|
ImVec2 operator+ (const ImVec2& a, const ImVec2& b) { return ImVec2(a.x + b.x, a.y + b.y); }
|
|
|
|
|
|
@@ -175,6 +168,7 @@ namespace ImGuizmo
|
|
|
struct matrix_t
|
|
|
{
|
|
|
public:
|
|
|
+
|
|
|
union
|
|
|
{
|
|
|
float m[4][4];
|
|
|
@@ -182,11 +176,7 @@ namespace ImGuizmo
|
|
|
struct
|
|
|
{
|
|
|
vec_t right, up, dir, position;
|
|
|
- };
|
|
|
- struct
|
|
|
- {
|
|
|
- vec_t line[4];
|
|
|
- };
|
|
|
+ } v;
|
|
|
};
|
|
|
|
|
|
matrix_t(const matrix_t& other) { memcpy(&m16[0], &other.m16[0], sizeof(float) * 16); }
|
|
|
@@ -194,24 +184,24 @@ namespace ImGuizmo
|
|
|
|
|
|
operator float * () { return m16; }
|
|
|
operator const float* () const { return m16; }
|
|
|
- void translation(float _x, float _y, float _z) { this->translation(vect(_x, _y, _z)); }
|
|
|
+ void Translation(float _x, float _y, float _z) { this->Translation(makeVect(_x, _y, _z)); }
|
|
|
|
|
|
- void translation(const vec_t& vt)
|
|
|
+ void Translation(const vec_t& vt)
|
|
|
{
|
|
|
- right.set(1.f, 0.f, 0.f, 0.f);
|
|
|
- up.set(0.f, 1.f, 0.f, 0.f);
|
|
|
- dir.set(0.f, 0.f, 1.f, 0.f);
|
|
|
- position.set(vt.x, vt.y, vt.z, 1.f);
|
|
|
+ v.right.Set(1.f, 0.f, 0.f, 0.f);
|
|
|
+ v.up.Set(0.f, 1.f, 0.f, 0.f);
|
|
|
+ v.dir.Set(0.f, 0.f, 1.f, 0.f);
|
|
|
+ v.position.Set(vt.x, vt.y, vt.z, 1.f);
|
|
|
}
|
|
|
|
|
|
- void scale(float _x, float _y, float _z)
|
|
|
+ void Scale(float _x, float _y, float _z)
|
|
|
{
|
|
|
- right.set(_x, 0.f, 0.f, 0.f);
|
|
|
- up.set(0.f, _y, 0.f, 0.f);
|
|
|
- dir.set(0.f, 0.f, _z, 0.f);
|
|
|
- position.set(0.f, 0.f, 0.f, 1.f);
|
|
|
+ v.right.Set(_x, 0.f, 0.f, 0.f);
|
|
|
+ v.up.Set(0.f, _y, 0.f, 0.f);
|
|
|
+ v.dir.Set(0.f, 0.f, _z, 0.f);
|
|
|
+ v.position.Set(0.f, 0.f, 0.f, 1.f);
|
|
|
}
|
|
|
- void scale(const vec_t& s) { scale(s.x, s.y, s.z); }
|
|
|
+ void Scale(const vec_t& s) { Scale(s.x, s.y, s.z); }
|
|
|
|
|
|
matrix_t& operator *= (const matrix_t& mat)
|
|
|
{
|
|
|
@@ -249,13 +239,14 @@ namespace ImGuizmo
|
|
|
|
|
|
float Inverse(const matrix_t &srcMatrix, bool affine = false);
|
|
|
float Inverse(bool affine = false);
|
|
|
- void SetToIdentity() {
|
|
|
- right.set(1.f, 0.f, 0.f, 0.f);
|
|
|
- up.set(0.f, 1.f, 0.f, 0.f);
|
|
|
- dir.set(0.f, 0.f, 1.f, 0.f);
|
|
|
- position.set(0.f, 0.f, 0.f, 1.f);
|
|
|
+ void SetToIdentity()
|
|
|
+ {
|
|
|
+ v.right.Set(1.f, 0.f, 0.f, 0.f);
|
|
|
+ v.up.Set(0.f, 1.f, 0.f, 0.f);
|
|
|
+ v.dir.Set(0.f, 0.f, 1.f, 0.f);
|
|
|
+ v.position.Set(0.f, 0.f, 0.f, 1.f);
|
|
|
}
|
|
|
- void transpose()
|
|
|
+ void Transpose()
|
|
|
{
|
|
|
matrix_t tmpm;
|
|
|
for (int l = 0; l < 4; l++)
|
|
|
@@ -269,6 +260,13 @@ namespace ImGuizmo
|
|
|
}
|
|
|
|
|
|
void RotationAxis(const vec_t & axis, float angle);
|
|
|
+
|
|
|
+ void OrthoNormalize()
|
|
|
+ {
|
|
|
+ v.right.Normalize();
|
|
|
+ v.up.Normalize();
|
|
|
+ v.dir.Normalize();
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
void vec_t::Transform(const matrix_t& matrix)
|
|
|
@@ -496,6 +494,7 @@ namespace ImGuizmo
|
|
|
matrix_t mProjectionMat;
|
|
|
matrix_t mModel;
|
|
|
matrix_t mModelInverse;
|
|
|
+ matrix_t mModelSource;
|
|
|
matrix_t mMVP;
|
|
|
matrix_t mViewProjection;
|
|
|
|
|
|
@@ -528,6 +527,10 @@ namespace ImGuizmo
|
|
|
float mRotationAngle;
|
|
|
float mRotationAngleOrigin;
|
|
|
|
|
|
+ // scale
|
|
|
+ vec_t mScale;
|
|
|
+ ImVec2 mScaleMousePos;
|
|
|
+
|
|
|
int mCurrentOperation;
|
|
|
};
|
|
|
|
|
|
@@ -536,12 +539,13 @@ namespace ImGuizmo
|
|
|
static const float angleLimit = 0.96f;
|
|
|
static const float planeLimit = 0.2f;
|
|
|
|
|
|
- static const vec_t direction[3] = { vect(1.f,0.f,0.f), vect(0.f,1.f,0.f), vect(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 selectionColor = 0xFF1080FF;
|
|
|
static const ImU32 inactiveColor = 0x99999999;
|
|
|
static const ImU32 translationLineColor = 0xAAAAAAAA;
|
|
|
- static const char *translationInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "X : %5.2f Y : %5.2f", "X : %5.2f Z : %5.2f", "Y : %5.2f Z : %5.2f", "X : %5.2f Y : %5.2f Z : %5.2f" };
|
|
|
+ static const char *translationInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "X : %5.2f Y : %5.2f", "Y : %5.2f Z : %5.2f", "X : %5.2f Z : %5.2f", "X : %5.2f Y : %5.2f Z : %5.2f" };
|
|
|
+ static const char *scaleInfoMask[] = { "X : %5.2f", "Y : %5.2f", "Z : %5.2f", "XYZ : %5.2f" };
|
|
|
static const char *rotationInfoMask[] = { "X : %5.2f deg %5.2f rad", "Y : %5.2f deg %5.2f rad", "Z : %5.2f deg %5.2f rad", "Screen : %5.2f deg %5.2f rad" };
|
|
|
static const int translationInfoIndex[] = { 0,0,0, 1,0,0, 2,0,0, 0,1,0, 0,2,0, 1,2,0, 0,1,2 };
|
|
|
static const float quadMin = 0.5f;
|
|
|
@@ -553,6 +557,7 @@ namespace ImGuizmo
|
|
|
//
|
|
|
static int GetMoveType(vec_t *gizmoHitProportion);
|
|
|
static int GetRotateType();
|
|
|
+ static int GetScaleType();
|
|
|
|
|
|
static ImVec2 worldToPos(const vec_t& worldPos, const matrix_t& mat)
|
|
|
{
|
|
|
@@ -561,7 +566,7 @@ namespace ImGuizmo
|
|
|
vec_t trans;
|
|
|
trans.TransformPoint(worldPos, mat);
|
|
|
trans *= 0.5f / trans.w;
|
|
|
- trans += vect(0.5f);
|
|
|
+ trans += makeVect(0.5f, 0.5f);
|
|
|
trans.y = 1.f - trans.y;
|
|
|
trans.x *= io.DisplaySize.x;
|
|
|
trans.y *= io.DisplaySize.y;
|
|
|
@@ -578,10 +583,10 @@ namespace ImGuizmo
|
|
|
float mox = (io.MousePos.x / io.DisplaySize.x) * 2.f - 1.f;
|
|
|
float moy = (1.f - (io.MousePos.y / io.DisplaySize.y)) * 2.f - 1.f;
|
|
|
|
|
|
- rayOrigin.Transform(vect(mox, moy, 0.f, 1.f), mViewProjInverse);
|
|
|
+ rayOrigin.Transform(makeVect(mox, moy, 0.f, 1.f), mViewProjInverse);
|
|
|
rayOrigin *= 1.f / rayOrigin.w;
|
|
|
vec_t rayEnd;
|
|
|
- rayEnd.Transform(vect(mox, moy, 1.f, 1.f), mViewProjInverse);
|
|
|
+ rayEnd.Transform(makeVect(mox, moy, 1.f, 1.f), mViewProjInverse);
|
|
|
rayEnd *= 1.f / rayEnd.w;
|
|
|
rayDir = Normalized(rayEnd - rayOrigin);
|
|
|
}
|
|
|
@@ -614,7 +619,7 @@ namespace ImGuizmo
|
|
|
|
|
|
bool IsOver()
|
|
|
{
|
|
|
- return (GetMoveType(NULL) != NONE) || GetRotateType() != NONE || IsUsing();
|
|
|
+ return (GetMoveType(NULL) != NONE) || GetRotateType() != NONE || GetScaleType() != NONE || IsUsing();
|
|
|
}
|
|
|
|
|
|
void Enable(bool enable)
|
|
|
@@ -626,30 +631,39 @@ namespace ImGuizmo
|
|
|
|
|
|
static float GetUniform(const vec_t& position, const matrix_t& mat)
|
|
|
{
|
|
|
- vec_t trf = vect(position.x, position.y, position.z, 1.f);
|
|
|
+ vec_t trf = makeVect(position.x, position.y, position.z, 1.f);
|
|
|
trf.Transform(mat);
|
|
|
return trf.w;
|
|
|
}
|
|
|
|
|
|
- static void ComputeContext(const float *view, const float *projection, float *matrix)
|
|
|
+ static void ComputeContext(const float *view, const float *projection, float *matrix, MODE mode)
|
|
|
{
|
|
|
gContext.mViewMat = *(matrix_t*)view;
|
|
|
gContext.mProjectionMat = *(matrix_t*)projection;
|
|
|
- gContext.mModel = *(matrix_t*)matrix;
|
|
|
+ if (mode == LOCAL)
|
|
|
+ {
|
|
|
+ gContext.mModel = *(matrix_t*)matrix;
|
|
|
+ gContext.mModel.OrthoNormalize();
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ gContext.mModel.Translation(((matrix_t*)matrix)->v.position);
|
|
|
+ }
|
|
|
+ gContext.mModelSource = *(matrix_t*)matrix;
|
|
|
gContext.mModelInverse.Inverse(gContext.mModel);
|
|
|
gContext.mViewProjection = gContext.mViewMat * gContext.mProjectionMat;
|
|
|
gContext.mMVP = gContext.mModel * gContext.mViewProjection;
|
|
|
|
|
|
matrix_t viewInverse;
|
|
|
viewInverse.Inverse(gContext.mViewMat);
|
|
|
- gContext.mCameraDir = viewInverse.dir;
|
|
|
- gContext.mCameraEye = viewInverse.position;
|
|
|
- gContext.mCameraRight = viewInverse.right;
|
|
|
- gContext.mCameraUp = viewInverse.up;
|
|
|
- gContext.mCameraToModel = gContext.mModel.position - gContext.mCameraEye;
|
|
|
- gContext.mScreenFactor = 0.1f * GetUniform(gContext.mModel.position, gContext.mViewProjection);
|
|
|
-
|
|
|
- ImVec2 centerSSpace = worldToPos(vect(0.f), gContext.mMVP);
|
|
|
+ gContext.mCameraDir = viewInverse.v.dir;
|
|
|
+ gContext.mCameraEye = viewInverse.v.position;
|
|
|
+ gContext.mCameraRight = viewInverse.v.right;
|
|
|
+ gContext.mCameraUp = viewInverse.v.up;
|
|
|
+ gContext.mCameraToModel = gContext.mModel.v.position - gContext.mCameraEye;
|
|
|
+ gContext.mScreenFactor = 0.1f * GetUniform(gContext.mModel.v.position, gContext.mViewProjection);
|
|
|
+
|
|
|
+ ImVec2 centerSSpace = worldToPos(makeVect(0.f, 0.f), gContext.mMVP);
|
|
|
gContext.mScreenSquareCenter = centerSSpace;
|
|
|
gContext.mScreenSquareMin = ImVec2(centerSSpace.x - 10.f, centerSSpace.y - 10.f);
|
|
|
gContext.mScreenSquareMax = ImVec2(centerSSpace.x + 10.f, centerSSpace.y + 10.f);
|
|
|
@@ -657,11 +671,11 @@ namespace ImGuizmo
|
|
|
ComputeCameraRay(gContext.mRayOrigin, gContext.mRayVector);
|
|
|
}
|
|
|
|
|
|
- static void ComputeColors(ImU32 *colors, int type, MODE mode)
|
|
|
+ static void ComputeColors(ImU32 *colors, int type, OPERATION operation)
|
|
|
{
|
|
|
if (gContext.mbEnable)
|
|
|
{
|
|
|
- switch (mode)
|
|
|
+ switch (operation)
|
|
|
{
|
|
|
case TRANSLATE:
|
|
|
colors[0] = (type == MOVE_SCREEN) ? selectionColor : 0xFFFFFFFF;
|
|
|
@@ -678,12 +692,15 @@ namespace ImGuizmo
|
|
|
colors[i + 1] = (type == (int)(ROTATE_X + i)) ? selectionColor : directionColor[i];
|
|
|
break;
|
|
|
case SCALE:
|
|
|
+ colors[0] = (type == SCALE_XYZ) ? selectionColor : 0xFFFFFFFF;
|
|
|
+ for (int i = 0; i < 3; i++)
|
|
|
+ colors[i + 1] = (type == (int)(SCALE_X + i)) ? selectionColor : directionColor[i];
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- for (int i = 0; i < int(sizeof(colors) / sizeof(ImU32)); i++)
|
|
|
+ for (int i = 0; i < 7; i++)
|
|
|
colors[i] = inactiveColor;
|
|
|
}
|
|
|
}
|
|
|
@@ -709,19 +726,19 @@ namespace ImGuizmo
|
|
|
for (unsigned int i = 0; i < halfCircleSegmentCount; i++)
|
|
|
{
|
|
|
float ng = angleStart + ZPI * ((float)i / (float)halfCircleSegmentCount);
|
|
|
- vec_t axisPos = vect(cosf(ng), sinf(ng), 0.f);
|
|
|
- vec_t pos = vect(axisPos[axis], axisPos[(axis+1)%3], axisPos[(axis+2)%3]) * gContext.mScreenFactor;
|
|
|
+ vec_t axisPos = makeVect(cosf(ng), sinf(ng), 0.f);
|
|
|
+ vec_t pos = makeVect(axisPos[axis], axisPos[(axis+1)%3], axisPos[(axis+2)%3]) * gContext.mScreenFactor;
|
|
|
circlePos[i] = worldToPos(pos, gContext.mMVP);
|
|
|
}
|
|
|
drawList->AddPolyline(circlePos, halfCircleSegmentCount, colors[3 - axis], false, 2, true);
|
|
|
}
|
|
|
- drawList->AddCircle(worldToPos(gContext.mModel.position, gContext.mViewProjection), 0.06f * io.DisplaySize.x, colors[0], 64);
|
|
|
+ drawList->AddCircle(worldToPos(gContext.mModel.v.position, gContext.mViewProjection), 0.06f * io.DisplaySize.x, colors[0], 64);
|
|
|
|
|
|
if (gContext.mbUsing)
|
|
|
{
|
|
|
ImVec2 circlePos[halfCircleSegmentCount +1];
|
|
|
|
|
|
- circlePos[0] = worldToPos(gContext.mModel.position, gContext.mViewProjection);
|
|
|
+ circlePos[0] = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
|
|
for (unsigned int i = 1; i < halfCircleSegmentCount; i++)
|
|
|
{
|
|
|
float ng = gContext.mRotationAngle * ((float)(i-1) / (float)(halfCircleSegmentCount -1));
|
|
|
@@ -730,7 +747,7 @@ namespace ImGuizmo
|
|
|
vec_t pos;
|
|
|
pos.TransformPoint(gContext.mRotationVectorSource, rotateVectorMatrix);
|
|
|
pos *= gContext.mScreenFactor;
|
|
|
- circlePos[i] = worldToPos(pos + gContext.mModel.position, gContext.mViewProjection);
|
|
|
+ circlePos[i] = worldToPos(pos + gContext.mModel.v.position, gContext.mViewProjection);
|
|
|
}
|
|
|
drawList->AddConvexPolyFilled(circlePos, halfCircleSegmentCount, 0x801080FF, true);
|
|
|
drawList->AddPolyline(circlePos, halfCircleSegmentCount, 0xFF1080FF, true, 2, true);
|
|
|
@@ -751,62 +768,63 @@ namespace ImGuizmo
|
|
|
ImU32 colors[7];
|
|
|
ComputeColors(colors, type, SCALE);
|
|
|
|
|
|
- // draw screen quad
|
|
|
- drawList->AddCircle(gContext.mScreenSquareCenter, 8.f, colors[0]);
|
|
|
- /*
|
|
|
+ // draw screen cirle
|
|
|
+ drawList->AddCircleFilled(gContext.mScreenSquareCenter, 12.f, colors[0], 32);
|
|
|
+
|
|
|
// draw
|
|
|
+ vec_t scale = { 1.f, 1.f, 1.f, 1.f };
|
|
|
+
|
|
|
+ if (gContext.mbUsing)
|
|
|
+ scale = gContext.mScale;
|
|
|
+
|
|
|
for (unsigned int i = 0; i < 3; i++)
|
|
|
{
|
|
|
- const int planNormal = (i + 2) % 3;
|
|
|
- const vec_t& dirPlaneX = direction[i];
|
|
|
- const vec_t& dirPlaneY = direction[(i + 1) % 3];
|
|
|
- const vec_t& dirPlaneNormal = direction[planNormal];
|
|
|
+ //const int planNormal = (i + 2) % 3;
|
|
|
+ const vec_t& dirPlaneX = directionUnary[i];
|
|
|
+ //const vec_t& dirPlaneY = directionUnary[(i + 1) % 3];
|
|
|
+ //const vec_t& dirPlaneNormal = directionUnary[planNormal];
|
|
|
|
|
|
- vec_t cameraEyeToGizmo = Normalized(gContext.mModel.position - gContext.mCameraEye);
|
|
|
- const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneX)) < angleLimit);
|
|
|
- const bool belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneNormal)) > planeLimit);
|
|
|
+ //vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
|
|
|
+ //const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneX)) < angleLimit);
|
|
|
+ //const bool belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneNormal)) > planeLimit);
|
|
|
|
|
|
// draw axis
|
|
|
- if (belowAxisLimit)
|
|
|
+ //if (belowAxisLimit)
|
|
|
{
|
|
|
ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP);
|
|
|
- ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
|
|
|
+ ImVec2 worldDirSSpaceNoScale = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
|
|
|
+ ImVec2 worldDirSSpace = worldToPos(dirPlaneX * (1.f / scale[i]) * gContext.mScreenFactor, gContext.mMVP);
|
|
|
|
|
|
- drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
|
|
|
- }
|
|
|
-
|
|
|
- // draw plane
|
|
|
- if (belowPlaneLimit)
|
|
|
- {
|
|
|
- ImVec2 screenQuadPts[4];
|
|
|
- for (int j = 0; j < 4; j++)
|
|
|
+ if (gContext.mbUsing)
|
|
|
{
|
|
|
- vec_t cornerWorldPos = (dirPlaneX * quadUV[j * 2] + dirPlaneY * quadUV[j * 2 + 1]) * gContext.mScreenFactor;
|
|
|
- screenQuadPts[j] = worldToPos(cornerWorldPos, gContext.mMVP);
|
|
|
+ drawList->AddLine(baseSSpace, worldDirSSpaceNoScale, 0xFF404040, 6.f);
|
|
|
+ drawList->AddCircleFilled(worldDirSSpaceNoScale, 10.f, 0xFF404040);
|
|
|
}
|
|
|
- drawList->AddConvexPolyFilled(screenQuadPts, 4, colors[i + 4], true);
|
|
|
+
|
|
|
+ drawList->AddLine(baseSSpace, worldDirSSpace, colors[i + 1], 6.f);
|
|
|
+ drawList->AddCircleFilled(worldDirSSpace, 10.f, colors[i + 1]);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
if (gContext.mbUsing)
|
|
|
{
|
|
|
- ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
|
|
- ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.position, gContext.mViewProjection);
|
|
|
- vec_t dif(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y);
|
|
|
+// ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
|
|
+ ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
|
|
+ /*vec_t dif(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y);
|
|
|
dif.Normalize();
|
|
|
dif *= 5.f;
|
|
|
drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor);
|
|
|
drawList->AddCircle(destinationPosOnScreen, 6.f, translationLineColor);
|
|
|
drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f);
|
|
|
-
|
|
|
+ */
|
|
|
char tmps[512];
|
|
|
- vec_t deltaInfo = gContext.mModel.position - gContext.mMatrixOrigin;
|
|
|
- int componentInfoIndex = (type - MOVE_X) * 3;
|
|
|
- ImFormatString(tmps, sizeof(tmps), translationInfoMask[type - MOVE_X], deltaInfo[translationInfoIndex[componentInfoIndex]], deltaInfo[translationInfoIndex[componentInfoIndex + 1]], deltaInfo[translationInfoIndex[componentInfoIndex + 2]]);
|
|
|
+ //vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin;
|
|
|
+ int componentInfoIndex = (type - SCALE_X) * 3;
|
|
|
+ ImFormatString(tmps, sizeof(tmps), scaleInfoMask[type - SCALE_X], 1.f/gContext.mScale[translationInfoIndex[componentInfoIndex]]);
|
|
|
drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
|
|
|
drawList->AddText(ImVec2(destinationPosOnScreen.x + 14, destinationPosOnScreen.y + 14), 0xFFFFFFFF, tmps);
|
|
|
}
|
|
|
- */
|
|
|
+
|
|
|
}
|
|
|
|
|
|
static void DrawTranslationGizmo(int type)
|
|
|
@@ -818,22 +836,22 @@ namespace ImGuizmo
|
|
|
ComputeColors(colors, type, TRANSLATE);
|
|
|
|
|
|
// draw screen quad
|
|
|
- drawList->AddCircle(gContext.mScreenSquareCenter, 8.f, colors[0]);
|
|
|
+ drawList->AddRectFilled(gContext.mScreenSquareMin, gContext.mScreenSquareMax, colors[0], 2.f);
|
|
|
|
|
|
// draw
|
|
|
for (unsigned int i = 0; i < 3; i++)
|
|
|
{
|
|
|
- const int planNormal = (i + 2) % 3;
|
|
|
- const vec_t& dirPlaneX = direction[i];
|
|
|
- const vec_t& dirPlaneY = direction[(i + 1) % 3];
|
|
|
- const vec_t& dirPlaneNormal = direction[planNormal];
|
|
|
+ //const int planNormal = (i + 2) % 3;
|
|
|
+ const vec_t& dirPlaneX = directionUnary[i];
|
|
|
+ const vec_t& dirPlaneY = directionUnary[(i + 1) % 3];
|
|
|
+ //const vec_t& dirPlaneNormal = directionUnary[planNormal];
|
|
|
|
|
|
- vec_t cameraEyeToGizmo = Normalized(gContext.mModel.position - gContext.mCameraEye);
|
|
|
- const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneX)) < angleLimit);
|
|
|
- const bool belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneNormal)) > planeLimit);
|
|
|
+ //vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
|
|
|
+ //const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneX)) < angleLimit);
|
|
|
+ //const bool belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(dirPlaneNormal)) > planeLimit);
|
|
|
|
|
|
// draw axis
|
|
|
- if (belowAxisLimit)
|
|
|
+ //if (belowAxisLimit)
|
|
|
{
|
|
|
ImVec2 baseSSpace = worldToPos(dirPlaneX * 0.1f * gContext.mScreenFactor, gContext.mMVP);
|
|
|
ImVec2 worldDirSSpace = worldToPos(dirPlaneX * gContext.mScreenFactor, gContext.mMVP);
|
|
|
@@ -842,7 +860,7 @@ namespace ImGuizmo
|
|
|
}
|
|
|
|
|
|
// draw plane
|
|
|
- if (belowPlaneLimit)
|
|
|
+ //if (belowPlaneLimit)
|
|
|
{
|
|
|
ImVec2 screenQuadPts[4];
|
|
|
for (int j = 0; j < 4; j++)
|
|
|
@@ -857,8 +875,8 @@ namespace ImGuizmo
|
|
|
if (gContext.mbUsing)
|
|
|
{
|
|
|
ImVec2 sourcePosOnScreen = worldToPos(gContext.mMatrixOrigin, gContext.mViewProjection);
|
|
|
- ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.position, gContext.mViewProjection);
|
|
|
- vec_t dif = vect(destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y);
|
|
|
+ ImVec2 destinationPosOnScreen = worldToPos(gContext.mModel.v.position, gContext.mViewProjection);
|
|
|
+ vec_t dif = { destinationPosOnScreen.x - sourcePosOnScreen.x, destinationPosOnScreen.y - sourcePosOnScreen.y, 0.0f, 0.0f };
|
|
|
dif.Normalize();
|
|
|
dif *= 5.f;
|
|
|
drawList->AddCircle(sourcePosOnScreen, 6.f, translationLineColor);
|
|
|
@@ -866,7 +884,7 @@ namespace ImGuizmo
|
|
|
drawList->AddLine(ImVec2(sourcePosOnScreen.x + dif.x, sourcePosOnScreen.y + dif.y), ImVec2(destinationPosOnScreen.x - dif.x, destinationPosOnScreen.y - dif.y), translationLineColor, 2.f);
|
|
|
|
|
|
char tmps[512];
|
|
|
- vec_t deltaInfo = gContext.mModel.position - gContext.mMatrixOrigin;
|
|
|
+ vec_t deltaInfo = gContext.mModel.v.position - gContext.mMatrixOrigin;
|
|
|
int componentInfoIndex = (type - MOVE_X) * 3;
|
|
|
ImFormatString(tmps, sizeof(tmps), translationInfoMask[type - MOVE_X], deltaInfo[translationInfoIndex[componentInfoIndex]], deltaInfo[translationInfoIndex[componentInfoIndex + 1]], deltaInfo[translationInfoIndex[componentInfoIndex + 2]]);
|
|
|
drawList->AddText(ImVec2(destinationPosOnScreen.x + 15, destinationPosOnScreen.y + 15), 0xFF000000, tmps);
|
|
|
@@ -879,32 +897,32 @@ namespace ImGuizmo
|
|
|
|
|
|
static int GetScaleType()
|
|
|
{
|
|
|
- int type = NONE;
|
|
|
- /*
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
- vec_t deltaScreen(io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y);
|
|
|
- float dist = deltaScreen.Length();
|
|
|
- if (dist >= 0.058f * io.DisplaySize.x && dist < 0.062f * io.DisplaySize.x)
|
|
|
- type = ROTATE_SCREEN;
|
|
|
+ int type = NONE;
|
|
|
|
|
|
- const vec_t planNormals[] = { gContext.mModel.right, gContext.mModel.up, gContext.mModel.dir };
|
|
|
+ // screen
|
|
|
+ if (io.MousePos.x >= gContext.mScreenSquareMin.x && io.MousePos.x <= gContext.mScreenSquareMax.x &&
|
|
|
+ io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y)
|
|
|
+ type = SCALE_XYZ;
|
|
|
|
|
|
+ const vec_t direction[3] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir };
|
|
|
+ // compute
|
|
|
for (unsigned int i = 0; i < 3 && type == NONE; i++)
|
|
|
{
|
|
|
- // pickup plan
|
|
|
- vec_t pickupPlan = BuildPlan(gContext.mModel.position, planNormals[i]);
|
|
|
+ const int planNormal = (i + 2) % 3;
|
|
|
+ const int nextPlan = (i + 1) % 3;
|
|
|
|
|
|
- const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, pickupPlan);
|
|
|
- vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.position;
|
|
|
+ vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
|
|
|
+ const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(direction[i])) < angleLimit);
|
|
|
|
|
|
- if (Dot(Normalized(localPos), gContext.mRayVector) > FLT_EPSILON)
|
|
|
- continue;
|
|
|
+ const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.v.position, direction[planNormal]));
|
|
|
+ vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
|
|
|
- float distance = localPos.Length() / gContext.mScreenFactor;
|
|
|
- if (distance > 0.9f && distance < 1.1f)
|
|
|
- type = ROTATE_X + i;
|
|
|
+ const float dx = direction[i].Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
|
|
+ const float dy = direction[nextPlan].Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
|
|
+ if (belowAxisLimit && dy > -0.1f && dy < 0.1f && dx > 0.1f && dx < 1.f)
|
|
|
+ type = SCALE_X + i;
|
|
|
}
|
|
|
- */
|
|
|
return type;
|
|
|
}
|
|
|
|
|
|
@@ -913,20 +931,20 @@ namespace ImGuizmo
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
int type = NONE;
|
|
|
|
|
|
- vec_t deltaScreen = vect(io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y);
|
|
|
+ vec_t deltaScreen = { io.MousePos.x - gContext.mScreenSquareCenter.x, io.MousePos.y - gContext.mScreenSquareCenter.y, 0.0f, 0.0f };
|
|
|
float dist = deltaScreen.Length();
|
|
|
if (dist >= 0.058f * io.DisplaySize.x && dist < 0.062f * io.DisplaySize.x)
|
|
|
type = ROTATE_SCREEN;
|
|
|
|
|
|
- const vec_t planNormals[] = { gContext.mModel.right, gContext.mModel.up, gContext.mModel.dir};
|
|
|
+ const vec_t planNormals[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir};
|
|
|
|
|
|
for (unsigned int i = 0; i < 3 && type == NONE; i++)
|
|
|
{
|
|
|
// pickup plan
|
|
|
- vec_t pickupPlan = BuildPlan(gContext.mModel.position, planNormals[i]);
|
|
|
+ vec_t pickupPlan = BuildPlan(gContext.mModel.v.position, planNormals[i]);
|
|
|
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, pickupPlan);
|
|
|
- vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.position;
|
|
|
+ vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
|
|
|
|
|
|
if (Dot(Normalized(localPos), gContext.mRayVector) > FLT_EPSILON)
|
|
|
continue;
|
|
|
@@ -949,21 +967,23 @@ namespace ImGuizmo
|
|
|
io.MousePos.y >= gContext.mScreenSquareMin.y && io.MousePos.y <= gContext.mScreenSquareMax.y)
|
|
|
type = MOVE_SCREEN;
|
|
|
|
|
|
+ const vec_t direction[3] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir };
|
|
|
+
|
|
|
// compute
|
|
|
for (unsigned int i = 0; i < 3 && type == NONE; i++)
|
|
|
{
|
|
|
const int planNormal = (i + 2) % 3;
|
|
|
const int nextPlan = (i + 1) % 3;
|
|
|
|
|
|
- vec_t cameraEyeToGizmo = Normalized(gContext.mModel.position - gContext.mCameraEye);
|
|
|
+ vec_t cameraEyeToGizmo = Normalized(gContext.mModel.v.position - gContext.mCameraEye);
|
|
|
const bool belowAxisLimit = (fabsf(cameraEyeToGizmo.Dot3(direction[i])) < angleLimit);
|
|
|
const bool belowPlaneLimit = (fabsf(cameraEyeToGizmo.Dot3(direction[planNormal])) > planeLimit);
|
|
|
|
|
|
- const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.position, direction[planNormal]));
|
|
|
+ const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, BuildPlan(gContext.mModel.v.position, direction[planNormal]));
|
|
|
vec_t posOnPlan = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
|
|
|
- const float dx = direction[i].Dot3((posOnPlan - gContext.mModel.position) * (1.f / gContext.mScreenFactor));
|
|
|
- const float dy = direction[nextPlan].Dot3((posOnPlan - gContext.mModel.position) * (1.f / gContext.mScreenFactor));
|
|
|
+ const float dx = direction[i].Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
|
|
+ const float dy = direction[nextPlan].Dot3((posOnPlan - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor));
|
|
|
if (belowAxisLimit && dy > -0.1f && dy < 0.1f && dx > 0.1f && dx < 1.f)
|
|
|
type = MOVE_X + i;
|
|
|
|
|
|
@@ -971,7 +991,7 @@ namespace ImGuizmo
|
|
|
type = MOVE_XY + i;
|
|
|
|
|
|
if (gizmoHitProportion)
|
|
|
- *gizmoHitProportion = vect(dx, dy, 0.f);
|
|
|
+ *gizmoHitProportion = makeVect(dx, dy, 0.f);
|
|
|
}
|
|
|
return type;
|
|
|
}
|
|
|
@@ -986,13 +1006,13 @@ namespace ImGuizmo
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
|
|
|
- vec_t delta = newOrigin - gContext.mModel.position;
|
|
|
+ vec_t delta = newOrigin - gContext.mModel.v.position;
|
|
|
|
|
|
// 1 axis constraint
|
|
|
if (gContext.mCurrentOperation >= MOVE_X && gContext.mCurrentOperation <= MOVE_Z)
|
|
|
{
|
|
|
int axisIndex = gContext.mCurrentOperation - MOVE_X;
|
|
|
- const vec_t& axisValue = gContext.mModel.line[axisIndex];
|
|
|
+ const vec_t& axisValue = *(vec_t*)&gContext.mModel.m[axisIndex];
|
|
|
float lengthOnAxis = Dot(axisValue, delta);
|
|
|
delta = axisValue * lengthOnAxis;
|
|
|
}
|
|
|
@@ -1000,10 +1020,10 @@ namespace ImGuizmo
|
|
|
// compute matrix & delta
|
|
|
gContext.mTranslationPlanOrigin += delta;
|
|
|
matrix_t deltaMatrixTranslation;
|
|
|
- deltaMatrixTranslation.translation(delta);
|
|
|
+ deltaMatrixTranslation.Translation(delta);
|
|
|
if (deltaMatrix)
|
|
|
memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
|
|
|
- matrix_t res = *(matrix_t*)matrix * deltaMatrixTranslation;
|
|
|
+ matrix_t res = gContext.mModelSource * deltaMatrixTranslation;
|
|
|
*(matrix_t*)matrix = res;
|
|
|
|
|
|
if (!io.MouseDown[0])
|
|
|
@@ -1020,80 +1040,90 @@ namespace ImGuizmo
|
|
|
{
|
|
|
gContext.mbUsing = true;
|
|
|
gContext.mCurrentOperation = type;
|
|
|
- const vec_t movePlanNormal[] = { gContext.mModel.up, gContext.mModel.dir, gContext.mModel.right, gContext.mModel.dir, gContext.mModel.up, gContext.mModel.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.right, gContext.mModel.v.up, -gContext.mCameraDir };
|
|
|
// pickup plan
|
|
|
- gContext.mTranslationPlan = BuildPlan(gContext.mModel.position, movePlanNormal[type - MOVE_X]);
|
|
|
+ gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - MOVE_X]);
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
- gContext.mMatrixOrigin = gContext.mModel.position;
|
|
|
+ gContext.mMatrixOrigin = gContext.mModel.v.position;
|
|
|
|
|
|
- gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.position) * (1.f / gContext.mScreenFactor);
|
|
|
+ gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- static void HandleScale(float * /*matrix*/, float * /*deltaMatrix*/, int& type)
|
|
|
+ static void HandleScale(float *matrix, float *deltaMatrix, int& type)
|
|
|
{
|
|
|
ImGuiIO& io = ImGui::GetIO();
|
|
|
|
|
|
- // move
|
|
|
+ if (!gContext.mbUsing)
|
|
|
+ {
|
|
|
+ // find new possible way to scale
|
|
|
+ //vec_t gizmoHitProportion;
|
|
|
+ type = GetScaleType();
|
|
|
+ if (io.MouseDown[0] && type != NONE)
|
|
|
+ {
|
|
|
+ gContext.mbUsing = true;
|
|
|
+ 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 };
|
|
|
+ // pickup plan
|
|
|
+
|
|
|
+ gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, movePlanNormal[type - SCALE_X]);
|
|
|
+ const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
+ gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
+ gContext.mMatrixOrigin = gContext.mModel.v.position;
|
|
|
+ gContext.mScale.Set(1.f, 1.f, 1.f);
|
|
|
+ gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.v.position) * (1.f / gContext.mScreenFactor);
|
|
|
+ gContext.mScaleMousePos = io.MousePos;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // scale
|
|
|
if (gContext.mbUsing)
|
|
|
{
|
|
|
- /*
|
|
|
+ vec_t newScale = { 1.f, 1.f, 1.f, 0.0f };
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
vec_t newPos = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
vec_t newOrigin = newPos - gContext.mRelativeOrigin * gContext.mScreenFactor;
|
|
|
- vec_t delta = newOrigin - gContext.mModel.position;
|
|
|
+ vec_t delta = newOrigin - gContext.mModel.v.position;
|
|
|
+
|
|
|
// 1 axis constraint
|
|
|
- if (gContext.mCurrentOperation >= MOVE_X && gContext.mCurrentOperation <= MOVE_Z)
|
|
|
+ if (gContext.mCurrentOperation >= SCALE_X && gContext.mCurrentOperation <= SCALE_Z)
|
|
|
{
|
|
|
- int axisIndex = gContext.mCurrentOperation - MOVE_X;
|
|
|
- const vec_t& axisValue = gContext.mModel.line[axisIndex];
|
|
|
- float lengthOnAxis = Dot(axisValue, delta);
|
|
|
- delta = axisValue * lengthOnAxis;
|
|
|
+ int axisIndex = gContext.mCurrentOperation - SCALE_X;
|
|
|
+ const vec_t& axisValue = directionUnary[axisIndex];
|
|
|
+ float lengthOnAxis = 1.f - Dot(axisValue, delta) / gContext.mScreenFactor;
|
|
|
+
|
|
|
+ if (lengthOnAxis >= 0.f)
|
|
|
+ newScale[axisIndex] = lengthOnAxis;
|
|
|
+ else
|
|
|
+ newScale[axisIndex] = Clamp(lengthOnAxis, 0.001f, 1.f);
|
|
|
}
|
|
|
-
|
|
|
+ else
|
|
|
+ {
|
|
|
+ float newScaleUniform = 1.f + (io.MousePos.x - gContext.mScaleMousePos.x) * 0.01f;
|
|
|
+ newScale.Set(newScaleUniform, newScaleUniform, newScaleUniform, 0.f);
|
|
|
+ }
|
|
|
+
|
|
|
// compute matrix & delta
|
|
|
- gContext.mTranslationPlanOrigin += delta;
|
|
|
- matrix_t deltaMatrixTranslation;
|
|
|
- deltaMatrixTranslation.translation(delta);
|
|
|
+ matrix_t deltaMatrixScale;
|
|
|
+ deltaMatrixScale.Scale(makeVect(1.f, 1.f, 1.f) - (newScale - gContext.mScale));
|
|
|
+ gContext.mScale = newScale;
|
|
|
if (deltaMatrix)
|
|
|
- memcpy(deltaMatrix, deltaMatrixTranslation.m16, sizeof(float) * 16);
|
|
|
- matrix_t res = *(matrix_t*)matrix * deltaMatrixTranslation;
|
|
|
+ memcpy(deltaMatrix, deltaMatrixScale.m16, sizeof(float) * 16);
|
|
|
+ matrix_t res = deltaMatrixScale * gContext.mModelSource;
|
|
|
*(matrix_t*)matrix = res;
|
|
|
- */
|
|
|
+
|
|
|
if (!io.MouseDown[0])
|
|
|
gContext.mbUsing = false;
|
|
|
|
|
|
type = gContext.mCurrentOperation;
|
|
|
}
|
|
|
- else
|
|
|
- {
|
|
|
- // find new possible way to move
|
|
|
- vec_t gizmoHitProportion;
|
|
|
- type = GetMoveType(&gizmoHitProportion);
|
|
|
- if (io.MouseDown[0] && type != NONE)
|
|
|
- {
|
|
|
- gContext.mbUsing = true;
|
|
|
- gContext.mCurrentOperation = type;
|
|
|
- // pickup plan
|
|
|
- /*
|
|
|
- const vec_t movePlanNormal[] = { gContext.mModel.up, gContext.mModel.dir, gContext.mModel.right, gContext.mModel.dir, gContext.mModel.up, gContext.mModel.right, -gContext.mCameraDir };
|
|
|
- gContext.mTranslationPlan = BuildPlan(gContext.mModel.position, movePlanNormal[type - MOVE_X]);
|
|
|
- const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
- gContext.mTranslationPlanOrigin = gContext.mRayOrigin + gContext.mRayVector * len;
|
|
|
- gContext.mMatrixOrigin = gContext.mModel.position;
|
|
|
-
|
|
|
- gContext.mRelativeOrigin = (gContext.mTranslationPlanOrigin - gContext.mModel.position) * (1.f / gContext.mScreenFactor);
|
|
|
- */
|
|
|
- }
|
|
|
- }
|
|
|
}
|
|
|
|
|
|
static float ComputeAngleOnPlan()
|
|
|
{
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
- vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.position);
|
|
|
+ vec_t localPos = Normalized(gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position);
|
|
|
|
|
|
vec_t perpendicularVector;
|
|
|
perpendicularVector.Cross(gContext.mRotationVectorSource, gContext.mTranslationPlan);
|
|
|
@@ -1115,33 +1145,35 @@ namespace ImGuizmo
|
|
|
{
|
|
|
gContext.mbUsing = true;
|
|
|
gContext.mCurrentOperation = type;
|
|
|
- const vec_t rotatePlanNormal[] = { gContext.mModel.right, gContext.mModel.up, gContext.mModel.dir, -gContext.mCameraDir };
|
|
|
+ const vec_t rotatePlanNormal[] = { gContext.mModel.v.right, gContext.mModel.v.up, gContext.mModel.v.dir, -gContext.mCameraDir };
|
|
|
// pickup plan
|
|
|
- gContext.mTranslationPlan = BuildPlan(gContext.mModel.position, rotatePlanNormal[type - ROTATE_X]);
|
|
|
+ gContext.mTranslationPlan = BuildPlan(gContext.mModel.v.position, rotatePlanNormal[type - ROTATE_X]);
|
|
|
|
|
|
const float len = IntersectRayPlane(gContext.mRayOrigin, gContext.mRayVector, gContext.mTranslationPlan);
|
|
|
- vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.position;
|
|
|
+ vec_t localPos = gContext.mRayOrigin + gContext.mRayVector * len - gContext.mModel.v.position;
|
|
|
gContext.mRotationVectorSource = Normalized(localPos);
|
|
|
gContext.mRotationAngleOrigin = ComputeAngleOnPlan();
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // move
|
|
|
+ // rotation
|
|
|
if (gContext.mbUsing)
|
|
|
{
|
|
|
gContext.mRotationAngle = ComputeAngleOnPlan();
|
|
|
|
|
|
vec_t rotationAxisLocalSpace;
|
|
|
- rotationAxisLocalSpace.TransformVector(vect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
|
|
|
+ rotationAxisLocalSpace.TransformVector(makeVect(gContext.mTranslationPlan.x, gContext.mTranslationPlan.y, gContext.mTranslationPlan.z, 0.f), gContext.mModelInverse);
|
|
|
|
|
|
matrix_t deltaRotation;
|
|
|
deltaRotation.RotationAxis(rotationAxisLocalSpace, gContext.mRotationAngle - gContext.mRotationAngleOrigin);
|
|
|
gContext.mRotationAngleOrigin = gContext.mRotationAngle;
|
|
|
|
|
|
- *(matrix_t*)matrix = deltaRotation * gContext.mModel;
|
|
|
+ *(matrix_t*)matrix = deltaRotation * gContext.mModelSource;
|
|
|
|
|
|
if (deltaMatrix)
|
|
|
- *(matrix_t*)deltaMatrix = deltaRotation;
|
|
|
+ {
|
|
|
+ *(matrix_t*)deltaMatrix = gContext.mModelInverse * deltaRotation * gContext.mModel;
|
|
|
+ }
|
|
|
|
|
|
if (!io.MouseDown[0])
|
|
|
gContext.mbUsing = false;
|
|
|
@@ -1149,10 +1181,43 @@ namespace ImGuizmo
|
|
|
type = gContext.mCurrentOperation;
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- void Mogwai(const float *view, const float *projection, ImGuizmo::MODE mode, float *matrix, float *deltaMatrix)
|
|
|
+
|
|
|
+ void DecomposeMatrixToComponents(const float *matrix, float *translation, float *rotation, float *scale)
|
|
|
+ {
|
|
|
+ matrix_t& mat = *(matrix_t*)matrix;
|
|
|
+
|
|
|
+ rotation[0] = RAD2DEG * atan2f(mat.m[1][2], mat.m[2][2]);
|
|
|
+ rotation[1] = RAD2DEG * atan2f(-mat.m[0][2], sqrtf(mat.m[1][2] * mat.m[1][2] + mat.m[2][2]* mat.m[2][2]));
|
|
|
+ rotation[2] = RAD2DEG * atan2f(mat.m[0][1], mat.m[0][0]);
|
|
|
+
|
|
|
+ scale[0] = mat.v.right.Length();
|
|
|
+ scale[1] = mat.v.up.Length();
|
|
|
+ scale[2] = mat.v.dir.Length();
|
|
|
+
|
|
|
+ translation[0] = mat.v.position.x;
|
|
|
+ translation[1] = mat.v.position.y;
|
|
|
+ translation[2] = mat.v.position.z;
|
|
|
+ }
|
|
|
+
|
|
|
+ void RecomposeMatrixFromComponents(const float *translation, const float *rotation, const float *scale, float *matrix)
|
|
|
{
|
|
|
- ComputeContext(view, projection, matrix);
|
|
|
+ matrix_t& mat = *(matrix_t*)matrix;
|
|
|
+
|
|
|
+ matrix_t rot[3];
|
|
|
+ for (int i = 0; i < 3;i++)
|
|
|
+ rot[i].RotationAxis(directionUnary[i], rotation[i] * DEG2RAD);
|
|
|
+
|
|
|
+ mat = rot[0] * rot[1] * rot[2];
|
|
|
+
|
|
|
+ mat.v.right *= scale[0];
|
|
|
+ mat.v.up *= scale[1];
|
|
|
+ mat.v.dir *= scale[2];
|
|
|
+ mat.v.position.Set(translation[0], translation[1], translation[2], 1.f);
|
|
|
+ }
|
|
|
+
|
|
|
+ void Manipulate(const float *view, const float *projection, OPERATION operation, MODE mode, float *matrix, float *deltaMatrix)
|
|
|
+ {
|
|
|
+ ComputeContext(view, projection, matrix, mode);
|
|
|
|
|
|
// set delta to identity
|
|
|
if (deltaMatrix)
|
|
|
@@ -1161,7 +1226,7 @@ namespace ImGuizmo
|
|
|
int type = NONE;
|
|
|
if (gContext.mbEnable)
|
|
|
{
|
|
|
- switch (mode)
|
|
|
+ switch (operation)
|
|
|
{
|
|
|
case ROTATE:
|
|
|
HandleRotation(matrix, deltaMatrix, type);
|
|
|
@@ -1175,7 +1240,7 @@ namespace ImGuizmo
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- switch (mode)
|
|
|
+ switch (operation)
|
|
|
{
|
|
|
case ROTATE:
|
|
|
DrawRotationGizmo(type);
|
|
|
@@ -1188,4 +1253,41 @@ namespace ImGuizmo
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
-} // namespace ImGuizmo
|
|
|
+
|
|
|
+ void DrawCube(const float *view, const float *projection, float *matrix)
|
|
|
+ {
|
|
|
+ matrix_t viewInverse;
|
|
|
+ viewInverse.Inverse(*(matrix_t*)view);
|
|
|
+ const matrix_t& model = *(matrix_t*)matrix;
|
|
|
+ matrix_t res = *(matrix_t*)matrix * *(matrix_t*)view * *(matrix_t*)projection;
|
|
|
+
|
|
|
+ for (int iFace = 0; iFace < 6; iFace++)
|
|
|
+ {
|
|
|
+ const int normalIndex = (iFace % 3);
|
|
|
+ const int perpXIndex = (normalIndex + 1) % 3;
|
|
|
+ const int perpYIndex = (normalIndex + 2) % 3;
|
|
|
+ const float invert = (iFace > 2) ? -1.f : 1.f;
|
|
|
+
|
|
|
+ const vec_t faceCoords[4] = { directionUnary[normalIndex] + directionUnary[perpXIndex] + directionUnary[perpYIndex],
|
|
|
+ directionUnary[normalIndex] + directionUnary[perpXIndex] - directionUnary[perpYIndex],
|
|
|
+ directionUnary[normalIndex] - directionUnary[perpXIndex] - directionUnary[perpYIndex],
|
|
|
+ directionUnary[normalIndex] - directionUnary[perpXIndex] + directionUnary[perpYIndex],
|
|
|
+ };
|
|
|
+ ImVec2 faceCoordsScreen[4];
|
|
|
+ for (unsigned int iCoord = 0; iCoord < 4; iCoord++)
|
|
|
+ faceCoordsScreen[iCoord] = worldToPos(faceCoords[iCoord] * 0.5f * invert, res);
|
|
|
+
|
|
|
+ // back face culling
|
|
|
+ vec_t cullPos, cullNormal;
|
|
|
+ cullPos.TransformPoint(faceCoords[0] * 0.5f * invert, model);
|
|
|
+ cullNormal.TransformVector(directionUnary[normalIndex] * invert, model);
|
|
|
+ float dt = Dot(Normalized(cullPos - viewInverse.v.position), Normalized(cullNormal));
|
|
|
+ if (dt>0.f)
|
|
|
+ continue;
|
|
|
+
|
|
|
+ // draw face with lighter color
|
|
|
+ gContext.mDrawList->AddConvexPolyFilled(faceCoordsScreen, 4, directionColor[normalIndex] | 0x808080, true);
|
|
|
+ }
|
|
|
+ }
|
|
|
+};
|
|
|
+
|