initial impl of PhysicsWorld::addEntity()

This commit is contained in:
Andrew Meadows 2014-11-06 16:42:07 -08:00
parent 94b6d89b4e
commit 053b16783c
8 changed files with 199 additions and 74 deletions

View file

@ -21,6 +21,7 @@
#include "EntityScriptingInterface.h"
#include "EntityItem.h"
#include "EntityMotionState.h"
#include "EntityTree.h"
const float EntityItem::IMMORTAL = -1.0f; /// special lifetime which means the entity lives for ever. default lifetime
@ -87,6 +88,9 @@ EntityItem::EntityItem(const EntityItemID& entityItemID) {
_lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0;
_created = 0;
#ifdef USE_BULLET_PHYSICS
_motionState = NULL;
#endif // USE_BULLET_PHYSICS
initFromEntityItemID(entityItemID);
}
@ -97,10 +101,21 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert
_lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0;
_created = properties.getCreated();
#ifdef USE_BULLET_PHYSICS
_motionState = NULL;
#endif // USE_BULLET_PHYSICS
initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy
}
EntityItem::~EntityItem() {
#ifdef USE_BULLET_PHYSICS
// make sure the _motionState is already deleted (e.g. the entity has been removed
// from the physics simulation) BEFORE you get here
assert(_motionState == NULL);
#endif // USE_BULLET_PHYSICS
}
EntityPropertyFlags EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties;

View file

@ -49,7 +49,7 @@ public:
EntityItem(const EntityItemID& entityItemID);
EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
virtual ~EntityItem() { }
virtual ~EntityItem();
// ID and EntityItemID related methods
QUuid getID() const { return _id; }
@ -260,8 +260,7 @@ public:
virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); }
#ifdef USE_BULLET_PHYSICS
//EntityMotionState* createMotionState() = 0;
EntityMotionState* createMotionState() { return NULL; }
virtual EntityMotionState* createMotionState() { return NULL; }
#endif // USE_BULLET_PHYSICS
protected:
@ -304,6 +303,9 @@ protected:
void setRadius(float value);
AACubeShape _collisionShape;
#ifdef USE_BULLET_PHYSICS
EntityMotionState* _motionState;
#endif // USE_BULLET_PHYSICS
};

View file

@ -0,0 +1,56 @@
//
// EntityMotionState.cpp
// libraries/entities/src
//
// Created by Andrew Meadows on 2014.11.06
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#include <BulletUtil.h>
#include "EntityItem.h"
#include "EntityMotionState.h"
EntityMotionState::EntityMotionState(EntityItem* entity) : _entity(entity) {
assert(entity != NULL);
}
EntityMotionState::~EntityMotionState() {
}
// This callback is invoked by the physics simulation in two cases:
// (1) when the RigidBody is first added to the world
// (irregardless of MotionType: STATIC, DYNAMIC, or KINEMATIC)
// (2) at the beginning of each simulation frame for KINEMATIC RigidBody's --
// it is an opportunity for outside code to update the position of the object
void EntityMotionState::getWorldTransform (btTransform &worldTrans) const {
btVector3 pos;
glmToBullet(_entity->getPosition(), pos);
btQuaternion rot;
glmToBullet(_entity->getRotation(), rot);
worldTrans.setOrigin(pos);
worldTrans.setRotation(rot);
}
// This callback is invoked by the physics simulation at the end of each simulation frame...
// iff the corresponding RigidBody is DYNAMIC and has moved.
void EntityMotionState::setWorldTransform (const btTransform &worldTrans) {
glm::vec3 pos;
bulletToGLM(worldTrans.getOrigin(), pos);
_entity->setPositionInMeters(pos);
glm::quat rot;
bulletToGLM(worldTrans.getRotation(), rot);
_entity->setRotation(rot);
}
void EntityMotionState::computeShapeInfo(ShapeInfo& info) {
// HACK: for now we make everything a box.
glm::vec3 halfExtents = _entity->getDimensionsInMeters();
btVector3 bulletHalfExtents;
glmToBullet(halfExtents, bulletHalfExtents);
info.setBox(bulletHalfExtents);
}

View file

