mirror of
https://github.com/lubosz/overte.git
synced 2025-04-26 14:15:39 +02:00
Merge pull request #13732 from AndrewMeadows/other-avatar-physics
reduce physics simulation cost of other-avatars
This commit is contained in:
commit
2013f1bd33
5 changed files with 46 additions and 8 deletions
interface/src/avatar
libraries
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -64,9 +64,9 @@ ShapeManager* ObjectMotionState::getShapeManager() {
|
|||
}
|
||||
|
||||
ObjectMotionState::ObjectMotionState(const btCollisionShape* shape) :
|
||||
_shape(shape),
|
||||
_lastKinematicStep(worldSimulationStep)
|
||||
{
|
||||
setShape(shape);
|
||||
}
|
||||
|
||||
ObjectMotionState::~ObjectMotionState() {
|
||||
|
|
|
@ -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 };
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue