From: <hik...@us...> - 2009-09-24 14:26:14
|
Revision: 4046 http://supertuxkart.svn.sourceforge.net/supertuxkart/?rev=4046&view=rev Author: hikerstk Date: 2009-09-24 14:26:03 +0000 (Thu, 24 Sep 2009) Log Message: ----------- 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. Modified Paths: -------------- main/branches/irrlicht/data/tracks/stk_track.py main/branches/irrlicht/src/modes/three_strikes_battle.cpp main/branches/irrlicht/src/tracks/track.cpp main/branches/irrlicht/src/tracks/track.hpp Modified: main/branches/irrlicht/data/tracks/stk_track.py =================================================================== --- main/branches/irrlicht/data/tracks/stk_track.py 2009-09-23 01:04:31 UTC (rev 4045) +++ main/branches/irrlicht/data/tracks/stk_track.py 2009-09-24 14:26:03 UTC (rev 4046) @@ -598,7 +598,7 @@ # Note: Y and Z are swapped! f.write(" <animations-IPO obj=\"%s\" %s %s>\n"% \ - (b3d_name, getXYZHPRString(obj), shape),) + (b3d_name, getXYZHPRString(obj), shape)) dInterp = {IpoCurve.InterpTypes.BEZIER: "bezier", IpoCurve.InterpTypes.LINEAR: "linear", IpoCurve.InterpTypes.CONST: "const" } @@ -643,7 +643,7 @@ # -------------------------------------------------------------------------- # Writes out all animations (be it animations with IPO or animations with # path constraints). - def writeAnimations(self, f, sPath, lAnimations, lObjects): + def writeAnimations(self, f, sPath, lAnimations): scene = Blender.Scene.getCurrent() f.write(" <animations fps=\"%d\">\n"%scene.getRenderingContext().fps) for obj in lAnimations: @@ -652,13 +652,25 @@ self.writeAnimationWithIPO(f, sPath, obj, ipo) else: self.writeAnimationsWithPaths(f, sPath, obj) - # For now objects are exported as animations (with no IPO attached) - for obj in lObjects: - self.writeAnimationWithIPO(f, sPath, obj, []) - f.write(" </animations>\n") # -------------------------------------------------------------------------- + # Write the objects that are part of the track (but not animated or + # physical). + def writeObjects(self, f, sPath, lObjects): + for obj in lObjects: + # An object can set the 'name' property, then this name will + # be used to name the exported object (instead of the python name + # which might be a default name with a number). Additionally, names + # are cached so it can be avoided to export two or more identical + # objects. + b3d_name = getProperty(obj, "name", obj.name)+".b3d" + if not self.dExportedObjects.has_key(b3d_name): + exportLocalB3D(obj, sPath+"/"+b3d_name) + f.write(" <object model=\"%s\" %s/>\n"% \ + (b3d_name, getXYZHPRString(obj)) ) + + # -------------------------------------------------------------------------- # Writes out all checklines. def writeChecks(self, f, lChecks): f.write(" <checks>\n") @@ -728,7 +740,13 @@ f.write("<?xml version=\"1.0\"?>\n") f.write("<scene>\n") - f.write(" <track model=\"%s\" x=\"0\" y=\"0\" z=\"0\"/>\n"%sTrackName) + if lObjects: + f.write(" <track model=\"%s\" x=\"0\" y=\"0\" z=\"0\">\n"%sTrackName) + self.writeObjects(f, sPath, lObjects) + f.write(" </track>\n") + else: + f.write(" <track model=\"%s\" x=\"0\" y=\"0\" z=\"0\"/>\n"%sTrackName) + if sWaterName: f.write(" <water model=\"%s\" x=\"0\" y=\"0\" z=\"0\"/>\n""" \ % sWaterName) @@ -777,8 +795,8 @@ f.write(" model=\"%s\" shape=\"%s\" mass=\"%f\"/>\n"\ % (name, shape, mass)) - if lAnimations or lObjects: - self.writeAnimations(f, sPath, lAnimations, lObjects) + if lAnimations: + self.writeAnimations(f, sPath, lAnimations) if lChecks: self.writeChecks(f, lChecks) scene = Blender.Scene.getCurrent() Modified: main/branches/irrlicht/src/modes/three_strikes_battle.cpp =================================================================== --- main/branches/irrlicht/src/modes/three_strikes_battle.cpp 2009-09-23 01:04:31 UTC (rev 4045) +++ main/branches/irrlicht/src/modes/three_strikes_battle.cpp 2009-09-24 14:26:03 UTC (rev 4046) @@ -261,7 +261,7 @@ 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 @@ { // 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 @@ } assert(closest_id_found != -1); + const Vec3 &v=RaceManager::getTrack()->getStartPosition(closest_id_found); + kart->setXYZ( Vec3(v) ); - kart->setXYZ( Vec3(RaceManager::getTrack()->m_start_positions[closest_id_found]) ); - // 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 Modified: main/branches/irrlicht/src/tracks/track.cpp =================================================================== --- main/branches/irrlicht/src/tracks/track.cpp 2009-09-23 01:04:31 UTC (rev 4045) +++ main/branches/irrlicht/src/tracks/track.cpp 2009-09-24 14:26:03 UTC (rev 4046) @@ -2,6 +2,7 @@ // // SuperTuxKart - a fun racing game with go-kart // Copyright (C) 2004 Steve Baker <sjb...@ai...> +// 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 @@ 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 @@ 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 @@ } // 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 @@ } 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 @@ } // 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 @@ 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 @@ * 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 @@ // ---------------------------------------------------------------------------- /** 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 @@ <<"', 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 @@ } 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 @@ } // 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 Modified: main/branches/irrlicht/src/tracks/track.hpp =================================================================== --- main/branches/irrlicht/src/tracks/track.hpp 2009-09-23 01:04:31 UTC (rev 4045) +++ main/branches/irrlicht/src/tracks/track.hpp 2009-09-24 14:26:03 UTC (rev 4046) @@ -56,7 +56,10 @@ 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 @@ /** 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 @@ 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 @@ /** 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 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |