2017-02-16 5 views
1

Мне нужно загрузить 3d-модель в мое приложение (это не игра, а не то, что она имеет какое-либо значение) и обнаружить, когда пользователь касается определенных частей этой модели, чтобы выполнить разные действия.Как обнаружить клики (касание) на определенных частях 3d модели?

Как я могу это сделать? Является ли это возможным?

+0

Не могли бы вы предоставить более подробную информацию об этих действиях? Это настоящее 3D-приложение, которое позволит модели свободно вращаться, и это позволит пользователю перемещаться по пространству 3D? Если да, то вы можете рассмотреть возможность использования OpenGL ES для Android. OpenGL - одна из фреймворков, которая делает возможным интерактивный 3D. После того, как вы установите OpenGL или какую-либо другую 3D-инфраструктуру, вы преобразуете 2D-точку касания к лучу в 3D-пространстве, а затем проверьте пересечения. Проверьте https://android-arsenal.com/tag/2 для рамки, которая выполняет большую часть работы для вас. OpenGL может быть немного грубо, чтобы учиться. – Rethunk

+0

Мне нужно одно действие, которое загружает трехмерную модель (в настоящее время загружает OBJ-файл), позволяет пользователю поворачивать эту модель вокруг своей оси (в центре экрана). Эта модель была разделена на несколько объектов в файле Blender перед экспортом в OBJ, тогда мне нужно было бы обнаружить взаимодействие на любом из этих разделенных объектов (dor, window, side mirror и т. Д.). В настоящее время я использую Rajawali, но это не является обязательным требованием. –

+0

Я отправлю ответ ниже, чтобы иметь больше места, но не стесняйтесь задавать больше вопросов в комментариях. У меня не будет времени копаться в Раджавали, но я могу описать в общих чертах, как подойти к проблеме. – Rethunk

ответ

0

Я не знаком с Rajawali, но GitHub описывает его как инфраструктуру OpenGL ES. Как вы описали его в комментарии выше, вам нужно будет рассмотреть два основных действия пользователя, и одно действие, которое я добавлю в качестве полезного:

  1. Проведите по экрану в определенном направлении: измените значение на X, измените Y.
  2. Прикоснитесь к некоторой (x, y) точке на экране с автомобилем в некоторой ориентации.
  3. (дополнительно) Масштабирование/уменьшение, чтобы облегчить пользователю выбор небольших функций, таких как боковые зеркала.

В зависимости от того, что OpenGL ES подробно раскрывает Rajawali, вам нужно сделать один или оба из следующих действий:

  • Узнайте о четырех матриц, которые определяют, как 3D-сцена визуализируется на 2D экран.
  • Найдите функции Rajawali с такими именами, как «lookAt» или «setViewpoint», и узнайте, как передавать информацию о жесткости экрана в эти функции.

Вы можете прочитать о четырех матрицах OpenGL в другом месте. Даже если Rajawali немного упрощает кодирование, вы должны немного узнать об этих матрицах. Хотя ваша первая наклонность заключается в изменении «модели» матрицы, которая влияет на положение и ориентацию объекта, более вероятно, что вы будете манипулировать матрицей «вид», которая определяет точку и направление в пространстве, из которого пользователь видит автомобиль. То есть, автомобиль фактически останется в центре (0,0,0), и пользовательские лапы, касания и щипцы изменят точку обзора.

Ограничительные движения, так что транспортное средство всегда центрировано, хорошо, потому что ваш код может быть немного проще, а также потому, что пользователь не может «потерять» автомобиль, сдвинув точку обзора слишком далеко в сторону.

Простейшим изменением точки зрения является масштабирование, которое в большинстве итераций означает просто изменение преобразования Z матрицы точек обзора. Rajawali может сделать это проще, предоставляя функции zoomIn() и zoomOut(). В противном случае вам нужно сделать, это:

  1. В обратном вызове или «обработчик событий», представленная Rajawali/Android для крайнего случая, получить щепотку в или пинче-ауте.
  2. Вызовите функцию ZoomIn() или RJawawali, если она существует. Скорее всего, вам нужно будет масштабировать значение, чтобы сумма пинчей соответствовала ожиданиям масштабирования и выключения модели автомобиля.
  3. В качестве альтернативы установите компонент преобразования Z в матрицу вида.

