DLA-Fire-Prediction-Thesis 1.0
|
00001 //---------------------------------------------------------------------------------------------------------------------- 00004 //---------------------------------------------------------------------------------------------------------------------- 00005 00006 #include "FirePath.h" 00007 00008 #include "ngl/Obj.h" 00009 #include "ngl/ShaderManager.h" 00010 #include "ngl/TransformStack.h" 00011 #include "ngl/Vector.h" 00012 #include "ngl/VBOPrimitives.h" 00013 00014 #include "DLAStructure.h" 00015 #include "FuelObject.h" 00016 #include "FuelPoint.h" 00017 #include "GLWindow.h" 00018 00019 //---------------------------------------------------------------------------------------------------------------------- 00020 FirePath::FirePath( 00021 std::vector<FuelPoint> _allDLAList, 00022 std::vector<FuelPoint> _allDLALine, 00023 std::vector<FuelPoint> _fuelList, 00024 float _approxObjMoisture, 00025 std::vector<FuelPoint> _originList, 00026 bool _windStatus, 00027 int _windSpeed, 00028 ngl::Vector _windDirection 00029 ) 00030 { 00031 m_fireDLAForm = _allDLAList; 00032 m_fireDLALine = _allDLALine; 00033 m_gridList = _fuelList; 00034 m_originList = _originList; 00035 00036 std::vector<FuelPoint> m_emptyList; 00037 m_fuelOnGridList = m_emptyList; 00038 00039 for(unsigned int q=0; q<m_gridList.size(); ++q) 00040 { 00041 FuelPoint m_gridPoint = m_gridList[q]; 00042 00043 m_gridPoint.setGridIndex(q); 00044 00045 if(m_gridPoint.isFuel()==true) 00046 m_fuelOnGridList.push_back(m_gridPoint); 00047 } 00048 00049 // set the fuel to be not burning first 00050 for(unsigned int m=0; m<m_fuelOnGridList.size(); ++m) 00051 { 00052 FuelPoint m_fuelPoint = m_fuelOnGridList[m]; 00053 ngl::Vector m_fuelPointColour = m_fuelPoint.getColour(); 00054 00055 ngl::Vector m_newColour = ngl::Vector(m_fuelPointColour.m_y, m_fuelPointColour.m_x, m_fuelPointColour.m_z); 00056 m_fuelPoint.changeColour(m_newColour); 00057 00058 m_fuelOnGridList[m] = m_fuelPoint; 00059 } 00060 00061 m_originalFuelOnGridList = m_fuelOnGridList; 00062 00063 m_currentDLAPointIndex = 1; 00064 m_sceneMoisture = 15.0; 00065 m_sceneTemp = 23.0; 00066 m_rateOfGrowth = 0.5; 00067 m_objMoisture = _approxObjMoisture; 00068 m_timeStep = 0; 00069 m_pause = false; 00070 m_onlyLine = true; 00071 00072 // wind variables 00073 m_windEnable = _windStatus; 00074 m_windSpeed = _windSpeed; 00075 m_windDirection = _windDirection; 00076 00077 // get maximum generation 00078 int m_generationCounter=0; 00079 for(unsigned int k=0; k<m_fireDLAForm.size(); ++k) 00080 { 00081 FuelPoint m = m_fireDLAForm[k]; 00082 if(m_generationCounter<m.getGeneration()) 00083 m_generationCounter = m.getGeneration(); 00084 } 00085 00086 for(unsigned int j=0; j<m_originList.size(); ++j) 00087 { 00088 FuelPoint m_origin = m_originList[j]; 00089 m_origin.setGeneration(m_generationCounter); 00090 m_originList[j] = m_origin; 00091 } 00092 00093 m_currentIndexForm.push_back(FuelPoint(ngl::Vector(m_currentDLAPointIndex, 0, m_fireDLAForm.size()-1,0), 0)); 00094 00095 setFirePath(); 00096 m_allShow = false; 00097 } 00098 00099 //---------------------------------------------------------------------------------------------------------------------- 00100 void FirePath::setNewOriginList(std::vector<FuelPoint> _newOriginList) 00101 { 00102 m_originList = _newOriginList; 00103 00104 std::vector<FuelPoint> m_empty; 00105 m_currentIndexForm = m_empty; 00106 00107 for(unsigned int q=0; q<m_originList.size(); ++q) 00108 { 00109 FuelPoint m_renewOrigin = m_originList[q]; 00110 ngl::Vector m_renew = m_renewOrigin.getPosition(); 00111 00112 int m_startIndex = 0; 00113 int m_lastIndex = m_renewOrigin.getEmittedHeat()-1; 00114 00115 // size for limiting the range of collecting total time that requires for burning 00116 if(q>0) 00117 { 00118 // get the start and last index 00119 for(unsigned int p=0; p<q; ++p) 00120 { 00121 //ngl::Vector m_previousSize = m_currentIndexForm[p]; 00122 m_lastIndex += m_renewOrigin.getEmittedHeat(); 00123 00124 FuelPoint m_previousOrigin = m_originList[p]; 00125 m_startIndex += m_previousOrigin.getEmittedHeat(); 00126 } 00127 } 00128 00129 m_renew.m_x = 1; // current generation 00130 m_renew.m_y = m_startIndex; // current index 00131 m_renew.m_z = m_lastIndex; // last index 00132 m_renew.m_w = m_startIndex; // start index 00133 00134 if(q==0) 00135 m_renew.m_w = 0; 00136 00137 m_currentIndexForm.push_back(FuelPoint(m_renew,0)); 00138 } 00139 } 00140 00141 //---------------------------------------------------------------------------------------------------------------------- 00142 void FirePath::assignNewObjMoisture(float _newObjMoisture) 00143 { 00144 m_objMoisture = _newObjMoisture; 00145 00146 for(unsigned int m=0; m<m_fuelOnGridList.size(); ++m) 00147 { 00148 FuelPoint m_fuelPoint = m_fuelOnGridList[m]; 00149 m_fuelPoint.setNewMoisture(m_objMoisture); 00150 m_fuelOnGridList[m] = m_fuelPoint; 00151 } 00152 } 00153 00154 //---------------------------------------------------------------------------------------------------------------------- 00155 void FirePath::setFirePath() 00156 { 00157 for(unsigned int g=0; g<m_fireDLAForm.size(); ++g) 00158 { 00159 FuelPoint m_firePathPoint = m_fireDLAForm[g]; 00160 m_firePathPoint.setNewMoisture(m_sceneMoisture/100); 00161 int m_burningTime = m_firePathPoint.getBurningTime(); 00162 m_firePathPoint.setEmittedHeat(1500+(m_burningTime*100)); 00163 m_fireDLAForm[g] = m_firePathPoint; 00164 } 00165 00166 calculateRateOfGrowth(); 00167 } 00168 00169 //---------------------------------------------------------------------------------------------------------------------- 00170 void FirePath::resetList() 00171 { 00172 std::vector<FuelPoint> m_emptyList; 00173 m_fireDLAForm = m_emptyList; 00174 m_fireDLALine = m_emptyList; 00175 00176 m_timeStep = 0; 00177 m_currentDLAPointIndex = 0; 00178 m_allShow = false; 00179 m_rateOfGrowth = 0.5; 00180 00181 assignNewObjMoisture(m_objMoisture); 00182 setFirePath(); 00183 } 00184 00185 //---------------------------------------------------------------------------------------------------------------------- 00186 void FirePath::timeUpdate(int _time) 00187 { 00188 int m_newTime = _time; 00189 00190 analyzeDLAAmount(m_newTime); 00191 00192 // check burning area that attacks with fuel object and area or not 00193 analyzeBurningArea(); 00194 00195 controlFirePathColour(); 00196 } 00197 00198 //---------------------------------------------------------------------------------------------------------------------- 00199 void FirePath::analyzeDLAAmount(int m_newTime) 00200 { 00201 for(unsigned int n=0; n<m_currentIndexForm.size(); ++n) 00202 { 00203 FuelPoint m_pointCurrent = m_currentIndexForm[n]; 00204 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00205 int m_startIndex = m_currentForm.m_w; 00206 int m_currentGeneration = m_currentForm.m_x; 00207 int m_currentIndex = m_currentForm.m_y; 00208 int m_lastIndexOfTheForm = m_currentForm.m_z; 00209 00210 int m_genTotalTime = 0; 00211 int m_startTime = 25*n; 00212 00213 for(unsigned int i=m_startIndex ;i<m_currentIndex; ++i) 00214 { 00215 FuelPoint m_firePoint = m_fireDLAForm[i]; 00216 int m_theBurningTime = m_firePoint.getBurningTime(); 00217 m_genTotalTime += m_theBurningTime; 00218 } // end for within the range 00219 00220 if((m_genTotalTime<=m_newTime)&&(m_currentIndex<m_lastIndexOfTheForm)&&(m_startTime<m_newTime)) 00221 { 00222 ++m_currentIndex; 00223 m_currentForm.m_y = m_currentIndex; 00224 m_pointCurrent.setPosition(m_currentForm); 00225 m_currentIndexForm[n] = m_pointCurrent; 00226 m_allShow = false; 00227 } 00228 else if(m_currentIndex>=m_lastIndexOfTheForm) 00229 { 00230 m_allShow = true; 00231 } 00232 00233 // assign burning area, according to the time 00234 /* for(unsigned int f=m_startIndex; f<m_currentIndex; ++f) 00235 { 00236 FuelPoint m_firePoint = m_fireDLAForm[f]; 00237 int m_recentForm = m_firePoint.getBurningFormNumber(); 00238 m_firePoint.setGridIndex(f); 00239 if(m_recentForm<0) 00240 m_firePoint.setBurningFormNumber(n); 00241 00242 bool m_isDraw = m_firePoint.canDraw(); 00243 00244 if(m_isDraw==true) 00245 m_burningPointList.push_back(m_firePoint); 00246 }*/ 00247 00248 } // end for loop of form number 00249 } 00250 00251 //---------------------------------------------------------------------------------------------------------------------- 00252 int FirePath::getIndexNumber(ngl::Vector m_position) 00253 { 00254 int m_index = 0; 00255 00256 for(unsigned int j=0; j<m_fireDLAForm.size(); ++j) 00257 { 00258 FuelPoint m_point = m_fireDLAForm[j]; 00259 ngl::Vector m_pointPosition = m_point.getPosition(); 00260 00261 if((m_pointPosition.m_x==m_position.m_x)&&(m_pointPosition.m_z==m_position.m_z)) 00262 m_index = j; 00263 } 00264 00265 return m_index; 00266 } 00267 00268 //---------------------------------------------------------------------------------------------------------------------- 00269 bool FirePath::checkCollisionWithBurningArea(ngl::Vector m_currentPos) 00270 { 00271 bool m_isCollided = false; 00272 00273 int m_minIndex = 0; 00274 float m_minDist = 10000.0; 00275 00276 for(unsigned int j=0; j<m_gridList.size(); ++j) 00277 { 00278 FuelPoint m_burningPoint = m_gridList[j]; 00279 ngl::Vector m_burningPos = m_burningPoint.getPosition(); 00280 00281 ngl::Vector m_delta = m_burningPos - m_currentPos; 00282 float m_distance = m_delta.length(); 00283 00284 if(m_distance<m_minDist) 00285 { 00286 m_minDist = m_distance; 00287 m_minIndex = j; 00288 } 00289 } 00290 00291 FuelPoint m_groundPoint = m_gridList[m_minIndex]; 00292 00293 if(m_groundPoint.isFlammable()==false) 00294 { 00295 m_isCollided = true; 00296 } // end if its burning 00297 00298 /* // check with surrounding burning area with the distance and the fire area of object 00299 ngl::Vector m_checkingGrondPos = m_groundPoint.getPosition(); 00300 00301 for(unsigned int k=0; k<m_gridList.size(); ++k) 00302 { 00303 if(k!=(unsigned)m_minIndex) 00304 { 00305 FuelPoint m_surroundGroundPoint = m_gridList[k]; 00306 ngl::Vector m_surroundGroundPos = m_surroundGroundPoint.getPosition(); 00307 00308 if((m_surroundGroundPoint.isBurning()==true)&&(m_surroundGroundPoint.isFuel()==true)) 00309 { 00310 if((m_surroundGroundPoint.getBurningFormNumber()<0)||(m_surroundGroundPoint.getBurningFormNumber()!=m_currentFormNumber)) 00311 { 00312 ngl::Vector m_deltaDistance = m_surroundGroundPos - m_checkingGrondPos; 00313 float m_farDistance = m_deltaDistance.length(); 00314 00315 if(m_farDistance<=0.3) 00316 m_isCollided = true; 00317 } // end if it is in the fuel object area 00318 } // end if it is burning 00319 } // end if the duplicate index number 00320 } 00321 */ 00322 return m_isCollided; 00323 } 00324 00325 //---------------------------------------------------------------------------------------------------------------------- 00326 void FirePath::showFireLineOnly( 00327 bool _showingLineOnlyStatus 00328 ) 00329 { 00330 m_onlyLine = _showingLineOnlyStatus; 00331 } 00332 00333 //---------------------------------------------------------------------------------------------------------------------- 00334 void FirePath::drawDLAPath( 00335 const std::string &_shaderName, 00336 ngl::TransformStack &_transformStack 00337 ) 00338 { 00339 ngl::ShaderManager *shader=ngl::ShaderManager::instance(); 00340 ngl::VBOPrimitives *prim=ngl::VBOPrimitives::instance(); 00341 00342 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00343 { 00344 00345 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00346 ngl::Vector m_currentForm = m_pointCurrent.getPosition();//m_currentIndexForm[a]; 00347 int m_startIndex = m_currentForm.m_w; 00348 int m_currentGeneration = m_currentForm.m_x; 00349 int m_currentIndex = m_currentForm.m_y; 00350 int m_lastIndexOfTheForm = m_currentForm.m_z; 00351 00352 std::vector<FuelPoint> m_emptyList; 00353 m_burningPointList = m_emptyList; 00354 00355 for(unsigned int i=m_startIndex; i<m_currentIndex; ++i) 00356 { 00357 FuelPoint m_drawingPoint = m_fireDLAForm[i]; 00358 ngl::Vector m_drawingPointPos = m_drawingPoint.getPosition(); 00359 //if(m_drawingPoint.canDraw()) 00360 { 00361 bool m_collision = false;//checkCollisionWithBurningArea(m_drawingPointPos,a);//,q); 00362 00363 if(m_collision==false) 00364 { 00365 (*shader)[_shaderName]->use(); 00366 shader->setShaderParamFromMatrix(_shaderName,"ModelMatrix",_transformStack.getCurrAndGlobal().getMatrix()); 00367 00368 // ----- set colour to each point 00369 ngl::Vector m_drawingColour = m_drawingPoint.getColour();//ngl::Vector(1.0,2.0,1.0);//ngl::Vector(1.0,2.0,0.0); 00370 shader->setShaderParam4f(_shaderName,_shaderName,m_drawingColour.m_x,m_drawingColour.m_y,m_drawingColour.m_z,1.0); 00371 00372 glLineWidth(3.0); 00373 // ----- draw line 00374 glBegin(GL_LINES); 00375 00376 glVertex3f(m_drawingPointPos.m_x, m_drawingPointPos.m_y+0.02, m_drawingPointPos.m_z); 00377 // int m_lineIndex = getIndexNumber(m_pointPosition); 00378 FuelPoint m_drawingHPoint = m_fireDLALine[i];//m_fireDLALine[m_lineIndex];//m_fireDLALine[q];// 00379 ngl::Vector m_drawingHPointPos = m_drawingHPoint.getPosition(); 00380 glVertex3f(m_drawingHPointPos.m_x, m_drawingHPointPos.m_y+0.02, m_drawingHPointPos.m_z); 00381 00382 glEnd(); 00383 00384 // add to burning point list , thus the program would know the current drawing spot 00385 // if(i>=m_burningPointList.size()) 00386 // m_burningPointList.push_back(m_drawingPoint); 00387 00388 // ----- burning area drawing 00389 if(m_onlyLine==false) 00390 { 00391 float m_yHPos = m_drawingHPointPos.m_y; 00392 float m_yPos = m_drawingPointPos.m_y; 00393 00394 if(m_drawingHPointPos.m_y<m_drawingPointPos.m_y) 00395 { 00396 m_drawingHPointPos.m_x += 0.18; 00397 m_drawingHPointPos.m_z += 0.18; 00398 00399 m_drawingPointPos.m_x -= 0.18; 00400 m_drawingPointPos.m_z -=0.18; 00401 00402 float m_tempYPos = m_yPos; 00403 m_yPos = m_yHPos; 00404 m_yHPos = m_tempYPos; 00405 } 00406 else 00407 { 00408 m_drawingHPointPos.m_x -= 0.18; 00409 m_drawingHPointPos.m_z -= 0.18; 00410 00411 m_drawingPointPos.m_x += 0.18; 00412 m_drawingPointPos.m_z +=0.18; 00413 } 00414 00415 ngl::Vector m_head = ngl::Vector(m_drawingHPointPos.m_x, m_yHPos ,m_drawingPointPos.m_z ); 00416 ngl::Vector m_tail = ngl::Vector(m_drawingPointPos.m_x, m_yPos , m_drawingHPointPos.m_z); 00417 00418 bool m_collideWithNonFlammableAreaH = checkCollisionWithBurningArea(m_head); 00419 bool m_collideWithNonFlammableAreaT = checkCollisionWithBurningArea(m_tail); 00420 00421 bool m_drawHeatTransferring = true; 00422 00423 if((m_head.m_x<0.49)&&(m_head.m_x>-0.49)&&(m_tail.m_x<0.49)&&(m_tail.m_x>-0.49)&&(m_head.m_z<0.49)&&(m_head.m_z>-0.49)&&(m_tail.m_z<0.49)&&(m_tail.m_z>-0.49)) 00424 m_drawHeatTransferring = true; 00425 00426 if((m_collideWithNonFlammableAreaH==true)||(m_collideWithNonFlammableAreaT==true)) 00427 m_drawHeatTransferring = false; 00428 00429 if(m_drawHeatTransferring==true) 00430 { 00431 glBegin(GL_QUADS); 00432 glVertex3f( m_drawingHPointPos.m_x, m_drawingHPointPos.m_y-0.02, m_drawingHPointPos.m_z); 00433 glVertex3f( m_head.m_x, m_head.m_y-0.02, m_head.m_z); 00434 glVertex3f( m_drawingPointPos.m_x, m_drawingPointPos.m_y-0.02, m_drawingPointPos.m_z); 00435 glVertex3f( m_tail.m_x, m_tail.m_y-0.02, m_tail.m_z); 00436 glEnd(); 00437 } 00438 00439 } // end if only line would show 00440 } 00441 } 00442 } 00443 } // end for loop of numbers of dla form 00444 } 00445 00446 //---------------------------------------------------------------------------------------------------------------------- 00447 void FirePath::updateDLAList(std::vector<FuelPoint> _allDLAList, std::vector<FuelPoint> _allDLALine) 00448 { 00449 resetList(); 00450 m_fireDLAForm = _allDLAList; 00451 m_fireDLALine = _allDLALine; 00452 m_fuelOnGridList = m_originalFuelOnGridList; 00453 m_currentDLAPointIndex = 0; 00454 m_sceneMoisture = 15.0; 00455 m_sceneTemp = 23.0; 00456 m_allShow = false; 00457 m_rateOfGrowth = 0.5; 00458 00459 assignNewObjMoisture(m_objMoisture); 00460 } 00461 00462 //---------------------------------------------------------------------------------------------------------------------- 00463 void FirePath::resetGrid(std::vector<FuelPoint> _currentGridPoint) 00464 { 00465 m_gridList = _currentGridPoint; 00466 } 00467 00468 //---------------------------------------------------------------------------------------------------------------------- 00469 void FirePath::updateFuelOnGrid(std::vector<FuelPoint> _fuelOnGridList) 00470 { 00471 resetList(); 00472 00473 m_gridList = _fuelOnGridList; 00474 00475 std::vector<FuelPoint> m_emptyList; 00476 m_fuelOnGridList = m_emptyList; 00477 00478 for(unsigned int q=0; q<m_gridList.size(); ++q) 00479 { 00480 FuelPoint m_gridPoint = m_gridList[q]; 00481 00482 m_gridPoint.setGridIndex(q); 00483 00484 if(m_gridPoint.isFuel()==true) 00485 m_fuelOnGridList.push_back(m_gridPoint); 00486 } 00487 00488 resetFuel(); 00489 assignNewObjMoisture(m_objMoisture); 00490 00491 } 00492 00493 //---------------------------------------------------------------------------------------------------------------------- 00494 void FirePath::resetFuel() 00495 { 00496 // set the fuel to be not burning first 00497 for(unsigned int m=0; m<m_fuelOnGridList.size(); ++m) 00498 { 00499 FuelPoint m_fuelPoint = m_fuelOnGridList[m]; 00500 ngl::Vector m_fuelPointColour = m_fuelPoint.getColour(); 00501 00502 ngl::Vector m_newColour = ngl::Vector(m_fuelPointColour.m_y, m_fuelPointColour.m_x, m_fuelPointColour.m_z); 00503 m_fuelPoint.changeColour(m_newColour); 00504 00505 m_fuelOnGridList[m] = m_fuelPoint; 00506 } 00507 00508 m_originalFuelOnGridList = m_fuelOnGridList; 00509 } 00510 00511 //---------------------------------------------------------------------------------------------------------------------- 00512 std::vector<FuelPoint> FirePath::getCurrentFuelList() 00513 { 00514 return m_fuelOnGridList; 00515 } 00516 00517 //---------------------------------------------------------------------------------------------------------------------- 00518 void FirePath::resetFuelListToOriginal() 00519 { 00520 m_fuelOnGridList = m_originalFuelOnGridList; 00521 m_currentDLAPointIndex = 0; 00522 m_rateOfGrowth = 0.5; 00523 m_allShow = false; 00524 00525 setFirePath(); 00526 } 00527 00528 //---------------------------------------------------------------------------------------------------------------------- 00529 // if temperature has changed, the burning time would be adjusted for 0.02 unit 00530 void FirePath::assignNewTemp(double _newTemp) 00531 { 00532 if(_newTemp<m_sceneTemp) 00533 { 00534 double m_deltaTemp = m_sceneTemp - _newTemp; 00535 float m_stepCount = 0.25; 00536 float m_gainingValue = 0.0; 00537 00538 if(m_deltaTemp<0) 00539 m_deltaTemp *= -1; 00540 00541 // step size 00542 m_gainingValue = 0.1*(m_deltaTemp/m_stepCount); 00543 00544 // fire burning time 00545 // make the fire speed slower 00546 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00547 { 00548 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00549 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00550 int m_currentSize = m_currentForm.m_y; 00551 int m_lastIndexOfTheForm = m_currentForm.m_z; 00552 00553 for(int b=m_currentSize; b<m_lastIndexOfTheForm; ++b) 00554 { 00555 FuelPoint m_point = m_fireDLAForm[b]; 00556 float m_currentBurningTime = m_point.getBurningTime(); 00557 00558 m_currentBurningTime += m_gainingValue; 00559 00560 if(m_currentBurningTime>25) 00561 m_currentBurningTime = 25; 00562 00563 m_point.setBurningTime(m_currentBurningTime); 00564 00565 // ----- set new moisture of each point 00566 float m_currentPointMoisture = m_point.getMoisture(); 00567 m_currentPointMoisture += m_gainingValue/100; 00568 m_point.setNewMoisture(m_currentPointMoisture); 00569 00570 m_fireDLAForm[b] = m_point; 00571 } 00572 } // end for loop of numbers of dla form 00573 00574 // adjust rate of growth 00575 m_rateOfGrowth -= m_deltaTemp/500; 00576 00577 } 00578 else if(_newTemp>m_sceneTemp) 00579 { 00580 double m_deltaTemp = m_sceneTemp - _newTemp; 00581 float m_stepCount = 0.25; 00582 float m_gainingValue = 0.0; 00583 00584 if(m_deltaTemp<0) 00585 m_deltaTemp *= -1; 00586 00587 // step size 00588 m_gainingValue = 0.1*(m_deltaTemp/m_stepCount); 00589 00590 // fire burning time 00591 // make the fire speed faster 00592 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00593 { 00594 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00595 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00596 int m_currentSize = m_currentForm.m_y; 00597 int m_lastIndexOfTheForm = m_currentForm.m_z; 00598 00599 for(int b=m_currentSize; b<m_lastIndexOfTheForm; ++b) 00600 { 00601 FuelPoint m_point = m_fireDLAForm[b]; 00602 float m_currentBurningTime = m_point.getBurningTime(); 00603 00604 m_currentBurningTime -= m_gainingValue; 00605 00606 if(m_currentBurningTime<0) 00607 m_currentBurningTime = 1; 00608 00609 m_point.setBurningTime(m_currentBurningTime); 00610 00611 // ----- set new moisture of each point 00612 float m_currentPointMoisture = m_point.getMoisture(); 00613 m_currentPointMoisture -= m_gainingValue/100; 00614 m_point.setNewMoisture(m_currentPointMoisture); 00615 00616 m_fireDLAForm[b] = m_point; 00617 } 00618 } // end for loop of numbers of dla form 00619 00620 // adjust rate of growth 00621 m_rateOfGrowth += m_deltaTemp/500; 00622 00623 } // end if-else the increasing and decreasing temperature occurs 00624 00625 m_sceneTemp = _newTemp; 00626 } 00627 00628 //---------------------------------------------------------------------------------------------------------------------- 00629 // 00630 void FirePath::assignNewMoisture(double _newMoisture) 00631 { 00632 if(_newMoisture<m_sceneMoisture) 00633 { 00634 double m_deltaMoisture = m_sceneMoisture - _newMoisture; 00635 float m_stepCount = 0.25; 00636 float m_gainingValue = 0.0; 00637 00638 if(m_deltaMoisture<0) 00639 m_deltaMoisture *= -1; 00640 00641 // step size 00642 m_gainingValue = 0.5*(m_deltaMoisture/m_stepCount); 00643 00644 // fire burning time 00645 // make the fire speed faster 00646 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00647 { 00648 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00649 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00650 int m_currentSize = m_currentForm.m_y; 00651 int m_lastIndexOfTheForm = m_currentForm.m_z; 00652 00653 for(int b=m_currentSize; b<m_lastIndexOfTheForm; ++b) 00654 { 00655 FuelPoint m_point = m_fireDLAForm[b]; 00656 float m_currentBurningTime = m_point.getBurningTime(); 00657 00658 m_currentBurningTime -= m_gainingValue; 00659 00660 if(m_currentBurningTime<0) 00661 m_currentBurningTime = 1; 00662 00663 m_point.setBurningTime(m_currentBurningTime); 00664 00665 // ----- set new moisture of each point 00666 float m_currentPointMoisture = m_point.getMoisture(); 00667 m_currentPointMoisture -= m_gainingValue/100; 00668 m_point.setNewMoisture(m_currentPointMoisture); 00669 00670 m_fireDLAForm[b] = m_point; 00671 } 00672 } // end for loop of numbers of dla form 00673 00674 // adjust rate of growth 00675 m_rateOfGrowth += m_deltaMoisture/100; 00676 00677 if(m_rateOfGrowth>1.0) 00678 m_rateOfGrowth = 0.9; 00679 else if(m_rateOfGrowth<0.0) 00680 m_rateOfGrowth = 0.1; 00681 } 00682 else if(_newMoisture>m_sceneMoisture) 00683 { 00684 double m_deltaMoisture = m_sceneMoisture - _newMoisture; 00685 float m_stepCount = 0.25; 00686 float m_gainingValue = 0.0; 00687 00688 if(m_deltaMoisture<0) 00689 m_deltaMoisture *= -1; 00690 00691 m_gainingValue = 0.25*(m_deltaMoisture/m_stepCount); 00692 00693 // fire burning time 00694 // make the fire speed slower 00695 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00696 { 00697 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00698 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00699 int m_currentSize = m_currentForm.m_y; 00700 int m_lastIndexOfTheForm = m_currentForm.m_z; 00701 00702 for(int b=m_currentSize; b<m_lastIndexOfTheForm; ++b) 00703 { 00704 FuelPoint m_point = m_fireDLAForm[b]; 00705 float m_currentBurningTime = m_point.getBurningTime(); 00706 00707 m_currentBurningTime += m_gainingValue; 00708 00709 if(m_currentBurningTime>25) 00710 m_currentBurningTime = 25; 00711 00712 m_point.setBurningTime(m_currentBurningTime); 00713 00714 // ----- set new moisture of each point 00715 float m_currentPointMoisture = m_point.getMoisture(); 00716 m_currentPointMoisture += m_gainingValue/100; 00717 m_point.setNewMoisture(m_currentPointMoisture); 00718 00719 m_fireDLAForm[b] = m_point; 00720 } 00721 } // end for loop of numbers of dla form 00722 00723 // adjust rate of growth 00724 m_rateOfGrowth -= m_deltaMoisture/100; 00725 00726 if(m_rateOfGrowth>1.0) 00727 m_rateOfGrowth = 0.9; 00728 else if(m_rateOfGrowth<0.0) 00729 m_rateOfGrowth = 0.1; 00730 } // end if-else moisture changes 00731 00732 m_sceneMoisture = _newMoisture; 00733 } 00734 00735 //---------------------------------------------------------------------------------------------------------------------- 00736 // More Fuel, more time to burn but faster the speed rate 00737 // More moisture, more time to ignite the fuel but the speed rate remains the same 00738 // More slope, higher rate of growth 00739 // More dried fuel object, higher rate of growth 00740 // No wind, higher rate of growth 00741 void FirePath::calculateRateOfGrowth() 00742 { 00743 // calculate with slope 00744 float m_burningTimePrefer = m_fireDLAForm.size()*10; 00745 float m_burningTimeTotal = 0; 00746 00747 for(unsigned int t=0; t<m_fireDLAForm.size(); ++t) 00748 { 00749 FuelPoint m_dlaPoint = m_fireDLAForm[t]; 00750 float m_bTime= m_dlaPoint.getBurningTime(); 00751 00752 m_burningTimeTotal += m_bTime; 00753 } 00754 00755 float m_diffTime = (m_burningTimePrefer - m_burningTimeTotal)/10000; 00756 00757 m_rateOfGrowth = m_rateOfGrowth + m_diffTime; 00758 00759 if(m_rateOfGrowth>1.0) 00760 m_rateOfGrowth = 0.9; 00761 else if(m_rateOfGrowth<0.0) 00762 m_rateOfGrowth = 0.1; 00763 } 00764 00765 //---------------------------------------------------------------------------------------------------------------------- 00766 void FirePath::analyzeBurningArea() 00767 { 00768 // checking with current burning point list 00769 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00770 { 00771 FuelPoint m_pointCurrent = m_currentIndexForm[a]; 00772 ngl::Vector m_currentForm = m_pointCurrent.getPosition(); 00773 int m_startIndex = m_currentForm.m_w; 00774 int m_currentIndex = m_currentForm.m_y; 00775 00776 for(unsigned int i=m_startIndex; i<m_currentIndex; ++i) 00777 { 00778 FuelPoint m_gridPoint = m_fireDLAForm[i]; 00779 int m_recentForm = a; 00780 00781 // ----- analyze fuel object 00782 for(unsigned int x=0; x<m_fuelOnGridList.size(); ++x) 00783 { 00784 FuelPoint m_fuelPoint = m_fuelOnGridList[x]; 00785 ngl::Vector m_fuelPointPos = m_fuelPoint.getPosition(); 00786 00787 ngl::Vector m_gridPointPos = m_gridPoint.getPosition(); 00788 00789 m_gridPointPos.m_y = 0.0; 00790 m_fuelPointPos.m_y = 0.0; 00791 00792 ngl::Vector m_distanceVector = m_gridPointPos - m_fuelPointPos; 00793 float m_burningDistance = m_distanceVector.length(); 00794 float m_fuelMoisture = m_fuelPoint.getMoisture(); 00795 float m_fuelAmount = m_fuelPoint.getCurrentFuelValue(); 00796 00797 if(m_burningDistance<0.3) 00798 { 00799 // ----- emitting heat 00800 m_fuelPoint.setEmittedHeat(m_fuelAmount*20); 00801 m_fuelPoint.setFire(); 00802 00803 if(m_fuelMoisture>0.25) 00804 m_fuelMoisture -= 0.01; 00805 else 00806 m_fuelMoisture = 0.25; 00807 00808 m_fuelPoint.setNewMoisture(m_fuelMoisture); 00809 00810 // the transparency needs to be lower than 0.25 before loosing the fuel 00811 if(m_fuelMoisture<=0.25) 00812 { 00813 m_fuelPoint.subtractFuel(0.05*m_rateOfGrowth); 00814 } 00815 m_fuelPoint.setBurningFormNumber(m_recentForm); 00816 00817 bool m_checkBurntStatus = m_fuelPoint.isBurningDown(); 00818 if(m_checkBurntStatus==false) 00819 { 00820 ngl::Vector m_firePathColour = m_gridPoint.getColour(); 00821 //m_firePathColour.m_x = m_fuelAmount/100; 00822 m_fuelPoint.changeColour(m_firePathColour); 00823 00824 } 00825 00826 m_fuelPoint.setBurningFormNumber(i); 00827 m_fuelOnGridList[x] = m_fuelPoint; 00828 00829 } // end if burning distance 00830 } 00831 } // end for loop of generation 00832 } // end for loop of dla form 00833 00834 // ----- check within the fuel list 00835 for(unsigned int j=0; j<m_fuelOnGridList.size();++j) 00836 { 00837 FuelPoint m_burnFuelPoint = m_fuelOnGridList[j]; 00838 float m_burningMoisture = m_burnFuelPoint.getMoisture(); 00839 float m_fuelAmount = m_burnFuelPoint.getCurrentFuelValue(); 00840 int m_closestFirePathIndex = m_burnFuelPoint.getBurningFormNumber(); 00841 00842 if(m_burnFuelPoint.isBurning()==true) 00843 { 00844 // ----- if sorrounding fuel is not burn yet 00845 m_burnFuelPoint.setEmittedHeat(m_fuelAmount*20); 00846 m_burnFuelPoint.setFire(); 00847 00848 if(m_burningMoisture>0.25) 00849 m_burningMoisture -= 0.005; 00850 else 00851 m_burningMoisture = 0.25; 00852 00853 m_burnFuelPoint.setNewMoisture(m_burningMoisture); 00854 00855 // the transparency needs to be lower than 0.25 before loosing the fuel 00856 if(m_burningMoisture<=0.25) 00857 { 00858 float m_subtractValue = 0.05; 00859 00860 ngl::Vector m_pos = m_burnFuelPoint.getPosition(); 00861 FuelPoint m_g = m_gridList[m_pos.m_w]; 00862 00863 if(m_fuelAmount>0.0) 00864 m_burnFuelPoint.subtractFuel(m_subtractValue); 00865 else 00866 m_burnFuelPoint.setFuelAmount(0.0); 00867 00868 // find the closest fire path 00869 FuelPoint m_getClosestFirePath = m_fireDLAForm[m_closestFirePathIndex]; 00870 bool m_checkBurntStatus = m_getClosestFirePath.isBurningDown(); 00871 if(m_checkBurntStatus==false) 00872 { 00873 ngl::Vector m_firePathColour = m_getClosestFirePath.getColour(); 00874 m_burnFuelPoint.changeColour(m_firePathColour); 00875 } 00876 00877 } 00878 m_fuelOnGridList[j] = m_burnFuelPoint; 00879 } 00880 00881 if(m_burningMoisture<=0.25) 00882 { 00883 int m_recentForm = m_burnFuelPoint.getBurningFormNumber(); 00884 for(unsigned int s = 0; s<m_fuelOnGridList.size(); ++s) 00885 { 00886 if(s!=j) 00887 { 00888 FuelPoint m_surroundingPoint = m_fuelOnGridList[s]; 00889 ngl::Vector m_fuelPos = m_burnFuelPoint.getPosition(); 00890 ngl::Vector m_surroundPos = m_surroundingPoint.getPosition(); 00891 ngl::Vector m_distScene = m_fuelPos - m_surroundPos; 00892 float m_posDistance = m_distScene.length(); 00893 float m_fAmount = m_surroundingPoint.getCurrentFuelValue(); 00894 00895 // ----- if the surround object 00896 if(m_posDistance<=0.25) 00897 { 00898 if(m_surroundingPoint.isBurning()==false) 00899 { 00900 // ----- if sorrounding fuel is not burn yet 00901 m_surroundingPoint.setEmittedHeat(m_fAmount*20); 00902 m_surroundingPoint.setFire(); 00903 00904 m_surroundingPoint.setBurningFormNumber(m_recentForm); 00905 m_surroundingPoint.setBurningFormNumber(m_closestFirePathIndex); 00906 00907 m_fuelOnGridList[s] = m_surroundingPoint; 00908 00909 int m_groundPointIndex = m_surroundingPoint.getGridIndex();//m_surroundPos.m_w; 00910 FuelPoint m_groundPoint = m_gridList[m_groundPointIndex]; 00911 m_groundPoint.setFire(); 00912 00913 // input the form number if it is not already taken 00914 if(m_recentForm<=-10) 00915 m_groundPoint.setBurningFormNumber(-5); 00916 else 00917 m_groundPoint.setBurningFormNumber(m_recentForm); 00918 00919 // set colour 00920 ngl::Vector m_colour = m_surroundingPoint.getColour(); 00921 m_groundPoint.changeColour(m_colour); 00922 00923 m_gridList[m_groundPointIndex] = m_groundPoint; 00924 00925 } // end if it is not ignited yet 00926 00927 } // end if the distance is within 0.25 00928 } // end if it's not duplicate index 00929 } // end for loop finding surrounding point 00930 } // end if it is be able to set the fire to surrounding fuel object 00931 } // end for loop of fuelongrid list 00932 } 00933 00934 //---------------------------------------------------------------------------------------------------------------------- 00935 void FirePath::pauseTheAnimation(bool _status) 00936 { 00937 m_pause = _status; 00938 } 00939 00940 //---------------------------------------------------------------------------------------------------------------------- 00941 // control colour of fire 00942 void FirePath::controlFirePathColour() 00943 { 00944 if(m_pause==false) 00945 { 00946 // collistion with fuel object 00947 for(unsigned int a=0; a<m_currentIndexForm.size(); ++a) 00948 { 00949 FuelPoint m_form = m_currentIndexForm[a]; 00950 ngl::Vector m_currentForm = m_form.getPosition(); 00951 int m_startIndex = m_currentForm.m_w; 00952 int m_currentIndex =m_currentForm.m_y; 00953 int m_lastIndexOfTheForm = m_currentForm.m_z; 00954 00955 float m_adjustXYZColour = 0.0; 00956 00957 FuelPoint m_lastPoint = m_fireDLAForm[m_lastIndexOfTheForm-1]; 00958 // get burning time to calculate the changing colour step size 00959 float m_burningTime = m_lastPoint.getBurningTime(); 00960 00961 if(m_burningTime<=10) 00962 { 00963 float m_newBurningTime = 10 + (10-m_burningTime); 00964 m_burningTime = m_newBurningTime; 00965 } 00966 else 00967 { 00968 float m_newBurningTime = 10 - (m_burningTime - 10); 00969 m_burningTime = m_newBurningTime; 00970 } 00971 00972 m_adjustXYZColour = ((m_burningTime*0.0005)/10); 00973 00974 // adjust colour changing with rate of growth 00975 m_adjustXYZColour *= m_rateOfGrowth; 00976 00977 for(int e=m_startIndex; e<m_currentIndex; ++e) 00978 { 00979 FuelPoint m_point = m_fireDLAForm[e]; 00980 bool m_checkBurntStatus = m_point.isBurningDown(); 00981 00982 // ----- set colour to each point 00983 ngl::Vector m_colour = m_point.getColour(); 00984 00985 if(m_checkBurntStatus==false) 00986 { 00987 // decrease colour 00988 if(m_colour.m_y<=1.0) 00989 { 00990 m_colour.m_y += m_adjustXYZColour; 00991 } 00992 else if(m_colour.m_z<=1.0) 00993 { 00994 m_colour.m_z += m_adjustXYZColour; 00995 } 00996 00997 if((m_colour.m_z>=1.0)&&(m_colour.m_x>=1.0)) 00998 { 00999 m_colour = ngl::Vector(1.0,1.0,1.0); 01000 m_point.setToBeBurningDown(); 01001 m_fireDLAForm[e] = m_point; 01002 } 01003 } // end if it is still burning 01004 01005 if(m_checkBurntStatus==true) 01006 { 01007 if((m_colour.m_x>0.0)&&(m_colour.m_y>0.0)&&(m_colour.m_z>0.0)) 01008 { 01009 m_colour.m_x -= 0.0002; 01010 m_colour.m_y -= 0.0002; 01011 m_colour.m_z -= 0.0002; 01012 } 01013 } // end if it is all burnt 01014 01015 m_point.changeColour(m_colour); 01016 m_fireDLAForm[e] = m_point; 01017 01018 } // end for loop of fire dla path 01019 } // end for loop of fire form number 01020 } // end if the pause is false 01021 } 01022 01023