You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
396 lines
12 KiB
396 lines
12 KiB
//========= Copyright © 1996-2005, Valve Corporation, All rights reserved. ============//
|
|
//
|
|
// Purpose:
|
|
//
|
|
// $NoKeywords: $
|
|
//=============================================================================//
|
|
|
|
#include "graphicgroup.h"
|
|
#include "gamegraphic.h"
|
|
#include "gameuidefinition.h"
|
|
#include "animdata.h"
|
|
|
|
// memdbgon must be the last include file in a .cpp file!!!
|
|
#include "tier0/memdbgon.h"
|
|
|
|
|
|
BEGIN_DMXELEMENT_UNPACK ( CGraphicGroup )
|
|
DMXELEMENT_UNPACK_FIELD_UTLSTRING( "name", "", m_pName )
|
|
DMXELEMENT_UNPACK_FIELD( "center", "0 0", Vector2D, m_Geometry.m_Center )
|
|
DMXELEMENT_UNPACK_FIELD( "scale", "1 1", Vector2D, m_Geometry.m_Scale )
|
|
DMXELEMENT_UNPACK_FIELD( "rotation", "0", float, m_Geometry.m_Rotation )
|
|
DMXELEMENT_UNPACK_FIELD( "maintainaspectratio", "0", bool, m_Geometry.m_bMaintainAspectRatio )
|
|
DMXELEMENT_UNPACK_FIELD( "sublayertype", "0", int, m_Geometry.m_Sublayer )
|
|
DMXELEMENT_UNPACK_FIELD( "visible", "1", bool, m_Geometry.m_bVisible )
|
|
DMXELEMENT_UNPACK_FIELD( "initialstate", "-1", int, m_CurrentState )
|
|
DMXELEMENT_UNPACK_FIELD( "horizgradient", "0", bool, m_Geometry.m_bHorizontalGradient )
|
|
DMXELEMENT_UNPACK_FIELD( "color", "255 255 255 255", Color, m_Geometry.m_Color )
|
|
DMXELEMENT_UNPACK_FIELD( "topcolor", "255 255 255 255", Color, m_Geometry.m_TopColor )
|
|
DMXELEMENT_UNPACK_FIELD( "bottomcolor", "255 255 255 255", Color, m_Geometry.m_BottomColor )
|
|
END_DMXELEMENT_UNPACK( CGraphicGroup, s_GraphicGroupUnpack )
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
CGraphicGroup::CGraphicGroup()
|
|
{
|
|
m_ResultantColor.r = 0;
|
|
m_ResultantColor.g = 0;
|
|
m_ResultantColor.b = 0;
|
|
m_ResultantColor.a = 0;
|
|
}
|
|
|
|
CGraphicGroup::~CGraphicGroup()
|
|
{
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Load data from file.
|
|
//-----------------------------------------------------------------------------
|
|
bool CGraphicGroup::Unserialize( CDmxElement *pElement, CUtlDict< CGameGraphic *, int > &unserializedGraphicMapping )
|
|
{
|
|
pElement->UnpackIntoStructure( this, s_GraphicGroupUnpack );
|
|
|
|
CDmxAttribute *pGroupElements = pElement->GetAttribute( "groupElements" );
|
|
if ( !pGroupElements || pGroupElements->GetType() != AT_ELEMENT_ARRAY )
|
|
{
|
|
return false;
|
|
}
|
|
const CUtlVector< CDmxElement * > &elements = pGroupElements->GetArray< CDmxElement * >( );
|
|
int nCount = elements.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
// Find the element in the map.
|
|
char pBuf[255];
|
|
UniqueIdToString( elements[i]->GetId(), pBuf, 255 );
|
|
int index = unserializedGraphicMapping.Find( pBuf );
|
|
Assert( unserializedGraphicMapping.IsValidIndex( index ) );
|
|
CGameGraphic *pGraphic = unserializedGraphicMapping.Element(index);
|
|
pGraphic->SetGroup( this );
|
|
m_MemberList.AddToTail( pGraphic );
|
|
}
|
|
|
|
|
|
// ANIMSTATES
|
|
CDmxAttribute *pImageAnims = pElement->GetAttribute( "imageanims" );
|
|
if ( !pImageAnims || pImageAnims->GetType() != AT_ELEMENT_ARRAY )
|
|
{
|
|
return false;
|
|
}
|
|
const CUtlVector< CDmxElement * > &imageanims = pImageAnims->GetArray< CDmxElement * >( );
|
|
nCount = imageanims.Count();
|
|
for ( int i = 0; i < nCount; ++i )
|
|
{
|
|
CAnimData *pAnimData = new CAnimData;
|
|
if ( !pAnimData->Unserialize( imageanims[i] ) )
|
|
{
|
|
delete pAnimData;
|
|
return false;
|
|
}
|
|
m_Anims.AddToTail( pAnimData );
|
|
}
|
|
|
|
char pBuf[255];
|
|
UniqueIdToString( pElement->GetId(), pBuf, 255 );
|
|
unserializedGraphicMapping.Insert( pBuf, this );
|
|
|
|
// Ok the initial state is 0, which is (usually ) default.
|
|
// default could be aliased to another state though so if it is fix the initial state here.
|
|
// default might also not be the state that is 0 so this sets the graphic's initial
|
|
// state to be the default one.
|
|
SetState( "default" );
|
|
|
|
return true;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::UpdateGeometry()
|
|
{
|
|
if ( m_CurrentState == -1 )
|
|
return;
|
|
|
|
DmeTime_t flAnimTime = GetAnimationTimePassed();
|
|
|
|
// Update color
|
|
m_Anims[ m_CurrentState ]->m_ColorAnim.GetValue( flAnimTime, &m_Geometry.m_Color );
|
|
|
|
// Update center location
|
|
m_Anims[ m_CurrentState ]->m_CenterPosAnim.GetValue( flAnimTime, &m_Geometry.m_Center );
|
|
|
|
// Update scale
|
|
m_Anims[ m_CurrentState ]->m_ScaleAnim.GetValue( flAnimTime, &m_Geometry.m_Scale );
|
|
|
|
// Update rotation
|
|
m_Anims[ m_CurrentState ]->m_RotationAnim.GetValue( flAnimTime, &m_Geometry.m_Rotation );
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); ++i )
|
|
{
|
|
m_MemberList[i]->UpdateGeometry();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Store the resultant color for groups so kids can just get that.
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::UpdateRenderData( color32 parentColor )
|
|
{
|
|
if ( !m_Geometry.m_bVisible )
|
|
return;
|
|
|
|
m_ResultantColor.r = (int)( (float)m_Geometry.m_Color.r * (float)(parentColor.r/255.0) );
|
|
m_ResultantColor.g = (int)( (float)m_Geometry.m_Color.g * (float)(parentColor.g/255.0) );
|
|
m_ResultantColor.b = (int)( (float)m_Geometry.m_Color.b * (float)(parentColor.b/255.0) );
|
|
m_ResultantColor.a = (int)( (float)m_Geometry.m_Color.a * (float)(parentColor.a/255.0) );
|
|
|
|
// Update any children that are groups
|
|
// Graphic members are not done because the colors are calculated when we get the render data out.
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
if ( m_MemberList[i]->IsGroup() )
|
|
{
|
|
CGraphicGroup *pGroup = (CGraphicGroup *)m_MemberList[i];
|
|
pGroup->UpdateRenderData( parentColor );
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Populate lists for rendering
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::UpdateRenderTransforms( const StageRenderInfo_t &stageRenderInfo )
|
|
{
|
|
m_Geometry.UpdateRenderTransforms( stageRenderInfo, GetGroup() );
|
|
|
|
|
|
// Create a matrix that ensures no aspect ratio changes.
|
|
// Update positions relative to the center, texture coords, and vertex colors
|
|
// If the group maintains aspect ratio it will already have handled this in its transform update.
|
|
Vector2D center;
|
|
// If this is the case we transform the center to screen coords first.
|
|
// Then take into account any size scaling in the scalemat
|
|
matrix3x4_t screenScalemat;
|
|
SetScaleMatrix( stageRenderInfo.parentScale.x, stageRenderInfo.parentScale.y, 1, screenScalemat );
|
|
Vector centerVec( m_Geometry.m_Center.x, m_Geometry.m_Center.y, 0 );
|
|
Vector centerInScreen;
|
|
VectorTransform( centerVec, screenScalemat, centerInScreen );
|
|
center.x = centerInScreen.x;
|
|
center.y = centerInScreen.y;
|
|
|
|
|
|
matrix3x4_t transmat;
|
|
Vector position( center.x, center.y, 0 );
|
|
SetIdentityMatrix( transmat );
|
|
PositionMatrix( position, transmat );
|
|
|
|
matrix3x4_t scalemat;
|
|
SetScaleMatrix( m_Geometry.m_Scale.x, m_Geometry.m_Scale.y, 1, scalemat );
|
|
|
|
matrix3x4_t rotmat;
|
|
Vector axis( 0, 0, 1 );
|
|
MatrixBuildRotationAboutAxis( axis, m_Geometry.m_Rotation, rotmat );
|
|
|
|
matrix3x4_t temp;
|
|
MatrixMultiply( rotmat, scalemat, temp );
|
|
matrix3x4_t rawToLocal;
|
|
MatrixMultiply( transmat, temp, rawToLocal );
|
|
|
|
matrix3x4_t groupToScreen;
|
|
// Use the matrix that doesn't contain any scale changes if we should
|
|
m_pGroup->GetRenderTransform( groupToScreen, true );
|
|
MatrixMultiply( groupToScreen, rawToLocal, m_RelToScreenHoldAspectRatio );
|
|
|
|
|
|
|
|
|
|
// Update all children
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
m_MemberList[i]->UpdateRenderTransforms( stageRenderInfo );
|
|
}
|
|
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::AddToGroup( CGameGraphic *pGraphic )
|
|
{
|
|
m_MemberList.AddToTail( pGraphic );
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::RemoveFromGroup( CGameGraphic *pGraphic )
|
|
{
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
// TODO, what if the graphic is a group?
|
|
if ( m_MemberList[i] == pGraphic )
|
|
{
|
|
m_MemberList.Remove( i );
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Returns true if any graphic in this group has the state.
|
|
//-----------------------------------------------------------------------------
|
|
bool CGraphicGroup::HasState( const char *pStateName )
|
|
{
|
|
if ( CGameGraphic::HasState( pStateName ) )
|
|
return true;
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
if ( m_MemberList[i]->HasState( pStateName ) )
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Set the state of all members to this state
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::SetState( const char *pStateName )
|
|
{
|
|
CGameGraphic::SetState( pStateName );
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
m_MemberList[i]->SetState( pStateName );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Start playing animations
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::StartPlaying()
|
|
{
|
|
CGameGraphic::StartPlaying();
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
m_MemberList[i]->StartPlaying();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Stop playing animations
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::StopPlaying()
|
|
{
|
|
CGameGraphic::StopPlaying();
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
m_MemberList[i]->StopPlaying();
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Move all members to the next available state
|
|
// Note this could put all of them into different states
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::AdvanceState()
|
|
{
|
|
CGameGraphic::AdvanceState();
|
|
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
m_MemberList[i]->AdvanceState();
|
|
}
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Return the first member of this group that can have keyfocus.
|
|
//-----------------------------------------------------------------------------
|
|
CHitArea *CGraphicGroup::GetKeyFocusRequestGraphic()
|
|
{
|
|
for ( int i = 0; i < m_MemberList.Count(); i++ )
|
|
{
|
|
if ( m_MemberList[i]->CanAcceptInput() )
|
|
{
|
|
return ( CHitArea * )m_MemberList[i];
|
|
}
|
|
}
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Does this graphic own a graphic with this name?
|
|
//-----------------------------------------------------------------------------
|
|
CGameGraphic *CGraphicGroup::FindGraphicByName( const char *pName ) const
|
|
{
|
|
int nGraphicCount = m_MemberList.Count();
|
|
for ( int i = 0; i < nGraphicCount; ++i )
|
|
{
|
|
CGameGraphic *pMember = m_MemberList[i];
|
|
if ( pMember->IsGraphicNamed( pName ) )
|
|
{
|
|
// Match.
|
|
return pMember;
|
|
}
|
|
}
|
|
|
|
return NULL;
|
|
}
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Group visibility affects all children.
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::SetVisible( bool bVisible )
|
|
{
|
|
CGameGraphic::SetVisible( bVisible );
|
|
|
|
int nGraphicCount = m_MemberList.Count();
|
|
for ( int i = 0; i < nGraphicCount; ++i )
|
|
{
|
|
CGameGraphic *pMember = m_MemberList[i];
|
|
pMember->SetVisible( bVisible );
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Return the appropriate render transform.
|
|
// m_RelToScreenHoldAspectRatio is calculated for a stage aspect ratio that has not changed.
|
|
//-----------------------------------------------------------------------------
|
|
void CGraphicGroup::GetRenderTransform( matrix3x4_t &relToScreen, bool bMaintainAspectRatio ) const
|
|
{
|
|
if ( bMaintainAspectRatio )
|
|
{
|
|
relToScreen = m_RelToScreenHoldAspectRatio;
|
|
}
|
|
else
|
|
{
|
|
relToScreen = m_Geometry.m_RenderToScreen;
|
|
}
|
|
}
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// If any parent of this group should maintain aspect ratio, this group should.
|
|
//-----------------------------------------------------------------------------
|
|
bool CGraphicGroup::MaintainAspectRatio() const
|
|
{
|
|
if ( m_pGroup && !m_Geometry.m_bMaintainAspectRatio )
|
|
{
|
|
return m_pGroup->MaintainAspectRatio();
|
|
}
|
|
|
|
return m_Geometry.m_bMaintainAspectRatio;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|