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"
|
||||
namespace OpenGTA {
|
||||
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
|
||||
#define OPENGTA_BLOCKDATA
|
||||
#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][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) { return m[i][j]; }
|
||||
void RotZ(float v);
|
||||
};
|
||||
|
||||
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -34,7 +34,8 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
template<> GraphicsBase & ActiveStyle::get() {
|
||||
assert(m_data);
|
||||
if (!m_data)
|
||||
throw E_NOTSUPPORTED("Load a style-file first!");
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
@ -81,7 +82,8 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
template<> Map & ActiveMap::get() {
|
||||
assert(m_data);
|
||||
if (!m_data)
|
||||
throw E_NOTSUPPORTED("Load a map-file first!");
|
||||
return *m_data;
|
||||
}
|
||||
|
||||
@ -97,4 +99,30 @@ namespace OpenGTA {
|
||||
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -28,18 +28,11 @@
|
||||
#include "Singleton.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
/*
|
||||
class ActiveStyle {
|
||||
public:
|
||||
ActiveStyle();
|
||||
~ActiveStyle();
|
||||
GraphicsBase & getStyle();
|
||||
void load(const std::string & file);
|
||||
private:
|
||||
void unload();
|
||||
GraphicsBase* m_style;
|
||||
};
|
||||
*/
|
||||
/** Wrapper around resource-holding classes.
|
||||
* - you have to call 'load' before 'get'
|
||||
*
|
||||
* - you may call load repeatedly
|
||||
*/
|
||||
template <class T>
|
||||
class ActiveData {
|
||||
public:
|
||||
@ -52,13 +45,30 @@ namespace OpenGTA {
|
||||
T* m_data;
|
||||
};
|
||||
|
||||
/** The wrapper around the GRY/G24 data interface.
|
||||
*/
|
||||
typedef ActiveData< GraphicsBase > ActiveStyle;
|
||||
/** The wrapper around the map data interface.
|
||||
*/
|
||||
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,
|
||||
Loki::SingleThreaded> StyleHolder;
|
||||
/** Singleton: Map
|
||||
*/
|
||||
typedef Loki::SingletonHolder< ActiveMap, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||
Loki::SingleThreaded> MapHolder;
|
||||
/** Singleton: Message strings
|
||||
*/
|
||||
typedef Loki::SingletonHolder< MainMsgLookup, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||
Loki::SingleThreaded> MainMsgHolder;
|
||||
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -17,6 +17,7 @@ Corrections and Notes regarding DMA GTA technical doument [cds.doc v12.10]
|
||||
http://www.fifengr.com/gtacars/topic.html
|
||||
|
||||
--- other links ---
|
||||
|
||||
A Stream-based Time Synchronization Technique For Networked Computer Games
|
||||
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.
|
||||
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:
|
||||
- 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
|
||||
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
|
||||
each of the of the possible blocks; this corresponds to
|
||||
#OpenGTA::Map::BlockInfo::slopeType.
|
||||
|
||||
Drawing of objects (sprites) is being moved into #OpenGTA::SpriteManager,
|
||||
though this is not yet complete.
|
||||
Drawing of objects (sprites) is done in #OpenGTA::SpriteManager.
|
||||
|
||||
#OpenGL::DrawableFont can display strings using the bitmaps from
|
||||
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"
|
||||
|
||||
namespace OpenGTA {
|
||||
@ -5,6 +27,10 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
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,
|
||||
|
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
|
||||
#define FONT_CACHE_H
|
||||
#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 *
|
||||
* 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 *
|
||||
* 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 *
|
||||
* distribution. *
|
||||
************************************************************************/
|
||||
#include "pedestrian.h"
|
||||
#include "game_objects.h"
|
||||
#include "spritemanager.h"
|
||||
#include "opengta.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);
|
||||
|
||||
namespace OpenGTA {
|
||||
Projectile::Projectile(uint8_t id, float r, Vector3D p, Vector3D d, Uint32 now) :
|
||||
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 GameObject_common::heightOverTerrain(const Vector3D & v) {
|
||||
float x, y, z;
|
||||
x = floor(v.x);
|
||||
y = floor(v.y);
|
||||
@ -102,9 +43,18 @@ namespace OpenGTA {
|
||||
x_b = (PHYSFS_uint8)x;
|
||||
z_b = (PHYSFS_uint8)z;
|
||||
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;
|
||||
}
|
||||
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();
|
||||
while (y >= map.getNumBlocksAtNew(x_b, z_b) && y > 0.0f)
|
||||
y -= 1.0f;
|
||||
@ -135,72 +85,181 @@ namespace OpenGTA {
|
||||
return 1.0f;
|
||||
}
|
||||
|
||||
Pedestrian::Pedestrian(const Vector3D & e,
|
||||
const Vector3D & p) : SpriteObject(p),
|
||||
OBox(RollMatrix3D(0), e * 0.5f) {
|
||||
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;
|
||||
Sprite::Animation::Animation() :
|
||||
Util::Animation(7, 7),
|
||||
firstFrameOffset(0), moveSpeed(0.0f) {}
|
||||
|
||||
Sprite::Animation::Animation(const Animation & other) :
|
||||
//Util::Animation(other.numFrames, 1000 / other.delay),
|
||||
Util::Animation(other),
|
||||
firstFrameOffset(other.firstFrameOffset),
|
||||
//numFrames(other.numFrames),
|
||||
moveSpeed(other.moveSpeed) {
|
||||
set(other.get(), other.getDone());
|
||||
}
|
||||
|
||||
Pedestrian::Pedestrian(const Vector3D & e,
|
||||
const Vector3D & p, const Uint32 & asId) : SpriteObject(p),
|
||||
OBox(RollMatrix3D(0), e * 0.5f) {
|
||||
m_M.Translate(p);
|
||||
pedId = asId;
|
||||
m_control = 0;
|
||||
animId = 0;
|
||||
inGroundContact = 0;
|
||||
sprType = GraphicsBase::SpriteNumbers::PED;
|
||||
activeWeapon = 0;
|
||||
speedForces = Vector3D(0, 0, 0);
|
||||
weaponReloadedAt = 0;
|
||||
Sprite::Animation::Animation(Uint16 foff, Uint8 num) :
|
||||
Util::Animation(num, 7),
|
||||
firstFrameOffset(foff), moveSpeed(0.0f) {}
|
||||
|
||||
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) {
|
||||
}
|
||||
|
||||
Pedestrian::Pedestrian(const Pedestrian & other) : SpriteObject(other),
|
||||
OBox(other.m_M, other.m_Extent) {
|
||||
//animRef(SpriteManagerHolder::Instance().getAnimationById(other.animId)) {
|
||||
copyValues(other);
|
||||
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 Pedestrian::switchToAnim(const Uint32 & newId) {
|
||||
void Sprite::switchToAnim(const Uint32 & newId) {
|
||||
INFO << "switching to anim " << newId << std::endl;
|
||||
anim = Animation(SpriteManagerHolder::Instance().getAnimationById(newId));
|
||||
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||
animId = newId;
|
||||
//curFrame = 0;
|
||||
}
|
||||
|
||||
void SpriteObject::setAnimation(Animation & otherAnim) {
|
||||
anim = Animation(otherAnim);
|
||||
//curFrame = 0;
|
||||
// FIXME: animId?
|
||||
Pedestrian::Pedestrian(Vector3D e, const Vector3D & p, uint32_t id, Sint16 remapId) :
|
||||
GameObject_common(p),
|
||||
Sprite(0, remapId, GraphicsBase::SpriteNumbers::PED),
|
||||
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;
|
||||
}
|
||||
|
||||
void Pedestrian::copyValues(const Pedestrian & other) {
|
||||
Pedestrian::Pedestrian(const Pedestrian & other) :
|
||||
GameObject_common(other), Sprite(other), OBox(other),
|
||||
|
||||
m_control = other.m_control;
|
||||
animId = other.animId;
|
||||
pedId = other.pedId;
|
||||
pedId(other.pedId),
|
||||
m_control(),
|
||||
speedForces(other.speedForces) {
|
||||
lastUpdateAt = other.lastUpdateAt;
|
||||
inGroundContact = other.inGroundContact;
|
||||
sprType = other.sprType;
|
||||
speedForces = other.speedForces;
|
||||
activeWeapon = other.activeWeapon;
|
||||
inventory = other.inventory;
|
||||
weaponReloadedAt = other.weaponReloadedAt;
|
||||
animId = other.animId;
|
||||
isDead = other.isDead;
|
||||
m_M = TranslateMatrix3D(other.pos);
|
||||
m_M.RotZ(other.rot);
|
||||
}
|
||||
|
||||
void Pedestrian::giveItem(uint8_t id, uint32_t amount) {
|
||||
InventoryType::iterator i = inventory.find(id);
|
||||
if (i == inventory.end())
|
||||
inventory[id] = amount;
|
||||
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
|
||||
i->second += amount;
|
||||
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::tryMove(Vector3D nPos) {
|
||||
@ -212,7 +271,7 @@ namespace OpenGTA {
|
||||
OpenGTA::GraphicsBase & graphics = OpenGTA::StyleHolder::Instance().get();
|
||||
//INFO << heightOverTerrain(nPos) << std::endl;
|
||||
float hot = heightOverTerrain(nPos);
|
||||
if (hot > 0.3f)
|
||||
if (hot > 0.1f)
|
||||
inGroundContact = 0;
|
||||
else if (hot < 0.0) {
|
||||
INFO << "gone below: " << hot << " at " << nPos.x << ", " << nPos.y << ", " << nPos.z << std::endl;
|
||||
@ -222,6 +281,10 @@ namespace OpenGTA {
|
||||
}
|
||||
else {
|
||||
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) {
|
||||
//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;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "xblock left: " << x - pos.x << " tex: " << int(block->left) << std::endl;
|
||||
#endif
|
||||
if (x - pos.x > 0 && x - pos.x < 0.2f)
|
||||
nPos.x = pos.x;
|
||||
else if (x - pos.x < 0 && x - pos.x > -0.2f)
|
||||
@ -267,7 +332,9 @@ namespace OpenGTA {
|
||||
}
|
||||
}
|
||||
if (block->right && block->isFlat() == false) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
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) {
|
||||
nPos.x = pos.x;
|
||||
}
|
||||
@ -276,14 +343,18 @@ namespace OpenGTA {
|
||||
}
|
||||
if (block->top && graphics.isBlockingSide(block->top)) { // && block->isFlat() == false) {
|
||||
if (block->isFlat()) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top) << std::endl;
|
||||
#endif
|
||||
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
||||
nPos.z = pos.z;
|
||||
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
||||
nPos.z = (nPos.z < pos.z) ? pos.z : nPos.z;
|
||||
}
|
||||
else {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "zblock top: " << z - pos.z << " tex: " << int(block->top)<< std::endl;
|
||||
#endif
|
||||
if (z - pos.z > 0 && z - pos.z < 0.2f)
|
||||
nPos.z = pos.z;
|
||||
else if (z - pos.z < 0 && z - pos.z > -0.2f)
|
||||
@ -291,7 +362,9 @@ namespace OpenGTA {
|
||||
}
|
||||
}
|
||||
if (block->bottom && block->isFlat() == false) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
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) {
|
||||
nPos.z = pos.z;
|
||||
}
|
||||
@ -301,7 +374,9 @@ namespace OpenGTA {
|
||||
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));
|
||||
if (block->right && block->isFlat() == false) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "xblock right: " << pos.x - x << " tex: " << int(block->right)<< std::endl;
|
||||
#endif
|
||||
if (pos.x - x < 0.2f) {
|
||||
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))) {
|
||||
block = map.getBlockAtNew(PHYSFS_uint8(x+1), PHYSFS_uint8(z), PHYSFS_uint8(y));
|
||||
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;
|
||||
#endif
|
||||
if (block->isFlat()) {
|
||||
if (x + 1 - pos.x > 0 && x + 1 - pos.x < 0.2f)
|
||||
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))) {
|
||||
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z-1), PHYSFS_uint8(y));
|
||||
if (block->bottom && block->isFlat() == false) {
|
||||
#ifdef DEBUG_OLD_PED_BLOCK
|
||||
INFO << "zblock bottom: " << pos.z - z<< " tex: " << int(block->bottom)<< std::endl;
|
||||
#endif
|
||||
if (pos.z - z < 0.2f) {
|
||||
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))) {
|
||||
block = map.getBlockAtNew(PHYSFS_uint8(x), PHYSFS_uint8(z+1), PHYSFS_uint8(y));
|
||||
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;
|
||||
#endif
|
||||
if (block->isFlat()) {
|
||||
if (z + 1 - pos.z > 0 && z + 1 - pos.z < 0.2f)
|
||||
nPos.z = (nPos.z < pos.z ? nPos.z : pos.z);
|
||||
@ -354,162 +435,152 @@ namespace OpenGTA {
|
||||
|
||||
}
|
||||
|
||||
void Pedestrian::equip(uint8_t id) {
|
||||
if (id == 0) {
|
||||
activeWeapon = 0;
|
||||
}
|
||||
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::die() {
|
||||
INFO << "DIE!!!" << std::endl;
|
||||
switchToAnim(42);
|
||||
}
|
||||
|
||||
void Pedestrian::fireWeapon(Uint32 ticks) {
|
||||
if (activeWeapon == 0)
|
||||
return; // FIXME: punching!
|
||||
InventoryType::iterator i = inventory.find(activeWeapon);
|
||||
if (i->second == 0)
|
||||
return; // no ammo
|
||||
if (ticks < weaponReloadedAt)
|
||||
return;
|
||||
|
||||
weaponReloadedAt = ticks + 2000;
|
||||
OpenGTA::SpriteManagerHolder::Instance().createProjectile(i->first, rot, pos, Vector3D(0.2f, 0, 0.2f), ticks);
|
||||
|
||||
void Pedestrian::getShot(bool front) {
|
||||
isDead = 1;
|
||||
switchToAnim(45);
|
||||
anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::FCALLBACK);
|
||||
Loki::Functor<void> cmd(this, &Pedestrian::die);
|
||||
anim.setCallback(cmd);
|
||||
}
|
||||
|
||||
void Pedestrian::update(Uint32 ticks) {
|
||||
// update the animation
|
||||
if (m_control) {
|
||||
switch(m_control->move) {
|
||||
case 1:
|
||||
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)) {
|
||||
Car::Car(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::CAR), OBox(),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(op.type)){
|
||||
carId = id;
|
||||
type = op.type;
|
||||
sprType = GraphicsBase::SpriteNumbers::CAR;
|
||||
sprNum = c_info.sprNum;
|
||||
m_Extent = Vector3D(INT2F_DIV128(c_info.width),
|
||||
INT2F_DIV128(c_info.depth),
|
||||
INT2F_DIV128(c_info.height));
|
||||
m_M.Translate(pos);
|
||||
sprNum = carInfo.sprNum;
|
||||
m_Extent = Vector3D(INT2F_DIV128(carInfo.width),
|
||||
INT2F_DIV128(carInfo.depth),
|
||||
INT2F_DIV128(carInfo.height));
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
|
||||
rot = op.rotation * 360 / 1024;
|
||||
}
|
||||
|
||||
Car::Car(const Car & other) : SpriteObject(other),
|
||||
OBox(other.m_M, other.m_Extent),
|
||||
c_info(*StyleHolder::Instance().get().findCarByModel(other.type)) {
|
||||
copyValues(other);
|
||||
}
|
||||
|
||||
void Car::copyValues(const Car & other) {
|
||||
sprType = other.sprType;
|
||||
delta = other.delta;
|
||||
carId = other.carId;
|
||||
Car::Car(const Car & other) :
|
||||
GameObject_common(other), Sprite(other), OBox(other),
|
||||
carInfo(*StyleHolder::Instance().get().findCarByModel(other.type)) {
|
||||
type = other.type;
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
|
||||
carId = other.carId;
|
||||
}
|
||||
|
||||
GameObject::GameObject(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()) {
|
||||
sprType = GraphicsBase::SpriteNumbers::OBJECT;
|
||||
void Car::update(Uint32 ticks) {
|
||||
}
|
||||
|
||||
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();
|
||||
sprNum = style.objectInfos[op.type]->sprNum;
|
||||
m_Extent = Vector3D(INT2F_DIV128(style.objectInfos[op.type]->width),
|
||||
INT2F_DIV128(style.objectInfos[op.type]->depth),
|
||||
INT2F_DIV128(style.objectInfos[op.type]->height));
|
||||
m_M.Translate(pos);
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
rot = op.rotation * 360 / 1024;
|
||||
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
GameObject::GameObject(const GameObject & other) : SpriteObject(other),
|
||||
OBox(other.m_M, other.m_Extent) {
|
||||
copyValues(other);
|
||||
SpriteObject::SpriteObject(Vector3D pos, Uint16 sprNum, OpenGTA::GraphicsBase::SpriteNumbers::SpriteTypes sprT) :
|
||||
GameObject_common(pos), Sprite(sprNum, -1, sprT), OBox() {
|
||||
isActive = true;
|
||||
m_M = TranslateMatrix3D(pos);
|
||||
m_M.RotZ(rot);
|
||||
}
|
||||
|
||||
void GameObject::copyValues(const GameObject & other) {
|
||||
sprType = other.sprType;
|
||||
SpriteObject::SpriteObject(const SpriteObject & other) :
|
||||
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -197,15 +197,15 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
switch(section) {
|
||||
case 0:
|
||||
graphics.getSide(idx, remap, rgba);
|
||||
graphics.getSide(idx, 0, rgba);
|
||||
image = get_image(graphics.getTmpBuffer(rgba), 64,64);
|
||||
break;
|
||||
case 1:
|
||||
graphics.getLid(idx, remap, rgba);
|
||||
graphics.getLid(idx, 0, rgba);
|
||||
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
||||
break;
|
||||
case 2:
|
||||
graphics.getAux(idx, remap, rgba);
|
||||
graphics.getAux(idx, 0, rgba);
|
||||
image = get_image(graphics.getTmpBuffer(rgba), 64, 64);
|
||||
break;
|
||||
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 *
|
||||
* 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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
|
@ -26,7 +26,18 @@ namespace OpenGL {
|
||||
void Camera::update_game(Uint32 ticks) {
|
||||
Vector3D delta(center - *followTarget);
|
||||
//INFO << delta.x << ", " << delta.y << ", " << delta.z << std::endl;
|
||||
float height_dist = fabs(delta.y);
|
||||
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;
|
||||
eye += -delta;
|
||||
gluLookAt(eye.x, eye.y, eye.z, center.x, center.y, center.z,
|
||||
|
178
gl_cityview.cpp
178
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -34,6 +34,7 @@
|
||||
#include "gl_screen.h"
|
||||
#include "blockdata.h"
|
||||
#include "image_loader.h"
|
||||
#include "blockanim.h"
|
||||
|
||||
float slope_height_offset(unsigned char slope_type, float dx, float dz);
|
||||
namespace OpenGTA {
|
||||
@ -84,6 +85,8 @@ namespace OpenGTA {
|
||||
loadedMap = NULL;
|
||||
sideCache = NULL;
|
||||
lidCache = NULL;
|
||||
auxCache = NULL;
|
||||
blockAnims = NULL;
|
||||
camVec[0] = 0.0f;
|
||||
camVec[1] = 1.0f;
|
||||
camVec[2] = 0.0f;
|
||||
@ -105,6 +108,7 @@ namespace OpenGTA {
|
||||
void CityView::resetTextures() {
|
||||
sideCache->clearAll();
|
||||
lidCache->clearAll();
|
||||
auxCache->clearAll();
|
||||
}
|
||||
void CityView::setVisibleRange(int r) {
|
||||
visibleRange = r;
|
||||
@ -124,6 +128,10 @@ namespace OpenGTA {
|
||||
delete sideCache;
|
||||
if (lidCache)
|
||||
delete lidCache;
|
||||
if (auxCache)
|
||||
delete auxCache;
|
||||
if (blockAnims)
|
||||
delete blockAnims;
|
||||
if (scene_display_list)
|
||||
glDeleteLists(scene_display_list, 1);
|
||||
setNull();
|
||||
@ -138,10 +146,20 @@ namespace OpenGTA {
|
||||
loadedMap = &MapHolder::Instance().get();
|
||||
StyleHolder::Instance().load(style_f);
|
||||
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");
|
||||
lidCache = new OpenGL::TextureCache<uint8_t>("LidCache");
|
||||
auxCache = new OpenGL::TextureCache<uint8_t>("AuxCache");
|
||||
sideCache->setClearMagic(5);
|
||||
lidCache->setClearMagic(8);
|
||||
auxCache->setClearMagic(5);
|
||||
blockAnims = new BlockAnimCtrl(style->animations);
|
||||
scene_is_dirty = true;
|
||||
lastCacheEmptyTicks = 0;
|
||||
|
||||
@ -151,16 +169,20 @@ namespace OpenGTA {
|
||||
for (PHYSFS_uint16 oc = 0; oc < loadedMap->numObjects; oc++) {
|
||||
createLevelObject(&loadedMap->objects[oc]);
|
||||
}
|
||||
//SpriteManagerHolder::Instance().trainSystem.loadStations(*loadedMap);
|
||||
}
|
||||
void CityView::createLevelObject(OpenGTA::Map::ObjectPosition *obj) {
|
||||
SpriteManager & s_man = SpriteManagerHolder::Instance();
|
||||
if (obj->remap >= 128) {
|
||||
Car car(*obj);
|
||||
s_man.addCar(car);
|
||||
Car car(*obj, 0);
|
||||
s_man.add(car);
|
||||
//s_man.addCar(car);
|
||||
}
|
||||
else {
|
||||
GameObject gobj(*obj);
|
||||
s_man.addObject(gobj);
|
||||
//GameObject gobj(*obj);
|
||||
SpriteObject gobj(*obj, 0);
|
||||
s_man.add(gobj);
|
||||
//s_man.addObject(gobj);
|
||||
}
|
||||
}
|
||||
void CityView::setZoom(const GLfloat zoom) {
|
||||
@ -341,6 +363,17 @@ namespace OpenGTA {
|
||||
if (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;
|
||||
|
||||
GL_CHECKERROR;
|
||||
@ -358,6 +391,12 @@ namespace OpenGTA {
|
||||
for (int j= x1; j <= x2; j++) {
|
||||
if (!frustum.BlockInFrustum(0.5f+j, 0.5f+i, 0.5f))
|
||||
continue;
|
||||
if (j < xd1)
|
||||
xd1 = j;
|
||||
xd2 = j;
|
||||
if (i < yd1)
|
||||
yd1 = i;
|
||||
yd2 = i;
|
||||
glPushMatrix();
|
||||
glTranslatef(1.0f*j, 0.0f, 1.0f*i);
|
||||
//PHYSFS_uint16 emptycount = loadedMap->getNumBlocksAt(j,i);
|
||||
@ -374,6 +413,11 @@ namespace OpenGTA {
|
||||
}
|
||||
//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) {
|
||||
glEndList();
|
||||
glCallList(scene_display_list);
|
||||
@ -388,14 +432,8 @@ namespace OpenGTA {
|
||||
(loadedMap->objects[oc].y >> 6) + 0.5f, 0.5f))
|
||||
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;
|
||||
SpriteManagerHolder::Instance().drawInRect(r);
|
||||
SpriteManagerHolder::Instance().drawInRect(activeRect);
|
||||
|
||||
lastCacheEmptyTicks += ticks;
|
||||
if (lastCacheEmptyTicks > 4000) {
|
||||
@ -540,6 +578,12 @@ namespace OpenGTA {
|
||||
|
||||
// FIXME: no remaps used!
|
||||
if (bi->lid) {
|
||||
int frame_num = -1;//style->checkBlockAnimation(0, bi->lid);
|
||||
BlockAnim * banim = blockAnims->getAnim(1, bi->lid);
|
||||
if (banim) {
|
||||
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));
|
||||
@ -548,7 +592,24 @@ namespace OpenGTA {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (bi->left) {
|
||||
int frame_num = -1;
|
||||
BlockAnim * banim = blockAnims->getAnim(0, bi->left);
|
||||
if (banim) {
|
||||
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));
|
||||
@ -557,7 +618,25 @@ namespace OpenGTA {
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
if (bi->right) {
|
||||
int frame_num = -1;
|
||||
BlockAnim * banim = blockAnims->getAnim(0, bi->right);
|
||||
if (banim) {
|
||||
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));
|
||||
@ -566,7 +645,25 @@ namespace OpenGTA {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (bi->top) {
|
||||
int frame_num = -1;
|
||||
BlockAnim * banim = blockAnims->getAnim(0, bi->top);
|
||||
if (banim) {
|
||||
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));
|
||||
@ -575,7 +672,25 @@ namespace OpenGTA {
|
||||
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);
|
||||
}
|
||||
}
|
||||
if (bi->bottom) {
|
||||
int frame_num = -1;
|
||||
BlockAnim * banim = blockAnims->getAnim(0, bi->bottom);
|
||||
if (banim) {
|
||||
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));
|
||||
@ -584,6 +699,18 @@ namespace OpenGTA {
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// handle flat/transparent case
|
||||
if (is_flat) {
|
||||
@ -1094,9 +1221,9 @@ namespace OpenGTA {
|
||||
HEIGHT_VERTEX(0.8f, 0.1f, 0.5f);
|
||||
glEnd();
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
// 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_POS2(a, b) glVertex3f(a + nx, slope_height_offset(which, a, b) + ny, b + nz)
|
||||
glBegin(GL_LINES);
|
||||
@ -1104,9 +1231,30 @@ namespace OpenGTA {
|
||||
NORMAL_POS(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();
|
||||
glColor3f(1, 1, 1);
|
||||
//#endif
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
#endif
|
||||
|
||||
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -31,6 +31,7 @@
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
class BlockAnimCtrl;
|
||||
class CityView {
|
||||
public:
|
||||
CityView();
|
||||
@ -59,6 +60,9 @@ namespace OpenGTA {
|
||||
void CityView::setDrawLines(bool v);
|
||||
|
||||
void resetTextures();
|
||||
const SDL_Rect & getActiveRect() { return activeRect; }
|
||||
const SDL_Rect & getOnScreenRect() { return drawnRect; }
|
||||
BlockAnimCtrl* blockAnims;
|
||||
|
||||
protected:
|
||||
void setNull();
|
||||
@ -69,6 +73,7 @@ namespace OpenGTA {
|
||||
Util::CFrustum frustum;
|
||||
OpenGL::TextureCache<uint8_t>* sideCache;
|
||||
OpenGL::TextureCache<uint8_t>* lidCache;
|
||||
OpenGL::TextureCache<uint8_t>* auxCache;
|
||||
Map* loadedMap;
|
||||
OpenGTA::GraphicsBase* style;
|
||||
GLfloat zoomLevel;
|
||||
@ -79,6 +84,9 @@ namespace OpenGTA {
|
||||
bool drawTextured;
|
||||
bool drawLines;
|
||||
|
||||
SDL_Rect activeRect;
|
||||
SDL_Rect drawnRect;
|
||||
|
||||
int scene_rendered_vertices;
|
||||
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 *
|
||||
* 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 *
|
||||
* 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 *
|
||||
* 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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -56,6 +56,12 @@ namespace OpenGL {
|
||||
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) {
|
||||
SDL_ShowCursor((visible ? SDL_ENABLE : SDL_DISABLE));
|
||||
}
|
||||
@ -103,14 +109,73 @@ namespace OpenGL {
|
||||
if (err)
|
||||
//throw "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);
|
||||
SDL_GL_SetAttribute( SDL_GL_BLUE_SIZE, 8);
|
||||
|
||||
const char* sdl_err = SDL_GetError();
|
||||
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_DOUBLEBUFFER, 1);
|
||||
#ifdef HAVE_SDL_VSYNC
|
||||
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() {
|
||||
GL_CHECKERROR;
|
||||
//GLfloat LightAmbient[] = { 0.8f, 0.8f, 0.8f, 1.0f };
|
||||
//GLfloat LightDiffuse[] = { 1.0f, 1.0f, 1.0f, 1.0f };
|
||||
//GLfloat LightPosition[] = { 128.0f, 200.0f, 128.0f, 1.0f };
|
||||
@ -128,15 +193,24 @@ namespace OpenGL {
|
||||
glCullFace(GL_BACK);
|
||||
//glPolygonMode(GL_FRONT, GL_FILL);
|
||||
//glPolygonMode(GL_BACK, GL_LINE);
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
void Screen::resize(Uint32 w, Uint32 h) {
|
||||
if (h == 0)
|
||||
h = 1;
|
||||
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);
|
||||
width = w;
|
||||
height = h;
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -44,6 +44,11 @@ namespace OpenGL {
|
||||
Uint32 getHeight();
|
||||
bool getFullscreen();
|
||||
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:
|
||||
void initGL();
|
||||
void initSDL();
|
||||
@ -54,7 +59,8 @@ namespace OpenGL {
|
||||
float nearPlane;
|
||||
float farPlane;
|
||||
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;
|
||||
};
|
||||
|
@ -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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -22,11 +22,14 @@
|
||||
************************************************************************/
|
||||
#include <map>
|
||||
#include <cassert>
|
||||
#include <SDL_image.h>
|
||||
#include "gl_spritecache.h"
|
||||
#include "opengta.h"
|
||||
#include "dataholder.h"
|
||||
#include "buffercache.h"
|
||||
#include "log.h"
|
||||
//#include "physfsrwops.h"
|
||||
//#include "image_loader.h"
|
||||
|
||||
namespace OpenGL {
|
||||
SpriteIdentifier::SpriteIdentifier() : sprNum(0), remap(-1), delta(0) {}
|
||||
@ -187,6 +190,26 @@ namespace OpenGL {
|
||||
getSpriteBitmap(sprite_num, remap , delta);
|
||||
unsigned int glwidth = 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)
|
||||
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 *
|
||||
* 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 *
|
||||
* 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 *
|
||||
* 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.
|
||||
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
|
||||
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
|
||||
@ -54,6 +54,15 @@ these remain under their respective licenses.
|
||||
notice appear in all copies and that both that copyright notice and this
|
||||
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
|
||||
with this software.
|
||||
|
@ -1,13 +1,28 @@
|
||||
#ifndef OGTA_LOCAL_PLAYER_H
|
||||
#define OGTA_LOCAL_PLAYER_H
|
||||
#include "Singleton.h"
|
||||
#include "pedestrian.h"
|
||||
#include "game_objects.h"
|
||||
#include "entity_controller.h"
|
||||
#include "id_sys.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
class PlayerController : public Pedestrian::Controller {
|
||||
class PlayerController { // : public PedController { //public Pedestrian::Controller {
|
||||
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,
|
||||
|
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 "lua_vm.h"
|
||||
#include "lunar.h"
|
||||
#include "lua_map.h"
|
||||
#include "lua_cityview.h"
|
||||
#include "lua_stackguard.h"
|
||||
#include "lua_camera.h"
|
||||
@ -33,22 +34,42 @@ namespace OpenGTA {
|
||||
void LuaVM::prepare() {
|
||||
LGUARD(L);
|
||||
if (!_registered) {
|
||||
Lunar<Block>::Register2(L);
|
||||
Lunar<LMap>::Register2(L);
|
||||
/*
|
||||
Lunar<CityView>::Register2(L);
|
||||
luaL_openlib(L, "camera", Camera::methods, 0);
|
||||
luaL_openlib(L, "screen", Screen::methods, 0);
|
||||
luaL_openlib(L, "spritecache", SpriteCache::methods, 0);
|
||||
*/
|
||||
}
|
||||
_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) {
|
||||
LGUARD(L);
|
||||
/*
|
||||
CityView *scv = static_cast<CityView*>(&cv);
|
||||
lua_gettable(L, LUA_GLOBALSINDEX);
|
||||
int scv_ref = Lunar<CityView>::push(L, scv, false);
|
||||
lua_pushliteral(L, "city_view");
|
||||
lua_pushvalue(L, scv_ref);
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
*/
|
||||
}
|
||||
|
||||
void LuaVM::runString(const char* _str) {
|
||||
|
@ -14,18 +14,20 @@ namespace OpenGTA {
|
||||
void runString(const char*);
|
||||
void runFile(const char*);
|
||||
void callSimpleFunction(const char*);
|
||||
void prepare();
|
||||
void setCityView(OpenGTA::CityView &);
|
||||
void setMap(OpenGTA::Map &);
|
||||
int getGlobalInt(const char*);
|
||||
float getGlobalFloat(const char*);
|
||||
const char* getGlobalString(const char*);
|
||||
void setGlobalInt(const char*, int);
|
||||
void setGlobalFloat(const char*, float);
|
||||
void setGlobalString(const char*, const char*);
|
||||
lua_State *getInternalState();
|
||||
protected:
|
||||
lua_State *L;
|
||||
private:
|
||||
bool _registered;
|
||||
void prepare();
|
||||
};
|
||||
typedef Loki::SingletonHolder<LuaVM, Loki::CreateUsingNew, Loki::DefaultLifetime,
|
||||
Loki::SingleThreaded> LuaVMHolder;
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
extern void parse_args(int argc, char* argv[]);
|
||||
extern void on_exit();
|
||||
extern void run_init();
|
||||
extern void run_init(const char*);
|
||||
extern void run_main();
|
||||
|
||||
int global_EC = 0;
|
||||
@ -30,10 +30,10 @@ int main(int argc, char* argv[]) {
|
||||
INFO << "ignoring exceptions" << std::endl;
|
||||
|
||||
if (!catch_exceptions)
|
||||
run_init();
|
||||
run_init(argv[0]);
|
||||
else {
|
||||
try {
|
||||
run_init();
|
||||
run_init(argv[0]);
|
||||
}
|
||||
catch (Exception & e) {
|
||||
ERROR << "Exception during startup: " << e.what() << endl;
|
||||
|
9
makefile
9
makefile
@ -1,7 +1,7 @@
|
||||
include src_list.make
|
||||
|
||||
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)
|
||||
|
||||
@ -44,7 +44,7 @@ coldet/libcoldet.a:
|
||||
make -C coldet -f makefile.g++ all
|
||||
|
||||
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
|
||||
|
||||
html: doxy_main.h
|
||||
@ -70,9 +70,12 @@ rclean:
|
||||
|
||||
libclean:
|
||||
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
|
||||
$(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
|
||||
//
|
||||
bool OBox::IsPointInBox(const Vector3D &InP)
|
||||
bool OBox::IsPointInBox(const Vector3D &InP) const
|
||||
{
|
||||
// Rotate the point into the box's coordinates
|
||||
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
|
||||
//
|
||||
bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius)
|
||||
bool OBox::IsSphereInBox( const Vector3D &InP, float fRadius) const
|
||||
{
|
||||
float fDist;
|
||||
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 )
|
||||
//
|
||||
bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP )
|
||||
bool OBox::BoxOutsidePlane( const Vector3D &InNorm, const Vector3D &InP ) const
|
||||
{
|
||||
// Plane Normal in Box Space
|
||||
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?
|
||||
//
|
||||
bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 )
|
||||
bool OBox::IsLineInBox( const Vector3D& L1, const Vector3D& L2 ) const
|
||||
{
|
||||
// Put line in box space
|
||||
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
|
||||
//
|
||||
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[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
|
||||
// Uses the separating axis test.
|
||||
//
|
||||
bool OBox::IsBoxInBox( OBox &BBox )
|
||||
bool OBox::IsBoxInBox( OBox &BBox ) const
|
||||
{
|
||||
Vector3D SizeA = m_Extent;
|
||||
Vector3D SizeB = BBox.m_Extent;
|
||||
|
18
math/obox.h
18
math/obox.h
@ -12,6 +12,8 @@ class OBox
|
||||
{ Set( m, extent ); }
|
||||
OBox( const Matrix3D & m, const Vector3D & low, const Vector3D & high )
|
||||
{ Set( m, low, high ); }
|
||||
OBox( const OBox & other)
|
||||
{ Set( other.m_M, other.m_Extent ); }
|
||||
|
||||
void Set( const Matrix3D & m, const Vector3D & extent )
|
||||
{
|
||||
@ -25,17 +27,17 @@ class OBox
|
||||
m_Extent = 0.5f * (high - low);
|
||||
}
|
||||
|
||||
Vector3D GetSize()
|
||||
Vector3D GetSize() const
|
||||
{ return 2.0f * m_Extent; }
|
||||
Vector3D GetCenterPoint()
|
||||
Vector3D GetCenterPoint() const
|
||||
{ return m_M.GetTranslate(); }
|
||||
void GetInvRot( Vector3D *pvRot );
|
||||
void GetInvRot( Vector3D *pvRot ) const;
|
||||
|
||||
bool IsPointInBox( const Vector3D & p );
|
||||
bool IsBoxInBox( OBox & box );
|
||||
bool IsSphereInBox( const Vector3D & p, float fRadius );
|
||||
bool IsLineInBox( const Vector3D & l1, const Vector3D & l2 );
|
||||
bool BoxOutsidePlane( const Vector3D & normal, const Vector3D & p );
|
||||
bool IsPointInBox( const Vector3D & p ) const ;
|
||||
bool IsBoxInBox( OBox & box ) const ;
|
||||
bool IsSphereInBox( const Vector3D & p, float fRadius ) const ;
|
||||
bool IsLineInBox( const Vector3D & l1, const Vector3D & l2 ) const ;
|
||||
bool BoxOutsidePlane( const Vector3D & normal, const Vector3D & p ) const ;
|
||||
|
||||
// Data
|
||||
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;
|
||||
}
|
||||
|
||||
// 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
|
||||
|
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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -11,8 +11,10 @@
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
#include <iomanip>
|
||||
#include "navdata.h"
|
||||
#include "log.h"
|
||||
#include "dataholder.h"
|
||||
#include "m_exceptions.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
@ -67,27 +69,30 @@ namespace OpenGTA {
|
||||
return res;
|
||||
}
|
||||
|
||||
NavData::Sector::Sector(PHYSFS_file* fd) : Rect2D() {
|
||||
NavData::Sector::Sector(PHYSFS_file* fd) : Rect2D(), sam(0), name("") {
|
||||
sam = 0;
|
||||
isADummy = 0;
|
||||
std::memset(&name, 0, 30);
|
||||
assert(fd);
|
||||
//memset(name2, 0, 30);
|
||||
PHYSFS_read(fd, static_cast<void*>(&x), 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*>(&h), 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;
|
||||
y = 0;
|
||||
w = 255;
|
||||
h = 255;
|
||||
sam = 0;
|
||||
std::memset(&name, 0, 30);
|
||||
isADummy = 1;
|
||||
//memset(name2, 0, 30);
|
||||
}
|
||||
|
||||
const char* NavData::Sector::getFullName() {
|
||||
@ -117,7 +122,7 @@ namespace OpenGTA {
|
||||
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) {
|
||||
std::ostringstream o;
|
||||
o << "Navdata size: " << size << " % 35 != 0";
|
||||
@ -126,6 +131,8 @@ namespace OpenGTA {
|
||||
}
|
||||
PHYSFS_uint32 c = size / 35;
|
||||
assert(fd);
|
||||
|
||||
MessageDB & msg = MainMsgHolder::Instance().get();
|
||||
for (PHYSFS_uint32 i = 0; i < c; ++i) {
|
||||
Sector *sec = new Sector(fd);
|
||||
if (sec->getSize() == 0) { // workaround for 'NYC.CMP' (empty sectors)
|
||||
@ -133,16 +140,25 @@ namespace OpenGTA {
|
||||
WARN << "skipping zero size sector" << std::endl;
|
||||
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));
|
||||
}
|
||||
}
|
||||
// dummy catch-all sector for gta london maps
|
||||
areas.insert(std::pair<PHYSFS_uint16, Sector*>(255*255, new Sector()));
|
||||
|
||||
/*
|
||||
std::cout << "map areas (by size)" << std::endl;
|
||||
SectorMapType::iterator i = areas.begin();
|
||||
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->h) << " sample " << int(i->second->sam) << std::endl;
|
||||
++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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -11,6 +11,7 @@
|
||||
#ifndef NAVDATA_H
|
||||
#define NAVDATA_H
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <physfs.h>
|
||||
|
||||
namespace OpenGTA {
|
||||
@ -77,14 +78,15 @@ namespace OpenGTA {
|
||||
* 2) probably sound?
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
const char* getFullName();
|
||||
private:
|
||||
bool isADummy;
|
||||
};
|
||||
NavData(PHYSFS_uint32 size, PHYSFS_file *fd);
|
||||
NavData(PHYSFS_uint32 size, PHYSFS_file *fd, const size_t level_num);
|
||||
~NavData();
|
||||
Sector* getSectorAt(PHYSFS_uint8, PHYSFS_uint8);
|
||||
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 *
|
||||
* 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 prepareLidTexture(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;
|
||||
|
||||
CarInfo* findCarByModel(PHYSFS_uint8);
|
||||
size_t getNumCarModels() { return carInfos.size(); }
|
||||
unsigned char* getTmpBuffer(bool rgba);
|
||||
SpriteInfo* getSprite(size_t id) { return spriteInfos[id]; }
|
||||
|
||||
@ -253,6 +256,9 @@ namespace OpenGTA {
|
||||
bool delta_is_a_set;
|
||||
|
||||
Util::Set sideTexBlockMove;
|
||||
|
||||
unsigned int firstValidPedRemap;
|
||||
unsigned int lastValidPedRemap;
|
||||
};
|
||||
|
||||
// just a forward declaration
|
||||
@ -468,7 +474,7 @@ namespace OpenGTA {
|
||||
void loadObjects();
|
||||
void loadRoutes();
|
||||
void loadLocations();
|
||||
void loadNavData();
|
||||
void loadNavData(const size_t level_num);
|
||||
static const PHYSFS_uint8 _topHeaderSize = 28;
|
||||
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() {
|
||||
FOO=GL_SRC
|
||||
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}"
|
||||
FOO=OGTA_SRC
|
||||
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}"
|
||||
|
||||
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_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
|
||||
}
|
||||
|
||||
@ -58,13 +65,13 @@ gfxextract${EXE_PFIX}: gfx_extract.cpp read_gry.o read_g24.o read_cmp.o navdata.
|
||||
-o \$@ \$+ \\
|
||||
\$(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) \\
|
||||
\$(INC) \\
|
||||
-o \$@ \$+ \\
|
||||
\$(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)
|
||||
\$(CXX) \$(CATCH_E) -DWITH_LUA \$(FLAGS) \$(DEFS) \\
|
||||
\$(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)
|
||||
|
||||
|
||||
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) \\
|
||||
\$(INC) \\
|
||||
-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
|
||||
\$(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
|
||||
}
|
||||
|
||||
@ -116,6 +143,19 @@ function check_sdl () {
|
||||
pkg_config_try_multiple SDL SDL sdl
|
||||
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 () {
|
||||
@ -145,6 +185,38 @@ function check_lua () {
|
||||
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 () {
|
||||
program_exists pkg-config
|
||||
if [ $? -eq 1 ]; then
|
||||
@ -153,18 +225,26 @@ function check_physfs () {
|
||||
}
|
||||
|
||||
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
|
||||
CXX=g++
|
||||
CXX=$_CXX
|
||||
else
|
||||
CXX=
|
||||
fi
|
||||
gcc 1>/dev/null 2>&1
|
||||
$_CC 1>/dev/null 2>&1
|
||||
if [ $? -eq 1 ]; then
|
||||
CC=gcc
|
||||
CC=$_CC
|
||||
else
|
||||
CC=
|
||||
fi
|
||||
GCC_VERSION=$($CXX --version | head -n 1)
|
||||
}
|
||||
|
||||
# defaults
|
||||
@ -172,11 +252,6 @@ function check_compiler () {
|
||||
DEBUG=-ggdb
|
||||
WARN=-Wall
|
||||
OPT=-O2
|
||||
if [ "$1" == "LINUX" ]; then
|
||||
DEFS="-DLINUX -DDO_SCALEX"
|
||||
else
|
||||
DEFS="-DWIN32 -DDO_SCALEX"
|
||||
fi
|
||||
PHYSFS_LIB=-lphysfs
|
||||
SDL_LIB=-lSDL
|
||||
LUA_LIB=-llua51
|
||||
@ -190,7 +265,7 @@ CC = $CC
|
||||
DEBUG = $DEBUG
|
||||
OPT = $OPT
|
||||
WARN = $WARN
|
||||
DEFS = $DEFS -DGCC
|
||||
DEFS = $DEFS
|
||||
|
||||
# def only for 'main' programs to let gdb handle the exception
|
||||
#CATCH_E = -DDONT_CATCH
|
||||
@ -211,6 +286,9 @@ SDL_IMG_LIB = -lSDL_image
|
||||
LUA_INC = $LUA_INC
|
||||
LUA_LIB = $LUA_LIB
|
||||
|
||||
AUDIO_INC =
|
||||
AUDIO_LIB = $AUDIO_LD
|
||||
|
||||
LINK_LAZY = -Xlinker --unresolved-symbols -Xlinker ignore-all
|
||||
|
||||
EOF
|
||||
@ -225,7 +303,7 @@ CC = i586-mingw32msvc-gcc
|
||||
#DEBUG = $DEBUG
|
||||
OPT = $OPT
|
||||
WARN = $WARN
|
||||
DEFS = $DEFS -DGCC
|
||||
DEFS = $DEFS
|
||||
|
||||
# def only for 'main' programs to let gdb handle the exception
|
||||
#CATCH_E = -DDONT_CATCH
|
||||
@ -256,7 +334,7 @@ function print_all() {
|
||||
check_sdl
|
||||
check_lua
|
||||
check_physfs
|
||||
check_compiler
|
||||
check_sdl_audio
|
||||
print_detected
|
||||
print_make_file_list
|
||||
print_target_list
|
||||
@ -266,12 +344,68 @@ include depend
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ "$1" == "LINUX" ]; then
|
||||
echo "*** LINUX ***"
|
||||
print_all > src_list.make
|
||||
else
|
||||
function print_config_h() {
|
||||
if [ -e ogta_version ]; then
|
||||
LAST_TOUCHED=$(cat ogta_version)
|
||||
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 ***"
|
||||
DEFS="-include config.h"
|
||||
check_compiler
|
||||
print_w32settings > src_list.make
|
||||
print_make_file_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
|
||||
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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -15,6 +15,7 @@
|
||||
#include "navdata.h"
|
||||
#include "log.h"
|
||||
#include "m_exceptions.h"
|
||||
#include "datahelper.h"
|
||||
|
||||
/* see http://members.aol.com/form1/fixed.htm for fixed point floats:
|
||||
* int_var = (long) fixed_var >> 8; // for 8 bits after point
|
||||
@ -35,6 +36,7 @@ namespace OpenGTA {
|
||||
o << filename << " with error: " << SDL_GetError();
|
||||
throw E_FILENOTFOUND(o.str());
|
||||
}
|
||||
size_t level_as_num = Helper::mapFileName2Number(filename);
|
||||
loadHeader();
|
||||
loadBase();
|
||||
loadColumn();
|
||||
@ -42,7 +44,7 @@ namespace OpenGTA {
|
||||
loadObjects();
|
||||
loadRoutes();
|
||||
loadLocations();
|
||||
loadNavData();
|
||||
loadNavData(level_as_num);
|
||||
//dump();
|
||||
}
|
||||
Map::~Map() {
|
||||
@ -217,11 +219,11 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
}
|
||||
void Map::loadNavData() {
|
||||
void Map::loadNavData(const size_t levelNum) {
|
||||
PHYSFS_uint32 _si = _baseSize + columnSize + _topHeaderSize +
|
||||
objectPosSize + routeSize + 3 * 6 * 6 + blockSize;
|
||||
PHYSFS_seek(fd, _si);
|
||||
nav = new NavData(navDataSize, fd);
|
||||
nav = new NavData(navDataSize, fd, levelNum);
|
||||
assert(nav);
|
||||
}
|
||||
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 *
|
||||
* 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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -11,6 +11,8 @@
|
||||
#include <stdio.h>
|
||||
#include <iostream>
|
||||
#include "opengta.h"
|
||||
#include "m_exceptions.h"
|
||||
#include "log.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
MessageDB::MessageDB() {
|
||||
@ -31,8 +33,7 @@ namespace OpenGTA {
|
||||
f = PHYSFS_openRead(f2.c_str());
|
||||
}
|
||||
if (f == NULL) {
|
||||
std::cerr << "Error: could not open " << file << " for reading" << std::endl;
|
||||
return;
|
||||
throw E_FILENOTFOUND(file);
|
||||
}
|
||||
|
||||
messages.clear();
|
||||
@ -92,7 +93,7 @@ namespace OpenGTA {
|
||||
const std::string& MessageDB::getText(const char* id) {
|
||||
std::map<std::string, std::string>::iterator i = messages.find(std::string(id));
|
||||
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 i->second;
|
||||
@ -101,7 +102,7 @@ namespace OpenGTA {
|
||||
const std::string& MessageDB::getText(const std::string &id) {
|
||||
std::map<std::string, std::string>::iterator i = messages.find(id);
|
||||
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 i->second;
|
||||
@ -112,7 +113,7 @@ namespace OpenGTA {
|
||||
snprintf(reinterpret_cast<char*>(&tmp), 10, "%i", id);
|
||||
std::map<std::string, std::string>::iterator i = messages.find(std::string(tmp));
|
||||
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 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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -29,6 +29,23 @@ namespace OpenGTA {
|
||||
palIndex = NULL;
|
||||
loadHeader();
|
||||
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() {
|
||||
@ -143,6 +160,7 @@ namespace OpenGTA {
|
||||
PHYSFS_uint64 st = static_cast<PHYSFS_uint64>(_topHeaderSize) +
|
||||
sideSize + lidSize + auxSize + auxBlockTrailSize + animSize +
|
||||
pagedClutSize + paletteIndexSize + objectInfoSize;
|
||||
//INFO << "seek for " << st << std::endl;
|
||||
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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -268,6 +268,17 @@ namespace OpenGTA {
|
||||
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() {
|
||||
fd = PHYSFS_openRead(style.c_str());
|
||||
if (fd == NULL) {
|
||||
@ -288,6 +299,8 @@ namespace OpenGTA {
|
||||
auxBlockTrailSize = 0;
|
||||
loadHeader();
|
||||
setupBlocking(style);
|
||||
firstValidPedRemap = 131;
|
||||
lastValidPedRemap = 187;
|
||||
}
|
||||
|
||||
Graphics8Bit::~Graphics8Bit() {
|
||||
@ -423,7 +436,7 @@ namespace OpenGTA {
|
||||
for (int j=0; j<animation->frameCount; j++) {
|
||||
uint8_t val;
|
||||
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);
|
||||
}
|
||||
animations.push_back(animation);
|
||||
@ -498,8 +511,10 @@ namespace OpenGTA {
|
||||
void GraphicsBase::loadCarInfo_shared(PHYSFS_uint64 offset) {
|
||||
PHYSFS_seek(fd, offset);
|
||||
|
||||
//INFO << "starting at offset " << offset << std::endl;
|
||||
PHYSFS_uint32 bytes_read = 0;
|
||||
while (bytes_read < carInfoSize) {
|
||||
//INFO << bytes_read << ": " << carInfoSize << std::endl;
|
||||
CarInfo * car = new CarInfo();
|
||||
|
||||
PHYSFS_readSLE16(fd, &car->width);
|
||||
@ -579,6 +594,10 @@ namespace OpenGTA {
|
||||
|
||||
PHYSFS_readSLE16(fd, &car->numDoors);
|
||||
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++) {
|
||||
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 *
|
||||
* DMA Design. It may not be used in a commercial product. *
|
||||
@ -9,31 +9,19 @@
|
||||
* This notice may not be removed or altered. *
|
||||
************************************************************************/
|
||||
#include <iostream>
|
||||
#include <string>
|
||||
#include <map>
|
||||
#include <stdlib.h>
|
||||
#include <physfs.h>
|
||||
#include "log.h"
|
||||
#include "read_ini.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
class ScriptParser {
|
||||
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) {
|
||||
ScriptParser::ScriptParser(const std::string &file) : section_info(""), section_vars("") {
|
||||
fd = PHYSFS_openRead(file.c_str());
|
||||
if (!fd) {
|
||||
std::cerr << "Error: could not open file " << file << " for reading!" << std::endl;
|
||||
}
|
||||
else {
|
||||
std::cout << "* Loading script " << file << " ... ";
|
||||
/*
|
||||
unsigned char v;
|
||||
unsigned char m = 0;
|
||||
char buffer[10];
|
||||
@ -50,15 +38,67 @@ namespace OpenGTA {
|
||||
*b = 0x00;
|
||||
b = reinterpret_cast<char*>(&buffer);
|
||||
levels[static_cast<PHYSFS_uint32>(atoi(buffer))] = PHYSFS_tell(fd) + 1;
|
||||
std::cout << buffer << " " << PHYSFS_tell(fd) + 1 << std::endl;
|
||||
}
|
||||
}
|
||||
if (v == '[') {
|
||||
m = 1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
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() {
|
||||
if (fd != NULL)
|
||||
@ -66,26 +106,65 @@ namespace OpenGTA {
|
||||
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) {
|
||||
LevelMapType::iterator i = levels.find(level);
|
||||
if (i == levels.end()) {
|
||||
std::cerr << "not a valid level: " << level << std::endl;
|
||||
return;
|
||||
}
|
||||
PHYSFS_sint64 end_of_section = sectionEndOffset(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 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);
|
||||
PHYSFS_read(fd, buffer + offset, 1, read_bytes);
|
||||
char* line_start = buffer;
|
||||
while (1) {
|
||||
char* line_end = strchr(line_start, '\r');
|
||||
if (line_start && line_end) {
|
||||
if (*(line_end - 1) == ' ')
|
||||
line_end--;
|
||||
*line_end = 0;
|
||||
while (*line_start == '\n' || *line_start == '\r' || *line_start == ' ')
|
||||
line_start++;
|
||||
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;
|
||||
if (*line_start == '\n')
|
||||
@ -94,16 +173,25 @@ namespace OpenGTA {
|
||||
else
|
||||
break;
|
||||
}
|
||||
typedef unsigned int uint32;
|
||||
//std::cout << uint32(line_start) - uint32(buffer) << std::endl;
|
||||
PHYSFS_uint32 begin_rest = PHYSFS_uint32(line_start) - PHYSFS_uint32(buffer);
|
||||
offset = 255 - begin_rest;
|
||||
memmove(buffer, &buffer[begin_rest], 255 - begin_rest);
|
||||
read_bytes = 255 - offset;
|
||||
offset = buf_len - begin_rest;
|
||||
memmove(buffer, &buffer[begin_rest], buf_len - begin_rest);
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
void ScriptParser::acceptDefinition(const char* str) {
|
||||
INFO << "def: " << str << std::endl;
|
||||
}
|
||||
|
||||
void ScriptParser::acceptCommand(const char* str) {
|
||||
INFO << "cmd: " << str << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#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 *
|
||||
* 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 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 =
|
||||
|
||||
You can download the game from http://www.rockstargames.com/classics/ .
|
||||
@ -40,6 +45,13 @@ Needed:
|
||||
STYLE*.GRY (for 8-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 =
|
||||
|
||||
== gfxextract ==
|
||||
@ -61,6 +73,13 @@ The optional param loads the respective city; default is 0:
|
||||
2 - MIAMI.CMP
|
||||
|
||||
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)
|
||||
-w width
|
||||
-h height
|
||||
@ -92,17 +111,15 @@ furthermore:
|
||||
f : toggle fullscreen/windowed
|
||||
PRINT : save 'screenshot.bmp' in current directory
|
||||
p : dump coords (in lua syntax) to stdout
|
||||
i,j,k,l : move player-char
|
||||
F2 : toggle drawing of sprite bounding-boxes
|
||||
F3 : toggle marking of sprite tex-border-boxes
|
||||
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)
|
||||
1 - 8 : choose a specific player-sprite animation
|
||||
9, 0 : set the player-sprite to a specific frame
|
||||
F9 : toggle city blocks drawn textured
|
||||
F10 : toggle blocks wireframe lines
|
||||
|
||||
in 3d view:
|
||||
F1 : demo-flight over the city
|
||||
w : forward
|
||||
s : backward
|
||||
space : stop
|
||||
@ -112,6 +129,14 @@ in 3d view:
|
||||
You can move the view with the mouse; when you switch
|
||||
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) ==
|
||||
|
||||
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 <sstream>
|
||||
#include <SDL_opengl.h>
|
||||
@ -29,13 +51,17 @@ int bbox_toggle = 0;
|
||||
int texsprite_toggle = 0;
|
||||
|
||||
int spr_type = (int)ped.sprType;
|
||||
namespace OpenGTA {
|
||||
void ai_step_fake(OpenGTA::Pedestrian*) {
|
||||
}
|
||||
}
|
||||
|
||||
void on_exit() {
|
||||
SDL_Quit();
|
||||
PHYSFS_deinit();
|
||||
}
|
||||
|
||||
void run_init() {
|
||||
void run_init(const char*) {
|
||||
PHYSFS_init("mapview");
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
@ -106,7 +132,7 @@ void drawScene(Uint32 ticks) {
|
||||
if (play_anim) {
|
||||
pedAnim.firstFrameOffset = now_frame;
|
||||
}
|
||||
OpenGTA::SpriteManagerHolder::Instance().drawPed(ped);
|
||||
OpenGTA::SpriteManagerHolder::Instance().draw(ped);
|
||||
|
||||
OpenGL::ScreenHolder::Instance().setFlatProjection();
|
||||
|
||||
@ -188,7 +214,7 @@ void handleKeyPress( SDL_keysym *keysym ) {
|
||||
}
|
||||
if (update_anim) {
|
||||
pedAnim.firstFrameOffset = frame_offset;
|
||||
ped.setAnimation(pedAnim);
|
||||
ped.anim = pedAnim;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,33 +1,35 @@
|
||||
/************************************************************************
|
||||
* 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. *
|
||||
************************************************************************/
|
||||
* 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 <SDL_opengl.h>
|
||||
#include "gl_spritecache.h"
|
||||
#include "dataholder.h"
|
||||
#include "spritemanager.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "id_sys.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
//SpriteManager::SpriteManager() : trainSystem(AbstractContainer<TrainSegment>::objs){
|
||||
SpriteManager::SpriteManager() {
|
||||
drawMode = (1);
|
||||
|
||||
@ -37,23 +39,43 @@ namespace OpenGTA {
|
||||
registerAnimation(2, SpriteObject::Animation(0, 7, 0.001f)); // walking
|
||||
registerAnimation(3, SpriteObject::Animation(8, 7, 0.0015f)); // running
|
||||
|
||||
// registerAnimation(3, SpriteObject::Animation(16, 0)); // sitting in car
|
||||
// registerAnimation(4, SpriteObject::Animation(17, 7)); // car-exit
|
||||
// registerAnimation(5, SpriteObject::Animation(25, 7)); // car-enter
|
||||
// registerAnimation(3, SpriteObject::Animation(16, 0)); // sitting in car
|
||||
// registerAnimation(4, SpriteObject::Animation(17, 7)); // car-exit
|
||||
// registerAnimation(5, SpriteObject::Animation(25, 7)); // car-enter
|
||||
//registerAnimation(3, SpriteObject::Animation(107, 7, 0.002f));
|
||||
//registerAnimation(4, SpriteObject::Animation(99, 7, 0.001f));
|
||||
//registerAnimation(5, SpriteObject::Animation(28, 7));
|
||||
// registerAnimation(6, SpriteObject::Animation(38, 2)); // falling
|
||||
registerAnimation(7, SpriteObject::Animation(41, 0)); // sliding under
|
||||
registerAnimation(8, SpriteObject::Animation(42, 1)); // death pose; maybe just 1?
|
||||
registerAnimation(9, SpriteObject::Animation(44, 0)); // death-back pose
|
||||
registerAnimation(10, SpriteObject::Animation(45, 1)); // shot-in-front
|
||||
registerAnimation(11, SpriteObject::Animation(47, 1)); // swimming
|
||||
registerAnimation(12, SpriteObject::Animation(98, 0)); // standing still
|
||||
// registerAnimation(6, SpriteObject::Animation(38, 2)); // falling
|
||||
//registerAnimation(7, SpriteObject::Animation(41, 0)); // sliding under
|
||||
//registerAnimation(9, SpriteObject::Animation(44, 0)); // death-back pose
|
||||
//registerAnimation(11, SpriteObject::Animation(47, 1)); // swimming
|
||||
//registerAnimation(12, SpriteObject::Animation(98, 0)); // standing still
|
||||
|
||||
registerAnimation(4, SpriteObject::Animation(89, 0)); // standing, gun
|
||||
registerAnimation(5, SpriteObject::Animation(99, 7, 0.001f)); // walking, gun
|
||||
registerAnimation(6, SpriteObject::Animation(107, 7, 0.002f)); // running, gun
|
||||
|
||||
registerAnimation(7, SpriteObject::Animation(134, 0)); //standing, flamethrower
|
||||
registerAnimation(8, SpriteObject::Animation(118, 7, 0.001f)); // walking, flamethrower
|
||||
registerAnimation(9, SpriteObject::Animation(126, 7, 0.002f)); // running, flamethrower
|
||||
|
||||
registerAnimation(10, SpriteObject::Animation(152, 0)); //standing, uzi
|
||||
registerAnimation(11, SpriteObject::Animation(136, 7, 0.001f)); // walking, uzi
|
||||
registerAnimation(12, SpriteObject::Animation(144, 7, 0.002f)); // running, uzi
|
||||
|
||||
registerAnimation(13, SpriteObject::Animation(170, 0)); //standing, rocket-launcher
|
||||
registerAnimation(14, SpriteObject::Animation(154, 7, 0.001f)); // walking, rocket-launcher
|
||||
registerAnimation(15, SpriteObject::Animation(162, 7, 0.002f)); // running, rocket-launcher
|
||||
|
||||
|
||||
|
||||
registerAnimation(42, SpriteObject::Animation(42, 1)); // death pose; maybe just 1?
|
||||
registerAnimation(45, SpriteObject::Animation(45, 1)); // shot-in-front
|
||||
|
||||
registerAnimation(46, SpriteObject::Animation(354, 12));
|
||||
|
||||
|
||||
|
||||
/*
|
||||
registerAnimation(12, SpriteObject::Animation(
|
||||
registerAnimation(13, SpriteObject::Animation(
|
||||
@ -63,7 +85,9 @@ namespace OpenGTA {
|
||||
registerAnimation(17, SpriteObject::Animation(
|
||||
registerAnimation(18, SpriteObject::Animation(
|
||||
registerAnimation(19, SpriteObject::Animation(
|
||||
*/
|
||||
*/
|
||||
registerAnimation(99, SpriteObject::Animation(0, 12));
|
||||
registerAnimation(100, SpriteObject::Animation(12, 12));
|
||||
}
|
||||
SpriteManager::~SpriteManager() {
|
||||
clear();
|
||||
@ -71,6 +95,7 @@ namespace OpenGTA {
|
||||
}
|
||||
|
||||
void SpriteManager::update(Uint32 ticks) {
|
||||
/*
|
||||
for (PedListType::iterator i = activePeds.begin(); i != activePeds.end(); ++i) {
|
||||
for (ObjectListType::iterator j = activeObjects.begin(); j != activeObjects.end(); ++j) {
|
||||
Pedestrian & ped = *i;
|
||||
@ -87,60 +112,143 @@ namespace OpenGTA {
|
||||
for (PedListType::iterator i = activePeds.begin(); i != activePeds.end(); ++i) {
|
||||
i->update(ticks);
|
||||
}
|
||||
for (ObjectListType::iterator i = activeObjects.begin(); i != activeObjects.end(); ++i) {
|
||||
i->update(ticks);
|
||||
}*/
|
||||
|
||||
size_t num_peds, num_cars, num_obj;
|
||||
num_peds = 0;
|
||||
for (AbstractContainer<Pedestrian>::Storage_T_Iterator i = AbstractContainer<Pedestrian>::objs.begin();
|
||||
i != AbstractContainer<Pedestrian>::objs.end(); ++i) {
|
||||
Pedestrian & ped = (*i);
|
||||
ped.update(ticks);
|
||||
num_peds++;
|
||||
}
|
||||
num_cars = 0;
|
||||
for (AbstractContainer<Car>::Storage_T_Iterator i = AbstractContainer<Car>::objs.begin();
|
||||
i != AbstractContainer<Car>::objs.end(); ++i) {
|
||||
Car & car = (*i);
|
||||
car.update(ticks);
|
||||
num_cars++;
|
||||
}
|
||||
for (AbstractContainer<SpriteObject>::Storage_T_Iterator i = AbstractContainer<SpriteObject>::objs.begin();
|
||||
i != AbstractContainer<SpriteObject>::objs.end(); ++i) {
|
||||
SpriteObject & obj = (*i);
|
||||
obj.update(ticks);
|
||||
num_obj++;
|
||||
if (obj.isActive == false)
|
||||
AbstractContainer<SpriteObject>::toBeRemoved.push_back(i);
|
||||
}
|
||||
for (ProjectileListType::iterator i = activeProjectiles.begin(); i != activeProjectiles.end();) {
|
||||
Projectile & pr = (*i);
|
||||
pr.update(ticks);
|
||||
if (pr.lastUpdateAt >= pr.endsAtTick) {
|
||||
ProjectileListType::iterator j = i++;
|
||||
activeProjectiles.erase(j);
|
||||
//INFO << "deleting old projectile; now " << activeProjectiles.size() << std::endl;
|
||||
}
|
||||
else
|
||||
++i;
|
||||
|
||||
}
|
||||
removeDeadStuff();
|
||||
if (num_peds < 10 && num_peds > 0) {
|
||||
//MapHelper::createPeds(5);
|
||||
Map & map = OpenGTA::MapHolder::Instance().get();
|
||||
while (1) {
|
||||
Util::TupleOfUint8 tu8 = creationArea.getValidCoord();
|
||||
int k = -1;
|
||||
for (int i = 0; i < map.getNumBlocksAtNew(tu8.first, tu8.second); ++i) {
|
||||
Map::BlockInfo * bi = map.getBlockAtNew(tu8.first, tu8.second, i);
|
||||
if (bi->blockType() == 3) {
|
||||
k = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (k == -1)
|
||||
continue;
|
||||
|
||||
INFO << int(tu8.first) << " " << int(tu8.second) << " " << k << std::endl;
|
||||
|
||||
Vector3D pos(tu8.first + 0.5f, k+1, tu8.second+0.5f);
|
||||
int id = OpenGTA::TypeIdBlackBox::requestId();
|
||||
Sint16 remap = OpenGTA::StyleHolder::Instance().get().getRandomPedRemapNumber();
|
||||
OpenGTA::Pedestrian p(Vector3D(0.3f, 0.5f, 0.3f), pos, id, remap);
|
||||
OpenGTA::SpriteManagerHolder::Instance().add<Pedestrian>(p);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteManager::drawInRect(SDL_Rect & r) {
|
||||
for (PedListType::iterator i = activePeds.begin(); i != activePeds.end(); ++i) {
|
||||
for (AbstractContainer<Pedestrian>::Storage_T_Iterator i = AbstractContainer<Pedestrian>::objs.begin();
|
||||
i != AbstractContainer<Pedestrian>::objs.end(); ++i) {
|
||||
Pedestrian & ped = (*i);
|
||||
if ((ped.pos.x >= r.x) && (ped.pos.x <= r.x + r.w) &&
|
||||
(ped.pos.z >= r.y) && (ped.pos.z <= r.y + r.h)) {
|
||||
drawPed(ped);
|
||||
(ped.pos.z >= r.y) && (ped.pos.z <= r.y + r.h))
|
||||
draw(ped);
|
||||
}
|
||||
}
|
||||
for (ObjectListType::iterator i = activeObjects.begin(); i != activeObjects.end(); ++i) {
|
||||
GameObject & obj = (*i);
|
||||
for (AbstractContainer<SpriteObject>::Storage_T_Iterator i = AbstractContainer<SpriteObject>::objs.begin();
|
||||
i != AbstractContainer<SpriteObject>::objs.end(); ++i) {
|
||||
SpriteObject & obj = (*i);
|
||||
if ((obj.pos.x >= r.x) && (obj.pos.x <= r.x + r.w) &&
|
||||
(obj.pos.z >= r.y) && (obj.pos.z <= r.y + r.h)) {
|
||||
drawObject(obj);
|
||||
(obj.pos.z >= r.y) && (obj.pos.z <= r.y + r.h))
|
||||
draw(obj);
|
||||
}
|
||||
}
|
||||
for (CarListType::iterator i = activeCars.begin(); i != activeCars.end(); ++i) {
|
||||
Car & car = *i;
|
||||
for (AbstractContainer<Car>::Storage_T_Iterator i = AbstractContainer<Car>::objs.begin();
|
||||
i != AbstractContainer<Car>::objs.end(); ++i) {
|
||||
Car & car = (*i);
|
||||
if ((car.pos.x >= r.x) && (car.pos.x <= r.x + r.w) &&
|
||||
(car.pos.z >= r.y) && (car.pos.z <= r.y + r.h)) {
|
||||
drawCar(car);
|
||||
(car.pos.z >= r.y) && (car.pos.z <= r.y + r.h))
|
||||
draw(car);
|
||||
}
|
||||
|
||||
glColor3f(0.2f, 0.2f, 0.2f);
|
||||
typedef ProjectileListType::iterator ProjectileIterator;
|
||||
for (ProjectileIterator i = activeProjectiles.begin(); i != activeProjectiles.end(); ++i) {
|
||||
Projectile & prj = (*i);
|
||||
if ((prj.pos.x >= r.x) && (prj.pos.x <= r.x + r.w) &&
|
||||
(prj.pos.z >= r.y) && (prj.pos.z <= r.y + r.h))
|
||||
draw(prj);
|
||||
}
|
||||
glColor3f(1, 1, 1);
|
||||
|
||||
}
|
||||
|
||||
void SpriteManager::clear() {
|
||||
activePeds.clear();
|
||||
activeObjects.clear();
|
||||
activeCars.clear();
|
||||
#define TYPED_CLEANUP(T) { \
|
||||
AbstractContainer<T>::objs.clear(); \
|
||||
AbstractContainer<T>::toBeRemoved.clear(); \
|
||||
}
|
||||
TYPED_CLEANUP(Pedestrian);
|
||||
TYPED_CLEANUP(Car);
|
||||
TYPED_CLEANUP(SpriteObject);
|
||||
//TYPED_CLEANUP(TrainSegment);
|
||||
activeProjectiles.clear();
|
||||
|
||||
#undef TYPED_CLEANUP
|
||||
}
|
||||
|
||||
/*
|
||||
void SpriteManager::drawCar(Car & car) {
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
|
||||
GraphicsBase::SpriteInfo * info = style.getSprite(sprNum);
|
||||
|
||||
OpenGL::PagedTexture t;
|
||||
GLfloat w, h;
|
||||
|
||||
drawGL(t, w, h);
|
||||
|
||||
}
|
||||
*/
|
||||
|
||||
#define GL_OBJ_COMMON(o) GL_CHECKERROR; \
|
||||
glPushMatrix(); \
|
||||
glTranslatef(o.pos.x, o.pos.y, o.pos.z); \
|
||||
glRotatef(o.rot, 0, 1, 0); \
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, *o.m_M.m)
|
||||
glPushMatrix(); \
|
||||
glTranslatef(o.pos.x, o.pos.y, o.pos.z); \
|
||||
glRotatef(o.rot, 0, 1, 0); \
|
||||
//glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat*)o.m_M.m)
|
||||
|
||||
#define DRAW_TEX_QUADS_OBJ(t, w, h) glBindTexture(GL_TEXTURE_2D, t.inPage); \
|
||||
glBegin(GL_QUADS); \
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v); \
|
||||
glVertex3f(-w/2, 0.0f, h/2); \
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v); \
|
||||
glVertex3f(w/2, 0.0f, h/2); \
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v); \
|
||||
glVertex3f(w/2, 0.0f, -h/2); \
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v); \
|
||||
glVertex3f(-w/2, 0.0f, -h/2); \
|
||||
glEnd()
|
||||
|
||||
|
||||
void SpriteManager::drawCar(Car & car) {
|
||||
void SpriteManager::draw(Car & car) {
|
||||
GL_OBJ_COMMON(car);
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
OpenGL::PagedTexture t;
|
||||
@ -158,38 +266,42 @@ namespace OpenGTA {
|
||||
car.anim.firstFrameOffset + car.anim.currentFrame,
|
||||
car.sprType, car.remap);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(w/2, 0.0f, h/2);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(w/2, 0.0f, -h/2);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
DRAW_TEX_QUADS_OBJ(t, w, h);
|
||||
|
||||
glEnd();
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (getDrawBBox()) {
|
||||
|
||||
if (getDrawBBox())
|
||||
drawBBoxOutline(car);
|
||||
if (getDrawTexBorder())
|
||||
drawTextureOutline(w, h);
|
||||
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
void SpriteManager::drawBBoxOutline(const OBox & box) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-car.m_Extent.x, 0.0f, car.m_Extent.z);
|
||||
glVertex3f(car.m_Extent.x, 0.0f, car.m_Extent.z);
|
||||
glVertex3f(car.m_Extent.x, 0.0f, -car.m_Extent.z);
|
||||
glVertex3f(-car.m_Extent.x, 0.0f, -car.m_Extent.z);
|
||||
glVertex3f(-car.m_Extent.x, 0.0f, car.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, 0.0f, box.m_Extent.z);
|
||||
glVertex3f(box.m_Extent.x, 0.0f, box.m_Extent.z);
|
||||
glVertex3f(box.m_Extent.x, 0.0f, -box.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, 0.0f, -box.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, 0.0f, box.m_Extent.z);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-car.m_Extent.x, car.m_Extent.y, car.m_Extent.z);
|
||||
glVertex3f(car.m_Extent.x, car.m_Extent.y, car.m_Extent.z);
|
||||
glVertex3f(car.m_Extent.x, car.m_Extent.y, -car.m_Extent.z);
|
||||
glVertex3f(-car.m_Extent.x, car.m_Extent.y, -car.m_Extent.z);
|
||||
glVertex3f(-car.m_Extent.x, car.m_Extent.y, car.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, box.m_Extent.y, box.m_Extent.z);
|
||||
glVertex3f(box.m_Extent.x, box.m_Extent.y, box.m_Extent.z);
|
||||
glVertex3f(box.m_Extent.x, box.m_Extent.y, -box.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, box.m_Extent.y, -box.m_Extent.z);
|
||||
glVertex3f(-box.m_Extent.x, box.m_Extent.y, box.m_Extent.z);
|
||||
glEnd();
|
||||
}
|
||||
if (getDrawTexBorder()) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
void SpriteManager::drawTextureOutline(const float & w, const float & h) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor3f(float(202)/255.0f, float(31)/255.0f, float(123)/255.0f);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
@ -199,14 +311,12 @@ namespace OpenGTA {
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glEnd();
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
}
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
void SpriteManager::draw(SpriteObject & obj) {
|
||||
if (obj.sprType == GraphicsBase::SpriteNumbers::EX) {
|
||||
return drawExplosion(obj);
|
||||
}
|
||||
|
||||
void SpriteManager::drawObject(GameObject & obj) {
|
||||
GL_OBJ_COMMON(obj);
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
OpenGL::PagedTexture t;
|
||||
@ -224,78 +334,30 @@ namespace OpenGTA {
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame,
|
||||
obj.sprType, obj.remap);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(w/2, 0.0f, h/2);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(w/2, 0.0f, -h/2);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
DRAW_TEX_QUADS_OBJ(t, w, h);
|
||||
|
||||
glEnd();
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (getDrawBBox()) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-obj.m_Extent.x, 0.0f, obj.m_Extent.z);
|
||||
glVertex3f(obj.m_Extent.x, 0.0f, obj.m_Extent.z);
|
||||
glVertex3f(obj.m_Extent.x, 0.0f, -obj.m_Extent.z);
|
||||
glVertex3f(-obj.m_Extent.x, 0.0f, -obj.m_Extent.z);
|
||||
glVertex3f(-obj.m_Extent.x, 0.0f, obj.m_Extent.z);
|
||||
glEnd();
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-obj.m_Extent.x, obj.m_Extent.y, obj.m_Extent.z);
|
||||
glVertex3f(obj.m_Extent.x, obj.m_Extent.y, obj.m_Extent.z);
|
||||
glVertex3f(obj.m_Extent.x, obj.m_Extent.y, -obj.m_Extent.z);
|
||||
glVertex3f(-obj.m_Extent.x, obj.m_Extent.y, -obj.m_Extent.z);
|
||||
glVertex3f(-obj.m_Extent.x, obj.m_Extent.y, obj.m_Extent.z);
|
||||
glEnd();
|
||||
}
|
||||
if (getDrawTexBorder()) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor3f(float(202)/255.0f, float(31)/255.0f, float(123)/255.0f);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glEnd();
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
|
||||
if (getDrawBBox())
|
||||
drawBBoxOutline(obj);
|
||||
if (getDrawTexBorder())
|
||||
drawTextureOutline(w, h);
|
||||
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteManager::drawPed(Pedestrian & ped) {
|
||||
void SpriteManager::draw(Pedestrian & ped) {
|
||||
GL_OBJ_COMMON(ped);
|
||||
/*
|
||||
GL_CHECKERROR;
|
||||
glPushMatrix();
|
||||
glTranslatef(ped.pos.x, ped.pos.y, ped.pos.z);
|
||||
glRotatef(ped.rot, 0, 1, 0);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, *ped.m_M.m);
|
||||
|
||||
|
||||
|
||||
for (int i=0; i < 4; i++) {
|
||||
for (int j=0; j <4 ;j++) {
|
||||
std::cout << ped.m_M.m[i][j] << " ";
|
||||
}
|
||||
std::cout << std::endl;
|
||||
}
|
||||
std::cout << std::endl;
|
||||
*/
|
||||
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
|
||||
|
||||
OpenGL::PagedTexture t;
|
||||
PHYSFS_uint16 sprNum = style.spriteNumbers.reIndex(ped.sprNum +
|
||||
ped.anim.firstFrameOffset + ped.anim.currentFrame, ped.sprType);
|
||||
@ -305,7 +367,6 @@ namespace OpenGTA {
|
||||
float w = float(info->w) / 64.0f;
|
||||
float h = float(info->h) / 64.0f;
|
||||
|
||||
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum, ped.remap))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum, ped.remap);
|
||||
else {
|
||||
@ -313,6 +374,170 @@ namespace OpenGTA {
|
||||
ped.anim.firstFrameOffset + ped.anim.currentFrame,
|
||||
ped.sprType, ped.remap);
|
||||
}
|
||||
|
||||
DRAW_TEX_QUADS_OBJ(t, w, h);
|
||||
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
|
||||
if (getDrawBBox())
|
||||
drawBBoxOutline(ped);
|
||||
if (getDrawTexBorder())
|
||||
drawTextureOutline(w, h);
|
||||
|
||||
if (getDrawBBox() || getDrawTexBorder())
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
|
||||
void SpriteManager::drawExplosion(SpriteObject & obj) {
|
||||
|
||||
if (obj.anim.get() == Util::Animation::STOPPED) {
|
||||
obj.isActive = false;
|
||||
return;
|
||||
}
|
||||
glPushMatrix();
|
||||
glTranslatef(obj.pos.x, obj.pos.y, obj.pos.z);
|
||||
//glRotatef(obj.rot, 0, 1, 0);
|
||||
glGetFloatv(GL_MODELVIEW_MATRIX, *obj.m_M.m);
|
||||
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
|
||||
PHYSFS_uint16 sprNum = style.spriteNumbers.reIndex(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame, obj.sprType);
|
||||
|
||||
GraphicsBase::SpriteInfo * info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
float w = float(info->w) / 64.0f;
|
||||
float h = float(info->h) / 64.0f;
|
||||
OpenGL::PagedTexture t;
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum);
|
||||
else
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame, obj.sprType, -1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(-w, 0.0f, 0.0f);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(0.0f, 0.0f, -h);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(-w, 0.0f, -h);
|
||||
|
||||
glEnd();
|
||||
|
||||
sprNum = style.spriteNumbers.reIndex(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame + 12, obj.sprType);
|
||||
info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
w = float(info->w) / 64.0f;
|
||||
h = float(info->h) / 64.0f;
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum);
|
||||
else
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame+12, obj.sprType, -1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(w, 0.0f, 0.0f);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(w, 0.0f, -h);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(0.0f, 0.0f, -h);
|
||||
|
||||
glEnd();
|
||||
|
||||
sprNum = style.spriteNumbers.reIndex(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame + 24, obj.sprType);
|
||||
info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
w = float(info->w) / 64.0f;
|
||||
h = float(info->h) / 64.0f;
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum);
|
||||
else
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame+24, obj.sprType, -1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(-w, 0.0f, 0.0f+h);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f+h);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(0.0f, 0.0f, -h+h);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(-w, 0.0f, -h+h);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
sprNum = style.spriteNumbers.reIndex(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame + 36, obj.sprType);
|
||||
info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
w = float(info->w) / 64.0f;
|
||||
h = float(info->h) / 64.0f;
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum);
|
||||
else
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(obj.sprNum +
|
||||
obj.anim.firstFrameOffset + obj.anim.currentFrame+36, obj.sprType, -1);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[1].v);
|
||||
glVertex3f(0.0f, 0.0f, 0.0f+h);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[1].v);
|
||||
glVertex3f(w, 0.0f, 0.0f+h);
|
||||
glTexCoord2f(t.coords[1].u, t.coords[0].v);
|
||||
glVertex3f(w, 0.0f, -h+h);
|
||||
glTexCoord2f(t.coords[0].u, t.coords[0].v);
|
||||
glVertex3f(0.0f, 0.0f, -h+h);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
void SpriteManager::draw(TrainSegment & train) {
|
||||
GL_OBJ_COMMON(train);
|
||||
GraphicsBase & style = StyleHolder::Instance().get();
|
||||
|
||||
OpenGL::PagedTexture t;
|
||||
PHYSFS_uint16 sprNum = style.spriteNumbers.reIndex(train.sprNum, train.sprType);
|
||||
|
||||
GraphicsBase::SpriteInfo * info = style.getSprite(sprNum);
|
||||
assert(info);
|
||||
float w = float(info->w) / 64.0f;
|
||||
float h = float(info->h) / 64.0f;
|
||||
|
||||
|
||||
if (OpenGL::SpriteCacheHolder::Instance().has(sprNum, train.remap))
|
||||
t = OpenGL::SpriteCacheHolder::Instance().get(sprNum, train.remap);
|
||||
else {
|
||||
t = OpenGL::SpriteCacheHolder::Instance().create(train.sprNum, train.sprType, -1);
|
||||
}
|
||||
glBindTexture(GL_TEXTURE_2D, t.inPage);
|
||||
|
||||
glBegin(GL_QUADS);
|
||||
@ -326,33 +551,38 @@ namespace OpenGTA {
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
|
||||
glEnd();
|
||||
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
*/
|
||||
|
||||
void SpriteManager::draw(Projectile & proj) {
|
||||
//GL_OBJ_COMMON(proj); // can't use; not derived from OBox
|
||||
const float w = 0.05f;
|
||||
const float h = 0.05f;
|
||||
|
||||
glPushMatrix(); \
|
||||
glTranslatef(proj.pos.x, proj.pos.y, proj.pos.z); \
|
||||
glRotatef(proj.rot, 0, 1, 0);
|
||||
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
if (getDrawBBox()) {
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glVertex3f(-ped.m_Extent.x, 0.0f, ped.m_Extent.z);
|
||||
glVertex3f(ped.m_Extent.x, 0.0f, ped.m_Extent.z);
|
||||
glVertex3f(ped.m_Extent.x, 0.0f, -ped.m_Extent.z);
|
||||
glVertex3f(-ped.m_Extent.x, 0.0f, -ped.m_Extent.z);
|
||||
glVertex3f(-ped.m_Extent.x, 0.0f, ped.m_Extent.z);
|
||||
glEnd();
|
||||
}
|
||||
if (getDrawTexBorder()) {
|
||||
glDisable(GL_TEXTURE_2D);
|
||||
glBegin(GL_LINE_STRIP);
|
||||
glColor3f(float(202)/255.0f, float(31)/255.0f, float(123)/255.0f);
|
||||
glBegin(GL_QUADS);
|
||||
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, h/2);
|
||||
glVertex3f(w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, -h/2);
|
||||
glVertex3f(-w/2, 0.0f, h/2);
|
||||
|
||||
glEnd();
|
||||
glColor3f(1.0f, 1.0f, 1.0f);
|
||||
}
|
||||
glEnable(GL_TEXTURE_2D);
|
||||
|
||||
glPopMatrix();
|
||||
GL_CHECKERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
void SpriteManager::addPed(Pedestrian & ped) {
|
||||
activePeds.push_back(ped);
|
||||
@ -369,6 +599,17 @@ namespace OpenGTA {
|
||||
return *activePeds.begin();
|
||||
}
|
||||
|
||||
TrainSegment & SpriteManager::getTrainById(const Uint32 & id) {
|
||||
TrainListType::iterator i = activeTrains.begin();
|
||||
while (i != activeTrains.end()) {
|
||||
if (i->trainId == id)
|
||||
return *i;
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activeTrains.begin();
|
||||
}
|
||||
|
||||
void SpriteManager::removePedById(const Uint32 & id) {
|
||||
PedListType::iterator i = activePeds.begin();
|
||||
while (i != activePeds.end()) {
|
||||
@ -402,28 +643,46 @@ namespace OpenGTA {
|
||||
activeObjects.push_back(go);
|
||||
}
|
||||
|
||||
void SpriteManager::createExplosion(Vector3D center) {
|
||||
GameObject exp(center, 0, GraphicsBase::SpriteNumbers::EX);
|
||||
exp.anim = SpriteObject::Animation(getAnimationById(99));
|
||||
exp.anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::LOOP);
|
||||
INFO << exp.anim.currentFrame << " " << exp.anim.numFrames << " " << exp.anim.delay << std::endl;
|
||||
activeObjects.push_back(exp);
|
||||
}
|
||||
|
||||
GameObject & SpriteManager::getObjectById(const Uint32 & id) {
|
||||
ObjectListType::iterator i = activeObjects.begin();
|
||||
while (i != activeObjects.end()) {
|
||||
while (i != activeObjects.end()) {
|
||||
if (i->objId == id) {
|
||||
return *i;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
assert(0);
|
||||
return *activeObjects.begin();
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return *activeObjects.begin();
|
||||
}
|
||||
*/
|
||||
|
||||
SpriteObject::Animation & SpriteManager::getAnimationById(const Uint32 & id) {
|
||||
void SpriteManager::removeDeadStuff() {
|
||||
AbstractContainer<Pedestrian>::doRealRemove();
|
||||
AbstractContainer<Car>::doRealRemove();
|
||||
AbstractContainer<SpriteObject>::doRealRemove();
|
||||
}
|
||||
|
||||
SpriteObject::Animation & SpriteManager::getAnimationById(const Uint32 & id) {
|
||||
AnimLookupType::iterator i = animations.find(id);
|
||||
assert(i != animations.end());
|
||||
return i->second;
|
||||
if (i == animations.end()) {
|
||||
ERROR << "Failed to find anim id: " << id << std::endl;
|
||||
return animations.begin()->second;
|
||||
}
|
||||
return i->second;
|
||||
}
|
||||
|
||||
void SpriteManager::registerAnimation(const Uint32 & id,
|
||||
void SpriteManager::registerAnimation(const Uint32 & id,
|
||||
const SpriteObject::Animation & anim) {
|
||||
animations.insert(std::make_pair<Uint32, SpriteObject::Animation>(id, anim));
|
||||
}
|
||||
}
|
||||
|
||||
void SpriteManager::setDrawBBox(bool v) {
|
||||
if (v)
|
||||
@ -439,10 +698,18 @@ namespace OpenGTA {
|
||||
drawMode = (drawMode & 2 ? drawMode - 2 : drawMode);
|
||||
}
|
||||
|
||||
void SpriteManager::setDrawTexture(bool v) {
|
||||
}
|
||||
|
||||
void SpriteManager::createProjectile(uint8_t typeId, float r, Vector3D p, Vector3D d, Uint32 & ticks) {
|
||||
activeProjectiles.push_back(Projectile(typeId, r, p, d, ticks));
|
||||
}
|
||||
void SpriteManager::setDrawTexture(bool v) {
|
||||
}
|
||||
|
||||
void SpriteManager::createProjectile(uint8_t typeId, float r, Vector3D p, Vector3D d, Uint32 & ticks, Uint32 & owner) {
|
||||
activeProjectiles.push_back(Projectile(typeId, r, p, d, ticks, owner));
|
||||
}
|
||||
|
||||
void SpriteManager::createExplosion(Vector3D center) {
|
||||
SpriteObject expl(center, 0, GraphicsBase::SpriteNumbers::EX);
|
||||
expl.anim = SpriteObject::Animation(getAnimationById(99));
|
||||
expl.anim.set(Util::Animation::PLAY_FORWARD, Util::Animation::STOP);
|
||||
add(expl);
|
||||
}
|
||||
|
||||
}
|
||||
|
107
spritemanager.h
107
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 *
|
||||
* warranty. In no event will the authors be held liable for any *
|
||||
@ -25,10 +25,16 @@
|
||||
|
||||
#include <list>
|
||||
#include <map>
|
||||
#include "pedestrian.h"
|
||||
#include "abstract_container.h"
|
||||
//#include "pedestrian.h"
|
||||
#include "game_objects.h"
|
||||
#include "Singleton.h"
|
||||
#include "train_system.h"
|
||||
#include "map_helper.h"
|
||||
|
||||
namespace OpenGTA {
|
||||
|
||||
#if 0
|
||||
class SpriteManager {
|
||||
public:
|
||||
SpriteManager();
|
||||
@ -62,11 +68,17 @@ namespace OpenGTA {
|
||||
void drawPed(Pedestrian & ped);
|
||||
void drawCar(Car & car);
|
||||
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 createExplosion(Vector3D center);
|
||||
void drawProjectile(Projectile & p);
|
||||
void collideProjectile(Projectile & p);
|
||||
|
||||
typedef std::list<TrainSegment> TrainListType;
|
||||
protected:
|
||||
typedef std::list<Pedestrian> PedListType;
|
||||
PedListType activePeds;
|
||||
@ -76,11 +88,102 @@ namespace OpenGTA {
|
||||
ObjectListType activeObjects;
|
||||
typedef std::list<Projectile> ProjectileListType;
|
||||
ProjectileListType activeProjectiles;
|
||||
TrainListType activeTrains;
|
||||
public:
|
||||
TrainSystem trainSystem;
|
||||
protected:
|
||||
typedef std::map<Uint32, SpriteObject::Animation> AnimLookupType;
|
||||
AnimLookupType animations;
|
||||
private:
|
||||
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,
|
||||
Loki::DefaultLifetime, Loki::SingleThreaded> SpriteManagerHolder;
|
||||
|
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>
|
||||
#define USE_RWOPS
|
||||
#include <SDL_sound.h>
|
||||
#include <SDL_mixer.h>
|
||||
#include <string>
|
||||
@ -69,7 +70,15 @@ void SoundDevice::open(int r, Uint16 f, int c, int bs) {
|
||||
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) {
|
||||
int i,act=0;
|
||||
Sint16 *ptr2;
|
||||
@ -123,15 +132,84 @@ void myMusicPlayer(void *udata, Uint8 *stream, int len) {
|
||||
for(i=0;i<len;i++) stream[i]=0;
|
||||
} /* if */
|
||||
} /* myMusicPlayer */
|
||||
#endif
|
||||
|
||||
#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[])
|
||||
{
|
||||
PHYSFS_init(argv[0]);
|
||||
PHYSFS_addToSearchPath("gtadata.zip", 1);
|
||||
PHYSFS_addToSearchPath(PHYSFS_getBaseDir(), 1);
|
||||
|
||||
Uint32 sdl_init_flags = SDL_INIT_AUDIO | SDL_INIT_VIDEO;
|
||||
if (SDL_Init(sdl_init_flags) == -1)
|
||||
@ -143,11 +221,16 @@ int main(int argc, char *argv[])
|
||||
SoundDevice dev;
|
||||
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::Entry & e = db.getEntry(atoi(argv[2]));
|
||||
unsigned char* mem = db.getBuffered(atoi(argv[2]));
|
||||
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);
|
||||
|
||||
@ -161,13 +244,40 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
delete [] mem;
|
||||
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);
|
||||
}
|
||||
delete [] mem2;
|
||||
//delete [] mem2;
|
||||
Mix_HaltMusic();
|
||||
Mix_FreeChunk(music);
|
||||
//Mix_FreeChunk(music);
|
||||
//music = NULL;
|
||||
SDL_Quit();
|
||||
return(0);
|
||||
|
@ -8,4 +8,5 @@ if [ $# -gt 0 ]; then
|
||||
fi
|
||||
sed '1{h; r $1
|
||||
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 j = 0; j < 256; j++) {
|
||||
PHYSFS_uint16 emptycount = map.getNumBlocksAt(j,i);
|
||||
PHYSFS_uint16 emptycount = map.getNumBlocksAtNew(j,i);
|
||||
int found_type = 0;
|
||||
for (int c=6-emptycount; c > 0; c--) {
|
||||
OpenGTA::Map::BlockInfo* bi = map.getBlockAt(j, i, c);
|
||||
//for (int c=6-emptycount; c > 0; c--) {
|
||||
for (int c = 0; c < emptycount ; ++c) {
|
||||
OpenGTA::Map::BlockInfo* bi = map.getBlockAtNew(j, i, c);
|
||||
/*
|
||||
if (bi->blockType() > 0)
|
||||
found_type = bi->blockType();
|
||||
@ -83,10 +84,12 @@ int main(int argc, char* argv[]) {
|
||||
if (bi->railEndTurn())
|
||||
std::cout << " end: " << i << ", " << j << std::endl;
|
||||
*/
|
||||
/*
|
||||
if (bi->blockType() > 0)
|
||||
found_type = bi->blockType();
|
||||
if (bi->trafficLights())
|
||||
found_type = 0;
|
||||
*/
|
||||
if (bi->railway())
|
||||
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 "animation.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
|
||||
#define UTIL_ANIMATION_H
|
||||
#include <vector>
|
||||
@ -6,6 +28,13 @@
|
||||
|
||||
namespace Util {
|
||||
|
||||
/** 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:
|
||||
typedef enum {
|
||||
@ -23,7 +52,8 @@ namespace Util {
|
||||
Animation(const Animation & o);
|
||||
inline const uint16_t & getCurrentFrameNumber() { return currentFrame; }
|
||||
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 update(const uint32_t & nowTicks);
|
||||
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 <physfs.h>
|
||||
#include <sstream>
|
||||
#include "m_exceptions.h"
|
||||
#include "file_helper.h"
|
||||
#include "buffercache.h"
|
||||
|
||||
#ifndef OGTA_DEFAULT_DATA_PATH
|
||||
#define OGTA_DEFAULT_DATA_PATH "gtadata.zip"
|
||||
@ -10,12 +33,14 @@
|
||||
#ifndef OGTA_DEFAULT_MOD_PATH
|
||||
#define OGTA_DEFAULT_MOD_PATH ""
|
||||
#endif
|
||||
|
||||
#ifndef OGTA_DEFAULT_HOME_PATH
|
||||
#ifdef LINUX
|
||||
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getUserDir()
|
||||
#elif WIN32
|
||||
#define OGTA_DEFAULT_HOME_PATH "config"
|
||||
#endif
|
||||
//#ifdef LINUX
|
||||
//#define OGTA_DEFAULT_HOME_PATH PHYSFS_getUserDir()
|
||||
//#elif WIN32
|
||||
//#define OGTA_DEFAULT_HOME_PATH "config"
|
||||
//#endif
|
||||
#define OGTA_DEFAULT_HOME_PATH PHYSFS_getBaseDir()
|
||||
#endif
|
||||
|
||||
namespace Util {
|
||||
@ -83,4 +108,13 @@ namespace Util {
|
||||
// take this one instead
|
||||
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
|
||||
#define UTIL_FILEHELPER_H
|
||||
|
||||
@ -17,6 +39,7 @@ namespace Util {
|
||||
bool existsInSystemFS(const std::string & file) const;
|
||||
bool existsInVFS(const std::string & file) const;
|
||||
PHYSFS_file* openReadVFS(const std::string & file) const;
|
||||
unsigned char* bufferFromVFS(PHYSFS_file*) const;
|
||||
private:
|
||||
std::string baseDataPath;
|
||||
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