Enforced coding style using clang-format

This commit is contained in:
Michaël Lemaire 2015-11-09 22:30:46 +01:00
parent d82fc73531
commit 88d2a78b70
314 changed files with 5150 additions and 7810 deletions

View file

@ -7,6 +7,9 @@ PATH:=${QTSDK}/bin:${PATH}
all:build all:build
format:
find src \( \( -name '*.cpp' -or -name '*.h' \) -and \! -path '*/googletest/*' \) -exec clang-format -i \{\} \;
dirs: dirs:
mkdir -p ${BUILDPATH} 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" #include "Vector3.h"
BoundingBox::BoundingBox() BoundingBox::BoundingBox() {
{
reset(); reset();
} }
void BoundingBox::reset() void BoundingBox::reset() {
{
empty = 1; empty = 1;
xmin = 10000000000.0; xmin = 10000000000.0;
xmax = -10000000000.0; xmax = -10000000000.0;
@ -18,31 +16,24 @@ void BoundingBox::reset()
zmax = -10000000000.0; zmax = -10000000000.0;
} }
void BoundingBox::pushPoint(const Vector3 &point) void BoundingBox::pushPoint(const Vector3 &point) {
{
empty = 0; empty = 0;
if (point.x < xmin) if (point.x < xmin) {
{
xmin = point.x; xmin = point.x;
} }
if (point.x > xmax) if (point.x > xmax) {
{
xmax = point.x; xmax = point.x;
} }
if (point.y < ymin) if (point.y < ymin) {
{
ymin = point.y; ymin = point.y;
} }
if (point.y > ymax) if (point.y > ymax) {
{
ymax = point.y; ymax = point.y;
} }
if (point.z < zmin) if (point.z < zmin) {
{
zmin = point.z; zmin = point.z;
} }
if (point.z > zmax) if (point.z > zmax) {
{
zmax = point.z; zmax = point.z;
} }
} }

View file

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

View file

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

View file

@ -11,13 +11,14 @@ namespace basics {
/** /**
* Geometric cylinder, with capped ends (not infinite). * Geometric cylinder, with capped ends (not infinite).
*/ */
class BASICSSHARED_EXPORT CappedCylinder: public InfiniteCylinder class BASICSSHARED_EXPORT CappedCylinder : public InfiniteCylinder {
{ public:
public:
CappedCylinder(); CappedCylinder();
CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length); 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. * Check the intersection between the cylinder and an infinite ray.
@ -32,10 +33,9 @@ public:
virtual void save(PackStream *stream) const override; virtual void save(PackStream *stream) const override;
virtual void load(PackStream *stream) override; virtual void load(PackStream *stream) override;
private: private:
double length; 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_WHITE = {1.0, 1.0, 1.0, 1.0};
const Color paysages::basics::COLOR_GREY = {0.5, 0.5, 0.5, 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(&r);
stream->write(&g); stream->write(&g);
stream->write(&b); stream->write(&b);
stream->write(&a); stream->write(&a);
} }
void Color::load(PackStream* stream) void Color::load(PackStream *stream) {
{
stream->read(&r); stream->read(&r);
stream->read(&g); stream->read(&g);
stream->read(&b); stream->read(&b);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,13 +11,14 @@ namespace basics {
/** /**
* Geometric plane disk. * Geometric plane disk.
*/ */
class BASICSSHARED_EXPORT Disk: public InfinitePlane class BASICSSHARED_EXPORT Disk : public InfinitePlane {
{ public:
public:
Disk(); Disk();
Disk(const Vector3 &point, const Vector3 &normal, double radius); 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. * 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. * 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 save(PackStream *stream) const override;
void load(PackStream *stream) override; void load(PackStream *stream) override;
private: private:
double radius; double radius;
double radius2; double radius2;
}; };
} }
} }

View file

@ -1,7 +1,6 @@
#include "FractalNoise.h" #include "FractalNoise.h"
FractalNoise::FractalNoise() FractalNoise::FractalNoise() {
{
scaling = 1.0; scaling = 1.0;
height = 1.0; height = 1.0;
step_scaling = 2.0; step_scaling = 2.0;
@ -10,47 +9,39 @@ FractalNoise::FractalNoise()
ridge = 0.0; 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->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling;
this->height = scaling * height; 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_scaling = scaling_factor < 0.00000001 ? 0.0 : 1.0 / scaling_factor;
this->step_height = scaling_factor * height_factor; this->step_height = scaling_factor * height_factor;
} }
void FractalNoise::setSlope(double slope_factor) void FractalNoise::setSlope(double slope_factor) {
{
this->slope = slope_factor; this->slope = slope_factor;
} }
void FractalNoise::setRidge(double ridge_factor) void FractalNoise::setRidge(double ridge_factor) {
{
this->ridge = ridge_factor; this->ridge = ridge_factor;
} }
void FractalNoise::setState(const NoiseState &state) void FractalNoise::setState(const NoiseState &state) {
{
state.copy(&this->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_scaling = scaling;
double current_height = height; double current_height = height;
double result = 0.0; double result = 0.0;
int state_level_count = state.level_offsets.size(); int state_level_count = state.level_offsets.size();
int i = 0; int i = 0;
while (current_height >= detail) while (current_height >= detail) {
{
const NoiseState::NoiseOffset &offset = state.level_offsets[i]; const NoiseState::NoiseOffset &offset = state.level_offsets[i];
result += getBase1d(offset.x + x * current_scaling) * current_height; 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; current_height *= step_height;
i++; i++;
if (i >= state_level_count) if (i >= state_level_count) {
{
i = 0; i = 0;
} }
} }
@ -68,16 +58,14 @@ double FractalNoise::get1d(double detail, double x) const
return result; 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_scaling = scaling;
double current_height = height; double current_height = height;
double result = 0.0; double result = 0.0;
int state_level_count = state.level_offsets.size(); int state_level_count = state.level_offsets.size();
int i = 0; int i = 0;
while (current_height >= detail) while (current_height >= detail) {
{
const NoiseState::NoiseOffset &offset = state.level_offsets[i]; const NoiseState::NoiseOffset &offset = state.level_offsets[i];
result += getBase2d(offset.x + x * current_scaling, offset.y + y * current_scaling) * current_height; 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; current_height *= step_height;
i++; i++;
if (i >= state_level_count) if (i >= state_level_count) {
{
i = 0; i = 0;
} }
} }
@ -95,26 +82,25 @@ double FractalNoise::get2d(double detail, double x, double y) const
return result; 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_scaling = scaling;
double current_height = height; double current_height = height;
double result = 0.0; double result = 0.0;
int state_level_count = state.level_offsets.size(); int state_level_count = state.level_offsets.size();
int i = 0; int i = 0;
while (current_height >= detail) while (current_height >= detail) {
{
const NoiseState::NoiseOffset &offset = state.level_offsets[i]; 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_scaling *= step_scaling;
current_height *= step_height; current_height *= step_height;
i++; i++;
if (i >= state_level_count) if (i >= state_level_count) {
{
i = 0; i = 0;
} }
} }
@ -122,12 +108,10 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const
return result; return result;
} }
double FractalNoise::getBase1d(double x) const double FractalNoise::getBase1d(double x) const {
{
return getBase2d(x, 0.0); 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); 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. * \brief Fractal noise generator, based on a sum of simple noise functions.
*/ */
class BASICSSHARED_EXPORT FractalNoise class BASICSSHARED_EXPORT FractalNoise {
{ public:
public:
FractalNoise(); FractalNoise();
virtual ~FractalNoise(); virtual ~FractalNoise();
void setScaling(double scaling, double height=1.0); void setScaling(double scaling, double height = 1.0);
void setStep(double scaling_factor, double height_factor=1.0); void setStep(double scaling_factor, double height_factor = 1.0);
void setSlope(double slope_factor); void setSlope(double slope_factor);
void setRidge(double ridge_factor); void setRidge(double ridge_factor);
void setState(const NoiseState &state); void setState(const NoiseState &state);
@ -31,7 +30,7 @@ public:
virtual double getBase2d(double x, double y) const; virtual double getBase2d(double x, double y) const;
virtual double getBase3d(double x, double y, double z) const = 0; virtual double getBase3d(double x, double y, double z) const = 0;
private: private:
NoiseState state; NoiseState state;
double scaling; double scaling;
@ -41,7 +40,6 @@ private:
double slope; double slope;
double ridge; double ridge;
}; };
} }
} }

