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:
parent
d130ada5b1
commit
95a7e5c125
@ -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 \
|
||||
|
@ -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 );
|
||||
|
@ -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
|
||||
|
@ -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"
|
||||
>
|
||||
|
@ -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,
|
||||
|
95
src/physics/btKartRaycast.cpp
Normal file
95
src/physics/btKartRaycast.cpp
Normal 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;
|
||||
}
|
||||
|
39
src/physics/btKartRaycast.hpp
Normal file
39
src/physics/btKartRaycast.hpp
Normal 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
|
||||
|
@ -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
|
||||
|
@ -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 */
|
||||
|
@ -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
|
||||
|
||||
|
@ -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(); }
|
||||
|
Loading…
x
Reference in New Issue
Block a user