Блог Александра Божко
Архивы
Рубрики
Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

Обещанный пост, посвященный использованию импортированых моделей. Я уже затрагивал эту тему ранее, однако, здесь осталось достаточное количество открытых вопросов. В частности, на днях я получил письмо примерно следующего содержания:

“…какими свойствами определяются координаты поверхностей и условно центра фигуры после загрузки произвольного объекта DAE в Model3D во время исполнения программы? Т.к. даже центр объекта далеко не всегда совпадает с центром модели…”

Собственно, данный вопрос давно интересовал меня самого. Использование моделей, созданных во внешних 3D редакторах – мощный инструмент. Но для того, что бы он стал действительно полезным, нам необходимо правильно расположить модель на форме. Это не всегда просто сделать даже в режиме проектирования, не говоря уже о RunTime.

Google SketchUp 8

Google SketchUp 8

И, для того, чтобы  разобраться с данным вопросом, я решил провести несколько экспериментов. Для создания модели я использовал Google SketchUp 8, основное преимущество которого – бесплатность. Я  уже упоминал об этом редакторе ранее.

Прежде всего, в SketchUp я создал куб размером с длинной каждой из сторон – 1М. Очевидно, что работа с любым 3D редактором требует определенной сноровки. Некоторое время мне пришлось потратить на то, что бы найти и изучить описания основ работы со SketchUp. Ниже приведены 2 рисунка, иллюстрирующие данный процесс.

sketchup_cub1

sketchup_cub2

На данном этапе я не стал создавать объект, а просто сделал экспорт в формат COLLADA (расширение файла .dae), поддерживаемый FireMonkey. COLLADA — это формат, разработанный для обмена между 3D приложениями.  COLLADA использует открытый стандарт XML для обмена форматами. Спецификация, документация, примеры приведены на официальном сайте.

Конечная цель примера заключается в том, что бы в FireMonkey 3D форме получить модель куба, определенного размера на определенной позиции. Я использовал компонент TModel3D, разместив его в центре формы (Position.X =0; Position.Y =0; Position.Z =0;). Загрузив в MeshCollection нашу COLLADA модель, эмпирическим путем я подобрал значение свойства scale таким образом, что бы длины сторон импортированного куба были равны единице. Естественно, для этого я использовал компонент TCube, поскольку непосредственно узнать размер импортированной модели не представляется возможным.

model

На рисунке компонент TCube – розовый куб, импортированная модель – черный куб.

Фрагмент .fmx файла (аналог dfm для FireMonkey) выглядит так:

object Model3D1: TModel3D
Scale.Point = ‘(0.025000000372529,0.025000000372529,0.025000000372529)’
Width = 1.000000000000000000
Height = 1.000000000000000000
Depth = 1.000000000000000000
Opacity = 1.000000000000000000
Quanternion = ‘(0,0,0,1)’
Data = {
17005450463005544D65736800064C6F636B6564090557696474680500000000


5175616E7465726E696F6E060928302C302C302C31290000}
end
object Cube1: TCube
Width = 1.000000000000000000
Height = 1.000000000000000000
Depth = 1.000000000000000000
Opacity = 1.000000000000000000
ZWrite = False
Material.Diffuse = claSandybrown
Material.Ambient = claBlack
Material.Emissive = claPlum
Material.Specular = claCornflowerblue
Quanternion = ‘(0,0,0,1)’
end

Как видно из кода и рисунка, для того, что бы куб с размерами сторон 1М, импортированый из SketcUp был одного размера с кубом TCube, свойства Depth, Height и Width которого равны 1, масштаб (свойство Scale) модели должен быть 0.025. Кроме того, следует учесть, что если для компонента TCube свойство Position определяет координаты условного центра фигуры, то для модели это свойство определяет центр компонента TModel3D. Понятно, что в данном случае, он не будет соответствовать центру фигуры. Поскольку в SketcUp модели в  точке начала координат у нас был угол куба, то в центре компонента TModel3D у нас тоже окажется угол куба. Координаты же противоположного угла будут {1,1,1}, как и в исходной модели. Хотя визуально куб будет повернут в другую сторону, это связано с тем,  что оси координат в SketchUp и в FireMonkey расположены по разному.

imported_collada_model

Таким образом, для того, что бы программно импортировать COLLADA модель в FireMonkey мы можем использовать следующий код:

var
MI: TDAEModelImporter;
ImSe: TModelImportServices;
AMesh: TMeshDynArray;
begin

Model3D1.Scale.X:=0.025;
Model3D1.Scale.Y:=0.025;
Model3D1.Scale.Z:=0.025;
Model3D1.Clear;

MI:=TDAEModelImporter.Create;
ImSe:=  TModelImportServices.Create;
ImSe.RegisterImporter(MI);

Model3D1.LoadFromFile('H:ScreenShortsSU_Modelcube.dae');
end;

