mirror of
https://github.com/Armored-Dragon/overte.git
synced 2025-03-11 16:13:16 +01:00
wait for objects added to physics before stop SafeLanding
This commit is contained in:
parent
4bc5282039
commit
520c62f6f6
12 changed files with 54 additions and 39 deletions
|
@ -201,6 +201,7 @@ void OtherAvatar::computeShapeLOD() {
|
|||
break;
|
||||
case workload::Region::UNKNOWN:
|
||||
case workload::Region::INVALID:
|
||||
case workload::Region::R4:
|
||||
case workload::Region::R3:
|
||||
default:
|
||||
newLOD = BodyLOD::Sphere;
|
||||
|
|
|
@ -122,9 +122,6 @@ void SafeLanding::updateTracking() {
|
|||
if (isEntityPhysicsReady(entity) && isVisuallyReady) {
|
||||
entityMapIter = _trackedEntities.erase(entityMapIter);
|
||||
} else {
|
||||
if (!isVisuallyReady) {
|
||||
entity->requestRenderUpdate();
|
||||
}
|
||||
entityMapIter++;
|
||||
}
|
||||
}
|
||||
|
@ -203,8 +200,11 @@ bool SafeLanding::isEntityPhysicsReady(const EntityItemPointer& entity) {
|
|||
if (hasAABox && downloadedCollisionTypes.count(modelEntity->getShapeType()) != 0) {
|
||||
auto space = _entityTreeRenderer->getWorkloadSpace();
|
||||
uint8_t region = space ? space->getRegion(entity->getSpaceIndex()) : (uint8_t)workload::Region::INVALID;
|
||||
bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical();
|
||||
return (!shouldBePhysical || entity->isInPhysicsSimulation() || modelEntity->computeShapeFailedToLoad());
|
||||
bool definitelyNotPhysical = (region > workload::Region::R2 && region < workload::Region::UNKNOWN) ||
|
||||
!entity->shouldBePhysical() ||
|
||||
modelEntity->unableToLoadCollisionShape();
|
||||
bool definitelyPhysical = entity->isInPhysicsSimulation();
|
||||
return definitelyNotPhysical || definitelyPhysical;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -282,27 +282,26 @@ bool RenderableModelEntityItem::findDetailedParabolaIntersection(const glm::vec3
|
|||
}
|
||||
|
||||
void RenderableModelEntityItem::fetchCollisionGeometryResource() {
|
||||
_compoundShapeResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCollisionShapeURL());
|
||||
_collisionGeometryResource = DependencyManager::get<ModelCache>()->getCollisionGeometryResource(getCollisionShapeURL());
|
||||
}
|
||||
|
||||
bool RenderableModelEntityItem::computeShapeFailedToLoad() {
|
||||
if (!_compoundShapeResource) {
|
||||
bool RenderableModelEntityItem::unableToLoadCollisionShape() {
|
||||
if (!_collisionGeometryResource) {
|
||||
fetchCollisionGeometryResource();
|
||||
}
|
||||
|
||||
return (_compoundShapeResource && _compoundShapeResource->isFailed());
|
||||
return (_collisionGeometryResource && _collisionGeometryResource->isFailed());
|
||||
}
|
||||
|
||||
void RenderableModelEntityItem::setShapeType(ShapeType type) {
|
||||
ModelEntityItem::setShapeType(type);
|
||||
auto shapeType = getShapeType();
|
||||
if (shapeType == SHAPE_TYPE_COMPOUND || shapeType == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
if (!_compoundShapeResource && !getCollisionShapeURL().isEmpty()) {
|
||||
if (!_collisionGeometryResource && !getCollisionShapeURL().isEmpty()) {
|
||||
fetchCollisionGeometryResource();
|
||||
}
|
||||
} else if (_compoundShapeResource && !getCompoundShapeURL().isEmpty()) {
|
||||
} else if (_collisionGeometryResource && !getCompoundShapeURL().isEmpty()) {
|
||||
// the compoundURL has been set but the shapeType does not agree
|
||||
_compoundShapeResource.reset();
|
||||
_collisionGeometryResource.reset();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,11 +332,11 @@ bool RenderableModelEntityItem::isReadyToComputeShape() const {
|
|||
}
|
||||
|
||||
if (model->isLoaded()) {
|
||||
if (!shapeURL.isEmpty() && !_compoundShapeResource) {
|
||||
if (!shapeURL.isEmpty() && !_collisionGeometryResource) {
|
||||
const_cast<RenderableModelEntityItem*>(this)->fetchCollisionGeometryResource();
|
||||
}
|
||||
|
||||
if (_compoundShapeResource && _compoundShapeResource->isLoaded()) {
|
||||
if (_collisionGeometryResource && _collisionGeometryResource->isLoaded()) {
|
||||
// we have both URLs AND both geometries AND they are both fully loaded.
|
||||
if (_needsInitialSimulation) {
|
||||
// the _model's offset will be wrong until _needsInitialSimulation is false
|
||||
|
@ -368,7 +367,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
}
|
||||
|
||||
if (type == SHAPE_TYPE_COMPOUND) {
|
||||
if (!_compoundShapeResource || !_compoundShapeResource->isLoaded()) {
|
||||
if (!_collisionGeometryResource || !_collisionGeometryResource->isLoaded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -376,8 +375,8 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
|
||||
// should never fall in here when collision model not fully loaded
|
||||
// TODO: assert that all geometries exist and are loaded
|
||||
//assert(_model && _model->isLoaded() && _compoundShapeResource && _compoundShapeResource->isLoaded());
|
||||
const HFMModel& collisionGeometry = _compoundShapeResource->getHFMModel();
|
||||
//assert(_model && _model->isLoaded() && _collisionGeometryResource && _collisionGeometryResource->isLoaded());
|
||||
const HFMModel& collisionGeometry = _collisionGeometryResource->getHFMModel();
|
||||
|
||||
ShapeInfo::PointCollection& pointCollection = shapeInfo.getPointCollection();
|
||||
pointCollection.clear();
|
||||
|
@ -499,7 +498,7 @@ void RenderableModelEntityItem::computeShapeInfo(ShapeInfo& shapeInfo) {
|
|||
|
||||
std::vector<std::shared_ptr<const graphics::Mesh>> meshes;
|
||||
if (type == SHAPE_TYPE_SIMPLE_COMPOUND) {
|
||||
auto& hfmMeshes = _compoundShapeResource->getHFMModel().meshes;
|
||||
auto& hfmMeshes = _collisionGeometryResource->getHFMModel().meshes;
|
||||
meshes.reserve(hfmMeshes.size());
|
||||
for (auto& hfmMesh : hfmMeshes) {
|
||||
meshes.push_back(hfmMesh._mesh);
|
||||
|
@ -727,10 +726,10 @@ int RenderableModelEntityItem::avatarJointIndex(int modelJointIndex) {
|
|||
|
||||
bool RenderableModelEntityItem::contains(const glm::vec3& point) const {
|
||||
auto model = getModel();
|
||||
if (EntityItem::contains(point) && model && _compoundShapeResource && _compoundShapeResource->isLoaded()) {
|
||||
if (EntityItem::contains(point) && model && _collisionGeometryResource && _collisionGeometryResource->isLoaded()) {
|
||||
glm::mat4 worldToHFMMatrix = model->getWorldToHFMMatrix();
|
||||
glm::vec3 hfmPoint = worldToHFMMatrix * glm::vec4(point, 1.0f);
|
||||
return _compoundShapeResource->getHFMModel().convexHullContains(hfmPoint);
|
||||
return _collisionGeometryResource->getHFMModel().convexHullContains(hfmPoint);
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -960,6 +959,10 @@ QStringList RenderableModelEntityItem::getJointNames() const {
|
|||
return result;
|
||||
}
|
||||
|
||||
QString RenderableModelEntityItem::getCollisionShapeURL() const {
|
||||
return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL();
|
||||
}
|
||||
|
||||
scriptable::ScriptableModelBase render::entities::ModelEntityRenderer::getScriptableModel() {
|
||||
auto model = resultWithReadLock<ModelPointer>([this]{ return _model; });
|
||||
|
||||
|
|
|
@ -79,7 +79,7 @@ public:
|
|||
|
||||
virtual bool isReadyToComputeShape() const override;
|
||||
virtual void computeShapeInfo(ShapeInfo& shapeInfo) override;
|
||||
bool computeShapeFailedToLoad();
|
||||
bool unableToLoadCollisionShape();
|
||||
|
||||
virtual bool contains(const glm::vec3& point) const override;
|
||||
void stopModelOverrideIfNoParent();
|
||||
|
@ -113,6 +113,9 @@ public:
|
|||
virtual int getJointIndex(const QString& name) const override;
|
||||
virtual QStringList getJointNames() const override;
|
||||
|
||||
// Returns the URL used for the collision shape
|
||||
QString getCollisionShapeURL() const;
|
||||
|
||||
private:
|
||||
bool needsUpdateModelBounds() const;
|
||||
void autoResizeJointArrays();
|
||||
|
@ -120,7 +123,7 @@ private:
|
|||
bool readyToAnimate() const;
|
||||
void fetchCollisionGeometryResource();
|
||||
|
||||
GeometryResource::Pointer _compoundShapeResource;
|
||||
GeometryResource::Pointer _collisionGeometryResource;
|
||||
std::vector<int> _jointMap;
|
||||
QVariantMap _originalTextures;
|
||||
bool _jointMapCompleted { false };
|
||||
|
|
|
@ -590,10 +590,6 @@ QString ModelEntityItem::getCompoundShapeURL() const {
|
|||
return _compoundShapeURL.get();
|
||||
}
|
||||
|
||||
QString ModelEntityItem::getCollisionShapeURL() const {
|
||||
return getShapeType() == SHAPE_TYPE_COMPOUND ? getCompoundShapeURL() : getModelURL();
|
||||
}
|
||||
|
||||
void ModelEntityItem::setColor(const glm::u8vec3& value) {
|
||||
withWriteLock([&] {
|
||||
_color = value;
|
||||
|
|
|
@ -75,9 +75,6 @@ public:
|
|||
static const QString DEFAULT_COMPOUND_SHAPE_URL;
|
||||
QString getCompoundShapeURL() const;
|
||||
|
||||
// Returns the URL used for the collision shape
|
||||
QString getCollisionShapeURL() const;
|
||||
|
||||
// model related properties
|
||||
virtual void setModelURL(const QString& url);
|
||||
virtual void setCompoundShapeURL(const QString& url);
|
||||
|
|
|
@ -49,9 +49,9 @@ void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) {
|
|||
assert(entity);
|
||||
assert(!entity->isDead());
|
||||
uint8_t region = _space->getRegion(entity->getSpaceIndex());
|
||||
bool shouldBePhysical = region < workload::Region::R3 && entity->shouldBePhysical();
|
||||
bool maybeShouldBePhysical = (region < workload::Region::R3 || region == workload::Region::UNKNOWN) && entity->shouldBePhysical();
|
||||
bool canBeKinematic = region <= workload::Region::R3;
|
||||
if (shouldBePhysical) {
|
||||
if (maybeShouldBePhysical) {
|
||||
EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo());
|
||||
if (motionState) {
|
||||
motionState->setRegion(region);
|
||||
|
@ -330,6 +330,18 @@ void PhysicalEntitySimulation::buildMotionStatesForEntitiesThatNeedThem() {
|
|||
continue;
|
||||
}
|
||||
|
||||
uint8_t region = _space->getRegion(entity->getSpaceIndex());
|
||||
if (region == workload::Region::UNKNOWN) {
|
||||
// the workload hasn't categorized it yet --> skip for later
|
||||
++entityItr;
|
||||
continue;
|
||||
}
|
||||
if (region > workload::Region::R2) {
|
||||
// not in physical zone --> remove from list
|
||||
entityItr = _entitiesToAddToPhysics.erase(entityItr);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (entity->isReadyToComputeShape()) {
|
||||
ShapeRequest shapeRequest(entity);
|
||||
ShapeRequests::iterator requestItr = _shapeRequests.find(shapeRequest);
|
||||
|
|
|
@ -21,6 +21,7 @@ public:
|
|||
R1 = 0,
|
||||
R2,
|
||||
R3,
|
||||
R4,
|
||||
UNKNOWN,
|
||||
INVALID,
|
||||
};
|
||||
|
@ -71,4 +72,4 @@ inline uint8_t Region::computeTransitionIndex(uint8_t prevIndex, uint8_t newInde
|
|||
|
||||
} // namespace workload
|
||||
|
||||
#endif // hifi_workload_Region_h
|
||||
#endif // hifi_workload_Region_h
|
||||
|
|
|
@ -28,7 +28,9 @@ void RegionState::run(const workload::WorkloadContextPointer& renderContext, con
|
|||
// ...
|
||||
// inputs[2N] = vector of ids exiting region N
|
||||
// inputs[2N + 1] = vector of ids entering region N
|
||||
assert(inputs.size() == 2 * Region::UNKNOWN);
|
||||
//
|
||||
// But we only pass inputs for R1 through R3
|
||||
assert(inputs.size() == 2 * (int32_t)(Region::R3 + 1));
|
||||
|
||||
// The id's in each vector are sorted in ascending order
|
||||
// because the source vectors are scanned in ascending order.
|
||||
|
|
|
@ -54,7 +54,7 @@ namespace workload {
|
|||
using JobModel = workload::Job::ModelI<RegionState, Inputs, Config>;
|
||||
|
||||
RegionState() {
|
||||
_state.resize(Region::UNKNOWN);
|
||||
_state.resize(Region::R3 + 1);
|
||||
}
|
||||
|
||||
void configure(const Config& config);
|
||||
|
|
|
@ -33,15 +33,15 @@ void RegionTracker::run(const WorkloadContextPointer& context, Outputs& outputs)
|
|||
//Changes changes;
|
||||
space->categorizeAndGetChanges(outChanges);
|
||||
|
||||
// use exit/enter lists for each region less than Region::UNKNOWN
|
||||
// use exit/enter lists for each region less than Region::R4
|
||||
outRegionChanges.resize(2 * (workload::Region::NUM_CLASSIFICATIONS - 1));
|
||||
for (uint32_t i = 0; i < outChanges.size(); ++i) {
|
||||
Space::Change& change = outChanges[i];
|
||||
if (change.prevRegion < Region::UNKNOWN) {
|
||||
if (change.prevRegion < Region::R4) {
|
||||
// EXIT list index = 2 * regionIndex
|
||||
outRegionChanges[2 * change.prevRegion].push_back(change.proxyId);
|
||||
}
|
||||
if (change.region < Region::UNKNOWN) {
|
||||
if (change.region < Region::R4) {
|
||||
// ENTER list index = 2 * regionIndex + 1
|
||||
outRegionChanges[2 * change.region + 1].push_back(change.proxyId);
|
||||
}
|
||||
|
|
|
@ -99,7 +99,7 @@ void Space::categorizeAndGetChanges(std::vector<Space::Change>& changes) {
|
|||
if (proxy.region < Region::INVALID) {
|
||||
glm::vec3 proxyCenter = glm::vec3(proxy.sphere);
|
||||
float proxyRadius = proxy.sphere.w;
|
||||
uint8_t region = Region::UNKNOWN;
|
||||
uint8_t region = Region::R4;
|
||||
for (uint32_t j = 0; j < numViews; ++j) {
|
||||
auto& view = _views[j];
|
||||
// for each 'view' we need only increment 'k' below the current value of 'region'
|
||||
|
|
Loading…
Reference in a new issue