31#import "MyOpenGLView.h"
41@interface OOSunEntity (Private)
43- (void) calculateGLArrays:(GLfloat)inner_radius width:(GLfloat)width zDistance:(GLfloat)z_distance;
61- (BOOL) setSunColor:(
OOColor*)sun_color
63 if (sun_color ==
nil)
return NO;
67 float hue, sat, bri, alf;
84 float hue_drift = 0.0038f * fabsf(
randf() -
randf());
90 GLfloat sun_ambient[] = { 0.0, 0.0, 0.0, 1.0};
91 sun_diffuse[0] = 0.5f * (1.0f + r);
92 sun_diffuse[1] = 0.5f * (1.0f + g);
93 sun_diffuse[2] = 0.5f * (1.0f + b);
98 sun_specular[3] = 1.0;
100 OOGL(glLightfv(GL_LIGHT1, GL_AMBIENT, sun_ambient));
101 OOGL(glLightfv(GL_LIGHT1, GL_DIFFUSE, sun_diffuse));
102 OOGL(glLightfv(GL_LIGHT1, GL_SPECULAR, sun_specular));
115 hue += hue_drift * 3;
119 [color
getRed:&outerCoronaColor[0]
green:&outerCoronaColor[1]
blue:&outerCoronaColor[2]
alpha:&outerCoronaColor[3]];
125- (id) initSunWithColor:(
OOColor *)sun_color andDictionary:(NSDictionary *) dict
131 collision_radius = 100000.0;
133 scanClass = CLASS_NO_DRAW;
135 _sunBrightnessFactor = [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"sbf" defaultValue:80.0f];
136 _sunCoronaAlphaFactor = [[NSUserDefaults standardUserDefaults] oo_floatForKey:@"scaf" defaultValue:0.005f];
138 [
self setSunColor:sun_color];
140 [
self setName:OOExpand([dict oo_stringForKey:KEY_SUNNAME defaultValue:@"[oolite-default-star-name]"])];
142 corona_blending=OOClamp_0_1_f([dict oo_floatForKey:
@"corona_hues" defaultValue:1.0f]);
143 corona_speed_factor=[dict oo_floatForKey:@"corona_shimmer" defaultValue:-1.0];
144 if(corona_speed_factor<0)
147 corona_speed_factor = 1.0 / (0.5 + 2.0 * (
randf() +
randf()));
152 corona_speed_factor=OOClamp_0_1_f(corona_speed_factor) * 2.0 +
randf() *
randf();
154#ifdef OO_DUMP_PLANETINFO
155 OOLog(
@"planetinfo.record",
@"corona_shimmer = %f",corona_speed_factor);
163 [
self changeSunProperty:@"sun_radius" withDictionary:dict];
166 for (
unsigned i=0 ; i < 360 ; i++)
168 unsigned j = (i+1)%360;
170 sunTriangles[k++] = 0;
171 sunTriangles[k++] = 1+i;
172 sunTriangles[k++] = 1+j;
174 for (
unsigned i=0 ; i < 360 ; i++)
176 unsigned j = (i+1)%360;
178 sunTriangles[k++] = 1+i;
179 sunTriangles[k++] = 1+j;
180 sunTriangles[k++] = 361+i;
181 sunTriangles[k++] = 1+j;
182 sunTriangles[k++] = 361+i;
183 sunTriangles[k++] = 361+j;
185 sunTriangles[k++] = 361+i;
186 sunTriangles[k++] = 361+j;
187 sunTriangles[k++] = 721+i;
188 sunTriangles[k++] = 361+j;
189 sunTriangles[k++] = 721+i;
190 sunTriangles[k++] = 721+j;
192 sunTriangles[k++] = 721+i;
193 sunTriangles[k++] = 721+j;
194 sunTriangles[k++] = 1081+i;
195 sunTriangles[k++] = 721+j;
196 sunTriangles[k++] = 1081+i;
197 sunTriangles[k++] = 1081+j;
199 sunTriangles[k++] = 1081+i;
200 sunTriangles[k++] = 1081+j;
201 sunTriangles[k++] = 1441+i;
202 sunTriangles[k++] = 1081+j;
203 sunTriangles[k++] = 1441+i;
204 sunTriangles[k++] = 1441+j;
218- (NSString*) descriptionComponents
220 NSString *result = [NSString stringWithFormat:@"ID: %u position: %@ radius: %.3fkm", [
self universalID], HPVectorDescription([
self position]), 0.001 * [
self radius]];
223 result = [result stringByAppendingString:@" (gone nova)"];
225 else if ([
self willGoNova])
227 result = [result stringByAppendingString:@" (will go nova)"];
241- (BOOL) checkCloseCollisionWith:(
Entity *)other
245 OOLog(
@"sun.collide",
@"%@",
@"SUN Collision!");
248 return [
super checkCloseCollisionWith:other];
255 [
super update:delta_t];
258 assert(player !=
nil);
261 if (throw_sparks && _novaExpansionRate > 0.0f)
263 if (_novaCountdown >= 0.0)
265 _novaCountdown -= delta_t;
266 if (corona_speed_factor < 5.0)
268 corona_speed_factor += 0.75 * delta_t;
273 if (_novaExpansionTimer <= 60.0)
275 double sky_bri = 1.0 - 1.5 * _novaExpansionTimer;
278 [UNIVERSE setSkyColorRed:0.0f
285 [UNIVERSE setSkyColorRed:sky_bri
293 [UNIVERSE setSystemDataKey:@"sun_gone_nova" value:[NSNumber numberWithBool:YES] fromManifest:@"org.oolite.oolite"];
294 [UNIVERSE setSystemDataKey:@"corona_flare" value:[NSNumber numberWithFloat:0.3] fromManifest:@"org.oolite.oolite"];
295 [UNIVERSE setSystemDataKey:@"corona_hues" value:[NSNumber numberWithFloat:0.05] fromManifest:@"org.oolite.oolite"];
299 OOLog(
@"sun.nova.start",
@"DEBUG: NOVA original radius %.1f", collision_radius);
301 discColor[0] = 1.0 * _sunBrightnessFactor; discColor[1] = 1.0 * _sunBrightnessFactor; discColor[2] = 1.0 * _sunBrightnessFactor;
302 _novaExpansionTimer += delta_t;
303 [UNIVERSE setSystemDataKey:@"sun_radius" value:[NSNumber numberWithFloat:collision_radius + delta_t * _novaExpansionRate] fromManifest:@"org.oolite.oolite"];
307 OOLog(
@"sun.nova.end",
@"DEBUG: NOVA final radius %.1f", collision_radius);
319 corona_stage += corona_speed_factor * delta_t;
320 while (corona_stage > 1.0)
324 for (i = 0; i < 360; i++)
326 rvalue[i] = rvalue[360 + i];
327 rvalue[360 + i] =
randf();
336- (void) drawImmediate:(
bool)immediate translucent:(
bool)translucent
346 [
self drawOpaqueParts];
355 [
self drawTranslucentParts];
361- (void) updateCameraRelativePosition
363 HPVector cr_temp = HPvector_subtract([
self absolutePositionForSubentity],[
PLAYER viewpointPosition]);
369 cr_temp = HPvector_multiply_scalar(cr_temp,1E9/HPmagnitude(cr_temp));
371 cameraRelativePosition = HPVectorToVector(cr_temp);
377 float sqrt_zero_distance = sqrt(cam_zero_distance);
378 float effective_radius = collision_radius;
379 float effective_cor16k = cor16k;
385 float large_distance_compensator = sqrt_zero_distance / 1000000000.0f;
386 if (large_distance_compensator > 1.0f)
388 sqrt_zero_distance /= large_distance_compensator;
389 effective_radius /= large_distance_compensator;
390 effective_cor16k /= large_distance_compensator;
399 int subdivideLevel = 2;
400 float drawFactor = [[UNIVERSE gameView] viewSize].width / 100.0;
401 float drawRatio2 = drawFactor * effective_radius / sqrt_zero_distance;
403 if (cam_zero_distance > 0.0f)
405 subdivideLevel = 2 + floorf(drawRatio2);
406 if (subdivideLevel > 4)
419 BOOL ignoreDepthBuffer = cam_zero_distance > effective_radius * effective_radius * 25;
424 if (ignoreDepthBuffer)
OOGL(glDisable(GL_DEPTH_TEST));
426 OOGL(glColor3fv(discColor));
428 OOGL(glDisable(GL_BLEND));
432 OOGL(glEnable(GL_BLEND));
434 if (ignoreDepthBuffer)
OOGL(glEnable(GL_DEPTH_TEST));
439 [
self calculateGLArrays:effective_radius
440 width:effective_cor16k
441 zDistance:sqrt_zero_distance];
442 OOGL(glDisable(GL_BLEND));
443 OOGL(glVertexPointer(3, GL_FLOAT, 0, sunVertices));
445 OOGL(glEnableClientState(GL_COLOR_ARRAY));
446 OOGL(glColorPointer(4, GL_FLOAT, 0, sunColors));
448 OOGL(glDrawElements(GL_TRIANGLES, 3*360, GL_UNSIGNED_INT, sunTriangles));
450 OOGL(glDisableClientState(GL_COLOR_ARRAY));
451 OOGL(glEnable(GL_BLEND));
472 OOGL(glVertexPointer(3, GL_FLOAT, 0, sunVertices));
474 OOGL(glEnableClientState(GL_COLOR_ARRAY));
475 OOGL(glColorPointer(4, GL_FLOAT, 0, sunColors));
476 OOGL(glDrawElements(GL_TRIANGLES, 24*360, GL_UNSIGNED_INT, sunTriangles+(3*360)));
478 OOGL(glDisableClientState(GL_COLOR_ARRAY));
483- (void) calculateGLArrays:(GLfloat)inner_radius width:(GLfloat)width zDistance:(GLfloat)z_distance
487 GLfloat activity[8] = {0.84, 0.74, 0.64, 0.54,
488 0.3 , 0.4 , 0.7 , 0.8};
491 GLfloat rv0, rv1, rv2, c0, c1, c2;
494 unsigned short i, j, k;
495 GLfloat theta = 0.0f, delta;
496 delta =
M_PI / 180.0f;
497 pt0=(1.0 - corona_stage) * corona_blending;
498 pt1=corona_stage * corona_blending;
500 sunVertices[0] = 0.0;
501 sunVertices[1] = 0.0;
502 sunVertices[2] = 0.0;
504 for (j = 0 ; j <= 4 ; j++)
506 GLfloat r = inner_radius;
522 for (i = 0 ; i < 360 ; i++)
527 rm = 1.0 + ((0.04/j)*(pt0 * (rvalue[i]+rvalue[i+1]+rvalue[i+2]) + pt1 * (rvalue[i+360]+rvalue[i+361]+rvalue[i+362])))/3;
529 GLfloat z = r * r * rm * rm / z_distance;
533 sunVertices[k++] = si * r * rm;
534 sunVertices[k++] = ci * r * rm;
535 sunVertices[k++] = -z;
539 GLfloat blackColor[4] = {0.0,0.0,0.0,0.0};
540 GLfloat *color = blackColor;
544 sunColors[k++] = discColor[0];
545 sunColors[k++] = discColor[1];
546 sunColors[k++] = discColor[2];
547 sunColors[k++] = discColor[3] * _sunCoronaAlphaFactor;
549 for (j = 0 ; j <= 4 ; j++)
557 color = outerCoronaColor;
561 color = outerCoronaColor;
573 for (i = 0 ; i < 360 ; i++)
577 sunColors[k++] = color[0];
578 sunColors[k++] = color[1];
579 sunColors[k++] = color[2];
580 sunColors[k++] = alpha * _sunCoronaAlphaFactor;
584 rv0 = pt0 * rvalue[i] + pt1 * rvalue[i + 360];
585 rv1 = pt0 * rvalue[i + 1] + pt1 * rvalue[i + 361];
586 rv2 = pt0 * rvalue[i + 2] + pt1 * rvalue[i + 362];
587 c0 = color[0] * (activity[j-1] + rv0*activity[j+3]);
588 c1 = color[1] * (activity[j-1] + rv1*activity[j+3]);
589 c2 = color[2] * (activity[j-1] + rv2*activity[j+3]);
590 if (c1 > c2 && c1 > c0)
598 sunColors[k++] = alpha * _sunCoronaAlphaFactor;