Jetzt möchte ich aber einen RayTest auf die Szene machen um Objekte auszuwählen, nur liefert er nie ein Ergebnis. Ich hatte früher schon einen Selektionstest mit Bounding Spheres und benutze die selben Komponenten, der Strahl müsste also stimmen. Ich habe auch einmal die Werte explizit so gesetzt, dass sie das Objekt treffen müssen, aber es wird immer noch kein Ergebnis geliefert. Ich muss auch sagen mir sind eine ganze Menge Dinge unklar, aber ich finde leider auch keine Demo oder Tutorials zu dem Thema. Und die Doku ist auch nicht wirklich ausführlich.
Also, Ausgangspunkt ist btCollisionWorld::rayTest. Los geht es mit den Parametern rayFromWorld und rayToWorld. Das wird wohl der Strahl sein, aber sind das 2 Punkte auf dem Strahl oder Start und Richtung? Irgendwie steht das nirgends. Naja, ich habe beides ausprobiert, ohne Erfolg. Dann das Callback Objekt. Dafür habe ich mir eine kleine Hilfsfunktion geschrieben, damit ich Lambdas benutzen kann, das ganze sieht dann so aus:
- Code: Ansicht erweitern :: Alles auswählen
#include <BulletCollision/CollisionDispatch/btCollisionWorld.h>
template<typename tFunc> class RayResultFunctorCallbackClass : public btCollisionWorld::RayResultCallback
{
public:
RayResultFunctorCallbackClass(tFunc Func): m_Func(Func) {}
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult &rayResult, bool normalInWorldSpace) override
{
m_Func(rayResult);
return 1;
}
private:
tFunc m_Func;
};
template<typename tFunc> RayResultFunctorCallbackClass<tFunc> RayResultFunctorCallback(tFunc Func)
{
return RayResultFunctorCallbackClass<tFunc>(Func);
}
list<EntityRef> SceneManager::GetObjects(Vector3f Start, Vector3f Direction)
{
list<EntityRef> ReturnList;
m_CollisionWorld->rayTest(asBtVec(Start), asBtVec(Direction), RayResultFunctorCallback(
[&ReturnList](btCollisionWorld::LocalRayResult &rayResult)
{
auto cod=reinterpret_cast<CollisionObjectData*>(rayResult.m_collisionObject->getUserPointer());
if(cod && cod->entity)
ReturnList.push_back(cod->entity);
}
));
return ReturnList;
}
Mit dem Lambda will ich dann also alle gefundenen Objekte in eine Liste packen, die ich dann abarbeiten kann. Aber soweit kommt es gar nicht, das Lambda wird nie aufgerufen. Ich habe gesehen, dass es statt dem RayResultCallback noch 2 andere Klassen gibt, scheinbar eine für nur den ersten Treffen und eine für alle Treffer. Allerdings wollen die im Konstruktor wieder Parameter für den Strahl haben, was für mich keinen Sinn ergibt, denn so würde der Strahl ja 2 mal an die RayTest Funktion übergeben (als direkter Parameter und in dem Callback).
Bevor ich jetzt weiter im dunkel rumstocher und mir Funktionen und Klassen anschaue, die quasi nicht dokumentiert sind, frage ich mich, ob hier nicht schonmal jemand das selbe tun wollte und mir sagen kann, wie es geht.
