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 "EntityScriptingInterface.h"
#include "EntityItem.h" #include "EntityItem.h"
#include "EntityMotionState.h"
#include "EntityTree.h" #include "EntityTree.h"
const float EntityItem::IMMORTAL = -1.0f; /// special lifetime which means the entity lives for ever. default lifetime 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; _lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0; _lastUpdated = 0;
_created = 0; _created = 0;
#ifdef USE_BULLET_PHYSICS
_motionState = NULL;
#endif // USE_BULLET_PHYSICS
initFromEntityItemID(entityItemID); initFromEntityItemID(entityItemID);
} }
@ -97,10 +101,21 @@ EntityItem::EntityItem(const EntityItemID& entityItemID, const EntityItemPropert
_lastEditedFromRemoteInRemoteTime = 0; _lastEditedFromRemoteInRemoteTime = 0;
_lastUpdated = 0; _lastUpdated = 0;
_created = properties.getCreated(); _created = properties.getCreated();
#ifdef USE_BULLET_PHYSICS
_motionState = NULL;
#endif // USE_BULLET_PHYSICS
initFromEntityItemID(entityItemID); initFromEntityItemID(entityItemID);
setProperties(properties, true); // force copy 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 EntityItem::getEntityProperties(EncodeBitstreamParams& params) const {
EntityPropertyFlags requestedProperties; EntityPropertyFlags requestedProperties;

View file

@ -49,7 +49,7 @@ public:
EntityItem(const EntityItemID& entityItemID); EntityItem(const EntityItemID& entityItemID);
EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties); EntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
virtual ~EntityItem() { } virtual ~EntityItem();
// ID and EntityItemID related methods // ID and EntityItemID related methods
QUuid getID() const { return _id; } QUuid getID() const { return _id; }
@ -260,8 +260,7 @@ public:
virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); } virtual bool contains(const glm::vec3& point) const { return getAABox().contains(point); }
#ifdef USE_BULLET_PHYSICS #ifdef USE_BULLET_PHYSICS
//EntityMotionState* createMotionState() = 0; virtual EntityMotionState* createMotionState() { return NULL; }
EntityMotionState* createMotionState() { return NULL; }
#endif // USE_BULLET_PHYSICS #endif // USE_BULLET_PHYSICS
protected: protected:
@ -304,6 +303,9 @@ protected:
void setRadius(float value); void setRadius(float value);
AACubeShape _collisionShape; 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 #ifdef USE_BULLET_PHYSICS
#include <math.h>
#include "CustomMotionState.h" #include "CustomMotionState.h"
CustomMotionState::CustomMotionState() : _motionType(MOTION_TYPE_STATIC), const float MIN_DENSITY = 200.0f;
_inertiaDiagLocal(1.0f, 1.0f, 1.0f), _mass(1.0f), const float DEFAULT_DENSITY = 1000.0f;
_shape(NULL), _object(NULL) { 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) {
} }
/* CustomMotionState::~CustomMotionState() {
void CustomMotionState::getWorldTransform (btTransform &worldTrans) const { 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) { void CustomMotionState::setRestitution(float restitution) {
} _restitution = btMax(btMin(fabsf(restitution), 1.0f), 0.0f);
*/
bool CustomMotionState::makeStatic() {
if (_motionType == MOTION_TYPE_STATIC) {
return true;
}
if (!_object) {
_motionType = MOTION_TYPE_STATIC;
return true;
}
return false;
} }
bool CustomMotionState::makeDynamic() { void CustomMotionState::setVolume(float volume) {
if (_motionType == MOTION_TYPE_DYNAMIC) { _volume = btMax(btMin(fabsf(volume), MAX_VOLUME), MIN_VOLUME);
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;
} }
#endif // USE_BULLET_PHYSICS #endif // USE_BULLET_PHYSICS

View file

@ -17,7 +17,6 @@
#include <btBulletDynamicsCommon.h> #include <btBulletDynamicsCommon.h>
#include "ShapeInfo.h" #include "ShapeInfo.h"
#include "UUIDHashKey.h"
enum MotionType { enum MotionType {
MOTION_TYPE_STATIC, // no motion MOTION_TYPE_STATIC, // no motion
@ -28,29 +27,34 @@ enum MotionType {
class CustomMotionState : public btMotionState { class CustomMotionState : public btMotionState {
public: public:
CustomMotionState(); CustomMotionState();
~CustomMotionState();
//// these override methods of the btMotionState base class //// these override methods of the btMotionState base class
//virtual void getWorldTransform (btTransform &worldTrans) const; //virtual void getWorldTransform (btTransform &worldTrans) const;
//virtual void setWorldTransform (const btTransform &worldTrans); //virtual void setWorldTransform (const btTransform &worldTrans);
virtual void computeMassProperties() = 0; virtual void computeShapeInfo(ShapeInfo& info) = 0;
virtual void getShapeInfo(ShapeInfo& info) = 0;
bool makeStatic();
bool makeDynamic();
bool makeKinematic();
MotionType getMotionType() const { return _motionType; } MotionType getMotionType() const { return _motionType; }
private: void setDensity(float density);
friend class PhysicsWorld; 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; MotionType _motionType;
btVector3 _inertiaDiagLocal; btRigidBody* _body;
float _mass;
btCollisionShape* _shape;
btCollisionObject* _object;
}; };
#endif // USE_BULLET_PHYSICS #endif // USE_BULLET_PHYSICS

View file

@ -76,23 +76,44 @@ bool PhysicsWorld::removeVoxel(const glm::vec3& position, float scale) {
return false; return false;
} }
bool PhysicsWorld::addEntity(const QUuid& id, CustomMotionState* motionState) { bool PhysicsWorld::addEntity(CustomMotionState* motionState, float mass) {
assert(motionState); assert(motionState);
UUIDHashKey key(id); ShapeInfo info;
CustomMotionState** statePtr = _entities.find(key); motionState->computeShapeInfo(info);
if (!statePtr) { btCollisionShape* shape = _shapeManager.getShape(info);
// BOOKMARK: Andrew to implement this if (shape) {
} else { btVector3 inertia;
assert(*statePtr == motionState); shape->calculateLocalInertia(mass, inertia);
btRigidBody* body = new btRigidBody(mass, motionState, shape, inertia);
_dynamicsWorld->addRigidBody(body);
motionState->_body = body;
} }
return false; return false;
} }
bool PhysicsWorld::removeEntity(const QUuid& id) { bool PhysicsWorld::removeEntity(CustomMotionState* motionState) {
UUIDHashKey key(id); assert(motionState);
CustomMotionState** statePtr = _entities.find(key); btRigidBody* body = motionState->_body;
if (statePtr) { if (body) {
// BOOKMARK: Andrew to implement this const btCollisionShape* shape = body->getCollisionShape();
ShapeInfo info;
info.collectInfo(shape);
_dynamicsWorld->removeRigidBody(body);
_shapeManager.releaseShape(info);
delete body;
motionState->_body = NULL;
} }
return false; 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 "CustomMotionState.h"
#include "PositionHashKey.h" #include "PositionHashKey.h"
#include "ShapeManager.h" #include "ShapeManager.h"
#include "UUIDHashKey.h"
#include "VoxelObject.h" #include "VoxelObject.h"
class PhysicsWorld { class PhysicsWorld {
@ -45,11 +44,15 @@ public:
/// \return true if Entity added /// \return true if Entity added
/// \param info information about collision shapes to create /// \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 /// \return true if Entity removed
/// \param id UUID of the entity /// \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: protected:
btDefaultCollisionConfiguration* _collisionConfig; btDefaultCollisionConfiguration* _collisionConfig;
@ -57,12 +60,10 @@ protected:
btBroadphaseInterface* _broadphaseFilter; btBroadphaseInterface* _broadphaseFilter;
btSequentialImpulseConstraintSolver* _constraintSolver; btSequentialImpulseConstraintSolver* _constraintSolver;
btDiscreteDynamicsWorld* _dynamicsWorld; btDiscreteDynamicsWorld* _dynamicsWorld;
ShapeManager _shapeManager; ShapeManager _shapeManager;
private: private:
btHashMap<PositionHashKey, VoxelObject> _voxels; btHashMap<PositionHashKey, VoxelObject> _voxels;
btHashMap<UUIDHashKey, CustomMotionState*> _entities;
}; };