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()
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_LIBBFD "Use libbfd for crash reporting and leak check" OFF)
endif()
@ -215,15 +214,10 @@ if(UNIX AND NOT APPLE)
find_package(X11 REQUIRED)
include_directories(${X11_INCLUDE_DIR})
if(USE_XRANDR)
find_package(Xrandr REQUIRED)
if(NOT XRANDR_FOUND)
message(FATAL_ERROR "XRANDR not found.")
endif()
else()
find_library(IRRLICHT_XF86VM_LIBRARY Xxf86vm)
mark_as_advanced(IRRLICHT_XF86VM_LIBRARY)
endif()
if(USE_LIBBFD)
find_package(Libbfd)
@ -382,12 +376,7 @@ else()
endif()
if(UNIX AND NOT APPLE)
target_link_libraries(supertuxkart ${X11_LIBRARIES})
if(USE_XRANDR)
target_link_libraries(supertuxkart ${XRANDR_LIBRARIES})
else()
target_link_libraries(supertuxkart ${IRRLICHT_XF86VM_LIBRARY})
endif()
target_link_libraries(supertuxkart ${X11_LIBRARIES} ${XRANDR_LIBRARIES})
if(USE_LIBBFD)
target_link_libraries(supertuxkart ${LIBBFD_LIBRARIES})
endif()

Binary file not shown.

View File

@ -1,15 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<stkgui>
<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" />
<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" />
</div>

View File

@ -30,7 +30,7 @@
<label width="100%"
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" />
<spacer width="5" height="20"/>

View File

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

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
<!-- Copyright 2014 Richard Hughes <richard@hughsie.com> -->
<application>
<id type="desktop">supertuxkart.desktop</id>
<component type="desktop">
<id>supertuxkart.desktop</id>
<metadata_license>CC0-1.0</metadata_license>
<project_license>GPL-3.0+</project_license>
<name>SuperTuxKart</name>
<summary>A racing game</summary>
<description>
@ -25,11 +25,25 @@
against the computer or your friends, and more!
</p>
</description>
<url type="homepage">http://supertuxkart.net/</url>
<screenshots>
<screenshot type="default">http://supertuxkart.sourceforge.net/persistent/images/4/4e/Supertuxkart-0.9-screenshot-2.jpg</screenshot>
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/a/a9/Supertuxkart-0.9-screenshot-1.jpg</screenshot>
<screenshot>http://supertuxkart.sourceforge.net/persistent/images/6/63/Supertuxkart-0.9-screenshot-3.jpg</screenshot>
<screenshot type="default">
<image>https://supertuxkart.net/images/8/83/Supertuxkart-0.9.2-screenshot-3.jpg</image>
<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>
<updatecontact>supertuxkart-devel@lists.sourceforge.net</updatecontact>
</application>
<developer_name>SuperTuxKart Team</developer_name>
<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()
# Xrandr
if(UNIX AND USE_XRANDR)
if(UNIX AND NOT APPLE)
add_definitions(-DNO_IRR_LINUX_X11_VIDMODE_)
add_definitions(-D_IRR_LINUX_X11_RANDR_)
endif()

View File

@ -381,7 +381,7 @@ void CGUIButton::setImage(video::ITexture* image)
Image = 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)
setPressedImage(Image);
@ -407,7 +407,7 @@ void CGUIButton::setPressedImage(video::ITexture* image)
PressedImage = 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
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 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords(
@ -1443,10 +1443,10 @@ namespace video
// now draw it.
core::rect<f32> tcoords;
tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getOriginalSize().Width ;
tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getOriginalSize().Height;
tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getOriginalSize().Width);
tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getOriginalSize().Height);
tcoords.UpperLeftCorner.X = (((f32)sourcePos.X)) / texture->getSize().Width ;
tcoords.UpperLeftCorner.Y = (((f32)sourcePos.Y)) / texture->getSize().Height;
tcoords.LowerRightCorner.X = tcoords.UpperLeftCorner.X + ((f32)(sourceSize.Width) / texture->getSize().Width);
tcoords.LowerRightCorner.Y = tcoords.UpperLeftCorner.Y + ((f32)(sourceSize.Height) / texture->getSize().Height);
const core::rect<s32> poss(targetPos, sourceSize);
@ -1496,7 +1496,7 @@ namespace video
// texcoords need to be flipped horizontally for RTTs
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 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords(
@ -1573,7 +1573,7 @@ namespace video
clipRect->getWidth(), clipRect->getHeight());
}
const core::dimension2du& ss = texture->getOriginalSize();
const core::dimension2du& ss = texture->getSize();
core::position2d<s32> targetPos(pos);
// texcoords need to be flipped horizontally for RTTs
const bool isRTT = texture->isRenderTarget();

View File

@ -15,6 +15,8 @@
#include "os.h"
#include "CImage.h"
#include "CColorConverter.h"
#include "IAttributes.h"
#include "IrrlichtDevice.h"
#include "irrString.h"
@ -171,6 +173,17 @@ void COGLES2Texture::getImageValues(IImage* image)
ImageSize.Width = (u32)(Driver->MaxTextureSize*ratio);
}
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());
}

View File

@ -2006,7 +2006,7 @@ void COpenGLDriver::draw2DImageBatch(const video::ITexture* texture,
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 invH = 1.f / static_cast<f32>(ss.Height);
const core::dimension2d<u32>& renderTargetSize = getCurrentRenderTargetSize();
@ -2225,7 +2225,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
// ok, we've clipped everything.
// 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 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords(
@ -2268,7 +2268,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture, const core::rect
if (!texture)
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 invH = 1.f / static_cast<f32>(ss.Height);
const core::rect<f32> tcoords(
@ -2361,7 +2361,7 @@ void COpenGLDriver::draw2DImage(const video::ITexture* texture,
clipRect->getWidth(),clipRect->getHeight());
}
const core::dimension2d<u32>& ss = texture->getOriginalSize();
const core::dimension2d<u32>& ss = texture->getSize();
core::position2d<s32> targetPos(pos);
const f32 invW = 1.f / static_cast<f32>(ss.Width);
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");
}
}
} // ChallengeData
// ----------------------------------------------------------------------------
const irr::core::stringw ChallengeData::getChallengeDescription() const
{
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
description += _("Laps : %i", m_num_laps);
description += _("Laps: %i", m_num_laps);
description += core::stringw(L"\n");
}
else if (track_node)
else
{
// Follow the leader mode:
description = _("Follow the leader");
}
m_challenge_description = description;
} // ChallengeData
}
return description;
} // getChallengeDescription
// ----------------------------------------------------------------------------
void ChallengeData::error(const char *id) const

