Lots of stuff I've been working on over the last few weeks - mainly moving ShipEntity rendering into new class (OOMesh); also work on robustness of plist handling and stuff. Texture caching management is currently buggy.

git-svn-id: http://svn.berlios.de/svnroot/repos/oolite-linux/trunk@954 127b21dd-08f5-0310-b4b7-95ae10353056
This commit is contained in:
Jens Ayton 2007-05-08 15:24:13 +00:00
parent c96837389c
commit 076bf6c4fa
37 changed files with 1376 additions and 1331 deletions

View File

@ -301,8 +301,6 @@
1A43234E0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */; };
1A43234F0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */; };
1A451D8D0BB1BD2A004CD72F /* OOMaths.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A9404920BAF4582005F6CF3 /* OOMaths.h */; };
1A45B4260BDAC43A0078EA87 /* OOMeshDATSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 1A45B4240BDAC43A0078EA87 /* OOMeshDATSupport.h */; };
1A45B4270BDAC43A0078EA87 /* OOMeshDATSupport.m in Sources */ = {isa = PBXBuildFile; fileRef = 1A45B4250BDAC43A0078EA87 /* OOMeshDATSupport.m */; };
1A472917096B5454000E78D8 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A472916096B5454000E78D8 /* CoreAudio.framework */; };
1A472921096B5468000E78D8 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A47291F096B5468000E78D8 /* AudioToolbox.framework */; };
1A472922096B5468000E78D8 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1A472920096B5468000E78D8 /* AudioUnit.framework */; };
@ -1112,8 +1110,6 @@
1A3AFF1E0BC4462200B5E2D9 /* OOJSVector.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOJSVector.m; sourceTree = "<group>"; };
1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOOpenGLExtensionManager.h; sourceTree = "<group>"; };
1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOOpenGLExtensionManager.m; sourceTree = "<group>"; };
1A45B4240BDAC43A0078EA87 /* OOMeshDATSupport.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OOMeshDATSupport.h; sourceTree = "<group>"; };
1A45B4250BDAC43A0078EA87 /* OOMeshDATSupport.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OOMeshDATSupport.m; sourceTree = "<group>"; };
1A472916096B5454000E78D8 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = /System/Library/Frameworks/CoreAudio.framework; sourceTree = "<absolute>"; };
1A47291F096B5468000E78D8 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = /System/Library/Frameworks/AudioToolbox.framework; sourceTree = "<absolute>"; };
1A472920096B5468000E78D8 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = /System/Library/Frameworks/AudioUnit.framework; sourceTree = "<absolute>"; };
@ -1698,8 +1694,6 @@
1A2A1B130BD2774300152975 /* OODrawable.m */,
1A2A1CA80BD2914F00152975 /* OOMesh.h */,
1A2A1CA90BD2914F00152975 /* OOMesh.m */,
1A45B4240BDAC43A0078EA87 /* OOMeshDATSupport.h */,
1A45B4250BDAC43A0078EA87 /* OOMeshDATSupport.m */,
1A43234A0BCFC9BB00F65914 /* OOOpenGLExtensionManager.h */,
1A43234B0BCFC9BB00F65914 /* OOOpenGLExtensionManager.m */,
25161100099544380037C2E1 /* OpenGLSprite.h */,
@ -2332,7 +2326,6 @@
1A2A1B2C0BD277D800152975 /* OOSelfDrawingEntity.h in Headers */,
1A2A1CAC0BD2914F00152975 /* OOMesh.h in Headers */,
1A2A1DEC0BD2A28E00152975 /* OOMacroOpenGL.h in Headers */,
1A45B4260BDAC43A0078EA87 /* OOMeshDATSupport.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -2564,7 +2557,6 @@
1A2A1B170BD2774300152975 /* OODrawable.m in Sources */,
1A2A1B2D0BD277D800152975 /* OOSelfDrawingEntity.m in Sources */,
1A2A1CAD0BD2914F00152975 /* OOMesh.m in Sources */,
1A45B4270BDAC43A0078EA87 /* OOMeshDATSupport.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -72,14 +72,6 @@ beacon.list = $scriptDebugOn;
beacon.list.flightTraining = inherit;
dataCache.found = inherit;
dataCache.notFound = inherit;
dataCache.rebuild = inherit;
dataCache.write.success = inherit;
dataCache.write.failed = $error;
dataCache.rebuild.octree = no;
dataCache.willWrite = no;
$dataCacheStatus = yes;
$dataCacheError = $error;
$dataCacheDebug = no;

View File

@ -70,8 +70,6 @@
<string>$dataCacheStatus</string>
<key>dataCache.rebuild.datesChanged</key>
<string>inherit</string>
<key>dataCache.rebuild.octree</key>
<string>no</string>
<key>dataCache.rebuild.pathsChanged</key>
<string>inherit</string>
<key>dataCache.remove.success</key>
@ -88,8 +86,6 @@
<string>$dataCacheDebug</string>
<key>dataCache.upToDate</key>
<string>$dataCacheStatus</string>
<key>dataCache.willWrite</key>
<string>no</string>
<key>dataCache.write.buildPath.failed</key>
<string>$dataCacheError</string>
<key>dataCache.write.failed</key>

View File

@ -272,11 +272,11 @@
<key>fuel</key>
<integer>70</integer>
<key>has_ecm</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_escape_pod</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>likely_cargo</key>
<integer>7</integer>
<key>max_cargo</key>
@ -931,7 +931,7 @@
<key>fuel</key>
<integer>70</integer>
<key>has_ecm</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_escape_pod</key>
<real>1</real>
<key>has_scoop</key>
@ -1488,11 +1488,11 @@
<key>fuel</key>
<integer>70</integer>
<key>has_ecm</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_escape_pod</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>likely_cargo</key>
<integer>3</integer>
<key>max_cargo</key>
@ -1755,9 +1755,9 @@
<key>has_ecm</key>
<real>0.14999999999999999</real>
<key>has_escape_pod</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>likely_cargo</key>
<integer>3</integer>
<key>max_cargo</key>
@ -1813,7 +1813,7 @@
<key>fuel</key>
<integer>70</integer>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>likely_cargo</key>
<integer>2</integer>
<key>max_cargo</key>
@ -1871,7 +1871,7 @@
<key>has_fuel_injection</key>
<real>0.25</real>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_shield_booster</key>
<real>0.25</real>
<key>likely_cargo</key>
@ -2803,7 +2803,7 @@
<key>has_fuel_injection</key>
<real>0.65000000000000002</real>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_shield_booster</key>
<real>0.5</real>
<key>has_shield_enhancer</key>
@ -2870,7 +2870,7 @@
<key>forward_weapon_type</key>
<string>WEAPON_BEAM_LASER</string>
<key>has_scoop</key>
<real>0.94999999999999996</real>
<real>0.95</real>
<key>has_shield_booster</key>
<real>0.25</real>
<key>likely_cargo</key>
@ -2880,9 +2880,9 @@
<key>max_energy</key>
<real>240</real>
<key>max_flight_pitch</key>
<real>1.3999999999999999</real>
<real>1.4</real>
<key>max_flight_roll</key>
<real>2.1000000000000001</real>
<real>2.1</real>
<key>max_flight_speed</key>
<real>320</real>
<key>max_missiles</key>
@ -2941,9 +2941,9 @@
<key>max_energy</key>
<real>240</real>
<key>max_flight_pitch</key>
<real>1.3999999999999999</real>
<real>1.4</real>
<key>max_flight_roll</key>
<real>2.1000000000000001</real>
<real>2.1</real>
<key>max_flight_speed</key>
<real>320</real>
<key>max_missiles</key>

View File

@ -41,10 +41,10 @@ MA 02110-1301, USA.
self = [super init];
//
n_vertices = DUST_N_PARTICLES;
n_faces = 0;
vertexCount = DUST_N_PARTICLES;
faceCount = 0;
//
for (vi = 0; vi < n_vertices; vi++)
for (vi = 0; vi < vertexCount; vi++)
{
vertices[vi].x = (ranrot_rand() % DUST_SCALE) - DUST_SCALE / 2;
vertices[vi].y = (ranrot_rand() % DUST_SCALE) - DUST_SCALE / 2;
@ -93,7 +93,7 @@ MA 02110-1301, USA.
Vector offset = (player)? player->position: position;
double half_scale = DUST_SCALE * 0.50;
int vi;
for (vi = 0; vi < n_vertices; vi++)
for (vi = 0; vi < vertexCount; vi++)
{
while (vertices[vi].x - offset.x < -half_scale)
vertices[vi].x += DUST_SCALE;
@ -172,7 +172,7 @@ MA 02110-1301, USA.
glBegin(dustMode);
for (vi = 0; vi < n_vertices; vi++)
for (vi = 0; vi < vertexCount; vi++)
{
glVertex3f( vertices[vi].x, vertices[vi].y, vertices[vi].z);
if (warp_stars)

View File

@ -92,7 +92,8 @@ extern int debug;
hasCollided: 1,
isSunlit: 1,
collisionTestFilter: 1,
throw_sparks: 1;
throw_sparks: 1,
isImmuneToBreakPatternHide: 1;
OOScanClass scanClass;
OOEntityStatus status;

View File

@ -34,4 +34,7 @@ MA 02110-1301, USA.
OODrawable *drawable;
}
- (OODrawable *)drawable;
- (void)setDrawable:(OODrawable *)drawable;
@end

View File

@ -37,6 +37,27 @@ MA 02110-1301, USA.
}
- (OODrawable *)drawable
{
return drawable;
}
- (void)setDrawable:(OODrawable *)inDrawable
{
if (inDrawable != drawable)
{
[drawable autorelease];
drawable = [inDrawable retain];
[drawable setBindingTarget:self];
actual_radius = collision_radius = [drawable collisionRadius];
no_draw_distance = [drawable maxDrawDistance];
boundingBox = [drawable boundingBox];
}
}
- (void)reloadTextures
{
[drawable reloadTextures];
@ -63,6 +84,13 @@ MA 02110-1301, USA.
- (void)drawEntity:(BOOL)immediate :(BOOL)translucent
{
if (no_draw_distance < zero_distance)
{
// Don't draw.
return;
}
if (translucent) [drawable renderTranslucentParts];
else [drawable renderOpaqueParts];
}

View File

@ -29,6 +29,28 @@ MA 02110-1301, USA.
#import "OOMesh.h" // Currently, we're sharing structures and constants with OOMesh
typedef char OOStr255[256]; // Not the same as the previously-abused Str255
typedef struct
{
GLfloat red;
GLfloat green;
GLfloat blue;
Vector normal;
int n_verts;
GLint vertex[MAX_VERTICES_PER_FACE];
OOStr255 textureFileName;
GLuint textureName;
GLfloat s[MAX_VERTICES_PER_FACE];
GLfloat t[MAX_VERTICES_PER_FACE];
} Face;
@interface OOSelfDrawingEntity: Entity
{
uint8_t isSmoothShaded: 1,
@ -38,8 +60,9 @@ MA 02110-1301, USA.
brokenInRender: 1,
materialsReady: 1;
uint8_t n_textures;
uint16_t n_vertices, n_faces;
OOMeshMaterialCount textureCount;
OOMeshVertexCount vertexCount;
OOMeshFaceCount faceCount;
NSString *basefile;
@ -50,8 +73,8 @@ MA 02110-1301, USA.
EntityData entityData;
NSRange triangle_range[MAX_TEXTURES_PER_ENTITY];
Str255 texture_file[MAX_TEXTURES_PER_ENTITY];
GLuint texture_name[MAX_TEXTURES_PER_ENTITY];
OOStr255 textureFileName[MAX_TEXTURES_PER_ENTITY];
GLuint textureNames[MAX_TEXTURES_PER_ENTITY];
// COMMON OGL STUFF
#if GL_APPLE_vertex_array_object
@ -64,6 +87,12 @@ MA 02110-1301, USA.
- (void) setModelName:(NSString *)modelName;
- (NSString *) modelName;
- (void)generateDisplayList;
- (void)regenerateDisplayList;
- (void) initializeTextures;
@end

View File

@ -54,11 +54,6 @@ BOOL global_testForVAR;
- (Vector) normalForVertex:(int)v_index withSharedRedValue:(GLfloat)red_value;
- (void)generateDisplayList;
- (void)regenerateDisplayList;
- (void) initializeTextures;
- (void) fakeTexturesWithImageFile: (NSString *) textureFile andMaxSize:(NSSize) maxSize;
- (void) setUpVertexArrays;
@ -138,9 +133,9 @@ BOOL global_testForVAR;
- (Geometry*) geometry
{
Geometry* result = [(Geometry *)[Geometry alloc] initWithCapacity: n_faces];
Geometry* result = [(Geometry *)[Geometry alloc] initWithCapacity: faceCount];
int i;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
Triangle tri;
tri.v[0] = vertices[faces[i].vertex[0]];
@ -191,7 +186,7 @@ BOOL global_testForVAR;
#if GL_APPLE_vertex_array_object
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
#endif
//
// gap removal (draws flat polys)
//
@ -212,9 +207,9 @@ BOOL global_testForVAR;
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_ambient);
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
for (ti = 1; ti <= n_textures; ti++)
for (ti = 1; ti <= textureCount; ti++)
{
glBindTexture(GL_TEXTURE_2D, texture_name[ti]);
glBindTexture(GL_TEXTURE_2D, textureNames[ti]);
glDrawArrays( GL_TRIANGLES, triangle_range[ti].location, triangle_range[ti].length);
}
}
@ -313,7 +308,7 @@ BOOL global_testForVAR;
BoundingBox result;
bounding_box_reset_to_vector(&result,rv);
int i;
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
pv.x = rpos.x + vertices[i].x;
pv.y = rpos.y + vertices[i].y;
@ -327,6 +322,54 @@ BOOL global_testForVAR;
return result;
}
- (void) initializeTextures
{
// roll out each face and texture in turn
//
int fi,ti;
for (fi = 0; fi < faceCount; fi++)
{
NSString* texture = [NSString stringWithUTF8String:faces[fi].textureFileName];
if ((faces[fi].textureName == 0)&&(texture))
{
faces[fi].textureName = [TextureStore getTextureNameFor: texture];
}
}
for (ti = 1; ti <= textureCount; ti++)
{
if (!textureNames[ti])
{
textureNames[ti] = [TextureStore getTextureNameFor:[NSString stringWithUTF8String:textureFileName[ti]]];
}
}
materialsReady = YES;
}
- (void) regenerateDisplayList
{
glDeleteLists(displayListName,1);
displayListName = 0;
}
- (void) generateDisplayList
{
displayListName = glGenLists(1);
if (displayListName != 0)
{
glNewList(displayListName, GL_COMPILE);
[self drawEntity:YES:NO]; // immediate YES translucent NO
glEndList();
//
CheckOpenGLErrors([NSString stringWithFormat:@"Entity after generateDisplayList for %@", self]);
//
}
}
@end
@ -374,8 +417,8 @@ BOOL global_testForVAR;
{
gVertexArrayRangeData[i].rangeSize = 0;
gVertexArrayRangeData[i].dataBlockPtr = nil;
gVertexArrayRangeData[i].forceUpdate = true;
gVertexArrayRangeData[i].activated = false;
gVertexArrayRangeData[i].forceUpdate = YES;
gVertexArrayRangeData[i].activated = NO;
}
return YES;
@ -391,7 +434,7 @@ BOOL global_testForVAR;
gVertexArrayRangeData[whichVAR].rangeSize = size;
gVertexArrayRangeData[whichVAR].dataBlockPtr = data;
gVertexArrayRangeData[whichVAR].forceUpdate = true;
gVertexArrayRangeData[whichVAR].forceUpdate = YES;
}
- (void) OGL_UpdateVAR
@ -428,7 +471,7 @@ BOOL global_testForVAR;
glFlushVertexArrayRangeAPPLE(size, gVertexArrayRangeData[i].dataBlockPtr);
glEnableClientState(GL_VERTEX_ARRAY_RANGE_APPLE);
gVertexArrayRangeData[i].activated = true;
gVertexArrayRangeData[i].activated = YES;
}
// ALREADY ACTIVE, SO JUST UPDATING
@ -438,7 +481,7 @@ BOOL global_testForVAR;
glFlushVertexArrayRangeAPPLE(size, gVertexArrayRangeData[i].dataBlockPtr);
}
gVertexArrayRangeData[i].forceUpdate = false;
gVertexArrayRangeData[i].forceUpdate = NO;
}
}
@ -454,8 +497,8 @@ BOOL global_testForVAR;
int fi;
// Force the entity to reload the textures for each face by clearing the face's texture name.
for (fi = 0; fi < n_faces; fi++)
faces[fi].texName = 0;
for (fi = 0; fi < faceCount; fi++)
faces[fi].textureNames = 0;
materialsReady = NO;
@ -465,67 +508,21 @@ BOOL global_testForVAR;
}
- (void) initializeTextures
{
// roll out each face and texture in turn
//
int fi,ti;
for (fi = 0; fi < n_faces; fi++)
{
NSString* texture = [NSString stringWithUTF8String:(char*)faces[fi].textureFileStr255];
if ((faces[fi].texName == 0)&&(texture))
{
faces[fi].texName = [TextureStore getTextureNameFor: texture];
}
}
for (ti = 1; ti <= n_textures; ti++)
{
if (!texture_name[ti])
{
texture_name[ti] = [TextureStore getTextureNameFor: [NSString stringWithUTF8String: (char*)texture_file[ti]]];
}
}
materialsReady = YES;
}
- (void) regenerateDisplayList
{
glDeleteLists(displayListName,1);
displayListName = 0;
}
- (void) generateDisplayList
{
displayListName = glGenLists(1);
if (displayListName != 0)
{
glNewList(displayListName, GL_COMPILE);
[self drawEntity:YES:NO]; // immediate YES translucent NO
glEndList();
//
CheckOpenGLErrors([NSString stringWithFormat:@"Entity after generateDisplayList for %@", self]);
//
}
}
- (NSDictionary*) modelData
{
NSMutableDictionary* mdict = [NSMutableDictionary dictionaryWithCapacity:8];
[mdict setObject:[NSNumber numberWithInt: n_vertices] forKey:@"n_vertices"];
[mdict setObject:[NSData dataWithBytes: vertices length: sizeof(Vector)*n_vertices] forKey:@"vertices"];
[mdict setObject:[NSData dataWithBytes: vertex_normal length: sizeof(Vector)*n_vertices] forKey:@"normals"];
[mdict setObject:[NSNumber numberWithInt: n_faces] forKey:@"n_faces"];
[mdict setObject:[NSData dataWithBytes: faces length: sizeof(Face)*n_faces] forKey:@"faces"];
[mdict setObject:[NSNumber numberWithInt: vertexCount] forKey:@"vertexCount"];
[mdict setObject:[NSData dataWithBytes: vertices length: sizeof(Vector)*vertexCount] forKey:@"vertices"];
[mdict setObject:[NSData dataWithBytes: vertex_normal length: sizeof(Vector)*vertexCount] forKey:@"normals"];
[mdict setObject:[NSNumber numberWithInt: faceCount] forKey:@"faceCount"];
[mdict setObject:[NSData dataWithBytes: faces length: sizeof(Face)*faceCount] forKey:@"faces"];
return [NSDictionary dictionaryWithDictionary:mdict];
}
- (BOOL) setModelFromModelData:(NSDictionary*) dict
{
n_vertices = [[dict objectForKey:@"n_vertices"] intValue];
n_faces = [[dict objectForKey:@"n_faces"] intValue];
vertexCount = [[dict objectForKey:@"vertexCount"] intValue];
faceCount = [[dict objectForKey:@"faceCount"] intValue];
NSData* vdata = (NSData*)[dict objectForKey:@"vertices"];
NSData* ndata = (NSData*)[dict objectForKey:@"normals"];
NSData* fdata = (NSData*)[dict objectForKey:@"faces"];
@ -535,12 +532,12 @@ BOOL global_testForVAR;
Vector* nbytes = (Vector*)[ndata bytes];
Face* fbytes = (Face*)[fdata bytes];
int i;
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
vertices[i] = vbytes[i];
vertex_normal[i] = nbytes[i];
}
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
faces[i] = fbytes[i];
}
@ -613,7 +610,7 @@ BOOL global_testForVAR;
{
int n_v;
if ([scanner scanInt:&n_v])
n_vertices = n_v;
vertexCount = n_v;
else
{
failFlag = YES;
@ -626,14 +623,14 @@ BOOL global_testForVAR;
failString = [NSString stringWithFormat:@"%@Failed to read NVERTS\n",failString];
}
if (n_vertices > MAX_VERTICES_PER_ENTITY)
if (vertexCount > MAX_VERTICES_PER_ENTITY)
{
OOLog(kOOLogEntityTooManyVertices, @"ERROR - model %@ has too many vertices (model has %d, maximum is %d)", filename, n_vertices, MAX_VERTICES_PER_ENTITY);
OOLog(kOOLogEntityTooManyVertices, @"ERROR - model %@ has too many vertices (model has %d, maximum is %d)", filename, vertexCount, MAX_VERTICES_PER_ENTITY);
failFlag = YES;
// ERROR model file not found
NSException* myException = [NSException
exceptionWithName:@"OoliteException"
reason:[NSString stringWithFormat:@"ERROR - model %@ has too many vertices (model has %d, maximum is %d)", filename, n_vertices, MAX_VERTICES_PER_ENTITY]
reason:[NSString stringWithFormat:@"ERROR - model %@ has too many vertices (model has %d, maximum is %d)", filename, vertexCount, MAX_VERTICES_PER_ENTITY]
userInfo:nil];
[myException raise];
}
@ -645,7 +642,7 @@ BOOL global_testForVAR;
{
int n_f;
if ([scanner scanInt:&n_f])
n_faces = n_f;
faceCount = n_f;
else
{
failFlag = YES;
@ -658,14 +655,14 @@ BOOL global_testForVAR;
failString = [NSString stringWithFormat:@"%@Failed to read NFACES\n",failString];
}
if (n_faces > MAX_FACES_PER_ENTITY)
if (faceCount > MAX_FACES_PER_ENTITY)
{
OOLog(kOOLogEntityTooManyFaces, @"ERROR - model %@ has too many faces (model has %d, maximum is %d)", filename, n_faces, MAX_FACES_PER_ENTITY);
OOLog(kOOLogEntityTooManyFaces, @"ERROR - model %@ has too many faces (model has %d, maximum is %d)", filename, faceCount, MAX_FACES_PER_ENTITY);
failFlag = YES;
// ERROR model file not found
NSException* myException = [NSException
exceptionWithName:@"OoliteException"
reason:[NSString stringWithFormat:@"ERROR - model %@ has too many faces (model has %d, maximum is %d)", filename, n_faces, MAX_FACES_PER_ENTITY]
reason:[NSString stringWithFormat:@"ERROR - model %@ has too many faces (model has %d, maximum is %d)", filename, faceCount, MAX_FACES_PER_ENTITY]
userInfo:nil];
[myException raise];
}
@ -675,7 +672,7 @@ BOOL global_testForVAR;
//[scanner setScanLocation:0]; //reset
if ([scanner scanString:@"VERTEX" intoString:(NSString **)nil])
{
for (j = 0; j < n_vertices; j++)
for (j = 0; j < vertexCount; j++)
{
float x, y, z;
if (!failFlag)
@ -707,7 +704,7 @@ BOOL global_testForVAR;
//
if ([scanner scanString:@"FACES" intoString:(NSString **)nil])
{
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
int r, g, b;
float nx, ny, nz;
@ -789,7 +786,7 @@ BOOL global_testForVAR;
//
if ([scanner scanString:@"TEXTURES" intoString:(NSString **)nil])
{
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
NSString *texfile;
float max_x, max_y;
@ -807,9 +804,9 @@ BOOL global_testForVAR;
else
{
// faces[j].textureFile = [texfile retain];
strlcpy( (char*)faces[j].textureFileStr255, [texfile UTF8String], 256);
strlcpy(faces[j].textureFileName, [texfile UTF8String], 256);
}
faces[j].texName = 0;
faces[j].textureName = 0;
// texture size
//
@ -897,7 +894,7 @@ BOOL global_testForVAR;
{
Vector calculatedNormal;
int i, j;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
Vector v0, v1, v2, norm;
v0 = vertices[faces[i].vertex[0]];
@ -937,8 +934,8 @@ BOOL global_testForVAR;
- (void) calculateVertexNormals
{
int i,j;
float triangle_area[n_faces];
for (i = 0 ; i < n_faces; i++)
float triangle_area[faceCount];
for (i = 0 ; i < faceCount; i++)
{
// calculate areas using Herons formula
// in the form Area = sqrt(2*(a2*b2+b2*c2+c2*a2)-(a4+b4+c4))/4
@ -947,10 +944,10 @@ BOOL global_testForVAR;
float c2 = distance2( vertices[faces[i].vertex[2]], vertices[faces[i].vertex[0]]);
triangle_area[i] = sqrt( 2.0 * (a2 * b2 + b2 * c2 + c2 * a2) - 0.25 * (a2 * a2 + b2 * b2 +c2 * c2));
}
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
Vector normal_sum = kZeroVector;
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
BOOL is_shared = ((faces[j].vertex[0] == i)||(faces[j].vertex[1] == i)||(faces[j].vertex[2] == i));
if (is_shared)
@ -971,7 +968,7 @@ BOOL global_testForVAR;
{
int j;
Vector normal_sum = kZeroVector;
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
if (faces[j].red == red_value)
{
@ -1000,16 +997,16 @@ BOOL global_testForVAR;
// if isSmoothShaded find any vertices that are between faces of two different colour (by red value)
// and mark them as being on an edge and therefore NOT smooth shaded
BOOL is_edge_vertex[n_vertices];
GLfloat red_value[n_vertices];
for (vi = 0; vi < n_vertices; vi++)
BOOL is_edge_vertex[vertexCount];
GLfloat red_value[vertexCount];
for (vi = 0; vi < vertexCount; vi++)
{
is_edge_vertex[vi] = NO;
red_value[vi] = -1;
}
if (isSmoothShaded)
{
for (fi = 0; fi < n_faces; fi++)
for (fi = 0; fi < faceCount; fi++)
{
GLfloat rv = faces[fi].red;
int i;
@ -1029,27 +1026,26 @@ BOOL global_testForVAR;
int tri_index = 0;
int uv_index = 0;
int vertex_index = 0;
entityData.texName = 0;
texi = 1; // index of first texture
for (face = 0; face < n_faces; face++)
for (face = 0; face < faceCount; face++)
{
NSString* tex_string = [NSString stringWithUTF8String: (char*)faces[face].textureFileStr255];
NSString* tex_string = [NSString stringWithUTF8String:faces[face].textureFileName];
if (![texturesProcessed objectForKey:tex_string])
{
// do this texture
triangle_range[texi].location = tri_index;
strlcpy( (char*)texture_file[texi], (char*)faces[face].textureFileStr255, 256);
texture_name[texi] = faces[face].texName;
strlcpy(textureFileName[texi], faces[face].textureFileName, 256);
textureNames[texi] = faces[face].textureName;
for (fi = 0; fi < n_faces; fi++)
for (fi = 0; fi < faceCount; fi++)
{
Vector normal = make_vector( 0.0, 0.0, 1.0);
int v;
if (!isSmoothShaded)
normal = faces[fi].normal;
if (strcmp( (char*)faces[fi].textureFileStr255, (char*)faces[face].textureFileStr255) == 0)
if (strcmp(faces[fi].textureFileName, faces[face].textureFileName) == 0)
{
for (vi = 0; vi < 3; vi++)
{
@ -1081,7 +1077,7 @@ BOOL global_testForVAR;
entityData.n_triangles = tri_index; // total number of triangle vertices
triangle_range[0] = NSMakeRange( 0, tri_index);
n_textures = texi - 1;
textureCount = texi - 1;
}
@ -1091,12 +1087,12 @@ BOOL global_testForVAR;
double d_squared, result, length_longest_axis, length_shortest_axis;
result = 0.0;
if (n_vertices)
if (vertexCount)
bounding_box_reset_to_vector(&boundingBox,vertices[0]);
else
bounding_box_reset(&boundingBox);
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
d_squared = vertices[i].x*vertices[i].x + vertices[i].y*vertices[i].y + vertices[i].z*vertices[i].z;
if (d_squared > result)
@ -1137,8 +1133,8 @@ BOOL global_testForVAR;
BOOL face_matched[MAX_FACES_PER_ENTITY];
tolerance = 1.00;
faces_to_match = n_faces;
for (i = 0; i < n_faces; i++)
faces_to_match = faceCount;
for (i = 0; i < faceCount; i++)
{
face_matched[i] = NO;
}
@ -1152,7 +1148,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1178,7 +1174,7 @@ BOOL global_testForVAR;
{
i = fi[j];
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"top_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"top_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1199,7 +1195,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1222,10 +1218,7 @@ BOOL global_testForVAR;
for (j = 0; j < nf; j++)
{
i = fi[j];
//fa[i] = faces[i];
// fa[i].textureFile = [NSString stringWithFormat:@"bottom_%@", textureFile];
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"bottom_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"bottom_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1242,7 +1235,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1265,10 +1258,7 @@ BOOL global_testForVAR;
for (j = 0; j < nf; j++)
{
i = fi[j];
//fa[i] = faces[i];
// fa[i].textureFile = [NSString stringWithFormat:@"right_%@", textureFile];
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"right_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"right_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1285,7 +1275,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1308,10 +1298,7 @@ BOOL global_testForVAR;
for (j = 0; j < nf; j++)
{
i = fi[j];
//fa[i] = faces[i];
// fa[i].textureFile = [NSString stringWithFormat:@"left_%@", textureFile];
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"left_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"left_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1328,7 +1315,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1351,10 +1338,7 @@ BOOL global_testForVAR;
for (j = 0; j < nf; j++)
{
i = fi[j];
//fa[i] = faces[i];
// fa[i].textureFile = [NSString stringWithFormat:@"front_%@", textureFile];
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"front_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"front_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1371,7 +1355,7 @@ BOOL global_testForVAR;
nf = 0;
max_s = -999999.0; min_s = 999999.0;
max_t = -999999.0; min_t = 999999.0;
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
float s, t;
float g = dot_product(vec, faces[i].normal) * sqrt(2.0);
@ -1394,10 +1378,7 @@ BOOL global_testForVAR;
for (j = 0; j < nf; j++)
{
i = fi[j];
//fa[i] = faces[i];
// fa[i].textureFile = [NSString stringWithFormat:@"back_%@", textureFile];
// strlcpy( (char*)fa[i].textureFileStr255, [fa[i].textureFile UTF8String], 256);
strlcpy( (char*)fa[i].textureFileStr255, [[NSString stringWithFormat:@"back_%@", textureFile] UTF8String], 256);
strlcpy(fa[i].textureFileName, [[NSString stringWithFormat:@"back_%@", textureFile] UTF8String], 256);
for (k = 0; k < faces[i].n_verts; k++)
{
float s, t;
@ -1409,19 +1390,19 @@ BOOL global_testForVAR;
}
}
for (i = 0; i < n_faces; i++)
for (i = 0; i < faceCount; i++)
{
NSString *result;
strlcpy( (char*)faces[i].textureFileStr255, (char*)fa[i].textureFileStr255, 256);
faces[i].texName = 0;
strlcpy(faces[i].textureFileName, fa[i].textureFileName, 256);
faces[i].textureName = 0;
for (j = 0; j < faces[i].n_verts; j++)
{
faces[i].s[j] = fa[i].s[j] / maxSize.width;
faces[i].t[j] = fa[i].t[j] / maxSize.height;
}
result = [NSString stringWithFormat:@"%s\t%d %d", faces[i].textureFileStr255, (int)maxSize.width, (int)maxSize.height];
result = [NSString stringWithFormat:@"%s\t%d %d", faces[i].textureFileName, (int)maxSize.width, (int)maxSize.height];
}
}
@ -1435,8 +1416,8 @@ BOOL global_testForVAR;
int i,j, r,g,b;
NSString *result;
NSString *boilerplate = @"# This is a file adapted from the model files for Java Elite\n# which in turn are based on the data released by Ian Bell\n# in the file b7051600.zip at\n# http://www.users.waitrose.com/~elitearc2/elite/archive/b7051600.zip\n#";
result = [NSString stringWithFormat:@"%@\n# %@\n#\n\nNVERTS %d\nNFACES %d\n\nVERTEX\n", boilerplate, basefile, n_vertices, n_faces];
for (i = 0; i < n_vertices; i++)
result = [NSString stringWithFormat:@"%@\n# %@\n#\n\nNVERTS %d\nNFACES %d\n\nVERTEX\n", boilerplate, basefile, vertexCount, faceCount];
for (i = 0; i < vertexCount; i++)
{
result = [NSString stringWithFormat:@"%@%f,\t%f,\t%f\n", result, vertices[i].x, vertices[i].y, vertices[i].z];
if ((i % 5)==4)
@ -1444,7 +1425,7 @@ BOOL global_testForVAR;
}
result = [NSString stringWithFormat:@"%@\nFACES\n", result];
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
r = (int)(faces[j].red * 255.0); g = (int)(faces[j].green * 255.0); b = (int)(faces[j].blue * 255.0);
result = [NSString stringWithFormat:@"%@%d, %d, %d,\t", result, r, g, b];
@ -1459,11 +1440,9 @@ BOOL global_testForVAR;
if (UNIVERSE)
{
result = [NSString stringWithFormat:@"%@\nTEXTURES\n", result];
for (j = 0; j < n_faces; j++)
for (j = 0; j < faceCount; j++)
{
// NSSize texSize = [TextureStore getSizeOfTexture:faces[j].textureFile];
// result = [NSString stringWithFormat:@"%@%@\t%d %d", result, faces[j].textureFile, (int)texSize.width, (int)texSize.height];
NSString* texture = [NSString stringWithUTF8String: (char*)faces[j].textureFileStr255];
NSString* texture = [NSString stringWithUTF8String: faces[j].textureFileName];
NSSize texSize = [TextureStore getSizeOfTexture: texture];
result = [NSString stringWithFormat:@"%@%@\t%d %d", result, texture, (int)texSize.width, (int)texSize.height];
for (i = 0; i < faces[j].n_verts; i++)

View File

@ -454,13 +454,13 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
[self initialiseTexture: textureNameString];
size = NSMakeSize(32.0,32.0);
//
n_vertices = n_fragments;
vertexCount = n_fragments;
time_counter = 0.0;
duration = 1.5;
position = fragPos;
[self setColor:[OOColor yellowColor]];
//
for (i = 0 ; i < n_vertices; i++)
for (i = 0 ; i < vertexCount; i++)
{
int speed = (ranrot_rand() % (speed_high - speed_low)) + speed_low;
vertices[i] = kZeroVector; // position
@ -506,7 +506,7 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
[self initialiseTexture: textureNameString];
size = NSMakeSize( fragSize, fragSize);
//
n_vertices = n_fragments;
vertexCount = n_fragments;
time_counter = 0.0;
duration = 1.5;
position = fragPos;
@ -559,12 +559,12 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
[self initialiseTexture: textureNameString];
size = NSMakeSize(32.0,32.0);
//
n_vertices = n_fragments;
vertexCount = n_fragments;
time_counter = 0.0;
duration = 1.5;
position = fragPos;
//
for (i = 0 ; i < n_vertices; i++)
for (i = 0 ; i < vertexCount; i++)
{
int speed = speed_low + ranrot_rand() % (speed_high - speed_low);
vertices[i] = kZeroVector;
@ -607,7 +607,7 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
[self initialiseTexture: textureNameString];
size = NSMakeSize( burstSize, burstSize);
//
n_vertices = n_fragments;
vertexCount = n_fragments;
time_counter = 0.0;
duration = 1.0;
position = fragPos;
@ -1212,7 +1212,7 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
{
int i;
//
for (i = 0 ; i < n_vertices; i++)
for (i = 0 ; i < vertexCount; i++)
{
GLfloat du = 0.5 + 0.03125 * (32 - i);
GLfloat alf = 1.0 - time_counter / du;
@ -1234,8 +1234,8 @@ static Vector circleVertex[65]; // holds vector coordinates for a unit circle
int i;
size.width = (1.0 + time_counter) * size.height; // current size vs starting size
//
GLfloat di = 1.0 / (n_vertices - 1);
for (i = 0 ; i < n_vertices; i++)
GLfloat di = 1.0 / (vertexCount - 1);
for (i = 0 ; i < vertexCount; i++)
{
GLfloat du = duration * (0.5 + di * i);
GLfloat alf = 1.0 - time_counter / du;
@ -1930,7 +1930,7 @@ GLuint tfan2[10] = { 33, 25, 26, 27, 28, 29, 30, 31, 32, 25}; // final fan 64..7
BeginAdditiveBlending();
glBegin(GL_QUADS);
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
glColor4f( faces[i].red, faces[i].green, faces[i].blue, faces[i].normal.z);
DrawQuadForView(vertices[i].x, vertices[i].y, vertices[i].z, faces[i].normal.x, faces[i].normal.x);
@ -1955,7 +1955,7 @@ GLuint tfan2[10] = { 33, 25, 26, 27, 28, 29, 30, 31, 32, 25}; // final fan 64..7
BeginAdditiveBlending();
glBegin(GL_QUADS);
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
glColor4f( faces[i].red, faces[i].green, faces[i].blue, faces[i].normal.z);
DrawQuadForView(vertices[i].x, vertices[i].y, vertices[i].z, size.width, size.width);

View File

@ -110,7 +110,7 @@ void setUpSinTable()
ranrot_srand(planet_seed);
percent_land = (ranrot_rand() % 50);
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
if (ranrot_rand() % 100 < percent_land) r_seed[i] = 0; // land
else r_seed[i] = 1; // sea
@ -470,7 +470,7 @@ void setUpSinTable()
// save the current random number generator seed
RNG_Seed saved_seed = currentRandomSeed();
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
if (gen_rnd_number() < 256 * percent_land / 100)
r_seed[i] = 0; // land
@ -636,7 +636,7 @@ void setUpSinTable()
[self initialiseBaseVertexArray];
int* planet_r_seed = [planet r_seed];
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
r_seed[i] = planet_r_seed[i]; // land or sea
[self initialiseBaseTerrainArray: -1]; // use the vertices we just set up
@ -759,7 +759,7 @@ void setUpSinTable()
// save the current random number generator seed
RNG_Seed saved_seed = currentRandomSeed();
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
if (gen_rnd_number() < 256 * percent_land / 100)
r_seed[i] = 0; // land
@ -929,7 +929,7 @@ void setUpSinTable()
// save the current random number generator seed
RNG_Seed saved_seed = currentRandomSeed();
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
if (gen_rnd_number() < 256 * percent_land / 100)
r_seed[i] = 0; // land
@ -1773,7 +1773,7 @@ void drawActiveCorona (double inner_radius, double outer_radius, int step, doubl
int i;
Vector vert;
for (i = 0; i < n_vertices; i++)
for (i = 0; i < vertexCount; i++)
{
vert = vertices[i]; // not guaranteed non-zero
if ((vert.x == 0.0)&&(vert.y == 0.0)&&(vert.z == 0.0))
@ -1870,14 +1870,14 @@ static BOOL last_one_was_textured;
//
// set first 12 or 14 vertices
//
for (vi = 0; vi < n_vertices; vi++)
for (vi = 0; vi < vertexCount; vi++)
base_vertex_array[next_free_vertex++] = vertices[vi];
//
// set first 20 triangles
//
triangle_start[0] = 0;
n_triangles[0] = n_faces;
for (fi = 0; fi < n_faces; fi++)
n_triangles[0] = faceCount;
for (fi = 0; fi < faceCount; fi++)
{
vertex_index_array[fi * 3 + 0] = faces[fi].vertex[0];
vertex_index_array[fi * 3 + 1] = faces[fi].vertex[1];
@ -1991,7 +1991,7 @@ int baseVertexIndexForEdge(int va, int vb, BOOL textured)
// set first 12 or 14 vertices
if (percent_land >= 0)
{
for (vi = 0; vi < n_vertices; vi++)
for (vi = 0; vi < vertexCount; vi++)
{
if (gen_rnd_number() < 256 * percent_land / 100)
base_terrain_array[vi] = 0; // land

View File

@ -997,7 +997,8 @@ static PlayerEntity *sSharedPlayer = nil;
for (i = 0; i < missiles; i++)
{
[missile_entity[i] release];
missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"]; // retain count = 1
// missile_entity[i] = [UNIVERSE newShipWithRole:@"EQ_MISSILE"]; // retain count = 1
missile_entity[i] = nil;
}
[self safe_all_missiles];

View File

@ -1361,8 +1361,8 @@ static NSMutableDictionary* currentShipyard = nil;
// change ship_desc
// TODO: detect brokenness here.
if (ship_desc) [ship_desc release];
ship_desc = [[ship_info stringForKey:SHIPYARD_KEY_SHIPDATA_KEY defaultValue:nil] copy];
NSDictionary *shipDict = [ship_info dictionaryForKey:SHIPYARD_KEY_SHIP defaultValue:nil];
ship_desc = [[ship_info stringForKey:SHIPYARD_KEY_SHIPDATA_KEY] copy];
NSDictionary *shipDict = [ship_info dictionaryForKey:SHIPYARD_KEY_SHIP];
// get a full tank for free
fuel = PLAYER_MAX_FUEL;
@ -1374,7 +1374,7 @@ static NSMutableDictionary* currentShipyard = nil;
aft_weapon = WEAPON_NONE;
port_weapon = WEAPON_NONE;
starboard_weapon = WEAPON_NONE;
forward_weapon = EquipmentStringToWeaponType([shipDict stringForKey:@"forward_weapon_type" defaultValue:nil]);
forward_weapon = EquipmentStringToWeaponType([shipDict stringForKey:@"forward_weapon_type"]);
// get basic max_cargo
max_cargo = [UNIVERSE maxCargoForShip:ship_desc];
@ -1394,7 +1394,7 @@ static NSMutableDictionary* currentShipyard = nil;
[self tidyMissilePylons];
// get missiles from ship_info
missiles = [shipDict intForKey:@"missiles" defaultValue:0];
missiles = [shipDict intForKey:@"missiles"];
// clear legal_status for free
legal_status = 0;

View File

@ -93,6 +93,7 @@ Ringdata ringentity;
velocity.z = 1.0;
//
isRing = YES;
isImmuneToBreakPatternHide = YES;
//
return self;
}

View File

@ -25,11 +25,10 @@ MA 02110-1301, USA.
*/
// #import "OOEntityWithDrawable.h"
#import "OOSelfDrawingEntity.h"
#import "OOEntityWithDrawable.h"
@class OOBrain, OOColor, StationEntity, ParticleEntity, PlanetEntity,
WormholeEntity, AI, Octree;
WormholeEntity, AI, Octree, OOMesh;
#define MAX_TARGETS 24
@ -80,7 +79,7 @@ MA 02110-1301, USA.
#define MAX_SCAN_NUMBER 16
@interface ShipEntity: OOSelfDrawingEntity // OOEntityWithDrawable
@interface ShipEntity: OOEntityWithDrawable
{
@public
NSArray *sub_entities;
@ -92,9 +91,6 @@ MA 02110-1301, USA.
// navigation
Vector v_forward, v_up, v_right; // unit vectors derived from the direction faced
// collision management
Octree* octree; // this is not retained by the ShipEntity but kept in a global dict.
// variables which are controlled by instincts/AI
Vector destination; // for flying to/from a set point
OOUniversalID primaryTarget; // for combat or rendezvous
@ -235,7 +231,6 @@ MA 02110-1301, USA.
GLfloat pitch_tolerance;
// BOOL within_station_aegis; // set to YES when within the station's protective zone
OOAegisStatus aegis_status; // set to YES when within the station's protective zone
double message_time; // counts down the seconds a radio message is active for
@ -281,6 +276,9 @@ MA 02110-1301, USA.
int next_navpoint_index;
int number_of_navpoints;
// Collision detection
Octree *octree;
// DEBUGGING
int debug_flag;
int debug_condition;
@ -294,6 +292,9 @@ MA 02110-1301, USA.
- (OOBrain*) brain;
- (void) setBrain:(OOBrain*) aBrain;
- (OOMesh *)mesh;
- (void)setMesh:(OOMesh *)mesh;
// octree collision hunting
- (GLfloat) doesHitLine:(Vector) v0: (Vector) v1;
- (GLfloat) doesHitLine:(Vector) v0: (Vector) v1 :(ShipEntity**) hitEntity;
@ -311,14 +312,10 @@ MA 02110-1301, USA.
- (void) setUpEscorts;
- (void) rescaleBy:(GLfloat) factor;
- (id) initWithDictionary:(NSDictionary *) dict;
- (void) setUpShipFromDictionary:(NSDictionary *) dict;
- (NSDictionary*) shipInfoDictionary;
- (void) setOctree:(Octree*) oct;
- (void) setDefaultWeaponOffsets;
- (BOOL)isFrangible;
@ -649,10 +646,4 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role);
BOOL ship_canCollide (ShipEntity* ship);
@interface OOCacheManager (Octree)
+ (Octree *)octreeForModel:(NSString *)inKey;
+ (void)setOctree:(Octree *)inOctree forModel:(NSString *)inKey;
@end
NSDictionary *DefaultShipShaderMacros(void);

