genesis-3d_engine/Engine/app/terrainfeature/components/TerrainNode.h
zhongdaohuan 6e8fbca745 genesis-3d engine version 1.3.
match the genesis editor version 1.3.0.653.
2014-05-05 14:50:33 +08:00

364 lines
11 KiB
C++

/****************************************************************************
Copyright (c) 2011-2013,WebJet Business Division,CYOU
http://www.genesis-3d.com.cn
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
****************************************************************************/
#ifndef __TerrainNode_H__
#define __TerrainNode_H__
#include "core/refcounted.h"
#include "math/bbox.h"
#include "resource/meshres.h"
#include "terrainsystem/TerrainDataSource.h"
#include "terrainfeature/components/TerrainRenderObject.h"
namespace Graphic
{
class RenderScene;
}
namespace App
{
//base enum and struct=============================================================================
enum NodeNeighborDir
{
eLeftNeighbor = 0,
eRightNeighbor = 1,
eUpNeighbor = 2,
eDownNeighbor = 3,
eNeighborCount = 4,
};
enum NodeChildDir
{
eLeftUpChild = 0,
eRightUpChild = 1,
eLeftDownChild = 2,
eRightDownChild = 3,
eChildCount = 4,
};
enum NodeDrawMode
{
eNodeDrawParent = 0,
eNodeDrawChild = 1,
eNodeDrawSelf = 2
};
// veritce buffer
struct FVF_TERRAIN
{
float x, y, z; //position
float u, v; //texcoord
float nx, ny, nz; //normal
};
// a unit grid
struct SRenderNormal
{
int haveTriangleIdx[2]; // one unit grid contains 2 triangle
};
typedef SRenderNormal* TSRenderNormal;
//=============================================================================
class TerrainNodeTraverser;
class TerrainRenderObject;
class TerrainNode
{
public:
TerrainNode();
~TerrainNode();
void Reset();
void ChangeRenderScene(Graphic::RenderScene* rnsc);
//-------------------For Traverser Pattern-----------------------------------------------------
/// accept NV's Apply function
void Accept(TerrainNodeTraverser& nv);
/** Traverse upwards : calls parents' accept method with NodeTraverser.*/
void TraverseParent(TerrainNodeTraverser& nv);
/** Traverse downwards : calls children's accept method with NodeTraverser.*/
void TraverseChilds(TerrainNodeTraverser& nv);
/** Traverse Neighbor : calls Neighbor's accept method with NodeTraverser.*/
void TraverseNeighbor(TerrainNodeTraverser& nv);
//----------------------basic property--------------------------------------------------
const Math::bbox& GetLocalBoundingBox() const;
void SetLocalBoundingBox(const Math::bbox& bb);
RenderBase::PrimitiveTopology::Code GetPrimitiveTopology(void)const ;
bool IsUseBaseMap(void) const ;
void SetUseBaseMap(bool b);
void SetNodeDrawMode( NodeDrawMode v);
NodeDrawMode GetNodeDrawMode(void) const;
float GetGeometryError(void) const;
void SetGeometryError(float h);
bool HaveHole();
void SetHole(bool b);
//------------------neighbor and parent-child relationship------------------------------------------------------
TerrainNode* GetParentNode()const ;
void SetParentNode(TerrainNode* p);
TerrainNode* GetChildNode(int dir) const;
void SetChildNode(TerrainNode* child, int dir);
TerrainNode* GetNeighborNode(int dir) const;
void SetNeighborNode(TerrainNode* neighbor, int dir);
//---------------------------Render---------------------------------------------
/// Set need render
void SetRenderEnable(bool b) ;
bool GetRenderEnable(void);
const GPtr<TerrainRenderObject>& GetRenderObject() const;
void SetRenderObject(const GPtr<TerrainRenderObject>& renderObj);
void SetEdgeMask( int mask );
int GetEdgeMask(void) const;
int ComputeNodeEdgeMask() ;
const RenderBase::PrimitiveHandle& GetPrimitiveHandle() const ;
void RequestBuildPritiveHandle();
bool IsNeedBulidPritiveHandle() const ;
/// if need, build PrimitiveHandle
void BuildPrimitiveHandleIfNeed(const GPtr<Terrain::TerrainDataSource>& terrainDataSource);
/// Force build PrimitiveHandle, slow! use it carefully!
void ForceBuildPrimitiveHandle(const GPtr<Terrain::TerrainDataSource>& terrainDataSource);
//--------------------------Ray Intersect----------------------------------------------
const Resources::PositionData::Elem* GetPositionData() const;
Resources::Index16Container::value_type* GetIndexData() const;
SizeT GetIndexDataCount() const;
SizeT GetPostionDataCount() const;
#ifdef __GENESIS_EDITOR__
const Resources::TexCoordData::Elem* GetTexCoorData() const;
const Resources::NormalData::Elem* GetNormalData() const;
#endif
protected:
int _ComputeNeedSutureEdgeMask(const TerrainNode &node, TerrainNode &nodeAnalysis);
// Use standard grid to build edge
void _BuildPrimitiveHandle_Reqular(const GPtr<Terrain::TerrainDataSource>& terrainDataSource);
void _BuildOneGridIdxData(Util::Array<uint16>& indexData, int xx,int yy);
void _BuildOneGridIdxDataWithHole(Util::Array<uint16>& indexData, int xx,int yy);
void _FixHeightAndNormal(FVF_TERRAIN* heightArray,Resources::PositionData& posData);
#ifdef __GENESIS_EDITOR__
void _SaveUVAndNormal(const FVF_TERRAIN* verticeData);
#endif
public:
int x;
int y;
int level;
int bundleIndex;
int m_levelDif[eNeighborCount];
bool m_NeedRebuild;
protected:
bool m_RenderEnable; // enable render
NodeDrawMode m_DrawMode; // node's LOD draw mode
float m_GeometryError; // node's bundle geometry error
Math::bbox m_LocalBoundingBox; // local Bound
bool m_UseBaseMap; // whether or not use base map
int m_EdgeMask; // show the edge suture status. 0: sutured. 1: need suture.
bool m_bHaveHole;
RenderBase::PrimitiveHandle m_PrimitiveHandle; // render handle
bool m_NeedBuildHandle; // whether or not need build PrimitiveHandle
GPtr<TerrainRenderObject> m_RenderObject; // Node's renderObject
TerrainNode* m_Neighbors[eNeighborCount];
TerrainNode* m_Childs[eChildCount];
TerrainNode* m_Parent;
/// Use for ray intersect
Resources::PositionData m_PositionData;
Resources::Index16Container m_IndexData;
#ifdef __GENESIS_EDITOR__
Resources::TexCoordData m_texUV;
Resources::NormalData m_normalData;
#endif
};
//inline method implement=====================================================
inline const Math::bbox& TerrainNode::GetLocalBoundingBox() const{
return m_LocalBoundingBox;
}
inline RenderBase::PrimitiveTopology::Code TerrainNode::GetPrimitiveTopology(void) const{
return RenderBase::PrimitiveTopology::TriangleList;
}
inline bool TerrainNode::IsUseBaseMap(void) const{
return m_UseBaseMap;
}
inline void TerrainNode::SetUseBaseMap(bool b){
m_UseBaseMap = b;
}
inline void TerrainNode::SetNodeDrawMode( NodeDrawMode v){
m_DrawMode = v;
}
inline NodeDrawMode TerrainNode::GetNodeDrawMode(void) const{
return m_DrawMode;
}
inline float TerrainNode::GetGeometryError(void) const{
return m_GeometryError;
}
inline void TerrainNode::SetGeometryError(float h){
m_GeometryError = h;
}
inline bool TerrainNode::HaveHole(){
return m_bHaveHole;
}
inline void TerrainNode::SetHole(bool b){
m_bHaveHole = b;
}
//------------------neighbor and parent-child relationship------------------------------------------------------
inline TerrainNode* TerrainNode::GetParentNode() const{
return m_Parent;
}
inline void TerrainNode::SetParentNode(TerrainNode* p){
m_Parent = p;
}
inline TerrainNode* TerrainNode::GetChildNode(int dir) const{
n_assert(dir >=eLeftUpChild && dir < eChildCount);
return m_Childs[dir];
}
inline void TerrainNode::SetChildNode(TerrainNode* child, int dir){
n_assert(dir >=eLeftUpChild && dir < eChildCount);
m_Childs[dir] = child;
}
inline TerrainNode* TerrainNode::GetNeighborNode(int dir) const{
n_assert(dir >=eLeftNeighbor && dir < eNeighborCount);
return m_Neighbors[dir];
}
inline void TerrainNode::SetNeighborNode(TerrainNode* neighbor, int dir){
n_assert(dir >=eLeftNeighbor && dir < eNeighborCount);
m_Neighbors[dir] = neighbor;
}
//---------------------------Render---------------------------------------------
/// Set need render
inline void TerrainNode::SetRenderEnable(bool b) {
m_RenderEnable = b;
}
inline bool TerrainNode::GetRenderEnable(void){
return m_RenderEnable;
}
inline const GPtr<TerrainRenderObject>& TerrainNode::GetRenderObject() const{
return m_RenderObject;
}
inline void TerrainNode::SetRenderObject(const GPtr<TerrainRenderObject>& renderObj){
m_RenderObject = renderObj;
}
/// Set edge's suture mask. When suture changed, call RequestBuildPritiveHandle to rebuild
inline void TerrainNode::SetEdgeMask( int mask ){
m_EdgeMask = mask;
}
inline int TerrainNode::GetEdgeMask(void) const{
return m_EdgeMask;
}
inline const RenderBase::PrimitiveHandle& TerrainNode::GetPrimitiveHandle() const{
return m_PrimitiveHandle;
}
inline void TerrainNode::RequestBuildPritiveHandle(){
m_NeedBuildHandle = true;
}
inline bool TerrainNode::IsNeedBulidPritiveHandle() const {
return m_NeedBuildHandle;
}
inline const Resources::PositionData::Elem* TerrainNode::GetPositionData() const{
if ( m_PositionData.IsEmpty() )
{
return NULL;
}
return &m_PositionData[0];
}
inline Resources::Index16Container::value_type* TerrainNode::GetIndexData() const{
if ( m_IndexData.IsEmpty() )
{
return NULL;
}
return &m_IndexData[0];
}
inline SizeT TerrainNode::GetIndexDataCount() const{
return m_IndexData.Size();
}
inline SizeT TerrainNode::GetPostionDataCount() const{
return m_PositionData.Size();
}
#ifdef __GENESIS_EDITOR__
inline const Resources::TexCoordData::Elem*
TerrainNode::GetTexCoorData() const{
if ( m_texUV.IsEmpty() )
{
return NULL;
}
return &m_texUV[0];
}
inline const Resources::NormalData::Elem*
TerrainNode::GetNormalData() const{
if ( m_normalData.IsEmpty() )
{
return NULL;
}
return &m_normalData[0];
}
#endif
}
#endif // __TerrainNode_H__