Oolite
Loading...
Searching...
No Matches
OOPlanetEntity.m
Go to the documentation of this file.
1/*
2
3OOPlanetEntity.m
4
5Oolite
6Copyright (C) 2004-2013 Giles C Williams and contributors
7
8This program is free software; you can redistribute it and/or
9modify it under the terms of the GNU General Public License
10as published by the Free Software Foundation; either version 2
11of the License, or (at your option) any later version.
12
13This program is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with this program; if not, write to the Free Software
20Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
21MA 02110-1301, USA.
22
23*/
24
25#import "OOPlanetEntity.h"
26
27#if NEW_PLANETS
28
29#define NEW_ATMOSPHERE 1
30
31#import "OOPlanetDrawable.h"
32
33#import "AI.h"
34#import "Universe.h"
35#import "ShipEntity.h"
36#import "PlayerEntity.h"
37#import "ShipEntityAI.h"
38#import "OOCharacter.h"
39
40#import "OOMaths.h"
41#import "ResourceManager.h"
42#import "OOStringParsing.h"
45
49#import "OOShaderMaterial.h"
52#import "OOStringExpander.h"
54
55
56#define OO_TERMINATOR_THRESHOLD_VECTOR_DEFAULT (make_vector(0.105, 0.18, 0.28)) // used to be (0.1, 0.105, 0.12);
57
58
59@interface OOPlanetEntity (Private) <OOGraphicsResetClient>
60
61- (void) setUpTerrainParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo;
62- (void) setUpLandParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo;
63- (void) setUpAtmosphereParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo;
64- (void) setUpColorParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo isAtmosphere:(BOOL)isAtmosphere;
65- (void) setUpTypeParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo;
66
67@end
68
69
70@implementation OOPlanetEntity
71
72// this is exclusively called to initialise the main planet.
73- (id) initAsMainPlanetForSystem:(OOSystemID)s
74{
75 NSMutableDictionary *planetInfo = [[UNIVERSE generateSystemData:s] mutableCopy];
76 [planetInfo autorelease];
77
78 [planetInfo oo_setBool:YES forKey:@"mainForLocalSystem"];
79 if (s != [PLAYER systemID])
80 {
81 [planetInfo oo_setBool:YES forKey:@"isMiniature"];
82 }
83 return [self initFromDictionary:planetInfo withAtmosphere:[planetInfo oo_boolForKey:@"has_atmosphere" defaultValue:YES] andSeed:[[UNIVERSE systemManager] getRandomSeedForSystem:s inGalaxy:[PLAYER galaxyNumber]] forSystem:s];
84}
85
86
87static const double kMesosphere = 10.0 * ATMOSPHERE_DEPTH; // atmosphere effect starts at 10x the height of the clouds
88
89
90- (id) initFromDictionary:(NSDictionary *)dict withAtmosphere:(BOOL)atmosphere andSeed:(Random_Seed)seed forSystem:(OOSystemID)systemID
91{
92 if (dict == nil) dict = [NSDictionary dictionary];
93 RANROTSeed savedRanrotSeed = RANROTGetFullSeed();
94
95 self = [self init];
96 if (self == nil) return nil;
97
98 scanClass = CLASS_NO_DRAW;
99
100 NSMutableDictionary *planetInfo = [[UNIVERSE generateSystemData:systemID] mutableCopy];
101 [planetInfo autorelease];
102
103 [self setUpTypeParametersWithSourceInfo:dict targetInfo:planetInfo];
104
106
107
108 // Load random seed override.
109 NSString *seedStr = [dict oo_stringForKey:@"seed"];
110 if (seedStr != nil)
111 {
112 Random_Seed overrideSeed = RandomSeedFromString(seedStr);
113 if (!is_nil_seed(overrideSeed)) seed = overrideSeed;
114 else OOLogERR(@"planet.fromDict", @"could not interpret \"%@\" as planet seed, using default.", seedStr);
115 }
116
117 // Generate various planet info.
119
120 _name = nil;
121 [self setName:OOExpand([dict oo_stringForKey:KEY_PLANETNAME defaultValue:[planetInfo oo_stringForKey:KEY_PLANETNAME defaultValue:@"%H"]])];
122
123 int radius_km = [dict oo_intForKey:KEY_RADIUS defaultValue:[planetInfo oo_intForKey:KEY_RADIUS]];
124 collision_radius = radius_km * 10.0; // Scale down by a factor of 100
125 OOTechLevelID techLevel = [dict oo_intForKey:KEY_TECHLEVEL defaultValue:[planetInfo oo_intForKey:KEY_TECHLEVEL]];
126
127 if (techLevel > 14) techLevel = 14;
128 _shuttlesOnGround = 1 + techLevel / 2;
129 _shuttleLaunchInterval = 3600.0 / (double)_shuttlesOnGround; // All are launched in one hour.
130 _lastLaunchTime = [UNIVERSE getTime] + 30.0 - _shuttleLaunchInterval; // launch 30s after player enters universe.
131 // make delay > 0 to allow scripts adding a station nearby.
132
133 int percent_land = [planetInfo oo_intForKey:@"percent_land" defaultValue:24 + (gen_rnd_number() % 48)];
134 [planetInfo setObject:[NSNumber numberWithFloat:0.01 * percent_land] forKey:@"land_fraction"];
135
136 int percent_ice = [planetInfo oo_intForKey:@"percent_ice" defaultValue:5];
137 [planetInfo setObject:[NSNumber numberWithFloat:0.01 * percent_ice] forKey:@"polar_fraction"];
138
139
140 RNG_Seed savedRndSeed = currentRandomSeed();
141
142 _planetDrawable = [[OOPlanetDrawable alloc] init];
143
144 _terminatorThresholdVector = [planetInfo oo_vectorForKey:@"terminator_threshold_vector" defaultValue:OO_TERMINATOR_THRESHOLD_VECTOR_DEFAULT];
145
146 // Load material parameters, including atmosphere.
147 RANROTSeed planetNoiseSeed = RANROTGetFullSeed();
148 [planetInfo setObject:[NSValue valueWithBytes:&planetNoiseSeed objCType:@encode(RANROTSeed)] forKey:@"noise_map_seed"];
149 [self setUpLandParametersWithSourceInfo:dict targetInfo:planetInfo];
150
151 _airColor = nil; // default to no air
152 _airColorMixRatio = 0.5f;
153 _airDensity = 0.75f;
154
155 _illuminationColor = [[planetInfo objectForKey:@"illumination_color"] retain];
156
157#if NEW_ATMOSPHERE
158 if (atmosphere)
159 {
160 // shader atmosphere always has a radius of collision_radius + ATMOSPHERE_DEPTH. For texture atmosphere, we need to check
161 // if a shader atmosphere is also used. If yes, set its radius to just cover the planet so that it doesn't conflict with
162 // the shader atmosphere at the planet edges. If no shader atmosphere is used, then set it to the standard radius
163 double atmosphereRadius = [UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS ? collision_radius : collision_radius + ATMOSPHERE_DEPTH;
164 _atmosphereDrawable = [[OOPlanetDrawable atmosphereWithRadius:atmosphereRadius] retain];
165 _cloudsShaderDrawable = [[OOPlanetDrawable atmosphereWithRadius:atmosphereRadius] retain];
166 _atmosphereShaderDrawable = [[OOPlanetDrawable atmosphereWithRadius:collision_radius + ATMOSPHERE_DEPTH] retain];
167
168 // convert the atmosphere settings to generic 'material parameters'
169 percent_land = 100 - [dict oo_intForKey:@"percent_cloud" defaultValue:100 - (3 + (gen_rnd_number() & 31)+(gen_rnd_number() & 31))];
170 [planetInfo setObject:[NSNumber numberWithFloat:0.01 * percent_land] forKey:@"cloud_fraction"];
172 // planetInfo now contains a valid air_color
173 _airColor = [[planetInfo objectForKey:@"air_color"] retain];
174 _airColorMixRatio = [planetInfo oo_floatForKey:@"air_color_mix_ratio"];
175
176 _airDensity = OOClamp_0_1_f([planetInfo oo_floatForKey:@"air_density"]);
177 // OOLog (@"planet.debug",@" translated air colour:%@ cloud colour:%@ polar cloud color:%@", [_airColor rgbaDescription],[(OOColor *)[planetInfo objectForKey:@"cloud_color"] rgbaDescription],[(OOColor *)[planetInfo objectForKey:@"polar_cloud_color"] rgbaDescription]);
178
179 _materialParameters = [planetInfo dictionaryWithValuesForKeys:[NSArray arrayWithObjects:@"cloud_fraction", @"air_color", @"air_color_mix_ratio", @"air_density", @"cloud_color", @"polar_cloud_color", @"cloud_alpha", @"land_fraction", @"land_color", @"sea_color", @"polar_land_color", @"polar_sea_color", @"noise_map_seed", @"economy", @"polar_fraction", @"isMiniature", @"perlin_3d", @"terminator_threshold_vector", nil]];
180 }
181 else
182#else
183 // NEW_ATMOSPHERE is 0? still differentiate between normal planets and moons.
184 if (atmosphere)
185 {
186 _atmosphereDrawable = [[OOPlanetDrawable atmosphereWithRadius:collision_radius + ATMOSPHERE_DEPTH] retain];
187 _airColor = [[OOColor colorWithRed:0.8f green:0.8f blue:0.9f alpha:1.0f] retain];
188 }
189 if (YES) // create _materialParameters when NEW_ATMOSPHERE is set to 0
190#endif
191 {
192 _materialParameters = [planetInfo dictionaryWithValuesForKeys:[NSArray arrayWithObjects:@"land_fraction", @"land_color", @"sea_color", @"polar_land_color", @"polar_sea_color", @"noise_map_seed", @"economy", @"polar_fraction", @"isMiniature", @"perlin_3d", @"terminator_threshold_vector", @"illumination_color", nil]];
193 }
194 [_materialParameters retain];
195
196 _mesopause2 = (atmosphere) ? (kMesosphere + collision_radius) * (kMesosphere + collision_radius) : 0.0;
197
198 _normSpecMapName = [[dict oo_stringForKey:@"texture_normspec"] retain]; // must be set up before _textureName
199
200 _textureName = [[dict oo_stringForKey:@"texture"] retain];
201 [self setUpPlanetFromTexture:_textureName];
202 [_planetDrawable setRadius:collision_radius];
203
204 // Orientation should be handled by the code that calls this planetEntity. Starting with a default value anyway.
205 orientation = (Quaternion){ M_SQRT1_2, M_SQRT1_2, 0, 0 };
206 _atmosphereOrientation = kIdentityQuaternion;
207 _rotationAxis = vector_up_from_quaternion(orientation);
208
209 // set speed of rotation.
210 if ([dict objectForKey:@"rotational_velocity"])
211 {
212 _rotationalVelocity = [dict oo_floatForKey:@"rotational_velocity" defaultValue:0.01f * randf()]; // 0.0 .. 0.01 avr 0.005
213 }
214 else
215 {
216 _rotationalVelocity = [planetInfo oo_floatForKey:@"rotation_speed" defaultValue:0.005f * randf()]; // 0.0 .. 0.005 avr 0.0025
217 _rotationalVelocity *= [planetInfo oo_floatForKey:@"rotation_speed_factor" defaultValue:1.0f];
218 }
219
220 _atmosphereRotationalVelocity = [dict oo_floatForKey:@"atmosphere_rotational_velocity" defaultValue:0.01f * randf()];
221
222 // set energy
223 energy = collision_radius * 1000.0f;
224
225 setRandomSeed(savedRndSeed);
226 RANROTSetFullSeed(savedRanrotSeed);
227
228 // rotate planet based on current time, needs to be done here - backported from PlanetEntity.
229 int deltaT = floor(fmod([PLAYER clockTimeAdjusted], 86400));
230 quaternion_rotate_about_axis(&orientation, _rotationAxis, _rotationalVelocity * deltaT);
231 quaternion_rotate_about_axis(&_atmosphereOrientation, kBasisYVector, _atmosphereRotationalVelocity * deltaT);
232
233
234#ifdef OO_DUMP_PLANETINFO
235#define CPROP(PROP) OOLog(@"planetinfo.record",@#PROP " = %@;",[(OOColor *)[planetInfo objectForKey:@#PROP] descriptionComponents]);
236#define FPROP(PROP) OOLog(@"planetinfo.record",@#PROP " = %f;",[planetInfo oo_floatForKey:@"" #PROP]);
237 CPROP(air_color);
238 CPROP(illumination_color);
239 FPROP(air_color_mix_ratio);
240 FPROP(cloud_alpha);
241 CPROP(cloud_color);
242 FPROP(cloud_fraction);
243 CPROP(land_color);
244 FPROP(land_fraction);
245 CPROP(polar_cloud_color);
246 CPROP(polar_land_color);
247 CPROP(polar_sea_color);
248 CPROP(sea_color);
249 OOLog(@"planetinfo.record",@"rotation_speed = %f",_rotationalVelocity);
250#endif
251
252 [self setStatus:STATUS_ACTIVE];
253
255
256 return self;
257}
258
259
260static Vector RandomHSBColor(void)
261{
262 return (Vector)
263 {
264 gen_rnd_number() / 256.0,
265 gen_rnd_number() / 256.0,
266 0.5 + gen_rnd_number() / 512.0
267 };
268}
269
270
271static Vector LighterHSBColor(Vector c)
272{
273 return (Vector)
274 {
275 c.x,
276 c.y * 0.25f,
277 1.0f - (c.z * 0.1f)
278 };
279}
280
281
282static Vector HSBColorWithColor(OOColor *color)
283{
285 return (Vector){ c.h/360, c.s, c.b };
286}
287
288
289static OOColor *ColorWithHSBColor(Vector c)
290{
291 return [OOColor colorWithHue:c.x saturation:c.y brightness:c.z alpha:1.0];
292}
293
294
295- (void) setUpTypeParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo
296{
297 [targetInfo oo_setBool:[sourceInfo oo_boolForKey:@"mainForLocalSystem"] forKey:@"mainForLocalSystem"];
298 [targetInfo oo_setBool:[sourceInfo oo_boolForKey:@"isMiniature"] forKey:@"isMiniature"];
299
300}
301
302
303- (void) setUpTerrainParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo
304{
305 NSArray *keys = [NSArray arrayWithObjects:@"atmosphere_rotational_velocity",@"rotational_velocity",@"cloud_alpha",@"has_atmosphere",@"percent_cloud",@"percent_ice",@"percent_land",@"radius",@"seed",nil];
306 NSString *key = nil;
307 foreach (key, keys) {
308 id sval = [sourceInfo objectForKey:key];
309 if (sval != nil) {
310 [targetInfo setObject:sval forKey:key];
311 }
312 }
313
314}
315
316
317- (void) setUpLandParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo
318{
319 [self setUpColorParametersWithSourceInfo:sourceInfo targetInfo:targetInfo isAtmosphere:NO];
320}
321
322
323- (void) setUpAtmosphereParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo
324{
325 [self setUpColorParametersWithSourceInfo:sourceInfo targetInfo:targetInfo isAtmosphere:YES];
326}
327
328
329- (void) setUpColorParametersWithSourceInfo:(NSDictionary *)sourceInfo targetInfo:(NSMutableDictionary *)targetInfo isAtmosphere:(BOOL)isAtmosphere
330{
331 // Stir the PRNG fourteen times for backwards compatibility.
332 unsigned i;
333 for (i = 0; i < 14; i++)
334 {
336 }
337
338 Vector landHSB, seaHSB, landPolarHSB, seaPolarHSB, illumHSB;
339 Vector terminatorThreshold;
340 OOColor *color;
341
342 landHSB = RandomHSBColor();
343
344 if (!isAtmosphere)
345 {
346 do
347 {
348 seaHSB = RandomHSBColor();
349 }
350 while (dot_product(landHSB, seaHSB) > .80f); // make sure land and sea colors differ significantly
351
352 // saturation bias - avoids really grey oceans
353 if (seaHSB.y < 0.22f) seaHSB.y = seaHSB.y * 0.3f + 0.2f;
354 // brightness bias - avoids really bright landmasses
355 if (landHSB.z > 0.66f) landHSB.z = 0.66f;
356
357 // planetinfo.plist overrides
358 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"land_color"]];
359 if (color != nil) landHSB = HSBColorWithColor(color);
360 else ScanVectorFromString([sourceInfo oo_stringForKey:@"land_hsb_color"], &landHSB);
361
362 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"sea_color"]];
363 if (color != nil) seaHSB = HSBColorWithColor(color);
364 else ScanVectorFromString([sourceInfo oo_stringForKey:@"sea_hsb_color"], &seaHSB);
365
366 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"illumination_color"]];
367 if (color != nil) illumHSB = HSBColorWithColor(color);
368 else
369 {
370 NSString *illumHSBColorString = [sourceInfo oo_stringForKey:@"illumination_hsb_color"];
371 if (illumHSBColorString) ScanVectorFromString(illumHSBColorString, &illumHSB);
372 else illumHSB = HSBColorWithColor([OOColor colorWithRed:0.8f green:0.8f blue:0.4f alpha:1.0f]);
373 }
374
375 // polar areas are brighter but have less colour (closer to white)
376 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"polar_land_color"]];
377 if (color != nil)
378 {
379 landPolarHSB = HSBColorWithColor(color);
380 }
381 else
382 {
383 landPolarHSB = LighterHSBColor(landHSB);
384 }
385
386 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"polar_sea_color"]];
387 if (color != nil)
388 {
389 seaPolarHSB = HSBColorWithColor(color);
390 }
391 else
392 {
393 seaPolarHSB = LighterHSBColor(seaHSB);
394 }
395
396 [targetInfo setObject:ColorWithHSBColor(landHSB) forKey:@"land_color"];
397 [targetInfo setObject:ColorWithHSBColor(seaHSB) forKey:@"sea_color"];
398 [targetInfo setObject:ColorWithHSBColor(landPolarHSB) forKey:@"polar_land_color"];
399 [targetInfo setObject:ColorWithHSBColor(seaPolarHSB) forKey:@"polar_sea_color"];
400 [targetInfo setObject:ColorWithHSBColor(illumHSB) forKey:@"illumination_color"];
401 }
402 else
403 {
404 landHSB = RandomHSBColor(); // NB: randomcolor is called twice to make the cloud colour similar to the old one.
405
406 // add a cloud_color tinge to sky blue({0.66, 0.3, 1}).
407 seaHSB = vector_add(landHSB,((Vector){1.333, 0.6, 2})); // 1 part cloud, 2 parts sky blue
408 scale_vector(&seaHSB, 0.333);
409
410 float cloudAlpha = OOClamp_0_1_f([sourceInfo oo_floatForKey:@"cloud_alpha" defaultValue:1.0f]);
411 [targetInfo setObject:[NSNumber numberWithFloat:cloudAlpha] forKey:@"cloud_alpha"];
412
413 // planetinfo overrides
414 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"air_color"]];
415 if (color != nil) seaHSB = HSBColorWithColor(color);
416
417 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"cloud_color"]];
418 if (color != nil) landHSB = HSBColorWithColor(color);
419
420 // polar areas: brighter, less saturation
421 landPolarHSB = vector_add(landHSB,LighterHSBColor(landHSB));
422 scale_vector(&landPolarHSB, 0.5);
423
424 color = [OOColor colorWithDescription:[sourceInfo objectForKey:@"polar_cloud_color"]];
425 if (color != nil) landPolarHSB = HSBColorWithColor(color);
426
427 [targetInfo setObject:ColorWithHSBColor(seaHSB) forKey:@"air_color"];
428 [targetInfo setObject:ColorWithHSBColor(landHSB) forKey:@"cloud_color"];
429 [targetInfo setObject:ColorWithHSBColor(landPolarHSB) forKey:@"polar_cloud_color"];
430 [targetInfo setObject:[NSNumber numberWithFloat:[sourceInfo oo_floatForKey:@"air_color_mix_ratio"]] forKey:@"air_color_mix_ratio"];
431 }
432 terminatorThreshold = [sourceInfo oo_vectorForKey:@"terminator_threshold_vector" defaultValue:OO_TERMINATOR_THRESHOLD_VECTOR_DEFAULT];
433 [targetInfo setObject:[NSString stringWithFormat:@"%f %f %f", terminatorThreshold.x, terminatorThreshold.y, terminatorThreshold.z] forKey:@"terminator_threshold_vector"];
434}
435
436
437- (id) initAsMiniatureVersionOfPlanet:(OOPlanetEntity *)planet
438{
439 // Nasty, nasty. I'd really prefer to have a separate entity class for this.
440 if (planet == nil)
441 {
442 [self release];
443 return nil;
444 }
445
446 self = [self init];
447 if (self == nil) return nil;
448
449 scanClass = CLASS_NO_DRAW;
450 [self setStatus:STATUS_COCKPIT_DISPLAY];
451
452 collision_radius = planet->collision_radius * PLANET_MINIATURE_FACTOR;
453 orientation = planet->orientation;
454 _rotationAxis = planet->_rotationAxis;
455 _atmosphereOrientation = planet->_atmosphereOrientation;
456 _rotationalVelocity = 0.04;
457
458 _terminatorThresholdVector = planet->_terminatorThresholdVector;
459
460 _miniature = YES;
461
462 _planetDrawable = [planet->_planetDrawable copy];
463 [_planetDrawable setRadius:collision_radius];
464
465 // FIXME: in old planet code, atmosphere (if textured) is set to 0.6 alpha.
466 _atmosphereDrawable = [planet->_atmosphereDrawable copy];
467 _cloudsShaderDrawable = [planet->_cloudsShaderDrawable copy];
468 _atmosphereShaderDrawable = [planet->_atmosphereShaderDrawable copy];
469 [_atmosphereDrawable setRadius:collision_radius + ATMOSPHERE_DEPTH * PLANET_MINIATURE_FACTOR * 2.0]; //not to scale: invisible otherwise
470 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setRadius:collision_radius + ATMOSPHERE_DEPTH * PLANET_MINIATURE_FACTOR * 2.0]; //not to scale: invisible otherwise
471 if (_atmosphereShaderDrawable) [_atmosphereShaderDrawable setRadius:collision_radius + ATMOSPHERE_DEPTH * PLANET_MINIATURE_FACTOR * 2.0];
472
473 [_planetDrawable setLevelOfDetail:0.8f];
474 [_atmosphereDrawable setLevelOfDetail:0.8f];
475 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setLevelOfDetail:0.8f];
476 if (_atmosphereShaderDrawable) [_atmosphereShaderDrawable setLevelOfDetail:0.8f];
477
478 return self;
479}
480
481
482- (void) dealloc
483{
484 DESTROY(_name);
485 DESTROY(_planetDrawable);
486 DESTROY(_atmosphereDrawable);
487 DESTROY(_cloudsShaderDrawable);
488 DESTROY(_atmosphereShaderDrawable);
489 DESTROY(_airColor);
490 DESTROY(_illuminationColor);
491 DESTROY(_materialParameters);
492 DESTROY(_textureName);
493 DESTROY(_normSpecMapName);
494
496
497 [super dealloc];
498}
499
500
501- (NSString*) descriptionComponents
502{
503 return [NSString stringWithFormat:@"position: %@ radius: %g m", HPVectorDescription([self position]), [self radius]];
504}
505
506
507- (void) setOrientation:(Quaternion) quat
508{
509 [super setOrientation: quat];
510 _rotationAxis = vector_up_from_quaternion(quat);
511}
512
513
514- (double) radius
515{
516 return collision_radius;
517}
518
519
520- (OOStellarBodyType) planetType
521{
522 if (_miniature) return STELLAR_TYPE_MINIATURE;
523 if (_atmosphereDrawable != nil) return STELLAR_TYPE_NORMAL_PLANET;
524 return STELLAR_TYPE_MOON;
525}
526
527
528- (instancetype) miniatureVersion
529{
530 return [[[[self class] alloc] initAsMiniatureVersionOfPlanet:self] autorelease];
531}
532
533
534- (void) update:(OOTimeDelta) delta_t
535{
536 [super update:delta_t];
537
538 if (EXPECT(!_miniature))
539 {
540 BOOL canDrawShaderAtmosphere = _atmosphereShaderDrawable && [UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS;
541 if (EXPECT_NOT(_atmosphereDrawable && cam_zero_distance < _mesopause2))
542 {
543 NSAssert(_airColor != nil, @"Expected a non-nil air colour for normal planet. Exiting.");
544 double alt = (sqrt(cam_zero_distance) - collision_radius) / kMesosphere; // the viewpoint altitude
545 double trueAlt = (sqrt(zero_distance) - collision_radius) / kMesosphere; // the actual ship altitude
546 // if at long distance external view, rotating the camera could potentially end up with it being
547 // at negative altitude. Since we know we are already inside the atmosphere at this point, just make sure
548 // that altitude is kept to a minimum positive value to avoid sudden black skies
549 if (alt <= 0.0) alt = 1e-4;
550 if (EXPECT_NOT(alt > 0 && alt <= 1.0)) // ensure aleph is clamped between 0 and 1
551 {
552 double aleph = 1.0 - alt;
553 double aleph2 = aleph * aleph;
554
555 // night sky, reddish flash on entering the atmosphere, low light pollution otherwhise
556 OOColor *mixColor = [OOColor colorWithRed:(EXPECT_NOT(alt > 0.98) ? 30.0f : 0.1f)
557 green:0.1f
558 blue:0.1f
559 alpha:aleph];
560
561 // occlusion rate: .9 is 18 degrees after the terminus, where twilight ends.
562 // 1 is the terminus, 1.033 is 6 degrees before the terminus, where the sky begins to redden
563 double rate = ([PLAYER occlusionLevel] - 0.97)/0.06; // from 0.97 to 1.03
564
565 if (EXPECT(rate <= 1.0 && rate > 0.0))
566 {
567 mixColor = [mixColor blendedColorWithFraction:rate ofColor:_airColor];
568 // TODO: properly calculated pink sky - needs to depend on sun's angular size,
569 // and its angular height on the horizon.
570 /*
571 rate -= 0.7;
572 if (rate >= 0.0) // pink sky!
573 {
574 rate = 0.5 - (fabs(rate - 0.15) / 0.3); // at most a 50% blend!
575 mixColor = [mixColor blendedColorWithFraction:rate ofColor:[OOColor colorWithRed:0.6
576 green:0.1
577 blue:0.0
578 alpha:aleph]];
579 }
580 */
581 }
582 else
583 {
584 if (PLAYER->isSunlit && _airColor != nil) mixColor = _airColor;
585 }
586 [UNIVERSE setSkyColorRed:[mixColor redComponent] * aleph2
587 green:[mixColor greenComponent] * aleph2
588 blue:[mixColor blueComponent] * aleph
589 alpha:aleph];
590 double atmosphereRadius = canDrawShaderAtmosphere ? collision_radius : collision_radius + (ATMOSPHERE_DEPTH * alt);
591 [_atmosphereDrawable setRadius:atmosphereRadius];
592 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setRadius: atmosphereRadius];
593 if (_atmosphereShaderDrawable) [_atmosphereShaderDrawable setRadius:collision_radius + (ATMOSPHERE_DEPTH * alt)];
594 // apply air resistance for the ship, not the camera. Although setSkyColorRed
595 // has already set the air resistance to aleph, override it immediately
596 [UNIVERSE setAirResistanceFactor:OOClamp_0_1_f(1.0 - trueAlt)];
597 }
598 }
599 else
600 {
601 if (EXPECT_NOT([_atmosphereDrawable radius] < collision_radius + ATMOSPHERE_DEPTH))
602 {
603 [_atmosphereDrawable setRadius:collision_radius + ATMOSPHERE_DEPTH];
604 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setRadius: collision_radius * ATMOSPHERE_DEPTH];
605 if (_atmosphereShaderDrawable) [_atmosphereShaderDrawable setRadius:collision_radius + ATMOSPHERE_DEPTH];
606 }
607 if (canDrawShaderAtmosphere && [_atmosphereDrawable radius] != collision_radius)
608 {
609 // if shader atmo is in use, force texture atmo radius to just collision_radius for cosmetic purposes
610 [_atmosphereDrawable setRadius:collision_radius];
611 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setRadius: collision_radius];
612 }
613 if ([PLAYER findNearestPlanet] == self) // ensure no problems in case of more than one planets
614 {
615 [UNIVERSE setAirResistanceFactor:0.0f]; // out of atmosphere - no air friction
616 }
617 }
618
619 double time = [UNIVERSE getTime];
620
621 if (_shuttlesOnGround > 0 && time > _lastLaunchTime + _shuttleLaunchInterval) [self launchShuttle];
622 }
623
624 quaternion_rotate_about_axis(&orientation, _rotationAxis, _rotationalVelocity * delta_t);
625 // atmosphere orientation is relative to the orientation of the planet
626 quaternion_rotate_about_axis(&_atmosphereOrientation, kBasisYVector, _atmosphereRotationalVelocity * delta_t);
627
628 [self orientationChanged];
629
630 // FIXME: update atmosphere rotation
631}
632
633
634- (BOOL) isFinishedLoading
635{
636 OOMaterial *material = [self material];
637 if (material != nil && ![material isFinishedLoading]) return NO;
638 material = [self atmosphereMaterial];
639 if (material != nil && ![material isFinishedLoading]) return NO;
640 material = [self atmosphereShaderMaterial];
641 if (material != nil && ![material isFinishedLoading]) return NO;
642 return YES;
643}
644
645
646- (void) drawImmediate:(bool)immediate translucent:(bool)translucent
647{
648 BOOL canDrawShaderAtmosphere = _atmosphereShaderDrawable && [UNIVERSE detailLevel] >= DETAIL_LEVEL_SHADERS;
649
650 if ([UNIVERSE breakPatternHide]) return; // DON'T DRAW
651 if (_miniature && ![self isFinishedLoading]) return; // For responsiveness, don't block to draw as miniature.
652
653 // too far away to be drawn
654 if (magnitude(cameraRelativePosition) > [self radius]*3000) {
655 return;
656 }
657 if (![UNIVERSE viewFrustumIntersectsSphereAt:cameraRelativePosition withRadius:([self radius] + ATMOSPHERE_DEPTH)])
658 {
659 // Don't draw
660 return;
661 }
662
663 if ([UNIVERSE wireframeGraphics]) OOGLWireframeModeOn();
664
665 if (!_miniature)
666 {
667 [_planetDrawable calculateLevelOfDetailForViewDistance:cam_zero_distance];
668 [_atmosphereDrawable setLevelOfDetail:[_planetDrawable levelOfDetail]];
669 if (canDrawShaderAtmosphere)
670 {
671 if (_cloudsShaderDrawable) [_cloudsShaderDrawable setLevelOfDetail: [_planetDrawable levelOfDetail]];
672 [_atmosphereShaderDrawable setLevelOfDetail:[_planetDrawable levelOfDetail]];
673 }
674 }
675
676 // 500km squared
677 // if (magnitude2(cameraRelativePosition) > 250000000000.0)
678 /* Temporarily for 1.82 make this branch unconditional. There's an
679 * odd change in appearance when crossing this boundary, which can
680 * be quite noticeable. There don't appear to be close-range
681 * problems with doing it this way all the time, though it's not
682 * ideal. - CIM */
683 {
684 /* at this distance the atmosphere is too close to the planet
685 * for a 24-bit depth buffer to reliably distinguish the two,
686 * so cheat and draw the atmosphere on the opaque pass: it's
687 * far enough away that painter's algorithm should do fine */
688 [_planetDrawable renderOpaqueParts];
689 if (_atmosphereDrawable != nil)
690 {
692 OOGLMultModelView(OOMatrixForQuaternionRotation(_atmosphereOrientation));
693 if (canDrawShaderAtmosphere)
694 {
695 if(_cloudsShaderDrawable) [_cloudsShaderDrawable renderTranslucentPartsOnOpaquePass];
696 [_atmosphereShaderDrawable renderTranslucentPartsOnOpaquePass];
697 }
698 else
699 {
700 [_atmosphereDrawable renderTranslucentPartsOnOpaquePass];
701 }
703 }
704 }
705#if OOLITE_HAVE_FIXED_THE_ABOVE_DESCRIBED_BUG_WHICH_WE_HAVENT
706 else
707 {
708 /* At close range we can do this properly and draw the
709 * atmosphere on the transparent pass */
710 if (translucent)
711 {
712 if (_atmosphereDrawable != nil)
713 {
715 OOGLMultModelView(OOMatrixForQuaternionRotation(_atmosphereOrientation));
716 [_atmosphereDrawable renderTranslucentParts];
717 if (canDrawShaderAtmosphere) [_atmosphereShaderDrawable renderTranslucentParts];
719 }
720 }
721 else
722 {
723 [_planetDrawable renderOpaqueParts];
724 }
725 }
726#endif
727
728 if ([UNIVERSE wireframeGraphics]) OOGLWireframeModeOff();
729}
730
731
732- (BOOL) checkCloseCollisionWith:(Entity *)other
733{
734 if (!other)
735 return NO;
736 if (other->isShip)
737 {
738 ShipEntity *ship = (ShipEntity *)other;
739 if ([ship behaviour] == BEHAVIOUR_LAND_ON_PLANET)
740 {
741 return NO;
742 }
743 }
744
745 return YES;
746}
747
748
749- (BOOL) planetHasStation
750{
751 // find the nearest station...
752 ShipEntity *station = nil;
753 station = [UNIVERSE nearestShipMatchingPredicate:IsStationPredicate
754 parameter:nil
755 relativeToEntity:self];
756
757 if (station && HPdistance([station position], position) < 4 * collision_radius) // there is a station in range.
758 {
759 return YES;
760 }
761 return NO;
762}
763
764
765- (void) launchShuttle
766{
767 if (_shuttlesOnGround == 0)
768 {
769 return;
770 }
771 if ([PLAYER status] == STATUS_START_GAME)
772 {
773 // don't launch if game not started
774 return;
775 }
776 if (self != [UNIVERSE planet] && ![self planetHasStation])
777 {
778 // don't launch shuttles when no station is nearby.
779 _shuttlesOnGround = 0;
780 return;
781 }
782
783 Quaternion q1;
785 float start_distance = collision_radius + 125.0f;
786 HPVector launch_pos = HPvector_add(position, vectorToHPVector(vector_multiply_scalar(vector_forward_from_quaternion(q1), start_distance)));
787
788 ShipEntity *shuttle_ship = [UNIVERSE newShipWithRole:@"shuttle"]; // retain count = 1
789 if (shuttle_ship)
790 {
791 if ([[shuttle_ship crew] count] == 0)
792 {
793 [shuttle_ship setSingleCrewWithRole:@"trader"];
794 }
795
796 [shuttle_ship setPosition:launch_pos];
797 [shuttle_ship setOrientation:q1];
798
799 [shuttle_ship setScanClass: CLASS_NEUTRAL];
800 [shuttle_ship setCargoFlag:CARGO_FLAG_FULL_PLENTIFUL];
801 [shuttle_ship switchAITo:@"oolite-shuttleAI.js"];
802 [UNIVERSE addEntity:shuttle_ship]; // STATUS_IN_FLIGHT, AI state GLOBAL
803 _shuttlesOnGround--;
804 _lastLaunchTime = [UNIVERSE getTime];
805
806 [shuttle_ship release];
807 }
808}
809
810
811- (void) welcomeShuttle:(ShipEntity *)shuttle
812{
813 _shuttlesOnGround++;
814}
815
816
817- (BOOL) isPlanet
818{
819 return YES;
820}
821
822
823- (BOOL) isVisible
824{
825 return YES;
826}
827
828
829- (double) rotationalVelocity
830{
831 return _rotationalVelocity;
832}
833
834
835- (void) setRotationalVelocity:(double) v
836{
837 if ([self hasAtmosphere])
838 {
839 // FIXME: change atmosphere rotation speed proportionally
840 }
841 _rotationalVelocity = v;
842}
843
844
845// this method is visible to shader bindings, hence it returns vector
846- (Vector) airColorAsVector
847{
848 float r, g, b, a;
849 [_airColor getRed:&r green:&g blue:&b alpha:&a];
850 return make_vector(r, g, b); // don't care about a
851}
852
853
854- (OOColor *) airColor
855{
856 return _airColor;
857}
858
859
860- (void) setAirColor:(OOColor *) newColor
861{
862 if (newColor)
863 {
864 [_airColor release];
865 _airColor = [newColor retain];
866 }
867}
868
869
870// this method is visible to shader bindings, hence it returns vector
871- (Vector) illuminationColorAsVector
872{
873 float r, g, b, a;
874 [_illuminationColor getRed:&r green:&g blue:&b alpha:&a];
875 return make_vector(r, g, b); // don't care about a
876}
877
878
879- (OOColor *) illuminationColor
880{
881 return _illuminationColor;
882}
883
884
885- (void) setIlluminationColor:(OOColor *) newColor
886{
887 if (newColor)
888 {
889 [_illuminationColor release];
890 _illuminationColor = [newColor retain];
891 }
892}
893
894
895// visible to shader bindings
896- (float) airColorMixRatio
897{
898 return _airColorMixRatio;
899}
900
901
902- (void) setAirColorMixRatio:(float) newRatio
903{
904 _airColorMixRatio = OOClamp_0_1_f(newRatio);
905}
906
907
908// visible to shader bindings
909- (float) airDensity
910{
911 return _airDensity;
912}
913
914
915- (void) setAirDensity: (float)newDensity
916{
917 _airDensity = OOClamp_0_1_f(newDensity);
918}
919
920
921- (void) setTerminatorThresholdVector:(Vector) newTerminatorThresholdVector
922{
923 _terminatorThresholdVector.x = newTerminatorThresholdVector.x;
924 _terminatorThresholdVector.y = newTerminatorThresholdVector.y;
925 _terminatorThresholdVector.z = newTerminatorThresholdVector.z;
926}
927
928
929- (Vector) terminatorThresholdVector
930{
931 return _terminatorThresholdVector;
932}
933
934
935- (BOOL) hasAtmosphere
936{
937 return _atmosphereDrawable != nil;
938}
939
940
941// FIXME: need material model.
942- (NSString *) textureFileName
943{
944 return [_planetDrawable textureName];
945}
946
947
948- (void)resetGraphicsState
949{
950 // reset the texture if graphics mode changes
951 [self setUpPlanetFromTexture:_textureName];
952}
953
954
955- (void) setTextureFileName:(NSString *)textureName
956{
957 BOOL isMoon = _atmosphereDrawable == nil;
958
959 OOTexture *diffuseMap = nil;
960 OOTexture *normalMap = nil;
961 NSDictionary *macros = nil;
962 NSDictionary *materialDefaults = [ResourceManager materialDefaults];
963
964#if OO_SHADERS
965 OOGraphicsDetail detailLevel = [UNIVERSE detailLevel];
966 BOOL shadersOn = detailLevel >= DETAIL_LEVEL_SHADERS;
967#else
968 const BOOL shadersOn = NO;
969#endif
970
971 if (textureName != nil)
972 {
973 NSDictionary *spec = [NSDictionary dictionaryWithObjectsAndKeys:textureName, @"name", @"yes", @"repeat_s", @"linear", @"min_filter", @"yes", @"cube_map", nil];
974 diffuseMap = [OOTexture textureWithConfiguration:spec];
975 if (diffuseMap == nil) return; // OOTexture will have logged a file-not-found warning.
976 if (shadersOn)
977 {
978 [diffuseMap ensureFinishedLoading]; // only know if it is a cube map if it's loaded
979 if ([diffuseMap isCubeMap])
980 {
981 macros = [materialDefaults oo_dictionaryForKey:isMoon ? @"moon-customized-cubemap-macros" : @"planet-customized-cubemap-macros"];
982 }
983 else
984 {
985 macros = [materialDefaults oo_dictionaryForKey:isMoon ? @"moon-customized-macros" : @"planet-customized-macros"];
986 }
987 }
988 else textureName = @"dynamic";
989
990 // let's try giving some love to normalMap too
991 if (_normSpecMapName)
992 {
993 NSDictionary *nspec = [NSDictionary dictionaryWithObjectsAndKeys:_normSpecMapName, @"name", @"yes", @"repeat_s", @"linear", @"min_filter", @"yes", @"cube_map", nil];
994 normalMap = [OOTexture textureWithConfiguration:nspec];
995 if (normalMap != nil) // OOTexture will have logged a file-not-found warning.
996 {
997 if (shadersOn)
998 {
999 [normalMap ensureFinishedLoading]; // only know if it is a cube map if it's loaded
1000 if ([normalMap isCubeMap])
1001 {
1002 macros = [materialDefaults oo_dictionaryForKey:isMoon ? @"moon-customized-cubemap-normspec-macros" : @"planet-customized-cubemap-normspec-macros"];
1003 }
1004 else
1005 {
1006 macros = [materialDefaults oo_dictionaryForKey:isMoon ? @"moon-customized-normspec-macros" : @"planet-customized-normspec-macros"];
1007 }
1008 }
1009 }
1010 }
1011 }
1012 else
1013 {
1014 [OOPlanetTextureGenerator generatePlanetTexture:&diffuseMap
1015 secondaryTexture:(detailLevel >= DETAIL_LEVEL_SHADERS) ? &normalMap : NULL
1016 withInfo:_materialParameters];
1017
1018 if (shadersOn)
1019 {
1020 macros = [materialDefaults oo_dictionaryForKey:isMoon ? @"moon-dynamic-macros" : @"planet-dynamic-macros"];
1021 }
1022 textureName = @"dynamic";
1023 }
1024
1025 /* Generate atmosphere texture */
1026 if (!isMoon)
1027 {
1028 OOLog(@"texture.planet.generate",@"Preparing atmosphere for planet %@",self);
1029 /* Generate a standalone atmosphere texture */
1030 OOTexture *atmosphere = nil;
1032 withInfo:_materialParameters];
1033
1034 OOLog(@"texture.planet.generate",@"Planet %@ has atmosphere %@",self,atmosphere);
1035
1036 OOSingleTextureMaterial *dynamicMaterial = [[OOSingleTextureMaterial alloc] initWithName:@"dynamic" texture:atmosphere configuration:nil];
1037 [_atmosphereDrawable setMaterial:dynamicMaterial];
1038
1039 if (shadersOn)
1040 {
1041 NSMutableDictionary *aConfig = [[[materialDefaults oo_dictionaryForKey:@"atmosphere-material"] mutableCopy] autorelease];
1042 [aConfig setObject:[NSArray arrayWithObjects:diffuseMap, normalMap, nil] forKey:@"_oo_texture_objects"];
1043
1044 NSDictionary *amacros = [materialDefaults oo_dictionaryForKey:@"atmosphere-dynamic-macros"];
1045
1046 OOMaterial *dynamicShaderMaterial = [OOShaderMaterial shaderMaterialWithName:@"dynamic"
1047 configuration:aConfig
1048 macros:amacros
1049 bindingTarget:self];
1050
1051 if (dynamicShaderMaterial == nil)
1052 {
1053 DESTROY(_atmosphereShaderDrawable);
1054 }
1055 else
1056 {
1057 [_atmosphereShaderDrawable setMaterial:dynamicShaderMaterial];
1058 }
1059
1060 NSMutableDictionary *cloudConfig = [[[materialDefaults oo_dictionaryForKey:@"clouds-dynamic-material"] mutableCopy] autorelease];
1061 [cloudConfig setObject:[NSArray arrayWithObjects: atmosphere, nil] forKey: @"_oo_texture_objects"];
1062 NSDictionary *cloudMacros = [materialDefaults oo_dictionaryForKey: @"clouds-dynamic-macros"];
1063
1064 OOMaterial *cloudsMaterial = [OOShaderMaterial shaderMaterialWithName:@"dynamic"
1065 configuration: cloudConfig
1066 macros: cloudMacros
1067 bindingTarget: self];
1068 if (cloudsMaterial == nil)
1069 {
1070 DESTROY(_cloudsShaderDrawable);
1071 }
1072 else
1073 {
1074 [_cloudsShaderDrawable setMaterial: cloudsMaterial];
1075 }
1076 }
1077
1078 [dynamicMaterial release];
1079 }
1080
1081 OOMaterial *material = nil;
1082
1083#if OO_SHADERS
1084 if (shadersOn)
1085 {
1086 NSMutableDictionary *config = [[[materialDefaults oo_dictionaryForKey:@"planet-material"] mutableCopy] autorelease];
1087 [config setObject:[NSArray arrayWithObjects:diffuseMap, normalMap, nil] forKey:@"_oo_texture_objects"];
1088
1089 material = [OOShaderMaterial shaderMaterialWithName:textureName
1090 configuration:config
1091 macros:macros
1092 bindingTarget:self];
1093 }
1094#endif
1095 if (material == nil)
1096 {
1097 material = [[OOSingleTextureMaterial alloc] initWithName:textureName texture:diffuseMap configuration:nil];
1098 [material autorelease];
1099 }
1100 [_planetDrawable setMaterial:material];
1101}
1102
1103
1104- (BOOL) setUpPlanetFromTexture:(NSString *)textureName
1105{
1106 [self setTextureFileName:textureName];
1107 return YES;
1108}
1109
1110
1111- (OOMaterial *) material
1112{
1113 return [_planetDrawable material];
1114}
1115
1116
1117- (OOMaterial *) atmosphereMaterial
1118{
1119 return [_atmosphereDrawable material];
1120}
1121
1122
1123- (OOMaterial *) atmosphereShaderMaterial
1124{
1125 if(!_atmosphereShaderDrawable) return nil;
1126 return [_atmosphereShaderDrawable material];
1127}
1128
1129
1130- (NSString *) name
1131{
1132 return _name;
1133}
1134
1135
1136- (void) setName:(NSString *)name
1137{
1138 [_name release];
1139 _name = [name retain];
1140}
1141
1142@end
1143
1144#endif // NEW_PLANETS
#define DESTROY(x)
Definition OOCocoa.h:75
#define EXPECT_NOT(x)
#define EXPECT(x)
#define OOLogERR(class, format,...)
Definition OOLogging.h:112
#define OOLog(class, format,...)
Definition OOLogging.h:88
#define M_SQRT1_2
Definition OOMaths.h:94
OOMatrix OOMatrixForQuaternionRotation(Quaternion orientation)
Definition OOMatrix.m:65
void OOGLPushModelView(void)
void OOGLMultModelView(OOMatrix matrix)
OOMatrix OOGLPopModelView(void)
void OOGLWireframeModeOn(void)
Definition OOOpenGL.m:87
void OOGLWireframeModeOff(void)
Definition OOOpenGL.m:103
return self
unsigned count
static const double kMesosphere
return nil
Vector vector_up_from_quaternion(Quaternion quat)
Vector vector_forward_from_quaternion(Quaternion quat)
void quaternion_set_random(Quaternion *quat)
const Quaternion kIdentityQuaternion
void quaternion_rotate_about_axis(Quaternion *quat, Vector axis, OOScalar angle)
#define PLANET_MINIATURE_FACTOR
#define ATMOSPHERE_DEPTH
OOStellarBodyType
@ STELLAR_TYPE_MOON
@ STELLAR_TYPE_MINIATURE
@ STELLAR_TYPE_NORMAL_PLANET
Random_Seed RandomSeedFromString(NSString *abcdefString)
BOOL ScanVectorFromString(NSString *xyzString, Vector *outVector)
OOGraphicsDetail
Definition OOTypes.h:243
@ DETAIL_LEVEL_SHADERS
Definition OOTypes.h:246
NSUInteger OOTechLevelID
Definition OOTypes.h:204
int16_t OOSystemID
Definition OOTypes.h:211
double OOTimeDelta
Definition OOTypes.h:224
const Vector kBasisYVector
Definition OOVector.m:30
#define PLAYER
#define UNIVERSE
Definition Universe.h:842
GLfloat collision_radius
Definition Entity.h:111
Quaternion orientation
Definition Entity.h:114
void setOrientation:(Quaternion quat)
Definition Entity.m:726
unsigned isShip
Definition Entity.h:91
void setScanClass:(OOScanClass sClass)
Definition Entity.m:800
id init()
Definition Entity.m:68
void setStatus:(OOEntityStatus stat)
Definition Entity.m:788
void setPosition:(HPVector posn)
Definition Entity.m:648
OOColor * colorWithRed:green:blue:alpha:(float red,[green] float green,[blue] float blue,[alpha] float alpha)
Definition OOColor.m:95
float blueComponent()
Definition OOColor.m:362
OOColor * colorWithDescription:(id description)
Definition OOColor.m:127
OOColor * colorWithHue:saturation:brightness:alpha:(float hue,[saturation] float saturation,[brightness] float brightness,[alpha] float alpha)
Definition OOColor.m:87
float redComponent()
Definition OOColor.m:350
OOHSBAComponents hsbaComponents()
Definition OOColor.m:474
OOColor * blendedColorWithFraction:ofColor:(float fraction,[ofColor] OOColor *color)
Definition OOColor.m:328
float greenComponent()
Definition OOColor.m:356
void registerClient:(id< OOGraphicsResetClient > client)
void unregisterClient:(id< OOGraphicsResetClient > client)
OOGraphicsResetManager * sharedManager()
void setRadius:(float radius)
instancetype atmosphereWithRadius:(float radius)
NSDictionary * _materialParameters
Quaternion _atmosphereOrientation
void setUpLandParametersWithSourceInfo:targetInfo:(NSDictionary *sourceInfo, [targetInfo] NSMutableDictionary *targetInfo)
static Vector HSBColorWithColor(OOColor *color)
static Vector LighterHSBColor(Vector c)
Vector _terminatorThresholdVector
void setUpTerrainParametersWithSourceInfo:targetInfo:(NSDictionary *sourceInfo, [targetInfo] NSMutableDictionary *targetInfo)
void setUpAtmosphereParametersWithSourceInfo:targetInfo:(NSDictionary *sourceInfo, [targetInfo] NSMutableDictionary *targetInfo)
id initFromDictionary:withAtmosphere:andSeed:forSystem:(NSDictionary *dict,[withAtmosphere] BOOL atmosphere,[andSeed] Random_Seed seed,[forSystem] OOSystemID systemID)
void setUpTypeParametersWithSourceInfo:targetInfo:(NSDictionary *sourceInfo, [targetInfo] NSMutableDictionary *targetInfo)
OOPlanetDrawable * _planetDrawable
BOOL setUpPlanetFromTexture:(NSString *fileName)
void setName:(NSString *name)
BOOL generateAtmosphereTexture:withInfo:(OOTexture **texture,[withInfo] NSDictionary *planetInfo)
void ensureFinishedLoading()
Definition OOTexture.m:289
id textureWithConfiguration:(id configuration)
Definition OOTexture.m:192
NSDictionary * materialDefaults()
void setCargoFlag:(OOCargoFlag flag)
void setSingleCrewWithRole:(NSString *crewRole)
void switchAITo:(NSString *aiString)
RANROTSeed RANROTGetFullSeed(void)
void setRandomSeed(RNG_Seed a_seed)
RNG_Seed currentRandomSeed(void)
void RANROTSetFullSeed(RANROTSeed seed)
int gen_rnd_number(void)
void seed_for_planet_description(Random_Seed s_seed)
OOINLINE int is_nil_seed(Random_Seed a_seed) INLINE_CONST_FUNC