답변:
총알 물리 엔진으로 특별히 작업하지는 않았지만 다른 물리 엔진에서 매우 비슷한 작업을 수행했습니다. 내가 해결 한 방법은 강체의 선형 속도를 직접 변환하는 대신 설정하는 것이 었습니다. 그런 다음 물리 엔진 업데이트 단계에서 이동 및 충돌을 자동으로 처리했습니다.
로부터 문서 있을 것 같습니다 btRigidBody::setLinearVelocity
당신이 사용할 수있는 방법. 예를 들어, 가속이 일어나지 않게하려면 캐릭터가 움직일 때마다 선형 속도를 적절한 값으로 설정하고 캐릭터가 정지해야 할 때 다시 (0,0,0)으로 설정하십시오. 플레이어가 키를 놓을 때).
어떤 값을 사용할 지에 대한 일반적인 접근 방식은 원하는 캐릭터 속도 (float / scalar)로 시작한 다음 이동하려는 방향을 가리키는 정규화 된 벡터를 곱하는 것입니다. 내가 볼 수 있듯이 btVector3
클래스에는 이미이 모든 방법이 있습니다.
또는 캐릭터를 완전한 물리 객체로 취급하고 applyForce
또는 applyImpulse
메소드를 사용하여 움직임을 처리하는 것을 고려할 수 있습니다 . 이로 인해 신체 가속이 발생하므로 캐릭터의 추진력이 높아지고 결과는 아마도 이런 식으로 더 좋아 보일 것입니다. 그러나 선형 속도가 클램핑되거나 댐핑 / 마찰로 놀아서 특정 제한을 초과하지 않도록하는 등의 추가 조치를 취해야합니다. 따라서 구현하고 미세 조정하기가 조금 더 어려울 것입니다.
두 가지 접근 방식을 모두 실험 한 다음 필요에 가장 가까운 방식을 선택하십시오.
실제로 물리학에 대한 경험은 2D 게임 엔진에서 Chimpunk를 사용하고 있지만이 개념이 3D로 잘 해석 될 것입니다.
나는 당신의 성격이 무게와 같은 물리 몸이라고 가정합니다. 가장 좋은 방법은 걷기의 시뮬레이션을 단순화하는 것입니다. 이것을 다음과 같이 생각하십시오. 서 있으면 발에 마찰이 많이 발생하므로 미끄러지지 않습니다. 움직일 때는 마찰을 제거하고 (발로 움직임에 저항하지 않기 때문에) 방향 힘을 가하는 것과 거의 같습니다. 나는 당신이 각 발을지면에서 밀고있는 것을 개별적으로 시뮬레이션해야한다는 것을 말하는 것이 아닙니다 .
get이 조금 복잡 해지는 곳은 다음과 같습니다.
힘과 댐핑을 정확하게 조정하면, 힘이 가해지면 특히 캐릭터가 물체를 밀고있을 때 가장 현실적인 결과를 얻을 수 있습니다. 물리 엔진은 실제로 그것을 이동이라고 생각하지 않기 때문에 번역은 최악의 방법입니다. 속도를 직접 설정하는 것이 다소 좋지만 내 경험상 힘과 댐핑을 사용하여 최상의 결과를 얻을 수 있습니다.
잘만되면 나는 이것을 충분히 설명했다. 설명이 필요한지 언제든지 문의하십시오. :)
글 머리 기호 2.87의 경우 적절한 방법은 내부 시뮬레이션 업데이트 속도 (아마도 100의 Hz)로 업데이트하는 틱 콜백을 갖는 것 같고 운동학 바디의 setWorldTransform ()은 위치를 부드럽게 업데이트합니다.
이 부분은 매뉴얼에 있습니다 :
// set the rigid body as kinematic
rigid_body->setCollisionFlags(
rigid_body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
rigid_body->setActivationState(DISABLE_DEACTIVATION);
...
이 부분은 알아 내기가 더 까다로 웠습니다.
void externalTickCallback(btDynamicsWorld *world, btScalar timeStep)
{
// get object passed into user data point
Foo* foo = static_cast<Foo*>(world->getWorldUserInfo());
... loop through all the rigid bodies, maybe foo has them
{
if (rigid_body->getCollisionFlags() & btCollisionObject::CF_KINEMATIC_OBJECT)
{
btVector3 kinematic_linear_vel = ... // get velocity from somewhere
btTransform trans;
rigid_body->getMotionState()->getWorldTransform(trans);
trans.setOrigin(trans.getOrigin() + kinematic_linear_vel * time_step);
// TODO support angular velocity
rigid_body_->getMotionState()->setWorldTransform(trans);
}
}
}
...
my_dynamics_world->setInternalTickCallback(tickCallback, static_cast<void*>(this), true);
이것은 btRigidBody.h https://github.com/bulletphysics/bullet3/blob/master/src/BulletDynamics/Dynamics/btRigidBody.h의 유용한 문서입니다 .
///-C) 운동 학적 객체. 질량이없는 객체이지만 사용자는 이동할 수 있습니다. 단방향 상호 작용이 있으며 Bullet은 시간 간격과 이전 및 현재 월드 변환을 기반으로 속도를 계산합니다.
운동 학적 객체에는 setLinearVelocity ()가 작동하지 않습니다 (이전 버전에서는 사용 했었 을까요?). 그러나 역학 세계는 setWorldTransform ()을 이해하고 운동학 객체에서 getLinearVelocity ()를 호출하면 틱 콜백에 설정된 속도를 반환합니다 (속도가 내부 틱에서 틱으로 변경되면 평균을 반환합니다).
https://github.com/bulletphysics/bullet3/issues/1204- 문제 포스터에 올바른 아이디어가 있지만 응답이 도움이되지 않습니다.