forked from ismailrohaga/assignment-cg
-
Notifications
You must be signed in to change notification settings - Fork 0
/
script.js
247 lines (206 loc) · 7.96 KB
/
script.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
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
import * as THREE from './three.js-master/build/three.module.js'
import {OrbitControls} from './three.js-master/examples/jsm/controls/OrbitControls.js'
/**
* Computer Graphic Project Assignment
* Create aplikasi grafis interaktif yang menggabungkan min. 2 object (lingkaran, tabung, dll)
* bisa ditransformasi geometri (translate, rotate, scale) dgn tambahan shadding, lighting, dsb
*
* Ismail Azh-Zhafir Rohaga - 2301911136
* Muhammad Akbar Zanucky - 2301934594
* Raden Naufal Nursatria Kusumawardana - 2301899906
* Nicholas Reynaldo - 2301847404
*/
//init variables
var scene, camera, renderer, control, n, m
var planeMesh, boxMesh, bowlMesh, pinMesh, pinHeadMesh, sun
var animation = false;
//collision detection (Not yet implemented)
var objects = [];
var collisions = [];
//Main function
var doInit = () => {
scene = new THREE.Scene()
const FOV = 60
const WIDTH = window.innerWidth
const HEIGHT = window.innerHeight
const ASPECT = WIDTH / HEIGHT
camera = new THREE.PerspectiveCamera(FOV, ASPECT)
camera.position.set(0, 5, 10)
camera.lookAt(0, 0, 0)
renderer = new THREE.WebGLRenderer({antialias: true})
renderer.setSize(WIDTH, HEIGHT)
renderer.shadowMap.enabled=true
renderer.setClearColor(0x303030)
// const loader = new THREE.TextureLoader();
// scene.add(
// new THREE.Mesh(
// new THREE.BoxGeometry(500, 500, 500),
// [
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0001.jpg'), side: THREE.DoubleSide}),
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0002.jpg'), side: THREE.DoubleSide}),
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0003.jpg'), side: THREE.DoubleSide}),
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0004.jpg'), side: THREE.DoubleSide}),
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0005.jpg'), side: THREE.DoubleSide}),
// new THREE.MeshPhongMaterial({map: loader.load('./texture/skybox/skyrender0006.jpg'), side: THREE.DoubleSide}),
// ]
// )
// )
scene.background = new THREE.CubeTextureLoader().load( [
'texture/skybox/corona_ft.png',
'texture/skybox/corona_bk.png',
'texture/skybox/corona_up.png',
'texture/skybox/corona_dn.png',
'texture/skybox/corona_rt.png',
'texture/skybox/corona_lf.png',
] )
//Texture
const bowlTex = new THREE.TextureLoader().load('./texture/ball.jpg'); //Bowling ball Texture
const laneTex = new THREE.TextureLoader().load('./texture/lane.jpg'); //Lane Texture
// const groundTex = new THREE.TextureLoader().load('./texture/ground.jpg');
//Bowling Lane
var planeGeo = new THREE.BoxGeometry(10, 0.5, 50);
var planeMat = new THREE.MeshStandardMaterial( { map : laneTex} );
planeMesh = new THREE.Mesh(planeGeo, planeMat);
planeMesh.receiveShadow=true;
planeMesh.castShadow=true;
planeMesh.position.z = -20;
scene.add(planeMesh);
//Ground
var boxGeo = new THREE.BoxGeometry(15, 2, 50);
var boxMat = new THREE.MeshMatcapMaterial({ color: 0x00000 })
boxMesh = new THREE.Mesh(boxGeo, boxMat);
boxMesh.position.set(0,-1.2,2);
boxMesh.position.z = -20;
boxMesh.receiveShadow=true;
scene.add(boxMesh);
//Bowling Ball
var bowlBall = new THREE.SphereGeometry(1, 8, 8);
var bowlMat = new THREE.MeshStandardMaterial( { map : bowlTex } );
bowlMesh = new THREE.Mesh(bowlBall, bowlMat);
bowlMesh.castShadow=true;
bowlMesh.receiveShadow=false;
bowlMesh.position.set(0, 1.2, 3);
bowlMesh.name = "bowlingball"
scene.add(bowlMesh);
//Pin Top
var pinGeo = new THREE.ConeGeometry(1, 2, 8)
var pinMat = new THREE.MeshStandardMaterial( {color : 0xffffff} )
pinMesh = new THREE.Mesh(pinGeo, pinMat)
pinMesh.castShadow=true
pinMesh.position.set(0, 1.2, -42)
scene.add(pinMesh)
//Pin Bottom
var pinHeadGeo = new THREE.SphereGeometry(0.8, 10, 5)
var pinHeadMat = new THREE.MeshStandardMaterial( {color : 0xffffff} )
pinHeadMesh = new THREE.Mesh(pinHeadGeo, pinHeadMat)
pinHeadMesh.castShadow=true
pinHeadMesh.position.set(0, 2.5, -42)
scene.add(pinHeadMesh)
//Interactive element
var slider = document.getElementById("slider"); //Position and Rotation
var slider2 = document.getElementById("slider2") //Scale
slider.addEventListener("input", moveBall)
slider2.addEventListener("input", scaleBall)
const button = document.getElementById("Reset") //Reset button
button.addEventListener("click", resetScene);
//Lighting
sun = new THREE.DirectionalLight( 0xffffff, 0.8 );
sun.position.set( 0,4,1 );
sun.castShadow = true;
scene.add(sun);
sun.shadow.mapSize.width = 256;
sun.shadow.mapSize.height = 256;
sun.shadow.camera.near = 0.5;
sun.shadow.camera.far = 50 ;
//Camera Control
control = new OrbitControls(camera, renderer.domElement)
control.target = bowlMesh.position
// control.enableZoom = false
// control.enableRotate= false
document.body.appendChild(renderer.domElement)
}
//Move the ball using value from HTML slider
function moveBall(e){
var target = (e.target) ? e.target : e.srcElement;
console.log("m: " + target.value)
bowlMesh.position.z = -target.value;
bowlMesh.rotation.z += -target.value;
}
//Scale the ball using value from HTML slider2
function scaleBall(e){
var target = (e.target) ? e.target : e.srcElement;
console.log(target.value)
bowlMesh.scale.x = target.value;
bowlMesh.scale.y = target.value;
bowlMesh.scale.z = target.value;
}
//Get mouse position to convert into RGB code and change the ground color
let mouseMove = (event) =>{
boxMesh.material.color = new THREE.Color(`rgb(${(event.clientX % 255)}, ${event.clientY % 255}, 50)`)
}
let addListener = () =>{
document.addEventListener("mousemove", mouseMove)
}
//Resetting the scene by reinstantiate the object to original position
function resetScene(e){
console.log("test")
scene.add(pinMesh)
scene.add(pinHeadMesh);
bowlMesh.position.z = 3;
}
//Animation of moving the ball from point A to point B using LERP
//Animation is triggered by clicking on the ball
let alpha = 0.01;
function doRender(){
requestAnimationFrame(doRender)
control.update()
renderer.render(scene, camera)
if(animation == true)
{
bowlMesh.rotation.x ++;
bowlMesh.position.lerp(new THREE.Vector3(0, 1.2, -51), alpha);
if(bowlMesh.position.z < -40.8)
{
animation = false;
scene.remove(pinMesh);
pinHeadMesh.position.lerp(new THREE.Vector3(0, 1.2, -55), alpha)
scene.remove(pinHeadMesh);
scene.remove(pinMesh);
}
}
}
window.onload = () => {
doInit()
addListener()
doRender()
}
window.onresize = () => {
const NEW_WIDTH = innerWidth
const NEW_HEIGHT = innerHeight
renderer.setSize(NEW_WIDTH, NEW_HEIGHT)
camera.aspect = NEW_WIDTH / NEW_HEIGHT
camera.updateProjectionMatrix()
}
//basic raycasting to check the object ID/name and enabling animation for the Bowling Ball
const onClickFunc = (event) =>
{
var mouse = new THREE.Vector2();
mouse.x = (event.clientX / window.innerWidth)*2 - 1;
mouse.y = -(event.clientY / window.innerHeight)*2 + 1;
let raycast = new THREE.Raycaster();
raycast.setFromCamera(mouse, camera);
let interact = raycast.intersectObjects(scene.children);
if(interact.length != 0)
{
for (let index = 0; index < interact.length; index++)
{
const element = interact[index];
if(element.object.name == "bowlingball")
{
console.log("hello")
animation = true;
}
}
}
}
document.addEventListener("pointerdown", onClickFunc);