Let's port the terrainDemo with reference to basicDemo porting in the previous chapter.
1
2
3
4
5
6
7
8
9
10
11
12
|
#include "TerrainDemo.h"
#include "GlutStuff.h"
int main(int argc,char** argv)
{
DemoApplication * demo = btCreateTerrainDemo();
btAssert(demo && "failed to create terrain demo object");
return glutmain(argc, argv, 800, 600,
"Terrain Demo. http://www.continuousphysics.com/Bullet/phpBB2/",
demo);
}
|
cs |
btCreateTerrainDemo () is executed instead of initPhysics. Follow the source.


The world setting is different. This part does not have prior knowledge of the bullet wrapper reference. Originally it was where btDbvtBroadphase ();
..... 추가

I'm changing 1- gravity, creating 2-btHeightFiledData, and 3- btHeightFiledTerrainShape.
I think you need to understand the new btHeightFiledData, btHeightFieldTerrainShape. Other work flows are no different from the dynamic world settings.
First, let's check the other terrainDemo part.
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
|
// creates a radially-varying heightfield
static void
setRadial
(
byte_t * grid,
int bytesPerElement,
PHY_ScalarType type,
float phase = 0.0
)
{
btAssert(grid);
btAssert(bytesPerElement > 0);
// min/max
float period = 0.5 / s_gridSpacing;
float floor = 0.0;
float min_r = 3.0 * sqrt(s_gridSpacing);
float magnitude = 50.0 * sqrt(s_gridSpacing);
// pick a base_phase such that phase = 0 results in max height
// (this way, if you create a heightfield with phase = 0,
// you can rely on the min/max heights that result)
float base_phase = (0.5 * SIMD_PI) - (period * min_r);
phase += base_phase;
// center of grid
float cx = 0.5 * s_gridSize * s_gridSpacing;
float cy = cx; // assume square grid
byte_t * p = grid;
for (int i = 0; i < s_gridSize; ++i) {
float x = i * s_gridSpacing;
for (int j = 0; j < s_gridSize; ++j) {
float y = j * s_gridSpacing;
float dx = x - cx;
float dy = y - cy;
float r = sqrt((dx * dx) + (dy * dy));
float z = period;
if (r < min_r) {
r = min_r;
}
z = (1.0 / r) * sin(period * r + phase);
if (z > period) {
z = period;
} else if (z < -period) {
z = -period;
}
z = floor + magnitude * z;
convertFromFloat(p, z, type);
p += bytesPerElement;
}
}
}
|
cs |
It is said to create radial change terrain. We can infer that we take a grid of bype_t * type that we don't know yet and change it. The last part can be read as changing p (since it's a grid) and shifting it by the data size.
convertFromFloat(p, z, type);
p += bytesPerElement;
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
|
// creates a random, fractal heightfield
static void
setFractal
(
byte_t * grid,
int bytesPerElement,
PHY_ScalarType type,
int step
)
{
btAssert(grid);
btAssert(bytesPerElement > 0);
btAssert(step > 0);
btAssert(step < s_gridSize);
int newStep = step / 2;
// std::cerr << "Computing grid with step = " << step << ": before\n";
// dumpGrid(grid, bytesPerElement, type, step + 1);
// special case: starting (must set four corners)
if (s_gridSize - 1 == step) {
// pick a non-zero (possibly negative) base elevation for testing
float base = randomHeight(step / 2);
convertFromFloat(grid, base, type);
convertFromFloat(grid + step * bytesPerElement, base, type);
convertFromFloat(grid + step * s_gridSize * bytesPerElement, base, type);
convertFromFloat(grid + (step * s_gridSize + step) * bytesPerElement, base, type);
}
// determine elevation of each corner
float c00 = convertToFloat(grid, type);
float c01 = convertToFloat(grid + step * bytesPerElement, type);
float c10 = convertToFloat(grid + (step * s_gridSize) * bytesPerElement, type);
float c11 = convertToFloat(grid + (step * s_gridSize + step) * bytesPerElement, type);
// set top middle
updateHeight(grid + newStep * bytesPerElement, 0.5 * (c00 + c01) + randomHeight(step), type);
// set left middle
updateHeight(grid + (newStep * s_gridSize) * bytesPerElement, 0.5 * (c00 + c10) + randomHeight(step), type);
// set right middle
updateHeight(grid + (newStep * s_gridSize + step) * bytesPerElement, 0.5 * (c01 + c11) + randomHeight(step), type);
// set bottom middle
updateHeight(grid + (step * s_gridSize + newStep) * bytesPerElement, 0.5 * (c10 + c11) + randomHeight(step), type);
// set middle
updateHeight(grid + (newStep * s_gridSize + newStep) * bytesPerElement, 0.25 * (c00 + c01 + c10 + c11) + randomHeight(step), type);
// std::cerr << "Computing grid with step = " << step << ": after\n";
// dumpGrid(grid, bytesPerElement, type, step + 1);
// terminate?
if (newStep < 2) {
return;
}
// recurse
setFractal(grid, bytesPerElement, type, newStep);
setFractal(grid + newStep * bytesPerElement, bytesPerElement, type, newStep);
setFractal(grid + (newStep * s_gridSize) * bytesPerElement, bytesPerElement, type, newStep);
setFractal(grid + ((newStep * s_gridSize) + newStep) * bytesPerElement, bytesPerElement, type, newStep);
}
|
cs |
Creates a random fractal height field.
setRadial () and setFractal () This doesn't know exactly what it does, but it can be expected to transform the grid data anyway. When you run the example, the ground is moving, so it seems to be the same.
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
|
static byte_t *
getRawHeightfieldData
(
eTerrainModel model,
PHY_ScalarType type,
btScalar& minHeight,
btScalar& maxHeight
)
{
// std::cerr << "\nRegenerating terrain\n";
// std::cerr << " model = " << model << "\n";
// std::cerr << " type = " << type << "\n";
long nElements = ((long) s_gridSize) * s_gridSize;
// std::cerr << " nElements = " << nElements << "\n";
int bytesPerElement = getByteSize(type);
// std::cerr << " bytesPerElement = " << bytesPerElement << "\n";
btAssert(bytesPerElement > 0 && "bad bytes per element");
long nBytes = nElements * bytesPerElement;
// std::cerr << " nBytes = " << nBytes << "\n";
byte_t * raw = new byte_t[nBytes];
btAssert(raw && "out of memory");
// reseed randomization every 30 seconds
// srand(time(NULL) / 30);
// populate based on model
switch (model) {
case eRadial:
setRadial(raw, bytesPerElement, type);
break;
case eFractal:
for (int i = 0; i < nBytes; i++)
{
raw[i] = 0;
}
setFractal(raw, bytesPerElement, type, s_gridSize - 1);
break;
default:
btAssert(!"bad model type");
}
if (0) {
// inside if(0) so it keeps compiling but isn't
// exercised and doesn't cause warnings
// std::cerr << "final grid:\n";
dumpGrid(raw, bytesPerElement, type, s_gridSize - 1);
}
// find min/max
for (int i = 0; i < s_gridSize; ++i) {
for (int j = 0; j < s_gridSize; ++j) {
float z = getGridHeight(raw, i, j, type);
// std::cerr << "i=" << i << ", j=" << j << ": z=" << z << "\n";
// update min/max
if (!i && !j) {
minHeight = z;
maxHeight = z;
} else {
if (z < minHeight) {
minHeight = z;
}
if (z > maxHeight) {
maxHeight = z;
}
}
}
}
if (maxHeight < -minHeight) {
maxHeight = -minHeight;
}
if (minHeight > -maxHeight) {
minHeight = -maxHeight;
}
// std::cerr << " minHeight = " << minHeight << "\n";
// std::cerr << " maxHeight = " << maxHeight << "\n";
return raw;
}
|
cs |
getRawHeightfieldData (), yes it seems to be a function that creates heightFieldData directly. But no data is received. You can see that it creates an empty data array called raw. By creating this, it seems to create terrain randomly with the above two functions.
We have looked at the main functions. Now, use your imagination to port the code above to libgdx / java, modify it, and see the value.
This part of drawOpenGL in GL_ShapeDrawer.cpp ..-> Move while watching getShapeType ()
By the way, getShapeType () did not find anything special. Then let's follow the same from the first world setting.
'LibGdx' 카테고리의 다른 글
AnimationController class (0) | 2021.04.09 |
---|---|
libgdx - Convert c ++ bullet file to libgdx file - 2( terrainDemo ) (0) | 2019.12.17 |
libgdx-collision handling 3 (collision, bullet engine) (0) | 2019.11.18 |
libgdx-collision handling 2 (collision, bullet engine) (0) | 2019.11.18 |
libgdx-collision handling (collision, bullet engine) (0) | 2019.11.18 |
댓글