Made skidlines appear to where the graphical wheels are (still not

100% correct).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14352 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk
2013-10-30 22:09:48 +00:00
parent 4c88999317
commit 90ca7db0c2
4 changed files with 112 additions and 38 deletions

View File

@@ -102,12 +102,11 @@ void SkidMarks::update(float dt, bool force_skid_marks,
// Get raycast information
// -----------------------
const btWheelInfo::RaycastInfo &raycast_right =
m_kart.getVehicle()->getWheelInfo(2).m_raycastInfo;
const btWheelInfo::RaycastInfo raycast_left =
m_kart.getVehicle()->getWheelInfo(3).m_raycastInfo;
Vec3 delta = raycast_right.m_contactPointWS
- raycast_left.m_contactPointWS;
const btKart *vehicle = m_kart.getVehicle();
const Vec3& raycast_right = vehicle->getVisualContactPoint(2);
const Vec3& raycast_left = vehicle->getVisualContactPoint(3);
Vec3 delta = raycast_right - raycast_left;
// The kart is making skid marks when it's:
// - forced to leave skid marks, or all of:
@@ -118,13 +117,13 @@ void SkidMarks::update(float dt, bool force_skid_marks,
// If only one wheel touches the ground, the 2nd one gets the same
// raycast result --> delta is 0, which is considered to be not skidding.
const Skidding *skid = m_kart.getSkidding();
bool is_skidding = raycast_right.m_isInContact &&
bool is_skidding = vehicle->visualWheelsTouchGround() &&
( force_skid_marks ||
( (skid->getSkidState()==Skidding::SKID_ACCUMULATE_LEFT||
skid->getSkidState()==Skidding::SKID_ACCUMULATE_RIGHT )
&& skid->getGraphicalJumpOffset()<=0
&& delta.length2()>=0.0001f ) );
is_skidding = true;
if(m_skid_marking)
{
if (!is_skidding) // end skid marking
@@ -141,20 +140,18 @@ void SkidMarks::update(float dt, bool force_skid_marks,
// -------------------------------------------------
delta.normalize();
delta *= m_width;
delta *= m_width*0.5f;
float distance = 0.0f;
Vec3 start = m_left[m_current]->getCenterStart();
Vec3 newPoint = (raycast_left.m_contactPointWS + raycast_right.m_contactPointWS)/2;
Vec3 newPoint = (raycast_left + raycast_right)/2;
// this linear distance does not account for the kart turning, it's true,
// but it produces good enough results
distance = (newPoint - start).length();
m_left [m_current]->add(raycast_left.m_contactPointWS,
raycast_left.m_contactPointWS + delta,
m_left [m_current]->add(raycast_left-delta, raycast_left+delta,
distance);
m_right[m_current]->add(raycast_right.m_contactPointWS-delta,
raycast_right.m_contactPointWS,
m_right[m_current]->add(raycast_right-delta, raycast_right+delta,
distance);
// Adjust the boundary box of the mesh to include the
// adjusted aabb of its buffers.
@@ -173,22 +170,20 @@ void SkidMarks::update(float dt, bool force_skid_marks,
// Start new skid marks
// --------------------
// No skidmarking if wheels don't have contact
if(!raycast_right.m_isInContact) return;
if(!vehicle->visualWheelsTouchGround()) return;
if(delta.length2()<0.0001) return;
delta.normalize();
delta *= m_width;
delta *= m_width*0.5f;
SkidMarkQuads *smq_left =
new SkidMarkQuads(raycast_left.m_contactPointWS,
raycast_left.m_contactPointWS + delta,
new SkidMarkQuads(raycast_left-delta, raycast_left+delta ,
m_material, m_avoid_z_fighting, custom_color);
scene::SMesh *new_mesh = new scene::SMesh();
new_mesh->addMeshBuffer(smq_left);
SkidMarkQuads *smq_right =
new SkidMarkQuads(raycast_right.m_contactPointWS - delta,
raycast_right.m_contactPointWS,
new SkidMarkQuads(raycast_right-delta, raycast_right+delta,
m_material, m_avoid_z_fighting, custom_color);
new_mesh->addMeshBuffer(smq_right);
scene::IMeshSceneNode *new_node = irr_driver->addMesh(new_mesh);
@@ -198,7 +193,7 @@ void SkidMarks::update(float dt, bool force_skid_marks,
#endif
// We don't keep a reference to the mesh here, so we have to decrement
// the reference count (which is set to 1 when doing "new SMesh()".
// the reference count (which is set to 1 when doing "new SMesh())".
// The scene node will keep the mesh alive.
new_mesh->drop();
m_current++;

View File

@@ -1969,7 +1969,7 @@ void Kart::updatePhysics(float dt)
m_skidding->update(dt, isOnGround(), m_controls.m_steer,
m_controls.m_skid);
m_vehicle->setVisualRotation(m_skidding->getVisualSkidRotation());
if(( m_skidding->getSkidState() == Skidding::SKID_ACCUMULATE_LEFT ||
m_skidding->getSkidState() == Skidding::SKID_ACCUMULATE_RIGHT ) &&
m_skidding->getGraphicalJumpOffset()==0)

View File

@@ -84,6 +84,7 @@ btWheelInfo& btKart::addWheel(const btVector3& connectionPointCS,
ci.m_maxSuspensionForce = tuning.m_maxSuspensionForce;
m_wheelInfo.push_back( btWheelInfo(ci));
m_visual_contact_point.push_back(btVector3());
btWheelInfo& wheel = m_wheelInfo[getNumWheels()-1];
@@ -111,16 +112,18 @@ void btKart::reset()
wheel.m_rotation = 0;
updateWheelTransform(i, true);
}
m_zipper_active = false;
m_zipper_velocity = btScalar(0);
m_skid_angular_velocity = 0;
m_is_skidding = false;
m_allow_sliding = false;
m_num_wheels_on_ground = 0;
m_additional_impulse = btVector3(0,0,0);
m_time_additional_impulse = 0;
m_additional_rotation = btVector3(0,0,0);
m_time_additional_rotation = 0;
m_visual_wheels_touch_ground = false;
m_zipper_active = false;
m_zipper_velocity = btScalar(0);
m_skid_angular_velocity = 0;
m_is_skidding = false;
m_allow_sliding = false;
m_num_wheels_on_ground = 0;
m_additional_impulse = btVector3(0,0,0);
m_time_additional_impulse = 0;
m_additional_rotation = btVector3(0,0,0);
m_time_additional_rotation = 0;
m_visual_rotation = 0;
// Set the brakes so that karts don't slide downhill
setAllBrakes(5.0f);
@@ -209,8 +212,12 @@ void btKart::updateWheelTransformsWS(btWheelInfo& wheel,
} // updateWheelTransformsWS
// ----------------------------------------------------------------------------
btScalar btKart::rayCast(btWheelInfo& wheel)
/**
*/
btScalar btKart::rayCast(unsigned int index)
{
btWheelInfo &wheel = m_wheelInfo[index];
// Work around a bullet problem: when using a convex hull the raycast
// would sometimes hit the chassis (which does not happen when using a
// box shape). Therefore set the collision mask in the chassis body so
@@ -225,7 +232,6 @@ btScalar btKart::rayCast(btWheelInfo& wheel)
updateWheelTransformsWS( wheel,false);
btScalar depth = -1;
btScalar raylen = wheel.getSuspensionRestLength()+wheel.m_wheelsRadius
@@ -311,12 +317,50 @@ btScalar btKart::rayCast(btWheelInfo& wheel)
wheel.m_clippedInvContactDotSuspension = btScalar(1.0);
}
#define USE_VISUAL
#ifndef USE_VISUAL
m_visual_contact_point[index] = rayResults.m_hitPointInWorld;
#else
if(index==2 || index==3)
{
if(m_visual_rotation==0)
{
m_visual_contact_point[index] = rayResults.m_hitPointInWorld;
m_visual_wheels_touch_ground &= (object!=NULL);
}
else
{
btTransform chassisTrans = getChassisWorldTransform();
if (getRigidBody()->getMotionState())
{
getRigidBody()->getMotionState()->getWorldTransform(chassisTrans);
}
btQuaternion q(Vec3(0,1,0), m_visual_rotation);
btQuaternion rot_new = chassisTrans.getRotation() * q;
chassisTrans.setRotation(rot_new);
btVector3 pos = wheel.m_chassisConnectionPointCS;
pos.setZ(pos.getZ() * 0.3f);
btVector3 source = chassisTrans( pos );
btVector3 target = source + rayvector;
btVehicleRaycaster::btVehicleRaycasterResult rayResults;
void* object = m_vehicleRaycaster->castRay(source,target,rayResults);
m_visual_contact_point[index] = rayResults.m_hitPointInWorld;
m_visual_wheels_touch_ground &= (object!=NULL);
}
}
#endif
if(m_chassisBody->getBroadphaseHandle())
{
m_chassisBody->getBroadphaseHandle()->m_collisionFilterGroup
= old_group;
}
return depth;
} // rayCast
// ----------------------------------------------------------------------------
@@ -342,11 +386,12 @@ void btKart::updateVehicle( btScalar step )
// Simulate suspension
// -------------------
m_num_wheels_on_ground = 0;
m_num_wheels_on_ground = 0;
m_visual_wheels_touch_ground = true;
for (int i=0;i<m_wheelInfo.size();i++)
{
btScalar depth;
depth = rayCast( m_wheelInfo[i]);
depth = rayCast( i);
if(m_wheelInfo[i].m_raycastInfo.m_isInContact)
m_num_wheels_on_ground++;
}

View File

@@ -122,6 +122,17 @@ private:
* properties. */
Kart *m_kart;
/** A visual rotation applied to the kart (for skidding).
* The physics use this to provide proper wheel contact points
* for skid marks. */
float m_visual_rotation;
/** True if the visual wheels touch the ground. */
bool m_visual_wheels_touch_ground;
/** Contact point of the visual wheel position. */
btAlignedObjectArray<btVector3> m_visual_contact_point;
btAlignedObjectArray<btWheelInfo> m_wheelInfo;
void defaultInit();
@@ -142,7 +153,7 @@ public:
void reset();
void debugDraw(btIDebugDraw* debugDrawer);
const btTransform& getChassisWorldTransform() const;
btScalar rayCast(btWheelInfo& wheel);
btScalar rayCast(unsigned int index);
virtual void updateVehicle(btScalar step);
void resetSuspension();
btScalar getSteeringValue(int wheel) const;
@@ -169,7 +180,22 @@ public:
void setSliding(bool active);
void instantSpeedIncreaseTo(float speed);
void capSpeed(float max_speed);
// ------------------------------------------------------------------------
/** Returns true if both rear visual wheels touch the ground. */
bool visualWheelsTouchGround() const
{
return m_visual_wheels_touch_ground;
} // visualWheelsTouchGround
// ------------------------------------------------------------------------
/** Returns the contact point of a visual wheel.
* \param n Index of the wheel, must be 2 or 3 since only the two rear
* wheels define the visual position
*/
const btVector3& getVisualContactPoint(int n) const
{
assert(n>=2 && n<=3);
return m_visual_contact_point[n];
} // getVisualContactPoint
// ------------------------------------------------------------------------
/** btActionInterface interface. */
virtual void updateAction(btCollisionWorld* collisionWorld,
@@ -230,6 +256,14 @@ public:
/** Returns the time an additional impulse is activated. */
float getCentralImpulseTime() const { return m_time_additional_impulse; }
// ------------------------------------------------------------------------
/** Sets a visual rotation to be applied, which the physics use to provide
* the location where the graphical wheels touch the ground (for
* skidmarks). */
void setVisualRotation(float angle)
{
m_visual_rotation = angle;
} // setVisualRotation
// ------------------------------------------------------------------------
/** Sets a rotation that is applied over a certain amount of time (to avoid
* a too rapid changes in the kart).
* \param t Time for the rotation to be applied.