View file

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

View file

@ -6,15 +6,14 @@
namespace paysages { namespace paysages {
namespace basics { namespace basics {
class BASICSSHARED_EXPORT Geometry class BASICSSHARED_EXPORT Geometry {
{ public:
public:
static double get2DAngle(double x, double y); static double get2DAngle(double x, double y);
static Vector3 getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right); static Vector3 getNormalFromTriangle(const Vector3 &center, const Vector3 &bottom, const Vector3 &right);
static double getDistance2D(double x1, double y1, double x2, double y2); 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 #define EPS 1E-8
InfiniteCylinder::InfiniteCylinder() InfiniteCylinder::InfiniteCylinder() {
{
} }
InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius): InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius) : axis(axis), radius(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. * 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. * 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 */ /* choose U, V so that U,V,F is orthonormal set */
if ( fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z) ) if (fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z)) {
{ length = sqrt(F.x * F.x + F.y * F.y);
length = sqrt(F.x*F.x+F.y*F.y); invLength = 1.0 / length;
invLength = 1.0/length; U.x = -F.y * invLength;
U.x = -F.y*invLength; U.y = +F.x * invLength;
U.y = +F.x*invLength;
U.z = 0.0; U.z = 0.0;
prod = -F.z*invLength; prod = -F.z * invLength;
V.x = F.x*prod; V.x = F.x * prod;
V.y = F.y*prod; V.y = F.y * prod;
V.z = length; V.z = length;
} } else {
else length = sqrt(F.y * F.y + F.z * F.z);
{ invLength = 1.0 / length;
length = sqrt(F.y*F.y+F.z*F.z);
invLength = 1.0/length;
U.x = 0.0; U.x = 0.0;
U.y = -F.z*invLength; U.y = -F.z * invLength;
U.z = +F.y*invLength; U.z = +F.y * invLength;
prod = -F.x*invLength; prod = -F.x * invLength;
V.x = length; V.x = length;
V.y = F.y*prod; V.y = F.y * prod;
V.z = F.z*prod; V.z = F.z * prod;
} }
/* orthonormal matrix */ /* orthonormal matrix */
R[0][0] = U.x; R[0][1] = U.y; R[0][2] = U.z; R[0][0] = U.x;
R[1][0] = V.x; R[1][1] = V.y; R[1][2] = V.z; R[0][1] = U.y;
R[2][0] = F.x; R[2][1] = F.y; R[2][2] = F.z; 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 */ /* matrix A */
A[0][0] = R[0][0]*R[0][0]+R[1][0]*R[1][0]; 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][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][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][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][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][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][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][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][2] = R[0][2] * R[0][2] + R[1][2] * R[1][2];
/* vector B */ /* vector B */
P = Vector3(0.0, 0.0, 0.0); 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 */ /* constant C */
e0 = -2.0*(R[0][0]*P.x+R[0][1]*P.y+R[0][2]*P.z); 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); 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; C = 0.25 * (e0 * e0 + e1 * e1) - radius * radius;
/* line */ /* line */
Q = ray.getOrigin().sub(axis.getOrigin()); Q = ray.getOrigin().sub(axis.getOrigin());
G = ray.getDirection(); G = ray.getDirection();
/* compute A*G */ /* compute A*G */
AG.x = A[0][0]*G.x+A[0][1]*G.y+A[0][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.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.z = A[2][0] * G.x + A[2][1] * G.y + A[2][2] * G.z;
/* compute A*Q */ /* compute A*Q */
AQ.x = A[0][0]*Q.x+A[0][1]*Q.y+A[0][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.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.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 */ /* compute quadratic equation c0+c1*t+c2*t^2 = 0 */
c2 = G.x*AG.x+G.y*AG.y+G.z*AG.z; 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); 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; 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 */ /* solve for intersections */
int numIntersections; int numIntersections;
discr = c1*c1-4.0*c0*c2; discr = c1 * c1 - 4.0 * c0 * c2;
if ( discr > EPS ) if (discr > EPS) {
{
numIntersections = 2; numIntersections = 2;
discr = sqrt(discr); discr = sqrt(discr);
invC2 = 1.0/c2; invC2 = 1.0 / c2;
root0 = -0.5*(c1+discr)*invC2; root0 = -0.5 * (c1 + discr) * invC2;
root1 = -0.5*(c1-discr)*invC2; root1 = -0.5 * (c1 - discr) * invC2;
first_intersection->x = Q.x+root0*G.x; first_intersection->x = Q.x + root0 * G.x;
first_intersection->y = Q.y+root0*G.y; first_intersection->y = Q.y + root0 * G.y;
first_intersection->z = Q.z+root0*G.z; first_intersection->z = Q.z + root0 * G.z;
second_intersection->x = Q.x+root1*G.x; second_intersection->x = Q.x + root1 * G.x;
second_intersection->y = Q.y+root1*G.y; second_intersection->y = Q.y + root1 * G.y;
second_intersection->z = Q.z+root1*G.z; second_intersection->z = Q.z + root1 * G.z;
*first_intersection = first_intersection->add(axis.getOrigin()); *first_intersection = first_intersection->add(axis.getOrigin());
*second_intersection = second_intersection->add(axis.getOrigin()); *second_intersection = second_intersection->add(axis.getOrigin());
} } else if (discr < -EPS) {
else if ( discr < -EPS )
{
numIntersections = 0; numIntersections = 0;
} } else {
else
{
numIntersections = 1; numIntersections = 1;
root = -0.5*c1/c2; root = -0.5 * c1 / c2;
first_intersection->x = Q.x+root*G.x; first_intersection->x = Q.x + root * G.x;
first_intersection->y = Q.y+root*G.y; first_intersection->y = Q.y + root * G.y;
first_intersection->z = Q.z+root*G.z; first_intersection->z = Q.z + root * G.z;
*first_intersection = first_intersection->add(axis.getOrigin()); *first_intersection = first_intersection->add(axis.getOrigin());
} }
@ -136,14 +133,12 @@ int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *firs
return numIntersections; return numIntersections;
} }
void InfiniteCylinder::save(PackStream *stream) const void InfiniteCylinder::save(PackStream *stream) const {
{
axis.save(stream); axis.save(stream);
stream->write(&radius); stream->write(&radius);
} }
void InfiniteCylinder::load(PackStream *stream) void InfiniteCylinder::load(PackStream *stream) {
{
axis.load(stream); axis.load(stream);
stream->read(&radius); stream->read(&radius);
} }

View file

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

View file

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

View file

@ -11,9 +11,8 @@ namespace basics {
/** /**
* Infinite 3d geometric plane. * Infinite 3d geometric plane.
*/ */
class BASICSSHARED_EXPORT InfinitePlane class BASICSSHARED_EXPORT InfinitePlane {
{ public:
public:
InfinitePlane(); InfinitePlane();
InfinitePlane(const Vector3 &point, const Vector3 &normal); 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. * 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 &getPoint() const {
inline const Vector3 &getNormal() const {return normal;} return point;
}
inline const Vector3 &getNormal() const {
return normal;
}
virtual void save(PackStream *stream) const; virtual void save(PackStream *stream) const;
virtual void load(PackStream *stream); virtual void load(PackStream *stream);
private: private:
Vector3 point; Vector3 point;
Vector3 normal; Vector3 normal;
}; };
} }
} }

View file

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

View file

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

View file

@ -1,7 +1,6 @@
#include "Interpolation.h" #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]; double buf_cubic_y[4];
buf_cubic_y[0] = Interpolation::cubic(stencil, x); 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); 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 e1 = linear(p[0], p[1], x);
double e2 = linear(p[3], p[2], x); double e2 = linear(p[3], p[2], x);
return Interpolation::linear(e1, e2, y); 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 f1 = bilinear(p, x, y);
double f2 = bilinear(p + 4, x, y); double f2 = bilinear(p + 4, x, y);
return Interpolation::linear(f1, f2, z); return Interpolation::linear(f1, f2, z);

View file

@ -6,23 +6,21 @@
namespace paysages { namespace paysages {
namespace basics { namespace basics {
class BASICSSHARED_EXPORT Interpolation class BASICSSHARED_EXPORT Interpolation {
{ public:
public: static inline double linear(double p1, double p2, double x) {
static inline double linear(double p1, double p2, double x)
{
return p1 + x * (p2 - p1); return p1 + x * (p2 - p1);
} }
static double bilinear(double p[4], double x, double y); static double bilinear(double p[4], double x, double y);
static double trilinear(double p[8], double x, double y, double z); static double trilinear(double p[8], double x, double y, double z);
static inline double cubic(double p[4], double x) static inline double cubic(double p[4], double x) {
{ return p[1] +
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]))); 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); static double bicubic(double stencil[16], double x, double y);
}; };
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,5 +1,4 @@
#include "SpaceGridIterator.h" #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. * This may be useful for ray marching algorithms for example.
*/ */
class BASICSSHARED_EXPORT SpaceGridIterator class BASICSSHARED_EXPORT SpaceGridIterator {
{ public:
public:
SpaceGridIterator(); SpaceGridIterator();
/** /**
@ -23,7 +22,6 @@ public:
*/ */
virtual bool onCell(int x, int y, int z) = 0; virtual bool onCell(int x, int y, int z) = 0;
}; };
} }
} }

View file

