Bullet Physics-딱딱한 물체에서 광선을 똑바로 캐스트 (1 인칭 카메라)


10

Bullet을 사용하여 1 인칭 카메라를 구현했습니다. 캡슐 형태의 강체입니다. 나는 며칠 동안 만 Bullet을 사용했으며 물리 엔진이 처음입니다. 나는 btRigidBody::setLinearVelocity()그것을 움직이며 세상과 완벽하게 충돌합니다. 유일한 문제는 Y 값이 자유롭게 움직이는 것입니다. 본문이 이동하기 전에 변환 벡터의 Y 값을 0으로 설정하여 일시적으로 해결했습니다. 이것은 높이에서 떨어질 때를 제외하고 모든 경우에 적용됩니다.

몸통이 키가 큰 개체를 떨어 뜨려도 이동 벡터의 Y 값이 0으로 설정되어 움직이지 않고지면으로 떨어질 때까지 계속 움직일 수 있습니다 (속도는 이동할 때만 설정 됨). 이 문제를 해결하기 위해 몸에서 광선을 내리고 월드의 Y 값을 결정하고 그 값과 카메라 몸체의 Y 값의 차이를 확인하고 움직임을 비활성화하거나 느리게하려고합니다. 차이가 충분히 큽니다.

나는 단순히 광선을 던지고 광선이 닿은 세계의 Y 값을 결정하는 것에 약간 붙어 있습니다. 이 콜백을 구현했습니다.

struct AllRayResultCallback : public btCollisionWorld::RayResultCallback{
    AllRayResultCallback(const btVector3& rayFromWorld, const btVector3& rayToWorld)
        : m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld), m_closestHitFraction(1.0){}

    btVector3   m_rayFromWorld;
    btVector3   m_rayToWorld;
    btVector3   m_hitNormalWorld;
    btVector3   m_hitPointWorld;
    float       m_closestHitFraction;

    virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace)
    {
        if(rayResult.m_hitFraction < m_closestHitFraction)
            m_closestHitFraction = rayResult.m_hitFraction;

        m_collisionObject = rayResult.m_collisionObject;
        if(normalInWorldSpace){
            m_hitNormalWorld = rayResult.m_hitNormalLocal;
        }
        else{
            m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal;
        }

        m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, m_closestHitFraction);
        return 1.0f;
    }
};

그리고 운동 기능에는 다음 코드가 있습니다.

btVector3 from(pos.x, pos.y + 1000, pos.z); // pos is the camera's rigid body position
btVector3 to(pos.x, 0, pos.z); // not sure if 0 is correct for Y

AllRayResultCallback callback(from, to);
Base::getSingletonPtr()->m_btWorld->rayTest(from, to, callback);

그래서 callback.m_hitPointWorld벡터 가 있습니다 . 각 프레임마다 카메라의 위치를 ​​보여주는 것 같습니다. 총알 문서뿐만 아니라 캐스팅 광선의 예를 Google에서 검색했으며 예제를 찾기가 어려웠습니다. 예는 정말 필요한 전부입니다.

아니면 딱딱한 몸체를 바닥에 고정시키는 방법이 Bullet에 있습니까?

Ogre3D를 렌더링 엔진으로 사용하고 있으며 광선을 캐스트하는 것은 매우 간단하지만 모든 광선을 간결하게 유지하기 위해 Bullet 내에 유지하고 싶습니다.

누구든지 올바른 방향으로 나를 가리킬 수 있습니까? 감사.

답변:


10

솔루션은 원래 시도보다 훨씬 간단하며 한 번의 충돌 만 테스트하는 경우 서브 클래 싱이 필요하지 않습니다.

충돌 벡터를 검색하기 위해 수행해야 할 모든 작업은 다음과 같습니다.

btVector3 btFrom(camPos.x, camPos.y, camPos.z);
btVector3 btTo(camPos.x, -5000.0f, camPos.z);
btCollisionWorld::ClosestRayResultCallback res(btFrom, btTo);

Base::getSingletonPtr()->m_btWorld->rayTest(btFrom, btTo, res); // m_btWorld is btDiscreteDynamicsWorld

if(res.hasHit()){
    printf("Collision at: <%.2f, %.2f, %.2f>\n", res.m_hitPointWorld.getX(), res.m_hitPointWorld.getY(), res.m_hitPointWorld.getZ());
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.