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); } } } }