@ -3,54 +3,36 @@
#include <climits> #include <climits>
#include "SpaceGridIterator.h" #include "SpaceGridIterator.h"
SpaceSegment::SpaceSegment(const Vector3& start, const Vector3& end): SpaceSegment::SpaceSegment(const Vector3 &start, const Vector3 &end) : start(start), end(end) {
start(start), end(end)
{
} }
bool SpaceSegment::intersectYInterval(double ymin, double ymax) bool SpaceSegment::intersectYInterval(double ymin, double ymax) {
{ if (start.y > ymax) {
if (start.y > ymax) if (end.y >= ymax) {
{
if (end.y >= ymax)
{
return false; return false;
} } else {
else
{
Vector3 diff = end.sub(start); Vector3 diff = end.sub(start);
start = start.add(diff.scale((ymax - start.y) / diff.y)); 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)); end = end.add(diff.scale((ymin - end.y) / diff.y));
} }
} }
} } else if (start.y < ymin) {
else if (start.y < ymin) if (end.y <= ymin) {
{
if (end.y <= ymin)
{
return false; return false;
} } else {
else
{
Vector3 diff = end.sub(start); Vector3 diff = end.sub(start);
start = start.add(diff.scale((ymin - start.y) / diff.y)); 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)); 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); Vector3 diff = end.sub(start);
if (end.y > ymax) if (end.y > ymax) {
{
end = start.add(diff.scale((ymax - start.y) / diff.y)); 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)); end = start.add(diff.scale((ymin - start.y) / diff.y));
} }
} }
@ -58,28 +40,23 @@ bool SpaceSegment::intersectYInterval(double ymin, double ymax)
return true; 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)); 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)); 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)); 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)); return SpaceSegment(start.scale(factor), end.scale(factor));
} }
bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate) bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate) {
{
Vector3 diff = end.sub(start); Vector3 diff = end.sub(start);
int stepX = diff.x < 0.0 ? -1 : 1; int stepX = diff.x < 0.0 ? -1 : 1;
@ -98,36 +75,25 @@ bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate)
double tMaxY = diff.y == 0.0 ? INFINITY : ((double)(Y + (stepY > 0 ? 1 : 0)) - start.y) / diff.y; 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; double tMaxZ = diff.z == 0.0 ? INFINITY : ((double)(Z + (stepZ > 0 ? 1 : 0)) - start.z) / diff.z;
do do {
{ if (not delegate.onCell(X, Y, Z)) {
if (not delegate.onCell(X, Y, Z))
{
return false; return false;
} }
if (tMaxX < tMaxY) if (tMaxX < tMaxY) {
{ if (tMaxX < tMaxZ) {
if (tMaxX < tMaxZ)
{
X = X + stepX; X = X + stepX;
tMaxX = tMaxX + tDeltaX; tMaxX = tMaxX + tDeltaX;
} } else {
else
{
Z = Z + stepZ; Z = Z + stepZ;
tMaxZ = tMaxZ + tDeltaZ; tMaxZ = tMaxZ + tDeltaZ;
} }
} } else {
else if (tMaxY < tMaxZ) {
{
if(tMaxY < tMaxZ)
{
Y = Y + stepY; Y = Y + stepY;
tMaxY = tMaxY + tDeltaY; tMaxY = tMaxY + tDeltaY;
} } else {
else Z = Z + stepZ;
{
Z= Z + stepZ;
tMaxZ = tMaxZ + tDeltaZ; tMaxZ = tMaxZ + tDeltaZ;
} }
} }

View file

@ -11,20 +11,34 @@ namespace basics {
/** /**
* A delimited segment in 3D space (mainly useful for rays). * A delimited segment in 3D space (mainly useful for rays).
*/ */
class BASICSSHARED_EXPORT SpaceSegment class BASICSSHARED_EXPORT SpaceSegment {
{ public:
public: SpaceSegment(const Vector3 &start, const Vector3 &end);
SpaceSegment(const Vector3& start, const Vector3& end); SpaceSegment() : SpaceSegment(Vector3(), Vector3()) {
SpaceSegment(): SpaceSegment(Vector3(), Vector3()) {} }
inline const Vector3 &getStart() const {return start;} inline const Vector3 &getStart() const {
inline const Vector3 &getEnd() const {return end;} return start;
inline Vector3 getDirection() const {return end.sub(start);} }
inline double getLength() const {return end.sub(start).getNorm();} 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 getXDiff() const {
inline double getYDiff() const {return end.y - start.y;} return end.x - start.x;
inline double getZDiff() const {return end.z - start.z;} }
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. * Keep only the intersection with a slice orthogonal to the Y axis.
@ -36,15 +50,15 @@ public:
/** /**
* Return a version of this segment, projected on a X plane. * 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. * 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. * 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. * Return a scaled version of this segment.
@ -64,11 +78,10 @@ public:
*/ */
bool iterateOnGrid(SpaceGridIterator &delegate); bool iterateOnGrid(SpaceGridIterator &delegate);
private: private:
Vector3 start; Vector3 start;
Vector3 end; Vector3 end;
}; };
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -6,32 +6,30 @@
namespace paysages { namespace paysages {
namespace basics { namespace basics {
class BASICSSHARED_EXPORT Texture4D class BASICSSHARED_EXPORT Texture4D {
{ public:
public:
Texture4D(int xsize, int ysize, int zsize, int wsize); Texture4D(int xsize, int ysize, int zsize, int wsize);
~Texture4D(); ~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); void setPixel(int x, int y, int z, int w, Color col);
Color getPixel(int x, int y, int z, int w) const; Color getPixel(int x, int y, int z, int w) const;
Color getNearest(double dx, double dy, double dz, double dw) const; Color getNearest(double dx, double dy, double dz, double dw) const;
Color getLinear(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; Color getCubic(double dx, double dy, double dz, double dw) const;
void fill(Color col); void fill(Color col);
void add(Texture4D* other); void add(Texture4D *other);
void save(PackStream* stream) const; void save(PackStream *stream) const;
void load(PackStream* stream); void load(PackStream *stream);
void saveToFile(const std::string &filepath) const; void saveToFile(const std::string &filepath) const;
private: private:
int xsize; int xsize;
int ysize; int ysize;
int zsize; int zsize;
int wsize; 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_WEST(-1.0, 0.0, 0.0);
const Vector3 paysages::basics::VECTOR_EAST(1.0, 0.0, 0.0); const Vector3 paysages::basics::VECTOR_EAST(1.0, 0.0, 0.0);
Vector3::Vector3(const VectorSpherical &v): 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)) : 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(&x);
stream->write(&y); stream->write(&y);
stream->write(&z); stream->write(&z);
} }
void Vector3::load(PackStream* stream) void Vector3::load(PackStream *stream) {
{
stream->read(&x); stream->read(&x);
stream->read(&y); stream->read(&y);
stream->read(&z); 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 // TEMP Copy of old euclid.c
double nx, ny, d, ret; double nx, ny, d, ret;
if (x == 0.0) if (x == 0.0) {
{ if (y == 0.0) {
if (y == 0.0)
{
return 0.0; return 0.0;
} } else if (y < 0.0) {
else if (y < 0.0)
{
return 3.0 * M_PI_2; return 3.0 * M_PI_2;
} } else {
else
{
return M_PI_2; return M_PI_2;
} }
} }
@ -56,21 +46,18 @@ static inline double _euclidGet2DAngle(double x, double y)
ny = y / d; ny = y / d;
ret = asin(ny); ret = asin(ny);
if (nx < 0.0) if (nx < 0.0) {
{
ret = M_PI - ret; ret = M_PI - ret;
} }
return ret < 0.0 ? ret + 2.0 * M_PI : ret; return ret < 0.0 ? ret + 2.0 * M_PI : ret;
} }
VectorSpherical Vector3::toSpherical() const VectorSpherical Vector3::toSpherical() const {
{
VectorSpherical result; VectorSpherical result;
result.phi = _euclidGet2DAngle(x, -z); result.phi = _euclidGet2DAngle(x, -z);
result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y); result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y);
if (y < 0.0) if (y < 0.0) {
{
result.theta -= 2.0 * M_PI; result.theta -= 2.0 * M_PI;
} }
result.r = getNorm(); result.r = getNorm();
@ -78,19 +65,14 @@ VectorSpherical Vector3::toSpherical() const
return result; 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); 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 // TODO More uniform spatial repartition
// The current randomization clusters result near the center and at the poles // The current randomization clusters result near the center and at the poles
VectorSpherical vec = { VectorSpherical vec = {only_surface ? radius : RandomGenerator::random() * radius,
only_surface ? radius : RandomGenerator::random() * radius, (RandomGenerator::random() - 0.5) * M_PI, RandomGenerator::random() * M_2PI};
(RandomGenerator::random() - 0.5) * M_PI,
RandomGenerator::random() * M_2PI
};
return Vector3(vec); return Vector3(vec);
} }

View file

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

View file

@ -1,73 +1,55 @@
#define VECTOR3_INLINE_CPP #define VECTOR3_INLINE_CPP
#ifdef VECTOR3_H #ifdef VECTOR3_H
# define METHSPEC inline #define METHSPEC inline
#else #else
# include "Vector3.h" #include "Vector3.h"
# define METHSPEC #define METHSPEC
#endif #endif
#include <cmath> #include <cmath>
METHSPEC Vector3::Vector3(double x, double y, double z): METHSPEC Vector3::Vector3(double x, double y, double z) : x(x), y(y), z(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); 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); 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); 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); 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); 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); 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); double norm = sqrt(x * x + y * y + z * z);
if (norm == 0.0) if (norm == 0.0) {
{
return VECTOR_ZERO; return VECTOR_ZERO;
} } else {
else
{
norm = 1.0 / norm; norm = 1.0 / norm;
return Vector3(x * norm, y * norm, z * 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; return x * other.x + y * other.y + z * other.z;
} }
METHSPEC Vector3 Vector3::crossProduct(const Vector3 &other) const 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);
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> #include <QtCore/qglobal.h>
#if defined(BASICS_LIBRARY) #if defined(BASICS_LIBRARY)
# define BASICSSHARED_EXPORT Q_DECL_EXPORT #define BASICSSHARED_EXPORT Q_DECL_EXPORT
#else #else
# define BASICSSHARED_EXPORT Q_DECL_IMPORT #define BASICSSHARED_EXPORT Q_DECL_IMPORT
#endif #endif
#include "system_global.h" #include "system_global.h"
namespace paysages { namespace paysages {
namespace basics { namespace basics {
class Vector3; class Vector3;
class Matrix4; class Matrix4;
class BoundingBox; class BoundingBox;
class SpaceGridIterator; class SpaceGridIterator;
class SpaceSegment; class SpaceSegment;
class Color; class Color;
class NoiseGenerator; class NoiseGenerator;
class NoiseState; class NoiseState;
class FractalNoise; class FractalNoise;
class Curve; class Curve;
class ColorProfile; class ColorProfile;
class Texture2D; class Texture2D;
class Texture3D; class Texture3D;
class Texture4D; class Texture4D;
class CappedCylinder; class CappedCylinder;
class InfiniteRay; class InfiniteRay;
class Sphere; class Sphere;
class InfinitePlane; class InfinitePlane;
} }
} }
using namespace paysages::basics; using namespace paysages::basics;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,20 +8,17 @@
namespace paysages { namespace paysages {
namespace definition { namespace definition {
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers {
{ public:
public: CloudsDefinition(DefinitionNode *parent);
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 typedef enum { CLOUDS_PRESET_PARTLY_CLOUDY } CloudsPreset;
{
CLOUDS_PRESET_PARTLY_CLOUDY
} CloudsPreset;
void applyPreset(CloudsPreset preset); void applyPreset(CloudsPreset preset);
}; };
} }
} }

