Added smoothing of normals for raycast wheels, but disabled for now (since

the normals of some tracks need to be fixed).


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@7600 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2011-02-03 21:06:50 +00:00
parent d130ada5b1
commit 95a7e5c125
11 changed files with 287 additions and 24 deletions

View File

@ -250,6 +250,8 @@ supertuxkart_SOURCES = \
network/world_loaded_message.hpp \
physics/btKart.cpp \
physics/btKart.hpp \
physics/btKartRaycast.cpp \
phsycis/btKartRaycast.hpp \
physics/btUprightConstraint.cpp \
physics/btUprightConstraint.hpp \
physics/irr_debug_drawer.cpp \

View File

@ -158,6 +158,7 @@ void STKConfig::init_defaults()
m_max_track_version = -100;
m_title_music = NULL;
m_enable_networking = true;
m_smooth_normals = false;
m_same_powerup_mode = POWERUP_MODE_ONLY_IF_SAME;
m_score_increase.clear();
m_leader_intervals.clear();
@ -222,6 +223,11 @@ void STKConfig::getAllData(const XMLNode * root)
leader_node->get("time-per-kart", &m_leader_time_per_kart);
}
if (const XMLNode *physics_node= root->getNode("physics"))
{
physics_node->get("smooth-normals", &m_smooth_normals );
}
if (const XMLNode *startup_node= root->getNode("startup"))
{
startup_node->get("penalty", &m_penalty_time );

View File

@ -83,6 +83,8 @@ public:
or reverse point order. */
int m_max_history; /**<Maximum number of frames to save in
a history files. */
bool m_smooth_normals; /**< If normals for raycasts for wheels
should be interpolated. */
int m_max_skidmarks; /**<Maximum number of skid marks/kart. */
float m_skid_fadeout_time; /**<Time till skidmarks fade away. */
float m_near_ground; /**<Determines when a kart is not near

View File

@ -578,6 +578,10 @@
RelativePath="..\..\physics\btKart.cpp"
>
</File>
<File
RelativePath="..\..\physics\btKartRaycast.cpp"
>
</File>
<File
RelativePath="..\..\physics\btUprightConstraint.cpp"
>
@ -1520,6 +1524,10 @@
RelativePath="..\..\physics\btKart.hpp"
>
</File>
<File
RelativePath="..\..\physics\btKartRaycast.hpp"
>
</File>
<File
RelativePath="..\..\physics\btUprightConstraint.hpp"
>

View File

@ -46,6 +46,7 @@
#include "network/race_state.hpp"
#include "network/network_manager.hpp"
#include "physics/btKart.hpp"
#include "physics/btKartRaycast.hpp"
#include "physics/btUprightConstraint.hpp"
#include "physics/physics.hpp"
#include "race/history.hpp"
@ -231,7 +232,7 @@ void Kart::createPhysics()
// Create the actual vehicle
// -------------------------
m_vehicle_raycaster =
new btDefaultVehicleRaycaster(World::getWorld()->getPhysics()->getPhysicsWorld());
new btKartRaycaster(World::getWorld()->getPhysics()->getPhysicsWorld());
m_tuning = new btKart::btVehicleTuning();
m_tuning->m_maxSuspensionTravelCm = m_kart_properties->getSuspensionTravelCM();
m_vehicle = new btKart(*m_tuning, m_body, m_vehicle_raycaster,

View File

@ -0,0 +1,95 @@
/*
* Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Erwin Coumans makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#include "LinearMath/btVector3.h"
#include "btKartRaycast.hpp"
#include "BulletCollision/CollisionDispatch/btCollisionWorld.h"
#include "BulletDynamics/Dynamics/btDynamicsWorld.h"
#include "modes/world.hpp"
#include "physics/triangle_mesh.hpp"
#include "tracks/track.hpp"
void* btKartRaycaster::castRay(const btVector3& from, const btVector3& to,
btVehicleRaycasterResult& result)
{
// ========================================================================
class ClosestWithNormal : public btCollisionWorld::ClosestRayResultCallback
{
private:
int m_triangle_index;
public:
/** Constructor, initialises the triangle index. */
ClosestWithNormal(const btVector3 &from,
const btVector3 &to)
: btCollisionWorld::ClosestRayResultCallback(from,to)
{
m_triangle_index = -1;
} // CloestWithNormal
// --------------------------------------------------------------------
/** Stores the index of the triangle hit. */
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult,
bool normalInWorldSpace)
{
// We don't always get a triangle index, sometimes (e.g. ray hits
// other kart) we get shapePart=-1, or no localShapeInfo at all
if(rayResult.m_localShapeInfo &&
rayResult.m_localShapeInfo->m_shapePart>-1)
m_triangle_index = rayResult.m_localShapeInfo->m_triangleIndex;
return
btCollisionWorld::ClosestRayResultCallback::addSingleResult(rayResult,
normalInWorldSpace);
}
// --------------------------------------------------------------------
/** Returns the index of the triangle which was hit, or -1 if
* no triangle was hit. */
int getTriangleIndex() const { return m_triangle_index; }
}; // CloestWithNormal
// ========================================================================
ClosestWithNormal rayCallback(from,to);
m_dynamicsWorld->rayTest(from, to, rayCallback);
if (rayCallback.hasHit())
{
btRigidBody* body = btRigidBody::upcast(rayCallback.m_collisionObject);
if (body && body->hasContactResponse())
{
result.m_hitPointInWorld = rayCallback.m_hitPointWorld;
result.m_hitNormalInWorld = rayCallback.m_hitNormalWorld;
result.m_hitNormalInWorld.normalize();
result.m_distFraction = rayCallback.m_closestHitFraction;
const TriangleMesh &tm =
World::getWorld()->getTrack()->getTriangleMesh();
if(stk_config->m_smooth_normals &&
rayCallback.getTriangleIndex()>-1)
{
btVector3 n=result.m_hitNormalInWorld;
result.m_hitNormalInWorld =
tm.getInterpolatedNormal(rayCallback.getTriangleIndex(),
result.m_hitPointInWorld);
#ifdef DEBUG_NORMALS
printf("old %f %f %f new %f %f %f\n",
n.getX(), n.getY(), n.getZ(),
result.m_hitNormalInWorld.getX(),
result.m_hitNormalInWorld.getY(),
result.m_hitNormalInWorld.getZ());
#endif
}
return body;
}
}
return 0;
}

