forked from markjay4k/Audio-Spectrum-Analyzer-in-Python
-
Notifications
You must be signed in to change notification settings - Fork 0
/
terrain.py
121 lines (101 loc) · 3.81 KB
/
terrain.py
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
"""
This creates a 3D mesh with perlin noise to simulate
a terrain. The mesh is animated by shifting the noise
to give a "fly-over" effect.
If you don't have pyOpenGL or opensimplex, then:
- conda install -c anaconda pyopengl
- pip install opensimplex
"""
import numpy as np
from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph.opengl as gl
import sys
from opensimplex import OpenSimplex
class Terrain(object):
def __init__(self):
"""
Initialize the graphics window and mesh
"""
# setup the view window
self.app = QtGui.QApplication(sys.argv)
self.w = gl.GLViewWidget()
self.w.setGeometry(0, 110, 1920, 1080)
self.w.show()
self.w.setWindowTitle('Terrain')
self.w.setCameraPosition(distance=30, elevation=8)
# constants and arrays
self.nsteps = 1
self.ypoints = range(-20, 22, self.nsteps)
self.xpoints = range(-20, 22, self.nsteps)
self.nfaces = len(self.ypoints)
self.offset = 0
# perlin noise object
self.tmp = OpenSimplex()
# create the veritices array
verts = np.array([
[
x, y, 1.5 * self.tmp.noise2d(x=n / 5, y=m / 5)
] for n, x in enumerate(self.xpoints) for m, y in enumerate(self.ypoints)
], dtype=np.float32)
# create the faces and colors arrays
faces = []
colors = []
for m in range(self.nfaces - 1):
yoff = m * self.nfaces
for n in range(self.nfaces - 1):
faces.append([n + yoff, yoff + n + self.nfaces, yoff + n + self.nfaces + 1])
faces.append([n + yoff, yoff + n + 1, yoff + n + self.nfaces + 1])
colors.append([0, 0, 0, 0])
colors.append([0, 0, 0, 0])
faces = np.array(faces)
colors = np.array(colors)
# create the mesh item
self.m1 = gl.GLMeshItem(
vertexes=verts,
faces=faces, faceColors=colors,
smooth=False, drawEdges=True,
)
self.m1.setGLOptions('additive')
self.w.addItem(self.m1)
def update(self):
"""
update the mesh and shift the noise each time
"""
verts = np.array([
[
x, y, 2.5 * self.tmp.noise2d(x=n / 5 + self.offset, y=m / 5 + self.offset)
] for n, x in enumerate(self.xpoints) for m, y in enumerate(self.ypoints)
], dtype=np.float32)
faces = []
colors = []
for m in range(self.nfaces - 1):
yoff = m * self.nfaces
for n in range(self.nfaces - 1):
faces.append([n + yoff, yoff + n + self.nfaces, yoff + n + self.nfaces + 1])
faces.append([n + yoff, yoff + n + 1, yoff + n + self.nfaces + 1])
colors.append([n / self.nfaces, 1 - n / self.nfaces, m / self.nfaces, 0.7])
colors.append([n / self.nfaces, 1 - n / self.nfaces, m / self.nfaces, 0.8])
faces = np.array(faces, dtype=np.uint32)
colors = np.array(colors, dtype=np.float32)
self.m1.setMeshData(
vertexes=verts, faces=faces, faceColors=colors
)
self.offset -= 0.18
def start(self):
"""
get the graphics window open and setup
"""
if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
QtGui.QApplication.instance().exec_()
def animation(self):
"""
calls the update method to run in a loop
"""
timer = QtCore.QTimer()
timer.timeout.connect(self.update)
timer.start(10)
self.start()
self.update()
if __name__ == '__main__':
t = Terrain()
t.animation()