Skip to content

Commit cd2a4d7

Browse files
🚚 Custom models with blender
1 parent 2762492 commit cd2a4d7

File tree

15 files changed

+51
-841
lines changed

15 files changed

+51
-841
lines changed

src/index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>23 - Raycaster and Mouse Events</title>
6+
<title>24 - Custom model with Blender</title>
77
<link rel="stylesheet" href="./style.css">
88
</head>
99
<body>

src/script.js

Lines changed: 50 additions & 164 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import * as THREE from 'three'
22
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
33
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
4+
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOLoader.js'
45
import GUI from 'lil-gui'
56

67
/**
@@ -16,37 +17,55 @@ const canvas = document.querySelector('canvas.webgl')
1617
const scene = new THREE.Scene()
1718

1819
/**
19-
* Objects
20+
* Models
2021
*/
21-
const object1 = new THREE.Mesh(
22-
new THREE.SphereGeometry(0.5, 16, 16),
23-
new THREE.MeshBasicMaterial({ color: '#ff0000' })
24-
)
25-
object1.position.x = - 2
22+
const dracoLoader = new DRACOLoader()
23+
dracoLoader.setDecoderPath('/draco/')
2624

27-
const object2 = new THREE.Mesh(
28-
new THREE.SphereGeometry(0.5, 16, 16),
29-
new THREE.MeshBasicMaterial({ color: '#ff0000' })
30-
)
25+
const gltfLoader = new GLTFLoader()
26+
gltfLoader.setDRACOLoader(dracoLoader)
27+
28+
let mixer = null
3129

32-
const object3 = new THREE.Mesh(
33-
new THREE.SphereGeometry(0.5, 16, 16),
34-
new THREE.MeshBasicMaterial({ color: '#ff0000' })
30+
gltfLoader.load(
31+
'/models/hamburger.glb',
32+
(gltf) =>
33+
{
34+
scene.add(gltf.scene)
35+
}
3536
)
36-
object3.position.x = 2
3737

38-
scene.add(object1, object2, object3)
38+
/**
39+
* Floor
40+
*/
41+
const floor = new THREE.Mesh(
42+
new THREE.PlaneGeometry(50, 50),
43+
new THREE.MeshStandardMaterial({
44+
color: '#444444',
45+
metalness: 0,
46+
roughness: 0.5
47+
})
48+
)
49+
floor.receiveShadow = true
50+
floor.rotation.x = - Math.PI * 0.5
51+
scene.add(floor)
3952

4053
/**
41-
* Raycaster
54+
* Lights
4255
*/
43-
const raycaster = new THREE.Raycaster()
44-
let currentIntersect = null
45-
const rayOrigin = new THREE.Vector3(- 3, 0, 0)
46-
const rayDirection = new THREE.Vector3(10, 0, 0)
47-
rayDirection.normalize()
56+
const ambientLight = new THREE.AmbientLight(0xffffff, 2.4)
57+
scene.add(ambientLight)
4858

49-
// raycaster.set(rayOrigin, rayDirection)
59+
const directionalLight = new THREE.DirectionalLight(0xffffff, 1.8)
60+
directionalLight.castShadow = true
61+
directionalLight.shadow.mapSize.set(1024, 1024)
62+
directionalLight.shadow.camera.far = 15
63+
directionalLight.shadow.camera.left = - 7
64+
directionalLight.shadow.camera.top = 7
65+
directionalLight.shadow.camera.right = 7
66+
directionalLight.shadow.camera.bottom = - 7
67+
directionalLight.position.set(5, 5, 5)
68+
scene.add(directionalLight)
5069

5170
/**
5271
* Sizes
@@ -71,48 +90,17 @@ window.addEventListener('resize', () =>
7190
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
7291
})
7392

74-
/**
75-
* Mouse
76-
*/
77-
const mouse = new THREE.Vector2()
78-
79-
window.addEventListener('mousemove', (event) =>
80-
{
81-
mouse.x = event.clientX / sizes.width * 2 - 1
82-
mouse.y = - (event.clientY / sizes.height) * 2 + 1
83-
})
84-
85-
window.addEventListener('click', () =>
86-
{
87-
if(currentIntersect)
88-
{
89-
switch(currentIntersect.object)
90-
{
91-
case object1:
92-
console.log('click on object 1')
93-
break
94-
95-
case object2:
96-
console.log('click on object 2')
97-
break
98-
99-
case object3:
100-
console.log('click on object 3')
101-
break
102-
}
103-
}
104-
})
105-
10693
/**
10794
* Camera
10895
*/
10996
// Base camera
11097
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height, 0.1, 100)
111-
camera.position.z = 3
98+
camera.position.set(- 8, 4, 8)
11299
scene.add(camera)
113100