View File

@ -0,0 +1,39 @@
/*
* Copyright (c) 2005 Erwin Coumans http://continuousphysics.com/Bullet/
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies.
* Erwin Coumans makes no representations about the suitability
* of this software for any purpose.
* It is provided "as is" without express or implied warranty.
*/
#ifndef BTKARTRAYCASTER_HPP
#define BTKARTRAYCSATER_HPP
#include "BulletDynamics/Dynamics/btRigidBody.h"
#include "BulletDynamics/ConstraintSolver/btTypedConstraint.h"
#include "BulletDynamics/Vehicle/btVehicleRaycaster.h"
class btDynamicsWorld;
#include "LinearMath/btAlignedObjectArray.h"
#include "BulletDynamics/Vehicle/btWheelInfo.h"
#include "BulletDynamics/Dynamics/btActionInterface.h"
class btKartRaycaster : public btVehicleRaycaster
{
btDynamicsWorld* m_dynamicsWorld;
public:
btKartRaycaster(btDynamicsWorld* world)
:m_dynamicsWorld(world)
{
}
virtual void* castRay(const btVector3& from,const btVector3& to,
btVehicleRaycasterResult& result);
};
#endif //RAYCASTVEHICLE_H

View File

@ -46,10 +46,22 @@ TriangleMesh::~TriangleMesh()
} // ~TriangleMesh
// -----------------------------------------------------------------------------
/** Adds a triangle to the bullet mesh. It also stores the material used for
* this triangle, and the three normals.
* \param t1,t2,t3 Points of the triangle.
* \param n1,n2,n3 Normals at the corresponding points.
* \param m Material used for this triangle
*/
void TriangleMesh::addTriangle(const btVector3 &t1, const btVector3 &t2,
const btVector3 &t3, const Material* m)
const btVector3 &t3,
const btVector3 &n1, const btVector3 &n2,
const btVector3 &n3,
const Material* m)
{
m_triangleIndex2Material.push_back(m);
m_normals.push_back(n1);
m_normals.push_back(n2);
m_normals.push_back(n3);
m_mesh.addTriangle(t1, t2, t3);
} // addTriangle
@ -106,3 +118,51 @@ void TriangleMesh::removeBody()
} // removeBody
// -----------------------------------------------------------------------------
/** Interpolates the normal at the given position for the triangle with
* a given index. The position must be inside of the given triangle.
* \param index Index of the triangle to use.
* \param position The position for which to interpolate the normal.
*/
btVector3 TriangleMesh::getInterpolatedNormal(unsigned int index,
const btVector3 &position) const
{
btVector3 p1, p2, p3;
getTriangle(index, &p1, &p2, &p3);
btVector3 n1, n2, n3;
getNormals(index, &n1, &n2, &n3);
// Compute the Barycentric coordinates of position inside triangle
// p1, p2, p3.
btVector3 edge1 = p2 - p1;
btVector3 edge2 = p3 - p1;
// Area of triangle ABC
btScalar p1p2p3 = edge1.cross(edge2).length2();
// Area of BCP
btScalar p2p3p = (p3 - p2).cross(position - p2).length2();
// Area of CAP
btScalar p3p1p = edge2.cross(position - p3).length2();
btScalar s = btSqrt(p2p3p / p1p2p3);
btScalar t = btSqrt(p3p1p / p1p2p3);
btScalar w = 1.0f - s - t;
#ifdef NORMAL_DEBUGGING
btVector3 regen_position = s * p1 + t * p2 + w * p3;
if((regen_position - position).length2() >= 0.0001f)
{
printf("bary:\n");
printf("new: %f %f %f\n", regen_position.getX(),regen_position.getY(),regen_position.getZ());
printf("old: %f %f %f\n", position.getX(), position.getY(),position.getZ());
printf("stw: %f %f %f\n", s, t, w);
printf("p1: %f %f %f\n", p1.getX(),p1.getY(),p1.getZ());
printf("p2: %f %f %f\n", p2.getX(),p2.getY(),p2.getZ());
printf("p3: %f %f %f\n", p3.getX(),p3.getY(),p3.getZ());
printf("pos: %f %f %f\n", position.getX(),position.getY(),position.getZ());
}
#endif
return s*n1 + t*n2 + w*n3;
} // getInterpolatedNormal

