DragonNest/Common/EternityEngine/EtObject.cpp

1209 lines
26 KiB
C++
Raw Permalink Normal View History

#include "StdAfx.h"
#include "EtObject.h"
#include "EtConvexVolume.h"
#include "EtFindCollision.h"
#include "EtLoader.h"
#include "EtCustomParam.h"
#include "EtGenerateCollisionMesh.h"
#include "EtOptionController.h"
#include "EtCollisionMng.h"
#include "EtWater.h"
#include "EtEngine.h"
#include "EtFrustum.h"
#include "EtSkyBoxRTT.h"
#if !defined( USE_BOOST_MEMPOOL )
#ifdef _DEBUG
#define new new(_NORMAL_BLOCK,__FILE__,__LINE__)
#endif
#endif
using namespace EternityEngine;
DECL_SMART_PTR_STATIC( CEtObject, 3000 )
CEtOctree< CEtObject * > *CEtObject::s_pDynamicOctree = NULL;
float CEtOctreeNode< CEtObject * >::s_fMinRadius = 1000.0f;
bool CEtObject::m_bSkipDrawCollision = false;
CEtObject::CEtObject(void)
: CSmartPtrBase< CEtObject >()
{
SetChild( false );
ShowObject( true );
EnableObject( true );
EnableCull( true );
EnableShadowCast( false );
m_bShadowReceive = false;
m_bLightMapInfluence = false;
EnableLightMapCast( false );
EnableWaterCast( false );
ShowBoundingBox( false );
ShowCollisionPrimitive( false );
EtMatrixIdentity( &m_WorldMat );
m_WorldMat._41 = m_WorldMat._42 = m_WorldMat._43 = FLT_MAX;
m_PrevWorldMat._11 = FLT_MAX;
EtMatrixIdentity( &m_LinkOffsetMat );
m_nLinkBoneIndex = -1;
m_nSaveMatIndex = -1;
m_bValidSaveMatIndex = false;
m_pSkinInstance = NULL;
m_fObjectAlpha = 1.0f;
m_pCurOctreeNode = NULL;
m_BoundingBox.Min = EtVector3( 0.f, 0.f, 0.f );
m_BoundingBox.Max = EtVector3( 0.f, 0.f, 0.f );
m_OriginalBoundingBox.Min = EtVector3( 0.f, 0.f, 0.f );
m_OriginalBoundingBox.Max = EtVector3( 0.f, 0.f, 0.f );
m_RenderType = RT_SCREEN;
m_bAniObject = false;
m_LinkType = LT_BONE;
m_nFrustumMask = 0;
}
CEtObject::~CEtObject(void)
{
if( m_hParent )
{
m_hParent->RemoveChild( GetMySmartPtr() );
}
if( m_pCurOctreeNode )
{
s_pDynamicOctree->Remove( this, m_pCurOctreeNode );
}
SAFE_DELETE( m_pSkinInstance );
Clear();
}
void CEtObject::Clear()
{
SAFE_RELEASE_SPTR( m_hSkin );
}
void CEtObject::InitializeClass()
{
s_pDynamicOctree = new CEtOctree< CEtObject * >;
}
void CEtObject::FinalizeClass()
{
SAFE_DELETE( s_pDynamicOctree );
}
int CEtObject::Initialize( EtSkinHandle hSkin )
{
Clear();
m_hSkin = hSkin;
m_pSkinInstance = new CEtSkinInstance();
if( !m_hSkin->AddCallback( this ) )
{
CommonInitialize();
}
return ET_OK;
}
void CEtObject::CommonInitialize()
{ CreateSkinInstance();
if( m_hSkin->GetMeshHandle() )
CEtCollisionEntity::Initialize( *m_hSkin->GetMeshHandle()->GetCollisionPrimitive(), *m_hSkin->GetMeshHandle()->GetCollisionPrimitiveParentIndex() );
UpdateCollisionPrimitive( m_WorldMat );
GetMeshBoundingBox( m_OriginalBoundingBox );
GetMeshBoundingSphere( m_OriginalBoundingSphere );
}
void CEtObject::CreateSkinInstance()
{
if( m_hSkin )
{
if( m_pSkinInstance == NULL )
{
m_pSkinInstance = new CEtSkinInstance();
}
m_pSkinInstance->CopySkinInfo( m_hSkin );
if( m_pSkinInstance->IsSkyBox() )
{
CEtSkyBoxRTT::GetInstance().AddObject( m_MySmartPtr );
CEtSkyBoxRTT::GetInstance().SetRenderFrameCount( -1 );
}
}
}
RenderType CEtObject::SetRenderType( RenderType Type )
{
RenderType Ret = m_RenderType;
m_RenderType = Type;
return Ret;
}
void CEtObject::SetParent( EtObjectHandle hObject, const char *pLinkBoneName, EtMatrix *pOffsetMat )
{
EtMeshHandle hMesh = hObject->GetMesh();
int nLinkBoneIndex = -1;
if( hMesh )
{
nLinkBoneIndex = hMesh->FindDummy( pLinkBoneName );
if( nLinkBoneIndex != -1 )
{
SetParent( hObject, nLinkBoneIndex, pOffsetMat, LT_MESH_DUMMY );
return;
}
nLinkBoneIndex = hMesh->FindBone( pLinkBoneName );
if( nLinkBoneIndex != -1 )
{
SetParent( hObject, nLinkBoneIndex, pOffsetMat, LT_BONE );
return;
}
}
}
void CEtObject::SetParent( EtObjectHandle hObject, int nBoneIndex, EtMatrix *pOffsetMat, LinkType Type )
{
if ( hObject == GetMySmartPtr() )
{
ASSERT( false && "hObject == GetMySmartPtr()" );
return;
}
// <20>Լ<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ʈ <20><><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD> <20><><EFBFBD><EFBFBD>!!!
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
if( m_hParent )
{
m_hParent->RemoveChild( GetMySmartPtr() );
}
if( hObject )
{
m_hParent = hObject;
m_nLinkBoneIndex = nBoneIndex;
m_LinkType = Type;
if( pOffsetMat )
{
m_LinkOffsetMat = *pOffsetMat;
}
m_hParent->AddChild( GetMySmartPtr() );
EnableShadowCast( m_hParent->IsShadowCast() );
EnableShadowReceive( m_hParent->IsShadowReceive() );
EnableLightMapInfluence( m_hParent->IsLightMapInfluence() );
SetObjectAlpha( m_hParent->GetObjectAlpha() );
SetChild( true );
int nItemIndex, nParentItemIndex;
nItemIndex = GetMyItemIndex();
nParentItemIndex = m_hParent->GetMyItemIndex();
if( nItemIndex < nParentItemIndex )
{
SwapItemIndex( nItemIndex, nParentItemIndex );
}
}
else
{
m_hParent.Identity();
m_nLinkBoneIndex = -1;
EtMatrixIdentity( &m_LinkOffsetMat );
SetChild( false );
}
}
void CEtObject::AddChild( EtObjectHandle hObject )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
m_vecChild.push_back( hObject );
if( m_hSkin->IsReady() )
{
RecalcBoundingBox();
RecalcBoundingSphere();
}
}
void CEtObject::RemoveChild( EtObjectHandle hObject )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i;
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
if( m_vecChild[ i ] == hObject )
{
m_vecChild.erase( m_vecChild.begin() + i );
RecalcBoundingBox();
RecalcBoundingSphere();
return;
}
}
ASSERT( 0 && "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> child<6C><64> <20><><EFBFBD><EFBFBD>" );
}
bool CEtObject::IsShow()
{
if( !m_hSkin ) return false;
return m_bShow && m_hSkin->IsReady();
}
void CEtObject::EnableLightMapInfluence( bool bEnable )
{
m_bLightMapInfluence = bEnable;
CalcLightMapInfluence();
}
void CEtObject::ShowSubmesh( int nSubmeshIndex, bool bShow )
{
if( m_pSkinInstance )
{
m_pSkinInstance->GetSkinRenderInfo( nSubmeshIndex )->bShowSubmesh = bShow;
}
}
bool CEtObject::IsShowSubmesh( int nSubmeshIndex )
{
if( m_pSkinInstance )
{
return m_pSkinInstance->GetSkinRenderInfo( nSubmeshIndex )->bShowSubmesh;
}
return true;
}
void CEtObject::SetFrustumMask( int nMask )
{
m_nFrustumMask = nMask;
}
void CEtObject::AddFrustumMask( int nMask )
{
m_nFrustumMask |= nMask;
int i, nCount;
nCount = ( int )m_vecChild.size();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hObject = m_vecChild[ i ];
hObject->AddFrustumMask( nMask );
}
}
void CEtObject::EnableShadowCast( bool bEnable )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
m_bShadowCast = bEnable;
int i, nCount;
nCount = ( int )m_vecChild.size();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hObject = m_vecChild[ i ];
hObject->EnableShadowCast( bEnable );
}
}
void CEtObject::EnableShadowReceive( bool bEnable )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
m_bShadowReceive = bEnable;
int i, nCount;
nCount = ( int )m_vecChild.size();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hObject = m_vecChild[ i ];
hObject->EnableShadowReceive( bEnable );
}
}
void CEtObject::SetObjectAlpha( float fAlpha )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
m_fObjectAlpha = fAlpha;
int i, nCount;
nCount = ( int )m_vecChild.size();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hObject = m_vecChild[ i ];
hObject->SetObjectAlpha( fAlpha );
}
}
void CEtObject::Update( EtMatrix *pWorldMat )
{
SSphere Sphere;
if( m_PrevWorldMat._11 == FLT_MAX )
{
m_PrevWorldMat = *pWorldMat;
m_bUpdateNeeded = true;
}
else
{
m_PrevWorldMat = m_WorldMat;
if( memcmp ( &m_PrevWorldMat, pWorldMat , sizeof(EtMatrix) ) != 0 ) {
m_bUpdateNeeded = true;
}
}
m_WorldMat = *pWorldMat;
UpdateBoundingPrimitive();
CalcLightInfluence();
CalcLightMapInfluence();
if( ( m_hSkin ) && ( !IsChild() ) )
{
UpdateCollisionPrimitive( m_WorldMat, m_bUpdateNeeded );
GetBoundingSphere( Sphere );
if( GetCollisionGroup() >= COLLISION_GROUP_DYNAMIC( 2 ) ) // <20><><EFBFBD>̳<EFBFBD><CCB3><EFBFBD> <20>ø<EFBFBD><C3B8><EFBFBD> Ÿ<><C5B8><EFBFBD><EFBFBD> <20>ֵ鸸 <20><>Ʈ<EFBFBD><C6AE><EFBFBD><EFBFBD> <20>־ üũ <20><><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD> KdTree<65><65> <20><><EFBFBD><EFBFBD>.
{
if( m_pCurOctreeNode )
{
m_pCurOctreeNode = s_pDynamicOctree->Update( this, Sphere, m_pCurOctreeNode );
}
else
{
m_pCurOctreeNode = s_pDynamicOctree->Insert( this, Sphere );
}
}
}
m_bUpdateNeeded = false;
}
void CEtObject::CalcParentBoneMat()
{
EtMatrix LinkMat, *pBoneMat;
EtMatrixMultiply( &LinkMat, m_hParent->GetWorldMat(), &m_LinkOffsetMat );
if( m_nLinkBoneIndex != -1 )
{
if( m_LinkType == LT_BONE )
{
pBoneMat = m_hParent->GetBoneTransMat( m_nLinkBoneIndex );
}
else
{
pBoneMat = m_hParent->GetDummyTransMat( m_nLinkBoneIndex );
}
if( pBoneMat )
{
EtMatrixMultiply( &LinkMat, pBoneMat, &LinkMat );
}
}
Update( &LinkMat );
}
void CEtObject::InitRender( int nSaveMatIndex )
{
if( !IsShow() )
{
return;
}
if( m_hParent )
{
CalcParentBoneMat();
}
int i;
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
m_vecChild[ i ]->InitRender( nSaveMatIndex );
}
}
void CEtObject::Render()
{
if( !IsShow() )
{
return;
}
if( IsShowBoundingBox() )
{
DrawBoundingBox();
}
if( m_pSkinInstance )
{
m_pSkinInstance->Render( m_WorldMat, m_PrevWorldMat, m_fObjectAlpha, m_vecInfluenceLight, m_bShadowReceive, m_nSaveMatIndex );
}
}
void CEtObject::RenderImmediate( bool bRenderChild )
{
if( !IsShow() )
{
return;
}
if( m_pSkinInstance )
{
m_pSkinInstance->RenderImmediate( m_WorldMat, m_WorldMat, m_fObjectAlpha, m_vecInfluenceLight, m_bShadowReceive, false, m_nSaveMatIndex );
}
if( bRenderChild )
{
int i;
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
if( m_vecChild[ i ] )
{
m_vecChild[ i ]->RenderImmediate( bRenderChild );
}
}
}
}
void CEtObject::RenderAlphaImmediate( bool bRenderChild )
{
if( !IsShow() )
{
return;
}
if( m_pSkinInstance )
{
m_pSkinInstance->RenderImmediate( m_WorldMat, m_WorldMat, m_fObjectAlpha, m_vecInfluenceLight, m_bShadowReceive, true, m_nSaveMatIndex );
}
if( bRenderChild )
{
int i;
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
if( m_vecChild[ i ] )
{
m_vecChild[ i ]->RenderAlphaImmediate( bRenderChild );
}
}
}
}
void CEtObject::RenderShadow()
{
if( !IsShow() )
{
return;
}
if( m_pSkinInstance )
{
m_pSkinInstance->RenderShadow( m_WorldMat, m_nSaveMatIndex );
}
}
void CEtObject::RenderWater( int index )
{
if( !IsShow() )
{
return;
}
if( m_pSkinInstance )
{
if( !m_hParent )
{
InitRender();
m_pSkinInstance->RenderWater( index, m_WorldMat, m_PrevWorldMat, m_fObjectAlpha, m_vecInfluenceLight, m_bShadowReceive, m_nSaveMatIndex );
}
}
}
void CEtObject::SetSaveMatIndex( int nIndex )
{
m_nSaveMatIndex = nIndex;
int i;
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
m_vecChild[ i ]->SetSaveMatIndex( nIndex );
}
}
void CEtObject::GetMeshBoundingBox( SAABox &AABox )
{
if( m_hSkin )
{
EtMeshHandle hMesh = m_hSkin->GetMeshHandle();
if( hMesh )
{
hMesh->GetBoundingBox( AABox );
}
return;
}
AABox.Min = EtVector3( -1.0f, -1.0f, -1.0f );
AABox.Max = EtVector3( 1.0f, 1.0f, 1.0f );
}
void CEtObject::GetMeshBoundingSphere( SSphere &Sphere )
{
if( m_hSkin )
{
EtMeshHandle hMesh = m_hSkin->GetMeshHandle();
if( hMesh )
{
hMesh->GetBoundingSphere( Sphere );
}
return;
}
Sphere.Center = EtVector3( 0.0f, 0.0f, 0.0f );
Sphere.fRadius = 1.0f;
}
void CEtObject::RecalcBoundingBox()
{
SAABox BoundingBox;
GetMeshBoundingBox( m_OriginalBoundingBox );
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ϵ尡 <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>ϰ<EFBFBD> <20>־ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><20><><EFBFBD>߱<EFBFBD> <20><><EFBFBD>ؼ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD>Ѵ<EFBFBD>. <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>..
/* for( int i = 0; i < ( int )m_vecChild.size(); i++ )
{
m_vecChild[ i ]->GetMeshBoundingBox( BoundingBox );
m_OriginalBoundingBox.AddPoint( BoundingBox.Max );
m_OriginalBoundingBox.AddPoint( BoundingBox.Min );
}*/
}
void CEtObject::RecalcBoundingSphere()
{
int i;
EtVector3 vDirection, vOriginalEnd, vChildEnd;
SSphere BoundingSphere;
GetMeshBoundingSphere( m_OriginalBoundingSphere );
for( i = 0; i < ( int )m_vecChild.size(); i++ )
{
m_vecChild[ i ]->GetMeshBoundingSphere( BoundingSphere );
if( m_OriginalBoundingSphere.IsInside( BoundingSphere ) )
{
continue;
}
vDirection = BoundingSphere.Center - m_OriginalBoundingSphere.Center;
EtVec3Normalize( &vDirection, &vDirection );
vOriginalEnd = m_OriginalBoundingSphere.Center - vDirection * m_OriginalBoundingSphere.fRadius;
vChildEnd = BoundingSphere.Center + vDirection * BoundingSphere.fRadius;
m_OriginalBoundingSphere.Center = ( vOriginalEnd + vChildEnd ) * 0.5f;
m_OriginalBoundingSphere.fRadius = EtVec3Length( &( vOriginalEnd - vChildEnd ) ) * 0.5f;
}
}
void CEtObject::DrawBoundingBox( DWORD dwColor )
{
int i;
static short s_LineIndices[] =
{
0, 1, 1, 3, 3, 2, 2, 0,
4, 5, 5, 7, 7, 6, 6, 4,
0, 4, 1, 5, 3, 7, 2, 6,
};
SOBB OBBox;
OBBox.Init( m_OriginalBoundingBox, m_WorldMat );
for( i = 0; i < sizeof( s_LineIndices ) / sizeof( short ) / 2; i++ )
{
DrawLine3D( OBBox.Vertices[ s_LineIndices[ i * 2 ] ], OBBox.Vertices[ s_LineIndices[ i * 2 + 1 ] ], dwColor );
}
}
void CEtObject::UpdateBoundingPrimitive()
{
if( !m_hSkin )
{
return;
}
if( !m_bUpdateNeeded ) { // Static Object <20><> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>Ź<EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20>ʿ<EFBFBD> <20><><EFBFBD><EFBFBD>.
return;
}
if( !m_OriginalBoundingBox.IsValid() ) {
return;
}
m_BoundingBox.Reset();
SOBB OBBox;
OBBox.Init( m_OriginalBoundingBox, m_WorldMat );
for( int i = 0; i < 8; i++) {
m_BoundingBox.AddPoint( OBBox.Vertices[i] );
}
m_BoundingSphere = m_OriginalBoundingSphere;
EtVec3TransformCoord( &m_BoundingSphere.Center, &m_OriginalBoundingSphere.Center, &m_WorldMat );
m_BoundingSphere.fRadius *= max( max( m_vScale.x, m_vScale.y ), m_vScale.z );
}
void CEtObject::UpdateCollisionPrimitive( EtMatrix &WorldMat, bool bUpdate )
{
if( !IsEnableCollision() )
{
return;
}
int i;
EtMatrix *pBoneMat, AniMat;
for( i = 0; i < ( int )m_vecPrimitive.size(); i++ )
{
pBoneMat = &WorldMat;
if( m_vecPrimitiveParentIndex[ i ] != -1 )
{
pBoneMat = GetBoneMat( m_vecPrimitiveParentIndex[ i ] );
if( pBoneMat )
{
pBoneMat = EtMatrixMultiply( &AniMat, pBoneMat, &WorldMat );
}
else
{
pBoneMat = &WorldMat;
}
CEtCollisionEntity::UpdateCollisionPrimitive( i, *pBoneMat );
}
else {
CEtCollisionEntity::UpdateCollisionPrimitive( i, *pBoneMat, bUpdate );
}
}
}
bool CEtObject::FindDynamicCollision( EtMatrix &WorldMat, DNVector(SCollisionResponse) &vecResponse, bool bCalcContactTime, bool bUpdaetPrimitive)
{
SAABox BoundingBox;
EtVector3 vMove;
vMove.x = WorldMat._41 - m_WorldMat._41;
vMove.y = WorldMat._42 - m_WorldMat._42;
vMove.z = WorldMat._43 - m_WorldMat._43;
GetBoundingBox( BoundingBox );
BoundingBox.Max += vMove;
BoundingBox.Min += vMove;
if( bUpdaetPrimitive )
{
UpdateCollisionPrimitive( WorldMat );
m_bUpdateNeeded = true;
}
return _FindDynamicCollision( BoundingBox, vMove, vecResponse, bCalcContactTime );
}
bool CEtObject::_FindDynamicCollision( SAABox &BoundingBox, EtVector3 &vMove, DNVector(SCollisionResponse) &vecResponse, bool bCalcContactTime)
{
static DNVector(CEtObject *) vecPickObject;
bool bRet = false;
vecPickObject.clear();
s_pDynamicOctree->Pick( BoundingBox, vecPickObject );
if( !vecPickObject.empty() )
{
int i;
for( i = 0; i < ( int )vecPickObject.size(); i++ )
{
std::vector< SCollisionPrimitive * > *pTargetPrimitive;
if( !vecPickObject[ i ]->IsEnableCollision() )
{
continue;
}
if( ( vecPickObject[ i ]->GetCollisionGroup() & GetTargetCollisionGroup() ) == 0 )
{
continue;
}
pTargetPrimitive = vecPickObject[ i ]->GetCollisionPrimitive();
if( !pTargetPrimitive )
{
continue;
}
if( CEtCollisionEntity::FindCollision( *pTargetPrimitive, vMove, vecResponse, bCalcContactTime ) )
{
bRet = true;
}
}
}
return bRet;
}
bool CEtObject::FindCollision( EtMatrix &WorldMat, DNVector(SCollisionResponse) &vecResponse, bool bCalcContactTime, bool bUpdaetPrimitive)
{
if( !IsEnableCollision() )
{
return false;
}
SAABox BoundingBox;
EtVector3 vMove;
bool bResult;
vMove.x = WorldMat._41 - m_WorldMat._41;
vMove.y = WorldMat._42 - m_WorldMat._42;
vMove.z = WorldMat._43 - m_WorldMat._43;
GetBoundingBox( BoundingBox );
BoundingBox.Max += vMove;
BoundingBox.Min += vMove;
if( bUpdaetPrimitive )
{
UpdateCollisionPrimitive( WorldMat );
m_bUpdateNeeded = true;
}
bResult = CEtCollisionMng::GetInstance().FindCollision( m_vecPrimitive, BoundingBox, vMove, vecResponse, bCalcContactTime );
if( _FindDynamicCollision( BoundingBox, vMove, vecResponse, bCalcContactTime ) )
{
bResult = true;
}
return bResult;
}
bool CEtObject::FindCollision( EtObjectHandle hObject, std::vector< SCollisionResponse > &vecResponse, bool bCalcContactTime )
{
int i, j;
SCollisionResponse Response;
bool bResult = false;
std::vector< SCollisionPrimitive * > &vecTragetPrimitive = *hObject->GetCollisionPrimitive();
for( i = 0; i < ( int )m_vecPrimitive.size(); i++ )
{
if( !m_vecPrimitiveEnable[ i ] )
{
continue;
}
for( j = 0; j < ( int )vecTragetPrimitive.size(); j++ )
{
if( !hObject->IsEnableCollision( vecTragetPrimitive[ j ] ) )
{
continue;
}
if( CEtCollisionFinder::GetInstance().FindCollision( *m_vecPrimitive[ i ], *vecTragetPrimitive[ j ], Response, bCalcContactTime ) )
{
Response.pCollisionPrimitive = vecTragetPrimitive[ j ];
vecResponse.push_back( Response );
if( Response.vExtraNormal.x != FLT_MAX )
{
Response.vNormal = Response.vExtraNormal;
vecResponse.push_back( Response );
}
bResult = true;
}
}
}
return bResult;
}
int CEtObject::AddCustomParam( const char *pParamName )
{
if( m_pSkinInstance )
{
return m_pSkinInstance->AddCustomParam( pParamName );
}
return -1;
}
bool CEtObject::SetCustomParam( int nParamIndex, void *pValue, int nSubMeshIndex )
{
if( m_pSkinInstance )
{
return m_pSkinInstance->SetCustomParam( nParamIndex, pValue, nSubMeshIndex );
}
return false;
}
void CEtObject::RestoreCustomParam( int nParamIndex, int nSubMeshIndex )
{
if( m_pSkinInstance )
{
m_pSkinInstance->RestoreCustomParam( nParamIndex, nSubMeshIndex );
}
}
void CEtObject::GetExtent( EtVector3 &Origin, EtVector3 &Extent )
{
Origin = ( m_BoundingBox.Max + m_BoundingBox.Min ) / 2;
Extent = ( m_BoundingBox.Max - m_BoundingBox.Min ) / 2;
}
void CEtObject::ClearFrustumMask()
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
GetItem( i )->SetFrustumMask( 0 );
}
}
void CEtObject::MaskFrustumObjectList( CEtConvexVolume *pFrustum, int nFrustumMask )
{
int i, j, nCount;
int nWaterCount = GetEtWater()->GetWaterCount();
std::vector<CEtConvexVolume> ReflectFrustumList;
ReflectFrustumList.resize( nWaterCount );
for( i = 0; i < nWaterCount; i++) {
ReflectFrustumList[i].Initialize( GetEtWater()->GetViewProjMat( i ) );
}
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtVector3 Origin, Extent;
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
CEtObject *pObject = hHandle.GetPointer();
if( !pObject->IsEnable() )
{
continue;
}
if( pObject->IsChild() )
{
continue;
}
if( !pObject->IsShow() )
{
continue;
}
pObject->GetExtent( Origin, Extent );
if( ( !pObject->IsEnableCull() ) || pFrustum->TesToBox( Origin, Extent ) )
{
pObject->AddFrustumMask( nFrustumMask );
}
if( pObject->IsWaterCast() )
{
for( j = 0; j < nWaterCount; j++)
{
if( GetEtWater()->GetWaterIgnoreBake( j ) )
continue;
if( ( !pObject->IsEnableCull() ) || ( ReflectFrustumList[j].TesToBox( Origin, Extent ) ) )
{
pObject->RenderWater( j );
}
}
}
}
}
void CEtObject::InitRenderObjectList()
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
if( hHandle->IsChild() )
{
continue;
}
if( hHandle->GetFrustumMask() )
{
hHandle->InitRender();
}
}
}
void CEtObject::RenderObjectList( int nMask )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
if( hHandle->GetRenderType() != CT_SCREEN )
{
continue;
}
if( hHandle->GetFrustumMask() & nMask )
{
hHandle->Render();
}
}
}
void CEtObject::RenderShadowObjectList( int nMask, float fShadowRange )
{
int i, nCount;
CEtConvexVolume Frustum;
EtMatrix ProjMat;
EtCameraHandle hCamera;
hCamera = CEtCamera::GetActiveCamera();
EtMatrixPerspectiveFovLH( &ProjMat, hCamera->GetFOV(), hCamera->GetAspectRatio(), hCamera->GetCameraNear(), fShadowRange );
EtMatrixMultiply( &ProjMat, hCamera->GetViewMat(), &ProjMat );
Frustum.Initialize( ProjMat );
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
if( hHandle->GetRenderType() != CT_SCREEN )
{
continue;
}
if( ( hHandle->GetFrustumMask() & nMask ) && ( hHandle->IsShadowCast() ) && ( hHandle->GetObjectAlpha() > 0.5f ) )
{
EtVector3 Origin, Extent;
hHandle->GetExtent( Origin, Extent );
if( ( !hHandle->IsEnableCull() ) || Frustum.TesToBox( Origin, Extent ) )
{
hHandle->RenderShadow();
}
}
}
}
void CEtObject::DrawCollisionList( int nMask )
{
if( m_bSkipDrawCollision ) { // <20>׷<EFBFBD><D7B7><EFBFBD><EFBFBD>°<EFBFBD><C2B0><EFBFBD> <20>ϳ<EFBFBD><CFB3><EFBFBD> <20><><EFBFBD>ٸ<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD>Ѵ<EFBFBD>.
return;
}
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
bool bDraw = false;
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
if( hHandle->GetRenderType() != CT_SCREEN )
{
continue;
}
if( hHandle->IsShowCollisionPrimitive() ) bDraw = true;
if( hHandle->GetFrustumMask() & nMask )
{
hHandle->DrawCollisionPrimitive();
}
}
if( !bDraw ) {
m_bSkipDrawCollision = true;
}
}
void CEtObject::CalcLightInfluence()
{
if( !m_bUpdateNeeded ) {
return;
}
m_vecInfluenceLight.clear();
CEtLight::CalcLightInfluence( m_BoundingSphere, m_vecInfluenceLight, m_MySmartPtr );
struct CompareFunc {
EtVector3 m_vOffset;
CompareFunc( EtVector3 &vOffset ) : m_vOffset(vOffset) {}
bool operator () ( CEtLight *pLight1, CEtLight *pLight2 ) const
{
float fLength1 = EtVec3LengthSq( &EtVector3( pLight1->GetLightInfo()->Position - m_vOffset ) );
float fLength2 = EtVec3LengthSq( &EtVector3( pLight2->GetLightInfo()->Position - m_vOffset ) );
return fLength1 < fLength2;
}
};
std::sort( m_vecInfluenceLight.begin(), m_vecInfluenceLight.end(), CompareFunc( m_BoundingSphere.Center ) );
int nMaxLightCount = MAX_POINT_LIGHT_COUNT + MAX_SPOT_LIGHT_COUNT - 1;
if( ( int )m_vecInfluenceLight.size() > nMaxLightCount )
{
m_vecInfluenceLight.erase( m_vecInfluenceLight.begin() + nMaxLightCount, m_vecInfluenceLight.end() );
}
}
void CEtObject::CalcLightInfluenceList( bool bForce )
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
if( bForce ) hHandle->SetUpdateNeeded( true );
hHandle->CalcLightInfluence();
}
}
void CEtObject::CalcLightMapInfluence()
{
if( m_pSkinInstance )
{
if( m_bLightMapInfluence )
{
if( m_bUpdateNeeded ) {
float fInfluence = CEtTerrainArea::CalcLightMapInfluence( m_WorldMat._41, m_WorldMat._43 );
m_pSkinInstance->SetDirLightAttenuation( fInfluence );
}
}
else
{
m_pSkinInstance->SetDirLightAttenuation( 1.0f );
}
}
}
void CEtObject::RecalcLightMapInfluence()
{
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
int i, nCount;
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
hHandle->SetUpdateNeeded( true );
hHandle->CalcLightMapInfluence();
}
}
void CEtObject::SetWorldSize( EtVector3 &WorldCenter, float fRadius )
{
CEtLight::SetWorldSize( WorldCenter, fRadius );
s_pDynamicOctree->Initialize( WorldCenter, fRadius );
int i, nItemCount;
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
nItemCount = GetItemCount();
for( i = 0; i < nItemCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( !hHandle )
{
continue;
}
hHandle->m_pCurOctreeNode = NULL;
}
}
EtObjectHandle CEtObject::Pick( int nX, int nY, int nCameraIndex )
{
CEtObject *pPickObject;
EtVector3 Position, Direction;
CEtCamera::GetItem( nCameraIndex )->CalcPositionAndDir( nX, nY, Position, Direction );
pPickObject = NULL;
s_pDynamicOctree->Pick( Position, Direction, pPickObject );
if( pPickObject )
{
return pPickObject->GetMySmartPtr();
}
else
{
EtObjectHandle Identity;
return Identity;
}
}
void CEtObject::OnLoadComplete( CBackgroundLoader *pLoader )
{
CommonInitialize();
RecalcBoundingBox();
RecalcBoundingSphere();
Update( &m_WorldMat );
CBackgroundLoaderCallback::OnLoadComplete( pLoader );
}
void CEtObject::AddCollisionMeshToKdTree()
{
if( ( !m_hSkin ) || ( ( m_nCollisionGroup & COLLISION_TYPE_STATIC ) == 0 ) )
{
return;
}
int i;
EtMeshHandle hMesh;
hMesh = m_hSkin->GetMeshHandle();
if( hMesh )
{
for( i = 0; i < hMesh->GetCollisionPrimitiveCount(); i++ )
{
CEtCollisionMng::GetInstance().AddCollisionMeshToKdTree( *( *hMesh->GetCollisionPrimitive() )[ i ], m_WorldMat, m_vScale );
}
}
}
void CEtObject::BuildKdTree()
{
int i, nCount;
CEtCollisionMng::GetInstance().Clear();
ScopeLock<CSyncLock> Lock( s_SmartPtrLock );
nCount = GetItemCount();
for( i = 0; i < nCount; i++ )
{
EtObjectHandle hHandle;
hHandle = GetItem( i );
if( hHandle )
{
if( !hHandle->IsEnableCollision() ) {
continue;
}
hHandle->UpdateCollisionPrimitive( *hHandle->GetWorldMat() );
hHandle->AddCollisionMeshToKdTree();
}
}
CEtCollisionMng::GetInstance().BuildCollisionTree();
}