@ -0,0 +1,34 @@
//
// EntityMotionState.h
// libraries/entities/src
//
// Created by Andrew Meadows on 2014.11.06
// Copyright 2013 High Fidelity, Inc.
//
// Distributed under the Apache License, Version 2.0.
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
//
#ifndef hifi_EntityMotionState_h
#define hifi_EntityMotionState_h
#ifdef USE_BULLET_PHYSICS
#include <CustomMotionState.h>
class EntityMotionState : public CustomMotionState {
public:
EntityMotionState(EntityItem* item);
virtual ~EntityMotionState();
virtual void getWorldTransform (btTransform &worldTrans) const;
virtual void setWorldTransform (const btTransform &worldTrans);
virtual void computeShapeInfo(ShapeInfo& info);
protected:
EntityItem* _entity;
};
#endif // USE_BULLET_PHYSICS
#endif // hifi_EntityMotionState_h

View file

@ -11,58 +11,50 @@
#ifdef USE_BULLET_PHYSICS
#include <math.h>
#include "CustomMotionState.h"
CustomMotionState::CustomMotionState() : _motionType(MOTION_TYPE_STATIC),
_inertiaDiagLocal(1.0f, 1.0f, 1.0f), _mass(1.0f),
_shape(NULL), _object(NULL) {
const float MIN_DENSITY = 200.0f;
const float DEFAULT_DENSITY = 1000.0f;
const float MAX_DENSITY = 20000.0f;
const float MIN_VOLUME = 0.001f;
const float DEFAULT_VOLUME = 1.0f;
const float MAX_VOLUME = 1000000.0f;
const float DEFAULT_FRICTION = 0.5f;
const float MAX_FRICTION = 10.0f;
const float DEFAULT_RESTITUTION = 0.0f;
CustomMotionState::CustomMotionState() :
_density(DEFAULT_DENSITY),
_volume(DEFAULT_VOLUME),
_friction(DEFAULT_FRICTION),
_restitution(DEFAULT_RESTITUTION),
_motionType(MOTION_TYPE_STATIC),
_body(NULL) {
}
/*
void CustomMotionState::getWorldTransform (btTransform &worldTrans) const {
CustomMotionState::~CustomMotionState() {
assert(_body == NULL);
}
void CustomMotionState::setWorldTransform (const btTransform &worldTrans) {
void CustomMotionState::setDensity(float density) {
_density = btMax(btMin(fabsf(density), MAX_DENSITY), MIN_DENSITY);
}
void CustomMotionState::computeMassProperties() {
void CustomMotionState::setFriction(float friction) {
_friction = btMax(btMin(fabsf(friction), MAX_FRICTION), 0.0f);
}
void CustomMotionState::getShapeInfo(ShapeInfo& info) {
}
*/
bool CustomMotionState::makeStatic() {
if (_motionType == MOTION_TYPE_STATIC) {
return true;
}
if (!_object) {
_motionType = MOTION_TYPE_STATIC;
return true;
}
return false;
void CustomMotionState::setRestitution(float restitution) {
_restitution = btMax(btMin(fabsf(restitution), 1.0f), 0.0f);
}
bool CustomMotionState::makeDynamic() {
if (_motionType == MOTION_TYPE_DYNAMIC) {
return true;
}
if (!_object) {
_motionType = MOTION_TYPE_DYNAMIC;
return true;
}
return false;
}
bool CustomMotionState::makeKinematic() {
if (_motionType == MOTION_TYPE_KINEMATIC) {
return true;
}
if (!_object) {
_motionType = MOTION_TYPE_KINEMATIC;
return true;
}
return false;
void CustomMotionState::setVolume(float volume) {
_volume = btMax(btMin(fabsf(volume), MAX_VOLUME), MIN_VOLUME);
}
#endif // USE_BULLET_PHYSICS

View file

@ -17,7 +17,6 @@
#include <btBulletDynamicsCommon.h>
#include "ShapeInfo.h"
#include "UUIDHashKey.h"
enum MotionType {
MOTION_TYPE_STATIC, // no motion
@ -28,29 +27,34 @@ enum MotionType {
class CustomMotionState : public btMotionState {
public:
CustomMotionState();
~CustomMotionState();
//// these override methods of the btMotionState base class
//virtual void getWorldTransform (btTransform &worldTrans) const;
//virtual void setWorldTransform (const btTransform &worldTrans);
virtual void computeMassProperties() = 0;
virtual void getShapeInfo(ShapeInfo& info) = 0;
bool makeStatic();
bool makeDynamic();
bool makeKinematic();
virtual void computeShapeInfo(ShapeInfo& info) = 0;
MotionType getMotionType() const { return _motionType; }
private:
friend class PhysicsWorld;
void setDensity(float density);
void setFriction(float friction);
void setRestitution(float restitution);
void setVolume(float volume);
//EntityItem* _entity;
float getMass() const { return _volume * _density; }
friend class PhysicsWorld;
protected:
float _density;
float _volume;
float _friction;
float _restitution;
// The data members below have NO setters. They are only changed by a PhysicsWorld instance.
MotionType _motionType;
btVector3 _inertiaDiagLocal;
float _mass;
btCollisionShape* _shape;
btCollisionObject* _object;
btRigidBody* _body;
};
#endif // USE_BULLET_PHYSICS

View file

@ -76,23 +76,44 @@ bool PhysicsWorld::removeVoxel(const glm::vec3& position, float scale) {
return false;
}
bool PhysicsWorld::addEntity(const QUuid& id, CustomMotionState* motionState) {
bool PhysicsWorld::addEntity(CustomMotionState* motionState, float mass) {
assert(motionState);
UUIDHashKey key(id);
CustomMotionState** statePtr = _entities.find(key);
if (!statePtr) {
// BOOKMARK: Andrew to implement this
} else {
assert(*statePtr == motionState);
ShapeInfo info;
motionState->computeShapeInfo(info);
btCollisionShape* shape = _shapeManager.getShape(info);
if (shape) {
btVector3 inertia;
shape->calculateLocalInertia(mass, inertia);
btRigidBody* body = new btRigidBody(mass, motionState, shape, inertia);
_dynamicsWorld->addRigidBody(body);
motionState->_body = body;
}
return false;
}
bool PhysicsWorld::removeEntity(const QUuid& id) {
UUIDHashKey key(id);
CustomMotionState** statePtr = _entities.find(key);
if (statePtr) {
// BOOKMARK: Andrew to implement this
bool PhysicsWorld::removeEntity(CustomMotionState* motionState) {
assert(motionState);
btRigidBody* body = motionState->_body;
if (body) {
const btCollisionShape* shape = body->getCollisionShape();
ShapeInfo info;
info.collectInfo(shape);
_dynamicsWorld->removeRigidBody(body);
_shapeManager.releaseShape(info);
delete body;
motionState->_body = NULL;
}
return false;
}
bool PhysicsWorld::updateEntityMotionType(CustomMotionState* motionState, MotionType type) {
// TODO: implement this
assert(motionState);
return false;
}
bool PhysicsWorld::updateEntityMassProperties(CustomMotionState* motionState, float mass, const glm::vec3& inertiaEigenValues) {
// TODO: implement this
assert(motionState);
return false;
}

View file

@ -20,7 +20,6 @@
#include "CustomMotionState.h"
#include "PositionHashKey.h"
#include "ShapeManager.h"
#include "UUIDHashKey.h"
#include "VoxelObject.h"
class PhysicsWorld {
@ -45,11 +44,15 @@ public:
/// \return true if Entity added
/// \param info information about collision shapes to create
bool addEntity(const QUuid& id, CustomMotionState* motionState);
bool addEntity(CustomMotionState* motionState, float mass);
/// \return true if Entity removed
/// \param id UUID of the entity
bool removeEntity(const QUuid& id);
bool removeEntity(CustomMotionState* motionState);
bool updateEntityMotionType(CustomMotionState* motionState, MotionType type);
bool updateEntityMassProperties(CustomMotionState* motionState, float mass, const glm::vec3& inertiaEigenValues);
protected:
btDefaultCollisionConfiguration* _collisionConfig;
@ -57,12 +60,10 @@ protected:
btBroadphaseInterface* _broadphaseFilter;
btSequentialImpulseConstraintSolver* _constraintSolver;
btDiscreteDynamicsWorld* _dynamicsWorld;
ShapeManager _shapeManager;
private:
btHashMap<PositionHashKey, VoxelObject> _voxels;
btHashMap<UUIDHashKey, CustomMotionState*> _entities;
};