Both the old and new code are called from this tracewrapper, which sits as the code "between" the Bullet physics code and the PMOVE code:
Code: Select all
void tracewrapper(traceResults* const results, const Position3D& start, const Position3D& end, const Position3D& BBHalfExtents, const Rotation3D& rotation, const Object* const traceobj)
{
NewPhysTraceResults out;
// Both start and end are positions in worldspace that reference the center of the trace object
const bool hasHit = NewPhysicsTrace(&out, start, end, BBHalfExtents, rotation, traceobj);
if (out.fraction < 0.001f)
results->startsolid = true;
else
results->startsolid = false;
results->allsolid = false;
if (!hasHit)
{
results->endpos = end;
results->planenormal = Position3D(0.0f, 1.0f, 0.0f); // Just to set it to some known value, why not make it the up vector
results->entityNum = ENTITYNUM_NONE;
results->fraction = 1.0f;
}
else
{
results->fraction = out.fraction;
results->planenormal = out.hitNormal;
bprintf("Start: (%f, %f, %f) End: (%f, %f, %f) HitNormal: (%f, %f, %f) Fraction: %f Hitpos: (%f, %f, %f)\n",
start.xPos, start.yPos, start.zPos,
end.xPos, end.yPos, end.zPos,
results->planenormal.xPos, results->planenormal.yPos, results->planenormal.zPos, results->fraction,
results->endpos.xPos, results->endpos.yPos, results->endpos.zPos);
// Override the Bullet hit position with one computed from the fraction and the ray direction
// because Bullet's hit position will not necessarily lie on the cast line (unless
// using the old ray-based trace code):
results->endpos = (out.endPos - start) * results->fraction;
results->endpos += start;
results->entityNum = ENTITYNUM_WORLD;
}
}
Code: Select all
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Position3D& start, const Position3D& end,
const Position3D& BBHalfExtents, const Rotation3D& rotation, const Object* const traceobj)
{
// Note that the ray-based version doesn't do anything with the shape it constructs
btBoxShape newshape(btVector3(BBHalfExtents.xPos, BBHalfExtents.yPos, BBHalfExtents.zPos) );
btTransform from, to;
from.setIdentity();
from.setOrigin(btVector3(start.xPos, start.yPos, start.zPos) );
from.setRotation(btQuaternion(rotation.yRot, rotation.xRot, rotation.zRot) );
to.setIdentity();
to.setOrigin(btVector3(end.xPos, end.yPos, end.zPos) );
to.setRotation(btQuaternion(rotation.yRot, rotation.xRot, rotation.zRot) );
btCollisionWorld::ClosestRayResultCallback newRayTraceCallback(btVector3(start.xPos, start.yPos, start.zPos), btVector3(end.xPos, end.yPos, end.zPos) );
m_dynamicsWorld->rayTest(btVector3(start.xPos, start.yPos, start.zPos), btVector3(end.xPos, end.yPos, end.zPos), newRayTraceCallback);
out->fraction = newRayTraceCallback.m_closestHitFraction;
out->hitNormal.xPos = newRayTraceCallback.m_hitNormalWorld.x();
out->hitNormal.yPos = newRayTraceCallback.m_hitNormalWorld.y();
out->hitNormal.zPos = newRayTraceCallback.m_hitNormalWorld.z();
out->endPos.xPos = newRayTraceCallback.m_hitPointWorld.x();
out->endPos.yPos = newRayTraceCallback.m_hitPointWorld.y();
out->endPos.zPos = newRayTraceCallback.m_hitPointWorld.z();
return out->fraction < 1.0f; // This is the same as returning newRayTraceCallback.hasHit()
}
Code: Select all
const bool NewPhysicsTrace(NewPhysTraceResults* const out, const Position3D& start, const Position3D& end,
const Position3D& BBHalfExtents, const Rotation3D& rotation, const Object* const traceobj)
{
btBoxShape newshape(btVector3(BBHalfExtents.xPos, BBHalfExtents.yPos, BBHalfExtents.zPos) );
btTransform from, to;
from.setIdentity();
from.setOrigin(btVector3(start.xPos, start.yPos, start.zPos) );
from.setRotation(btQuaternion(rotation.yRot, rotation.xRot, rotation.zRot) );
to.setIdentity();
to.setOrigin(btVector3(end.xPos, end.yPos, end.zPos) );
to.setRotation(btQuaternion(rotation.yRot, rotation.xRot, rotation.zRot) );
btCollisionWorld::ClosestConvexResultCallback
newTraceCallback(btVector3(start.xPos, start.yPos, start.zPos), btVector3(end.xPos, end.yPos, end.zPos) );
m_dynamicsWorld->convexSweepTest(&newshape, from, to, newTraceCallback);
out->fraction = newTraceCallback.m_closestHitFraction;
out->hitNormal.xPos = newTraceCallback.m_hitNormalWorld.x();
out->hitNormal.yPos = newTraceCallback.m_hitNormalWorld.y();
out->hitNormal.zPos = newTraceCallback.m_hitNormalWorld.z();
out->endPos.xPos = newTraceCallback.m_hitPointWorld.x();
out->endPos.yPos = newTraceCallback.m_hitPointWorld.y();
out->endPos.zPos = newTraceCallback.m_hitPointWorld.z();
return out->fraction < 1.0f; // This is the same as returning newTraceCallback.hasHit()
}
If you want to see a video of the old (ray-based) character controller in action, you can see that here, but note that this is not a product advertisement, I'm looking for help on this problem!