put avatar body in right spot, and give it mass

This commit is contained in:
Andrew Meadows 2015-05-22 11:08:56 -07:00
parent 01cc629224
commit 0431e8da36
8 changed files with 26 additions and 15 deletions

View file

@ -9,11 +9,17 @@
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <PhysicsHelpers.h>
#include "Avatar.h"
#include "AvatarMotionState.h"
#include "BulletUtil.h"
AvatarMotionState::AvatarMotionState(Avatar* avatar, btCollisionShape* shape) : ObjectMotionState(shape), _avatar(avatar) {
assert(_avatar);
if (_shape) {
_mass = 100.0f; // HACK
}
}
AvatarMotionState::~AvatarMotionState() {
@ -35,7 +41,7 @@ MotionType AvatarMotionState::computeObjectMotionType() const {
return MOTION_TYPE_DYNAMIC;
}
// virtual
// virtual and protected
btCollisionShape* AvatarMotionState::computeNewShape() {
if (_avatar) {
ShapeInfo shapeInfo;
@ -68,10 +74,15 @@ void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
if (!_avatar) {
return;
}
// The PhysicsEngine does not move other Avatars.
// Instead we enforce the current transform of the Avatar
// 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(glmToBullet(getObjectPosition()));
newTransform.setOrigin((1.0f - tau) * currentPosition + tau * targetPosition);
newTransform.setRotation(glmToBullet(getObjectRotation()));
_body->setWorldTransform(newTransform);
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
@ -103,7 +114,7 @@ float AvatarMotionState::getObjectAngularDamping() const {
// virtual
glm::vec3 AvatarMotionState::getObjectPosition() const {
return glm::vec3(0.0f);
return _avatar->getPosition();
}
// virtual

View file

@ -28,7 +28,6 @@ public:
virtual uint32_t getAndClearIncomingDirtyFlags();
virtual MotionType computeObjectMotionType() const;
virtual btCollisionShape* computeNewShape();
virtual bool isMoving() const;
@ -65,6 +64,7 @@ public:
friend class AvatarManager;
protected:
virtual btCollisionShape* computeNewShape();
virtual void clearObjectBackPointer();
Avatar* _avatar;
uint32_t _dirtyFlags;

View file

@ -311,9 +311,11 @@ void DynamicCharacterController::updateShapeIfNecessary() {
// create new shape
_shape = new btCapsuleShape(_radius, 2.0f * _halfHeight);
// HACK: use some simple mass property defaults for now
float mass = 100.0f;
btVector3 inertia(30.0f, 8.0f, 30.0f);
// create new body
float mass = 1.0f;
btVector3 inertia(1.0f, 1.0f, 1.0f);
_rigidBody = new btRigidBody(mass, nullptr, _shape, inertia);
_rigidBody->setSleepingThresholds(0.0f, 0.0f);
_rigidBody->setAngularFactor(0.0f);

View file

@ -40,7 +40,8 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItem* entity
_loopsWithoutOwner(0)
{
_type = MOTIONSTATE_TYPE_ENTITY;
assert(entity != nullptr);
assert(_entity != nullptr);
setMass(_entity->computeMass());
}
EntityMotionState::~EntityMotionState() {
@ -176,6 +177,7 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
#endif
}
// virtual and protected
btCollisionShape* EntityMotionState::computeNewShape() {
if (_entity) {
ShapeInfo shapeInfo;

View file

@ -43,8 +43,6 @@ public:
// this relays outgoing position/rotation to the EntityItem
virtual void setWorldTransform(const btTransform& worldTrans);
virtual btCollisionShape* computeNewShape();
bool isCandidateForOwnership(const QUuid& sessionID) const;
bool remoteSimulationOutOfSync(uint32_t simulationStep);
bool shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID);
@ -82,6 +80,7 @@ public:
friend class PhysicalEntitySimulation;
protected:
virtual btCollisionShape* computeNewShape();
virtual void clearObjectBackPointer();
virtual void setMotionType(MotionType motionType);

View file

@ -163,7 +163,6 @@ void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
}
getShapeManager()->releaseShape(_shape);
if (_shape != newShape) {
// huh... the shape didn't actually change, so we remove the DIRTY_SHAPE flag
_shape = newShape;
_body->setCollisionShape(_shape);
flags &= ~EntityItem::DIRTY_SHAPE;

View file

@ -94,7 +94,6 @@ public:
virtual uint32_t getAndClearIncomingDirtyFlags() = 0;
virtual MotionType computeObjectMotionType() const = 0;
virtual btCollisionShape* computeNewShape() = 0;
btCollisionShape* getShape() const { return _shape; }
btRigidBody* getRigidBody() const { return _body; }
@ -127,6 +126,7 @@ public:
friend class PhysicsEngine;
protected:
virtual btCollisionShape* computeNewShape() = 0;
void setMotionType(MotionType motionType);
// clearObjectBackPointer() overrrides should call the base method, then actually clear the object back pointer.

View file

@ -156,12 +156,10 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToAdd() {
if (shape) {
EntityMotionState* motionState = new EntityMotionState(shape, entity);
entity->setPhysicsInfo(static_cast<void*>(motionState));
motionState->setMass(entity->computeMass());
_physicalObjects.insert(motionState);
_tempVector.push_back(motionState);
entityItr = _pendingAdds.erase(entityItr);
} else {
// TODO: Seth to look into why this case is hit.
//qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName();
++entityItr;
}