Опять же, учитываем, что оси в SketchUp (и большинстве других редактров) ориентированы не так как в FireMonkey. Поэтому модель нужно еще и развернуть по оси X на 90 градусов.

Model3D1.RotationAngle.X:= 90;

Таким образом, получаем нечто подобное (скриншот в режиме проектирования).

imported_model

Я уже говорил выше, что “условный центр” модели FireMonkey соответствует центру модели SketchUp. В центре находится ближний левый нижний угол куба, а не центр фигуры.

Попробуем поместить куб в центр сцены в SketchUp. Для этого выделяем все элементы нашей модели (Ctrl+A) и используем клавишу M. Задаем один из углов куба в качестве начальной точки и конечную точку на расстоянии -0,5 М по одной из осей. Тоже самое делаем по двум оставшимся осям. В итоге условный центр куба переместится в центр сцены SketchUp. Экспортируем модель в COLLADA формат.

Как и следовало ожидать, после импорта условный центр фигуры совпадет с условным центром компонента Model3D.

modified_model

Таким образом, мы выяснили следующее:

  • COLLADA модель импортируется в FireMonkey с соблюдением пропорций. 1М в SketchUp соответствует 40 единицам FireMonkey;
  • При импорте центр импортированной модели будет соответствовать точке начала координат исходной COLLADA модели, однако он может не соответствовать условному центру импортируемой фигуры;
  • Направление осей в FireMonkey и в SketchUp отличаются, и для достижения визуального соответствия требуется поворт компонента TModel3D на 90 градусов по оси X.

Лично мне оптимальным видится вариант предварительной обработки моделей в 3D редакторе перед их использованием.

Очевидно, к данной теме я еще вернусь в одном из следующих постов. И я буду очень признателен, если вы поделитесь собственным опытом.

Другие статьи серии:

Firemonkey на практике #0
Firemonkey на практике #1
Firemonkey на практике #2. Освещение и материал поверхности 3D объектов
Firemonkey на практике #2. Движение 3D объектов
Firemonkey на практике #3. Использование 3D моделей
Firemonkey на практике #4. Ты попал!


Поделись с другими!
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  
  •  

3 комментария: Firemonkey на практике #5.

  • >>1М в SketchUp соответствует 40 единицам FireMonkey;

    40 единиц – это понятно.
    Единица – понятие настолько абстрактное, что не вызывает вопросов.

    А что такое “M” в терминах Google SketchUp?

    • Очевидно, что именно метры. Это следует из третьего рисунка. Рост Susan (именно так зовут эту девушку, исходя из model info) должен быть менее 2х метров. Вот и получается что m это метры. Хотя все это условности, конечно. Впрочем возможно где-то и как-то в SketchUp можно определить масштаб отображения моделей. Тогда эти метры станут вполне осязаемыми.

  • Доброго времени суток…
    Подскажите, каким образом можно загружать *.dae файлы из access в model3D.MeshCollection?
    при выполнении как записи в access:

    var
    obj: TModel3D;
    MI: TDAEModelImporter;
    ImSe: TModelImportServices;
    AMesh: TMeshDynArray;
    begin
    MI:=TDAEModelImporter.Create;
    ImSe:= TModelImportServices.Create;
    ImSe.RegisterImporter(MI);

    if OpenDialog1.Execute then ;
    begin
    obj:=TModel3D.Create(self);
    obj.LoadFromFile(OpenDialog1.FileName);
    FormData.Query.Active:=false;
    FormData.Query.SQL.Clear;
    FormData.Query.SQL.Add(‘SELECT * FROM Fasad WHERE TypeFasad = ”DoorRight”’);
    FormData.Query.Active:=true;
    FormData.Query.First;
    FormData.Query.Append;
    FormData.Query.FieldByName(‘Construct’).Assign(obj);
    FormData.Query.Post;
    obj.Free;
    end;

    end;

    Так и чтения:

    var

    MI: TDAEModelImporter;
    ImSe: TModelImportServices;
    AMesh: TMeshDynArray;
    begin
    MI:=TDAEModelImporter.Create;
    ImSe:= TModelImportServices.Create;
    ImSe.RegisterImporter(MI);

    with FormData do
    begin

    Query.Active:=false;
    Query.SQL.Clear;
    Query.SQL.Add(‘SELECT * FROM Fasad WHERE TypeFasad = ”DoorRight”’);
    Query.Active:=true;
    Query.First;
    MainHomeForm.Model3D2.Assign(TBlobField(Query.FieldByName(‘Construct’)));
    end;

    End;

    выдыет ошибку ‘cannot assign TbloobField to a TModel3d’

Ответить на Erinov Отмена ответа

Ваш email не будет опубликован. Обязательные поля отмечены *

Вы можете использовать это HTMLтеги и атрибуты: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>

Продукты DevArt
Купить онлайн:



Читай русскоязычные Delphi блоги
Каталог блогов Blogdir.ru
Яндекс.Метрика