From d5957b8c5f2188674eb6b3d480bd8eb70d253f79 Mon Sep 17 00:00:00 2001 From: Stuart Buchanan Date: Sat, 23 Nov 2019 17:05:20 +0000 Subject: [PATCH] Random Buildings - improved texture mapping Previously the front and side faces of random/OSM buildings had identical texture coordinates. This resulted in the sides of buildings texture mapping being squeezed or stretched. This change generates a separate texture mapping for the sides of the buildings. --- simgear/scene/tgdb/SGBuildingBin.cxx | 99 +++++++++++++++------------- simgear/scene/tgdb/SGBuildingBin.hxx | 4 +- 2 files changed, 54 insertions(+), 49 deletions(-) diff --git a/simgear/scene/tgdb/SGBuildingBin.cxx b/simgear/scene/tgdb/SGBuildingBin.cxx index 157dcccd..2208f1e8 100644 --- a/simgear/scene/tgdb/SGBuildingBin.cxx +++ b/simgear/scene/tgdb/SGBuildingBin.cxx @@ -83,7 +83,8 @@ struct MakeBuildingLeaf osg::Vec3Array* n = new osg::Vec3Array; osg::Vec4Array* c = new osg::Vec4Array; // Color array is used to identify the different building faces by the - // vertex shader for texture mapping. + // vertex shader for texture mapping: + // (front, roof, roof top vertex, side) v->reserve(52); t->reserve(52); @@ -174,7 +175,7 @@ struct MakeBuildingLeaf for (int i=0; i<4; ++i) { n->push_back( osg::Vec3(0, -1, 0) ); // normal - c->push_back( osg::Vec4(1, 0, 0, 0) ); // color - used to differentiate wall from roof + c->push_back( osg::Vec4(0, 0, 0, 1) ); // color - used to differentiate wall from roof } // Back face @@ -206,7 +207,7 @@ struct MakeBuildingLeaf for (int i=0; i<4; ++i) { n->push_back( osg::Vec3(0, 1, 0) ); // normal - c->push_back( osg::Vec4(1, 0, 0, 0) ); // color - used to differentiate wall from roof + c->push_back( osg::Vec4(0, 0, 0, 1) ); // color - used to differentiate wall from roof } // ROOF 1 - built as a block. The shader will deform it to the correct shape. @@ -369,9 +370,9 @@ struct AddBuildingLeafObject osg::Vec3Array* positions = static_cast (geom->getVertexAttribArray(BUILDING_POSITION_ATTR)); // (x,y,z) osg::Vec3Array* scale = static_cast (geom->getVertexAttribArray(BUILDING_SCALE_ATTR)); // (width, depth, height) - osg::Vec3Array* rot = static_cast (geom->getVertexAttribArray(BUILDING_ROT_PITCH_TEX0X_ATTR)); // (rotation, pitch height, wall texture x offset) - osg::Vec3Array* tex = static_cast (geom->getVertexAttribArray(BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR)); // (wall texture y offset, wall/roof texture x gain, wall/roof texture y gain) - osg::Vec3Array* rtex = static_cast (geom->getVertexAttribArray(BUILDING_RTEX0X_RTEX0Y_ATTR)); // (roof texture x offset, roof texture y offset, unused) + osg::Vec3Array* rot = static_cast (geom->getVertexAttribArray(BUILDING_ROT_PITCH_TEX0X_ATTR)); // (rotation, pitch height, wall texture x0) + osg::Vec3Array* tex = static_cast (geom->getVertexAttribArray(BUILDING_TEX0Y_TEX1X_TEX1Y_ATTR)); // (wall texture y0, front/roof texture x1, front/side/roof texture y1) + osg::Vec3Array* rtex = static_cast (geom->getVertexAttribArray(BUILDING_RTEX0X_RTEX0Y_ATTR)); // (roof texture x0, roof texture y0, side texture x1) osg::Vec3Array* rooftops = static_cast (geom->getVertexAttribArray(BUILDING_ROFFTOPSCALE_ATTR)); // (rooftop scale x, rooftop scale y, unused) positions->push_back(building.position); @@ -379,7 +380,7 @@ struct AddBuildingLeafObject scale->push_back(osg::Vec3f(building.depth, building.width, building.height)); rot->push_back(osg::Vec3f(building.rotation, building.pitch_height, building.walltex0.x())); tex->push_back(osg::Vec3f(building.walltex0.y(), building.tex1.x(), building.tex1.y())); - rtex->push_back(osg::Vec3f(building.rooftex0.x(), building.rooftex0.y(), 0.0f)); + rtex->push_back(osg::Vec3f(building.rooftex0.x(), building.rooftex0.y(), building.tex1.z())); rooftops->push_back(osg::Vec3f(building.rooftop_scale.x(), building.rooftop_scale.y(), 0.0f)); DrawArrays* primSet = static_cast(geom->getPrimitiveSet(0)); @@ -439,7 +440,7 @@ typedef QuadTreeBuilder 0.5f) || - (wall_offset_y + gain_y > (6.0f * 3.0f * BUILDING_TEXTURE_BLOCK_HEIGHT))) { - SG_LOG(SG_TERRAIN, SG_ALERT, "Small building texture coordinates out of bounds offset (" << wall_offset_x << ", " << wall_offset_y << ") gain (" << gain_x << ", " << gain_y << ")"); + if ((wall_x0 + wall_roof_x1 > 0.5f) || + (wall_y0 + y1 > (6.0f * 3.0f * BUILDING_TEXTURE_BLOCK_HEIGHT))) { + SG_LOG(SG_TERRAIN, SG_ALERT, "Small building texture coordinates out of bounds offset (" << wall_x0 << ", " << wall_y0 << ") gain (" << wall_roof_x1 << ", " << y1 << ")"); } - wall_tex0 = Vec2f(wall_offset_x, wall_offset_y); - roof_tex0 = Vec2f(roof_offset_x, roof_offset_y); - tex1 = Vec2f(gain_x, gain_y); + wall_tex0 = Vec2f(wall_x0, wall_y0); + roof_tex0 = Vec2f(roof_x0, roof_y0); + tex1 = Vec3f(wall_roof_x1, y1, side_x1); } else if (buildingtype == SGBuildingBin::MEDIUM) { // MEDIUM BUILDING // Maximum texture height is 8 stories. @@ -533,27 +536,28 @@ typedef QuadTreeBuilder 0.5f) || - (wall_offset_y + gain_y < (6.0f * 3.0f * BUILDING_TEXTURE_BLOCK_HEIGHT)) || - (wall_offset_y + gain_y > ((6.0f * 3.0f + 3.0f * 8.0f) * BUILDING_TEXTURE_BLOCK_HEIGHT))) { - SG_LOG(SG_TERRAIN, SG_ALERT, "Medium building texture coordinates out of bounds offset (" << wall_offset_x << ", " << wall_offset_y << ") gain (" << gain_x << ", " << gain_y << ")"); + if ((wall_x0 + wall_roof_x1 > 0.5f) || + (wall_y0 + y1 < (6.0f * 3.0f * BUILDING_TEXTURE_BLOCK_HEIGHT)) || + (wall_y0 + y1 > ((6.0f * 3.0f + 3.0f * 8.0f) * BUILDING_TEXTURE_BLOCK_HEIGHT))) { + SG_LOG(SG_TERRAIN, SG_ALERT, "Medium building texture coordinates out of bounds offset (" << wall_x0 << ", " << wall_y0 << ") gain (" << wall_roof_x1 << ", " << y1 << ")"); } - wall_tex0 = Vec2f(wall_offset_x, wall_offset_y); - roof_tex0 = Vec2f(roof_offset_x, roof_offset_y); - tex1 = Vec2f(gain_x, gain_y); + wall_tex0 = Vec2f(wall_x0, wall_y0); + roof_tex0 = Vec2f(roof_x0, roof_y0); + tex1 = Vec3f(wall_roof_x1, y1, side_x1); } else { // LARGE BUILDING // Maximum texture height is 22 stories. @@ -563,22 +567,23 @@ typedef QuadTreeBuilder 0.5f) || - (wall_offset_y + gain_y < ((6.0f * 3.0f + 3.0f * 8.0f) * BUILDING_TEXTURE_BLOCK_HEIGHT)) || - (wall_offset_y + gain_y > 1.0) ) { - SG_LOG(SG_TERRAIN, SG_ALERT, "Large building texture coordinates out of bounds offset (" << wall_offset_x << ", " << wall_offset_y << ") gain (" << gain_x << ", " << gain_y << ")"); + if ((wall_x0 + wall_roof_x1 > 0.5f) || + (wall_y0 + y1 < ((6.0f * 3.0f + 3.0f * 8.0f) * BUILDING_TEXTURE_BLOCK_HEIGHT)) || + (wall_y0 + y1 > 1.0) ) { + SG_LOG(SG_TERRAIN, SG_ALERT, "Large building texture coordinates out of bounds offset (" << wall_x0 << ", " << wall_y0 << ") gain (" << wall_roof_x1 << ", " << y1 << ")"); } - wall_tex0 = Vec2f(wall_offset_x, wall_offset_y); - roof_tex0 = Vec2f(roof_offset_x, roof_offset_y); - tex1 = Vec2f(gain_x, gain_y); + wall_tex0 = Vec2f(wall_x0, wall_y0); + roof_tex0 = Vec2f(roof_x0, roof_y0); + tex1 = Vec3f(wall_roof_x1, y1, side_x1); } // Build a scaling factor in the x,y axes for the top of the roof. This allows us to create gabled, hipped, pyramidal roofs. diff --git a/simgear/scene/tgdb/SGBuildingBin.hxx b/simgear/scene/tgdb/SGBuildingBin.hxx index d10d1c1d..6e99d45b 100644 --- a/simgear/scene/tgdb/SGBuildingBin.hxx +++ b/simgear/scene/tgdb/SGBuildingBin.hxx @@ -92,7 +92,7 @@ public: LARGE }; struct BuildingInstance { - BuildingInstance(Vec3f p, float w, float d, float h, float ph, float r, Vec2f wt0, Vec2f rt0, Vec2f t1, Vec2f rs) : + BuildingInstance(Vec3f p, float w, float d, float h, float ph, float r, Vec2f wt0, Vec2f rt0, Vec3f t1, Vec2f rs) : position(p), width(w), depth(d), @@ -128,7 +128,7 @@ public: Vec2f walltex0; Vec2f rooftex0; - Vec2f tex1; + Vec3f tex1; // Texture gains for the front, roof and sides Vec2f rooftop_scale;