csgo-2018-source/hammer/gizmo.cpp

356 lines
12 KiB
C++
Raw Normal View History

2021-07-25 12:11:47 +08:00
//========= Copyright <20> 1996-2005, Valve Corporation, All rights reserved. ============//
//
// Purpose:
//
// $NoKeywords: $
//=============================================================================//
#include "stdafx.h"
#include "BoundBox.h"
#include "Gizmo.h"
#include "Render3D.h"
#include "Resource.h"
#include "materialsystem/IMesh.h"
#include "TextureSystem.h"
#include "camera.h"
// memdbgon must be the last include file in a .cpp file!!!
#include <tier0/memdbgon.h>
static IEditorTexture* g_pAxisTexture = 0;
static IEditorTexture* g_pRotateHandleTexture = 0;
static IEditorTexture* g_pScaleHandleTexture = 0;
static IEditorTexture* g_pTranslateHandleTexture = 0;
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
CGizmo::CGizmo(void)
{
static bool bFirst = true;
if (bFirst)
{
g_pAxisTexture = g_Textures.FindActiveTexture("editor/gizmoAxis");
g_pRotateHandleTexture = g_Textures.FindActiveTexture("editor/gizmoRotateHandle");
g_pScaleHandleTexture = g_Textures.FindActiveTexture("editor/gizmoScaleHandle");
g_pTranslateHandleTexture = g_Textures.FindActiveTexture("editor/gizmoTranslateHandle");
bFirst = false;
}
Initialize();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : x -
// y -
// z -
//-----------------------------------------------------------------------------
CGizmo::CGizmo(float x, float y, float z)
{
Initialize();
m_Position[0] = x;
m_Position[1] = y;
m_Position[2] = z;
}
//-----------------------------------------------------------------------------
// Purpose:
//-----------------------------------------------------------------------------
void CGizmo::Initialize(void)
{
m_Position[0] = m_Position[1] = m_Position[2] = 0;
m_fAxisLength = 100;
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : ViewPoint -
// Origin -
// EndPoint -
// red -
// green -
// blue -
// Output :
//-----------------------------------------------------------------------------
#define GIZMO_AXIS_WIDTH 2
#define GIZMO_HANDLE_WIDTH 4
void CGizmo::DrawGizmoAxis(CRender3D *pRender, Vector& Origin,
Vector& EndPoint, int red, int green, int blue,
unsigned int uAxisHandle)
{
CCamera *pCamera = pRender->GetCamera();
Vector ViewUp;
pCamera->GetViewUp(ViewUp);
Vector ViewPoint;
Vector ViewForward;
pCamera->GetViewPoint(ViewPoint);
VectorSubtract(Origin, ViewPoint, ViewForward);
Vector Axis;
VectorSubtract(EndPoint, Origin, Axis);
CrossProduct(ViewForward, Axis, ViewUp);
VectorNormalize(ViewUp);
Vector Start;
Vector End;
//
// Draw the first segment of the gizmo axis.
//
VectorMA(Origin, 0.1, Axis, Start);
VectorMA(Origin, 0.25, Axis, End);
pRender->BindTexture( g_pAxisTexture );
CMeshBuilder meshBuilder;
CMatRenderContextPtr pRenderContext( MaterialSystemInterface() );
IMesh* pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_POLYGON, 4 );
meshBuilder.TexCoord2f(0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f(0, 2, 0);
meshBuilder.Position3f(End[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f(0, 2, 1);
meshBuilder.Position3f(End[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f(0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
//
// Draw the scale handle.
//
Start = End;
VectorMA(Origin, 0.35, Axis, End);
pRender->BeginRenderHitTarget(this, uAxisHandle + GIZMO_HANDLE_SCALE);
pRender->BindTexture( g_pScaleHandleTexture );
pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_POLYGON, 4 );
meshBuilder.TexCoord2f( 0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] - ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] - ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 1, 0);
meshBuilder.Position3f(End[0] - ViewUp[0] * GIZMO_HANDLE_WIDTH, End[1] - ViewUp[1] * GIZMO_HANDLE_WIDTH, End[2] - ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 1, 1);
meshBuilder.Position3f(End[0] + ViewUp[0] * GIZMO_HANDLE_WIDTH, End[1] + ViewUp[1] * GIZMO_HANDLE_WIDTH, End[2] + ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] + ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] + ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
pRender->EndRenderHitTarget();
//
// Draw the second segment of the gizmo axis.
//
Start = End;
VectorMA(Origin, 0.5, Axis, End);
pRender->BindTexture( g_pAxisTexture );
pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_POLYGON, 4 );
meshBuilder.TexCoord2f( 0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 2, 0);
meshBuilder.Position3f(End[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.AdvanceVertex();
meshBuilder.Color3ub(red, green, blue);
meshBuilder.TexCoord2f( 0, 2, 1);
meshBuilder.Position3f(End[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
//
// Draw the rotate handle.
//
Start = End;
VectorMA(Origin, 0.6, Axis, End);
pRender->BeginRenderHitTarget(this, uAxisHandle + GIZMO_HANDLE_ROTATE);
pRender->BindTexture( g_pRotateHandleTexture );
pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_POLYGON, 4 );
meshBuilder.TexCoord2f( 0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] - ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] - ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 1, 0);
meshBuilder.Position3f(End[0] - ViewUp[0] * GIZMO_HANDLE_WIDTH, End[1] - ViewUp[1] * GIZMO_HANDLE_WIDTH, End[2] - ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 1, 1);
meshBuilder.Position3f(End[0] + ViewUp[0] * GIZMO_HANDLE_WIDTH, End[1] + ViewUp[1] * GIZMO_HANDLE_WIDTH, End[2] + ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] + ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] + ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
pRender->EndRenderHitTarget();
//
// Draw the third segment of the gizmo axis.
//
Start = End;
VectorMA(Origin, 0.75, Axis, End);
pRender->BindTexture( g_pAxisTexture );
pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_POLYGON, 4 );
meshBuilder.TexCoord2f( 0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 2, 0);
meshBuilder.Position3f(End[0] - ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] - ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] - ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 2, 1);
meshBuilder.Position3f(End[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, End[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, End[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_AXIS_WIDTH, Start[1] + ViewUp[1] * GIZMO_AXIS_WIDTH, Start[2] + ViewUp[2] * GIZMO_AXIS_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
//
// Draw the translate handle (arrowhead).
//
Start = End;
pRender->BeginRenderHitTarget(this, uAxisHandle + GIZMO_HANDLE_TRANSLATE);
pRender->BindTexture( g_pTranslateHandleTexture );
pMesh = pRenderContext->GetDynamicMesh( );
meshBuilder.Begin( pMesh, MATERIAL_TRIANGLES, 1 );
meshBuilder.TexCoord2f( 0, 0, 0);
meshBuilder.Position3f(Start[0] - ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] - ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] - ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 1, 0.5);
meshBuilder.Position3f(EndPoint[0], EndPoint[1], EndPoint[2]);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.TexCoord2f( 0, 0, 1);
meshBuilder.Position3f(Start[0] + ViewUp[0] * GIZMO_HANDLE_WIDTH, Start[1] + ViewUp[1] * GIZMO_HANDLE_WIDTH, Start[2] + ViewUp[2] * GIZMO_HANDLE_WIDTH);
meshBuilder.Color3ub(red, green, blue);
meshBuilder.AdvanceVertex();
meshBuilder.End();
pMesh->Draw();
pRender->EndRenderHitTarget();
}
//-----------------------------------------------------------------------------
// Purpose:
// Input : *pRender -
//-----------------------------------------------------------------------------
void CGizmo::Render(CRender3D *pRender)
{
Vector XAxis( m_Position[0] + m_fAxisLength, m_Position[1], m_Position[2] );
Vector YAxis( m_Position[0], m_Position[1] + m_fAxisLength, m_Position[2] );
Vector ZAxis( m_Position[0], m_Position[1], m_Position[2] + m_fAxisLength );
static BoundBox UniformScaleBox;
Vector Mins;
Vector Maxs;
Mins[0] = m_Position[0] - m_fAxisLength * 0.1;
Mins[1] = m_Position[1] - m_fAxisLength * 0.1;
Mins[2] = m_Position[2] - m_fAxisLength * 0.1;
Maxs[0] = m_Position[0] + m_fAxisLength * 0.1;
Maxs[1] = m_Position[1] + m_fAxisLength * 0.1;
Maxs[2] = m_Position[2] + m_fAxisLength * 0.1;
UniformScaleBox.ResetBounds();
UniformScaleBox.UpdateBounds(Mins, Maxs);
pRender->BeginRenderHitTarget(this, GIZMO_HANDLE_UNIFORM_SCALE);
//pRender->RenderBox(Mins, Maxs, BoxType_Solid, 200, 200, 200);
pRender->EndRenderHitTarget();
pRender->SetRenderMode( RENDER_MODE_TEXTURED );
DrawGizmoAxis(pRender, m_Position, XAxis, 255, 0, 0, GIZMO_AXIS_X);
DrawGizmoAxis(pRender, m_Position, YAxis, 0, 255, 0, GIZMO_AXIS_Y);
DrawGizmoAxis(pRender, m_Position, ZAxis, 0, 0, 255, GIZMO_AXIS_Z);
pRender->SetRenderMode( RENDER_MODE_DEFAULT );
}