avatars collide again

This commit is contained in:
Andrew Meadows 2018-05-11 17:01:48 -07:00
parent c624528f72
commit 6de175e794
4 changed files with 72 additions and 37 deletions

View file

@ -21,6 +21,17 @@ AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisi
_type = MOTIONSTATE_TYPE_AVATAR; _type = MOTIONSTATE_TYPE_AVATAR;
} }
void AvatarMotionState::handleEasyChanges(uint32_t& flags) {
ObjectMotionState::handleEasyChanges(flags);
if (flags & Simulation::DIRTY_PHYSICS_ACTIVATION && !_body->isActive()) {
_body->activate();
}
}
bool AvatarMotionState::handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) {
return ObjectMotionState::handleHardAndEasyChanges(flags, engine);
}
AvatarMotionState::~AvatarMotionState() { AvatarMotionState::~AvatarMotionState() {
assert(_avatar); assert(_avatar);
_avatar = nullptr; _avatar = nullptr;
@ -46,6 +57,9 @@ PhysicsMotionType AvatarMotionState::computePhysicsMotionType() const {
const btCollisionShape* AvatarMotionState::computeNewShape() { const btCollisionShape* AvatarMotionState::computeNewShape() {
ShapeInfo shapeInfo; ShapeInfo shapeInfo;
std::static_pointer_cast<Avatar>(_avatar)->computeShapeInfo(shapeInfo); std::static_pointer_cast<Avatar>(_avatar)->computeShapeInfo(shapeInfo);
glm::vec3 halfExtents = shapeInfo.getHalfExtents();
halfExtents.y = 0.0f;
_radius2 = glm::length2(halfExtents);
return getShapeManager()->getShape(shapeInfo); return getShapeManager()->getShape(shapeInfo);
} }
@ -60,7 +74,7 @@ void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const {
worldTrans.setRotation(glmToBullet(getObjectRotation())); worldTrans.setRotation(glmToBullet(getObjectRotation()));
if (_body) { if (_body) {
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); _body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity())); _body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
} }
} }
@ -72,13 +86,23 @@ void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
const float SPRING_TIMESCALE = 0.5f; const float SPRING_TIMESCALE = 0.5f;
float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE; float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE;
btVector3 currentPosition = worldTrans.getOrigin(); btVector3 currentPosition = worldTrans.getOrigin();
btVector3 targetPosition = glmToBullet(getObjectPosition()); btVector3 offsetToTarget = glmToBullet(getObjectPosition()) - currentPosition;
btTransform newTransform; float distance2 = offsetToTarget.length2();
newTransform.setOrigin((1.0f - tau) * currentPosition + tau * targetPosition); const float TWO_SQUARED = 4.0f;
newTransform.setRotation(glmToBullet(getObjectRotation())); if (distance2 > TWO_SQUARED * _radius2) {
_body->setWorldTransform(newTransform); // reduce the offsetToTarget by slamming the position
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity())); btTransform newTransform;
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity())); newTransform.setOrigin(currentPosition + tau * offsetToTarget);
newTransform.setRotation(glmToBullet(getObjectRotation()));
_body->setWorldTransform(newTransform);
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
} else {
// reduce the offsetToTarget by slamming the velocity
btVector3 velocity = glmToBullet(getObjectLinearVelocity()) + (1.0f / SPRING_TIMESCALE) * offsetToTarget;
_body->setLinearVelocity(velocity);
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
}
} }
// These pure virtual methods must be implemented for each MotionState type // These pure virtual methods must be implemented for each MotionState type
@ -145,3 +169,8 @@ void AvatarMotionState::computeCollisionGroupAndMask(int16_t& group, int16_t& ma
mask = Physics::getDefaultCollisionMask(group); mask = Physics::getDefaultCollisionMask(group);
} }
// virtual
float AvatarMotionState::getMass() const {
return std::static_pointer_cast<Avatar>(_avatar)->computeMass();
}

View file

@ -23,46 +23,51 @@ class AvatarMotionState : public ObjectMotionState {
public: public:
AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape); AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape);
virtual PhysicsMotionType getMotionType() const override { return _motionType; } void handleEasyChanges(uint32_t& flags) override;
bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override;
virtual uint32_t getIncomingDirtyFlags() override; PhysicsMotionType getMotionType() const override { return _motionType; }
virtual void clearIncomingDirtyFlags() override;
virtual PhysicsMotionType computePhysicsMotionType() const override; uint32_t getIncomingDirtyFlags() override;
void clearIncomingDirtyFlags() override;
virtual bool isMoving() const override; PhysicsMotionType computePhysicsMotionType() const override;
bool isMoving() const override;
// this relays incoming position/rotation to the RigidBody // this relays incoming position/rotation to the RigidBody
virtual void getWorldTransform(btTransform& worldTrans) const override; void getWorldTransform(btTransform& worldTrans) const override;
// this relays outgoing position/rotation to the EntityItem // this relays outgoing position/rotation to the EntityItem
virtual void setWorldTransform(const btTransform& worldTrans) override; void setWorldTransform(const btTransform& worldTrans) override;
// These pure virtual methods must be implemented for each MotionState type // These pure virtual methods must be implemented for each MotionState type
// and make it possible to implement more complicated methods in this base class. // and make it possible to implement more complicated methods in this base class.
// pure virtual overrides from ObjectMotionState // pure virtual overrides from ObjectMotionState
virtual float getObjectRestitution() const override; float getObjectRestitution() const override;
virtual float getObjectFriction() const override; float getObjectFriction() const override;
virtual float getObjectLinearDamping() const override; float getObjectLinearDamping() const override;
virtual float getObjectAngularDamping() const override; float getObjectAngularDamping() const override;
virtual glm::vec3 getObjectPosition() const override; glm::vec3 getObjectPosition() const override;
virtual glm::quat getObjectRotation() const override; glm::quat getObjectRotation() const override;
virtual glm::vec3 getObjectLinearVelocity() const override; glm::vec3 getObjectLinearVelocity() const override;
virtual glm::vec3 getObjectAngularVelocity() const override; glm::vec3 getObjectAngularVelocity() const override;
virtual glm::vec3 getObjectGravity() const override; glm::vec3 getObjectGravity() const override;
virtual const QUuid getObjectID() const override; const QUuid getObjectID() const override;
virtual QUuid getSimulatorID() const override; QUuid getSimulatorID() const override;
void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal); void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal);
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; } void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
virtual void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override; void computeCollisionGroupAndMask(int16_t& group, int16_t& mask) const override;
float getMass() const override;
friend class AvatarManager; friend class AvatarManager;
friend class Avatar; friend class Avatar;
@ -72,10 +77,11 @@ protected:
// ever called by the Avatar class dtor. // ever called by the Avatar class dtor.
~AvatarMotionState(); ~AvatarMotionState();
virtual bool isReadyToComputeShape() const override { return true; } bool isReadyToComputeShape() const override { return true; }
virtual const btCollisionShape* computeNewShape() override; const btCollisionShape* computeNewShape() override;
AvatarSharedPointer _avatar; AvatarSharedPointer _avatar;
float _radius2 { 0.0f };
uint32_t _dirtyFlags; uint32_t _dirtyFlags;
}; };

View file

@ -799,7 +799,6 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
return true; return true;
} }
// virtual
void Avatar::simulateAttachments(float deltaTime) { void Avatar::simulateAttachments(float deltaTime) {
assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size()); assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size());
PerformanceTimer perfTimer("attachments"); PerformanceTimer perfTimer("attachments");
@ -1482,12 +1481,14 @@ void Avatar::updateDisplayNameAlpha(bool showDisplayName) {
} }
} }
// virtual
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) { void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
float uniformScale = getModelScale(); float uniformScale = getModelScale();
shapeInfo.setCapsuleY(uniformScale * _skeletonModel->getBoundingCapsuleRadius(), float radius = uniformScale * _skeletonModel->getBoundingCapsuleRadius();
0.5f * uniformScale * _skeletonModel->getBoundingCapsuleHeight()); float height = uniformScale * _skeletonModel->getBoundingCapsuleHeight();
shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset()); shapeInfo.setCapsuleY(radius, 0.5f * height);
glm::vec3 offset = uniformScale * _skeletonModel->getBoundingCapsuleOffset();
shapeInfo.setOffset(offset);
} }
void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) { void Avatar::getCapsule(glm::vec3& start, glm::vec3& end, float& radius) {
@ -1510,9 +1511,8 @@ float Avatar::computeMass() {
return _density * TWO_PI * radius * radius * (glm::length(end - start) + 2.0f * radius / 3.0f); return _density * TWO_PI * radius * radius * (glm::length(end - start) + 2.0f * radius / 3.0f);
} }
// virtual
void Avatar::rebuildCollisionShape() { void Avatar::rebuildCollisionShape() {
addPhysicsFlags(Simulation::DIRTY_SHAPE); addPhysicsFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
} }
void Avatar::setPhysicsCallback(AvatarPhysicsCallback cb) { void Avatar::setPhysicsCallback(AvatarPhysicsCallback cb) {

View file

@ -111,7 +111,7 @@ public:
virtual PhysicsMotionType getMotionType() const { return _motionType; } virtual PhysicsMotionType getMotionType() const { return _motionType; }
void setMass(float mass); void setMass(float mass);
float getMass() const; virtual float getMass() const;
void setBodyLinearVelocity(const glm::vec3& velocity) const; void setBodyLinearVelocity(const glm::vec3& velocity) const;
void setBodyAngularVelocity(const glm::vec3& velocity) const; void setBodyAngularVelocity(const glm::vec3& velocity) const;