20 Мая 2024, 06:57:59
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.

Навигация по форуму







guest3d
Quest3D - Русскоязычное сообщество > Quest3D > Программирование > ColladaImport и DetecMouseCollision
ColladaImport и DetecMouseCollision
(Прочитано 16002 раз)
  [1] 2
Печать
Deepl | * | Новичок | Сообщений: 18 | « 13 Сентября 2010, 15:22:35 »
ColladaImport и DetecMouseCollision |
0
Добре, Уважаемые.
Подскажите как заставить вставленный с помощью ColladaImport объект работать с DetecMouseCollision.

Буду чрезвычайно благодарен!
Deepl | * | Новичок | Сообщений: 18 | «Ответ #1 16 Сентября 2010, 19:17:48 »
Re: ColladaImport и DetecMouseCollision |
1
Неужели у местных Гуру нет никаких идей??
Deepl | * | Новичок | Сообщений: 18 | «Ответ #2 28 Сентября 2010, 20:09:35 »
Re: ColladaImport и DetecMouseCollision |
2
Ну, что же. Я решил проблему. Судя по количеству просмотров и количеству ответов - всем интересно и никто не знает. Если надо - могу приблизительно написать как, что и куда. не знаю насколько академически правильно, но это работает.
DimiS | **** | Старожил | Сообщений: 284 | «Ответ #3 29 Сентября 2010, 10:10:02 »
Re: ColladaImport и DetecMouseCollision |
3
наливай  Подмигивающий
Deepl | * | Новичок | Сообщений: 18 | «Ответ #4 29 Сентября 2010, 15:53:11 »
Re: ColladaImport и DetecMouseCollision |
4
Итак, как же заставить работать DetectMouseCollision, который работает с 3D Object(и только с ним), когда у нас есть разрозненный пакет данных, полученный в результате работы ColladaImport? В принципе, ответ я уже написал. Надо сделать из полученных данных 3D Object. Все проще пареной репы, приступим.
Работать будем с ОО системой квеста.

Теперь по пунктам с картинками:
1. Изучим, что же мы получаем благодаря ColladaImport:
У нас три класса:
a. cImportObject
b. cImportSurface
c. cImportTexture

в а. формально хранится вся информация, необходимая для создания объекта:
- ImportObject (так и не понял что в нем хранится, но обошелся и без него)
- MotionSet(грубо говоря, это список матриц объекта. используется если объект анимирован. Я не пользовался, т.к. объекты у меня без анимации)
- Normalized Matrix(матрица объекта. Положение, ориентация и масштаб объекта в пространстве. Грубо говоря тот самый Motion).
- Surfaces(Интересная штука. Это OO_Container. Т.е. такая штука, которая содержит множество ОО_Instances. Другими словами, это такой массив в котором содержаться... Внимание!.. ...объекты класса cImportSurface!

В b. Формально хранится вся инфа для создания поверхности:
- Diffuse(Цвет диффуза)
- Emissive(цвет самосвечения)
- Object Data(собственно инфа о вершинах)
- Specular(блеск)
- SpecularPower(сила блеска)
- TextureList(опять же СПИСОК! ClassInstanceContainer объектов класса сImportTexture)

В c. Тут хранится вся информация, необходимая для создания ноды Texture.
- Texture

Таким образом получается следующая иерархия:
cImportObject -> cImportSurface -> cImportTexture

Я намеренно упустил из описания класса cImportSurface один пункт - функцию Draw. Эта функция прорисовывает все поверхности, используя матрицу объекта, получая ее из внешнего параметра-матрицы World.

А теперь давайте посмотрим какие входы есть у ноды 3D Object:
- Matrix (Положение, ориентация и масштаб объекта в пространстве. Грубо говоря тот самый Motion. Обязательная нода)
- Offset Matrix(Дополнительная матрица, которая накладывает свое действие на основную. Другими словами таким образом можно "Припарентить" объект к другому. Не обязательна)
- Surface(Данные о поверхности. Нода множественная и обязательная. Сюда подключается информация о всех поверхностях, составляющих объект)
- Draw object (рисует объект или нет)

Таким образом для создания объекта нам необходимы всего два входа: Matrix и Surface.

Matrix у нас есть. Нет ноды Surface. Зато есть данные для создания этого сюрфейса. Ну, так вперед!

В интерфейсе iImportSurface Содаем новую функцию MakeSurface  типа Channel->Surface:
www.avdeevk.ru/3qdLess/001.jpg
http://www.avdeevk.ru/3qdLess/002.jpg
http://www.avdeevk.ru/3qdLess/003.jpg
Убеждаемся что все точно как у меня.
http://www.avdeevk.ru/3qdLess/004.jpg

Обратите внимание что в поле Target стоит Target not found!
Это означает, что у этой функции есть объявление, но нету исполняемой части. Теперь эту часть и надо сделать.

Нажмите кнопку F2 на клаве, переведя Quest в режим Dual ChannelGraph. В верхней части выберите OO Editor, в нижней группу OO 3D Object Template. И просто перетащите функцию MakeSurface сверху из OO Editor'a в ChannelGraph внизу.
Получите следующее:
http://www.avdeevk.ru/3qdLess/005.jpg
Сверху нода Surface, а снизу указатель на то от какого элемента класса надо брать параметры diffuse, emissive и т.д. Вы же помните, что поверхностей в объекте может быть много, следовательно у каждой из них будут свои параметры.
Именно для этого и служит нода THIS.

Теперь надо перетащить в ChannelGraph необходимые параметры. Делается это следующим образом. Откройте закладку ProjectTree.

Раскройте папку Include, в ней раскройте группу OO 3D Object Template. Внутри которой раскройте класс cImportSurface и увидите все параметры и функции, присутствующие в этом классе.
http://www.avdeevk.ru/3qdLess/006.jpg
http://www.avdeevk.ru/3qdLess/007.jpg
Перетащите из этого списка в ChannelGraph следующие параметры:
- Diffuse
- Emissive
- Specular
- SpecularPower
- ObjectData
TextureList перетаскивать не надо, т.к. для коллизии с мышью нас текстуры мало интересуют.

Получите следующий набор:
http://www.avdeevk.ru/3qdLess/008.jpg
Важный момент: у каждого из параметров снизу есть вход под названием OOClassInstance. Сюда надо подключить нашу ноду THIS, указывающую на то, параметры какого представителя класса(в данном случае поверхности) нас интересуют. Поэтому присоедините THIS ко всем параметрам:
http://www.avdeevk.ru/3qdLess/009.jpg
Также создайте новую ноду Material, удалите у нее всех Child'ов и подсоедините к ней наши соответствующие параметры:
http://www.avdeevk.ru/3qdLess/010.jpg
а затем к главной ноде подсоедините ноды ObjectData и Material.
http://www.avdeevk.ru/3qdLess/011.jpg
Вот и готова функция создания поверхности.

Для проверки DetecMouseCollision создадим функцию CheckMouseCollision.
Эта функция будет заниматься только одним: менять значение параметра MouseOver с 0 на 1, если мышь над этим объектом.
Первоначальные действия примерно такие же:
1. добавляем в интерфейс iImportObject параметр типа Value с именем MouseOver.
2. добавляем в интерфейс iImportObject функцию CheckMouseCollision, оставляя стандартный ChannelCaller.

 Назовем ее CheckMouseCollision.
http://www.avdeevk.ru/3qdLess/013.jpg
Перетащим новую функцию в ChannelGraph прямо из этого списка.

Нет времени дальше так подробно расписывать. Вот вся функция с описанием блоков:
красная рамка: Логика функции. Если есть коллизия -> параметр MouseOver=1, если нет параметр MouseOver=0.

Синяя рамка: По идее должен быть цикл. Но цикл работать так и не захотел. Все время выдавал одну поверхность объекта, а не все. Поэтому я забил в проекте 20 таких штук. По идее должно хватить.

Зеленая рамка. Решение некой корявости NormilizedMatrix в ColladaImport. т.е. я просто пересоздаю матрицу заново. В своем проекте сделал это при импорте.
http://www.avdeevk.ru/3qdLess/014.jpg
Теперь самое интересное: У меня нода 3D Object соединена с главной нодой. Это дает возможноть увидеть объект для коллизи во вьюпорте. т.е. так как это объект он начинает визуализироваться. Очень удобно для дебага.

Теперь как это все вписывается и где вызывается:
http://www.avdeevk.ru/3qdLess/015.jpg

Пояснения:
Красная рамка вызов функции.
Зеленая рамка: изменеие в алгоритме рендеринга. Вместо матрицы World мы подставляем матрицу NormiliaedMatrix нашего объекта.

Все работает. Можно убедиться, запустив прогу и перейдя в группу OO 3D Object Template.

А еще лучше сделав функцию HighLight в классе cImportObject
Типа Этой:
http://www.avdeevk.ru/3qdLess/015.jpg

В зеленой рамке у меня параметр функции цвета. Если непонятно, можно заменить на ValueVector со значениями RGB.

Вот ссылка на проект без Функции HighLight.
http://www.avdeevk.ru/3qdLess/less.zip

Спасибо за внимание. Извините, что не расписал полностью - начальник пришел ))

Задавайте вопросы.

У меня заодно вопрос. Можно ли как-то отследить у FileDialog была нажата кнопка ОК или Отмена?
andkash | * | Новичок | Сообщений: 11 | «Ответ #5 28 Октября 2010, 01:35:10 »
Re: ColladaImport и DetecMouseCollision |
5
 Шокированный Ух... Даже не думал, что в простейшем действии скрывается такая сложность.
Как раз это мне сейчас и надо было применить. Надо чтоб при наведении мышки всплывало название элемента. Помнится в cult3d это делалось на раз.
Я приложил пример файлика:
http://narod.ru/disk/26654493000/2.4.3.rar.html

Там всё сделано как надо, за исключением текста, который реагирует на целый объект, а надо, чтоб реагировал каждый элемент отдельно.

Можно ли сделать это как-то проще, или надо разбираться с OO? У меня пока получается, что если я использую разложение на отдельные объекты, они у меня накладываются все в кучу. А потом собирать их и выстраивать, чёт как-то не хочется.

