mirror of
https://github.com/rwengine/openrw.git
synced 2024-11-25 11:52:40 +01:00
Merge pull request #450 from husho/objphy
[Ready] Fixed script objects falling through the ground
This commit is contained in:
commit
de8131924d
@ -19,10 +19,13 @@ InstanceObject::InstanceObject(GameWorld* engine, const glm::vec3& pos,
|
||||
const std::shared_ptr<DynamicObjectData>& dyn)
|
||||
: GameObject(engine, pos, rot, modelinfo)
|
||||
, health(100.f)
|
||||
, visible(true)
|
||||
, floating(false)
|
||||
, usePhysics(false)
|
||||
, changeAtomic(-1)
|
||||
, scale(scale)
|
||||
, body(nullptr)
|
||||
, dynamics(dyn)
|
||||
, _enablePhysics(false) {
|
||||
, dynamics(dyn) {
|
||||
if (modelinfo) {
|
||||
changeModel(modelinfo);
|
||||
setPosition(pos);
|
||||
@ -68,12 +71,10 @@ void InstanceObject::tickPhysics(float dt) {
|
||||
changeModel(getModelInfo<SimpleModelInfo>(), changeAtomic);
|
||||
changeAtomic = -1;
|
||||
}
|
||||
if (_enablePhysics) {
|
||||
if (body->getBulletBody()->isStaticObject()) {
|
||||
body->changeMass(dynamics->mass);
|
||||
}
|
||||
}
|
||||
|
||||
if (usePhysics) {
|
||||
body->changeMass(dynamics->mass);
|
||||
}
|
||||
|
||||
// Only certain objects should float on water
|
||||
if (floating) {
|
||||
@ -127,7 +128,7 @@ void InstanceObject::tickPhysics(float dt) {
|
||||
->getOrientation()
|
||||
.getAngle());
|
||||
body->getBulletBody()->applyImpulse(btVector3(0.f, 0.f, F),
|
||||
forcePos);
|
||||
forcePos);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -149,7 +150,8 @@ void InstanceObject::changeModel(BaseModelInfo* incoming, int atomicNumber) {
|
||||
setModel(getModelInfo<SimpleModelInfo>()->getModel());
|
||||
auto collision = getModelInfo<SimpleModelInfo>()->getCollision();
|
||||
|
||||
RW_ASSERT(getModelInfo<SimpleModelInfo>()->getNumAtomics() > atomicNumber);
|
||||
RW_ASSERT(getModelInfo<SimpleModelInfo>()->getNumAtomics() >
|
||||
atomicNumber);
|
||||
auto atomic = getModelInfo<SimpleModelInfo>()->getAtomic(atomicNumber);
|
||||
if (atomic) {
|
||||
auto previous = atomic_;
|
||||
@ -190,6 +192,19 @@ void InstanceObject::setRotation(const glm::quat& r) {
|
||||
GameObject::setRotation(r);
|
||||
}
|
||||
|
||||
void InstanceObject::setStatic(bool s) {
|
||||
int flags = body->getBulletBody()->getCollisionFlags();
|
||||
|
||||
if (s) {
|
||||
flags |= btCollisionObject::CF_STATIC_OBJECT;
|
||||
} else {
|
||||
flags &= ~btCollisionObject::CF_STATIC_OBJECT;
|
||||
}
|
||||
|
||||
body->getBulletBody()->setCollisionFlags(flags);
|
||||
static_ = s;
|
||||
}
|
||||
|
||||
bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||
if (!dynamics) {
|
||||
return false;
|
||||
@ -198,13 +213,20 @@ bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||
const auto effect = dynamics->collDamageEffect;
|
||||
|
||||
if (dmg.hitpoints > 0.f) {
|
||||
if (effect || dynamics->collResponseFlags) {
|
||||
if (dmg.impulse >= dynamics->uprootForce && !isStatic()) {
|
||||
usePhysics = true;
|
||||
}
|
||||
}
|
||||
|
||||
switch (effect) {
|
||||
case DynamicObjectData::Damage_ChangeModel:
|
||||
changeAtomic = 1;
|
||||
break;
|
||||
case DynamicObjectData::Damage_ChangeThenSmash:
|
||||
changeAtomic = 1;
|
||||
RW_UNIMPLEMENTED("Collision Damage Effect: Changing, then Smashing");
|
||||
RW_UNIMPLEMENTED(
|
||||
"Collision Damage Effect: Changing, then Smashing");
|
||||
break;
|
||||
case DynamicObjectData::Damage_Smash:
|
||||
RW_UNIMPLEMENTED("Collision Damage Effect: Smashing");
|
||||
@ -220,11 +242,6 @@ bool InstanceObject::takeDamage(const GameObject::DamageInfo& dmg) {
|
||||
}
|
||||
}
|
||||
|
||||
if (dmg.impulse >= dynamics->uprootForce &&
|
||||
body->getBulletBody()->isStaticObject()) {
|
||||
_enablePhysics = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -18,9 +18,11 @@ class GameWorld;
|
||||
*/
|
||||
class InstanceObject : public GameObject {
|
||||
float health;
|
||||
bool visible = true;
|
||||
bool floating = false;
|
||||
int changeAtomic = -1;
|
||||
bool visible;
|
||||
bool floating;
|
||||
bool static_;
|
||||
bool usePhysics;
|
||||
int changeAtomic;
|
||||
|
||||
/**
|
||||
* The Atomic instance for this object
|
||||
@ -31,7 +33,6 @@ public:
|
||||
glm::vec3 scale;
|
||||
std::unique_ptr<CollisionInstance> body;
|
||||
std::shared_ptr<DynamicObjectData> dynamics;
|
||||
bool _enablePhysics;
|
||||
|
||||
InstanceObject(GameWorld* engine, const glm::vec3& pos,
|
||||
const glm::quat& rot, const glm::vec3& scale,
|
||||
@ -59,19 +60,27 @@ public:
|
||||
|
||||
bool takeDamage(const DamageInfo& damage) override;
|
||||
|
||||
void setSolid(bool solid);
|
||||
void setSolid(bool s);
|
||||
|
||||
void setVisible(bool visible) {
|
||||
this->visible = visible;
|
||||
void setStatic(bool s);
|
||||
|
||||
bool isStatic() const {
|
||||
return static_;
|
||||
}
|
||||
float getVisible() const {
|
||||
|
||||
void setVisible(bool v) {
|
||||
visible = v;
|
||||
}
|
||||
|
||||
bool isVisible() const {
|
||||
return visible;
|
||||
}
|
||||
|
||||
void setFloating(bool floating) {
|
||||
this->floating = floating;
|
||||
void setFloating(bool f) {
|
||||
floating = f;
|
||||
}
|
||||
float getFloating() const {
|
||||
|
||||
bool isFloating() const {
|
||||
return floating;
|
||||
}
|
||||
|
||||
|
@ -35,10 +35,9 @@ constexpr float kMagicLODDistance = 330.f;
|
||||
constexpr float kVehicleLODDistance = 70.f;
|
||||
constexpr float kVehicleDrawDistance = 280.f;
|
||||
|
||||
RenderKey createKey(float normalizedDepth,
|
||||
Renderer::Textures& textures) {
|
||||
RenderKey createKey(float normalizedDepth, Renderer::Textures& textures) {
|
||||
return (uint32_t(0x7FFFFF * normalizedDepth) << 8 |
|
||||
uint8_t(0xFF & (!textures.empty() ? textures[0] : 0)));
|
||||
uint8_t(0xFF & (!textures.empty() ? textures[0] : 0)));
|
||||
}
|
||||
|
||||
void ObjectRenderer::renderGeometry(Geometry* geom,
|
||||
@ -106,9 +105,8 @@ void ObjectRenderer::renderGeometry(Geometry* geom,
|
||||
float distance = glm::length(m_camera.position - position);
|
||||
float depth = (distance - m_camera.frustum.near) /
|
||||
(m_camera.frustum.far - m_camera.frustum.near);
|
||||
outList.emplace_back(
|
||||
createKey(depth * depth, dp.textures), modelMatrix,
|
||||
&geom->dbuff, dp);
|
||||
outList.emplace_back(createKey(depth * depth, dp.textures), modelMatrix,
|
||||
&geom->dbuff, dp);
|
||||
}
|
||||
}
|
||||
|
||||
@ -154,7 +152,7 @@ void ObjectRenderer::renderInstance(InstanceObject* instance,
|
||||
}
|
||||
|
||||
// Only draw visible objects
|
||||
if (!instance->getVisible()) {
|
||||
if (!instance->isVisible()) {
|
||||
return;
|
||||
}
|
||||
|
||||
@ -226,7 +224,8 @@ void ObjectRenderer::renderCharacter(CharacterObject* pedestrian,
|
||||
}
|
||||
}
|
||||
|
||||
renderClump(pedestrian->getClump().get(), glm::mat4(1.0f), nullptr, outList);
|
||||
renderClump(pedestrian->getClump().get(), glm::mat4(1.0f), nullptr,
|
||||
outList);
|
||||
|
||||
auto item = pedestrian->getActiveItem();
|
||||
const auto& weapon = pedestrian->engine->data->weaponData[item];
|
||||
@ -254,7 +253,8 @@ void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
|
||||
return;
|
||||
}
|
||||
|
||||
float mindist = glm::length(vehicle->getPosition() - m_camera.position) / kVehicleDrawDistanceFactor;
|
||||
float mindist = glm::length(vehicle->getPosition() - m_camera.position) /
|
||||
kVehicleDrawDistanceFactor;
|
||||
if (mindist > kVehicleDrawDistance) {
|
||||
culled++;
|
||||
return;
|
||||
@ -308,7 +308,8 @@ void ObjectRenderer::renderVehicle(VehicleObject* vehicle,
|
||||
void ObjectRenderer::renderPickup(PickupObject* pickup, RenderList& outList) {
|
||||
if (!pickup->isEnabled()) return;
|
||||
|
||||
glm::mat4 modelMatrix = glm::translate(glm::mat4(1.0f), pickup->getPosition());
|
||||
glm::mat4 modelMatrix =
|
||||
glm::translate(glm::mat4(1.0f), pickup->getPosition());
|
||||
modelMatrix = glm::rotate(modelMatrix, m_world->getGameTime(),
|
||||
glm::vec3(0.f, 0.f, 1.f));
|
||||
|
||||
|
@ -2989,11 +2989,10 @@ bool opcode_0106(const ScriptArguments& args, const ScriptCharacter character0,
|
||||
@arg object Object
|
||||
*/
|
||||
void opcode_0107(const ScriptArguments& args, const ScriptModel model, ScriptVec3 coord, ScriptObject& object) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x0107);
|
||||
RW_UNUSED(model);
|
||||
RW_UNUSED(coord);
|
||||
RW_UNUSED(object);
|
||||
RW_UNUSED(args);
|
||||
// @todo calculate distance from centre of mass to base of model and apply it as spawnOffset
|
||||
coord = script::getGround(args, coord);
|
||||
object = args.getWorld()->createInstance(script::getModel(args, model), coord);
|
||||
object->setStatic(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -6890,15 +6889,9 @@ void opcode_0299(const ScriptArguments& args, const ScriptGarage garage) {
|
||||
@arg object Object
|
||||
*/
|
||||
void opcode_029b(const ScriptArguments& args, const ScriptModel model, ScriptVec3 coord, ScriptObject& object) {
|
||||
auto modelid = model;
|
||||
if (modelid < 0) {
|
||||
/// @todo move this to args.getModel();
|
||||
auto& models = args.getVM()->getFile()->getModels();
|
||||
auto& modelname = models[-modelid];
|
||||
modelid = args.getWorld()->data->findModelObject(modelname);
|
||||
}
|
||||
|
||||
object = args.getWorld()->createInstance(modelid, coord);
|
||||
coord = script::getGround(args, coord);
|
||||
object = args.getWorld()->createInstance(script::getModel(args, model), coord);
|
||||
object->setStatic(true);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -10435,13 +10428,11 @@ void opcode_0391(const ScriptArguments& args) {
|
||||
|
||||
opcode 0392
|
||||
@arg object Object
|
||||
@arg arg2 Boolean true/false
|
||||
@arg dynamic Boolean true/false
|
||||
*/
|
||||
void opcode_0392(const ScriptArguments& args, const ScriptObject object, const ScriptBoolean arg2) {
|
||||
RW_UNIMPLEMENTED_OPCODE(0x0392);
|
||||
RW_UNUSED(object);
|
||||
RW_UNUSED(arg2);
|
||||
void opcode_0392(const ScriptArguments& args, const ScriptObject object, const ScriptBoolean dynamic) {
|
||||
RW_UNUSED(args);
|
||||
object->setStatic(!dynamic);
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user