Ejemplo n.º 1
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;
}
Ejemplo n.º 2
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();
            }
        }
    }
}