]> git.mxchange.org Git - simgear.git/blob - simgear/scene/tgdb/SGOceanTile.cxx
911553f3166491dee64776964284f580f906ef94
[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/MatrixTransform>
33 #include <osg/StateSet>
34
35 #include <simgear/bucket/newbucket.hxx>
36 #include <simgear/math/sg_geodesy.hxx>
37 #include <simgear/math/sg_types.hxx>
38 #include <simgear/misc/texcoord.hxx>
39 #include <simgear/scene/material/mat.hxx>
40 #include <simgear/scene/material/matlib.hxx>
41
42 // Generate an ocean tile
43 osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
44 {
45   osg::StateSet *stateSet = 0;
46
47   double tex_width = 1000.0;
48   
49   // find Ocean material in the properties list
50   SGMaterial *mat = matlib->find( "Ocean" );
51   if ( mat != NULL ) {
52     // set the texture width and height values for this
53     // material
54     tex_width = mat->get_xsize();
55     
56     // set ssgState
57     stateSet = mat->get_state();
58   } else {
59     SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
60   }
61   
62   // Calculate center point
63   SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
64   Point3D center = Point3D(cartCenter[0], cartCenter[1], cartCenter[2]);
65   
66   double clon = b.get_center_lon();
67   double clat = b.get_center_lat();
68   double height = b.get_height();
69   double width = b.get_width();
70   
71   // Caculate corner vertices
72   SGGeod geod[4];
73   geod[0] = SGGeod::fromDeg( clon - 0.5*width, clat - 0.5*height );
74   geod[1] = SGGeod::fromDeg( clon + 0.5*width, clat - 0.5*height );
75   geod[2] = SGGeod::fromDeg( clon + 0.5*width, clat + 0.5*height );
76   geod[3] = SGGeod::fromDeg( clon - 0.5*width, clat + 0.5*height );
77   
78   int i;
79   SGVec3f normals[4];
80   SGVec3d rel[4];
81   for ( i = 0; i < 4; ++i ) {
82     SGVec3d cart = SGVec3d::fromGeod(geod[i]);
83     rel[i] = cart - center.toSGVec3d();
84     normals[i] = toVec3f(normalize(cart));
85   }
86   
87   // Calculate texture coordinates
88   point_list geod_nodes;
89   geod_nodes.clear();
90   geod_nodes.reserve(4);
91   int_list rectangle;
92   rectangle.clear();
93   rectangle.reserve(4);
94   for ( i = 0; i < 4; ++i ) {
95     geod_nodes.push_back(Point3D(geod[i].getLongitudeDeg(),
96                                  geod[i].getLatitudeDeg(),
97                                  geod[i].getElevationM()));
98     rectangle.push_back( i );
99   }
100   point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle, 
101                                      1000.0 / tex_width );
102   
103   // Allocate ssg structure
104   osg::Vec3Array *vl = new osg::Vec3Array;
105   osg::Vec3Array *nl = new osg::Vec3Array;
106   osg::Vec2Array *tl = new osg::Vec2Array;
107   
108   for ( i = 0; i < 4; ++i ) {
109     vl->push_back(rel[i].osg());
110     nl->push_back(normals[i].osg());
111     tl->push_back(texs[i].toSGVec2f().osg());
112   }
113   
114   osg::Vec4Array* cl = new osg::Vec4Array;
115   cl->push_back(osg::Vec4(1, 1, 1, 1));
116   
117   osg::Geometry* geometry = new osg::Geometry;
118   geometry->setVertexArray(vl);
119   geometry->setNormalArray(nl);
120   geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
121   geometry->setColorArray(cl);
122   geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
123   geometry->setTexCoordArray(0, tl);
124   osg::DrawArrays* drawArrays;
125   drawArrays = new osg::DrawArrays(GL_TRIANGLE_FAN, 0, vl->size());
126   geometry->addPrimitiveSet(drawArrays);
127
128   osg::Geode* geode = new osg::Geode;
129   geode->setName("Ocean tile");
130   geode->addDrawable(geometry);
131   geode->setStateSet(stateSet);
132
133   osg::MatrixTransform* transform = new osg::MatrixTransform;
134   transform->setName("Ocean");
135   transform->setMatrix(osg::Matrix::translate(cartCenter.osg()));
136   transform->addChild(geode);
137   
138   return transform;
139 }