New explosion effect

This commit is contained in:
cim 2013-09-22 19:55:42 +01:00
parent 94178d5bbd
commit fb5734dba5
10 changed files with 248 additions and 6 deletions

View File

@ -182,6 +182,7 @@ OOLITE_ENTITY_FILES = \
OOPlasmaShotEntity.m \ OOPlasmaShotEntity.m \
OOPlasmaBurstEntity.m \ OOPlasmaBurstEntity.m \
OOFlashEffectEntity.m \ OOFlashEffectEntity.m \
OOExplosionCloudEntity.m \
ShipEntityLoadRestore.m \ ShipEntityLoadRestore.m \
OOLaserShotEntity.m \ OOLaserShotEntity.m \
OOQuiriumCascadeEntity.m \ OOQuiriumCascadeEntity.m \

@ -1 +1 @@
Subproject commit ae4c4709ceef2c3b0745e262e2ce5c2ff4e26588 Subproject commit 3fd82bb81e830e9c9a553ef6142278f042d671d2

View File

@ -0,0 +1,41 @@
/*
OOExplosionCloudEntity.h
Cloud effect during explosions
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOParticleSystem.h"
@interface OOExplosionCloudEntity: OOParticleSystem
{
@private
float _growthRate;
}
+ (instancetype) explosionCloudFromEntity:(Entity *)entity;
+ (void) setUpTexture;
@end

View File

@ -0,0 +1,172 @@
/*
OOExplosionCloudEntity.m
Oolite
Copyright (C) 2004-2013 Giles C Williams and contributors
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
MA 02110-1301, USA.
*/
#import "OOExplosionCloudEntity.h"
#import "Universe.h"
#import "PlayerEntity.h"
#import "OOColor.h"
#import "OOTexture.h"
#import "OOGraphicsResetManager.h"
#define kExplosionCloudDuration 0.9f
#define kGrowthRateFactor 1.5f
#define kExplosionCloudAlpha 0.85f
static OOTexture *sCloudTexture1 = nil;
static OOTexture *sCloudTexture2 = nil;
@interface OOExplosionCloudEntity (Private)
+ (void) resetGraphicsState;
@end
@implementation OOExplosionCloudEntity
- (id) initExplosionCloudWithPosition:(HPVector)pos velocity:(Vector)vel size:(float)size
{
unsigned i;
unsigned count = 25;
GLfloat baseColor[4] = {1.0,1.0,1.0,1.0};
_growthRate = kGrowthRateFactor * size;
if ((self = [super initWithPosition:pos velocity:vel count:count minSpeed:size*0.8 maxSpeed:size*1.2 duration:kExplosionCloudDuration baseColor:baseColor]))
{
for (i=0;i<count;i++)
{
float r,g,b;
r = randf();
g = randf();
if (g > r) {
r = 1.0f;
}
b = randf();
if (b > g) {
b = g;
}
_particleColor[i][0] = r;
_particleColor[i][1] = g;
_particleColor[i][2] = b;
_particleColor[i][3] = kExplosionCloudAlpha;
}
}
return self;
}
+ (instancetype) explosionCloudFromEntity:(Entity *)entity
{
return [[[self alloc] initExplosionCloudWithPosition:[entity position] velocity:[entity velocity] size:[entity collisionRadius]*2.5] autorelease];
}
- (void) update:(OOTimeDelta)delta_t
{
[super update:delta_t];
// Fade out.
unsigned i, count = _count;
GLfloat (*particleColor)[4] = _particleColor;
float newAlpha = kExplosionCloudAlpha * (1-(_timePassed / kExplosionCloudDuration));
for (i=0;i<count;i++) {
_particleSize[i] += delta_t * _growthRate;
particleColor[i][3] = newAlpha;
if (particleColor[i][2] > 0.0)
{
particleColor[i][2] -= delta_t;
if (particleColor[i][2] < 0.0)
{
particleColor[i][2] = 0.0f;
}
}
else if (particleColor[i][1] > 0.0)
{
particleColor[i][1] -= delta_t;
if (particleColor[i][1] < 0.0)
{
particleColor[i][1] = 0.0f;
}
}
else if (particleColor[i][0] > 0.0)
{
particleColor[i][0] -= delta_t;
if (particleColor[i][0] < 0.0)
{
particleColor[i][0] = 0.0f;
}
}
}
}
- (OOTexture *) texture:(NSUInteger)idx
{
if (sCloudTexture1 == nil) [OOExplosionCloudEntity setUpTexture];
if (idx < _count/5)
{
return sCloudTexture1;
}
else
{
return sCloudTexture2;
}
}
+ (void) setUpTexture
{
if (sCloudTexture1 == nil)
{
sCloudTexture1 = [[OOTexture textureWithName:@"oolite-particle-cloud.png"
inFolder:@"Textures"
options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
anisotropy:kOOTextureDefaultAnisotropy
lodBias:0.0] retain];
sCloudTexture2 = [[OOTexture textureWithName:@"oolite-particle-cloud2.png"
inFolder:@"Textures"
options:kOOTextureMinFilterMipMap | kOOTextureMagFilterLinear | kOOTextureAlphaMask
anisotropy:kOOTextureDefaultAnisotropy
lodBias:0.0] retain];
[[OOGraphicsResetManager sharedManager] registerClient:(id<OOGraphicsResetClient>)[OOExplosionCloudEntity class]];
}
}
+ (void) resetGraphicsState
{
[sCloudTexture1 release];
sCloudTexture1 = nil;
[sCloudTexture2 release];
sCloudTexture2 = nil;
}
@end

