src/Viewer/sview.*: fixed various issues with extra view windows.
Reversed the affect of mouse in some legacy views, e.g. Helicopter and Pilot views now move in expected direction for mouse drags. Also increased scale of movement to make things similar to the default view system. In chase view etc, apply mouse movements after damping of aircraft orientation, previously mouse movements were getting damped. Removed SviewStepFinalToTarget. SviewStepFinal now automatically aims at target if new posdir.target_is_set flag is true. Improved double views: Avoid duplicate SviewStepCopyToTarget step. Disabled mouse drag handling - was gives weird results and is not required or helpful. Be more consistent in using target position if available, otherwise eye position; for example using a Helicopter view to create a double view now uses the target of the helicopter view, not the eye point, which works much better. Removed internal use of SviewStepFinal from SviewStepDouble - used to be special case. Split mouse drag handling out of SviewStepRotate into new SviewStepMouseDrag. Simplified last-pair code - both last-pair and last-pair double find position and target in the same way.
This commit is contained in:
parent
d860a79901
commit
7ed93e4e64
2 changed files with 203 additions and 238 deletions
|
@ -101,7 +101,8 @@ struct SviewPosDir
|
||||||
:
|
:
|
||||||
heading(0),
|
heading(0),
|
||||||
pitch(0),
|
pitch(0),
|
||||||
roll(0)
|
roll(0),
|
||||||
|
target_is_set(false)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,9 +111,8 @@ struct SviewPosDir
|
||||||
double pitch;
|
double pitch;
|
||||||
double roll;
|
double roll;
|
||||||
|
|
||||||
/* Only used by SviewStepFinalToTarget; usually will be from a previously
|
|
||||||
evaluated Sview. */
|
|
||||||
SGGeod target;
|
SGGeod target;
|
||||||
|
bool target_is_set;
|
||||||
|
|
||||||
/* The final position and direction, in a form suitable for setting an
|
/* The final position and direction, in a form suitable for setting an
|
||||||
osg::Camera's view matrix. */
|
osg::Camera's view matrix. */
|
||||||
|
@ -143,7 +143,7 @@ struct SviewPosDir
|
||||||
|
|
||||||
/* Generic damping support. Improved version of class in view.hxx and view.cxx.
|
/* Generic damping support. Improved version of class in view.hxx and view.cxx.
|
||||||
|
|
||||||
We model dx/dt = (target-current)/damping_time, do damping_time is time for
|
We model dx/dt = (target-current)/damping_time, so damping_time is time for
|
||||||
value to change by a factor of e. */
|
value to change by a factor of e. */
|
||||||
struct Damping {
|
struct Damping {
|
||||||
|
|
||||||
|
@ -358,7 +358,7 @@ struct SviewStepMove : SviewStep
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Modifies heading, pitch and roll by fixed amounts; does not change
|
/* Modifies heading, pitch and roll by fixed amounts; does not change
|
||||||
position. Optionally implements a mouse drag handler which pans/tilts the view.
|
position.
|
||||||
|
|
||||||
E.g. can be used to preserve direction (relative to aircraft) of Helicopter
|
E.g. can be used to preserve direction (relative to aircraft) of Helicopter
|
||||||
view at the time it was cloned. */
|
view at the time it was cloned. */
|
||||||
|
@ -368,16 +368,14 @@ struct SviewStepRotate : SviewStep
|
||||||
double heading,
|
double heading,
|
||||||
double pitch,
|
double pitch,
|
||||||
double roll,
|
double roll,
|
||||||
bool fixed=false,
|
double damping_heading = 0,
|
||||||
double damping_heading=0,
|
double damping_pitch = 0,
|
||||||
double damping_pitch=0,
|
double damping_roll = 0
|
||||||
double damping_roll=0
|
|
||||||
)
|
)
|
||||||
:
|
:
|
||||||
m_heading(heading),
|
m_heading(heading),
|
||||||
m_pitch(pitch),
|
m_pitch(pitch),
|
||||||
m_roll(roll),
|
m_roll(roll),
|
||||||
m_fixed(fixed),
|
|
||||||
m_damping_heading(damping_heading, 360 /*m_wrap_max*/),
|
m_damping_heading(damping_heading, 360 /*m_wrap_max*/),
|
||||||
m_damping_pitch(damping_pitch, 360 /*m_wrap_max*/),
|
m_damping_pitch(damping_pitch, 360 /*m_wrap_max*/),
|
||||||
m_damping_roll(damping_roll, 360 /*m_wrap_max*/)
|
m_damping_roll(damping_roll, 360 /*m_wrap_max*/)
|
||||||
|
@ -392,22 +390,6 @@ struct SviewStepRotate : SviewStep
|
||||||
posdir.roll = m_damping_roll.update(dt, posdir.roll + m_roll);
|
posdir.roll = m_damping_roll.update(dt, posdir.roll + m_roll);
|
||||||
}
|
}
|
||||||
|
|
||||||
void mouse_drag(double delta_x_deg, double delta_y_deg) override
|
|
||||||
{
|
|
||||||
if (m_fixed) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
m_heading += delta_x_deg;
|
|
||||||
m_pitch += delta_y_deg;
|
|
||||||
SG_LOG(SG_VIEW, SG_DEBUG,
|
|
||||||
" delta_x_deg=" << delta_x_deg
|
|
||||||
<< " delta_y_deg=" << delta_y_deg
|
|
||||||
<< ":"
|
|
||||||
<< " m_heading=" << m_heading
|
|
||||||
<< " m_pitch=" << m_pitch
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void stream(std::ostream& out) const
|
virtual void stream(std::ostream& out) const
|
||||||
{
|
{
|
||||||
out << " <SviewStepRotate>"
|
out << " <SviewStepRotate>"
|
||||||
|
@ -421,12 +403,38 @@ struct SviewStepRotate : SviewStep
|
||||||
double m_heading;
|
double m_heading;
|
||||||
double m_pitch;
|
double m_pitch;
|
||||||
double m_roll;
|
double m_roll;
|
||||||
bool m_fixed;
|
|
||||||
Damping m_damping_heading;
|
Damping m_damping_heading;
|
||||||
Damping m_damping_pitch;
|
Damping m_damping_pitch;
|
||||||
Damping m_damping_roll;
|
Damping m_damping_roll;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Modify a view's heading and pitch in response to mouse dragging. */
|
||||||
|
struct SviewStepMouseDrag : SviewStep
|
||||||
|
{
|
||||||
|
SviewStepMouseDrag(double heading_scale, double pitch_scale)
|
||||||
|
:
|
||||||
|
m_heading_scale(heading_scale),
|
||||||
|
m_pitch_scale(pitch_scale)
|
||||||
|
{}
|
||||||
|
|
||||||
|
void evaluate(SviewPosDir& posdir, double dt) override
|
||||||
|
{
|
||||||
|
posdir.heading += m_heading;
|
||||||
|
posdir.pitch += m_pitch;
|
||||||
|
}
|
||||||
|
|
||||||
|
void mouse_drag(double delta_x_deg, double delta_y_deg) override
|
||||||
|
{
|
||||||
|
m_heading += m_heading_scale * delta_x_deg;
|
||||||
|
m_pitch += m_pitch_scale * delta_y_deg;
|
||||||
|
}
|
||||||
|
|
||||||
|
double m_heading_scale;
|
||||||
|
double m_pitch_scale;
|
||||||
|
double m_heading = 0;
|
||||||
|
double m_pitch = 0;
|
||||||
|
};
|
||||||
|
|
||||||
/* Multiply heading, pitch and roll by constants. */
|
/* Multiply heading, pitch and roll by constants. */
|
||||||
struct SviewStepDirectionMultiply : SviewStep
|
struct SviewStepDirectionMultiply : SviewStep
|
||||||
{
|
{
|
||||||
|
@ -463,12 +471,14 @@ struct SviewStepDirectionMultiply : SviewStep
|
||||||
|
|
||||||
/* Copies current position to posdir.target. Used by SviewEyeTarget()
|
/* Copies current position to posdir.target. Used by SviewEyeTarget()
|
||||||
to make current position be available as target later on, e.g. by
|
to make current position be available as target later on, e.g. by
|
||||||
SviewStepFinalToTarget. */
|
SviewStepFinal with to_target=true. */
|
||||||
struct SviewStepCopyToTarget : SviewStep
|
struct SviewStepCopyToTarget : SviewStep
|
||||||
{
|
{
|
||||||
void evaluate(SviewPosDir& posdir, double dt) override
|
void evaluate(SviewPosDir& posdir, double dt) override
|
||||||
{
|
{
|
||||||
|
assert(!posdir.target_is_set);
|
||||||
posdir.target = posdir.position;
|
posdir.target = posdir.position;
|
||||||
|
posdir.target_is_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void stream(std::ostream& out) const
|
virtual void stream(std::ostream& out) const
|
||||||
|
@ -517,139 +527,78 @@ struct SviewStepNearestTower : SviewStep
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
/* Rotates view direction to point at a previously-calculated target. Should be
|
|
||||||
final step if not SviewStepFinal. */
|
|
||||||
struct SviewStepFinalToTarget : SviewStep
|
|
||||||
{
|
|
||||||
/* Alters posdir.direction to point to posdir.target. */
|
|
||||||
void evaluate(SviewPosDir& posdir, double dt) override
|
|
||||||
{
|
|
||||||
/* See View::recalcLookAt(). */
|
|
||||||
|
|
||||||
SGQuatd geodEyeOr = SGQuatd::fromYawPitchRollDeg(posdir.heading, posdir.pitch, posdir.roll);
|
|
||||||
SGQuatd geodEyeHlOr = SGQuatd::fromLonLat(posdir.position);
|
|
||||||
|
|
||||||
SGQuatd ec2eye = geodEyeHlOr*geodEyeOr;
|
|
||||||
SGVec3d eyeCart = SGVec3d::fromGeod(posdir.position);
|
|
||||||
|
|
||||||
SGVec3d atCart = SGVec3d::fromGeod(posdir.target);
|
|
||||||
|
|
||||||
/* add target offsets to at_position...
|
|
||||||
Compute the eyepoints orientation and position wrt the earth centered
|
|
||||||
frame - that is global coorinates _absolute_view_pos = eyeCart; */
|
|
||||||
|
|
||||||
/* the view direction. */
|
|
||||||
SGVec3d dir = normalize(atCart - eyeCart);
|
|
||||||
|
|
||||||
/* the up directon. */
|
|
||||||
SGVec3d up = ec2eye.backTransform(SGVec3d(0, 0, -1));
|
|
||||||
|
|
||||||
/* rotate -dir to the 2-th unit vector
|
|
||||||
rotate up to 1-th unit vector
|
|
||||||
Note that this matches the OpenGL camera coordinate system with
|
|
||||||
x-right, y-up, z-back. */
|
|
||||||
posdir.direction2 = SGQuatd::fromRotateTo(-dir, 2, up, 1);
|
|
||||||
|
|
||||||
posdir.position2 = SGVec3d::fromGeod(posdir.position);
|
|
||||||
|
|
||||||
SG_LOG(SG_VIEW, SG_BULK, "have set posdir.position2: " << posdir.position2);
|
|
||||||
SG_LOG(SG_VIEW, SG_BULK, "have set posdir.direction2: " << posdir.direction2);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void stream(std::ostream& out) const
|
|
||||||
{
|
|
||||||
out << " <SviewStepFinalToTarget>";
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Applies optional rotation (see View::recalcLookFrom) and then converts position
|
Converts posdir's eye position/direction to global cartesian
|
||||||
and direction into position2 and direction2, which will be used to set the
|
position/quarternion direction in position2 and direction2, which will be used
|
||||||
camera parameters.
|
to set the camera parameters.
|
||||||
|
|
||||||
default_heading etc are for future when we have implemented event handling to
|
If posdir.target_is_set is true (i.e. posdir.target is valid), we also change
|
||||||
modify the view in response to mouse movements.
|
the direction to point at the target, using the original direction to determine
|
||||||
|
the 'up' vector.
|
||||||
*/
|
*/
|
||||||
struct SviewStepFinal : SviewStep
|
struct SviewStepFinal : SviewStep
|
||||||
{
|
{
|
||||||
SviewStepFinal(
|
|
||||||
double heading,
|
|
||||||
double pitch,
|
|
||||||
double roll,
|
|
||||||
double default_heading,
|
|
||||||
double default_pitch,
|
|
||||||
double default_roll
|
|
||||||
)
|
|
||||||
:
|
|
||||||
m_orientation(true),
|
|
||||||
m_heading(heading),
|
|
||||||
m_pitch(pitch),
|
|
||||||
m_roll(roll),
|
|
||||||
m_default_heading(default_heading),
|
|
||||||
m_default_pitch(default_pitch),
|
|
||||||
m_default_roll(default_roll)
|
|
||||||
{
|
|
||||||
SG_LOG(SG_VIEW, SG_INFO, "heading=" << heading << " pitch=" << pitch << " roll=" << roll);
|
|
||||||
}
|
|
||||||
|
|
||||||
SviewStepFinal()
|
SviewStepFinal()
|
||||||
:
|
|
||||||
m_orientation(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
void evaluate(SviewPosDir& posdir, double dt) override
|
void evaluate(SviewPosDir& posdir, double dt) override
|
||||||
{
|
{
|
||||||
/* See View::recalcLookFrom(). */
|
/* See View::recalcLookFrom(). */
|
||||||
SGQuatd rotation = SGQuatd::fromYawPitchRollDeg(-m_heading, m_pitch, m_roll);
|
|
||||||
|
|
||||||
/* The rotation rotating from the earth centerd frame to the horizontal
|
/* The rotation rotating from the earth centerd frame to the horizontal
|
||||||
local frame. */
|
local frame. */
|
||||||
SGQuatd hlOr = SGQuatd::fromLonLat(posdir.position);
|
SGQuatd eye_position_direction = SGQuatd::fromLonLat(posdir.position);
|
||||||
|
|
||||||
/* The rotation from the horizontal local frame to the basic view
|
/* The rotation from the horizontal local frame to the basic view
|
||||||
orientation. */
|
orientation. */
|
||||||
SGQuatd hlToBody = SGQuatd::fromYawPitchRollDeg(posdir.heading, posdir.pitch, posdir.roll);
|
SGQuatd eye_local_direction = SGQuatd::fromYawPitchRollDeg(posdir.heading, posdir.pitch, posdir.roll);
|
||||||
|
|
||||||
/* Compute the eyepoints orientation and position wrt the earth
|
|
||||||
centered frame - that is global coorinates. */
|
|
||||||
SGQuatd ec2body = hlOr * hlToBody;
|
|
||||||
|
|
||||||
/* The cartesian position of the basic view coordinate. */
|
/* The cartesian position of the basic view coordinate. */
|
||||||
SGVec3d position = SGVec3d::fromGeod(posdir.position);
|
SGVec3d eye_position = SGVec3d::fromGeod(posdir.position);
|
||||||
|
|
||||||
/* This is rotates the x-forward, y-right, z-down coordinate system the
|
/* Compute the eye direction in global coordinates. */
|
||||||
where simulation runs into the OpenGL camera system with x-right, y-up,
|
SGQuatd eye_direction = eye_position_direction * eye_local_direction;
|
||||||
z-back. */
|
|
||||||
SGQuatd q(-0.5, -0.5, 0.5, 0.5);
|
|
||||||
|
|
||||||
posdir.position2 = position;
|
if (posdir.target_is_set)
|
||||||
posdir.direction2 = ec2body * rotation * q;
|
{
|
||||||
}
|
/* Rotate eye direction to point at posdir.target. */
|
||||||
|
|
||||||
void mouse_drag(double delta_x_deg, double delta_y_deg) override
|
SGVec3d target_position = SGVec3d::fromGeod(posdir.target);
|
||||||
{
|
|
||||||
if (m_orientation) {
|
/* add target offsets to at_position...
|
||||||
m_heading += delta_x_deg;
|
Compute the eyepoints orientation and position wrt the earth centered
|
||||||
m_pitch += delta_y_deg;
|
frame - that is global coorinates _absolute_view_pos = eye_position; */
|
||||||
|
|
||||||
|
/* the view direction. */
|
||||||
|
SGVec3d eye_to_target_direction = normalize(target_position - eye_position);
|
||||||
|
|
||||||
|
/* the up directon. */
|
||||||
|
SGVec3d up = eye_direction.backTransform(SGVec3d(0, 0, -1));
|
||||||
|
|
||||||
|
/* rotate -dir to the 2-th unit vector
|
||||||
|
rotate up to 1-th unit vector
|
||||||
|
Note that this matches the OpenGL camera coordinate system with
|
||||||
|
x-right, y-up, z-back. */
|
||||||
|
posdir.direction2 = SGQuatd::fromRotateTo(-eye_to_target_direction, 2, up, 1);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* This is rotates the x-forward, y-right, z-down coordinate system the
|
||||||
|
where simulation runs into the OpenGL camera system with x-right, y-up,
|
||||||
|
z-back. */
|
||||||
|
SGQuatd q(-0.5, -0.5, 0.5, 0.5);
|
||||||
|
|
||||||
|
posdir.direction2 = eye_direction * q;
|
||||||
|
}
|
||||||
|
|
||||||
|
posdir.position2 = eye_position;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void stream(std::ostream& out) const
|
virtual void stream(std::ostream& out) const
|
||||||
{
|
{
|
||||||
out << " <SviewStepFinal>";
|
out << " <SviewStepFinal>";
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
bool m_orientation;
|
|
||||||
double m_heading = 0;
|
|
||||||
double m_pitch = 0;
|
|
||||||
double m_roll = 0;
|
|
||||||
double m_default_heading = 0;
|
|
||||||
double m_default_pitch = 0;
|
|
||||||
double m_default_roll = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -675,6 +624,7 @@ struct SviewStepAGL : SviewStep
|
||||||
m_chase_distance = m_callsign.m_root->getDoubleValue("set/sim/chase-distance-m", m_chase_distance);
|
m_chase_distance = m_callsign.m_root->getDoubleValue("set/sim/chase-distance-m", m_chase_distance);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
assert(posdir.target_is_set);
|
||||||
double _fov_user_deg = 30;
|
double _fov_user_deg = 30;
|
||||||
double _configFOV_deg = 30;
|
double _configFOV_deg = 30;
|
||||||
/* Some aircraft appear to have elevation that is slightly below ground
|
/* Some aircraft appear to have elevation that is slightly below ground
|
||||||
|
@ -862,8 +812,10 @@ struct SviewStepDouble : SviewStep
|
||||||
debug = true;
|
debug = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert(posdir.target_is_set);
|
||||||
SviewPosDir posdir_remote = posdir;
|
SviewPosDir posdir_remote = posdir;
|
||||||
SviewPosDir posdir_local = posdir;
|
SviewPosDir posdir_local = posdir;
|
||||||
|
|
||||||
posdir_local.target = posdir_local.position;
|
posdir_local.target = posdir_local.position;
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
|
@ -919,17 +871,19 @@ struct SviewStepDouble : SviewStep
|
||||||
move.evaluate(posdir_local, 0 /*dt*/);
|
move.evaluate(posdir_local, 0 /*dt*/);
|
||||||
|
|
||||||
/* At this point, posdir_local.position is eye position. We make
|
/* At this point, posdir_local.position is eye position. We make
|
||||||
posdir_local.direction2 point from this eye position to halfway between
|
posdir_local.pitch point from this eye position to halfway between the
|
||||||
the remote and local aircraft. */
|
remote and local aircraft. */
|
||||||
double er_vertical = posdir_remote.target.getElevationM()
|
double er_vertical = posdir_remote.target.getElevationM()
|
||||||
- posdir_local.position.getElevationM();
|
- posdir_local.position.getElevationM();
|
||||||
double her = asin(er_vertical / er);
|
double her = asin(er_vertical / er);
|
||||||
double hel = (hlr + rle) - pi;
|
double hel = (hlr + rle) - pi;
|
||||||
posdir_local.pitch = (her + hel) / 2 * 180 / pi;
|
posdir_local.pitch = (her + hel) / 2 * 180 / pi;
|
||||||
auto stepfinal = SviewStepFinal();
|
|
||||||
stepfinal.evaluate(posdir_local, 0 /*dt*/);
|
|
||||||
posdir = posdir_local;
|
posdir = posdir_local;
|
||||||
|
|
||||||
|
/* Need to ensure that SviewStepFinal will not rotate the view to point
|
||||||
|
at posdir.target. */
|
||||||
|
posdir.target_is_set = false;
|
||||||
|
|
||||||
if (debug) {
|
if (debug) {
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, ""
|
SG_LOG(SG_VIEW, SG_ALERT, ""
|
||||||
<< " lr=" << lr
|
<< " lr=" << lr
|
||||||
|
@ -1021,9 +975,9 @@ struct SviewView
|
||||||
assert(composite_viewer);
|
assert(composite_viewer);
|
||||||
for (unsigned i=0; i<composite_viewer->getNumViews(); ++i) {
|
for (unsigned i=0; i<composite_viewer->getNumViews(); ++i) {
|
||||||
osgViewer::View* view = composite_viewer->getView(i);
|
osgViewer::View* view = composite_viewer->getView(i);
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "composite_viewer view i=" << i << " view=" << view);
|
SG_LOG(SG_VIEW, SG_DEBUG, "composite_viewer view i=" << i << " view=" << view);
|
||||||
}
|
}
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "removing m_osg_view=" << m_osg_view);
|
SG_LOG(SG_VIEW, SG_DEBUG, "removing m_osg_view=" << m_osg_view);
|
||||||
composite_viewer->stopThreading();
|
composite_viewer->stopThreading();
|
||||||
composite_viewer->removeView(m_osg_view);
|
composite_viewer->removeView(m_osg_view);
|
||||||
composite_viewer->startThreading();
|
composite_viewer->startThreading();
|
||||||
|
@ -1126,7 +1080,9 @@ struct SviewViewEyeTarget : SviewView
|
||||||
:
|
:
|
||||||
SviewView(view)
|
SviewView(view)
|
||||||
{
|
{
|
||||||
if (!strcmp(config->getStringValue("type"), "legacy")) {
|
if (!strcmp(config->getStringValue("type"), "legacy"))
|
||||||
|
{
|
||||||
|
/* Legacy view. */
|
||||||
std::string callsign = config->getStringValue("callsign");
|
std::string callsign = config->getStringValue("callsign");
|
||||||
std::string callsign_desc = (callsign == "") ? "" : ": " + callsign;
|
std::string callsign_desc = (callsign == "") ? "" : ": " + callsign;
|
||||||
SG_LOG(SG_VIEW, SG_INFO, "callsign=" << callsign);
|
SG_LOG(SG_VIEW, SG_INFO, "callsign=" << callsign);
|
||||||
|
@ -1147,9 +1103,9 @@ struct SviewViewEyeTarget : SviewView
|
||||||
-config->getDoubleValue("view/config/target-x-offset-m")
|
-config->getDoubleValue("view/config/target-x-offset-m")
|
||||||
));
|
));
|
||||||
|
|
||||||
/* Add a step to set pitch and roll to zero, otherwise
|
/* Add a step to set pitch and roll to zero, otherwise view
|
||||||
view from tower (as calculated by SviewStepFinalToTarget)
|
from tower (as calculated by SviewStepFinal) rolls/pitches
|
||||||
rolls/pitches with aircraft. */
|
with aircraft. */
|
||||||
m_steps.add_step(new SviewStepDirectionMultiply(
|
m_steps.add_step(new SviewStepDirectionMultiply(
|
||||||
1 /* heading */,
|
1 /* heading */,
|
||||||
0 /* pitch */,
|
0 /* pitch */,
|
||||||
|
@ -1167,16 +1123,17 @@ struct SviewViewEyeTarget : SviewView
|
||||||
if (config->getBoolValue("view/config/lookat-agl")) {
|
if (config->getBoolValue("view/config/lookat-agl")) {
|
||||||
double damping = config->getDoubleValue("view/config/lookat-agl-damping");
|
double damping = config->getDoubleValue("view/config/lookat-agl-damping");
|
||||||
double damping_time = log(10) * legacy_damping_time(damping);
|
double damping_time = log(10) * legacy_damping_time(damping);
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "lookat-agl");
|
SG_LOG(SG_VIEW, SG_DEBUG, "lookat-agl");
|
||||||
m_steps.add_step(new SviewStepAGL(callsign, damping_time));
|
m_steps.add_step(new SviewStepAGL(callsign, damping_time));
|
||||||
}
|
}
|
||||||
m_steps.add_step(new SviewStepFinalToTarget);
|
|
||||||
|
m_steps.add_step(new SviewStepFinal);
|
||||||
|
|
||||||
/* Would be nice to add a step that moves towards the
|
/* Would be nice to add a step that moves towards the
|
||||||
target a little, like we do with Tower view look from. But
|
target a little, like we do with Tower view look from. But
|
||||||
simply adding a SviewStepMove doesn't work because the
|
simply adding a SviewStepMove doesn't work because the
|
||||||
preceding SviewStepFinalToTarget has finalised the view
|
preceding SviewStepFinal has finalised the view angle etc.
|
||||||
angle etc. */
|
*/
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* E.g. Tower view look from. */
|
/* E.g. Tower view look from. */
|
||||||
|
@ -1196,6 +1153,10 @@ struct SviewViewEyeTarget : SviewView
|
||||||
movement not change the height. */
|
movement not change the height. */
|
||||||
m_steps.add_step(new SviewStepMove(1, 0, 0));
|
m_steps.add_step(new SviewStepMove(1, 0, 0));
|
||||||
|
|
||||||
|
m_steps.add_step(new SviewStepMouseDrag(
|
||||||
|
1 /*mouse_heading_scale*/,
|
||||||
|
1 /*mouse_pitch_scale*/
|
||||||
|
));
|
||||||
m_steps.add_step(new SviewStepFinal);
|
m_steps.add_step(new SviewStepFinal);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1221,8 +1182,6 @@ struct SviewViewEyeTarget : SviewView
|
||||||
-config->getDoubleValue("view/config/target-x-offset-m")
|
-config->getDoubleValue("view/config/target-x-offset-m")
|
||||||
));
|
));
|
||||||
|
|
||||||
m_steps.add_step(new SviewStepCopyToTarget);
|
|
||||||
|
|
||||||
/* Add a step that crudely preserves or don't preserve
|
/* Add a step that crudely preserves or don't preserve
|
||||||
aircraft's heading, pitch and roll; this enables us to mimic
|
aircraft's heading, pitch and roll; this enables us to mimic
|
||||||
Helicopter and Chase views. In theory we should evaluate the
|
Helicopter and Chase views. In theory we should evaluate the
|
||||||
|
@ -1248,12 +1207,24 @@ struct SviewViewEyeTarget : SviewView
|
||||||
-globals->get_props()->getDoubleValue("sim/current-view/heading-offset-deg"),
|
-globals->get_props()->getDoubleValue("sim/current-view/heading-offset-deg"),
|
||||||
-globals->get_props()->getDoubleValue("sim/current-view/pitch-offset-deg"),
|
-globals->get_props()->getDoubleValue("sim/current-view/pitch-offset-deg"),
|
||||||
globals->get_props()->getDoubleValue("sim/current-view/roll-offset-deg"),
|
globals->get_props()->getDoubleValue("sim/current-view/roll-offset-deg"),
|
||||||
false /*fixed*/,
|
|
||||||
damping_heading,
|
damping_heading,
|
||||||
damping_pitch,
|
damping_pitch,
|
||||||
damping_roll
|
damping_roll
|
||||||
));
|
));
|
||||||
|
|
||||||
|
m_steps.add_step(new SviewStepMouseDrag(
|
||||||
|
1 /*mouse_heading_scale*/,
|
||||||
|
-1 /*mouse_pitch_scale*/
|
||||||
|
));
|
||||||
|
|
||||||
|
/* Set current position as target. This isn't actually
|
||||||
|
necessary for this view because the direction implied by
|
||||||
|
heading/pitch/roll will still point to the centre of the
|
||||||
|
aircraft after the following steps. But it allows double
|
||||||
|
views to work better - they will use the centre of the
|
||||||
|
aircraft instead of the eye position. */
|
||||||
|
m_steps.add_step(new SviewStepCopyToTarget);
|
||||||
|
|
||||||
/* Add step that moves eye away from aircraft.
|
/* Add step that moves eye away from aircraft.
|
||||||
config/z-offset-m defaults to /sim/chase-distance-m (see
|
config/z-offset-m defaults to /sim/chase-distance-m (see
|
||||||
fgdata:defaults.xml) which is -ve, e.g. -25m. */
|
fgdata:defaults.xml) which is -ve, e.g. -25m. */
|
||||||
|
@ -1263,12 +1234,10 @@ struct SviewViewEyeTarget : SviewView
|
||||||
config->getDoubleValue("view/config/x-offset-m")
|
config->getDoubleValue("view/config/x-offset-m")
|
||||||
));
|
));
|
||||||
|
|
||||||
m_steps.add_step(new SviewStepFinalToTarget);
|
|
||||||
|
|
||||||
/* Finally add a step that converts
|
/* Finally add a step that converts
|
||||||
lat,lon,height,heading,pitch,roll into SGVec3d position and
|
lat,lon,height,heading,pitch,roll into SGVec3d position and
|
||||||
SGQuatd orientation. */
|
SGQuatd orientation. */
|
||||||
//m_steps.add_step(new SviewStepFinal);
|
m_steps.add_step(new SviewStepFinal);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
/* E.g. pilot view.
|
/* E.g. pilot view.
|
||||||
|
@ -1289,33 +1258,35 @@ struct SviewViewEyeTarget : SviewView
|
||||||
double current_heading_offset = globals->get_props()->getDoubleValue("sim/current-view/heading-offset-deg");
|
double current_heading_offset = globals->get_props()->getDoubleValue("sim/current-view/heading-offset-deg");
|
||||||
double current_pitch_offset = globals->get_props()->getDoubleValue("sim/current-view/pitch-offset-deg");
|
double current_pitch_offset = globals->get_props()->getDoubleValue("sim/current-view/pitch-offset-deg");
|
||||||
double current_roll_offset = globals->get_props()->getDoubleValue("sim/current-view/roll-offset-deg");
|
double current_roll_offset = globals->get_props()->getDoubleValue("sim/current-view/roll-offset-deg");
|
||||||
double default_heading_offset = config->getDoubleValue("view/config/heading-offset-deg");
|
/*double default_heading_offset = config->getDoubleValue("view/config/heading-offset-deg");
|
||||||
double default_pitch_offset = config->getDoubleValue("view/config/pitch-offset-deg");
|
double default_pitch_offset = config->getDoubleValue("view/config/pitch-offset-deg");
|
||||||
double default_roll_offset = config->getDoubleValue("view/config/roll-offset-deg");
|
double default_roll_offset = config->getDoubleValue("view/config/roll-offset-deg");*/
|
||||||
|
|
||||||
/* Final step applies rotation. */
|
/* Apply final rotation. */
|
||||||
m_steps.add_step(new SviewStepFinal(
|
m_steps.add_step(new SviewStepRotate(
|
||||||
current_heading_offset,
|
current_heading_offset,
|
||||||
current_pitch_offset,
|
current_pitch_offset,
|
||||||
current_roll_offset,
|
current_roll_offset
|
||||||
default_heading_offset,
|
|
||||||
default_pitch_offset,
|
|
||||||
default_roll_offset
|
|
||||||
));
|
));
|
||||||
|
|
||||||
|
m_steps.add_step(new SviewStepMouseDrag(
|
||||||
|
1 /*mouse_heading_scale*/,
|
||||||
|
1 /*mouse_pitch_scale*/
|
||||||
|
));
|
||||||
|
m_steps.add_step(new SviewStepFinal);
|
||||||
SG_LOG(SG_VIEW, SG_INFO, "m_steps=" << m_steps);
|
SG_LOG(SG_VIEW, SG_INFO, "m_steps=" << m_steps);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else
|
||||||
|
{
|
||||||
/* New-style Sview specification, where each step is specified for
|
/* New-style Sview specification, where each step is specified for
|
||||||
us. */
|
us. */
|
||||||
simgear::PropertyList steps = config->getChildren("step");
|
simgear::PropertyList steps = config->getChildren("step");
|
||||||
if (steps.empty()) {
|
if (steps.empty()) {
|
||||||
throw std::runtime_error(std::string() + "No steps specified");
|
throw std::runtime_error(std::string() + "No steps specified");
|
||||||
}
|
}
|
||||||
bool finalised = false;
|
|
||||||
for (SGPropertyNode* step: steps) {
|
for (SGPropertyNode* step: steps) {
|
||||||
finalised = false;
|
|
||||||
const char* type = step->getStringValue("type");
|
const char* type = step->getStringValue("type");
|
||||||
if (0) {}
|
if (0) {}
|
||||||
else if (!strcmp(type, "aircraft")) {
|
else if (!strcmp(type, "aircraft")) {
|
||||||
|
@ -1353,7 +1324,6 @@ struct SviewViewEyeTarget : SviewView
|
||||||
step->getDoubleValue("heading"),
|
step->getDoubleValue("heading"),
|
||||||
step->getDoubleValue("pitch"),
|
step->getDoubleValue("pitch"),
|
||||||
step->getDoubleValue("roll"),
|
step->getDoubleValue("roll"),
|
||||||
step->getBoolValue("fixed"),
|
|
||||||
step->getDoubleValue("damping-heading"),
|
step->getDoubleValue("damping-heading"),
|
||||||
step->getDoubleValue("damping-pitch"),
|
step->getDoubleValue("damping-pitch"),
|
||||||
step->getDoubleValue("damping-roll")
|
step->getDoubleValue("damping-roll")
|
||||||
|
@ -1366,13 +1336,15 @@ struct SviewViewEyeTarget : SviewView
|
||||||
globals->get_props()->getDoubleValue("roll")
|
globals->get_props()->getDoubleValue("roll")
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
else if (!strcmp(type, "rotate-to-target")) {
|
else if (!strcmp(type, "mouse-drag"))
|
||||||
m_steps.add_step(new SviewStepFinalToTarget);
|
{
|
||||||
finalised = true;
|
m_steps.add_step(new SviewStepMouseDrag(
|
||||||
|
step->getDoubleValue("heading-scale", 1),
|
||||||
|
step->getDoubleValue("pitch-scale", 1)
|
||||||
|
));
|
||||||
}
|
}
|
||||||
else if (!strcmp(type, "double")) {
|
else if (!strcmp(type, "double")) {
|
||||||
m_steps.add_step(new SviewStepDouble(step));
|
m_steps.add_step(new SviewStepDouble(step));
|
||||||
finalised = true;
|
|
||||||
m_steps.m_name += " double";
|
m_steps.m_name += " double";
|
||||||
}
|
}
|
||||||
else if (!strcmp(type, "agl")) {
|
else if (!strcmp(type, "agl")) {
|
||||||
|
@ -1384,14 +1356,12 @@ struct SviewViewEyeTarget : SviewView
|
||||||
throw std::runtime_error(std::string() + "Unrecognised step name: '" + type + "'");
|
throw std::runtime_error(std::string() + "Unrecognised step name: '" + type + "'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!finalised) {
|
m_steps.add_step(new SviewStepFinal);
|
||||||
m_steps.add_step(new SviewStepFinal);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "m_steps=" << m_steps);
|
SG_LOG(SG_VIEW, SG_DEBUG, "m_steps=" << m_steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Construct from two step sequences. */
|
/* Construct a double view using two step sequences. */
|
||||||
SviewViewEyeTarget(
|
SviewViewEyeTarget(
|
||||||
osgViewer::View* view,
|
osgViewer::View* view,
|
||||||
SGPropertyNode* config,
|
SGPropertyNode* config,
|
||||||
|
@ -1405,62 +1375,55 @@ struct SviewViewEyeTarget : SviewView
|
||||||
if (!type) {
|
if (!type) {
|
||||||
throw std::runtime_error("double-type not specified");
|
throw std::runtime_error("double-type not specified");
|
||||||
}
|
}
|
||||||
if (!strcmp(type, "last_pair")) {
|
if (!strcmp(type, "last_pair") || !strcmp(type, "last_pair_double"))
|
||||||
/* todo: remove steps that have no affect on the target/eye that we are
|
{
|
||||||
interested in. */
|
/* Copy steps from <b> that will set .target. */
|
||||||
SviewSteps& eye = a;
|
for (auto step: b.m_steps)
|
||||||
SviewSteps& target = b;
|
{
|
||||||
m_steps.m_name = std::string() + " pair: " + eye.m_name + " - " + target.m_name;
|
|
||||||
for (auto step: target.m_steps) {
|
|
||||||
if (0
|
if (0
|
||||||
|| dynamic_cast<SviewStepCopyToTarget*>(step.get())
|
|| dynamic_cast<SviewStepCopyToTarget*>(step.get())
|
||||||
|| dynamic_cast<SviewStepFinal*>(step.get())
|
|| dynamic_cast<SviewStepFinal*>(step.get())
|
||||||
|| dynamic_cast<SviewStepFinalToTarget*>(step.get())
|
)
|
||||||
) {
|
{
|
||||||
continue;
|
break;
|
||||||
}
|
}
|
||||||
m_steps.add_step(step);
|
m_steps.add_step(step);
|
||||||
}
|
}
|
||||||
m_steps.add_step(new SviewStepCopyToTarget);
|
m_steps.add_step(new SviewStepCopyToTarget);
|
||||||
|
|
||||||
for (auto step: eye.m_steps) {
|
/* Copy steps from <a> that will set .position. */
|
||||||
|
for (auto step: a.m_steps)
|
||||||
|
{
|
||||||
if (0
|
if (0
|
||||||
|| dynamic_cast<SviewStepCopyToTarget*>(step.get())
|
|| dynamic_cast<SviewStepCopyToTarget*>(step.get())
|
||||||
|| dynamic_cast<SviewStepFinal*>(step.get())
|
|| dynamic_cast<SviewStepFinal*>(step.get())
|
||||||
|| dynamic_cast<SviewStepFinalToTarget*>(step.get())
|
)
|
||||||
) {
|
{
|
||||||
continue;
|
|
||||||
}
|
|
||||||
m_steps.add_step(step);
|
|
||||||
}
|
|
||||||
m_steps.add_step(new SviewStepFinalToTarget);
|
|
||||||
SG_LOG(SG_VIEW, SG_INFO, " m_steps:" << m_steps);
|
|
||||||
}
|
|
||||||
else if (!strcmp(type, "last_pair_double")) {
|
|
||||||
SviewSteps& local = a;
|
|
||||||
SviewSteps& remote = b;
|
|
||||||
m_steps.m_name = std::string() + " double: " + local.m_name + " - " + remote.m_name;
|
|
||||||
for (auto step: remote.m_steps) {
|
|
||||||
m_steps.add_step(step);
|
|
||||||
if (dynamic_cast<SviewStepCopyToTarget*>(step.get())) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
m_steps.add_step(new SviewStepCopyToTarget);
|
|
||||||
|
|
||||||
for (auto step: local.m_steps) {
|
|
||||||
if (dynamic_cast<SviewStepCopyToTarget*>(step.get())) {
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
m_steps.add_step(step);
|
m_steps.add_step(step);
|
||||||
}
|
}
|
||||||
m_steps.add_step(new SviewStepDouble);
|
|
||||||
|
if (!strcmp(type, "last_pair_double"))
|
||||||
|
{
|
||||||
|
/* We need a final SviewStepDouble step. */
|
||||||
|
m_steps.add_step(new SviewStepDouble);
|
||||||
|
m_steps.m_name = std::string() + " double: " + a.m_name + " - " + b.m_name;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_steps.m_name = std::string() + " pair: " + a.m_name + " - " + b.m_name;
|
||||||
|
}
|
||||||
|
m_steps.add_step(new SviewStepFinal);
|
||||||
SG_LOG(SG_VIEW, SG_INFO, " m_steps:" << m_steps);
|
SG_LOG(SG_VIEW, SG_INFO, " m_steps:" << m_steps);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
throw std::runtime_error(std::string("Unrecognised double view: ") + type);
|
throw std::runtime_error(std::string("Unrecognised double view: ") + type);
|
||||||
}
|
}
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "m_steps=" << m_steps);
|
|
||||||
|
/* Disable our mouse_drag() method - doesn't make sense for double views. */
|
||||||
|
m_mouse_drag = false;
|
||||||
|
SG_LOG(SG_VIEW, SG_DEBUG, "m_steps=" << m_steps);
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::string description() override
|
const std::string description() override
|
||||||
|
@ -1492,12 +1455,14 @@ struct SviewViewEyeTarget : SviewView
|
||||||
|
|
||||||
void mouse_drag(double delta_x_deg, double delta_y_deg) override
|
void mouse_drag(double delta_x_deg, double delta_y_deg) override
|
||||||
{
|
{
|
||||||
|
if (!m_mouse_drag) return;
|
||||||
for (auto step: m_steps.m_steps) {
|
for (auto step: m_steps.m_steps) {
|
||||||
step->mouse_drag(delta_x_deg, delta_y_deg);
|
step->mouse_drag(delta_x_deg, delta_y_deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SviewSteps m_steps;
|
SviewSteps m_steps;
|
||||||
|
bool m_mouse_drag = true;
|
||||||
bool m_debug = false;
|
bool m_debug = false;
|
||||||
time_t m_debug_time = 0;
|
time_t m_debug_time = 0;
|
||||||
};
|
};
|
||||||
|
@ -1564,7 +1529,7 @@ void SviewPush()
|
||||||
SGPropertyNode_ptr config = SviewConfigForCurrentView();
|
SGPropertyNode_ptr config = SviewConfigForCurrentView();
|
||||||
std::shared_ptr<SviewViewEyeTarget> v(new SviewViewEyeTarget(nullptr /*view*/, config));
|
std::shared_ptr<SviewViewEyeTarget> v(new SviewViewEyeTarget(nullptr /*view*/, config));
|
||||||
s_recent_views.push_back(v);
|
s_recent_views.push_back(v);
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "Have pushed view: " << v);
|
SG_LOG(SG_VIEW, SG_DEBUG, "Have pushed view: " << v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1660,7 +1625,7 @@ std::shared_ptr<SviewView> SviewCreate(SGPropertyNode* config)
|
||||||
osgViewer::View* main_view = renderer->getView();
|
osgViewer::View* main_view = renderer->getView();
|
||||||
osg::Node* scene_data = main_view->getSceneData();
|
osg::Node* scene_data = main_view->getSceneData();
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "main_view->getNumSlaves()=" << main_view->getNumSlaves());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "main_view->getNumSlaves()=" << main_view->getNumSlaves());
|
||||||
|
|
||||||
osgViewer::View* view = new osgViewer::View();
|
osgViewer::View* view = new osgViewer::View();
|
||||||
flightgear::FGEventHandler* event_handler = globals->get_renderer()->getEventHandler();
|
flightgear::FGEventHandler* event_handler = globals->get_renderer()->getEventHandler();
|
||||||
|
@ -1669,7 +1634,7 @@ std::shared_ptr<SviewView> SviewCreate(SGPropertyNode* config)
|
||||||
std::shared_ptr<SviewView> sview_view;
|
std::shared_ptr<SviewView> sview_view;
|
||||||
|
|
||||||
const char* type = config->getStringValue("type");
|
const char* type = config->getStringValue("type");
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "type=" << type);
|
SG_LOG(SG_VIEW, SG_DEBUG, "type=" << type);
|
||||||
if (0) {
|
if (0) {
|
||||||
}
|
}
|
||||||
else if (!strcmp(type, "current")) {
|
else if (!strcmp(type, "current")) {
|
||||||
|
@ -1844,13 +1809,13 @@ std::shared_ptr<SviewView> SviewCreate(SGPropertyNode* config)
|
||||||
composite_viewer->addView(view);
|
composite_viewer->addView(view);
|
||||||
composite_viewer->startThreading();
|
composite_viewer->startThreading();
|
||||||
|
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "main_view->getNumSlaves()=" << main_view->getNumSlaves());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "main_view->getNumSlaves()=" << main_view->getNumSlaves());
|
||||||
SG_LOG(SG_GENERAL, SG_ALERT, "view->getNumSlaves()=" << view->getNumSlaves());
|
SG_LOG(SG_GENERAL, SG_DEBUG, "view->getNumSlaves()=" << view->getNumSlaves());
|
||||||
|
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "have added extra view. views are now:");
|
SG_LOG(SG_VIEW, SG_DEBUG, "have added extra view. views are now:");
|
||||||
for (unsigned i=0; i<composite_viewer->getNumViews(); ++i) {
|
for (unsigned i=0; i<composite_viewer->getNumViews(); ++i) {
|
||||||
osgViewer::View* view = composite_viewer->getView(i);
|
osgViewer::View* view = composite_viewer->getView(i);
|
||||||
SG_LOG(SG_VIEW, SG_ALERT, "composite_viewer view i=" << i << " view=" << view);
|
SG_LOG(SG_VIEW, SG_DEBUG, "composite_viewer view i=" << i << " view=" << view);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sview_view;
|
return sview_view;
|
||||||
|
@ -1925,7 +1890,12 @@ bool SviewMouseMotion(int x, int y, const osgGA::GUIEventAdapter& ea)
|
||||||
osg::Viewport* viewport = compositor->getViewport();
|
osg::Viewport* viewport = compositor->getViewport();
|
||||||
double delta_x_deg = delta_x / viewport->width() * fov_x;
|
double delta_x_deg = delta_x / viewport->width() * fov_x;
|
||||||
double delta_y_deg = delta_y / viewport->height() * fov_y;
|
double delta_y_deg = delta_y / viewport->height() * fov_y;
|
||||||
|
|
||||||
|
/* Scale movement a little to make things more similar to normal
|
||||||
|
operation. */
|
||||||
|
double scale = 5;
|
||||||
|
delta_x_deg *= scale;
|
||||||
|
delta_y_deg *= scale;
|
||||||
sview_view->mouse_drag(delta_x_deg, delta_y_deg);
|
sview_view->mouse_drag(delta_x_deg, delta_y_deg);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1935,4 +1905,3 @@ bool SviewMouseMotion(int x, int y, const osgGA::GUIEventAdapter& ea)
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -66,6 +66,8 @@ config:
|
||||||
x, y:
|
x, y:
|
||||||
Position of new window.
|
Position of new window.
|
||||||
type:
|
type:
|
||||||
|
"sview" or not specified:
|
||||||
|
List of sview-step's - see below.
|
||||||
"current"
|
"current"
|
||||||
Clones the current view.
|
Clones the current view.
|
||||||
"last_pair"
|
"last_pair"
|
||||||
|
@ -101,16 +103,13 @@ config:
|
||||||
view, possibly because the viewpoint correction config/y-offset-m
|
view, possibly because the viewpoint correction config/y-offset-m
|
||||||
is applied after rotation instead of before.
|
is applied after rotation instead of before.
|
||||||
|
|
||||||
"sview" or not specified:
|
|
||||||
List of sview-step's.
|
|
||||||
|
|
||||||
An sview-step is:
|
An sview-step is:
|
||||||
step:
|
step:
|
||||||
type:
|
type:
|
||||||
"aircraft"
|
"aircraft"
|
||||||
callsign:
|
callsign:
|
||||||
"": move to user aircraft.
|
"": The user's aircraft.
|
||||||
Otherwise move to specified multiplayer aircraft.
|
Otherwise specifies a multiplayer aircraft.
|
||||||
"move":
|
"move":
|
||||||
forward
|
forward
|
||||||
up
|
up
|
||||||
|
@ -120,26 +119,27 @@ An sview-step is:
|
||||||
"direction-multiply":
|
"direction-multiply":
|
||||||
heading, pitch, roll:
|
heading, pitch, roll:
|
||||||
Values to multiply into direction. This can be used to
|
Values to multiply into direction. This can be used to
|
||||||
preserve or don't preserve heading, pitch and roll which
|
preserve/not preserve heading, pitch and roll, which allows
|
||||||
allows implementation of Helicopter and Chase views etc.
|
implementation of Helicopter and Chase views etc.
|
||||||
"copy-to-target":
|
"copy-to-target":
|
||||||
Copy current position into target.
|
Copy current position into target. This creates an implicit
|
||||||
|
final step that rotates the view to point at this target.
|
||||||
|
"mouse-drag":
|
||||||
|
Modify heading and pitch in response to mouse drags.
|
||||||
|
heading-scale:
|
||||||
|
pitch-scale:
|
||||||
|
Defaults to 1. For example use zero to disable or -1 to
|
||||||
|
reverse response.
|
||||||
"nearest-tower":
|
"nearest-tower":
|
||||||
Move to nearest tower to aircraft.
|
Move to position of the nearest tower to the aircraft.
|
||||||
"rotate":
|
"rotate":
|
||||||
heading, pitch, roll:
|
heading, pitch, roll:
|
||||||
Values used to rotate direction.
|
Values used to rotate direction.
|
||||||
fixed:
|
|
||||||
If false (the default), mouse drags modify heading and
|
|
||||||
pitch.
|
|
||||||
damping-time-heading, damping-time-pitch, damping-time-roll:
|
damping-time-heading, damping-time-pitch, damping-time-roll:
|
||||||
Damping times for heading, pitch and roll; zero gives no
|
Damping times for heading, pitch and roll; zero gives no
|
||||||
damping. See 'agl' below for details of damping.
|
damping. See 'agl' below for details of damping.
|
||||||
"rotate-current-view":
|
"rotate-current-view":
|
||||||
Rotate view direction by current /sim/current-view/....
|
Rotate view direction by current /sim/current-view/....
|
||||||
"rotate-to-target":
|
|
||||||
Rotate view direction to point at previously-calculated target
|
|
||||||
position.
|
|
||||||
"double":
|
"double":
|
||||||
A double view, with eye in foreground and target in background.
|
A double view, with eye in foreground and target in background.
|
||||||
chase-distance:
|
chase-distance:
|
||||||
|
@ -188,10 +188,6 @@ Examples:
|
||||||
<type>nearest-tower</type>
|
<type>nearest-tower</type>
|
||||||
</step>
|
</step>
|
||||||
|
|
||||||
<step> <!-- Look at target position we found earlier. -->
|
|
||||||
<type>rotate-to-target</type>
|
|
||||||
</step>
|
|
||||||
|
|
||||||
Helicopter view:
|
Helicopter view:
|
||||||
|
|
||||||
<step> <!-- Move to aircraft. -->
|
<step> <!-- Move to aircraft. -->
|
||||||
|
|
Loading…
Add table
Reference in a new issue