You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
openmw/apps/opencs/view/render/cellarrow.cpp

193 lines
5.4 KiB
C++

#include "cellarrow.hpp"
#include <osg/Group>
#include <osg/PositionAttitudeTransform>
#include <osg/Billboard>
#include <osg/Geometry>
#include <osg/PrimitiveSet>
#include "../../model/prefs/state.hpp"
#include <components/misc/constants.hpp>
#include "mask.hpp"
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;
auto *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);
auto *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);
auto *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);
geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF);
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;
}