-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathterrain.py
More file actions
45 lines (39 loc) · 1.77 KB
/
terrain.py
File metadata and controls
45 lines (39 loc) · 1.77 KB
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
import noise
import numpy as np
import pybullet as p
class Terrain:
def __init__(self):
"""
Make the terrain
"""
rows, cols = 16, 16
lateral_scale = 2
vertical_scale = 8
self.heightmap = np.zeros((cols, rows), dtype=float)
for x in range(cols):
for y in range(rows):
# Perlin needs inputs between 0 and 1
# We also need to scale as it outputs between -1 and 1
self.heightmap[x, y] = vertical_scale * noise.pnoise2(
x / cols / lateral_scale, y / rows / lateral_scale,
octaves=6, persistence=0.5, lacunarity=2.0, base=0,
)
self.terrain_shape = p.createCollisionShape(
shapeType=p.GEOM_HEIGHTFIELD, heightfieldData=self.heightmap.T.reshape(-1),
heightfieldTextureScaling=rows - 1,
numHeightfieldRows=rows, numHeightfieldColumns=cols,
)
self.terrain_multi_body = p.createMultiBody(0, self.terrain_shape)
# Precompute normals
# self.normals = np.zeros((cols, rows, 3), dtype=float)
# for x in range(1, cols):
# for y in range(1, rows):
# # Shoot a ray from the sky directly above this cell and collect the hit normal
# # I figured this would be most similar to the snake giving back normal values from contact
# x_c = x - cols / 2
# y_c = y - rows / 2
# hit, = client.rayTest([x_c, y_c, 100], [x_c, y_c, -100])
# hit_normal = hit[4]
# self.normals[x, y] = hit_normal
# point = np.array([x_c, y_c, self.heightmap[x, y]])
# client.addUserDebugLine(point, point + hit_normal, [1, 0, 0])