Menu

app5_core

Vladimir Baranov
Attachments
app5_main_window.jpg (202254 bytes)
app5_main_window_min.jpg (93217 bytes)
mudem_file_format.jpg (38800 bytes)

Содержание



Классы реализация которых еще не закончена

Алгоритм ухода от столкновения реализация класса CVehicle

Интерфейс пользователя

foobar

Рис1. вид главного окна app5.


Создание обьекта

Создать обьект можно с помощью кнопки Add, либо c помощью комадны create_obj.


Выбор обьекта

Выбор обьекта осуществляется через список ObjList. Список поддерживает фильтрацию по различным полям. При выборе обьекта он переходит в состояние выбран и его ссылка появляется в списке выбранных обьектов обьекта CSelection.


Выбор визуального обьекта

Выбор обьекта можно делать щелкнув по нему мышью.
Выбор нескольких обьектов осуществляется с клавишей shift.


Фильтрация списка обьектов

Может проходить по следующим полям:

  1. По имени в поле контекст(рис 1). Можно задавать несколько имен через пробел
  2. По классу
  3. По группе

Стандартные типы обьектов в версии 1.01

Следующие типы обьектов являются стандартными и различаются в версии 1.01

  • Полигональная сетка (GemObject)
  • Геометрический примитив (сфера, куб, цилиндр, пирамида, обьект Кассини, обьект вращения)
  • Кривые (спираль, дуга, сплайн, кривая Мебиуса)
  • Машины
  • Помошники (точки, стрелки)
  • Группы (содержащие ссылки на другие обьекты)
  • Несгрупированные

Действия над виртуальными обьектами

Видимые визуальные обьекты можно поворачивать, масштабировать и перемещать в пределах сцены и применять к ним различные функции. Обьекты можно прятать и проявлять. Их можно обьединять в группу и перемещать эту группу. Перемещение обьекта мышью можно ограничить по одной оси, нажав кнопки x,y,z . Параметры обьекта меняются через инспектор обьектов.


Мониторинг переменных

Любой аттрибут можно вывести на экран обновления строчкой watch("objname","attrname")
У экрана вывода переменных есть режим surviveMode, означающий что выводится только то что обновляет свое значение в течении N циклов апдейта. Если переменная не меняется она автоматически удаляется из мониторинга. Также можно выводить любую переменную из c++ вызвав pscr.upd(var). За мониторинг сейчас отвечает отдельное прилодение "Монитор app5".


Базовый класс Object

Функции объекта можно вызвать в окне ObjectInspector, в командном интерпретаторе, либо посредством muapi. Для того чтобы свойства обьекта были доступны пользователю необходимо создать метод Declare. в котором указать каждый нужный метод или свойство си++ и передать его адрес в функцию SET_ATTR или SET_METHOD.
Каждый обьект может быть сохранен в файл сцены. При отсутствии специальнорго способа сохранения у потомков базового класса, сохраняются только свойства базового класса. Свойство можно пометить как isNotSaving тогда оно не будет сохраняться в файл сцены.

class Object : public CObject
{
    public:
        DECLARE_SERIAL( Object )
        Object();
        ~Object();
        Object(Object& B)  

                virtual operator=(Object& A)
        virtual void NullReferences(){};
        void Connect();
        void Disconnect();
        virtual void Copy(Object* A);


        //Установить имя обьекта, недопускаются повторы. 
        void    SetName(std::string str);

        //Переименовать 
        void    Rename(std::string str);

        //Установить имя класса 
        void    SetClassName(std::string);

        void SetAddr2this(t_atr& a)

        //  Присвоить значение аттрибуту
        void    SET(char* attrname, char* val)

        //  Присвоить описание обьекту
        void    SET_DESCR(string descr);

        //Задекларировать аттрибут
        void    SET_ATTR(string name, void* addr, string type, bool bHidden);

        //Взять аттрибут
        t_atr* GET_ATTR(string name);

        //Установить метод
        void* SET_METHOD(char* parentclassname, char* argstr, char* classname, char* methname, ...);

        //Установить обьект (старый метод обобавляющий его в реестр всех обьектов, а также в глобальную таблицу Луа)
        int   SET_OBJECT(void* this_ptr, char* objname);

