mirror of
https://github.com/JulianGro/overte.git
synced 2025-04-25 20:55:10 +02:00
224 lines
8.1 KiB
C++
224 lines
8.1 KiB
C++
//
|
|
// SimpleEntitySimulation.cpp
|
|
// libraries/entities/src
|
|
//
|
|
// Created by Andrew Meadows on 2014.11.24
|
|
// Copyright 2014 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 <AACube.h>
|
|
#include <PerfStat.h>
|
|
|
|
#include "EntityItem.h"
|
|
#include "MovingEntitiesOperator.h"
|
|
#include "SimpleEntitySimulation.h"
|
|
|
|
void SimpleEntitySimulation::update(QSet<EntityItem*>& entitiesToDelete) {
|
|
quint64 now = usecTimestampNow();
|
|
updateChangedEntities(now, entitiesToDelete);
|
|
updateMovingEntities(now, entitiesToDelete);
|
|
updateMortalEntities(now, entitiesToDelete);
|
|
}
|
|
|
|
void SimpleEntitySimulation::addEntity(EntityItem* entity) {
|
|
assert(entity && entity->getSimulationState() == EntityItem::Static);
|
|
EntityItem::SimulationState state = entity->computeSimulationState();
|
|
switch(state) {
|
|
case EntityItem::Moving:
|
|
_movingEntities.push_back(entity);
|
|
entity->setSimulationState(state);
|
|
break;
|
|
case EntityItem::Mortal:
|
|
_mortalEntities.push_back(entity);
|
|
entity->setSimulationState(state);
|
|
break;
|
|
case EntityItem::Static:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
void SimpleEntitySimulation::removeEntity(EntityItem* entity) {
|
|
assert(entity);
|
|
// make sure to remove it from any of our simulation lists
|
|
EntityItem::SimulationState state = entity->getSimulationState();
|
|
switch (state) {
|
|
case EntityItem::Moving:
|
|
_movingEntities.removeAll(entity);
|
|
break;
|
|
case EntityItem::Mortal:
|
|
_mortalEntities.removeAll(entity);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
entity->setSimulationState(EntityItem::Static);
|
|
_changedEntities.remove(entity);
|
|
}
|
|
|
|
void SimpleEntitySimulation::entityChanged(EntityItem* entity) {
|
|
assert(entity);
|
|
// we batch all changes and deal with them in updateChangedEntities()
|
|
_changedEntities.insert(entity);
|
|
}
|
|
|
|
void SimpleEntitySimulation::clearEntities() {
|
|
foreach (EntityItem* entity, _changedEntities) {
|
|
entity->clearUpdateFlags();
|
|
entity->setSimulationState(EntityItem::Static);
|
|
}
|
|
_changedEntities.clear();
|
|
_movingEntities.clear();
|
|
_mortalEntities.clear();
|
|
}
|
|
|
|
void SimpleEntitySimulation::updateChangedEntities(quint64 now, QSet<EntityItem*>& entitiesToDelete) {
|
|
foreach (EntityItem* entity, _changedEntities) {
|
|
// check to see if the lifetime has expired, for immortal entities this is always false
|
|
if (entity->lifetimeHasExpired()) {
|
|
qDebug() << "Lifetime has expired for entity:" << entity->getEntityItemID();
|
|
entitiesToDelete.insert(entity);
|
|
clearEntityState(entity);
|
|
} else {
|
|
updateEntityState(entity);
|
|
}
|
|
entity->clearUpdateFlags();
|
|
}
|
|
_changedEntities.clear();
|
|
}
|
|
|
|
void SimpleEntitySimulation::updateMovingEntities(quint64 now, QSet<EntityItem*>& entitiesToDelete) {
|
|
if (_entityTree && _movingEntities.size() > 0) {
|
|
PerformanceTimer perfTimer("_movingEntities");
|
|
MovingEntitiesOperator moveOperator(_entityTree);
|
|
QList<EntityItem*>::iterator item_itr = _movingEntities.begin();
|
|
while (item_itr != _movingEntities.end()) {
|
|
EntityItem* entity = *item_itr;
|
|
|
|
// always check to see if the lifetime has expired, for immortal entities this is always false
|
|
if (entity->lifetimeHasExpired()) {
|
|
qDebug() << "Lifetime has expired for entity:" << entity->getEntityItemID();
|
|
entitiesToDelete.insert(entity);
|
|
// remove entity from the list
|
|
item_itr = _movingEntities.erase(item_itr);
|
|
entity->setSimulationState(EntityItem::Static);
|
|
} else {
|
|
AACube oldCube = entity->getMaximumAACube();
|
|
entity->update(now);
|
|
AACube newCube = entity->getMaximumAACube();
|
|
|
|
// check to see if this movement has sent the entity outside of the domain.
|
|
AACube domainBounds(glm::vec3(0.0f,0.0f,0.0f), 1.0f);
|
|
if (!domainBounds.touches(newCube)) {
|
|
qDebug() << "Entity " << entity->getEntityItemID() << " moved out of domain bounds.";
|
|
entitiesToDelete.insert(entity);
|
|
// remove entity from the list
|
|
item_itr = _movingEntities.erase(item_itr);
|
|
entity->setSimulationState(EntityItem::Static);
|
|
} else {
|
|
moveOperator.addEntityToMoveList(entity, oldCube, newCube);
|
|
EntityItem::SimulationState newState = entity->computeSimulationState();
|
|
if (newState != EntityItem::Moving) {
|
|
if (newState == EntityItem::Mortal) {
|
|
_mortalEntities.push_back(entity);
|
|
}
|
|
// remove entity from the list
|
|
item_itr = _movingEntities.erase(item_itr);
|
|
entity->setSimulationState(newState);
|
|
} else {
|
|
++item_itr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if (moveOperator.hasMovingEntities()) {
|
|
PerformanceTimer perfTimer("recurseTreeWithOperator");
|
|
_entityTree->recurseTreeWithOperator(&moveOperator);
|
|
}
|
|
}
|
|
}
|
|
|
|
void SimpleEntitySimulation::updateMortalEntities(quint64 now, QSet<EntityItem*>& entitiesToDelete) {
|
|
QList<EntityItem*>::iterator item_itr = _mortalEntities.begin();
|
|
while (item_itr != _mortalEntities.end()) {
|
|
EntityItem* entity = *item_itr;
|
|
// always check to see if the lifetime has expired, for immortal entities this is always false
|
|
if (entity->lifetimeHasExpired()) {
|
|
qDebug() << "Lifetime has expired for entity:" << entity->getEntityItemID();
|
|
entitiesToDelete.insert(entity);
|
|
// remove entity from the list
|
|
item_itr = _mortalEntities.erase(item_itr);
|
|
entity->setSimulationState(EntityItem::Static);
|
|
} else {
|
|
// check to see if this entity is no longer moving
|
|
EntityItem::SimulationState newState = entity->computeSimulationState();
|
|
if (newState != EntityItem::Mortal) {
|
|
if (newState == EntityItem::Moving) {
|
|
entity->update(now);
|
|
_movingEntities.push_back(entity);
|
|
}
|
|
// remove entity from the list
|
|
item_itr = _mortalEntities.erase(item_itr);
|
|
entity->setSimulationState(newState);
|
|
} else {
|
|
++item_itr;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void SimpleEntitySimulation::updateEntityState(EntityItem* entity) {
|
|
EntityItem::SimulationState oldState = entity->getSimulationState();
|
|
EntityItem::SimulationState newState = entity->computeSimulationState();
|
|
if (newState != oldState) {
|
|
switch (oldState) {
|
|
case EntityItem::Moving:
|
|
_movingEntities.removeAll(entity);
|
|
break;
|
|
|
|
case EntityItem::Mortal:
|
|
_mortalEntities.removeAll(entity);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
switch (newState) {
|
|
case EntityItem::Moving:
|
|
_movingEntities.push_back(entity);
|
|
break;
|
|
|
|
case EntityItem::Mortal:
|
|
_mortalEntities.push_back(entity);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
entity->setSimulationState(newState);
|
|
}
|
|
}
|
|
|
|
void SimpleEntitySimulation::clearEntityState(EntityItem* entity) {
|
|
EntityItem::SimulationState oldState = entity->getSimulationState();
|
|
switch (oldState) {
|
|
case EntityItem::Moving:
|
|
_movingEntities.removeAll(entity);
|
|
break;
|
|
|
|
case EntityItem::Mortal:
|
|
_mortalEntities.removeAll(entity);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
entity->setSimulationState(EntityItem::Static);
|
|
}
|
|
|
|
|