From 2d592efb4018a7177251e3e915ce044a405c0d7e Mon Sep 17 00:00:00 2001 From: AnotherCommander Date: Fri, 5 Feb 2016 11:44:25 +0100 Subject: [PATCH] Proposed fix for issue #176 (Cache problems with rescaled models). --- Resources/Config/logcontrol.plist | 1 + src/Core/Entities/OOEntityWithDrawable.h | 1 + src/Core/Entities/OOExhaustPlumeEntity.m | 7 +++++ src/Core/Entities/OOFlasherEntity.m | 7 +++++ src/Core/Entities/OOVisualEffectEntity.m | 7 +++++ src/Core/Entities/ShipEntity.m | 15 ++++++++-- src/Core/OOCacheManager.m | 2 +- src/Core/OOMesh.h | 5 +++- src/Core/OOMesh.m | 38 +++++++++++++++++++----- src/Core/Universe.m | 2 +- 10 files changed, 71 insertions(+), 14 deletions(-) diff --git a/Resources/Config/logcontrol.plist b/Resources/Config/logcontrol.plist index 1c1d690a..0e189ffe 100644 --- a/Resources/Config/logcontrol.plist +++ b/Resources/Config/logcontrol.plist @@ -184,6 +184,7 @@ mesh.load.cached = inherit; mesh.load.uncached = inherit; mesh.load.octree.size = no; + mesh.load.octreeCached = inherit; mesh.load.error = $error; mesh.load.error.badCacheData = inherit; diff --git a/src/Core/Entities/OOEntityWithDrawable.h b/src/Core/Entities/OOEntityWithDrawable.h index 7ea8499b..370cbf7d 100644 --- a/src/Core/Entities/OOEntityWithDrawable.h +++ b/src/Core/Entities/OOEntityWithDrawable.h @@ -32,6 +32,7 @@ MA 02110-1301, USA. @protocol OOSubEntity - (void) rescaleBy:(GLfloat)factor; +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache; // Separate drawing path for subentities of ships. - (void) drawSubEntityImmediate:(bool)immediate translucent:(bool)translucent; diff --git a/src/Core/Entities/OOExhaustPlumeEntity.m b/src/Core/Entities/OOExhaustPlumeEntity.m index 0c24aeac..dade43c5 100644 --- a/src/Core/Entities/OOExhaustPlumeEntity.m +++ b/src/Core/Entities/OOExhaustPlumeEntity.m @@ -622,6 +622,13 @@ static GLfloat pA[6] = { 0.01, 0.0, 2.0, 4.0, 6.0, 10.0 }; // phase adjustments } +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache +{ + /* Do nothing; this is only needed because of OOEntityWithDrawable + implementation requirements */ +} + + - (OOTexture *) texture { return [OOExhaustPlumeEntity plumeTexture]; diff --git a/src/Core/Entities/OOFlasherEntity.m b/src/Core/Entities/OOFlasherEntity.m index 9ad0d90f..fb28756f 100644 --- a/src/Core/Entities/OOFlasherEntity.m +++ b/src/Core/Entities/OOFlasherEntity.m @@ -234,6 +234,13 @@ MA 02110-1301, USA. [self setDiameter:[self diameter] * factor]; } + +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache +{ + /* Do nothing; this is only needed because of OOEntityWithDrawable + implementation requirements */ +} + @end diff --git a/src/Core/Entities/OOVisualEffectEntity.m b/src/Core/Entities/OOVisualEffectEntity.m index 4932f899..6d15a75b 100644 --- a/src/Core/Entities/OOVisualEffectEntity.m +++ b/src/Core/Entities/OOVisualEffectEntity.m @@ -424,6 +424,13 @@ MA 02110-1301, USA. } +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache +{ + /* Do nothing; this is only needed because of OOEntityWithDrawable + implementation requirements */ +} + + - (GLfloat) scaleMax { GLfloat scale = 1.0; diff --git a/src/Core/Entities/ShipEntity.m b/src/Core/Entities/ShipEntity.m index 4c947758..d557e617 100644 --- a/src/Core/Entities/ShipEntity.m +++ b/src/Core/Entities/ShipEntity.m @@ -138,6 +138,7 @@ static GLfloat calcFuelChargeRate (GLfloat myMass) #endif - (void) rescaleBy:(GLfloat)factor; +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache; - (BOOL) setUpOneSubentity:(NSDictionary *) subentDict; - (BOOL) setUpOneFlasher:(NSDictionary *) subentDict; @@ -396,7 +397,8 @@ static ShipEntity *doOctreesCollide(ShipEntity *prime, ShipEntity *other); smooth:[shipDict oo_boolForKey:@"smooth" defaultValue:NO] shaderMacros:OODefaultShipShaderMacros() shaderBindingTarget:self - scaleFactor:_scaleFactor]; + scaleFactor:_scaleFactor + cacheWriteable:YES]; if (mesh == nil) return NO; [self setMesh:mesh]; @@ -8994,6 +8996,12 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context) - (void) rescaleBy:(GLfloat)factor +{ + [self rescaleBy:factor writeToCache:YES]; +} + + +- (void) rescaleBy:(GLfloat)factor writeToCache:(BOOL)writeToCache { _scaleFactor *= factor; OOMesh *mesh = nil; @@ -9009,7 +9017,8 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context) smooth:[shipDict oo_boolForKey:@"smooth" defaultValue:NO] shaderMacros:OODefaultShipShaderMacros() shaderBindingTarget:self - scaleFactor:factor]; + scaleFactor:factor + cacheWriteable:writeToCache]; if (mesh == nil) return; [self setMesh:mesh]; @@ -9020,7 +9029,7 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context) foreach (se, [self subEntities]) { [se setPosition:HPvector_multiply_scalar([se position], factor)]; - [se rescaleBy:factor]; + [se rescaleBy:factor writeToCache:writeToCache]; } // rescale mass diff --git a/src/Core/OOCacheManager.m b/src/Core/OOCacheManager.m index 91410360..1bab31d2 100644 --- a/src/Core/OOCacheManager.m +++ b/src/Core/OOCacheManager.m @@ -73,7 +73,7 @@ static NSString * const kCacheKeyCaches = @"caches"; enum { kEndianTagValue = 0x0123456789ABCDEFULL, - kFormatVersionValue = 218 + kFormatVersionValue = 219 }; diff --git a/src/Core/OOMesh.h b/src/Core/OOMesh.h index 2a282795..4c4e254d 100644 --- a/src/Core/OOMesh.h +++ b/src/Core/OOMesh.h @@ -98,6 +98,8 @@ typedef struct OOMeshFaceCount faceCount; NSString *baseFile; + NSString *baseFileOctreeCacheRef; + BOOL _cacheWriteable; Vector *_vertices; Vector *_normals; @@ -155,7 +157,8 @@ typedef struct smooth:(BOOL)smooth shaderMacros:(NSDictionary *)macros shaderBindingTarget:(id)object - scaleFactor:(float)factor; + scaleFactor:(float)factor + cacheWriteable:(BOOL)cacheWriteable; + (OOMaterial *) placeholderMaterial; diff --git a/src/Core/OOMesh.m b/src/Core/OOMesh.m index dc3ec970..c61d02a7 100644 --- a/src/Core/OOMesh.m +++ b/src/Core/OOMesh.m @@ -136,7 +136,8 @@ materialDictionary:(NSDictionary *)materialDict smooth:(BOOL)smooth shaderMacros:(NSDictionary *)macros shaderBindingTarget:(id)object - scaleFactor:(float)scale; + scaleFactor:(float)scale + cacheWriteable:(BOOL)cacheWriteable; - (BOOL) loadData:(NSString *)filename scaleFactor:(float)scale; - (void) checkNormalsAndAdjustWinding; @@ -244,7 +245,8 @@ static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode) smooth:smooth shaderMacros:macros shaderBindingTarget:object - scaleFactor:1.0f] autorelease]; + scaleFactor:1.0f + cacheWriteable:YES] autorelease]; } + (instancetype) meshWithName:(NSString *)name @@ -255,6 +257,7 @@ static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode) shaderMacros:(NSDictionary *)macros shaderBindingTarget:(id)object scaleFactor:(float)scale + cacheWriteable:(BOOL)cacheWriteable { return [[[self alloc] initWithName:name cacheKey:cacheKey @@ -263,7 +266,8 @@ static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode) smooth:smooth shaderMacros:macros shaderBindingTarget:object - scaleFactor:scale] autorelease]; + scaleFactor:scale + cacheWriteable:cacheWriteable] autorelease]; } @@ -286,6 +290,8 @@ static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode) if (self == nil) return nil; baseFile = @"No Model"; + baseFileOctreeCacheRef = @"No Model-0.000"; + _cacheWriteable = YES; #if OO_MULTITEXTURE _textureUnitCount = NSNotFound; #endif @@ -302,6 +308,7 @@ static BOOL IsPerVertexNormalMode(OOMeshNormalMode mode) { unsigned i; + DESTROY(baseFileOctreeCacheRef); DESTROY(baseFile); DESTROY(octree); @@ -652,7 +659,7 @@ static NSString *NormalModeDescription(OOMeshNormalMode mode) { if (octree == nil) { - octree = [[OOCacheManager octreeForModel:baseFile] retain]; + octree = [[OOCacheManager octreeForModel:baseFileOctreeCacheRef] retain]; if (octree == nil) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; @@ -671,10 +678,17 @@ static NSString *NormalModeDescription(OOMeshNormalMode mode) octree = [converter findOctreeToDepth:[self octreeDepth]]; [octree retain]; - [OOCacheManager setOctree:octree forModel:baseFile]; + if (EXPECT(_cacheWriteable)) + { + [OOCacheManager setOctree:octree forModel:baseFileOctreeCacheRef]; + } [pool release]; } + else + { + OOLog(@"mesh.load.octreeCached", @"Retrieved octree \"%@\" from cache.", baseFileOctreeCacheRef); + } } return octree; @@ -850,6 +864,7 @@ materialDictionary:(NSDictionary *)materialDict shaderMacros:(NSDictionary *)macros shaderBindingTarget:(id)target scaleFactor:(float)scale + cacheWriteable:(BOOL)cacheWriteable { OOJS_PROFILE_ENTER @@ -858,6 +873,7 @@ shaderBindingTarget:(id)target NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init]; _normalMode = smooth ? kNormalModeSmooth : kNormalModePerFace; + _cacheWriteable = cacheWriteable; #if OOMESH_PROFILE _stopwatch = [[OOProfilingStopwatch alloc] init]; @@ -869,6 +885,7 @@ shaderBindingTarget:(id)target PROFILE(@"finished calculateBoundingVolumes (again\?\?)"); baseFile = [name copy]; + baseFileOctreeCacheRef = [[NSString stringWithFormat:@"%@-%.3f", baseFile, scale] copy]; /* New in r3033: save the material-defining parameters here so we can rebind the materials at any time. @@ -917,6 +934,7 @@ shaderBindingTarget:(id)target if (result != nil) { [result->baseFile retain]; + [result->baseFileOctreeCacheRef retain]; [result->octree retain]; [result->_retainedObjects retain]; [result->_materialDict retain]; @@ -1154,7 +1172,7 @@ shaderBindingTarget:(id)target if (!using_preloaded) { - OOLog(@"mesh.load.uncached", @"Mesh \"%@\" is not in cache, loading.", filename); + OOLog(@"mesh.load.uncached", @"Mesh \"%@\" is not in cache, loading.", cacheKey); NSCharacterSet *whitespaceCharSet = [NSCharacterSet whitespaceCharacterSet]; NSCharacterSet *whitespaceAndNewlineCharSet = [NSCharacterSet whitespaceAndNewlineCharacterSet]; @@ -1587,8 +1605,11 @@ shaderBindingTarget:(id)target } // save the resulting data for possible reuse - [OOCacheManager setMeshData:[self modelData] forName:cacheKey]; - PROFILE(@"saved to cache"); + if (EXPECT(_cacheWriteable)) + { + [OOCacheManager setMeshData:[self modelData] forName:cacheKey]; + PROFILE(@"saved to cache"); + } if (failFlag) { @@ -2004,6 +2025,7 @@ static float FaceAreaCorrect(GLuint *vertIndices, Vector *vertices) [self calculateBoundingVolumes]; DESTROY(octree); DESTROY(baseFile); // Avoid octree cache. + DESTROY(baseFileOctreeCacheRef); } diff --git a/src/Core/Universe.m b/src/Core/Universe.m index fa707bc9..d1b23731 100644 --- a/src/Core/Universe.m +++ b/src/Core/Universe.m @@ -5492,7 +5492,7 @@ static BOOL MaintainLinkedLists(Universe *uni) GLfloat expected_mass = 0.1f * [ship mass] * (0.75 + 0.5 * randf()); GLfloat wreck_mass = [wreck mass]; GLfloat scale_factor = powf(expected_mass / wreck_mass, 0.33333333f) * scale; // cube root of volume ratio - [wreck rescaleBy: scale_factor]; + [wreck rescaleBy:scale_factor writeToCache:NO]; [wreck setPosition:rpos];