Files
Leviathan/Client/Game/engine/TerrainEngine/TerrainProp.h
T
2026-06-01 12:46:52 +02:00

370 lines
12 KiB
C++

#pragma once
#include "K3DTypes.h"
#include "KObject.h"
//#include "KViewport.h"
#include "KPrimitiveMesh.h"
#include <geometry/X2DPolygon.h>
#include <geometry/X2DQuadTree.h>
#include <toolkit/ILock.h>
class CTerrainInfo;
class K3DBoundRotCube;
class KViewportObject;
class KSeqForm;
class CTerrainPropInfo;
class CTerrainMapEngine;
//class K3DFrustum;
//// Prop에 내장된 밟고 올라서는 발판
//class CTerrainStool
//{
//public:
// CTerrainStool( const K3DBoundRotCube& rCube )
// {
// K3DVertex vtMin = rCube.GetMinVertex();
// K3DVertex vtMax = rCube.GetMaxVertex();
//
// m_ptMin = K3DPoint( vtMin.x, vtMin.y );
// m_ptMax = K3DPoint( vtMax.x, vtMax.y );
//
// const K3DVertex* pVertices = rCube.GetVertices();
// m_FourPoints[0] = pVertices[4];
// m_FourPoints[1] = pVertices[7];
// m_FourPoints[2] = pVertices[5];
// m_FourPoints[3] = pVertices[6];
//
// //m_vtNormal0 = CTerrainInfo::BuildNormalVector( m_FourPoints[0], m_FourPoints[1], m_FourPoints[2] );
// //m_vtNormal1 = CTerrainInfo::BuildNormalVector( m_FourPoints[1], m_FourPoints[3], m_FourPoints[2] );
//
// //BuildWire( KColor( 255, 255, 0, 255 ) );
// }
//
// const K3DPoint& GetMinPoint() const { return m_ptMin; }
// const K3DPoint& GetMaxPoint() const { return m_ptMax; }
//
// bool GetHeight( float x, float y, float& rHeight ) const
// {
// if( m_ptMin.x <= x && x <= m_ptMax.x && m_ptMin.y <= y && y <= m_ptMax.y )
// {
// if( CTerrainUtil::IsInside2DPolygon( m_FourPoints[0], m_FourPoints[1], m_FourPoints[2], x, y ) )
// {
// rHeight = CTerrainUtil::GetHeightForPolygon( m_FourPoints[0], m_FourPoints[1], m_FourPoints[2], x, y );
// return true;
// }
// if( CTerrainUtil::IsInside2DPolygon( m_FourPoints[1], m_FourPoints[3], m_FourPoints[2], x, y ) )
// {
// rHeight = CTerrainUtil::GetHeightForPolygon( m_FourPoints[1], m_FourPoints[3], m_FourPoints[2], x, y );
// return true;
// }
// }
// return false;
// }
// bool GetLineCrossedPoint( const K3DVector& rNear, const K3DVector& rFar, K3DVector& rIntersect ) const
// { return CTerrainUtil::GetLineCrossedPointBothFaces( m_FourPoints, rNear, rFar, rIntersect ); }
//
// //void Render( KViewportObject* pViewport )
// //{
// // pViewport->RegisterWire( &m_WirePrimitive );
// //}
//
// //void BuildWire( const KColor& rColor ) const
// //{
// // CTerrainStool* pThis = const_cast<CTerrainStool*>(this);
//
// // pThis->m_WirePrimitive.Clear();
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[0], m_FourPoints[1], rColor );
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[1], m_FourPoints[2], rColor );
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[2], m_FourPoints[0], rColor );
//
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[1], m_FourPoints[3], rColor );
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[3], m_FourPoints[2], rColor );
//
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[0], m_FourPoints[0] + (m_vtNormal0 * 32.f), rColor );
// // pThis->m_WirePrimitive.AddLine( m_FourPoints[1], m_FourPoints[1] + (m_vtNormal1 * 32.f), rColor );
// //}
// //void AddWire( const K3DVertex vt0, const K3DVertex vt1, const KColor& rColor ) const
// //{
// // CTerrainStool* pThis = const_cast<CTerrainStool*>(this);
// // pThis->m_WirePrimitive.AddLine( vt0, vt1, rColor );
// //}
//
//private:
// K3DPoint m_ptMin, m_ptMax;
// K3DVertex m_FourPoints[4];
//
// //K3DVertex m_vtNormal0;
// //K3DVertex m_vtNormal1;
// //KWireUtilPrimitive m_WirePrimitive;
//};
//typedef std::vector<CTerrainStool> TERRAINSTOOL_VECTOR;
class CTerrainProp : public KObject
{
public:
void RefreshLightmap(bool bEnableLightmap);
protected:
void _SetLightmap();
public:
enum
{
TYPE_GRASS = 0,
TYPE_SPEEDTREE,
TYPE_PROPSMALL,
TYPE_PROPLARGE,
TYPE_NPC,
TYPE_BUILDINGSMALL,
TYPE_BUILDINGLARGE,
};
CTerrainProp( const K3DVector& rPos, const K3DVector& rRotate, const K3DVector& rScale, float fZOffset, WORD wPropNum, const CTerrainPropInfo* pPropInfo, bool bLockHeight,
int segmentIdx, int propIdx, bool bEnableLightmap, short texturegroupindex );
CTerrainProp() {}
virtual ~CTerrainProp();
const K3DVector& GetPos() const { return m_Pos; }
const K3DVector& GetRotate() const { return m_Rotate; }
const K3DVector& GetScale() const { return m_Scale; }
float GetZOffset() const { return m_fZOffset; }
const size_t& GetSegmentIdx() const { return m_segmentIdx; }
const size_t& GetPropIdx() const { return m_propIdx; }
void LightClipTest( const K3DVector* pFrustum);
void ClipTest( const K3DVector* pFrustum);
bool GetIsClip();
bool GetIsLightClip();
const K3DBoundRotCube* GetBoundCube() const;
/// { [sonador][COLLIDABLE_CAMERA]
bool CheckPolygonCollisionWithCollisionMesh
( const K3DVector& rayStart
, const K3DVector& rayEnd
, float& fNearestT
, K3DVector& vCollidedPoint
#ifdef _DEBUG
, K3DVector* pCollidedPolygon
#endif
);
// }
/// { [sonador][7.1.7]충돌 처리 개선(Swept Shpere Collision Detection)
bool CheckPolygonEllipsoidCollisionWithCollisionMesh
( const K3DVector& rayStart
, const K3DVector& rayEnd
, const K3DMatrix& matCBM
, float& fNearestT
, K3DVector& vCollidedPoint
#ifdef _DEBUG
, K3DVector* pCollidedPolygon
#endif
);
// }
float CheckPolygonCollision( const K3DVector& rNear, const K3DVector& rFar, K3DVector& rPickedPoint );
float GetVisibility() const { return m_fVisibility; }
void SetVisibility( float fVisible ); ///< 0.f ~ 1.f
void SetFloatLod(float fCameraDist, float fVisRange); ///< 0.0f ~ 1.0f
int GetLodLevel() const { return m_nLodLevel; }
void SetLodLevel( int nLevel ); ///< 0이 기본
WORD GetPropNum() const { return m_wPropNum; }
const K3DMatrix& GetTransform() const { return m_matTransform; }
const bool IsHeight() const { return !m_listTrianglesHeight.empty(); }
const bool IsInRectArea(float x, float y) const { return m_PropArea.IsCollision(X2D::Point<float>(x,y) ); }
float GetPropHeightByTriangleIndex( float x, float y) const;
float GetPropHeight( const K3DVector& rNear, const K3DVector& rFar, K3DVector& rPickedPoint ) const;
void GetPropTriangle( float x, float y, K3DVector& v1, K3DVector& v2, K3DVector& v3 ) const;
void SetX( float x ) { m_Pos.x = x; RefreshAllTransform(); }
void SetY( float y ) { m_Pos.y = y; RefreshAllTransform(); }
void SetZ( float z ) { m_Pos.z = z; RefreshAllTransform(); }
void SetRotateX( float x ) { m_Rotate.x = x; RefreshAllTransform(); }
void SetRotateY( float y ) { m_Rotate.y = y; RefreshAllTransform(); }
void SetRotateZ( float z ) { m_Rotate.z = z; RefreshAllTransform(); }
void SetScaleX( float x ) { m_Scale.x = x; RefreshAllTransform(); }
void SetScaleY( float y ) { m_Scale.y = y; RefreshAllTransform(); }
void SetScaleZ( float z ) { m_Scale.z = z; RefreshAllTransform(); }
void SetZOffset( float fZOffset ) { m_fZOffset = fZOffset; RefreshAllTransform(); }
/// 이동한다
void SetPosition( const K3DVector& vPos )
{
m_Pos = vPos;
RefreshAllTransform();
}
void CallRefreshTMFuntion() { RefreshAllTransform(); };
void SetOriginCorrection( const K3DVertex* pOriginCorrection = NULL )
{ m_pOriginCorrection = pOriginCorrection; }
int Process( DWORD dwTime );
virtual void Render( KViewportObject* pViewport );
const int GetRenderType() { return m_nRenderType; }
bool IsLoadCompleted() const;
void GetAttrbuteCubes( std::vector<K3DBoundRotCube>& rCubeVector ) const;
bool IsLodExist() const { return m_bLodExist; }
//#ifndef NDEBUG
std::string m_strFileName; ///< 화일 이름, 디버그 용
//#endif
static void BeginPropLoadingThread();
static void EndPropLoadingThread();
void StartThreadLoading() { m_bIsThreadLoading = true; }
void PendLoading();
bool IsPendLoading() { return m_bIsThreadPending; }
bool IsLoadFinished() { return IsRealLoad(); }
void Load_Real( bool bSlowLoad = false );
const bool IsRealLoad() { return m_bIsRealLoad; }
static void SetLodMax( float fLodMax ) { m_fLodMax = fLodMax; } ///< 스피드트리만 쓰고 있음
static void SetLodDist( float fLodDist ) { m_fLodDist = fLodDist; } ///< 스피드트리만 쓰고 있음
static void SetGrassVisRange(float fRange);
static void SetSpeedTreeVisRange(float fRange);
static void SetPropSmallVisRange(float fRange);
static void SetPropLargeVisRange(float fRange);
//static void SetNpcVisRange(float fRange);
static void SetBuildingSmallVisRange(float fRange);
static void SetBuildingLargeVisRange(float fRange);
static void SetTogglePropHeightRender() { m_bHeightRender = !m_bHeightRender; }
static void SetSkipVisibility( bool bFlag ) { m_bSetSkipVisibility = bFlag; }
static void SetTogglePropCaColRender() { m_bCameraCollisionRender = !m_bCameraCollisionRender; }
static void SetPropCaColVisibility( float fVis ) { m_fCameraCollisionVisibility = fVis; }
static bool IsShowPropCacol() { return m_bCameraCollisionRender; }
//void SetVisible(float fCameraDist, float fVisRange);
float GetVisRatio();
int GetPropType() {return m_nPropType;}
KSeqForm* GetModel() {return m_pModel;}
void Destroy();
bool IsSizeCull();
CTerrainProp* GetTerrainProp();
KSeqForm* GetTerrainHeightProp() { return m_pModelHeight; }
protected:
K3DVector m_Pos;
K3DVector m_Rotate;
K3DVector m_Scale;
float m_fZOffset;
WORD m_wPropNum;
DWORD m_dwTime;
const K3DVertex* m_pOriginCorrection;
K3DVertex m_ptCurrentOriginCorrection;
K3DMatrix m_matTransform;
K3DMatrix m_matCorrectedTransform;
KSeqForm* m_pModel; ///< 로딩에 실패하면 NULL일 수 있음.
KSeqForm* m_pModelHeight; ///< 높이 화일
K3DBoundRotCube* m_pBoundCube; ///< 반드시 NULL이 아님.
KSeqForm* m_pCameraCollision;
std::vector< K3DVector > m_CameraCollisionResource;
bool CreateCameraCollisionSource( );
// TERRAINSTOOL_VECTOR m_StoolVector; // 밟고 올라서는 발판들
float m_fVisibility;
int m_nLodLevel;
int m_nRenderType;
int m_nShadowFlag;
DWORD m_nRenderFlag; ///< RenderType + ShadowFlag
bool m_bLodExist;
//Prop Info
int m_nPropType; ///< PROP_NX3, PROP_COB, PROP_SPEEDTREE
DWORD m_dwPropCategory;
DWORD m_dwPropRenderType;
DWORD m_dwPropShadowType;
bool m_bIsClip;
volatile bool m_bIsRealLoad;
static float m_fLodMax; ///< 1.f~0.f
static float m_fLodDist;
static bool m_bHeightRender;
static bool m_bSetSkipVisibility;
static bool m_bCameraCollisionRender;
static float m_fCameraCollisionVisibility; ///< sonador][7.1.5]테스트용 클라이언트 제작 및 충돌 프랍 투명화 적용
/// Visible Cube 만 로드
void LoadCOB( const char* szNX3FileName, const K3DMatrix& rMatrix );
static KSeqForm* CreateNX3Model( const char* szNX3FileName, const char* szNAFFileName );
static KSeqForm* CreateNAFModel( const char* szFileName );
static KSeqForm* CreateSpeedTreeModel( const char* szFileName, const K3DMatrix& rMatrix );
static KSeqForm* CreateNPCModel( const char* szFileName );
static K3DBoundRotCube* CreateDummyBoundCube();
void UpdateTransform();
void UpdateCorrectedTransform();
void RefreshAllTransform();
void CreateStools();
void CreateTriangleIndex();
std::vector<K3DVector> m_listTrianglesHeight; ///< 삼각형 정보
// 여기서 일부러 노출안시켜도 되지만... 귀찮아서 -_-
protected:
X2D::Rect<float> m_PropArea;
class STriangleIndex* m_pIndexTri;
KWireUtilPrimitive m_WirePrimitive;
static float m_fGrassVisRange;
static float m_fSpeedTreeVisRange;
static float m_fPropSmallVisRange;
static float m_fPropLargeVisRange;
static float m_fBuildingSmallVisRange;
static float m_fBuildingLargeVisRange;
static unsigned int __stdcall prop_loader( void* pArg );
static volatile bool s_bStopThread;
volatile bool m_bIsThreadLoading;
volatile bool m_bIsThreadPending;
size_t m_segmentIdx;
size_t m_propIdx;
std::string m_nx3FileName;
bool m_bEnableLightmap;
XCriticalSection m_LightmapSetLock;
void addToLoadingList();
void removeFromLoadingList();
void ChangeTexture( short nTextureGroup );
//bool m_bVisible;
KWireUtilPrimitive m_prTestWire;
bool m_bDrawTestWire;
bool m_bTestWireCreated;
bool m_bLockHeight;
short m_nTextureGroupIndex;
std::vector< struct TEXTURE_GROUP_LIST* > m_vTextureGroupData;
};