View File

@ -110,8 +110,6 @@ private:
/** Number of trophies required to access this challenge */
int m_num_trophies;
irr::core::stringw m_challenge_description;
public:
ChallengeData(const std::string& filename);
@ -195,10 +193,7 @@ public:
// ------------------------------------------------------------------------
/** Returns the description of this challenge.
*/
const irr::core::stringw& getChallengeDescription() const
{
return m_challenge_description;
} // getChallengeDescription
const irr::core::stringw getChallengeDescription() const;
// ------------------------------------------------------------------------
/** 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
// Copyright (C) 2006-2015 SuperTuxKart-Team
// Modelled after Supertux's configfile.cpp
// Copyright (C) 2006-2016 SuperTuxKart-Team
// Modeled after Supertux's configfile.cpp
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
@ -683,8 +683,8 @@ bool UserConfig::loadConfig()
XMLNode* root = file_manager->createXMLTree(filename);
if(!root || root->getName() != "stkconfig")
{
Log::error("UserConfig",
"Could not read user config file '%s'.", filename.c_str());
Log::info("UserConfig",
"Could not read user config file '%s'. A new file will be created.", filename.c_str());
if(root) delete root;
// 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

View File

@ -491,6 +491,14 @@ namespace UserConfigParams
PARAM_PREFIX BoolUserConfigParam m_old_driver_popup
PARAM_DEFAULT(BoolUserConfigParam(true, "old_driver_popup",
&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
/** If gamepad debugging is enabled. */

View File

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

View File

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

View File

@ -23,6 +23,8 @@
#include "font/digit_face.hpp"
#include "font/face_ttf.hpp"
#include "font/regular_face.hpp"
#include "utils/string_utils.hpp"
#include "utils/translation.hpp"
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());
}
} // 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 unitTesting();
// ------------------------------------------------------------------------
FT_Library getFTLibrary() const { return m_ft_library; }
}; // FontManager

View File

@ -116,6 +116,13 @@ void FontWithFace::createNewGlyphPage()
m_used_width = 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()
->addTexture("Glyph_page", m_page);
m_spritebank->addTexture(NULL);
@ -127,6 +134,9 @@ void FontWithFace::createNewGlyphPage()
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // createNewGlyphPage
// ----------------------------------------------------------------------------
@ -172,13 +182,22 @@ void FontWithFace::insertGlyph(wchar_t c, const GlyphInfo& gi)
{
// Current glyph page is full:
// 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()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
page_texture);
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
// Clear and add a new one
createNewGlyphPage();
}
@ -283,6 +302,11 @@ void FontWithFace::updateCharactersList()
m_new_char_holder.clear();
// 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()
->addTexture("Glyph_page", m_page);
m_spritebank->setTexture(m_spritebank->getTextureCount() - 1,
@ -291,6 +315,9 @@ void FontWithFace::updateCharactersList()
irr_driver->getVideoDriver()->removeTexture(page_texture);
assert(page_texture->getReferenceCount() == 1);
irr_driver->getVideoDriver()->getNonConstDriverAttributes()
.setAttribute("MAX_TEXTURE_SIZE", old_max_size);
} // updateCharactersList
// ----------------------------------------------------------------------------

View File

@ -109,14 +109,12 @@ private:
FontWithFace* m_fallback_font;
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;
gui::IGUISpriteBank* m_spritebank;
/** A full glyph page for this font.
*/
/** A full glyph page for this font. */
video::IImage* m_page;
unsigned int m_temp_height;

View File

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

View File

@ -73,7 +73,8 @@ Camera* Camera::createCamera(unsigned int index, CameraType type,
Camera *camera = NULL;
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_FPS: camera = new CameraFPS (index, kart); break;
case CM_TYPE_END: camera = new CameraEnd (index, kart); break;
@ -112,10 +113,11 @@ void Camera::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_type = CameraType::CM_TYPE_NORMAL;
m_type = type;
m_index = camera_index;
m_original_kart = kart;
m_camera = irr_driver->addCameraSceneNode();

View File

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

View File

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

View File

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

View File

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

View File

@ -28,8 +28,17 @@
#include "tracks/track.hpp"
// ============================================================================
CameraNormal::CameraNormal(int camera_index, AbstractKart* kart)
: Camera(camera_index, kart)
/** Constructor for the normal camera. This is the only camera constructor
* 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_ambient_light = World::getWorld()->getTrack()->getDefaultAmbientColor();

View File

@ -61,7 +61,8 @@ private:
friend class Camera;
friend class CameraDebug;
friend class CameraEnd;
CameraNormal(int camera_index, AbstractKart* kart);
CameraNormal(Camera::CameraType type, int camera_index,
AbstractKart* kart);
virtual ~CameraNormal() {}
public:
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);
}
// ----------------------------------------------------------------------------
#if defined(__linux__) && !defined(ANDROID)
@ -646,7 +645,9 @@ void IrrDriver::setMaxTextureSize()
if( (UserConfigParams::m_high_definition_textures & 0x01) == 0)
{
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

View File

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

View File

@ -21,6 +21,7 @@
#define HEADER_MATERIAL_HPP
#include "utils/no_copy.hpp"
#include "utils/random_generator.hpp"
#include <assert.h>
#include <map>
@ -181,6 +182,12 @@ private:
/** Minimum resulting saturation when colorized (from 0 to 1) */
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
* the intended effect. */
//enum {ADJ_NONE, ADJ_PREMUL, ADJ_DIV}
@ -291,7 +298,7 @@ public:
* is driving on it. */
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; }
// ------------------------------------------------------------------------
@ -299,6 +306,17 @@ public:
*/
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
* crashes against it. */
CollisionReaction getCollisionReaction() const { return m_collision_reaction; }

View File

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

View File

