1) Fixed 'objects' import from blender script: objects are now

converted into the physics track model (previously they were
   only shown, but karts could drive through them).
2) Cleaned start position code: arena and normal tracks now use
   the same way and variables/functions to specify the start
   positions.


git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/branches/irrlicht@4046 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
hikerstk 2009-09-24 14:26:03 +00:00
parent dacf594076
commit 049ab14678
3 changed files with 113 additions and 68 deletions

View File

@ -261,7 +261,7 @@ RaceGUI::KartIconDisplayInfo* ThreeStrikesBattle::getKartsDisplayInfo()
void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
{
// find closest point to drop kart on
const int start_spots_amount = RaceManager::getTrack()->m_start_positions.size();
const int start_spots_amount = RaceManager::getTrack()->getNumberOfStartPositions();
assert(start_spots_amount > 0);
int smallest_distance_found = -1, closest_id_found = -1;
@ -273,8 +273,9 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
{
// no need for the overhead to compute exact distance with sqrt(), so using the
// 'manhattan' heuristic which will do fine enough.
const int dist_n = abs((int)(kart_x - RaceManager::getTrack()->m_start_positions[n][0])) +
abs((int)(kart_y - RaceManager::getTrack()->m_start_positions[n][1]));
const Vec3 &v=RaceManager::getTrack()->getStartPosition(n);
const int dist_n = abs((int)(kart_x - v.getX())) +
abs((int)(kart_y - v.getY()));
if(dist_n < smallest_distance_found || closest_id_found == -1)
{
closest_id_found = n;
@ -283,11 +284,12 @@ void ThreeStrikesBattle::moveKartAfterRescue(Kart* kart, btRigidBody* body)
}
assert(closest_id_found != -1);
kart->setXYZ( Vec3(RaceManager::getTrack()->m_start_positions[closest_id_found]) );
const Vec3 &v=RaceManager::getTrack()->getStartPosition(closest_id_found);
kart->setXYZ( Vec3(v) );
// FIXME - implement correct heading
btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f), 0 /* angle */ );
btQuaternion heading(btVector3(0.0f, 0.0f, 1.0f),
RaceManager::getTrack()->getStartHeading(closest_id_found));
kart->setRotation(heading);
//position kart from same height as in World::resetAllKarts

View File