View file

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

View file

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

View file

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

View file

@ -9,29 +9,40 @@ namespace definition {
/** /**
* Base class for all nodes of the definition tree. * Base class for all nodes of the definition tree.
*/ */
class DEFINITIONSHARED_EXPORT DefinitionNode class DEFINITIONSHARED_EXPORT DefinitionNode {
{ public:
public: DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name = "");
DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name = "");
virtual ~DefinitionNode(); virtual ~DefinitionNode();
virtual void save(PackStream* stream) const; virtual void save(PackStream *stream) const;
virtual void load(PackStream* stream); virtual void load(PackStream *stream);
virtual void copy(DefinitionNode* destination) const; virtual void copy(DefinitionNode *destination) const;
virtual void validate(); 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); 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 Scenery* getScenery(); virtual Scenery *getScenery();
inline const DefinitionNode *getParent() const {return parent;} inline const DefinitionNode *getParent() const {
inline const DefinitionNode *getRoot() const {return root;} return parent;
inline DiffManager *getDiffManager() const {return diffs;} }
inline int getChildrenCount() const {return children.size();} 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). * Return a string representation of the tree (mainly for debugging purposes).
@ -59,7 +70,7 @@ public:
* *
* Return true if the diff could be applied. * 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. * 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. * 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. * Get the current number of watchers.
*/ */
int getWatcherCount() const; int getWatcherCount() const;
protected: protected:
void addChild(DefinitionNode* child); void addChild(DefinitionNode *child);
void removeChild(DefinitionNode* child); void removeChild(DefinitionNode *child);
virtual DefinitionNode *findChildByName(const std::string name); virtual DefinitionNode *findChildByName(const std::string name);
/** /**
@ -104,15 +115,14 @@ protected:
*/ */
void addDiff(const DefinitionDiff *diff); void addDiff(const DefinitionDiff *diff);
private: private:
DefinitionNode *parent; DefinitionNode *parent;
DefinitionNode *root; DefinitionNode *root;
DiffManager *diffs; DiffManager *diffs;
std::string type_name; std::string type_name;
std::string name; std::string name;
std::vector<DefinitionNode*> children; std::vector<DefinitionNode *> children;
}; };
} }
} }

View file

@ -1,7 +1,4 @@
#include "DefinitionWatcher.h" #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. * Watchers will be registered in DiffManager to receive DefinitionDiff objects.
*/ */
class DEFINITIONSHARED_EXPORT DefinitionWatcher class DEFINITIONSHARED_EXPORT DefinitionWatcher {
{ public:
public:
DefinitionWatcher(); DefinitionWatcher();
/** /**
@ -21,7 +20,6 @@ public:
*/ */
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0; virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
}; };
} }
} }

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -11,30 +11,29 @@ namespace definition {
/** /**
* Definition node with noise parameters. * Definition node with noise parameters.
*/ */
class DEFINITIONSHARED_EXPORT NoiseNode: public DefinitionNode class DEFINITIONSHARED_EXPORT NoiseNode : public DefinitionNode {
{ public:
public:
NoiseNode(DefinitionNode *parent); NoiseNode(DefinitionNode *parent);
virtual ~NoiseNode(); 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. * 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 save(PackStream *stream) const override;
virtual void load(PackStream *stream) 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; virtual void validate() override;
private: private:
NoiseGenerator *noise; NoiseGenerator *noise;
}; };
} }
} }

View file

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

View file

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

View file

