//========= Copyright © 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 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 ); }