3DCoat
3D-COAT 4.9.xx
3DCoat is the one application that has all the tools you need to take your 3D idea from a block of digital clay all the way to a production ready, fully textured organic or hard surface model.
|
Для регистрации членов класса с целью последующего показа класса в UI или сериализации необходимо, чтобы класс был наследником BaseClass
. Регистрацию делай так
Или в секции SAVE ... ENDSAVE
так (архаичный способ, для нового класса так не надо)
Или так (тоже по древнему, но лучше, чем тулить всё в хидер)
Используем, если тип переменной variable_name
не является наследником BaseClass
.
Соответствие типов данных c++ и class_type
глянь в этой табличке.
c++ type | class_type |
---|---|
float | _float |
int | _int |
bool | _bool |
DWORD | _DWORD |
DWORD | _color (когда нужно интерпретировать DWORD как цвет) |
short | _short |
BYTE | _byte |
char | _char |
Используй в случае, если тип переменной является наследником BaseClass
.
Если хотишь, чтобы переменные типа int
и float
появлялись в UI как слайдеры (ползунки).
Можешь регистрировать функции и члены класса. В UI они появятся как кнопки, при нажатии на кнопку стартует заданная тобой функция.
В команде выше функцию объявляешь так
При регистрации можно модифицировать идентификатор в UI, который соответствует переменной. При использовании предыдущих команд этот идентификатор такой же, как имя переменной.
С помощью специальных директив можно управлять различными свойствами объекта в UI. Директивы располагаются как префикс перед идентификатором. Если тип переменной variable_name
не является наследником BaseClass
, используй команду
Например
В этом случае имя переменной в UI ты не увидишь, только её значение. Однако, есть проблема: если несколько переменных вдруг окажутся зарегистрированы с пустым именем, то при сохранении данных класса в виде XML получишь два пустых тега: данные о значении переменной потеряешь. Поэтому лучше сильно не умничать, а регистрировать так
В этом случае имя переменной также не увидишь в UI, но в XML у неё будет ID $integer_variable
. Это пример, зачем нужны приставки в определении переменных.
Для регистрации вызова функций.
Используем для функций, если необходимо динамически формировать идентификатор UI.
При этом name_for_UI_with_quotes
будет char*
.
Набор приставок перед идентификаторами. Приставки используй в том же порядке, как они приведены в таблице.
Приставка | Что делает |
---|---|
{0xHEXADECMAIL_VALUE} | Цвет подложки для этого поля в UI |
{fc0xHEXADECMAIL_VALUE} | Цвет шрифта для поля |
[scale=floating_value] | Дополнительный масштабный коэффициент для редактируемого поля |
integer_value <td> integer_value - идентификатор группы для чекбоксов. В этом случае чекбокс показывается как radio-button. Чекбоксы одной группы должны использовать одинаковые integer_value. Например <tr><td>^ <td> REG_MEMBER_EX( _bool, Choice1, 1Choice1 ); | |
^ | REG_MEMBER_EX( _bool, Choice2, <tt>1Choice2 ); <tr><td>^ <td> REG_MEMBER_EX( _bool, Choice3,1Choice3 ); |
^ | В этом случае мы получим 3 radio buttons и только один из низ может быть выделен. |
% | Применять масштаб сцены к этому контролу (обычно это поле float или float-slider) |
{hotkey hotkey_id} | hotkey будет назначен хоткееем по умолчанию для кнопки. Например |
^ | {hotkey CTRL ALT SHIFT A} |
^ | {hotkey SHIFT NUM_PLUS} |
^ | Список всех идентификаторов |
^ | 0 1 2 3 4 5 6 7 8 9 |
^ | A B C D E F G H I J K L M N O P Q R S T U V W X Y Z |
^ | ENTER ESC NUM0 NUM1 NUM2 NUM3 NUM4 NUM5 NUM6 NUM7 NUM8 NUM9 F1 F2 F3 F4 F5 F6 F7 F8 F9 F10 PGDN PGUP HOME END INS NUM_PLUS NUM_MINUS NUM* NUM/ < > ? |
^ | F11 F12 ~ SPACE BACK PAUSE DELETE [ ] ; ' , . / |
^ | Left Right Up Down |
^ | Lwin Rwin App Lmemu Rmenu Tab Back - + |
^ | LMB RMB MMB CTRL ALT SHIFT X1 X2 |
# | Не показывать подсказку (HINT) |
~ | Функция недоступна в Demo-режиме |
* | Принудительное выравнивание влево |
$ | Не показывать имя поля, только значение |
! | Показывать только значение, read only |
[^] | Иконка Move_area_16.tga |
^ | Read only |
{icon filename_path} | Показать иконку |
Если в UI необходим выпадающий список, то регистрируем переменную типа int
так
Или
где ENUM_ID
- енумератор (набор значений для выпадающего списка).
Обычно, енумератор создаётся так
Этот код лучше всего размещать внутри секции SAVE ... ENDSAVE
.
Пример
При сохранении или же показе данных экземпляра класса, структура представления может динамически меняться. Для этого раньше использовали маскирование элементов с помощью битовых масок. Ты ведь помнишь, что теперь классы мы регистрируем динамически и маски нам не нужны, да? Нет? См. выше.
Например
Обрати внимание на функцию GetClassMask()
: она возвращает битовую маску элементов, которые разрешено показывать. SAVE_SECTION
определяет битовую маску для всех последующих элементов до следующей директивы SAVE_SECTION
. Если операция побитового AND
для GetClassMask
и SAVE_SECTION
возвращает ненулевой результат, то элемент показывается в UI или будет принимать участие в сериализации.
Элементы в UI можно размещать в несколько столбиков, контролировать, будет ли ширина поля фиксированной, или же подбираться автоматически. За это отвечает директива
Внутри COLUMNS
размещаются (без кавычек ") относительная или абсолютная ширина последующих элементов. Например:
Вариант команды COLUMNS
Ещё вариант
Все три поля в данном случае выводятся без названия, только значения. Ширина контрола, соответствующего bool_field
будет 16 пкс, а ширина поля IntField1
будет вдвое больше ширины IntField2
.
В качестве дополнительных элементов форматирования удобно использовать
Существует несколько модификаторов при регистрации членов класса. Все модификаторы пишутся *перед* командой регистрации элемента.
Указывает на то, что данных элемент не участвует в сериализации класса, то есть не сохраняется и не считывается из XML-структуры.
Элемент может участвовать в сериализации, но будет невидим в UI.
Модификаторы NOSAVE
и INVISIBLE
полезны для согласования как класс увидит художник и как класс сохранится в XML.
При регистрации статических переменных класса или же глобальных переменных не членов класса, обязательно указывай, что они являются статическими.
Если класс является наследником BaseClass
, то регистрируем класс так
Или так
В 3DCoat существует несколько полезных классов, для которых уже написан сравнительно удобный редактор. Вот табличка этих удобств.
Класс / Тип | Как регистрировать | Что творит |
---|---|---|
_str | REG_AUTO/REG_AUTO_EX | Редактирование строки, однострочный редактор. |
_int | REG_MEMBER( _TextureID, ... ) | Выбор текстуры, в результате в переменной типа int будет либо -1 , либо идентификатор текстуры. |
One2DCurve | REG_AUTO | Редактирование кривых. |
ClassArray<One2DCurve> | REG_AUTO | Редактирование группы кривых. |
_str | REG_AUTO_EX(path,save:*.ext1;*.ext2;) | Строка используется как путь к файлу. В зависимости от использования load или save при выбое пути открывается файловый диалог для загрузки или же сохранения файлов. |
^ | REG_AUTO_EX(path,load:*.ext1;*.ext2;) | ^ |
_bool | REG_MEMBER(_bool,Visible); | Если элемент класса зарегистрирован как _bool и называется Visible, то он будет отображаться в виде иконки с глазиком. |
В некоторых случаях необходимо создать собственный редактор класса, **отличный** от стандартного. В этом случае смело перегружай функцию
При создании интерфейса эта функция вызывается для каждого зарегистрированного элемента класса. Ты можешь идентифицировать этот член по его имени в FieldName
. Контролы можешь строить внутри W
. До вызова OnCreateControl()
в W
уже создано стандартное представление данного элемента. Его размер и расположение записаны в BaseWidget::Rect
, но ты всё можешь поменять.
Посмотри примеры реализации собственного редактора в этих классах
Вызывается на каждом кадре при редактировании класса.
Вызывается после изменения пользователем элемента класса. В настоящий момент возвращаемое значение не играет роли.
Вызывается непосредственно перед изменением пользователем элемента класса. Полезна для Undo.
Используются для реализации Drag & Drop. Для углублённого понимания смотри примеры в коде Кота.
Каждый наследник BaseClass
может быть сохранён в поток данных или же считан из него. Примеры сохранения и считывания