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;
|
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 ****************/
|
/**************** Form ****************/
|
||||||
FormClouds::FormClouds(QWidget *parent):
|
FormClouds::FormClouds(QWidget *parent):
|
||||||
BaseForm(parent, false, true)
|
BaseForm(parent, false, true)
|
||||||
|
@ -59,6 +142,7 @@ FormClouds::FormClouds(QWidget *parent):
|
||||||
_layer = cloudsLayerCreateDefinition();
|
_layer = cloudsLayerCreateDefinition();
|
||||||
|
|
||||||
addPreview(new PreviewCloudsCoverage(parent), "Layer coverage (no lighting)");
|
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("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);
|
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 cloudsLayerCreateDefinition()
|
||||||
{
|
{
|
||||||
CloudsLayerDefinition result;
|
CloudsLayerDefinition result;
|
||||||
|
@ -133,6 +156,8 @@ CloudsLayerDefinition cloudsLayerCreateDefinition()
|
||||||
result.ymin = 50.0;
|
result.ymin = 50.0;
|
||||||
result.ycenter = 100.0;
|
result.ycenter = 100.0;
|
||||||
result.ymax = 200.0;
|
result.ymax = 200.0;
|
||||||
|
|
||||||
|
result.customcoverage = _standardCoverageFunc;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
@ -188,8 +213,7 @@ int cloudsAddLayer(CloudsDefinition* definition)
|
||||||
if (definition->nblayers < CLOUDS_MAX_LAYERS)
|
if (definition->nblayers < CLOUDS_MAX_LAYERS)
|
||||||
{
|
{
|
||||||
layer = definition->layers + definition->nblayers;
|
layer = definition->layers + definition->nblayers;
|
||||||
layer->noise = noiseCreateGenerator();
|
*layer = cloudsLayerCreateDefinition();
|
||||||
layer->coverage = 0.0;
|
|
||||||
|
|
||||||
return definition->nblayers++;
|
return definition->nblayers++;
|
||||||
}
|
}
|
||||||
|
@ -214,45 +238,47 @@ void cloudsDeleteLayer(CloudsDefinition* definition, int layer)
|
||||||
|
|
||||||
static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 position)
|
static inline double _getDistanceToBorder(CloudsLayerDefinition* layer, Vector3 position)
|
||||||
{
|
{
|
||||||
double val, min;
|
double val;
|
||||||
|
|
||||||
if (position.y > layer->ycenter)
|
|
||||||
{
|
|
||||||
min = (position.y - layer->ycenter) / (layer->ymax - layer->ycenter);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
min = (layer->ycenter - position.y) / (layer->ycenter - layer->ymin);
|
|
||||||
}
|
|
||||||
|
|
||||||
val = 0.5 * noiseGet3DTotal(layer->noise, position.x / layer->scaling, position.y / layer->scaling, position.z / layer->scaling) / noiseGetMaxValue(layer->noise);
|
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)
|
static inline Vector3 _getNormal(CloudsLayerDefinition* layer, Vector3 position, double detail)
|
||||||
{
|
{
|
||||||
Vector3 result = {0.0, 0.0, 0.0};
|
Vector3 result = {0.0, 0.0, 0.0};
|
||||||
|
Vector3 dposition;
|
||||||
double val, dval;
|
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;
|
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;
|
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;
|
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;
|
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;
|
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;
|
result.z -= dval;
|
||||||
|
|
||||||
return v3Normalize(result);
|
return v3Normalize(result);
|
||||||
|
|
|
@ -12,7 +12,11 @@ extern "C" {
|
||||||
|
|
||||||
#define CLOUDS_MAX_LAYERS 6
|
#define CLOUDS_MAX_LAYERS 6
|
||||||
|
|
||||||
typedef struct
|
typedef struct CloudsLayerDefinition CloudsLayerDefinition;
|
||||||
|
|
||||||
|
typedef double (*CloudCoverageFunc)(CloudsLayerDefinition* definition, Vector3 position);
|
||||||
|
|
||||||
|
struct CloudsLayerDefinition
|
||||||
{
|
{
|
||||||
double ycenter;
|
double ycenter;
|
||||||
double ymin;
|
double ymin;
|
||||||
|
@ -24,7 +28,8 @@ typedef struct
|
||||||
double minimumlight;
|
double minimumlight;
|
||||||
double scaling;
|
double scaling;
|
||||||
double coverage;
|
double coverage;
|
||||||
} CloudsLayerDefinition;
|
CloudCoverageFunc customcoverage;
|
||||||
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in a new issue