        //Найти обьект в таблице по имени (старый метод)
        static void* GET_OBJECT(char* objname);

        //Удалить обьект
        static void  DELETE_OBJECT(char* objname);

        //Вызвать метод обьекта
        int   CALL(char* obname, char* classname, char* methname);   
        string GetMethName(char* dummy,...);

        //Для записи аттрибутов в файл
        string ReadString(CArchive& archive);
        void   WriteString(CArchive& archive, string str);

        int    RemoveSignals();


        // Обычные слоты  
        virtual void mouse_move(int x, int y){};
        virtual void mouse_wheel(int zDelta){};
        virtual void click_lmb(int state){};    
        virtual void click_rmb(int state){};
        virtual void click_mmb(int state){};
        virtual void key_pressed(int k){};


        //сюда приходит сигнал апдейта от первого таймера
        virtual void Slot1(CSignal& sig); 
        virtual void Slot2(CSignal& sig);
        virtual void Slot3(CSignal& sig);
        virtual void Slot4(CSignal& sig);

        // Слюда приходит сообщение
        virtual void MessageSlot(CMessage& msg);

        //События
        virtual void OnSelect(){};
        virtual void OnUnselect(){};
        virtual void OnAttrChange(t_atr& a){};
        virtual void OnAttrSelect(t_atr& a){};
        virtual void OnDrag( float x, float y, float z );




        name;                //имя
        classname;          //имя класса
        groupname;          //имя группового обьекта
        int  livetime;      //время жизни
        bool     connected; //соединен с системой сигналов

        EntetyInfo    ei;           // информация о ентети
        vector<t_atr> atrs;       // массив аттрибутов
        map<string,int > atrsmap; // таблица аттрибутов

        vector<string> expressions;//выражения
        //tagTYPE    meth_args[1][1]; // параметры функции

        bool         isEntety;      // это сущность мира
        bool         isNotSaving;   // это не сохраняемый обьект
        bool         isCanRender;   // этот обьект может быть визуализирован
        int      isSelected;        // этот обькт выбран в данный момент (0- обьект не выбран,  2 - обьект выбран)
        bool            isGroup;    // эта группа
        bool         isLoading;     // идет загрузка обьекта
        //bool       isPhysic;      
        bool         onOpora;       // свободно либо на опоре  
        int      isHidden;          //0-виден в сцене 1 - отфильтрован флагами 2-спрятан пользователем
        bool         m_Updated;

        string       updatescript;      //скрипт для обновления параметров
        string       initscript;        //скрипт для инициализации
        time_t       osCreationTime;    //время создания
        DWORD        osCreationTimeTicks;   //время в тиках
        bool         bHideStdAttrs;         // имеет спятанные аттрибуты


};

Класс RenderObject


Обьекты этого класса визуализируются на экране. Другими словами попадают в конвеер рендеринга.

Интерфейс:
class RenderObject : public Object
{
RenderObject();
//вызываются из нити рендеринга
virtual void Render();
virtual void PreRender();
virtual void PostRender();
};

Чтобы сделать визуальный обьект сделайте следующее:

  1. Создайте отдельный класс
  2. Унаследуйте его от RenderObject
  3. Опишите логику этого класса
  4. Напишите функцию отрисовки обьекта в Render()
  5. Добавте свой обьект через диалог создания обьекта
  6. Сохраните сцену

Загрузка и сохранение сцены

Для загрузки сцены нужно 3 файла: object.arh classes.arh offset.arh. В файл classes.arh записываются имена классов обьектов, в файл obj.arh записываются данные обьектов, в файл offsets.arh записывается таблица имя оьекта - смещение на начало данных. У обьекта сохраняются все аттрибуты за исключением тех аттрибутов для которых выставлен флаг isNotSaving.


Сохранение и восстановление состояния обьекта

Для любого выбранного обьекта можно сохранять его состояние в любой момент времени.
Потом с помощью кнопки ReloadObj восстановить это сохраненное состояние.


Имена обьектов

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


Аттрибуты обьектов

В текущей версии 1.01 сохраняются все аттрибуты базового класса: дефолтовый размер примерно равен 1.4 кб. Добавление специальных методов Serialize у классов потомков естественно может увеличить размер. Например в случае геометрического обьекта обьем выделяемой памяти зависит от количества вершин. Вам необходимо написать свой метод сериализации таких обьектов, не забыв вызвав метод Serialize базового класса вначале.


Идентификаторы обьектов

Идентификаторы генерируются каждый раз при загрузке сцены. Поскольку при создании компилятор размещает обьекты си++ в разные участки памяти нам не нужно заботиться о выдаче уникальных идентификаторов если они вообще понадобятся. Поиск обьектов эффективно реализуется по имени через функцию CObjRegistry::FindObj


Группы

Объект может содержать в себе группу обьектов. Для таких объектов должен быть установлен флаг базового класса isGroup. Кроме того групповой обьект должен быть унаследован от класса Group. Обьект класса Group может содержать обьекты незарегистрированные в реестре обьектов (основной таблице обьектов).

bool isGroup;

Элементы PhysicalInfo обьекта Object

 Pnt         bounds;   // размеры
 Pnt         C0;       //центр
 float       mass;     //масса
 Pnt         kurs0;    //курс вектор из точки C0
 Pnt              v;       //мгновенная скорость

Класс физики CMovement. Силы действующие на обьект типа Object

Силы :

  • сила тяжести на обьекты у которых есть масса (mass>0),
  • сила трения со стороны поверхности учитывается при расчете движения Vehicle
  • сила опоры (если обьект на опоре у него выставляется флаг onOpora)
  • внешняя сила при отскоке по типу упругих шаров

Движение:
в классе Ball реализовано качение шара по плоскости в одном направлении
в классе Vehicle реализовано поступательное движение обьекта.


Режимы работы вьюпорта

MODE_SELECTION - режим выбора обьекта мышью
MODE_MOVE - режим перемещения мышью
MODE_SCROLLVIEW - используется для скроллинга вида сверху вдоль осей x и y
MODE_PICK - в этом режиме редактор позволяет назначить точку кликом мыши.


Класс сигнала CSignal

Класс сигнала используется в системе рассылки сигналов.
Для того чтобы подсоединить обьект к циклу обновления, необходимо вызвать метод базового класса Connect() в конструкторе. По умолчанию задается первый слот (слот апдейта), имя сигнала по умолчанию присваивается в виде "Dest_objname-Src_objname"

class CSignal
{
public:

CSignal(Object* dest, int slot_num);
CSignal(Object* dest, Object* src,  int slot_num);
void SetName(string name){strcpy(Name, name.c_str()); };
int Send();   // Немедленная посылка сигнала
int Post();   // Запланированная посылка сигнала

char   Name[255]; // имя сигнала 
int    slot_num;  //номер слота
void*  data;      // ссылка на произвольные данные

Object* dest;     // Обьект которому идет сигнал
Object* src;      // Обьект от которого идет сигнал

};


Структура t_atr.

Определяет аттрибут обьекта

Тип аттрибута обьекта один из распознаваемых ObjectInspector. Может быть untyped
Список типов поддерживаемых ObjectInspector
Обьекты имеют динамический список аттрибутов, которые могут добавлятся в процессе работы программы.
Например при создании новой точки в кривой появляется новое свойство с именем Pnt1

Типы аттрибутов

float

  • int
  • string
  • selector
  • func
  • GLColor3f
  • bool
  • Pnt

Свойства аттрибутов

min -минимальное зн-е
max - максимальное зн-е
step - шаг
flags - флаги установленные для аттрибута

Функции работы с аттрибутами

Hide()
Ставит флаг isHidden. Прячет аттрибут. Необходимо для функции фильтрации свойств в ObjInspector

Unhide()
Снимает флаг isHidden.

Select()
Ставит флаг isSelected. Для выбранного аттрибута отображается адрес в консоле.

Unselect()

toString()
Конвертирует значение аттрибута в строку

fromString()
Парсирует строку в тип аттрибута.

Watch()
Устанавливает флаг isWatched. Это нужно для просмотра значения аттрибута на экране выводимых переменных.

isWatched()

ReadOnly()
Устанавливает флаг isReadOnly. Нужно для защиты от записи аттрибута. Например имя обьекта, поскольку оно занесено в реестр обьектов.

isReadOnly()
проверяет флаг isReadOnly