View File

@ -41,6 +41,7 @@ MA 02110-1301, USA.
#import "OOBrain.h"
#import "AI.h"
#import "OOMesh.h"
#import "Geometry.h"
#import "Octree.h"
#import "OOColor.h"
@ -61,9 +62,11 @@ extern NSString * const kOOLogSyntaxAddShips;
static NSString * const kOOLogEntityBehaviourChanged = @"entity.behaviour.changed";
#if OLD_SHADERS
static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProgram);
#endif
@interface ShipEntity (Private)
- (void) drawSubEntity:(BOOL) immediate :(BOOL) translucent;
@end
@implementation ShipEntity
@ -99,7 +102,7 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
- (void) setUpShipFromDictionary:(NSDictionary *) dict
{
NSDictionary *shipdict = dict;
NSDictionary *shipDict = dict;
int i;
// Does this positional stuff need setting up here?
@ -117,31 +120,31 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
for (;;)
{
// TODO: avoid reference loops.
NSString *other_shipdesc = [shipdict stringForKey:@"like_ship" defaultValue:nil];
NSDictionary *other_shipdict = [UNIVERSE getDictionaryForShip:other_shipdesc];
if (other_shipdict == nil) break;
NSString *other_shipdesc = [shipDict stringForKey:@"like_ship"];
NSDictionary *other_shipDict = [UNIVERSE getDictionaryForShip:other_shipdesc];
if (other_shipDict == nil) break;
other_shipdesc = [other_shipdict objectForKey:@"like_ship"];
other_shipdesc = [other_shipDict objectForKey:@"like_ship"];
NSMutableDictionary* this_shipdict = [NSMutableDictionary dictionaryWithDictionary:other_shipdict]; // basics from that one
[this_shipdict addEntriesFromDictionary:shipdict]; // overrides from this one
[this_shipdict setObject:other_shipdesc forKey:@"like_ship"];
shipdict = this_shipdict;
NSMutableDictionary* this_shipDict = [NSMutableDictionary dictionaryWithDictionary:other_shipDict]; // basics from that one
[this_shipDict addEntriesFromDictionary:shipDict]; // overrides from this one
[this_shipDict setObject:other_shipdesc forKey:@"like_ship"];
shipDict = this_shipDict;
}
shipinfoDictionary = [shipdict copy];
shipdict = shipinfoDictionary; // TEMP: ensure no mutation
shipinfoDictionary = [shipDict copy];
shipDict = shipinfoDictionary; // TEMP: ensure no mutation
// set things from dictionary from here out
max_flight_speed = [shipdict doubleForKey:@"max_flight_speed" defaultValue:0.0f];
max_flight_roll = [shipdict doubleForKey:@"max_flight_roll" defaultValue:0.0f];
max_flight_pitch = [shipdict doubleForKey:@"max_flight_pitch" defaultValue:0.0f];
max_flight_yaw = [shipdict doubleForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch
max_flight_speed = [shipDict doubleForKey:@"max_flight_speed"];
max_flight_roll = [shipDict doubleForKey:@"max_flight_roll"];
max_flight_pitch = [shipDict doubleForKey:@"max_flight_pitch"];
max_flight_yaw = [shipDict doubleForKey:@"max_flight_yaw" defaultValue:max_flight_pitch]; // Note by default yaw == pitch
thrust = [shipdict doubleForKey:@"thrust" defaultValue:thrust];
thrust = [shipDict doubleForKey:@"thrust" defaultValue:thrust];
// This was integer percentages, made it floating point... I don't see any reason to limit the value's precision. -- Ahruman
float accuracy = [shipdict doubleForKey:@"accuracy" defaultValue:-100]; // Out-of-range default
float accuracy = [shipDict doubleForKey:@"accuracy" defaultValue:-100]; // Out-of-range default
if (accuracy >= -5.0f && accuracy <= 10.0f)
{
pitch_tolerance = 0.01 * (85.0f + accuracy);
@ -152,35 +155,35 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
pitch_tolerance = 0.01 * (80 +(ranrot_rand() & 15));
}
maxEnergy = [shipdict floatForKey:@"max_energy" defaultValue:0.0];
energy_recharge_rate = [shipdict floatForKey:@"energy_recharge_rate" defaultValue:0.0];
maxEnergy = [shipDict floatForKey:@"max_energy"];
energy_recharge_rate = [shipDict floatForKey:@"energy_recharge_rate"];
forward_weapon_type = StringToWeaponType([shipdict stringForKey:@"forward_weapon_type" defaultValue:@"WEAPON_NONE"]);
aft_weapon_type = StringToWeaponType([shipdict stringForKey:@"aft_weapon_type" defaultValue:@"WEAPON_NONE"]);
forward_weapon_type = StringToWeaponType([shipDict stringForKey:@"forward_weapon_type" defaultValue:@"WEAPON_NONE"]);
aft_weapon_type = StringToWeaponType([shipDict stringForKey:@"aft_weapon_type" defaultValue:@"WEAPON_NONE"]);
weapon_energy = [shipdict doubleForKey:@"weapon_energy" defaultValue:0.0];
scanner_range = [shipdict doubleForKey:@"weapon_energy" defaultValue:25600.0];
missiles = [shipdict intForKey:@"missiles" defaultValue:0];
weapon_energy = [shipDict doubleForKey:@"weapon_energy"];
scanner_range = [shipDict doubleForKey:@"weapon_energy" defaultValue:25600.0];
missiles = [shipDict intForKey:@"missiles"];
// upgrades:
has_ecm = [shipdict fuzzyBooleanForKey:@"has_ecm" defaultValue:0.0];
has_scoop = [shipdict fuzzyBooleanForKey:@"has_scoop" defaultValue:0.0];
has_escape_pod = [shipdict fuzzyBooleanForKey:@"has_escape_pod" defaultValue:0.0];
has_energy_bomb = [shipdict fuzzyBooleanForKey:@"has_energy_bomb" defaultValue:0.0];
has_fuel_injection = [shipdict fuzzyBooleanForKey:@"has_fuel_injection" defaultValue:0.0];
has_cloaking_device = [shipdict fuzzyBooleanForKey:@"has_cloaking_device" defaultValue:0.0];
has_military_jammer = [shipdict fuzzyBooleanForKey:@"has_military_jammer" defaultValue:0.0];
has_military_scanner_filter = [shipdict fuzzyBooleanForKey:@"has_military_scanner_filter" defaultValue:0.0];
canFragment = [shipdict fuzzyBooleanForKey:@"fragment_chance" defaultValue:0.9];
has_ecm = [shipDict fuzzyBooleanForKey:@"has_ecm"];
has_scoop = [shipDict fuzzyBooleanForKey:@"has_scoop"];
has_escape_pod = [shipDict fuzzyBooleanForKey:@"has_escape_pod"];
has_energy_bomb = [shipDict fuzzyBooleanForKey:@"has_energy_bomb"];
has_fuel_injection = [shipDict fuzzyBooleanForKey:@"has_fuel_injection"];
has_cloaking_device = [shipDict fuzzyBooleanForKey:@"has_cloaking_device"];
has_military_jammer = [shipDict fuzzyBooleanForKey:@"has_military_jammer"];
has_military_scanner_filter = [shipDict fuzzyBooleanForKey:@"has_military_scanner_filter"];
canFragment = [shipDict fuzzyBooleanForKey:@"fragment_chance" defaultValue:0.9];
cloaking_device_active = NO;
military_jammer_active = NO;
if ([shipdict fuzzyBooleanForKey:@"has_shield_booster" defaultValue:0.0])
if ([shipDict fuzzyBooleanForKey:@"has_shield_booster"])
{
maxEnergy += 256.0f;
}
if ([shipdict fuzzyBooleanForKey:@"has_shield_enhancer" defaultValue:0.0])
if ([shipDict fuzzyBooleanForKey:@"has_shield_enhancer"])
{
maxEnergy += 256.0f;
energy_recharge_rate *= 1.5;
@ -189,27 +192,27 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
// Moved here from above upgrade loading so that ships start with full energy banks. -- Ahruman
energy = maxEnergy;
fuel = [shipdict intForKey:@"fuel" defaultValue:0]; // Does it make sense that this defaults to 0? Should it not be 70? -- Ahruman
fuel = [shipDict intForKey:@"fuel"]; // Does it make sense that this defaults to 0? Should it not be 70? -- Ahruman
fuel_accumulator = 1.0;
bounty = [shipdict intForKey:@"bounty" defaultValue:0];
bounty = [shipDict intForKey:@"bounty"];
[shipAI autorelease];
shipAI = [[AI alloc] init];
[shipAI setStateMachine:[shipdict stringForKey:@"ai_type" defaultValue:@"nullAI.plist"]];
[shipAI setStateMachine:[shipDict stringForKey:@"ai_type" defaultValue:@"nullAI.plist"]];
max_cargo = [shipdict intForKey:@"max_cargo" defaultValue:0];
likely_cargo = [shipdict intForKey:@"likely_cargo" defaultValue:0];
extra_cargo = [shipdict intForKey:@"extra_cargo" defaultValue:15];
max_cargo = [shipDict intForKey:@"max_cargo"];
likely_cargo = [shipDict intForKey:@"likely_cargo"];
extra_cargo = [shipDict intForKey:@"extra_cargo" defaultValue:15];
if ([shipdict objectForKey:@"cargo_carried"])
if ([shipDict objectForKey:@"cargo_carried"])
{
cargo_flag = CARGO_FLAG_FULL_UNIFORM;
[self setCommodity:NSNotFound andAmount:0];
int c_commodity = NSNotFound;
int c_amount = 1;
NSScanner* scanner = [NSScanner scannerWithString: [shipdict objectForKey:@"cargo_carried"]];
NSScanner* scanner = [NSScanner scannerWithString: [shipDict objectForKey:@"cargo_carried"]];
if ([scanner scanInt: &c_amount])
{
[scanner ooliteScanCharactersFromSet:[NSCharacterSet whitespaceCharacterSet] intoString:NULL]; // skip whitespace
@ -218,39 +221,45 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
else
{
c_amount = 1;
c_commodity = [UNIVERSE commodityForName: (NSString*)[shipdict objectForKey:@"cargo_carried"]];
c_commodity = [UNIVERSE commodityForName: (NSString*)[shipDict objectForKey:@"cargo_carried"]];
}
if (c_commodity != NSNotFound) [self setCommodity:c_commodity andAmount:c_amount];
}
if ([shipdict objectForKey:@"cargo_type"])
if ([shipDict objectForKey:@"cargo_type"])
{
cargo_type = StringToCargoType([shipdict objectForKey:@"cargo_type"]);
cargo_type = StringToCargoType([shipDict objectForKey:@"cargo_type"]);
[cargo autorelease];
cargo = [[NSMutableArray alloc] initWithCapacity:max_cargo]; // alloc retains;
}
// A HACK!! - must do this before the model is set
isSmoothShaded = [shipdict boolForKey:@"smooth" defaultValue:NO];
// Load the model (must be before subentities)
NSString *modelName = [shipDict stringForKey:@"model"];
if (modelName != nil)
{
OOMesh *mesh = [OOMesh meshWithName:modelName
materialDictionary:[shipDict dictionaryForKey:@"materials"]
shadersDictionary:[shipDict dictionaryForKey:@"shaders"]
smooth:[shipDict boolForKey:@"smooth" defaultValue:NO]
shaderMacros:DefaultShipShaderMacros()
shaderBindingTarget:self];
[self setMesh:mesh];
}
// must do this next one before checking subentities
NSString *modelName = [shipdict stringForKey:@"model" defaultValue:nil];
if (modelName != nil) [self setModelName:modelName];
float density = [shipdict floatForKey:@"density" defaultValue:1.0];
float density = [shipDict floatForKey:@"density" defaultValue:1.0];
if (octree) mass = density * 20.0 * [octree volume];
[name autorelease];
name = [[shipdict stringForKey:@"name" defaultValue:name] copy];
name = [[shipDict stringForKey:@"name" defaultValue:name] copy];
[roles release];
roles = [[shipdict stringForKey:@"roles" defaultValue:nil] copy];
roles = [[shipDict stringForKey:@"roles"] copy];
[self setOwner:self];
NSArray *plumes = [shipdict arrayForKey:@"exhaust" defaultValue:nil];
NSArray *plumes = [shipDict arrayForKey:@"exhaust"];
for (i = 0; i < [plumes count]; i++)
{
ParticleEntity *exhaust = [[ParticleEntity alloc] initExhaustFromShip:self details:[plumes objectAtIndex:i]];
@ -258,9 +267,9 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
[exhaust release];
}
is_hulk = [shipdict boolForKey:@"is_hulk" defaultValue:NO];
is_hulk = [shipDict boolForKey:@"is_hulk" defaultValue:NO];
NSArray *subs = [shipdict arrayForKey:@"subentities" defaultValue:nil];
NSArray *subs = [shipDict arrayForKey:@"subentities"];
for (i = 0; i < [subs count]; i++)
{
NSArray *details = ScanTokensFromString([subs objectAtIndex:i]);
@ -331,21 +340,21 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
}
}
isFrangible = [shipdict boolForKey:@"frangible" defaultValue:YES];
isFrangible = [shipDict boolForKey:@"frangible" defaultValue:YES];
OOColor *color = [OOColor brightColorWithDescription:[shipdict objectForKey:@"laser_color"]];
OOColor *color = [OOColor brightColorWithDescription:[shipDict objectForKey:@"laser_color"]];
if (color == nil) color = [OOColor redColor];
[self setLaserColor:color];
// scan class
scanClass = StringToScanClass([shipdict objectForKey:@"scanClass"]);
scanClass = StringToScanClass([shipDict objectForKey:@"scanClass"]);
// scripting
// TODO: use OOScript here. -- Ahruman
launch_actions = [[shipdict arrayForKey:KEY_LAUNCH_ACTIONS defaultValue:nil] copy];
script_actions = [[shipdict arrayForKey:KEY_LAUNCH_ACTIONS defaultValue:nil] copy];
death_actions = [[shipdict arrayForKey:KEY_LAUNCH_ACTIONS defaultValue:nil] copy];
NSArray *setUpActions = [shipdict arrayForKey:KEY_SETUP_ACTIONS defaultValue:nil];
launch_actions = [[shipDict arrayForKey:KEY_LAUNCH_ACTIONS] copy];
script_actions = [[shipDict arrayForKey:KEY_LAUNCH_ACTIONS] copy];
death_actions = [[shipDict arrayForKey:KEY_LAUNCH_ACTIONS] copy];
NSArray *setUpActions = [shipDict arrayForKey:KEY_SETUP_ACTIONS];
if (setUpActions != nil)
{
PlayerEntity* player = [PlayerEntity sharedPlayer];
@ -354,23 +363,23 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
}
// escorts
n_escorts = [shipdict intForKey:@"escorts" defaultValue:0];
n_escorts = [shipDict intForKey:@"escorts"];
escortsAreSetUp = (n_escorts == 0);
// beacons
NSString *beaconCode = [shipdict stringForKey:@"beacon" defaultValue:nil];
NSString *beaconCode = [shipDict stringForKey:@"beacon"];
if (beaconCode == nil) beaconChar = '\0';
else beaconChar = [beaconCode lossyCString][0];
// rotating subentities
subentityRotationalVelocity = kIdentityQuaternion;
ScanQuaternionFromString([shipdict objectForKey:@"rotational_velocity"], &subentityRotationalVelocity);
ScanQuaternionFromString([shipDict objectForKey:@"rotational_velocity"], &subentityRotationalVelocity);
// contact tracking entities
//
if ([shipdict objectForKey:@"track_contacts"])
if ([shipDict objectForKey:@"track_contacts"])
{
[self setTrackCloseContacts:[[shipdict objectForKey:@"track_contacts"] boolValue]];
[self setTrackCloseContacts:[[shipDict objectForKey:@"track_contacts"] boolValue]];
// DEBUG....
[self setReportAImessages:YES];
}
@ -382,30 +391,28 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
// set weapon offsets
[self setDefaultWeaponOffsets];
//
ScanVectorFromString([shipdict objectForKey:@"weapon_position_forward"], &forwardWeaponOffset);
ScanVectorFromString([shipdict objectForKey:@"weapon_position_aft"], &aftWeaponOffset);
ScanVectorFromString([shipdict objectForKey:@"weapon_position_port"], &portWeaponOffset);
ScanVectorFromString([shipdict objectForKey:@"weapon_position_starboard"], &starboardWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_forward"], &forwardWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_aft"], &aftWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_port"], &portWeaponOffset);
ScanVectorFromString([shipDict objectForKey:@"weapon_position_starboard"], &starboardWeaponOffset);
// fuel scoop destination position (where cargo gets sucked into)
tractor_position = kZeroVector;
ScanVectorFromString([shipdict objectForKey:@"scoop_position"], &tractor_position);
ScanVectorFromString([shipDict objectForKey:@"scoop_position"], &tractor_position);
// ship skin insulation factor (1.0 is normal)
heat_insulation = [shipdict doubleForKey:@"heat_insulation" defaultValue:1.0];
heat_insulation = [shipDict doubleForKey:@"heat_insulation" defaultValue:1.0];
// crew and passengers
NSDictionary* cdict = [[UNIVERSE characters] objectForKey:[shipdict stringForKey:@"pilot" defaultValue:nil]];
NSDictionary* cdict = [[UNIVERSE characters] objectForKey:[shipDict stringForKey:@"pilot"]];
if (cdict != nil)
{
OOCharacter *pilot = [OOCharacter characterWithDictionary:cdict];
[self setCrew:[NSArray arrayWithObject:pilot]];
}
[self initializeTextures];
// unpiloted (like missiles asteroids etc.)
if ([shipdict fuzzyBooleanForKey:@"unpiloted" defaultValue:0.0f]) [self setCrew:nil];
if ([shipDict fuzzyBooleanForKey:@"unpiloted"]) [self setCrew:nil];
}
@ -465,36 +472,24 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
return [NSString stringWithFormat:@"<%@ %@ %d>", [self class], name, universalID];
}
- (void) setOctree:(Octree*) oct
- (OOMesh *)mesh
{
[octree release];
octree = [oct retain];
return (OOMesh *)[self drawable];
}
- (void) setModelName:(NSString*) modelName
- (void)setMesh:(OOMesh *)mesh
{
NS_DURING
[super setModelName:modelName];
NS_HANDLER
if ([[localException name] isEqual: OOLITE_EXCEPTION_DATA_NOT_FOUND])
{
OOLog(kOOLogException, @"***** Oolite Data Not Found Exception : '%@' in [ShipEntity setModelName:] *****", [localException reason]);
}
[localException raise];
NS_ENDHANDLER
Octree *newOctree;
newOctree = [OOCacheManager octreeForModel:modelName];
if (newOctree == nil)
if (mesh != [self mesh])
{
newOctree = [[self geometry] findOctreeToDepth: OCTREE_MAX_DEPTH];
[OOCacheManager setOctree:newOctree forModel:modelName];
[self setDrawable:mesh];
[octree autorelease];
octree = [[mesh octree] retain];
}
[self setOctree:newOctree];
}
// ship's brains!
- (OOBrain*) brain
{
@ -590,8 +585,8 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
}
// Tell subentities, too
NSEnumerator *subEntityEnum;
Entity *subEntity;
NSEnumerator *subEntityEnum = nil;
Entity *subEntity = nil;
for (subEntityEnum = [sub_entities objectEnumerator]; (subEntity = [subEntityEnum nextObject]); )
{
@ -604,8 +599,8 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
- (void) wasRemovedFromUniverse
{
NSEnumerator *subEntityEnum;
Entity *subEntity;
NSEnumerator *subEntityEnum = nil;
Entity *subEntity = nil;
for (subEntityEnum = [sub_entities objectEnumerator]; (subEntity = [subEntityEnum nextObject]); )
{
@ -752,70 +747,7 @@ static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProg
}
- (void) rescaleBy:(GLfloat) factor
{
// rescale vertices and rebuild vertex arrays
//
int i;
for (i = 0; i < n_vertices; i++)
{
vertices[i].x *= factor;
vertices[i].y *= factor;
vertices[i].z *= factor;
}
[self setUpVertexArrays];
usingVAR = [self OGL_InitVAR];
if (usingVAR)
[self OGL_AssignVARMemory:sizeof(EntityData) :(void *)&entityData :0];
// rescale the collision radii & bounding box
//
collision_radius *= factor;
actual_radius *= factor;
boundingBox.min.x *= factor;
boundingBox.min.y *= factor;
boundingBox.min.z *= factor;
boundingBox.max.x *= factor;
boundingBox.max.y *= factor;
boundingBox.max.z *= factor;
// rescale octree
//
[self setOctree:[octree octreeScaledBy: factor]];
// rescale positions of subentities
//
int n_subs = [sub_entities count];
for (i = 0; i < n_subs; i++)
{
Entity* se = (Entity*)[sub_entities objectAtIndex:i];
se->position.x *= factor;
se->position.y *= factor;
se->position.z *= factor;
// rescale ship subentities
if (se->isShip)
[(ShipEntity*)se rescaleBy: factor];
// rescale particle subentities
if (se->isParticle)
{
ParticleEntity* pe = (ParticleEntity*)se;
NSSize sz = [pe size];
sz.width *= factor;
sz.height *= factor;
[pe setSize: sz];
}
}
// rescale mass
//
mass *= factor * factor * factor;
}
- (NSDictionary*) shipInfoDictionary
- (NSDictionary *)shipInfoDictionary
{
return shipinfoDictionary;
}
@ -1016,6 +948,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
}
#if OBSOLETE
- (BoundingBox) findSubentityBoundingBox
{
BoundingBox result;
@ -1037,6 +970,12 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
return result;
}
#else
- (BoundingBox)findSubentityBoundingBox
{
return [[self mesh] findSubentityBoundingBoxWithPosition:position rotMatrix:rotMatrix];
}
#endif
- (Vector) absolutePositionForSubentity
@ -2432,243 +2371,30 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
}
- (void) initializeTextures
- (void)drawEntity:(BOOL)immediate :(BOOL)translucent
{
NSDictionary *shaderDefs = nil;
NSEnumerator *shaderEnum = nil;
NSString *shaderKey = nil;
NSDictionary *shaderConfig = nil;
OOShaderMaterial *shader = nil;
static NSDictionary *macros = nil;
static NSDictionary *defaultBindings = nil;
Entity *propertyEntity = nil;
NSDictionary *materialDefaults = nil;
[super initializeTextures];
// TODO: this won't do when we have non-shader OOMaterials.
if (![[OOOpenGLExtensionManager sharedManager] shadersSupported]) return;
shaderDefs = [shipinfoDictionary objectForKey:@"shaders"];
if (shaderDefs)
{
if (materials)
{
OOLog(@"shipEntity.squashRecycling", @"Hmm, shaders is non-nil for %@.", self);
[materials release];
}
materials = [[NSMutableDictionary alloc] init];
OOLog(@"shader.vessel.init", @"Initialising shaders for %@", self);
OOLogIndentIf(@"shader.vessel.init");
if (macros == nil)
{
// Set up macros and bindings used for all ship shaders
materialDefaults = [ResourceManager dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
macros = [[materialDefaults dictionaryForKey:@"ship-prefix-macros" defaultValue:[NSDictionary dictionary]] retain];
defaultBindings = [[materialDefaults dictionaryForKey:@"ship-default-bindings" defaultValue:[NSDictionary dictionary]] retain];
}
propertyEntity = [self entityForShaderProperties];
for (shaderEnum = [shaderDefs keyEnumerator]; (shaderKey = [shaderEnum nextObject]); )
{
shaderConfig = [shaderDefs dictionaryForKey:shaderKey defaultValue:nil];
if (shaderConfig != nil)
{
shader = [OOShaderMaterial shaderMaterialWithName:shaderKey configuration:shaderConfig macros:macros bindingTarget:propertyEntity];
if (shader != nil)
{
[materials setObject:shader forKey:shaderKey];
[shader addUniformsFromDictionary:defaultBindings withBindingTarget:propertyEntity];
[shader bindUniform:@"time"
toObject:UNIVERSE
property:@selector(getTime)
clamped:NO];
}
}
}
OOLogOutdentIf(@"shader.vessel.init");
}
materialsReady = YES;
}
- (Entity *)entityForShaderProperties
{
if (!isSubentity) return self;
else return [self owner];
}
- (void)exerciseMaterials
{
NSEnumerator *materialEnum = nil;
OOMaterial *material = nil;
for (materialEnum = [materials objectEnumerator]; (material = [materialEnum nextObject]); )
{
[material ensureFinishedLoading];
}
}
- (void) drawEntity:(BOOL) immediate :(BOOL) translucent
{
NSString *textureKey = nil;
unsigned i;
OOMaterial *material = nil;
NSEnumerator *subEntityEnum = nil;
Entity *subEntity = nil;
ShipEntity *subEntity = nil;
if (no_draw_distance < zero_distance ||
[UNIVERSE breakPatternHide] ||
if ((no_draw_distance < zero_distance) || // Done redundantly to skip subentities
(cloaking_device_active && randf() > 0.10))
{
// Don't draw.
return;
}
NS_DURING
if (!translucent)
// Draw self.
[super drawEntity:immediate :translucent];
// Draw subentities.
if (!immediate) // TODO: is this relevant any longer?
{
for (subEntityEnum = [sub_entities objectEnumerator]; (subEntity = [subEntityEnum nextObject]); )
{
GLfloat mat_ambient[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat mat_no[] = { 0.0, 0.0, 0.0, 1.0 };
GLfloat amb_diff0[] = { 0.5, 0.5, 0.5, 1.0 };
if (EXPECT_NOT(basefile == nil))
{
OOLog(@"render.shipEntity.expectedBaseFile", @"Error: no basefile for entity %@", self);
}
// Set up state
glShadeModel(isSmoothShaded ? GL_SMOOTH : GL_FLAT);
glDisableClientState(GL_COLOR_ARRAY);
glDisableClientState(GL_INDEX_ARRAY);
glDisableClientState(GL_EDGE_FLAG_ARRAY);
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glVertexPointer( 3, GL_FLOAT, 0, entityData.vertex_array);
glNormalPointer( GL_FLOAT, 0, entityData.normal_array);
glTexCoordPointer( 2, GL_FLOAT, 0, entityData.texture_uv_array);
if (immediate)
{
/* Gap removal (draw flat polys).
It is my belief that this has absolutely no effect whatsoever on gaps,
as it's using the same geometry as the "real" rendering, but does stop
alpha textures from semi-working. This is probably good, since we
don't depth sort, but could be replaced with disabling blending.
TODO: try the blending thing as above.
-- Ahruman
*/
glDisable(GL_TEXTURE_2D);
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, amb_diff0);
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
glColor4f( 0.25, 0.25, 0.25, 1.0); // gray
glDepthMask(GL_FALSE); // don't write to depth buffer
glDrawArrays(GL_TRIANGLES, 0, entityData.n_triangles); // draw in gray to mask the edges
glDepthMask(GL_TRUE);
// Now draw textured polygons.
glEnable(GL_TEXTURE_2D);
glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, mat_ambient);
glMaterialfv( GL_FRONT_AND_BACK, GL_EMISSION, mat_no); // TODO: replace with using default OOMaterial if no custom material is defined.
for (i = 1; i <= n_textures; i++)
{
textureKey = [TextureStore getNameOfTextureWithGLuint: texture_name[i]];
material = [materials objectForKey:textureKey];
if (material == nil)
{
// TODO: use a default material instead
[OOMaterial applyNone];
glBindTexture(GL_TEXTURE_2D, texture_name[i]);
}
else
{
[material apply];
}
glDrawArrays( GL_TRIANGLES, triangle_range[i].location, triangle_range[i].length);
}
[OOMaterial applyNone];
}
else
{
// Not immediate.
if (displayListName != 0)
{
// TODO: Isn't this equivalent to "if immedate || displayListName != 0" above, along with passing displayListName != 0 as the super call's immediate parameter? -- Ahruman
[self drawEntity:YES :translucent];
}
else
{
// Set up display list.
if (!materialsReady) [self initializeTextures];
#if GL_APPLE_vertex_array_object
if (usingVAR) glBindVertexArrayAPPLE(gVertexArrayRangeObjects[0]);
#endif
/* Apply all materials to ensure textures are loaded.
This is needed because you can't create textures in a
display list.
*/
[self exerciseMaterials];
// Do the display list.
[self generateDisplayList];
}
}
if (!isSmoothShaded) glShadeModel(GL_SMOOTH);
[subEntity setOwner:self]; // refresh ownership
[subEntity drawSubEntity:immediate :translucent];
}
else
{
// Translucent.
if ((status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
[octree drawOctree];
if ((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE))
[octree drawOctreeCollisions];
if ((isSubentity)&&[self owner])
{
if (([self owner]->status == STATUS_COCKPIT_DISPLAY)&&((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE)))
[octree drawOctree];
if ((debug | debug_flag) & (DEBUG_COLLISIONS | DEBUG_OCTREE))
[octree drawOctreeCollisions];
}
}
if (!immediate)
{
// Draw subentities.
for (subEntityEnum = [sub_entities objectEnumerator]; (subEntity = [subEntityEnum nextObject]); )
{
[subEntity setOwner:self]; // refresh ownership
[subEntity drawSubEntity:immediate :translucent];
}
}
CheckOpenGLErrors([NSString stringWithFormat:@"%s after drawing %@ (immediate: %s, translucent: %s)", __PRETTY_FUNCTION__, self, immediate ? "YES" : "NO", translucent ? "YES" : "NO"]);
NS_HANDLER
OOLog(@"exception.shipEntity.draw", @"***** %s encountered exception: %@ : %@ *****", __PRETTY_FUNCTION__, [localException name], [localException reason]);
OOLog(@"exception.shipEntity.draw", @"***** Removing entity %@ from UNIVERSE *****", self);
[UNIVERSE removeEntity:self];
if ([[localException name] hasPrefix:@"Oolite"]) [UNIVERSE handleOoliteException:localException]; // handle these ourself
else [localException raise]; // pass these on
NS_ENDHANDLER
}
}
@ -2723,6 +2449,7 @@ ShipEntity* doOctreesCollide(ShipEntity* prime, ShipEntity* other)
}
}
static GLfloat cargo_color[4] = { 0.9, 0.9, 0.9, 1.0}; // gray
static GLfloat hostile_color[4] = { 1.0, 0.25, 0.0, 1.0}; // red/orange
static GLfloat neutral_color[4] = { 1.0, 1.0, 0.0, 1.0}; // yellow
@ -3543,6 +3270,41 @@ static GLfloat mascem_color2[4] = { 0.4, 0.1, 0.4, 1.0}; // purple
}
- (void) rescaleBy:(GLfloat) factor
{
// rescale mesh (and collision detection stuff)
[self setMesh:[[self mesh] meshRescaledBy:factor]];
// rescale positions of subentities
unsigned i, n_subs = [sub_entities count];
for (i = 0; i < n_subs; i++)
{
Entity* se = (Entity*)[sub_entities objectAtIndex:i];
se->position.x *= factor;
se->position.y *= factor;
se->position.z *= factor;
// rescale ship subentities
if (se->isShip)
[(ShipEntity*)se rescaleBy: factor];
// rescale particle subentities
if (se->isParticle)
{
ParticleEntity* pe = (ParticleEntity*)se;
NSSize sz = [pe size];
sz.width *= factor;
sz.height *= factor;
[pe setSize: sz];
}
}
// rescale mass
//
mass *= factor * factor * factor;
}
- (void) becomeExplosion
{
OOCargoQuantity cargo_to_go;
@ -7026,45 +6788,10 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
- (BoundingBox) findBoundingBoxRelativeTo:(Entity *)other InVectors:(Vector) _i :(Vector) _j :(Vector) _k
{
Vector opv = (other)? other->position : position;
Vector opv = other ? other->position : position;
return [self findBoundingBoxRelativeToPosition:opv InVectors:_i :_j :_k];
}
- (BoundingBox) findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k
{
Vector pv, rv;
Vector rpos = position;
rpos.x -= opv.x; rpos.y -= opv.y; rpos.z -= opv.z; // model origin relative to opv
rv.x = dot_product(_i,rpos);
rv.y = dot_product(_j,rpos);
rv.z = dot_product(_k,rpos); // model origin rel to opv in ijk
BoundingBox result;
if (n_vertices < 1)
bounding_box_reset_to_vector(&result,rv);
else
{
pv.x = rpos.x + v_right.x * vertices[0].x + v_up.x * vertices[0].y + v_forward.x * vertices[0].z;
pv.y = rpos.y + v_right.y * vertices[0].x + v_up.y * vertices[0].y + v_forward.y * vertices[0].z;
pv.z = rpos.z + v_right.z * vertices[0].x + v_up.z * vertices[0].y + v_forward.z * vertices[0].z; // vertices[0] position rel to opv
rv.x = dot_product(_i,pv);
rv.y = dot_product(_j,pv);
rv.z = dot_product(_k,pv); // vertices[0] position rel to opv in ijk
bounding_box_reset_to_vector(&result,rv);
}
int i;
for (i = 1; i < n_vertices; i++)
{
pv.x = rpos.x + v_right.x * vertices[i].x + v_up.x * vertices[i].y + v_forward.x * vertices[i].z;
pv.y = rpos.y + v_right.y * vertices[i].x + v_up.y * vertices[i].y + v_forward.y * vertices[i].z;
pv.z = rpos.z + v_right.z * vertices[i].x + v_up.z * vertices[i].y + v_forward.z * vertices[i].z;
rv.x = dot_product(_i,pv);
rv.y = dot_product(_j,pv);
rv.z = dot_product(_k,pv);
bounding_box_add_vector(&result,rv);
}
return result;
}
- (void) spawn:(NSString *)roles_number
{
@ -7338,90 +7065,26 @@ inline BOOL pairOK(NSString* my_role, NSString* their_role)
OOLog(@"dumpState.shipEntity.glsl", @"entity_personality_int: %i", entity_personality);
}
@end
static NSString * const kOOCacheOctrees = @"octrees";
@implementation OOCacheManager (Octree)
+ (Octree *)octreeForModel:(NSString *)inKey
- (Entity *)entityForShaderProperties
{
NSDictionary *dict = nil;
Octree *result = nil;
dict = [[self sharedCache] objectForKey:inKey inCache:kOOCacheOctrees];
if (dict != nil)
{
result = [[Octree alloc] initWithDictionary:dict];
[result autorelease];
}
return result;
}
+ (void)setOctree:(Octree *)inOctree forModel:(NSString *)inKey
{
[[self sharedCache] setObject:[inOctree dict] forKey:inKey inCache:kOOCacheOctrees];
if (!isSubentity) return self;
else return [self owner];
}
@end
#if OLD_SHADERS
// This could be more efficient.
static void ApplyConstantUniforms(NSDictionary *uniforms, GLhandleARB shaderProgram)
NSDictionary *DefaultShipShaderMacros(void)
{
// Shipdata-defined uniforms.
NSEnumerator *uniformEnum = nil;
NSString *name = nil;
id definition = nil;
id value = nil;
NSString *type = nil;
GLint variableLocation;
GLfloat floatValue;
GLint intValue;
BOOL gotValue;
static NSDictionary *macros = nil;
NSDictionary *materialDefaults = nil;
for (uniformEnum = [uniforms keyEnumerator]; (name = [uniformEnum nextObject]); )
if (macros == nil)
{
variableLocation = glGetUniformLocationARB(shaderProgram, [name UTF8String]);
if (variableLocation == -1) continue;
definition = [uniforms objectForKey:name];
if ([definition isKindOfClass:[NSDictionary class]])
{
value = [definition objectForKey:@"value"];
type = [definition objectForKey:@"type"];
}
else
{
value = definition;
type = @"float";
}
if ([type isEqualToString:@"float"])
{
gotValue = YES;
if ([value respondsToSelector:@selector(floatValue)]) floatValue = [value floatValue];
else if ([value respondsToSelector:@selector(doubleValue)]) floatValue = [value doubleValue];
else if ([value respondsToSelector:@selector(intValue)]) floatValue = [value intValue];
else gotValue = NO;
if (gotValue)
{
glUniform1fARB(variableLocation, floatValue);
}
}
else if ([type isEqualToString:@"int"])
{
if ([value respondsToSelector:@selector(intValue)])
{
intValue = [value intValue];
glUniform1iARB(variableLocation, intValue);
}
}
materialDefaults = [ResourceManager dictionaryFromFilesNamed:@"material-defaults.plist" inFolder:@"Config" andMerge:YES];
macros = [[materialDefaults dictionaryForKey:@"ship-prefix-macros" defaultValue:[NSDictionary dictionary]] retain];
}
return macros;
}
#endif

View File

@ -700,7 +700,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
// ** Set up a the docking port
// Look for subentity specifying position
NSArray *subs = [dict arrayForKey:@"subentities" defaultValue:nil];
NSArray *subs = [dict arrayForKey:@"subentities"];
NSArray *dockSubEntity = nil;
for (i = 0; i < [subs count]; i++)
@ -729,7 +729,7 @@ static NSDictionary* instructions(int station_id, Vector coords, float speed, fl
}
// port_dimensions can be set for rock-hermits and other specials
if (!ScanVectorFromString([dict stringForKey:@"port_dimensions" defaultValue:nil], &port_dimensions))
if (!ScanVectorFromString([dict stringForKey:@"port_dimensions"], &port_dimensions))
{
port_dimensions = make_vector( 69, 69, 250); // base port size (square)
}

View File

@ -66,7 +66,6 @@ SOFTWARE.
// Specular exponent
uint8_t shininess; // Default: 0.0
BOOL smooth; // Default: YES
}
/* Initialize with default values (historical Olite defaults, not GL defaults):
@ -75,7 +74,6 @@ SOFTWARE.
ambient { 1.0, 1.0, 1.0, 1.0 }
emission { 0.0, 0.0, 0.0, 1.0 }
shininess 0
smooth YES
*/
- (id)initWithName:(NSString *)name;
@ -85,8 +83,6 @@ SOFTWARE.
ambient colour description
emission colour description
shininess integer
smooth boolean (probably not useful to expose to users, since
normals won't automagically be adjusted)
"Colour description" refers to anything +[OOColor colorWithDescription:]
will accept.
@ -122,7 +118,4 @@ SOFTWARE.
- (uint8_t)shininess;
- (void)setShininess:(uint8_t)value; // Clamped to [0, 128]
- (BOOL)smooth;
- (void)setSmooth:(BOOL)value;
@end

View File

@ -69,7 +69,6 @@ static OOBasicMaterial *sDefaultMaterial = nil;
[self setAmbientRed:1.0f green:1.0f blue:1.0f alpha:1.0f];
specular[3] = 1.0;
emission[3] = 1.0;
smooth = YES;
return self;
}
@ -100,7 +99,6 @@ static OOBasicMaterial *sDefaultMaterial = nil;
colorDesc = [configuration objectForKey:@"specular"];
if (colorDesc != nil) [self setSpecularColor:[OOColor colorWithDescription:colorDesc]];
}
[self setSmooth:[configuration boolForKey:@"smooth" defaultValue:NO]];
return self;
}
@ -128,7 +126,6 @@ static OOBasicMaterial *sDefaultMaterial = nil;
glMaterialfv(FACE, GL_AMBIENT, ambient);
glMaterialfv(FACE, GL_EMISSION, emission);
glMateriali(FACE, GL_SHININESS, shininess);
glShadeModel(smooth ? GL_SMOOTH : GL_FLAT);
return YES;
}
@ -345,16 +342,4 @@ static OOBasicMaterial *sDefaultMaterial = nil;
shininess = MAX(value, 128);
}
- (BOOL)smooth
{
return smooth;
}
- (void)setSmooth:(BOOL)value
{
smooth = value;
}
@end

