3

Я пытаюсь создать 3D-просмотрщик для создания моделей. Мы загрузили модель и пытаемся сделать какое-то взаимодействие с моделью. Поэтому мы используем OrbiControls для вращения, панорамирования и масштабирования модели.Элементы управления орбиты ThreeJS устанавливают цель без lookAt

Мы хотим, чтобы поведение в телезрителе показывало, что когда пользователь нажимает и перетаскивает (поворачивая таким образом), центр вращения находится в точке здания, где пользователь нажимает.

Я думал, что был мудр, изменив цель на OrbitControl как таковой:

control.target.set(newX, newY, newZ); 

Однако то, что я нашел в источнике файла OrbitControl.js, является то, что, когда обновления управления, то

camera.lookAt() 

функция вызвана, что приводит к переходу камеры в новое положение.

Есть ли способ обойти это? Я пробовал уже несколько часов, и ничего не работало.

Попробуй изменить цель0, а затем вызвать reset() на элементе управления. попытался также изменения камеры обратно в прежнее положение (это может быть, как его сделать, но я бы попробовал это плохо

+1

Вы решили это? :) –

+0

Нет, у меня нет –

+0

Думаю, я могу решить это для вас, если вы все еще заинтересованы, но я просто хочу понять ваш предполагаемый результат. Если пользователь нажимает на сторону здания, вы хотите, чтобы центральная точка элементов управления стала ближайшей точкой на сетке, которая была нажата? Или центральной точкой сетки здания, которое было нажато? Кто это, или я неправильно понял? –

ответ

0

Попробуйте это:.

Сначала установите положение элемента управления:

control.center.set(0, 0, 0); 

Тогда сделайте это:.

camera.position.copy(control.center).add(new THREE.Vector3(x, y, z+10)); 

где х, у и г является положение модели здания

Примечание. Я добавил +10 в z, чтобы камера находилась перед моделью. Измените значение +10 на какое-то другое значение, чтобы приблизить/отойти от модели.

+0

Привет, спасибо за отзыв, но это было не совсем то, что я хотел. Вы устанавливаете положение камеры в точке, на которую нажимаете, и контрольные объекты нацелены на 0,0,0. Тем не менее, я хочу, чтобы положение камеры изменилось, и только цель элементов управления обновиться! –

+0

Как насчет, вместо control.target.set (newX, newY, newZ); сделайте это: control.center.set (newX, newY, newZ); – TheWebDesignerPro

0

Есть ли способ обойти это?

Короткий ответ: «Да, но он не использует стандартную версию OrbitControls.js».

читать для моего подробного рассуждения ....

Я только что провел некоторое время, глядя на исходный код OrbitControls.js (R87) рассматривает идею внедрения аксессуара, который позволит вам обеспечить дополнительный 2-й пункт, который он будет использовать в качестве цели камеры.

Однако, после изучения кода, я думаю, что это будет плохая функция для добавления к стандартной общедоступной версии. Есть много особенностей OrbitControls, таких как способность ограничивать угол обзора, минимальное и максимальное вращение и расстояние между долями, которые предполагают, что камера и центр орбиты одинаковы. Если бы был вариант 2-й камеры, это все нужно было бы изменить, чтобы использовать либо центр орбиты, либо цель камеры, либо иметь настраиваемый параметр, который переключает ту, которую он использует. Это добавит сотни лишних строк кода, что усложнит понимание, и все это будет иметь очень нишу.

Итак ... Решение:

Поскольку вы строите технический инструмент, я подозреваю, что вы не заботитесь о ограниченный угол обзора, расстояния или вращения, так что если бы я тебя, я бы скопировать OrbitControls.js в ваш проект, переименовать его в OrbitControls_customised.js и внести изменения вам необходимо:

Добавить 2 новые параметры ниже this.target называемые this.cameraTarget и this.coupleCenters

// "target" sets the location of focus, where the object orbits around 
this.target = new THREE.Vector3(); 

// "cameraTarget" is where the camera is looking (by default the same as target 
this.cameraTarget = new THREE.Vector3(); 

// Whether the camera should be locked to the orbit center 
this.coupleCenters = true; 

А на линии, где он инструктирует камеру, чтобы посмотреть на центр ...

scope.object.lookAt(scope.target); 

... изменить его так, что только обновляет камеру, когда coupleCenters правда ...

if(scope.coupleCenters){ 
    scope.cameraTarget = scope.target; 
} 
scope.object.lookAt(scope.cameraTarget); 

Теперь, с внесенными вами изменениями, вы можете поместить событие onMouseDown, которое использует RayCasting, чтобы найти точку на вашем объекте, устанавливает controls.decoupleCenters в false и устанавливает controls.target на пересекающуюся/пересекающую точку raycast. Затем событие onMouseUp, которое устанавливает controls.target назад на controls.cameraTarget, чтобы позволить ему вести себя как обычно.

Надеюсь, что это ответит на ваш вопрос и даст вам приблизительную дорожную карту для работы.

+0

Мартин, спасибо за отличный учебник. Я займусь этим коротко и вернусь к вам –

 Смежные вопросы

  • Нет связанных вопросов^_^