View File

@ -24,6 +24,7 @@
#include "btBulletDynamicsCommon.h"
#include "physics/user_pointer.hpp"
#include "utils/aligned_array.hpp"
class Material;
@ -40,15 +41,46 @@ private:
btTriangleMesh m_mesh;
btDefaultMotionState *m_motion_state;
btCollisionShape *m_collision_shape;
/** The three normals for each triangle. */
AlignedArray<btVector3> m_normals;
public:
TriangleMesh();
~TriangleMesh();
void addTriangle(const btVector3 &t1, const btVector3 &t2,
const btVector3 &t3, const Material* m);
const btVector3 &t3, const btVector3 &n1,
const btVector3 &n2, const btVector3 &n3,
const Material* m);
void createBody(btCollisionObject::CollisionFlags flags=
(btCollisionObject::CollisionFlags)0);
void removeBody();
const Material* getMaterial(int n) const {return m_triangleIndex2Material[n];}
btVector3 getInterpolatedNormal(unsigned int index,
const btVector3 &position) const;
// ------------------------------------------------------------------------
const Material* getMaterial(int n) const
{return m_triangleIndex2Material[n];}
// ------------------------------------------------------------------------
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];
} // 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, 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];
} // getNormals
};
#endif
/* EOF */

View File

@ -439,6 +439,7 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
u16 *mbIndices = mb->getIndices();
Vec3 vertices[3];
Vec3 normals[3];
irr::video::S3DVertex* mbVertices=(video::S3DVertex*)mb->getVertices();
for(unsigned int j=0; j<mb->getIndexCount(); j+=3) {
for(unsigned int k=0; k<3; k++) {
@ -446,9 +447,12 @@ void Track::convertTrackToBullet(scene::ISceneNode *node)
core::vector3df v = mbVertices[indx].Pos;
mat.transformVect(v);
vertices[k]=v;
normals[k]=mbVertices[indx].Normal;
} // for k
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], material );
vertices[2], normals[0],
normals[1], normals[2],
material );
} // for j
} // for i<getMeshBufferCount

