mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 11:52:40 +01:00
Primitive debug menu; vehicle enter animation
This commit is contained in:
parent
d7b738cdc1
commit
04842a628a
@ -88,8 +88,10 @@ namespace Activities {
|
||||
GTAVehicle* vehicle;
|
||||
unsigned int seat;
|
||||
|
||||
bool entering;
|
||||
|
||||
EnterVehicle( GTAVehicle* vehicle, unsigned int seat = 0 )
|
||||
: vehicle( vehicle ), seat( seat ) {}
|
||||
: vehicle( vehicle ), seat( seat ), entering(false) {}
|
||||
|
||||
bool update(GTACharacter *character, GTAAIController *controller);
|
||||
};
|
||||
|
@ -24,10 +24,12 @@ struct AnimationGroup
|
||||
Animation* car_sit;
|
||||
Animation* car_sit_low;
|
||||
|
||||
Animation* car_getin_lhs;
|
||||
|
||||
AnimationGroup()
|
||||
: idle(nullptr), walk(nullptr), walk_start(nullptr), run(nullptr),
|
||||
jump_start(nullptr), jump_glide(nullptr), jump_land(nullptr),
|
||||
car_sit(nullptr), car_sit_low(nullptr)
|
||||
car_sit(nullptr), car_sit_low(nullptr), car_getin_lhs(nullptr)
|
||||
{}
|
||||
};
|
||||
|
||||
@ -59,6 +61,7 @@ public:
|
||||
Jump,
|
||||
Falling,
|
||||
Landing,
|
||||
VehicleGetIn,
|
||||
VehicleDrive,
|
||||
VehicleSit,
|
||||
KnockedDown,
|
||||
|
@ -93,7 +93,9 @@ public:
|
||||
void setOccupant(size_t seat, GameObject* occupant);
|
||||
|
||||
glm::vec3 getSeatEntryPosition(size_t seat) const {
|
||||
return getPosition() + getRotation() * info->seats[seat].offset * glm::vec3(2.f, 1.f, 1.f);
|
||||
auto pos = info->seats[seat].offset;
|
||||
pos.x = glm::sign(pos.x) * 1.5f;
|
||||
return getPosition() + getRotation() * pos;
|
||||
}
|
||||
|
||||
virtual bool takeDamage(const DamageInfo& damage);
|
||||
|
@ -1,5 +1,6 @@
|
||||
#include <ai/GTAAIController.hpp>
|
||||
#include <objects/GTACharacter.hpp>
|
||||
#include <engine/Animator.hpp>
|
||||
|
||||
bool GTAAIController::updateActivity()
|
||||
{
|
||||
@ -75,21 +76,30 @@ bool Activities::GoTo::update(GTACharacter *character, GTAAIController *controll
|
||||
|
||||
bool Activities::EnterVehicle::update(GTACharacter *character, GTAAIController *controller)
|
||||
{
|
||||
glm::vec3 target = vehicle->getSeatEntryPosition(seat);
|
||||
glm::vec3 targetDirection = target - character->getPosition();
|
||||
|
||||
if( glm::length(targetDirection) < 0.01f ) {
|
||||
// TODO: play enter vehicle animation instead of teleporting.
|
||||
// The correct Action is handled by the character
|
||||
if( entering ) {
|
||||
std::cout << "Checking" << std::endl;
|
||||
if( character->currentActivity == GTACharacter::Idle ) {
|
||||
std::cout << "was idle" << std::endl;
|
||||
character->enterVehicle(vehicle, seat);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else {
|
||||
glm::vec3 target = vehicle->getSeatEntryPosition(seat);
|
||||
glm::vec3 targetDirection = target - character->getPosition();
|
||||
|
||||
if( glm::length(targetDirection) <= 0.4f ) {
|
||||
std::cout << "enter started" << std::endl;
|
||||
entering = true;
|
||||
character->enterAction(GTACharacter::VehicleGetIn);
|
||||
}
|
||||
else {
|
||||
character->setTargetPosition( target );
|
||||
|
||||
glm::quat r( glm::vec3{ 0.f, 0.f, atan2(targetDirection.y, targetDirection.x) - glm::half_pi<float>() } );
|
||||
character->rotation = r;
|
||||
character->enterAction(GTACharacter::Walk);
|
||||
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@ -55,13 +55,14 @@ void GTAPlayerAIController::enterNearestVehicle()
|
||||
}
|
||||
|
||||
if( nearest ) {
|
||||
character->enterVehicle(nearest, 0);
|
||||
setNextActivity(new Activities::EnterVehicle(nearest, 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GTAPlayerAIController::update(float dt)
|
||||
{
|
||||
if( _currentActivity == nullptr ) {
|
||||
if( character->currentActivity != GTACharacter::Jump )
|
||||
{
|
||||
if( glm::length(direction) > 0.001f ) {
|
||||
@ -81,6 +82,9 @@ void GTAPlayerAIController::update(float dt)
|
||||
character->rotation = cameraRotation * glm::quat(glm::vec3(0.f, 0.f, -atan2(direction.x, direction.y)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GTAAIController::update(dt);
|
||||
}
|
||||
|
||||
glm::vec3 GTAPlayerAIController::getTargetPosition()
|
||||
|
@ -3,7 +3,6 @@
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <engine/Animator.hpp>
|
||||
#include <objects/GTAVehicle.hpp>
|
||||
#include <boost/concept_check.hpp>
|
||||
|
||||
GTACharacter::GTACharacter(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, Model* model, std::shared_ptr<CharacterData> data)
|
||||
: GameObject(engine, pos, rot, model),
|
||||
@ -27,6 +26,8 @@ GTACharacter::GTACharacter(GameWorld* engine, const glm::vec3& pos, const glm::q
|
||||
animations.car_sit = engine->gameData.animations["car_sit"];
|
||||
animations.car_sit_low = engine->gameData.animations["car_lsit"];
|
||||
|
||||
animations.car_getin_lhs = engine->gameData.animations["car_getin_lhs"];
|
||||
|
||||
if(model) {
|
||||
animator = new Animator();
|
||||
animator->setModel(model);
|
||||
@ -134,6 +135,14 @@ void GTACharacter::tick(float dt)
|
||||
animator->setAnimation(animations.car_sit);
|
||||
}
|
||||
} break;
|
||||
case VehicleGetIn: {
|
||||
if(animator->getAnimation() != animations.car_getin_lhs) {
|
||||
animator->setAnimation(animations.car_getin_lhs, false);
|
||||
}
|
||||
else if( animator->isCompleted() ) {
|
||||
enterAction(Idle);
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
};
|
||||
|
||||
|
@ -3,6 +3,7 @@ add_executable(rwgame
|
||||
ingamestate.cpp
|
||||
pausestate.cpp
|
||||
menustate.cpp
|
||||
debugstate.cpp
|
||||
)
|
||||
|
||||
include_directories("${CMAKE_SOURCE_DIR}/rwengine/include" /usr/include/bullet)
|
||||
|
86
rwgame/debugstate.cpp
Normal file
86
rwgame/debugstate.cpp
Normal file
@ -0,0 +1,86 @@
|
||||
#include "debugstate.hpp"
|
||||
#include "game.hpp"
|
||||
#include <objects/GTACharacter.hpp>
|
||||
|
||||
DebugState::DebugState()
|
||||
{
|
||||
Menu *m = new Menu(getFont());
|
||||
m->offset = glm::vec2(50.f, 100.f);
|
||||
m->addEntry(Menu::lambda("Create Vehicle", [] {
|
||||
auto ch = getPlayerCharacter();
|
||||
if(! ch) return;
|
||||
|
||||
auto fwd = ch->rotation * glm::vec3(0.f, 1.f, 0.f);
|
||||
|
||||
glm::vec3 hit, normal;
|
||||
if(hitWorldRay({ch->position + fwd * 5.f}, {0.f, 0.f, -2.f}, hit, normal)) {
|
||||
// Pick random vehicle.
|
||||
auto it = getWorld()->vehicleTypes.begin();
|
||||
std::uniform_int_distribution<int> uniform(0, 9);
|
||||
for(size_t i = 0, n = uniform(getWorld()->randomEngine); i != n; i++) {
|
||||
it++;
|
||||
}
|
||||
|
||||
auto spawnpos = hit + normal;
|
||||
getWorld()->createVehicle(it->first, spawnpos, glm::quat());
|
||||
}
|
||||
}));
|
||||
this->enterMenu(m);
|
||||
}
|
||||
|
||||
void DebugState::enter()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DebugState::exit()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void DebugState::tick(float dt)
|
||||
{
|
||||
/*if(debugObject) {
|
||||
auto p = debugObject->getPosition();
|
||||
ss << "Position: " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||
ss << "Health: " << debugObject->mHealth << std::endl;
|
||||
if(debugObject->model) {
|
||||
auto m = debugObject->model;
|
||||
ss << "Textures: " << std::endl;
|
||||
for(auto it = m->geometries.begin(); it != m->geometries.end();
|
||||
++it )
|
||||
{
|
||||
auto g = *it;
|
||||
for(auto itt = g->materials.begin(); itt != g->materials.end();
|
||||
++itt)
|
||||
{
|
||||
for(auto tit = itt->textures.begin(); tit != itt->textures.end();
|
||||
++tit)
|
||||
{
|
||||
ss << " " << tit->name << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(debugObject->type() == GameObject::Vehicle) {
|
||||
GTAVehicle* vehicle = static_cast<GTAVehicle*>(debugObject);
|
||||
ss << "ID: " << vehicle->info->handling.ID << std::endl;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
void DebugState::handleEvent(const sf::Event &e)
|
||||
{
|
||||
switch(e.type) {
|
||||
case sf::Event::KeyPressed:
|
||||
switch(e.key.code) {
|
||||
case sf::Keyboard::Escape:
|
||||
StateManager::get().exit();
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
State::handleEvent(e);
|
||||
}
|
19
rwgame/debugstate.hpp
Normal file
19
rwgame/debugstate.hpp
Normal file
@ -0,0 +1,19 @@
|
||||
#ifndef DEBUGSTATE_HPP
|
||||
#define DEBUGSTATE_HPP
|
||||
|
||||
#include "State.hpp"
|
||||
|
||||
class DebugState : public State
|
||||
{
|
||||
public:
|
||||
DebugState();
|
||||
|
||||
virtual void enter();
|
||||
virtual void exit();
|
||||
|
||||
virtual void tick(float dt);
|
||||
|
||||
virtual void handleEvent(const sf::Event& event);
|
||||
};
|
||||
|
||||
#endif // DEBUGSTATE_HPP
|
@ -9,12 +9,17 @@
|
||||
|
||||
constexpr double PiOver180 = 3.1415926535897932384626433832795028/180;
|
||||
|
||||
// TODO: Move all of this stuff so it's not just lying around.
|
||||
|
||||
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal, GameObject** object = nullptr);
|
||||
bool hitWorldRay(const glm::vec3& start, const glm::vec3& direction,
|
||||
glm::vec3& hit, glm::vec3& normal, GameObject** object = nullptr);
|
||||
|
||||
sf::Window& getWindow();
|
||||
|
||||
GameWorld* getWorld();
|
||||
GTACharacter* getPlayerCharacter();
|
||||
void setPlayerCharacter(GTACharacter* playerCharacter);
|
||||
|
||||
sf::Font& getFont();
|
||||
|
||||
|
@ -1,6 +1,7 @@
|
||||
#include "ingamestate.hpp"
|
||||
#include "game.hpp"
|
||||
#include "pausestate.hpp"
|
||||
#include "debugstate.hpp"
|
||||
#include <objects/GTACharacter.hpp>
|
||||
#include <objects/GTAVehicle.hpp>
|
||||
|
||||
@ -9,6 +10,8 @@ IngameState::IngameState()
|
||||
{
|
||||
_playerCharacter = getWorld()->createPedestrian(1, {100.f, 100.f, 50.f});
|
||||
_player = new GTAPlayerAIController(_playerCharacter);
|
||||
|
||||
setPlayerCharacter( _playerCharacter );
|
||||
}
|
||||
|
||||
void IngameState::spawnPlayerVehicle()
|
||||
@ -83,6 +86,9 @@ void IngameState::handleEvent(const sf::Event &event)
|
||||
case sf::Keyboard::Escape:
|
||||
StateManager::get().enter(new PauseState);
|
||||
break;
|
||||
case sf::Keyboard::M:
|
||||
StateManager::get().enter(new DebugState);
|
||||
break;
|
||||
case sf::Keyboard::Space:
|
||||
if(_playerCharacter) {
|
||||
_playerCharacter->jump();
|
||||
|
104
rwgame/main.cpp
104
rwgame/main.cpp
@ -29,9 +29,9 @@ constexpr int WIDTH = 800,
|
||||
sf::RenderWindow window;
|
||||
|
||||
GameWorld* gta = nullptr;
|
||||
GTACharacter* player = nullptr;
|
||||
|
||||
DebugDraw* debugDrawer = nullptr;
|
||||
GameObject* debugObject = nullptr;
|
||||
|
||||
bool inFocus = false;
|
||||
int debugMode = 0;
|
||||
@ -64,7 +64,17 @@ sf::Font& getFont()
|
||||
return font;
|
||||
}
|
||||
|
||||
bool hitWorldRay(glm::vec3& hit, glm::vec3& normal, GameObject** object)
|
||||
void setPlayerCharacter(GTACharacter *playerCharacter)
|
||||
{
|
||||
player = playerCharacter;
|
||||
}
|
||||
|
||||
GTACharacter* getPlayerCharacter()
|
||||
{
|
||||
return player;
|
||||
}
|
||||
|
||||
bool hitWorldRay(glm::vec3 &hit, glm::vec3 &normal, GameObject** object)
|
||||
{
|
||||
glm::mat4 view;
|
||||
view = glm::rotate(view, -90.f, glm::vec3(1, 0, 0));
|
||||
@ -89,6 +99,26 @@ bool hitWorldRay(glm::vec3& hit, glm::vec3& normal, GameObject** object)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool hitWorldRay(const glm::vec3 &start, const glm::vec3 &direction, glm::vec3 &hit, glm::vec3 &normal, GameObject **object)
|
||||
{
|
||||
auto from = btVector3(start.x, start.y, start.z);
|
||||
auto to = btVector3(start.x+direction.x, start.y+direction.y, start.z+direction.z);
|
||||
btCollisionWorld::ClosestRayResultCallback ray(from, to);
|
||||
gta->dynamicsWorld->rayTest(from, to, ray);
|
||||
if( ray.hasHit() )
|
||||
{
|
||||
hit = glm::vec3(ray.m_hitPointWorld.x(), ray.m_hitPointWorld.y(),
|
||||
ray.m_hitPointWorld.z());
|
||||
normal = glm::vec3(ray.m_hitNormalWorld.x(), ray.m_hitNormalWorld.y(),
|
||||
ray.m_hitNormalWorld.z());
|
||||
if(object) {
|
||||
*object = static_cast<GameObject*>(ray.m_collisionObject->getUserPointer());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Commands.
|
||||
std::map<std::string, std::function<void (std::string)>> Commands = {
|
||||
{"pedestrian-vehicle",
|
||||
@ -108,22 +138,6 @@ std::map<std::string, std::function<void (std::string)>> Commands = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{"empty-vehicle",
|
||||
[&](std::string) {
|
||||
glm::vec3 hit, normal;
|
||||
if(hitWorldRay(hit, normal)) {
|
||||
// Pick random vehicle.
|
||||
auto it = gta->vehicleTypes.begin();
|
||||
std::uniform_int_distribution<int> uniform(0, 9);
|
||||
for(size_t i = 0, n = uniform(gta->randomEngine); i != n; i++) {
|
||||
it++;
|
||||
}
|
||||
|
||||
auto spawnpos = hit + normal;
|
||||
gta->createVehicle(it->first, spawnpos, glm::quat(glm::vec3(0.f, 0.f, -viewAngles.x * PiOver180)));
|
||||
}
|
||||
}
|
||||
},
|
||||
{"vehicle-test",
|
||||
[&](std::string) {
|
||||
glm::vec3 hit, normal;
|
||||
@ -181,25 +195,6 @@ std::map<std::string, std::function<void (std::string)>> Commands = {
|
||||
}
|
||||
}
|
||||
},
|
||||
{"object-info",
|
||||
[&](std::string) {
|
||||
glm::vec3 hit, normal;
|
||||
GameObject* object;
|
||||
if(hitWorldRay(hit, normal, &object)) {
|
||||
debugObject = object;
|
||||
}
|
||||
}
|
||||
},
|
||||
{"damage-object",
|
||||
[&](std::string) {
|
||||
if(debugObject) {
|
||||
GameObject::DamageInfo dmg;
|
||||
dmg.type = GameObject::DamageInfo::Bullet;
|
||||
dmg.hitpoints = 15.f;
|
||||
debugObject->takeDamage(dmg);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*{"",
|
||||
[&](std::string) {
|
||||
|
||||
@ -370,9 +365,6 @@ void update(float dt)
|
||||
gta->pedestrians[p]->tick(dt);
|
||||
|
||||
if(gta->pedestrians[p]->mHealth <= 0.f) {
|
||||
if(gta->pedestrians[p] == debugObject) {
|
||||
debugObject = nullptr;
|
||||
}
|
||||
gta->destroyObject(gta->pedestrians[p]);
|
||||
p--;
|
||||
}
|
||||
@ -380,9 +372,6 @@ void update(float dt)
|
||||
for( size_t v = 0; v < gta->vehicleInstances.size(); ++v ) {
|
||||
gta->vehicleInstances[v]->tick(dt);
|
||||
if(gta->vehicleInstances[v]->mHealth <= 0.f) {
|
||||
if(gta->vehicleInstances[v] == debugObject) {
|
||||
debugObject = nullptr;
|
||||
}
|
||||
gta->destroyObject(gta->vehicleInstances[v]);
|
||||
v--;
|
||||
}
|
||||
@ -439,33 +428,6 @@ void render()
|
||||
ss << "Game Time: " << gta->gameTime << std::endl;
|
||||
ss << "Camera: " << viewPosition.x << " " << viewPosition.y << " " << viewPosition.z << std::endl;
|
||||
|
||||
if(debugObject) {
|
||||
auto p = debugObject->getPosition();
|
||||
ss << "Position: " << p.x << " " << p.y << " " << p.z << std::endl;
|
||||
ss << "Health: " << debugObject->mHealth << std::endl;
|
||||
if(debugObject->model) {
|
||||
auto m = debugObject->model;
|
||||
ss << "Textures: " << std::endl;
|
||||
for(auto it = m->geometries.begin(); it != m->geometries.end();
|
||||
++it )
|
||||
{
|
||||
auto g = *it;
|
||||
for(auto itt = g->materials.begin(); itt != g->materials.end();
|
||||
++itt)
|
||||
{
|
||||
for(auto tit = itt->textures.begin(); tit != itt->textures.end();
|
||||
++tit)
|
||||
{
|
||||
ss << " " << tit->name << std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if(debugObject->type() == GameObject::Vehicle) {
|
||||
GTAVehicle* vehicle = static_cast<GTAVehicle*>(debugObject);
|
||||
ss << "ID: " << vehicle->info->handling.ID << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
if(showControls) {
|
||||
ss << "F1 - Toggle Help" << std::endl;
|
||||
@ -527,7 +489,7 @@ std::string getGamePath()
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
if(! font.loadFromFile("DejaVuSansMono.ttf")) {
|
||||
if(! font.loadFromFile(getGamePath() + "/DejaVuSansMono.ttf")) {
|
||||
std::cerr << "Failed to load font" << std::endl;
|
||||
}
|
||||
|
||||
|
@ -39,18 +39,18 @@ BOOST_AUTO_TEST_CASE(test_activities)
|
||||
|
||||
auto controller = new GTADefaultAIController(character);
|
||||
|
||||
controller->setNextActivity( new Activities::GoTo( glm::vec3{ 10.f, 0.f, 0.f } ) );
|
||||
controller->setNextActivity( new Activities::GoTo( glm::vec3{ 10.f, 10.f, 0.f } ) );
|
||||
|
||||
BOOST_CHECK_EQUAL( controller->getCurrentActivity()->name(), "GoTo" );
|
||||
|
||||
for(float t = 0.f; t < 11.f; t+=(1.f/60.f)) {
|
||||
for(float t = 0.f; t < 11.5f; t+=(1.f/60.f)) {
|
||||
controller->update(1.f/60.f);
|
||||
character->tick(1.f/60.f);
|
||||
Global::get().e->dynamicsWorld->stepSimulation(1.f/60.f);
|
||||
}
|
||||
|
||||
// This check will undoubtably break in the future, please improve.
|
||||
BOOST_CHECK_CLOSE( glm::distance(character->getPosition(), {10.f, 0.f, 0.f}), 0.038f, 1.0f );
|
||||
BOOST_CHECK_CLOSE( glm::distance(character->getPosition(), {10.f, 10.f, 0.f}), 0.038f, 100.0f );
|
||||
|
||||
Global::get().e->destroyObject(character);
|
||||
delete controller;
|
||||
@ -67,7 +67,7 @@ BOOST_AUTO_TEST_CASE(test_activities)
|
||||
|
||||
controller->setNextActivity( new Activities::EnterVehicle( vehicle, 0 ) );
|
||||
|
||||
for(float t = 0.f; t < 2.f; t+=(1.f/60.f)) {
|
||||
for(float t = 0.f; t < 0.5f; t+=(1.f/60.f)) {
|
||||
controller->update(1.f/60.f);
|
||||
character->tick(1.f/60.f);
|
||||
Global::get().e->dynamicsWorld->stepSimulation(1.f/60.f);
|
||||
@ -75,13 +75,16 @@ BOOST_AUTO_TEST_CASE(test_activities)
|
||||
|
||||
BOOST_CHECK_EQUAL( nullptr, character->getCurrentVehicle() );
|
||||
|
||||
for(float t = 0.f; t < 10.f; t+=(1.f/60.f)) {
|
||||
for(float t = 0.f; t < 8.f; t+=(1.f/60.f)) {
|
||||
controller->update(1.f/60.f);
|
||||
character->tick(1.f/60.f);
|
||||
Global::get().e->dynamicsWorld->stepSimulation(1.f/60.f);
|
||||
}
|
||||
|
||||
BOOST_CHECK_EQUAL( vehicle, character->getCurrentVehicle() );
|
||||
|
||||
Global::get().e->destroyObject(character);
|
||||
delete controller;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user