View File

@ -174,8 +174,11 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type)
if (OK)
{
location = glGetUniformLocationARB([shaderProgram program], [uniformName lossyCString]);
if (location == -1) OK = NO;
OOLog(@"shader.uniform.bind.failed", @"***** Shader error: could not bind uniform \"%@\" to -[%@ %s] (no uniform of that name could be found).", uniformName, [target class], selector);
if (location == -1)
{
OK = NO;
OOLog(@"shader.uniform.bind.failed", @"***** Shader error: could not bind uniform \"%@\" to -[%@ %s] (no uniform of that name could be found).", uniformName, [target class], selector);
}
}
// If we're still OK, it's a bindable method.
@ -343,6 +346,7 @@ OOINLINE BOOL ValidBindingType(OOShaderUniformType type)
else if (0 == strcmp("l", typeCode) || 0 == strcmp("L", typeCode)) type = kOOShaderUniformTypeLong;
else
{
OK = NO;
methodProblem = [NSString stringWithFormat:@"unsupported type \"%s\"", typeCode];
}
}

View File

@ -469,6 +469,7 @@ static BOOL sRectangleTextureAvailable;
if (EXPECT_NOT(sRecentTextures == nil))
{
sRecentTextures = [[OOCache alloc] init];
[sRecentTextures setName:@"recent textures"];
[sRecentTextures setAutoPrune:YES];
[sRecentTextures setPruneThreshold:kRecentTexturesCount];
}

