2007-04-16
This commit is contained in:
parent
78c27f03c8
commit
e20673c2cd
59
blockanim.cpp
Normal file
59
blockanim.cpp
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#include "blockanim.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
BlockAnimCtrl::BlockAnimCtrl(const DataAnimVector & v) {
|
||||||
|
for (size_t i = 0; i < v.size(); i++) {
|
||||||
|
OpenGTA::GraphicsBase::LoadedAnim *da = v[i];
|
||||||
|
anims.push_back(new BlockAnim(da));
|
||||||
|
}
|
||||||
|
/* while (i != v.end()) {
|
||||||
|
OpenGTA::GraphicsBase::LoadedAnim * da = *i;
|
||||||
|
anims.push_back(new BlockAnim(da));
|
||||||
|
i++;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
BlockAnim* BlockAnimCtrl::getAnim(uint8_t area, uint8_t id) {
|
||||||
|
for (size_t i = 0; i < anims.size(); i++) {
|
||||||
|
if ((anims[i]->ad_ptr->which == area) && (anims[i]->ad_ptr->block == id)) {
|
||||||
|
return anims[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void BlockAnimCtrl::update(uint32_t ticks) {
|
||||||
|
for (size_t i = 0; i < anims.size(); i++)
|
||||||
|
anims[i]->update(ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
BlockAnimCtrl::~BlockAnimCtrl() {
|
||||||
|
for (size_t i = 0; i < anims.size(); i++) {
|
||||||
|
delete anims[i];
|
||||||
|
}
|
||||||
|
anims.clear();
|
||||||
|
}
|
||||||
|
}
|
59
blockanim.h
Normal file
59
blockanim.h
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#include "opengta.h"
|
||||||
|
#include "animation.h"
|
||||||
|
namespace OpenGTA {
|
||||||
|
class BlockAnim : public Util::Animation {
|
||||||
|
public:
|
||||||
|
BlockAnim(GraphicsBase::LoadedAnim * anim_data) :
|
||||||
|
// fix for STYLE001.G24 water anim seems one frame longer than data exists!
|
||||||
|
Util::Animation(
|
||||||
|
(anim_data->frameCount == 11 && anim_data->which == 1 ? anim_data->frameCount : anim_data->frameCount + 1),
|
||||||
|
5),
|
||||||
|
ad_ptr(anim_data) {
|
||||||
|
set(PLAY_FORWARD, LOOP);
|
||||||
|
/*
|
||||||
|
INFO << "ANIM: " << int(anim_data->block) << " " << int(anim_data->which)<< std::endl;
|
||||||
|
for (int i= 0; i < anim_data->frameCount; i++) {
|
||||||
|
INFO << "FRAME " << int(anim_data->frame[i]) << std::endl;
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
uint8_t getFrame(uint8_t num) {
|
||||||
|
return ad_ptr->frame[num];
|
||||||
|
}
|
||||||
|
GraphicsBase::LoadedAnim * ad_ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
class BlockAnimCtrl {
|
||||||
|
public:
|
||||||
|
typedef std::vector<GraphicsBase::LoadedAnim*> DataAnimVector;
|
||||||
|
typedef std::vector<BlockAnim*> BlockAnimVector;
|
||||||
|
BlockAnimCtrl(const DataAnimVector & v);
|
||||||
|
~BlockAnimCtrl();
|
||||||
|
void update(uint32_t ticks);
|
||||||
|
BlockAnim * getAnim(uint8_t area, uint8_t id);
|
||||||
|
private:
|
||||||
|
BlockAnimVector anims;
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#include "blockdata.h"
|
#include "blockdata.h"
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
float BlockData::slope_raw_data[numBlockTypes][numFaces][4][3] = {
|
float BlockData::slope_raw_data[numBlockTypes][numFaces][4][3] = {
|
||||||
|
22
blockdata.h
22
blockdata.h
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#ifndef OPENGTA_BLOCKDATA
|
#ifndef OPENGTA_BLOCKDATA
|
||||||
#define OPENGTA_BLOCKDATA
|
#define OPENGTA_BLOCKDATA
|
||||||
#include <cstddef>
|
#include <cstddef>
|
||||||
|
19
bugs.rec
Normal file
19
bugs.rec
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
Bug: style001.gry bridge texture artifacts
|
||||||
|
Image: http://skybound.portland.co.uk/ogta/bugs_in_transparent_texture_2006-10-03.jpg
|
||||||
|
black pixel inside a side texture (nyc.cmp)... thus begins the
|
||||||
|
'how many errors can there be about black vs. transparent contest'.
|
||||||
|
%%
|
||||||
|
Bug: wrong block texture coords
|
||||||
|
Image: http://lh6.google.com/image/under.northern.sky/RZnek0op0yI/AAAAAAAAAB4/zfCFvPS8gWg/still_slope_tex_errors_2007-01-01.jpg
|
||||||
|
Most likely the side that is a triangle and not a quad.
|
||||||
|
Needs research if 'flipping' the texture is related.
|
||||||
|
%%
|
||||||
|
Bug: transparent pixel in g24 tiles
|
||||||
|
Image: http://lh4.google.com/image/under.northern.sky/Rh58SCRd8kI/AAAAAAAAAEQ/FK6KLriTfOs/nyc_gry_block_transparent_pixel_bug_2007-04-12.jpg
|
||||||
|
Those should probably just be black. It is not a very obvious
|
||||||
|
error, but it should be fixed.
|
||||||
|
%%
|
||||||
|
Bug: black border around sprites
|
||||||
|
Image: http://lh4.google.com/image/under.northern.sky/Rh58SCRd8lI/AAAAAAAAAEY/tnMwSk8IVok/g24_obj_black_border_2007-04-12.jpg
|
||||||
|
Simply doesn't look good, especially with g24 graphics.
|
||||||
|
%%
|
@ -91,3 +91,11 @@ void Matrix3D::Translate(const Vector3D & v)
|
|||||||
m[3][1] += v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1];
|
m[3][1] += v.x * m[0][1] + v.y * m[1][1] + v.z * m[2][1];
|
||||||
m[3][2] += v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2];
|
m[3][2] += v.x * m[0][2] + v.y * m[1][2] + v.z * m[2][2];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Matrix3D::RotZ(float angle) {
|
||||||
|
const float TO_RAD = M_PI / 180.0f;
|
||||||
|
m[0][0] = cosf(angle*TO_RAD);
|
||||||
|
m[1][0] = sinf(angle*TO_RAD);
|
||||||
|
m[0][1] = -sinf(angle*TO_RAD);
|
||||||
|
m[1][1] = cosf(angle*TO_RAD);
|
||||||
|
}
|
||||||
|
@ -140,6 +140,7 @@ struct Matrix3D
|
|||||||
|
|
||||||
float operator() (int i, int j) const { return m[i][j]; }
|
float operator() (int i, int j) const { return m[i][j]; }
|
||||||
float& operator() (int i, int j) { return m[i][j]; }
|
float& operator() (int i, int j) { return m[i][j]; }
|
||||||
|
void RotZ(float v);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Plane
|
struct Plane
|
||||||
|
27
datahelper.cpp
Normal file
27
datahelper.cpp
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
#include "datahelper.h"
|
||||||
|
#include "opengta.h"
|
||||||
|
#include "cistring.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
namespace Helper {
|
||||||
|
// level-filename to index-into-message-db
|
||||||
|
// needed for area-name lookup
|
||||||
|
size_t mapFileName2Number(const std::string & file) {
|
||||||
|
size_t num = 0;
|
||||||
|
Util::ci_string ci_file(file.c_str());
|
||||||
|
#define STRING_TEST(n) ci_file.find(n) != std::string::npos
|
||||||
|
if (STRING_TEST("nyc.cmp"))
|
||||||
|
num = 1;
|
||||||
|
else if (STRING_TEST("sanb.cmp"))
|
||||||
|
num = 2;
|
||||||
|
else if (STRING_TEST("miami.cmp"))
|
||||||
|
num = 3;
|
||||||
|
else
|
||||||
|
ERROR << "unknown level: " << file << std::endl;
|
||||||
|
#undef STRING_TEST
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
7
datahelper.h
Normal file
7
datahelper.h
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
#include <string>
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
namespace Helper {
|
||||||
|
size_t mapFileName2Number(const std::string & file);
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -34,7 +34,8 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<> GraphicsBase & ActiveStyle::get() {
|
template<> GraphicsBase & ActiveStyle::get() {
|
||||||
assert(m_data);
|
if (!m_data)
|
||||||
|
throw E_NOTSUPPORTED("Load a style-file first!");
|
||||||
return *m_data;
|
return *m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -81,7 +82,8 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
template<> Map & ActiveMap::get() {
|
template<> Map & ActiveMap::get() {
|
||||||
assert(m_data);
|
if (!m_data)
|
||||||
|
throw E_NOTSUPPORTED("Load a map-file first!");
|
||||||
return *m_data;
|
return *m_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,4 +99,30 @@ namespace OpenGTA {
|
|||||||
assert(m_data);
|
assert(m_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<> MainMsgLookup::ActiveData() {
|
||||||
|
m_data = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> MainMsgLookup::~ActiveData() {
|
||||||
|
unload();
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> MessageDB & MainMsgLookup::get() {
|
||||||
|
if (!m_data)
|
||||||
|
throw E_NOTSUPPORTED("Load a message-file first!");
|
||||||
|
return *m_data;
|
||||||
|
}
|
||||||
|
|
||||||
|
template<> void MainMsgLookup::load(const std::string & file) {
|
||||||
|
unload();
|
||||||
|
try {
|
||||||
|
m_data = new MessageDB(file);
|
||||||
|
}
|
||||||
|
catch (const Exception & e) {
|
||||||
|
ERROR << "loading message-db failed: " << e.what();
|
||||||
|
m_data = 0;
|
||||||
|
}
|
||||||
|
assert(m_data);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
36
dataholder.h
36
dataholder.h
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -28,18 +28,11 @@
|
|||||||
#include "Singleton.h"
|
#include "Singleton.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
/*
|
/** Wrapper around resource-holding classes.
|
||||||
class ActiveStyle {
|
* - you have to call 'load' before 'get'
|
||||||
public:
|
*
|
||||||
ActiveStyle();
|
* - you may call load repeatedly
|
||||||
~ActiveStyle();
|
*/
|
||||||
GraphicsBase & getStyle();
|
|
||||||
void load(const std::string & file);
|
|
||||||
private:
|
|
||||||
void unload();
|
|
||||||
GraphicsBase* m_style;
|
|
||||||
};
|
|
||||||
*/
|
|
||||||
template <class T>
|
template <class T>
|
||||||
class ActiveData {
|
class ActiveData {
|
||||||
public:
|
public:
|
||||||
@ -52,13 +45,30 @@ namespace OpenGTA {
|
|||||||
T* m_data;
|
T* m_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** The wrapper around the GRY/G24 data interface.
|
||||||
|
*/
|
||||||
typedef ActiveData< GraphicsBase > ActiveStyle;
|
typedef ActiveData< GraphicsBase > ActiveStyle;
|
||||||
|
/** The wrapper around the map data interface.
|
||||||
|
*/
|
||||||
typedef ActiveData< Map > ActiveMap;
|
typedef ActiveData< Map > ActiveMap;
|
||||||
|
/** The wrapper around the message-string data interface.
|
||||||
|
*/
|
||||||
|
typedef ActiveData< MessageDB > MainMsgLookup;
|
||||||
|
|
||||||
|
/** Singleton: Graphics
|
||||||
|
*/
|
||||||
typedef Loki::SingletonHolder< ActiveStyle, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
typedef Loki::SingletonHolder< ActiveStyle, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||||
Loki::SingleThreaded> StyleHolder;
|
Loki::SingleThreaded> StyleHolder;
|
||||||
|
/** Singleton: Map
|
||||||
|
*/
|
||||||
typedef Loki::SingletonHolder< ActiveMap, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
typedef Loki::SingletonHolder< ActiveMap, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||||
Loki::SingleThreaded> MapHolder;
|
Loki::SingleThreaded> MapHolder;
|
||||||
|
/** Singleton: Message strings
|
||||||
|
*/
|
||||||
|
typedef Loki::SingletonHolder< MainMsgLookup, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||||
|
Loki::SingleThreaded> MainMsgHolder;
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -17,6 +17,7 @@ Corrections and Notes regarding DMA GTA technical doument [cds.doc v12.10]
|
|||||||
http://www.fifengr.com/gtacars/topic.html
|
http://www.fifengr.com/gtacars/topic.html
|
||||||
|
|
||||||
--- other links ---
|
--- other links ---
|
||||||
|
|
||||||
A Stream-based Time Synchronization Technique For Networked Computer Games
|
A Stream-based Time Synchronization Technique For Networked Computer Games
|
||||||
http://www.mine-control.com/zack/timesync/timesync.html
|
http://www.mine-control.com/zack/timesync/timesync.html
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ the most important formats.
|
|||||||
Reading _(cds.doc) is probably vital; you may want them all.
|
Reading _(cds.doc) is probably vital; you may want them all.
|
||||||
So in no particular order:
|
So in no particular order:
|
||||||
|
|
||||||
include(`doc/doc_links.txt')dnl ~oh m4, your glorious thing~
|
include(`doc/doc_links.txt')dnl ~oh m4, you glorious thing~
|
||||||
|
|
||||||
Support for the following formats is implemented:
|
Support for the following formats is implemented:
|
||||||
- CMP (compressed map) #OpenGTA::Map
|
- CMP (compressed map) #OpenGTA::Map
|
||||||
@ -68,12 +68,14 @@ using the graphics loaded inside a derived instance of
|
|||||||
CityView maintains a couple of #OpenGL::TextureCache (s) to store the
|
CityView maintains a couple of #OpenGL::TextureCache (s) to store the
|
||||||
texture-ids (for the static city blocks).
|
texture-ids (for the static city blocks).
|
||||||
|
|
||||||
|
In case of animated block textures #OpenGTA::BlockAnim and
|
||||||
|
#OpenGTA::BlockAnimCtrl are used to display a sequence of textures.
|
||||||
|
|
||||||
#OpenGTA::BlockData contains the vertex data and texture coords for
|
#OpenGTA::BlockData contains the vertex data and texture coords for
|
||||||
each of the of the possible blocks; this corresponds to
|
each of the of the possible blocks; this corresponds to
|
||||||
#OpenGTA::Map::BlockInfo::slopeType.
|
#OpenGTA::Map::BlockInfo::slopeType.
|
||||||
|
|
||||||
Drawing of objects (sprites) is being moved into #OpenGTA::SpriteManager,
|
Drawing of objects (sprites) is done in #OpenGTA::SpriteManager.
|
||||||
though this is not yet complete.
|
|
||||||
|
|
||||||
#OpenGL::DrawableFont can display strings using the bitmaps from
|
#OpenGL::DrawableFont can display strings using the bitmaps from
|
||||||
a #OpenGTA::Font.
|
a #OpenGTA::Font.
|
||||||
|
198
entity_controller.cpp
Normal file
198
entity_controller.cpp
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#include "entity_controller.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
EntityController::EntityController() :
|
||||||
|
rawData(0),
|
||||||
|
dataSet(sizeof(rawData) * 8, (unsigned char*)&rawData) {}
|
||||||
|
|
||||||
|
EntityController::EntityController(const EntityController & other) :
|
||||||
|
rawData(other.rawData),
|
||||||
|
dataSet(sizeof(rawData) * 8, (unsigned char*)&rawData) {}
|
||||||
|
|
||||||
|
void EntityController::zero() {
|
||||||
|
rawData = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EntityController::setRaw(Storage_T v) {
|
||||||
|
rawData = v;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setTurnLeft(bool press) {
|
||||||
|
dataSet.set_item(0, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setTurnRight(bool press) {
|
||||||
|
dataSet.set_item(1, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setMoveForward(bool press) {
|
||||||
|
dataSet.set_item(2, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setMoveBack(bool press) {
|
||||||
|
dataSet.set_item(3, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setAction(bool press) {
|
||||||
|
dataSet.set_item(4, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setJump(bool press) {
|
||||||
|
dataSet.set_item(5, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setFireWeapon(bool press) {
|
||||||
|
dataSet.set_item(6, press);
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char PedController::getTurn() {
|
||||||
|
if (dataSet.get_item(0) && dataSet.get_item(1)) // special: straight ahead
|
||||||
|
return 0;
|
||||||
|
if (dataSet.get_item(0))
|
||||||
|
return 1;
|
||||||
|
else if (dataSet.get_item(1))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
signed char PedController::getMove() {
|
||||||
|
if (dataSet.get_item(2) && dataSet.get_item(3)) // special: evens out
|
||||||
|
return 0;
|
||||||
|
if (dataSet.get_item(2))
|
||||||
|
return 1;
|
||||||
|
else if (dataSet.get_item(3))
|
||||||
|
return -1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PedController::getAction() {
|
||||||
|
return dataSet.get_item(4);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PedController::getJump() {
|
||||||
|
return dataSet.get_item(5);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PedController::getFireWeapon() {
|
||||||
|
return dataSet.get_item(6);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setRunning(bool yes) {
|
||||||
|
dataSet.set_item(7, yes);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool PedController::getRunning() {
|
||||||
|
return dataSet.get_item(7);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char PedController::getActiveWeapon() {
|
||||||
|
// 0 .. k
|
||||||
|
unsigned char r = 0;
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
if (dataSet.get_item(j + 8))
|
||||||
|
r += (1 << j);
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
void PedController::setActiveWeapon(unsigned char k) {
|
||||||
|
if (k > 7) {
|
||||||
|
throw E_OUTOFRANGE("foo");
|
||||||
|
}
|
||||||
|
for (int j = 0; j < 3; ++j) {
|
||||||
|
if (k & 1u)
|
||||||
|
dataSet.set_item(j + 8, true);
|
||||||
|
else
|
||||||
|
dataSet.set_item(j + 8, false);
|
||||||
|
k >>= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include <SDL_events.h>
|
||||||
|
#include "localplayer.h"
|
||||||
|
class ConfigurableKeyConsumer {
|
||||||
|
static const SDLKey sym_array[];
|
||||||
|
static const int TURN_LEFT = 0;
|
||||||
|
static const int TURN_RIGHT = 1;
|
||||||
|
static const int MOVE_FORWARD = 2;
|
||||||
|
static const int MOVE_BACKWARD = 3;
|
||||||
|
public:
|
||||||
|
void handle(const SDL_keysym & ks, bool press) {
|
||||||
|
PedController & pc = LocalPlayer::Instance().getCtrl();
|
||||||
|
if (ks.sym == sym_array[TURN_LEFT]) {
|
||||||
|
pc.setTurnLeft(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (ks.sym == sym_array[TURN_RIGHT]) {
|
||||||
|
pc.setTurnRight(true);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
#include <SDL_events.h>
|
||||||
|
#include "localplayer.h"
|
||||||
|
|
||||||
|
template <class ENTITY>
|
||||||
|
class ClassicKeyConsumer {
|
||||||
|
public:
|
||||||
|
bool handle(const SDL_keysym & ks, bool press);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <> bool ClassicKeyConsumer<PedController>::handle(const SDL_keysym & ks, bool press) {
|
||||||
|
bool swallow_event = true;
|
||||||
|
PedController & pc = LocalPlayer::Instance().getEntity().m_control;
|
||||||
|
switch(ks.sym) {
|
||||||
|
case SDLK_LEFT:
|
||||||
|
pc.setTurnLeft(press);
|
||||||
|
break;
|
||||||
|
case SDLK_RIGHT:
|
||||||
|
pc.setTurnRight(press);
|
||||||
|
break;
|
||||||
|
case SDLK_UP:
|
||||||
|
pc.setMoveForward(press);
|
||||||
|
break;
|
||||||
|
case SDLK_DOWN:
|
||||||
|
pc.setMoveBack(press);
|
||||||
|
break;
|
||||||
|
case SDLK_RETURN:
|
||||||
|
pc.setAction(press);
|
||||||
|
break;
|
||||||
|
case SDLK_SPACE:
|
||||||
|
pc.setJump(press);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
swallow_event = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return swallow_event;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
102
entity_controller.h
Normal file
102
entity_controller.h
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#ifndef OBJECT_CONTROLLER_H
|
||||||
|
#define OBJECT_CONTROLLER_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "set.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
class EntityController {
|
||||||
|
public:
|
||||||
|
EntityController();
|
||||||
|
|
||||||
|
void zero();
|
||||||
|
typedef uint32_t Storage_T;
|
||||||
|
void setRaw(Storage_T v);
|
||||||
|
protected:
|
||||||
|
EntityController(const EntityController & other);
|
||||||
|
Storage_T rawData;
|
||||||
|
Util::Set dataSet;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pedestrian;
|
||||||
|
class PedController : public EntityController {
|
||||||
|
public:
|
||||||
|
PedController() {}
|
||||||
|
PedController(const PedController & other) : EntityController(other) {}
|
||||||
|
void setTurnLeft(bool press = true);
|
||||||
|
inline void releaseTurnLeft() { setTurnLeft(false); }
|
||||||
|
void setTurnRight(bool press = true);
|
||||||
|
inline void releaseTurnRight() { setTurnRight(false); }
|
||||||
|
signed char getTurn();
|
||||||
|
void setMoveForward(bool press = true);
|
||||||
|
inline void releaseMoveForward() { setMoveForward(false); }
|
||||||
|
void setMoveBack(bool press = true);
|
||||||
|
inline void releaseMoveBack() { setMoveBack(false); }
|
||||||
|
signed char getMove();
|
||||||
|
void setAction(bool press = true);
|
||||||
|
inline void releaseAction() { setAction(false); }
|
||||||
|
bool getAction();
|
||||||
|
// bool getAction();
|
||||||
|
void setJump(bool press = true);
|
||||||
|
inline void releaseJump() { setJump(false); }
|
||||||
|
bool getJump();
|
||||||
|
// bool getJump();
|
||||||
|
void setFireWeapon(bool press = true);
|
||||||
|
inline void releaseFireWeapon() { setFireWeapon(false); }
|
||||||
|
bool getFireWeapon();
|
||||||
|
|
||||||
|
void setActiveWeapon(unsigned char);
|
||||||
|
unsigned char getActiveWeapon();
|
||||||
|
|
||||||
|
void setRunning(bool yes = true);
|
||||||
|
inline void releaseRunning() { setRunning(false); }
|
||||||
|
bool getRunning();
|
||||||
|
|
||||||
|
// weapons, equip, shoot
|
||||||
|
};
|
||||||
|
|
||||||
|
class VehicleController : public EntityController {
|
||||||
|
public:
|
||||||
|
VehicleController() {}
|
||||||
|
VehicleController(const VehicleController & other) : EntityController(other) {}
|
||||||
|
void setTurnLeft(bool press = true);
|
||||||
|
inline void releaseTurnLeft() { setTurnLeft(false); }
|
||||||
|
void setTurnRight(bool press = true);
|
||||||
|
inline void releaseTurnRight() { setTurnRight(false); }
|
||||||
|
void setAccelerate(bool press = true);
|
||||||
|
inline void releaseAccelerate() { setAccelerate(false); }
|
||||||
|
void setReverse(bool press = true);
|
||||||
|
inline void releaseReverse() { setReverse(false); }
|
||||||
|
void setHandbrake(bool press = true);
|
||||||
|
inline void releaseHandbrake() { setHandbrake(false); }
|
||||||
|
void setAction(bool press = true);
|
||||||
|
inline void releaseAction() { setAction(false); }
|
||||||
|
|
||||||
|
// vehicle specials
|
||||||
|
};
|
||||||
|
|
||||||
|
// HeliController?
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#include "font_cache.h"
|
#include "font_cache.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
@ -5,6 +27,10 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FontCache::~FontCache() {
|
FontCache::~FontCache() {
|
||||||
|
for (FontMap::iterator i = loadedFonts.begin(); i != loadedFonts.end(); i++) {
|
||||||
|
delete i->second;
|
||||||
|
}
|
||||||
|
loadedFonts.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
OpenGL::DrawableFont & FontCache::getFont(const std::string & file,
|
OpenGL::DrawableFont & FontCache::getFont(const std::string & file,
|
||||||
|
22
font_cache.h
22
font_cache.h
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#ifndef FONT_CACHE_H
|
#ifndef FONT_CACHE_H
|
||||||
#define FONT_CACHE_H
|
#define FONT_CACHE_H
|
||||||
#include <string>
|
#include <string>
|
||||||
|
2
fx_sdt.h
2
fx_sdt.h
@ -5,7 +5,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -20,80 +20,21 @@
|
|||||||
* 3. This notice may not be removed or altered from any source *
|
* 3. This notice may not be removed or altered from any source *
|
||||||
* distribution. *
|
* distribution. *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include "pedestrian.h"
|
#include "game_objects.h"
|
||||||
#include "spritemanager.h"
|
#include "spritemanager.h"
|
||||||
#include "opengta.h"
|
|
||||||
#include "dataholder.h"
|
#include "dataholder.h"
|
||||||
#include "log.h"
|
#include "cell_iterator.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "Functor.h"
|
||||||
|
|
||||||
|
#define INT2FLOAT_WRLD(c) (float(c >> 6) + float(c % 64) / 64.0f)
|
||||||
|
#define INT2F_DIV64(v) (float(v) / 64.0f)
|
||||||
|
#define INT2F_DIV128(v) (float(v) / 128.0f)
|
||||||
|
|
||||||
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
Projectile::Projectile(uint8_t id, float r, Vector3D p, Vector3D d, Uint32 now) :
|
float GameObject_common::heightOverTerrain(const Vector3D & v) {
|
||||||
typeId(id), rot(r), pos(p), delta(d), endsAtTick(now + 5000) {}
|
|
||||||
|
|
||||||
SpriteObject::Animation::Animation() :
|
|
||||||
Util::Animation(7, 7),
|
|
||||||
firstFrameOffset(0), moveSpeed(0.0f) {}
|
|
||||||
|
|
||||||
SpriteObject::Animation::Animation(const Animation & other) :
|
|
||||||
Util::Animation(other.numFrames, 1000 / other.delay),
|
|
||||||
firstFrameOffset(other.firstFrameOffset),
|
|
||||||
//numFrames(other.numFrames),
|
|
||||||
moveSpeed(other.moveSpeed) {}
|
|
||||||
|
|
||||||
SpriteObject::Animation::Animation(Uint16 foff, Uint8 num) :
|
|
||||||
Util::Animation(num, 7),
|
|
||||||
firstFrameOffset(foff), moveSpeed(0.0f) {}
|
|
||||||
|
|
||||||
SpriteObject::Animation::Animation(Uint16 foff, Uint8 num, float speed) :
|
|
||||||
Util::Animation(num, 7),
|
|
||||||
firstFrameOffset(foff), moveSpeed(speed) {}
|
|
||||||
|
|
||||||
SpriteObject::SpriteObject(const Vector3D & p) :
|
|
||||||
pos(p), //animRef(&SpriteManagerHolder::Instance().getAnimationById(0)) {
|
|
||||||
anim(SpriteManagerHolder::Instance().getAnimationById(0)) {
|
|
||||||
sprNum = 0;
|
|
||||||
remap = -1;
|
|
||||||
//curFrame = 0;
|
|
||||||
lastFrameUpdateAt = 0;
|
|
||||||
lastUpdateAt = 0;
|
|
||||||
rot = 0.0f;
|
|
||||||
animActive = false;
|
|
||||||
sprType = GraphicsBase::SpriteNumbers::ARROW;
|
|
||||||
}
|
|
||||||
|
|
||||||
Uint8 SpriteObject::calcCurrentFrame(Uint32 ticks) {
|
|
||||||
Uint32 delta = ticks - lastFrameUpdateAt;
|
|
||||||
//assert(animRef);
|
|
||||||
if (delta > 100) {
|
|
||||||
//curFrame += 1;
|
|
||||||
//INFO << "new frame: " << int(curFrame) << " total: " << sprNum + curFrame + anim.firstFrameOffset << std::endl;
|
|
||||||
lastFrameUpdateAt = ticks;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
if (curFrame > anim.numFrames)
|
|
||||||
curFrame = 0;
|
|
||||||
*/
|
|
||||||
return 0;//curFrame;
|
|
||||||
}
|
|
||||||
|
|
||||||
SpriteObject::SpriteObject(const SpriteObject & other) :
|
|
||||||
pos(other.pos), anim(other.anim) {
|
|
||||||
copyValues(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void SpriteObject::copyValues(const SpriteObject & other) {
|
|
||||||
sprNum = other.sprNum;
|
|
||||||
//curFrame = other.curFrame;
|
|
||||||
remap = other.remap;
|
|
||||||
lastFrameUpdateAt = other.lastFrameUpdateAt;
|
|
||||||
lastUpdateAt = other.lastUpdateAt;
|
|
||||||
rot = other.rot;
|
|
||||||
sprType = other.sprType;
|
|
||||||
animActive = other.animActive;
|
|
||||||
}
|
|
||||||
|
|
||||||
float SpriteObject::heightOverTerrain(const Vector3D & v) {
|
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
x = floor(v.x);
|
x = floor(v.x);
|
||||||
y = floor(v.y);
|
y = floor(v.y);
|
||||||
@ -102,9 +43,18 @@ namespace OpenGTA {
|
|||||||
x_b = (PHYSFS_uint8)x;
|
x_b = (PHYSFS_uint8)x;
|
||||||
z_b = (PHYSFS_uint8)z;
|
z_b = (PHYSFS_uint8)z;
|
||||||
if (y < 0.0f) {
|
if (y < 0.0f) {
|
||||||
ERROR << "Below level! at coords: " << v.x << ", " << v.y << ", " << v.z << std::endl;
|
//ERROR << "Below level! at coords: " << v.x << ", " << v.y << ", " << v.z << std::endl;
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
if (x < 0 || x > 255 || z < 0 || z > 255) {
|
||||||
|
//ERROR << "x = " << x << "(" << v.x << ") z = " << z << " (" << v.z << ")" << std::endl;
|
||||||
|
throw E_OUTOFRANGE("invalid x/z pos");
|
||||||
|
}
|
||||||
|
if (y > 20) {
|
||||||
|
INFO << y << " seems a bit high; going to 20" << std::endl;
|
||||||
|
INFO << x << " " << z << std::endl;
|
||||||
|
y = 20;
|
||||||
|
}
|
||||||
OpenGTA::Map & map = OpenGTA::MapHolder::Instance().get();
|
OpenGTA::Map & map = OpenGTA::MapHolder::Instance().get();
|
||||||
while (y >= map.getNumBlocksAtNew(x_b, z_b) && y > 0.0f)
|
while (y >= map.getNumBlocksAtNew(x_b, z_b) && y > 0.0f)
|
||||||
y -= 1.0f;
|
y -= 1.0f;
|
||||||
@ -135,75 +85,184 @@ namespace OpenGTA {
|
|||||||
return 1.0f;
|
return 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
Pedestrian::Pedestrian(const Vector3D & e,
|
Sprite::Animation::Animation() :
|
||||||
const Vector3D & p) : SpriteObject(p),
|
Util::Animation(7, 7),
|
||||||
OBox(RollMatrix3D(0), e * 0.5f) {
|
firstFrameOffset(0), moveSpeed(0.0f) {}
|
||||||
m_M.Translate(p);
|
|
||||||
pedId = 0;
|
|
||||||
m_control = 0;
|
|
||||||
animId = 0;
|
|
||||||
inGroundContact = 0;
|
|
||||||
sprType = GraphicsBase::SpriteNumbers::PED;
|
|
||||||
activeWeapon = 0;
|
|
||||||
speedForces = Vector3D(0, 0, 0);
|
|
||||||
weaponReloadedAt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pedestrian::Pedestrian(const Vector3D & e,
|
Sprite::Animation::Animation(const Animation & other) :
|
||||||
const Vector3D & p, const Uint32 & asId) : SpriteObject(p),
|
//Util::Animation(other.numFrames, 1000 / other.delay),
|
||||||
OBox(RollMatrix3D(0), e * 0.5f) {
|
Util::Animation(other),
|
||||||
m_M.Translate(p);
|
firstFrameOffset(other.firstFrameOffset),
|
||||||
pedId = asId;
|
//numFrames(other.numFrames),
|
||||||
m_control = 0;
|
moveSpeed(other.moveSpeed) {
|
||||||
animId = 0;
|
set(other.get(), other.getDone());
|
||||||
inGroundContact = 0;
|
}
|
||||||
sprType = GraphicsBase::SpriteNumbers::PED;
|
|
||||||
activeWeapon = 0;
|
|
||||||
speedForces = Vector3D(0, 0, 0);
|
|
||||||
weaponReloadedAt = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Pedestrian::Pedestrian(const Pedestrian & other) : SpriteObject(other),
|
Sprite::Animation::Animation(Uint16 foff, Uint8 num) :
|
||||||
OBox(other.m_M, other.m_Extent) {
|
Util::Animation(num, 7),
|
||||||
//animRef(SpriteManagerHolder::Instance().getAnimationById(other.animId)) {
|
firstFrameOffset(foff), moveSpeed(0.0f) {}
|
||||||
copyValues(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pedestrian::switchToAnim(const Uint32 & newId) {
|
Sprite::Animation::Animation(Uint16 foff, Uint8 num, float speed) :
|
||||||
|
Util::Animation(num, 7),
|
||||||
|
firstFrameOffset(foff), moveSpeed(speed) {}
|
||||||
|
|
||||||
|
Sprite::Sprite() :
|
||||||
|
sprNum(0), remap(-1),
|
||||||
|
//anim(SpriteManagerHolder::Instance().getAnimationById(0)),
|
||||||
|
anim(), animId(),
|
||||||
|
sprType(GraphicsBase::SpriteNumbers::ARROW) {
|
||||||
|
}
|
||||||
|
|
||||||
|
Sprite::Sprite(Uint16 sprN, Sint16 rem, GraphicsBase::SpriteNumbers::SpriteTypes sprT) :
|
||||||
|
sprNum(sprN), remap(rem),
|
||||||
|
anim(), animId(),
|
||||||
|
sprType(sprT) {}
|
||||||
|
|
||||||
|
Sprite::Sprite(const Sprite & other) :
|
||||||
|
sprNum(other.sprNum), remap(other.remap), anim(other.anim), animId(other.animId),
|
||||||
|
sprType(other.sprType) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void Sprite::switchToAnim(const Uint32 & newId) {
|
||||||
|
INFO << "switching to anim " << newId << std::endl;
|
||||||
anim = Animation(SpriteManagerHolder::Instance().getAnimationById(newId));
|
anim = Animation(SpriteManagerHolder::Instance().getAnimationById(newId));
|
||||||
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||||
animId = newId;
|
animId = newId;
|
||||||
//curFrame = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void SpriteObject::setAnimation(Animation & otherAnim) {
|
Pedestrian::Pedestrian(Vector3D e, const Vector3D & p, uint32_t id, Sint16 remapId) :
|
||||||
anim = Animation(otherAnim);
|
GameObject_common(p),
|
||||||
//curFrame = 0;
|
Sprite(0, remapId, GraphicsBase::SpriteNumbers::PED),
|
||||||
// FIXME: animId?
|
OBox(TranslateMatrix3D(p), e * 0.5f),
|
||||||
|
m_control(),
|
||||||
|
speedForces(0, 0, 0) {
|
||||||
|
m_M = TranslateMatrix3D(p);
|
||||||
|
m_M.RotZ(rot);
|
||||||
|
pedId = id;
|
||||||
|
animId = 0;
|
||||||
|
isDead = 0;
|
||||||
|
lastUpdateAt = TimerHolder::Instance().getRealTime();
|
||||||
|
inGroundContact = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Pedestrian::Pedestrian(const Pedestrian & other) :
|
||||||
|
GameObject_common(other), Sprite(other), OBox(other),
|
||||||
|
|
||||||
|
pedId(other.pedId),
|
||||||
|
m_control(),
|
||||||
|
speedForces(other.speedForces) {
|
||||||
|
lastUpdateAt = other.lastUpdateAt;
|
||||||
|
inGroundContact = other.inGroundContact;
|
||||||
|
animId = other.animId;
|
||||||
|
isDead = other.isDead;
|
||||||
|
m_M = TranslateMatrix3D(other.pos);
|
||||||
|
m_M.RotZ(other.rot);
|
||||||
|
}
|
||||||
|
|
||||||
|
extern void ai_step_fake(Pedestrian*);
|
||||||
|
void Pedestrian::update(Uint32 ticks) {
|
||||||
|
if (isDead) {
|
||||||
|
anim.update(ticks);
|
||||||
|
lastUpdateAt = ticks;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (pedId < 0xffffffff)
|
||||||
|
ai_step_fake(this);
|
||||||
|
uint8_t activeWeapon = m_control.getActiveWeapon();
|
||||||
|
switch(m_control.getMove()) {
|
||||||
|
case 1:
|
||||||
|
//if (!(animId == 2u + activeWeapon*3))
|
||||||
|
// switchToAnim(2 + activeWeapon*3);
|
||||||
|
if (m_control.getRunning()) {
|
||||||
|
if (!(animId == 3u + activeWeapon*3))
|
||||||
|
switchToAnim(3 + activeWeapon*3);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (!(animId == 2u + activeWeapon*2))
|
||||||
|
switchToAnim(2 + activeWeapon*2);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
/*
|
||||||
|
case 2:
|
||||||
|
if (!(animId == 3u + activeWeapon*3))
|
||||||
|
switchToAnim(3 + activeWeapon*3);
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
case 0:
|
||||||
|
if (!(animId == 1u + activeWeapon*3))
|
||||||
|
switchToAnim(1 + activeWeapon*3);
|
||||||
|
break;
|
||||||
|
case -1:
|
||||||
|
if (!(animId == 2u + activeWeapon*3)) {
|
||||||
|
switchToAnim(2 + activeWeapon*3);
|
||||||
|
anim.set(Util::Animation::PLAY_BACKWARD, Util::Animation::LOOP);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
anim.update(ticks);
|
||||||
|
Uint32 delta = ticks - lastUpdateAt;
|
||||||
|
//INFO << "delta = " << delta << " t: " << ticks << " lt: " << lastUpdateAt << std::endl;
|
||||||
|
Vector3D moveDelta(0, 0, 0);
|
||||||
|
switch(m_control.getTurn()) {
|
||||||
|
case -1:
|
||||||
|
rot -= 0.2f * delta;
|
||||||
|
//INFO << "rot: "<< rot << std::endl;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
rot += 0.2f * delta;
|
||||||
|
//INFO << "rot: "<< rot << std::endl;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (rot >= 360.0f)
|
||||||
|
rot -= 360.0f;
|
||||||
|
if (rot < 0.0f)
|
||||||
|
rot += 360.0f;
|
||||||
|
switch(m_control.getMove()) {
|
||||||
|
case -1:
|
||||||
|
moveDelta.x -= sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
moveDelta.z -= cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
moveDelta.x += sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
moveDelta.z += cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
moveDelta.x += sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
moveDelta.z += cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
tryMove(pos + moveDelta);
|
||||||
|
if (!inGroundContact) {
|
||||||
|
speedForces.y += 0.0005f *delta;
|
||||||
|
pos.y -= speedForces.y;
|
||||||
|
if (speedForces.y < 0.2f)
|
||||||
|
INFO << "bridge step? height: " << pos.y << " speed: " << speedForces.y << std::endl;
|
||||||
|
else
|
||||||
|
INFO << "FALLING " << pos.y << " speed " << speedForces.y << std::endl;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (speedForces.y > 0.1)
|
||||||
|
INFO << "impacting with speed: " << speedForces.y << std::endl;
|
||||||
|
speedForces.y = 0.0f;
|
||||||
|
}
|
||||||
|
m_M = TranslateMatrix3D(pos);
|
||||||
|
m_M.RotZ(rot);
|
||||||
|
if (m_control.getFireWeapon() && ticks - lastWeaponTick > 400) {
|
||||||
|
Vector3D d1(
|
||||||
|
//Vector3D(-cos(rot * M_PI/180.0f), 0, sin(rot * M_PI/180.0f)).Normalized() * 0.05f
|
||||||
|
Vector3D(sin(rot * M_PI/180.0f), 0, cos(rot * M_PI/180.0f)).Normalized() * 0.01f
|
||||||
|
);
|
||||||
|
SpriteManagerHolder::Instance().createProjectile(0, rot, pos, d1, ticks, pedId);
|
||||||
|
lastWeaponTick = ticks;
|
||||||
|
}
|
||||||
|
//INFO << pos.x << " " << pos.y << " " << pos.z << std::endl;
|
||||||
|
lastUpdateAt = ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pedestrian::copyValues(const Pedestrian & other) {
|
void Pedestrian::tryMove(Vector3D nPos) {
|
||||||
|
|
||||||
m_control = other.m_control;
|
|
||||||
animId = other.animId;
|
|
||||||
pedId = other.pedId;
|
|
||||||
inGroundContact = other.inGroundContact;
|
|
||||||
sprType = other.sprType;
|
|
||||||
speedForces = other.speedForces;
|
|
||||||
activeWeapon = other.activeWeapon;
|
|
||||||
inventory = other.inventory;
|
|
||||||
weaponReloadedAt = other.weaponReloadedAt;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pedestrian::giveItem(uint8_t id, uint32_t amount) {
|
|
||||||
InventoryType::iterator i = inventory.find(id);
|
|
||||||
if (i == inventory.end())
|
|
||||||
inventory[id] = amount;
|
|
||||||
else
|
|
||||||
i->second += amount;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Pedestrian::tryMove(Vector3D nPos) {
|
|
||||||
float x, y, z;
|
float x, y, z;
|
||||||
x = floor(nPos.x);
|
x = floor(nPos.x);
|
||||||
y = floor(nPos.y);
|
y = floor(nPos.y);
|
||||||
@ -212,7 +271,7 @@ namespace OpenGTA {
|
|||||||
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
||||||
//INFO << heightOverTerrain(nPos) << std::endl;
|
//INFO << heightOverTerrain(nPos) << std::endl;
|
||||||
float hot = heightOverTerrain(nPos);
|
float hot = heightOverTerrain(nPos);
|
||||||
if (hot > 0.3f)
|
if (hot > 0.1f)
|
||||||
inGroundContact = 0;
|
inGroundContact = 0;
|
||||||
else if (hot < 0.0) {
|
else if (hot < 0.0) {
|
||||||
INFO << "gone below: " << hot << " at " << nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
INFO << "gone below: " << hot << " at " << nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
||||||
@ -222,6 +281,10 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inGroundContact = 1;
|
inGroundContact = 1;
|
||||||
|
if (isDead)
|
||||||
|
nPos.y -= hot - 0.05f;
|
||||||
|
else
|
||||||
|
nPos.y -= hot - 0.1f;
|
||||||
}
|
}
|
||||||
if (y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z)) && y > 0.0f) {
|
if (y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z)) && y > 0.0f) {
|
||||||
//INFO << x << ", " << y << ", " << z << ": " << int(map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z))) << std::endl;
|
//INFO << x << ", " << y << ", " << z << ": " << int(map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z))) << std::endl;
|
||||||
@ -259,7 +322,9 @@ namespace OpenGTA {
|
|||||||
nPos.x = pos.x;
|
nPos.x = pos.x;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "xblock left: " << x - pos.x << " tex: " << int(block->left) << std::endl;
|
INFO << "xblock left: " << x - pos.x << " tex: " << int(block->left) << std::endl;
|
||||||
|
#endif
|
||||||
if (x - pos.x > 0 && x - pos.x < 0.2f)
|
if (x - pos.x > 0 && x - pos.x < 0.2f)
|
||||||
nPos.x = pos.x;
|
nPos.x = pos.x;
|
||||||
else if (x - pos.x < 0 && x - pos.x > -0.2f)
|
else if (x - pos.x < 0 && x - pos.x > -0.2f)
|
||||||
@ -267,7 +332,9 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (block->right && block->isFlat() == false) {
|
if (block->right && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "xblock right: " << pos.x - x - 1 << " tex: " << int(block->right) << std::endl;
|
INFO << "xblock right: " << pos.x - x - 1 << " tex: " << int(block->right) << std::endl;
|
||||||
|
#endif
|
||||||
if (pos.x - x - 1 > 0 && pos.x - x - 1 < 0.2f) {
|
if (pos.x - x - 1 > 0 && pos.x - x - 1 < 0.2f) {
|
||||||
nPos.x = pos.x;
|
nPos.x = pos.x;
|
||||||
}
|
}
|
||||||
@ -276,14 +343,18 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
||||||
if (block->isFlat()) {
|
if (block->isFlat()) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top) << std::endl;
|
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top) << std::endl;
|
||||||
|
#endif
|
||||||
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
||||||
nPos.z = pos.z;
|
nPos.z = pos.z;
|
||||||
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
||||||
nPos.z = (nPos.z < pos.z) ? pos.z : nPos.z;
|
nPos.z = (nPos.z < pos.z) ? pos.z : nPos.z;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top)<< std::endl;
|
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top)<< std::endl;
|
||||||
|
#endif
|
||||||
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
||||||
nPos.z = pos.z;
|
nPos.z = pos.z;
|
||||||
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
||||||
@ -291,7 +362,9 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (block->bottom && block->isFlat() == false) {
|
if (block->bottom && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "zblock bottom: " << pos.z - z - 1<< " tex: " << int(block->bottom)<< std::endl;
|
INFO << "zblock bottom: " << pos.z - z - 1<< " tex: " << int(block->bottom)<< std::endl;
|
||||||
|
#endif
|
||||||
if (pos.z - z - 1 > 0 && pos.z - z - 1 < 0.2f) {
|
if (pos.z - z - 1 > 0 && pos.z - z - 1 < 0.2f) {
|
||||||
nPos.z = pos.z;
|
nPos.z = pos.z;
|
||||||
}
|
}
|
||||||
@ -301,7 +374,9 @@ namespace OpenGTA {
|
|||||||
if (x >= 1 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x-1), PHYSFS_uint8(z))) {
|
if (x >= 1 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x-1), PHYSFS_uint8(z))) {
|
||||||
block = map.getBlockAtNew(PHYSFS_uint8(x-1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
block = map.getBlockAtNew(PHYSFS_uint8(x-1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||||
if (block->right && block->isFlat() == false) {
|
if (block->right && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "xblock right: " << pos.x - x << " tex: " << int(block->right)<< std::endl;
|
INFO << "xblock right: " << pos.x - x << " tex: " << int(block->right)<< std::endl;
|
||||||
|
#endif
|
||||||
if (pos.x - x < 0.2f) {
|
if (pos.x - x < 0.2f) {
|
||||||
nPos.x = (nPos.x < pos.x ? pos.x : nPos.x);
|
nPos.x = (nPos.x < pos.x ? pos.x : nPos.x);
|
||||||
}
|
}
|
||||||
@ -310,7 +385,9 @@ namespace OpenGTA {
|
|||||||
if (x < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z))) {
|
if (x < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z))) {
|
||||||
block = map.getBlockAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
block = map.getBlockAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||||
if (block->left && graphics.isBlockingSide(block->left)) { // && block->isFlat() == false) {
|
if (block->left && graphics.isBlockingSide(block->left)) { // && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "xblock left: " << x + 1 - pos.x << " tex: " << int(block->left)<< std::endl;
|
INFO << "xblock left: " << x + 1 - pos.x << " tex: " << int(block->left)<< std::endl;
|
||||||
|
#endif
|
||||||
if (block->isFlat()) {
|
if (block->isFlat()) {
|
||||||
if (x + 1 - pos.x > 0 && x + 1 - pos.x < 0.2f)
|
if (x + 1 - pos.x > 0 && x + 1 - pos.x < 0.2f)
|
||||||
nPos.x = (nPos.x < pos.x ? nPos.x : pos.x);
|
nPos.x = (nPos.x < pos.x ? nPos.x : pos.x);
|
||||||
@ -324,7 +401,9 @@ namespace OpenGTA {
|
|||||||
if (z >= 1 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z-1))) {
|
if (z >= 1 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z-1))) {
|
||||||
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z-1), PHYSFS_uint8(y));
|
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z-1), PHYSFS_uint8(y));
|
||||||
if (block->bottom && block->isFlat() == false) {
|
if (block->bottom && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "zblock bottom: " << pos.z - z<< " tex: " << int(block->bottom)<< std::endl;
|
INFO << "zblock bottom: " << pos.z - z<< " tex: " << int(block->bottom)<< std::endl;
|
||||||
|
#endif
|
||||||
if (pos.z - z < 0.2f) {
|
if (pos.z - z < 0.2f) {
|
||||||
nPos.z = (nPos.z < pos.z ? pos.z : nPos.z);
|
nPos.z = (nPos.z < pos.z ? pos.z : nPos.z);
|
||||||
}
|
}
|
||||||
@ -333,7 +412,9 @@ namespace OpenGTA {
|
|||||||
if (z < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1))) {
|
if (z < 255 && y < map.getNumBlocksAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1))) {
|
||||||
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1), PHYSFS_uint8(y));
|
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1), PHYSFS_uint8(y));
|
||||||
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
||||||
|
#ifdef DEBUG_OLD_PED_BLOCK
|
||||||
INFO << "zblock top: " << z + 1 - pos.z<< " tex: " << int(block->top) << std::endl;
|
INFO << "zblock top: " << z + 1 - pos.z<< " tex: " << int(block->top) << std::endl;
|
||||||
|
#endif
|
||||||
if (block->isFlat()) {
|
if (block->isFlat()) {
|
||||||
if (z + 1 - pos.z > 0 && z + 1 - pos.z < 0.2f)
|
if (z + 1 - pos.z > 0 && z + 1 - pos.z < 0.2f)
|
||||||
nPos.z = (nPos.z < pos.z ? nPos.z : pos.z);
|
nPos.z = (nPos.z < pos.z ? nPos.z : pos.z);
|
||||||
@ -354,162 +435,152 @@ namespace OpenGTA {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pedestrian::equip(uint8_t id) {
|
void Pedestrian::die() {
|
||||||
if (id == 0) {
|
INFO << "DIE!!!" << std::endl;
|
||||||
activeWeapon = 0;
|
switchToAnim(42);
|
||||||
}
|
|
||||||
else {
|
|
||||||
InventoryType::iterator i = inventory.find(id);
|
|
||||||
if (i != inventory.end()) {
|
|
||||||
activeWeapon = i->first;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
ERROR << "Ped does not have item type " << int(id) << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pedestrian::fireWeapon(Uint32 ticks) {
|
void Pedestrian::getShot(bool front) {
|
||||||
if (activeWeapon == 0)
|
isDead = 1;
|
||||||
return; // FIXME: punching!
|
switchToAnim(45);
|
||||||
InventoryType::iterator i = inventory.find(activeWeapon);
|
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::FCALLBACK);
|
||||||
if (i->second == 0)
|
Loki::Functor<void> cmd(this, &Pedestrian::die);
|
||||||
return; // no ammo
|
anim.setCallback(cmd);
|
||||||
if (ticks < weaponReloadedAt)
|
|
||||||
return;
|
|
||||||
|
|
||||||
weaponReloadedAt = ticks + 2000;
|
|
||||||
OpenGTA::SpriteManagerHolder::Instance().createProjectile(i->first, rot, pos, Vector3D(0.2f, 0, 0.2f), ticks);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Pedestrian::update(Uint32 ticks) {
|
Car::Car(OpenGTA::Map::ObjectPosition& op, uint32_t id) :
|
||||||
// update the animation
|
GameObject_common(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
||||||
if (m_control) {
|
Sprite(0, -1, GraphicsBase::SpriteNumbers::CAR), OBox(),
|
||||||
switch(m_control->move) {
|
carInfo(*StyleHolder::Instance().get().findCarByModel(op.type)){
|
||||||
case 1:
|
carId = id;
|
||||||
if (!(animId == 2u + activeWeapon*3))
|
|
||||||
switchToAnim(2 + activeWeapon*3);
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
if (!(animId == 3u + activeWeapon*3))
|
|
||||||
switchToAnim(3 + activeWeapon*3);
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
if (!(animId == 1u + activeWeapon*3))
|
|
||||||
switchToAnim(1 + activeWeapon*3);
|
|
||||||
break;
|
|
||||||
case -1:
|
|
||||||
if (!(animId == 2u + activeWeapon*3)) {
|
|
||||||
switchToAnim(2 + activeWeapon*3);
|
|
||||||
anim.set(Util::Animation::PLAY_BACKWARD, Util::Animation::LOOP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
anim.update(ticks);
|
|
||||||
// update position/rotation
|
|
||||||
Uint32 delta = ticks - lastUpdateAt;
|
|
||||||
Vector3D moveDelta(0, 0, 0);
|
|
||||||
if (m_control) {
|
|
||||||
switch(m_control->turn) {
|
|
||||||
case -1:
|
|
||||||
rot -= 0.2f * delta;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
rot += 0.2f * delta;
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (rot >= 360.0f)
|
|
||||||
rot -= 360.0f;
|
|
||||||
if (rot < 0.0f)
|
|
||||||
rot += 360.0f;
|
|
||||||
switch(m_control->move) {
|
|
||||||
case -1:
|
|
||||||
moveDelta.x -= sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
moveDelta.z -= cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
moveDelta.x += sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
moveDelta.z += cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
break;
|
|
||||||
case 2:
|
|
||||||
moveDelta.x += sin(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
moveDelta.z += cos(rot * M_PI / 180.0f) * anim.moveSpeed * delta;
|
|
||||||
break;
|
|
||||||
case 0:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
tryMove(pos + moveDelta);
|
|
||||||
if (!inGroundContact) {
|
|
||||||
speedForces.y += 0.1f;
|
|
||||||
pos.y -= speedForces.y;
|
|
||||||
if (speedForces.y < 0.2f)
|
|
||||||
INFO << "bridge step? height: " << pos.y << " speed: " << speedForces.y << std::endl;
|
|
||||||
else
|
|
||||||
INFO << "FALLING" << pos.y << " speed " << speedForces.y << std::endl;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if (speedForces.y > 0.1)
|
|
||||||
INFO << "impacting with speed: " << speedForces.y << std::endl;
|
|
||||||
speedForces.y = 0.0f;
|
|
||||||
}
|
|
||||||
lastUpdateAt = ticks;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#define INT2FLOAT_WRLD(c) (float(c >> 6) + float(c % 64) / 64.0f)
|
|
||||||
#define INT2F_DIV64(v) (float(v) / 64.0f)
|
|
||||||
#define INT2F_DIV128(v) (float(v) / 128.0f)
|
|
||||||
|
|
||||||
Car::Car(const OpenGTA::Map::ObjectPosition & op) :
|
|
||||||
SpriteObject(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
|
||||||
OBox(RollMatrix3D(0), Vector3D()),
|
|
||||||
c_info(*StyleHolder::Instance().get().findCarByModel(op.type)) {
|
|
||||||
type = op.type;
|
type = op.type;
|
||||||
sprType = GraphicsBase::SpriteNumbers::CAR;
|
sprNum = carInfo.sprNum;
|
||||||
sprNum = c_info.sprNum;
|
m_Extent = Vector3D(INT2F_DIV128(carInfo.width),
|
||||||
m_Extent = Vector3D(INT2F_DIV128(c_info.width),
|
INT2F_DIV128(carInfo.depth),
|
||||||
INT2F_DIV128(c_info.depth),
|
INT2F_DIV128(carInfo.height));
|
||||||
INT2F_DIV128(c_info.height));
|
m_M = TranslateMatrix3D(pos);
|
||||||
m_M.Translate(pos);
|
m_M.RotZ(rot);
|
||||||
|
|
||||||
rot = op.rotation * 360 / 1024;
|
rot = op.rotation * 360 / 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
Car::Car(const Car & other) : SpriteObject(other),
|
Car::Car(const Car & other) :
|
||||||
OBox(other.m_M, other.m_Extent),
|
GameObject_common(other), Sprite(other), OBox(other),
|
||||||
c_info(*StyleHolder::Instance().get().findCarByModel(other.type)) {
|
carInfo(*StyleHolder::Instance().get().findCarByModel(other.type)) {
|
||||||
copyValues(other);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Car::copyValues(const Car & other) {
|
|
||||||
sprType = other.sprType;
|
|
||||||
delta = other.delta;
|
|
||||||
carId = other.carId;
|
|
||||||
type = other.type;
|
type = other.type;
|
||||||
|
m_M = TranslateMatrix3D(pos);
|
||||||
|
m_M.RotZ(rot);
|
||||||
|
|
||||||
|
carId = other.carId;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject::GameObject(const OpenGTA::Map::ObjectPosition & op) :
|
void Car::update(Uint32 ticks) {
|
||||||
SpriteObject(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
}
|
||||||
OBox(RollMatrix3D(0), Vector3D()) {
|
|
||||||
sprType = GraphicsBase::SpriteNumbers::OBJECT;
|
SpriteObject::SpriteObject(OpenGTA::Map::ObjectPosition& op, uint32_t id) :
|
||||||
|
GameObject_common(Vector3D(INT2FLOAT_WRLD(op.x), 6.05f-INT2FLOAT_WRLD(op.z), INT2FLOAT_WRLD(op.y))),
|
||||||
|
Sprite(0, -1, GraphicsBase::SpriteNumbers::OBJECT), OBox() {
|
||||||
|
objId = id;
|
||||||
GraphicsBase & style = StyleHolder::Instance().get();
|
GraphicsBase & style = StyleHolder::Instance().get();
|
||||||
sprNum = style.objectInfos[op.type]->sprNum;
|
sprNum = style.objectInfos[op.type]->sprNum;
|
||||||
m_Extent = Vector3D(INT2F_DIV128(style.objectInfos[op.type]->width),
|
m_Extent = Vector3D(INT2F_DIV128(style.objectInfos[op.type]->width),
|
||||||
INT2F_DIV128(style.objectInfos[op.type]->depth),
|
INT2F_DIV128(style.objectInfos[op.type]->depth),
|
||||||
INT2F_DIV128(style.objectInfos[op.type]->height));
|
INT2F_DIV128(style.objectInfos[op.type]->height));
|
||||||
m_M.Translate(pos);
|
m_M = TranslateMatrix3D(pos);
|
||||||
|
m_M.RotZ(rot);
|
||||||
rot = op.rotation * 360 / 1024;
|
rot = op.rotation * 360 / 1024;
|
||||||
|
isActive = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObject::GameObject(const GameObject & other) : SpriteObject(other),
|
SpriteObject::SpriteObject(Vector3D pos, Uint16 sprNum, OpenGTA::GraphicsBase::SpriteNumbers::SpriteTypes sprT) :
|
||||||
OBox(other.m_M, other.m_Extent) {
|
GameObject_common(pos), Sprite(sprNum, -1, sprT), OBox() {
|
||||||
copyValues(other);
|
isActive = true;
|
||||||
|
m_M = TranslateMatrix3D(pos);
|
||||||
|
m_M.RotZ(rot);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObject::copyValues(const GameObject & other) {
|
SpriteObject::SpriteObject(const SpriteObject & other) :
|
||||||
sprType = other.sprType;
|
GameObject_common(other), Sprite(other), OBox(other),
|
||||||
|
|
||||||
|
objId(other.objId) {
|
||||||
|
m_M = TranslateMatrix3D(pos);
|
||||||
|
m_M.RotZ(rot);
|
||||||
|
|
||||||
|
isActive = other.isActive;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SpriteObject::update(Uint32 ticks) {
|
||||||
|
anim.update(ticks);
|
||||||
|
}
|
||||||
|
|
||||||
|
Projectile::Projectile(unsigned char t, float r, Vector3D p, Vector3D d, uint32_t ticks, uint32_t o) :
|
||||||
|
GameObject_common(p, r),
|
||||||
|
typeId(t), delta(d), endsAtTick(ticks),
|
||||||
|
owner(o), lastUpdateAt(ticks) {
|
||||||
|
endsAtTick = lastUpdateAt + 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
Projectile::Projectile(const Projectile & other) :
|
||||||
|
GameObject_common(other),
|
||||||
|
typeId(other.typeId), delta(other.delta), endsAtTick(other.endsAtTick),
|
||||||
|
owner(other.owner), lastUpdateAt(other.lastUpdateAt) {}
|
||||||
|
|
||||||
|
void Projectile::update(uint32_t ticks) {
|
||||||
|
Uint32 dt = ticks - lastUpdateAt;
|
||||||
|
Vector3D new_pos(pos + delta * dt);
|
||||||
|
/*INFO << "p-m " << pos.x << " " << pos.y << " " << pos.z <<
|
||||||
|
" to " << new_pos.x << " " << new_pos.y << " " << new_pos.z << std::endl;
|
||||||
|
*/
|
||||||
|
std::list<Pedestrian> & list = SpriteManagerHolder::Instance().getList<Pedestrian>();
|
||||||
|
for (std::list<Pedestrian>::iterator i = list.begin(); i != list.end(); ++i) {
|
||||||
|
Pedestrian & ped = *i;
|
||||||
|
if (ped.id() == owner)
|
||||||
|
continue;
|
||||||
|
if (ped.isDead)
|
||||||
|
continue;
|
||||||
|
/*INFO << "ped " << ped.id() << " pos: " << ped.pos.x << " " << ped.pos.y << " " << ped.pos.z << std::endl;
|
||||||
|
Vector3D p = ped.GetCenterPoint();
|
||||||
|
INFO << "CP " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||||
|
p = ped.m_Extent;
|
||||||
|
INFO << "extent " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||||
|
for (int i=0; i < 4; i++) {
|
||||||
|
for (int j=0; j < 4; j++) {
|
||||||
|
std::cout << "M " << ped.m_M.m[i][j] << " ";
|
||||||
|
}
|
||||||
|
std::cout << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
|
||||||
|
if (ped.IsLineInBox( pos, new_pos ) ) {
|
||||||
|
INFO << "HIT ped " << ped.id() << std::endl;
|
||||||
|
ped.getShot(true);
|
||||||
|
//ped.sprType = GraphicsBase::SpriteNumbers::OBJECT;
|
||||||
|
//ped.remap = -1;
|
||||||
|
//SpriteManagerHolder::Instance().removePed(ped.pedId);
|
||||||
|
endsAtTick = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Util::CellIterator oi(pos);
|
||||||
|
|
||||||
|
Util::CellIterator ni(new_pos);
|
||||||
|
//FIXME ni valid?
|
||||||
|
|
||||||
|
if (oi.isValid() && ni.isValid()) {
|
||||||
|
if (oi == ni) { // only one cell to check
|
||||||
|
Math::line_intersect(pos, new_pos);//, oi.getBlock());
|
||||||
|
}
|
||||||
|
else { // crosses cell boundary
|
||||||
|
Math::line_intersect(pos, new_pos);//, oi.getBlock());
|
||||||
|
//Math::line_intersect(pos, new_pos);//, ni.getBlock());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
INFO << "NEITHER VALID!"<< oi.x << " " << oi.y << " " << oi.z <<std::endl;
|
||||||
|
*/
|
||||||
|
pos = new_pos;
|
||||||
|
|
||||||
|
lastUpdateAt = ticks;
|
||||||
}
|
}
|
||||||
}
|
}
|
146
game_objects.h
Normal file
146
game_objects.h
Normal file
@ -0,0 +1,146 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#ifndef GAME_OBJECTS_H
|
||||||
|
#define GAME_OBJECTS_H
|
||||||
|
|
||||||
|
#include "math3d.h"
|
||||||
|
#include "obox.h"
|
||||||
|
#include "animation.h"
|
||||||
|
#include "opengta.h"
|
||||||
|
#include "cell_iterator.h"
|
||||||
|
#include "entity_controller.h"
|
||||||
|
#include "OpenSteer/Proximity.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
|
||||||
|
struct GameObject_common;
|
||||||
|
typedef OpenSteer::AbstractTokenForProximityDatabase<GameObject_common*> ProximityToken;
|
||||||
|
typedef OpenSteer::AbstractProximityDatabase<GameObject_common*> ProximityDatabase;
|
||||||
|
struct GameObject_common {
|
||||||
|
Vector3D pos;
|
||||||
|
float rot;
|
||||||
|
float bSphereRadius;
|
||||||
|
//uint8_t activeState;
|
||||||
|
GameObject_common() :
|
||||||
|
pos(0, 0, 0), rot(0), bSphereRadius(0.1f) {}
|
||||||
|
GameObject_common(const Vector3D & p) : pos(p), rot(0) {}
|
||||||
|
GameObject_common(const Vector3D & p, float r) : pos(p), rot(r) {}
|
||||||
|
GameObject_common(const GameObject_common & o) :
|
||||||
|
pos(o.pos), rot(o.rot), bSphereRadius(o.bSphereRadius) {}
|
||||||
|
float heightOverTerrain(const Vector3D &);
|
||||||
|
ProximityToken* proxToken;
|
||||||
|
};
|
||||||
|
|
||||||
|
class Sprite {
|
||||||
|
public:
|
||||||
|
struct Animation : public Util::Animation {
|
||||||
|
Animation();
|
||||||
|
Animation(const Animation & other);
|
||||||
|
Animation(Uint16 foff, Uint8 num);
|
||||||
|
Animation(Uint16 foff, Uint8 num, float speed);
|
||||||
|
Uint16 firstFrameOffset;
|
||||||
|
//Uint8 numFrames;
|
||||||
|
float moveSpeed;
|
||||||
|
};
|
||||||
|
Sprite();
|
||||||
|
Sprite(Uint16 sprN, Sint16 rem, GraphicsBase::SpriteNumbers::SpriteTypes sprT);
|
||||||
|
Sprite(const Sprite & o);
|
||||||
|
Uint16 sprNum;
|
||||||
|
Sint16 remap;
|
||||||
|
Animation anim;
|
||||||
|
Uint32 animId;
|
||||||
|
GraphicsBase::SpriteNumbers::SpriteTypes sprType;
|
||||||
|
Uint8 calcCurrentFrame(Uint32 ticks);
|
||||||
|
void switchToAnim(const Uint32 & newId);
|
||||||
|
};
|
||||||
|
|
||||||
|
class Pedestrian : public GameObject_common, public Sprite, public OBox {
|
||||||
|
public:
|
||||||
|
Pedestrian(Vector3D, const Vector3D &, uint32_t id, Sint16 remapId = -1);
|
||||||
|
Pedestrian(const Pedestrian & o);
|
||||||
|
uint32_t pedId;
|
||||||
|
inline uint32_t id() const { return pedId; }
|
||||||
|
void equip(uint8_t eq_id);
|
||||||
|
void giveItem(uint8_t id, uint32_t amount);
|
||||||
|
PedController m_control;
|
||||||
|
void update(Uint32 ticks);
|
||||||
|
Uint32 lastUpdateAt;
|
||||||
|
Uint32 lastWeaponTick;
|
||||||
|
Vector3D speedForces;
|
||||||
|
bool inGroundContact;
|
||||||
|
void tryMove(Vector3D nPos);
|
||||||
|
uint8_t isDead;
|
||||||
|
void getShot(bool front = true);
|
||||||
|
void die();
|
||||||
|
};
|
||||||
|
|
||||||
|
class Car : public GameObject_common, public Sprite, public OBox {
|
||||||
|
public:
|
||||||
|
Car(const Car & o);
|
||||||
|
Car(OpenGTA::Map::ObjectPosition&, uint32_t id);
|
||||||
|
uint32_t carId;
|
||||||
|
inline uint32_t id() const { return carId; }
|
||||||
|
GraphicsBase::CarInfo & carInfo;
|
||||||
|
uint8_t type;
|
||||||
|
void update(Uint32 ticks);
|
||||||
|
Uint32 lastUpdateAt;
|
||||||
|
};
|
||||||
|
|
||||||
|
class SpriteObject : public GameObject_common, public Sprite, public OBox {
|
||||||
|
public:
|
||||||
|
SpriteObject(OpenGTA::Map::ObjectPosition&, uint32_t id);
|
||||||
|
SpriteObject(Vector3D pos, Uint16 spriteNum, GraphicsBase::SpriteNumbers::SpriteTypes st);
|
||||||
|
SpriteObject(const SpriteObject & o);
|
||||||
|
uint32_t objId;
|
||||||
|
inline uint32_t id() const { return objId; }
|
||||||
|
void update(Uint32 ticks);
|
||||||
|
Uint32 lastUpdateAt;
|
||||||
|
|
||||||
|
bool isActive;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
class TrainSegment : public GameObject_common, public OBox {
|
||||||
|
public:
|
||||||
|
TrainSegment(uint32_t id, Util::CellIterator & cell);
|
||||||
|
TrainSegment(const TrainSegment & o);
|
||||||
|
uint32_t trainId;
|
||||||
|
inline uint32_t id() const { return trainId; }
|
||||||
|
};*/
|
||||||
|
|
||||||
|
class Projectile : public GameObject_common {
|
||||||
|
public:
|
||||||
|
Projectile(uint8_t, float, Vector3D, Vector3D, uint32_t, uint32_t);
|
||||||
|
Projectile(const Projectile & other);
|
||||||
|
uint8_t typeId;
|
||||||
|
Vector3D delta;
|
||||||
|
uint32_t endsAtTick;
|
||||||
|
uint32_t owner;
|
||||||
|
void update(Uint32 ticks);
|
||||||
|
Uint32 lastUpdateAt;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -197,15 +197,15 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
switch(section) {
|
switch(section) {
|
||||||
case 0:
|
case 0:
|
||||||
graphics.getSide(idx, remap, rgba);
|
graphics.getSide(idx, 0, rgba);
|
||||||
image = get_image(graphics.getTmpBuffer(rgba), 64,64);
|
image = get_image(graphics.getTmpBuffer(rgba), 64,64);
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
graphics.getLid(idx, remap, rgba);
|
graphics.getLid(idx, 0, rgba);
|
||||||
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
graphics.getAux(idx, remap, rgba);
|
graphics.getAux(idx, 0, rgba);
|
||||||
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
||||||
break;
|
break;
|
||||||
case 3:
|
case 3:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -26,7 +26,18 @@ namespace OpenGL {
|
|||||||
void Camera::update_game(Uint32 ticks) {
|
void Camera::update_game(Uint32 ticks) {
|
||||||
Vector3D delta(center - *followTarget);
|
Vector3D delta(center - *followTarget);
|
||||||
//INFO << delta.x << ", " << delta.y << ", " << delta.z << std::endl;
|
//INFO << delta.x << ", " << delta.y << ", " << delta.z << std::endl;
|
||||||
|
float height_dist = fabs(delta.y);
|
||||||
delta.y = 0;
|
delta.y = 0;
|
||||||
|
if (camGravity) {
|
||||||
|
if (center.y - followTarget->y > 4.1) {
|
||||||
|
delta.y = 0.001f * height_dist;
|
||||||
|
}
|
||||||
|
else if (center.y - followTarget->y < 3.9) {
|
||||||
|
delta.y = -0.001f * height_dist;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//INFO << center.y << " " << followTarget->y<< " " << height_dist << std::endl;
|
||||||
|
|
||||||
center += -delta;
|
center += -delta;
|
||||||
eye += -delta;
|
eye += -delta;
|
||||||
gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z,
|
gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z,
|
||||||
|
238
gl_cityview.cpp
238
gl_cityview.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -34,6 +34,7 @@
|
|||||||
#include "gl_screen.h"
|
#include "gl_screen.h"
|
||||||
#include "blockdata.h"
|
#include "blockdata.h"
|
||||||
#include "image_loader.h"
|
#include "image_loader.h"
|
||||||
|
#include "blockanim.h"
|
||||||
|
|
||||||
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
@ -84,6 +85,8 @@ namespace OpenGTA {
|
|||||||
loadedMap = NULL;
|
loadedMap = NULL;
|
||||||
sideCache = NULL;
|
sideCache = NULL;
|
||||||
lidCache = NULL;
|
lidCache = NULL;
|
||||||
|
auxCache = NULL;
|
||||||
|
blockAnims = NULL;
|
||||||
camVec[0] = 0.0f;
|
camVec[0] = 0.0f;
|
||||||
camVec[1] = 1.0f;
|
camVec[1] = 1.0f;
|
||||||
camVec[2] = 0.0f;
|
camVec[2] = 0.0f;
|
||||||
@ -105,6 +108,7 @@ namespace OpenGTA {
|
|||||||
void CityView::resetTextures() {
|
void CityView::resetTextures() {
|
||||||
sideCache->clearAll();
|
sideCache->clearAll();
|
||||||
lidCache->clearAll();
|
lidCache->clearAll();
|
||||||
|
auxCache->clearAll();
|
||||||
}
|
}
|
||||||
void CityView::setVisibleRange(int r) {
|
void CityView::setVisibleRange(int r) {
|
||||||
visibleRange = r;
|
visibleRange = r;
|
||||||
@ -124,6 +128,10 @@ namespace OpenGTA {
|
|||||||
delete sideCache;
|
delete sideCache;
|
||||||
if (lidCache)
|
if (lidCache)
|
||||||
delete lidCache;
|
delete lidCache;
|
||||||
|
if (auxCache)
|
||||||
|
delete auxCache;
|
||||||
|
if (blockAnims)
|
||||||
|
delete blockAnims;
|
||||||
if (scene_display_list)
|
if (scene_display_list)
|
||||||
glDeleteLists(scene_display_list, 1);
|
glDeleteLists(scene_display_list, 1);
|
||||||
setNull();
|
setNull();
|
||||||
@ -138,10 +146,20 @@ namespace OpenGTA {
|
|||||||
loadedMap = &MapHolder::Instance().get();
|
loadedMap = &MapHolder::Instance().get();
|
||||||
StyleHolder::Instance().load(style_f);
|
StyleHolder::Instance().load(style_f);
|
||||||
style = &StyleHolder::Instance().get();
|
style = &StyleHolder::Instance().get();
|
||||||
|
/*
|
||||||
|
for (size_t i = 0; i < style->carInfos.size(); ++i) {
|
||||||
|
OpenGTA::GraphicsBase::CarInfo * cinfo = style->carInfos[i];
|
||||||
|
assert(cinfo);
|
||||||
|
INFO << cinfo->numDoors << std::endl;
|
||||||
|
}*/
|
||||||
|
|
||||||
sideCache = new OpenGL::TextureCache<uint8_t>("SideCache");
|
sideCache = new OpenGL::TextureCache<uint8_t>("SideCache");
|
||||||
lidCache = new OpenGL::TextureCache<uint8_t>("LidCache");
|
lidCache = new OpenGL::TextureCache<uint8_t>("LidCache");
|
||||||
|
auxCache = new OpenGL::TextureCache<uint8_t>("AuxCache");
|
||||||
sideCache->setClearMagic(5);
|
sideCache->setClearMagic(5);
|
||||||
lidCache->setClearMagic(8);
|
lidCache->setClearMagic(8);
|
||||||
|
auxCache->setClearMagic(5);
|
||||||
|
blockAnims = new BlockAnimCtrl(style->animations);
|
||||||
scene_is_dirty = true;
|
scene_is_dirty = true;
|
||||||
lastCacheEmptyTicks = 0;
|
lastCacheEmptyTicks = 0;
|
||||||
|
|
||||||
@ -151,16 +169,20 @@ namespace OpenGTA {
|
|||||||
for (PHYSFS_uint16 oc = 0; oc < loadedMap->numObjects; oc++) {
|
for (PHYSFS_uint16 oc = 0; oc < loadedMap->numObjects; oc++) {
|
||||||
createLevelObject(&loadedMap->objects[oc]);
|
createLevelObject(&loadedMap->objects[oc]);
|
||||||
}
|
}
|
||||||
|
//SpriteManagerHolder::Instance().trainSystem.loadStations(*loadedMap);
|
||||||
}
|
}
|
||||||
void CityView::createLevelObject(OpenGTA::Map::ObjectPosition *obj) {
|
void CityView::createLevelObject(OpenGTA::Map::ObjectPosition *obj) {
|
||||||
SpriteManager & s_man = SpriteManagerHolder::Instance();
|
SpriteManager & s_man = SpriteManagerHolder::Instance();
|
||||||
if (obj->remap >= 128) {
|
if (obj->remap >= 128) {
|
||||||
Car car(*obj);
|
Car car(*obj, 0);
|
||||||
s_man.addCar(car);
|
s_man.add(car);
|
||||||
|
//s_man.addCar(car);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
GameObject gobj(*obj);
|
//GameObject gobj(*obj);
|
||||||
s_man.addObject(gobj);
|
SpriteObject gobj(*obj, 0);
|
||||||
|
s_man.add(gobj);
|
||||||
|
//s_man.addObject(gobj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void CityView::setZoom(const GLfloat zoom) {
|
void CityView::setZoom(const GLfloat zoom) {
|
||||||
@ -341,6 +363,17 @@ namespace OpenGTA {
|
|||||||
if (y2 > 255)
|
if (y2 > 255)
|
||||||
y2 = 255;
|
y2 = 255;
|
||||||
|
|
||||||
|
activeRect.x = x1;
|
||||||
|
activeRect.y = y1;
|
||||||
|
activeRect.w = x2 - x1;
|
||||||
|
activeRect.h = y2 - y1;
|
||||||
|
//INFO << "Active area: " << x1 << " - " << x2 << " , " << y1 << " - " << y2 << std::endl;
|
||||||
|
int xd1, xd2, yd1, yd2;
|
||||||
|
xd2 = 0;
|
||||||
|
yd2 = 0;
|
||||||
|
xd1 = x2;
|
||||||
|
yd1 = y2;
|
||||||
|
|
||||||
bool use_display_list = false;
|
bool use_display_list = false;
|
||||||
|
|
||||||
GL_CHECKERROR;
|
GL_CHECKERROR;
|
||||||
@ -358,6 +391,12 @@ namespace OpenGTA {
|
|||||||
for (int j= x1; j <= x2; j++) {
|
for (int j= x1; j <= x2; j++) {
|
||||||
if (!frustum.BlockInFrustum(0.5f+j, 0.5f+i, 0.5f))
|
if (!frustum.BlockInFrustum(0.5f+j, 0.5f+i, 0.5f))
|
||||||
continue;
|
continue;
|
||||||
|
if (j < xd1)
|
||||||
|
xd1 = j;
|
||||||
|
xd2 = j;
|
||||||
|
if (i < yd1)
|
||||||
|
yd1 = i;
|
||||||
|
yd2 = i;
|
||||||
glPushMatrix();
|
glPushMatrix();
|
||||||
glTranslatef(1.0f*j, 0.0f, 1.0f*i);
|
glTranslatef(1.0f*j, 0.0f, 1.0f*i);
|
||||||
//PHYSFS_uint16 emptycount = loadedMap->getNumBlocksAt(j,i);
|
//PHYSFS_uint16 emptycount = loadedMap->getNumBlocksAt(j,i);
|
||||||
@ -374,6 +413,11 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
//glPopMatrix();
|
//glPopMatrix();
|
||||||
}
|
}
|
||||||
|
drawnRect.x = xd1;
|
||||||
|
drawnRect.y = yd1;
|
||||||
|
drawnRect.w = xd2 - xd1;
|
||||||
|
drawnRect.h = yd2 - yd1;
|
||||||
|
//INFO << "area drawn: " << xd1 << " - " << xd2 << " , " << yd1 << " - " << yd2 << std::endl;
|
||||||
if (use_display_list) {
|
if (use_display_list) {
|
||||||
glEndList();
|
glEndList();
|
||||||
glCallList(scene_display_list);
|
glCallList(scene_display_list);
|
||||||
@ -388,14 +432,8 @@ namespace OpenGTA {
|
|||||||
(loadedMap->objects[oc].y >> 6) + 0.5f, 0.5f))
|
(loadedMap->objects[oc].y >> 6) + 0.5f, 0.5f))
|
||||||
drawObject(&loadedMap->objects[oc]);
|
drawObject(&loadedMap->objects[oc]);
|
||||||
}*/
|
}*/
|
||||||
SDL_Rect r;
|
|
||||||
r.x = x1;
|
|
||||||
r.y = y1;
|
|
||||||
r.w = x2 - x1;
|
|
||||||
r.h = y2 - y1;
|
|
||||||
//INFO << "active rect: " << r.x << "," <<r.y << " - " << r.x + r.w << "," << r.y+r.h<<std::endl;
|
|
||||||
GL_CHECKERROR;
|
GL_CHECKERROR;
|
||||||
SpriteManagerHolder::Instance().drawInRect(r);
|
SpriteManagerHolder::Instance().drawInRect(activeRect);
|
||||||
|
|
||||||
lastCacheEmptyTicks += ticks;
|
lastCacheEmptyTicks += ticks;
|
||||||
if (lastCacheEmptyTicks > 4000) {
|
if (lastCacheEmptyTicks > 4000) {
|
||||||
@ -540,49 +578,138 @@ namespace OpenGTA {
|
|||||||
|
|
||||||
// FIXME: no remaps used!
|
// FIXME: no remaps used!
|
||||||
if (bi->lid) {
|
if (bi->lid) {
|
||||||
if (!lidCache->hasTexture(bi->lid)) {
|
int frame_num = -1;//style->checkBlockAnimation(0, bi->lid);
|
||||||
lid_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
BlockAnim * banim = blockAnims->getAnim(1, bi->lid);
|
||||||
style->getLid(static_cast<unsigned int>(bi->lid), 0, is_flat));
|
if (banim) {
|
||||||
lidCache->addTexture(bi->lid, lid_tex);
|
frame_num = banim->getCurrentFrameNumber();
|
||||||
|
}
|
||||||
|
if (frame_num <= 0) {
|
||||||
|
if (!lidCache->hasTexture(bi->lid)) {
|
||||||
|
lid_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getLid(static_cast<unsigned int>(bi->lid), 0, is_flat));
|
||||||
|
lidCache->addTexture(bi->lid, lid_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lid_tex = lidCache->getTextureWithId(bi->lid);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t aux_id = banim->getFrame(frame_num - 1);
|
||||||
|
if (!auxCache->hasTexture(aux_id)) {
|
||||||
|
lid_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getAux(static_cast<unsigned int>(aux_id), 0, is_flat));
|
||||||
|
auxCache->addTexture(aux_id, lid_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
lid_tex = auxCache->getTextureWithId(aux_id);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
lid_tex = lidCache->getTextureWithId(bi->lid);
|
|
||||||
}
|
}
|
||||||
if (bi->left) {
|
if (bi->left) {
|
||||||
if (!sideCache->hasTexture(bi->left)) {
|
int frame_num = -1;
|
||||||
left_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
BlockAnim * banim = blockAnims->getAnim(0, bi->left);
|
||||||
style->getSide(static_cast<unsigned int>(bi->left), 0, is_flat));
|
if (banim) {
|
||||||
sideCache->addTexture(bi->left, left_tex);
|
frame_num = banim->getCurrentFrameNumber();
|
||||||
|
}
|
||||||
|
if (frame_num <= 0) {
|
||||||
|
if (!sideCache->hasTexture(bi->left)) {
|
||||||
|
left_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getSide(static_cast<unsigned int>(bi->left), 0, is_flat));
|
||||||
|
sideCache->addTexture(bi->left, left_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
left_tex = sideCache->getTextureWithId(bi->left);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t aux_id = banim->getFrame(frame_num - 1);
|
||||||
|
if (!auxCache->hasTexture(aux_id)) {
|
||||||
|
left_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getAux(static_cast<unsigned int>(aux_id), 0, is_flat));
|
||||||
|
auxCache->addTexture(aux_id, left_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
left_tex = auxCache->getTextureWithId(aux_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
left_tex = sideCache->getTextureWithId(bi->left);
|
|
||||||
}
|
}
|
||||||
if (bi->right) {
|
if (bi->right) {
|
||||||
if (!sideCache->hasTexture(bi->right)) {
|
int frame_num = -1;
|
||||||
right_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
BlockAnim * banim = blockAnims->getAnim(0, bi->right);
|
||||||
style->getSide(static_cast<unsigned int>(bi->right), 0, is_flat));
|
if (banim) {
|
||||||
sideCache->addTexture(bi->right, right_tex);
|
frame_num = banim->getCurrentFrameNumber();
|
||||||
|
}
|
||||||
|
if (frame_num <= 0) {
|
||||||
|
if (!sideCache->hasTexture(bi->right)) {
|
||||||
|
right_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getSide(static_cast<unsigned int>(bi->right), 0, is_flat));
|
||||||
|
sideCache->addTexture(bi->right, right_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
right_tex = sideCache->getTextureWithId(bi->right);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t aux_id = banim->getFrame(frame_num - 1);
|
||||||
|
if (!auxCache->hasTexture(aux_id)) {
|
||||||
|
right_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getAux(static_cast<unsigned int>(aux_id), 0, is_flat));
|
||||||
|
auxCache->addTexture(aux_id, right_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
right_tex = auxCache->getTextureWithId(aux_id);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
right_tex = sideCache->getTextureWithId(bi->right);
|
|
||||||
}
|
}
|
||||||
if (bi->top) {
|
if (bi->top) {
|
||||||
if (!sideCache->hasTexture(bi->top)) {
|
int frame_num = -1;
|
||||||
top_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
BlockAnim * banim = blockAnims->getAnim(0, bi->top);
|
||||||
style->getSide(static_cast<unsigned int>(bi->top), 0, is_flat));
|
if (banim) {
|
||||||
sideCache->addTexture(bi->top, top_tex);
|
frame_num = banim->getCurrentFrameNumber();
|
||||||
|
}
|
||||||
|
if (frame_num <= 0) {
|
||||||
|
|
||||||
|
if (!sideCache->hasTexture(bi->top)) {
|
||||||
|
top_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getSide(static_cast<unsigned int>(bi->top), 0, is_flat));
|
||||||
|
sideCache->addTexture(bi->top, top_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
top_tex = sideCache->getTextureWithId(bi->top);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t aux_id = banim->getFrame(frame_num - 1);
|
||||||
|
if (!auxCache->hasTexture(aux_id)) {
|
||||||
|
top_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getAux(static_cast<unsigned int>(aux_id), 0, is_flat));
|
||||||
|
auxCache->addTexture(aux_id, top_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
top_tex = auxCache->getTextureWithId(aux_id);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
top_tex = sideCache->getTextureWithId(bi->top);
|
|
||||||
}
|
}
|
||||||
if (bi->bottom) {
|
if (bi->bottom) {
|
||||||
if (!sideCache->hasTexture(bi->bottom)) {
|
int frame_num = -1;
|
||||||
bottom_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
BlockAnim * banim = blockAnims->getAnim(0, bi->bottom);
|
||||||
style->getSide(static_cast<unsigned int>(bi->bottom), 0, is_flat));
|
if (banim) {
|
||||||
sideCache->addTexture(bi->bottom, bottom_tex);
|
frame_num = banim->getCurrentFrameNumber();
|
||||||
|
}
|
||||||
|
if (frame_num <= 0) {
|
||||||
|
|
||||||
|
if (!sideCache->hasTexture(bi->bottom)) {
|
||||||
|
bottom_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getSide(static_cast<unsigned int>(bi->bottom), 0, is_flat));
|
||||||
|
sideCache->addTexture(bi->bottom, bottom_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bottom_tex = sideCache->getTextureWithId(bi->bottom);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
uint8_t aux_id = banim->getFrame(frame_num - 1);
|
||||||
|
if (!auxCache->hasTexture(aux_id)) {
|
||||||
|
bottom_tex = ImageUtil::createGLTexture(64, 64, is_flat,
|
||||||
|
style->getAux(static_cast<unsigned int>(aux_id), 0, is_flat));
|
||||||
|
auxCache->addTexture(aux_id, bottom_tex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
bottom_tex = auxCache->getTextureWithId(aux_id);
|
||||||
|
|
||||||
}
|
}
|
||||||
else
|
|
||||||
bottom_tex = sideCache->getTextureWithId(bi->bottom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// handle flat/transparent case
|
// handle flat/transparent case
|
||||||
@ -1094,9 +1221,9 @@ namespace OpenGTA {
|
|||||||
HEIGHT_VERTEX(0.8f, 0.1f, 0.5f);
|
HEIGHT_VERTEX(0.8f, 0.1f, 0.5f);
|
||||||
glEnd();
|
glEnd();
|
||||||
}
|
}
|
||||||
glEnable(GL_TEXTURE_2D);
|
|
||||||
// block lid normals
|
// block lid normals
|
||||||
#if 0
|
//#if 0
|
||||||
|
glColor3f(1, 0, 0);
|
||||||
#define NORMAL_POS(a, b) glVertex3f(a, slope_height_offset(which, a, b), b)
|
#define NORMAL_POS(a, b) glVertex3f(a, slope_height_offset(which, a, b), b)
|
||||||
#define NORMAL_POS2(a, b) glVertex3f(a + nx, slope_height_offset(which, a, b) + ny, b + nz)
|
#define NORMAL_POS2(a, b) glVertex3f(a + nx, slope_height_offset(which, a, b) + ny, b + nz)
|
||||||
glBegin(GL_LINES);
|
glBegin(GL_LINES);
|
||||||
@ -1104,9 +1231,30 @@ namespace OpenGTA {
|
|||||||
NORMAL_POS(0.5f, 0.5f);
|
NORMAL_POS(0.5f, 0.5f);
|
||||||
NORMAL_POS2(0.5f, 0.5f);
|
NORMAL_POS2(0.5f, 0.5f);
|
||||||
}
|
}
|
||||||
|
glColor3f(0, 1, 0);
|
||||||
|
if (bi->left) {
|
||||||
|
glVertex3f(0, 0.5f, 0.5f);
|
||||||
|
glVertex3f(-0.4f, 0.5f, 0.5f);
|
||||||
|
}
|
||||||
|
glColor3f(0, 0, 1);
|
||||||
|
if (bi->right && !bi->isFlat()) {
|
||||||
|
glVertex3f(1, 0.5f, 0.5f);
|
||||||
|
glVertex3f(1.4f, 0.5f, 0.5f);
|
||||||
|
}
|
||||||
|
glColor3f(0, 1, 0);
|
||||||
|
if (bi->top) {
|
||||||
|
glVertex3f(0.5f, 0.5f, 0.0f);
|
||||||
|
glVertex3f(0.5f, 0.5f, -0.4f);
|
||||||
|
}
|
||||||
|
glColor3f(0, 0, 1);
|
||||||
|
if (bi->bottom && !bi->isFlat()) {
|
||||||
|
glVertex3f(0.5f, 0.5f, 1.0f);
|
||||||
|
glVertex3f(0.5f, 0.5f, 1.4f);
|
||||||
|
}
|
||||||
glEnd();
|
glEnd();
|
||||||
|
glColor3f(1, 1, 1);
|
||||||
|
//#endif
|
||||||
glEnable(GL_TEXTURE_2D);
|
glEnable(GL_TEXTURE_2D);
|
||||||
#endif
|
|
||||||
|
|
||||||
GL_CHECKERROR;
|
GL_CHECKERROR;
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
|
|
||||||
|
class BlockAnimCtrl;
|
||||||
class CityView {
|
class CityView {
|
||||||
public:
|
public:
|
||||||
CityView();
|
CityView();
|
||||||
@ -59,6 +60,9 @@ namespace OpenGTA {
|
|||||||
void CityView::setDrawLines(bool v);
|
void CityView::setDrawLines(bool v);
|
||||||
|
|
||||||
void resetTextures();
|
void resetTextures();
|
||||||
|
const SDL_Rect & getActiveRect() { return activeRect; }
|
||||||
|
const SDL_Rect & getOnScreenRect() { return drawnRect; }
|
||||||
|
BlockAnimCtrl* blockAnims;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void setNull();
|
void setNull();
|
||||||
@ -69,6 +73,7 @@ namespace OpenGTA {
|
|||||||
Util::CFrustum frustum;
|
Util::CFrustum frustum;
|
||||||
OpenGL::TextureCache<uint8_t>* sideCache;
|
OpenGL::TextureCache<uint8_t>* sideCache;
|
||||||
OpenGL::TextureCache<uint8_t>* lidCache;
|
OpenGL::TextureCache<uint8_t>* lidCache;
|
||||||
|
OpenGL::TextureCache<uint8_t>* auxCache;
|
||||||
Map* loadedMap;
|
Map* loadedMap;
|
||||||
OpenGTA::GraphicsBase* style;
|
OpenGTA::GraphicsBase* style;
|
||||||
GLfloat zoomLevel;
|
GLfloat zoomLevel;
|
||||||
@ -79,6 +84,9 @@ namespace OpenGTA {
|
|||||||
bool drawTextured;
|
bool drawTextured;
|
||||||
bool drawLines;
|
bool drawLines;
|
||||||
|
|
||||||
|
SDL_Rect activeRect;
|
||||||
|
SDL_Rect drawnRect;
|
||||||
|
|
||||||
int scene_rendered_vertices;
|
int scene_rendered_vertices;
|
||||||
int scene_rendered_blocks;
|
int scene_rendered_blocks;
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -56,6 +56,12 @@ namespace OpenGL {
|
|||||||
setSystemMouseCursor(false);
|
setSystemMouseCursor(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Screen::setupGlVars( float fov, float near_p, float far_p) {
|
||||||
|
fieldOfView = fov;
|
||||||
|
nearPlane = near_p;
|
||||||
|
farPlane = far_p;
|
||||||
|
}
|
||||||
|
|
||||||
void Screen::setSystemMouseCursor(bool visible) {
|
void Screen::setSystemMouseCursor(bool visible) {
|
||||||
SDL_ShowCursor((visible ? SDL_ENABLE : SDL_DISABLE));
|
SDL_ShowCursor((visible ? SDL_ENABLE : SDL_DISABLE));
|
||||||
}
|
}
|
||||||
@ -103,14 +109,73 @@ namespace OpenGL {
|
|||||||
if (err)
|
if (err)
|
||||||
//throw "SDL_Init failed: " + std::string(SDL_GetError());
|
//throw "SDL_Init failed: " + std::string(SDL_GetError());
|
||||||
throw E_INVALIDFORMAT("SDL_Init failed: " + std::string(SDL_GetError()));
|
throw E_INVALIDFORMAT("SDL_Init failed: " + std::string(SDL_GetError()));
|
||||||
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, 8);
|
|
||||||
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, 8);
|
const char* sdl_err = SDL_GetError();
|
||||||
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8);
|
if (strlen(sdl_err) > 0)
|
||||||
|
INFO << "sdl_init complained: " << sdl_err << std::endl;
|
||||||
|
SDL_ClearError();
|
||||||
|
|
||||||
|
const SDL_VideoInfo *vInfo = SDL_GetVideoInfo();
|
||||||
|
|
||||||
|
if (vInfo == NULL)
|
||||||
|
throw E_NOTSUPPORTED("SDL_GetVideoInfo failed: " + std::string(SDL_GetError()));
|
||||||
|
|
||||||
|
if (vInfo->hw_available == 1)
|
||||||
|
videoFlags |= SDL_HWSURFACE;
|
||||||
|
else
|
||||||
|
videoFlags |= SDL_SWSURFACE;
|
||||||
|
|
||||||
|
if (vInfo->blit_hw)
|
||||||
|
videoFlags |= SDL_HWACCEL;
|
||||||
|
|
||||||
|
bpp = vInfo->vfmt->BitsPerPixel;
|
||||||
|
|
||||||
|
INFO << "video-probe:" << std::endl <<
|
||||||
|
" hw-surface: " << (vInfo->hw_available == 1 ? "on" : "off") << std::endl <<
|
||||||
|
" hw-blit: " << (vInfo->blit_hw ? "on" : "off") << std::endl <<
|
||||||
|
" bpp: " << int (bpp) << std::endl;
|
||||||
|
|
||||||
|
size_t color_depth_triple[3];
|
||||||
|
switch(bpp) {
|
||||||
|
case 32:
|
||||||
|
case 24:
|
||||||
|
for (int i=0; i < 3; ++i)
|
||||||
|
color_depth_triple[i] = 8;
|
||||||
|
break;
|
||||||
|
case 16:
|
||||||
|
color_depth_triple[0] = 5;
|
||||||
|
color_depth_triple[1] = 6;
|
||||||
|
color_depth_triple[2] = 5;
|
||||||
|
break;
|
||||||
|
case 15:
|
||||||
|
for (int i=0; i < 3; ++i)
|
||||||
|
color_depth_triple[i] = 5;
|
||||||
|
break;
|
||||||
|
case 8:
|
||||||
|
color_depth_triple[0] = 2;
|
||||||
|
color_depth_triple[1] = 3;
|
||||||
|
color_depth_triple[2] = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw E_NOTSUPPORTED("Invalid bit-per-pixel setting");
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_RED_SIZE, color_depth_triple[0]);
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_GREEN_SIZE, color_depth_triple[1]);
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, color_depth_triple[2]);
|
||||||
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
|
SDL_GL_SetAttribute( SDL_GL_DEPTH_SIZE, 16);
|
||||||
|
SDL_GL_SetAttribute( SDL_GL_DOUBLEBUFFER, 1);
|
||||||
|
#ifdef HAVE_SDL_VSYNC
|
||||||
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1);
|
SDL_GL_SetAttribute( SDL_GL_SWAP_CONTROL, 1);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
sdl_err = SDL_GetError();
|
||||||
|
if (strlen(sdl_err) > 0)
|
||||||
|
ERROR << "setting sdl_gl attributes: " << sdl_err << std::endl;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::initGL() {
|
void Screen::initGL() {
|
||||||
|
GL_CHECKERROR;
|
||||||
//GLfloat LightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
//GLfloat LightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||||
//GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
//GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||||
//GLfloat LightPosition[] = { 128.0f, 200.0f, 128.0f, 1.0f };
|
//GLfloat LightPosition[] = { 128.0f, 200.0f, 128.0f, 1.0f };
|
||||||
@ -128,15 +193,24 @@ namespace OpenGL {
|
|||||||
glCullFace(GL_BACK);
|
glCullFace(GL_BACK);
|
||||||
//glPolygonMode(GL_FRONT, GL_FILL);
|
//glPolygonMode(GL_FRONT, GL_FILL);
|
||||||
//glPolygonMode(GL_BACK, GL_LINE);
|
//glPolygonMode(GL_BACK, GL_LINE);
|
||||||
|
GL_CHECKERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::resize(Uint32 w, Uint32 h) {
|
void Screen::resize(Uint32 w, Uint32 h) {
|
||||||
if (h == 0)
|
if (h == 0)
|
||||||
h = 1;
|
h = 1;
|
||||||
surface = SDL_SetVideoMode(w, h, bpp, videoFlags);
|
surface = SDL_SetVideoMode(w, h, bpp, videoFlags);
|
||||||
|
if (surface == NULL) {
|
||||||
|
ERROR << "vide-mode: " << w << ", " << h << " bpp: " << bpp <<
|
||||||
|
" hw-surface: " << (videoFlags & SDL_HWSURFACE == SDL_HWSURFACE ? "on" : "off") <<
|
||||||
|
" hw-blit: " << (videoFlags & SDL_HWACCEL == SDL_HWACCEL ? "on" : "off") << std::endl;
|
||||||
|
throw E_NOTSUPPORTED(SDL_GetError());
|
||||||
|
}
|
||||||
|
|
||||||
glViewport(0, 0, w, h);
|
glViewport(0, 0, w, h);
|
||||||
width = w;
|
width = w;
|
||||||
height = h;
|
height = h;
|
||||||
|
GL_CHECKERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Screen::set3DProjection() {
|
void Screen::set3DProjection() {
|
||||||
|
10
gl_screen.h
10
gl_screen.h
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -44,6 +44,11 @@ namespace OpenGL {
|
|||||||
Uint32 getHeight();
|
Uint32 getHeight();
|
||||||
bool getFullscreen();
|
bool getFullscreen();
|
||||||
void makeScreenshot(const char* filename);
|
void makeScreenshot(const char* filename);
|
||||||
|
inline float getFieldOfView() { return fieldOfView; }
|
||||||
|
inline float getNearPlane() { return nearPlane; }
|
||||||
|
inline float getFarPlane() { return farPlane; }
|
||||||
|
void setupGlVars( float fov, float near_p, float far_p);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void initGL();
|
void initGL();
|
||||||
void initSDL();
|
void initSDL();
|
||||||
@ -54,7 +59,8 @@ namespace OpenGL {
|
|||||||
float nearPlane;
|
float nearPlane;
|
||||||
float farPlane;
|
float farPlane;
|
||||||
static const Uint32 defaultVideoFlags =
|
static const Uint32 defaultVideoFlags =
|
||||||
SDL_OPENGL | SDL_GL_DOUBLEBUFFER | SDL_HWPALETTE | SDL_HWACCEL;
|
SDL_OPENGL | SDL_GL_DOUBLEBUFFER;// | SDL_HWPALETTE | SDL_HWACCEL;
|
||||||
|
//FIXME: use ^ here as well? not just SDL_GL_SetAttribute?
|
||||||
|
|
||||||
SDL_Surface *surface;
|
SDL_Surface *surface;
|
||||||
};
|
};
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -22,11 +22,14 @@
|
|||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
|
#include <SDL_image.h>
|
||||||
#include "gl_spritecache.h"
|
#include "gl_spritecache.h"
|
||||||
#include "opengta.h"
|
#include "opengta.h"
|
||||||
#include "dataholder.h"
|
#include "dataholder.h"
|
||||||
#include "buffercache.h"
|
#include "buffercache.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
//#include "physfsrwops.h"
|
||||||
|
//#include "image_loader.h"
|
||||||
|
|
||||||
namespace OpenGL {
|
namespace OpenGL {
|
||||||
SpriteIdentifier::SpriteIdentifier() : sprNum(0), remap(-1), delta(0) {}
|
SpriteIdentifier::SpriteIdentifier() : sprNum(0), remap(-1), delta(0) {}
|
||||||
@ -187,6 +190,26 @@ namespace OpenGL {
|
|||||||
getSpriteBitmap(sprite_num, remap , delta);
|
getSpriteBitmap(sprite_num, remap , delta);
|
||||||
unsigned int glwidth = 1;
|
unsigned int glwidth = 1;
|
||||||
unsigned int glheight = 1;
|
unsigned int glheight = 1;
|
||||||
|
#if 0
|
||||||
|
if (sprite_num == 257) {
|
||||||
|
info->w = 72;
|
||||||
|
info->h = 72;
|
||||||
|
SDL_RWops * rwops = PHYSFSRWOPS_openRead("tree.png");//file.c_str());
|
||||||
|
SDL_Surface *surface = IMG_Load_RW(rwops, 1);
|
||||||
|
assert(surface);
|
||||||
|
uint16_t bpp = surface->format->BytesPerPixel;
|
||||||
|
ImageUtil::NextPowerOfTwo npot(surface->w, surface->h);
|
||||||
|
uint8_t * buffer = Util::BufferCacheHolder::Instance().requestBuffer(npot.w * npot.h * bpp);
|
||||||
|
SDL_LockSurface(surface);
|
||||||
|
ImageUtil::copyImage2Image(buffer, (uint8_t*)surface->pixels, surface->pitch, surface->h,
|
||||||
|
npot.w * bpp);
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
|
|
||||||
|
GLuint texture = ImageUtil::createGLTexture(npot.w, npot.h, (bpp == 4) ? true : false, buffer);
|
||||||
|
return OpenGL::PagedTexture(texture, 0, 0, GLfloat(surface->w)/npot.w, GLfloat(surface->h)/npot.h);
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
while(glwidth < info->w)
|
while(glwidth < info->w)
|
||||||
glwidth <<= 1;
|
glwidth <<= 1;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
8
id_sys.cpp
Normal file
8
id_sys.cpp
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
#include "id_sys.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
uint32_t TypeIdBlackBox::nextId = 0;
|
||||||
|
uint32_t TypeIdBlackBox::firstPlayerId = 0xffffffff - 32;
|
||||||
|
uint32_t TypeIdBlackBox::lastPlayerId = 0xffffffff;
|
||||||
|
|
||||||
|
}
|
29
id_sys.h
Normal file
29
id_sys.h
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
#ifndef ID_COUNTER_SYS_H
|
||||||
|
#define ID_COUNTER_SYS_H
|
||||||
|
|
||||||
|
#include "game_objects.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
|
||||||
|
class TypeIdBlackBox {
|
||||||
|
public:
|
||||||
|
static uint32_t requestId() {
|
||||||
|
if (nextId + 1 >= firstPlayerId) {
|
||||||
|
throw E_OUTOFRANGE("Player id range reached!");
|
||||||
|
}
|
||||||
|
return nextId++;
|
||||||
|
}
|
||||||
|
static uint32_t getPlayerId() {
|
||||||
|
return lastPlayerId;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
static uint32_t nextId;
|
||||||
|
static uint32_t firstPlayerId;
|
||||||
|
static uint32_t lastPlayerId;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
13
license.txt
13
license.txt
@ -1,4 +1,4 @@
|
|||||||
Copyright (c) 2005-2006 tok@openlinux.org.uk
|
Copyright (c) 2005-2007 tok@openlinux.org.uk
|
||||||
|
|
||||||
This software is provided 'as-is', without any express or implied warranty.
|
This software is provided 'as-is', without any express or implied warranty.
|
||||||
In no event will the authors be held liable for any damages arising from
|
In no event will the authors be held liable for any damages arising from
|
||||||
@ -18,7 +18,7 @@ the following restrictions:
|
|||||||
Altered source versions must be plainly marked as such, and must not be
|
Altered source versions must be plainly marked as such, and must not be
|
||||||
misrepresented as being the original software.
|
misrepresented as being the original software.
|
||||||
|
|
||||||
5. This notice may not be removed or altered from any distribution.
|
4. This notice may not be removed or altered from any distribution.
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
The file formats of the data files are described in documentation released
|
The file formats of the data files are described in documentation released
|
||||||
@ -54,6 +54,15 @@ these remain under their respective licenses.
|
|||||||
notice appear in all copies and that both that copyright notice and this
|
notice appear in all copies and that both that copyright notice and this
|
||||||
permission notice appear in supporting documentation.
|
permission notice appear in supporting documentation.
|
||||||
|
|
||||||
|
* OpenSteer
|
||||||
|
Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
MIT license
|
||||||
|
|
||||||
|
* ColDet - C++ 3D Collision Detection Library
|
||||||
|
Copyright (C) 2000 Amir Geva
|
||||||
|
GNU Library General Public License
|
||||||
|
|
||||||
***************************************************************************
|
***************************************************************************
|
||||||
Please do not redistribute the data files of the original game together
|
Please do not redistribute the data files of the original game together
|
||||||
with this software.
|
with this software.
|
||||||
|
@ -1,13 +1,28 @@
|
|||||||
#ifndef OGTA_LOCAL_PLAYER_H
|
#ifndef OGTA_LOCAL_PLAYER_H
|
||||||
#define OGTA_LOCAL_PLAYER_H
|
#define OGTA_LOCAL_PLAYER_H
|
||||||
#include "Singleton.h"
|
#include "Singleton.h"
|
||||||
#include "pedestrian.h"
|
#include "game_objects.h"
|
||||||
|
#include "entity_controller.h"
|
||||||
|
#include "id_sys.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
|
|
||||||
class PlayerController : public Pedestrian::Controller {
|
class PlayerController { // : public PedController { //public Pedestrian::Controller {
|
||||||
public:
|
public:
|
||||||
PlayerController() { turn = 0; move = 0; }
|
PlayerController() {
|
||||||
|
playerId = TypeIdBlackBox::getPlayerId();
|
||||||
|
pc_ptr = NULL;
|
||||||
|
}
|
||||||
|
PedController & getCtrl() {
|
||||||
|
assert(pc_ptr);
|
||||||
|
return *pc_ptr;
|
||||||
|
}
|
||||||
|
void setCtrl(PedController & pc) {
|
||||||
|
pc_ptr = &pc;
|
||||||
|
}
|
||||||
|
private:
|
||||||
|
uint32_t playerId;
|
||||||
|
PedController * pc_ptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef Loki::SingletonHolder<PlayerController, Loki::CreateUsingNew,
|
typedef Loki::SingletonHolder<PlayerController, Loki::CreateUsingNew,
|
||||||
|
87
lua_addon/lua_ini_bridge.cpp
Normal file
87
lua_addon/lua_ini_bridge.cpp
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
#include "lua_ini_bridge.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
namespace OpenGTA { namespace Script {
|
||||||
|
|
||||||
|
#define GLOBAL_TABLE(name) lua_newtable(L); lua_setglobal(L, name)
|
||||||
|
|
||||||
|
IniScriptBridge::IniScriptBridge(const std::string & file) :
|
||||||
|
ScriptParser(file) {
|
||||||
|
L = lua_open();
|
||||||
|
luaL_openlibs(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
IniScriptBridge::~IniScriptBridge() {
|
||||||
|
lua_close(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniScriptBridge::reset() {
|
||||||
|
lua_settop(L, 0);
|
||||||
|
GLOBAL_TABLE("commands");
|
||||||
|
GLOBAL_TABLE("definitions");
|
||||||
|
lua_gc(L, LUA_GCCOLLECT, 0);
|
||||||
|
lua_settop(L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniScriptBridge::loadLevel(PHYSFS_uint32 level) {
|
||||||
|
reset();
|
||||||
|
ScriptParser::loadLevel(level);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniScriptBridge::acceptCommand(const char* cmd) {
|
||||||
|
char *skip_idx = strchr(cmd, ' ');
|
||||||
|
assert(skip_idx);
|
||||||
|
*skip_idx = 0;
|
||||||
|
int idx = atoi(cmd);
|
||||||
|
++skip_idx;
|
||||||
|
//INFO << idx << " " << skip_idx << std::endl;
|
||||||
|
lua_settop(L, 0);
|
||||||
|
|
||||||
|
lua_getglobal(L, "commands");
|
||||||
|
lua_pushinteger(L, idx);
|
||||||
|
lua_pushstring(L, skip_idx);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
|
||||||
|
lua_settop(L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void IniScriptBridge::acceptDefinition(const char* def) {
|
||||||
|
char *skip_idx = strchr(def, ' ');
|
||||||
|
assert(skip_idx);
|
||||||
|
*skip_idx = 0;
|
||||||
|
int idx = atoi(def);
|
||||||
|
skip_idx++;
|
||||||
|
if (*skip_idx == '1' && *(skip_idx+1) == ' ')
|
||||||
|
skip_idx += 2;
|
||||||
|
//INFO << idx << " " << skip_idx << std::endl;
|
||||||
|
|
||||||
|
lua_settop(L, 0);
|
||||||
|
|
||||||
|
lua_getglobal(L, "definitions");
|
||||||
|
lua_pushinteger(L, idx);
|
||||||
|
lua_pushstring(L, skip_idx);
|
||||||
|
lua_settable(L, -3);
|
||||||
|
|
||||||
|
lua_settop(L, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
}}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
void on_exit() {
|
||||||
|
PHYSFS_deinit();
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
PHYSFS_init(argv[0]);
|
||||||
|
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||||
|
atexit(on_exit);
|
||||||
|
OpenGTA::Script::IniScriptBridge p(argv[1]);
|
||||||
|
p.loadLevel(atoi(argv[2]));
|
||||||
|
|
||||||
|
if (luaL_loadfile(p.L, argv[3]) || lua_pcall(p.L, 0, 0, 0))
|
||||||
|
ERROR << lua_tostring(p.L, -1);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#endif
|
25
lua_addon/lua_ini_bridge.h
Normal file
25
lua_addon/lua_ini_bridge.h
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
#ifndef LUA_INI_BRIDGE_H
|
||||||
|
#define LUA_INI_BRIDGE_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include "read_ini.h"
|
||||||
|
#include "lua.hpp"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
namespace Script {
|
||||||
|
class IniScriptBridge : public ScriptParser {
|
||||||
|
public:
|
||||||
|
IniScriptBridge(const std::string &file);
|
||||||
|
~IniScriptBridge();
|
||||||
|
lua_State *L;
|
||||||
|
void loadLevel(PHYSFS_uint32 level);
|
||||||
|
protected:
|
||||||
|
void reset();
|
||||||
|
void acceptDefinition(const char*);
|
||||||
|
void acceptCommand(const char*);
|
||||||
|
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
26
lua_addon/lua_spritecache.cpp
Normal file
26
lua_addon/lua_spritecache.cpp
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
#include "lua_spritecache.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
namespace Script {
|
||||||
|
using namespace OpenGL;
|
||||||
|
int SpriteCache::getScale2x(lua_State *L) {
|
||||||
|
bool b = SpriteCacheHolder::Instance().getScale2x();
|
||||||
|
lua_pushboolean(L, b);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
int SpriteCache::setScale2x(lua_State *L) {
|
||||||
|
bool b = SpriteCacheHolder::Instance().getScale2x();
|
||||||
|
bool v = lua_toboolean(L, 1);
|
||||||
|
if (b != v)
|
||||||
|
SpriteCacheHolder::Instance().setScale2x(v);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
#define method(name) {#name, SpriteCache::name}
|
||||||
|
const luaL_reg SpriteCache::methods[] = {
|
||||||
|
method(setScale2x),
|
||||||
|
method(getScale2x),
|
||||||
|
{NULL, NULL}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
19
lua_addon/lua_spritecache.h
Normal file
19
lua_addon/lua_spritecache.h
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
#ifndef LUA_OGTA_SPRITECACHE_H
|
||||||
|
#define LUA_OGTA_SPRITECACHE_H
|
||||||
|
|
||||||
|
#include "gl_spritecache.h"
|
||||||
|
#include "lua.hpp"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
namespace Script {
|
||||||
|
|
||||||
|
class SpriteCache {
|
||||||
|
public:
|
||||||
|
static int getScale2x(lua_State *L);
|
||||||
|
static int setScale2x(lua_State *L);
|
||||||
|
|
||||||
|
static const luaL_reg methods[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,6 +1,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include "lua_vm.h"
|
#include "lua_vm.h"
|
||||||
#include "lunar.h"
|
#include "lunar.h"
|
||||||
|
#include "lua_map.h"
|
||||||
#include "lua_cityview.h"
|
#include "lua_cityview.h"
|
||||||
#include "lua_stackguard.h"
|
#include "lua_stackguard.h"
|
||||||
#include "lua_camera.h"
|
#include "lua_camera.h"
|
||||||
@ -33,22 +34,42 @@ namespace OpenGTA {
|
|||||||
void LuaVM::prepare() {
|
void LuaVM::prepare() {
|
||||||
LGUARD(L);
|
LGUARD(L);
|
||||||
if (!_registered) {
|
if (!_registered) {
|
||||||
|
Lunar<Block>::Register2(L);
|
||||||
|
Lunar<LMap>::Register2(L);
|
||||||
|
/*
|
||||||
Lunar<CityView>::Register2(L);
|
Lunar<CityView>::Register2(L);
|
||||||
luaL_openlib(L, "camera", Camera::methods, 0);
|
luaL_openlib(L, "camera", Camera::methods, 0);
|
||||||
luaL_openlib(L, "screen", Screen::methods, 0);
|
luaL_openlib(L, "screen", Screen::methods, 0);
|
||||||
luaL_openlib(L, "spritecache", SpriteCache::methods, 0);
|
luaL_openlib(L, "spritecache", SpriteCache::methods, 0);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
_registered = true;
|
_registered = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
lua_State* LuaVM::getInternalState() {
|
||||||
|
return(L);
|
||||||
|
}
|
||||||
|
|
||||||
|
void LuaVM::setMap(OpenGTA::Map & map) {
|
||||||
|
LGUARD(L);
|
||||||
|
LMap * mptr = static_cast<LMap*>(&map);
|
||||||
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||||
|
int scv_ref = Lunar<LMap>::push(L, mptr, false);
|
||||||
|
lua_pushliteral(L, "map");
|
||||||
|
lua_pushvalue(L, scv_ref);
|
||||||
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
|
}
|
||||||
|
|
||||||
void LuaVM::setCityView(OpenGTA::CityView & cv) {
|
void LuaVM::setCityView(OpenGTA::CityView & cv) {
|
||||||
LGUARD(L);
|
LGUARD(L);
|
||||||
|
/*
|
||||||
CityView *scv = static_cast<CityView*>(&cv);
|
CityView *scv = static_cast<CityView*>(&cv);
|
||||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||||
int scv_ref = Lunar<CityView>::push(L, scv, false);
|
int scv_ref = Lunar<CityView>::push(L, scv, false);
|
||||||
lua_pushliteral(L, "city_view");
|
lua_pushliteral(L, "city_view");
|
||||||
lua_pushvalue(L, scv_ref);
|
lua_pushvalue(L, scv_ref);
|
||||||
lua_settable(L, LUA_GLOBALSINDEX);
|
lua_settable(L, LUA_GLOBALSINDEX);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
void LuaVM::runString(const char* _str) {
|
void LuaVM::runString(const char* _str) {
|
||||||
|
@ -14,18 +14,20 @@ namespace OpenGTA {
|
|||||||
void runString(const char*);
|
void runString(const char*);
|
||||||
void runFile(const char*);
|
void runFile(const char*);
|
||||||
void callSimpleFunction(const char*);
|
void callSimpleFunction(const char*);
|
||||||
void prepare();
|
|
||||||
void setCityView(OpenGTA::CityView &);
|
void setCityView(OpenGTA::CityView &);
|
||||||
|
void setMap(OpenGTA::Map &);
|
||||||
int getGlobalInt(const char*);
|
int getGlobalInt(const char*);
|
||||||
float getGlobalFloat(const char*);
|
float getGlobalFloat(const char*);
|
||||||
const char* getGlobalString(const char*);
|
const char* getGlobalString(const char*);
|
||||||
void setGlobalInt(const char*, int);
|
void setGlobalInt(const char*, int);
|
||||||
void setGlobalFloat(const char*, float);
|
void setGlobalFloat(const char*, float);
|
||||||
void setGlobalString(const char*, const char*);
|
void setGlobalString(const char*, const char*);
|
||||||
|
lua_State *getInternalState();
|
||||||
protected:
|
protected:
|
||||||
lua_State *L;
|
lua_State *L;
|
||||||
private:
|
private:
|
||||||
bool _registered;
|
bool _registered;
|
||||||
|
void prepare();
|
||||||
};
|
};
|
||||||
typedef Loki::SingletonHolder<LuaVM, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
typedef Loki::SingletonHolder<LuaVM, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||||
Loki::SingleThreaded> LuaVMHolder;
|
Loki::SingleThreaded> LuaVMHolder;
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
extern void parse_args(int argc, char* argv[]);
|
extern void parse_args(int argc, char* argv[]);
|
||||||
extern void on_exit();
|
extern void on_exit();
|
||||||
extern void run_init();
|
extern void run_init(const char*);
|
||||||
extern void run_main();
|
extern void run_main();
|
||||||
|
|
||||||
int global_EC = 0;
|
int global_EC = 0;
|
||||||
@ -30,10 +30,10 @@ int main(int argc, char* argv[]) {
|
|||||||
INFO << "ignoring exceptions" << std::endl;
|
INFO << "ignoring exceptions" << std::endl;
|
||||||
|
|
||||||
if (!catch_exceptions)
|
if (!catch_exceptions)
|
||||||
run_init();
|
run_init(argv[0]);
|
||||||
else {
|
else {
|
||||||
try {
|
try {
|
||||||
run_init();
|
run_init(argv[0]);
|
||||||
}
|
}
|
||||||
catch (Exception & e) {
|
catch (Exception & e) {
|
||||||
ERROR << "Exception during startup: " << e.what() << endl;
|
ERROR << "Exception during startup: " << e.what() << endl;
|
||||||
|
9
makefile
9
makefile
@ -1,7 +1,7 @@
|
|||||||
include src_list.make
|
include src_list.make
|
||||||
|
|
||||||
INC_EX_LIBS = $(PHYSFS_INC) $(SDL_INC) $(LUA_INC)
|
INC_EX_LIBS = $(PHYSFS_INC) $(SDL_INC) $(LUA_INC)
|
||||||
INC_INTERN = -I. -Iloki/include/loki -Iutil -Icoldet -Imath
|
INC_INTERN = -I. -Iloki/include/loki -Iutil -Icoldet -Imath -Iopensteer/include
|
||||||
|
|
||||||
INC = $(INC_INTERN) $(INC_EX_LIBS)
|
INC = $(INC_INTERN) $(INC_EX_LIBS)
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ coldet/libcoldet.a:
|
|||||||
make -C coldet -f makefile.g++ all
|
make -C coldet -f makefile.g++ all
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -f tags depend *.o tools/*.o coldet/*.o lua_addon/*.o math/*.o util/*.o \
|
rm -f tags depend *.o tools/*.o coldet/*.o lua_addon/*.o math/*.o util/*.o opensteer/src/Clock.o \
|
||||||
spriteplayer gfxextract viewer $(TOOLS) objdump objdump_map minimap slopeview luaviewer g24
|
spriteplayer gfxextract viewer $(TOOLS) objdump objdump_map minimap slopeview luaviewer g24
|
||||||
|
|
||||||
html: doxy_main.h
|
html: doxy_main.h
|
||||||
@ -70,9 +70,12 @@ rclean:
|
|||||||
|
|
||||||
libclean:
|
libclean:
|
||||||
make -C coldet -f makefile.g++ clean
|
make -C coldet -f makefile.g++ clean
|
||||||
|
make -c loki clean
|
||||||
|
rm -f loki/lib/libloki.*
|
||||||
|
rm -f $(OSTEER_OBJ)
|
||||||
|
|
||||||
|
|
||||||
depend: loki src_list.make
|
depend: loki src_list.make
|
||||||
$(RM) depend
|
$(RM) depend
|
||||||
$(CXX) $(CXXFLAGS) -DGCC -E -MM $(GL_SRC) $(OGTA_SRC) $(UTIL_SRC) > depend
|
$(CXX) $(CXXFLAGS) -E -MM $(GL_SRC) $(OGTA_SRC) $(UTIL_SRC) > depend
|
||||||
|
|
||||||
|
218
math/interpolate.hpp
Normal file
218
math/interpolate.hpp
Normal file
@ -0,0 +1,218 @@
|
|||||||
|
#ifndef MMATH_INTERPOLATE_H
|
||||||
|
#define MMATH_INTERPOLATE_H
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
namespace Interpolator {
|
||||||
|
|
||||||
|
/** Interpolate between values - creating data out of nothing.
|
||||||
|
*
|
||||||
|
* The math mainly comes from:
|
||||||
|
* http://local.wasp.uwa.edu.au/~pbourke/other/interpolation/
|
||||||
|
*
|
||||||
|
* Capsuled into classes which store the values to allow usage
|
||||||
|
* as a kind of data - consumer/producer.
|
||||||
|
*
|
||||||
|
* This idea comes from here: */
|
||||||
|
// http://exult.cvs.sourceforge.net/*checkout*/exult/exult/audio/Audio.cc
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Linear {
|
||||||
|
public:
|
||||||
|
Linear(const T & y1, const T & y2);
|
||||||
|
T getAt(const T & mu) const;
|
||||||
|
void shiftAndFeed(const T & y_i);
|
||||||
|
private:
|
||||||
|
T v1, v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Cubic {
|
||||||
|
public:
|
||||||
|
Cubic(const T & y0,
|
||||||
|
const T & y1, const T & y2, const T & y3);
|
||||||
|
Cubic(const T & y1,
|
||||||
|
const T & y2, const T & y3);
|
||||||
|
|
||||||
|
void shiftAndFeed(const T & y_i);
|
||||||
|
void shift();
|
||||||
|
T getAt(const T & mu) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setCoefficients(const T y0,
|
||||||
|
const T y1, const T y2, const T y3);
|
||||||
|
T a0, a1, a2, a3;
|
||||||
|
T v2, v3;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Cosine {
|
||||||
|
public:
|
||||||
|
Cosine(const T & y1, const T & y2);
|
||||||
|
|
||||||
|
T getAt(const T & mu) const;
|
||||||
|
void shiftAndFeed(const T & y_i);
|
||||||
|
|
||||||
|
private:
|
||||||
|
T v1, v2;
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
class Hermite {
|
||||||
|
public:
|
||||||
|
Hermite(const T & y1, const T & y2, const T & y3,
|
||||||
|
const T & _tension, const T & _bias);
|
||||||
|
Hermite(const T & y0, const T & y1, const T & y2,
|
||||||
|
const T & y3, const T & _tension, const T & _bias);
|
||||||
|
|
||||||
|
T getAt(const T & mu) const;
|
||||||
|
void shiftAndFeed(const T & y_i);
|
||||||
|
void shift();
|
||||||
|
void setTension(const T & _tension);
|
||||||
|
void setBias(const T & _bias);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void setCoefficients(const T y0, const T y1, const T y2,
|
||||||
|
const T y3);
|
||||||
|
void updateCoefficients();
|
||||||
|
T m0, m1;
|
||||||
|
T v0, v1, v2, v3;
|
||||||
|
T tension, bias;
|
||||||
|
};
|
||||||
|
|
||||||
|
// implementation
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Linear<T>::Linear(const T & y1, const T & y2) : v1(y1), v2(y2) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Linear<T>::getAt(const T & mu) const {
|
||||||
|
return v1 * (1 - mu) + v2 * mu;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Linear<T>::shiftAndFeed(const T & y_i) {
|
||||||
|
v1 = v2;
|
||||||
|
v2 = y_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cubic
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Cubic<T>::Cubic(const T & y0,
|
||||||
|
const T & y1, const T & y2, const T & y3) {
|
||||||
|
setCoefficients(y0, y1, y2, y3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Cubic<T>::Cubic(const T & y1,
|
||||||
|
const T & y2, const T & y3) {
|
||||||
|
setCoefficients(2 * y1 - y2, y1, y2, y3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Cubic<T>::shiftAndFeed(const T & y_i) {
|
||||||
|
setCoefficients(a3, v2, v3, y_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Cubic<T>::shift() {
|
||||||
|
setCoefficients(a3, v2, v3, 2 * v2 - a3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Cubic<T>::setCoefficients(const T y0,
|
||||||
|
const T y1, const T y2, const T y3) {
|
||||||
|
v2 = y2; v3 = y3;
|
||||||
|
|
||||||
|
a0 = y3 - y2 - y0 + y1;
|
||||||
|
a1 = y0 - y1 - a0;
|
||||||
|
a2 = y2 - y0;
|
||||||
|
a3 = y1;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Cubic<T>::getAt(const T & mu) const {
|
||||||
|
const T mu_sq = mu * mu;
|
||||||
|
return(a0 * mu * mu_sq + a1 * mu_sq + a2 * mu + a3);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cosine
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Cosine<T>::Cosine(const T & y1, const T & y2) : v1(y1), v2(y2) {}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Cosine<T>::getAt(const T & mu) const {
|
||||||
|
T mu2 = (1 - cos(mu * M_PI)) / 2;
|
||||||
|
return v1 * (1 - mu2) + v2 * mu2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Cosine<T>::shiftAndFeed(const T & y_i) {
|
||||||
|
v1 = v2;
|
||||||
|
v2 = y_i;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Hermite
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
Hermite<T>::Hermite(const T & y1, const T & y2, const T & y3,
|
||||||
|
const T & _tension, const T & _bias) : tension(_tension), bias(_bias) {
|
||||||
|
setCoefficients(2 * y1 - y2, y1, y2, y3);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
T Hermite<T>::getAt(const T & mu) const {
|
||||||
|
const T mu_sq = mu * mu;
|
||||||
|
const T mu_cu = mu_sq * mu;
|
||||||
|
|
||||||
|
T a0 = 2 * mu_cu - 3 * mu_sq + 1;
|
||||||
|
T a1 = mu_cu - 2 * mu_sq + mu;
|
||||||
|
T a2 = mu_cu - mu_sq;
|
||||||
|
T a3 =-2 * mu_cu + 3 * mu_sq;
|
||||||
|
|
||||||
|
return a0 * v1 + a1 * m0 + a2 * m1 + a3 * v2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::setCoefficients(const T y0, const T y1, const T y2,
|
||||||
|
const T y3) {
|
||||||
|
v0 = y0; v1 = y1; v2 = y2; v3 = y3;
|
||||||
|
updateCoefficients();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::updateCoefficients() {
|
||||||
|
m0 = (v1 - v0) * (1 + bias) * (1 - tension) / 2;
|
||||||
|
m0 += (v2 - v1) * (1 - bias) * (1 - tension) / 2;
|
||||||
|
m1 = (v2 - v1) * (1 + bias) * (1 - tension) / 2;
|
||||||
|
m1 += (v3 - v2) * (1 - bias) * (1 - tension) / 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::setTension(const T & _tension) {
|
||||||
|
tension = _tension;
|
||||||
|
updateCoefficients();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::setBias(const T & _bias) {
|
||||||
|
bias = _bias;
|
||||||
|
updateCoefficients();
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::shiftAndFeed(const T & y_i) {
|
||||||
|
setCoefficients(v1, v2, v3, y_i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
void Hermite<T>::shift() {
|
||||||
|
setCoefficients(v1, v2, v3, 2 * v2 - v1);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -8,7 +8,7 @@
|
|||||||
//
|
//
|
||||||
// Check if a point is in this bounding box
|
// Check if a point is in this bounding box
|
||||||
//
|
//
|
||||||
bool OBox::IsPointInBox(const Vector3D &InP)
|
bool OBox::IsPointInBox(const Vector3D &InP) const
|
||||||
{
|
{
|
||||||
// Rotate the point into the box's coordinates
|
// Rotate the point into the box's coordinates
|
||||||
Vector3D P = Transform(InP, m_M.Inverse());
|
Vector3D P = Transform(InP, m_M.Inverse());
|
||||||
@ -23,7 +23,7 @@ bool OBox::IsPointInBox(const Vector3D &InP)
|
|||||||
//
|
//
|
||||||
// Check if a sphere overlaps any part of this bounding box
|
// Check if a sphere overlaps any part of this bounding box
|
||||||
//
|
//
|
||||||
bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius)
|
bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius) const
|
||||||
{
|
{
|
||||||
float fDist;
|
float fDist;
|
||||||
float fDistSq = 0;
|
float fDistSq = 0;
|
||||||
@ -44,7 +44,7 @@ bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius)
|
|||||||
//
|
//
|
||||||
// Check if the bounding box is completely behind a plane( defined by a normal and a point )
|
// Check if the bounding box is completely behind a plane( defined by a normal and a point )
|
||||||
//
|
//
|
||||||
bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP )
|
bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||||
{
|
{
|
||||||
// Plane Normal in Box Space
|
// Plane Normal in Box Space
|
||||||
Vector3D Norm = rotateVector(InNorm, m_M.Inverse() );
|
Vector3D Norm = rotateVector(InNorm, m_M.Inverse() );
|
||||||
@ -62,7 +62,7 @@ bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP )
|
|||||||
//
|
//
|
||||||
// Does the Line (L1, L2) intersect the Box?
|
// Does the Line (L1, L2) intersect the Box?
|
||||||
//
|
//
|
||||||
bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 )
|
bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 ) const
|
||||||
{
|
{
|
||||||
// Put line in box space
|
// Put line in box space
|
||||||
Matrix3D MInv = m_M.Inverse();
|
Matrix3D MInv = m_M.Inverse();
|
||||||
@ -90,7 +90,7 @@ bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 )
|
|||||||
//
|
//
|
||||||
// Returns a 3x3 rotation matrix as vectors
|
// Returns a 3x3 rotation matrix as vectors
|
||||||
//
|
//
|
||||||
inline void OBox::GetInvRot( Vector3D *pvRot )
|
inline void OBox::GetInvRot( Vector3D *pvRot ) const
|
||||||
{
|
{
|
||||||
pvRot[0] = Vector3D( m_M.m[0][0], m_M.m[0][1], m_M.m[0][2] );
|
pvRot[0] = Vector3D( m_M.m[0][0], m_M.m[0][1], m_M.m[0][2] );
|
||||||
pvRot[1] = Vector3D( m_M.m[1][0], m_M.m[1][1], m_M.m[1][2] );
|
pvRot[1] = Vector3D( m_M.m[1][0], m_M.m[1][1], m_M.m[1][2] );
|
||||||
@ -101,7 +101,7 @@ inline void OBox::GetInvRot( Vector3D *pvRot )
|
|||||||
// Check if any part of a box is inside any part of another box
|
// Check if any part of a box is inside any part of another box
|
||||||
// Uses the separating axis test.
|
// Uses the separating axis test.
|
||||||
//
|
//
|
||||||
bool OBox::IsBoxInBox( OBox &BBox )
|
bool OBox::IsBoxInBox( OBox &BBox ) const
|
||||||
{
|
{
|
||||||
Vector3D SizeA = m_Extent;
|
Vector3D SizeA = m_Extent;
|
||||||
Vector3D SizeB = BBox.m_Extent;
|
Vector3D SizeB = BBox.m_Extent;
|
||||||
|
18
math/obox.h
18
math/obox.h
@ -12,6 +12,8 @@ class OBox
|
|||||||
{ Set( m, extent ); }
|
{ Set( m, extent ); }
|
||||||
OBox( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
OBox( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
||||||
{ Set( m, low, high ); }
|
{ Set( m, low, high ); }
|
||||||
|
OBox( const OBox & other)
|
||||||
|
{ Set( other.m_M, other.m_Extent ); }
|
||||||
|
|
||||||
void Set( const Matrix3D & m, const Vector3D & extent )
|
void Set( const Matrix3D & m, const Vector3D & extent )
|
||||||
{
|
{
|
||||||
@ -25,17 +27,17 @@ class OBox
|
|||||||
m_Extent = 0.5f * (high - low);
|
m_Extent = 0.5f * (high - low);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3D GetSize()
|
Vector3D GetSize() const
|
||||||
{ return 2.0f * m_Extent; }
|
{ return 2.0f * m_Extent; }
|
||||||
Vector3D GetCenterPoint()
|
Vector3D GetCenterPoint() const
|
||||||
{ return m_M.GetTranslate(); }
|
{ return m_M.GetTranslate(); }
|
||||||
void GetInvRot( Vector3D *pvRot );
|
void GetInvRot( Vector3D *pvRot ) const;
|
||||||
|
|
||||||
bool IsPointInBox( const Vector3D & p );
|
bool IsPointInBox( const Vector3D & p ) const ;
|
||||||
bool IsBoxInBox( OBox & box );
|
bool IsBoxInBox( OBox & box ) const ;
|
||||||
bool IsSphereInBox( const Vector3D & p, float fRadius );
|
bool IsSphereInBox( const Vector3D & p, float fRadius ) const ;
|
||||||
bool IsLineInBox( const Vector3D & l1, const Vector3D & l2 );
|
bool IsLineInBox( const Vector3D & l1, const Vector3D & l2 ) const ;
|
||||||
bool BoxOutsidePlane( const Vector3D & normal, const Vector3D & p );
|
bool BoxOutsidePlane( const Vector3D & normal, const Vector3D & p ) const ;
|
||||||
|
|
||||||
// Data
|
// Data
|
||||||
Matrix3D m_M;
|
Matrix3D m_M;
|
||||||
|
108
math/rectangle.hpp
Normal file
108
math/rectangle.hpp
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
#ifndef RECTANGLE_2D_H
|
||||||
|
#define RECTANGLE_2D_H
|
||||||
|
|
||||||
|
#include <list>
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
|
||||||
|
template <typename U> struct Rectangle {
|
||||||
|
U x;
|
||||||
|
U y;
|
||||||
|
U w;
|
||||||
|
U h;
|
||||||
|
|
||||||
|
Rectangle() : x(0), y(0), w(0), h(0) {}
|
||||||
|
|
||||||
|
Rectangle(U _x, U _y, U _w, U _h) :
|
||||||
|
x(_x), y(_y), w(_w), h(_h) {}
|
||||||
|
|
||||||
|
Rectangle(const Rectangle<U> & o) :
|
||||||
|
x(o.x), y(o.y), w(o.w), h(o.h) {}
|
||||||
|
|
||||||
|
inline bool operator == (const Rectangle<U> & o) const {
|
||||||
|
return ((x == o.x) && (y == o.y) && (w == o.w) && (h == o.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
inline bool isInside(U _x, U _y) const {
|
||||||
|
return ((_x >= x) && (_y >= y) &&
|
||||||
|
(_x <= x + w) && (_y <= y + h) );
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U> bool rectangle_test_inside (
|
||||||
|
const Rectangle<U> & larger,
|
||||||
|
const Rectangle<U> & smaller ) {
|
||||||
|
return (larger.isInside( smaller.x, smaller.y ) &&
|
||||||
|
larger.isInside( smaller.x + smaller.w, smaller.y ) &&
|
||||||
|
larger.isInside( smaller.x, smaller.y + smaller.h ) &&
|
||||||
|
larger.isInside( smaller.x + smaller.w, smaller.y + smaller.h));
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> bool rectangle_test_leftborder (
|
||||||
|
const Rectangle<U> & larger,
|
||||||
|
const Rectangle<U> & smaller ) {
|
||||||
|
return (larger.x == smaller.x);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> bool rectangle_test_rightborder (
|
||||||
|
const Rectangle<U> & larger,
|
||||||
|
const Rectangle<U> & smaller ) {
|
||||||
|
return (larger.x + larger.w == smaller.x + smaller.w);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> bool rectangle_test_bottomborder (
|
||||||
|
const Rectangle<U> & larger,
|
||||||
|
const Rectangle<U> & smaller ) {
|
||||||
|
return (larger.y == smaller.y);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename U> bool rectangle_test_topborder (
|
||||||
|
const Rectangle<U> & larger,
|
||||||
|
const Rectangle<U> & smaller ) {
|
||||||
|
return (larger.y + larger.h == smaller.y + smaller.h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
template <typename U> class RectangleGeometry {
|
||||||
|
public:
|
||||||
|
typedef std::list< Rectangle < U > > ListOfRectangleU;
|
||||||
|
/* void Union (ListOfRectangleU & list, const Rectangle< U > & first,
|
||||||
|
const Rectangle< U > & second);
|
||||||
|
void Intersection(ListOfRectangleU & list, const Rectangle< U > & first,
|
||||||
|
const Rectangle< U > & second);
|
||||||
|
*/
|
||||||
|
static void difference(ListOfRectangleU & list, const Rectangle< U > & first,
|
||||||
|
const Rectangle< U > & second);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <typename U> void RectangleGeometry<U>::difference(ListOfRectangleU & list,
|
||||||
|
const Rectangle< U > & first, const Rectangle< U > & second) {
|
||||||
|
// assume first is larger, second is smaller
|
||||||
|
if (! rectangle_test_leftborder<U>(first, second)) {
|
||||||
|
/*
|
||||||
|
### #
|
||||||
|
#x# split off the left col #
|
||||||
|
### #
|
||||||
|
*/
|
||||||
|
list.push_back( Rectangle<U>( first.x, first.y, second.x - first.x, first.h ) );
|
||||||
|
}
|
||||||
|
if (! rectangle_test_rightborder<U>(first, second)) {
|
||||||
|
// split of the right column
|
||||||
|
list.push_back( Rectangle<U>( second.x + second.w, first.y,
|
||||||
|
first.x + first.w - (second.x + second.w), first.h));
|
||||||
|
}
|
||||||
|
if (! rectangle_test_topborder<U>(first, second)) {
|
||||||
|
// remainder of the top row
|
||||||
|
list.push_back( Rectangle<U>( second.x, second.y + second.h,
|
||||||
|
second.w, first.y + first.h - (second.y + second.h)));
|
||||||
|
}
|
||||||
|
if (! rectangle_test_bottomborder<U>(first, second)) {
|
||||||
|
// remainder of the bottom row
|
||||||
|
list.push_back( Rectangle<U>(second.x, first.y,
|
||||||
|
second.w, second.y - first.y));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -149,6 +149,23 @@ public:
|
|||||||
{
|
{
|
||||||
return fabs (x - v.x) < e && fabs (y - v.y) < e && fabs (z - v.z) < e;
|
return fabs (x - v.x) < e && fabs (y - v.y) < e && fabs (z - v.z) < e;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// component-wise maximum
|
||||||
|
const Vector max(const Vector & other) const {
|
||||||
|
Vector _res;
|
||||||
|
_res.x = (x > other.x) ? x : other.x;
|
||||||
|
_res.y = (y > other.y) ? y : other.y;
|
||||||
|
_res.z = (z > other.x) ? z : other.z;
|
||||||
|
return _res;
|
||||||
|
}
|
||||||
|
|
||||||
|
const Vector abs() const {
|
||||||
|
Vector _res;
|
||||||
|
_res.x = (x >= 0) ? x : -x;
|
||||||
|
_res.y = (y >= 0) ? y : -y;
|
||||||
|
_res.z = (z >= 0) ? z : -z;
|
||||||
|
return _res;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
//
|
//
|
||||||
// A 3D position
|
// A 3D position
|
||||||
|
34
math/weighted_set.cpp
Normal file
34
math/weighted_set.cpp
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
#include "weighted_set.h"
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
WeightedSet::WeightedSet(unsigned int seed) :
|
||||||
|
elements(),
|
||||||
|
rng(seed) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void WeightedSet::add(unsigned int w, unsigned int e) {
|
||||||
|
while (w > 0) {
|
||||||
|
elements.push_back(e);
|
||||||
|
--w;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int WeightedSet::getRandom() {
|
||||||
|
//unsigned int rnd = (int) (totalWeight * (rand() / (RAND_MAX + 1.0)));
|
||||||
|
unsigned int rnd = rng.nextUint(elements.size());
|
||||||
|
return elements[rnd];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
#include <iostream>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
Util::Math::WeightedSet set(int(getpid()) ^ int(time(0)));
|
||||||
|
set.add(1, 1);
|
||||||
|
set.add(2, 2);
|
||||||
|
set.add(2, 3);
|
||||||
|
set.add(3, 4);
|
||||||
|
set.add(3, 5);
|
||||||
|
|
||||||
|
std::cout << set.getRandom() << std::endl;
|
||||||
|
}*/
|
20
math/weighted_set.h
Normal file
20
math/weighted_set.h
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
#ifndef WEIGHTED_SET_H
|
||||||
|
#define WEIGHTED_SET_H
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include "yasli/random.h"
|
||||||
|
|
||||||
|
namespace Math {
|
||||||
|
|
||||||
|
class WeightedSet {
|
||||||
|
public:
|
||||||
|
WeightedSet(unsigned int seed);
|
||||||
|
void add(unsigned int w, unsigned int e);
|
||||||
|
unsigned int getRandom();
|
||||||
|
private:
|
||||||
|
std::vector<unsigned int> elements;
|
||||||
|
Random rng;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
34
navdata.cpp
34
navdata.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -11,8 +11,10 @@
|
|||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
#include <iomanip>
|
||||||
#include "navdata.h"
|
#include "navdata.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
#include "dataholder.h"
|
||||||
#include "m_exceptions.h"
|
#include "m_exceptions.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
@ -67,27 +69,30 @@ namespace OpenGTA {
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
NavData::Sector::Sector(PHYSFS_file* fd) : Rect2D() {
|
NavData::Sector::Sector(PHYSFS_file* fd) : Rect2D(), sam(0), name("") {
|
||||||
sam = 0;
|
sam = 0;
|
||||||
isADummy = 0;
|
isADummy = 0;
|
||||||
std::memset(&name, 0, 30);
|
|
||||||
assert(fd);
|
assert(fd);
|
||||||
|
//memset(name2, 0, 30);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&x), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&x), 1, 1);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&y), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&y), 1, 1);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&w), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&w), 1, 1);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&h), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&h), 1, 1);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&sam), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&sam), 1, 1);
|
||||||
PHYSFS_read(fd, static_cast<void*>(&name), 30, 1);
|
// seek over the name embedded in the mapfile; use sample-num to
|
||||||
|
// lookup in msg-db
|
||||||
|
//PHYSFS_read(fd, static_cast<void*>(&name2), 30, 1);
|
||||||
|
PHYSFS_seek(fd, PHYSFS_tell(fd) + 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
NavData::Sector::Sector() : Rect2D() {
|
NavData::Sector::Sector() : Rect2D(), sam(0), name("") {
|
||||||
x = 0;
|
x = 0;
|
||||||
y = 0;
|
y = 0;
|
||||||
w = 255;
|
w = 255;
|
||||||
h = 255;
|
h = 255;
|
||||||
sam = 0;
|
sam = 0;
|
||||||
std::memset(&name, 0, 30);
|
|
||||||
isADummy = 1;
|
isADummy = 1;
|
||||||
|
//memset(name2, 0, 30);
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* NavData::Sector::getFullName() {
|
const char* NavData::Sector::getFullName() {
|
||||||
@ -117,7 +122,7 @@ namespace OpenGTA {
|
|||||||
return n.c_str();
|
return n.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
NavData::NavData(PHYSFS_uint32 size, PHYSFS_file *fd) {
|
NavData::NavData(PHYSFS_uint32 size, PHYSFS_file *fd, const size_t level_num) {
|
||||||
if (size % 35) {
|
if (size % 35) {
|
||||||
std::ostringstream o;
|
std::ostringstream o;
|
||||||
o << "Navdata size: " << size << " % 35 != 0";
|
o << "Navdata size: " << size << " % 35 != 0";
|
||||||
@ -126,6 +131,8 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
PHYSFS_uint32 c = size / 35;
|
PHYSFS_uint32 c = size / 35;
|
||||||
assert(fd);
|
assert(fd);
|
||||||
|
|
||||||
|
MessageDB & msg = MainMsgHolder::Instance().get();
|
||||||
for (PHYSFS_uint32 i = 0; i < c; ++i) {
|
for (PHYSFS_uint32 i = 0; i < c; ++i) {
|
||||||
Sector *sec = new Sector(fd);
|
Sector *sec = new Sector(fd);
|
||||||
if (sec->getSize() == 0) { // workaround for 'NYC.CMP' (empty sectors)
|
if (sec->getSize() == 0) { // workaround for 'NYC.CMP' (empty sectors)
|
||||||
@ -133,16 +140,25 @@ namespace OpenGTA {
|
|||||||
WARN << "skipping zero size sector" << std::endl;
|
WARN << "skipping zero size sector" << std::endl;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
else
|
else {
|
||||||
|
std::ostringstream os;
|
||||||
|
os << std::setfill('0') << std::setw(3) << level_num << "area" << std::setfill('0') <<
|
||||||
|
std::setw(3) << int(sec->sam);
|
||||||
|
|
||||||
|
//INFO << i << " " << sec->name2 << std::endl << os.str() << " : " << msg.getText(os.str()) << std::endl;
|
||||||
|
sec->name = msg.getText(os.str());
|
||||||
|
|
||||||
areas.insert(std::pair<PHYSFS_uint16, Sector*>(sec->getSize(), sec));
|
areas.insert(std::pair<PHYSFS_uint16, Sector*>(sec->getSize(), sec));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// dummy catch-all sector for gta london maps
|
// dummy catch-all sector for gta london maps
|
||||||
areas.insert(std::pair<PHYSFS_uint16, Sector*>(255*255, new Sector()));
|
areas.insert(std::pair<PHYSFS_uint16, Sector*>(255*255, new Sector()));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
std::cout << "map areas (by size)" << std::endl;
|
std::cout << "map areas (by size)" << std::endl;
|
||||||
SectorMapType::iterator i = areas.begin();
|
SectorMapType::iterator i = areas.begin();
|
||||||
while (i != areas.end()) {
|
while (i != areas.end()) {
|
||||||
std::cout << " " << i->first << " : " << i->second->name << " @ " <<
|
std::cout << " " << i->first << " : " << i->second->name2 << " @ " <<
|
||||||
int(i->second->x) << "," << int(i->second->y) << " " << int(i->second->w) << "x" <<
|
int(i->second->x) << "," << int(i->second->y) << " " << int(i->second->w) << "x" <<
|
||||||
int(i->second->h) << " sample " << int(i->second->sam) << std::endl;
|
int(i->second->h) << " sample " << int(i->second->sam) << std::endl;
|
||||||
++i;
|
++i;
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -11,6 +11,7 @@
|
|||||||
#ifndef NAVDATA_H
|
#ifndef NAVDATA_H
|
||||||
#define NAVDATA_H
|
#define NAVDATA_H
|
||||||
#include <map>
|
#include <map>
|
||||||
|
#include <string>
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
@ -77,14 +78,15 @@ namespace OpenGTA {
|
|||||||
* 2) probably sound?
|
* 2) probably sound?
|
||||||
*/
|
*/
|
||||||
PHYSFS_uint8 sam; // sample number
|
PHYSFS_uint8 sam; // sample number
|
||||||
char name[30]; // FIXME: should not be used
|
//char name2[30]; // FIXME: should not be used
|
||||||
|
std::string name;
|
||||||
/** Returns the name prefixed with sub-area location.
|
/** Returns the name prefixed with sub-area location.
|
||||||
*/
|
*/
|
||||||
const char* getFullName();
|
const char* getFullName();
|
||||||
private:
|
private:
|
||||||
bool isADummy;
|
bool isADummy;
|
||||||
};
|
};
|
||||||
NavData(PHYSFS_uint32 size, PHYSFS_file *fd);
|
NavData(PHYSFS_uint32 size, PHYSFS_file *fd, const size_t level_num);
|
||||||
~NavData();
|
~NavData();
|
||||||
Sector* getSectorAt(PHYSFS_uint8, PHYSFS_uint8);
|
Sector* getSectorAt(PHYSFS_uint8, PHYSFS_uint8);
|
||||||
private:
|
private:
|
||||||
|
1
ogta_version
Normal file
1
ogta_version
Normal file
@ -0,0 +1 @@
|
|||||||
|
2007-04-16
|
10
opengta.h
10
opengta.h
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -179,10 +179,13 @@ namespace OpenGTA {
|
|||||||
void prepareSideTexture(unsigned int idx, unsigned char* dst);
|
void prepareSideTexture(unsigned int idx, unsigned char* dst);
|
||||||
void prepareLidTexture(unsigned int idx, unsigned char* dst);
|
void prepareLidTexture(unsigned int idx, unsigned char* dst);
|
||||||
void prepareAuxTexture(unsigned int idx, unsigned char* dst);
|
void prepareAuxTexture(unsigned int idx, unsigned char* dst);
|
||||||
|
unsigned int getRandomPedRemapNumber();
|
||||||
|
unsigned int getPedRemapNumberType(unsigned int _type);
|
||||||
|
|
||||||
SpriteNumbers spriteNumbers;
|
SpriteNumbers spriteNumbers;
|
||||||
|
|
||||||
CarInfo* findCarByModel(PHYSFS_uint8);
|
CarInfo* findCarByModel(PHYSFS_uint8);
|
||||||
|
size_t getNumCarModels() { return carInfos.size(); }
|
||||||
unsigned char* getTmpBuffer(bool rgba);
|
unsigned char* getTmpBuffer(bool rgba);
|
||||||
SpriteInfo* getSprite(size_t id) { return spriteInfos[id]; }
|
SpriteInfo* getSprite(size_t id) { return spriteInfos[id]; }
|
||||||
|
|
||||||
@ -253,6 +256,9 @@ namespace OpenGTA {
|
|||||||
bool delta_is_a_set;
|
bool delta_is_a_set;
|
||||||
|
|
||||||
Util::Set sideTexBlockMove;
|
Util::Set sideTexBlockMove;
|
||||||
|
|
||||||
|
unsigned int firstValidPedRemap;
|
||||||
|
unsigned int lastValidPedRemap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// just a forward declaration
|
// just a forward declaration
|
||||||
@ -468,7 +474,7 @@ namespace OpenGTA {
|
|||||||
void loadObjects();
|
void loadObjects();
|
||||||
void loadRoutes();
|
void loadRoutes();
|
||||||
void loadLocations();
|
void loadLocations();
|
||||||
void loadNavData();
|
void loadNavData(const size_t level_num);
|
||||||
static const PHYSFS_uint8 _topHeaderSize = 28;
|
static const PHYSFS_uint8 _topHeaderSize = 28;
|
||||||
static const PHYSFS_uint64 _baseSize = 262144;
|
static const PHYSFS_uint64 _baseSize = 262144;
|
||||||
};
|
};
|
||||||
|
30
opensteer/COPYING.OPENSTEER
Normal file
30
opensteer/COPYING.OPENSTEER
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
|
||||||
|
|
||||||
|
Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer is open source software distributed in accordance with the MIT
|
||||||
|
License (http://www.opensource.org/licenses/mit-license.php) which says:
|
||||||
|
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
copy of this software and associated documentation files (the "Software"),
|
||||||
|
to deal in the Software without restriction, including without limitation
|
||||||
|
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in
|
||||||
|
all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
|
205
opensteer/include/OpenSteer/Clock.h
Normal file
205
opensteer/include/OpenSteer/Clock.h
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// discrete time simulation clock for OpenSteerDemo
|
||||||
|
//
|
||||||
|
// Keeps track of real clock time and simulation time. Encapsulates the time
|
||||||
|
// API of the underlying operating system. Can be put in either "as fast as
|
||||||
|
// possible" variable time step mode (where simulation time steps are based on
|
||||||
|
// real time elapsed between updates), or in fixed "target FPS" mode where the
|
||||||
|
// simulation steps are constrained to start on 1/FPS boundaries (e.g. on a 60
|
||||||
|
// hertz video game console). Also handles the notion of "pausing" simulation
|
||||||
|
// time.
|
||||||
|
//
|
||||||
|
// Usage: allocate a clock, set its "paused" or "targetFPS" parameters, then
|
||||||
|
// call updateGlobalSimulationClock before each simulation step.
|
||||||
|
//
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 11-11-03 cwr: another overhaul: support aniamtion mode, switch to
|
||||||
|
// functional API, move smoothed stats inside this class
|
||||||
|
// 09-24-02 cwr: major overhaul
|
||||||
|
// 06-26-02 cwr: created
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_CLOCK_H
|
||||||
|
#define OPENSTEER_CLOCK_H
|
||||||
|
|
||||||
|
#include "OpenSteer/Utilities.h"
|
||||||
|
|
||||||
|
#if defined (_XBOX)
|
||||||
|
#include <xtl.h>
|
||||||
|
#elif defined (_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSteer {
|
||||||
|
|
||||||
|
class Clock
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
Clock ();
|
||||||
|
|
||||||
|
// update this clock, called exactly once per simulation step ("frame")
|
||||||
|
void update (void);
|
||||||
|
|
||||||
|
// returns the number of seconds of real time (represented as a float)
|
||||||
|
// since the clock was first updated.
|
||||||
|
float realTimeSinceFirstClockUpdate (void);
|
||||||
|
|
||||||
|
// force simulation time ahead, ignoring passage of real time.
|
||||||
|
// Used for OpenSteerDemo's "single step forward" and animation mode
|
||||||
|
float advanceSimulationTimeOneFrame (void);
|
||||||
|
void advanceSimulationTime (const float seconds);
|
||||||
|
|
||||||
|
// "wait" until next frame time
|
||||||
|
void frameRateSync (void);
|
||||||
|
|
||||||
|
|
||||||
|
// main clock modes: variable or fixed frame rate, real-time or animation
|
||||||
|
// mode, running or paused.
|
||||||
|
private:
|
||||||
|
// run as fast as possible, simulation time is based on real time
|
||||||
|
bool variableFrameRateMode;
|
||||||
|
|
||||||
|
// fixed frame rate (ignored when in variable frame rate mode) in
|
||||||
|
// real-time mode this is a "target", in animation mode it is absolute
|
||||||
|
int fixedFrameRate;
|
||||||
|
|
||||||
|
// used for offline, non-real-time applications
|
||||||
|
bool animationMode;
|
||||||
|
|
||||||
|
// is simulation running or paused?
|
||||||
|
bool paused;
|
||||||
|
public:
|
||||||
|
int getFixedFrameRate (void) {return fixedFrameRate;}
|
||||||
|
int setFixedFrameRate (int ffr) {return fixedFrameRate = ffr;}
|
||||||
|
|
||||||
|
bool getAnimationMode (void) {return animationMode;}
|
||||||
|
bool setAnimationMode (bool am) {return animationMode = am;}
|
||||||
|
|
||||||
|
bool getVariableFrameRateMode (void) {return variableFrameRateMode;}
|
||||||
|
bool setVariableFrameRateMode (bool vfrm)
|
||||||
|
{return variableFrameRateMode = vfrm;}
|
||||||
|
|
||||||
|
bool togglePausedState (void) {return (paused = !paused);};
|
||||||
|
bool getPausedState (void) {return paused;};
|
||||||
|
bool setPausedState (bool newPS) {return paused = newPS;};
|
||||||
|
|
||||||
|
|
||||||
|
// clock keeps track of "smoothed" running average of recent frame rates.
|
||||||
|
// When a fixed frame rate is used, a running average of "CPU load" is
|
||||||
|
// kept (aka "non-wait time", the percentage of each frame time (time
|
||||||
|
// step) that the CPU is busy).
|
||||||
|
private:
|
||||||
|
float smoothedFPS;
|
||||||
|
float smoothedUsage;
|
||||||
|
void updateSmoothedRegisters (void)
|
||||||
|
{
|
||||||
|
const float rate = getSmoothingRate ();
|
||||||
|
if (elapsedRealTime > 0)
|
||||||
|
blendIntoAccumulator (rate, 1 / elapsedRealTime, smoothedFPS);
|
||||||
|
if (! getVariableFrameRateMode ())
|
||||||
|
blendIntoAccumulator (rate, getUsage (), smoothedUsage);
|
||||||
|
}
|
||||||
|
public:
|
||||||
|
float getSmoothedFPS (void) const {return smoothedFPS;}
|
||||||
|
float getSmoothedUsage (void) const {return smoothedUsage;}
|
||||||
|
float getSmoothingRate (void) const
|
||||||
|
{
|
||||||
|
if (smoothedFPS == 0) return 1; else return elapsedRealTime * 1.5f;
|
||||||
|
}
|
||||||
|
float getUsage (void)
|
||||||
|
{
|
||||||
|
// run time per frame over target frame time (as a percentage)
|
||||||
|
return ((100 * elapsedNonWaitRealTime) / (1.0f / fixedFrameRate));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// clock state member variables and public accessors for them
|
||||||
|
private:
|
||||||
|
// real "wall clock" time since launch
|
||||||
|
float totalRealTime;
|
||||||
|
|
||||||
|
// total time simulation has run
|
||||||
|
float totalSimulationTime;
|
||||||
|
|
||||||
|
// total time spent paused
|
||||||
|
float totalPausedTime;
|
||||||
|
|
||||||
|
// sum of (non-realtime driven) advances to simulation time
|
||||||
|
float totalAdvanceTime;
|
||||||
|
|
||||||
|
// interval since last simulation time
|
||||||
|
// (xxx does this need to be stored in the instance? xxx)
|
||||||
|
float elapsedSimulationTime;
|
||||||
|
|
||||||
|
// interval since last clock update time
|
||||||
|
// (xxx does this need to be stored in the instance? xxx)
|
||||||
|
float elapsedRealTime;
|
||||||
|
|
||||||
|
// interval since last clock update,
|
||||||
|
// exclusive of time spent waiting for frame boundary when targetFPS>0
|
||||||
|
float elapsedNonWaitRealTime;
|
||||||
|
public:
|
||||||
|
float getTotalRealTime (void) {return totalRealTime;}
|
||||||
|
float getTotalSimulationTime (void) {return totalSimulationTime;}
|
||||||
|
float getTotalPausedTime (void) {return totalPausedTime;}
|
||||||
|
float getTotalAdvanceTime (void) {return totalAdvanceTime;}
|
||||||
|
float getElapsedSimulationTime (void) {return elapsedSimulationTime;}
|
||||||
|
float getElapsedRealTime (void) {return elapsedRealTime;}
|
||||||
|
float getElapsedNonWaitRealTime (void) {return elapsedNonWaitRealTime;}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
// "manually" advance clock by this amount on next update
|
||||||
|
float newAdvanceTime;
|
||||||
|
|
||||||
|
// "Calendar time" when this clock was first updated
|
||||||
|
#ifdef _WIN32
|
||||||
|
// from QueryPerformanceCounter on Windows
|
||||||
|
LONGLONG basePerformanceCounter;
|
||||||
|
#else
|
||||||
|
// from gettimeofday on Linux and Mac OS X
|
||||||
|
int baseRealTimeSec;
|
||||||
|
int baseRealTimeUsec;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OpenSteer
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
#endif // OPENSTEER_CLOCK_H
|
337
opensteer/include/OpenSteer/Proximity.h
Normal file
337
opensteer/include/OpenSteer/Proximity.h
Normal file
@ -0,0 +1,337 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Proximity
|
||||||
|
//
|
||||||
|
// Data structures for accelerating proximity/locality/neighborhood queries
|
||||||
|
//
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 06-20-01 cwr: created
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_PROXIMITY_H
|
||||||
|
#define OPENSTEER_PROXIMITY_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include "OpenSteer/Vec3.h"
|
||||||
|
#include "OpenSteer/lq.h" // XXX temp?
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSteer {
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// "tokens" are the objects manipulated by the spatial database
|
||||||
|
|
||||||
|
|
||||||
|
template <class ContentType>
|
||||||
|
class AbstractTokenForProximityDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
virtual ~AbstractTokenForProximityDatabase () {}
|
||||||
|
|
||||||
|
// the client object calls this each time its position changes
|
||||||
|
virtual void updateForNewPosition (const Vec3& position) = 0;
|
||||||
|
|
||||||
|
// find all neighbors within the given sphere (as center and radius)
|
||||||
|
virtual void findNeighbors (const Vec3& center,
|
||||||
|
const float radius,
|
||||||
|
std::vector<ContentType>& results) = 0;
|
||||||
|
|
||||||
|
#ifndef NO_LQ_BIN_STATS
|
||||||
|
// only meaningful for LQProximityDatabase, provide dummy default
|
||||||
|
virtual void getBinPopulationStats (int& min, int& max, float& average)
|
||||||
|
{min=max=0; average=0.0;}
|
||||||
|
#endif // NO_LQ_BIN_STATS
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// abstract type for all kinds of proximity databases
|
||||||
|
|
||||||
|
|
||||||
|
template <class ContentType>
|
||||||
|
class AbstractProximityDatabase
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// type for the "tokens" manipulated by this spatial database
|
||||||
|
typedef AbstractTokenForProximityDatabase<ContentType> tokenType;
|
||||||
|
|
||||||
|
|
||||||
|
virtual ~AbstractProximityDatabase() { /* Nothing to do? */ }
|
||||||
|
|
||||||
|
// allocate a token to represent a given client object in this database
|
||||||
|
virtual tokenType* allocateToken (ContentType parentObject) = 0;
|
||||||
|
|
||||||
|
// insert
|
||||||
|
// XXX maybe this should return an iterator?
|
||||||
|
// XXX see http://www.sgi.com/tech/stl/set.html
|
||||||
|
// virtual void insert (const ContentType& x) = 0;
|
||||||
|
|
||||||
|
// XXX name?
|
||||||
|
// returns the number of tokens in the proximity database
|
||||||
|
virtual int getPopulation (void) = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// This is the "brute force" O(n^2) approach implemented in terms of the
|
||||||
|
// AbstractProximityDatabase protocol so it can be compared directly to other
|
||||||
|
// approaches. (e.g. the Boids plugin allows switching at runtime.)
|
||||||
|
|
||||||
|
|
||||||
|
template <class ContentType>
|
||||||
|
class BruteForceProximityDatabase
|
||||||
|
: public AbstractProximityDatabase<ContentType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
BruteForceProximityDatabase (void)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
virtual ~BruteForceProximityDatabase ()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
// "token" to represent objects stored in the database
|
||||||
|
class tokenType : public AbstractTokenForProximityDatabase<ContentType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
tokenType (ContentType parentObject, BruteForceProximityDatabase& pd)
|
||||||
|
{
|
||||||
|
// store pointer to our associated database and the object this
|
||||||
|
// token represents, and store this token on the database's vector
|
||||||
|
bfpd = &pd;
|
||||||
|
object = parentObject;
|
||||||
|
bfpd->group.push_back (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
virtual ~tokenType ()
|
||||||
|
{
|
||||||
|
// remove this token from the database's vector
|
||||||
|
bfpd->group.erase (std::find (bfpd->group.begin(),
|
||||||
|
bfpd->group.end(),
|
||||||
|
this));
|
||||||
|
}
|
||||||
|
|
||||||
|
// the client object calls this each time its position changes
|
||||||
|
void updateForNewPosition (const Vec3& newPosition)
|
||||||
|
{
|
||||||
|
position = newPosition;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all neighbors within the given sphere (as center and radius)
|
||||||
|
void findNeighbors (const Vec3& center,
|
||||||
|
const float radius,
|
||||||
|
std::vector<ContentType>& results)
|
||||||
|
{
|
||||||
|
// loop over all tokens
|
||||||
|
const float r2 = radius * radius;
|
||||||
|
for (tokenIterator i = bfpd->group.begin();
|
||||||
|
i != bfpd->group.end();
|
||||||
|
i++)
|
||||||
|
{
|
||||||
|
const Vec3 offset = center - (**i).position;
|
||||||
|
const float d2 = offset.lengthSquared();
|
||||||
|
|
||||||
|
// push onto result vector when within given radius
|
||||||
|
if (d2 < r2) results.push_back ((**i).object);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
BruteForceProximityDatabase* bfpd;
|
||||||
|
ContentType object;
|
||||||
|
Vec3 position;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::vector<tokenType*> tokenVector;
|
||||||
|
typedef typename tokenVector::const_iterator tokenIterator;
|
||||||
|
|
||||||
|
// allocate a token to represent a given client object in this database
|
||||||
|
tokenType* allocateToken (ContentType parentObject)
|
||||||
|
{
|
||||||
|
return new tokenType (parentObject, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the number of tokens currently in the database
|
||||||
|
int getPopulation (void)
|
||||||
|
{
|
||||||
|
return (int) group.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
// STL vector containing all tokens in database
|
||||||
|
tokenVector group;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// A AbstractProximityDatabase-style wrapper for the LQ bin lattice system
|
||||||
|
|
||||||
|
|
||||||
|
template <class ContentType>
|
||||||
|
class LQProximityDatabase : public AbstractProximityDatabase<ContentType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
LQProximityDatabase (const Vec3& center,
|
||||||
|
const Vec3& dimensions,
|
||||||
|
const Vec3& divisions)
|
||||||
|
{
|
||||||
|
const Vec3 halfsize (dimensions * 0.5f);
|
||||||
|
const Vec3 origin (center - halfsize);
|
||||||
|
|
||||||
|
lq = lqCreateDatabase (origin.x, origin.y, origin.z,
|
||||||
|
dimensions.x, dimensions.y, dimensions.z,
|
||||||
|
(int) round (divisions.x),
|
||||||
|
(int) round (divisions.y),
|
||||||
|
(int) round (divisions.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
virtual ~LQProximityDatabase ()
|
||||||
|
{
|
||||||
|
lqDeleteDatabase (lq);
|
||||||
|
lq = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "token" to represent objects stored in the database
|
||||||
|
class tokenType : public AbstractTokenForProximityDatabase<ContentType>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// constructor
|
||||||
|
tokenType (ContentType parentObject, LQProximityDatabase& lqsd)
|
||||||
|
{
|
||||||
|
lqInitClientProxy (&proxy, parentObject);
|
||||||
|
lq = lqsd.lq;
|
||||||
|
}
|
||||||
|
|
||||||
|
// destructor
|
||||||
|
virtual ~tokenType (void)
|
||||||
|
{
|
||||||
|
lqRemoveFromBin (&proxy);
|
||||||
|
}
|
||||||
|
|
||||||
|
// the client object calls this each time its position changes
|
||||||
|
void updateForNewPosition (const Vec3& p)
|
||||||
|
{
|
||||||
|
lqUpdateForNewLocation (lq, &proxy, p.x, p.y, p.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
// find all neighbors within the given sphere (as center and radius)
|
||||||
|
void findNeighbors (const Vec3& center,
|
||||||
|
const float radius,
|
||||||
|
std::vector<ContentType>& results)
|
||||||
|
{
|
||||||
|
lqMapOverAllObjectsInLocality (lq,
|
||||||
|
center.x, center.y, center.z,
|
||||||
|
radius,
|
||||||
|
perNeighborCallBackFunction,
|
||||||
|
(void*)&results);
|
||||||
|
}
|
||||||
|
|
||||||
|
// called by LQ for each clientObject in the specified neighborhood:
|
||||||
|
// push that clientObject onto the ContentType vector in void*
|
||||||
|
// clientQueryState
|
||||||
|
// (parameter names commented out to prevent compiler warning from "-W")
|
||||||
|
static void perNeighborCallBackFunction (void* clientObject,
|
||||||
|
float /*distanceSquared*/,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
typedef std::vector<ContentType> ctv;
|
||||||
|
ctv& results = *((ctv*) clientQueryState);
|
||||||
|
results.push_back ((ContentType) clientObject);
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifndef NO_LQ_BIN_STATS
|
||||||
|
// Get statistics about bin populations: min, max and
|
||||||
|
// average of non-empty bins.
|
||||||
|
void getBinPopulationStats (int& min, int& max, float& average)
|
||||||
|
{
|
||||||
|
lqGetBinPopulationStats (lq, &min, &max, &average);
|
||||||
|
}
|
||||||
|
#endif // NO_LQ_BIN_STATS
|
||||||
|
|
||||||
|
private:
|
||||||
|
lqClientProxy proxy;
|
||||||
|
lqDB* lq;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// allocate a token to represent a given client object in this database
|
||||||
|
tokenType* allocateToken (ContentType parentObject)
|
||||||
|
{
|
||||||
|
return new tokenType (parentObject, *this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// count the number of tokens currently in the database
|
||||||
|
int getPopulation (void)
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
lqMapOverAllObjects (lq, counterCallBackFunction, &count);
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
// (parameter names commented out to prevent compiler warning from "-W")
|
||||||
|
static void counterCallBackFunction (void* /*clientObject*/,
|
||||||
|
float /*distanceSquared*/,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
int& counter = *(int*)clientQueryState;
|
||||||
|
counter++;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
lqDB* lq;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace OpenSteer
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
#endif // OPENSTEER_PROXIMITY_H
|
514
opensteer/include/OpenSteer/Utilities.h
Normal file
514
opensteer/include/OpenSteer/Utilities.h
Normal file
@ -0,0 +1,514 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Utilities for OpenSteering
|
||||||
|
//
|
||||||
|
// 08-06-05 bk: added functions to clamp values to a certain value range, to
|
||||||
|
// compare values using a tolerance, and so on.
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 07-09-02 cwr: created
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_UTILITIES_H
|
||||||
|
#define OPENSTEER_UTILITIES_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <iostream> // for ostream, <<, etc.
|
||||||
|
#include <cstdlib> // for rand, etc.
|
||||||
|
#include <cfloat> // for FLT_MAX, etc.
|
||||||
|
#include <cmath> // for sqrt, etc.
|
||||||
|
#include <vector> // for std::vector
|
||||||
|
#include <cassert> // for assert
|
||||||
|
#include <limits> // for numeric_limits
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// For the sake of Windows, apparently this is a "Linux/Unix thing"
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_M_PI
|
||||||
|
#define OPENSTEER_M_PI 3.14159265358979323846f
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#undef min
|
||||||
|
#undef max
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSteer {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Generic interpolation
|
||||||
|
|
||||||
|
|
||||||
|
template<class T> inline T interpolate (float alpha, const T& x0, const T& x1)
|
||||||
|
{
|
||||||
|
return x0 + ((x1 - x0) * alpha);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Random number utilities
|
||||||
|
|
||||||
|
|
||||||
|
// Returns a float randomly distributed between 0 and 1
|
||||||
|
|
||||||
|
inline float frandom01 (void)
|
||||||
|
{
|
||||||
|
return (((float) rand ()) / ((float) RAND_MAX));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns a float randomly distributed between lowerBound and upperBound
|
||||||
|
|
||||||
|
inline float frandom2 (float lowerBound, float upperBound)
|
||||||
|
{
|
||||||
|
return lowerBound + (frandom01 () * (upperBound - lowerBound));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Constrain a given value (x) to be between two (ordered) bounds: min
|
||||||
|
// and max. Returns x if it is between the bounds, otherwise returns
|
||||||
|
// the nearer bound.
|
||||||
|
|
||||||
|
|
||||||
|
inline float clip (const float x, const float min, const float max)
|
||||||
|
{
|
||||||
|
if (x < min) return min;
|
||||||
|
if (x > max) return max;
|
||||||
|
return x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// remap a value specified relative to a pair of bounding values
|
||||||
|
// to the corresponding value relative to another pair of bounds.
|
||||||
|
// Inspired by (dyna:remap-interval y y0 y1 z0 z1)
|
||||||
|
|
||||||
|
|
||||||
|
inline float remapInterval (float x,
|
||||||
|
float in0, float in1,
|
||||||
|
float out0, float out1)
|
||||||
|
{
|
||||||
|
// uninterpolate: what is x relative to the interval in0:in1?
|
||||||
|
float relative = (x - in0) / (in1 - in0);
|
||||||
|
|
||||||
|
// now interpolate between output interval based on relative x
|
||||||
|
return interpolate (relative, out0, out1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Like remapInterval but the result is clipped to remain between
|
||||||
|
// out0 and out1
|
||||||
|
|
||||||
|
|
||||||
|
inline float remapIntervalClip (float x,
|
||||||
|
float in0, float in1,
|
||||||
|
float out0, float out1)
|
||||||
|
{
|
||||||
|
// uninterpolate: what is x relative to the interval in0:in1?
|
||||||
|
float relative = (x - in0) / (in1 - in0);
|
||||||
|
|
||||||
|
// now interpolate between output interval based on relative x
|
||||||
|
return interpolate (clip (relative, 0, 1), out0, out1);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// classify a value relative to the interval between two bounds:
|
||||||
|
// returns -1 when below the lower bound
|
||||||
|
// returns 0 when between the bounds (inside the interval)
|
||||||
|
// returns +1 when above the upper bound
|
||||||
|
|
||||||
|
|
||||||
|
inline int intervalComparison (float x, float lowerBound, float upperBound)
|
||||||
|
{
|
||||||
|
if (x < lowerBound) return -1;
|
||||||
|
if (x > upperBound) return +1;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
inline float scalarRandomWalk (const float initial,
|
||||||
|
const float walkspeed,
|
||||||
|
const float min,
|
||||||
|
const float max)
|
||||||
|
{
|
||||||
|
const float next = initial + (((frandom01() * 2) - 1) * walkspeed);
|
||||||
|
if (next < min) return min;
|
||||||
|
if (next > max) return max;
|
||||||
|
return next;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
inline float square (float x)
|
||||||
|
{
|
||||||
|
return x * x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// for debugging: prints one line with a given C expression, an equals sign,
|
||||||
|
// and the value of the expression. For example "angle = 35.6"
|
||||||
|
|
||||||
|
|
||||||
|
#define debugPrint(e) (std::cout << #e" = " << (e) << std::endl << std::flush)
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// blends new values into an accumulator to produce a smoothed time series
|
||||||
|
//
|
||||||
|
// Modifies its third argument, a reference to the float accumulator holding
|
||||||
|
// the "smoothed time series."
|
||||||
|
//
|
||||||
|
// The first argument (smoothRate) is typically made proportional to "dt" the
|
||||||
|
// simulation time step. If smoothRate is 0 the accumulator will not change,
|
||||||
|
// if smoothRate is 1 the accumulator will be set to the new value with no
|
||||||
|
// smoothing. Useful values are "near zero".
|
||||||
|
//
|
||||||
|
// Usage:
|
||||||
|
// blendIntoAccumulator (dt * 0.4f, currentFPS, smoothedFPS);
|
||||||
|
|
||||||
|
|
||||||
|
template<class T>
|
||||||
|
inline void blendIntoAccumulator (const float smoothRate,
|
||||||
|
const T& newValue,
|
||||||
|
T& smoothedAccumulator)
|
||||||
|
{
|
||||||
|
smoothedAccumulator = interpolate (clip (smoothRate, 0, 1),
|
||||||
|
smoothedAccumulator,
|
||||||
|
newValue);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// given a new Angle and an old angle, adjust the new for angle wraparound (the
|
||||||
|
// 0->360 flip), returning a value equivalent to newAngle, but closest in
|
||||||
|
// absolute value to oldAngle. For radians fullCircle = OPENSTEER_M_PI*2, for degrees
|
||||||
|
// fullCircle = 360. Based on code in stuart/bird/fish demo's camera.cc
|
||||||
|
//
|
||||||
|
// (not currently used)
|
||||||
|
|
||||||
|
/*
|
||||||
|
inline float distance1D (const float a, const float b)
|
||||||
|
{
|
||||||
|
const float d = a - b;
|
||||||
|
return (d > 0) ? d : -d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
float adjustForAngleWraparound (float newAngle,
|
||||||
|
float oldAngle,
|
||||||
|
float fullCircle)
|
||||||
|
{
|
||||||
|
// adjust newAngle for angle wraparound: consider its current value (a)
|
||||||
|
// as well as the angle 2pi larger (b) and 2pi smaller (c). Select the
|
||||||
|
// one closer (magnitude of difference) to the current value of oldAngle.
|
||||||
|
const float a = newAngle;
|
||||||
|
const float b = newAngle + fullCircle;
|
||||||
|
const float c = newAngle - fullCircle;
|
||||||
|
const float ad = distance1D (a, oldAngle);
|
||||||
|
const float bd = distance1D (b, oldAngle);
|
||||||
|
const float cd = distance1D (c, oldAngle);
|
||||||
|
|
||||||
|
if ((bd < ad) && (bd < cd)) return b;
|
||||||
|
if ((cd < ad) && (cd < bd)) return c;
|
||||||
|
return a;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Functions to encapsulate cross-platform differences for several <cmath>
|
||||||
|
// functions. Specifically, the C++ standard says that these functions are
|
||||||
|
// in the std namespace (std::sqrt, etc.) Apparently the MS VC6 compiler (or
|
||||||
|
// its header files) do not implement this correctly and the function names
|
||||||
|
// are in the global namespace. We hope these -XXX versions are a temporary
|
||||||
|
// expedient, to be removed later.
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
inline float floorXXX (float x) {return ::floor (x);}
|
||||||
|
inline float sqrtXXX (float x) {return ::sqrt (x);}
|
||||||
|
inline float sinXXX (float x) {return ::sin (x);}
|
||||||
|
inline float cosXXX (float x) {return ::cos (x);}
|
||||||
|
inline float absXXX (float x) {return ::abs (x);}
|
||||||
|
inline int absXXX (int x) {return ::abs (x);}
|
||||||
|
inline float maxXXX (float x, float y) {if (x > y) return x; else return y;}
|
||||||
|
inline float minXXX (float x, float y) {if (x < y) return x; else return y;}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
inline float floorXXX (float x) {return std::floor (x);}
|
||||||
|
inline float sqrtXXX (float x) {return std::sqrt (x);}
|
||||||
|
inline float sinXXX (float x) {return std::sin (x);}
|
||||||
|
inline float cosXXX (float x) {return std::cos (x);}
|
||||||
|
inline float absXXX (float x) {return std::abs (x);}
|
||||||
|
inline int absXXX (int x) {return std::abs (x);}
|
||||||
|
inline float maxXXX (float x, float y) {return std::max (x, y);}
|
||||||
|
inline float minXXX (float x, float y) {return std::min (x, y);}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// round (x) "round off" x to the nearest integer (as a float value)
|
||||||
|
//
|
||||||
|
// This is a Gnu-sanctioned(?) post-ANSI-Standard(?) extension (as in
|
||||||
|
// http://www.opengroup.org/onlinepubs/007904975/basedefs/math.h.html)
|
||||||
|
// which may not be present in all C++ environments. It is defined in
|
||||||
|
// math.h headers in Linux and Mac OS X, but apparently not in Win32:
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
|
||||||
|
inline float round (float x)
|
||||||
|
{
|
||||||
|
if (x < 0)
|
||||||
|
return -floorXXX (0.5f - x);
|
||||||
|
else
|
||||||
|
return floorXXX (0.5f + x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
inline float round( float x )
|
||||||
|
{
|
||||||
|
return ::round( x );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns @a valueToClamp clamped to the range @a minValue - @a maxValue.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
T
|
||||||
|
clamp( T const& valueToClamp, T const& minValue, T const& maxValue) {
|
||||||
|
assert( minValue <= maxValue && "minValue must be lesser or equal to maxValue." );
|
||||||
|
|
||||||
|
if ( valueToClamp < minValue ) {
|
||||||
|
return minValue;
|
||||||
|
} else if ( valueToClamp > maxValue ) {
|
||||||
|
return maxValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
return valueToClamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline float modulo( float x, float y ) {
|
||||||
|
assert( 0.0f != y && "Division by zero." );
|
||||||
|
return std::fmod( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline double modulo( double x, double y ) {
|
||||||
|
assert( 0.0 != y && "Division by zero." );
|
||||||
|
return std::fmod( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline long double modulo( long double x, long double y ) {
|
||||||
|
assert( 0.0 != y && "Division by zero." );
|
||||||
|
return std::fmod( x, y );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline short modulo( short x, short y ) {
|
||||||
|
assert( 0 != y && "Division by zero." );
|
||||||
|
return x % y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline int modulo( int x, int y ) {
|
||||||
|
assert( 0 != y && "Division by zero." );
|
||||||
|
return x % y;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the floating point remainder of the division of @a x by @a y.
|
||||||
|
* If @a y is @c 0 the behavior is undefined.
|
||||||
|
*/
|
||||||
|
inline long modulo( long x, long y ) {
|
||||||
|
assert( 0 != y && "Division by zero." );
|
||||||
|
return x % y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns <code>value</code> if <code>value >= 0 </code>, otherwise
|
||||||
|
* <code>-value</code>.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
T abs( T const& value ) {
|
||||||
|
return absXXX( value );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the maximum of the three values @a v0, @a v1, and @a v2.
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
T
|
||||||
|
max( T const& v0, T const& v1, T const& v2 ) {
|
||||||
|
return maxXXX( v0, maxXXX( v1, v2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the minimum of the three values @a v0, @a v1, and @a v2.
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
T
|
||||||
|
min( T const& v0, T const& v1, T const& v2 ) {
|
||||||
|
return minXXX( v0, minXXX( v1, v2 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares the absolute value of @a v with @a tolerance.
|
||||||
|
*
|
||||||
|
* See Christer Ericson, Real-Time Collision Detection, Morgan Kaufmann,
|
||||||
|
* 2005, pp. 441--443.
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
bool
|
||||||
|
isZero( T const& v, T const& tolerance = std::numeric_limits< T >::epsilon() ) {
|
||||||
|
return abs( v ) <= tolerance;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares @a lhs with @a rhs given a specific @a tolerance.
|
||||||
|
*
|
||||||
|
* @attention Adapt @a tolerance to the range of values of @a lhs and
|
||||||
|
* @a rhs.
|
||||||
|
* See Christer Ericson, Real-Time Collision Detection, Morgan Kaufmann,
|
||||||
|
* 2005, pp. 441--443.
|
||||||
|
*
|
||||||
|
* @return <code>abs( lhs - rhs ) <= tolerance</code>
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
bool
|
||||||
|
equalsAbsolute( T const& lhs, T const& rhs, T const& tolerance = std::numeric_limits< T >::epsilon() ) {
|
||||||
|
return isZero( lhs - rhs, tolerance );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compares @a lhs with @a rhs given a specific @a tolerance taking the
|
||||||
|
* range of values into account.
|
||||||
|
*
|
||||||
|
* See Christer Ericson, Real-Time Collision Detection, Morgan Kaufmann,
|
||||||
|
* 2005, pp. 441--443.
|
||||||
|
*
|
||||||
|
* @return <code>abs( lhs - rhs ) <= tolerance * max( abs( lhs ), abs( rhs ), 1 )</code>
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
bool
|
||||||
|
equalsRelative( T const& lhs, T const& rhs, T const& tolerance = std::numeric_limits< T >::epsilon() ) {
|
||||||
|
return isZero( lhs - rhs, tolerance * max( abs( lhs ), abs( rhs ), T( 1 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Approximately compares @a lhs with @a rhs given a specific @a tolerance
|
||||||
|
* taking the range of values into account.
|
||||||
|
*
|
||||||
|
* See Christer Ericson, Real-Time Collision Detection, Morgan Kaufmann,
|
||||||
|
* 2005, pp. 441--443.
|
||||||
|
*
|
||||||
|
* @return <code>abs( lhs - rhs ) <= tolerance * ( abs( lhs ) + abs( rhs ) + 1 )</code>
|
||||||
|
*
|
||||||
|
* @todo Write a unit test.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
bool
|
||||||
|
equalsRelativeApproximately( T const& lhs, T const& rhs, T const& tolerance = std::numeric_limits< T >::epsilon() ) {
|
||||||
|
return isZero( lhs - rhs, tolerance * ( abs( lhs ) + abs( rhs ) + T( 1 ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shrinks the capacity of a std::vector to fit its content.
|
||||||
|
*
|
||||||
|
* See Scott Meyer, Effective STL, Addison-Wesley, 2001, pp. 77--79.
|
||||||
|
*/
|
||||||
|
template< typename T >
|
||||||
|
void shrinkToFit( std::vector< T >& v ) {
|
||||||
|
std::vector< T >( v ).swap( v );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace OpenSteer
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
#endif // OPENSTEER_UTILITIES_H
|
382
opensteer/include/OpenSteer/Vec3.h
Normal file
382
opensteer/include/OpenSteer/Vec3.h
Normal file
@ -0,0 +1,382 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Vec3: OpenSteer's generic type for 3d vectors
|
||||||
|
//
|
||||||
|
// This file defines the class Vec3, which is used throughout OpenSteer to
|
||||||
|
// manipulate 3d geometric data. It includes standard vector operations (like
|
||||||
|
// vector addition, subtraction, scale, dot, cross...) and more idiosyncratic
|
||||||
|
// utility functions.
|
||||||
|
//
|
||||||
|
// When integrating OpenSteer into a preexisting 3d application, it may be
|
||||||
|
// important to use the 3d vector type of that application. In that case Vec3
|
||||||
|
// can be changed to inherit from the preexisting application' vector type and
|
||||||
|
// to match the interface used by OpenSteer to the interface provided by the
|
||||||
|
// preexisting 3d vector type.
|
||||||
|
//
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 03-26-03 cwr: created to replace for Hiranabe-san's execellent but larger
|
||||||
|
// vecmath package (http://objectclub.esm.co.jp/vecmath/)
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_VEC3_H
|
||||||
|
#define OPENSTEER_VEC3_H
|
||||||
|
|
||||||
|
|
||||||
|
#include "OpenSteer/Utilities.h" // for interpolate, etc.
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSteer {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
class Vec3
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
|
||||||
|
// ----------------------------------------- generic 3d vector operations
|
||||||
|
|
||||||
|
// three-dimensional Cartesian coordinates
|
||||||
|
float x, y, z;
|
||||||
|
|
||||||
|
// constructors
|
||||||
|
Vec3 (void): x( 0.0f ), y( 0.0f ), z( 0.0f ) {}
|
||||||
|
Vec3 (float X, float Y, float Z) : x( X ), y( Y ), z( Z ) {}
|
||||||
|
|
||||||
|
// vector addition
|
||||||
|
Vec3 operator+ (const Vec3& v) const {return Vec3 (x+v.x, y+v.y, z+v.z);}
|
||||||
|
|
||||||
|
// vector subtraction
|
||||||
|
Vec3 operator- (const Vec3& v) const {return Vec3 (x-v.x, y-v.y, z-v.z);}
|
||||||
|
|
||||||
|
// unary minus
|
||||||
|
Vec3 operator- (void) const {return Vec3 (-x, -y, -z);}
|
||||||
|
|
||||||
|
// vector times scalar product (scale length of vector times argument)
|
||||||
|
Vec3 operator* (const float s) const {return Vec3 (x * s, y * s, z * s);}
|
||||||
|
|
||||||
|
// vector divided by a scalar (divide length of vector by argument)
|
||||||
|
Vec3 operator/ (const float s) const {return Vec3 (x / s, y / s, z / s);}
|
||||||
|
|
||||||
|
// dot product
|
||||||
|
float dot (const Vec3& v) const {return (x * v.x) + (y * v.y) + (z * v.z);}
|
||||||
|
|
||||||
|
// length
|
||||||
|
float length (void) const {return sqrtXXX (lengthSquared ());}
|
||||||
|
|
||||||
|
// length squared
|
||||||
|
float lengthSquared (void) const {return this->dot (*this);}
|
||||||
|
|
||||||
|
// normalize: returns normalized version (parallel to this, length = 1)
|
||||||
|
Vec3 normalize (void) const
|
||||||
|
{
|
||||||
|
// skip divide if length is zero
|
||||||
|
const float len = length ();
|
||||||
|
return (len>0) ? (*this)/len : (*this);
|
||||||
|
}
|
||||||
|
|
||||||
|
// cross product (modify "*this" to be A x B)
|
||||||
|
// [XXX side effecting -- deprecate this function? XXX]
|
||||||
|
void cross(const Vec3& a, const Vec3& b)
|
||||||
|
{
|
||||||
|
*this = Vec3 ((a.y * b.z) - (a.z * b.y),
|
||||||
|
(a.z * b.x) - (a.x * b.z),
|
||||||
|
(a.x * b.y) - (a.y * b.x));
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignment
|
||||||
|
Vec3 operator= (const Vec3& v) {x=v.x; y=v.y; z=v.z; return *this;}
|
||||||
|
|
||||||
|
// set XYZ coordinates to given three floats
|
||||||
|
Vec3 set (const float _x, const float _y, const float _z)
|
||||||
|
{x = _x; y = _y; z = _z; return *this;}
|
||||||
|
|
||||||
|
// +=
|
||||||
|
Vec3 operator+= (const Vec3& v) {return *this = (*this + v);}
|
||||||
|
|
||||||
|
// -=
|
||||||
|
Vec3 operator-= (const Vec3& v) {return *this = (*this - v);}
|
||||||
|
|
||||||
|
// *=
|
||||||
|
Vec3 operator*= (const float& s) {return *this = (*this * s);}
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 operator/=( float d ) { return *this = (*this / d); }
|
||||||
|
|
||||||
|
// equality/inequality
|
||||||
|
bool operator== (const Vec3& v) const {return x==v.x && y==v.y && z==v.z;}
|
||||||
|
bool operator!= (const Vec3& v) const {return !(*this == v);}
|
||||||
|
|
||||||
|
// @todo Remove - use @c distance from the Vec3Utilitites header instead.
|
||||||
|
// XXX experimental (4-1-03 cwr): is this the right approach? defining
|
||||||
|
// XXX "Vec3 distance (vec3, Vec3)" collided with STL's distance template.
|
||||||
|
static float distance (const Vec3& a, const Vec3& b){ return(a-b).length();}
|
||||||
|
|
||||||
|
// --------------------------- utility member functions used in OpenSteer
|
||||||
|
|
||||||
|
// return component of vector parallel to a unit basis vector
|
||||||
|
// (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1))
|
||||||
|
|
||||||
|
inline Vec3 parallelComponent (const Vec3& unitBasis) const
|
||||||
|
{
|
||||||
|
const float projection = this->dot (unitBasis);
|
||||||
|
return unitBasis * projection;
|
||||||
|
}
|
||||||
|
|
||||||
|
// return component of vector perpendicular to a unit basis vector
|
||||||
|
// (IMPORTANT NOTE: assumes "basis" has unit magnitude (length==1))
|
||||||
|
|
||||||
|
inline Vec3 perpendicularComponent (const Vec3& unitBasis) const
|
||||||
|
{
|
||||||
|
return (*this) - parallelComponent (unitBasis);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clamps the length of a given vector to maxLength. If the vector is
|
||||||
|
// shorter its value is returned unaltered, if the vector is longer
|
||||||
|
// the value returned has length of maxLength and is paralle to the
|
||||||
|
// original input.
|
||||||
|
|
||||||
|
Vec3 truncateLength (const float maxLength) const
|
||||||
|
{
|
||||||
|
const float maxLengthSquared = maxLength * maxLength;
|
||||||
|
const float vecLengthSquared = this->lengthSquared ();
|
||||||
|
if (vecLengthSquared <= maxLengthSquared)
|
||||||
|
return *this;
|
||||||
|
else
|
||||||
|
return (*this) * (maxLength / sqrtXXX (vecLengthSquared));
|
||||||
|
}
|
||||||
|
|
||||||
|
// forces a 3d position onto the XZ (aka y=0) plane
|
||||||
|
|
||||||
|
Vec3 setYtoZero (void) const {return Vec3 (this->x, 0, this->z);}
|
||||||
|
|
||||||
|
// rotate this vector about the global Y (up) axis by the given angle
|
||||||
|
|
||||||
|
Vec3 rotateAboutGlobalY (float angle) const
|
||||||
|
{
|
||||||
|
const float s = sinXXX (angle);
|
||||||
|
const float c = cosXXX (angle);
|
||||||
|
return Vec3 ((this->x * c) + (this->z * s),
|
||||||
|
(this->y),
|
||||||
|
(this->z * c) - (this->x * s));
|
||||||
|
}
|
||||||
|
|
||||||
|
// version for caching sin/cos computation
|
||||||
|
Vec3 rotateAboutGlobalY (float angle, float& sin, float& cos) const
|
||||||
|
{
|
||||||
|
// is both are zero, they have not be initialized yet
|
||||||
|
if (sin==0 && cos==0)
|
||||||
|
{
|
||||||
|
sin = sinXXX (angle);
|
||||||
|
cos = cosXXX (angle);
|
||||||
|
}
|
||||||
|
return Vec3 ((this->x * cos) + (this->z * sin),
|
||||||
|
(this->y),
|
||||||
|
(this->z * cos) - (this->x * sin));
|
||||||
|
}
|
||||||
|
|
||||||
|
// if this position is outside sphere, push it back in by one diameter
|
||||||
|
|
||||||
|
Vec3 sphericalWrapAround (const Vec3& center, float radius)
|
||||||
|
{
|
||||||
|
const Vec3 offset = *this - center;
|
||||||
|
const float r = offset.length();
|
||||||
|
if (r > radius)
|
||||||
|
return *this + ((offset/r) * radius * -2);
|
||||||
|
else
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
// names for frequently used vector constants
|
||||||
|
static const Vec3 zero;
|
||||||
|
static const Vec3 side;
|
||||||
|
static const Vec3 up;
|
||||||
|
static const Vec3 forward;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// scalar times vector product ("float * Vec3")
|
||||||
|
|
||||||
|
|
||||||
|
inline Vec3 operator* (float s, const Vec3& v) {return v*s;}
|
||||||
|
|
||||||
|
|
||||||
|
// return cross product a x b
|
||||||
|
inline Vec3 crossProduct(const Vec3& a, const Vec3& b)
|
||||||
|
{
|
||||||
|
Vec3 result((a.y * b.z) - (a.z * b.y),
|
||||||
|
(a.z * b.x) - (a.x * b.z),
|
||||||
|
(a.x * b.y) - (a.y * b.x));
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// default character stream output method
|
||||||
|
|
||||||
|
#ifndef NOT_OPENSTEERDEMO // only when building OpenSteerDemo
|
||||||
|
|
||||||
|
inline std::ostream& operator<< (std::ostream& o, const Vec3& v)
|
||||||
|
{
|
||||||
|
return o << "(" << v.x << "," << v.y << "," << v.z << ")";
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // NOT_OPENSTEERDEMO
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed inside a sphere of unit radius
|
||||||
|
// centered at the origin. Orientation will be random and length will range
|
||||||
|
// between 0 and 1
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 RandomVectorInUnitRadiusSphere (void);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed on a disk of unit radius
|
||||||
|
// on the XZ (Y=0) plane, centered at the origin. Orientation will be
|
||||||
|
// random and length will range between 0 and 1
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 randomVectorOnUnitRadiusXZDisk (void);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed on the surface of a sphere
|
||||||
|
// of unit radius centered at the origin. Orientation will be random
|
||||||
|
// and length will be 1
|
||||||
|
|
||||||
|
|
||||||
|
inline Vec3 RandomUnitVector (void)
|
||||||
|
{
|
||||||
|
return RandomVectorInUnitRadiusSphere().normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed on a circle of unit radius
|
||||||
|
// on the XZ (Y=0) plane, centered at the origin. Orientation will be
|
||||||
|
// random and length will be 1
|
||||||
|
|
||||||
|
|
||||||
|
inline Vec3 RandomUnitVectorOnXZPlane (void)
|
||||||
|
{
|
||||||
|
return RandomVectorInUnitRadiusSphere().setYtoZero().normalize();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// used by limitMaxDeviationAngle / limitMinDeviationAngle below
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 vecLimitDeviationAngleUtility (const bool insideOrOutside,
|
||||||
|
const Vec3& source,
|
||||||
|
const float cosineOfConeAngle,
|
||||||
|
const Vec3& basis);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Enforce an upper bound on the angle by which a given arbitrary vector
|
||||||
|
// diviates from a given reference direction (specified by a unit basis
|
||||||
|
// vector). The effect is to clip the "source" vector to be inside a cone
|
||||||
|
// defined by the basis and an angle.
|
||||||
|
|
||||||
|
|
||||||
|
inline Vec3 limitMaxDeviationAngle (const Vec3& source,
|
||||||
|
const float cosineOfConeAngle,
|
||||||
|
const Vec3& basis)
|
||||||
|
{
|
||||||
|
return vecLimitDeviationAngleUtility (true, // force source INSIDE cone
|
||||||
|
source,
|
||||||
|
cosineOfConeAngle,
|
||||||
|
basis);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Enforce a lower bound on the angle by which a given arbitrary vector
|
||||||
|
// diviates from a given reference direction (specified by a unit basis
|
||||||
|
// vector). The effect is to clip the "source" vector to be outside a cone
|
||||||
|
// defined by the basis and an angle.
|
||||||
|
|
||||||
|
|
||||||
|
inline Vec3 limitMinDeviationAngle (const Vec3& source,
|
||||||
|
const float cosineOfConeAngle,
|
||||||
|
const Vec3& basis)
|
||||||
|
{
|
||||||
|
return vecLimitDeviationAngleUtility (false, // force source OUTSIDE cone
|
||||||
|
source,
|
||||||
|
cosineOfConeAngle,
|
||||||
|
basis);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns the distance between a point and a line. The line is defined in
|
||||||
|
// terms of a point on the line ("lineOrigin") and a UNIT vector parallel to
|
||||||
|
// the line ("lineUnitTangent")
|
||||||
|
|
||||||
|
|
||||||
|
inline float distanceFromLine (const Vec3& point,
|
||||||
|
const Vec3& lineOrigin,
|
||||||
|
const Vec3& lineUnitTangent)
|
||||||
|
{
|
||||||
|
const Vec3 offset = point - lineOrigin;
|
||||||
|
const Vec3 perp = offset.perpendicularComponent (lineUnitTangent);
|
||||||
|
return perp.length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// given a vector, return a vector perpendicular to it (note that this
|
||||||
|
// arbitrarily selects one of the infinitude of perpendicular vectors)
|
||||||
|
|
||||||
|
|
||||||
|
Vec3 findPerpendicularIn3d (const Vec3& direction);
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// candidates for global utility functions
|
||||||
|
//
|
||||||
|
// dot
|
||||||
|
// cross
|
||||||
|
// length
|
||||||
|
// distance
|
||||||
|
// normalized
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace OpenSteer
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
#endif // OPENSTEER_VEC3_H
|
96
opensteer/include/OpenSteer/Vec3Utilities.h
Normal file
96
opensteer/include/OpenSteer/Vec3Utilities.h
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
// Utilities to work with Vec3.
|
||||||
|
//
|
||||||
|
// 05-12-05 bk: Created based on code of PolylinePathway.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef OPENSTEER_VEC3UTILITIES_H
|
||||||
|
#define OPENSTEER_VEC3UTILITIES_H
|
||||||
|
|
||||||
|
|
||||||
|
// Include OpenSteer::Vec3
|
||||||
|
#include "OpenSteer/Vec3.h"
|
||||||
|
|
||||||
|
// Include OpenSteer::size_t
|
||||||
|
#include "OpenSteer/StandardTypes.h"
|
||||||
|
|
||||||
|
// Include OpenSteer::equalsRelative
|
||||||
|
#include "OpenSteer/Utilities.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
namespace OpenSteer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the nearest point on the segment @a segmentPoint0 to
|
||||||
|
* @a segmentPoint1 from @a point.
|
||||||
|
*/
|
||||||
|
OpenSteer::Vec3 nearestPointOnSegment( const Vec3& point,
|
||||||
|
const Vec3& segmentPoint0,
|
||||||
|
const Vec3& segmentPoint1 );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Computes minimum distance from @a point to the line segment defined by
|
||||||
|
* @a segmentPoint0 and @a segmentPoint1.
|
||||||
|
*/
|
||||||
|
float pointToSegmentDistance( const Vec3& point,
|
||||||
|
const Vec3& segmentPoint0,
|
||||||
|
const Vec3& segmentPoint1);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retuns distance between @a a and @a b.
|
||||||
|
*/
|
||||||
|
inline float distance (const Vec3& a, const Vec3& b) {
|
||||||
|
return (a-b).length();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Elementwise relative tolerance comparison of @a lhs and @a rhs taking
|
||||||
|
* the range of the elements into account.
|
||||||
|
*
|
||||||
|
* See Christer Ericson, Real-Time Collision Detection, Morgan Kaufmann,
|
||||||
|
* 2005, pp. 441--443.
|
||||||
|
*
|
||||||
|
* @todo Rewrite using the stl or providing an own range based function.
|
||||||
|
*/
|
||||||
|
inline
|
||||||
|
bool
|
||||||
|
equalsRelative( Vec3 const& lhs,
|
||||||
|
Vec3 const& rhs,
|
||||||
|
float const& tolerance = std::numeric_limits< float >::epsilon() ) {
|
||||||
|
return equalsRelative( lhs.x, rhs.x, tolerance ) && equalsRelative( lhs.y, rhs.y ) && equalsRelative( lhs.z, rhs.z );
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace OpenSteer
|
||||||
|
|
||||||
|
#endif // OPENSTEER_VEC3UTILITIES_H
|
323
opensteer/include/OpenSteer/lq.h
Normal file
323
opensteer/include/OpenSteer/lq.h
Normal file
@ -0,0 +1,323 @@
|
|||||||
|
/*
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
/* Locality Query (LQ) Facility */
|
||||||
|
/* */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/*
|
||||||
|
|
||||||
|
This utility is a spatial database which stores objects each of
|
||||||
|
which is associated with a 3d point (a location in a 3d space).
|
||||||
|
The points serve as the "search key" for the associated object.
|
||||||
|
It is intended to efficiently answer "sphere inclusion" queries,
|
||||||
|
also known as range queries: basically questions like:
|
||||||
|
|
||||||
|
Which objects are within a radius R of the location L?
|
||||||
|
|
||||||
|
In this context, "efficiently" means significantly faster than the
|
||||||
|
naive, brute force O(n) testing of all known points. Additionally
|
||||||
|
it is assumed that the objects move along unpredictable paths, so
|
||||||
|
that extensive preprocessing (for example, constructing a Delaunay
|
||||||
|
triangulation of the point set) may not be practical.
|
||||||
|
|
||||||
|
The implementation is a "bin lattice": a 3d rectangular array of
|
||||||
|
brick-shaped (rectangular parallelepipeds) regions of space. Each
|
||||||
|
region is represented by a pointer to a (possibly empty) doubly-
|
||||||
|
linked list of objects. All of these sub-bricks are the same
|
||||||
|
size. All bricks are aligned with the global coordinate axes.
|
||||||
|
|
||||||
|
Terminology used here: the region of space associated with a bin
|
||||||
|
is called a sub-brick. The collection of all sub-bricks is called
|
||||||
|
the super-brick. The super-brick should be specified to surround
|
||||||
|
the region of space in which (almost) all the key-points will
|
||||||
|
exist. If key-points move outside the super-brick everything will
|
||||||
|
continue to work, but without the speed advantage provided by the
|
||||||
|
spatial subdivision. For more details about how to specify the
|
||||||
|
super-brick's position, size and subdivisions see lqCreateDatabase
|
||||||
|
below.
|
||||||
|
|
||||||
|
Overview of usage: an application using this facility would first
|
||||||
|
create a database with lqCreateDatabase. For each client object
|
||||||
|
the application wants to put in the database it creates a
|
||||||
|
lqClientProxy and initializes it with lqInitClientProxy. When a
|
||||||
|
client object moves, the application calls lqUpdateForNewLocation.
|
||||||
|
To perform a query lqMapOverAllObjectsInLocality is passed an
|
||||||
|
application-supplied call-back function to be applied to all
|
||||||
|
client objects in the locality. See lqCallBackFunction below for
|
||||||
|
more detail. The lqFindNearestNeighborWithinRadius function can
|
||||||
|
be used to find a single nearest neighbor using the database.
|
||||||
|
|
||||||
|
Note that "locality query" is also known as neighborhood query,
|
||||||
|
neighborhood search, near neighbor search, and range query. For
|
||||||
|
additional information on this and related topics see:
|
||||||
|
http://www.red3d.com/cwr/boids/ips.html
|
||||||
|
|
||||||
|
For some description and illustrations of this database in use,
|
||||||
|
see this paper: http://www.red3d.com/cwr/papers/2000/pip.html
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _lq_h
|
||||||
|
#define _lq_h
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C"
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
/* Data types use by LQ */
|
||||||
|
/* */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* This structure represents the spatial database. Typically one of
|
||||||
|
these would be created (by a call to lqCreateDatabase) for a given
|
||||||
|
application. */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct lqInternalDB lqDB;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* This structure is a proxy for (and contains a pointer to) a client
|
||||||
|
(application) object in the spatial database. One of these exists
|
||||||
|
for each client object. This might be included within the
|
||||||
|
structure of a client object, or could be allocated separately. */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct lqClientProxy
|
||||||
|
{
|
||||||
|
/* previous object in this bin, or NULL */
|
||||||
|
struct lqClientProxy* prev;
|
||||||
|
|
||||||
|
/* next object in this bin, or NULL */
|
||||||
|
struct lqClientProxy* next;
|
||||||
|
|
||||||
|
/* bin ID (pointer to pointer to bin contents list) */
|
||||||
|
struct lqClientProxy** bin;
|
||||||
|
|
||||||
|
/* pointer to client object */
|
||||||
|
void* object;
|
||||||
|
|
||||||
|
/* the object's location ("key point") used for spatial sorting */
|
||||||
|
float x;
|
||||||
|
float y;
|
||||||
|
float z;
|
||||||
|
} lqClientProxy;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
/* Basic API */
|
||||||
|
/* */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Allocate and initialize an LQ database, returns a pointer to it.
|
||||||
|
The application needs to call this before using the LQ facility.
|
||||||
|
The nine parameters define the properties of the "super-brick":
|
||||||
|
(1) origin: coordinates of one corner of the super-brick, its
|
||||||
|
minimum x, y and z extent.
|
||||||
|
(2) size: the width, height and depth of the super-brick.
|
||||||
|
(3) the number of subdivisions (sub-bricks) along each axis.
|
||||||
|
This routine also allocates the bin array, and initialize its
|
||||||
|
contents. */
|
||||||
|
|
||||||
|
|
||||||
|
lqDB* lqCreateDatabase (float originx, float originy, float originz,
|
||||||
|
float sizex, float sizey, float sizez,
|
||||||
|
int divx, int divy, int divz);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Deallocates the LQ database */
|
||||||
|
|
||||||
|
|
||||||
|
void lqDeleteDatabase (lqDB*);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* The application needs to call this once on each lqClientProxy at
|
||||||
|
setup time to initialize its list pointers and associate the proxy
|
||||||
|
with its client object. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqInitClientProxy (lqClientProxy* proxy, void* clientObject);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Call for each client object every time its location changes. For
|
||||||
|
example, in an animation application, this would be called each
|
||||||
|
frame for every moving object. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqUpdateForNewLocation (lqDB* lq,
|
||||||
|
lqClientProxy* object,
|
||||||
|
float x, float y, float z);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Apply an application-specific function to all objects in a certain
|
||||||
|
locality. The locality is specified as a sphere with a given
|
||||||
|
center and radius. All objects whose location (key-point) is
|
||||||
|
within this sphere are identified and the function is applied to
|
||||||
|
them. The application-supplied function takes three arguments:
|
||||||
|
|
||||||
|
(1) a void* pointer to an lqClientProxy's "object".
|
||||||
|
(2) the square of the distance from the center of the search
|
||||||
|
locality sphere (x,y,z) to object's key-point.
|
||||||
|
(3) a void* pointer to the caller-supplied "client query state"
|
||||||
|
object -- typically NULL, but can be used to store state
|
||||||
|
between calls to the lqCallBackFunction.
|
||||||
|
|
||||||
|
This routine uses the LQ database to quickly reject any objects in
|
||||||
|
bins which do not overlap with the sphere of interest. Incremental
|
||||||
|
calculation of index values is used to efficiently traverse the
|
||||||
|
bins of interest. */
|
||||||
|
|
||||||
|
|
||||||
|
/* type for a pointer to a function used to map over client objects */
|
||||||
|
typedef void (* lqCallBackFunction) (void* clientObject,
|
||||||
|
float distanceSquared,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInLocality (lqDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
/* Other API */
|
||||||
|
/* */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Search the database to find the object whose key-point is nearest
|
||||||
|
to a given location yet within a given radius. That is, it finds
|
||||||
|
the object (if any) within a given search sphere which is nearest
|
||||||
|
to the sphere's center. The ignoreObject argument can be used to
|
||||||
|
exclude an object from consideration (or it can be NULL). This is
|
||||||
|
useful when looking for the nearest neighbor of an object in the
|
||||||
|
database, since otherwise it would be its own nearest neighbor.
|
||||||
|
The function returns a void* pointer to the nearest object, or
|
||||||
|
NULL if none is found. */
|
||||||
|
|
||||||
|
|
||||||
|
void* lqFindNearestNeighborWithinRadius (lqDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
void* ignoreObject);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Adds a given client object to a given bin, linking it into the bin
|
||||||
|
contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqAddToBin (lqClientProxy* object, lqClientProxy** bin);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Removes a given client object from its current bin, unlinking it
|
||||||
|
from the bin contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqRemoveFromBin (lqClientProxy* object);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Given an LQ database object and the nine basic parameters: fill in
|
||||||
|
the object's slots, allocate the bin array, and initialize its
|
||||||
|
contents. Normally the application does NOT call this directly, it
|
||||||
|
is called by lqCreateDatabase. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqInitDatabase (lqDB* lq,
|
||||||
|
float originx, float originy, float originz,
|
||||||
|
float sizex, float sizey, float sizez,
|
||||||
|
int divx, int divy, int divz);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Find the bin ID for a location in space. The location is given in
|
||||||
|
terms of its XYZ coordinates. The bin ID is a pointer to a pointer
|
||||||
|
to the bin contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
lqClientProxy** lqBinForLocation (lqDB* lq, float x, float y, float z);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Apply a user-supplied function to all objects in the database,
|
||||||
|
regardless of locality (cf lqMapOverAllObjectsInLocality) */
|
||||||
|
|
||||||
|
|
||||||
|
void lqMapOverAllObjects (lqDB* lq,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Removes (all proxies for) all objects from all bins */
|
||||||
|
|
||||||
|
|
||||||
|
void lqRemoveAllObjects (lqDB* lq);
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Get statistics about bin populations: min, max and average of
|
||||||
|
non-empty bins. */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NO_LQ_BIN_STATS
|
||||||
|
void lqGetBinPopulationStats (lqDB* lq,
|
||||||
|
int* min,
|
||||||
|
int* max,
|
||||||
|
float* average);
|
||||||
|
#endif /* NO_LQ_BIN_STATS */
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef NULL
|
||||||
|
#define NULL 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _lq_h */
|
5
opensteer/ogta_opensteer.txt
Normal file
5
opensteer/ogta_opensteer.txt
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
OpenSteer_0_8_2_source.zip
|
||||||
|
|
||||||
|
This is only a subset of OpenSteer; didn't want to add code that I don't use.
|
||||||
|
|
||||||
|
The docs are gone as well.
|
310
opensteer/src/Clock.cpp
Normal file
310
opensteer/src/Clock.cpp
Normal file
@ -0,0 +1,310 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// discrete time simulation clock for OpenSteerDemo
|
||||||
|
//
|
||||||
|
// Keeps track of real clock time and simulation time. Encapsulates OS's
|
||||||
|
// time API. Can be put in either "as fast as possible" variable time step
|
||||||
|
// mode (where simulation time steps are based on real time elapsed between
|
||||||
|
// updates), or in fixed "target FPS" mode where the simulation steps are
|
||||||
|
// constrained to start on 1/FPS boundaries (e.g. on a 60 hertz video game
|
||||||
|
// console). Also handles the notion of "pausing" simulation time.
|
||||||
|
//
|
||||||
|
// Usage: allocate a clock, set its "paused" or "targetFPS" parameters,
|
||||||
|
// then call updateGlobalSimulationClock before each simulation step.
|
||||||
|
//
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 09-24-02 cwr: major overhaul
|
||||||
|
// 06-26-02 cwr: created
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#include "OpenSteer/Clock.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// XXX This is a bit ad hoc. Need to revisit conditionalization on operating
|
||||||
|
// XXX system. As of 5-5-03, this module knows about Win32 (code thanks to
|
||||||
|
// XXX Leaf Garland and Bruce Mitchener) and Linux/Unix (Craig's original
|
||||||
|
// XXX version). It tests for Xbox and Win32 and assumes Linux/Unix
|
||||||
|
// XXX otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (_XBOX)
|
||||||
|
#include <xtl.h>
|
||||||
|
#elif defined (_WIN32)
|
||||||
|
#include <windows.h>
|
||||||
|
#else
|
||||||
|
#include <sys/time.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Constructor
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer::Clock::Clock (void)
|
||||||
|
{
|
||||||
|
// default is "real time, variable frame rate" and not paused
|
||||||
|
setFixedFrameRate (0);
|
||||||
|
setPausedState (false);
|
||||||
|
setAnimationMode (false);
|
||||||
|
setVariableFrameRateMode (true);
|
||||||
|
|
||||||
|
// real "wall clock" time since launch
|
||||||
|
totalRealTime = 0;
|
||||||
|
|
||||||
|
// time simulation has run
|
||||||
|
totalSimulationTime = 0;
|
||||||
|
|
||||||
|
// time spent paused
|
||||||
|
totalPausedTime = 0;
|
||||||
|
|
||||||
|
// sum of (non-realtime driven) advances to simulation time
|
||||||
|
totalAdvanceTime = 0;
|
||||||
|
|
||||||
|
// interval since last simulation time
|
||||||
|
elapsedSimulationTime = 0;
|
||||||
|
|
||||||
|
// interval since last clock update time
|
||||||
|
elapsedRealTime = 0;
|
||||||
|
|
||||||
|
// interval since last clock update,
|
||||||
|
// exclusive of time spent waiting for frame boundary when targetFPS>0
|
||||||
|
elapsedNonWaitRealTime = 0;
|
||||||
|
|
||||||
|
// "manually" advance clock by this amount on next update
|
||||||
|
newAdvanceTime = 0;
|
||||||
|
|
||||||
|
// "Calendar time" when this clock was first updated
|
||||||
|
#ifdef _WIN32
|
||||||
|
basePerformanceCounter = 0; // from QueryPerformanceCounter on Windows
|
||||||
|
#else
|
||||||
|
baseRealTimeSec = 0; // from gettimeofday on Linux and Mac OS X
|
||||||
|
baseRealTimeUsec = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// clock keeps track of "smoothed" running average of recent frame rates.
|
||||||
|
// When a fixed frame rate is used, a running average of "CPU load" is
|
||||||
|
// kept (aka "non-wait time", the percentage of each frame time (time
|
||||||
|
// step) that the CPU is busy).
|
||||||
|
smoothedFPS = 0;
|
||||||
|
smoothedUsage = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// update this clock, called once per simulation step ("frame") to:
|
||||||
|
//
|
||||||
|
// track passage of real time
|
||||||
|
// manage passage of simulation time (modified by Paused state)
|
||||||
|
// measure time elapsed between time updates ("frame rate")
|
||||||
|
// optionally: "wait" for next realtime frame boundary
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenSteer::Clock::update (void)
|
||||||
|
{
|
||||||
|
// keep track of average frame rate and average usage percentage
|
||||||
|
updateSmoothedRegisters ();
|
||||||
|
|
||||||
|
// wait for next frame time (when targetFPS>0)
|
||||||
|
// XXX should this be at the end of the update function?
|
||||||
|
frameRateSync ();
|
||||||
|
|
||||||
|
// save previous real time to measure elapsed time
|
||||||
|
const float previousRealTime = totalRealTime;
|
||||||
|
|
||||||
|
// real "wall clock" time since this application was launched
|
||||||
|
totalRealTime = realTimeSinceFirstClockUpdate ();
|
||||||
|
|
||||||
|
// time since last clock update
|
||||||
|
elapsedRealTime = totalRealTime - previousRealTime;
|
||||||
|
|
||||||
|
// accumulate paused time
|
||||||
|
if (paused) totalPausedTime += elapsedRealTime;
|
||||||
|
|
||||||
|
// save previous simulation time to measure elapsed time
|
||||||
|
const float previousSimulationTime = totalSimulationTime;
|
||||||
|
|
||||||
|
// update total simulation time
|
||||||
|
if (getAnimationMode ())
|
||||||
|
{
|
||||||
|
// for "animation mode" use fixed frame time, ignore real time
|
||||||
|
const float frameDuration = 1.0f / getFixedFrameRate ();
|
||||||
|
totalSimulationTime += paused ? newAdvanceTime : frameDuration;
|
||||||
|
if (!paused) newAdvanceTime += frameDuration - elapsedRealTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// new simulation time is total run time minus time spent paused
|
||||||
|
totalSimulationTime = (totalRealTime
|
||||||
|
+ totalAdvanceTime
|
||||||
|
- totalPausedTime);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// update total "manual advance" time
|
||||||
|
totalAdvanceTime += newAdvanceTime;
|
||||||
|
|
||||||
|
// how much time has elapsed since the last simulation step?
|
||||||
|
elapsedSimulationTime = (paused ?
|
||||||
|
newAdvanceTime :
|
||||||
|
(totalSimulationTime - previousSimulationTime));
|
||||||
|
|
||||||
|
// reset advance amount
|
||||||
|
newAdvanceTime = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// "wait" until next frame time (actually spin around this tight loop)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// (xxx there are probably a smarter ways to do this (using events or
|
||||||
|
// thread waits (eg usleep)) but they are likely to be unportable. xxx)
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenSteer::Clock::frameRateSync (void)
|
||||||
|
{
|
||||||
|
// when in real time fixed frame rate mode
|
||||||
|
// (not animation mode and not variable frame rate mode)
|
||||||
|
if ((! getAnimationMode ()) && (! getVariableFrameRateMode ()))
|
||||||
|
{
|
||||||
|
// find next (real time) frame start time
|
||||||
|
const float targetStepSize = 1.0f / getFixedFrameRate ();
|
||||||
|
const float now = realTimeSinceFirstClockUpdate ();
|
||||||
|
const int lastFrameCount = (int) (now / targetStepSize);
|
||||||
|
const float nextFrameTime = (lastFrameCount + 1) * targetStepSize;
|
||||||
|
|
||||||
|
// record usage ("busy time", "non-wait time") for OpenSteerDemo app
|
||||||
|
elapsedNonWaitRealTime = now - totalRealTime;
|
||||||
|
|
||||||
|
// wait until next frame time
|
||||||
|
do {} while (realTimeSinceFirstClockUpdate () < nextFrameTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// force simulation time ahead, ignoring passage of real time.
|
||||||
|
// Used for OpenSteerDemo's "single step forward" and animation mode
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
OpenSteer::Clock::advanceSimulationTimeOneFrame (void)
|
||||||
|
{
|
||||||
|
// decide on what frame time is (use fixed rate, average for variable rate)
|
||||||
|
const float fps = (getVariableFrameRateMode () ?
|
||||||
|
getSmoothedFPS () :
|
||||||
|
getFixedFrameRate ());
|
||||||
|
const float frameTime = 1 / fps;
|
||||||
|
|
||||||
|
// bump advance time
|
||||||
|
advanceSimulationTime (frameTime);
|
||||||
|
|
||||||
|
// return the time value used (for OpenSteerDemo)
|
||||||
|
return frameTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
OpenSteer::Clock::advanceSimulationTime (const float seconds)
|
||||||
|
{
|
||||||
|
if (seconds < 0) {
|
||||||
|
/// @todo - throw? how to handle error conditions? Not by crashing an app!
|
||||||
|
std::cerr << "negative arg to advanceSimulationTime - results will not be valid";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
newAdvanceTime += seconds;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns the number of seconds of real time (represented as a float) since
|
||||||
|
// the clock was first updated.
|
||||||
|
//
|
||||||
|
// XXX Need to revisit conditionalization on operating system.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
clockErrorExit (void)
|
||||||
|
{
|
||||||
|
/// @todo - throw? how to handle error conditions? Not by crashing an app!
|
||||||
|
std::cerr << "Problem reading system clock - results will not be valid";
|
||||||
|
return 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
|
float
|
||||||
|
OpenSteer::Clock::realTimeSinceFirstClockUpdate (void)
|
||||||
|
#ifdef _WIN32
|
||||||
|
{
|
||||||
|
// get time from Windows
|
||||||
|
LONGLONG counter, frequency;
|
||||||
|
bool clockOK = (QueryPerformanceCounter ((LARGE_INTEGER *)&counter) &&
|
||||||
|
QueryPerformanceFrequency ((LARGE_INTEGER *)&frequency));
|
||||||
|
if (!clockOK) return clockErrorExit ();
|
||||||
|
|
||||||
|
// ensure the base counter is recorded once after launch
|
||||||
|
if (basePerformanceCounter == 0) basePerformanceCounter = counter;
|
||||||
|
|
||||||
|
// real "wall clock" time since launch
|
||||||
|
const LONGLONG counterDifference = counter - basePerformanceCounter;
|
||||||
|
return ((float) counterDifference) / ((float)frequency);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
// get time from Linux (Unix, Mac OS X, ...)
|
||||||
|
timeval t;
|
||||||
|
if (gettimeofday (&t, 0) != 0) return clockErrorExit ();
|
||||||
|
|
||||||
|
// ensure the base time is recorded once after launch
|
||||||
|
if (baseRealTimeSec == 0)
|
||||||
|
{
|
||||||
|
baseRealTimeSec = t.tv_sec;
|
||||||
|
baseRealTimeUsec = t.tv_usec;
|
||||||
|
}
|
||||||
|
|
||||||
|
// real "wall clock" time since launch
|
||||||
|
return (( t.tv_sec - baseRealTimeSec) +
|
||||||
|
((t.tv_usec - baseRealTimeUsec) / 1000000.0f));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
213
opensteer/src/Vec3.cpp
Normal file
213
opensteer/src/Vec3.cpp
Normal file
@ -0,0 +1,213 @@
|
|||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// Vec3: OpenSteer's generic type for 3d vectors
|
||||||
|
//
|
||||||
|
// This file defines the class Vec3, which is used throughout OpenSteer to
|
||||||
|
// manipulate 3d geometric data. It includes standard vector operations (like
|
||||||
|
// vector addition, subtraction, scale, dot, cross...) and more idiosyncratic
|
||||||
|
// utility functions.
|
||||||
|
//
|
||||||
|
// When integrating OpenSteer into a preexisting 3d application, it may be
|
||||||
|
// important to use the 3d vector type of that application. In that case Vec3
|
||||||
|
// can be changed to inherit from the preexisting application' vector type and
|
||||||
|
// to match the interface used by OpenSteer to the interface provided by the
|
||||||
|
// preexisting 3d vector type.
|
||||||
|
//
|
||||||
|
// 10-04-04 bk: put everything into the OpenSteer namespace
|
||||||
|
// 03-26-03 cwr: created to replace for Hiranabe-san's execellent but larger
|
||||||
|
// vecmath package (http://objectclub.esm.co.jp/vecmath/)
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
|
||||||
|
#include "OpenSteer/Vec3.h"
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// names for frequently used vector constants
|
||||||
|
|
||||||
|
|
||||||
|
const OpenSteer::Vec3 OpenSteer::Vec3::zero (0, 0, 0);
|
||||||
|
const OpenSteer::Vec3 OpenSteer::Vec3::up (0, 1, 0);
|
||||||
|
const OpenSteer::Vec3 OpenSteer::Vec3::forward (0, 0, 1);
|
||||||
|
|
||||||
|
// XXX This should be unified with LocalSpace::rightHanded, but I don't want
|
||||||
|
// XXX Vec3 to be based on LocalSpace which is based on Vec3. Perhaps there
|
||||||
|
// XXX should be a tiny chirality.h header to define a const? That could
|
||||||
|
// XXX then be included by both Vec3.h and LocalSpace.h
|
||||||
|
|
||||||
|
const OpenSteer::Vec3 OpenSteer::Vec3::side (-1, 0, 0);
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed inside a sphere of unit radius
|
||||||
|
// centered at the origin. Orientation will be random and length will range
|
||||||
|
// between 0 and 1
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer::Vec3
|
||||||
|
OpenSteer::RandomVectorInUnitRadiusSphere (void)
|
||||||
|
{
|
||||||
|
Vec3 v;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
v.set ((frandom01()*2) - 1,
|
||||||
|
(frandom01()*2) - 1,
|
||||||
|
(frandom01()*2) - 1);
|
||||||
|
}
|
||||||
|
while (v.length() >= 1);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Returns a position randomly distributed on a disk of unit radius
|
||||||
|
// on the XZ (Y=0) plane, centered at the origin. Orientation will be
|
||||||
|
// random and length will range between 0 and 1
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer::Vec3
|
||||||
|
OpenSteer::randomVectorOnUnitRadiusXZDisk (void)
|
||||||
|
{
|
||||||
|
Vec3 v;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
v.set ((frandom01()*2) - 1,
|
||||||
|
0,
|
||||||
|
(frandom01()*2) - 1);
|
||||||
|
}
|
||||||
|
while (v.length() >= 1);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// Does a "ceiling" or "floor" operation on the angle by which a given vector
|
||||||
|
// deviates from a given reference basis vector. Consider a cone with "basis"
|
||||||
|
// as its axis and slope of "cosineOfConeAngle". The first argument controls
|
||||||
|
// whether the "source" vector is forced to remain inside or outside of this
|
||||||
|
// cone. Called by vecLimitMaxDeviationAngle and vecLimitMinDeviationAngle.
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer::Vec3
|
||||||
|
OpenSteer::vecLimitDeviationAngleUtility (const bool insideOrOutside,
|
||||||
|
const Vec3& source,
|
||||||
|
const float cosineOfConeAngle,
|
||||||
|
const Vec3& basis)
|
||||||
|
{
|
||||||
|
// immediately return zero length input vectors
|
||||||
|
float sourceLength = source.length();
|
||||||
|
if (sourceLength == 0) return source;
|
||||||
|
|
||||||
|
// measure the angular diviation of "source" from "basis"
|
||||||
|
const Vec3 direction = source / sourceLength;
|
||||||
|
float cosineOfSourceAngle = direction.dot (basis);
|
||||||
|
|
||||||
|
// Simply return "source" if it already meets the angle criteria.
|
||||||
|
// (note: we hope this top "if" gets compiled out since the flag
|
||||||
|
// is a constant when the function is inlined into its caller)
|
||||||
|
if (insideOrOutside)
|
||||||
|
{
|
||||||
|
// source vector is already inside the cone, just return it
|
||||||
|
if (cosineOfSourceAngle >= cosineOfConeAngle) return source;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// source vector is already outside the cone, just return it
|
||||||
|
if (cosineOfSourceAngle <= cosineOfConeAngle) return source;
|
||||||
|
}
|
||||||
|
|
||||||
|
// find the portion of "source" that is perpendicular to "basis"
|
||||||
|
const Vec3 perp = source.perpendicularComponent (basis);
|
||||||
|
|
||||||
|
// normalize that perpendicular
|
||||||
|
const Vec3 unitPerp = perp.normalize ();
|
||||||
|
|
||||||
|
// construct a new vector whose length equals the source vector,
|
||||||
|
// and lies on the intersection of a plane (formed the source and
|
||||||
|
// basis vectors) and a cone (whose axis is "basis" and whose
|
||||||
|
// angle corresponds to cosineOfConeAngle)
|
||||||
|
float perpDist = sqrtXXX (1 - (cosineOfConeAngle * cosineOfConeAngle));
|
||||||
|
const Vec3 c0 = basis * cosineOfConeAngle;
|
||||||
|
const Vec3 c1 = unitPerp * perpDist;
|
||||||
|
return (c0 + c1) * sourceLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
// given a vector, return a vector perpendicular to it. arbitrarily selects
|
||||||
|
// one of the infinitely many perpendicular vectors. a zero vector maps to
|
||||||
|
// itself, otherwise length is irrelevant (empirically, output length seems to
|
||||||
|
// remain within 20% of input length).
|
||||||
|
|
||||||
|
|
||||||
|
OpenSteer::Vec3
|
||||||
|
OpenSteer::findPerpendicularIn3d (const Vec3& direction)
|
||||||
|
{
|
||||||
|
// to be filled in:
|
||||||
|
Vec3 quasiPerp; // a direction which is "almost perpendicular"
|
||||||
|
Vec3 result; // the computed perpendicular to be returned
|
||||||
|
|
||||||
|
// three mutually perpendicular basis vectors
|
||||||
|
const Vec3 i (1, 0, 0);
|
||||||
|
const Vec3 j (0, 1, 0);
|
||||||
|
const Vec3 k (0, 0, 1);
|
||||||
|
|
||||||
|
// measure the projection of "direction" onto each of the axes
|
||||||
|
const float id = i.dot (direction);
|
||||||
|
const float jd = j.dot (direction);
|
||||||
|
const float kd = k.dot (direction);
|
||||||
|
|
||||||
|
// set quasiPerp to the basis which is least parallel to "direction"
|
||||||
|
if ((id <= jd) && (id <= kd))
|
||||||
|
{
|
||||||
|
quasiPerp = i; // projection onto i was the smallest
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if ((jd <= id) && (jd <= kd))
|
||||||
|
quasiPerp = j; // projection onto j was the smallest
|
||||||
|
else
|
||||||
|
quasiPerp = k; // projection onto k was the smallest
|
||||||
|
}
|
||||||
|
|
||||||
|
// return the cross product (direction x quasiPerp)
|
||||||
|
// which is guaranteed to be perpendicular to both of them
|
||||||
|
result.cross (direction, quasiPerp);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ----------------------------------------------------------------------------
|
88
opensteer/src/Vec3Utilities.cpp
Normal file
88
opensteer/src/Vec3Utilities.cpp
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/**
|
||||||
|
* OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
*
|
||||||
|
* Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
* Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* @author Bjoern Knafla <bknafla@uni-kassel.de>
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "OpenSteer/Vec3Utilities.h"
|
||||||
|
|
||||||
|
// Include assert
|
||||||
|
#include <cassert>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// Include OpenSteer::clamp
|
||||||
|
#include "OpenSteer/Utilities.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @todo Is this useful?
|
||||||
|
std::pair< Vec3, Vec3 >
|
||||||
|
OpenSteer::convertPointAndSegmentToVectors( const Vec3& point,
|
||||||
|
const Vec3& segmentPoint0,
|
||||||
|
const Vec3& segmentPoint1 )
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
OpenSteer::Vec3
|
||||||
|
OpenSteer::nearestPointOnSegment( const Vec3& point,
|
||||||
|
const Vec3& segmentPoint0,
|
||||||
|
const Vec3& segmentPoint1 )
|
||||||
|
{
|
||||||
|
// convert the test point to be "local" to ep0
|
||||||
|
Vec3 const local( point - segmentPoint0 );
|
||||||
|
|
||||||
|
// find the projection of "local" onto "segmentNormal"
|
||||||
|
Vec3 const segment( segmentPoint1 - segmentPoint0 );
|
||||||
|
float const segmentLength( segment.length() );
|
||||||
|
|
||||||
|
assert( 0 != segmentLength && "Segment mustn't be of length zero." );
|
||||||
|
|
||||||
|
Vec3 const segmentNormalized( segment / segmentLength );
|
||||||
|
float segmentProjection = segmentNormalized.dot (local);
|
||||||
|
|
||||||
|
segmentProjection = clamp( segmentProjection, 0.0f, segmentLength );
|
||||||
|
|
||||||
|
Vec3 result( segmentNormalized * segmentProjection );
|
||||||
|
result += segmentPoint0;
|
||||||
|
return result;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
float
|
||||||
|
OpenSteer::pointToSegmentDistance ( const Vec3& point,
|
||||||
|
const Vec3& segmentPoint0,
|
||||||
|
const Vec3& segmentPoint1)
|
||||||
|
{
|
||||||
|
return distance( point, nearestPointOnSegment( point, segmentPoint0, segmentPoint1 ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
712
opensteer/src/lq.c
Normal file
712
opensteer/src/lq.c
Normal file
@ -0,0 +1,712 @@
|
|||||||
|
/*
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
//
|
||||||
|
//
|
||||||
|
// OpenSteer -- Steering Behaviors for Autonomous Characters
|
||||||
|
//
|
||||||
|
// Copyright (c) 2002-2005, Sony Computer Entertainment America
|
||||||
|
// Original author: Craig Reynolds <craig_reynolds@playstation.sony.com>
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
// copy of this software and associated documentation files (the "Software"),
|
||||||
|
// to deal in the Software without restriction, including without limitation
|
||||||
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
// and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
// Software is furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
// ----------------------------------------------------------------------------
|
||||||
|
*/
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* */
|
||||||
|
/* Locality Query facility */
|
||||||
|
/* */
|
||||||
|
/* (by Craig Reynolds, see lq.h file for documentation) */
|
||||||
|
/* */
|
||||||
|
/* 5-17-99: created */
|
||||||
|
/* 5-20-99: found elusive "allocate 0 bins" bug */
|
||||||
|
/* 5-28-99: lqMapOverAllObjectsInLocality: clipped, incremental */
|
||||||
|
/* 6- 7-99: clean up, split off annotation stuff into debuglq.c */
|
||||||
|
/* 6- 8-99: tried screening by sum of coords ("first mean"?) but */
|
||||||
|
/* it was slightly slower, moved unused code to debuglq */
|
||||||
|
/* 10-19-99: Change lqClientObject, lqObject from: "struct x {};" to */
|
||||||
|
/* "typedef struct x {} x;" for EE compiler. */
|
||||||
|
/* 12- 2-00: Make lqObject "private" using lqInternalDB. */
|
||||||
|
/* 12- 5-00: Rename lqObject to lqDB, lqClientObject to lqClientProxy */
|
||||||
|
/* 12- 6-00: Change lqCallBackFunction from arglist of (void*) to: */
|
||||||
|
/* (void* clientObject, float distanceSquared, void* */
|
||||||
|
/* clientQueryState). Add void* clientQueryState arg to */
|
||||||
|
/* lqMapOverAllObjectsInLocality and its helper functions */
|
||||||
|
/* lqMapOverAllObjectsInLocalityClipped and */
|
||||||
|
/* lqMapOverAllOutsideObjects. Change macro */
|
||||||
|
/* lqTraverseBinClientObjectList to invoke callback */
|
||||||
|
/* function with three arguments, add "state" to its */
|
||||||
|
/* arglist. Remove extern lqDistanceSquared. */
|
||||||
|
/* 12- 7-00: Rename lqInitClientObject to lqInitClientProxy, make */
|
||||||
|
/* "func" be an argument to lqTraverseBinClientObjectList, */
|
||||||
|
/* add comments. */
|
||||||
|
/* 12- 8-00: Add lqFindNearestNeighborWithinRadius and related */
|
||||||
|
/* definitions: lqFindNearestHelper lqFindNearestState */
|
||||||
|
/* Add lqMapOverAllObjects and lqRemoveAllObjects (plus: */
|
||||||
|
/* lqMapOverAllObjectsInBin and lqRemoveAllObjectsInBin) */
|
||||||
|
/* */
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <float.h>
|
||||||
|
#include <limits.h> /* for INT_MAX */
|
||||||
|
#include "OpenSteer/lq.h"
|
||||||
|
|
||||||
|
/* for debugging and graphical annotation (normally unused) */
|
||||||
|
#ifdef BOIDS_LQ_DEBUG
|
||||||
|
#include "OpenSteer/debuglq.c"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef WIN32
|
||||||
|
#define USUSED_PARAM __attribute__ ((unused))
|
||||||
|
#else
|
||||||
|
#define USUSED_PARAM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* This structure represents the spatial database. Typically one of
|
||||||
|
these would be created, by a call to lqCreateDatabase, for a given
|
||||||
|
application. */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct lqInternalDB
|
||||||
|
{
|
||||||
|
|
||||||
|
/* the origin is the super-brick corner minimum coordinates */
|
||||||
|
float originx, originy, originz;
|
||||||
|
|
||||||
|
/* length of the edges of the super-brick */
|
||||||
|
float sizex, sizey, sizez;
|
||||||
|
|
||||||
|
/* number of sub-brick divisions in each direction */
|
||||||
|
int divx, divy, divz;
|
||||||
|
|
||||||
|
/* pointer to an array of pointers, one for each bin */
|
||||||
|
lqClientProxy** bins;
|
||||||
|
|
||||||
|
/* extra bin for "everything else" (points outside super-brick) */
|
||||||
|
lqClientProxy* other;
|
||||||
|
|
||||||
|
} lqInternalDB;
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Allocate and initialize an LQ database, return a pointer to it.
|
||||||
|
The application needs to call this before using the LQ facility.
|
||||||
|
The nine parameters define the properties of the "super-brick":
|
||||||
|
(1) origin: coordinates of one corner of the super-brick, its
|
||||||
|
minimum x, y and z extent.
|
||||||
|
(2) size: the width, height and depth of the super-brick.
|
||||||
|
(3) the number of subdivisions (sub-bricks) along each axis.
|
||||||
|
This routine also allocates the bin array, and initialize its
|
||||||
|
contents. */
|
||||||
|
|
||||||
|
|
||||||
|
lqInternalDB* lqCreateDatabase (float originx, float originy, float originz,
|
||||||
|
float sizex, float sizey, float sizez,
|
||||||
|
int divx, int divy, int divz)
|
||||||
|
{
|
||||||
|
lqInternalDB* lq = ((lqInternalDB*) malloc (sizeof (lqInternalDB)));
|
||||||
|
|
||||||
|
lqInitDatabase (lq,
|
||||||
|
originx, originy, originz,
|
||||||
|
sizex, sizey, sizez,
|
||||||
|
divx, divy, divz);
|
||||||
|
return lq;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Deallocate the memory used by the LQ database */
|
||||||
|
|
||||||
|
|
||||||
|
void lqDeleteDatabase(lqDB* lq)
|
||||||
|
{
|
||||||
|
free (lq->bins);
|
||||||
|
free (lq);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Given an LQ database object and the nine basic parameters: fill in
|
||||||
|
the object's slots, allocate the bin array, and initialize its
|
||||||
|
contents. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqInitDatabase (lqInternalDB* lq,
|
||||||
|
float originx, float originy, float originz,
|
||||||
|
float sizex, float sizey, float sizez,
|
||||||
|
int divx, int divy, int divz)
|
||||||
|
{
|
||||||
|
lq->originx = originx;
|
||||||
|
lq->originy = originy;
|
||||||
|
lq->originz = originz;
|
||||||
|
lq->sizex = sizex;
|
||||||
|
lq->sizey = sizey;
|
||||||
|
lq->sizez = sizez;
|
||||||
|
lq->divx = divx;
|
||||||
|
lq->divy = divy;
|
||||||
|
lq->divz = divz;
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int bincount = divx * divy * divz;
|
||||||
|
int arraysize = sizeof (lqClientProxy*) * bincount;
|
||||||
|
lq->bins = (lqClientProxy**) malloc (arraysize);
|
||||||
|
for (i=0; i<bincount; i++) lq->bins[i] = NULL;
|
||||||
|
}
|
||||||
|
lq->other = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Determine index into linear bin array given 3D bin indices */
|
||||||
|
|
||||||
|
|
||||||
|
#define lqBinCoordsToBinIndex(lq, ix, iy, iz) \
|
||||||
|
((ix * (lq)->divy * (lq)->divz) + (iy * (lq)->divz) + iz)
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Find the bin ID for a location in space. The location is given in
|
||||||
|
terms of its XYZ coordinates. The bin ID is a pointer to a pointer
|
||||||
|
to the bin contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
lqClientProxy** lqBinForLocation (lqInternalDB* lq,
|
||||||
|
float x, float y, float z)
|
||||||
|
{
|
||||||
|
int i, ix, iy, iz;
|
||||||
|
|
||||||
|
/* if point outside super-brick, return the "other" bin */
|
||||||
|
if (x < lq->originx) return &(lq->other);
|
||||||
|
if (y < lq->originy) return &(lq->other);
|
||||||
|
if (z < lq->originz) return &(lq->other);
|
||||||
|
if (x >= lq->originx + lq->sizex) return &(lq->other);
|
||||||
|
if (y >= lq->originy + lq->sizey) return &(lq->other);
|
||||||
|
if (z >= lq->originz + lq->sizez) return &(lq->other);
|
||||||
|
|
||||||
|
/* if point inside super-brick, compute the bin coordinates */
|
||||||
|
ix = (int) (((x - lq->originx) / lq->sizex) * lq->divx);
|
||||||
|
iy = (int) (((y - lq->originy) / lq->sizey) * lq->divy);
|
||||||
|
iz = (int) (((z - lq->originz) / lq->sizez) * lq->divz);
|
||||||
|
|
||||||
|
/* convert to linear bin number */
|
||||||
|
i = lqBinCoordsToBinIndex (lq, ix, iy, iz);
|
||||||
|
|
||||||
|
/* return pointer to that bin */
|
||||||
|
return &(lq->bins[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* The application needs to call this once on each lqClientProxy at
|
||||||
|
setup time to initialize its list pointers and associate the proxy
|
||||||
|
with its client object. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqInitClientProxy (lqClientProxy* proxy, void* clientObject)
|
||||||
|
{
|
||||||
|
proxy->prev = NULL;
|
||||||
|
proxy->next = NULL;
|
||||||
|
proxy->bin = NULL;
|
||||||
|
proxy->object = clientObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Adds a given client object to a given bin, linking it into the bin
|
||||||
|
contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqAddToBin (lqClientProxy* object, lqClientProxy** bin)
|
||||||
|
{
|
||||||
|
/* if bin is currently empty */
|
||||||
|
if (*bin == NULL)
|
||||||
|
{
|
||||||
|
object->prev = NULL;
|
||||||
|
object->next = NULL;
|
||||||
|
*bin = object;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
object->prev = NULL;
|
||||||
|
object->next = *bin;
|
||||||
|
(*bin)->prev = object;
|
||||||
|
*bin = object;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* record bin ID in proxy object */
|
||||||
|
object->bin = bin;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Removes a given client object from its current bin, unlinking it
|
||||||
|
from the bin contents list. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqRemoveFromBin (lqClientProxy* object)
|
||||||
|
{
|
||||||
|
/* adjust pointers if object is currently in a bin */
|
||||||
|
if (object->bin != NULL)
|
||||||
|
{
|
||||||
|
/* If this object is at the head of the list, move the bin
|
||||||
|
pointer to the next item in the list (might be NULL). */
|
||||||
|
if (*(object->bin) == object) *(object->bin) = object->next;
|
||||||
|
|
||||||
|
/* If there is a prev object, link its "next" pointer to the
|
||||||
|
object after this one. */
|
||||||
|
if (object->prev != NULL) object->prev->next = object->next;
|
||||||
|
|
||||||
|
/* If there is a next object, link its "prev" pointer to the
|
||||||
|
object before this one. */
|
||||||
|
if (object->next != NULL) object->next->prev = object->prev;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Null out prev, next and bin pointers of this object. */
|
||||||
|
object->prev = NULL;
|
||||||
|
object->next = NULL;
|
||||||
|
object->bin = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Call for each client object every time its location changes. For
|
||||||
|
example, in an animation application, this would be called each
|
||||||
|
frame for every moving object. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqUpdateForNewLocation (lqInternalDB* lq,
|
||||||
|
lqClientProxy* object,
|
||||||
|
float x, float y, float z)
|
||||||
|
{
|
||||||
|
/* find bin for new location */
|
||||||
|
lqClientProxy** newBin = lqBinForLocation (lq, x, y, z);
|
||||||
|
|
||||||
|
/* store location in client object, for future reference */
|
||||||
|
object->x = x;
|
||||||
|
object->y = y;
|
||||||
|
object->z = z;
|
||||||
|
|
||||||
|
/* has object moved into a new bin? */
|
||||||
|
if (newBin != object->bin)
|
||||||
|
{
|
||||||
|
lqRemoveFromBin (object);
|
||||||
|
lqAddToBin (object, newBin);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Given a bin's list of client proxies, traverse the list and invoke
|
||||||
|
the given lqCallBackFunction on each object that falls within the
|
||||||
|
search radius. */
|
||||||
|
|
||||||
|
|
||||||
|
#define lqTraverseBinClientObjectList(co, radiusSquared, func, state) \
|
||||||
|
while (co != NULL) \
|
||||||
|
{ \
|
||||||
|
/* compute distance (squared) from this client */ \
|
||||||
|
/* object to given locality sphere's centerpoint */ \
|
||||||
|
float dx = x - co->x; \
|
||||||
|
float dy = y - co->y; \
|
||||||
|
float dz = z - co->z; \
|
||||||
|
float distanceSquared = (dx * dx) + (dy * dy) + (dz * dz); \
|
||||||
|
\
|
||||||
|
/* apply function if client object within sphere */ \
|
||||||
|
if (distanceSquared < radiusSquared) \
|
||||||
|
(*func) (co->object, distanceSquared, state); \
|
||||||
|
\
|
||||||
|
/* consider next client object in bin list */ \
|
||||||
|
co = co->next; \
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* This subroutine of lqMapOverAllObjectsInLocality efficiently
|
||||||
|
traverses of subset of bins specified by max and min bin
|
||||||
|
coordinates. */
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInLocalityClipped (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState,
|
||||||
|
int minBinX,
|
||||||
|
int minBinY,
|
||||||
|
int minBinZ,
|
||||||
|
int maxBinX,
|
||||||
|
int maxBinY,
|
||||||
|
int maxBinZ);
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInLocalityClipped (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState,
|
||||||
|
int minBinX,
|
||||||
|
int minBinY,
|
||||||
|
int minBinZ,
|
||||||
|
int maxBinX,
|
||||||
|
int maxBinY,
|
||||||
|
int maxBinZ)
|
||||||
|
{
|
||||||
|
int i, j, k;
|
||||||
|
int iindex, jindex, kindex;
|
||||||
|
int slab = lq->divy * lq->divz;
|
||||||
|
int row = lq->divz;
|
||||||
|
int istart = minBinX * slab;
|
||||||
|
int jstart = minBinY * row;
|
||||||
|
int kstart = minBinZ;
|
||||||
|
lqClientProxy* co;
|
||||||
|
lqClientProxy** bin;
|
||||||
|
float radiusSquared = radius * radius;
|
||||||
|
|
||||||
|
#ifdef BOIDS_LQ_DEBUG
|
||||||
|
if (lqAnnoteEnable) drawBallGL (x, y, z, radius);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* loop for x bins across diameter of sphere */
|
||||||
|
iindex = istart;
|
||||||
|
for (i = minBinX; i <= maxBinX; i++)
|
||||||
|
{
|
||||||
|
/* loop for y bins across diameter of sphere */
|
||||||
|
jindex = jstart;
|
||||||
|
for (j = minBinY; j <= maxBinY; j++)
|
||||||
|
{
|
||||||
|
/* loop for z bins across diameter of sphere */
|
||||||
|
kindex = kstart;
|
||||||
|
for (k = minBinZ; k <= maxBinZ; k++)
|
||||||
|
{
|
||||||
|
/* get current bin's client object list */
|
||||||
|
bin = &lq->bins[iindex + jindex + kindex];
|
||||||
|
co = *bin;
|
||||||
|
|
||||||
|
#ifdef BOIDS_LQ_DEBUG
|
||||||
|
if (lqAnnoteEnable) drawBin (lq, bin);
|
||||||
|
#endif
|
||||||
|
/* traverse current bin's client object list */
|
||||||
|
lqTraverseBinClientObjectList (co,
|
||||||
|
radiusSquared,
|
||||||
|
func,
|
||||||
|
clientQueryState);
|
||||||
|
kindex += 1;
|
||||||
|
}
|
||||||
|
jindex += row;
|
||||||
|
}
|
||||||
|
iindex += slab;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* If the query region (sphere) extends outside of the "super-brick"
|
||||||
|
we need to check for objects in the catch-all "other" bin which
|
||||||
|
holds any object which are not inside the regular sub-bricks */
|
||||||
|
|
||||||
|
void lqMapOverAllOutsideObjects (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
void lqMapOverAllOutsideObjects (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
lqClientProxy* co = lq->other;
|
||||||
|
float radiusSquared = radius * radius;
|
||||||
|
|
||||||
|
/* traverse the "other" bin's client object list */
|
||||||
|
lqTraverseBinClientObjectList (co,
|
||||||
|
radiusSquared,
|
||||||
|
func,
|
||||||
|
clientQueryState);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Apply an application-specific function to all objects in a certain
|
||||||
|
locality. The locality is specified as a sphere with a given
|
||||||
|
center and radius. All objects whose location (key-point) is
|
||||||
|
within this sphere are identified and the function is applied to
|
||||||
|
them. The application-supplied function takes three arguments:
|
||||||
|
|
||||||
|
(1) a void* pointer to an lqClientProxy's "object".
|
||||||
|
(2) the square of the distance from the center of the search
|
||||||
|
locality sphere (x,y,z) to object's key-point.
|
||||||
|
(3) a void* pointer to the caller-supplied "client query state"
|
||||||
|
object -- typically NULL, but can be used to store state
|
||||||
|
between calls to the lqCallBackFunction.
|
||||||
|
|
||||||
|
This routine uses the LQ database to quickly reject any objects in
|
||||||
|
bins which do not overlap with the sphere of interest. Incremental
|
||||||
|
calculation of index values is used to efficiently traverse the
|
||||||
|
bins of interest. */
|
||||||
|
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInLocality (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
int partlyOut = 0;
|
||||||
|
int completelyOutside =
|
||||||
|
(((x + radius) < lq->originx) ||
|
||||||
|
((y + radius) < lq->originy) ||
|
||||||
|
((z + radius) < lq->originz) ||
|
||||||
|
((x - radius) >= lq->originx + lq->sizex) ||
|
||||||
|
((y - radius) >= lq->originy + lq->sizey) ||
|
||||||
|
((z - radius) >= lq->originz + lq->sizez));
|
||||||
|
int minBinX, minBinY, minBinZ, maxBinX, maxBinY, maxBinZ;
|
||||||
|
|
||||||
|
/* is the sphere completely outside the "super brick"? */
|
||||||
|
if (completelyOutside)
|
||||||
|
{
|
||||||
|
lqMapOverAllOutsideObjects (lq, x, y, z, radius, func,
|
||||||
|
clientQueryState);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* compute min and max bin coordinates for each dimension */
|
||||||
|
minBinX = (int) ((((x - radius) - lq->originx) / lq->sizex) * lq->divx);
|
||||||
|
minBinY = (int) ((((y - radius) - lq->originy) / lq->sizey) * lq->divy);
|
||||||
|
minBinZ = (int) ((((z - radius) - lq->originz) / lq->sizez) * lq->divz);
|
||||||
|
maxBinX = (int) ((((x + radius) - lq->originx) / lq->sizex) * lq->divx);
|
||||||
|
maxBinY = (int) ((((y + radius) - lq->originy) / lq->sizey) * lq->divy);
|
||||||
|
maxBinZ = (int) ((((z + radius) - lq->originz) / lq->sizez) * lq->divz);
|
||||||
|
|
||||||
|
/* clip bin coordinates */
|
||||||
|
if (minBinX < 0) {partlyOut = 1; minBinX = 0;}
|
||||||
|
if (minBinY < 0) {partlyOut = 1; minBinY = 0;}
|
||||||
|
if (minBinZ < 0) {partlyOut = 1; minBinZ = 0;}
|
||||||
|
if (maxBinX >= lq->divx) {partlyOut = 1; maxBinX = lq->divx - 1;}
|
||||||
|
if (maxBinY >= lq->divy) {partlyOut = 1; maxBinY = lq->divy - 1;}
|
||||||
|
if (maxBinZ >= lq->divz) {partlyOut = 1; maxBinZ = lq->divz - 1;}
|
||||||
|
|
||||||
|
/* map function over outside objects if necessary (if clipped) */
|
||||||
|
if (partlyOut)
|
||||||
|
lqMapOverAllOutsideObjects (lq, x, y, z, radius, func,
|
||||||
|
clientQueryState);
|
||||||
|
|
||||||
|
/* map function over objects in bins */
|
||||||
|
lqMapOverAllObjectsInLocalityClipped (lq,
|
||||||
|
x, y, z,
|
||||||
|
radius,
|
||||||
|
func,
|
||||||
|
clientQueryState,
|
||||||
|
minBinX, minBinY, minBinZ,
|
||||||
|
maxBinX, maxBinY, maxBinZ);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* internal helper function */
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct lqFindNearestState
|
||||||
|
{
|
||||||
|
void* ignoreObject;
|
||||||
|
void* nearestObject;
|
||||||
|
float minDistanceSquared;
|
||||||
|
|
||||||
|
} lqFindNearestState;
|
||||||
|
|
||||||
|
|
||||||
|
void lqFindNearestHelper (void* clientObject,
|
||||||
|
float distanceSquared,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
void lqFindNearestHelper (void* clientObject,
|
||||||
|
float distanceSquared,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
lqFindNearestState* fns = (lqFindNearestState*) clientQueryState;
|
||||||
|
|
||||||
|
/* do nothing if this is the "ignoreObject" */
|
||||||
|
if (fns->ignoreObject != clientObject)
|
||||||
|
{
|
||||||
|
/* record this object if it is the nearest one so far */
|
||||||
|
if (fns->minDistanceSquared > distanceSquared)
|
||||||
|
{
|
||||||
|
fns->nearestObject = clientObject;
|
||||||
|
fns->minDistanceSquared = distanceSquared;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Search the database to find the object whose key-point is nearest
|
||||||
|
to a given location yet within a given radius. That is, it finds
|
||||||
|
the object (if any) within a given search sphere which is nearest
|
||||||
|
to the sphere's center. The ignoreObject argument can be used to
|
||||||
|
exclude an object from consideration (or it can be NULL). This is
|
||||||
|
useful when looking for the nearest neighbor of an object in the
|
||||||
|
database, since otherwise it would be its own nearest neighbor.
|
||||||
|
The function returns a void* pointer to the nearest object, or
|
||||||
|
NULL if none is found. */
|
||||||
|
|
||||||
|
|
||||||
|
void* lqFindNearestNeighborWithinRadius (lqInternalDB* lq,
|
||||||
|
float x, float y, float z,
|
||||||
|
float radius,
|
||||||
|
void* ignoreObject)
|
||||||
|
{
|
||||||
|
/* initialize search state */
|
||||||
|
lqFindNearestState lqFNS;
|
||||||
|
lqFNS.nearestObject = NULL;
|
||||||
|
lqFNS.ignoreObject = ignoreObject;
|
||||||
|
lqFNS.minDistanceSquared = FLT_MAX;
|
||||||
|
|
||||||
|
/* map search helper function over all objects within radius */
|
||||||
|
lqMapOverAllObjectsInLocality (lq,
|
||||||
|
x, y, z,
|
||||||
|
radius,
|
||||||
|
lqFindNearestHelper,
|
||||||
|
&lqFNS);
|
||||||
|
|
||||||
|
/* return nearest object found, if any */
|
||||||
|
return lqFNS.nearestObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* internal helper function */
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInBin (lqClientProxy* binProxyList,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
void lqMapOverAllObjectsInBin (lqClientProxy* binProxyList,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
/* walk down proxy list, applying call-back function to each one */
|
||||||
|
while (binProxyList != NULL)
|
||||||
|
{
|
||||||
|
(*func) (binProxyList->object, 0, clientQueryState);
|
||||||
|
binProxyList = binProxyList->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Apply a user-supplied function to all objects in the database,
|
||||||
|
regardless of locality (cf lqMapOverAllObjectsInLocality) */
|
||||||
|
|
||||||
|
void lqMapOverAllObjects (lqInternalDB* lq,
|
||||||
|
lqCallBackFunction func,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int bincount = lq->divx * lq->divy * lq->divz;
|
||||||
|
for (i=0; i<bincount; i++)
|
||||||
|
{
|
||||||
|
lqMapOverAllObjectsInBin (lq->bins[i], func, clientQueryState);
|
||||||
|
}
|
||||||
|
lqMapOverAllObjectsInBin (lq->other, func, clientQueryState);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* looks at all bins (except "other") finding the min and max bin
|
||||||
|
populations and the average of NON-EMPTY bin populations. (The
|
||||||
|
average over all bins is a constant (population/bincount)) */
|
||||||
|
|
||||||
|
#ifndef NO_LQ_BIN_STATS
|
||||||
|
|
||||||
|
void lqgbpsCounter (void* clientObject USUSED_PARAM,
|
||||||
|
float distanceSquared USUSED_PARAM,
|
||||||
|
void* clientQueryState);
|
||||||
|
|
||||||
|
void lqgbpsCounter (void* clientObject USUSED_PARAM,
|
||||||
|
float distanceSquared USUSED_PARAM,
|
||||||
|
void* clientQueryState)
|
||||||
|
{
|
||||||
|
(*(int*)clientQueryState)++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lqGetBinPopulationStats (lqInternalDB* lq,
|
||||||
|
int* min,
|
||||||
|
int* max,
|
||||||
|
float* average)
|
||||||
|
{
|
||||||
|
int minPop = INT_MAX;
|
||||||
|
int maxPop = 0;
|
||||||
|
int totalCount = 0;
|
||||||
|
int nonEmptyBinCount = 0;
|
||||||
|
int bincount = lq->divx * lq->divy * lq->divz;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<bincount; i++)
|
||||||
|
{
|
||||||
|
/* clear the counter */
|
||||||
|
int objectCount = 0;
|
||||||
|
|
||||||
|
/* apply counting function to each object in bin[i] */
|
||||||
|
lqMapOverAllObjectsInBin (lq->bins[i], lqgbpsCounter, &objectCount);
|
||||||
|
|
||||||
|
/* collect data: max and min population, count objects and non-empty bins */
|
||||||
|
if (objectCount > 0)
|
||||||
|
{
|
||||||
|
nonEmptyBinCount++;
|
||||||
|
if (maxPop < objectCount) maxPop = objectCount;
|
||||||
|
if (minPop > objectCount) minPop = objectCount;
|
||||||
|
totalCount += objectCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set return values */
|
||||||
|
*min = minPop;
|
||||||
|
*max = maxPop;
|
||||||
|
*average = ((float) totalCount) / ((float) nonEmptyBinCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* NO_LQ_BIN_STATS */
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* internal helper function */
|
||||||
|
|
||||||
|
|
||||||
|
#define lqRemoveAllObjectsInBin(bin) \
|
||||||
|
while ((bin) != NULL) lqRemoveFromBin ((bin));
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
||||||
|
/* Removes (all proxies for) all objects from all bins */
|
||||||
|
|
||||||
|
|
||||||
|
void lqRemoveAllObjects (lqInternalDB* lq)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
int bincount = lq->divx * lq->divy * lq->divz;
|
||||||
|
for (i=0; i<bincount; i++)
|
||||||
|
{
|
||||||
|
lqRemoveAllObjectsInBin (lq->bins[i]);
|
||||||
|
}
|
||||||
|
lqRemoveAllObjectsInBin (lq->other);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* ------------------------------------------------------------------ */
|
134
pedestrian.h
134
pedestrian.h
@ -1,134 +0,0 @@
|
|||||||
/************************************************************************
|
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
|
||||||
* *
|
|
||||||
* This software is provided as-is, without any express or implied *
|
|
||||||
* warranty. In no event will the authors be held liable for any *
|
|
||||||
* damages arising from the use of this software. *
|
|
||||||
* *
|
|
||||||
* Permission is granted to anyone to use this software for any purpose, *
|
|
||||||
* including commercial applications, and to alter it and redistribute *
|
|
||||||
* it freely, subject to the following restrictions: *
|
|
||||||
* *
|
|
||||||
* 1. The origin of this software must not be misrepresented; you must *
|
|
||||||
* not claim that you wrote the original software. If you use this *
|
|
||||||
* software in a product, an acknowledgment in the product documentation *
|
|
||||||
* would be appreciated but is not required. *
|
|
||||||
* *
|
|
||||||
* 2. Altered source versions must be plainly marked as such, and must *
|
|
||||||
* not be misrepresented as being the original software. *
|
|
||||||
* *
|
|
||||||
* 3. This notice may not be removed or altered from any source *
|
|
||||||
* distribution. *
|
|
||||||
************************************************************************/
|
|
||||||
#ifndef OGTA_PEDESTRIAN_H
|
|
||||||
#define OGTA_PEDESTRIAN_H
|
|
||||||
|
|
||||||
#include <SDL.h>
|
|
||||||
#include "math3d.h"
|
|
||||||
#include "obox.h"
|
|
||||||
#include "animation.h"
|
|
||||||
#include "opengta.h"
|
|
||||||
|
|
||||||
namespace OpenGTA {
|
|
||||||
struct Projectile {
|
|
||||||
Projectile(uint8_t, float, Vector3D, Vector3D, Uint32);
|
|
||||||
uint8_t typeId;
|
|
||||||
float rot;
|
|
||||||
Vector3D pos;
|
|
||||||
Vector3D delta;
|
|
||||||
Uint32 endsAtTick;
|
|
||||||
};
|
|
||||||
class SpriteObject {
|
|
||||||
public:
|
|
||||||
SpriteObject(const Vector3D & p);
|
|
||||||
SpriteObject(const SpriteObject & other);
|
|
||||||
struct Animation : public Util::Animation {
|
|
||||||
Animation();
|
|
||||||
Animation(const Animation & other);
|
|
||||||
Animation(Uint16 foff, Uint8 num);
|
|
||||||
Animation(Uint16 foff, Uint8 num, float speed);
|
|
||||||
Uint16 firstFrameOffset;
|
|
||||||
//Uint8 numFrames;
|
|
||||||
float moveSpeed;
|
|
||||||
};
|
|
||||||
Vector3D pos;
|
|
||||||
//Uint8 curFrame;
|
|
||||||
Uint16 sprNum;
|
|
||||||
Sint16 remap;
|
|
||||||
//Animation * animRef;
|
|
||||||
Animation anim;
|
|
||||||
bool animActive;
|
|
||||||
void update(Uint32 ticks);
|
|
||||||
Uint32 lastFrameUpdateAt;
|
|
||||||
Uint32 lastUpdateAt;
|
|
||||||
float rot;
|
|
||||||
GraphicsBase::SpriteNumbers::SpriteTypes sprType;
|
|
||||||
void setAnimation(Animation & otherAnim);
|
|
||||||
protected:
|
|
||||||
Uint8 calcCurrentFrame(Uint32 ticks);
|
|
||||||
float heightOverTerrain(const Vector3D & v);
|
|
||||||
private:
|
|
||||||
void copyValues(const SpriteObject & other);
|
|
||||||
SpriteObject & operator = (const SpriteObject & other) { return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Pedestrian : public SpriteObject, public OBox {
|
|
||||||
public:
|
|
||||||
struct Controller {
|
|
||||||
// turn, move,
|
|
||||||
// run/walk/swim/crawl
|
|
||||||
// jump, shoot/punch,
|
|
||||||
Sint8 turn;
|
|
||||||
Sint8 move;
|
|
||||||
};
|
|
||||||
Pedestrian(const Vector3D & e, const Vector3D & pos);
|
|
||||||
Pedestrian(const Vector3D & e, const Vector3D & pos, const Uint32 & asId);
|
|
||||||
Pedestrian(const Pedestrian & other);
|
|
||||||
Uint32 pedId;
|
|
||||||
Controller* m_control;
|
|
||||||
Uint32 animId;
|
|
||||||
Vector3D speedForces;
|
|
||||||
void switchToAnim(const Uint32 & newId);
|
|
||||||
|
|
||||||
void update(Uint32 ticks);
|
|
||||||
void equip(uint8_t eq_id);
|
|
||||||
void giveItem(uint8_t id, uint32_t amount);
|
|
||||||
void fireWeapon(Uint32 ticks);
|
|
||||||
private:
|
|
||||||
typedef std::map<uint8_t, uint32_t> InventoryType;
|
|
||||||
InventoryType inventory;
|
|
||||||
uint8_t activeWeapon;
|
|
||||||
bool inGroundContact;
|
|
||||||
void tryMove(Vector3D nPos);
|
|
||||||
void copyValues(const Pedestrian & other);
|
|
||||||
Uint32 weaponReloadedAt;
|
|
||||||
//Uint8 calcCurrentFrame(Uint32 ticks);
|
|
||||||
Pedestrian & operator = (const Pedestrian & other) { return *this; }
|
|
||||||
};
|
|
||||||
|
|
||||||
class Car : public SpriteObject, public OBox {
|
|
||||||
public:
|
|
||||||
Car(const OpenGTA::Map::ObjectPosition & op);
|
|
||||||
Car(const Car & other);
|
|
||||||
Uint32 delta;
|
|
||||||
Uint32 carId;
|
|
||||||
Uint8 type;
|
|
||||||
private:
|
|
||||||
GraphicsBase::CarInfo & c_info;
|
|
||||||
void copyValues(const Car & other);
|
|
||||||
Car & operator = (const Car & other) { return *this; }
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
class GameObject : public SpriteObject, public OBox {
|
|
||||||
public:
|
|
||||||
GameObject(const OpenGTA::Map::ObjectPosition & op);
|
|
||||||
GameObject(const GameObject & other);
|
|
||||||
Uint32 objId;
|
|
||||||
private:
|
|
||||||
void copyValues(const GameObject & other);
|
|
||||||
GameObject & operator = (const GameObject & o) { return *this; }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
176
prepare_build.sh
176
prepare_build.sh
@ -13,11 +13,11 @@ function program_exists() {
|
|||||||
function print_make_file_list() {
|
function print_make_file_list() {
|
||||||
FOO=GL_SRC
|
FOO=GL_SRC
|
||||||
FOOO=GL_OBJ
|
FOOO=GL_OBJ
|
||||||
( grep -l "^namespace OpenGL" *.cpp ; echo "gl_frustum.cpp";echo "math/obox.cpp coldet/math3d.cpp" ) | sort | xargs echo "$FOO ="
|
( grep -l "^namespace OpenGL" *.cpp ;echo "gl_frustum.cpp";echo "math/obox.cpp coldet/math3d.cpp util/physfsrwops.c" ) | sort | xargs echo "$FOO ="
|
||||||
echo "$FOOO = \${$FOO:.cpp=.o}"
|
echo "$FOOO = \${$FOO:.cpp=.o}"
|
||||||
FOO=OGTA_SRC
|
FOO=OGTA_SRC
|
||||||
FOOO=OGTA_OBJ
|
FOOO=OGTA_OBJ
|
||||||
( grep -l "^namespace OpenGTA" *.cpp ; echo "slope_height_func.cpp" ) | sort | xargs echo "$FOO ="
|
( grep -l "^namespace OpenGTA" *.cpp ; echo "slope_height_func.cpp" )|grep -v viewer.cpp |grep -v sprite_anim_player.cpp| sort | xargs echo "$FOO ="
|
||||||
echo "$FOOO = \${$FOO:.cpp=.o}"
|
echo "$FOOO = \${$FOO:.cpp=.o}"
|
||||||
|
|
||||||
UTIL_SRC=$(ls util/*.cpp | grep -v color.cpp | grep -v sound | xargs echo)
|
UTIL_SRC=$(ls util/*.cpp | grep -v color.cpp | grep -v sound | xargs echo)
|
||||||
@ -35,6 +35,13 @@ LUA_OBJ = \${LUA_SRC:.cpp=.o}
|
|||||||
SOUND_SRC = $SOUND_SRC
|
SOUND_SRC = $SOUND_SRC
|
||||||
SOUND_OBJ = \${SOUND_SRC:.cpp=.o}
|
SOUND_OBJ = \${SOUND_SRC:.cpp=.o}
|
||||||
|
|
||||||
|
OSTEER_SRC = opensteer/src/Clock.cpp
|
||||||
|
OSTEER_OBJ = \${OSTEER_SRC:.cpp=.o}
|
||||||
|
|
||||||
|
SOUND_SRC = util/sound_device.cpp util/sound_fx_cache.cpp util/sound_music_player.cpp \
|
||||||
|
util/sound_resample2.cpp util/sound_system.cpp
|
||||||
|
SOUND_OBJ = \$(SOUND_SRC:.cpp=.p)
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -58,13 +65,13 @@ gfxextract${EXE_PFIX}: gfx_extract.cpp read_gry.o read_g24.o read_cmp.o navdata.
|
|||||||
-o \$@ \$+ \\
|
-o \$@ \$+ \\
|
||||||
\$(SDL_LIB) \$(SDL_GL_LIB) \$(SDL_IMG_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB)
|
\$(SDL_LIB) \$(SDL_GL_LIB) \$(SDL_IMG_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB)
|
||||||
|
|
||||||
viewer${EXE_PFIX}: main2.cpp viewer.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ)
|
viewer${EXE_PFIX}: main2.cpp viewer.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OSTEER_OBJ)
|
||||||
\$(CXX) \$(CATCH_E) \$(FLAGS) \$(DEFS) \\
|
\$(CXX) \$(CATCH_E) \$(FLAGS) \$(DEFS) \\
|
||||||
\$(INC) \\
|
\$(INC) \\
|
||||||
-o \$@ \$+ \\
|
-o \$@ \$+ \\
|
||||||
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB)
|
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB)
|
||||||
|
|
||||||
luaviewer${EXE_PFIX}: main2.cpp viewer.cpp \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \
|
luaviewer${EXE_PFIX}: main2.cpp viewer.cpp \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OSTEER_OBJ) \
|
||||||
\$(LUA_OBJ)
|
\$(LUA_OBJ)
|
||||||
\$(CXX) \$(CATCH_E) -DWITH_LUA \$(FLAGS) \$(DEFS) \\
|
\$(CXX) \$(CATCH_E) -DWITH_LUA \$(FLAGS) \$(DEFS) \\
|
||||||
\$(INC) \\
|
\$(INC) \\
|
||||||
@ -72,7 +79,7 @@ luaviewer${EXE_PFIX}: main2.cpp viewer.cpp \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ)
|
|||||||
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB) \$(LUA_LIB)
|
\$(SDL_LIB) \$(SDL_GL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(COLDET_LIB) \$(LUA_LIB)
|
||||||
|
|
||||||
|
|
||||||
spriteplayer${EXE_PFIX}: sprite_anim_player.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) main2.cpp
|
spriteplayer${EXE_PFIX}: sprite_anim_player.o \$(OGTA_OBJ) \$(GL_OBJ) \$(UTIL_OBJ) \$(OSTEER_OBJ) main2.cpp
|
||||||
\$(CXX) \$(CATCH_E) \$(FLAGS) \$(DEFS) \\
|
\$(CXX) \$(CATCH_E) \$(FLAGS) \$(DEFS) \\
|
||||||
\$(INC) \\
|
\$(INC) \\
|
||||||
-o \$@ \$+ \\
|
-o \$@ \$+ \\
|
||||||
@ -91,6 +98,26 @@ objdump: tools/obj_dump.cpp read_gry.o \$(UTIL_OBJ) main2.o
|
|||||||
objdump_map: tools/obj_dump.cpp read_gry.o \$(UTIL_OBJ) main2.o read_cmp.o navdata.o
|
objdump_map: tools/obj_dump.cpp read_gry.o \$(UTIL_OBJ) main2.o read_cmp.o navdata.o
|
||||||
\$(CXX) \$(CXXFLAGS) -DDUMP_OBJ_IN_MAP -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB)
|
\$(CXX) \$(CXXFLAGS) -DDUMP_OBJ_IN_MAP -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB)
|
||||||
|
|
||||||
|
car_dump: tools/car_dump.cpp dataholder.o read_gry.o read_cmp.o read_g24.o navdata.o \
|
||||||
|
main2.o read_fxt.o util/set.o util/buffercache.o util/log.o util/m_exceptions.o
|
||||||
|
\$(CXX) \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB)
|
||||||
|
|
||||||
|
plane_test: tests/test_plane.cpp math/line_intersect.o util/log.o \
|
||||||
|
util/m_exceptions.o util/cell_iterator.o util/set.o util/buffercache.o \
|
||||||
|
read_cmp.o datahelper.o navdata.o read_fxt.o read_gry.o read_g24.o \
|
||||||
|
dataholder.o
|
||||||
|
\$(CXX) \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB)
|
||||||
|
|
||||||
|
lua_map_test: tests/lua_map_test.o util/file_helper.o util/log.o \
|
||||||
|
util/m_exceptions.o util/buffercache.o util/set.o navdata.o \
|
||||||
|
dataholder.o read_cmp.o read_gry.o read_g24.o read_fxt.o datahelper.o \
|
||||||
|
main2.o lua_addon/lua_map.o lua_addon/lua_vm.o lua_addon/lua_stackguard.o
|
||||||
|
\$(CXX) \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(LUA_LIB)
|
||||||
|
|
||||||
|
sound_test: read_sdt.o util/m_exceptions.o util/sound_resample2.o \
|
||||||
|
util/sound_device.o util/sound_system.cpp util/sound_fx_cache.o \
|
||||||
|
util/sound_music_player.o util/physfsrwops.c util/log.o
|
||||||
|
\$(CXX) -DSOUND_TEST \$(CXXFLAGS) -o \$@ \$+ \$(SDL_LIB) \$(PHYSFS_LIB) \$(LOKI_LIB) \$(AUDIO_LIB)
|
||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -116,6 +143,19 @@ function check_sdl () {
|
|||||||
pkg_config_try_multiple SDL SDL sdl
|
pkg_config_try_multiple SDL SDL sdl
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
cat <<EOF >_out_$$.cpp
|
||||||
|
#include <SDL.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
SDL_GL_SWAP_CONTROL;
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
g++ $SDL_INC _out_$$.cpp 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
SDL_GL_SWAP_CONTROL='#define HAVE_SDL_VSYNC'
|
||||||
|
else
|
||||||
|
SDL_GL_SWAP_CONTROL='#undef HAVE_SDL_VSYNC'
|
||||||
|
fi
|
||||||
|
rm -f _out_$$.cpp a.out
|
||||||
}
|
}
|
||||||
|
|
||||||
function pkg_config_try_multiple () {
|
function pkg_config_try_multiple () {
|
||||||
@ -145,6 +185,38 @@ function check_lua () {
|
|||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function check_sdl_audio () {
|
||||||
|
local good=0
|
||||||
|
cat <<EOF >_out_$$.cpp
|
||||||
|
#include <SDL_mixer.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
g++ $SDL_INC _out_$$.cpp 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
let good=$good+1
|
||||||
|
fi
|
||||||
|
rm -f _out_$$.cpp
|
||||||
|
|
||||||
|
cat <<EOF >_out_$$.cpp
|
||||||
|
#include <SDL_sound.h>
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
g++ $SDL_INC _out_$$.cpp 2>/dev/null
|
||||||
|
if [ $? -eq 0 ]; then
|
||||||
|
let good=$good+1
|
||||||
|
fi
|
||||||
|
rm -f _out_$$.cpp a.out
|
||||||
|
|
||||||
|
if [ $good -eq 2 ]; then
|
||||||
|
AUDIO_LD="-lSDL_mixer -lSDL_sound"
|
||||||
|
SDL_SOUND_MIXER='#define WITH_SOUND'
|
||||||
|
else
|
||||||
|
SDL_SOUND_MIXER='#undef WITH_SOUND'
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
function check_physfs () {
|
function check_physfs () {
|
||||||
program_exists pkg-config
|
program_exists pkg-config
|
||||||
if [ $? -eq 1 ]; then
|
if [ $? -eq 1 ]; then
|
||||||
@ -153,18 +225,26 @@ function check_physfs () {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function check_compiler () {
|
function check_compiler () {
|
||||||
g++ 1>/dev/null 2>&1
|
if [ "$OGTA_PLATFORM" == "WIN32" ]; then
|
||||||
|
_CXX=i586-mingw32msvc-g++
|
||||||
|
_CC=i586-mingw32msvc-gcc
|
||||||
|
else
|
||||||
|
_CXX=g++
|
||||||
|
_CC=gcc
|
||||||
|
fi
|
||||||
|
$_CXX 1>/dev/null 2>&1
|
||||||
if [ $? -eq 1 ]; then
|
if [ $? -eq 1 ]; then
|
||||||
CXX=g++
|
CXX=$_CXX
|
||||||
else
|
else
|
||||||
CXX=
|
CXX=
|
||||||
fi
|
fi
|
||||||
gcc 1>/dev/null 2>&1
|
$_CC 1>/dev/null 2>&1
|
||||||
if [ $? -eq 1 ]; then
|
if [ $? -eq 1 ]; then
|
||||||
CC=gcc
|
CC=$_CC
|
||||||
else
|
else
|
||||||
CC=
|
CC=
|
||||||
fi
|
fi
|
||||||
|
GCC_VERSION=$($CXX --version | head -n 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
# defaults
|
# defaults
|
||||||
@ -172,11 +252,6 @@ function check_compiler () {
|
|||||||
DEBUG=-ggdb
|
DEBUG=-ggdb
|
||||||
WARN=-Wall
|
WARN=-Wall
|
||||||
OPT=-O2
|
OPT=-O2
|
||||||
if [ "$1" == "LINUX" ]; then
|
|
||||||
DEFS="-DLINUX -DDO_SCALEX"
|
|
||||||
else
|
|
||||||
DEFS="-DWIN32 -DDO_SCALEX"
|
|
||||||
fi
|
|
||||||
PHYSFS_LIB=-lphysfs
|
PHYSFS_LIB=-lphysfs
|
||||||
SDL_LIB=-lSDL
|
SDL_LIB=-lSDL
|
||||||
LUA_LIB=-llua51
|
LUA_LIB=-llua51
|
||||||
@ -190,7 +265,7 @@ CC = $CC
|
|||||||
DEBUG = $DEBUG
|
DEBUG = $DEBUG
|
||||||
OPT = $OPT
|
OPT = $OPT
|
||||||
WARN = $WARN
|
WARN = $WARN
|
||||||
DEFS = $DEFS -DGCC
|
DEFS = $DEFS
|
||||||
|
|
||||||
# def only for 'main' programs to let gdb handle the exception
|
# def only for 'main' programs to let gdb handle the exception
|
||||||
#CATCH_E = -DDONT_CATCH
|
#CATCH_E = -DDONT_CATCH
|
||||||
@ -211,6 +286,9 @@ SDL_IMG_LIB = -lSDL_image
|
|||||||
LUA_INC = $LUA_INC
|
LUA_INC = $LUA_INC
|
||||||
LUA_LIB = $LUA_LIB
|
LUA_LIB = $LUA_LIB
|
||||||
|
|
||||||
|
AUDIO_INC =
|
||||||
|
AUDIO_LIB = $AUDIO_LD
|
||||||
|
|
||||||
LINK_LAZY = -Xlinker --unresolved-symbols -Xlinker ignore-all
|
LINK_LAZY = -Xlinker --unresolved-symbols -Xlinker ignore-all
|
||||||
|
|
||||||
EOF
|
EOF
|
||||||
@ -225,7 +303,7 @@ CC = i586-mingw32msvc-gcc
|
|||||||
#DEBUG = $DEBUG
|
#DEBUG = $DEBUG
|
||||||
OPT = $OPT
|
OPT = $OPT
|
||||||
WARN = $WARN
|
WARN = $WARN
|
||||||
DEFS = $DEFS -DGCC
|
DEFS = $DEFS
|
||||||
|
|
||||||
# def only for 'main' programs to let gdb handle the exception
|
# def only for 'main' programs to let gdb handle the exception
|
||||||
#CATCH_E = -DDONT_CATCH
|
#CATCH_E = -DDONT_CATCH
|
||||||
@ -256,7 +334,7 @@ function print_all() {
|
|||||||
check_sdl
|
check_sdl
|
||||||
check_lua
|
check_lua
|
||||||
check_physfs
|
check_physfs
|
||||||
check_compiler
|
check_sdl_audio
|
||||||
print_detected
|
print_detected
|
||||||
print_make_file_list
|
print_make_file_list
|
||||||
print_target_list
|
print_target_list
|
||||||
@ -266,12 +344,68 @@ include depend
|
|||||||
EOF
|
EOF
|
||||||
}
|
}
|
||||||
|
|
||||||
if [ "$1" == "LINUX" ]; then
|
function print_config_h() {
|
||||||
echo "*** LINUX ***"
|
if [ -e ogta_version ]; then
|
||||||
print_all > src_list.make
|
LAST_TOUCHED=$(cat ogta_version)
|
||||||
else
|
else
|
||||||
|
LAST_TOUCHED=$(find . -type f -exec ls -tl {} \; | grep -v CVS | tail -1 | awk '{print $6}')
|
||||||
|
echo $LAST_TOUCHED > ogta_version
|
||||||
|
fi
|
||||||
|
|
||||||
|
cat <<EOF
|
||||||
|
// WIN32 already defined when cross-compiling...
|
||||||
|
#ifndef $OGTA_PLATFORM
|
||||||
|
#define $OGTA_PLATFORM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// to avoid some errors on prg-exit
|
||||||
|
#define LOKI_FUNCTOR_IS_NOT_A_SMALLOBJECT
|
||||||
|
|
||||||
|
// platform specific switches
|
||||||
|
#ifdef LINUX
|
||||||
|
#define OGTA_PLATFORM_INFO "linux"
|
||||||
|
// for coldet; FIXME: really only for linux?
|
||||||
|
#define GCC
|
||||||
|
|
||||||
|
#elif WIN32
|
||||||
|
#define OGTA_PLATFORM_INFO "win32"
|
||||||
|
#else
|
||||||
|
#error(No platform defined)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// global compile-time vars
|
||||||
|
#define OGTA_VERSION_INFO "$LAST_TOUCHED"
|
||||||
|
|
||||||
|
#define DEFAULT_SCREEN_WIDTH 640
|
||||||
|
#define DEFAULT_SCREEN_HEIGHT 480
|
||||||
|
|
||||||
|
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
||||||
|
#define OGTA_DEFAULT_MOD_PATH ""
|
||||||
|
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getBaseDir()
|
||||||
|
|
||||||
|
#define USED_GCC_VERSION "$GCC_VERSION"
|
||||||
|
|
||||||
|
// enable features
|
||||||
|
#define DO_SCALEX
|
||||||
|
#undef WITH_LUA
|
||||||
|
$SDL_SOUND_MIXER
|
||||||
|
$SDL_GL_SWAP_CONTROL
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
if [[ -n "$1" && "$1" != "LINUX" ]]; then
|
||||||
|
OGTA_PLATFORM=WIN32
|
||||||
echo "*** WIN32 ***"
|
echo "*** WIN32 ***"
|
||||||
|
DEFS="-include config.h"
|
||||||
|
check_compiler
|
||||||
print_w32settings > src_list.make
|
print_w32settings > src_list.make
|
||||||
print_make_file_list >> src_list.make
|
print_make_file_list >> src_list.make
|
||||||
print_target_list >> src_list.make
|
print_target_list >> src_list.make
|
||||||
|
else
|
||||||
|
OGTA_PLATFORM="LINUX"
|
||||||
|
echo "*** LINUX ***"
|
||||||
|
check_compiler
|
||||||
|
DEFS="-include config.h"
|
||||||
|
print_all > src_list.make
|
||||||
fi
|
fi
|
||||||
|
print_config_h > config.h
|
||||||
|
10
read_cmp.cpp
10
read_cmp.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -15,6 +15,7 @@
|
|||||||
#include "navdata.h"
|
#include "navdata.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "m_exceptions.h"
|
#include "m_exceptions.h"
|
||||||
|
#include "datahelper.h"
|
||||||
|
|
||||||
/* see http://members.aol.com/form1/fixed.htm for fixed point floats:
|
/* see http://members.aol.com/form1/fixed.htm for fixed point floats:
|
||||||
* int_var = (long) fixed_var >> 8; // for 8 bits after point
|
* int_var = (long) fixed_var >> 8; // for 8 bits after point
|
||||||
@ -35,6 +36,7 @@ namespace OpenGTA {
|
|||||||
o << filename << " with error: " << SDL_GetError();
|
o << filename << " with error: " << SDL_GetError();
|
||||||
throw E_FILENOTFOUND(o.str());
|
throw E_FILENOTFOUND(o.str());
|
||||||
}
|
}
|
||||||
|
size_t level_as_num = Helper::mapFileName2Number(filename);
|
||||||
loadHeader();
|
loadHeader();
|
||||||
loadBase();
|
loadBase();
|
||||||
loadColumn();
|
loadColumn();
|
||||||
@ -42,7 +44,7 @@ namespace OpenGTA {
|
|||||||
loadObjects();
|
loadObjects();
|
||||||
loadRoutes();
|
loadRoutes();
|
||||||
loadLocations();
|
loadLocations();
|
||||||
loadNavData();
|
loadNavData(level_as_num);
|
||||||
//dump();
|
//dump();
|
||||||
}
|
}
|
||||||
Map::~Map() {
|
Map::~Map() {
|
||||||
@ -217,11 +219,11 @@ namespace OpenGTA {
|
|||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
void Map::loadNavData() {
|
void Map::loadNavData(const size_t levelNum) {
|
||||||
PHYSFS_uint32 _si = _baseSize + columnSize + _topHeaderSize +
|
PHYSFS_uint32 _si = _baseSize + columnSize + _topHeaderSize +
|
||||||
objectPosSize + routeSize + 3 * 6 * 6 + blockSize;
|
objectPosSize + routeSize + 3 * 6 * 6 + blockSize;
|
||||||
PHYSFS_seek(fd, _si);
|
PHYSFS_seek(fd, _si);
|
||||||
nav = new NavData(navDataSize, fd);
|
nav = new NavData(navDataSize, fd, levelNum);
|
||||||
assert(nav);
|
assert(nav);
|
||||||
}
|
}
|
||||||
PHYSFS_uint16 Map::getNumBlocksAt(PHYSFS_uint8 x, PHYSFS_uint8 y) {
|
PHYSFS_uint16 Map::getNumBlocksAt(PHYSFS_uint8 x, PHYSFS_uint8 y) {
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
|
13
read_fxt.cpp
13
read_fxt.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -11,6 +11,8 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include "opengta.h"
|
#include "opengta.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
MessageDB::MessageDB() {
|
MessageDB::MessageDB() {
|
||||||
@ -31,8 +33,7 @@ namespace OpenGTA {
|
|||||||
f = PHYSFS_openRead(f2.c_str());
|
f = PHYSFS_openRead(f2.c_str());
|
||||||
}
|
}
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
std::cerr << "Error: could not open " << file << " for reading" << std::endl;
|
throw E_FILENOTFOUND(file);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
messages.clear();
|
messages.clear();
|
||||||
@ -92,7 +93,7 @@ namespace OpenGTA {
|
|||||||
const std::string& MessageDB::getText(const char* id) {
|
const std::string& MessageDB::getText(const char* id) {
|
||||||
std::map<std::string, std::string>::iterator i = messages.find(std::string(id));
|
std::map<std::string, std::string>::iterator i = messages.find(std::string(id));
|
||||||
if (i == messages.end()) {
|
if (i == messages.end()) {
|
||||||
std::cerr << "Error: string lookup failed for key: " << id << std::endl;
|
ERROR << "string lookup failed for key: " << id << std::endl;
|
||||||
return _error;
|
return _error;
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
@ -101,7 +102,7 @@ namespace OpenGTA {
|
|||||||
const std::string& MessageDB::getText(const std::string &id) {
|
const std::string& MessageDB::getText(const std::string &id) {
|
||||||
std::map<std::string, std::string>::iterator i = messages.find(id);
|
std::map<std::string, std::string>::iterator i = messages.find(id);
|
||||||
if (i == messages.end()) {
|
if (i == messages.end()) {
|
||||||
std::cerr << "Error: string lookup failed for key: " << id << std::endl;
|
ERROR << "string lookup failed for key: " << id << std::endl;
|
||||||
return _error;
|
return _error;
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
@ -112,7 +113,7 @@ namespace OpenGTA {
|
|||||||
snprintf(reinterpret_cast<char*>(&tmp), 10, "%i", id);
|
snprintf(reinterpret_cast<char*>(&tmp), 10, "%i", id);
|
||||||
std::map<std::string, std::string>::iterator i = messages.find(std::string(tmp));
|
std::map<std::string, std::string>::iterator i = messages.find(std::string(tmp));
|
||||||
if (i == messages.end()) {
|
if (i == messages.end()) {
|
||||||
std::cerr << "Error: string lookup failed for key: " << id << std::endl;
|
ERROR << "string lookup failed for key: " << id << std::endl;
|
||||||
return _error;
|
return _error;
|
||||||
}
|
}
|
||||||
return i->second;
|
return i->second;
|
||||||
|
20
read_g24.cpp
20
read_g24.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -29,6 +29,23 @@ namespace OpenGTA {
|
|||||||
palIndex = NULL;
|
palIndex = NULL;
|
||||||
loadHeader();
|
loadHeader();
|
||||||
setupBlocking(style);
|
setupBlocking(style);
|
||||||
|
// actually the next two are style003.g24, but at least somewhere close
|
||||||
|
firstValidPedRemap = 60;
|
||||||
|
lastValidPedRemap = 116;
|
||||||
|
if (style.find("001") != std::string::npos) {
|
||||||
|
firstValidPedRemap = 75;
|
||||||
|
lastValidPedRemap = 131;
|
||||||
|
}
|
||||||
|
else if (style.find("002") != std::string::npos) {
|
||||||
|
firstValidPedRemap = 79;
|
||||||
|
lastValidPedRemap = 135;
|
||||||
|
}
|
||||||
|
else if (style.find("003") != std::string::npos) {
|
||||||
|
// already set
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
WARN << "Unknown g24 style - ped remaps most likely broken!" << std::endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics24Bit::~Graphics24Bit() {
|
Graphics24Bit::~Graphics24Bit() {
|
||||||
@ -143,6 +160,7 @@ namespace OpenGTA {
|
|||||||
PHYSFS_uint64 st = static_cast<PHYSFS_uint64>(_topHeaderSize) +
|
PHYSFS_uint64 st = static_cast<PHYSFS_uint64>(_topHeaderSize) +
|
||||||
sideSize + lidSize + auxSize + auxBlockTrailSize + animSize +
|
sideSize + lidSize + auxSize + auxBlockTrailSize + animSize +
|
||||||
pagedClutSize + paletteIndexSize + objectInfoSize;
|
pagedClutSize + paletteIndexSize + objectInfoSize;
|
||||||
|
//INFO << "seek for " << st << std::endl;
|
||||||
loadCarInfo_shared(st);
|
loadCarInfo_shared(st);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
read_gry.cpp
23
read_gry.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -268,6 +268,17 @@ namespace OpenGTA {
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int GraphicsBase::getRandomPedRemapNumber() {
|
||||||
|
return int(rand() * (1.0f / (1.0f + RAND_MAX)) *
|
||||||
|
(lastValidPedRemap - firstValidPedRemap) +
|
||||||
|
firstValidPedRemap);
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int GraphicsBase::getPedRemapNumberType(unsigned int _type) {
|
||||||
|
ERROR << "not implemented"<< std::endl;
|
||||||
|
return _type;
|
||||||
|
}
|
||||||
|
|
||||||
Graphics8Bit::Graphics8Bit(const std::string& style) : GraphicsBase() {
|
Graphics8Bit::Graphics8Bit(const std::string& style) : GraphicsBase() {
|
||||||
fd = PHYSFS_openRead(style.c_str());
|
fd = PHYSFS_openRead(style.c_str());
|
||||||
if (fd == NULL) {
|
if (fd == NULL) {
|
||||||
@ -288,6 +299,8 @@ namespace OpenGTA {
|
|||||||
auxBlockTrailSize = 0;
|
auxBlockTrailSize = 0;
|
||||||
loadHeader();
|
loadHeader();
|
||||||
setupBlocking(style);
|
setupBlocking(style);
|
||||||
|
firstValidPedRemap = 131;
|
||||||
|
lastValidPedRemap = 187;
|
||||||
}
|
}
|
||||||
|
|
||||||
Graphics8Bit::~Graphics8Bit() {
|
Graphics8Bit::~Graphics8Bit() {
|
||||||
@ -423,7 +436,7 @@ namespace OpenGTA {
|
|||||||
for (int j=0; j<animation->frameCount; j++) {
|
for (int j=0; j<animation->frameCount; j++) {
|
||||||
uint8_t val;
|
uint8_t val;
|
||||||
PHYSFS_read(fd, static_cast<void*>(&val), 1, 1);
|
PHYSFS_read(fd, static_cast<void*>(&val), 1, 1);
|
||||||
animation->frame.push_back(val);
|
animation->frame[j] = val;
|
||||||
//PHYSFS_read(fd, static_cast<void*>(&animations[i].frame[j]), 1, 1);
|
//PHYSFS_read(fd, static_cast<void*>(&animations[i].frame[j]), 1, 1);
|
||||||
}
|
}
|
||||||
animations.push_back(animation);
|
animations.push_back(animation);
|
||||||
@ -498,8 +511,10 @@ namespace OpenGTA {
|
|||||||
void GraphicsBase::loadCarInfo_shared(PHYSFS_uint64 offset) {
|
void GraphicsBase::loadCarInfo_shared(PHYSFS_uint64 offset) {
|
||||||
PHYSFS_seek(fd, offset);
|
PHYSFS_seek(fd, offset);
|
||||||
|
|
||||||
|
//INFO << "starting at offset " << offset << std::endl;
|
||||||
PHYSFS_uint32 bytes_read = 0;
|
PHYSFS_uint32 bytes_read = 0;
|
||||||
while (bytes_read < carInfoSize) {
|
while (bytes_read < carInfoSize) {
|
||||||
|
//INFO << bytes_read << ": " << carInfoSize << std::endl;
|
||||||
CarInfo * car = new CarInfo();
|
CarInfo * car = new CarInfo();
|
||||||
|
|
||||||
PHYSFS_readSLE16(fd, &car->width);
|
PHYSFS_readSLE16(fd, &car->width);
|
||||||
@ -579,6 +594,10 @@ namespace OpenGTA {
|
|||||||
|
|
||||||
PHYSFS_readSLE16(fd, &car->numDoors);
|
PHYSFS_readSLE16(fd, &car->numDoors);
|
||||||
bytes_read += 2;
|
bytes_read += 2;
|
||||||
|
if (car->numDoors > 2) {
|
||||||
|
WARN << "num-doors: " << car->numDoors << " > 2 ???" << std::endl;
|
||||||
|
car->numDoors = 0;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i=0; i < car->numDoors; i++) {
|
for (int i=0; i < car->numDoors; i++) {
|
||||||
PHYSFS_readSLE16(fd, &car->door[i].rpx);
|
PHYSFS_readSLE16(fd, &car->door[i].rpx);
|
||||||
|
138
read_ini.cpp
138
read_ini.cpp
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This file contains code derived from information copyrighted by *
|
* This file contains code derived from information copyrighted by *
|
||||||
* DMA Design. It may not be used in a commercial product. *
|
* DMA Design. It may not be used in a commercial product. *
|
||||||
@ -9,31 +9,19 @@
|
|||||||
* This notice may not be removed or altered. *
|
* This notice may not be removed or altered. *
|
||||||
************************************************************************/
|
************************************************************************/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <string>
|
#include "log.h"
|
||||||
#include <map>
|
#include "read_ini.h"
|
||||||
#include <stdlib.h>
|
|
||||||
#include <physfs.h>
|
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
|
|
||||||
class ScriptParser {
|
ScriptParser::ScriptParser(const std::string &file) : section_info(""), section_vars("") {
|
||||||
public:
|
|
||||||
ScriptParser(const std::string &file);
|
|
||||||
~ScriptParser();
|
|
||||||
void loadLevel(PHYSFS_uint32 level);
|
|
||||||
private:
|
|
||||||
typedef std::map<PHYSFS_uint32, PHYSFS_sint64> LevelMapType;
|
|
||||||
LevelMapType levels;
|
|
||||||
PHYSFS_file* fd;
|
|
||||||
};
|
|
||||||
|
|
||||||
ScriptParser::ScriptParser(const std::string &file) {
|
|
||||||
fd = PHYSFS_openRead(file.c_str());
|
fd = PHYSFS_openRead(file.c_str());
|
||||||
if (!fd) {
|
if (!fd) {
|
||||||
std::cerr << "Error: could not open file " << file << " for reading!" << std::endl;
|
std::cerr << "Error: could not open file " << file << " for reading!" << std::endl;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::cout << "* Loading script " << file << " ... ";
|
std::cout << "* Loading script " << file << " ... ";
|
||||||
|
/*
|
||||||
unsigned char v;
|
unsigned char v;
|
||||||
unsigned char m = 0;
|
unsigned char m = 0;
|
||||||
char buffer[10];
|
char buffer[10];
|
||||||
@ -50,15 +38,67 @@ namespace OpenGTA {
|
|||||||
*b = 0x00;
|
*b = 0x00;
|
||||||
b = reinterpret_cast<char*>(&buffer);
|
b = reinterpret_cast<char*>(&buffer);
|
||||||
levels[static_cast<PHYSFS_uint32>(atoi(buffer))] = PHYSFS_tell(fd) + 1;
|
levels[static_cast<PHYSFS_uint32>(atoi(buffer))] = PHYSFS_tell(fd) + 1;
|
||||||
|
std::cout << buffer << " " << PHYSFS_tell(fd) + 1 << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (v == '[') {
|
if (v == '[') {
|
||||||
m = 1;
|
m = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
std::cout << int(levels.size()) << " sections indexed" << std::endl;
|
*/
|
||||||
|
const size_t buflen = 1024;
|
||||||
|
char buffer[buflen+1];
|
||||||
|
char numbuf[10];
|
||||||
|
PHYSFS_sint64 fd_off = 0;
|
||||||
|
while(!PHYSFS_eof(fd)) {
|
||||||
|
memset(buffer, 0, buflen+1);
|
||||||
|
PHYSFS_sint64 fd_off_add = PHYSFS_read(fd, static_cast<void*>(buffer), 1, buflen);
|
||||||
|
|
||||||
|
char * buf_ptr = buffer;
|
||||||
|
while (buf_ptr) {
|
||||||
|
char * found_str = strchr(buf_ptr, '[');
|
||||||
|
char * found_str_end = strchr(buf_ptr, ']');
|
||||||
|
if (found_str && found_str_end) {
|
||||||
|
memset(numbuf, 0, 10);
|
||||||
|
strncpy(numbuf, found_str + 1, found_str_end - found_str - 1);
|
||||||
|
//std::cout << numbuf << ": " << fd_off + found_str_end - buf_ptr + 2 << std::endl;
|
||||||
|
levels[static_cast<PHYSFS_uint32>(atoi(numbuf))] = fd_off + found_str_end - buf_ptr + 2;
|
||||||
|
}
|
||||||
|
if ((found_str) && (!found_str_end)) {
|
||||||
|
PHYSFS_seek(fd, PHYSFS_tell(fd) - 10);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (found_str)
|
||||||
|
buf_ptr = found_str + 1;
|
||||||
|
else
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
fd_off += fd_off_add;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
std::cout << int(levels.size()) << " sections indexed" << std::endl;
|
||||||
}
|
}
|
||||||
|
/*
|
||||||
|
* * Loading script MISSION.INI ... 1 4
|
||||||
|
2 84961
|
||||||
|
1001 195409
|
||||||
|
1002 224532
|
||||||
|
1003 256339
|
||||||
|
1004 288768
|
||||||
|
102 323745
|
||||||
|
103 446555
|
||||||
|
1101 568117
|
||||||
|
1102 607842
|
||||||
|
1103 648562
|
||||||
|
1104 690150
|
||||||
|
202 732582
|
||||||
|
203 910588
|
||||||
|
1201 1107740
|
||||||
|
1202 1147497
|
||||||
|
1203 1188235
|
||||||
|
1204 1229847
|
||||||
|
18 sections indexed
|
||||||
|
*/
|
||||||
|
|
||||||
ScriptParser::~ScriptParser() {
|
ScriptParser::~ScriptParser() {
|
||||||
if (fd != NULL)
|
if (fd != NULL)
|
||||||
@ -66,26 +106,65 @@ namespace OpenGTA {
|
|||||||
levels.clear();
|
levels.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
PHYSFS_sint64 ScriptParser::sectionEndOffset(PHYSFS_sint64 start) {
|
||||||
|
PHYSFS_sint64 offset = PHYSFS_fileLength(fd);
|
||||||
|
LevelMapType::iterator i = levels.begin();
|
||||||
|
while (i != levels.end()) {
|
||||||
|
if (i->second > start)
|
||||||
|
if (i->second < offset)
|
||||||
|
offset = i->second;
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return offset;
|
||||||
|
}
|
||||||
|
|
||||||
void ScriptParser::loadLevel(PHYSFS_uint32 level) {
|
void ScriptParser::loadLevel(PHYSFS_uint32 level) {
|
||||||
LevelMapType::iterator i = levels.find(level);
|
LevelMapType::iterator i = levels.find(level);
|
||||||
if (i == levels.end()) {
|
if (i == levels.end()) {
|
||||||
std::cerr << "not a valid level: " << level << std::endl;
|
std::cerr << "not a valid level: " << level << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
PHYSFS_sint64 end_of_section = sectionEndOffset(i->second);
|
||||||
PHYSFS_seek(fd, i->second);
|
PHYSFS_seek(fd, i->second);
|
||||||
char buffer[256];
|
|
||||||
|
const size_t buf_len = 255; // +1
|
||||||
|
char buffer[buf_len+1];
|
||||||
PHYSFS_uint16 read_bytes = 255;
|
PHYSFS_uint16 read_bytes = 255;
|
||||||
PHYSFS_uint16 offset = 0;
|
PHYSFS_uint16 offset = 0;
|
||||||
while(!PHYSFS_eof(fd)) {
|
size_t num_lines_read = 0;
|
||||||
|
bool first_part_of_section = true;
|
||||||
|
while(PHYSFS_tell(fd) < end_of_section) {
|
||||||
memset(buffer+offset, 0, read_bytes+1);
|
memset(buffer+offset, 0, read_bytes+1);
|
||||||
PHYSFS_read(fd, buffer + offset, 1, read_bytes);
|
PHYSFS_read(fd, buffer + offset, 1, read_bytes);
|
||||||
char* line_start = buffer;
|
char* line_start = buffer;
|
||||||
while (1) {
|
while (1) {
|
||||||
char* line_end = strchr(line_start, '\r');
|
char* line_end = strchr(line_start, '\r');
|
||||||
if (line_start && line_end) {
|
if (line_start && line_end) {
|
||||||
|
if (*(line_end - 1) == ' ')
|
||||||
|
line_end--;
|
||||||
*line_end = 0;
|
*line_end = 0;
|
||||||
|
while (*line_start == '\n' || *line_start == '\r' || *line_start == ' ')
|
||||||
|
line_start++;
|
||||||
if (strlen(line_start) > 0) {
|
if (strlen(line_start) > 0) {
|
||||||
std::cout <<"["<< line_start << "]" << strlen(line_start)<<std::endl;
|
//std::cout <<"["<< line_start << "]" << strlen(line_start)<<std::endl;
|
||||||
|
if (num_lines_read == 0)
|
||||||
|
//std::cout << "level: " << line_start << std::endl;
|
||||||
|
section_info = line_start;
|
||||||
|
else if (num_lines_read == 1)
|
||||||
|
//std::cout << "vars: " << line_start << std::endl;
|
||||||
|
section_vars = line_start;
|
||||||
|
else {
|
||||||
|
if (strncmp(line_start, "-1", 2) == 0)
|
||||||
|
first_part_of_section = false;
|
||||||
|
else {
|
||||||
|
if (first_part_of_section)
|
||||||
|
acceptDefinition(line_start);
|
||||||
|
else
|
||||||
|
acceptCommand(line_start);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
++num_lines_read;
|
||||||
}
|
}
|
||||||
line_start = line_end + 1;
|
line_start = line_end + 1;
|
||||||
if (*line_start == '\n')
|
if (*line_start == '\n')
|
||||||
@ -94,16 +173,25 @@ namespace OpenGTA {
|
|||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
typedef unsigned int uint32;
|
|
||||||
//std::cout << uint32(line_start) - uint32(buffer) << std::endl;
|
//std::cout << uint32(line_start) - uint32(buffer) << std::endl;
|
||||||
PHYSFS_uint32 begin_rest = PHYSFS_uint32(line_start) - PHYSFS_uint32(buffer);
|
PHYSFS_uint32 begin_rest = PHYSFS_uint32(line_start) - PHYSFS_uint32(buffer);
|
||||||
offset = 255 - begin_rest;
|
offset = buf_len - begin_rest;
|
||||||
memmove(buffer, &buffer[begin_rest], 255 - begin_rest);
|
memmove(buffer, &buffer[begin_rest], buf_len - begin_rest);
|
||||||
read_bytes = 255 - offset;
|
read_bytes = buf_len - offset;
|
||||||
|
if (PHYSFS_tell(fd) + read_bytes > end_of_section)
|
||||||
|
read_bytes = end_of_section - PHYSFS_tell(fd);
|
||||||
//std::cout << buffer << std::endl;
|
//std::cout << buffer << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ScriptParser::acceptDefinition(const char* str) {
|
||||||
|
INFO << "def: " << str << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ScriptParser::acceptCommand(const char* str) {
|
||||||
|
INFO << "cmd: " << str << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
28
read_ini.h
Normal file
28
read_ini.h
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef READ_INI_H
|
||||||
|
#define READ_INI_H
|
||||||
|
#include <string>
|
||||||
|
#include <map>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <physfs.h>
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
|
||||||
|
class ScriptParser {
|
||||||
|
public:
|
||||||
|
ScriptParser(const std::string &file);
|
||||||
|
virtual ~ScriptParser();
|
||||||
|
void loadLevel(PHYSFS_uint32 level);
|
||||||
|
private:
|
||||||
|
typedef std::map<PHYSFS_uint32, PHYSFS_sint64> LevelMapType;
|
||||||
|
LevelMapType levels;
|
||||||
|
PHYSFS_file* fd;
|
||||||
|
PHYSFS_sint64 sectionEndOffset(PHYSFS_sint64 start);
|
||||||
|
protected:
|
||||||
|
std::string section_info;
|
||||||
|
std::string section_vars;
|
||||||
|
virtual void acceptDefinition(const char*);
|
||||||
|
virtual void acceptCommand(const char*);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
35
readme.txt
35
readme.txt
@ -24,6 +24,11 @@ Just run 'make' or specifically 'make viewer'.
|
|||||||
|
|
||||||
The other programs are/were used for development or debugging.
|
The other programs are/were used for development or debugging.
|
||||||
|
|
||||||
|
The distributed win32 binaries are created with a cross-compiler.
|
||||||
|
|
||||||
|
The file doc/compiling.txt in the source code release contains
|
||||||
|
information on the build process.
|
||||||
|
|
||||||
= Installing the data-files =
|
= Installing the data-files =
|
||||||
|
|
||||||
You can download the game from http://www.rockstargames.com/classics/ .
|
You can download the game from http://www.rockstargames.com/classics/ .
|
||||||
@ -40,6 +45,13 @@ Needed:
|
|||||||
STYLE*.GRY (for 8-bit graphics)
|
STYLE*.GRY (for 8-bit graphics)
|
||||||
STYLE*.G24 (for 24-bit graphics)
|
STYLE*.G24 (for 24-bit graphics)
|
||||||
|
|
||||||
|
Will be needed (in the future):
|
||||||
|
MISSION.INI
|
||||||
|
*.RAT ( 8 bit menu graphics)
|
||||||
|
*.RAW (24 bit menu graphics)
|
||||||
|
AUDIO/*.RAW AUDIO/*.SDT (sound effects)
|
||||||
|
AUDIO/*.WAV (cutscene text; in legacy format)
|
||||||
|
|
||||||
= Running =
|
= Running =
|
||||||
|
|
||||||
== gfxextract ==
|
== gfxextract ==
|
||||||
@ -61,6 +73,13 @@ The optional param loads the respective city; default is 0:
|
|||||||
2 - MIAMI.CMP
|
2 - MIAMI.CMP
|
||||||
|
|
||||||
flags are:
|
flags are:
|
||||||
|
|
||||||
|
-V show version and compile time switches
|
||||||
|
-h show usage
|
||||||
|
|
||||||
|
( The compiled-in usage information is more recent than the
|
||||||
|
following. )
|
||||||
|
|
||||||
* screen dimensions (have to specify neither or both)
|
* screen dimensions (have to specify neither or both)
|
||||||
-w width
|
-w width
|
||||||
-h height
|
-h height
|
||||||
@ -92,17 +111,15 @@ furthermore:
|
|||||||
f : toggle fullscreen/windowed
|
f : toggle fullscreen/windowed
|
||||||
PRINT : save 'screenshot.bmp' in current directory
|
PRINT : save 'screenshot.bmp' in current directory
|
||||||
p : dump coords (in lua syntax) to stdout
|
p : dump coords (in lua syntax) to stdout
|
||||||
i,j,k,l : move player-char
|
|
||||||
F2 : toggle drawing of sprite bounding-boxes
|
F2 : toggle drawing of sprite bounding-boxes
|
||||||
F3 : toggle marking of sprite tex-border-boxes
|
F3 : toggle marking of sprite tex-border-boxes
|
||||||
F4 : toggle free-move vs. follow-player
|
F4 : toggle free-move vs. follow-player
|
||||||
F5 : toggle drawing of road heading arrows
|
F5 : toggle drawing of road heading arrows (& normals)
|
||||||
F6 : city map mode (ESC to exit, +, -, cursor keys)
|
F6 : city map mode (ESC to exit, +, -, cursor keys)
|
||||||
1 - 8 : choose a specific player-sprite animation
|
F9 : toggle city blocks drawn textured
|
||||||
9, 0 : set the player-sprite to a specific frame
|
F10 : toggle blocks wireframe lines
|
||||||
|
|
||||||
in 3d view:
|
in 3d view:
|
||||||
F1 : demo-flight over the city
|
|
||||||
w : forward
|
w : forward
|
||||||
s : backward
|
s : backward
|
||||||
space : stop
|
space : stop
|
||||||
@ -112,6 +129,14 @@ in 3d view:
|
|||||||
You can move the view with the mouse; when you switch
|
You can move the view with the mouse; when you switch
|
||||||
to 3d and the screen is black: move the mouse down.
|
to 3d and the screen is black: move the mouse down.
|
||||||
|
|
||||||
|
in follow-player mode:
|
||||||
|
i,j,k,l : move player-char
|
||||||
|
l-shift : toggle walking/running
|
||||||
|
0 : unselect weapon / unarmed
|
||||||
|
1,2,3,4 : select weapon (only switches graphic)
|
||||||
|
F7 : draw explosion at player pos (graphical effect)
|
||||||
|
F8 : create random-walker ped at player-pos
|
||||||
|
|
||||||
== luaviewer: viewer + Lua (optional target) ==
|
== luaviewer: viewer + Lua (optional target) ==
|
||||||
|
|
||||||
Also needs Lua (only 5.1 tried) in path; run: 'make luaviewer'
|
Also needs Lua (only 5.1 tried) in path; run: 'make luaviewer'
|
||||||
|
205
release_files_sorted
Normal file
205
release_files_sorted
Normal file
@ -0,0 +1,205 @@
|
|||||||
|
ogta/blockanim.cpp
|
||||||
|
ogta/blockanim.h
|
||||||
|
ogta/blockdata.cpp
|
||||||
|
ogta/blockdata.h
|
||||||
|
ogta/bugs.rec
|
||||||
|
ogta/coldet/box_bld.cpp
|
||||||
|
ogta/coldet/box.cpp
|
||||||
|
ogta/coldet/box.h
|
||||||
|
ogta/coldet/coldet_bld.cpp
|
||||||
|
ogta/coldet/coldet.cpp
|
||||||
|
ogta/coldet/coldet.dsp
|
||||||
|
ogta/coldet/coldet.h
|
||||||
|
ogta/coldet/coldetimpl.h
|
||||||
|
ogta/coldet/makefile.g++
|
||||||
|
ogta/coldet/math3d.cpp
|
||||||
|
ogta/coldet/math3d.h
|
||||||
|
ogta/coldet/mytritri.cpp
|
||||||
|
ogta/coldet/mytritri.h
|
||||||
|
ogta/coldet/quickstart.html
|
||||||
|
ogta/coldet/readme.txt
|
||||||
|
ogta/coldet/sysdep.cpp
|
||||||
|
ogta/coldet/sysdep.h
|
||||||
|
ogta/coldet/transform.txt
|
||||||
|
ogta/coldet/tritri.c
|
||||||
|
ogta/common_sdl_gl.cpp
|
||||||
|
ogta/common_sdl_gl.h
|
||||||
|
ogta/datahelper.cpp
|
||||||
|
ogta/datahelper.h
|
||||||
|
ogta/dataholder.cpp
|
||||||
|
ogta/dataholder.h
|
||||||
|
ogta/doc/doc_links.txt
|
||||||
|
ogta/doc/gouranga.txt
|
||||||
|
ogta/doc/gta1_winex.txt
|
||||||
|
ogta/doc/hacking.txt
|
||||||
|
ogta/doc/more_hints_delfi.txt
|
||||||
|
ogta/doc/more_info.txt
|
||||||
|
ogta/doc/slopes1.txt
|
||||||
|
ogta/Doxyfile
|
||||||
|
ogta/entity_controller.cpp
|
||||||
|
ogta/entity_controller.h
|
||||||
|
ogta/font_cache.cpp
|
||||||
|
ogta/font_cache.h
|
||||||
|
ogta/fx_sdt.h
|
||||||
|
ogta/game_objects.cpp
|
||||||
|
ogta/game_objects.h
|
||||||
|
ogta/gfx_extract.cpp
|
||||||
|
ogta/gl_base.cpp
|
||||||
|
ogta/gl_base.h
|
||||||
|
ogta/gl_camera.cpp
|
||||||
|
ogta/gl_camera.h
|
||||||
|
ogta/gl_cityview.cpp
|
||||||
|
ogta/gl_cityview.h
|
||||||
|
ogta/gl_font.cpp
|
||||||
|
ogta/gl_font.h
|
||||||
|
ogta/gl_frustum.cpp
|
||||||
|
ogta/gl_frustum.h
|
||||||
|
ogta/gl_pagedtexture.h
|
||||||
|
ogta/gl_screen.cpp
|
||||||
|
ogta/gl_screen.h
|
||||||
|
ogta/gl_spritecache.cpp
|
||||||
|
ogta/gl_spritecache.h
|
||||||
|
ogta/gl_texturecache.cpp
|
||||||
|
ogta/gl_texturecache.h
|
||||||
|
ogta/id_sys.cpp
|
||||||
|
ogta/id_sys.h
|
||||||
|
ogta/licenses/LGPL-2.1.gz
|
||||||
|
ogta/licenses/LGPL-2.gz
|
||||||
|
ogta/licenses/mit.txt
|
||||||
|
ogta/licenses/readme.txt
|
||||||
|
ogta/licenses/zlib.txt
|
||||||
|
ogta/license.txt
|
||||||
|
ogta/lid_normal_data.h
|
||||||
|
ogta/localplayer.h
|
||||||
|
ogta/loki.make
|
||||||
|
ogta/loki.make.w32_cross
|
||||||
|
ogta/lua_addon/lua_camera.cpp
|
||||||
|
ogta/lua_addon/lua_camera.h
|
||||||
|
ogta/lua_addon/lua_cityview.cpp
|
||||||
|
ogta/lua_addon/lua_cityview.h
|
||||||
|
ogta/lua_addon/lua.hpp
|
||||||
|
ogta/lua_addon/lua_ini_bridge.cpp
|
||||||
|
ogta/lua_addon/lua_ini_bridge.h
|
||||||
|
ogta/lua_addon/lua_screen.cpp
|
||||||
|
ogta/lua_addon/lua_screen.h
|
||||||
|
ogta/lua_addon/lua_spritecache.cpp
|
||||||
|
ogta/lua_addon/lua_spritecache.h
|
||||||
|
ogta/lua_addon/lua_stackguard.cpp
|
||||||
|
ogta/lua_addon/lua_stackguard.h
|
||||||
|
ogta/lua_addon/lua_vm.cpp
|
||||||
|
ogta/lua_addon/lua_vm.h
|
||||||
|
ogta/lua_addon/lunar.h
|
||||||
|
ogta/main2.cpp
|
||||||
|
ogta/main.cpp
|
||||||
|
ogta/makefile
|
||||||
|
ogta/math/basis.hpp
|
||||||
|
ogta/math/coord_frame.hpp
|
||||||
|
ogta/math/interpolate.hpp
|
||||||
|
ogta/math/makefile
|
||||||
|
ogta/math/matrix.hpp
|
||||||
|
ogta/math/obb.cpp
|
||||||
|
ogta/math/obb.hpp
|
||||||
|
ogta/math/obox.cpp
|
||||||
|
ogta/math/obox.h
|
||||||
|
ogta/math/quaternion.h
|
||||||
|
ogta/math/rectangle.hpp
|
||||||
|
ogta/math/vector.hpp
|
||||||
|
ogta/math/weighted_set.cpp
|
||||||
|
ogta/math/weighted_set.h
|
||||||
|
ogta/navdata.cpp
|
||||||
|
ogta/navdata.h
|
||||||
|
ogta/ogta_version
|
||||||
|
ogta/opengta.h
|
||||||
|
ogta/opensteer/COPYING.OPENSTEER
|
||||||
|
ogta/opensteer/include/OpenSteer/Clock.h
|
||||||
|
ogta/opensteer/include/OpenSteer/lq.h
|
||||||
|
ogta/opensteer/include/OpenSteer/Proximity.h
|
||||||
|
ogta/opensteer/include/OpenSteer/Utilities.h
|
||||||
|
ogta/opensteer/include/OpenSteer/Vec3.h
|
||||||
|
ogta/opensteer/include/OpenSteer/Vec3Utilities.h
|
||||||
|
ogta/opensteer/ogta_opensteer.txt
|
||||||
|
ogta/opensteer/src/Clock.cpp
|
||||||
|
ogta/opensteer/src/lq.c
|
||||||
|
ogta/opensteer/src/Vec3.cpp
|
||||||
|
ogta/opensteer/src/Vec3Utilities.cpp
|
||||||
|
ogta/prepare_build.sh
|
||||||
|
ogta/read_cmp.cpp
|
||||||
|
ogta/read_fnt.cpp
|
||||||
|
ogta/read_fxt.cpp
|
||||||
|
ogta/read_g24.cpp
|
||||||
|
ogta/read_gry.cpp
|
||||||
|
ogta/read_ini.cpp
|
||||||
|
ogta/read_ini.h
|
||||||
|
ogta/readme.txt
|
||||||
|
ogta/read_sdt.cpp
|
||||||
|
ogta/release_files_sorted
|
||||||
|
ogta/scripts/demo1.lua
|
||||||
|
ogta/scripts/demo2.lua
|
||||||
|
ogta/scripts/demo3.lua
|
||||||
|
ogta/slope1_data.h
|
||||||
|
ogta/slope1_tcoords.h
|
||||||
|
ogta/slope_height_func.cpp
|
||||||
|
ogta/sprite_anim_player.cpp
|
||||||
|
ogta/spritemanager.cpp
|
||||||
|
ogta/spritemanager.h
|
||||||
|
ogta/tests/interpolate_test.cpp
|
||||||
|
ogta/tests/menudemo.cpp
|
||||||
|
ogta/tests/new_obj_test.cpp
|
||||||
|
ogta/tests/sound_test1.cpp
|
||||||
|
ogta/tools/analyse_lids_2.c
|
||||||
|
ogta/tools/analyse_lids.c
|
||||||
|
ogta/tools/blockview.cpp
|
||||||
|
ogta/tools/create_normals.cpp
|
||||||
|
ogta/tools/display_font.cpp
|
||||||
|
ogta/tools/display_slopes.cpp
|
||||||
|
ogta/tools/doxy_doc.sh
|
||||||
|
ogta/tools/gen_texcoords.c
|
||||||
|
ogta/tools/insert_copyright.sh
|
||||||
|
ogta/tools/mapinfo.cpp
|
||||||
|
ogta/tools/minimap.cpp
|
||||||
|
ogta/tools/obj_dump.cpp
|
||||||
|
ogta/tools/replace_in_files.sh
|
||||||
|
ogta/tools/resort_quads.c
|
||||||
|
ogta/tools/slope_conv.awk
|
||||||
|
ogta/tools/slope_exchange.sh
|
||||||
|
ogta/tools/style_demo.sh
|
||||||
|
ogta/train_system.cpp
|
||||||
|
ogta/train_system.h
|
||||||
|
ogta/util/abstract_container.h
|
||||||
|
ogta/util/animation.cpp
|
||||||
|
ogta/util/animation.h
|
||||||
|
ogta/util/buffercache.cpp
|
||||||
|
ogta/util/buffercache.h
|
||||||
|
ogta/util/cell_iterator.cpp
|
||||||
|
ogta/util/cell_iterator.h
|
||||||
|
ogta/util/cistring.h
|
||||||
|
ogta/util/file_helper.cpp
|
||||||
|
ogta/util/file_helper.h
|
||||||
|
ogta/util/gui.h
|
||||||
|
ogta/util/image_loader.cpp
|
||||||
|
ogta/util/image_loader.h
|
||||||
|
ogta/util/log.cpp
|
||||||
|
ogta/util/log.h
|
||||||
|
ogta/util/map_helper.cpp
|
||||||
|
ogta/util/map_helper.h
|
||||||
|
ogta/util/m_exceptions.cpp
|
||||||
|
ogta/util/m_exceptions.h
|
||||||
|
ogta/util/physfsrwops.c
|
||||||
|
ogta/util/physfsrwops.h
|
||||||
|
ogta/util/sample_cache.h
|
||||||
|
ogta/util/set.cpp
|
||||||
|
ogta/util/set.h
|
||||||
|
ogta/util/sound_device.cpp
|
||||||
|
ogta/util/sound_device.h
|
||||||
|
ogta/util/sound_fx_cache.cpp
|
||||||
|
ogta/util/sound_fx_cache.h
|
||||||
|
ogta/util/sound_mixer.h
|
||||||
|
ogta/util/sound_music_player.cpp
|
||||||
|
ogta/util/sound_music_player.h
|
||||||
|
ogta/util/sound_resample2.cpp
|
||||||
|
ogta/util/sound_resample2.h
|
||||||
|
ogta/util/sound_system.cpp
|
||||||
|
ogta/util/sound_system.h
|
||||||
|
ogta/util/timer.cpp
|
||||||
|
ogta/util/timer.h
|
||||||
|
ogta/viewer.cpp
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <SDL_opengl.h>
|
#include <SDL_opengl.h>
|
||||||
@ -29,13 +51,17 @@ int bbox_toggle = 0;
|
|||||||
int texsprite_toggle = 0;
|
int texsprite_toggle = 0;
|
||||||
|
|
||||||
int spr_type = (int)ped.sprType;
|
int spr_type = (int)ped.sprType;
|
||||||
|
namespace OpenGTA {
|
||||||
|
void ai_step_fake(OpenGTA::Pedestrian*) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void on_exit() {
|
void on_exit() {
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
PHYSFS_deinit();
|
PHYSFS_deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void run_init() {
|
void run_init(const char*) {
|
||||||
PHYSFS_init("mapview");
|
PHYSFS_init("mapview");
|
||||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||||
@ -106,7 +132,7 @@ void drawScene(Uint32 ticks) {
|
|||||||
if (play_anim) {
|
if (play_anim) {
|
||||||
pedAnim.firstFrameOffset = now_frame;
|
pedAnim.firstFrameOffset = now_frame;
|
||||||
}
|
}
|
||||||
OpenGTA::SpriteManagerHolder::Instance().drawPed(ped);
|
OpenGTA::SpriteManagerHolder::Instance().draw(ped);
|
||||||
|
|
||||||
OpenGL::ScreenHolder::Instance().setFlatProjection();
|
OpenGL::ScreenHolder::Instance().setFlatProjection();
|
||||||
|
|
||||||
@ -188,7 +214,7 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
|||||||
}
|
}
|
||||||
if (update_anim) {
|
if (update_anim) {
|
||||||
pedAnim.firstFrameOffset = frame_offset;
|
pedAnim.firstFrameOffset = frame_offset;
|
||||||
ped.setAnimation(pedAnim);
|
ped.anim = pedAnim;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
File diff suppressed because it is too large
Load Diff
109
spritemanager.h
109
spritemanager.h
@ -1,5 +1,5 @@
|
|||||||
/************************************************************************
|
/************************************************************************
|
||||||
* Copyright (c) 2005-2006 tok@openlinux.org.uk *
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
* *
|
* *
|
||||||
* This software is provided as-is, without any express or implied *
|
* This software is provided as-is, without any express or implied *
|
||||||
* warranty. In no event will the authors be held liable for any *
|
* warranty. In no event will the authors be held liable for any *
|
||||||
@ -25,10 +25,16 @@
|
|||||||
|
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <map>
|
#include <map>
|
||||||
#include "pedestrian.h"
|
#include "abstract_container.h"
|
||||||
|
//#include "pedestrian.h"
|
||||||
|
#include "game_objects.h"
|
||||||
#include "Singleton.h"
|
#include "Singleton.h"
|
||||||
|
#include "train_system.h"
|
||||||
|
#include "map_helper.h"
|
||||||
|
|
||||||
namespace OpenGTA {
|
namespace OpenGTA {
|
||||||
|
|
||||||
|
#if 0
|
||||||
class SpriteManager {
|
class SpriteManager {
|
||||||
public:
|
public:
|
||||||
SpriteManager();
|
SpriteManager();
|
||||||
@ -62,11 +68,17 @@ namespace OpenGTA {
|
|||||||
void drawPed(Pedestrian & ped);
|
void drawPed(Pedestrian & ped);
|
||||||
void drawCar(Car & car);
|
void drawCar(Car & car);
|
||||||
void drawObject(GameObject & obj);
|
void drawObject(GameObject & obj);
|
||||||
|
void drawExplosion(GameObject & obj);
|
||||||
|
|
||||||
|
void drawTrain(TrainSegment & train);
|
||||||
|
TrainSegment & getTrainById(const Uint32 & id);
|
||||||
|
|
||||||
void createProjectile(uint8_t typeId, float, Vector3D p, Vector3D d, Uint32 & ticks);
|
void createProjectile(uint8_t typeId, float, Vector3D p, Vector3D d, Uint32 & ticks);
|
||||||
|
void createExplosion(Vector3D center);
|
||||||
void drawProjectile(Projectile & p);
|
void drawProjectile(Projectile & p);
|
||||||
void collideProjectile(Projectile & p);
|
void collideProjectile(Projectile & p);
|
||||||
|
|
||||||
|
typedef std::list<TrainSegment> TrainListType;
|
||||||
protected:
|
protected:
|
||||||
typedef std::list<Pedestrian> PedListType;
|
typedef std::list<Pedestrian> PedListType;
|
||||||
PedListType activePeds;
|
PedListType activePeds;
|
||||||
@ -76,14 +88,105 @@ namespace OpenGTA {
|
|||||||
ObjectListType activeObjects;
|
ObjectListType activeObjects;
|
||||||
typedef std::list<Projectile> ProjectileListType;
|
typedef std::list<Projectile> ProjectileListType;
|
||||||
ProjectileListType activeProjectiles;
|
ProjectileListType activeProjectiles;
|
||||||
|
TrainListType activeTrains;
|
||||||
|
public:
|
||||||
|
TrainSystem trainSystem;
|
||||||
|
protected:
|
||||||
typedef std::map<Uint32, SpriteObject::Animation> AnimLookupType;
|
typedef std::map<Uint32, SpriteObject::Animation> AnimLookupType;
|
||||||
AnimLookupType animations;
|
AnimLookupType animations;
|
||||||
private:
|
private:
|
||||||
Uint32 drawMode;
|
Uint32 drawMode;
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
class SpriteManager :
|
||||||
|
public AbstractContainer<Pedestrian>,
|
||||||
|
public AbstractContainer<Car>,
|
||||||
|
public AbstractContainer<SpriteObject> { //,
|
||||||
|
//public AbstractContainer<TrainSegment> {
|
||||||
|
public:
|
||||||
|
|
||||||
|
~SpriteManager();
|
||||||
|
void drawInRect(SDL_Rect & r);
|
||||||
|
void clear();
|
||||||
|
void removeDeadStuff();
|
||||||
|
|
||||||
|
template <typename T> T & add(const T & t) {
|
||||||
|
return AbstractContainer<T>::doAdd(t);
|
||||||
|
}
|
||||||
|
template <typename T> size_t getNum() {
|
||||||
|
return AbstractContainer<T>::objs.size();
|
||||||
|
}
|
||||||
|
inline Pedestrian & getPed(uint32_t id) {
|
||||||
|
return AbstractContainer<Pedestrian>::doGet(id);
|
||||||
|
}
|
||||||
|
inline Car & getCar(uint32_t id) {
|
||||||
|
return AbstractContainer<Car>::doGet(id);
|
||||||
|
}
|
||||||
|
inline SpriteObject & getObject(uint32_t id) {
|
||||||
|
return AbstractContainer<SpriteObject>::doGet(id);
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
inline TrainSegment & getTrain(uint32_t id) {
|
||||||
|
return AbstractContainer<TrainSegment>::doGet(id);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
template <typename T> inline std::list<T> & getList() {
|
||||||
|
return AbstractContainer<T>::objs;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void removePed(uint32_t id) {
|
||||||
|
AbstractContainer<Pedestrian>::doRemove(id);
|
||||||
|
}
|
||||||
|
inline void removeCar(uint32_t id) {
|
||||||
|
AbstractContainer<Car>::doRemove(id);
|
||||||
|
}
|
||||||
|
void realRemove();
|
||||||
|
|
||||||
|
inline bool getDrawTexture() { return (drawMode & 1); }
|
||||||
|
inline bool getDrawTexBorder() { return (drawMode & 2); }
|
||||||
|
inline bool getDrawBBox() { return (drawMode & 4); }
|
||||||
|
void setDrawTexture(bool v);
|
||||||
|
void setDrawTexBorder(bool v);
|
||||||
|
void setDrawBBox(bool v);
|
||||||
|
void drawBBoxOutline(const OBox &);
|
||||||
|
void drawTextureOutline(const float &, const float &);
|
||||||
|
|
||||||
|
void draw(Car &);
|
||||||
|
void draw(Pedestrian &);
|
||||||
|
void draw(SpriteObject &);
|
||||||
|
void draw(Projectile &);
|
||||||
|
|
||||||
|
void drawExplosion(SpriteObject &);
|
||||||
|
|
||||||
|
void update(Uint32 ticks);
|
||||||
|
|
||||||
|
SpriteObject::Animation & getAnimationById(const Uint32 & id);
|
||||||
|
void registerAnimation(const Uint32 & id, const SpriteObject::Animation & anim);
|
||||||
|
|
||||||
|
void createExplosion(Vector3D center);
|
||||||
|
void createProjectile(uint8_t typeId, float, Vector3D p, Vector3D d, Uint32 & ticks, Uint32 & owner);
|
||||||
|
|
||||||
|
|
||||||
|
public:
|
||||||
|
//TrainSystem trainSystem;
|
||||||
|
SpriteManager();
|
||||||
|
Util::SpriteCreationArea creationArea;
|
||||||
|
protected:
|
||||||
|
typedef std::map<Uint32, SpriteObject::Animation> AnimLookupType;
|
||||||
|
AnimLookupType animations;
|
||||||
|
typedef std::list<Projectile> ProjectileListType;
|
||||||
|
ProjectileListType activeProjectiles;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Uint32 drawMode;
|
||||||
|
|
||||||
|
//SpriteManager(const SpriteManager & o) : trainSystem(AbstractContainer<TrainSegment>::objs) {assert(0);}
|
||||||
|
SpriteManager(const SpriteManager & o) {assert(0);}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
typedef Loki::SingletonHolder<SpriteManager, Loki::CreateUsingNew,
|
typedef Loki::SingletonHolder<SpriteManager, Loki::CreateUsingNew,
|
||||||
Loki::DefaultLifetime, Loki::SingleThreaded> SpriteManagerHolder;
|
Loki::DefaultLifetime, Loki::SingleThreaded> SpriteManagerHolder;
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
160
tests/interpolate_test.cpp
Normal file
160
tests/interpolate_test.cpp
Normal file
@ -0,0 +1,160 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <getopt.h>
|
||||||
|
#include "interpolate.hpp"
|
||||||
|
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
void run_linear(int numSteps) {
|
||||||
|
float y1, y2;
|
||||||
|
cin >> y1;
|
||||||
|
cin >> y2;
|
||||||
|
Math::Interpolator::Linear<float> li(y1, y2);
|
||||||
|
int counter = 0;
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << li.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
while (cin >> y2) {
|
||||||
|
li.shiftAndFeed(y2);
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << li.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_cubic(int numSteps) {
|
||||||
|
float y1, y2, y3;
|
||||||
|
|
||||||
|
cin >> y1;
|
||||||
|
cin >> y2;
|
||||||
|
cin >> y3;
|
||||||
|
Math::Interpolator::Cubic<float> ci(y1, y2, y3);
|
||||||
|
int counter = 0;
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << ci.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
while (cin >> y3) {
|
||||||
|
ci.shiftAndFeed(y3);
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << ci.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ci.shift();
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << ci.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_cosine(int numSteps) {
|
||||||
|
float y1, y2;
|
||||||
|
|
||||||
|
cin >> y1;
|
||||||
|
cin >> y2;
|
||||||
|
|
||||||
|
Math::Interpolator::Cosine<float> ci(y1, y2);
|
||||||
|
int counter = 0;
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << ci.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
while (cin >> y2) {
|
||||||
|
ci.shiftAndFeed(y2);
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << ci.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_hermite(int numSteps, float tension, float bias) {
|
||||||
|
float y1, y2, y3;
|
||||||
|
|
||||||
|
cin >> y1;
|
||||||
|
cin >> y2;
|
||||||
|
cin >> y3;
|
||||||
|
Math::Interpolator::Hermite<float> hi(y1, y2, y3, tension, bias);
|
||||||
|
int counter = 0;
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << hi.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
while (cin >> y3) {
|
||||||
|
hi.shiftAndFeed(y3);
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << hi.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hi.shift();
|
||||||
|
for (int i = 0; i < numSteps; ++i) {
|
||||||
|
cout << counter << " " << hi.getAt(float(i) / numSteps) << endl;
|
||||||
|
++counter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
int numSteps = 10;
|
||||||
|
int run = 2;
|
||||||
|
|
||||||
|
float hermite_bias = 1.0f;
|
||||||
|
float hermite_tension = 1.0f;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int option_index = 0;
|
||||||
|
static struct option long_options[] = {
|
||||||
|
{"linear", 0, 0, 'l'},
|
||||||
|
{"cosine", 0, 0, 'o'},
|
||||||
|
{"cubic", 0, 0, 'c'},
|
||||||
|
{"hermite", 0, 0, 'h'},
|
||||||
|
{"steps", 1, 0, 's'},
|
||||||
|
{0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
int c = getopt_long (argc, argv, "h",
|
||||||
|
long_options, &option_index);
|
||||||
|
if (c == -1)
|
||||||
|
break;
|
||||||
|
switch (c) {
|
||||||
|
case 's':
|
||||||
|
numSteps = atoi(optarg);
|
||||||
|
break;
|
||||||
|
case 'o':
|
||||||
|
run = 1;
|
||||||
|
break;
|
||||||
|
case 'c':
|
||||||
|
run = 2;
|
||||||
|
break;
|
||||||
|
case 'l':
|
||||||
|
run = 0;
|
||||||
|
break;
|
||||||
|
case 'h':
|
||||||
|
run = 3;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
exit(1);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
switch(run) {
|
||||||
|
case 2:
|
||||||
|
run_cubic(numSteps);
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
run_cosine(numSteps);
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
run_linear(numSteps);
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
run_hermite(numSteps, hermite_tension, hermite_bias);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
542
tests/menudemo.cpp
Normal file
542
tests/menudemo.cpp
Normal file
@ -0,0 +1,542 @@
|
|||||||
|
#include <iostream>
|
||||||
|
#include <sstream>
|
||||||
|
#include <SDL_image.h>
|
||||||
|
#include <SDL_opengl.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <physfs.h>
|
||||||
|
#include "gl_screen.h"
|
||||||
|
#include "gl_pagedtexture.h"
|
||||||
|
#include "log.h"
|
||||||
|
#include "buffercache.h"
|
||||||
|
#include "physfsrwops.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "timer.h"
|
||||||
|
#include "dataholder.h"
|
||||||
|
#include "gl_spritecache.h"
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
|
||||||
|
extern int global_EC;
|
||||||
|
extern int global_Done;
|
||||||
|
|
||||||
|
Uint32 arg_screen_w = 800;
|
||||||
|
Uint32 arg_screen_h = 600;
|
||||||
|
|
||||||
|
namespace GUI {
|
||||||
|
Object::Object(const SDL_Rect & r) :
|
||||||
|
id(0), rect(), color(),
|
||||||
|
manager(ManagerHolder::Instance()) {
|
||||||
|
copyRect(r);
|
||||||
|
color.r = 255; color.g = 255; color.b = 255; color.unused = 255;
|
||||||
|
}
|
||||||
|
Object::Object(const size_t Id, const SDL_Rect & r) :
|
||||||
|
id(Id), rect(), color(),
|
||||||
|
manager(ManagerHolder::Instance()) {
|
||||||
|
copyRect(r);
|
||||||
|
color.r = 255; color.g = 255; color.b = 255; color.unused = 255;
|
||||||
|
}
|
||||||
|
Object::Object(const size_t Id, const SDL_Rect & r, const SDL_Color & c) :
|
||||||
|
id(Id), rect(), color(),
|
||||||
|
manager(ManagerHolder::Instance()) {
|
||||||
|
copyRect(r);
|
||||||
|
copyColor(c);
|
||||||
|
}
|
||||||
|
void Object::draw() {
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||||
|
glVertex2i(rect.x, rect.y + rect.h);
|
||||||
|
glEnd();
|
||||||
|
}
|
||||||
|
void Object::copyRect(const SDL_Rect & src) {
|
||||||
|
rect.x = src.x;
|
||||||
|
rect.y = src.y;
|
||||||
|
rect.w = src.w;
|
||||||
|
rect.h = src.h;
|
||||||
|
}
|
||||||
|
void Object::copyColor(const SDL_Color & src) {
|
||||||
|
color.r = src.r;
|
||||||
|
color.g = src.g;
|
||||||
|
color.b = src.b;
|
||||||
|
color.unused = src.unused;
|
||||||
|
}
|
||||||
|
|
||||||
|
void TexturedObject::draw() {
|
||||||
|
|
||||||
|
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x, rect.y + rect.h);
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AnimatedTextureObject::draw() {
|
||||||
|
if (!animation)
|
||||||
|
animation = manager.findAnimation(animId);
|
||||||
|
|
||||||
|
assert(animation);
|
||||||
|
size_t texId = animation->getCurrentFrame();
|
||||||
|
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x, rect.y + rect.h);
|
||||||
|
glEnd();
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Label::draw() {
|
||||||
|
glPushMatrix();
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glTranslatef(rect.x, rect.y, 0);
|
||||||
|
rect.w = uint16_t(font->drawString(text));
|
||||||
|
rect.h = font->getHeight();
|
||||||
|
glPopMatrix();
|
||||||
|
/*
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
glBegin(GL_LINE_STRIP);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||||
|
glVertex2i(rect.x, rect.y + rect.h);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glEnd();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pager::draw() {
|
||||||
|
|
||||||
|
const OpenGL::PagedTexture & tex = manager.getCachedImage(texId);
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glEnable(GL_TEXTURE_2D);
|
||||||
|
glBindTexture(GL_TEXTURE_2D, tex.inPage);
|
||||||
|
glBegin(GL_QUADS);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[1].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y);
|
||||||
|
glTexCoord2f(tex.coords[1].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x + rect.w, rect.y + rect.h);
|
||||||
|
glTexCoord2f(tex.coords[0].u, tex.coords[0].v);
|
||||||
|
glVertex2i(rect.x, rect.y + rect.h);
|
||||||
|
glEnd();
|
||||||
|
glScissor(rect.x, rect.y, rect.w, rect.h);
|
||||||
|
glEnable(GL_SCISSOR_TEST);
|
||||||
|
|
||||||
|
glPushMatrix();
|
||||||
|
glColor4ub(color.r, color.g, color.b, color.unused);
|
||||||
|
glTranslatef(rect.x+offset, rect.y+4, 0);
|
||||||
|
int slen = (int)font->drawString("test - hello world, this is a really long message. it will not end. never... or maybe sometime, but not yet. The end.");
|
||||||
|
if (slen + offset < -10) {
|
||||||
|
color.unused = 0;
|
||||||
|
manager.remove(this);
|
||||||
|
}
|
||||||
|
INFO << slen <<" " << offset << std::endl;
|
||||||
|
glPopMatrix();
|
||||||
|
|
||||||
|
glDisable(GL_SCISSOR_TEST);
|
||||||
|
glDisable(GL_TEXTURE_2D);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void Pager::update(Uint32 ticks) {
|
||||||
|
offset -= 1;
|
||||||
|
|
||||||
|
//if (offset < -50)
|
||||||
|
// color.unused = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::draw() {
|
||||||
|
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||||
|
|
||||||
|
while (layer_it != guiLayers.end()) {
|
||||||
|
GuiObjectList & inThisLayer = layer_it->second;
|
||||||
|
for (GuiObjectList::iterator obj_it = inThisLayer.begin();
|
||||||
|
obj_it != inThisLayer.end(); ++obj_it) {
|
||||||
|
Object * obj = *obj_it;
|
||||||
|
obj->draw();
|
||||||
|
}
|
||||||
|
++layer_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::~Manager() {
|
||||||
|
clearObjects();
|
||||||
|
clearCache();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::clearObjects() {
|
||||||
|
INFO << "clearing gui objects" << std::endl;
|
||||||
|
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||||
|
while (layer_it != guiLayers.end()) {
|
||||||
|
GuiObjectList & list = layer_it->second;
|
||||||
|
for (GuiObjectList::iterator i = list.begin(); i != list.end(); ++i) {
|
||||||
|
delete *i;
|
||||||
|
}
|
||||||
|
list.clear();
|
||||||
|
++layer_it;
|
||||||
|
}
|
||||||
|
guiLayers.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::clearCache() {
|
||||||
|
INFO << "clearing gui texture cache" << std::endl;
|
||||||
|
for (GuiTextureCache::iterator i = texCache.begin(); i != texCache.end(); ++i) {
|
||||||
|
OpenGL::PagedTexture & p = i->second;
|
||||||
|
glDeleteTextures(1, &p.inPage);
|
||||||
|
}
|
||||||
|
texCache.clear();
|
||||||
|
for (AnimationMap::iterator i = guiAnimations.begin(); i != guiAnimations.end(); ++i) {
|
||||||
|
delete i->second;
|
||||||
|
}
|
||||||
|
guiAnimations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
const OpenGL::PagedTexture & Manager::getCachedImage(size_t Id) {
|
||||||
|
GuiTextureCache::iterator i = findByCacheId(Id);
|
||||||
|
if (i == texCache.end()) {
|
||||||
|
std::ostringstream o;
|
||||||
|
o << "cached texture id " << int(Id);
|
||||||
|
throw E_UNKNOWNKEY(o.str());
|
||||||
|
}
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::GuiTextureCache::iterator Manager::findByCacheId(const size_t & Id) {
|
||||||
|
return texCache.find(Id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Manager::GuiObjectListMap::iterator Manager::findLayer(uint8_t l) {
|
||||||
|
return guiLayers.find(l);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::cacheImageRAW(const std::string & file, size_t k) {
|
||||||
|
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k, ImageUtil::loadImageRAW(file)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::cacheImageRAT(const std::string & file, const std::string & palette, size_t k) {
|
||||||
|
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k,
|
||||||
|
ImageUtil::loadImageRATWithPalette(file, palette)));
|
||||||
|
}
|
||||||
|
|
||||||
|
// FIXME: move stuff to ImageUtil
|
||||||
|
void Manager::cacheImageSDL(const std::string & file, size_t k) {
|
||||||
|
SDL_RWops * rwops = PHYSFSRWOPS_openRead(file.c_str());
|
||||||
|
//SDL_Surface *surface = IMG_Load(file.c_str());
|
||||||
|
SDL_Surface *surface = IMG_Load_RW(rwops, 1);
|
||||||
|
assert(surface);
|
||||||
|
|
||||||
|
ImageUtil::NextPowerOfTwo npot(surface->w, surface->h);
|
||||||
|
uint16_t bpp = surface->format->BytesPerPixel;
|
||||||
|
|
||||||
|
uint8_t * buffer = Util::BufferCacheHolder::Instance().requestBuffer(npot.w * npot.h * bpp);
|
||||||
|
SDL_LockSurface(surface);
|
||||||
|
ImageUtil::copyImage2Image(buffer, (uint8_t*)surface->pixels, surface->pitch, surface->h,
|
||||||
|
npot.w * bpp);
|
||||||
|
SDL_UnlockSurface(surface);
|
||||||
|
|
||||||
|
GLuint texture = ImageUtil::createGLTexture(npot.w, npot.h, (bpp == 4) ? true : false, buffer);
|
||||||
|
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(k,
|
||||||
|
OpenGL::PagedTexture(texture, 0, 0, GLfloat(surface->w)/npot.w, GLfloat(surface->h)/npot.h)));
|
||||||
|
SDL_FreeSurface(surface);
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageUtil::WidthHeightPair Manager::cacheStyleArrowSprite(const size_t id, int remap) {
|
||||||
|
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
||||||
|
PHYSFS_uint16 t = graphics.spriteNumbers.reIndex(id, OpenGTA::GraphicsBase::SpriteNumbers::ARROW);
|
||||||
|
OpenGTA::GraphicsBase::SpriteInfo * info = graphics.getSprite(t);
|
||||||
|
texCache.insert(std::make_pair<size_t, OpenGL::PagedTexture>(
|
||||||
|
id, OpenGL::SpriteCacheHolder::Instance().createSprite(size_t(t), remap, 0, info)
|
||||||
|
));
|
||||||
|
return ImageUtil::WidthHeightPair(info->w, info->h);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::add(Object * obj, uint8_t onLevel) {
|
||||||
|
GuiObjectListMap::iterator l = findLayer(onLevel);
|
||||||
|
if (l == guiLayers.end()) {
|
||||||
|
GuiObjectList list;
|
||||||
|
list.push_back(obj);
|
||||||
|
guiLayers.insert(std::make_pair<uint8_t, GuiObjectList>(onLevel, list));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
GuiObjectList & list = l->second;
|
||||||
|
list.push_back(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::remove(Object * obj) {
|
||||||
|
for (GuiObjectListMap::iterator l = guiLayers.begin(); l != guiLayers.end(); ++l) {
|
||||||
|
GuiObjectList & list = l->second;
|
||||||
|
for (GuiObjectList::iterator m = list.begin(); m != list.end(); ++m) {
|
||||||
|
Object * o = *m;
|
||||||
|
if (o == obj) {
|
||||||
|
delete o;
|
||||||
|
list.erase(m);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
throw E_UNKNOWNKEY("not a managed object-ptr");
|
||||||
|
}
|
||||||
|
|
||||||
|
Object* Manager::findObject(const size_t id) {
|
||||||
|
for (GuiObjectListMap::iterator l = guiLayers.begin(); l != guiLayers.end(); ++l) {
|
||||||
|
GuiObjectList & list = l->second;
|
||||||
|
for (GuiObjectList::iterator m = list.begin(); m != list.end(); ++m) {
|
||||||
|
Object * o = *m;
|
||||||
|
if (o->id == id)
|
||||||
|
return o;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
std::ostringstream o;
|
||||||
|
o << "object by id " << int(id);
|
||||||
|
throw E_UNKNOWNKEY(o.str());
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::removeById(const size_t id) {
|
||||||
|
Object * o = findObject(id);
|
||||||
|
if (o)
|
||||||
|
remove(o);
|
||||||
|
//else
|
||||||
|
// ERROR << "failed to find object " << id << " - cannot remove it" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Manager::isInside(Object & obj, Uint16 x, Uint16 y) const {
|
||||||
|
if ((obj.rect.x <= x) && (x <= obj.rect.x + obj.rect.w) &&
|
||||||
|
(obj.rect.y <= y) && (y <= obj.rect.y + obj.rect.h))
|
||||||
|
return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::receive(SDL_MouseButtonEvent & mb_event) {
|
||||||
|
Uint32 sh = OpenGL::ScreenHolder::Instance().getHeight();
|
||||||
|
GuiObjectListMap::reverse_iterator l = guiLayers.rbegin();
|
||||||
|
while (l != guiLayers.rend()) {
|
||||||
|
std::cout << int(l->first) << std::endl;
|
||||||
|
GuiObjectList & list = l->second;
|
||||||
|
for (GuiObjectList::iterator i = list.begin(); i != list.end(); ++i) {
|
||||||
|
Object * obj = *i;
|
||||||
|
if (isInside(*obj, mb_event.x, sh - mb_event.y)) {
|
||||||
|
std::cout << "mouse inside obj id: " << obj->id << " at " << mb_event.x << "," << mb_event.y << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++l;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::update(uint32_t nowticks) {
|
||||||
|
for (AnimationMap::iterator i = guiAnimations.begin(); i != guiAnimations.end(); ++i) {
|
||||||
|
i->second->update(nowticks);
|
||||||
|
}
|
||||||
|
GuiObjectListMap::iterator layer_it = guiLayers.begin();
|
||||||
|
while (layer_it != guiLayers.end()) {
|
||||||
|
GuiObjectList & inThisLayer = layer_it->second;
|
||||||
|
for (GuiObjectList::iterator obj_it = inThisLayer.begin();
|
||||||
|
obj_it != inThisLayer.end(); ++obj_it) {
|
||||||
|
Object * obj = *obj_it;
|
||||||
|
obj->update(nowticks);
|
||||||
|
}
|
||||||
|
++layer_it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Animation* Manager::findAnimation(uint16_t id) {
|
||||||
|
AnimationMap::iterator i = guiAnimations.find(id);
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Manager::createAnimation(const std::vector<uint16_t> & indices, uint16_t fps, size_t k) {
|
||||||
|
Animation * anim = new Animation(indices, fps);
|
||||||
|
guiAnimations.insert(std::make_pair<size_t, Animation*>(k, anim));
|
||||||
|
anim->set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||||
|
}
|
||||||
|
|
||||||
|
uint16_t Animation::getCurrentFrame() {
|
||||||
|
return indices[getCurrentFrameNumber()];
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef GUI_MENU_DEMO
|
||||||
|
GUI::Manager guiManager;
|
||||||
|
|
||||||
|
void on_exit() {
|
||||||
|
SDL_Quit();
|
||||||
|
PHYSFS_deinit();
|
||||||
|
if (global_EC)
|
||||||
|
std::cerr << "Exiting after fatal problem - please see output above" << std::endl;
|
||||||
|
else
|
||||||
|
std::cout << "Goodbye" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void parse_args(int argc, char* argv[]) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void turn_anim_off(float) {
|
||||||
|
GUI::AnimatedTextureObject * obj= (GUI::AnimatedTextureObject *)guiManager.findObject(2);
|
||||||
|
obj->animation->set(obj->animation->get(), Util::Animation::STOP);
|
||||||
|
INFO << "stopped animation" << std::endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
void font_play(float b) {
|
||||||
|
//INFO << b << std::endl;
|
||||||
|
GUI::Object * obj = guiManager.findObject(5);
|
||||||
|
obj->color.r = obj->color.g = obj->color.b = obj->color.unused = Uint8((1.0f - b) * 255);
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_init() {
|
||||||
|
PHYSFS_init("ogta");
|
||||||
|
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||||
|
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||||
|
if (getenv("OGTA_MOD"))
|
||||||
|
PHYSFS_addToSearchPath(getenv("OGTA_MOD"), 0);
|
||||||
|
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||||
|
screen.activate(arg_screen_w, arg_screen_h);
|
||||||
|
screen.setSystemMouseCursor(true);
|
||||||
|
glEnable(GL_ALPHA_TEST);
|
||||||
|
glAlphaFunc(GL_GREATER, 0);
|
||||||
|
|
||||||
|
OpenGTA::StyleHolder::Instance().load("STYLE001.G24");
|
||||||
|
|
||||||
|
SDL_EnableKeyRepeat( 100, SDL_DEFAULT_REPEAT_INTERVAL );
|
||||||
|
|
||||||
|
std::vector<uint16_t> frame_nums(8);
|
||||||
|
for (int i = 0; i < 8; ++i) {
|
||||||
|
std::stringstream o;
|
||||||
|
o << "F_LOGO" << i << ".RAW";
|
||||||
|
guiManager.cacheImageRAW(o.str(), 100+i);
|
||||||
|
frame_nums[i] = 100+i;
|
||||||
|
}
|
||||||
|
guiManager.createAnimation(frame_nums, 5, 1);
|
||||||
|
|
||||||
|
SDL_Rect r;
|
||||||
|
r.x = 0; r.y = 0; r.h = 312 * screen.getHeight() / 480; r.w = screen.getWidth();
|
||||||
|
std::string rawfile("F_LOWER1.RAW");
|
||||||
|
guiManager.cacheImageRAW(rawfile, 99);
|
||||||
|
GUI::TexturedObject * b2 = new GUI::TexturedObject(1, r, 99);
|
||||||
|
guiManager.add(b2, 2);
|
||||||
|
r.y = 312 * screen.getHeight() / 480;
|
||||||
|
r.h = 168 * screen.getHeight() / 480;
|
||||||
|
GUI::AnimatedTextureObject * b3 = new GUI::AnimatedTextureObject(2, r, 1);
|
||||||
|
guiManager.add(b3, 2);
|
||||||
|
|
||||||
|
Timer & t = TimerHolder::Instance();
|
||||||
|
|
||||||
|
|
||||||
|
ImageUtil::WidthHeightPair whp = guiManager.cacheStyleArrowSprite(16, -1);
|
||||||
|
guiManager.cacheStyleArrowSprite(17, -1);
|
||||||
|
std::vector<uint16_t> anim2frames(2);
|
||||||
|
anim2frames[0] = 16;
|
||||||
|
anim2frames[1] = 17;
|
||||||
|
guiManager.createAnimation(anim2frames, 10, 2);
|
||||||
|
r.x = 200;
|
||||||
|
r.y = 200;
|
||||||
|
r.w = whp.first * 2; r.h = whp.second * 2;
|
||||||
|
GUI::AnimatedTextureObject * b5 = new GUI::AnimatedTextureObject(1, r, 2);
|
||||||
|
guiManager.add(b5, 3);
|
||||||
|
|
||||||
|
whp = guiManager.cacheStyleArrowSprite(2, -1);
|
||||||
|
r.w = whp.first;
|
||||||
|
r.h = whp.second;
|
||||||
|
GUI::Pager * pager = new GUI::Pager(3, r, 2, "STREET1.FON", 1);
|
||||||
|
|
||||||
|
guiManager.add(pager, 5);
|
||||||
|
|
||||||
|
/*Timer::CallbackType cmd(turn_anim_off);
|
||||||
|
t.registerCallback(false, cmd, t.getRealTime() + 2000);
|
||||||
|
|
||||||
|
Timer::CallbackType cmd2(font_play);
|
||||||
|
t.registerCallback(false, cmd2, t.getRealTime() + 100, t.getRealTime() + 3000);
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleKeyPress( SDL_keysym *keysym ) {
|
||||||
|
switch ( keysym->sym ) {
|
||||||
|
case SDLK_ESCAPE:
|
||||||
|
global_Done = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void draw_menu() {
|
||||||
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
|
OpenGL::Screen & screen = OpenGL::ScreenHolder::Instance();
|
||||||
|
screen.setFlatProjection();
|
||||||
|
glDisable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
guiManager.draw();
|
||||||
|
|
||||||
|
|
||||||
|
glEnable(GL_DEPTH_TEST);
|
||||||
|
|
||||||
|
SDL_GL_SwapBuffers();
|
||||||
|
}
|
||||||
|
|
||||||
|
void run_main() {
|
||||||
|
SDL_Event event;
|
||||||
|
Timer & t = TimerHolder::Instance();
|
||||||
|
t.update();
|
||||||
|
//Uint32 now_ticks = SDL_GetTicks();
|
||||||
|
Uint32 now_ticks = t.getRealTime();
|
||||||
|
while(!global_Done && !global_EC) {
|
||||||
|
while (SDL_PollEvent(&event)) {
|
||||||
|
switch(event.type) {
|
||||||
|
case SDL_KEYDOWN:
|
||||||
|
handleKeyPress(&event.key.keysym);
|
||||||
|
break;
|
||||||
|
case SDL_MOUSEBUTTONDOWN:
|
||||||
|
guiManager.receive(event.button);
|
||||||
|
break;
|
||||||
|
/*case SDL_KEYUP:
|
||||||
|
handleKeyUp(&event.key.keysym);
|
||||||
|
break;*/
|
||||||
|
case SDL_VIDEORESIZE:
|
||||||
|
OpenGL::ScreenHolder::Instance().resize(event.resize.w, event.resize.h);
|
||||||
|
break;
|
||||||
|
case SDL_QUIT:
|
||||||
|
global_Done = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
draw_menu();
|
||||||
|
//now_ticks = SDL_GetTicks();
|
||||||
|
t.update();
|
||||||
|
now_ticks = t.getRealTime();
|
||||||
|
guiManager.update(now_ticks);
|
||||||
|
SDL_Delay(20);
|
||||||
|
}
|
||||||
|
// otherwise only at exit, which... troubles loki::smallobject
|
||||||
|
guiManager.clearCache();
|
||||||
|
TimerHolder::Instance().clearAllEvents();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
51
tests/new_obj_test.cpp
Normal file
51
tests/new_obj_test.cpp
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
#include "log.h"
|
||||||
|
#include "game_objects.h"
|
||||||
|
#include "abstract_container.h"
|
||||||
|
|
||||||
|
using namespace OpenGTA;
|
||||||
|
|
||||||
|
class ConcreteContainer :
|
||||||
|
public AbstractContainer<Pedestrian>,
|
||||||
|
public AbstractContainer<Car> {
|
||||||
|
public:
|
||||||
|
template <typename T> void add(const T & t) {
|
||||||
|
AbstractContainer<T>::doAdd(t);
|
||||||
|
}
|
||||||
|
Car & getCar(uint32_t id) {
|
||||||
|
return AbstractContainer<Car>::doGet(id);
|
||||||
|
}
|
||||||
|
Pedestrian & getPed(uint32_t id) {
|
||||||
|
return AbstractContainer<Pedestrian>::doGet(id);
|
||||||
|
}
|
||||||
|
void removeCar(uint32_t id) {
|
||||||
|
AbstractContainer<Car>::doRemove(id);
|
||||||
|
}
|
||||||
|
void removePed(uint32_t id) {
|
||||||
|
AbstractContainer<Pedestrian>::doRemove(id);
|
||||||
|
}
|
||||||
|
void realRemove() {
|
||||||
|
AbstractContainer<Car>::doRealRemove();
|
||||||
|
AbstractContainer<Pedestrian>::doRealRemove();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
Car c1(1);
|
||||||
|
|
||||||
|
Pedestrian p1(20);
|
||||||
|
Car c2(20);
|
||||||
|
|
||||||
|
ConcreteContainer cc;
|
||||||
|
cc.add(p1);
|
||||||
|
cc.add(c1);
|
||||||
|
cc.add(c2);
|
||||||
|
|
||||||
|
Car & c = cc.getCar(1);
|
||||||
|
INFO << c.carId << std::endl;
|
||||||
|
|
||||||
|
Pedestrian & p = cc.getPed(20);
|
||||||
|
cc.removeCar(20);
|
||||||
|
cc.realRemove();
|
||||||
|
c = cc.getCar(20);
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
#include <SDL.h>
|
#include <SDL.h>
|
||||||
|
#define USE_RWOPS
|
||||||
#include <SDL_sound.h>
|
#include <SDL_sound.h>
|
||||||
#include <SDL_mixer.h>
|
#include <SDL_mixer.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
@ -69,7 +70,15 @@ void SoundDevice::open(int r, Uint16 f, int c, int bs) {
|
|||||||
open();
|
open();
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
int music_volume=127;
|
||||||
|
|
||||||
|
bool sound_enabled=false;
|
||||||
|
|
||||||
|
bool playing_music=false;
|
||||||
|
Sound_Sample *music_sound=0;
|
||||||
|
int music_loops=1;
|
||||||
|
int current_music_loop=0;
|
||||||
|
|
||||||
void myMusicPlayer(void *udata, Uint8 *stream, int len) {
|
void myMusicPlayer(void *udata, Uint8 *stream, int len) {
|
||||||
int i,act=0;
|
int i,act=0;
|
||||||
Sint16 *ptr2;
|
Sint16 *ptr2;
|
||||||
@ -123,15 +132,84 @@ void myMusicPlayer(void *udata, Uint8 *stream, int len) {
|
|||||||
for(i=0;i<len;i++) stream[i]=0;
|
for(i=0;i<len;i++) stream[i]=0;
|
||||||
} /* if */
|
} /* if */
|
||||||
} /* myMusicPlayer */
|
} /* myMusicPlayer */
|
||||||
#endif
|
|
||||||
|
|
||||||
#include "fx_sdt.h"
|
#include "fx_sdt.h"
|
||||||
#include "sound_resample.h"
|
#include "sound_resample2.h"
|
||||||
|
|
||||||
|
class AudioChunkCache {
|
||||||
|
public:
|
||||||
|
struct ChunkId {
|
||||||
|
std::string src_file;
|
||||||
|
size_t idx_in_file;
|
||||||
|
ChunkId(const std::string & file, const size_t idx) :
|
||||||
|
src_file(file), idx_in_file(idx) {}
|
||||||
|
bool operator == (const ChunkId & o) const {
|
||||||
|
return (idx_in_file == o.idx_in_file && src_file == o.src_file);
|
||||||
|
}
|
||||||
|
bool operator < (const ChunkId & o) const {
|
||||||
|
if (idx_in_file < o.idx_in_file)
|
||||||
|
return true;
|
||||||
|
if (idx_in_file > o.idx_in_file)
|
||||||
|
return false;
|
||||||
|
return src_file < o.src_file;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
struct ChunkData {
|
||||||
|
Uint8 * mem_buf;
|
||||||
|
Mix_Chunk * chunk;
|
||||||
|
size_t ref;
|
||||||
|
ChunkData(Uint8 * m, Mix_Chunk * c, size_t r = 1) :
|
||||||
|
mem_buf(m), chunk(c), ref(r) {}
|
||||||
|
ChunkData(const ChunkData & o) :
|
||||||
|
mem_buf(o.mem_buf), chunk(o.chunk), ref(o.ref) {}
|
||||||
|
};
|
||||||
|
typedef std::map< ChunkId, ChunkData > CacheType;
|
||||||
|
CacheType cached;
|
||||||
|
ChunkData & getChunk(std::string & file, size_t idx);
|
||||||
|
void prepareDB(std::string db_file);
|
||||||
|
OpenGTA::SoundsDB * getDB(std::string db_file);
|
||||||
|
private:
|
||||||
|
ChunkData loadChunk(std::string & file, size_t idx);
|
||||||
|
typedef std::map< std::string, OpenGTA::SoundsDB* > LookupCache;
|
||||||
|
LookupCache lookup;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
AudioChunkCache::ChunkData & AudioChunkCache::getChunk(std::string & file, size_t idx) {
|
||||||
|
ChunkId id(file, idx);
|
||||||
|
CacheType::iterator i = cached.find(id);
|
||||||
|
if (i == cached.end()) {
|
||||||
|
ChunkData c = loadChunk(file, idx);
|
||||||
|
cached.insert(std::make_pair<ChunkId, ChunkData>(id, c));
|
||||||
|
i = cached.find(id);
|
||||||
|
}
|
||||||
|
return i->second;
|
||||||
|
}
|
||||||
|
|
||||||
|
AudioChunkCache::ChunkData AudioChunkCache::loadChunk(std::string & file, size_t idx) {
|
||||||
|
LookupCache::iterator j = lookup.find(file);
|
||||||
|
if (j == lookup.end()) {
|
||||||
|
prepareDB(file);
|
||||||
|
j = lookup.find(file);
|
||||||
|
}
|
||||||
|
OpenGTA::SoundsDB & db = *j->second;
|
||||||
|
OpenGTA::SoundsDB::Entry & e = db.getEntry(idx);
|
||||||
|
size_t si;
|
||||||
|
unsigned char* mem = db.getBuffered(idx);
|
||||||
|
Uint8 *mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100);
|
||||||
|
Mix_Chunk * music = Mix_QuickLoad_RAW(mem2, si);
|
||||||
|
return ChunkData(mem2, music, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void AudioChunkCache::prepareDB(std::string db) {
|
||||||
|
lookup[db] = new OpenGTA::SoundsDB(db);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
PHYSFS_init(argv[0]);
|
PHYSFS_init(argv[0]);
|
||||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||||
|
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||||
|
|
||||||
Uint32 sdl_init_flags = SDL_INIT_AUDIO | SDL_INIT_VIDEO;
|
Uint32 sdl_init_flags = SDL_INIT_AUDIO | SDL_INIT_VIDEO;
|
||||||
if (SDL_Init(sdl_init_flags) == -1)
|
if (SDL_Init(sdl_init_flags) == -1)
|
||||||
@ -143,11 +221,16 @@ int main(int argc, char *argv[])
|
|||||||
SoundDevice dev;
|
SoundDevice dev;
|
||||||
dev.open();
|
dev.open();
|
||||||
|
|
||||||
|
if (argc == 3) {
|
||||||
|
AudioChunkCache acc;
|
||||||
|
std::string foo(argv[1]);
|
||||||
|
AudioChunkCache::ChunkData & cd = acc.getChunk(foo, atoi(argv[2]));
|
||||||
|
/*
|
||||||
OpenGTA::SoundsDB db(argv[1]);
|
OpenGTA::SoundsDB db(argv[1]);
|
||||||
OpenGTA::SoundsDB::Entry & e = db.getEntry(atoi(argv[2]));
|
OpenGTA::SoundsDB::Entry & e = db.getEntry(atoi(argv[2]));
|
||||||
unsigned char* mem = db.getBuffered(atoi(argv[2]));
|
unsigned char* mem = db.getBuffered(atoi(argv[2]));
|
||||||
size_t si;
|
size_t si;
|
||||||
Uint8 *mem2 = (Uint8*)resample_new(mem, e.rawSize, si, e.sampleRate, 44100);
|
Uint8 *mem2 = (Uint8*)Audio::resample_new(mem, e.rawSize, si, e.sampleRate, 44100);
|
||||||
|
|
||||||
//write(1, mem, e.rawSize+ 36 + 8);
|
//write(1, mem, e.rawSize+ 36 + 8);
|
||||||
|
|
||||||
@ -161,13 +244,40 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
delete [] mem;
|
delete [] mem;
|
||||||
Mix_PlayChannel(0,music,0);
|
Mix_PlayChannel(0,music,0);
|
||||||
|
*/
|
||||||
|
|
||||||
while (Mix_Playing(0)) {
|
Mix_PlayChannel(0, cd.chunk, 0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
/*
|
||||||
|
SDL_RWops * rw = PHYSFSRWOPS_openRead(argv[1]);
|
||||||
|
assert(rw);
|
||||||
|
Mix_Music * music = Mix_LoadMUS_RW(rw);
|
||||||
|
assert(music);
|
||||||
|
Mix_PlayMusic(music, 0);
|
||||||
|
*/
|
||||||
|
Sound_Init();
|
||||||
|
Sound_AudioInfo inf;
|
||||||
|
#define AUDIO_BUFFER 4096
|
||||||
|
inf.format=AUDIO_S16;
|
||||||
|
inf.channels=2;
|
||||||
|
inf.rate=44100;
|
||||||
|
|
||||||
|
SDL_RWops * rw = PHYSFSRWOPS_openRead(argv[1]);
|
||||||
|
|
||||||
|
assert(rw);
|
||||||
|
music_sound = Sound_NewSample(rw, "mp3" ,&inf,AUDIO_BUFFER);
|
||||||
|
assert(music_sound);
|
||||||
|
Mix_HookMusic(myMusicPlayer, 0);
|
||||||
|
playing_music = true;
|
||||||
|
}
|
||||||
|
//while (Mix_Playing(0)) {
|
||||||
|
while (playing_music) {
|
||||||
SDL_Delay(1000);
|
SDL_Delay(1000);
|
||||||
}
|
}
|
||||||
delete [] mem2;
|
//delete [] mem2;
|
||||||
Mix_HaltMusic();
|
Mix_HaltMusic();
|
||||||
Mix_FreeChunk(music);
|
//Mix_FreeChunk(music);
|
||||||
//music = NULL;
|
//music = NULL;
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
return(0);
|
return(0);
|
||||||
|
@ -8,4 +8,5 @@ if [ $# -gt 0 ]; then
|
|||||||
fi
|
fi
|
||||||
sed '1{h; r $1
|
sed '1{h; r $1
|
||||||
D; }
|
D; }
|
||||||
2{x; G; }' $copyright_file $input
|
2{x; G; }' $copyright_file $input >${input}.copy
|
||||||
|
mv ${input}.copy $input
|
||||||
|
@ -62,10 +62,11 @@ int main(int argc, char* argv[]) {
|
|||||||
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
for (int j = 0; j < 256; j++) {
|
for (int j = 0; j < 256; j++) {
|
||||||
PHYSFS_uint16 emptycount = map.getNumBlocksAt(j,i);
|
PHYSFS_uint16 emptycount = map.getNumBlocksAtNew(j,i);
|
||||||
int found_type = 0;
|
int found_type = 0;
|
||||||
for (int c=6-emptycount; c > 0; c--) {
|
//for (int c=6-emptycount; c > 0; c--) {
|
||||||
OpenGTA::Map::BlockInfo* bi = map.getBlockAt(j, i, c);
|
for (int c = 0; c < emptycount ; ++c) {
|
||||||
|
OpenGTA::Map::BlockInfo* bi = map.getBlockAtNew(j, i, c);
|
||||||
/*
|
/*
|
||||||
if (bi->blockType() > 0)
|
if (bi->blockType() > 0)
|
||||||
found_type = bi->blockType();
|
found_type = bi->blockType();
|
||||||
@ -83,10 +84,12 @@ int main(int argc, char* argv[]) {
|
|||||||
if (bi->railEndTurn())
|
if (bi->railEndTurn())
|
||||||
std::cout << " end: " << i << ", " << j << std::endl;
|
std::cout << " end: " << i << ", " << j << std::endl;
|
||||||
*/
|
*/
|
||||||
|
/*
|
||||||
if (bi->blockType() > 0)
|
if (bi->blockType() > 0)
|
||||||
found_type = bi->blockType();
|
found_type = bi->blockType();
|
||||||
if (bi->trafficLights())
|
if (bi->trafficLights())
|
||||||
found_type = 0;
|
found_type = 0;
|
||||||
|
*/
|
||||||
if (bi->railway())
|
if (bi->railway())
|
||||||
found_type = 7;
|
found_type = 7;
|
||||||
}
|
}
|
||||||
|
70
train_system.cpp
Normal file
70
train_system.cpp
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#include "train_system.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
/*
|
||||||
|
using Util::CellIterator;
|
||||||
|
TrainSystem::TrainSystem(std::list<TrainSegment> & list) :
|
||||||
|
stations(),
|
||||||
|
segments(list) {
|
||||||
|
numTrains = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
TrainSystem::~TrainSystem() {
|
||||||
|
stations.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrainSystem::update(Uint32 now_ticks) {
|
||||||
|
}
|
||||||
|
|
||||||
|
void TrainSystem::loadStations(Map & map) {
|
||||||
|
std::list<CellIterator> stationsWithTrain;
|
||||||
|
for (int y = 0; y < 256; ++y) {
|
||||||
|
for (int x = 0; x < 256; ++x) {
|
||||||
|
PHYSFS_uint16 num_blocks = map.getNumBlocksAtNew(x, y);
|
||||||
|
for (int c=0; c < num_blocks; ++c) {
|
||||||
|
OpenGTA::Map::BlockInfo* bi = map.getBlockAtNew(x, y, c);
|
||||||
|
assert(bi);
|
||||||
|
if (bi->railway() && bi->railStation()) {
|
||||||
|
stations.push_back(Util::CellIterator(map, x, y, c));
|
||||||
|
if (bi->railStationTrain())
|
||||||
|
stationsWithTrain.push_back(CellIterator(map, x, y, c));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
INFO << "should create " << stationsWithTrain.size() << " / " << stations.size()
|
||||||
|
<< " trains" << std::endl;
|
||||||
|
while (stationsWithTrain.size() > 0) {
|
||||||
|
CellIterator & i = stationsWithTrain.front();
|
||||||
|
stationsWithTrain.pop_front();
|
||||||
|
INFO << "at " << i.x << " " << i.y << " " << i.z << std::endl;
|
||||||
|
TrainSegment ts(i);
|
||||||
|
ts.trainId = numTrains++;
|
||||||
|
segments.push_back(ts);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
}
|
50
train_system.h
Normal file
50
train_system.h
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#ifndef OGTA_TRAINSYSTEM_H
|
||||||
|
#define OGTA_TRAINSYSTEM_H
|
||||||
|
|
||||||
|
#include "opengta.h"
|
||||||
|
//#include "pedestrian.h"
|
||||||
|
#include "game_objects.h"
|
||||||
|
#include "cell_iterator.h"
|
||||||
|
|
||||||
|
namespace OpenGTA {
|
||||||
|
/*
|
||||||
|
class TrainSystem {
|
||||||
|
public:
|
||||||
|
TrainSystem(std::list<TrainSegment> & list);
|
||||||
|
~TrainSystem();
|
||||||
|
void update(Uint32 now_ticks);
|
||||||
|
void loadStations(Map & map);
|
||||||
|
const size_t getNumStations() const { return stations.size(); }
|
||||||
|
const int getNumTrains() const { return numTrains; }
|
||||||
|
private:
|
||||||
|
int numTrains;
|
||||||
|
std::list<Util::CellIterator> stations;
|
||||||
|
std::list<TrainSegment> & segments;
|
||||||
|
|
||||||
|
};
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
88
util/abstract_container.h
Normal file
88
util/abstract_container.h
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#ifndef ABSTRACT_CONTAINER_H
|
||||||
|
#define ABSTRACT_CONTAINER_H
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <list>
|
||||||
|
#include <sstream>
|
||||||
|
#include "m_exceptions.h"
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
class AbstractContainer {
|
||||||
|
public:
|
||||||
|
T & doGet(uint32_t);
|
||||||
|
void doRemove(uint32_t);
|
||||||
|
inline T & doAdd(const T & t) {
|
||||||
|
objs.push_back(t);
|
||||||
|
return *objs.rbegin();
|
||||||
|
}
|
||||||
|
void doRealRemove();
|
||||||
|
protected:
|
||||||
|
typedef typename std::list<T> Storage_T;
|
||||||
|
Storage_T objs;
|
||||||
|
typedef typename std::list<T>::iterator Storage_T_Iterator;
|
||||||
|
typedef typename std::list< Storage_T_Iterator > Iterator_Storage;
|
||||||
|
Iterator_Storage toBeRemoved;
|
||||||
|
private:
|
||||||
|
Storage_T_Iterator findById(uint32_t & id);
|
||||||
|
};
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void AbstractContainer<T>::doRealRemove() {
|
||||||
|
typename Iterator_Storage::iterator i = toBeRemoved.begin();
|
||||||
|
while (i != toBeRemoved.end()) {
|
||||||
|
typename Iterator_Storage::iterator j = i++;
|
||||||
|
typename Storage_T::iterator ii = *j;
|
||||||
|
// remove the pointed-to object
|
||||||
|
objs.erase(ii);
|
||||||
|
// remove from list of lists
|
||||||
|
toBeRemoved.erase(j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
void AbstractContainer<T>::doRemove(uint32_t id) {
|
||||||
|
typename Storage_T::iterator i = findById(id);
|
||||||
|
toBeRemoved.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
T & AbstractContainer<T>::doGet(uint32_t id) {
|
||||||
|
typename Storage_T::iterator i = findById(id);
|
||||||
|
return *i;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class T>
|
||||||
|
typename std::list<T>::iterator AbstractContainer<T>::findById(uint32_t & id) {
|
||||||
|
typename Storage_T::iterator i;
|
||||||
|
for (i = objs.begin(); i != objs.end(); ++i) {
|
||||||
|
if (i->id() == id)
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
std::ostringstream ostr;
|
||||||
|
ostr << id;
|
||||||
|
throw E_UNKNOWNKEY(ostr.str());
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "animation.h"
|
#include "animation.h"
|
||||||
#include "m_exceptions.h"
|
#include "m_exceptions.h"
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#ifndef UTIL_ANIMATION_H
|
#ifndef UTIL_ANIMATION_H
|
||||||
#define UTIL_ANIMATION_H
|
#define UTIL_ANIMATION_H
|
||||||
#include <vector>
|
#include <vector>
|
||||||
@ -6,7 +28,14 @@
|
|||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
|
|
||||||
class Animation {
|
/** Capsules play-frames-in-sequence logic.
|
||||||
|
*
|
||||||
|
* This class only knows about the number of frames
|
||||||
|
* and the fps; it does have multiple flags that
|
||||||
|
* switch the behaviour whenever the 'last' frame is
|
||||||
|
* finished.
|
||||||
|
*/
|
||||||
|
class Animation {
|
||||||
public:
|
public:
|
||||||
typedef enum {
|
typedef enum {
|
||||||
STOPPED = 0,
|
STOPPED = 0,
|
||||||
@ -23,7 +52,8 @@ namespace Util {
|
|||||||
Animation(const Animation & o);
|
Animation(const Animation & o);
|
||||||
inline const uint16_t & getCurrentFrameNumber() { return currentFrame; }
|
inline const uint16_t & getCurrentFrameNumber() { return currentFrame; }
|
||||||
inline void set(const Status doThis, const OnDone done = STOP) { status = doThis; onDone = done; }
|
inline void set(const Status doThis, const OnDone done = STOP) { status = doThis; onDone = done; }
|
||||||
inline const Status & get() { return status; }
|
inline const Status & get() const { return status; }
|
||||||
|
inline const OnDone & getDone() const { return onDone; }
|
||||||
void jumpToFrame(const uint16_t num, const Status andDo);
|
void jumpToFrame(const uint16_t num, const Status andDo);
|
||||||
void update(const uint32_t & nowTicks);
|
void update(const uint32_t & nowTicks);
|
||||||
typedef Loki::Functor<void> CallbackType;
|
typedef Loki::Functor<void> CallbackType;
|
||||||
|
64
util/cell_iterator.cpp
Normal file
64
util/cell_iterator.cpp
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#include "cell_iterator.h"
|
||||||
|
#include "log.h"
|
||||||
|
|
||||||
|
namespace Util {
|
||||||
|
float distance(const Vector3D & p1, const Vector3D & p2) {
|
||||||
|
float dx = p1.x - p2.x;
|
||||||
|
float dy = p1.y - p2.y;
|
||||||
|
float dz = p1.z - p2.z;
|
||||||
|
return sqrt(dx * dx + dy * dy + dz * dz);
|
||||||
|
}
|
||||||
|
float xz_angle(const Vector3D & from, const Vector3D & to) {
|
||||||
|
Vector3D rel_to(to);
|
||||||
|
rel_to = rel_to - from;
|
||||||
|
double res = atan(rel_to.x / rel_to.z) * 180.0f / M_PI;
|
||||||
|
if (rel_to.z < 0)
|
||||||
|
return 180.0f + res;
|
||||||
|
if (rel_to.z >= 0 && rel_to.x < 0)
|
||||||
|
return 360.0f + res;
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool CellIterator::isValid() const {
|
||||||
|
if (x < 0 || x > 255)
|
||||||
|
return false;
|
||||||
|
if (y < 0 || y > 255)
|
||||||
|
return false;
|
||||||
|
if (z < 0)
|
||||||
|
return false;
|
||||||
|
return (z < mapRef.getNumBlocksAtNew(x, y));
|
||||||
|
}
|
||||||
|
|
||||||
|
OpenGTA::Map::BlockInfo & CellIterator::getBlock() {
|
||||||
|
assert(isValid());
|
||||||
|
return *mapRef.getBlockAtNew(x, y, z);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define IABS(v) ((v > 0) ? v : -v)
|
||||||
|
int CellIterator::distance(const CellIterator & o) const {
|
||||||
|
return (IABS(x - o.x) + IABS(y - o.y) + IABS(z - o.z));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
100
util/cell_iterator.h
Normal file
100
util/cell_iterator.h
Normal file
@ -0,0 +1,100 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
|
#ifndef UTIL_CELLITERATOR_H
|
||||||
|
#define UTIL_CELLITERATOR_H
|
||||||
|
#include <cassert>
|
||||||
|
#include "opengta.h"
|
||||||
|
#include "dataholder.h"
|
||||||
|
#include "math3d.h"
|
||||||
|
#include "SDL_video.h"
|
||||||
|
|
||||||
|
namespace Util {
|
||||||
|
float distance(const Vector3D & p1, const Vector3D & p2);
|
||||||
|
float xz_angle(const Vector3D & from, const Vector3D & to);
|
||||||
|
|
||||||
|
class CellIterator {
|
||||||
|
public:
|
||||||
|
CellIterator(const Vector3D & p) :
|
||||||
|
x(int(floor(p.x))), y(int(floor(p.z))), z(int(floor(p.y))),
|
||||||
|
mapRef(OpenGTA::MapHolder::Instance().get()) {}
|
||||||
|
|
||||||
|
CellIterator(OpenGTA::Map & map, int _x, int _y, int _z) :
|
||||||
|
x(_x), y(_y), z(_z), mapRef(map) {}
|
||||||
|
|
||||||
|
CellIterator(const CellIterator & o) :
|
||||||
|
x(o.x), y(o.y), z(o.z), mapRef(o.mapRef) {}
|
||||||
|
|
||||||
|
bool isValid() const;
|
||||||
|
int distance(const CellIterator & o) const;
|
||||||
|
|
||||||
|
bool operator == (const CellIterator & o) const {
|
||||||
|
return (x == o.x && y == o.y && z == o.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
CellIterator operator = (const CellIterator & o) {
|
||||||
|
mapRef = o.mapRef;
|
||||||
|
x = o.x;
|
||||||
|
y = o.y;
|
||||||
|
z = o.z;
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
CellIterator left() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.x -= 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
CellIterator right() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.x += 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
CellIterator top() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.y += 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
CellIterator bottom() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.y -= 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
CellIterator up() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.z += 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
CellIterator down() const {
|
||||||
|
CellIterator p(*this);
|
||||||
|
p.z -= 1;
|
||||||
|
return p;
|
||||||
|
}
|
||||||
|
int x, y, z;
|
||||||
|
OpenGTA::Map::BlockInfo & getBlock();
|
||||||
|
private:
|
||||||
|
OpenGTA::Map & mapRef;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
@ -1,8 +1,31 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
#include <physfs.h>
|
#include <physfs.h>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include "m_exceptions.h"
|
#include "m_exceptions.h"
|
||||||
#include "file_helper.h"
|
#include "file_helper.h"
|
||||||
|
#include "buffercache.h"
|
||||||
|
|
||||||
#ifndef OGTA_DEFAULT_DATA_PATH
|
#ifndef OGTA_DEFAULT_DATA_PATH
|
||||||
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
||||||
@ -10,12 +33,14 @@
|
|||||||
#ifndef OGTA_DEFAULT_MOD_PATH
|
#ifndef OGTA_DEFAULT_MOD_PATH
|
||||||
#define OGTA_DEFAULT_MOD_PATH ""
|
#define OGTA_DEFAULT_MOD_PATH ""
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef OGTA_DEFAULT_HOME_PATH
|
#ifndef OGTA_DEFAULT_HOME_PATH
|
||||||
#ifdef LINUX
|
//#ifdef LINUX
|
||||||
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getUserDir()
|
//#define OGTA_DEFAULT_HOME_PATH PHYSFS_getUserDir()
|
||||||
#elif WIN32
|
//#elif WIN32
|
||||||
#define OGTA_DEFAULT_HOME_PATH "config"
|
//#define OGTA_DEFAULT_HOME_PATH "config"
|
||||||
#endif
|
//#endif
|
||||||
|
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getBaseDir()
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Util {
|
namespace Util {
|
||||||
@ -83,4 +108,13 @@ namespace Util {
|
|||||||
// take this one instead
|
// take this one instead
|
||||||
return fd;
|
return fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned char* FileHelper::bufferFromVFS(PHYSFS_file *fd) const {
|
||||||
|
assert(fd);
|
||||||
|
unsigned int size = PHYSFS_fileLength(fd);
|
||||||
|
unsigned char* buffer = BufferCacheHolder::Instance().requestBuffer(size+1);
|
||||||
|
size = PHYSFS_read(fd, buffer, 1, size);
|
||||||
|
PHYSFS_close(fd);
|
||||||
|
return buffer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,25 @@
|
|||||||
|
/************************************************************************
|
||||||
|
* Copyright (c) 2005-2007 tok@openlinux.org.uk *
|
||||||
|
* *
|
||||||
|
* This software is provided as-is, without any express or implied *
|
||||||
|
* warranty. In no event will the authors be held liable for any *
|
||||||
|
* damages arising from the use of this software. *
|
||||||
|
* *
|
||||||
|
* Permission is granted to anyone to use this software for any purpose, *
|
||||||
|
* including commercial applications, and to alter it and redistribute *
|
||||||
|
* it freely, subject to the following restrictions: *
|
||||||
|
* *
|
||||||
|
* 1. The origin of this software must not be misrepresented; you must *
|
||||||
|
* not claim that you wrote the original software. If you use this *
|
||||||
|
* software in a product, an acknowledgment in the product documentation *
|
||||||
|
* would be appreciated but is not required. *
|
||||||
|
* *
|
||||||
|
* 2. Altered source versions must be plainly marked as such, and must *
|
||||||
|
* not be misrepresented as being the original software. *
|
||||||
|
* *
|
||||||
|
* 3. This notice may not be removed or altered from any source *
|
||||||
|
* distribution. *
|
||||||
|
************************************************************************/
|
||||||
#ifndef UTIL_FILEHELPER_H
|
#ifndef UTIL_FILEHELPER_H
|
||||||
#define UTIL_FILEHELPER_H
|
#define UTIL_FILEHELPER_H
|
||||||
|
|
||||||
@ -17,6 +39,7 @@ namespace Util {
|
|||||||
bool existsInSystemFS(const std::string & file) const;
|
bool existsInSystemFS(const std::string & file) const;
|
||||||
bool existsInVFS(const std::string & file) const;
|
bool existsInVFS(const std::string & file) const;
|
||||||
PHYSFS_file* openReadVFS(const std::string & file) const;
|
PHYSFS_file* openReadVFS(const std::string & file) const;
|
||||||
|
unsigned char* bufferFromVFS(PHYSFS_file*) const;
|
||||||
private:
|
private:
|
||||||
std::string baseDataPath;
|
std::string baseDataPath;
|
||||||
std::string modDataPath;
|
std::string modDataPath;
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user