Hi , Im a beginner in three.js and I have been trying to get my raycastor to give me coordinates of the objects it intersects but for some reason the raycaster never intersects the objects of the children of the scene. please give my code alook and let me know where im doing it wrong.
The code itself has gotten a bit messy , but i hope it is stilll understandable
import * as THREE from 'three'
import * as dat from 'dat.gui'
import { GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader.js'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import CANNON, { Sphere, World } from 'cannon'
import { DRACOLoader } from 'three/examples/jsm/loaders/DRACOloader.js'
import matVertex from './shaders/Mat/MatVertex.glsl'
import matFragment from './shaders/Mat/MatFragment.glsl'
import { gsap } from 'gsap'
import { Mesh, MOUSE } from 'three'
/**
* Debug Gui
*/
const gui = new dat.GUI()
//Sizes
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
/**
* rayCaster
*/
const raycaster = new THREE.Raycaster()
const mouse = new THREE.Vector2()
let mouseCoordinates = new THREE.Vector2()
let draggable = new THREE.Object3D();
/**
* query selector
*/
const loadingBarElement = document.querySelector('.loading-bar')
const canvas = document.querySelector('canvas.webgl')
// canvas.addEventListener('click', (event) => {
//
// mouseCoordinates.x = event.clientX
// mouseCoordinates.y = event.clientY
// mouse.x = (event.clientX/sizes.width)*2 - 1
// mouse.y = (event.clientY/sizes.height)*2 +1
// console.log(mouse)
// })
/**
* Physics World
*/
// world
const world = new CANNON.World()
//gravity
world.gravity.set(0,-9.82,0)
//Material
const concreteMaterial = new CANNON.Material('Concrete')
const elasticMaterial = new CANNON.Material('Elastic')
const plasticMaterial = new CANNON.Material('Plastic')
//Contact Material
const elasticPlasticContactMaterial = new CANNON.ContactMaterial(
elasticMaterial,
plasticMaterial,
{
friction:0.1,
restitution: 0.9,
}
)
const concretePlasticContactMaterial = new CANNON.ContactMaterial(
concreteMaterial,
plasticMaterial,
{
friction: 0.1,
restitution: 0.9
}
)
world.addContactMaterial(elasticPlasticContactMaterial)
world.addContactMaterial(concretePlasticContactMaterial)
//Sphere Shape
const sphereShape = new CANNON.Sphere(0.5)
//Sphere Body
const sphereBody = new CANNON.Body({
mass:1,
material: plasticMaterial,
position: new CANNON.Vec3(0,4,0),
shape: sphereShape
})
world.addBody(sphereBody)
//Plane
const floorShape = new CANNON.Plane()
const floorBody = new CANNON.Body(
)
floorBody.mass = 0
//floorShape.scale.set(1,1,1)
floorBody.material = concreteMaterial
floorBody.position = new CANNON.Vec3(0,-0.37,0)
floorBody.addShape(floorShape)
floorBody.quaternion.setFromAxisAngle(new CANNON.Vec3(-1,0,0), Math.PI *0.5)
//sphereBody.applyLocalForce(new CANNON.Vec3(100,0,-41), new CANNON.Vec3(0,0,0))
world.addBody(floorBody)
//Cube Trampoline
const cubeShape = new CANNON.Box(new CANNON.Vec3(1, 1, 1))
const cubeBody = new CANNON.Body({
mass: 0,
shape: cubeShape,
material: elasticMaterial,
position: new CANNON.Vec3(0,-1.05,0)
}
)
world.addBody(cubeBody)
//cube 1
const cubeBody1 = new CANNON.Body({
mass: 0,
shape: cubeShape,
material: elasticMaterial,
position: new CANNON.Vec3(4.5,-1.05,1.8)
}
)
world.addBody(cubeBody1)
// Scene
const scene = new THREE.Scene()
/**
* Loaders
*/
//Loading Manager
const loadingManager = new THREE.LoadingManager(
//Loaded
()=>
{
gsap.to(overlayMaterial.uniforms.uAplha, {duration: 3, value: 0})
loadingBarElement.classList.add('ended')
loadingBarElement.style.transform = ''
},
//Progress
(itemUrl, itemsloaded, itemsTotal)=>
{
const progressRatio = itemsloaded / itemsTotal
loadingBarElement.style.transform = `scaleX(${progressRatio})`
}
)
//TextureLoaders
const textureLoader = new THREE.TextureLoader(loadingManager)
//cube texture loader
const cubeTextureLoader = new THREE.CubeTextureLoader()
//Darco Loader
const darcoLoader = new DRACOLoader(loadingManager)
darcoLoader.setDecoderPath('draco/')
//GLTF
const gltfLoader = new GLTFLoader(loadingManager)
gltfLoader.setDRACOLoader(darcoLoader)
/**
* Textures
*/
const bakedTexture = textureLoader.load('bakedTexture.jpg')
bakedTexture.flipY = false
bakedTexture.encoding = THREE.sRGBEncoding
/**
* Materials
*/
//Baked Material
const bakedMaterial = new THREE.MeshBasicMaterial({map : bakedTexture })
//Pole Light Material
const parkLampMaterial = new THREE.MeshBasicMaterial({ color : 0xffffe5})
/**
* Model
*/
gltfLoader.load(
'GameScene.glb',
(gltf) =>
{
gltf.userData.name = 'scene'
gltf.scene.traverse((child) =>
{
child.material = bakedMaterial
})
const parkLampEmission = gltf.scene.children.find(child => child.name === 'ParkLampEmission')
const parkLampEmission1 = gltf.scene.children.find(child => child.name === 'ParkLampEmission1')
const parkLampEmission2 = gltf.scene.children.find(child => child.name === 'ParkLampEmission2')
const parkLampEmission3 = gltf.scene.children.find(child => child.name === 'ParkLampEmission3')
const parkLampEmission4 = gltf.scene.children.find(child => child.name === 'ParkLampEmission4')
const parkLampEmission5 = gltf.scene.children.find(child => child.name === 'ParkLampEmission5')
const parkLampEmission6 = gltf.scene.children.find(child => child.name === 'ParkLampEmission6')
const parkLampEmission7 = gltf.scene.children.find(child => child.name === 'ParkLampEmission7')
parkLampEmission.material = parkLampMaterial
parkLampEmission1.material = parkLampMaterial
parkLampEmission2.material = parkLampMaterial
parkLampEmission3.material = parkLampMaterial
parkLampEmission4.material = parkLampMaterial
parkLampEmission5.material = parkLampMaterial
parkLampEmission6.material = parkLampMaterial
parkLampEmission7.material = parkLampMaterial
gltf.scene.castShadow = true
scene.add(gltf.scene)
}
)
//Trampoline Loading
let mat,stands,frame = null
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
stands = gltf.scene.getObjectByName('Stands')
frame = gltf.scene.getObjectByName('Frame')
mat = gltf.scene.getObjectByName('Mat')
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.userData.name = 'Trampoline 1'
scene.add(gltf.scene)
}
)
//Bottom b/w shops from the left
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = 4
gltf.scene.position.z = 1.5
scene.add(gltf.scene)
}
)
//Bottom b/w shops from the right
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = 4
gltf.scene.position.z = -1.6
scene.add(gltf.scene)
}
)
//top b/w shops from the left
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = -4
gltf.scene.position.z = 1.6
scene.add(gltf.scene)
}
)
//top b/w shops from the right
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = -4
gltf.scene.position.z = -1.5
scene.add(gltf.scene)
}
)
//top on the road from the right
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = -2.3
gltf.scene.position.z = -4
scene.add(gltf.scene)
}
)
//top on the road from the left
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = -2.3
gltf.scene.position.z = 4
scene.add(gltf.scene)
}
)
//bottom on the road from the right
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = 2.3
gltf.scene.position.z = -4
scene.add(gltf.scene)
}
)
//bottom-left trampoline on the street
gltfLoader.load(
'trampoline.glb',
(gltf) =>
{
gltf.scene.scale.set(0.5,0.5,0.5)
gltf.scene.receiveShadow= true
gltf.scene.position.x = 2.3
gltf.scene.position.z =
scene.add(gltf.scene)
}
)
/**
* OverLay
*/
const overlayGeometry = new THREE.PlaneBufferGeometry(2,2,1,1)
const overlayMaterial = new THREE.ShaderMaterial({
transparent: true,
uniforms:
{
uAplha: { value: 1}
},
vertexShader: `
void main()
{
gl_Position = vec4(position, 1.0);
}
`,
fragmentShader:`
uniform float uAplha;
void main(){
gl_FragColor = vec4(0.0,0.0,0.10,uAplha);
}
`
})
const overlay = new THREE.Mesh(overlayGeometry, overlayMaterial)
scene.add(overlay)
/**
* Sphere Ball
*/
//geometry
const sphereGeometry = new THREE.SphereBufferGeometry(0.1,32,32)
//Material
const sphereMaterial = new THREE.MeshBasicMaterial({color:0x110000})
//Mesh
const sphere= new THREE.Mesh(
sphereGeometry,
sphereMaterial
)
sphere.castShadow = true
sphere.userData.draggable= true
sphere.userData.name= 'sphere'
sphere.position.set(0,0.5,0)
/**
* cube
*/
const cubeGeometry = new THREE.BoxBufferGeometry(1,1,1)
const cubeMaterial = new THREE.MeshBasicMaterial({color: 0xffffff})
const cube = new Mesh( cubeGeometry, cubeMaterial)
cube.position.y = -0.15
//cube.visible = false
cube.userData.draggable='true'
cube.userData.name= 'cube'
scene.add(cube)
scene.add(sphere)
/**
* Light
*/
const pointLight = new THREE.PointLight(0xffffff,2)
pointLight.position.y = 2
scene.add(pointLight)
window.addEventListener('resize',()=>
{
//Update Sizes
sizes.width = window.innerWidth
sizes.height = window.innerHeight
//Update Camera
camera.aspect = sizes.width/sizes.height
camera.updateProjectionMatrix()
//Update renderer
renderer.setSize(sizes.width,sizes.height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio,2))
})
//Camera
//const camera2 = new THREE.OrthographicCamera(75,sizes.width/sizes.height)
const camera = new THREE.PerspectiveCamera(75, sizes.width / sizes.height)
camera.position.z =0
camera.position.x = -6
camera.position.y = 7
camera.rotation.y= -Math.PI/2
camera.lookAt(sphere.position)
scene.add(camera)
//Renderer
const renderer = new THREE.WebGLRenderer({
canvas: canvas
})
renderer.setSize(sizes.width, sizes.height)
renderer.outputEncoding = THREE.sRGBEncoding
renderer.setClearColor(0x111111,1)
//Controls
const controls = new OrbitControls(camera,renderer.domElement)
/**
* Animate
*/
window.addEventListener('click', event =>{
mouseCoordinates.x = event.clientX
mouseCoordinates.y = event.clientY
mouse.x = (event.clientX/window.innerWidth)*2 - 1
mouse.y = (event.clientY/window.innerHeight)*2 +1
console.log(mouse)
raycaster.setFromCamera(mouse,camera)
const found = raycaster.intersectObjects(scene.children)
console.log(scene.children)
if (found.length > 0 && found[0].object.userData.draggable){
draggable = found[0].object
console.log(`found objects ${ draggable.userData.name}`)
}
})
//clock
const clock = new THREE.Clock()
let oldElapsedTime = 0
let time = 0
const tick = () =>
{
//Delta Time
const elapsedTime = clock.getElapsedTime()
const deltaTime = elapsedTime - oldElapsedTime
oldElapsedTime = elapsedTime
//update controls
controls.update()
// Update Renderer
renderer.render(scene, camera)
//Animation
window.requestAnimationFrame(tick)
}
tick()