merged with master

This commit is contained in:
Elderme 2016-08-18 22:36:19 +02:00
commit 41cd1e0364
101 changed files with 862 additions and 750 deletions

View File

@ -41,7 +41,6 @@ else()
endif() endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
option(USE_XRANDR "Use xrandr instead of vidmode" ON)
option(USE_ASAN "Build with Leak/Address sanitizer" OFF) option(USE_ASAN "Build with Leak/Address sanitizer" OFF)
option(USE_LIBBFD "Use libbfd for crash reporting and leak check" OFF) option(USE_LIBBFD "Use libbfd for crash reporting and leak check" OFF)
endif() endif()
@ -215,15 +214,10 @@ if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED) find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR}) include_directories(${X11_INCLUDE_DIR})
if(USE_XRANDR)
find_package(Xrandr REQUIRED) find_package(Xrandr REQUIRED)
if(NOT XRANDR_FOUND) if(NOT XRANDR_FOUND)
message(FATAL_ERROR "XRANDR not found.") message(FATAL_ERROR "XRANDR not found.")
endif() endif()
else()
find_library(IRRLICHT_XF86VM_LIBRARY Xxf86vm)
mark_as_advanced(IRRLICHT_XF86VM_LIBRARY)
endif()
if(USE_LIBBFD) if(USE_LIBBFD)
find_package(Libbfd) find_package(Libbfd)
@ -382,12 +376,7 @@ else()
endif() endif()
if(UNIX AND NOT APPLE) if(UNIX AND NOT APPLE)
target_link_libraries(supertuxkart ${X11_LIBRARIES}) target_link_libraries(supertuxkart ${X11_LIBRARIES} ${XRANDR_LIBRARIES})
if(USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
else()
target_link_libraries(supertuxkart ${IRRLICHT_XF86VM_LIBRARY})
endif()
if(USE_LIBBFD) if(USE_LIBBFD)
target_link_libraries(supertuxkart ${LIBBFD_LIBRARIES}) target_link_libraries(supertuxkart ${LIBBFD_LIBRARIES})
endif() endif()

Binary file not shown.

View File

@ -1,15 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<stkgui> <stkgui>
<div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" > <div x="2%" y="10%" width="96%" height="80%" layout="vertical-row" >
<label id="title" width="100%" text_align="center" word_wrap="true" proportion="1" /> <label id="title" width="100%" text_align="top" word_wrap="true" proportion="1" />
<spacer height="25" width="10" /> <spacer height="25" width="10" />
<button id="confirm" I18N="In a 'are you sure?' dialog" text="Yes" align="center"/> <buttonbar id="buttons" height="30%" width="30%" align="center">
<spacer height="15" width="10" /> <icon-button id="confirm" icon="gui/green_check.png" I18N="In a 'are you sure?' dialog"
text="Yes" align="center"/>
<button id="cancel" I18N="In a 'are you sure?' dialog" text="Cancel" align="center"/> <icon-button id="cancel" icon="gui/remove.png" I18N="In a 'are you sure?' dialog"
text="Cancel" align="center"/>
</buttonbar>
<spacer height="10" width="10" /> <spacer height="10" width="10" />
</div> </div>

View File

@ -30,7 +30,7 @@
<label width="100%" <label width="100%"
I18N="In the player configuration screen" I18N="In the player configuration screen"
text="Press enter or double-click on a player to edit him/her" text="Press enter or double-click on a player to edit their settings"
text_align="center" /> text_align="center" />
<spacer width="5" height="20"/> <spacer width="5" height="20"/>

View File

@ -1,4 +1,5 @@
uniform sampler2D tex; uniform sampler2D tex;
uniform float scale;
out vec4 FragColor; out vec4 FragColor;
@ -7,7 +8,7 @@ out vec4 FragColor;
void main() void main()
{ {
vec2 uv = gl_FragCoord.xy / 512.; vec2 uv = gl_FragCoord.xy / (512. * scale);
vec3 col = texture(tex, uv).xyz; vec3 col = texture(tex, uv).xyz;
vec3 Yxy = getCIEYxy(col); vec3 Yxy = getCIEYxy(col);
vec3 WhiteYxy = getCIEYxy(vec3(1.)); vec3 WhiteYxy = getCIEYxy(vec3(1.));

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2014 Richard Hughes <richard@hughsie.com> --> <!-- Copyright 2014 Richard Hughes <richard@hughsie.com> -->
<component type="desktop">
<application> <id>supertuxkart.desktop</id>
<id type="desktop">supertuxkart.desktop</id>
<metadata_license>CC0-1.0</metadata_license> <metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>SuperTuxKart</name> <name>SuperTuxKart</name>
<summary>A racing game</summary> <summary>A racing game</summary>
<description> <description>
@ -25,11 +25,25 @@
against the computer or your friends, and more! against the computer or your friends, and more!
</p> </p>
</description> </description>
<url type="homepage">http://supertuxkart.net/</url>
<screenshots> <screenshots>
<screenshot type="default">http://supertuxkart.sourceforge.net/persistent/images/4/4e/Supertuxkart-0.9-screenshot-2.jpg</screenshot> <screenshot type="default">
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/a/a9/Supertuxkart-0.9-screenshot-1.jpg</screenshot> <image>https://supertuxkart.net/images/8/83/Supertuxkart-0.9.2-screenshot-3.jpg</image>
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/6/63/Supertuxkart-0.9-screenshot-3.jpg</screenshot> <caption>Normal Race</caption>
</screenshot>
<screenshot>
<image>https://supertuxkart.net/images/1/1f/Supertuxkart-0.9.2-screenshot-1.jpg</image>
<caption>Battle Mode</caption>
</screenshot>
<screenshot>
<image>https://supertuxkart.net/images/2/2a/Supertuxkart-0.9.2-screenshot-2.jpg</image>
<caption>Soccer Mode</caption>
</screenshot>
</screenshots> </screenshots>
<updatecontact>supertuxkart-devel@lists.sourceforge.net</updatecontact> <developer_name>SuperTuxKart Team</developer_name>
</application> <update_contact>supertuxkart-devel@lists.sourceforge.net</update_contact>
<url type="homepage">https://supertuxkart.net</url>
<url type="bugtracker">https://github.com/supertuxkart/stk-code/issues</url>
<url type="donation">https://supertuxkart.net/Donate</url>
<url type="help">https://supertuxkart.net/Community</url>
<url type="translate">https://supertuxkart.net/Translating_STK</url>
</component>

View File

@ -47,7 +47,7 @@ if(USE_GLES2)
endif() endif()
# Xrandr # Xrandr
if(UNIX AND USE_XRANDR) if(UNIX AND NOT APPLE)
add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_) add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_)
add_definitions(-D_IRR_LINUX_X11_RANDR_) add_definitions(-D_IRR_LINUX_X11_RANDR_)
endif() endif()

View File

@ -381,7 +381,7 @@ void CGUIButton::setImage(video::ITexture* image)
Image = image; Image = image;
if (image) if (image)
ImageRect = core::rect<s32>(core::position2d<s32>(0,0), image->getOriginalSize()); ImageRect = core::rect<s32>(core::position2d<s32>(0,0), image->getSize());
if (!PressedImage) if (!PressedImage)
setPressedImage(Image); setPressedImage(Image);
@ -407,7 +407,7 @@ void CGUIButton::setPressedImage(video::ITexture* image)
PressedImage = image; PressedImage = image;
if (image) if (image)
PressedImageRect = core::rect<s32>(core::position2d<s32>(0,0), image->getOriginalSize()); PressedImageRect = core::rect<s32>(core::position2d<s32>(0,0), image->getSize());
} }

View File

@ -1314,7 +1314,7 @@ namespace video
// texcoords need to be flipped horizontally for RTTs // texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget(); const bool isRTT = texture->isRenderTarget();
const core::dimension2d<u32>& ss = texture->getOriginalSize(); const core::dimension2d<u32>& ss = texture->getSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
@ -1443,10 +1443,10 @@ namespace video
// now draw it. // now draw it.
core::rect<f32> tcoords; core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ; tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getSize().Width ;
tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height; tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getSize().Height;
tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width); tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getSize().Width);
tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height); tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getSize().Height);
const core::rect<s32> poss(targetPos, sourceSize); const core::rect<s32> poss(targetPos, sourceSize);
@ -1496,7 +1496,7 @@ namespace video
// texcoords need to be flipped horizontally for RTTs // texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget(); const bool isRTT = texture->isRenderTarget();
const core::dimension2du& ss = texture->getOriginalSize(); const core::dimension2du& ss = texture->getSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
@ -1573,7 +1573,7 @@ namespace video
clipRect->getWidth(), clipRect->getHeight()); clipRect->getWidth(), clipRect->getHeight());
} }
const core::dimension2du& ss = texture->getOriginalSize(); const core::dimension2du& ss = texture->getSize();
core::position2d<s32> targetPos(pos); core::position2d<s32> targetPos(pos);
// texcoords need to be flipped horizontally for RTTs // texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget(); const bool isRTT = texture->isRenderTarget();

View File

@ -15,6 +15,8 @@
#include "os.h" #include "os.h"
#include "CImage.h" #include "CImage.h"
#include "CColorConverter.h" #include "CColorConverter.h"
#include "IAttributes.h"
#include "IrrlichtDevice.h"
#include "irrString.h" #include "irrString.h"
@ -171,6 +173,17 @@ void COGLES2Texture::getImageValues(IImage* image)
ImageSize.Width = (u32)(Driver->MaxTextureSize*ratio); ImageSize.Width = (u32)(Driver->MaxTextureSize*ratio);
} }
TextureSize=ImageSize.getOptimalSize(false); TextureSize=ImageSize.getOptimalSize(false);
const core::dimension2du max_size = Driver->getDriverAttributes()
.getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
if (max_size.Width> 0 && TextureSize.Width > max_size.Width)
{
TextureSize.Width = max_size.Width;
}
if (max_size.Height> 0 && TextureSize.Height > max_size.Height)
{
TextureSize.Height = max_size.Height;
}
ColorFormat = getBestColorFormat(image->getColorFormat()); ColorFormat = getBestColorFormat(image->getColorFormat());
} }

View File

@ -2006,7 +2006,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size()); const u32 drawCount = core::min_<u32>(positions.size(), sourceRects.size());
const core::dimension2d<u32>& ss = texture->getOriginalSize(); const core::dimension2d<u32>& ss = texture->getSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize(); const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
@ -2225,7 +2225,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
// ok, we've clipped everything. // ok, we've clipped everything.
// now draw it. // now draw it.
const core::dimension2d<u32>& ss = texture->getOriginalSize(); const core::dimension2d<u32>& ss = texture->getSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
@ -2268,7 +2268,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
if (!texture) if (!texture)
return; return;
const core::dimension2d<u32>& ss = texture->getOriginalSize(); const core::dimension2d<u32>& ss = texture->getSize();
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords( const core::rect<f32> tcoords(
@ -2361,7 +2361,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
clipRect->getWidth(),clipRect->getHeight()); clipRect->getWidth(),clipRect->getHeight());
} }
const core::dimension2d<u32>& ss = texture->getOriginalSize(); const core::dimension2d<u32>& ss = texture->getSize();
core::position2d<s32> targetPos(pos); core::position2d<s32> targetPos(pos);
const f32 invW = 1.f / static_cast<f32>(ss.Width); const f32 invW = 1.f / static_cast<f32>(ss.Width);
const f32 invH = 1.f / static_cast<f32>(ss.Height); const f32 invH = 1.f / static_cast<f32>(ss.Height);

View File

@ -251,22 +251,29 @@ ChallengeData::ChallengeData(const std::string& filename)
throw std::runtime_error("Unknown unlock entry"); throw std::runtime_error("Unknown unlock entry");
} }
} }
} // ChallengeData
// ----------------------------------------------------------------------------
const irr::core::stringw ChallengeData::getChallengeDescription() const
{
core::stringw description; core::stringw description;
if (track_node != NULL && m_minor!=RaceManager::MINOR_MODE_FOLLOW_LEADER) if (!m_track_id.empty())
{
if (m_minor != RaceManager::MINOR_MODE_FOLLOW_LEADER)
{ {
//I18N: number of laps to race in a challenge //I18N: number of laps to race in a challenge
description += _("Laps : %i", m_num_laps); description += _("Laps: %i", m_num_laps);
description += core::stringw(L"\n"); description += core::stringw(L"\n");
} }
else if (track_node) else
{ {
// Follow the leader mode: // Follow the leader mode:
description = _("Follow the leader"); description = _("Follow the leader");
} }
}
m_challenge_description = description; return description;
} // ChallengeData } // getChallengeDescription
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void ChallengeData::error(const char *id) const void ChallengeData::error(const char *id) const

View File

@ -110,8 +110,6 @@ private:
/** Number of trophies required to access this challenge */ /** Number of trophies required to access this challenge */
int m_num_trophies; int m_num_trophies;
irr::core::stringw m_challenge_description;
public: public:
ChallengeData(const std::string& filename); ChallengeData(const std::string& filename);
@ -195,10 +193,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the description of this challenge. /** Returns the description of this challenge.
*/ */
const irr::core::stringw& getChallengeDescription() const const irr::core::stringw getChallengeDescription() const;
{
return m_challenge_description;
} // getChallengeDescription
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the minimum position the player must have in order to win. /** Returns the minimum position the player must have in order to win.

View File

@ -1,7 +1,7 @@
// //
// SuperTuxKart - a fun racing game with go-kart // SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2006-2015 SuperTuxKart-Team // Copyright (C) 2006-2016 SuperTuxKart-Team
// Modelled after Supertux's configfile.cpp // Modeled after Supertux's configfile.cpp
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License // modify it under the terms of the GNU General Public License
@ -683,8 +683,8 @@ bool UserConfig::loadConfig()
XMLNode* root = file_manager->createXMLTree(filename); XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "stkconfig") if(!root || root->getName() != "stkconfig")
{ {
Log::error("UserConfig", Log::info("UserConfig",
"Could not read user config file '%s'.", filename.c_str()); "Could not read user config file '%s'. A new file will be created.", filename.c_str());
if(root) delete root; if(root) delete root;
// Create a default config file - just in case that stk crashes later // Create a default config file - just in case that stk crashes later
// there is a config file that can be modified (to e.g. disable // there is a config file that can be modified (to e.g. disable

View File

@ -491,6 +491,14 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_old_driver_popup PARAM_PREFIX BoolUserConfigParam m_old_driver_popup
PARAM_DEFAULT(BoolUserConfigParam(true, "old_driver_popup", PARAM_DEFAULT(BoolUserConfigParam(true, "old_driver_popup",
&m_video_group, "Determines if popup message about too old drivers should be displayed.")); &m_video_group, "Determines if popup message about too old drivers should be displayed."));
PARAM_PREFIX FloatUserConfigParam m_scale_rtts_factor
PARAM_DEFAULT(FloatUserConfigParam(1.0f, "scale_rtts_factor",
&m_video_group, "Allows to increase performance by setting lower RTTs "
"resolution. Value should be smaller or equal to 1.0"));
PARAM_PREFIX IntUserConfigParam m_max_texture_size
PARAM_DEFAULT(IntUserConfigParam(512, "max_texture_size",
&m_video_group, "Max texture size when high definition textures are "
"disabled"));
// ---- Debug - not saved to config file // ---- Debug - not saved to config file
/** If gamepad debugging is enabled. */ /** If gamepad debugging is enabled. */

View File

@ -37,6 +37,7 @@ void BoldFace::init()
setFallbackFontScale(2.0f);*/ setFallbackFontScale(2.0f);*/
} // init } // init
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void BoldFace::reset() void BoldFace::reset()
{ {

View File

@ -33,6 +33,7 @@ void DigitFace::init()
m_font_max_height = m_glyph_max_height + 10; m_font_max_height = m_glyph_max_height + 10;
} // init } // init
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void DigitFace::reset() void DigitFace::reset()
{ {

View File

@ -23,6 +23,8 @@
#include "font/digit_face.hpp" #include "font/digit_face.hpp"
#include "font/face_ttf.hpp" #include "font/face_ttf.hpp"
#include "font/regular_face.hpp" #include "font/regular_face.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
FontManager *font_manager = NULL; FontManager *font_manager = NULL;
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -77,3 +79,56 @@ void FontManager::checkFTError(FT_Error err, const std::string& desc) const
Log::error("FontManager", "Something wrong when %s!", desc.c_str()); Log::error("FontManager", "Something wrong when %s!", desc.c_str());
} }
} // checkFTError } // checkFTError
// ----------------------------------------------------------------------------
void FontManager::unitTesting()
{
std::vector<std::string> list = *(translations->getLanguageList());
const int cur_log_level = Log::getLogLevel();
for (const std::string& lang : list)
{
// Hide gettext warning
Log::setLogLevel(5);
delete translations;
#ifdef WIN32
std::string s=std::string("LANGUAGE=") + lang.c_str();
_putenv(s.c_str());
#else
setenv("LANGUAGE", lang.c_str(), 1);
#endif
translations = new Translations();
Log::setLogLevel(cur_log_level);
std::set<wchar_t> used_chars = translations->getCurrentAllChar();
for (const wchar_t& c : used_chars)
{
// Skip non-printing characters
if (c < 32) continue;
unsigned int font_number = 0;
unsigned int glyph_index = 0;
while (font_number < m_normal_ttf->getTotalFaces())
{
glyph_index =
FT_Get_Char_Index(m_normal_ttf->getFace(font_number), c);
if (glyph_index > 0) break;
font_number++;
}
if (glyph_index > 0)
{
Log::debug("UnitTest", "Character %s in language %s"
" use face %s",
StringUtils::wideToUtf8(core::stringw(&c, 1)).c_str(),
lang.c_str(),
m_normal_ttf->getFace(font_number)->family_name);
}
else
{
Log::warn("UnitTest", "Character %s in language %s"
" is not supported by all fonts!",
StringUtils::wideToUtf8(core::stringw(&c, 1)).c_str(),
lang.c_str());
}
}
}
} // unitTesting

View File

@ -76,6 +76,8 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void loadFonts(); void loadFonts();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void unitTesting();
// ------------------------------------------------------------------------
FT_Library getFTLibrary() const { return m_ft_library; } FT_Library getFTLibrary() const { return m_ft_library; }
}; // FontManager }; // FontManager

View File

@ -116,6 +116,13 @@ void FontWithFace::createNewGlyphPage()
m_used_width = 0; m_used_width = 0;
m_used_height = 0; m_used_height = 0;
// Font textures can not be resized (besides the impact on quality in
// this case, the rectangles in spritebank would become wrong).
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver() video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page); ->addTexture("Glyph_page", m_page);
m_spritebank->addTexture(NULL); m_spritebank->addTexture(NULL);
@ -127,6 +134,9 @@ void FontWithFace::createNewGlyphPage()
irr_driver->getVideoDriver()->removeTexture(page_texture); irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1); assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // createNewGlyphPage } // createNewGlyphPage
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -172,13 +182,22 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
{ {
// Current glyph page is full: // Current glyph page is full:
// Save the old glyph page // Save the old glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d
("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver() video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page); ->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1, m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture); page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture); irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1); assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
// Clear and add a new one // Clear and add a new one
createNewGlyphPage(); createNewGlyphPage();
} }
@ -283,6 +302,11 @@ void FontWithFace::updateCharactersList()
m_new_char_holder.clear(); m_new_char_holder.clear();
// Update last glyph page // Update last glyph page
core::dimension2du old_max_size = irr_driver->getVideoDriver()
->getDriverAttributes().getAttributeAsDimension2d("MAX_TEXTURE_SIZE");
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(0, 0));
video::ITexture* page_texture = irr_driver->getVideoDriver() video::ITexture* page_texture = irr_driver->getVideoDriver()
->addTexture("Glyph_page", m_page); ->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1, m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
@ -291,6 +315,9 @@ void FontWithFace::updateCharactersList()
irr_driver->getVideoDriver()->removeTexture(page_texture); irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1); assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // updateCharactersList } // updateCharactersList
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -109,14 +109,12 @@ private:
FontWithFace* m_fallback_font; FontWithFace* m_fallback_font;
float m_fallback_font_scale; float m_fallback_font_scale;
/** A temporary holder stored new char to be inserted. /** A temporary holder stored new char to be inserted. */
*/
std::set<wchar_t> m_new_char_holder; std::set<wchar_t> m_new_char_holder;
gui::IGUISpriteBank* m_spritebank; gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font. /** A full glyph page for this font. */
*/
video::IImage* m_page; video::IImage* m_page;
unsigned int m_temp_height; unsigned int m_temp_height;

View File

@ -33,6 +33,7 @@ void RegularFace::init()
m_font_max_height = m_glyph_max_height + 10; m_font_max_height = m_glyph_max_height + 10;
} // init } // init
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void RegularFace::reset() void RegularFace::reset()
{ {

View File

@ -73,7 +73,8 @@ Camera* Camera::createCamera(unsigned int index, CameraType type,
Camera *camera = NULL; Camera *camera = NULL;
switch (type) switch (type)
{ {
case CM_TYPE_NORMAL: camera = new CameraNormal(index, kart); break; case CM_TYPE_NORMAL: camera = new CameraNormal(CM_TYPE_NORMAL, index, kart);
break;
case CM_TYPE_DEBUG: camera = new CameraDebug (index, kart); break; case CM_TYPE_DEBUG: camera = new CameraDebug (index, kart); break;
case CM_TYPE_FPS: camera = new CameraFPS (index, kart); break; case CM_TYPE_FPS: camera = new CameraFPS (index, kart); break;
case CM_TYPE_END: camera = new CameraEnd (index, kart); break; case CM_TYPE_END: camera = new CameraEnd (index, kart); break;
@ -112,10 +113,11 @@ void Camera::resetAllCameras()
} // resetAllCameras } // resetAllCameras
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
Camera::Camera(int camera_index, AbstractKart* kart) : m_kart(NULL) Camera::Camera(CameraType type, int camera_index, AbstractKart* kart)
: m_kart(NULL)
{ {
m_mode = CM_NORMAL; m_mode = CM_NORMAL;
m_type = CameraType::CM_TYPE_NORMAL; m_type = type;
m_index = camera_index; m_index = camera_index;
m_original_kart = kart; m_original_kart = kart;
m_camera = irr_driver->addCameraSceneNode(); m_camera = irr_driver->addCameraSceneNode();

View File

@ -128,7 +128,7 @@ protected:
static Camera* createCamera(unsigned int index, CameraType type, static Camera* createCamera(unsigned int index, CameraType type,
AbstractKart* kart); AbstractKart* kart);
Camera(int camera_index, AbstractKart* kart); Camera(CameraType type, int camera_index, AbstractKart* kart);
virtual ~Camera(); virtual ~Camera();
virtual void reset(); virtual void reset();
public: public:

View File

@ -32,7 +32,7 @@ CameraDebug::CameraDebugType CameraDebug::m_default_debug_Type =
// ============================================================================ // ============================================================================
CameraDebug::CameraDebug(int camera_index, AbstractKart* kart) CameraDebug::CameraDebug(int camera_index, AbstractKart* kart)
: CameraNormal(camera_index, kart) : CameraNormal(Camera::CM_TYPE_DEBUG, camera_index, kart)
{ {
reset(); reset();
} // Camera } // Camera

View File

@ -27,7 +27,7 @@
AlignedArray<CameraEnd::EndCameraInformation> CameraEnd::m_end_cameras; AlignedArray<CameraEnd::EndCameraInformation> CameraEnd::m_end_cameras;
// ============================================================================ // ============================================================================
CameraEnd::CameraEnd(int camera_index, AbstractKart* kart) CameraEnd::CameraEnd(int camera_index, AbstractKart* kart)
: CameraNormal(camera_index, kart) : CameraNormal(Camera::CM_TYPE_END, camera_index, kart)
{ {
reset(); reset();
if(m_end_cameras.size()>0) if(m_end_cameras.size()>0)

View File

@ -30,7 +30,7 @@ using namespace irr;
// ============================================================================ // ============================================================================
CameraFPS::CameraFPS(int camera_index, AbstractKart* kart) CameraFPS::CameraFPS(int camera_index, AbstractKart* kart)
: Camera(camera_index, kart) : Camera(Camera::CM_TYPE_FPS, camera_index, kart)
{ {
m_attached = false; m_attached = false;

View File

@ -28,8 +28,17 @@
#include "tracks/track.hpp" #include "tracks/track.hpp"
// ============================================================================ // ============================================================================
CameraNormal::CameraNormal(int camera_index, AbstractKart* kart) /** Constructor for the normal camera. This is the only camera constructor
: Camera(camera_index, kart) * except for the base class that takes a camera type as parameter. This is
* because debug and end camera use the normal camera as their base class.
* \param type The type of the camera that is created (can be CM_TYPE_END
* or CM_TYPE_DEBUG).
* \param camera_index Index of this camera.
* \param Kart Pointer to the kart for which this camera is used.
*/
CameraNormal::CameraNormal(Camera::CameraType type, int camera_index,
AbstractKart* kart)
: Camera(type, camera_index, kart)
{ {
m_distance = kart ? kart->getKartProperties()->getCameraDistance() : 1000.0f; m_distance = kart ? kart->getKartProperties()->getCameraDistance() : 1000.0f;
m_ambient_light = World::getWorld()->getTrack()->getDefaultAmbientColor(); m_ambient_light = World::getWorld()->getTrack()->getDefaultAmbientColor();

View File

@ -61,7 +61,8 @@ private:
friend class Camera; friend class Camera;
friend class CameraDebug; friend class CameraDebug;
friend class CameraEnd; friend class CameraEnd;
CameraNormal(int camera_index, AbstractKart* kart); CameraNormal(Camera::CameraType type, int camera_index,
AbstractKart* kart);
virtual ~CameraNormal() {} virtual ~CameraNormal() {}
public: public:
bool isDebug() { return false; } bool isDebug() { return false; }

View File

@ -196,7 +196,6 @@ std::unique_ptr<RenderTarget> IrrDriver::createRenderTarget(const irr::core::dim
return m_renderer->createRenderTarget(dimension, name); return m_renderer->createRenderTarget(dimension, name);
} }
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID) #if defined(__linux__) && !defined(ANDROID)
@ -646,7 +645,9 @@ void IrrDriver::setMaxTextureSize()
if( (UserConfigParams::m_high_definition_textures & 0x01) == 0) if( (UserConfigParams::m_high_definition_textures & 0x01) == 0)
{ {
io::IAttributes &att = m_video_driver->getNonConstDriverAttributes(); io::IAttributes &att = m_video_driver->getNonConstDriverAttributes();
att.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(512, 512)); att.setAttribute("MAX_TEXTURE_SIZE", core::dimension2du(
UserConfigParams::m_max_texture_size,
UserConfigParams::m_max_texture_size));
} }
} // setMaxTextureSize } // setMaxTextureSize

View File

@ -143,6 +143,7 @@ Material::Material(const XMLNode *node, bool deprecated)
node->get("disable-z-write", &m_disable_z_write ); node->get("disable-z-write", &m_disable_z_write );
node->get("colorizable", &m_colorizable ); node->get("colorizable", &m_colorizable );
node->get("colorization-factor", &m_colorization_factor); node->get("colorization-factor", &m_colorization_factor);
node->get("hue-settings", &m_hue_settings );
node->get("fog", &m_fog ); node->get("fog", &m_fog );
node->get("mask", &m_mask ); node->get("mask", &m_mask );

View File

@ -21,6 +21,7 @@
#define HEADER_MATERIAL_HPP #define HEADER_MATERIAL_HPP
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
#include <assert.h> #include <assert.h>
#include <map> #include <map>
@ -181,6 +182,12 @@ private:
/** Minimum resulting saturation when colorized (from 0 to 1) */ /** Minimum resulting saturation when colorized (from 0 to 1) */
float m_colorization_factor; float m_colorization_factor;
/** List of hue pre-defined for colorization (from 0 to 1) */
std::vector<float> m_hue_settings;
/** Random generator for getting pre-defined hue */
RandomGenerator m_random_hue;
/** Some textures need to be pre-multiplied, some divided to give /** Some textures need to be pre-multiplied, some divided to give
* the intended effect. */ * the intended effect. */
//enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV} //enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV}
@ -291,7 +298,7 @@ public:
* is driving on it. */ * is driving on it. */
bool isDriveReset () const { return m_drive_reset; } bool isDriveReset () const { return m_drive_reset; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns if this material can be colorized (like red/blue in team game). /** Returns if this material can be colorized.
*/ */
bool isColorizable () const { return m_colorizable; } bool isColorizable () const { return m_colorizable; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -299,6 +306,17 @@ public:
*/ */
float getColorizationFactor () const { return m_colorization_factor; } float getColorizationFactor () const { return m_colorization_factor; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a random hue when colorized.
*/
float getRandomHue()
{
if (m_hue_settings.empty())
return 0.0f;
const unsigned int hue = m_random_hue.get(m_hue_settings.size());
assert(hue < m_hue_settings.size());
return m_hue_settings[hue];
}
// ------------------------------------------------------------------------
/** Returns if this material should trigger a rescue if a kart /** Returns if this material should trigger a rescue if a kart
* crashes against it. */ * crashes against it. */
CollisionReaction getCollisionReaction() const { return m_collision_reaction; } CollisionReaction getCollisionReaction() const { return m_collision_reaction; }

View File

@ -333,21 +333,21 @@ public:
}; // ComputeGaussian17TapVShader }; // ComputeGaussian17TapVShader
// ============================================================================ // ============================================================================
class BloomShader : public TextureShader<BloomShader, 1> class BloomShader : public TextureShader<BloomShader, 1, float>
{ {
public: public:
BloomShader() BloomShader()
{ {
loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert", loadProgram(OBJECT, GL_VERTEX_SHADER, "screenquad.vert",
GL_FRAGMENT_SHADER, "bloom.frag"); GL_FRAGMENT_SHADER, "bloom.frag");
assignUniforms(); assignUniforms("scale");
assignSamplerNames(0, "tex", ST_NEAREST_FILTERED); assignSamplerNames(0, "tex", ST_NEAREST_FILTERED);
} // BloomShader } // BloomShader
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void render(GLuint in) void render(GLuint in)
{ {
BloomShader::getInstance()->setTextureUnits(in); BloomShader::getInstance()->setTextureUnits(in);
drawFullScreenEffect(); drawFullScreenEffect(UserConfigParams::m_scale_rtts_factor);
} // render } // render
}; // BloomShader }; // BloomShader

View File

@ -26,6 +26,19 @@
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
RenderInfo::RenderInfo(float hue, bool transparent) RenderInfo::RenderInfo(float hue, bool transparent)
{ {
m_hue = hue; m_static_hue = hue;
m_transparent = transparent; m_transparent = transparent;
} // RenderInfo } // RenderInfo
// ----------------------------------------------------------------------------
void RenderInfo::setDynamicHue(irr::scene::IMesh* mesh)
{
unsigned int n = mesh->getMeshBufferCount();
for (unsigned int i = 0; i < n; i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
m_dynamic_hue.push_back(m->getRandomHue());
}
} // setDynamicHue

View File

@ -20,31 +20,36 @@
#define HEADER_RENDER_INFO_HPP #define HEADER_RENDER_INFO_HPP
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <assert.h>
#include <vector>
namespace irr namespace irr
{ {
namespace scene { class IMesh; } namespace scene { class IMesh; }
} }
/** enum KartRenderType: unsigned int
* \ingroup graphics
*/
class RenderInfo
{ {
public:
enum KartRenderType
{
KRT_DEFAULT, KRT_DEFAULT,
KRT_RED, KRT_RED,
KRT_BLUE, KRT_BLUE,
KRT_TRANSPARENT, KRT_TRANSPARENT,
}; };
/**
* \ingroup graphics
*/
class RenderInfo : public NoCopy
{
private: private:
float m_hue; float m_static_hue;
bool m_transparent; bool m_transparent;
std::vector<float> m_dynamic_hue;
public: public:
LEAK_CHECK(); LEAK_CHECK();
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -52,23 +57,34 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
~RenderInfo() {} ~RenderInfo() {}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setHue(float hue) { m_hue = hue; } void setHue(float hue) { m_static_hue = hue; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setTransparent(bool transparent) { m_transparent = transparent; } void setTransparent(bool transparent) { m_transparent = transparent; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
float getHue() const { return m_hue; } float getHue() const { return m_static_hue; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isTransparent() const { return m_transparent; } bool isTransparent() const { return m_transparent; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setKartModelRenderInfo(KartRenderType krt) void setKartModelRenderInfo(KartRenderType krt)
{ {
setHue(krt == RenderInfo::KRT_BLUE ? 0.66f : setHue(krt == KRT_BLUE ? 0.66f : krt == KRT_RED ? 1.0f : 0.0f);
krt == RenderInfo::KRT_RED ? 1.0f : 0.0f); setTransparent(krt == KRT_TRANSPARENT ? true : false);
setTransparent(krt == RenderInfo::KRT_TRANSPARENT ? true : false);
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void setRenderInfo(const RenderInfo* other) { *this = *other; } /** Returns true if this render info is static. ie affect all material
* using the same hue. (like the kart colorization in soccer game)
*/
bool isStatic() const { return m_dynamic_hue.empty(); }
// ------------------------------------------------------------------------
unsigned int getNumberOfHue() const { return m_dynamic_hue.size(); }
// ------------------------------------------------------------------------
float getDynamicHue(unsigned int hue) const
{
assert(hue < m_dynamic_hue.size());
return m_dynamic_hue[hue];
}
// ------------------------------------------------------------------------
void setDynamicHue(irr::scene::IMesh* mesh);
}; // RenderInfo }; // RenderInfo

View File

@ -59,12 +59,14 @@ RTT::RTT(size_t width, size_t height)
using namespace video; using namespace video;
using namespace core; using namespace core;
const dimension2du res(width, height); dimension2du res(width * UserConfigParams::m_scale_rtts_factor,
height * UserConfigParams::m_scale_rtts_factor);
const dimension2du half = res/2; const dimension2du half = res/2;
const dimension2du quarter = res/4; const dimension2du quarter = res/4;
const dimension2du eighth = res/8; const dimension2du eighth = res/8;
const u16 shadowside = 1024; const u16 shadowside = 1024 * UserConfigParams::m_scale_rtts_factor;
const dimension2du shadowsize0(shadowside, shadowside); const dimension2du shadowsize0(shadowside, shadowside);
const dimension2du shadowsize1(shadowside / 2, shadowside / 2); const dimension2du shadowsize1(shadowside / 2, shadowside / 2);
const dimension2du shadowsize2(shadowside / 4, shadowside / 4); const dimension2du shadowsize2(shadowside / 4, shadowside / 4);
@ -118,7 +120,6 @@ RTT::RTT(size_t width, size_t height)
std::vector<GLuint> somevector; std::vector<GLuint> somevector;
somevector.push_back(RenderTargetTextures[RTT_SSAO]); somevector.push_back(RenderTargetTextures[RTT_SSAO]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_NORMAL_AND_DEPTH]); somevector.push_back(RenderTargetTextures[RTT_NORMAL_AND_DEPTH]);
@ -158,12 +159,12 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_LINEAR_DEPTH]); somevector.push_back(RenderTargetTextures[RTT_LINEAR_DEPTH]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF1]); somevector.push_back(RenderTargetTextures[RTT_HALF1]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF1_R]); somevector.push_back(RenderTargetTextures[RTT_HALF1_R]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF2]); somevector.push_back(RenderTargetTextures[RTT_HALF2]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
@ -186,42 +187,42 @@ RTT::RTT(size_t width, size_t height)
somevector.push_back(RenderTargetTextures[RTT_DISPLACE]); somevector.push_back(RenderTargetTextures[RTT_DISPLACE]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height)); FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_BLOOM_1024]); somevector.push_back(RenderTargetTextures[RTT_BLOOM_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize0.Width, shadowsize0.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]); somevector.push_back(RenderTargetTextures[RTT_SCALAR_1024]);
FrameBuffers.push_back(new FrameBuffer(somevector, 1024, 1024)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize0.Width, shadowsize0.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]); somevector.push_back(RenderTargetTextures[RTT_BLOOM_512]);
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize1.Width, shadowsize1.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP_512]); somevector.push_back(RenderTargetTextures[RTT_TMP_512]);
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize1.Width, shadowsize1.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_LENS_512]); somevector.push_back(RenderTargetTextures[RTT_LENS_512]);
FrameBuffers.push_back(new FrameBuffer(somevector, 512, 512)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize1.Width, shadowsize1.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_BLOOM_256]); somevector.push_back(RenderTargetTextures[RTT_BLOOM_256]);
FrameBuffers.push_back(new FrameBuffer(somevector, 256, 256)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize2.Width, shadowsize2.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP_256]); somevector.push_back(RenderTargetTextures[RTT_TMP_256]);
FrameBuffers.push_back(new FrameBuffer(somevector, 256, 256)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize2.Width, shadowsize2.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_LENS_256]); somevector.push_back(RenderTargetTextures[RTT_LENS_256]);
FrameBuffers.push_back(new FrameBuffer(somevector, 256, 256)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize2.Width, shadowsize2.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_BLOOM_128]); somevector.push_back(RenderTargetTextures[RTT_BLOOM_128]);
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize3.Width, shadowsize3.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_TMP_128]); somevector.push_back(RenderTargetTextures[RTT_TMP_128]);
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize3.Width, shadowsize3.Height));
somevector.clear(); somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_LENS_128]); somevector.push_back(RenderTargetTextures[RTT_LENS_128]);
FrameBuffers.push_back(new FrameBuffer(somevector, 128, 128)); FrameBuffers.push_back(new FrameBuffer(somevector, shadowsize3.Width, shadowsize3.Height));
if (CVS->isShadowEnabled()) if (CVS->isShadowEnabled())
{ {

View File

@ -231,8 +231,11 @@ void ShaderBasedRenderer::uploadLightingData() const
void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode, void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
size_t width, size_t height) size_t width, size_t height)
{ {
m_current_screen_size = core::vector2df(float(width), float(height));
m_shadow_matrices.computeMatrixesAndCameras(camnode, width, height, m_rtts->getDepthStencilTexture()); float w = width * UserConfigParams::m_scale_rtts_factor;
float h = height * UserConfigParams::m_scale_rtts_factor;
m_current_screen_size = core::vector2df(w, h);
m_shadow_matrices.computeMatrixesAndCameras(camnode, w, h, m_rtts->getDepthStencilTexture());
} // computeMatrixesAndCameras } // computeMatrixesAndCameras
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -628,6 +631,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
glEnable(GL_FRAMEBUFFER_SRGB); glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0); glBindFramebuffer(GL_FRAMEBUFFER, 0);
camera->activate(); camera->activate();
glViewport(viewport.UpperLeftCorner.X, viewport.UpperLeftCorner.Y, viewport.LowerRightCorner.X, viewport.LowerRightCorner.Y);
m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y); m_post_processing->renderPassThrough(fbo->getRTT()[0], viewport.LowerRightCorner.X - viewport.UpperLeftCorner.X, viewport.LowerRightCorner.Y - viewport.UpperLeftCorner.Y);
glDisable(GL_FRAMEBUFFER_SRGB); glDisable(GL_FRAMEBUFFER_SRGB);
} }

View File

@ -100,22 +100,44 @@ void STKAnimatedMesh::updateNoGL()
if (!isMaterialInitialized) if (!isMaterialInitialized)
{ {
video::IVideoDriver* driver = SceneManager->getVideoDriver(); video::IVideoDriver* driver = SceneManager->getVideoDriver();
for (u32 i = 0; i < m->getMeshBufferCount(); ++i) const u32 mb_count = m->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
bool affected = false; bool affected = false;
if (!m_all_parts_colorized && mb && m_mesh_render_info) RenderInfo* cur_ri = m_mesh_render_info;
if (!m_all_parts_colorized && mb && cur_ri)
{ {
// Test if material is affected by hue change if (m_mesh_render_info && !m_mesh_render_info->isStatic())
{
// Convert to static render info for each mesh buffer
assert(m_mesh_render_info->getNumberOfHue() == mb_count);
const float hue = m_mesh_render_info->getDynamicHue(i);
if (hue > 0.0f)
{
cur_ri = new RenderInfo(hue);
m_static_render_info.push_back(cur_ri);
affected = true;
}
else
{
cur_ri = NULL;
}
}
else
{
// Test if material is affected by static hue change
Material* m = material_manager->getMaterialFor(mb Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb); ->getMaterial().getTexture(0), mb);
if (m->isColorizable()) if (m->isColorizable())
affected = true; affected = true;
} }
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name, GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || m_all_parts_colorized || (m_mesh_render_info affected || m_all_parts_colorized || (cur_ri
&& m_mesh_render_info->isTransparent()) ? m_mesh_render_info : NULL)); && cur_ri->isTransparent()) ? cur_ri : NULL));
} }
for (u32 i = 0; i < m->getMeshBufferCount(); ++i) for (u32 i = 0; i < m->getMeshBufferCount(); ++i)

View File

@ -32,6 +32,7 @@ class STKAnimatedMesh : public irr::scene::CAnimatedMeshSceneNode, public STKMes
protected: protected:
bool isMaterialInitialized; bool isMaterialInitialized;
bool isGLInitialized; bool isGLInitialized;
PtrVector<RenderInfo> m_static_render_info;
std::vector<GLMesh> GLmeshes; std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix; core::matrix4 ModelViewProjectionMatrix;
void cleanGLMeshes(); void cleanGLMeshes();

View File

@ -77,22 +77,44 @@ void STKMeshSceneNode::setReloadEachFrame(bool val)
void STKMeshSceneNode::createGLMeshes(RenderInfo* render_info, bool all_parts_colorized) void STKMeshSceneNode::createGLMeshes(RenderInfo* render_info, bool all_parts_colorized)
{ {
for (u32 i = 0; i<Mesh->getMeshBufferCount(); ++i) const u32 mb_count = Mesh->getMeshBufferCount();
for (u32 i = 0; i < mb_count; ++i)
{ {
scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i); scene::IMeshBuffer* mb = Mesh->getMeshBuffer(i);
bool affected = false; bool affected = false;
RenderInfo* cur_ri = render_info;
if (!all_parts_colorized && mb && render_info) if (!all_parts_colorized && mb && render_info)
{ {
// Test if material is affected by hue change if (render_info && !render_info->isStatic())
{
// Convert to static render info for each mesh buffer
assert(render_info->getNumberOfHue() == mb_count);
const float hue = render_info->getDynamicHue(i);
if (hue > 0.0f)
{
cur_ri = new RenderInfo(hue);
m_static_render_info.push_back(cur_ri);
affected = true;
}
else
{
cur_ri = NULL;
}
}
else
{
// Test if material is affected by static hue change
Material* m = material_manager->getMaterialFor(mb Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb); ->getMaterial().getTexture(0), mb);
if (m->isColorizable()) if (m->isColorizable())
affected = true; affected = true;
} }
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name, GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || all_parts_colorized || (render_info && affected || all_parts_colorized || (cur_ri &&
render_info->isTransparent()) ? render_info : NULL)); cur_ri->isTransparent()) ? cur_ri : NULL));
} }
isMaterialInitialized = false; isMaterialInitialized = false;
isGLInitialized = false; isGLInitialized = false;

View File

