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 \
OOPlasmaBurstEntity.m \
OOFlashEffectEntity.m \
OOExplosionCloudEntity.m \
ShipEntityLoadRestore.m \
OOLaserShotEntity.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
float _duration;
float _growthRate;
float _alpha;
}
+ (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 kMinExplosionGrowth 600.0f
#define kLaserFlashInitialSize 1.0f
#define kExplosionFlashAlpha 0.5f
static OOTexture *sFlashTexture = nil;
@ -60,6 +60,7 @@ static OOTexture *sFlashTexture = nil;
if ((self = [self initWithPosition:pos size:size color:[OOColor whiteColor] duration:kExplosionFlashDuration]))
{
_growthRate = fmax(_growthRate, kMinExplosionGrowth);
_alpha = kExplosionFlashAlpha;
[self setVelocity:vel];
}
return self;
@ -71,6 +72,7 @@ static OOTexture *sFlashTexture = nil;
if ((self = [self initWithPosition:pos size:kLaserFlashInitialSize color:color duration:kLaserFlashDuration]))
{
[self setVelocity:vel];
_alpha = 1.0f;
}
return self;
}
@ -114,7 +116,7 @@ static OOTexture *sFlashTexture = nil;
// Fade in and out.
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.
if (lifeTime > _duration) [UNIVERSE removeEntity:self];

View File

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

View File

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

View File

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

View File

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