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

Further improve vehicle door dynamics

+ Rename some part target angle names
+ Improve behaviour of opening and closing doors
+ Use different animations for right hand side of vehicle
This commit is contained in:
Daniel Evans 2015-01-23 02:03:21 +00:00
parent 4ea6e14299
commit 5d41002b36
6 changed files with 63 additions and 31 deletions

View File

@ -60,6 +60,8 @@ protected:
bool running;
float vehicleIdle;
// Goal related variables
Goal currentGoal;
CharacterObject* leader;

View File

@ -37,11 +37,16 @@ struct AnimationGroup
Animation* car_getin_lhs;
Animation* car_getout_lhs;
Animation* car_open_rhs;
Animation* car_getin_rhs;
Animation* car_getout_rhs;
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_open_lhs(nullptr),
car_getin_lhs(nullptr), car_getout_lhs(nullptr)
car_getin_lhs(nullptr), car_getout_lhs(nullptr), car_open_rhs(nullptr),
car_getin_rhs(nullptr), car_getout_rhs(nullptr)
{}
};

View File

@ -38,7 +38,7 @@ public:
ModelFrame* damaged;
btRigidBody* body;
btHingeConstraint* constraint;
bool holdAngle;
bool moveToAngle;
float targetAngle;
float openAngle;
float closedAngle;

View File

@ -28,7 +28,7 @@ void CharacterController::setActivity(CharacterController::Activity* activity)
CharacterController::CharacterController(CharacterObject* character)
: character(character), _currentActivity(nullptr), _nextActivity(nullptr), running(false),
currentGoal(None), leader(nullptr)
vehicleIdle(0.f), currentGoal(None), leader(nullptr)
{
character->controller = this;
}
@ -73,21 +73,26 @@ void CharacterController::update(float dt)
/// @todo play _low variant if car has low flag.
character->playAnimation(character->animations.car_sit, true);
// If character is idle in vehicle, close door.
if( glm::length( d ) <= 0.1f )
{
auto entryDoor = character->getCurrentVehicle()->getSeatEntryDoor(character->getCurrentSeat());
vehicleIdle += dt;
}
else
{
vehicleIdle = 0.f;
}
if( vehicleIdle >= 1.f )
{
// If character is idle in vehicle, try to close the door.
auto v = character->getCurrentVehicle();
auto entryDoor = v->getSeatEntryDoor(character->getCurrentSeat());
if( entryDoor && entryDoor->constraint )
{
character->getCurrentVehicle()->setPartTarget(entryDoor, true, entryDoor->closedAngle);
}
}
else
{
auto entryDoor = character->getCurrentVehicle()->getSeatEntryDoor(character->getCurrentSeat());
entryDoor->holdAngle = false;
}
}
}
else {
@ -247,12 +252,18 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
character->enterVehicle(vehicle, seat);
return true;
}
auto entryDoor = vehicle->getSeatEntryDoor(seat);
auto anm_open = character->animations.car_open_lhs;
auto anm_enter = character->animations.car_getin_lhs;
auto entryDoor = vehicle->getSeatEntryDoor(seat);
if( entryDoor->dummy->getDefaultTranslation().x > 0.f )
{
anm_open = character->animations.car_open_rhs;
anm_enter = character->animations.car_getin_rhs;
}
if( entering ) {
if( character->animator->getAnimation() == anm_open ) {
if( character->animator->isCompleted() ) {
@ -317,8 +328,16 @@ bool Activities::ExitVehicle::update(CharacterObject *character, CharacterContro
if( character->getCurrentVehicle() == nullptr ) return true;
auto vehicle = character->getCurrentVehicle();
auto anm_exit = character->animations.car_getout_lhs;
auto seat = character->getCurrentSeat();
auto door = vehicle->getSeatEntryDoor(seat);
auto anm_exit = character->animations.car_getout_lhs;
if( door->dummy->getDefaultTranslation().x > 0.f )
{
anm_exit = character->animations.car_getout_rhs;
}
if( vehicle->vehicle->type == VehicleData::BOAT ) {
auto ppos = character->getPosition();
@ -339,8 +358,6 @@ bool Activities::ExitVehicle::update(CharacterObject *character, CharacterContro
}
else {
character->playAnimation(anm_exit, false);
auto door = vehicle->getSeatEntryDoor(character->getCurrentSeat());
if( door )
{
vehicle->setPartTarget(door, true, door->openAngle);

View File

@ -42,6 +42,10 @@ CharacterObject::CharacterObject(GameWorld* engine, const glm::vec3& pos, const
animations.car_open_lhs = engine->gameData.animations["car_open_lhs"];
animations.car_getin_lhs = engine->gameData.animations["car_getin_lhs"];
animations.car_getout_lhs = engine->gameData.animations["car_getout_lhs"];
animations.car_open_rhs = engine->gameData.animations["car_open_rhs"];
animations.car_getin_rhs = engine->gameData.animations["car_getin_rhs"];
animations.car_getout_rhs = engine->gameData.animations["car_getout_rhs"];
if(model) {
skeleton = new Skeleton;

View File

@ -307,20 +307,30 @@ void VehicleObject::tickPhysics(float dt)
//next.translation = p2;
skeleton->setData(it.second.dummy->getIndex(), { next, prev, true } );
if( it.second.holdAngle )
if( it.second.moveToAngle )
{
it.second.constraint->setMotorTarget(it.second.targetAngle, 0.1f);
auto angledelta = it.second.targetAngle - it.second.constraint->getHingeAngle();
if( glm::abs(angledelta) <= 0.01f )
{
it.second.constraint->enableAngularMotor(false, 1.f, 1.f);
dynamicParts[it.first].moveToAngle = false;
}
else
{
it.second.constraint->enableAngularMotor(true, glm::sign(angledelta) * 5.f, 1.f);
}
}
it.second.constraint->enableMotor( it.second.holdAngle );
// If the part is moving quite fast and near the limit, lock it.
/// @TODO not all parts rotate in the z axis.
if(it.second.body->getAngularVelocity().getZ() >= PART_CLOSE_VELOCITY)
float zspeed = it.second.body->getAngularVelocity().getZ();
if(it.second.openAngle < 0.f) zspeed = -zspeed;
if(zspeed >= PART_CLOSE_VELOCITY)
{
auto d = it.second.constraint->getHingeAngle() - it.second.closedAngle;
if( std::abs(d) < 0.05f )
if( glm::abs(d) < 0.05f )
{
it.second.holdAngle = false;
dynamicParts[it.first].moveToAngle = false;
setPartLocked(&(it.second), true);
}
}
@ -525,20 +535,14 @@ void VehicleObject::setPartTarget(VehicleObject::Part* part, bool enable, float
}
part->targetAngle = target;
part->holdAngle = true;
part->constraint->enableMotor(true);
part->moveToAngle = true;
part->body->activate(true);
}
else
{
part->targetAngle = target;
part->holdAngle = false;
if( part->constraint )
{
part->constraint->enableMotor(false);
}
part->moveToAngle = false;
}
}
@ -692,7 +696,7 @@ void VehicleObject::destroyObjectHinge(Part* part)
part->constraint = nullptr;
// Reset target.
part->holdAngle = false;
part->moveToAngle = false;
}
}