View File

@ -80,7 +80,7 @@ MA 02110-1301, USA.
break;
}
GLfloat iprio = [instinctDictionary floatForKey:key defaultValue:0.0f];
GLfloat iprio = [instinctDictionary floatForKey:key];
if (iprio != 0.0f)
{
instinct = [[OOInstinct alloc] initInstinctOfType:itype ofPriority:iprio forOwner:anOwner withShip:aShip];

View File

@ -79,4 +79,7 @@ MA 02110-1301, USA.
- (BOOL)dirty;
- (void)markClean;
- (NSString *)name;
- (void)setName:(NSString *)name;
@end

View File

@ -140,6 +140,8 @@ static BOOL CacheRemoveOldest(OOCacheImpl *cache);
static id CacheRetrieve(OOCacheImpl *cache, id key);
static unsigned CacheGetCount(OOCacheImpl *cache);
static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache);
static NSString *CacheGetName(OOCacheImpl *cache);
static void CacheSetName(OOCacheImpl *cache, NSString *name);
#if OOCACHE_PERFORM_INTEGRITY_CHECKS
static void CacheCheckIntegrity(OOCacheImpl *cache, NSString *context);
@ -171,7 +173,7 @@ static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache);
- (NSString *)description
{
return [NSString stringWithFormat:@"<%@ %p>{%u elements, prune threshold=%u, dirty=%s}", [self class], self, CacheGetCount(cache), pruneThreshold, dirty ? "yes" : "no"];
return [NSString stringWithFormat:@"<%@ %p>{\"%@\", %u elements, prune threshold=%u, auto-prune=%s dirty=%s}", [self class], self, [self name], CacheGetCount(cache), pruneThreshold, autoPrune ? "yes" : "no", dirty ? "yes" : "no"];
}
@ -301,11 +303,11 @@ static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache);
if (autoPrune) desiredCount = (pruneThreshold * 4) / 5;
else desiredCount = pruneThreshold;
if (pruneThreshold == kOOCacheNoPrune || CacheGetCount(cache) < desiredCount) return;
if (pruneThreshold == kOOCacheNoPrune || CacheGetCount(cache) <= desiredCount) return;
pruneCount = pruneThreshold - desiredCount;
OOLog(kOOLogCachePrune, @"Pruning cache - removing %u entries", pruneCount);
OOLog(kOOLogCachePrune, @"Pruning cache \"%@\" - removing %u entries", CacheGetName(cache), pruneCount);
OOLogIndentIf(kOOLogCachePrune);
while (pruneCount--) CacheRemoveOldest(cache);
@ -325,6 +327,18 @@ static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache);
dirty = NO;
}
- (NSString *)name
{
return CacheGetName(cache);
}
- (void)setName:(NSString *)name
{
CacheSetName(cache, name);
}
@end
@ -367,6 +381,7 @@ struct OOCacheImpl
OOCacheNode *oldest, *youngest;
unsigned count;
NSString *name;
};
@ -421,6 +436,7 @@ static void CacheFree(OOCacheImpl *cache)
if (cache == NULL) return;
CacheNodeFree(cache, cache->root);
[cache->name autorelease];
free(cache);
}
@ -474,7 +490,7 @@ static BOOL CacheRemoveOldest(OOCacheImpl *cache)
// This could be more efficient, but does it need to be?
if (cache == NULL || cache->oldest == NULL) return NO;
OOLog(kOOLogCachePrune, @"Pruning cache: removing %@", cache->oldest->key);
OOLog(kOOLogCachePrune, @"Pruning cache \"%@\": removing %@", cache->name, cache->oldest->key);
return CacheRemove(cache, cache->oldest->key);
}
@ -517,6 +533,19 @@ static NSArray *CacheArrayOfNodesByAge(OOCacheImpl *cache)
}
static NSString *CacheGetName(OOCacheImpl *cache)
{
return cache->name;
}
static void CacheSetName(OOCacheImpl *cache, NSString *name)
{
[cache->name autorelease];
cache->name = [name copy];
}
static unsigned CacheGetCount(OOCacheImpl *cache)
{
return cache->count;
@ -534,7 +563,7 @@ static void CacheCheckIntegrity(OOCacheImpl *cache, NSString *context)
if (kCountUnknown == cache->count) cache->count = trueCount;
else if (cache->count != trueCount)
{
OOLog(kOOLogCacheIntegrityCheck, @"Count is %u, but should be %u.", cache->count, trueCount);
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): count is %u, but should be %u.", context, cache->name, cache->count, trueCount);
cache->count = trueCount;
}
@ -738,7 +767,7 @@ static OOCacheNode *TreeInsert(OOCacheImpl *cache, id key, id value)
else
{
// Key already exists, which we should have caught above
OOLog(@"dataCache.inconsistency", @"%s() internal inconsistency, insertion failed.", __FUNCTION__);
OOLog(@"dataCache.inconsistency", @"%s() internal inconsistency for cache \"%@\", insertion failed.", __FUNCTION__, cache->name);
CacheNodeFree(cache, node);
return NULL;
}
@ -767,13 +796,13 @@ static OOCacheNode *TreeCheckIntegrity(OOCacheImpl *cache, OOCacheNode *node, OO
if (OK && node->key == nil)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): node %@ has nil key; deleting subtree.", context, CacheNodeGetDescription(node));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): node %@ has nil key; deleting subtree.", context, cache->name, CacheNodeGetDescription(node));
OK = NO;
}
if (OK && node->value == nil)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): node %@ has nil value, deleting.", context, CacheNodeGetDescription(node));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): node %@ has nil value, deleting.", context, cache->name, CacheNodeGetDescription(node));
OK = NO;
}
if (OK && node->leftChild != NULL)
@ -781,7 +810,7 @@ static OOCacheNode *TreeCheckIntegrity(OOCacheImpl *cache, OOCacheNode *node, OO
order = [node->key compare:node->leftChild->key];
if (order != NSOrderedDescending)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): node %@'s left child %@ is not correctly ordered. Deleting subtree.", context, CacheNodeGetDescription(node), CacheNodeGetDescription(node->leftChild));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): node %@'s left child %@ is not correctly ordered. Deleting subtree.", context, cache->name, CacheNodeGetDescription(node), CacheNodeGetDescription(node->leftChild));
CacheNodeFree(cache, node->leftChild);
node->leftChild = nil;
cache->count = kCountUnknown;
@ -796,7 +825,7 @@ static OOCacheNode *TreeCheckIntegrity(OOCacheImpl *cache, OOCacheNode *node, OO
order = [node->key compare:node->rightChild->key];
if (order != NSOrderedAscending)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): node %@'s right child %@ is not correctly ordered. Deleting subtree.", context, CacheNodeGetDescription(node), CacheNodeGetDescription(node->rightChild));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): node %@'s right child %@ is not correctly ordered. Deleting subtree.", context, cache->name, CacheNodeGetDescription(node), CacheNodeGetDescription(node->rightChild));
CacheNodeFree(cache, node->rightChild);
node->rightChild = nil;
cache->count = kCountUnknown;
@ -874,7 +903,7 @@ static void AgeListCheckIntegrity(OOCacheImpl *cache, NSString *context)
if (next->younger != node)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): node %@ has invalid older link (should be %@, is %@); repairing.", context, CacheNodeGetDescription(next), CacheNodeGetDescription(node), CacheNodeGetDescription(next->older));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): node %@ has invalid older link (should be %@, is %@); repairing.", context, cache->name, CacheNodeGetDescription(next), CacheNodeGetDescription(node), CacheNodeGetDescription(next->older));
next->older = node;
}
node = next;
@ -883,7 +912,7 @@ static void AgeListCheckIntegrity(OOCacheImpl *cache, NSString *context)
if (seenCount != cache->count)
{
// This is especially bad since this function is called just after verifying that the count field reflects the number of objects in the tree.
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): expected %u nodes, found %u. Cannot repair; clearing cache.", context, cache->count, seenCount);
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): expected %u nodes, found %u. Cannot repair; clearing cache.", context, cache->name, cache->count, seenCount);
cache->count = 0;
CacheNodeFree(cache, cache->root);
cache->root = NULL;
@ -894,7 +923,7 @@ static void AgeListCheckIntegrity(OOCacheImpl *cache, NSString *context)
if (node != cache->oldest)
{
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@): oldest pointer in cache is wrong (should be %@, is %@); repairing.", context, CacheNodeGetDescription(node), CacheNodeGetDescription(cache->oldest));
OOLog(kOOLogCacheIntegrityCheck, @"Integrity check (%@ for \"%@\"): oldest pointer in cache is wrong (should be %@, is %@); repairing.", context, cache->name, CacheNodeGetDescription(node), CacheNodeGetDescription(cache->oldest));
cache->oldest = node;
}
}