Посоветуете что-нибудь?
Deepl | * | Новичок | Сообщений: 18 | «Ответ #6 28 Октября 2010, 11:04:20 »
Re: ColladaImport и DetecMouseCollision |
6
Да, ничего особо сложного нет, просто пытался расписать наиболее развернуто. Видимо не получилось.

Не совсем понял вашу задачу. У вас при динамической загрузке должно все происходить? Т.е. вы прямо из своего скомпилированного приложения загружаете модель, потом наводите на каждую поерхность и получаете разные подсказки? Потом загружаете другую модель и получаете другие подсказки?
Тут да, придется малость попариться и да, без ОО не обойтись.

Или у вас модель сначала импортируется в квест? Т.е. динамической загрузки не будет? Если так, то это очень просто.
1. Загружаете модель с несколькими элементами.
2. Подключаете ее к рендеру и т.д. - она начинает отображаться в сцене.
3. На каждый элемент делаете свой 3D Object и подключаете туда матрицу объекта и Surface соответствующего элемента.
4. К каждому объекту подключаете DetectMouseCollision - получается что при наведении на какой-то элемент в соответствующем ему DetectMouseCollision вы получаете 1.
5. Воспользовавшись каналами Trigger или ChannelSwitch спокойно реализуете необходимый функционал.
andkash | * | Новичок | Сообщений: 11 | «Ответ #7 28 Октября 2010, 13:44:30 »
Re: ColladaImport и DetecMouseCollision |
7
У меня как в предложеном файлике, без динамической загрузки. Сейчас попытался посоздавать объекты внутри, вроде работает, но как-то странно - если объекты перекрываются друг другом, названия всплывают всех наложенных друг на друга объектов, курсор "видит" их насквозь.
А можно как-то сделать, чтоб название отображалось только у объекта на переднем плане?
Sqwer | ***** | Ветеран | Сообщений: 540 | «Ответ #8 28 Октября 2010, 15:55:50 »
Re: ColladaImport и DetecMouseCollision |
8
Есть  несколько вариантов   решения сей проблемы:

1) определять расстояние от объекта до камеры , и из всех   объектов, прошедших тест на пересечения луча (маус дэтекшн) выбирать ближайший к камере  (самый простой)

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

3) это гибрид 1 и 2 методов , сперва  находим массив   объектов по пункту 1,  а затем их отрисовываем , после чего вступает в силу  алгоритм 2.
andkash | * | Новичок | Сообщений: 11 | «Ответ #9 28 Октября 2010, 18:21:47 »
Re: ColladaImport и DetecMouseCollision |
9
Вот первый вариант видится приемлемым, но, тем не менее не понятным. Чем определять расстояние? Ну и замороченная же прога!
Sqwer | ***** | Ветеран | Сообщений: 540 | «Ответ #10 28 Октября 2010, 20:01:12 »
Re: ColladaImport и DetecMouseCollision |
10
Есть матрица камеры? - есть
Есть матрица объекта?  - есть

следовательно можно  получить    мировые координаты  в векторной форме  как  камеры так и   объекта
команда TranslationMatrix


после ничего не состовляет труда  узнать расстояние между векторами

заносим все значения в массив   и сортируем  , что ближе - то и выбираем.
* StartGroup.rar (248.14 Кб - загружено 583 раз.)
andkash | * | Новичок | Сообщений: 11 | «Ответ #11 28 Октября 2010, 20:24:20 »
Re: ColladaImport и DetecMouseCollision |
11
Спасибо большое, попробую разобраться.
Ruslan | ***** | Ветеран | Сообщений: 664 | «Ответ #12 28 Октября 2010, 20:41:15 »
Re: ColladaImport и DetecMouseCollision |
12
+ есть еще способ:
ValueOperator -> Get distance to camera (matrix))
на вход подаешь матрицу объекта, на выходе получаешь расстояние от объекта до активной камеры.

Цитировать
Ну и замороченная же прога!
нормальная прога!, только вначале разобраться в ней нужно.   Показает язык
« Последнее редактирование: 28 Октября 2010, 20:44:32 от Ruslan »
Deepl | * | Новичок | Сообщений: 18 | «Ответ #13 28 Октября 2010, 21:41:48 »
Re: ColladaImport и DetecMouseCollision |
13
Вообще, пользоваться матрицами не самый лучший способ.
Представь, что в одной точке находится огромный шар и маленький куб.
А еще лучше, длиииииный параллелепипед и сфера. Матрицы - одинаковые. А конец параллелепипеда к нам ближе. )
Ruslan | ***** | Ветеран | Сообщений: 664 | «Ответ #14 28 Октября 2010, 21:46:45 »
Re: ColladaImport и DetecMouseCollision |
14
Цитировать
Вообще, пользоваться матрицами не самый лучший способ.
зато быстрый..
в случае, когда объекты в одной позиции и разного размера, можно учитывать к дистанции еще и ААББ объектов
 
  [1] 2
Печать
 
Quest3D - Русскоязычное сообщество > Quest3D > Программирование > ColladaImport и DetecMouseCollision
Перейти в: