Skip to content

Commit

Permalink
#123 Add render gizmo function (translate, rotate, scale)
Browse files Browse the repository at this point in the history
  • Loading branch information
ducphamhong committed May 19, 2021
1 parent 1a748e5 commit e6f3958
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 110 deletions.
4 changes: 2 additions & 2 deletions Projects/Editor/Source/Editor/Space/Scene/CSpaceScene.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,8 +109,8 @@ namespace Skylicht
camObj->addComponent<CEditorCamera>()->setMoveSpeed(2.0f);

m_editorCamera = camObj->getComponent<CCamera>();
m_editorCamera->setPosition(core::vector3df(0.0f, 1.5f, 0.0f));
m_editorCamera->lookAt(core::vector3df(0.0f, 0.0f, 4.0f), core::vector3df(0.0f, 1.0f, 0.0f));
m_editorCamera->setPosition(core::vector3df(-2.0f, 1.5f, -2.0f));
m_editorCamera->lookAt(core::vector3df(0.0f, 0.0f, 0.0f), core::vector3df(0.0f, 1.0f, 0.0f));

// grid
m_gridPlane = zone->createEmptyObject();
Expand Down
245 changes: 158 additions & 87 deletions Projects/Editor/Source/EditorComponents/Handles/CHandlesRenderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,111 +96,182 @@ namespace Skylicht
core::vector3df cameraRight(invView[0], invView[1], invView[2]);
core::vector3df cameraLook(invView[8], invView[9], invView[10]);
core::vector3df cameraUp(invView[4], invView[5], invView[6]);
core::vector3df cameraPos = entityManager->getCamera()->getGameObject()->getPosition();

cameraRight.normalize();
cameraLook.normalize();
cameraUp.normalize();

m_screenFactor = 0.2f / getSegmentLengthClipSpace(core::vector3df(), cameraRight, entityManager->getCamera());
CCamera* camera = entityManager->getCamera();

m_screenFactor = 0.2f / getSegmentLengthClipSpace(core::vector3df(), cameraRight, camera);

// Draw position axis
CHandles* handles = CHandles::getInstance();
if (handles->isHandlePosition())
{
const core::vector3df& pos = handles->getHandlePosition();

float quadMin = 0.1f;
float quadMax = 0.4f;
drawTranslateGizmo(pos, cameraLook, camera);
//drawRotationGizmo(pos, cameraPos);
//drawScaleGizmo(pos, cameraLook, cameraUp, camera);
}

((CLineDrawData*)m_data)->updateBuffer();
((CPolygonDrawData*)m_data)->updateBuffer();
}

