Fix shape LOD

This commit is contained in:
luiscuenca 2019-01-13 11:30:39 -07:00
parent 19701ef333
commit 65896b3b6f
5 changed files with 103 additions and 20 deletions

View file

@ -413,7 +413,7 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
transaction.objectsToRemove.push_back(mState);
}
}
qCDebug(animation) << "Removing " << detailedMotionStates.size() << " detailed motion states from " << avatar->getSessionUUID();
qDebug() << "Removing " << detailedMotionStates.size() << " detailed motion states from " << avatar->getSessionUUID();
avatar->resetDetailedMotionStates();
} else {
if (avatar->_motionState == nullptr) {
@ -427,20 +427,16 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
transaction.objectsToAdd.push_back(motionState);
}
}
auto& detailedMotionStates = avatar->getDetailedMotionStates();
if (detailedMotionStates.size() == 0) {
for (int i = 0; i < avatar->getJointCount(); i++) {
auto dMotionState = avatar->createDetailedMotionStateForJoint(avatar, i);
if (dMotionState) {
detailedMotionStates.push_back(dMotionState);
transaction.objectsToAdd.push_back(dMotionState);
}
if (avatar->getDetailedMotionStates().size() == 0) {
avatar->createDetailedMotionStates(avatar);
for (auto dMotionState : avatar->getDetailedMotionStates()) {
transaction.objectsToAdd.push_back(dMotionState);
}
if (avatar->_motionState == nullptr || avatar->getDetailedMotionStates().size() == 0) {
failedShapeBuilds.insert(avatar);
}
//qCDebug(animation) << "Creating " << detailedMotionStates.size() << " detailed motion states from " << avatar->getSessionUUID();
}
if (avatar->_motionState == nullptr || detailedMotionStates.size() == 0) {
failedShapeBuilds.insert(avatar);
}
qDebug() << "Adding " << avatar->getDetailedMotionStates().size() << " detailed motion states from " << avatar->getSessionUUID();
}
} else if (isInPhysics) {
transaction.objectsToChange.push_back(avatar->_motionState);
@ -450,7 +446,6 @@ void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transact
transaction.objectsToChange.push_back(mState);
}
}
//qCDebug(animation) << "Updating " << detailedMotionStates.size() << " detailed motion states from " << avatar->getSessionUUID();
}
}
_avatarsToChangeInPhysics.swap(failedShapeBuilds);

View file

@ -60,7 +60,13 @@ const btCollisionShape* DetailedMotionState::computeNewShape() {
btCollisionShape* shape = nullptr;
if (!_avatar->isMyAvatar()) {
OtherAvatarPointer otherAvatar = std::static_pointer_cast<OtherAvatar>(_avatar);
shape = otherAvatar->createDetailedCollisionShapeForJoint(_jointIndex);
if (otherAvatar) {
if (_isAvatarCapsule) {
shape = otherAvatar->createCapsuleCollisionShape();
} else {
shape = otherAvatar->createDetailedCollisionShapeForJoint(_jointIndex);
}
}
} else {
std::shared_ptr<MyAvatar> myAvatar = std::static_pointer_cast<MyAvatar>(_avatar);
shape = myAvatar->getCharacterController()->createDetailedCollisionShapeForJoint(_jointIndex);
@ -109,7 +115,7 @@ float DetailedMotionState::getObjectAngularDamping() const {
// virtual
glm::vec3 DetailedMotionState::getObjectPosition() const {
return _avatar->getJointPosition(_jointIndex);
return _isAvatarCapsule ? _avatar->getFitBounds().calcCenter() : _avatar->getJointPosition(_jointIndex);
}
// virtual

View file

@ -70,6 +70,7 @@ public:
void forceActive();
QUuid getAvatarID() { return _avatar->getID(); }
int getJointIndex() { return _jointIndex; }
void setIsAvatarCapsule(bool isAvatarCapsule) { _isAvatarCapsule = isAvatarCapsule; }
friend class AvatarManager;
friend class Avatar;
@ -90,6 +91,8 @@ protected:
uint32_t _dirtyFlags;
int _jointIndex { -1 };
bool _isAvatarCapsule { false };
};
#endif // hifi_DetailedMotionState_h

View file

@ -122,6 +122,17 @@ btCollisionShape* OtherAvatar::createDetailedCollisionShapeForJoint(int jointInd
return nullptr;
}
btCollisionShape* OtherAvatar::createCapsuleCollisionShape() {
ShapeInfo shapeInfo;
computeShapeInfo(shapeInfo);
shapeInfo.setOffset(glm::vec3(0.0f));
if (shapeInfo.getType() != SHAPE_TYPE_NONE) {
btCollisionShape* shape = const_cast<btCollisionShape*>(ObjectMotionState::getShapeManager()->getShape(shapeInfo));
return shape;
}
return nullptr;
}
DetailedMotionState* OtherAvatar::createDetailedMotionStateForJoint(std::shared_ptr<OtherAvatar> avatar, int jointIndex) {
auto shape = createDetailedCollisionShapeForJoint(jointIndex);
if (shape) {
@ -132,6 +143,17 @@ DetailedMotionState* OtherAvatar::createDetailedMotionStateForJoint(std::shared_
return nullptr;
}
DetailedMotionState* OtherAvatar::createCapsuleMotionState(std::shared_ptr<OtherAvatar> avatar) {
auto shape = createCapsuleCollisionShape();
if (shape) {
DetailedMotionState* motionState = new DetailedMotionState(avatar, shape, -1);
motionState->setIsAvatarCapsule(true);
motionState->setMass(computeMass());
return motionState;
}
return nullptr;
}
void OtherAvatar::resetDetailedMotionStates() {
for (size_t i = 0; i < _detailedMotionStates.size(); i++) {
_detailedMotionStates[i] = nullptr;
@ -141,15 +163,42 @@ void OtherAvatar::resetDetailedMotionStates() {
void OtherAvatar::setWorkloadRegion(uint8_t region) {
_workloadRegion = region;
QString printRegion = "";
if (region == workload::Region::R1) {
printRegion = "R1";
} else if (region == workload::Region::R2) {
printRegion = "R2";
} else if (region == workload::Region::R3) {
printRegion = "R3";
} else {
printRegion = "invalid";
}
qDebug() << "Setting workload region to " << printRegion;
computeShapeLOD();
}
void OtherAvatar::computeShapeLOD() {
auto newBodyLOD = (_workloadRegion < workload::Region::R3 && !isDead()) ? BodyLOD::MultiSphereShapes : BodyLOD::CapsuleShape;
if (newBodyLOD != _bodyLOD) {
_bodyLOD = newBodyLOD;
if (isInPhysicsSimulation()) {
qDebug() << "Changing to body LOD " << (_bodyLOD == BodyLOD::MultiSphereShapes ? "MultiSpheres" : "Capsule");
_needsReinsertion = true;
}
}
}
bool OtherAvatar::isInPhysicsSimulation() const {
return _motionState != nullptr && _detailedMotionStates.size() > 0;
}
bool OtherAvatar::shouldBeInPhysicsSimulation() const {
return (_workloadRegion < workload::Region::R3 && !isDead());
return !(isInPhysicsSimulation() && _needsReinsertion);
}
bool OtherAvatar::needsPhysicsUpdate() const {
constexpr uint32_t FLAGS_OF_INTEREST = Simulation::DIRTY_SHAPE | Simulation::DIRTY_MASS | Simulation::DIRTY_POSITION | Simulation::DIRTY_COLLISION_GROUP;
return (_motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST));
return (_needsReinsertion || _motionState && (bool)(_motionState->getIncomingDirtyFlags() & FLAGS_OF_INTEREST));
}
void OtherAvatar::rebuildCollisionShape() {
@ -175,4 +224,22 @@ void OtherAvatar::updateCollisionGroup(bool myAvatarCollide) {
_motionState->addDirtyFlags(Simulation::DIRTY_COLLISION_GROUP);
}
}
}
}
void OtherAvatar::createDetailedMotionStates(const std::shared_ptr<OtherAvatar>& avatar){
auto& detailedMotionStates = getDetailedMotionStates();
if (_bodyLOD == BodyLOD::MultiSphereShapes) {
for (int i = 0; i < getJointCount(); i++) {
auto dMotionState = createDetailedMotionStateForJoint(avatar, i);
if (dMotionState) {
detailedMotionStates.push_back(dMotionState);
}
}
} else if (_bodyLOD == BodyLOD::CapsuleShape) {
auto dMotionState = createCapsuleMotionState(avatar);
if (dMotionState) {
detailedMotionStates.push_back(dMotionState);
}
}
_needsReinsertion = false;
}

View file

@ -27,6 +27,11 @@ public:
explicit OtherAvatar(QThread* thread);
virtual ~OtherAvatar();
enum BodyLOD {
CapsuleShape,
MultiSphereShapes
};
virtual void instantiableAvatar() override { };
virtual void createOrb() override;
virtual void indicateLoadingStatus(LoadingStatus loadingStatus) override;
@ -39,7 +44,7 @@ public:
int parseDataFromBuffer(const QByteArray& buffer) override;
bool isInPhysicsSimulation() const { return _motionState != nullptr && _detailedMotionStates.size() > 0; }
bool isInPhysicsSimulation() const;
void rebuildCollisionShape() override;
void setWorkloadRegion(uint8_t region);
@ -47,9 +52,14 @@ public:
bool needsPhysicsUpdate() const;
btCollisionShape* createDetailedCollisionShapeForJoint(int jointIndex);
btCollisionShape* createCapsuleCollisionShape();
DetailedMotionState* createDetailedMotionStateForJoint(std::shared_ptr<OtherAvatar> avatar, int jointIndex);
DetailedMotionState* createCapsuleMotionState(std::shared_ptr<OtherAvatar> avatar);
void createDetailedMotionStates(const std::shared_ptr<OtherAvatar>& avatar);
std::vector<DetailedMotionState*>& getDetailedMotionStates() { return _detailedMotionStates; }
void resetDetailedMotionStates();
BodyLOD getBodyLOD() { return _bodyLOD; }
void computeShapeLOD();
void updateCollisionGroup(bool myAvatarCollide);
@ -62,6 +72,8 @@ protected:
std::vector<DetailedMotionState*> _detailedMotionStates;
int32_t _spaceIndex { -1 };
uint8_t _workloadRegion { workload::Region::INVALID };
BodyLOD _bodyLOD { BodyLOD::CapsuleShape };
bool _needsReinsertion { false };
};
using OtherAvatarPointer = std::shared_ptr<OtherAvatar>;