You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
o3de/Code/Editor/Objects/TrackGizmo.cpp

264 lines
6.5 KiB
C++

/*
* Copyright (c) Contributors to the Open 3D Engine Project.
* For complete copyright and license terms please see the LICENSE at the root of this distribution.
*
* SPDX-License-Identifier: Apache-2.0 OR MIT
*
*/
#include "EditorDefs.h"
#include "TrackGizmo.h"
// Editor
#include "DisplayContext.h"
#include "TrackView/TrackViewAnimNode.h"
#include "AnimationContext.h"
#include "Maestro/Types/AnimParamType.h"
#include "Settings.h"
#include "Viewport.h"
#define TRACK_DRAW_Z_OFFSET (0.01f)
//////////////////////////////////////////////////////////////////////////
// CTrackGizmo implementation.
//////////////////////////////////////////////////////////////////////////
#define AXIS_SIZE 0.1f
#if 0
namespace {
int s_highlightAxis = 0;
}
#endif
//////////////////////////////////////////////////////////////////////////
CTrackGizmo::CTrackGizmo()
{
m_pAnimNode = nullptr;
m_worldBbox.min = Vec3(-10000, -10000, -10000);
m_worldBbox.max = Vec3(10000, 10000, 10000);
m_keysSelected = false;
}
//////////////////////////////////////////////////////////////////////////
CTrackGizmo::~CTrackGizmo()
{
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::SetMatrix(const Matrix34& tm)
{
CGizmo::SetMatrix(tm);
m_worldBbox.min = Vec3(-10000, -10000, -10000);
m_worldBbox.max = Vec3(10000, 10000, 10000);
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::Display(DisplayContext& dc)
{
if (!(dc.flags & DISPLAY_TRACKS))
{
return;
}
if (!m_pAnimNode)
{
return;
}
CAnimationContext* ac = GetIEditor()->GetAnimation();
// Should have animation sequence.
if (!ac->GetSequence())
{
return;
}
m_keysSelected = false;
// Must have non empty position track.
CTrackViewTrack* pTrack = m_pAnimNode->GetTrackForParameter(AnimParamType::Position);
if (!pTrack)
{
return;
}
int nkeys = pTrack->GetKeyCount();
if (nkeys < 2)
{
return;
}
Range range = ac->GetTimeRange();
//range.start = __min(range.end,track->GetKeyTime(0));
//range.end = __min(range.end,track->GetKeyTime(nkeys-1));
//float step = range.Length() / 100.0f;
//step = min(step,0.01f);
float step = 0.1f;
bool bTicks = (dc.flags & DISPLAY_TRACKTICKS) == DISPLAY_TRACKTICKS;
// Get Spline color.
ColorF splineCol(0.5f, 0.3f, 1, 1);
ColorF timeCol(0, 1, 0, 1);
m_worldBbox.Reset();
float zOffset = TRACK_DRAW_Z_OFFSET;
Vec3 p0(0, 0, 0), p1(0, 0, 0);
Vec3 tick(0, 0, 0.05f);
pTrack->GetValue(range.start, p0);
p0 = m_matrix * p0;
p0.z += zOffset;
// Update bounding box.
m_worldBbox.Add(p0);
for (float t = range.start + step; t < range.end; t += step)
{
p1 = Vec3(0, 0, 0);
pTrack->GetValue(t, p1);
p1 = m_matrix * p1;
p1.z += zOffset;
// Update bounding box.
m_worldBbox.Add(p1);
if (bTicks)
{
dc.DrawLine(p0 - tick, p0 + tick, timeCol, timeCol);
}
dc.DrawLine(p0, p1, splineCol, splineCol);
p0 = p1;
}
int nSubTracks = pTrack->GetChildCount();
if (nSubTracks > 0)
{
for (int i = 0; i < nSubTracks; i++)
{
DrawKeys(dc, pTrack, static_cast<CTrackViewTrack*>(pTrack->GetChild(i)));
}
}
else
{
DrawKeys(dc, pTrack, pTrack);
}
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::SetAnimNode(CTrackViewAnimNode* pNode)
{
m_pAnimNode = pNode;
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::GetWorldBounds(AABB& bbox)
{
bbox = m_worldBbox;
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::DrawAxis(DisplayContext& dc, const Vec3& org)
{
float size = AXIS_SIZE;
dc.DepthTestOff();
Vec3 x(size, 0, 0);
Vec3 y(0, size, 0);
Vec3 z(0, 0, size);
float fScreenScale = dc.view->GetScreenScaleFactor(org);
x = x * fScreenScale;
y = y * fScreenScale;
z = z * fScreenScale;
Vec3 colX(1, 0, 0), colY(0, 1, 0), colZ(0, 0, 1);
AZ_ErrorOnce(nullptr, false, "CTrackGizmo::DrawAxis needs to be removed/ported to use Atom");
#if 0
float col[4] = { 1, 1, 1, 1 };
dc.renderer->DrawLabelEx(org + x, 1.2f, col, true, true, "X");
dc.renderer->DrawLabelEx(org + y, 1.2f, col, true, true, "Y");
dc.renderer->DrawLabelEx(org + z, 1.2f, col, true, true, "Z");
if (s_highlightAxis)
{
float col2[4] = { 1, 0, 0, 1 };
if (s_highlightAxis == 1)
{
colX(1, 1, 0);
dc.renderer->DrawLabelEx(org + x, 1.2f, col2, true, true, "X");
}
if (s_highlightAxis == 2)
{
colY(1, 1, 0);
dc.renderer->DrawLabelEx(org + y, 1.2f, col2, true, true, "Y");
}
if (s_highlightAxis == 3)
{
colZ(1, 1, 0);
dc.renderer->DrawLabelEx(org + z, 1.2f, col2, true, true, "Z");
}
}
#endif
x = x * 0.8f;
y = y * 0.8f;
z = z * 0.8f;
float fArrowScale = fScreenScale * 0.07f;
dc.SetColor(colX);
dc.DrawArrow(org, org + x, fArrowScale);
dc.SetColor(colY);
dc.DrawArrow(org, org + y, fArrowScale);
dc.SetColor(colZ);
dc.DrawArrow(org, org + z, fArrowScale);
dc.DepthTestOn();
}
//////////////////////////////////////////////////////////////////////////
bool CTrackGizmo::HitTest([[maybe_unused]] HitContext& hc)
{
return false;
}
//////////////////////////////////////////////////////////////////////////
void CTrackGizmo::DrawKeys(DisplayContext& dc, CTrackViewTrack* pTrack, CTrackViewTrack* pKeysTrack)
{
// Get Key color.
dc.SetColor(1, 0, 0, 1);
float zOffset = TRACK_DRAW_Z_OFFSET;
int nkeys = pKeysTrack->GetKeyCount();
for (int i = 0; i < nkeys; i++)
{
const CTrackViewKeyHandle& keyHandle = pKeysTrack->GetKey(i);
const float t = keyHandle.GetTime();
Vec3 p0(0, 0, 0);
pTrack->GetValue(t, p0);
p0 = m_matrix * p0;
p0.z += zOffset;
//float sz = 0.01f * dc.view->GetScreenScaleFactor(p0);
float sz2 = 0.005f * dc.view->GetScreenScaleFactor(p0);
// Draw quad.
//dc.DrawBall( p0,sz );
dc.DrawWireBox(p0 - Vec3(sz2, sz2, sz2), p0 + Vec3(sz2, sz2, sz2));
if (keyHandle.IsSelected())
{
m_keysSelected = true;
DrawAxis(dc, p0);
dc.SetColor(1, 0, 0, 1);
}
}
}