diff --git a/gui_qt/formtextures.cpp b/gui_qt/formtextures.cpp index 4e1a3c4..ed039e6 100644 --- a/gui_qt/formtextures.cpp +++ b/gui_qt/formtextures.cpp @@ -7,6 +7,19 @@ static TexturesDefinition _definition; static TextureLayerDefinition _layer; +typedef struct +{ + double height_soft_min; + double height_hard_min; + double height_hard_max; + double height_soft_max; + double slope_soft_min; + double slope_hard_min; + double slope_hard_max; + double slope_soft_max; +} TextureSupp; +static TextureSupp _supp; + /**************** Previews ****************/ class PreviewTexturesCoverage:public BasePreview { @@ -119,6 +132,15 @@ FormTextures::FormTextures(QWidget *parent): addInputDouble(tr("Light reflection"), &_layer.material.reflection, 0.0, 1.0, 0.01, 0.1); addInputDouble(tr("Light reflection shininess"), &_layer.material.shininess, 0.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Hard minimal height"), &_supp.height_hard_min, -20.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Soft minimal height"), &_supp.height_soft_min, -20.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Soft maximal height"), &_supp.height_soft_max, -20.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Hard maximal height"), &_supp.height_hard_max, -20.0, 20.0, 0.1, 1.0); + addInputDouble(tr("Hard minimal slope"), &_supp.slope_hard_min, 0.0, 5.0, 0.05, 0.5); + addInputDouble(tr("Soft minimal slope"), &_supp.slope_soft_min, 0.0, 5.0, 0.05, 0.5); + addInputDouble(tr("Soft maximal slope"), &_supp.slope_soft_max, 0.0, 5.0, 0.05, 0.5); + addInputDouble(tr("Hard maximal slope"), &_supp.slope_hard_max, 0.0, 5.0, 0.05, 0.5); + revertConfig(); } @@ -137,7 +159,29 @@ void FormTextures::applyConfig() void FormTextures::configChangeEvent() { + ZoneRangeCondition range; + texturesLayerCopyDefinition(&_layer, texturesGetLayer(&_definition, currentLayer())); + + if (zoneGetHeightRangeCount(_layer.zone) > 0) + { + range.value = 1.0; + range.softmin = _supp.height_soft_min; + range.hardmin = _supp.height_hard_min; + range.hardmax = _supp.height_hard_max; + range.softmax = _supp.height_soft_max; + zoneSetHeightRange(_layer.zone, 0, &range); + } + if (zoneGetSlopeRangeCount(_layer.zone) > 0) + { + range.value = 1.0; + range.softmin = _supp.slope_soft_min; + range.hardmin = _supp.slope_hard_min; + range.hardmax = _supp.slope_hard_max; + range.softmax = _supp.slope_soft_max; + zoneSetSlopeRange(_layer.zone, 0, &range); + } + texturesValidateDefinition(&_definition); BaseForm::configChangeEvent(); } @@ -159,7 +203,29 @@ void FormTextures::layerDeletedEvent(int layer) void FormTextures::layerSelectedEvent(int layer) { + ZoneRangeCondition range; + texturesLayerCopyDefinition(texturesGetLayer(&_definition, layer), &_layer); + if (zoneGetHeightRangeCount(_layer.zone) == 0) + { + zoneAddHeightRange(_layer.zone); + } + zoneGetHeightRange(_layer.zone, 0, &range); + _supp.height_soft_min = range.softmin; + _supp.height_hard_min = range.hardmin; + _supp.height_hard_max = range.hardmax; + _supp.height_soft_max = range.softmax; + + if (zoneGetSlopeRangeCount(_layer.zone) == 0) + { + zoneAddSlopeRange(_layer.zone); + } + zoneGetSlopeRange(_layer.zone, 0, &range); + _supp.slope_soft_min = range.softmin; + _supp.slope_hard_min = range.hardmin; + _supp.slope_hard_max = range.hardmax; + _supp.slope_soft_max = range.softmax; + BaseForm::layerSelectedEvent(layer); } diff --git a/gui_qt/inputdouble.cpp b/gui_qt/inputdouble.cpp index 47c6579..c4ba377 100644 --- a/gui_qt/inputdouble.cpp +++ b/gui_qt/inputdouble.cpp @@ -10,7 +10,7 @@ InputDouble::InputDouble(QWidget* form, QString label, double* value, double min slider = new QSlider(form); slider->setOrientation(Qt::Horizontal); - slider->setMinimumWidth(150); + slider->setMinimumWidth(200); slider->setMaximumWidth(400); slider->setMinimum(0); diff --git a/i18n/paysages_fr.ts b/i18n/paysages_fr.ts index 11dd933..2865165 100644 --- a/i18n/paysages_fr.ts +++ b/i18n/paysages_fr.ts @@ -477,7 +477,7 @@ Maintenir Ctrl : Plus rapide FormTextures - + Coverage preview Aperçu de la couverture @@ -486,40 +486,80 @@ Maintenir Ctrl : Plus rapide Rendu en couleur - + Lighted sample Echantillon éclairé - + Surface noise Bruit de surface - + Surface noise height Hauteur du bruit - + Surface noise scaling Echelle du bruit - + Base color Couleur de base - + Light reflection Réflexion de lumière - + Light reflection shininess Concentration de la réflexion de lumière + + + Soft minimal height + Altitude minimal (adoucie) + + + + Hard minimal height + Altitude minimale + + + + Hard maximal height + Altitude maximale + + + + Soft maximal height + Altitude maximale (adoucie) + + + + Soft minimal slope + Pente minimale (adoucie) + + + + Hard minimal slope + Pente minimale + + + + Hard maximal slope + Pente maximale + + + + Soft maximal slope + Pente maximale (adoucie) + FormWater @@ -761,7 +801,7 @@ Maintenir Ctrl : Plus rapide Credits : Programming - Michael Lemaire - Un logiciel d'édition et rendu de décors naturels en 3D + Un logiciel d'édition et rendu de décors naturels en 3D Crédits : Développement - Michaël LEMAIRE diff --git a/lib_paysages/auto.c b/lib_paysages/auto.c index ec33ec7..c8191c8 100644 --- a/lib_paysages/auto.c +++ b/lib_paysages/auto.c @@ -66,8 +66,6 @@ void autoGenRealisticLandscape(int seed) TexturesDefinition textures; TextureLayerDefinition* texture; LightingDefinition lighting; - HeightModifier* mod; - Zone* zone; if (!seed) { @@ -144,32 +142,14 @@ void autoGenRealisticLandscape(int seed) noiseAddLevelsSimple(terrain.height_noise, 10, 1.0, 1.0); terrain.height_factor = 12.0 / noiseGetMaxValue(terrain.height_noise); terrain.scaling = 10.0; - /* DEBUG */ - mod = modifierCreate(); - zone = modifierGetZone(mod); - zoneIncludeCircleArea(zone, 0.4, 0.0, 0.0, 8.0, 20.0); - modifierActionFixValue(mod, -2.0); - terrainAddModifier(&terrain, mod); - modifierDelete(mod); - mod = modifierCreate(); - zone = modifierGetZone(mod); - zoneIncludeCircleArea(zone, 1.0, 0.0, 0.0, 0.3, 8.0); - modifierActionAddValue(mod, 8.0); - terrainAddModifier(&terrain, mod); - modifierDelete(mod); - mod = modifierCreate(); - zone = modifierGetZone(mod); - zoneIncludeCircleArea(zone, 0.8, 0.0, 0.0, 0.3, 4.0); - modifierActionFixValue(mod, -8.0); - terrainAddModifier(&terrain, mod); - modifierDelete(mod); - /* DEBUG */ scenerySetTerrain(&terrain); terrainDeleteDefinition(&terrain); /* Textures */ textures = texturesCreateDefinition(); texture = texturesGetLayer(&textures, texturesAddLayer(&textures)); + zoneAddHeightRangeQuick(texture->zone, 1.0, -20.0, -20.0, 20.0, 20.0); + zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 5.0, 5.0); noiseGenerateBaseNoise(texture->bump_noise, 102400); noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 1.0); texture->bump_height = 0.1; @@ -180,8 +160,8 @@ void autoGenRealisticLandscape(int seed) texture->material.reflection = 0.2; texture->material.shininess = 3.0; texture = texturesGetLayer(&textures, texturesAddLayer(&textures)); - zoneAddHeightRange(texture->zone, 1.0, -1.0, 0.0, 3.0, 15.0); - zoneAddSteepnessRange(texture->zone, 1.0, 0.0, 0.0, 0.2, 0.3); + zoneAddHeightRangeQuick(texture->zone, 1.0, -1.0, 0.0, 3.0, 15.0); + zoneAddSlopeRangeQuick(texture->zone, 1.0, 0.0, 0.0, 0.2, 0.3); noiseGenerateBaseNoise(texture->bump_noise, 102400); noiseAddLevelsSimple(texture->bump_noise, 6, 1.0, 0.4); texture->bump_height = 0.02; diff --git a/lib_paysages/zone.c b/lib_paysages/zone.c index 5c281b5..af14a63 100644 --- a/lib_paysages/zone.c +++ b/lib_paysages/zone.c @@ -7,15 +7,6 @@ #define MAX_RANGES 20 #define MAX_CIRCLES 20 -typedef struct -{ - double value; - double hardmin; - double softmin; - double softmax; - double hardmax; -} Range; - typedef struct { double value; @@ -26,11 +17,11 @@ typedef struct } Circle; struct Zone { - Range height_ranges[MAX_RANGES]; + ZoneRangeCondition height_ranges[MAX_RANGES]; int height_ranges_count; - Range steepness_ranges[MAX_RANGES]; - int steepness_ranges_count; + ZoneRangeCondition slope_ranges[MAX_RANGES]; + int slope_ranges_count; Circle circles_included[MAX_CIRCLES]; int circles_included_count; @@ -45,7 +36,7 @@ Zone* zoneCreate() result = (Zone*)malloc(sizeof(Zone)); result->height_ranges_count = 0; - result->steepness_ranges_count = 0; + result->slope_ranges_count = 0; result->circles_included_count = 0; result->circles_excluded_count = 0; @@ -71,14 +62,14 @@ void zoneSave(FILE* f, Zone* zone) toolsSaveDouble(f, &zone->height_ranges[i].hardmax); } - toolsSaveInt(f, &zone->steepness_ranges_count); - for (i = 0; i < zone->steepness_ranges_count; i++) + toolsSaveInt(f, &zone->slope_ranges_count); + for (i = 0; i < zone->slope_ranges_count; i++) { - toolsSaveDouble(f, &zone->steepness_ranges[i].value); - toolsSaveDouble(f, &zone->steepness_ranges[i].hardmin); - toolsSaveDouble(f, &zone->steepness_ranges[i].softmin); - toolsSaveDouble(f, &zone->steepness_ranges[i].softmax); - toolsSaveDouble(f, &zone->steepness_ranges[i].hardmax); + toolsSaveDouble(f, &zone->slope_ranges[i].value); + toolsSaveDouble(f, &zone->slope_ranges[i].hardmin); + toolsSaveDouble(f, &zone->slope_ranges[i].softmin); + toolsSaveDouble(f, &zone->slope_ranges[i].softmax); + toolsSaveDouble(f, &zone->slope_ranges[i].hardmax); } toolsSaveInt(f, &zone->circles_included_count); @@ -116,14 +107,14 @@ void zoneLoad(FILE* f, Zone* zone) toolsLoadDouble(f, &zone->height_ranges[i].hardmax); } - toolsLoadInt(f, &zone->steepness_ranges_count); - for (i = 0; i < zone->steepness_ranges_count; i++) + toolsLoadInt(f, &zone->slope_ranges_count); + for (i = 0; i < zone->slope_ranges_count; i++) { - toolsLoadDouble(f, &zone->steepness_ranges[i].value); - toolsLoadDouble(f, &zone->steepness_ranges[i].hardmin); - toolsLoadDouble(f, &zone->steepness_ranges[i].softmin); - toolsLoadDouble(f, &zone->steepness_ranges[i].softmax); - toolsLoadDouble(f, &zone->steepness_ranges[i].hardmax); + toolsLoadDouble(f, &zone->slope_ranges[i].value); + toolsLoadDouble(f, &zone->slope_ranges[i].hardmin); + toolsLoadDouble(f, &zone->slope_ranges[i].softmin); + toolsLoadDouble(f, &zone->slope_ranges[i].softmax); + toolsLoadDouble(f, &zone->slope_ranges[i].hardmax); } toolsLoadInt(f, &zone->circles_included_count); @@ -167,27 +158,129 @@ void zoneExcludeCircleArea(Zone* zone, double centerx, double centerz, double so /* TODO */ } -void zoneAddHeightRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax) +int zoneAddHeightRange(Zone* zone) { - Range range = {value, hardmin, softmin, softmax, hardmax}; - if (zone->height_ranges_count < MAX_RANGES) { - zone->height_ranges[zone->height_ranges_count++] = range; + zone->height_ranges[zone->height_ranges_count].value = 0.0; + zone->height_ranges[zone->height_ranges_count].softmin = 0.0; + zone->height_ranges[zone->height_ranges_count].hardmin = 0.0; + zone->height_ranges[zone->height_ranges_count].hardmax = 0.0; + zone->height_ranges[zone->height_ranges_count].softmax = 0.0; + return zone->height_ranges_count++; } -} - -void zoneAddSteepnessRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax) -{ - Range range = {value, hardmin, softmin, softmax, hardmax}; - - if (zone->steepness_ranges_count < MAX_RANGES) + else { - zone->steepness_ranges[zone->steepness_ranges_count++] = range; + return -1; } } -static inline double _getRangeInfluence(Range range, double position) +int zoneGetHeightRangeCount(Zone* zone) +{ + return zone->height_ranges_count; +} + +int zoneGetHeightRange(Zone* zone, int position, ZoneRangeCondition* range) +{ + if (position >= 0 && position < zone->height_ranges_count) + { + *range = zone->height_ranges[position]; + return 1; + } + else + { + return 0; + } +} + +int zoneSetHeightRange(Zone* zone, int position, ZoneRangeCondition* range) +{ + if (position >= 0 && position < zone->height_ranges_count) + { + zone->height_ranges[position] = *range; + return 1; + } + else + { + return 0; + } +} + +int zoneAddHeightRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax) +{ + ZoneRangeCondition range = {value, hardmin, softmin, softmax, hardmax}; + int position; + + position = zoneAddHeightRange(zone); + if (position >= 0) + { + zoneSetHeightRange(zone, position, &range); + } + return position; +} + +int zoneAddSlopeRange(Zone* zone) +{ + if (zone->slope_ranges_count < MAX_RANGES) + { + zone->slope_ranges[zone->slope_ranges_count].value = 0.0; + zone->slope_ranges[zone->slope_ranges_count].softmin = 0.0; + zone->slope_ranges[zone->slope_ranges_count].hardmin = 0.0; + zone->slope_ranges[zone->slope_ranges_count].hardmax = 0.0; + zone->slope_ranges[zone->slope_ranges_count].softmax = 0.0; + return zone->slope_ranges_count++; + } + else + { + return -1; + } +} + +int zoneGetSlopeRangeCount(Zone* zone) +{ + return zone->slope_ranges_count; +} + +int zoneGetSlopeRange(Zone* zone, int position, ZoneRangeCondition* range) +{ + if (position >= 0 && position < zone->slope_ranges_count) + { + *range = zone->slope_ranges[position]; + return 1; + } + else + { + return 0; + } +} + +int zoneSetSlopeRange(Zone* zone, int position, ZoneRangeCondition* range) +{ + if (position >= 0 && position < zone->slope_ranges_count) + { + zone->slope_ranges[position] = *range; + return 1; + } + else + { + return 0; + } +} + +int zoneAddSlopeRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax) +{ + ZoneRangeCondition range = {value, hardmin, softmin, softmax, hardmax}; + int position; + + position = zoneAddSlopeRange(zone); + if (position >= 0) + { + zoneSetSlopeRange(zone, position, &range); + } + return position; +} + +static inline double _getRangeInfluence(ZoneRangeCondition range, double position) { if (position >= range.hardmin && position <= range.hardmax) { @@ -271,12 +364,12 @@ double zoneGetValue(Zone* zone, Vector3 location, Vector3 normal) value_height = 1.0; } - if (zone->steepness_ranges_count > 0) + if (zone->slope_ranges_count > 0) { value_steepness = 0.0; - for (i = 0; i < zone->steepness_ranges_count; i++) + for (i = 0; i < zone->slope_ranges_count; i++) { - value = _getRangeInfluence(zone->steepness_ranges[i], (1.0 - normal.y)); + value = _getRangeInfluence(zone->slope_ranges[i], (1.0 - normal.y)); if (value > value_steepness) { value_steepness = value; diff --git a/lib_paysages/zone.h b/lib_paysages/zone.h index 9e13ad6..12c9e8e 100644 --- a/lib_paysages/zone.h +++ b/lib_paysages/zone.h @@ -7,6 +7,15 @@ extern "C" { #endif +typedef struct +{ + double value; + double hardmin; + double softmin; + double softmax; + double hardmax; +} ZoneRangeCondition; + Zone* zoneCreate(); void zoneDelete(Zone* zone); void zoneSave(FILE* f, Zone* zone); @@ -14,8 +23,19 @@ void zoneLoad(FILE* f, Zone* zone); void zoneCopy(Zone* source, Zone* destination); void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double centerz, double softradius, double hardradius); void zoneExcludeCircleArea(Zone* zone, double centerx, double centerz, double softradius, double hardradius); -void zoneAddHeightRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax); -void zoneAddSteepnessRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax); + +int zoneAddHeightRange(Zone* zone); +int zoneGetHeightRangeCount(Zone* zone); +int zoneGetHeightRange(Zone* zone, int position, ZoneRangeCondition* range); +int zoneSetHeightRange(Zone* zone, int position, ZoneRangeCondition* range); +int zoneAddHeightRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax); + +int zoneAddSlopeRange(Zone* zone); +int zoneGetSlopeRangeCount(Zone* zone); +int zoneGetSlopeRange(Zone* zone, int position, ZoneRangeCondition* range); +int zoneSetSlopeRange(Zone* zone, int position, ZoneRangeCondition* range); +int zoneAddSlopeRangeQuick(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax); + double zoneGetValue(Zone* zone, Vector3 location, Vector3 normal); #ifdef __cplusplus