diff options
Diffstat (limited to 'tools/foundry/DmeVMFEntity.cpp')
| -rw-r--r-- | tools/foundry/DmeVMFEntity.cpp | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/tools/foundry/DmeVMFEntity.cpp b/tools/foundry/DmeVMFEntity.cpp new file mode 100644 index 0000000..29446ae --- /dev/null +++ b/tools/foundry/DmeVMFEntity.cpp @@ -0,0 +1,246 @@ +//========= Copyright Valve Corporation, All rights reserved. ============// +// +// Purpose: +// +//============================================================================= + +#include "DmeVMFEntity.h" +#include "datamodel/dmelementfactoryhelper.h" +#include "toolframework/itoolentity.h" +#include "materialsystem/imesh.h" +#include "materialsystem/imaterial.h" +#include "materialsystem/imaterialsystem.h" +#include "engine/iclientleafsystem.h" +#include "toolutils/enginetools_int.h" +#include "foundrytool.h" + +// memdbgon must be the last include file in a .cpp file!!! +#include "tier0/memdbgon.h" + + +#define SPHERE_RADIUS 16 + +//----------------------------------------------------------------------------- +// Expose this class to the scene database +//----------------------------------------------------------------------------- +IMPLEMENT_ELEMENT_FACTORY( DmeVMFEntity, CDmeVMFEntity ); + + +//----------------------------------------------------------------------------- +// Purpose: +//----------------------------------------------------------------------------- +void CDmeVMFEntity::OnConstruction() +{ + m_ClassName.Init( this, "classname" ); + m_TargetName.Init( this, "targetname" ); + m_bIsPlaceholder.InitAndSet( this, "_placeholder", false, FATTRIB_DONTSAVE ); + m_vecLocalOrigin.Init( this, "origin" ); + m_vecLocalAngles.Init( this, "angles" ); + + // Used to make sure these aren't saved if they aren't changed + m_TargetName.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + m_vecLocalAngles.GetAttribute()->AddFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + + m_hEngineEntity = HTOOLHANDLE_INVALID; + + m_Wireframe.Init( "debug/debugwireframe", "editor" ); +} + +void CDmeVMFEntity::OnDestruction() +{ + // Unhook it from the engine + AttachToEngineEntity( false ); + m_Wireframe.Shutdown(); +} + + +//----------------------------------------------------------------------------- +// Called whem attributes change +//----------------------------------------------------------------------------- +void CDmeVMFEntity::OnAttributeChanged( CDmAttribute *pAttribute ) +{ + BaseClass::OnAttributeChanged( pAttribute ); + + // Once these have changed, then save them out, and don't bother calling back + if ( pAttribute == m_TargetName.GetAttribute() || + pAttribute == m_vecLocalAngles.GetAttribute() ) + { + pAttribute->RemoveFlag( FATTRIB_DONTSAVE | FATTRIB_HAS_CALLBACK ); + return; + } +} + + +//----------------------------------------------------------------------------- +// Returns the entity ID +//----------------------------------------------------------------------------- +int CDmeVMFEntity::GetEntityId() const +{ + return atoi( GetName() ); +} + + +//----------------------------------------------------------------------------- +// Entity Key iteration +//----------------------------------------------------------------------------- +bool CDmeVMFEntity::IsEntityKey( CDmAttribute *pEntityKey ) +{ + return pEntityKey->IsFlagSet( FATTRIB_USERDEFINED ); +} + +CDmAttribute *CDmeVMFEntity::FirstEntityKey() +{ + for ( CDmAttribute *pAttribute = FirstAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) + { + if ( IsEntityKey( pAttribute ) ) + return pAttribute; + } + return NULL; +} + +CDmAttribute *CDmeVMFEntity::NextEntityKey( CDmAttribute *pEntityKey ) +{ + if ( !pEntityKey ) + return NULL; + + for ( CDmAttribute *pAttribute = pEntityKey->NextAttribute(); pAttribute; pAttribute = pAttribute->NextAttribute() ) + { + if ( IsEntityKey( pAttribute ) ) + return pAttribute; + } + return NULL; +} + + +//----------------------------------------------------------------------------- +// Attach/detach from an engine entity with the same editor index +//----------------------------------------------------------------------------- +void CDmeVMFEntity::AttachToEngineEntity( bool bAttach ) +{ + if ( !bAttach ) + { + m_hEngineEntity = HTOOLHANDLE_INVALID; + } + else + { + } +} + + +//----------------------------------------------------------------------------- +// Draws the helper for the entity +//----------------------------------------------------------------------------- +int CDmeVMFEntity::DrawModel( int flags ) +{ + Assert( IsDrawingInEngine() ); + + matrix3x4_t mat; + AngleMatrix( m_vecLocalAngles, m_vecLocalOrigin, mat ); + + CMatRenderContextPtr rc( g_pMaterialSystem->GetRenderContext() ); + + rc->MatrixMode( MATERIAL_MODEL ); + rc->PushMatrix(); + rc->LoadMatrix( mat ); + + int nTheta = 20, nPhi = 20; + float flRadius = SPHERE_RADIUS; + int nVertices = nTheta * nPhi; + int nIndices = 2 * ( nTheta + 1 ) * ( nPhi - 1 ); + + rc->FogMode( MATERIAL_FOG_NONE ); + rc->SetNumBoneWeights( 0 ); + rc->Bind( m_Wireframe ); + rc->CullMode( MATERIAL_CULLMODE_CW ); + + IMesh* pMesh = rc->GetDynamicMesh(); + + CMeshBuilder meshBuilder; + meshBuilder.Begin( pMesh, MATERIAL_TRIANGLE_STRIP, nVertices, nIndices ); + + // + // Build the index buffer. + // + int i, j; + for ( i = 0; i < nPhi; ++i ) + { + for ( j = 0; j < nTheta; ++j ) + { + float u = j / ( float )(nTheta - 1); + float v = i / ( float )(nPhi - 1); + float theta = ( j != nTheta-1 ) ? 2.0f * M_PI * u : 0.0f; + float phi = M_PI * v; + + Vector vecPos; + vecPos.x = flRadius * sin(phi) * cos(theta); + vecPos.y = flRadius * cos(phi); + vecPos.z = -flRadius * sin(phi) * sin(theta); + + unsigned char red = (int)( u * 255.0f ); + unsigned char green = (int)( v * 255.0f ); + unsigned char blue = (int)( v * 255.0f ); + unsigned char alpha = (int)( v * 255.0f ); + + meshBuilder.Position3fv( vecPos.Base() ); + meshBuilder.Color4ub( red, green, blue, alpha ); + meshBuilder.TexCoord2f( 0, u, v ); + meshBuilder.BoneWeight( 0, 1.0f ); + meshBuilder.BoneMatrix( 0, 0 ); + meshBuilder.AdvanceVertex(); + } + } + + // + // Emit the triangle strips. + // + int idx = 0; + for ( i = 0; i < nPhi - 1; ++i ) + { + for ( j = 0; j < nTheta; ++j ) + { + idx = nTheta * i + j; + + meshBuilder.FastIndex( idx ); + meshBuilder.FastIndex( idx + nTheta ); + } + + // + // Emit a degenerate triangle to skip to the next row without + // a connecting triangle. + // + if ( i < nPhi - 2 ) + { + meshBuilder.FastIndex( idx + 1 ); + meshBuilder.FastIndex( idx + 1 + nTheta ); + } + } + + meshBuilder.End(); + pMesh->Draw(); + + rc->CullMode( MATERIAL_CULLMODE_CCW ); + rc->MatrixMode( MATERIAL_MODEL ); + rc->PopMatrix(); + + return 0; +} + + +//----------------------------------------------------------------------------- +// Position and bounds for the model +//----------------------------------------------------------------------------- +const Vector &CDmeVMFEntity::GetRenderOrigin( void ) +{ + return m_vecLocalOrigin; +} + +const QAngle &CDmeVMFEntity::GetRenderAngles( void ) +{ + return m_vecLocalAngles; +} + +void CDmeVMFEntity::GetRenderBounds( Vector& mins, Vector& maxs ) +{ + mins.Init( -SPHERE_RADIUS, -SPHERE_RADIUS, -SPHERE_RADIUS ); + maxs.Init( SPHERE_RADIUS, SPHERE_RADIUS, SPHERE_RADIUS ); +} |