View File

@ -143,16 +143,16 @@ static OOCacheManager *sSingleton = nil;
result = [cache objectForKey:inKey];
if (result != nil)
{
OOLog(kOOLogDataCacheRetrieveSuccess, @"Retrieved cache %@ object %@.", inCacheKey, inKey);
OOLog(kOOLogDataCacheRetrieveSuccess, @"Retrieved \"%@\" cache object %@.", inCacheKey, inKey);
}
else
{
OOLog(kOOLogDataCacheRetrieveFailed, @"Failed to retrive %@ cache object %@ -- no such entry.", inCacheKey, inKey);
OOLog(kOOLogDataCacheRetrieveFailed, @"Failed to retrive \"%@\" cache object %@ -- no such entry.", inCacheKey, inKey);
}
}
else
{
OOLog(kOOLogDataCacheRetrieveFailed, @"Failed to retrive %@ cache object %@ -- no such cache.", inCacheKey, inKey);
OOLog(kOOLogDataCacheRetrieveFailed, @"Failed to retrive\"%@\" cache object %@ -- no such cache.", inCacheKey, inKey);
}
return result;
@ -175,15 +175,16 @@ static OOCacheManager *sSingleton = nil;
cache = [[OOCache alloc] init];
if (cache == nil)
{
OOLog(kOOLogDataCacheSetFailed, @"Failed to create cache for key %@.", inCacheKey);
OOLog(kOOLogDataCacheSetFailed, @"Failed to create cache for key \"%@\".", inCacheKey);
return;
}
[cache setName:inCacheKey];
[cache setAutoPrune:AUTO_PRUNE];
[caches setObject:cache forKey:inCacheKey];
}
[cache setObject:inObject forKey:inKey];
OOLog(kOOLogDataCacheSetSuccess, @"Updated entry %@ in cache %@.", inKey, inCacheKey);
OOLog(kOOLogDataCacheSetSuccess, @"Updated entry %@ in cache \"%@\".", inKey, inCacheKey);
}
@ -200,16 +201,16 @@ static OOCacheManager *sSingleton = nil;
if (nil != [cache objectForKey:inKey])
{
[cache removeObjectForKey:inKey];
OOLog(kOOLogDataCacheRemoveSuccess, @"Removed entry keyed %@ from cache %@.", inKey, inCacheKey);
OOLog(kOOLogDataCacheRemoveSuccess, @"Removed entry keyed %@ from cache \"%@\".", inKey, inCacheKey);
}
else
{
OOLog(kOOLogDataCacheRemoveSuccess, @"No need to remove non-existent entry keyed %@ from cache %@.", inKey, inCacheKey);
OOLog(kOOLogDataCacheRemoveSuccess, @"No need to remove non-existent entry keyed %@ from cache \"%@\".", inKey, inCacheKey);
}
}
else
{
OOLog(kOOLogDataCacheRemoveSuccess, @"No need to remove entry keyed %@ from non-existent cache %@.", inKey, inCacheKey);
OOLog(kOOLogDataCacheRemoveSuccess, @"No need to remove entry keyed %@ from non-existent cache \"%@\".", inKey, inCacheKey);
}
}
@ -222,11 +223,11 @@ static OOCacheManager *sSingleton = nil;
if (nil != [caches objectForKey:inCacheKey])
{
[caches removeObjectForKey:inCacheKey];
OOLog(kOOLogDataCacheClearSuccess, @"Cleared cache %@.", inCacheKey);
OOLog(kOOLogDataCacheClearSuccess, @"Cleared cache \"%@\".", inCacheKey);
}
else
{
OOLog(kOOLogDataCacheClearSuccess, @"No need to clear non-existent cache %@.", inCacheKey);
OOLog(kOOLogDataCacheClearSuccess, @"No need to clear non-existent cache \"%@\".", inCacheKey);
}
}
@ -437,6 +438,7 @@ static OOCacheManager *sSingleton = nil;
cache = [[OOCache alloc] initWithPList:value];
if (cache != nil)
{
[cache setName:key];
[caches setObject:cache forKey:key];
[cache release];
}

