mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-14 11:46:34 +02:00
avatars collide again again
This commit is contained in:
parent
4880492d05
commit
085130e3c9
6 changed files with 54 additions and 23 deletions
|
@ -21,6 +21,17 @@ AvatarMotionState::AvatarMotionState(AvatarSharedPointer avatar, const btCollisi
|
|||
_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() {
|
||||
assert(_avatar);
|
||||
_avatar = nullptr;
|
||||
|
@ -46,6 +57,9 @@ 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);
|
||||
}
|
||||
|
||||
|
@ -60,25 +74,31 @@ void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const {
|
|||
worldTrans.setRotation(glmToBullet(getObjectRotation()));
|
||||
if (_body) {
|
||||
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||
// HACK: The PhysicsEngine does not actually move OTHER avatars -- instead it slaves their local RigidBody to the transform
|
||||
// as specified by a remote simulation. However, to give the remote simulation time to respond to our own objects we tie
|
||||
// the other avatar's body to its true position with a simple spring. This is a HACK that will have to be improved later.
|
||||
const float SPRING_TIMESCALE = 0.5f;
|
||||
float tau = PHYSICS_ENGINE_FIXED_SUBSTEP / SPRING_TIMESCALE;
|
||||
btVector3 currentPosition = worldTrans.getOrigin();
|
||||
btVector3 targetPosition = glmToBullet(getObjectPosition());
|
||||
btTransform newTransform;
|
||||
newTransform.setOrigin((1.0f - tau) * currentPosition + tau * targetPosition);
|
||||
newTransform.setRotation(glmToBullet(getObjectRotation()));
|
||||
_body->setWorldTransform(newTransform);
|
||||
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
btVector3 offsetToTarget = glmToBullet(getObjectPosition()) - currentPosition;
|
||||
float distance = offsetToTarget.length();
|
||||
if ((1.0f - tau) * distance > _diameter) {
|
||||
// the avatar body is far from its target --> slam position
|
||||
btTransform newTransform;
|
||||
newTransform.setOrigin(currentPosition + offsetToTarget);
|
||||
newTransform.setRotation(glmToBullet(getObjectRotation()));
|
||||
_body->setWorldTransform(newTransform);
|
||||
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
_body->setAngularVelocity(glmToBullet(getObjectAngularVelocity()));
|
||||
} else {
|
||||
// the avatar body is near its target --> slam 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
|
||||
|
@ -145,3 +165,8 @@ void AvatarMotionState::computeCollisionGroupAndMask(int32_t& group, int32_t& ma
|
|||
mask = Physics::getDefaultCollisionMask(group);
|
||||
}
|
||||
|
||||
// virtual
|
||||
float AvatarMotionState::getMass() const {
|
||||
return std::static_pointer_cast<Avatar>(_avatar)->computeMass();
|
||||
}
|
||||
|
||||
|
|
|
@ -23,6 +23,9 @@ class AvatarMotionState : public ObjectMotionState {
|
|||
public:
|
||||
AvatarMotionState(AvatarSharedPointer avatar, const btCollisionShape* shape);
|
||||
|
||||
virtual void handleEasyChanges(uint32_t& flags) override;
|
||||
virtual bool handleHardAndEasyChanges(uint32_t& flags, PhysicsEngine* engine) override;
|
||||
|
||||
virtual PhysicsMotionType getMotionType() const override { return _motionType; }
|
||||
|
||||
virtual uint32_t getIncomingDirtyFlags() override;
|
||||
|
@ -64,6 +67,8 @@ public:
|
|||
|
||||
virtual void computeCollisionGroupAndMask(int32_t& group, int32_t& mask) const override;
|
||||
|
||||
virtual float getMass() const override;
|
||||
|
||||
friend class AvatarManager;
|
||||
friend class Avatar;
|
||||
|
||||
|
@ -76,6 +81,7 @@ protected:
|
|||
virtual const btCollisionShape* computeNewShape() override;
|
||||
|
||||
AvatarSharedPointer _avatar;
|
||||
float _diameter { 0.0f };
|
||||
|
||||
uint32_t _dirtyFlags;
|
||||
};
|
||||
|
|
|
@ -861,7 +861,6 @@ bool Avatar::shouldRenderHead(const RenderArgs* renderArgs) const {
|
|||
return true;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void Avatar::simulateAttachments(float deltaTime) {
|
||||
assert(_attachmentModels.size() == _attachmentModelsTexturesLoaded.size());
|
||||
PerformanceTimer perfTimer("attachments");
|
||||
|
@ -1544,12 +1543,13 @@ void Avatar::updateDisplayNameAlpha(bool showDisplayName) {
|
|||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||
float uniformScale = getModelScale();
|
||||
shapeInfo.setCapsuleY(uniformScale * _skeletonModel->getBoundingCapsuleRadius(),
|
||||
0.5f * uniformScale * _skeletonModel->getBoundingCapsuleHeight());
|
||||
shapeInfo.setOffset(uniformScale * _skeletonModel->getBoundingCapsuleOffset());
|
||||
float radius = glm::max(MIN_AVATAR_RADIUS, uniformScale * _skeletonModel->getBoundingCapsuleRadius());
|
||||
float height = glm::max(MIN_AVATAR_HEIGHT, uniformScale * _skeletonModel->getBoundingCapsuleHeight());
|
||||
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) {
|
||||
|
@ -1572,9 +1572,8 @@ float Avatar::computeMass() {
|
|||
return _density * TWO_PI * radius * radius * (glm::length(end - start) + 2.0f * radius / 3.0f);
|
||||
}
|
||||
|
||||
// virtual
|
||||
void Avatar::rebuildCollisionShape() {
|
||||
addPhysicsFlags(Simulation::DIRTY_SHAPE);
|
||||
addPhysicsFlags(Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS);
|
||||
}
|
||||
|
||||
void Avatar::setPhysicsCallback(AvatarPhysicsCallback cb) {
|
||||
|
|
|
@ -110,8 +110,8 @@ public:
|
|||
MotionStateType getType() const { return _type; }
|
||||
virtual PhysicsMotionType getMotionType() const { return _motionType; }
|
||||
|
||||
void setMass(float mass);
|
||||
float getMass() const;
|
||||
virtual void setMass(float mass);
|
||||
virtual float getMass() const;
|
||||
|
||||
void setBodyLinearVelocity(const glm::vec3& velocity) const;
|
||||
void setBodyAngularVelocity(const glm::vec3& velocity) const;
|
||||
|
|
|
@ -105,9 +105,9 @@ void PhysicsEngine::addObjectToDynamicsWorld(ObjectMotionState* motionState) {
|
|||
}
|
||||
case MOTION_TYPE_DYNAMIC: {
|
||||
mass = motionState->getMass();
|
||||
if (mass != mass || mass < 1.0f) {
|
||||
qCDebug(physics) << "mass is too low, setting to 1.0 Kg --" << mass;
|
||||
mass = 1.0f;
|
||||
const float MIN_DYNAMIC_MASS = 0.01f;
|
||||
if (mass != mass || mass < MIN_DYNAMIC_MASS) {
|
||||
mass = MIN_DYNAMIC_MASS;
|
||||
}
|
||||
btCollisionShape* shape = const_cast<btCollisionShape*>(motionState->getShape());
|
||||
assert(shape);
|
||||
|
|
|
@ -69,6 +69,7 @@ static const float MIN_AVATAR_SCALE = 0.005f;
|
|||
|
||||
static const float MAX_AVATAR_HEIGHT = 1000.0f * DEFAULT_AVATAR_HEIGHT; // meters
|
||||
static const float MIN_AVATAR_HEIGHT = 0.005f * DEFAULT_AVATAR_HEIGHT; // meters
|
||||
static const float MIN_AVATAR_RADIUS = 0.5f * MIN_AVATAR_HEIGHT;
|
||||
static const float AVATAR_WALK_SPEED_SCALAR = 1.0f;
|
||||
static const float AVATAR_SPRINT_SPEED_SCALAR = 3.0f;
|
||||
|
||||
|
|
Loading…
Reference in a new issue