View File

@ -33,6 +33,7 @@ MA 02110-1301, USA.
@private @private
float _duration; float _duration;
float _growthRate; float _growthRate;
float _alpha;
} }
+ (instancetype) explosionFlashFromEntity:(Entity *)entity; + (instancetype) explosionFlashFromEntity:(Entity *)entity;

View File

@ -36,7 +36,7 @@ MA 02110-1301, USA.
#define kGrowthRateFactor 150.0f // if average flashSize is 80 then this is 12000 #define kGrowthRateFactor 150.0f // if average flashSize is 80 then this is 12000
#define kMinExplosionGrowth 600.0f #define kMinExplosionGrowth 600.0f
#define kLaserFlashInitialSize 1.0f #define kLaserFlashInitialSize 1.0f
#define kExplosionFlashAlpha 0.5f
static OOTexture *sFlashTexture = nil; static OOTexture *sFlashTexture = nil;
@ -60,6 +60,7 @@ static OOTexture *sFlashTexture = nil;
if ((self = [self initWithPosition:pos size:size color:[OOColor whiteColor] duration:kExplosionFlashDuration])) if ((self = [self initWithPosition:pos size:size color:[OOColor whiteColor] duration:kExplosionFlashDuration]))
{ {
_growthRate = fmax(_growthRate, kMinExplosionGrowth); _growthRate = fmax(_growthRate, kMinExplosionGrowth);
_alpha = kExplosionFlashAlpha;
[self setVelocity:vel]; [self setVelocity:vel];
} }
return self; return self;
@ -71,6 +72,7 @@ static OOTexture *sFlashTexture = nil;
if ((self = [self initWithPosition:pos size:kLaserFlashInitialSize color:color duration:kLaserFlashDuration])) if ((self = [self initWithPosition:pos size:kLaserFlashInitialSize color:color duration:kLaserFlashDuration]))
{ {
[self setVelocity:vel]; [self setVelocity:vel];
_alpha = 1.0f;
} }
return self; return self;
} }
@ -114,7 +116,7 @@ static OOTexture *sFlashTexture = nil;
// Fade in and out. // Fade in and out.
OOTimeDelta lifeTime = [self timeElapsedSinceSpawn]; OOTimeDelta lifeTime = [self timeElapsedSinceSpawn];
_colorComponents[3] = (lifeTime < tf) ? (lifeTime / tf) : (_duration - lifeTime) / tf1; _colorComponents[3] = _alpha * ((lifeTime < tf) ? (lifeTime / tf) : (_duration - lifeTime) / tf1);
// Disappear as necessary. // Disappear as necessary.
if (lifeTime > _duration) [UNIVERSE removeEntity:self]; if (lifeTime > _duration) [UNIVERSE removeEntity:self];

View File

@ -64,6 +64,8 @@ enum
duration:(OOTimeDelta)duration duration:(OOTimeDelta)duration
baseColor:(GLfloat[4])baseColor; baseColor:(GLfloat[4])baseColor;
- (OOTexture *) texture:(NSUInteger)idx;
@end @end

View File

