예제 #1
0
void EmberEntity::reattachChildren()
{
  for (unsigned int i = 0; i < numContained(); ++i) {
    EmberEntity* entity = getEmberContained(i);
    if (entity) {
      entity->onLocationChanged(entity->getEmberLocation());
      entity->reattachChildren();
    }
  }
}
예제 #2
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);
					}
				}
			}
		}
	}
}