NotSaving()
Устанавливает флаг NotSaving. Это означает что его значение не будет сохраняться в файл при сохранении сцены.

isNotSaving()
проверяет флаг isNotSaving()


Класс Camera

Наследование: Object->RenderObject

При запуске мира в нем существует одна камера свободного обзора.
Для отображения ортогональных видов применяется тот же класс.
Активная камера — это та камера которой передается управление мыши, клавиатуры и других устройств ввода. Выбор активной камеры делается кликом по вьюпорту. Камера может быть визуализирована в изображении другой камеры. Камера отображается в другом окне как тетрайдер, основание которого - плоскость проекции виртуального изображения.
Управляется камера с помощью клавиш - w,a,s,d направление обзора и движения регулируется мышью. Вектор движения определяется чрез точку lookAt, точкой в которую смотрит камера. Координаты этой точки преобразуются в сферической системе координат взависимости от движений мыши.
Для более плавного движения камеры рассматривается применение математического аппарата кватернионов.


Класс CMainInterface

Определяет начальные действия
-Инициирует загрузку сцены
-Создает и разммещает данные обьектов в памяти
-Определяет порядок рендеринга обьектов


Способы отрисовки моделей

Определяются глобальными флагами flags
-bShading Шейдинг с наложением материала на полигоны
-bColorRendering - Используется matid для выбора цвета грань
-bWire - Режим отображения в виде сеточного каркаса
-bMayPaintGDI - особый режим отрисовки (нужен для удаленного дисплея)


Структура EntetyInfo

характеризуется

  • файлом модели
  • координатами
  • именем класса обьекта
  • GUID в карте
  • именем
  • типом материала
  • сценарием

Структура PhysicalInfo

характеризуется:
-скоростью
-обьемом(длинами сторон ограничевающего параллепипеда)
-массой
-направлением


Реестр обьектов CObjRegistry

Содержит:
Таблицу (objname, EntetyInfo)
Функции:

  1. Поиск обьектов по имени
  2. Поиск по координатам
  3. Поиск по классу

Реестр ресурсов CResRegistry

Содержит:
Таблицу (resname, ResInfo)
Функции:

  1. Загрузка файлов модели
  2. Загрузка текстур
  3. Загрузка и компиляция шейдеров
  4. Создание новых ресурсов
  5. Поиск по имени ресурса
  6. Обработка исключительных ситуаций при отсутсвии нужного ресурса

Класс CInput

Перенаправляет действия пользователя обьекту управления.
Предоставляет двухмерные координаты в экране (вьюпорте OpenGl)
Предоставляет трехмерные координаты точки в виде "сверху".
Содержит включение режима "прилипания" курсора к сетке.


ObjInspector

Отображает список свойств обьекта,
Изменяет любое свойство не ReadOnly
Отражает изменение свойства во времени
Вызывает функции обьекта.
Плавно меняет свойство в пределах выбранной точности
Поддерживает базовые типы: число, строка, флаг
Поддерживает некоторые специальные типы:
коллекция строк, вектор, точка, цвет


Класс Space

Описывает пространство.
Пространство состоит из набора узловых точек MapPoint.
Пространство делится на сектора(Sector) вершины которых представляют собой узловые точки.
Позволяет осуществить поиск обьектов в окресности некоторой точки.
Функции мировой системы координат
Переводы из локальной системы координат в мировую
Подразумевает деление пространства на отдельные сектора содержащие
ссылки на обьекты, которые в нем присутсвуют (целесообразно для больших карт).
Функции:

  1. Поиск обьектов в окресности некой точки
    Поиск обьектов в зоне
    p = (x / sect_size, y / sect_size, z / sect_size )
    Рассмотрение списков обьетктов 8 секторов узловой точки
    Составление списка секторов зоны ( по умолчанию параллепипед )
    Классы CSector имеют 6 ссылок на соседние сектора (up,down,left,right,front,back)

Класс CSelection.

Реализация механизма выбора обьектов.


Геометрические примитивы и связанная с ними физика


Класс Ball

Наследование: Object->RenderObject

Класс визуализирующий сферу с физикой мяча


Загрузка геометрии и материалов из файла формата 3dmax ascii