View File

@ -84,6 +84,35 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue);
- (NSDictionary *)dictionaryAtIndex:(unsigned)index defaultValue:(NSDictionary *)value;
- (NSData *)dataAtIndex:(unsigned)index defaultValue:(NSData *)value;
// Default: 0
- (char)charAtIndex:(unsigned)index;
- (short)shortAtIndex:(unsigned)index;
- (int)intAtIndex:(unsigned)index;
- (long)longAtIndex:(unsigned)index;
- (long long)longLongAtIndex:(unsigned)index;
- (unsigned char)unsignedCharAtIndex:(unsigned)index;
- (unsigned short)unsignedShortAtIndex:(unsigned)index;
- (unsigned int)unsignedIntAtIndex:(unsigned)index;
- (unsigned long)unsignedLongAtIndex:(unsigned)index;
- (unsigned long long)unsignedLongLongAtIndex:(unsigned)index;
// Default: NO
- (BOOL)boolAtIndex:(unsigned)index;
- (BOOL)fuzzyBooleanAtIndex:(unsigned)index; // Reads a float in the range [0, 1], and returns YES with that probability.
// Default: 0.0
- (float)floatAtIndex:(unsigned)index;
- (double)doubleAtIndex:(unsigned)index;
// Default: nil
// - (id)objectAtIndex:(unsigned)index; // Already defined
- (NSString *)stringAtIndex:(unsigned)index;
- (NSArray *)arrayAtIndex:(unsigned)index;
- (NSDictionary *)dictionaryAtIndex:(unsigned)index;
- (NSData *)dataAtIndex:(unsigned)index;
@end
@ -113,6 +142,35 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue);
- (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)value;
- (NSData *)dataForKey:(id)key defaultValue:(NSData *)value;
// Default: 0
- (char)charForKey:(id)key;
- (short)shortForKey:(id)key;
- (int)intForKey:(id)key;
- (long)longForKey:(id)key;
- (long long)longLongForKey:(id)key;
- (unsigned char)unsignedCharForKey:(id)key;
- (unsigned short)unsignedShortForKey:(id)key;
- (unsigned int)unsignedIntForKey:(id)key;
- (unsigned long)unsignedLongForKey:(id)key;
- (unsigned long long)unsignedLongLongForKey:(id)key;
// Default: NO
- (BOOL)boolForKey:(id)key;
- (BOOL)fuzzyBooleanForKey:(id)key; // Reads a float in the range [0, 1], and returns YES with that probability.
// Default: 0.0
- (float)floatForKey:(id)key;
- (double)doubleForKey:(id)key;
// Default: nil
// - (id)objectForKey:(id)key; // Already defined
- (NSString *)stringForKey:(id)key;
- (NSArray *)arrayForKey:(id)key;
- (NSDictionary *)dictionaryForKey:(id)key;
- (NSData *)dataForKey:(id)key;
@end
@ -142,4 +200,33 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue);
- (NSDictionary *)dictionaryForKey:(id)key defaultValue:(NSDictionary *)value;
- (NSData *)dataForKey:(id)key defaultValue:(NSData *)value;
// Default: 0
- (char)charForKey:(id)key;
- (short)shortForKey:(id)key;
- (int)intForKey:(id)key;
- (long)longForKey:(id)key;
- (long long)longLongForKey:(id)key;
- (unsigned char)unsignedCharForKey:(id)key;
- (unsigned short)unsignedShortForKey:(id)key;
- (unsigned int)unsignedIntForKey:(id)key;
- (unsigned long)unsignedLongForKey:(id)key;
- (unsigned long long)unsignedLongLongForKey:(id)key;
// Default: NO
// - (BOOL)boolForKey:(id)key;
- (BOOL)fuzzyBooleanForKey:(id)key; // Reads a float in the range [0, 1], and returns YES with that probability.
// Default: 0.0
// - (float)floatForKey:(id)key;
- (double)doubleForKey:(id)key;
// Default: nil
// - (id)objectForKey:(id)key; // Already defined
// - (NSString *)stringForKey:(id)key;
// - (NSArray *)arrayForKey:(id)key;
// - (NSDictionary *)dictionaryForKey:(id)key;
// - (NSData *)dataForKey:(id)key;
@end

