'v' toggles internal vs. external view modes.
Add the distance of the bouding radius into the tile's range selector.
t->adjust_warp_delta (+30);
local_update_sky_and_lighting_params();
return;
- case 120: // X key
+ case 118: // v key
+ v->cycle_view_mode();
+ return;
+ case 120: // x key
fov = current_options.get_fov();
fov /= 1.05;
if ( fov < FG_FOV_MIN ) {
sgMat4 sgTRANS;
sgMakeTransMat4( sgTRANS,
- current_view.view_pos.x()
- + current_view.view_forward[0] * 20,
- current_view.view_pos.y()
- + current_view.view_forward[1] * 20,
- current_view.view_pos.z()
- + current_view.view_forward[2] * 20 );
-
- sgMat4 sgTMP;
+ current_view.view_pos.x(),
+ current_view.view_pos.y(),
+ current_view.view_pos.z() );
+
+ // sgMat4 sgTMP;
sgMat4 sgTUX;
- sgMultMat4( sgTMP, current_view.sgUP, sgTRANS );
- sgMultMat4( sgTUX, current_view.sgLARC_TO_SSG, sgTMP );
+ // sgMultMat4( sgTMP, current_view.sgUP, sgTRANS );
+ // sgMultMat4( sgTUX, current_view.sgLARC_TO_SSG, sgTMP );
+ sgMultMat4( sgTUX, current_view.sgVIEW_ROT, sgTRANS );
sgCoord tuxpos;
sgSetCoord( &tuxpos, sgTUX );
current_view.view_pos.y(),
current_view.view_pos.z() );
sgMat4 sgVIEW;
- sgMultMat4( sgVIEW, current_view.sgVIEW, sgTRANS );
+
+ if ( current_view.view_mode == FGView::FG_VIEW_FIRST_PERSON ) {
+ sgCopyMat4( sgVIEW, current_view.sgVIEW );
+ } else if ( current_view.view_mode == FGView::FG_VIEW_FOLLOW ) {
+ FGMat4Wrapper tmp = current_view.follow.front();
+ sgCopyMat4( sgVIEW, tmp.m );
+ }
+ if ( current_view.follow.size() > 15 ) {
+ current_view.follow.pop_front();
+ }
+
ssgSetCamera( sgVIEW );
global_tile_mgr.prep_ssg_nodes();
void FGView::Init( void ) {
FG_LOG( FG_VIEW, FG_INFO, "Initializing View parameters" );
+ view_mode = FG_VIEW_FIRST_PERSON;
view_offset = 0.0;
goal_view_offset = 0.0;
}
+// Cycle view mode
+void FGView::cycle_view_mode() {
+ if ( view_mode == FG_VIEW_FIRST_PERSON ) {
+ view_mode = FG_VIEW_FOLLOW;
+ } else if ( view_mode == FG_VIEW_FOLLOW ) {
+ view_mode = FG_VIEW_FIRST_PERSON;
+ }
+}
+
+
// Basically, this is a modified version of the Mesa gluLookAt()
// function that's been modified slightly so we can capture the
// result before sending it off to OpenGL land.
sgMat4 sgTMP;
sgMultMat4( sgTMP, sgLOCAL, sgUP );
- sgMultMat4( sgVIEW, sgLARC_TO_SSG, sgTMP );
+ sgMultMat4( sgVIEW_ROT, sgLARC_TO_SSG, sgTMP );
+
+ sgMakeTransMat4( sgTRANS, view_pos.x(), view_pos.y(), view_pos.z() );
+
+ sgMultMat4( sgVIEW, sgVIEW_ROT, sgTRANS );
+
+ FGMat4Wrapper tmp;
+ sgCopyMat4( tmp.m, sgVIEW );
+ follow.push_back( tmp );
/*
cout << "FG derived VIEW matrix using sg routines" << endl;
# error This library requires C++
#endif
+#include <Include/compiler.h>
+
+#include <list>
+
#include <sg.h> // plib include
#include <FDM/flight.hxx>
#include "options.hxx"
+FG_USING_STD(list);
+
+
+class FGMat4Wrapper {
+public:
+ sgMat4 m;
+};
+
+typedef list < FGMat4Wrapper > sgMat4_list;
+typedef sgMat4_list::iterator sgMat4_list_iterator;
+typedef sgMat4_list::const_iterator const_sgMat4_list_iterator;
+
// used in views.cxx and tilemgr.cxx
#define USE_FAST_FOV_CLIP
public:
+ enum fgViewMode
+ {
+ FG_VIEW_FIRST_PERSON = 0,
+ FG_VIEW_FOLLOW = 1
+ };
+
// the current offset from forward for viewing
double view_offset;
// Current model view matrix;
GLfloat MODEL_VIEW[16];
- sgMat4 sgLOCAL, sgUP, sgVIEW, sgLARC_TO_SSG;
+ // view mode
+ fgViewMode view_mode;
+
+ // sg versions of our friendly matrices
+ sgMat4 sgLOCAL, sgUP, sgVIEW_ROT, sgTRANS, sgVIEW, sgLARC_TO_SSG;
+
+ // queue of view matrices so we can have a follow view
+ sgMat4_list follow;
public:
// Update the field of view coefficients
void UpdateFOV( const fgOPTIONS& o );
+ // Cycle view mode
+ void cycle_view_mode();
+
// accessor functions
inline double get_view_offset() const { return view_offset; }
inline void set_view_offset( double a ) { view_offset = a; }
float ranges[2];
ranges[0] = 0.0f;
- ranges[1] = current_weather.get_visibility();
// traverse the potentially viewable tile list and update range
// selector and transform
t = global_tile_cache.get_tile(index);
if ( t->is_loaded() ) {
- // set range selector (LOD trick)
+ // set range selector (LOD trick) to be distance to center
+ // of tile + bounding radius
+ ranges[1] = current_weather.get_visibility() + t->bounding_radius;
t->range_ptr->setRanges( ranges, 2 );
// calculate tile offset