@ -2,6 +2,7 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004 Steve Baker <sjbaker1@airmail.net>
// 2009 Joerg Henrichs, Steve Baker
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -166,21 +167,9 @@ const Vec3& Track::trackToSpatial(const int sector) const
btTransform Track::getStartTransform(unsigned int pos) const
{
Vec3 orig;
if(isArena())
{
assert(pos < m_start_positions.size());
orig.setX( m_start_positions[pos][0] );
orig.setY( m_start_positions[pos][1] );
orig.setZ( m_start_positions[pos][2] );
}
else
{
orig.setX( pos<m_start_x.size() ? m_start_x[pos] : ((pos%2==0)?1.5f:-1.5f) );
orig.setY( pos<m_start_y.size() ? m_start_y[pos] : -1.5f*pos-1.5f );
orig.setZ( pos<m_start_z.size() ? m_start_z[pos] : 1.0f );
}
Vec3 orig = pos<m_start_positions.size()
? m_start_positions[pos]
: Vec3( (pos%2==0)?1.5f:-1.5f, -1.5f*pos-1.5f, 1.0f);
btTransform start;
start.setOrigin(orig);
start.setRotation(btQuaternion(btVector3(0, 0, 1),
@ -226,10 +215,6 @@ void Track::loadTrackInfo(const std::string &filename)
root->get("item", &m_item_style);
root->get("screenshot", &m_screenshot);
root->get("sky-color", &m_sky_color);
root->get("start-x", &m_start_x);
root->get("start-y", &m_start_y);
root->get("start-z", &m_start_z);
root->get("start-heading", &m_start_heading);
root->get("use-fog", &m_use_fog);
root->get("fog-color", &m_fog_color);
root->get("fog-density", &m_fog_density);
@ -343,10 +328,13 @@ void Track::loadQuadGraph(unsigned int mode_id)
} // loadQuadGraph
// -----------------------------------------------------------------------------
//* Convert the ssg track tree into its physics equivalents.
void Track::createPhysicsModel()
/** Convert the track tree into its physics equivalents.
* \param main_track_count The number of meshes that are already converted
* when the main track was converted. Only the additional meshes
* added later still need to be converted.
*/
void Track::createPhysicsModel(unsigned int main_track_count)
{
// Remove the temporary track rigid body, and then convert all objects
// (i.e. the track and all additional objects) into a new rigid body
// and convert this again. So this way we have an optimised track
@ -367,9 +355,9 @@ void Track::createPhysicsModel()
}
m_track_mesh->removeBody();
for(unsigned int i=1; i<m_all_meshes.size(); i++)
for(unsigned int i=main_track_count; i<m_all_meshes.size(); i++)
{
convertTrackToBullet(m_all_meshes[i]);
convertTrackToBullet(m_all_meshes[i], m_all_nodes[i]);
}
m_track_mesh->createBody();
m_non_collision_mesh->createBody(btCollisionObject::CF_NO_CONTACT_RESPONSE);
@ -377,9 +365,18 @@ void Track::createPhysicsModel()
} // createPhysicsModel
// -----------------------------------------------------------------------------
//* Convert the graohics track into its physics equivalents.
void Track::convertTrackToBullet(const scene::IMesh *mesh)
/** Convert the graohics track into its physics equivalents.
* \param mesh The mesh to convert.
* \param node The scene node.
*/
void Track::convertTrackToBullet(const scene::IMesh *mesh,
const scene::ISceneNode *node)
{
const core::vector3df &pos = node->getPosition();
const core::vector3df &hpr = node->getRotation();
core::matrix4 mat;
mat.setRotationDegrees(hpr);
mat.setTranslation(pos);
for(unsigned int i=0; i<mesh->getMeshBufferCount(); i++) {
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
// FIXME: take translation/rotation into account
@ -405,7 +402,9 @@ void Track::convertTrackToBullet(const scene::IMesh *mesh)
for(unsigned int j=0; j<mb->getIndexCount(); j+=3) {
for(unsigned int k=0; k<3; k++) {
int indx=mbIndices[j+k];
vertices[k] = Vec3(mbVertices[indx].Pos);
core::vector3df v = mbVertices[indx].Pos;
mat.transformVect(v);
vertices[k] = Vec3(v);
} // for k
if(tmesh) tmesh->addTriangle(vertices[0], vertices[1],
vertices[2], material );
@ -418,43 +417,74 @@ void Track::convertTrackToBullet(const scene::IMesh *mesh)
* scene might use raycast on this track model to determine the actual
* height of the terrain.
*/
bool Track::loadMainTrack(const XMLNode &xml_node)
bool Track::loadMainTrack(const XMLNode &root)
{
const XMLNode *track_node= root.getNode("track");
std::string model_name;
xml_node.get("model", &model_name);
track_node->get("model", &model_name);
std::string full_path = m_root+"/"+model_name;
scene::IMesh *mesh = irr_driver->getAnimatedMesh(full_path);
if(!mesh)
{
fprintf(stderr, "Warning: Main track model '%s' in '%s' not found, aborting.\n",
xml_node.getName().c_str(), model_name.c_str());
track_node->getName().c_str(), model_name.c_str());
exit(-1);
}
m_all_meshes.push_back(mesh);
scene::ISceneNode *scene_node = irr_driver->addOctTree(mesh);
core::vector3df xyz(0,0,0);
track_node->getXYZ(&xyz);
core::vector3df hpr(0,0,0);
track_node->getHPR(&hpr);
scene_node->setPosition(xyz);
scene_node->setRotation(hpr);
handleAnimatedTextures(scene_node, *track_node);
m_all_nodes.push_back(scene_node);
MeshTools::minMax3D(mesh, &m_aabb_min, &m_aabb_max);
RaceManager::getWorld()->getPhysics()->init(m_aabb_min, m_aabb_max);
for(unsigned int i=0; i<track_node->getNumNodes(); i++)
{
const XMLNode *n=track_node->getNode(i);
assert(n->getName()=="object");
model_name="";
n->get("model", &model_name);
full_path = m_root+"/"+model_name;
scene::IAnimatedMesh *a_mesh = irr_driver->getAnimatedMesh(full_path);
if(!a_mesh)
{
fprintf(stderr, "Warning: object model '%s' not found, ignored.\n",
full_path.c_str());
continue;
}
m_all_meshes.push_back(a_mesh);
scene::ISceneNode *scene_node = irr_driver->addAnimatedMesh(a_mesh);
core::vector3df xyz(0,0,0);
n->get("xyz", &xyz);
core::vector3df hpr(0,0,0);
n->get("hpr", &hpr);
scene_node->setPosition(xyz);
scene_node->setRotation(hpr);
handleAnimatedTextures(scene_node, *n);
m_all_nodes.push_back(scene_node);
} // for i
// This will (at this stage) only convert the main track model.
convertTrackToBullet(mesh);
for(unsigned int i=0; i<m_all_meshes.size(); i++)
//for(unsigned int i=0; i<1; i++)
{
convertTrackToBullet(m_all_meshes[i], m_all_nodes[i]);
}
if (m_track_mesh == NULL)
{
fprintf(stderr, "ERROR: m_track_mesh == NULL, cannot loadMainTrack\n");
return false;
exit(-1);
}
m_track_mesh->createBody();
scene::ISceneNode *scene_node = irr_driver->addOctTree(mesh);
core::vector3df xyz(0,0,0);
xml_node.getXYZ(&xyz);
core::vector3df hpr(0,0,0);
xml_node.getHPR(&hpr);
scene_node->setPosition(xyz);
scene_node->setRotation(hpr);
handleAnimatedTextures(scene_node, xml_node);
m_all_nodes.push_back(scene_node);
scene_node->setMaterialFlag(video::EMF_LIGHTING, true);
scene_node->setMaterialFlag(video::EMF_GOURAUD_SHADING, true);
@ -463,7 +493,8 @@ bool Track::loadMainTrack(const XMLNode &xml_node)
// ----------------------------------------------------------------------------
/** Handles animated textures.
* \param node The node containing the data for the animated notion.
* \param node The scene node for which animated textures are handled.
* \param xml The node containing the data for the animated notion.
*/
void Track::handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml)
{
@ -631,8 +662,9 @@ void Track::loadTrackModel(unsigned int mode_id)
<<"', aborting.";
throw std::runtime_error(msg.str());
}
const XMLNode *node = root->getNode("track");
loadMainTrack(*node);
loadMainTrack(*root);
unsigned int main_track_count = m_all_meshes.size();
for(unsigned int i=0; i<root->getNumNodes(); i++)
{
const XMLNode *node = root->getNode(i);
@ -686,9 +718,12 @@ void Track::loadTrackModel(unsigned int mode_id)
}
else if (name=="start")
{
core::vector3df xyz(0,0,0);
Vec3 xyz(0,0,0);
node->getXYZ(&xyz);
m_start_positions.push_back(Vec3(xyz.X, xyz.Y, xyz.Z));
m_start_positions.push_back(xyz);
float h=0;
node->get("h", &h);
m_start_heading.push_back(h);
}
else if(name=="animations")
{
@ -777,7 +812,7 @@ void Track::loadTrackModel(unsigned int mode_id)
}
// Note: the physics world for irrlicht is created in loadMainTrack
createPhysicsModel();
createPhysicsModel(main_track_count);
if(UserConfigParams::m_track_debug)
m_quad_graph->createDebugMesh();
} // loadTrackModel

View File

@ -56,7 +56,10 @@ private:
std::string m_ident;
std::string m_screenshot;
std::vector<MusicInformation*> m_music;
std::vector<float> m_start_x, m_start_y, m_start_z, m_start_heading;
/** Start heading of karts (if specified in the scene file). */
std::vector<float> m_start_heading;
/** Start positions of karts (if specified in the scene file). */
std::vector<Vec3> m_start_positions;
std::string m_item_style;
std::string m_description;
std::string m_designer;
@ -150,23 +153,21 @@ private:
/** Checkline manager. */
CheckManager *m_check_manager;
void loadTrackInfo(const std::string &filename);
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
int bNeedHeight);
void loadQuadGraph(unsigned int mode_id);
void convertTrackToBullet(const scene::IMesh *mesh);
bool loadMainTrack(const XMLNode &node);
void createWater(const XMLNode &node);
void getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation*>& m_music );
void loadTrackInfo(const std::string &filename);
void itemCommand(const Vec3 &xyz, Item::ItemType item_type,
int bNeedHeight);
void loadQuadGraph(unsigned int mode_id);
void convertTrackToBullet(const scene::IMesh *mesh,
const scene::ISceneNode*node);
bool loadMainTrack(const XMLNode &node);
void createWater(const XMLNode &node);
void getMusicInformation(std::vector<std::string>& filenames,
std::vector<MusicInformation*>& m_music );
void loadCurves(const XMLNode &node);
void handleAnimatedTextures(scene::ISceneNode *node, const XMLNode &xml);
void handleSky(const XMLNode &root, const std::string &filename);
public:
/** Start positions for arenas (unused in linear races) */
std::vector<Vec3> m_start_positions;
static const float NOHIT;
@ -215,7 +216,7 @@ public:
void getTerrainInfo(const Vec3 &pos, float *hot, Vec3* normal,
const Material **material) const;
float getTerrainHeight(const Vec3 &pos) const;
void createPhysicsModel();
void createPhysicsModel(unsigned int main_track_count);
void update(float dt);
void reset();
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp) const;
@ -255,6 +256,13 @@ public:
/** Sets the current ambient color. */
void setAmbientColor(const video::SColor &color)
{ m_ambient_color = color; }
/** Get the number of start positions defined in the scene file. */
unsigned int getNumberOfStartPositions() const
{ return m_start_positions.size(); }
/** Returns the i-th. start position. */
const Vec3 &getStartPosition(unsigned int i) {return m_start_positions[i];}
/** Returns the heading of the i-th. start position. */
const float getStartHeading(unsigned int i) {return m_start_heading[i]; }
}; // class Track
#endif