1 /* -*-c++-*- 2 * 3 * Copyright (C) 2011 Stuart Buchanan 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 #ifndef SG_BUILDING_BIN_HXX 23 #define SG_BUILDING_BIN_HXX 24 25 #include <math.h> 26 27 #include <vector> 28 #include <string> 29 30 #include <osg/Geode> 31 #include <osg/Geometry> 32 #include <osg/Math> 33 #include <osg/MatrixTransform> 34 #include <osg/Matrix> 35 #include <osg/ShadeModel> 36 #include <osg/Material> 37 #include <osg/CullFace> 38 #include <osg/VertexAttribDivisor> 39 40 #include <simgear/scene/util/OsgMath.hxx> 41 #include <simgear/scene/material/mat.hxx> 42 43 #include <simgear/scene/material/Effect.hxx> 44 #include <simgear/scene/material/EffectGeode.hxx> 45 46 #include <simgear/scene/util/QuadTreeBuilder.hxx> 47 #include <simgear/scene/util/RenderConstants.hxx> 48 #include <simgear/scene/util/StateAttributeFactory.hxx> 49 #include <simgear/structure/OSGUtils.hxx> 50 51 #define SG_BUILDING_QUAD_TREE_DEPTH 2 52 #define SG_BUILDING_FADE_OUT_LEVELS 4 53 54 // these correspond to building.eff 55 const int BUILDING_POSITION_ATTR = 10; // (x,y,z) 56 const int BUILDING_SCALE_ATTR = 11; // (width, depth, height) 57 const int BUILDING_ATTR1 = 12; 58 const int BUILDING_ATTR2 = 13; 59 const int BUILDING_ATTR3 = 14; 60 const int BUILDING_ATTR4 = 15; 61 62 using namespace osg; 63 64 namespace simgear 65 { 66 67 struct BuildingBoundingBoxCallback : public Drawable::ComputeBoundingBoxCallback 68 { BuildingBoundingBoxCallbacksimgear::BuildingBoundingBoxCallback69 BuildingBoundingBoxCallback() {} BuildingBoundingBoxCallbacksimgear::BuildingBoundingBoxCallback70 BuildingBoundingBoxCallback(const BuildingBoundingBoxCallback&, const CopyOp&) {} 71 META_Object(simgear, BuildingBoundingBoxCallback); computeBoundsimgear::BuildingBoundingBoxCallback72 virtual BoundingBox computeBound(const Drawable& drawable) const 73 { 74 BoundingBox bb; 75 const Geometry* geom = static_cast<const Geometry*>(&drawable); 76 const Vec3Array* pos = static_cast<const Vec3Array*>(geom->getVertexAttribArray(BUILDING_POSITION_ATTR)); 77 78 for (unsigned int v=0; v<pos->size(); ++v) { 79 Vec3 pt = (*pos)[v]; 80 bb.expandBy(pt); 81 } 82 return bb; 83 } 84 }; 85 86 class SGBuildingBin { 87 public: 88 89 enum BuildingType { 90 SMALL = 0, 91 MEDIUM, 92 LARGE }; 93 94 struct BuildingInstance { BuildingInstancesimgear::SGBuildingBin::BuildingInstance95 BuildingInstance(Vec3f p, float w, float d, float h, float ph, float r, Vec2f wt0, Vec2f rt0, Vec3f t1, Vec2f rs) : 96 position(p), 97 width(w), 98 depth(d), 99 height(h), 100 pitch_height(ph), 101 rotation(r), 102 walltex0(wt0), 103 rooftex0(rt0), 104 tex1(t1), 105 rooftop_scale(rs) 106 { } 107 BuildingInstancesimgear::SGBuildingBin::BuildingInstance108 BuildingInstance(Vec3f p, BuildingInstance b) : 109 position(p), 110 width(b.width), 111 depth(b.depth), 112 height(b.height), 113 pitch_height(b.pitch_height), 114 rotation(b.rotation), 115 walltex0(b.walltex0), 116 rooftex0(b.rooftex0), 117 tex1(b.tex1), 118 rooftop_scale(b.rooftop_scale) 119 { } 120 121 122 Vec3f position; 123 float width; 124 float depth; 125 float height; 126 float pitch_height; 127 float rotation; 128 129 Vec2f walltex0; 130 Vec2f rooftex0; 131 Vec3f tex1; // Texture gains for the front, roof and sides 132 133 Vec2f rooftop_scale; 134 135 // References to allow the QuadTreeBuilder to work 136 //const BuildingList* buildingList; 137 //ref_ptr<Geometry> sharedGeometry; 138 getPositionsimgear::SGBuildingBin::BuildingInstance139 Vec3f getPosition() { return position; } getRotationsimgear::SGBuildingBin::BuildingInstance140 float getRotation() { return rotation; } 141 getDistSqrsimgear::SGBuildingBin::BuildingInstance142 float getDistSqr(Vec3f p) { 143 return (p - position) * (p - position); 144 } 145 }; 146 147 private: 148 const SGSharedPtr<SGMaterial> _material; 149 150 std::string _materialName; 151 std::string _textureName; 152 std::string _lightMapName; 153 154 // Visibility range for buildings 155 float buildingRange; 156 157 158 // Information for an instance of a building - position and orientation 159 typedef std::vector<BuildingInstance> BuildingInstanceList; 160 BuildingInstanceList buildingLocations; 161 162 public: 163 164 SGBuildingBin(const SGMaterial *mat, bool useVBOs); 165 SGBuildingBin(const SGPath& absoluteFileName, const SGMaterial *mat, bool useVBOs); 166 167 ~SGBuildingBin(); 168 169 // Generate a building specifying the exact position, dimensions and texture index. 170 void insert(SGVec3f p, 171 float r, 172 BuildingType buildingtype, 173 float width, 174 float depth, 175 float height, 176 float pitch_height, 177 int floors, 178 int roof_shape, 179 int roof_orientation, 180 int wall_tex_index, 181 int roof_tex_index); 182 183 // Generate a building of a given type at a specified position, using the random building material definition to determine the dimensions and texture index. 184 void insert(SGVec3f p, float r, BuildingType type); 185 int getNumBuildings(); 186 187 bool checkMinDist (SGVec3f p, float radius); 188 getMaterialName() const189 const std::string& getMaterialName() const { return _materialName; } 190 191 BuildingType getBuildingType(float roll); 192 float getBuildingMaxRadius(BuildingType); 193 float getBuildingMaxDepth(BuildingType); 194 195 ref_ptr<Group> createBuildingsGroup(Matrix transInv, const SGReaderWriterOptions* options); 196 197 }; 198 199 // List of buildings 200 typedef std::list<SGBuildingBin*> SGBuildingBinList; 201 202 203 osg::Group* createRandomBuildings(SGBuildingBinList& buildinglist, const osg::Matrix& transform, 204 const SGReaderWriterOptions* options); 205 } 206 #endif 207