Properly fix driving no physical objects to enable smoothing (e.g.
volcano in both directions).
This commit is contained in:
parent
76491d13ec
commit
c23873da37
@ -981,17 +981,17 @@ void btKart::debugDraw(btIDebugDraw* debugDrawer)
|
||||
if (n > -1)
|
||||
{
|
||||
const TriangleMesh &tm = Track::getCurrentTrack()->getTriangleMesh();
|
||||
btVector3 *p1, *p2, *p3;
|
||||
btVector3 p1, p2, p3;
|
||||
tm.getTriangle(n, &p1, &p2, &p3);
|
||||
const btVector3 *n1, *n2, *n3;
|
||||
btVector3 n1, n2, n3;
|
||||
tm.getNormals(n, &n1, &n2, &n3);
|
||||
// Draw the normals at the vertices
|
||||
debugDrawer->drawLine(*p1, *p1 + *n1, white);
|
||||
debugDrawer->drawLine(*p2, *p2 + *n2, white);
|
||||
debugDrawer->drawLine(*p3, *p3 + *n3, white);
|
||||
debugDrawer->drawLine(p1, p1 + n1, white);
|
||||
debugDrawer->drawLine(p2, p2 + n2, white);
|
||||
debugDrawer->drawLine(p3, p3 + n3, white);
|
||||
// Also draw the triangle in white, it can make it easier
|
||||
// to identify which triangle a wheel is on
|
||||
debugDrawer->drawTriangle(*p1, *p2, *p3, white, 1.0f);
|
||||
debugDrawer->drawTriangle(p1, p2, p3, white, 1.0f);
|
||||
}
|
||||
|
||||
} // for i < getNumWheels
|
||||
|
@ -81,9 +81,11 @@ void* btKartRaycaster::castRay(const btVector3& from, const btVector3& to,
|
||||
// different triangle mesh). TODO: Add a mapping from bullet
|
||||
// objects back to triangle meshes, so that it's easy to pick up
|
||||
// the right triangle mesh for smoothing
|
||||
TriangleMesh::RigidBodyTriangleMesh *rbtm =
|
||||
dynamic_cast<TriangleMesh::RigidBodyTriangleMesh*>(body);
|
||||
if(m_smooth_normals &&
|
||||
rayCallback.getTriangleIndex()>-1 &&
|
||||
body == Track::getCurrentTrack()->getTriangleMesh().getBody())
|
||||
rbtm != NULL )
|
||||
{
|
||||
#undef DEBUG_NORMALS
|
||||
#ifdef DEBUG_NORMALS
|
||||
@ -91,7 +93,7 @@ void* btKartRaycaster::castRay(const btVector3& from, const btVector3& to,
|
||||
#endif
|
||||
result.m_triangle_index = rayCallback.getTriangleIndex();
|
||||
result.m_hitNormalInWorld =
|
||||
tm.getInterpolatedNormal(rayCallback.getTriangleIndex(),
|
||||
rbtm->m_triangle_mesh->getInterpolatedNormal(rayCallback.getTriangleIndex(),
|
||||
result.m_hitPointInWorld);
|
||||
#ifdef DEBUG_NORMALS
|
||||
printf("old %f %f %f new %f %f %f\n",
|
||||
|
@ -378,7 +378,8 @@ void PhysicalObject::init(const PhysicalObject::Settings& settings)
|
||||
return;
|
||||
} // switch node->getType()
|
||||
|
||||
std::unique_ptr<TriangleMesh> triangle_mesh(new TriangleMesh());
|
||||
std::unique_ptr<TriangleMesh>
|
||||
triangle_mesh(new TriangleMesh(/*can_be_transformed*/true));
|
||||
|
||||
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++)
|
||||
{
|
||||
@ -522,7 +523,10 @@ void PhysicalObject::init(const PhysicalObject::Settings& settings)
|
||||
btRigidBody::btRigidBodyConstructionInfo info(m_mass, m_motion_state,
|
||||
m_shape, inertia);
|
||||
|
||||
m_body = new btRigidBody(info);
|
||||
if(m_triangle_mesh)
|
||||
m_body = new TriangleMesh::RigidBodyTriangleMesh(m_triangle_mesh, info);
|
||||
else
|
||||
m_body = new btRigidBody(info);
|
||||
m_user_pointer.set(this);
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
|
||||
|
@ -30,11 +30,12 @@
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Constructor: Initialises all data structures with zero.
|
||||
*/
|
||||
TriangleMesh::TriangleMesh() : m_mesh()
|
||||
TriangleMesh::TriangleMesh(bool can_be_transformed) : m_mesh()
|
||||
{
|
||||
m_body = NULL;
|
||||
m_free_body = true;
|
||||
m_motion_state = NULL;
|
||||
m_body = NULL;
|
||||
m_free_body = true;
|
||||
m_motion_state = NULL;
|
||||
m_can_be_transformed = can_be_transformed;
|
||||
// FIXME: on VS in release mode this statement actually overwrites
|
||||
// part of the data of m_mesh, causing a crash later. Debugging
|
||||
// shows that apparently m_collision_shape is at the same address
|
||||
@ -194,7 +195,7 @@ void TriangleMesh::createPhysicalBody(float friction,
|
||||
info.m_restitution = 0.8f;
|
||||
info.m_friction = friction;
|
||||
|
||||
m_body=new btRigidBody(info);
|
||||
m_body=new RigidBodyTriangleMesh(this, info);
|
||||
Physics::getInstance()->addBody(m_body);
|
||||
|
||||
m_body->setUserPointer(&m_user_pointer);
|
||||
@ -239,22 +240,41 @@ void TriangleMesh::removeAll()
|
||||
btVector3 TriangleMesh::getInterpolatedNormal(unsigned int index,
|
||||
const btVector3 &position) const
|
||||
{
|
||||
btVector3 *p1, *p2, *p3;
|
||||
getTriangle(index, &p1, &p2, &p3);
|
||||
const btVector3 *n1, *n2, *n3;
|
||||
getNormals(index, &n1, &n2, &n3);
|
||||
btVector3 p1, p2, p3;
|
||||
btVector3 n1, n2, n3;
|
||||
if(m_can_be_transformed)
|
||||
{
|
||||
btVector3 q1, q2, q3;
|
||||
getTriangle(index, &q1, &q2, &q3);
|
||||
const btTransform &tf = m_body->getWorldTransform();
|
||||
// The triangle verteces must be moved according to the transform of the body
|
||||
p1 = tf(q1);
|
||||
p2 = tf(q2);
|
||||
p3 = tf(q3);
|
||||
// The normals must be rotated according to the transform of the body
|
||||
btVector3 m1, m2, m3;
|
||||
getNormals(index, &m1, &m2, &m3);
|
||||
n1 = tf.getBasis() * m1;
|
||||
n2 = tf.getBasis() * m2;
|
||||
n3 = tf.getBasis() * m3;
|
||||
}
|
||||
else
|
||||
{
|
||||
getTriangle(index, &p1, &p2, &p3);
|
||||
getNormals(index, &n1, &n2, &n3);
|
||||
}
|
||||
|
||||
// Compute the Barycentric coordinates of position inside triangle
|
||||
// p1, p2, p3.
|
||||
|
||||
btScalar p1p2p3 = getP1P2P3(index);
|
||||
float p1p2p3 = getP1P2P3(index);
|
||||
|
||||
// Area of BCP
|
||||
btScalar p2p3p = (*p3 - *p2).cross(position - *p2).length2();
|
||||
btScalar p2p3p = (p3 - p2).cross(position - p2).length2();
|
||||
|
||||
// Area of CAP
|
||||
btVector3 edge2 = *p3 - *p1;
|
||||
btScalar p3p1p = edge2.cross(position - *p3).length2();
|
||||
btVector3 edge2 = p3 - p1;
|
||||
btScalar p3p1p = edge2.cross(position - p3).length2();
|
||||
btScalar s = btSqrt(p2p3p / p1p2p3);
|
||||
btScalar t = btSqrt(p3p1p / p1p2p3);
|
||||
btScalar w = 1.0f - s - t;
|
||||
@ -275,7 +295,7 @@ btVector3 TriangleMesh::getInterpolatedNormal(unsigned int index,
|
||||
}
|
||||
#endif
|
||||
|
||||
return s*(*n1) + t*(*n2) + w*(*n3);
|
||||
return s*n1 + t*n2 + w*n3;
|
||||
} // getInterpolatedNormal
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
@ -45,12 +45,32 @@ private:
|
||||
btVector3 dummy1, dummy2;
|
||||
btDefaultMotionState *m_motion_state;
|
||||
btCollisionShape *m_collision_shape;
|
||||
|
||||
/** The three normals for each triangle. */
|
||||
AlignedArray<btVector3> m_normals;
|
||||
|
||||
/** Pre-compute value used in smoothing. */
|
||||
AlignedArray<float> m_p1p2p3;
|
||||
|
||||
/** If the rigid body can be transformed (which means that normalising
|
||||
* the normals need to update the vertices and normals used according
|
||||
* to the current transform of the body. */
|
||||
bool m_can_be_transformed;
|
||||
|
||||
public:
|
||||
TriangleMesh();
|
||||
class RigidBodyTriangleMesh : public btRigidBody
|
||||
{
|
||||
public:
|
||||
TriangleMesh *m_triangle_mesh;
|
||||
RigidBodyTriangleMesh(TriangleMesh *tm,
|
||||
const btRigidBody::btRigidBodyConstructionInfo &ci)
|
||||
: btRigidBody(ci),
|
||||
m_triangle_mesh(tm)
|
||||
{
|
||||
} // RigidBodyTriangleMesh
|
||||
};
|
||||
|
||||
TriangleMesh(bool can_be_transformed);
|
||||
~TriangleMesh();
|
||||
void addTriangle(const btVector3 &t1, const btVector3 &t2,
|
||||
const btVector3 &t3, const btVector3 &n1,
|
||||
@ -96,27 +116,27 @@ public:
|
||||
/** Returns the points of the 'indx' triangle.
|
||||
* \param indx Index of the triangle to get.
|
||||
* \param p1,p2,p3 On return the three points of the triangle. */
|
||||
void getTriangle(unsigned int indx, btVector3 **p1, btVector3 **p2,
|
||||
btVector3 **p3) const
|
||||
void getTriangle(unsigned int indx, btVector3 *p1, btVector3 *p2,
|
||||
btVector3 *p3) const
|
||||
{
|
||||
const IndexedMeshArray &m = m_mesh.getIndexedMeshArray();
|
||||
btVector3 *p = &(((btVector3*)(m[0].m_vertexBase))[3*indx]);
|
||||
*p1 = &(p[0]);
|
||||
*p2 = &(p[1]);
|
||||
*p3 = &(p[2]);
|
||||
*p1 = p[0];
|
||||
*p2 = p[1];
|
||||
*p3 = p[2];
|
||||
} // getTriangle
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns the normals of the triangle with the given index.
|
||||
* \param indx Index of the triangle to get the three normals of.
|
||||
* \result n1,n2,n3 The three normals. */
|
||||
void getNormals(unsigned int indx, const btVector3 **n1,
|
||||
const btVector3 **n2, const btVector3 **n3) const
|
||||
void getNormals(unsigned int indx, btVector3 *n1,
|
||||
btVector3 *n2, btVector3 *n3) const
|
||||
{
|
||||
assert(indx < m_triangleIndex2Material.size());
|
||||
unsigned int n = indx*3;
|
||||
*n1 = &(m_normals[n ]);
|
||||
*n2 = &(m_normals[n+1]);
|
||||
*n3 = &(m_normals[n+2]);
|
||||
*n1 = m_normals[n ];
|
||||
*n2 = m_normals[n+1];
|
||||
*n3 = m_normals[n+2];
|
||||
} // getNormals
|
||||
// ------------------------------------------------------------------------
|
||||
/** Returns basically the area of the triangle, which is needed when
|
||||
|
@ -1095,8 +1095,8 @@ bool Track::loadMainTrack(const XMLNode &root)
|
||||
|
||||
m_challenges.clear();
|
||||
|
||||
m_track_mesh = new TriangleMesh();
|
||||
m_gfx_effect_mesh = new TriangleMesh();
|
||||
m_track_mesh = new TriangleMesh(/*can_be_transformed*/false);
|
||||
m_gfx_effect_mesh = new TriangleMesh(/*can_be_transformed*/false);
|
||||
|
||||
const XMLNode *track_node = root.getNode("track");
|
||||
std::string model_name;
|
||||
|
Loading…
Reference in New Issue
Block a user