diff --git a/rwcore/rw/types.hpp b/rwcore/rw/types.hpp index d5bde0dd..5d971e6b 100644 --- a/rwcore/rw/types.hpp +++ b/rwcore/rw/types.hpp @@ -2,7 +2,6 @@ #define _LIBRW_TYPES_HPP_ #include -#include #include #include #include diff --git a/rwengine/CMakeLists.txt b/rwengine/CMakeLists.txt index 9019e3dd..cddfe5f9 100644 --- a/rwengine/CMakeLists.txt +++ b/rwengine/CMakeLists.txt @@ -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 diff --git a/rwengine/src/ai/AIGraph.cpp b/rwengine/src/ai/AIGraph.cpp index 9d8debbb..20f20e79 100644 --- a/rwengine/src/ai/AIGraph.cpp +++ b/rwengine/src/ai/AIGraph.cpp @@ -11,6 +11,8 @@ #include #include +namespace ai { + void AIGraph::createPathNodes(const glm::vec3& position, const glm::quat& rotation, PathData& path) { auto startIndex = static_cast(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& 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 diff --git a/rwengine/src/ai/AIGraph.hpp b/rwengine/src/ai/AIGraph.hpp index a6f13dc3..bb27fc4c 100644 --- a/rwengine/src/ai/AIGraph.hpp +++ b/rwengine/src/ai/AIGraph.hpp @@ -1,17 +1,20 @@ #ifndef _RWENGINE_AIGRAPH_HPP_ #define _RWENGINE_AIGRAPH_HPP_ -#include -#include -#include - -#include "ai/AIGraphNode.hpp" +#include #include -struct AIGraphNode; +#include +#include + 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& nodes, AIGraphNode::NodeType type); + std::vector& nodes, NodeType type); }; +} // ai + #endif diff --git a/rwengine/src/ai/AIGraphNode.hpp b/rwengine/src/ai/AIGraphNode.hpp index dce0b9d7..a19928c8 100644 --- a/rwengine/src/ai/AIGraphNode.hpp +++ b/rwengine/src/ai/AIGraphNode.hpp @@ -1,12 +1,16 @@ #ifndef _RWENGINE_AIGRAPHNODE_HPP_ #define _RWENGINE_AIGRAPHNODE_HPP_ + +#include + #include -#include #include -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 connections; }; +} // namespace ai + #endif diff --git a/rwengine/src/ai/CharacterController.cpp b/rwengine/src/ai/CharacterController.cpp index b2d5f2f8..99780adc 100644 --- a/rwengine/src/ai/CharacterController.cpp +++ b/rwengine/src/ai/CharacterController.cpp @@ -21,6 +21,8 @@ #include #include +#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 diff --git a/rwengine/src/ai/CharacterController.hpp b/rwengine/src/ai/CharacterController.hpp index 9a161b2f..c4e96511 100644 --- a/rwengine/src/ai/CharacterController.hpp +++ b/rwengine/src/ai/CharacterController.hpp @@ -1,14 +1,19 @@ #ifndef _RWENGINE_CHARACTERCONTROLLER_HPP_ #define _RWENGINE_CHARACTERCONTROLLER_HPP_ -#include + +#include +#include #include #include -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 _currentActivity = nullptr; std::unique_ptr _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 diff --git a/rwengine/src/ai/DefaultAIController.cpp b/rwengine/src/ai/DefaultAIController.cpp index d447a0f2..56d2fcd1 100644 --- a/rwengine/src/ai/DefaultAIController.cpp +++ b/rwengine/src/ai/DefaultAIController.cpp @@ -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::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 diff --git a/rwengine/src/ai/DefaultAIController.hpp b/rwengine/src/ai/DefaultAIController.hpp index d1e115e2..343e471e 100644 --- a/rwengine/src/ai/DefaultAIController.hpp +++ b/rwengine/src/ai/DefaultAIController.hpp @@ -1,14 +1,17 @@ #ifndef _RWENGINE_DEFAULTAICONTROLLER_HPP_ #define _RWENGINE_DEFAULTAICONTROLLER_HPP_ -#include -#include + +#include + +#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 diff --git a/rwengine/src/ai/PlayerController.cpp b/rwengine/src/ai/PlayerController.cpp index 4a180d0b..58247673 100644 --- a/rwengine/src/ai/PlayerController.cpp +++ b/rwengine/src/ai/PlayerController.cpp @@ -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 diff --git a/rwengine/src/ai/PlayerController.hpp b/rwengine/src/ai/PlayerController.hpp index 23eb4b58..40fdd82c 100644 --- a/rwengine/src/ai/PlayerController.hpp +++ b/rwengine/src/ai/PlayerController.hpp @@ -1,10 +1,12 @@ #ifndef _RWENGINE_PLAYERCONTROLLER_HPP_ #define _RWENGINE_PLAYERCONTROLLER_HPP_ -#include -#include +#include "ai/CharacterController.hpp" + #include +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 diff --git a/rwengine/src/ai/TrafficDirector.cpp b/rwengine/src/ai/TrafficDirector.cpp index 570f1743..c6f0b84c 100644 --- a/rwengine/src/ai/TrafficDirector.cpp +++ b/rwengine/src/ai/TrafficDirector.cpp @@ -24,19 +24,21 @@ #include #endif +namespace ai { + TrafficDirector::TrafficDirector(AIGraph* g, GameWorld* w) : graph(g) , world(w) { } -std::vector TrafficDirector::findAvailableNodes( - AIGraphNode::NodeType type, const ViewCamera& camera, float radius) { - std::vector available; +std::vector TrafficDirector::findAvailableNodes( + ai::NodeType type, const ViewCamera& camera, float radius) { + std::vector 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 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 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 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 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 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 diff --git a/rwengine/src/ai/TrafficDirector.hpp b/rwengine/src/ai/TrafficDirector.hpp index db967ed8..5b182544 100644 --- a/rwengine/src/ai/TrafficDirector.hpp +++ b/rwengine/src/ai/TrafficDirector.hpp @@ -1,24 +1,27 @@ #ifndef _RWENGINE_TRAFFICDIRECTOR_HPP_ #define _RWENGINE_TRAFFICDIRECTOR_HPP_ -#include "AIGraphNode.hpp" - #include -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 findAvailableNodes(AIGraphNode::NodeType type, + std::vector 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 diff --git a/rwengine/src/audio/Sound.cpp b/rwengine/src/audio/Sound.cpp new file mode 100644 index 00000000..df934cd7 --- /dev/null +++ b/rwengine/src/audio/Sound.cpp @@ -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; +} diff --git a/rwengine/src/audio/Sound.hpp b/rwengine/src/audio/Sound.hpp index c5669488..fbb29122 100644 --- a/rwengine/src/audio/Sound.hpp +++ b/rwengine/src/audio/Sound.hpp @@ -1,19 +1,12 @@ #ifndef _RWENGINE_SOUND_HPP_ #define _RWENGINE_SOUND_HPP_ +#include + #include -#include -#include -#include -#include -#include - -#include -#include - -#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 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 diff --git a/rwengine/src/audio/SoundBuffer.cpp b/rwengine/src/audio/SoundBuffer.cpp index 80f93843..9d367eb8 100644 --- a/rwengine/src/audio/SoundBuffer.cpp +++ b/rwengine/src/audio/SoundBuffer.cpp @@ -3,6 +3,7 @@ #include #include "audio/alCheck.hpp" +#include "audio/SoundSource.hpp" SoundBuffer::SoundBuffer() { alCheck(alGenSources(1, &source)); diff --git a/rwengine/src/audio/SoundBuffer.hpp b/rwengine/src/audio/SoundBuffer.hpp index 0b06a385..2a5f6949 100644 --- a/rwengine/src/audio/SoundBuffer.hpp +++ b/rwengine/src/audio/SoundBuffer.hpp @@ -2,10 +2,9 @@ #define _RWENGINE_SOUND_BUFFER_HPP_ #include -#include -#include +#include -#include "audio/SoundSource.hpp" +class SoundSource; /// OpenAL tool for playing /// sound instance. diff --git a/rwengine/src/audio/SoundManager.cpp b/rwengine/src/audio/SoundManager.cpp index f3325b70..328feef7 100644 --- a/rwengine/src/audio/SoundManager.cpp +++ b/rwengine/src/audio/SoundManager.cpp @@ -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" diff --git a/rwengine/src/audio/SoundManager.hpp b/rwengine/src/audio/SoundManager.hpp index 09a1ab55..07efda60 100644 --- a/rwengine/src/audio/SoundManager.hpp +++ b/rwengine/src/audio/SoundManager.hpp @@ -3,21 +3,16 @@ #include "audio/Sound.hpp" -#include -#include -#include -#include -#include -#include -#include - -#include #include -#include + +#include #include #include +#include +#include + class GameWorld; class ViewCamera; diff --git a/rwengine/src/audio/SoundSource.hpp b/rwengine/src/audio/SoundSource.hpp index 7f3334b5..6a30eadc 100644 --- a/rwengine/src/audio/SoundSource.hpp +++ b/rwengine/src/audio/SoundSource.hpp @@ -1,11 +1,12 @@ #ifndef _RWENGINE_SOUND_SOURCE_HPP_ #define _RWENGINE_SOUND_SOURCE_HPP_ -#include #include #include +class LoaderSDT; + /// Opaque for raw sound, /// cooperate with ffmpeg /// (loading and decoding sound) diff --git a/rwengine/src/data/Chase.cpp b/rwengine/src/data/Chase.cpp index ad2a615b..b70c1d89 100644 --- a/rwengine/src/data/Chase.cpp +++ b/rwengine/src/data/Chase.cpp @@ -6,6 +6,8 @@ #include +#include + #include "engine/GameWorld.hpp" #include "objects/GameObject.hpp" diff --git a/rwengine/src/data/Chase.hpp b/rwengine/src/data/Chase.hpp index 14d52b7f..306b19a0 100644 --- a/rwengine/src/data/Chase.hpp +++ b/rwengine/src/data/Chase.hpp @@ -1,8 +1,9 @@ #ifndef _RWENGINE_CHASE_HPP_ #define _RWENGINE_CHASE_HPP_ -#include #include +#include + #include #include #include diff --git a/rwengine/src/data/CollisionModel.hpp b/rwengine/src/data/CollisionModel.hpp index 2e8f2690..99b44563 100644 --- a/rwengine/src/data/CollisionModel.hpp +++ b/rwengine/src/data/CollisionModel.hpp @@ -1,7 +1,9 @@ #ifndef _RWENGINE_COLLISIONMODEL_HPP_ #define _RWENGINE_COLLISIONMODEL_HPP_ + +#include + #include -#include #include #include diff --git a/rwengine/src/data/CutsceneData.cpp b/rwengine/src/data/CutsceneData.cpp new file mode 100644 index 00000000..6dd67030 --- /dev/null +++ b/rwengine/src/data/CutsceneData.cpp @@ -0,0 +1,95 @@ +#include "data/CutsceneData.hpp" + +#include + +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; +} diff --git a/rwengine/src/data/CutsceneData.hpp b/rwengine/src/data/CutsceneData.hpp index d3526321..ca77996c 100644 --- a/rwengine/src/data/CutsceneData.hpp +++ b/rwengine/src/data/CutsceneData.hpp @@ -1,6 +1,8 @@ #ifndef _RWENGINE_CUTSCENEDATA_HPP_ #define _RWENGINE_CUTSCENEDATA_HPP_ -#include + +#include + #include #include #include @@ -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 { diff --git a/rwengine/src/data/InstanceData.hpp b/rwengine/src/data/InstanceData.hpp index f7be3b09..2a2fc316 100644 --- a/rwengine/src/data/InstanceData.hpp +++ b/rwengine/src/data/InstanceData.hpp @@ -1,7 +1,9 @@ #ifndef _RWENGINE_INSTANCEDATA_HPP_ #define _RWENGINE_INSTANCEDATA_HPP_ -#include + #include +#include + #include struct InstanceData { diff --git a/rwengine/src/data/ModelData.cpp b/rwengine/src/data/ModelData.cpp index 88362551..b00edd6c 100644 --- a/rwengine/src/data/ModelData.cpp +++ b/rwengine/src/data/ModelData.cpp @@ -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 &col) { + collision = std::move(col); +} + +BaseModelInfo::~BaseModelInfo() = default; diff --git a/rwengine/src/data/ModelData.hpp b/rwengine/src/data/ModelData.hpp index 8abe09c8..5c40057d 100644 --- a/rwengine/src/data/ModelData.hpp +++ b/rwengine/src/data/ModelData.hpp @@ -1,8 +1,15 @@ #ifndef _RWENGINE_MODELDATA_HPP_ #define _RWENGINE_MODELDATA_HPP_ + +#include +#include + +#ifdef RW_WINDOWS +#include +#endif + #include #include -#include #include #include #include @@ -10,15 +17,8 @@ #include #include -#include -#include -#include - -#include -#include -#ifdef RW_WINDOWS -#include -#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& col) { - collision = std::move(col); - } + void setCollisionModel(std::unique_ptr& col); CollisionModel* getCollision() const { return collision.get(); @@ -146,10 +143,9 @@ public: /// @todo remove this from here too :) std::vector 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) { diff --git a/rwengine/src/data/PathData.hpp b/rwengine/src/data/PathData.hpp index 788e7675..75aec6f7 100644 --- a/rwengine/src/data/PathData.hpp +++ b/rwengine/src/data/PathData.hpp @@ -1,7 +1,9 @@ #ifndef _RWENGINE_PATHDATA_HPP_ #define _RWENGINE_PATHDATA_HPP_ + +#include + #include -#include #include #include diff --git a/rwengine/src/data/PedData.hpp b/rwengine/src/data/PedData.hpp index 90c1bd2b..528c9a63 100644 --- a/rwengine/src/data/PedData.hpp +++ b/rwengine/src/data/PedData.hpp @@ -1,5 +1,6 @@ #ifndef _RWENGINE_PEDDATA_HPP_ #define _RWENGINE_PEDDATA_HPP_ + #include #include #include diff --git a/rwengine/src/data/VehicleGenerator.hpp b/rwengine/src/data/VehicleGenerator.hpp index a969e743..30cae5e0 100644 --- a/rwengine/src/data/VehicleGenerator.hpp +++ b/rwengine/src/data/VehicleGenerator.hpp @@ -1,6 +1,7 @@ #ifndef RWENGINE_VEHICLEGENERATOR_HPP #define RWENGINE_VEHICLEGENERATOR_HPP -#include + +#include /** * Stores information about where the game can generate vehicles. diff --git a/rwengine/src/data/WeaponData.hpp b/rwengine/src/data/WeaponData.hpp index f00a3fbe..7004f2a7 100644 --- a/rwengine/src/data/WeaponData.hpp +++ b/rwengine/src/data/WeaponData.hpp @@ -1,7 +1,9 @@ #ifndef _RWENGINE_WEAPONDATA_HPP_ #define _RWENGINE_WEAPONDATA_HPP_ + +#include + #include -#include #include struct WeaponData { diff --git a/rwengine/src/data/Weather.cpp b/rwengine/src/data/Weather.cpp index 4855891c..8c6855fc 100644 --- a/rwengine/src/data/Weather.cpp +++ b/rwengine/src/data/Weather.cpp @@ -1,5 +1,6 @@ #include "Weather.hpp" +#include namespace { Weather::Entry interpolateWeather(const Weather::Entry& a, diff --git a/rwengine/src/data/Weather.hpp b/rwengine/src/data/Weather.hpp index 41adb617..582d10ec 100644 --- a/rwengine/src/data/Weather.hpp +++ b/rwengine/src/data/Weather.hpp @@ -1,12 +1,13 @@ #ifndef _RWENGINE_WEATHER_HPP_ #define _RWENGINE_WEATHER_HPP_ +#include + #include #include #include -#include enum class WeatherCondition { Sunny = 0, Cloudy = 1, Rainy = 2, Foggy = 3 }; diff --git a/rwengine/src/data/ZoneData.cpp b/rwengine/src/data/ZoneData.cpp new file mode 100644 index 00000000..49f4ac98 --- /dev/null +++ b/rwengine/src/data/ZoneData.cpp @@ -0,0 +1,50 @@ +#include "data/ZoneData.hpp" + +#include "glm/glm.hpp" + +#include + +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; +} diff --git a/rwengine/src/data/ZoneData.hpp b/rwengine/src/data/ZoneData.hpp index 0205ddeb..df7932cd 100644 --- a/rwengine/src/data/ZoneData.hpp +++ b/rwengine/src/data/ZoneData.hpp @@ -1,8 +1,8 @@ #ifndef _RWENGINE_ZONEDATA_HPP_ #define _RWENGINE_ZONEDATA_HPP_ -#include -#include +#include + #include #include #include @@ -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; diff --git a/rwengine/src/engine/Animator.hpp b/rwengine/src/engine/Animator.hpp index 783e2d24..7c7c13d8 100644 --- a/rwengine/src/engine/Animator.hpp +++ b/rwengine/src/engine/Animator.hpp @@ -1,11 +1,12 @@ #ifndef _RWENGINE_ANIMATOR_HPP_ #define _RWENGINE_ANIMATOR_HPP_ -#include -#include #include #include +#include +#include + struct AnimationBone; class ModelFrame; diff --git a/rwengine/src/engine/GameData.cpp b/rwengine/src/engine/GameData.cpp index b7731c91..2f9f20f7 100644 --- a/rwengine/src/engine/GameData.cpp +++ b/rwengine/src/engine/GameData.cpp @@ -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((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]; } diff --git a/rwengine/src/engine/GameData.hpp b/rwengine/src/engine/GameData.hpp index 6fef3b1e..68edff43 100644 --- a/rwengine/src/engine/GameData.hpp +++ b/rwengine/src/engine/GameData.hpp @@ -11,8 +11,6 @@ #include #include -#include - #include #include #include @@ -28,7 +26,6 @@ #include #include #include -#include 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> modelinfo; diff --git a/rwengine/src/engine/GameState.hpp b/rwengine/src/engine/GameState.hpp index 21696d07..99013b32 100644 --- a/rwengine/src/engine/GameState.hpp +++ b/rwengine/src/engine/GameState.hpp @@ -1,14 +1,5 @@ #ifndef _RWENGINE_GAMESTATE_HPP_ #define _RWENGINE_GAMESTATE_HPP_ -#include -#include -#include -#include -#include -#include - -#include -#include #include #include "data/CutsceneData.hpp" @@ -20,6 +11,17 @@ #include "objects/ObjectTypes.hpp" #include "script/ScriptTypes.hpp" +#include +#include +#include + +#include +#include +#include +#include +#include +#include + class GameWorld; class GameObject; class ScriptMachine; diff --git a/rwengine/src/engine/GameWorld.cpp b/rwengine/src/engine/GameWorld.cpp index 716af9e9..4170ff3b 100644 --- a/rwengine/src/engine/GameWorld.cpp +++ b/rwengine/src/engine/GameWorld.cpp @@ -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(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(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(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(object)->controller; - return static_cast(controller); + return static_cast(controller); } return nullptr; } diff --git a/rwengine/src/engine/GameWorld.hpp b/rwengine/src/engine/GameWorld.hpp index 1fd9f0a9..e928058a 100644 --- a/rwengine/src/engine/GameWorld.hpp +++ b/rwengine/src/engine/GameWorld.hpp @@ -17,20 +17,11 @@ #pragma warning(default : 4305) #endif -#include -#include - #include -#include #include