Worked on creating data to output ... normals, bounding spheres, etc.
This commit is contained in:
parent
1dce89b1aa
commit
427762b074
3 changed files with 342 additions and 36 deletions
|
@ -23,14 +23,130 @@
|
|||
// (Log is kept at end of this file)
|
||||
|
||||
|
||||
#include <time.h>
|
||||
|
||||
#include <Tools/scenery_version.hxx>
|
||||
#include <Math/mat3.h>
|
||||
|
||||
#include "genobj.hxx"
|
||||
|
||||
|
||||
// Calculate the global bounding sphere from all the input points.
|
||||
// Center is the average of the points.
|
||||
static void calc_gbs( const trinode_list& nodelist, Point3D *center,
|
||||
double *radius )
|
||||
{
|
||||
// build the wgs-84 point list
|
||||
void FGGenOutput::gen_wgs84_points() {
|
||||
cout << "calculating wgs84 point" << endl;
|
||||
Point3D geod, radians, cart;
|
||||
|
||||
const_point_list_iterator current = geod_nodes.begin();
|
||||
const_point_list_iterator last = geod_nodes.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
geod = *current;
|
||||
|
||||
// convert to radians
|
||||
radians = Point3D( geod.x() * DEG_TO_RAD,
|
||||
geod.y() * DEG_TO_RAD,
|
||||
geod.z() );
|
||||
|
||||
cart = fgGeodToCart(radians);
|
||||
// cout << cart << endl;
|
||||
wgs84_nodes.push_back(cart);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table. there
|
||||
// is an entry for each point containing a list of all the triangles
|
||||
// that share that point.
|
||||
void FGGenOutput::gen_node_ele_lookup_table() {
|
||||
belongs_to ele_list;
|
||||
ele_list.erase( ele_list.begin(), ele_list.end() );
|
||||
|
||||
// initialize reverse_ele_lookup structure by creating an empty
|
||||
// list for each point
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
for ( ; w_current != w_last; ++w_current ) {
|
||||
reverse_ele_lookup.push_back( ele_list );
|
||||
}
|
||||
|
||||
// traverse triangle structure building reverse lookup table
|
||||
const_triele_list_iterator current = tri_elements.begin();
|
||||
const_triele_list_iterator last = tri_elements.end();
|
||||
int counter = 0;
|
||||
for ( ; current != last; ++current ) {
|
||||
reverse_ele_lookup[ current->get_n1() ].push_back( counter );
|
||||
reverse_ele_lookup[ current->get_n2() ].push_back( counter );
|
||||
reverse_ele_lookup[ current->get_n3() ].push_back( counter );
|
||||
++counter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D FGGenOutput::calc_normal( int i ) {
|
||||
double v1[3], v2[3], normal[3];
|
||||
double temp;
|
||||
|
||||
Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
|
||||
|
||||
v1[0] = p2.x() - p1.x(); v1[1] = p2.y() - p1.y(); v1[2] = p2.z() - p1.z();
|
||||
v2[0] = p3.x() - p1.x(); v2[1] = p3.y() - p1.y(); v2[2] = p3.z() - p1.z();
|
||||
|
||||
MAT3cross_product(normal, v1, v2);
|
||||
MAT3_NORMALIZE_VEC(normal,temp);
|
||||
|
||||
return Point3D( normal[0], normal[1], normal[2] );
|
||||
}
|
||||
|
||||
|
||||
// build the face normal list
|
||||
void FGGenOutput::gen_face_normals() {
|
||||
// traverse triangle structure building the face normal table
|
||||
|
||||
cout << "calculating face normals" << endl;
|
||||
|
||||
for ( int i = 0; i < (int)tri_elements.size(); i++ ) {
|
||||
// cout << calc_normal( i ) << endl;
|
||||
face_normals.push_back( calc_normal( i ) );
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void FGGenOutput::gen_normals() {
|
||||
Point3D normal;
|
||||
cout << "caculating node normals" << endl;
|
||||
|
||||
// for each node
|
||||
for ( int i = 0; i < (int)wgs84_nodes.size(); ++i ) {
|
||||
belongs_to tri_list = reverse_ele_lookup[i];
|
||||
|
||||
belongs_to_iterator current = tri_list.begin();
|
||||
belongs_to_iterator last = tri_list.end();
|
||||
|
||||
Point3D average( 0.0 );
|
||||
|
||||
// for each triangle that shares this node
|
||||
for ( ; current != last; ++current ) {
|
||||
normal = face_normals[ *current ];
|
||||
average += normal;
|
||||
// cout << normal << endl;
|
||||
}
|
||||
|
||||
average /= tri_list.size();
|
||||
// cout << "average = " << average << endl;
|
||||
|
||||
point_normals.push_back( average );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of the
|
||||
// points.
|
||||
void FGGenOutput::calc_gbs() {
|
||||
double x = 0;
|
||||
double y = 0;
|
||||
double z = 0;
|
||||
|
@ -38,8 +154,8 @@ static void calc_gbs( const trinode_list& nodelist, Point3D *center,
|
|||
double dist_squared;
|
||||
double radius_squared = 0;
|
||||
|
||||
const_trinode_list_iterator current = nodelist.begin();
|
||||
const_trinode_list_iterator last = nodelist.end();
|
||||
const_point_list_iterator current = wgs84_nodes.begin();
|
||||
const_point_list_iterator last = wgs84_nodes.end();
|
||||
|
||||
for ( ; current != last; ++current ) {
|
||||
x += current->x();
|
||||
|
@ -47,39 +163,163 @@ static void calc_gbs( const trinode_list& nodelist, Point3D *center,
|
|||
z += current->z();
|
||||
}
|
||||
|
||||
x /= nodelist.size();
|
||||
y /= nodelist.size();
|
||||
z /= nodelist.size();
|
||||
x /= wgs84_nodes.size();
|
||||
y /= wgs84_nodes.size();
|
||||
z /= wgs84_nodes.size();
|
||||
|
||||
*center = Point3D(x, y, z);
|
||||
gbs_center = Point3D(x, y, z);
|
||||
|
||||
current = nodelist.begin();
|
||||
current = wgs84_nodes.begin();
|
||||
for ( ; current != last; ++current ) {
|
||||
dist_squared = center->distance3Dsquared(*current);
|
||||
dist_squared = gbs_center.distance3Dsquared(*current);
|
||||
if ( dist_squared > radius_squared ) {
|
||||
radius_squared = dist_squared;
|
||||
}
|
||||
}
|
||||
|
||||
*radius = sqrt(radius_squared);
|
||||
gbs_radius = sqrt(radius_squared);
|
||||
}
|
||||
|
||||
|
||||
// generate the flight gear format from the triangulation
|
||||
int fgGenOutput( const FGTriangle& t ) {
|
||||
Point3D gbs;
|
||||
double gradius;
|
||||
|
||||
// build the necessary output structures based on the triangulation
|
||||
// data
|
||||
int FGGenOutput::build( const FGTriangle& t ) {
|
||||
FGTriNodes trinodes = t.get_out_nodes();
|
||||
trinode_list nodelist = trinodes.get_node_list();
|
||||
|
||||
calc_gbs( nodelist, &gbs, &gradius );
|
||||
cout << "center = " << gbs << " radius = " << gradius << endl;
|
||||
// copy the geodetic node list into this class
|
||||
geod_nodes = trinodes.get_node_list();
|
||||
|
||||
// copy the triangle list into this class
|
||||
tri_elements = t.get_elelist();
|
||||
|
||||
// generate the point list in wgs-84 coordinates
|
||||
gen_wgs84_points();
|
||||
|
||||
// calculate the global bounding sphere
|
||||
calc_gbs();
|
||||
cout << "center = " << gbs_center << " radius = " << gbs_radius << endl;
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table
|
||||
gen_node_ele_lookup_table();
|
||||
|
||||
// build the face normal list
|
||||
gen_face_normals();
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
gen_normals();
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void FGGenOutput::calc_bounding_sphere( int i, Point3D *center,
|
||||
double *radius ) {
|
||||
Point3D c( 0.0 );
|
||||
|
||||
Point3D p1 = wgs84_nodes[ tri_elements[i].get_n1() ];
|
||||
Point3D p2 = wgs84_nodes[ tri_elements[i].get_n2() ];
|
||||
Point3D p3 = wgs84_nodes[ tri_elements[i].get_n3() ];
|
||||
|
||||
c = p1 + p2 + p3;
|
||||
c /= 3;
|
||||
|
||||
double dist_squared;
|
||||
double max_squared = 0;
|
||||
|
||||
dist_squared = c.distance3Dsquared(p1);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p2);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
dist_squared = c.distance3Dsquared(p3);
|
||||
if ( dist_squared > max_squared ) {
|
||||
max_squared = dist_squared;
|
||||
}
|
||||
|
||||
*center = c;
|
||||
*radius = sqrt(max_squared);
|
||||
}
|
||||
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int FGGenOutput::write( const string& path ) {
|
||||
Point3D p;
|
||||
|
||||
FILE *fp;
|
||||
if ( (fp = fopen( path.c_str(), "w" )) == NULL ) {
|
||||
cout << "ERROR: opening " << path << " for writing!" << endl;
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
// write headers
|
||||
fprintf(fp, "# FGFS Scenery Version %s\n", FG_SCENERY_FILE_FORMAT);
|
||||
|
||||
time_t calendar_time = time(NULL);
|
||||
struct tm *local_tm;
|
||||
local_tm = localtime( &calendar_time );
|
||||
char time_str[256];
|
||||
strftime( time_str, 256, "%a %b %d %H:%M:%S %Z %Y", local_tm);
|
||||
fprintf(fp, "# Created %s\n", time_str );
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write global bounding spher
|
||||
fprintf(fp, "# gbs %.5f %.5f %.5f %.2f\n",
|
||||
gbs_center.x(), gbs_center.y(), gbs_center.z(), gbs_radius);
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write nodes
|
||||
fprintf(fp, "# vertex list\n");
|
||||
const_point_list_iterator w_current = wgs84_nodes.begin();
|
||||
const_point_list_iterator w_last = wgs84_nodes.end();
|
||||
for ( ; w_current != w_last; ++w_current ) {
|
||||
p = *w_current - gbs_center;
|
||||
fprintf(fp, "v %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write vertex normals
|
||||
fprintf(fp, "# vertex normal list\n");
|
||||
const_point_list_iterator n_current = point_normals.begin();
|
||||
const_point_list_iterator n_last = point_normals.end();
|
||||
for ( ; n_current != n_last; ++n_current ) {
|
||||
p = *n_current;
|
||||
fprintf(fp, "vn %.5f %.5f %.5f\n", p.x(), p.y(), p.z());
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
|
||||
// write triangles
|
||||
Point3D center;
|
||||
double radius;
|
||||
fprintf(fp, "# triangle list\n");
|
||||
fprintf(fp, "\n");
|
||||
const_triele_list_iterator t_current = tri_elements.begin();
|
||||
const_triele_list_iterator t_last = tri_elements.end();
|
||||
int counter = 0;
|
||||
for ( ; t_current != t_last; ++t_current ) {
|
||||
calc_bounding_sphere( counter, ¢er, &radius );
|
||||
fprintf(fp, "# usemtl desert1\n");
|
||||
fprintf(fp, "# bs %.2f %.2f %.2f %.2f\n",
|
||||
center.x(), center.y(), center.z(), radius);
|
||||
fprintf(fp, "f %d %d %d\n",
|
||||
t_current->get_n1(), t_current->get_n2(), t_current->get_n3());
|
||||
fprintf(fp, "\n");
|
||||
++counter;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.2 1999/03/23 22:02:03 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.1 1999/03/22 23:51:51 curt
|
||||
// Initial revision.
|
||||
//
|
||||
|
|
|
@ -32,38 +32,93 @@
|
|||
#endif
|
||||
|
||||
|
||||
#include <Math/fg_geodesy.hxx>
|
||||
#include <Math/point3d.hxx>
|
||||
#include <Triangulate/triangle.hxx>
|
||||
|
||||
|
||||
typedef vector < Point3D > wgs84_node_list;
|
||||
typedef wgs84_node_list::iterator wgs84_node_list_iterator;
|
||||
typedef wgs84_node_list::const_iterator const_wgs84_node_list_iterator;
|
||||
typedef vector < int > belongs_to;
|
||||
typedef belongs_to::iterator belongs_to_iterator;
|
||||
typedef belongs_to::const_iterator belongs_to_tripoly_iterator;
|
||||
|
||||
typedef vector < belongs_to > belongs_to_list;
|
||||
typedef belongs_to_list::iterator belongs_to_list_iterator;
|
||||
typedef belongs_to_list::const_iterator belongs_to_list_tripoly_iterator;
|
||||
|
||||
typedef vector < Point3D > normal_list;
|
||||
typedef normal_list::iterator normal_list_iterator;
|
||||
typedef normal_list::const_iterator const_normal_list_iterator;
|
||||
|
||||
class FGGenOutput {
|
||||
|
||||
private:
|
||||
|
||||
wgs84_node_list wgs84_nodes;
|
||||
normal_list normals;
|
||||
// node list in geodetic coordinats
|
||||
point_list geod_nodes;
|
||||
|
||||
// node list in cartesian coords (wgs84 model)
|
||||
point_list wgs84_nodes;
|
||||
|
||||
// face normal list (for flat shading)
|
||||
point_list face_normals;
|
||||
|
||||
// normal list (for each point) in cart coords (for smooth
|
||||
// shading)
|
||||
point_list point_normals;
|
||||
|
||||
// triangles (by index into point list)
|
||||
triele_list tri_elements;
|
||||
|
||||
// for each node, a list of triangle indices that contain this node
|
||||
belongs_to_list reverse_ele_lookup;
|
||||
|
||||
// global bounding sphere
|
||||
Point3D gbs_center;
|
||||
double gbs_radius;
|
||||
|
||||
// build the wgs-84 point list
|
||||
void gen_wgs84_points();
|
||||
|
||||
// build the node -> element (triangle) reverse lookup table.
|
||||
// there is an entry for each point containing a list of all the
|
||||
// triangles that share that point.
|
||||
void gen_node_ele_lookup_table();
|
||||
|
||||
// calculate the normals for each point in wgs84_nodes
|
||||
void gen_normals();
|
||||
|
||||
// build the face normal list
|
||||
void gen_face_normals();
|
||||
|
||||
// caclulate the normal for the specified triangle face
|
||||
Point3D calc_normal( int i );
|
||||
|
||||
// calculate the global bounding sphere. Center is the average of
|
||||
// the points.
|
||||
void calc_gbs();
|
||||
|
||||
// caclulate the bounding sphere for the specified triangle face
|
||||
void calc_bounding_sphere( int i, Point3D *center, double *radius );
|
||||
|
||||
public:
|
||||
|
||||
// Constructor && Destructor
|
||||
inline FGGenOutput() { }
|
||||
inline ~FGGenOutput() { }
|
||||
|
||||
// build the necessary output structures based on the
|
||||
// triangulation data
|
||||
int build( const FGTriangle& t );
|
||||
|
||||
// write out the fgfs scenery file
|
||||
int write( const string& path );
|
||||
};
|
||||
|
||||
|
||||
// generate the flight gear format from the triangulation
|
||||
int fgGenOutput( const FGTriangle& t );
|
||||
|
||||
|
||||
#endif // _GENOBJ_HXX
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.3 1999/03/23 22:02:04 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.2 1999/03/23 17:44:49 curt
|
||||
// Beginning work on generating output scenery.
|
||||
//
|
||||
|
|
|
@ -156,6 +156,13 @@ void do_triangulate( const FGArray& array, const FGClipper& clipper,
|
|||
}
|
||||
|
||||
|
||||
// generate the flight gear scenery file
|
||||
void do_output( const FGTriangle& t, FGGenOutput& output ) {
|
||||
output.build( t );
|
||||
output.write( "output" );
|
||||
}
|
||||
|
||||
|
||||
main(int argc, char **argv) {
|
||||
fitnode_list fit_list;
|
||||
double lon, lat;
|
||||
|
@ -188,11 +195,15 @@ main(int argc, char **argv) {
|
|||
do_triangulate( array, clipper, t );
|
||||
|
||||
// generate the output
|
||||
fgGenOutput( t );
|
||||
FGGenOutput output;
|
||||
do_output( t, output );
|
||||
}
|
||||
|
||||
|
||||
// $Log$
|
||||
// Revision 1.8 1999/03/23 22:02:17 curt
|
||||
// Worked on creating data to output ... normals, bounding spheres, etc.
|
||||
//
|
||||
// Revision 1.7 1999/03/22 23:48:29 curt
|
||||
// Added GenOutput/
|
||||
//
|
||||
|
|
Loading…
Add table
Reference in a new issue