paysages : Added cloud color preview.

git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@262 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
This commit is contained in:
Michaël Lemaire 2012-02-08 14:24:53 +00:00 committed by ThunderK
parent a632974d29
commit e7f76022ec
3 changed files with 137 additions and 22 deletions

View file

@ -51,6 +51,89 @@ private:
CloudsLayerDefinition _preview_layer;
};
class PreviewCloudsColor:public Preview
{
public:
PreviewCloudsColor(QWidget* parent):Preview(parent)
{
LightDefinition light;
_preview_layer = cloudsLayerCreateDefinition();
_lighting = lightingCreateDefinition();
light.color = COLOR_WHITE;
light.amplitude = 0.0;
light.direction.x = 0.0;
light.direction.y = -0.4794;
light.direction.z = 0.8776;
light.filtered = 0;
light.masked = 1;
light.reflection = 1.0;
lightingAddLight(&_lighting, light);
lightingValidateDefinition(&_lighting);
_renderer = rendererCreate();
_renderer.render_quality = 3;
_renderer.applyLightingToSurface = _applyLightingToSurface;
_renderer.maskLight = _maskLight;
_renderer.customData[0] = &_preview_layer;
_renderer.customData[1] = &_lighting;
}
protected:
QColor getColor(double x, double y)
{
Vector3 start, end;
Color color_layer, result;
start.x = x;
start.y = y;
start.z = -100.0;
end.x = x;
end.y = y;
end.z = 100.0;
result = COLOR_BLUE;
color_layer = cloudsGetLayerColor(&_preview_layer, &_renderer, start, end);
colorMask(&result, &color_layer);
return colorToQColor(result);
}
void updateData()
{
cloudsLayerCopyDefinition(&_layer, &_preview_layer);
_preview_layer.ymin = -100.0;
_preview_layer.ycenter = 0.0;
_preview_layer.ymax = 100.0;
_preview_layer.customcoverage = _coverageFunc;
}
private:
Renderer _renderer;
CloudsLayerDefinition _preview_layer;
LightingDefinition _lighting;
static double _coverageFunc(CloudsLayerDefinition* layer, Vector3 position)
{
double dist = v3Norm(position);
if (dist >= 100.0)
{
return 0.0;
}
else
{
return 1.0 - dist / 100.0;
}
}
static Color _applyLightingToSurface(Renderer* renderer, Vector3 location, Vector3 normal, SurfaceMaterial material)
{
return lightingApplyToSurface((LightingDefinition*)renderer->customData[1], renderer, location, normal, material);
}
static Color _maskLight(Renderer* renderer, Color light_color, Vector3 at_location, Vector3 light_location, Vector3 direction_to_light)
{
return cloudsLayerFilterLight((CloudsLayerDefinition*)renderer->customData[0], renderer, light_color, at_location, light_location, direction_to_light);
}
};
/**************** Form ****************/
FormClouds::FormClouds(QWidget *parent):
BaseForm(parent, false, true)
@ -59,6 +142,7 @@ FormClouds::FormClouds(QWidget *parent):
_layer = cloudsLayerCreateDefinition();
addPreview(new PreviewCloudsCoverage(parent), "Layer coverage (no lighting)");
addPreview(new PreviewCloudsColor(parent), "Color and lighting");
addInputDouble("Start altitude", &_layer.ymin, -10.0, 250.0, 0.5, 5.0);
addInputDouble("Max density altitude", &_layer.ycenter, -10.0, 250.0, 0.5, 5.0);

View file

