#include "StdAfx.h" #ifndef CODE_INGAME #include #include #include #include "AODiskGenerator.h" #include "Terrain.h" using namespace SceneCore; CAODiskGenerator::CAODiskGenerator(CTerrain* pkTerrain) : m_pkTerrain(pkTerrain) { assert(m_pkTerrain); m_iNumChunkX = m_pkTerrain->GetChunkNumX(); m_iNumChunkY = m_pkTerrain->GetChunkNumY(); int iNumChunks = m_iNumChunkX*m_iNumChunkY; m_aSceneDiskList = new list[iNumChunks]; m_aTerrainDiskList = new list[iNumChunks]; _GenerateDisk(m_pkTerrain); } //-------------------------------------------------------------------------- CAODiskGenerator::~CAODiskGenerator(void) { int iNumChunks = m_pkTerrain->GetChunkNumX()*m_pkTerrain->GetChunkNumY(); for (int i=0; iGenerateDisk((NiGeometry*)pkAVObject); } return true; } protected: CAODiskGenerator* m_spDiskGenerator; }; //-------------------------------------------------------------------------- /// 产生 disk void CAODiskGenerator::RecursiveFindGenerateDisk(NiAVObjectPtr pkSceneRoot) { // 遍历 pkSceneRoot 将所有 NiGeometry 的 顶点构造成 disk RecursiveGenerateDisk kFunctor(this); NiTNodeTraversal::DepthFirst_AllObjects(pkSceneRoot, kFunctor); } //-------------------------------------------------------------------------- void CAODiskGenerator::GenerateDisk(NiGeometryPtr pkGeom) { pkGeom->Update(0.0f); NiTransform kTransform = pkGeom->GetWorldTransform(); NiPoint3 kTranslate = pkGeom->GetTranslate(); NiMatrix3 kRotate = pkGeom->GetRotate(); float fScale = pkGeom->GetScale(); NiGeometryData* pkGeomData = pkGeom->GetModelData(); if (NiIsKindOf(NiTriBasedGeomData, pkGeomData)) { NiTriBasedGeomData* pkTriGeomData = (NiTriBasedGeomData*)pkGeomData; unsigned short usNumVertices = pkTriGeomData->GetVertexCount(); // 顶点数量 NiPoint3* pkVertices = pkTriGeomData->GetVertices(); // 顶点列表 NiPoint3* pkNormals = pkTriGeomData->GetNormals(); // 法线列表 if (pkNormals == NULL) // 不支持没有法线列表的模型生成 disk { //pkNormals = (NiPoint3*)NiMalloc(sizeof(NiPoint3)*usNumVertices); return; //pkNormals = pkTriGeomData->GetNormals(); } unsigned short usNumTringles = pkTriGeomData->GetTriangleCount(); vector* vert2TriList = new vector[usNumVertices]; // 顶点-三角形 对应列表 float* pTriAreaList = new float[usNumTringles]; // 三角形面积列表 // 遍历所有三角形,找出顶点和三角形的对应关系 for (unsigned short i=0; iGetTriangleIndices(i, i0, i1, i2); pTriAreaList[i] = TriangleArea(pkVertices[i0], pkVertices[i1], pkVertices[i2]); vert2TriList[i0].push_back(i); vert2TriList[i1].push_back(i); vert2TriList[i2].push_back(i); } NiTransform kWorldTransform = pkGeom->GetWorldTransform(); NiTransform kLocalTransform = pkGeom->GetLocalTransform(); NiTransform kTransform = kWorldTransform*kLocalTransform;// //kTransform.m_Rotate = kRotate; //kTransform.m_Translate = kTranslate; //kTransform.m_fScale = fScale; NiPoint3* pkWorldNromals = (NiPoint3*)NiMalloc(sizeof(NiPoint3)*usNumVertices); NiMatrix3::TransformNormals(kTransform.m_Rotate, usNumVertices, pkNormals, pkWorldNromals); // 遍历所有顶点,计算每个顶点世界坐标的位置,世界坐标中的法线,disk 的面积.将所有 disk 添加到 disk 列表中 for (unsigned short i=0; i0.01f) { // 判断 disk 所在 chunk id, 将其放到相应 list 中 int iChunkID = m_pkTerrain->GetChunkIndex(disk.kPosition); if (iChunkID>=0 && iChunkIDGetTotalSize(); const NiPoint3* pkVertices = pkTerrain->GetVertices(); const NiPoint3* pkNormals = pkTerrain->GetNormals(); const NiColorA* pkColors = pkTerrain->GetVertexColor(); float fArea = 0.5f; int iNumVertexPerRow = m_iNumChunkX*GRIDINCHUNK+1; // 遍历所有 chunk ,逐个生成 AODisks int iChunkIdx = 0; for (int i=0; iGetChunkIndex(disk.kPosition); // m_aTerrainDiskList[iChunkID].push_back(disk); //} } //-------------------------------------------------------------------------- #endif