import './style.css'
import * as THREE from "three"
import {OrbitControls} from "three/examples/jsm/controls/OrbitControls.js"
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'
import * as dat from 'dat.gui'
const sizes = {
width: window.innerWidth,
height: window.innerHeight
}
//scene and camera
const scene = new THREE.Scene()
const camera = new THREE.PerspectiveCamera(45,sizes.width/sizes.height,0.1,1000)
camera.position.set(0,5,-5)
const sphereMesh = new THREE.Mesh(
new THREE.SphereGeometry(3),
new THREE.MeshStandardMaterial({
color: 0xffffff
})
)
scene.add(sphereMesh)
sphereMesh.position.set(-5,5,0)
sphereMesh.castShadow = true
const sphereMeshid = sphereMesh.id
//Light Sources
const ambientLight = new THREE.AmbientLight(0xffffff,1)
scene.add(ambientLight)
const directionalLight = new THREE.DirectionalLight(0xffffff,1)
scene.add(directionalLight)
directionalLight.position.set(-15,20,0)
directionalLight.shadow.camera.bottom = -10
directionalLight.castShadow = true
const spotLight = new THREE.SpotLight(0xffffff)
spotLight.castShadow = true;
scene.add(spotLight)
spotLight.position.set(-100, 70, 0)
//helpers
const axesHelper = new THREE.AxesHelper(20)
scene.add(axesHelper)
// const gridHelper = new THREE.GridHelper(30,20)
// scene.add(gridHelper)
// const dLightHelper = new THREE.DirectionalLightHelper(directionalLight)
// scene.add(dLightHelper)
// const dLightShadowHelper = new THREE.CameraHelper(directionalLight.shadow.camera)
// scene.add(dLightShadowHelper)
// const sLightHelper = new THREE.SpotLightHelper(spotLight)
// scene.add(sLightHelper)
//renderer
const canvas = document.querySelector('.webgl')
const renderer = new THREE.WebGLRenderer({canvas})
renderer.shadowMap.enabled = true
renderer.setSize(sizes.width,sizes.height)
renderer.setPixelRatio(window.devicePixelRatio)
renderer.render(scene,camera)
//Object Controls
const controls = new OrbitControls(camera,renderer.domElement)
controls.update()
//Meshes and Objects
//ChessBoard
var lightMaterial = new THREE.MeshStandardMaterial({color: 0xffffff})
var blackMaterial = new THREE.MeshStandardMaterial({color: 0x000000})
var cubeGeometry = new THREE.BoxGeometry(1,0.4,1)
var board = new THREE.Group()
for(let x=0; x<8; x++){
for(let z = 0; z<8; z++){
if(z%2 == false){
var cube = new THREE.Mesh(cubeGeometry, x%2 == false ? lightMaterial : blackMaterial) // column even , first square white
} else{
var cube = new THREE.Mesh(cubeGeometry, x%2 == false ? blackMaterial : lightMaterial) // column odd , first square odd
}
cube.position.set(x,0,z)
controls.target.set(x/2,0,z/2)
board.add(cube)
}
}
scene.add(board)
//Chessboard Scale
var boardScaleFactor = 1; // Change this value as needed
board.scale.set(boardScaleFactor, boardScaleFactor, boardScaleFactor)
const gltfLoader = new GLTFLoader()
gltfLoader.load("/assets/chess/chess.glb",(glb) => {
const models = glb.scene
gltfLoader._modelRepository = models
models.scale.set(1,1,1)
createPieces({row :8 , col: 8}, "polySurface1_Chass_0","White-Pawn")
}, undefined, (error) => {
console.error('error loading gltf model:', error);
});
// Create a new Box3 object
const boundingBox = new THREE.Box3();
// Iterate over the children of the board group to compute the bounding box
board.children.forEach(child => {
boundingBox.expandByObject(child);
});
function getBoardPosition(row,col,boundingBox){
const box = new THREE.Box3().setFromObject(board)
const size = box.max.x - box.min.x
const cellWidth = size/8
return{
x : col * cellWidth + cellWidth/2 - size/2,
z : row * cellWidth + cellWidth/2 - size/2
}
}
function createPieces(boardPos, pieceName, meshName) {
const mesh = gltfLoader._modelRepository.getObjectByName(pieceName);
mesh.name = meshName;
const posRC = getBoardPosition(boardPos.row,boardPos.col)
const pos = {x:posRC.x,y: 0.2, z:posRC.y}
const meshScaleFactor = 0.23
mesh.scale.set(meshScaleFactor,meshScaleFactor,meshScaleFactor)
mesh.position.set(pos.x,pos.y,pos.z)
scene.add(mesh);
}
//Event Listeners
window.addEventListener('resize', () => {
sizes.width = window.innerWidth
sizes.height = window.innerHeight
camera.aspect = sizes.width/sizes.height
camera.updateProjectionMatrix()
renderer.setSize(sizes.width,sizes.height)
controls.update()
renderer.render(scene,camera)
})
const mousePosition = new THREE.Vector2()
window.addEventListener('mousemove',(e) => {
mousePosition.x = (e.clientX/window.innerWidth) * 2 - 1
mousePosition.y = -(e.clientY/window.innerHeight) * 2 + 1
})
//raycaster
const rayCaster = new THREE.Raycaster()
const gui = new dat.GUI()
const options = {
planeColor: '#ffffff',
sphereColor: '#ffffff',
sphereWireframe : false,
sphereSpeed : 0.01,
angle : 0.1,
penumbra : 0,
intensity : 1
}
gui.addColor(options,'planeColor').onChange((e) => {
planeMesh.material.color.set(e)
})
gui.addColor(options,'sphereColor').onChange((e) => {
sphereMesh.material.color.set(e)
})
gui.add(options,'sphereWireframe').onChange((e) => {
sphereMesh.material.wireframe = e
})
gui.add(options,'sphereSpeed',0,0.01)
gui.add(options,'angle',0,1)
gui.add(options,'penumbra',0,1)
gui.add(options,'intensity',0,0.1)
//Animation Variables
let step = 0
//Animation Loop
const clock = new THREE.Clock()
const loop = () => {
const elapsedTime = clock.getElapsedTime()
window.requestAnimationFrame(loop)
controls.update()
// spotLight.angle = options.angle
// spotLight.penumbra = options.penumbra
// spotLight.intensity = options.intensity
// sLightHelper.update()
rayCaster.setFromCamera(mousePosition, camera)
const intersects = rayCaster.intersectObjects(scene.children)
console.log(intersects)
for(let i = 0; i<intersects.length; i++){
if(intersects[i].object.id === sphereMeshid){
intersects[i].object.material.color.set(0xff0000)
}
}
renderer.render(scene,camera)
}
loop()
The function getBoardPosition
returns object with elements {x,z}
.
However, in function createPieces
you use elements {x,y}
:
const posRC = getBoardPosition(boardPos.row,boardPos.col)
const pos = {x:posRC.x,y: 0.2, z:posRC.y}
// ↑
// see here
// try z:posRC.z
1 Like