Irrlicht only: improved XML handling, support xml files
for .track and .loc files, started working on items. git-svn-id: svn+ssh://svn.code.sf.net/p/supertuxkart/code/trunk/supertuxkart@3179 178a84e3-b1eb-0310-8ba1-8eac791a3b58
This commit is contained in:
parent
220353b940
commit
1cbed5cfe2
@ -47,7 +47,7 @@ public:
|
||||
scene::ISceneNode *addAnimatedMesh(scene::IAnimatedMesh *mesh);
|
||||
scene::ICameraSceneNode
|
||||
*addCamera();
|
||||
void update(float dt);
|
||||
void update(float dt);
|
||||
}; // IrrDriver
|
||||
|
||||
extern IrrDriver *irr_driver;
|
||||
|
@ -76,29 +76,32 @@ HelpPageOne::HelpPageOne()
|
||||
widget_manager->breakLine();
|
||||
|
||||
/*Rotating 3D models*/
|
||||
ssgEntity* hm = item_manager->getItemModel(ITEM_BONUS_BOX);
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
ssgEntity* hm = item_manager->getItemModel(Item::ITEM_BONUS_BOX);
|
||||
ssgDeRefDelete(m_box);
|
||||
m_box = new ssgTransform;
|
||||
m_box->ref();
|
||||
m_box->addKid(hm);
|
||||
|
||||
hm = item_manager->getItemModel(ITEM_SILVER_COIN);
|
||||
hm = item_manager->getItemModel(Item::ITEM_SILVER_COIN);
|
||||
ssgDeRefDelete(m_silver_coin);
|
||||
|
||||
m_silver_coin = new ssgTransform;
|
||||
m_silver_coin->ref();
|
||||
m_silver_coin->addKid(hm);
|
||||
|
||||
hm = item_manager->getItemModel(ITEM_GOLD_COIN);
|
||||
hm = item_manager->getItemModel(Item::ITEM_GOLD_COIN);
|
||||
ssgDeRefDelete(m_gold_coin);
|
||||
m_gold_coin = new ssgTransform;
|
||||
m_gold_coin->ref();
|
||||
m_gold_coin->addKid(hm);
|
||||
|
||||
hm = item_manager->getItemModel(ITEM_BANANA);
|
||||
hm = item_manager->getItemModel(Item::ITEM_BANANA);
|
||||
ssgDeRefDelete(m_banana);
|
||||
m_banana = new ssgTransform;
|
||||
m_banana->ref();
|
||||
m_banana->addKid(hm);
|
||||
#endif
|
||||
|
||||
/*Empty widget to cover the space for the 3D models*/
|
||||
widget_manager->addEmptyWgt( WidgetManager::WGT_NONE, 100, 15);
|
||||
|
@ -21,8 +21,9 @@
|
||||
#include "utils/string_utils.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
XMLNode::XMLNode(io::IXMLReader *xml)
|
||||
XMLNode::XMLNode(const std::string &name, io::IXMLReader *xml)
|
||||
{
|
||||
m_name = name;
|
||||
for(unsigned int i=0; i<xml->getAttributeCount(); i++)
|
||||
{
|
||||
std::string name = core::stringc(xml->getAttributeName(i)).c_str();
|
||||
@ -33,105 +34,119 @@ XMLNode::XMLNode(io::IXMLReader *xml)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
/** If 'attribute' was defined, set 'value' to the value of the
|
||||
* attribute and return true, otherwise return false and do not
|
||||
* change value.
|
||||
* attribute and return 1, otherwise return 0 and do not change value.
|
||||
* \param attribute Name of the attribute.
|
||||
* \param value Value of the attribute.
|
||||
*/
|
||||
bool XMLNode::get(const std::string &attribute, std::string *value)
|
||||
int XMLNode::get(const std::string &attribute, std::string *value) const
|
||||
{
|
||||
std::map<std::string, core::stringw>::iterator o;
|
||||
if(m_attributes.size()==0) return 0;
|
||||
std::map<std::string, core::stringw>::const_iterator o;
|
||||
o = m_attributes.find(attribute);
|
||||
if(o==m_attributes.end()) return false;
|
||||
if(o==m_attributes.end()) return 0;
|
||||
*value=core::stringc(o->second).c_str();
|
||||
return true;
|
||||
return 1;
|
||||
} // get
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, core::vector3df *value)
|
||||
int XMLNode::get(const std::string &attribute, core::vector3df *value) const
|
||||
{
|
||||
std::string s = "";
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
if(v.size()!=3) return false;
|
||||
if(v.size()!=3) return 0;
|
||||
value->X = (float)atof(v[0].c_str());
|
||||
value->Y = (float)atof(v[1].c_str());
|
||||
value->Z = (float)atof(v[2].c_str());
|
||||
return true;
|
||||
return 1;
|
||||
} // get(vector3df)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, Vec3 *value)
|
||||
int XMLNode::get(const std::string &attribute, Vec3 *value) const
|
||||
{
|
||||
std::string s = "";
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
if(v.size()!=3) return false;
|
||||
if(v.size()!=3) return 0;
|
||||
value->setX((float)atof(v[0].c_str()));
|
||||
value->setY((float)atof(v[1].c_str()));
|
||||
value->setZ((float)atof(v[2].c_str()));
|
||||
return true;
|
||||
return 1;
|
||||
} // get(Vec3)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, video::SColorf *color)
|
||||
int XMLNode::get(const std::string &attribute, video::SColorf *color) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
if(v.size()!=4) return false;
|
||||
if(v.size()!=4) return 0;
|
||||
color->set((float)atof(v[0].c_str()),
|
||||
(float)atof(v[1].c_str()),
|
||||
(float)atof(v[2].c_str()),
|
||||
(float)atof(v[3].c_str()));
|
||||
return true;
|
||||
return 1;
|
||||
} // get(SColor)
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, int *value)
|
||||
int XMLNode::get(const std::string &attribute, int *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
*value = atoi(s.c_str());
|
||||
return true;
|
||||
return 1;
|
||||
} // get(int)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, float *value)
|
||||
int XMLNode::get(const std::string &attribute, float *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
*value = (float)atof(s.c_str());
|
||||
return true;
|
||||
return 1;
|
||||
} // get(int)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, bool *value)
|
||||
int XMLNode::get(const std::string &attribute, bool *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
*value = s=="" || s[0]=='T' || s[0]=='t' ||
|
||||
s=="true" || s=="TRUE" || s=="#t" || s=="#T";
|
||||
return true;
|
||||
return 1;
|
||||
} // get(bool)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, std::vector<std::string> *value)
|
||||
/** If 'attribute' was defined, split the value of the attribute by spaces,
|
||||
* set value to this vector array and return the number of elements. Otherwise
|
||||
* return 0 and do not change value.
|
||||
* \param attribute Name of the attribute.
|
||||
* \param value Value of the attribute.
|
||||
*/
|
||||
int XMLNode::get(const std::string &attribute,
|
||||
std::vector<std::string> *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
*value = StringUtils::split(s,' ');
|
||||
return true;
|
||||
return value->size();
|
||||
} // get(vector<string>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, std::vector<float> *value)
|
||||
/** If 'attribute' was defined, split the value of the attribute by spaces,
|
||||
* set value to this vector array and return the number of elements. Otherwise
|
||||
* return 0 and do not change value.
|
||||
* \param attribute Name of the attribute.
|
||||
* \param value Value of the attribute.
|
||||
*/
|
||||
int XMLNode::get(const std::string &attribute,
|
||||
std::vector<float> *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
value->clear();
|
||||
@ -139,14 +154,20 @@ bool XMLNode::get(const std::string &attribute, std::vector<float> *value)
|
||||
{
|
||||
value->push_back((float)atof(v[i].c_str()));
|
||||
}
|
||||
return true;
|
||||
return value->size();
|
||||
} // get(vector<float>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
bool XMLNode::get(const std::string &attribute, std::vector<int> *value)
|
||||
/** If 'attribute' was defined, split the value of the attribute by spaces,
|
||||
* set value to this vector array and return the number of elements. Otherwise
|
||||
* return 0 and do not change value.
|
||||
* \param attribute Name of the attribute.
|
||||
* \param value Value of the attribute.
|
||||
*/
|
||||
int XMLNode::get(const std::string &attribute, std::vector<int> *value) const
|
||||
{
|
||||
std::string s;
|
||||
if(!get(attribute, &s)) return false;
|
||||
if(!get(attribute, &s)) return 0;
|
||||
|
||||
std::vector<std::string> v = StringUtils::split(s,' ');
|
||||
value->clear();
|
||||
@ -154,9 +175,29 @@ bool XMLNode::get(const std::string &attribute, std::vector<int> *value)
|
||||
{
|
||||
value->push_back(atoi(v[i].c_str()));
|
||||
}
|
||||
return true;
|
||||
return value->size();
|
||||
} // get(vector<int>)
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
/** Interprets the attributes 'x', 'y', 'z' or 'h', 'p', 'r' as a 3d vector
|
||||
* and set the corresponding elements of value. Not all values need to be
|
||||
* defined as attributes (and the correspnding elements of the vector will
|
||||
* not be changed). It returns a bit field for each defined value, i.e. if x
|
||||
* and y are defined, 3 is returned.
|
||||
* \param value Vector to return the values in.
|
||||
*/
|
||||
int XMLNode::get(core::vector3df *value) const
|
||||
{
|
||||
float f;
|
||||
int bits=0;
|
||||
core::vector3df result = *value;
|
||||
if(get("x", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("h", &f)) { value->X = f; bits |= 1; }
|
||||
if(get("y", &f)) { value->Y = f; bits |= 2; }
|
||||
if(get("p", &f)) { value->Y = f; bits |= 2; }
|
||||
if(get("z", &f)) { value->Z = f; bits |= 4; }
|
||||
if(get("r", &f)) { value->Z = f; bits |= 4; }
|
||||
return bits;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
#endif
|
||||
|
@ -32,19 +32,31 @@ class Vec3;
|
||||
class XMLNode
|
||||
{
|
||||
private:
|
||||
/** Name of this element. */
|
||||
std::string m_name;
|
||||
/** List of all attributes. */
|
||||
std::map<std::string, core::stringw> m_attributes;
|
||||
public:
|
||||
XMLNode(io::IXMLReader *xml);
|
||||
bool get(const std::string &attribute, std::string *value);
|
||||
bool get(const std::string &attribute, core::vector3df *value);
|
||||
bool get(const std::string &attribute, Vec3 *value);
|
||||
bool get(const std::string &attribute, video::SColorf *value);
|
||||
bool get(const std::string &attribute, std::vector<std::string> *value);
|
||||
bool get(const std::string &attribute, std::vector<float> *value);
|
||||
bool get(const std::string &attribute, std::vector<int> *value);
|
||||
bool get(const std::string &attribute, int *value);
|
||||
bool get(const std::string &attribute, float *value);
|
||||
bool get(const std::string &attribute, bool *value);
|
||||
XMLNode(const std::string &name, io::IXMLReader *xml);
|
||||
const std::string &getName() const {return m_name; }
|
||||
int get(const std::string &attribute, std::string *value) const;
|
||||
int get(const std::string &attribute, int *value) const;
|
||||
int get(const std::string &attribute, float *value) const;
|
||||
int get(const std::string &attribute, bool *value) const;
|
||||
int get(const std::string &attribute, Vec3 *value) const;
|
||||
int get(const std::string &attribute, core::vector3df *value) const;
|
||||
int get(const std::string &attribute, video::SColorf *value) const;
|
||||
int get(const std::string &attribute, std::vector<std::string> *value) const;
|
||||
int get(const std::string &attribute, std::vector<float> *value) const;
|
||||
int get(const std::string &attribute, std::vector<int> *value) const;
|
||||
int get(core::vector3df *value) const;
|
||||
/** Handy functions to test the bit pattern returned by get(vector3df*).*/
|
||||
static bool hasX(int b) { return (b&1)==1; }
|
||||
static bool hasY(int b) { return (b&2)==2; }
|
||||
static bool hasZ(int b) { return (b&4)==4; }
|
||||
static bool hasH(int b) { return (b&1)==1; }
|
||||
static bool hasP(int b) { return (b&2)==2; }
|
||||
static bool hasR(int b) { return (b&4)==4; }
|
||||
}; // XMLNode
|
||||
|
||||
#endif
|
||||
|
@ -33,8 +33,8 @@ XMLReader::XMLReader(io::IXMLReader *xml)
|
||||
// FIXME: is there an easier way to convert
|
||||
// stringw to std::string?
|
||||
std::string s = core::stringc(xml->getNodeName()).c_str();
|
||||
XMLNode *node = new XMLNode(xml);
|
||||
m_all_nodes[s] = node;
|
||||
const XMLNode *node = new XMLNode(s, xml);
|
||||
m_all_nodes.push_back(node);
|
||||
break;
|
||||
}
|
||||
case io::EXN_ELEMENT_END: // Ignore all other types
|
||||
@ -46,12 +46,24 @@ XMLReader::XMLReader(io::IXMLReader *xml)
|
||||
} // XMLReader
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
XMLNode *XMLReader::getNode(const std::string &node_name)
|
||||
unsigned int XMLReader::getNumNodes() const
|
||||
{
|
||||
std::map<std::string, XMLNode *>::iterator node;
|
||||
node = m_all_nodes.find(node_name);
|
||||
if(node==m_all_nodes.end()) return NULL;
|
||||
return m_all_nodes.size();
|
||||
} // getNumNodes
|
||||
|
||||
return node->second;
|
||||
// ----------------------------------------------------------------------------
|
||||
const XMLNode *XMLReader::getNode(unsigned int n) const
|
||||
{
|
||||
return m_all_nodes[n];
|
||||
} // getNode
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
const XMLNode *XMLReader::getNode(const std::string &node_name) const
|
||||
{
|
||||
for(unsigned int i=0; i<m_all_nodes.size(); i++)
|
||||
{
|
||||
if(m_all_nodes[i]->getName()==node_name) return m_all_nodes[i];
|
||||
}
|
||||
return NULL;
|
||||
} // getNode
|
||||
#endif
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define HEADER_XML_READER_HPP
|
||||
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include "irrlicht.h"
|
||||
using namespace irr;
|
||||
@ -33,11 +33,12 @@ class XMLReader
|
||||
{
|
||||
private:
|
||||
io::IXMLReader *m_reader;
|
||||
std::map<std::string, XMLNode *> m_all_nodes;
|
||||
std::vector<const XMLNode *> m_all_nodes;
|
||||
public:
|
||||
XMLReader(io::IXMLReader *r);
|
||||
|
||||
XMLNode *getNode(const std::string &node_name);
|
||||
XMLReader(io::IXMLReader *r);
|
||||
unsigned int getNumNodes() const;
|
||||
const XMLNode *getNode(const std::string &node_name) const;
|
||||
const XMLNode *getNode(unsigned int n) const;
|
||||
}; // XMLReader
|
||||
#endif
|
||||
#endif
|
@ -19,13 +19,21 @@
|
||||
|
||||
#include "items/bubblegumitem.hpp"
|
||||
|
||||
#ifdef HAVE_IRRLICHT
|
||||
BubbleGumItem::BubbleGumItem(ItemType type, const Vec3& xyz, const Vec3 &normal,
|
||||
scene::IMesh* mesh, unsigned int item_id)
|
||||
: Item(type, xyz, normal, mesh, item_id,
|
||||
/* rotate */ false)
|
||||
{
|
||||
} // BubbleGumItem
|
||||
#else
|
||||
BubbleGumItem::BubbleGumItem(ItemType type, const Vec3& xyz, const Vec3 &normal,
|
||||
ssgEntity* model, unsigned int item_id)
|
||||
: Item(type, xyz, normal, model, item_id,
|
||||
/* rotate */ false)
|
||||
{
|
||||
} // BubbleGumItem
|
||||
|
||||
#endif
|
||||
//-----------------------------------------------------------------------------
|
||||
BubbleGumItem::~BubbleGumItem()
|
||||
{
|
||||
|
@ -17,8 +17,8 @@
|
||||
// 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_BUBBLEGUMITEM_H
|
||||
#define HEADER_BUBBLEGUMITEM_H
|
||||
#ifndef HEADER_BUBBLEGUMITEM_HPP
|
||||
#define HEADER_BUBBLEGUMITEM_HPP
|
||||
|
||||
#include "items/item.hpp"
|
||||
|
||||
@ -26,9 +26,15 @@
|
||||
class BubbleGumItem : public Item
|
||||
{
|
||||
public:
|
||||
#ifdef HAVE_IRRLICHT
|
||||
BubbleGumItem(ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal, scene::IMesh* mesh,
|
||||
unsigned int item_id);
|
||||
#else
|
||||
BubbleGumItem(ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal, ssgEntity* model,
|
||||
unsigned int item_id);
|
||||
#endif
|
||||
~BubbleGumItem ();
|
||||
virtual void isCollected(float t);
|
||||
}
|
||||
|
@ -24,8 +24,13 @@
|
||||
#include "utils/coord.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
#ifdef HAVE_IRRLICHT
|
||||
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
scene::IMesh* mesh, unsigned int item_id, bool rotate)
|
||||
#else
|
||||
Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
ssgEntity* model, unsigned int item_id, bool rotate)
|
||||
#endif
|
||||
{
|
||||
m_rotate = rotate;
|
||||
m_parent = NULL;
|
||||
@ -50,8 +55,11 @@ Item::Item(ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
//-----------------------------------------------------------------------------
|
||||
Item::~Item()
|
||||
{
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
stk_scene->remove(m_root);
|
||||
ssgDeRefDelete(m_root);
|
||||
#endif
|
||||
} // ~Item
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -60,7 +68,10 @@ void Item::reset()
|
||||
m_collected = false;
|
||||
m_time_till_return = 0.0f;
|
||||
m_deactive_time = 0.0f;
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
m_root->setTransform(const_cast<sgCoord*>(&m_coord.toSgCoord()));
|
||||
#endif
|
||||
} // reset
|
||||
//-----------------------------------------------------------------------------
|
||||
void Item::setParent(Kart* parent)
|
||||
@ -83,12 +94,16 @@ void Item::update(float delta)
|
||||
|
||||
hell.setZ( (m_time_till_return>1.0f) ? -1000000.0f
|
||||
: m_coord.getXYZ().getZ() - m_time_till_return / 2.0f);
|
||||
#ifndef HAVE_IRRLICHT
|
||||
m_root->setTransform(hell.toFloat());
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
m_collected = false;
|
||||
#ifndef HAVE_IRRLICHT
|
||||
m_root->setTransform(const_cast<sgCoord*>(&m_coord.toSgCoord()));
|
||||
#endif
|
||||
} // T>0
|
||||
|
||||
}
|
||||
|
@ -17,41 +17,49 @@
|
||||
// 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_ITEM_H
|
||||
#define HEADER_ITEM_H
|
||||
#ifndef HEADER_ITEM_HPP
|
||||
#define HEADER_ITEM_HPP
|
||||
|
||||
// num_players triggers 'already defined' messages without the WINSOCKAPI define. Don't ask me :(
|
||||
#define _WINSOCKAPI_
|
||||
#include <plib/sg.h>
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#include "irrlicht.h"
|
||||
using namespace irr;
|
||||
#endif
|
||||
#include "karts/kart.hpp"
|
||||
#include "utils/coord.hpp"
|
||||
|
||||
class ssgTransform;
|
||||
#ifndef HAVE_IRRLICHT
|
||||
class ssgtransform;
|
||||
class ssgEntity;
|
||||
|
||||
enum ItemType
|
||||
{
|
||||
ITEM_FIRST = -1,
|
||||
|
||||
ITEM_BONUS_BOX = 0,
|
||||
ITEM_BANANA,
|
||||
ITEM_GOLD_COIN,
|
||||
ITEM_SILVER_COIN,
|
||||
ITEM_BUBBLEGUM,
|
||||
|
||||
ITEM_LAST
|
||||
};
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
class Item
|
||||
{
|
||||
public:
|
||||
enum ItemType
|
||||
{
|
||||
ITEM_FIRST = -1,
|
||||
|
||||
ITEM_BONUS_BOX = 0,
|
||||
ITEM_BANANA,
|
||||
ITEM_GOLD_COIN,
|
||||
ITEM_SILVER_COIN,
|
||||
ITEM_BUBBLEGUM,
|
||||
|
||||
ITEM_LAST
|
||||
};
|
||||
|
||||
private:
|
||||
ItemType m_type; // Item type
|
||||
bool m_collected; // true if item was collected & is not displayed
|
||||
float m_time_till_return; // time till a collected item reappears
|
||||
Coord m_coord; // Original coordinates, used mainly when
|
||||
// collected items reappear.
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
ssgTransform* m_root; // The actual root of the item
|
||||
#endif
|
||||
unsigned int m_item_id; // index in item_manager field
|
||||
|
||||
bool m_rotate; // set to false if item should not rotate
|
||||
@ -64,9 +72,15 @@ private:
|
||||
float m_deactive_time;
|
||||
|
||||
public:
|
||||
#ifdef HAVE_IRRLICHT
|
||||
Item (ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
scene::IMesh* mesh, unsigned int item_id,
|
||||
bool rotate=true);
|
||||
#else
|
||||
Item (ItemType type, const Vec3& xyz, const Vec3& normal,
|
||||
ssgEntity* model, unsigned int item_id,
|
||||
bool rotate=true);
|
||||
#endif
|
||||
virtual ~Item ();
|
||||
void update (float delta);
|
||||
virtual void isCollected(float t=2.0f);
|
||||
@ -91,7 +105,10 @@ public:
|
||||
void deactivate(float t) { m_deactive_time=t; }
|
||||
// ------------------------------------------------------------------------
|
||||
unsigned int getItemId() const { return m_item_id; }
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
ssgTransform* getRoot() const { return m_root; }
|
||||
#endif
|
||||
ItemType getType() const { return m_type; }
|
||||
bool wasCollected() const { return m_collected;}
|
||||
void setParent(Kart* parent);
|
||||
|
@ -79,11 +79,19 @@ Shadow::Shadow ( float x1, float x2, float y1, float y2 )
|
||||
|
||||
//=============================================================================
|
||||
ItemManager* item_manager;
|
||||
#ifdef HAVE_IRRLICHT
|
||||
typedef std::map<std::string,scene::IMesh*>::const_iterator CI_type;
|
||||
#else
|
||||
typedef std::map<std::string,ssgEntity*>::const_iterator CI_type;
|
||||
#endif
|
||||
|
||||
ItemManager::ItemManager()
|
||||
{
|
||||
#ifdef HAVE_IRRLICHT
|
||||
m_all_meshes.clear();
|
||||
#else
|
||||
m_all_models.clear();
|
||||
#endif
|
||||
// The actual loading is done in loadDefaultItems
|
||||
} // ItemManager
|
||||
|
||||
@ -97,11 +105,19 @@ void ItemManager::removeTextures()
|
||||
}
|
||||
m_all_items.clear();
|
||||
|
||||
#ifdef HAVE_IRRLICHT
|
||||
for(CI_type i=m_all_meshes.begin(); i!=m_all_meshes.end(); ++i)
|
||||
{
|
||||
i->second->drop();
|
||||
}
|
||||
m_all_meshes.clear();
|
||||
#else
|
||||
for(CI_type i=m_all_models.begin(); i!=m_all_models.end(); ++i)
|
||||
{
|
||||
i->second->deRef();
|
||||
}
|
||||
m_all_models.clear();
|
||||
#endif
|
||||
callback_manager->clear(CB_ITEM);
|
||||
} // removeTextures
|
||||
|
||||
@ -109,6 +125,15 @@ void ItemManager::removeTextures()
|
||||
ItemManager::~ItemManager()
|
||||
{
|
||||
#ifdef HAVE_IRRLICHT
|
||||
for(CI_type i=m_all_meshes.begin(); i!=m_all_meshes.end(); ++i)
|
||||
{
|
||||
// FIXME: What about this plib comment:
|
||||
// We can't use ssgDeRefDelete here, since then the object would be
|
||||
// freed, and when m_all_models is deleted, we have invalid memory
|
||||
// accesses.
|
||||
i->second->drop();
|
||||
}
|
||||
m_all_meshes.clear();
|
||||
#else
|
||||
for(CI_type i=m_all_models.begin(); i!=m_all_models.end(); ++i)
|
||||
{
|
||||
@ -117,8 +142,8 @@ ItemManager::~ItemManager()
|
||||
// accesses.
|
||||
i->second->deRef();
|
||||
}
|
||||
#endif
|
||||
m_all_models.clear();
|
||||
#endif
|
||||
} // ~ItemManager
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
@ -147,15 +172,6 @@ void ItemManager::loadDefaultItems()
|
||||
#endif
|
||||
} // for i
|
||||
|
||||
|
||||
// FIXME LEAK: these can be deleted
|
||||
// Load the old, internal only models
|
||||
// ----------------------------------
|
||||
sgVec3 yellow = { 1.0f, 1.0f, 0.4f }; createDefaultItem(yellow, "OLD_GOLD" );
|
||||
sgVec3 cyan = { 0.4f, 1.0f, 1.0f }; createDefaultItem(cyan , "OLD_SILVER");
|
||||
sgVec3 red = { 0.8f, 0.0f, 0.0f }; createDefaultItem(red , "OLD_RED" );
|
||||
sgVec3 green = { 0.0f, 0.8f, 0.0f }; createDefaultItem(green , "OLD_GREEN" );
|
||||
|
||||
setDefaultItemStyle();
|
||||
} // loadDefaultItems
|
||||
|
||||
@ -163,19 +179,24 @@ void ItemManager::loadDefaultItems()
|
||||
void ItemManager::setDefaultItemStyle()
|
||||
{
|
||||
// FIXME - This should go in an internal, system wide configuration file
|
||||
std::string DEFAULT_NAMES[ITEM_LAST - ITEM_FIRST - 1];
|
||||
DEFAULT_NAMES[ITEM_BONUS_BOX] = "gift-box";
|
||||
DEFAULT_NAMES[ITEM_BANANA] = "banana";
|
||||
DEFAULT_NAMES[ITEM_GOLD_COIN] = "nitrotank-big";
|
||||
DEFAULT_NAMES[ITEM_SILVER_COIN] = "nitrotank-small";
|
||||
DEFAULT_NAMES[ITEM_BUBBLEGUM] = "bubblegum";
|
||||
std::string DEFAULT_NAMES[Item::ITEM_LAST - Item::ITEM_FIRST - 1];
|
||||
DEFAULT_NAMES[Item::ITEM_BONUS_BOX] = "gift-box";
|
||||
DEFAULT_NAMES[Item::ITEM_BANANA] = "banana";
|
||||
DEFAULT_NAMES[Item::ITEM_GOLD_COIN] = "nitrotank-big";
|
||||
DEFAULT_NAMES[Item::ITEM_SILVER_COIN] = "nitrotank-small";
|
||||
DEFAULT_NAMES[Item::ITEM_BUBBLEGUM] = "bubblegum";
|
||||
|
||||
bool bError=0;
|
||||
std::ostringstream msg;
|
||||
for(int i=ITEM_FIRST+1; i<ITEM_LAST; i++)
|
||||
for(int i=Item::ITEM_FIRST+1; i<Item::ITEM_LAST; i++)
|
||||
{
|
||||
#ifdef HAVE_IRRLICHT
|
||||
m_item_mesh[i] = m_all_meshes[DEFAULT_NAMES[i]];
|
||||
if(!m_item_mesh[i])
|
||||
#else
|
||||
m_item_model[i] = m_all_models[DEFAULT_NAMES[i]];
|
||||
if(!m_item_model[i])
|
||||
#endif
|
||||
{
|
||||
msg << "Item model '" << DEFAULT_NAMES[i]
|
||||
<< "' is missing (see item_manager)!\n";
|
||||
@ -186,20 +207,17 @@ void ItemManager::setDefaultItemStyle()
|
||||
if(bError)
|
||||
{
|
||||
fprintf(stderr, "The following models are available:\n");
|
||||
#ifdef HAVE_IRRLICHT
|
||||
for(CI_type i=m_all_meshes.begin(); i!=m_all_meshes.end(); ++i)
|
||||
#else
|
||||
for(CI_type i=m_all_models.begin(); i!=m_all_models.end(); ++i)
|
||||
#endif
|
||||
{
|
||||
if(i->second)
|
||||
{
|
||||
if(i->first.substr(0,3)=="OLD")
|
||||
{
|
||||
fprintf(stderr," %s internally only.\n",i->first.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, " %s in %s.ac.\n",
|
||||
i->first.c_str(),
|
||||
i->first.c_str());
|
||||
}
|
||||
fprintf(stderr, " %s in %s.ac.\n",
|
||||
i->first.c_str(),
|
||||
i->first.c_str());
|
||||
} // if i->second
|
||||
}
|
||||
#ifndef HAVE_IRRLICHT
|
||||
@ -212,17 +230,25 @@ void ItemManager::setDefaultItemStyle()
|
||||
} // setDefaultItemStyle
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
Item* ItemManager::newItem(ItemType type, const Vec3& xyz, const Vec3 &normal,
|
||||
Kart* parent)
|
||||
Item* ItemManager::newItem(Item::ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal, Kart *parent)
|
||||
{
|
||||
Item* h;
|
||||
if(type == ITEM_BUBBLEGUM)
|
||||
#ifdef HAVE_IRRLICHT
|
||||
if(type == Item::ITEM_BUBBLEGUM)
|
||||
h = new BubbleGumItem(type, xyz, normal, m_item_mesh[type],
|
||||
m_all_items.size());
|
||||
else
|
||||
h = new Item(type, xyz, normal, m_item_mesh[type],
|
||||
m_all_items.size());
|
||||
#else
|
||||
if(type == Item::ITEM_BUBBLEGUM)
|
||||
h = new BubbleGumItem(type, xyz, normal, m_item_model[type],
|
||||
m_all_items.size());
|
||||
else
|
||||
h = new Item(type, xyz, normal, m_item_model[type],
|
||||
m_all_items.size());
|
||||
|
||||
#endif
|
||||
if(parent != NULL) h->setParent(parent);
|
||||
|
||||
m_all_items.push_back(h);
|
||||
@ -317,7 +343,7 @@ void ItemManager::reset()
|
||||
AllItemTypes::iterator i=m_all_items.begin();
|
||||
while(i!=m_all_items.end())
|
||||
{
|
||||
if((*i)->getType()==ITEM_BUBBLEGUM)
|
||||
if((*i)->getType()==Item::ITEM_BUBBLEGUM)
|
||||
{
|
||||
BubbleGumItem *b=static_cast<BubbleGumItem*>(*i);
|
||||
AllItemTypes::iterator i_next = m_all_items.erase(i);
|
||||
@ -342,49 +368,6 @@ void ItemManager::update(float delta)
|
||||
} // for m_all_items
|
||||
} // delta
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ItemManager::createDefaultItem(sgVec3 colour, std::string name)
|
||||
{
|
||||
ssgVertexArray *va = new ssgVertexArray () ; sgVec3 v ;
|
||||
ssgNormalArray *na = new ssgNormalArray () ; sgVec3 n ;
|
||||
ssgColourArray *ca = new ssgColourArray () ; sgVec4 c ;
|
||||
ssgTexCoordArray *ta = new ssgTexCoordArray () ; sgVec2 t ;
|
||||
|
||||
sgSetVec3(v, -0.5f, 0.0f, 0.0f ) ; va->add(v) ;
|
||||
sgSetVec3(v, 0.5f, 0.0f, 0.0f ) ; va->add(v) ;
|
||||
sgSetVec3(v, -0.5f, 0.0f, 0.5f ) ; va->add(v) ;
|
||||
sgSetVec3(v, 0.5f, 0.0f, 0.5f ) ; va->add(v) ;
|
||||
sgSetVec3(v, -0.5f, 0.0f, 0.0f ) ; va->add(v) ;
|
||||
sgSetVec3(v, 0.5f, 0.0f, 0.0f ) ; va->add(v) ;
|
||||
|
||||
sgSetVec3(n, 0.0f, 1.0f, 0.0f ) ; na->add(n) ;
|
||||
|
||||
sgCopyVec3 ( c, colour ) ; c[ 3 ] = 1.0f ; ca->add(c) ;
|
||||
|
||||
sgSetVec2(t, 0.0f, 0.0f ) ; ta->add(t) ;
|
||||
sgSetVec2(t, 1.0f, 0.0f ) ; ta->add(t) ;
|
||||
sgSetVec2(t, 0.0f, 1.0f ) ; ta->add(t) ;
|
||||
sgSetVec2(t, 1.0f, 1.0f ) ; ta->add(t) ;
|
||||
sgSetVec2(t, 0.0f, 0.0f ) ; ta->add(t) ;
|
||||
sgSetVec2(t, 1.0f, 0.0f ) ; ta->add(t) ;
|
||||
|
||||
|
||||
ssgLeaf *gset = new ssgVtxTable ( GL_TRIANGLE_STRIP, va, na, ta, ca ) ;
|
||||
|
||||
// FIXME - this method seems outdated
|
||||
//gset->setState(material_manager->getMaterial("herring.rgb")->getState()) ;
|
||||
|
||||
Shadow* sh = new Shadow ( -0.5f, 0.5f, -0.25f, 0.25f ) ;
|
||||
|
||||
ssgTransform* tr = new ssgTransform () ;
|
||||
|
||||
tr -> addKid ( sh -> getRoot () ) ;
|
||||
tr -> addKid ( gset ) ;
|
||||
tr -> ref () ; /* Make sure it doesn't get deleted by mistake */
|
||||
m_all_models[name] = tr;
|
||||
|
||||
} // createDefaultItem
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ItemManager::loadItemStyle(const std::string filename)
|
||||
{
|
||||
@ -403,21 +386,25 @@ void ItemManager::loadItemStyle(const std::string filename)
|
||||
throw std::runtime_error(msg.str());
|
||||
delete root;
|
||||
}
|
||||
setItem(item_node, "red", ITEM_BONUS_BOX );
|
||||
setItem(item_node, "green", ITEM_BANANA );
|
||||
setItem(item_node, "gold" ,ITEM_GOLD_COIN );
|
||||
setItem(item_node, "silver",ITEM_SILVER_COIN);
|
||||
setItem(item_node, "red", Item::ITEM_BONUS_BOX );
|
||||
setItem(item_node, "green", Item::ITEM_BANANA );
|
||||
setItem(item_node, "gold" ,Item::ITEM_GOLD_COIN );
|
||||
setItem(item_node, "silver",Item::ITEM_SILVER_COIN);
|
||||
delete root;
|
||||
} // loadItemStyle
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
void ItemManager::setItem(const lisp::Lisp *item_node,
|
||||
const char *colour, ItemType type)
|
||||
const char *colour, Item::ItemType type)
|
||||
{
|
||||
std::string name;
|
||||
item_node->get(colour, name);
|
||||
if(name.size()>0)
|
||||
{
|
||||
#ifdef HAVE_IRRLICHT
|
||||
m_item_mesh[type]=m_all_meshes[name];
|
||||
#else
|
||||
m_item_model[type]=m_all_models[name];
|
||||
#endif
|
||||
}
|
||||
} // setItem
|
||||
|
@ -38,25 +38,30 @@ private:
|
||||
AllItemTypes m_all_items;
|
||||
|
||||
// This stores all item models
|
||||
ssgEntity *m_item_model[ITEM_SILVER_COIN+1];
|
||||
#ifdef HAVE_IRRLICHT
|
||||
// FIXME: why ITEM_SILVER_COINT+1 in plib??
|
||||
scene::IMesh *m_item_mesh[Item::ITEM_LAST];
|
||||
std::map<std::string,scene::IMesh*> m_all_meshes;
|
||||
#else
|
||||
ssgEntity *m_item_model[Item::ITEM_SILVER_COIN+1];
|
||||
|
||||
// This is the active model. It gets determined by first loading the
|
||||
// default, then track models, user models, grand prix models. This means that
|
||||
// an item style specified in a track overwrites a command line option.
|
||||
std::map<std::string,ssgEntity*> m_all_models;
|
||||
#endif
|
||||
|
||||
std::string m_user_filename;
|
||||
void createDefaultItem(sgVec3 colour, std::string name);
|
||||
void setDefaultItemStyle();
|
||||
void setItem(const lisp::Lisp *item_node, const char *colour,
|
||||
ItemType type);
|
||||
Item::ItemType type);
|
||||
|
||||
public:
|
||||
ItemManager();
|
||||
~ItemManager();
|
||||
void loadDefaultItems();
|
||||
void loadItemStyle (const std::string filename);
|
||||
Item* newItem (ItemType type, const Vec3& xyz,
|
||||
Item* newItem (Item::ItemType type, const Vec3& xyz,
|
||||
const Vec3 &normal, Kart* parent=NULL);
|
||||
void update (float delta);
|
||||
void hitItem (Kart* kart);
|
||||
@ -66,8 +71,13 @@ public:
|
||||
void setUserFilename (char *s) {m_user_filename=s;}
|
||||
void collectedItem (int item_id, Kart *kart,
|
||||
int add_info=-1);
|
||||
ssgEntity* getItemModel (ItemType type)
|
||||
#ifdef HAVE_IRRLICHT
|
||||
scene::IMesh* getItemModel (Item::ItemType type)
|
||||
{return m_item_mesh[type];}
|
||||
#else
|
||||
ssgEntity* getItemModel (Item::ItemType type)
|
||||
{return m_item_model[type];}
|
||||
#endif
|
||||
};
|
||||
|
||||
extern ItemManager* item_manager;
|
||||
|
@ -149,7 +149,7 @@ void Powerup::use()
|
||||
|
||||
pos.setZ(z_coord-0.05f);
|
||||
|
||||
item_manager->newItem(ITEM_BUBBLEGUM, pos, normal, m_owner);
|
||||
item_manager->newItem(Item::ITEM_BUBBLEGUM, pos, normal, m_owner);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -377,14 +377,14 @@ void Kart::raceFinished(float time)
|
||||
//-----------------------------------------------------------------------------
|
||||
void Kart::collectedItem(const Item &item, int add_info)
|
||||
{
|
||||
const ItemType type = item.getType();
|
||||
const Item::ItemType type = item.getType();
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case ITEM_BANANA : m_attachment.hitBanana(item, add_info); break;
|
||||
case ITEM_SILVER_COIN : m_collected_energy++ ; break;
|
||||
case ITEM_GOLD_COIN : m_collected_energy += 3 ; break;
|
||||
case ITEM_BONUS_BOX :
|
||||
case Item::ITEM_BANANA : m_attachment.hitBanana(item, add_info); break;
|
||||
case Item::ITEM_SILVER_COIN: m_collected_energy++ ; break;
|
||||
case Item::ITEM_GOLD_COIN : m_collected_energy += 3 ; break;
|
||||
case Item::ITEM_BONUS_BOX :
|
||||
{
|
||||
// In wheelie style, karts get more items depending on energy,
|
||||
// in nitro mode it's only one item.
|
||||
@ -392,7 +392,7 @@ void Kart::collectedItem(const Item &item, int add_info)
|
||||
m_powerup.hitBonusBox(n, item,add_info);
|
||||
break;
|
||||
}
|
||||
case ITEM_BUBBLEGUM:
|
||||
case Item::ITEM_BUBBLEGUM:
|
||||
// slow down
|
||||
m_body->setLinearVelocity(m_body->getLinearVelocity()*0.3f);
|
||||
m_goo_sound->position(getXYZ());
|
||||
@ -405,7 +405,7 @@ void Kart::collectedItem(const Item &item, int add_info)
|
||||
// functions (hit{Red,Green}Item), so only coins need to be
|
||||
// stored here.
|
||||
if(network_manager->getMode()==NetworkManager::NW_SERVER &&
|
||||
(type==ITEM_SILVER_COIN || type==ITEM_GOLD_COIN) )
|
||||
(type==Item::ITEM_SILVER_COIN || type==Item::ITEM_GOLD_COIN) )
|
||||
{
|
||||
race_state->itemCollected(getWorldKartId(), item.getItemId());
|
||||
}
|
||||
|
@ -356,16 +356,16 @@ void PlayerKart::collectedItem(const Item &item, int add_info)
|
||||
{
|
||||
switch(item.getType())
|
||||
{
|
||||
case ITEM_BANANA:
|
||||
m_ugh_sound->play();
|
||||
break;
|
||||
case ITEM_BUBBLEGUM:
|
||||
//The skid sound is played by the kart class. Do nothing here.
|
||||
//See Kart::collectedItem()
|
||||
break;
|
||||
default:
|
||||
m_grab_sound->play();
|
||||
break;
|
||||
case Item::ITEM_BANANA:
|
||||
m_ugh_sound->play();
|
||||
break;
|
||||
case Item::ITEM_BUBBLEGUM:
|
||||
//The skid sound is played by the kart class. Do nothing here.
|
||||
//See Kart::collectedItem()
|
||||
break;
|
||||
default:
|
||||
m_grab_sound->play();
|
||||
break;
|
||||
}
|
||||
}
|
||||
} // collectedItem
|
||||
|
@ -41,6 +41,15 @@ void TriangleMesh::addTriangle(const btVector3 &t1, const btVector3 &t2,
|
||||
} // addTriangle
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
/** Creates the physics body for this triangle mesh. If the body already
|
||||
* exists (because it was created by a previous call to createBody)
|
||||
* it is first removed from the world. This is used by loading the track
|
||||
* where a physics body is used to determine the height of terrain. To have
|
||||
* an optimised rigid body including all static objects, the track is then
|
||||
* removed and all objects together with the track is converted again into
|
||||
* a single rigid body. This avoids using irrlicht (or the graphics engine)
|
||||
* for height of terrain detection).
|
||||
*/
|
||||
void TriangleMesh::createBody(btCollisionObject::CollisionFlags flags)
|
||||
{
|
||||
if(m_triangleIndex2Material.size()==0)
|
||||
|
@ -838,27 +838,29 @@ void Track::draw2Dview (float x_offset, float y_offset) const
|
||||
//-----------------------------------------------------------------------------
|
||||
void Track::loadTrack(const std::string &filename)
|
||||
{
|
||||
m_filename = filename;
|
||||
|
||||
m_ident = StringUtils::basename(StringUtils::without_extension(m_filename));
|
||||
std::string path = StringUtils::without_extension(m_filename);
|
||||
m_filename = filename;
|
||||
m_ident = StringUtils::basename(
|
||||
StringUtils::without_extension(m_filename));
|
||||
std::string path = StringUtils::without_extension(m_filename);
|
||||
|
||||
// Default values
|
||||
m_use_fog = false;
|
||||
m_fog_density = 1.0f/100.0f;
|
||||
m_fog_start = 0.0f;
|
||||
m_fog_end = 1000.0f;
|
||||
m_gravity = 9.80665f;
|
||||
m_use_fog = false;
|
||||
m_fog_density = 1.0f/100.0f;
|
||||
m_fog_start = 0.0f;
|
||||
m_fog_end = 1000.0f;
|
||||
m_gravity = 9.80665f;
|
||||
#ifdef HAVE_IRRLICHT
|
||||
m_sun_position = core::vector3df(0.4f, 0.4f, 0.4f);
|
||||
m_sky_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
||||
m_fog_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
||||
m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
XMLReader *xml = file_manager->getXMLReader(m_filename);
|
||||
XMLNode *node = xml->getNode("track");
|
||||
|
||||
m_sun_position = core::vector3df(0.4f, 0.4f, 0.4f);
|
||||
m_sky_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
||||
m_fog_color = video::SColorf(0.3f, 0.7f, 0.9f, 1.0f);
|
||||
m_ambient_color = video::SColorf(0.5f, 0.5f, 0.5f, 1.0f);
|
||||
m_specular_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
m_diffuse_color = video::SColorf(1.0f, 1.0f, 1.0f, 1.0f);
|
||||
XMLReader *xml = file_manager->getXMLReader(m_filename);
|
||||
const XMLNode *node = xml->getNode("track");
|
||||
if(!node)
|
||||
{
|
||||
}
|
||||
node->get("name", &m_name);
|
||||
node->get("description", &m_description);
|
||||
node->get("designer", &m_designer);
|
||||
@ -893,8 +895,10 @@ void Track::loadTrack(const std::string &filename)
|
||||
m_groups.push_back("standard");
|
||||
// if both camera position and rotation are defined,
|
||||
// set the flag that the track has final camera position
|
||||
m_has_final_camera = node->get("camera-final-position", &m_camera_final_position);
|
||||
m_has_final_camera &= node->get("camera-final-hpr", &m_camera_final_hpr);
|
||||
m_has_final_camera = node->get("camera-final-position",
|
||||
&m_camera_final_position)!=1;
|
||||
m_has_final_camera &= node->get("camera-final-hpr",
|
||||
&m_camera_final_hpr) !=1;
|
||||
m_camera_final_hpr.degreeToRad();
|
||||
#else
|
||||
sgSetVec3 ( m_sun_position, 0.4f, 0.4f, 0.4f );
|
||||
@ -1153,8 +1157,8 @@ void Track::createPhysicsModel()
|
||||
sgMat4 mat;
|
||||
sgMakeIdentMat4(mat);
|
||||
convertTrackToBullet(m_model, mat);
|
||||
m_track_mesh->createBody();
|
||||
#endif
|
||||
m_track_mesh->createBody();
|
||||
m_non_collision_mesh->createBody(btCollisionObject::CF_NO_CONTACT_RESPONSE);
|
||||
|
||||
} // createPhysicsModel
|
||||
@ -1209,7 +1213,6 @@ void Track::convertTrackToBullet()
|
||||
} // for j
|
||||
} // for i<getMeshBufferCount
|
||||
} // for obj in children
|
||||
m_track_mesh->createBody();
|
||||
|
||||
} // convertTrackToBullet
|
||||
|
||||
@ -1297,11 +1300,87 @@ void Track::loadTrackModel()
|
||||
// no temporary materials.dat file, ignore
|
||||
(void)e;
|
||||
}
|
||||
|
||||
// Start building the scene graph
|
||||
#ifdef HAVE_IRRLICHT
|
||||
std::string path = file_manager->getTrackFile(getIdent()+".irrloc");
|
||||
XMLReader *xml = file_manager->getXMLReader(path);
|
||||
|
||||
// Make sure that we have a track (which is used for raycasts to
|
||||
// place other objects).
|
||||
const XMLNode *node = xml->getNode(0);
|
||||
if(!node || node->getName()!="track")
|
||||
{
|
||||
std::ostringstream msg;
|
||||
msg<< "No track model defined in '"<<path
|
||||
<<"' (it must be the first element).";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
for(unsigned int i=0; i<xml->getNumNodes(); i++)
|
||||
{
|
||||
const XMLNode *node = xml->getNode(i);
|
||||
const std::string name = node->getName();
|
||||
if(name=="track" || name=="object")
|
||||
{
|
||||
std::string model_name;
|
||||
node->get("model", &model_name);
|
||||
std::string full_path = file_manager->getTrackFile(model_name,
|
||||
getIdent());
|
||||
scene::IAnimatedMesh *obj = irr_driver->getAnimatedMesh(full_path);
|
||||
if(!obj)
|
||||
{
|
||||
fprintf(stderr, "Warning: '%s' in '%s' not found and is ignored.\n",
|
||||
node->getName().c_str(), model_name.c_str());
|
||||
continue;
|
||||
}
|
||||
scene::IMesh *mesh = obj->getMesh(0);
|
||||
m_all_meshes.push_back(mesh);
|
||||
scene::ISceneNode *scene_node = irr_driver->addOctTree(mesh);
|
||||
core::vector3df xyz(0,0,0);
|
||||
int result = node->get(&xyz);
|
||||
if(!XMLNode::hasZ(result)) // needs height
|
||||
{
|
||||
}
|
||||
core::vector3df hpr(0,0,0);
|
||||
result = node->get(&hpr);
|
||||
if(!XMLNode::hasP(result) ||
|
||||
!XMLNode::hasR(result)) // Needs perhaps pitch and roll
|
||||
{
|
||||
}
|
||||
scene_node->setPosition(xyz);
|
||||
scene_node->setRotation(hpr);
|
||||
m_all_nodes.push_back(scene_node);
|
||||
scene_node->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
}
|
||||
else if(name=="banana" || name=="item" ||
|
||||
name=="small-nitro" || name=="big-nitro")
|
||||
{
|
||||
Item::ItemType type=Item::ITEM_BANANA;
|
||||
if (name=="banana" ) type = Item::ITEM_BANANA;
|
||||
else if(name=="item" ) type = Item::ITEM_BONUS_BOX;
|
||||
else if(name=="small-nitro") type = Item::ITEM_SILVER_COIN;
|
||||
else type = Item::ITEM_GOLD_COIN;
|
||||
core::vector3df xyz;
|
||||
int bits = node->get(&xyz);
|
||||
// Height is needed if bit 2 (for z) is not set
|
||||
itemCommand(&xyz, type, /* need_height */ !XMLNode::hasZ(bits) );
|
||||
}
|
||||
else if(name=="item")
|
||||
{
|
||||
}
|
||||
else if(name=="small-nitro" || node->getName()=="big-nitro")
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr, "Warning: element '%s' not found.\n",
|
||||
node->getName().c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#else
|
||||
std::string path = file_manager->getTrackFile(getIdent()+".loc");
|
||||
#endif
|
||||
|
||||
FILE *fd = fopen (path.c_str(), "r" );
|
||||
if ( fd == NULL )
|
||||
@ -1310,13 +1389,8 @@ void Track::loadTrackModel()
|
||||
msg<<"Can't open track location file '"<<path<<"'.";
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
|
||||
// Start building the scene graph
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
m_model = new ssgBranch ;
|
||||
stk_scene->add(m_model);
|
||||
#endif
|
||||
|
||||
char s [ 1024 ] ;
|
||||
|
||||
@ -1338,67 +1412,67 @@ void Track::loadTrackModel()
|
||||
if ( sscanf ( s, "%cHERRING,%f,%f,%f", &htype,
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 4 )
|
||||
{
|
||||
ItemType type=ITEM_BANANA;
|
||||
if ( htype=='Y' || htype=='y' ) { type = ITEM_GOLD_COIN ;}
|
||||
if ( htype=='G' || htype=='g' ) { type = ITEM_BANANA ;}
|
||||
if ( htype=='R' || htype=='r' ) { type = ITEM_BONUS_BOX ;}
|
||||
if ( htype=='S' || htype=='s' ) { type = ITEM_SILVER_COIN ;}
|
||||
Item::ItemType type=Item::ITEM_BANANA;
|
||||
if ( htype=='Y' || htype=='y' ) { type = Item::ITEM_GOLD_COIN ;}
|
||||
if ( htype=='G' || htype=='g' ) { type = Item::ITEM_BANANA ;}
|
||||
if ( htype=='R' || htype=='r' ) { type = Item::ITEM_BONUS_BOX ;}
|
||||
if ( htype=='S' || htype=='s' ) { type = Item::ITEM_SILVER_COIN ;}
|
||||
itemCommand(&loc.xyz, type, false) ;
|
||||
}
|
||||
else if ( sscanf ( s, "%cHERRING,%f,%f", &htype,
|
||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 3 )
|
||||
{
|
||||
ItemType type=ITEM_BANANA;
|
||||
if ( htype=='Y' || htype=='y' ) { type = ITEM_GOLD_COIN ;}
|
||||
if ( htype=='G' || htype=='g' ) { type = ITEM_BANANA ;}
|
||||
if ( htype=='R' || htype=='r' ) { type = ITEM_BONUS_BOX ;}
|
||||
if ( htype=='S' || htype=='s' ) { type = ITEM_SILVER_COIN ;}
|
||||
Item::ItemType type=Item::ITEM_BANANA;
|
||||
if ( htype=='Y' || htype=='y' ) { type = Item::ITEM_GOLD_COIN ;}
|
||||
if ( htype=='G' || htype=='g' ) { type = Item::ITEM_BANANA ;}
|
||||
if ( htype=='R' || htype=='r' ) { type = Item::ITEM_BONUS_BOX ;}
|
||||
if ( htype=='S' || htype=='s' ) { type = Item::ITEM_SILVER_COIN ;}
|
||||
itemCommand (&loc.xyz, type, true) ;
|
||||
}
|
||||
/* and now the new names */
|
||||
else if ( sscanf ( s, "BBOX,%f,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 3 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_BONUS_BOX, false);
|
||||
itemCommand(&loc.xyz, Item::ITEM_BONUS_BOX, false);
|
||||
}
|
||||
else if ( sscanf ( s, "BBOX,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 2 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_BONUS_BOX, true);
|
||||
itemCommand(&loc.xyz, Item::ITEM_BONUS_BOX, true);
|
||||
}
|
||||
|
||||
else if ( sscanf ( s, "BANA,%f,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 3 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_BANANA, false);
|
||||
itemCommand(&loc.xyz, Item::ITEM_BANANA, false);
|
||||
}
|
||||
|
||||
else if ( sscanf ( s, "BANA,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 2 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_BANANA, true);
|
||||
itemCommand(&loc.xyz, Item::ITEM_BANANA, true);
|
||||
}
|
||||
|
||||
else if ( sscanf ( s, "COIN,%f,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 3 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_SILVER_COIN, false);
|
||||
itemCommand(&loc.xyz, Item::ITEM_SILVER_COIN, false);
|
||||
}
|
||||
else if ( sscanf ( s, "COIN,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 2 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_SILVER_COIN, true);
|
||||
itemCommand(&loc.xyz, Item::ITEM_SILVER_COIN, true);
|
||||
}
|
||||
|
||||
else if ( sscanf ( s, "GOLD,%f,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]), &(loc.xyz[2]) ) == 3 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_GOLD_COIN, false);
|
||||
itemCommand(&loc.xyz, Item::ITEM_GOLD_COIN, false);
|
||||
}
|
||||
else if ( sscanf ( s, "GOLD,%f,%f",
|
||||
&(loc.xyz[0]), &(loc.xyz[1]) ) == 2 )
|
||||
{
|
||||
itemCommand(&loc.xyz, ITEM_GOLD_COIN, true);
|
||||
itemCommand(&loc.xyz, Item::ITEM_GOLD_COIN, true);
|
||||
}
|
||||
|
||||
else if ( sscanf ( s, "START,%f,%f,%f",
|
||||
@ -1479,11 +1553,8 @@ void Track::loadTrackModel()
|
||||
if ( need_hat )
|
||||
{
|
||||
sgVec3 nrm ;
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
loc.xyz[2] = 1000.0f ;
|
||||
loc.xyz[2] = getHeightAndNormal ( m_model, loc.xyz, nrm ) ;
|
||||
#endif
|
||||
if ( fit_skin )
|
||||
{
|
||||
float sy = sin ( -loc.hpr [ 0 ] * SG_DEGREES_TO_RADIANS ) ;
|
||||
@ -1496,16 +1567,10 @@ void Track::loadTrackModel()
|
||||
}
|
||||
} // if need_hat
|
||||
|
||||
#ifdef HAVE_IRRLICHT
|
||||
std::string full_path = file_manager->getTrackFile(fname, getIdent());
|
||||
scene::IAnimatedMesh *obj = irr_driver->getAnimatedMesh(full_path);
|
||||
m_all_meshes.push_back(obj->getMesh(0));
|
||||
#else
|
||||
ssgEntity *obj = loader->load(file_manager->getModelFile(fname),
|
||||
CB_TRACK,
|
||||
/* optimise */ true,
|
||||
/*is_full_path*/ true);
|
||||
#endif
|
||||
if(!obj)
|
||||
{
|
||||
fclose(fd);
|
||||
@ -1515,13 +1580,6 @@ void Track::loadTrackModel()
|
||||
file_manager->popModelSearchPath ();
|
||||
throw std::runtime_error(msg.str());
|
||||
}
|
||||
#ifdef HAVE_IRRLICHT
|
||||
// FIXME: for now only static objects
|
||||
scene::ISceneNode *node = irr_driver->addOctTree(obj->getMesh(0));
|
||||
m_all_nodes.push_back(node);
|
||||
node->setMaterialFlag(video::EMF_LIGHTING, false);
|
||||
|
||||
#else
|
||||
SSGHelp::createDisplayLists(obj);
|
||||
ssgRangeSelector *lod = new ssgRangeSelector ;
|
||||
ssgTransform *trans = new ssgTransform ( & loc ) ;
|
||||
@ -1532,7 +1590,6 @@ void Track::loadTrackModel()
|
||||
trans -> addKid(lod );
|
||||
m_model-> addKid(trans );
|
||||
lod -> setRanges(r, 2);
|
||||
#endif
|
||||
if(user_config->m_track_debug)
|
||||
addDebugToScene(user_config->m_track_debug);
|
||||
|
||||
@ -1545,6 +1602,8 @@ void Track::loadTrackModel()
|
||||
} // while fgets
|
||||
|
||||
fclose ( fd ) ;
|
||||
#endif
|
||||
|
||||
file_manager->popTextureSearchPath();
|
||||
file_manager->popModelSearchPath ();
|
||||
|
||||
@ -1565,6 +1624,30 @@ void Track::loadTrackModel()
|
||||
} // loadTrack
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifdef HAVE_IRRLICHT
|
||||
void Track::itemCommand(core::vector3df *xyz, Item::ItemType type,
|
||||
int bNeedHeight)
|
||||
{
|
||||
// Some modes (e.g. time trial) don't have any bonus boxes
|
||||
if(type==Item::ITEM_BONUS_BOX &&
|
||||
!RaceManager::getWorld()->enableBonusBoxes())
|
||||
return;
|
||||
|
||||
// if only 2d coordinates are given, let the item fall from very high
|
||||
if(bNeedHeight) xyz->Z = 1000000.0f;
|
||||
|
||||
// Even if 3d data are given, make sure that the item is on the ground
|
||||
//xyz->Z = irr_dirver->getHeight( m_model, *xyz ) + 0.06f;
|
||||
|
||||
Vec3 loc(*xyz);
|
||||
|
||||
// Don't tilt the items, since otherwise the rotation will look odd,
|
||||
// i.e. the items will not rotate around the normal, but 'wobble'
|
||||
// around.
|
||||
Vec3 normal(0, 0, 0.0f);
|
||||
item_manager->newItem(type, loc, normal);
|
||||
} // itemCommand
|
||||
#else
|
||||
void Track::itemCommand (sgVec3 *xyz, int type, int bNeedHeight )
|
||||
{
|
||||
|
||||
@ -1572,13 +1655,10 @@ void Track::itemCommand (sgVec3 *xyz, int type, int bNeedHeight )
|
||||
if(bNeedHeight) (*xyz)[2] = 1000000.0f;
|
||||
|
||||
// Even if 3d data are given, make sure that the item is on the ground
|
||||
#ifdef HAVE_IRRLICHT
|
||||
#else
|
||||
(*xyz)[2] = getHeight( m_model, *xyz ) + 0.06f;
|
||||
#endif
|
||||
|
||||
// Some modes (e.g. time trial) don't have any bonus boxes
|
||||
if(type==ITEM_BONUS_BOX && !RaceManager::getWorld()->enableBonusBoxes())
|
||||
if(type==Item::ITEM_BONUS_BOX && !RaceManager::getWorld()->enableBonusBoxes())
|
||||
return;
|
||||
Vec3 loc((*xyz));
|
||||
|
||||
@ -1586,8 +1666,9 @@ void Track::itemCommand (sgVec3 *xyz, int type, int bNeedHeight )
|
||||
// i.e. the items will not rotate around the normal, but 'wobble'
|
||||
// around.
|
||||
Vec3 normal(0, 0, 0.0f);
|
||||
item_manager->newItem((ItemType)type, loc, normal);
|
||||
item_manager->newItem((Item::ItemType)type, loc, normal);
|
||||
} // itemCommand
|
||||
#endif
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
void Track::getTerrainInfo(const Vec3 &pos, float *hot, Vec3 *normal,
|
||||
|
@ -38,6 +38,7 @@ using namespace irr;
|
||||
#include "LinearMath/btTransform.h"
|
||||
#include "material.hpp"
|
||||
#include "audio/music_information.hpp"
|
||||
#include "items/item.hpp"
|
||||
#include "utils/vec3.hpp"
|
||||
|
||||
class TriangleMesh;
|
||||
@ -227,15 +228,20 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
void loadTrack (const std::string &filename);
|
||||
void itemCommand (sgVec3 *xyz, int item_type, int bNeedHeight);
|
||||
void loadDriveline ();
|
||||
void readDrivelineFromFile (std::vector<Vec3>& line,
|
||||
const std::string& file_ext);
|
||||
void loadTrack(const std::string &filename);
|
||||
#ifdef HAVE_IRRLICHT
|
||||
void convertTrackToBullet ();
|
||||
void itemCommand(core::vector3df *xyz, Item::ItemType item_type,
|
||||
int bNeedHeight);
|
||||
#else
|
||||
void convertTrackToBullet (ssgEntity *track, sgMat4 m);
|
||||
void itemCommand(sgVec3 *xyz, int item_type, int bNeedHeight);
|
||||
#endif
|
||||
void loadDriveline();
|
||||
void readDrivelineFromFile(std::vector<Vec3>& line,
|
||||
const std::string& file_ext);
|
||||
#ifdef HAVE_IRRLICHT
|
||||
void convertTrackToBullet();
|
||||
#else
|
||||
void convertTrackToBullet(ssgEntity *track, sgMat4 m);
|
||||
#endif
|
||||
float pointSideToLine(const Vec3& L1, const Vec3& L2,
|
||||
const Vec3& P ) const;
|
||||
|
@ -132,7 +132,7 @@ void TrackManager::loadTrackList ()
|
||||
{
|
||||
// getTrackFile appends dir, so it's opening: *dir/*dir.track
|
||||
#ifdef HAVE_IRRLICHT
|
||||
config_file = file_manager->getTrackFile((*dir)+".scene");
|
||||
config_file = file_manager->getTrackFile((*dir)+".irrtrack");
|
||||
#else
|
||||
config_file = file_manager->getTrackFile((*dir)+".track");
|
||||
#endif
|
||||
|
@ -36,6 +36,9 @@ private:
|
||||
void setPitchRoll(const Vec3 &normal);
|
||||
|
||||
public:
|
||||
#ifdef HAVE_IRRLICHT
|
||||
inline Vec3(const core::vector3df &v) : btVector3(v.X, v.Y, v.Z) {}
|
||||
#endif
|
||||
inline Vec3(sgVec3 a) : btVector3(a[0], a[1], a[2]) {}
|
||||
inline Vec3(const btVector3& a) : btVector3(a) {}
|
||||
inline Vec3() : btVector3() {}
|
||||
|
Loading…
Reference in New Issue
Block a user