@ -26,6 +26,19 @@
// ----------------------------------------------------------------------------
RenderInfo::RenderInfo(float hue, bool transparent)
{
m_hue = hue;
m_static_hue = hue;
m_transparent = transparent;
} // 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
#include "utils/leak_check.hpp"
#include "utils/no_copy.hpp"
#include <assert.h>
#include <vector>
namespace irr
{
namespace scene { class IMesh; }
}
/**
* \ingroup graphics
*/
class RenderInfo
enum KartRenderType: unsigned int
{
public:
enum KartRenderType
{
KRT_DEFAULT,
KRT_RED,
KRT_BLUE,
KRT_TRANSPARENT,
};
};
/**
* \ingroup graphics
*/
class RenderInfo : public NoCopy
{
private:
float m_hue;
float m_static_hue;
bool m_transparent;
std::vector<float> m_dynamic_hue;
public:
LEAK_CHECK();
// ------------------------------------------------------------------------
@ -52,23 +57,34 @@ public:
// ------------------------------------------------------------------------
~RenderInfo() {}
// ------------------------------------------------------------------------
void setHue(float hue) { m_hue = hue; }
void setHue(float hue) { m_static_hue = hue; }
// ------------------------------------------------------------------------
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; }
// ------------------------------------------------------------------------
void setKartModelRenderInfo(KartRenderType krt)
{
setHue(krt == RenderInfo::KRT_BLUE ? 0.66f :
krt == RenderInfo::KRT_RED ? 1.0f : 0.0f);
setTransparent(krt == RenderInfo::KRT_TRANSPARENT ? true : false);
setHue(krt == KRT_BLUE ? 0.66f : krt == KRT_RED ? 1.0f : 0.0f);
setTransparent(krt == 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

View File

@ -59,12 +59,14 @@ RTT::RTT(size_t width, size_t height)
using namespace video;
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 quarter = res/4;
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 shadowsize1(shadowside / 2, shadowside / 2);
const dimension2du shadowsize2(shadowside / 4, shadowside / 4);
@ -118,7 +120,6 @@ RTT::RTT(size_t width, size_t height)
std::vector<GLuint> somevector;
somevector.push_back(RenderTargetTextures[RTT_SSAO]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
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]);
FrameBuffers.push_back(new FrameBuffer(somevector, res.Width, res.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF1]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF1_R]);
FrameBuffers.push_back(new FrameBuffer(somevector, half.Width, half.Height));
somevector.clear();
somevector.push_back(RenderTargetTextures[RTT_HALF2]);
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]);
FrameBuffers.push_back(new FrameBuffer(somevector, DepthStencilTexture, res.Width, res.Height));
somevector.clear();
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.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.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.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.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.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.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.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.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.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.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())
{

View File

@ -231,8 +231,11 @@ void ShaderBasedRenderer::uploadLightingData() const
void ShaderBasedRenderer::computeMatrixesAndCameras(scene::ICameraSceneNode *const camnode,
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
// ----------------------------------------------------------------------------
@ -628,6 +631,7 @@ void ShaderBasedRenderer::renderPostProcessing(Camera * const camera)
glEnable(GL_FRAMEBUFFER_SRGB);
glBindFramebuffer(GL_FRAMEBUFFER, 0);
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);
glDisable(GL_FRAMEBUFFER_SRGB);
}

View File

@ -100,22 +100,44 @@ void STKAnimatedMesh::updateNoGL()
if (!isMaterialInitialized)
{
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);
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
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
}
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || m_all_parts_colorized || (m_mesh_render_info
&& m_mesh_render_info->isTransparent()) ? m_mesh_render_info : NULL));
affected || m_all_parts_colorized || (cur_ri
&& cur_ri->isTransparent()) ? cur_ri : NULL));
}
for (u32 i = 0; i < m->getMeshBufferCount(); ++i)

View File

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

View File

@ -77,22 +77,44 @@ void STKMeshSceneNode::setReloadEachFrame(bool val)
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);
bool affected = false;
RenderInfo* cur_ri = 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
->getMaterial().getTexture(0), mb);
if (m->isColorizable())
affected = true;
}
}
assert(cur_ri ? cur_ri->isStatic() : true);
GLmeshes.push_back(allocateMeshBuffer(mb, m_debug_name,
affected || all_parts_colorized || (render_info &&
render_info->isTransparent()) ? render_info : NULL));
affected || all_parts_colorized || (cur_ri &&
cur_ri->isTransparent()) ? cur_ri : NULL));
}
isMaterialInitialized = false;
isGLInitialized = false;

View File

@ -28,6 +28,7 @@ class RenderInfo;
class STKMeshSceneNode : public irr::scene::CMeshSceneNode, public STKMeshCommon
{
protected:
PtrVector<RenderInfo> m_static_render_info;
std::vector<GLMesh> GLmeshes;
core::matrix4 ModelViewProjectionMatrix;
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)
{
if (!w->isActivated()) return EVENT_BLOCK;
if (w->onActivationInput(playerID) == EVENT_BLOCK)
return EVENT_BLOCK;
Widget* parent = w->m_event_handler;

View File

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

View File

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

View File

@ -23,12 +23,13 @@
#include <IMesh.h>
#include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "utils/aligned_array.hpp"
#include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp"
class RenderInfo;
namespace GUIEngine
{
/** \brief A model view widget.
@ -64,7 +65,7 @@ namespace GUIEngine
scene::ISceneNode *m_light;
RenderInfo m_render_info;
RenderInfo *m_render_info;
public:
@ -103,7 +104,7 @@ namespace GUIEngine
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();
} // 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,
const std::string& originator,

View File

@ -24,6 +24,7 @@
#include "guiengine/widget.hpp"
#include "guiengine/widgets/icon_button_widget.hpp"
#include "utils/cpp2011.hpp"
#include "utils/leak_check.hpp"
#include "utils/ptr_vector.hpp"
@ -192,6 +193,8 @@ namespace GUIEngine
void removeChildNamed(const char* name);
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)
{
// Center of the screen
core::vector2df screen_size = irr_driver->getCurrentScreenSize();
int mid_x = (int) screen_size.X / 2;
int mid_y = (int) screen_size.Y / 2;
core::dimension2du screen_size = irr_driver->getActualScreenSize();
int mid_x = (int) screen_size.Width / 2;
int mid_y = (int) screen_size.Height / 2;
// Relative mouse movement
int diff_x = event.MouseInput.X - m_mouse_val_x;
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),
new btSphereShape(0.5f*m_extend.getY()),
1.0f /*restitution*/,
0.8f /*restitution*/,
-70.0f /*gravity*/,
true /*rotates*/);
// 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_SMALL ? Item::ITEM_NITRO_SMALL : Item::ITEM_BANANA);
Vec3 loc = BattleGraph::get()
->getPolyOfNode(used_location[i]).getCenter();
->getQuadOfNode(used_location[i]).getCenter();
Item* item = newItem(type, loc, Vec3(0, 1, 0));
BattleGraph::get()->insertItems(item, used_location[i]);
}

View File

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

View File

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

View File

