Настройка запроса на поиск столкновений

Если возможности настроек структуры cdet_collided_faces не достаточны, пользователь геометрического ядра C3D может реализовать собственный запрос. Для этого необходимо определить наследника класса cdet_query и реализовать для него специальную функцию обратного вызова (call-back функцию) вида:

typedef cback_res (*cback_func)(cdet_query *, message, cback_data &).

Ниже приведен пример реализации на языке программирования С++ структуры cdet_query_result, являющейся наследником структуры запроса cdet_query. Пример задает поиск до первого найденного пересечения и определяет, есть ли хотя бы одно пересечение в контрольном наборе тел. Пример можно найти в файле cdet_data.h.

//------------------------------------------------------------
struct cdet_query_result: public cdet_query
{
cdet_result result;
cdet_query_result()
    : cdet_query(QueryFunc)
    , result(CDM_RESULT_NoCollisionDetected) {} 
private:
static cback_res QueryFunc(cdet_query * query, message code, cback_data &)
{
    cdet_query_result * q = static_cast<cdet_query_result*>(query);
    switch( code )
    {
        case CDET_QUERY_STARTED: // The collision query is started for all solids of the set
        {
            q->result = CDM_RESULT_NoCollisionDetected;
            return CBACK_VOID_RESULT;
        }
        case CDET_INTERSECTED: // First intersection is founded.
        {
            q->result = CDM_RESULT_CollisionDetected;
            return CBACK_SUFFICIENT;
        }
        case CDET_FINISHED: // A pair of solids is finished.
        return (q->result == CDM_RESULT_CollisionDetected) ? CBACK_BREAK:CBACK_VOID_RESULT;
        default:
        return CBACK_VOID;
        }
    }
};

В основе запроса лежит функция обратного вызова

static cback_res QueryFunc(cdet_query * query, message code, cback_data & cData),   

которую пользователь может реализовать на свое усмотрение. Данная функция передается в алгоритм CheckCollisions через структуру cdet_query и будет вызываться при наступлении одного из следующих событий (enum cdet_query::message):

  • CDET_QUERY_STARTED (начат поиск столкновений в контрольной группе тел),

  • CDET_STARTED (начат поиск столкновений для пары объектов),

  • CDET_FINISHED (завершен поиск столкновений для пары объектов),

  • CDET_INTERSECTED (найдено пересечение граней от пары объектов),

  • CDET_TOUCHED (найдены соприкасающиеся грани пары объектов).

Входными параметрами функции QueryFunc являются:

  • query – указатель на структуру запроса,

  • code – целочисленное значение, кодирующее событие поиска,

  • cData – структура передачи данных.

Функция возвращает одно из значений перечисления cback_res:

  • CBACK_SUFFICIENT (Реакция клиентского приложения на события CDET_INTERSECTED или CDET_TOUCHED. Прерывает поиск для данной пары тел, но продолжает поиск столкновений других пар из контрольного набора тел),

  • CBACK_SKIP (Пропустить поиск для данной пары тел по событию CDET_STARTED: Поиск для других пар из набора будет продолжен),

  • CBACK_BREAK (Прерывает дальнейший поиск пересечений для всех событий),

  • CBACK_VOID (Не оказывает влияния на запрос столкновений, продолжает поиск), которое передает клиентское приложение ядру C3D для настройки алгоритма поиска.

Целочисленное значение code определяет событие поиска и может принимать одно из значений:

  • CDET_QUERY_STARTED,

  • CDET_STARTED,

  • CDET_FINISHED,

  • CDET_INTERSECTED,

  • CDET_TOUCHED,

Структура данных cData предназначена для передачи пары элементов типа cdet_query::geom_element и должна иметь вид:

struct cback_data
    {
        geom_element first, second;
    };  

где элемент пары cdet_query::geom_element – это структура деталей поиска, содержащая следующие:

  • geom_element::appItem – геометрический объект клиентского приложения,

  • geom_element::refItem – геометрический объект типа MbRefItem, как правило это грань MbFace,

  • geom_element::wMatrix – матрица перехода в общую, мировую СК из локальной СК тела.

Различная реализация метода обратного вызова QueryFunc позволяет выполнять следующие настройки процесса поиска:

  • Собрать все пары граней, участвующих в столкновении тел;

  • В любой момент исключать из рассмотрения определенные тела или пары тел;

  • Различать случай пересечения и касания граней;

  • Прерывать поиск всех пересечений при достижении определенного результата;

  • Прерывать поиск при обнаружении пересечения или касания;

  • Группировать тела, чтобы в пределах группы пересечения не искались.