mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-09 21:56:26 +02:00
initial impl of PhysicsWorld::addEntity()
This commit is contained in:
parent
94b6d89b4e
commit
053b16783c
8 changed files with 199 additions and 74 deletions
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
56
libraries/entities/src/EntityMotionState.cpp
Normal file
56
libraries/entities/src/EntityMotionState.cpp
Normal 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);
|
||||||
|
}
|
||||||
|
|
34
libraries/entities/src/EntityMotionState.h
Normal file
34
libraries/entities/src/EntityMotionState.h
Normal 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
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue