mirror of
https://github.com/HifiExperiments/overte.git
synced 2025-08-04 02:33:09 +02:00
135 lines
4.7 KiB
C++
135 lines
4.7 KiB
C++
//
|
|
// PhysicalEntitySimulation.h
|
|
// libraries/physics/src
|
|
//
|
|
// Created by Andrew Meadows 2015.04.27
|
|
// 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_PhysicalEntitySimulation_h
|
|
#define hifi_PhysicalEntitySimulation_h
|
|
|
|
#include <stdint.h>
|
|
#include <map>
|
|
#include <set>
|
|
|
|
#include <btBulletDynamicsCommon.h>
|
|
#include <BulletCollision/CollisionDispatch/btGhostObject.h>
|
|
|
|
#include <EntityItem.h>
|
|
#include <EntitySimulation.h>
|
|
#include <workload/Space.h>
|
|
|
|
#include "PhysicsEngine.h"
|
|
#include "EntityMotionState.h"
|
|
|
|
class PhysicalEntitySimulation;
|
|
using PhysicalEntitySimulationPointer = std::shared_ptr<PhysicalEntitySimulation>;
|
|
using SetOfEntityMotionStates = QSet<EntityMotionState*>;
|
|
|
|
class VectorOfEntityMotionStates: public std::vector<EntityMotionState*> {
|
|
public:
|
|
void remove(uint32_t index) {
|
|
assert(index < size());
|
|
if (index < size() - 1) {
|
|
(*this)[index] = back();
|
|
}
|
|
pop_back();
|
|
}
|
|
void removeFirst(EntityMotionState* state) {
|
|
for (uint32_t i = 0; i < size(); ++i) {
|
|
if ((*this)[i] == state) {
|
|
remove(i);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
};
|
|
|
|
class PhysicalEntitySimulation : public EntitySimulation {
|
|
Q_OBJECT
|
|
public:
|
|
PhysicalEntitySimulation();
|
|
~PhysicalEntitySimulation();
|
|
|
|
void init(EntityTreePointer tree, PhysicsEnginePointer engine, EntityEditPacketSender* packetSender);
|
|
void setWorkloadSpace(const workload::SpacePointer space) { _space = space; }
|
|
|
|
virtual void addDynamic(EntityDynamicPointer dynamic) override;
|
|
virtual void applyDynamicChanges() override;
|
|
|
|
virtual void takeDeadEntities(SetOfEntities& deadEntities) override;
|
|
void takeDeadAvatarEntities(SetOfEntities& deadEntities);
|
|
|
|
signals:
|
|
void entityCollisionWithEntity(const EntityItemID& idA, const EntityItemID& idB, const Collision& collision);
|
|
|
|
protected: // only called by EntitySimulation
|
|
// overrides for EntitySimulation
|
|
virtual void updateEntitiesInternal(uint64_t now) override;
|
|
virtual void addEntityInternal(EntityItemPointer entity) override;
|
|
virtual void removeEntityInternal(EntityItemPointer entity) override;
|
|
void processChangedEntity(const EntityItemPointer& entity) override;
|
|
virtual void clearEntitiesInternal() override;
|
|
|
|
void removeOwnershipData(EntityMotionState* motionState);
|
|
void clearOwnershipData();
|
|
|
|
public:
|
|
virtual void prepareEntityForDelete(EntityItemPointer entity) override;
|
|
void removeDeadEntities();
|
|
|
|
void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
|
void handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction);
|
|
|
|
void handleDeactivatedMotionStates(const VectorOfMotionStates& motionStates);
|
|
void handleChangedMotionStates(const VectorOfMotionStates& motionStates);
|
|
void handleCollisionEvents(const CollisionEvents& collisionEvents);
|
|
|
|
EntityEditPacketSender* getPacketSender() { return _entityPacketSender; }
|
|
|
|
void addOwnershipBid(EntityMotionState* motionState);
|
|
void addOwnership(EntityMotionState* motionState);
|
|
void sendOwnershipBids(uint32_t numSubsteps);
|
|
void sendOwnedUpdates(uint32_t numSubsteps);
|
|
|
|
private:
|
|
void buildMotionStatesForEntitiesThatNeedThem();
|
|
|
|
class ShapeRequest {
|
|
public:
|
|
ShapeRequest() { }
|
|
ShapeRequest(const EntityItemPointer& e) : entity(e) { }
|
|
bool operator<(const ShapeRequest& other) const { return entity.get() < other.entity.get(); }
|
|
bool operator==(const ShapeRequest& other) const { return entity.get() == other.entity.get(); }
|
|
EntityItemPointer entity { nullptr };
|
|
mutable uint64_t shapeHash { 0 };
|
|
};
|
|
SetOfEntities _entitiesToAddToPhysics; // we could also call this: _entitiesThatNeedMotionStates
|
|
SetOfEntities _entitiesToRemoveFromPhysics;
|
|
SetOfEntityMotionStates _incomingChanges; // EntityMotionStates changed by external events
|
|
SetOfMotionStates _physicalObjects; // MotionStates of entities in PhysicsEngine
|
|
|
|
using ShapeRequests = std::set<ShapeRequest>;
|
|
ShapeRequests _shapeRequests;
|
|
|
|
PhysicsEnginePointer _physicsEngine = nullptr;
|
|
EntityEditPacketSender* _entityPacketSender = nullptr;
|
|
|
|
VectorOfEntityMotionStates _owned;
|
|
VectorOfEntityMotionStates _bids;
|
|
SetOfEntities _deadAvatarEntities;
|
|
std::vector<EntityItemPointer> _entitiesToDeleteLater;
|
|
workload::SpacePointer _space;
|
|
uint64_t _nextBidExpiry;
|
|
uint32_t _lastStepSendPackets { 0 };
|
|
uint32_t _lastWorkDeliveryCount { 0 };
|
|
};
|
|
|
|
|
|
typedef std::shared_ptr<PhysicalEntitySimulation> PhysicalEntitySimulationPointer;
|
|
|
|
#endif // hifi_PhysicalEntitySimulation_h
|