void PolygonPointPickListener::processPickResult(bool& continuePicking, Ogre::RaySceneQueryResultEntry& entry, Ogre::Ray& /*cameraRay */, const MousePickerArgs& mousePickerArgs) { if (entry.movable) { Ogre::MovableObject* pickedMovable = entry.movable; if (pickedMovable->isVisible() && pickedMovable->getUserObjectBindings().getUserAny().getType() == typeid(PolygonPointUserObject*)) { continuePicking = false; if (mousePickerArgs.pickType == MPT_PRESS) { //TODO: make sure that it's a point which belongs to our polygon mPickedUserObject = Ogre::any_cast<PolygonPointUserObject*>(pickedMovable->getUserObjectBindings().getUserAny()); } } } }
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); } } } } } }