From be76aae2566b48427221edcccff695261687fa11 Mon Sep 17 00:00:00 2001 From: hiker Date: Sun, 29 Jun 2014 22:53:35 +1000 Subject: [PATCH] Interpolate the normal for the gravity to allow smoother changes of gravity - though it does not improve the bumpiness on twisted road section. --- src/physics/triangle_mesh.cpp | 33 +++++++++++++++++++++++---------- src/physics/triangle_mesh.hpp | 2 +- src/tracks/terrain_info.cpp | 6 ++++-- 3 files changed, 28 insertions(+), 13 deletions(-) diff --git a/src/physics/triangle_mesh.cpp b/src/physics/triangle_mesh.cpp index e57c37793..4b338388b 100644 --- a/src/physics/triangle_mesh.cpp +++ b/src/physics/triangle_mesh.cpp @@ -274,12 +274,16 @@ btVector3 TriangleMesh::getInterpolatedNormal(unsigned int index, * \param xyz The position in world where the ray hit. * \param material The material of the mesh that was hit. * \param normal The intrapolated normal at that position. + * \param interpolate_normal If true, the returned normal is the interpolated + * based on the three normals of the triangle and the location of the + * hit point (which is more compute intensive, but results in much + * smoother results). * \return True if a triangle was hit, false otherwise (and no output * variable will be set. */ bool TriangleMesh::castRay(const btVector3 &from, const btVector3 &to, btVector3 *xyz, const Material **material, - btVector3 *normal) const + btVector3 *normal, bool interpolate_normal) const { if(!m_collision_shape) { @@ -300,26 +304,25 @@ bool TriangleMesh::castRay(const btVector3 &from, const btVector3 &to, btCollisionWorld::ClosestRayResultCallback result(from, to); - + /** A special ray result class that stores the index of the triangle + * that was hit. */ class MaterialRayResult : public btCollisionWorld::ClosestRayResultCallback { public: - const Material* m_material; - const TriangleMesh *m_this; + /** Stores the index of the triangle that was hit. */ + int m_index; // -------------------------------------------------------------------- MaterialRayResult(const btVector3 &p1, const btVector3 &p2, const TriangleMesh *me) : btCollisionWorld::ClosestRayResultCallback(p1,p2) { - m_material = NULL; - m_this = me; + m_index = -1;; } // MaterialRayResult // -------------------------------------------------------------------- virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) { - m_material = - m_this->getMaterial(rayResult.m_localShapeInfo->m_triangleIndex); + m_index = rayResult.m_localShapeInfo->m_triangleIndex; return btCollisionWorld::ClosestRayResultCallback ::addSingleResult(rayResult, normalInWorldSpace); } // AddSingleResult @@ -335,13 +338,23 @@ bool TriangleMesh::castRay(const btVector3 &from, const btVector3 &to, : m_body, m_collision_shape, world_trans, ray_callback); + // Get the index of the triangle hit + int index = ray_callback.m_index; if(ray_callback.hasHit()) { *xyz = ray_callback.m_hitPointWorld; - *material = ray_callback.m_material; + *material = m_triangleIndex2Material[index]; + if(normal) { - *normal = ray_callback.m_hitNormalWorld; + // If requested interpolate the normal. I.e. instead of using + // the normal of the triangle interpolate the normal at the + // hit position based on the three normals of the triangle. + if(interpolate_normal) + *normal = getInterpolatedNormal(ray_callback.m_index, + ray_callback.m_hitPointWorld); + else + *normal = ray_callback.m_hitNormalWorld; normal->normalize(); } } diff --git a/src/physics/triangle_mesh.hpp b/src/physics/triangle_mesh.hpp index 118ec2de5..185c21302 100644 --- a/src/physics/triangle_mesh.hpp +++ b/src/physics/triangle_mesh.hpp @@ -70,7 +70,7 @@ public: // ------------------------------------------------------------------------ bool castRay(const btVector3 &from, const btVector3 &to, btVector3 *xyz, const Material **material, - btVector3 *normal=NULL) const; + btVector3 *normal=NULL, bool interpolate_normal=false) const; // ------------------------------------------------------------------------ /** Returns the points of the 'indx' triangle. * \param indx Index of the triangle to get. diff --git a/src/tracks/terrain_info.cpp b/src/tracks/terrain_info.cpp index b12f0d9d3..64c60eea5 100644 --- a/src/tracks/terrain_info.cpp +++ b/src/tracks/terrain_info.cpp @@ -57,7 +57,8 @@ void TerrainInfo::update(const Vec3 &from) to.setY(-10000.0f); const TriangleMesh &tm = World::getWorld()->getTrack()->getTriangleMesh(); - tm.castRay(from, to, &m_hit_point, &m_material, &m_normal); + tm.castRay(from, to, &m_hit_point, &m_material, &m_normal, + /*interpolate*/false); } // update //----------------------------------------------------------------------------- /** Update the terrain information based on the latest position. @@ -71,7 +72,8 @@ void TerrainInfo::update(const btTransform &trans, const Vec3 &offset) to = trans(to); const TriangleMesh &tm = World::getWorld()->getTrack()->getTriangleMesh(); - tm.castRay(from, to, &m_hit_point, &m_material, &m_normal); + tm.castRay(from, to, &m_hit_point, &m_material, &m_normal, + /*interpolate*/true); } // update // -----------------------------------------------------------------------------