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