Add initial library object loading code. Not complete yet. Samuncle, this is for you ;)
git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/main/trunk@14840 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
7645883508
commit
36fc36c7fb
@ -154,12 +154,17 @@ void LodNodeLoader::done(Track* track,
|
||||
full_path = directory + "/" + group[m].second.m_model_file;
|
||||
|
||||
// TODO: check whether the mesh contains animations or not?
|
||||
scene::IMesh *a_mesh = irr_driver->getMesh(full_path);
|
||||
if(!a_mesh)
|
||||
scene::IMesh* a_mesh = irr_driver->getMesh(full_path);
|
||||
if (!a_mesh)
|
||||
{
|
||||
fprintf(stderr, "Warning: object model '%s' not found, ignored.\n",
|
||||
full_path.c_str());
|
||||
continue;
|
||||
a_mesh = irr_driver->getMesh(group[m].second.m_model_file);
|
||||
|
||||
if (!a_mesh)
|
||||
{
|
||||
Log::warn("LODNodeLoad", "Warning: object model '%s' not found, ignored.\n",
|
||||
full_path.c_str());
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
if (group[m].second.m_tangent)
|
||||
|
@ -1425,7 +1425,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
// Add the track directory to the texture search path
|
||||
file_manager->pushTextureSearchPath(m_root);
|
||||
file_manager->pushModelSearchPath (m_root);
|
||||
// First read the temporary materials.dat file if it exists
|
||||
|
||||
// First read the temporary materials.xml file if it exists
|
||||
try
|
||||
{
|
||||
std::string materials_file = m_root+"materials.xml";
|
||||
@ -1440,24 +1441,10 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
}
|
||||
catch (std::exception& e)
|
||||
{
|
||||
// no temporary materials.dat file, ignore
|
||||
// no temporary materials.xml file, ignore
|
||||
(void)e;
|
||||
}
|
||||
|
||||
// Start building the scene graph
|
||||
std::string path = m_root+m_all_modes[mode_id].m_scene;
|
||||
XMLNode *root = file_manager->createXMLTree(path);
|
||||
|
||||
// Make sure that we have a track (which is used for raycasts to
|
||||
// place other objects).
|
||||
if(!root || root->getName()!="scene")
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg<< "No track model defined in '"<<path
|
||||
<<"', aborting.";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
|
||||
// Load the graph only now: this function is called from world, after
|
||||
// the race gui was created. The race gui is needed since it stores
|
||||
// the information about the size of the texture to render the mini
|
||||
@ -1473,15 +1460,31 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
float upwards_distance = 0.1f;
|
||||
int karts_per_row = 2;
|
||||
|
||||
const XMLNode *default_start=root->getNode("default-start");
|
||||
if(default_start)
|
||||
|
||||
// Start building the scene graph
|
||||
std::string path = m_root + m_all_modes[mode_id].m_scene;
|
||||
XMLNode *root = file_manager->createXMLTree(path);
|
||||
|
||||
// Make sure that we have a track (which is used for raycasts to
|
||||
// place other objects).
|
||||
if (!root || root->getName()!="scene")
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg<< "No track model defined in '"<<path
|
||||
<<"', aborting.";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
|
||||
const XMLNode *default_start = root->getNode("default-start");
|
||||
if (default_start)
|
||||
{
|
||||
default_start->get("forwards-distance", &forwards_distance );
|
||||
default_start->get("sidewards-distance", &sidewards_distance);
|
||||
default_start->get("upwards-distance", &upwards_distance );
|
||||
default_start->get("karts-per-row", &karts_per_row );
|
||||
}
|
||||
if(!m_is_arena && !m_is_soccer && !m_is_cutscene)
|
||||
|
||||
if (!m_is_arena && !m_is_soccer && !m_is_cutscene)
|
||||
{
|
||||
m_start_transforms.resize(race_manager->getNumberOfKarts());
|
||||
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
||||
@ -1491,10 +1494,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
upwards_distance);
|
||||
}
|
||||
|
||||
unsigned int start_position_counter = 0;
|
||||
|
||||
// we need to check for fog before loading the main track model
|
||||
if(const XMLNode *node = root->getNode("sun"))
|
||||
if (const XMLNode *node = root->getNode("sun"))
|
||||
{
|
||||
node->get("xyz", &m_sun_position );
|
||||
node->get("ambient", &m_default_ambient_color);
|
||||
@ -1512,31 +1513,204 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
loadMainTrack(*root);
|
||||
unsigned int main_track_count = m_all_nodes.size();
|
||||
|
||||
LodNodeLoader lod_loader;
|
||||
loadObjects(root, path);
|
||||
|
||||
for(unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
// ---- Fog
|
||||
// It's important to execute this BEFORE the code that creates the skycube,
|
||||
// otherwise the skycube node could be modified to have fog enabled, which
|
||||
// we don't want
|
||||
if (m_use_fog && !UserConfigParams::m_camera_debug && !irr_driver->isGLSL())
|
||||
{
|
||||
/* NOTE: if LINEAR type, density does not matter, if EXP or EXP2, start
|
||||
and end do not matter */
|
||||
irr_driver->getVideoDriver()->setFog(m_fog_color,
|
||||
video::EFT_FOG_LINEAR,
|
||||
m_fog_start, m_fog_end,
|
||||
1.0f);
|
||||
}
|
||||
|
||||
// Enable for for all track nodes if fog is used
|
||||
const unsigned int count = m_all_nodes.size();
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
adjustForFog(m_all_nodes[i]);
|
||||
}
|
||||
m_track_object_manager->enableFog(m_use_fog);
|
||||
|
||||
// Sky dome and boxes support
|
||||
// --------------------------
|
||||
if(m_sky_type==SKY_DOME && m_sky_textures.size() > 0)
|
||||
{
|
||||
scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0],
|
||||
m_sky_hori_segments,
|
||||
m_sky_vert_segments,
|
||||
m_sky_texture_percent,
|
||||
m_sky_sphere_percent);
|
||||
for(unsigned int i=0; i<node->getMaterialCount(); i++)
|
||||
{
|
||||
video::SMaterial &irrMaterial=node->getMaterial(i);
|
||||
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
|
||||
{
|
||||
video::ITexture* t=irrMaterial.getTexture(j);
|
||||
if(!t) continue;
|
||||
core::matrix4 *m = &irrMaterial.getTextureMatrix(j);
|
||||
m_animated_textures.push_back(new MovingTexture(m, m_sky_dx, m_sky_dy));
|
||||
} // for j<MATERIAL_MAX_TEXTURES
|
||||
} // for i<getMaterialCount
|
||||
|
||||
m_all_nodes.push_back(node);
|
||||
}
|
||||
else if(m_sky_type==SKY_BOX && m_sky_textures.size() == 6)
|
||||
{
|
||||
m_all_nodes.push_back(irr_driver->addSkyBox(m_sky_textures));
|
||||
}
|
||||
else if(m_sky_type==SKY_COLOR)
|
||||
{
|
||||
World::getWorld()->setClearbackBufferColor(m_sky_color);
|
||||
}
|
||||
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath ();
|
||||
|
||||
// ---- Set ambient color
|
||||
m_ambient_color = m_default_ambient_color;
|
||||
irr_driver->getSceneManager()->setAmbientLight(m_ambient_color);
|
||||
|
||||
// ---- Create sun (non-ambient directional light)
|
||||
if (m_sun_position.getLengthSQ() < 0.03f)
|
||||
{
|
||||
m_sun_position = core::vector3df(500, 250, 250);
|
||||
}
|
||||
|
||||
const video::SColorf tmpf(m_sun_diffuse_color);
|
||||
m_sun = irr_driver->addLight(m_sun_position, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true);
|
||||
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
scene::ILightSceneNode *sun = (scene::ILightSceneNode *) m_sun;
|
||||
sun->setLightType(video::ELT_DIRECTIONAL);
|
||||
|
||||
// The angle of the light is rather important - let the sun
|
||||
// point towards (0,0,0).
|
||||
if (m_sun_position.getLengthSQ() < 0.03f)
|
||||
// Backward compatibility: if no sun is specified, use the
|
||||
// old hardcoded default angle
|
||||
m_sun->setRotation( core::vector3df(180, 45, 45) );
|
||||
else
|
||||
m_sun->setRotation((-m_sun_position).getHorizontalAngle());
|
||||
|
||||
sun->getLightData().SpecularColor = m_sun_specular_color;
|
||||
}
|
||||
|
||||
|
||||
createPhysicsModel(main_track_count);
|
||||
|
||||
|
||||
for (unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string &name = node->getName();
|
||||
if (name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro" ||
|
||||
name=="easter-egg" )
|
||||
{
|
||||
itemCommand(node);
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
|
||||
delete root;
|
||||
|
||||
if (UserConfigParams::m_track_debug &&
|
||||
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES &&
|
||||
!m_is_cutscene)
|
||||
{
|
||||
QuadGraph::get()->createDebugMesh();
|
||||
}
|
||||
|
||||
// Only print warning if not in battle mode, since battle tracks don't have
|
||||
// any quads or check lines.
|
||||
if (CheckManager::get()->getCheckStructureCount()==0 &&
|
||||
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && !m_is_cutscene)
|
||||
{
|
||||
Log::warn("track", "No check lines found in track '%s'.",
|
||||
m_ident.c_str());
|
||||
Log::warn("track", "Lap counting will not work, and start "
|
||||
"positions might be incorrect.");
|
||||
}
|
||||
|
||||
if (UserConfigParams::logMemory())
|
||||
{
|
||||
Log::debug("track", "[memory] After loading '%s': mesh cache %d "
|
||||
"texture cache %d\n", getIdent().c_str(),
|
||||
irr_driver->getSceneManager()->getMeshCache()->getMeshCount(),
|
||||
irr_driver->getVideoDriver()->getTextureCount());
|
||||
}
|
||||
|
||||
World *world = World::getWorld();
|
||||
if (world->useChecklineRequirements())
|
||||
{
|
||||
QuadGraph::get()->computeChecklineRequirements();
|
||||
}
|
||||
|
||||
EasterEggHunt *easter_world = dynamic_cast<EasterEggHunt*>(world);
|
||||
if(easter_world)
|
||||
{
|
||||
std::string dir = StringUtils::getPath(m_filename);
|
||||
easter_world->readData(dir+"/easter_eggs.xml");
|
||||
}
|
||||
|
||||
irr_driver->unsetTextureErrorMessage();
|
||||
} // loadTrackModel
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
void Track::loadObjects(const XMLNode* root, const std::string& path)
|
||||
{
|
||||
LodNodeLoader lod_loader;
|
||||
unsigned int start_position_counter = 0;
|
||||
|
||||
unsigned int node_count = root->getNumNodes();
|
||||
for (unsigned int i = 0; i < node_count; i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string name = node->getName();
|
||||
// The track object was already converted before the loop, and the
|
||||
// default start was already used, too - so ignore those.
|
||||
if(name=="track" || name=="default-start") continue;
|
||||
if(name=="object")
|
||||
if (name == "track" || name == "default-start") continue;
|
||||
if (name == "object")
|
||||
{
|
||||
lod_loader.check(node);
|
||||
m_track_object_manager->add(*node);
|
||||
}
|
||||
else if(name=="water")
|
||||
else if (name == "library")
|
||||
{
|
||||
std::string name;
|
||||
node->get("name", &name);
|
||||
std::string lib_node_path = file_manager->getAsset("library/" + name + "/node.xml");
|
||||
std::string lib_path = file_manager->getAsset("library/" + name);
|
||||
XMLNode *libroot = file_manager->createXMLTree(lib_node_path);
|
||||
if (libroot == NULL) continue;
|
||||
|
||||
file_manager->pushTextureSearchPath(lib_path + "/");
|
||||
file_manager->pushModelSearchPath (lib_path);
|
||||
|
||||
loadObjects(libroot, lib_path);
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath();
|
||||
}
|
||||
else if (name == "water")
|
||||
{
|
||||
createWater(*node);
|
||||
}
|
||||
else if(name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro" ||
|
||||
name=="easter-egg" )
|
||||
else if (name == "banana" || name == "item" ||
|
||||
name == "small-nitro" || name == "big-nitro" ||
|
||||
name == "easter-egg" )
|
||||
{
|
||||
// will be handled later
|
||||
}
|
||||
else if (name=="start")
|
||||
else if (name == "start")
|
||||
{
|
||||
unsigned int position = start_position_counter;
|
||||
start_position_counter++;
|
||||
@ -1556,34 +1730,34 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
btQuaternion(btVector3(0,1,0),
|
||||
h*DEGREE_TO_RAD ) );
|
||||
}
|
||||
else if(name=="camera")
|
||||
else if (name == "camera")
|
||||
{
|
||||
node->get("far", &m_camera_far);
|
||||
}
|
||||
else if(name=="checks")
|
||||
else if (name == "checks")
|
||||
{
|
||||
CheckManager::get()->load(*node);
|
||||
}
|
||||
else if (name=="particle-emitter")
|
||||
else if (name == "particle-emitter")
|
||||
{
|
||||
if (UserConfigParams::m_graphical_effects)
|
||||
{
|
||||
m_track_object_manager->add(*node);
|
||||
}
|
||||
}
|
||||
else if(name=="sky-dome" || name=="sky-box" || name=="sky-color")
|
||||
else if (name == "sky-dome" || name == "sky-box" || name == "sky-color")
|
||||
{
|
||||
handleSky(*node, path);
|
||||
}
|
||||
else if(name=="end-cameras")
|
||||
else if (name == "end-cameras")
|
||||
{
|
||||
Camera::readEndCamera(*node);
|
||||
}
|
||||
else if(name=="light")
|
||||
else if (name == "light")
|
||||
{
|
||||
m_track_object_manager->add(*node);
|
||||
}
|
||||
else if(name=="weather")
|
||||
else if (name == "weather")
|
||||
{
|
||||
std::string weather_particles;
|
||||
std::string weather_type;
|
||||
@ -1646,13 +1820,16 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
// -------- Create and assign LOD nodes --------
|
||||
// recheck the static area, we will need LOD info
|
||||
const XMLNode* track_node = root->getNode("track");
|
||||
for(unsigned int i=0; i<track_node->getNumNodes(); i++)
|
||||
if (track_node != NULL)
|
||||
{
|
||||
const XMLNode* n = track_node->getNode(i);
|
||||
bool is_instance = false;
|
||||
n->get("lod_instance", &is_instance);
|
||||
for(unsigned int i=0; i<track_node->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode* n = track_node->getNode(i);
|
||||
bool is_instance = false;
|
||||
n->get("lod_instance", &is_instance);
|
||||
|
||||
if (!is_instance) lod_loader.check(n);
|
||||
if (!is_instance) lod_loader.check(n);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<LODNode*> lod_nodes;
|
||||
@ -1664,154 +1841,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
||||
|
||||
// Init all track objects
|
||||
m_track_object_manager->init();
|
||||
|
||||
|
||||
// ---- Fog
|
||||
// It's important to execute this BEFORE the code that creates the skycube,
|
||||
// otherwise the skycube node could be modified to have fog enabled, which
|
||||
// we don't want
|
||||
if (m_use_fog && !UserConfigParams::m_camera_debug && !irr_driver->isGLSL())
|
||||
{
|
||||
/* NOTE: if LINEAR type, density does not matter, if EXP or EXP2, start
|
||||
and end do not matter */
|
||||
irr_driver->getVideoDriver()->setFog(m_fog_color,
|
||||
video::EFT_FOG_LINEAR,
|
||||
m_fog_start, m_fog_end,
|
||||
1.0f);
|
||||
}
|
||||
|
||||
// Enable for for all track nodes if fog is used
|
||||
//if(m_use_fog)
|
||||
//{
|
||||
const unsigned int count = m_all_nodes.size();
|
||||
for(unsigned int i=0; i<count; i++)
|
||||
{
|
||||
adjustForFog(m_all_nodes[i]);
|
||||
}
|
||||
//}
|
||||
m_track_object_manager->enableFog(m_use_fog);
|
||||
|
||||
// Sky dome and boxes support
|
||||
// --------------------------
|
||||
if(m_sky_type==SKY_DOME && m_sky_textures.size() > 0)
|
||||
{
|
||||
scene::ISceneNode *node = irr_driver->addSkyDome(m_sky_textures[0],
|
||||
m_sky_hori_segments,
|
||||
m_sky_vert_segments,
|
||||
m_sky_texture_percent,
|
||||
m_sky_sphere_percent);
|
||||
for(unsigned int i=0; i<node->getMaterialCount(); i++)
|
||||
{
|
||||
video::SMaterial &irrMaterial=node->getMaterial(i);
|
||||
for(unsigned int j=0; j<video::MATERIAL_MAX_TEXTURES; j++)
|
||||
{
|
||||
video::ITexture* t=irrMaterial.getTexture(j);
|
||||
if(!t) continue;
|
||||
core::matrix4 *m = &irrMaterial.getTextureMatrix(j);
|
||||
m_animated_textures.push_back(new MovingTexture(m, m_sky_dx, m_sky_dy));
|
||||
} // for j<MATERIAL_MAX_TEXTURES
|
||||
} // for i<getMaterialCount
|
||||
|
||||
m_all_nodes.push_back(node);
|
||||
}
|
||||
else if(m_sky_type==SKY_BOX && m_sky_textures.size() == 6)
|
||||
{
|
||||
m_all_nodes.push_back(irr_driver->addSkyBox(m_sky_textures));
|
||||
}
|
||||
else if(m_sky_type==SKY_COLOR)
|
||||
{
|
||||
World::getWorld()->setClearbackBufferColor(m_sky_color);
|
||||
}
|
||||
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath ();
|
||||
|
||||
// ---- Set ambient color
|
||||
m_ambient_color = m_default_ambient_color;
|
||||
irr_driver->getSceneManager()->setAmbientLight(m_ambient_color);
|
||||
|
||||
// ---- Create sun (non-ambient directional light)
|
||||
if (m_sun_position.getLengthSQ() < 0.03f)
|
||||
{
|
||||
m_sun_position = core::vector3df(500, 250, 250);
|
||||
}
|
||||
|
||||
const video::SColorf tmpf(m_sun_diffuse_color);
|
||||
m_sun = irr_driver->addLight(m_sun_position, 10000.0f, 0., tmpf.r, tmpf.g, tmpf.b, true);
|
||||
|
||||
if (!irr_driver->isGLSL())
|
||||
{
|
||||
scene::ILightSceneNode *sun = (scene::ILightSceneNode *) m_sun;
|
||||
sun->setLightType(video::ELT_DIRECTIONAL);
|
||||
|
||||
// The angle of the light is rather important - let the sun
|
||||
// point towards (0,0,0).
|
||||
if(m_sun_position.getLengthSQ() < 0.03f)
|
||||
// Backward compatibility: if no sun is specified, use the
|
||||
// old hardcoded default angle
|
||||
m_sun->setRotation( core::vector3df(180, 45, 45) );
|
||||
else
|
||||
m_sun->setRotation((-m_sun_position).getHorizontalAngle());
|
||||
|
||||
sun->getLightData().SpecularColor = m_sun_specular_color;
|
||||
}
|
||||
|
||||
|
||||
createPhysicsModel(main_track_count);
|
||||
|
||||
|
||||
for(unsigned int i=0; i<root->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *node = root->getNode(i);
|
||||
const std::string &name = node->getName();
|
||||
if (name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro" ||
|
||||
name=="easter-egg" )
|
||||
{
|
||||
itemCommand(node);
|
||||
}
|
||||
} // for i<root->getNumNodes()
|
||||
|
||||
delete root;
|
||||
|
||||
if (UserConfigParams::m_track_debug &&
|
||||
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES &&
|
||||
!m_is_cutscene)
|
||||
QuadGraph::get()->createDebugMesh();
|
||||
|
||||
// Only print warning if not in battle mode, since battle tracks don't have
|
||||
// any quads or check lines.
|
||||
if(CheckManager::get()->getCheckStructureCount()==0 &&
|
||||
race_manager->getMinorMode()!=RaceManager::MINOR_MODE_3_STRIKES && !m_is_cutscene)
|
||||
{
|
||||
Log::warn("track", "No check lines found in track '%s'.",
|
||||
m_ident.c_str());
|
||||
Log::warn("track", "Lap counting will not work, and start "
|
||||
"positions might be incorrect.");
|
||||
}
|
||||
|
||||
if(UserConfigParams::logMemory())
|
||||
Log::debug("track", "[memory] After loading '%s': mesh cache %d "
|
||||
"texture cache %d\n", getIdent().c_str(),
|
||||
irr_driver->getSceneManager()->getMeshCache()->getMeshCount(),
|
||||
irr_driver->getVideoDriver()->getTextureCount());
|
||||
|
||||
World *world = World::getWorld();
|
||||
if (world->useChecklineRequirements())
|
||||
{
|
||||
QuadGraph::get()->computeChecklineRequirements();
|
||||
}
|
||||
|
||||
EasterEggHunt *easter_world = dynamic_cast<EasterEggHunt*>(world);
|
||||
if(easter_world)
|
||||
{
|
||||
std::string dir = StringUtils::getPath(m_filename);
|
||||
easter_world->readData(dir+"/easter_eggs.xml");
|
||||
}
|
||||
|
||||
irr_driver->unsetTextureErrorMessage();
|
||||
} // loadTrackModel
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
/** Changes all materials of the given mesh to use the current fog
|
||||
|
@ -399,6 +399,7 @@ private:
|
||||
std::vector<MusicInformation*>& m_music );
|
||||
void loadCurves(const XMLNode &node);
|
||||
void handleSky(const XMLNode &root, const std::string &filename);
|
||||
void loadObjects(const XMLNode* root, const std::string& path);
|
||||
|
||||
public:
|
||||
|
||||
|
@ -186,9 +186,14 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
|
||||
full_path = file_manager->getAsset(FileManager::MODEL,model_name);
|
||||
m_mesh = irr_driver->getAnimatedMesh(full_path);
|
||||
|
||||
if(!m_mesh)
|
||||
if (!m_mesh)
|
||||
{
|
||||
throw std::runtime_error("Model '" + model_name + "' cannot be found");
|
||||
m_mesh = irr_driver->getAnimatedMesh(model_name);
|
||||
|
||||
if (!m_mesh)
|
||||
{
|
||||
throw std::runtime_error("Model '" + model_name + "' cannot be found");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -457,10 +462,13 @@ TrackObjectPresentationBillboard::TrackObjectPresentationBillboard(const XMLNode
|
||||
xml_node.get("end", &m_fade_out_end );
|
||||
}
|
||||
|
||||
video::ITexture *texture =
|
||||
video::ITexture* texture =
|
||||
irr_driver->getTexture(file_manager->searchTexture(texture_name));
|
||||
m_node = irr_driver->addBillboard(core::dimension2df(width, height),
|
||||
texture);
|
||||
if (texture == NULL)
|
||||
{
|
||||
Log::warn("TrackObjectPresentation", "Billboard texture '%s' not found", texture_name.c_str());
|
||||
}
|
||||
m_node = irr_driver->addBillboard(core::dimension2df(width, height), texture);
|
||||
Material *stk_material = material_manager->getMaterial(texture_name);
|
||||
stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user