Skip to content

Commit

Permalink
UPBGE: Fix inertia form factor.
Browse files Browse the repository at this point in the history
The "Form Factor" UI value was not working anymore since a long time,
this was caused by the fact that UpdateCcdPhysicsController was
always called on conversion and that this function recalculated
the inertia tensor without the factor.

In this bug two parts are fixed, first the factor is applied
properly everytime setMassProps is called.
Secondly the call to UpdateCcdPhysicsController is avoided during
conversion. This call was proceeded because the functions
SetUserCollision[Group/mask] are calling RefreshCollisions. To avoid
these calls the collision group and mask are moved fully to
physics part, now KX_GameObject is reading and setting these bitmask
from the PHY_IPhysicsController API. The group and mask is initialized
along physics controller in ConvertObject function.
  • Loading branch information
panzergame committed Nov 17, 2017
1 parent 4326995 commit ca95d10
Show file tree
Hide file tree
Showing 11 changed files with 106 additions and 88 deletions.
2 changes: 1 addition & 1 deletion source/blender/makesrna/intern/rna_object.c
Original file line number Diff line number Diff line change
Expand Up @@ -1875,7 +1875,7 @@ static void rna_def_object_game_settings(BlenderRNA *brna)

prop = RNA_def_property(srna, "form_factor", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "formfactor");
RNA_def_property_range(prop, 0.0, 1.0);
RNA_def_property_range(prop, 0.0, 1000.0);
RNA_def_property_float_default(prop, 0.4f);
RNA_def_property_ui_text(prop, "Form Factor", "Form factor scales the inertia tensor");

Expand Down
6 changes: 0 additions & 6 deletions source/gameengine/Converter/BL_BlenderDataConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -710,15 +710,9 @@ static void BL_CreatePhysicsObjectNew(KX_GameObject *gameobj, Object *blenderobj
{
// Object has physics representation?
if (!(blenderobject->gameflag & OB_COLLISION)) {
// Respond to all collisions so that Near sensors work on No Collision objects.
gameobj->SetUserCollisionGroup(0xffff);
gameobj->SetUserCollisionMask(0xffff);
return;
}

gameobj->SetUserCollisionGroup(blenderobject->col_group);
gameobj->SetUserCollisionMask(blenderobject->col_mask);

Object *parent = blenderobject->parent;

bool isCompoundChild = false;
Expand Down
6 changes: 5 additions & 1 deletion source/gameengine/Expressions/EXP_PyObjectPlus.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,13 @@
#define USE_WEAKREFS

#include "EXP_Python.h"

#include "BLI_utildefines.h" // For BLI_assert.

#include "MT_Vector3.h"

#include <string>
#include <initializer_list>
#include "MT_Vector3.h"
#include <stddef.h>

#ifdef WITH_PYTHON
Expand Down
39 changes: 18 additions & 21 deletions source/gameengine/Ketsji/KX_GameObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -566,31 +566,28 @@ void KX_GameObject::ActivateGraphicController(bool recurse)
}
}

void KX_GameObject::SetUserCollisionGroup(unsigned short group)
void KX_GameObject::SetCollisionGroup(unsigned short group)
{
m_userCollisionGroup = group;
if (m_pPhysicsController)
if (m_pPhysicsController) {
m_pPhysicsController->SetCollisionGroup(group);
m_pPhysicsController->RefreshCollisions();
}
}
void KX_GameObject::SetUserCollisionMask(unsigned short mask)
void KX_GameObject::SetCollisionMask(unsigned short mask)
{
m_userCollisionMask = mask;
if (m_pPhysicsController)
if (m_pPhysicsController) {
m_pPhysicsController->SetCollisionMask(mask);
m_pPhysicsController->RefreshCollisions();
}
}

unsigned short KX_GameObject::GetUserCollisionGroup()
{
return m_userCollisionGroup;
}
unsigned short KX_GameObject::GetUserCollisionMask()
unsigned short KX_GameObject::GetCollisionGroup() const
{
return m_userCollisionMask;
return m_pPhysicsController ? m_pPhysicsController->GetCollisionGroup() : 0;
}

bool KX_GameObject::CheckCollision(KX_GameObject* other)
unsigned short KX_GameObject::GetCollisionMask() const
{
return this->m_userCollisionGroup & other->m_userCollisionMask;
return m_pPhysicsController ? m_pPhysicsController->GetCollisionMask() : 0;
}

