From 049ab146780cd02f2a9712ef7b60ec7af192ed97 Mon Sep 17 00:00:00 2001 From: hikerstk Date: Thu, 24 Sep 2009 14:26:03 +0000 Subject: [PATCH] 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 --- src/modes/three_strikes_battle.cpp | 14 +-- src/tracks/track.cpp | 131 ++++++++++++++++++----------- src/tracks/track.hpp | 36 +++++--- 3 files changed, 113 insertions(+), 68 deletions(-) diff --git a/src/modes/three_strikes_battle.cpp b/src/modes/three_strikes_battle.cpp index baac9aabb..e90b1c848 100644 --- a/src/modes/three_strikes_battle.cpp +++ b/src/modes/three_strikes_battle.cpp @@ -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 diff --git a/src/tracks/track.cpp b/src/tracks/track.cpp index b475bd3ea..406b21cf5 100644 --- a/src/tracks/track.cpp +++ b/src/tracks/track.cpp @@ -2,6 +2,7 @@ // // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2004 Steve Baker +// 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( posget("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; icreateBody(); 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; igetMeshBufferCount(); 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; jgetIndexCount(); 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; igetNumNodes(); 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; icreateBody(); - - 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; igetNumNodes(); 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 diff --git a/src/tracks/track.hpp b/src/tracks/track.hpp index 54d17381d..d12c93e8d 100644 --- a/src/tracks/track.hpp +++ b/src/tracks/track.hpp @@ -56,7 +56,10 @@ private: std::string m_ident; std::string m_screenshot; std::vector m_music; - std::vector m_start_x, m_start_y, m_start_z, m_start_heading; + /** Start heading of karts (if specified in the scene file). */ + std::vector m_start_heading; + /** Start positions of karts (if specified in the scene file). */ + std::vector 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& filenames, - std::vector& 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& filenames, + std::vector& 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 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