void CHandlesRenderer::drawRotationGizmo(const core::vector3df& pos, const core::vector3df& cameraPos)
{
core::vector3df cameraToObject = pos - cameraPos;
cameraToObject.normalize();

const int halfCircleSegmentCount = 64;
const int circleMul = 1;

core::vector3df quad[4] = {
core::vector3df(quadMin, quadMin, 0.0f),
core::vector3df(quadMin, quadMax, 0.0f),
core::vector3df(quadMax, quadMax, 0.0f),
core::vector3df(quadMax, quadMin, 0.0f),
};
core::vector3df* circlePos = new core::vector3df[circleMul * halfCircleSegmentCount + 1];

for (int i = 0; i < 3; i++)
for (int axis = 0; axis < 3; axis++)
{
// draw rotation
float* p = &cameraToObject.X;
float angleStart = atan2f(p[(4 - axis) % 3], p[(3 - axis) % 3]) + core::PI * 0.5f;

for (unsigned int i = 0; i < circleMul * halfCircleSegmentCount + 1; i++)
{
core::vector3df dirAxis, dirPlaneX, dirPlaneY;
bool belowAxisLimit, belowPlaneLimit;

computeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, entityManager->getCamera());

if (belowAxisLimit)
{
// draw axis
m_data->addLineVertexBatch(pos, pos + dirAxis * m_screenFactor, m_directionColor[i]);

// draw arrow
float arrowSize1 = m_screenFactor * 0.1f;
float arrowSize2 = m_screenFactor * 0.05f;

core::vector3df side = dirAxis.crossProduct(cameraLook);
side.normalize();

core::vector3df a = pos + dirAxis * m_screenFactor;
core::vector3df m = a - dirAxis * arrowSize1;
core::vector3df b = m + side * arrowSize2;
core::vector3df c = m - side * arrowSize2;
m_data->addTriangleFill(a, b, c, m_directionColor[i]);

// draw quad
/*
float arrowSize1 = m_screenFactor * 0.1f;
float arrowSize2 = m_screenFactor * 0.05f;
core::vector3df a = pos + dirAxis * m_screenFactor;
core::vector3df sideQuad = side * arrowSize2;
core::vector3df upQuad = cameraUp * arrowSize2;
core::vector3df v1, v2, v3, v4;
v1.set(
a.X - sideQuad.X + upQuad.X,
a.Y - sideQuad.Y + upQuad.Y,
a.Z - sideQuad.Z + upQuad.Z
);
v2.set(
a.X + sideQuad.X + upQuad.X,
a.Y + sideQuad.Y + upQuad.Y,
a.Z + sideQuad.Z + upQuad.Z
);
v3.set(
a.X + sideQuad.X - upQuad.X,
a.Y + sideQuad.Y - upQuad.Y,
a.Z + sideQuad.Z - upQuad.Z
);
v4.set(
a.X - sideQuad.X - upQuad.X,
a.Y - sideQuad.Y - upQuad.Y,
a.Z - sideQuad.Z - upQuad.Z
);
core::vector3df arrow[] = { v1, v2, v3, v4 };
m_data->addPolygonFill(arrow, 4, m_directionColor[i]);
*/
}

if (belowPlaneLimit)
{
// draw plane
core::vector3df planeLine[4];
for (int j = 0; j < 4; j++)
planeLine[j] = (dirPlaneX * quad[j].X + dirPlaneY * quad[j].Y) * m_screenFactor;

m_data->addLineVertexBatch(planeLine[0], planeLine[1], m_directionColor[i]);
m_data->addLineVertexBatch(planeLine[1], planeLine[2], m_directionColor[i]);
m_data->addLineVertexBatch(planeLine[2], planeLine[3], m_directionColor[i]);
m_data->addLineVertexBatch(planeLine[3], planeLine[0], m_directionColor[i]);

SColor fillColor = m_directionColor[i];
fillColor.setAlpha(50);
m_data->addPolygonFill(planeLine, 4, fillColor);
}
float ng = angleStart + core::PI * ((float)i / (float)halfCircleSegmentCount);

core::vector3df axisPos = core::vector3df(cosf(ng), sinf(ng), 0.f);
p = &axisPos.X;

circlePos[i] = core::vector3df(p[axis], p[(axis + 1) % 3], p[(axis + 2) % 3]) * m_screenFactor;
}

// draw circle
m_data->addPolyline(circlePos, circleMul * halfCircleSegmentCount, false, m_directionColor[axis]);
}

((CLineDrawData*)m_data)->updateBuffer();
((CPolygonDrawData*)m_data)->updateBuffer();
delete[]circlePos;
}

void CHandlesRenderer::drawScaleGizmo(const core::vector3df& pos, const core::vector3df& cameraLook, const core::vector3df& cameraUp, CCamera* camera)
{
float quadMin = 0.1f;
float quadMax = 0.4f;

core::vector3df quad[4] = {
core::vector3df(quadMin, quadMin, 0.0f),
core::vector3df(quadMin, quadMax, 0.0f),
core::vector3df(quadMax, quadMax, 0.0f),
core::vector3df(quadMax, quadMin, 0.0f),
};

for (int i = 0; i < 3; i++)
{
core::vector3df dirAxis, dirPlaneX, dirPlaneY;
bool belowAxisLimit, belowPlaneLimit;

computeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, camera);

if (belowAxisLimit)
{
// draw axis
m_data->addLine(pos, pos + dirAxis * m_screenFactor, m_directionColor[i]);

// draw quad
float arrowSize1 = m_screenFactor * 0.1f;
float arrowSize2 = m_screenFactor * 0.05f;

core::vector3df side = cameraUp.crossProduct(cameraLook);
side.normalize();

core::vector3df a = pos + dirAxis * m_screenFactor;

core::vector3df sideQuad = side * arrowSize2;
core::vector3df upQuad = cameraUp * arrowSize2;

core::vector3df v1, v2, v3, v4;
v1.set(
a.X - sideQuad.X + upQuad.X,
a.Y - sideQuad.Y + upQuad.Y,
a.Z - sideQuad.Z + upQuad.Z
);
v2.set(
a.X + sideQuad.X + upQuad.X,
a.Y + sideQuad.Y + upQuad.Y,
a.Z + sideQuad.Z + upQuad.Z
);
v3.set(
a.X + sideQuad.X - upQuad.X,
a.Y + sideQuad.Y - upQuad.Y,
a.Z + sideQuad.Z - upQuad.Z
);
v4.set(
a.X - sideQuad.X - upQuad.X,
a.Y - sideQuad.Y - upQuad.Y,
a.Z - sideQuad.Z - upQuad.Z
);
core::vector3df arrow[] = { v1, v2, v3, v4 };
m_data->addPolygonFill(arrow, 4, m_directionColor[i]);
}
}
}

