Separate rendering of window menus. It's still awkward. Needs polishing.
parent
7eaf015b87
commit
57e48cfc03
@ -1,308 +0,0 @@
|
||||
#include "openxrmenu.hpp"
|
||||
#include "vrenvironment.hpp"
|
||||
#include "openxrsession.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "vranimation.hpp"
|
||||
#include <openxr/openxr.h>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/ClipNode>
|
||||
#include <osg/FrontFace>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/Depth>
|
||||
#include <components/sceneutil/visitor.hpp>
|
||||
#include <components/sceneutil/shadow.hpp>
|
||||
#include <osgViewer/Renderer>
|
||||
#include "../mwrender/util.hpp"
|
||||
#include "../mwrender/renderbin.hpp"
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
||||
/// Draw callback for RTT that can be used to regenerate mipmaps
|
||||
/// either as a predraw before use or a postdraw after RTT.
|
||||
class MipmapCallback : public osg::Camera::DrawCallback
|
||||
{
|
||||
public:
|
||||
MipmapCallback(osg::Texture2D* texture)
|
||||
: mTexture(texture)
|
||||
{}
|
||||
|
||||
void operator()(osg::RenderInfo& info) const override;
|
||||
|
||||
private:
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> mTexture;
|
||||
};
|
||||
|
||||
/// RTT camera used to draw the osg GUI to a texture
|
||||
class GUICamera : public osg::Camera
|
||||
{
|
||||
public:
|
||||
GUICamera()
|
||||
{
|
||||
setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
// Make the texture just a little transparent to feel more natural in the game world.
|
||||
setClearColor(osg::Vec4(0.f,0.f,0.f,.75f));
|
||||
|
||||
setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
setName("MenuCamera");
|
||||
|
||||
setCullMask(SceneUtil::Mask_GUI);
|
||||
setNodeMask(SceneUtil::Mask_RenderToTexture);
|
||||
|
||||
unsigned int rttSize = 4000;
|
||||
setViewport(0, 0, rttSize, rttSize);
|
||||
|
||||
// No need for Update traversal since the mSceneRoot is already updated as part of the main scene graph
|
||||
// A double update would mess with the light collection (in addition to being plain redundant)
|
||||
setUpdateCallback(new MWRender::NoTraverseCallback);
|
||||
|
||||
// Create the texture
|
||||
mTexture = new osg::Texture2D;
|
||||
mTexture->setTextureSize(rttSize, rttSize);
|
||||
mTexture->setInternalFormat(GL_RGBA);
|
||||
mTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
|
||||
mTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||
mTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
mTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
attach(osg::Camera::COLOR_BUFFER, mTexture);
|
||||
// Need to regenerate mipmaps every frame
|
||||
setPostDrawCallback(new MipmapCallback(mTexture));
|
||||
|
||||
// Do not want to waste time on shadows when generating the GUI texture
|
||||
SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet());
|
||||
|
||||
// Put rendering as early as possible
|
||||
getOrCreateStateSet()->setRenderBinDetails(-1, "RenderBin");
|
||||
|
||||
}
|
||||
|
||||
void setScene(osg::Node* scene)
|
||||
{
|
||||
if (mScene)
|
||||
removeChild(mScene);
|
||||
mScene = scene;
|
||||
addChild(scene);
|
||||
Log(Debug::Verbose) << "Set new scene: " << mScene->getName();
|
||||
}
|
||||
|
||||
osg::Texture2D* getTexture() const
|
||||
{
|
||||
return mTexture.get();
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Texture2D> mTexture;
|
||||
osg::ref_ptr<osg::Node> mScene;
|
||||
};
|
||||
|
||||
|
||||
OpenXRMenu::OpenXRMenu(
|
||||
osg::ref_ptr<osg::Group> geometryRoot,
|
||||
osg::ref_ptr<osg::Group> cameraRoot,
|
||||
osg::ref_ptr<osg::Node> menuSubgraph,
|
||||
const std::string& title,
|
||||
osg::Vec2 extent_meters,
|
||||
Pose pose,
|
||||
int width,
|
||||
int height,
|
||||
const osg::Vec4& clearColor,
|
||||
osgViewer::Viewer* viewer)
|
||||
: mTitle(title)
|
||||
, mGeometryRoot(geometryRoot)
|
||||
, mCameraRoot(cameraRoot)
|
||||
, mMenuSubgraph(menuSubgraph)
|
||||
{
|
||||
osg::ref_ptr<osg::Vec3Array> vertices{ new osg::Vec3Array(4) };
|
||||
osg::ref_ptr<osg::Vec2Array> texCoords{ new osg::Vec2Array(4) };
|
||||
osg::ref_ptr<osg::Vec3Array> normals{ new osg::Vec3Array(1) };
|
||||
|
||||
// Units are divided by 2 because geometry has an extent of 2 (-1 to 1)
|
||||
auto extent_units = extent_meters * Environment::get().unitsPerMeter() / 2.f;
|
||||
|
||||
// Define the menu quad
|
||||
osg::Vec3 top_left (-1, 1, 1);
|
||||
osg::Vec3 bottom_left(-1, -1, 1);
|
||||
osg::Vec3 bottom_right(1, -1, 1);
|
||||
osg::Vec3 top_right (1, 1, 1);
|
||||
(*vertices)[0] = top_left;
|
||||
(*vertices)[1] = bottom_left;
|
||||
(*vertices)[2] = bottom_right;
|
||||
(*vertices)[3] = top_right;
|
||||
mGeometry->setVertexArray(vertices);
|
||||
(*texCoords)[0].set(0.0f, 1.0f);
|
||||
(*texCoords)[1].set(0.0f, 0.0f);
|
||||
(*texCoords)[2].set(1.0f, 0.0f);
|
||||
(*texCoords)[3].set(1.0f, 1.0f);
|
||||
mGeometry->setTexCoordArray(0, texCoords);
|
||||
(*normals)[0].set(0.0f, -1.0f, 0.0f);
|
||||
mGeometry->setNormalArray(normals, osg::Array::BIND_OVERALL);
|
||||
mGeometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
|
||||
mGeometry->setDataVariance(osg::Object::DYNAMIC);
|
||||
mGeometry->setSupportsDisplayList(false);
|
||||
mGeometry->setName("XR Menu Geometry");
|
||||
//mGeode->addDrawable(mGeometry);
|
||||
|
||||
// Define the camera that will render the menu texture
|
||||
mGUICamera = new GUICamera();
|
||||
mGUICamera->setScene(menuSubgraph);
|
||||
|
||||
// Define state set that allows rendering with transparency
|
||||
mStateSet->setTextureAttributeAndModes(0, menuTexture(), osg::StateAttribute::ON);
|
||||
mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
mStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
mStateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
mStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
mGeometry->setStateSet(mStateSet);
|
||||
|
||||
// Position in the game world
|
||||
mTransform->setScale(osg::Vec3(extent_units.x(), extent_units.y(), 1.f));
|
||||
mTransform->setAttitude(pose.orientation);
|
||||
mTransform->setPosition(pose.position);
|
||||
mTransform->addChild(mGeometry);
|
||||
//mTransform->addChild(VRAnimation::createPointerGeometry());
|
||||
|
||||
// Add to scene graph
|
||||
mGeometryRoot->addChild(mTransform);
|
||||
mCameraRoot->addChild(mGUICamera);
|
||||
}
|
||||
|
||||
OpenXRMenu::~OpenXRMenu()
|
||||
{
|
||||
mGeometryRoot->removeChild(mTransform);
|
||||
mCameraRoot->removeChild(mGUICamera);
|
||||
}
|
||||
|
||||
void OpenXRMenu::updateCallback()
|
||||
{
|
||||
}
|
||||
|
||||
void MipmapCallback::operator()(osg::RenderInfo& renderInfo) const
|
||||
{
|
||||
auto* gl = renderInfo.getState()->get<osg::GLExtensions>();
|
||||
auto* tex = mTexture->getTextureObject(renderInfo.getContextID());
|
||||
if (tex)
|
||||
{
|
||||
tex->bind();
|
||||
gl->glGenerateMipmap(tex->target());
|
||||
}
|
||||
}
|
||||
|
||||
osg::Camera* OpenXRMenu::camera()
|
||||
{
|
||||
return mGUICamera.get();
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> OpenXRMenu::menuTexture()
|
||||
{
|
||||
if (mGUICamera)
|
||||
return mGUICamera->getTexture();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OpenXRMenu::updatePose(Pose pose)
|
||||
{
|
||||
mTransform->setAttitude(pose.orientation);
|
||||
mTransform->setPosition(pose.position);
|
||||
}
|
||||
|
||||
|
||||
OpenXRMenuManager::OpenXRMenuManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer)
|
||||
: mOsgViewer(viewer)
|
||||
{
|
||||
mGUIGeometriesRoot->setName("XR GUI Geometry Root");
|
||||
mGUICamerasRoot->setName("XR GUI Cameras Root");
|
||||
auto* root = viewer->getSceneData();
|
||||
|
||||
SceneUtil::FindByNameVisitor findGUIVisitor("GUI Root");
|
||||
root->accept(findGUIVisitor);
|
||||
mGuiRoot = findGUIVisitor.mFoundNode;
|
||||
if (!mGuiRoot)
|
||||
{
|
||||
Log(Debug::Error) << "GUI Root doesn't exist";
|
||||
return;
|
||||
}
|
||||
|
||||
SceneUtil::FindByNameVisitor findSceneVisitor("Scene Root");
|
||||
root->accept(findSceneVisitor);
|
||||
if(!findSceneVisitor.mFoundNode)
|
||||
{
|
||||
Log(Debug::Error) << "Scene Root doesn't exist";
|
||||
return;
|
||||
}
|
||||
|
||||
Log(Debug::Verbose) << "Root note: " << root->getName();
|
||||
|
||||
findSceneVisitor.mFoundNode->addChild(mGUIGeometriesRoot);
|
||||
root->asGroup()->addChild(mGUICamerasRoot);
|
||||
|
||||
}
|
||||
|
||||
OpenXRMenuManager::~OpenXRMenuManager(void)
|
||||
{
|
||||
}
|
||||
|
||||
void OpenXRMenuManager::showMenus(bool show)
|
||||
{
|
||||
// TODO: Configurable menu dimensions
|
||||
int width = 1000;
|
||||
int height = 1000;
|
||||
|
||||
if (show && !mMenu)
|
||||
{
|
||||
updatePose();
|
||||
mMenu.reset(new OpenXRMenu(
|
||||
mGUIGeometriesRoot,
|
||||
mGUICamerasRoot,
|
||||
mGuiRoot,
|
||||
"Main Menu",
|
||||
osg::Vec2(1.5f, 1.5f),
|
||||
mPose,
|
||||
width,
|
||||
height,
|
||||
mOsgViewer->getCamera()->getClearColor(),
|
||||
mOsgViewer
|
||||
));
|
||||
Log(Debug::Error) << "Created menu";
|
||||
}
|
||||
else if (!show && mMenu)
|
||||
{
|
||||
mMenu = nullptr;
|
||||
Log(Debug::Error) << "Destroyed menu";
|
||||
}
|
||||
}
|
||||
|
||||
void OpenXRMenuManager::updatePose(void)
|
||||
{
|
||||
osg::Vec3 eye{};
|
||||
osg::Vec3 center{};
|
||||
osg::Vec3 up{};
|
||||
|
||||
auto* camera = mOsgViewer->getCamera();
|
||||
if (!camera)
|
||||
{
|
||||
Log(Debug::Error) << "osg viewer has no camera";
|
||||
return;
|
||||
}
|
||||
|
||||
camera->getViewMatrixAsLookAt(eye, center, up);
|
||||
|
||||
// Position the menu about two thirds of a meter in front of the player
|
||||
osg::Vec3 dir = center - eye;
|
||||
dir.normalize();
|
||||
mPose.position = eye + dir * Environment::get().unitsPerMeter() * 2.f / 3.f;
|
||||
|
||||
|
||||
mPose.orientation = camera->getViewMatrix().getRotate().inverse();
|
||||
|
||||
if (mMenu)
|
||||
mMenu->updatePose(mPose);
|
||||
|
||||
Log(Debug::Error) << "New menu pose: " << mPose;
|
||||
}
|
||||
}
|
@ -1,83 +0,0 @@
|
||||
#ifndef OPENXR_MENU_HPP
|
||||
#define OPENXR_MENU_HPP
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Camera>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include "openxrview.hpp"
|
||||
#include "openxrlayer.hpp"
|
||||
|
||||
struct XrCompositionLayerQuad;
|
||||
namespace MWVR
|
||||
{
|
||||
class GUICamera;
|
||||
|
||||
class OpenXRMenu
|
||||
{
|
||||
public:
|
||||
OpenXRMenu(
|
||||
osg::ref_ptr<osg::Group> geometryRoot,
|
||||
osg::ref_ptr<osg::Group> cameraRoot,
|
||||
osg::ref_ptr<osg::Node> menuSubgraph,
|
||||
const std::string& title,
|
||||
osg::Vec2 extent_meters,
|
||||
Pose pose,
|
||||
int width,
|
||||
int height,
|
||||
const osg::Vec4& clearColor,
|
||||
osgViewer::Viewer* viewer);
|
||||
~OpenXRMenu();
|
||||
const std::string& title() const { return mTitle; }
|
||||
void updateCallback();
|
||||
|
||||
void preRenderCallback(osg::RenderInfo& renderInfo);
|
||||
void postRenderCallback(osg::RenderInfo& renderInfo);
|
||||
osg::Camera* camera();
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> menuTexture();
|
||||
|
||||
void updatePose(Pose pose);
|
||||
|
||||
public:
|
||||
std::string mTitle;
|
||||
osg::ref_ptr<osg::Group> mGeometryRoot;
|
||||
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mTransform{ new osg::PositionAttitudeTransform };
|
||||
|
||||
osg::ref_ptr<osg::Group> mCameraRoot;
|
||||
osg::ref_ptr<osg::Node> mMenuSubgraph;
|
||||
osg::ref_ptr<osg::StateSet> mStateSet{ new osg::StateSet };
|
||||
osg::ref_ptr<GUICamera> mGUICamera;
|
||||
};
|
||||
|
||||
class OpenXRMenuManager
|
||||
{
|
||||
public:
|
||||
OpenXRMenuManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer);
|
||||
|
||||
~OpenXRMenuManager(void);
|
||||
|
||||
void showMenus(bool show);
|
||||
|
||||
void updatePose(void);
|
||||
|
||||
OpenXRMenu* getMenu(void) const { return mMenu.get(); }
|
||||
|
||||
private:
|
||||
Pose mPose{};
|
||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
||||
|
||||
osg::ref_ptr<osg::Group> mGUIGeometriesRoot{ new osg::Group };
|
||||
osg::ref_ptr<osg::Group> mGUICamerasRoot{ new osg::Group };
|
||||
|
||||
osg::ref_ptr<osg::Node> mGuiRoot{ nullptr };
|
||||
|
||||
std::unique_ptr<OpenXRMenu> mMenu{ nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,512 @@
|
||||
#include "vrgui.hpp"
|
||||
#include "vrenvironment.hpp"
|
||||
#include "openxrsession.hpp"
|
||||
#include "openxrmanagerimpl.hpp"
|
||||
#include "openxrinputmanager.hpp"
|
||||
#include "vranimation.hpp"
|
||||
#include <openxr/openxr.h>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/ClipNode>
|
||||
#include <osg/FrontFace>
|
||||
#include <osg/BlendFunc>
|
||||
#include <osg/Depth>
|
||||
#include <components/sceneutil/visitor.hpp>
|
||||
#include <components/sceneutil/shadow.hpp>
|
||||
#include <components/myguiplatform/myguirendermanager.hpp>
|
||||
#include <osgViewer/Renderer>
|
||||
#include "../mwrender/util.hpp"
|
||||
#include "../mwrender/renderbin.hpp"
|
||||
#include "../mwrender/renderingmanager.hpp"
|
||||
#include "../mwrender/camera.hpp"
|
||||
#include "../mwbase/world.hpp"
|
||||
#include "../mwbase/environment.hpp"
|
||||
#include "../mwgui/windowbase.hpp"
|
||||
|
||||
#include <MyGUI_Widget.h>
|
||||
#include <MyGUI_ILayer.h>
|
||||
#include <MyGUI_InputManager.h>
|
||||
#include <MyGUI_WidgetManager.h>
|
||||
#include <MyGUI_Window.h>
|
||||
|
||||
namespace MWVR
|
||||
{
|
||||
|
||||
/// RTT camera used to draw the osg GUI to a texture
|
||||
class GUICamera : public osg::Camera
|
||||
{
|
||||
public:
|
||||
GUICamera(int width, int height, osg::Vec4 clearColor)
|
||||
{
|
||||
setRenderOrder(osg::Camera::PRE_RENDER);
|
||||
setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
setCullingActive(false);
|
||||
|
||||
// Make the texture just a little transparent to feel more natural in the game world.
|
||||
setClearColor(clearColor);
|
||||
|
||||
setRenderTargetImplementation(osg::Camera::FRAME_BUFFER_OBJECT);
|
||||
setReferenceFrame(osg::Camera::ABSOLUTE_RF);
|
||||
setComputeNearFarMode(osg::CullSettings::DO_NOT_COMPUTE_NEAR_FAR);
|
||||
setName("GUICamera");
|
||||
|
||||
setCullMask(SceneUtil::Mask_GUI);
|
||||
setNodeMask(SceneUtil::Mask_RenderToTexture);
|
||||
|
||||
setViewport(0, 0, width, height);
|
||||
|
||||
// No need for Update traversal since the mSceneRoot is already updated as part of the main scene graph
|
||||
// A double update would mess with the light collection (in addition to being plain redundant)
|
||||
setUpdateCallback(new MWRender::NoTraverseCallback);
|
||||
|
||||
// Create the texture
|
||||
mTexture = new osg::Texture2D;
|
||||
mTexture->setTextureSize(width, height);
|
||||
mTexture->setInternalFormat(GL_RGBA);
|
||||
mTexture->setFilter(osg::Texture::MIN_FILTER, osg::Texture::LINEAR_MIPMAP_LINEAR);
|
||||
mTexture->setFilter(osg::Texture::MAG_FILTER, osg::Texture::LINEAR);
|
||||
mTexture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE);
|
||||
mTexture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_EDGE);
|
||||
attach(osg::Camera::COLOR_BUFFER, mTexture);
|
||||
// Need to regenerate mipmaps every frame
|
||||
setPostDrawCallback(new MWRender::MipmapCallback(mTexture));
|
||||
|
||||
// Do not want to waste time on shadows when generating the GUI texture
|
||||
SceneUtil::ShadowManager::disableShadowsForStateSet(getOrCreateStateSet());
|
||||
|
||||
// Put rendering as early as possible
|
||||
getOrCreateStateSet()->setRenderBinDetails(-1, "RenderBin");
|
||||
|
||||
}
|
||||
|
||||
void setScene(osg::Node* scene)
|
||||
{
|
||||
if (mScene)
|
||||
removeChild(mScene);
|
||||
mScene = scene;
|
||||
addChild(scene);
|
||||
Log(Debug::Verbose) << "Set new scene: " << mScene->getName();
|
||||
}
|
||||
|
||||
osg::Texture2D* getTexture() const
|
||||
{
|
||||
return mTexture.get();
|
||||
}
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osg::Texture2D> mTexture;
|
||||
osg::ref_ptr<osg::Node> mScene;
|
||||
};
|
||||
|
||||
|
||||
class LayerUpdateCallback : public osg::Callback
|
||||
{
|
||||
public:
|
||||
LayerUpdateCallback(VRGUILayer* layer)
|
||||
: mLayer(layer)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
bool run(osg::Object* object, osg::Object* data)
|
||||
{
|
||||
mLayer->update();
|
||||
return traverse(object, data);
|
||||
}
|
||||
|
||||
private:
|
||||
VRGUILayer* mLayer;
|
||||
};
|
||||
|
||||
VRGUILayer::VRGUILayer(
|
||||
osg::ref_ptr<osg::Group> geometryRoot,
|
||||
osg::ref_ptr<osg::Group> cameraRoot,
|
||||
int width,
|
||||
int height,
|
||||
std::string filter,
|
||||
LayerConfig config,
|
||||
MWGui::Layout* widget,
|
||||
VRGUIManager* parent)
|
||||
: mConfig(config)
|
||||
, mFilter(filter)
|
||||
, mWidget(widget)
|
||||
, mWindow(dynamic_cast<MWGui::WindowBase*>(mWidget))
|
||||
, mMyGUIWindow(dynamic_cast<MyGUI::Window*>(mWidget->mMainWidget))
|
||||
, mParent(parent)
|
||||
, mGeometryRoot(geometryRoot)
|
||||
, mCameraRoot(cameraRoot)
|
||||
{
|
||||
osg::ref_ptr<osg::Vec3Array> vertices{ new osg::Vec3Array(4) };
|
||||
osg::ref_ptr<osg::Vec2Array> texCoords{ new osg::Vec2Array(4) };
|
||||
osg::ref_ptr<osg::Vec3Array> normals{ new osg::Vec3Array(1) };
|
||||
|
||||
// Units are divided by 2 because geometry has an extent of 2 (-1 to 1)
|
||||
auto extent_units = config.extent * Environment::get().unitsPerMeter() / 2.f;
|
||||
|
||||
// Define the menu quad
|
||||
osg::Vec3 top_left (-1, 1, 1);
|
||||
osg::Vec3 bottom_left(-1, 1, -1);
|
||||
osg::Vec3 bottom_right(1, 1, -1);
|
||||
osg::Vec3 top_right (1, 1, 1);
|
||||
(*vertices)[0] = top_left;
|
||||
(*vertices)[1] = bottom_left;
|
||||
(*vertices)[2] = bottom_right;
|
||||
(*vertices)[3] = top_right;
|
||||
mGeometry->setVertexArray(vertices);
|
||||
(*texCoords)[0].set(0.0f, 1.0f);
|
||||
(*texCoords)[1].set(0.0f, 0.0f);
|
||||
(*texCoords)[2].set(1.0f, 0.0f);
|
||||
(*texCoords)[3].set(1.0f, 1.0f);
|
||||
mGeometry->setTexCoordArray(0, texCoords);
|
||||
(*normals)[0].set(0.0f, -1.0f, 0.0f);
|
||||
mGeometry->setNormalArray(normals, osg::Array::BIND_OVERALL);
|
||||
mGeometry->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));
|
||||
mGeometry->setDataVariance(osg::Object::DYNAMIC);
|
||||
mGeometry->setSupportsDisplayList(false);
|
||||
mGeometry->setName("VRGUILayer");
|
||||
mGeometry->setUserData(new VRGUILayerUserData(this));
|
||||
|
||||
// Create the camera that will render the menu texture
|
||||
mGUICamera = new GUICamera(width, height, config.backgroundColor);
|
||||
osgMyGUI::RenderManager& renderManager = static_cast<osgMyGUI::RenderManager&>(MyGUI::RenderManager::getInstance());
|
||||
mGUICamera->setScene(renderManager.createGUICamera(osg::Camera::NESTED_RENDER, filter));
|
||||
|
||||
// Define state set that allows rendering with transparency
|
||||
mStateSet->setTextureAttributeAndModes(0, menuTexture(), osg::StateAttribute::ON);
|
||||
mStateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
||||
mStateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
|
||||
mStateSet->setAttributeAndModes(new osg::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA));
|
||||
mStateSet->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
||||
mGeometry->setStateSet(mStateSet);
|
||||
|
||||
// Position in the game world
|
||||
mTransform->setScale(osg::Vec3(extent_units.x(), 1.f, extent_units.y()));
|
||||
mTransform->addChild(mGeometry);
|
||||
|
||||
// Add to scene graph
|
||||
mGeometryRoot->addChild(mTransform);
|
||||
mCameraRoot->addChild(mGUICamera);
|
||||
|
||||
mTransform->addUpdateCallback(new LayerUpdateCallback(this));
|
||||
}
|
||||
|
||||
VRGUILayer::~VRGUILayer()
|
||||
{
|
||||
mGeometryRoot->removeChild(mTransform);
|
||||
mCameraRoot->removeChild(mGUICamera);
|
||||
}
|
||||
osg::Camera* VRGUILayer::camera()
|
||||
{
|
||||
return mGUICamera.get();
|
||||
}
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> VRGUILayer::menuTexture()
|
||||
{
|
||||
if (mGUICamera)
|
||||
return mGUICamera->getTexture();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void VRGUILayer::updatePose()
|
||||
{
|
||||
osg::Vec3 eye{};
|
||||
osg::Vec3 center{};
|
||||
osg::Vec3 up{};
|
||||
|
||||
// Get head pose by reading the camera view matrix to place the GUI in the world.
|
||||
Pose headPose{};
|
||||
auto* world = MWBase::Environment::get().getWorld();
|
||||
if (!world)
|
||||
return;
|
||||
auto* camera = world->getRenderingManager().getCamera()->getOsgCamera();
|
||||
if (!camera)
|
||||
return;
|
||||
camera->getViewMatrixAsLookAt(eye, center, up);
|
||||
headPose.position = eye;
|
||||
headPose.orientation = camera->getViewMatrix().getRotate();
|
||||
|
||||
if (mConfig.trackedLimb == TrackedLimb::HEAD)
|
||||
{
|
||||
mTrackedPose = headPose;
|
||||
mTrackedPose.orientation = mTrackedPose.orientation.inverse();
|
||||
}
|
||||
else
|
||||
{
|
||||
// If it's not head, it's one of the hands, so i don't bother checking
|
||||
auto* session = MWVR::Environment::get().getSession();
|
||||
auto& poses = session->predictedPoses(OpenXRSession::PredictionSlice::Predraw);
|
||||
mTrackedPose = poses.hands[(int)TrackedSpace::STAGE][(int)mConfig.trackedLimb];
|
||||
// World position is the head, so must add difference between head and hand in tracking space to world pose
|
||||
mTrackedPose.position = mTrackedPose.position * MWVR::Environment::get().unitsPerMeter() - poses.head[(int)TrackedSpace::STAGE].position * MWVR::Environment::get().unitsPerMeter() + headPose.position;
|
||||
}
|
||||
|
||||
mLayerPose.orientation = mConfig.rotation * mTrackedPose.orientation;
|
||||
|
||||
if (mConfig.vertical)
|
||||
{
|
||||
// Force layer to be vertical
|
||||
auto axis = osg::Z_AXIS;
|
||||
osg::Quat vertical;
|
||||
auto local = mLayerPose.orientation * axis;
|
||||
vertical.makeRotate(local, axis);
|
||||
mLayerPose.orientation = mLayerPose.orientation * vertical;
|
||||
}
|
||||
// Orient the offset and move the layer
|
||||
mLayerPose.position = mTrackedPose.position + mLayerPose.orientation * mConfig.offset * MWVR::Environment::get().unitsPerMeter();
|
||||
|
||||
mTransform->setAttitude(mLayerPose.orientation);
|
||||
mTransform->setPosition(mLayerPose.position);
|
||||
}
|
||||
|
||||
void VRGUILayer::update()
|
||||
{
|
||||
if (mConfig.trackingMode == TrackingMode::Auto)
|
||||
updatePose();
|
||||
|
||||
if (mConfig.stretch)
|
||||
{
|
||||
if (mWindow && mMyGUIWindow)
|
||||
{
|
||||
mWindow->setCoordf(0.f, 0.f, 1.f, 1.f);
|
||||
mWindow->onWindowResize(mMyGUIWindow);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VRGUIManager::VRGUIManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer)
|
||||
: mOsgViewer(viewer)
|
||||
{
|
||||
mGUIGeometriesRoot->setName("XR GUI Geometry Root");
|
||||
mGUICamerasRoot->setName("XR GUI Cameras Root");
|
||||
auto* root = viewer->getSceneData();
|
||||
|
||||
SceneUtil::FindByNameVisitor findSceneVisitor("Scene Root");
|
||||
root->accept(findSceneVisitor);
|
||||
if(!findSceneVisitor.mFoundNode)
|
||||
{
|
||||
Log(Debug::Error) << "Scene Root doesn't exist";
|
||||
return;
|
||||
}
|
||||
|
||||
findSceneVisitor.mFoundNode->addChild(mGUIGeometriesRoot);
|
||||
root->asGroup()->addChild(mGUICamerasRoot);
|
||||
|
||||
}
|
||||
|
||||
VRGUIManager::~VRGUIManager(void)
|
||||
{
|
||||
}
|
||||
|
||||
void VRGUIManager::showGUIs(bool show)
|
||||
{
|
||||
}
|
||||
|
||||
LayerConfig gDefaultConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
osg::Vec4{0.f,0.f,0.f,.75f}, // background
|
||||
osg::Quat{}, // rotation
|
||||
osg::Vec3(0.f,1.f,0.f), // offset
|
||||
osg::Vec2(1.f, 1.f), // extent (meters)
|
||||
osg::Vec2i(2024,2024), // resolution (pixels)
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
|
||||
LayerConfig gStatusHUDConfig = LayerConfig
|
||||
{
|
||||
false, // stretch
|
||||
osg::Vec4{0.f,0.f,0.f,0.f}, // background
|
||||
osg::Quat{}, // rotation
|
||||
osg::Vec3(0.f,.0f,.2f), // offset (meters)
|
||||
osg::Vec2(.2f, .2f), // extent (meters)
|
||||
osg::Vec2i(1024,512), // resolution (pixels)
|
||||
TrackedLimb::RIGHT_HAND,
|
||||
TrackingMode::Auto,
|
||||
false // vertical
|
||||
};
|
||||
|
||||
LayerConfig gMinimapHUDConfig = LayerConfig
|
||||
{
|
||||
false, // stretch
|
||||
osg::Vec4{0.f,0.f,0.f,0.f}, // background
|
||||
osg::Quat{}, // rotation
|
||||
osg::Vec3(0.f,.0f,.2f), // offset (meters)
|
||||
osg::Vec2(.2f, .2f), // extent (meters)
|
||||
osg::Vec2i(1024,512), // resolution (pixels)
|
||||
TrackedLimb::RIGHT_HAND,
|
||||
TrackingMode::Auto,
|
||||
false // vertical
|
||||
};
|
||||
|
||||
LayerConfig gPopupConfig = LayerConfig
|
||||
{
|
||||
false, // stretch
|
||||
osg::Vec4{0.f,0.f,0.f,0.f}, // background
|
||||
osg::Quat{}, // rotation
|
||||
osg::Vec3(0.f,0.f,.2f), // offset
|
||||
osg::Vec2(.2f, .2f), // extent (meters)
|
||||
osg::Vec2i(1024,1024),
|
||||
TrackedLimb::RIGHT_HAND,
|
||||
TrackingMode::Auto,
|
||||
false // vertical
|
||||
};
|
||||
|
||||
LayerConfig gWindowsConfig = gDefaultConfig;
|
||||
LayerConfig gJournalBooksConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
gDefaultConfig.backgroundColor,
|
||||
osg::Quat{}, // rotation
|
||||
gDefaultConfig.offset,
|
||||
gDefaultConfig.extent,
|
||||
gDefaultConfig.resolution,
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
LayerConfig gSpellWindowConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
gDefaultConfig.backgroundColor,
|
||||
osg::Quat{-osg::PI_2, osg::Z_AXIS}, // rotation
|
||||
gDefaultConfig.offset,
|
||||
gDefaultConfig.extent,
|
||||
gDefaultConfig.resolution,
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
LayerConfig gInventoryWindowConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
gDefaultConfig.backgroundColor,
|
||||
osg::Quat{}, // rotation
|
||||
gDefaultConfig.offset,
|
||||
gDefaultConfig.extent,
|
||||
gDefaultConfig.resolution,
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
LayerConfig gMapWindowConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
gDefaultConfig.backgroundColor,
|
||||
osg::Quat{osg::PI, osg::Z_AXIS}, // rotation
|
||||
gDefaultConfig.offset,
|
||||
gDefaultConfig.extent,
|
||||
gDefaultConfig.resolution,
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
LayerConfig gStatsWindowConfig = LayerConfig
|
||||
{
|
||||
true, // stretch
|
||||
gDefaultConfig.backgroundColor,
|
||||
osg::Quat{osg::PI_2, osg::Z_AXIS}, // rotation
|
||||
gDefaultConfig.offset,
|
||||
gDefaultConfig.extent,
|
||||
gDefaultConfig.resolution,
|
||||
TrackedLimb::HEAD,
|
||||
TrackingMode::Manual,
|
||||
true // vertical
|
||||
};
|
||||
|
||||
|
||||
static std::map<std::string, LayerConfig&> gLayerConfigs =
|
||||
{
|
||||
{"StatusHUD", gStatusHUDConfig},
|
||||
{"MinimapHUD", gMinimapHUDConfig},
|
||||
{"Popup", gPopupConfig},
|
||||
{"Windows", gWindowsConfig},
|
||||
{"JournalBooks", gJournalBooksConfig},
|
||||
{"SpellWindow", gSpellWindowConfig},
|
||||
{"InventoryWindow", gInventoryWindowConfig},
|
||||
{"MapWindow", gMapWindowConfig},
|
||||
{"StatsWindow", gStatsWindowConfig},
|
||||
{"Default", gDefaultConfig},
|
||||
};
|
||||
|
||||
static std::set<std::string> layerBlacklist =
|
||||
{
|
||||
"Overlay"
|
||||
};
|
||||
|
||||
void VRGUIManager::setVisible(MWGui::Layout* widget, bool visible)
|
||||
{
|
||||
auto* layer = widget->mMainWidget->getLayer();
|
||||
//if (!layer)
|
||||
//{
|
||||
// Log(Debug::Warning) << "Hark! MyGUI has betrayed us. The widget " << widget->mMainWidget->getName() << " has no layer";
|
||||
// return;
|
||||
//}
|
||||
auto name = layer->getName();
|
||||
|
||||
Log(Debug::Verbose) << "setVisible (" << name << "): " << visible;
|
||||
if (layerBlacklist.find(name) != layerBlacklist.end())
|
||||
{
|
||||
Log(Debug::Verbose) << "Blacklisted";
|
||||
// Never pick an invisible layer
|
||||
widget->setLayerPick(false);
|
||||
return;
|
||||
}
|
||||
if (visible)
|
||||
{
|
||||
if (mLayers.find(name) == mLayers.end())
|
||||
{
|
||||
LayerConfig config = gDefaultConfig;
|
||||
auto configIt = gLayerConfigs.find(name);
|
||||
if (configIt != gLayerConfigs.end())
|
||||
config = configIt->second;
|
||||
|
||||
mLayers[name] = std::unique_ptr<VRGUILayer>(new VRGUILayer(
|
||||
mGUIGeometriesRoot,
|
||||
mGUICamerasRoot,
|
||||
2048,
|
||||
2048,
|
||||
name,
|
||||
config,
|
||||
widget,
|
||||
this
|
||||
));
|
||||
|
||||
// Default new layer's pick to false
|
||||
widget->setLayerPick(false);
|
||||
|
||||
Log(Debug::Verbose) << "Created GUI layer " << name;
|
||||
}
|
||||
updatePose();
|
||||
}
|
||||
else
|
||||
{
|
||||
auto it = mLayers.find(name);
|
||||
if (it != mLayers.end())
|
||||
{
|
||||
if (it->second.get() == mFocusLayer)
|
||||
setFocusLayer(nullptr);
|
||||
mLayers.erase(it);
|
||||
Log(Debug::Verbose) << "Erased GUI layer " << name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void VRGUIManager::updatePose(void)
|
||||
{
|
||||
for (auto& layer : mLayers)
|
||||
layer.second->updatePose();
|
||||
}
|
||||
|
||||
void VRGUIManager::setFocusLayer(VRGUILayer* layer)
|
||||
{
|
||||
if (mFocusLayer)
|
||||
mFocusLayer->mWidget->setLayerPick(false);
|
||||
mFocusLayer = layer;
|
||||
if (mFocusLayer)
|
||||
mFocusLayer->mWidget->setLayerPick(true);
|
||||
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,129 @@
|
||||
#ifndef OPENXR_MENU_HPP
|
||||
#define OPENXR_MENU_HPP
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <regex>
|
||||
|
||||
#include <osg/Geometry>
|
||||
#include <osg/TexMat>
|
||||
#include <osg/Texture2D>
|
||||
#include <osg/Camera>
|
||||
#include <osg/PositionAttitudeTransform>
|
||||
|
||||
#include "openxrview.hpp"
|
||||
#include "openxrlayer.hpp"
|
||||
|
||||
namespace MyGUI
|
||||
{
|
||||
class Widget;
|
||||
class Window;
|
||||
}
|
||||
|
||||
namespace MWGui
|
||||
{
|
||||
class Layout;
|
||||
class WindowBase;
|
||||
}
|
||||
|
||||
struct XrCompositionLayerQuad;
|
||||
namespace MWVR
|
||||
{
|
||||
class GUICamera;
|
||||
class VRGUIManager;
|
||||
|
||||
enum class TrackingMode
|
||||
{
|
||||
Auto, //!< Update tracking every frame
|
||||
Manual //!< Update tracking only on user request or when GUI visibility changes.
|
||||
};
|
||||
|
||||
struct LayerConfig
|
||||
{
|
||||
bool stretch; //!< Resize layer window to occupy full quad
|
||||
osg::Vec4 backgroundColor; //!< Background color of layer
|
||||
osg::Quat rotation; //!< Rotation relative to the tracking node
|
||||
osg::Vec3 offset; //!< Offset from tracked node in meters
|
||||
osg::Vec2 extent; //!< Spatial extent of the layer in meters
|
||||
osg::Vec2i resolution; //!< Pixel resolution of the texture
|
||||
TrackedLimb trackedLimb; //!< Which limb to track
|
||||
TrackingMode trackingMode; //!< Tracking mode
|
||||
bool vertical; //!< Make layer vertical regardless of tracking orientation
|
||||
};
|
||||
|
||||
class VRGUILayer
|
||||
{
|
||||
public:
|
||||
VRGUILayer(
|
||||
osg::ref_ptr<osg::Group> geometryRoot,
|
||||
osg::ref_ptr<osg::Group> cameraRoot,
|
||||
int width,
|
||||
int height,
|
||||
std::string filter,
|
||||
LayerConfig config,
|
||||
MWGui::Layout* widget,
|
||||
VRGUIManager* parent);
|
||||
~VRGUILayer();
|
||||
|
||||
osg::Camera* camera();
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> menuTexture();
|
||||
|
||||
void updatePose();
|
||||
void update();
|
||||
|
||||
public:
|
||||
Pose mTrackedPose{};
|
||||
Pose mLayerPose{};
|
||||
LayerConfig mConfig;
|
||||
std::string mFilter;
|
||||
MWGui::Layout* mWidget;
|
||||
MWGui::WindowBase* mWindow;
|
||||
MyGUI::Window* mMyGUIWindow;
|
||||
VRGUIManager* mParent;
|
||||
osg::ref_ptr<osg::Group> mGeometryRoot;
|
||||
osg::ref_ptr<osg::Geometry> mGeometry{ new osg::Geometry };
|
||||
osg::ref_ptr<osg::PositionAttitudeTransform> mTransform{ new osg::PositionAttitudeTransform };
|
||||
|
||||
osg::ref_ptr<osg::Group> mCameraRoot;
|
||||
osg::ref_ptr<osg::StateSet> mStateSet{ new osg::StateSet };
|
||||
osg::ref_ptr<GUICamera> mGUICamera;
|
||||
};
|
||||
|
||||
class VRGUILayerUserData : public osg::Referenced
|
||||
{
|
||||
public:
|
||||
VRGUILayerUserData(VRGUILayer* layer) : mLayer(layer) {};
|
||||
|
||||
VRGUILayer* mLayer;
|
||||
};
|
||||
|
||||
class VRGUIManager
|
||||
{
|
||||
public:
|
||||
VRGUIManager(
|
||||
osg::ref_ptr<osgViewer::Viewer> viewer);
|
||||
|
||||
~VRGUIManager(void);
|
||||
|
||||
void showGUIs(bool show);
|
||||
|
||||
void setVisible(MWGui::Layout*, bool visible);
|
||||
|
||||
void updatePose(void);
|
||||
|
||||
void setFocusLayer(VRGUILayer* layer);
|
||||
|
||||
private:
|
||||
osg::ref_ptr<osgViewer::Viewer> mOsgViewer{ nullptr };
|
||||
|
||||
osg::ref_ptr<osg::Group> mGUIGeometriesRoot{ new osg::Group };
|
||||
osg::ref_ptr<osg::Group> mGUICamerasRoot{ new osg::Group };
|
||||
|
||||
std::map<std::string, std::unique_ptr<VRGUILayer>> mLayers;
|
||||
|
||||
VRGUILayer* mFocusLayer{ nullptr };
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
@ -0,0 +1,10 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<MyGUI>
|
||||
<MyGUI type="List">
|
||||
<List file="skins.xml" />
|
||||
<List file="openmw_layers_vr.xml" />
|
||||
<List file="openmw_pointer.xml" />
|
||||
<List file="openmw_settings.xml" />
|
||||
</MyGUI>
|
||||
</MyGUI>
|
||||
|
@ -0,0 +1,132 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Widget" layer="StatusHUD" position="0 0 185 80" name="_Main" align="Default">
|
||||
<!-- Spell effects box -->
|
||||
<Widget type="Widget" skin="HUD_Box_Transparent" position="0 15 20 20" align="Left Bottom" name="EffectBox">
|
||||
</Widget>
|
||||
<!-- Energy bars -->
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Yellow" position="0 0 65 12" align="Left Bottom" name="EnemyHealth">
|
||||
<Property key="Visible" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="" position="0 38 65 12" align="Left Bottom" name="HealthFrame">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\health.dds"/>
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Red" position="0 0 65 12" align="Left Bottom" name="Health">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="" position="0 53 65 12" align="Left Bottom" name="MagickaFrame">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\magicka.dds"/>
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Blue" position="0 0 65 12" align="Left Bottom" name="Magicka">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="Button" skin="" position="0 68 65 12" align="Left Bottom" name="FatigueFrame">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\fatigue.dds"/>
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Green" position="0 0 65 12" align="Left Bottom" name="Stamina">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Equipped weapon box -->
|
||||
<Widget type="Button" skin="" position="69 38 36 41" align="Left Bottom" name="WeapBox">
|
||||
<Widget type="Widget" skin="HUD_Box" position="0 0 36 36">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Widget type="ItemWidget" skin="MW_ItemIconNoShadow" position="-3 -3 42 42" align="Left Top" name="WeapImage">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Weapon" position="0 36 36 6" align="Left Bottom" name="WeapStatus">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Selected spell box -->
|
||||
<Widget type="Button" position="109 38 36 41" align="Left Bottom" name="SpellBox">
|
||||
<Widget type="Widget" skin="HUD_Box" position="0 0 36 36">
|
||||
<Widget type="SpellWidget" skin="MW_ItemIconNoShadow" position="-3 -3 42 42" align="Left Top" name="SpellImage"/>
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="ProgressBar" skin="MW_EnergyBar_Magic" position="0 36 36 6" align="Left Bottom" name="SpellStatus">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Sneak indicator box -->
|
||||
<Widget type="Button" skin="" position="149 38 36 36" align="Left Bottom" name="SneakBox">
|
||||
<Property key="Visible" value="false"/>
|
||||
<Widget type="Widget" skin="HUD_Box" position="0 0 36 36">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Widget type="ImageBox" skin="ImageBox" position="2 2 32 32" align="Left Top" name="SneakImage">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Property key="ImageTexture" value="icons\k\stealth_sneak.dds"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
<Widget type="Widget" layer="MiniMapHUD" position="0 0 300 92" name="_Main2" align="Stretch">
|
||||
<!-- Drowning bar -->
|
||||
<Widget type="Window" skin="MW_Dialog" position="0 36 230 58" align="Center Top" name="DrowningFrame">
|
||||
<Property key="Visible" value="false"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 3 222 24" name="DrowningTitle" align="Center Top HStretch">
|
||||
<Property key="Caption" value="#{sBreath}"/>
|
||||
<Property key="TextAlign" value="Center"/>
|
||||
<Property key="TextShadow" value="true"/>
|
||||
<Property key="TextShadowColour" value="0 0 0"/>
|
||||
</Widget>
|
||||
<Widget type="Widget" skin="MW_Box" position="11 29 200 10" align="Stretch" name="BoundingBox"/>
|
||||
<Widget type="ProgressBar" skin="MW_Progress_Drowning_Full" position="13 31 196 6" align="Center Top" name="Drowning">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="Widget" skin="MW_Progress_Drowning_Small" position="15 33 192 2" align="Center Top" name="Flash"/>
|
||||
</Widget>
|
||||
|
||||
<!-- Equipped weapon/selected spell name display for a few seconds after it changes -->
|
||||
<Widget type="TextBox" skin="SandText" position="13 118 270 24" name="WeaponSpellName" align="Left Bottom HStretch">
|
||||
<Property key="Visible" value="false"/>
|
||||
<Property key="TextAlign" value="Left"/>
|
||||
<Property key="TextShadow" value="true"/>
|
||||
<Property key="TextShadowColour" value="0 0 0"/>
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
|
||||
<!-- Cell name display when cell changes -->
|
||||
<Widget type="TextBox" skin="SandText" position="0 89 288 24" name="CellName" align="Left Bottom HStretch">
|
||||
<Property key="Visible" value="false"/>
|
||||
<Property key="TextAlign" value="Right"/>
|
||||
<Property key="TextShadow" value="true"/>
|
||||
<Property key="TextShadowColour" value="0 0 0"/>
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
|
||||
<!-- Map box -->
|
||||
<Widget type="Widget" skin="" position="223 15 65 65" name="MiniMapBox" align="Right Bottom">
|
||||
<Widget type="Widget" skin="HUD_Box" position="0 0 65 65" align="Center">
|
||||
|
||||
<Widget type="ScrollView" skin="MW_MapView" position="2 2 61 61" align="Left Bottom" name="MiniMap">
|
||||
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="Bottom Left" name="Compass">
|
||||
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position_real="0 0 1 1" name="MiniMapButton" align="Stretch">
|
||||
<Property key="Depth" value="10"/>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Crosshair -->
|
||||
<Widget type="ImageBox" skin="HUD_Crosshair" position="0 0 32 32" align="Center Center" name="Crosshair">
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</MyGUI>
|
@ -0,0 +1,63 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window_Pinnable" layer="InventoryWindow" position="0 0 600 300" name="_Main">
|
||||
<Property key="MinSize" value="40 40"/>
|
||||
|
||||
<Widget type="Widget" skin="" position="0 0 224 223" align="Left Top" name="LeftPane">
|
||||
|
||||
<!-- Player encumbrance -->
|
||||
<Widget type="MWDynamicStat" skin="MW_ChargeBar_Blue" position="8 8 212 24" name="EncumbranceBar" align="Left Top HStretch">
|
||||
</Widget>
|
||||
|
||||
<!-- Avatar -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 38 212 185" name="Avatar" align="Left Top Stretch">
|
||||
<Widget type="ImageBox" skin="ImageBox" position="3 3 206 158" align="Stretch" name="AvatarImage">
|
||||
<UserString key="ToolTipType" value="AvatarItemSelection"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="ProgressText" position="0 161 212 24" align="HStretch Bottom" name="ArmorRating">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
|
||||
<Widget type="Widget" skin="" position="228 0 350 223" align="Left Top" name="RightPane">
|
||||
|
||||
<!-- Items in inventory -->
|
||||
<Widget type="ItemView" skin="MW_ItemView" position="0 38 350 185" name="ItemView" align="Left Top Stretch">
|
||||
</Widget>
|
||||
|
||||
<!-- Categories -->
|
||||
<Widget type="HBox" position="0 6 350 28" align="Left Top HStretch" name="Categories">
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 60 24" name="AllButton">
|
||||
<Property key="Caption" value="#{sAllTab}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 60 24" name="WeaponButton">
|
||||
<Property key="Caption" value="#{sWeaponTab}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 60 24" name="ApparelButton">
|
||||
<Property key="Caption" value="#{sApparelTab}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 60 24" name="MagicButton">
|
||||
<Property key="Caption" value="#{sMagicTab}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="0 0 60 24" name="MiscButton">
|
||||
<Property key="Caption" value="#{sMiscTab}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
<!-- Search box-->
|
||||
<Widget type="EditBox" skin="MW_TextBoxEditWithBorder" position="0 0 0 23" name="FilterEdit">
|
||||
<UserString key="HStretch" value="true"/>
|
||||
<UserString key="AcceptTab" value="true"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</MyGUI>
|
@ -0,0 +1,26 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layer" version="1.0">
|
||||
<Layer name="Scene" overlapped="false" pick="false"/>
|
||||
<Layer name="Overlay" overlapped="false" pick="false"/>
|
||||
<Layer name="AdditiveOverlay" type="AdditiveLayer" pick="false"/>
|
||||
<Layer name="StatusHUD" overlapped="false" pick="true"/>
|
||||
<Layer name="MiniMapHUD" overlapped="false" pick="true"/>
|
||||
<Layer name="Menu" overlapped="false" pick="true"/>
|
||||
<Layer name="InventoryWindow" overlapped="true" pick="true"/>
|
||||
<Layer name="SpellWindow" overlapped="true" pick="true"/>
|
||||
<Layer name="MapWindow" overlapped="true" pick="true"/>
|
||||
<Layer name="StatsWindow" overlapped="true" pick="true"/>
|
||||
<Layer name="Windows" overlapped="true" pick="true"/>
|
||||
<Layer name="JournalBooks" type="ScalingLayer" pick="true">
|
||||
<Property key="Size" value="600 520"/>
|
||||
</Layer>
|
||||
<Layer name="Debug" overlapped="true" pick="true"/>
|
||||
<Layer name="Notification" overlapped="false" pick="false"/>
|
||||
<Layer name="Popup" overlapped="true" pick="true"/>
|
||||
<Layer name="DragAndDrop" overlapped="false" pick="false"/>
|
||||
<Layer name="LoadingScreen" overlapped="false" pick="true"/>
|
||||
<Layer name="MessageBox" overlapped="false" pick="true"/>
|
||||
<Layer name="InputBlocker" overlapped="false" pick="true"/>
|
||||
<Layer name="Pointer" overlapped="false" pick="false"/>
|
||||
</MyGUI>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window_Pinnable" layer="MapWindow" position="0 0 300 300" name="_Main">
|
||||
<Property key="MinSize" value="40 40"/>
|
||||
|
||||
<!-- Local map -->
|
||||
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="Stretch" name="LocalMap">
|
||||
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="Top Left" name="CompassLocal">
|
||||
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position_real="0 0 1 1" name="EventBoxLocal" align="Stretch">
|
||||
<Property key="Depth" value="10"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Global map -->
|
||||
<Widget type="ScrollView" skin="MW_MapView" position="0 0 284 264" align="Stretch" name="GlobalMap">
|
||||
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="GlobalMapImage">
|
||||
<Widget type="ImageBox" skin="ImageBox" position_real="0 0 1 1" align="Stretch" name="GlobalMapOverlay"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="ImageBox" skin="RotatingSkin" position="0 0 32 32" align="Top Left" name="CompassGlobal">
|
||||
<Property key="ImageTexture" value="textures\compass.dds"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position_real="0 0 1 1" name="EventBoxGlobal" align="Stretch"/>
|
||||
</Widget>
|
||||
|
||||
<!-- World button -->
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" position="213 233 61 22" align="Bottom Right" name="WorldButton">
|
||||
<Property key="ExpandDirection" value="Left"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</MyGUI>
|
@ -0,0 +1,31 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window_Pinnable" layer="SpellWindow" position="0 0 300 600" name="_Main">
|
||||
<Property key="MinSize" value="40 40"/>
|
||||
|
||||
<!-- Effect box-->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 8 268 23" align="Left Top HStretch">
|
||||
<Widget type="Widget" skin="" position="2 1 264 20" align="Left Top Stretch" name="EffectsBox"/>
|
||||
</Widget>
|
||||
|
||||
<!-- Spell list -->
|
||||
<Widget type="SpellView" skin="MW_SpellView" position="8 38 268 490" align="Left Top Stretch" name="SpellView">
|
||||
</Widget>
|
||||
|
||||
<Widget type="HBox" position="8 535 268 23" align="Right Bottom HStretch">
|
||||
<Widget type="Spacer"/>
|
||||
<!-- Spell deletion button -->
|
||||
<Widget type="AutoSizedButton" skin="MW_Button" align="Right Bottom" position="8 535 0 23" name="DeleteSpellButton">
|
||||
<Property key="Caption" value="#{sDelete}"/>
|
||||
<Property key="NeedKey" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Search box-->
|
||||
<Widget type="EditBox" skin="MW_TextBoxEditWithBorder" position="8 535 268 23" align="Left Bottom HStretch" name="FilterEdit">
|
||||
<UserString key="AcceptTab" value="true"/>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</MyGUI>
|
@ -0,0 +1,246 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<MyGUI type="Layout">
|
||||
<Widget type="Window" skin="MW_Window_Pinnable" layer="StatsWindow" position="0 0 500 342" name="_Main">
|
||||
<Property key="MinSize" value="244 114"/>
|
||||
<Widget type="Widget" skin="" name="LeftPane" position="0 0 220 342">
|
||||
<UserString key="LeftOffsetWidth" value="24"/>
|
||||
<UserString key="LeftPaneRatio" value="0.44"/>
|
||||
|
||||
<!-- Player health stats -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 8 212 62" align="Left Top HStretch">
|
||||
<!-- Health -->
|
||||
<Widget type="Widget" skin="" position="4 4 204 18" name="Health" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="true"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\health.dds"/>
|
||||
<Widget type="TextBox" skin="NormalText" position="0 0 70 18" name="Health_str" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Property key="Caption" value="#{sHealth}"/>
|
||||
</Widget>
|
||||
<Widget type="ProgressBar" skin="MW_Progress_Red" position="74 0 130 18" name="HBar" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Widget type="TextBox" skin="ProgressText" position="0 0 130 14" name="HBarT" align="Right VCenter">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Magicka -->
|
||||
<Widget type="Widget" skin="" position="4 22 204 18" name="Magicka" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="true"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\magicka.dds"/>
|
||||
|
||||
<Widget type="TextBox" skin="NormalText" position="0 0 70 18" name="Magicka_str" align="Left Top HStretch">
|
||||
<Property key="Caption" value="#{sMagic}"/>
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="ProgressBar" skin="MW_Progress_Blue" position="74 0 130 18" name="MBar" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Widget type="TextBox" skin="ProgressText" position="0 0 130 14" name="MBarT" align="Right VCenter">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Fatigue -->
|
||||
<Widget type="Widget" skin="" position="4 40 204 18" name="Fatigue" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="true"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="HealthToolTip"/>
|
||||
<UserString key="ImageTexture_HealthImage" value="icons\k\fatigue.dds"/>
|
||||
|
||||
<Widget type="TextBox" skin="NormalText" position="0 0 70 18" name="Fatigue_str" align="Left Top HStretch">
|
||||
<Property key="Caption" value="#{sFatigue}"/>
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
|
||||
<Widget type="ProgressBar" skin="MW_Progress_Green" position="74 0 130 18" name="FBar" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
<Widget type="TextBox" skin="ProgressText" position="0 0 130 14" name="FBarT" align="Right VCenter">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<!-- Player level, race and class -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 78 212 62" align="Top HStretch">
|
||||
<Widget type="HBox" position="4 4 204 18" align="Top HStretch">
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 200 18" name="Level_str" align="Left Top">
|
||||
<Property key="Caption" value="#{sLevel}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="200 0 40 18" name="LevelText" align="Right Top">
|
||||
<Property key="TextAlign" value="Right Top"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="LevelToolTip"/>
|
||||
<UserString key="HStretch" value="true"/>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
<Widget type="HBox" position="4 24 204 18" align="Top HStretch">
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 95 18" name="Race_str" align="Left Top">
|
||||
<Property key="Caption" value="#{sRace}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="RaceToolTip"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="104 0 200 18" name="RaceText" align="Left Top">
|
||||
<Property key="TextAlign" value="Right Top"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="RaceToolTip"/>
|
||||
<UserString key="HStretch" value="true"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
<Widget type="HBox" position="4 42 204 18" align="Top HStretch">
|
||||
<Widget type="AutoSizedTextBox" skin="NormalText" position="0 0 95 18" name="Class_str" align="Left Top">
|
||||
<Property key="Caption" value="#{sClass}"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="104 0 200 18" name="ClassText" align="Left Top">
|
||||
<Property key="TextAlign" value="Right Top"/>
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="ClassToolTip"/>
|
||||
<UserString key="HStretch" value="true"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Widget" skin="MW_Box" position="8 148 212 152" align="Left Top Stretch">
|
||||
<!-- TODO: this should be a scroll view -->
|
||||
<Widget type="Widget" skin="" position="4 4 204 144" align="Left Top Stretch">
|
||||
<Widget type="Button" skin="" position="0 0 204 18" name="Attrib1Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeStrength}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sStrDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_strength.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib1" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal1" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 18 204 18" name="Attrib2Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeIntelligence}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sIntDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_int.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib2" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal2" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 36 204 18" name="Attrib3Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeWillpower}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sWilDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_wilpower.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib3" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal3" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 54 204 18" name="Attrib4Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeAgility}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sAgiDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_agility.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib4" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal4" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 72 204 18" name="Attrib5Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeSpeed}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sSpdDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_speed.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib5" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal5" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 90 204 18" name="Attrib6Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeEndurance}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sEndDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_endurance.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib6" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal6" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 108 204 18" name="Attrib7Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributePersonality}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sPerDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_personality.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib7" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal7" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
<Widget type="Button" skin="" position="0 126 204 18" name="Attrib8Box" align="Left Top HStretch">
|
||||
<UserString key="ToolTipType" value="Layout"/>
|
||||
<UserString key="ToolTipLayout" value="AttributeToolTip"/>
|
||||
<UserString key="Caption_AttributeName" value="#{sAttributeLuck}"/>
|
||||
<UserString key="Caption_AttributeDescription" value="#{sLucDesc}"/>
|
||||
<UserString key="ImageTexture_AttributeImage" value="icons\k\attribute_luck.dds"/>
|
||||
<Widget type="TextBox" skin="SandText" position="0 0 160 18" name="Attrib8" align="Left Top HStretch">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
<Widget type="TextBox" skin="SandTextRight" position="160 0 44 18" name="AttribVal8" align="Right Top">
|
||||
<Property key="NeedMouse" value="false"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
|
||||
<Widget type="Widget" skin="" name="RightPane" position="220 0 280 342">
|
||||
|
||||
<!-- Player skills, factions, birthsign and reputation -->
|
||||
<Widget type="Widget" skin="MW_Box" position="8 8 248 292" align="Left Stretch" name="Skills">
|
||||
<Widget type="ScrollView" skin="MW_ScrollView" position="4 4 240 284" align="Left Top Stretch" name="SkillView">
|
||||
<Property key="CanvasAlign" value="Left Top"/>
|
||||
</Widget>
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
|
||||
</Widget>
|
||||
</MyGUI>
|
Loading…
Reference in New Issue