Я вижу несколько неправильных вещей.Я не могу сказать, является ли это тем, что вы пропустили разделы своего кода.
Во-первых, предоставленный вами код не определяет ни геометрию, ни материал.Вы подразумевали, что рисуете куб для каждого результата БД, поэтому я сделаю предположение и использую BoxBufferGeometry
.У вас также не определены источники света, поэтому я просто буду использовать MeshBasicMaterial
, который не нуждается в источниках света.
С этими исключениями кажется, что вы на полпути к настройкеЦикл рендеринга с использованием window.requestAnimationFrame
, но вы все равно вызываете render
только один раз, даже если выборка БД асинхронна.Другими словами, рендеринг может произойти еще до того, как вы получите ответ от вашей БД, поэтому вы ничего не увидите.Я добавил некоторый шаблонный код для настройки цикла рендеринга, аналогично тому, как Three.js делает в своих примерах.
Интересно, что это было все, что потребовалось.Raycaster начал работать, и я смог утешить результаты.Я получил несколько ложных срабатываний, когда сцена впервые начала рендеринг, но это потому, что еще не было никакого ввода мышью, поэтому это было лучевое вещание с середины экрана (там, где существует первый куб).
Обычно, вы не хотели бы получать raycast для каждого кадра, но я понимаю, что ситуация с виртуальной реальностью может быть разной (чертовски суетливые люди).
Наконец, одно из последних изменений, которое я сделал, - дать каждому кубу свой материал.(ну клоны оригинала).Это было необходимо для того, чтобы вы могли передавать лучи против каждого отдельно.
// Need to create geometry and material
var geometry = new THREE.BoxBufferGeometry(0.5, 0.5, 0.5);
var material = new THREE.MeshBasicMaterial({
color: "green"
});
var renderer, scene, container, camera;
var controls, group;
var raycaster = new THREE.Raycaster();
var mouse = new THREE.Vector2();
init()
function onMouseMove(event) {
// calculate mouse position in normalized device coordinates
// (-1 to +1) for both components
mouse.x = (event.clientX / window.innerWidth) * 2 - 1;
mouse.y = -(event.clientY / window.innerHeight) * 2 + 1;
}
function init() {
// init renderer
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
// document.body.appendChild( renderer.domElement );
container = document.getElementById('container');
container.appendChild(renderer.domElement);
// init scene
scene = new THREE.Scene();
scene.background = new THREE.Color(0xffffff);
group = new THREE.Group();
scene.add(group)
//fetch data from database and add object for each entry
getData()
async function getData() {
/**
* @author TheJim01
* Replacing DB call with fake data to make it work here.
* Nancy: Please feel free to add appropriate data.
*/
// var response = await fetch('/api/indexvr');
// var data = await response.json();
var data = [{}, {}, {}, {}, {}]
//console.log(data)
for (var i = 0; i < data.length; i++) {
cube = new THREE.Mesh(geometry, material.clone());
cube.position.x = i;
scene.add(cube);
//group.add(data)
}
}
// init camera
camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(15, 15, 15); //camera.position.set( 5, 0, 10 );
camera.lookAt(scene.position);
// controls = new OrbitControls( camera, renderer.domElement );
// controls.enableRotate = true;
}
function render() {
// update the picking ray with the camera and mouse position
raycaster.setFromCamera(mouse, camera);
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObjects(scene.children);
if (intersects.length > 0) {
console.log(intersects);
}
for (var i = 0; i < intersects.length; i++) {
intersects[i].object.material.color.set(0xff0000);
}
renderer.render(scene, camera);
}
window.addEventListener('mousemove', onMouseMove, false);
// Here's the bbasic render loop implementation
function animate() {
requestAnimationFrame(animate);
render();
}
animate();
html,
body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/108/three.min.js"></script>
<div id="container"></div>