Для импорта моделей используется формат сцены 3dmax ASE
http://paulbourke.net/dataformats/ase/

Импорт сцены формата ASE реализован в ascii3d.cpp.
По спецификации сцены ASE в app5 создаются модели класса GemObject. Внутри GemObject создается агрегированный обьект класса Mesh (полигональная сетка). Каждому полигону присваивается номер matid. Дальше по этому полю возможен цветовой рендеринг в случае отсутсвия текстур. Также в память загружаются материалы. Инициализируются материалы присвоенные полигону, координаты текстур, устанавливается модель меппинга (циллиндрический, планарный, сферический). Импортируются сплайновые обьекты типа Shape.


Класс CAsciiLoader

Класс для загрузки ASE.
Создание и правильное размещение обьектов в мире app5.

class CAsciiLoader
{
public:
CAsciiLoader();
vector<string> info;
std::string filename;
tm time;
int version;
void ProcessMesh();
char NextLine();
void Reset();
void AssignMt()
void ResetFlags()
//~CAsciiLoader();
int LoadASCIIIFile(char
ASC3d_filename);
void GetInfo();</string>

};


Класс GemObject

Наследование: Object->RenderObject

Copy(Object* A)
ComputeC0() | поиск геометрического центра обьекта
SetNumFaces() | Установить количество полигонов
SetNumVert() | Установить количество вершин
CenterModel() | Пересчитывает координаты обьекта из мировых в локальные
Serialize() | Метод реализирующий бинарный экспорт данных обьекта
LoadMesh(string goname); // для обьектов типа Ссылка (ссылка на данные со своими pos, rot, scale и тд))
FillArrays();
Render();

Стуркура определяющая вершину сетки

struct Vertex

Стуркура определяющая точку сплайна

struct Vertex_knot
{
int idx;
Pnt c;
bool knot; // узловая точка или интерпол
};

Стуркура определяющая грань сетки

typedef struct TFace
{
Vertex vertices[4]; // полигон состоит из 4 точек
Pnt facetNormal; // нормаль полигона
char matid; // номер материала
}TFace;

Групповой обьект

class GroupObject: public Object
{
public:
string NODE_NAME;
string HELPER_CLASS;
Pnt BOUNDINGBOX_MIN;
Pnt BOUNDINGBOX_MAX;
Node_TM nodetm;
};

Cплайновый обьект

class ShapeObject : public Object
{
public:
DECLARE_SERIAL( ShapeObject )
string NODE_NAME;
string NODE_PARENT;
Node_TM modetm;
int SHAPE_LINECOUNT;
vector<shapeline> shapelines; </shapeline>


класс CVehicle

Содержит модель движения автомобиля, анимацию автомобиля (анимируются колеса).
Обьекту этого класса может быть присвоена траектория класса Curve.
Машину можно перемещать в начало траектории.
Управление клавишами o,k,l,;
При движении на автомобиль кроме силы тяги действует сила тяжести и сила трения.
Когда машина управляется пользователем на траектории отображаются ближайшая точка.
Эта точка окрашивается в зеленый цвет если машина движется по направлению к концу траектории и в синиий цвет - если наоборот.


класс Curve

Содержит визуальный сплайн Эрмита с возможностью редактировать контрольные точки, перемещать их и регулировать степень кривизны (производные в контрольных точках).
В Curve добавлена Спираль задается двумя радиусами и высотой
В Curve добавлена Дуга задается двумя точками и высотой
В Curve добавлен альтернативный алгоритм сплайна Кочана-Бартельса


класс DemoRecorder

Деморекордер позволяет записывать положения обьектов и другие параметры
в данный момент времени. Или на протяжении периода времени.


Возможность применения управления поверх записанных параметров.

Например запретить поворот колес. Запретить изменение скорости, задать параметр const.
Тогда прямое обращение к аттрибуту нужно заменить косвенным.
Как это согласовать с контроллером, который присвоен аттрибуту.


В какой последовательности обрабатывается воспроизведение и запись демок?

Вызовы функций осуществляются в gtimer.Timer2() при каждом тике