void CHandlesRenderer::drawTranslateGizmo(const core::vector3df& pos, const core::vector3df& cameraLook, CCamera* camera)
{
float quadMin = 0.1f;
float quadMax = 0.4f;

core::vector3df quad[4] = {
core::vector3df(quadMin, quadMin, 0.0f),
core::vector3df(quadMin, quadMax, 0.0f),
core::vector3df(quadMax, quadMax, 0.0f),
core::vector3df(quadMax, quadMin, 0.0f),
};

for (int i = 0; i < 3; i++)
{
core::vector3df dirAxis, dirPlaneX, dirPlaneY;
bool belowAxisLimit, belowPlaneLimit;

computeTripodAxisAndVisibility(i, dirAxis, dirPlaneX, dirPlaneY, belowAxisLimit, belowPlaneLimit, camera);

if (belowAxisLimit)
{
// draw axis
m_data->addLine(pos, pos + dirAxis * m_screenFactor, m_directionColor[i]);

// draw arrow
float arrowSize1 = m_screenFactor * 0.1f;
float arrowSize2 = m_screenFactor * 0.05f;

core::vector3df side = dirAxis.crossProduct(cameraLook);
side.normalize();

core::vector3df a = pos + dirAxis * m_screenFactor;
core::vector3df m = a - dirAxis * arrowSize1;
core::vector3df b = m + side * arrowSize2;
core::vector3df c = m - side * arrowSize2;
m_data->addTriangleFill(a, b, c, m_directionColor[i]);
}

if (belowPlaneLimit)
{
// draw plane
core::vector3df planeLine[4];
for (int j = 0; j < 4; j++)
planeLine[j] = (dirPlaneX * quad[j].X + dirPlaneY * quad[j].Y) * m_screenFactor;

m_data->addLine(planeLine[0], planeLine[1], m_directionColor[i]);
m_data->addLine(planeLine[1], planeLine[2], m_directionColor[i]);
m_data->addLine(planeLine[2], planeLine[3], m_directionColor[i]);
m_data->addLine(planeLine[3], planeLine[0], m_directionColor[i]);

SColor fillColor = m_directionColor[i];
fillColor.setAlpha(50);
m_data->addPolygonFill(planeLine, 4, fillColor);
}
}
}

// References: https://github.com/CedricGuillemet/ImGuizmo/blob/master/ImGuizmo.cpp
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,12 @@ namespace Skylicht

protected:

void drawRotationGizmo(const core::vector3df& pos, const core::vector3df& cameraPos);

void drawScaleGizmo(const core::vector3df& pos, const core::vector3df& cameraLook, const core::vector3df& cameraUp, CCamera* camera);

void drawTranslateGizmo(const core::vector3df& pos, const core::vector3df& cameraLook, CCamera* camera);

float getSegmentLengthClipSpace(const core::vector3df& start, const core::vector3df& end, CCamera* camera);

float getParallelogram(const core::vector3df& ptO, const core::vector3df& ptA, const core::vector3df& ptB, CCamera* camera);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,9 +79,9 @@ namespace Skylicht
core::vector3df zero(0.0f, 0.0f, 0.0f);

float s = 0.8f;
addLineVertexBatch(zero, Position[0] * s, red);
addLineVertexBatch(zero, Position[2] * s, blue);
addLineVertexBatch(zero, Position[4] * s, green);
addLine(zero, Position[0] * s, red);
addLine(zero, Position[2] * s, blue);
addLine(zero, Position[4] * s, green);
}

CViewpointData::~CViewpointData()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ namespace Skylicht
else
color = grey;

addLineVertexBatch(start, end, color);
addLine(start, end, color);

start.Z += GridSize;
end.Z += GridSize;
Expand All @@ -81,7 +81,7 @@ namespace Skylicht
else
color = grey;

addLineVertexBatch(start, end, color);
addLine(start, end, color);

start.X += GridSize;
end.X += GridSize;
Expand Down
Loading

0 comments on commit e6f3958

Please sign in to comment.