114101
// Controls
115102
const controls = new OrbitControls(camera, canvas)
103+
controls.target.set(0, 1, 0)
116104
controls.enableDamping = true
117105

118106
/**
@@ -121,128 +109,26 @@ controls.enableDamping = true
121109
const renderer = new THREE.WebGLRenderer({
122110
canvas: canvas
123111
})
112+
renderer.shadowMap.enabled = true
113+
renderer.shadowMap.type = THREE.PCFSoftShadowMap
124114
renderer.setSize(sizes.width, sizes.height)
125115
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2))
126116

127-
/**
128-
* Lights
129-
*/
130-
// Ambient light
131-
const ambientLight = new THREE.AmbientLight('#ffffff', 0.9)
132-
scene.add(ambientLight)
133-
134-
// Directional light
135-
const directionalLight = new THREE.DirectionalLight('#ffffff', 2.1)
136-
directionalLight.position.set(1, 2, 3)
137-
scene.add(directionalLight)
138-
139-
/**
140-
* Model
141-
*/
142-
const gltfLoader = new GLTFLoader()
143-
144-
let model = null
145-
gltfLoader.load(
146-
'./models/Duck/glTF-Binary/Duck.glb',
147-
(gltf) =>
148-
{
149-
model = gltf.scene
150-
model.position.y = - 1.2
151-
scene.add(model)
152-
}
153-
)
154-
155117
/**
156118
* Animate
157119
*/
158120
const clock = new THREE.Clock()
121+
let previousTime = 0
159122

160123
const tick = () =>
161124
{
162125
const elapsedTime = clock.getElapsedTime()
126+
const deltaTime = elapsedTime - previousTime
127+
previousTime = elapsedTime
163128

164-
// Animate objects
165-
object1.position.y = Math.sin(elapsedTime * 0.3) * 1.5
166-
object2.position.y = Math.sin(elapsedTime * 0.8) * 1.5
167-
object3.position.y = Math.sin(elapsedTime * 1.4) * 1.5
168-
169-
// Cast a fixed ray
170-
// const rayOrigin = new THREE.Vector3(- 3, 0, 0)
171-
// const rayDirection = new THREE.Vector3(1, 0, 0)
172-
// rayDirection.normalize()
173-
174-
// raycaster.set(rayOrigin, rayDirection)
175-
176-
// const objectsToTest = [object1, object2, object3]
177-
// const intersects = raycaster.intersectObjects(objectsToTest)
178-
179-
// for(const object of objectsToTest)
180-
// {
181-
// object.material.color.set('#ff0000')
182-
// }
183-
184-
// for(const intersect of intersects)
185-
// {
186-
// intersect.object.material.color.set('#0000ff')
187-
// }
188-
189-
// Cast a ray from the mouse
190-
// raycaster.setFromCamera(mouse, camera)
191-
192-
// const objectsToTest = [object1, object2, object3]
193-
// const intersects = raycaster.intersectObjects(objectsToTest)
194-
195-
// for(const intersect of intersects)
196-
// {
197-
// intersect.object.material.color.set('#0000ff')
198-
// }
199-
200-
// for(const object of objectsToTest)
201-
// {
202-
// if(!intersects.find(intersect => intersect.object === object))
203-
// {
204-
// object.material.color.set('#ff0000')
205-
// }
206-
// }
207-
208-
// Cast a ray from the mouse and handle events
209-
raycaster.setFromCamera(mouse, camera)
210-
211-
const objectsToTest = [object1, object2, object3]
212-
const intersects = raycaster.intersectObjects(objectsToTest)
213-
214-
if(intersects.length)
215-
{
216-
if(!currentIntersect)
217-
{
218-
console.log('mouse enter')
219-
}
220-
221-
currentIntersect = intersects[0]
222-
}
223-
else
224-
{
225-
if(currentIntersect)
226-
{
227-
console.log('mouse leave')
228-
}
229-
230-
currentIntersect = null
231-
}
232-
233-
// Test intersect with a model
234-
if(model)
129+
if(mixer)
235130
{
236-
const modelIntersects = raycaster.intersectObject(model)
237-
238-
if(modelIntersects.length)
239-
{
240-
model.scale.set(1.2, 1.2, 1.2)
241-
}
242-
else
243-
{
244-
model.scale.set(1, 1, 1)
245-
}
131+
mixer.update(deltaTime)
246132
}
247133

248134
// Update controls

static/models/.gitkeep

Whitespace-only changes.

static/models/Duck/README.md

Lines changed: 0 additions & 14 deletions
This file was deleted.
-118 KB
Binary file not shown.
-14.5 KB
Binary file not shown.
-10.1 KB
Binary file not shown.

0 commit comments

Comments
 (0)