1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3
4 #include "SmokeProjectile2.h"
5
6 #include "Game/Camera.h"
7 #include "Game/GlobalUnsynced.h"
8 #include "Map/Ground.h"
9 #include "Rendering/GlobalRendering.h"
10 #include "Rendering/ProjectileDrawer.h"
11 #include "Rendering/GL/VertexArray.h"
12 #include "Rendering/Textures/TextureAtlas.h"
13 #include "Sim/Misc/Wind.h"
14
15 CR_BIND_DERIVED(CSmokeProjectile2, CProjectile, )
16
17 CR_REG_METADATA(CSmokeProjectile2,
18 (
19 CR_MEMBER_BEGINFLAG(CM_Config),
20 CR_MEMBER(color),
21 CR_MEMBER(ageSpeed),
22 CR_MEMBER(size),
23 CR_MEMBER(startSize),
24 CR_MEMBER(sizeExpansion),
25 CR_MEMBER(wantedPos),
26 CR_MEMBER(glowFalloff),
27 CR_MEMBER_ENDFLAG(CM_Config),
28 CR_MEMBER(age),
29 CR_MEMBER(textureNum),
30 CR_RESERVED(8)
31 ))
32
33 //////////////////////////////////////////////////////////////////////
34 // Construction/Destruction
35 //////////////////////////////////////////////////////////////////////
36
CSmokeProjectile2()37 CSmokeProjectile2::CSmokeProjectile2():
38 CProjectile(),
39 color(0.5f),
40 age(0.0f),
41 ageSpeed(1.0f),
42 size(0.0f),
43 startSize(0.0f),
44 sizeExpansion(0.0f),
45 textureNum(0),
46 glowFalloff(0.0f)
47 {
48 deleteMe = false;
49 checkCol = false;
50 }
51
CSmokeProjectile2(CUnit * owner,const float3 & pos,const float3 & wantedPos,const float3 & speed,float ttl,float startSize,float sizeExpansion,float color)52 CSmokeProjectile2::CSmokeProjectile2(
53 CUnit* owner,
54 const float3& pos,
55 const float3& wantedPos,
56 const float3& speed,
57 float ttl,
58 float startSize,
59 float sizeExpansion,
60 float color)
61 : CProjectile(pos, speed, owner, false, false, false),
62 color(color),
63 age(0),
64 size(0),
65 startSize(startSize),
66 sizeExpansion(sizeExpansion),
67 wantedPos(wantedPos)
68 {
69 ageSpeed = 1 / ttl;
70 checkCol = false;
71 castShadow = true;
72 if ((pos.y - CGround::GetApproximateHeight(pos.x, pos.z, false)) > 10) {
73 useAirLos = true;
74 }
75 glowFalloff = 4.5f + gu->RandFloat() * 6;
76 textureNum = (int)(gu->RandInt() % projectileDrawer->smoketex.size());
77 }
78
79
80
Init(const CUnit * owner,const float3 & offset)81 void CSmokeProjectile2::Init(const CUnit* owner, const float3& offset)
82 {
83 textureNum = (int) (gu->RandInt() % projectileDrawer->smoketex.size());
84
85 if (offset.y - CGround::GetApproximateHeight(offset.x, offset.z, false) > 10) {
86 useAirLos = true;
87 }
88
89 if (!owner) {
90 alwaysVisible = true;
91 }
92
93 wantedPos += offset;
94
95 CProjectile::Init(owner, offset);
96 }
97
Update()98 void CSmokeProjectile2::Update()
99 {
100 wantedPos += speed;
101 wantedPos += wind.GetCurrentWind() * age * 0.05f;
102
103 pos.x += (wantedPos.x - pos.x) * 0.07f;
104 pos.y += (wantedPos.y - pos.y) * 0.02f;
105 pos.z += (wantedPos.z - pos.z) * 0.07f;
106 age += ageSpeed;
107 size += sizeExpansion;
108 if (size < startSize) {
109 size += (startSize - size) * 0.2f;
110 }
111 SetRadiusAndHeight(size, 0.0f);
112 if (age > 1) {
113 age = 1;
114 deleteMe = true;
115 }
116 }
117
Draw()118 void CSmokeProjectile2::Draw()
119 {
120 inArray = true;
121 const float interAge = std::min(1.0f, age + ageSpeed * globalRendering->timeOffset);
122 unsigned char col[4];
123 unsigned char alpha;
124 if (interAge < 0.05f) {
125 alpha = (unsigned char) (interAge * 19 * 127);
126 } else {
127 alpha = (unsigned char) ((1 - interAge) * 127);
128 }
129 const float rglow = std::max(0.f, (1 - (interAge * glowFalloff)) * 127);
130 const float gglow = std::max(0.f, (1 - (interAge * glowFalloff * 2.5f)) * 127);
131 col[0] = (unsigned char) (color * alpha + rglow);
132 col[1] = (unsigned char) (color * alpha + gglow);
133 col[2] = (unsigned char) std::max(0.f, color * alpha - gglow * 0.5f);
134 col[3] = alpha/*-alphaFalloff*globalRendering->timeOffset*/;
135
136 const float3 interPos = pos + (wantedPos + speed * globalRendering->timeOffset - pos) * 0.1f * globalRendering->timeOffset;
137 const float interSize = size + sizeExpansion * globalRendering->timeOffset;
138 const float3 pos1 ((camera->right - camera->up) * interSize);
139 const float3 pos2 ((camera->right + camera->up) * interSize);
140
141 #define st projectileDrawer->smoketex[textureNum]
142 va->AddVertexTC(interPos - pos2, st->xstart, st->ystart, col);
143 va->AddVertexTC(interPos + pos1, st->xend, st->ystart, col);
144 va->AddVertexTC(interPos + pos2, st->xend, st->yend, col);
145 va->AddVertexTC(interPos - pos1, st->xstart, st->yend, col);
146 #undef st
147 }
148