File: Wind.cpp

package info (click to toggle)
spring 104.0%2Bdfsg-3
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 47,512 kB
  • sloc: cpp: 391,093; ansic: 79,943; python: 12,356; java: 12,201; awk: 5,889; sh: 1,826; xml: 655; makefile: 486; perl: 405; php: 211; objc: 194; sed: 2
file content (114 lines) | stat: -rw-r--r-- 2,511 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
/* This file is part of the Spring engine (GPL v2 or later), see LICENSE.html */


#include "Wind.h"
#include "GlobalSynced.h"
#include "Sim/Units/Unit.h"
#include "Sim/Units/UnitHandler.h"
#include "System/ContainerUtil.h"
#include "System/myMath.h"

CR_BIND(CWind, )

CR_REG_METADATA(CWind, (
	CR_MEMBER(maxWind),
	CR_MEMBER(minWind),

	CR_MEMBER(curWind),
	CR_MEMBER(curStrength),
	CR_MEMBER(curDir),

	CR_MEMBER(newWind),
	CR_MEMBER(oldWind),
	CR_MEMBER(status),

	CR_MEMBER(windGenIDs)
))


// update all units every 15 secs
static const int WIND_UPDATE_RATE = 15 * GAME_SPEED;

CWind wind;

void CWind::LoadWind(float minw, float maxw)
{
	minWind = std::min(minw, maxw);
	maxWind = std::max(minw, maxw);
	curWind = float3(minWind, 0.0f, 0.0f);
	oldWind = curWind;
}

void CWind::ResetState()
{
	maxWind = 100.0f;
	minWind = 0.0f;
	curStrength = 0.0f;
	curDir = RgtVector;
	curWind = ZeroVector;
	newWind = ZeroVector;
	oldWind = ZeroVector;
	status = 0;
	windGenIDs.clear();
}


bool CWind::AddUnit(CUnit* u) {
	// duplicates should never happen, no need to check
	spring::VectorInsertUnique(windGenIDs, u->id);

	// start pointing in direction of wind
	u->UpdateWind(curDir.x, curDir.z, curStrength);
	return true;
}

bool CWind::DelUnit(CUnit* u) {
	return (spring::VectorErase(windGenIDs, u->id));
}



void CWind::Update()
{
	// zero-strength wind does not need updates
	if (maxWind <= 0.0f)
		return;

	if (status == 0) {
		oldWind = curWind;
		newWind = oldWind;

		// generate new wind direction
		float newStrength = 0.0f;

		do {
			newWind.x -= (gsRNG.NextFloat() - 0.5f) * maxWind;
			newWind.z -= (gsRNG.NextFloat() - 0.5f) * maxWind;
			newStrength = newWind.Length();
		} while (newStrength == 0.0f);

		// normalize and clamp s.t. minWind <= strength <= maxWind
		newWind /= newStrength;
		newWind *= (newStrength = Clamp(newStrength, minWind, maxWind));

		// update generators
		for (const int unitID: windGenIDs) {
			(unitHandler->GetUnit(unitID))->UpdateWind(newWind.x, newWind.z, newStrength);
		}
	} else {
		const float mod = smoothstep(0.0f, 1.0f, status / float(WIND_UPDATE_RATE));

		// blend between old & new wind directions
		// note: only generators added on simframes when
		// status != 0 receive a snapshot of the blended
		// direction
		curWind = mix(oldWind, newWind, mod);
		curStrength = curWind.LengthNormalize();

		curDir = curWind;
		curWind = curDir * (curStrength = Clamp(curStrength, minWind, maxWind));
	}

	status = (status + 1) % (WIND_UPDATE_RATE + 1);
}