  1. DemoRecorder::Slot1() - воспроизведение
  2. Обработка контроллеров всех параметров
  3. Все Slot1 всех обьектов
  4. DemoRecorder::Slot2() - запись

Формат записи файла демо

Для каждого обьекта свой файл следующего содержания
Формат имени файла: objname_time.mudem

foobar


Как просматривать историю записей?

Нужен вывод данных в табличной форме.
Нужен вывод данных в виде графиков.
Подход 1:

  1. Выбираем обьект.
  2. Выбираем демку из выпадающего списка.
  3. Выбераем аттрибут (checkbox справа) от параметра
  4. Нажимаем кнопку История-График или История-Таблица

Как записывать демо.

  1. Выделяются обьекты демо которых надо записать. Специальный диалог(можно взять ObjList)
  2. Нажимается кнопка StartRecord.
    3 В каталоге mu/demos появляется файл с именем objname_time.mudem

Как проигрывать демо?

  1. Выбор из списка выпадающего демок demolist
  2. Отметить пункт bWant2Play
  3. Нажать на Play\Stop

Прочее

Каталог: mu/demos
Формат имени: objname_time.mudem


Интерфейс класса DemoRecorder

ndemos; //кол-во демок
demoname; //имя текущей демки
interval; //интервал времени через который бкруться аттрибуты
Cycle(); //Зациклить демо
RecordNew(); //Записать новую дему для обьектов
Delete(); //Удалить демо
Play(); //Проиграть
Bind(); //Применить \ Отменить демо для текущего обьекта
Next(); //Следующий шаг. Цикл по всем демкам

Интерфейс класса Demo

demoname; // Имя демо = objname_dem_time
timestarted; // время нажатия на кнопку "Запись"
interval; // интервал времени через который бкруться аттрибуты
length; // время записи
descr; // описание
filename; // objname_time.mudem
objectname; // имя обьекта
bCycled; // зациклено
offset; // смещение относительно начала файла
size; // размер демо в байтах
Next(); // восстановить следующий дамп
LoadNext(); // восстановить следующее состояние обьекта
LoadPrevios(); // восстановить предыдущее состояние обьекта
SaveNext(); // сохранить текущее состояние обьекта


Cправка по виртуальной машине(необработанная под wiki)

В глобальной области этой виртуальной машины (далее MUVM) создаются таблицы с именами обьектов. По умолчанию через MUVM доступны все обьекты которые вы видите в списке(включая скрытые) и все методы бызового класса Object. Также можно преобразовать ссылку базовый класс в ссылку на класс потомка. С помощью функций asCamera, asCMovement, asHelperObject, asCVehicle, asShapeObject, asGemObject, asCMaterial, asCLight, asKirpich, asBall

Функция createobj('NAME_OF_OBJECT','NAME_OF_CLASS')


Создает обьект заданного класса.

Функция s(objname,attrname,value)


Присвоить значение аттрибуту обьекта

Функция c(objname,methname)


Вызвать метод обьекта

Функция unselect_all()


Снять выделение со всех обьектов

Функция unselect()


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

Функция select()


Выбрать обьект\ы имена через запятую.
Регулярные выражения не допускаются.

Функция clear_all()


Очистка сцены. Удаление всех обьектов

Функция print(), prn()


Печать переменной или строки на консоль

Функция watch


Установить мониторинг за переменной

Функция reset_watch


Сбросить мониторинг переменной

Функции и ключевые слова ВМ
for, min, max, random, exit, date, print, clock,watch, getenv, gsub, format


Пример 1: Вычислить выражение


Например чтобы вычислить чему равна сумма 2 и 2 можно написать:
a = 2 + 2;
prn(a);


Пример 2: Изменить положение обьекта


Например чтобы изменить положение камеры можно написать:
cam02.ei.coord = Point(2,6,0);



Классы реализация которых еще не закончена


<object style="height: 390px; width: 640px"><param name="movie" value="http://www.youtube.com/v/ud9AXDbhCGg?version=3&amp;feature=player_profilepage"><param name="allowFullScreen" value="true"><param name="allowScriptAccess" value="always"><embed src="http://www.youtube.com/v/ud9AXDbhCGg?version=3&amp;feature=player_profilepage" type="application/x-shockwave-flash" allowfullscreen="true" allowscriptaccess="always" width="640" height="360"></object>

MongoDB Logo MongoDB