Exemplo n.º 1
0
void ModeProperty::apply(LocatedEntity *entity)
{

    if (m_data == "planted") {
        //See if there's a rotation we should apply
        const auto* plantedRotation = entity->getPropertyClass<QuaternionProperty>("planted_rotation");
        if (plantedRotation && plantedRotation->data().isValid()) {
            //Check that the rotation is applied already, otherwise apply it.
            auto* activeRotationProp = entity->requirePropertyClass<QuaternionProperty>("active_rotation");
            if (activeRotationProp->data() != plantedRotation->data()) {
                WFMath::Quaternion currentOrientation = entity->m_location.orientation();

                if (activeRotationProp->data().isValid() && activeRotationProp->data() != WFMath::Quaternion::Identity()) {
                    WFMath::Quaternion rotation = activeRotationProp->data().inverse();
                    //normalize to avoid drift
                    rotation.normalize();
                    currentOrientation = rotation * currentOrientation;
                }

                WFMath::Quaternion rotation = plantedRotation->data();
                //normalize to avoid drift
                rotation.normalize();
                currentOrientation = rotation * currentOrientation;

                activeRotationProp->data() = plantedRotation->data();
                activeRotationProp->apply(entity);
                activeRotationProp->removeFlags(per_clean);
                activeRotationProp->addFlags(flag_unsent);

                Atlas::Objects::Entity::Anonymous move_arg;
                move_arg->setId(entity->getId());
                move_arg->setAttr("orientation", currentOrientation.toAtlas());

                Atlas::Objects::Operation::Move moveOp;
                moveOp->setTo(entity->getId());
                moveOp->setSeconds(BaseWorld::instance().getTime());
                moveOp->setArgs1(move_arg);
                entity->sendWorld(moveOp);
            }
        }
    } else {
        if (entity->hasAttr("active_rotation")) {
            auto* activeRotationProp = entity->modPropertyClass<QuaternionProperty>("active_rotation");
            if (activeRotationProp->data().isValid()) {
                WFMath::Quaternion currentOrientation = entity->m_location.orientation();

                WFMath::Quaternion rotation = activeRotationProp->data().inverse();
                //normalize to avoid drift
                rotation.normalize();
                currentOrientation = rotation * currentOrientation;

                activeRotationProp->data() = WFMath::Quaternion::Identity();
                activeRotationProp->apply(entity);
                activeRotationProp->removeFlags(per_clean);
                activeRotationProp->addFlags(flag_unsent);

                Atlas::Objects::Entity::Anonymous move_arg;
                move_arg->setId(entity->getId());
                move_arg->setAttr("orientation", currentOrientation.toAtlas());

                Atlas::Objects::Operation::Move moveOp;
                moveOp->setTo(entity->getId());
                moveOp->setSeconds(BaseWorld::instance().getTime());
                moveOp->setArgs1(move_arg);
                entity->sendWorld(moveOp);

            }
        }
    }
}