mirror of
https://github.com/rwengine/openrw.git
synced 2024-09-18 16:32:32 +02:00
Overhaul object transformation handling
Objects must now write back to their position and rotations using updateTransform(position, rotation) to updae their transform. This allows the getPosition and getRotation methods to become non virtual
This commit is contained in:
parent
b3fe87c2ea
commit
f860e4c9a7
@ -158,15 +158,13 @@ public:
|
||||
|
||||
virtual void setPosition(const glm::vec3& pos);
|
||||
|
||||
virtual glm::vec3 getPosition() const;
|
||||
|
||||
virtual glm::quat getRotation() const;
|
||||
|
||||
bool isAlive() const;
|
||||
bool takeDamage(const DamageInfo& damage) override;
|
||||
|
||||
bool enterVehicle(VehicleObject* vehicle, size_t seat);
|
||||
|
||||
bool isEnteringOrExitingVehicle() const;
|
||||
|
||||
/**
|
||||
* @brief isStopped
|
||||
* @return True if the character isn't moving
|
||||
|
@ -98,10 +98,10 @@ public:
|
||||
|
||||
virtual void setPosition(const glm::vec3& pos);
|
||||
|
||||
virtual glm::vec3 getPosition() const { return position; }
|
||||
const glm::vec3& getPosition() const { return position; }
|
||||
const glm::vec3& getLastPosition() const { return _lastPosition; }
|
||||
|
||||
virtual glm::quat getRotation() const;
|
||||
const glm::quat& getRotation() const { return rotation; }
|
||||
virtual void setRotation(const glm::quat &orientation);
|
||||
|
||||
float getHeading() const;
|
||||
@ -185,7 +185,15 @@ public:
|
||||
|
||||
void setLifetime(ObjectLifetime ol) { lifetime = ol; }
|
||||
ObjectLifetime getLifetime() const { return lifetime; }
|
||||
|
||||
|
||||
void updateTransform(const glm::vec3& pos, const glm::quat& rot)
|
||||
{
|
||||
_lastPosition = position;
|
||||
_lastRotation = rotation;
|
||||
position = pos;
|
||||
rotation = rot;
|
||||
}
|
||||
|
||||
private:
|
||||
ObjectLifetime lifetime;
|
||||
};
|
||||
|
@ -31,9 +31,6 @@ public:
|
||||
|
||||
void changeModel(std::shared_ptr<ObjectData> incoming);
|
||||
|
||||
glm::vec3 getPosition() const override;
|
||||
glm::quat getRotation() const override;
|
||||
|
||||
virtual void setRotation(const glm::quat& r);
|
||||
|
||||
virtual bool takeDamage(const DamageInfo& damage);
|
||||
|
@ -57,12 +57,8 @@ public:
|
||||
|
||||
void setPosition(const glm::vec3& pos);
|
||||
|
||||
glm::vec3 getPosition() const;
|
||||
|
||||
void setRotation(const glm::quat &orientation);
|
||||
|
||||
glm::quat getRotation() const;
|
||||
|
||||
Type type() { return Vehicle; }
|
||||
|
||||
void setSteeringAngle(float);
|
||||
@ -111,7 +107,10 @@ public:
|
||||
glm::vec3 getSeatEntryPosition(size_t seat) const {
|
||||
auto pos = info->seats[seat].offset;
|
||||
pos -= glm::vec3(glm::sign(pos.x) * -0.81756252f, 0.34800607f, -0.486281008f);
|
||||
return getPosition() + getRotation() * pos;
|
||||
return pos;
|
||||
}
|
||||
glm::vec3 getSeatEntryPositionWorld(size_t seat) const {
|
||||
return getPosition() + getRotation() * getSeatEntryPosition(seat);
|
||||
}
|
||||
|
||||
Part* getSeatEntryDoor(size_t seat);
|
||||
|
@ -207,7 +207,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
|
||||
float nearest = std::numeric_limits<float>::max();
|
||||
for(unsigned int s = 1; s < vehicle->info->seats.size(); ++s)
|
||||
{
|
||||
auto entry = vehicle->getSeatEntryPosition(s);
|
||||
auto entry = vehicle->getSeatEntryPositionWorld(s);
|
||||
float dist = glm::distance(entry, character->getPosition());
|
||||
if( dist < nearest )
|
||||
{
|
||||
@ -218,6 +218,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
|
||||
}
|
||||
|
||||
auto entryDoor = vehicle->getSeatEntryDoor(seat);
|
||||
auto entryPos = vehicle->getSeatEntryPositionWorld(seat);
|
||||
|
||||
auto anm_open = character->animations.car_open_lhs;
|
||||
auto anm_enter = character->animations.car_getin_lhs;
|
||||
@ -262,8 +263,7 @@ bool Activities::EnterVehicle::update(CharacterObject *character, CharacterContr
|
||||
}
|
||||
}
|
||||
else {
|
||||
glm::vec3 target = vehicle->getSeatEntryPosition(seat);
|
||||
glm::vec3 targetDirection = target - character->getPosition();
|
||||
glm::vec3 targetDirection = entryPos - character->getPosition();
|
||||
targetDirection.z = 0.f;
|
||||
|
||||
float targetDistance = glm::length(targetDirection);
|
||||
@ -387,7 +387,7 @@ bool Activities::ExitVehicle::update(CharacterObject *character, CharacterContro
|
||||
|
||||
if( character->animator->getAnimation(AnimIndexAction) == anm_exit ) {
|
||||
if( character->animator->isCompleted(AnimIndexAction) ) {
|
||||
auto exitpos = vehicle->getSeatEntryPosition(seat);
|
||||
auto exitpos = vehicle->getSeatEntryPositionWorld(seat);
|
||||
|
||||
character->enterVehicle(nullptr, seat);
|
||||
character->setPosition(exitpos);
|
||||
|
@ -4,6 +4,34 @@
|
||||
#include <engine/GameWorld.hpp>
|
||||
#include <engine/GameData.hpp>
|
||||
|
||||
class GameObjectMotionState : public btMotionState
|
||||
{
|
||||
public:
|
||||
GameObjectMotionState(GameObject *object)
|
||||
: m_object(object)
|
||||
{ }
|
||||
|
||||
virtual void getWorldTransform(btTransform& tform) const
|
||||
{
|
||||
auto& position = m_object->getPosition();
|
||||
auto& rotation = m_object->getRotation();
|
||||
tform.setOrigin(btVector3(position.x, position.y, position.z));
|
||||
tform.setRotation(btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w));
|
||||
}
|
||||
|
||||
virtual void setWorldTransform(const btTransform& tform)
|
||||
{
|
||||
auto& o = tform.getOrigin();
|
||||
auto r = tform.getRotation();
|
||||
glm::vec3 position(o.x(), o.y(), o.z());
|
||||
glm::quat rotation(r.w(), r.x(), r.y(), r.z());
|
||||
m_object->updateTransform(position, rotation);
|
||||
}
|
||||
|
||||
private:
|
||||
GameObject *m_object;
|
||||
};
|
||||
|
||||
CollisionInstance::~CollisionInstance()
|
||||
{
|
||||
if( m_body ) {
|
||||
@ -32,14 +60,7 @@ bool CollisionInstance::createPhysicsBody(GameObject *object, const std::string&
|
||||
if( phyit != object->engine->data->collisions.end()) {
|
||||
btCompoundShape* cmpShape = new btCompoundShape;
|
||||
|
||||
auto p = object->getPosition();
|
||||
auto r = object->getRotation();
|
||||
|
||||
m_motionState = new btDefaultMotionState;
|
||||
m_motionState->setWorldTransform(btTransform(
|
||||
btQuaternion(r.x, r.y, r.z, -r.w).inverse(),
|
||||
btVector3(p.x, p.y, p.z)
|
||||
));
|
||||
m_motionState = new GameObjectMotionState(object);
|
||||
m_shapes.push_back(cmpShape);
|
||||
|
||||
btRigidBody::btRigidBodyConstructionInfo info(0.f, m_motionState, cmpShape);
|
||||
|
@ -316,8 +316,6 @@ void CharacterObject::updateCharacter(float dt)
|
||||
if(physCharacter) {
|
||||
glm::vec3 walkDir = updateMovementAnimation(dt);
|
||||
|
||||
position = getPosition();
|
||||
|
||||
if (canTurn()) {
|
||||
rotation = glm::angleAxis(m_look.x, glm::vec3{0.f, 0.f, 1.f});
|
||||
}
|
||||
@ -399,39 +397,6 @@ void CharacterObject::setPosition(const glm::vec3& pos)
|
||||
position = pos;
|
||||
}
|
||||
|
||||
glm::vec3 CharacterObject::getPosition() const
|
||||
{
|
||||
if(physCharacter) {
|
||||
btVector3 Pos = physCharacter->getGhostObject()->getWorldTransform().getOrigin();
|
||||
return glm::vec3(Pos.x(), Pos.y(), Pos.z());
|
||||
}
|
||||
if(currentVehicle) {
|
||||
/// @todo this is hacky.
|
||||
if( animator->getAnimation(AnimIndexAction) == animations.car_getout_lhs ) {
|
||||
return currentVehicle->getSeatEntryPosition(currentSeat);
|
||||
}
|
||||
|
||||
auto v = getCurrentVehicle();
|
||||
auto R = glm::mat3_cast(v->getRotation());
|
||||
glm::vec3 offset;
|
||||
auto o = (animator->getAnimation(AnimIndexAction) == animations.car_getin_lhs) ? enter_offset : glm::vec3();
|
||||
if(getCurrentSeat() < v->info->seats.size()) {
|
||||
offset = R * (v->info->seats[getCurrentSeat()].offset -
|
||||
o);
|
||||
}
|
||||
return currentVehicle->getPosition() + offset;
|
||||
}
|
||||
return position;
|
||||
}
|
||||
|
||||
glm::quat CharacterObject::getRotation() const
|
||||
{
|
||||
if(currentVehicle) {
|
||||
return currentVehicle->getRotation();
|
||||
}
|
||||
return GameObject::getRotation();
|
||||
}
|
||||
|
||||
bool CharacterObject::isAlive() const
|
||||
{
|
||||
return currentState.health > 0.f;
|
||||
@ -465,6 +430,12 @@ bool CharacterObject::enterVehicle(VehicleObject* vehicle, size_t seat)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CharacterObject::isEnteringOrExitingVehicle() const
|
||||
{
|
||||
return animator->getAnimation(AnimIndexAction) == animations.car_getout_lhs ||
|
||||
animator->getAnimation(AnimIndexAction) == animations.car_getin_lhs;
|
||||
}
|
||||
|
||||
bool CharacterObject::isStopped() const
|
||||
{
|
||||
if (currentVehicle != nullptr) {
|
||||
|
@ -23,11 +23,6 @@ void GameObject::setPosition(const glm::vec3& pos)
|
||||
_lastPosition = position = pos;
|
||||
}
|
||||
|
||||
glm::quat GameObject::getRotation() const
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void GameObject::setRotation(const glm::quat& orientation)
|
||||
{
|
||||
rotation = orientation;
|
||||
|
@ -49,12 +49,8 @@ void InstanceObject::tick(float dt)
|
||||
body->changeMass(dynamics->mass);
|
||||
}
|
||||
}
|
||||
|
||||
_updateLastTransform();
|
||||
|
||||
/// @todo replace with position from motionstate
|
||||
auto _bws = body->getBulletBody()->getWorldTransform().getOrigin();
|
||||
glm::vec3 ws(_bws.x(), _bws.y(), _bws.z());
|
||||
const glm::vec3& ws = getPosition();
|
||||
auto wX = (int) ((ws.x + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
|
||||
auto wY = (int) ((ws.y + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
|
||||
float vH = ws.z;// - _collisionHeight/2.f;
|
||||
@ -136,16 +132,6 @@ void InstanceObject::changeModel(std::shared_ptr<ObjectData> incoming)
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 InstanceObject::getPosition() const
|
||||
{
|
||||
return position;
|
||||
}
|
||||
|
||||
glm::quat InstanceObject::getRotation() const
|
||||
{
|
||||
return rotation;
|
||||
}
|
||||
|
||||
void InstanceObject::setRotation(const glm::quat &r)
|
||||
{
|
||||
if( body ) {
|
||||
|
@ -163,12 +163,6 @@ void VehicleObject::setPosition(const glm::vec3& pos)
|
||||
}
|
||||
}
|
||||
|
||||
glm::vec3 VehicleObject::getPosition() const
|
||||
{
|
||||
/// @todo update our position from the motion state
|
||||
return position;
|
||||
}
|
||||
|
||||
void VehicleObject::setRotation(const glm::quat &orientation)
|
||||
{
|
||||
if( collision->getBulletBody() ) {
|
||||
@ -179,11 +173,6 @@ void VehicleObject::setRotation(const glm::quat &orientation)
|
||||
GameObject::setRotation(orientation);
|
||||
}
|
||||
|
||||
glm::quat VehicleObject::getRotation() const
|
||||
{
|
||||
/// @todo update our rotation from the motion state
|
||||
return rotation;
|
||||
}
|
||||
|
||||
#include <glm/gtc/type_ptr.hpp>
|
||||
|
||||
@ -232,11 +221,30 @@ void VehicleObject::tickPhysics(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
// Update passenger positions
|
||||
for (auto& seat : seatOccupants)
|
||||
{
|
||||
auto character = static_cast<CharacterObject*>(seat.second);
|
||||
|
||||
glm::vec3 passPosition;
|
||||
if (character->isEnteringOrExitingVehicle())
|
||||
{
|
||||
passPosition = getSeatEntryPositionWorld(seat.first);
|
||||
}
|
||||
else
|
||||
{
|
||||
passPosition = getPosition();
|
||||
if (seat.first < info->seats.size()) {
|
||||
passPosition += getRotation() * (info->seats[seat.first].offset);
|
||||
}
|
||||
}
|
||||
seat.second->updateTransform(passPosition, getRotation());
|
||||
}
|
||||
|
||||
if( vehicle->type == VehicleData::BOAT ) {
|
||||
if( isInWater() ) {
|
||||
float sign = std::signbit(steerAngle) ? -1.f : 1.f;
|
||||
float steer = std::min(info->handling.steeringLock*(3.141f/180.f), std::abs(steerAngle)) * sign;
|
||||
/// @todo get orientation from motion state
|
||||
auto orient = collision->getBulletBody()->getOrientation();
|
||||
|
||||
// Find the local-space velocity
|
||||
@ -265,7 +273,7 @@ void VehicleObject::tickPhysics(float dt)
|
||||
}
|
||||
}
|
||||
|
||||
auto ws = getPosition();
|
||||
const auto& ws = getPosition();
|
||||
auto wX = (int) ((ws.x + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
|
||||
auto wY = (int) ((ws.y + WATER_WORLD_SIZE/2.f) / (WATER_WORLD_SIZE/WATER_HQ_DATA_SIZE));
|
||||
btVector3 bbmin, bbmax;
|
||||
|
@ -298,7 +298,28 @@ void ObjectRenderer::renderInstance(InstanceObject *instance,
|
||||
void ObjectRenderer::renderCharacter(CharacterObject *pedestrian,
|
||||
RenderList& outList)
|
||||
{
|
||||
glm::mat4 matrixModel = pedestrian->getTimeAdjustedTransform( m_renderAlpha );
|
||||
glm::mat4 matrixModel;
|
||||
|
||||
if (pedestrian->getCurrentVehicle())
|
||||
{
|
||||
auto vehicle = pedestrian->getCurrentVehicle();
|
||||
auto seat = pedestrian->getCurrentSeat();
|
||||
matrixModel = vehicle->getTimeAdjustedTransform( m_renderAlpha );
|
||||
if (pedestrian->isEnteringOrExitingVehicle())
|
||||
{
|
||||
matrixModel = glm::translate(matrixModel, vehicle->getSeatEntryPosition(seat));
|
||||
}
|
||||
else
|
||||
{
|
||||
if (seat < vehicle->info->seats.size()) {
|
||||
matrixModel = glm::translate(matrixModel, vehicle->info->seats[seat].offset);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
matrixModel = pedestrian->getTimeAdjustedTransform( m_renderAlpha );
|
||||
}
|
||||
|
||||
if(!pedestrian->model->resource) return;
|
||||
|
||||
|
@ -78,7 +78,7 @@ BOOST_AUTO_TEST_CASE(test_door_position)
|
||||
BOOST_REQUIRE(vehicle->info != nullptr);
|
||||
BOOST_REQUIRE(vehicle->vehicle != nullptr);
|
||||
|
||||
BOOST_CHECK( vehicle->getSeatEntryPosition(0).x > 5.f );
|
||||
BOOST_CHECK( vehicle->getSeatEntryPositionWorld(0).x > 5.f );
|
||||
|
||||
|
||||
Global::get().e->destroyObject(vehicle);
|
||||
|
Loading…
Reference in New Issue
Block a user