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/MatrixTransform>
33 #include <osg/StateSet>
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>
42 // Generate an ocean tile
43 osg::Node* SGOceanTile(const SGBucket& b, SGMaterialLib *matlib)
45 osg::StateSet *stateSet = 0;
47 double tex_width = 1000.0;
49 // find Ocean material in the properties list
50 SGMaterial *mat = matlib->find( "Ocean" );
52 // set the texture width and height values for this
54 tex_width = mat->get_xsize();
57 stateSet = mat->get_state();
59 SG_LOG( SG_TERRAIN, SG_ALERT, "Ack! unknown use material name = Ocean");
62 // Calculate center point
63 SGVec3d cartCenter = SGVec3d::fromGeod(b.get_center());
64 Point3D center = Point3D(cartCenter[0], cartCenter[1], cartCenter[2]);
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();
71 // Caculate corner vertices
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 );
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));
87 // Calculate texture coordinates
88 point_list geod_nodes;
90 geod_nodes.reserve(4);
94 for ( i = 0; i < 4; ++i ) {
95 geod_nodes.push_back( Point3D::fromSGGeod(geod[i]) );
96 rectangle.push_back( i );
98 point_list texs = sgCalcTexCoords( b, geod_nodes, rectangle,
101 // Allocate ssg structure
102 osg::Vec3Array *vl = new osg::Vec3Array;
103 osg::Vec3Array *nl = new osg::Vec3Array;
104 osg::Vec2Array *tl = new osg::Vec2Array;
106 for ( i = 0; i < 4; ++i ) {
107 vl->push_back(rel[i].osg());
108 nl->push_back(normals[i].osg());
109 tl->push_back(texs[i].toSGVec2f().osg());
112 osg::Vec4Array* cl = new osg::Vec4Array;
113 cl->push_back(osg::Vec4(1, 1, 1, 1));
115 osg::Geometry* geometry = new osg::Geometry;
116 geometry->setVertexArray(vl);
117 geometry->setNormalArray(nl);
118 geometry->setNormalBinding(osg::Geometry::BIND_PER_VERTEX);
119 geometry->setColorArray(cl);
120 geometry->setColorBinding(osg::Geometry::BIND_OVERALL);
121 geometry->setTexCoordArray(0, tl);
122 osg::DrawArrays* drawArrays;
123 drawArrays = new osg::DrawArrays(GL_TRIANGLE_FAN, 0, vl->size());
124 geometry->addPrimitiveSet(drawArrays);
126 osg::Geode* geode = new osg::Geode;
127 geode->setName("Ocean tile");
128 geode->addDrawable(geometry);
129 geode->setStateSet(stateSet);
131 osg::MatrixTransform* transform = new osg::MatrixTransform;
132 transform->setName("Ocean");
133 transform->setMatrix(osg::Matrix::translate(cartCenter.osg()));
134 transform->addChild(geode);