Three.js - обработка повторного события на объекте


#1

Здравствуйте. Подскажите, как сделать в tree.js повторное выполнение события на том же объекте (по click). Первый раз событие выполняется, после нет. Вот код скрипта:

window.onload = function(){
var scene, camera, mesh;
var player = {height:1.7, speed: 0.2, turnSpeed:Math.PI*0.02};       
var raycaster;//
var width = window.innerWidth;
var height = window.innerHeight;
var canvas = document.getElementById('sal');
canvas.setAttribute('width', width);
canvas.setAttribute('height', height);		
var renderer = new THREE.WebGLRenderer({canvas: canvas, antialias: true});
renderer.setPixelRatio(window.devicePixelRatio * 1.5);
renderer.setSize(width, height);
renderer.setClearColor(0xfffeee);             
camera = new THREE.PerspectiveCamera(45, width/height, 0.1, 1000);
camera.position.set(0, player.height, -10);
camera.lookAt(new THREE.Vector3(0,player.height,0));
scene = new THREE.Scene();	
var amLight = new THREE.AmbientLight(0xffffff, 0.2);
scene.add(amLight);		
var meshFloor = new THREE.Mesh(
    new THREE.PlaneGeometry(10,10,10,10),
    new THREE.MeshPhongMaterial({color:0xf0f0f0, wireframe:false})
);
meshFloor.rotation.x -= Math.PI / 2;
meshFloor.receiveShadow = true;
scene.add(meshFloor);						
var cubeGeometry = new THREE.CubeGeometry(1, 1, 1);
var cubeMaterial = new THREE.MeshBasicMaterial({ color: 0xfff000 });
var cube = new THREE.Mesh(cubeGeometry, cubeMaterial);    
cube.rotation.y = Math.PI * 30 / 180;
cube.position.y = 0.5; 
scene.add( cube );    
function animate(){
requestAnimationFrame(animate);	
renderer.render(scene, camera);} animate();	
            function onWindowResize() {
		camera.aspect = window.innerWidth / window.innerHeight;
		camera.updateProjectionMatrix();
		renderer.setSize( window.innerWidth, window.innerHeight );
	}				
	var selectedObject = null;
	var open = function onDocumentMouseClick( event ) {
		event.preventDefault();
		var intersects = getIntersects( event.layerX, event.layerY );
		if ( intersects.length > 0 ) {
				selectedObject = intersects[0].object;					
				selectedObject.material.color.set( '#f00' );
				selectedObject.rotation.y = Math.PI * 10 / 180;											 
                    }									
	}		
	var raycaster = new THREE.Raycaster();
	var mouseVector = new THREE.Vector3();
	function getIntersects( x, y ) {
		x = ( x / window.innerWidth ) * 2 - 1;
		y = - ( y  / window.innerHeight ) * 2 + 1;
		z = 0.5;
		mouseVector.set( x, y, z );
		raycaster.setFromCamera( mouseVector, camera );
		return raycaster.intersectObject( cube, true );
	}    		
    canvas.addEventListener( 'resize', onWindowResize, false );
    canvas.addEventListener( "click", onDocumentMouseClick, false );}

#2

Впредь делись кодом так чтобы его можно было взять и запустить. А то сложно переносить все в jsfiddle вручную.

https://jsfiddle.net/n4cjL1xs/

Код выполняется без ошибки. Единственное что я убрал присвоение в переменную open в этой строке
var open = function onDocumentMouseClick

Функция обработки клика выполняется вызови console.log или alert из функции обработчика клика чтобы убедиться. Просто результат ее работы одинаковый при каждом последующем клике.


#3

Уважаемый dmitry. Я знаю, что код выполняется. Но он выполняется только один раз при первом клике на объекте. При втором клике ничего не происходит. В скрипте есть строка для поворота объекта при клике:
selectedObject.rotation.y = Math.PI * 10 / 180;
Поворот происходит при первом клике. Мне нужно чтобы при повторном клике объект также выполнял поворот и при последующих кликах также. (Или выполнял другое действие, которое я пропишу)


#4

Мы тут свободноб общаемся на “ты”. Считай как в компании людей объединенными интересом. Но если тебе удобнее использовать другие формы - без проблем.

Просто я дотошен к формулировке:

код выполняется повторные разы, просто результат выполнения всегда одинаковый. Код корректен и выполняет именно то что в нем описано. Поймешь эту ситуацию, проще будет добавлять другие действия.

Более точно вопрос был бы сформулирован таким образом “вот код, ожидаю что когда буду кликать несколько раз по объекту, тот будет вращаться, но вращается только при первом клике”.

А теперь по поводу проблемы: чтобы объект вращался, значение поворота должно быть разным при последующих кликах. Значит надо где-то “аккумулировать” знание о текущем повороте.

Я ввел переменную rot, использую ее для вычисления значения поворота и меняю ее значение при каждом клике. Получается новое значение при каждом клике и объект вращается.

https://jsfiddle.net/p09k8hje/


#5

Спасибо за указанный путь к решению задачи. Я неверно истолковывал понятие “rotation”. Я воспринимал это как угол поворота движения (динамика). Но в данном случае это понятие означает не вращение (поворот), а положение объекта в пространстве (статика).
“Правильно заданный вопрос - это на 90% ответ”
Еще раз спасибо.