@ -20,6 +20,7 @@
#include "graphics/slip_stream.hpp"
#include "karts/abstract_kart.hpp"
#include "karts/kart_model.hpp"
#include "karts/skidding.hpp"
#include "modes/world.hpp"
#include "physics/physics.hpp"
@ -55,6 +56,12 @@ AbstractKartAnimation::AbstractKartAnimation(AbstractKart *kart,
// A time of 0 reset the squashing
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
// ----------------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@ -52,6 +52,8 @@ class SlipStream;
class Stars;
class TerrainInfo;
enum KartRenderType: unsigned int;
/** 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
* 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,
int position, const btTransform& init_transform,
PerPlayerDifficulty difficulty,
RenderInfo::KartRenderType krt = RenderInfo::KRT_DEFAULT);
KartRenderType krt);
virtual ~Kart();
virtual void init(RaceManager::KartType type);
virtual void kartIsInRestNow();

View File

@ -30,6 +30,7 @@
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/mesh_tools.hpp"
#include "graphics/render_info.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
#include "karts/abstract_kart.hpp"
@ -116,6 +117,7 @@ KartModel::KartModel(bool is_master)
m_hat_name = "";
m_hat_node = NULL;
m_hat_offset = core::vector3df(0,0,0);
m_render_info = NULL;
for(unsigned int i=0; i<4; i++)
{
@ -141,7 +143,7 @@ KartModel::KartModel(bool is_master)
m_animation_speed = 25;
m_current_animation = AF_DEFAULT;
m_play_non_loop = false;
m_krt = RenderInfo::KRT_DEFAULT;
m_krt = KRT_DEFAULT;
m_support_colorization = false;
} // KartModel
@ -246,7 +248,7 @@ KartModel::~KartModel()
assert(!m_is_master);
// 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();
}
@ -275,6 +277,8 @@ KartModel::~KartModel()
}
}
}
delete m_render_info;
#ifdef DEBUG
#if SKELETON_DEBUG
irr_driver->clearDebugMeshes();
@ -289,12 +293,13 @@ KartModel::~KartModel()
* It is also marked not to be a master copy, so attachModel can be called
* 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
// that there is indeed no animated node defined here ...
// just in case.
assert(m_is_master);
assert(m_render_info == NULL);
assert(!m_animated_node);
KartModel *km = new KartModel(/*is master*/ false);
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_krt = krt;
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[1] = m_nitro_emitter_position[1];
@ -335,7 +342,7 @@ KartModel* KartModel::makeCopy(RenderInfo::KartRenderType krt)
// Master should not have any speed weighted nodes.
assert(!m_speed_weighted_objects[i].m_node);
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
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);
scene::ISceneNode* node = NULL;
m_render_info.setKartModelRenderInfo(m_krt);
if (animated_models)
{
@ -982,6 +988,20 @@ void KartModel::update(float dt, float distance, float steer, float speed,
m_animated_node->setCurrentFrame(frame);
} // 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()
{
@ -1017,3 +1037,10 @@ void KartModel::attachHat()
} // if bone
} // if(m_hat_name)
} // 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;
#include "graphics/render_info.hpp"
#include "utils/no_copy.hpp"
#include "utils/vec3.hpp"
class AbstractKart;
class KartProperties;
class RenderInfo;
class XMLNode;
enum KartRenderType: unsigned int;
/** A speed-weighted object is an object whose characteristics are influenced by the kart's speed */
struct SpeedWeightedObject
{
@ -231,16 +233,16 @@ private:
/** Pointer to the kart object belonging to this kart model. */
AbstractKart* m_kart;
RenderInfo::KartRenderType m_krt;
KartRenderType m_krt;
RenderInfo m_render_info;
RenderInfo* m_render_info;
bool m_support_colorization;
public:
KartModel(bool is_master);
~KartModel();
KartModel* makeCopy(RenderInfo::KartRenderType krt);
KartModel* makeCopy(KartRenderType krt);
void reset();
void loadInfo(const XMLNode &node);
bool loadModels(const KartProperties &kart_properties);
@ -249,6 +251,7 @@ public:
float current_lean_angle,
int gt_replay_index = -1);
void finishedRace();
void resetVisualWheelPosition();
scene::ISceneNode*
attachModel(bool animatedModels, bool always_animated);
// ------------------------------------------------------------------------
@ -337,17 +340,7 @@ public:
// ------------------------------------------------------------------------
core::vector3df getHatOffset() { return m_hat_offset; }
// ------------------------------------------------------------------------
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;
}
RenderInfo* getRenderInfo();
// ------------------------------------------------------------------------
bool supportColorization() const { return m_support_colorization; }

View File

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

View File

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

View File

@ -1887,6 +1887,9 @@ void runUnitTests()
Log::info("UnitTest", "Battle Graph");
BattleGraph::unitTesting();
Log::info("UnitTest", "Fonts for translation");
font_manager->unitTesting();
Log::info("UnitTest", "=====================");
Log::info("UnitTest", "Testing successful ");
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);
AbstractKart *new_kart = new Kart(kart_ident, index, position, init_pos,
difficulty, team == SOCCER_TEAM_BLUE ?
RenderInfo::KRT_BLUE : RenderInfo::KRT_RED);
difficulty, team == SOCCER_TEAM_BLUE ? KRT_BLUE : KRT_RED);
new_kart->init(race_manager->getKartType(index));
Controller *controller = NULL;

View File

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

View File

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

View File

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

View File

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

View File

@ -277,7 +277,7 @@ void ArenasScreen::buildTrackList()
}
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 );
}
}
@ -329,7 +329,7 @@ void ArenasScreen::buildTrackList()
}
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 );
}
}

View File

