3 * Copyright (C) 2006-2007 Mathias Froehlich
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.
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.
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,
23 # include <simgear_config.h>
26 #include "SGOceanTile.hxx"
28 #include <simgear/compiler.h>
31 #include <osg/Geometry>
32 #include <osg/StateSet>
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>
41 // Generate an ocean tile
42 osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
44 osg::StateSet *stateSet = 0;
46 double tex_width = 1000.0;
48 // find Ocean material in the properties list
49 SGMaterial *mat = matlib->find( "Ocean" );
51 // set the texture width and height values for this
53 tex_width = mat->get_xsize();
56 stateSet = mat->get_state();
58 SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
61 // Calculate center point
62 SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
63 Point3D center = Point3D(cartCenter[0], cartCenter[1], cartCenter[2]);
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();
70 // Caculate corner vertices
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 );
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));
86 // Calculate texture coordinates
87 point_list geod_nodes;
89 geod_nodes.reserve(4);
93 for ( i = 0; i < 4; ++i ) {
94 geod_nodes.push_back( Point3D::fromSGGeod(geod[i]) );
95 rectangle.push_back( i );
97 point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle,
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;
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());
111 osg::Vec4Array* cl = new osg::Vec4Array;
112 cl->push_back(osg::Vec4(1, 1, 1, 1));
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);
125 osg::Geode* geode = new osg::Geode;
126 geode->setName("Ocean tile");
127 geode->addDrawable(geometry);
128 geode->setStateSet(stateSet);