子弹头车轮落后和错误的底盘俯仰方向
Posted
技术标签:
【中文标题】子弹头车轮落后和错误的底盘俯仰方向【英文标题】:Bullet vehicle wheels fall behind and wrong chassis pitch direction 【发布时间】:2013-12-09 22:54:40 【问题描述】:我已经创建了一个在顶部带有炮塔的子弹车,如下所示:
gEngineForce = 0.f;
gBreakingFrontForce = 0.f;
gBreakingBackForce = 0.f;
maxEngineForce = 20000.f;
minEngineForce = -2000.f;
maxBreakingFrontForce = 4000.f;
maxBreakingBackForce = 600.f;
gVehicleSteering = 0.f;
steeringIncrement = 0.002f;
steeringClamp = 0.6f;
wheelRadius = 0.5f;
wheelWidth = 0.4f;
wheelFriction = 50;
suspensionStiffness = 10.f;
suspensionDamping = 1.3f;
suspensionCompression = 4.4f;
rollInfluence = 0.1f;//1.0f
btScalar suspensionRestLength(0.6);
btVector3 wheelDirectionCS0(0, -1, 0);
btVector3 wheelAxleCS(-1, 0, 0);
btTransform tr;
tr.setIdentity();
chassisShape = new btBoxShape(btVector3(1.f, 0.5f, 2.f));
bulletCollisionShapes.push_back(chassisShape);
compound = new btCompoundShape();
bulletCollisionShapes.push_back(compound);
btTransform chassisTrans;
chassisTrans.setIdentity();
//localTrans effectively shifts the center of mass with respect to the chassis
chassisTrans.setOrigin(btVector3(0, 1.3, 0));
compound->addChildShape(chassisTrans, chassisShape);
tr.setOrigin(btVector3(0, 0.f, 0));
//m_carChassis = CreateRigidBody(2000, tr, compound);
//m_carChassis->setDamping(0.2,0.2);
m_wheelShape = new btCylinderShapeX(btVector3(wheelWidth, wheelRadius, wheelRadius));
m_carChassis = CreateRigidBody(2000, tr, compound);
// create turret
turretShape = new btBoxShape(btVector3(0.4f, 0.2f, 0.8f));
bulletCollisionShapes.push_back(turretShape);
btTransform turretTrans;
turretTrans.setIdentity();
turretTrans.setOrigin(btVector3(0.0f, 0.7f, 0.0f));
turretBody = CreateRigidBody(1, turretTrans, turretShape);
// add some data to build constraint frames
btVector3 axisA(0.f, 1.f, 0.f);
btVector3 axisB(0.f, 0.f, 0.f);
btVector3 pivotA(0.f, 1.f, 0.f);
btVector3 pivotB(0.f, 0.f, 0.f);
hinge = new btHingeConstraint(*m_carChassis, *turretBody, pivotA, pivotB, axisA, axisB);
//hinge->setLimit(-SIMD_HALF_PI * 0.5f, SIMD_HALF_PI * 0.5f);
hinge->enableAngularMotor(true, 0, 1);
// add constraint to world
bt_dynamicsWorld->addConstraint(hinge, true);
btTransform something;
something.setIdentity();
something.setOrigin(btVector3(0, 10, 0));
m_carChassis->setWorldTransform(something);
m_vehicleRayCaster = new btDefaultVehicleRaycaster(bt_dynamicsWorld);
m_vehicle = new btRaycastVehicle(m_tuning, m_carChassis, m_vehicleRayCaster);
m_carChassis->setActivationState(DISABLE_DEACTIVATION);
bt_dynamicsWorld->addVehicle(m_vehicle);
float connectionHeight = 1.2f;
//choose coordinate system
m_vehicle->setCoordinateSystem(rightIndex, upIndex, forwardIndex);
bool isFrontWheel = true;
btVector3 connectionPointCS0(1 - (-0.8*wheelWidth), connectionHeight, 3 * 1 - wheelRadius);
m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
connectionPointCS0 = btVector3(-1 + (-0.8*wheelWidth), connectionHeight, 3 * 1 - wheelRadius);
m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
isFrontWheel = false;
connectionPointCS0 = btVector3(-1 + (-0.8*wheelWidth), connectionHeight, -3 * 1 + wheelRadius);
m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
connectionPointCS0 = btVector3(1 - (-0.8*wheelWidth), connectionHeight, -3 * 1 + wheelRadius);
m_vehicle->addWheel(connectionPointCS0, wheelDirectionCS0, wheelAxleCS, suspensionRestLength, wheelRadius, m_tuning, isFrontWheel);
for (int i = 0; i < m_vehicle->getNumWheels(); i++)
btWheelInfo& wheel = m_vehicle->getWheelInfo(i);
wheel.m_suspensionStiffness = suspensionStiffness;
wheel.m_wheelsDampingRelaxation = suspensionDamping;
wheel.m_wheelsDampingCompression = suspensionCompression;
wheel.m_frictionSlip = wheelFriction;
wheel.m_rollInfluence = rollInfluence;
int wheelIndex = 2;
m_vehicle->applyEngineForce(gEngineForce, wheelIndex);
m_vehicle->setBrake(gBreakingBackForce, wheelIndex);
wheelIndex = 3;
m_vehicle->applyEngineForce(gEngineForce, wheelIndex);
m_vehicle->setBrake(gBreakingBackForce, wheelIndex);
wheelIndex = 0;
m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex);
m_vehicle->setBrake(gBreakingFrontForce, wheelIndex);
wheelIndex = 1;
m_vehicle->setSteeringValue(gVehicleSteering, wheelIndex);
m_vehicle->setBrake(gBreakingFrontForce, wheelIndex);
这是我渲染车辆的方式:
// render wheels
btScalar mwheel[16];
for (int i = 0; i<m_vehicle->getNumWheels(); i++)
//synchronize the wheels with the (interpolated) chassis worldtransform
m_vehicle->updateWheelTransform(i, true);
//draw wheels
m_vehicle->getWheelInfo(i).m_worldTransform.getOpenGLMatrix(mwheel);
RenderWheel(m_wheelShape, mwheel);
// render car chassis
btScalar mchassis[16];
m_vehicle->getChassisWorldTransform().getOpenGLMatrix(mchassis);
RenderBox(chassisShape, mchassis);
// render turret
btScalar mturret[16];
// get chassis and turret transforms
btTransform chassisTransform = m_vehicle->getChassisWorldTransform();
//btTransform turretTransform = compound->getChildTransform(1);
btTransform turretTransform = turretBody->getWorldTransform();
// multiply transforms to get updated turret transform
//turretTransform *= chassisTransform;
turretTransform.getOpenGLMatrix(mturret);
RenderBox(turretShape, mturret);
使用箭头键,我可以像这样施加中断或加速力:
bullet.gEngineForce = bullet.maxEngineForce;
bullet.gBreakingFrontForce = 0.f;
bullet.gBreakingBackForce = 0.f;
等等
摄像头安装在汽车顶部的炮塔上,因此安装在汽车本身上。
问题在于,当汽车开始行驶并加速时,车轮似乎落后而底盘向前移动。我想让***和底盘更紧,但玩弄汽车悬架设置并没有帮助。
这是一个演示此行为的视频:click
我还注意到另一个与汽车在移动、刹车和转弯时的倾斜方式有关的奇怪行为。
增加重力会加重这种行为。当我加速时,底盘向前倾斜,当我刹车时,它向后倾斜。这显然是错误的,因为它应该是相反的。左转时也会发生同样的情况,汽车向左而不是向右倾斜,反之亦然。
这是另一个演示此行为的视频:click
【问题讨论】:
你解决问题了吗? 【参考方案1】:我遇到了这种问题。事实证明,车轮是使用变换渲染的,而不是来自与底盘相同的框架。即从框架 n-1 开始,而底盘使用框架 n。
事情并不明显,因为车轮网格是底盘节点的子节点,因为它是我在渲染引擎中实现的方式,而在子弹物理中,车轮坐标是全局的,底盘也是如此。 但这还不是全部,当将车轮坐标从全局转换为局部车辆空间时,会出现精度损失,这仍然会导致问题。它是通过将车轮网格作为全局节点来修复的。
【讨论】:
以上是关于子弹头车轮落后和错误的底盘俯仰方向的主要内容,如果未能解决你的问题,请参考以下文章