1
0
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:
Daniel Evans 2014-05-31 08:18:50 +01:00
parent d7b738cdc1
commit 04842a628a
13 changed files with 222 additions and 110 deletions

View File

@ -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);
};

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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()

View File

@ -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;
};

View File

@ -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
View 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
View 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

View File

@ -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();

View File

@ -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();

View File

@ -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;
}

View File

@ -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;
}
}