⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 teengine.cpp

📁 海量地形数据漫游系统,对于OPENGL开发人员具有一定的参考
💻 CPP
📖 第 1 页 / 共 4 页
字号:
 * This function can be called only once and this should be done after adding * all desired objects and correctly setting the active one, after attaching * scene and HUD cameras. Repeated calls are simply ignored. */void TeEngine::initialize(){  static SbBool initialized = FALSE;  if (!initialized) {    if ( !sceneRoot || !HUDRoot || !sceneCamera || !HUDCamera         || !objectList.getLength() || !activeObject ) {      SoDebugError::post("TeEngine::initialize",                         "Some vital TeEngine's attribute is not set or there is no active object in the engine.\n\nThe application will close now.");      exit(0);    }    // schedule creation of patches below inserted objects...    for (int i=0; i<objectList.getLength(); i++)      updateGraph(objectList[i]);    // ...and force the generation    while (taskQueue.getLength()) {      if (this->genTick()) done();    }    activeObject->createHUD();    initialized = TRUE;  }}//-----------------------------------------------------------------------------/** * Time tick function of the engine. * * This function has to be called continuously by application that uses engine * in order to have chance to do its work. This function is responsible for * giving generators chance to work (it calls genTick() method) and checking * if all cameras have whole visible terain ready to render (it calls * updateGraph() for all engine objects and TeObject::timeTick() as well). * * \param delta Time elapsed since last call. */void TeEngine::timeTick(const SbTime delta){  // fps  static SbTime lastUpdate = SbTime::getTimeOfDay();  SbTime current = SbTime::getTimeOfDay();  if (current-lastUpdate >= 0.1) {    fps = 1.0f/float(delta.getValue());    lastUpdate = current;  }  // generator tick, should go first, because we don't want searching  // in patch tree and first step of generation in one timeTick call  if (taskQueue.getLength())    if (this->genTick()) done();  // update scenegraph to satisfy objects' needs, insert tasks to taskQueue  // here, after genTick() call#if 0 // Shall be this enabled? PCJohn 2005-08-27   for (int i=0; i<objectList.getLength(); i++) {    objectList[i]->timeTick(delta);    updateGraph(objectList[i]);  }#endif}//-----------------------------------------------------------------------------/** * Internal patch generator tick function. * * This method performs one TeGenerator::genStep() for the 1st task in the * queue. Process is controlled by the TeETask::TeETaskStatus values. * * \return TRUE if task finished and result is ready; done() should be called *         in this case. * * \todo Consider creating high-level "TePatchGenerator" that will do this *       work and make this function obsolete. */SbBool TeEngine::genTick(){  TePatch *p = taskQueue[0].p;  switch(taskQueue[0].status) {      case TeETask::BM0: if (!p->getBuildMap(0)) {                           p->findBuildMap(0);                           if (!p->getBuildMap(0)) {                             p->setBuildMap(0, new TeHeightMap(getBuildMapResolution()));                             switch (taskQueue[0].gm) {                               case FAULT_FORMATION: generator = &faultFormation; break;                             }                             generator->setHMap(p->getBuildMap(0));                             ((TeFaultFormation*)generator)->seed = int(taskQueue[0].p->getArea().getMin()[0] + taskQueue[0].p->getArea().getMin()[1] * 257.f);                             taskQueue[0].status = TeETask::BM0G;                           }                           else taskQueue[0].status = TeETask::BM1;                         }                         else taskQueue[0].status = TeETask::BM1;                         break;     case TeETask::BM0G: if (generator->genStep()) {                           taskQueue[0].status = TeETask::BM0F;                           switch (taskQueue[0].fm) {                               case NONE: taskQueue[0].status = TeETask::BM1; break;                             case LINEAR: generator = &linearFilter; break;                           }                           generator->setHMap(p->getBuildMap(0));                         }                         break;     case TeETask::BM0F: if (generator->genStep()) taskQueue[0].status = TeETask::BM0;                         break;      case TeETask::BM1: if (!p->getBuildMap(1)) {                           p->findBuildMap(1);                           if (!p->getBuildMap(1)) {                             p->setBuildMap(1, new TeHeightMap(getBuildMapResolution()));                             switch (taskQueue[0].gm) {                               case FAULT_FORMATION: generator = &faultFormation; break;                             }                             generator->setHMap(p->getBuildMap(1));                             ((TeFaultFormation*)generator)->seed = int(taskQueue[0].p->getArea().getMin()[0] + taskQueue[0].p->getArea().getMin()[1] * 257.f);                             taskQueue[0].status = TeETask::BM1G;                           }                           else taskQueue[0].status = TeETask::BM2;                         }                         else taskQueue[0].status = TeETask::BM2;                         break;     case TeETask::BM1G: if (generator->genStep()) {                           taskQueue[0].status = TeETask::BM1F;                           switch (taskQueue[0].fm) {                               case NONE: taskQueue[0].status = TeETask::BM2; break;                             case LINEAR: generator = &linearFilter; break;                           }                           generator->setHMap(p->getBuildMap(1));                         }                         break;     case TeETask::BM1F: if (generator->genStep()) taskQueue[0].status = TeETask::BM1;                         break;      case TeETask::BM2: if (!p->getBuildMap(2)) {                           p->findBuildMap(2);                           if (!p->getBuildMap(2)) {                             p->setBuildMap(2, new TeHeightMap(getBuildMapResolution()));                             switch (taskQueue[0].gm) {                               case FAULT_FORMATION: generator = &faultFormation; break;                             }                             generator->setHMap(p->getBuildMap(2));                             ((TeFaultFormation*)generator)->seed = int(taskQueue[0].p->getArea().getMin()[0] + taskQueue[0].p->getArea().getMin()[1] * 257.f);                             taskQueue[0].status = TeETask::BM2G;                           }                           else taskQueue[0].status = TeETask::BM3;                         }                         else taskQueue[0].status = TeETask::BM3;                         break;     case TeETask::BM2G: if (generator->genStep()) {                           taskQueue[0].status = TeETask::BM2F;                           switch (taskQueue[0].fm) {                               case NONE: taskQueue[0].status = TeETask::BM3; break;                             case LINEAR: generator = &linearFilter; break;                           }                           generator->setHMap(p->getBuildMap(2));                         }                         break;     case TeETask::BM2F: if (generator->genStep()) taskQueue[0].status = TeETask::BM2;                         break;      case TeETask::BM3: if (!p->getBuildMap(3)) {                           p->findBuildMap(3);                           if (!p->getBuildMap(3)) {                             p->setBuildMap(3, new TeHeightMap(getBuildMapResolution()));                             switch (taskQueue[0].gm) {                               case FAULT_FORMATION: generator = &faultFormation; break;                             }                             generator->setHMap(p->getBuildMap(3));                             ((TeFaultFormation*)generator)->seed = int(taskQueue[0].p->getArea().getMin()[0] + taskQueue[0].p->getArea().getMin()[1] * 257.f);                             taskQueue[0].status = TeETask::BM3G;                           }                           else taskQueue[0].status = TeETask::HM;                         }                         else taskQueue[0].status = TeETask::HM;                         break;     case TeETask::BM3G: if (generator->genStep()) {                           taskQueue[0].status = TeETask::BM3F;                           switch (taskQueue[0].fm) {                               case NONE: taskQueue[0].status = TeETask::HM; break;                             case LINEAR: generator = &linearFilter; break;                           }                           generator->setHMap(p->getBuildMap(3));                         }                         break;     case TeETask::BM3F: if (generator->genStep()) taskQueue[0].status = TeETask::HM;                         break;       case TeETask::HM: if (!p->getHMap()) p->buildHMapFromBuildMaps();                         taskQueue[0].status = TeETask::GRAPH;                         break;    case TeETask::GRAPH: p->getPatchGraph();                         taskQueue[0].status = TeETask::SEAMS;                         break;    case TeETask::SEAMS: for (int i=0; i<8; i++) {                           if (p->generateSeamMap(TePatch::Direction(i))) p->getSeamGraph(TePatch::Direction(i));                         }                         return TRUE;                         break;  }  return FALSE;}//-----------------------------------------------------------------------------/** * Tests whether the patch is already generated or not. * * Patch is specified by its center in the world-space coordinates passed * to this function in the \a patchPos argument. This is way how to * uniquely describe each patch. * * \param patchPos Position of the center of the patch in world-space. * \return TRUE if the specified patch is ready, FALSE if it isn't * * \todo Is the attribute TeEngine::patchReadyTree necessary? Try to use *       getPatch() with TePatch::DONT_CREATE policy instead. * * \sa patchReadyTree */SbBool TeEngine::isReady(SbVec2f patchPos){  return (patchReadyTree.findPoint(SbVec3f(patchPos[0],patchPos[1],0.0f)) != -1);}//-----------------------------------------------------------------------------/** * Tests whether the patch is scheduled for generating or not. * * Patch is specified by its center in the world-space coordinates passed * to this function in the \a patchPos argument. This is way how to * uniquely describe each patch. * * \param patchPos Position of the center of the patch in world-space. * \return TRUE if the specified patch is scheduled, FALSE if it isn't * * \sa schedule(), patchScheduledTree */SbBool TeEngine::isScheduled(SbVec2f patchPos){  return (patchScheduledTree.findPoint(SbVec3f(patchPos[0],patchPos[1],0.0f)) != -1);}//-----------------------------------------------------------------------------/** * Schedule generation of patch at \a patchPos. * * This function creates TeETask object, fills all its attributes and * inserts it into the TeEngine::taskQueue. To control the generation process, * modify TeEngine::currGen and TeEngine::currFilter attributes before * calling this method. * * \param patchPos Position of the center of the patch in world-space. * * \sa TeETask, setCurrGen(), setCurrFilter() */void TeEngine::schedule(SbVec2f patchPos){  TeETask task;  task.p = getPatch(patchPos);  task.patchPos = patchPos;  task.status = TeETask::BM0;  task.gm = currGen;  task.fm = currFilter;  taskQueue.append(task);  tasksInQueue++;  patchScheduledTree.addPoint(SbVec3f(patchPos[0],patchPos[1],0.0f));}//-----------------------------------------------------------------------------/** * Removes task from the queue and marks the patch as ready. * * Called after succesfull completion of each task. * * \sa taskQueue */void TeEngine::done(){  patchScheduledTree.removePoint(SbVec3f(taskQueue[0].patchPos[0],taskQueue[0].patchPos[1],0.0f));  patchReadyTree.addPoint(SbVec3f(taskQueue[0].patchPos[0],taskQueue[0].patchPos[1],0.0f));  taskQueue.remove(0);  tasksInQueue--;  patchesNum++;}//-----------------------------------------------------------------------------/** * Schedules generation of all not existing neighbours of the patch at * \a patchPos. * * Patch at \a patchPos is likely to be under camera in a few moments, so look * in scheduled and ready patches and schedule generation of all necessary * neighbours. * * Little trick is used in this method: Count from 7 backwards is here because * NORTH neighbour is represented by nr.7 and with the camera currently * pointing to the north it is good to create north neighbour as the first * one. * * \param patchPos Position of the center of the patch in world-space. * * \todo Additional logic to assure that patches will be in the queue *       in optimal order (according to the movement speed vector). This will *       make the trick mentioned above obsolete. */void TeEngine::prepareNeighbours(SbVec2f patchPos){  for (int i=7; i>=0; i--) {

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -