Esempio n. 1
0
// protected
void AvatarManager::removeAvatarMotionState(AvatarSharedPointer avatar) {
    auto rawPointer = std::static_pointer_cast<Avatar>(avatar);
    AvatarMotionState* motionState = rawPointer->getMotionState();
    if (motionState) {
        // clean up physics stuff
        motionState->clearObjectBackPointer();
        rawPointer->setMotionState(nullptr);
        _avatarMotionStates.remove(motionState);
        _motionStatesToAdd.remove(motionState);
        _motionStatesToDelete.push_back(motionState);
    }
}
Esempio n. 2
0
void AvatarManager::rebuildAvatarPhysics(PhysicsEngine::Transaction& transaction, OtherAvatarPointer avatar) {
    if (!avatar->_motionState) {
        avatar->_motionState = new AvatarMotionState(avatar, nullptr);
    }
    AvatarMotionState* motionState = avatar->_motionState;
    ShapeInfo shapeInfo;
    avatar->computeShapeInfo(shapeInfo);
    const btCollisionShape* shape = ObjectMotionState::getShapeManager()->getShape(shapeInfo);
    assert(shape);
    motionState->setShape(shape);
    motionState->setMass(avatar->computeMass());
    if (motionState->getRigidBody()) {
        transaction.objectsToReinsert.push_back(motionState);
    } else {
        transaction.objectsToAdd.push_back(motionState);
    }
    motionState->clearIncomingDirtyFlags();

    // Rather than reconcile numbers of joints after change to model or LOD
    // we blow away old detailedMotionStates and create anew all around.

    // delete old detailedMotionStates
    auto& detailedMotionStates = avatar->getDetailedMotionStates();
    if (detailedMotionStates.size() != 0) {
        for (auto& detailedMotionState : detailedMotionStates) {
            transaction.objectsToRemove.push_back(detailedMotionState);
        }
        avatar->resetDetailedMotionStates();
    }

    // build new detailedMotionStates
    OtherAvatar::BodyLOD lod = avatar->getBodyLOD();
    if (lod == OtherAvatar::BodyLOD::Sphere) {
        auto dMotionState = createDetailedMotionState(avatar, -1);
        if (dMotionState) {
            detailedMotionStates.push_back(dMotionState);
            transaction.objectsToAdd.push_back(dMotionState);
        }
    } else {
        int32_t numJoints = avatar->getJointCount();
        for (int32_t i = 0; i < numJoints; i++) {
            auto dMotionState = createDetailedMotionState(avatar, i);
            if (dMotionState) {
                detailedMotionStates.push_back(dMotionState);
                transaction.objectsToAdd.push_back(dMotionState);
            }
        }
    }
    avatar->_needsReinsertion = false;
}
Esempio n. 3
0
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
    SetOfOtherAvatars failedShapeBuilds;
    for (auto avatar : _avatarsToChangeInPhysics) {
        bool isInPhysics = avatar->isInPhysicsSimulation();
        if (isInPhysics != avatar->shouldBeInPhysicsSimulation()) {
            if (isInPhysics) {
                transaction.objectsToRemove.push_back(avatar->_motionState);
                avatar->_motionState = nullptr;
                auto& detailedMotionStates = avatar->getDetailedMotionStates();
                for (auto& mState : detailedMotionStates) {
                    transaction.objectsToRemove.push_back(mState);
                }
                avatar->resetDetailedMotionStates();
            } else {
                if (avatar->getDetailedMotionStates().size() == 0) {
                    avatar->createDetailedMotionStates(avatar);
                    for (auto dMotionState : avatar->getDetailedMotionStates()) {
                        transaction.objectsToAdd.push_back(dMotionState);
                    }
                }
                if (avatar->getDetailedMotionStates().size() > 0) {
                    ShapeInfo shapeInfo;
                    avatar->computeShapeInfo(shapeInfo);
                    btCollisionShape* shape = const_cast<btCollisionShape*>(ObjectMotionState::getShapeManager()->getShape(shapeInfo));
                    if (shape) {
                        AvatarMotionState* motionState = new AvatarMotionState(avatar, shape);
                        motionState->setMass(avatar->computeMass());
                        avatar->_motionState = motionState;
                        transaction.objectsToAdd.push_back(motionState);
                    } else {
                        failedShapeBuilds.insert(avatar);
                    }
                } else {
                    failedShapeBuilds.insert(avatar);
                }
            }
        } else if (isInPhysics) {
            transaction.objectsToChange.push_back(avatar->_motionState);
            
            auto& detailedMotionStates = avatar->getDetailedMotionStates();
            for (auto& mState : detailedMotionStates) {
                if (mState) {
                    transaction.objectsToChange.push_back(mState);
                }
            }
            
        }
    }
    _avatarsToChangeInPhysics.swap(failedShapeBuilds);
}
Esempio n. 4
0
void AvatarManager::buildPhysicsTransaction(PhysicsEngine::Transaction& transaction) {
    _myAvatar->getCharacterController()->buildPhysicsTransaction(transaction);
    for (auto avatar : _otherAvatarsToChangeInPhysics) {
        bool isInPhysics = avatar->isInPhysicsSimulation();
        if (isInPhysics != avatar->shouldBeInPhysicsSimulation()) {
            if (isInPhysics) {
                transaction.objectsToRemove.push_back(avatar->_motionState);
                avatar->_motionState = nullptr;
                auto& detailedMotionStates = avatar->getDetailedMotionStates();
                for (auto& motionState : detailedMotionStates) {
                    transaction.objectsToRemove.push_back(motionState);
                }
                avatar->resetDetailedMotionStates();
            } else {
                rebuildAvatarPhysics(transaction, avatar);
            }
        } else if (isInPhysics) {
            AvatarMotionState* motionState = avatar->_motionState;
            uint32_t flags = motionState->getIncomingDirtyFlags();
            if (flags & EASY_DIRTY_PHYSICS_FLAGS) {
                motionState->handleEasyChanges(flags);
            }
            // NOTE: we don't call detailedMotionState->handleEasyChanges() here because they are KINEMATIC
            // and Bullet will automagically call DetailedMotionState::getWorldTransform() on all that are active.

            if (motionState->needsNewShape()) {
                rebuildAvatarPhysics(transaction, avatar);
            } else {
                if (flags & (Simulation::DIRTY_MOTION_TYPE | Simulation::DIRTY_COLLISION_GROUP)) {
                    transaction.objectsToReinsert.push_back(motionState);
                }
                motionState->clearIncomingDirtyFlags();
            }
        }
    }
}