EXP_Value* KX_GameObject::GetReplica()
Expand Down Expand Up @@ -2361,7 +2358,7 @@ int KX_GameObject::pyattr_set_collisionCallbacks(EXP_PyObjectPlus *self_v, const
PyObject *KX_GameObject::pyattr_get_collisionGroup(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyLong_FromLong(self->GetUserCollisionGroup());
return PyLong_FromLong(self->GetCollisionGroup());
}

int KX_GameObject::pyattr_set_collisionGroup(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value)
Expand All @@ -2379,14 +2376,14 @@ int KX_GameObject::pyattr_set_collisionGroup(EXP_PyObjectPlus *self_v, const EXP
return PY_SET_ATTR_FAIL;
}

self->SetUserCollisionGroup(val);
self->SetCollisionGroup(val);
return PY_SET_ATTR_SUCCESS;
}

PyObject *KX_GameObject::pyattr_get_collisionMask(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef)
{
KX_GameObject* self = static_cast<KX_GameObject*>(self_v);
return PyLong_FromLong(self->GetUserCollisionMask());
return PyLong_FromLong(self->GetCollisionMask());
}

int KX_GameObject::pyattr_set_collisionMask(EXP_PyObjectPlus *self_v, const EXP_PYATTRIBUTE_DEF *attrdef, PyObject *value)
Expand All @@ -2404,7 +2401,7 @@ int KX_GameObject::pyattr_set_collisionMask(EXP_PyObjectPlus *self_v, const EXP_
return PY_SET_ATTR_FAIL;
}

self->SetUserCollisionMask(val);
self->SetCollisionMask(val);
return PY_SET_ATTR_SUCCESS;
}

Expand Down Expand Up @@ -3840,7 +3837,7 @@ bool KX_GameObject::RayHit(KX_ClientObjectInfo *client, KX_RayCast *result, RayC
// if X-ray option is selected, the unwnted objects were not tested, so get here only with true hit
// if not, all objects were tested and the front one may not be the correct one.
if ((rayData->m_xray || rayData->m_prop.empty() || hitKXObj->GetProperty(rayData->m_prop) != nullptr) &&
hitKXObj->GetUserCollisionGroup() & rayData->m_mask)
hitKXObj->GetCollisionGroup() & rayData->m_mask)
{
rayData->m_hitObject = hitKXObj;
return true;
Expand Down Expand Up @@ -3868,7 +3865,7 @@ bool KX_GameObject::NeedRayCast(KX_ClientObjectInfo *client, RayCastData *rayDat
// if X-Ray option is selected, skip object that don't match the criteria as we see through them
// if not, test all objects because we don't know yet which one will be on front
if ((!rayData->m_xray || rayData->m_prop.size() || hitKXObj->GetProperty(rayData->m_prop) != nullptr) &&
hitKXObj->GetUserCollisionGroup() & rayData->m_mask)
hitKXObj->GetCollisionGroup() & rayData->m_mask)
{
return true;
}
Expand Down
16 changes: 4 additions & 12 deletions source/gameengine/Ketsji/KX_GameObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -114,10 +114,6 @@ class KX_GameObject : public SCA_IObject
bool m_bIsNegativeScaling;
MT_Vector4 m_objectColor;

// Bit fields for user control over physics collisions
unsigned short m_userCollisionGroup;
unsigned short m_userCollisionMask;

// visible = user setting
// culled = while rendering, depending on camera
bool m_bVisible;
Expand Down Expand Up @@ -486,18 +482,14 @@ class KX_GameObject : public SCA_IObject
/** Set the object's collison group
* \param filter The group bitfield
*/
void SetUserCollisionGroup(unsigned short filter);
void SetCollisionGroup(unsigned short filter);

/** Set the object's collison mask
* \param filter The mask bitfield
*/
void SetUserCollisionMask(unsigned short mask);
unsigned short GetUserCollisionGroup();
unsigned short GetUserCollisionMask();
/**
* Extra broadphase check for user controllable collisions
*/
bool CheckCollision(KX_GameObject *other);
void SetCollisionMask(unsigned short mask);
unsigned short GetCollisionGroup() const;
unsigned short GetCollisionMask() const;

/**
* \section Coordinate system manipulation functions
Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Ketsji/KX_MouseFocusSensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ bool KX_MouseFocusSensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(
}

// The current object is not in the proper layer.
if (!(hitKXObj->GetUserCollisionGroup() & m_mask)) {
if (!(hitKXObj->GetCollisionGroup() & m_mask)) {
return false;
}

Expand Down
2 changes: 1 addition & 1 deletion source/gameengine/Ketsji/KX_RaySensor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,7 +168,7 @@ bool KX_RaySensor::NeedRayCast(KX_ClientObjectInfo *client, void *UNUSED(data))
}

// The current object is not in the proper layer.
if (!(hitKXObj->GetUserCollisionGroup() & m_mask)) {
if (!(hitKXObj->GetCollisionGroup() & m_mask)) {
return false;
}

Expand Down
32 changes: 29 additions & 3 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1105,6 +1105,11 @@ void CcdPhysicsController::SetMass(MT_Scalar newmass)
}
}

float CcdPhysicsController::GetInertiaFactor() const
{
return m_cci.m_inertiaFactor;
}

// physics methods
void CcdPhysicsController::ApplyTorque(const MT_Vector3& torquein, bool local)
{
Expand Down Expand Up @@ -1270,6 +1275,26 @@ void CcdPhysicsController::SetActive(bool active)
{
}

unsigned short CcdPhysicsController::GetCollisionGroup() const
{
return m_cci.m_collisionGroup;
}

unsigned short CcdPhysicsController::GetCollisionMask() const
{
return m_cci.m_collisionMask;
}

void CcdPhysicsController::SetCollisionGroup(unsigned short group)
{
m_cci.m_collisionGroup = group;
}

void CcdPhysicsController::SetCollisionMask(unsigned short mask)
{
m_cci.m_collisionMask = mask;
}

float CcdPhysicsController::GetLinearDamping() const
{
const btRigidBody *body = GetRigidBody();
Expand Down Expand Up @@ -1464,12 +1489,13 @@ void CcdPhysicsController::AddCompoundChild(PHY_IPhysicsController *child)
proxyShapeInfo->Release();
// remember we created this shape
childCtrl->m_bulletChildShape = newChildShape;
// recompute inertia of parent

// Recalculate inertia for object owning compound shape.
if (!rootBody->isStaticOrKinematicObject()) {
btVector3 localInertia;
float mass = 1.0f / rootBody->getInvMass();
compoundShape->calculateLocalInertia(mass, localInertia);
rootBody->setMassProps(mass, localInertia);
rootBody->setMassProps(mass, localInertia * m_cci.m_inertiaFactor);
}
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
Expand Down Expand Up @@ -1523,7 +1549,7 @@ void CcdPhysicsController::RemoveCompoundChild(PHY_IPhysicsController *child)
btVector3 localInertia;
float mass = 1.f / rootBody->getInvMass();
compoundShape->calculateLocalInertia(mass, localInertia);
rootBody->setMassProps(mass, localInertia);
rootBody->setMassProps(mass, localInertia * m_cci.m_inertiaFactor);
}
// must update the broadphase cache,
GetPhysicsEnvironment()->RefreshCcdPhysicsController(this);
Expand Down
14 changes: 12 additions & 2 deletions source/gameengine/Physics/Bullet/CcdPhysicsController.h
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,8 @@ struct CcdConstructionInfo {
m_bGimpact(false),
m_collisionFilterGroup(DefaultFilter),
m_collisionFilterMask(AllFilter),
m_collisionGroup(0xFFFF),
m_collisionMask(0xFFFF),
m_collisionShape(nullptr),
m_MotionState(nullptr),
m_shapeInfo(nullptr),
Expand Down Expand Up @@ -400,6 +402,9 @@ struct CcdConstructionInfo {
short int m_collisionFilterGroup;
short int m_collisionFilterMask;

unsigned short m_collisionGroup;
unsigned short m_collisionMask;

/** these pointers are used as argument passing for the CcdPhysicsController constructor
* and not anymore after that
*/
Expand Down Expand Up @@ -683,6 +688,8 @@ class CcdPhysicsController : public PHY_IPhysicsController
virtual MT_Scalar GetMass();
virtual void SetMass(MT_Scalar newmass);

float GetInertiaFactor() const;

// physics methods
virtual void ApplyImpulse(const MT_Vector3& attach, const MT_Vector3& impulsein, bool local);
virtual void ApplyTorque(const MT_Vector3& torque, bool local);
Expand All @@ -692,6 +699,11 @@ class CcdPhysicsController : public PHY_IPhysicsController
virtual void Jump();
virtual void SetActive(bool active);

virtual unsigned short GetCollisionGroup() const;
virtual unsigned short GetCollisionMask() const;
virtual void SetCollisionGroup(unsigned short group);
virtual void SetCollisionMask(unsigned short mask);

virtual float GetLinearDamping() const;
virtual float GetAngularDamping() const;
virtual void SetLinearDamping(float damping);
Expand Down Expand Up @@ -806,8 +818,6 @@ class CcdPhysicsController : public PHY_IPhysicsController

static btTransform GetTransformFromMotionState(PHY_IMotionState *motionState);

void setAabb(const btVector3& aabbMin, const btVector3& aabbMax);

class PHY_IMotionState *GetMotionState()
{
return m_MotionState;
Expand Down
Loading

0 comments on commit ca95d10

Please sign in to comment.