@ -141,6 +141,9 @@ do { \
- (void) drawImmediate:(bool)immediate translucent:(bool)translucent - (void) drawImmediate:(bool)immediate translucent:(bool)translucent
{ {
if (!translucent || [UNIVERSE breakPatternHide]) return; if (!translucent || [UNIVERSE breakPatternHide]) return;
OOTexture *tex = nil;
OOTexture *lastTex = nil;
OO_ENTER_OPENGL(); OO_ENTER_OPENGL();
OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING); OOSetOpenGLState(OPENGL_STATE_ADDITIVE_BLENDING);
@ -148,7 +151,6 @@ do { \
OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT)); OOGL(glPushAttrib(GL_ENABLE_BIT | GL_COLOR_BUFFER_BIT));
OOGL(glEnable(GL_TEXTURE_2D)); OOGL(glEnable(GL_TEXTURE_2D));
[[OOLightParticleEntity defaultParticleTexture] apply];
OOGL(glEnable(GL_BLEND)); OOGL(glEnable(GL_BLEND));
OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE)); OOGL(glBlendFunc(GL_SRC_ALPHA, GL_ONE));
@ -169,6 +171,12 @@ do { \
OOGLBEGIN(GL_QUADS); OOGLBEGIN(GL_QUADS);
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
OOTexture *tex = [self texture:i];
if (tex != lastTex)
{
lastTex = tex;
[tex apply];
}
glColor4fv(particleColor[i]); glColor4fv(particleColor[i]);
DrawQuadForView(particlePosition[i].x, particlePosition[i].y, particlePosition[i].z, particleSize[i]); DrawQuadForView(particlePosition[i].x, particlePosition[i].y, particlePosition[i].z, particleSize[i]);
} }
@ -192,6 +200,13 @@ do { \
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
OOTexture *tex = [self texture:i];
if (tex != lastTex)
{
lastTex = tex;
[tex apply];
}
OOGL(glPushMatrix()); OOGL(glPushMatrix());
GLTranslateOOVector(particlePosition[i]); GLTranslateOOVector(particlePosition[i]);
GLMultOOMatrix(bbMatrix); GLMultOOMatrix(bbMatrix);
@ -242,6 +257,10 @@ do { \
return YES; return YES;
} }
- (OOTexture *) texture:(NSUInteger)idx
{
return [OOLightParticleEntity defaultParticleTexture];
}
#ifndef NDEBUG #ifndef NDEBUG
- (NSSet *) allTextures - (NSSet *) allTextures

View File

@ -70,6 +70,7 @@ MA 02110-1301, USA.
#import "OOECMBlastEntity.h" #import "OOECMBlastEntity.h"
#import "OOPlasmaShotEntity.h" #import "OOPlasmaShotEntity.h"
#import "OOFlashEffectEntity.h" #import "OOFlashEffectEntity.h"
#import "OOExplosionCloudEntity.h"
#import "ProxyPlayerEntity.h" #import "ProxyPlayerEntity.h"
#import "OOLaserShotEntity.h" #import "OOLaserShotEntity.h"
#import "OOQuiriumCascadeEntity.h" #import "OOQuiriumCascadeEntity.h"
@ -7888,9 +7889,10 @@ NSComparisonResult ComparePlanetsBySurfaceDistance(id i1, id i2, void* context)
if (add_debris) if (add_debris)
{ {
// 1. fast sparks // 1. fast sparks
[UNIVERSE addEntity:[OOSmallFragmentBurstEntity fragmentBurstFromEntity:self]]; // [UNIVERSE addEntity:[OOSmallFragmentBurstEntity fragmentBurstFromEntity:self]];
// 2. slow clouds // 2. slow clouds
[UNIVERSE addEntity:[OOBigFragmentBurstEntity fragmentBurstFromEntity:self]]; [UNIVERSE addEntity:[OOExplosionCloudEntity explosionCloudFromEntity:self]];
// [UNIVERSE addEntity:[OOBigFragmentBurstEntity fragmentBurstFromEntity:self]];
} }
// 3. flash // 3. flash
[UNIVERSE addEntity:[OOFlashEffectEntity explosionFlashFromEntity:self]]; [UNIVERSE addEntity:[OOFlashEffectEntity explosionFlashFromEntity:self]];

View File

@ -73,6 +73,7 @@ MA 02110-1301, USA.
#import "OORingEffectEntity.h" #import "OORingEffectEntity.h"
#import "OOLightParticleEntity.h" #import "OOLightParticleEntity.h"
#import "OOFlashEffectEntity.h" #import "OOFlashEffectEntity.h"
#import "OOExplosionCloudEntity.h"
#import "OOMusicController.h" #import "OOMusicController.h"
#import "OOAsyncWorkManager.h" #import "OOAsyncWorkManager.h"
@ -347,6 +348,7 @@ GLfloat docked_light_specular[4] = { DOCKED_ILLUM_LEVEL, DOCKED_ILLUM_LEVEL, DOC
// Preload particle effect textures: // Preload particle effect textures:
[OOLightParticleEntity setUpTexture]; [OOLightParticleEntity setUpTexture];
[OOFlashEffectEntity setUpTexture]; [OOFlashEffectEntity setUpTexture];
[OOExplosionCloudEntity setUpTexture];
player = [PlayerEntity sharedPlayer]; player = [PlayerEntity sharedPlayer];
[player deferredInit]; [player deferredInit];