void PhysicalEntitySimulation::changeEntityInternal(EntityItemPointer entity) { // queue incoming changes: from external sources (script, EntityServer, etc) to physics engine QMutexLocker lock(&_mutex); assert(entity); EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo()); if (motionState) { if (!entity->shouldBePhysical()) { // the entity should be removed from the physical simulation _pendingChanges.remove(motionState); _physicalObjects.remove(motionState); _outgoingChanges.remove(motionState); _entitiesToRemoveFromPhysics.insert(entity); if (entity->isMovingRelativeToParent()) { _simpleKinematicEntities.insert(entity); } } else { _pendingChanges.insert(motionState); } } else if (entity->shouldBePhysical()) { // The intent is for this object to be in the PhysicsEngine, but it has no MotionState yet. // Perhaps it's shape has changed and it can now be added? _entitiesToAddToPhysics.insert(entity); _simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic } else if (entity->isMovingRelativeToParent()) { _simpleKinematicEntities.insert(entity); } else { _simpleKinematicEntities.remove(entity); // just in case it's non-physical-kinematic } }
void EntityRenderer::doRenderUpdateSynchronous(const ScenePointer& scene, Transaction& transaction, const EntityItemPointer& entity) { DETAILED_PROFILE_RANGE(simulation_physics, __FUNCTION__); withWriteLock([&] { auto transparent = isTransparent(); if (_prevIsTransparent && !transparent) { _isFading = false; } _prevIsTransparent = transparent; bool success = false; auto bound = entity->getAABox(success); if (success) { _bound = bound; } auto newModelTransform = entity->getTransformToCenter(success); if (success) { _modelTransform = newModelTransform; } _moving = entity->isMovingRelativeToParent(); _visible = entity->getVisible(); _canCastShadow = entity->getCanCastShadow(); _cauterized = entity->getCauterized(); _needsRenderUpdate = false; }); }
void EntitySimulation::addEntityInternal(EntityItemPointer entity) { if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) { QMutexLocker lock(&_mutex); _simpleKinematicEntities.insert(entity); entity->setLastSimulated(usecTimestampNow()); } }
void PhysicalEntitySimulation::getObjectsToAddToPhysics(VectorOfMotionStates& result) { result.clear(); QMutexLocker lock(&_mutex); SetOfEntities::iterator entityItr = _entitiesToAddToPhysics.begin(); while (entityItr != _entitiesToAddToPhysics.end()) { EntityItemPointer entity = (*entityItr); assert(!entity->getPhysicsInfo()); if (entity->isDead()) { prepareEntityForDelete(entity); } else if (!entity->shouldBePhysical()) { // this entity should no longer be on the internal _entitiesToAddToPhysics entityItr = _entitiesToAddToPhysics.erase(entityItr); if (entity->isMovingRelativeToParent()) { _simpleKinematicEntities.insert(entity); } } else if (entity->isReadyToComputeShape()) { ShapeInfo shapeInfo; entity->computeShapeInfo(shapeInfo); btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo); if (shape) { EntityMotionState* motionState = new EntityMotionState(shape, entity); entity->setPhysicsInfo(static_cast<void*>(motionState)); _physicalObjects.insert(motionState); result.push_back(motionState); entityItr = _entitiesToAddToPhysics.erase(entityItr); } else { //qDebug() << "Warning! Failed to generate new shape for entity." << entity->getName(); ++entityItr; } } else { ++entityItr; } } }
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) { QMutexLocker lock(&_mutex); if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) { _simpleKinematicEntities.insert(entity); } else { _simpleKinematicEntities.remove(entity); } }
void EntitySimulation::changeEntityInternal(EntityItemPointer entity) { QMutexLocker lock(&_mutex); if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) { int numKinematicEntities = _simpleKinematicEntities.size(); _simpleKinematicEntities.insert(entity); if (numKinematicEntities != _simpleKinematicEntities.size()) { entity->setLastSimulated(usecTimestampNow()); } } else { _simpleKinematicEntities.remove(entity); } }
void PhysicalEntitySimulation::addEntityInternal(EntityItemPointer entity) { QMutexLocker lock(&_mutex); assert(entity); assert(!entity->isDead()); if (entity->shouldBePhysical()) { EntityMotionState* motionState = static_cast<EntityMotionState*>(entity->getPhysicsInfo()); if (!motionState) { _entitiesToAddToPhysics.insert(entity); } } else if (entity->isMovingRelativeToParent()) { _simpleKinematicEntities.insert(entity); } }
void EntitySimulation::moveSimpleKinematics(const quint64& now) { SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin(); while (itemItr != _simpleKinematicEntities.end()) { EntityItemPointer entity = *itemItr; if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo()) { entity->simulate(now); _entitiesToSort.insert(entity); ++itemItr; } else { // the entity is no longer non-physical-kinematic itemItr = _simpleKinematicEntities.erase(itemItr); } } }
// Returns true if the item in question needs to have updateInScene called because of changes in the entity bool EntityRenderer::needsRenderUpdateFromEntity(const EntityItemPointer& entity) const { bool success = false; auto bound = _entity->getAABox(success); if (success && _bound != bound) { return true; } auto newModelTransform = _entity->getTransformToCenter(success); // FIXME can we use a stale model transform here? if (success && newModelTransform != _modelTransform) { return true; } if (_moving != entity->isMovingRelativeToParent()) { return true; } return false; }
void EntitySimulation::moveSimpleKinematics(const quint64& now) { SetOfEntities::iterator itemItr = _simpleKinematicEntities.begin(); while (itemItr != _simpleKinematicEntities.end()) { EntityItemPointer entity = *itemItr; // The entity-server doesn't know where avatars are, so don't attempt to do simple extrapolation for // children of avatars. See related code in EntityMotionState::remoteSimulationOutOfSync. bool ancestryIsKnown; entity->getMaximumAACube(ancestryIsKnown); bool hasAvatarAncestor = entity->hasAncestorOfType(NestableType::Avatar); if (entity->isMovingRelativeToParent() && !entity->getPhysicsInfo() && ancestryIsKnown && !hasAvatarAncestor) { entity->simulate(now); _entitiesToSort.insert(entity); ++itemItr; } else { // the entity is no longer non-physical-kinematic itemItr = _simpleKinematicEntities.erase(itemItr); } } }