1 /* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */
2
3
4 #include "BeamLaserProjectile.h"
5 #include "Game/Camera.h"
6 #include "Rendering/GL/VertexArray.h"
7 #include "Rendering/Textures/TextureAtlas.h"
8 #include "Sim/Projectiles/ProjectileHandler.h"
9 #include "Sim/Weapons/WeaponDef.h"
10 #include <cstring> //memset
11
12 CR_BIND_DERIVED(CBeamLaserProjectile, CWeaponProjectile, (ProjectileParams()))
13
14 CR_REG_METADATA(CBeamLaserProjectile,(
15 CR_SETFLAG(CF_Synced),
16 CR_MEMBER(coreColStart),
17 CR_MEMBER(coreColEnd),
18 CR_MEMBER(edgeColStart),
19 CR_MEMBER(edgeColEnd),
20 CR_MEMBER(thickness),
21 CR_MEMBER(corethickness),
22 CR_MEMBER(flaresize),
23 CR_MEMBER(decay),
24 CR_MEMBER(midtexx),
25 CR_RESERVED(16)
26 ))
27
28
CBeamLaserProjectile(const ProjectileParams & params)29 CBeamLaserProjectile::CBeamLaserProjectile(const ProjectileParams& params): CWeaponProjectile(params)
30 , thickness(0.0f)
31 , corethickness(0.0f)
32 , flaresize(0.0f)
33 , decay(0.0f)
34 , midtexx(0.0f)
35 {
36 projectileType = WEAPON_BEAMLASER_PROJECTILE;
37
38 if (weaponDef != NULL) {
39 assert(weaponDef->IsHitScanWeapon());
40
41 thickness = weaponDef->visuals.thickness;
42 corethickness = weaponDef->visuals.corethickness;
43 flaresize = weaponDef->visuals.laserflaresize;
44 decay = weaponDef->visuals.beamdecay;
45
46 midtexx =
47 (weaponDef->visuals.texture2->xstart +
48 (weaponDef->visuals.texture2->xend - weaponDef->visuals.texture2->xstart) * 0.5f);
49
50 coreColStart[0] = (weaponDef->visuals.color2.x * params.startAlpha);
51 coreColStart[1] = (weaponDef->visuals.color2.y * params.startAlpha);
52 coreColStart[2] = (weaponDef->visuals.color2.z * params.startAlpha);
53 coreColStart[3] = 1;
54 coreColEnd[0] = (weaponDef->visuals.color2.x * params.endAlpha);
55 coreColEnd[1] = (weaponDef->visuals.color2.y * params.endAlpha);
56 coreColEnd[2] = (weaponDef->visuals.color2.z * params.endAlpha);
57 coreColEnd[3] = 1;
58 edgeColStart[0] = (weaponDef->visuals.color.x * params.startAlpha);
59 edgeColStart[1] = (weaponDef->visuals.color.y * params.startAlpha);
60 edgeColStart[2] = (weaponDef->visuals.color.z * params.startAlpha);
61 edgeColStart[3] = 1;
62 edgeColEnd[0] = (weaponDef->visuals.color.x * params.endAlpha);
63 edgeColEnd[1] = (weaponDef->visuals.color.y * params.endAlpha);
64 edgeColEnd[2] = (weaponDef->visuals.color.z * params.endAlpha);
65 edgeColEnd[3] = 1;
66 } else {
67 memset(&coreColStart[0], 0, sizeof(coreColStart));
68 memset(&coreColEnd[0], 0, sizeof(coreColEnd));
69 memset(&edgeColStart[0], 0, sizeof(edgeColStart));
70 memset(&edgeColEnd[0], 0, sizeof(edgeColEnd));
71 }
72 }
73
74
75
Update()76 void CBeamLaserProjectile::Update()
77 {
78 if ((--ttl) <= 0) {
79 deleteMe = true;
80 } else {
81 for (int i = 0; i < 3; i++) {
82 coreColStart[i] *= decay;
83 coreColEnd[i] *= decay;
84 edgeColStart[i] *= decay;
85 edgeColEnd[i] *= decay;
86 }
87
88 explGenHandler->GenExplosion(cegID, startPos + ((targetPos - startPos) / ttl), (targetPos - startPos), 0.0f, flaresize, 0.0f, NULL, NULL);
89 }
90
91 UpdateInterception();
92 }
93
Draw()94 void CBeamLaserProjectile::Draw()
95 {
96 inArray = true;
97
98 const float3 midPos = (targetPos + startPos) * 0.5f;
99 const float3 cameraDir = (midPos - camera->GetPos()).SafeANormalize();
100 // beam's coor-system; degenerate if targetPos == startPos
101 const float3 zdir = (targetPos - startPos).SafeANormalize();
102 const float3 xdir = (cameraDir.cross(zdir)).SafeANormalize();
103 const float3 ydir = (cameraDir.cross(xdir));
104
105 const float beamEdgeSize = thickness;
106 const float beamCoreSize = beamEdgeSize * corethickness;
107 const float flareEdgeSize = thickness * flaresize;
108 const float flareCoreSize = flareEdgeSize * corethickness;
109
110 const float3& pos1 = startPos;
111 const float3& pos2 = targetPos;
112
113 va->EnlargeArrays(32, 0, VA_SIZE_TC);
114
115 #define WT1 weaponDef->visuals.texture1
116 #define WT2 weaponDef->visuals.texture2
117 #define WT3 weaponDef->visuals.texture3
118
119 if ((midPos - camera->GetPos()).SqLength() < (1000.0f * 1000.0f)) {
120 va->AddVertexQTC(pos1 - xdir * beamEdgeSize, midtexx, WT2->ystart, edgeColStart);
121 va->AddVertexQTC(pos1 + xdir * beamEdgeSize, midtexx, WT2->yend, edgeColStart);
122 va->AddVertexQTC(pos1 + xdir * beamEdgeSize - ydir * beamEdgeSize, WT2->xend, WT2->yend, edgeColStart);
123 va->AddVertexQTC(pos1 - xdir * beamEdgeSize - ydir * beamEdgeSize, WT2->xend, WT2->ystart, edgeColStart);
124 va->AddVertexQTC(pos1 - xdir * beamCoreSize, midtexx, WT2->ystart, coreColStart);
125 va->AddVertexQTC(pos1 + xdir * beamCoreSize, midtexx, WT2->yend, coreColStart);
126 va->AddVertexQTC(pos1 + xdir * beamCoreSize - ydir * beamCoreSize, WT2->xend, WT2->yend, coreColStart);
127 va->AddVertexQTC(pos1 - xdir * beamCoreSize - ydir * beamCoreSize, WT2->xend, WT2->ystart, coreColStart);
128
129 va->AddVertexQTC(pos1 - xdir * beamEdgeSize, WT1->xstart, WT1->ystart, edgeColStart);
130 va->AddVertexQTC(pos1 + xdir * beamEdgeSize, WT1->xstart, WT1->yend, edgeColStart);
131 va->AddVertexQTC(pos2 + xdir * beamEdgeSize, WT1->xend, WT1->yend, edgeColEnd);
132 va->AddVertexQTC(pos2 - xdir * beamEdgeSize, WT1->xend, WT1->ystart, edgeColEnd);
133 va->AddVertexQTC(pos1 - xdir * beamCoreSize, WT1->xstart, WT1->ystart, coreColStart);
134 va->AddVertexQTC(pos1 + xdir * beamCoreSize, WT1->xstart, WT1->yend, coreColStart);
135 va->AddVertexQTC(pos2 + xdir * beamCoreSize, WT1->xend, WT1->yend, coreColEnd);
136 va->AddVertexQTC(pos2 - xdir * beamCoreSize, WT1->xend, WT1->ystart, coreColEnd);
137
138 va->AddVertexQTC(pos2 - xdir * beamEdgeSize, midtexx, WT2->ystart, edgeColStart);
139 va->AddVertexQTC(pos2 + xdir * beamEdgeSize, midtexx, WT2->yend, edgeColStart);
140 va->AddVertexQTC(pos2 + xdir * beamEdgeSize + ydir * beamEdgeSize, WT2->xend, WT2->yend, edgeColStart);
141 va->AddVertexQTC(pos2 - xdir * beamEdgeSize + ydir * beamEdgeSize, WT2->xend, WT2->ystart, edgeColStart);
142 va->AddVertexQTC(pos2 - xdir * beamCoreSize, midtexx, WT2->ystart, coreColStart);
143 va->AddVertexQTC(pos2 + xdir * beamCoreSize, midtexx, WT2->yend, coreColStart);
144 va->AddVertexQTC(pos2 + xdir * beamCoreSize + ydir * beamCoreSize, WT2->xend, WT2->yend, coreColStart);
145 va->AddVertexQTC(pos2 - xdir * beamCoreSize + ydir * beamCoreSize, WT2->xend, WT2->ystart, coreColStart);
146 } else {
147 va->AddVertexQTC(pos1 - xdir * beamEdgeSize, WT1->xstart, WT1->ystart, edgeColStart);
148 va->AddVertexQTC(pos1 + xdir * beamEdgeSize, WT1->xstart, WT1->yend, edgeColStart);
149 va->AddVertexQTC(pos2 + xdir * beamEdgeSize, WT1->xend, WT1->yend, edgeColEnd);
150 va->AddVertexQTC(pos2 - xdir * beamEdgeSize, WT1->xend, WT1->ystart, edgeColEnd);
151 va->AddVertexQTC(pos1 - xdir * beamCoreSize, WT1->xstart, WT1->ystart, coreColStart);
152 va->AddVertexQTC(pos1 + xdir * beamCoreSize, WT1->xstart, WT1->yend, coreColStart);
153 va->AddVertexQTC(pos2 + xdir * beamCoreSize, WT1->xend, WT1->yend, coreColEnd);
154 va->AddVertexQTC(pos2 - xdir * beamCoreSize, WT1->xend, WT1->ystart, coreColEnd);
155 }
156
157 // draw flare
158 va->AddVertexQTC(pos1 - camera->right * flareEdgeSize - camera->up * flareEdgeSize, WT3->xstart, WT3->ystart, edgeColStart);
159 va->AddVertexQTC(pos1 + camera->right * flareEdgeSize - camera->up * flareEdgeSize, WT3->xend, WT3->ystart, edgeColStart);
160 va->AddVertexQTC(pos1 + camera->right * flareEdgeSize + camera->up * flareEdgeSize, WT3->xend, WT3->yend, edgeColStart);
161 va->AddVertexQTC(pos1 - camera->right * flareEdgeSize + camera->up * flareEdgeSize, WT3->xstart, WT3->yend, edgeColStart);
162
163 va->AddVertexQTC(pos1 - camera->right * flareCoreSize - camera->up * flareCoreSize, WT3->xstart, WT3->ystart, coreColStart);
164 va->AddVertexQTC(pos1 + camera->right * flareCoreSize - camera->up * flareCoreSize, WT3->xend, WT3->ystart, coreColStart);
165 va->AddVertexQTC(pos1 + camera->right * flareCoreSize + camera->up * flareCoreSize, WT3->xend, WT3->yend, coreColStart);
166 va->AddVertexQTC(pos1 - camera->right * flareCoreSize + camera->up * flareCoreSize, WT3->xstart, WT3->yend, coreColStart);
167
168 #undef WT3
169 #undef WT2
170 #undef WT1
171 }
172
DrawOnMinimap(CVertexArray & lines,CVertexArray & points)173 void CBeamLaserProjectile::DrawOnMinimap(CVertexArray& lines, CVertexArray& points)
174 {
175 const unsigned char color[4] = {edgeColStart[0], edgeColStart[1], edgeColStart[2], 255};
176
177 lines.AddVertexQC(startPos, color);
178 lines.AddVertexQC(targetPos, color);
179 }
180