@ -117,6 +117,29 @@ void cloudsValidateDefinition(CloudsDefinition* definition)
}
}
static double _standardCoverageFunc(CloudsLayerDefinition* layer, Vector3 position)
{
double inside;
if (position.y > layer->ycenter)
{
inside = 1.0 - (position.y - layer->ycenter) / (layer->ymax - layer->ycenter);
}
else
{
inside = 1.0 - (layer->ycenter - position.y) / (layer->ycenter - layer->ymin);
}
if (inside <= 0.0)
{
return 0.0;
}
else
{
return layer->coverage * inside;
}
}
CloudsLayerDefinition cloudsLayerCreateDefinition()
{
CloudsLayerDefinition result;
@ -133,6 +156,8 @@ CloudsLayerDefinition cloudsLayerCreateDefinition()
result.ymin = 50.0;
result.ycenter = 100.0;
result.ymax = 200.0;
result.customcoverage = _standardCoverageFunc;
return result;
}
@ -188,8 +213,7 @@ int cloudsAddLayer(CloudsDefinition* definition)
if (definition->nblayers < CLOUDS_MAX_LAYERS)
{
layer = definition->layers + definition->nblayers;
layer->noise = noiseCreateGenerator();
layer->coverage = 0.0;
*layer = cloudsLayerCreateDefinition();
return definition->nblayers++;
}
@ -214,45 +238,47 @@ void cloudsDeleteLayer(CloudsDefinition* definition, int layer)
static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 position)
{
double val, min;
if (position.y > layer->ycenter)
{
min = (position.y - layer->ycenter) / (layer->ymax - layer->ycenter);
}
else
{
min = (layer->ycenter - position.y) / (layer->ycenter - layer->ymin);
}
double val;
val = 0.5 * noiseGet3DTotal(layer->noise, position.x / layer->scaling, position.y / layer->scaling, position.z / layer->scaling) / noiseGetMaxValue(layer->noise);
return (val - 0.5 - min + layer->coverage) * layer->scaling;
return (val - 0.5 + layer->customcoverage(layer, position)) * layer->scaling;
}
static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position, double detail)
{
Vector3 result = {0.0, 0.0, 0.0};
Vector3 dposition;
double val, dval;
val = noiseGet3DDetail(layer->noise, position.x / layer->scaling, position.y / layer->scaling, position.z / layer->scaling, detail);
val = _getDistanceToBorder(layer, position);
dval = val - noiseGet3DDetail(layer->noise, (position.x + detail) / layer->scaling, position.y / layer->scaling, position.z / layer->scaling, detail);
dposition.x = position.x + detail;
dposition.y = position.y;
dposition.z = position.z;
dval = val - _getDistanceToBorder(layer, dposition);
result.x += dval;
dval = val - noiseGet3DDetail(layer->noise, (position.x - detail) / layer->scaling, position.y / layer->scaling, position.z / layer->scaling, detail);
dposition.x = position.x - detail;
dval = val - _getDistanceToBorder(layer, dposition);
result.x -= dval;
dval = val - noiseGet3DDetail(layer->noise, position.x / layer->scaling, (position.y + detail) / layer->scaling, position.z / layer->scaling, detail);
dposition.x = position.x;
dposition.y = position.y + detail;
dval = val - _getDistanceToBorder(layer, dposition);
result.y += dval;
dval = val - noiseGet3DDetail(layer->noise, position.x / layer->scaling, (position.y - detail) / layer->scaling, position.z / layer->scaling, detail);
dposition.y = position.y - detail;
dval = val - _getDistanceToBorder(layer, dposition);
result.y -= dval;
dval = val - noiseGet3DDetail(layer->noise, position.x / layer->scaling, position.y / layer->scaling, (position.z + detail) / layer->scaling, detail);
dposition.y = position.y;
dposition.z = position.z + detail;
dval = val - _getDistanceToBorder(layer, dposition);
result.z += dval;
dval = val - noiseGet3DDetail(layer->noise, position.x / layer->scaling, position.y / layer->scaling, (position.z - detail) / layer->scaling, detail);
dposition.z = position.z - detail;
dval = val - _getDistanceToBorder(layer, dposition);
result.z -= dval;
return v3Normalize(result);

View file

@ -12,7 +12,11 @@ extern "C" {
#define CLOUDS_MAX_LAYERS 6
typedef struct
typedef struct CloudsLayerDefinition CloudsLayerDefinition;
typedef double (*CloudCoverageFunc)(CloudsLayerDefinition* definition, Vector3 position);
struct CloudsLayerDefinition
{
double ycenter;
double ymin;
@ -24,7 +28,8 @@ typedef struct
double minimumlight;
double scaling;
double coverage;
} CloudsLayerDefinition;
CloudCoverageFunc customcoverage;
};
typedef struct
{