@ -17,10 +17,8 @@
#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/ribbon_widget.hpp"
#include "modes/world.hpp"
#include "states_screens/state_manager.hpp"
#include "utils/translation.hpp"
@ -111,28 +109,29 @@ void MessageDialog::loadedFromFile()
{
LabelWidget* message = getWidget<LabelWidget>("title");
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
// change "Cancel" to "OK"
if (m_type == MessageDialog::MESSAGE_DIALOG_OK)
{
ButtonWidget* yesbtn = getWidget<ButtonWidget>("confirm");
IconButtonWidget* yesbtn = getWidget<IconButtonWidget>("cancel");
yesbtn->setVisible(false);
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("cancel");
IconButtonWidget* cancelbtn = getWidget<IconButtonWidget>("confirm");
cancelbtn->setText(_("OK"));
cancelbtn->setFocusForPlayer(PLAYER_ID_GAME_MASTER);
}
else if (m_type == MessageDialog::MESSAGE_DIALOG_YESNO)
{
ButtonWidget* cancelbtn = getWidget<ButtonWidget>("cancel");
IconButtonWidget* cancelbtn = getWidget<IconButtonWidget>("cancel");
cancelbtn->setText(_("No"));
}
else if (m_type == MessageDialog::MESSAGE_DIALOG_OK_CANCEL)
{
// 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"));
}
}
@ -147,8 +146,9 @@ void MessageDialog::onEnterPressedInternal()
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)
{
@ -161,7 +161,7 @@ GUIEngine::EventPropagation MessageDialog::processEvent(const std::string& event
return GUIEngine::EVENT_BLOCK;
}
else if (eventSource == "confirm")
else if (ribbon->getSelectionIDString(PLAYER_ID_GAME_MASTER) == "confirm")
{
if (m_listener == NULL)
{

View File

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

View File

@ -23,6 +23,7 @@
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.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]);
if (kart != NULL)
{
KartModel* kart_model = kart->getKartModelCopy();
KartModel* kart_model = kart->getKartModelCopy(KRT_DEFAULT);
m_all_kart_models.push_back(kart_model);
scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false);

View File

@ -23,6 +23,7 @@
#include "challenges/unlock_manager.hpp"
#include "config/player_manager.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/engine.hpp"
#include "guiengine/scalable_font.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]);
if (kp == NULL) continue;
KartModel* kart_model = kp->getKartModelCopy();
KartModel* kart_model = kp->getKartModelCopy(KRT_DEFAULT);
m_all_kart_models.push_back(kart_model);
scene::ISceneNode* kart_main_node = kart_model->attachModel(false, false);

View File

@ -21,6 +21,7 @@
#include "audio/sfx_manager.hpp"
#include "audio/sfx_base.hpp"
#include "config/hardware_stats.hpp"
#include "config/player_manager.hpp"
#include "config/user_config.hpp"
#include "font/bold_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_label->setVisible(false);
PlayerProfile* profile = PlayerManager::getCurrentPlayer();
if (profile != NULL && profile->isLoggedIn())
profile->requestSignOut();
}
}
else if (name=="enable-hw-report")
{

View File

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

View File

@ -108,6 +108,7 @@ RaceGUIOverworld::RaceGUIOverworld()
m_string_lap = _("Lap");
m_string_rank = _("Rank");
m_active_challenge = NULL;
// Determine maximum length of the rank/lap text, in order to
// align those texts properly on the right side of the viewport.
@ -512,7 +513,13 @@ void RaceGUIOverworld::drawGlobalMiniMap()
pos.UpperLeftCorner.Y += GUIEngine::getTitleFontHeight();
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),
false, false /* vcenter */, NULL);

View File

@ -101,6 +101,11 @@ private:
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. */
const OverworldChallenge *m_current_challenge;

View File

@ -1420,7 +1420,7 @@ void RaceResultGUI::backToLobby()
if (race_manager->modeHasLaps())
{
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),
white_color, false, false, nullptr, true);
}
@ -1428,7 +1428,7 @@ void RaceResultGUI::backToLobby()
const core::stringw& difficulty_name =
race_manager->getDifficultyName(race_manager->getDifficulty());
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),
white_color, false, false, nullptr, true);
// show fastest lap
@ -1437,7 +1437,7 @@ void RaceResultGUI::backToLobby()
float best_lap_time = static_cast<LinearWorld*>(World::getWorld())->getFastestLap();
core::stringw best_lap_string = _("Best lap time: %s",
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,
core::recti(x, current_y, 0, 0), white_color, false, false,
nullptr, true);

View File

@ -116,7 +116,7 @@ void RaceSetupScreen::init()
irr::core::stringw name5 = irr::core::stringw(
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));
#define ENABLE_EASTER_EGG_MODE

View File

@ -19,6 +19,7 @@
#include "audio/sfx_manager.hpp"
#include "config/user_config.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/widgets/bubble_widget.hpp"
#include "guiengine/widgets/button_widget.hpp"
#include "guiengine/widgets/spinner_widget.hpp"
@ -149,9 +150,8 @@ void SoccerSetupScreen::beforeAddingWidget()
info.support_colorization = kart_model.supportColorization();
if (info.support_colorization)
{
kart_view->getModelViewRenderInfo().setKartModelRenderInfo
(info.team == SOCCER_TEAM_BLUE ?
RenderInfo::KRT_BLUE : RenderInfo::KRT_RED);
kart_view->getModelViewRenderInfo()->setKartModelRenderInfo
(info.team == SOCCER_TEAM_BLUE ? KRT_BLUE : KRT_RED);
}
// 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)
{
m_kart_view_info[playerId].view->getModelViewRenderInfo()
.setKartModelRenderInfo(RenderInfo::KRT_RED);
->setKartModelRenderInfo(KRT_RED);
}
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)
{
m_kart_view_info[playerId].view->getModelViewRenderInfo()
.setKartModelRenderInfo(RenderInfo::KRT_BLUE);
->setKartModelRenderInfo(KRT_BLUE);
}
for(int i=0 ; i < nb_players ; i++)

View File

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

View File

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

View File

