- Moved some property specific code into simgear/props/

- Split out the condition code from fgfs/src/Main/fg_props and put it
  in it's own source file in simgear/props/
- Created a scene subdirectory for scenery, model, and material property
  related code.
- Moved location.[ch]xx into simgear/scene/model/
- The location and condition code had dependencies on flightgear's global
  state (all the globals-> stuff, the flightgear property tree, etc.)  SimGear
  code can't depend on it so that data has to be passed as parameters to the
  functions/methods/constructors.
This commit is contained in:
curt
2003-05-06 23:40:43 +00:00
parent 701031a473
commit 525d2df3cc
17 changed files with 1145 additions and 14 deletions

View File

@@ -415,7 +415,10 @@ AC_CONFIG_FILES([ \
simgear/math/Makefile \
simgear/metar/Makefile \
simgear/misc/Makefile \
simgear/props/Makefile \
simgear/route/Makefile \
simgear/scene/Makefile \
simgear/scene/model/Makefile \
simgear/screen/Makefile \
simgear/serial/Makefile \
simgear/sky/Makefile \

View File

@@ -23,7 +23,9 @@ SUBDIRS = \
magvar \
math \
$(METAR_DIRS) \
props \
route \
scene \
screen \
serial \
sky \

View File

@@ -5,8 +5,6 @@ lib_LIBRARIES = libsgmisc.a
include_HEADERS = \
commands.hxx \
exception.hxx \
props.hxx \
props_io.hxx \
sg_path.hxx \
sgstream.hxx \
stopwatch.hxx \
@@ -18,8 +16,6 @@ include_HEADERS = \
libsgmisc_a_SOURCES = \
commands.cxx \
exception.cxx \
props.cxx \
props_io.cxx \
sg_path.cxx \
sgstream.cxx \
strutils.cxx \
@@ -27,12 +23,12 @@ libsgmisc_a_SOURCES = \
texcoord.cxx \
zfstream.cxx
noinst_PROGRAMS = props_test tabbed_value_test
props_test_SOURCES = props_test.cxx
props_test_LDADD = libsgmisc.a ../xml/libsgxml.a ../debug/libsgdebug.a
noinst_PROGRAMS = tabbed_value_test
tabbed_value_test_SOURCES = tabbed_values_test.cxx
tabbed_value_test_LDADD = libsgmisc.a ../xml/libsgxml.a ../debug/libsgdebug.a
tabbed_value_test_LDADD = \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/xml/libsgxml.a \
$(top_builddir)/simgear/debug/libsgdebug.a
INCLUDES = -I$(top_srcdir)

View File

@@ -4,8 +4,9 @@
//
// $Id$
#include <simgear/props/props_io.hxx>
#include "commands.hxx"
#include "props_io.hxx"

View File

@@ -17,7 +17,7 @@
#include <map>
#include <vector>
#include "props.hxx"
#include <simgear/props/props.hxx>
SG_USING_STD(string);
SG_USING_STD(map);

24
simgear/props/Makefile.am Normal file
View File

@@ -0,0 +1,24 @@
includedir = @includedir@/props
lib_LIBRARIES = libsgprops.a
include_HEADERS = \
condition.hxx \
props.hxx \
props_io.hxx
libsgprops_a_SOURCES = \
condition.cxx \
props.cxx \
props_io.cxx
noinst_PROGRAMS = props_test
props_test_SOURCES = props_test.cxx
props_test_LDADD = \
$(top_builddir)/simgear/props/libsgprops.a \
$(top_builddir)/simgear/xml/libsgxml.a \
$(top_builddir)/simgear/misc/libsgmisc.a \
$(top_builddir)/simgear/debug/libsgdebug.a
INCLUDES = -I$(top_srcdir)

435
simgear/props/condition.cxx Normal file
View File

@@ -0,0 +1,435 @@
// condition.hxx - Declarations and inline methods for property conditions.
// Written by David Megginson, started 2000.
// CLO May 2003 - Split out condition specific code.
//
// This file is in the Public Domain, and comes with no warranty.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <simgear/compiler.h>
#endif
// #include STL_IOSTREAM
#include <simgear/misc/exception.hxx>
#include "props.hxx"
#include "condition.hxx"
SG_USING_STD(istream);
SG_USING_STD(ostream);
////////////////////////////////////////////////////////////////////////
// Implementation of FGCondition.
////////////////////////////////////////////////////////////////////////
FGCondition::FGCondition ()
{
}
FGCondition::~FGCondition ()
{
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGPropertyCondition.
////////////////////////////////////////////////////////////////////////
FGPropertyCondition::FGPropertyCondition ( SGPropertyNode *prop_root,
const char *propname )
: _node( prop_root->getNode(propname, true) )
{
cout << "FGPropertyCondition::FGPropertyCondition()" << endl;
cout << " prop_root = " << prop_root << endl;
cout << " propname = " << propname << endl;
_node = prop_root->getNode(propname, true);
cout << " _node = " << _node << endl;
}
FGPropertyCondition::~FGPropertyCondition ()
{
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGNotCondition.
////////////////////////////////////////////////////////////////////////
FGNotCondition::FGNotCondition (FGCondition * condition)
: _condition(condition)
{
}
FGNotCondition::~FGNotCondition ()
{
delete _condition;
}
bool
FGNotCondition::test () const
{
return !(_condition->test());
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGAndCondition.
////////////////////////////////////////////////////////////////////////
FGAndCondition::FGAndCondition ()
{
}
FGAndCondition::~FGAndCondition ()
{
for (unsigned int i = 0; i < _conditions.size(); i++)
delete _conditions[i];
}
bool
FGAndCondition::test () const
{
int nConditions = _conditions.size();
for (int i = 0; i < nConditions; i++) {
if (!_conditions[i]->test())
return false;
}
return true;
}
void
FGAndCondition::addCondition (FGCondition * condition)
{
_conditions.push_back(condition);
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGOrCondition.
////////////////////////////////////////////////////////////////////////
FGOrCondition::FGOrCondition ()
{
}
FGOrCondition::~FGOrCondition ()
{
for (unsigned int i = 0; i < _conditions.size(); i++)
delete _conditions[i];
}
bool
FGOrCondition::test () const
{
int nConditions = _conditions.size();
for (int i = 0; i < nConditions; i++) {
if (_conditions[i]->test())
return true;
}
return false;
}
void
FGOrCondition::addCondition (FGCondition * condition)
{
_conditions.push_back(condition);
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGComparisonCondition.
////////////////////////////////////////////////////////////////////////
static int
doComparison (const SGPropertyNode * left, const SGPropertyNode *right)
{
switch (left->getType()) {
case SGPropertyNode::BOOL: {
bool v1 = left->getBoolValue();
bool v2 = right->getBoolValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
case SGPropertyNode::INT: {
int v1 = left->getIntValue();
int v2 = right->getIntValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
case SGPropertyNode::LONG: {
long v1 = left->getLongValue();
long v2 = right->getLongValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
case SGPropertyNode::FLOAT: {
float v1 = left->getFloatValue();
float v2 = right->getFloatValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
case SGPropertyNode::DOUBLE: {
double v1 = left->getDoubleValue();
double v2 = right->getDoubleValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
case SGPropertyNode::STRING:
case SGPropertyNode::NONE:
case SGPropertyNode::UNSPECIFIED: {
string v1 = left->getStringValue();
string v2 = right->getStringValue();
if (v1 < v2)
return FGComparisonCondition::LESS_THAN;
else if (v1 > v2)
return FGComparisonCondition::GREATER_THAN;
else
return FGComparisonCondition::EQUALS;
break;
}
}
throw sg_exception("Unrecognized node type");
return 0;
}
FGComparisonCondition::FGComparisonCondition (Type type, bool reverse)
: _type(type),
_reverse(reverse),
_left_property(0),
_right_property(0),
_right_value(0)
{
}
FGComparisonCondition::~FGComparisonCondition ()
{
delete _right_value;
}
bool
FGComparisonCondition::test () const
{
// Always fail if incompletely specified
if (_left_property == 0 ||
(_right_property == 0 && _right_value == 0))
return false;
// Get LESS_THAN, EQUALS, or GREATER_THAN
int cmp =
doComparison(_left_property,
(_right_property != 0 ? _right_property : _right_value));
if (!_reverse)
return (cmp == _type);
else
return (cmp != _type);
}
void
FGComparisonCondition::setLeftProperty( SGPropertyNode *prop_root,
const char * propname )
{
_left_property = prop_root->getNode(propname, true);
}
void
FGComparisonCondition::setRightProperty( SGPropertyNode *prop_root,
const char * propname )
{
delete _right_value;
_right_value = 0;
_right_property = prop_root->getNode(propname, true);
}
void
FGComparisonCondition::setRightValue (const SGPropertyNode *node)
{
_right_property = 0;
delete _right_value;
_right_value = new SGPropertyNode(*node);
}
////////////////////////////////////////////////////////////////////////
// Read a condition and use it if necessary.
////////////////////////////////////////////////////////////////////////
// Forward declaration
static FGCondition * readCondition( SGPropertyNode *prop_root,
const SGPropertyNode *node );
static FGCondition *
readPropertyCondition( SGPropertyNode *prop_root,
const SGPropertyNode *node )
{
return new FGPropertyCondition( prop_root, node->getStringValue() );
}
static FGCondition *
readNotCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
{
int nChildren = node->nChildren();
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode * child = node->getChild(i);
FGCondition * condition = readCondition(prop_root, child);
if (condition != 0)
return new FGNotCondition(condition);
}
SG_LOG(SG_COCKPIT, SG_ALERT, "Panel: empty 'not' condition");
return 0;
}
static FGCondition *
readAndConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
{
FGAndCondition * andCondition = new FGAndCondition;
int nChildren = node->nChildren();
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode * child = node->getChild(i);
FGCondition * condition = readCondition(prop_root, child);
if (condition != 0)
andCondition->addCondition(condition);
}
return andCondition;
}
static FGCondition *
readOrConditions( SGPropertyNode *prop_root, const SGPropertyNode *node )
{
FGOrCondition * orCondition = new FGOrCondition;
int nChildren = node->nChildren();
for (int i = 0; i < nChildren; i++) {
const SGPropertyNode * child = node->getChild(i);
FGCondition * condition = readCondition(prop_root, child);
if (condition != 0)
orCondition->addCondition(condition);
}
return orCondition;
}
static FGCondition *
readComparison( SGPropertyNode *prop_root,
const SGPropertyNode *node,
FGComparisonCondition::Type type,
bool reverse)
{
FGComparisonCondition * condition = new FGComparisonCondition(type, reverse);
condition->setLeftProperty(prop_root, node->getStringValue("property[0]"));
if (node->hasValue("property[1]"))
condition->setRightProperty(prop_root, node->getStringValue("property[1]"));
else
condition->setRightValue(node->getChild("value", 0));
return condition;
}
static FGCondition *
readCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
{
const string &name = node->getName();
if (name == "property")
return readPropertyCondition(prop_root, node);
else if (name == "not")
return readNotCondition(prop_root, node);
else if (name == "and")
return readAndConditions(prop_root, node);
else if (name == "or")
return readOrConditions(prop_root, node);
else if (name == "less-than")
return readComparison(prop_root, node, FGComparisonCondition::LESS_THAN,
false);
else if (name == "less-than-equals")
return readComparison(prop_root, node, FGComparisonCondition::GREATER_THAN,
true);
else if (name == "greater-than")
return readComparison(prop_root, node, FGComparisonCondition::GREATER_THAN,
false);
else if (name == "greater-than-equals")
return readComparison(prop_root, node, FGComparisonCondition::LESS_THAN,
true);
else if (name == "equals")
return readComparison(prop_root, node, FGComparisonCondition::EQUALS,
false);
else if (name == "not-equals")
return readComparison(prop_root, node, FGComparisonCondition::EQUALS, true);
else
return 0;
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGConditional.
////////////////////////////////////////////////////////////////////////
FGConditional::FGConditional ()
: _condition (0)
{
}
FGConditional::~FGConditional ()
{
delete _condition;
}
void
FGConditional::setCondition (FGCondition * condition)
{
delete _condition;
_condition = condition;
}
bool
FGConditional::test () const
{
return ((_condition == 0) || _condition->test());
}
// The top-level is always an implicit 'and' group
FGCondition *
fgReadCondition( SGPropertyNode *prop_root, const SGPropertyNode *node )
{
return readAndConditions(prop_root, node);
}
// end of fg_props.cxx

176
simgear/props/condition.hxx Normal file
View File

@@ -0,0 +1,176 @@
// condition.hxx - Declarations and inline methods for property conditions.
// Written by David Megginson, started 2000.
// CLO May 2003 - Split out condition specific code.
//
// This file is in the Public Domain, and comes with no warranty.
#ifndef __SG_CONDITION_HXX
#define __SG_CONDITION_HXX
#include <simgear/debug/logstream.hxx>
#include <simgear/props/props.hxx>
#include <simgear/props/props_io.hxx>
////////////////////////////////////////////////////////////////////////
// Conditions.
////////////////////////////////////////////////////////////////////////
/**
* An encoded condition.
*
* This class encodes a single condition of some sort, possibly
* connected with properties.
*
* This class should migrate to somewhere more general.
*/
class FGCondition
{
public:
FGCondition ();
virtual ~FGCondition ();
virtual bool test () const = 0;
};
/**
* Condition for a single property.
*
* This condition is true only if the property returns a boolean
* true value.
*/
class FGPropertyCondition : public FGCondition
{
public:
FGPropertyCondition ( SGPropertyNode *prop_root,
const char * propname );
virtual ~FGPropertyCondition ();
virtual bool test () const { return _node->getBoolValue(); }
private:
const SGPropertyNode * _node;
};
/**
* Condition for a 'not' operator.
*
* This condition is true only if the child condition is false.
*/
class FGNotCondition : public FGCondition
{
public:
// transfer pointer ownership
FGNotCondition (FGCondition * condition);
virtual ~FGNotCondition ();
virtual bool test () const;
private:
FGCondition * _condition;
};
/**
* Condition for an 'and' group.
*
* This condition is true only if all of the conditions
* in the group are true.
*/
class FGAndCondition : public FGCondition
{
public:
FGAndCondition ();
virtual ~FGAndCondition ();
virtual bool test () const;
// transfer pointer ownership
virtual void addCondition (FGCondition * condition);
private:
vector<FGCondition *> _conditions;
};
/**
* Condition for an 'or' group.
*
* This condition is true if at least one of the conditions in the
* group is true.
*/
class FGOrCondition : public FGCondition
{
public:
FGOrCondition ();
virtual ~FGOrCondition ();
virtual bool test () const;
// transfer pointer ownership
virtual void addCondition (FGCondition * condition);
private:
vector<FGCondition *> _conditions;
};
/**
* Abstract base class for property comparison conditions.
*/
class FGComparisonCondition : public FGCondition
{
public:
enum Type {
LESS_THAN,
GREATER_THAN,
EQUALS
};
FGComparisonCondition (Type type, bool reverse = false);
virtual ~FGComparisonCondition ();
virtual bool test () const;
virtual void setLeftProperty( SGPropertyNode *prop_root,
const char * propname );
virtual void setRightProperty( SGPropertyNode *prop_root,
const char * propname );
// will make a local copy
virtual void setRightValue (const SGPropertyNode * value);
private:
Type _type;
bool _reverse;
const SGPropertyNode * _left_property;
const SGPropertyNode * _right_property;
const SGPropertyNode * _right_value;
};
/**
* Base class for a conditional components.
*
* This class manages the conditions and tests; the component should
* invoke the test() method whenever it needs to decide whether to
* active itself, draw itself, and so on.
*/
class FGConditional
{
public:
FGConditional ();
virtual ~FGConditional ();
// transfer pointer ownership
virtual void setCondition (FGCondition * condition);
virtual const FGCondition * getCondition () const { return _condition; }
virtual bool test () const;
private:
FGCondition * _condition;
};
/**
* Global function to make a condition out of properties.
*
* The top-level is always an implicit 'and' group, whatever the
* node's name (it should usually be "condition").
*
* @param node The top-level condition node (usually named "condition").
* @return A pointer to a newly-allocated condition; it is the
* responsibility of the caller to delete the condition when
* it is no longer needed.
*/
FGCondition * fgReadCondition( SGPropertyNode *prop_root,
const SGPropertyNode *node );
#endif // __SG_CONDITION_HXX

View File

@@ -1726,7 +1726,7 @@ SGPropertyNode::getNode (const char * relative_path, bool create)
if (result != 0)
_path_cache->put(relative_path, result);
}
return result;
}

View File

@@ -5,9 +5,9 @@
#include <simgear/sg_inlines.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/sg_path.hxx>
#include <simgear/xml/easyxml.hxx>
#include "sg_path.hxx"
#include "props.hxx"
#include "props_io.hxx"

View File

@@ -13,7 +13,7 @@
#define __PROPS_IO_HXX
#include <simgear/compiler.h>
#include <simgear/misc/props.hxx>
#include <simgear/props/props.hxx>
#include <stdio.h>

13
simgear/scene/Makefile.am Normal file
View File

@@ -0,0 +1,13 @@
includedir = @includedir@/scene
SUBDIRS = model
# lib_LIBRARIES = libsgscene.a
# noinst_HEADERS =
# include_HEADERS =
# libsgscene_a_SOURCES =
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,11 @@
includedir = @includedir@/scene/model
lib_LIBRARIES = libsgmodel.a
noinst_HEADERS =
include_HEADERS = location.hxx
libsgmodel_a_SOURCES = location.cxx
INCLUDES = -I$(top_srcdir)

View File

@@ -0,0 +1,283 @@
// location.cxx -- class for determining model location in the flightgear world.
//
// Written by Jim Wilson, David Megginson, started April 2002.
// Based largely on code by Curtis Olson and Norman Vine.
//
// Copyright (C) 2002 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include <simgear/compiler.h>
#ifdef HAVE_CONFIG_H
# include <simgear_config.h>
#endif
#include <simgear/debug/logstream.hxx>
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/math/sg_geodesy.hxx>
#include <simgear/math/vector.hxx>
// #include <Scenery/scenery.hxx>
// #include "globals.hxx"
#include "location.hxx"
/**
* make model transformation Matrix - based on optimizations by NHV
*/
static void MakeTRANS( sgMat4 dst, const double Theta,
const double Phi, const double Psi,
const sgMat4 UP)
{
SGfloat cosTheta = (SGfloat) cos(Theta);
SGfloat sinTheta = (SGfloat) sin(Theta);
SGfloat cosPhi = (SGfloat) cos(Phi);
SGfloat sinPhi = (SGfloat) sin(Phi);
SGfloat sinPsi = (SGfloat) sin(Psi) ;
SGfloat cosPsi = (SGfloat) cos(Psi) ;
sgMat4 tmp;
tmp[0][0] = cosPhi * cosTheta;
tmp[0][1] = sinPhi * cosPsi + cosPhi * -sinTheta * -sinPsi;
tmp[0][2] = sinPhi * sinPsi + cosPhi * -sinTheta * cosPsi;
tmp[1][0] = -sinPhi * cosTheta;
tmp[1][1] = cosPhi * cosPsi + -sinPhi * -sinTheta * -sinPsi;
tmp[1][2] = cosPhi * sinPsi + -sinPhi * -sinTheta * cosPsi;
tmp[2][0] = sinTheta;
tmp[2][1] = cosTheta * -sinPsi;
tmp[2][2] = cosTheta * cosPsi;
float a = UP[0][0];
float b = UP[1][0];
float c = UP[2][0];
dst[2][0] = a*tmp[0][0] + b*tmp[0][1] + c*tmp[0][2] ;
dst[1][0] = a*tmp[1][0] + b*tmp[1][1] + c*tmp[1][2] ;
dst[0][0] = -(a*tmp[2][0] + b*tmp[2][1] + c*tmp[2][2]) ;
dst[3][0] = SG_ZERO ;
a = UP[0][1];
b = UP[1][1];
c = UP[2][1];
dst[2][1] = a*tmp[0][0] + b*tmp[0][1] + c*tmp[0][2] ;
dst[1][1] = a*tmp[1][0] + b*tmp[1][1] + c*tmp[1][2] ;
dst[0][1] = -(a*tmp[2][0] + b*tmp[2][1] + c*tmp[2][2]) ;
dst[3][1] = SG_ZERO ;
a = UP[0][2];
c = UP[2][2];
dst[2][2] = a*tmp[0][0] + c*tmp[0][2] ;
dst[1][2] = a*tmp[1][0] + c*tmp[1][2] ;
dst[0][2] = -(a*tmp[2][0] + c*tmp[2][2]) ;
dst[3][2] = SG_ZERO ;
dst[2][3] = SG_ZERO ;
dst[1][3] = SG_ZERO ;
dst[0][3] = SG_ZERO ;
dst[3][3] = SG_ONE ;
}
////////////////////////////////////////////////////////////////////////
// Implementation of FGLocation.
////////////////////////////////////////////////////////////////////////
// Constructor
FGLocation::FGLocation( void ):
_dirty(true),
_lon_deg(0),
_lat_deg(0),
_alt_ft(0),
_roll_deg(0),
_pitch_deg(0),
_heading_deg(0),
_cur_elev_m(0),
_tile_center(0)
{
sgdZeroVec3(_absolute_view_pos);
sgZeroVec3(_relative_view_pos);
sgZeroVec3(_zero_elev_view_pos);
sgMakeRotMat4( UP, 0.0, 0.0, 0.0 );
sgMakeRotMat4( TRANS, 0.0, 0.0, 0.0 );
}
// Destructor
FGLocation::~FGLocation( void ) {
}
void
FGLocation::init ()
{
}
void
FGLocation::bind ()
{
}
void
FGLocation::unbind ()
{
}
void
FGLocation::setPosition (double lon_deg, double lat_deg, double alt_ft)
{
_dirty = true;
_lon_deg = lon_deg;
_lat_deg = lat_deg;
_alt_ft = alt_ft;
}
void
FGLocation::setOrientation (double roll_deg, double pitch_deg, double heading_deg)
{
_dirty = true;
_roll_deg = roll_deg;
_pitch_deg = pitch_deg;
_heading_deg = heading_deg;
}
double *
FGLocation::get_absolute_view_pos( const Point3D scenery_center )
{
if ( _dirty ) {
recalc( scenery_center );
}
return _absolute_view_pos;
}
float *
FGLocation::getRelativeViewPos( const Point3D scenery_center )
{
if ( _dirty ) {
recalc( scenery_center );
}
return _relative_view_pos;
}
float *
FGLocation::getZeroElevViewPos( const Point3D scenery_center )
{
if ( _dirty ) {
recalc( scenery_center );
}
return _zero_elev_view_pos;
}
// recalc() is done every time one of the setters is called (making the
// cached data "dirty") on the next "get". It calculates all the outputs
// for viewer.
void
FGLocation::recalc( const Point3D scenery_center )
{
recalcPosition( _lon_deg, _lat_deg, _alt_ft, scenery_center );
// Make the world up rotation matrix for eye positioin...
sgMakeRotMat4( UP, _lon_deg, 0.0, -_lat_deg );
// get the world up radial vector from planet center for output
sgSetVec3( _world_up, UP[0][0], UP[0][1], UP[0][2] );
// Creat local matrix with current geodetic position. Converting
// the orientation (pitch/roll/heading) to vectors.
MakeTRANS( TRANS, _pitch_deg * SG_DEGREES_TO_RADIANS,
_roll_deg * SG_DEGREES_TO_RADIANS,
-_heading_deg * SG_DEGREES_TO_RADIANS,
UP);
// Given a vector pointing straight down (-Z), map into onto the
// local plane representing "horizontal". This should give us the
// local direction for moving "south".
sgVec3 minus_z;
sgSetVec3( minus_z, 0.0, 0.0, -1.0 );
sgmap_vec_onto_cur_surface_plane(_world_up, _relative_view_pos, minus_z,
_surface_south);
sgNormalizeVec3(_surface_south);
// now calculate the surface east vector
sgVec3 world_down;
sgNegateVec3(world_down, _world_up);
sgVectorProductVec3(_surface_east, _surface_south, world_down);
set_clean();
}
void
FGLocation::recalcPosition( double lon_deg, double lat_deg, double alt_ft,
const Point3D scenery_center ) const
{
double sea_level_radius_m;
double lat_geoc_rad;
// Convert from geodetic to geocentric
// coordinates.
sgGeodToGeoc(lat_deg * SGD_DEGREES_TO_RADIANS,
alt_ft * SG_FEET_TO_METER,
&sea_level_radius_m,
&lat_geoc_rad);
// Calculate the cartesian coordinates
// of point directly below at sea level.
// aka Zero Elevation Position
Point3D p = Point3D(lon_deg * SG_DEGREES_TO_RADIANS,
lat_geoc_rad,
sea_level_radius_m);
Point3D tmp = sgPolarToCart3d(p) - _tile_center;
sgSetVec3(_zero_elev_view_pos, tmp[0], tmp[1], tmp[2]);
// Calculate the absolute view position
// in fgfs coordinates.
// aka Absolute View Position
p.setz(p.radius() + alt_ft * SG_FEET_TO_METER);
tmp = sgPolarToCart3d(p);
sgdSetVec3(_absolute_view_pos, tmp[0], tmp[1], tmp[2]);
// Calculate the relative view position
// from the scenery center.
// aka Relative View Position
// FIXME: view position should ONLY be calculated in the viewer...
// Anything else should calculate their own positions relative to the
// viewer's tile_center.
sgdVec3 center;
sgdSetVec3( center,
scenery_center.x(), scenery_center.y(), scenery_center.z() );
sgdVec3 view_pos;
sgdSubVec3(view_pos, _absolute_view_pos, center);
sgSetVec3(_relative_view_pos, view_pos);
}
void
FGLocation::update (int dt)
{
}

View File

@@ -0,0 +1,187 @@
// location.hxx -- class for determining model location in the flightgear world.
//
// Written by Jim Wilson, David Megginson, started April 2002.
//
// Copyright (C) 2002 Jim Wilson, David Megginson
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _LOCATION_HXX
#define _LOCATION_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
#include <plib/sg.h> // plib include
// #include "fgfs.hxx"
// Define a structure containing view information
class FGLocation
{
public:
// Constructor
FGLocation( void );
// Destructor
virtual ~FGLocation( void );
//////////////////////////////////////////////////////////////////////
// Part 1: standard FGSubsystem implementation.
//////////////////////////////////////////////////////////////////////
virtual void init ();
virtual void bind ();
virtual void unbind ();
void update (int dt);
//////////////////////////////////////////////////////////////////////
// Part 2: user settings.
//////////////////////////////////////////////////////////////////////
// Geodetic position of model...
virtual double getLongitude_deg () const { return _lon_deg; }
virtual double getLatitude_deg () const { return _lat_deg; }
virtual double getAltitudeASL_ft () const { return _alt_ft; }
virtual void setPosition (double lon_deg, double lat_deg, double alt_ft);
// Reference orientation rotations...
// These are rotations that represent the plane attitude effect on
// the view (in Pilot view). IE The view frustrum rotates as the plane
// turns, pitches, and rolls.
// In model view (lookat/chaseview) these end up changing the angle that
// the eye is looking at the ojbect (ie the model).
// FIXME: the FGModel class should have its own version of these so that
// it can generate it's own model rotations.
virtual double getRoll_deg () const { return _roll_deg; }
virtual double getPitch_deg () const {return _pitch_deg; }
virtual double getHeading_deg () const {return _heading_deg; }
virtual void setOrientation (double roll_deg, double pitch_deg, double heading_deg);
//////////////////////////////////////////////////////////////////////
// Part 3: output vectors and matrices in FlightGear coordinates.
//////////////////////////////////////////////////////////////////////
// Vectors and positions...
// Get zero view_pos
virtual float * get_view_pos() { return _relative_view_pos; }
// Get the absolute view position in fgfs coordinates.
virtual double * get_absolute_view_pos( const Point3D scenery_center );
// Get zero elev
virtual float * get_zero_elev() { return _zero_elev_view_pos; }
// Get world up vector
virtual float *get_world_up() { return _world_up; }
// Get the relative (to scenery center) view position in fgfs coordinates.
virtual float * getRelativeViewPos( const Point3D scenery_center );
// Get the absolute zero-elevation view position in fgfs coordinates.
virtual float * getZeroElevViewPos( const Point3D scenery_center );
// Get surface east vector
virtual float *get_surface_east() { return _surface_east; }
// Get surface south vector
virtual float *get_surface_south() { return _surface_south; }
// Elevation of ground under location (based on scenery output)...
void set_cur_elev_m ( double elev ) { _cur_elev_m = elev; }
inline double get_cur_elev_m () { return _cur_elev_m; }
// Interface to current buckets for use with tilemgr...
void set_tile_center ( Point3D tile_center ) { _tile_center = tile_center; }
inline Point3D get_tile_center () { return _tile_center; }
// Matrices...
virtual const sgVec4 *getTransformMatrix( const Point3D scenery_center ) {
if ( _dirty ) {
recalc( scenery_center );
}
return TRANS;
}
virtual const sgVec4 *getCachedTransformMatrix() { return TRANS; }
virtual const sgVec4 *getUpMatrix( const Point3D scenery_center ) {
if ( _dirty ) {
recalc( scenery_center );
}
return UP;
}
virtual const sgVec4 *getCachedUpMatrix() { return UP; }
private:
//////////////////////////////////////////////////////////////////
// private data //
//////////////////////////////////////////////////////////////////
// flag forcing a recalc of derived view parameters
bool _dirty;
mutable sgdVec3 _absolute_view_pos;
mutable sgVec3 _relative_view_pos;
mutable sgVec3 _zero_elev_view_pos;
double _lon_deg;
double _lat_deg;
double _alt_ft;
double _roll_deg;
double _pitch_deg;
double _heading_deg;
// elevation of ground under this location...
double _cur_elev_m;
Point3D _tile_center;
// surface vector heading south
sgVec3 _surface_south;
// surface vector heading east (used to unambiguously align sky
// with sun)
sgVec3 _surface_east;
// world up vector (normal to the plane tangent to the earth's
// surface at the spot we are directly above
sgVec3 _world_up;
// sg versions of our friendly matrices
sgMat4 TRANS, UP;
//////////////////////////////////////////////////////////////////
// private functions //
//////////////////////////////////////////////////////////////////
void recalc( const Point3D scenery_center );
void recalcPosition( double lon_deg, double lat_deg, double alt_ft,
const Point3D scenery_center ) const;
inline void set_dirty() { _dirty = true; }
inline void set_clean() { _dirty = false; }
};
#endif // _LOCATION_HXX