Something went wrong. Try again.
OpenMW is an open implementation of the Morrowind engine
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231#include "cellarrow.hpp"
#include <osg/Array>#include <osg/GL>#include <osg/Geometry>#include <osg/Group>#include <osg/Math>#include <osg/PositionAttitudeTransform>#include <osg/PrimitiveSet>#include <osg/Quat>#include <osg/StateAttribute>#include <osg/StateSet>#include <osg/Vec3f>#include <osg/Vec4f>
#include "../../model/prefs/state.hpp"
#include <apps/opencs/model/prefs/shortcutmanager.hpp>#include <apps/opencs/model/world/cellcoordinates.hpp>#include <apps/opencs/view/render/tagbase.hpp>
#include <components/misc/constants.hpp>
#include "mask.hpp"
namespace CSVRender{ struct WorldspaceHitResult;}
CSVRender::CellArrowTag::CellArrowTag(CellArrow* arrow) : TagBase(Mask_CellArrow) , mArrow(arrow){}
CSVRender::CellArrow* CSVRender::CellArrowTag::getCellArrow() const{ return mArrow;}
QString CSVRender::CellArrowTag::getToolTip(bool hideBasics, const WorldspaceHitResult& /*hit*/) const{ QString text("Direction: ");
switch (mArrow->getDirection()) { case CellArrow::Direction_North: text += "North"; break; case CellArrow::Direction_West: text += "West"; break; case CellArrow::Direction_South: text += "South"; break; case CellArrow::Direction_East: text += "East"; break; }
if (!hideBasics) { text += "<p>" "Modify which cells are shown" "<ul><li>{scene-edit-primary}: Add cell in given direction</li>" "<li>{scene-edit-secondary}: Add cell and remove old cell</li>" "<li>{scene-select-primary}: Add cells in given direction</li>" "<li>{scene-select-secondary}: Add cells and remove old cells</li>" "<li>{scene-load-cam-cell}: Load cell where camera is located</li>" "<li>{scene-load-cam-eastcell}: Load cell to east</li>" "<li>{scene-load-cam-northcell}: Load cell to north</li>" "<li>{scene-load-cam-westcell}: Load cell to west</li>" "<li>{scene-load-cam-southcell}: Load cell to south</li>" "</ul>"; }
return CSMPrefs::State::get().getShortcutManager().processToolTip(text);}
void CSVRender::CellArrow::adjustTransform(){ // position const int cellSize = Constants::CellSizeInUnits; const int offset = cellSize / 2 + 600;
int x = mCoordinates.getX() * cellSize + cellSize / 2; int y = mCoordinates.getY() * cellSize + cellSize / 2;
float xr = 0; float yr = 0; float zr = 0;
float angle = osg::DegreesToRadians(90.0f);
switch (mDirection) { case Direction_North: y += offset; xr = -angle; zr = angle; break; case Direction_West: x -= offset; yr = -angle; break; case Direction_South: y -= offset; xr = angle; zr = angle; break; case Direction_East: x += offset; yr = angle; break; };
mBaseNode->setPosition(osg::Vec3f(x, y, 0));
// orientation osg::Quat xr2(xr, osg::Vec3f(1, 0, 0)); osg::Quat yr2(yr, osg::Vec3f(0, 1, 0)); osg::Quat zr2(zr, osg::Vec3f(0, 0, 1)); mBaseNode->setAttitude(zr2 * yr2 * xr2);}
void CSVRender::CellArrow::buildShape(){ osg::ref_ptr<osg::Geometry> geometry(new osg::Geometry);
const int arrowWidth = 2700; const int arrowLength = 1350; const int arrowHeight = 300;
osg::Vec3Array* vertices = new osg::Vec3Array; for (int i2 = 0; i2 < 2; ++i2) for (int i = 0; i < 2; ++i) { float height = i ? -arrowHeight / 2 : arrowHeight / 2; vertices->push_back(osg::Vec3f(height, -arrowWidth / 2, 0)); vertices->push_back(osg::Vec3f(height, arrowWidth / 2, 0)); vertices->push_back(osg::Vec3f(height, 0, arrowLength)); }
geometry->setVertexArray(vertices);
osg::DrawElementsUShort* primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES, 0);
// top primitives->push_back(0); primitives->push_back(1); primitives->push_back(2);
// bottom primitives->push_back(5); primitives->push_back(4); primitives->push_back(3);
// back primitives->push_back(3 + 6); primitives->push_back(4 + 6); primitives->push_back(1 + 6);
primitives->push_back(3 + 6); primitives->push_back(1 + 6); primitives->push_back(0 + 6);
// sides primitives->push_back(0 + 6); primitives->push_back(2 + 6); primitives->push_back(5 + 6);
primitives->push_back(0 + 6); primitives->push_back(5 + 6); primitives->push_back(3 + 6);
primitives->push_back(4 + 6); primitives->push_back(5 + 6); primitives->push_back(2 + 6);
primitives->push_back(4 + 6); primitives->push_back(2 + 6); primitives->push_back(1 + 6);
geometry->addPrimitiveSet(primitives);
osg::Vec4Array* colours = new osg::Vec4Array;
for (int i = 0; i < 6; ++i) colours->push_back(osg::Vec4f(0.11f, 0.6f, 0.95f, 1.0f)); for (int i = 0; i < 6; ++i) colours->push_back(osg::Vec4f(0.08f, 0.44f, 0.7f, 1.0f));
geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX);
mBaseNode->addChild(geometry);}
CSVRender::CellArrow::CellArrow(osg::Group* cellNode, Direction direction, const CSMWorld::CellCoordinates& coordinates) : mDirection(direction) , mParentNode(cellNode) , mCoordinates(coordinates){ mBaseNode = new osg::PositionAttitudeTransform;
mBaseNode->setUserData(new CellArrowTag(this));
mParentNode->addChild(mBaseNode);
mBaseNode->setNodeMask(Mask_CellArrow);
adjustTransform(); buildShape();}
CSVRender::CellArrow::~CellArrow(){ mParentNode->removeChild(mBaseNode);}
CSMWorld::CellCoordinates CSVRender::CellArrow::getCoordinates() const{ return mCoordinates;}
CSVRender::CellArrow::Direction CSVRender::CellArrow::getDirection() const{ return mDirection;}