diff --git a/CMakeLists.txt b/CMakeLists.txt index b5b0884e4..e01b3d26b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -103,6 +103,7 @@ set(OENGINE_OGRE ${LIBDIR}/openengine/ogre/fader.cpp ${LIBDIR}/openengine/ogre/imagerotate.cpp ${LIBDIR}/openengine/ogre/atlas.cpp + ${LIBDIR}/openengine/ogre/selectionbuffer.cpp ) set(OENGINE_GUI ${LIBDIR}/openengine/gui/manager.cpp diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f56313ba3..0865f6383 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -274,6 +274,7 @@ namespace MWBase virtual void updateCharacterPreview(int sizeX, int sizeY) = 0; virtual void updateRaceSelectionPreview(float angle) = 0; + virtual MWWorld::Ptr getCharacterPreviewItemSelected(int posX, int posY) = 0; }; } diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 9df6d893d..7e46aeb03 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -44,6 +44,8 @@ namespace MWGui : ContainerBase(dragAndDrop) , WindowPinnableBase("openmw_inventory_window.layout", parWindowManager) , mTrading(false) + , mAvatarClickedPosX(0) + , mAvatarClickedPosY(0) { static_cast(mMainWidget)->eventWindowChangeCoord += MyGUI::newDelegate(this, &InventoryWindow::onWindowResize); @@ -107,6 +109,7 @@ namespace MWGui MWBase::Environment::get().getWorld()->updateCharacterPreview (size.width, size.height); mAvatarImage->setSize(MyGUI::IntSize(std::max(mAvatar->getSize().width, 512), std::max(mAvatar->getSize().height, 1024))); mAvatarImage->setImageTexture("CharacterPreview"); + mAvatarImage->setImageTexture("SelectionBuffer"); } void InventoryWindow::onFilterChanged(MyGUI::Widget* _sender) @@ -180,6 +183,28 @@ namespace MWGui notifyContentChanged(); } + else + { + MyGUI::IntPoint mousePos = MyGUI::InputManager::getInstance ().getLastPressedPosition (MyGUI::MouseButton::Left); + MyGUI::IntPoint relPos = mousePos - mAvatar->getAbsolutePosition (); + int realX = int(float(relPos.left) / float(mAvatar->getSize().width) * 512.f ); + int realY = int(float(relPos.top) / float(mAvatar->getSize().height) * 1024.f ); + MWWorld::Ptr itemSelected = MWBase::Environment::get().getWorld ()->getCharacterPreviewItemSelected (realX, realY); + if (itemSelected.isEmpty ()) + return; + + + for (unsigned int i=0; i < mContainerWidget->getChildCount (); ++i) + { + MyGUI::Widget* w = mContainerWidget->getChildAt (i); + + if (*w->getUserData() == itemSelected) + { + onSelectedItem(w); + return; + } + } + } } std::vector InventoryWindow::getEquippedItems() @@ -336,4 +361,9 @@ namespace MWGui text->setCaption(getCountString(count)); mDragAndDrop->mDraggedFrom = this; } + + MyGUI::IntCoord InventoryWindow::getAvatarScreenCoord () + { + return mAvatar->getAbsoluteCoord (); + } } diff --git a/apps/openmw/mwgui/inventorywindow.hpp b/apps/openmw/mwgui/inventorywindow.hpp index 4a385dd71..288f32704 100644 --- a/apps/openmw/mwgui/inventorywindow.hpp +++ b/apps/openmw/mwgui/inventorywindow.hpp @@ -22,6 +22,8 @@ namespace MWGui int getPlayerGold(); + MyGUI::IntCoord getAvatarScreenCoord(); + protected: MyGUI::Widget* mAvatar; MyGUI::ImageBox* mAvatarImage; @@ -38,6 +40,10 @@ namespace MWGui MyGUI::Button* mFilterMagic; MyGUI::Button* mFilterMisc; + int mAvatarClickedPosX; + int mAvatarClickedPosY; + + bool mTrading; void onWindowResize(MyGUI::Window* _sender); diff --git a/apps/openmw/mwgui/tooltips.cpp b/apps/openmw/mwgui/tooltips.cpp index 7aee26bcc..3306ea5c2 100644 --- a/apps/openmw/mwgui/tooltips.cpp +++ b/apps/openmw/mwgui/tooltips.cpp @@ -14,6 +14,7 @@ #include "map_window.hpp" #include "widgets.hpp" +#include "inventorywindow.hpp" using namespace MWGui; using namespace MyGUI; @@ -162,12 +163,22 @@ void ToolTips::onFrame(float frameDuration) return; } - if (type == "ItemPtr") { mFocusObject = *focus->getUserData(); tooltipSize = getToolTipViaPtr(false); } + else if (type == "AvatarItemSelection") + { + MyGUI::IntCoord avatarPos = mWindowManager->getInventoryWindow ()->getAvatarScreenCoord (); + MyGUI::IntPoint relMousePos = MyGUI::InputManager::getInstance ().getMousePosition () - MyGUI::IntPoint(avatarPos.left, avatarPos.top); + int realX = int(float(relMousePos.left) / float(avatarPos.width) * 512.f ); + int realY = int(float(relMousePos.top) / float(avatarPos.height) * 1024.f ); + MWWorld::Ptr item = MWBase::Environment::get().getWorld ()->getCharacterPreviewItemSelected (realX, realY); + + mFocusObject = item; + tooltipSize = getToolTipViaPtr(false); + } else if (type == "Spell") { ToolTipInfo info; diff --git a/apps/openmw/mwrender/characterpreview.cpp b/apps/openmw/mwrender/characterpreview.cpp index 21442782f..4a450fad9 100644 --- a/apps/openmw/mwrender/characterpreview.cpp +++ b/apps/openmw/mwrender/characterpreview.cpp @@ -4,6 +4,8 @@ #include #include +#include + #include "renderconst.hpp" #include "npcanimation.hpp" @@ -50,7 +52,12 @@ namespace MWRender : CharacterPreview(sceneMgr, node, 512, 1024, "CharacterPreview", Ogre::Vector3(0, 65, -180), Ogre::Vector3(0,65,0)) , mAnimation(NULL) { + mSelectionBuffer = new OEngine::Render::SelectionBuffer(mCamera, 512, 1024, RV_PlayerPreview); + } + InventoryPreview::~InventoryPreview() + { + delete mSelectionBuffer; } void InventoryPreview::update(int sizeX, int sizeY) @@ -63,7 +70,10 @@ namespace MWRender mNode->setOrientation (Ogre::Quaternion::IDENTITY); mNode->setVisible (true); + mRenderTarget->update(); + mSelectionBuffer->update(); + mNode->setVisible (false); } @@ -72,6 +82,12 @@ namespace MWRender mAnimation = anim; } + int InventoryPreview::getSlotSelected (int posX, int posY) + { + std::cout << posX << " " << posY << std::endl; + return mSelectionBuffer->getSelected (posX, posY); + } + // -------------------------------------------------------------------------------------------------- RaceSelectionPreview::RaceSelectionPreview(Ogre::SceneManager *sceneMgr, Ogre::SceneNode *node) diff --git a/apps/openmw/mwrender/characterpreview.hpp b/apps/openmw/mwrender/characterpreview.hpp index ba48ea17d..fd406ceb5 100644 --- a/apps/openmw/mwrender/characterpreview.hpp +++ b/apps/openmw/mwrender/characterpreview.hpp @@ -2,6 +2,16 @@ #define MWRENDER_CHARACTERPREVIEW_H #include +#include + + +namespace OEngine +{ +namespace Render +{ +class SelectionBuffer; +} +} namespace MWRender { @@ -32,13 +42,18 @@ namespace MWRender { public: InventoryPreview(Ogre::SceneManager* sceneMgr, Ogre::SceneNode* node); + virtual ~InventoryPreview(); void update(int sizeX, int sizeY); + int getSlotSelected(int posX, int posY); + void setNpcAnimation (NpcAnimation* anim); private: NpcAnimation* mAnimation; + + OEngine::Render::SelectionBuffer* mSelectionBuffer; }; class RaceSelectionPreview : public CharacterPreview diff --git a/apps/openmw/mwrender/npcanimation.cpp b/apps/openmw/mwrender/npcanimation.cpp index 00b877ba0..c039b8d44 100644 --- a/apps/openmw/mwrender/npcanimation.cpp +++ b/apps/openmw/mwrender/npcanimation.cpp @@ -94,6 +94,8 @@ NpcAnimation::NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, OEngi { Ogre::Entity *base = mEntityList.mEntities[i]; + base->getUserObjectBindings ().setUserAny (Ogre::Any(-1)); + base->setVisibilityFlags(mVisibilityFlags); bool transparent = false; for(unsigned int j=0;j < base->getNumSubEntities();++j) @@ -351,13 +353,16 @@ void NpcAnimation::updateParts() } } -NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, const std::string &bonename) +NifOgre::EntityList NpcAnimation::insertBoundedPart(const std::string &mesh, int group, const std::string &bonename) { NifOgre::EntityList entities = NIFLoader::createEntities(mEntityList.mSkelBase, bonename, mInsert, mesh); std::vector &parts = entities.mEntities; for(size_t i = 0;i < parts.size();i++) + { parts[i]->setVisibilityFlags(mVisibilityFlags); + parts[i]->getUserObjectBindings ().setUserAny (Ogre::Any(group)); + } return entities; } @@ -480,83 +485,83 @@ bool NpcAnimation::addOrReplaceIndividualPart(int type, int group, int priority, switch(type) { case ESM::PRT_Head: //0 - head = insertBoundedPart(mesh, "Head"); + head = insertBoundedPart(mesh, group, "Head"); break; case ESM::PRT_Hair: //1 - hair = insertBoundedPart(mesh, "Head"); + hair = insertBoundedPart(mesh, group, "Head"); break; case ESM::PRT_Neck: //2 - neck = insertBoundedPart(mesh, "Neck"); + neck = insertBoundedPart(mesh, group, "Neck"); break; case ESM::PRT_Cuirass: //3 - chest = insertBoundedPart(mesh, "Chest"); + chest = insertBoundedPart(mesh, group, "Chest"); break; case ESM::PRT_Groin: //4 - groin = insertBoundedPart(mesh, "Groin"); + groin = insertBoundedPart(mesh, group, "Groin"); break; case ESM::PRT_Skirt: //5 - skirt = insertBoundedPart(mesh, "Groin"); + skirt = insertBoundedPart(mesh, group, "Groin"); break; case ESM::PRT_RHand: //6 - rHand = insertBoundedPart(mesh, "Right Hand"); + rHand = insertBoundedPart(mesh, group, "Right Hand"); break; case ESM::PRT_LHand: //7 - lHand = insertBoundedPart(mesh, "Left Hand"); + lHand = insertBoundedPart(mesh, group, "Left Hand"); break; case ESM::PRT_RWrist: //8 - rWrist = insertBoundedPart(mesh, "Right Wrist"); + rWrist = insertBoundedPart(mesh, group, "Right Wrist"); break; case ESM::PRT_LWrist: //9 - lWrist = insertBoundedPart(mesh, "Left Wrist"); + lWrist = insertBoundedPart(mesh, group, "Left Wrist"); break; case ESM::PRT_Shield: //10 break; case ESM::PRT_RForearm: //11 - rForearm = insertBoundedPart(mesh, "Right Forearm"); + rForearm = insertBoundedPart(mesh, group, "Right Forearm"); break; case ESM::PRT_LForearm: //12 - lForearm = insertBoundedPart(mesh, "Left Forearm"); + lForearm = insertBoundedPart(mesh, group, "Left Forearm"); break; case ESM::PRT_RUpperarm: //13 - rupperArm = insertBoundedPart(mesh, "Right Upper Arm"); + rupperArm = insertBoundedPart(mesh, group, "Right Upper Arm"); break; case ESM::PRT_LUpperarm: //14 - lupperArm = insertBoundedPart(mesh, "Left Upper Arm"); + lupperArm = insertBoundedPart(mesh, group, "Left Upper Arm"); break; case ESM::PRT_RFoot: //15 - rfoot = insertBoundedPart(mesh, "Right Foot"); + rfoot = insertBoundedPart(mesh, group, "Right Foot"); break; case ESM::PRT_LFoot: //16 - lfoot = insertBoundedPart(mesh, "Left Foot"); + lfoot = insertBoundedPart(mesh, group, "Left Foot"); break; case ESM::PRT_RAnkle: //17 - rAnkle = insertBoundedPart(mesh, "Right Ankle"); + rAnkle = insertBoundedPart(mesh, group, "Right Ankle"); break; case ESM::PRT_LAnkle: //18 - lAnkle = insertBoundedPart(mesh, "Left Ankle"); + lAnkle = insertBoundedPart(mesh, group, "Left Ankle"); break; case ESM::PRT_RKnee: //19 - rKnee = insertBoundedPart(mesh, "Right Knee"); + rKnee = insertBoundedPart(mesh, group, "Right Knee"); break; case ESM::PRT_LKnee: //20 - lKnee = insertBoundedPart(mesh, "Left Knee"); + lKnee = insertBoundedPart(mesh, group, "Left Knee"); break; case ESM::PRT_RLeg: //21 - rUpperLeg = insertBoundedPart(mesh, "Right Upper Leg"); + rUpperLeg = insertBoundedPart(mesh, group, "Right Upper Leg"); break; case ESM::PRT_LLeg: //22 - lUpperLeg = insertBoundedPart(mesh, "Left Upper Leg"); + lUpperLeg = insertBoundedPart(mesh, group, "Left Upper Leg"); break; case ESM::PRT_RPauldron: //23 - rclavicle = insertBoundedPart(mesh , "Right Clavicle"); + rclavicle = insertBoundedPart(mesh , group, "Right Clavicle"); break; case ESM::PRT_LPauldron: //24 - lclavicle = insertBoundedPart(mesh, "Left Clavicle"); + lclavicle = insertBoundedPart(mesh, group, "Left Clavicle"); break; case ESM::PRT_Weapon: //25 break; case ESM::PRT_Tail: //26 - tail = insertBoundedPart(mesh, "Tail"); + tail = insertBoundedPart(mesh, group, "Tail"); break; } return true; @@ -575,7 +580,7 @@ void NpcAnimation::addPartGroup(int group, int priority, std::vectorgetStore().bodyParts.search(part.male); if(bodypart) - addOrReplaceIndividualPart(part.part, group,priority,"meshes\\" + bodypart->model); + addOrReplaceIndividualPart(part.part, group, priority,"meshes\\" + bodypart->model); else reserveIndividualPart(part.part, group, priority); } diff --git a/apps/openmw/mwrender/npcanimation.hpp b/apps/openmw/mwrender/npcanimation.hpp index fe66d733a..699c6648d 100644 --- a/apps/openmw/mwrender/npcanimation.hpp +++ b/apps/openmw/mwrender/npcanimation.hpp @@ -18,8 +18,6 @@ private: int mPartslots[27]; //Each part slot is taken by clothing, armor, or is empty int mPartPriorities[27]; - bool mIsPlayer; - //Bounded Parts NifOgre::EntityList lclavicle; NifOgre::EntityList rclavicle; @@ -73,7 +71,7 @@ public: NpcAnimation(const MWWorld::Ptr& ptr, Ogre::SceneNode* node, OEngine::Render::OgreRenderer& _rend, MWWorld::InventoryStore& _inv, int visibilityFlags); virtual ~NpcAnimation(); - NifOgre::EntityList insertBoundedPart(const std::string &mesh, const std::string &bonename); + NifOgre::EntityList insertBoundedPart(const std::string &mesh, int group, const std::string &bonename); virtual void runAnimation(float timepassed); void updateParts(); void removeEntities(NifOgre::EntityList &entities); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index d2a51f5f1..a1ad77caf 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -905,4 +905,10 @@ void RenderingManager::updateRaceSelectionPreview (float angle) mRaceSelectionPreview->update(angle); } +int RenderingManager::getCharacterPreviewSlotSelected(int posX, int posY) +{ + std::cout << "SLOT IS " << mInventoryPreview->getSlotSelected(posX, posY) << std::endl; + return mInventoryPreview->getSlotSelected(posX, posY); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index cbad67472..42fcb1502 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -195,6 +195,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void updateCharacterPreview(int sizeX, int sizeY); void updateRaceSelectionPreview(float angle); + int getCharacterPreviewSlotSelected(int posX, int posY); protected: virtual void windowResized(Ogre::RenderWindow* rw); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 005b94ffa..a38cdd5ff 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1232,4 +1232,19 @@ namespace MWWorld { mRendering->updateRaceSelectionPreview(angle); } + + MWWorld::Ptr World::getCharacterPreviewItemSelected(int posX, int posY) + { + int slot = mRendering->getCharacterPreviewSlotSelected(posX, posY); + + if (slot == -1) + return MWWorld::Ptr(); + + MWWorld::Ptr player = getPlayer().getPlayer (); + MWWorld::InventoryStore& invStore = MWWorld::Class::get(player).getInventoryStore(player); + if (invStore.getSlot(slot) != invStore.end()) + return *invStore.getSlot (slot); + else + return MWWorld::Ptr(); + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 20da6f729..cd7286861 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -310,6 +310,7 @@ namespace MWWorld virtual void updateCharacterPreview(int sizeX, int sizeY); virtual void updateRaceSelectionPreview(float angle); + virtual MWWorld::Ptr getCharacterPreviewItemSelected(int posX, int posY); }; } diff --git a/extern/shiny b/extern/shiny index 716841523..4750676ac 160000 --- a/extern/shiny +++ b/extern/shiny @@ -1 +1 @@ -Subproject commit 7168415233905de2864eec71ed4312cb8f83059b +Subproject commit 4750676ac46a7aaa86bca53dc68c5a1ba11f3bc1 diff --git a/files/CMakeLists.txt b/files/CMakeLists.txt index 3e99f5745..e8426afb7 100644 --- a/files/CMakeLists.txt +++ b/files/CMakeLists.txt @@ -40,7 +40,9 @@ set(MATERIAL_FILES water.mat water.shader water.shaderset - + selection.mat + selection.shader + selection.shaderset ) copy_all_files(${CMAKE_CURRENT_SOURCE_DIR}/water "${OpenMW_BINARY_DIR}/resources/water/" "${WATER_FILES}") diff --git a/files/materials/selection.mat b/files/materials/selection.mat new file mode 100644 index 000000000..a76dd7179 --- /dev/null +++ b/files/materials/selection.mat @@ -0,0 +1,8 @@ +material SelectionColour +{ + pass + { + vertex_program selection_vertex + fragment_program selection_fragment + } +} diff --git a/files/materials/selection.shader b/files/materials/selection.shader new file mode 100644 index 000000000..095a31259 --- /dev/null +++ b/files/materials/selection.shader @@ -0,0 +1,24 @@ +#include "core.h" + +#ifdef SH_VERTEX_SHADER + + SH_BEGIN_PROGRAM + shUniform(float4x4, wvp) @shAutoConstant(wvp, worldviewproj_matrix) + + SH_START_PROGRAM + { + shOutputPosition = shMatrixMult(wvp, shInputPosition); + } + +#else + + SH_BEGIN_PROGRAM + shUniform(float4, colour) @shAutoConstant(colour, custom, 1) + + SH_START_PROGRAM + { + shOutputColour(0) = colour; + //shOutputColour(0) = float4(1,0,0,1); + } + +#endif diff --git a/files/materials/selection.shaderset b/files/materials/selection.shaderset new file mode 100644 index 000000000..c90826282 --- /dev/null +++ b/files/materials/selection.shaderset @@ -0,0 +1,15 @@ +shader_set selection_vertex +{ + source selection.shader + type vertex + profiles_cg vs_2_0 arbvp1 + profiles_hlsl vs_2_0 +} + +shader_set selection_fragment +{ + source selection.shader + type fragment + profiles_cg ps_2_x ps_2_0 ps arbfp1 + profiles_hlsl ps_2_0 +} diff --git a/files/mygui/openmw_chargen_race.layout b/files/mygui/openmw_chargen_race.layout index 6891f5d93..b69073899 100644 --- a/files/mygui/openmw_chargen_race.layout +++ b/files/mygui/openmw_chargen_race.layout @@ -14,7 +14,7 @@ - + diff --git a/files/mygui/openmw_inventory_window.layout b/files/mygui/openmw_inventory_window.layout index 4f295212b..86dee558f 100644 --- a/files/mygui/openmw_inventory_window.layout +++ b/files/mygui/openmw_inventory_window.layout @@ -12,6 +12,7 @@ + diff --git a/libs/openengine/ogre/selectionbuffer.cpp b/libs/openengine/ogre/selectionbuffer.cpp new file mode 100644 index 000000000..99489f008 --- /dev/null +++ b/libs/openengine/ogre/selectionbuffer.cpp @@ -0,0 +1,123 @@ +#include "selectionbuffer.hpp" + +#include +#include +#include +#include + +#include + +namespace OEngine +{ +namespace Render +{ + + SelectionBuffer::SelectionBuffer(Ogre::Camera *camera, int sizeX, int sizeY, int visibilityFlags) + { + mTexture = Ogre::TextureManager::getSingleton().createManual("SelectionBuffer", + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, Ogre::TEX_TYPE_2D, sizeX, sizeY, 0, Ogre::PF_R8G8B8, Ogre::TU_RENDERTARGET); + + mRenderTarget = mTexture->getBuffer()->getRenderTarget(); + Ogre::Viewport* vp = mRenderTarget->addViewport(camera); + vp->setOverlaysEnabled(false); + vp->setBackgroundColour(Ogre::ColourValue(0, 0, 0, 0)); + vp->setShadowsEnabled(false); + vp->setMaterialScheme("selectionbuffer"); + vp->setVisibilityMask (visibilityFlags); + mRenderTarget->setActive(true); + mRenderTarget->setAutoUpdated (false); + + mCurrentColour = Ogre::ColourValue(0.3, 0.3, 0.3); + } + + SelectionBuffer::~SelectionBuffer() + { + Ogre::TextureManager::getSingleton ().remove("SelectionBuffer"); + } + + void SelectionBuffer::update () + { + Ogre::MaterialManager::getSingleton ().addListener (this); + + mRenderTarget->update(); + + Ogre::MaterialManager::getSingleton ().removeListener (this); + + mTexture->convertToImage(mBuffer); + } + + int SelectionBuffer::getSelected(int xPos, int yPos) + { + Ogre::ColourValue clr = mBuffer.getColourAt (xPos, yPos, 0); + clr.a = 1; + if (mColourMap.find(clr) != mColourMap.end()) + return mColourMap[clr]; + else + return -1; // nothing selected + } + + Ogre::Technique* SelectionBuffer::handleSchemeNotFound ( + unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial, + unsigned short lodIndex, const Ogre::Renderable *rend) + { + if (schemeName == "selectionbuffer") + { + sh::Factory::getInstance ()._ensureMaterial ("SelectionColour", "Default"); + + Ogre::MaterialPtr m = Ogre::MaterialManager::getSingleton ().getByName("SelectionColour"); + + + if(typeid(*rend) == typeid(Ogre::SubEntity)) + { + const Ogre::SubEntity *subEntity = static_cast(rend); + int id = subEntity->getParent ()->getUserObjectBindings().getUserAny().get(); + std::cout << "found ID:" << id << " entity name is " << subEntity->getParent()->getName() << std::endl; + bool found = false; + Ogre::ColourValue colour; + for (std::map::iterator it = mColourMap.begin(); it != mColourMap.end(); ++it) + { + if (it->second == id) + { + found = true; + colour = it->first; + } + } + + + if (!found) + { + getNextColour(); + const_cast(subEntity)->setCustomParameter(1, Ogre::Vector4(mCurrentColour.r, mCurrentColour.g, mCurrentColour.b, 1.0)); + mColourMap[mCurrentColour] = id; + } + else + { + const_cast(subEntity)->setCustomParameter(1, Ogre::Vector4(colour.r, colour.g, colour.b, 1.0)); + } + + assert(m->getTechnique(1)); + return m->getTechnique(1); + } + else + throw std::runtime_error("selectionbuffer only works with entities"); + } + return NULL; + } + + void SelectionBuffer::getNextColour () + { + Ogre::ARGB color = (float(rand()) / float(RAND_MAX)) * std::numeric_limits::max(); + + if (mCurrentColour.getAsARGB () == color) + { + getNextColour(); + return; + } + + mCurrentColour.setAsARGB(color); + mCurrentColour.a = 1; + } + + +} +} diff --git a/libs/openengine/ogre/selectionbuffer.hpp b/libs/openengine/ogre/selectionbuffer.hpp new file mode 100644 index 000000000..c487b24b0 --- /dev/null +++ b/libs/openengine/ogre/selectionbuffer.hpp @@ -0,0 +1,54 @@ +#ifndef OENGINE_SELECTIONBUFFER_H +#define OENGINE_SELECTIONBUFFER_H + + +#include +#include +#include + +namespace OEngine +{ +namespace Render +{ + + struct cmp_ColourValue + { + bool operator()(const Ogre::ColourValue &a, const Ogre::ColourValue &b) const + { + return a.getAsBGRA() < b.getAsBGRA(); + } + }; + + class SelectionBuffer : public Ogre::MaterialManager::Listener + { + public: + SelectionBuffer(Ogre::Camera* camera, int sizeX, int sizeY, int visibilityFlags); + virtual ~SelectionBuffer(); + + int getSelected(int xPos, int yPos); + ///< @return ID of the selected object + + void update(); + + virtual Ogre::Technique* handleSchemeNotFound ( + unsigned short schemeIndex, const Ogre::String &schemeName, Ogre::Material *originalMaterial, + unsigned short lodIndex, const Ogre::Renderable *rend); + + + private: + Ogre::TexturePtr mTexture; + Ogre::RenderTexture* mRenderTarget; + + Ogre::Image mBuffer; + + std::map mColourMap; + + Ogre::ColourValue mCurrentColour; + + void getNextColour(); + }; + +} +} + +#endif