@ -4,13 +4,11 @@
#include "NoiseGenerator.h" #include "NoiseGenerator.h"
#include "PaintedGrid.h" #include "PaintedGrid.h"
PaintedGridBrush::PaintedGridBrush(double hard_radius, double smoothed_size, double 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) : 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; double s = smoothed_size + hard_radius;
*xstart = (int)floor(x - s); *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); *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); double distance = sqrt(dx * dx + dy * dy);
if (distance > hard_radius) if (distance > hard_radius) {
{ if (distance <= hard_radius + smoothed_size) {
if (distance <= hard_radius + smoothed_size)
{
return 1.0 - (distance - hard_radius) / smoothed_size; return 1.0 - (distance - hard_radius) / smoothed_size;
} } else {
else
{
return 0.0; return 0.0;
} }
} } else {
else
{
return 1.0; 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; 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; 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; double ideal, factor;
ideal = grid->getFinalValue((x + total_radius * 0.5), y); ideal = grid->getFinalValue((x + total_radius * 0.5), y);
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 += grid->getFinalValue(x, (y + total_radius * 0.5));
ideal /= 4.0; ideal /= 4.0;
factor = influence * force; factor = influence * force;
if (factor > 1.0) if (factor > 1.0) {
{
factor = 0.0; factor = 0.0;
} }
return basevalue + (ideal - basevalue) * factor; 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; 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); double ideal = grid->getInitialValue(x, y);
return basevalue + (ideal - basevalue) * influence * force; 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; double ideal = target;
return basevalue + (ideal - basevalue) * influence * force; 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. * Base class for brushes that can be used to paint values on a PaintedGrid.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrush {
{ public:
public:
PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius); 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. * 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 hard_radius;
double smoothed_size; double smoothed_size;
double total_radius; double total_radius;
@ -38,57 +38,64 @@ protected:
/** /**
* Brush able to raise or lower the grid value. * Brush able to raise or lower the grid value.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower: public PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower : public PaintedGridBrush {
{ public:
public: PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {} }
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override; 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. * Brush able to smooth the value in an area.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth: public PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth : public PaintedGridBrush {
{ public:
public: PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {} }
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override; double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
}; };
/** /**
* Brush able to add random fractal noise. * Brush able to add random fractal noise.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise: public PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise : public PaintedGridBrush {
{ public:
public: PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator)
PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator) : PaintedGridBrush(brush), generator(generator) {} : PaintedGridBrush(brush), generator(generator) {
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override; }
private: double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
double force) const override;
private:
NoiseGenerator *generator; NoiseGenerator *generator;
}; };
/** /**
* Brush able to reset to initial value. * Brush able to reset to initial value.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrushReset: public PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrushReset : public PaintedGridBrush {
{ public:
public: PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {} }
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override; 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. * Brush able to flatten to a specific value.
*/ */
class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten: public PaintedGridBrush class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten : public PaintedGridBrush {
{ public:
public: PaintedGridBrushFlatten(const PaintedGridBrush &brush, double target) : PaintedGridBrush(brush), target(target) {
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; double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
private: double force) const override;
private:
double target; double target;
}; };
} }
} }

View file

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

View file

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

View file

