|
|
|
@ -3,6 +3,7 @@
|
|
|
|
|
#include <stdexcept>
|
|
|
|
|
#include <iostream>
|
|
|
|
|
|
|
|
|
|
#include <osg/Depth>
|
|
|
|
|
#include <osg/Group>
|
|
|
|
|
#include <osg/PositionAttitudeTransform>
|
|
|
|
|
|
|
|
|
@ -21,6 +22,7 @@
|
|
|
|
|
#include "../../model/world/universalid.hpp"
|
|
|
|
|
#include "../../model/world/commandmacro.hpp"
|
|
|
|
|
#include "../../model/world/cellcoordinates.hpp"
|
|
|
|
|
#include "../../model/prefs/state.hpp"
|
|
|
|
|
|
|
|
|
|
#include <components/resource/scenemanager.hpp>
|
|
|
|
|
#include <components/sceneutil/lightutil.hpp>
|
|
|
|
@ -220,7 +222,7 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeMoveOrScaleMarker (int axis)
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<2; ++i)
|
|
|
|
|
{
|
|
|
|
|
float length = i ? shaftLength : 0;
|
|
|
|
|
float length = i ? shaftLength : MarkerShaftWidth;
|
|
|
|
|
|
|
|
|
|
vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, -MarkerShaftWidth/2, length, axis));
|
|
|
|
|
vertices->push_back (getMarkerPosition (-MarkerShaftWidth/2, MarkerShaftWidth/2, length, axis));
|
|
|
|
@ -285,15 +287,15 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeMoveOrScaleMarker (int axis)
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<8; ++i)
|
|
|
|
|
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f,
|
|
|
|
|
axis==2 ? 1.0f : 0.2f, 1.0f));
|
|
|
|
|
axis==2 ? 1.0f : 0.2f, mMarkerTransparency));
|
|
|
|
|
|
|
|
|
|
for (int i=8; i<8+4+1; ++i)
|
|
|
|
|
colours->push_back (osg::Vec4f (axis==0 ? 1.0f : 0.0f, axis==1 ? 1.0f : 0.0f,
|
|
|
|
|
axis==2 ? 1.0f : 0.0f, 1.0f));
|
|
|
|
|
axis==2 ? 1.0f : 0.0f, mMarkerTransparency));
|
|
|
|
|
|
|
|
|
|
geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX);
|
|
|
|
|
|
|
|
|
|
geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF);
|
|
|
|
|
setupCommonMarkerState(geometry);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Geode> geode (new osg::Geode);
|
|
|
|
|
geode->addDrawable (geometry);
|
|
|
|
@ -305,11 +307,11 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeRotateMarker (int axis)
|
|
|
|
|
{
|
|
|
|
|
const float Pi = 3.14159265f;
|
|
|
|
|
|
|
|
|
|
const float InnerRadius = mBaseNode->getBound().radius();
|
|
|
|
|
const float InnerRadius = std::max(MarkerShaftBaseLength, mBaseNode->getBound().radius());
|
|
|
|
|
const float OuterRadius = InnerRadius + MarkerShaftWidth;
|
|
|
|
|
|
|
|
|
|
const float SegmentDistance = 100.f;
|
|
|
|
|
const size_t SegmentCount = std::min(64, std::max(8, (int)(OuterRadius * 2 * Pi / SegmentDistance)));
|
|
|
|
|
const size_t SegmentCount = std::min(64, std::max(24, (int)(OuterRadius * 2 * Pi / SegmentDistance)));
|
|
|
|
|
const size_t VerticesPerSegment = 4;
|
|
|
|
|
const size_t IndicesPerSegment = 24;
|
|
|
|
|
|
|
|
|
@ -334,6 +336,9 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeRotateMarker (int axis)
|
|
|
|
|
osg::ref_ptr<osg::DrawElementsUShort> primitives = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES,
|
|
|
|
|
IndexCount);
|
|
|
|
|
|
|
|
|
|
// prevent some depth collision issues from overlaps
|
|
|
|
|
osg::Vec3f offset = getMarkerPosition(0, MarkerShaftWidth/4, 0, axis);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < SegmentCount; ++i)
|
|
|
|
|
{
|
|
|
|
|
size_t index = i * VerticesPerSegment;
|
|
|
|
@ -344,13 +349,17 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeRotateMarker (int axis)
|
|
|
|
|
float outerX = OuterRadius * std::cos(i * Angle);
|
|
|
|
|
float outerY = OuterRadius * std::sin(i * Angle);
|
|
|
|
|
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis);
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis);
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis);
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis);
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(innerX, innerY, MarkerShaftWidth / 2, axis) + offset;
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(innerX, innerY, -MarkerShaftWidth / 2, axis) + offset;
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(outerX, outerY, MarkerShaftWidth / 2, axis) + offset;
|
|
|
|
|
vertices->at(index++) = getMarkerPosition(outerX, outerY, -MarkerShaftWidth / 2, axis) + offset;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
colors->at(0) = osg::Vec4f (axis==0 ? 1.0f : 0.2f, axis==1 ? 1.0f : 0.2f, axis==2 ? 1.0f : 0.2f, 1.0f);
|
|
|
|
|
colors->at(0) = osg::Vec4f (
|
|
|
|
|
axis==0 ? 1.0f : 0.2f,
|
|
|
|
|
axis==1 ? 1.0f : 0.2f,
|
|
|
|
|
axis==2 ? 1.0f : 0.2f,
|
|
|
|
|
mMarkerTransparency);
|
|
|
|
|
|
|
|
|
|
for (size_t i = 0; i < SegmentCount; ++i)
|
|
|
|
|
{
|
|
|
|
@ -374,7 +383,7 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeRotateMarker (int axis)
|
|
|
|
|
geometry->setColorArray(colors, osg::Array::BIND_OVERALL);
|
|
|
|
|
geometry->addPrimitiveSet(primitives);
|
|
|
|
|
|
|
|
|
|
geometry->getOrCreateStateSet()->setMode (GL_LIGHTING, osg::StateAttribute::OFF);
|
|
|
|
|
setupCommonMarkerState(geometry);
|
|
|
|
|
|
|
|
|
|
osg::ref_ptr<osg::Geode> geode = new osg::Geode();
|
|
|
|
|
geode->addDrawable (geometry);
|
|
|
|
@ -382,6 +391,15 @@ osg::ref_ptr<osg::Node> CSVRender::Object::makeRotateMarker (int axis)
|
|
|
|
|
return geode;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::Object::setupCommonMarkerState(osg::ref_ptr<osg::Geometry> geometry)
|
|
|
|
|
{
|
|
|
|
|
osg::ref_ptr<osg::StateSet> state = geometry->getOrCreateStateSet();
|
|
|
|
|
state->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
|
|
|
|
|
state->setMode(GL_BLEND, osg::StateAttribute::ON);
|
|
|
|
|
|
|
|
|
|
state->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int axis)
|
|
|
|
|
{
|
|
|
|
|
switch (axis)
|
|
|
|
@ -399,7 +417,7 @@ osg::Vec3f CSVRender::Object::getMarkerPosition (float x, float y, float z, int
|
|
|
|
|
CSVRender::Object::Object (CSMWorld::Data& data, osg::Group* parentNode,
|
|
|
|
|
const std::string& id, bool referenceable, bool forceBaseToZero)
|
|
|
|
|
: mData (data), mBaseNode(0), mSelected(false), mParentNode(parentNode), mResourceSystem(data.getResourceSystem().get()), mForceBaseToZero (forceBaseToZero),
|
|
|
|
|
mScaleOverride (1), mOverrideFlags (0), mSubMode (-1)
|
|
|
|
|
mScaleOverride (1), mOverrideFlags (0), mSubMode (-1), mMarkerTransparency(0.5f)
|
|
|
|
|
{
|
|
|
|
|
mRootNode = new osg::PositionAttitudeTransform;
|
|
|
|
|
|
|
|
|
@ -453,6 +471,7 @@ void CSVRender::Object::setSelected(bool selected)
|
|
|
|
|
else
|
|
|
|
|
mRootNode->addChild(mBaseNode);
|
|
|
|
|
|
|
|
|
|
mMarkerTransparency = CSMPrefs::get()["3D Scene Input"]["object-marker-alpha"].toDouble();
|
|
|
|
|
updateMarker();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -629,6 +648,12 @@ void CSVRender::Object::setScale (float scale)
|
|
|
|
|
adjustTransform();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::Object::setMarkerTransparency(float value)
|
|
|
|
|
{
|
|
|
|
|
mMarkerTransparency = value;
|
|
|
|
|
updateMarker();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void CSVRender::Object::apply (CSMWorld::CommandMacro& commands)
|
|
|
|
|
{
|
|
|
|
|
const CSMWorld::RefCollection& collection = mData.getReferences();
|
|
|
|
|