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:
parent
4ea6e14299
commit
5d41002b36
@ -60,6 +60,8 @@ protected:
|
||||
|
||||
bool running;
|
||||
|
||||
float vehicleIdle;
|
||||
|
||||
// Goal related variables
|
||||
Goal currentGoal;
|
||||
CharacterObject* leader;
|
||||
|
@ -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)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -38,7 +38,7 @@ public:
|
||||
ModelFrame* damaged;
|
||||
btRigidBody* body;
|
||||
btHingeConstraint* constraint;
|
||||
bool holdAngle;
|
||||
bool moveToAngle;
|
||||
float targetAngle;
|
||||
float openAngle;
|
||||
float closedAngle;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user