File: Wind.cpp

package info (click to toggle)
spring 106.0%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 55,316 kB
  • sloc: cpp: 543,954; ansic: 44,800; python: 12,575; java: 12,201; awk: 5,889; sh: 1,796; asm: 1,546; xml: 655; perl: 405; php: 211; objc: 194; makefile: 76; sed: 2
file content (127 lines) | stat: -rw-r--r-- 3,390 bytes parent folder | download | duplicates (3)
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
115
116
117
118
119
120
121
122
123
124
125
126
127
/* 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/SpringMath.h"

CR_BIND(EnvResourceHandler, )

CR_REG_METADATA(EnvResourceHandler, (
	CR_MEMBER(curTidalStrength),
	CR_MEMBER(curWindStrength),
	CR_MEMBER(minWindStrength),
	CR_MEMBER(maxWindStrength),

	CR_MEMBER(curWindVec),
	CR_MEMBER(curWindDir),

	CR_MEMBER(newWindVec),
	CR_MEMBER(oldWindVec),

	CR_MEMBER(windDirTimer),

	CR_MEMBER(allGeneratorIDs),
	CR_MEMBER(newGeneratorIDs)
))


EnvResourceHandler envResHandler;


void EnvResourceHandler::ResetState()
{
	curTidalStrength = 0.0f;
	curWindStrength = 0.0f;
	minWindStrength = 0.0f;
	maxWindStrength = 100.0f;

	curWindDir = RgtVector;
	curWindVec = ZeroVector;
	newWindVec = ZeroVector;
	oldWindVec = ZeroVector;

	windDirTimer = 0;

	allGeneratorIDs.clear();
	allGeneratorIDs.reserve(256);
	newGeneratorIDs.clear();
	newGeneratorIDs.reserve(256);
}

void EnvResourceHandler::LoadWind(float minStrength, float maxStrength)
{
	minWindStrength = std::min(minStrength, maxStrength);
	maxWindStrength = std::max(minStrength, maxStrength);

	curWindVec = mix(curWindDir * GetAverageWindStrength(), RgtVector * GetAverageWindStrength(), curWindDir == RgtVector);
	oldWindVec = curWindVec;
}


bool EnvResourceHandler::AddGenerator(CUnit* u) {
	// duplicates should never happen, no need to check
	return (spring::VectorInsertUnique(newGeneratorIDs, u->id));
}

bool EnvResourceHandler::DelGenerator(CUnit* u) {
	// id is never present in both
	return (spring::VectorErase(newGeneratorIDs, u->id) || spring::VectorErase(allGeneratorIDs, u->id));
}



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

	if (windDirTimer == 0) {
		oldWindVec = curWindVec;
		newWindVec = oldWindVec;

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

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

		// normalize and clamp s.t. minWindStrength <= strength <= maxWindStrength
		newWindVec /= newStrength;
		newWindVec *= (newStrength = Clamp(newStrength, minWindStrength, maxWindStrength));

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

		// blend between old & new wind directions
		// note: generators added on simframes when timer is 0
		// do not receive a snapshot of the blended direction
		curWindVec = mix(oldWindVec, newWindVec, mod);
		curWindStrength = curWindVec.LengthNormalize();

		curWindDir = curWindVec;
		curWindVec = curWindDir * (curWindStrength = Clamp(curWindStrength, minWindStrength, maxWindStrength));

		for (const int unitID: newGeneratorIDs) {
			// make newly added generators point in direction of wind
			(unitHandler.GetUnit(unitID))->UpdateWind(curWindDir.x, curWindDir.z, curWindStrength);
			allGeneratorIDs.push_back(unitID);
		}

		newGeneratorIDs.clear();
	}

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