Line data Source code
1 0 : /* 2 : 3 : SkyEntity.m 4 : 5 : Oolite 6 : Copyright (C) 2004-2013 Giles C Williams and contributors 7 : 8 : This program is free software; you can redistribute it and/or 9 : modify it under the terms of the GNU General Public License 10 : as published by the Free Software Foundation; either version 2 11 : of the License, or (at your option) any later version. 12 : 13 : This program is distributed in the hope that it will be useful, 14 : but WITHOUT ANY WARRANTY; without even the implied warranty of 15 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 : GNU General Public License for more details. 17 : 18 : You should have received a copy of the GNU General Public License 19 : along with this program; if not, write to the Free Software 20 : Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 21 : MA 02110-1301, USA. 22 : 23 : */ 24 : 25 : 26 : #import "SkyEntity.h" 27 : #import "OOSkyDrawable.h" 28 : #import "PlayerEntity.h" 29 : 30 : #import "OOMaths.h" 31 : #import "Universe.h" 32 : #import "MyOpenGLView.h" 33 : #import "OOColor.h" 34 : #import "OOStringParsing.h" 35 : #import "OOCollectionExtractors.h" 36 : #import "OOMaterial.h" 37 : 38 : 39 0 : #define SKY_BASIS_STARS 4800 40 0 : #define SKY_BASIS_BLOBS 1280 41 0 : #define SKY_clusterChance 0.80 42 0 : #define SKY_alpha 0.10 43 0 : #define SKY_scale 10.0 44 : 45 : 46 : @interface SkyEntity (OOPrivate) 47 : 48 0 : - (BOOL)readColor1:(OOColor **)ioColor1 andColor2:(OOColor **)ioColor2 andColor3:(OOColor **)ioColor3 andColor4:(OOColor **)ioColor4 fromDictionary:(NSDictionary *)dictionary; 49 : 50 : @end 51 : 52 : 53 : @implementation SkyEntity 54 : 55 : - (id) initWithColors:(OOColor *)col1 :(OOColor *)col2 andSystemInfo:(NSDictionary *)systemInfo 56 : { 57 : OOSkyDrawable *skyDrawable; 58 : float clusterChance, 59 : alpha, 60 : scale, 61 : starCountMultiplier, 62 : nebulaCountMultiplier; 63 : signed starCount, // Need to be able to hold -1... 64 : nebulaCount; 65 : 66 : self = [super init]; 67 : if (self == nil) return nil; 68 : 69 : OOColor *col3 = [OOColor colorWithDescription:col1]; 70 : OOColor *col4 = [OOColor colorWithDescription:col2]; 71 : 72 : // Load colours 73 : BOOL nebulaColorSet = [self readColor1:&col1 andColor2:&col2 andColor3:&col3 andColor4:&col4 fromDictionary:systemInfo]; 74 : 75 : skyColor = [[OOColor colorWithDescription:[systemInfo objectForKey:@"sun_color"]] retain]; 76 : if (skyColor == nil) 77 : { 78 : skyColor = [[col2 blendedColorWithFraction:0.5 ofColor:col1] retain]; 79 : } 80 : 81 : // Load distribution values 82 : clusterChance = [systemInfo oo_floatForKey:@"sky_blur_cluster_chance" defaultValue:SKY_clusterChance]; 83 : alpha = [systemInfo oo_floatForKey:@"sky_blur_alpha" defaultValue:SKY_alpha]; 84 : scale = [systemInfo oo_floatForKey:@"sky_blur_scale" defaultValue:SKY_scale]; 85 : 86 : // Load star count 87 : starCount = [systemInfo oo_floatForKey:@"sky_n_stars" defaultValue:-1]; 88 : starCountMultiplier = [systemInfo oo_floatForKey:@"star_count_multiplier" defaultValue:1.0f]; 89 : if (starCountMultiplier < 0.0f) starCountMultiplier *= -1.0f; 90 : if (0 <= starCount) 91 : { 92 : // changed for 1.82, default set to 1 93 : // lets OXPers modify the broad number without stopping variation 94 : starCount *= starCountMultiplier; 95 : } 96 : else 97 : { 98 : starCount = starCountMultiplier * SKY_BASIS_STARS * (0.5 + randf()); 99 : } 100 : 101 : // ...and nebula count. (Note: simplifying this would change the appearance of stars/blobs.) 102 : nebulaCount = [systemInfo oo_floatForKey:@"sky_n_blurs" defaultValue:-1]; 103 : nebulaCountMultiplier = [systemInfo oo_floatForKey:@"nebula_count_multiplier" defaultValue:1.0f]; 104 : if (nebulaCountMultiplier < 0.0f) nebulaCountMultiplier *= -1.0f; 105 : if (0 <= nebulaCount) 106 : { 107 : // changed for 1.82, default set to 1 108 : // lets OXPers modify the broad number without stopping variation 109 : nebulaCount *= nebulaCountMultiplier; 110 : } 111 : else 112 : { 113 : nebulaCount = nebulaCountMultiplier * SKY_BASIS_BLOBS * (0.5 + randf()); 114 : } 115 : 116 : if ([UNIVERSE reducedDetail]) 117 : { 118 : // limit stars and blobs to basis levels, and halve stars again 119 : if (starCount > SKY_BASIS_STARS) 120 : { 121 : starCount = SKY_BASIS_STARS; 122 : } 123 : starCount /= 2; 124 : if (nebulaCount > SKY_BASIS_BLOBS) 125 : { 126 : nebulaCount = SKY_BASIS_BLOBS; 127 : } 128 : } 129 : 130 : skyDrawable = [[OOSkyDrawable alloc] 131 : initWithColor1:col1 132 : Color2:col2 133 : Color3:col3 134 : Color4:col4 135 : starCount:starCount 136 : nebulaCount:nebulaCount 137 : nebulaHueFix:nebulaColorSet 138 : clusterFactor:clusterChance 139 : alpha:alpha 140 : scale:scale]; 141 : [self setDrawable:skyDrawable]; 142 : [skyDrawable release]; 143 : 144 : [self setStatus:STATUS_EFFECT]; 145 : 146 : return self; 147 : } 148 : 149 : 150 0 : - (void) dealloc 151 : { 152 : [skyColor release]; 153 : 154 : [super dealloc]; 155 : } 156 : 157 : 158 : - (OOColor *) skyColor 159 : { 160 : return skyColor; 161 : } 162 : 163 : 164 : - (BOOL) changeProperty:(NSString *)key withDictionary:(NSDictionary*)dict 165 : { 166 : id object = [dict objectForKey:key]; 167 : 168 : // TODO: properties requiring reInit? 169 : if ([key isEqualToString:@"sun_color"]) 170 : { 171 : OOColor *col=[[OOColor colorWithDescription:object] retain]; 172 : if (col != nil) 173 : { 174 : [skyColor release]; 175 : skyColor = [col copy]; 176 : [col release]; 177 : [UNIVERSE setLighting]; 178 : } 179 : } 180 : else 181 : { 182 : OOLogWARN(@"script.warning", @"Change to property '%@' not applied, will apply only on leaving and re-entering this system.",key); 183 : return NO; 184 : } 185 : return YES; 186 : } 187 : 188 : 189 0 : - (void) update:(OOTimeDelta) delta_t 190 : { 191 : PlayerEntity *player = PLAYER; 192 : zero_distance = MAX_CLEAR_DEPTH * MAX_CLEAR_DEPTH; 193 : cam_zero_distance = zero_distance; 194 : if (player != nil) 195 : { 196 : position = [player viewpointPosition]; 197 : } 198 : else 199 : { 200 : OOLog(@"sky.warning", @"%@", @"PLAYER is nil"); 201 : } 202 : } 203 : 204 : 205 0 : - (BOOL) isSky 206 : { 207 : return YES; 208 : } 209 : 210 : 211 0 : - (BOOL) isVisible 212 : { 213 : return YES; 214 : } 215 : 216 : 217 0 : - (BOOL) canCollide 218 : { 219 : return NO; 220 : } 221 : 222 : 223 0 : - (GLfloat) cameraRangeFront 224 : { 225 : return MAX_CLEAR_DEPTH; 226 : } 227 : 228 : 229 0 : - (GLfloat) cameraRangeBack 230 : { 231 : return MAX_CLEAR_DEPTH; 232 : } 233 : 234 : 235 0 : - (void) drawImmediate:(bool)immediate translucent:(bool)translucent 236 : { 237 : if ([UNIVERSE breakPatternHide]) return; 238 : 239 : [super drawImmediate:immediate translucent:translucent]; 240 : 241 : OOCheckOpenGLErrors(@"SkyEntity after drawing %@", self); 242 : } 243 : 244 : 245 : #ifndef NDEBUG 246 0 : - (NSString *) descriptionForObjDump 247 : { 248 : // Don't include range and visibility flag as they're irrelevant. 249 : return [self descriptionForObjDumpBasic]; 250 : } 251 : #endif 252 : 253 : @end 254 : 255 : 256 : @implementation SkyEntity (OOPrivate) 257 : 258 : - (BOOL)readColor1:(OOColor **)ioColor1 andColor2:(OOColor **)ioColor2 andColor3:(OOColor **)ioColor3 andColor4:(OOColor **)ioColor4 fromDictionary:(NSDictionary *)dictionary 259 : { 260 : NSString *string = nil; 261 : NSArray *tokens = nil; 262 : id colorDesc = nil; 263 : OOColor *color = nil; 264 : BOOL nebulaSet = NO; 265 : 266 : assert(ioColor1 != NULL && ioColor2 != NULL); 267 : 268 : string = [dictionary oo_stringForKey:@"sky_rgb_colors"]; 269 : if (string != nil) 270 : { 271 : tokens = ScanTokensFromString(string); 272 : 273 : if ([tokens count] == 6) 274 : { 275 : float r1 = OOClamp_0_1_f([tokens oo_floatAtIndex:0]); 276 : float g1 = OOClamp_0_1_f([tokens oo_floatAtIndex:1]); 277 : float b1 = OOClamp_0_1_f([tokens oo_floatAtIndex:2]); 278 : float r2 = OOClamp_0_1_f([tokens oo_floatAtIndex:3]); 279 : float g2 = OOClamp_0_1_f([tokens oo_floatAtIndex:4]); 280 : float b2 = OOClamp_0_1_f([tokens oo_floatAtIndex:5]); 281 : *ioColor1 = [OOColor colorWithRed:r1 green:g1 blue:b1 alpha:1.0]; 282 : *ioColor2 = [OOColor colorWithRed:r2 green:g2 blue:b2 alpha:1.0]; 283 : } 284 : else 285 : { 286 : OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as two RGB colours (must be six numbers).", string); 287 : } 288 : } 289 : colorDesc = [dictionary objectForKey:@"sky_color_1"]; 290 : if (colorDesc != nil) 291 : { 292 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 293 : if (color != nil) *ioColor1 = color; 294 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 295 : } 296 : colorDesc = [dictionary objectForKey:@"sky_color_2"]; 297 : if (colorDesc != nil) 298 : { 299 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 300 : if (color != nil) *ioColor2 = color; 301 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 302 : } 303 : 304 : colorDesc = [dictionary objectForKey:@"nebula_color_1"]; 305 : if (colorDesc != nil) 306 : { 307 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 308 : if (color != nil) 309 : { 310 : *ioColor3 = color; 311 : nebulaSet = YES; 312 : } 313 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 314 : } 315 : else 316 : { 317 : colorDesc = [dictionary objectForKey:@"sky_color_1"]; 318 : if (colorDesc != nil) 319 : { 320 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 321 : if (color != nil) *ioColor3 = color; 322 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 323 : } 324 : } 325 : 326 : colorDesc = [dictionary objectForKey:@"nebula_color_2"]; 327 : if (colorDesc != nil) 328 : { 329 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 330 : if (color != nil) 331 : { 332 : *ioColor4 = color; 333 : nebulaSet = YES; 334 : } 335 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 336 : } 337 : else 338 : { 339 : colorDesc = [dictionary objectForKey:@"sky_color_2"]; 340 : if (colorDesc != nil) 341 : { 342 : color = [[OOColor colorWithDescription:colorDesc] premultipliedColor]; 343 : if (color != nil) *ioColor4 = color; 344 : else OOLogWARN(@"sky.fromDict", @"could not interpret \"%@\" as a colour.", colorDesc); 345 : } 346 : } 347 : return nebulaSet; 348 : } 349 : 350 : @end