@ -28,6 +28,7 @@ class RenderInfo;
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{ {
protected: protected:
PtrVector<RenderInfo> m_static_render_info;
std::vector<GLMesh> GLmeshes; std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix; core::matrix4 ModelViewProjectionMatrix;
core::vector3df windDir; core::vector3df windDir;

View File

@ -532,7 +532,8 @@ void EventHandler::sendEventToUser(GUIEngine::Widget* widget, std::string& name,
EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID) EventPropagation EventHandler::onWidgetActivated(GUIEngine::Widget* w, const int playerID)
{ {
if (!w->isActivated()) return EVENT_BLOCK; if (w->onActivationInput(playerID) == EVENT_BLOCK)
return EVENT_BLOCK;
Widget* parent = w->m_event_handler; Widget* parent = w->m_event_handler;

View File

@ -332,6 +332,8 @@ namespace GUIEngine
bool isActivated() const; bool isActivated() const;
virtual EventPropagation onActivationInput(const int playerID) { return EVENT_LET; }
/** /**
* Call to resize/move the widget. Not all widgets can resize gracefully. * Call to resize/move the widget. Not all widgets can resize gracefully.
*/ */

View File

@ -17,6 +17,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/widgets/model_view_widget.hpp" #include "guiengine/widgets/model_view_widget.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
@ -45,6 +46,7 @@ IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false,
m_type = WTYPE_MODEL_VIEW; m_type = WTYPE_MODEL_VIEW;
m_render_target = NULL; m_render_target = NULL;
m_rotation_mode = ROTATE_OFF; m_rotation_mode = ROTATE_OFF;
m_render_info = new RenderInfo();
// so that the base class doesn't complain there is no icon defined // so that the base class doesn't complain there is no icon defined
m_properties[PROP_ICON]="gui/main_help.png"; m_properties[PROP_ICON]="gui/main_help.png";
@ -55,6 +57,7 @@ IconButtonWidget(IconButtonWidget::SCALE_MODE_KEEP_TEXTURE_ASPECT_RATIO, false,
ModelViewWidget::~ModelViewWidget() ModelViewWidget::~ModelViewWidget()
{ {
GUIEngine::needsUpdate.remove(this); GUIEngine::needsUpdate.remove(this);
delete m_render_info;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ModelViewWidget::add() void ModelViewWidget::add()
@ -199,7 +202,7 @@ void ModelViewWidget::setupRTTScene()
if (m_model_frames[0] == -1) if (m_model_frames[0] == -1)
{ {
scene::ISceneNode* node = irr_driver->addMesh(m_models.get(0), "rtt_mesh", scene::ISceneNode* node = irr_driver->addMesh(m_models.get(0), "rtt_mesh",
NULL, &m_render_info, m_model_render_info_affected[0]); NULL, m_render_info, m_model_render_info_affected[0]);
node->setPosition(m_model_location[0].toIrrVector()); node->setPosition(m_model_location[0].toIrrVector());
node->setScale(m_model_scale[0].toIrrVector()); node->setScale(m_model_scale[0].toIrrVector());
node->setMaterialFlag(video::EMF_FOG_ENABLE, false); node->setMaterialFlag(video::EMF_FOG_ENABLE, false);
@ -209,7 +212,7 @@ void ModelViewWidget::setupRTTScene()
{ {
scene::IAnimatedMeshSceneNode* node = scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(0), "rtt_mesh", irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(0), "rtt_mesh",
NULL, &m_render_info, m_model_render_info_affected[0]); NULL, m_render_info, m_model_render_info_affected[0]);
node->setPosition(m_model_location[0].toIrrVector()); node->setPosition(m_model_location[0].toIrrVector());
node->setFrameLoop(m_model_frames[0], m_model_frames[0]); node->setFrameLoop(m_model_frames[0], m_model_frames[0]);
node->setAnimationSpeed(0); node->setAnimationSpeed(0);
@ -231,7 +234,7 @@ void ModelViewWidget::setupRTTScene()
{ {
scene::ISceneNode* node = scene::ISceneNode* node =
irr_driver->addMesh(m_models.get(n), "rtt_node", m_rtt_main_node, irr_driver->addMesh(m_models.get(n), "rtt_node", m_rtt_main_node,
&m_render_info, m_model_render_info_affected[n]); m_render_info, m_model_render_info_affected[n]);
node->setPosition(m_model_location[n].toIrrVector()); node->setPosition(m_model_location[n].toIrrVector());
node->updateAbsolutePosition(); node->updateAbsolutePosition();
node->setScale(m_model_scale[n].toIrrVector()); node->setScale(m_model_scale[n].toIrrVector());
@ -240,7 +243,7 @@ void ModelViewWidget::setupRTTScene()
{ {
scene::IAnimatedMeshSceneNode* node = scene::IAnimatedMeshSceneNode* node =
irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(n), irr_driver->addAnimatedMesh((scene::IAnimatedMesh*)m_models.get(n),
"modelviewrtt", m_rtt_main_node, &m_render_info, "modelviewrtt", m_rtt_main_node, m_render_info,
m_model_render_info_affected[n]); m_model_render_info_affected[n]);
node->setPosition(m_model_location[n].toIrrVector()); node->setPosition(m_model_location[n].toIrrVector());
node->setFrameLoop(m_model_frames[n], m_model_frames[n]); node->setFrameLoop(m_model_frames[n], m_model_frames[n]);

View File

@ -23,12 +23,13 @@
#include <IMesh.h> #include <IMesh.h>
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/widgets/icon_button_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp"
#include "utils/aligned_array.hpp" #include "utils/aligned_array.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
class RenderInfo;
namespace GUIEngine namespace GUIEngine
{ {
/** \brief A model view widget. /** \brief A model view widget.
@ -64,7 +65,7 @@ namespace GUIEngine
scene::ISceneNode *m_light; scene::ISceneNode *m_light;
RenderInfo m_render_info; RenderInfo *m_render_info;
public: public:
@ -103,7 +104,7 @@ namespace GUIEngine
void drawRTTScene(const irr::core::rect<s32>& dest_rect) const; void drawRTTScene(const irr::core::rect<s32>& dest_rect) const;
RenderInfo& getModelViewRenderInfo() { return m_render_info; } RenderInfo* getModelViewRenderInfo() { return m_render_info; }
}; };
} }

View File

@ -666,6 +666,26 @@ void RibbonWidget::updateSelection()
if (m_listener) m_listener->onSelectionChange(); if (m_listener) m_listener->onSelectionChange();
} // updateSelection } // updateSelection
// ----------------------------------------------------------------------------
EventPropagation RibbonWidget::onActivationInput(const int playerID)
{
assert(m_magic_number == 0xCAFEC001);
if (m_deactivated)
return EVENT_BLOCK;
if (m_selection[playerID] > -1 &&
m_selection[playerID] < (int)(m_active_children.size()))
{
if (m_active_children[m_selection[playerID]].m_deactivated)
{
return EVENT_BLOCK;
}
}
return EVENT_LET;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
EventPropagation RibbonWidget::transmitEvent(Widget* w, EventPropagation RibbonWidget::transmitEvent(Widget* w,
const std::string& originator, const std::string& originator,

View File

@ -24,6 +24,7 @@
#include "guiengine/widget.hpp" #include "guiengine/widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp" #include "guiengine/widgets/icon_button_widget.hpp"
#include "utils/cpp2011.hpp"
#include "utils/leak_check.hpp" #include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
@ -192,6 +193,8 @@ namespace GUIEngine
void removeChildNamed(const char* name); void removeChildNamed(const char* name);
PtrVector<Widget>& getRibbonChildren() { return m_children; } PtrVector<Widget>& getRibbonChildren() { return m_children; }
virtual EventPropagation onActivationInput(const int playerID) OVERRIDE;
}; };
} }

View File

@ -1005,9 +1005,9 @@ EventPropagation InputManager::input(const SEvent& event)
if (cam) if (cam)
{ {
// Center of the screen // Center of the screen
core::vector2df screen_size = irr_driver->getCurrentScreenSize(); core::dimension2du screen_size = irr_driver->getActualScreenSize();
int mid_x = (int) screen_size.X / 2; int mid_x = (int) screen_size.Width / 2;
int mid_y = (int) screen_size.Y / 2; int mid_y = (int) screen_size.Height / 2;
// Relative mouse movement // Relative mouse movement
int diff_x = event.MouseInput.X - m_mouse_val_x; int diff_x = event.MouseInput.X - m_mouse_val_x;
int diff_y = event.MouseInput.Y - m_mouse_val_y; int diff_y = event.MouseInput.Y - m_mouse_val_y;

View File

@ -57,7 +57,7 @@ Bowling::Bowling(AbstractKart *kart)
createPhysics(y_offset, btVector3(0.0f, 0.0f, m_speed*2), createPhysics(y_offset, btVector3(0.0f, 0.0f, m_speed*2),
new btSphereShape(0.5f*m_extend.getY()), new btSphereShape(0.5f*m_extend.getY()),
1.0f /*restitution*/, 0.8f /*restitution*/,
-70.0f /*gravity*/, -70.0f /*gravity*/,
true /*rotates*/); true /*rotates*/);
// Even if the ball is fired backwards, m_speed must be positive, // Even if the ball is fired backwards, m_speed must be positive,

View File

@ -567,7 +567,7 @@ bool ItemManager::randomItemsForArena(const AlignedArray<btTransform>& pos)
j > NITRO_BIG ? Item::ITEM_NITRO_BIG : j > NITRO_BIG ? Item::ITEM_NITRO_BIG :
j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA); j > NITRO_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA);
Vec3 loc = BattleGraph::get() Vec3 loc = BattleGraph::get()
->getPolyOfNode(used_location[i]).getCenter(); ->getQuadOfNode(used_location[i]).getCenter();
Item* item = newItem(type, loc, Vec3(0, 1, 0)); Item* item = newItem(type, loc, Vec3(0, 1, 0));
BattleGraph::get()->insertItems(item, used_location[i]); BattleGraph::get()->insertItems(item, used_location[i]);
} }

View File

@ -19,6 +19,7 @@
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "graphics/render_info.hpp"
#include "items/powerup.hpp" #include "items/powerup.hpp"
#include "karts/abstract_kart_animation.hpp" #include "karts/abstract_kart_animation.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
@ -34,8 +35,7 @@
AbstractKart::AbstractKart(const std::string& ident, AbstractKart::AbstractKart(const std::string& ident,
int world_kart_id, int position, int world_kart_id, int position,
const btTransform& init_transform, const btTransform& init_transform,
PerPlayerDifficulty difficulty, PerPlayerDifficulty difficulty, KartRenderType krt)
RenderInfo::KartRenderType krt)
: Moveable() : Moveable()
{ {
m_world_kart_id = world_kart_id; m_world_kart_id = world_kart_id;

View File

@ -22,7 +22,6 @@
#include <memory> #include <memory>
#include "items/powerup_manager.hpp" #include "items/powerup_manager.hpp"
#include "graphics/render_info.hpp"
#include "karts/moveable.hpp" #include "karts/moveable.hpp"
#include "karts/controller/kart_control.hpp" #include "karts/controller/kart_control.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
@ -50,6 +49,8 @@ class Skidding;
class SlipStream; class SlipStream;
class TerrainInfo; class TerrainInfo;
enum KartRenderType: unsigned int;
/** An abstract interface for the actual karts. Some functions are actually /** An abstract interface for the actual karts. Some functions are actually
* implemented here in order to allow inlining. * implemented here in order to allow inlining.
* \ingroup karts * \ingroup karts
@ -100,7 +101,7 @@ public:
int world_kart_id, int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty, PerPlayerDifficulty difficulty,
RenderInfo::KartRenderType krt); KartRenderType krt);
virtual ~AbstractKart(); virtual ~AbstractKart();
virtual core::stringw getName() const; virtual core::stringw getName() const;
virtual void reset(); virtual void reset();

View File

@ -20,6 +20,7 @@
#include "graphics/slip_stream.hpp" #include "graphics/slip_stream.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/skidding.hpp" #include "karts/skidding.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "physics/physics.hpp" #include "physics/physics.hpp"
@ -55,6 +56,12 @@ AbstractKartAnimation::AbstractKartAnimation(AbstractKart *kart,
// A time of 0 reset the squashing // A time of 0 reset the squashing
kart->setSquash(0.0f, 0.0f); kart->setSquash(0.0f, 0.0f);
} }
// Reset the wheels (and any other animation played for that kart)
// This avoid the effect that some wheels might be way below the kart
// which is very obvious in the rescue animation.
m_kart->getKartModel()->resetVisualWheelPosition();
} // AbstractKartAnimation } // AbstractKartAnimation
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -27,6 +27,7 @@
#include "karts/controller/ai_properties.hpp" #include "karts/controller/ai_properties.hpp"
#include "karts/kart_properties.hpp" #include "karts/kart_properties.hpp"
#include "tracks/battle_graph.hpp" #include "tracks/battle_graph.hpp"
#include "tracks/quad.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
int ArenaAI::m_test_node_for_banana = BattleGraph::UNKNOWN_POLY; int ArenaAI::m_test_node_for_banana = BattleGraph::UNKNOWN_POLY;
@ -156,7 +157,7 @@ bool ArenaAI::updateAimingPosition()
if (forward == m_target_node) if (forward == m_target_node)
{ {
m_aiming_points.push_back(BattleGraph::get() m_aiming_points.push_back(BattleGraph::get()
->getPolyOfNode(forward).getCenter()); ->getQuadOfNode(forward).getCenter());
m_aiming_points.push_back(m_target_point); m_aiming_points.push_back(m_target_point);
m_aiming_nodes.insert(forward); m_aiming_nodes.insert(forward);
@ -174,9 +175,9 @@ bool ArenaAI::updateAimingPosition()
} }
m_aiming_points.push_back(BattleGraph::get() m_aiming_points.push_back(BattleGraph::get()
->getPolyOfNode(forward).getCenter()); ->getQuadOfNode(forward).getCenter());
m_aiming_points.push_back(BattleGraph::get() m_aiming_points.push_back(BattleGraph::get()
->getPolyOfNode(next_node).getCenter()); ->getQuadOfNode(next_node).getCenter());
m_aiming_nodes.insert(forward); m_aiming_nodes.insert(forward);
m_aiming_nodes.insert(next_node); m_aiming_nodes.insert(next_node);

View File

@ -20,6 +20,7 @@
#include "karts/controller/ghost_controller.hpp" #include "karts/controller/ghost_controller.hpp"
#include "karts/kart_gfx.hpp" #include "karts/kart_gfx.hpp"
#include "karts/kart_model.hpp" #include "karts/kart_model.hpp"
#include "graphics/render_info.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "LinearMath/btQuaternion.h" #include "LinearMath/btQuaternion.h"
@ -28,7 +29,7 @@ GhostKart::GhostKart(const std::string& ident, unsigned int world_kart_id,
int position) int position)
: Kart(ident, world_kart_id, : Kart(ident, world_kart_id,
position, btTransform(btQuaternion(0, 0, 0, 1)), position, btTransform(btQuaternion(0, 0, 0, 1)),
PLAYER_DIFFICULTY_NORMAL, RenderInfo::KRT_TRANSPARENT) PLAYER_DIFFICULTY_NORMAL, KRT_TRANSPARENT)
{ {
} // GhostKart } // GhostKart

View File

@ -1,7 +1,7 @@
// //
// SuperTuxKart - a fun racing game with go-kart // SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2004-2015 Steve Baker <sjbaker1@airmail.net> // Copyright (C) 2004-2016 Steve Baker <sjbaker1@airmail.net>
// Copyright (C) 2006-2015 SuperTuxKart-Team, Joerg Henrichs, Steve Baker // Copyright (C) 2006-2016 SuperTuxKart-Team, Joerg Henrichs, Steve Baker
// //
// This program is free software; you can redistribute it and/or // This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License // modify it under the terms of the GNU General Public License
@ -33,6 +33,7 @@
#include "graphics/particle_emitter.hpp" #include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp" #include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/render_info.hpp"
#include "graphics/shadow.hpp" #include "graphics/shadow.hpp"
#include "graphics/skid_marks.hpp" #include "graphics/skid_marks.hpp"
#include "graphics/slip_stream.hpp" #include "graphics/slip_stream.hpp"
@ -91,8 +92,7 @@
*/ */
Kart::Kart (const std::string& ident, unsigned int world_kart_id, Kart::Kart (const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty, PerPlayerDifficulty difficulty, KartRenderType krt)
RenderInfo::KartRenderType krt)
: AbstractKart(ident, world_kart_id, position, init_transform, : AbstractKart(ident, world_kart_id, position, init_transform,
difficulty, krt) difficulty, krt)
@ -2110,6 +2110,7 @@ void Kart::updatePhysics(float dt)
{ {
m_has_started = true; m_has_started = true;
float f = getStartupBoost(); float f = getStartupBoost();
if(f >= 0.0f) m_kart_gfx->setCreationRateAbsolute(KartGFX::KGFX_ZIPPER, 100*f);
m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER, m_max_speed->instantSpeedIncrease(MaxSpeed::MS_INCREASE_ZIPPER,
0.9f*f, f, 0.9f*f, f,
/*engine_force*/200.0f, /*engine_force*/200.0f,

View File

@ -52,6 +52,8 @@ class SlipStream;
class Stars; class Stars;
class TerrainInfo; class TerrainInfo;
enum KartRenderType: unsigned int;
/** The main kart class. All type of karts are of this object, but with /** The main kart class. All type of karts are of this object, but with
* different controllers. The controllers are what turn a kart into a * different controllers. The controllers are what turn a kart into a
* player kart (i.e. the controller handle input), or an AI kart (the * player kart (i.e. the controller handle input), or an AI kart (the
@ -232,7 +234,7 @@ public:
Kart(const std::string& ident, unsigned int world_kart_id, Kart(const std::string& ident, unsigned int world_kart_id,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty, PerPlayerDifficulty difficulty,
RenderInfo::KartRenderType krt = RenderInfo::KRT_DEFAULT); KartRenderType krt);
virtual ~Kart(); virtual ~Kart();
virtual void init(RaceManager::KartType type); virtual void init(RaceManager::KartType type);
virtual void kartIsInRestNow(); virtual void kartIsInRestNow();

View File

@ -30,6 +30,7 @@
#include "graphics/material.hpp" #include "graphics/material.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/mesh_tools.hpp" #include "graphics/mesh_tools.hpp"
#include "graphics/render_info.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp" #include "karts/abstract_kart.hpp"
@ -116,6 +117,7 @@ KartModel::KartModel(bool is_master)
m_hat_name = ""; m_hat_name = "";
m_hat_node = NULL; m_hat_node = NULL;
m_hat_offset = core::vector3df(0,0,0); m_hat_offset = core::vector3df(0,0,0);
m_render_info = NULL;
for(unsigned int i=0; i<4; i++) for(unsigned int i=0; i<4; i++)
{ {
@ -141,7 +143,7 @@ KartModel::KartModel(bool is_master)
m_animation_speed = 25; m_animation_speed = 25;
m_current_animation = AF_DEFAULT; m_current_animation = AF_DEFAULT;
m_play_non_loop = false; m_play_non_loop = false;
m_krt = RenderInfo::KRT_DEFAULT; m_krt = KRT_DEFAULT;
m_support_colorization = false; m_support_colorization = false;
} // KartModel } // KartModel
@ -246,7 +248,7 @@ KartModel::~KartModel()
assert(!m_is_master); assert(!m_is_master);
// Drop the cloned transparent model if created // Drop the cloned transparent model if created
if (m_krt == RenderInfo::KRT_TRANSPARENT) if (m_krt == KRT_TRANSPARENT)
{ {
m_speed_weighted_objects[i].m_model->drop(); m_speed_weighted_objects[i].m_model->drop();
} }
@ -275,6 +277,8 @@ KartModel::~KartModel()
} }
} }
} }
delete m_render_info;
#ifdef DEBUG #ifdef DEBUG
#if SKELETON_DEBUG #if SKELETON_DEBUG
irr_driver->clearDebugMeshes(); irr_driver->clearDebugMeshes();
@ -289,12 +293,13 @@ KartModel::~KartModel()
* It is also marked not to be a master copy, so attachModel can be called * It is also marked not to be a master copy, so attachModel can be called
* for this instance. * for this instance.
*/ */
KartModel* KartModel::makeCopy(RenderInfo::KartRenderType krt) KartModel* KartModel::makeCopy(KartRenderType krt)
{ {
// Make sure that we are copying from a master objects, and // Make sure that we are copying from a master objects, and
// that there is indeed no animated node defined here ... // that there is indeed no animated node defined here ...
// just in case. // just in case.
assert(m_is_master); assert(m_is_master);
assert(m_render_info == NULL);
assert(!m_animated_node); assert(!m_animated_node);
KartModel *km = new KartModel(/*is master*/ false); KartModel *km = new KartModel(/*is master*/ false);
km->m_kart_width = m_kart_width; km->m_kart_width = m_kart_width;
@ -311,6 +316,8 @@ KartModel* KartModel::makeCopy(RenderInfo::KartRenderType krt)
km->m_hat_name = m_hat_name; km->m_hat_name = m_hat_name;
km->m_krt = krt; km->m_krt = krt;
km->m_support_colorization = m_support_colorization; km->m_support_colorization = m_support_colorization;
km->m_render_info = new RenderInfo();
km->m_render_info->setKartModelRenderInfo(krt);
km->m_nitro_emitter_position[0] = m_nitro_emitter_position[0]; km->m_nitro_emitter_position[0] = m_nitro_emitter_position[0];
km->m_nitro_emitter_position[1] = m_nitro_emitter_position[1]; km->m_nitro_emitter_position[1] = m_nitro_emitter_position[1];
@ -335,7 +342,7 @@ KartModel* KartModel::makeCopy(RenderInfo::KartRenderType krt)
// Master should not have any speed weighted nodes. // Master should not have any speed weighted nodes.
assert(!m_speed_weighted_objects[i].m_node); assert(!m_speed_weighted_objects[i].m_node);
km->m_speed_weighted_objects[i] = m_speed_weighted_objects[i]; km->m_speed_weighted_objects[i] = m_speed_weighted_objects[i];
if (krt == RenderInfo::KRT_TRANSPARENT) if (krt == KRT_TRANSPARENT)
{ {
// Only clone the mesh if transparent type is used, see #2445 // Only clone the mesh if transparent type is used, see #2445
km->m_speed_weighted_objects[i].m_model = irr_driver km->m_speed_weighted_objects[i].m_model = irr_driver
@ -359,7 +366,6 @@ scene::ISceneNode* KartModel::attachModel(bool animated_models, bool always_anim
assert(!m_is_master); assert(!m_is_master);
scene::ISceneNode* node = NULL; scene::ISceneNode* node = NULL;
m_render_info.setKartModelRenderInfo(m_krt);
if (animated_models) if (animated_models)
{ {
@ -982,6 +988,20 @@ void KartModel::update(float dt, float distance, float steer, float speed,
m_animated_node->setCurrentFrame(frame); m_animated_node->setCurrentFrame(frame);
} // update } // update
//-----------------------------------------------------------------------------
/** Called when a kart is rescued to reset all visual wheels to their default
* position to avoid that some wheels look too far away from the kart (which
* is not that visible while a kart is driving).
*/
void KartModel::resetVisualWheelPosition()
{
for(unsigned int i=0; i<4; i++)
{
m_kart->getVehicle()->getWheelInfo(i).m_raycastInfo.m_suspensionLength =
m_default_physics_suspension[i];
} // for i < 4
} // resetVisualSuspension
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void KartModel::attachHat() void KartModel::attachHat()
{ {
@ -1017,3 +1037,10 @@ void KartModel::attachHat()
} // if bone } // if bone
} // if(m_hat_name) } // if(m_hat_name)
} // attachHat } // attachHat
//-----------------------------------------------------------------------------
RenderInfo* KartModel::getRenderInfo()
{
return m_support_colorization || m_krt == KRT_TRANSPARENT ?
m_render_info : NULL;
} // getRenderInfo

View File

@ -30,14 +30,16 @@ namespace irr
} }
using namespace irr; using namespace irr;
#include "graphics/render_info.hpp"
#include "utils/no_copy.hpp" #include "utils/no_copy.hpp"
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
class AbstractKart; class AbstractKart;
class KartProperties; class KartProperties;
class RenderInfo;
class XMLNode; class XMLNode;
enum KartRenderType: unsigned int;
/** A speed-weighted object is an object whose characteristics are influenced by the kart's speed */ /** A speed-weighted object is an object whose characteristics are influenced by the kart's speed */
struct SpeedWeightedObject struct SpeedWeightedObject
{ {
@ -231,16 +233,16 @@ private:
/** Pointer to the kart object belonging to this kart model. */ /** Pointer to the kart object belonging to this kart model. */
AbstractKart* m_kart; AbstractKart* m_kart;
RenderInfo::KartRenderType m_krt; KartRenderType m_krt;
RenderInfo m_render_info; RenderInfo* m_render_info;
bool m_support_colorization; bool m_support_colorization;
public: public:
KartModel(bool is_master); KartModel(bool is_master);
~KartModel(); ~KartModel();
KartModel* makeCopy(RenderInfo::KartRenderType krt); KartModel* makeCopy(KartRenderType krt);
void reset(); void reset();
void loadInfo(const XMLNode &node); void loadInfo(const XMLNode &node);
bool loadModels(const KartProperties &kart_properties); bool loadModels(const KartProperties &kart_properties);
@ -249,6 +251,7 @@ public:
float current_lean_angle, float current_lean_angle,
int gt_replay_index = -1); int gt_replay_index = -1);
void finishedRace(); void finishedRace();
void resetVisualWheelPosition();
scene::ISceneNode* scene::ISceneNode*
attachModel(bool animatedModels, bool always_animated); attachModel(bool animatedModels, bool always_animated);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
@ -337,17 +340,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
core::vector3df getHatOffset() { return m_hat_offset; } core::vector3df getHatOffset() { return m_hat_offset; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
RenderInfo* getRenderInfo() RenderInfo* getRenderInfo();
{
return m_support_colorization || m_krt == RenderInfo::KRT_TRANSPARENT ?
&m_render_info : NULL;
}
// ------------------------------------------------------------------------
const RenderInfo* getRenderInfo() const
{
return m_support_colorization || m_krt == RenderInfo::KRT_TRANSPARENT ?
&m_render_info : NULL;
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool supportColorization() const { return m_support_colorization; } bool supportColorization() const { return m_support_colorization; }

View File

@ -45,6 +45,8 @@ class CombinedCharacteristic;
class Material; class Material;
class XMLNode; class XMLNode;
enum KartRenderType: unsigned int;
/** /**
* \brief This class stores the properties of a kart. * \brief This class stores the properties of a kart.
* This includes size, name, identifier, physical properties etc. * This includes size, name, identifier, physical properties etc.
@ -242,9 +244,11 @@ public:
video::ITexture *getMinimapIcon () const {return m_minimap_icon; } video::ITexture *getMinimapIcon () const {return m_minimap_icon; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a pointer to the KartModel object. */ /** Returns a pointer to the KartModel object.
KartModel* getKartModelCopy * \param krt The KartRenderType, like default, red, blue or transparent.
(RenderInfo::KartRenderType krt = RenderInfo::KRT_DEFAULT) const * see the RenderInfo include for details
*/
KartModel* getKartModelCopy(KartRenderType krt) const
{return m_kart_model->makeCopy(krt); } {return m_kart_model->makeCopy(krt); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -18,6 +18,7 @@
#include "karts/kart_with_stats.hpp" #include "karts/kart_with_stats.hpp"
#include "graphics/render_info.hpp"
#include "karts/explosion_animation.hpp" #include "karts/explosion_animation.hpp"
#include "karts/rescue_animation.hpp" #include "karts/rescue_animation.hpp"
#include "items/item.hpp" #include "items/item.hpp"
@ -28,7 +29,7 @@ KartWithStats::KartWithStats(const std::string& ident,
int position, const btTransform& init_transform, int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty) PerPlayerDifficulty difficulty)
: Kart(ident, world_kart_id, position, : Kart(ident, world_kart_id, position,
init_transform, difficulty) init_transform, difficulty, KRT_DEFAULT)
{ {
} // KartWithStats } // KartWithStats

View File

@ -1887,6 +1887,9 @@ void runUnitTests()
Log::info("UnitTest", "Battle Graph"); Log::info("UnitTest", "Battle Graph");
BattleGraph::unitTesting(); BattleGraph::unitTesting();
Log::info("UnitTest", "Fonts for translation");
font_manager->unitTesting();
Log::info("UnitTest", "====================="); Log::info("UnitTest", "=====================");
Log::info("UnitTest", "Testing successful "); Log::info("UnitTest", "Testing successful ");
Log::info("UnitTest", "====================="); Log::info("UnitTest", "=====================");

View File

@ -396,8 +396,7 @@ AbstractKart *SoccerWorld::createKart(const std::string &kart_ident, int index,
m_kart_position_map[index] = (unsigned)(pos_index - 1); m_kart_position_map[index] = (unsigned)(pos_index - 1);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos, AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
difficulty, team == SOCCER_TEAM_BLUE ? difficulty, team == SOCCER_TEAM_BLUE ? KRT_BLUE : KRT_RED);
RenderInfo::KRT_BLUE : RenderInfo::KRT_RED);
new_kart->init(race_manager->getKartType(index)); new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL; Controller *controller = NULL;

View File

@ -27,6 +27,7 @@
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/camera.hpp" #include "graphics/camera.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "input/device_manager.hpp" #include "input/device_manager.hpp"
#include "input/keyboard_device.hpp" #include "input/keyboard_device.hpp"
@ -334,7 +335,7 @@ AbstractKart *World::createKart(const std::string &kart_ident, int index,
int position = index+1; int position = index+1;
btTransform init_pos = getStartTransform(index - gk); btTransform init_pos = getStartTransform(index - gk);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos, AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
difficulty); difficulty, KRT_DEFAULT);
new_kart->init(race_manager->getKartType(index)); new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL; Controller *controller = NULL;
switch(kart_type) switch(kart_type)

View File

@ -90,7 +90,7 @@ void GetPublicAddress::createStunRequest()
m_transaction_host = new Network(1, 1, 0, 0); m_transaction_host = new Network(1, 1, 0, 0);
// Assemble the message for the stun server // Assemble the message for the stun server
BareNetworkString s(21); BareNetworkString s(20);
// bytes 0-1: the type of the message // bytes 0-1: the type of the message
// bytes 2-3: message length added to header (attributes) // bytes 2-3: message length added to header (attributes)
@ -105,8 +105,6 @@ void GetPublicAddress::createStunRequest()
s.addUInt8(random_byte); s.addUInt8(random_byte);
m_stun_tansaction_id[i] = random_byte; m_stun_tansaction_id[i] = random_byte;
} }
s.addChar(0);
m_transaction_host->sendRawPacket(s, m_transaction_host->sendRawPacket(s,
TransportAddress(m_stun_server_ip, TransportAddress(m_stun_server_ip,
@ -140,7 +138,7 @@ std::string GetPublicAddress::parseStunResponse()
return "STUN response contains no data at all"; return "STUN response contains no data at all";
// Convert to network string. // Convert to network string.
NetworkString datas((uint8_t*)buffer, len); BareNetworkString datas(buffer, len);
// check that the stun response is a response, contains the magic cookie // check that the stun response is a response, contains the magic cookie
// and the transaction ID // and the transaction ID

View File

@ -188,6 +188,7 @@ void TriangleMesh::createPhysicalBody(btCollisionObject::CollisionFlags flags,
m_motion_state = new btDefaultMotionState(startTransform); m_motion_state = new btDefaultMotionState(startTransform);
btRigidBody::btRigidBodyConstructionInfo info(0.0f, m_motion_state, btRigidBody::btRigidBodyConstructionInfo info(0.0f, m_motion_state,
m_collision_shape); m_collision_shape);
info.m_restitution = 0.8f;
m_body=new btRigidBody(info); m_body=new btRigidBody(info);
World::getWorld()->getPhysics()->addBody(m_body); World::getWorld()->getPhysics()->addBody(m_body);

View File

@ -23,7 +23,6 @@
#include "graphics/central_settings.hpp" #include "graphics/central_settings.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "states_screens/dialogs/tutorial_message_dialog.hpp" #include "states_screens/dialogs/tutorial_message_dialog.hpp"

View File

@ -277,7 +277,7 @@ void ArenasScreen::buildTrackList()
} }
else else
{ {
w->addItem( curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0, w->addItem( translations->fribidize(curr->getName()), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE ); IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
} }
} }
@ -329,7 +329,7 @@ void ArenasScreen::buildTrackList()
} }
else else
{ {
w->addItem( curr->getName(), curr->getIdent(), curr->getScreenshotFile(), 0, w->addItem( translations->fribidize(curr->getName()), curr->getIdent(), curr->getScreenshotFile(), 0,
IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE ); IconButtonWidget::ICON_PATH_TYPE_ABSOLUTE );
} }
} }

View File

@ -17,10 +17,8 @@
#include "states_screens/dialogs/message_dialog.hpp" #include "states_screens/dialogs/message_dialog.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/screen.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/label_widget.hpp" #include "guiengine/widgets/label_widget.hpp"
#include "guiengine/widgets/ribbon_widget.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "states_screens/state_manager.hpp" #include "states_screens/state_manager.hpp"
#include "utils/translation.hpp" #include "utils/translation.hpp"
@ -111,28 +109,29 @@ void MessageDialog::loadedFromFile()
{ {
LabelWidget* message = getWidget<LabelWidget>("title"); LabelWidget* message = getWidget<LabelWidget>("title");
message->setText( m_msg, false ); message->setText( m_msg, false );
RibbonWidget* ribbon = getWidget<RibbonWidget>("buttons");
ribbon->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
// If the dialog is a simple 'OK' dialog, then hide the "Yes" button and // If the dialog is a simple 'OK' dialog, then hide the "Yes" button and
// change "Cancel" to "OK" // change "Cancel" to "OK"
if (m_type == MessageDialog::MESSAGE_DIALOG_OK) if (m_type == MessageDialog::MESSAGE_DIALOG_OK)
{ {
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm"); IconButtonWidget* yesbtn = getWidget<IconButtonWidget>("cancel");
yesbtn->setVisible(false); yesbtn->setVisible(false);
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("cancel"); IconButtonWidget* cancelbtn = getWidget<IconButtonWidget>("confirm");
cancelbtn->setText(_("OK")); cancelbtn->setText(_("OK"));
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER); cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
} }
else if (m_type == MessageDialog::MESSAGE_DIALOG_YESNO) else if (m_type == MessageDialog::MESSAGE_DIALOG_YESNO)
{ {
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("cancel"); IconButtonWidget* cancelbtn = getWidget<IconButtonWidget>("cancel");
cancelbtn->setText(_("No")); cancelbtn->setText(_("No"));
} }
else if (m_type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL) else if (m_type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL)
{ {
// In case of a OK_CANCEL dialog, change the text from 'Yes' to 'Ok' // In case of a OK_CANCEL dialog, change the text from 'Yes' to 'Ok'
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm"); IconButtonWidget* yesbtn = getWidget<IconButtonWidget>("confirm");
yesbtn->setText(_("OK")); yesbtn->setText(_("OK"));
} }
} }
@ -147,8 +146,9 @@ void MessageDialog::onEnterPressedInternal()
GUIEngine::EventPropagation MessageDialog::processEvent(const std::string& eventSource) GUIEngine::EventPropagation MessageDialog::processEvent(const std::string& eventSource)
{ {
RibbonWidget* ribbon = getWidget<RibbonWidget>(eventSource.c_str());
if (eventSource == "cancel") if (ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER) == "cancel")
{ {
if (m_listener == NULL) if (m_listener == NULL)
{ {
@ -161,7 +161,7 @@ GUIEngine::EventPropagation MessageDialog::processEvent(const std::string& event
return GUIEngine::EVENT_BLOCK; return GUIEngine::EVENT_BLOCK;
} }
else if (eventSource == "confirm") else if (ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER) == "confirm")
{ {
if (m_listener == NULL) if (m_listener == NULL)
{ {

View File

@ -25,6 +25,7 @@
#include "challenges/unlock_manager.hpp" #include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
@ -295,7 +296,7 @@ void FeatureUnlockedCutScene::init()
else if (m_unlocked_stuff[n].m_unlocked_kart != NULL) else if (m_unlocked_stuff[n].m_unlocked_kart != NULL)
{ {
KartModel *kart_model = KartModel *kart_model =
m_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy(); m_unlocked_stuff[n].m_unlocked_kart->getKartModelCopy(KRT_DEFAULT);
m_all_kart_models.push_back(kart_model); m_all_kart_models.push_back(kart_model);
m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true, false); m_unlocked_stuff[n].m_root_gift_node = kart_model->attachModel(true, false);
m_unlocked_stuff[n].m_scale = 5.0f; m_unlocked_stuff[n].m_scale = 5.0f;

View File

@ -23,6 +23,7 @@
#include "challenges/unlock_manager.hpp" #include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/button_widget.hpp"
@ -181,7 +182,7 @@ void GrandPrixLose::setKarts(std::vector<std::string> ident_arg)
const KartProperties* kart = kart_properties_manager->getKart(ident_arg[n]); const KartProperties* kart = kart_properties_manager->getKart(ident_arg[n]);
if (kart != NULL) if (kart != NULL)
{ {
KartModel* kart_model = kart->getKartModelCopy(); KartModel* kart_model = kart->getKartModelCopy(KRT_DEFAULT);
m_all_kart_models.push_back(kart_model); m_all_kart_models.push_back(kart_model);
scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false);

View File

@ -23,6 +23,7 @@
#include "challenges/unlock_manager.hpp" #include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp" #include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp" #include "guiengine/engine.hpp"
#include "guiengine/scalable_font.hpp" #include "guiengine/scalable_font.hpp"
#include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/button_widget.hpp"
@ -304,7 +305,7 @@ void GrandPrixWin::setKarts(const std::string idents_arg[3])
const KartProperties* kp = kart_properties_manager->getKart(idents[i]); const KartProperties* kp = kart_properties_manager->getKart(idents[i]);
if (kp == NULL) continue; if (kp == NULL) continue;
KartModel* kart_model = kp->getKartModelCopy(); KartModel* kart_model = kp->getKartModelCopy(KRT_DEFAULT);
m_all_kart_models.push_back(kart_model); m_all_kart_models.push_back(kart_model);
scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false); scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false);

View File

@ -21,6 +21,7 @@
#include "audio/sfx_manager.hpp" #include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp" #include "audio/sfx_base.hpp"
#include "config/hardware_stats.hpp" #include "config/hardware_stats.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "font/bold_face.hpp" #include "font/bold_face.hpp"
#include "font/regular_face.hpp" #include "font/regular_face.hpp"
@ -284,8 +285,10 @@ void OptionsScreenUI::eventCallback(Widget* widget, const std::string& name, con
{ {
stats->setVisible(false); stats->setVisible(false);
stats_label->setVisible(false); stats_label->setVisible(false);
PlayerProfile* profile = PlayerManager::getCurrentPlayer();
if (profile != NULL && profile->isLoggedIn())
profile->requestSignOut();
} }
} }
else if (name=="enable-hw-report") else if (name=="enable-hw-report")
{ {

View File

@ -356,6 +356,7 @@ void RaceGUI::drawGlobalMiniMap()
const Vec3& xyz = kart->getXYZ(); const Vec3& xyz = kart->getXYZ();
Vec3 draw_at; Vec3 draw_at;
world->getTrack()->mapPoint2MiniMap(xyz, &draw_at); world->getTrack()->mapPoint2MiniMap(xyz, &draw_at);
draw_at *= UserConfigParams::m_scale_rtts_factor;
video::ITexture* icon = kart->getKartProperties()->getMinimapIcon(); video::ITexture* icon = kart->getKartProperties()->getMinimapIcon();
@ -376,6 +377,7 @@ void RaceGUI::drawGlobalMiniMap()
{ {
Vec3 draw_at; Vec3 draw_at;
world->getTrack()->mapPoint2MiniMap(sw->getBallPosition(), &draw_at); world->getTrack()->mapPoint2MiniMap(sw->getBallPosition(), &draw_at);
draw_at *= UserConfigParams::m_scale_rtts_factor;
video::ITexture* icon = video::ITexture* icon =
irr_driver->getTexture(FileManager::GUI, "soccer_ball_normal.png"); irr_driver->getTexture(FileManager::GUI, "soccer_ball_normal.png");

View File

@ -108,6 +108,7 @@ RaceGUIOverworld::RaceGUIOverworld()
m_string_lap = _("Lap"); m_string_lap = _("Lap");
m_string_rank = _("Rank"); m_string_rank = _("Rank");
m_active_challenge = NULL;
// Determine maximum length of the rank/lap text, in order to // Determine maximum length of the rank/lap text, in order to
// align those texts properly on the right side of the viewport. // align those texts properly on the right side of the viewport.
@ -512,7 +513,13 @@ void RaceGUIOverworld::drawGlobalMiniMap()
pos.UpperLeftCorner.Y += GUIEngine::getTitleFontHeight(); pos.UpperLeftCorner.Y += GUIEngine::getTitleFontHeight();
pos.LowerRightCorner.Y = irr_driver->getActualScreenSize().Height; pos.LowerRightCorner.Y = irr_driver->getActualScreenSize().Height;
GUIEngine::getFont()->draw(challenge->getChallengeDescription().c_str(),
if (m_active_challenge != challenge)
{
m_active_challenge = challenge;
m_challenge_description = challenge->getChallengeDescription();
}
GUIEngine::getFont()->draw(m_challenge_description,
pos, video::SColor(255,255,255,255), pos, video::SColor(255,255,255,255),
false, false /* vcenter */, NULL); false, false /* vcenter */, NULL);

View File

@ -101,6 +101,11 @@ private:
int m_trophy_points_width; int m_trophy_points_width;
/** The latest challenge approached by the kart */
const ChallengeData* m_active_challenge;
core::stringw m_challenge_description;
/** The current challenge over which the mouse is hovering. */ /** The current challenge over which the mouse is hovering. */
const OverworldChallenge *m_current_challenge; const OverworldChallenge *m_current_challenge;

View File

@ -1420,7 +1420,7 @@ void RaceResultGUI::backToLobby()
if (race_manager->modeHasLaps()) if (race_manager->modeHasLaps())
{ {
core::stringw laps = _("Laps: %i", race_manager->getNumLaps()); core::stringw laps = _("Laps: %i", race_manager->getNumLaps());
current_y += m_distance_between_rows * 0.8f * 2; current_y += int(m_distance_between_rows * 0.8f * 2);
GUIEngine::getFont()->draw(laps, core::recti(x, current_y, 0, 0), GUIEngine::getFont()->draw(laps, core::recti(x, current_y, 0, 0),
white_color, false, false, nullptr, true); white_color, false, false, nullptr, true);
} }
@ -1428,7 +1428,7 @@ void RaceResultGUI::backToLobby()
const core::stringw& difficulty_name = const core::stringw& difficulty_name =
race_manager->getDifficultyName(race_manager->getDifficulty()); race_manager->getDifficultyName(race_manager->getDifficulty());
core::stringw difficulty_string = _("Difficulty: %s", difficulty_name); core::stringw difficulty_string = _("Difficulty: %s", difficulty_name);
current_y += m_distance_between_rows * 0.8f; current_y += int(m_distance_between_rows * 0.8f);
GUIEngine::getFont()->draw(difficulty_string, core::recti(x, current_y, 0, 0), GUIEngine::getFont()->draw(difficulty_string, core::recti(x, current_y, 0, 0),
white_color, false, false, nullptr, true); white_color, false, false, nullptr, true);
// show fastest lap // show fastest lap
@ -1437,7 +1437,7 @@ void RaceResultGUI::backToLobby()
float best_lap_time = static_cast<LinearWorld*>(World::getWorld())->getFastestLap(); float best_lap_time = static_cast<LinearWorld*>(World::getWorld())->getFastestLap();
core::stringw best_lap_string = _("Best lap time: %s", core::stringw best_lap_string = _("Best lap time: %s",
StringUtils::timeToString(best_lap_time).c_str()); StringUtils::timeToString(best_lap_time).c_str());
current_y += m_distance_between_rows * 0.8f; current_y += int(m_distance_between_rows * 0.8f);
GUIEngine::getFont()->draw(best_lap_string, GUIEngine::getFont()->draw(best_lap_string,
core::recti(x, current_y, 0, 0), white_color, false, false, core::recti(x, current_y, 0, 0), white_color, false, false,
nullptr, true); nullptr, true);

View File

@ -116,7 +116,7 @@ void RaceSetupScreen::init()
irr::core::stringw name5 = irr::core::stringw( irr::core::stringw name5 = irr::core::stringw(
RaceManager::getNameOf(RaceManager::MINOR_MODE_SOCCER)) + L"\n"; RaceManager::getNameOf(RaceManager::MINOR_MODE_SOCCER)) + L"\n";
name5 += _("Push the ball to the opposite cage to score goals."); name5 += _("Push the ball into the opposite cage to score goals.");
w2->addItem( name5, IDENT_SOCCER, RaceManager::getIconOf(RaceManager::MINOR_MODE_SOCCER)); w2->addItem( name5, IDENT_SOCCER, RaceManager::getIconOf(RaceManager::MINOR_MODE_SOCCER));
#define ENABLE_EASTER_EGG_MODE #define ENABLE_EASTER_EGG_MODE

View File

@ -19,6 +19,7 @@
#include "audio/sfx_manager.hpp" #include "audio/sfx_manager.hpp"
#include "config/user_config.hpp" #include "config/user_config.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/widgets/bubble_widget.hpp" #include "guiengine/widgets/bubble_widget.hpp"
#include "guiengine/widgets/button_widget.hpp" #include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/spinner_widget.hpp" #include "guiengine/widgets/spinner_widget.hpp"
@ -149,9 +150,8 @@ void SoccerSetupScreen::beforeAddingWidget()
info.support_colorization = kart_model.supportColorization(); info.support_colorization = kart_model.supportColorization();
if (info.support_colorization) if (info.support_colorization)
{ {
kart_view->getModelViewRenderInfo().setKartModelRenderInfo kart_view->getModelViewRenderInfo()->setKartModelRenderInfo
(info.team == SOCCER_TEAM_BLUE ? (info.team == SOCCER_TEAM_BLUE ? KRT_BLUE : KRT_RED);
RenderInfo::KRT_BLUE : RenderInfo::KRT_RED);
} }
// Add the kart model (including wheels and speed weight objects) // Add the kart model (including wheels and speed weight objects)
@ -295,7 +295,7 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions(PlayerAction action
if (m_kart_view_info[playerId].support_colorization) if (m_kart_view_info[playerId].support_colorization)
{ {
m_kart_view_info[playerId].view->getModelViewRenderInfo() m_kart_view_info[playerId].view->getModelViewRenderInfo()
.setKartModelRenderInfo(RenderInfo::KRT_RED); ->setKartModelRenderInfo(KRT_RED);
} }
for(int i=0 ; i < nb_players ; i++) for(int i=0 ; i < nb_players ; i++)
@ -315,7 +315,7 @@ GUIEngine::EventPropagation SoccerSetupScreen::filterActions(PlayerAction action
if (m_kart_view_info[playerId].support_colorization) if (m_kart_view_info[playerId].support_colorization)
{ {
m_kart_view_info[playerId].view->getModelViewRenderInfo() m_kart_view_info[playerId].view->getModelViewRenderInfo()
.setKartModelRenderInfo(RenderInfo::KRT_BLUE); ->setKartModelRenderInfo(KRT_BLUE);
} }
for(int i=0 ; i < nb_players ; i++) for(int i=0 ; i < nb_players ; i++)

View File

@ -18,7 +18,6 @@
#ifndef HEADER_SOCCER_SETUP_SCREEN_HPP #ifndef HEADER_SOCCER_SETUP_SCREEN_HPP
#define HEADER_SOCCER_SETUP_SCREEN_HPP #define HEADER_SOCCER_SETUP_SCREEN_HPP
#include "graphics/render_info.hpp"
#include "guiengine/screen.hpp" #include "guiengine/screen.hpp"
#include "network/remote_kart_info.hpp" #include "network/remote_kart_info.hpp"
@ -41,7 +40,6 @@ class SoccerSetupScreen : public GUIEngine::Screen,
bool confirmed; bool confirmed;
bool support_colorization; bool support_colorization;
SoccerTeam team; SoccerTeam team;
RenderInfo render_info;
KartViewInfo() : view(), confirmed(false), support_colorization(false), KartViewInfo() : view(), confirmed(false), support_colorization(false),
team(SOCCER_TEAM_NONE) {} team(SOCCER_TEAM_NONE) {}

View File

@ -338,9 +338,9 @@ POParser::parse()
// skip UTF-8 intro that some text editors produce // skip UTF-8 intro that some text editors produce
// see http://en.wikipedia.org/wiki/Byte-order_mark // see http://en.wikipedia.org/wiki/Byte-order_mark
if (current_line.size() >= 3 && if (current_line.size() >= 3 &&
current_line[0] == static_cast<char>(0xef) && current_line[0] == static_cast<unsigned char>(0xef) &&
current_line[1] == static_cast<char>(0xbb) && current_line[1] == static_cast<unsigned char>(0xbb) &&
current_line[2] == static_cast<char>(0xbf)) current_line[2] == static_cast<unsigned char>(0xbf))
{ {
current_line = current_line.substr(3); current_line = current_line.substr(3);
} }

View File

@ -28,10 +28,12 @@
#include "items/item_manager.hpp" #include "items/item_manager.hpp"
#include "race/race_manager.hpp" #include "race/race_manager.hpp"
#include "tracks/navmesh.hpp" #include "tracks/navmesh.hpp"
#include "tracks/quad.hpp"
#include "tracks/track.hpp" #include "tracks/track.hpp"
#include "tracks/track_manager.hpp" #include "tracks/track_manager.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
#include <algorithm>
#include <queue> #include <queue>
const int BattleGraph::UNKNOWN_POLY = -1; const int BattleGraph::UNKNOWN_POLY = -1;
@ -50,9 +52,10 @@ BattleGraph::BattleGraph(const std::string &navmesh_file_name,
buildGraph(NavMesh::get()); buildGraph(NavMesh::get());
// Compute shortest distance from all nodes // Compute shortest distance from all nodes
for(unsigned int i=0; i < NavMesh::get()->getNumberOfPolys(); i++) for(unsigned int i=0; i < NavMesh::get()->getNumberOfQuads(); i++)
computeDijkstra(i); computeDijkstra(i);
sortNearbyQuad();
if (node && race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER) if (node && race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
loadGoalNodes(node); loadGoalNodes(node);
@ -73,35 +76,32 @@ BattleGraph::~BattleGraph(void)
* adjacency matrix. */ * adjacency matrix. */
void BattleGraph::buildGraph(NavMesh* navmesh) void BattleGraph::buildGraph(NavMesh* navmesh)
{ {
unsigned int n_polys = navmesh->getNumberOfPolys(); const unsigned int n_quads = navmesh->getNumberOfQuads();
m_distance_matrix = std::vector< std::vector<float> > m_distance_matrix = std::vector<std::vector<float>>
(n_polys, std::vector<float>(n_polys, 9999.9f)); (n_quads, std::vector<float>(n_quads, 9999.9f));
for(unsigned int i=0; i<n_polys; i++) for(unsigned int i = 0; i < n_quads; i++)
{ {
NavPoly currentPoly = navmesh->getNavPoly(i); const Quad& cur_quad = navmesh->getQuad(i);
const std::vector<int> &adjacents = navmesh->getAdjacentPolys(i); for (const int& adjacent : navmesh->getAdjacentQuads(i))
for(unsigned int j=0; j<adjacents.size(); j++)
{ {
Vec3 diff = navmesh->getCenterOfPoly(adjacents[j]) Vec3 diff = navmesh->getQuad(adjacent).getCenter()
- currentPoly.getCenter(); - cur_quad.getCenter();
float distance = diff.length(); float distance = diff.length();
m_distance_matrix[i][adjacents[j]] = distance; m_distance_matrix[i][adjacent] = distance;
//m_distance_matrix[adjacents[j]][i] = distance;
} }
m_distance_matrix[i][i] = 0.0f; m_distance_matrix[i][i] = 0.0f;
} }
// Allocate and initialise the previous node data structure: // Allocate and initialise the previous node data structure:
unsigned int n = getNumNodes(); m_parent_poly = std::vector<std::vector<int>>
m_parent_poly = std::vector< std::vector<int> > (n_quads, std::vector<int>(n_quads, BattleGraph::UNKNOWN_POLY));
(n, std::vector<int>(n, BattleGraph::UNKNOWN_POLY)); for (unsigned int i = 0; i < n_quads; i++)
for(unsigned int i=0; i<n; i++)
{ {
for(unsigned int j=0; j<n; j++) for (unsigned int j = 0; j < n_quads; j++)
{ {
if(i == j || m_distance_matrix[i][j]>=9899.9f) if(i == j || m_distance_matrix[i][j] >= 9899.9f)
m_parent_poly[i][j]=-1; m_parent_poly[i][j] = -1;
else else
m_parent_poly[i][j] = i; m_parent_poly[i][j] = i;
} // for j } // for j
@ -145,11 +145,9 @@ void BattleGraph::computeDijkstra(int source)
int cur_index = current.first; int cur_index = current.first;
if(visited[cur_index]) continue; if(visited[cur_index]) continue;
visited[cur_index] = true; visited[cur_index] = true;
const NavPoly &current_poly = navmesh->getNavPoly(cur_index);
const std::vector<int> &adjacents = current_poly.getAdjacents(); for (const int& adjacent : navmesh->getAdjacentQuads(cur_index))
for(unsigned int j=0; j<adjacents.size(); j++)
{ {
int adjacent = adjacents[j];
// Distance already computed, can be ignored // Distance already computed, can be ignored
if(visited[adjacent]) continue; if(visited[adjacent]) continue;
@ -224,7 +222,7 @@ void BattleGraph::findItemsOnGraphNodes()
for (unsigned int j = 0; j < this->getNumNodes(); ++j) for (unsigned int j = 0; j < this->getNumNodes(); ++j)
{ {
if (NavMesh::get()->getNavPoly(j).pointInPoly(xyz, false)) if (getQuadOfNode(j).pointInQuad(xyz, false))
polygon = j; polygon = j;
} }
@ -243,70 +241,50 @@ int BattleGraph::pointToNode(const int cur_node,
const Vec3& cur_point, const Vec3& cur_point,
bool ignore_vertical) const bool ignore_vertical) const
{ {
int final_node = BattleGraph::UNKNOWN_POLY;
if (cur_node == BattleGraph::UNKNOWN_POLY) if (cur_node == BattleGraph::UNKNOWN_POLY)
{ {
// Try all nodes in the battle graph // Try all nodes in the battle graph
bool found = false; for (unsigned int node = 0; node < this->getNumNodes(); node++)
unsigned int node = 0;
while (!found && node < this->getNumNodes())
{ {
const NavPoly& p_all = this->getPolyOfNode(node); const Quad& quad = this->getQuadOfNode(node);
if (p_all.pointInPoly(cur_point, ignore_vertical)) if (quad.pointInQuad(cur_point, ignore_vertical))
{ {
final_node = node; return node;
found = true;
} }
node++;
} }
} }
else else
{ {
// Check if the point is still on the same node // Check if the point is still on the same node
const NavPoly& p_cur = this->getPolyOfNode(cur_node); const Quad& cur_quad = this->getQuadOfNode(cur_node);
if (p_cur.pointInPoly(cur_point, ignore_vertical)) return cur_node; if (cur_quad.pointInQuad(cur_point, ignore_vertical)) return cur_node;
// If not then check all adjacent polys // If not then check all nearby quads (8 quads)
const std::vector<int>& adjacents = NavMesh::get() // Skip the same node
->getAdjacentPolys(cur_node); assert(cur_node == m_nearby_quads[cur_node][0]);
for (unsigned int i = 1; i < m_nearby_quads[0].size(); i++)
bool found = false;
unsigned int num = 0;
while (!found && num < adjacents.size())
{ {
const NavPoly& p_temp = this->getPolyOfNode(adjacents[num]); const int test_node = m_nearby_quads[cur_node][i];
if (p_temp.pointInPoly(cur_point, ignore_vertical)) const Quad& quad = this->getQuadOfNode(test_node);
if (quad.pointInQuad(cur_point, ignore_vertical))
{ {
final_node = adjacents[num]; return test_node;
found = true;
} }
num++;
} }
// Current node is still unkown // Current node is still unkown:
if (final_node == BattleGraph::UNKNOWN_POLY)
{
// Calculated distance from saved node to current position, // Calculated distance from saved node to current position,
// if it's close enough than use the saved node anyway, it // if it's close enough than use the saved node anyway, it
// may happen when the kart stays on the edge of obstacles // may happen when the kart stays on the edge of obstacles
const NavPoly& p = this->getPolyOfNode(cur_node); Vec3 diff = (cur_quad.getCenter() - cur_point);
const float dist = (p.getCenter() - cur_point).length_2d(); float dist = diff.length();
if (dist < 3.0f) if (dist < 3.0f)
final_node = cur_node; return cur_node;
} }
}
return final_node;
} // pointToNode
// -----------------------------------------------------------------------------
const int BattleGraph::getNextShortestPathPoly(int i, int j) const
{
if (i == BattleGraph::UNKNOWN_POLY || j == BattleGraph::UNKNOWN_POLY)
return BattleGraph::UNKNOWN_POLY; return BattleGraph::UNKNOWN_POLY;
return m_parent_poly[j][i]; } // pointToNode
} // getNextShortestPathPoly
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
const bool BattleGraph::differentNodeColor(int n, NodeColor* c) const const bool BattleGraph::differentNodeColor(int n, NodeColor* c) const
@ -456,3 +434,39 @@ std::vector<int> BattleGraph::getPathFromTo(int from, int to,
} }
return path; return path;
} // getPathFromTo } // getPathFromTo
// ----------------------------------------------------------------------------
void BattleGraph::sortNearbyQuad()
{
// Only try the nearby 8 quads
const unsigned int n = 8;
m_nearby_quads = std::vector< std::vector<int> >
(this->getNumNodes(), std::vector<int>(n, BattleGraph::UNKNOWN_POLY));
for (unsigned int i = 0; i < this->getNumNodes(); i++)
{
// Get the distance to all nodes at i
std::vector<float> dist = m_distance_matrix[i];
for (unsigned int j = 0; j < n; j++)
{
std::vector<float>::iterator it =
std::min_element(dist.begin(), dist.end());
const int pos = it - dist.begin();
m_nearby_quads[i][j] = pos;
dist[pos] = 999999.0f;
}
}
} // sortNearbyQuad
// ----------------------------------------------------------------------------
void BattleGraph::set3DVerticesOfGraph(int i, video::S3DVertex *v,
const video::SColor &color) const
{
NavMesh::get()->getQuad(i).getVertices(v, color);
} // set3DVerticesOfGraph
// ----------------------------------------------------------------------------
const bool BattleGraph::isNodeInvisible(int n) const
{
return NavMesh::get()->getQuad(n).isInvisible();
} // isNodeInvisible

View File

@ -26,10 +26,8 @@
#include "tracks/graph_structure.hpp" #include "tracks/graph_structure.hpp"
#include "tracks/navmesh.hpp" #include "tracks/navmesh.hpp"
class GraphStructure;
class Item; class Item;
class ItemManager; class ItemManager;
class Navmesh;
class XMLNode; class XMLNode;
/** /**
@ -53,6 +51,8 @@ private:
/** The matrix that is used to store computed shortest paths */ /** The matrix that is used to store computed shortest paths */
std::vector< std::vector< int > > m_parent_poly; std::vector< std::vector< int > > m_parent_poly;
std::vector< std::vector< int > > m_nearby_quads;
/** Stores the name of the file containing the NavMesh data */ /** Stores the name of the file containing the NavMesh data */
std::string m_navmesh_file; std::string m_navmesh_file;
@ -64,23 +64,19 @@ private:
void buildGraph(NavMesh*); void buildGraph(NavMesh*);
void computeFloydWarshall(); void computeFloydWarshall();
void loadGoalNodes(const XMLNode *node); void loadGoalNodes(const XMLNode *node);
void sortNearbyQuad();
BattleGraph(const std::string &navmesh_file_name, const XMLNode *node=NULL); BattleGraph(const std::string &navmesh_file_name, const XMLNode *node=NULL);
~BattleGraph(void); ~BattleGraph(void);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void set3DVerticesOfGraph(int i, video::S3DVertex *v, virtual void set3DVerticesOfGraph(int i, video::S3DVertex *v,
const video::SColor &color) const const video::SColor &color) const;
{ NavMesh::get()->setVertices(i, v, color); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) const virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) const
{ NavMesh::get()->getBoundingBox(min, max); } { NavMesh::get()->getBoundingBox(min, max); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual const bool isNodeInvisible(int n) const virtual const bool isNodeInvisible(int n) const;
{ return false; }
// ------------------------------------------------------------------------
virtual const bool isNodeInvalid(int n) const
{ return (NavMesh::get()->getNavPoly(n).getVerticesIndex()).size()!=4; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual const bool hasLapLine() const virtual const bool hasLapLine() const
{ return false; } { return false; }
@ -94,15 +90,16 @@ public:
static const int UNKNOWN_POLY; static const int UNKNOWN_POLY;
void findItemsOnGraphNodes(); void findItemsOnGraphNodes();
// ----------------------------------------------------------------------
int pointToNode(const int cur_node, int pointToNode(const int cur_node,
const Vec3& cur_point, const Vec3& cur_point,
bool ignore_vertical) const; bool ignore_vertical) const;
// ------------------------------------------------------------------------
static void unitTesting(); static void unitTesting();
// ------------------------------------------------------------------------
/** Returns the one instance of this object. */ /** Returns the one instance of this object. */
static BattleGraph *get() { return m_battle_graph; } static BattleGraph *get() { return m_battle_graph; }
// ---------------------------------------------------------------------- // ------------------------------------------------------------------------
/** Asserts that no BattleGraph instance exists. Then /** Asserts that no BattleGraph instance exists. Then
* creates a BattleGraph instance. */ * creates a BattleGraph instance. */
static void create(const std::string &navmesh_file_name, static void create(const std::string &navmesh_file_name,
@ -110,9 +107,8 @@ public:
{ {
assert(m_battle_graph==NULL); assert(m_battle_graph==NULL);
m_battle_graph = new BattleGraph(navmesh_file_name, node); m_battle_graph = new BattleGraph(navmesh_file_name, node);
} // create } // create
// ---------------------------------------------------------------------- // ------------------------------------------------------------------------
/** Cleans up the BattleGraph instance if it exists */ /** Cleans up the BattleGraph instance if it exists */
static void destroy() static void destroy()
{ {
@ -122,14 +118,13 @@ public:
m_battle_graph = NULL; m_battle_graph = NULL;
} }
} // destroy } // destroy
// ------------------------------------------------------------------------
// ---------------------------------------------------------------------- /** Returns the number of nodes in the BattleGraph (equal to the number
/** Returns the number of nodes in the BattleGraph (equal to the number of * of quads in the NavMesh
* polygons in the NavMesh */ */
virtual const unsigned int getNumNodes() const virtual const unsigned int getNumNodes() const
{ return m_distance_matrix.size(); } { return NavMesh::get()->getNumberOfQuads(); }
// ------------------------------------------------------------------------
// ----------------------------------------------------------------------
/** Returns the distance between any two nodes */ /** Returns the distance between any two nodes */
float getDistance(int from, int to) const float getDistance(int from, int to) const
{ {
@ -139,26 +134,33 @@ public:
return m_distance_matrix[from][to]; return m_distance_matrix[from][to];
} }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the NavPoly corresponding to the i-th node of the BattleGraph */
const NavPoly& getPolyOfNode(int i) const
{ return NavMesh::get()->getNavPoly(i); }
// ------------------------------------------------------------------------
/** Returns true if the NavPoly lies near the edge. */
bool isNearEdge(int i) const
{ return NavMesh::get()->getNavPoly(i).isPolyNearEdge(); }
// ------------------------------------------------------------------------
/** Returns the next polygon on the shortest path from i to j. /** Returns the next polygon on the shortest path from i to j.
* Note: m_parent_poly[j][i] contains the parent of i on path from j to i, * Note: m_parent_poly[j][i] contains the parent of i on path from j to i,
* which is the next node on the path from i to j (undirected graph) */ * which is the next node on the path from i to j (undirected graph)
const int getNextShortestPathPoly(int i, int j) const; */
int getNextShortestPathPoly(int i, int j) const
{
if (i == BattleGraph::UNKNOWN_POLY || j == BattleGraph::UNKNOWN_POLY)
return BattleGraph::UNKNOWN_POLY;
return m_parent_poly[j][i];
}
// ------------------------------------------------------------------------
std::vector<std::pair<const Item*, int>>& getItemList() std::vector<std::pair<const Item*, int>>& getItemList()
{ return m_items_on_graph; } { return m_items_on_graph; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void insertItems(Item* item, int polygon) void insertItems(Item* item, int polygon)
{ m_items_on_graph.push_back(std::make_pair(item, polygon)); } { m_items_on_graph.push_back(std::make_pair(item, polygon)); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the quad that belongs to a node. */
const Quad& getQuadOfNode(unsigned int n) const
{ return NavMesh::get()->getQuad(n); }
// ------------------------------------------------------------------------
/** Returns true if the quad lies near the edge, which means it doesn't
* have 4 adjacent quads.
*/
bool isNearEdge(unsigned int n) const
{ return NavMesh::get()->getAdjacentQuads(n).size() != 4; }
// ------------------------------------------------------------------------
}; //BattleGraph }; //BattleGraph
#endif #endif

View File

@ -28,6 +28,7 @@
#include "graphics/shaders.hpp" #include "graphics/shaders.hpp"
#include "graphics/rtts.hpp" #include "graphics/rtts.hpp"
#include "modes/world.hpp" #include "modes/world.hpp"
#include "modes/profile_world.hpp"
#include "utils/log.hpp" #include "utils/log.hpp"
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -129,12 +130,6 @@ void GraphStructure::createMesh(bool show_invisible,
// Ignore invisible quads // Ignore invisible quads
if (!show_invisible && isNodeInvisible(count)) if (!show_invisible && isNodeInvisible(count))
continue; continue;
else if (isNodeInvalid(count))
{
// There should not be a node which isn't made of 4 vertices
Log::warn("Graph Structure", "There is an invalid node!");
continue;
}
// Swap the colours from red to blue and back // Swap the colours from red to blue and back
if (!track_color) if (!track_color)
@ -235,6 +230,9 @@ RenderTarget* GraphStructure::makeMiniMap(const core::dimension2du &dimension,
const std::string &name, const std::string &name,
const video::SColor &fill_color) const video::SColor &fill_color)
{ {
// Skip minimap when profiling
if (ProfileWorld::isNoGraphics()) return NULL;
const video::SColor oldClearColor = World::getWorld()->getClearColor(); const video::SColor oldClearColor = World::getWorld()->getClearColor();
World::getWorld()->setClearbackBufferColor(video::SColor(0, 255, 255, 255)); World::getWorld()->setClearbackBufferColor(video::SColor(0, 255, 255, 255));
World::getWorld()->forceFogDisabled(true); World::getWorld()->forceFogDisabled(true);

View File

@ -81,7 +81,6 @@ private:
const video::SColor &color) const = 0; const video::SColor &color) const = 0;
virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) const = 0; virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) const = 0;
virtual const bool isNodeInvisible(int n) const = 0; virtual const bool isNodeInvisible(int n) const = 0;
virtual const bool isNodeInvalid(int n) const = 0;
virtual const bool hasLapLine() const = 0; virtual const bool hasLapLine() const = 0;
virtual const bool differentNodeColor(int n, NodeColor* c) const = 0; virtual const bool differentNodeColor(int n, NodeColor* c) const = 0;

View File

@ -1,87 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "tracks/nav_poly.hpp"
#include "tracks/navmesh.hpp"
#include <algorithm>
#include <iostream>
/** Constructor that takes a vector of points and a vector of adjacent polygons */
NavPoly::NavPoly(const std::vector<int> &polygonVertIndices,
const std::vector<int> &adjacentPolygonIndices)
{
m_vertices = polygonVertIndices;
m_adjacents = adjacentPolygonIndices;
std::vector<Vec3> xyz_points = getVertices();
Vec3 temp(0.0f,0.0f,0.0f);
for(unsigned int i=0; i<xyz_points.size(); i++)
temp = temp + xyz_points[i];
m_center = (temp)*( 1.0f / xyz_points.size());
}
//-----------------------------------------------------------------------------
const std::vector<Vec3> NavPoly::getVertices()
{
std::vector<Vec3> points;
for(unsigned int i=0; i<m_vertices.size(); i++)
points.push_back(NavMesh::get()->getVertex(m_vertices[i]));
return points;
}
//-----------------------------------------------------------------------------
bool NavPoly::pointInPoly(const Vec3& p, bool ignore_vertical) const
{
std::vector<Vec3> points;
for(unsigned int i=0; i<m_vertices.size(); i++)
points.push_back(NavMesh::get()->getVertex(m_vertices[i]));
// The point is on which side of the first edge
float side = p.sideOfLine2D(points[0],points[1]);
// The point is inside the polygon if it is on the same side for all edges
for(unsigned int i=1; i<points.size(); i++)
{
// If it is on different side then product is < 0 , return false
if(p.sideOfLine2D(points[i % points.size()],
points[(i+1)% points.size()]) * side < 0)
return false;
}
if (ignore_vertical) return true;
// Check for vertical distance too
const float dist = p.getY() - m_center.getY();
if (fabsf(dist) > 1.0f)
return false;
return true;
}
//-----------------------------------------------------------------------------
const Vec3& NavPoly::operator[](int i) const
{
return NavMesh::get()->getVertex(m_vertices[i]);
}

View File

@ -1,75 +0,0 @@
//
// SuperTuxKart - a fun racing game with go-kart
// Copyright (C) 2009-2015 Joerg Henrichs
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 3
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#ifndef HEADER_NAV_POLY_HPP
#define HEADER_NAV_POLY_HPP
#include <vector>
#include <string>
#include <SColor.h>
#include "utils/vec3.hpp"
/**
* \ingroup tracks
*/
class NavPoly
{
private:
/** Holds the index of vertices for a polygon **/
std::vector<int> m_vertices;
/** Center of this polygon. **/
Vec3 m_center;
/** Holds the index of adjacent polyogns **/
std::vector<int> m_adjacents;
public:
NavPoly(const std::vector<int> &polygonVertIndices,
const std::vector<int> &adjacentPolygonIndices);
// ------------------------------------------------------------------------
/** Returns the center point of a polygon. */
const Vec3& getCenter() const { return m_center; }
// ------------------------------------------------------------------------
/** Returns the adjacent polygons of a polygon. */
const std::vector<int>& getAdjacents() const { return m_adjacents; }
// ------------------------------------------------------------------------
/** Returns the vertices(Vec3) of this polygon. */
const std::vector<Vec3> getVertices();
// ------------------------------------------------------------------------
/** Returns the indices of the vertices of this polygon */
const std::vector<int> getVerticesIndex() const
{ return m_vertices; }
// ------------------------------------------------------------------------
/** Returns true if a given point lies in this polygon. */
bool pointInPoly(const Vec3& p,
bool ignore_vertical) const;
// ------------------------------------------------------------------------
/** Returns true if this polygon lies near the edge. */
bool isPolyNearEdge() const
{ return m_adjacents.size() < 4; }
// ------------------------------------------------------------------------
const Vec3& operator[](int i) const ;
}; // class NavPoly
#endif

View File

@ -17,16 +17,13 @@
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "tracks/navmesh.hpp" #include "tracks/navmesh.hpp"
#include "tracks/nav_poly.hpp"
#include <algorithm>
#include <S3DVertex.h>
#include <triangle3d.h>
#include "LinearMath/btTransform.h"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "utils/string_utils.hpp" #include "tracks/quad.hpp"
#include "utils/log.hpp"
#include <algorithm>
NavMesh *NavMesh::m_nav_mesh = NULL; NavMesh *NavMesh::m_nav_mesh = NULL;
@ -39,78 +36,68 @@ NavMesh::NavMesh(const std::string &filename)
m_min = Vec3( 99999, 99999, 99999); m_min = Vec3( 99999, 99999, 99999);
m_max = Vec3(-99999, -99999, -99999); m_max = Vec3(-99999, -99999, -99999);
m_n_verts=0;
m_n_polys=0;
XMLNode *xml = file_manager->createXMLTree(filename); XMLNode *xml = file_manager->createXMLTree(filename);
if(xml->getName()!="navmesh") if (xml->getName() != "navmesh")
{ {
Log::error("NavMesh", "NavMesh is invalid. \n"); Log::error("NavMesh", "NavMesh is invalid.");
delete xml; delete xml;
return; return;
} }
// Assigning m_nav_mesh here because constructing NavPoly requires m_nav_mesh to be defined std::vector<Vec3> all_vertices;
m_nav_mesh = this; for (unsigned int i = 0; i < xml->getNumNodes(); i++)
for(unsigned int i=0; i<xml->getNumNodes(); i++)
{ {
const XMLNode *xml_node = xml->getNode(i); const XMLNode *xml_node = xml->getNode(i);
if(xml_node->getName()=="vertices") if (xml_node->getName() == "vertices")
{ {
for(unsigned int i=0; i<xml_node->getNumNodes(); i++) for (unsigned int i = 0; i < xml_node->getNumNodes(); i++)
{ {
const XMLNode *xml_node_node = xml_node->getNode(i); const XMLNode *xml_node_node = xml_node->getNode(i);
if(!(xml_node_node->getName()=="vertex")) if (!(xml_node_node->getName() == "vertex"))
{ {
Log::error("NavMesh", "Unsupported type '%s' found in '%s' - ignored. \n", Log::error("NavMesh", "Unsupported type '%s' found"
xml_node_node->getName().c_str(),filename.c_str()); "in '%s' - ignored.",
xml_node_node->getName().c_str(), filename.c_str());
continue; continue;
} }
//Reading vertices // Reading vertices
Vec3 p; Vec3 p;
readVertex(xml_node_node, &p); readVertex(xml_node_node, &p);
m_max.max(p); m_max.max(p);
m_min.min(p); m_min.min(p);
m_n_verts++; all_vertices.push_back(p);
m_verts.push_back(p); }
} }
} if (xml_node->getName() == "faces")
if(xml_node->getName()=="faces")
{ {
for(unsigned int i=0; i<xml_node->getNumNodes(); i++) for(unsigned int i = 0; i < xml_node->getNumNodes(); i++)
{ {
const XMLNode *xml_node_node = xml_node->getNode(i); const XMLNode *xml_node_node = xml_node->getNode(i);
if(xml_node_node->getName()!="face") if (xml_node_node->getName() != "face")
{ {
Log::error("NavMesh", "Unsupported type '%s' found in '%s' - ignored. \n", Log::error("NavMesh", "Unsupported type '%s' found in '%s'"
xml_node_node->getName().c_str(),filename.c_str()); " - ignored.",
xml_node_node->getName().c_str(), filename.c_str());
continue; continue;
} }
//Reading faces/polys // Reading quads
std::vector<int> polygonVertIndices; std::vector<int> quad_index;
std::vector<int> adjacentPolygonIndices; std::vector<int> adjacent_quad_index;
xml_node_node->get("indices", &polygonVertIndices); xml_node_node->get("indices", &quad_index);
xml_node_node->get("adjacents", &adjacentPolygonIndices); xml_node_node->get("adjacents", &adjacent_quad_index);
NavPoly *np = new NavPoly(polygonVertIndices, adjacentPolygonIndices); assert(quad_index.size() == 4);
m_polys.push_back(*np);
m_n_polys++;
}
m_adjacent_quads.push_back(adjacent_quad_index);
m_quads.push_back(new Quad(
all_vertices[quad_index[0]], all_vertices[quad_index[1]],
all_vertices[quad_index[2]], all_vertices[quad_index[3]]));
} }
if(xml_node->getName()=="MaxVertsPerPoly")
{
xml_node->get("nvp", &m_nvp);
} }
//delete xml_node;
} }
delete xml; delete xml;
} // NavMesh } // NavMesh
@ -119,48 +106,14 @@ NavMesh::NavMesh(const std::string &filename)
NavMesh::~NavMesh() NavMesh::~NavMesh()
{ {
for (unsigned int i = 0; i < m_quads.size(); i++)
{
delete m_quads[i];
}
m_quads.clear();
} // ~NavMesh } // ~NavMesh
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
/** Sets the vertices in a irrlicht vertex array to the 4 points of this quad.
*/
void NavMesh::setVertices(int n, video::S3DVertex *v, const video::SColor &color) const
{
NavPoly poly = NavMesh::get()->getNavPoly(n);
const std::vector<Vec3>& p = poly.getVertices();
if (p.size() !=4) return;
// Eps is used to raise the track debug quads a little bit higher than
// the ground, so that they are actually visible.
core::vector3df eps(0, 0.1f, 0);
v[0].Pos = p[0].toIrrVector()+eps;
v[1].Pos = p[1].toIrrVector()+eps;
v[2].Pos = p[2].toIrrVector()+eps;
v[3].Pos = p[3].toIrrVector()+eps;
core::triangle3df tri(p[0].toIrrVector(), p[1].toIrrVector(),
p[2].toIrrVector());
core::vector3df normal = tri.getNormal();
normal.normalize();
v[0].Normal = normal;
v[1].Normal = normal;
v[2].Normal = normal;
core::triangle3df tri1(p[0].toIrrVector(), p[2].toIrrVector(),
p[3].toIrrVector());
core::vector3df normal1 = tri1.getNormal();
normal1.normalize();
v[3].Normal = normal1;
v[0].Color = color;
v[1].Color = color;
v[2].Color = color;
v[3].Color = color;
} // setVertices
// ----------------------------------------------------------------------------
/** Reads the vertex information from an XMLNode */ /** Reads the vertex information from an XMLNode */
void NavMesh::readVertex(const XMLNode *xml, Vec3* result) const void NavMesh::readVertex(const XMLNode *xml, Vec3* result) const
{ {
@ -171,3 +124,10 @@ void NavMesh::readVertex(const XMLNode *xml, Vec3* result) const
Vec3 temp(x, y, z); Vec3 temp(x, y, z);
*result = temp; *result = temp;
} // readVertex } // readVertex
// ----------------------------------------------------------------------------
const Vec3& NavMesh::getCenterOfQuad(unsigned int n) const
{
assert(m_quads.size() > 0 && n < m_quads.size());
return m_quads[n]->getCenter();
} // getCenterOfQuad

View File

@ -19,36 +19,25 @@
#ifndef HEADER_NAVMESH_HPP #ifndef HEADER_NAVMESH_HPP
#define HEADER_NAVMESH_HPP #define HEADER_NAVMESH_HPP
#include "tracks/nav_poly.hpp"
#include <vector> #include <vector>
#include <string> #include <string>
#include <set>
#include "utils/vec3.hpp" #include "utils/vec3.hpp"
namespace irr class Quad;
{
namespace video { struct S3DVertex; }
}
using namespace irr;
class btTransform;
class XMLNode; class XMLNode;
/** /**
* \ingroup tracks * \brief This class stores a set of navigation quads. It uses a
* * 'simplified singleton' design pattern: it has a static create function
* \brief This class stores a set of navigatoin polygons. It uses a * to create exactly one instance, a destroy function, and a get function
* 'simplified singleton' design pattern: it has a static create function * (that does not have the side effect of the 'normal singleton' design
* to create exactly one instance, a destroy function, and a get function * pattern to create an instance). Besides saving on the if statement in
* (that does not have the side effect of the 'normal singleton' design * get(), this is necessary since certain race modes might not have a
* pattern to create an instance). Besides saving on the if statement in get(), * navigation mesh at all (e.g. race mode). So get() returns NULL in this
* this is necessary since certain race modes might not have a navigaton * case, and this is tested where necessary.
* mesh at all (e.g. race mode). So get() returns NULL in this case, and * \ingroup tracks
* this is tested where necessary. */
\ingroup tracks
*/
class NavMesh class NavMesh
{ {
@ -59,104 +48,74 @@ private:
Vec3 m_min; Vec3 m_min;
Vec3 m_max; Vec3 m_max;
/** The actual set of nav polys that constitute the nav mesh */ /** The actual set of quads that constitute the nav mesh */
std::vector<NavPoly> m_polys; std::vector<Quad*> m_quads;
/** The set of vertices that are part of this nav mesh*/ std::vector<std::vector<int>> m_adjacent_quads;
std::vector< Vec3 > m_verts;
/** Number of vertices */
unsigned int m_n_verts;
/** Number of polygons */
unsigned int m_n_polys;
/** Maximum vertices per polygon */
unsigned int m_nvp;
void readVertex(const XMLNode *xml, Vec3* result) const; void readVertex(const XMLNode *xml, Vec3* result) const;
//void readFace(const XMLNode *xml, Vec3* result) const; // ------------------------------------------------------------------------
NavMesh(const std::string &filename); NavMesh(const std::string &filename);
// ------------------------------------------------------------------------
~NavMesh(); ~NavMesh();
public: public:
/** Creates a NavMesh instance. */ /** Creates a NavMesh instance. */
static void create(const std::string &filename) static void create(const std::string &filename)
{ {
assert(m_nav_mesh==NULL); assert(m_nav_mesh == NULL);
m_nav_mesh = new NavMesh(filename);
// m_nav_mesh assigned in the constructor because it needs to defined
// for NavPoly which is constructed in NavMesh()
new NavMesh(filename);
} }
// ------------------------------------------------------------------------
/** Cleans up the nav mesh. It is possible that this function is called /** Cleans up the nav mesh. It is possible that this function is called
* even if no instance exists (e.g. in race). So it is not an * even if no instance exists (e.g. in race). So it is not an
* error if there is no instance. */ * error if there is no instance.
*/
static void destroy() static void destroy()
{ {
if(m_nav_mesh) if (m_nav_mesh)
{ {
delete m_nav_mesh; delete m_nav_mesh;
m_nav_mesh = NULL; m_nav_mesh = NULL;
} }
} }
// ------------------------------------------------------------------------
/** Returns the one instance of this object. It is possible that there /** Returns the one instance of this object. It is possible that there
* is no instance created (e.g. in normal race, since it doesn't have * is no instance created (e.g. in normal race, since it doesn't have
* a nav mesh), so we don't assert that an instance exist, and we * a nav mesh), so we don't assert that an instance exist, and we
* also don't create one if it doesn't exists. */ * also don't create one if it doesn't exists.
*/
static NavMesh *get() { return m_nav_mesh; } static NavMesh *get() { return m_nav_mesh; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Return the minimum and maximum coordinates of this navmesh. */ /** Return the minimum and maximum coordinates of this navmesh. */
void getBoundingBox(Vec3 *min, Vec3 *max) void getBoundingBox(Vec3 *min, Vec3 *max) { *min=m_min; *max=m_max; }
{ *min=m_min; *max=m_max; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a const reference to a NavPoly */ /** Returns a const reference to a quad */
const NavPoly& getNavPoly(int n) const const Quad& getQuad(unsigned int n) const
{ return m_polys[n]; } {
// ------------------------------------------------------------------------ assert(m_quads.size() > 0 && n < m_quads.size());
/** Returns a const reference to a vertex(Vec3) */ return *(m_quads[n]);
const Vec3& getVertex(int n) const }
{ return m_verts[n]; }
// ------------------------------------------------------------------------
/** Sets the vertices in a irrlicht vertex array to
* the 4 points of a navpoly.
* \param n The number of a navpoly.
* \param v The vertex array in which to set the vertices.
* \param color The color to use for this quad.
*/
void setVertices(int n, video::S3DVertex *v,
const video::SColor &color) const;
// ------------------------------------------------------------------------
/** Returns a const reference to a vector containing all vertices */
const std::vector<Vec3>& getAllVertices() const
{ return m_verts; }
// ------------------------------------------------------------------------
/** Returns the total number of polys */
unsigned int getNumberOfPolys() const
{ return m_n_polys; }
// ------------------------------------------------------------------------
/** Returns the total number of vertices */
unsigned int getNumberOfVerts() const
{ return m_n_verts; }
// ------------------------------------------------------------------------
/** Returns maximum vertices per polygon */
unsigned int getMaxVertsPerPoly() const
{ return m_nvp; }
// ------------------------------------------------------------------------
/** Returns the center of a polygon */
const Vec3& getCenterOfPoly(int n) const
{return m_polys[n].getCenter();}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a const referece to a vector containing the indices /** Returns a const referece to a vector containing the indices
* of polygons adjacent to a given polygon */ * of quads adjacent to a given quad
const std::vector<int>& getAdjacentPolys(int n) const */
{return m_polys[n].getAdjacents();} const std::vector<int>& getAdjacentQuads(unsigned int n) const
{
assert(m_adjacent_quads.size() > 0 && n < m_adjacent_quads.size() &&
m_quads.size() == m_adjacent_quads.size());
return m_adjacent_quads[n];
}
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns a const reference to a vector containing the vertices /** Returns the total number of quads */
* of a given polygon. */ unsigned int getNumberOfQuads() const
const std::vector<Vec3> getVertsOfPoly(int n) {
{return m_polys[n].getVertices();} assert(m_quads.size() > 0);
return m_quads.size();
}
// ------------------------------------------------------------------------
/** Returns the center of a quad */
const Vec3& getCenterOfQuad(unsigned int n) const;
}; };
#endif #endif

View File

@ -88,7 +88,7 @@ void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const
} // setVertices } // setVertices
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
bool Quad::pointInQuad(const Vec3& p) const bool Quad::pointInQuad(const Vec3& p, bool ignore_vertical) const
{ {
// In case that a kart can validly run too high over one driveline // In case that a kart can validly run too high over one driveline
// and it should not be considered to be on that driveline. Example: // and it should not be considered to be on that driveline. Example:
@ -98,17 +98,21 @@ bool Quad::pointInQuad(const Vec3& p) const
// is taken into account, too. to simplify this test we only compare // is taken into account, too. to simplify this test we only compare
// with the minimum height of the quad (and not with the actual // with the minimum height of the quad (and not with the actual
// height of the quad at the point where the kart is). // height of the quad at the point where the kart is).
if(p.getY() - m_max_height > 5.0f || if(!ignore_vertical &&
p.getY() - m_min_height < -1.0f ) (p.getY() - m_max_height > 5.0f ||
p.getY() - m_min_height < -1.0f ))
return false; return false;
// If a point is exactly on the line of two quads (e.g. between points // If a point is exactly on the line of two quads (e.g. between points
// 0,1 on one quad, and 3,2 of the previous quad), assign this point // 0,1 on one quad, and 3,2 of the previous quad), assign this point
// to be on the 'later' quad, i.e. on the line between points 0 and 1. // to be on the 'later' quad, i.e. on the line between points 0 and 1.
if(p.sideOfLine2D(m_p[0], m_p[2])<0) { if(p.sideOfLine2D(m_p[0], m_p[2])<0)
{
return p.sideOfLine2D(m_p[0], m_p[1]) >= 0.0 && return p.sideOfLine2D(m_p[0], m_p[1]) >= 0.0 &&
p.sideOfLine2D(m_p[1], m_p[2]) >= 0.0; p.sideOfLine2D(m_p[1], m_p[2]) >= 0.0;
} else { }
else
{
return p.sideOfLine2D(m_p[2], m_p[3]) > 0.0 && return p.sideOfLine2D(m_p[2], m_p[3]) > 0.0 &&
p.sideOfLine2D(m_p[3], m_p[0]) >= 0.0; p.sideOfLine2D(m_p[3], m_p[0]) >= 0.0;
} }

View File

@ -61,7 +61,7 @@ public:
Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3, Quad(const Vec3 &p0, const Vec3 &p1, const Vec3 &p2, const Vec3 &p3,
bool invis=false, bool ai_ignore=false); bool invis=false, bool ai_ignore=false);
void getVertices(video::S3DVertex *v, const video::SColor &color) const; void getVertices(video::S3DVertex *v, const video::SColor &color) const;
bool pointInQuad(const Vec3& p) const; bool pointInQuad(const Vec3& p, bool ignore_vertical = false) const;
void transform(const btTransform &t, Quad *result) const; void transform(const btTransform &t, Quad *result) const;
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
/** Returns the i-th. point of a quad. */ /** Returns the i-th. point of a quad. */

View File

@ -39,7 +39,6 @@ namespace irr
using namespace irr; using namespace irr;
class CheckLine; class CheckLine;
class GraphStructure;
/** /**
* \brief This class stores a graph of quads. It uses a 'simplified singleton' * \brief This class stores a graph of quads. It uses a 'simplified singleton'
@ -95,9 +94,6 @@ private:
virtual const bool isNodeInvisible(int n) const virtual const bool isNodeInvisible(int n) const
{ return m_all_nodes[n]->getQuad().isInvisible(); } { return m_all_nodes[n]->getQuad().isInvisible(); }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
virtual const bool isNodeInvalid(int n) const
{ return false; }
// ------------------------------------------------------------------------
virtual const bool hasLapLine() const virtual const bool hasLapLine() const
{ return true; } { return true; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -38,8 +38,6 @@
#include "graphics/particle_emitter.hpp" #include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp" #include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp" #include "graphics/particle_kind_manager.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "items/item.hpp" #include "items/item.hpp"
@ -1717,7 +1715,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
} }
} }
loadObjects(root, path, model_def_loader, true, NULL, NULL, NULL); loadObjects(root, path, model_def_loader, true, NULL, NULL);
model_def_loader.cleanLibraryNodesAfterLoad(); model_def_loader.cleanLibraryNodesAfterLoad();
@ -1905,7 +1903,7 @@ void Track::loadTrackModel(bool reverse_track, unsigned int mode_id)
void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader, void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefinitionLoader& model_def_loader,
bool create_lod_definitions, scene::ISceneNode* parent, bool create_lod_definitions, scene::ISceneNode* parent,
TrackObject* parent_library, RenderInfo* ri) TrackObject* parent_library)
{ {
unsigned int start_position_counter = 0; unsigned int start_position_counter = 0;
@ -1919,7 +1917,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
if (name == "track" || name == "default-start") continue; if (name == "track" || name == "default-start") continue;
if (name == "object" || name == "library") if (name == "object" || name == "library")
{ {
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, ri); m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
} }
else if (name == "water") else if (name == "water")
{ {
@ -1963,7 +1961,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
{ {
if (UserConfigParams::m_graphical_effects) if (UserConfigParams::m_graphical_effects)
{ {
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, NULL); m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
} }
} }
else if (name == "sky-dome" || name == "sky-box" || name == "sky-color") else if (name == "sky-dome" || name == "sky-box" || name == "sky-color")
@ -1976,7 +1974,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
} }
else if (name == "light") else if (name == "light")
{ {
m_track_object_manager->add(*node, parent, model_def_loader, parent_library, NULL); m_track_object_manager->add(*node, parent, model_def_loader, parent_library);
} }
else if (name == "weather") else if (name == "weather")
{ {

View File

@ -56,7 +56,6 @@ class MusicInformation;
class ParticleEmitter; class ParticleEmitter;
class ParticleKind; class ParticleKind;
class PhysicalObject; class PhysicalObject;
class RenderInfo;
class TrackObject; class TrackObject;
class TrackObjectManager; class TrackObjectManager;
class TriangleMesh; class TriangleMesh;
@ -451,8 +450,7 @@ public:
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
void loadObjects(const XMLNode* root, const std::string& path, void loadObjects(const XMLNode* root, const std::string& path,
ModelDefinitionLoader& lod_loader, bool create_lod_definitions, ModelDefinitionLoader& lod_loader, bool create_lod_definitions,
scene::ISceneNode* parent, TrackObject* parent_library, scene::ISceneNode* parent, TrackObject* parent_library);
RenderInfo* ri);
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------
bool isSoccer () const { return m_is_soccer; } bool isSoccer () const { return m_is_soccer; }
// ------------------------------------------------------------------------ // ------------------------------------------------------------------------

View File

@ -20,6 +20,8 @@
#include "animations/three_d_animation.hpp" #include "animations/three_d_animation.hpp"
#include "graphics/irr_driver.hpp" #include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp" #include "graphics/render_info.hpp"
#include "io/file_manager.hpp" #include "io/file_manager.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
@ -43,9 +45,9 @@
*/ */
TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent, TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri) TrackObject* parent_library)
{ {
init(xml_node, parent, model_def_loader, parent_library, ri); init(xml_node, parent, model_def_loader, parent_library);
} // TrackObject } // TrackObject
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
@ -68,6 +70,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
m_animator = NULL; m_animator = NULL;
m_physical_object = NULL; m_physical_object = NULL;
m_parent_library = NULL; m_parent_library = NULL;
m_render_info = NULL;
m_interaction = interaction; m_interaction = interaction;
m_presentation = presentation; m_presentation = presentation;
m_is_driveable = false; m_is_driveable = false;
@ -94,11 +97,12 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
*/ */
void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent, void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri) TrackObject* parent_library)
{ {
m_init_xyz = core::vector3df(0,0,0); m_init_xyz = core::vector3df(0,0,0);
m_init_hpr = core::vector3df(0,0,0); m_init_hpr = core::vector3df(0,0,0);
m_init_scale = core::vector3df(1,1,1); m_init_scale = core::vector3df(1,1,1);
m_render_info = NULL;
m_enabled = true; m_enabled = true;
m_initially_visible = false; m_initially_visible = false;
m_presentation = NULL; m_presentation = NULL;
@ -178,13 +182,39 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
} }
else else
{ {
// Colorization settings
std::string model_name;
xml_node.get("model", &model_name);
bool colorizable = false;
scene::IMesh* mesh = NULL;
if (model_name.size() > 0)
{
mesh = irr_driver->getMesh(model_name);
assert(mesh != NULL);
unsigned int n = mesh->getMeshBufferCount();
for (unsigned int i = 0; i < n; i++)
{
scene::IMeshBuffer *mb = mesh->getMeshBuffer(i);
Material* m = material_manager->getMaterialFor(mb
->getMaterial().getTexture(0), mb);
colorizable = colorizable || m->isColorizable();
}
}
// If at least one material is colorizable, add RenderInfo for it
if (colorizable)
{
m_render_info = new RenderInfo();
m_render_info->setDynamicHue(mesh);
}
scene::ISceneNode *glownode = NULL; scene::ISceneNode *glownode = NULL;
bool is_movable = false; bool is_movable = false;
if (lod_instance) if (lod_instance)
{ {
m_type = "lod"; m_type = "lod";
TrackObjectPresentationLOD* lod_node = TrackObjectPresentationLOD* lod_node =
new TrackObjectPresentationLOD(xml_node, parent, model_def_loader, ri); new TrackObjectPresentationLOD(xml_node, parent, model_def_loader, m_render_info);
m_presentation = lod_node; m_presentation = lod_node;
LODNode* node = (LODNode*)lod_node->getNode(); LODNode* node = (LODNode*)lod_node->getNode();
@ -209,7 +239,7 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
m_presentation = new TrackObjectPresentationMesh(xml_node, m_presentation = new TrackObjectPresentationMesh(xml_node,
m_enabled, m_enabled,
parent, parent,
ri); m_render_info);
scene::ISceneNode* node = ((TrackObjectPresentationMesh *)m_presentation)->getNode(); scene::ISceneNode* node = ((TrackObjectPresentationMesh *)m_presentation)->getNode();
if (type == "movable" && parent != NULL) if (type == "movable" && parent != NULL)
{ {
@ -356,6 +386,7 @@ TrackObject::~TrackObject()
delete m_presentation; delete m_presentation;
delete m_animator; delete m_animator;
delete m_physical_object; delete m_physical_object;
delete m_render_info;
} // ~TrackObject } // ~TrackObject
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------

View File

@ -31,10 +31,10 @@
#include <string> #include <string>
#include "animations/three_d_animation.hpp" #include "animations/three_d_animation.hpp"
class XMLNode;
class ThreeDAnimation;
class ModelDefinitionLoader; class ModelDefinitionLoader;
class RenderInfo; class RenderInfo;
class ThreeDAnimation;
class XMLNode;
/** /**
* \ingroup tracks * \ingroup tracks
@ -60,8 +60,9 @@ private:
std::string m_id; std::string m_id;
protected: RenderInfo* m_render_info;
protected:
/** The initial XYZ position of the object. */ /** The initial XYZ position of the object. */
core::vector3df m_init_xyz; core::vector3df m_init_xyz;
@ -99,14 +100,13 @@ protected:
void init(const XMLNode &xml_node, scene::ISceneNode* parent, void init(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri); TrackObject* parent_library);
public: public:
TrackObject(const XMLNode &xml_node, TrackObject(const XMLNode &xml_node,
scene::ISceneNode* parent, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, TrackObject* parent_library);
RenderInfo* ri);
TrackObject(const core::vector3df& xyz, TrackObject(const core::vector3df& xyz,
const core::vector3df& hpr, const core::vector3df& hpr,

View File

@ -22,7 +22,6 @@
#include "animations/three_d_animation.hpp" #include "animations/three_d_animation.hpp"
#include "graphics/lod_node.hpp" #include "graphics/lod_node.hpp"
#include "graphics/material_manager.hpp" #include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp"
#include "io/xml_node.hpp" #include "io/xml_node.hpp"
#include "physics/physical_object.hpp" #include "physics/physical_object.hpp"
#include "tracks/track_object.hpp" #include "tracks/track_object.hpp"
@ -46,11 +45,11 @@ TrackObjectManager::~TrackObjectManager()
*/ */
void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent, void TrackObjectManager::add(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri) TrackObject* parent_library)
{ {
try try
{ {
TrackObject *obj = new TrackObject(xml_node, parent, model_def_loader, parent_library, ri); TrackObject *obj = new TrackObject(xml_node, parent, model_def_loader, parent_library);
m_all_objects.push_back(obj); m_all_objects.push_back(obj);
if(obj->isDriveable()) if(obj->isDriveable())
m_driveable_objects.push_back(obj); m_driveable_objects.push_back(obj);

View File

@ -23,11 +23,10 @@
#include "tracks/track_object.hpp" #include "tracks/track_object.hpp"
#include "utils/ptr_vector.hpp" #include "utils/ptr_vector.hpp"
class LODNode;
class RenderInfo;
class Track; class Track;
class Vec3; class Vec3;
class XMLNode; class XMLNode;
class LODNode;
#include <map> #include <map>
#include <vector> #include <vector>
@ -59,7 +58,7 @@ public:
void init(); void init();
void add(const XMLNode &xml_node, scene::ISceneNode* parent, void add(const XMLNode &xml_node, scene::ISceneNode* parent,
ModelDefinitionLoader& model_def_loader, ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri); TrackObject* parent_library);
void update(float dt); void update(float dt);
void handleExplosion(const Vec3 &pos, const PhysicalObject *mp, void handleExplosion(const Vec3 &pos, const PhysicalObject *mp,
bool secondary_hits=true); bool secondary_hits=true);

View File

@ -177,13 +177,8 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
ModelDefinitionLoader& model_def_loader) ModelDefinitionLoader& model_def_loader)
: TrackObjectPresentationSceneNode(xml_node) : TrackObjectPresentationSceneNode(xml_node)
{ {
m_render_info = NULL;
std::string name; std::string name;
xml_node.get("name", &name); xml_node.get("name", &name);
float custom_hue = 0.0f;
xml_node.get("hue", &custom_hue);
if (custom_hue > 0.0f)
m_render_info = new RenderInfo(custom_hue, false);
m_node = irr_driver->getSceneManager()->addEmptySceneNode(); m_node = irr_driver->getSceneManager()->addEmptySceneNode();
#ifdef DEBUG #ifdef DEBUG
@ -273,7 +268,7 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
assert(libroot != NULL); assert(libroot != NULL);
World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader, World::getWorld()->getTrack()->loadObjects(libroot, lib_path, model_def_loader,
create_lod_definitions, m_node, parent, m_render_info); create_lod_definitions, m_node, parent);
m_parent = parent; m_parent = parent;
} // TrackObjectPresentationLibraryNode } // TrackObjectPresentationLibraryNode
@ -281,8 +276,6 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode() TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode()
{ {
irr_driver->removeNode(m_node); irr_driver->removeNode(m_node);
delete m_render_info;
m_render_info = NULL;
} // TrackObjectPresentationLibraryNode } // TrackObjectPresentationLibraryNode
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void TrackObjectPresentationLibraryNode::move(const core::vector3df& xyz, const core::vector3df& hpr, void TrackObjectPresentationLibraryNode::move(const core::vector3df& xyz, const core::vector3df& hpr,

View File

@ -185,7 +185,6 @@ public:
class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode class TrackObjectPresentationLibraryNode : public TrackObjectPresentationSceneNode
{ {
TrackObject* m_parent; TrackObject* m_parent;
RenderInfo* m_render_info;
public: public:
TrackObjectPresentationLibraryNode(TrackObject* parent, TrackObjectPresentationLibraryNode(TrackObject* parent,
const XMLNode& xml_node, const XMLNode& xml_node,

Some files were not shown because too many files have changed in this diff Show More