예제 #1
0
파일: EmberEntity.cpp 프로젝트: Laefy/ember
void EmberEntity::updateAttachment()
{
	//Get the new location. We use getEmberLocation() since we always know that all entities are of type EmberEntity.
	EmberEntity* newLocationEntity = getEmberLocation();

	if (newLocationEntity && newLocationEntity->getAttachment()) {
		try {
			IEntityAttachment* newAttachment = newLocationEntity->getAttachment()->attachEntity(*this);
			setAttachment(newAttachment);
			if (newAttachment) {
				newAttachment->updateScale();
			}
		} catch (const std::exception& ex) {
			S_LOG_WARNING("Problem when creating new attachment for entity." << ex);
		}
		//If we're the top level entity the attachment has been set from the outside and shouldn't be changed.
		//FIXME This is a little hackish; how can we improve it to not require special cases?
	} else if (m_view->getTopLevel() == this) {
		return;
	} else {
		try {
			setAttachment(nullptr);
		} catch (const std::exception& ex) {
			S_LOG_WARNING("Problem when setting attachment for entity." << ex);
		}
	}
}
예제 #2
0
void EmberEntity::onLocationChanged(Eris::Entity *oldLocation)
{
  //Get the new location. We use getEmberLocation() since we always know that all entities are of type EmberEntity.
  EmberEntity* newLocationEntity = getEmberLocation();

  if (newLocationEntity && newLocationEntity->getAttachment()) {
    try {
      IEntityAttachment* newAttachment = newLocationEntity->getAttachment()->attachEntity(*this);
      setAttachment(newAttachment);
      if (newAttachment) {
        newAttachment->updateScale();
      }
    } catch (const std::exception& ex) {
      S_LOG_WARNING("Problem when creating new attachment for entity." << ex);
    }
  } else {
    try {
      setAttachment(0);
    } catch (const std::exception& ex) {
      S_LOG_WARNING("Problem when setting attachment for entity." << ex);
    }
  }

  Eris::Entity::onLocationChanged(oldLocation);

}
예제 #3
0
std::string EntityTooltip::composeEntityInfoText(EmberEntity& entity)
{
	std::stringstream ss;
	if (entity.getName() != "") {
		ss << entity.getName() << " (of type " << entity.getType()->getName() << ")";
	} else {
		ss << entity.getType()->getName();
	}
	if (entity.hasAttr("biomass")) {
		ss << std::endl << "Edible";
	}
	if (entity.hasAttr("right_hand_wield")) {
		ss << std::endl << "Wieldable";
	}
	if (entity.hasAttr("worn")) {
		const Atlas::Message::Element& element = entity.valueOfAttr("worn");
		if (element.isString()) {
			ss << std::endl << "Worn on the " << element.asString();
		}
	}
	std::vector<std::string> actions = entity.getActions();
	if (actions.size()) {
		for (std::vector<std::string>::const_iterator I = actions.begin(); I != actions.end(); ++I) {
			ss << std::endl << "Can be used to " << *I;
		}
	}
	std::vector<std::string> operations = entity.getDefaultUseOperators();
	if (operations.size()) {
		for (std::vector<std::string>::const_iterator I = operations.begin(); I != operations.end(); ++I) {
			ss << std::endl << "Can be used to " << *I;
		}
	}

	return ss.str();
}
예제 #4
0
SimpleEntityVisualization::SimpleEntityVisualization(EmberEntity& entity, Ogre::SceneNode* sceneNode) :
		mEntity(entity),
		mSceneNode(sceneNode),
		mErisEntityBoundingBox(OGRE_NEW Ogre::OOBBWireBoundingBox()),
		mBboxConnection(entity.observe("bbox", sigc::mem_fun(*this, &SimpleEntityVisualization::entity_BboxChanged))),
		mScaleConnection(entity.observe("scale", sigc::mem_fun(*this, &SimpleEntityVisualization::entity_BboxChanged)))
{

	mVelocityArrowEntity = sceneNode->getCreator()->createEntity("common/primitives/model/arrow.mesh");
	mVelocitySceneNode = sceneNode->getParentSceneNode()->createChildSceneNode();
	mVelocitySceneNode->attachObject(mVelocityArrowEntity);
	mVelocitySceneNode->setScale(0.5, 0.5, 0.5);

	try {
		auto materialPtr = Ogre::MaterialManager::getSingleton().getByName(BboxMaterialName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
		if (materialPtr) {
			mErisEntityBoundingBox->setMaterial(materialPtr);
		}
	} catch (const std::exception& ex) {
		S_LOG_FAILURE("Error when setting Ogre material for bounding box.");
		OGRE_DELETE mErisEntityBoundingBox;
		mErisEntityBoundingBox = nullptr;
		throw Exception("Error when setting Ogre material for bounding box.");
	}
	mSceneNode->attachObject(mErisEntityBoundingBox);
	mErisEntityBoundingBox->setVisible(true);
	updateBbox();
	updatePositionAndOrientation();
	mEntity.Moved.connect(sigc::mem_fun(*this, &SimpleEntityVisualization::entity_Moved));
}
예제 #5
0
파일: EmberEntity.cpp 프로젝트: Laefy/ember
void EmberEntity::reattachChildren()
{
	for (unsigned int i = 0; i < numContained(); ++i) {
		EmberEntity* entity = getEmberContained(i);
		if (entity) {
			entity->updateAttachment();
			entity->reattachChildren();
		}
	}
}
예제 #6
0
파일: EmberEntity.cpp 프로젝트: Laefy/ember
void EmberEntity::accept(IEntityVisitor& visitor)
{
	visitor.visit(*this);
	for (unsigned int i = 0; i < numContained(); ++i) {
		EmberEntity* entity = getEmberContained(i);
		if (entity) {
			entity->accept(visitor);
		}
	}
}
예제 #7
0
void EmberEntity::reattachChildren()
{
  for (unsigned int i = 0; i < numContained(); ++i) {
    EmberEntity* entity = getEmberContained(i);
    if (entity) {
      entity->onLocationChanged(entity->getEmberLocation());
      entity->reattachChildren();
    }
  }
}
예제 #8
0
파일: EmberEntity.cpp 프로젝트: Laefy/ember
void EmberEntity::accept(std::function<bool(const EmberEntity&)>& visitor) const
{
	if (visitor(*this)) {
		for (unsigned int i = 0; i < numContained(); ++i) {
			EmberEntity* entity = getEmberContained(i);
			if (entity) {
				entity->accept(visitor);
			}
		}
	}
}
예제 #9
0
// create whatever entity the client desires
Eris::Entity* EmberEntityFactory::instantiate(const Atlas::Objects::Entity::RootEntity &ge, Eris::TypeInfo* type, Eris::View* w)
{

	EmberEntity* entity = new EmberEntity(ge->getId(), type, w);
	//the creator binds the model mapping and this instance together by creating instance of EmberEntityModelAction and EmberEntityPartAction which in turn calls the setModel(..) and show/hideModelPart(...) methods.
	EmberEntityActionCreator creator(*entity, mScene);
	EntityMapping::EntityMapping* mapping = Mapping::EmberEntityMappingManager::getSingleton().getManager().createMapping(*entity, creator, &mView);
	entity->BeingDeleted.connect(sigc::bind(sigc::mem_fun(*this, &EmberEntityFactory::deleteMapping), mapping));
	mapping->initialize();
	S_LOG_VERBOSE("Entity " << entity->getId() << " (" << type->getName() << ") added to game view.");
	return entity;
}
예제 #10
0
void EntityMoveManager::startMove(EmberEntity& entity)
{
	//disallow moving of the root entity
	if (entity.getLocation()) {
		//Only provide movement for entities which have a node attachment.
		NodeAttachment* attachment = dynamic_cast<NodeAttachment*> (entity.getAttachment());
		if (attachment) {
			EntityMover* mover = new EntityMover(*attachment, *this);
			mMoveAdapter.attachToBridge(mover);
			//The EntityMoveInstance will delete itself when either movement is finished or the entity is deleted, so we don't need to hold a reference to it.
			new EntityMoveInstance(entity, mMoveAdapter, EventFinishedMoving, EventCancelledMoving);
			EventStartMoving.emit(entity, *mover);
		}
	}
}
예제 #11
0
AvatarLogger::AvatarLogger(EmberEntity& avatarEntity)
: mChatLogger(nullptr)
{
	assert(&avatarEntity);

	//Put log files in a "logs" subdirectory of the home directory.
	const std::string dir = EmberServices::getSingleton().getConfigService().getHomeDirectory() + "/logs/";
	try {
		//make sure the directory exists

		oslink::directory osdir(dir);

		if (!osdir.isExisting()) {
			oslink::directory::mkdir(dir.c_str());
		}
		//perform setup of the stream
		std::stringstream logFileSS;
		logFileSS << dir << "/" << avatarEntity.getName() << "_chatlog.log";
		mChatLogger = std::unique_ptr<std::ofstream>(new std::ofstream(logFileSS.str().c_str(), std::ios::app));
		S_LOG_VERBOSE("Chat Logging set to write in [ " << logFileSS.str() << " ]");

		*mChatLogger << "-------------------------------------------------------" << std::endl;
		*mChatLogger << "Chat Logging Initialized at " <<  Time::getLocalTimeStr() << std::endl;
		*mChatLogger << "-------------------------------------------------------" << std::endl;

		//wait with connecting until everything has been properly set up
		GUIManager::getSingleton().AppendIGChatLine.connect(sigc::mem_fun(*this, &AvatarLogger::GUIManager_AppendIGChatLine));

	} catch (const std::exception& ex) {
		S_LOG_FAILURE("Error when creating directory for logs." << ex);
	}
}
예제 #12
0
void TerrainEntityManager::entityTerrainAttrChanged(EmberEntity& entity, const Atlas::Message::Element& value)
{
	if (!mTerrainEntityDeleteConnection) {
		mTerrainEntityDeleteConnection = entity.BeingDeleted.connect([this](){
			mTerrainHandler.EventTerrainDisabled();
			mTerrainEntityDeleteConnection.disconnect();
		});
	}

	Terrain::TerrainShaderParser terrainShaderParser(mTerrainHandler);
	terrainShaderParser.createShaders(value);
	Terrain::TerrainParser terrainParser;
	WFMath::Point<3> pos = entity.getPosition().isValid() ? entity.getPredictedPos() : WFMath::Point<3>::ZERO();
	mTerrainHandler.updateTerrain(terrainParser.parseTerrain(value, pos));
	entity.setHeightProvider(&mTerrainHandler);
	mTerrainHandler.EventTerrainEnabled(entity);
}
예제 #13
0
파일: EmberEntity.cpp 프로젝트: Laefy/ember
EmberEntity* EmberEntity::getAttachedEntity(const std::string& namedPoint)
{
	//HACK: this is just a temporary solution
	if (hasAttr(namedPoint)) {
		const Atlas::Message::Element& idElement = valueOfAttr(namedPoint);
		std::string id;
		if (Eris::Entity::extractEntityId(idElement, id)) {
			for (unsigned int i = 0; i < numContained(); ++i) {
				EmberEntity* entity = getEmberContained(i);
				if (entity && entity->getId() == id) {
					return entity;
				}
			}
		}
	}

	return 0;
}
예제 #14
0
void EmberEntityFactory::dumpAttributesOfEntity(const std::string& entityId) const
{
	EmberEntity* entity = static_cast<EmberEntity*>(mView.getEntity(entityId));
	if (entity) {
		//make sure the directory exists
		std::string dir(EmberServices::getSingleton().getConfigService().getHomeDirectory() + "/entityexport/");

		if (!oslink::directory(dir).isExisting()) {
			S_LOG_INFO("Creating directory " << dir);
			oslink::directory::mkdir(dir.c_str());
		}

		const std::string fileName(dir + entityId + ".atlas");
		std::fstream exportFile(fileName.c_str(), std::fstream::out);

		S_LOG_INFO("Dumping attributes to " << fileName);
		entity->dumpAttributes(exportFile, std::cout);
		ConsoleBackend::getSingletonPtr()->pushMessage(std::string("Dumped attributes to ") + fileName, "info");
	}
}
예제 #15
0
void TerrainEntityManager::entityAreaAttrChanged(EmberEntity& entity, const Atlas::Message::Element& value)
{
	Terrain::TerrainArea* terrainArea;
	auto I = mAreas.find(&entity);
	if (I == mAreas.end()) {
		terrainArea = new Terrain::TerrainArea(entity);
		mAreas.insert(std::make_pair(&entity, terrainArea));
		terrainArea->EventEntityBeingDeleted.connect(sigc::bind(sigc::mem_fun(*this, &TerrainEntityManager::entityBeingDeletedArea), &entity));
		terrainArea->EventEntityMoved.connect(sigc::bind(sigc::mem_fun(*this, &TerrainEntityManager::entityMovedArea), &entity));
	} else {
		terrainArea = I->second;
	}

	Mercator::Area* area = nullptr;
	terrainArea->parse(value, &area);

	mTerrainHandler.updateArea(entity.getId(), area);
	delete area;
}
예제 #16
0
void EntityWorldPickListener::processPickResult(bool& continuePicking, Ogre::RaySceneQueryResultEntry& entry, Ogre::Ray& cameraRay, const MousePickerArgs& mousePickerArgs)
{
	if (!mContinuePickingThisContext) {
		return;
	}

	if (entry.worldFragment) {
		//this is terrain
		//a position of -1, -1, -1 is not valid terrain
		Ogre::SceneQuery::WorldFragment* wf = entry.worldFragment;
		static const Ogre::Vector3 invalidPos(-1, -1, -1);
		if (wf->singleIntersection != invalidPos) {

			if (mFurthestPickingDistance == 0 || mResult.empty()) {
				EntityPickResult result;
				result.entity = findTerrainEntity();
				result.position = wf->singleIntersection;
				result.distance = entry.distance;
				result.isTransparent = false;
				mResult.push_back(result);
				mContinuePickingThisContext = false;
			} else {
				if (entry.distance < mResult[mResult.size() - 1].distance) {
					//If the last result is transparent, add another result, but if it's not replace it.
					if (mResult.size() && !mResult[mResult.size() - 1].isTransparent) {
						mResult.pop_back();
					}
					EntityPickResult result;
					result.entity = findTerrainEntity();
					result.position = wf->singleIntersection;
					result.distance = entry.distance;
					result.isTransparent = false;
					mResult.push_back(result);
					mContinuePickingThisContext = false;
				}
			}
		}
		/*		std::stringstream ss;
		 ss << wf->singleIntersection;
		 S_LOG_VERBOSE("Picked in terrain: " << ss.str() << " distance: " << mResult.distance);*/

	} else if (entry.movable) {
		Ogre::MovableObject* pickedMovable = entry.movable;
		if (pickedMovable->isVisible() && pickedMovable->getUserObjectBindings().getUserAny().getType() == typeid(EmberEntityUserObject::SharedPtr)) {
			EmberEntityUserObject* anUserObject = Ogre::any_cast<EmberEntityUserObject::SharedPtr>(pickedMovable->getUserObjectBindings().getUserAny()).get();
			//refit the opcode mesh to adjust for changes in the mesh (for example animations)
			anUserObject->refit();

			ICollisionDetector* collisionDetector = anUserObject->getCollisionDetector();
			if (collisionDetector) {
				CollisionResult collisionResult;
				collisionResult.collided = false;
				collisionResult.isTransparent = false;
				collisionDetector->testCollision(cameraRay, collisionResult);
				if (collisionResult.collided) {
					if (mFurthestPickingDistance == 0) {
						//If the current collision is transparent, also check for entities which are further away.
						if (!collisionResult.isTransparent) {
							//test all objects that fall into this distance
							mFurthestPickingDistance = (pickedMovable->getParentNode()->_getDerivedPosition() - cameraRay.getOrigin()).length() + pickedMovable->getBoundingRadius();
						}
					} else {
						if (collisionResult.distance > mFurthestPickingDistance) {
							mContinuePickingThisContext = false;
							return;
						} else {
							if (!mResult.empty() && mResult[mResult.size() - 1].distance > collisionResult.distance) {
								//If the last result is transparent, add another result, but if it's not replace it.
								if (!mResult[mResult.size() - 1].isTransparent) {
									mResult.pop_back();
								}
							} else {
								return;
							}
						}
					}
					EmberEntity& pickedEntity = anUserObject->getEmberEntity();

					std::list<EmberEntity*> entities;
					entities.push_front(&pickedEntity);
					EmberEntity* entity = pickedEntity.getEmberLocation();
					while (entity) {
						if (entity->getCompositionMode() == EmberEntity::CM_COMPOSITION) {
							entities.push_front(entity);
						} else if (entity->getCompositionMode() == EmberEntity::CM_COMPOSITION_EXCLUSIVE) {
							entities.clear();
							entities.push_front(entity);
						}
						entity = entity->getEmberLocation();
					}

					for (std::list<EmberEntity*>::const_iterator I = entities.begin(); I != entities.end(); ++I) {
						EntityPickResult result;
						result.entity = *I;
						result.position = collisionResult.position;
						result.distance = collisionResult.distance;
						result.isTransparent = collisionResult.isTransparent;
						mResult.push_back(result);
					}
				}
			}
		}
	}
}
예제 #17
0
void TerrainEntityManager::topLevelEntityChanged()
{
	EmberEntity* entity = static_cast<EmberEntity*>(mView.getTopLevel());
	entity->setAttachment(nullptr);
	entity->setAttachment(new WorldAttachment(*entity, mSceneManager.getRootSceneNode()->createChildSceneNode("entity_" + entity->getId())));
}
SimpleEntityVisualization::SimpleEntityVisualization(EmberEntity& entity, Ogre::SceneNode* sceneNode) :
	mEntity(entity), mSceneNode(sceneNode), mErisEntityBoundingBox(OGRE_NEW Ogre::OOBBWireBoundingBox()), mBboxConnection(entity.observe("bbox", sigc::mem_fun(*this, &SimpleEntityVisualization::entity_BboxChanged)))
{
	try {
		mErisEntityBoundingBox->setMaterial(BboxMaterialName);
	} catch (const std::exception& ex) {
		S_LOG_FAILURE("Error when setting Ogre material for bounding box.");
		OGRE_DELETE mErisEntityBoundingBox;
		mErisEntityBoundingBox = 0;
		throw Exception("Error when setting Ogre material for bounding box.");
	}
	mSceneNode->attachObject(mErisEntityBoundingBox);
	mErisEntityBoundingBox->setVisible(true);
	updateBbox();
	updatePositionAndOrientation();
	mEntity.Moved.connect(sigc::mem_fun(*this, &SimpleEntityVisualization::entity_Moved));
}