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;
|
full_path = directory + "/" + group[m].second.m_model_file;
|
||||||
|
|
||||||
// TODO: check whether the mesh contains animations or not?
|
// TODO: check whether the mesh contains animations or not?
|
||||||
scene::IMesh *a_mesh = irr_driver->getMesh(full_path);
|
scene::IMesh* a_mesh = irr_driver->getMesh(full_path);
|
||||||
if(!a_mesh)
|
if (!a_mesh)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "Warning: object model '%s' not found, ignored.\n",
|
a_mesh = irr_driver->getMesh(group[m].second.m_model_file);
|
||||||
full_path.c_str());
|
|
||||||
continue;
|
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)
|
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
|
// Add the track directory to the texture search path
|
||||||
file_manager->pushTextureSearchPath(m_root);
|
file_manager->pushTextureSearchPath(m_root);
|
||||||
file_manager->pushModelSearchPath (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
|
try
|
||||||
{
|
{
|
||||||
std::string materials_file = m_root+"materials.xml";
|
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)
|
catch (std::exception& e)
|
||||||
{
|
{
|
||||||
// no temporary materials.dat file, ignore
|
// no temporary materials.xml file, ignore
|
||||||
(void)e;
|
(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
|
// 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 race gui was created. The race gui is needed since it stores
|
||||||
// the information about the size of the texture to render the mini
|
// 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;
|
float upwards_distance = 0.1f;
|
||||||
int karts_per_row = 2;
|
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("forwards-distance", &forwards_distance );
|
||||||
default_start->get("sidewards-distance", &sidewards_distance);
|
default_start->get("sidewards-distance", &sidewards_distance);
|
||||||
default_start->get("upwards-distance", &upwards_distance );
|
default_start->get("upwards-distance", &upwards_distance );
|
||||||
default_start->get("karts-per-row", &karts_per_row );
|
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());
|
m_start_transforms.resize(race_manager->getNumberOfKarts());
|
||||||
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
QuadGraph::get()->setDefaultStartPositions(&m_start_transforms,
|
||||||
@ -1491,10 +1494,8 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
|||||||
upwards_distance);
|
upwards_distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int start_position_counter = 0;
|
|
||||||
|
|
||||||
// we need to check for fog before loading the main track model
|
// 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("xyz", &m_sun_position );
|
||||||
node->get("ambient", &m_default_ambient_color);
|
node->get("ambient", &m_default_ambient_color);
|
||||||
@ -1512,31 +1513,204 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
|||||||
loadMainTrack(*root);
|
loadMainTrack(*root);
|
||||||
unsigned int main_track_count = m_all_nodes.size();
|
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 XMLNode *node = root->getNode(i);
|
||||||
const std::string name = node->getName();
|
const std::string name = node->getName();
|
||||||
// The track object was already converted before the loop, and the
|
// The track object was already converted before the loop, and the
|
||||||
// default start was already used, too - so ignore those.
|
// default start was already used, too - so ignore those.
|
||||||
if(name=="track" || name=="default-start") continue;
|
if (name == "track" || name == "default-start") continue;
|
||||||
if(name=="object")
|
if (name == "object")
|
||||||
{
|
{
|
||||||
lod_loader.check(node);
|
lod_loader.check(node);
|
||||||
m_track_object_manager->add(*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);
|
createWater(*node);
|
||||||
}
|
}
|
||||||
else if(name=="banana" || name=="item" ||
|
else if (name == "banana" || name == "item" ||
|
||||||
name=="small-nitro" || name=="big-nitro" ||
|
name == "small-nitro" || name == "big-nitro" ||
|
||||||
name=="easter-egg" )
|
name == "easter-egg" )
|
||||||
{
|
{
|
||||||
// will be handled later
|
// will be handled later
|
||||||
}
|
}
|
||||||
else if (name=="start")
|
else if (name == "start")
|
||||||
{
|
{
|
||||||
unsigned int position = start_position_counter;
|
unsigned int position = start_position_counter;
|
||||||
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),
|
btQuaternion(btVector3(0,1,0),
|
||||||
h*DEGREE_TO_RAD ) );
|
h*DEGREE_TO_RAD ) );
|
||||||
}
|
}
|
||||||
else if(name=="camera")
|
else if (name == "camera")
|
||||||
{
|
{
|
||||||
node->get("far", &m_camera_far);
|
node->get("far", &m_camera_far);
|
||||||
}
|
}
|
||||||
else if(name=="checks")
|
else if (name == "checks")
|
||||||
{
|
{
|
||||||
CheckManager::get()->load(*node);
|
CheckManager::get()->load(*node);
|
||||||
}
|
}
|
||||||
else if (name=="particle-emitter")
|
else if (name == "particle-emitter")
|
||||||
{
|
{
|
||||||
if (UserConfigParams::m_graphical_effects)
|
if (UserConfigParams::m_graphical_effects)
|
||||||
{
|
{
|
||||||
m_track_object_manager->add(*node);
|
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);
|
handleSky(*node, path);
|
||||||
}
|
}
|
||||||
else if(name=="end-cameras")
|
else if (name == "end-cameras")
|
||||||
{
|
{
|
||||||
Camera::readEndCamera(*node);
|
Camera::readEndCamera(*node);
|
||||||
}
|
}
|
||||||
else if(name=="light")
|
else if (name == "light")
|
||||||
{
|
{
|
||||||
m_track_object_manager->add(*node);
|
m_track_object_manager->add(*node);
|
||||||
}
|
}
|
||||||
else if(name=="weather")
|
else if (name == "weather")
|
||||||
{
|
{
|
||||||
std::string weather_particles;
|
std::string weather_particles;
|
||||||
std::string weather_type;
|
std::string weather_type;
|
||||||
@ -1646,13 +1820,16 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
|||||||
// -------- Create and assign LOD nodes --------
|
// -------- Create and assign LOD nodes --------
|
||||||
// recheck the static area, we will need LOD info
|
// recheck the static area, we will need LOD info
|
||||||
const XMLNode* track_node = root->getNode("track");
|
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);
|
for(unsigned int i=0; i<track_node->getNumNodes(); i++)
|
||||||
bool is_instance = false;
|
{
|
||||||
n->get("lod_instance", &is_instance);
|
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;
|
std::vector<LODNode*> lod_nodes;
|
||||||
@ -1664,154 +1841,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
|
|||||||
|
|
||||||
// Init all track objects
|
// Init all track objects
|
||||||
m_track_object_manager->init();
|
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
|
/** Changes all materials of the given mesh to use the current fog
|
||||||
|
@ -399,6 +399,7 @@ private:
|
|||||||
std::vector<MusicInformation*>& m_music );
|
std::vector<MusicInformation*>& m_music );
|
||||||
void loadCurves(const XMLNode &node);
|
void loadCurves(const XMLNode &node);
|
||||||
void handleSky(const XMLNode &root, const std::string &filename);
|
void handleSky(const XMLNode &root, const std::string &filename);
|
||||||
|
void loadObjects(const XMLNode* root, const std::string& path);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
@ -186,9 +186,14 @@ TrackObjectPresentationMesh::TrackObjectPresentationMesh(const XMLNode& xml_node
|
|||||||
full_path = file_manager->getAsset(FileManager::MODEL,model_name);
|
full_path = file_manager->getAsset(FileManager::MODEL,model_name);
|
||||||
m_mesh = irr_driver->getAnimatedMesh(full_path);
|
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 );
|
xml_node.get("end", &m_fade_out_end );
|
||||||
}
|
}
|
||||||
|
|
||||||
video::ITexture *texture =
|
video::ITexture* texture =
|
||||||
irr_driver->getTexture(file_manager->searchTexture(texture_name));
|
irr_driver->getTexture(file_manager->searchTexture(texture_name));
|
||||||
m_node = irr_driver->addBillboard(core::dimension2df(width, height),
|
if (texture == NULL)
|
||||||
texture);
|
{
|
||||||
|
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);
|
Material *stk_material = material_manager->getMaterial(texture_name);
|
||||||
stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
|
stk_material->setMaterialProperties(&(m_node->getMaterial(0)), NULL);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user