Revision: 1558
          http://rigsofrods.svn.sourceforge.net/rigsofrods/?rev=1558&view=rev
Author:   aperion
Date:     2010-12-19 10:39:47 +0000 (Sun, 19 Dec 2010)

Log Message:
-----------
collision limit removed (#50) and reduced cell size, reducing freezing when 
near complexe objects (#203)

Modified Paths:
--------------
    trunk/source/main/collisions.cpp
    trunk/source/main/collisions.h

Modified: trunk/source/main/collisions.cpp
===================================================================
--- trunk/source/main/collisions.cpp    2010-12-19 07:11:27 UTC (rev 1557)
+++ trunk/source/main/collisions.cpp    2010-12-19 10:39:47 UTC (rev 1558)
@@ -104,26 +104,28 @@
 #ifdef USE_LUA
   LuaSystem *mlua,
 #endif
-  RoRFrameListener *efl, bool _debugMode) : mefl(efl), ground_models()
-{
-       landuse=0;
-       debugMode=_debugMode;
-       debugModeEvents = SETTINGS.getSetting("Debug Event Boxes") == "Yes";
-       last_used_ground_model=0;
+  RoRFrameListener *efl, bool _debugMode)
+: free_collision_box(0)
+, free_collision_tri(0)
+, free_cell(0)
+, free_eventsource(0)
 #ifdef USE_LUA
-       lua=mlua;
+, lua(mlua)
 #endif
-       free_collision_box=0;
-       free_collision_tri=0;
-       free_eventsource=0;
-       free_cell=0;
-       forcecam=false;
-       hashmask=0;
-       hfinder=0;
-       collision_count=0;
-       largest_cellcount=0;
+, mefl(efl)
+, hashmask(0)
+, hfinder(0)
+, collision_count(0)
+, largest_cellcount(0)
+, debugMode(_debugMode)
+, debugModeEvents ( SETTINGS.getSetting("Debug Event Boxes") == "Yes")
+, landuse(0)
+, forcecam(false)
+, last_used_ground_model(0)
+{
        for (int i=0; i<HASH_SIZE; i++) {hashmask=hashmask<<1; hashmask++;};
        for (int i=0; i<(1<<HASH_SIZE); i++) hashtable[i].cellid=UNUSED_CELLID;
+       
        loadDefaultModels();
        defaultgm = getGroundModelByString("concrete");
        defaultgroundgm = getGroundModelByString("gravel");
@@ -360,12 +362,12 @@
        {
                cell_t *cell = hashtable[pos].cell;
                // cell has content, search it
-               for(int i=0;i<cell->free;i++)
+               for(int i=0;i<cell->size();i++)
                {
-                       if(cell->element[i] == value)
+                       if((*cell)[i] == value)
                        {
                                // remove that element
-                               cell->element[i] = UNUSED_CELLID;
+                               cell->erase(cell->begin() + i);
                                break;
                        }
                }
@@ -391,85 +393,22 @@
 
        if (hashtable[pos].cellid==UNUSED_CELLID)
        {
-               if (free_cell<MAX_CELLS)
-               {
-                       //create a new cell
-                       hashtable[pos].cellid=cellid;
-                       hashtable[pos].cell=&cells[free_cell];
-                       cells[free_cell].free=1;
-                       cells[free_cell].element[0]=value;
-                       cells[free_cell].next=0;
-                       if (pos!=hashfunc(cellid)) collision_count++;
-                       if (cells[free_cell].free>largest_cellcount) 
largest_cellcount=cells[free_cell].free;
-                       free_cell++;
-               }
-               else
-               {
-                       if(debugMode)
-                               
Ogre::LogManager::getSingleton().logMessage("COLL: not enough cells available");
-               }
+               //create a new cell
+               cell_t* newcell = new cell_t;
+               
+               hashtable[pos].cellid=cellid;
+               hashtable[pos].cell=newcell;
+               newcell->push_back(value);
+               cells.push_back(newcell);
+               if (pos!=hashfunc(cellid)) collision_count++;
+               if (newcell->size()>largest_cellcount) 
largest_cellcount=newcell->size();
        }
        else if (hashtable[pos].cellid==cellid)
        {
                //there is already a cell ready
                cell_t *cell=hashtable[pos].cell;
-
-               // check for re-usable cellelements
-               bool found=false;
-hash_add_next_cell:
-               for(int i=0;i<CELL_BLOCKSIZE;i++)
-               {
-                       if(cell->element[i] == (int)UNUSED_CELLELEMENT)
-                       {
-                               // found free cellelement, using it!
-                               cell->element[i]=value;
-                               found=true;
-                               if(debugMode)
-                                       
Ogre::LogManager::getSingleton().logMessage("COLL: reused cell element!");
-                               break;
-                       }
-               }
-               if(!found && cell->next)
-               {
-                       // ugly recursive cell search
-                       cell = (cell_t*) cell->next;
-                       goto hash_add_next_cell;
-               }
-               if(!found)
-               {
-                       // no reusable cellelement found, creating new one
-                       if (cell->free<CELL_BLOCKSIZE)
-                       {
-                               cell->element[cell->free]=value;
-                               cell->free++;
-                               
//Ogre::LogManager::getSingleton().logMessage("COLL: created new cell 
element!");
-                               if (cell->free>largest_cellcount) 
largest_cellcount=cell->free;
-                       }
-                       else if (cell->free >= CELL_BLOCKSIZE && !cell->next)
-                       {
-                               // create new linked cell
-
-                               // find empty cell
-                               int pos2=pos;
-                               while (pos2!=(int)stop && 
hashtable[pos2].cellid!=(unsigned int)UNUSED_CELLID)
-                                       pos2++;
-
-                               // allocate that cell and link it to the 
current cell
-                               if (hashtable[pos2].cellid==UNUSED_CELLID)
-                               {
-                                       //create a new cell
-                                       hashtable[pos2].cellid=cellid;
-                                       hashtable[pos2].cell=&cells[free_cell];
-                                       cells[free_cell].free=1;
-                                       cells[free_cell].element[0]=value;
-                                       cells[free_cell].next=0;
-                                       if (pos!=hashfunc(cellid)) 
collision_count++;
-                                       if 
(cells[free_cell].free>largest_cellcount) 
largest_cellcount=cells[free_cell].free;
-                                       free_cell++;
-                                       cell->next = hashtable[pos2].cell;
-                               }
-                       }
-               }
+               cell->push_back(value);
+               if (cell->size()>largest_cellcount) 
largest_cellcount=cell->size();
        }
        else
        {
@@ -755,9 +694,9 @@
 {
        LogManager::getSingleton().logMessage("COLL: Collision system 
statistics:");
        LogManager::getSingleton().logMessage("COLL: Cell size: 
"+StringConverter::toString((float)CELL_SIZE)+" m");
-       LogManager::getSingleton().logMessage("COLL: Hashtable occupation: 
"+StringConverter::toString(free_cell)+"/"+StringConverter::toString(MAX_CELLS)+"
 ("+StringConverter::toString(100.0f*free_cell/(MAX_CELLS))+"%)");
+       LogManager::getSingleton().logMessage("COLL: Hashtable occupation: 
"+StringConverter::toString(cells.size()));
        LogManager::getSingleton().logMessage("COLL: Hashtable collisions: 
"+StringConverter::toString(collision_count));
-       LogManager::getSingleton().logMessage("COLL: Largest cell: 
"+StringConverter::toString(largest_cellcount)+"/"+StringConverter::toString(CELL_BLOCKSIZE)+"
 ("+StringConverter::toString(100.0f*largest_cellcount/CELL_BLOCKSIZE)+"%)");
+       LogManager::getSingleton().logMessage("COLL: Largest cell: 
"+StringConverter::toString(largest_cellcount));
 
 }
 
@@ -781,12 +720,11 @@
 
        if (cell)
        {
-coll_corr_resume_cell:
-               for (k=0; k<cell->free; k++)
+               for (k=0; k<cell->size(); k++)
                {
-                       if (cell->element[k] != (int)UNUSED_CELLELEMENT && 
cell->element[k]<MAX_COLLISION_BOXES)
+                       if ((*cell)[k] != (int)UNUSED_CELLELEMENT && 
(*cell)[k]<MAX_COLLISION_BOXES)
                        {
-                               collision_box_t 
*cbox=&collision_boxes[cell->element[k]];
+                               collision_box_t 
*cbox=&collision_boxes[(*cell)[k]];
                                if (refpos->x>cbox->lo_x && 
refpos->x<cbox->hi_x && refpos->y>cbox->lo_y && refpos->y<cbox->hi_y && 
refpos->z>cbox->lo_z && refpos->z<cbox->hi_z)
                                {
                                        if (cbox->refined || cbox->selfrotated)
@@ -916,7 +854,7 @@
                        }
                        else
                        {
-                               collision_tri_t 
*ctri=&collision_tris[cell->element[k]-MAX_COLLISION_BOXES];
+                               collision_tri_t 
*ctri=&collision_tris[(*cell)[k]-MAX_COLLISION_BOXES];
                                if(!ctri->enabled)
                                        continue;
                                //check if this tri is minimal
@@ -934,12 +872,6 @@
                                }
                        }
                }
-               if(cell->next)
-               {
-                       // continue with next cell
-                       cell=(cell_t*)cell->next;
-                       goto coll_corr_resume_cell;
-               }
        }
        //process minctri collision
        if (minctri)
@@ -996,12 +928,11 @@
 
        if (cell)
        {
-node_coll_resume_cell:
-               for (k=0; k<cell->free; k++)
+               for (k=0; k<cell->size(); k++)
                {
-                       if (cell->element[k] != (int)UNUSED_CELLELEMENT && 
cell->element[k]<MAX_COLLISION_BOXES)
+                       if ((*cell)[k] != (int)UNUSED_CELLELEMENT && 
(*cell)[k]<MAX_COLLISION_BOXES)
                        {
-                               collision_box_t 
*cbox=&collision_boxes[cell->element[k]];
+                               collision_box_t 
*cbox=&collision_boxes[(*cell)[k]];
                                if (node->AbsPosition.x>cbox->lo_x && 
node->AbsPosition.x<cbox->hi_x && node->AbsPosition.y>cbox->lo_y && 
node->AbsPosition.y<cbox->hi_y && node->AbsPosition.z>cbox->lo_z && 
node->AbsPosition.z<cbox->hi_z)
                                {
                                        if (cbox->refined || cbox->selfrotated)
@@ -1156,7 +1087,7 @@
                        else
                        {
                                //tri collision
-                               collision_tri_t 
*ctri=&collision_tris[cell->element[k]-MAX_COLLISION_BOXES];
+                               collision_tri_t 
*ctri=&collision_tris[(*cell)[k]-MAX_COLLISION_BOXES];
                                //check if this tri is minimal
                                //transform
                                Vector3 
point=ctri->forward*(node->AbsPosition-ctri->a);
@@ -1172,12 +1103,6 @@
                                }
                        }
                }
-               if(cell->next)
-               {
-                       // continue with next cell
-                       cell=(cell_t*)cell->next;
-                       goto node_coll_resume_cell;
-               }
        }
        //process minctri collision
        if (minctri)
@@ -1525,10 +1450,7 @@
                                groundheight+=0.1; // 10 cm hover
                                // ground height should fit
 
-                               int deep = 0, cc=cell->free;
-                               if(cell->next) { deep++; 
cc+=((cell_t*)cell->next)->free; };
-                               if(cell->next && ((cell_t*)cell->next)->next) { 
deep++; cc+=((cell_t*)((cell_t*)cell->next)->next)->free; };
-                               if(cell->next && ((cell_t*)cell->next)->next && 
((cell_t*)((cell_t*)cell->next)->next)->next) { deep++; 
cc+=((cell_t*)((cell_t*)((cell_t*)cell->next)->next)->next)->free; };
+                               int deep = 0, cc=cell->size();
                                float percent = cc / (float)CELL_BLOCKSIZE;
 
                                float percentd = percent;

Modified: trunk/source/main/collisions.h
===================================================================
--- trunk/source/main/collisions.h      2010-12-19 07:11:27 UTC (rev 1557)
+++ trunk/source/main/collisions.h      2010-12-19 10:39:47 UTC (rev 1558)
@@ -21,6 +21,7 @@
 #define __Collisions_H__
 
 #include "Ogre.h"
+#include <vector>
 //using namespace Ogre;
 #include "OgreTextAreaOverlayElement.h"
 #if OGRE_PLATFORM == OGRE_PLATFORM_WIN32
@@ -39,8 +40,8 @@
 #define UNUSED_CELLID 0xFFFFFFFF
 #define UNUSED_CELLELEMENT 0xFFFFFFFF
 //terrain size is limited to 327km x 327km:
-#define CELL_SIZE 10.0
-#define inverse_CELL_SIZE 0.1
+#define CELL_SIZE 2.0
+#define inverse_CELL_SIZE 0.5
 #define MAXIMUM_CELL 0x7FFF
 
 #define MAX_EVENTSOURCE 500
@@ -89,12 +90,11 @@
        bool enabled;
 } collision_tri_t;
 
-typedef struct _cell
-{
-       int free;
-       int element[CELL_BLOCKSIZE];
-       void *next;
-} cell_t;
+//typedef struct _cell
+//{
+//     std::vector<int> element;//[CELL_BLOCKSIZE]; //value is stored in 
here...
+//} cell_t;
+typedef std::vector<int> cell_t;
 
 typedef struct _hash
 {
@@ -116,7 +116,7 @@
        //collision hashtable
        hash_t hashtable[1<<HASH_SIZE];
        //cell pool
-       cell_t cells[MAX_CELLS];
+       std::vector<cell_t*> cells;//[MAX_CELLS];
        int free_cell;
 
        eventsource_t eventsources[MAX_EVENTSOURCE];
@@ -137,6 +137,7 @@
        Landusemap *landuse;
 
 private:
+       /// What is value for?? seams to be the array location where the items 
are stored
        void hash_add(int cell_x, int cell_z, int value);
        void hash_free(int cell_x, int cell_z, int value);
        cell_t *hash_find(int cell_x, int cell_z);


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Lotusphere 2011
Register now for Lotusphere 2011 and learn how
to connect the dots, take your collaborative environment
to the next level, and enter the era of Social Business.
http://p.sf.net/sfu/lotusphere-d2d
_______________________________________________
Rigsofrods-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/rigsofrods-devel

Reply via email to