void EntityMaker::createEntityOfType(Eris::TypeInfo* typeinfo, const std::string& parentEntityId, const std::string& name) { Atlas::Objects::Operation::Create c; c->setFrom(mAvatar.getId()); //if the avatar is a "creator", i.e. and admin, we will set the TO property //this will bypass all of the server's filtering, allowing us to create any entity and have it have a working mind too if (mAvatar.getIsAdmin()) { c->setTo(mAvatar.getEntityId()); } Atlas::Message::MapType msg; msg["loc"] = parentEntityId; WFMath::Point<3> pos = WFMath::Point<3>::ZERO(); WFMath::Quaternion orientation = WFMath::Quaternion::Identity(); //Only place it if we're creating the new entity in the same location as the avatar if (parentEntityId == mAvatar.getEntity()->getLocation()->getId()) { //Place the new entity two meters in front of the avatar. WFMath::Vector<3> vector(0, 0, 2); //We need to constraint the orientation to only around the y axis. WFMath::Vector<3> rotator(0.0, 0.0, 1.0f); rotator.rotate(mAvatar.getEntity()->getOrientation()); auto atan = std::atan2(rotator.x(), rotator.z()); orientation.rotation(1, atan); pos = mAvatar.getEntity()->getPosition() + (vector.rotate(orientation)); } msg["pos"] = pos.toAtlas(); msg["orientation"] = orientation.toAtlas(); if (!name.empty()) { msg["name"] = name; } msg["parent"] = typeinfo->getName(); c->setArgsAsList(Atlas::Message::ListType(1, msg)); mConnection.send(c); std::stringstream ss; ss << pos; S_LOG_INFO("Trying to create entity of type " << typeinfo->getName() << " at position " << ss.str()); }
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); } } } }