Rigs of Rods
2023.09
Soft-body Physics Simulation
Main Page
Related Pages
Topics
Namespaces
Data Structures
Files
File List
Globals
•
All
Data Structures
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Modules
Pages
Loading...
Searching...
No Matches
source
main
physics
water
Wavefield.cpp
Go to the documentation of this file.
1
/*
2
This source file is part of Rigs of Rods
3
Copyright 2005-2012 Pierre-Michel Ricordel
4
Copyright 2007-2012 Thomas Fischer
5
Copyright 2013-2025 Petr Ohlidal
6
7
For more information, see http://www.rigsofrods.org/
8
9
Rigs of Rods is free software: you can redistribute it and/or modify
10
it under the terms of the GNU General Public License version 3, as
11
published by the Free Software Foundation.
12
13
Rigs of Rods is distributed in the hope that it will be useful,
14
but WITHOUT ANY WARRANTY; without even the implied warranty of
15
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16
GNU General Public License for more details.
17
18
You should have received a copy of the GNU General Public License
19
along with Rigs of Rods. If not, see <http://www.gnu.org/licenses/>.
20
*/
21
22
#include "
Wavefield.h
"
23
24
#include "
Actor.h
"
25
#include "
AppContext.h
"
26
#include "
CameraManager.h
"
27
#include "
GfxScene.h
"
28
#include "
PlatformUtils.h
"
// PathCombine
29
#include "
Terrain.h
"
30
31
#include <Ogre.h>
32
33
using namespace
RoR
;
34
35
Wavefield::Wavefield
(
Vec3
terrn_size) :
36
m_map_size(terrn_size)
37
{
38
if
(
m_map_size
.
x
< 1500 &&
m_map_size
.
z
< 1500)
39
m_waterplane_mesh_scale
= 1.5f;
40
41
char
line[1024] = {};
42
std::string filepath =
PathCombine
(
RoR::App::sys_config_dir
->getStr(),
"wavefield.cfg"
);
43
FILE* fd = fopen(filepath.c_str(),
"r"
);
44
if
(fd)
45
{
46
while
(!feof(fd))
47
{
48
int
res = fscanf(fd,
" %[^\n\r]"
, line);
49
if
(line[0] ==
';'
)
50
continue
;
51
float
wl, amp, mx, dir;
52
res = sscanf(line,
"%f, %f, %f, %f"
, &wl, &, &mx, &dir);
53
if
(res < 4)
54
continue
;
55
56
WaveTrain
wavetrain;
57
wavetrain.
wavelength
= wl;
58
wavetrain.
amplitude
= amp;
59
wavetrain.
maxheight
= mx;
60
wavetrain.
direction
= dir / 57.0;
61
wavetrain.
dir_sin
= sin(wavetrain.
direction
);
62
wavetrain.
dir_cos
= cos(wavetrain.
direction
);
63
64
m_wavetrain_defs
.push_back(wavetrain);
65
}
66
fclose(fd);
67
}
68
for
(
size_t
i = 0; i <
m_wavetrain_defs
.size(); i++)
69
{
70
m_wavetrain_defs
[i].wavespeed = 1.25 * sqrt(
m_wavetrain_defs
[i].wavelength);
71
m_max_ampl
+=
m_wavetrain_defs
[i].maxheight;
72
}
73
}
35
Wavefield::Wavefield
(
Vec3
terrn_size) : {
…
}
74
75
float
Wavefield::GetStaticWaterHeight
()
76
{
77
return
m_water_height
;
78
};
75
float
Wavefield::GetStaticWaterHeight
() {
…
}
79
80
void
Wavefield::SetStaticWaterHeight
(
float
value)
81
{
82
m_water_height
= value;
83
}
80
void
Wavefield::SetStaticWaterHeight
(
float
value) {
…
}
84
85
void
Wavefield::SetWavesHeight
(
float
value)
86
{
87
m_waves_height
= value;
88
}
85
void
Wavefield::SetWavesHeight
(
float
value) {
…
}
89
90
float
Wavefield::CalcWavesHeight
(
Vec3
pos,
float
timeshift_sec)
91
{
92
// no waves?
93
if
(!
RoR::App::gfx_water_waves
->getBool() ||
RoR::App::mp_state
->getEnum<MpState>() ==
RoR::MpState::CONNECTED
)
94
{
95
// constant height, sea is flat as pancake
96
return
m_water_height
;
97
}
98
99
// uh, some upper limit?!
100
if
(pos.
y
>
m_water_height
+
m_max_ampl
)
101
return
m_water_height
;
102
103
const
float
time_sec =
m_sim_time_counter
+ timeshift_sec;
104
105
float
waveheight =
GetWaveHeight
(pos);
106
// we will store the result in this variable, init it with the default height
107
float
result =
m_water_height
;
108
// now walk through all the wave trains. One 'train' is one sin/cos set that will generate once wave. All the trains together will sum up, so that they generate a 'rough' sea
109
for
(
size_t
i = 0; i <
m_wavetrain_defs
.size(); i++)
110
{
111
// calculate the amplitude that this wave will have. wavetrains[i].amplitude is read from the config
112
// upper limit: prevent too big waves by setting an upper limit
113
float
amp = std::min(
m_wavetrain_defs
[i].amplitude * waveheight,
m_wavetrain_defs
[i].maxheight);
114
// now the main thing:
115
// calculate the sinus with the values of the config file and add it to the result
116
result += amp * sin(Ogre::Math::TWO_PI * ((time_sec *
m_wavetrain_defs
[i].wavespeed +
m_wavetrain_defs
[i].dir_sin * pos.
x
+
m_wavetrain_defs
[i].dir_cos * pos.
z
) /
m_wavetrain_defs
[i].wavelength));
117
}
118
// return the summed up waves
119
return
result;
120
}
90
float
Wavefield::CalcWavesHeight
(
Vec3
pos,
float
timeshift_sec) {
…
}
121
122
bool
Wavefield::IsUnderWater
(
Vec3
pos)
123
{
124
float
waterheight =
m_water_height
;
125
126
if
(
RoR::App::gfx_water_waves
->getBool() &&
RoR::App::mp_state
->getEnum<MpState>() ==
RoR::MpState::DISABLED
)
127
{
128
float
waveheight =
GetWaveHeight
(pos);
129
130
if
(pos.
y
>
m_water_height
+
m_max_ampl
* waveheight || pos.
y
>
m_water_height
+
m_max_ampl
)
131
return
false
;
132
133
waterheight =
CalcWavesHeight
(pos);
134
}
135
136
return
pos.
y
< waterheight;
137
}
122
bool
Wavefield::IsUnderWater
(
Vec3
pos) {
…
}
138
139
Vec3
Wavefield::CalcWavesVelocity
(
Vec3
pos,
float
timeshift_sec)
140
{
141
if
(!
RoR::App::gfx_water_waves
->getBool() ||
RoR::App::mp_state
->getEnum<MpState>() ==
RoR::MpState::CONNECTED
)
142
return
Vec3
();
143
144
float
waveheight =
GetWaveHeight
(pos);
145
146
if
(pos.
y
>
m_water_height
+
m_max_ampl
)
147
return
Vec3
();
148
149
Vec3
result;
150
151
const
float
time_sec =
m_sim_time_counter
+ timeshift_sec;
152
153
for
(
size_t
i = 0; i <
m_wavetrain_defs
.size(); i++)
154
{
155
float
amp = std::min(
m_wavetrain_defs
[i].amplitude * waveheight,
m_wavetrain_defs
[i].maxheight);
156
float
speed = Ogre::Math::TWO_PI * amp / (
m_wavetrain_defs
[i].wavelength /
m_wavetrain_defs
[i].wavespeed);
157
float
coeff = Ogre::Math::TWO_PI * (time_sec *
m_wavetrain_defs
[i].wavespeed +
m_wavetrain_defs
[i].dir_sin * pos.
x
+
m_wavetrain_defs
[i].dir_cos * pos.
z
) /
m_wavetrain_defs
[i].wavelength;
158
result.
y
+= speed * cos(coeff);
159
result +=
Vec3
(
m_wavetrain_defs
[i].dir_sin, 0,
m_wavetrain_defs
[i].dir_cos) * speed * sin(coeff);
160
}
161
162
return
result;
163
}
139
Vec3
Wavefield::CalcWavesVelocity
(
Vec3
pos,
float
timeshift_sec) {
…
}
164
165
void
Wavefield::FrameStepWaveField
(
float
dt)
166
{
167
m_sim_time_counter
+= dt;
168
}
165
void
Wavefield::FrameStepWaveField
(
float
dt) {
…
}
169
170
float
Wavefield::GetWaveHeight
(
Vec3
pos)
171
{
172
// calculate how high the waves should be at this point
173
// (mapsize.x * m_waterplane_mesh_scale) / 2 = terrain width / 2
174
// (mapsize.z * m_waterplane_mesh_scale) / 2 = terrain height / 2
175
// calculate distance to the center of the terrain and divide by 3.000.000
176
float
waveheight = (pos -
Vec3
((
m_map_size
.
x
*
m_waterplane_mesh_scale
) * 0.5,
m_water_height
, (
m_map_size
.
z
*
m_waterplane_mesh_scale
) * 0.5)).squaredLength() / 3000000.0;
177
waveheight +=
m_waves_height
;
178
179
return
waveheight;
180
}
170
float
Wavefield::GetWaveHeight
(
Vec3
pos) {
…
}
181
182
Actor.h
AppContext.h
System integration layer; inspired by OgreBites::ApplicationContext.
CameraManager.h
GfxScene.h
PlatformUtils.h
Platform-specific utilities. We use narrow UTF-8 encoded strings as paths. Inspired by http://utf8eve...
Terrain.h
Wavefield.h
RoR::Wavefield::CalcWavesVelocity
Vec3 CalcWavesVelocity(Vec3 pos, float timeshift_sec=0.f)
Definition
Wavefield.cpp:139
RoR::Wavefield::IsUnderWater
bool IsUnderWater(Vec3 pos)
Definition
Wavefield.cpp:122
RoR::Wavefield::CalcWavesHeight
float CalcWavesHeight(Vec3 pos, float timeshift_sec=0.f)
Definition
Wavefield.cpp:90
RoR::Wavefield::SetStaticWaterHeight
void SetStaticWaterHeight(float value)
Definition
Wavefield.cpp:80
RoR::Wavefield::SetWavesHeight
void SetWavesHeight(float)
Definition
Wavefield.cpp:85
RoR::Wavefield::m_waves_height
float m_waves_height
Definition
Wavefield.h:62
RoR::Wavefield::m_water_height
float m_water_height
Definition
Wavefield.h:61
RoR::Wavefield::FrameStepWaveField
void FrameStepWaveField(float dt)
Definition
Wavefield.cpp:165
RoR::Wavefield::m_waterplane_mesh_scale
float m_waterplane_mesh_scale
Definition
Wavefield.h:60
RoR::Wavefield::Wavefield
Wavefield(Vec3 terrn_size)
Definition
Wavefield.cpp:35
RoR::Wavefield::m_wavetrain_defs
std::vector< WaveTrain > m_wavetrain_defs
Definition
Wavefield.h:58
RoR::Wavefield::m_max_ampl
float m_max_ampl
Definition
Wavefield.h:64
RoR::Wavefield::m_map_size
Vec3 m_map_size
Definition
Wavefield.h:66
RoR::Wavefield::m_sim_time_counter
float m_sim_time_counter
Elapsed simulation time in seconds.
Definition
Wavefield.h:65
RoR::Wavefield::GetStaticWaterHeight
float GetStaticWaterHeight()
Returns static water level configured in 'terrn2'.
Definition
Wavefield.cpp:75
RoR::Wavefield::GetWaveHeight
float GetWaveHeight(Vec3 pos)
Definition
Wavefield.cpp:170
RoR::PathCombine
std::string PathCombine(std::string a, std::string b)
Definition
PlatformUtils.h:48
RoR::MpState::DISABLED
@ DISABLED
Not connected for whatever reason.
RoR::MpState::CONNECTED
@ CONNECTED
RoR::App::sys_config_dir
CVar * sys_config_dir
Definition
Application.cpp:165
RoR::App::gfx_water_waves
CVar * gfx_water_waves
Definition
Application.cpp:240
RoR::App::mp_state
CVar * mp_state
Definition
Application.cpp:115
RoR
Definition
AppContext.h:36
RoR::Vec3
Designed to work smoothly with optimizations disabled.
Definition
Vec3.h:29
RoR::Vec3::x
float x
Definition
Vec3.h:30
RoR::Vec3::z
float z
Definition
Vec3.h:30
RoR::Vec3::y
float y
Definition
Vec3.h:30
RoR::Wavefield::WaveTrain
Definition
Wavefield.h:49
RoR::Wavefield::WaveTrain::dir_cos
float dir_cos
Definition
Wavefield.h:56
RoR::Wavefield::WaveTrain::amplitude
float amplitude
Definition
Wavefield.h:50
RoR::Wavefield::WaveTrain::direction
float direction
Definition
Wavefield.h:54
RoR::Wavefield::WaveTrain::wavelength
float wavelength
Definition
Wavefield.h:52
RoR::Wavefield::WaveTrain::dir_sin
float dir_sin
Definition
Wavefield.h:55
RoR::Wavefield::WaveTrain::maxheight
float maxheight
Definition
Wavefield.h:51
Generated on Fri Jan 2 2026 09:37:03 for Rigs of Rods by
1.9.8