| 111 |
111 |
#ifdef USE_LUA
|
| 112 |
112 |
lua=mlua;
|
| 113 |
113 |
#endif
|
|
114 |
resizeCells(1000); // previous default value was 10k, lowered it a bit
|
| 114 |
115 |
free_collision_box=0;
|
| 115 |
116 |
free_collision_tri=0;
|
| 116 |
117 |
free_eventsource=0;
|
| ... | ... | |
| 305 |
306 |
return hash&hashmask;
|
| 306 |
307 |
}
|
| 307 |
308 |
|
|
309 |
void Collisions::resizeCells(int newsize)
|
|
310 |
{
|
|
311 |
int oldsize = cells.size();
|
|
312 |
|
|
313 |
cell_t* old_array_start = &cells[0];
|
|
314 |
cells.resize(newsize);
|
|
315 |
cell_t* new_array_start = &cells[0];
|
|
316 |
ptrdiff_t ptr_delta = new_array_start - old_array_start;
|
|
317 |
|
|
318 |
|
|
319 |
//adjust pointer values in hashtable
|
|
320 |
for(size_t i = 0; i < (1 << HASH_SIZE); i++)
|
|
321 |
{
|
|
322 |
if( hashtable[i].cellid == UNUSED_CELLID ) continue;
|
|
323 |
|
|
324 |
hashtable[i].cell += ptr_delta;
|
|
325 |
}
|
|
326 |
|
|
327 |
|
|
328 |
|
|
329 |
if(debugMode)
|
|
330 |
{
|
|
331 |
Ogre::LogManager::getSingleton().logMessage("COLL: cell limit of " + StringConverter::toString(oldsize) + " reached. Increasing limit by 1000.");
|
|
332 |
Ogre::LogManager::getSingleton().logMessage("COLL: cell memory is now " + StringConverter::toString(cells.size() * sizeof(cell_t) / 1024.0f) + " kB big");
|
|
333 |
}
|
|
334 |
|
|
335 |
|
|
336 |
if(oldsize > (int)cells.size())
|
|
337 |
{
|
|
338 |
for(size_t i = oldsize - 1; i < cells.size(); i++)
|
|
339 |
{
|
|
340 |
memset(&cells[i], 0xff, sizeof(cell_t));
|
|
341 |
//for(int j=0;j<CELL_BLOCKSIZE;j++)
|
|
342 |
// cells[i].element[j] = UNUSED_CELLELEMENT;
|
|
343 |
cells[i].next=0;
|
|
344 |
cells[i].free=0;
|
|
345 |
}
|
|
346 |
}
|
|
347 |
}
|
|
348 |
|
|
349 |
|
| 308 |
350 |
int Collisions::removeCollisionTri(int number)
|
| 309 |
351 |
{
|
| 310 |
352 |
if(number>free_collision_tri)
|
| ... | ... | |
| 382 |
424 |
|
| 383 |
425 |
if (hashtable[pos].cellid==UNUSED_CELLID)
|
| 384 |
426 |
{
|
| 385 |
|
if (free_cell<MAX_CELLS)
|
| 386 |
|
{
|
| 387 |
|
//create a new cell
|
| 388 |
|
hashtable[pos].cellid=cellid;
|
| 389 |
|
hashtable[pos].cell=&cells[free_cell];
|
| 390 |
|
cells[free_cell].free=1;
|
| 391 |
|
cells[free_cell].element[0]=value;
|
| 392 |
|
cells[free_cell].next=0;
|
| 393 |
|
if (pos!=hashfunc(cellid)) collision_count++;
|
| 394 |
|
if (cells[free_cell].free>largest_cellcount) largest_cellcount=cells[free_cell].free;
|
| 395 |
|
free_cell++;
|
| 396 |
|
}
|
| 397 |
|
else
|
|
427 |
if (free_cell + 10>=(int)cells.size())
|
| 398 |
428 |
{
|
| 399 |
|
if(debugMode)
|
| 400 |
|
Ogre::LogManager::getSingleton().logMessage("COLL: not enough cells available");
|
|
429 |
//int oldsize = cells.size();
|
|
430 |
resizeCells(cells.size() + 1000);
|
| 401 |
431 |
}
|
|
432 |
//create a new cell
|
|
433 |
hashtable[pos].cellid=cellid;
|
|
434 |
hashtable[pos].cell=&cells[free_cell];
|
|
435 |
cells[free_cell].free=1;
|
|
436 |
cells[free_cell].element[0]=value;
|
|
437 |
cells[free_cell].next=0;
|
|
438 |
if (pos!=hashfunc(cellid)) collision_count++;
|
|
439 |
if (cells[free_cell].free>largest_cellcount) largest_cellcount=cells[free_cell].free;
|
|
440 |
free_cell++;
|
| 402 |
441 |
}
|
| 403 |
442 |
else if (hashtable[pos].cellid==cellid)
|
| 404 |
443 |
{
|
| ... | ... | |
| 469 |
508 |
}
|
| 470 |
509 |
}
|
| 471 |
510 |
|
| 472 |
|
cell_t *Collisions::hash_find(int cell_x, int cell_z)
|
|
511 |
hash_t *Collisions::hash_find(int cell_x, int cell_z)
|
| 473 |
512 |
{
|
| 474 |
513 |
unsigned int cellid=(cell_x<<16)+cell_z;
|
| 475 |
514 |
unsigned int hash=hashfunc(cellid);
|
| ... | ... | |
| 483 |
522 |
pos++;
|
| 484 |
523 |
if (pos==(1<<HASH_SIZE)) pos=0;
|
| 485 |
524 |
}
|
|
525 |
|
|
526 |
return &hashtable[pos];
|
|
527 |
}
|
|
528 |
|
|
529 |
cell_t *Collisions::cell_find(int cell_x, int cell_z)
|
|
530 |
{
|
|
531 |
#if 1
|
|
532 |
unsigned int cellid=(cell_x<<16)+cell_z;
|
|
533 |
unsigned int hash=hashfunc(cellid);
|
|
534 |
//search the spot
|
|
535 |
unsigned int pos=hash;
|
|
536 |
unsigned int stop=hash-1;
|
|
537 |
if (hash==0) stop=(1<<HASH_SIZE)-1;
|
|
538 |
|
|
539 |
while (pos!=stop && hashtable[pos].cellid!=UNUSED_CELLID && hashtable[pos].cellid!=cellid)
|
|
540 |
{
|
|
541 |
pos++;
|
|
542 |
if (pos==(1<<HASH_SIZE)) pos=0;
|
|
543 |
}
|
|
544 |
|
| 486 |
545 |
if (hashtable[pos].cellid==cellid) return hashtable[pos].cell;
|
| 487 |
546 |
return NULL;
|
|
547 |
#else
|
|
548 |
|
|
549 |
hash_t *hash = hash_find(cell_x, cell_y);
|
|
550 |
return (hash->cellid == cellid) ? hash->cell : NULL;
|
|
551 |
#endif
|
| 488 |
552 |
}
|
| 489 |
553 |
|
| 490 |
554 |
|
| ... | ... | |
| 685 |
749 |
{
|
| 686 |
750 |
LogManager::getSingleton().logMessage("COLL: Collision system statistics:");
|
| 687 |
751 |
LogManager::getSingleton().logMessage("COLL: Cell size: "+StringConverter::toString((float)CELL_SIZE)+" m");
|
| 688 |
|
LogManager::getSingleton().logMessage("COLL: Hashtable occupation: "+StringConverter::toString(free_cell)+"/"+StringConverter::toString(MAX_CELLS)+" ("+StringConverter::toString(100.0f*free_cell/(MAX_CELLS))+"%)");
|
|
752 |
LogManager::getSingleton().logMessage("COLL: Amount of Cells: " + StringConverter::toString(cells.size()));
|
|
753 |
LogManager::getSingleton().logMessage("COLL: Cell memory is now " + StringConverter::toString(cells.size() * sizeof(cell_t) / 1024.0f) + " kB big");
|
|
754 |
LogManager::getSingleton().logMessage("COLL: Hashtable occupation: "+StringConverter::toString(free_cell)+"/"+StringConverter::toString(cells.size())+" ("+StringConverter::toString(100.0f*free_cell/(cells.size()))+"%)");
|
| 689 |
755 |
LogManager::getSingleton().logMessage("COLL: Hashtable collisions: "+StringConverter::toString(collision_count));
|
| 690 |
756 |
LogManager::getSingleton().logMessage("COLL: Largest cell: "+StringConverter::toString(largest_cellcount)+"/"+StringConverter::toString(CELL_BLOCKSIZE)+" ("+StringConverter::toString(100.0f*largest_cellcount/CELL_BLOCKSIZE)+"%)");
|
| 691 |
|
|
| 692 |
757 |
}
|
| 693 |
758 |
|
| 694 |
759 |
|
| ... | ... | |
| 703 |
768 |
|
| 704 |
769 |
refx=(int)(refpos->x/(float)CELL_SIZE);
|
| 705 |
770 |
refz=(int)(refpos->z/(float)CELL_SIZE);
|
| 706 |
|
cell_t *cell=hash_find(refx, refz);
|
|
771 |
cell_t *cell=cell_find(refx, refz);
|
| 707 |
772 |
|
| 708 |
773 |
collision_tri_t *minctri=0;
|
| 709 |
774 |
float minctridist=100.0;
|
| ... | ... | |
| 901 |
966 |
int refx, refz;
|
| 902 |
967 |
refx=(int)(node->AbsPosition.x*inverse_CELL_SIZE);
|
| 903 |
968 |
refz=(int)(node->AbsPosition.z*inverse_CELL_SIZE);
|
| 904 |
|
cell_t *cell=hash_find(refx, refz);
|
|
969 |
cell_t *cell=cell_find(refx, refz);
|
| 905 |
970 |
//LogManager::getSingleton().logMessage("Checking cell "+StringConverter::toString(refx)+" "+StringConverter::toString(refz)+" total indexes: "+StringConverter::toString(num_cboxes_index[refp]));
|
| 906 |
971 |
|
| 907 |
972 |
collision_tri_t *minctri=0;
|
| ... | ... | |
| 1371 |
1436 |
{
|
| 1372 |
1437 |
int cellx = (int)(x/(float)CELL_SIZE);
|
| 1373 |
1438 |
int cellz = (int)(z/(float)CELL_SIZE);
|
| 1374 |
|
cell_t *cell=hash_find(cellx, cellz);
|
|
1439 |
cell_t *cell=cell_find(cellx, cellz);
|
| 1375 |
1440 |
if(cell)
|
| 1376 |
1441 |
{
|
| 1377 |
1442 |
float groundheight = -9999;
|