@ -15,9 +15,7 @@
static const double APP_HEADER = 19866544632.125; static const double APP_HEADER = 19866544632.125;
static const int DATA_VERSION = 1; static const int DATA_VERSION = 1;
Scenery::Scenery(): Scenery::Scenery() : DefinitionNode(NULL, "scenery", "scenery") {
DefinitionNode(NULL, "scenery", "scenery")
{
atmosphere = new AtmosphereDefinition(this); atmosphere = new AtmosphereDefinition(this);
camera = new CameraDefinition(this); camera = new CameraDefinition(this);
clouds = new CloudsDefinition(this); clouds = new CloudsDefinition(this);
@ -26,21 +24,18 @@ Scenery::Scenery():
water = new WaterDefinition(this); water = new WaterDefinition(this);
} }
void Scenery::validate() void Scenery::validate() {
{
DefinitionNode::validate(); DefinitionNode::validate();
keepCameraAboveGround(camera); keepCameraAboveGround(camera);
} }
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const {
{
PackStream stream; PackStream stream;
double app_header = (double)APP_HEADER; double app_header = (double)APP_HEADER;
double version_header = (double)DATA_VERSION; double version_header = (double)DATA_VERSION;
if (not stream.bindToFile(filepath, true)) if (not stream.bindToFile(filepath, true)) {
{
return FILE_OPERATION_IOERROR; return FILE_OPERATION_IOERROR;
} }
@ -56,25 +51,21 @@ Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) co
return FILE_OPERATION_OK; return FILE_OPERATION_OK;
} }
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) {
{
PackStream stream; PackStream stream;
double app_header, version_header; double app_header, version_header;
if (not stream.bindToFile(filepath, false)) if (not stream.bindToFile(filepath, false)) {
{
return FILE_OPERATION_IOERROR; return FILE_OPERATION_IOERROR;
} }
stream.read(&app_header); stream.read(&app_header);
if (app_header != APP_HEADER) if (app_header != APP_HEADER) {
{
return FILE_OPERATION_APP_MISMATCH; return FILE_OPERATION_APP_MISMATCH;
} }
stream.read(&version_header); stream.read(&version_header);
if ((int)version_header != DATA_VERSION) if ((int)version_header != DATA_VERSION) {
{
return FILE_OPERATION_VERSION_MISMATCH; return FILE_OPERATION_VERSION_MISMATCH;
} }
@ -85,14 +76,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
version_header = -1; version_header = -1;
stream.read(&version_header); stream.read(&version_header);
if ((int)version_header != DATA_VERSION) if ((int)version_header != DATA_VERSION) {
{
return FILE_OPERATION_VERSION_MISMATCH; return FILE_OPERATION_VERSION_MISMATCH;
} }
stream.read(&app_header); stream.read(&app_header);
if (app_header != APP_HEADER) if (app_header != APP_HEADER) {
{
return FILE_OPERATION_APP_MISMATCH; return FILE_OPERATION_APP_MISMATCH;
} }
@ -100,15 +89,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
return FILE_OPERATION_OK; return FILE_OPERATION_OK;
} }
Scenery* Scenery::getScenery() Scenery *Scenery::getScenery() {
{
return this; return this;
} }
void Scenery::autoPreset(int seed) void Scenery::autoPreset(int seed) {
{ if (!seed) {
if (!seed)
{
seed = time(NULL); seed = time(NULL);
} }
srand(seed); srand(seed);
@ -127,74 +113,60 @@ void Scenery::autoPreset(int seed)
Logs::debug() << "New scenery generated from seed " << seed << std::endl; Logs::debug() << "New scenery generated from seed " << seed << std::endl;
} }
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere) void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
{
atmosphere->copy(this->atmosphere); atmosphere->copy(this->atmosphere);
} }
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere) void Scenery::getAtmosphere(AtmosphereDefinition *atmosphere) {
{
this->atmosphere->copy(atmosphere); this->atmosphere->copy(atmosphere);
} }
void Scenery::setCamera(CameraDefinition* camera) void Scenery::setCamera(CameraDefinition *camera) {
{
camera->copy(this->camera); camera->copy(this->camera);
keepCameraAboveGround(this->camera); keepCameraAboveGround(this->camera);
} }
void Scenery::getCamera(CameraDefinition* camera) void Scenery::getCamera(CameraDefinition *camera) {
{
this->camera->copy(camera); this->camera->copy(camera);
} }
void Scenery::setClouds(CloudsDefinition* clouds) void Scenery::setClouds(CloudsDefinition *clouds) {
{
clouds->copy(this->clouds); clouds->copy(this->clouds);
} }
void Scenery::getClouds(CloudsDefinition* clouds) void Scenery::getClouds(CloudsDefinition *clouds) {
{
this->clouds->copy(clouds); this->clouds->copy(clouds);
} }
void Scenery::setTerrain(TerrainDefinition* terrain) void Scenery::setTerrain(TerrainDefinition *terrain) {
{
terrain->copy(this->terrain); terrain->copy(this->terrain);
} }
void Scenery::getTerrain(TerrainDefinition* terrain) void Scenery::getTerrain(TerrainDefinition *terrain) {
{
this->terrain->copy(terrain); this->terrain->copy(terrain);
} }
void Scenery::setTextures(TexturesDefinition* textures) void Scenery::setTextures(TexturesDefinition *textures) {
{
textures->copy(this->textures); textures->copy(this->textures);
} }
void Scenery::getTextures(TexturesDefinition* textures) void Scenery::getTextures(TexturesDefinition *textures) {
{
this->textures->copy(textures); this->textures->copy(textures);
} }
void Scenery::setWater(WaterDefinition* water) void Scenery::setWater(WaterDefinition *water) {
{
water->copy(this->water); water->copy(this->water);
} }
void Scenery::getWater(WaterDefinition* water) void Scenery::getWater(WaterDefinition *water) {
{
this->water->copy(water); this->water->copy(water);
} }
void Scenery::keepCameraAboveGround(CameraDefinition* camera) void Scenery::keepCameraAboveGround(CameraDefinition *camera) {
{
Vector3 camera_location = camera->getLocation(); Vector3 camera_location = camera->getLocation();
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 1.0; double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 1.0;
double water_height = 0.5; 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; double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0))); 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. * This class contains the whole scenery definition.
*/ */
class DEFINITIONSHARED_EXPORT Scenery: public DefinitionNode class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
{ public:
public:
typedef enum { typedef enum {
FILE_OPERATION_OK, FILE_OPERATION_OK,
FILE_OPERATION_IOERROR, FILE_OPERATION_IOERROR,
@ -23,9 +22,9 @@ public:
FILE_OPERATION_VERSION_MISMATCH FILE_OPERATION_VERSION_MISMATCH
} FileOperationResult; } FileOperationResult;
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data); typedef void (*SceneryCustomDataCallback)(PackStream *stream, void *data);
public: public:
Scenery(); Scenery();
virtual void validate() override; virtual void validate() override;
@ -33,45 +32,56 @@ public:
FileOperationResult saveGlobal(const std::string &filepath) const; FileOperationResult saveGlobal(const std::string &filepath) const;
FileOperationResult loadGlobal(const std::string &filepath); FileOperationResult loadGlobal(const std::string &filepath);
virtual Scenery* getScenery() override; virtual Scenery *getScenery() override;
void autoPreset(int seed=0); void autoPreset(int seed = 0);
void setAtmosphere(AtmosphereDefinition* atmosphere); void setAtmosphere(AtmosphereDefinition *atmosphere);
inline AtmosphereDefinition* getAtmosphere() const {return atmosphere;} inline AtmosphereDefinition *getAtmosphere() const {
void getAtmosphere(AtmosphereDefinition* atmosphere); return atmosphere;
}
void getAtmosphere(AtmosphereDefinition *atmosphere);
void setCamera(CameraDefinition* camera); void setCamera(CameraDefinition *camera);
inline CameraDefinition* getCamera() const {return camera;} inline CameraDefinition *getCamera() const {
void getCamera(CameraDefinition* camera); return camera;
}
void getCamera(CameraDefinition *camera);
void setClouds(CloudsDefinition* clouds); void setClouds(CloudsDefinition *clouds);
inline CloudsDefinition* getClouds() const {return clouds;} inline CloudsDefinition *getClouds() const {
void getClouds(CloudsDefinition* clouds); return clouds;
}
void getClouds(CloudsDefinition *clouds);
void setTerrain(TerrainDefinition* terrain); void setTerrain(TerrainDefinition *terrain);
inline TerrainDefinition* getTerrain() const {return terrain;} inline TerrainDefinition *getTerrain() const {
void getTerrain(TerrainDefinition* terrain); return terrain;
}
void getTerrain(TerrainDefinition *terrain);
void setTextures(TexturesDefinition* textures); void setTextures(TexturesDefinition *textures);
inline TexturesDefinition* getTextures() const {return textures;} inline TexturesDefinition *getTextures() const {
void getTextures(TexturesDefinition* textures); return textures;
}
void getTextures(TexturesDefinition *textures);
void setWater(WaterDefinition* water); void setWater(WaterDefinition *water);
inline WaterDefinition* getWater() const {return water;} inline WaterDefinition *getWater() const {
void getWater(WaterDefinition* water); return water;
}
void getWater(WaterDefinition *water);
void keepCameraAboveGround(CameraDefinition* camera); void keepCameraAboveGround(CameraDefinition *camera);
private: private:
AtmosphereDefinition* atmosphere; AtmosphereDefinition *atmosphere;
CameraDefinition* camera; CameraDefinition *camera;
CloudsDefinition* clouds; CloudsDefinition *clouds;
TerrainDefinition* terrain; TerrainDefinition *terrain;
TexturesDefinition* textures; TexturesDefinition *textures;
WaterDefinition* water; WaterDefinition *water;
}; };
} }
} }

View file

