1
0
mirror of https://github.com/rwengine/openrw.git synced 2024-11-25 03:42:48 +01:00

Remove raw ptrs from VehicleObject

This commit is contained in:
Filip Gawin 2018-08-28 23:00:11 +02:00
parent fae8f0c1a9
commit 63ab663ea5
3 changed files with 86 additions and 70 deletions

View File

@ -99,7 +99,8 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
collision->createPhysicsBody(this, modelinfo->getCollision(), nullptr, collision->createPhysicsBody(this, modelinfo->getCollision(), nullptr,
&info->handling); &info->handling);
collision->getBulletBody()->forceActivationState(DISABLE_DEACTIVATION); collision->getBulletBody()->forceActivationState(DISABLE_DEACTIVATION);
physRaycaster = new VehicleRaycaster(this, engine->dynamicsWorld.get()); physRaycaster =
std::make_unique<VehicleRaycaster>(this, engine->dynamicsWorld.get());
btRaycastVehicle::btVehicleTuning tuning; btRaycastVehicle::btVehicleTuning tuning;
float travel = fabs(info->handling.suspensionUpperLimit - float travel = fabs(info->handling.suspensionUpperLimit -
@ -120,10 +121,10 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
tuning.m_frictionSlip = 1.8f + maxVelocity * accelerationFloor / massFloor; tuning.m_frictionSlip = 1.8f + maxVelocity * accelerationFloor / massFloor;
tuning.m_maxSuspensionTravelCm = travel * 100.f; tuning.m_maxSuspensionTravelCm = travel * 100.f;
physVehicle = physVehicle = std::make_unique<btRaycastVehicle>(
new btRaycastVehicle(tuning, collision->getBulletBody(), physRaycaster); tuning, collision->getBulletBody(), physRaycaster.get());
physVehicle->setCoordinateSystem(0, 2, 1); physVehicle->setCoordinateSystem(0, 2, 1);
engine->dynamicsWorld->addAction(physVehicle); engine->dynamicsWorld->addAction(physVehicle.get());
float kC = 0.5f; float kC = 0.5f;
float kR = 0.6f; float kR = 0.6f;
@ -173,14 +174,11 @@ VehicleObject::VehicleObject(GameWorld* engine, const glm::vec3& pos,
VehicleObject::~VehicleObject() { VehicleObject::~VehicleObject() {
ejectAll(); ejectAll();
engine->dynamicsWorld->removeAction(physVehicle); engine->dynamicsWorld->removeAction(physVehicle.get());
for (auto& p : dynamicParts) { for (auto& p : dynamicParts) {
destroyObjectHinge(&p.second); destroyObjectHinge(&p.second);
} }
delete physVehicle;
delete physRaycaster;
} }
void VehicleObject::setupModel() { void VehicleObject::setupModel() {
@ -272,7 +270,7 @@ void VehicleObject::setPosition(const glm::vec3& pos) {
auto bodyOrigin = btVector3(position.x, position.y, position.z); auto bodyOrigin = btVector3(position.x, position.y, position.z);
for (auto& part : dynamicParts) { for (auto& part : dynamicParts) {
if (part.second.body == nullptr) continue; if (part.second.body == nullptr) continue;
auto body = part.second.body; auto body = part.second.body.get();
auto rel = body->getWorldTransform().getOrigin() - bodyOrigin; auto rel = body->getWorldTransform().getOrigin() - bodyOrigin;
body->getWorldTransform().setOrigin( body->getWorldTransform().setOrigin(
btVector3(pos.x + rel.x(), pos.y + rel.y(), pos.z + rel.z())); btVector3(pos.x + rel.x(), pos.y + rel.y(), pos.z + rel.z()));
@ -588,7 +586,7 @@ void VehicleObject::tickPhysics(float dt) {
it.second.constraint->getHingeAngle(); it.second.constraint->getHingeAngle();
if (glm::abs(angledelta) <= 0.01f) { if (glm::abs(angledelta) <= 0.01f) {
it.second.constraint->enableAngularMotor(false, 1.f, 1.f); it.second.constraint->enableAngularMotor(false, 1.f, 1.f);
dynamicParts[it.first].moveToAngle = false; it.second.moveToAngle = false;
} else { } else {
it.second.constraint->enableAngularMotor( it.second.constraint->enableAngularMotor(
true, glm::sign(angledelta) * 5.f, 1.f); true, glm::sign(angledelta) * 5.f, 1.f);
@ -603,7 +601,7 @@ void VehicleObject::tickPhysics(float dt) {
auto d = it.second.constraint->getHingeAngle() - auto d = it.second.constraint->getHingeAngle() -
it.second.closedAngle; it.second.closedAngle;
if (glm::abs(d) < 0.05f) { if (glm::abs(d) < 0.05f) {
dynamicParts[it.first].moveToAngle = false; it.second.moveToAngle = false;
setPartLocked(&(it.second), true); setPartLocked(&(it.second), true);
} }
} }
@ -752,7 +750,7 @@ bool VehicleObject::takeDamage(const GameObject::DamageInfo& dmg) {
dpoint = glm::inverse(getRotation()) * dpoint; dpoint = glm::inverse(getRotation()) * dpoint;
// Set any parts within range to damaged state. // Set any parts within range to damaged state.
for (auto d : dynamicParts) { for (auto& d : dynamicParts) {
auto p = &d.second; auto p = &d.second;
if (p->normal == nullptr) continue; if (p->normal == nullptr) continue;
@ -863,10 +861,11 @@ void VehicleObject::registerPart(ModelFrame* mf) {
damage->setFlag(Atomic::ATOMIC_RENDER, false); damage->setFlag(Atomic::ATOMIC_RENDER, false);
} }
} }
Part part{mf, normal, damage, nullptr, nullptr, nullptr, false,
0.f, 0.f, 0.f};
dynamicParts.insert({mf->getName(), dynamicParts.insert({mf->getName(),
{mf, normal, damage, nullptr, nullptr, nullptr, false, std::move(part)});
0.f, 0.f, 0.f}});
} }
void VehicleObject::createObjectHinge(Part* part) { void VehicleObject::createObjectHinge(Part* part) {
@ -909,7 +908,7 @@ void VehicleObject::createObjectHinge(Part* part) {
return; return;
} }
auto ms = new VehiclePartMotionState(this, part); auto ms = std::make_unique<VehiclePartMotionState>(this, part);
btTransform tr = btTransform::getIdentity(); btTransform tr = btTransform::getIdentity();
const auto& p = part->dummy->getDefaultTranslation(); const auto& p = part->dummy->getDefaultTranslation();
@ -917,7 +916,7 @@ void VehicleObject::createObjectHinge(Part* part) {
tr.setOrigin(btVector3(p.x, p.y, p.z)); tr.setOrigin(btVector3(p.x, p.y, p.z));
tr.setRotation(btQuaternion(o.x, o.y, o.z, o.w)); tr.setRotation(btQuaternion(o.x, o.y, o.z, o.w));
btCollisionShape* cs = new btBoxShape(boxSize); auto cs = std::make_unique<btBoxShape>(boxSize);
btTransform t; btTransform t;
t.setIdentity(); t.setIdentity();
t.setOrigin(boxOffset); t.setOrigin(boxOffset);
@ -925,41 +924,38 @@ void VehicleObject::createObjectHinge(Part* part) {
btVector3 inertia; btVector3 inertia;
cs->calculateLocalInertia(10.f, inertia); cs->calculateLocalInertia(10.f, inertia);
btRigidBody::btRigidBodyConstructionInfo rginfo(10.f, ms, cs, inertia); btRigidBody::btRigidBodyConstructionInfo rginfo(10.f, ms.get(), cs.get(), inertia);
btRigidBody* subObject = new btRigidBody(rginfo); auto subObject = std::make_unique<btRigidBody>(rginfo);
subObject->setUserPointer(this); subObject->setUserPointer(this);
auto hinge = new btHingeConstraint(*collision->getBulletBody(), *subObject, auto hinge = std::make_unique<btHingeConstraint>(*collision->getBulletBody(), *subObject,
tr.getOrigin(), hingePosition, hingeAxis, tr.getOrigin(), hingePosition, hingeAxis,
hingeAxis); hingeAxis);
hinge->setLimit(hingeMin, hingeMax); hinge->setLimit(hingeMin, hingeMax);
hinge->setBreakingImpulseThreshold(250.f); hinge->setBreakingImpulseThreshold(250.f);
part->cs = cs; part->cs = std::move(cs);
part->body = subObject; part->body = std::move(subObject);
part->constraint = hinge; part->motionState = std::move(ms);
part->constraint = std::move(hinge);
engine->dynamicsWorld->addRigidBody(part->body); engine->dynamicsWorld->addRigidBody(part->body.get());
engine->dynamicsWorld->addConstraint(part->constraint, true); engine->dynamicsWorld->addConstraint(part->constraint.get(), true);
} }
void VehicleObject::destroyObjectHinge(Part* part) { void VehicleObject::destroyObjectHinge(Part* part) {
if (part->constraint != nullptr) { if (part->constraint != nullptr) {
engine->dynamicsWorld->removeConstraint(part->constraint); engine->dynamicsWorld->removeConstraint(part->constraint.get());
delete part->constraint; part->constraint = nullptr;
} }
if (part->body != nullptr) { if (part->body != nullptr) {
engine->dynamicsWorld->removeCollisionObject(part->body); engine->dynamicsWorld->removeCollisionObject(part->body.get());
delete part->body->getMotionState(); part->body = nullptr;
delete part->body; part->motionState = nullptr;
delete part->cs; part->cs = nullptr;
} }
part->cs = nullptr;
part->body = nullptr;
part->constraint = nullptr;
// Reset target. // Reset target.
part->moveToAngle = false; part->moveToAngle = false;
} }

View File

@ -3,9 +3,9 @@
#include <cstddef> #include <cstddef>
#include <cstdint> #include <cstdint>
#include <map>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
#include <LinearMath/btScalar.h> #include <LinearMath/btScalar.h>
#include <glm/glm.hpp> #include <glm/glm.hpp>
@ -15,18 +15,14 @@
#include <objects/GameObject.hpp> #include <objects/GameObject.hpp>
#include <objects/VehicleInfo.hpp> #include <objects/VehicleInfo.hpp>
#include <btBulletDynamicsCommon.h>
class Atomic; class Atomic;
class CharacterObject; class CharacterObject;
class CollisionInstance; class CollisionInstance;
class GameWorld; class GameWorld;
class ModelFrame; class ModelFrame;
class btCollisionShape;
struct btVehicleRaycaster;
class btRaycastVehicle;
class btRigidBody;
class btHingeConstraint;
/** /**
* @class VehicleObject * @class VehicleObject
* Implements Vehicle behaviours. * Implements Vehicle behaviours.
@ -55,23 +51,47 @@ public:
std::map<size_t, GameObject*> seatOccupants; std::map<size_t, GameObject*> seatOccupants;
std::unique_ptr<CollisionInstance> collision; std::unique_ptr<CollisionInstance> collision;
btVehicleRaycaster* physRaycaster = nullptr; std::unique_ptr<btVehicleRaycaster> physRaycaster;
btRaycastVehicle* physVehicle = nullptr; std::unique_ptr<btRaycastVehicle> physVehicle;
struct Part { struct Part {
Part(ModelFrame* p_dummy, Atomic* p_normal, Atomic* p_damaged,
std::unique_ptr<btCollisionShape> p_cs,
std::unique_ptr<btRigidBody> p_body,
std::unique_ptr<btHingeConstraint> p_constraint,
bool p_moveToAngle, float p_targetAngle, float p_openAngle,
float p_closedAngle)
: dummy(p_dummy)
, normal(p_normal)
, damaged(p_damaged)
, cs(std::move(p_cs))
, body(std::move(p_body))
, constraint(std::move(p_constraint))
, moveToAngle(p_moveToAngle)
, targetAngle(p_targetAngle)
, openAngle(p_openAngle)
, closedAngle(p_closedAngle) {
}
Part(Part&& part) = default;
Part& operator=(Part&& part) = default;
~Part() = default;
ModelFrame* dummy; ModelFrame* dummy;
Atomic* normal; Atomic* normal;
Atomic* damaged; Atomic* damaged;
btCollisionShape* cs; std::unique_ptr<btCollisionShape> cs;
btRigidBody* body; std::unique_ptr<btRigidBody> body;
btHingeConstraint* constraint; std::unique_ptr<btMotionState> motionState;
std::unique_ptr<btHingeConstraint> constraint;
bool moveToAngle; bool moveToAngle;
float targetAngle; float targetAngle;
float openAngle; float openAngle;
float closedAngle; float closedAngle;
}; };
std::map<std::string, Part> dynamicParts; std::unordered_map<std::string, Part> dynamicParts;
VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot, VehicleObject(GameWorld* engine, const glm::vec3& pos, const glm::quat& rot,
BaseModelInfo* modelinfo, VehicleInfoHandle info, BaseModelInfo* modelinfo, VehicleInfoHandle info,

View File

@ -10,10 +10,10 @@ BOOST_AUTO_TEST_CASE(test_create_vehicle) {
VehicleObject* vehicle = VehicleObject* vehicle =
Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}); Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle != nullptr); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->info != nullptr); BOOST_REQUIRE(vehicle->info);
BOOST_REQUIRE(vehicle->getVehicle() != nullptr); BOOST_REQUIRE(vehicle->getVehicle());
// Hardcoded values for the moment // Hardcoded values for the moment
BOOST_CHECK_EQUAL(vehicle->getVehicle()->vehicletype_, BOOST_CHECK_EQUAL(vehicle->getVehicle()->vehicletype_,
@ -30,15 +30,15 @@ BOOST_AUTO_TEST_CASE(vehicle_parts) {
VehicleObject* vehicle = VehicleObject* vehicle =
Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}); Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle != nullptr); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->getModel() != nullptr); BOOST_REQUIRE(vehicle->getModel());
VehicleObject::Part* part = vehicle->getPart("bonnet_dummy"); VehicleObject::Part* part = vehicle->getPart("bonnet_dummy");
BOOST_REQUIRE(part != nullptr); BOOST_REQUIRE(part);
BOOST_REQUIRE(part->normal != nullptr); BOOST_REQUIRE(part->normal);
BOOST_REQUIRE(part->damaged != nullptr); BOOST_REQUIRE(part->damaged);
BOOST_REQUIRE(part->normal->getFrame()); BOOST_REQUIRE(part->normal->getFrame());
BOOST_REQUIRE(part->damaged->getFrame()); BOOST_REQUIRE(part->damaged->getFrame());
@ -53,8 +53,8 @@ BOOST_AUTO_TEST_CASE(vehicle_part_vis) {
VehicleObject* vehicle = VehicleObject* vehicle =
Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f}); Global::get().e->createVehicle(90u, glm::vec3(), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle != nullptr); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->getModel() != nullptr); BOOST_REQUIRE(vehicle->getModel());
VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy"); VehicleObject::Part* bonnetpart = vehicle->getPart("bonnet_dummy");
@ -75,10 +75,10 @@ BOOST_AUTO_TEST_CASE(test_door_position) {
VehicleObject* vehicle = Global::get().e->createVehicle( VehicleObject* vehicle = Global::get().e->createVehicle(
90u, glm::vec3(10.f, 0.f, 0.f), glm::quat{1.0f,0.0f,0.0f,0.0f}); 90u, glm::vec3(10.f, 0.f, 0.f), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle != nullptr); BOOST_REQUIRE(vehicle);
BOOST_REQUIRE(vehicle->info != nullptr); BOOST_REQUIRE(vehicle->info);
BOOST_REQUIRE(vehicle->getVehicle() != nullptr); BOOST_REQUIRE(vehicle->getVehicle());
BOOST_CHECK(vehicle->getSeatEntryPositionWorld(0).x > 5.f); BOOST_CHECK(vehicle->getSeatEntryPositionWorld(0).x > 5.f);
@ -93,20 +93,20 @@ BOOST_AUTO_TEST_CASE(test_hinges) {
VehicleObject::Part* part = vehicle->getPart("door_lf_dummy"); VehicleObject::Part* part = vehicle->getPart("door_lf_dummy");
BOOST_REQUIRE(part != nullptr); BOOST_REQUIRE(part);
BOOST_CHECK_EQUAL(part->constraint, nullptr); BOOST_CHECK(!part->constraint);
BOOST_CHECK_EQUAL(part->body, nullptr); BOOST_CHECK(!part->body);
vehicle->setPartLocked(part, false); vehicle->setPartLocked(part, false);
BOOST_CHECK_NE(part->body, nullptr); BOOST_CHECK(part->body);
BOOST_CHECK_NE(part->constraint, nullptr); BOOST_CHECK(part->constraint);
vehicle->setPartLocked(part, true); vehicle->setPartLocked(part, true);
BOOST_CHECK_EQUAL(part->constraint, nullptr); BOOST_CHECK(!part->constraint);
BOOST_CHECK_EQUAL(part->body, nullptr); BOOST_CHECK(!part->body);
Global::get().e->destroyObject(vehicle); Global::get().e->destroyObject(vehicle);
} }
@ -115,13 +115,13 @@ BOOST_AUTO_TEST_CASE(test_open_part) {
VehicleObject* vehicle = Global::get().e->createVehicle( VehicleObject* vehicle = Global::get().e->createVehicle(
90u, glm::vec3(10.f, 0.f, 0.f), glm::quat{1.0f,0.0f,0.0f,0.0f}); 90u, glm::vec3(10.f, 0.f, 0.f), glm::quat{1.0f,0.0f,0.0f,0.0f});
BOOST_REQUIRE(vehicle != nullptr); BOOST_REQUIRE(vehicle);
VehicleObject::Part* part = vehicle->getPart("door_lf_dummy"); VehicleObject::Part* part = vehicle->getPart("door_lf_dummy");
BOOST_REQUIRE(part != nullptr); BOOST_REQUIRE(part);
BOOST_CHECK_EQUAL(part->body, nullptr); BOOST_CHECK(!part->body);
vehicle->setPartLocked(part, true); vehicle->setPartLocked(part, true);
vehicle->setPartTarget(part, true, 1.f); vehicle->setPartTarget(part, true, 1.f);