diff --git a/src/display3d.cpp b/src/display3d.cpp index 680be0dfb95..ce969dd51ae 100644 --- a/src/display3d.cpp +++ b/src/display3d.cpp @@ -2479,12 +2479,17 @@ void renderFeature(FEATURE *psFeature, const glm::mat4 &viewMatrix, const glm::m /* these cast a shadow */ pieFlags = pie_SHADOW; } + float stretchDepth = 0.f; + if (psFeature->psStats->subType == FEAT_TREE) + { + stretchDepth = psFeature->pos.z - psFeature->foundationDepth; + } iIMDBaseShape *imd = psFeature->sDisplay.imd; if (imd) { /* Translate the feature - N.B. We can also do rotations here should we require buildings to face different ways - Don't know if this is necessary - should be IMO */ - pie_Draw3DShape(imd->displayModel(), 0, 0, brightness, pieFlags, 0, modelMatrix, viewMatrix); + pie_Draw3DShape(imd->displayModel(), 0, 0, brightness, pieFlags, 0, modelMatrix, viewMatrix, stretchDepth); } setScreenDispWithPerspective(&psFeature->sDisplay, perspectiveViewMatrix * modelMatrix); diff --git a/src/feature.cpp b/src/feature.cpp index 58f748a5e4f..0653a17a739 100644 --- a/src/feature.cpp +++ b/src/feature.cpp @@ -202,16 +202,11 @@ static void updateFeatureOrientation(FEATURE *psFeature) psFeature->pos.z = MAX(psFeature->pos.z, (hx0 + hx1) / 2); psFeature->pos.z = MAX(psFeature->pos.z, (hy0 + hy1) / 2); - if (psFeature->psStats->subType == FEAT_TREE) + if (psFeature->psStats->subType == FEAT_TREE || + psFeature->psStats->subType == FEAT_SKYSCRAPER || + psFeature->psStats->subType == FEAT_BUILDING) { - // Do not rotate or pitch - trees look weird if they aren't pointing up - // FUTURE TODO: Ensure that no tree geometry is hovering above the terrain when placed on an aggressive slope, while still ensuring it points up, by burying the base a bit if needed? - return; - } - if (psFeature->psStats->subType == FEAT_SKYSCRAPER) - { - // Do not rotate or pitch - skyscrapers should also point up - // FUTURE TODO: Possibly stretch the base of the skyscraper if needed? + // Do not rotate or pitch - trees + buildings look weird if they aren't pointing up return; } @@ -235,7 +230,6 @@ static void updateFeatureOrientation(FEATURE *psFeature) psFeature->rot.roll = iAtan2(dzdw, (2 * d) << 16); // pitch = atan(∂z(x, y)/∂w)/2π << 16 } - /* Create a feature on the map */ FEATURE *buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y, bool FromSave, uint32_t id) { @@ -296,6 +290,7 @@ FEATURE *buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y, bool FromSave, psFeature->body = psStats->body; psFeature->periodicalDamageStart = 0; psFeature->periodicalDamage = 0; + psFeature->foundationDepth = std::min(foundationMin, TILE_MAX_HEIGHT); // it has never been drawn psFeature->sDisplay.frameNumber = 0; @@ -361,6 +356,7 @@ FEATURE *buildFeature(FEATURE_STATS *psStats, UDWORD x, UDWORD y, bool FromSave, FEATURE::FEATURE(uint32_t id, FEATURE_STATS const *psStats) : BASE_OBJECT(OBJ_FEATURE, id, PLAYER_FEATURE) // Set the default player out of range to avoid targeting confusions , psStats(psStats) + , foundationDepth(0.f) {} /* Release the resources associated with a feature */ diff --git a/src/featuredef.h b/src/featuredef.h index 55bfc2bfd27..58e54a88bfb 100644 --- a/src/featuredef.h +++ b/src/featuredef.h @@ -70,6 +70,7 @@ struct FEATURE : public BASE_OBJECT ~FEATURE(); FEATURE_STATS const *psStats; + float foundationDepth; ///< Depth of features's foundation // DISPLAY-ONLY inline Vector2i size() const { return psStats->size(); } };