]> git.mxchange.org Git - simgear.git/blob - simgear/scene/tgdb/SGOceanTile.cxx
017436ea9a9a4f2183acb24c31fc68d85f3e2976
[simgear.git] / simgear / scene / tgdb / SGOceanTile.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2006-2007 Mathias Froehlich 
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include <simgear_config.h>
24 #endif
25
26 #include "SGOceanTile.hxx"
27
28 #include <simgear/compiler.h>
29
30 #include <osg/Geode>
31 #include <osg/Geometry>
32 #include <osg/StateSet>
33
34 #include <simgear/bucket/newbucket.hxx>
35 #include <simgear/math/sg_geodesy.hxx>
36 #include <simgear/math/sg_types.hxx>
37 #include <simgear/misc/texcoord.hxx>
38 #include <simgear/scene/material/mat.hxx>
39 #include <simgear/scene/material/matlib.hxx>
40
41 // Generate an ocean tile
42 osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
43 {
44   osg::StateSet *stateSet = 0;
45
46   double tex_width = 1000.0;
47   
48   // find Ocean material in the properties list
49   SGMaterial *mat = matlib->find( "Ocean" );
50   if ( mat != NULL ) {
51     // set the texture width and height values for this
52     // material
53     tex_width = mat->get_xsize();
54     
55     // set ssgState
56     stateSet = mat->get_state();
57   } else {
58     SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
59   }
60   
61   // Calculate center point
62   SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
63   Point3D center = Point3D(cartCenter[0], cartCenter[1], cartCenter[2]);
64   
65   double clon = b.get_center_lon();
66   double clat = b.get_center_lat();
67   double height = b.get_height();
68   double width = b.get_width();
69   
70   // Caculate corner vertices
71   SGGeod geod[4];
72   geod[0] = SGGeod::fromDeg( clon - 0.5*width, clat - 0.5*height );
73   geod[1] = SGGeod::fromDeg( clon + 0.5*width, clat - 0.5*height );
74   geod[2] = SGGeod::fromDeg( clon + 0.5*width, clat + 0.5*height );
75   geod[3] = SGGeod::fromDeg( clon - 0.5*width, clat + 0.5*height );
76   
77   int i;
78   SGVec3f normals[4];
79   SGVec3d rel[4];
80   for ( i = 0; i < 4; ++i ) {
81     SGVec3d cart = SGVec3d::fromGeod(geod[i]);
82     rel[i] = cart - center.toSGVec3d();
83     normals[i] = toVec3f(normalize(cart));
84   }
85   
86   // Calculate texture coordinates
87   point_list geod_nodes;
88   geod_nodes.clear();
89   geod_nodes.reserve(4);
90   int_list rectangle;
91   rectangle.clear();
92   rectangle.reserve(4);
93   for ( i = 0; i < 4; ++i ) {
94     geod_nodes.push_back( Point3D::fromSGGeod(geod[i]) );
95     rectangle.push_back( i );
96   }
97   point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle, 
98                                      1000.0 / tex_width );
99   
100   // Allocate ssg structure
101   osg::Vec3Array *vl = new osg::Vec3Array;
102   osg::Vec3Array *nl = new osg::Vec3Array;
103   osg::Vec2Array *tl = new osg::Vec2Array;
104   
105   for ( i = 0; i < 4; ++i ) {
106     vl->push_back(rel[i].osg());
107     nl->push_back(normals[i].osg());
108     tl->push_back(texs[i].toSGVec2f().osg());
109   }
110   
111   osg::Vec4Array* cl = new osg::Vec4Array;
112   cl->push_back(osg::Vec4(1, 1, 1, 1));
113   
114   osg::Geometry* geometry = new osg::Geometry;
115   geometry->setVertexArray(vl);
116   geometry->setNormalArray(nl);
117   geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
118   geometry->setColorArray(cl);
119   geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
120   geometry->setTexCoordArray(0, tl);
121   osg::DrawArrays* drawArrays;
122   drawArrays = new osg::DrawArrays(GL_TRIANGLE_FAN, 0, vl->size());
123   geometry->addPrimitiveSet(drawArrays);
124
125   osg::Geode* geode = new osg::Geode;
126   geode->setName("Ocean tile");
127   geode->addDrawable(geometry);
128   geode->setStateSet(stateSet);
129   
130   return geode;
131 }