@ -28,10 +28,12 @@
#include "items/item_manager.hpp"
#include "race/race_manager.hpp"
#include "tracks/navmesh.hpp"
#include "tracks/quad.hpp"
#include "tracks/track.hpp"
#include "tracks/track_manager.hpp"
#include "utils/log.hpp"
#include <algorithm>
#include <queue>
const int BattleGraph::UNKNOWN_POLY = -1;
@ -50,9 +52,10 @@ BattleGraph::BattleGraph(const std::string &navmesh_file_name,
buildGraph(NavMesh::get());
// 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);
sortNearbyQuad();
if (node && race_manager->getMinorMode() == RaceManager::MINOR_MODE_SOCCER)
loadGoalNodes(node);
@ -73,35 +76,32 @@ BattleGraph::~BattleGraph(void)
* adjacency matrix. */
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> >
(n_polys, std::vector<float>(n_polys, 9999.9f));
for(unsigned int i=0; i<n_polys; i++)
m_distance_matrix = std::vector<std::vector<float>>
(n_quads, std::vector<float>(n_quads, 9999.9f));
for(unsigned int i = 0; i < n_quads; i++)
{
NavPoly currentPoly = navmesh->getNavPoly(i);
const std::vector<int> &adjacents = navmesh->getAdjacentPolys(i);
for(unsigned int j=0; j<adjacents.size(); j++)
const Quad& cur_quad = navmesh->getQuad(i);
for (const int& adjacent : navmesh->getAdjacentQuads(i))
{
Vec3 diff = navmesh->getCenterOfPoly(adjacents[j])
- currentPoly.getCenter();
Vec3 diff = navmesh->getQuad(adjacent).getCenter()
- cur_quad.getCenter();
float distance = diff.length();
m_distance_matrix[i][adjacents[j]] = distance;
//m_distance_matrix[adjacents[j]][i] = distance;
m_distance_matrix[i][adjacent] = distance;
}
m_distance_matrix[i][i] = 0.0f;
}
// Allocate and initialise the previous node data structure:
unsigned int n = getNumNodes();
m_parent_poly = std::vector< std::vector<int> >
(n, std::vector<int>(n, BattleGraph::UNKNOWN_POLY));
for(unsigned int i=0; i<n; i++)
m_parent_poly = std::vector<std::vector<int>>
(n_quads, std::vector<int>(n_quads, BattleGraph::UNKNOWN_POLY));
for (unsigned int i = 0; i < n_quads; 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)
m_parent_poly[i][j]=-1;
if(i == j || m_distance_matrix[i][j] >= 9899.9f)
m_parent_poly[i][j] = -1;
else
m_parent_poly[i][j] = i;
} // for j
@ -145,11 +145,9 @@ void BattleGraph::computeDijkstra(int source)
int cur_index = current.first;
if(visited[cur_index]) continue;
visited[cur_index] = true;
const NavPoly &current_poly = navmesh->getNavPoly(cur_index);
const std::vector<int> &adjacents = current_poly.getAdjacents();
for(unsigned int j=0; j<adjacents.size(); j++)
for (const int& adjacent : navmesh->getAdjacentQuads(cur_index))
{
int adjacent = adjacents[j];
// Distance already computed, can be ignored
if(visited[adjacent]) continue;
@ -224,7 +222,7 @@ void BattleGraph::findItemsOnGraphNodes()
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;
}
@ -243,70 +241,50 @@ int BattleGraph::pointToNode(const int cur_node,
const Vec3& cur_point,
bool ignore_vertical) const
{
int final_node = BattleGraph::UNKNOWN_POLY;
if (cur_node == BattleGraph::UNKNOWN_POLY)
{
// Try all nodes in the battle graph
bool found = false;
unsigned int node = 0;
while (!found && node < this->getNumNodes())
for (unsigned int node = 0; node < this->getNumNodes(); node++)
{
const NavPoly& p_all = this->getPolyOfNode(node);
if (p_all.pointInPoly(cur_point, ignore_vertical))
const Quad& quad = this->getQuadOfNode(node);
if (quad.pointInQuad(cur_point, ignore_vertical))
{
final_node = node;
found = true;
return node;
}
node++;
}
}
else
{
// Check if the point is still on the same node
const NavPoly& p_cur = this->getPolyOfNode(cur_node);
if (p_cur.pointInPoly(cur_point, ignore_vertical)) return cur_node;
const Quad& cur_quad = this->getQuadOfNode(cur_node);
if (cur_quad.pointInQuad(cur_point, ignore_vertical)) return cur_node;
// If not then check all adjacent polys
const std::vector<int>& adjacents = NavMesh::get()
->getAdjacentPolys(cur_node);
bool found = false;
unsigned int num = 0;
while (!found && num < adjacents.size())
// If not then check all nearby quads (8 quads)
// Skip the same node
assert(cur_node == m_nearby_quads[cur_node][0]);
for (unsigned int i = 1; i < m_nearby_quads[0].size(); i++)
{
const NavPoly& p_temp = this->getPolyOfNode(adjacents[num]);
if (p_temp.pointInPoly(cur_point, ignore_vertical))
const int test_node = m_nearby_quads[cur_node][i];
const Quad& quad = this->getQuadOfNode(test_node);
if (quad.pointInQuad(cur_point, ignore_vertical))
{
final_node = adjacents[num];
found = true;
return test_node;
}
num++;
}
// Current node is still unkown
if (final_node == BattleGraph::UNKNOWN_POLY)
{
// Current node is still unkown:
// Calculated distance from saved node to current position,
// if it's close enough than use the saved node anyway, it
// may happen when the kart stays on the edge of obstacles
const NavPoly& p = this->getPolyOfNode(cur_node);
const float dist = (p.getCenter() - cur_point).length_2d();
Vec3 diff = (cur_quad.getCenter() - cur_point);
float dist = diff.length();
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 m_parent_poly[j][i];
} // getNextShortestPathPoly
} // pointToNode
// -----------------------------------------------------------------------------
const bool BattleGraph::differentNodeColor(int n, NodeColor* c) const
@ -456,3 +434,39 @@ std::vector<int> BattleGraph::getPathFromTo(int from, int to,
}
return path;
} // 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/navmesh.hpp"
class GraphStructure;
class Item;
class ItemManager;
class Navmesh;
class XMLNode;
/**
@ -53,6 +51,8 @@ private:
/** The matrix that is used to store computed shortest paths */
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 */
std::string m_navmesh_file;
@ -64,23 +64,19 @@ private:
void buildGraph(NavMesh*);
void computeFloydWarshall();
void loadGoalNodes(const XMLNode *node);
void sortNearbyQuad();
BattleGraph(const std::string &navmesh_file_name, const XMLNode *node=NULL);
~BattleGraph(void);
// ------------------------------------------------------------------------
virtual void set3DVerticesOfGraph(int i, video::S3DVertex *v,
const video::SColor &color) const
{ NavMesh::get()->setVertices(i, v, color); }
const video::SColor &color) const;
// ------------------------------------------------------------------------
virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) const
{ NavMesh::get()->getBoundingBox(min, max); }
// ------------------------------------------------------------------------
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 isNodeInvisible(int n) const;
// ------------------------------------------------------------------------
virtual const bool hasLapLine() const
{ return false; }
@ -94,15 +90,16 @@ public:
static const int UNKNOWN_POLY;
void findItemsOnGraphNodes();
// ----------------------------------------------------------------------
int pointToNode(const int cur_node,
const Vec3& cur_point,
bool ignore_vertical) const;
// ------------------------------------------------------------------------
static void unitTesting();
// ------------------------------------------------------------------------
/** Returns the one instance of this object. */
static BattleGraph *get() { return m_battle_graph; }
// ----------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Asserts that no BattleGraph instance exists. Then
* creates a BattleGraph instance. */
static void create(const std::string &navmesh_file_name,
@ -110,9 +107,8 @@ public:
{
assert(m_battle_graph==NULL);
m_battle_graph = new BattleGraph(navmesh_file_name, node);
} // create
// ----------------------------------------------------------------------
// ------------------------------------------------------------------------
/** Cleans up the BattleGraph instance if it exists */
static void destroy()
{
@ -122,14 +118,13 @@ public:
m_battle_graph = NULL;
}
} // destroy
// ----------------------------------------------------------------------
/** Returns the number of nodes in the BattleGraph (equal to the number of
* polygons in the NavMesh */
// ------------------------------------------------------------------------
/** Returns the number of nodes in the BattleGraph (equal to the number
* of quads in the NavMesh
*/
virtual const unsigned int getNumNodes() const
{ return m_distance_matrix.size(); }
// ----------------------------------------------------------------------
{ return NavMesh::get()->getNumberOfQuads(); }
// ------------------------------------------------------------------------
/** Returns the distance between any two nodes */
float getDistance(int from, int to) const
{
@ -139,26 +134,33 @@ public:
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.
* 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) */
const int getNextShortestPathPoly(int i, int j) const;
* which is the next node on the path from i to j (undirected graph)
*/
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()
{ return m_items_on_graph; }
// ------------------------------------------------------------------------
void insertItems(Item* item, int 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
#endif

View File

@ -28,6 +28,7 @@
#include "graphics/shaders.hpp"
#include "graphics/rtts.hpp"
#include "modes/world.hpp"
#include "modes/profile_world.hpp"
#include "utils/log.hpp"
// -----------------------------------------------------------------------------
@ -129,12 +130,6 @@ void GraphStructure::createMesh(bool show_invisible,
// Ignore invisible quads
if (!show_invisible && isNodeInvisible(count))
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
if (!track_color)
@ -235,6 +230,9 @@ RenderTarget* GraphStructure::makeMiniMap(const core::dimension2du &dimension,
const std::string &name,
const video::SColor &fill_color)
{
// Skip minimap when profiling
if (ProfileWorld::isNoGraphics()) return NULL;
const video::SColor oldClearColor = World::getWorld()->getClearColor();
World::getWorld()->setClearbackBufferColor(video::SColor(0, 255, 255, 255));
World::getWorld()->forceFogDisabled(true);

View File

@ -81,7 +81,6 @@ private:
const video::SColor &color) const = 0;
virtual void getGraphBoundingBox(Vec3 *min, Vec3 *max) 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 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.
#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/xml_node.hpp"
#include "utils/string_utils.hpp"
#include "tracks/quad.hpp"
#include "utils/log.hpp"
#include <algorithm>
NavMesh *NavMesh::m_nav_mesh = NULL;
@ -39,78 +36,68 @@ NavMesh::NavMesh(const std::string &filename)
m_min = Vec3( 99999, 99999, 99999);
m_max = Vec3(-99999, -99999, -99999);
m_n_verts=0;
m_n_polys=0;
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;
return;
}
// Assigning m_nav_mesh here because constructing NavPoly requires m_nav_mesh to be defined
m_nav_mesh = this;
for(unsigned int i=0; i<xml->getNumNodes(); i++)
std::vector<Vec3> all_vertices;
for (unsigned int i = 0; i < xml->getNumNodes(); 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);
if(!(xml_node_node->getName()=="vertex"))
if (!(xml_node_node->getName() == "vertex"))
{
Log::error("NavMesh", "Unsupported type '%s' found in '%s' - ignored. \n",
xml_node_node->getName().c_str(),filename.c_str());
Log::error("NavMesh", "Unsupported type '%s' found"
"in '%s' - ignored.",
xml_node_node->getName().c_str(), filename.c_str());
continue;
}
//Reading vertices
// Reading vertices
Vec3 p;
readVertex(xml_node_node, &p);
m_max.max(p);
m_min.min(p);
m_n_verts++;
m_verts.push_back(p);
all_vertices.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);
if(xml_node_node->getName()!="face")
if (xml_node_node->getName() != "face")
{
Log::error("NavMesh", "Unsupported type '%s' found in '%s' - ignored. \n",
xml_node_node->getName().c_str(),filename.c_str());
Log::error("NavMesh", "Unsupported type '%s' found in '%s'"
" - ignored.",
xml_node_node->getName().c_str(), filename.c_str());
continue;
}
//Reading faces/polys
std::vector<int> polygonVertIndices;
std::vector<int> adjacentPolygonIndices;
xml_node_node->get("indices", &polygonVertIndices);
xml_node_node->get("adjacents", &adjacentPolygonIndices);
NavPoly *np = new NavPoly(polygonVertIndices, adjacentPolygonIndices);
m_polys.push_back(*np);
m_n_polys++;
}
// Reading quads
std::vector<int> quad_index;
std::vector<int> adjacent_quad_index;
xml_node_node->get("indices", &quad_index);
xml_node_node->get("adjacents", &adjacent_quad_index);
assert(quad_index.size() == 4);
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;
} // NavMesh
@ -119,48 +106,14 @@ NavMesh::NavMesh(const std::string &filename)
NavMesh::~NavMesh()
{
for (unsigned int i = 0; i < m_quads.size(); i++)
{
delete m_quads[i];
}
m_quads.clear();
} // ~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 */
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);
*result = temp;
} // 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
#define HEADER_NAVMESH_HPP
#include "tracks/nav_poly.hpp"
#include <vector>
#include <string>
#include <set>
#include "utils/vec3.hpp"
namespace irr
{
namespace video { struct S3DVertex; }
}
using namespace irr;
class btTransform;
class Quad;
class XMLNode;
/**
* \ingroup tracks
*
* \brief This class stores a set of navigatoin polygons. It uses a
* 'simplified singleton' design pattern: it has a static create function
* to create exactly one instance, a destroy function, and a get function
* (that does not have the side effect of the 'normal singleton' design
* pattern to create an instance). Besides saving on the if statement in get(),
* this is necessary since certain race modes might not have a navigaton
* mesh at all (e.g. race mode). So get() returns NULL in this case, and
* this is tested where necessary.
\ingroup tracks
*/
* \brief This class stores a set of navigation quads. It uses a
* 'simplified singleton' design pattern: it has a static create function
* to create exactly one instance, a destroy function, and a get function
* (that does not have the side effect of the 'normal singleton' design
* pattern to create an instance). Besides saving on the if statement in
* get(), this is necessary since certain race modes might not have a
* navigation mesh at all (e.g. race mode). So get() returns NULL in this
* case, and this is tested where necessary.
* \ingroup tracks
*/
class NavMesh
{
@ -59,104 +48,74 @@ private:
Vec3 m_min;
Vec3 m_max;
/** The actual set of nav polys that constitute the nav mesh */
std::vector<NavPoly> m_polys;
/** The actual set of quads that constitute the nav mesh */
std::vector<Quad*> m_quads;
/** The set of vertices that are part of this nav mesh*/
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;
std::vector<std::vector<int>> m_adjacent_quads;
void readVertex(const XMLNode *xml, Vec3* result) const;
//void readFace(const XMLNode *xml, Vec3* result) const;
// ------------------------------------------------------------------------
NavMesh(const std::string &filename);
// ------------------------------------------------------------------------
~NavMesh();
public:
/** Creates a NavMesh instance. */
static void create(const std::string &filename)
{
assert(m_nav_mesh==NULL);
// m_nav_mesh assigned in the constructor because it needs to defined
// for NavPoly which is constructed in NavMesh()
new NavMesh(filename);
assert(m_nav_mesh == NULL);
m_nav_mesh = new NavMesh(filename);
}
// ------------------------------------------------------------------------
/** 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
* error if there is no instance. */
* error if there is no instance.
*/
static void destroy()
{
if(m_nav_mesh)
if (m_nav_mesh)
{
delete m_nav_mesh;
m_nav_mesh = NULL;
}
}
// ------------------------------------------------------------------------
/** 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
* 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; }
// ------------------------------------------------------------------------
/** Return the minimum and maximum coordinates of this navmesh. */
void getBoundingBox(Vec3 *min, Vec3 *max)
{ *min=m_min; *max=m_max; }
void getBoundingBox(Vec3 *min, Vec3 *max) { *min=m_min; *max=m_max; }
// ------------------------------------------------------------------------
/** Returns a const reference to a NavPoly */
const NavPoly& getNavPoly(int n) const
{ return m_polys[n]; }
// ------------------------------------------------------------------------
/** Returns a const reference to a vertex(Vec3) */
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 reference to a quad */
const Quad& getQuad(unsigned int n) const
{
assert(m_quads.size() > 0 && n < m_quads.size());
return *(m_quads[n]);
}
// ------------------------------------------------------------------------
/** Returns a const referece to a vector containing the indices
* of polygons adjacent to a given polygon */
const std::vector<int>& getAdjacentPolys(int n) const
{return m_polys[n].getAdjacents();}
* of quads adjacent to a given quad
*/
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
* of a given polygon. */
const std::vector<Vec3> getVertsOfPoly(int n)
{return m_polys[n].getVertices();}
/** Returns the total number of quads */
unsigned int getNumberOfQuads() const
{
assert(m_quads.size() > 0);
return m_quads.size();
}
// ------------------------------------------------------------------------
/** Returns the center of a quad */
const Vec3& getCenterOfQuad(unsigned int n) const;
};
#endif