@ -5,13 +5,10 @@
static SurfaceMaterial DEFAULT; static SurfaceMaterial DEFAULT;
SurfaceMaterial::SurfaceMaterial(): SurfaceMaterial::SurfaceMaterial() : SurfaceMaterial(COLOR_BLACK) {
SurfaceMaterial(COLOR_BLACK)
{
} }
SurfaceMaterial::SurfaceMaterial(const Color &color) SurfaceMaterial::SurfaceMaterial(const Color &color) {
{
base = new Color(color); base = new Color(color);
hardness = 0.5; hardness = 0.5;
reflection = 0.0; reflection = 0.0;
@ -19,26 +16,22 @@ SurfaceMaterial::SurfaceMaterial(const Color &color)
receive_shadows = 1.0; receive_shadows = 1.0;
} }
SurfaceMaterial::~SurfaceMaterial() SurfaceMaterial::~SurfaceMaterial() {
{
delete base; delete base;
} }
const SurfaceMaterial &SurfaceMaterial::getDefault() const SurfaceMaterial &SurfaceMaterial::getDefault() {
{
return DEFAULT; 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->r = r;
base->g = g; base->g = g;
base->b = b; base->b = b;
base->a = a; base->a = a;
} }
void SurfaceMaterial::save(PackStream* stream) const void SurfaceMaterial::save(PackStream *stream) const {
{
base->save(stream); base->save(stream);
stream->write(&hardness); stream->write(&hardness);
@ -48,8 +41,7 @@ void SurfaceMaterial::save(PackStream* stream) const
stream->write(&receive_shadows); stream->write(&receive_shadows);
} }
void SurfaceMaterial::load(PackStream* stream) void SurfaceMaterial::load(PackStream *stream) {
{
base->load(stream); base->load(stream);
stream->read(&hardness); stream->read(&hardness);
@ -59,8 +51,7 @@ void SurfaceMaterial::load(PackStream* stream)
stream->read(&receive_shadows); stream->read(&receive_shadows);
} }
void SurfaceMaterial::copy(SurfaceMaterial *destination) const void SurfaceMaterial::copy(SurfaceMaterial *destination) const {
{
*destination->base = *base; *destination->base = *base;
destination->hardness = hardness; destination->hardness = hardness;
destination->reflection = reflection; destination->reflection = reflection;
@ -69,6 +60,5 @@ void SurfaceMaterial::copy(SurfaceMaterial *destination) const
destination->validate(); destination->validate();
} }
void SurfaceMaterial::validate() void SurfaceMaterial::validate() {
{
} }

View file

@ -6,23 +6,22 @@
namespace paysages { namespace paysages {
namespace definition { namespace definition {
class DEFINITIONSHARED_EXPORT SurfaceMaterial class DEFINITIONSHARED_EXPORT SurfaceMaterial {
{ public:
public:
SurfaceMaterial(); SurfaceMaterial();
SurfaceMaterial(const Color& color); SurfaceMaterial(const Color &color);
~SurfaceMaterial(); ~SurfaceMaterial();
static const SurfaceMaterial &getDefault(); static const SurfaceMaterial &getDefault();
void setColor(double r, double g, double b, double a); void setColor(double r, double g, double b, double a);
void save(PackStream* stream) const; void save(PackStream *stream) const;
void load(PackStream* stream); void load(PackStream *stream);
void copy(SurfaceMaterial *destination) const; void copy(SurfaceMaterial *destination) const;
void validate(); void validate();
public: public:
Color *base; Color *base;
double hardness; double hardness;
@ -31,7 +30,6 @@ public:
double receive_shadows; double receive_shadows;
}; };
} }
} }

View file

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

View file

@ -8,56 +8,52 @@
namespace paysages { namespace paysages {
namespace definition { namespace definition {
typedef struct typedef struct {
{
double min_height; double min_height;
double max_height; double max_height;
double base_height; double base_height;
} HeightInfo; } HeightInfo;
class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode {
{ public:
public: TerrainDefinition(DefinitionNode *parent);
TerrainDefinition(DefinitionNode* parent);
virtual ~TerrainDefinition(); virtual ~TerrainDefinition();
virtual void save(PackStream* stream) const override; virtual void save(PackStream *stream) const override;
virtual void load(PackStream* stream) 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; 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 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; double getWaterOffset() const;
unsigned long getMemoryStats(); unsigned long getMemoryStats();
HeightInfo getHeightInfo(); HeightInfo getHeightInfo();
public: public:
typedef enum typedef enum { TERRAIN_PRESET_STANDARD } TerrainPreset;
{
TERRAIN_PRESET_STANDARD
} TerrainPreset;
void applyPreset(TerrainPreset preset); void applyPreset(TerrainPreset preset);
public: public:
double height; double height;
double shadow_smoothing; double shadow_smoothing;
TerrainHeightMap* height_map; TerrainHeightMap *height_map;
bool has_painting; bool has_painting;
double _detail; double _detail;
NoiseGenerator* _height_noise; NoiseGenerator *_height_noise;
double _min_height; double _min_height;
double _max_height; double _max_height;
private: private:
FloatNode *water_height; FloatNode *water_height;
}; };
} }
} }

View file

@ -3,64 +3,55 @@
#include "TerrainDefinition.h" #include "TerrainDefinition.h"
#include "PaintedGridBrush.h" #include "PaintedGridBrush.h"
TerrainHeightMap::TerrainHeightMap(TerrainDefinition* terrain): TerrainHeightMap::TerrainHeightMap(TerrainDefinition *terrain) : PaintedGrid(terrain), terrain(terrain) {
PaintedGrid(terrain), terrain(terrain)
{
} }
void TerrainHeightMap::copy(DefinitionNode* _destination) const void TerrainHeightMap::copy(DefinitionNode *_destination) const {
{ TerrainHeightMap *destination = (TerrainHeightMap *)_destination;
TerrainHeightMap* destination = (TerrainHeightMap*)_destination;
destination->terrain = terrain; destination->terrain = terrain;
PaintedGrid::copy(destination); 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); 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); PaintedGridBrushRaiseLower sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit); 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); PaintedGridBrushFlatten sbrush(brush, height);
applyBrush(sbrush, x, y, force / terrain->height, commit); 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); PaintedGridBrushSmooth sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit); 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); PaintedGridBrushAddNoise sbrush(brush, generator);
applyBrush(sbrush, x, y, value / terrain->height, commit); 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); PaintedGridBrushReset sbrush(brush);
applyBrush(sbrush, x, y, value / terrain->height, commit); applyBrush(sbrush, x, y, value / terrain->height, commit);
} }
void TerrainHeightMap::clearPainting() void TerrainHeightMap::clearPainting() {
{
PaintedGrid::clearPainting(); PaintedGrid::clearPainting();
terrain->validate(); terrain->validate();
} }
void TerrainHeightMap::endBrushStroke() void TerrainHeightMap::endBrushStroke() {
{
PaintedGrid::endBrushStroke(); PaintedGrid::endBrushStroke();
terrain->validate(); terrain->validate();

View file

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

View file

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

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