Merge branch 'master' into vegetation

Conflicts:
	src/basics/Disk.cpp
	src/basics/Disk.h
	src/basics/SpaceSegment.cpp
	src/definition/DefinitionNode.cpp
	src/definition/DefinitionNode.h
	src/definition/Scenery.cpp
	src/definition/Scenery.h
	src/definition/SurfaceMaterial.cpp
	src/definition/SurfaceMaterial.h
	src/definition/TextureLayerDefinition.cpp
	src/definition/definition_global.h
	src/interface/commandline/tests.cpp
	src/render/opengl/OpenGLRenderer.cpp
	src/render/software/SoftwareCanvasRenderer.cpp
	src/render/software/SoftwareCanvasRenderer.h
	src/render/software/SoftwareRenderer.h
	src/render/software/TerrainRasterizer.cpp
	src/render/software/TerrainRasterizer.h
	src/render/software/TerrainRenderer.h
	src/render/software/software_global.h
This commit is contained in:
Michaël Lemaire 2015-11-09 22:38:00 +01:00
commit 9a096ec329
335 changed files with 5430 additions and 8193 deletions

View file

@ -7,6 +7,9 @@ PATH:=${QTSDK}/bin:${PATH}
all:build
format:
find src \( \( -name '*.cpp' -or -name '*.h' \) -and \! -path '*/googletest/*' \) -exec clang-format -i \{\} \;
dirs:
mkdir -p ${BUILDPATH}

6
src/.clang-format Normal file
View file

@ -0,0 +1,6 @@
BasedOnStyle: LLVM
IndentWidth: 4
ColumnLimit: 120
AllowShortFunctionsOnASingleLine: false
AllowShortIfStatementsOnASingleLine: false
AllowShortLoopsOnASingleLine: false

View file

