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:
parent
a632974d29
commit
e7f76022ec
3 changed files with 137 additions and 22 deletions
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
@ -134,6 +157,8 @@ CloudsLayerDefinition cloudsLayerCreateDefinition()
|
|||
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);
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue