3
0
Fork 0
mirror of https://github.com/lubosz/overte.git synced 2025-04-26 14:15:39 +02:00

Merge pull request from AndrewMeadows/other-avatar-physics

reduce physics simulation cost of other-avatars
This commit is contained in:
Sam Gateau 2018-08-03 09:33:59 -07:00 committed by GitHub
commit 2013f1bd33
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 46 additions and 8 deletions

View file

@ -19,6 +19,7 @@
AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) {
assert(_avatar);
_type = MOTIONSTATE_TYPE_AVATAR;
cacheShapeDiameter();
}
void AvatarMotionState::handleEasyChanges(uint32_t& flags) {
@ -57,9 +58,6 @@ PhysicsMotionType AvatarMotionState::computePhysicsMotionType() const {
const btCollisionShape* AvatarMotionState::computeNewShape() {
ShapeInfo shapeInfo;
std::static_pointer_cast<Avatar>(_avatar)->computeShapeInfo(shapeInfo);
glm::vec3 halfExtents = shapeInfo.getHalfExtents();
halfExtents.y = 0.0f;
_diameter = 2.0f * glm::length(halfExtents);
return getShapeManager()->getShape(shapeInfo);
}
@ -98,6 +96,10 @@ void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
btVector3 velocity = glmToBullet(getObjectLinearVelocity()) + (1.0f / SPRING_TIMESCALE) * offsetToTarget;
_body->setLinearVelocity(velocity);
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
// slam its rotation
btTransform newTransform = worldTrans;
newTransform.setRotation(glmToBullet(getObjectRotation()));
_body->setWorldTransform(newTransform);
}
}
@ -141,7 +143,10 @@ glm::vec3 AvatarMotionState::getObjectLinearVelocity() const {
// virtual
glm::vec3 AvatarMotionState::getObjectAngularVelocity() const {
return _avatar->getWorldAngularVelocity();
// HACK: avatars use a capusle collision shape and their angularVelocity in the local simulation is unimportant.
// Therefore, as optimization toward support for larger crowds we ignore it and return zero.
//return _avatar->getWorldAngularVelocity();
return glm::vec3(0.0f);
}
// virtual
@ -174,3 +179,28 @@ float AvatarMotionState::getMass() const {
return std::static_pointer_cast<Avatar>(_avatar)->computeMass();
}
void AvatarMotionState::cacheShapeDiameter() {
if (_shape) {
// shape is capsuleY
btVector3 aabbMin, aabbMax;
btTransform transform;
transform.setIdentity();
_shape->getAabb(transform, aabbMin, aabbMax);
_diameter = (aabbMax - aabbMin).getX();
} else {
_diameter = 0.0f;
}
}
void AvatarMotionState::setRigidBody(btRigidBody* body) {
ObjectMotionState::setRigidBody(body);
if (_body) {
// remove angular dynamics from this body
_body->setAngularFactor(0.0f);
}
}
void AvatarMotionState::setShape(const btCollisionShape* shape) {
ObjectMotionState::setShape(shape);
cacheShapeDiameter();
}

View file

@ -74,6 +74,10 @@ public:
friend class Avatar;
protected:
void setRigidBody(btRigidBody* body) override;
void setShape(const btCollisionShape* shape) override;
void cacheShapeDiameter();
// the dtor had been made protected to force the compiler to verify that it is only
// ever called by the Avatar class dtor.
~AvatarMotionState();

View file

@ -64,9 +64,9 @@ ShapeManager* ObjectMotionState::getShapeManager() {
}
ObjectMotionState::ObjectMotionState(const btCollisionShape* shape) :
_shape(shape),
_lastKinematicStep(worldSimulationStep)
{
setShape(shape);
}
ObjectMotionState::~ObjectMotionState() {

View file

@ -175,13 +175,13 @@ protected:
virtual void setMotionType(PhysicsMotionType motionType);
void updateCCDConfiguration();
void setRigidBody(btRigidBody* body);
virtual void setRigidBody(btRigidBody* body);
virtual void setShape(const btCollisionShape* shape);
MotionStateType _type { MOTIONSTATE_TYPE_INVALID }; // type of MotionState
PhysicsMotionType _motionType { MOTION_TYPE_STATIC }; // type of motion: KINEMATIC, DYNAMIC, or STATIC
const btCollisionShape* _shape;
const btCollisionShape* _shape { nullptr };
btRigidBody* _body { nullptr };
float _density { 1.0f };

View file

@ -59,7 +59,11 @@ const int32_t BULLET_COLLISION_MASK_KINEMATIC = BULLET_COLLISION_MASK_STATIC;
// MY_AVATAR does not collide with itself
const int32_t BULLET_COLLISION_MASK_MY_AVATAR = ~(BULLET_COLLISION_GROUP_COLLISIONLESS | BULLET_COLLISION_GROUP_MY_AVATAR);
const int32_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_MASK_DEFAULT;
// OTHER_AVATARs are dynamic, but are slammed to whatever the avatar-mixer says, which means
// their motion can't actually be affected by the local physics simulation -- we rely on the remote simulation
// to move its avatar around correctly and to communicate its motion through the avatar-mixer.
// Therefore, they only need to collide against things that can be affected by their motion: dynamic and MyAvatar
const int32_t BULLET_COLLISION_MASK_OTHER_AVATAR = BULLET_COLLISION_GROUP_DYNAMIC | BULLET_COLLISION_GROUP_MY_AVATAR;
// COLLISIONLESS gets an empty mask.
const int32_t BULLET_COLLISION_MASK_COLLISIONLESS = 0;