w00t narrowed ghost bug to subregions of CollisionRegion, eliminated them, and implemented much more efficient collision group finding routines
git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@495 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
parent
7543d5db37
commit
0037ef4493
@ -309,7 +309,7 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
||||
Entity *e1,*e2;
|
||||
Vector p1, p2;
|
||||
double dist2, r1, r2, r0, min_dist2;
|
||||
int i,j;
|
||||
int i;
|
||||
Entity* entities_to_test[n_entities];
|
||||
//
|
||||
|
||||
@ -323,9 +323,14 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
||||
for (i = 0; i < n_entities; i++)
|
||||
{
|
||||
e1 = entity_array[i];
|
||||
if (!e1->collisionTestFilter)
|
||||
if (!(e1->collisionTestFilter))
|
||||
entities_to_test[n_entities_to_test++] = e1;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
NSLog(@"\nDEBUG in collision region %@ testing %d out of %d entities", self, n_entities_to_test, n_entities);
|
||||
|
||||
|
||||
if (n_entities_to_test < 2)
|
||||
return;
|
||||
|
||||
@ -350,26 +355,30 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
||||
[(CollisionRegion*)[subregions objectAtIndex: i] findCollisionsInUniverse: universe];
|
||||
//
|
||||
|
||||
// test each entity in this region against the others
|
||||
// test each entity in this region against the entities in its collision chain
|
||||
//
|
||||
for (i = 0; i < n_entities_to_test; i++)
|
||||
{
|
||||
e1 = entities_to_test[i];
|
||||
p1 = e1->position;
|
||||
r1 = e1->collision_radius;
|
||||
for (j = i + 1; j < n_entities_to_test; j++)
|
||||
|
||||
// check against the first in the collision chain
|
||||
e2 = e1->collision_chain;
|
||||
while (e2)
|
||||
{
|
||||
e2 = entities_to_test[j];
|
||||
|
||||
if (debug)
|
||||
{
|
||||
debug = NO;
|
||||
NSLog(@"DEBUG Testing collision between %@ and %@", e1, e2);
|
||||
debug = YES;
|
||||
}
|
||||
|
||||
p2 = e2->position;
|
||||
r2 = e2->collision_radius;
|
||||
r0 = r1 + r2;
|
||||
p2.x -= p1.x; p2.y -= p1.y; p2.z -= p1.z;
|
||||
if ((p2.x > r0)||(p2.x < -r0)) // test for simple x distance
|
||||
continue; // next j
|
||||
if ((p2.y > r0)||(p2.y < -r0)) // test for simple y distance
|
||||
continue; // next j
|
||||
if ((p2.z > r0)||(p2.z < -r0)) // test for simple z distance
|
||||
continue; // next j
|
||||
dist2 = p2.x*p2.x + p2.y*p2.y + p2.z*p2.z;
|
||||
min_dist2 = r0 * r0;
|
||||
if (dist2 < PROXIMITY_WARN_DISTANCE2 * min_dist2)
|
||||
@ -419,6 +428,8 @@ NSArray* subregionsContainingPosition( Vector position, CollisionRegion* region)
|
||||
}
|
||||
}
|
||||
}
|
||||
// check the next in the collision chain
|
||||
e2 = e2->collision_chain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,7 +76,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
//
|
||||
displayListName = 0;
|
||||
//
|
||||
status = STATUS_TEST;
|
||||
status = STATUS_ACTIVE;
|
||||
//
|
||||
return self;
|
||||
}
|
||||
|
@ -190,12 +190,13 @@ extern int debug;
|
||||
int status;
|
||||
//
|
||||
int zero_index;
|
||||
// int x_index, y_index, z_index;
|
||||
BOOL collisionTestFilter;
|
||||
// replace x_index etc. with linked lists..
|
||||
Entity *x_previous, *x_next;
|
||||
Entity *y_previous, *y_next;
|
||||
Entity *z_previous, *z_next;
|
||||
//
|
||||
Entity *collision_chain;
|
||||
|
||||
//
|
||||
// experimental lighting:
|
||||
|
@ -292,6 +292,8 @@ static Universe *data_store_universe;
|
||||
y_next = y_previous = nil;
|
||||
z_next = z_previous = nil;
|
||||
//
|
||||
collision_chain = nil;
|
||||
//
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -1789,7 +1791,7 @@ static Universe *data_store_universe;
|
||||
|
||||
- (BoundingBox) findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k
|
||||
{
|
||||
NSLog(@"DEBUG ** DEPRECATED [Entity findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k] CALLED **");
|
||||
// NSLog(@"DEBUG ** DEPRECATED [Entity findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k] CALLED **");
|
||||
|
||||
Vector pv, rv;
|
||||
Vector rpos = position;
|
||||
|
@ -886,7 +886,10 @@ static NSTimeInterval time_last_frame;
|
||||
if ([gameView isDown:48])// look for the '0' key
|
||||
{
|
||||
if (!cloak_pressed)
|
||||
{
|
||||
[universe obj_dump]; // dump objects
|
||||
debug = !debug;
|
||||
}
|
||||
cloak_pressed = YES;
|
||||
}
|
||||
else
|
||||
|
@ -1015,7 +1015,7 @@ static Quaternion quaternion_identity = { (GLfloat)1.0, (GLfloat)0.0, (GLfloat)0
|
||||
//
|
||||
displayListName = 0;
|
||||
//
|
||||
status = STATUS_TEST;
|
||||
status = STATUS_ACTIVE;
|
||||
//
|
||||
shield_booster = 1;
|
||||
shield_enhancer = 0;
|
||||
|
@ -299,13 +299,62 @@ NSString* describeBehaviour(int some_behaviour)
|
||||
return @"** BEHAVIOUR UNKNOWN **";
|
||||
}
|
||||
|
||||
NSString* describeStatus(int some_status)
|
||||
{
|
||||
switch(some_status)
|
||||
{
|
||||
case STATUS_AUTOPILOT_ENGAGED :
|
||||
return @"STATUS_AUTOPILOT_ENGAGED";
|
||||
case STATUS_DEAD :
|
||||
return @"STATUS_DEAD";
|
||||
case STATUS_START_GAME :
|
||||
return @"STATUS_START_GAME";
|
||||
case STATUS_DEMO :
|
||||
return @"STATUS_DEMO";
|
||||
case STATUS_DOCKING :
|
||||
return @"STATUS_DOCKING";
|
||||
case STATUS_DOCKED :
|
||||
return @"STATUS_DOCKED";
|
||||
case STATUS_EFFECT :
|
||||
return @"STATUS_EFFECT";
|
||||
case STATUS_ENTERING_WITCHSPACE :
|
||||
return @"STATUS_ENTERING_WITCHSPACE";
|
||||
case STATUS_ESCAPE_SEQUENCE :
|
||||
return @"STATUS_ESCAPE_SEQUENCE";
|
||||
case STATUS_EXITING_WITCHSPACE :
|
||||
return @"STATUS_EXITING_WITCHSPACE";
|
||||
case STATUS_EXPERIMENTAL :
|
||||
return @"STATUS_EXPERIMENTAL";
|
||||
case STATUS_IN_FLIGHT :
|
||||
return @"STATUS_IN_FLIGHT";
|
||||
case STATUS_IN_HOLD :
|
||||
return @"STATUS_IN_HOLD";
|
||||
case STATUS_INACTIVE :
|
||||
return @"STATUS_INACTIVE";
|
||||
case STATUS_LAUNCHING :
|
||||
return @"STATUS_LAUNCHING";
|
||||
case STATUS_TEST :
|
||||
return @"STATUS_TEST";
|
||||
case STATUS_WITCHSPACE_COUNTDOWN :
|
||||
return @"STATUS_WITCHSPACE_COUNTDOWN";
|
||||
}
|
||||
return @"** STATUS UNKNOWN **";
|
||||
}
|
||||
|
||||
- (NSString*) description
|
||||
{
|
||||
if (!debug)
|
||||
return [NSString stringWithFormat:@"<ShipEntity %@ %d>", name, universal_id];
|
||||
|
||||
NSString* result = [NSString stringWithFormat:@"\n<ShipEntity %@ %d (%@) %@ %@ on target %d // %@>",
|
||||
name, universal_id, roles, (universe == nil)? @" (not in universe)":@"", describeBehaviour(behaviour), primaryTarget, collision_region];
|
||||
NSMutableString* result = [NSMutableString stringWithFormat:@"\n<ShipEntity %@ %d>", name, universal_id];
|
||||
[result appendFormat:@"\n isPlayer: %@", (isPlayer)? @"YES":@"NO"];
|
||||
[result appendFormat:@"\n isShip: %@", (isShip)? @"YES":@"NO"];
|
||||
[result appendFormat:@"\n isStation: %@", (isStation)? @"YES":@"NO"];
|
||||
[result appendFormat:@"\n isSubentity: %@", (isSubentity)? @"YES":@"NO"];
|
||||
[result appendFormat:@"\n canCollide: %@", ([self canCollide])? @"YES":@"NO"];
|
||||
[result appendFormat:@"\n behaviour: %d %@", behaviour, describeBehaviour(behaviour)];
|
||||
[result appendFormat:@"\n status: %d %@", status, describeStatus(status)];
|
||||
[result appendFormat:@"\n collisionRegion: %@", collision_region];
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -4197,10 +4246,10 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
|
||||
[plate setVelocity:v];
|
||||
quaternion_set_random(&q);
|
||||
[plate setQRotation:q];
|
||||
[plate setStatus:STATUS_TEST];
|
||||
[plate setScanClass: CLASS_CARGO];
|
||||
[plate setCommodity:9 andAmount:1];
|
||||
[universe addEntity:plate];
|
||||
[plate setStatus:STATUS_IN_FLIGHT];
|
||||
[[plate getAI] setState:@"GLOBAL"];
|
||||
[plate release];
|
||||
}
|
||||
@ -4430,11 +4479,11 @@ Vector positionOffsetForShipInRotationToAlignment(ShipEntity* ship, Quaternion q
|
||||
rpos.x += (ranrot_rand() % 7) - 3;
|
||||
rpos.y += (ranrot_rand() % 7) - 3;
|
||||
rpos.z += (ranrot_rand() % 7) - 3;
|
||||
[container setStatus:STATUS_TEST];
|
||||
[container setPosition:rpos];
|
||||
[container setScanClass: CLASS_CARGO];
|
||||
[universe addEntity:container];
|
||||
[[container getAI] setState:@"GLOBAL"];
|
||||
[container setStatus:STATUS_IN_FLIGHT];
|
||||
[container release];
|
||||
if (n_cargo > 0)
|
||||
n_cargo--; // count down extra cargo
|
||||
|
@ -514,9 +514,10 @@ Your fair use and other rights are in no way affected by the above.
|
||||
|
||||
- (void) obj_dump
|
||||
{
|
||||
int show_count = (debug)? 10 : n_entities;
|
||||
NSLog(@"DEBUG ENTITY DUMP: [entities count] = %d,\tn_entities = %d", [entities count], n_entities);
|
||||
int i;
|
||||
for (i = 0; i < n_entities; i++)
|
||||
for (i = 0; i < show_count; i++)
|
||||
{
|
||||
ShipEntity* se = (sortedEntities[i]->isShip)? (ShipEntity*)sortedEntities[i]: nil;
|
||||
NSLog(@"-> Ent:%d\t\t%@ mass %.2f %@", i, sortedEntities[i], [sortedEntities[i] mass], [se getAI]);
|
||||
@ -524,33 +525,36 @@ Your fair use and other rights are in no way affected by the above.
|
||||
if ([entities count] != n_entities)
|
||||
NSLog(@"entities = %@", [entities description]);
|
||||
//
|
||||
NSLog(@"\n----->X list...");
|
||||
NSLog(@"\n----->X list... to %d", show_count);
|
||||
int n = 0;
|
||||
Entity* e0 = x_list_start;
|
||||
while (e0)
|
||||
{
|
||||
n++;
|
||||
NSLog(@"%d.) %@ at x-cr = %.2f", n, e0, e0->position.x - e0->collision_radius);
|
||||
if (n <= show_count)
|
||||
NSLog(@"%d.) %@ at x-cr = %.2f", n, e0, e0->position.x - e0->collision_radius);
|
||||
e0 = e0->x_next;
|
||||
}
|
||||
//
|
||||
NSLog(@"\n----->Y list...");
|
||||
NSLog(@"\n----->Y list... to %d", show_count);
|
||||
n = 0;
|
||||
e0 = y_list_start;
|
||||
while (e0)
|
||||
{
|
||||
n++;
|
||||
NSLog(@"%d.) %@ at y-cr = %.2f", n, e0, e0->position.y - e0->collision_radius);
|
||||
if (n <= show_count)
|
||||
NSLog(@"%d.) %@ at y-cr = %.2f", n, e0, e0->position.y - e0->collision_radius);
|
||||
e0 = e0->y_next;
|
||||
}
|
||||
//
|
||||
NSLog(@"\n----->Z list...");
|
||||
NSLog(@"\n----->Z list... to %d", show_count);
|
||||
n = 0;
|
||||
e0 = z_list_start;
|
||||
while (e0)
|
||||
{
|
||||
n++;
|
||||
NSLog(@"%d.) %@ at z-cr = %.2f", n, e0, e0->position.z - e0->collision_radius);
|
||||
if (n <= show_count)
|
||||
NSLog(@"%d.) %@ at z-cr = %.2f", n, e0, e0->position.z - e0->collision_radius);
|
||||
e0 = e0->z_next;
|
||||
}
|
||||
}
|
||||
@ -901,7 +905,7 @@ Your fair use and other rights are in no way affected by the above.
|
||||
Vector region_pos = a_planet->position;
|
||||
while (region_pos.z > -planet_radius)
|
||||
{
|
||||
[universeRegion addSubregionAtPosition: region_pos withRadius: region_radius]; // collision regions from planet to witchpoint
|
||||
// [universeRegion addSubregionAtPosition: region_pos withRadius: region_radius]; // collision regions from planet to witchpoint
|
||||
region_pos.z -= region_spacing;
|
||||
}
|
||||
|
||||
@ -1784,11 +1788,11 @@ GLfloat docked_light_specular[] = { (GLfloat) 1.0, (GLfloat) 1.0, (GLfloat) 0.5,
|
||||
}
|
||||
}
|
||||
|
||||
// hint to the collision detection system
|
||||
if (cluster_size > 3)
|
||||
{
|
||||
[universeRegion addSubregionAtPosition: spawnPos withRadius: SCANNER_MAX_RANGE * 1.5f ]; // 50% fudge on size
|
||||
}
|
||||
// // hint to the collision detection system
|
||||
// if (cluster_size > 3)
|
||||
// {
|
||||
// [universeRegion addSubregionAtPosition: spawnPos withRadius: SCANNER_MAX_RANGE * 1.5f ]; // 50% fudge on size
|
||||
// }
|
||||
|
||||
return rocks;
|
||||
}
|
||||
@ -4950,8 +4954,7 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
[universeRegion clearEntityList];
|
||||
//
|
||||
for (i = 0; i < n_entities; i++)
|
||||
if ([sortedEntities[i] canCollide]) // on Jens' suggestion only check collidables
|
||||
[universeRegion checkEntity: sortedEntities[i]]; // sorts out which region it's in
|
||||
[universeRegion checkEntity: sortedEntities[i]]; // sorts out which region it's in
|
||||
//
|
||||
[universeRegion findCollisionsInUniverse: self];
|
||||
//
|
||||
@ -5280,10 +5283,16 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
// now the linked lists
|
||||
[thing updateLinkedLists];
|
||||
//
|
||||
thing->collisionTestFilter = NO;
|
||||
// filter from collision detection?
|
||||
thing->collisionTestFilter = ![thing canCollide];
|
||||
//
|
||||
// reset list of colliding objects
|
||||
thing->collision_chain = nil;
|
||||
//
|
||||
// done maintaining sorted lists
|
||||
|
||||
|
||||
// update deterministic AI
|
||||
//
|
||||
if (thing->isShip)
|
||||
{
|
||||
AI* theShipsAI = [(ShipEntity *)thing getAI];
|
||||
@ -5297,6 +5306,8 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
}
|
||||
}
|
||||
}
|
||||
//
|
||||
////
|
||||
}
|
||||
|
||||
//
|
||||
@ -5373,7 +5384,7 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
}
|
||||
// done! list filtered
|
||||
|
||||
// then with the y_list
|
||||
// then with the y_list, z_list singletons now create more gaps..
|
||||
e0 = y_list_start;
|
||||
while (e0)
|
||||
{
|
||||
@ -5381,8 +5392,11 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
start = e0->position.y - e0->collision_radius;
|
||||
finish = start + 2.0f * e0->collision_radius;
|
||||
next = e0->y_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated from the list of possible colliders - so skip it
|
||||
next = next->y_next;
|
||||
if (next)
|
||||
{
|
||||
|
||||
next_start = next->position.y - next->collision_radius;
|
||||
if (next_start < finish)
|
||||
{
|
||||
@ -5395,6 +5409,8 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
finish = next_finish;
|
||||
e0 = next;
|
||||
next = e0->y_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated - so skip it
|
||||
next = next->y_next;
|
||||
if (next)
|
||||
next_start = next->position.y - next->collision_radius;
|
||||
}
|
||||
@ -5423,6 +5439,8 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
start = e0->position.x - e0->collision_radius;
|
||||
finish = start + 2.0f * e0->collision_radius;
|
||||
next = e0->x_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated from the list of possible colliders - so skip it
|
||||
next = next->x_next;
|
||||
if (next)
|
||||
{
|
||||
next_start = next->position.x - next->collision_radius;
|
||||
@ -5437,6 +5455,8 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
finish = next_finish;
|
||||
e0 = next;
|
||||
next = e0->x_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated - so skip it
|
||||
next = next->x_next;
|
||||
if (next)
|
||||
next_start = next->position.x - next->collision_radius;
|
||||
}
|
||||
@ -5457,6 +5477,101 @@ GLfloat starboard_matrix[] = { 0.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 0.0f,
|
||||
}
|
||||
// done! list filtered
|
||||
|
||||
// repeat the y_list - so gaps from the x_list influence singletons
|
||||
e0 = y_list_start;
|
||||
while (e0)
|
||||
{
|
||||
// here we are either at the start of the list or just past a gap
|
||||
start = e0->position.y - e0->collision_radius;
|
||||
finish = start + 2.0f * e0->collision_radius;
|
||||
next = e0->y_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated from the list of possible colliders - so skip it
|
||||
next = next->y_next;
|
||||
if (next)
|
||||
{
|
||||
|
||||
next_start = next->position.y - next->collision_radius;
|
||||
if (next_start < finish)
|
||||
{
|
||||
// e0 and next overlap
|
||||
while ((next)&&(next_start < finish))
|
||||
{
|
||||
// skip forward to the next gap or the end of the list
|
||||
next_finish = next_start + 2.0f * next->collision_radius;
|
||||
if (next_finish > finish)
|
||||
finish = next_finish;
|
||||
e0 = next;
|
||||
next = e0->y_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated - so skip it
|
||||
next = next->y_next;
|
||||
if (next)
|
||||
next_start = next->position.y - next->collision_radius;
|
||||
}
|
||||
// now either (next == nil) or (next_start >= finish)-which would imply a gap!
|
||||
}
|
||||
else
|
||||
{
|
||||
// e0 is a singleton
|
||||
e0->collisionTestFilter = YES;
|
||||
}
|
||||
}
|
||||
else // (next == nil)
|
||||
{
|
||||
// at the end of the list so e0 is a singleton
|
||||
e0->collisionTestFilter = YES;
|
||||
}
|
||||
e0 = next;
|
||||
}
|
||||
// done! list filtered
|
||||
|
||||
// finally, repeat the z_list - this time building collision chains...
|
||||
e0 = z_list_start;
|
||||
while (e0)
|
||||
{
|
||||
// here we are either at the start of the list or just past a gap
|
||||
start = e0->position.z - e0->collision_radius;
|
||||
finish = start + 2.0f * e0->collision_radius;
|
||||
next = e0->z_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated from the list of possible colliders - so skip it
|
||||
next = next->z_next;
|
||||
if (next)
|
||||
{
|
||||
|
||||
next_start = next->position.z - next->collision_radius;
|
||||
if (next_start < finish)
|
||||
{
|
||||
// e0 and next overlap
|
||||
while ((next)&&(next_start < finish))
|
||||
{
|
||||
// chain e0 to next in collision
|
||||
e0->collision_chain = next;
|
||||
// skip forward to the next gap or the end of the list
|
||||
next_finish = next_start + 2.0f * next->collision_radius;
|
||||
if (next_finish > finish)
|
||||
finish = next_finish;
|
||||
e0 = next;
|
||||
next = e0->z_next;
|
||||
while ((next)&&(next->collisionTestFilter)) // next has been eliminated - so skip it
|
||||
next = next->z_next;
|
||||
if (next)
|
||||
next_start = next->position.z - next->collision_radius;
|
||||
}
|
||||
// now either (next == nil) or (next_start >= finish)-which would imply a gap!
|
||||
}
|
||||
else
|
||||
{
|
||||
// e0 is a singleton
|
||||
e0->collisionTestFilter = YES;
|
||||
}
|
||||
}
|
||||
else // (next == nil)
|
||||
{
|
||||
// at the end of the list so e0 is a singleton
|
||||
e0->collisionTestFilter = YES;
|
||||
}
|
||||
e0 = next;
|
||||
}
|
||||
// done! list filtered
|
||||
}
|
||||
|
||||
- (void) setGalaxy_seed:(Random_Seed) gal_seed
|
||||
|
Loading…
x
Reference in New Issue
Block a user