View File

@ -217,19 +217,6 @@ public:
/** Starts the music for this track. */
void startMusic () const;
/** Returns the filename of this track. */
const std::string& getFilename () const {return m_filename; }
const std::string& getDesigner () const {return m_designer; }
/** Returns an absolute path to the screenshot file of this track */
const std::string& getScreenshotFile () const {return m_screenshot; }
/** Returns the start coordinates for a kart with a given index.
* \param index Index of kart ranging from 0 to kart_num-1. */
btTransform getStartTransform (unsigned int index) const
{return m_start_transforms[index];}
void getTerrainInfo(const Vec3 &pos, float *hot, Vec3* normal,
const Material **material) const;
float getTerrainHeight(const Vec3 &pos) const;
@ -237,13 +224,33 @@ public:
void update(float dt);
void reset();
void adjustForFog(scene::ISceneNode *node);
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp) const;
/** Sets the current ambient color for a kart with index k. */
void setAmbientColor(const video::SColor &color,
unsigned int k);
void handleExplosion(const Vec3 &pos,
const PhysicalObject *mp) const;
// ------------------------------------------------------------------------
/** Returns the filename of this track. */
const std::string& getFilename () const {return m_filename; }
// ------------------------------------------------------------------------
/** Returns the name of the designer. */
const std::string& getDesigner () const {return m_designer; }
// ------------------------------------------------------------------------
/** Returns an absolute path to the screenshot file of this track */
const std::string& getScreenshotFile () const {return m_screenshot; }
// ------------------------------------------------------------------------
/** Returns the start coordinates for a kart with a given index.
* \param index Index of kart ranging from 0 to kart_num-1. */
btTransform getStartTransform (unsigned int index) const
{return m_start_transforms[index];}
// ------------------------------------------------------------------------
/** Sets pointer to the aabb of this track. */
void getAABB(const Vec3 **min, const Vec3 **max) const
{ *min = &m_aabb_min; *max = &m_aabb_max; }
// ------------------------------------------------------------------------
/** Returns the graph of quads, mainly for the AI. */
QuadGraph& getQuadGraph() const { return *m_quad_graph; }
// ------------------------------------------------------------------------
/** Returns 'a' angle for quad n. This angle is used to position a kart
* after a rescue, and to detect wrong directions. This function will
* always return the angle towards the first successor, i.e. the angle
@ -251,7 +258,8 @@ public:
* \param n Number of the quad for which the angle is asked.
*/
float getAngle(int n) const
{ return m_quad_graph->getAngleToNext(n, 0); }
{ return m_quad_graph->getAngleToNext(n, 0); }
// ------------------------------------------------------------------------
/** Returns the 2d coordinates of a point when drawn on the mini map
* texture.
* \param xyz Coordinates of the point to map.
@ -260,23 +268,29 @@ public:
*/
void mapPoint2MiniMap(const Vec3 &xyz, Vec3 *draw_at) const
{ m_quad_graph->mapPoint2MiniMap(xyz, draw_at); }
// ------------------------------------------------------------------------
/** Returns the full path of a given file inside this track directory. */
std::string getTrackFile(const std::string &s) const
{ return m_root+"/"+s; }
// ------------------------------------------------------------------------
/** Returns the number of modes available for this track. */
unsigned int getNumberOfModes() const { return m_all_modes.size(); }
// ------------------------------------------------------------------------
/** Returns the name of the i-th. mode. */
const std::string &getModeName(unsigned int i) const
{ return m_all_modes[i].m_name;}
// ------------------------------------------------------------------------
/** Returns the default ambient color. */
const video::SColor &getDefaultAmbientColor() const
{ return m_default_ambient_color;}
/** Sets the current ambient color for a kart with index k. */
void setAmbientColor(const video::SColor &color,
unsigned int k);
// ------------------------------------------------------------------------
/** Returns the far value for cameras. */
float getCameraFar() const { return m_camera_far; }
// ------------------------------------------------------------------------
/** Returns the triangle mesh for this track. */
const TriangleMesh& getTriangleMesh() const {return *m_track_mesh; }
// ------------------------------------------------------------------------
/** Get the number of start positions defined in the scene file. */
unsigned int getNumberOfStartPositions() const
{ return m_start_transforms.size(); }