mirror of
https://github.com/nillerusr/source-engine.git
synced 2024-12-23 22:56:50 +00:00
247 lines
6.6 KiB
C++
247 lines
6.6 KiB
C++
|
//========= 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 );
|
||
|
}
|