View File

@ -366,6 +366,114 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue)
return result;
}
- (char)charAtIndex:(unsigned)index
{
return [self charAtIndex:index defaultValue:0];
}
- (short)shortAtIndex:(unsigned)index
{
return [self shortAtIndex:index defaultValue:0];
}
- (int)intAtIndex:(unsigned)index
{
return [self intAtIndex:index defaultValue:0];
}
- (long)longAtIndex:(unsigned)index
{
return [self longAtIndex:index defaultValue:0];
}
- (long long)longLongAtIndex:(unsigned)index
{
return [self longLongAtIndex:index defaultValue:0];
}
- (unsigned char)unsignedCharAtIndex:(unsigned)index
{
return [self unsignedCharAtIndex:index defaultValue:0];
}
- (unsigned short)unsignedShortAtIndex:(unsigned)index
{
return [self unsignedShortAtIndex:index defaultValue:0];
}
- (unsigned int)unsignedIntAtIndex:(unsigned)index
{
return [self unsignedIntAtIndex:index defaultValue:0];
}
- (unsigned long)unsignedLongAtIndex:(unsigned)index
{
return [self unsignedLongAtIndex:index defaultValue:0];
}
- (unsigned long long)unsignedLongLongAtIndex:(unsigned)index
{
return [self unsignedLongLongAtIndex:index defaultValue:0];
}
- (BOOL)boolAtIndex:(unsigned)index
{
return [self boolAtIndex:index defaultValue:NO];
}
- (BOOL)fuzzyBooleanAtIndex:(unsigned)index
{
return [self fuzzyBooleanAtIndex:index defaultValue:0.0f];
}
- (float)floatAtIndex:(unsigned)index
{
return [self floatAtIndex:index defaultValue:0.0f];
}
- (double)doubleAtIndex:(unsigned)index
{
return [self doubleAtIndex:index defaultValue:0.0];
}
- (NSString *)stringAtIndex:(unsigned)index
{
return [self stringAtIndex:index defaultValue:nil];
}
- (NSArray *)arrayAtIndex:(unsigned)index
{
return [self arrayAtIndex:index defaultValue:nil];
}
- (NSDictionary *)dictionaryAtIndex:(unsigned)index
{
return [self dictionaryAtIndex:index defaultValue:nil];
}
- (NSData *)dataAtIndex:(unsigned)index
{
return [self dataAtIndex:index defaultValue:nil];
}
@end
@ -653,6 +761,114 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue)
return result;
}
- (char)charForKey:(id)key
{
return [self charForKey:key defaultValue:0];
}
- (short)shortForKey:(id)key
{
return [self shortForKey:key defaultValue:0];
}
- (int)intForKey:(id)key
{
return [self intForKey:key defaultValue:0];
}
- (long)longForKey:(id)key
{
return [self longForKey:key defaultValue:0];
}
- (long long)longLongForKey:(id)key
{
return [self longLongForKey:key defaultValue:0];
}
- (unsigned char)unsignedCharForKey:(id)key
{
return [self unsignedCharForKey:key defaultValue:0];
}
- (unsigned short)unsignedShortForKey:(id)key
{
return [self unsignedShortForKey:key defaultValue:0];
}
- (unsigned int)unsignedIntForKey:(id)key
{
return [self unsignedIntForKey:key defaultValue:0];
}
- (unsigned long)unsignedLongForKey:(id)key
{
return [self unsignedLongForKey:key defaultValue:0];
}
- (unsigned long long)unsignedLongLongForKey:(id)key
{
return [self unsignedLongLongForKey:key defaultValue:0];
}
- (BOOL)boolForKey:(id)key
{
return [self boolForKey:key defaultValue:NO];
}
- (BOOL)fuzzyBooleanForKey:(id)key
{
return [self fuzzyBooleanForKey:key defaultValue:0.0f];
}
- (float)floatForKey:(id)key
{
return [self floatForKey:key defaultValue:0.0f];
}
- (double)doubleForKey:(id)key
{
return [self doubleForKey:key defaultValue:0.0];
}
- (NSString *)stringForKey:(id)key
{
return [self stringForKey:key defaultValue:nil];
}
- (NSArray *)arrayForKey:(id)key
{
return [self arrayForKey:key defaultValue:nil];
}
- (NSDictionary *)dictionaryForKey:(id)key
{
return [self dictionaryForKey:key defaultValue:nil];
}
- (NSData *)dataForKey:(id)key
{
return [self dataForKey:key defaultValue:nil];
}
@end
@ -940,4 +1156,76 @@ BOOL EvaluateAsBoolean(id object, BOOL defaultValue)
return result;
}
- (char)charForKey:(id)key
{
return [self charForKey:key defaultValue:0];
}
- (short)shortForKey:(id)key
{
return [self shortForKey:key defaultValue:0];
}
- (int)intForKey:(id)key
{
return [self intForKey:key defaultValue:0];
}
- (long)longForKey:(id)key
{
return [self longForKey:key defaultValue:0];
}
- (long long)longLongForKey:(id)key
{
return [self longLongForKey:key defaultValue:0];
}
- (unsigned char)unsignedCharForKey:(id)key
{
return [self unsignedCharForKey:key defaultValue:0];
}
- (unsigned short)unsignedShortForKey:(id)key
{
return [self unsignedShortForKey:key defaultValue:0];
}
- (unsigned int)unsignedIntForKey:(id)key
{
return [self unsignedIntForKey:key defaultValue:0];
}
- (unsigned long)unsignedLongForKey:(id)key
{
return [self unsignedLongForKey:key defaultValue:0];
}
- (unsigned long long)unsignedLongLongForKey:(id)key
{
return [self unsignedLongLongForKey:key defaultValue:0];
}
- (BOOL)fuzzyBooleanForKey:(id)key
{
return [self fuzzyBooleanForKey:key defaultValue:0.0f];
}
- (double)doubleForKey:(id)key
{
return [self doubleForKey:key defaultValue:0.0];
}
@end

