Как известно, в Urho3D доступный набор параметров для Constraint'ов сильно ограничен, поэтому предполагается, что все остальные параметры будут настраиваться непосредственно в Bullet'овских Constraint'ах, но вот беда: при попытке получить указатель на Constraint, он постоянно оказывается равен NULL, из-за чего, естественно, возникает ошибка. Например:
btTypedConstraint* btConstraint = constraint->GetConstraint(); //NULL
btSliderConstraint* btConstraint = static_cast<btSliderConstraint*>(constraint->GetConstraint( )); //NULL
и т.д.
Видел на офф. форуме запись об этой проблеме, но не видел её решения. Полазил по исходникам Constraint'а, но не увидел там ничего криминального. Можно ли как-то пофиксить эту ошибку?
чип
Не знаю, что там в 1.7, но в 1.7.1 Constraint::GetConstraint() возвращает NULL. Сейчас спецом попробовал получить указатель на btTypedConstraint сразу после создания Constraint'а, и, что закономерно, ничего не получилось. После SetConstraintType() — тоже. Код верный, т.к. урховский Constraint работает нормально. Ну а о том, что без подключенной либы Bullet'а выдётся undefined reference, я вообще молчу...
Странно... В простом примере всё работает, а там, где надо — нет. RigidBody на месте, Constraint присутствует и работает, но GetConstraint() упорно возвращает NULL, хоть до SetConstraintType(), хоть после. Очень, очень странно... Единственная разница с простым примером, которую я вижу, в том, что в простом примере нода с констраинтом — потомок сцены, а в нужном месте — потомок другой ноды, но, по идее, это никак не должно сказываться на конечном результате.
А я всё ещё пытаюсь понять, почему же не получается получить btTypedConstraint... Итак, у меня есть структура танка, которая загружается из XML-файла: корпус, башня с пушкой, и две гусеницы с колёсами. Башня и гусеницы — потомки корпуса, а колёса — потомки гусениц. На корпусе висит RigidBody, на гусеницах — StaticModel, а на каждом колесе — RigidBody и CollisionShape. На каждую ноду гусеницы так же повешан компонент, отвечающий за её логику. При создании компонента происходит нахождение колёс (т.к. в гусенице есть ещё и кости), и создание констраинтов для них. Вот именно из этих констраинтов и нужно получить btTypedConstraint для последующей работы с ним:
Пробовал сделать загрузку простой сцены — там всё работает. Я уже близок к тому, что бы забить на урховские констраинты, и добавлять Bullet'овские констраинты напрямую, хоть это и более геморно.
P.S. Что, чёрт возьми, с выравниванием блоков кода? Неужели так сложно сделать так, что бы они были на одной линии с текстом?
чип
> Это логический компонент?
Да, каждая гусеница — компонент, унаследованный от LogicComponent
> А основной код инициализации размещают в функции
Сомневаюсь, что это что-то изменит, но попробую потом
> Попробуйте еще перед созданием
> child->CreateComponent<Constraint>();
> сделать проверку на существование RigidBody в узле с выводом в лог.
Они там есть, потому что:
1. Я их собственноручно повешал в редакторе на каждое колесо
2. Танк на эти колёса опирается, а если бы на них не было RigidBody, то они проваливались бы сквозь поверхность.
3. Делал вывод, RigidBody на колёсах действительно есть
4. Насколько я понял из исходника Constraint'а, при отсутствии и ownBody, и otherBody, он просто не создастся, а он создаётся и работает.
> Почти уверен что в последней функции можно получить искомые Булетовские
> ограничители.
Если бы...
void Vehicle::GetWheelComponents() { frontLeftAxis_ = frontLeft_->GetComponent<Constraint>( ); frontRightAxis_ = frontRight_->GetComponent<Constraint>( ); frontLeftBody_ = frontLeft_->GetComponent<RigidBody>( ); frontRightBody_ = frontRight_->GetComponent<RigidBody>( ); rearLeftBody_ = rearLeft_->GetComponent<RigidBody>( ); rearRightBody_ = rearRight_->GetComponent<RigidBody>( ); }
Любопытно... Переименовал функцию в DelayedStart() — и констраинты появились. Кажется, я чего-то не понимаю, а конкретно того, в какой последовательности в движке (в урхе, или в Bullet'е) происходит инициализация констраинтов... Хотя, судя по исходнику констраинта, SetConstraintType() не привязан ни к каким событиям (как и CreateConstraint(), которая вызывается внутри неё), и указатель на btTypedConstraint должен существовать сразу после её вызова.
Тема в архиве.