Преобразования (х, у) 2D сенсорного экрана точки луча, брошенный в 3D-пространство может быть сложен, если Rajawali не обеспечивает соответствующую функцию под названием что-то вроде «screenToWorld», который принимает точку в 2D пространстве экрана и 3D-точку или 3D-луч в мировом пространстве. Потратьте время на поиск «лучевого кастинга» для Rajawali.Вот краткий обзор того, что код должен будет делать:

  1. Преобразование 2D-точки касания в 3D-луч, направленный в экран.
  2. Проверьте пересечение (-ы) трехмерного луча и различные подобъекты.
  3. (необязательно) Измените цвет или иначе выделите выбранный объект.

OpenGL не обеспечивает функцию лучевого каста, и я не рекомендую ее применять самостоятельно, если у вас нет выбора. Различные функции, которые обертывают или дополняют OpenGL, могут обеспечить эту функцию. OpenGL кодеры будет придираться меня для этого описания, но из памяти вот как преобразовать 2D TouchPoint в 3D луч, указывая на экран:

  1. Получить сенсорную точку (х, у) 2D экрана от «потрогать» или «click» callback или обработчик событий в Rajawali или Android.
  2. Преобразование 2D-точки касания в трехмерную точку. Если я помню, это означает, что Z означает некоторое значение, такое как -1, 0 или 1. Это базовая точка луча.
  3. Определите вторую трехмерную точку с другим значением Z. Это дальняя точка луча.
  4. Используйте матрицы экрана, проекции и просмотра, чтобы превратить 3D-точки в «мировое» пространство.
  5. Учитывая координаты 3D-мира для вашей базовой точки и дальней точки, используйте пересечение луча-объекта, чтобы определить, какой объект пересечен.

Опять же, Rajawali может предоставить некоторую функцию, которая определяет, какие объекты пересекаются лучом. Если возвращаются несколько объектов, выберите ближайший объект. Поскольку ваш автомобиль уже разделен на несколько подобъектов, это не должно быть слишком сложным. Внедрение pinch-to-zoom может облегчить пользователю выбор небольшого объекта.

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

  1. От Android/Rajawali обработайте обработчик события или обратного вызова. Это аналогично функции «mouseMove».
  2. Перевести левый/правый саблей в отрицательное/положительное значение.
  3. Вызвать функцию rotateAboutY(), если она доступна, ИЛИ применить поворот к матрице точек обзора (которую я здесь не буду описывать).

Учитывая все, что я хотел бы предложить следующий подход:

  1. Смотрите, если Rajawali предоставляет удобные функции для преобразования координаты экрана в мире луча, чтобы преобразовать Размах экрана к повороту, и проверить пересечение лучей с рядом объектов.
  2. Даже если Rajawali предоставляет эти функции, немного прочитайте об низкоуровневом OpenGL ES внизу и четырех матрицах: экране, перспективе, точке обзора и модели.
  3. Если Rajawali не предоставляет функции удобства, найдите фреймворк, который делает ИЛИ видит, может ли какая-либо другая библиотека, которая работает с Rajawali, предоставить эти удобные функции.
  4. Если вы не можете изменить рамки или найти фреймворк, который скрывает грязные детали, планируйте потратить неделю или больше на изучение OpenGL. Вам, вероятно, не нужно знать о шейдерах, текстурах и т. Д., Но вам нужно будет понять пространство OpenGL 3D, четыре матрицы и т. Д.
+1

Благодарим вас за отличное объяснение. –

+0

Вы, безусловно, приветствуетесь. Надеюсь, ваш проект пройдет хорошо. – Rethunk