@ -2,13 +2,11 @@
#include "Vector3.h"
BoundingBox::BoundingBox()
{
BoundingBox::BoundingBox() {
reset();
}
void BoundingBox::reset()
{
void BoundingBox::reset() {
empty = 1;
xmin = 10000000000.0;
xmax = -10000000000.0;
@ -18,31 +16,24 @@ void BoundingBox::reset()
zmax = -10000000000.0;
}
void BoundingBox::pushPoint(const Vector3 &point)
{
void BoundingBox::pushPoint(const Vector3 &point) {
empty = 0;
if (point.x < xmin)
{
if (point.x < xmin) {
xmin = point.x;
}
if (point.x > xmax)
{
if (point.x > xmax) {
xmax = point.x;
}
if (point.y < ymin)
{
if (point.y < ymin) {
ymin = point.y;
}
if (point.y > ymax)
{
if (point.y > ymax) {
ymax = point.y;
}
if (point.z < zmin)
{
if (point.z < zmin) {
zmin = point.z;
}
if (point.z > zmax)
{
if (point.z > zmax) {
zmax = point.z;
}
}

View file

@ -6,15 +6,14 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT BoundingBox
{
public:
class BASICSSHARED_EXPORT BoundingBox {
public:
BoundingBox();
void reset();
void pushPoint(const Vector3 &point);
public:
public:
int empty;
double xmin;
double xmax;
@ -23,7 +22,6 @@ public:
double zmin;
double zmax;
};
}
}

View file

@ -3,77 +3,56 @@
#include "Vector3.h"
#include "PackStream.h"
CappedCylinder::CappedCylinder()
{
CappedCylinder::CappedCylinder() {
}
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length):
InfiniteCylinder(InfiniteRay(base, direction), radius), length(length)
{
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length)
: InfiniteCylinder(InfiniteRay(base, direction), radius), length(length) {
}
int CappedCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
{
int CappedCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
Vector3 *second_intersection) const {
// TODO Apply the caps
int count = InfiniteCylinder::checkRayIntersection(ray, first_intersection, second_intersection);
if (count == 0)
{
if (count == 0) {
return 0;
}
else if (count == 2)
{
if (checkPointProjection(first_intersection))
{
if (checkPointProjection(second_intersection))
{
} else if (count == 2) {
if (checkPointProjection(first_intersection)) {
if (checkPointProjection(second_intersection)) {
return 2;
}
else
{
} else {
return 1;
}
}
else
{
if (checkPointProjection(second_intersection))
{
} else {
if (checkPointProjection(second_intersection)) {
*first_intersection = *second_intersection;
return 1;
}
else
{
} else {
return 0;
}
}
}
else // count == 1
} else // count == 1
{
if (checkPointProjection(first_intersection))
{
if (checkPointProjection(first_intersection)) {
return 1;
}
else
{
} else {
return 0;
}
}
}
bool CappedCylinder::checkPointProjection(Vector3 *point) const
{
bool CappedCylinder::checkPointProjection(Vector3 *point) const {
double proj_length = axis.getDirection().dotProduct(point->sub(axis.getOrigin()));
return 0.0 <= proj_length && proj_length <= length;
}
void CappedCylinder::save(PackStream *stream) const
{
void CappedCylinder::save(PackStream *stream) const {
InfiniteCylinder::save(stream);
stream->write(&length);
}
void CappedCylinder::load(PackStream *stream)
{
void CappedCylinder::load(PackStream *stream) {
InfiniteCylinder::load(stream);
stream->read(&length);
}

View file

@ -11,13 +11,14 @@ namespace basics {
/**
* Geometric cylinder, with capped ends (not infinite).
*/
class BASICSSHARED_EXPORT CappedCylinder: public InfiniteCylinder
{
public:
class BASICSSHARED_EXPORT CappedCylinder : public InfiniteCylinder {
public:
CappedCylinder();
CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length);
inline double getLength() const {return length;}
inline double getLength() const {
return length;
}
/**
* Check the intersection between the cylinder and an infinite ray.
@ -32,10 +33,9 @@ public:
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
private:
private:
double length;
};
}
}

View file

@ -11,16 +11,14 @@ const Color paysages::basics::COLOR_BLUE = {0.0, 0.0, 1.0, 1.0};
const Color paysages::basics::COLOR_WHITE = {1.0, 1.0, 1.0, 1.0};
const Color paysages::basics::COLOR_GREY = {0.5, 0.5, 0.5, 1.0};
void Color::save(PackStream* stream) const
{
void Color::save(PackStream *stream) const {
stream->write(&r);
stream->write(&g);
stream->write(&b);
stream->write(&a);
}
void Color::load(PackStream* stream)
{
void Color::load(PackStream *stream) {
stream->read(&r);
stream->read(&g);
stream->read(&b);

View file

@ -6,15 +6,14 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Color
{
public:
class BASICSSHARED_EXPORT Color {
public:
Color() = default;
Color(const Color &col);
Color(double r, double g, double b, double a=1.0);
Color(double r, double g, double b, double a = 1.0);
void save(PackStream* stream) const;
void load(PackStream* stream);
void save(PackStream *stream) const;
void load(PackStream *stream);
unsigned int to32BitRGBA() const;
unsigned int to32BitBGRA() const;
@ -26,16 +25,16 @@ public:
static Color from32BitARGB(unsigned int col);
static Color from32BitABGR(unsigned int col);
void mask(const Color& mask);
void mask(const Color &mask);
double normalize();
double getValue() const;
double getPower() const;
void limitPower(double max_power);
Color add(const Color& other) const;
Color lerp(const Color& other, double f) const;
Color add(const Color &other) const;
Color lerp(const Color &other, double f) const;
public:
public:
double r;
double g;
double b;
@ -49,7 +48,6 @@ BASICSSHARED_EXPORT extern const Color COLOR_GREEN;
BASICSSHARED_EXPORT extern const Color COLOR_BLUE;
BASICSSHARED_EXPORT extern const Color COLOR_WHITE;
BASICSSHARED_EXPORT extern const Color COLOR_GREY;
}
}

View file

@ -6,84 +6,59 @@
#endif
#ifdef COLOR_H
# define METHSPEC inline
#define METHSPEC inline
#else
# include "Color.h"
# define METHSPEC
#include "Color.h"
#define METHSPEC
#endif
METHSPEC Color::Color(double r, double g, double b, double a):
r(r), g(g), b(b), a(a)
{
METHSPEC Color::Color(double r, double g, double b, double a) : r(r), g(g), b(b), a(a) {
}
METHSPEC Color::Color(const Color &col):
r(col.r), g(col.g), b(col.b), a(col.a)
{
METHSPEC Color::Color(const Color &col) : r(col.r), g(col.g), b(col.b), a(col.a) {
}
METHSPEC unsigned int Color::to32BitRGBA() const
{
return (((unsigned int) (a * 255.0)) << 24) | (((unsigned int) (b * 255.0)) << 16) | (((unsigned int) (g * 255.0)) << 8) | ((unsigned int) (r * 255.0));
METHSPEC unsigned int Color::to32BitRGBA() const {
return (((unsigned int)(a * 255.0)) << 24) | (((unsigned int)(b * 255.0)) << 16) |
(((unsigned int)(g * 255.0)) << 8) | ((unsigned int)(r * 255.0));
}
METHSPEC unsigned int Color::to32BitBGRA() const
{
return (((unsigned int) (a * 255.0)) << 24) | (((unsigned int) (r * 255.0)) << 16) | (((unsigned int) (g * 255.0)) << 8) | ((unsigned int) (b * 255.0));
METHSPEC unsigned int Color::to32BitBGRA() const {
return (((unsigned int)(a * 255.0)) << 24) | (((unsigned int)(r * 255.0)) << 16) |
(((unsigned int)(g * 255.0)) << 8) | ((unsigned int)(b * 255.0));
}
METHSPEC unsigned int Color::to32BitARGB() const
{
return (((unsigned int) (b * 255.0)) << 24) | (((unsigned int) (g * 255.0)) << 16) | (((unsigned int) (r * 255.0)) << 8) | ((unsigned int) (a * 255.0));
METHSPEC unsigned int Color::to32BitARGB() const {
return (((unsigned int)(b * 255.0)) << 24) | (((unsigned int)(g * 255.0)) << 16) |
(((unsigned int)(r * 255.0)) << 8) | ((unsigned int)(a * 255.0));
}
METHSPEC unsigned int Color::to32BitABGR() const
{
return (((unsigned int) (r * 255.0)) << 24) | (((unsigned int) (g * 255.0)) << 16) | (((unsigned int) (b * 255.0)) << 8) | ((unsigned int) (a * 255.0));
METHSPEC unsigned int Color::to32BitABGR() const {
return (((unsigned int)(r * 255.0)) << 24) | (((unsigned int)(g * 255.0)) << 16) |
(((unsigned int)(b * 255.0)) << 8) | ((unsigned int)(a * 255.0));
}
METHSPEC Color Color::from32BitRGBA(unsigned int col)
{
return Color(
((double) (col & 0x000000FF)) / 255.0,
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
((double) ((col & 0xFF000000) >> 24)) / 255.0
);
METHSPEC Color Color::from32BitRGBA(unsigned int col) {
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
}
METHSPEC Color Color::from32BitBGRA(unsigned int col)
{
return Color(
((double) (col & 0x000000FF)) / 255.0,
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
((double) ((col & 0xFF000000) >> 24)) / 255.0
);
METHSPEC Color Color::from32BitBGRA(unsigned int col) {
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
}
METHSPEC Color Color::from32BitARGB(unsigned int col)
{
return Color(
((double) (col & 0x000000FF)) / 255.0,
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
((double) ((col & 0xFF000000) >> 24)) / 255.0
);
METHSPEC Color Color::from32BitARGB(unsigned int col) {
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
}
METHSPEC Color Color::from32BitABGR(unsigned int col)
{
return Color(
((double) (col & 0x000000FF)) / 255.0,
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
((double) ((col & 0xFF000000) >> 24)) / 255.0
);
METHSPEC Color Color::from32BitABGR(unsigned int col) {
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
}
METHSPEC void Color::mask(const Color& mask)
{
METHSPEC void Color::mask(const Color &mask) {
double new_a;
new_a = a + mask.a - (a * mask.a);
r = (mask.r * mask.a + r * a - r * a * mask.a) / new_a;
@ -100,8 +75,7 @@ METHSPEC void Color::mask(const Color& mask)
base->a = base->a + mask_weight * (1.0 - base->a);*/
}
METHSPEC double Color::normalize()
{
METHSPEC double Color::normalize() {
#ifndef NDEBUG
assert(r >= 0.0);
assert(g >= 0.0);
@ -121,16 +95,13 @@ METHSPEC double Color::normalize()
#endif
#endif
if (r > 1.0)
{
if (r > 1.0) {
r = 1.0;
}
if (g > 1.0)
{
if (g > 1.0) {
g = 1.0;
}
if (b > 1.0)
{
if (b > 1.0) {
b = 1.0;
}
return 1.0;
@ -147,33 +118,27 @@ METHSPEC double Color::normalize()
return max;*/
}
METHSPEC double Color::getValue() const
{
METHSPEC double Color::getValue() const {
double max;
max = r;
if (g > max)
{
if (g > max) {
max = g;
}
if (b > max)
{
if (b > max) {
max = b;
}
return max;
}
METHSPEC double Color::getPower() const
{
METHSPEC double Color::getPower() const {
return r + g + b;
}
METHSPEC void Color::limitPower(double max_power)
{
METHSPEC void Color::limitPower(double max_power) {
double power = r + g + b;
if (power > max_power)
{
if (power > max_power) {
double factor = max_power / power;
r *= factor;
@ -182,18 +147,12 @@ METHSPEC void Color::limitPower(double max_power)
}
}
METHSPEC Color Color::add(const Color& other) const
{
METHSPEC Color Color::add(const Color &other) const {
return Color(r + other.r, g + other.g, b + other.b, a);
}
METHSPEC Color Color::lerp(const Color& other, double f) const
{
Color result(
r * (1.0 - f) + other.r * f,
g * (1.0 - f) + other.g * f,
b * (1.0 - f) + other.b * f,
a * (1.0 - f) + other.a * f
);
METHSPEC Color Color::lerp(const Color &other, double f) const {
Color result(r * (1.0 - f) + other.r * f, g * (1.0 - f) + other.g * f, b * (1.0 - f) + other.b * f,
a * (1.0 - f) + other.a * f);
return result;
}

View file

@ -2,26 +2,26 @@
#include "Color.h"
static inline double _hue2rgb(double p, double q, double t)
{
if (t < 0.0) t += 1;
if (t > 1.0) t -= 1;
if (t < 1.0 / 6.0) return p + (q - p) * 6.0 * t;
if (t < 1.0 / 2.0) return q;
if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
static inline double _hue2rgb(double p, double q, double t) {
if (t < 0.0)
t += 1;
if (t > 1.0)
t -= 1;
if (t < 1.0 / 6.0)
return p + (q - p) * 6.0 * t;
if (t < 1.0 / 2.0)
return q;
if (t < 2.0 / 3.0)
return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
return p;
}
Color colorFromHSL(const ColorHSL &col)
{
Color colorFromHSL(const ColorHSL &col) {
Color result;
if (col.s == 0)
{
if (col.s == 0) {
result.r = result.g = result.b = col.l;
}
else
{
} else {
double q = col.l < 0.5 ? col.l * (1.0 + col.s) : col.l + col.s - col.l * col.s;
double p = 2 * col.l - q;
result.r = _hue2rgb(p, q, col.h + 1.0 / 3.0);
@ -34,8 +34,7 @@ Color colorFromHSL(const ColorHSL &col)
return result;
}
ColorHSL colorToHSL(const Color &col)
{
ColorHSL colorToHSL(const Color &col) {
ColorHSL result;
double min, max;
@ -47,24 +46,16 @@ ColorHSL colorToHSL(const Color &col)
result.h = result.s = result.l = (max + min) / 2.0;
if (max == min)
{
if (max == min) {
result.h = result.s = 0.0;
}
else
{
} else {
double d = max - min;
result.s = result.l > 0.5 ? d / (2.0 - max - min) : d / (max + min);
if (max == col.r)
{
if (max == col.r) {
result.h = (col.g - col.b) / d + (col.g < col.b ? 6.0 : 0);
}
else if (max == col.g)
{
} else if (max == col.g) {
result.h = (col.b - col.r) / d + 2.0;
}
else
{
} else {
result.h = (col.r - col.g) / d + 4.0;
}
result.h /= 6.0;
@ -75,8 +66,7 @@ ColorHSL colorToHSL(const Color &col)
return result;
}
ColorHSL colorHSLFromValues(double h, double s, double l, double a)
{
ColorHSL colorHSLFromValues(double h, double s, double l, double a) {
ColorHSL result;
result.h = h;

View file

@ -3,8 +3,7 @@
#include "basics_global.h"
typedef struct
{
typedef struct {
double h;
double s;
double l;

View file

@ -2,18 +2,15 @@
#include "PackStream.h"
ColorProfile::ColorProfile()
{
ColorProfile::ColorProfile() {
setToneMapping(TONE_MAPPING_UNCHARTED, 1.6);
}
ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure)
{
ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure) {
setToneMapping(tonemapper, exposure);
}
static inline double _uncharted2Tonemap(double x)
{
static inline double _uncharted2Tonemap(double x) {
double A = 0.15;
double B = 0.50;
double C = 0.10;
@ -24,61 +21,43 @@ static inline double _uncharted2Tonemap(double x)
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
}
static inline Color _toneMappingUncharted(const Color &pixel, double exposure)
{
static inline Color _toneMappingUncharted(const Color &pixel, double exposure) {
static const double W = 11.2;
static const double white_scale = 1.0 / _uncharted2Tonemap(W);
static const double factor = 1.0 / 2.2;
Color result(
pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, factor),
pixel.a
);
Color result(pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, factor),
pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, factor), pixel.a);
return result;
}
static inline Color _toneMappingReinhard(const Color &pixel, double exposure)
{
Color result(
(pixel.r * exposure) / (1.0 + pixel.r * exposure),
(pixel.g * exposure) / (1.0 + pixel.g * exposure),
(pixel.b * exposure) / (1.0 + pixel.b * exposure),
pixel.a
);
static inline Color _toneMappingReinhard(const Color &pixel, double exposure) {
Color result((pixel.r * exposure) / (1.0 + pixel.r * exposure), (pixel.g * exposure) / (1.0 + pixel.g * exposure),
(pixel.b * exposure) / (1.0 + pixel.b * exposure), pixel.a);
return result;
}
static inline Color _toneMappingClamp(const Color &pixel)
{
Color result(
pixel.r > 1.0 ? 1.0 : pixel.r,
pixel.g > 1.0 ? 1.0 : pixel.g,
pixel.b > 1.0 ? 1.0 : pixel.b,
pixel.a
);
static inline Color _toneMappingClamp(const Color &pixel) {
Color result(pixel.r > 1.0 ? 1.0 : pixel.r, pixel.g > 1.0 ? 1.0 : pixel.g, pixel.b > 1.0 ? 1.0 : pixel.b, pixel.a);
return result;
}
void ColorProfile::setToneMapping(ToneMappingOperator tonemapper, double exposure)
{
void ColorProfile::setToneMapping(ToneMappingOperator tonemapper, double exposure) {
this->mapper = tonemapper;
this->exposure = exposure;
}
void ColorProfile::save(PackStream* stream) const
{
void ColorProfile::save(PackStream *stream) const {
int imapper = (int)mapper;
stream->write(&imapper);
stream->write(&exposure);
}
void ColorProfile::load(PackStream* stream)
{
void ColorProfile::load(PackStream *stream) {
int imapper = (int)mapper;
stream->read(&imapper);
stream->read(&exposure);
@ -86,16 +65,13 @@ void ColorProfile::load(PackStream* stream)
mapper = (ToneMappingOperator)imapper;
}
void ColorProfile::copy(ColorProfile* destination) const
{
void ColorProfile::copy(ColorProfile *destination) const {
destination->mapper = mapper;
destination->exposure = exposure;
}
Color ColorProfile::apply(const Color &pixel) const
{
switch (mapper)
{
Color ColorProfile::apply(const Color &pixel) const {
switch (mapper) {
case TONE_MAPPING_REIHNARD:
return _toneMappingReinhard(pixel, exposure);
case TONE_MAPPING_UNCHARTED:

View file

@ -8,33 +8,26 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT ColorProfile
{
public:
typedef enum
{
TONE_MAPPING_UNCHARTED,
TONE_MAPPING_REIHNARD,
TONE_MAPPING_CLAMP
} ToneMappingOperator;
class BASICSSHARED_EXPORT ColorProfile {
public:
typedef enum { TONE_MAPPING_UNCHARTED, TONE_MAPPING_REIHNARD, TONE_MAPPING_CLAMP } ToneMappingOperator;
public:
public:
ColorProfile();
ColorProfile(ToneMappingOperator tonemapper, double exposure);
void setToneMapping(ToneMappingOperator tonemapper, double exposure);
void save(PackStream* stream) const;
void load(PackStream* stream);
void copy(ColorProfile* destination) const;
void save(PackStream *stream) const;
void load(PackStream *stream);
void copy(ColorProfile *destination) const;
Color apply(const Color &pixel) const;
private:
private:
ToneMappingOperator mapper;
double exposure;
};
}
}

View file

@ -5,167 +5,123 @@
const int MAX_NB_POINTS = 30;
Curve::Curve()
{
Curve::Curve() {
nbpoints = 0;
default_value = 0.0;
points = new CurvePoint[MAX_NB_POINTS];
}
Curve::~Curve()
{
Curve::~Curve() {
delete[] points;
}
void Curve::copy(Curve* destination) const
{
void Curve::copy(Curve *destination) const {
destination->nbpoints = nbpoints;
destination->default_value = default_value;
for (int i = 0; i < nbpoints; i++)
{
for (int i = 0; i < nbpoints; i++) {
destination->points[i] = points[i];
}
}
void Curve::save(PackStream* stream) const
{
void Curve::save(PackStream *stream) const {
stream->write(&default_value);
stream->write(&nbpoints);
for (int i = 0; i < nbpoints; i++)
{
for (int i = 0; i < nbpoints; i++) {
stream->write(&points[i].position);
stream->write(&points[i].value);
}
}
void Curve::load(PackStream* stream)
{
void Curve::load(PackStream *stream) {
stream->read(&default_value);
stream->read(&nbpoints);
for (int i = 0; i < nbpoints; i++)
{
for (int i = 0; i < nbpoints; i++) {
stream->read(&points[i].position);
stream->read(&points[i].value);
}
}
void Curve::clear()
{
void Curve::clear() {
nbpoints = 0;
}
void Curve::setDefault(double value)
{
void Curve::setDefault(double value) {
default_value = value;
}
int Curve::addPoint(const CurvePoint &point)
{
if (nbpoints < MAX_NB_POINTS)
{
int Curve::addPoint(const CurvePoint &point) {
if (nbpoints < MAX_NB_POINTS) {
points[nbpoints] = point;
return nbpoints++;
}
else
{
} else {
return -1;
}
}
int Curve::addPoint(double position, double value)
{
int Curve::addPoint(double position, double value) {
CurvePoint point = {position, value};
return addPoint(point);
}
CurvePoint Curve::getPoint(int number) const
{
if (number >= 0 && number < nbpoints)
{
CurvePoint Curve::getPoint(int number) const {
if (number >= 0 && number < nbpoints) {
return points[number];
}
else
{
} else {
return {0.0, 0.0};
}
}
bool Curve::getPoint(int number, CurvePoint *point) const
{
if (number >= 0 && number < nbpoints)
{
bool Curve::getPoint(int number, CurvePoint *point) const {
if (number >= 0 && number < nbpoints) {
*point = points[number];
return true;
}
else
{
} else {
return false;
}
}
void Curve::setPoint(int number, const CurvePoint &point)
{
if (number >= 0 && number < nbpoints)
{
void Curve::setPoint(int number, const CurvePoint &point) {
if (number >= 0 && number < nbpoints) {
points[number] = point;
}
}
void Curve::removePoint(int number)
{
if (number >= 0 && number < nbpoints)
{
if (nbpoints > 0 && number < nbpoints - 1)
{
void Curve::removePoint(int number) {
if (number >= 0 && number < nbpoints) {
if (nbpoints > 0 && number < nbpoints - 1) {
memmove(points + number, points + number + 1, sizeof(CurvePoint) * (nbpoints - number - 1));
}
nbpoints--;
}
}
int _point_compare(const void* part1, const void* part2)
{
if (((CurvePoint*)part1)->position > ((CurvePoint*)part2)->position)
{
int _point_compare(const void *part1, const void *part2) {
if (((CurvePoint *)part1)->position > ((CurvePoint *)part2)->position) {
return 1;
}
else
{
} else {
return -1;
}
}
void Curve::validate()
{
if (nbpoints > 1)
{
void Curve::validate() {
if (nbpoints > 1) {
qsort(points, nbpoints, sizeof(CurvePoint), _point_compare);
}
}
double Curve::getValue(double position) const
{
double Curve::getValue(double position) const {
int i;
double fact;
if (nbpoints == 0)
{
if (nbpoints == 0) {
return default_value;
}
else if (nbpoints == 1 || position <= points[0].position)
{
} else if (nbpoints == 1 || position <= points[0].position) {
return points[0].value;
}
else if (position >= points[nbpoints - 1].position)
{
} else if (position >= points[nbpoints - 1].position) {
return points[nbpoints - 1].value;
}
else
{
for (i = 1; i < nbpoints; i++)
{
if (position < points[i].position)
{
} else {
for (i = 1; i < nbpoints; i++) {
if (position < points[i].position) {
fact = (position - points[i - 1].position) / (points[i].position - points[i - 1].position);
return points[i - 1].value + (points[i].value - points[i - 1].value) * fact;
}

View file

@ -11,18 +11,19 @@ typedef struct {
double value;
} CurvePoint;
class BASICSSHARED_EXPORT Curve
{
public:
class BASICSSHARED_EXPORT Curve {
public:
Curve();
~Curve();
void copy(Curve* destination) const;
void save(PackStream* stream) const;
void load(PackStream* stream);
void copy(Curve *destination) const;
void save(PackStream *stream) const;
void load(PackStream *stream);
void validate();
inline int getPointCount() const {return nbpoints;}
inline int getPointCount() const {
return nbpoints;
}
CurvePoint getPoint(int number) const;
bool getPoint(int number, CurvePoint *point) const;
@ -35,12 +36,11 @@ public:
void setPoint(int number, const CurvePoint &point);
void removePoint(int number);
private:
private:
double default_value;
int nbpoints;
CurvePoint* points;
CurvePoint *points;
};
}
}

View file

@ -2,37 +2,29 @@
#include "PackStream.h"
Disk::Disk(const Vector3 &point, const Vector3 &normal, double radius):
InfinitePlane(point, normal), radius(radius)
{
Disk::Disk(const Vector3 &point, const Vector3 &normal, double radius) : InfinitePlane(point, normal), radius(radius) {
radius2 = radius * radius;
}
int Disk::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const
{
int Disk::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const {
int result = InfinitePlane::checkRayIntersection(ray, intersection);
if (result == 1)
{
if (result == 1) {
Vector3 v = intersection->sub(getPoint());
double d2 = v.dotProduct(v);
return (d2 <= radius2) ? 1 : 0;
}
else
{
} else {
return result;
}
}
void Disk::save(PackStream *stream) const
{
void Disk::save(PackStream *stream) const {
InfinitePlane::save(stream);
stream->write(&radius);
stream->write(&radius2);
}
void Disk::load(PackStream *stream)
{
void Disk::load(PackStream *stream) {
InfinitePlane::load(stream);
stream->read(&radius);
stream->read(&radius2);

View file

@ -11,13 +11,14 @@ namespace basics {
/**
* Geometric plane disk.
*/
class BASICSSHARED_EXPORT Disk: public InfinitePlane
{
public:
class BASICSSHARED_EXPORT Disk : public InfinitePlane {
public:
Disk() = default;
Disk(const Vector3 &point, const Vector3 &normal, double radius);
inline double getRadius() const {return radius;}
inline double getRadius() const {
return radius;
}
/**
* Check the intersection between the disk and an infinite ray.
@ -26,16 +27,15 @@ public:
*
* Returns -1 if the ray shares a segment with the disk.
*/
int checkRayIntersection(const InfiniteRay& ray, Vector3 *intersection) const;
int checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const;
void save(PackStream *stream) const override;
void load(PackStream *stream) override;
private:
private:
double radius;
double radius2;
};
}
}

View file

@ -1,7 +1,6 @@
#include "FractalNoise.h"
FractalNoise::FractalNoise()
{
FractalNoise::FractalNoise() {
scaling = 1.0;
height = 1.0;
step_scaling = 2.0;
@ -10,47 +9,39 @@ FractalNoise::FractalNoise()
ridge = 0.0;
}
FractalNoise::~FractalNoise()
{
FractalNoise::~FractalNoise() {
}
void FractalNoise::setScaling(double scaling, double height)
{
void FractalNoise::setScaling(double scaling, double height) {
this->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling;
this->height = scaling * height;
}
void FractalNoise::setStep(double scaling_factor, double height_factor)
{
void FractalNoise::setStep(double scaling_factor, double height_factor) {
this->step_scaling = scaling_factor < 0.00000001 ? 0.0 : 1.0 / scaling_factor;
this->step_height = scaling_factor * height_factor;
}
void FractalNoise::setSlope(double slope_factor)
{
void FractalNoise::setSlope(double slope_factor) {
this->slope = slope_factor;
}
void FractalNoise::setRidge(double ridge_factor)
{
void FractalNoise::setRidge(double ridge_factor) {
this->ridge = ridge_factor;
}
void FractalNoise::setState(const NoiseState &state)
{
void FractalNoise::setState(const NoiseState &state) {
state.copy(&this->state);
}
double FractalNoise::get1d(double detail, double x) const
{
double FractalNoise::get1d(double detail, double x) const {
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
int state_level_count = state.level_offsets.size();
int i = 0;
while (current_height >= detail)
{
while (current_height >= detail) {
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
result += getBase1d(offset.x + x * current_scaling) * current_height;
@ -59,8 +50,7 @@ double FractalNoise::get1d(double detail, double x) const
current_height *= step_height;
i++;
if (i >= state_level_count)
{
if (i >= state_level_count) {
i = 0;
}
}
@ -68,16 +58,14 @@ double FractalNoise::get1d(double detail, double x) const
return result;
}
double FractalNoise::get2d(double detail, double x, double y) const
{
double FractalNoise::get2d(double detail, double x, double y) const {
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
int state_level_count = state.level_offsets.size();
int i = 0;
while (current_height >= detail)
{
while (current_height >= detail) {
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
result += getBase2d(offset.x + x * current_scaling, offset.y + y * current_scaling) * current_height;
@ -86,8 +74,7 @@ double FractalNoise::get2d(double detail, double x, double y) const
current_height *= step_height;
i++;
if (i >= state_level_count)
{
if (i >= state_level_count) {
i = 0;
}
}
@ -95,26 +82,25 @@ double FractalNoise::get2d(double detail, double x, double y) const
return result;
}
double FractalNoise::get3d(double detail, double x, double y, double z) const
{
double FractalNoise::get3d(double detail, double x, double y, double z) const {
double current_scaling = scaling;
double current_height = height;
double result = 0.0;
int state_level_count = state.level_offsets.size();
int i = 0;
while (current_height >= detail)
{
while (current_height >= detail) {
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
result += getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) * current_height;
result +=
getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) *
current_height;
current_scaling *= step_scaling;
current_height *= step_height;
i++;
if (i >= state_level_count)
{
if (i >= state_level_count) {
i = 0;
}
}
@ -122,12 +108,10 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const
return result;
}
double FractalNoise::getBase1d(double x) const
{
double FractalNoise::getBase1d(double x) const {
return getBase2d(x, 0.0);
}
double FractalNoise::getBase2d(double x, double y) const
{
double FractalNoise::getBase2d(double x, double y) const {
return getBase3d(x, y, 0.0);
}

View file

@ -11,14 +11,13 @@ namespace basics {
/*!
* \brief Fractal noise generator, based on a sum of simple noise functions.
*/
class BASICSSHARED_EXPORT FractalNoise
{
public:
class BASICSSHARED_EXPORT FractalNoise {
public:
FractalNoise();
virtual ~FractalNoise();
void setScaling(double scaling, double height=1.0);
void setStep(double scaling_factor, double height_factor=1.0);
void setScaling(double scaling, double height = 1.0);
void setStep(double scaling_factor, double height_factor = 1.0);
void setSlope(double slope_factor);
void setRidge(double ridge_factor);
void setState(const NoiseState &state);
@ -31,7 +30,7 @@ public:
virtual double getBase2d(double x, double y) const;
virtual double getBase3d(double x, double y, double z) const = 0;
private:
private:
NoiseState state;
double scaling;
@ -41,7 +40,6 @@ private:
double slope;
double ridge;
};
}
}

View file

@ -3,22 +3,15 @@
#include <cmath>
#include "Vector3.h"
double Geometry::get2DAngle(double x, double y)
{
double Geometry::get2DAngle(double x, double y) {
double nx, ny, d, ret;
if (x == 0.0)
{
if (y == 0.0)
{
if (x == 0.0) {
if (y == 0.0) {
return 0.0;
}
else if (y < 0.0)
{
} else if (y < 0.0) {
return 3.0 * M_PI_2;
}
else
{
} else {
return M_PI_2;
}
}
@ -28,54 +21,46 @@ double Geometry::get2DAngle(double x, double y)
ny = y / d;
ret = asin(ny);
if (nx < 0.0)
{
if (nx < 0.0) {
ret = M_PI - ret;
}
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
}
Vector3 Geometry::getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right)
{
Vector3 Geometry::getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right) {
Vector3 dx = right.sub(center);
Vector3 dz = bottom.sub(center);
return dz.crossProduct(dx).normalize();
}
double Geometry::getDistance2D(double x1, double y1, double x2, double y2)
{
double Geometry::getDistance2D(double x1, double y1, double x2, double y2) {
double dx = x2 - x1;
double dy = y2 - y1;
return sqrt(dx * dx + dy * dy);
}
int Geometry::rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center, double sphere_radius, Vector3 *hit1, Vector3 *hit2)
{
int Geometry::rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center,
double sphere_radius, Vector3 *hit1, Vector3 *hit2) {
Vector3 ray_direction_sphere = ray_point.sub(sphere_center);
double a, b, c, d;
a = ray_direction.x * ray_direction.x + ray_direction.y * ray_direction.y + ray_direction.z * ray_direction.z;
b = 2 * (ray_direction.x * ray_direction_sphere.x + ray_direction.y * ray_direction_sphere.y + ray_direction.z * ray_direction_sphere.z);
c = ray_direction_sphere.x * ray_direction_sphere.x + ray_direction_sphere.y * ray_direction_sphere.y + ray_direction_sphere.z * ray_direction_sphere.z - sphere_radius * sphere_radius;
b = 2 * (ray_direction.x * ray_direction_sphere.x + ray_direction.y * ray_direction_sphere.y +
ray_direction.z * ray_direction_sphere.z);
c = ray_direction_sphere.x * ray_direction_sphere.x + ray_direction_sphere.y * ray_direction_sphere.y +
ray_direction_sphere.z * ray_direction_sphere.z - sphere_radius * sphere_radius;
d = b * b - 4 * a * c;
if (d < 0.0)
{
if (d < 0.0) {
return 0;
}
else if (d > 0.0)
{
if (hit1 && hit2)
{
} else if (d > 0.0) {
if (hit1 && hit2) {
*hit1 = ray_point.add(ray_direction.scale((-b - sqrt(d)) / (2 * a)));
*hit2 = ray_point.add(ray_direction.scale((-b + sqrt(d)) / (2 * a)));
}
return 2;
}
else
{
if (hit1)
{
} else {
if (hit1) {
*hit1 = ray_point.add(ray_direction.scale(-b / (2 * a)));
}
return 1;

View file

@ -6,15 +6,14 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Geometry
{
public:
class BASICSSHARED_EXPORT Geometry {
public:
static double get2DAngle(double x, double y);
static Vector3 getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right);
static double getDistance2D(double x1, double y1, double x2, double y2);
static int rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center, double sphere_radius, Vector3 *hit1, Vector3 *hit2);
static int rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center,
double sphere_radius, Vector3 *hit1, Vector3 *hit2);
};
}
}

View file

@ -4,17 +4,14 @@
#define EPS 1E-8
InfiniteCylinder::InfiniteCylinder()
{
InfiniteCylinder::InfiniteCylinder() {
}
InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius):
axis(axis), radius(radius)
{
InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius) : axis(axis), radius(radius) {
}
int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
{
int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
Vector3 *second_intersection) const {
/*
* Original algorithm has been altered, because it didn't work with non-(0,0,0) axis origin.
* Maybe some optimizations could be made from this.
@ -27,108 +24,108 @@ int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *firs
/* choose U, V so that U,V,F is orthonormal set */
if ( fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z) )
{
length = sqrt(F.x*F.x+F.y*F.y);
invLength = 1.0/length;
U.x = -F.y*invLength;
U.y = +F.x*invLength;
if (fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z)) {
length = sqrt(F.x * F.x + F.y * F.y);
invLength = 1.0 / length;
U.x = -F.y * invLength;
U.y = +F.x * invLength;
U.z = 0.0;
prod = -F.z*invLength;
V.x = F.x*prod;
V.y = F.y*prod;
prod = -F.z * invLength;
V.x = F.x * prod;
V.y = F.y * prod;
V.z = length;
}
else
{
length = sqrt(F.y*F.y+F.z*F.z);
invLength = 1.0/length;
} else {
length = sqrt(F.y * F.y + F.z * F.z);
invLength = 1.0 / length;
U.x = 0.0;
U.y = -F.z*invLength;
U.z = +F.y*invLength;
prod = -F.x*invLength;
U.y = -F.z * invLength;
U.z = +F.y * invLength;
prod = -F.x * invLength;
V.x = length;
V.y = F.y*prod;
V.z = F.z*prod;
V.y = F.y * prod;
V.z = F.z * prod;
}
/* orthonormal matrix */
R[0][0] = U.x; R[0][1] = U.y; R[0][2] = U.z;
R[1][0] = V.x; R[1][1] = V.y; R[1][2] = V.z;
R[2][0] = F.x; R[2][1] = F.y; R[2][2] = F.z;
R[0][0] = U.x;
R[0][1] = U.y;
R[0][2] = U.z;
R[1][0] = V.x;
R[1][1] = V.y;
R[1][2] = V.z;
R[2][0] = F.x;
R[2][1] = F.y;
R[2][2] = F.z;
/* matrix A */
A[0][0] = R[0][0]*R[0][0]+R[1][0]*R[1][0];
A[0][1] = R[0][0]*R[0][1]+R[1][0]*R[1][1];
A[0][2] = R[0][0]*R[0][2]+R[1][0]*R[1][2];
A[0][0] = R[0][0] * R[0][0] + R[1][0] * R[1][0];
A[0][1] = R[0][0] * R[0][1] + R[1][0] * R[1][1];
A[0][2] = R[0][0] * R[0][2] + R[1][0] * R[1][2];
A[1][0] = R[0][1]*R[0][0]+R[1][1]*R[1][0];
A[1][1] = R[0][1]*R[0][1]+R[1][1]*R[1][1];
A[1][2] = R[0][1]*R[0][2]+R[1][1]*R[1][2];
A[1][0] = R[0][1] * R[0][0] + R[1][1] * R[1][0];
A[1][1] = R[0][1] * R[0][1] + R[1][1] * R[1][1];
A[1][2] = R[0][1] * R[0][2] + R[1][1] * R[1][2];
A[2][0] = R[0][2]*R[0][0]+R[1][2]*R[1][0];
A[2][1] = R[0][2]*R[0][1]+R[1][2]*R[1][1];
A[2][2] = R[0][2]*R[0][2]+R[1][2]*R[1][2];
A[2][0] = R[0][2] * R[0][0] + R[1][2] * R[1][0];
A[2][1] = R[0][2] * R[0][1] + R[1][2] * R[1][1];
A[2][2] = R[0][2] * R[0][2] + R[1][2] * R[1][2];
/* vector B */
P = Vector3(0.0, 0.0, 0.0);
B.x = -2.0*P.x; B.y = -2.0*P.y; B.z = -2.0*P.z;
B.x = -2.0 * P.x;
B.y = -2.0 * P.y;
B.z = -2.0 * P.z;
/* constant C */
e0 = -2.0*(R[0][0]*P.x+R[0][1]*P.y+R[0][2]*P.z);
e1 = -2.0*(R[1][0]*P.x+R[1][1]*P.y+R[1][2]*P.z);
C = 0.25*(e0*e0+e1*e1) - radius*radius;
e0 = -2.0 * (R[0][0] * P.x + R[0][1] * P.y + R[0][2] * P.z);
e1 = -2.0 * (R[1][0] * P.x + R[1][1] * P.y + R[1][2] * P.z);
C = 0.25 * (e0 * e0 + e1 * e1) - radius * radius;
/* line */
Q = ray.getOrigin().sub(axis.getOrigin());
G = ray.getDirection();
/* compute A*G */
AG.x = A[0][0]*G.x+A[0][1]*G.y+A[0][2]*G.z;
AG.y = A[1][0]*G.x+A[1][1]*G.y+A[1][2]*G.z;
AG.z = A[2][0]*G.x+A[2][1]*G.y+A[2][2]*G.z;
AG.x = A[0][0] * G.x + A[0][1] * G.y + A[0][2] * G.z;
AG.y = A[1][0] * G.x + A[1][1] * G.y + A[1][2] * G.z;
AG.z = A[2][0] * G.x + A[2][1] * G.y + A[2][2] * G.z;
/* compute A*Q */
AQ.x = A[0][0]*Q.x+A[0][1]*Q.y+A[0][2]*Q.z;
AQ.y = A[1][0]*Q.x+A[1][1]*Q.y+A[1][2]*Q.z;
AQ.z = A[2][0]*Q.x+A[2][1]*Q.y+A[2][2]*Q.z;
AQ.x = A[0][0] * Q.x + A[0][1] * Q.y + A[0][2] * Q.z;
AQ.y = A[1][0] * Q.x + A[1][1] * Q.y + A[1][2] * Q.z;
AQ.z = A[2][0] * Q.x + A[2][1] * Q.y + A[2][2] * Q.z;
/* compute quadratic equation c0+c1*t+c2*t^2 = 0 */
c2 = G.x*AG.x+G.y*AG.y+G.z*AG.z;
c1 = B.x*G.x+B.y*G.y+B.z*G.z+2.0f*(Q.x*AG.x+Q.y*AG.y+Q.z*AG.z);
c0 = Q.x*AQ.x+Q.y*AQ.y+Q.z*AQ.z+B.x*Q.x+B.y*Q.y+B.z*Q.z+C;
c2 = G.x * AG.x + G.y * AG.y + G.z * AG.z;
c1 = B.x * G.x + B.y * G.y + B.z * G.z + 2.0f * (Q.x * AG.x + Q.y * AG.y + Q.z * AG.z);
c0 = Q.x * AQ.x + Q.y * AQ.y + Q.z * AQ.z + B.x * Q.x + B.y * Q.y + B.z * Q.z + C;
/* solve for intersections */
int numIntersections;
discr = c1*c1-4.0*c0*c2;
if ( discr > EPS )
{
discr = c1 * c1 - 4.0 * c0 * c2;
if (discr > EPS) {
numIntersections = 2;
discr = sqrt(discr);
invC2 = 1.0/c2;
root0 = -0.5*(c1+discr)*invC2;
root1 = -0.5*(c1-discr)*invC2;
first_intersection->x = Q.x+root0*G.x;
first_intersection->y = Q.y+root0*G.y;
first_intersection->z = Q.z+root0*G.z;
second_intersection->x = Q.x+root1*G.x;
second_intersection->y = Q.y+root1*G.y;
second_intersection->z = Q.z+root1*G.z;
invC2 = 1.0 / c2;
root0 = -0.5 * (c1 + discr) * invC2;
root1 = -0.5 * (c1 - discr) * invC2;
first_intersection->x = Q.x + root0 * G.x;
first_intersection->y = Q.y + root0 * G.y;
first_intersection->z = Q.z + root0 * G.z;
second_intersection->x = Q.x + root1 * G.x;
second_intersection->y = Q.y + root1 * G.y;
second_intersection->z = Q.z + root1 * G.z;
*first_intersection = first_intersection->add(axis.getOrigin());
*second_intersection = second_intersection->add(axis.getOrigin());
}
else if ( discr < -EPS )
{
} else if (discr < -EPS) {
numIntersections = 0;
}
else
{
} else {
numIntersections = 1;
root = -0.5*c1/c2;
first_intersection->x = Q.x+root*G.x;
first_intersection->y = Q.y+root*G.y;
first_intersection->z = Q.z+root*G.z;
root = -0.5 * c1 / c2;
first_intersection->x = Q.x + root * G.x;
first_intersection->y = Q.y + root * G.y;
first_intersection->z = Q.z + root * G.z;
*first_intersection = first_intersection->add(axis.getOrigin());
}
@ -136,14 +133,12 @@ int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *firs
return numIntersections;
}
void InfiniteCylinder::save(PackStream *stream) const
{
void InfiniteCylinder::save(PackStream *stream) const {
axis.save(stream);
stream->write(&radius);
}
void InfiniteCylinder::load(PackStream *stream)
{
void InfiniteCylinder::load(PackStream *stream) {
axis.load(stream);
stream->read(&radius);
}

View file

@ -11,30 +11,32 @@ namespace basics {
/**
* Geometric cylinder, with infinite length.
*/
class BASICSSHARED_EXPORT InfiniteCylinder
{
public:
class BASICSSHARED_EXPORT InfiniteCylinder {
public:
InfiniteCylinder();
InfiniteCylinder(const InfiniteRay &axis, double radius);
inline const InfiniteRay& getAxis() const {return axis;}
inline double getRadius() const {return radius;}
inline const InfiniteRay &getAxis() const {
return axis;
}
inline double getRadius() const {
return radius;
}
/**
* Check the intersection between the cylinder and an infinite ray.
*
* Returns the number of intersections (0, 1 or 2) and fill the intersection points.
*/
int checkRayIntersection(const InfiniteRay& ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
int checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
virtual void save(PackStream *stream) const;
virtual void load(PackStream *stream);
protected:
protected:
InfiniteRay axis;
double radius;
};
}
}

View file

@ -3,28 +3,20 @@
#include "PackStream.h"
#include "InfiniteRay.h"
InfinitePlane::InfinitePlane()
{
InfinitePlane::InfinitePlane() {
}
InfinitePlane::InfinitePlane(const Vector3 &point, const Vector3 &normal):
point(point), normal(normal)
{
InfinitePlane::InfinitePlane(const Vector3 &point, const Vector3 &normal) : point(point), normal(normal) {
}
int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const
{
int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const {
Vector3 p1 = ray.getDirection();
double d = normal.dotProduct(p1);
if (fabs(d) < 1e-8)
{
if (normal.dotProduct(ray.getPointAtCursor(1.0).sub(point)) == 0)
{
if (fabs(d) < 1e-8) {
if (normal.dotProduct(ray.getPointAtCursor(1.0).sub(point)) == 0) {
return -1;
}
else
{
} else {
return 0;
}
}
@ -34,15 +26,12 @@ int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *interse
return 1;
}
void InfinitePlane::save(PackStream *stream) const
{
void InfinitePlane::save(PackStream *stream) const {
point.save(stream);
normal.save(stream);
}
void InfinitePlane::load(PackStream *stream)
{
void InfinitePlane::load(PackStream *stream) {
point.load(stream);
normal.load(stream);
}

View file

@ -11,9 +11,8 @@ namespace basics {
/**
* Infinite 3d geometric plane.
*/
class BASICSSHARED_EXPORT InfinitePlane
{
public:
class BASICSSHARED_EXPORT InfinitePlane {
public:
InfinitePlane();
InfinitePlane(const Vector3 &point, const Vector3 &normal);
@ -24,19 +23,22 @@ public:
*
* Returns -1 if the ray is on the plane, and make for an infinite number of intersection points.
*/
int checkRayIntersection(const InfiniteRay& ray, Vector3 *intersection) const;
int checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const;
inline const Vector3 &getPoint() const {return point;}
inline const Vector3 &getNormal() const {return normal;}
inline const Vector3 &getPoint() const {
return point;
}
inline const Vector3 &getNormal() const {
return normal;
}
virtual void save(PackStream *stream) const;
virtual void load(PackStream *stream);
private:
private:
Vector3 point;
Vector3 normal;
};
}
}

View file

@ -1,27 +1,22 @@
#include "InfiniteRay.h"
InfiniteRay::InfiniteRay()
{
InfiniteRay::InfiniteRay() {
}
InfiniteRay::InfiniteRay(const Vector3 &origin, const Vector3 &direction):
origin(origin), direction(direction.normalize())
{
InfiniteRay::InfiniteRay(const Vector3 &origin, const Vector3 &direction)
: origin(origin), direction(direction.normalize()) {
}
InfiniteRay InfiniteRay::fromPoints(const Vector3 &point1, const Vector3 &point2)
{
InfiniteRay InfiniteRay::fromPoints(const Vector3 &point1, const Vector3 &point2) {
return InfiniteRay(point1, point2.sub(point1).normalize());
}
void InfiniteRay::save(PackStream *stream) const
{
void InfiniteRay::save(PackStream *stream) const {
origin.save(stream);
direction.save(stream);
}
void InfiniteRay::load(PackStream *stream)
{
void InfiniteRay::load(PackStream *stream) {
origin.load(stream);
direction.load(stream);
}

View file

@ -11,28 +11,34 @@ namespace basics {
/**
* Infinite ray (line).
*/
class BASICSSHARED_EXPORT InfiniteRay
{
public:
class BASICSSHARED_EXPORT InfiniteRay {
public:
InfiniteRay();
InfiniteRay(const Vector3 &origin, const Vector3 &direction);
static InfiniteRay fromPoints(const Vector3 &point1, const Vector3 &point2);
inline const Vector3 &getOrigin() const {return origin;}
inline const Vector3 &getDirection() const {return direction;}
inline const Vector3 &getOrigin() const {
return origin;
}
inline const Vector3 &getDirection() const {
return direction;
}
inline double getCursor(const Vector3 &point) const {return point.sub(origin).dotProduct(direction);}
inline Vector3 getPointAtCursor(double distance) const {return origin.add(direction.scale(distance));}
inline double getCursor(const Vector3 &point) const {
return point.sub(origin).dotProduct(direction);
}
inline Vector3 getPointAtCursor(double distance) const {
return origin.add(direction.scale(distance));
}
void save(PackStream *stream) const;
void load(PackStream *stream);
private:
private:
Vector3 origin;
Vector3 direction;
};
}
}

View file

@ -1,7 +1,6 @@
#include "Interpolation.h"
double Interpolation::bicubic(double stencil[16], double x, double y)
{
double Interpolation::bicubic(double stencil[16], double x, double y) {
double buf_cubic_y[4];
buf_cubic_y[0] = Interpolation::cubic(stencil, x);
@ -12,15 +11,13 @@ double Interpolation::bicubic(double stencil[16], double x, double y)
return Interpolation::cubic(buf_cubic_y, y);
}
double Interpolation::bilinear(double p[4], double x, double y)
{
double Interpolation::bilinear(double p[4], double x, double y) {
double e1 = linear(p[0], p[1], x);
double e2 = linear(p[3], p[2], x);
return Interpolation::linear(e1, e2, y);
}
double Interpolation::trilinear(double p[8], double x, double y, double z)
{
double Interpolation::trilinear(double p[8], double x, double y, double z) {
double f1 = bilinear(p, x, y);
double f2 = bilinear(p + 4, x, y);
return Interpolation::linear(f1, f2, z);

View file

@ -6,23 +6,21 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Interpolation
{
public:
static inline double linear(double p1, double p2, double x)
{
class BASICSSHARED_EXPORT Interpolation {
public:
static inline double linear(double p1, double p2, double x) {
return p1 + x * (p2 - p1);
}
static double bilinear(double p[4], double x, double y);
static double trilinear(double p[8], double x, double y, double z);
static inline double cubic(double p[4], double x)
{
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
static inline double cubic(double p[4], double x) {
return p[1] +
0.5 * x * (p[2] - p[0] +
x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
}
static double bicubic(double stencil[16], double x, double y);
};
}
}

View file

@ -4,15 +4,13 @@
#include "PackStream.h"
#include "Vector3.h"
Matrix4::Matrix4(bool identity)
{
Matrix4::Matrix4(bool identity) {
b = c = d = e = g = h = 0.0;
i = j = l = m = n = o = 0.0;
a = f = k = p = (identity ? 1.0 : 0.0);
}
void Matrix4::save(PackStream* stream) const
{
void Matrix4::save(PackStream *stream) const {
stream->write(&a);
stream->write(&b);
stream->write(&c);
@ -31,8 +29,7 @@ void Matrix4::save(PackStream* stream) const
stream->write(&p);
}
void Matrix4::load(PackStream* stream)
{
void Matrix4::load(PackStream *stream) {
stream->read(&a);
stream->read(&b);
stream->read(&c);
@ -51,8 +48,7 @@ void Matrix4::load(PackStream* stream)
stream->read(&p);
}
Matrix4 Matrix4::mult(const Matrix4 &other) const
{
Matrix4 Matrix4::mult(const Matrix4 &other) const {
Matrix4 result;
result.a = a * other.a + b * other.e + c * other.i + d * other.m;
result.b = a * other.b + b * other.f + c * other.j + d * other.n;
@ -73,8 +69,7 @@ Matrix4 Matrix4::mult(const Matrix4 &other) const
return result;
}
Vector3 Matrix4::multPoint(const Vector3 &v) const
{
Vector3 Matrix4::multPoint(const Vector3 &v) const {
Vector3 result;
result.x = a * v.x + b * v.y + c * v.z + d;
result.y = e * v.x + f * v.y + g * v.z + h;
@ -82,30 +77,19 @@ Vector3 Matrix4::multPoint(const Vector3 &v) const
return result;
}
Vector3 Matrix4::transform(const Vector3 &v) const
{
Vector3 Matrix4::transform(const Vector3 &v) const {
double w = m * v.x + n * v.y + o * v.z + p;
if (w != 0.0)
{
if (w != 0.0) {
w = 1.0 / w;
return Vector3(
(a * v.x + b * v.y + c * v.z + d) * w,
(e * v.x + f * v.y + g * v.z + h) * w,
(i * v.x + j * v.y + k * v.z + l) * w
);
}
else
{
return Vector3(
a * v.x + b * v.y + c * v.z + d,
e * v.x + f * v.y + g * v.z + h,
i * v.x + j * v.y + k * v.z + l
);
return Vector3((a * v.x + b * v.y + c * v.z + d) * w, (e * v.x + f * v.y + g * v.z + h) * w,
(i * v.x + j * v.y + k * v.z + l) * w);
} else {
return Vector3(a * v.x + b * v.y + c * v.z + d, e * v.x + f * v.y + g * v.z + h,
i * v.x + j * v.y + k * v.z + l);
}
}
Matrix4 Matrix4::transposed() const
{
Matrix4 Matrix4::transposed() const {
Matrix4 result;
result.a = a;
result.e = b;
@ -126,8 +110,7 @@ Matrix4 Matrix4::transposed() const
return result;
}
Matrix4 Matrix4::newScale(double x, double y, double z)
{
Matrix4 Matrix4::newScale(double x, double y, double z) {
Matrix4 result;
result.a = x;
result.f = y;
@ -135,8 +118,7 @@ Matrix4 Matrix4::newScale(double x, double y, double z)
return result;
}
Matrix4 Matrix4::newTranslate(double x, double y, double z)
{
Matrix4 Matrix4::newTranslate(double x, double y, double z) {
Matrix4 result;
result.d = x;
result.h = y;
@ -144,8 +126,7 @@ Matrix4 Matrix4::newTranslate(double x, double y, double z)
return result;
}
Matrix4 Matrix4::newRotateX(double angle)
{
Matrix4 Matrix4::newRotateX(double angle) {
Matrix4 result;
double si = sin(angle);
double co = cos(angle);
@ -155,8 +136,7 @@ Matrix4 Matrix4::newRotateX(double angle)
return result;
}
Matrix4 Matrix4::newRotateY(double angle)
{
Matrix4 Matrix4::newRotateY(double angle) {
Matrix4 result;
double si = sin(angle);
double co = cos(angle);
@ -166,8 +146,7 @@ Matrix4 Matrix4::newRotateY(double angle)
return result;
}
Matrix4 Matrix4::newRotateZ(double angle)
{
Matrix4 Matrix4::newRotateZ(double angle) {
Matrix4 result;
double si = sin(angle);
double co = cos(angle);
@ -177,8 +156,7 @@ Matrix4 Matrix4::newRotateZ(double angle)
return result;
}
Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis)
{
Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis) {
Matrix4 result;
double si = sin(angle);
double co = cos(angle);
@ -196,8 +174,7 @@ Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis)
return result;
}
Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank)
{
Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank) {
Matrix4 result;
double ch = cos(heading);
double sh = sin(heading);
@ -217,8 +194,7 @@ Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank)
return result;
}
Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const Vector3 &z)
{
Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const Vector3 &z) {
Matrix4 result;
result.a = x.x;
result.b = y.x;
@ -232,8 +208,7 @@ Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const V
return result;
}
Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up)
{
Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up) {
Vector3 z = at.sub(eye).normalize();
Vector3 x = up.crossProduct(z).normalize();
Vector3 y = z.crossProduct(x);
@ -244,8 +219,7 @@ Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3
return result.inversed();
}
Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double far)
{
Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double far) {
Matrix4 result;
double fo = 1 / tan(fov_y / 2.0);
result.a = fo / aspect;
@ -257,29 +231,16 @@ Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double
return result;
}
double Matrix4::getDeterminant() const
{
return ((a * f - e * b)
* (k * p - o * l)
- (a * j - i * b)
* (g * p - o * h)
+ (a * n - m * b)
* (g * l - k * h)
+ (e * j - i * f)
* (c * p - o * d)
- (e * n - m * f)
* (c * l - k * d)
+ (i * n - m * j)
* (c * h - g * d));
double Matrix4::getDeterminant() const {
return ((a * f - e * b) * (k * p - o * l) - (a * j - i * b) * (g * p - o * h) + (a * n - m * b) * (g * l - k * h) +
(e * j - i * f) * (c * p - o * d) - (e * n - m * f) * (c * l - k * d) + (i * n - m * j) * (c * h - g * d));
}
Matrix4 Matrix4::inversed() const
{
Matrix4 Matrix4::inversed() const {
Matrix4 result;
double det = getDeterminant();
if (fabs(det) >= 0.00001)
{
if (fabs(det) >= 0.00001) {
det = 1.0 / det;
result.a = det * (f * (k * p - o * l) + j * (o * h - g * p) + n * (g * l - k * h));
@ -301,7 +262,6 @@ Matrix4 Matrix4::inversed() const
result.h = det * (c * (i * h - e * l) + g * (a * l - i * d) + k * (e * d - a * h));
result.l = det * (d * (i * f - e * j) + h * (a * j - i * b) + l * (e * b - a * f));
result.p = det * (a * (f * k - j * g) + e * (j * c - b * k) + i * (b * g - f * c));
}
return result;

View file

@ -10,13 +10,12 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Matrix4
{
public:
Matrix4(bool identity=true);
class BASICSSHARED_EXPORT Matrix4 {
public:
Matrix4(bool identity = true);
void save(PackStream* stream) const;
void load(PackStream* stream);
void save(PackStream *stream) const;
void load(PackStream *stream);
Matrix4 mult(const Matrix4 &other) const;
Vector3 multPoint(const Vector3 &v) const;
@ -39,14 +38,11 @@ public:
#ifdef QT_GUI_LIB
inline QMatrix4x4 toQMatrix() const {
return QMatrix4x4(a, b, c, d,
e, f, g, h,
i, j, k, l,
m, n, o, p);
return QMatrix4x4(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
}
#endif
private:
private:
double a;
double b;
double c;
@ -64,7 +60,6 @@ private:
double o;
double p;
};
}
}

View file

@ -9,15 +9,14 @@
#include <cstdlib>
#include <cmath>
NoiseFunctionPerlin::NoiseFunctionPerlin()
{
NoiseFunctionPerlin::NoiseFunctionPerlin() {
}
#define B 0x100
#define BM 0xff
#define N 0x1000
#define NP 12 /* 2^N */
#define NP 12 /* 2^N */
#define NM 0xfff
static int p[B + B + 2];
@ -25,108 +24,117 @@ static double g3[B + B + 2][3];
static double g2[B + B + 2][2];
static double g1[B + B + 2];
#define s_curve(t) ( t * t * (3. - 2. * t) )
#define s_curve(t) (t * t * (3. - 2. * t))
#define lerp(t, a, b) ( a + t * (b - a) )
#define lerp(t, a, b) (a + t * (b - a))
#define setup(i,b0,b1,r0,r1)\
t = vec[i] + N;\
b0 = ((int)t) & BM;\
b1 = (b0+1) & BM;\
r0 = t - (int)t;\
#define setup(i, b0, b1, r0, r1) \
t = vec[i] + N; \
b0 = ((int)t) & BM; \
b1 = (b0 + 1) & BM; \
r0 = t - (int)t; \
r1 = r0 - 1.;
double noisePerlinGet1DValue(double x)
{
double vec[1] = {x*2.0};
double noisePerlinGet1DValue(double x) {
double vec[1] = {x * 2.0};
int bx0, bx1;
double rx0, rx1, sx, t, u, v;
setup(0, bx0,bx1, rx0,rx1);
setup(0, bx0, bx1, rx0, rx1);
sx = s_curve(rx0);
u = rx0 * g1[ p[ bx0 ] ];
v = rx1 * g1[ p[ bx1 ] ];
u = rx0 * g1[p[bx0]];
v = rx1 * g1[p[bx1]];
return lerp(sx, u, v) * 1.068 + 0.5;
}
double noisePerlinGet2DValue(double x, double y)
{
double vec[2] = {x*2.0, y*2.0};
double noisePerlinGet2DValue(double x, double y) {
double vec[2] = {x * 2.0, y * 2.0};
int bx0, bx1, by0, by1, b00, b10, b01, b11;
double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
int i, j;
setup(0, bx0,bx1, rx0,rx1);
setup(1, by0,by1, ry0,ry1);
setup(0, bx0, bx1, rx0, rx1);
setup(1, by0, by1, ry0, ry1);
i = p[ bx0 ];
j = p[ bx1 ];
i = p[bx0];
j = p[bx1];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
b00 = p[i + by0];
b10 = p[j + by0];
b01 = p[i + by1];
b11 = p[j + by1];
sx = s_curve(rx0);
sy = s_curve(ry0);
#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
#define at2(rx, ry) (rx * q[0] + ry * q[1])
q = g2[ b00 ] ; u = at2(rx0,ry0);
q = g2[ b10 ] ; v = at2(rx1,ry0);
q = g2[b00];
u = at2(rx0, ry0);
q = g2[b10];
v = at2(rx1, ry0);
a = lerp(sx, u, v);
q = g2[ b01 ] ; u = at2(rx0,ry1);
q = g2[ b11 ] ; v = at2(rx1,ry1);
q = g2[b01];
u = at2(rx0, ry1);
q = g2[b11];
v = at2(rx1, ry1);
b = lerp(sx, u, v);
return lerp(sy, a, b) * 0.709 + 0.5;
}
double noisePerlinGet3DValue(double x, double y, double z)
{
double vec[3] = {x*2.0, y*2.0, z*2.0};
double noisePerlinGet3DValue(double x, double y, double z) {
double vec[3] = {x * 2.0, y * 2.0, z * 2.0};
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
int i, j;
setup(0, bx0,bx1, rx0,rx1);
setup(1, by0,by1, ry0,ry1);
setup(2, bz0,bz1, rz0,rz1);
setup(0, bx0, bx1, rx0, rx1);
setup(1, by0, by1, ry0, ry1);
setup(2, bz0, bz1, rz0, rz1);
i = p[ bx0 ];
j = p[ bx1 ];
i = p[bx0];
j = p[bx1];
b00 = p[ i + by0 ];
b10 = p[ j + by0 ];
b01 = p[ i + by1 ];
b11 = p[ j + by1 ];
b00 = p[i + by0];
b10 = p[j + by0];
b01 = p[i + by1];
b11 = p[j + by1];
t = s_curve(rx0);
t = s_curve(rx0);
sy = s_curve(ry0);
sz = s_curve(rz0);
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
#define at3(rx, ry, rz) (rx * q[0] + ry * q[1] + rz * q[2])
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
q = g3[b00 + bz0];
u = at3(rx0, ry0, rz0);
q = g3[b10 + bz0];
v = at3(rx1, ry0, rz0);
a = lerp(t, u, v);
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
q = g3[b01 + bz0];
u = at3(rx0, ry1, rz0);
q = g3[b11 + bz0];
v = at3(rx1, ry1, rz0);
b = lerp(t, u, v);
c = lerp(sy, a, b);
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
q = g3[b00 + bz1];
u = at3(rx0, ry0, rz1);
q = g3[b10 + bz1];
v = at3(rx1, ry0, rz1);
a = lerp(t, u, v);
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
q = g3[b01 + bz1];
u = at3(rx0, ry1, rz1);
q = g3[b11 + bz1];
v = at3(rx1, ry1, rz1);
b = lerp(t, u, v);
d = lerp(sy, a, b);
@ -134,8 +142,7 @@ double noisePerlinGet3DValue(double x, double y, double z)
return lerp(sz, c, d) * 0.661 + 0.5;
}
static void _normalize2(double v[2])
{
static void _normalize2(double v[2]) {
double s;
s = sqrt(v[0] * v[0] + v[1] * v[1]);
@ -143,8 +150,7 @@ static void _normalize2(double v[2])
v[1] = v[1] / s;
}
static void _normalize3(double v[3])
{
static void _normalize3(double v[3]) {
double s;
s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
@ -153,20 +159,19 @@ static void _normalize3(double v[3])
v[2] = v[2] / s;
}
static int noisePerlinInit(void)
{
static int noisePerlinInit(void) {
int i, j, k;
for (i = 0 ; i < B ; i++) {
for (i = 0; i < B; i++) {
p[i] = i;
g1[i] = (double)((rand() % (B + B)) - B) / B;
for (j = 0 ; j < 2 ; j++)
for (j = 0; j < 2; j++)
g2[i][j] = (double)((rand() % (B + B)) - B) / B;
_normalize2(g2[i]);
for (j = 0 ; j < 3 ; j++)
for (j = 0; j < 3; j++)
g3[i][j] = (double)((rand() % (B + B)) - B) / B;
_normalize3(g3[i]);
}
@ -177,12 +182,12 @@ static int noisePerlinInit(void)
p[j] = k;
}
for (i = 0 ; i < B + 2 ; i++) {
for (i = 0; i < B + 2; i++) {
p[B + i] = p[i];
g1[B + i] = g1[i];
for (j = 0 ; j < 2 ; j++)
for (j = 0; j < 2; j++)
g2[B + i][j] = g2[i][j];
for (j = 0 ; j < 3 ; j++)
for (j = 0; j < 3; j++)
g3[B + i][j] = g3[i][j];
}

View file

@ -6,12 +6,10 @@
namespace paysages {
namespace basics {
class NoiseFunctionPerlin
{
public:
class NoiseFunctionPerlin {
public:
NoiseFunctionPerlin();
};
}
}

View file

@ -14,84 +14,78 @@
#include "Geometry.h"
#include "Vector3.h"
typedef struct
{
typedef struct {
double x;
double y;
double z;
} Grad3;
typedef struct
{
typedef struct {
double x;
double y;
double z;
double w;
} Grad4;
static Grad3 _grad3[] = {
{1, 1, 0},
{-1, 1, 0},
{1, -1, 0},
{-1, -1, 0},
{1, 0, 1},
{-1, 0, 1},
{1, 0, -1},
{-1, 0, -1},
{0, 1, 1},
{0, -1, 1},
{0, 1, -1},
{0, -1, -1}
};
static Grad3 _grad3[] = {{1, 1, 0},
{-1, 1, 0},
{1, -1, 0},
{-1, -1, 0},
{1, 0, 1},
{-1, 0, 1},
{1, 0, -1},
{-1, 0, -1},
{0, 1, 1},
{0, -1, 1},
{0, 1, -1},
{0, -1, -1}};
static Grad4 _grad4[] = {
{0, 1, 1, 1},
{0, 1, 1, -1},
{0, 1, -1, 1},
{0, 1, -1, -1},
{0, -1, 1, 1},
{0, -1, 1, -1},
{0, -1, -1, 1},
{0, -1, -1, -1},
{1, 0, 1, 1},
{1, 0, 1, -1},
{1, 0, -1, 1},
{1, 0, -1, -1},
{-1, 0, 1, 1},
{-1, 0, 1, -1},
{-1, 0, -1, 1},
{-1, 0, -1, -1},
{1, 1, 0, 1},
{1, 1, 0, -1},
{1, -1, 0, 1},
{1, -1, 0, -1},
{-1, 1, 0, 1},
{-1, 1, 0, -1},
{-1, -1, 0, 1},
{-1, -1, 0, -1},
{1, 1, 1, 0},
{1, 1, -1, 0},
{1, -1, 1, 0},
{1, -1, -1, 0},
{-1, 1, 1, 0},
{-1, 1, -1, 0},
{-1, -1, 1, 0},
{-1, -1, -1, 0}
};
static Grad4 _grad4[] = {{0, 1, 1, 1},
{0, 1, 1, -1},
{0, 1, -1, 1},
{0, 1, -1, -1},
{0, -1, 1, 1},
{0, -1, 1, -1},
{0, -1, -1, 1},
{0, -1, -1, -1},
{1, 0, 1, 1},
{1, 0, 1, -1},
{1, 0, -1, 1},
{1, 0, -1, -1},
{-1, 0, 1, 1},
{-1, 0, 1, -1},
{-1, 0, -1, 1},
{-1, 0, -1, -1},
{1, 1, 0, 1},
{1, 1, 0, -1},
{1, -1, 0, 1},
{1, -1, 0, -1},
{-1, 1, 0, 1},
{-1, 1, 0, -1},
{-1, -1, 0, 1},
{-1, -1, 0, -1},
{1, 1, 1, 0},
{1, 1, -1, 0},
{1, -1, 1, 0},
{1, -1, -1, 0},
{-1, 1, 1, 0},
{-1, 1, -1, 0},
{-1, -1, 1, 0},
{-1, -1, -1, 0}};
static short _permutations[] = {151, 160, 137, 91, 90, 15,
131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};
static short _permutations[] = {
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142,
8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203,
117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165,
71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250,
124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34,
242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114,
67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};
static short _permutations2[512];
static short _permutationsMod12[512];
@ -102,36 +96,30 @@ static double _G3;
static double _F4;
static double _G4;
static inline int _fastfloor(double x)
{
int xi = (int) x;
static inline int _fastfloor(double x) {
int xi = (int)x;
return x < xi ? xi - 1 : xi;
}
static inline double _dot2(Grad3 g, double x, double y)
{
static inline double _dot2(Grad3 g, double x, double y) {
return g.x * x + g.y * y;
}
static inline double _dot3(Grad3 g, double x, double y, double z)
{
static inline double _dot3(Grad3 g, double x, double y, double z) {
return g.x * x + g.y * y + g.z * z;
}
static inline double _dot4(Grad4 g, double x, double y, double z, double w)
{
static inline double _dot4(Grad4 g, double x, double y, double z, double w) {
return g.x * x + g.y * y + g.z * z + g.w * w;
}
static int noiseSimplexInit()
{
static int noiseSimplexInit() {
int i;
/* To remove the need for index wrapping, double the permutation table length */
for (i = 0; i < 512; i++)
{
for (i = 0; i < 512; i++) {
_permutations2[i] = _permutations[i & 255];
_permutationsMod12[i] = (short) (_permutations2[i] % 12);
_permutationsMod12[i] = (short)(_permutations2[i] % 12);
}
/* Skewing and unskewing factors for 2, 3, and 4 dimensions */
@ -147,14 +135,12 @@ static int noiseSimplexInit()
static int _inited = noiseSimplexInit();
double noiseSimplexGet1DValue(double x)
{
double noiseSimplexGet1DValue(double x) {
/* TODO Find custom function */
return noiseSimplexGet2DValue(x, 0.0);
}
double noiseSimplexGet2DValue(double x, double y)
{
double noiseSimplexGet2DValue(double x, double y) {
double n0, n1, n2; /* Noise contributions from the three corners */
/* Skew the input space to determine which simplex cell we're in */
double s = (x + y) * _F2; /* Hairy factor for 2D */
@ -168,19 +154,17 @@ double noiseSimplexGet2DValue(double x, double y)
/* For the 2D case, the simplex shape is an equilateral triangle.
Determine which simplex we are in. */
int i1, j1; /* Offsets for second (middle) corner of simplex in (i,j) coords */
if (x0 > y0)
{
if (x0 > y0) {
i1 = 1;
j1 = 0;
} /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */
else
{
else {
i1 = 0;
j1 = 1;
} /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
/* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
c = (3-sqrt(3))/6 */
} /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
/* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
c = (3-sqrt(3))/6 */
double x1 = x0 - i1 + _G2; /* Offsets for middle corner in (x,y) unskewed coords */
double y1 = y0 - j1 + _G2;
double x2 = x0 - 1.0 + 2.0 * _G2; /* Offsets for last corner in (x,y) unskewed coords */
@ -192,24 +176,24 @@ double noiseSimplexGet2DValue(double x, double y)
int gi1 = _permutationsMod12[ii + i1 + _permutations2[jj + j1]];
int gi2 = _permutationsMod12[ii + 1 + _permutations2[jj + 1]];
/* Calculate the contribution from the three corners */
double t0 = 0.5 - x0 * x0 - y0*y0;
if (t0 < 0) n0 = 0.0;
else
{
double t0 = 0.5 - x0 * x0 - y0 * y0;
if (t0 < 0)
n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * _dot2(_grad3[gi0], x0, y0); /* (x,y) of _grad3 used for 2D gradient */
}
double t1 = 0.5 - x1 * x1 - y1*y1;
if (t1 < 0) n1 = 0.0;
else
{
double t1 = 0.5 - x1 * x1 - y1 * y1;
if (t1 < 0)
n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * _dot2(_grad3[gi1], x1, y1);
}
double t2 = 0.5 - x2 * x2 - y2*y2;
if (t2 < 0) n2 = 0.0;
else
{
double t2 = 0.5 - x2 * x2 - y2 * y2;
if (t2 < 0)
n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * _dot2(_grad3[gi2], x2, y2);
}
@ -218,8 +202,7 @@ double noiseSimplexGet2DValue(double x, double y)
return 35.0 * (n0 + n1 + n2) + 0.5;
}
double noiseSimplexGet3DValue(double x, double y, double z)
{
double noiseSimplexGet3DValue(double x, double y, double z) {
double n0, n1, n2, n3; /* Noise contributions from the four corners */
/* Skew the input space to determine which simplex cell we're in */
double s = (x + y + z) * _F3; /* Very nice and simple skew factor for 3D */
@ -237,10 +220,8 @@ double noiseSimplexGet3DValue(double x, double y, double z)
Determine which simplex we are in. */
int i1, j1, k1; /* Offsets for second corner of simplex in (i,j,k) coords */
int i2, j2, k2; /* Offsets for third corner of simplex in (i,j,k) coords */
if (x0 >= y0)
{
if (y0 >= z0)
{
if (x0 >= y0) {
if (y0 >= z0) {
i1 = 1;
j1 = 0;
k1 = 0;
@ -248,8 +229,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
j2 = 1;
k2 = 0;
} /* X Y Z order */
else if (x0 >= z0)
{
else if (x0 >= z0) {
i1 = 1;
j1 = 0;
k1 = 0;
@ -257,20 +237,16 @@ double noiseSimplexGet3DValue(double x, double y, double z)
j2 = 0;
k2 = 1;
} /* X Z Y order */
else
{
else {
i1 = 0;
j1 = 0;
k1 = 1;
i2 = 1;
j2 = 0;
k2 = 1;
} /* Z X Y order */
}
else
{ /* x0<y0 */
if (y0 < z0)
{
} /* Z X Y order */
} else { /* x0<y0 */
if (y0 < z0) {
i1 = 0;
j1 = 0;
k1 = 1;
@ -278,8 +254,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
j2 = 1;
k2 = 1;
} /* Z Y X order */
else if (x0 < z0)
{
else if (x0 < z0) {
i1 = 0;
j1 = 1;
k1 = 0;
@ -287,8 +262,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
j2 = 1;
k2 = 1;
} /* Y Z X order */
else
{
else {
i1 = 0;
j1 = 1;
k1 = 0;
@ -319,31 +293,31 @@ double noiseSimplexGet3DValue(double x, double y, double z)
int gi2 = _permutationsMod12[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2]]];
int gi3 = _permutationsMod12[ii + 1 + _permutations2[jj + 1 + _permutations2[kk + 1]]];
/* Calculate the contribution from the four corners */
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0*z0;
if (t0 < 0) n0 = 0.0;
else
{
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
if (t0 < 0)
n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * _dot3(_grad3[gi0], x0, y0, z0);
}
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1*z1;
if (t1 < 0) n1 = 0.0;
else
{
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
if (t1 < 0)
n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * _dot3(_grad3[gi1], x1, y1, z1);
}
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2*z2;
if (t2 < 0) n2 = 0.0;
else
{
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
if (t2 < 0)
n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * _dot3(_grad3[gi2], x2, y2, z2);
}
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3*z3;
if (t3 < 0) n3 = 0.0;
else
{
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
if (t3 < 0)
n3 = 0.0;
else {
t3 *= t3;
n3 = t3 * t3 * _dot3(_grad3[gi3], x3, y3, z3);
}
@ -352,8 +326,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
return 16.0 * (n0 + n1 + n2 + n3) + 0.5;
}
double noiseSimplexGet4DValue(double x, double y, double z, double w)
{
double noiseSimplexGet4DValue(double x, double y, double z, double w) {
double n0, n1, n2, n3, n4; /* Noise contributions from the five corners */
/* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */
double s = (x + y + z + w) * _F4; /* Factor for 4D skewing */
@ -362,7 +335,7 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
int k = _fastfloor(z + s);
int l = _fastfloor(w + s);
double t = (i + j + k + l) * _G4; /* Factor for 4D unskewing */
double X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */
double X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */
double Y0 = j - t;
double Z0 = k - t;
double W0 = l - t;
@ -379,26 +352,38 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
int ranky = 0;
int rankz = 0;
int rankw = 0;
if (x0 > y0) rankx++;
else ranky++;
if (x0 > z0) rankx++;
else rankz++;
if (x0 > w0) rankx++;
else rankw++;
if (y0 > z0) ranky++;
else rankz++;
if (y0 > w0) ranky++;
else rankw++;
if (z0 > w0) rankz++;
else rankw++;
if (x0 > y0)
rankx++;
else
ranky++;
if (x0 > z0)
rankx++;
else
rankz++;
if (x0 > w0)
rankx++;
else
rankw++;
if (y0 > z0)
ranky++;
else
rankz++;
if (y0 > w0)
ranky++;
else
rankw++;
if (z0 > w0)
rankz++;
else
rankw++;
int i1, j1, k1, l1; /* The integer offsets for the second simplex corner */
int i2, j2, k2, l2; /* The integer offsets for the third simplex corner */
int i3, j3, k3, l3; /* The integer offsets for the fourth simplex corner */
/* simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
impossible. Only the 24 indices which have non-zero entries make any sense.
We use a thresholding to set the coordinates in turn from the largest magnitude.
Rank 3 denotes the largest coordinate. */
/* simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
impossible. Only the 24 indices which have non-zero entries make any sense.
We use a thresholding to set the coordinates in turn from the largest magnitude.
Rank 3 denotes the largest coordinate. */
i1 = rankx >= 3 ? 1 : 0;
j1 = ranky >= 3 ? 1 : 0;
k1 = rankz >= 3 ? 1 : 0;
@ -436,43 +421,46 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
int kk = k & 255;
int ll = l & 255;
int gi0 = _permutations2[ii + _permutations2[jj + _permutations2[kk + _permutations2[ll]]]] % 32;
int gi1 = _permutations2[ii + i1 + _permutations2[jj + j1 + _permutations2[kk + k1 + _permutations2[ll + l1]]]] % 32;
int gi2 = _permutations2[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2 + _permutations2[ll + l2]]]] % 32;
int gi3 = _permutations2[ii + i3 + _permutations2[jj + j3 + _permutations2[kk + k3 + _permutations2[ll + l3]]]] % 32;
int gi1 =
_permutations2[ii + i1 + _permutations2[jj + j1 + _permutations2[kk + k1 + _permutations2[ll + l1]]]] % 32;
int gi2 =
_permutations2[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2 + _permutations2[ll + l2]]]] % 32;
int gi3 =
_permutations2[ii + i3 + _permutations2[jj + j3 + _permutations2[kk + k3 + _permutations2[ll + l3]]]] % 32;
int gi4 = _permutations2[ii + 1 + _permutations2[jj + 1 + _permutations2[kk + 1 + _permutations2[ll + 1]]]] % 32;
/* Calculate the contribution from the five corners */
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0*w0;
if (t0 < 0) n0 = 0.0;
else
{
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
if (t0 < 0)
n0 = 0.0;
else {
t0 *= t0;
n0 = t0 * t0 * _dot4(_grad4[gi0], x0, y0, z0, w0);
}
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1*w1;
if (t1 < 0) n1 = 0.0;
else
{
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
if (t1 < 0)
n1 = 0.0;
else {
t1 *= t1;
n1 = t1 * t1 * _dot4(_grad4[gi1], x1, y1, z1, w1);
}
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2*w2;
if (t2 < 0) n2 = 0.0;
else
{
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
if (t2 < 0)
n2 = 0.0;
else {
t2 *= t2;
n2 = t2 * t2 * _dot4(_grad4[gi2], x2, y2, z2, w2);
}
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3*w3;
if (t3 < 0) n3 = 0.0;
else
{
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
if (t3 < 0)
n3 = 0.0;
else {
t3 *= t3;
n3 = t3 * t3 * _dot4(_grad4[gi3], x3, y3, z3, w3);
}
double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4*w4;
if (t4 < 0) n4 = 0.0;
else
{
double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
if (t4 < 0)
n4 = 0.0;
else {
t4 *= t4;
n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
}
@ -480,31 +468,25 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
return 13.5 * (n0 + n1 + n2 + n3 + n4) + 0.5;
}
double NoiseFunctionSimplex::getBase2d(double x, double y) const
{
double NoiseFunctionSimplex::getBase2d(double x, double y) const {
return noiseSimplexGet2DValue(x, y);
}
double NoiseFunctionSimplex::getBase3d(double x, double y, double z) const
{
double NoiseFunctionSimplex::getBase3d(double x, double y, double z) const {
return noiseSimplexGet3DValue(x, y, z);
}
static Texture2D *_valueTexture = NULL;
const Texture2D *NoiseFunctionSimplex::getValueTexture()
{
if (!_valueTexture)
{
const Texture2D *NoiseFunctionSimplex::getValueTexture() {
if (!_valueTexture) {
const int width = 1024;
const int height = 1024;
_valueTexture = new Texture2D(width, height);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
for (int x = 0; x < width; x++) {
for (int z = 0; z < height; z++) {
double val = noiseSimplexGet2DValue((double)x, (double)z);
_valueTexture->setPixel(x, z, Color(val, val, val));
}
@ -516,27 +498,21 @@ const Texture2D *NoiseFunctionSimplex::getValueTexture()
static Texture2D *_normalTexture = NULL;
const Texture2D *NoiseFunctionSimplex::getNormalTexture()
{
if (!_normalTexture)
{
const Texture2D *NoiseFunctionSimplex::getNormalTexture() {
if (!_normalTexture) {
const int width = 1024;
const int height = 1024;
_normalTexture = new Texture2D(width, height);
for (int x = 0; x < width; x++)
{
for (int z = 0; z < height; z++)
{
for (int x = 0; x < width; x++) {
for (int z = 0; z < height; z++) {
double vcenter = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z);
double vsouth = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z + 0.001);
double veast = noiseSimplexGet2DValue(0.01 * (double)x + 0.001, 0.01 * (double)z);
Vector3 normal = Geometry::getNormalFromTriangle(Vector3(0.0, vcenter, 0.0),
Vector3(0.0, vsouth, 0.01),
Vector3(0.01, veast, 0.0)
);
Vector3 normal = Geometry::getNormalFromTriangle(Vector3(0.0, vcenter, 0.0), Vector3(0.0, vsouth, 0.01),
Vector3(0.01, veast, 0.0));
_normalTexture->setPixel(x, z, Color(normal.x, normal.y, normal.z));
}

View file

@ -8,16 +8,14 @@
namespace paysages {
namespace basics {
class NoiseFunctionSimplex:public FractalNoise
{
class NoiseFunctionSimplex : public FractalNoise {
virtual double getBase2d(double x, double y) const override;
virtual double getBase3d(double x, double y, double z) const override;
public:
public:
static const Texture2D *getValueTexture();
static const Texture2D *getNormalTexture();
};
}
}

View file

@ -13,8 +13,7 @@
/* NoiseGenerator class */
NoiseGenerator::NoiseGenerator()
{
NoiseGenerator::NoiseGenerator() {
function.algorithm = NOISE_FUNCTION_SIMPLEX;
function.ridge_factor = 0.0;
function.curve_factor = 0.0;
@ -25,12 +24,10 @@ NoiseGenerator::NoiseGenerator()
validate();
}
NoiseGenerator::~NoiseGenerator()
{
NoiseGenerator::~NoiseGenerator() {
}
void NoiseGenerator::save(PackStream* stream) const
{
void NoiseGenerator::save(PackStream *stream) const {
int x;
x = (int)function.algorithm;
@ -41,9 +38,8 @@ void NoiseGenerator::save(PackStream* stream) const
stream->write(&height_offset);
stream->write(&level_count);
for (x = 0; x < level_count; x++)
{
const NoiseLevel* level = levels + x;
for (x = 0; x < level_count; x++) {
const NoiseLevel *level = levels + x;
stream->write(&level->frequency);
stream->write(&level->amplitude);
@ -53,8 +49,7 @@ void NoiseGenerator::save(PackStream* stream) const
state.save(stream);
}
void NoiseGenerator::load(PackStream* stream)
{
void NoiseGenerator::load(PackStream *stream) {
int x;
stream->read(&x);
@ -65,14 +60,12 @@ void NoiseGenerator::load(PackStream* stream)
stream->read(&height_offset);
stream->read(&level_count);
if (level_count > MAX_LEVEL_COUNT)
{
if (level_count > MAX_LEVEL_COUNT) {
level_count = MAX_LEVEL_COUNT;
}
for (x = 0; x < level_count; x++)
{
NoiseLevel* level = levels + x;
for (x = 0; x < level_count; x++) {
NoiseLevel *level = levels + x;
stream->read(&level->frequency);
stream->read(&level->amplitude);
@ -84,8 +77,7 @@ void NoiseGenerator::load(PackStream* stream)
validate();
}
void NoiseGenerator::copy(NoiseGenerator* destination) const
{
void NoiseGenerator::copy(NoiseGenerator *destination) const {
destination->function = function;
destination->height_offset = height_offset;
destination->level_count = level_count;
@ -97,16 +89,13 @@ void NoiseGenerator::copy(NoiseGenerator* destination) const
destination->validate();
}
void NoiseGenerator::validate()
{
void NoiseGenerator::validate() {
int x;
if (function.algorithm < 0 || function.algorithm > NOISE_FUNCTION_SIMPLEX)
{
if (function.algorithm < 0 || function.algorithm > NOISE_FUNCTION_SIMPLEX) {
function.algorithm = NOISE_FUNCTION_SIMPLEX;
}
switch (function.algorithm)
{
switch (function.algorithm) {
case NOISE_FUNCTION_PERLIN:
_func_noise_1d = noisePerlinGet1DValue;
_func_noise_2d = noisePerlinGet2DValue;
@ -121,103 +110,86 @@ void NoiseGenerator::validate()
break;
}
if (function.ridge_factor > 0.5)
{
if (function.ridge_factor > 0.5) {
function.ridge_factor = 0.5;
}
if (function.ridge_factor < -0.5)
{
if (function.ridge_factor < -0.5) {
function.ridge_factor = -0.5;
}
if (function.curve_factor > 1.0)
{
if (function.curve_factor > 1.0) {
function.curve_factor = 1.0;
}
if (function.curve_factor < -1.0)
{
if (function.curve_factor < -1.0) {
function.curve_factor = -1.0;
}
_min_value = height_offset;
_max_value = height_offset;
for (x = 0; x < level_count; x++)
{
for (x = 0; x < level_count; x++) {
_min_value += levels[x].minvalue;
_max_value += levels[x].minvalue + levels[x].amplitude;
}
}
void NoiseGenerator::setState(const NoiseState &state)
{
void NoiseGenerator::setState(const NoiseState &state) {
state.copy(&this->state);
}
void NoiseGenerator::randomizeOffsets()
{
void NoiseGenerator::randomizeOffsets() {
state.randomizeOffsets();
}
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction()
{
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction() {
return function;
}
void NoiseGenerator::setFunction(NoiseFunction* function)
{
void NoiseGenerator::setFunction(NoiseFunction *function) {
this->function = *function;
validate();
}
void NoiseGenerator::setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y), double (*func3d)(double x, double y, double z))
{
void NoiseGenerator::setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
double (*func3d)(double x, double y, double z)) {
_func_noise_1d = func1d;
_func_noise_2d = func2d;
_func_noise_3d = func3d;
function.algorithm = NOISE_FUNCTION_CUSTOM;
}
void NoiseGenerator::setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor)
{
void NoiseGenerator::setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor) {
NoiseFunction function = {algorithm, ridge_factor, curve_factor};
setFunction(&function);
}
void NoiseGenerator::forceValue(double value)
{
void NoiseGenerator::forceValue(double value) {
clearLevels();
height_offset = value;
addLevelSimple(1.0, 0.0, 0.0); /* FIXME Should not be needed */
}
void NoiseGenerator::getRange(double* minvalue, double* maxvalue) const
{
void NoiseGenerator::getRange(double *minvalue, double *maxvalue) const {
*minvalue = _min_value;
*maxvalue = _max_value;
}
int NoiseGenerator::getLevelCount() const
{
int NoiseGenerator::getLevelCount() const {
return level_count;
}
void NoiseGenerator::clearLevels()
{
void NoiseGenerator::clearLevels() {
level_count = 0;
validate();
}
void NoiseGenerator::addLevel(NoiseLevel level)
{
if (level_count < MAX_LEVEL_COUNT)
{
void NoiseGenerator::addLevel(NoiseLevel level) {
if (level_count < MAX_LEVEL_COUNT) {
levels[level_count] = level;
level_count++;
validate();
}
}
void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxvalue)
{
void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxvalue) {
NoiseLevel level;
level.frequency = 1.0 / scaling;
@ -227,12 +199,11 @@ void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxv
addLevel(level);
}
void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor)
{
void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor,
double center_factor) {
int i;
for (i = 0; i < level_count; i++)
{
for (i = 0; i < level_count; i++) {
addLevel(start_level);
start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor;
start_level.frequency /= scaling_factor;
@ -240,8 +211,8 @@ void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double s
}
}
void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue, double center_factor)
{
void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue,
double center_factor) {
NoiseLevel level;
level.frequency = 1.0 / scaling;
@ -250,12 +221,9 @@ void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double min
addLevels(level_count, level, 0.5, 0.5, center_factor);
}
void NoiseGenerator::removeLevel(int level)
{
if (level >= 0 && level < level_count)
{
if (level_count > 1 && level < level_count - 1)
{
void NoiseGenerator::removeLevel(int level) {
if (level >= 0 && level < level_count) {
if (level_count > 1 && level < level_count - 1) {
memmove(levels + level, levels + level + 1, sizeof(NoiseLevel) * (level_count - level - 1));
}
level_count--;
@ -263,30 +231,23 @@ void NoiseGenerator::removeLevel(int level)
}
}
int NoiseGenerator::getLevel(int level, NoiseLevel* params) const
{
if (level >= 0 && level < level_count)
{
int NoiseGenerator::getLevel(int level, NoiseLevel *params) const {
if (level >= 0 && level < level_count) {
*params = levels[level];
return 1;
}
else
{
} else {
return 0;
}
}
void NoiseGenerator::setLevel(int index, NoiseLevel level)
{
if (index >= 0 && index < level_count)
{
void NoiseGenerator::setLevel(int index, NoiseLevel level) {
if (index >= 0 && index < level_count) {
levels[index] = level;
validate();
}
}
void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue, double maxvalue)
{
void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue, double maxvalue) {
NoiseLevel level;
level.frequency = 1.0 / scaling;
@ -296,14 +257,12 @@ void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue,
setLevel(index, level);
}
void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling)
{
void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling) {
int level;
double current_minvalue, current_maxvalue, current_amplitude;
double target_amplitude, factor;
if (level_count == 0)
{
if (level_count == 0) {
return;
}
@ -312,12 +271,10 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
current_amplitude = current_maxvalue - current_minvalue;
factor = target_amplitude / current_amplitude;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
levels[level].minvalue *= factor;
levels[level].amplitude *= factor;
if (adjust_scaling)
{
if (adjust_scaling) {
levels[level].frequency /= factor;
}
}
@ -325,36 +282,24 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
validate();
}
static inline double _fixValue(double value, double ridge, double curve)
{
if (value < 0.0)
{
static inline double _fixValue(double value, double ridge, double curve) {
if (value < 0.0) {
value = 0.0;
}
else if (value > 1.0)
{
} else if (value > 1.0) {
value = 1.0;
}
if (curve > 0.0)
{
if (curve > 0.0) {
value = value * (1.0 - curve) + sqrt(value) * curve;
}
else if (curve < 0.0)
{
} else if (curve < 0.0) {
value = value * (1.0 - curve) + value * value * curve;
}
if (ridge > 0.0)
{
if (ridge > 0.0) {
return fabs(value - ridge) / (1.0 - ridge);
}
else if (ridge < 0.0)
{
} else if (ridge < 0.0) {
return 1.0 - fabs(value - 1.0 - ridge) / (1.0 + ridge);
}
else
{
} else {
return value;
}
/*if (ridge > 0.0)
@ -371,55 +316,43 @@ static inline double _fixValue(double value, double ridge, double curve)
}*/
}
inline double NoiseGenerator::_get1DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) const
{
return level->minvalue + _fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude;
inline double NoiseGenerator::_get1DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset,
double x) const {
return level->minvalue +
_fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) *
level->amplitude;
}
double NoiseGenerator::get1DLevel(int level, double x) const
{
if (level >= 0 && level < level_count)
{
double NoiseGenerator::get1DLevel(int level, double x) const {
if (level >= 0 && level < level_count) {
return _get1DLevelValue(levels + level, state.level_offsets[level], x);
}
else
{
} else {
return 0.0;
}
}
double NoiseGenerator::get1DTotal(double x) const
{
double NoiseGenerator::get1DTotal(double x) const {
int level;
double result;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
result += _get1DLevelValue(levels + level, state.level_offsets[level], x);
}
return result + height_offset;
}
double NoiseGenerator::get1DDetail(double x, double detail) const
{
double NoiseGenerator::get1DDetail(double x, double detail) const {
int level;
double result, height, factor;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
height = levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{
if (height < detail * 0.25) {
break;
}
else if (height < detail * 0.5)
{
} else if (height < detail * 0.5) {
factor = (detail * 0.5 - height) / 0.25;
}
@ -428,55 +361,44 @@ double NoiseGenerator::get1DDetail(double x, double detail) const
return result + height_offset;
}
inline double NoiseGenerator::_get2DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) const
{
return level->minvalue + _fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude;
inline double NoiseGenerator::_get2DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x,
double y) const {
return level->minvalue +
_fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y),
function.ridge_factor, function.curve_factor) *
level->amplitude;
}
double NoiseGenerator::get2DLevel(int level, double x, double y) const
{
if (level >= 0 && level < level_count)
{
double NoiseGenerator::get2DLevel(int level, double x, double y) const {
if (level >= 0 && level < level_count) {
return _get2DLevelValue(levels + level, state.level_offsets[level], x, y);
}
else
{
} else {
return 0.0;
}
}
double NoiseGenerator::get2DTotal(double x, double y) const
{
double NoiseGenerator::get2DTotal(double x, double y) const {
int level;
double result;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
result += _get2DLevelValue(levels + level, state.level_offsets[level], x, y);
}
return result + height_offset;
}
double NoiseGenerator::get2DDetail(double x, double y, double detail) const
{
double NoiseGenerator::get2DDetail(double x, double y, double detail) const {
int level;
double result, height, factor;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
height = levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{
if (height < detail * 0.25) {
break;
}
else if (height < detail * 0.5)
{
} else if (height < detail * 0.5) {
factor = (detail * 0.5 - height) / 0.25;
}
@ -485,55 +407,45 @@ double NoiseGenerator::get2DDetail(double x, double y, double detail) const
return result + height_offset;
}
inline double NoiseGenerator::_get3DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) const
{
return level->minvalue + _fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y, z * level->frequency + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude;
inline double NoiseGenerator::_get3DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x,
double y, double z) const {
return level->minvalue +
_fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y,
z * level->frequency + offset.z),
function.ridge_factor, function.curve_factor) *
level->amplitude;
}
double NoiseGenerator::get3DLevel(int level, double x, double y, double z) const
{
if (level >= 0 && level < level_count)
{
double NoiseGenerator::get3DLevel(int level, double x, double y, double z) const {
if (level >= 0 && level < level_count) {
return _get3DLevelValue(levels + level, state.level_offsets[level], x, y, z);
}
else
{
} else {
return 0.0;
}
}
double NoiseGenerator::get3DTotal(double x, double y, double z) const
{
double NoiseGenerator::get3DTotal(double x, double y, double z) const {
int level;
double result;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
result += _get3DLevelValue(levels + level, state.level_offsets[level], x, y, z);
}
return result + height_offset;
}
double NoiseGenerator::get3DDetail(double x, double y, double z, double detail) const
{
double NoiseGenerator::get3DDetail(double x, double y, double z, double detail) const {
int level;
double result, height, factor;
result = 0.0;
for (level = 0; level < level_count; level++)
{
for (level = 0; level < level_count; level++) {
height = levels[level].amplitude;
factor = 1.0;
if (height < detail * 0.25)
{
if (height < detail * 0.25) {
break;
}
else if (height < detail * 0.5)
{
} else if (height < detail * 0.5) {
factor = (detail * 0.5 - height) / 0.25;
}

View file

@ -9,57 +9,53 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT NoiseGenerator
{
public:
typedef enum
{
NOISE_FUNCTION_PERLIN,
NOISE_FUNCTION_SIMPLEX,
NOISE_FUNCTION_CUSTOM
} NoiseFunctionAlgorithm;
class BASICSSHARED_EXPORT NoiseGenerator {
public:
typedef enum { NOISE_FUNCTION_PERLIN, NOISE_FUNCTION_SIMPLEX, NOISE_FUNCTION_CUSTOM } NoiseFunctionAlgorithm;
typedef struct
{
typedef struct {
NoiseFunctionAlgorithm algorithm;
double ridge_factor; /* -0.5;0.5 */
double curve_factor; /* -1.0;1.0 */
} NoiseFunction;
typedef struct
{
typedef struct {
double frequency;
double amplitude;
double minvalue;
} NoiseLevel;
public:
public:
NoiseGenerator();
virtual ~NoiseGenerator();
virtual void save(PackStream* stream) const;
virtual void load(PackStream* stream);
virtual void copy(NoiseGenerator* destination) const;
virtual void save(PackStream *stream) const;
virtual void load(PackStream *stream);
virtual void copy(NoiseGenerator *destination) const;
virtual void validate();
inline const NoiseState &getState() const {return state;}
inline const NoiseState &getState() const {
return state;
}
void setState(const NoiseState &state);
void randomizeOffsets();
NoiseFunction getFunction();
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y), double (*func3d)(double x, double y, double z));
void setFunction(NoiseFunction* function);
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
double (*func3d)(double x, double y, double z));
void setFunction(NoiseFunction *function);
void setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor);
void forceValue(double value);
void getRange(double* minvalue, double* maxvalue) const;
void getRange(double *minvalue, double *maxvalue) const;
int getLevelCount() const;
void clearLevels();
void addLevel(NoiseLevel level);
void addLevelSimple(double scaling, double minvalue, double maxvalue);
void addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor);
void addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor,
double center_factor);
void addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue, double center_factor);
void removeLevel(int level);
int getLevel(int level, NoiseLevel* params) const;
int getLevel(int level, NoiseLevel *params) const;
void setLevel(int index, NoiseLevel level);
void setLevelSimple(int index, double scaling, double minvalue, double maxvalue);
void normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling);
@ -73,10 +69,11 @@ public:
double get3DTotal(double x, double y, double z) const;
double get3DDetail(double x, double y, double z, double detail) const;
private:
double _get1DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) const;
double _get2DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) const;
double _get3DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) const;
private:
double _get1DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x) const;
double _get2DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x, double y) const;
double _get3DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x, double y,
double z) const;
NoiseFunction function;
double height_offset;
@ -91,7 +88,6 @@ private:
double (*_func_noise_2d)(double x, double y);
double (*_func_noise_3d)(double x, double y, double z);
};
}
}

View file

@ -3,40 +3,33 @@
#include "PackStream.h"
#include "RandomGenerator.h"
NoiseState::NoiseState()
{
for (int i = 0; i < 30; i++)
{
NoiseState::NoiseState() {
for (int i = 0; i < 30; i++) {
level_offsets.push_back(NoiseOffset());
}
randomizeOffsets();
}
void NoiseState::save(PackStream *stream) const
{
void NoiseState::save(PackStream *stream) const {
int levels = level_offsets.size();
stream->write(&levels);
for (const auto &level_offset:level_offsets)
{
for (const auto &level_offset : level_offsets) {
stream->write(&level_offset.x);
stream->write(&level_offset.y);
stream->write(&level_offset.z);
}
}
void NoiseState::load(PackStream *stream)
{
void NoiseState::load(PackStream *stream) {
int levels;
stream->read(&levels);
level_offsets.clear();
if (levels > 1000)
{
if (levels > 1000) {
levels = 1000;
}
for (int i = 0; i < levels; i++)
{
for (int i = 0; i < levels; i++) {
NoiseOffset level_offset;
stream->read(&level_offset.x);
stream->read(&level_offset.y);
@ -45,38 +38,31 @@ void NoiseState::load(PackStream *stream)
}
}
void NoiseState::copy(NoiseState *destination) const
{
void NoiseState::copy(NoiseState *destination) const {
destination->level_offsets = level_offsets;
}
void NoiseState::randomizeOffsets()
{
for (auto &level_offset:level_offsets)
{
void NoiseState::randomizeOffsets() {
for (auto &level_offset : level_offsets) {
level_offset.x = RandomGenerator::random();
level_offset.y = RandomGenerator::random();
level_offset.z = RandomGenerator::random();
}
}
void NoiseState::resetOffsets(double x, double y, double z)
{
for (auto &level_offset:level_offsets)
{
void NoiseState::resetOffsets(double x, double y, double z) {
for (auto &level_offset : level_offsets) {
level_offset.x = x;
level_offset.y = y;
level_offset.z = z;
}
}
void NoiseState::setLevel(int level, double x, double y, double z)
{
void NoiseState::setLevel(int level, double x, double y, double z) {
NoiseOffset offset = {x, y, z};
level_offsets.at(level) = offset;
}
void NoiseState::setLevelCount(int level_count)
{
void NoiseState::setLevelCount(int level_count) {
level_offsets.resize(level_count);
}

View file

@ -11,35 +11,33 @@ namespace basics {
*
* This state contains the noise offsets for noise layers.
*/
class BASICSSHARED_EXPORT NoiseState
{
public:
class BASICSSHARED_EXPORT NoiseState {
public:
typedef struct {
double x;
double y;
double z;
} NoiseOffset;
public:
public:
NoiseState();
void save(PackStream* stream) const;
void load(PackStream* stream);
void copy(NoiseState* destination) const;
void save(PackStream *stream) const;
void load(PackStream *stream);
void copy(NoiseState *destination) const;
void randomizeOffsets();
void resetOffsets(double x=0.0, double y=0.0, double z=0.0);
void resetOffsets(double x = 0.0, double y = 0.0, double z = 0.0);
void setLevel(int level, double x, double y, double z);
void setLevelCount(int level_count);
private:
private:
std::vector<NoiseOffset> level_offsets;
friend class NoiseGenerator;
friend class FractalNoise;
};
}
}

View file

@ -1,5 +1,4 @@
#include "SpaceGridIterator.h"
SpaceGridIterator::SpaceGridIterator()
{
SpaceGridIterator::SpaceGridIterator() {
}

View file

@ -11,9 +11,8 @@ namespace basics {
*
* This may be useful for ray marching algorithms for example.
*/
class BASICSSHARED_EXPORT SpaceGridIterator
{
public:
class BASICSSHARED_EXPORT SpaceGridIterator {
public:
SpaceGridIterator();
/**
@ -23,7 +22,6 @@ public:
*/
virtual bool onCell(int x, int y, int z) = 0;
};
}
}

View file

@ -4,54 +4,36 @@
#include "SpaceGridIterator.h"
using namespace std;
SpaceSegment::SpaceSegment(const Vector3& start, const Vector3& end):
start(start), end(end)
{
SpaceSegment::SpaceSegment(const Vector3 &start, const Vector3 &end) : start(start), end(end) {
}
bool SpaceSegment::intersectYInterval(double ymin, double ymax)
{
if (start.y > ymax)
{
if (end.y >= ymax)
{
bool SpaceSegment::intersectYInterval(double ymin, double ymax) {
if (start.y > ymax) {
if (end.y >= ymax) {
return false;
}
else
{
} else {
Vector3 diff = end.sub(start);
start = start.add(diff.scale((ymax - start.y) / diff.y));
if (end.y < ymin)
{
if (end.y < ymin) {
end = end.add(diff.scale((ymin - end.y) / diff.y));
}
}
}
else if (start.y < ymin)
{
if (end.y <= ymin)
{
} else if (start.y < ymin) {
if (end.y <= ymin) {
return false;
}
else
{
} else {
Vector3 diff = end.sub(start);
start = start.add(diff.scale((ymin - start.y) / diff.y));
if (end.y >= ymax)
{
if (end.y >= ymax) {
end = end.add(diff.scale((ymax - end.y) / diff.y));
}
}
}
else /* start is inside layer */
} else /* start is inside layer */
{
Vector3 diff = end.sub(start);
if (end.y > ymax)
{
if (end.y > ymax) {
end = start.add(diff.scale((ymax - start.y) / diff.y));
}
else if (end.y < ymin)
{
} else if (end.y < ymin) {
end = start.add(diff.scale((ymin - start.y) / diff.y));
}
}
@ -59,8 +41,7 @@ bool SpaceSegment::intersectYInterval(double ymin, double ymax)
return true;
}
bool SpaceSegment::intersectBoundingBox(const SpaceSegment &bbox) const
{
bool SpaceSegment::intersectBoundingBox(const SpaceSegment &bbox) const {
Vector3 dir = getDirection();
// r.dir is unit direction vector of ray
double dfx = 1.0 / dir.x;
@ -80,15 +61,13 @@ bool SpaceSegment::intersectBoundingBox(const SpaceSegment &bbox) const
// if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behing us
double t;
if (tmax < 0.0)
{
if (tmax < 0.0) {
t = tmax;
return false;
}
// if tmin > tmax, ray doesn't intersect AABB
if (tmin > tmax)
{
if (tmin > tmax) {
t = tmax;
return false;
}
@ -97,28 +76,23 @@ bool SpaceSegment::intersectBoundingBox(const SpaceSegment &bbox) const
return true;
}
SpaceSegment SpaceSegment::projectedOnXPlane(double x) const
{
SpaceSegment SpaceSegment::projectedOnXPlane(double x) const {
return SpaceSegment(Vector3(x, start.y, start.z), Vector3(x, end.y, end.z));
}
SpaceSegment SpaceSegment::projectedOnYPlane(double y) const
{
SpaceSegment SpaceSegment::projectedOnYPlane(double y) const {
return SpaceSegment(Vector3(start.x, y, start.z), Vector3(end.x, y, end.z));
}
SpaceSegment SpaceSegment::projectedOnZPlane(double z) const
{
SpaceSegment SpaceSegment::projectedOnZPlane(double z) const {
return SpaceSegment(Vector3(start.x, start.y, z), Vector3(end.x, end.y, z));
}
SpaceSegment SpaceSegment::scaled(double factor) const
{
SpaceSegment SpaceSegment::scaled(double factor) const {
return SpaceSegment(start.scale(factor), end.scale(factor));
}
bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate)
{
bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate) {
Vector3 diff = end.sub(start);
int stepX = diff.x < 0.0 ? -1 : 1;
@ -137,36 +111,25 @@ bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate)
double tMaxY = diff.y == 0.0 ? INFINITY : ((double)(Y + (stepY > 0 ? 1 : 0)) - start.y) / diff.y;
double tMaxZ = diff.z == 0.0 ? INFINITY : ((double)(Z + (stepZ > 0 ? 1 : 0)) - start.z) / diff.z;
do
{
if (not delegate.onCell(X, Y, Z))
{
do {
if (not delegate.onCell(X, Y, Z)) {
return false;
}
if (tMaxX < tMaxY)
{
if (tMaxX < tMaxZ)
{
if (tMaxX < tMaxY) {
if (tMaxX < tMaxZ) {
X = X + stepX;
tMaxX = tMaxX + tDeltaX;
}
else
{
} else {
Z = Z + stepZ;
tMaxZ = tMaxZ + tDeltaZ;
}
}
else
{
if(tMaxY < tMaxZ)
{
} else {
if (tMaxY < tMaxZ) {
Y = Y + stepY;
tMaxY = tMaxY + tDeltaY;
}
else
{
Z= Z + stepZ;
} else {
Z = Z + stepZ;
tMaxZ = tMaxZ + tDeltaZ;
}
}

View file

@ -11,20 +11,34 @@ namespace basics {
/**
* A delimited segment in 3D space (mainly useful for rays).
*/
class BASICSSHARED_EXPORT SpaceSegment
{
public:
SpaceSegment(const Vector3& start, const Vector3& end);
SpaceSegment(): SpaceSegment(Vector3(), Vector3()) {}
class BASICSSHARED_EXPORT SpaceSegment {
public:
SpaceSegment(const Vector3 &start, const Vector3 &end);
SpaceSegment() : SpaceSegment(Vector3(), Vector3()) {
}
inline const Vector3 &getStart() const {return start;}
inline const Vector3 &getEnd() const {return end;}
inline Vector3 getDirection() const {return end.sub(start);}
inline double getLength() const {return end.sub(start).getNorm();}
inline const Vector3 &getStart() const {
return start;
}
inline const Vector3 &getEnd() const {
return end;
}
inline Vector3 getDirection() const {
return end.sub(start);
}
inline double getLength() const {
return end.sub(start).getNorm();
}
inline double getXDiff() const {return end.x - start.x;}
inline double getYDiff() const {return end.y - start.y;}
inline double getZDiff() const {return end.z - start.z;}
inline double getXDiff() const {
return end.x - start.x;
}
inline double getYDiff() const {
return end.y - start.y;
}
inline double getZDiff() const {
return end.z - start.z;
}
/**
* Keep only the intersection with a slice orthogonal to the Y axis.
@ -41,15 +55,15 @@ public:
/**
* Return a version of this segment, projected on a X plane.
*/
SpaceSegment projectedOnXPlane(double x=0.0) const;
SpaceSegment projectedOnXPlane(double x = 0.0) const;
/**
* Return a version of this segment, projected on a Y plane.
*/
SpaceSegment projectedOnYPlane(double y=0.0) const;
SpaceSegment projectedOnYPlane(double y = 0.0) const;
/**
* Return a version of this segment, projected on a Z plane.
*/
SpaceSegment projectedOnZPlane(double z=0.0) const;
SpaceSegment projectedOnZPlane(double z = 0.0) const;
/**
* Return a scaled version of this segment.
@ -69,11 +83,10 @@ public:
*/
bool iterateOnGrid(SpaceGridIterator &delegate);
private:
private:
Vector3 start;
Vector3 end;
};
}
}

View file

@ -3,43 +3,32 @@
#include "PackStream.h"
#include "InfiniteRay.h"
Sphere::Sphere()
{
Sphere::Sphere() {
}
Sphere::Sphere(const Vector3 &center, double radius):
center(center), radius(radius)
{
Sphere::Sphere(const Vector3 &center, double radius) : center(center), radius(radius) {
radius2 = radius * radius;
}
int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
{
int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
Vector3 *second_intersection) const {
Vector3 L = ray.getOrigin().sub(center);
double b = 2.0 * ray.getDirection().dotProduct(L);
double c = L.dotProduct(L) - radius2;
double discr = b * b - 4.0 * c;
if (discr < 0)
{
if (discr < 0) {
return 0;
}
else if (discr == 0)
{
} else if (discr == 0) {
*first_intersection = ray.getPointAtCursor(-0.5 * b);
return 1;
}
else
{
} else {
double x0 = (b > 0.0) ? -0.5 * (b + sqrt(discr)) : -0.5 * (b - sqrt(discr));
double x1 = c / x0;
if (x0 > x1)
{
if (x0 > x1) {
*first_intersection = ray.getPointAtCursor(x1);
*second_intersection = ray.getPointAtCursor(x0);
}
else
{
} else {
*first_intersection = ray.getPointAtCursor(x0);
*second_intersection = ray.getPointAtCursor(x1);
}
@ -47,15 +36,13 @@ int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersec
}
}
void Sphere::save(PackStream *stream) const
{
void Sphere::save(PackStream *stream) const {
center.save(stream);
stream->write(&radius);
stream->write(&radius2);
}
void Sphere::load(PackStream *stream)
{
void Sphere::load(PackStream *stream) {
center.load(stream);
stream->read(&radius);
stream->read(&radius2);

View file

@ -11,31 +11,33 @@ namespace basics {
/**
* Geometric sphere.
*/
class BASICSSHARED_EXPORT Sphere
{
public:
class BASICSSHARED_EXPORT Sphere {
public:
Sphere();
Sphere(const Vector3 &center, double radius);
inline const Vector3 &getCenter() const {return center;}
inline const double &getRadius() const {return radius;}
inline const Vector3 &getCenter() const {
return center;
}
inline const double &getRadius() const {
return radius;
}
/**
* Check the intersection between the sphere and an infinite ray.
*
* Returns the number of intersections (0, 1 or 2) and fill the intersection points.
*/
int checkRayIntersection(const InfiniteRay& ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
int checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
void save(PackStream *stream) const;
void load(PackStream *stream);
private:
private:
Vector3 center;
double radius;
double radius2;
};
}
}

View file

@ -5,8 +5,7 @@
#include "PackStream.h"
#include "PictureWriter.h"
Texture2D::Texture2D(int xsize, int ysize)
{
Texture2D::Texture2D(int xsize, int ysize) {
assert(xsize > 0 && ysize > 0);
this->xsize = xsize;
@ -14,39 +13,38 @@ Texture2D::Texture2D(int xsize, int ysize)
this->data = new Color[xsize * ysize];
}
Texture2D::~Texture2D()
{
Texture2D::~Texture2D() {
delete[] data;
}
void Texture2D::getSize(int* xsize, int* ysize) const
{
void Texture2D::getSize(int *xsize, int *ysize) const {
*xsize = this->xsize;
*ysize = this->ysize;
}
void Texture2D::setPixel(int x, int y, Color col)
{
void Texture2D::setPixel(int x, int y, Color col) {
assert(x >= 0 && x < xsize);
assert(y >= 0 && y < ysize);
data[y * xsize + x] = col;
}
Color Texture2D::getPixel(int x, int y) const
{
Color Texture2D::getPixel(int x, int y) const {
assert(x >= 0 && x < xsize);
assert(y >= 0 && y < ysize);
return data[y * xsize + x];
}
Color Texture2D::getNearest(double dx, double dy) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
Color Texture2D::getNearest(double dx, double dy) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
@ -57,31 +55,32 @@ Color Texture2D::getNearest(double dx, double dy) const
return this->data[iy * this->xsize + ix];
}
Color Texture2D::getLinear(double dx, double dy) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
Color Texture2D::getLinear(double dx, double dy) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
if (ix == this->xsize - 1) {
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
if (iy == this->ysize - 1) {
iy--;
}
dx -= (double)ix;
dy -= (double)iy;
Color* data = this->data + iy * this->xsize + ix;
Color *data = this->data + iy * this->xsize + ix;
Color c1 = data->lerp(*(data + 1), dx);
Color c2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
@ -89,32 +88,27 @@ Color Texture2D::getLinear(double dx, double dy) const
return c1.lerp(c2, dy);
}
Color Texture2D::getCubic(double dx, double dy) const
{
Color Texture2D::getCubic(double dx, double dy) const {
/* TODO */
return getLinear(dx, dy);
}
void Texture2D::fill(Color col)
{
void Texture2D::fill(Color col) {
int i, n;
n = this->xsize * this->ysize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i] = col;
}
}
void Texture2D::add(Texture2D* source)
{
void Texture2D::add(Texture2D *source) {
int i, n;
assert(source->xsize == this->xsize);
assert(source->ysize == this->ysize);
n = source->xsize * source->ysize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
@ -122,47 +116,42 @@ void Texture2D::add(Texture2D* source)
}
}
void Texture2D::save(PackStream* stream) const
{
void Texture2D::save(PackStream *stream) const {
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
n = this->xsize * this->ysize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->save(stream);
}
}
void Texture2D::load(PackStream* stream)
{
void Texture2D::load(PackStream *stream) {
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
n = this->xsize * this->ysize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->load(stream);
}
}
class Texture2DWriter:public PictureWriter
{
public:
Texture2DWriter(const Texture2D *tex): tex(tex) {}
class Texture2DWriter : public PictureWriter {
public:
Texture2DWriter(const Texture2D *tex) : tex(tex) {
}
virtual unsigned int getPixel(int x, int y) override
{
virtual unsigned int getPixel(int x, int y) override {
return tex->getPixel(x, y).to32BitBGRA();
}
private:
private:
const Texture2D *tex;
};
void Texture2D::saveToFile(const std::string &filepath) const
{
void Texture2D::saveToFile(const std::string &filepath) const {
Texture2DWriter writer(this);
writer.save(filepath, xsize, ysize);
}

View file

@ -6,30 +6,28 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Texture2D
{
public:
class BASICSSHARED_EXPORT Texture2D {
public:
Texture2D(int xsize, int ysize);
~Texture2D();
void getSize(int* xsize, int* ysize) const;
void getSize(int *xsize, int *ysize) const;
void setPixel(int x, int y, Color col);
Color getPixel(int x, int y) const;
Color getNearest(double dx, double dy) const;
Color getLinear(double dx, double dy) const;
Color getCubic(double dx, double dy) const;
void fill(Color col);
void add(Texture2D* other);
void save(PackStream* stream) const;
void load(PackStream* stream);
void add(Texture2D *other);
void save(PackStream *stream) const;
void load(PackStream *stream);
void saveToFile(const std::string &filepath) const;
private:
private:
int xsize;
int ysize;
Color* data;
Color *data;
};
}
}

View file

@ -5,8 +5,7 @@
#include "PackStream.h"
#include "PictureWriter.h"
Texture3D::Texture3D(int xsize, int ysize, int zsize)
{
Texture3D::Texture3D(int xsize, int ysize, int zsize) {
assert(xsize > 0 && ysize > 0 && zsize > 0);
this->xsize = xsize;
@ -15,20 +14,17 @@ Texture3D::Texture3D(int xsize, int ysize, int zsize)
this->data = new Color[xsize * ysize * zsize];
}
Texture3D::~Texture3D()
{
Texture3D::~Texture3D() {
delete[] data;
}
void Texture3D::getSize(int* xsize, int* ysize, int* zsize) const
{
void Texture3D::getSize(int *xsize, int *ysize, int *zsize) const {
*xsize = this->xsize;
*ysize = this->ysize;
*zsize = this->zsize;
}
void Texture3D::setPixel(int x, int y, int z, Color col)
{
void Texture3D::setPixel(int x, int y, int z, Color col) {
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->ysize);
@ -36,8 +32,7 @@ void Texture3D::setPixel(int x, int y, int z, Color col)
this->data[z * this->xsize * this->ysize + y * this->xsize + x] = col;
}
Color Texture3D::getPixel(int x, int y, int z) const
{
Color Texture3D::getPixel(int x, int y, int z) const {
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
@ -45,14 +40,19 @@ Color Texture3D::getPixel(int x, int y, int z) const
return this->data[z * this->xsize * this->ysize + y * this->xsize + x];
}
Color Texture3D::getNearest(double dx, double dy, double dz) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
Color Texture3D::getNearest(double dx, double dy, double dz) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
if (dz < 0.0)
dz = 0.0;
if (dz > 1.0)
dz = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
@ -65,32 +65,34 @@ Color Texture3D::getNearest(double dx, double dy, double dz) const
return this->data[iz * this->xsize * this->ysize + iy * this->xsize + ix];
}
Color Texture3D::getLinear(double dx, double dy, double dz) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
Color Texture3D::getLinear(double dx, double dy, double dz) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
if (dz < 0.0)
dz = 0.0;
if (dz > 1.0)
dz = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
dz *= (double)(this->zsize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
if (ix == this->xsize - 1) {
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
if (iy == this->ysize - 1) {
iy--;
}
int iz = (int)floor(dz);
if (iz == this->zsize - 1)
{
if (iz == this->zsize - 1) {
iz--;
}
@ -98,7 +100,7 @@ Color Texture3D::getLinear(double dx, double dy, double dz) const
dy -= (double)iy;
dz -= (double)iz;
Color* data = this->data + iz * this->xsize * this->ysize + iy * this->xsize + ix;
Color *data = this->data + iz * this->xsize * this->ysize + iy * this->xsize + ix;
Color cx1 = data->lerp(*(data + 1), dx);
Color cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
@ -112,24 +114,20 @@ Color Texture3D::getLinear(double dx, double dy, double dz) const
return cy1.lerp(cy2, dz);
}
Color Texture3D::getCubic(double dx, double dy, double dz) const
{
Color Texture3D::getCubic(double dx, double dy, double dz) const {
/* TODO */
return getLinear(dx, dy, dz);
}
void Texture3D::fill(Color col)
{
void Texture3D::fill(Color col) {
int i, n;
n = this->xsize * this->ysize * this->zsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i] = col;
}
}
void Texture3D::add(Texture3D* source)
{
void Texture3D::add(Texture3D *source) {
int i, n;
assert(source->xsize == this->xsize);
@ -137,8 +135,7 @@ void Texture3D::add(Texture3D* source)
assert(source->zsize == this->zsize);
n = source->xsize * source->ysize * source->zsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
@ -146,21 +143,18 @@ void Texture3D::add(Texture3D* source)
}
}
void Texture3D::save(PackStream* stream) const
{
void Texture3D::save(PackStream *stream) const {
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
stream->write(&this->zsize);
n = this->xsize * this->ysize * this->zsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->save(stream);
}
}
void Texture3D::load(PackStream* stream)
{
void Texture3D::load(PackStream *stream) {
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
@ -168,19 +162,17 @@ void Texture3D::load(PackStream* stream)
n = this->xsize * this->ysize * this->zsize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->load(stream);
}
}
class Texture3DWriter:public PictureWriter
{
public:
Texture3DWriter(const Texture3D *tex): tex(tex) {}
class Texture3DWriter : public PictureWriter {
public:
Texture3DWriter(const Texture3D *tex) : tex(tex) {
}
virtual unsigned int getPixel(int x, int y) override
{
virtual unsigned int getPixel(int x, int y) override {
int xsize, ysize, zsize;
tex->getSize(&xsize, &ysize, &zsize);
@ -189,12 +181,12 @@ public:
return tex->getPixel(x, y, z).to32BitBGRA();
}
private:
private:
const Texture3D *tex;
};
void Texture3D::saveToFile(const std::string &filepath) const
{
void Texture3D::saveToFile(const std::string &filepath) const {
Texture3DWriter writer(this);
writer.save(filepath, xsize, ysize * zsize);
}

View file

@ -6,31 +6,29 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Texture3D
{
public:
class BASICSSHARED_EXPORT Texture3D {
public:
Texture3D(int xsize, int ysize, int zsize);
~Texture3D();
void getSize(int* xsize, int* ysize, int* zsize) const;
void getSize(int *xsize, int *ysize, int *zsize) const;
void setPixel(int x, int y, int z, Color col);
Color getPixel(int x, int y, int z) const;
Color getNearest(double dx, double dy, double dz) const;
Color getLinear(double dx, double dy, double dz) const;
Color getCubic(double dx, double dy, double dz) const;
void fill(Color col);
void add(Texture3D* other);
void save(PackStream* stream) const;
void load(PackStream* stream);
void add(Texture3D *other);
void save(PackStream *stream) const;
void load(PackStream *stream);
void saveToFile(const std::string &filepath) const;
private:
private:
int xsize;
int ysize;
int zsize;
Color* data;
Color *data;
};
}
}

View file

@ -5,8 +5,7 @@
#include "PackStream.h"
#include "PictureWriter.h"
Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize)
{
Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize) {
assert(xsize > 0 && ysize > 0 && zsize > 0 && wsize > 0);
this->xsize = xsize;
@ -16,21 +15,18 @@ Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize)
this->data = new Color[xsize * ysize * zsize * wsize];
}
Texture4D::~Texture4D()
{
Texture4D::~Texture4D() {
delete[] data;
}
void Texture4D::getSize(int* xsize, int* ysize, int* zsize, int* wsize) const
{
void Texture4D::getSize(int *xsize, int *ysize, int *zsize, int *wsize) const {
*xsize = this->xsize;
*ysize = this->ysize;
*zsize = this->zsize;
*wsize = this->wsize;
}
void Texture4D::setPixel(int x, int y, int z, int w, Color col)
{
void Texture4D::setPixel(int x, int y, int z, int w, Color col) {
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
@ -39,26 +35,33 @@ void Texture4D::setPixel(int x, int y, int z, int w, Color col)
this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x] = col;
}
Color Texture4D::getPixel(int x, int y, int z, int w) const
{
Color Texture4D::getPixel(int x, int y, int z, int w) const {
assert(x >= 0 && x < this->xsize);
assert(y >= 0 && y < this->ysize);
assert(z >= 0 && z < this->zsize);
assert(w >= 0 && w < this->wsize);
return this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x];
return this
->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x];
}
Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
if (dz < 0.0)
dz = 0.0;
if (dz > 1.0)
dz = 1.0;
if (dw < 0.0)
dw = 0.0;
if (dw > 1.0)
dw = 1.0;
int ix = (int)(dx * (double)(this->xsize - 1));
int iy = (int)(dy * (double)(this->ysize - 1));
@ -70,19 +73,27 @@ Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const
assert(iz >= 0 && iz < this->zsize);
assert(iw >= 0 && iw < this->wsize);
return this->data[iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix];
return this
->data[iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix];
}
Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
{
if (dx < 0.0) dx = 0.0;
if (dx > 1.0) dx = 1.0;
if (dy < 0.0) dy = 0.0;
if (dy > 1.0) dy = 1.0;
if (dz < 0.0) dz = 0.0;
if (dz > 1.0) dz = 1.0;
if (dw < 0.0) dw = 0.0;
if (dw > 1.0) dw = 1.0;
Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const {
if (dx < 0.0)
dx = 0.0;
if (dx > 1.0)
dx = 1.0;
if (dy < 0.0)
dy = 0.0;
if (dy > 1.0)
dy = 1.0;
if (dz < 0.0)
dz = 0.0;
if (dz > 1.0)
dz = 1.0;
if (dw < 0.0)
dw = 0.0;
if (dw > 1.0)
dw = 1.0;
dx *= (double)(this->xsize - 1);
dy *= (double)(this->ysize - 1);
@ -90,23 +101,19 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
dw *= (double)(this->wsize - 1);
int ix = (int)floor(dx);
if (ix == this->xsize - 1)
{
if (ix == this->xsize - 1) {
ix--;
}
int iy = (int)floor(dy);
if (iy == this->ysize - 1)
{
if (iy == this->ysize - 1) {
iy--;
}
int iz = (int)floor(dz);
if (iz == this->zsize - 1)
{
if (iz == this->zsize - 1) {
iz--;
}
int iw = (int)floor(dw);
if (iw == this->wsize - 1)
{
if (iw == this->wsize - 1) {
iw--;
}
@ -115,7 +122,8 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
dz -= (double)iz;
dw -= (double)iw;
Color* data = this->data + iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix;
Color *data = this->data + iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize +
iy * this->xsize + ix;
Color cz1, cz2;
Color cx1 = data->lerp(*(data + 1), dx);
@ -143,24 +151,20 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
return cz1.lerp(cz2, dw);
}
Color Texture4D::getCubic(double dx, double dy, double dz, double dw) const
{
Color Texture4D::getCubic(double dx, double dy, double dz, double dw) const {
/* TODO */
return getLinear(dx, dy, dz, dw);
}
void Texture4D::fill(Color col)
{
void Texture4D::fill(Color col) {
int i, n;
n = this->xsize * this->ysize * this->zsize * this->wsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i] = col;
}
}
void Texture4D::add(Texture4D* source)
{
void Texture4D::add(Texture4D *source) {
int i, n;
assert(source->xsize == this->xsize);
@ -169,8 +173,7 @@ void Texture4D::add(Texture4D* source)
assert(source->wsize == this->wsize);
n = source->xsize * source->ysize * source->zsize * source->wsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
this->data[i].r += source->data[i].r;
this->data[i].g += source->data[i].g;
this->data[i].b += source->data[i].b;
@ -178,22 +181,19 @@ void Texture4D::add(Texture4D* source)
}
}
void Texture4D::save(PackStream* stream) const
{
void Texture4D::save(PackStream *stream) const {
int i, n;
stream->write(&this->xsize);
stream->write(&this->ysize);
stream->write(&this->zsize);
stream->write(&this->wsize);
n = this->xsize * this->ysize * this->zsize * this->wsize;
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->save(stream);
}
}
void Texture4D::load(PackStream* stream)
{
void Texture4D::load(PackStream *stream) {
int i, n;
stream->read(&this->xsize);
stream->read(&this->ysize);
@ -202,20 +202,17 @@ void Texture4D::load(PackStream* stream)
n = this->xsize * this->ysize * this->zsize * this->wsize;
delete[] this->data;
this->data = new Color[n];
for (i = 0; i < n; i++)
{
for (i = 0; i < n; i++) {
(this->data + i)->load(stream);
}
}
class Texture4DWriter : public PictureWriter {
public:
Texture4DWriter(const Texture4D *tex) : tex(tex) {
}
class Texture4DWriter:public PictureWriter
{
public:
Texture4DWriter(const Texture4D *tex): tex(tex) {}
virtual unsigned int getPixel(int x, int y) override
{
virtual unsigned int getPixel(int x, int y) override {
int xsize, ysize, zsize, wsize;
tex->getSize(&xsize, &ysize, &zsize, &wsize);
@ -227,12 +224,12 @@ public:
return tex->getPixel(x, y, z, w).to32BitBGRA();
}
private:
private:
const Texture4D *tex;
};
void Texture4D::saveToFile(const std::string &filepath) const
{
void Texture4D::saveToFile(const std::string &filepath) const {
Texture4DWriter writer(this);
writer.save(filepath, xsize * wsize, ysize * zsize);
}

View file

@ -6,32 +6,30 @@
namespace paysages {
namespace basics {
class BASICSSHARED_EXPORT Texture4D
{
public:
class BASICSSHARED_EXPORT Texture4D {
public:
Texture4D(int xsize, int ysize, int zsize, int wsize);
~Texture4D();
void getSize(int* xsize, int* ysize, int* zsize, int* wsize) const;
void getSize(int *xsize, int *ysize, int *zsize, int *wsize) const;
void setPixel(int x, int y, int z, int w, Color col);
Color getPixel(int x, int y, int z, int w) const;
Color getNearest(double dx, double dy, double dz, double dw) const;
Color getLinear(double dx, double dy, double dz, double dw) const;
Color getCubic(double dx, double dy, double dz, double dw) const;
void fill(Color col);
void add(Texture4D* other);
void save(PackStream* stream) const;
void load(PackStream* stream);
void add(Texture4D *other);
void save(PackStream *stream) const;
void load(PackStream *stream);
void saveToFile(const std::string &filepath) const;
private:
private:
int xsize;
int ysize;
int zsize;
int wsize;
Color* data;
Color *data;
};
}
}

View file

@ -12,41 +12,31 @@ const Vector3 paysages::basics::VECTOR_SOUTH(0.0, 0.0, 1.0);
const Vector3 paysages::basics::VECTOR_WEST(-1.0, 0.0, 0.0);
const Vector3 paysages::basics::VECTOR_EAST(1.0, 0.0, 0.0);
Vector3::Vector3(const VectorSpherical &v):
x(v.r * cos(v.phi) * cos(v.theta)), y(v.r * sin(v.theta)), z(-v.r * sin(v.phi) * cos(v.theta))
{
Vector3::Vector3(const VectorSpherical &v)
: x(v.r * cos(v.phi) * cos(v.theta)), y(v.r * sin(v.theta)), z(-v.r * sin(v.phi) * cos(v.theta)) {
}
void Vector3::save(PackStream* stream) const
{
void Vector3::save(PackStream *stream) const {
stream->write(&x);
stream->write(&y);
stream->write(&z);
}
void Vector3::load(PackStream* stream)
{
void Vector3::load(PackStream *stream) {
stream->read(&x);
stream->read(&y);
stream->read(&z);
}
static inline double _euclidGet2DAngle(double x, double y)
{
static inline double _euclidGet2DAngle(double x, double y) {
// TEMP Copy of old euclid.c
double nx, ny, d, ret;
if (x == 0.0)
{
if (y == 0.0)
{
if (x == 0.0) {
if (y == 0.0) {
return 0.0;
}
else if (y < 0.0)
{
} else if (y < 0.0) {
return 3.0 * M_PI_2;
}
else
{
} else {
return M_PI_2;
}
}
@ -56,21 +46,18 @@ static inline double _euclidGet2DAngle(double x, double y)
ny = y / d;
ret = asin(ny);
if (nx < 0.0)
{
if (nx < 0.0) {
ret = M_PI - ret;
}
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
}
VectorSpherical Vector3::toSpherical() const
{
VectorSpherical Vector3::toSpherical() const {
VectorSpherical result;
result.phi = _euclidGet2DAngle(x, -z);
result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y);
if (y < 0.0)
{
if (y < 0.0) {
result.theta -= 2.0 * M_PI;
}
result.r = getNorm();
@ -78,19 +65,14 @@ VectorSpherical Vector3::toSpherical() const
return result;
}
Vector3 Vector3::midPointTo(const Vector3 &other) const
{
Vector3 Vector3::midPointTo(const Vector3 &other) const {
return Vector3((other.x + x) * 0.5, (other.y + y) * 0.5, (other.z + z) * 0.5);
}
Vector3 Vector3::randomInSphere(double radius, bool only_surface)
{
Vector3 Vector3::randomInSphere(double radius, bool only_surface) {
// TODO More uniform spatial repartition
// The current randomization clusters result near the center and at the poles
VectorSpherical vec = {
only_surface ? radius : RandomGenerator::random() * radius,
(RandomGenerator::random() - 0.5) * M_PI,
RandomGenerator::random() * M_2PI
};
VectorSpherical vec = {only_surface ? radius : RandomGenerator::random() * radius,
(RandomGenerator::random() - 0.5) * M_PI, RandomGenerator::random() * M_2PI};
return Vector3(vec);
}

View file

@ -33,16 +33,14 @@ namespace basics {
* X=0 Y=-1 Z=0 => THETA=-PI/2
*/
typedef struct
{
typedef struct {
double r;
double theta;
double phi;
} VectorSpherical;
class BASICSSHARED_EXPORT Vector3
{
public:
class BASICSSHARED_EXPORT Vector3 {
public:
Vector3() = default;
Vector3(double x, double y, double z);
Vector3(const VectorSpherical &v);
@ -73,9 +71,9 @@ public:
*
* If *only_surface* is true, produce a vector with *radius* as length.
*/
static Vector3 randomInSphere(double radius=1.0, bool only_surface=false);
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false);
public:
public:
// TODO Make private
double x;
double y;
@ -89,7 +87,6 @@ BASICSSHARED_EXPORT extern const Vector3 VECTOR_NORTH;
BASICSSHARED_EXPORT extern const Vector3 VECTOR_SOUTH;
BASICSSHARED_EXPORT extern const Vector3 VECTOR_EAST;
BASICSSHARED_EXPORT extern const Vector3 VECTOR_WEST;
}
}

View file

@ -1,73 +1,55 @@
#define VECTOR3_INLINE_CPP
#ifdef VECTOR3_H
# define METHSPEC inline
#define METHSPEC inline
#else
# include "Vector3.h"
# define METHSPEC
#include "Vector3.h"
#define METHSPEC
#endif
#include <cmath>
METHSPEC Vector3::Vector3(double x, double y, double z):
x(x), y(y), z(z)
{
METHSPEC Vector3::Vector3(double x, double y, double z) : x(x), y(y), z(z) {
}
METHSPEC Vector3 Vector3::add(double x, double y, double z) const
{
METHSPEC Vector3 Vector3::add(double x, double y, double z) const {
return Vector3(this->x + x, this->y + y, this->z + z);
}
METHSPEC Vector3 Vector3::add(const Vector3 &other) const
{
METHSPEC Vector3 Vector3::add(const Vector3 &other) const {
return Vector3(x + other.x, y + other.y, z + other.z);
}
METHSPEC Vector3 Vector3::sub(const Vector3 &other) const
{
METHSPEC Vector3 Vector3::sub(const Vector3 &other) const {
return Vector3(x - other.x, y - other.y, z - other.z);
}
METHSPEC Vector3 Vector3::inverse() const
{
METHSPEC Vector3 Vector3::inverse() const {
return Vector3(-x, -y, -z);
}
METHSPEC Vector3 Vector3::scale(double scaling) const
{
METHSPEC Vector3 Vector3::scale(double scaling) const {
return Vector3(x * scaling, y * scaling, z * scaling);
}
METHSPEC double Vector3::getNorm() const
{
METHSPEC double Vector3::getNorm() const {
return sqrt(x * x + y * y + z * z);
}
METHSPEC Vector3 Vector3::normalize() const
{
METHSPEC Vector3 Vector3::normalize() const {
double norm = sqrt(x * x + y * y + z * z);
if (norm == 0.0)
{
if (norm == 0.0) {
return VECTOR_ZERO;
}
else
{
} else {
norm = 1.0 / norm;
return Vector3(x * norm, y * norm, z * norm);
}
}
METHSPEC double Vector3:: dotProduct(const Vector3 &other) const
{
METHSPEC double Vector3::dotProduct(const Vector3 &other) const {
return x * other.x + y * other.y + z * other.z;
}
METHSPEC Vector3 Vector3::crossProduct(const Vector3 &other) const
{
return Vector3(
y * other.z - z * other.y,
z * other.x - x * other.z,
x * other.y - y * other.x
);
METHSPEC Vector3 Vector3::crossProduct(const Vector3 &other) const {
return Vector3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);
}

View file

@ -3,33 +3,33 @@
#include <QtCore/qglobal.h>
#if defined(BASICS_LIBRARY)
# define BASICSSHARED_EXPORT Q_DECL_EXPORT
#define BASICSSHARED_EXPORT Q_DECL_EXPORT
#else
# define BASICSSHARED_EXPORT Q_DECL_IMPORT
#define BASICSSHARED_EXPORT Q_DECL_IMPORT
#endif
#include "system_global.h"
namespace paysages {
namespace basics {
class Vector3;
class Matrix4;
class BoundingBox;
class SpaceGridIterator;
class SpaceSegment;
class Color;
class NoiseGenerator;
class NoiseState;
class FractalNoise;
class Curve;
class ColorProfile;
class Texture2D;
class Texture3D;
class Texture4D;
class CappedCylinder;
class InfiniteRay;
class Sphere;
class InfinitePlane;
class Vector3;
class Matrix4;
class BoundingBox;
class SpaceGridIterator;
class SpaceSegment;
class Color;
class NoiseGenerator;
class NoiseState;
class FractalNoise;
class Curve;
class ColorProfile;
class Texture2D;
class Texture3D;
class Texture4D;
class CappedCylinder;
class InfiniteRay;
class Sphere;
class InfinitePlane;
}
}
using namespace paysages::basics;

View file

@ -5,24 +5,21 @@
#include "FloatNode.h"
#include "GodRaysDefinition.h"
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent):
DefinitionNode(parent, "atmosphere", "atmosphere")
{
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
: DefinitionNode(parent, "atmosphere", "atmosphere") {
godrays = new GodRaysDefinition(this);
daytime = new FloatNode(this, "daytime");
humidity = new FloatNode(this, "humidity");
sun_radius = new FloatNode(this, "sun_radius");
}
AtmosphereDefinition::~AtmosphereDefinition()
{
AtmosphereDefinition::~AtmosphereDefinition() {
}
void AtmosphereDefinition::save(PackStream* stream) const
{
void AtmosphereDefinition::save(PackStream *stream) const {
DefinitionNode::save(stream);
stream->write((int*)&model);
stream->write((int *)&model);
sun_color.save(stream);
stream->write(&dome_lighting);
stream->write(&moon_radius);
@ -31,19 +28,17 @@ void AtmosphereDefinition::save(PackStream* stream) const
int star_count = stars.size();
stream->write(&star_count);
for (const auto &star : stars)
{
for (const auto &star : stars) {
star.location.save(stream);
star.col.save(stream);
stream->write(&star.radius);
}
}
void AtmosphereDefinition::load(PackStream* stream)
{
void AtmosphereDefinition::load(PackStream *stream) {
DefinitionNode::load(stream);
stream->read((int*)&model);
stream->read((int *)&model);
sun_color.load(stream);
stream->read(&dome_lighting);
stream->read(&moon_radius);
@ -52,8 +47,7 @@ void AtmosphereDefinition::load(PackStream* stream)
int star_count;
stream->read(&star_count);
for (int i = 0; i < star_count; i++)
{
for (int i = 0; i < star_count; i++) {
Star star;
star.location.load(stream);
@ -66,11 +60,10 @@ void AtmosphereDefinition::load(PackStream* stream)
validate();
}
void AtmosphereDefinition::copy(DefinitionNode* _destination) const
{
void AtmosphereDefinition::copy(DefinitionNode *_destination) const {
DefinitionNode::copy(_destination);
AtmosphereDefinition* destination = (AtmosphereDefinition*)_destination;
AtmosphereDefinition *destination = (AtmosphereDefinition *)_destination;
destination->model = model;
destination->sun_color = sun_color;
@ -83,25 +76,19 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const
destination->validate();
}
void AtmosphereDefinition::setDayTime(double value)
{
void AtmosphereDefinition::setDayTime(double value) {
daytime->setValue(value);
}
void AtmosphereDefinition::setDayTime(int hour, int minute, int second)
{
void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
setDayTime((double)hour / 24.0 + (double)minute / 1440.0 + (double)second / 86400.0);
}
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const
{
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const {
double value = daytime->getValue();
if (value >= 0.0)
{
if (value >= 0.0) {
value = fmod(value, 1.0);
}
else
{
} else {
value = 1.0 - fmod(-value, 1.0);
}
value *= 86400.0;
@ -111,8 +98,7 @@ void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const
*second = value - *minute * 60.0;
}
void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
{
void AtmosphereDefinition::applyPreset(AtmospherePreset preset) {
sun_color.r = 1.0;
sun_color.g = 0.95;
sun_color.b = 0.9;
@ -124,35 +110,34 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
model = ATMOSPHERE_MODEL_BRUNETON;
switch (preset)
{
case ATMOSPHERE_PRESET_CLEAR_DAY:
setDayTime(15);
humidity->setValue(0.1);
dome_lighting = 0.2;
break;
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
setDayTime(17, 45);
humidity->setValue(0.1);
dome_lighting = 0.3;
break;
case ATMOSPHERE_PRESET_HAZY_MORNING:
setDayTime(8, 30);
humidity->setValue(0.4);
dome_lighting = 0.25;
break;
case ATMOSPHERE_PRESET_FOGGY:
setDayTime(15);
humidity->setValue(0.7);
dome_lighting = 0.1;
break;
case ATMOSPHERE_PRESET_STORMY:
setDayTime(15);
humidity->setValue(0.9);
dome_lighting = 0.05;
break;
default:
;
switch (preset) {
case ATMOSPHERE_PRESET_CLEAR_DAY:
setDayTime(15);
humidity->setValue(0.1);
dome_lighting = 0.2;
break;
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
setDayTime(17, 45);
humidity->setValue(0.1);
dome_lighting = 0.3;
break;
case ATMOSPHERE_PRESET_HAZY_MORNING:
setDayTime(8, 30);
humidity->setValue(0.4);
dome_lighting = 0.25;
break;
case ATMOSPHERE_PRESET_FOGGY:
setDayTime(15);
humidity->setValue(0.7);
dome_lighting = 0.1;
break;
case ATMOSPHERE_PRESET_STORMY:
setDayTime(15);
humidity->setValue(0.9);
dome_lighting = 0.05;
break;
default:
;
}
generateStars(2000);
@ -160,22 +145,22 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
validate();
}
void AtmosphereDefinition::generateStars(int count)
{
void AtmosphereDefinition::generateStars(int count) {
stars.clear();
for (int i = 0; i < count; ++i)
{
for (int i = 0; i < count; ++i) {
Star star;
star.location = Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() * 0.5) * 100000.0, (RandomGenerator::random() - 0.5) * 100000.0);
if (star.location.getNorm() < 30000.0)
{
star.location =
Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() * 0.5) * 100000.0,
(RandomGenerator::random() - 0.5) * 100000.0);
if (star.location.getNorm() < 30000.0) {
i--;
continue;
}
double brillance = RandomGenerator::random() * 0.05 + 0.1;
star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, 1.0);
star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03,
brillance + RandomGenerator::random() * 0.03, 1.0);
star.radius = 30.0 + RandomGenerator::random() * 20.0;
stars.push_back(star);

View file

@ -11,24 +11,17 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode
{
public:
typedef struct
{
class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
public:
typedef struct {
Vector3 location;
double radius;
Color col;
} Star;
public:
typedef enum
{
ATMOSPHERE_MODEL_DISABLED = 0,
ATMOSPHERE_MODEL_BRUNETON = 1
} AtmosphereModel;
typedef enum
{
public:
typedef enum { ATMOSPHERE_MODEL_DISABLED = 0, ATMOSPHERE_MODEL_BRUNETON = 1 } AtmosphereModel;
typedef enum {
ATMOSPHERE_PRESET_CLEAR_DAY = 0,
ATMOSPHERE_PRESET_CLEAR_SUNSET = 1,
ATMOSPHERE_PRESET_HAZY_MORNING = 2,
@ -36,19 +29,27 @@ public:
ATMOSPHERE_PRESET_STORMY = 4
} AtmospherePreset;
public:
AtmosphereDefinition(DefinitionNode* parent);
public:
AtmosphereDefinition(DefinitionNode *parent);
virtual ~AtmosphereDefinition();
virtual void save(PackStream* stream) const override;
virtual void load(PackStream* stream) override;
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void copy(DefinitionNode *destination) const override;
inline GodRaysDefinition *childGodRays() const {return godrays;}
inline FloatNode *propDayTime() const {return daytime;}
inline FloatNode *propHumidity() const {return humidity;}
inline FloatNode *propSunRadius() const {return sun_radius;}
inline GodRaysDefinition *childGodRays() const {
return godrays;
}
inline FloatNode *propDayTime() const {
return daytime;
}
inline FloatNode *propHumidity() const {
return humidity;
}
inline FloatNode *propSunRadius() const {
return sun_radius;
}
/**
* Set the daytime from a 0.0-1.0 value.
@ -57,7 +58,7 @@ public:
/**
* Set the daytime from hour/minute/second info.
*/
void setDayTime(int hour, int minute=0, int second=0);
void setDayTime(int hour, int minute = 0, int second = 0);
/**
* Get the daytime info, in hour/minute/second.
*/
@ -66,7 +67,7 @@ public:
void applyPreset(AtmospherePreset preset);
void generateStars(int count);
public:
public:
AtmosphereModel model;
Color sun_color;
@ -78,13 +79,12 @@ public:
std::vector<Star> stars;
private:
private:
GodRaysDefinition *godrays;
FloatNode *humidity;
FloatNode *daytime;
FloatNode *sun_radius;
};
}
}

View file

@ -4,9 +4,7 @@
#include "PackStream.h"
#include "BoundingBox.h"
CameraDefinition::CameraDefinition(DefinitionNode *parent):
DefinitionNode(parent, "camera", "camera")
{
CameraDefinition::CameraDefinition(DefinitionNode *parent) : DefinitionNode(parent, "camera", "camera") {
location.x = 0.0;
location.y = 0.0;
location.z = 0.0;
@ -25,8 +23,7 @@ CameraDefinition::CameraDefinition(DefinitionNode *parent):
validate();
}
void CameraDefinition::save(PackStream* stream) const
{
void CameraDefinition::save(PackStream *stream) const {
location.save(stream);
stream->write(&direction.r);
stream->write(&direction.phi);
@ -35,8 +32,7 @@ void CameraDefinition::save(PackStream* stream) const
stream->write(&perspective.yfov);
}
void CameraDefinition::load(PackStream* stream)
{
void CameraDefinition::load(PackStream *stream) {
location.load(stream);
stream->read(&direction.r);
stream->read(&direction.phi);
@ -47,9 +43,8 @@ void CameraDefinition::load(PackStream* stream)
validate();
}
void CameraDefinition::copy(DefinitionNode* _destination) const
{
CameraDefinition* destination = (CameraDefinition*)_destination;
void CameraDefinition::copy(DefinitionNode *_destination) const {
CameraDefinition *destination = (CameraDefinition *)_destination;
destination->location = location;
destination->direction = direction;
@ -60,10 +55,8 @@ void CameraDefinition::copy(DefinitionNode* _destination) const
destination->validate();
}
void CameraDefinition::validate()
{
if (location.y > 300.0)
{
void CameraDefinition::validate() {
if (location.y > 300.0) {
location.y = 300.0;
}
@ -85,7 +78,8 @@ void CameraDefinition::validate()
target = location.add(direction);
Matrix4 mperspective = Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
Matrix4 mperspective =
Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
unperspective = mperspective.inversed();
projector = mperspective.mult(Matrix4::newLookAt(location, target, up));
@ -95,33 +89,28 @@ void CameraDefinition::validate()
inv_y_factor = 1.0 / (0.5 * height);
}
double CameraDefinition::getRealDepth(const Vector3 &projected) const
{
double CameraDefinition::getRealDepth(const Vector3 &projected) const {
Vector3 v(projected.x * inv_x_factor - 1.0, -(projected.y * inv_x_factor - 1.0), projected.z);
return unperspective.transform(v).z;
}
void CameraDefinition::setLocation(const Vector3 &location)
{
void CameraDefinition::setLocation(const Vector3 &location) {
this->location = location;
validate();
}
void CameraDefinition::setLocationCoords(double x, double y, double z)
{
void CameraDefinition::setLocationCoords(double x, double y, double z) {
location = Vector3(x, y, z);
validate();
}
void CameraDefinition::setTarget(const Vector3 &target)
{
void CameraDefinition::setTarget(const Vector3 &target) {
Vector3 forward;
forward = target.sub(location);
if (forward.getNorm() < 0.0000001)
{
if (forward.getNorm() < 0.0000001) {
return;
}
@ -130,77 +119,66 @@ void CameraDefinition::setTarget(const Vector3 &target)
validate();
}
void CameraDefinition::setTargetCoords(double x, double y, double z)
{
void CameraDefinition::setTargetCoords(double x, double y, double z) {
setTarget(Vector3(x, y, z));
}
void CameraDefinition::setRoll(double angle)
{
void CameraDefinition::setRoll(double angle) {
roll = angle;
validate();
}
void CameraDefinition::setZoomToTarget(double zoom)
{
void CameraDefinition::setZoomToTarget(double zoom) {
direction.r = zoom;
location = target.add(Vector3(direction).scale(-1.0));
validate();
}
void CameraDefinition::setFov(double fov)
{
void CameraDefinition::setFov(double fov) {
perspective.yfov = fov;
validate();
}
void CameraDefinition::strafeForward(double value)
{
void CameraDefinition::strafeForward(double value) {
location = location.add(forward.scale(value));
validate();
}
void CameraDefinition::strafeRight(double value)
{
void CameraDefinition::strafeRight(double value) {
location = location.add(right.scale(value));
validate();
}
void CameraDefinition::strafeUp(double value)
{
void CameraDefinition::strafeUp(double value) {
location = location.add(up.scale(value));
validate();
}
void CameraDefinition::rotateYaw(double value)
{
void CameraDefinition::rotateYaw(double value) {
direction.phi += value;
validate();
}
void CameraDefinition::rotatePitch(double value)
{
void CameraDefinition::rotatePitch(double value) {
direction.theta += value;
validate();
}
void CameraDefinition::rotateRoll(double value)
{
void CameraDefinition::rotateRoll(double value) {
roll += value;
validate();
}
void CameraDefinition::setRenderSize(int width, int height)
{
void CameraDefinition::setRenderSize(int width, int height) {
this->width = (double)width;
this->height = (double)height;
perspective.xratio = this->width / this->height;
@ -208,11 +186,9 @@ void CameraDefinition::setRenderSize(int width, int height)
validate();
}
Vector3 CameraDefinition::project(const Vector3 &point) const
{
Vector3 CameraDefinition::project(const Vector3 &point) const {
Vector3 tpoint = projector.transform(point);
if (tpoint.z < 1.0)
{
if (tpoint.z < 1.0) {
tpoint.x = -tpoint.x;
tpoint.y = -tpoint.y;
}
@ -221,19 +197,16 @@ Vector3 CameraDefinition::project(const Vector3 &point) const
return tpoint;
}
Vector3 CameraDefinition::unproject(const Vector3 &point) const
{
Vector3 CameraDefinition::unproject(const Vector3 &point) const {
Vector3 tpoint(point.x / (0.5 * width) - 1.0, -(point.y / (0.5 * height) - 1.0), point.z);
if (tpoint.z < 1.0)
{
if (tpoint.z < 1.0) {
tpoint.x = -tpoint.x;
tpoint.y = -tpoint.y;
}
return unprojector.transform(tpoint);
}
int CameraDefinition::isBoxInView(const Vector3 &center, double xsize, double ysize, double zsize) const
{
int CameraDefinition::isBoxInView(const Vector3 &center, double xsize, double ysize, double zsize) const {
BoundingBox box;
box.pushPoint(center.add(Vector3(-xsize, -ysize, -zsize)));
@ -242,8 +215,7 @@ int CameraDefinition::isBoxInView(const Vector3 &center, double xsize, double ys
return isUnprojectedBoxInView(box);
}
int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const
{
int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const {
BoundingBox projected;
projected.pushPoint(project(Vector3(box.xmin, box.ymin, box.zmin)));
@ -258,23 +230,19 @@ int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const
return isProjectedBoxInView(projected);
}
int CameraDefinition::isProjectedBoxInView(const BoundingBox &box) const
{
if (box.xmin <= width && box.xmax >= 0.0 && box.ymin <= height && box.ymax >= 0.0 && box.zmax >= perspective.znear)
{
int CameraDefinition::isProjectedBoxInView(const BoundingBox &box) const {
if (box.xmin <= width && box.xmax >= 0.0 && box.ymin <= height && box.ymax >= 0.0 &&
box.zmax >= perspective.znear) {
double dx = box.xmax - box.xmin;
double dy = box.ymax - box.ymin;
return (int)ceil(dx) * (int)ceil(dy);
}
else
{
} else {
return 0;
}
}
bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, double factor)
{
bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, double factor) {
double dx, dy, dz, dr, dphi, dtheta, droll;
dx = wanted->location.x - location.x;
@ -285,12 +253,10 @@ bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, doubl
dtheta = wanted->direction.theta - direction.theta;
droll = wanted->roll - roll;
if (fabs(dx) < 0.000001 && fabs(dy) < 0.000001 && fabs(dz) < 0.000001 && fabs(dr) < 0.000001 && fabs(dphi) < 0.000001 && fabs(dtheta) < 0.000001 && fabs(droll) < 0.000001)
{
if (fabs(dx) < 0.000001 && fabs(dy) < 0.000001 && fabs(dz) < 0.000001 && fabs(dr) < 0.000001 &&
fabs(dphi) < 0.000001 && fabs(dtheta) < 0.000001 && fabs(droll) < 0.000001) {
return false;
}
else
{
} else {
location.x += dx * factor;
location.y += dy * factor;
location.z += dz * factor;

View file

@ -11,36 +11,56 @@
namespace paysages {
namespace definition {
typedef struct
{
typedef struct {
double yfov;
double xratio;
double znear;
double zfar;
} CameraPerspective;
class DEFINITIONSHARED_EXPORT CameraDefinition: public DefinitionNode
{
public:
class DEFINITIONSHARED_EXPORT CameraDefinition : public DefinitionNode {
public:
CameraDefinition(DefinitionNode *parent = NULL);
virtual void save(PackStream* pack) const override;
virtual void load(PackStream* pack) override;
virtual void save(PackStream *pack) const override;
virtual void load(PackStream *pack) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void copy(DefinitionNode *destination) const override;
virtual void validate() override;
inline const Vector3 &getLocation() const {return location;}
inline const Vector3 &getTarget() const {return target;}
inline const Vector3 &getUpVector() const {return up;}
inline double getRoll() const {return roll;}
inline Vector3 getDirection() const {return Vector3(direction);}
inline const Vector3 &getDirectionNormalized() const {return forward;}
inline const Matrix4 &getTransformationMatrix() const {return projector;}
inline const VectorSpherical &getDirectionSpherical() const {return direction;}
inline const CameraPerspective &getPerspective() const {return perspective;}
inline double getWidth() const {return width;}
inline double getHeight() const {return height;}
inline const Vector3 &getLocation() const {
return location;
}
inline const Vector3 &getTarget() const {
return target;
}
inline const Vector3 &getUpVector() const {
return up;
}
inline double getRoll() const {
return roll;
}
inline Vector3 getDirection() const {
return Vector3(direction);
}
inline const Vector3 &getDirectionNormalized() const {
return forward;
}
inline const Matrix4 &getTransformationMatrix() const {
return projector;
}
inline const VectorSpherical &getDirectionSpherical() const {
return direction;
}
inline const CameraPerspective &getPerspective() const {
return perspective;
}
inline double getWidth() const {
return width;
}
inline double getHeight() const {
return height;
}
double getRealDepth(const Vector3 &projected) const;
@ -68,7 +88,7 @@ public:
bool transitionToAnother(const CameraDefinition *wanted, double factor);
private:
private:
/* Definition */
Vector3 location;
VectorSpherical direction;
@ -90,7 +110,6 @@ private:
double inv_x_factor;
double inv_y_factor;
};
}
}

View file

@ -6,9 +6,7 @@
#include "PackStream.h"
#include "FloatNode.h"
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode* parent):
DefinitionNode(parent, "layer", "cloudlayer")
{
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent) : DefinitionNode(parent, "layer", "cloudlayer") {
type = CIRRUS;
altitude = 0.5;
scaling = 0.5;
@ -18,26 +16,22 @@ CloudLayerDefinition::CloudLayerDefinition(DefinitionNode* parent):
zoffset = new FloatNode(this, "zoffset");
}
CloudLayerDefinition::~CloudLayerDefinition()
{
CloudLayerDefinition::~CloudLayerDefinition() {
}
CloudLayerDefinition* CloudLayerDefinition::newCopy(const CloudLayerDefinition& other, DefinitionNode* parent)
{
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
CloudLayerDefinition *CloudLayerDefinition::newCopy(const CloudLayerDefinition &other, DefinitionNode *parent) {
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
other.copy(layer);
return layer;
}
CloudLayerDefinition* CloudLayerDefinition::newCopy(DefinitionNode* parent) const
{
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
CloudLayerDefinition *CloudLayerDefinition::newCopy(DefinitionNode *parent) const {
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
copy(layer);
return layer;
}
void CloudLayerDefinition::save(PackStream* stream) const
{
void CloudLayerDefinition::save(PackStream *stream) const {
DefinitionNode::save(stream);
int clouds_type = (int)type;
@ -50,8 +44,7 @@ void CloudLayerDefinition::save(PackStream* stream) const
noise_state.save(stream);
}
void CloudLayerDefinition::load(PackStream* stream)
{
void CloudLayerDefinition::load(PackStream *stream) {
DefinitionNode::load(stream);
int clouds_type;
@ -67,11 +60,10 @@ void CloudLayerDefinition::load(PackStream* stream)
validate();
}
void CloudLayerDefinition::copy(DefinitionNode* _destination) const
{
void CloudLayerDefinition::copy(DefinitionNode *_destination) const {
DefinitionNode::copy(_destination);
CloudLayerDefinition* destination = (CloudLayerDefinition*)_destination;
CloudLayerDefinition *destination = (CloudLayerDefinition *)_destination;
destination->type = type;
destination->altitude = altitude;
@ -81,12 +73,10 @@ void CloudLayerDefinition::copy(DefinitionNode* _destination) const
noise_state.copy(&destination->noise_state);
}
void CloudLayerDefinition::validate()
{
void CloudLayerDefinition::validate() {
DefinitionNode::validate();
if (scaling < 0.1)
{
if (scaling < 0.1) {
scaling = 0.1;
}
}

View file

@ -10,28 +10,32 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode
{
public:
CloudLayerDefinition(DefinitionNode* parent);
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode {
public:
CloudLayerDefinition(DefinitionNode *parent);
virtual ~CloudLayerDefinition();
inline const NoiseState &getNoiseState() const {return noise_state;}
inline FloatNode *propXOffset() const {return xoffset;}
inline FloatNode *propZOffset() const {return zoffset;}
inline const NoiseState &getNoiseState() const {
return noise_state;
}
inline FloatNode *propXOffset() const {
return xoffset;
}
inline FloatNode *propZOffset() const {
return zoffset;
}
static CloudLayerDefinition* newCopy(const CloudLayerDefinition& other, DefinitionNode* parent);
CloudLayerDefinition* newCopy(DefinitionNode* parent) const;
static CloudLayerDefinition *newCopy(const CloudLayerDefinition &other, DefinitionNode *parent);
CloudLayerDefinition *newCopy(DefinitionNode *parent) const;
virtual void save(PackStream* pack) const override;
virtual void load(PackStream* pack) override;
virtual void save(PackStream *pack) const override;
virtual void load(PackStream *pack) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void copy(DefinitionNode *destination) const override;
virtual void validate() override;
public:
typedef enum
{
public:
typedef enum {
STRATUS,
NIMBOSTRATUS,
CUMULUS,
@ -44,18 +48,17 @@ public:
CIRRUS
} CloudsType;
public:
public:
CloudsType type;
NoiseState noise_state;
double altitude;
double scaling;
double coverage;
private:
private:
FloatNode *xoffset;
FloatNode *zoffset;
};
}
}

View file

@ -2,23 +2,18 @@
#include "CloudLayerDefinition.h"
static DefinitionNode* _layerConstructor(Layers* parent)
{
static DefinitionNode *_layerConstructor(Layers *parent) {
return new CloudLayerDefinition(parent);
}
CloudsDefinition::CloudsDefinition(DefinitionNode* parent):
Layers(parent, "clouds", _layerConstructor)
{
CloudsDefinition::CloudsDefinition(DefinitionNode *parent) : Layers(parent, "clouds", _layerConstructor) {
}
void CloudsDefinition::applyPreset(CloudsPreset preset)
{
void CloudsDefinition::applyPreset(CloudsPreset preset) {
clear();
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY)
{
CloudLayerDefinition* layer = new CloudLayerDefinition(this);
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY) {
CloudLayerDefinition *layer = new CloudLayerDefinition(this);
layer->type = CloudLayerDefinition::STRATOCUMULUS;
layer->setName("Strato-cumulus");
addLayer(layer);

View file

@ -8,20 +8,17 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers
{
public:
CloudsDefinition(DefinitionNode* parent);
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers {
public:
CloudsDefinition(DefinitionNode *parent);
inline CloudLayerDefinition* getCloudLayer(int position) const {return (CloudLayerDefinition*)getLayer(position);}
inline CloudLayerDefinition *getCloudLayer(int position) const {
return (CloudLayerDefinition *)getLayer(position);
}
typedef enum
{
CLOUDS_PRESET_PARTLY_CLOUDY
} CloudsPreset;
typedef enum { CLOUDS_PRESET_PARTLY_CLOUDY } CloudsPreset;
void applyPreset(CloudsPreset preset);
};
}
}

View file

@ -2,7 +2,5 @@
#include "DefinitionNode.h"
DefinitionDiff::DefinitionDiff(const DefinitionNode *node):
type_name(node->getTypeName()), path(node->getPath())
{
DefinitionDiff::DefinitionDiff(const DefinitionNode *node) : type_name(node->getTypeName()), path(node->getPath()) {
}

View file

@ -11,19 +11,21 @@ namespace definition {
*
* Diffs are used to undo/redo changes.
*/
class DEFINITIONSHARED_EXPORT DefinitionDiff
{
public:
class DEFINITIONSHARED_EXPORT DefinitionDiff {
public:
DefinitionDiff(const DefinitionNode *node);
inline const std::string &getTypeName() const {return type_name;}
inline const std::string &getPath() const {return path;}
inline const std::string &getTypeName() const {
return type_name;
}
inline const std::string &getPath() const {
return path;
}
private:
private:
std::string type_name;
std::string path;
};
}
}

View file

@ -8,171 +8,123 @@
#include <cassert>
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name):
parent(parent), type_name(type_name), name(name)
{
if (parent)
{
DefinitionNode::DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name)
: parent(parent), type_name(type_name), name(name) {
if (parent) {
root = parent->root;
parent->addChild(this);
diffs = NULL;
}
else
{
} else {
root = this;
diffs = new DiffManager(this);
}
}
DefinitionNode::~DefinitionNode()
{
if (parent)
{
DefinitionNode::~DefinitionNode() {
if (parent) {
parent->removeChild(this);
parent = NULL;
}
if (diffs)
{
if (diffs) {
delete diffs;
diffs = NULL;
}
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
std::vector<DefinitionNode*> children_copy = children;
for (auto child:children_copy)
{
if (child->getParent() == this)
{
std::vector<DefinitionNode *> children_copy = children;
for (auto child : children_copy) {
if (child->getParent() == this) {
delete child;
}
}
}
void DefinitionNode::setName(const std::string &name)
{
void DefinitionNode::setName(const std::string &name) {
this->name = name;
}
const Scenery* DefinitionNode::getScenery() const
{
if (parent)
{
const Scenery *DefinitionNode::getScenery() const {
if (parent) {
return parent->getScenery();
}
else
{
} else {
return NULL;
}
}
std::string DefinitionNode::toString(int indent) const
{
std::string DefinitionNode::toString(int indent) const {
std::string result;
for (int i = 0; i < indent; i++)
{
for (int i = 0; i < indent; i++) {
result += " ";
}
result += name;
if (not children.empty())
{
for (auto &child: children)
{
if (not children.empty()) {
for (auto &child : children) {
result += "\n" + child->toString(indent + 1);
}
}
return result;
}
std::string DefinitionNode::getPath() const
{
if (parent == root)
{
std::string DefinitionNode::getPath() const {
if (parent == root) {
return parent->getPath() + name;
}
else if (parent)
{
} else if (parent) {
return parent->getPath() + "/" + name;
}
else
{
} else {
return "/";
}
}
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const
{
if (path.empty())
{
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const {
if (path.empty()) {
return NULL;
}
else if (path[0] == '/')
{
if (path.length() == 1)
{
} else if (path[0] == '/') {
if (path.length() == 1) {
return root;
}
else if (root == this)
{
} else if (root == this) {
return findByPath(path.substr(1));
}
else
{
} else {
return root->findByPath(path);
}
}
else
{
} else {
size_t seppos = path.find("/");
std::string child_name = (seppos == std::string::npos) ? path : path.substr(0, seppos);
DefinitionNode *child = ((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
if (child)
{
if (seppos == std::string::npos)
{
DefinitionNode *child =
((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
if (child) {
if (seppos == std::string::npos) {
return child;
}
else
{
} else {
return child->findByPath(path.substr(seppos + 1));
}
}
else
{
} else {
return NULL;
}
}
}
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
{
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool) {
// Only do type check, subclasses will do the rest
if (diff->getTypeName() == type_name)
{
if (diff->getTypeName() == type_name) {
return true;
}
else
{
Logs::error() << "Can't apply " << diff->getTypeName() << " diff to " << getName() << " " << type_name << " node" << std::endl;
} else {
Logs::error() << "Can't apply " << diff->getTypeName() << " diff to " << getName() << " " << type_name
<< " node" << std::endl;
return false;
}
}
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const
{
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const {
}
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff)
{
if (root && root->diffs)
{
if (init_diff)
{
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff) {
if (root && root->diffs) {
if (init_diff) {
std::vector<const DefinitionDiff *> diffs;
generateInitDiffs(&diffs);
for (auto diff: diffs)
{
for (auto diff : diffs) {
watcher->nodeChanged(this, diff);
delete diff;
}
@ -181,37 +133,29 @@ void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff)
}
}
int DefinitionNode::getWatcherCount() const
{
if (root && root->diffs)
{
int DefinitionNode::getWatcherCount() const {
if (root && root->diffs) {
return root->diffs->getWatcherCount(this);
}
else
{
} else {
return 0;
}
}
void DefinitionNode::save(PackStream* stream) const
{
void DefinitionNode::save(PackStream *stream) const {
int children_count = (int)children.size();
stream->write(&children_count);
for (auto child: children)
{
for (auto child : children) {
stream->write(child->name);
int child_size = child->getStreamSize();
if (child_size >= 0)
{
if (child_size >= 0) {
stream->write(&child_size);
child->save(stream);
}
else
{
} else {
// Child size not known, write it to a temporary stream to know it
Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream" << std::endl;
Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream"
<< std::endl;
PackStream substream;
child->save(&substream);
stream->writeFromBuffer(substream, true);
@ -219,27 +163,22 @@ void DefinitionNode::save(PackStream* stream) const
}
}
void DefinitionNode::load(PackStream* stream)
{
void DefinitionNode::load(PackStream *stream) {
int children_count;
stream->read(&children_count);
for (int i = 0; i < children_count; i++)
{
for (int i = 0; i < children_count; i++) {
std::string child_name = stream->readString();
int child_size;
stream->read(&child_size);
DefinitionNode *child = findChildByName(child_name);
if (child)
{
if (child) {
// TODO type check
child->load(stream);
}
else
{
} else {
// TODO Ask subclass if it can instanciate a child
// Else skip length of unknown child
stream->skipBytes(child_size);
@ -248,85 +187,65 @@ void DefinitionNode::load(PackStream* stream)
}
}
void DefinitionNode::copy(DefinitionNode* destination) const
{
if (destination->getTypeName() == getTypeName())
{
void DefinitionNode::copy(DefinitionNode *destination) const {
if (destination->getTypeName() == getTypeName()) {
destination->setName(name);
for (auto &child: children)
{
for (auto &child : children) {
DefinitionNode *dest_child = destination->findChildByName(child->name);
if (dest_child)
{
if (dest_child) {
child->copy(dest_child);
}
else
{
Logs::warning() << "Can't copy to child " << child->name << " of " << destination->getTypeName() << std::endl;
} else {
Logs::warning() << "Can't copy to child " << child->name << " of " << destination->getTypeName()
<< std::endl;
}
}
}
else
{
} else {
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
}
}
void DefinitionNode::validate()
{
for (auto child: children)
{
void DefinitionNode::validate() {
for (auto child : children) {
child->validate();
}
}
void DefinitionNode::addChild(DefinitionNode* child)
{
if (std::find(children.begin(), children.end(), child) == children.end())
{
void DefinitionNode::addChild(DefinitionNode *child) {
if (std::find(children.begin(), children.end(), child) == children.end()) {
children.push_back(child);
child->parent = this;
child->root = this->root;
}
}
void DefinitionNode::removeChild(DefinitionNode* child)
{
std::vector<DefinitionNode*>::iterator it = std::find(children.begin(), children.end(), child);
if (it != children.end())
{
void DefinitionNode::removeChild(DefinitionNode *child) {
std::vector<DefinitionNode *>::iterator it = std::find(children.begin(), children.end(), child);
if (it != children.end()) {
child->parent = NULL;
children.erase(it);
}
else
{
Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'" << std::endl;
} else {
Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'"
<< std::endl;
}
}
DefinitionNode *DefinitionNode::findChildByName(const std::string name)
{
for (auto child: children)
{
if (child->name == name)
{
DefinitionNode *DefinitionNode::findChildByName(const std::string name) {
for (auto child : children) {
if (child->name == name) {
return child;
}
}
return NULL;
}
int DefinitionNode::getStreamSize() const
{
int DefinitionNode::getStreamSize() const {
return -1;
}
void DefinitionNode::addDiff(const DefinitionDiff *diff)
{
void DefinitionNode::addDiff(const DefinitionDiff *diff) {
assert(diff->getTypeName() == type_name);
if (root && root->diffs)
{
if (root && root->diffs) {
root->diffs->addDiff(this, diff);
}
}

View file

@ -9,29 +9,40 @@ namespace definition {
/**
* Base class for all nodes of the definition tree.
*/
class DEFINITIONSHARED_EXPORT DefinitionNode
{
public:
DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name = "");
class DEFINITIONSHARED_EXPORT DefinitionNode {
public:
DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name = "");
virtual ~DefinitionNode();
virtual void save(PackStream* stream) const;
virtual void load(PackStream* stream);
virtual void save(PackStream *stream) const;
virtual void load(PackStream *stream);
virtual void copy(DefinitionNode* destination) const;
virtual void copy(DefinitionNode *destination) const;
virtual void validate();
inline const std::string &getName() const {return name;}
inline const std::string &getName() const {
return name;
}
virtual void setName(const std::string &name);
inline const std::string &getTypeName() const {return type_name;}
inline const std::string &getTypeName() const {
return type_name;
}
virtual const Scenery* getScenery() const;
virtual const Scenery *getScenery() const;
inline const DefinitionNode *getParent() const {return parent;}
inline const DefinitionNode *getRoot() const {return root;}
inline DiffManager *getDiffManager() const {return diffs;}
inline int getChildrenCount() const {return children.size();}
inline const DefinitionNode *getParent() const {
return parent;
}
inline const DefinitionNode *getRoot() const {
return root;
}
inline DiffManager *getDiffManager() const {
return diffs;
}
inline int getChildrenCount() const {
return children.size();
}
/**
* Return a string representation of the tree (mainly for debugging purposes).
@ -59,7 +70,7 @@ public:
*
* Return true if the diff could be applied.
*/
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false);
/**
* Fill a diff array to be applied to initialize a proper state for a watcher.
@ -75,16 +86,16 @@ public:
*
* If *init_diff* is set to true, a first diff (or several) will be be pushed immediately to initialize the state.
*/
void addWatcher(DefinitionWatcher *watcher, bool init_diff=false);
void addWatcher(DefinitionWatcher *watcher, bool init_diff = false);
/**
* Get the current number of watchers.
*/
int getWatcherCount() const;
protected:
void addChild(DefinitionNode* child);
void removeChild(DefinitionNode* child);
protected:
void addChild(DefinitionNode *child);
void removeChild(DefinitionNode *child);
virtual DefinitionNode *findChildByName(const std::string name);
/**
@ -104,15 +115,14 @@ protected:
*/
void addDiff(const DefinitionDiff *diff);
private:
private:
DefinitionNode *parent;
DefinitionNode *root;
DiffManager *diffs;
std::string type_name;
std::string name;
std::vector<DefinitionNode*> children;
std::vector<DefinitionNode *> children;
};
}
}

View file

@ -1,7 +1,4 @@
#include "DefinitionWatcher.h"
DefinitionWatcher::DefinitionWatcher()
{
DefinitionWatcher::DefinitionWatcher() {
}

View file

@ -11,9 +11,8 @@ namespace definition {
*
* Watchers will be registered in DiffManager to receive DefinitionDiff objects.
*/
class DEFINITIONSHARED_EXPORT DefinitionWatcher
{
public:
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
public:
DefinitionWatcher();
/**
@ -21,7 +20,6 @@ public:
*/
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
};
}
}

View file

@ -4,38 +4,29 @@
#include "DefinitionDiff.h"
#include "DefinitionWatcher.h"
DiffManager::DiffManager(DefinitionNode *tree):
tree(tree)
{
DiffManager::DiffManager(DefinitionNode *tree) : tree(tree) {
undone = 0;
}
DiffManager::~DiffManager()
{
for (auto diff: diffs)
{
DiffManager::~DiffManager() {
for (auto diff : diffs) {
delete diff;
}
diffs.clear();
}
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher)
{
if (std::find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end())
{
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher) {
if (std::find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end()) {
watchers[node].push_back(watcher);
}
}
int DiffManager::getWatcherCount(const DefinitionNode *node)
{
int DiffManager::getWatcherCount(const DefinitionNode *node) {
return watchers[node].size();
}
void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
{
while (undone > 0)
{
void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff) {
while (undone > 0) {
// truncate diffs ahead
delete diffs.back();
diffs.pop_back();
@ -47,16 +38,13 @@ void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
// TODO Delayed commit (with merge of consecutive diffs)
node->applyDiff(diff);
for (auto watcher: watchers[node])
{
for (auto watcher : watchers[node]) {
watcher->nodeChanged(node, diff);
}
}
void DiffManager::undo()
{
if (undone < (int)diffs.size())
{
void DiffManager::undo() {
if (undone < (int)diffs.size()) {
undone++;
const DefinitionDiff *diff = diffs[diffs.size() - undone];
@ -64,18 +52,15 @@ void DiffManager::undo()
DefinitionNode *node = tree->findByPath(diff->getPath());
node->applyDiff(diff, true);
for (auto watcher: watchers[node])
{
for (auto watcher : watchers[node]) {
// FIXME Reverse diff
watcher->nodeChanged(node, diff);
}
}
}
void DiffManager::redo()
{
if (undone > 0)
{
void DiffManager::redo() {
if (undone > 0) {
const DefinitionDiff *diff = diffs[diffs.size() - undone];
undone--;
@ -83,10 +68,8 @@ void DiffManager::redo()
DefinitionNode *node = tree->findByPath(diff->getPath());
node->applyDiff(diff);
for (auto watcher: watchers[node])
{
for (auto watcher : watchers[node]) {
watcher->nodeChanged(node, diff);
}
}
}

View file

@ -14,9 +14,8 @@ namespace definition {
*
* Watchers can register themselves to received these diffs.
*/
class DEFINITIONSHARED_EXPORT DiffManager
{
public:
class DEFINITIONSHARED_EXPORT DiffManager {
public:
DiffManager(DefinitionNode *tree);
~DiffManager();
@ -47,13 +46,12 @@ public:
*/
void redo();
private:
private:
DefinitionNode *tree;
int undone;
std::vector<const DefinitionDiff *> diffs;
std::map<const DefinitionNode *, std::vector<DefinitionWatcher *>> watchers;
};
}
}

View file

@ -1,6 +1,5 @@
#include "FloatDiff.h"
FloatDiff::FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue):
DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue)
{
FloatDiff::FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue)
: DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue) {
}

View file

@ -11,19 +11,21 @@ namespace definition {
/**
* Diff for a FloatNode.
*/
class DEFINITIONSHARED_EXPORT FloatDiff: public DefinitionDiff
{
public:
class DEFINITIONSHARED_EXPORT FloatDiff : public DefinitionDiff {
public:
FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue);
inline double getOldValue() const {return oldvalue;}
inline double getNewValue() const {return newvalue;}
inline double getOldValue() const {
return oldvalue;
}
inline double getNewValue() const {
return newvalue;
}
private:
private:
double oldvalue;
double newvalue;
};
}
}

View file

@ -6,13 +6,11 @@
#include <sstream>
#include <cassert>
FloatNode::FloatNode(DefinitionNode* parent, const std::string &name, double value):
DefinitionNode(parent, name, "float"), value(value)
{
FloatNode::FloatNode(DefinitionNode *parent, const std::string &name, double value)
: DefinitionNode(parent, name, "float"), value(value) {
}
std::string FloatNode::toString(int indent) const
{
std::string FloatNode::toString(int indent) const {
std::ostringstream stream;
stream << DefinitionNode::toString(indent) << " " << value;
@ -20,47 +18,36 @@ std::string FloatNode::toString(int indent) const
return stream.str();
}
void FloatNode::save(PackStream *stream) const
{
void FloatNode::save(PackStream *stream) const {
stream->write(&value);
}
void FloatNode::load(PackStream *stream)
{
void FloatNode::load(PackStream *stream) {
stream->read(&value);
}
void FloatNode::copy(DefinitionNode *destination) const
{
if (destination->getTypeName() == getTypeName())
{
void FloatNode::copy(DefinitionNode *destination) const {
if (destination->getTypeName() == getTypeName()) {
((FloatNode *)destination)->value = value;
}
else
{
} else {
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
}
}
void FloatNode::setValue(double new_value)
{
void FloatNode::setValue(double new_value) {
addDiff(produceDiff(new_value));
}
const FloatDiff *FloatNode::produceDiff(double new_value) const
{
const FloatDiff *FloatNode::produceDiff(double new_value) const {
return new FloatDiff(this, value, new_value);
}
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const
{
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
diffs->push_back(produceDiff(value));
}
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
{
if (!DefinitionNode::applyDiff(diff, backward))
{
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward) {
if (!DefinitionNode::applyDiff(diff, backward)) {
return false;
}
@ -70,19 +57,15 @@ bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
double previous = backward ? float_diff->getNewValue() : float_diff->getOldValue();
double next = backward ? float_diff->getOldValue() : float_diff->getNewValue();
if (value == previous)
{
if (value == previous) {
value = next;
return true;
}
else
{
} else {
Logs::error() << "Can't apply float diff " << previous << " => " << next << " to " << getName() << std::endl;
return false;
}
}
void FloatNode::addValue(double added)
{
void FloatNode::addValue(double added) {
setValue(value + added);
}

View file

@ -11,17 +11,18 @@ namespace definition {
/**
* Node with a single floating point numeric value, for the definition tree.
*/
class DEFINITIONSHARED_EXPORT FloatNode: public DefinitionNode
{
public:
FloatNode(DefinitionNode* parent, const std::string &name, double value = 0.0);
class DEFINITIONSHARED_EXPORT FloatNode : public DefinitionNode {
public:
FloatNode(DefinitionNode *parent, const std::string &name, double value = 0.0);
inline double getValue() const {return value;}
inline double getValue() const {
return value;
}
virtual std::string toString(int indent) const override;
virtual void save(PackStream* stream) const override;
virtual void load(PackStream* stream) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode *destination) const override;
/**
* Change the float value stored.
@ -31,13 +32,13 @@ public:
void setValue(double new_value);
const FloatDiff *produceDiff(double new_value) const;
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
void addValue(double added);
private:
private:
double value;
};
}
}

View file

@ -2,11 +2,8 @@
#include "FloatNode.h"
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent):
DefinitionNode(parent, "godrays", "godrays")
{
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent) : DefinitionNode(parent, "godrays", "godrays") {
penetration = new FloatNode(this, "penetration", 0.01);
resistance = new FloatNode(this, "resistance", 0.3);
boost = new FloatNode(this, "boost", 8.0);
}

View file

@ -8,21 +8,25 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT GodRaysDefinition: public DefinitionNode
{
public:
class DEFINITIONSHARED_EXPORT GodRaysDefinition : public DefinitionNode {
public:
GodRaysDefinition(DefinitionNode *parent);
inline FloatNode *propPenetration() const {return penetration;}
inline FloatNode *propResistance() const {return resistance;}
inline FloatNode *propBoost() const {return boost;}
inline FloatNode *propPenetration() const {
return penetration;
}
inline FloatNode *propResistance() const {
return resistance;
}
inline FloatNode *propBoost() const {
return boost;
}
private:
private:
FloatNode *penetration;
FloatNode *resistance;
FloatNode *boost;
};
}
}

View file

@ -1,7 +1,5 @@
#include "IntDiff.h"
IntDiff::IntDiff(const DefinitionNode *node, int oldvalue, int newvalue):
DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue)
{
IntDiff::IntDiff(const DefinitionNode *node, int oldvalue, int newvalue)
: DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue) {
}

View file

@ -11,19 +11,21 @@ namespace definition {
/**
* Diff for an IntNode.
*/
class DEFINITIONSHARED_EXPORT IntDiff: public DefinitionDiff
{
public:
class DEFINITIONSHARED_EXPORT IntDiff : public DefinitionDiff {
public:
IntDiff(const DefinitionNode *node, int oldvalue, int newvalue);
inline int getOldValue() const {return oldvalue;}
inline int getNewValue() const {return newvalue;}
inline int getOldValue() const {
return oldvalue;
}
inline int getNewValue() const {
return newvalue;
}
private:
private:
int oldvalue;
int newvalue;
};
}
}

View file

@ -6,13 +6,11 @@
#include <sstream>
#include <cassert>
IntNode::IntNode(DefinitionNode* parent, const std::string &name, int value):
DefinitionNode(parent, name, "int"), value(value)
{
IntNode::IntNode(DefinitionNode *parent, const std::string &name, int value)
: DefinitionNode(parent, name, "int"), value(value) {
}
std::string IntNode::toString(int indent) const
{
std::string IntNode::toString(int indent) const {
std::ostringstream stream;
stream << DefinitionNode::toString(indent) << " " << value;
@ -20,47 +18,36 @@ std::string IntNode::toString(int indent) const
return stream.str();
}
void IntNode::save(PackStream *stream) const
{
void IntNode::save(PackStream *stream) const {
stream->write(&value);
}
void IntNode::load(PackStream *stream)
{
void IntNode::load(PackStream *stream) {
stream->read(&value);
}
void IntNode::copy(DefinitionNode *destination) const
{
if (destination->getTypeName() == getTypeName())
{
void IntNode::copy(DefinitionNode *destination) const {
if (destination->getTypeName() == getTypeName()) {
((IntNode *)destination)->value = value;
}
else
{
} else {
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
}
}
void IntNode::setValue(int new_value)
{
void IntNode::setValue(int new_value) {
addDiff(produceDiff(new_value));
}
const IntDiff *IntNode::produceDiff(int new_value) const
{
const IntDiff *IntNode::produceDiff(int new_value) const {
return new IntDiff(this, value, new_value);
}
void IntNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const
{
void IntNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
diffs->push_back(produceDiff(value));
}
bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward)
{
if (!DefinitionNode::applyDiff(diff, backward))
{
bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward) {
if (!DefinitionNode::applyDiff(diff, backward)) {
return false;
}
@ -70,13 +57,10 @@ bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward)
double previous = backward ? int_diff->getNewValue() : int_diff->getOldValue();
double next = backward ? int_diff->getOldValue() : int_diff->getNewValue();
if (value == previous)
{
if (value == previous) {
value = next;
return true;
}
else
{
} else {
Logs::error() << "Can't apply int diff " << previous << " => " << next << " to " << getName() << std::endl;
return false;
}

View file

@ -11,17 +11,18 @@ namespace definition {
/**
* Node with a single integer value, for the definition tree.
*/
class DEFINITIONSHARED_EXPORT IntNode: public DefinitionNode
{
public:
IntNode(DefinitionNode* parent, const std::string &name, int value = 0);
class DEFINITIONSHARED_EXPORT IntNode : public DefinitionNode {
public:
IntNode(DefinitionNode *parent, const std::string &name, int value = 0);
inline int getValue() const {return value;}
inline int getValue() const {
return value;
}
virtual std::string toString(int indent) const override;
virtual void save(PackStream* stream) const override;
virtual void load(PackStream* stream) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode *destination) const override;
/**
* Change the int value stored.
@ -31,12 +32,11 @@ public:
void setValue(int new_value);
const IntDiff *produceDiff(int new_value) const;
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
private:
private:
int value;
};
}
}

View file

@ -3,57 +3,48 @@
#include "PackStream.h"
#include "Logs.h"
Layers::Layers(DefinitionNode* parent, const std::string &name, LayerConstructor layer_constructor):
DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor)
{
Layers::Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor)
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
max_layer_count = 100;
null_layer = layer_constructor(this);
}
Layers::~Layers()
{
Layers::~Layers() {
clear();
delete null_layer;
}
void Layers::save(PackStream *stream) const
{
void Layers::save(PackStream *stream) const {
int layer_count = (int)layers.size();
stream->write(&layer_count);
for (int i = 0; i < layer_count; i++)
{
for (int i = 0; i < layer_count; i++) {
stream->write(layers[i]->getName());
layers[i]->save(stream);
}
}
void Layers::load(PackStream *stream)
{
void Layers::load(PackStream *stream) {
int layer_count;
stream->read(&layer_count);
if (layer_count > max_layer_count)
{
if (layer_count > max_layer_count) {
layer_count = max_layer_count;
}
clear();
for (int i = 0; i < layer_count; i++)
{
for (int i = 0; i < layer_count; i++) {
int position = addLayer();
if (position >= 0)
{
if (position >= 0) {
layers[position]->setName(stream->readString());
layers[position]->load(stream);
}
}
}
void Layers::copy(DefinitionNode* destination_) const
{
void Layers::copy(DefinitionNode *destination_) const {
DefinitionNode::copy(destination_);
Layers* destination = (Layers*)destination_;
Layers *destination = (Layers *)destination_;
destination->clear();
@ -61,142 +52,113 @@ void Layers::copy(DefinitionNode* destination_) const
null_layer->copy(destination->null_layer);
for (auto layer: layers)
{
for (auto layer : layers) {
int position = destination->addLayer();
DefinitionNode* new_layer = destination->getLayer(position);
DefinitionNode *new_layer = destination->getLayer(position);
layer->copy(new_layer);
}
}
Layers* Layers::newCopy() const
{
Layers* result = new Layers(NULL, getName(), layer_constructor);
Layers *Layers::newCopy() const {
Layers *result = new Layers(NULL, getName(), layer_constructor);
copy(result);
return result;
}
void Layers::setMaxLayerCount(int max_layer_count)
{
void Layers::setMaxLayerCount(int max_layer_count) {
this->max_layer_count = max_layer_count;
// TODO Delete overlimit layers ?
}
int Layers::count() const
{
int Layers::count() const {
return layers.size();
}
DefinitionNode* Layers::getLayer(int position) const
{
if (position >= 0 and position < (int)layers.size())
{
DefinitionNode *Layers::getLayer(int position) const {
if (position >= 0 and position < (int)layers.size()) {
return layers[position];
}
else
{
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size() << std::endl;
} else {
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size()
<< std::endl;
return null_layer;
}
}
int Layers::findLayer(DefinitionNode* layer) const
{
int Layers::findLayer(DefinitionNode *layer) const {
int i = 0;
for (auto it:layers)
{
if (it == layer)
{
for (auto it : layers) {
if (it == layer) {
return i;
}
i++;
}
Logs::warning() << "Layer " << layer << " (" << layer->getName() << " not found, on a total of " << (int)layers.size() << std::endl;
Logs::warning() << "Layer " << layer << " (" << layer->getName() << " not found, on a total of "
<< (int)layers.size() << std::endl;
return -1;
}
int Layers::addLayer(DefinitionNode* layer)
{
if ((int)layers.size() < max_layer_count)
{
int Layers::addLayer(DefinitionNode *layer) {
if ((int)layers.size() < max_layer_count) {
layers.push_back(layer);
addChild(layer);
return layers.size() - 1;
}
else
{
} else {
Logs::warning() << "Add layer ignored because limit of " << max_layer_count << " reached" << std::endl;
delete layer;
return -1;
}
}
int Layers::addLayer()
{
int Layers::addLayer() {
return addLayer(layer_constructor(this));
}
void Layers::removeLayer(int position)
{
if (position >= 0 and position < (int)layers.size())
{
DefinitionNode* removed = layers[position];
void Layers::removeLayer(int position) {
if (position >= 0 and position < (int)layers.size()) {
DefinitionNode *removed = layers[position];
removeChild(removed);
layers.erase(layers.begin() + position);
delete removed;
}
else
{
Logs::warning() << "Removing unknown layer " << position << " on " << (int)layers.size() << " from '" << getName() << "'" << std::endl;
} else {
Logs::warning() << "Removing unknown layer " << position << " on " << (int)layers.size() << " from '"
<< getName() << "'" << std::endl;
}
}
void Layers::removeLayer(DefinitionNode* layer)
{
void Layers::removeLayer(DefinitionNode *layer) {
removeLayer(findLayer(layer));
}
void Layers::moveLayer(int old_position, int new_position)
{
if (old_position >= 0 and old_position < (int)layers.size() and new_position >= 0 and new_position < (int)layers.size())
{
DefinitionNode* layer = layers[old_position];
void Layers::moveLayer(int old_position, int new_position) {
if (old_position >= 0 and old_position < (int)layers.size() and new_position >= 0 and
new_position < (int)layers.size()) {
DefinitionNode *layer = layers[old_position];
layers.erase(layers.begin() + old_position);
layers.insert(layers.begin() + new_position, layer);
}
}
void Layers::moveLayer(DefinitionNode* layer, int new_position)
{
void Layers::moveLayer(DefinitionNode *layer, int new_position) {
moveLayer(findLayer(layer), new_position);
}
void Layers::clear()
{
while (layers.size() > 0)
{
void Layers::clear() {
while (layers.size() > 0) {
removeLayer(0);
}
}
DefinitionNode *Layers::findChildByName(const std::string name)
{
DefinitionNode *Layers::findChildByName(const std::string name) {
DefinitionNode *result = DefinitionNode::findChildByName(name);
if (result)
{
if (result) {
return result;
}
else
{
} else {
int position = addLayer();
if (position >= 0)
{
if (position >= 0) {
result = getLayer(position);
result->setName(name);
return result;
}
else
{
} else {
return NULL;
}
}

View file

@ -8,27 +8,26 @@
namespace paysages {
namespace definition {
typedef DefinitionNode* (*LayerConstructor)(Layers* parent);
typedef DefinitionNode *(*LayerConstructor)(Layers *parent);
/**
* @brief Layers of definitions, ideally all of the same type.
*/
class DEFINITIONSHARED_EXPORT Layers:public DefinitionNode
{
public:
Layers(DefinitionNode* parent, const std::string &name, LayerConstructor layer_constructor);
class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
public:
Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor);
virtual ~Layers();
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode* destination) const override;
Layers* newCopy() const;
virtual void copy(DefinitionNode *destination) const override;
Layers *newCopy() const;
void setMaxLayerCount(int max_layer_count);
int count() const;
DefinitionNode* getLayer(int position) const;
int findLayer(DefinitionNode* layer) const;
DefinitionNode *getLayer(int position) const;
int findLayer(DefinitionNode *layer) const;
/**
* @brief Add a new layer
@ -40,22 +39,20 @@ public:
int addLayer(DefinitionNode *layer);
int addLayer();
void removeLayer(int position);
void removeLayer(DefinitionNode* layer);
void removeLayer(DefinitionNode *layer);
void moveLayer(int old_position, int new_position);
void moveLayer(DefinitionNode* layer, int new_position);
void moveLayer(DefinitionNode *layer, int new_position);
void clear();
protected:
protected:
virtual DefinitionNode *findChildByName(const std::string name) override;
public:
public:
LayerConstructor layer_constructor;
int max_layer_count;
std::vector<DefinitionNode*> layers;
DefinitionNode* null_layer;
std::vector<DefinitionNode *> layers;
DefinitionNode *null_layer;
};
}
}

View file

@ -3,19 +3,15 @@
#include "NoiseGenerator.h"
#include "Logs.h"
NoiseNode::NoiseNode(DefinitionNode *parent):
DefinitionNode(parent, "noise")
{
NoiseNode::NoiseNode(DefinitionNode *parent) : DefinitionNode(parent, "noise") {
noise = new NoiseGenerator();
}
NoiseNode::~NoiseNode()
{
NoiseNode::~NoiseNode() {
delete noise;
}
void NoiseNode::setLevels(int levels, double min_value, double max_value)
{
void NoiseNode::setLevels(int levels, double min_value, double max_value) {
noise->clearLevels();
noise->addLevelsSimple(levels, 1.0, -1.0, 1.0, 0.5);
noise->normalizeAmplitude(min_value, max_value, false);
@ -23,29 +19,22 @@ void NoiseNode::setLevels(int levels, double min_value, double max_value)
noise->validate();
}
void NoiseNode::save(PackStream *stream) const
{
void NoiseNode::save(PackStream *stream) const {
noise->save(stream);
}
void NoiseNode::load(PackStream *stream)
{
void NoiseNode::load(PackStream *stream) {
noise->load(stream);
}
void NoiseNode::copy(DefinitionNode *destination) const
{
if (destination->getTypeName() == getTypeName())
{
void NoiseNode::copy(DefinitionNode *destination) const {
if (destination->getTypeName() == getTypeName()) {
noise->copy(((NoiseNode *)destination)->noise);
}
else
{
} else {
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
}
}
void NoiseNode::validate()
{
void NoiseNode::validate() {
noise->validate();
}

View file

@ -11,30 +11,29 @@ namespace definition {
/**
* Definition node with noise parameters.
*/
class DEFINITIONSHARED_EXPORT NoiseNode: public DefinitionNode
{
public:
class DEFINITIONSHARED_EXPORT NoiseNode : public DefinitionNode {
public:
NoiseNode(DefinitionNode *parent);
virtual ~NoiseNode();
inline const NoiseGenerator *getGenerator() {return noise;}
inline const NoiseGenerator *getGenerator() {
return noise;
}
/**
* Set the number of levels to use in the noise generator.
*/
void setLevels(int levels, double min_value=-1.0, double max_value=1.0);
void setLevels(int levels, double min_value = -1.0, double max_value = 1.0);
protected:
protected:
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode *destination) const override;
virtual void validate() override;
private:
private:
NoiseGenerator *noise;
};
}
}

View file

@ -6,40 +6,33 @@
#include "PaintedGridData.h"
#include "PaintedGridBrush.h"
PaintedGrid::PaintedGrid(DefinitionNode *parent):
DefinitionNode(parent, "grid", "grid")
{
PaintedGrid::PaintedGrid(DefinitionNode *parent) : DefinitionNode(parent, "grid", "grid") {
merged_data = new PaintedGridData;
brush_data = new PaintedGridData;
}
PaintedGrid::~PaintedGrid()
{
PaintedGrid::~PaintedGrid() {
delete merged_data;
delete brush_data;
}
void PaintedGrid::copy(DefinitionNode *_destination) const
{
PaintedGrid* destination = (PaintedGrid *)_destination;
void PaintedGrid::copy(DefinitionNode *_destination) const {
PaintedGrid *destination = (PaintedGrid *)_destination;
merged_data->copy(destination->merged_data);
destination->brush_data->clear();
}
void PaintedGrid::save(PackStream *stream) const
{
void PaintedGrid::save(PackStream *stream) const {
merged_data->save(stream);
}
void PaintedGrid::load(PackStream *stream)
{
void PaintedGrid::load(PackStream *stream) {
merged_data->load(stream);
brush_data->clear();
}
bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
{
bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const {
int ix, iy;
int xlow;
int ylow;
@ -48,27 +41,20 @@ bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
ylow = floor(y);
int hit = 0;
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++)
{
for (iy = ylow - 1; iy <= ylow + 2 && !hit; iy++)
{
if (getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false))
{
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++) {
for (iy = ylow - 1; iy <= ylow + 2 && !hit; iy++) {
if (getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false)) {
hit = 1;
}
}
}
if (hit && result)
{
if (hit && result) {
double stencil[16];
double value;
for (ix = xlow - 1; ix <= xlow + 2; ix++)
{
for (iy = ylow - 1; iy <= ylow + 2; iy++)
{
if (!getGridValue(ix, iy, &value))
{
for (ix = xlow - 1; ix <= xlow + 2; ix++) {
for (iy = ylow - 1; iy <= ylow + 2; iy++) {
if (!getGridValue(ix, iy, &value)) {
value = getInitialValue(ix, iy);
}
stencil[(iy - (ylow - 1)) * 4 + ix - (xlow - 1)] = value;
@ -81,67 +67,51 @@ bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
return hit;
}
bool PaintedGrid::getGridValue(int x, int y, double *result) const
{
double* dpointer;
bool PaintedGrid::getGridValue(int x, int y, double *result) const {
double *dpointer;
dpointer = getDataPointer(brush_data, x, y, NULL, false);
if (dpointer)
{
if (dpointer) {
*result = *dpointer;
return true;
}
else
{
} else {
dpointer = getDataPointer(merged_data, x, y, NULL, false);
if (dpointer)
{
if (dpointer) {
*result = *dpointer;
return true;
}
else
{
} else {
return false;
}
}
}
double PaintedGrid::getFinalValue(double x, double y) const
{
double PaintedGrid::getFinalValue(double x, double y) const {
double result;
if (getInterpolatedValue(x, y, &result))
{
if (getInterpolatedValue(x, y, &result)) {
return result;
}
else
{
} else {
return getInitialValue(x, y);
}
}
bool PaintedGrid::hasPainting() const
{
bool PaintedGrid::hasPainting() const {
return merged_data->hasData() || brush_data->hasData();
}
bool PaintedGrid::isPainted(int x, int y) const
{
bool PaintedGrid::isPainted(int x, int y) const {
return getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false);
}
unsigned long PaintedGrid::getMemoryStats() const
{
unsigned long PaintedGrid::getMemoryStats() const {
return merged_data->memsize + brush_data->memsize;
}
void PaintedGrid::clearPainting()
{
void PaintedGrid::clearPainting() {
merged_data->clear();
brush_data->clear();
}
void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit)
{
void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit) {
int xstart, xend, ystart, yend;
brush.getArea(x, y, &xstart, &ystart, &xend, &yend);
@ -149,41 +119,34 @@ void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y,
int ix, iy;
double dx, dy, influence;
for (ix = xstart; ix <= xend; ix++)
{
for (ix = xstart; ix <= xend; ix++) {
dx = (double)ix;
for (iy = ystart; iy <= yend; iy++)
{
for (iy = ystart; iy <= yend; iy++) {
dy = (double)iy;
influence = brush.getInfluence(x - dx, y - dy);
if (influence > 0.0)
{
double* dpointer = getDataPointer(brush_data, ix, iy, merged_data, true);
if (influence > 0.0) {
double *dpointer = getDataPointer(brush_data, ix, iy, merged_data, true);
*dpointer = brush.getValue(this, dx, dy, *dpointer, influence, force);
}
}
}
if (commit)
{
if (commit) {
endBrushStroke();
}
}
void PaintedGrid::endBrushStroke()
{
void PaintedGrid::endBrushStroke() {
int i, j, k;
PaintedGridData* data = brush_data;
PaintedGridData *data = brush_data;
for (i = 0; i < data->rows_count; i++)
{
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
{
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++)
{
double* dpointer = getDataPointer(merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].y, NULL, true);
for (i = 0; i < data->rows_count; i++) {
for (j = 0; j < data->rows[i].pixel_groups_count; j++) {
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++) {
double *dpointer =
getDataPointer(merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].y, NULL, true);
*dpointer = data->rows[i].pixel_groups[j].height[k];
}
}
@ -192,63 +155,51 @@ void PaintedGrid::endBrushStroke()
brush_data->clear();
}
double PaintedGrid::getInitialValue(double, double) const
{
double PaintedGrid::getInitialValue(double, double) const {
return 0.0;
}
double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const
{
double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const {
int i;
/* Find row */
/* TODO Dichotomic search */
PaintedGridData::HeightMapRow* row;
PaintedGridData::HeightMapRow *row;
i = 0;
while (i < data->rows_count && data->rows[i].y < y)
{
while (i < data->rows_count && data->rows[i].y < y) {
i++;
}
if (i < data->rows_count && data->rows[i].y == y)
{
if (i < data->rows_count && data->rows[i].y == y) {
row = data->rows + i;
}
else if (grow)
{
row = (PaintedGridData::HeightMapRow*)Memory::naiveArrayInsert((void**)&data->rows, sizeof(PaintedGridData::HeightMapRow), data->rows_count, i);
} else if (grow) {
row = (PaintedGridData::HeightMapRow *)Memory::naiveArrayInsert(
(void **)&data->rows, sizeof(PaintedGridData::HeightMapRow), data->rows_count, i);
row->y = y;
row->pixel_groups_count = 0;
row->pixel_groups = (PaintedGridData::HeightMapPixelGroup*)malloc(1);
row->pixel_groups = (PaintedGridData::HeightMapPixelGroup *)malloc(1);
data->rows_count++;
data->memsize += sizeof(PaintedGridData::HeightMapRow);
}
else
{
} else {
return NULL;
}
#ifndef NDEBUG
/* Check rows */
for (i = 1; i < data->rows_count; i++)
{
for (i = 1; i < data->rows_count; i++) {
assert(data->rows[i].y > data->rows[i - 1].y);
}
#endif
/* Find pixel group */
PaintedGridData::HeightMapPixelGroup* pixel_group = NULL;
for (i = 0; i < row->pixel_groups_count; i++)
{
if (x < row->pixel_groups[i].xstart - 1)
{
PaintedGridData::HeightMapPixelGroup *pixel_group = NULL;
for (i = 0; i < row->pixel_groups_count; i++) {
if (x < row->pixel_groups[i].xstart - 1) {
break;
}
else if (x <= row->pixel_groups[i].xend + 1)
{
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 && x == row->pixel_groups[i + 1].xstart)
{
} else if (x <= row->pixel_groups[i].xend + 1) {
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 &&
x == row->pixel_groups[i + 1].xstart) {
/* Choose next group if it already includes the pixel */
i++;
}
@ -258,53 +209,47 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
}
/* Alter pixel group */
double* pixel;
double *pixel;
int added = 1;
if (!pixel_group)
{
if (!grow)
{
if (!pixel_group) {
if (!grow) {
return NULL;
}
/* Create the pixel group with one pixel */
pixel_group = (PaintedGridData::HeightMapPixelGroup*)Memory::naiveArrayInsert((void**)&row->pixel_groups, sizeof(PaintedGridData::HeightMapPixelGroup), row->pixel_groups_count, i);
pixel_group = (PaintedGridData::HeightMapPixelGroup *)Memory::naiveArrayInsert(
(void **)&row->pixel_groups, sizeof(PaintedGridData::HeightMapPixelGroup), row->pixel_groups_count, i);
pixel_group->xstart = x;
pixel_group->xend = x;
pixel_group->height = (double*)malloc(sizeof(double));
pixel_group->height = (double *)malloc(sizeof(double));
pixel = pixel_group->height;
row->pixel_groups_count++;
data->memsize += sizeof(PaintedGridData::HeightMapPixelGroup) + sizeof(double);
}
else if (x == pixel_group->xstart - 1)
{
if (!grow)
{
} else if (x == pixel_group->xstart - 1) {
if (!grow) {
return NULL;
}
/* Extend the rowgroup at start */
pixel_group->xstart--;
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
pixel = (double *)Memory::naiveArrayInsert((void **)&pixel_group->height, sizeof(double),
pixel_group->xend - pixel_group->xstart, 0);
data->memsize += sizeof(double);
}
else if (x == pixel_group->xend + 1)
{
if (!grow)
{
} else if (x == pixel_group->xend + 1) {
if (!grow) {
return NULL;
}
/* Extend the rowgroup at end */
pixel_group->xend++;
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
pixel = (double *)Memory::naiveArrayInsert((void **)&pixel_group->height, sizeof(double),
pixel_group->xend - pixel_group->xstart,
pixel_group->xend - pixel_group->xstart);
data->memsize += sizeof(double);
}
else
{
} else {
assert(x >= pixel_group->xstart);
assert(x <= pixel_group->xend);
pixel = pixel_group->height + x - pixel_group->xstart;
@ -313,14 +258,11 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
#ifndef NDEBUG
/* Check pixel groups */
for (i = 0; i < row->pixel_groups_count; i++)
{
if (i > 0)
{
for (i = 0; i < row->pixel_groups_count; i++) {
if (i > 0) {
assert(row->pixel_groups[i].xstart > row->pixel_groups[i - 1].xend);
}
if (i < row->pixel_groups_count - 1)
{
if (i < row->pixel_groups_count - 1) {
assert(row->pixel_groups[i].xend < row->pixel_groups[i + 1].xstart);
}
assert(row->pixel_groups[i].xend >= row->pixel_groups[i].xstart);
@ -328,22 +270,15 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
#endif
/* Reset pixel if it had been added */
if (added)
{
if (fallback)
{
double* dpointer = getDataPointer(fallback, x, y, NULL, false);
if (dpointer)
{
if (added) {
if (fallback) {
double *dpointer = getDataPointer(fallback, x, y, NULL, false);
if (dpointer) {
*pixel = *dpointer;
}
else
{
} else {
*pixel = getInitialValue(x, y);
}
}
else
{
} else {
*pixel = getInitialValue(x, y);
}
}

View file

@ -15,10 +15,9 @@ namespace definition {
*
* Grid cells are considered to be 1.0-sized.
*/
class DEFINITIONSHARED_EXPORT PaintedGrid: public DefinitionNode
{
public:
PaintedGrid(DefinitionNode *parent=0);
class DEFINITIONSHARED_EXPORT PaintedGrid : public DefinitionNode {
public:
PaintedGrid(DefinitionNode *parent = 0);
virtual ~PaintedGrid();
virtual void copy(DefinitionNode *destination) const override;
@ -67,7 +66,7 @@ public:
/**
* Apply a brush stroke at a grid location (locating the brush center).
*/
virtual void applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit=false);
virtual void applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit = false);
/**
* Commit previous brush strokes.
@ -81,14 +80,13 @@ public:
*/
virtual double getInitialValue(double x, double y) const;
private:
private:
double *getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const;
private:
private:
PaintedGridData *merged_data;
PaintedGridData *brush_data;
};
}
}

View file

@ -4,13 +4,11 @@
#include "NoiseGenerator.h"
#include "PaintedGrid.h"
PaintedGridBrush::PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius):
hard_radius(hard_radius), smoothed_size(smoothed_size), total_radius(total_radius)
{
PaintedGridBrush::PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius)
: hard_radius(hard_radius), smoothed_size(smoothed_size), total_radius(total_radius) {
}
void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int *xend, int *yend) const
{
void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int *xend, int *yend) const {
double s = smoothed_size + hard_radius;
*xstart = (int)floor(x - s);
@ -19,39 +17,31 @@ void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int
*yend = (int)ceil(y + s);
}
double PaintedGridBrush::getInfluence(double dx, double dy) const
{
double PaintedGridBrush::getInfluence(double dx, double dy) const {
double distance = sqrt(dx * dx + dy * dy);
if (distance > hard_radius)
{
if (distance <= hard_radius + smoothed_size)
{
if (distance > hard_radius) {
if (distance <= hard_radius + smoothed_size) {
return 1.0 - (distance - hard_radius) / smoothed_size;
}
else
{
} else {
return 0.0;
}
}
else
{
} else {
return 1.0;
}
}
double PaintedGridBrush::getValue(const PaintedGrid *, double, double, double basevalue, double, double) const
{
double PaintedGridBrush::getValue(const PaintedGrid *, double, double, double basevalue, double, double) const {
return basevalue;
}
double PaintedGridBrushRaiseLower::getValue(const PaintedGrid *, double, double, double basevalue, double influence, double force) const
{
double PaintedGridBrushRaiseLower::getValue(const PaintedGrid *, double, double, double basevalue, double influence,
double force) const {
return basevalue + influence * force;
}
double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const
{
double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
double force) const {
double ideal, factor;
ideal = grid->getFinalValue((x + total_radius * 0.5), y);
ideal += grid->getFinalValue((x - total_radius * 0.5), y);
@ -59,26 +49,25 @@ double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, doubl
ideal += grid->getFinalValue(x, (y + total_radius * 0.5));
ideal /= 4.0;
factor = influence * force;
if (factor > 1.0)
{
if (factor > 1.0) {
factor = 0.0;
}
return basevalue + (ideal - basevalue) * factor;
}
double PaintedGridBrushAddNoise::getValue(const PaintedGrid *, double x, double y, double basevalue, double influence, double force) const
{
double PaintedGridBrushAddNoise::getValue(const PaintedGrid *, double x, double y, double basevalue, double influence,
double force) const {
return basevalue + generator->get2DTotal(x / total_radius, y / total_radius) * influence * force * total_radius;
}
double PaintedGridBrushReset::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const
{
double PaintedGridBrushReset::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
double force) const {
double ideal = grid->getInitialValue(x, y);
return basevalue + (ideal - basevalue) * influence * force;
}
double PaintedGridBrushFlatten::getValue(const PaintedGrid *, double, double, double basevalue, double influence, double force) const
{
double PaintedGridBrushFlatten::getValue(const PaintedGrid *, double, double, double basevalue, double influence,
double force) const {
double ideal = target;
return basevalue + (ideal - basevalue) * influence * force;
}

View file

@ -9,9 +9,8 @@ namespace definition {
/**
* Base class for brushes that can be used to paint values on a PaintedGrid.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrush
{
public:
class DEFINITIONSHARED_EXPORT PaintedGridBrush {
public:
PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius);
/**
@ -27,9 +26,10 @@ public:
/**
* Abstract method to reimplement to get the final value of a brush stroke at a given point.
*/
virtual double getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const;
virtual double getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
double force) const;
protected:
protected:
double hard_radius;
double smoothed_size;
double total_radius;
@ -38,57 +38,64 @@ protected:
/**
* Brush able to raise or lower the grid value.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower: public PaintedGridBrush
{
public:
PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower : public PaintedGridBrush {
public:
PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
};
/**
* Brush able to smooth the value in an area.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth: public PaintedGridBrush
{
public:
PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth : public PaintedGridBrush {
public:
PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
};
/**
* Brush able to add random fractal noise.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise: public PaintedGridBrush
{
public:
PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator) : PaintedGridBrush(brush), generator(generator) {}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
private:
class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise : public PaintedGridBrush {
public:
PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator)
: PaintedGridBrush(brush), generator(generator) {
}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
private:
NoiseGenerator *generator;
};
/**
* Brush able to reset to initial value.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrushReset: public PaintedGridBrush
{
public:
PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
class DEFINITIONSHARED_EXPORT PaintedGridBrushReset : public PaintedGridBrush {
public:
PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
};
/**
* Brush able to flatten to a specific value.
*/
class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten: public PaintedGridBrush
{
public:
PaintedGridBrushFlatten(const PaintedGridBrush &brush, double target) : PaintedGridBrush(brush), target(target) {}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
private:
class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten : public PaintedGridBrush {
public:
PaintedGridBrushFlatten(const PaintedGridBrush &brush, double target) : PaintedGridBrush(brush), target(target) {
}
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
private:
double target;
};
}
}

View file

@ -3,46 +3,40 @@
#include <cstring>
#include "PackStream.h"
PaintedGridData::PaintedGridData()
{
PaintedGridData::PaintedGridData() {
rows_count = 0;
rows = (HeightMapRow *)malloc(sizeof(HeightMapRow));
memsize = 0;
}
PaintedGridData::~PaintedGridData()
{
PaintedGridData::~PaintedGridData() {
clear();
free(rows);
}
void PaintedGridData::copy(PaintedGridData *destination) const
{
void PaintedGridData::copy(PaintedGridData *destination) const {
int i, j, n;
size_t size;
destination->clear();
destination->rows_count = this->rows_count;
if (destination->rows_count > 0)
{
if (destination->rows_count > 0) {
size = sizeof(HeightMapRow) * destination->rows_count;
destination->rows = (HeightMapRow*)realloc(destination->rows, size);
destination->rows = (HeightMapRow *)realloc(destination->rows, size);
destination->memsize += size;
for (i = 0; i < destination->rows_count; i++)
{
for (i = 0; i < destination->rows_count; i++) {
destination->rows[i].y = this->rows[i].y;
destination->rows[i].pixel_groups_count = this->rows[i].pixel_groups_count;
size = sizeof(HeightMapPixelGroup) * destination->rows[i].pixel_groups_count;
destination->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
destination->rows[i].pixel_groups = (HeightMapPixelGroup *)malloc(size);
destination->memsize += size;
for (j = 0; j < destination->rows[i].pixel_groups_count; j++)
{
for (j = 0; j < destination->rows[i].pixel_groups_count; j++) {
destination->rows[i].pixel_groups[j].xstart = this->rows[i].pixel_groups[j].xstart;
destination->rows[i].pixel_groups[j].xend = this->rows[i].pixel_groups[j].xend;
n = destination->rows[i].pixel_groups[j].xend - destination->rows[i].pixel_groups[j].xstart + 1;
size = sizeof(double) * n;
destination->rows[i].pixel_groups[j].height = (double*)malloc(size);
destination->rows[i].pixel_groups[j].height = (double *)malloc(size);
destination->memsize += size;
memcpy(destination->rows[i].pixel_groups[j].height, this->rows[i].pixel_groups[j].height, size);
}
@ -50,56 +44,47 @@ void PaintedGridData::copy(PaintedGridData *destination) const
}
}
void PaintedGridData::save(PackStream *stream) const
{
void PaintedGridData::save(PackStream *stream) const {
int i, j, k;
stream->write(&rows_count);
for (i = 0; i < rows_count; i++)
{
for (i = 0; i < rows_count; i++) {
stream->write(&rows[i].y);
stream->write(&rows[i].pixel_groups_count);
for (j = 0; j < rows[i].pixel_groups_count; j++)
{
for (j = 0; j < rows[i].pixel_groups_count; j++) {
stream->write(&rows[i].pixel_groups[j].xstart);
stream->write(&rows[i].pixel_groups[j].xend);
for (k = 0; k < rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart; k++)
{
for (k = 0; k < rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart; k++) {
stream->write(&rows[i].pixel_groups[j].height[k]);
}
}
}
}
void PaintedGridData::load(PackStream *stream)
{
void PaintedGridData::load(PackStream *stream) {
int i, j, k, n;
size_t size;
clear();
stream->read(&rows_count);
if (rows_count > 0)
{
if (rows_count > 0) {
size = sizeof(HeightMapRow) * rows_count;
rows = (HeightMapRow*)realloc(rows, size);
rows = (HeightMapRow *)realloc(rows, size);
memsize += size;
for (i = 0; i < rows_count; i++)
{
for (i = 0; i < rows_count; i++) {
stream->read(&rows[i].y);
stream->read(&rows[i].pixel_groups_count);
size = sizeof(HeightMapPixelGroup) * rows[i].pixel_groups_count;
rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
rows[i].pixel_groups = (HeightMapPixelGroup *)malloc(size);
memsize += size;
for (j = 0; j < rows[i].pixel_groups_count; j++)
{
for (j = 0; j < rows[i].pixel_groups_count; j++) {
stream->read(&rows[i].pixel_groups[j].xstart);
stream->read(&rows[i].pixel_groups[j].xend);
n = rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart;
size = sizeof(double) * n;
rows[i].pixel_groups[j].height = (double*)malloc(size);
rows[i].pixel_groups[j].height = (double *)malloc(size);
memsize += size;
for (k = 0; k < n; k++)
{
for (k = 0; k < n; k++) {
stream->read(&rows[i].pixel_groups[j].height[k]);
}
}
@ -107,13 +92,10 @@ void PaintedGridData::load(PackStream *stream)
}
}
void PaintedGridData::clear()
{
void PaintedGridData::clear() {
int i, j;
for (i = 0; i < rows_count; i++)
{
for (j = 0; j < rows[i].pixel_groups_count; j++)
{
for (i = 0; i < rows_count; i++) {
for (j = 0; j < rows[i].pixel_groups_count; j++) {
free(rows[i].pixel_groups[j].height);
}
free(rows[i].pixel_groups);

View file

@ -9,11 +9,10 @@ namespace definition {
/**
* Internal storage class to hold data for a PaintedGrid.
*/
class PaintedGridData
{
class PaintedGridData {
friend class PaintedGrid;
public:
public:
PaintedGridData();
~PaintedGridData();
@ -26,28 +25,27 @@ public:
*/
void clear();
inline bool hasData() const {return rows_count > 0;}
inline bool hasData() const {
return rows_count > 0;
}
private:
typedef struct
{
private:
typedef struct {
int xstart;
int xend;
double* height;
double *height;
} HeightMapPixelGroup;
typedef struct
{
typedef struct {
int y;
int pixel_groups_count;
HeightMapPixelGroup* pixel_groups;
HeightMapPixelGroup *pixel_groups;
} HeightMapRow;
int memsize;
int rows_count;
HeightMapRow* rows;
HeightMapRow *rows;
};
}
}

View file

@ -16,9 +16,7 @@
static const double APP_HEADER = 19866544632.125;
static const int DATA_VERSION = 1;
Scenery::Scenery():
DefinitionNode(NULL, "scenery", "scenery")
{
Scenery::Scenery() : DefinitionNode(NULL, "scenery", "scenery") {
atmosphere = new AtmosphereDefinition(this);
camera = new CameraDefinition(this);
clouds = new CloudsDefinition(this);
@ -28,21 +26,18 @@ Scenery::Scenery():
vegetation = new VegetationDefinition(this);
}
void Scenery::validate()
{
void Scenery::validate() {
DefinitionNode::validate();
keepCameraAboveGround(camera);
}
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const
{
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const {
PackStream stream;
double app_header = (double)APP_HEADER;
double version_header = (double)DATA_VERSION;
if (not stream.bindToFile(filepath, true))
{
if (not stream.bindToFile(filepath, true)) {
return FILE_OPERATION_IOERROR;
}
@ -58,25 +53,21 @@ Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) co
return FILE_OPERATION_OK;
}
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
{
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) {
PackStream stream;
double app_header, version_header;
if (not stream.bindToFile(filepath, false))
{
if (not stream.bindToFile(filepath, false)) {
return FILE_OPERATION_IOERROR;
}
stream.read(&app_header);
if (app_header != APP_HEADER)
{
if (app_header != APP_HEADER) {
return FILE_OPERATION_APP_MISMATCH;
}
stream.read(&version_header);
if ((int)version_header != DATA_VERSION)
{
if ((int)version_header != DATA_VERSION) {
return FILE_OPERATION_VERSION_MISMATCH;
}
@ -87,14 +78,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
version_header = -1;
stream.read(&version_header);
if ((int)version_header != DATA_VERSION)
{
if ((int)version_header != DATA_VERSION) {
return FILE_OPERATION_VERSION_MISMATCH;
}
stream.read(&app_header);
if (app_header != APP_HEADER)
{
if (app_header != APP_HEADER) {
return FILE_OPERATION_APP_MISMATCH;
}
@ -102,15 +91,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
return FILE_OPERATION_OK;
}
const Scenery* Scenery::getScenery() const
{
const Scenery *Scenery::getScenery() const {
return this;
}
void Scenery::autoPreset(int seed)
{
if (!seed)
{
void Scenery::autoPreset(int seed) {
if (!seed) {
seed = time(NULL);
}
srand(seed);
@ -130,84 +116,68 @@ void Scenery::autoPreset(int seed)
Logs::debug() << "New scenery generated from seed " << seed << std::endl;
}
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere)
{
void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
atmosphere->copy(this->atmosphere);
}
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere)
{
void Scenery::getAtmosphere(AtmosphereDefinition *atmosphere) {
this->atmosphere->copy(atmosphere);
}
void Scenery::setCamera(CameraDefinition* camera)
{
void Scenery::setCamera(CameraDefinition *camera) {
camera->copy(this->camera);
keepCameraAboveGround(this->camera);
}
void Scenery::getCamera(CameraDefinition* camera)
{
void Scenery::getCamera(CameraDefinition *camera) {
this->camera->copy(camera);
}
void Scenery::setClouds(CloudsDefinition* clouds)
{
void Scenery::setClouds(CloudsDefinition *clouds) {
clouds->copy(this->clouds);
}
void Scenery::getClouds(CloudsDefinition* clouds)
{
void Scenery::getClouds(CloudsDefinition *clouds) {
this->clouds->copy(clouds);
}
void Scenery::setTerrain(TerrainDefinition* terrain)
{
void Scenery::setTerrain(TerrainDefinition *terrain) {
terrain->copy(this->terrain);
}
void Scenery::getTerrain(TerrainDefinition* terrain)
{
void Scenery::getTerrain(TerrainDefinition *terrain) {
this->terrain->copy(terrain);
}
void Scenery::setTextures(TexturesDefinition* textures)
{
void Scenery::setTextures(TexturesDefinition *textures) {
textures->copy(this->textures);
}
void Scenery::getTextures(TexturesDefinition* textures)
{
void Scenery::getTextures(TexturesDefinition *textures) {
this->textures->copy(textures);
}
void Scenery::setVegetation(VegetationDefinition* vegetation)
{
void Scenery::setVegetation(VegetationDefinition *vegetation) {
vegetation->copy(this->vegetation);
}
void Scenery::getVegetation(VegetationDefinition* vegetation)
{
void Scenery::getVegetation(VegetationDefinition *vegetation) {
this->vegetation->copy(vegetation);
}
void Scenery::setWater(WaterDefinition* water)
{
void Scenery::setWater(WaterDefinition *water) {
water->copy(this->water);
}
void Scenery::getWater(WaterDefinition* water)
{
void Scenery::getWater(WaterDefinition *water) {
this->water->copy(water);
}
void Scenery::keepCameraAboveGround(CameraDefinition* camera)
{
void Scenery::keepCameraAboveGround(CameraDefinition *camera) {
Vector3 camera_location = camera->getLocation();
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 1.0;
double water_height = 0.5;
if (camera_location.y < water_height || camera_location.y < terrain_height)
{
if (camera_location.y < water_height || camera_location.y < terrain_height) {
double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0)));
}

View file

@ -13,9 +13,8 @@ namespace definition {
*
* This class contains the whole scenery definition.
*/
class DEFINITIONSHARED_EXPORT Scenery: public DefinitionNode
{
public:
class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
public:
typedef enum {
FILE_OPERATION_OK,
FILE_OPERATION_IOERROR,
@ -23,9 +22,9 @@ public:
FILE_OPERATION_VERSION_MISMATCH
} FileOperationResult;
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
typedef void (*SceneryCustomDataCallback)(PackStream *stream, void *data);
public:
public:
Scenery();
virtual void validate() override;
@ -33,50 +32,63 @@ public:
FileOperationResult saveGlobal(const std::string &filepath) const;
FileOperationResult loadGlobal(const std::string &filepath);
virtual const Scenery* getScenery() const override;
virtual const Scenery *getScenery() const override;
void autoPreset(int seed=0);
void autoPreset(int seed = 0);
void setAtmosphere(AtmosphereDefinition* atmosphere);
inline AtmosphereDefinition* getAtmosphere() const {return atmosphere;}
void getAtmosphere(AtmosphereDefinition* atmosphere);
void setAtmosphere(AtmosphereDefinition *atmosphere);
inline AtmosphereDefinition *getAtmosphere() const {
return atmosphere;
}
void getAtmosphere(AtmosphereDefinition *atmosphere);
void setCamera(CameraDefinition* camera);
inline CameraDefinition* getCamera() const {return camera;}
void getCamera(CameraDefinition* camera);
void setCamera(CameraDefinition *camera);
inline CameraDefinition *getCamera() const {
return camera;
}
void getCamera(CameraDefinition *camera);
void setClouds(CloudsDefinition* clouds);
inline CloudsDefinition* getClouds() const {return clouds;}
void getClouds(CloudsDefinition* clouds);
void setClouds(CloudsDefinition *clouds);
inline CloudsDefinition *getClouds() const {
return clouds;
}
void getClouds(CloudsDefinition *clouds);
void setTerrain(TerrainDefinition* terrain);
inline TerrainDefinition* getTerrain() const {return terrain;}
void getTerrain(TerrainDefinition* terrain);
void setTerrain(TerrainDefinition *terrain);
inline TerrainDefinition *getTerrain() const {
return terrain;
}
void getTerrain(TerrainDefinition *terrain);
void setTextures(TexturesDefinition* textures);
inline TexturesDefinition* getTextures() const {return textures;}
void getTextures(TexturesDefinition* textures);
void setTextures(TexturesDefinition *textures);
inline TexturesDefinition *getTextures() const {
return textures;
}
void getTextures(TexturesDefinition *textures);
void setVegetation(VegetationDefinition* Vegetation);
inline VegetationDefinition* getVegetation() const {return vegetation;}
void getVegetation(VegetationDefinition* Vegetation);
void setVegetation(VegetationDefinition *Vegetation);
inline VegetationDefinition *getVegetation() const {
return vegetation;
}
void getVegetation(VegetationDefinition *Vegetation);
void setWater(WaterDefinition* water);
inline WaterDefinition* getWater() const {return water;}
void getWater(WaterDefinition* water);
void setWater(WaterDefinition *water);
inline WaterDefinition *getWater() const {
return water;
}
void getWater(WaterDefinition *water);
void keepCameraAboveGround(CameraDefinition* camera);
void keepCameraAboveGround(CameraDefinition *camera);
private:
AtmosphereDefinition* atmosphere;
CameraDefinition* camera;
CloudsDefinition* clouds;
TerrainDefinition* terrain;
TexturesDefinition* textures;
VegetationDefinition* vegetation;
WaterDefinition* water;
private:
AtmosphereDefinition *atmosphere;
CameraDefinition *camera;
CloudsDefinition *clouds;
TerrainDefinition *terrain;
TexturesDefinition *textures;
VegetationDefinition *vegetation;
WaterDefinition *water;
};
}
}

View file

@ -5,13 +5,10 @@
static SurfaceMaterial DEFAULT;
SurfaceMaterial::SurfaceMaterial():
SurfaceMaterial(COLOR_BLACK)
{
SurfaceMaterial::SurfaceMaterial() : SurfaceMaterial(COLOR_BLACK) {
}
SurfaceMaterial::SurfaceMaterial(const Color &color)
{
SurfaceMaterial::SurfaceMaterial(const Color &color) {
base = new Color(color);
hardness = 0.5;
reflection = 0.0;
@ -19,32 +16,26 @@ SurfaceMaterial::SurfaceMaterial(const Color &color)
receive_shadows = 1.0;
}
SurfaceMaterial::SurfaceMaterial(const SurfaceMaterial &other):
SurfaceMaterial(COLOR_BLACK)
{
SurfaceMaterial::SurfaceMaterial(const SurfaceMaterial &other) : SurfaceMaterial(COLOR_BLACK) {
other.copy(this);
}
SurfaceMaterial::~SurfaceMaterial()
{
SurfaceMaterial::~SurfaceMaterial() {
delete base;
}
const SurfaceMaterial &SurfaceMaterial::getDefault()
{
const SurfaceMaterial &SurfaceMaterial::getDefault() {
return DEFAULT;
}
void SurfaceMaterial::setColor(double r, double g, double b, double a)
{
void SurfaceMaterial::setColor(double r, double g, double b, double a) {
base->r = r;
base->g = g;
base->b = b;
base->a = a;
}
void SurfaceMaterial::save(PackStream* stream) const
{
void SurfaceMaterial::save(PackStream *stream) const {
base->save(stream);
stream->write(&hardness);
@ -54,8 +45,7 @@ void SurfaceMaterial::save(PackStream* stream) const
stream->write(&receive_shadows);
}
void SurfaceMaterial::load(PackStream* stream)
{
void SurfaceMaterial::load(PackStream *stream) {
base->load(stream);
stream->read(&hardness);
@ -65,8 +55,7 @@ void SurfaceMaterial::load(PackStream* stream)
stream->read(&receive_shadows);
}
void SurfaceMaterial::copy(SurfaceMaterial *destination) const
{
void SurfaceMaterial::copy(SurfaceMaterial *destination) const {
*destination->base = *base;
destination->hardness = hardness;
destination->reflection = reflection;
@ -75,6 +64,5 @@ void SurfaceMaterial::copy(SurfaceMaterial *destination) const
destination->validate();
}
void SurfaceMaterial::validate()
{
void SurfaceMaterial::validate() {
}

View file

@ -6,9 +6,8 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT SurfaceMaterial
{
public:
class DEFINITIONSHARED_EXPORT SurfaceMaterial {
public:
SurfaceMaterial();
SurfaceMaterial(const Color &color);
SurfaceMaterial(const SurfaceMaterial &other);
@ -23,7 +22,7 @@ public:
void copy(SurfaceMaterial *destination) const;
void validate();
public:
public:
Color *base;
double hardness;
@ -32,7 +31,6 @@ public:
double receive_shadows;
};
}
}

View file

@ -5,9 +5,7 @@
#include "PackStream.h"
#include "FloatNode.h"
TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
DefinitionNode(parent, "terrain", "terrain")
{
TerrainDefinition::TerrainDefinition(DefinitionNode *parent) : DefinitionNode(parent, "terrain", "terrain") {
height = 1.0;
shadow_smoothing = 0.0;
@ -20,17 +18,14 @@ TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
_height_noise = new NoiseGenerator;
}
TerrainDefinition::~TerrainDefinition()
{
TerrainDefinition::~TerrainDefinition() {
delete _height_noise;
}
void TerrainDefinition::validate()
{
void TerrainDefinition::validate() {
_height_noise->validate();
if (height < 1.0)
{
if (height < 1.0) {
height = 1.0;
}
@ -43,9 +38,8 @@ void TerrainDefinition::validate()
has_painting = height_map->hasPainting();
}
void TerrainDefinition::copy(DefinitionNode* _destination) const
{
TerrainDefinition* destination = (TerrainDefinition*)_destination;
void TerrainDefinition::copy(DefinitionNode *_destination) const {
TerrainDefinition *destination = (TerrainDefinition *)_destination;
destination->height = height;
destination->shadow_smoothing = shadow_smoothing;
@ -57,8 +51,7 @@ void TerrainDefinition::copy(DefinitionNode* _destination) const
destination->validate();
}
void TerrainDefinition::save(PackStream* stream) const
{
void TerrainDefinition::save(PackStream *stream) const {
DefinitionNode::save(stream);
stream->write(&height);
@ -66,8 +59,7 @@ void TerrainDefinition::save(PackStream* stream) const
_height_noise->save(stream);
}
void TerrainDefinition::load(PackStream* stream)
{
void TerrainDefinition::load(PackStream *stream) {
DefinitionNode::load(stream);
stream->read(&height);
@ -77,44 +69,36 @@ void TerrainDefinition::load(PackStream* stream)
validate();
}
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
{
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting) {
double h;
if (!with_painting || !has_painting || !height_map->getGridValue(x, z, &h))
{
if (!with_painting || !has_painting || !height_map->getGridValue(x, z, &h)) {
h = _height_noise->get2DTotal((double)x, (double)z);
}
return h;
}
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset)
{
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting,
bool water_offset) {
double h;
if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h))
{
if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h)) {
h = _height_noise->get2DTotal(x, z);
}
if (scaled)
{
if (scaled) {
return (water_offset ? (h - water_height->getValue()) : h) * height;
}
else
{
} else {
return h;
}
}
double TerrainDefinition::getWaterOffset() const
{
double TerrainDefinition::getWaterOffset() const {
return -water_height->getValue() * height;
}
HeightInfo TerrainDefinition::getHeightInfo()
{
HeightInfo TerrainDefinition::getHeightInfo() {
HeightInfo result;
result.min_height = _min_height;
@ -124,16 +108,13 @@ HeightInfo TerrainDefinition::getHeightInfo()
return result;
}
unsigned long TerrainDefinition::getMemoryStats()
{
unsigned long TerrainDefinition::getMemoryStats() {
return height_map->getMemoryStats();
}
void TerrainDefinition::applyPreset(TerrainPreset preset)
{
void TerrainDefinition::applyPreset(TerrainPreset preset) {
int resolution = 8;
switch (preset)
{
switch (preset) {
case TERRAIN_PRESET_STANDARD:
_height_noise->randomizeOffsets();
_height_noise->clearLevels();

View file

@ -8,56 +8,52 @@
namespace paysages {
namespace definition {
typedef struct
{
typedef struct {
double min_height;
double max_height;
double base_height;
} HeightInfo;
class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode
{
public:
TerrainDefinition(DefinitionNode* parent);
class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode {
public:
TerrainDefinition(DefinitionNode *parent);
virtual ~TerrainDefinition();
virtual void save(PackStream* stream) const override;
virtual void load(PackStream* stream) override;
virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override;
virtual void copy(DefinitionNode* destination) const override;
virtual void copy(DefinitionNode *destination) const override;
virtual void validate() override;
inline FloatNode *propWaterHeight() const {return water_height;}
inline FloatNode *propWaterHeight() const {
return water_height;
}
double getGridHeight(int x, int z, bool with_painting);
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset=true);
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset = true);
double getWaterOffset() const;
unsigned long getMemoryStats();
HeightInfo getHeightInfo();
public:
typedef enum
{
TERRAIN_PRESET_STANDARD
} TerrainPreset;
public:
typedef enum { TERRAIN_PRESET_STANDARD } TerrainPreset;
void applyPreset(TerrainPreset preset);
public:
public:
double height;
double shadow_smoothing;
TerrainHeightMap* height_map;
TerrainHeightMap *height_map;
bool has_painting;
double _detail;
NoiseGenerator* _height_noise;
NoiseGenerator *_height_noise;
double _min_height;
double _max_height;
private:
private:
FloatNode *water_height;
};
}
}

View file

@ -3,64 +3,55 @@
#include "TerrainDefinition.h"
#include "PaintedGridBrush.h"
TerrainHeightMap::TerrainHeightMap(TerrainDefinition* terrain):
PaintedGrid(terrain), terrain(terrain)
{
TerrainHeightMap::TerrainHeightMap(TerrainDefinition *terrain) : PaintedGrid(terrain), terrain(terrain) {
}
void TerrainHeightMap::copy(DefinitionNode* _destination) const
{
TerrainHeightMap* destination = (TerrainHeightMap*)_destination;
void TerrainHeightMap::copy(DefinitionNode *_destination) const {
TerrainHeightMap *destination = (TerrainHeightMap *)_destination;
destination->terrain = terrain;
PaintedGrid::copy(destination);
}
double TerrainHeightMap::getInitialValue(double x, double y) const
{
double TerrainHeightMap::getInitialValue(double x, double y) const {
return terrain->getInterpolatedHeight(x, y, false, false);
}
void TerrainHeightMap::brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
{
void TerrainHeightMap::brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
PaintedGridBrushRaiseLower sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit);
}
void TerrainHeightMap::brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force, bool commit)
{
void TerrainHeightMap::brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force,
bool commit) {
PaintedGridBrushFlatten sbrush(brush, height);
applyBrush(sbrush, x, y, force / terrain->height, commit);
}
void TerrainHeightMap::brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
{
void TerrainHeightMap::brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
PaintedGridBrushSmooth sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit);
}
void TerrainHeightMap::brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator* generator, double value, bool commit)
{
void TerrainHeightMap::brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator *generator,
double value, bool commit) {
PaintedGridBrushAddNoise sbrush(brush, generator);
applyBrush(sbrush, x, y, value / terrain->height, commit);
}
void TerrainHeightMap::brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
{
void TerrainHeightMap::brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
PaintedGridBrushReset sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit);
}
void TerrainHeightMap::clearPainting()
{
void TerrainHeightMap::clearPainting() {
PaintedGrid::clearPainting();
terrain->validate();
}
void TerrainHeightMap::endBrushStroke()
{
void TerrainHeightMap::endBrushStroke() {
PaintedGrid::endBrushStroke();
terrain->validate();

View file

@ -8,30 +8,32 @@
namespace paysages {
namespace definition {
class DEFINITIONSHARED_EXPORT TerrainHeightMap : public PaintedGrid
{
public:
class DEFINITIONSHARED_EXPORT TerrainHeightMap : public PaintedGrid {
public:
TerrainHeightMap(TerrainDefinition *terrain);
virtual void copy(DefinitionNode *destination) const override;
inline TerrainDefinition* getTerrain() const {return terrain;}
inline TerrainDefinition *getTerrain() const {
return terrain;
}
virtual double getInitialValue(double x, double y) const override;
void brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
void brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
void brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator* generator, double value, bool commit=false);
void brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
void brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force, bool commit=false);
void brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
void brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
void brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator *generator, double value,
bool commit = false);
void brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
void brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force,
bool commit = false);
virtual void clearPainting() override;
virtual void endBrushStroke() override;
private:
TerrainDefinition* terrain;
private:
TerrainDefinition *terrain;
};
}
}

View file

@ -8,9 +8,8 @@
#include "TerrainDefinition.h"
#include "Color.h"
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode* parent):
DefinitionNode(parent, "texture", "texturelayer")
{
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent)
: DefinitionNode(parent, "texture", "texturelayer") {
terrain_zone = new Zone;
_displacement_noise = new NoiseGenerator;
_detail_noise = new NoiseGenerator;
@ -20,20 +19,17 @@ TextureLayerDefinition::TextureLayerDefinition(DefinitionNode* parent):
displacement_scaling = 1.0;
}
TextureLayerDefinition::~TextureLayerDefinition()
{
TextureLayerDefinition::~TextureLayerDefinition() {
delete terrain_zone;
delete _displacement_noise;
delete _detail_noise;
delete material;
}
void TextureLayerDefinition::validate()
{
void TextureLayerDefinition::validate() {
DefinitionNode::validate();
if (displacement_scaling < 0.000001)
{
if (displacement_scaling < 0.000001) {
displacement_scaling = 0.000001;
}
@ -50,20 +46,18 @@ void TextureLayerDefinition::validate()
material->validate();
/* Update zone height range */
const Scenery* scenery = getScenery();
if (scenery)
{
TerrainDefinition* terrain = scenery->getTerrain();
const Scenery *scenery = getScenery();
if (scenery) {
TerrainDefinition *terrain = scenery->getTerrain();
HeightInfo height_info = terrain->getHeightInfo();
terrain_zone->setRelativeHeight(height_info.min_height, height_info.base_height, height_info.max_height);
}
}
void TextureLayerDefinition::copy(DefinitionNode *_destination) const
{
void TextureLayerDefinition::copy(DefinitionNode *_destination) const {
DefinitionNode::copy(_destination);
TextureLayerDefinition* destination = (TextureLayerDefinition*)_destination;
TextureLayerDefinition *destination = (TextureLayerDefinition *)_destination;
terrain_zone->copy(destination->terrain_zone);
@ -76,8 +70,7 @@ void TextureLayerDefinition::copy(DefinitionNode *_destination) const
_detail_noise->copy(destination->_detail_noise);
}
void TextureLayerDefinition::save(PackStream* stream) const
{
void TextureLayerDefinition::save(PackStream *stream) const {
DefinitionNode::save(stream);
terrain_zone->save(stream);
@ -90,8 +83,7 @@ void TextureLayerDefinition::save(PackStream* stream) const
_detail_noise->save(stream);
}
void TextureLayerDefinition::load(PackStream* stream)
{
void TextureLayerDefinition::load(PackStream *stream) {
DefinitionNode::load(stream);
terrain_zone->load(stream);
@ -104,64 +96,62 @@ void TextureLayerDefinition::load(PackStream* stream)
_detail_noise->load(stream);
}
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset)
{
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset) {
_displacement_noise->randomizeOffsets();
_detail_noise->randomizeOffsets();
terrain_zone->clear();
switch (preset)
{
case TEXTURES_LAYER_PRESET_MUD:
displacement_height = 0.02;
displacement_scaling = 3.0;
displacement_offset = 0.0;
material->setColor(0.015, 0.014, 0.014, 1.0);
material->reflection = 0.003;
material->shininess = 4.0;
break;
case TEXTURES_LAYER_PRESET_ROCK:
terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 1.0, 1.0);
displacement_height = 0.3;
displacement_scaling = 2.0;
displacement_offset = 0.0;
material->setColor(0.6, 0.55, 0.57, 1.0);
material->reflection = 0.006;
material->shininess = 6.0;
break;
case TEXTURES_LAYER_PRESET_GRASS:
terrain_zone->addHeightRangeQuick(1.0, 0.45, 0.5, 0.8, 1.0);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.05, 0.4);
displacement_height = 0.0;
displacement_scaling = 1.0;
displacement_offset = 0.0;
material->setColor(0.12, 0.19, 0.035, 1.0);
material->reflection = 0.001;
material->shininess = 4.0;
break;
case TEXTURES_LAYER_PRESET_SAND:
terrain_zone->addHeightRangeQuick(1.0, 0.495, 0.505, 0.56, 0.63);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.1, 0.4);
displacement_height = 0.05;
displacement_scaling = 5.0;
displacement_offset = 0.0;
material->setColor(1.2, 1.1, 0.9, 1.0);
material->reflection = 0.008;
material->shininess = 1.0;
break;
case TEXTURES_LAYER_PRESET_SNOW:
terrain_zone->addHeightRangeQuick(1.0, 0.77, 0.85, 1.0, 1.0);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.2, 1.0);
displacement_height = 0.1;
displacement_scaling = 1.0;
displacement_offset = 0.0;
material->setColor(5.0, 5.0, 5.0, 1.0);
material->reflection = 0.02;
material->shininess = 0.6;
break;
default:
break;
switch (preset) {
case TEXTURES_LAYER_PRESET_MUD:
displacement_height = 0.02;
displacement_scaling = 3.0;
displacement_offset = 0.0;
material->setColor(0.015, 0.014, 0.014, 1.0);
material->reflection = 0.003;
material->shininess = 4.0;
break;
case TEXTURES_LAYER_PRESET_ROCK:
terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 1.0, 1.0);
displacement_height = 0.3;
displacement_scaling = 2.0;
displacement_offset = 0.0;
material->setColor(0.6, 0.55, 0.57, 1.0);
material->reflection = 0.006;
material->shininess = 6.0;
break;
case TEXTURES_LAYER_PRESET_GRASS:
terrain_zone->addHeightRangeQuick(1.0, 0.45, 0.5, 0.8, 1.0);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.05, 0.4);
displacement_height = 0.0;
displacement_scaling = 1.0;
displacement_offset = 0.0;
material->setColor(0.12, 0.19, 0.035, 1.0);
material->reflection = 0.001;
material->shininess = 4.0;
break;
case TEXTURES_LAYER_PRESET_SAND:
terrain_zone->addHeightRangeQuick(1.0, 0.495, 0.505, 0.56, 0.63);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.1, 0.4);
displacement_height = 0.05;
displacement_scaling = 5.0;
displacement_offset = 0.0;
material->setColor(1.2, 1.1, 0.9, 1.0);
material->reflection = 0.008;
material->shininess = 1.0;
break;
case TEXTURES_LAYER_PRESET_SNOW:
terrain_zone->addHeightRangeQuick(1.0, 0.77, 0.85, 1.0, 1.0);
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.2, 1.0);
displacement_height = 0.1;
displacement_scaling = 1.0;
displacement_offset = 0.0;
material->setColor(5.0, 5.0, 5.0, 1.0);
material->reflection = 0.02;
material->shininess = 0.6;
break;
default:
break;
}
validate();

Some files were not shown because too many files have changed in this diff Show more