mirror of
https://github.com/overte-org/overte.git
synced 2025-04-20 02:03:57 +02:00
Merge remote-tracking branch 'upstream/master' into plugins
This commit is contained in:
commit
dd87707c7b
97 changed files with 913 additions and 575 deletions
|
@ -262,7 +262,6 @@ $(document).ready(function(){
|
|||
$('#' + Settings.FORM_ID).on('click', '#' + Settings.CONNECT_ACCOUNT_BTN_ID, function(e){
|
||||
$(this).blur();
|
||||
prepareAccessTokenPrompt();
|
||||
e.preventDefault();
|
||||
});
|
||||
|
||||
var panelsSource = $('#panels-template').html()
|
||||
|
|
|
@ -682,6 +682,10 @@ Application::~Application() {
|
|||
|
||||
getActiveDisplayPlugin()->deactivate();
|
||||
|
||||
// remove avatars from physics engine
|
||||
DependencyManager::get<AvatarManager>()->clearOtherAvatars();
|
||||
_physicsEngine.deleteObjects(DependencyManager::get<AvatarManager>()->getObjectsToDelete());
|
||||
|
||||
DependencyManager::destroy<OffscreenUi>();
|
||||
DependencyManager::destroy<AvatarManager>();
|
||||
DependencyManager::destroy<AnimationCache>();
|
||||
|
@ -1908,7 +1912,7 @@ void Application::toggleFaceTrackerMute() {
|
|||
}
|
||||
|
||||
bool Application::exportEntities(const QString& filename, const QVector<EntityItemID>& entityIDs) {
|
||||
QVector<EntityItem*> entities;
|
||||
QVector<EntityItemPointer> entities;
|
||||
|
||||
auto entityTree = _entities.getTree();
|
||||
EntityTree exportTree;
|
||||
|
@ -1949,7 +1953,7 @@ bool Application::exportEntities(const QString& filename, const QVector<EntityIt
|
|||
}
|
||||
|
||||
bool Application::exportEntities(const QString& filename, float x, float y, float z, float scale) {
|
||||
QVector<EntityItem*> entities;
|
||||
QVector<EntityItemPointer> entities;
|
||||
_entities.getTree()->findEntities(AACube(glm::vec3(x, y, z), scale), entities);
|
||||
|
||||
if (entities.size() > 0) {
|
||||
|
@ -2091,7 +2095,7 @@ void Application::init() {
|
|||
_physicsEngine.init();
|
||||
|
||||
EntityTree* tree = _entities.getTree();
|
||||
_entitySimulation.init(tree, &_physicsEngine, &_shapeManager, &_entityEditSender);
|
||||
_entitySimulation.init(tree, &_physicsEngine, &_entityEditSender);
|
||||
tree->setSimulation(&_entitySimulation);
|
||||
|
||||
auto entityScriptingInterface = DependencyManager::get<EntityScriptingInterface>();
|
||||
|
@ -2411,12 +2415,21 @@ void Application::update(float deltaTime) {
|
|||
_physicsEngine.changeObjects(_entitySimulation.getObjectsToChange());
|
||||
_entitySimulation.unlock();
|
||||
|
||||
AvatarManager* avatarManager = DependencyManager::get<AvatarManager>().data();
|
||||
_physicsEngine.deleteObjects(avatarManager->getObjectsToDelete());
|
||||
_physicsEngine.addObjects(avatarManager->getObjectsToAdd());
|
||||
_physicsEngine.changeObjects(avatarManager->getObjectsToChange());
|
||||
|
||||
_physicsEngine.stepSimulation();
|
||||
|
||||
if (_physicsEngine.hasOutgoingChanges()) {
|
||||
_entitySimulation.lock();
|
||||
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
|
||||
_entitySimulation.unlock();
|
||||
|
||||
avatarManager->handleOutgoingChanges(_physicsEngine.getOutgoingChanges());
|
||||
avatarManager->handleCollisionEvents(_physicsEngine.getCollisionEvents());
|
||||
|
||||
_physicsEngine.dumpStatsIfNecessary();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include "Application.h"
|
||||
#include "Avatar.h"
|
||||
#include "AvatarManager.h"
|
||||
#include "AvatarMotionState.h"
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "Menu.h"
|
||||
|
@ -972,6 +973,9 @@ int Avatar::parseDataAtOffset(const QByteArray& packet, int offset) {
|
|||
|
||||
const float MOVE_DISTANCE_THRESHOLD = 0.001f;
|
||||
_moving = glm::distance(oldPosition, _position) > MOVE_DISTANCE_THRESHOLD;
|
||||
if (_moving && _motionState) {
|
||||
_motionState->addDirtyFlags(EntityItem::DIRTY_POSITION);
|
||||
}
|
||||
|
||||
return bytesRead;
|
||||
}
|
||||
|
@ -1087,20 +1091,15 @@ void Avatar::setShowDisplayName(bool showDisplayName) {
|
|||
|
||||
}
|
||||
|
||||
// virtual
|
||||
void Avatar::rebuildSkeletonBody() {
|
||||
/* TODO: implement this and remove override from MyAvatar (when we have AvatarMotionStates working)
|
||||
if (_motionState) {
|
||||
// compute localAABox
|
||||
const CapsuleShape& capsule = _skeletonModel.getBoundingShape();
|
||||
float radius = capsule.getRadius();
|
||||
float height = 2.0f * (capsule.getHalfHeight() + radius);
|
||||
glm::vec3 corner(-radius, -0.5f * height, -radius);
|
||||
corner += _skeletonModel.getBoundingShapeOffset();
|
||||
glm::vec3 scale(2.0f * radius, height, 2.0f * radius);
|
||||
//_characterController.setLocalBoundingBox(corner, scale);
|
||||
_motionState->setBoundingBox(corner, scale);
|
||||
}
|
||||
*/
|
||||
// virtual
|
||||
void Avatar::computeShapeInfo(ShapeInfo& shapeInfo) {
|
||||
const CapsuleShape& capsule = _skeletonModel.getBoundingShape();
|
||||
shapeInfo.setCapsuleY(capsule.getRadius(), capsule.getHalfHeight());
|
||||
shapeInfo.setOffset(_skeletonModel.getBoundingShapeOffset());
|
||||
}
|
||||
|
||||
// virtual
|
||||
void Avatar::rebuildSkeletonBody() {
|
||||
DependencyManager::get<AvatarManager>()->updateAvatarPhysicsShape(getSessionUUID());
|
||||
}
|
||||
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
#include <QtCore/QUuid>
|
||||
|
||||
#include <AvatarData.h>
|
||||
#include <ShapeInfo.h>
|
||||
|
||||
#include "Hand.h"
|
||||
#include "Head.h"
|
||||
#include "InterfaceConfig.h"
|
||||
#include "Recorder.h"
|
||||
#include "SkeletonModel.h"
|
||||
#include "world.h"
|
||||
|
||||
|
@ -55,6 +55,7 @@ enum ScreenTintLayer {
|
|||
NUM_SCREEN_TINT_LAYERS
|
||||
};
|
||||
|
||||
class AvatarMotionState;
|
||||
class Texture;
|
||||
|
||||
class Avatar : public AvatarData {
|
||||
|
@ -146,9 +147,9 @@ public:
|
|||
|
||||
Q_INVOKABLE glm::vec3 getNeckPosition() const;
|
||||
|
||||
Q_INVOKABLE glm::vec3 getAcceleration() const { return _acceleration; }
|
||||
Q_INVOKABLE glm::vec3 getAngularVelocity() const { return _angularVelocity; }
|
||||
Q_INVOKABLE glm::vec3 getAngularAcceleration() const { return _angularAcceleration; }
|
||||
Q_INVOKABLE const glm::vec3& getAcceleration() const { return _acceleration; }
|
||||
Q_INVOKABLE const glm::vec3& getAngularVelocity() const { return _angularVelocity; }
|
||||
Q_INVOKABLE const glm::vec3& getAngularAcceleration() const { return _angularAcceleration; }
|
||||
|
||||
|
||||
/// Scales a world space position vector relative to the avatar position and scale
|
||||
|
@ -164,6 +165,10 @@ public:
|
|||
|
||||
virtual void rebuildSkeletonBody();
|
||||
|
||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo);
|
||||
|
||||
friend class AvatarManager;
|
||||
|
||||
signals:
|
||||
void collisionWithAvatar(const QUuid& myUUID, const QUuid& theirUUID, const CollisionInfo& collision);
|
||||
|
||||
|
@ -231,7 +236,7 @@ private:
|
|||
|
||||
int _voiceSphereID;
|
||||
|
||||
//AvatarMotionState* _motionState = nullptr;
|
||||
AvatarMotionState* _motionState = nullptr;
|
||||
};
|
||||
|
||||
#endif // hifi_Avatar_h
|
||||
|
|
|
@ -92,22 +92,18 @@ void AvatarManager::updateOtherAvatars(float deltaTime) {
|
|||
// simulate avatars
|
||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||
while (avatarIterator != _avatarHash.end()) {
|
||||
AvatarSharedPointer sharedAvatar = avatarIterator.value();
|
||||
Avatar* avatar = reinterpret_cast<Avatar*>(sharedAvatar.data());
|
||||
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||
|
||||
if (sharedAvatar == _myAvatar || !avatar->isInitialized()) {
|
||||
if (avatar == _myAvatar || !avatar->isInitialized()) {
|
||||
// DO NOT update _myAvatar! Its update has already been done earlier in the main loop.
|
||||
// DO NOT update uninitialized Avatars
|
||||
// DO NOT update or fade out uninitialized Avatars
|
||||
++avatarIterator;
|
||||
continue;
|
||||
}
|
||||
if (!shouldKillAvatar(sharedAvatar)) {
|
||||
// this avatar's mixer is still around, go ahead and simulate it
|
||||
} else if (avatar->shouldDie()) {
|
||||
_avatarFades.push_back(avatarIterator.value());
|
||||
avatarIterator = _avatarHash.erase(avatarIterator);
|
||||
} else {
|
||||
avatar->simulate(deltaTime);
|
||||
++avatarIterator;
|
||||
} else {
|
||||
// the mixer that owned this avatar is gone, give it to the vector of fades and kill it
|
||||
avatarIterator = erase(avatarIterator);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -175,24 +171,52 @@ AvatarSharedPointer AvatarManager::newSharedAvatar() {
|
|||
return AvatarSharedPointer(new Avatar());
|
||||
}
|
||||
|
||||
AvatarHash::iterator AvatarManager::erase(const AvatarHash::iterator& iterator) {
|
||||
if (iterator.key() != MY_AVATAR_KEY) {
|
||||
if (reinterpret_cast<Avatar*>(iterator.value().data())->isInitialized()) {
|
||||
_avatarFades.push_back(iterator.value());
|
||||
// virtual
|
||||
AvatarSharedPointer AvatarManager::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
AvatarSharedPointer avatar = AvatarHashMap::addAvatar(sessionUUID, mixerWeakPointer);
|
||||
return avatar;
|
||||
}
|
||||
|
||||
// protected
|
||||
void AvatarManager::removeAvatarMotionState(Avatar* avatar) {
|
||||
AvatarMotionState* motionState= avatar->_motionState;
|
||||
if (motionState) {
|
||||
// clean up physics stuff
|
||||
motionState->clearObjectBackPointer();
|
||||
avatar->_motionState = nullptr;
|
||||
_avatarMotionStates.remove(motionState);
|
||||
_motionStatesToAdd.remove(motionState);
|
||||
_motionStatesToDelete.push_back(motionState);
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarManager::removeAvatar(const QUuid& sessionUUID) {
|
||||
AvatarHash::iterator avatarIterator = _avatarHash.find(sessionUUID);
|
||||
if (avatarIterator != _avatarHash.end()) {
|
||||
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||
if (avatar != _myAvatar && avatar->isInitialized()) {
|
||||
removeAvatarMotionState(avatar);
|
||||
|
||||
_avatarFades.push_back(avatarIterator.value());
|
||||
_avatarHash.erase(avatarIterator);
|
||||
}
|
||||
return AvatarHashMap::erase(iterator);
|
||||
} else {
|
||||
// never remove _myAvatar from the list
|
||||
AvatarHash::iterator returnIterator = iterator;
|
||||
return ++returnIterator;
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarManager::clearOtherAvatars() {
|
||||
// clear any avatars that came from an avatar-mixer
|
||||
AvatarHash::iterator removeAvatar = _avatarHash.begin();
|
||||
while (removeAvatar != _avatarHash.end()) {
|
||||
removeAvatar = erase(removeAvatar);
|
||||
AvatarHash::iterator avatarIterator = _avatarHash.begin();
|
||||
while (avatarIterator != _avatarHash.end()) {
|
||||
Avatar* avatar = reinterpret_cast<Avatar*>(avatarIterator.value().data());
|
||||
if (avatar == _myAvatar || !avatar->isInitialized()) {
|
||||
// don't remove myAvatar or uninitialized avatars from the list
|
||||
++avatarIterator;
|
||||
} else {
|
||||
removeAvatarMotionState(avatar);
|
||||
_avatarFades.push_back(avatarIterator.value());
|
||||
avatarIterator = _avatarHash.erase(avatarIterator);
|
||||
}
|
||||
}
|
||||
_myAvatar->clearLookAtTargetAvatar();
|
||||
}
|
||||
|
@ -215,3 +239,57 @@ QVector<AvatarManager::LocalLight> AvatarManager::getLocalLights() const {
|
|||
return _localLights;
|
||||
}
|
||||
|
||||
VectorOfMotionStates& AvatarManager::getObjectsToDelete() {
|
||||
_tempMotionStates.clear();
|
||||
_tempMotionStates.swap(_motionStatesToDelete);
|
||||
return _tempMotionStates;
|
||||
}
|
||||
|
||||
VectorOfMotionStates& AvatarManager::getObjectsToAdd() {
|
||||
_tempMotionStates.clear();
|
||||
|
||||
for (auto motionState : _motionStatesToAdd) {
|
||||
_tempMotionStates.push_back(motionState);
|
||||
}
|
||||
_motionStatesToAdd.clear();
|
||||
return _tempMotionStates;
|
||||
}
|
||||
|
||||
VectorOfMotionStates& AvatarManager::getObjectsToChange() {
|
||||
_tempMotionStates.clear();
|
||||
for (auto state : _avatarMotionStates) {
|
||||
if (state->_dirtyFlags > 0) {
|
||||
_tempMotionStates.push_back(state);
|
||||
}
|
||||
}
|
||||
return _tempMotionStates;
|
||||
}
|
||||
|
||||
void AvatarManager::handleOutgoingChanges(VectorOfMotionStates& motionStates) {
|
||||
// TODO: extract the MyAvatar results once we use a MotionState for it.
|
||||
}
|
||||
|
||||
void AvatarManager::handleCollisionEvents(CollisionEvents& collisionEvents) {
|
||||
// TODO: expose avatar collision events to JS
|
||||
}
|
||||
|
||||
void AvatarManager::updateAvatarPhysicsShape(const QUuid& id) {
|
||||
AvatarHash::iterator avatarItr = _avatarHash.find(id);
|
||||
if (avatarItr != _avatarHash.end()) {
|
||||
Avatar* avatar = static_cast<Avatar*>(avatarItr.value().data());
|
||||
AvatarMotionState* motionState = avatar->_motionState;
|
||||
if (motionState) {
|
||||
motionState->addDirtyFlags(EntityItem::DIRTY_SHAPE);
|
||||
} else {
|
||||
ShapeInfo shapeInfo;
|
||||
avatar->computeShapeInfo(shapeInfo);
|
||||
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||
if (shape) {
|
||||
AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
|
||||
avatar->_motionState = motionState;
|
||||
_motionStatesToAdd.insert(motionState);
|
||||
_avatarMotionStates.insert(motionState);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -17,8 +17,10 @@
|
|||
#include <QtCore/QSharedPointer>
|
||||
|
||||
#include <AvatarHashMap.h>
|
||||
#include <PhysicsEngine.h>
|
||||
|
||||
#include "Avatar.h"
|
||||
#include "AvatarMotionState.h"
|
||||
|
||||
class MyAvatar;
|
||||
|
||||
|
@ -51,6 +53,14 @@ public:
|
|||
|
||||
Q_INVOKABLE void setLocalLights(const QVector<AvatarManager::LocalLight>& localLights);
|
||||
Q_INVOKABLE QVector<AvatarManager::LocalLight> getLocalLights() const;
|
||||
|
||||
VectorOfMotionStates& getObjectsToDelete();
|
||||
VectorOfMotionStates& getObjectsToAdd();
|
||||
VectorOfMotionStates& getObjectsToChange();
|
||||
void handleOutgoingChanges(VectorOfMotionStates& motionStates);
|
||||
void handleCollisionEvents(CollisionEvents& collisionEvents);
|
||||
|
||||
void updateAvatarPhysicsShape(const QUuid& id);
|
||||
|
||||
public slots:
|
||||
void setShouldShowReceiveStats(bool shouldShowReceiveStats) { _shouldShowReceiveStats = shouldShowReceiveStats; }
|
||||
|
@ -62,10 +72,11 @@ private:
|
|||
void simulateAvatarFades(float deltaTime);
|
||||
void renderAvatarFades(const glm::vec3& cameraPosition, RenderArgs::RenderMode renderMode);
|
||||
|
||||
AvatarSharedPointer newSharedAvatar();
|
||||
|
||||
// virtual overrides
|
||||
AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
|
||||
virtual AvatarSharedPointer newSharedAvatar();
|
||||
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
void removeAvatarMotionState(Avatar* avatar);
|
||||
virtual void removeAvatar(const QUuid& sessionUUID);
|
||||
|
||||
QVector<AvatarSharedPointer> _avatarFades;
|
||||
QSharedPointer<MyAvatar> _myAvatar;
|
||||
|
@ -74,6 +85,11 @@ private:
|
|||
QVector<AvatarManager::LocalLight> _localLights;
|
||||
|
||||
bool _shouldShowReceiveStats = false;
|
||||
|
||||
SetOfAvatarMotionStates _avatarMotionStates;
|
||||
SetOfMotionStates _motionStatesToAdd;
|
||||
VectorOfMotionStates _motionStatesToDelete;
|
||||
VectorOfMotionStates _tempMotionStates;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(AvatarManager::LocalLight)
|
||||
|
|
160
interface/src/avatar/AvatarMotionState.cpp
Normal file
160
interface/src/avatar/AvatarMotionState.cpp
Normal file
|
@ -0,0 +1,160 @@
|
|||
//
|
||||
// AvatarMotionState.cpp
|
||||
// interface/src/avatar/
|
||||
//
|
||||
// Created by Andrew Meadows 2015.05.14
|
||||
// Copyright 2015 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 <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() {
|
||||
_avatar = nullptr;
|
||||
}
|
||||
|
||||
// virtual
|
||||
uint32_t AvatarMotionState::getAndClearIncomingDirtyFlags() {
|
||||
uint32_t dirtyFlags = 0;
|
||||
if (_body && _avatar) {
|
||||
dirtyFlags = _dirtyFlags;
|
||||
_dirtyFlags = 0;
|
||||
}
|
||||
return dirtyFlags;
|
||||
}
|
||||
|
||||
MotionType AvatarMotionState::computeObjectMotionType() const {
|
||||
// TODO?: support non-DYNAMIC motion for avatars? (e.g. when sitting)
|
||||
return MOTION_TYPE_DYNAMIC;
|
||||
}
|
||||
|
||||
// virtual and protected
|
||||
btCollisionShape* AvatarMotionState::computeNewShape() {
|
||||
if (_avatar) {
|
||||
ShapeInfo shapeInfo;
|
||||
_avatar->computeShapeInfo(shapeInfo);
|
||||
return getShapeManager()->getShape(shapeInfo);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// virtual
|
||||
bool AvatarMotionState::isMoving() const {
|
||||
return false;
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::getWorldTransform(btTransform& worldTrans) const {
|
||||
if (!_avatar) {
|
||||
return;
|
||||
}
|
||||
worldTrans.setOrigin(glmToBullet(getObjectPosition()));
|
||||
worldTrans.setRotation(glmToBullet(getObjectRotation()));
|
||||
if (_body) {
|
||||
_body->setLinearVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
_body->setAngularVelocity(glmToBullet(getObjectLinearVelocity()));
|
||||
}
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::setWorldTransform(const btTransform& worldTrans) {
|
||||
if (!_avatar) {
|
||||
return;
|
||||
}
|
||||
// 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()));
|
||||
}
|
||||
|
||||
// These pure virtual methods must be implemented for each MotionState type
|
||||
// and make it possible to implement more complicated methods in this base class.
|
||||
|
||||
// virtual
|
||||
float AvatarMotionState::getObjectRestitution() const {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
// virtual
|
||||
float AvatarMotionState::getObjectFriction() const {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
// virtual
|
||||
float AvatarMotionState::getObjectLinearDamping() const {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
// virtual
|
||||
float AvatarMotionState::getObjectAngularDamping() const {
|
||||
return 0.5f;
|
||||
}
|
||||
|
||||
// virtual
|
||||
glm::vec3 AvatarMotionState::getObjectPosition() const {
|
||||
return _avatar->getPosition();
|
||||
}
|
||||
|
||||
// virtual
|
||||
glm::quat AvatarMotionState::getObjectRotation() const {
|
||||
return _avatar->getOrientation();
|
||||
}
|
||||
|
||||
// virtual
|
||||
const glm::vec3& AvatarMotionState::getObjectLinearVelocity() const {
|
||||
return _avatar->getVelocity();
|
||||
}
|
||||
|
||||
// virtual
|
||||
const glm::vec3& AvatarMotionState::getObjectAngularVelocity() const {
|
||||
return _avatar->getAngularVelocity();
|
||||
}
|
||||
|
||||
// virtual
|
||||
const glm::vec3& AvatarMotionState::getObjectGravity() const {
|
||||
return _avatar->getAcceleration();
|
||||
}
|
||||
|
||||
// virtual
|
||||
const QUuid& AvatarMotionState::getObjectID() const {
|
||||
return _avatar->getSessionUUID();
|
||||
}
|
||||
|
||||
// virtual
|
||||
QUuid AvatarMotionState::getSimulatorID() const {
|
||||
return _avatar->getSessionUUID();
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::bump() {
|
||||
}
|
||||
|
||||
// virtual
|
||||
void AvatarMotionState::clearObjectBackPointer() {
|
||||
ObjectMotionState::clearObjectBackPointer();
|
||||
_avatar = nullptr;
|
||||
}
|
||||
|
||||
|
75
interface/src/avatar/AvatarMotionState.h
Normal file
75
interface/src/avatar/AvatarMotionState.h
Normal file
|
@ -0,0 +1,75 @@
|
|||
//
|
||||
// AvatarMotionState.h
|
||||
// interface/src/avatar/
|
||||
//
|
||||
// Created by Andrew Meadows 2015.05.14
|
||||
// Copyright 2015 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_AvatarMotionState_h
|
||||
#define hifi_AvatarMotionState_h
|
||||
|
||||
#include <QSet>
|
||||
|
||||
#include <ObjectMotionState.h>
|
||||
|
||||
class Avatar;
|
||||
|
||||
class AvatarMotionState : public ObjectMotionState {
|
||||
public:
|
||||
AvatarMotionState(Avatar* avatar, btCollisionShape* shape);
|
||||
~AvatarMotionState();
|
||||
|
||||
virtual MotionType getMotionType() const { return _motionType; }
|
||||
|
||||
virtual uint32_t getAndClearIncomingDirtyFlags();
|
||||
|
||||
virtual MotionType computeObjectMotionType() const;
|
||||
|
||||
virtual bool isMoving() const;
|
||||
|
||||
// this relays incoming position/rotation to the RigidBody
|
||||
virtual void getWorldTransform(btTransform& worldTrans) const;
|
||||
|
||||
// this relays outgoing position/rotation to the EntityItem
|
||||
virtual void setWorldTransform(const btTransform& worldTrans);
|
||||
|
||||
|
||||
// These pure virtual methods must be implemented for each MotionState type
|
||||
// and make it possible to implement more complicated methods in this base class.
|
||||
|
||||
virtual float getObjectRestitution() const;
|
||||
virtual float getObjectFriction() const;
|
||||
virtual float getObjectLinearDamping() const;
|
||||
virtual float getObjectAngularDamping() const;
|
||||
|
||||
virtual glm::vec3 getObjectPosition() const;
|
||||
virtual glm::quat getObjectRotation() const;
|
||||
virtual const glm::vec3& getObjectLinearVelocity() const;
|
||||
virtual const glm::vec3& getObjectAngularVelocity() const;
|
||||
virtual const glm::vec3& getObjectGravity() const;
|
||||
|
||||
virtual const QUuid& getObjectID() const;
|
||||
|
||||
virtual QUuid getSimulatorID() const;
|
||||
virtual void bump();
|
||||
|
||||
void setBoundingBox(const glm::vec3& corner, const glm::vec3& diagonal);
|
||||
|
||||
void addDirtyFlags(uint32_t flags) { _dirtyFlags |= flags; }
|
||||
|
||||
friend class AvatarManager;
|
||||
|
||||
protected:
|
||||
virtual btCollisionShape* computeNewShape();
|
||||
virtual void clearObjectBackPointer();
|
||||
Avatar* _avatar;
|
||||
uint32_t _dirtyFlags;
|
||||
};
|
||||
|
||||
typedef QSet<AvatarMotionState*> SetOfAvatarMotionStates;
|
||||
|
||||
#endif // hifi_AvatarMotionState_h
|
|
@ -30,7 +30,7 @@ ModelReferential::ModelReferential(Referential* referential, EntityTree* tree, A
|
|||
return;
|
||||
}
|
||||
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
if (item != NULL) {
|
||||
_lastRefDimension = item->getDimensions();
|
||||
_refRotation = item->getRotation();
|
||||
|
@ -44,7 +44,7 @@ ModelReferential::ModelReferential(const QUuid& entityID, EntityTree* tree, Avat
|
|||
_entityID(entityID),
|
||||
_tree(tree)
|
||||
{
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
if (!isValid() || item == NULL) {
|
||||
qCDebug(interfaceapp) << "ModelReferential::constructor(): Not Valid";
|
||||
_isValid = false;
|
||||
|
@ -61,7 +61,7 @@ ModelReferential::ModelReferential(const QUuid& entityID, EntityTree* tree, Avat
|
|||
}
|
||||
|
||||
void ModelReferential::update() {
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
if (!isValid() || item == NULL || _avatar == NULL) {
|
||||
return;
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ JointReferential::JointReferential(Referential* referential, EntityTree* tree, A
|
|||
return;
|
||||
}
|
||||
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
const Model* model = getModel(item);
|
||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||
_lastRefDimension = item->getDimensions();
|
||||
|
@ -120,7 +120,7 @@ JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, E
|
|||
_jointIndex(jointIndex)
|
||||
{
|
||||
_type = JOINT;
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
const Model* model = getModel(item);
|
||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||
qCDebug(interfaceapp) << "JointReferential::constructor(): Not Valid";
|
||||
|
@ -139,7 +139,7 @@ JointReferential::JointReferential(uint32_t jointIndex, const QUuid& entityID, E
|
|||
}
|
||||
|
||||
void JointReferential::update() {
|
||||
const EntityItem* item = _tree->findEntityByID(_entityID);
|
||||
EntityItemPointer item = _tree->findEntityByID(_entityID);
|
||||
const Model* model = getModel(item);
|
||||
if (!isValid() || model == NULL || _jointIndex >= (uint32_t)(model->getJointStateCount())) {
|
||||
return;
|
||||
|
@ -163,7 +163,7 @@ void JointReferential::update() {
|
|||
}
|
||||
}
|
||||
|
||||
const Model* JointReferential::getModel(const EntityItem* item) {
|
||||
const Model* JointReferential::getModel(EntityItemPointer item) {
|
||||
EntityItemFBXService* fbxService = _tree->getFBXService();
|
||||
if (item != NULL && fbxService != NULL) {
|
||||
return fbxService->getModelForEntityItem(item);
|
||||
|
|
|
@ -38,7 +38,7 @@ public:
|
|||
virtual void update();
|
||||
|
||||
protected:
|
||||
const Model* getModel(const EntityItem* item);
|
||||
const Model* getModel(EntityItemPointer item);
|
||||
virtual int packExtraData(unsigned char* destinationBuffer) const;
|
||||
virtual int unpackExtraData(const unsigned char* sourceBuffer, int size);
|
||||
|
||||
|
|
|
@ -41,6 +41,7 @@ SkeletonModel::SkeletonModel(Avatar* owningAvatar, QObject* parent) :
|
|||
_headClipDistance(DEFAULT_NEAR_CLIP)
|
||||
{
|
||||
assert(_owningAvatar);
|
||||
_enableShapes = true;
|
||||
}
|
||||
|
||||
SkeletonModel::~SkeletonModel() {
|
||||
|
|
|
@ -11,8 +11,6 @@
|
|||
|
||||
#include <GlowEffect.h>
|
||||
|
||||
#include "../../Menu.h"
|
||||
|
||||
#include "ModelOverlay.h"
|
||||
|
||||
ModelOverlay::ModelOverlay()
|
||||
|
|
|
@ -69,6 +69,7 @@ const quint32 AVATAR_MOTION_DEFAULTS =
|
|||
const quint32 AVATAR_MOTION_SCRIPTABLE_BITS =
|
||||
AVATAR_MOTION_SCRIPTED_MOTOR_ENABLED;
|
||||
|
||||
const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND;
|
||||
|
||||
// Bitset of state flags - we store the key state, hand state, faceshift, chat circling, and existance of
|
||||
// referential data in this bit set. The hand state is an octal, but is split into two sections to maintain
|
||||
|
@ -290,7 +291,6 @@ public:
|
|||
QString getSkeletonModelURLFromScript() const { return _skeletonModelURL.toString(); }
|
||||
void setSkeletonModelURLFromScript(const QString& skeletonModelString) { setSkeletonModelURL(QUrl(skeletonModelString)); }
|
||||
|
||||
Node* getOwningAvatarMixer() { return _owningAvatarMixer.data(); }
|
||||
void setOwningAvatarMixer(const QWeakPointer<Node>& owningAvatarMixer) { _owningAvatarMixer = owningAvatarMixer; }
|
||||
|
||||
const AABox& getLocalAABox() const { return _localAABox; }
|
||||
|
@ -301,8 +301,10 @@ public:
|
|||
int getReceiveRate() const;
|
||||
|
||||
void setVelocity(const glm::vec3 velocity) { _velocity = velocity; }
|
||||
Q_INVOKABLE glm::vec3 getVelocity() const { return _velocity; }
|
||||
glm::vec3 getTargetVelocity() const { return _targetVelocity; }
|
||||
Q_INVOKABLE const glm::vec3& getVelocity() const { return _velocity; }
|
||||
const glm::vec3& getTargetVelocity() const { return _targetVelocity; }
|
||||
|
||||
bool shouldDie() const { return _owningAvatarMixer.isNull() || getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS; }
|
||||
|
||||
public slots:
|
||||
void sendAvatarDataPacket();
|
||||
|
|
|
@ -20,19 +20,6 @@ AvatarHashMap::AvatarHashMap() {
|
|||
connect(DependencyManager::get<NodeList>().data(), &NodeList::uuidChanged, this, &AvatarHashMap::sessionUUIDChanged);
|
||||
}
|
||||
|
||||
|
||||
AvatarHash::iterator AvatarHashMap::erase(const AvatarHash::iterator& iterator) {
|
||||
qCDebug(avatars) << "Removing Avatar with UUID" << iterator.key() << "from AvatarHashMap.";
|
||||
return _avatarHash.erase(iterator);
|
||||
}
|
||||
|
||||
const qint64 AVATAR_SILENCE_THRESHOLD_USECS = 5 * USECS_PER_SECOND;
|
||||
|
||||
bool AvatarHashMap::shouldKillAvatar(const AvatarSharedPointer& sharedAvatar) {
|
||||
return (sharedAvatar->getOwningAvatarMixer() == NULL
|
||||
|| sharedAvatar->getUsecsSinceLastUpdate() > AVATAR_SILENCE_THRESHOLD_USECS);
|
||||
}
|
||||
|
||||
void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
switch (packetTypeForPacket(datagram)) {
|
||||
case PacketTypeBulkAvatarData:
|
||||
|
@ -52,10 +39,6 @@ void AvatarHashMap::processAvatarMixerDatagram(const QByteArray& datagram, const
|
|||
}
|
||||
}
|
||||
|
||||
bool AvatarHashMap::containsAvatarWithDisplayName(const QString& displayName) {
|
||||
return !avatarWithDisplayName(displayName).isNull();
|
||||
}
|
||||
|
||||
bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range) {
|
||||
foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) {
|
||||
glm::vec3 avatarPosition = sharedAvatar->getPosition();
|
||||
|
@ -67,45 +50,19 @@ bool AvatarHashMap::isAvatarInRange(const glm::vec3& position, const float range
|
|||
return false;
|
||||
}
|
||||
|
||||
AvatarWeakPointer AvatarHashMap::avatarWithDisplayName(const QString& displayName) {
|
||||
foreach(const AvatarSharedPointer& sharedAvatar, _avatarHash) {
|
||||
if (sharedAvatar->getDisplayName() == displayName) {
|
||||
// this is a match
|
||||
// check if this avatar should still be around
|
||||
if (!shouldKillAvatar(sharedAvatar)) {
|
||||
// we have a match, return the AvatarData
|
||||
return sharedAvatar;
|
||||
} else {
|
||||
// we should remove this avatar, but we might not be on a thread that is allowed
|
||||
// so we just return NULL to the caller
|
||||
return AvatarWeakPointer();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return AvatarWeakPointer();
|
||||
}
|
||||
|
||||
AvatarSharedPointer AvatarHashMap::newSharedAvatar() {
|
||||
return AvatarSharedPointer(new AvatarData());
|
||||
}
|
||||
|
||||
AvatarSharedPointer AvatarHashMap::matchingOrNewAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
AvatarSharedPointer matchingAvatar = _avatarHash.value(sessionUUID);
|
||||
|
||||
if (!matchingAvatar) {
|
||||
// insert the new avatar into our hash
|
||||
matchingAvatar = newSharedAvatar();
|
||||
|
||||
qCDebug(avatars) << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarHashMap.";
|
||||
|
||||
matchingAvatar->setSessionUUID(sessionUUID);
|
||||
matchingAvatar->setOwningAvatarMixer(mixerWeakPointer);
|
||||
|
||||
_avatarHash.insert(sessionUUID, matchingAvatar);
|
||||
}
|
||||
|
||||
return matchingAvatar;
|
||||
AvatarSharedPointer AvatarHashMap::addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer) {
|
||||
qCDebug(avatars) << "Adding avatar with sessionUUID " << sessionUUID << "to AvatarHashMap.";
|
||||
|
||||
AvatarSharedPointer avatar = newSharedAvatar();
|
||||
avatar->setSessionUUID(sessionUUID);
|
||||
avatar->setOwningAvatarMixer(mixerWeakPointer);
|
||||
_avatarHash.insert(sessionUUID, avatar);
|
||||
|
||||
return avatar;
|
||||
}
|
||||
|
||||
void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QWeakPointer<Node> &mixerWeakPointer) {
|
||||
|
@ -118,10 +75,13 @@ void AvatarHashMap::processAvatarDataPacket(const QByteArray &datagram, const QW
|
|||
bytesRead += NUM_BYTES_RFC4122_UUID;
|
||||
|
||||
if (sessionUUID != _lastOwnerSessionUUID) {
|
||||
AvatarSharedPointer matchingAvatarData = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
||||
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||
if (!avatar) {
|
||||
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||
}
|
||||
|
||||
// have the matching (or new) avatar parse the data from the packet
|
||||
bytesRead += matchingAvatarData->parseDataAtOffset(datagram, bytesRead);
|
||||
bytesRead += avatar->parseDataAtOffset(datagram, bytesRead);
|
||||
} else {
|
||||
// create a dummy AvatarData class to throw this data on the ground
|
||||
AvatarData dummyData;
|
||||
|
@ -145,24 +105,24 @@ void AvatarHashMap::processAvatarIdentityPacket(const QByteArray &packet, const
|
|||
identityStream >> sessionUUID >> faceMeshURL >> skeletonURL >> attachmentData >> displayName;
|
||||
|
||||
// mesh URL for a UUID, find avatar in our list
|
||||
AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
||||
if (matchingAvatar) {
|
||||
|
||||
if (matchingAvatar->getFaceModelURL() != faceMeshURL) {
|
||||
matchingAvatar->setFaceModelURL(faceMeshURL);
|
||||
}
|
||||
|
||||
if (matchingAvatar->getSkeletonModelURL() != skeletonURL) {
|
||||
matchingAvatar->setSkeletonModelURL(skeletonURL);
|
||||
}
|
||||
|
||||
if (matchingAvatar->getAttachmentData() != attachmentData) {
|
||||
matchingAvatar->setAttachmentData(attachmentData);
|
||||
}
|
||||
|
||||
if (matchingAvatar->getDisplayName() != displayName) {
|
||||
matchingAvatar->setDisplayName(displayName);
|
||||
}
|
||||
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||
if (!avatar) {
|
||||
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||
}
|
||||
if (avatar->getFaceModelURL() != faceMeshURL) {
|
||||
avatar->setFaceModelURL(faceMeshURL);
|
||||
}
|
||||
|
||||
if (avatar->getSkeletonModelURL() != skeletonURL) {
|
||||
avatar->setSkeletonModelURL(skeletonURL);
|
||||
}
|
||||
|
||||
if (avatar->getAttachmentData() != attachmentData) {
|
||||
avatar->setAttachmentData(attachmentData);
|
||||
}
|
||||
|
||||
if (avatar->getDisplayName() != displayName) {
|
||||
avatar->setDisplayName(displayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -171,24 +131,25 @@ void AvatarHashMap::processAvatarBillboardPacket(const QByteArray& packet, const
|
|||
int headerSize = numBytesForPacketHeader(packet);
|
||||
QUuid sessionUUID = QUuid::fromRfc4122(QByteArray::fromRawData(packet.constData() + headerSize, NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
AvatarSharedPointer matchingAvatar = matchingOrNewAvatar(sessionUUID, mixerWeakPointer);
|
||||
if (matchingAvatar) {
|
||||
QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID);
|
||||
if (matchingAvatar->getBillboard() != billboard) {
|
||||
matchingAvatar->setBillboard(billboard);
|
||||
}
|
||||
AvatarSharedPointer avatar = _avatarHash.value(sessionUUID);
|
||||
if (!avatar) {
|
||||
avatar = addAvatar(sessionUUID, mixerWeakPointer);
|
||||
}
|
||||
|
||||
QByteArray billboard = packet.mid(headerSize + NUM_BYTES_RFC4122_UUID);
|
||||
if (avatar->getBillboard() != billboard) {
|
||||
avatar->setBillboard(billboard);
|
||||
}
|
||||
}
|
||||
|
||||
void AvatarHashMap::processKillAvatar(const QByteArray& datagram) {
|
||||
// read the node id
|
||||
QUuid sessionUUID = QUuid::fromRfc4122(datagram.mid(numBytesForPacketHeader(datagram), NUM_BYTES_RFC4122_UUID));
|
||||
|
||||
// remove the avatar with that UUID from our hash, if it exists
|
||||
AvatarHash::iterator matchedAvatar = _avatarHash.find(sessionUUID);
|
||||
if (matchedAvatar != _avatarHash.end()) {
|
||||
erase(matchedAvatar);
|
||||
}
|
||||
removeAvatar(sessionUUID);
|
||||
}
|
||||
|
||||
void AvatarHashMap::removeAvatar(const QUuid& sessionUUID) {
|
||||
_avatarHash.remove(sessionUUID);
|
||||
}
|
||||
|
||||
void AvatarHashMap::sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID) {
|
||||
|
|
|
@ -36,28 +36,26 @@ public:
|
|||
|
||||
public slots:
|
||||
void processAvatarMixerDatagram(const QByteArray& datagram, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
bool containsAvatarWithDisplayName(const QString& displayName);
|
||||
bool isAvatarInRange(const glm::vec3 & position, const float range);
|
||||
AvatarWeakPointer avatarWithDisplayName(const QString& displayname);
|
||||
|
||||
private slots:
|
||||
void sessionUUIDChanged(const QUuid& sessionUUID, const QUuid& oldUUID);
|
||||
|
||||
protected:
|
||||
AvatarHashMap();
|
||||
virtual AvatarHash::iterator erase(const AvatarHash::iterator& iterator);
|
||||
|
||||
bool shouldKillAvatar(const AvatarSharedPointer& sharedAvatar);
|
||||
|
||||
virtual AvatarSharedPointer newSharedAvatar();
|
||||
AvatarSharedPointer matchingOrNewAvatar(const QUuid& nodeUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
virtual AvatarSharedPointer addAvatar(const QUuid& sessionUUID, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
virtual void removeAvatar(const QUuid& sessionUUID);
|
||||
|
||||
AvatarHash _avatarHash;
|
||||
|
||||
private:
|
||||
void processAvatarDataPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
void processAvatarIdentityPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
void processAvatarBillboardPacket(const QByteArray& packet, const QWeakPointer<Node>& mixerWeakPointer);
|
||||
void processKillAvatar(const QByteArray& datagram);
|
||||
|
||||
AvatarHash _avatarHash;
|
||||
QUuid _lastOwnerSessionUUID;
|
||||
};
|
||||
|
||||
|
|
|
@ -138,7 +138,7 @@ void EntityTreeRenderer::errorInLoadingScript(const QUrl& url) {
|
|||
}
|
||||
|
||||
QScriptValue EntityTreeRenderer::loadEntityScript(const EntityItemID& entityItemID, bool isPreload) {
|
||||
EntityItem* entity = static_cast<EntityTree*>(_tree)->findEntityByEntityItemID(entityItemID);
|
||||
EntityItemPointer entity = static_cast<EntityTree*>(_tree)->findEntityByEntityItemID(entityItemID);
|
||||
return loadEntityScript(entity, isPreload);
|
||||
}
|
||||
|
||||
|
@ -190,7 +190,7 @@ QString EntityTreeRenderer::loadScriptContents(const QString& scriptMaybeURLorTe
|
|||
}
|
||||
|
||||
|
||||
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItem* entity, bool isPreload) {
|
||||
QScriptValue EntityTreeRenderer::loadEntityScript(EntityItemPointer entity, bool isPreload) {
|
||||
if (_shuttingDown) {
|
||||
return QScriptValue(); // since we're shutting down, we don't load any more scripts
|
||||
}
|
||||
|
@ -324,7 +324,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
|
||||
if (avatarPosition != _lastAvatarPosition) {
|
||||
float radius = 1.0f; // for now, assume 1 meter radius
|
||||
QVector<const EntityItem*> foundEntities;
|
||||
QVector<EntityItemPointer> foundEntities;
|
||||
QVector<EntityItemID> entitiesContainingAvatar;
|
||||
|
||||
// find the entities near us
|
||||
|
@ -332,7 +332,7 @@ void EntityTreeRenderer::checkEnterLeaveEntities() {
|
|||
static_cast<EntityTree*>(_tree)->findEntities(avatarPosition, radius, foundEntities);
|
||||
|
||||
// create a list of entities that actually contain the avatar's position
|
||||
foreach(const EntityItem* entity, foundEntities) {
|
||||
foreach(EntityItemPointer entity, foundEntities) {
|
||||
if (entity->contains(avatarPosition)) {
|
||||
entitiesContainingAvatar << entity->getEntityItemID();
|
||||
}
|
||||
|
@ -517,12 +517,12 @@ void EntityTreeRenderer::render(RenderArgs::RenderMode renderMode,
|
|||
deleteReleasedModels(); // seems like as good as any other place to do some memory cleanup
|
||||
}
|
||||
|
||||
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem* entityItem) {
|
||||
const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(EntityItemPointer entityItem) {
|
||||
const FBXGeometry* result = NULL;
|
||||
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
assert(modelEntityItem); // we need this!!!
|
||||
Model* model = modelEntityItem->getModel(this);
|
||||
if (model) {
|
||||
|
@ -532,23 +532,23 @@ const FBXGeometry* EntityTreeRenderer::getGeometryForEntity(const EntityItem* en
|
|||
return result;
|
||||
}
|
||||
|
||||
const Model* EntityTreeRenderer::getModelForEntityItem(const EntityItem* entityItem) {
|
||||
const Model* EntityTreeRenderer::getModelForEntityItem(EntityItemPointer entityItem) {
|
||||
const Model* result = NULL;
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
result = modelEntityItem->getModel(this);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(const EntityItem* entityItem) {
|
||||
const FBXGeometry* EntityTreeRenderer::getCollisionGeometryForEntity(EntityItemPointer entityItem) {
|
||||
const FBXGeometry* result = NULL;
|
||||
|
||||
if (entityItem->getType() == EntityTypes::Model) {
|
||||
const RenderableModelEntityItem* constModelEntityItem = dynamic_cast<const RenderableModelEntityItem*>(entityItem);
|
||||
if (constModelEntityItem->hasCompoundShapeURL()) {
|
||||
RenderableModelEntityItem* modelEntityItem = const_cast<RenderableModelEntityItem*>(constModelEntityItem);
|
||||
std::shared_ptr<RenderableModelEntityItem> modelEntityItem =
|
||||
std::dynamic_pointer_cast<RenderableModelEntityItem>(entityItem);
|
||||
if (modelEntityItem->hasCompoundShapeURL()) {
|
||||
Model* model = modelEntityItem->getModel(this);
|
||||
if (model) {
|
||||
const QSharedPointer<NetworkGeometry> collisionNetworkGeometry = model->getCollisionGeometry();
|
||||
|
@ -615,7 +615,7 @@ void EntityTreeRenderer::renderElementProxy(EntityTreeElement* entityTreeElement
|
|||
}
|
||||
}
|
||||
|
||||
void EntityTreeRenderer::renderProxies(const EntityItem* entity, RenderArgs* args) {
|
||||
void EntityTreeRenderer::renderProxies(EntityItemPointer entity, RenderArgs* args) {
|
||||
bool isShadowMode = args->_renderMode == RenderArgs::SHADOW_RENDER_MODE;
|
||||
if (!isShadowMode && _displayModelBounds) {
|
||||
PerformanceTimer perfTimer("renderProxies");
|
||||
|
@ -674,7 +674,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
// we need to iterate the actual entityItems of the element
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
|
||||
QList<EntityItem*>& entityItems = entityTreeElement->getEntities();
|
||||
EntityItems& entityItems = entityTreeElement->getEntities();
|
||||
|
||||
|
||||
uint16_t numberOfEntities = entityItems.size();
|
||||
|
@ -686,7 +686,7 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
}
|
||||
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
EntityItem* entityItem = entityItems[i];
|
||||
EntityItemPointer entityItem = entityItems[i];
|
||||
|
||||
if (entityItem->isVisible()) {
|
||||
|
||||
|
@ -696,17 +696,17 @@ void EntityTreeRenderer::renderElement(OctreeElement* element, RenderArgs* args)
|
|||
float entityVolumeEstimate = entityItem->getVolumeEstimate();
|
||||
if (entityVolumeEstimate < _bestZoneVolume) {
|
||||
_bestZoneVolume = entityVolumeEstimate;
|
||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||
} else if (entityVolumeEstimate == _bestZoneVolume) {
|
||||
if (!_bestZone) {
|
||||
_bestZoneVolume = entityVolumeEstimate;
|
||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||
} else {
|
||||
// in the case of the volume being equal, we will use the
|
||||
// EntityItemID to deterministically pick one entity over the other
|
||||
if (entityItem->getEntityItemID() < _bestZone->getEntityItemID()) {
|
||||
_bestZoneVolume = entityVolumeEstimate;
|
||||
_bestZone = dynamic_cast<const ZoneEntityItem*>(entityItem);
|
||||
_bestZone = std::dynamic_pointer_cast<ZoneEntityItem>(entityItem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -835,7 +835,7 @@ RayToEntityIntersectionResult EntityTreeRenderer::findRayIntersectionWorker(cons
|
|||
EntityTree* entityTree = static_cast<EntityTree*>(_tree);
|
||||
|
||||
OctreeElement* element;
|
||||
EntityItem* intersectedEntity = NULL;
|
||||
EntityItemPointer intersectedEntity = NULL;
|
||||
result.intersects = entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||
precisionPicking);
|
||||
|
@ -1110,7 +1110,7 @@ void EntityTreeRenderer::changingEntityID(const EntityItemID& oldEntityID, const
|
|||
}
|
||||
|
||||
void EntityTreeRenderer::playEntityCollisionSound(const QUuid& myNodeID, EntityTree* entityTree, const EntityItemID& id, const Collision& collision) {
|
||||
EntityItem* entity = entityTree->findEntityByEntityItemID(id);
|
||||
EntityItemPointer entity = entityTree->findEntityByEntityItemID(id);
|
||||
if (!entity) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -62,9 +62,9 @@ public:
|
|||
RenderArgs::RenderSide renderSide = RenderArgs::MONO,
|
||||
RenderArgs::DebugFlags renderDebugFlags = RenderArgs::RENDER_DEBUG_NONE);
|
||||
|
||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem);
|
||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem);
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem);
|
||||
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem);
|
||||
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem);
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem);
|
||||
|
||||
/// clears the tree
|
||||
virtual void clear();
|
||||
|
@ -130,7 +130,7 @@ private:
|
|||
void checkAndCallUnload(const EntityItemID& entityID);
|
||||
|
||||
QList<Model*> _releasedModels;
|
||||
void renderProxies(const EntityItem* entity, RenderArgs* args);
|
||||
void renderProxies(EntityItemPointer entity, RenderArgs* args);
|
||||
RayToEntityIntersectionResult findRayIntersectionWorker(const PickRay& ray, Octree::lockType lockType,
|
||||
bool precisionPicking);
|
||||
|
||||
|
@ -147,7 +147,7 @@ private:
|
|||
ScriptEngine* _entitiesScriptEngine;
|
||||
ScriptEngine* _sandboxScriptEngine;
|
||||
|
||||
QScriptValue loadEntityScript(EntityItem* entity, bool isPreload = false);
|
||||
QScriptValue loadEntityScript(EntityItemPointer entity, bool isPreload = false);
|
||||
QScriptValue loadEntityScript(const EntityItemID& entityItemID, bool isPreload = false);
|
||||
QScriptValue getPreviouslyLoadedEntityScript(const EntityItemID& entityItemID);
|
||||
QString loadScriptContents(const QString& scriptMaybeURLorText, bool& isURL, bool& isPending, QUrl& url);
|
||||
|
@ -173,7 +173,7 @@ private:
|
|||
QMultiMap<QUrl, EntityItemID> _waitingOnPreload;
|
||||
|
||||
bool _hasPreviousZone = false;
|
||||
const ZoneEntityItem* _bestZone;
|
||||
std::shared_ptr<ZoneEntityItem> _bestZone;
|
||||
float _bestZoneVolume;
|
||||
|
||||
glm::vec3 _previousKeyLightColor;
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
#include "RenderableBoxEntityItem.h"
|
||||
|
||||
EntityItem* RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableBoxEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableBoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableBoxEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableBoxEntityItem::render(RenderArgs* args) {
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
class RenderableBoxEntityItem : public BoxEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableBoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
BoxEntityItem(entityItemID, properties)
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "RenderableLightEntityItem.h"
|
||||
|
||||
EntityItem* RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableLightEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableLightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableLightEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableLightEntityItem::render(RenderArgs* args) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class RenderableLightEntityItem : public LightEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableLightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
LightEntityItem(entityItemID, properties)
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
|
||||
#include "RenderableLineEntityItem.h"
|
||||
|
||||
EntityItem* RenderableLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableLineEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableLineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableLineEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableLineEntityItem::render(RenderArgs* args) {
|
||||
|
@ -37,5 +37,6 @@ void RenderableLineEntityItem::render(RenderArgs* args) {
|
|||
glm::vec3& p2 = dimensions;
|
||||
DependencyManager::get<DeferredLightingEffect>()->renderLine(p1, p2, lineColor, lineColor);
|
||||
glPopMatrix();
|
||||
|
||||
RenderableDebugableEntityItem::render(this, args);
|
||||
};
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
class RenderableLineEntityItem : public LineEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableLineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
LineEntityItem(entityItemID, properties) { }
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
#include "EntitiesRendererLogging.h"
|
||||
#include "RenderableModelEntityItem.h"
|
||||
|
||||
EntityItem* RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableModelEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableModelEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
RenderableModelEntityItem::~RenderableModelEntityItem() {
|
||||
|
|
|
@ -23,7 +23,7 @@ class EntityTreeRenderer;
|
|||
|
||||
class RenderableModelEntityItem : public ModelEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
ModelEntityItem(entityItemID, properties),
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
|
||||
#include "RenderableParticleEffectEntityItem.h"
|
||||
|
||||
EntityItem* RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableParticleEffectEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableParticleEffectEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
RenderableParticleEffectEntityItem::RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class RenderableParticleEffectEntityItem : public ParticleEffectEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
RenderableParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
virtual void render(RenderArgs* args);
|
||||
|
||||
|
|
|
@ -19,8 +19,8 @@
|
|||
|
||||
#include "RenderableSphereEntityItem.h"
|
||||
|
||||
EntityItem* RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableSphereEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableSphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableSphereEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableSphereEntityItem::render(RenderArgs* args) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class RenderableSphereEntityItem : public SphereEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableSphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
SphereEntityItem(entityItemID, properties)
|
||||
|
|
|
@ -23,8 +23,8 @@
|
|||
|
||||
const int FIXED_FONT_POINT_SIZE = 40;
|
||||
|
||||
EntityItem* RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableTextEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableTextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableTextEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
void RenderableTextEntityItem::render(RenderArgs* args) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class RenderableTextEntityItem : public TextEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableTextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
TextEntityItem(entityItemID, properties)
|
||||
|
|
|
@ -28,8 +28,8 @@
|
|||
const float DPI = 30.47f;
|
||||
const float METERS_TO_INCHES = 39.3701f;
|
||||
|
||||
EntityItem* RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableWebEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableWebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableWebEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
RenderableWebEntityItem::RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -17,7 +17,7 @@ class OffscreenQmlSurface;
|
|||
|
||||
class RenderableWebEntityItem : public WebEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableWebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
~RenderableWebEntityItem();
|
||||
|
|
|
@ -16,8 +16,8 @@
|
|||
#include <GeometryCache.h>
|
||||
#include <PerfStat.h>
|
||||
|
||||
EntityItem* RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new RenderableZoneEntityItem(entityID, properties);
|
||||
EntityItemPointer RenderableZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new RenderableZoneEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
template<typename Lambda>
|
||||
|
|
|
@ -19,7 +19,7 @@ class NetworkGeometry;
|
|||
|
||||
class RenderableZoneEntityItem : public ZoneEntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
RenderableZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
ZoneEntityItem(entityItemID, properties),
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
#include "AddEntityOperator.h"
|
||||
|
||||
AddEntityOperator::AddEntityOperator(EntityTree* tree,
|
||||
EntityItem* newEntity) :
|
||||
EntityItemPointer newEntity) :
|
||||
_tree(tree),
|
||||
_newEntity(newEntity),
|
||||
_foundNew(false),
|
||||
|
|
|
@ -14,14 +14,14 @@
|
|||
|
||||
class AddEntityOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
AddEntityOperator(EntityTree* tree, EntityItem* newEntity);
|
||||
AddEntityOperator(EntityTree* tree, EntityItemPointer newEntity);
|
||||
|
||||
virtual bool preRecursion(OctreeElement* element);
|
||||
virtual bool postRecursion(OctreeElement* element);
|
||||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||
private:
|
||||
EntityTree* _tree;
|
||||
EntityItem* _newEntity;
|
||||
EntityItemPointer _newEntity;
|
||||
bool _foundNew;
|
||||
quint64 _changeTime;
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "EntityTreeElement.h"
|
||||
|
||||
|
||||
EntityItem* BoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = new BoxEntityItem(entityID, properties);
|
||||
EntityItemPointer BoxEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result { new BoxEntityItem(entityID, properties) };
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class BoxEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
BoxEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -92,7 +92,7 @@ bool DeleteEntityOperator::preRecursion(OctreeElement* element) {
|
|||
// If this is the element we're looking for, then ask it to remove the old entity
|
||||
// and we can stop searching.
|
||||
if (entityTreeElement == details.containingElement) {
|
||||
EntityItem* theEntity = details.entity;
|
||||
EntityItemPointer theEntity = details.entity;
|
||||
bool entityDeleted = entityTreeElement->removeEntityItem(theEntity); // remove it from the element
|
||||
assert(entityDeleted);
|
||||
_tree->setContainingElement(details.entity->getEntityItemID(), NULL); // update or id to element lookup
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
class EntityToDeleteDetails {
|
||||
public:
|
||||
EntityItem* entity;
|
||||
EntityItemPointer entity;
|
||||
AACube cube;
|
||||
EntityTreeElement* containingElement;
|
||||
};
|
||||
|
|
|
@ -78,7 +78,7 @@ QUuid EntityScriptingInterface::addEntity(const EntityItemProperties& properties
|
|||
bool success = true;
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForWrite();
|
||||
EntityItem* entity = _entityTree->addEntity(id, propertiesWithSimID);
|
||||
EntityItemPointer entity = _entityTree->addEntity(id, propertiesWithSimID);
|
||||
if (entity) {
|
||||
entity->setLastBroadcast(usecTimestampNow());
|
||||
// This Node is creating a new object. If it's in motion, set this Node as the simulator.
|
||||
|
@ -102,7 +102,8 @@ EntityItemProperties EntityScriptingInterface::getEntityProperties(QUuid identit
|
|||
EntityItemProperties results;
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
EntityItem* entity = const_cast<EntityItem*>(_entityTree->findEntityByEntityItemID(EntityItemID(identity)));
|
||||
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(EntityItemID(identity));
|
||||
|
||||
if (entity) {
|
||||
results = entity->getProperties();
|
||||
|
@ -137,7 +138,7 @@ QUuid EntityScriptingInterface::editEntity(QUuid id, const EntityItemProperties&
|
|||
|
||||
// make sure the properties has a type, so that the encode can know which properties to include
|
||||
if (properties.getType() == EntityTypes::Unknown) {
|
||||
EntityItem* entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
// we need to change the outgoing properties, so we make a copy, modify, and send.
|
||||
EntityItemProperties modifiedProperties = properties;
|
||||
|
@ -161,7 +162,7 @@ void EntityScriptingInterface::deleteEntity(QUuid id) {
|
|||
if (_entityTree) {
|
||||
_entityTree->lockForWrite();
|
||||
|
||||
EntityItem* entity = const_cast<EntityItem*>(_entityTree->findEntityByEntityItemID(entityID));
|
||||
EntityItemPointer entity = _entityTree->findEntityByEntityItemID(entityID);
|
||||
if (entity) {
|
||||
if (entity->getLocked()) {
|
||||
shouldDelete = false;
|
||||
|
@ -183,7 +184,7 @@ QUuid EntityScriptingInterface::findClosestEntity(const glm::vec3& center, float
|
|||
EntityItemID result;
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
const EntityItem* closestEntity = _entityTree->findClosestEntity(center, radius);
|
||||
EntityItemPointer closestEntity = _entityTree->findClosestEntity(center, radius);
|
||||
_entityTree->unlock();
|
||||
if (closestEntity) {
|
||||
result = closestEntity->getEntityItemID();
|
||||
|
@ -205,11 +206,11 @@ QVector<QUuid> EntityScriptingInterface::findEntities(const glm::vec3& center, f
|
|||
QVector<QUuid> result;
|
||||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
QVector<const EntityItem*> entities;
|
||||
QVector<EntityItemPointer> entities;
|
||||
_entityTree->findEntities(center, radius, entities);
|
||||
_entityTree->unlock();
|
||||
|
||||
foreach (const EntityItem* entity, entities) {
|
||||
foreach (EntityItemPointer entity, entities) {
|
||||
result << entity->getEntityItemID();
|
||||
}
|
||||
}
|
||||
|
@ -221,11 +222,11 @@ QVector<QUuid> EntityScriptingInterface::findEntitiesInBox(const glm::vec3& corn
|
|||
if (_entityTree) {
|
||||
_entityTree->lockForRead();
|
||||
AABox box(corner, dimensions);
|
||||
QVector<EntityItem*> entities;
|
||||
QVector<EntityItemPointer> entities;
|
||||
_entityTree->findEntities(box, entities);
|
||||
_entityTree->unlock();
|
||||
|
||||
foreach (const EntityItem* entity, entities) {
|
||||
foreach (EntityItemPointer entity, entities) {
|
||||
result << entity->getEntityItemID();
|
||||
}
|
||||
}
|
||||
|
@ -248,7 +249,7 @@ RayToEntityIntersectionResult EntityScriptingInterface::findRayIntersectionWorke
|
|||
RayToEntityIntersectionResult result;
|
||||
if (_entityTree) {
|
||||
OctreeElement* element;
|
||||
EntityItem* intersectedEntity = NULL;
|
||||
EntityItemPointer intersectedEntity = NULL;
|
||||
result.intersects = _entityTree->findRayIntersection(ray.origin, ray.direction, element, result.distance, result.face,
|
||||
(void**)&intersectedEntity, lockType, &result.accurate,
|
||||
precisionPicking);
|
||||
|
|
|
@ -39,7 +39,7 @@ public:
|
|||
float distance;
|
||||
BoxFace face;
|
||||
glm::vec3 intersection;
|
||||
EntityItem* entity;
|
||||
EntityItemPointer entity;
|
||||
};
|
||||
|
||||
Q_DECLARE_METATYPE(RayToEntityIntersectionResult)
|
||||
|
|
|
@ -38,22 +38,21 @@ void EntitySimulation::updateEntities() {
|
|||
}
|
||||
|
||||
void EntitySimulation::getEntitiesToDelete(VectorOfEntities& entitiesToDelete) {
|
||||
for (auto entityItr : _entitiesToDelete) {
|
||||
EntityItem* entity = &(*entityItr);
|
||||
|
||||
for (auto entity : _entitiesToDelete) {
|
||||
// this entity is still in its tree, so we insert into the external list
|
||||
entitiesToDelete.push_back(entity);
|
||||
++entityItr;
|
||||
}
|
||||
_entitiesToDelete.clear();
|
||||
}
|
||||
|
||||
void EntitySimulation::addEntityInternal(EntityItem* entity) {
|
||||
void EntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void EntitySimulation::changeEntityInternal(EntityItem* entity) {
|
||||
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||
_simpleKinematicEntities.insert(entity);
|
||||
} else {
|
||||
|
@ -68,7 +67,7 @@ void EntitySimulation::expireMortalEntities(const quint64& now) {
|
|||
_nextExpiry = quint64(-1);
|
||||
SetOfEntities::iterator itemItr = _mortalEntities.begin();
|
||||
while (itemItr != _mortalEntities.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
EntityItemPointer entity = *itemItr;
|
||||
quint64 expiry = entity->getExpiry();
|
||||
if (expiry < now) {
|
||||
_entitiesToDelete.insert(entity);
|
||||
|
@ -96,7 +95,7 @@ void EntitySimulation::callUpdateOnEntitiesThatNeedIt(const quint64& now) {
|
|||
PerformanceTimer perfTimer("updatingEntities");
|
||||
SetOfEntities::iterator itemItr = _entitiesToUpdate.begin();
|
||||
while (itemItr != _entitiesToUpdate.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
EntityItemPointer entity = *itemItr;
|
||||
// TODO: catch transition from needing update to not as a "change"
|
||||
// so we don't have to scan for it here.
|
||||
if (!entity->needsToCallUpdate()) {
|
||||
|
@ -117,7 +116,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
|||
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), (float)TREE_SCALE);
|
||||
SetOfEntities::iterator itemItr = _entitiesToSort.begin();
|
||||
while (itemItr != _entitiesToSort.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
EntityItemPointer entity = *itemItr;
|
||||
// check to see if this movement has sent the entity outside of the domain.
|
||||
AACube newCube = entity->getMaximumAACube();
|
||||
if (!domainBounds.touches(newCube)) {
|
||||
|
@ -145,7 +144,7 @@ void EntitySimulation::sortEntitiesThatMoved() {
|
|||
_entitiesToSort.clear();
|
||||
}
|
||||
|
||||
void EntitySimulation::addEntity(EntityItem* entity) {
|
||||
void EntitySimulation::addEntity(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
if (entity->isMortal()) {
|
||||
_mortalEntities.insert(entity);
|
||||
|
@ -167,7 +166,7 @@ void EntitySimulation::addEntity(EntityItem* entity) {
|
|||
entity->clearDirtyFlags();
|
||||
}
|
||||
|
||||
void EntitySimulation::removeEntity(EntityItem* entity) {
|
||||
void EntitySimulation::removeEntity(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
_entitiesToUpdate.remove(entity);
|
||||
_mortalEntities.remove(entity);
|
||||
|
@ -180,7 +179,7 @@ void EntitySimulation::removeEntity(EntityItem* entity) {
|
|||
entity->_simulated = false;
|
||||
}
|
||||
|
||||
void EntitySimulation::changeEntity(EntityItem* entity) {
|
||||
void EntitySimulation::changeEntity(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
if (!entity->_simulated) {
|
||||
// This entity was either never added to the simulation or has been removed
|
||||
|
@ -250,7 +249,7 @@ void EntitySimulation::clearEntities() {
|
|||
void EntitySimulation::moveSimpleKinematics(const quint64& now) {
|
||||
SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin();
|
||||
while (itemItr != _simpleKinematicEntities.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
EntityItemPointer entity = *itemItr;
|
||||
if (entity->isMoving() && !entity->getPhysicsInfo()) {
|
||||
entity->simulate(now);
|
||||
_entitiesToSort.insert(entity);
|
||||
|
|
|
@ -21,8 +21,8 @@
|
|||
#include "EntityItem.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
typedef QSet<EntityItem*> SetOfEntities;
|
||||
typedef QVector<EntityItem*> VectorOfEntities;
|
||||
typedef QSet<EntityItemPointer> SetOfEntities;
|
||||
typedef QVector<EntityItemPointer> VectorOfEntities;
|
||||
|
||||
// the EntitySimulation needs to know when these things change on an entity,
|
||||
// so it can sort EntityItem or relay its state to the PhysicsEngine.
|
||||
|
@ -59,16 +59,16 @@ public:
|
|||
protected: // these only called by the EntityTree?
|
||||
/// \param entity pointer to EntityItem to be added
|
||||
/// \sideeffect sets relevant backpointers in entity, but maybe later when appropriate data structures are locked
|
||||
void addEntity(EntityItem* entity);
|
||||
void addEntity(EntityItemPointer entity);
|
||||
|
||||
/// \param entity pointer to EntityItem to be removed
|
||||
/// \brief the actual removal may happen later when appropriate data structures are locked
|
||||
/// \sideeffect nulls relevant backpointers in entity
|
||||
void removeEntity(EntityItem* entity);
|
||||
void removeEntity(EntityItemPointer entity);
|
||||
|
||||
/// \param entity pointer to EntityItem to that may have changed in a way that would affect its simulation
|
||||
/// call this whenever an entity was changed from some EXTERNAL event (NOT by the EntitySimulation itself)
|
||||
void changeEntity(EntityItem* entity);
|
||||
void changeEntity(EntityItemPointer entity);
|
||||
|
||||
void clearEntities();
|
||||
|
||||
|
@ -88,9 +88,9 @@ protected:
|
|||
// These pure virtual methods are protected because they are not to be called will-nilly. The base class
|
||||
// calls them in the right places.
|
||||
virtual void updateEntitiesInternal(const quint64& now) = 0;
|
||||
virtual void addEntityInternal(EntityItem* entity);
|
||||
virtual void removeEntityInternal(EntityItem* entity) = 0;
|
||||
virtual void changeEntityInternal(EntityItem* entity);
|
||||
virtual void addEntityInternal(EntityItemPointer entity);
|
||||
virtual void removeEntityInternal(EntityItemPointer entity) = 0;
|
||||
virtual void changeEntityInternal(EntityItemPointer entity);
|
||||
virtual void clearEntitiesInternal() = 0;
|
||||
|
||||
void expireMortalEntities(const quint64& now);
|
||||
|
|
|
@ -75,7 +75,7 @@ bool EntityTree::handlesEditPacketType(PacketType packetType) const {
|
|||
}
|
||||
|
||||
/// Adds a new entity item to the tree
|
||||
void EntityTree::postAddEntity(EntityItem* entity) {
|
||||
void EntityTree::postAddEntity(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
// check to see if we need to simulate this entity..
|
||||
if (_simulation) {
|
||||
|
@ -94,7 +94,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
|||
return false;
|
||||
}
|
||||
|
||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
if (!existingEntity) {
|
||||
qCDebug(entities) << "UNEXPECTED!!!! don't call updateEntity() on entity items that don't exist. entityID=" << entityID;
|
||||
return false;
|
||||
|
@ -103,7 +103,7 @@ bool EntityTree::updateEntity(const EntityItemID& entityID, const EntityItemProp
|
|||
return updateEntityWithElement(existingEntity, properties, containingElement, senderNode);
|
||||
}
|
||||
|
||||
bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||
bool EntityTree::updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode) {
|
||||
EntityTreeElement* containingElement = getContainingElement(entity->getEntityItemID());
|
||||
if (!containingElement) {
|
||||
qCDebug(entities) << "UNEXPECTED!!!! EntityTree::updateEntity() entity-->element lookup failed!!! entityID="
|
||||
|
@ -113,7 +113,7 @@ bool EntityTree::updateEntity(EntityItem* entity, const EntityItemProperties& pr
|
|||
return updateEntityWithElement(entity, properties, containingElement, senderNode);
|
||||
}
|
||||
|
||||
bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemProperties& origProperties,
|
||||
bool EntityTree::updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& origProperties,
|
||||
EntityTreeElement* containingElement, const SharedNodePointer& senderNode) {
|
||||
EntityItemProperties properties = origProperties;
|
||||
|
||||
|
@ -220,8 +220,8 @@ bool EntityTree::updateEntityWithElement(EntityItem* entity, const EntityItemPro
|
|||
return true;
|
||||
}
|
||||
|
||||
EntityItem* EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = NULL;
|
||||
EntityItemPointer EntityTree::addEntity(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result = NULL;
|
||||
|
||||
if (getIsClient()) {
|
||||
// if our Node isn't allowed to create entities in this domain, don't try.
|
||||
|
@ -291,7 +291,7 @@ void EntityTree::deleteEntity(const EntityItemID& entityID, bool force, bool ign
|
|||
return;
|
||||
}
|
||||
|
||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
if (!existingEntity) {
|
||||
if (!ignoreWarnings) {
|
||||
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntity() on entity items that don't exist. "
|
||||
|
@ -328,7 +328,7 @@ void EntityTree::deleteEntities(QSet<EntityItemID> entityIDs, bool force, bool i
|
|||
continue;
|
||||
}
|
||||
|
||||
EntityItem* existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
EntityItemPointer existingEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
if (!existingEntity) {
|
||||
if (!ignoreWarnings) {
|
||||
qCDebug(entities) << "UNEXPECTED!!!! don't call EntityTree::deleteEntities() on entity items that don't exist. "
|
||||
|
@ -362,7 +362,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
|||
_simulation->lock();
|
||||
}
|
||||
foreach(const EntityToDeleteDetails& details, entities) {
|
||||
EntityItem* theEntity = details.entity;
|
||||
EntityItemPointer theEntity = details.entity;
|
||||
|
||||
if (getIsServer()) {
|
||||
// set up the deleted entities ID
|
||||
|
@ -374,8 +374,7 @@ void EntityTree::processRemovedEntities(const DeleteEntityOperator& theOperator)
|
|||
|
||||
if (_simulation) {
|
||||
_simulation->removeEntity(theEntity);
|
||||
}
|
||||
delete theEntity; // we can delete the entity immediately
|
||||
}
|
||||
}
|
||||
if (_simulation) {
|
||||
_simulation->unlock();
|
||||
|
@ -388,7 +387,7 @@ public:
|
|||
glm::vec3 position;
|
||||
float targetRadius;
|
||||
bool found;
|
||||
const EntityItem* closestEntity;
|
||||
EntityItemPointer closestEntity;
|
||||
float closestEntityDistance;
|
||||
};
|
||||
|
||||
|
@ -402,7 +401,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
|||
|
||||
// If this entityTreeElement contains the point, then search it...
|
||||
if (sphereIntersection) {
|
||||
const EntityItem* thisClosestEntity = entityTreeElement->getClosestEntity(args->position);
|
||||
EntityItemPointer thisClosestEntity = entityTreeElement->getClosestEntity(args->position);
|
||||
|
||||
// we may have gotten NULL back, meaning no entity was available
|
||||
if (thisClosestEntity) {
|
||||
|
@ -428,7 +427,7 @@ bool EntityTree::findNearPointOperation(OctreeElement* element, void* extraData)
|
|||
return false;
|
||||
}
|
||||
|
||||
const EntityItem* EntityTree::findClosestEntity(glm::vec3 position, float targetRadius) {
|
||||
EntityItemPointer EntityTree::findClosestEntity(glm::vec3 position, float targetRadius) {
|
||||
FindNearPointArgs args = { position, targetRadius, false, NULL, FLT_MAX };
|
||||
lockForRead();
|
||||
// NOTE: This should use recursion, since this is a spatial operation
|
||||
|
@ -441,7 +440,7 @@ class FindAllNearPointArgs {
|
|||
public:
|
||||
glm::vec3 position;
|
||||
float targetRadius;
|
||||
QVector<const EntityItem*> entities;
|
||||
QVector<EntityItemPointer> entities;
|
||||
};
|
||||
|
||||
|
||||
|
@ -462,8 +461,8 @@ bool EntityTree::findInSphereOperation(OctreeElement* element, void* extraData)
|
|||
}
|
||||
|
||||
// NOTE: assumes caller has handled locking
|
||||
void EntityTree::findEntities(const glm::vec3& center, float radius, QVector<const EntityItem*>& foundEntities) {
|
||||
FindAllNearPointArgs args = { center, radius, QVector<const EntityItem*>() };
|
||||
void EntityTree::findEntities(const glm::vec3& center, float radius, QVector<EntityItemPointer>& foundEntities) {
|
||||
FindAllNearPointArgs args = { center, radius, QVector<EntityItemPointer>() };
|
||||
// NOTE: This should use recursion, since this is a spatial operation
|
||||
recurseTreeWithOperation(findInSphereOperation, &args);
|
||||
|
||||
|
@ -478,7 +477,7 @@ public:
|
|||
}
|
||||
|
||||
AACube _cube;
|
||||
QVector<EntityItem*> _foundEntities;
|
||||
QVector<EntityItemPointer> _foundEntities;
|
||||
};
|
||||
|
||||
bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
||||
|
@ -492,7 +491,7 @@ bool EntityTree::findInCubeOperation(OctreeElement* element, void* extraData) {
|
|||
}
|
||||
|
||||
// NOTE: assumes caller has handled locking
|
||||
void EntityTree::findEntities(const AACube& cube, QVector<EntityItem*>& foundEntities) {
|
||||
void EntityTree::findEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities) {
|
||||
FindEntitiesInCubeArgs args(cube);
|
||||
// NOTE: This should use recursion, since this is a spatial operation
|
||||
recurseTreeWithOperation(findInCubeOperation, &args);
|
||||
|
@ -507,7 +506,7 @@ public:
|
|||
}
|
||||
|
||||
AABox _box;
|
||||
QVector<EntityItem*> _foundEntities;
|
||||
QVector<EntityItemPointer> _foundEntities;
|
||||
};
|
||||
|
||||
bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) {
|
||||
|
@ -521,7 +520,7 @@ bool EntityTree::findInBoxOperation(OctreeElement* element, void* extraData) {
|
|||
}
|
||||
|
||||
// NOTE: assumes caller has handled locking
|
||||
void EntityTree::findEntities(const AABox& box, QVector<EntityItem*>& foundEntities) {
|
||||
void EntityTree::findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities) {
|
||||
FindEntitiesInBoxArgs args(box);
|
||||
// NOTE: This should use recursion, since this is a spatial operation
|
||||
recurseTreeWithOperation(findInBoxOperation, &args);
|
||||
|
@ -529,13 +528,13 @@ void EntityTree::findEntities(const AABox& box, QVector<EntityItem*>& foundEntit
|
|||
foundEntities.swap(args._foundEntities);
|
||||
}
|
||||
|
||||
EntityItem* EntityTree::findEntityByID(const QUuid& id) {
|
||||
EntityItemPointer EntityTree::findEntityByID(const QUuid& id) {
|
||||
EntityItemID entityID(id);
|
||||
return findEntityByEntityItemID(entityID);
|
||||
}
|
||||
|
||||
EntityItem* EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /*const*/ {
|
||||
EntityItem* foundEntity = NULL;
|
||||
EntityItemPointer EntityTree::findEntityByEntityItemID(const EntityItemID& entityID) /*const*/ {
|
||||
EntityItemPointer foundEntity = NULL;
|
||||
EntityTreeElement* containingElement = getContainingElement(entityID);
|
||||
if (containingElement) {
|
||||
foundEntity = containingElement->getEntityWithEntityItemID(entityID);
|
||||
|
@ -571,7 +570,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
|||
// an existing entity... handle appropriately
|
||||
if (validEditPacket) {
|
||||
// search for the entity by EntityItemID
|
||||
EntityItem* existingEntity = findEntityByEntityItemID(entityItemID);
|
||||
EntityItemPointer existingEntity = findEntityByEntityItemID(entityItemID);
|
||||
if (existingEntity && packetType == PacketTypeEntityEdit) {
|
||||
// if the EntityItem exists, then update it
|
||||
if (wantEditLogging()) {
|
||||
|
@ -588,7 +587,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
|||
qCDebug(entities) << " properties:" << properties;
|
||||
}
|
||||
properties.setCreated(properties.getLastEdited());
|
||||
EntityItem* newEntity = addEntity(entityItemID, properties);
|
||||
EntityItemPointer newEntity = addEntity(entityItemID, properties);
|
||||
if (newEntity) {
|
||||
newEntity->markAsChangedOnServer();
|
||||
notifyNewlyCreatedEntity(*newEntity, senderNode);
|
||||
|
@ -604,7 +603,7 @@ int EntityTree::processEditPacketData(PacketType packetType, const unsigned char
|
|||
<< "] attempted to add an entity.";
|
||||
}
|
||||
} else {
|
||||
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity;
|
||||
qCDebug(entities) << "Add or Edit failed." << packetType << existingEntity.get();
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -652,7 +651,7 @@ void EntityTree::releaseSceneEncodeData(OctreeElementExtraEncodeData* extraEncod
|
|||
extraEncodeData->clear();
|
||||
}
|
||||
|
||||
void EntityTree::entityChanged(EntityItem* entity) {
|
||||
void EntityTree::entityChanged(EntityItemPointer entity) {
|
||||
if (_simulation) {
|
||||
_simulation->lock();
|
||||
_simulation->changeEntity(entity);
|
||||
|
@ -672,11 +671,12 @@ void EntityTree::update() {
|
|||
if (pendingDeletes.size() > 0) {
|
||||
// translate into list of ID's
|
||||
QSet<EntityItemID> idsToDelete;
|
||||
for (auto entityItr : pendingDeletes) {
|
||||
EntityItem* entity = &(*entityItr);
|
||||
|
||||
for (auto entity : pendingDeletes) {
|
||||
assert(!entity->getPhysicsInfo()); // TODO: Andrew to remove this after testing
|
||||
idsToDelete.insert(entity->getEntityItemID());
|
||||
}
|
||||
|
||||
// delete these things the roundabout way
|
||||
deleteEntities(idsToDelete, true);
|
||||
}
|
||||
|
@ -1004,7 +1004,7 @@ bool EntityTree::sendEntitiesOperation(OctreeElement* element, void* extraData)
|
|||
SendEntitiesOperationArgs* args = static_cast<SendEntitiesOperationArgs*>(extraData);
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
|
||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
||||
const EntityItems& entities = entityTreeElement->getEntities();
|
||||
for (int i = 0; i < entities.size(); i++) {
|
||||
EntityItemID newID(QUuid::createUuid());
|
||||
args->newEntityIDs->append(newID);
|
||||
|
@ -1056,7 +1056,7 @@ bool EntityTree::readFromMap(QVariantMap& map) {
|
|||
entityItemID = EntityItemID(QUuid::createUuid());
|
||||
}
|
||||
|
||||
EntityItem* entity = addEntity(entityItemID, properties);
|
||||
EntityItemPointer entity = addEntity(entityItemID, properties);
|
||||
if (!entity) {
|
||||
qCDebug(entities) << "adding Entity failed:" << entityItemID << properties.getType();
|
||||
}
|
||||
|
|
|
@ -30,9 +30,9 @@ public:
|
|||
|
||||
class EntityItemFBXService {
|
||||
public:
|
||||
virtual const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) = 0;
|
||||
virtual const Model* getModelForEntityItem(const EntityItem* entityItem) = 0;
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(const EntityItem* entityItem) = 0;
|
||||
virtual const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||
virtual const Model* getModelForEntityItem(EntityItemPointer entityItem) = 0;
|
||||
virtual const FBXGeometry* getCollisionGeometryForEntity(EntityItemPointer entityItem) = 0;
|
||||
};
|
||||
|
||||
|
||||
|
@ -83,24 +83,24 @@ public:
|
|||
virtual void update();
|
||||
|
||||
// The newer API...
|
||||
void postAddEntity(EntityItem* entityItem);
|
||||
void postAddEntity(EntityItemPointer entityItem);
|
||||
|
||||
EntityItem* addEntity(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
EntityItemPointer addEntity(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
// use this method if you only know the entityID
|
||||
bool updateEntity(const EntityItemID& entityID, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
|
||||
// use this method if you have a pointer to the entity (avoid an extra entity lookup)
|
||||
bool updateEntity(EntityItem* entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
bool updateEntity(EntityItemPointer entity, const EntityItemProperties& properties, const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
|
||||
void deleteEntity(const EntityItemID& entityID, bool force = false, bool ignoreWarnings = false);
|
||||
void deleteEntities(QSet<EntityItemID> entityIDs, bool force = false, bool ignoreWarnings = false);
|
||||
|
||||
/// \param position point of query in world-frame (meters)
|
||||
/// \param targetRadius radius of query (meters)
|
||||
const EntityItem* findClosestEntity(glm::vec3 position, float targetRadius);
|
||||
EntityItem* findEntityByID(const QUuid& id);
|
||||
EntityItem* findEntityByEntityItemID(const EntityItemID& entityID);
|
||||
EntityItemPointer findClosestEntity(glm::vec3 position, float targetRadius);
|
||||
EntityItemPointer findEntityByID(const QUuid& id);
|
||||
EntityItemPointer findEntityByEntityItemID(const EntityItemID& entityID);
|
||||
|
||||
EntityItemID assignEntityID(const EntityItemID& entityItemID); /// Assigns a known ID for a creator token ID
|
||||
|
||||
|
@ -108,21 +108,21 @@ public:
|
|||
/// finds all entities that touch a sphere
|
||||
/// \param center the center of the sphere in world-frame (meters)
|
||||
/// \param radius the radius of the sphere in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of const EntityItem*
|
||||
/// \param foundEntities[out] vector of EntityItemPointer
|
||||
/// \remark Side effect: any initial contents in foundEntities will be lost
|
||||
void findEntities(const glm::vec3& center, float radius, QVector<const EntityItem*>& foundEntities);
|
||||
void findEntities(const glm::vec3& center, float radius, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
/// finds all entities that touch a cube
|
||||
/// \param cube the query cube in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of non-const EntityItem*
|
||||
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||
/// \remark Side effect: any initial contents in entities will be lost
|
||||
void findEntities(const AACube& cube, QVector<EntityItem*>& foundEntities);
|
||||
void findEntities(const AACube& cube, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
/// finds all entities that touch a box
|
||||
/// \param box the query box in world-frame (meters)
|
||||
/// \param foundEntities[out] vector of non-const EntityItem*
|
||||
/// \param foundEntities[out] vector of non-EntityItemPointer
|
||||
/// \remark Side effect: any initial contents in entities will be lost
|
||||
void findEntities(const AABox& box, QVector<EntityItem*>& foundEntities);
|
||||
void findEntities(const AABox& box, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
void addNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||
void removeNewlyCreatedHook(NewlyCreatedEntityHook* hook);
|
||||
|
@ -138,10 +138,10 @@ public:
|
|||
|
||||
EntityItemFBXService* getFBXService() const { return _fbxService; }
|
||||
void setFBXService(EntityItemFBXService* service) { _fbxService = service; }
|
||||
const FBXGeometry* getGeometryForEntity(const EntityItem* entityItem) {
|
||||
const FBXGeometry* getGeometryForEntity(EntityItemPointer entityItem) {
|
||||
return _fbxService ? _fbxService->getGeometryForEntity(entityItem) : NULL;
|
||||
}
|
||||
const Model* getModelForEntityItem(const EntityItem* entityItem) {
|
||||
const Model* getModelForEntityItem(EntityItemPointer entityItem) {
|
||||
return _fbxService ? _fbxService->getModelForEntityItem(entityItem) : NULL;
|
||||
}
|
||||
|
||||
|
@ -153,7 +153,7 @@ public:
|
|||
|
||||
QVector<EntityItemID> sendEntities(EntityEditPacketSender* packetSender, EntityTree* localTree, float x, float y, float z);
|
||||
|
||||
void entityChanged(EntityItem* entity);
|
||||
void entityChanged(EntityItemPointer entity);
|
||||
|
||||
void emitEntityScriptChanging(const EntityItemID& entityItemID);
|
||||
|
||||
|
@ -177,7 +177,7 @@ signals:
|
|||
private:
|
||||
|
||||
void processRemovedEntities(const DeleteEntityOperator& theOperator);
|
||||
bool updateEntityWithElement(EntityItem* entity, const EntityItemProperties& properties,
|
||||
bool updateEntityWithElement(EntityItemPointer entity, const EntityItemProperties& properties,
|
||||
EntityTreeElement* containingElement,
|
||||
const SharedNodePointer& senderNode = SharedNodePointer(nullptr));
|
||||
static bool findNearPointOperation(OctreeElement* element, void* extraData);
|
||||
|
|
|
@ -39,7 +39,7 @@ OctreeElement* EntityTreeElement::createNewElement(unsigned char* octalCode) {
|
|||
|
||||
void EntityTreeElement::init(unsigned char* octalCode) {
|
||||
OctreeElement::init(octalCode);
|
||||
_entityItems = new QList<EntityItem*>;
|
||||
_entityItems = new EntityItems;
|
||||
_octreeMemoryUsage += sizeof(EntityTreeElement);
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ void EntityTreeElement::initializeExtraEncodeData(EncodeBitstreamParams& params)
|
|||
}
|
||||
}
|
||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
||||
}
|
||||
|
||||
|
@ -263,7 +263,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
}
|
||||
}
|
||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
entityTreeElementExtraEncodeData->entities.insert(entity->getEntityItemID(), entity->getEntityProperties(params));
|
||||
}
|
||||
}
|
||||
|
@ -284,7 +284,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
// need to handle the case where our sibling elements need encoding but we don't.
|
||||
if (!entityTreeElementExtraEncodeData->elementCompleted) {
|
||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
bool includeThisEntity = true;
|
||||
|
||||
if (!params.forceSendScene && entity->getLastChangedOnServer() < params.lastViewFrustumSent) {
|
||||
|
@ -320,7 +320,7 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
|
||||
if (successAppendEntityCount) {
|
||||
foreach (uint16_t i, indexesOfEntitiesToInclude) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
LevelDetails entityLevel = packetData->startLevel();
|
||||
OctreeElement::AppendState appendEntityState = entity->appendEntityData(packetData,
|
||||
params, entityTreeElementExtraEncodeData);
|
||||
|
@ -408,11 +408,11 @@ OctreeElement::AppendState EntityTreeElement::appendElementData(OctreePacketData
|
|||
return appendElementState;
|
||||
}
|
||||
|
||||
bool EntityTreeElement::containsEntityBounds(const EntityItem* entity) const {
|
||||
bool EntityTreeElement::containsEntityBounds(EntityItemPointer entity) const {
|
||||
return containsBounds(entity->getMaximumAACube());
|
||||
}
|
||||
|
||||
bool EntityTreeElement::bestFitEntityBounds(const EntityItem* entity) const {
|
||||
bool EntityTreeElement::bestFitEntityBounds(EntityItemPointer entity) const {
|
||||
return bestFitBounds(entity->getMaximumAACube());
|
||||
}
|
||||
|
||||
|
@ -476,14 +476,14 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
|||
// only called if we do intersect our bounding cube, but find if we actually intersect with entities...
|
||||
int entityNumber = 0;
|
||||
|
||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
||||
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
|
||||
EntityItems::iterator entityItr = _entityItems->begin();
|
||||
EntityItems::const_iterator entityEnd = _entityItems->end();
|
||||
bool somethingIntersected = false;
|
||||
|
||||
//float bestEntityDistance = distance;
|
||||
|
||||
while(entityItr != entityEnd) {
|
||||
EntityItem* entity = (*entityItr);
|
||||
EntityItemPointer entity = (*entityItr);
|
||||
|
||||
AABox entityBox = entity->getAABox();
|
||||
float localDistance;
|
||||
|
@ -519,7 +519,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
|||
if (localDistance < distance) {
|
||||
distance = localDistance;
|
||||
face = localFace;
|
||||
*intersectedObject = (void*)entity;
|
||||
*intersectedObject = (void*)entity.get();
|
||||
somethingIntersected = true;
|
||||
}
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
|||
if (localDistance < distance) {
|
||||
distance = localDistance;
|
||||
face = localFace;
|
||||
*intersectedObject = (void*)entity;
|
||||
*intersectedObject = (void*)entity.get();
|
||||
somethingIntersected = true;
|
||||
}
|
||||
}
|
||||
|
@ -545,10 +545,10 @@ bool EntityTreeElement::findDetailedRayIntersection(const glm::vec3& origin, con
|
|||
// TODO: change this to use better bounding shape for entity than sphere
|
||||
bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const {
|
||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
||||
QList<EntityItem*>::const_iterator entityEnd = _entityItems->end();
|
||||
EntityItems::iterator entityItr = _entityItems->begin();
|
||||
EntityItems::const_iterator entityEnd = _entityItems->end();
|
||||
while(entityItr != entityEnd) {
|
||||
EntityItem* entity = (*entityItr);
|
||||
EntityItemPointer entity = (*entityItr);
|
||||
glm::vec3 entityCenter = entity->getPosition();
|
||||
float entityRadius = entity->getRadius();
|
||||
|
||||
|
@ -559,7 +559,9 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad
|
|||
|
||||
if (findSphereSpherePenetration(center, radius, entityCenter, entityRadius, penetration)) {
|
||||
// return true on first valid entity penetration
|
||||
*penetratedObject = (void*)(entity);
|
||||
|
||||
*penetratedObject = (void*)(entity.get());
|
||||
|
||||
return true;
|
||||
}
|
||||
++entityItr;
|
||||
|
@ -567,8 +569,8 @@ bool EntityTreeElement::findSpherePenetration(const glm::vec3& center, float rad
|
|||
return false;
|
||||
}
|
||||
|
||||
const EntityItem* EntityTreeElement::getClosestEntity(glm::vec3 position) const {
|
||||
const EntityItem* closestEntity = NULL;
|
||||
EntityItemPointer EntityTreeElement::getClosestEntity(glm::vec3 position) const {
|
||||
EntityItemPointer closestEntity = NULL;
|
||||
float closestEntityDistance = FLT_MAX;
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
|
@ -581,10 +583,10 @@ const EntityItem* EntityTreeElement::getClosestEntity(glm::vec3 position) const
|
|||
}
|
||||
|
||||
// TODO: change this to use better bounding shape for entity than sphere
|
||||
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<const EntityItem*>& foundEntities) const {
|
||||
void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searchRadius, QVector<EntityItemPointer>& foundEntities) const {
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
const EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
float distance = glm::length(entity->getPosition() - searchPosition);
|
||||
if (distance < searchRadius + entity->getRadius()) {
|
||||
foundEntities.push_back(entity);
|
||||
|
@ -593,12 +595,12 @@ void EntityTreeElement::getEntities(const glm::vec3& searchPosition, float searc
|
|||
}
|
||||
|
||||
// TODO: change this to use better bounding shape for entity than sphere
|
||||
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItem*>& foundEntities) {
|
||||
QList<EntityItem*>::iterator entityItr = _entityItems->begin();
|
||||
QList<EntityItem*>::iterator entityEnd = _entityItems->end();
|
||||
void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities) {
|
||||
EntityItems::iterator entityItr = _entityItems->begin();
|
||||
EntityItems::iterator entityEnd = _entityItems->end();
|
||||
AACube entityCube;
|
||||
while(entityItr != entityEnd) {
|
||||
EntityItem* entity = (*entityItr);
|
||||
EntityItemPointer entity = (*entityItr);
|
||||
float radius = entity->getRadius();
|
||||
// NOTE: we actually do cube-cube collision queries here, which is sloppy but good enough for now
|
||||
// TODO: decide whether to replace entityCube-cube query with sphere-cube (requires a square root
|
||||
|
@ -611,8 +613,8 @@ void EntityTreeElement::getEntities(const AACube& box, QVector<EntityItem*>& fou
|
|||
}
|
||||
}
|
||||
|
||||
const EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||
const EntityItem* foundEntity = NULL;
|
||||
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) const {
|
||||
EntityItemPointer foundEntity = NULL;
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
||||
|
@ -623,8 +625,8 @@ const EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemI
|
|||
return foundEntity;
|
||||
}
|
||||
|
||||
EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) {
|
||||
EntityItem* foundEntity = NULL;
|
||||
EntityItemPointer EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id) {
|
||||
EntityItemPointer foundEntity = NULL;
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
if ((*_entityItems)[i]->getEntityItemID() == id) {
|
||||
|
@ -638,9 +640,13 @@ EntityItem* EntityTreeElement::getEntityWithEntityItemID(const EntityItemID& id)
|
|||
void EntityTreeElement::cleanupEntities() {
|
||||
uint16_t numberOfEntities = _entityItems->size();
|
||||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
entity->_element = NULL;
|
||||
delete entity;
|
||||
|
||||
// NOTE: We explicitly don't delete the EntityItem here because since we only
|
||||
// access it by smart pointers, when we remove it from the _entityItems
|
||||
// we know that it will be deleted.
|
||||
//delete entity;
|
||||
}
|
||||
_entityItems->clear();
|
||||
}
|
||||
|
@ -659,7 +665,7 @@ bool EntityTreeElement::removeEntityWithEntityItemID(const EntityItemID& id) {
|
|||
return foundEntity;
|
||||
}
|
||||
|
||||
bool EntityTreeElement::removeEntityItem(EntityItem* entity) {
|
||||
bool EntityTreeElement::removeEntityItem(EntityItemPointer entity) {
|
||||
int numEntries = _entityItems->removeAll(entity);
|
||||
if (numEntries > 0) {
|
||||
assert(entity->_element == this);
|
||||
|
@ -706,7 +712,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
|
|||
for (uint16_t i = 0; i < numberOfEntities; i++) {
|
||||
int bytesForThisEntity = 0;
|
||||
EntityItemID entityItemID;
|
||||
EntityItem* entityItem = NULL;
|
||||
EntityItemPointer entityItem = NULL;
|
||||
|
||||
// Old model files don't have UUIDs in them. So we don't want to try to read those IDs from the stream.
|
||||
// Since this can only happen on loading an old file, we can safely treat these as new entity cases,
|
||||
|
@ -771,7 +777,7 @@ int EntityTreeElement::readElementDataFromBuffer(const unsigned char* data, int
|
|||
return bytesRead;
|
||||
}
|
||||
|
||||
void EntityTreeElement::addEntityItem(EntityItem* entity) {
|
||||
void EntityTreeElement::addEntityItem(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
assert(entity->_element == NULL);
|
||||
_entityItems->push_back(entity);
|
||||
|
@ -809,7 +815,7 @@ bool EntityTreeElement::pruneChildren() {
|
|||
void EntityTreeElement::expandExtentsToContents(Extents& extents) {
|
||||
if (_entityItems->size()) {
|
||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
extents.add(entity->getAABox());
|
||||
}
|
||||
}
|
||||
|
@ -825,7 +831,7 @@ void EntityTreeElement::debugDump() {
|
|||
qCDebug(entities) << " has entities:" << _entityItems->size();
|
||||
qCDebug(entities) << "--------------------------------------------------";
|
||||
for (uint16_t i = 0; i < _entityItems->size(); i++) {
|
||||
EntityItem* entity = (*_entityItems)[i];
|
||||
EntityItemPointer entity = (*_entityItems)[i];
|
||||
entity->debugDump();
|
||||
}
|
||||
qCDebug(entities) << "--------------------------------------------------";
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#ifndef hifi_EntityTreeElement_h
|
||||
#define hifi_EntityTreeElement_h
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <OctreeElement.h>
|
||||
#include <QList>
|
||||
|
||||
|
@ -19,6 +21,8 @@
|
|||
#include "EntityItem.h"
|
||||
#include "EntityTree.h"
|
||||
|
||||
typedef QVector<EntityItemPointer> EntityItems;
|
||||
|
||||
class EntityTree;
|
||||
class EntityTreeElement;
|
||||
|
||||
|
@ -30,7 +34,7 @@ public:
|
|||
_movingItems(0)
|
||||
{ }
|
||||
|
||||
QList<EntityItem*> _movingEntities;
|
||||
QList<EntityItemPointer> _movingEntities;
|
||||
int _totalElements;
|
||||
int _totalItems;
|
||||
int _movingItems;
|
||||
|
@ -142,40 +146,41 @@ public:
|
|||
virtual bool findSpherePenetration(const glm::vec3& center, float radius,
|
||||
glm::vec3& penetration, void** penetratedObject) const;
|
||||
|
||||
const QList<EntityItem*>& getEntities() const { return *_entityItems; }
|
||||
QList<EntityItem*>& getEntities() { return *_entityItems; }
|
||||
const EntityItems& getEntities() const { return *_entityItems; }
|
||||
EntityItems& getEntities() { return *_entityItems; }
|
||||
|
||||
bool hasEntities() const { return _entityItems ? _entityItems->size() > 0 : false; }
|
||||
|
||||
void setTree(EntityTree* tree) { _myTree = tree; }
|
||||
|
||||
bool updateEntity(const EntityItem& entity);
|
||||
void addEntityItem(EntityItem* entity);
|
||||
void addEntityItem(EntityItemPointer entity);
|
||||
|
||||
const EntityItem* getClosestEntity(glm::vec3 position) const;
|
||||
EntityItemPointer getClosestEntity(glm::vec3 position) const;
|
||||
|
||||
/// finds all entities that touch a sphere
|
||||
/// \param position the center of the query sphere
|
||||
/// \param radius the radius of the query sphere
|
||||
/// \param entities[out] vector of const EntityItem*
|
||||
void getEntities(const glm::vec3& position, float radius, QVector<const EntityItem*>& foundEntities) const;
|
||||
/// \param entities[out] vector of const EntityItemPointer
|
||||
void getEntities(const glm::vec3& position, float radius, QVector<EntityItemPointer>& foundEntities) const;
|
||||
|
||||
/// finds all entities that touch a box
|
||||
/// \param box the query box
|
||||
/// \param entities[out] vector of non-const EntityItem*
|
||||
void getEntities(const AACube& box, QVector<EntityItem*>& foundEntities);
|
||||
/// \param entities[out] vector of non-const EntityItemPointer
|
||||
void getEntities(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
const EntityItem* getEntityWithID(uint32_t id) const;
|
||||
const EntityItem* getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||
void getEntitiesInside(const AACube& box, QVector<EntityItem*>& foundEntities);
|
||||
EntityItemPointer getEntityWithID(uint32_t id) const;
|
||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id) const;
|
||||
void getEntitiesInside(const AACube& box, QVector<EntityItemPointer>& foundEntities);
|
||||
|
||||
EntityItem* getEntityWithEntityItemID(const EntityItemID& id);
|
||||
EntityItemPointer getEntityWithEntityItemID(const EntityItemID& id);
|
||||
|
||||
void cleanupEntities(); /// called by EntityTree on cleanup this will free all entities
|
||||
bool removeEntityWithEntityItemID(const EntityItemID& id);
|
||||
bool removeEntityItem(EntityItem* entity);
|
||||
bool removeEntityItem(EntityItemPointer entity);
|
||||
|
||||
bool containsEntityBounds(const EntityItem* entity) const;
|
||||
bool bestFitEntityBounds(const EntityItem* entity) const;
|
||||
bool containsEntityBounds(EntityItemPointer entity) const;
|
||||
bool bestFitEntityBounds(EntityItemPointer entity) const;
|
||||
|
||||
bool containsBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
||||
bool bestFitBounds(const EntityItemProperties& properties) const; // NOTE: property units in meters
|
||||
|
@ -198,7 +203,7 @@ public:
|
|||
protected:
|
||||
virtual void init(unsigned char * octalCode);
|
||||
EntityTree* _myTree;
|
||||
QList<EntityItem*>* _entityItems;
|
||||
EntityItems* _entityItems;
|
||||
};
|
||||
|
||||
#endif // hifi_EntityTreeElement_h
|
||||
|
|
|
@ -76,9 +76,9 @@ bool EntityTypes::registerEntityType(EntityType entityType, const char* name, En
|
|||
return false;
|
||||
}
|
||||
|
||||
EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
|
||||
EntityItemPointer EntityTypes::constructEntityItem(EntityType entityType, const EntityItemID& entityID,
|
||||
const EntityItemProperties& properties) {
|
||||
EntityItem* newEntityItem = NULL;
|
||||
EntityItemPointer newEntityItem = NULL;
|
||||
EntityTypeFactory factory = NULL;
|
||||
if (entityType >= 0 && entityType <= LAST) {
|
||||
factory = _factories[entityType];
|
||||
|
@ -91,7 +91,7 @@ EntityItem* EntityTypes::constructEntityItem(EntityType entityType, const Entity
|
|||
return newEntityItem;
|
||||
}
|
||||
|
||||
EntityItem* EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead,
|
||||
EntityItemPointer EntityTypes::constructEntityItem(const unsigned char* data, int bytesToRead,
|
||||
ReadBitstreamToTreeParams& args) {
|
||||
|
||||
if (args.bitstreamVersion < VERSION_ENTITIES_SUPPORT_SPLIT_MTU) {
|
||||
|
|
|
@ -20,11 +20,17 @@
|
|||
#include <OctreeRenderer.h> // for RenderArgs
|
||||
|
||||
class EntityItem;
|
||||
typedef std::shared_ptr<EntityItem> EntityItemPointer;
|
||||
|
||||
inline uint qHash(const EntityItemPointer& a, uint seed) {
|
||||
return qHash(a.get(), seed);
|
||||
}
|
||||
|
||||
class EntityItemID;
|
||||
class EntityItemProperties;
|
||||
class ReadBitstreamToTreeParams;
|
||||
|
||||
typedef EntityItem* (*EntityTypeFactory)(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
typedef EntityItemPointer (*EntityTypeFactory)(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
class EntityTypes {
|
||||
public:
|
||||
|
@ -45,8 +51,8 @@ public:
|
|||
static const QString& getEntityTypeName(EntityType entityType);
|
||||
static EntityTypes::EntityType getEntityTypeFromName(const QString& name);
|
||||
static bool registerEntityType(EntityType entityType, const char* name, EntityTypeFactory factoryMethod);
|
||||
static EntityItem* constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItem* constructEntityItem(const unsigned char* data, int bytesToRead, ReadBitstreamToTreeParams& args);
|
||||
static EntityItemPointer constructEntityItem(EntityType entityType, const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer constructEntityItem(const unsigned char* data, int bytesToRead, ReadBitstreamToTreeParams& args);
|
||||
|
||||
private:
|
||||
static QMap<EntityType, QString> _typeToNameMap;
|
||||
|
@ -59,7 +65,7 @@ private:
|
|||
/// Macro for registering entity types. Make sure to add an element to the EntityType enum with your name, and your class should be
|
||||
/// named NameEntityItem and must of a static method called factory that takes an EnityItemID, and EntityItemProperties and return a newly
|
||||
/// constructed (heap allocated) instance of your type. e.g. The following prototype:
|
||||
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
// static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
#define REGISTER_ENTITY_TYPE(x) static bool x##Registration = \
|
||||
EntityTypes::registerEntityType(EntityTypes::x, #x, x##EntityItem::factory);
|
||||
|
||||
|
@ -67,7 +73,7 @@ private:
|
|||
/// an element to the EntityType enum with your name. But unlike REGISTER_ENTITY_TYPE, your class can be named anything
|
||||
/// so long as you provide a static method passed to the macro, that takes an EnityItemID, and EntityItemProperties and
|
||||
/// returns a newly constructed (heap allocated) instance of your type. e.g. The following prototype:
|
||||
// static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
// static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
#define REGISTER_ENTITY_TYPE_WITH_FACTORY(x,y) static bool x##Registration = \
|
||||
EntityTypes::registerEntityType(EntityTypes::x, #x, y); \
|
||||
if (!x##Registration) { \
|
||||
|
|
|
@ -22,8 +22,9 @@
|
|||
|
||||
bool LightEntityItem::_lightsArePickable = false;
|
||||
|
||||
EntityItem* LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new LightEntityItem(entityID, properties);
|
||||
EntityItemPointer LightEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result { new LightEntityItem(entityID, properties) };
|
||||
return result;
|
||||
}
|
||||
|
||||
// our non-pure virtual subclass for now...
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class LightEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
LightEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include "EntityTreeElement.h"
|
||||
|
||||
|
||||
EntityItem* LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = new LineEntityItem(entityID, properties);
|
||||
EntityItemPointer LineEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result { new LineEntityItem(entityID, properties) };
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class LineEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
LineEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -28,8 +28,8 @@ const bool ModelEntityItem::DEFAULT_ANIMATION_IS_PLAYING = false;
|
|||
const float ModelEntityItem::DEFAULT_ANIMATION_FPS = 30.0f;
|
||||
|
||||
|
||||
EntityItem* ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new ModelEntityItem(entityID, properties);
|
||||
EntityItemPointer ModelEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new ModelEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
ModelEntityItem::ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
class ModelEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
ModelEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -50,7 +50,7 @@ MovingEntitiesOperator::~MovingEntitiesOperator() {
|
|||
}
|
||||
|
||||
|
||||
void MovingEntitiesOperator::addEntityToMoveList(EntityItem* entity, const AACube& newCube) {
|
||||
void MovingEntitiesOperator::addEntityToMoveList(EntityItemPointer entity, const AACube& newCube) {
|
||||
EntityTreeElement* oldContainingElement = _tree->getContainingElement(entity->getEntityItemID());
|
||||
AABox newCubeClamped = newCube.clamp(0.0f, (float)TREE_SCALE);
|
||||
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
class EntityToMoveDetails {
|
||||
public:
|
||||
EntityItem* entity;
|
||||
EntityItemPointer entity;
|
||||
AACube oldCube; // meters
|
||||
AACube newCube; // meters
|
||||
AABox newCubeClamped; // meters
|
||||
|
@ -37,7 +37,7 @@ public:
|
|||
MovingEntitiesOperator(EntityTree* tree);
|
||||
~MovingEntitiesOperator();
|
||||
|
||||
void addEntityToMoveList(EntityItem* entity, const AACube& newCube);
|
||||
void addEntityToMoveList(EntityItemPointer entity, const AACube& newCube);
|
||||
virtual bool preRecursion(OctreeElement* element);
|
||||
virtual bool postRecursion(OctreeElement* element);
|
||||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||
|
|
|
@ -55,8 +55,8 @@ const float ParticleEffectEntityItem::DEFAULT_PARTICLE_RADIUS = 0.025f;
|
|||
const QString ParticleEffectEntityItem::DEFAULT_TEXTURES = "";
|
||||
|
||||
|
||||
EntityItem* ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new ParticleEffectEntityItem(entityID, properties);
|
||||
EntityItemPointer ParticleEffectEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new ParticleEffectEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
// our non-pure virtual subclass for now...
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
class ParticleEffectEntityItem : public EntityItem {
|
||||
public:
|
||||
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
ParticleEffectEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
virtual ~ParticleEffectEntityItem();
|
||||
|
|
|
@ -43,11 +43,11 @@ bool RecurseOctreeToMapOperator::postRecursion(OctreeElement* element) {
|
|||
EntityItemProperties defaultProperties;
|
||||
|
||||
EntityTreeElement* entityTreeElement = static_cast<EntityTreeElement*>(element);
|
||||
const QList<EntityItem*>& entities = entityTreeElement->getEntities();
|
||||
const EntityItems& entities = entityTreeElement->getEntities();
|
||||
|
||||
QVariantList entitiesQList = qvariant_cast<QVariantList>(_map["Entities"]);
|
||||
|
||||
foreach (EntityItem* entityItem, entities) {
|
||||
foreach (EntityItemPointer entityItem, entities) {
|
||||
EntityItemProperties properties = entityItem->getProperties();
|
||||
QScriptValue qScriptValues;
|
||||
if (_skipDefaultValues) {
|
||||
|
|
|
@ -25,7 +25,7 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
|||
|
||||
SetOfEntities::iterator itemItr = _hasSimulationOwnerEntities.begin();
|
||||
while (itemItr != _hasSimulationOwnerEntities.end()) {
|
||||
EntityItem* entity = *itemItr;
|
||||
EntityItemPointer entity = *itemItr;
|
||||
if (entity->getSimulatorID().isNull()) {
|
||||
itemItr = _hasSimulationOwnerEntities.erase(itemItr);
|
||||
} else if (now - entity->getLastChangedOnServer() >= AUTO_REMOVE_SIMULATION_OWNER_USEC) {
|
||||
|
@ -44,18 +44,18 @@ void SimpleEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
|||
}
|
||||
}
|
||||
|
||||
void SimpleEntitySimulation::addEntityInternal(EntityItem* entity) {
|
||||
void SimpleEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||
EntitySimulation::addEntityInternal(entity);
|
||||
if (!entity->getSimulatorID().isNull()) {
|
||||
_hasSimulationOwnerEntities.insert(entity);
|
||||
}
|
||||
}
|
||||
|
||||
void SimpleEntitySimulation::removeEntityInternal(EntityItem* entity) {
|
||||
void SimpleEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||
_hasSimulationOwnerEntities.remove(entity);
|
||||
}
|
||||
|
||||
void SimpleEntitySimulation::changeEntityInternal(EntityItem* entity) {
|
||||
void SimpleEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||
EntitySimulation::changeEntityInternal(entity);
|
||||
if (!entity->getSimulatorID().isNull()) {
|
||||
_hasSimulationOwnerEntities.insert(entity);
|
||||
|
|
|
@ -23,9 +23,9 @@ public:
|
|||
|
||||
protected:
|
||||
virtual void updateEntitiesInternal(const quint64& now);
|
||||
virtual void addEntityInternal(EntityItem* entity);
|
||||
virtual void removeEntityInternal(EntityItem* entity);
|
||||
virtual void changeEntityInternal(EntityItem* entity);
|
||||
virtual void addEntityInternal(EntityItemPointer entity);
|
||||
virtual void removeEntityInternal(EntityItemPointer entity);
|
||||
virtual void changeEntityInternal(EntityItemPointer entity);
|
||||
virtual void clearEntitiesInternal();
|
||||
|
||||
SetOfEntities _hasSimulationOwnerEntities;
|
||||
|
|
|
@ -23,8 +23,9 @@
|
|||
#include "SphereEntityItem.h"
|
||||
|
||||
|
||||
EntityItem* SphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return new SphereEntityItem(entityID, properties);
|
||||
EntityItemPointer SphereEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItemPointer result { new SphereEntityItem(entityID, properties) };
|
||||
return result;
|
||||
}
|
||||
|
||||
// our non-pure virtual subclass for now...
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class SphereEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
SphereEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -28,9 +28,8 @@ const float TextEntityItem::DEFAULT_LINE_HEIGHT = 0.1f;
|
|||
const xColor TextEntityItem::DEFAULT_TEXT_COLOR = { 255, 255, 255 };
|
||||
const xColor TextEntityItem::DEFAULT_BACKGROUND_COLOR = { 0, 0, 0};
|
||||
|
||||
EntityItem* TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = new TextEntityItem(entityID, properties);
|
||||
return result;
|
||||
EntityItemPointer TextEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new TextEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
TextEntityItem::TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
class TextEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
TextEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
|
||||
UpdateEntityOperator::UpdateEntityOperator(EntityTree* tree,
|
||||
EntityTreeElement* containingElement,
|
||||
EntityItem* existingEntity,
|
||||
EntityItemPointer existingEntity,
|
||||
const EntityItemProperties& properties) :
|
||||
_tree(tree),
|
||||
_existingEntity(existingEntity),
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
class UpdateEntityOperator : public RecurseOctreeOperator {
|
||||
public:
|
||||
UpdateEntityOperator(EntityTree* tree, EntityTreeElement* containingElement,
|
||||
EntityItem* existingEntity, const EntityItemProperties& properties);
|
||||
EntityItemPointer existingEntity, const EntityItemProperties& properties);
|
||||
~UpdateEntityOperator();
|
||||
|
||||
virtual bool preRecursion(OctreeElement* element);
|
||||
|
@ -23,7 +23,7 @@ public:
|
|||
virtual OctreeElement* possiblyCreateChildAt(OctreeElement* element, int childIndex);
|
||||
private:
|
||||
EntityTree* _tree;
|
||||
EntityItem* _existingEntity;
|
||||
EntityItemPointer _existingEntity;
|
||||
EntityTreeElement* _containingElement;
|
||||
AACube _containingElementCube; // we temporarily store our cube here in case we need to delete the containing element
|
||||
EntityItemProperties _properties;
|
||||
|
|
|
@ -22,9 +22,8 @@
|
|||
|
||||
const QString WebEntityItem::DEFAULT_SOURCE_URL("http://www.google.com");
|
||||
|
||||
EntityItem* WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = new WebEntityItem(entityID, properties);
|
||||
return result;
|
||||
EntityItemPointer WebEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new WebEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
WebEntityItem::WebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -15,7 +15,7 @@ class WebEntityItem : public EntityItem {
|
|||
public:
|
||||
static const QString DEFAULT_SOURCE_URL;
|
||||
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
WebEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -29,9 +29,8 @@ const glm::vec3 ZoneEntityItem::DEFAULT_KEYLIGHT_DIRECTION = { 0.0f, -1.0f, 0.0f
|
|||
const ShapeType ZoneEntityItem::DEFAULT_SHAPE_TYPE = SHAPE_TYPE_BOX;
|
||||
const QString ZoneEntityItem::DEFAULT_COMPOUND_SHAPE_URL = "";
|
||||
|
||||
EntityItem* ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
EntityItem* result = new ZoneEntityItem(entityID, properties);
|
||||
return result;
|
||||
EntityItemPointer ZoneEntityItem::factory(const EntityItemID& entityID, const EntityItemProperties& properties) {
|
||||
return EntityItemPointer(new ZoneEntityItem(entityID, properties));
|
||||
}
|
||||
|
||||
ZoneEntityItem::ZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties) :
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
class ZoneEntityItem : public EntityItem {
|
||||
public:
|
||||
static EntityItem* factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
static EntityItemPointer factory(const EntityItemID& entityID, const EntityItemProperties& properties);
|
||||
|
||||
ZoneEntityItem(const EntityItemID& entityItemID, const EntityItemProperties& properties);
|
||||
|
||||
|
|
|
@ -43,18 +43,18 @@ void Mesh::addAttribute(Slot slot, const BufferView& buffer) {
|
|||
}
|
||||
|
||||
void Mesh::evalVertexFormat() {
|
||||
VertexFormat vf;
|
||||
auto vf = new VertexFormat();
|
||||
int channelNum = 0;
|
||||
if (hasVertexData()) {
|
||||
vf.setAttribute(gpu::Stream::POSITION, channelNum, _vertexBuffer._element, 0);
|
||||
vf->setAttribute(gpu::Stream::POSITION, channelNum, _vertexBuffer._element, 0);
|
||||
channelNum++;
|
||||
}
|
||||
for (auto attrib : _attributeBuffers) {
|
||||
vf.setAttribute(attrib.first, channelNum, attrib.second._element, 0);
|
||||
vf->setAttribute(attrib.first, channelNum, attrib.second._element, 0);
|
||||
channelNum++;
|
||||
}
|
||||
|
||||
_vertexFormat = vf;
|
||||
_vertexFormat.reset(vf);
|
||||
}
|
||||
|
||||
void Mesh::setIndexBuffer(const BufferView& buffer) {
|
||||
|
@ -112,12 +112,12 @@ const gpu::BufferStream Mesh::makeBufferStream() const {
|
|||
|
||||
int channelNum = 0;
|
||||
if (hasVertexData()) {
|
||||
stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat.getChannelStride(channelNum));
|
||||
stream.addBuffer(_vertexBuffer._buffer, _vertexBuffer._offset, _vertexFormat->getChannelStride(channelNum));
|
||||
channelNum++;
|
||||
}
|
||||
for (auto attrib : _attributeBuffers) {
|
||||
BufferView& view = attrib.second;
|
||||
stream.addBuffer(view._buffer, view._offset, _vertexFormat.getChannelStride(channelNum));
|
||||
stream.addBuffer(view._buffer, view._offset, _vertexFormat->getChannelStride(channelNum));
|
||||
channelNum++;
|
||||
}
|
||||
|
||||
|
|
|
@ -47,14 +47,14 @@ public:
|
|||
void setVertexBuffer(const BufferView& buffer);
|
||||
const BufferView& getVertexBuffer() const { return _vertexBuffer; }
|
||||
uint getNumVertices() const { return _vertexBuffer.getNumElements(); }
|
||||
bool hasVertexData() const { return !_vertexBuffer._buffer; }
|
||||
bool hasVertexData() const { return _vertexBuffer._buffer.get() != nullptr; }
|
||||
|
||||
// Attribute Buffers
|
||||
int getNumAttributes() const { return _attributeBuffers.size(); }
|
||||
void addAttribute(Slot slot, const BufferView& buffer);
|
||||
|
||||
// Stream format
|
||||
const VertexFormat& getVertexFormat() const { return _vertexFormat; }
|
||||
const gpu::Stream::FormatPointer getVertexFormat() const { return _vertexFormat; }
|
||||
|
||||
// Index Buffer
|
||||
void setIndexBuffer(const BufferView& buffer);
|
||||
|
@ -114,7 +114,7 @@ public:
|
|||
|
||||
protected:
|
||||
|
||||
VertexFormat _vertexFormat;
|
||||
gpu::Stream::FormatPointer _vertexFormat;
|
||||
|
||||
BufferView _vertexBuffer;
|
||||
BufferViewMap _attributeBuffers;
|
||||
|
|
|
@ -27,7 +27,7 @@ void ReceivedPacketProcessor::queueReceivedPacket(const SharedNodePointer& sendi
|
|||
_nodePacketCounts[sendingNode->getUUID()]++;
|
||||
unlock();
|
||||
|
||||
// Make sure to wake our actual processing thread because we now have packets for it to process.
|
||||
// Make sure to wake our actual processing thread because we now have packets for it to process.
|
||||
_hasPackets.wakeAll();
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -22,7 +22,7 @@ static const float ACCELERATION_EQUIVALENT_EPSILON_RATIO = 0.1f;
|
|||
static const quint8 STEPS_TO_DECIDE_BALLISTIC = 4;
|
||||
|
||||
|
||||
EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItem* entity) :
|
||||
EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItemPointer entity) :
|
||||
ObjectMotionState(shape),
|
||||
_entity(entity),
|
||||
_sentActive(false),
|
||||
|
@ -39,8 +39,9 @@ EntityMotionState::EntityMotionState(btCollisionShape* shape, EntityItem* entity
|
|||
_loopsSinceOwnershipBid(0),
|
||||
_loopsWithoutOwner(0)
|
||||
{
|
||||
_type = MOTION_STATE_TYPE_ENTITY;
|
||||
assert(entity != nullptr);
|
||||
_type = MOTIONSTATE_TYPE_ENTITY;
|
||||
assert(_entity != nullptr);
|
||||
setMass(_entity->computeMass());
|
||||
}
|
||||
|
||||
EntityMotionState::~EntityMotionState() {
|
||||
|
@ -88,7 +89,6 @@ void EntityMotionState::handleEasyChanges(uint32_t flags) {
|
|||
if ((flags & EntityItem::DIRTY_PHYSICS_ACTIVATION) && !_body->isActive()) {
|
||||
_body->activate();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -98,10 +98,9 @@ void EntityMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
|
|||
ObjectMotionState::handleHardAndEasyChanges(flags, engine);
|
||||
}
|
||||
|
||||
void EntityMotionState::clearEntity() {
|
||||
void EntityMotionState::clearObjectBackPointer() {
|
||||
ObjectMotionState::clearObjectBackPointer();
|
||||
_entity = nullptr;
|
||||
// set the type to INVALID so that external logic that pivots on the type won't try to access _entity
|
||||
_type = MOTION_STATE_TYPE_INVALID;
|
||||
}
|
||||
|
||||
MotionType EntityMotionState::computeObjectMotionType() const {
|
||||
|
@ -178,10 +177,14 @@ void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void EntityMotionState::computeObjectShapeInfo(ShapeInfo& shapeInfo) {
|
||||
// virtual and protected
|
||||
btCollisionShape* EntityMotionState::computeNewShape() {
|
||||
if (_entity) {
|
||||
ShapeInfo shapeInfo;
|
||||
_entity->computeShapeInfo(shapeInfo);
|
||||
return getShapeManager()->getShape(shapeInfo);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// RELIABLE_SEND_HACK: until we have truly reliable resends of non-moving updates
|
||||
|
@ -444,7 +447,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, const Q
|
|||
_lastStep = step;
|
||||
}
|
||||
|
||||
uint32_t EntityMotionState::getAndClearIncomingDirtyFlags() const {
|
||||
uint32_t EntityMotionState::getAndClearIncomingDirtyFlags() {
|
||||
uint32_t dirtyFlags = 0;
|
||||
if (_body && _entity) {
|
||||
dirtyFlags = _entity->getDirtyFlags();
|
||||
|
|
|
@ -25,7 +25,7 @@ class EntityItem;
|
|||
class EntityMotionState : public ObjectMotionState {
|
||||
public:
|
||||
|
||||
EntityMotionState(btCollisionShape* shape, EntityItem* item);
|
||||
EntityMotionState(btCollisionShape* shape, EntityItemPointer item);
|
||||
virtual ~EntityMotionState();
|
||||
|
||||
void updateServerPhysicsVariables(uint32_t flags);
|
||||
|
@ -43,14 +43,12 @@ public:
|
|||
// this relays outgoing position/rotation to the EntityItem
|
||||
virtual void setWorldTransform(const btTransform& worldTrans);
|
||||
|
||||
virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo);
|
||||
|
||||
bool isCandidateForOwnership(const QUuid& sessionID) const;
|
||||
bool remoteSimulationOutOfSync(uint32_t simulationStep);
|
||||
bool shouldSendUpdate(uint32_t simulationStep, const QUuid& sessionID);
|
||||
void sendUpdate(OctreeEditPacketSender* packetSender, const QUuid& sessionID, uint32_t step);
|
||||
|
||||
virtual uint32_t getAndClearIncomingDirtyFlags() const;
|
||||
virtual uint32_t getAndClearIncomingDirtyFlags();
|
||||
|
||||
void incrementAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount++; }
|
||||
void resetAccelerationNearlyGravityCount() { _accelerationNearlyGravityCount = 0; }
|
||||
|
@ -62,7 +60,7 @@ public:
|
|||
virtual float getObjectAngularDamping() const { return _entity->getAngularDamping(); }
|
||||
|
||||
virtual glm::vec3 getObjectPosition() const { return _entity->getPosition() - ObjectMotionState::getWorldOffset(); }
|
||||
virtual const glm::quat& getObjectRotation() const { return _entity->getRotation(); }
|
||||
virtual glm::quat getObjectRotation() const { return _entity->getRotation(); }
|
||||
virtual const glm::vec3& getObjectLinearVelocity() const { return _entity->getVelocity(); }
|
||||
virtual const glm::vec3& getObjectAngularVelocity() const { return _entity->getAngularVelocity(); }
|
||||
virtual const glm::vec3& getObjectGravity() const { return _entity->getGravity(); }
|
||||
|
@ -72,7 +70,7 @@ public:
|
|||
virtual QUuid getSimulatorID() const;
|
||||
virtual void bump();
|
||||
|
||||
EntityItem* getEntity() const { return _entity; }
|
||||
EntityItemPointer getEntity() const { return _entity; }
|
||||
|
||||
void resetMeasuredBodyAcceleration();
|
||||
void measureBodyAcceleration();
|
||||
|
@ -82,11 +80,11 @@ public:
|
|||
friend class PhysicalEntitySimulation;
|
||||
|
||||
protected:
|
||||
void clearEntity();
|
||||
|
||||
virtual btCollisionShape* computeNewShape();
|
||||
virtual void clearObjectBackPointer();
|
||||
virtual void setMotionType(MotionType motionType);
|
||||
|
||||
EntityItem* _entity;
|
||||
EntityItemPointer _entity;
|
||||
|
||||
bool _sentActive; // true if body was active when we sent last update
|
||||
int _numNonMovingUpdates; // RELIABLE_SEND_HACK for "not so reliable" resends of packets for non-moving objects
|
||||
|
|
|
@ -140,20 +140,14 @@ void ObjectMotionState::handleEasyChanges(uint32_t flags) {
|
|||
}
|
||||
|
||||
if (flags & EntityItem::DIRTY_MASS) {
|
||||
float mass = getMass();
|
||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||
_body->getCollisionShape()->calculateLocalInertia(mass, inertia);
|
||||
_body->setMassProps(mass, inertia);
|
||||
_body->updateInertiaTensor();
|
||||
updateBodyMassProperties();
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine) {
|
||||
if (flags & EntityItem::DIRTY_SHAPE) {
|
||||
// make sure the new shape is valid
|
||||
ShapeInfo shapeInfo;
|
||||
computeObjectShapeInfo(shapeInfo);
|
||||
btCollisionShape* newShape = getShapeManager()->getShape(shapeInfo);
|
||||
btCollisionShape* newShape = computeNewShape();
|
||||
if (!newShape) {
|
||||
qCDebug(physics) << "Warning: failed to generate new shape!";
|
||||
// failed to generate new shape! --> keep old shape and remove shape-change flag
|
||||
|
@ -168,17 +162,22 @@ void ObjectMotionState::handleHardAndEasyChanges(uint32_t flags, PhysicsEngine*
|
|||
}
|
||||
}
|
||||
getShapeManager()->releaseShape(_shape);
|
||||
_shape = newShape;
|
||||
_body->setCollisionShape(_shape);
|
||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||
handleEasyChanges(flags);
|
||||
}
|
||||
} else {
|
||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||
handleEasyChanges(flags);
|
||||
if (_shape != newShape) {
|
||||
_shape = newShape;
|
||||
_body->setCollisionShape(_shape);
|
||||
} else {
|
||||
// huh... the shape didn't actually change, so we clear the DIRTY_SHAPE flag
|
||||
flags &= ~EntityItem::DIRTY_SHAPE;
|
||||
}
|
||||
}
|
||||
engine->reinsertObject(this);
|
||||
if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
|
||||
handleEasyChanges(flags);
|
||||
}
|
||||
// it is possible that there are no HARD flags at this point (if DIRTY_SHAPE was removed)
|
||||
// so we check again befoe we reinsert:
|
||||
if (flags & HARD_DIRTY_PHYSICS_FLAGS) {
|
||||
engine->reinsertObject(this);
|
||||
}
|
||||
}
|
||||
|
||||
void ObjectMotionState::updateBodyMaterialProperties() {
|
||||
|
@ -193,3 +192,11 @@ void ObjectMotionState::updateBodyVelocities() {
|
|||
setBodyGravity(getObjectGravity());
|
||||
_body->setActivationState(ACTIVE_TAG);
|
||||
}
|
||||
|
||||
void ObjectMotionState::updateBodyMassProperties() {
|
||||
float mass = getMass();
|
||||
btVector3 inertia(0.0f, 0.0f, 0.0f);
|
||||
_body->getCollisionShape()->calculateLocalInertia(mass, inertia);
|
||||
_body->setMassProps(mass, inertia);
|
||||
_body->updateInertiaTensor();
|
||||
}
|
||||
|
|
|
@ -15,6 +15,9 @@
|
|||
#include <btBulletDynamicsCommon.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
|
||||
#include <EntityItem.h>
|
||||
|
||||
#include "ContactInfo.h"
|
||||
|
@ -27,9 +30,9 @@ enum MotionType {
|
|||
};
|
||||
|
||||
enum MotionStateType {
|
||||
MOTION_STATE_TYPE_INVALID,
|
||||
MOTION_STATE_TYPE_ENTITY,
|
||||
MOTION_STATE_TYPE_AVATAR
|
||||
MOTIONSTATE_TYPE_INVALID,
|
||||
MOTIONSTATE_TYPE_ENTITY,
|
||||
MOTIONSTATE_TYPE_AVATAR
|
||||
};
|
||||
|
||||
// The update flags trigger two varieties of updates: "hard" which require the body to be pulled
|
||||
|
@ -71,8 +74,9 @@ public:
|
|||
virtual void handleEasyChanges(uint32_t flags);
|
||||
virtual void handleHardAndEasyChanges(uint32_t flags, PhysicsEngine* engine);
|
||||
|
||||
virtual void updateBodyMaterialProperties();
|
||||
virtual void updateBodyVelocities();
|
||||
void updateBodyMaterialProperties();
|
||||
void updateBodyVelocities();
|
||||
virtual void updateBodyMassProperties();
|
||||
|
||||
MotionStateType getType() const { return _type; }
|
||||
virtual MotionType getMotionType() const { return _motionType; }
|
||||
|
@ -87,11 +91,9 @@ public:
|
|||
glm::vec3 getBodyLinearVelocity() const;
|
||||
glm::vec3 getBodyAngularVelocity() const;
|
||||
|
||||
virtual uint32_t getAndClearIncomingDirtyFlags() const = 0;
|
||||
virtual uint32_t getAndClearIncomingDirtyFlags() = 0;
|
||||
|
||||
virtual MotionType computeObjectMotionType() const = 0;
|
||||
virtual void computeObjectShapeInfo(ShapeInfo& shapeInfo) = 0;
|
||||
|
||||
|
||||
btCollisionShape* getShape() const { return _shape; }
|
||||
btRigidBody* getRigidBody() const { return _body; }
|
||||
|
@ -109,7 +111,7 @@ public:
|
|||
virtual float getObjectAngularDamping() const = 0;
|
||||
|
||||
virtual glm::vec3 getObjectPosition() const = 0;
|
||||
virtual const glm::quat& getObjectRotation() const = 0;
|
||||
virtual glm::quat getObjectRotation() const = 0;
|
||||
virtual const glm::vec3& getObjectLinearVelocity() const = 0;
|
||||
virtual const glm::vec3& getObjectAngularVelocity() const = 0;
|
||||
virtual const glm::vec3& getObjectGravity() const = 0;
|
||||
|
@ -124,10 +126,15 @@ public:
|
|||
friend class PhysicsEngine;
|
||||
|
||||
protected:
|
||||
virtual void setMotionType(MotionType motionType);
|
||||
virtual btCollisionShape* computeNewShape() = 0;
|
||||
void setMotionType(MotionType motionType);
|
||||
|
||||
// clearObjectBackPointer() overrrides should call the base method, then actually clear the object back pointer.
|
||||
virtual void clearObjectBackPointer() { _type = MOTIONSTATE_TYPE_INVALID; }
|
||||
|
||||
void setRigidBody(btRigidBody* body);
|
||||
|
||||
MotionStateType _type = MOTION_STATE_TYPE_INVALID; // type of MotionState
|
||||
MotionStateType _type = MOTIONSTATE_TYPE_INVALID; // type of MotionState
|
||||
MotionType _motionType; // type of motion: KINEMATIC, DYNAMIC, or STATIC
|
||||
|
||||
btCollisionShape* _shape;
|
||||
|
@ -137,4 +144,7 @@ protected:
|
|||
uint32_t _lastKinematicStep;
|
||||
};
|
||||
|
||||
typedef QSet<ObjectMotionState*> SetOfMotionStates;
|
||||
typedef QVector<ObjectMotionState*> VectorOfMotionStates;
|
||||
|
||||
#endif // hifi_ObjectMotionState_h
|
||||
|
|
|
@ -9,11 +9,9 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "EntityMotionState.h"
|
||||
#include "PhysicalEntitySimulation.h"
|
||||
#include "PhysicsHelpers.h"
|
||||
#include "PhysicsLogging.h"
|
||||
#include "ShapeInfoUtil.h"
|
||||
#include "ShapeManager.h"
|
||||
|
||||
PhysicalEntitySimulation::PhysicalEntitySimulation() {
|
||||
|
@ -25,7 +23,6 @@ PhysicalEntitySimulation::~PhysicalEntitySimulation() {
|
|||
void PhysicalEntitySimulation::init(
|
||||
EntityTree* tree,
|
||||
PhysicsEngine* physicsEngine,
|
||||
ShapeManager* shapeManager,
|
||||
EntityEditPacketSender* packetSender) {
|
||||
assert(tree);
|
||||
setEntityTree(tree);
|
||||
|
@ -33,9 +30,6 @@ void PhysicalEntitySimulation::init(
|
|||
assert(physicsEngine);
|
||||
_physicsEngine = physicsEngine;
|
||||
|
||||
assert(shapeManager);
|
||||
_shapeManager = shapeManager;
|
||||
|
||||
assert(packetSender);
|
||||
_entityPacketSender = packetSender;
|
||||
}
|
||||
|
@ -45,7 +39,7 @@ void PhysicalEntitySimulation::updateEntitiesInternal(const quint64& now) {
|
|||
// TODO: add back non-physical kinematic objects and step them forward here
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::addEntityInternal(EntityItem* entity) {
|
||||
void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
||||
assert(entity);
|
||||
if (entity->shouldBePhysical()) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
|
@ -57,10 +51,10 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItem* entity) {
|
|||
}
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::removeEntityInternal(EntityItem* entity) {
|
||||
void PhysicalEntitySimulation::removeEntityInternal(EntityItemPointer entity) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
if (motionState) {
|
||||
motionState->clearEntity();
|
||||
motionState->clearObjectBackPointer();
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
_pendingRemoves.insert(motionState);
|
||||
_outgoingChanges.remove(motionState);
|
||||
|
@ -68,7 +62,7 @@ void PhysicalEntitySimulation::removeEntityInternal(EntityItem* entity) {
|
|||
_pendingAdds.remove(entity);
|
||||
}
|
||||
|
||||
void PhysicalEntitySimulation::changeEntityInternal(EntityItem* entity) {
|
||||
void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) {
|
||||
// queue incoming changes: from external sources (script, EntityServer, etc) to physics engine
|
||||
assert(entity);
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
|
@ -105,11 +99,11 @@ void PhysicalEntitySimulation::clearEntitiesInternal() {
|
|||
// first disconnect each MotionStates from its Entity
|
||||
for (auto stateItr : _physicalObjects) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(&(*stateItr));
|
||||
EntityItem* entity = motionState->getEntity();
|
||||
EntityItemPointer entity = motionState->getEntity();
|
||||
if (entity) {
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
}
|
||||
motionState->clearEntity();
|
||||
motionState->clearObjectBackPointer();
|
||||
}
|
||||
|
||||
// then delete the objects (aka MotionStates)
|
||||
|
@ -131,11 +125,11 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToDelete() {
|
|||
_pendingChanges.remove(motionState);
|
||||
_physicalObjects.remove(motionState);
|
||||
|
||||
EntityItem* entity = motionState->getEntity();
|
||||
EntityItemPointer entity = motionState->getEntity();
|
||||
if (entity) {
|
||||
_pendingAdds.remove(entity);
|
||||
entity->setPhysicsInfo(nullptr);
|
||||
motionState->clearEntity();
|
||||
motionState->clearObjectBackPointer();
|
||||
}
|
||||
_tempVector.push_back(motionState);
|
||||
}
|
||||
|
@ -147,7 +141,7 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToAdd() {
|
|||
_tempVector.clear();
|
||||
SetOfEntities::iterator entityItr = _pendingAdds.begin();
|
||||
while (entityItr != _pendingAdds.end()) {
|
||||
EntityItem* entity = *entityItr;
|
||||
EntityItemPointer entity = *entityItr;
|
||||
assert(!entity->getPhysicsInfo());
|
||||
if (!entity->shouldBePhysical()) {
|
||||
// this entity should no longer be on the internal _pendingAdds
|
||||
|
@ -158,16 +152,14 @@ VectorOfMotionStates& PhysicalEntitySimulation::getObjectsToAdd() {
|
|||
} else if (entity->isReadyToComputeShape()) {
|
||||
ShapeInfo shapeInfo;
|
||||
entity->computeShapeInfo(shapeInfo);
|
||||
btCollisionShape* shape = _shapeManager->getShape(shapeInfo);
|
||||
btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
|
||||
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;
|
||||
}
|
||||
|
@ -192,9 +184,9 @@ void PhysicalEntitySimulation::handleOutgoingChanges(VectorOfMotionStates& motio
|
|||
// walk the motionStates looking for those that correspond to entities
|
||||
for (auto stateItr : motionStates) {
|
||||
ObjectMotionState* state = &(*stateItr);
|
||||
if (state && state->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||
if (state && state->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
EntityMotionState* entityState = static_cast<EntityMotionState*>(state);
|
||||
EntityItem* entity = entityState->getEntity();
|
||||
EntityItemPointer entity = entityState->getEntity();
|
||||
if (entity) {
|
||||
if (entityState->isCandidateForOwnership(sessionID)) {
|
||||
_outgoingChanges.insert(entityState);
|
||||
|
|
|
@ -21,10 +21,7 @@
|
|||
#include <EntitySimulation.h>
|
||||
|
||||
#include "PhysicsEngine.h"
|
||||
#include "PhysicsTypedefs.h"
|
||||
|
||||
class EntityMotionState;
|
||||
class ShapeManager;
|
||||
#include "EntityMotionState.h"
|
||||
|
||||
typedef QSet<EntityMotionState*> SetOfEntityMotionStates;
|
||||
|
||||
|
@ -33,14 +30,14 @@ public:
|
|||
PhysicalEntitySimulation();
|
||||
~PhysicalEntitySimulation();
|
||||
|
||||
void init(EntityTree* tree, PhysicsEngine* engine, ShapeManager* shapeManager, EntityEditPacketSender* packetSender);
|
||||
void init(EntityTree* tree, PhysicsEngine* engine, EntityEditPacketSender* packetSender);
|
||||
|
||||
protected: // only called by EntitySimulation
|
||||
// overrides for EntitySimulation
|
||||
virtual void updateEntitiesInternal(const quint64& now);
|
||||
virtual void addEntityInternal(EntityItem* entity);
|
||||
virtual void removeEntityInternal(EntityItem* entity);
|
||||
virtual void changeEntityInternal(EntityItem* entity);
|
||||
virtual void addEntityInternal(EntityItemPointer entity);
|
||||
virtual void removeEntityInternal(EntityItemPointer entity);
|
||||
virtual void changeEntityInternal(EntityItemPointer entity);
|
||||
virtual void clearEntitiesInternal();
|
||||
|
||||
public:
|
||||
|
@ -63,7 +60,6 @@ private:
|
|||
SetOfMotionStates _physicalObjects; // MotionStates of entities in PhysicsEngine
|
||||
VectorOfMotionStates _tempVector; // temporary array reference, valid immediately after getObjectsToRemove() (and friends)
|
||||
|
||||
ShapeManager* _shapeManager = nullptr;
|
||||
PhysicsEngine* _physicsEngine = nullptr;
|
||||
EntityEditPacketSender* _entityPacketSender = nullptr;
|
||||
|
||||
|
|
|
@ -318,16 +318,16 @@ CollisionEvents& PhysicsEngine::getCollisionEvents() {
|
|||
ObjectMotionState* A = static_cast<ObjectMotionState*>(contactItr->first._a);
|
||||
ObjectMotionState* B = static_cast<ObjectMotionState*>(contactItr->first._b);
|
||||
|
||||
if (A && A->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||
if (A && A->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
QUuid idA = A->getObjectID();
|
||||
QUuid idB;
|
||||
if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||
if (B && B->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
idB = B->getObjectID();
|
||||
}
|
||||
glm::vec3 position = bulletToGLM(contact.getPositionWorldOnB()) + _originOffset;
|
||||
glm::vec3 penetration = bulletToGLM(contact.distance * contact.normalWorldOnB);
|
||||
_collisionEvents.push_back(Collision(type, idA, idB, position, penetration));
|
||||
} else if (B && B->getType() == MOTION_STATE_TYPE_ENTITY) {
|
||||
} else if (B && B->getType() == MOTIONSTATE_TYPE_ENTITY) {
|
||||
QUuid idB = B->getObjectID();
|
||||
glm::vec3 position = bulletToGLM(contact.getPositionWorldOnA()) + _originOffset;
|
||||
// NOTE: we're flipping the order of A and B (so that the first objectID is never NULL)
|
||||
|
|
|
@ -22,13 +22,11 @@
|
|||
#include "BulletUtil.h"
|
||||
#include "ContactInfo.h"
|
||||
#include "DynamicCharacterController.h"
|
||||
#include "PhysicsTypedefs.h"
|
||||
#include "ObjectMotionState.h"
|
||||
#include "ThreadSafeDynamicsWorld.h"
|
||||
|
||||
const float HALF_SIMULATION_EXTENT = 512.0f; // meters
|
||||
|
||||
class ObjectMotionState;
|
||||
|
||||
// simple class for keeping track of contacts
|
||||
class ContactKey {
|
||||
public:
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
//
|
||||
// PhysicsTypedefs.h
|
||||
// libraries/physcis/src
|
||||
//
|
||||
// Created by Andrew Meadows 2015.04.29
|
||||
// Copyright 2015 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_PhysicsTypedefs_h
|
||||
#define hifi_PhysicsTypedefs_h
|
||||
|
||||
#include <QSet>
|
||||
#include <QVector>
|
||||
|
||||
class ObjectMotionState;
|
||||
|
||||
typedef QSet<ObjectMotionState*> SetOfMotionStates;
|
||||
typedef QVector<ObjectMotionState*> VectorOfMotionStates;
|
||||
|
||||
#endif //hifi_PhysicsTypedefs_h
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// ShapeInfoUtil.cpp
|
||||
// ShapeFactory.cpp
|
||||
// libraries/physcis/src
|
||||
//
|
||||
// Created by Andrew Meadows 2014.12.01
|
||||
|
@ -9,14 +9,16 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include <SharedUtil.h> // for MILLIMETERS_PER_METER
|
||||
|
||||
#include "ShapeInfoUtil.h"
|
||||
#include "ShapeFactory.h"
|
||||
#include "BulletUtil.h"
|
||||
|
||||
|
||||
|
||||
btConvexHullShape* ShapeInfoUtil::createConvexHull(const QVector<glm::vec3>& points) {
|
||||
btConvexHullShape* ShapeFactory::createConvexHull(const QVector<glm::vec3>& points) {
|
||||
assert(points.size() > 0);
|
||||
|
||||
btConvexHullShape* hull = new btConvexHullShape();
|
||||
|
@ -57,9 +59,10 @@ btConvexHullShape* ShapeInfoUtil::createConvexHull(const QVector<glm::vec3>& poi
|
|||
return hull;
|
||||
}
|
||||
|
||||
btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
|
||||
btCollisionShape* ShapeFactory::createShapeFromInfo(const ShapeInfo& info) {
|
||||
btCollisionShape* shape = NULL;
|
||||
switch(info.getType()) {
|
||||
int type = info.getType();
|
||||
switch(type) {
|
||||
case SHAPE_TYPE_BOX: {
|
||||
shape = new btBoxShape(glmToBullet(info.getHalfExtents()));
|
||||
}
|
||||
|
@ -95,5 +98,17 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
if (shape && type != SHAPE_TYPE_COMPOUND) {
|
||||
if (glm::length2(info.getOffset()) > MIN_SHAPE_OFFSET * MIN_SHAPE_OFFSET) {
|
||||
// this shape has an offset, which we support by wrapping the true shape
|
||||
// in a btCompoundShape with a local transform
|
||||
auto compound = new btCompoundShape();
|
||||
btTransform trans;
|
||||
trans.setIdentity();
|
||||
trans.setOrigin(glmToBullet(info.getOffset()));
|
||||
compound->addChildShape(trans, shape);
|
||||
shape = compound;
|
||||
}
|
||||
}
|
||||
return shape;
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
//
|
||||
// ShapeInfoUtil.h
|
||||
// ShapeFactory.h
|
||||
// libraries/physcis/src
|
||||
//
|
||||
// Created by Andrew Meadows 2014.12.01
|
||||
|
@ -9,8 +9,8 @@
|
|||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#ifndef hifi_ShapeInfoUtil_h
|
||||
#define hifi_ShapeInfoUtil_h
|
||||
#ifndef hifi_ShapeFactory_h
|
||||
#define hifi_ShapeFactory_h
|
||||
|
||||
#include <btBulletDynamicsCommon.h>
|
||||
#include <glm/glm.hpp>
|
||||
|
@ -20,11 +20,11 @@
|
|||
// translates between ShapeInfo and btShape
|
||||
|
||||
// TODO: rename this to ShapeFactory
|
||||
namespace ShapeInfoUtil {
|
||||
namespace ShapeFactory {
|
||||
|
||||
btConvexHullShape* createConvexHull(const QVector<glm::vec3>& points);
|
||||
|
||||
btCollisionShape* createShapeFromInfo(const ShapeInfo& info);
|
||||
};
|
||||
|
||||
#endif // hifi_ShapeInfoUtil_h
|
||||
#endif // hifi_ShapeFactory_h
|
|
@ -13,7 +13,7 @@
|
|||
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "ShapeInfoUtil.h"
|
||||
#include "ShapeFactory.h"
|
||||
#include "ShapeManager.h"
|
||||
|
||||
ShapeManager::ShapeManager() {
|
||||
|
@ -46,7 +46,7 @@ btCollisionShape* ShapeManager::getShape(const ShapeInfo& info) {
|
|||
shapeRef->refCount++;
|
||||
return shapeRef->shape;
|
||||
}
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
btCollisionShape* shape = ShapeFactory::createShapeFromInfo(info);
|
||||
if (shape) {
|
||||
ShapeReference newRef;
|
||||
newRef.refCount = 1;
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
#include <LinearMath/btQuickprof.h>
|
||||
|
||||
#include "ObjectMotionState.h"
|
||||
#include "ThreadSafeDynamicsWorld.h"
|
||||
|
||||
ThreadSafeDynamicsWorld::ThreadSafeDynamicsWorld(
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
#include <BulletDynamics/Dynamics/btRigidBody.h>
|
||||
#include <BulletDynamics/Dynamics/btDiscreteDynamicsWorld.h>
|
||||
|
||||
#include "PhysicsTypedefs.h"
|
||||
#include "ObjectMotionState.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(class) ThreadSafeDynamicsWorld : public btDiscreteDynamicsWorld {
|
||||
public:
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
|
||||
void ShapeInfo::clear() {
|
||||
_type = SHAPE_TYPE_NONE;
|
||||
_halfExtents = glm::vec3(0.0f);
|
||||
_halfExtents = _offset = glm::vec3(0.0f);
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
|
@ -45,6 +45,7 @@ void ShapeInfo::setParams(ShapeType type, const glm::vec3& halfExtents, QString
|
|||
_halfExtents = halfExtents;
|
||||
break;
|
||||
}
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
void ShapeInfo::setBox(const glm::vec3& halfExtents) {
|
||||
|
@ -85,6 +86,11 @@ void ShapeInfo::setCapsuleY(float radius, float halfHeight) {
|
|||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
void ShapeInfo::setOffset(const glm::vec3& offset) {
|
||||
_offset = offset;
|
||||
_doubleHashKey.clear();
|
||||
}
|
||||
|
||||
uint32_t ShapeInfo::getNumSubShapes() const {
|
||||
if (_type == SHAPE_TYPE_NONE) {
|
||||
return 0;
|
||||
|
@ -175,6 +181,7 @@ bool ShapeInfo::contains(const glm::vec3& point) const {
|
|||
const DoubleHashKey& ShapeInfo::getHash() const {
|
||||
// NOTE: we cache the key so we only ever need to compute it once for any valid ShapeInfo instance.
|
||||
if (_doubleHashKey.isNull() && _type != SHAPE_TYPE_NONE) {
|
||||
bool useOffset = glm::length2(_offset) > MIN_SHAPE_OFFSET * MIN_SHAPE_OFFSET;
|
||||
// The key is not yet cached therefore we must compute it! To this end we bypass the const-ness
|
||||
// of this method by grabbing a non-const pointer to "this" and a non-const reference to _doubleHashKey.
|
||||
ShapeInfo* thisPtr = const_cast<ShapeInfo*>(this);
|
||||
|
@ -190,9 +197,14 @@ const DoubleHashKey& ShapeInfo::getHash() const {
|
|||
for (int j = 0; j < 3; ++j) {
|
||||
// NOTE: 0.49f is used to bump the float up almost half a millimeter
|
||||
// so the cast to int produces a round() effect rather than a floor()
|
||||
uint32_t floatHash =
|
||||
DoubleHashKey::hashFunction((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f), primeIndex++);
|
||||
hash ^= floatHash;
|
||||
hash ^= DoubleHashKey::hashFunction(
|
||||
(uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f),
|
||||
primeIndex++);
|
||||
if (useOffset) {
|
||||
hash ^= DoubleHashKey::hashFunction(
|
||||
(uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f),
|
||||
primeIndex++);
|
||||
}
|
||||
}
|
||||
key.setHash(hash);
|
||||
|
||||
|
@ -201,8 +213,12 @@ const DoubleHashKey& ShapeInfo::getHash() const {
|
|||
for (int j = 0; j < 3; ++j) {
|
||||
// NOTE: 0.49f is used to bump the float up almost half a millimeter
|
||||
// so the cast to int produces a round() effect rather than a floor()
|
||||
uint32_t floatHash =
|
||||
DoubleHashKey::hashFunction2((uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f));
|
||||
uint32_t floatHash = DoubleHashKey::hashFunction2(
|
||||
(uint32_t)(_halfExtents[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _halfExtents[j]) * 0.49f));
|
||||
if (useOffset) {
|
||||
floatHash ^= DoubleHashKey::hashFunction2(
|
||||
(uint32_t)(_offset[j] * MILLIMETERS_PER_METER + copysignf(1.0f, _offset[j]) * 0.49f));
|
||||
}
|
||||
hash += ~(floatHash << 17);
|
||||
hash ^= (floatHash >> 11);
|
||||
hash += (floatHash << 4);
|
||||
|
|
|
@ -16,9 +16,12 @@
|
|||
#include <QString>
|
||||
#include <QUrl>
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtx/norm.hpp>
|
||||
|
||||
#include "DoubleHashKey.h"
|
||||
|
||||
const float MIN_SHAPE_OFFSET = 0.001f; // offsets less than 1mm will be ignored
|
||||
|
||||
enum ShapeType {
|
||||
SHAPE_TYPE_NONE,
|
||||
SHAPE_TYPE_BOX,
|
||||
|
@ -46,10 +49,12 @@ public:
|
|||
void setEllipsoid(const glm::vec3& halfExtents);
|
||||
void setConvexHulls(const QVector<QVector<glm::vec3>>& points);
|
||||
void setCapsuleY(float radius, float halfHeight);
|
||||
void setOffset(const glm::vec3& offset);
|
||||
|
||||
int getType() const { return _type; }
|
||||
|
||||
const glm::vec3& getHalfExtents() const { return _halfExtents; }
|
||||
const glm::vec3& getOffset() const { return _offset; }
|
||||
|
||||
const QVector<QVector<glm::vec3>>& getPoints() const { return _points; }
|
||||
uint32_t getNumSubShapes() const;
|
||||
|
@ -68,6 +73,7 @@ public:
|
|||
protected:
|
||||
ShapeType _type = SHAPE_TYPE_NONE;
|
||||
glm::vec3 _halfExtents = glm::vec3(0.0f);
|
||||
glm::vec3 _offset = glm::vec3(0.0f);
|
||||
DoubleHashKey _doubleHashKey;
|
||||
QVector<QVector<glm::vec3>> _points; // points for convex collision hulls
|
||||
QUrl _url; // url for model of convex collision hulls
|
||||
|
|
|
@ -62,14 +62,14 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
tree.addEntity(entityID, properties);
|
||||
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius.get();
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x << ","
|
||||
|
@ -103,14 +103,14 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
tree.updateEntity(entityID, properties);
|
||||
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionNearOrigin, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByRadius = tree.findClosestEntity(positionNearOrigin, targetRadius);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius.get();
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x << ","
|
||||
|
@ -143,14 +143,14 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
tree.updateEntity(entityID, properties);
|
||||
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
const AACube& elementCube = containingElement ? containingElement->getAACube() : AACube();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius.get();
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x << ","
|
||||
|
@ -179,17 +179,17 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
quint64 start = usecTimestampNow();
|
||||
const EntityItem* foundEntityByRadius = NULL;
|
||||
EntityItemPointer foundEntityByRadius = NULL;
|
||||
for (int i = 0; i < TEST_ITERATIONS; i++) {
|
||||
foundEntityByRadius = tree.findClosestEntity(positionAtCenter, targetRadius);
|
||||
}
|
||||
quint64 end = usecTimestampNow();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius.get();
|
||||
}
|
||||
|
||||
bool passed = foundEntityByRadius;
|
||||
bool passed = true; // foundEntityByRadius;
|
||||
if (passed) {
|
||||
testsPassed++;
|
||||
} else {
|
||||
|
@ -210,7 +210,7 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
}
|
||||
|
||||
quint64 start = usecTimestampNow();
|
||||
const EntityItem* foundEntityByID = NULL;
|
||||
EntityItemPointer foundEntityByID = NULL;
|
||||
for (int i = 0; i < TEST_ITERATIONS; i++) {
|
||||
// TODO: does this need to be updated??
|
||||
foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
|
@ -218,10 +218,10 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
quint64 end = usecTimestampNow();
|
||||
|
||||
if (verbose) {
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
}
|
||||
|
||||
bool passed = foundEntityByID;
|
||||
bool passed = foundEntityByID.get();
|
||||
if (passed) {
|
||||
testsPassed++;
|
||||
} else {
|
||||
|
@ -278,8 +278,8 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
|
||||
quint64 startFind = usecTimestampNow();
|
||||
float targetRadius = oneMeter * 2.0f;
|
||||
const EntityItem* foundEntityByRadius = tree.findClosestEntity(randomPosition, targetRadius);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByRadius = tree.findClosestEntity(randomPosition, targetRadius);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
quint64 endFind = usecTimestampNow();
|
||||
totalElapsedFind += (endFind - startFind);
|
||||
|
||||
|
@ -289,8 +289,8 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
bool elementIsBestFit = containingElement->bestFitEntityBounds(foundEntityByID);
|
||||
|
||||
if (extraVerbose) {
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "foundEntityByRadius=" << foundEntityByRadius.get();
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "containingElement.box="
|
||||
<< elementCube.getCorner().x << ","
|
||||
|
@ -313,9 +313,10 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
} else {
|
||||
if (extraVerbose) {
|
||||
qDebug() << "FAILED - Test" << testsTaken <<":" << qPrintable(testName) << "iteration:" << i
|
||||
<< "foundEntityByRadius=" << foundEntityByRadius << "foundEntityByID=" << foundEntityByID
|
||||
<< "x/y/z=" << randomX << "," << randomY << "," << randomZ
|
||||
<< "elementIsBestFit=" << elementIsBestFit;
|
||||
//<< "foundEntityByRadius=" << foundEntityByRadius
|
||||
<< "foundEntityByID=" << foundEntityByID.get()
|
||||
<< "x/y/z=" << randomX << "," << randomY << "," << randomZ
|
||||
<< "elementIsBestFit=" << elementIsBestFit;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -368,15 +369,14 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
}
|
||||
|
||||
quint64 startFind = usecTimestampNow();
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
quint64 endFind = usecTimestampNow();
|
||||
totalElapsedFind += (endFind - startFind);
|
||||
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
|
||||
if (extraVerbose) {
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID.get();
|
||||
}
|
||||
|
||||
// Every 1000th test, show the size of the tree...
|
||||
|
@ -390,7 +390,6 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
} else {
|
||||
if (extraVerbose) {
|
||||
qDebug() << "FAILED - Test" << testsTaken <<":" << qPrintable(testName) << "iteration:" << i
|
||||
<< "foundEntityByID=" << foundEntityByID
|
||||
<< "containingElement=" << containingElement;
|
||||
}
|
||||
}
|
||||
|
@ -457,11 +456,11 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
//uint32_t id = 2 + (i * ENTITIES_PER_ITERATION) + j; // These are the entities we added above
|
||||
QUuid id = QUuid::createUuid();// make sure it doesn't collide with previous entity ids
|
||||
EntityItemID entityID(id);
|
||||
const EntityItem* foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityItemPointer foundEntityByID = tree.findEntityByEntityItemID(entityID);
|
||||
EntityTreeElement* containingElement = tree.getContainingElement(entityID);
|
||||
|
||||
if (extraVerbose) {
|
||||
qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
//qDebug() << "foundEntityByID=" << foundEntityByID;
|
||||
qDebug() << "containingElement=" << containingElement;
|
||||
}
|
||||
bool passed = foundEntityByID == NULL && containingElement == NULL;
|
||||
|
@ -470,7 +469,6 @@ void EntityTests::entityTreeTests(bool verbose) {
|
|||
} else {
|
||||
if (extraVerbose) {
|
||||
qDebug() << "FAILED - Test" << testsTaken <<":" << qPrintable(testName) << "iteration:" << i
|
||||
<< "foundEntityByID=" << foundEntityByID
|
||||
<< "containingElement=" << containingElement;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#include <DoubleHashKey.h>
|
||||
#include <ShapeInfo.h>
|
||||
#include <ShapeInfoUtil.h>
|
||||
#include <ShapeFactory.h>
|
||||
#include <StreamUtils.h>
|
||||
|
||||
#include "ShapeInfoTests.h"
|
||||
|
@ -142,7 +142,7 @@ void ShapeInfoTests::testBoxShape() {
|
|||
info.setBox(halfExtents);
|
||||
DoubleHashKey key = info.getHash();
|
||||
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
btCollisionShape* shape = ShapeFactory::createShapeFromInfo(info);
|
||||
if (!shape) {
|
||||
std::cout << __FILE__ << ":" << __LINE__ << " ERROR: NULL Box shape" << std::endl;
|
||||
}
|
||||
|
@ -168,7 +168,7 @@ void ShapeInfoTests::testSphereShape() {
|
|||
info.setSphere(radius);
|
||||
DoubleHashKey key = info.getHash();
|
||||
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
btCollisionShape* shape = ShapeFactory::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo = info;
|
||||
DoubleHashKey otherKey = otherInfo.getHash();
|
||||
|
@ -192,7 +192,7 @@ void ShapeInfoTests::testCylinderShape() {
|
|||
info.setCylinder(radius, height);
|
||||
DoubleHashKey key = info.getHash();
|
||||
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
btCollisionShape* shape = ShapeFactory::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo = info;
|
||||
DoubleHashKey otherKey = otherInfo.getHash();
|
||||
|
@ -217,7 +217,7 @@ void ShapeInfoTests::testCapsuleShape() {
|
|||
info.setCapsule(radius, height);
|
||||
DoubleHashKey key = info.getHash();
|
||||
|
||||
btCollisionShape* shape = ShapeInfoUtil::createShapeFromInfo(info);
|
||||
btCollisionShape* shape = ShapeFactory::createShapeFromInfo(info);
|
||||
|
||||
ShapeInfo otherInfo = info;
|
||||
DoubleHashKey otherKey = otherInfo.getHash();
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
//
|
||||
|
||||
#include <iostream>
|
||||
#include <ShapeInfoUtil.h>
|
||||
#include <ShapeManager.h>
|
||||
#include <StreamUtils.h>
|
||||
|
||||
|
|
Loading…
Reference in a new issue