View File

@ -88,7 +88,7 @@ void Quad::getVertices(video::S3DVertex *v, const video::SColor &color) const
} // 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
// 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
// with the minimum height of the quad (and not with the actual
// height of the quad at the point where the kart is).
if(p.getY() - m_max_height > 5.0f ||
p.getY() - m_min_height < -1.0f )
if(!ignore_vertical &&
(p.getY() - m_max_height > 5.0f ||
p.getY() - m_min_height < -1.0f ))
return false;
// 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
// 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 &&
p.sideOfLine2D(m_p[1], m_p[2]) >= 0.0;
} else {
}
else
{
return p.sideOfLine2D(m_p[2], m_p[3]) > 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,
bool invis=false, bool ai_ignore=false);
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;
// ------------------------------------------------------------------------
/** Returns the i-th. point of a quad. */

View File

@ -39,7 +39,6 @@ namespace irr
using namespace irr;
class CheckLine;
class GraphStructure;
/**
* \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
{ return m_all_nodes[n]->getQuad().isInvisible(); }
// ------------------------------------------------------------------------
virtual const bool isNodeInvalid(int n) const
{ return false; }
// ------------------------------------------------------------------------
virtual const bool hasLapLine() const
{ return true; }
// ------------------------------------------------------------------------

View File

@ -38,8 +38,6 @@
#include "graphics/particle_emitter.hpp"
#include "graphics/particle_kind.hpp"
#include "graphics/particle_kind_manager.hpp"
#include "graphics/render_info.hpp"
#include "guiengine/scalable_font.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.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();
@ -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,
bool create_lod_definitions, scene::ISceneNode* parent,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
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 == "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")
{
@ -1963,7 +1961,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
{
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")
@ -1976,7 +1974,7 @@ void Track::loadObjects(const XMLNode* root, const std::string& path, ModelDefin
}
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")
{

View File

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

View File

@ -20,6 +20,8 @@
#include "animations/three_d_animation.hpp"
#include "graphics/irr_driver.hpp"
#include "graphics/material.hpp"
#include "graphics/material_manager.hpp"
#include "graphics/render_info.hpp"
#include "io/file_manager.hpp"
#include "io/xml_node.hpp"
@ -43,9 +45,9 @@
*/
TrackObject::TrackObject(const XMLNode &xml_node, scene::ISceneNode* parent,
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
// ----------------------------------------------------------------------------
@ -68,6 +70,7 @@ TrackObject::TrackObject(const core::vector3df& xyz, const core::vector3df& hpr,
m_animator = NULL;
m_physical_object = NULL;
m_parent_library = NULL;
m_render_info = NULL;
m_interaction = interaction;
m_presentation = presentation;
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,
ModelDefinitionLoader& model_def_loader,
TrackObject* parent_library, RenderInfo* ri)
TrackObject* parent_library)
{
m_init_xyz = core::vector3df(0,0,0);
m_init_hpr = core::vector3df(0,0,0);
m_init_scale = core::vector3df(1,1,1);
m_render_info = NULL;
m_enabled = true;
m_initially_visible = false;
m_presentation = NULL;
@ -178,13 +182,39 @@ void TrackObject::init(const XMLNode &xml_node, scene::ISceneNode* parent,
}
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;
bool is_movable = false;
if (lod_instance)
{
m_type = "lod";
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;
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_enabled,
parent,
ri);
m_render_info);
scene::ISceneNode* node = ((TrackObjectPresentationMesh *)m_presentation)->getNode();
if (type == "movable" && parent != NULL)
{
@ -356,6 +386,7 @@ TrackObject::~TrackObject()
delete m_presentation;
delete m_animator;
delete m_physical_object;
delete m_render_info;
} // ~TrackObject
// ----------------------------------------------------------------------------

View File

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

View File

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

View File

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

View File

@ -177,13 +177,8 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
ModelDefinitionLoader& model_def_loader)
: TrackObjectPresentationSceneNode(xml_node)
{
m_render_info = NULL;
std::string 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();
#ifdef DEBUG
@ -273,7 +268,7 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
assert(libroot != NULL);
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;
} // TrackObjectPresentationLibraryNode
@ -281,8 +276,6 @@ TrackObjectPresentationLibraryNode::TrackObjectPresentationLibraryNode(
TrackObjectPresentationLibraryNode::~TrackObjectPresentationLibraryNode()
{
irr_driver->removeNode(m_node);
delete m_render_info;
m_render_info = NULL;
} // TrackObjectPresentationLibraryNode
// ----------------------------------------------------------------------------
void TrackObjectPresentationLibraryNode::move(const core::vector3df& xyz, const core::vector3df& hpr,

View File

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

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