View File

@ -126,7 +126,7 @@ MA 02110-1301, USA.
if ([description objectForKey:@"hue"] != nil)
{
// Treat as HSB(A) dictionary
float h = [description floatForKey:@"hue" defaultValue:0.0f];
float h = [description floatForKey:@"hue"];
float s = [description floatForKey:@"saturation" defaultValue:1.0f];
float b = [description floatForKey:@"brightness" defaultValue:-1.0f];
if (b < 0.0f) b = [description floatForKey:@"value" defaultValue:1.0f];
@ -138,9 +138,9 @@ MA 02110-1301, USA.
else
{
// Treat as RGB(A) dictionary
float r = [description floatForKey:@"red" defaultValue:0.0f];
float g = [description floatForKey:@"green" defaultValue:0.0f];
float b = [description floatForKey:@"blue" defaultValue:0.0f];
float r = [description floatForKey:@"red"];
float g = [description floatForKey:@"green"];
float b = [description floatForKey:@"blue"];
float a = [description floatForKey:@"alpha" defaultValue:-1.0f];
if (a < 0.0f) a = [description floatForKey:@"opacity" defaultValue:1.0f];

View File

@ -50,6 +50,7 @@ SOFTWARE.
#import "OOCocoa.h"
#import "OOOpenGL.h"
#import "OOMaths.h"
#import "OOWeakReference.h"
@class Geometry;
@ -68,9 +69,13 @@ SOFTWARE.
- (Geometry *)geometry;
- (GLfloat)volume;
- (BoundingBox)boundingBox;
// This needs a better name.
- (BoundingBox)findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k;
// Passed to all materials.
- (void)setBindingTarget:(id<OOWeakReferenceSupport>)target;
- (void)dumpSelfState;
@end

View File

@ -103,12 +103,24 @@ SOFTWARE.
}
- (BoundingBox)boundingBox
{
return kZeroBoundingBox;
}
- (BoundingBox)findBoundingBoxRelativeToPosition:(Vector)opv InVectors:(Vector) _i :(Vector) _j :(Vector) _k
{
return kZeroBoundingBox;
}
- (void)setBindingTarget:(id<OOWeakReferenceSupport>)target
{
}
- (void)dumpSelfState
{

View File

@ -2,7 +2,17 @@
OOMesh.h
Standard OODrawable for static meshes from DAT files.
Standard OODrawable for static meshes from DAT files. OOMeshes are immutable
(and can therefore be shared). Avoid the temptation to add externally-visible
mutator methods as it will break such sharing. (Sharing will be implemented
when ship types are turned into objects instead of dictionaries; this is
currently slated for post-1.70. -- Ahruman)
Hmm. On further consideration, sharing will be problematic because of material
bindings. Two possible solutions: separate mesh data into shared object with
each mesh instance having its own set of materials but shared data, or
retarget bindings each frame. -- Ahruman
Oolite
Copyright (C) 2004-2007 Giles C Williams and contributors
@ -28,7 +38,7 @@ MA 02110-1301, USA.
#import "OOOpenGL.h"
#import "OOWeakReference.h"
@class OOMaterial;
@class OOMaterial, Octree;
enum
@ -54,22 +64,19 @@ typedef struct
GLint vertex[MAX_VERTICES_PER_FACE];
Str255 textureFileStr255;
GLuint texName;
NSString *texFileName;
GLfloat s[MAX_VERTICES_PER_FACE];
GLfloat t[MAX_VERTICES_PER_FACE];
} Face;
} OOMeshFace;
typedef struct
{
GLint index_array[3 * MAX_FACES_PER_ENTITY]; // triangles
GLfloat texture_uv_array[ 3 * MAX_FACES_PER_ENTITY * 2];
GLfloat texture_uv_array[3 * MAX_FACES_PER_ENTITY * 2];
Vector vertex_array[3 * MAX_FACES_PER_ENTITY];
Vector normal_array[3 * MAX_FACES_PER_ENTITY];
GLuint texName;
int n_triangles;
} EntityData; // per texture
@ -83,35 +90,42 @@ typedef struct
} VertexArrayRangeType;
@interface OOMesh: OODrawable
typedef uint16_t OOMeshVertexCount, OOMeshFaceCount;
typedef uint8_t OOMeshMaterialCount;
@interface OOMesh: OODrawable <NSCopying>
{
uint8_t isSmoothShaded: 1,
#if GL_APPLE_vertex_array_object
usingVAR: 1,
#endif
brokenInRender: 1,
materialsReady: 1;
brokenInRender: 1;
uint8_t textureCount;
uint16_t vertexCount, faceCount;
OOMeshMaterialCount materialCount;
OOMeshVertexCount vertexCount;
OOMeshFaceCount faceCount;
NSString *basefile;
NSString *baseFile;
NSSet *textureNameSet;
Vector vertices[MAX_VERTICES_PER_ENTITY];
Vector vertex_normal[MAX_VERTICES_PER_ENTITY];
Face faces[MAX_FACES_PER_ENTITY];
Vector normals[MAX_VERTICES_PER_ENTITY];
OOMeshFace faces[MAX_FACES_PER_ENTITY];
GLuint displayList;
EntityData entityData;
NSRange triangle_range[MAX_TEXTURES_PER_ENTITY];
Str255 texture_file[MAX_TEXTURES_PER_ENTITY];
GLuint texture_name[MAX_TEXTURES_PER_ENTITY];
NSString *texFileNames[MAX_TEXTURES_PER_ENTITY];
OOMaterial *materials[MAX_TEXTURES_PER_ENTITY];
GLfloat collisionRadius;
GLfloat maxDrawDistance;
BoundingBox boundingBox;
GLfloat volume;
Octree *octree;
// COMMON OGL STUFF
#if GL_APPLE_vertex_array_object
GLuint gVertexArrayRangeObjects[NUM_VERTEX_ARRAY_RANGES]; // OpenGL's VAR object references
@ -119,17 +133,24 @@ typedef struct
#endif
}
// + (id)meshWithName:(NSString *)name materialDictionary:(NSDictionary *)materialDict shadersDictionary:(NSDictionary *)shadersDict smooth:(BOOL)smooth shaderMacros:(NSDictionary *)macros shaderBindingTarget:(id<OOWeakReferenceSupport>)object;
+ (id)meshWithName:(NSString *)name
materialDictionary:(NSDictionary *)materialDict
shadersDictionary:(NSDictionary *)shadersDict
smooth:(BOOL)smooth
shaderMacros:(NSDictionary *)macros
shaderBindingTarget:(id<OOWeakReferenceSupport>)object;
- (void) setModelName:(NSString *)modelName;
- (NSString *) modelName;
- (size_t)vertexCount;
- (size_t)faceCount;
- (BOOL)isSmoothShaded;
- (Octree *)octree;
- (Geometry *)geometry;
- (BoundingBox)findSubentityBoundingBoxWithPosition:(Vector)position rotMatrix:(gl_matrix)rotMatrix;
- (OOMesh *)meshRescaledBy:(GLfloat)scaleFactor;
- (OOMesh *)meshRescaledByX:(GLfloat)scaleX y:(GLfloat)scaleY z:(GLfloat)scaleZ;
@end
@ -170,3 +191,11 @@ void LogOpenGLState();
// check for OpenGL errors, reporting them if where is not nil
//
BOOL CheckOpenGLErrors(NSString* where);
@interface OOCacheManager (Octree)
+ (Octree *)octreeForModel:(NSString *)inKey;
+ (void)setOctree:(Octree *)inOctree forModel:(NSString *)inKey;
@end

File diff suppressed because it is too large Load Diff

View File

@ -51,6 +51,14 @@ SOFTWARE.
#import <stdlib.h>
/* If nonzero, disable shaders for OpenGL versions less than 1.5. It is my
contention that this isn't needed since we test for extensions. Enabling
this check disables shaders on Intel GMA 950 hardware under Mac OS
10.4.9; they seem to work fine otherwise. -- Ahruman
*/
#define SHADER_CHECK_FOR_VERSION 0
static NSString * const kOOLogOpenGLShaderSupport = @"rendering.opengl.shader.support";
@ -252,11 +260,13 @@ static unsigned IntegerFromString(const GLubyte **ioString)
{
shadersAvailable = NO;
#if SHADER_CHECK_FOR_VERSION
if (major <= 1 && minor < 5)
{
OOLog(kOOLogOpenGLShaderSupport, @"Shaders will not be used (OpenGL version < 1.5).");
return;
}
#endif
const NSString *requiredExtension[] =
{

View File

@ -30,7 +30,7 @@ MA 02110-1301, USA.
#else
typedef struct
typedef struct Quaternion
{
GLfloat w;
GLfloat x;

View File

@ -30,7 +30,7 @@ MA 02110-1301, USA.
#else
typedef struct
typedef struct Vector
{
GLfloat x;
GLfloat y;

View File

@ -41,6 +41,7 @@ MA 02110-1301, USA.
#import "OOOpenGLExtensionManager.h"
#import "OOCPUInfo.h"
#import "OOMaterial.h"
#import "OOTexture.h"
#import "Octree.h"
#import "CollisionRegion.h"
@ -338,6 +339,7 @@ static BOOL MaintainLinkedLists(Universe* uni);
[ResourceManager setUseAddOns:!strict];
[ResourceManager loadScripts];
[TextureStore reloadTextures];
[OOTexture clearCache];
#ifndef GNUSTEP
//// speech stuff
@ -3402,7 +3404,7 @@ GLfloat* custom_matrix;
int furthest = draw_count - 1;
int nearest = 0;
BOOL bpHide = [self breakPatternHide];
// DRAW ALL THE OPAQUE ENTITIES
@ -3412,13 +3414,13 @@ GLfloat* custom_matrix;
drawthing = my_entities[i];
d_status = drawthing->status;
if (bpHide && !drawthing->isImmuneToBreakPatternHide) continue;
GLfloat flat_ambdiff[4] = {1.0, 1.0, 1.0, 1.0}; // for alpha
GLfloat mat_no[4] = {0.0, 0.0, 0.0, 1.0}; // nothing
if (((d_status == STATUS_COCKPIT_DISPLAY)&&(inGUIMode)) || ((d_status != STATUS_COCKPIT_DISPLAY)&&(!inGUIMode)))
{
OOLog(@"render.entity.opaque", @"Rendering %@", drawthing);
// reset material properties
glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE, flat_ambdiff);
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat_no);
@ -3497,10 +3499,10 @@ GLfloat* custom_matrix;
drawthing = my_entities[i];
d_status = drawthing->status;
if (bpHide && !drawthing->isImmuneToBreakPatternHide) continue;
if (((d_status == STATUS_COCKPIT_DISPLAY)&&(inGUIMode)) || ((d_status != STATUS_COCKPIT_DISPLAY)&&(!inGUIMode)))
{
OOLog(@"render.entity.translucent", @"Rendering %@", drawthing);
// experimental - atmospheric fog
BOOL fogging = (air_resist_factor > 0.01);
@ -3550,7 +3552,6 @@ GLfloat* custom_matrix;
glDepthMask(GL_TRUE); // restore write to depth buffer
}
if (OOLogWillDisplayMessagesInClass(@"$shaderDebugOn")) OOLogSetDisplayMessagesInClass(@"$shaderDebugOn", NO);
glPopMatrix(); //restore saved flat viewpoint