1 /* 2 Copyright (c) 2013 yvt 3 4 This file is part of OpenSpades. 5 6 OpenSpades is free software: you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation, either version 3 of the License, or 9 (at your option) any later version. 10 11 OpenSpades is distributed in the hope that it will be useful, 12 but WITHOUT ANY WARRANTY; without even the implied warranty of 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 GNU General Public License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with OpenSpades. If not, see <http://www.gnu.org/licenses/>. 18 19 */ 20 21 #include "ParticleSpriteEntity.h" 22 #include <Core/Debug.h> 23 #include "GameMap.h" 24 #include "World.h" 25 26 namespace spades { 27 namespace client { ParticleSpriteEntity(Client * cli,IImage * image,Vector4 color)28 ParticleSpriteEntity::ParticleSpriteEntity(Client *cli, IImage *image, Vector4 color) 29 : image(image), color(color) { 30 position = MakeVector3(0, 0, 0); 31 velocity = MakeVector3(0, 0, 0); 32 radius = 1.f; 33 radiusVelocity = 0.f; 34 angle = 0.f; 35 rotationVelocity = 0.f; 36 velocityDamp = 1; 37 gravityScale = 1.f; 38 lifetime = 1.f; 39 radiusDamp = 1.f; 40 time = 0.f; 41 fadeInDuration = .1f; 42 fadeOutDuration = .5f; 43 additive = false; 44 blockHitAction = Delete; 45 46 if (image != NULL) 47 image->AddRef(); 48 49 renderer = cli->GetRenderer(); 50 if (cli->GetWorld()) 51 map = cli->GetWorld()->GetMap(); 52 else 53 map = NULL; 54 } 55 ~ParticleSpriteEntity()56 ParticleSpriteEntity::~ParticleSpriteEntity() { 57 if (image != NULL) { 58 image->Release(); 59 } 60 } 61 SetLifeTime(float lifeTime,float fadeIn,float fadeOut)62 void ParticleSpriteEntity::SetLifeTime(float lifeTime, float fadeIn, float fadeOut) { 63 lifetime = lifeTime; 64 fadeInDuration = fadeIn; 65 fadeOutDuration = fadeOut; 66 } SetTrajectory(Vector3 pos,Vector3 vel,float damp,float grav)67 void ParticleSpriteEntity::SetTrajectory(Vector3 pos, Vector3 vel, float damp, float grav) { 68 position = pos; 69 velocity = vel; 70 velocityDamp = damp; 71 gravityScale = grav; 72 } 73 SetRotation(float initialAngle,float angleVelocity)74 void ParticleSpriteEntity::SetRotation(float initialAngle, float angleVelocity) { 75 angle = initialAngle; 76 rotationVelocity = angleVelocity; 77 } 78 SetRadius(float initialRadius,float radiusVelocity,float damp)79 void ParticleSpriteEntity::SetRadius(float initialRadius, float radiusVelocity, 80 float damp) { 81 radius = initialRadius; 82 this->radiusVelocity = radiusVelocity; 83 radiusDamp = damp; 84 } 85 Update(float dt)86 bool ParticleSpriteEntity::Update(float dt) { 87 SPADES_MARK_FUNCTION_DEBUG(); 88 Vector3 lastPos = position; 89 90 time += dt; 91 if (time > lifetime) 92 return false; 93 94 position += velocity * dt; 95 velocity.z += 32.f * dt * gravityScale; 96 97 // TODO: control clip action 98 if (blockHitAction != Ignore && map) { 99 if (map->ClipWorld(position.x, position.y, position.z)) { 100 if (blockHitAction == Delete) { 101 return false; 102 } else { 103 IntVector3 lp2 = lastPos.Floor(); 104 IntVector3 lp = position.Floor(); 105 if (lp.z != lp2.z && ((lp.x == lp2.x && lp.y == lp2.y) || 106 !map->ClipWorld(lp.x, lp.y, lp2.z))) 107 velocity.z = -velocity.z; 108 else if (lp.x != lp2.x && ((lp.y == lp2.y && lp.z == lp2.z) || 109 !map->ClipWorld(lp2.x, lp.y, lp.z))) 110 velocity.x = -velocity.x; 111 else if (lp.y != lp2.y && ((lp.x == lp2.x && lp.z == lp2.z) || 112 !map->ClipWorld(lp.x, lp2.y, lp.z))) 113 velocity.y = -velocity.y; 114 velocity *= .36f; 115 position = lastPos; 116 } 117 } 118 } 119 120 // radius 121 if (radiusVelocity != 0.f) 122 radius += radiusVelocity * dt; 123 124 if (rotationVelocity != 0.f) 125 angle += rotationVelocity * dt; 126 127 if (velocityDamp != 1.f) 128 velocity *= powf(velocityDamp, dt); 129 130 if (radiusDamp != 1.f) 131 radiusVelocity *= powf(radiusDamp, dt); 132 133 return true; 134 } 135 Render3D()136 void ParticleSpriteEntity::Render3D() { 137 SPADES_MARK_FUNCTION_DEBUG(); 138 139 float fade = 1.f; 140 if (time < fadeInDuration) { 141 fade *= time / fadeInDuration; 142 } 143 if (time > lifetime - fadeOutDuration) { 144 fade *= (lifetime - time) / fadeOutDuration; 145 } 146 147 Vector4 col = color; 148 col.w *= fade; 149 150 // premultiplied alpha! 151 col.x *= col.w; 152 col.y *= col.w; 153 col.z *= col.w; 154 155 if (additive) 156 col.w = 0.f; 157 158 renderer->SetColorAlphaPremultiplied(col); 159 renderer->AddSprite(image, position, radius, angle); 160 } SetImage(IImage * img)161 void ParticleSpriteEntity::SetImage(IImage *img) { 162 if (img == image) 163 return; 164 if (image != NULL) 165 image->Release(); 166 image = img; 167 if (image != NULL) 168 image->AddRef(); 169 } 170 } 171 } 172