1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-22 02:12:45 +01:00

Cleanup headers of rwengine

This commit is contained in:
Filip Gawin 2018-12-10 01:51:05 +01:00
parent c03fbf79f8
commit dd8de77b8e
98 changed files with 984 additions and 1066 deletions

View File

@ -2,7 +2,6 @@
#define _LIBRW_TYPES_HPP_
#include <cstdint>
#include <glm/glm.hpp>
#include <map>
#include <memory>
#include <rw/debug.hpp>

View File

@ -16,6 +16,7 @@ set(RWENGINE_SOURCES
src/audio/alCheck.hpp
src/audio/SfxParameters.cpp
src/audio/SfxParameters.hpp
src/audio/Sound.cpp
src/audio/Sound.hpp
src/audio/SoundBuffer.cpp
src/audio/SoundBuffer.hpp
@ -34,6 +35,7 @@ set(RWENGINE_SOURCES
src/data/Chase.cpp
src/data/Chase.hpp
src/data/CollisionModel.hpp
src/data/CutsceneData.cpp
src/data/CutsceneData.hpp
src/data/InstanceData.hpp
src/data/ModelData.cpp
@ -45,6 +47,7 @@ set(RWENGINE_SOURCES
src/data/WeaponData.hpp
src/data/Weather.cpp
src/data/Weather.hpp
src/data/ZoneData.cpp
src/data/ZoneData.hpp
src/dynamics/CollisionInstance.cpp
@ -122,6 +125,7 @@ set(RWENGINE_SOURCES
src/render/TextRenderer.cpp
src/render/TextRenderer.hpp
src/render/ViewCamera.hpp
src/render/ViewFrustum.cpp
src/render/ViewFrustum.hpp
src/render/VisualFX.cpp
src/render/VisualFX.hpp

View File

@ -11,6 +11,8 @@
#include <rw/debug.hpp>
#include <rw/types.hpp>
namespace ai {
void AIGraph::createPathNodes(const glm::vec3& position,
const glm::quat& rotation, PathData& path) {
auto startIndex = static_cast<std::uint32_t>(nodes.size());
@ -38,8 +40,8 @@ void AIGraph::createPathNodes(const glm::vec3& position,
auto ptr = ainode.get();
ainode->type =
(path.type == PathData::PATH_PED ? AIGraphNode::Pedestrian
: AIGraphNode::Vehicle);
(path.type == PathData::PATH_PED ? NodeType::Pedestrian
: NodeType::Vehicle);
ainode->nextIndex = node.next >= 0 ? startIndex + node.next : -1;
ainode->flags = AIGraphNode::None;
ainode->size = node.size;
@ -95,7 +97,7 @@ glm::ivec2 worldToGrid(const glm::vec2& world) {
void AIGraph::gatherExternalNodesNear(const glm::vec3& center,
const float radius,
std::vector<AIGraphNode*>& nodes,
AIGraphNode::NodeType type) {
NodeType type) {
// the bounds end up covering more than might fit
auto planecoords = glm::vec2(center);
auto minWorld = planecoords - glm::vec2(radius);
@ -119,3 +121,5 @@ void AIGraph::gatherExternalNodesNear(const glm::vec3& center,
}
}
}
} // namespace ai

View File

@ -1,17 +1,20 @@
#ifndef _RWENGINE_AIGRAPH_HPP_
#define _RWENGINE_AIGRAPH_HPP_
#include <array>
#include <vector>
#include <glm/glm.hpp>
#include "ai/AIGraphNode.hpp"
#include <glm/gtc/quaternion.hpp>
#include <rw/types.hpp>
struct AIGraphNode;
#include <array>
#include <vector>
struct PathData;
namespace ai {
enum class NodeType;
struct AIGraphNode;
class AIGraph {
public:
~AIGraph() = default;
@ -34,7 +37,9 @@ public:
PathData& path);
void gatherExternalNodesNear(const glm::vec3& center, const float radius,
std::vector<AIGraphNode*>& nodes, AIGraphNode::NodeType type);
std::vector<AIGraphNode*>& nodes, NodeType type);
};
} // ai
#endif

View File

@ -1,12 +1,16 @@
#ifndef _RWENGINE_AIGRAPHNODE_HPP_
#define _RWENGINE_AIGRAPHNODE_HPP_
#include <glm/vec3.hpp>
#include <cstdint>
#include <glm/glm.hpp>
#include <vector>
struct AIGraphNode {
enum NodeType { Vehicle, Pedestrian };
namespace ai {
enum class NodeType { Vehicle, Pedestrian };
struct AIGraphNode {
enum {
None = 0,
CrossesRoad =
@ -28,4 +32,6 @@ struct AIGraphNode {
std::vector<AIGraphNode*> connections;
};
} // namespace ai
#endif

View File

@ -21,6 +21,8 @@
#include <rw/debug.hpp>
#include <dynamics/HitTest.hpp>
#include "ai/CharacterController.hpp"
#include "ai/AIGraphNode.hpp"
#include "data/WeaponData.hpp"
#include "engine/Animator.hpp"
#include "engine/GameData.hpp"
@ -31,6 +33,8 @@
constexpr float kCloseDoorIdleTime = 2.f;
namespace ai {
bool CharacterController::updateActivity() {
if (_currentActivity && character->isAlive()) {
return _currentActivity->update(character, this);
@ -731,3 +735,5 @@ bool Activities::UseItem::update(CharacterObject *character,
return false;
}
} // namespace ai

View File

@ -1,14 +1,19 @@
#ifndef _RWENGINE_CHARACTERCONTROLLER_HPP_
#define _RWENGINE_CHARACTERCONTROLLER_HPP_
#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <memory>
#include <string>
struct AIGraphNode;
class CharacterObject;
class VehicleObject;
namespace ai {
struct AIGraphNode;
/**
* @class CharacterController
* Character Controller Interface, translates high-level behaviours into low
@ -59,11 +64,6 @@ public:
};
protected:
/**
* The character being controlled.
*/
CharacterObject* character = nullptr;
std::unique_ptr<Activity> _currentActivity = nullptr;
std::unique_ptr<Activity> _nextActivity = nullptr;
@ -80,6 +80,10 @@ protected:
CharacterObject* leader = nullptr;
public:
/**
* The character being controlled.
*/
CharacterObject* character = nullptr;
AIGraphNode* targetNode;
AIGraphNode* lastTargetNode;
@ -294,4 +298,6 @@ struct UseItem : public CharacterController::Activity {
};
}
} // ai
#endif

View File

@ -11,6 +11,8 @@
#include "objects/CharacterObject.hpp"
#include "objects/VehicleObject.hpp"
namespace ai {
glm::vec3 DefaultAIController::getTargetPosition() {
/*if(targetNode) {
if(lastNode && character->getCurrentVehicle()) {
@ -79,7 +81,7 @@ void DefaultAIController::update(float dt) {
AIGraphNode* node = nullptr;
float mindist = std::numeric_limits<float>::max();
for (const auto& n : graph.nodes) {
if (n->type != AIGraphNode::Pedestrian) {
if (n->type != ai::NodeType::Pedestrian) {
continue;
}
@ -182,7 +184,7 @@ void DefaultAIController::update(float dt) {
for (const auto& n : graph.nodes) {
// No vehicle node, continue
if (n->type != AIGraphNode::Vehicle) {
if (n->type != ai::NodeType::Vehicle) {
continue;
}
@ -216,3 +218,5 @@ void DefaultAIController::update(float dt) {
CharacterController::update(dt);
}
} // namespace ai

View File

@ -1,14 +1,17 @@
#ifndef _RWENGINE_DEFAULTAICONTROLLER_HPP_
#define _RWENGINE_DEFAULTAICONTROLLER_HPP_
#include <glm/glm.hpp>
#include <ai/CharacterController.hpp>
#include <glm/vec3.hpp>
#include "ai/CharacterController.hpp"
namespace ai {
class DefaultAIController final : public CharacterController {
glm::vec3 gotoPos{};
public:
DefaultAIController()
: CharacterController() {
DefaultAIController() : CharacterController() {
}
glm::vec3 getTargetPosition() override;
@ -16,4 +19,6 @@ public:
void update(float dt) override;
};
} // namespace ai
#endif

View File

@ -13,6 +13,8 @@
class Animator;
namespace ai {
void PlayerController::setInputEnabled(bool enabled) {
_enabled = enabled;
}
@ -358,3 +360,5 @@ void PlayerController::freeFromCutscene() {
// @todo: make player no longer invincible
// ignored by police
}
} // namespace ai

View File

@ -1,10 +1,12 @@
#ifndef _RWENGINE_PLAYERCONTROLLER_HPP_
#define _RWENGINE_PLAYERCONTROLLER_HPP_
#include <ai/CharacterController.hpp>
#include <glm/glm.hpp>
#include "ai/CharacterController.hpp"
#include <glm/gtc/quaternion.hpp>
namespace ai {
class PlayerController final : public CharacterController {
private:
glm::quat cameraRotation{1.0f, 0.0f, 0.0f, 0.0f};
@ -94,7 +96,7 @@ public:
bool isAdrenalineActive() {
return adrenalineEffect;
};
}
void activateAdrenalineEffect();
@ -108,4 +110,6 @@ public:
}
};
} // namespace ai
#endif

View File

@ -24,19 +24,21 @@
#include <rw_mingw.hpp>
#endif
namespace ai {
TrafficDirector::TrafficDirector(AIGraph* g, GameWorld* w)
: graph(g)
, world(w) {
}
std::vector<AIGraphNode*> TrafficDirector::findAvailableNodes(
AIGraphNode::NodeType type, const ViewCamera& camera, float radius) {
std::vector<AIGraphNode*> available;
std::vector<ai::AIGraphNode*> TrafficDirector::findAvailableNodes(
ai::NodeType type, const ViewCamera& camera, float radius) {
std::vector<ai::AIGraphNode*> available;
available.reserve(20);
graph->gatherExternalNodesNear(camera.position, radius, available, type);
float density = type == AIGraphNode::Vehicle ? carDensity : pedDensity;
float density = type == ai::NodeType::Vehicle ? carDensity : pedDensity;
float minDist = (15.f / density) * (15.f / density);
float halfRadius2 = std::pow(radius / 2.f, 2.f);
@ -80,12 +82,12 @@ std::vector<AIGraphNode*> TrafficDirector::findAvailableNodes(
return available;
}
void TrafficDirector::setDensity(AIGraphNode::NodeType type, float density) {
void TrafficDirector::setDensity(ai::NodeType type, float density) {
switch (type) {
case AIGraphNode::Vehicle:
case ai::NodeType::Vehicle:
carDensity = density;
break;
case AIGraphNode::Pedestrian:
case ai::NodeType::Pedestrian:
pedDensity = density;
break;
}
@ -146,7 +148,7 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
111, 112, 116, 119, 128, 129, 130, 134, 135, 136, 138, 139, 144, 146
}};
auto availablePedsNodes = findAvailableNodes(AIGraphNode::Pedestrian, camera, radius);
auto availablePedsNodes = findAvailableNodes(ai::NodeType::Pedestrian, camera, radius);
// We have not reached the limit of spawned pedestrians
if (maximumPedestrians > world->pedestrianPool.objects.size()) {
@ -159,7 +161,7 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
}
for (AIGraphNode* spawn : availablePedsNodes) {
if (spawn->type != AIGraphNode::Pedestrian) {
if (spawn->type != ai::NodeType::Pedestrian) {
continue;
}
if (counter == 0) {
@ -178,7 +180,7 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
}
}
auto availableVehicleNodes = findAvailableNodes(AIGraphNode::Vehicle, camera, radius);
auto availableVehicleNodes = findAvailableNodes(ai::NodeType::Vehicle, camera, radius);
// We have not reached the limit of spawned vehicles
if (maximumCars > world->vehiclePool.objects.size()) {
@ -191,7 +193,7 @@ std::vector<GameObject*> TrafficDirector::populateNearby(
}
for (AIGraphNode* spawn : availableVehicleNodes) {
if (spawn->type != AIGraphNode::Vehicle) {
if (spawn->type != ai::NodeType::Vehicle) {
continue;
}
if (counter == 0) {
@ -265,3 +267,5 @@ void TrafficDirector::setPopulationLimits(int maxPeds, int maxCars) {
maximumPedestrians = maxPeds;
maximumCars = maxCars;
}
} // namespace ai

View File

@ -1,24 +1,27 @@
#ifndef _RWENGINE_TRAFFICDIRECTOR_HPP_
#define _RWENGINE_TRAFFICDIRECTOR_HPP_
#include "AIGraphNode.hpp"
#include <vector>
class AIGraph;
class GameObject;
class GameWorld;
class GameObject;
class ViewCamera;
namespace ai {
enum class NodeType;
class AIGraph;
struct AIGraphNode;
class TrafficDirector {
public:
TrafficDirector(AIGraph* graph, GameWorld* world);
std::vector<AIGraphNode*> findAvailableNodes(AIGraphNode::NodeType type,
std::vector<AIGraphNode*> findAvailableNodes(NodeType type,
const ViewCamera& camera,
float radius);
void setDensity(AIGraphNode::NodeType type, float density);
void setDensity(NodeType type, float density);
/**
* Creates new traffic at available locations.
@ -43,4 +46,6 @@ private:
size_t maximumCars = 10;
};
} // namespace ai
#endif

View File

@ -0,0 +1,51 @@
#include "audio/Sound.hpp"
#include "audio/SoundBuffer.hpp"
bool Sound::isPlaying() const {
return buffer->isPlaying();
}
bool Sound::isPaused() const {
return buffer->isPaused();
}
bool Sound::isStopped() const {
return buffer->isStopped();
}
void Sound::play() {
buffer->play();
}
void Sound::pause() {
buffer->pause();
}
void Sound::stop() {
buffer->stop();
}
void Sound::setPosition(const glm::vec3 &position) {
buffer->setPosition(position);
}
void Sound::setLooping(bool looping) {
buffer->setLooping(looping);
}
void Sound::setPitch(float pitch) {
buffer->setPitch(pitch);
}
void Sound::setGain(float gain) {
buffer->setGain(gain);
}
void Sound::setMaxDistance(float maxDist) {
buffer->setMaxDistance(maxDist);
}
size_t Sound::getScriptObjectID() const {
return id;
}

View File

@ -1,19 +1,12 @@
#ifndef _RWENGINE_SOUND_HPP_
#define _RWENGINE_SOUND_HPP_
#include <glm/vec3.hpp>
#include <memory>
#include <string>
#include <vector>
#include <al.h>
#include <alc.h>
#include <glm/glm.hpp>
#include <rw/filesystem.hpp>
#include <rw/types.hpp>
#include "audio/SoundBuffer.hpp"
#include "audio/SoundSource.hpp"
class SoundSource;
struct SoundBuffer;
/// Wrapper for SoundBuffer and SoundSource.
/// Each command connected
@ -26,52 +19,29 @@ struct Sound {
std::unique_ptr<SoundBuffer> buffer;
Sound() = default;
~Sound() = default;
bool isPlaying() const {
return buffer->isPlaying();
}
bool isPlaying() const;
bool isPaused() const {
return buffer->isPaused();
}
bool isStopped() const {
return buffer->isStopped();
}
bool isPaused() const;
bool isStopped() const;
void play() {
buffer->play();
}
void play();
void pause() {
buffer->pause();
}
void pause();
void stop() {
buffer->stop();
}
void stop();
void setPosition(const glm::vec3& position) {
buffer->setPosition(position);
}
void setPosition(const glm::vec3& position);
void setLooping(bool looping) {
buffer->setLooping(looping);
}
void setLooping(bool looping);
void setPitch(float pitch) {
buffer->setPitch(pitch);
}
void setPitch(float pitch);
void setGain(float gain) {
buffer->setGain(gain);
}
void setGain(float gain);
void setMaxDistance(float maxDist) {
buffer->setMaxDistance(maxDist);
}
void setMaxDistance(float maxDist);
size_t getScriptObjectID() const {
return id;
}
size_t getScriptObjectID() const;
};
#endif

View File

@ -3,6 +3,7 @@
#include <rw/types.hpp>
#include "audio/alCheck.hpp"
#include "audio/SoundSource.hpp"
SoundBuffer::SoundBuffer() {
alCheck(alGenSources(1, &source));

View File

@ -2,10 +2,9 @@
#define _RWENGINE_SOUND_BUFFER_HPP_
#include <al.h>
#include <alc.h>
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include "audio/SoundSource.hpp"
class SoundSource;
/// OpenAL tool for playing
/// sound instance.

View File

@ -8,6 +8,9 @@ extern "C" {
}
#include "audio/alCheck.hpp"
#include "audio/Sound.hpp"
#include "audio/SoundBuffer.hpp"
#include "audio/SoundSource.hpp"
#include "engine/GameData.hpp"
#include "engine/GameWorld.hpp"
#include "render/ViewCamera.hpp"

View File

@ -3,21 +3,16 @@
#include "audio/Sound.hpp"
#include <algorithm>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <unordered_map>
#include <vector>
#include <al.h>
#include <alc.h>
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <rw/filesystem.hpp>
#include <loaders/LoaderSDT.hpp>
#include <string>
#include <unordered_map>
class GameWorld;
class ViewCamera;

View File

@ -1,11 +1,12 @@
#ifndef _RWENGINE_SOUND_SOURCE_HPP_
#define _RWENGINE_SOUND_SOURCE_HPP_
#include <loaders/LoaderSDT.hpp>
#include <rw/filesystem.hpp>
#include <cstdint>
class LoaderSDT;
/// Opaque for raw sound,
/// cooperate with ffmpeg
/// (loading and decoding sound)

View File

@ -6,6 +6,8 @@
#include <rw/debug.hpp>
#include <glm/gtc/quaternion.hpp>
#include "engine/GameWorld.hpp"
#include "objects/GameObject.hpp"

View File

@ -1,8 +1,9 @@
#ifndef _RWENGINE_CHASE_HPP_
#define _RWENGINE_CHASE_HPP_
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp>
#include <string>
#include <unordered_map>
#include <vector>

View File

@ -1,7 +1,9 @@
#ifndef _RWENGINE_COLLISIONMODEL_HPP_
#define _RWENGINE_COLLISIONMODEL_HPP_
#include <glm/vec3.hpp>
#include <cstdint>
#include <glm/glm.hpp>
#include <string>
#include <vector>

View File

@ -0,0 +1,95 @@
#include "data/CutsceneData.hpp"
#include <glm/glm.hpp>
glm::vec3 CutsceneTracks::getPositionAt(float time) const {
glm::vec3 p = position.rbegin()->second;
for (auto it = position.begin(); it != position.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != position.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
p = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
p = glm::mix(a, b, fac);
}
}
}
return p;
}
glm::vec3 CutsceneTracks::getTargetAt(float time) const {
glm::vec3 p = position.rbegin()->second;
for (auto it = target.begin(); it != target.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != target.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
p = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
p = glm::mix(a, b, fac);
}
}
}
return p;
}
float CutsceneTracks::getZoomAt(float time) const {
float r = zoom.rbegin()->second;
for (auto it = zoom.begin(); it != zoom.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != zoom.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
r = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
r = glm::mix(a, b, fac);
}
}
}
return r;
}
float CutsceneTracks::getRotationAt(float time) const {
float r = rotation.rbegin()->second;
for (auto it = rotation.begin(); it != rotation.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != rotation.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
r = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
r = glm::mix(a, b, fac);
}
}
}
return r;
}

View File

@ -1,6 +1,8 @@
#ifndef _RWENGINE_CUTSCENEDATA_HPP_
#define _RWENGINE_CUTSCENEDATA_HPP_
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <map>
#include <string>
#include <vector>
@ -39,97 +41,13 @@ struct CutsceneTracks {
float duration{0.f};
glm::vec3 getPositionAt(float time) const {
glm::vec3 p = position.rbegin()->second;
for (auto it = position.begin(); it != position.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != position.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
p = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
p = glm::mix(a, b, fac);
}
}
}
return p;
}
glm::vec3 getPositionAt(float time) const;
glm::vec3 getTargetAt(float time) const {
glm::vec3 p = position.rbegin()->second;
for (auto it = target.begin(); it != target.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != target.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
p = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
p = glm::mix(a, b, fac);
}
}
}
return p;
}
glm::vec3 getTargetAt(float time) const;
float getZoomAt(float time) const {
float r = zoom.rbegin()->second;
for (auto it = zoom.begin(); it != zoom.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != zoom.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
r = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
r = glm::mix(a, b, fac);
}
}
}
return r;
}
float getZoomAt(float time) const;
float getRotationAt(float time) const {
float r = rotation.rbegin()->second;
for (auto it = rotation.begin(); it != rotation.end(); ++it) {
if (it->first <= time) {
auto a = it->second;
auto b = it->second;
auto nextIt = it;
float t = it->first;
if (++nextIt != rotation.end()) {
b = nextIt->second;
t = nextIt->first;
}
float tdiff = t - it->first;
r = b;
if (tdiff > 0.f) {
float fac = (time - it->first) / tdiff;
r = glm::mix(a, b, fac);
}
}
}
return r;
}
float getRotationAt(float time) const;
};
struct CutsceneData {

View File

@ -1,7 +1,9 @@
#ifndef _RWENGINE_INSTANCEDATA_HPP_
#define _RWENGINE_INSTANCEDATA_HPP_
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp>
#include <string>
struct InstanceData {

View File

@ -1,5 +1,16 @@
#include "data/ModelData.hpp"
#include "data/CollisionModel.hpp"
#include "data/PathData.hpp"
SimpleModelInfo::SimpleModelInfo() : BaseModelInfo(kType) {
}
SimpleModelInfo::SimpleModelInfo(ModelDataType type) : BaseModelInfo(type) {
}
SimpleModelInfo::~SimpleModelInfo() = default;
void SimpleModelInfo::setupBigBuilding(const ModelInfoTable& models) {
if (loddistances_[0] > 300.f && atomics_[2] == nullptr) {
isbigbuilding_ = true;
@ -23,3 +34,12 @@ void SimpleModelInfo::findRelatedModel(const ModelInfoTable& models) {
}
}
}
BaseModelInfo::BaseModelInfo(ModelDataType type) : type_(type) {
}
void BaseModelInfo::setCollisionModel(std::unique_ptr<CollisionModel> &col) {
collision = std::move(col);
}
BaseModelInfo::~BaseModelInfo() = default;

View File

@ -1,8 +1,15 @@
#ifndef _RWENGINE_MODELDATA_HPP_
#define _RWENGINE_MODELDATA_HPP_
#include <rw/debug.hpp>
#include <rw/forward.hpp>
#ifdef RW_WINDOWS
#include <rw_mingw.hpp>
#endif
#include <array>
#include <cstdint>
#include <glm/glm.hpp>
#include <memory>
#include <string>
#include <unordered_map>
@ -10,15 +17,8 @@
#include <utility>
#include <vector>
#include <data/Clump.hpp>
#include <rw/debug.hpp>
#include <rw/forward.hpp>
#include <data/CollisionModel.hpp>
#include <data/PathData.hpp>
#ifdef RW_WINDOWS
#include <rw_mingw.hpp>
#endif
struct CollisionModel;
struct PathData;
/**
* 16-bit model ID identifier (from .ide)
@ -47,10 +47,9 @@ public:
std::string name;
std::string textureslot;
BaseModelInfo(ModelDataType type) : type_(type) {
}
BaseModelInfo(ModelDataType type);
virtual ~BaseModelInfo() = default;
virtual ~BaseModelInfo();
ModelID id() const {
return modelid_;
@ -76,9 +75,7 @@ public:
return refcount_;
}
void setCollisionModel(std::unique_ptr<CollisionModel>& col) {
collision = std::move(col);
}
void setCollisionModel(std::unique_ptr<CollisionModel>& col);
CollisionModel* getCollision() const {
return collision.get();
@ -146,10 +143,9 @@ public:
/// @todo remove this from here too :)
std::vector<PathData> paths;
SimpleModelInfo() : BaseModelInfo(kType) {
}
SimpleModelInfo(ModelDataType type) : BaseModelInfo(type) {
}
SimpleModelInfo();
SimpleModelInfo(ModelDataType type);
~SimpleModelInfo() override;
/// @todo change with librw
void setAtomic(const ClumpPtr& model, int n, const AtomicPtr& atomic) {

View File

@ -1,7 +1,9 @@
#ifndef _RWENGINE_PATHDATA_HPP_
#define _RWENGINE_PATHDATA_HPP_
#include <glm/vec3.hpp>
#include <cstdint>
#include <glm/glm.hpp>
#include <string>
#include <vector>

View File

@ -1,5 +1,6 @@
#ifndef _RWENGINE_PEDDATA_HPP_
#define _RWENGINE_PEDDATA_HPP_
#include <cstdint>
#include <string>
#include <vector>

View File

@ -1,6 +1,7 @@
#ifndef RWENGINE_VEHICLEGENERATOR_HPP
#define RWENGINE_VEHICLEGENERATOR_HPP
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
/**
* Stores information about where the game can generate vehicles.

View File

@ -1,7 +1,9 @@
#ifndef _RWENGINE_WEAPONDATA_HPP_
#define _RWENGINE_WEAPONDATA_HPP_
#include <glm/vec3.hpp>
#include <cinttypes>
#include <glm/glm.hpp>
#include <string>
struct WeaponData {

View File

@ -1,5 +1,6 @@
#include "Weather.hpp"
#include <cmath>
namespace {
Weather::Entry interpolateWeather(const Weather::Entry& a,

View File

@ -1,12 +1,13 @@
#ifndef _RWENGINE_WEATHER_HPP_
#define _RWENGINE_WEATHER_HPP_
#include <glm/vec3.hpp>
#include <rw/types.hpp>
#include <cstdint>
#include <vector>
#include <glm/glm.hpp>
enum class WeatherCondition { Sunny = 0, Cloudy = 1, Rainy = 2, Foggy = 3 };

View File

@ -0,0 +1,50 @@
#include "data/ZoneData.hpp"
#include "glm/glm.hpp"
#include <algorithm>
bool ZoneData::isZoneContained(const ZoneData &inner, const ZoneData &outer) {
return glm::all(glm::greaterThanEqual(inner.min, outer.min)) &&
glm::all(glm::lessThanEqual(inner.max, outer.max));
}
bool ZoneData::containsPoint(const glm::vec3 &point) const {
return glm::all(glm::greaterThanEqual(point, min)) &&
glm::all(glm::lessThanEqual(point, max));
}
ZoneData *ZoneData::findLeafAtPoint(const glm::vec3 &point) {
for (ZoneData* child : children_) {
auto descendent = child->findLeafAtPoint(point);
if (descendent) {
return descendent;
}
}
return containsPoint(point) ? this : nullptr;
}
bool ZoneData::insertZone(ZoneData &inner) {
if (!isZoneContained(inner, *this)) {
return false;
}
for (ZoneData* child : children_) {
if (child->insertZone(inner)) {
return true;
}
}
// inner is a child of outer
// Move any zones that are really within inner to inner
auto it = std::stable_partition(
children_.begin(), children_.end(),
[&](ZoneData* a) { return !inner.insertZone(*a); });
children_.erase(it, children_.end());
children_.push_back(&inner);
inner.parent_ = this;
return true;
}

View File

@ -1,8 +1,8 @@
#ifndef _RWENGINE_ZONEDATA_HPP_
#define _RWENGINE_ZONEDATA_HPP_
#include <algorithm>
#include <glm/glm.hpp>
#include <glm/vec3.hpp>
#include <memory>
#include <string>
#include <utility>
@ -90,50 +90,13 @@ struct ZoneData {
ZoneData() = default;
static bool isZoneContained(const ZoneData& inner, const ZoneData& outer) {
return glm::all(glm::greaterThanEqual(inner.min, outer.min)) &&
glm::all(glm::lessThanEqual(inner.max, outer.max));
}
static bool isZoneContained(const ZoneData& inner, const ZoneData& outer);
bool containsPoint(const glm::vec3& point) const {
return glm::all(glm::greaterThanEqual(point, min)) &&
glm::all(glm::lessThanEqual(point, max));
}
bool containsPoint(const glm::vec3& point) const;
ZoneData* findLeafAtPoint(const glm::vec3& point) {
for (ZoneData* child : children_) {
auto descendent = child->findLeafAtPoint(point);
if (descendent) {
return descendent;
}
}
return containsPoint(point) ? this : nullptr;
}
ZoneData* findLeafAtPoint(const glm::vec3& point);
bool insertZone(ZoneData& inner) {
if (!isZoneContained(inner, *this)) {
return false;
}
for (ZoneData* child : children_) {
if (child->insertZone(inner)) {
return true;
}
}
// inner is a child of outer
// Move any zones that are really within inner to inner
auto it = std::stable_partition(
children_.begin(), children_.end(),
[&](ZoneData* a) { return !inner.insertZone(*a); });
children_.erase(it, children_.end());
children_.push_back(&inner);
inner.parent_ = this;
return true;
}
bool insertZone(ZoneData& inner);
};
using ZoneDataList = std::vector<ZoneData>;

View File

@ -1,11 +1,12 @@
#ifndef _RWENGINE_ANIMATOR_HPP_
#define _RWENGINE_ANIMATOR_HPP_
#include <map>
#include <vector>
#include <rw/debug.hpp>
#include <rw/forward.hpp>
#include <map>
#include <vector>
struct AnimationBone;
class ModelFrame;

View File

@ -19,6 +19,7 @@
#include "core/Logger.hpp"
#include "core/Profiler.hpp"
#include "data/CollisionModel.hpp"
#include "engine/GameState.hpp"
#include "engine/GameWorld.hpp"
#include "loaders/LoaderCOL.hpp"
@ -701,6 +702,31 @@ void GameData::loadSplash(const std::string& name) {
engine->state->currentSplash = lower;
}
TextureData::Handle GameData::findSlotTexture(const std::string &slot, const std::string &texture) const {
auto slotit = textureslots.find(slot);
if (slotit == textureslots.end()) {
return nullptr;
}
auto textureit = slotit->second.find(texture);
if (textureit == slotit->second.end()) {
return nullptr;
}
return textureit->second;
}
ZoneData *GameData::findZone(const std::string &name) {
auto it =
std::find_if(gamezones.begin(), gamezones.end(),
[&](const ZoneData& a) { return a.name == name; });
return it != gamezones.end() ? &(*it) : nullptr;
}
ZoneData *GameData::findZoneAt(const glm::vec3 &pos) {
RW_CHECK(!gamezones.empty(), "No game zones loaded");
ZoneData* zone = gamezones[0].findLeafAtPoint(pos);
return zone;
}
int GameData::getWaterIndexAt(const glm::vec3& ws) const {
auto wX = static_cast<int>((ws.x + WATER_WORLD_SIZE / 2.f) /
(WATER_WORLD_SIZE / WATER_HQ_DATA_SIZE));
@ -708,7 +734,7 @@ int GameData::getWaterIndexAt(const glm::vec3& ws) const {
(WATER_WORLD_SIZE / WATER_HQ_DATA_SIZE));
if (wX >= 0 && wX < WATER_HQ_DATA_SIZE && wY >= 0 &&
wY < WATER_HQ_DATA_SIZE) {
wY < WATER_HQ_DATA_SIZE) {
int i = (wX * WATER_HQ_DATA_SIZE) + wY;
return engine->data->realWater[i];
}

View File

@ -11,8 +11,6 @@
#include <unordered_map>
#include <vector>
#include <glm/glm.hpp>
#include <platform/FileIndex.hpp>
#include <rw/debug.hpp>
#include <rw/forward.hpp>
@ -28,7 +26,6 @@
#include <loaders/LoaderIMG.hpp>
#include <loaders/LoaderTXD.hpp>
#include <objects/VehicleInfo.hpp>
#include <gl/TextureData.hpp>
class Logger;
struct WeaponData;
@ -194,17 +191,7 @@ public:
void loadSplash(const std::string& name);
TextureData::Handle findSlotTexture(const std::string& slot,
const std::string& texture) const {
auto slotit = textureslots.find(slot);
if (slotit == textureslots.end()) {
return nullptr;
}
auto textureit = slotit->second.find(texture);
if (textureit == slotit->second.end()) {
return nullptr;
}
return textureit->second;
}
const std::string& texture) const;
FileIndex index;
@ -227,18 +214,9 @@ public:
ZoneDataList mapzones;
ZoneData* findZone(const std::string& name) {
auto it =
std::find_if(gamezones.begin(), gamezones.end(),
[&](const ZoneData& a) { return a.name == name; });
return it != gamezones.end() ? &(*it) : nullptr;
}
ZoneData* findZone(const std::string& name);
ZoneData* findZoneAt(const glm::vec3& pos) {
RW_CHECK(!gamezones.empty(), "No game zones loaded");
ZoneData* zone = gamezones[0].findLeafAtPoint(pos);
return zone;
}
ZoneData* findZoneAt(const glm::vec3& pos);
std::unordered_map<ModelID, std::unique_ptr<BaseModelInfo>> modelinfo;

View File

@ -1,14 +1,5 @@
#ifndef _RWENGINE_GAMESTATE_HPP_
#define _RWENGINE_GAMESTATE_HPP_
#include <bitset>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <fonts/GameTexts.hpp>
#include "data/CutsceneData.hpp"
@ -20,6 +11,17 @@
#include "objects/ObjectTypes.hpp"
#include "script/ScriptTypes.hpp"
#include <glm/gtc/quaternion.hpp>
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
#include <bitset>
#include <cstdint>
#include <map>
#include <optional>
#include <string>
#include <vector>
class GameWorld;
class GameObject;
class ScriptMachine;

View File

@ -18,7 +18,9 @@
#include "engine/GameData.hpp"
#include "engine/GameState.hpp"
#include "engine/Payphone.hpp"
#include "ai/AIGraphNode.hpp"
#include "ai/DefaultAIController.hpp"
#include "ai/PlayerController.hpp"
#include "ai/TrafficDirector.hpp"
@ -172,7 +174,7 @@ InstanceObject* GameWorld::createInstance(const uint16_t id,
}
void GameWorld::createTraffic(const ViewCamera& viewCamera) {
TrafficDirector director(&aigraph, this);
ai::TrafficDirector director(&aigraph, this);
director.populateNearby(viewCamera, kMaxTrafficSpawnRadius, 5);
}
@ -336,7 +338,7 @@ CharacterObject* GameWorld::createPedestrian(const uint16_t id,
data->loadModel(id);
}
auto controller = new DefaultAIController();
auto controller = new ai::DefaultAIController();
auto ped = std::make_unique<CharacterObject>(this, pos, rot, pt, controller);
auto ptr = ped.get();
ped->setGameObjectID(gid);
@ -364,7 +366,7 @@ CharacterObject* GameWorld::createPlayer(const glm::vec3& pos,
pt->setModel(model);
}
auto controller = new PlayerController();
auto controller = new ai::PlayerController();
auto ped = std::make_unique<CharacterObject>(this, pos, rot, pt, controller);
auto ptr = ped.get();
ped->setGameObjectID(gid);
@ -429,7 +431,7 @@ PickupObject* GameWorld::createPickup(const glm::vec3& pos, int id, int type) {
}
Garage* GameWorld::createGarage(const glm::vec3 coord0, const glm::vec3 coord1,
Garage::Type type) {
GarageType type) {
const size_t id = garages.size();
garages.emplace_back(std::make_unique<Garage>(this, id, coord0, coord1, type));
return garages.back().get();
@ -873,7 +875,7 @@ void GameWorld::loadSpecialModel(const unsigned short index,
state->specialModels[index] = lowerName;
}
void GameWorld::disableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
void GameWorld::disableAIPaths(ai::NodeType type, const glm::vec3& min,
const glm::vec3& max) {
for (auto& n : aigraph.nodes) {
if (n->type == type) {
@ -886,7 +888,7 @@ void GameWorld::disableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
}
}
void GameWorld::enableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
void GameWorld::enableAIPaths(ai::NodeType type, const glm::vec3& min,
const glm::vec3& max) {
for (auto& n : aigraph.nodes) {
if (n->type == type) {
@ -1064,11 +1066,11 @@ void GameWorld::clearObjectsWithinArea(const glm::vec3 center,
// explosions, remove all projectiles
}
PlayerController* GameWorld::getPlayer() {
ai::PlayerController* GameWorld::getPlayer() {
auto object = pedestrianPool.find(state->playerObject);
if (object) {
auto controller = static_cast<CharacterObject*>(object)->controller;
return static_cast<PlayerController*>(controller);
return static_cast<ai::PlayerController*>(controller);
}
return nullptr;
}

View File

@ -17,20 +17,11 @@
#pragma warning(default : 4305)
#endif
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <ai/AIGraph.hpp>
#include <ai/AIGraphNode.hpp>
#include <audio/SoundManager.hpp>
#include <engine/Garage.hpp>
#include <engine/Payphone.hpp>
#include <objects/ObjectTypes.hpp>
#include <render/VisualFX.hpp>
#include <data/Chase.hpp>
#include <engine/Garage.hpp>
#include <objects/ObjectTypes.hpp>
class btCollisionDispatcher;
class btDefaultCollisionConfiguration;
@ -45,7 +36,10 @@ class GameState;
class Garage;
class Payphone;
namespace ai {
class PlayerController;
} // namespace ai
class Logger;
class GameData;
@ -63,6 +57,11 @@ struct BlipData;
struct WeaponScan;
struct VehicleGenerator;
struct LightFX;
struct ParticleFX;
struct TrailFX;
struct VisualFX;
/**
* Information about "Goal" locations so they can be rendered
* (this doesn't really belong here).
@ -158,7 +157,7 @@ public:
* Creates a garage
*/
Garage* createGarage(const glm::vec3 coord0, const glm::vec3 coord1,
Garage::Type type);
GarageType type);
/**
* Creates a payphone
@ -291,7 +290,7 @@ public:
ObjectPool& getTypeObjectPool(GameObject* object);
std::vector<PlayerController*> players;
std::vector<ai::PlayerController*> players;
std::vector<std::unique_ptr<Garage>> garages;
@ -312,7 +311,7 @@ public:
/**
* AI Graph
*/
AIGraph aigraph;
ai::AIGraph aigraph;
/**
* Visual Effects
@ -368,9 +367,9 @@ public:
const std::string& name);
void loadSpecialModel(const unsigned short index, const std::string& name);
void disableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
void disableAIPaths(ai::NodeType type, const glm::vec3& min,
const glm::vec3& max);
void enableAIPaths(AIGraphNode::NodeType type, const glm::vec3& min,
void enableAIPaths(ai::NodeType type, const glm::vec3& min,
const glm::vec3& max);
void drawAreaIndicator(AreaIndicatorInfo::AreaIndicatorType type,
@ -398,14 +397,14 @@ public:
void clearObjectsWithinArea(const glm::vec3 center, const float radius,
const bool clearParticles);
PlayerController* getPlayer();
ai::PlayerController* getPlayer();
template <
typename T1, typename T2 = T1,
typename std::enable_if<std::is_integral<T1>::value>::type* = nullptr,
typename std::enable_if<std::is_integral<T2>::value>::type* = nullptr>
T1 getRandomNumber(T1 min, T2 max) {
std::uniform_int_distribution<T1> dist(min, max);
std::uniform_int_distribution<T1> dist(min, static_cast<T1>(max));
return dist(randomNumberGen);
}
@ -416,7 +415,7 @@ public:
typename std::enable_if<std::is_floating_point<T2>::value>::type* =
nullptr>
T1 getRandomNumber(T1 min, T2 max) {
std::uniform_real_distribution<T1> dist(min, max);
std::uniform_real_distribution<T1> dist(min, static_cast<T1>(max));
return dist(randomNumberGen);
}

View File

@ -10,19 +10,17 @@
#include <glm/gtx/quaternion.hpp>
#include "dynamics/CollisionInstance.hpp"
#include "ai/PlayerController.hpp"
#include "data/CollisionModel.hpp"
#include "dynamics/CollisionInstance.hpp"
#include "engine/GameState.hpp"
#include "objects/CharacterObject.hpp"
#include "objects/GameObject.hpp"
#include "objects/InstanceObject.hpp"
#include "objects/VehicleObject.hpp"
Garage::Garage(GameWorld* engine_, size_t id_, const glm::vec3& coord0,
const glm::vec3& coord1, Type type_)
const glm::vec3& coord1, GarageType type_)
: engine(engine_), id(id_), type(type_) {
min.x = std::min(coord0.x, coord1.x);
min.y = std::min(coord0.y, coord1.y);
@ -81,32 +79,32 @@ Garage::Garage(GameWorld* engine_, size_t id_, const glm::vec3& coord0,
step /= doorHeight;
switch (type) {
case Garage::Type::Mission:
case Garage::Type::CollectCars1:
case Garage::Type::CollectCars2:
case Garage::Type::MissionForCarToComeOut:
case Garage::Type::MissionKeepCar:
case Garage::Type::Hideout1:
case Garage::Type::Hideout2:
case Garage::Type::Hideout3:
case Garage::Type::MissionToOpenAndClose:
case Garage::Type::MissionForSpecificCar:
case Garage::Type::MissionKeepCarAndRemainClosed: {
state = State::Closed;
case GarageType::Mission:
case GarageType::CollectCars1:
case GarageType::CollectCars2:
case GarageType::MissionForCarToComeOut:
case GarageType::MissionKeepCar:
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3:
case GarageType::MissionToOpenAndClose:
case GarageType::MissionForSpecificCar:
case GarageType::MissionKeepCarAndRemainClosed: {
state = GarageState::Closed;
break;
}
case Garage::Type::BombShop1:
case Garage::Type::BombShop2:
case Garage::Type::BombShop3:
case Garage::Type::Respray:
case Garage::Type::Crusher: {
state = State::Opened;
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3:
case GarageType::Respray:
case GarageType::Crusher: {
state = GarageState::Opened;
break;
}
}
if (state == State::Closed) {
if (state == GarageState::Closed) {
fraction = 0.f;
} else {
fraction = 1.f;
@ -129,14 +127,14 @@ void Garage::makeDoorSwing() {
}
bool Garage::isTargetInsideGarage() const {
return state == State::Closed && isObjectInsideGarage(target);
return state == GarageState::Closed && isObjectInsideGarage(target);
}
void Garage::activate() {
active = true;
if (type == Type::MissionForCarToComeOut && state == State::Closed) {
state = State::Opening;
if (type == GarageType::MissionForCarToComeOut && state == GarageState::Closed) {
state = GarageState::Opening;
}
}
@ -145,14 +143,14 @@ void Garage::deactivate() {
}
void Garage::open() {
if (state == State::Closed || state == State::Closing) {
state = State::Opening;
if (state == GarageState::Closed || state == GarageState::Closing) {
state = GarageState::Opening;
}
}
void Garage::close() {
if (state == State::Opened || state == State::Opening) {
state = State::Closing;
if (state == GarageState::Opened || state == GarageState::Opening) {
state = GarageState::Closing;
}
}
@ -204,7 +202,7 @@ bool Garage::shouldClose() {
bool playerIsInVehicle = playerVehicle != nullptr;
switch (type) {
case Type::Mission: {
case GarageType::Mission: {
if (!isObjectInsideGarage(static_cast<GameObject*>(plyChar)) &&
isObjectInsideGarage(target) && !playerIsInVehicle &&
getDistanceToGarage(playerPosition) >= 2.f) {
@ -214,9 +212,9 @@ bool Garage::shouldClose() {
return false;
}
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3: {
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3: {
if (playerIsInVehicle) {
if (isObjectInsideGarage(
static_cast<GameObject*>(playerVehicle)) &&
@ -228,7 +226,7 @@ bool Garage::shouldClose() {
return false;
}
case Type::Respray: {
case GarageType::Respray: {
if (playerIsInVehicle) {
if (isObjectInsideGarage(
static_cast<GameObject*>(playerVehicle)) &&
@ -246,8 +244,8 @@ bool Garage::shouldClose() {
return false;
}
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
if (playerIsInVehicle) {
if (isObjectInsideGarage(
static_cast<GameObject*>(playerVehicle))) {
@ -263,24 +261,24 @@ bool Garage::shouldClose() {
return false;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
// @todo unimplemented
return false;
}
case Type::Crusher: {
case GarageType::Crusher: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
// @todo unimplemented
return false;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
// Not sure about these values
if ((!playerIsInVehicle &&
getDistanceToGarage(playerPosition) >= 5.f) ||
@ -292,17 +290,17 @@ bool Garage::shouldClose() {
return false;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
// @todo unimplemented
return false;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
// @todo unimplemented
return false;
}
@ -321,7 +319,7 @@ bool Garage::shouldOpen() {
bool playerIsInVehicle = playerVehicle != nullptr;
switch (type) {
case Type::Mission: {
case GarageType::Mission: {
// Not sure about these values
if (playerIsInVehicle &&
getDistanceToGarage(playerPosition) < 8.f &&
@ -332,10 +330,10 @@ bool Garage::shouldOpen() {
return false;
}
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3:
case Type::Respray: {
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3:
case GarageType::Respray: {
if (garageTimer < engine->getGameTime()) {
return true;
}
@ -343,30 +341,30 @@ bool Garage::shouldOpen() {
return false;
}
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
// @todo unimplemented
return false;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
// @todo unimplemented
return false;
}
case Type::Crusher: {
case GarageType::Crusher: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
// @todo unimplemented
return false;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
// Not sure about these values
if ((!playerIsInVehicle &&
getDistanceToGarage(playerPosition) < 5.f) ||
@ -378,17 +376,17 @@ bool Garage::shouldOpen() {
return false;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
// @todo unimplemented
return false;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
// @todo unimplemented
return false;
}
@ -407,34 +405,34 @@ bool Garage::shouldStopClosing() {
bool playerIsInVehicle = playerVehicle != nullptr;
switch (type) {
case Type::Mission:
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3:
case Type::Respray:
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::Mission:
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3:
case GarageType::Respray:
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
return false;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
// @todo unimplemented
return false;
}
case Type::Crusher: {
case GarageType::Crusher: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
// @todo unimplemented
return false;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
// Not sure about these values
if ((!playerIsInVehicle &&
getDistanceToGarage(playerPosition) < 5.f) ||
@ -446,17 +444,17 @@ bool Garage::shouldStopClosing() {
return false;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
// @todo unimplemented
return false;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
// @todo unimplemented
return false;
}
@ -475,34 +473,34 @@ bool Garage::shouldStopOpening() {
bool playerIsInVehicle = playerVehicle != nullptr;
switch (type) {
case Type::Mission:
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3:
case Type::Respray:
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::Mission:
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3:
case GarageType::Respray:
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
return false;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
// @todo unimplemented
return false;
}
case Type::Crusher: {
case GarageType::Crusher: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
// @todo unimplemented
return false;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
// Not sure about these values
if ((!playerIsInVehicle &&
getDistanceToGarage(playerPosition) >= 5.f) ||
@ -514,17 +512,17 @@ bool Garage::shouldStopOpening() {
return false;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
// @todo unimplemented
return false;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
// @todo unimplemented
return false;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
// @todo unimplemented
return false;
}
@ -545,58 +543,58 @@ void Garage::doOnOpenEvent() {
RW_UNUSED(playerIsInVehicle);
switch (type) {
case Type::Mission: {
case GarageType::Mission: {
break;
}
case Type::BombShop1: {
case GarageType::BombShop1: {
break;
}
case Type::BombShop2: {
case GarageType::BombShop2: {
break;
}
case Type::BombShop3: {
case GarageType::BombShop3: {
break;
}
case Type::Respray: {
case GarageType::Respray: {
break;
}
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
break;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
break;
}
case Type::Crusher: {
case GarageType::Crusher: {
break;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
break;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
break;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
break;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
break;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
break;
}
@ -614,21 +612,21 @@ void Garage::doOnCloseEvent() {
RW_UNUSED(playerIsInVehicle);
switch (type) {
case Type::Mission: {
case GarageType::Mission: {
player->setInputEnabled(true);
break;
}
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3: {
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3: {
// Find out real value
garageTimer = engine->getGameTime() + 1.5f;
break;
}
case Type::Respray: {
case GarageType::Respray: {
// Find out real value
garageTimer = engine->getGameTime() + 2.f;
playerVehicle->setHealth(1000.f);
@ -636,38 +634,38 @@ void Garage::doOnCloseEvent() {
break;
}
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
break;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
break;
}
case Type::Crusher: {
case GarageType::Crusher: {
break;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
break;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
break;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
break;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
break;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
break;
}
@ -685,58 +683,58 @@ void Garage::doOnStartOpeningEvent() {
RW_UNUSED(playerIsInVehicle);
switch (type) {
case Type::Mission: {
case GarageType::Mission: {
break;
}
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
player->setInputEnabled(true);
break;
}
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3: {
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3: {
player->setInputEnabled(true);
playerVehicle->setHandbraking(false);
break;
}
case Type::Respray: {
case GarageType::Respray: {
player->setInputEnabled(true);
playerVehicle->setHandbraking(false);
resprayDone = true;
break;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
break;
}
case Type::Crusher: {
case GarageType::Crusher: {
break;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
break;
}
case Type::Hideout1:
case Type::Hideout2:
case Type::Hideout3: {
case GarageType::Hideout1:
case GarageType::Hideout2:
case GarageType::Hideout3: {
break;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
break;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
break;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
break;
}
@ -754,43 +752,43 @@ void Garage::doOnStartClosingEvent() {
RW_UNUSED(playerIsInVehicle);
switch (type) {
case Type::Mission:
case Type::CollectCars1:
case Type::CollectCars2: {
case GarageType::Mission:
case GarageType::CollectCars1:
case GarageType::CollectCars2: {
player->setInputEnabled(false);
break;
}
case Type::BombShop1:
case Type::BombShop2:
case Type::BombShop3:
case Type::Respray: {
case GarageType::BombShop1:
case GarageType::BombShop2:
case GarageType::BombShop3:
case GarageType::Respray: {
player->setInputEnabled(false);
playerVehicle->setHandbraking(true);
break;
}
case Type::MissionForCarToComeOut: {
case GarageType::MissionForCarToComeOut: {
break;
}
case Type::Crusher: {
case GarageType::Crusher: {
break;
}
case Type::MissionKeepCar: {
case GarageType::MissionKeepCar: {
break;
}
case Type::MissionToOpenAndClose: {
case GarageType::MissionToOpenAndClose: {
break;
}
case Type::MissionForSpecificCar: {
case GarageType::MissionForSpecificCar: {
break;
}
case Type::MissionKeepCarAndRemainClosed: {
case GarageType::MissionKeepCarAndRemainClosed: {
break;
}
@ -809,32 +807,32 @@ void Garage::tick(float dt) {
needsToUpdate = false;
switch (state) {
case State::Opened: {
case GarageState::Opened: {
if (shouldClose()) {
state = State::Closing;
state = GarageState::Closing;
doOnStartClosingEvent();
}
break;
}
case State::Closed: {
case GarageState::Closed: {
if (shouldOpen()) {
state = State::Opening;
state = GarageState::Opening;
doOnStartOpeningEvent();
}
break;
}
case State::Opening: {
case GarageState::Opening: {
if (shouldStopOpening()) {
state = State::Closing;
state = GarageState::Closing;
} else {
fraction += dt * step;
if (fraction >= 1.0f) {
state = State::Opened;
state = GarageState::Opened;
fraction = 1.f;
doOnOpenEvent();
}
@ -845,14 +843,14 @@ void Garage::tick(float dt) {
break;
}
case State::Closing: {
case GarageState::Closing: {
if (shouldStopClosing()) {
state = State::Opening;
state = GarageState::Opening;
} else {
fraction -= dt * step;
if (fraction <= 0.f) {
state = State::Closed;
state = GarageState::Closed;
fraction = 0.f;
doOnCloseEvent();
}

View File

@ -1,11 +1,12 @@
#ifndef _RWENGINE_GARAGE_HPP_
#define _RWENGINE_GARAGE_HPP_
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp>
#include <rw/debug.hpp>
namespace ai {
class PlayerController;
} // namespace ai
class GameWorld;
@ -13,6 +14,28 @@ class CharacterObject;
class InstanceObject;
class GameObject;
// Garage types are from original game
enum class GarageType {
Mission = 1,
BombShop1 = 2,
BombShop2 = 3,
BombShop3 = 4,
Respray = 5,
CollectCars1 = 8,
CollectCars2 = 9,
MissionForCarToComeOut = 11,
Crusher = 13,
MissionKeepCar = 14,
Hideout1 = 16,
Hideout2 = 17,
Hideout3 = 18,
MissionToOpenAndClose = 19,
MissionForSpecificCar = 20,
MissionKeepCarAndRemainClosed = 21,
};
enum class GarageState { Closed, Closing, Opening, Opened };
class Garage {
private:
InstanceObject* doorObject = nullptr;
@ -49,28 +72,6 @@ private:
void updateDoor();
public:
// Garage types are from original game
enum class Type {
Mission = 1,
BombShop1 = 2,
BombShop2 = 3,
BombShop3 = 4,
Respray = 5,
CollectCars1 = 8,
CollectCars2 = 9,
MissionForCarToComeOut = 11,
Crusher = 13,
MissionKeepCar = 14,
Hideout1 = 16,
Hideout2 = 17,
Hideout3 = 18,
MissionToOpenAndClose = 19,
MissionForSpecificCar = 20,
MissionKeepCarAndRemainClosed = 21,
};
enum class State { Closed, Closing, Opening, Opened };
GameWorld* engine;
size_t id;
@ -81,18 +82,18 @@ public:
glm::vec3 min;
glm::vec3 max;
Type type;
GarageType type;
GameObject* target = nullptr;
// @todo use model type
int targetModel = 0;
State state = State::Closed;
GarageState state = GarageState::Closed;
bool resprayDone = false;
Garage(GameWorld* engine_, size_t id_, const glm::vec3& coord0,
const glm::vec3& coord1, Type type_);
const glm::vec3& coord1, GarageType type_);
~Garage() = default;
void makeDoorSwing();

View File

@ -1,10 +1,14 @@
#ifndef _RWENGINE_PAYPHONE_HPP_
#define _RWENGINE_PAYPHONE_HPP_
#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <string>
namespace ai {
class PlayerController;
} // namespace ai
class GameWorld;
class GameState;

View File

@ -1267,7 +1267,7 @@ bool SaveGame::loadGame(GameState& state, const std::string& file) {
auto& garage = garages[g];
state.world->createGarage(glm::vec3(garage.x1, garage.y1, garage.z1),
glm::vec3(garage.x2, garage.y2, garage.z2),
static_cast<Garage::Type>(garage.type));
static_cast<GarageType>(garage.type));
}
for (auto &c : garageData.cars) {
if (c.modelId == 0) continue;

View File

@ -1,15 +1,19 @@
#ifndef _RWENGINE_SCREENTEXT_HPP_
#define _RWENGINE_SCREENTEXT_HPP_
#include <glm/gtc/type_precision.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <fonts/GameTexts.hpp>
#include <algorithm>
#include <array>
#include <cstddef>
#include <string>
#include <vector>
#include <glm/glm.hpp>
#include <fonts/GameTexts.hpp>
enum class ScreenTextType {
/// Big text will be rendered according to the proscribed style.
/// Adding a 2nd big text will cause the first to terminate.

View File

@ -6,6 +6,8 @@
#include "data/WeaponData.hpp"
#include "dynamics/HitTest.hpp"
#include <data/Clump.hpp>
#include "engine/GameWorld.hpp"
#include "objects/CharacterObject.hpp"
#include "objects/ProjectileObject.hpp"

View File

@ -1,16 +1,19 @@
#ifndef _RWENGINE_LOADERCOL_HPP_
#define _RWENGINE_LOADERCOL_HPP_
#include <data/CollisionModel.hpp>
#include <memory>
#include <string>
#include <vector>
struct CollisionModel;
/**
* @class LoaderCOL
* Loads collision data from COL files
*/
class LoaderCOL {
public:
/// Load the COL data into memory
bool load(const std::string& file);

View File

@ -1,5 +1,6 @@
#ifndef _RWENGINE_LOADERGXT_HPP_
#define _RWENGINE_LOADERGXT_HPP_
#include <rw/forward.hpp>
class GameTexts;

View File

@ -1,5 +1,7 @@
#include "loaders/LoaderIFP.hpp"
#include <glm/glm.hpp>
#include <algorithm>
#include <cctype>
#include <memory>

View File

@ -7,8 +7,8 @@
#include <unordered_map>
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/vec3.hpp>
#include <rw/forward.hpp>

View File

@ -4,6 +4,8 @@
#include <fstream>
#include <sstream>
#include <data/Weather.hpp>
namespace {
glm::vec3 readRGB(std::stringstream &ss) {
int r, g, b;

View File

@ -1,10 +1,10 @@
#ifndef _RWENGINE_WEATHERLOADER_HPP_
#define _RWENGINE_WEATHERLOADER_HPP_
#include <data/Weather.hpp>
#include <string>
class Weather;
namespace WeatherLoader {
bool load(const std::string &filename, Weather& outWeather);
}

View File

@ -1,10 +1,5 @@
#include "objects/CharacterObject.hpp"
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <memory>
#ifdef _MSC_VER
#pragma warning(disable : 4305)
#endif
@ -15,9 +10,14 @@
#pragma warning(default : 4305)
#endif
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <rw/debug.hpp>
#include "ai/CharacterController.hpp"
#include "ai/AIGraphNode.hpp"
#include "ai/PlayerController.hpp"
#include "engine/Animator.hpp"
#include "engine/GameData.hpp"
@ -31,13 +31,17 @@
#error Unable to find BT_BULLET_VERSION
#endif
#include <algorithm>
#include <cctype>
#include <cstdlib>
#include <memory>
const float CharacterObject::DefaultJumpSpeed = 2.f;
CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, BaseModelInfo* modelinfo,
CharacterController* controller)
: GameObject(engine, pos, rot, modelinfo)
, controller(controller) {
ai::CharacterController* controller)
: GameObject(engine, pos, rot, modelinfo), controller(controller) {
auto info = getModelInfo<PedModelInfo>();
setClump(info->getModel()->clone());
if (info->getModel()) {
@ -117,7 +121,7 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
glm::vec3 animTranslate{};
if (isPlayer()) {
auto c = static_cast<PlayerController*>(controller);
auto c = static_cast<ai::PlayerController*>(controller);
if (c->isTalkingOnPayphone()) {
animator->playAnimation(
@ -218,7 +222,8 @@ glm::vec3 CharacterObject::updateMovementAnimation(float dt) {
}
}
if (isPlayer() && static_cast<PlayerController*>(controller)->isAdrenalineActive() &&
if (isPlayer() &&
static_cast<ai::PlayerController*>(controller)->isAdrenalineActive() &&
movementAnimation == animations->animation(AnimCycle::WalkStart)) {
animationSpeed *= 2;
}
@ -599,13 +604,13 @@ void CharacterObject::setJumpSpeed(float speed) {
void CharacterObject::resetToAINode() {
auto& nodes = engine->aigraph.nodes;
bool vehicleNode = !!getCurrentVehicle();
AIGraphNode* nearest = nullptr;
ai::AIGraphNode* nearest = nullptr;
float d = std::numeric_limits<float>::max();
for (const auto& node : nodes) {
if (vehicleNode) {
if (node->type == AIGraphNode::Pedestrian) continue;
if (node->type == ai::NodeType::Pedestrian) continue;
} else {
if (node->type == AIGraphNode::Vehicle) continue;
if (node->type == ai::NodeType::Vehicle) continue;
}
float dist = glm::length(node->position - getPosition());
@ -714,7 +719,7 @@ void CharacterObject::useItem(bool active, bool primary) {
if (!currentState.primaryActive && active) {
// If we've just started, activate
controller->setNextActivity(
std::make_unique<Activities::UseItem>(item));
std::make_unique<ai::Activities::UseItem>(item));
} else if (currentState.primaryActive && !active) {
// UseItem will cancel itself upon !primaryActive
}

View File

@ -7,16 +7,16 @@
#include <cstdint>
#include <string>
#include <glm/glm.hpp>
#include <glm/gtc/constants.hpp>
#include <rw/forward.hpp>
#include <data/AnimGroup.hpp>
#include <objects/GameObject.hpp>
class BaseModelInfo;
namespace ai {
class CharacterController;
}
class BaseModelInfo;
class btCapsuleShapeZ;
class btKinematicCharacterController;
class btPairCachingGhostObject;
@ -85,7 +85,7 @@ public:
std::unique_ptr<btPairCachingGhostObject> physObject;
std::unique_ptr<btCapsuleShapeZ> physShape;
CharacterController* controller;
ai::CharacterController* controller;
AnimGroup* animations;
@ -97,7 +97,7 @@ public:
*/
CharacterObject(GameWorld* engine, const glm::vec3& pos,
const glm::quat& rot, BaseModelInfo* modelinfo,
CharacterController* controller);
ai::CharacterController* controller);
~CharacterObject() override;

View File

@ -1,6 +1,5 @@
#ifndef _RWENGINE_CUTSCENEOBJECT_HPP_
#define _RWENGINE_CUTSCENEOBJECT_HPP_
#include <glm/glm.hpp>
#include <rw/forward.hpp>

View File

@ -1,6 +1,8 @@
#include "objects/GameObject.hpp"
#include <glm/gtc/constants.hpp>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include "engine/Animator.hpp"
@ -28,3 +30,10 @@ void GameObject::setHeading(float heading) {
auto quat = glm::normalize(glm::quat(glm::vec3(0.f, 0.f, hdg)));
setRotation(quat);
}
glm::mat4 GameObject::getTimeAdjustedTransform(float alpha) const {
glm::mat4 t{1.0f};
t = glm::translate(t, glm::mix(_lastPosition, getPosition(), alpha));
t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha));
return t;
}

View File

@ -3,9 +3,8 @@
#include <limits>
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/vec3.hpp>
#include <rw/debug.hpp>
#include <rw/forward.hpp>
@ -223,12 +222,7 @@ public:
_lastRotation = getRotation();
}
glm::mat4 getTimeAdjustedTransform(float alpha) const {
glm::mat4 t{1.0f};
t = glm::translate(t, glm::mix(_lastPosition, getPosition(), alpha));
t = t * glm::mat4_cast(glm::slerp(_lastRotation, getRotation(), alpha));
return t;
}
glm::mat4 getTimeAdjustedTransform(float alpha) const;
enum ObjectLifetime {
/// lifetime has not been set

View File

@ -14,6 +14,7 @@
#include <rw/types.hpp>
#include "data/PathData.hpp"
#include "dynamics/CollisionInstance.hpp"
#include "engine/Animator.hpp"
#include "engine/GameData.hpp"

View File

@ -1,12 +1,11 @@
#ifndef _RWENGINE_INSTANCEOBJECT_HPP_
#define _RWENGINE_INSTANCEOBJECT_HPP_
#include <memory>
#include <glm/glm.hpp>
#include "objects/GameObject.hpp"
#include <rw/forward.hpp>
#include <objects/GameObject.hpp>
#include <memory>
class BaseModelInfo;
class CollisionInstance;

View File

@ -11,8 +11,6 @@
#pragma warning(default : 4305)
#endif
#include <glm/gtc/quaternion.hpp>
#include "ai/PlayerController.hpp"
#include "data/WeaponData.hpp"
#include "engine/GameData.hpp"

View File

@ -2,7 +2,6 @@
#define _RWENGINE_PICKUPOBJECT_HPP_
#include <cstdint>
#include <glm/glm.hpp>
#include <rw/debug.hpp>

View File

@ -1,8 +1,6 @@
#ifndef _RWENGINE_PROJECTILEOBJECT_HPP_
#define _RWENGINE_PROJECTILEOBJECT_HPP_
#include <glm/glm.hpp>
#include <objects/GameObject.hpp>
#include "render/VisualFX.hpp"

View File

@ -1,14 +1,14 @@
#ifndef _RWENGINE_VEHICLEINFO_HPP_
#define _RWENGINE_VEHICLEINFO_HPP_
#include <glm/vec3.hpp>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>
#include <glm/glm.hpp>
/**
* @brief Stores data loaded from handling.cfg
*/

View File

@ -1095,3 +1095,21 @@ std::tuple<glm::vec3, glm::vec3> VehicleObject::obstacleCheckVolume() const {
};
}
VehicleObject::Part::Part(ModelFrame* p_dummy, Atomic* p_normal,
Atomic* p_damaged,
std::unique_ptr<btCollisionShape> p_cs,
std::unique_ptr<btRigidBody> p_body,
std::unique_ptr<btHingeConstraint> p_constraint,
bool p_moveToAngle, float p_targetAngle,
float p_openAngle, float p_closedAngle)
: dummy(p_dummy)
, normal(p_normal)
, damaged(p_damaged)
, cs(std::move(p_cs))
, body(std::move(p_body))
, constraint(std::move(p_constraint))
, moveToAngle(p_moveToAngle)
, targetAngle(p_targetAngle)
, openAngle(p_openAngle)
, closedAngle(p_closedAngle) {
}

View File

@ -10,14 +10,13 @@
#ifdef _MSC_VER
#pragma warning(disable : 4305)
#endif
#include <btBulletDynamicsCommon.h>
#include <LinearMath/btScalar.h>
#ifdef _MSC_VER
#pragma warning(default : 4305)
#endif
#include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/vec3.hpp>
#include <data/ModelData.hpp>
#include <objects/GameObject.hpp>
@ -29,6 +28,12 @@ class CharacterObject;
class CollisionInstance;
class GameWorld;
class ModelFrame;
class btRaycastVehicle;
class btCollisionShape;
class btRigidBody;
class btHingeConstraint;
class btMotionState;
struct btVehicleRaycaster;
/**
* @class VehicleObject
@ -67,18 +72,7 @@ public:
std::unique_ptr<btRigidBody> p_body,
std::unique_ptr<btHingeConstraint> p_constraint,
bool p_moveToAngle, float p_targetAngle, float p_openAngle,
float p_closedAngle)
: dummy(p_dummy)
, normal(p_normal)
, damaged(p_damaged)
, cs(std::move(p_cs))
, body(std::move(p_body))
, constraint(std::move(p_constraint))
, moveToAngle(p_moveToAngle)
, targetAngle(p_targetAngle)
, openAngle(p_openAngle)
, closedAngle(p_closedAngle) {
}
float p_closedAngle);
Part(Part&& part) = default;
Part& operator=(Part&& part) = default;

View File

@ -13,15 +13,13 @@
#pragma warning(default : 4305)
#endif
#include <data/Clump.hpp>
#include <gl/gl_core_3_3.h>
#include "render/OpenGLRenderer.hpp"
class btVector3;
class DrawBuffer;
class GameRenderer;
class GeometryBuffer;
struct GeometryVertex;
class DebugDraw final : public btIDebugDraw {
public:

View File

@ -4,11 +4,8 @@
#include <cstddef>
#include <memory>
#include <glm/glm.hpp>
#include <gl/DrawBuffer.hpp>
#include <gl/GeometryBuffer.hpp>
#include <gl/gl_core_3_3.h>
#include <rw/forward.hpp>

View File

@ -5,6 +5,7 @@
#include <vector>
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include <gl/gl_core_3_3.h>

View File

@ -4,8 +4,6 @@
#include <memory>
#include <string>
#include <glm/glm.hpp>
#include <gl/DrawBuffer.hpp>
#include <gl/GeometryBuffer.hpp>

View File

@ -3,15 +3,7 @@
#include <cstddef>
#include <gl/gl_core_3_3.h>
//#include <engine/GameWorld.hpp>
//#include <gl/DrawBuffer.hpp>
#include <glm/glm.hpp>
//#include <objects/GameObject.hpp>
#include <render/OpenGLRenderer.hpp>
//#include <render/ViewCamera.hpp>
//#include <rw/types.hpp>
#include "render/OpenGLRenderer.hpp"
class Atomic;
class CharacterObject;

View File

@ -149,6 +149,49 @@ void OpenGLRenderer::useTexture(GLuint unit, GLuint tex) {
}
}
void OpenGLRenderer::setBlend(BlendMode mode) {
if (mode!=BlendMode::BLEND_NONE && blendMode==BlendMode::BLEND_NONE)//To don't call glEnable again when it already enabled
glEnable(GL_BLEND);
if (mode!=blendMode) {
switch (mode) {
default:
assert(false);
break;
case BlendMode::BLEND_NONE:
glDisable(GL_BLEND);
break;
case BlendMode::BLEND_ALPHA:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case BlendMode::BLEND_ADDITIVE:
glBlendFunc(GL_ONE, GL_ONE);
break;
}
}
blendMode = mode;
}
void OpenGLRenderer::setDepthMode(DepthMode mode) {
if (mode != depthMode) {
if (depthMode == DepthMode::OFF) glEnable(GL_DEPTH_TEST);
switch(mode) {
case DepthMode::OFF: glDisable(GL_DEPTH_TEST); break;
case DepthMode::LESS: glDepthFunc(GL_LESS); break;
}
depthMode = mode;
}
}
void OpenGLRenderer::setDepthWrite(bool enable) {
if (enable != depthWriteEnabled) {
glDepthMask(enable ? GL_TRUE : GL_FALSE);
depthWriteEnabled = enable;
}
}
void OpenGLRenderer::useProgram(Renderer::ShaderProgram* p) {
if (p != currentProgram) {
currentProgram = static_cast<OpenGLShaderProgram*>(p);
@ -391,6 +434,13 @@ bool OpenGLRenderer::createUBO(Buffer &out, GLsizei size, GLsizei entrySize)
return true;
}
void OpenGLRenderer::attachUBO(GLuint buffer) {
if (currentUBO != buffer) {
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
currentUBO = buffer;
}
}
void OpenGLRenderer::uploadUBOEntry(Buffer &buffer, const void *data, size_t size)
{
attachUBO(buffer.name);
@ -469,3 +519,15 @@ const Renderer::ProfileInfo& OpenGLRenderer::popDebugGroup() {
}
Renderer::ShaderProgram::~ShaderProgram() = default;
GLint OpenGLRenderer::OpenGLShaderProgram::getUniformLocation(const std::string &name) {
auto c = uniforms.find(name.c_str());
GLint loc = -1;
if (c == uniforms.end()) {
loc = glGetUniformLocation(program, name.c_str());
uniforms[name] = loc;
} else {
loc = c->second;
}
return loc;
}

View File

@ -9,11 +9,13 @@
#include <vector>
#include <array>
#include <glm/glm.hpp>
#include <gl/gl_core_3_3.h>
#include <gl/GeometryBuffer.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/mat4x4.hpp>
#include <glm/vec2.hpp>
#include <glm/vec4.hpp>
class DrawBuffer;
typedef uint64_t RenderKey;
@ -271,17 +273,7 @@ public:
return program;
}
GLint getUniformLocation(const std::string& name) {
auto c = uniforms.find(name.c_str());
GLint loc = -1;
if (c == uniforms.end()) {
loc = glGetUniformLocation(program, name.c_str());
uniforms[name] = loc;
} else {
loc = c->second;
}
return loc;
}
GLint getUniformLocation(const std::string& name);
};
OpenGLRenderer();
@ -357,48 +349,11 @@ private:
std::map<GLuint, GLuint> currentTextures;
// Set state
void setBlend(BlendMode mode) {
if (mode!=BlendMode::BLEND_NONE && blendMode==BlendMode::BLEND_NONE)//To don't call glEnable again when it already enabled
glEnable(GL_BLEND);
void setBlend(BlendMode mode);
if (mode!=blendMode) {
switch (mode) {
default:
assert(false);
break;
case BlendMode::BLEND_NONE:
glDisable(GL_BLEND);
break;
case BlendMode::BLEND_ALPHA:
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
break;
case BlendMode::BLEND_ADDITIVE:
glBlendFunc(GL_ONE, GL_ONE);
break;
void setDepthMode(DepthMode mode);
}
}
blendMode = mode;
}
void setDepthMode(DepthMode mode) {
if (mode != depthMode) {
if (depthMode == DepthMode::OFF) glEnable(GL_DEPTH_TEST);
switch(mode) {
case DepthMode::OFF: glDisable(GL_DEPTH_TEST); break;
case DepthMode::LESS: glDepthFunc(GL_LESS); break;
}
depthMode = mode;
}
}
void setDepthWrite(bool enable) {
if (enable != depthWriteEnabled) {
glDepthMask(enable ? GL_TRUE : GL_FALSE);
depthWriteEnabled = enable;
}
}
void setDepthWrite(bool enable);
template <class T>
void uploadUBO(Buffer& buffer, const T& data) {
@ -413,12 +368,7 @@ private:
// Buffer Helpers
bool createUBO(Buffer& out, GLsizei size, GLsizei entrySize);
void attachUBO(GLuint buffer) {
if (currentUBO != buffer) {
glBindBuffer(GL_UNIFORM_BUFFER, buffer);
currentUBO = buffer;
}
}
void attachUBO(GLuint buffer);
void uploadUBOEntry(Buffer& buffer, const void *data, size_t size);

View File

@ -6,8 +6,6 @@
#include <string>
#include <array>
#include <glm/glm.hpp>
#include <gl/DrawBuffer.hpp>
#include <gl/GeometryBuffer.hpp>

View File

@ -1,5 +1,7 @@
#ifndef _RWENGINE_VIEWCAMERA_HPP_
#define _RWENGINE_VIEWCAMERA_HPP_
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/quaternion.hpp>
#include "render/ViewFrustum.hpp"

View File

@ -0,0 +1,35 @@
#include "render/ViewFrustum.hpp"
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
glm::mat4 ViewFrustum::projection() {
return glm::perspective(fov / aspectRatio, aspectRatio, near, far);
}
void ViewFrustum::update(const glm::mat4 &proj) {
for (auto i = 0u; i < 6; ++i) {
float sign = (i % 2 == 0) ? 1.f : -1.f;
auto r = i / 2;
planes[i].normal.x = proj[0][3] + proj[0][r] * sign;
planes[i].normal.y = proj[1][3] + proj[1][r] * sign;
planes[i].normal.z = proj[2][3] + proj[2][r] * sign;
planes[i].distance = proj[3][3] + proj[3][r] * sign;
auto l = glm::length(planes[i].normal);
planes[i].normal /= l;
planes[i].distance /= l;
}
}
bool ViewFrustum::intersects(glm::vec3 center, float radius) const {
float d;
bool result = true;
for (const auto &plane : planes) {
d = glm::dot(plane.normal, center) + plane.distance;
if (d < -radius) result = false;
}
return result;
}

View File

@ -1,8 +1,8 @@
#ifndef _RWENGINE_VIEWFRUSTUM_HPP_
#define _RWENGINE_VIEWFRUSTUM_HPP_
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/mat4x4.hpp>
#include <glm/vec3.hpp>
#ifdef RW_WINDOWS
#include <rw_mingw.hpp>
@ -27,36 +27,11 @@ public:
: near(near), far(far), fov(fov), aspectRatio(aspect) {
}
glm::mat4 projection() {
return glm::perspective(fov / aspectRatio, aspectRatio, near, far);
}
glm::mat4 projection();
void update(const glm::mat4& proj) {
for (auto i = 0u; i < 6; ++i) {
float sign = (i % 2 == 0) ? 1.f : -1.f;
auto r = i / 2;
planes[i].normal.x = proj[0][3] + proj[0][r] * sign;
planes[i].normal.y = proj[1][3] + proj[1][r] * sign;
planes[i].normal.z = proj[2][3] + proj[2][r] * sign;
planes[i].distance = proj[3][3] + proj[3][r] * sign;
void update(const glm::mat4& proj);
auto l = glm::length(planes[i].normal);
planes[i].normal /= l;
planes[i].distance /= l;
}
}
bool intersects(glm::vec3 center, float radius) const {
float d;
bool result = true;
for (const auto &plane : planes) {
d = glm::dot(plane.normal, center) + plane.distance;
if (d < -radius) result = false;
}
return result;
}
bool intersects(glm::vec3 center, float radius) const;
};
#endif

View File

@ -1,7 +1,9 @@
#ifndef _RWENGINE_VISUALFX_HPP_
#define _RWENGINE_VISUALFX_HPP_
#include <glm/glm.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <glm/vec4.hpp>
#include <gl/TextureData.hpp>
@ -22,7 +24,7 @@ struct VisualFX {
struct LightFX final : public VisualFX {
LightFX() = default;
~LightFX() = default;
~LightFX() override = default;
EffectType getType() const override {
return Light;
@ -61,7 +63,7 @@ struct ParticleFX final : public VisualFX {
/** Constructs a particle */
ParticleFX() = default;
~ParticleFX() = default;
~ParticleFX() override = default;
EffectType getType() const override {
return Particle;

View File

@ -7,7 +7,6 @@
#include <gl/DrawBuffer.hpp>
#include <gl/GeometryBuffer.hpp>
#include <gl/gl_core_3_3.h>
#include <render/OpenGLRenderer.hpp>

View File

@ -6,6 +6,7 @@
#include <rw/casts.hpp>
#include <cstdint>
#include <memory>
#include <string>
#include <vector>

View File

@ -235,11 +235,11 @@ inline void removeObjectFromMissionCleanup(const ScriptArguments& args,
}
}
inline void getClosestNode(const ScriptArguments& args, ScriptVec3& coord, AIGraphNode::NodeType type,
inline void getClosestNode(const ScriptArguments& args, ScriptVec3& coord, ai::NodeType type,
ScriptFloat& xCoord, ScriptFloat& yCoord, ScriptFloat& zCoord) {
coord = script::getGround(args, coord);
float closest = 10000.f;
std::vector<AIGraphNode*> nodes;
std::vector<ai::AIGraphNode*> nodes;
args.getWorld()->aigraph.gatherExternalNodesNear(coord, closest, nodes, type);
for (const auto &node : nodes) {

View File

@ -41,7 +41,7 @@ int ScriptArguments::getModel(unsigned int arg) const {
GameObject* ScriptArguments::getPlayerCharacter(unsigned int player) const {
auto playerId = parameters->at(player).integerValue();
PlayerController* controller = getWorld()->players.at(playerId);
auto controller = getWorld()->players.at(playerId);
RW_CHECK(controller != nullptr, "No controller for player " << player);
RW_CHECK(controller->getCharacter(), "No character for player " << player);
return controller->getCharacter();
@ -50,11 +50,11 @@ GameObject* ScriptArguments::getPlayerCharacter(unsigned int player) const {
// @todo figure out original cast
template <>
ScriptGarageType ScriptArguments::getParameter<ScriptGarageType>(unsigned int arg) const {
return static_cast<Garage::Type>(getParameters().at(arg).integerValue());
return static_cast<GarageType>(getParameters().at(arg).integerValue());
}
template <>
GameObject* ScriptArguments::getObject<PlayerController>(
GameObject* ScriptArguments::getObject<ai::PlayerController>(
unsigned int arg) const {
return getPlayerCharacter(arg);
}
@ -187,17 +187,17 @@ ScriptObjectType<PickupObject> ScriptArguments::getScriptObject(
return {param.handleValue(), getObject<PickupObject>(arg)};
}
template <>
ScriptObjectType<PlayerController> ScriptArguments::getScriptObject(
ScriptObjectType<ai::PlayerController> ScriptArguments::getScriptObject(
unsigned int arg) const {
auto& param = (*this)[arg];
RW_CHECK(param.isLvalue(), "Non lvalue passed as object");
/// @todo suport more than one player
auto player = getState()->playerObject;
auto object = getWorld()->pedestrianPool.find(player);
PlayerController* ctrl = nullptr;
ai::PlayerController* ctrl = nullptr;
if (object) {
auto playerObject = static_cast<CharacterObject*>(object);
ctrl = static_cast<PlayerController*>(playerObject->controller);
ctrl = static_cast<ai::PlayerController*>(playerObject->controller);
}
return {param.handleValue(), ctrl};
}

View File

@ -1,18 +1,23 @@
#ifndef _RWENGINE_SCRIPTTYPES_HPP_
#define _RWENGINE_SCRIPTTYPES_HPP_
#include "engine/Garage.hpp"
#include <rw/debug.hpp>
#include <glm/gtc/type_precision.hpp>
#include <glm/vec2.hpp>
#include <glm/vec3.hpp>
#include <cstdint>
#include <functional>
#include <map>
#include <string>
#include <vector>
#include <glm/glm.hpp>
#include <rw/debug.hpp>
#include "audio/Sound.hpp"
#include "engine/Garage.hpp"
namespace ai {
class PlayerController;
} // namespace ai
class CharacterObject;
class CutsceneObject;
@ -20,7 +25,6 @@ class GameObject;
class InstanceObject;
class PickupObject;
class VehicleObject;
class PlayerController;
class ScriptMachine;
class ScriptModule;
struct SCMThread;
@ -28,6 +32,7 @@ class GameState;
class GameWorld;
class Payphone;
class Garage;
struct Sound;
typedef uint16_t SCMOpcode;
typedef char SCMByte;
@ -98,7 +103,7 @@ struct ScriptObjectType {
};
using ScriptObject = ScriptObjectType<InstanceObject>;
using ScriptPlayer = ScriptObjectType<PlayerController>;
using ScriptPlayer = ScriptObjectType<ai::PlayerController>;
using ScriptVehicle = ScriptObjectType<VehicleObject>;
using ScriptCharacter = ScriptObjectType<CharacterObject>;
using ScriptPickup = ScriptObjectType<PickupObject>;
@ -162,7 +167,7 @@ using ScriptParticle = int;
using ScriptTempact = int;
using ScriptSoundType = int;
using ScriptPickupType = int;
using ScriptGarageType = Garage::Type;
using ScriptGarageType = GarageType;
///////////////////////////////////////////////////////////
// Script Bytecode Types
@ -294,7 +299,7 @@ template <>
GameObject* ScriptArguments::getObject<PickupObject>(unsigned int arg) const;
/** Special player-index returning function */
template <>
GameObject* ScriptArguments::getObject<PlayerController>(
GameObject* ScriptArguments::getObject<ai::PlayerController>(
unsigned int arg) const;
template <>
@ -330,7 +335,7 @@ template <>
ScriptObjectType<CharacterObject> ScriptArguments::getScriptObject(
unsigned int arg) const;
template <>
ScriptObjectType<PlayerController> ScriptArguments::getScriptObject(
ScriptObjectType<ai::PlayerController> ScriptArguments::getScriptObject(
unsigned int arg) const;
template <>
ScriptObjectType<CutsceneObject> ScriptArguments::getScriptObject(

View File

@ -1,4 +1,4 @@
#include <ai/PlayerController.hpp>
#include <ai/PlayerController.hpp>
#include <audio/SfxParameters.hpp>
#include <core/Logger.hpp>
#include <data/CutsceneData.hpp>
@ -6,6 +6,7 @@
#include <engine/GameData.hpp>
#include <engine/GameState.hpp>
#include <engine/GameWorld.hpp>
#include <engine/Payphone.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/CutsceneObject.hpp>
#include <objects/InstanceObject.hpp>
@ -913,7 +914,7 @@ void opcode_0053(const ScriptArguments& args, const ScriptInt index, ScriptVec3
/// @todo fix the API interfaces that are now totally incoherent
auto character = args.getWorld()->createPlayer(coord);
character->applyOffset();
player = static_cast<PlayerController*>(character->controller);
player = static_cast<ai::PlayerController*>(character->controller);
args.getState()->playerObject = character->getGameObjectID();
}
@ -2069,7 +2070,7 @@ void opcode_00ae(const ScriptArguments& args, const ScriptVehicle vehicle, const
if (vehicle->getDriver() != nullptr)
{
// @todo set the right driving style and lane
vehicle->getDriver()->controller->setGoal(CharacterController::TrafficDriver);
vehicle->getDriver()->controller->setGoal(ai::CharacterController::TrafficDriver);
vehicle->getDriver()->controller->setLane(1);
}
}
@ -5238,7 +5239,7 @@ void opcode_01d3(const ScriptArguments& args, const ScriptCharacter character, c
RW_UNUSED(args);
character->controller->skipActivity();
character->controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());
std::make_unique<ai::Activities::ExitVehicle>());
}
/**
@ -5252,8 +5253,8 @@ void opcode_01d4(const ScriptArguments& args, const ScriptCharacter character, c
RW_UNUSED(args);
character->controller->skipActivity();
character->controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(
vehicle,Activities::EnterVehicle::ANY_SEAT));
std::make_unique<ai::Activities::EnterVehicle>(
vehicle, ai::Activities::EnterVehicle::ANY_SEAT));
}
/**
@ -5266,7 +5267,7 @@ void opcode_01d4(const ScriptArguments& args, const ScriptCharacter character, c
void opcode_01d5(const ScriptArguments& args, const ScriptCharacter character, const ScriptVehicle vehicle) {
RW_UNUSED(args);
character->controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle));
std::make_unique<ai::Activities::EnterVehicle>(vehicle));
}
/**
@ -5319,7 +5320,7 @@ void opcode_01de(const ScriptArguments& args, const ScriptCharacter character0,
@arg player
*/
void opcode_01df(const ScriptArguments& args, const ScriptCharacter character, const ScriptPlayer player) {
character->controller->setGoal(CharacterController::FollowLeader);
character->controller->setGoal(ai::CharacterController::FollowLeader);
character->controller->setTargetCharacter(player->getCharacter());
RW_UNUSED(args);
}
@ -5432,7 +5433,7 @@ void opcode_01e5(const ScriptArguments& args, const ScriptString gxtEntry, const
@arg coord1 Coordinates
*/
void opcode_01e7(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coord1) {
args.getWorld()->enableAIPaths(AIGraphNode::Vehicle, coord0, coord1);
args.getWorld()->enableAIPaths(ai::NodeType::Vehicle, coord0, coord1);
}
/**
@ -5443,7 +5444,7 @@ void opcode_01e7(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coor
@arg coord1 Coordinates
*/
void opcode_01e8(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coord1) {
args.getWorld()->disableAIPaths(AIGraphNode::Vehicle, coord0, coord1);
args.getWorld()->disableAIPaths(ai::NodeType::Vehicle, coord0, coord1);
}
/**
@ -6009,11 +6010,11 @@ void opcode_0211(const ScriptArguments& args, const ScriptCharacter character, S
{
// Since we just cleared the Activities, this will become current immediatley.
character->controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());
std::make_unique<ai::Activities::ExitVehicle>());
}
character->controller->setNextActivity(
std::make_unique<Activities::GoTo>(target));
std::make_unique<ai::Activities::GoTo>(target));
}
/**
@ -6290,7 +6291,7 @@ void opcode_0229(const ScriptArguments& args, const ScriptVehicle vehicle, const
@arg coord1 Coordinates
*/
void opcode_022a(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coord1) {
args.getWorld()->enableAIPaths(AIGraphNode::Pedestrian, coord0, coord1);
args.getWorld()->enableAIPaths(ai::NodeType::Pedestrian, coord0, coord1);
}
/**
@ -6301,7 +6302,7 @@ void opcode_022a(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coor
@arg coord1 Coordinates
*/
void opcode_022b(const ScriptArguments& args, ScriptVec3 coord0, ScriptVec3 coord1) {
args.getWorld()->disableAIPaths(AIGraphNode::Pedestrian, coord0, coord1);
args.getWorld()->disableAIPaths(ai::NodeType::Pedestrian, coord0, coord1);
}
/**
@ -6438,7 +6439,7 @@ void opcode_0237(const ScriptArguments& args, const ScriptGang gangID, const Scr
void opcode_0239(const ScriptArguments& args, const ScriptCharacter character, ScriptVec2 coord) {
auto target = script::getGround(args, glm::vec3(coord, -100.f));
character->controller->setNextActivity(
std::make_unique<Activities::GoTo>(target, true));
std::make_unique<ai::Activities::GoTo>(target, true));
}
/**
@ -7378,7 +7379,7 @@ bool opcode_02bf(const ScriptArguments& args, const ScriptVehicle vehicle) {
@arg zCoord Z Coord
*/
void opcode_02c0(const ScriptArguments& args, ScriptVec3 coord, ScriptFloat& xCoord, ScriptFloat& yCoord, ScriptFloat& zCoord) {
script::getClosestNode(args, coord, AIGraphNode::NodeType::Pedestrian, xCoord, yCoord, zCoord);
script::getClosestNode(args, coord, ai::NodeType::Pedestrian, xCoord, yCoord, zCoord);
}
/**
@ -7391,7 +7392,7 @@ void opcode_02c0(const ScriptArguments& args, ScriptVec3 coord, ScriptFloat& xCo
@arg zCoord Z Coord
*/
void opcode_02c1(const ScriptArguments& args, ScriptVec3 coord, ScriptFloat& xCoord, ScriptFloat& yCoord, ScriptFloat& zCoord) {
script::getClosestNode(args, coord, AIGraphNode::NodeType::Vehicle, xCoord, yCoord, zCoord);
script::getClosestNode(args, coord, ai::NodeType::Vehicle, xCoord, yCoord, zCoord);
}
/**
@ -10702,7 +10703,7 @@ void opcode_03a5(const ScriptArguments& args, const ScriptGarage garage, const S
RW_UNUSED(args);
garage->type = garageType;
garage->targetModel = model;
garage->state = Garage::State::Closed;
garage->state = GarageState::Closed;
}
/**
@ -10826,7 +10827,7 @@ bool opcode_03b0(const ScriptArguments& args, const ScriptGarage garage) {
*/
bool opcode_03b1(const ScriptArguments& args, const ScriptGarage garage) {
RW_UNUSED(args);
return garage->state == Garage::State::Closed;
return garage->state == GarageState::Closed;
}
/**
@ -11286,7 +11287,7 @@ bool opcode_03d2(const ScriptArguments& args) {
*/
void opcode_03d3(const ScriptArguments& args, ScriptVec3 coord, ScriptFloat& xCoord, ScriptFloat& yCoord, ScriptFloat& zCoord, ScriptFloat& angle) {
RW_UNIMPLEMENTED_OPCODE(0x03d3);
script::getClosestNode(args, coord, AIGraphNode::NodeType::Vehicle, xCoord, yCoord, zCoord);
script::getClosestNode(args, coord, ai::NodeType::Vehicle, xCoord, yCoord, zCoord);
// @todo calculate angle based on node connections
angle = 0.f;
}
@ -11304,10 +11305,10 @@ bool opcode_03d4(const ScriptArguments& args, const ScriptGarage garage, const S
RW_CHECK(entryIndex < 32, "Entry index too high");
// @todo reimplement
if (garage->type == Garage::Type::CollectCars1) {
if (garage->type == GarageType::CollectCars1) {
return args.getState()->importExportPortland[entryIndex];
}
if (garage->type == Garage::Type::CollectCars2) {
if (garage->type == GarageType::CollectCars2) {
return args.getState()->importExportShoreside[entryIndex];
}

View File

@ -1,284 +0,0 @@
#ifndef RWGAME_GAMECONFIG_HPP
#define RWGAME_GAMECONFIG_HPP
#include <map>
#include <string>
#include <vector>
#include <rw/filesystem.hpp>
class GameConfig {
private:
enum ParseType { DEFAULT, CONFIG, FILE, STRING };
/**
* @brief extractFilenameParseTypeData Get a human readable filename string
* @return file path or a description of the data type
*/
static std::string extractFilenameParseTypeData(ParseType type,
const std::string &data);
public:
class ParseResult {
public:
enum ErrorType {
/// UNINITIALIZED: The config was not initialized
UNINITIALIZED,
/// GOOD: Input file/string was good
GOOD,
/// INVALIDINPUTFILE: There was some error while reading from a file
/// or string or the input was ambiguous (e.g. duplicate keys)
INVALIDINPUTFILE,
/// INVALIDARGUMENT: The parser received impossible arguments
INVALIDARGUMENT,
/// INVALIDCONTENT: Some required keys were missing or some values
/// were of incorrect type
INVALIDCONTENT,
/// INVALIDOUTPUTFILE: There was some error while writing to a file
/// or string
INVALIDOUTPUTFILE
};
private:
/**
* @brief ParseResult Holds the issues occurred while parsing of a
* config file.
* @param srcType Type of the source
* @param source The source of the parser
* @param destType Type of the destination
* @param destination The destination
*/
ParseResult(ParseType srcType, const std::string &source,
ParseType destType, const std::string &destination);
/**
* @brief ParseResult Create empty ParseResult
*/
ParseResult();
public:
/**
* @brief type Get the type of error
* @return Type of error or GOOD if there was no error
*/
ErrorType type() const;
/**
* @brief getKeysRequiredMissing Get the keys that were missing
* @return A vector with all the keys
*/
const std::vector<std::string> &getKeysRequiredMissing() const;
/**
* @brief getKeysInvalidData Get the keys that contained invalid data
* @return A vector with all the keys
*/
const std::vector<std::string> &getKeysInvalidData() const;
/**
* @brief Mark this result as valid
*/
void markGood();
/**
* @brief failInputFile Fail because the input file was invalid
* @param line Line number where the error is located
* @param message Description of the error
*/
void failInputFile(size_t line, const std::string &message);
/**
* @brief failArgument Fail because an argument was invalid
* @param srcType type of the source
* @param destType type of the destination
*/
void failArgument();
/**
* @brief failRequiredMissing Fail because a required key is missing
* @param key The key that is missing
*/
void failRequiredMissing(const std::string &key);
/**
* @brief failInvalidData Fail because a key contains invalid data
* @param key The key that contains invalid data
*/
void failInvalidData(const std::string &key);
/**
* @brief failOutputFile Fail because an error occurred while while
* writing to the output
* @param line Line number where the error is located
* @param message Description of the error
*/
void failOutputFile(size_t line, const std::string &message);
/**
* @brief isValid
* @return True if the loaded configuration is valid
*/
bool isValid() const;
/**
* @brief what Get a string representing the error
* @return String with the error description
*/
std::string what() const;
/**
* @brief addUnknownData Add unknown key value pairs
* @param key The unknown key
* @param value The associated data
*/
void addUnknownData(const std::string &key, const std::string &value);
/**
* @brief addUnknownData Get all the unknown key value pairs
* @return Mapping of the unknown keys with associated data
*/
const std::map<std::string, std::string> &getUnknownData() const;
private:
/// Type of the failure
ErrorType m_result;
/// Filename of the input file
std::string m_inputfilename;
/// Filename of the output file
std::string m_outputfilename;
/// Line number where the failure occurred (on invalid input or output
/// file)
size_t m_line;
/// Description of the failure (on invalid input or output file)
std::string m_message;
/// All required keys that are missing
std::vector<std::string> m_keys_requiredMissing;
/// All keys that contain invalid data
std::vector<std::string> m_keys_invalidData;
// Mapping of unknown keys and associated data
std::map<std::string, std::string> m_unknownData;
/**
* @brief setUnknownData Replace the the unknown key value pairs
*/
void setUnknownData(
const std::map<std::string, std::string> &unknownData);
friend class GameConfig;
};
/**
* @brief GameConfig Create a game configuration (initially invalid)
*/
GameConfig() = default;
/**
* @brief Initialize this object using the config file at path
* @param path Path of the configuration file
*/
void loadFile(const rwfs::path &path);
/**
* @brief getConfigPath Returns the path for the configuration
*/
rwfs::path getConfigPath() const;
/**
* @brief writeConfig Save the game configuration
*/
ParseResult saveConfig();
/**
* @brief isValid
* @return True if the loaded configuration is valid
*/
bool isValid() const;
/**
* @brief getParseResult Get more information on parsing failures
* @return A ParseResult object containing more information
*/
const ParseResult &getParseResult() const;
/**
* @brief getConfigString Returns the content of the default INI
* configuration.
* @return INI string
*/
std::string getDefaultINIString();
const rwfs::path &getGameDataPath() const {
return m_gamePath;
}
const std::string &getGameLanguage() const {
return m_gameLanguage;
}
bool getInputInvertY() const {
return m_inputInvertY;
}
int getWindowWidth() const {
return m_windowWidth;
}
int getWindowHeight() const {
return m_windowHeight;
}
bool getWindowFullscreen() const {
return m_windowFullscreen;
}
float getHUDScale() const {
return m_HUDscale;
}
static rwfs::path getDefaultConfigPath();
private:
/**
* @brief parseConfig Load data from source and write it to destination.
* Whitespace will be stripped from unknown data.
* @param srcType Can be DEFAULT | CONFIG | FILE | STRING
* @param source don't care if srcType == (DEFAULT | CONFIG),
* path of INI file if srcType == FILE
* INI string if srcType == STRING
* @param destType Can be CONFIG | FILE | STRING (DEFAULT is invalid)
* @param destination don't care if srcType == CONFIG
* path of INI file if destType == FILE
* INI string if srcType == STRING
* @return True if the parsing succeeded
*/
ParseResult parseConfig(ParseType srcType, const std::string &source,
ParseType destType, std::string &destination);
/* Config State */
rwfs::path m_configPath{};
ParseResult m_parseResult{};
/* Actual Configuration */
/// Path to the game data
rwfs::path m_gamePath;
/// Language for game
std::string m_gameLanguage = "american";
/// Invert the y axis for camera control.
bool m_inputInvertY = false;
/// Size of the window
int m_windowWidth{800};
int m_windowHeight{600};
/// Set the window to fullscreen
bool m_windowFullscreen = false;
/// HUD scale parameter
float m_HUDscale = 1.f;
};
#endif

View File

@ -9,6 +9,8 @@
#include <render/GameRenderer.hpp>
#include <glm/gtc/constants.hpp>
#include <glm/gtc/quaternion.hpp>
#include <iomanip>
#include <sstream>
@ -43,7 +45,7 @@ void HUDDrawer::drawScriptTimer(GameWorld* world, GameRenderer& render) {
}
}
void HUDDrawer::drawMap(ViewCamera& currentView, PlayerController* player,
void HUDDrawer::drawMap(ViewCamera& currentView, ai::PlayerController* player,
GameWorld* world, GameRenderer& render) {
MapRenderer::MapInfo map;
@ -72,7 +74,7 @@ void HUDDrawer::drawMap(ViewCamera& currentView, PlayerController* player,
}
}
void HUDDrawer::drawPlayerInfo(PlayerController* player, GameWorld* world,
void HUDDrawer::drawPlayerInfo(ai::PlayerController* player, GameWorld* world,
GameRenderer& render) {
float infoTextX = static_cast<float>(render.getRenderer().getViewport().x -
(hudParameters.uiOuterMargin + hudParameters.uiWeaponSize + hudParameters.uiInfoMargin));
@ -248,7 +250,7 @@ void HUDDrawer::drawPlayerInfo(PlayerController* player, GameWorld* world,
}
}
void HUDDrawer::drawHUD(ViewCamera& currentView, PlayerController* player,
void HUDDrawer::drawHUD(ViewCamera& currentView, ai::PlayerController* player,
GameWorld* world, GameRenderer& render) {
if (player && player->getCharacter()) {
drawMap(currentView, player, world, render);

View File

@ -1,9 +1,12 @@
#ifndef _RWGAME_HUDDRAWER_HPP_
#define _RWGAME_HUDDRAWER_HPP_
namespace ai {
class PlayerController;
} // namespace ai
class GameWorld;
class GameRenderer;
class PlayerController;
class ViewCamera;
#include <glm/gtc/type_precision.hpp>
@ -44,7 +47,7 @@ public:
void applyHUDScale(float scale);
HUDParameters getHUDParameters();
void drawHUD(ViewCamera& currentView, PlayerController* player,
void drawHUD(ViewCamera& currentView, ai::PlayerController* player,
GameWorld* world, GameRenderer& render);
void drawOnScreenText(GameWorld* world, GameRenderer& renderer);
@ -52,9 +55,9 @@ private:
HUDParameters hudParameters;
void drawScriptTimer(GameWorld* world, GameRenderer& render);
void drawMap(ViewCamera& currentView, PlayerController* player,
void drawMap(ViewCamera& currentView, ai::PlayerController* player,
GameWorld* world, GameRenderer& render);
void drawPlayerInfo(PlayerController* player, GameWorld* world,
void drawPlayerInfo(ai::PlayerController* player, GameWorld* world,
GameRenderer& render);
};

View File

@ -12,11 +12,13 @@
#include <core/Profiler.hpp>
#include <engine/Payphone.hpp>
#include <engine/SaveGame.hpp>
#include <objects/GameObject.hpp>
#include <script/SCMFile.hpp>
#include <ai/AIGraphNode.hpp>
#include <ai/PlayerController.hpp>
#include <core/Logger.hpp>
#include <objects/CharacterObject.hpp>
@ -767,7 +769,7 @@ void RWGame::renderDebugPaths(float time) {
for (const auto& n : world->aigraph.nodes) {
btVector3 p(n->position.x, n->position.y, n->position.z);
auto& col = n->type == AIGraphNode::Pedestrian ? pedColour : roadColour;
auto& col = n->type == ai::NodeType::Pedestrian ? pedColour : roadColour;
debug.drawLine(p - btVector3(0.f, 0.f, 1.f),
p + btVector3(0.f, 0.f, 1.f), col);
debug.drawLine(p - btVector3(1.f, 0.f, 0.f),

View File

@ -19,8 +19,6 @@
#include <chrono>
class PlayerController;
class RWGame final : public GameBase {
GameData data;
GameRenderer renderer;

View File

@ -2,6 +2,8 @@
#include "RWGame.hpp"
#include <glm/gtc/quaternion.hpp>
// This serves as the "initial" camera position.
const ViewCamera defaultView{{-250.f, -550.f, 75.f},
glm::angleAxis(glm::radians(5.f),

View File

@ -2,6 +2,8 @@
#include <engine/GameState.hpp>
#include "RWGame.hpp"
#include <glm/gtc/quaternion.hpp>
#include <fstream>
#include <iostream>

View File

@ -527,7 +527,7 @@ void DebugState::spawnFollower(unsigned int id) {
auto spawnPos = hit + normal;
auto follower = game->getWorld()->createPedestrian(id, spawnPos);
jumpCharacter(game, follower, spawnPos);
follower->controller->setGoal(CharacterController::FollowLeader);
follower->controller->setGoal(ai::CharacterController::FollowLeader);
follower->controller->setTargetCharacter(ch);
}
}

View File

@ -27,6 +27,8 @@
#pragma warning(disable : 4305)
#endif
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
#include <BulletDynamics/Dynamics/btRigidBody.h>
#include <btBulletDynamicsCommon.h>
#ifdef _MSC_VER
#pragma warning(default : 4305)
#endif
@ -251,12 +253,12 @@ void IngameState::tick(float dt) {
if (player->getCharacter()->getCurrentVehicle()) {
player->exitVehicle();
} else if (!player->isCurrentActivity(
Activities::EnterVehicle::ActivityName)) {
ai::Activities::EnterVehicle::ActivityName)) {
player->enterNearestVehicle();
}
} else if (glm::length2(movement) > 0.001f) {
if (player->isCurrentActivity(
Activities::EnterVehicle::ActivityName)) {
ai::Activities::EnterVehicle::ActivityName)) {
// Give up entering a vehicle if we're alreadying doing so
player->skipActivity();
}

View File

@ -22,7 +22,7 @@ BOOST_AUTO_TEST_CASE(test_create) {
// Check that Idle activities are instantly displaced.
controller->setNextActivity(
std::make_unique<Activities::GoTo>(glm::vec3{1000.f, 0.f, 0.f}));
std::make_unique<ai::Activities::GoTo>(glm::vec3{1000.f, 0.f, 0.f}));
BOOST_CHECK_EQUAL(controller->getCurrentActivity()->name(), "GoTo");
BOOST_CHECK_EQUAL(controller->getNextActivity(), nullptr);
@ -41,7 +41,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_REQUIRE(controller != nullptr);
controller->setNextActivity(
std::make_unique<Activities::GoTo>(glm::vec3{10.f, 10.f, 0.f}));
std::make_unique<ai::Activities::GoTo>(glm::vec3{10.f, 10.f, 0.f}));
BOOST_CHECK_EQUAL(controller->getCurrentActivity()->name(), "GoTo");
@ -71,7 +71,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_REQUIRE(controller != nullptr);
controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle, 0));
std::make_unique<ai::Activities::EnterVehicle>(vehicle, 0));
for (float t = 0.f; t < 0.5f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);
@ -88,7 +88,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
BOOST_CHECK_EQUAL(vehicle, character->getCurrentVehicle());
controller->setNextActivity(
std::make_unique<Activities::ExitVehicle>());
std::make_unique<ai::Activities::ExitVehicle>());
for (float t = 0.f; t < 9.0f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);
@ -99,7 +99,7 @@ BOOST_AUTO_TEST_CASE(test_activities) {
character->setPosition(glm::vec3(5.f, 0.f, 0.f));
controller->setNextActivity(
std::make_unique<Activities::EnterVehicle>(vehicle, 0));
std::make_unique<ai::Activities::EnterVehicle>(vehicle, 0));
for (float t = 0.f; t < 0.5f; t += (1.f / 60.f)) {
character->tick(1.f / 60.f);

View File

@ -8,7 +8,7 @@ BOOST_AUTO_TEST_SUITE(GarageTests)
BOOST_AUTO_TEST_CASE(test_garage_interaction) {
{
auto garage = Global::get().e->createGarage(
{0.f, 0.f, 0.f}, {3.f, 3.f, 3.f}, Garage::Type::Respray);
{0.f, 0.f, 0.f}, {3.f, 3.f, 3.f}, GarageType::Respray);
BOOST_REQUIRE(garage != nullptr);
}
}

View File

@ -3,6 +3,7 @@
#include <boost/test/unit_test.hpp>
#include <audio/Sound.hpp>
#include <audio/SoundBuffer.hpp>
#include <audio/SoundManager.hpp>
BOOST_AUTO_TEST_SUITE(SoundTests)

View File

@ -2,15 +2,17 @@
#include "test_Globals.hpp"
#include <ai/AIGraph.hpp>
#include <ai/AIGraphNode.hpp>
#include <ai/TrafficDirector.hpp>
#include <data/PathData.hpp>
#include <objects/CharacterObject.hpp>
#include <objects/InstanceObject.hpp>
#include <render/ViewCamera.hpp>
bool operator!=(const AIGraphNode* lhs, const glm::vec3& rhs) {
bool operator!=(const ai::AIGraphNode* lhs, const glm::vec3& rhs) {
return lhs->position != rhs;
}
std::ostream& operator<<(std::ostream& os, const AIGraphNode* yt) {
std::ostream& operator<<(std::ostream& os, const ai::AIGraphNode* yt) {
os << glm::to_string(yt->position);
return os;
}
@ -19,7 +21,7 @@ BOOST_AUTO_TEST_SUITE(TrafficDirectorTests)
#if RW_TEST_WITH_DATA
BOOST_AUTO_TEST_CASE(test_available_nodes) {
AIGraph graph;
ai::AIGraph graph;
PathData path{PathData::PATH_PED,
0,
@ -36,12 +38,12 @@ BOOST_AUTO_TEST_CASE(test_available_nodes) {
graph.createPathNodes(glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}, path);
TrafficDirector director(&graph, Global::get().e);
ai::TrafficDirector director(&graph, Global::get().e);
ViewCamera testCamera(glm::vec3(-5.f, -5.f, 0.f));
auto open =
director.findAvailableNodes(AIGraphNode::Pedestrian, testCamera, 10.f);
director.findAvailableNodes(ai::NodeType::Pedestrian, testCamera, 10.f);
std::vector<glm::vec3> expected{
{0.f, -10.f, 0.f}, {-10.f, -10.f, 0.f}, {-10.f, 0.f, 0.f}};
@ -50,14 +52,14 @@ BOOST_AUTO_TEST_CASE(test_available_nodes) {
BOOST_ASSERT(expected.size() == open.size());
for (auto& v : expected) {
BOOST_CHECK(std::find_if(open.begin(), open.end(), [v](AIGraphNode* n) {
BOOST_CHECK(std::find_if(open.begin(), open.end(), [v](ai::AIGraphNode* n) {
return n->position == v;
}) != open.end());
}
}
BOOST_AUTO_TEST_CASE(test_node_not_blocking) {
AIGraph graph;
ai::AIGraph graph;
PathData path{PathData::PATH_PED,
0,
@ -68,14 +70,14 @@ BOOST_AUTO_TEST_CASE(test_node_not_blocking) {
graph.createPathNodes(glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}, path);
TrafficDirector director(&graph, Global::get().e);
ai::TrafficDirector director(&graph, Global::get().e);
// Create something that isn't a pedestrian
InstanceObject* box =
Global::get().e->createInstance(1337, glm::vec3(10.f, 10.f, 0.f));
{
auto open = director.findAvailableNodes(AIGraphNode::Pedestrian,
auto open = director.findAvailableNodes(ai::NodeType::Pedestrian,
glm::vec3(5.f, 5.f, 0.f), 10.f);
BOOST_CHECK(open.size() == 1);
}
@ -84,7 +86,7 @@ BOOST_AUTO_TEST_CASE(test_node_not_blocking) {
}
BOOST_AUTO_TEST_CASE(test_node_blocking) {
AIGraph graph;
ai::AIGraph graph;
PathData path{PathData::PATH_PED,
0,
@ -95,14 +97,14 @@ BOOST_AUTO_TEST_CASE(test_node_blocking) {
graph.createPathNodes(glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}, path);
TrafficDirector director(&graph, Global::get().e);
ai::TrafficDirector director(&graph, Global::get().e);
// create something that should block the spawn point
CharacterObject* ped =
Global::get().e->createPedestrian(1, glm::vec3(10.f, 10.f, 0.f));
{
auto open = director.findAvailableNodes(AIGraphNode::Pedestrian,
auto open = director.findAvailableNodes(ai::NodeType::Pedestrian,
glm::vec3(5.f, 5.f, 0.f), 10.f);
BOOST_CHECK(open.size() == 0);
}
@ -111,7 +113,7 @@ BOOST_AUTO_TEST_CASE(test_node_blocking) {
}
BOOST_AUTO_TEST_CASE(test_node_density) {
AIGraph graph;
ai::AIGraph graph;
PathData path{PathData::PATH_PED,
0,
@ -122,21 +124,21 @@ BOOST_AUTO_TEST_CASE(test_node_density) {
graph.createPathNodes(glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}, path);
TrafficDirector director(&graph, Global::get().e);
ai::TrafficDirector director(&graph, Global::get().e);
CharacterObject* ped =
Global::get().e->createPedestrian(1, glm::vec3(5.f, 5.f, 0.f));
{
director.setDensity(AIGraphNode::Pedestrian, 1.f);
auto open = director.findAvailableNodes(AIGraphNode::Pedestrian,
director.setDensity(ai::NodeType::Pedestrian, 1.f);
auto open = director.findAvailableNodes(ai::NodeType::Pedestrian,
glm::vec3(5.f, 5.f, 0.f), 10.f);
BOOST_CHECK(open.size() == 0);
}
{
director.setDensity(AIGraphNode::Pedestrian, 2.f);
auto open = director.findAvailableNodes(AIGraphNode::Pedestrian,
director.setDensity(ai::NodeType::Pedestrian, 2.f);
auto open = director.findAvailableNodes(ai::NodeType::Pedestrian,
glm::vec3(5.f, 5.f, 0.f), 10.f);
BOOST_CHECK(open.size() == 1);
}
@ -145,7 +147,7 @@ BOOST_AUTO_TEST_CASE(test_node_density) {
}
BOOST_AUTO_TEST_CASE(test_create_traffic) {
AIGraph graph;
ai::AIGraph graph;
PathData path{PathData::PATH_PED,
0,
@ -156,7 +158,7 @@ BOOST_AUTO_TEST_CASE(test_create_traffic) {
graph.createPathNodes(glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}, path);
TrafficDirector director(&graph, Global::get().e);
ai::TrafficDirector director(&graph, Global::get().e);
auto created = director.populateNearby(glm::vec3(0.f, 0.f, 0.f), 20.f);