-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathindex.js
175 lines (134 loc) · 5.22 KB
/
index.js
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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
const sizeSlider = document.getElementById("mapSize");
const linearitySlider = document.getElementById("mapLinearity");
const altitudeSlider = document.getElementById("altitudeVariation");
const sizeOutput = document.getElementById("sizeOutput");
const linearityOutput = document.getElementById("linearityOutput");
const altitudeOutput = document.getElementById("altitudeOutput");
sizeOutput.innerHTML = sizeSlider.value;
linearityOutput.innerHTML = linearitySlider.value;
altitudeOutput.innerHTML = altitudeSlider.value;
sizeSlider.oninput = function () {
sizeOutput.innerHTML = this.value;
};
linearitySlider.oninput = function () {
linearityOutput.innerHTML = this.value;
};
altitudeSlider.oninput = function () {
altitudeOutput.innerHTML = this.value;
};
function removeElement(elementId) {
const element = document.getElementById(elementId);
element.parentNode.removeChild(element);
}
function init() {
const sizeVal = sizeSlider.value;
const linearityVal = linearitySlider.value;
const altitudeVal = altitudeSlider.value;
removeElement('prompt');
startRendering(parseInt(sizeVal), parseInt(linearityVal), parseInt(altitudeVal));
}
function startRendering(size, linearity, altitudeVar) {
let camera, scene, renderer;
let geom, material, mesh, object, spotLight, light, zMax;
let map = MapGen.getMap(size, linearity, altitudeVar);
init();
let angle = 0;
let finishedInit = false;
animate();
function init() {
camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.z = 1;
scene = new THREE.Scene();
const loader = new THREE.CubeTextureLoader();
loader.setPath('img/');
// for skybox
const textureCube = loader.load([
'sky.jpg', 'sky.jpg',
'sky.jpg', 'sky.jpg',
'sky.jpg', 'sky.jpg'
]);
scene.background = textureCube;
scene.fog = new THREE.FogExp2(0xcccccc, 0.002);
geom = new THREE.Geometry();
// create geometry for road
let vertexIndex = 0;
for (let shape of map) {
for (let pos of shape) {
geom.vertices.push(new THREE.Vector3(pos[0], pos[1], pos[2]));
}
if (shape.length === 4) {
// 4 vertices -> square
// need to triangulate
geom.faces.push(new THREE.Face3(vertexIndex, vertexIndex + 1, vertexIndex + 2));
geom.faces.push(new THREE.Face3(vertexIndex + 2, vertexIndex + 3, vertexIndex));
vertexIndex += 4;
} else {
// triangle with 3 vertices
geom.faces.push(new THREE.Face3(vertexIndex, vertexIndex + 1, vertexIndex + 2));
vertexIndex += 3;
}
}
geom.computeFaceNormals();
geom.drawMode = THREE.TriangleStripDrawMode;
object = new THREE.Mesh(geom, new THREE.MeshStandardMaterial({
wireframe: false,
flatShading: false,
side: THREE.DoubleSide,
envMap: textureCube,
color: 0x333333,
roughness: 0,
metalness: 0.5
}));
// get bounding box size of generated road
const bbox = new THREE.Box3().setFromObject(object);
const xSize = bbox.max.x - bbox.min.x;
const ySize = bbox.max.y - bbox.min.y;
zMax = bbox.max.z;
// init camera pos
camera.position.z = 2 * size;
camera.position.y += ySize * 4;
// center obj
object.position.y = -size / 2;
object.position.x = (size - xSize) / 2;
scene.add(object);
// add edges
const edges = new THREE.EdgesGeometry(object.geometry);
const eColor = new THREE.LineBasicMaterial({
color: 0x00
});
const wireframe = new THREE.LineSegments(edges, eColor);
wireframe.position.y = -size / 2;
wireframe.position.x = (size - xSize) / 2;
scene.add(wireframe);
// moving source of light
spotLight = new THREE.SpotLight(0xAA33FF, 6);
scene.add(spotLight);
// static source of light
light = new THREE.AmbientLight(0xff44ff, 2);
scene.add(light);
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth * 0.75, window.innerHeight * 0.75);
document.body.appendChild(renderer.domElement);
renderer.render(scene, camera);
// control camera with mouse
controls = new THREE.TrackballControls(camera);
controls.target.set(size, 0, 0);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 1;
controls.panSpeed = 1;
controls.dynamicDampingFactor = 0.3;
}
function animate() {
requestAnimationFrame(animate);
controls.update();
spotLight.position.set(3 * size * Math.cos(angle), size, 3 * size * Math.sin(angle));
angle += 0.02;
if (angle >= 2 * Math.PI) angle = 0;
if (camera.position.z > zMax && !finishedInit)
camera.position.z -= Math.max(1, (camera.position.z - zMax) / 20);
else finishedInit = true;
renderer.render(scene, camera);
}
}