Enforced coding style using clang-format
This commit is contained in:
parent
d82fc73531
commit
88d2a78b70
314 changed files with 5150 additions and 7810 deletions
3
Makefile
3
Makefile
|
@ -7,6 +7,9 @@ PATH:=${QTSDK}/bin:${PATH}
|
|||
|
||||
all:build
|
||||
|
||||
format:
|
||||
find src \( \( -name '*.cpp' -or -name '*.h' \) -and \! -path '*/googletest/*' \) -exec clang-format -i \{\} \;
|
||||
|
||||
dirs:
|
||||
mkdir -p ${BUILDPATH}
|
||||
|
||||
|
|
6
src/.clang-format
Normal file
6
src/.clang-format
Normal file
|
@ -0,0 +1,6 @@
|
|||
BasedOnStyle: LLVM
|
||||
IndentWidth: 4
|
||||
ColumnLimit: 120
|
||||
AllowShortFunctionsOnASingleLine: false
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
|
@ -2,13 +2,11 @@
|
|||
|
||||
#include "Vector3.h"
|
||||
|
||||
BoundingBox::BoundingBox()
|
||||
{
|
||||
BoundingBox::BoundingBox() {
|
||||
reset();
|
||||
}
|
||||
|
||||
void BoundingBox::reset()
|
||||
{
|
||||
void BoundingBox::reset() {
|
||||
empty = 1;
|
||||
xmin = 10000000000.0;
|
||||
xmax = -10000000000.0;
|
||||
|
@ -18,31 +16,24 @@ void BoundingBox::reset()
|
|||
zmax = -10000000000.0;
|
||||
}
|
||||
|
||||
void BoundingBox::pushPoint(const Vector3 &point)
|
||||
{
|
||||
void BoundingBox::pushPoint(const Vector3 &point) {
|
||||
empty = 0;
|
||||
if (point.x < xmin)
|
||||
{
|
||||
if (point.x < xmin) {
|
||||
xmin = point.x;
|
||||
}
|
||||
if (point.x > xmax)
|
||||
{
|
||||
if (point.x > xmax) {
|
||||
xmax = point.x;
|
||||
}
|
||||
if (point.y < ymin)
|
||||
{
|
||||
if (point.y < ymin) {
|
||||
ymin = point.y;
|
||||
}
|
||||
if (point.y > ymax)
|
||||
{
|
||||
if (point.y > ymax) {
|
||||
ymax = point.y;
|
||||
}
|
||||
if (point.z < zmin)
|
||||
{
|
||||
if (point.z < zmin) {
|
||||
zmin = point.z;
|
||||
}
|
||||
if (point.z > zmax)
|
||||
{
|
||||
if (point.z > zmax) {
|
||||
zmax = point.z;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT BoundingBox
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT BoundingBox {
|
||||
public:
|
||||
BoundingBox();
|
||||
|
||||
void reset();
|
||||
void pushPoint(const Vector3 &point);
|
||||
|
||||
public:
|
||||
public:
|
||||
int empty;
|
||||
double xmin;
|
||||
double xmax;
|
||||
|
@ -23,7 +22,6 @@ public:
|
|||
double zmin;
|
||||
double zmax;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,77 +3,56 @@
|
|||
#include "Vector3.h"
|
||||
#include "PackStream.h"
|
||||
|
||||
CappedCylinder::CappedCylinder()
|
||||
{
|
||||
CappedCylinder::CappedCylinder() {
|
||||
}
|
||||
|
||||
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length):
|
||||
InfiniteCylinder(InfiniteRay(base, direction), radius), length(length)
|
||||
{
|
||||
CappedCylinder::CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length)
|
||||
: InfiniteCylinder(InfiniteRay(base, direction), radius), length(length) {
|
||||
}
|
||||
|
||||
int CappedCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
|
||||
{
|
||||
int CappedCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
|
||||
Vector3 *second_intersection) const {
|
||||
// TODO Apply the caps
|
||||
int count = InfiniteCylinder::checkRayIntersection(ray, first_intersection, second_intersection);
|
||||
|
||||
if (count == 0)
|
||||
{
|
||||
if (count == 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (count == 2)
|
||||
{
|
||||
if (checkPointProjection(first_intersection))
|
||||
{
|
||||
if (checkPointProjection(second_intersection))
|
||||
{
|
||||
} else if (count == 2) {
|
||||
if (checkPointProjection(first_intersection)) {
|
||||
if (checkPointProjection(second_intersection)) {
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (checkPointProjection(second_intersection))
|
||||
{
|
||||
} else {
|
||||
if (checkPointProjection(second_intersection)) {
|
||||
*first_intersection = *second_intersection;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
else // count == 1
|
||||
} else // count == 1
|
||||
{
|
||||
if (checkPointProjection(first_intersection))
|
||||
{
|
||||
if (checkPointProjection(first_intersection)) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool CappedCylinder::checkPointProjection(Vector3 *point) const
|
||||
{
|
||||
bool CappedCylinder::checkPointProjection(Vector3 *point) const {
|
||||
double proj_length = axis.getDirection().dotProduct(point->sub(axis.getOrigin()));
|
||||
return 0.0 <= proj_length && proj_length <= length;
|
||||
}
|
||||
|
||||
void CappedCylinder::save(PackStream *stream) const
|
||||
{
|
||||
void CappedCylinder::save(PackStream *stream) const {
|
||||
InfiniteCylinder::save(stream);
|
||||
stream->write(&length);
|
||||
}
|
||||
|
||||
void CappedCylinder::load(PackStream *stream)
|
||||
{
|
||||
void CappedCylinder::load(PackStream *stream) {
|
||||
InfiniteCylinder::load(stream);
|
||||
stream->read(&length);
|
||||
}
|
||||
|
|
|
@ -11,13 +11,14 @@ namespace basics {
|
|||
/**
|
||||
* Geometric cylinder, with capped ends (not infinite).
|
||||
*/
|
||||
class BASICSSHARED_EXPORT CappedCylinder: public InfiniteCylinder
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT CappedCylinder : public InfiniteCylinder {
|
||||
public:
|
||||
CappedCylinder();
|
||||
CappedCylinder(const Vector3 &base, const Vector3 &direction, double radius, double length);
|
||||
|
||||
inline double getLength() const {return length;}
|
||||
inline double getLength() const {
|
||||
return length;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the intersection between the cylinder and an infinite ray.
|
||||
|
@ -32,10 +33,9 @@ public:
|
|||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
double length;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -11,16 +11,14 @@ const Color paysages::basics::COLOR_BLUE = {0.0, 0.0, 1.0, 1.0};
|
|||
const Color paysages::basics::COLOR_WHITE = {1.0, 1.0, 1.0, 1.0};
|
||||
const Color paysages::basics::COLOR_GREY = {0.5, 0.5, 0.5, 1.0};
|
||||
|
||||
void Color::save(PackStream* stream) const
|
||||
{
|
||||
void Color::save(PackStream *stream) const {
|
||||
stream->write(&r);
|
||||
stream->write(&g);
|
||||
stream->write(&b);
|
||||
stream->write(&a);
|
||||
}
|
||||
|
||||
void Color::load(PackStream* stream)
|
||||
{
|
||||
void Color::load(PackStream *stream) {
|
||||
stream->read(&r);
|
||||
stream->read(&g);
|
||||
stream->read(&b);
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Color
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Color {
|
||||
public:
|
||||
Color() = default;
|
||||
Color(const Color &col);
|
||||
Color(double r, double g, double b, double a=1.0);
|
||||
Color(double r, double g, double b, double a = 1.0);
|
||||
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
|
||||
unsigned int to32BitRGBA() const;
|
||||
unsigned int to32BitBGRA() const;
|
||||
|
@ -26,16 +25,16 @@ public:
|
|||
static Color from32BitARGB(unsigned int col);
|
||||
static Color from32BitABGR(unsigned int col);
|
||||
|
||||
void mask(const Color& mask);
|
||||
void mask(const Color &mask);
|
||||
double normalize();
|
||||
double getValue() const;
|
||||
double getPower() const;
|
||||
void limitPower(double max_power);
|
||||
|
||||
Color add(const Color& other) const;
|
||||
Color lerp(const Color& other, double f) const;
|
||||
Color add(const Color &other) const;
|
||||
Color lerp(const Color &other, double f) const;
|
||||
|
||||
public:
|
||||
public:
|
||||
double r;
|
||||
double g;
|
||||
double b;
|
||||
|
@ -49,7 +48,6 @@ BASICSSHARED_EXPORT extern const Color COLOR_GREEN;
|
|||
BASICSSHARED_EXPORT extern const Color COLOR_BLUE;
|
||||
BASICSSHARED_EXPORT extern const Color COLOR_WHITE;
|
||||
BASICSSHARED_EXPORT extern const Color COLOR_GREY;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,84 +6,59 @@
|
|||
#endif
|
||||
|
||||
#ifdef COLOR_H
|
||||
# define METHSPEC inline
|
||||
#define METHSPEC inline
|
||||
#else
|
||||
# include "Color.h"
|
||||
# define METHSPEC
|
||||
#include "Color.h"
|
||||
#define METHSPEC
|
||||
#endif
|
||||
|
||||
METHSPEC Color::Color(double r, double g, double b, double a):
|
||||
r(r), g(g), b(b), a(a)
|
||||
{
|
||||
METHSPEC Color::Color(double r, double g, double b, double a) : r(r), g(g), b(b), a(a) {
|
||||
}
|
||||
|
||||
METHSPEC Color::Color(const Color &col):
|
||||
r(col.r), g(col.g), b(col.b), a(col.a)
|
||||
{
|
||||
METHSPEC Color::Color(const Color &col) : r(col.r), g(col.g), b(col.b), a(col.a) {
|
||||
}
|
||||
|
||||
METHSPEC unsigned int Color::to32BitRGBA() const
|
||||
{
|
||||
return (((unsigned int) (a * 255.0)) << 24) | (((unsigned int) (b * 255.0)) << 16) | (((unsigned int) (g * 255.0)) << 8) | ((unsigned int) (r * 255.0));
|
||||
METHSPEC unsigned int Color::to32BitRGBA() const {
|
||||
return (((unsigned int)(a * 255.0)) << 24) | (((unsigned int)(b * 255.0)) << 16) |
|
||||
(((unsigned int)(g * 255.0)) << 8) | ((unsigned int)(r * 255.0));
|
||||
}
|
||||
|
||||
METHSPEC unsigned int Color::to32BitBGRA() const
|
||||
{
|
||||
return (((unsigned int) (a * 255.0)) << 24) | (((unsigned int) (r * 255.0)) << 16) | (((unsigned int) (g * 255.0)) << 8) | ((unsigned int) (b * 255.0));
|
||||
METHSPEC unsigned int Color::to32BitBGRA() const {
|
||||
return (((unsigned int)(a * 255.0)) << 24) | (((unsigned int)(r * 255.0)) << 16) |
|
||||
(((unsigned int)(g * 255.0)) << 8) | ((unsigned int)(b * 255.0));
|
||||
}
|
||||
|
||||
METHSPEC unsigned int Color::to32BitARGB() const
|
||||
{
|
||||
return (((unsigned int) (b * 255.0)) << 24) | (((unsigned int) (g * 255.0)) << 16) | (((unsigned int) (r * 255.0)) << 8) | ((unsigned int) (a * 255.0));
|
||||
METHSPEC unsigned int Color::to32BitARGB() const {
|
||||
return (((unsigned int)(b * 255.0)) << 24) | (((unsigned int)(g * 255.0)) << 16) |
|
||||
(((unsigned int)(r * 255.0)) << 8) | ((unsigned int)(a * 255.0));
|
||||
}
|
||||
|
||||
METHSPEC unsigned int Color::to32BitABGR() const
|
||||
{
|
||||
return (((unsigned int) (r * 255.0)) << 24) | (((unsigned int) (g * 255.0)) << 16) | (((unsigned int) (b * 255.0)) << 8) | ((unsigned int) (a * 255.0));
|
||||
METHSPEC unsigned int Color::to32BitABGR() const {
|
||||
return (((unsigned int)(r * 255.0)) << 24) | (((unsigned int)(g * 255.0)) << 16) |
|
||||
(((unsigned int)(b * 255.0)) << 8) | ((unsigned int)(a * 255.0));
|
||||
}
|
||||
|
||||
METHSPEC Color Color::from32BitRGBA(unsigned int col)
|
||||
{
|
||||
return Color(
|
||||
((double) (col & 0x000000FF)) / 255.0,
|
||||
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
|
||||
((double) ((col & 0xFF000000) >> 24)) / 255.0
|
||||
);
|
||||
METHSPEC Color Color::from32BitRGBA(unsigned int col) {
|
||||
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
|
||||
}
|
||||
|
||||
METHSPEC Color Color::from32BitBGRA(unsigned int col)
|
||||
{
|
||||
return Color(
|
||||
((double) (col & 0x000000FF)) / 255.0,
|
||||
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
|
||||
((double) ((col & 0xFF000000) >> 24)) / 255.0
|
||||
);
|
||||
METHSPEC Color Color::from32BitBGRA(unsigned int col) {
|
||||
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
|
||||
}
|
||||
|
||||
METHSPEC Color Color::from32BitARGB(unsigned int col)
|
||||
{
|
||||
return Color(
|
||||
((double) (col & 0x000000FF)) / 255.0,
|
||||
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
|
||||
((double) ((col & 0xFF000000) >> 24)) / 255.0
|
||||
);
|
||||
METHSPEC Color Color::from32BitARGB(unsigned int col) {
|
||||
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
|
||||
}
|
||||
|
||||
METHSPEC Color Color::from32BitABGR(unsigned int col)
|
||||
{
|
||||
return Color(
|
||||
((double) (col & 0x000000FF)) / 255.0,
|
||||
((double) ((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double) ((col & 0x00FF0000) >> 16)) / 255.0,
|
||||
((double) ((col & 0xFF000000) >> 24)) / 255.0
|
||||
);
|
||||
METHSPEC Color Color::from32BitABGR(unsigned int col) {
|
||||
return Color(((double)(col & 0x000000FF)) / 255.0, ((double)((col & 0x0000FF00) >> 8)) / 255.0,
|
||||
((double)((col & 0x00FF0000) >> 16)) / 255.0, ((double)((col & 0xFF000000) >> 24)) / 255.0);
|
||||
}
|
||||
|
||||
METHSPEC void Color::mask(const Color& mask)
|
||||
{
|
||||
METHSPEC void Color::mask(const Color &mask) {
|
||||
double new_a;
|
||||
new_a = a + mask.a - (a * mask.a);
|
||||
r = (mask.r * mask.a + r * a - r * a * mask.a) / new_a;
|
||||
|
@ -100,8 +75,7 @@ METHSPEC void Color::mask(const Color& mask)
|
|||
base->a = base->a + mask_weight * (1.0 - base->a);*/
|
||||
}
|
||||
|
||||
METHSPEC double Color::normalize()
|
||||
{
|
||||
METHSPEC double Color::normalize() {
|
||||
#ifndef NDEBUG
|
||||
assert(r >= 0.0);
|
||||
assert(g >= 0.0);
|
||||
|
@ -121,16 +95,13 @@ METHSPEC double Color::normalize()
|
|||
#endif
|
||||
#endif
|
||||
|
||||
if (r > 1.0)
|
||||
{
|
||||
if (r > 1.0) {
|
||||
r = 1.0;
|
||||
}
|
||||
if (g > 1.0)
|
||||
{
|
||||
if (g > 1.0) {
|
||||
g = 1.0;
|
||||
}
|
||||
if (b > 1.0)
|
||||
{
|
||||
if (b > 1.0) {
|
||||
b = 1.0;
|
||||
}
|
||||
return 1.0;
|
||||
|
@ -147,33 +118,27 @@ METHSPEC double Color::normalize()
|
|||
return max;*/
|
||||
}
|
||||
|
||||
METHSPEC double Color::getValue() const
|
||||
{
|
||||
METHSPEC double Color::getValue() const {
|
||||
double max;
|
||||
|
||||
max = r;
|
||||
if (g > max)
|
||||
{
|
||||
if (g > max) {
|
||||
max = g;
|
||||
}
|
||||
if (b > max)
|
||||
{
|
||||
if (b > max) {
|
||||
max = b;
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
METHSPEC double Color::getPower() const
|
||||
{
|
||||
METHSPEC double Color::getPower() const {
|
||||
return r + g + b;
|
||||
}
|
||||
|
||||
METHSPEC void Color::limitPower(double max_power)
|
||||
{
|
||||
METHSPEC void Color::limitPower(double max_power) {
|
||||
double power = r + g + b;
|
||||
|
||||
if (power > max_power)
|
||||
{
|
||||
if (power > max_power) {
|
||||
double factor = max_power / power;
|
||||
|
||||
r *= factor;
|
||||
|
@ -182,18 +147,12 @@ METHSPEC void Color::limitPower(double max_power)
|
|||
}
|
||||
}
|
||||
|
||||
METHSPEC Color Color::add(const Color& other) const
|
||||
{
|
||||
METHSPEC Color Color::add(const Color &other) const {
|
||||
return Color(r + other.r, g + other.g, b + other.b, a);
|
||||
}
|
||||
|
||||
METHSPEC Color Color::lerp(const Color& other, double f) const
|
||||
{
|
||||
Color result(
|
||||
r * (1.0 - f) + other.r * f,
|
||||
g * (1.0 - f) + other.g * f,
|
||||
b * (1.0 - f) + other.b * f,
|
||||
a * (1.0 - f) + other.a * f
|
||||
);
|
||||
METHSPEC Color Color::lerp(const Color &other, double f) const {
|
||||
Color result(r * (1.0 - f) + other.r * f, g * (1.0 - f) + other.g * f, b * (1.0 - f) + other.b * f,
|
||||
a * (1.0 - f) + other.a * f);
|
||||
return result;
|
||||
}
|
||||
|
|
|
@ -2,26 +2,26 @@
|
|||
|
||||
#include "Color.h"
|
||||
|
||||
static inline double _hue2rgb(double p, double q, double t)
|
||||
{
|
||||
if (t < 0.0) t += 1;
|
||||
if (t > 1.0) t -= 1;
|
||||
if (t < 1.0 / 6.0) return p + (q - p) * 6.0 * t;
|
||||
if (t < 1.0 / 2.0) return q;
|
||||
if (t < 2.0 / 3.0) return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
|
||||
static inline double _hue2rgb(double p, double q, double t) {
|
||||
if (t < 0.0)
|
||||
t += 1;
|
||||
if (t > 1.0)
|
||||
t -= 1;
|
||||
if (t < 1.0 / 6.0)
|
||||
return p + (q - p) * 6.0 * t;
|
||||
if (t < 1.0 / 2.0)
|
||||
return q;
|
||||
if (t < 2.0 / 3.0)
|
||||
return p + (q - p) * (2.0 / 3.0 - t) * 6.0;
|
||||
return p;
|
||||
}
|
||||
|
||||
Color colorFromHSL(const ColorHSL &col)
|
||||
{
|
||||
Color colorFromHSL(const ColorHSL &col) {
|
||||
Color result;
|
||||
|
||||
if (col.s == 0)
|
||||
{
|
||||
if (col.s == 0) {
|
||||
result.r = result.g = result.b = col.l;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
double q = col.l < 0.5 ? col.l * (1.0 + col.s) : col.l + col.s - col.l * col.s;
|
||||
double p = 2 * col.l - q;
|
||||
result.r = _hue2rgb(p, q, col.h + 1.0 / 3.0);
|
||||
|
@ -34,8 +34,7 @@ Color colorFromHSL(const ColorHSL &col)
|
|||
return result;
|
||||
}
|
||||
|
||||
ColorHSL colorToHSL(const Color &col)
|
||||
{
|
||||
ColorHSL colorToHSL(const Color &col) {
|
||||
ColorHSL result;
|
||||
double min, max;
|
||||
|
||||
|
@ -47,24 +46,16 @@ ColorHSL colorToHSL(const Color &col)
|
|||
|
||||
result.h = result.s = result.l = (max + min) / 2.0;
|
||||
|
||||
if (max == min)
|
||||
{
|
||||
if (max == min) {
|
||||
result.h = result.s = 0.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
double d = max - min;
|
||||
result.s = result.l > 0.5 ? d / (2.0 - max - min) : d / (max + min);
|
||||
if (max == col.r)
|
||||
{
|
||||
if (max == col.r) {
|
||||
result.h = (col.g - col.b) / d + (col.g < col.b ? 6.0 : 0);
|
||||
}
|
||||
else if (max == col.g)
|
||||
{
|
||||
} else if (max == col.g) {
|
||||
result.h = (col.b - col.r) / d + 2.0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
result.h = (col.r - col.g) / d + 4.0;
|
||||
}
|
||||
result.h /= 6.0;
|
||||
|
@ -75,8 +66,7 @@ ColorHSL colorToHSL(const Color &col)
|
|||
return result;
|
||||
}
|
||||
|
||||
ColorHSL colorHSLFromValues(double h, double s, double l, double a)
|
||||
{
|
||||
ColorHSL colorHSLFromValues(double h, double s, double l, double a) {
|
||||
ColorHSL result;
|
||||
|
||||
result.h = h;
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
|
||||
#include "basics_global.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double h;
|
||||
double s;
|
||||
double l;
|
||||
|
|
|
@ -2,18 +2,15 @@
|
|||
|
||||
#include "PackStream.h"
|
||||
|
||||
ColorProfile::ColorProfile()
|
||||
{
|
||||
ColorProfile::ColorProfile() {
|
||||
setToneMapping(TONE_MAPPING_UNCHARTED, 1.6);
|
||||
}
|
||||
|
||||
ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure)
|
||||
{
|
||||
ColorProfile::ColorProfile(ToneMappingOperator tonemapper, double exposure) {
|
||||
setToneMapping(tonemapper, exposure);
|
||||
}
|
||||
|
||||
static inline double _uncharted2Tonemap(double x)
|
||||
{
|
||||
static inline double _uncharted2Tonemap(double x) {
|
||||
double A = 0.15;
|
||||
double B = 0.50;
|
||||
double C = 0.10;
|
||||
|
@ -24,61 +21,43 @@ static inline double _uncharted2Tonemap(double x)
|
|||
return ((x * (A * x + C * B) + D * E) / (x * (A * x + B) + D * F)) - E / F;
|
||||
}
|
||||
|
||||
static inline Color _toneMappingUncharted(const Color &pixel, double exposure)
|
||||
{
|
||||
static inline Color _toneMappingUncharted(const Color &pixel, double exposure) {
|
||||
static const double W = 11.2;
|
||||
static const double white_scale = 1.0 / _uncharted2Tonemap(W);
|
||||
static const double factor = 1.0 / 2.2;
|
||||
|
||||
Color result(
|
||||
pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, factor),
|
||||
pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, factor),
|
||||
pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, factor),
|
||||
pixel.a
|
||||
);
|
||||
Color result(pow(_uncharted2Tonemap(pixel.r * exposure) * white_scale, factor),
|
||||
pow(_uncharted2Tonemap(pixel.g * exposure) * white_scale, factor),
|
||||
pow(_uncharted2Tonemap(pixel.b * exposure) * white_scale, factor), pixel.a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline Color _toneMappingReinhard(const Color &pixel, double exposure)
|
||||
{
|
||||
Color result(
|
||||
(pixel.r * exposure) / (1.0 + pixel.r * exposure),
|
||||
(pixel.g * exposure) / (1.0 + pixel.g * exposure),
|
||||
(pixel.b * exposure) / (1.0 + pixel.b * exposure),
|
||||
pixel.a
|
||||
);
|
||||
static inline Color _toneMappingReinhard(const Color &pixel, double exposure) {
|
||||
Color result((pixel.r * exposure) / (1.0 + pixel.r * exposure), (pixel.g * exposure) / (1.0 + pixel.g * exposure),
|
||||
(pixel.b * exposure) / (1.0 + pixel.b * exposure), pixel.a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline Color _toneMappingClamp(const Color &pixel)
|
||||
{
|
||||
Color result(
|
||||
pixel.r > 1.0 ? 1.0 : pixel.r,
|
||||
pixel.g > 1.0 ? 1.0 : pixel.g,
|
||||
pixel.b > 1.0 ? 1.0 : pixel.b,
|
||||
pixel.a
|
||||
);
|
||||
static inline Color _toneMappingClamp(const Color &pixel) {
|
||||
Color result(pixel.r > 1.0 ? 1.0 : pixel.r, pixel.g > 1.0 ? 1.0 : pixel.g, pixel.b > 1.0 ? 1.0 : pixel.b, pixel.a);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void ColorProfile::setToneMapping(ToneMappingOperator tonemapper, double exposure)
|
||||
{
|
||||
void ColorProfile::setToneMapping(ToneMappingOperator tonemapper, double exposure) {
|
||||
this->mapper = tonemapper;
|
||||
this->exposure = exposure;
|
||||
}
|
||||
|
||||
void ColorProfile::save(PackStream* stream) const
|
||||
{
|
||||
void ColorProfile::save(PackStream *stream) const {
|
||||
int imapper = (int)mapper;
|
||||
stream->write(&imapper);
|
||||
stream->write(&exposure);
|
||||
}
|
||||
|
||||
void ColorProfile::load(PackStream* stream)
|
||||
{
|
||||
void ColorProfile::load(PackStream *stream) {
|
||||
int imapper = (int)mapper;
|
||||
stream->read(&imapper);
|
||||
stream->read(&exposure);
|
||||
|
@ -86,16 +65,13 @@ void ColorProfile::load(PackStream* stream)
|
|||
mapper = (ToneMappingOperator)imapper;
|
||||
}
|
||||
|
||||
void ColorProfile::copy(ColorProfile* destination) const
|
||||
{
|
||||
void ColorProfile::copy(ColorProfile *destination) const {
|
||||
destination->mapper = mapper;
|
||||
destination->exposure = exposure;
|
||||
}
|
||||
|
||||
Color ColorProfile::apply(const Color &pixel) const
|
||||
{
|
||||
switch (mapper)
|
||||
{
|
||||
Color ColorProfile::apply(const Color &pixel) const {
|
||||
switch (mapper) {
|
||||
case TONE_MAPPING_REIHNARD:
|
||||
return _toneMappingReinhard(pixel, exposure);
|
||||
case TONE_MAPPING_UNCHARTED:
|
||||
|
|
|
@ -8,33 +8,26 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT ColorProfile
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
TONE_MAPPING_UNCHARTED,
|
||||
TONE_MAPPING_REIHNARD,
|
||||
TONE_MAPPING_CLAMP
|
||||
} ToneMappingOperator;
|
||||
class BASICSSHARED_EXPORT ColorProfile {
|
||||
public:
|
||||
typedef enum { TONE_MAPPING_UNCHARTED, TONE_MAPPING_REIHNARD, TONE_MAPPING_CLAMP } ToneMappingOperator;
|
||||
|
||||
public:
|
||||
public:
|
||||
ColorProfile();
|
||||
ColorProfile(ToneMappingOperator tonemapper, double exposure);
|
||||
|
||||
void setToneMapping(ToneMappingOperator tonemapper, double exposure);
|
||||
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void copy(ColorProfile* destination) const;
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void copy(ColorProfile *destination) const;
|
||||
|
||||
Color apply(const Color &pixel) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
ToneMappingOperator mapper;
|
||||
double exposure;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,167 +5,123 @@
|
|||
|
||||
const int MAX_NB_POINTS = 30;
|
||||
|
||||
Curve::Curve()
|
||||
{
|
||||
Curve::Curve() {
|
||||
nbpoints = 0;
|
||||
default_value = 0.0;
|
||||
points = new CurvePoint[MAX_NB_POINTS];
|
||||
}
|
||||
|
||||
Curve::~Curve()
|
||||
{
|
||||
Curve::~Curve() {
|
||||
delete[] points;
|
||||
}
|
||||
|
||||
void Curve::copy(Curve* destination) const
|
||||
{
|
||||
void Curve::copy(Curve *destination) const {
|
||||
destination->nbpoints = nbpoints;
|
||||
destination->default_value = default_value;
|
||||
for (int i = 0; i < nbpoints; i++)
|
||||
{
|
||||
for (int i = 0; i < nbpoints; i++) {
|
||||
destination->points[i] = points[i];
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::save(PackStream* stream) const
|
||||
{
|
||||
void Curve::save(PackStream *stream) const {
|
||||
stream->write(&default_value);
|
||||
stream->write(&nbpoints);
|
||||
for (int i = 0; i < nbpoints; i++)
|
||||
{
|
||||
for (int i = 0; i < nbpoints; i++) {
|
||||
stream->write(&points[i].position);
|
||||
stream->write(&points[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::load(PackStream* stream)
|
||||
{
|
||||
void Curve::load(PackStream *stream) {
|
||||
stream->read(&default_value);
|
||||
stream->read(&nbpoints);
|
||||
for (int i = 0; i < nbpoints; i++)
|
||||
{
|
||||
for (int i = 0; i < nbpoints; i++) {
|
||||
stream->read(&points[i].position);
|
||||
stream->read(&points[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::clear()
|
||||
{
|
||||
void Curve::clear() {
|
||||
nbpoints = 0;
|
||||
}
|
||||
|
||||
void Curve::setDefault(double value)
|
||||
{
|
||||
void Curve::setDefault(double value) {
|
||||
default_value = value;
|
||||
}
|
||||
|
||||
int Curve::addPoint(const CurvePoint &point)
|
||||
{
|
||||
if (nbpoints < MAX_NB_POINTS)
|
||||
{
|
||||
int Curve::addPoint(const CurvePoint &point) {
|
||||
if (nbpoints < MAX_NB_POINTS) {
|
||||
points[nbpoints] = point;
|
||||
return nbpoints++;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int Curve::addPoint(double position, double value)
|
||||
{
|
||||
int Curve::addPoint(double position, double value) {
|
||||
CurvePoint point = {position, value};
|
||||
return addPoint(point);
|
||||
}
|
||||
|
||||
CurvePoint Curve::getPoint(int number) const
|
||||
{
|
||||
if (number >= 0 && number < nbpoints)
|
||||
{
|
||||
CurvePoint Curve::getPoint(int number) const {
|
||||
if (number >= 0 && number < nbpoints) {
|
||||
return points[number];
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return {0.0, 0.0};
|
||||
}
|
||||
}
|
||||
|
||||
bool Curve::getPoint(int number, CurvePoint *point) const
|
||||
{
|
||||
if (number >= 0 && number < nbpoints)
|
||||
{
|
||||
bool Curve::getPoint(int number, CurvePoint *point) const {
|
||||
if (number >= 0 && number < nbpoints) {
|
||||
*point = points[number];
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::setPoint(int number, const CurvePoint &point)
|
||||
{
|
||||
if (number >= 0 && number < nbpoints)
|
||||
{
|
||||
void Curve::setPoint(int number, const CurvePoint &point) {
|
||||
if (number >= 0 && number < nbpoints) {
|
||||
points[number] = point;
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::removePoint(int number)
|
||||
{
|
||||
if (number >= 0 && number < nbpoints)
|
||||
{
|
||||
if (nbpoints > 0 && number < nbpoints - 1)
|
||||
{
|
||||
void Curve::removePoint(int number) {
|
||||
if (number >= 0 && number < nbpoints) {
|
||||
if (nbpoints > 0 && number < nbpoints - 1) {
|
||||
memmove(points + number, points + number + 1, sizeof(CurvePoint) * (nbpoints - number - 1));
|
||||
}
|
||||
nbpoints--;
|
||||
}
|
||||
}
|
||||
|
||||
int _point_compare(const void* part1, const void* part2)
|
||||
{
|
||||
if (((CurvePoint*)part1)->position > ((CurvePoint*)part2)->position)
|
||||
{
|
||||
int _point_compare(const void *part1, const void *part2) {
|
||||
if (((CurvePoint *)part1)->position > ((CurvePoint *)part2)->position) {
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
void Curve::validate()
|
||||
{
|
||||
if (nbpoints > 1)
|
||||
{
|
||||
void Curve::validate() {
|
||||
if (nbpoints > 1) {
|
||||
qsort(points, nbpoints, sizeof(CurvePoint), _point_compare);
|
||||
}
|
||||
}
|
||||
|
||||
double Curve::getValue(double position) const
|
||||
{
|
||||
double Curve::getValue(double position) const {
|
||||
int i;
|
||||
double fact;
|
||||
|
||||
if (nbpoints == 0)
|
||||
{
|
||||
if (nbpoints == 0) {
|
||||
return default_value;
|
||||
}
|
||||
else if (nbpoints == 1 || position <= points[0].position)
|
||||
{
|
||||
} else if (nbpoints == 1 || position <= points[0].position) {
|
||||
return points[0].value;
|
||||
}
|
||||
else if (position >= points[nbpoints - 1].position)
|
||||
{
|
||||
} else if (position >= points[nbpoints - 1].position) {
|
||||
return points[nbpoints - 1].value;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i = 1; i < nbpoints; i++)
|
||||
{
|
||||
if (position < points[i].position)
|
||||
{
|
||||
} else {
|
||||
for (i = 1; i < nbpoints; i++) {
|
||||
if (position < points[i].position) {
|
||||
fact = (position - points[i - 1].position) / (points[i].position - points[i - 1].position);
|
||||
return points[i - 1].value + (points[i].value - points[i - 1].value) * fact;
|
||||
}
|
||||
|
|
|
@ -11,18 +11,19 @@ typedef struct {
|
|||
double value;
|
||||
} CurvePoint;
|
||||
|
||||
class BASICSSHARED_EXPORT Curve
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Curve {
|
||||
public:
|
||||
Curve();
|
||||
~Curve();
|
||||
|
||||
void copy(Curve* destination) const;
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void copy(Curve *destination) const;
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void validate();
|
||||
|
||||
inline int getPointCount() const {return nbpoints;}
|
||||
inline int getPointCount() const {
|
||||
return nbpoints;
|
||||
}
|
||||
CurvePoint getPoint(int number) const;
|
||||
bool getPoint(int number, CurvePoint *point) const;
|
||||
|
||||
|
@ -35,12 +36,11 @@ public:
|
|||
void setPoint(int number, const CurvePoint &point);
|
||||
void removePoint(int number);
|
||||
|
||||
private:
|
||||
private:
|
||||
double default_value;
|
||||
int nbpoints;
|
||||
CurvePoint* points;
|
||||
CurvePoint *points;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,41 +2,32 @@
|
|||
|
||||
#include "PackStream.h"
|
||||
|
||||
Disk::Disk()
|
||||
{
|
||||
Disk::Disk() {
|
||||
}
|
||||
|
||||
Disk::Disk(const Vector3 &point, const Vector3 &normal, double radius):
|
||||
InfinitePlane(point, normal), radius(radius)
|
||||
{
|
||||
Disk::Disk(const Vector3 &point, const Vector3 &normal, double radius) : InfinitePlane(point, normal), radius(radius) {
|
||||
radius2 = radius * radius;
|
||||
}
|
||||
|
||||
int Disk::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const
|
||||
{
|
||||
int Disk::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const {
|
||||
int result = InfinitePlane::checkRayIntersection(ray, intersection);
|
||||
|
||||
if (result == 1)
|
||||
{
|
||||
if (result == 1) {
|
||||
Vector3 v = intersection->sub(getPoint());
|
||||
double d2 = v.dotProduct(v);
|
||||
return (d2 <= radius2) ? 1 : 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
void Disk::save(PackStream *stream) const
|
||||
{
|
||||
void Disk::save(PackStream *stream) const {
|
||||
InfinitePlane::save(stream);
|
||||
stream->write(&radius);
|
||||
stream->write(&radius2);
|
||||
}
|
||||
|
||||
void Disk::load(PackStream *stream)
|
||||
{
|
||||
void Disk::load(PackStream *stream) {
|
||||
InfinitePlane::load(stream);
|
||||
stream->read(&radius);
|
||||
stream->read(&radius2);
|
||||
|
|
|
@ -11,13 +11,14 @@ namespace basics {
|
|||
/**
|
||||
* Geometric plane disk.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT Disk: public InfinitePlane
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Disk : public InfinitePlane {
|
||||
public:
|
||||
Disk();
|
||||
Disk(const Vector3 &point, const Vector3 &normal, double radius);
|
||||
|
||||
inline double getRadius() const {return radius;}
|
||||
inline double getRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the intersection between the disk and an infinite ray.
|
||||
|
@ -26,16 +27,15 @@ public:
|
|||
*
|
||||
* Returns -1 if the ray shares a segment with the disk.
|
||||
*/
|
||||
int checkRayIntersection(const InfiniteRay& ray, Vector3 *intersection) const;
|
||||
int checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const;
|
||||
|
||||
void save(PackStream *stream) const override;
|
||||
void load(PackStream *stream) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
double radius;
|
||||
double radius2;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "FractalNoise.h"
|
||||
|
||||
FractalNoise::FractalNoise()
|
||||
{
|
||||
FractalNoise::FractalNoise() {
|
||||
scaling = 1.0;
|
||||
height = 1.0;
|
||||
step_scaling = 2.0;
|
||||
|
@ -10,47 +9,39 @@ FractalNoise::FractalNoise()
|
|||
ridge = 0.0;
|
||||
}
|
||||
|
||||
FractalNoise::~FractalNoise()
|
||||
{
|
||||
FractalNoise::~FractalNoise() {
|
||||
}
|
||||
|
||||
void FractalNoise::setScaling(double scaling, double height)
|
||||
{
|
||||
void FractalNoise::setScaling(double scaling, double height) {
|
||||
this->scaling = scaling < 0.00000001 ? 0.0 : 1.0 / scaling;
|
||||
this->height = scaling * height;
|
||||
}
|
||||
|
||||
void FractalNoise::setStep(double scaling_factor, double height_factor)
|
||||
{
|
||||
void FractalNoise::setStep(double scaling_factor, double height_factor) {
|
||||
this->step_scaling = scaling_factor < 0.00000001 ? 0.0 : 1.0 / scaling_factor;
|
||||
this->step_height = scaling_factor * height_factor;
|
||||
}
|
||||
|
||||
void FractalNoise::setSlope(double slope_factor)
|
||||
{
|
||||
void FractalNoise::setSlope(double slope_factor) {
|
||||
this->slope = slope_factor;
|
||||
}
|
||||
|
||||
void FractalNoise::setRidge(double ridge_factor)
|
||||
{
|
||||
void FractalNoise::setRidge(double ridge_factor) {
|
||||
this->ridge = ridge_factor;
|
||||
}
|
||||
|
||||
void FractalNoise::setState(const NoiseState &state)
|
||||
{
|
||||
void FractalNoise::setState(const NoiseState &state) {
|
||||
state.copy(&this->state);
|
||||
}
|
||||
|
||||
double FractalNoise::get1d(double detail, double x) const
|
||||
{
|
||||
double FractalNoise::get1d(double detail, double x) const {
|
||||
double current_scaling = scaling;
|
||||
double current_height = height;
|
||||
double result = 0.0;
|
||||
int state_level_count = state.level_offsets.size();
|
||||
int i = 0;
|
||||
|
||||
while (current_height >= detail)
|
||||
{
|
||||
while (current_height >= detail) {
|
||||
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||
|
||||
result += getBase1d(offset.x + x * current_scaling) * current_height;
|
||||
|
@ -59,8 +50,7 @@ double FractalNoise::get1d(double detail, double x) const
|
|||
current_height *= step_height;
|
||||
|
||||
i++;
|
||||
if (i >= state_level_count)
|
||||
{
|
||||
if (i >= state_level_count) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
@ -68,16 +58,14 @@ double FractalNoise::get1d(double detail, double x) const
|
|||
return result;
|
||||
}
|
||||
|
||||
double FractalNoise::get2d(double detail, double x, double y) const
|
||||
{
|
||||
double FractalNoise::get2d(double detail, double x, double y) const {
|
||||
double current_scaling = scaling;
|
||||
double current_height = height;
|
||||
double result = 0.0;
|
||||
int state_level_count = state.level_offsets.size();
|
||||
int i = 0;
|
||||
|
||||
while (current_height >= detail)
|
||||
{
|
||||
while (current_height >= detail) {
|
||||
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||
|
||||
result += getBase2d(offset.x + x * current_scaling, offset.y + y * current_scaling) * current_height;
|
||||
|
@ -86,8 +74,7 @@ double FractalNoise::get2d(double detail, double x, double y) const
|
|||
current_height *= step_height;
|
||||
|
||||
i++;
|
||||
if (i >= state_level_count)
|
||||
{
|
||||
if (i >= state_level_count) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
@ -95,26 +82,25 @@ double FractalNoise::get2d(double detail, double x, double y) const
|
|||
return result;
|
||||
}
|
||||
|
||||
double FractalNoise::get3d(double detail, double x, double y, double z) const
|
||||
{
|
||||
double FractalNoise::get3d(double detail, double x, double y, double z) const {
|
||||
double current_scaling = scaling;
|
||||
double current_height = height;
|
||||
double result = 0.0;
|
||||
int state_level_count = state.level_offsets.size();
|
||||
int i = 0;
|
||||
|
||||
while (current_height >= detail)
|
||||
{
|
||||
while (current_height >= detail) {
|
||||
const NoiseState::NoiseOffset &offset = state.level_offsets[i];
|
||||
|
||||
result += getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) * current_height;
|
||||
result +=
|
||||
getBase3d(offset.x + x * current_scaling, offset.y + y * current_scaling, offset.z + z * current_scaling) *
|
||||
current_height;
|
||||
|
||||
current_scaling *= step_scaling;
|
||||
current_height *= step_height;
|
||||
|
||||
i++;
|
||||
if (i >= state_level_count)
|
||||
{
|
||||
if (i >= state_level_count) {
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
|
@ -122,12 +108,10 @@ double FractalNoise::get3d(double detail, double x, double y, double z) const
|
|||
return result;
|
||||
}
|
||||
|
||||
double FractalNoise::getBase1d(double x) const
|
||||
{
|
||||
double FractalNoise::getBase1d(double x) const {
|
||||
return getBase2d(x, 0.0);
|
||||
}
|
||||
|
||||
double FractalNoise::getBase2d(double x, double y) const
|
||||
{
|
||||
double FractalNoise::getBase2d(double x, double y) const {
|
||||
return getBase3d(x, y, 0.0);
|
||||
}
|
||||
|
|
|
@ -11,14 +11,13 @@ namespace basics {
|
|||
/*!
|
||||
* \brief Fractal noise generator, based on a sum of simple noise functions.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT FractalNoise
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT FractalNoise {
|
||||
public:
|
||||
FractalNoise();
|
||||
virtual ~FractalNoise();
|
||||
|
||||
void setScaling(double scaling, double height=1.0);
|
||||
void setStep(double scaling_factor, double height_factor=1.0);
|
||||
void setScaling(double scaling, double height = 1.0);
|
||||
void setStep(double scaling_factor, double height_factor = 1.0);
|
||||
void setSlope(double slope_factor);
|
||||
void setRidge(double ridge_factor);
|
||||
void setState(const NoiseState &state);
|
||||
|
@ -31,7 +30,7 @@ public:
|
|||
virtual double getBase2d(double x, double y) const;
|
||||
virtual double getBase3d(double x, double y, double z) const = 0;
|
||||
|
||||
private:
|
||||
private:
|
||||
NoiseState state;
|
||||
|
||||
double scaling;
|
||||
|
@ -41,7 +40,6 @@ private:
|
|||
double slope;
|
||||
double ridge;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,22 +3,15 @@
|
|||
#include <cmath>
|
||||
#include "Vector3.h"
|
||||
|
||||
double Geometry::get2DAngle(double x, double y)
|
||||
{
|
||||
double Geometry::get2DAngle(double x, double y) {
|
||||
double nx, ny, d, ret;
|
||||
|
||||
if (x == 0.0)
|
||||
{
|
||||
if (y == 0.0)
|
||||
{
|
||||
if (x == 0.0) {
|
||||
if (y == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
else if (y < 0.0)
|
||||
{
|
||||
} else if (y < 0.0) {
|
||||
return 3.0 * M_PI_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return M_PI_2;
|
||||
}
|
||||
}
|
||||
|
@ -28,54 +21,46 @@ double Geometry::get2DAngle(double x, double y)
|
|||
ny = y / d;
|
||||
|
||||
ret = asin(ny);
|
||||
if (nx < 0.0)
|
||||
{
|
||||
if (nx < 0.0) {
|
||||
ret = M_PI - ret;
|
||||
}
|
||||
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
|
||||
}
|
||||
|
||||
Vector3 Geometry::getNormalFromTriangle(const Vector3 ¢er, const Vector3 &bottom, const Vector3 &right)
|
||||
{
|
||||
Vector3 Geometry::getNormalFromTriangle(const Vector3 ¢er, const Vector3 &bottom, const Vector3 &right) {
|
||||
Vector3 dx = right.sub(center);
|
||||
Vector3 dz = bottom.sub(center);
|
||||
return dz.crossProduct(dx).normalize();
|
||||
}
|
||||
|
||||
double Geometry::getDistance2D(double x1, double y1, double x2, double y2)
|
||||
{
|
||||
double Geometry::getDistance2D(double x1, double y1, double x2, double y2) {
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
return sqrt(dx * dx + dy * dy);
|
||||
}
|
||||
|
||||
int Geometry::rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center, double sphere_radius, Vector3 *hit1, Vector3 *hit2)
|
||||
{
|
||||
int Geometry::rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center,
|
||||
double sphere_radius, Vector3 *hit1, Vector3 *hit2) {
|
||||
Vector3 ray_direction_sphere = ray_point.sub(sphere_center);
|
||||
double a, b, c, d;
|
||||
|
||||
a = ray_direction.x * ray_direction.x + ray_direction.y * ray_direction.y + ray_direction.z * ray_direction.z;
|
||||
b = 2 * (ray_direction.x * ray_direction_sphere.x + ray_direction.y * ray_direction_sphere.y + ray_direction.z * ray_direction_sphere.z);
|
||||
c = ray_direction_sphere.x * ray_direction_sphere.x + ray_direction_sphere.y * ray_direction_sphere.y + ray_direction_sphere.z * ray_direction_sphere.z - sphere_radius * sphere_radius;
|
||||
b = 2 * (ray_direction.x * ray_direction_sphere.x + ray_direction.y * ray_direction_sphere.y +
|
||||
ray_direction.z * ray_direction_sphere.z);
|
||||
c = ray_direction_sphere.x * ray_direction_sphere.x + ray_direction_sphere.y * ray_direction_sphere.y +
|
||||
ray_direction_sphere.z * ray_direction_sphere.z - sphere_radius * sphere_radius;
|
||||
d = b * b - 4 * a * c;
|
||||
|
||||
if (d < 0.0)
|
||||
{
|
||||
if (d < 0.0) {
|
||||
return 0;
|
||||
}
|
||||
else if (d > 0.0)
|
||||
{
|
||||
if (hit1 && hit2)
|
||||
{
|
||||
} else if (d > 0.0) {
|
||||
if (hit1 && hit2) {
|
||||
*hit1 = ray_point.add(ray_direction.scale((-b - sqrt(d)) / (2 * a)));
|
||||
*hit2 = ray_point.add(ray_direction.scale((-b + sqrt(d)) / (2 * a)));
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hit1)
|
||||
{
|
||||
} else {
|
||||
if (hit1) {
|
||||
*hit1 = ray_point.add(ray_direction.scale(-b / (2 * a)));
|
||||
}
|
||||
return 1;
|
||||
|
|
|
@ -6,15 +6,14 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Geometry
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Geometry {
|
||||
public:
|
||||
static double get2DAngle(double x, double y);
|
||||
static Vector3 getNormalFromTriangle(const Vector3 ¢er, const Vector3 &bottom, const Vector3 &right);
|
||||
static double getDistance2D(double x1, double y1, double x2, double y2);
|
||||
static int rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center, double sphere_radius, Vector3 *hit1, Vector3 *hit2);
|
||||
static int rayIntersectSphere(const Vector3 &ray_point, const Vector3 &ray_direction, const Vector3 &sphere_center,
|
||||
double sphere_radius, Vector3 *hit1, Vector3 *hit2);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,17 +4,14 @@
|
|||
|
||||
#define EPS 1E-8
|
||||
|
||||
InfiniteCylinder::InfiniteCylinder()
|
||||
{
|
||||
InfiniteCylinder::InfiniteCylinder() {
|
||||
}
|
||||
|
||||
InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius):
|
||||
axis(axis), radius(radius)
|
||||
{
|
||||
InfiniteCylinder::InfiniteCylinder(const InfiniteRay &axis, double radius) : axis(axis), radius(radius) {
|
||||
}
|
||||
|
||||
int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
|
||||
{
|
||||
int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
|
||||
Vector3 *second_intersection) const {
|
||||
/*
|
||||
* Original algorithm has been altered, because it didn't work with non-(0,0,0) axis origin.
|
||||
* Maybe some optimizations could be made from this.
|
||||
|
@ -27,108 +24,108 @@ int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *firs
|
|||
|
||||
/* choose U, V so that U,V,F is orthonormal set */
|
||||
|
||||
if ( fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z) )
|
||||
{
|
||||
length = sqrt(F.x*F.x+F.y*F.y);
|
||||
invLength = 1.0/length;
|
||||
U.x = -F.y*invLength;
|
||||
U.y = +F.x*invLength;
|
||||
if (fabs(F.x) > fabs(F.y) && fabs(F.x) > fabs(F.z)) {
|
||||
length = sqrt(F.x * F.x + F.y * F.y);
|
||||
invLength = 1.0 / length;
|
||||
U.x = -F.y * invLength;
|
||||
U.y = +F.x * invLength;
|
||||
U.z = 0.0;
|
||||
prod = -F.z*invLength;
|
||||
V.x = F.x*prod;
|
||||
V.y = F.y*prod;
|
||||
prod = -F.z * invLength;
|
||||
V.x = F.x * prod;
|
||||
V.y = F.y * prod;
|
||||
V.z = length;
|
||||
}
|
||||
else
|
||||
{
|
||||
length = sqrt(F.y*F.y+F.z*F.z);
|
||||
invLength = 1.0/length;
|
||||
} else {
|
||||
length = sqrt(F.y * F.y + F.z * F.z);
|
||||
invLength = 1.0 / length;
|
||||
U.x = 0.0;
|
||||
U.y = -F.z*invLength;
|
||||
U.z = +F.y*invLength;
|
||||
prod = -F.x*invLength;
|
||||
U.y = -F.z * invLength;
|
||||
U.z = +F.y * invLength;
|
||||
prod = -F.x * invLength;
|
||||
V.x = length;
|
||||
V.y = F.y*prod;
|
||||
V.z = F.z*prod;
|
||||
V.y = F.y * prod;
|
||||
V.z = F.z * prod;
|
||||
}
|
||||
|
||||
/* orthonormal matrix */
|
||||
R[0][0] = U.x; R[0][1] = U.y; R[0][2] = U.z;
|
||||
R[1][0] = V.x; R[1][1] = V.y; R[1][2] = V.z;
|
||||
R[2][0] = F.x; R[2][1] = F.y; R[2][2] = F.z;
|
||||
R[0][0] = U.x;
|
||||
R[0][1] = U.y;
|
||||
R[0][2] = U.z;
|
||||
R[1][0] = V.x;
|
||||
R[1][1] = V.y;
|
||||
R[1][2] = V.z;
|
||||
R[2][0] = F.x;
|
||||
R[2][1] = F.y;
|
||||
R[2][2] = F.z;
|
||||
|
||||
/* matrix A */
|
||||
A[0][0] = R[0][0]*R[0][0]+R[1][0]*R[1][0];
|
||||
A[0][1] = R[0][0]*R[0][1]+R[1][0]*R[1][1];
|
||||
A[0][2] = R[0][0]*R[0][2]+R[1][0]*R[1][2];
|
||||
A[0][0] = R[0][0] * R[0][0] + R[1][0] * R[1][0];
|
||||
A[0][1] = R[0][0] * R[0][1] + R[1][0] * R[1][1];
|
||||
A[0][2] = R[0][0] * R[0][2] + R[1][0] * R[1][2];
|
||||
|
||||
A[1][0] = R[0][1]*R[0][0]+R[1][1]*R[1][0];
|
||||
A[1][1] = R[0][1]*R[0][1]+R[1][1]*R[1][1];
|
||||
A[1][2] = R[0][1]*R[0][2]+R[1][1]*R[1][2];
|
||||
A[1][0] = R[0][1] * R[0][0] + R[1][1] * R[1][0];
|
||||
A[1][1] = R[0][1] * R[0][1] + R[1][1] * R[1][1];
|
||||
A[1][2] = R[0][1] * R[0][2] + R[1][1] * R[1][2];
|
||||
|
||||
A[2][0] = R[0][2]*R[0][0]+R[1][2]*R[1][0];
|
||||
A[2][1] = R[0][2]*R[0][1]+R[1][2]*R[1][1];
|
||||
A[2][2] = R[0][2]*R[0][2]+R[1][2]*R[1][2];
|
||||
A[2][0] = R[0][2] * R[0][0] + R[1][2] * R[1][0];
|
||||
A[2][1] = R[0][2] * R[0][1] + R[1][2] * R[1][1];
|
||||
A[2][2] = R[0][2] * R[0][2] + R[1][2] * R[1][2];
|
||||
|
||||
/* vector B */
|
||||
P = Vector3(0.0, 0.0, 0.0);
|
||||
B.x = -2.0*P.x; B.y = -2.0*P.y; B.z = -2.0*P.z;
|
||||
B.x = -2.0 * P.x;
|
||||
B.y = -2.0 * P.y;
|
||||
B.z = -2.0 * P.z;
|
||||
|
||||
/* constant C */
|
||||
e0 = -2.0*(R[0][0]*P.x+R[0][1]*P.y+R[0][2]*P.z);
|
||||
e1 = -2.0*(R[1][0]*P.x+R[1][1]*P.y+R[1][2]*P.z);
|
||||
C = 0.25*(e0*e0+e1*e1) - radius*radius;
|
||||
e0 = -2.0 * (R[0][0] * P.x + R[0][1] * P.y + R[0][2] * P.z);
|
||||
e1 = -2.0 * (R[1][0] * P.x + R[1][1] * P.y + R[1][2] * P.z);
|
||||
C = 0.25 * (e0 * e0 + e1 * e1) - radius * radius;
|
||||
|
||||
/* line */
|
||||
Q = ray.getOrigin().sub(axis.getOrigin());
|
||||
G = ray.getDirection();
|
||||
|
||||
/* compute A*G */
|
||||
AG.x = A[0][0]*G.x+A[0][1]*G.y+A[0][2]*G.z;
|
||||
AG.y = A[1][0]*G.x+A[1][1]*G.y+A[1][2]*G.z;
|
||||
AG.z = A[2][0]*G.x+A[2][1]*G.y+A[2][2]*G.z;
|
||||
AG.x = A[0][0] * G.x + A[0][1] * G.y + A[0][2] * G.z;
|
||||
AG.y = A[1][0] * G.x + A[1][1] * G.y + A[1][2] * G.z;
|
||||
AG.z = A[2][0] * G.x + A[2][1] * G.y + A[2][2] * G.z;
|
||||
|
||||
/* compute A*Q */
|
||||
AQ.x = A[0][0]*Q.x+A[0][1]*Q.y+A[0][2]*Q.z;
|
||||
AQ.y = A[1][0]*Q.x+A[1][1]*Q.y+A[1][2]*Q.z;
|
||||
AQ.z = A[2][0]*Q.x+A[2][1]*Q.y+A[2][2]*Q.z;
|
||||
AQ.x = A[0][0] * Q.x + A[0][1] * Q.y + A[0][2] * Q.z;
|
||||
AQ.y = A[1][0] * Q.x + A[1][1] * Q.y + A[1][2] * Q.z;
|
||||
AQ.z = A[2][0] * Q.x + A[2][1] * Q.y + A[2][2] * Q.z;
|
||||
|
||||
/* compute quadratic equation c0+c1*t+c2*t^2 = 0 */
|
||||
c2 = G.x*AG.x+G.y*AG.y+G.z*AG.z;
|
||||
c1 = B.x*G.x+B.y*G.y+B.z*G.z+2.0f*(Q.x*AG.x+Q.y*AG.y+Q.z*AG.z);
|
||||
c0 = Q.x*AQ.x+Q.y*AQ.y+Q.z*AQ.z+B.x*Q.x+B.y*Q.y+B.z*Q.z+C;
|
||||
c2 = G.x * AG.x + G.y * AG.y + G.z * AG.z;
|
||||
c1 = B.x * G.x + B.y * G.y + B.z * G.z + 2.0f * (Q.x * AG.x + Q.y * AG.y + Q.z * AG.z);
|
||||
c0 = Q.x * AQ.x + Q.y * AQ.y + Q.z * AQ.z + B.x * Q.x + B.y * Q.y + B.z * Q.z + C;
|
||||
|
||||
/* solve for intersections */
|
||||
int numIntersections;
|
||||
discr = c1*c1-4.0*c0*c2;
|
||||
if ( discr > EPS )
|
||||
{
|
||||
discr = c1 * c1 - 4.0 * c0 * c2;
|
||||
if (discr > EPS) {
|
||||
numIntersections = 2;
|
||||
discr = sqrt(discr);
|
||||
invC2 = 1.0/c2;
|
||||
root0 = -0.5*(c1+discr)*invC2;
|
||||
root1 = -0.5*(c1-discr)*invC2;
|
||||
first_intersection->x = Q.x+root0*G.x;
|
||||
first_intersection->y = Q.y+root0*G.y;
|
||||
first_intersection->z = Q.z+root0*G.z;
|
||||
second_intersection->x = Q.x+root1*G.x;
|
||||
second_intersection->y = Q.y+root1*G.y;
|
||||
second_intersection->z = Q.z+root1*G.z;
|
||||
invC2 = 1.0 / c2;
|
||||
root0 = -0.5 * (c1 + discr) * invC2;
|
||||
root1 = -0.5 * (c1 - discr) * invC2;
|
||||
first_intersection->x = Q.x + root0 * G.x;
|
||||
first_intersection->y = Q.y + root0 * G.y;
|
||||
first_intersection->z = Q.z + root0 * G.z;
|
||||
second_intersection->x = Q.x + root1 * G.x;
|
||||
second_intersection->y = Q.y + root1 * G.y;
|
||||
second_intersection->z = Q.z + root1 * G.z;
|
||||
|
||||
*first_intersection = first_intersection->add(axis.getOrigin());
|
||||
*second_intersection = second_intersection->add(axis.getOrigin());
|
||||
}
|
||||
else if ( discr < -EPS )
|
||||
{
|
||||
} else if (discr < -EPS) {
|
||||
numIntersections = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
numIntersections = 1;
|
||||
root = -0.5*c1/c2;
|
||||
first_intersection->x = Q.x+root*G.x;
|
||||
first_intersection->y = Q.y+root*G.y;
|
||||
first_intersection->z = Q.z+root*G.z;
|
||||
root = -0.5 * c1 / c2;
|
||||
first_intersection->x = Q.x + root * G.x;
|
||||
first_intersection->y = Q.y + root * G.y;
|
||||
first_intersection->z = Q.z + root * G.z;
|
||||
|
||||
*first_intersection = first_intersection->add(axis.getOrigin());
|
||||
}
|
||||
|
@ -136,14 +133,12 @@ int InfiniteCylinder::checkRayIntersection(const InfiniteRay &ray, Vector3 *firs
|
|||
return numIntersections;
|
||||
}
|
||||
|
||||
void InfiniteCylinder::save(PackStream *stream) const
|
||||
{
|
||||
void InfiniteCylinder::save(PackStream *stream) const {
|
||||
axis.save(stream);
|
||||
stream->write(&radius);
|
||||
}
|
||||
|
||||
void InfiniteCylinder::load(PackStream *stream)
|
||||
{
|
||||
void InfiniteCylinder::load(PackStream *stream) {
|
||||
axis.load(stream);
|
||||
stream->read(&radius);
|
||||
}
|
||||
|
|
|
@ -11,30 +11,32 @@ namespace basics {
|
|||
/**
|
||||
* Geometric cylinder, with infinite length.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT InfiniteCylinder
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT InfiniteCylinder {
|
||||
public:
|
||||
InfiniteCylinder();
|
||||
InfiniteCylinder(const InfiniteRay &axis, double radius);
|
||||
|
||||
inline const InfiniteRay& getAxis() const {return axis;}
|
||||
inline double getRadius() const {return radius;}
|
||||
inline const InfiniteRay &getAxis() const {
|
||||
return axis;
|
||||
}
|
||||
inline double getRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the intersection between the cylinder and an infinite ray.
|
||||
*
|
||||
* Returns the number of intersections (0, 1 or 2) and fill the intersection points.
|
||||
*/
|
||||
int checkRayIntersection(const InfiniteRay& ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
|
||||
int checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
|
||||
|
||||
virtual void save(PackStream *stream) const;
|
||||
virtual void load(PackStream *stream);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
InfiniteRay axis;
|
||||
double radius;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,28 +3,20 @@
|
|||
#include "PackStream.h"
|
||||
#include "InfiniteRay.h"
|
||||
|
||||
InfinitePlane::InfinitePlane()
|
||||
{
|
||||
InfinitePlane::InfinitePlane() {
|
||||
}
|
||||
|
||||
InfinitePlane::InfinitePlane(const Vector3 &point, const Vector3 &normal):
|
||||
point(point), normal(normal)
|
||||
{
|
||||
InfinitePlane::InfinitePlane(const Vector3 &point, const Vector3 &normal) : point(point), normal(normal) {
|
||||
}
|
||||
|
||||
int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const
|
||||
{
|
||||
int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const {
|
||||
Vector3 p1 = ray.getDirection();
|
||||
double d = normal.dotProduct(p1);
|
||||
|
||||
if (fabs(d) < 1e-8)
|
||||
{
|
||||
if (normal.dotProduct(ray.getPointAtCursor(1.0).sub(point)) == 0)
|
||||
{
|
||||
if (fabs(d) < 1e-8) {
|
||||
if (normal.dotProduct(ray.getPointAtCursor(1.0).sub(point)) == 0) {
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -34,15 +26,12 @@ int InfinitePlane::checkRayIntersection(const InfiniteRay &ray, Vector3 *interse
|
|||
return 1;
|
||||
}
|
||||
|
||||
void InfinitePlane::save(PackStream *stream) const
|
||||
{
|
||||
void InfinitePlane::save(PackStream *stream) const {
|
||||
point.save(stream);
|
||||
normal.save(stream);
|
||||
}
|
||||
|
||||
void InfinitePlane::load(PackStream *stream)
|
||||
{
|
||||
void InfinitePlane::load(PackStream *stream) {
|
||||
point.load(stream);
|
||||
normal.load(stream);
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@ namespace basics {
|
|||
/**
|
||||
* Infinite 3d geometric plane.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT InfinitePlane
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT InfinitePlane {
|
||||
public:
|
||||
InfinitePlane();
|
||||
InfinitePlane(const Vector3 &point, const Vector3 &normal);
|
||||
|
||||
|
@ -24,19 +23,22 @@ public:
|
|||
*
|
||||
* Returns -1 if the ray is on the plane, and make for an infinite number of intersection points.
|
||||
*/
|
||||
int checkRayIntersection(const InfiniteRay& ray, Vector3 *intersection) const;
|
||||
int checkRayIntersection(const InfiniteRay &ray, Vector3 *intersection) const;
|
||||
|
||||
inline const Vector3 &getPoint() const {return point;}
|
||||
inline const Vector3 &getNormal() const {return normal;}
|
||||
inline const Vector3 &getPoint() const {
|
||||
return point;
|
||||
}
|
||||
inline const Vector3 &getNormal() const {
|
||||
return normal;
|
||||
}
|
||||
|
||||
virtual void save(PackStream *stream) const;
|
||||
virtual void load(PackStream *stream);
|
||||
|
||||
private:
|
||||
private:
|
||||
Vector3 point;
|
||||
Vector3 normal;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,27 +1,22 @@
|
|||
#include "InfiniteRay.h"
|
||||
|
||||
InfiniteRay::InfiniteRay()
|
||||
{
|
||||
InfiniteRay::InfiniteRay() {
|
||||
}
|
||||
|
||||
InfiniteRay::InfiniteRay(const Vector3 &origin, const Vector3 &direction):
|
||||
origin(origin), direction(direction.normalize())
|
||||
{
|
||||
InfiniteRay::InfiniteRay(const Vector3 &origin, const Vector3 &direction)
|
||||
: origin(origin), direction(direction.normalize()) {
|
||||
}
|
||||
|
||||
InfiniteRay InfiniteRay::fromPoints(const Vector3 &point1, const Vector3 &point2)
|
||||
{
|
||||
InfiniteRay InfiniteRay::fromPoints(const Vector3 &point1, const Vector3 &point2) {
|
||||
return InfiniteRay(point1, point2.sub(point1).normalize());
|
||||
}
|
||||
|
||||
void InfiniteRay::save(PackStream *stream) const
|
||||
{
|
||||
void InfiniteRay::save(PackStream *stream) const {
|
||||
origin.save(stream);
|
||||
direction.save(stream);
|
||||
}
|
||||
|
||||
void InfiniteRay::load(PackStream *stream)
|
||||
{
|
||||
void InfiniteRay::load(PackStream *stream) {
|
||||
origin.load(stream);
|
||||
direction.load(stream);
|
||||
}
|
||||
|
|
|
@ -11,28 +11,34 @@ namespace basics {
|
|||
/**
|
||||
* Infinite ray (line).
|
||||
*/
|
||||
class BASICSSHARED_EXPORT InfiniteRay
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT InfiniteRay {
|
||||
public:
|
||||
InfiniteRay();
|
||||
InfiniteRay(const Vector3 &origin, const Vector3 &direction);
|
||||
|
||||
static InfiniteRay fromPoints(const Vector3 &point1, const Vector3 &point2);
|
||||
|
||||
inline const Vector3 &getOrigin() const {return origin;}
|
||||
inline const Vector3 &getDirection() const {return direction;}
|
||||
inline const Vector3 &getOrigin() const {
|
||||
return origin;
|
||||
}
|
||||
inline const Vector3 &getDirection() const {
|
||||
return direction;
|
||||
}
|
||||
|
||||
inline double getCursor(const Vector3 &point) const {return point.sub(origin).dotProduct(direction);}
|
||||
inline Vector3 getPointAtCursor(double distance) const {return origin.add(direction.scale(distance));}
|
||||
inline double getCursor(const Vector3 &point) const {
|
||||
return point.sub(origin).dotProduct(direction);
|
||||
}
|
||||
inline Vector3 getPointAtCursor(double distance) const {
|
||||
return origin.add(direction.scale(distance));
|
||||
}
|
||||
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
|
||||
private:
|
||||
private:
|
||||
Vector3 origin;
|
||||
Vector3 direction;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "Interpolation.h"
|
||||
|
||||
double Interpolation::bicubic(double stencil[16], double x, double y)
|
||||
{
|
||||
double Interpolation::bicubic(double stencil[16], double x, double y) {
|
||||
double buf_cubic_y[4];
|
||||
|
||||
buf_cubic_y[0] = Interpolation::cubic(stencil, x);
|
||||
|
@ -12,15 +11,13 @@ double Interpolation::bicubic(double stencil[16], double x, double y)
|
|||
return Interpolation::cubic(buf_cubic_y, y);
|
||||
}
|
||||
|
||||
double Interpolation::bilinear(double p[4], double x, double y)
|
||||
{
|
||||
double Interpolation::bilinear(double p[4], double x, double y) {
|
||||
double e1 = linear(p[0], p[1], x);
|
||||
double e2 = linear(p[3], p[2], x);
|
||||
return Interpolation::linear(e1, e2, y);
|
||||
}
|
||||
|
||||
double Interpolation::trilinear(double p[8], double x, double y, double z)
|
||||
{
|
||||
double Interpolation::trilinear(double p[8], double x, double y, double z) {
|
||||
double f1 = bilinear(p, x, y);
|
||||
double f2 = bilinear(p + 4, x, y);
|
||||
return Interpolation::linear(f1, f2, z);
|
||||
|
|
|
@ -6,23 +6,21 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Interpolation
|
||||
{
|
||||
public:
|
||||
static inline double linear(double p1, double p2, double x)
|
||||
{
|
||||
class BASICSSHARED_EXPORT Interpolation {
|
||||
public:
|
||||
static inline double linear(double p1, double p2, double x) {
|
||||
return p1 + x * (p2 - p1);
|
||||
}
|
||||
static double bilinear(double p[4], double x, double y);
|
||||
static double trilinear(double p[8], double x, double y, double z);
|
||||
|
||||
static inline double cubic(double p[4], double x)
|
||||
{
|
||||
return p[1] + 0.5 * x * (p[2] - p[0] + x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
|
||||
static inline double cubic(double p[4], double x) {
|
||||
return p[1] +
|
||||
0.5 * x * (p[2] - p[0] +
|
||||
x * (2.0 * p[0] - 5.0 * p[1] + 4.0 * p[2] - p[3] + x * (3.0 * (p[1] - p[2]) + p[3] - p[0])));
|
||||
}
|
||||
static double bicubic(double stencil[16], double x, double y);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,15 +4,13 @@
|
|||
#include "PackStream.h"
|
||||
#include "Vector3.h"
|
||||
|
||||
Matrix4::Matrix4(bool identity)
|
||||
{
|
||||
Matrix4::Matrix4(bool identity) {
|
||||
b = c = d = e = g = h = 0.0;
|
||||
i = j = l = m = n = o = 0.0;
|
||||
a = f = k = p = (identity ? 1.0 : 0.0);
|
||||
}
|
||||
|
||||
void Matrix4::save(PackStream* stream) const
|
||||
{
|
||||
void Matrix4::save(PackStream *stream) const {
|
||||
stream->write(&a);
|
||||
stream->write(&b);
|
||||
stream->write(&c);
|
||||
|
@ -31,8 +29,7 @@ void Matrix4::save(PackStream* stream) const
|
|||
stream->write(&p);
|
||||
}
|
||||
|
||||
void Matrix4::load(PackStream* stream)
|
||||
{
|
||||
void Matrix4::load(PackStream *stream) {
|
||||
stream->read(&a);
|
||||
stream->read(&b);
|
||||
stream->read(&c);
|
||||
|
@ -51,8 +48,7 @@ void Matrix4::load(PackStream* stream)
|
|||
stream->read(&p);
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::mult(const Matrix4 &other) const
|
||||
{
|
||||
Matrix4 Matrix4::mult(const Matrix4 &other) const {
|
||||
Matrix4 result;
|
||||
result.a = a * other.a + b * other.e + c * other.i + d * other.m;
|
||||
result.b = a * other.b + b * other.f + c * other.j + d * other.n;
|
||||
|
@ -73,8 +69,7 @@ Matrix4 Matrix4::mult(const Matrix4 &other) const
|
|||
return result;
|
||||
}
|
||||
|
||||
Vector3 Matrix4::multPoint(const Vector3 &v) const
|
||||
{
|
||||
Vector3 Matrix4::multPoint(const Vector3 &v) const {
|
||||
Vector3 result;
|
||||
result.x = a * v.x + b * v.y + c * v.z + d;
|
||||
result.y = e * v.x + f * v.y + g * v.z + h;
|
||||
|
@ -82,30 +77,19 @@ Vector3 Matrix4::multPoint(const Vector3 &v) const
|
|||
return result;
|
||||
}
|
||||
|
||||
Vector3 Matrix4::transform(const Vector3 &v) const
|
||||
{
|
||||
Vector3 Matrix4::transform(const Vector3 &v) const {
|
||||
double w = m * v.x + n * v.y + o * v.z + p;
|
||||
if (w != 0.0)
|
||||
{
|
||||
if (w != 0.0) {
|
||||
w = 1.0 / w;
|
||||
return Vector3(
|
||||
(a * v.x + b * v.y + c * v.z + d) * w,
|
||||
(e * v.x + f * v.y + g * v.z + h) * w,
|
||||
(i * v.x + j * v.y + k * v.z + l) * w
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
return Vector3(
|
||||
a * v.x + b * v.y + c * v.z + d,
|
||||
e * v.x + f * v.y + g * v.z + h,
|
||||
i * v.x + j * v.y + k * v.z + l
|
||||
);
|
||||
return Vector3((a * v.x + b * v.y + c * v.z + d) * w, (e * v.x + f * v.y + g * v.z + h) * w,
|
||||
(i * v.x + j * v.y + k * v.z + l) * w);
|
||||
} else {
|
||||
return Vector3(a * v.x + b * v.y + c * v.z + d, e * v.x + f * v.y + g * v.z + h,
|
||||
i * v.x + j * v.y + k * v.z + l);
|
||||
}
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::transposed() const
|
||||
{
|
||||
Matrix4 Matrix4::transposed() const {
|
||||
Matrix4 result;
|
||||
result.a = a;
|
||||
result.e = b;
|
||||
|
@ -126,8 +110,7 @@ Matrix4 Matrix4::transposed() const
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newScale(double x, double y, double z)
|
||||
{
|
||||
Matrix4 Matrix4::newScale(double x, double y, double z) {
|
||||
Matrix4 result;
|
||||
result.a = x;
|
||||
result.f = y;
|
||||
|
@ -135,8 +118,7 @@ Matrix4 Matrix4::newScale(double x, double y, double z)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newTranslate(double x, double y, double z)
|
||||
{
|
||||
Matrix4 Matrix4::newTranslate(double x, double y, double z) {
|
||||
Matrix4 result;
|
||||
result.d = x;
|
||||
result.h = y;
|
||||
|
@ -144,8 +126,7 @@ Matrix4 Matrix4::newTranslate(double x, double y, double z)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateX(double angle)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateX(double angle) {
|
||||
Matrix4 result;
|
||||
double si = sin(angle);
|
||||
double co = cos(angle);
|
||||
|
@ -155,8 +136,7 @@ Matrix4 Matrix4::newRotateX(double angle)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateY(double angle)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateY(double angle) {
|
||||
Matrix4 result;
|
||||
double si = sin(angle);
|
||||
double co = cos(angle);
|
||||
|
@ -166,8 +146,7 @@ Matrix4 Matrix4::newRotateY(double angle)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateZ(double angle)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateZ(double angle) {
|
||||
Matrix4 result;
|
||||
double si = sin(angle);
|
||||
double co = cos(angle);
|
||||
|
@ -177,8 +156,7 @@ Matrix4 Matrix4::newRotateZ(double angle)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis) {
|
||||
Matrix4 result;
|
||||
double si = sin(angle);
|
||||
double co = cos(angle);
|
||||
|
@ -196,8 +174,7 @@ Matrix4 Matrix4::newRotateAxis(double angle, const Vector3 &_axis)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank) {
|
||||
Matrix4 result;
|
||||
double ch = cos(heading);
|
||||
double sh = sin(heading);
|
||||
|
@ -217,8 +194,7 @@ Matrix4 Matrix4::newRotateEuler(double heading, double attitude, double bank)
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const Vector3 &z)
|
||||
{
|
||||
Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const Vector3 &z) {
|
||||
Matrix4 result;
|
||||
result.a = x.x;
|
||||
result.b = y.x;
|
||||
|
@ -232,8 +208,7 @@ Matrix4 Matrix4::newRotateTripleAxis(const Vector3 &x, const Vector3 &y, const V
|
|||
return result;
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up)
|
||||
{
|
||||
Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3 &up) {
|
||||
Vector3 z = at.sub(eye).normalize();
|
||||
Vector3 x = up.crossProduct(z).normalize();
|
||||
Vector3 y = z.crossProduct(x);
|
||||
|
@ -244,8 +219,7 @@ Matrix4 Matrix4::newLookAt(const Vector3 &eye, const Vector3 &at, const Vector3
|
|||
return result.inversed();
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double far)
|
||||
{
|
||||
Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double far) {
|
||||
Matrix4 result;
|
||||
double fo = 1 / tan(fov_y / 2.0);
|
||||
result.a = fo / aspect;
|
||||
|
@ -257,29 +231,16 @@ Matrix4 Matrix4::newPerspective(double fov_y, double aspect, double near, double
|
|||
return result;
|
||||
}
|
||||
|
||||
double Matrix4::getDeterminant() const
|
||||
{
|
||||
return ((a * f - e * b)
|
||||
* (k * p - o * l)
|
||||
- (a * j - i * b)
|
||||
* (g * p - o * h)
|
||||
+ (a * n - m * b)
|
||||
* (g * l - k * h)
|
||||
+ (e * j - i * f)
|
||||
* (c * p - o * d)
|
||||
- (e * n - m * f)
|
||||
* (c * l - k * d)
|
||||
+ (i * n - m * j)
|
||||
* (c * h - g * d));
|
||||
double Matrix4::getDeterminant() const {
|
||||
return ((a * f - e * b) * (k * p - o * l) - (a * j - i * b) * (g * p - o * h) + (a * n - m * b) * (g * l - k * h) +
|
||||
(e * j - i * f) * (c * p - o * d) - (e * n - m * f) * (c * l - k * d) + (i * n - m * j) * (c * h - g * d));
|
||||
}
|
||||
|
||||
Matrix4 Matrix4::inversed() const
|
||||
{
|
||||
Matrix4 Matrix4::inversed() const {
|
||||
Matrix4 result;
|
||||
double det = getDeterminant();
|
||||
|
||||
if (fabs(det) >= 0.00001)
|
||||
{
|
||||
if (fabs(det) >= 0.00001) {
|
||||
det = 1.0 / det;
|
||||
|
||||
result.a = det * (f * (k * p - o * l) + j * (o * h - g * p) + n * (g * l - k * h));
|
||||
|
@ -301,7 +262,6 @@ Matrix4 Matrix4::inversed() const
|
|||
result.h = det * (c * (i * h - e * l) + g * (a * l - i * d) + k * (e * d - a * h));
|
||||
result.l = det * (d * (i * f - e * j) + h * (a * j - i * b) + l * (e * b - a * f));
|
||||
result.p = det * (a * (f * k - j * g) + e * (j * c - b * k) + i * (b * g - f * c));
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
|
@ -10,13 +10,12 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Matrix4
|
||||
{
|
||||
public:
|
||||
Matrix4(bool identity=true);
|
||||
class BASICSSHARED_EXPORT Matrix4 {
|
||||
public:
|
||||
Matrix4(bool identity = true);
|
||||
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
|
||||
Matrix4 mult(const Matrix4 &other) const;
|
||||
Vector3 multPoint(const Vector3 &v) const;
|
||||
|
@ -39,14 +38,11 @@ public:
|
|||
|
||||
#ifdef QT_GUI_LIB
|
||||
inline QMatrix4x4 toQMatrix() const {
|
||||
return QMatrix4x4(a, b, c, d,
|
||||
e, f, g, h,
|
||||
i, j, k, l,
|
||||
m, n, o, p);
|
||||
return QMatrix4x4(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p);
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
private:
|
||||
double a;
|
||||
double b;
|
||||
double c;
|
||||
|
@ -64,7 +60,6 @@ private:
|
|||
double o;
|
||||
double p;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,15 +9,14 @@
|
|||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
|
||||
NoiseFunctionPerlin::NoiseFunctionPerlin()
|
||||
{
|
||||
NoiseFunctionPerlin::NoiseFunctionPerlin() {
|
||||
}
|
||||
|
||||
#define B 0x100
|
||||
#define BM 0xff
|
||||
|
||||
#define N 0x1000
|
||||
#define NP 12 /* 2^N */
|
||||
#define NP 12 /* 2^N */
|
||||
#define NM 0xfff
|
||||
|
||||
static int p[B + B + 2];
|
||||
|
@ -25,108 +24,117 @@ static double g3[B + B + 2][3];
|
|||
static double g2[B + B + 2][2];
|
||||
static double g1[B + B + 2];
|
||||
|
||||
#define s_curve(t) ( t * t * (3. - 2. * t) )
|
||||
#define s_curve(t) (t * t * (3. - 2. * t))
|
||||
|
||||
#define lerp(t, a, b) ( a + t * (b - a) )
|
||||
#define lerp(t, a, b) (a + t * (b - a))
|
||||
|
||||
#define setup(i,b0,b1,r0,r1)\
|
||||
t = vec[i] + N;\
|
||||
b0 = ((int)t) & BM;\
|
||||
b1 = (b0+1) & BM;\
|
||||
r0 = t - (int)t;\
|
||||
#define setup(i, b0, b1, r0, r1) \
|
||||
t = vec[i] + N; \
|
||||
b0 = ((int)t) & BM; \
|
||||
b1 = (b0 + 1) & BM; \
|
||||
r0 = t - (int)t; \
|
||||
r1 = r0 - 1.;
|
||||
|
||||
double noisePerlinGet1DValue(double x)
|
||||
{
|
||||
double vec[1] = {x*2.0};
|
||||
double noisePerlinGet1DValue(double x) {
|
||||
double vec[1] = {x * 2.0};
|
||||
int bx0, bx1;
|
||||
double rx0, rx1, sx, t, u, v;
|
||||
|
||||
setup(0, bx0,bx1, rx0,rx1);
|
||||
setup(0, bx0, bx1, rx0, rx1);
|
||||
|
||||
sx = s_curve(rx0);
|
||||
|
||||
u = rx0 * g1[ p[ bx0 ] ];
|
||||
v = rx1 * g1[ p[ bx1 ] ];
|
||||
u = rx0 * g1[p[bx0]];
|
||||
v = rx1 * g1[p[bx1]];
|
||||
|
||||
return lerp(sx, u, v) * 1.068 + 0.5;
|
||||
}
|
||||
|
||||
double noisePerlinGet2DValue(double x, double y)
|
||||
{
|
||||
double vec[2] = {x*2.0, y*2.0};
|
||||
double noisePerlinGet2DValue(double x, double y) {
|
||||
double vec[2] = {x * 2.0, y * 2.0};
|
||||
int bx0, bx1, by0, by1, b00, b10, b01, b11;
|
||||
double rx0, rx1, ry0, ry1, *q, sx, sy, a, b, t, u, v;
|
||||
int i, j;
|
||||
|
||||
setup(0, bx0,bx1, rx0,rx1);
|
||||
setup(1, by0,by1, ry0,ry1);
|
||||
setup(0, bx0, bx1, rx0, rx1);
|
||||
setup(1, by0, by1, ry0, ry1);
|
||||
|
||||
i = p[ bx0 ];
|
||||
j = p[ bx1 ];
|
||||
i = p[bx0];
|
||||
j = p[bx1];
|
||||
|
||||
b00 = p[ i + by0 ];
|
||||
b10 = p[ j + by0 ];
|
||||
b01 = p[ i + by1 ];
|
||||
b11 = p[ j + by1 ];
|
||||
b00 = p[i + by0];
|
||||
b10 = p[j + by0];
|
||||
b01 = p[i + by1];
|
||||
b11 = p[j + by1];
|
||||
|
||||
sx = s_curve(rx0);
|
||||
sy = s_curve(ry0);
|
||||
|
||||
#define at2(rx,ry) ( rx * q[0] + ry * q[1] )
|
||||
#define at2(rx, ry) (rx * q[0] + ry * q[1])
|
||||
|
||||
q = g2[ b00 ] ; u = at2(rx0,ry0);
|
||||
q = g2[ b10 ] ; v = at2(rx1,ry0);
|
||||
q = g2[b00];
|
||||
u = at2(rx0, ry0);
|
||||
q = g2[b10];
|
||||
v = at2(rx1, ry0);
|
||||
a = lerp(sx, u, v);
|
||||
|
||||
q = g2[ b01 ] ; u = at2(rx0,ry1);
|
||||
q = g2[ b11 ] ; v = at2(rx1,ry1);
|
||||
q = g2[b01];
|
||||
u = at2(rx0, ry1);
|
||||
q = g2[b11];
|
||||
v = at2(rx1, ry1);
|
||||
b = lerp(sx, u, v);
|
||||
|
||||
return lerp(sy, a, b) * 0.709 + 0.5;
|
||||
}
|
||||
|
||||
double noisePerlinGet3DValue(double x, double y, double z)
|
||||
{
|
||||
double vec[3] = {x*2.0, y*2.0, z*2.0};
|
||||
double noisePerlinGet3DValue(double x, double y, double z) {
|
||||
double vec[3] = {x * 2.0, y * 2.0, z * 2.0};
|
||||
int bx0, bx1, by0, by1, bz0, bz1, b00, b10, b01, b11;
|
||||
double rx0, rx1, ry0, ry1, rz0, rz1, *q, sy, sz, a, b, c, d, t, u, v;
|
||||
int i, j;
|
||||
|
||||
setup(0, bx0,bx1, rx0,rx1);
|
||||
setup(1, by0,by1, ry0,ry1);
|
||||
setup(2, bz0,bz1, rz0,rz1);
|
||||
setup(0, bx0, bx1, rx0, rx1);
|
||||
setup(1, by0, by1, ry0, ry1);
|
||||
setup(2, bz0, bz1, rz0, rz1);
|
||||
|
||||
i = p[ bx0 ];
|
||||
j = p[ bx1 ];
|
||||
i = p[bx0];
|
||||
j = p[bx1];
|
||||
|
||||
b00 = p[ i + by0 ];
|
||||
b10 = p[ j + by0 ];
|
||||
b01 = p[ i + by1 ];
|
||||
b11 = p[ j + by1 ];
|
||||
b00 = p[i + by0];
|
||||
b10 = p[j + by0];
|
||||
b01 = p[i + by1];
|
||||
b11 = p[j + by1];
|
||||
|
||||
t = s_curve(rx0);
|
||||
t = s_curve(rx0);
|
||||
sy = s_curve(ry0);
|
||||
sz = s_curve(rz0);
|
||||
|
||||
#define at3(rx,ry,rz) ( rx * q[0] + ry * q[1] + rz * q[2] )
|
||||
#define at3(rx, ry, rz) (rx * q[0] + ry * q[1] + rz * q[2])
|
||||
|
||||
q = g3[ b00 + bz0 ] ; u = at3(rx0,ry0,rz0);
|
||||
q = g3[ b10 + bz0 ] ; v = at3(rx1,ry0,rz0);
|
||||
q = g3[b00 + bz0];
|
||||
u = at3(rx0, ry0, rz0);
|
||||
q = g3[b10 + bz0];
|
||||
v = at3(rx1, ry0, rz0);
|
||||
a = lerp(t, u, v);
|
||||
|
||||
q = g3[ b01 + bz0 ] ; u = at3(rx0,ry1,rz0);
|
||||
q = g3[ b11 + bz0 ] ; v = at3(rx1,ry1,rz0);
|
||||
q = g3[b01 + bz0];
|
||||
u = at3(rx0, ry1, rz0);
|
||||
q = g3[b11 + bz0];
|
||||
v = at3(rx1, ry1, rz0);
|
||||
b = lerp(t, u, v);
|
||||
|
||||
c = lerp(sy, a, b);
|
||||
|
||||
q = g3[ b00 + bz1 ] ; u = at3(rx0,ry0,rz1);
|
||||
q = g3[ b10 + bz1 ] ; v = at3(rx1,ry0,rz1);
|
||||
q = g3[b00 + bz1];
|
||||
u = at3(rx0, ry0, rz1);
|
||||
q = g3[b10 + bz1];
|
||||
v = at3(rx1, ry0, rz1);
|
||||
a = lerp(t, u, v);
|
||||
|
||||
q = g3[ b01 + bz1 ] ; u = at3(rx0,ry1,rz1);
|
||||
q = g3[ b11 + bz1 ] ; v = at3(rx1,ry1,rz1);
|
||||
q = g3[b01 + bz1];
|
||||
u = at3(rx0, ry1, rz1);
|
||||
q = g3[b11 + bz1];
|
||||
v = at3(rx1, ry1, rz1);
|
||||
b = lerp(t, u, v);
|
||||
|
||||
d = lerp(sy, a, b);
|
||||
|
@ -134,8 +142,7 @@ double noisePerlinGet3DValue(double x, double y, double z)
|
|||
return lerp(sz, c, d) * 0.661 + 0.5;
|
||||
}
|
||||
|
||||
static void _normalize2(double v[2])
|
||||
{
|
||||
static void _normalize2(double v[2]) {
|
||||
double s;
|
||||
|
||||
s = sqrt(v[0] * v[0] + v[1] * v[1]);
|
||||
|
@ -143,8 +150,7 @@ static void _normalize2(double v[2])
|
|||
v[1] = v[1] / s;
|
||||
}
|
||||
|
||||
static void _normalize3(double v[3])
|
||||
{
|
||||
static void _normalize3(double v[3]) {
|
||||
double s;
|
||||
|
||||
s = sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]);
|
||||
|
@ -153,20 +159,19 @@ static void _normalize3(double v[3])
|
|||
v[2] = v[2] / s;
|
||||
}
|
||||
|
||||
static int noisePerlinInit(void)
|
||||
{
|
||||
static int noisePerlinInit(void) {
|
||||
int i, j, k;
|
||||
|
||||
for (i = 0 ; i < B ; i++) {
|
||||
for (i = 0; i < B; i++) {
|
||||
p[i] = i;
|
||||
|
||||
g1[i] = (double)((rand() % (B + B)) - B) / B;
|
||||
|
||||
for (j = 0 ; j < 2 ; j++)
|
||||
for (j = 0; j < 2; j++)
|
||||
g2[i][j] = (double)((rand() % (B + B)) - B) / B;
|
||||
_normalize2(g2[i]);
|
||||
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
for (j = 0; j < 3; j++)
|
||||
g3[i][j] = (double)((rand() % (B + B)) - B) / B;
|
||||
_normalize3(g3[i]);
|
||||
}
|
||||
|
@ -177,12 +182,12 @@ static int noisePerlinInit(void)
|
|||
p[j] = k;
|
||||
}
|
||||
|
||||
for (i = 0 ; i < B + 2 ; i++) {
|
||||
for (i = 0; i < B + 2; i++) {
|
||||
p[B + i] = p[i];
|
||||
g1[B + i] = g1[i];
|
||||
for (j = 0 ; j < 2 ; j++)
|
||||
for (j = 0; j < 2; j++)
|
||||
g2[B + i][j] = g2[i][j];
|
||||
for (j = 0 ; j < 3 ; j++)
|
||||
for (j = 0; j < 3; j++)
|
||||
g3[B + i][j] = g3[i][j];
|
||||
}
|
||||
|
||||
|
|
|
@ -6,12 +6,10 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class NoiseFunctionPerlin
|
||||
{
|
||||
public:
|
||||
class NoiseFunctionPerlin {
|
||||
public:
|
||||
NoiseFunctionPerlin();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,84 +14,78 @@
|
|||
#include "Geometry.h"
|
||||
#include "Vector3.h"
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} Grad3;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
double w;
|
||||
} Grad4;
|
||||
|
||||
static Grad3 _grad3[] = {
|
||||
{1, 1, 0},
|
||||
{-1, 1, 0},
|
||||
{1, -1, 0},
|
||||
{-1, -1, 0},
|
||||
{1, 0, 1},
|
||||
{-1, 0, 1},
|
||||
{1, 0, -1},
|
||||
{-1, 0, -1},
|
||||
{0, 1, 1},
|
||||
{0, -1, 1},
|
||||
{0, 1, -1},
|
||||
{0, -1, -1}
|
||||
};
|
||||
static Grad3 _grad3[] = {{1, 1, 0},
|
||||
{-1, 1, 0},
|
||||
{1, -1, 0},
|
||||
{-1, -1, 0},
|
||||
{1, 0, 1},
|
||||
{-1, 0, 1},
|
||||
{1, 0, -1},
|
||||
{-1, 0, -1},
|
||||
{0, 1, 1},
|
||||
{0, -1, 1},
|
||||
{0, 1, -1},
|
||||
{0, -1, -1}};
|
||||
|
||||
static Grad4 _grad4[] = {
|
||||
{0, 1, 1, 1},
|
||||
{0, 1, 1, -1},
|
||||
{0, 1, -1, 1},
|
||||
{0, 1, -1, -1},
|
||||
{0, -1, 1, 1},
|
||||
{0, -1, 1, -1},
|
||||
{0, -1, -1, 1},
|
||||
{0, -1, -1, -1},
|
||||
{1, 0, 1, 1},
|
||||
{1, 0, 1, -1},
|
||||
{1, 0, -1, 1},
|
||||
{1, 0, -1, -1},
|
||||
{-1, 0, 1, 1},
|
||||
{-1, 0, 1, -1},
|
||||
{-1, 0, -1, 1},
|
||||
{-1, 0, -1, -1},
|
||||
{1, 1, 0, 1},
|
||||
{1, 1, 0, -1},
|
||||
{1, -1, 0, 1},
|
||||
{1, -1, 0, -1},
|
||||
{-1, 1, 0, 1},
|
||||
{-1, 1, 0, -1},
|
||||
{-1, -1, 0, 1},
|
||||
{-1, -1, 0, -1},
|
||||
{1, 1, 1, 0},
|
||||
{1, 1, -1, 0},
|
||||
{1, -1, 1, 0},
|
||||
{1, -1, -1, 0},
|
||||
{-1, 1, 1, 0},
|
||||
{-1, 1, -1, 0},
|
||||
{-1, -1, 1, 0},
|
||||
{-1, -1, -1, 0}
|
||||
};
|
||||
static Grad4 _grad4[] = {{0, 1, 1, 1},
|
||||
{0, 1, 1, -1},
|
||||
{0, 1, -1, 1},
|
||||
{0, 1, -1, -1},
|
||||
{0, -1, 1, 1},
|
||||
{0, -1, 1, -1},
|
||||
{0, -1, -1, 1},
|
||||
{0, -1, -1, -1},
|
||||
{1, 0, 1, 1},
|
||||
{1, 0, 1, -1},
|
||||
{1, 0, -1, 1},
|
||||
{1, 0, -1, -1},
|
||||
{-1, 0, 1, 1},
|
||||
{-1, 0, 1, -1},
|
||||
{-1, 0, -1, 1},
|
||||
{-1, 0, -1, -1},
|
||||
{1, 1, 0, 1},
|
||||
{1, 1, 0, -1},
|
||||
{1, -1, 0, 1},
|
||||
{1, -1, 0, -1},
|
||||
{-1, 1, 0, 1},
|
||||
{-1, 1, 0, -1},
|
||||
{-1, -1, 0, 1},
|
||||
{-1, -1, 0, -1},
|
||||
{1, 1, 1, 0},
|
||||
{1, 1, -1, 0},
|
||||
{1, -1, 1, 0},
|
||||
{1, -1, -1, 0},
|
||||
{-1, 1, 1, 0},
|
||||
{-1, 1, -1, 0},
|
||||
{-1, -1, 1, 0},
|
||||
{-1, -1, -1, 0}};
|
||||
|
||||
static short _permutations[] = {151, 160, 137, 91, 90, 15,
|
||||
131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, 23,
|
||||
190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33,
|
||||
88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166,
|
||||
77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244,
|
||||
102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89, 18, 169, 200, 196,
|
||||
135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123,
|
||||
5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42,
|
||||
223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
|
||||
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228,
|
||||
251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107,
|
||||
49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254,
|
||||
138, 236, 205, 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};
|
||||
static short _permutations[] = {
|
||||
151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142,
|
||||
8, 99, 37, 240, 21, 10, 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203,
|
||||
117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, 174, 20, 125, 136, 171, 168, 68, 175, 74, 165,
|
||||
71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, 133, 230, 220, 105, 92, 41,
|
||||
55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, 89,
|
||||
18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250,
|
||||
124, 123, 5, 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189,
|
||||
28, 42, 223, 183, 170, 213, 119, 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9,
|
||||
129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, 178, 185, 112, 104, 218, 246, 97, 228, 251, 34,
|
||||
242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, 14, 239, 107, 49, 192, 214, 31,
|
||||
181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, 93, 222, 114,
|
||||
67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180};
|
||||
static short _permutations2[512];
|
||||
static short _permutationsMod12[512];
|
||||
|
||||
|
@ -102,36 +96,30 @@ static double _G3;
|
|||
static double _F4;
|
||||
static double _G4;
|
||||
|
||||
static inline int _fastfloor(double x)
|
||||
{
|
||||
int xi = (int) x;
|
||||
static inline int _fastfloor(double x) {
|
||||
int xi = (int)x;
|
||||
return x < xi ? xi - 1 : xi;
|
||||
}
|
||||
|
||||
static inline double _dot2(Grad3 g, double x, double y)
|
||||
{
|
||||
static inline double _dot2(Grad3 g, double x, double y) {
|
||||
return g.x * x + g.y * y;
|
||||
}
|
||||
|
||||
static inline double _dot3(Grad3 g, double x, double y, double z)
|
||||
{
|
||||
static inline double _dot3(Grad3 g, double x, double y, double z) {
|
||||
return g.x * x + g.y * y + g.z * z;
|
||||
}
|
||||
|
||||
static inline double _dot4(Grad4 g, double x, double y, double z, double w)
|
||||
{
|
||||
static inline double _dot4(Grad4 g, double x, double y, double z, double w) {
|
||||
return g.x * x + g.y * y + g.z * z + g.w * w;
|
||||
}
|
||||
|
||||
static int noiseSimplexInit()
|
||||
{
|
||||
static int noiseSimplexInit() {
|
||||
int i;
|
||||
|
||||
/* To remove the need for index wrapping, double the permutation table length */
|
||||
for (i = 0; i < 512; i++)
|
||||
{
|
||||
for (i = 0; i < 512; i++) {
|
||||
_permutations2[i] = _permutations[i & 255];
|
||||
_permutationsMod12[i] = (short) (_permutations2[i] % 12);
|
||||
_permutationsMod12[i] = (short)(_permutations2[i] % 12);
|
||||
}
|
||||
|
||||
/* Skewing and unskewing factors for 2, 3, and 4 dimensions */
|
||||
|
@ -147,14 +135,12 @@ static int noiseSimplexInit()
|
|||
|
||||
static int _inited = noiseSimplexInit();
|
||||
|
||||
double noiseSimplexGet1DValue(double x)
|
||||
{
|
||||
double noiseSimplexGet1DValue(double x) {
|
||||
/* TODO Find custom function */
|
||||
return noiseSimplexGet2DValue(x, 0.0);
|
||||
}
|
||||
|
||||
double noiseSimplexGet2DValue(double x, double y)
|
||||
{
|
||||
double noiseSimplexGet2DValue(double x, double y) {
|
||||
double n0, n1, n2; /* Noise contributions from the three corners */
|
||||
/* Skew the input space to determine which simplex cell we're in */
|
||||
double s = (x + y) * _F2; /* Hairy factor for 2D */
|
||||
|
@ -168,19 +154,17 @@ double noiseSimplexGet2DValue(double x, double y)
|
|||
/* For the 2D case, the simplex shape is an equilateral triangle.
|
||||
Determine which simplex we are in. */
|
||||
int i1, j1; /* Offsets for second (middle) corner of simplex in (i,j) coords */
|
||||
if (x0 > y0)
|
||||
{
|
||||
if (x0 > y0) {
|
||||
i1 = 1;
|
||||
j1 = 0;
|
||||
} /* lower triangle, XY order: (0,0)->(1,0)->(1,1) */
|
||||
else
|
||||
{
|
||||
else {
|
||||
i1 = 0;
|
||||
j1 = 1;
|
||||
} /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
|
||||
/* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
c = (3-sqrt(3))/6 */
|
||||
} /* upper triangle, YX order: (0,0)->(0,1)->(1,1) */
|
||||
/* A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
|
||||
a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
|
||||
c = (3-sqrt(3))/6 */
|
||||
double x1 = x0 - i1 + _G2; /* Offsets for middle corner in (x,y) unskewed coords */
|
||||
double y1 = y0 - j1 + _G2;
|
||||
double x2 = x0 - 1.0 + 2.0 * _G2; /* Offsets for last corner in (x,y) unskewed coords */
|
||||
|
@ -192,24 +176,24 @@ double noiseSimplexGet2DValue(double x, double y)
|
|||
int gi1 = _permutationsMod12[ii + i1 + _permutations2[jj + j1]];
|
||||
int gi2 = _permutationsMod12[ii + 1 + _permutations2[jj + 1]];
|
||||
/* Calculate the contribution from the three corners */
|
||||
double t0 = 0.5 - x0 * x0 - y0*y0;
|
||||
if (t0 < 0) n0 = 0.0;
|
||||
else
|
||||
{
|
||||
double t0 = 0.5 - x0 * x0 - y0 * y0;
|
||||
if (t0 < 0)
|
||||
n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * _dot2(_grad3[gi0], x0, y0); /* (x,y) of _grad3 used for 2D gradient */
|
||||
}
|
||||
double t1 = 0.5 - x1 * x1 - y1*y1;
|
||||
if (t1 < 0) n1 = 0.0;
|
||||
else
|
||||
{
|
||||
double t1 = 0.5 - x1 * x1 - y1 * y1;
|
||||
if (t1 < 0)
|
||||
n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * _dot2(_grad3[gi1], x1, y1);
|
||||
}
|
||||
double t2 = 0.5 - x2 * x2 - y2*y2;
|
||||
if (t2 < 0) n2 = 0.0;
|
||||
else
|
||||
{
|
||||
double t2 = 0.5 - x2 * x2 - y2 * y2;
|
||||
if (t2 < 0)
|
||||
n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * _dot2(_grad3[gi2], x2, y2);
|
||||
}
|
||||
|
@ -218,8 +202,7 @@ double noiseSimplexGet2DValue(double x, double y)
|
|||
return 35.0 * (n0 + n1 + n2) + 0.5;
|
||||
}
|
||||
|
||||
double noiseSimplexGet3DValue(double x, double y, double z)
|
||||
{
|
||||
double noiseSimplexGet3DValue(double x, double y, double z) {
|
||||
double n0, n1, n2, n3; /* Noise contributions from the four corners */
|
||||
/* Skew the input space to determine which simplex cell we're in */
|
||||
double s = (x + y + z) * _F3; /* Very nice and simple skew factor for 3D */
|
||||
|
@ -237,10 +220,8 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
Determine which simplex we are in. */
|
||||
int i1, j1, k1; /* Offsets for second corner of simplex in (i,j,k) coords */
|
||||
int i2, j2, k2; /* Offsets for third corner of simplex in (i,j,k) coords */
|
||||
if (x0 >= y0)
|
||||
{
|
||||
if (y0 >= z0)
|
||||
{
|
||||
if (x0 >= y0) {
|
||||
if (y0 >= z0) {
|
||||
i1 = 1;
|
||||
j1 = 0;
|
||||
k1 = 0;
|
||||
|
@ -248,8 +229,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
j2 = 1;
|
||||
k2 = 0;
|
||||
} /* X Y Z order */
|
||||
else if (x0 >= z0)
|
||||
{
|
||||
else if (x0 >= z0) {
|
||||
i1 = 1;
|
||||
j1 = 0;
|
||||
k1 = 0;
|
||||
|
@ -257,20 +237,16 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
j2 = 0;
|
||||
k2 = 1;
|
||||
} /* X Z Y order */
|
||||
else
|
||||
{
|
||||
else {
|
||||
i1 = 0;
|
||||
j1 = 0;
|
||||
k1 = 1;
|
||||
i2 = 1;
|
||||
j2 = 0;
|
||||
k2 = 1;
|
||||
} /* Z X Y order */
|
||||
}
|
||||
else
|
||||
{ /* x0<y0 */
|
||||
if (y0 < z0)
|
||||
{
|
||||
} /* Z X Y order */
|
||||
} else { /* x0<y0 */
|
||||
if (y0 < z0) {
|
||||
i1 = 0;
|
||||
j1 = 0;
|
||||
k1 = 1;
|
||||
|
@ -278,8 +254,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
j2 = 1;
|
||||
k2 = 1;
|
||||
} /* Z Y X order */
|
||||
else if (x0 < z0)
|
||||
{
|
||||
else if (x0 < z0) {
|
||||
i1 = 0;
|
||||
j1 = 1;
|
||||
k1 = 0;
|
||||
|
@ -287,8 +262,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
j2 = 1;
|
||||
k2 = 1;
|
||||
} /* Y Z X order */
|
||||
else
|
||||
{
|
||||
else {
|
||||
i1 = 0;
|
||||
j1 = 1;
|
||||
k1 = 0;
|
||||
|
@ -319,31 +293,31 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
int gi2 = _permutationsMod12[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2]]];
|
||||
int gi3 = _permutationsMod12[ii + 1 + _permutations2[jj + 1 + _permutations2[kk + 1]]];
|
||||
/* Calculate the contribution from the four corners */
|
||||
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0*z0;
|
||||
if (t0 < 0) n0 = 0.0;
|
||||
else
|
||||
{
|
||||
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
|
||||
if (t0 < 0)
|
||||
n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * _dot3(_grad3[gi0], x0, y0, z0);
|
||||
}
|
||||
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1*z1;
|
||||
if (t1 < 0) n1 = 0.0;
|
||||
else
|
||||
{
|
||||
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
|
||||
if (t1 < 0)
|
||||
n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * _dot3(_grad3[gi1], x1, y1, z1);
|
||||
}
|
||||
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2*z2;
|
||||
if (t2 < 0) n2 = 0.0;
|
||||
else
|
||||
{
|
||||
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
|
||||
if (t2 < 0)
|
||||
n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * _dot3(_grad3[gi2], x2, y2, z2);
|
||||
}
|
||||
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3*z3;
|
||||
if (t3 < 0) n3 = 0.0;
|
||||
else
|
||||
{
|
||||
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
|
||||
if (t3 < 0)
|
||||
n3 = 0.0;
|
||||
else {
|
||||
t3 *= t3;
|
||||
n3 = t3 * t3 * _dot3(_grad3[gi3], x3, y3, z3);
|
||||
}
|
||||
|
@ -352,8 +326,7 @@ double noiseSimplexGet3DValue(double x, double y, double z)
|
|||
return 16.0 * (n0 + n1 + n2 + n3) + 0.5;
|
||||
}
|
||||
|
||||
double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
||||
{
|
||||
double noiseSimplexGet4DValue(double x, double y, double z, double w) {
|
||||
double n0, n1, n2, n3, n4; /* Noise contributions from the five corners */
|
||||
/* Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in */
|
||||
double s = (x + y + z + w) * _F4; /* Factor for 4D skewing */
|
||||
|
@ -362,7 +335,7 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
|||
int k = _fastfloor(z + s);
|
||||
int l = _fastfloor(w + s);
|
||||
double t = (i + j + k + l) * _G4; /* Factor for 4D unskewing */
|
||||
double X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */
|
||||
double X0 = i - t; /* Unskew the cell origin back to (x,y,z,w) space */
|
||||
double Y0 = j - t;
|
||||
double Z0 = k - t;
|
||||
double W0 = l - t;
|
||||
|
@ -379,26 +352,38 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
|||
int ranky = 0;
|
||||
int rankz = 0;
|
||||
int rankw = 0;
|
||||
if (x0 > y0) rankx++;
|
||||
else ranky++;
|
||||
if (x0 > z0) rankx++;
|
||||
else rankz++;
|
||||
if (x0 > w0) rankx++;
|
||||
else rankw++;
|
||||
if (y0 > z0) ranky++;
|
||||
else rankz++;
|
||||
if (y0 > w0) ranky++;
|
||||
else rankw++;
|
||||
if (z0 > w0) rankz++;
|
||||
else rankw++;
|
||||
if (x0 > y0)
|
||||
rankx++;
|
||||
else
|
||||
ranky++;
|
||||
if (x0 > z0)
|
||||
rankx++;
|
||||
else
|
||||
rankz++;
|
||||
if (x0 > w0)
|
||||
rankx++;
|
||||
else
|
||||
rankw++;
|
||||
if (y0 > z0)
|
||||
ranky++;
|
||||
else
|
||||
rankz++;
|
||||
if (y0 > w0)
|
||||
ranky++;
|
||||
else
|
||||
rankw++;
|
||||
if (z0 > w0)
|
||||
rankz++;
|
||||
else
|
||||
rankw++;
|
||||
int i1, j1, k1, l1; /* The integer offsets for the second simplex corner */
|
||||
int i2, j2, k2, l2; /* The integer offsets for the third simplex corner */
|
||||
int i3, j3, k3, l3; /* The integer offsets for the fourth simplex corner */
|
||||
/* simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
|
||||
Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
|
||||
impossible. Only the 24 indices which have non-zero entries make any sense.
|
||||
We use a thresholding to set the coordinates in turn from the largest magnitude.
|
||||
Rank 3 denotes the largest coordinate. */
|
||||
/* simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
|
||||
Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
|
||||
impossible. Only the 24 indices which have non-zero entries make any sense.
|
||||
We use a thresholding to set the coordinates in turn from the largest magnitude.
|
||||
Rank 3 denotes the largest coordinate. */
|
||||
i1 = rankx >= 3 ? 1 : 0;
|
||||
j1 = ranky >= 3 ? 1 : 0;
|
||||
k1 = rankz >= 3 ? 1 : 0;
|
||||
|
@ -436,43 +421,46 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
|||
int kk = k & 255;
|
||||
int ll = l & 255;
|
||||
int gi0 = _permutations2[ii + _permutations2[jj + _permutations2[kk + _permutations2[ll]]]] % 32;
|
||||
int gi1 = _permutations2[ii + i1 + _permutations2[jj + j1 + _permutations2[kk + k1 + _permutations2[ll + l1]]]] % 32;
|
||||
int gi2 = _permutations2[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2 + _permutations2[ll + l2]]]] % 32;
|
||||
int gi3 = _permutations2[ii + i3 + _permutations2[jj + j3 + _permutations2[kk + k3 + _permutations2[ll + l3]]]] % 32;
|
||||
int gi1 =
|
||||
_permutations2[ii + i1 + _permutations2[jj + j1 + _permutations2[kk + k1 + _permutations2[ll + l1]]]] % 32;
|
||||
int gi2 =
|
||||
_permutations2[ii + i2 + _permutations2[jj + j2 + _permutations2[kk + k2 + _permutations2[ll + l2]]]] % 32;
|
||||
int gi3 =
|
||||
_permutations2[ii + i3 + _permutations2[jj + j3 + _permutations2[kk + k3 + _permutations2[ll + l3]]]] % 32;
|
||||
int gi4 = _permutations2[ii + 1 + _permutations2[jj + 1 + _permutations2[kk + 1 + _permutations2[ll + 1]]]] % 32;
|
||||
/* Calculate the contribution from the five corners */
|
||||
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0*w0;
|
||||
if (t0 < 0) n0 = 0.0;
|
||||
else
|
||||
{
|
||||
double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
|
||||
if (t0 < 0)
|
||||
n0 = 0.0;
|
||||
else {
|
||||
t0 *= t0;
|
||||
n0 = t0 * t0 * _dot4(_grad4[gi0], x0, y0, z0, w0);
|
||||
}
|
||||
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1*w1;
|
||||
if (t1 < 0) n1 = 0.0;
|
||||
else
|
||||
{
|
||||
double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
|
||||
if (t1 < 0)
|
||||
n1 = 0.0;
|
||||
else {
|
||||
t1 *= t1;
|
||||
n1 = t1 * t1 * _dot4(_grad4[gi1], x1, y1, z1, w1);
|
||||
}
|
||||
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2*w2;
|
||||
if (t2 < 0) n2 = 0.0;
|
||||
else
|
||||
{
|
||||
double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
|
||||
if (t2 < 0)
|
||||
n2 = 0.0;
|
||||
else {
|
||||
t2 *= t2;
|
||||
n2 = t2 * t2 * _dot4(_grad4[gi2], x2, y2, z2, w2);
|
||||
}
|
||||
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3*w3;
|
||||
if (t3 < 0) n3 = 0.0;
|
||||
else
|
||||
{
|
||||
double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
|
||||
if (t3 < 0)
|
||||
n3 = 0.0;
|
||||
else {
|
||||
t3 *= t3;
|
||||
n3 = t3 * t3 * _dot4(_grad4[gi3], x3, y3, z3, w3);
|
||||
}
|
||||
double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4*w4;
|
||||
if (t4 < 0) n4 = 0.0;
|
||||
else
|
||||
{
|
||||
double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
|
||||
if (t4 < 0)
|
||||
n4 = 0.0;
|
||||
else {
|
||||
t4 *= t4;
|
||||
n4 = t4 * t4 * _dot4(_grad4[gi4], x4, y4, z4, w4);
|
||||
}
|
||||
|
@ -480,31 +468,25 @@ double noiseSimplexGet4DValue(double x, double y, double z, double w)
|
|||
return 13.5 * (n0 + n1 + n2 + n3 + n4) + 0.5;
|
||||
}
|
||||
|
||||
double NoiseFunctionSimplex::getBase2d(double x, double y) const
|
||||
{
|
||||
double NoiseFunctionSimplex::getBase2d(double x, double y) const {
|
||||
return noiseSimplexGet2DValue(x, y);
|
||||
}
|
||||
|
||||
double NoiseFunctionSimplex::getBase3d(double x, double y, double z) const
|
||||
{
|
||||
double NoiseFunctionSimplex::getBase3d(double x, double y, double z) const {
|
||||
return noiseSimplexGet3DValue(x, y, z);
|
||||
}
|
||||
|
||||
static Texture2D *_valueTexture = NULL;
|
||||
|
||||
const Texture2D *NoiseFunctionSimplex::getValueTexture()
|
||||
{
|
||||
if (!_valueTexture)
|
||||
{
|
||||
const Texture2D *NoiseFunctionSimplex::getValueTexture() {
|
||||
if (!_valueTexture) {
|
||||
const int width = 1024;
|
||||
const int height = 1024;
|
||||
|
||||
_valueTexture = new Texture2D(width, height);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int z = 0; z < height; z++)
|
||||
{
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < height; z++) {
|
||||
double val = noiseSimplexGet2DValue((double)x, (double)z);
|
||||
_valueTexture->setPixel(x, z, Color(val, val, val));
|
||||
}
|
||||
|
@ -516,27 +498,21 @@ const Texture2D *NoiseFunctionSimplex::getValueTexture()
|
|||
|
||||
static Texture2D *_normalTexture = NULL;
|
||||
|
||||
const Texture2D *NoiseFunctionSimplex::getNormalTexture()
|
||||
{
|
||||
if (!_normalTexture)
|
||||
{
|
||||
const Texture2D *NoiseFunctionSimplex::getNormalTexture() {
|
||||
if (!_normalTexture) {
|
||||
const int width = 1024;
|
||||
const int height = 1024;
|
||||
|
||||
_normalTexture = new Texture2D(width, height);
|
||||
|
||||
for (int x = 0; x < width; x++)
|
||||
{
|
||||
for (int z = 0; z < height; z++)
|
||||
{
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int z = 0; z < height; z++) {
|
||||
double vcenter = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z);
|
||||
double vsouth = noiseSimplexGet2DValue(0.01 * (double)x, 0.01 * (double)z + 0.001);
|
||||
double veast = noiseSimplexGet2DValue(0.01 * (double)x + 0.001, 0.01 * (double)z);
|
||||
|
||||
Vector3 normal = Geometry::getNormalFromTriangle(Vector3(0.0, vcenter, 0.0),
|
||||
Vector3(0.0, vsouth, 0.01),
|
||||
Vector3(0.01, veast, 0.0)
|
||||
);
|
||||
Vector3 normal = Geometry::getNormalFromTriangle(Vector3(0.0, vcenter, 0.0), Vector3(0.0, vsouth, 0.01),
|
||||
Vector3(0.01, veast, 0.0));
|
||||
|
||||
_normalTexture->setPixel(x, z, Color(normal.x, normal.y, normal.z));
|
||||
}
|
||||
|
|
|
@ -8,16 +8,14 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class NoiseFunctionSimplex:public FractalNoise
|
||||
{
|
||||
class NoiseFunctionSimplex : public FractalNoise {
|
||||
virtual double getBase2d(double x, double y) const override;
|
||||
virtual double getBase3d(double x, double y, double z) const override;
|
||||
|
||||
public:
|
||||
public:
|
||||
static const Texture2D *getValueTexture();
|
||||
static const Texture2D *getNormalTexture();
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,8 +13,7 @@
|
|||
|
||||
/* NoiseGenerator class */
|
||||
|
||||
NoiseGenerator::NoiseGenerator()
|
||||
{
|
||||
NoiseGenerator::NoiseGenerator() {
|
||||
function.algorithm = NOISE_FUNCTION_SIMPLEX;
|
||||
function.ridge_factor = 0.0;
|
||||
function.curve_factor = 0.0;
|
||||
|
@ -25,12 +24,10 @@ NoiseGenerator::NoiseGenerator()
|
|||
validate();
|
||||
}
|
||||
|
||||
NoiseGenerator::~NoiseGenerator()
|
||||
{
|
||||
NoiseGenerator::~NoiseGenerator() {
|
||||
}
|
||||
|
||||
void NoiseGenerator::save(PackStream* stream) const
|
||||
{
|
||||
void NoiseGenerator::save(PackStream *stream) const {
|
||||
int x;
|
||||
|
||||
x = (int)function.algorithm;
|
||||
|
@ -41,9 +38,8 @@ void NoiseGenerator::save(PackStream* stream) const
|
|||
stream->write(&height_offset);
|
||||
stream->write(&level_count);
|
||||
|
||||
for (x = 0; x < level_count; x++)
|
||||
{
|
||||
const NoiseLevel* level = levels + x;
|
||||
for (x = 0; x < level_count; x++) {
|
||||
const NoiseLevel *level = levels + x;
|
||||
|
||||
stream->write(&level->frequency);
|
||||
stream->write(&level->amplitude);
|
||||
|
@ -53,8 +49,7 @@ void NoiseGenerator::save(PackStream* stream) const
|
|||
state.save(stream);
|
||||
}
|
||||
|
||||
void NoiseGenerator::load(PackStream* stream)
|
||||
{
|
||||
void NoiseGenerator::load(PackStream *stream) {
|
||||
int x;
|
||||
|
||||
stream->read(&x);
|
||||
|
@ -65,14 +60,12 @@ void NoiseGenerator::load(PackStream* stream)
|
|||
stream->read(&height_offset);
|
||||
stream->read(&level_count);
|
||||
|
||||
if (level_count > MAX_LEVEL_COUNT)
|
||||
{
|
||||
if (level_count > MAX_LEVEL_COUNT) {
|
||||
level_count = MAX_LEVEL_COUNT;
|
||||
}
|
||||
|
||||
for (x = 0; x < level_count; x++)
|
||||
{
|
||||
NoiseLevel* level = levels + x;
|
||||
for (x = 0; x < level_count; x++) {
|
||||
NoiseLevel *level = levels + x;
|
||||
|
||||
stream->read(&level->frequency);
|
||||
stream->read(&level->amplitude);
|
||||
|
@ -84,8 +77,7 @@ void NoiseGenerator::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
void NoiseGenerator::copy(NoiseGenerator* destination) const
|
||||
{
|
||||
void NoiseGenerator::copy(NoiseGenerator *destination) const {
|
||||
destination->function = function;
|
||||
destination->height_offset = height_offset;
|
||||
destination->level_count = level_count;
|
||||
|
@ -97,16 +89,13 @@ void NoiseGenerator::copy(NoiseGenerator* destination) const
|
|||
destination->validate();
|
||||
}
|
||||
|
||||
void NoiseGenerator::validate()
|
||||
{
|
||||
void NoiseGenerator::validate() {
|
||||
int x;
|
||||
|
||||
if (function.algorithm < 0 || function.algorithm > NOISE_FUNCTION_SIMPLEX)
|
||||
{
|
||||
if (function.algorithm < 0 || function.algorithm > NOISE_FUNCTION_SIMPLEX) {
|
||||
function.algorithm = NOISE_FUNCTION_SIMPLEX;
|
||||
}
|
||||
switch (function.algorithm)
|
||||
{
|
||||
switch (function.algorithm) {
|
||||
case NOISE_FUNCTION_PERLIN:
|
||||
_func_noise_1d = noisePerlinGet1DValue;
|
||||
_func_noise_2d = noisePerlinGet2DValue;
|
||||
|
@ -121,103 +110,86 @@ void NoiseGenerator::validate()
|
|||
break;
|
||||
}
|
||||
|
||||
if (function.ridge_factor > 0.5)
|
||||
{
|
||||
if (function.ridge_factor > 0.5) {
|
||||
function.ridge_factor = 0.5;
|
||||
}
|
||||
if (function.ridge_factor < -0.5)
|
||||
{
|
||||
if (function.ridge_factor < -0.5) {
|
||||
function.ridge_factor = -0.5;
|
||||
}
|
||||
if (function.curve_factor > 1.0)
|
||||
{
|
||||
if (function.curve_factor > 1.0) {
|
||||
function.curve_factor = 1.0;
|
||||
}
|
||||
if (function.curve_factor < -1.0)
|
||||
{
|
||||
if (function.curve_factor < -1.0) {
|
||||
function.curve_factor = -1.0;
|
||||
}
|
||||
|
||||
_min_value = height_offset;
|
||||
_max_value = height_offset;
|
||||
for (x = 0; x < level_count; x++)
|
||||
{
|
||||
for (x = 0; x < level_count; x++) {
|
||||
_min_value += levels[x].minvalue;
|
||||
_max_value += levels[x].minvalue + levels[x].amplitude;
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseGenerator::setState(const NoiseState &state)
|
||||
{
|
||||
void NoiseGenerator::setState(const NoiseState &state) {
|
||||
state.copy(&this->state);
|
||||
}
|
||||
|
||||
void NoiseGenerator::randomizeOffsets()
|
||||
{
|
||||
void NoiseGenerator::randomizeOffsets() {
|
||||
state.randomizeOffsets();
|
||||
}
|
||||
|
||||
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction()
|
||||
{
|
||||
NoiseGenerator::NoiseFunction NoiseGenerator::getFunction() {
|
||||
return function;
|
||||
}
|
||||
|
||||
void NoiseGenerator::setFunction(NoiseFunction* function)
|
||||
{
|
||||
void NoiseGenerator::setFunction(NoiseFunction *function) {
|
||||
this->function = *function;
|
||||
validate();
|
||||
}
|
||||
|
||||
void NoiseGenerator::setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y), double (*func3d)(double x, double y, double z))
|
||||
{
|
||||
void NoiseGenerator::setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
|
||||
double (*func3d)(double x, double y, double z)) {
|
||||
_func_noise_1d = func1d;
|
||||
_func_noise_2d = func2d;
|
||||
_func_noise_3d = func3d;
|
||||
function.algorithm = NOISE_FUNCTION_CUSTOM;
|
||||
}
|
||||
|
||||
void NoiseGenerator::setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor)
|
||||
{
|
||||
void NoiseGenerator::setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor) {
|
||||
NoiseFunction function = {algorithm, ridge_factor, curve_factor};
|
||||
setFunction(&function);
|
||||
}
|
||||
|
||||
void NoiseGenerator::forceValue(double value)
|
||||
{
|
||||
void NoiseGenerator::forceValue(double value) {
|
||||
clearLevels();
|
||||
height_offset = value;
|
||||
addLevelSimple(1.0, 0.0, 0.0); /* FIXME Should not be needed */
|
||||
}
|
||||
|
||||
void NoiseGenerator::getRange(double* minvalue, double* maxvalue) const
|
||||
{
|
||||
void NoiseGenerator::getRange(double *minvalue, double *maxvalue) const {
|
||||
*minvalue = _min_value;
|
||||
*maxvalue = _max_value;
|
||||
}
|
||||
|
||||
int NoiseGenerator::getLevelCount() const
|
||||
{
|
||||
int NoiseGenerator::getLevelCount() const {
|
||||
return level_count;
|
||||
}
|
||||
|
||||
void NoiseGenerator::clearLevels()
|
||||
{
|
||||
void NoiseGenerator::clearLevels() {
|
||||
level_count = 0;
|
||||
validate();
|
||||
}
|
||||
|
||||
void NoiseGenerator::addLevel(NoiseLevel level)
|
||||
{
|
||||
if (level_count < MAX_LEVEL_COUNT)
|
||||
{
|
||||
void NoiseGenerator::addLevel(NoiseLevel level) {
|
||||
if (level_count < MAX_LEVEL_COUNT) {
|
||||
levels[level_count] = level;
|
||||
level_count++;
|
||||
validate();
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxvalue)
|
||||
{
|
||||
void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxvalue) {
|
||||
NoiseLevel level;
|
||||
|
||||
level.frequency = 1.0 / scaling;
|
||||
|
@ -227,12 +199,11 @@ void NoiseGenerator::addLevelSimple(double scaling, double minvalue, double maxv
|
|||
addLevel(level);
|
||||
}
|
||||
|
||||
void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor)
|
||||
{
|
||||
void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor,
|
||||
double center_factor) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < level_count; i++)
|
||||
{
|
||||
for (i = 0; i < level_count; i++) {
|
||||
addLevel(start_level);
|
||||
start_level.minvalue += start_level.amplitude * (1.0 - amplitude_factor) * center_factor;
|
||||
start_level.frequency /= scaling_factor;
|
||||
|
@ -240,8 +211,8 @@ void NoiseGenerator::addLevels(int level_count, NoiseLevel start_level, double s
|
|||
}
|
||||
}
|
||||
|
||||
void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue, double center_factor)
|
||||
{
|
||||
void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue,
|
||||
double center_factor) {
|
||||
NoiseLevel level;
|
||||
|
||||
level.frequency = 1.0 / scaling;
|
||||
|
@ -250,12 +221,9 @@ void NoiseGenerator::addLevelsSimple(int level_count, double scaling, double min
|
|||
addLevels(level_count, level, 0.5, 0.5, center_factor);
|
||||
}
|
||||
|
||||
void NoiseGenerator::removeLevel(int level)
|
||||
{
|
||||
if (level >= 0 && level < level_count)
|
||||
{
|
||||
if (level_count > 1 && level < level_count - 1)
|
||||
{
|
||||
void NoiseGenerator::removeLevel(int level) {
|
||||
if (level >= 0 && level < level_count) {
|
||||
if (level_count > 1 && level < level_count - 1) {
|
||||
memmove(levels + level, levels + level + 1, sizeof(NoiseLevel) * (level_count - level - 1));
|
||||
}
|
||||
level_count--;
|
||||
|
@ -263,30 +231,23 @@ void NoiseGenerator::removeLevel(int level)
|
|||
}
|
||||
}
|
||||
|
||||
int NoiseGenerator::getLevel(int level, NoiseLevel* params) const
|
||||
{
|
||||
if (level >= 0 && level < level_count)
|
||||
{
|
||||
int NoiseGenerator::getLevel(int level, NoiseLevel *params) const {
|
||||
if (level >= 0 && level < level_count) {
|
||||
*params = levels[level];
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseGenerator::setLevel(int index, NoiseLevel level)
|
||||
{
|
||||
if (index >= 0 && index < level_count)
|
||||
{
|
||||
void NoiseGenerator::setLevel(int index, NoiseLevel level) {
|
||||
if (index >= 0 && index < level_count) {
|
||||
levels[index] = level;
|
||||
validate();
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue, double maxvalue)
|
||||
{
|
||||
void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue, double maxvalue) {
|
||||
NoiseLevel level;
|
||||
|
||||
level.frequency = 1.0 / scaling;
|
||||
|
@ -296,14 +257,12 @@ void NoiseGenerator::setLevelSimple(int index, double scaling, double minvalue,
|
|||
setLevel(index, level);
|
||||
}
|
||||
|
||||
void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling)
|
||||
{
|
||||
void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling) {
|
||||
int level;
|
||||
double current_minvalue, current_maxvalue, current_amplitude;
|
||||
double target_amplitude, factor;
|
||||
|
||||
if (level_count == 0)
|
||||
{
|
||||
if (level_count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -312,12 +271,10 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
|
|||
current_amplitude = current_maxvalue - current_minvalue;
|
||||
factor = target_amplitude / current_amplitude;
|
||||
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
levels[level].minvalue *= factor;
|
||||
levels[level].amplitude *= factor;
|
||||
if (adjust_scaling)
|
||||
{
|
||||
if (adjust_scaling) {
|
||||
levels[level].frequency /= factor;
|
||||
}
|
||||
}
|
||||
|
@ -325,36 +282,24 @@ void NoiseGenerator::normalizeAmplitude(double minvalue, double maxvalue, int ad
|
|||
validate();
|
||||
}
|
||||
|
||||
static inline double _fixValue(double value, double ridge, double curve)
|
||||
{
|
||||
if (value < 0.0)
|
||||
{
|
||||
static inline double _fixValue(double value, double ridge, double curve) {
|
||||
if (value < 0.0) {
|
||||
value = 0.0;
|
||||
}
|
||||
else if (value > 1.0)
|
||||
{
|
||||
} else if (value > 1.0) {
|
||||
value = 1.0;
|
||||
}
|
||||
|
||||
if (curve > 0.0)
|
||||
{
|
||||
if (curve > 0.0) {
|
||||
value = value * (1.0 - curve) + sqrt(value) * curve;
|
||||
}
|
||||
else if (curve < 0.0)
|
||||
{
|
||||
} else if (curve < 0.0) {
|
||||
value = value * (1.0 - curve) + value * value * curve;
|
||||
}
|
||||
|
||||
if (ridge > 0.0)
|
||||
{
|
||||
if (ridge > 0.0) {
|
||||
return fabs(value - ridge) / (1.0 - ridge);
|
||||
}
|
||||
else if (ridge < 0.0)
|
||||
{
|
||||
} else if (ridge < 0.0) {
|
||||
return 1.0 - fabs(value - 1.0 - ridge) / (1.0 + ridge);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return value;
|
||||
}
|
||||
/*if (ridge > 0.0)
|
||||
|
@ -371,55 +316,43 @@ static inline double _fixValue(double value, double ridge, double curve)
|
|||
}*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline double NoiseGenerator::_get1DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) const
|
||||
{
|
||||
return level->minvalue + _fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) * level->amplitude;
|
||||
inline double NoiseGenerator::_get1DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset,
|
||||
double x) const {
|
||||
return level->minvalue +
|
||||
_fixValue(_func_noise_1d(x * level->frequency + offset.x), function.ridge_factor, function.curve_factor) *
|
||||
level->amplitude;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get1DLevel(int level, double x) const
|
||||
{
|
||||
if (level >= 0 && level < level_count)
|
||||
{
|
||||
double NoiseGenerator::get1DLevel(int level, double x) const {
|
||||
if (level >= 0 && level < level_count) {
|
||||
return _get1DLevelValue(levels + level, state.level_offsets[level], x);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double NoiseGenerator::get1DTotal(double x) const
|
||||
{
|
||||
double NoiseGenerator::get1DTotal(double x) const {
|
||||
int level;
|
||||
double result;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
result += _get1DLevelValue(levels + level, state.level_offsets[level], x);
|
||||
}
|
||||
return result + height_offset;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get1DDetail(double x, double detail) const
|
||||
{
|
||||
double NoiseGenerator::get1DDetail(double x, double detail) const {
|
||||
int level;
|
||||
double result, height, factor;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
height = levels[level].amplitude;
|
||||
factor = 1.0;
|
||||
if (height < detail * 0.25)
|
||||
{
|
||||
if (height < detail * 0.25) {
|
||||
break;
|
||||
}
|
||||
else if (height < detail * 0.5)
|
||||
{
|
||||
} else if (height < detail * 0.5) {
|
||||
factor = (detail * 0.5 - height) / 0.25;
|
||||
}
|
||||
|
||||
|
@ -428,55 +361,44 @@ double NoiseGenerator::get1DDetail(double x, double detail) const
|
|||
return result + height_offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline double NoiseGenerator::_get2DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) const
|
||||
{
|
||||
return level->minvalue + _fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y), function.ridge_factor, function.curve_factor) * level->amplitude;
|
||||
inline double NoiseGenerator::_get2DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x,
|
||||
double y) const {
|
||||
return level->minvalue +
|
||||
_fixValue(_func_noise_2d(x * level->frequency + offset.x, y * level->frequency + offset.y),
|
||||
function.ridge_factor, function.curve_factor) *
|
||||
level->amplitude;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get2DLevel(int level, double x, double y) const
|
||||
{
|
||||
if (level >= 0 && level < level_count)
|
||||
{
|
||||
double NoiseGenerator::get2DLevel(int level, double x, double y) const {
|
||||
if (level >= 0 && level < level_count) {
|
||||
return _get2DLevelValue(levels + level, state.level_offsets[level], x, y);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double NoiseGenerator::get2DTotal(double x, double y) const
|
||||
{
|
||||
double NoiseGenerator::get2DTotal(double x, double y) const {
|
||||
int level;
|
||||
double result;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
result += _get2DLevelValue(levels + level, state.level_offsets[level], x, y);
|
||||
}
|
||||
return result + height_offset;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get2DDetail(double x, double y, double detail) const
|
||||
{
|
||||
double NoiseGenerator::get2DDetail(double x, double y, double detail) const {
|
||||
int level;
|
||||
double result, height, factor;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
height = levels[level].amplitude;
|
||||
factor = 1.0;
|
||||
if (height < detail * 0.25)
|
||||
{
|
||||
if (height < detail * 0.25) {
|
||||
break;
|
||||
}
|
||||
else if (height < detail * 0.5)
|
||||
{
|
||||
} else if (height < detail * 0.5) {
|
||||
factor = (detail * 0.5 - height) / 0.25;
|
||||
}
|
||||
|
||||
|
@ -485,55 +407,45 @@ double NoiseGenerator::get2DDetail(double x, double y, double detail) const
|
|||
return result + height_offset;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
inline double NoiseGenerator::_get3DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) const
|
||||
{
|
||||
return level->minvalue + _fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y, z * level->frequency + offset.z), function.ridge_factor, function.curve_factor) * level->amplitude;
|
||||
inline double NoiseGenerator::_get3DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x,
|
||||
double y, double z) const {
|
||||
return level->minvalue +
|
||||
_fixValue(_func_noise_3d(x * level->frequency + offset.x, y * level->frequency + offset.y,
|
||||
z * level->frequency + offset.z),
|
||||
function.ridge_factor, function.curve_factor) *
|
||||
level->amplitude;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get3DLevel(int level, double x, double y, double z) const
|
||||
{
|
||||
if (level >= 0 && level < level_count)
|
||||
{
|
||||
double NoiseGenerator::get3DLevel(int level, double x, double y, double z) const {
|
||||
if (level >= 0 && level < level_count) {
|
||||
return _get3DLevelValue(levels + level, state.level_offsets[level], x, y, z);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
double NoiseGenerator::get3DTotal(double x, double y, double z) const
|
||||
{
|
||||
double NoiseGenerator::get3DTotal(double x, double y, double z) const {
|
||||
int level;
|
||||
double result;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
result += _get3DLevelValue(levels + level, state.level_offsets[level], x, y, z);
|
||||
}
|
||||
return result + height_offset;
|
||||
}
|
||||
|
||||
double NoiseGenerator::get3DDetail(double x, double y, double z, double detail) const
|
||||
{
|
||||
double NoiseGenerator::get3DDetail(double x, double y, double z, double detail) const {
|
||||
int level;
|
||||
double result, height, factor;
|
||||
|
||||
result = 0.0;
|
||||
for (level = 0; level < level_count; level++)
|
||||
{
|
||||
for (level = 0; level < level_count; level++) {
|
||||
height = levels[level].amplitude;
|
||||
factor = 1.0;
|
||||
if (height < detail * 0.25)
|
||||
{
|
||||
if (height < detail * 0.25) {
|
||||
break;
|
||||
}
|
||||
else if (height < detail * 0.5)
|
||||
{
|
||||
} else if (height < detail * 0.5) {
|
||||
factor = (detail * 0.5 - height) / 0.25;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,57 +9,53 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT NoiseGenerator
|
||||
{
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
NOISE_FUNCTION_PERLIN,
|
||||
NOISE_FUNCTION_SIMPLEX,
|
||||
NOISE_FUNCTION_CUSTOM
|
||||
} NoiseFunctionAlgorithm;
|
||||
class BASICSSHARED_EXPORT NoiseGenerator {
|
||||
public:
|
||||
typedef enum { NOISE_FUNCTION_PERLIN, NOISE_FUNCTION_SIMPLEX, NOISE_FUNCTION_CUSTOM } NoiseFunctionAlgorithm;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
NoiseFunctionAlgorithm algorithm;
|
||||
double ridge_factor; /* -0.5;0.5 */
|
||||
double curve_factor; /* -1.0;1.0 */
|
||||
} NoiseFunction;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double frequency;
|
||||
double amplitude;
|
||||
double minvalue;
|
||||
} NoiseLevel;
|
||||
|
||||
public:
|
||||
public:
|
||||
NoiseGenerator();
|
||||
virtual ~NoiseGenerator();
|
||||
|
||||
virtual void save(PackStream* stream) const;
|
||||
virtual void load(PackStream* stream);
|
||||
virtual void copy(NoiseGenerator* destination) const;
|
||||
virtual void save(PackStream *stream) const;
|
||||
virtual void load(PackStream *stream);
|
||||
virtual void copy(NoiseGenerator *destination) const;
|
||||
virtual void validate();
|
||||
|
||||
inline const NoiseState &getState() const {return state;}
|
||||
inline const NoiseState &getState() const {
|
||||
return state;
|
||||
}
|
||||
void setState(const NoiseState &state);
|
||||
|
||||
void randomizeOffsets();
|
||||
NoiseFunction getFunction();
|
||||
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y), double (*func3d)(double x, double y, double z));
|
||||
void setFunction(NoiseFunction* function);
|
||||
void setCustomFunction(double (*func1d)(double x), double (*func2d)(double x, double y),
|
||||
double (*func3d)(double x, double y, double z));
|
||||
void setFunction(NoiseFunction *function);
|
||||
void setFunctionParams(NoiseFunctionAlgorithm algorithm, double ridge_factor, double curve_factor);
|
||||
void forceValue(double value);
|
||||
void getRange(double* minvalue, double* maxvalue) const;
|
||||
void getRange(double *minvalue, double *maxvalue) const;
|
||||
int getLevelCount() const;
|
||||
void clearLevels();
|
||||
void addLevel(NoiseLevel level);
|
||||
void addLevelSimple(double scaling, double minvalue, double maxvalue);
|
||||
void addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor, double center_factor);
|
||||
void addLevels(int level_count, NoiseLevel start_level, double scaling_factor, double amplitude_factor,
|
||||
double center_factor);
|
||||
void addLevelsSimple(int level_count, double scaling, double minvalue, double maxvalue, double center_factor);
|
||||
void removeLevel(int level);
|
||||
int getLevel(int level, NoiseLevel* params) const;
|
||||
int getLevel(int level, NoiseLevel *params) const;
|
||||
void setLevel(int index, NoiseLevel level);
|
||||
void setLevelSimple(int index, double scaling, double minvalue, double maxvalue);
|
||||
void normalizeAmplitude(double minvalue, double maxvalue, int adjust_scaling);
|
||||
|
@ -73,10 +69,11 @@ public:
|
|||
double get3DTotal(double x, double y, double z) const;
|
||||
double get3DDetail(double x, double y, double z, double detail) const;
|
||||
|
||||
private:
|
||||
double _get1DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x) const;
|
||||
double _get2DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y) const;
|
||||
double _get3DLevelValue(const NoiseLevel* level, const NoiseState::NoiseOffset &offset, double x, double y, double z) const;
|
||||
private:
|
||||
double _get1DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x) const;
|
||||
double _get2DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x, double y) const;
|
||||
double _get3DLevelValue(const NoiseLevel *level, const NoiseState::NoiseOffset &offset, double x, double y,
|
||||
double z) const;
|
||||
|
||||
NoiseFunction function;
|
||||
double height_offset;
|
||||
|
@ -91,7 +88,6 @@ private:
|
|||
double (*_func_noise_2d)(double x, double y);
|
||||
double (*_func_noise_3d)(double x, double y, double z);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,40 +3,33 @@
|
|||
#include "PackStream.h"
|
||||
#include "RandomGenerator.h"
|
||||
|
||||
NoiseState::NoiseState()
|
||||
{
|
||||
for (int i = 0; i < 30; i++)
|
||||
{
|
||||
NoiseState::NoiseState() {
|
||||
for (int i = 0; i < 30; i++) {
|
||||
level_offsets.push_back(NoiseOffset());
|
||||
}
|
||||
randomizeOffsets();
|
||||
}
|
||||
|
||||
void NoiseState::save(PackStream *stream) const
|
||||
{
|
||||
void NoiseState::save(PackStream *stream) const {
|
||||
int levels = level_offsets.size();
|
||||
stream->write(&levels);
|
||||
for (const auto &level_offset:level_offsets)
|
||||
{
|
||||
for (const auto &level_offset : level_offsets) {
|
||||
stream->write(&level_offset.x);
|
||||
stream->write(&level_offset.y);
|
||||
stream->write(&level_offset.z);
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseState::load(PackStream *stream)
|
||||
{
|
||||
void NoiseState::load(PackStream *stream) {
|
||||
int levels;
|
||||
stream->read(&levels);
|
||||
level_offsets.clear();
|
||||
|
||||
if (levels > 1000)
|
||||
{
|
||||
if (levels > 1000) {
|
||||
levels = 1000;
|
||||
}
|
||||
|
||||
for (int i = 0; i < levels; i++)
|
||||
{
|
||||
for (int i = 0; i < levels; i++) {
|
||||
NoiseOffset level_offset;
|
||||
stream->read(&level_offset.x);
|
||||
stream->read(&level_offset.y);
|
||||
|
@ -45,38 +38,31 @@ void NoiseState::load(PackStream *stream)
|
|||
}
|
||||
}
|
||||
|
||||
void NoiseState::copy(NoiseState *destination) const
|
||||
{
|
||||
void NoiseState::copy(NoiseState *destination) const {
|
||||
destination->level_offsets = level_offsets;
|
||||
}
|
||||
|
||||
void NoiseState::randomizeOffsets()
|
||||
{
|
||||
for (auto &level_offset:level_offsets)
|
||||
{
|
||||
void NoiseState::randomizeOffsets() {
|
||||
for (auto &level_offset : level_offsets) {
|
||||
level_offset.x = RandomGenerator::random();
|
||||
level_offset.y = RandomGenerator::random();
|
||||
level_offset.z = RandomGenerator::random();
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseState::resetOffsets(double x, double y, double z)
|
||||
{
|
||||
for (auto &level_offset:level_offsets)
|
||||
{
|
||||
void NoiseState::resetOffsets(double x, double y, double z) {
|
||||
for (auto &level_offset : level_offsets) {
|
||||
level_offset.x = x;
|
||||
level_offset.y = y;
|
||||
level_offset.z = z;
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseState::setLevel(int level, double x, double y, double z)
|
||||
{
|
||||
void NoiseState::setLevel(int level, double x, double y, double z) {
|
||||
NoiseOffset offset = {x, y, z};
|
||||
level_offsets.at(level) = offset;
|
||||
}
|
||||
|
||||
void NoiseState::setLevelCount(int level_count)
|
||||
{
|
||||
void NoiseState::setLevelCount(int level_count) {
|
||||
level_offsets.resize(level_count);
|
||||
}
|
||||
|
|
|
@ -11,35 +11,33 @@ namespace basics {
|
|||
*
|
||||
* This state contains the noise offsets for noise layers.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT NoiseState
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT NoiseState {
|
||||
public:
|
||||
typedef struct {
|
||||
double x;
|
||||
double y;
|
||||
double z;
|
||||
} NoiseOffset;
|
||||
|
||||
public:
|
||||
public:
|
||||
NoiseState();
|
||||
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void copy(NoiseState* destination) const;
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void copy(NoiseState *destination) const;
|
||||
|
||||
void randomizeOffsets();
|
||||
void resetOffsets(double x=0.0, double y=0.0, double z=0.0);
|
||||
void resetOffsets(double x = 0.0, double y = 0.0, double z = 0.0);
|
||||
|
||||
void setLevel(int level, double x, double y, double z);
|
||||
void setLevelCount(int level_count);
|
||||
|
||||
private:
|
||||
private:
|
||||
std::vector<NoiseOffset> level_offsets;
|
||||
|
||||
friend class NoiseGenerator;
|
||||
friend class FractalNoise;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#include "SpaceGridIterator.h"
|
||||
|
||||
SpaceGridIterator::SpaceGridIterator()
|
||||
{
|
||||
SpaceGridIterator::SpaceGridIterator() {
|
||||
}
|
||||
|
|
|
@ -11,9 +11,8 @@ namespace basics {
|
|||
*
|
||||
* This may be useful for ray marching algorithms for example.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT SpaceGridIterator
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT SpaceGridIterator {
|
||||
public:
|
||||
SpaceGridIterator();
|
||||
|
||||
/**
|
||||
|
@ -23,7 +22,6 @@ public:
|
|||
*/
|
||||
virtual bool onCell(int x, int y, int z) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,54 +3,36 @@
|
|||
#include <climits>
|
||||
#include "SpaceGridIterator.h"
|
||||
|
||||
SpaceSegment::SpaceSegment(const Vector3& start, const Vector3& end):
|
||||
start(start), end(end)
|
||||
{
|
||||
SpaceSegment::SpaceSegment(const Vector3 &start, const Vector3 &end) : start(start), end(end) {
|
||||
}
|
||||
|
||||
bool SpaceSegment::intersectYInterval(double ymin, double ymax)
|
||||
{
|
||||
if (start.y > ymax)
|
||||
{
|
||||
if (end.y >= ymax)
|
||||
{
|
||||
bool SpaceSegment::intersectYInterval(double ymin, double ymax) {
|
||||
if (start.y > ymax) {
|
||||
if (end.y >= ymax) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Vector3 diff = end.sub(start);
|
||||
start = start.add(diff.scale((ymax - start.y) / diff.y));
|
||||
if (end.y < ymin)
|
||||
{
|
||||
if (end.y < ymin) {
|
||||
end = end.add(diff.scale((ymin - end.y) / diff.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (start.y < ymin)
|
||||
{
|
||||
if (end.y <= ymin)
|
||||
{
|
||||
} else if (start.y < ymin) {
|
||||
if (end.y <= ymin) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Vector3 diff = end.sub(start);
|
||||
start = start.add(diff.scale((ymin - start.y) / diff.y));
|
||||
if (end.y >= ymax)
|
||||
{
|
||||
if (end.y >= ymax) {
|
||||
end = end.add(diff.scale((ymax - end.y) / diff.y));
|
||||
}
|
||||
}
|
||||
}
|
||||
else /* start is inside layer */
|
||||
} else /* start is inside layer */
|
||||
{
|
||||
Vector3 diff = end.sub(start);
|
||||
if (end.y > ymax)
|
||||
{
|
||||
if (end.y > ymax) {
|
||||
end = start.add(diff.scale((ymax - start.y) / diff.y));
|
||||
}
|
||||
else if (end.y < ymin)
|
||||
{
|
||||
} else if (end.y < ymin) {
|
||||
end = start.add(diff.scale((ymin - start.y) / diff.y));
|
||||
}
|
||||
}
|
||||
|
@ -58,28 +40,23 @@ bool SpaceSegment::intersectYInterval(double ymin, double ymax)
|
|||
return true;
|
||||
}
|
||||
|
||||
SpaceSegment SpaceSegment::projectedOnXPlane(double x) const
|
||||
{
|
||||
SpaceSegment SpaceSegment::projectedOnXPlane(double x) const {
|
||||
return SpaceSegment(Vector3(x, start.y, start.z), Vector3(x, end.y, end.z));
|
||||
}
|
||||
|
||||
SpaceSegment SpaceSegment::projectedOnYPlane(double y) const
|
||||
{
|
||||
SpaceSegment SpaceSegment::projectedOnYPlane(double y) const {
|
||||
return SpaceSegment(Vector3(start.x, y, start.z), Vector3(end.x, y, end.z));
|
||||
}
|
||||
|
||||
SpaceSegment SpaceSegment::projectedOnZPlane(double z) const
|
||||
{
|
||||
SpaceSegment SpaceSegment::projectedOnZPlane(double z) const {
|
||||
return SpaceSegment(Vector3(start.x, start.y, z), Vector3(end.x, end.y, z));
|
||||
}
|
||||
|
||||
SpaceSegment SpaceSegment::scaled(double factor) const
|
||||
{
|
||||
SpaceSegment SpaceSegment::scaled(double factor) const {
|
||||
return SpaceSegment(start.scale(factor), end.scale(factor));
|
||||
}
|
||||
|
||||
bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate)
|
||||
{
|
||||
bool SpaceSegment::iterateOnGrid(SpaceGridIterator &delegate) {
|
||||
Vector3 diff = end.sub(start);
|
||||
|
||||
int stepX = diff.x < 0.0 ? -1 : 1;
|
||||
|
@ -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 tMaxZ = diff.z == 0.0 ? INFINITY : ((double)(Z + (stepZ > 0 ? 1 : 0)) - start.z) / diff.z;
|
||||
|
||||
do
|
||||
{
|
||||
if (not delegate.onCell(X, Y, Z))
|
||||
{
|
||||
do {
|
||||
if (not delegate.onCell(X, Y, Z)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (tMaxX < tMaxY)
|
||||
{
|
||||
if (tMaxX < tMaxZ)
|
||||
{
|
||||
if (tMaxX < tMaxY) {
|
||||
if (tMaxX < tMaxZ) {
|
||||
X = X + stepX;
|
||||
tMaxX = tMaxX + tDeltaX;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Z = Z + stepZ;
|
||||
tMaxZ = tMaxZ + tDeltaZ;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(tMaxY < tMaxZ)
|
||||
{
|
||||
} else {
|
||||
if (tMaxY < tMaxZ) {
|
||||
Y = Y + stepY;
|
||||
tMaxY = tMaxY + tDeltaY;
|
||||
}
|
||||
else
|
||||
{
|
||||
Z= Z + stepZ;
|
||||
} else {
|
||||
Z = Z + stepZ;
|
||||
tMaxZ = tMaxZ + tDeltaZ;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,20 +11,34 @@ namespace basics {
|
|||
/**
|
||||
* A delimited segment in 3D space (mainly useful for rays).
|
||||
*/
|
||||
class BASICSSHARED_EXPORT SpaceSegment
|
||||
{
|
||||
public:
|
||||
SpaceSegment(const Vector3& start, const Vector3& end);
|
||||
SpaceSegment(): SpaceSegment(Vector3(), Vector3()) {}
|
||||
class BASICSSHARED_EXPORT SpaceSegment {
|
||||
public:
|
||||
SpaceSegment(const Vector3 &start, const Vector3 &end);
|
||||
SpaceSegment() : SpaceSegment(Vector3(), Vector3()) {
|
||||
}
|
||||
|
||||
inline const Vector3 &getStart() const {return start;}
|
||||
inline const Vector3 &getEnd() const {return end;}
|
||||
inline Vector3 getDirection() const {return end.sub(start);}
|
||||
inline double getLength() const {return end.sub(start).getNorm();}
|
||||
inline const Vector3 &getStart() const {
|
||||
return start;
|
||||
}
|
||||
inline const Vector3 &getEnd() const {
|
||||
return end;
|
||||
}
|
||||
inline Vector3 getDirection() const {
|
||||
return end.sub(start);
|
||||
}
|
||||
inline double getLength() const {
|
||||
return end.sub(start).getNorm();
|
||||
}
|
||||
|
||||
inline double getXDiff() const {return end.x - start.x;}
|
||||
inline double getYDiff() const {return end.y - start.y;}
|
||||
inline double getZDiff() const {return end.z - start.z;}
|
||||
inline double getXDiff() const {
|
||||
return end.x - start.x;
|
||||
}
|
||||
inline double getYDiff() const {
|
||||
return end.y - start.y;
|
||||
}
|
||||
inline double getZDiff() const {
|
||||
return end.z - start.z;
|
||||
}
|
||||
|
||||
/**
|
||||
* Keep only the intersection with a slice orthogonal to the Y axis.
|
||||
|
@ -36,15 +50,15 @@ public:
|
|||
/**
|
||||
* Return a version of this segment, projected on a X plane.
|
||||
*/
|
||||
SpaceSegment projectedOnXPlane(double x=0.0) const;
|
||||
SpaceSegment projectedOnXPlane(double x = 0.0) const;
|
||||
/**
|
||||
* Return a version of this segment, projected on a Y plane.
|
||||
*/
|
||||
SpaceSegment projectedOnYPlane(double y=0.0) const;
|
||||
SpaceSegment projectedOnYPlane(double y = 0.0) const;
|
||||
/**
|
||||
* Return a version of this segment, projected on a Z plane.
|
||||
*/
|
||||
SpaceSegment projectedOnZPlane(double z=0.0) const;
|
||||
SpaceSegment projectedOnZPlane(double z = 0.0) const;
|
||||
|
||||
/**
|
||||
* Return a scaled version of this segment.
|
||||
|
@ -64,11 +78,10 @@ public:
|
|||
*/
|
||||
bool iterateOnGrid(SpaceGridIterator &delegate);
|
||||
|
||||
private:
|
||||
private:
|
||||
Vector3 start;
|
||||
Vector3 end;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,43 +3,32 @@
|
|||
#include "PackStream.h"
|
||||
#include "InfiniteRay.h"
|
||||
|
||||
Sphere::Sphere()
|
||||
{
|
||||
Sphere::Sphere() {
|
||||
}
|
||||
|
||||
Sphere::Sphere(const Vector3 ¢er, double radius):
|
||||
center(center), radius(radius)
|
||||
{
|
||||
Sphere::Sphere(const Vector3 ¢er, double radius) : center(center), radius(radius) {
|
||||
radius2 = radius * radius;
|
||||
}
|
||||
|
||||
int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const
|
||||
{
|
||||
int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection,
|
||||
Vector3 *second_intersection) const {
|
||||
Vector3 L = ray.getOrigin().sub(center);
|
||||
double b = 2.0 * ray.getDirection().dotProduct(L);
|
||||
double c = L.dotProduct(L) - radius2;
|
||||
|
||||
double discr = b * b - 4.0 * c;
|
||||
if (discr < 0)
|
||||
{
|
||||
if (discr < 0) {
|
||||
return 0;
|
||||
}
|
||||
else if (discr == 0)
|
||||
{
|
||||
} else if (discr == 0) {
|
||||
*first_intersection = ray.getPointAtCursor(-0.5 * b);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
double x0 = (b > 0.0) ? -0.5 * (b + sqrt(discr)) : -0.5 * (b - sqrt(discr));
|
||||
double x1 = c / x0;
|
||||
if (x0 > x1)
|
||||
{
|
||||
if (x0 > x1) {
|
||||
*first_intersection = ray.getPointAtCursor(x1);
|
||||
*second_intersection = ray.getPointAtCursor(x0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*first_intersection = ray.getPointAtCursor(x0);
|
||||
*second_intersection = ray.getPointAtCursor(x1);
|
||||
}
|
||||
|
@ -47,15 +36,13 @@ int Sphere::checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersec
|
|||
}
|
||||
}
|
||||
|
||||
void Sphere::save(PackStream *stream) const
|
||||
{
|
||||
void Sphere::save(PackStream *stream) const {
|
||||
center.save(stream);
|
||||
stream->write(&radius);
|
||||
stream->write(&radius2);
|
||||
}
|
||||
|
||||
void Sphere::load(PackStream *stream)
|
||||
{
|
||||
void Sphere::load(PackStream *stream) {
|
||||
center.load(stream);
|
||||
stream->read(&radius);
|
||||
stream->read(&radius2);
|
||||
|
|
|
@ -11,31 +11,33 @@ namespace basics {
|
|||
/**
|
||||
* Geometric sphere.
|
||||
*/
|
||||
class BASICSSHARED_EXPORT Sphere
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Sphere {
|
||||
public:
|
||||
Sphere();
|
||||
Sphere(const Vector3 ¢er, double radius);
|
||||
|
||||
inline const Vector3 &getCenter() const {return center;}
|
||||
inline const double &getRadius() const {return radius;}
|
||||
inline const Vector3 &getCenter() const {
|
||||
return center;
|
||||
}
|
||||
inline const double &getRadius() const {
|
||||
return radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the intersection between the sphere and an infinite ray.
|
||||
*
|
||||
* Returns the number of intersections (0, 1 or 2) and fill the intersection points.
|
||||
*/
|
||||
int checkRayIntersection(const InfiniteRay& ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
|
||||
int checkRayIntersection(const InfiniteRay &ray, Vector3 *first_intersection, Vector3 *second_intersection) const;
|
||||
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
|
||||
private:
|
||||
private:
|
||||
Vector3 center;
|
||||
double radius;
|
||||
double radius2;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "PictureWriter.h"
|
||||
|
||||
Texture2D::Texture2D(int xsize, int ysize)
|
||||
{
|
||||
Texture2D::Texture2D(int xsize, int ysize) {
|
||||
assert(xsize > 0 && ysize > 0);
|
||||
|
||||
this->xsize = xsize;
|
||||
|
@ -14,39 +13,38 @@ Texture2D::Texture2D(int xsize, int ysize)
|
|||
this->data = new Color[xsize * ysize];
|
||||
}
|
||||
|
||||
Texture2D::~Texture2D()
|
||||
{
|
||||
Texture2D::~Texture2D() {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture2D::getSize(int* xsize, int* ysize) const
|
||||
{
|
||||
void Texture2D::getSize(int *xsize, int *ysize) const {
|
||||
*xsize = this->xsize;
|
||||
*ysize = this->ysize;
|
||||
}
|
||||
|
||||
void Texture2D::setPixel(int x, int y, Color col)
|
||||
{
|
||||
void Texture2D::setPixel(int x, int y, Color col) {
|
||||
assert(x >= 0 && x < xsize);
|
||||
assert(y >= 0 && y < ysize);
|
||||
|
||||
data[y * xsize + x] = col;
|
||||
}
|
||||
|
||||
Color Texture2D::getPixel(int x, int y) const
|
||||
{
|
||||
Color Texture2D::getPixel(int x, int y) const {
|
||||
assert(x >= 0 && x < xsize);
|
||||
assert(y >= 0 && y < ysize);
|
||||
|
||||
return data[y * xsize + x];
|
||||
}
|
||||
|
||||
Color Texture2D::getNearest(double dx, double dy) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
Color Texture2D::getNearest(double dx, double dy) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
|
||||
int ix = (int)(dx * (double)(this->xsize - 1));
|
||||
int iy = (int)(dy * (double)(this->ysize - 1));
|
||||
|
@ -57,31 +55,32 @@ Color Texture2D::getNearest(double dx, double dy) const
|
|||
return this->data[iy * this->xsize + ix];
|
||||
}
|
||||
|
||||
Color Texture2D::getLinear(double dx, double dy) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
Color Texture2D::getLinear(double dx, double dy) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
|
||||
dx *= (double)(this->xsize - 1);
|
||||
dy *= (double)(this->ysize - 1);
|
||||
|
||||
int ix = (int)floor(dx);
|
||||
if (ix == this->xsize - 1)
|
||||
{
|
||||
if (ix == this->xsize - 1) {
|
||||
ix--;
|
||||
}
|
||||
int iy = (int)floor(dy);
|
||||
if (iy == this->ysize - 1)
|
||||
{
|
||||
if (iy == this->ysize - 1) {
|
||||
iy--;
|
||||
}
|
||||
|
||||
dx -= (double)ix;
|
||||
dy -= (double)iy;
|
||||
|
||||
Color* data = this->data + iy * this->xsize + ix;
|
||||
Color *data = this->data + iy * this->xsize + ix;
|
||||
|
||||
Color c1 = data->lerp(*(data + 1), dx);
|
||||
Color c2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
|
||||
|
@ -89,32 +88,27 @@ Color Texture2D::getLinear(double dx, double dy) const
|
|||
return c1.lerp(c2, dy);
|
||||
}
|
||||
|
||||
Color Texture2D::getCubic(double dx, double dy) const
|
||||
{
|
||||
Color Texture2D::getCubic(double dx, double dy) const {
|
||||
/* TODO */
|
||||
return getLinear(dx, dy);
|
||||
}
|
||||
|
||||
void Texture2D::fill(Color col)
|
||||
{
|
||||
void Texture2D::fill(Color col) {
|
||||
int i, n;
|
||||
n = this->xsize * this->ysize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i] = col;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::add(Texture2D* source)
|
||||
{
|
||||
void Texture2D::add(Texture2D *source) {
|
||||
int i, n;
|
||||
|
||||
assert(source->xsize == this->xsize);
|
||||
assert(source->ysize == this->ysize);
|
||||
|
||||
n = source->xsize * source->ysize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i].r += source->data[i].r;
|
||||
this->data[i].g += source->data[i].g;
|
||||
this->data[i].b += source->data[i].b;
|
||||
|
@ -122,47 +116,42 @@ void Texture2D::add(Texture2D* source)
|
|||
}
|
||||
}
|
||||
|
||||
void Texture2D::save(PackStream* stream) const
|
||||
{
|
||||
void Texture2D::save(PackStream *stream) const {
|
||||
int i, n;
|
||||
stream->write(&this->xsize);
|
||||
stream->write(&this->ysize);
|
||||
n = this->xsize * this->ysize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->save(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture2D::load(PackStream* stream)
|
||||
{
|
||||
void Texture2D::load(PackStream *stream) {
|
||||
int i, n;
|
||||
stream->read(&this->xsize);
|
||||
stream->read(&this->ysize);
|
||||
n = this->xsize * this->ysize;
|
||||
delete[] this->data;
|
||||
this->data = new Color[n];
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
class Texture2DWriter:public PictureWriter
|
||||
{
|
||||
public:
|
||||
Texture2DWriter(const Texture2D *tex): tex(tex) {}
|
||||
class Texture2DWriter : public PictureWriter {
|
||||
public:
|
||||
Texture2DWriter(const Texture2D *tex) : tex(tex) {
|
||||
}
|
||||
|
||||
virtual unsigned int getPixel(int x, int y) override
|
||||
{
|
||||
virtual unsigned int getPixel(int x, int y) override {
|
||||
return tex->getPixel(x, y).to32BitBGRA();
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
const Texture2D *tex;
|
||||
};
|
||||
|
||||
void Texture2D::saveToFile(const std::string &filepath) const
|
||||
{
|
||||
void Texture2D::saveToFile(const std::string &filepath) const {
|
||||
Texture2DWriter writer(this);
|
||||
writer.save(filepath, xsize, ysize);
|
||||
}
|
||||
|
|
|
@ -6,30 +6,28 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Texture2D
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Texture2D {
|
||||
public:
|
||||
Texture2D(int xsize, int ysize);
|
||||
~Texture2D();
|
||||
|
||||
void getSize(int* xsize, int* ysize) const;
|
||||
void getSize(int *xsize, int *ysize) const;
|
||||
void setPixel(int x, int y, Color col);
|
||||
Color getPixel(int x, int y) const;
|
||||
Color getNearest(double dx, double dy) const;
|
||||
Color getLinear(double dx, double dy) const;
|
||||
Color getCubic(double dx, double dy) const;
|
||||
void fill(Color col);
|
||||
void add(Texture2D* other);
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void add(Texture2D *other);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void saveToFile(const std::string &filepath) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
int xsize;
|
||||
int ysize;
|
||||
Color* data;
|
||||
Color *data;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "PictureWriter.h"
|
||||
|
||||
Texture3D::Texture3D(int xsize, int ysize, int zsize)
|
||||
{
|
||||
Texture3D::Texture3D(int xsize, int ysize, int zsize) {
|
||||
assert(xsize > 0 && ysize > 0 && zsize > 0);
|
||||
|
||||
this->xsize = xsize;
|
||||
|
@ -15,20 +14,17 @@ Texture3D::Texture3D(int xsize, int ysize, int zsize)
|
|||
this->data = new Color[xsize * ysize * zsize];
|
||||
}
|
||||
|
||||
Texture3D::~Texture3D()
|
||||
{
|
||||
Texture3D::~Texture3D() {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture3D::getSize(int* xsize, int* ysize, int* zsize) const
|
||||
{
|
||||
void Texture3D::getSize(int *xsize, int *ysize, int *zsize) const {
|
||||
*xsize = this->xsize;
|
||||
*ysize = this->ysize;
|
||||
*zsize = this->zsize;
|
||||
}
|
||||
|
||||
void Texture3D::setPixel(int x, int y, int z, Color col)
|
||||
{
|
||||
void Texture3D::setPixel(int x, int y, int z, Color col) {
|
||||
assert(x >= 0 && x < this->xsize);
|
||||
assert(y >= 0 && y < this->ysize);
|
||||
assert(z >= 0 && z < this->ysize);
|
||||
|
@ -36,8 +32,7 @@ void Texture3D::setPixel(int x, int y, int z, Color col)
|
|||
this->data[z * this->xsize * this->ysize + y * this->xsize + x] = col;
|
||||
}
|
||||
|
||||
Color Texture3D::getPixel(int x, int y, int z) const
|
||||
{
|
||||
Color Texture3D::getPixel(int x, int y, int z) const {
|
||||
assert(x >= 0 && x < this->xsize);
|
||||
assert(y >= 0 && y < this->ysize);
|
||||
assert(z >= 0 && z < this->zsize);
|
||||
|
@ -45,14 +40,19 @@ Color Texture3D::getPixel(int x, int y, int z) const
|
|||
return this->data[z * this->xsize * this->ysize + y * this->xsize + x];
|
||||
}
|
||||
|
||||
Color Texture3D::getNearest(double dx, double dy, double dz) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
if (dz < 0.0) dz = 0.0;
|
||||
if (dz > 1.0) dz = 1.0;
|
||||
Color Texture3D::getNearest(double dx, double dy, double dz) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
if (dz < 0.0)
|
||||
dz = 0.0;
|
||||
if (dz > 1.0)
|
||||
dz = 1.0;
|
||||
|
||||
int ix = (int)(dx * (double)(this->xsize - 1));
|
||||
int iy = (int)(dy * (double)(this->ysize - 1));
|
||||
|
@ -65,32 +65,34 @@ Color Texture3D::getNearest(double dx, double dy, double dz) const
|
|||
return this->data[iz * this->xsize * this->ysize + iy * this->xsize + ix];
|
||||
}
|
||||
|
||||
Color Texture3D::getLinear(double dx, double dy, double dz) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
if (dz < 0.0) dz = 0.0;
|
||||
if (dz > 1.0) dz = 1.0;
|
||||
Color Texture3D::getLinear(double dx, double dy, double dz) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
if (dz < 0.0)
|
||||
dz = 0.0;
|
||||
if (dz > 1.0)
|
||||
dz = 1.0;
|
||||
|
||||
dx *= (double)(this->xsize - 1);
|
||||
dy *= (double)(this->ysize - 1);
|
||||
dz *= (double)(this->zsize - 1);
|
||||
|
||||
int ix = (int)floor(dx);
|
||||
if (ix == this->xsize - 1)
|
||||
{
|
||||
if (ix == this->xsize - 1) {
|
||||
ix--;
|
||||
}
|
||||
int iy = (int)floor(dy);
|
||||
if (iy == this->ysize - 1)
|
||||
{
|
||||
if (iy == this->ysize - 1) {
|
||||
iy--;
|
||||
}
|
||||
int iz = (int)floor(dz);
|
||||
if (iz == this->zsize - 1)
|
||||
{
|
||||
if (iz == this->zsize - 1) {
|
||||
iz--;
|
||||
}
|
||||
|
||||
|
@ -98,7 +100,7 @@ Color Texture3D::getLinear(double dx, double dy, double dz) const
|
|||
dy -= (double)iy;
|
||||
dz -= (double)iz;
|
||||
|
||||
Color* data = this->data + iz * this->xsize * this->ysize + iy * this->xsize + ix;
|
||||
Color *data = this->data + iz * this->xsize * this->ysize + iy * this->xsize + ix;
|
||||
|
||||
Color cx1 = data->lerp(*(data + 1), dx);
|
||||
Color cx2 = (data + this->xsize)->lerp(*(data + this->xsize + 1), dx);
|
||||
|
@ -112,24 +114,20 @@ Color Texture3D::getLinear(double dx, double dy, double dz) const
|
|||
return cy1.lerp(cy2, dz);
|
||||
}
|
||||
|
||||
Color Texture3D::getCubic(double dx, double dy, double dz) const
|
||||
{
|
||||
Color Texture3D::getCubic(double dx, double dy, double dz) const {
|
||||
/* TODO */
|
||||
return getLinear(dx, dy, dz);
|
||||
}
|
||||
|
||||
void Texture3D::fill(Color col)
|
||||
{
|
||||
void Texture3D::fill(Color col) {
|
||||
int i, n;
|
||||
n = this->xsize * this->ysize * this->zsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i] = col;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture3D::add(Texture3D* source)
|
||||
{
|
||||
void Texture3D::add(Texture3D *source) {
|
||||
int i, n;
|
||||
|
||||
assert(source->xsize == this->xsize);
|
||||
|
@ -137,8 +135,7 @@ void Texture3D::add(Texture3D* source)
|
|||
assert(source->zsize == this->zsize);
|
||||
|
||||
n = source->xsize * source->ysize * source->zsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i].r += source->data[i].r;
|
||||
this->data[i].g += source->data[i].g;
|
||||
this->data[i].b += source->data[i].b;
|
||||
|
@ -146,21 +143,18 @@ void Texture3D::add(Texture3D* source)
|
|||
}
|
||||
}
|
||||
|
||||
void Texture3D::save(PackStream* stream) const
|
||||
{
|
||||
void Texture3D::save(PackStream *stream) const {
|
||||
int i, n;
|
||||
stream->write(&this->xsize);
|
||||
stream->write(&this->ysize);
|
||||
stream->write(&this->zsize);
|
||||
n = this->xsize * this->ysize * this->zsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->save(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture3D::load(PackStream* stream)
|
||||
{
|
||||
void Texture3D::load(PackStream *stream) {
|
||||
int i, n;
|
||||
stream->read(&this->xsize);
|
||||
stream->read(&this->ysize);
|
||||
|
@ -168,19 +162,17 @@ void Texture3D::load(PackStream* stream)
|
|||
n = this->xsize * this->ysize * this->zsize;
|
||||
delete[] this->data;
|
||||
this->data = new Color[n];
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
class Texture3DWriter:public PictureWriter
|
||||
{
|
||||
public:
|
||||
Texture3DWriter(const Texture3D *tex): tex(tex) {}
|
||||
class Texture3DWriter : public PictureWriter {
|
||||
public:
|
||||
Texture3DWriter(const Texture3D *tex) : tex(tex) {
|
||||
}
|
||||
|
||||
virtual unsigned int getPixel(int x, int y) override
|
||||
{
|
||||
virtual unsigned int getPixel(int x, int y) override {
|
||||
int xsize, ysize, zsize;
|
||||
tex->getSize(&xsize, &ysize, &zsize);
|
||||
|
||||
|
@ -189,12 +181,12 @@ public:
|
|||
|
||||
return tex->getPixel(x, y, z).to32BitBGRA();
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
const Texture3D *tex;
|
||||
};
|
||||
|
||||
void Texture3D::saveToFile(const std::string &filepath) const
|
||||
{
|
||||
void Texture3D::saveToFile(const std::string &filepath) const {
|
||||
Texture3DWriter writer(this);
|
||||
writer.save(filepath, xsize, ysize * zsize);
|
||||
}
|
||||
|
|
|
@ -6,31 +6,29 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Texture3D
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Texture3D {
|
||||
public:
|
||||
Texture3D(int xsize, int ysize, int zsize);
|
||||
~Texture3D();
|
||||
|
||||
void getSize(int* xsize, int* ysize, int* zsize) const;
|
||||
void getSize(int *xsize, int *ysize, int *zsize) const;
|
||||
void setPixel(int x, int y, int z, Color col);
|
||||
Color getPixel(int x, int y, int z) const;
|
||||
Color getNearest(double dx, double dy, double dz) const;
|
||||
Color getLinear(double dx, double dy, double dz) const;
|
||||
Color getCubic(double dx, double dy, double dz) const;
|
||||
void fill(Color col);
|
||||
void add(Texture3D* other);
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void add(Texture3D *other);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void saveToFile(const std::string &filepath) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
int xsize;
|
||||
int ysize;
|
||||
int zsize;
|
||||
Color* data;
|
||||
Color *data;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,8 +5,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "PictureWriter.h"
|
||||
|
||||
Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize)
|
||||
{
|
||||
Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize) {
|
||||
assert(xsize > 0 && ysize > 0 && zsize > 0 && wsize > 0);
|
||||
|
||||
this->xsize = xsize;
|
||||
|
@ -16,21 +15,18 @@ Texture4D::Texture4D(int xsize, int ysize, int zsize, int wsize)
|
|||
this->data = new Color[xsize * ysize * zsize * wsize];
|
||||
}
|
||||
|
||||
Texture4D::~Texture4D()
|
||||
{
|
||||
Texture4D::~Texture4D() {
|
||||
delete[] data;
|
||||
}
|
||||
|
||||
void Texture4D::getSize(int* xsize, int* ysize, int* zsize, int* wsize) const
|
||||
{
|
||||
void Texture4D::getSize(int *xsize, int *ysize, int *zsize, int *wsize) const {
|
||||
*xsize = this->xsize;
|
||||
*ysize = this->ysize;
|
||||
*zsize = this->zsize;
|
||||
*wsize = this->wsize;
|
||||
}
|
||||
|
||||
void Texture4D::setPixel(int x, int y, int z, int w, Color col)
|
||||
{
|
||||
void Texture4D::setPixel(int x, int y, int z, int w, Color col) {
|
||||
assert(x >= 0 && x < this->xsize);
|
||||
assert(y >= 0 && y < this->ysize);
|
||||
assert(z >= 0 && z < this->zsize);
|
||||
|
@ -39,26 +35,33 @@ void Texture4D::setPixel(int x, int y, int z, int w, Color col)
|
|||
this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x] = col;
|
||||
}
|
||||
|
||||
Color Texture4D::getPixel(int x, int y, int z, int w) const
|
||||
{
|
||||
Color Texture4D::getPixel(int x, int y, int z, int w) const {
|
||||
assert(x >= 0 && x < this->xsize);
|
||||
assert(y >= 0 && y < this->ysize);
|
||||
assert(z >= 0 && z < this->zsize);
|
||||
assert(w >= 0 && w < this->wsize);
|
||||
|
||||
return this->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x];
|
||||
return this
|
||||
->data[w * this->xsize * this->ysize * this->zsize + z * this->xsize * this->ysize + y * this->xsize + x];
|
||||
}
|
||||
|
||||
Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
if (dz < 0.0) dz = 0.0;
|
||||
if (dz > 1.0) dz = 1.0;
|
||||
if (dw < 0.0) dw = 0.0;
|
||||
if (dw > 1.0) dw = 1.0;
|
||||
Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
if (dz < 0.0)
|
||||
dz = 0.0;
|
||||
if (dz > 1.0)
|
||||
dz = 1.0;
|
||||
if (dw < 0.0)
|
||||
dw = 0.0;
|
||||
if (dw > 1.0)
|
||||
dw = 1.0;
|
||||
|
||||
int ix = (int)(dx * (double)(this->xsize - 1));
|
||||
int iy = (int)(dy * (double)(this->ysize - 1));
|
||||
|
@ -70,19 +73,27 @@ Color Texture4D::getNearest(double dx, double dy, double dz, double dw) const
|
|||
assert(iz >= 0 && iz < this->zsize);
|
||||
assert(iw >= 0 && iw < this->wsize);
|
||||
|
||||
return this->data[iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix];
|
||||
return this
|
||||
->data[iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix];
|
||||
}
|
||||
|
||||
Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
|
||||
{
|
||||
if (dx < 0.0) dx = 0.0;
|
||||
if (dx > 1.0) dx = 1.0;
|
||||
if (dy < 0.0) dy = 0.0;
|
||||
if (dy > 1.0) dy = 1.0;
|
||||
if (dz < 0.0) dz = 0.0;
|
||||
if (dz > 1.0) dz = 1.0;
|
||||
if (dw < 0.0) dw = 0.0;
|
||||
if (dw > 1.0) dw = 1.0;
|
||||
Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const {
|
||||
if (dx < 0.0)
|
||||
dx = 0.0;
|
||||
if (dx > 1.0)
|
||||
dx = 1.0;
|
||||
if (dy < 0.0)
|
||||
dy = 0.0;
|
||||
if (dy > 1.0)
|
||||
dy = 1.0;
|
||||
if (dz < 0.0)
|
||||
dz = 0.0;
|
||||
if (dz > 1.0)
|
||||
dz = 1.0;
|
||||
if (dw < 0.0)
|
||||
dw = 0.0;
|
||||
if (dw > 1.0)
|
||||
dw = 1.0;
|
||||
|
||||
dx *= (double)(this->xsize - 1);
|
||||
dy *= (double)(this->ysize - 1);
|
||||
|
@ -90,23 +101,19 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
|
|||
dw *= (double)(this->wsize - 1);
|
||||
|
||||
int ix = (int)floor(dx);
|
||||
if (ix == this->xsize - 1)
|
||||
{
|
||||
if (ix == this->xsize - 1) {
|
||||
ix--;
|
||||
}
|
||||
int iy = (int)floor(dy);
|
||||
if (iy == this->ysize - 1)
|
||||
{
|
||||
if (iy == this->ysize - 1) {
|
||||
iy--;
|
||||
}
|
||||
int iz = (int)floor(dz);
|
||||
if (iz == this->zsize - 1)
|
||||
{
|
||||
if (iz == this->zsize - 1) {
|
||||
iz--;
|
||||
}
|
||||
int iw = (int)floor(dw);
|
||||
if (iw == this->wsize - 1)
|
||||
{
|
||||
if (iw == this->wsize - 1) {
|
||||
iw--;
|
||||
}
|
||||
|
||||
|
@ -115,7 +122,8 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
|
|||
dz -= (double)iz;
|
||||
dw -= (double)iw;
|
||||
|
||||
Color* data = this->data + iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize + iy * this->xsize + ix;
|
||||
Color *data = this->data + iw * this->xsize * this->ysize * this->zsize + iz * this->xsize * this->ysize +
|
||||
iy * this->xsize + ix;
|
||||
Color cz1, cz2;
|
||||
|
||||
Color cx1 = data->lerp(*(data + 1), dx);
|
||||
|
@ -143,24 +151,20 @@ Color Texture4D::getLinear(double dx, double dy, double dz, double dw) const
|
|||
return cz1.lerp(cz2, dw);
|
||||
}
|
||||
|
||||
Color Texture4D::getCubic(double dx, double dy, double dz, double dw) const
|
||||
{
|
||||
Color Texture4D::getCubic(double dx, double dy, double dz, double dw) const {
|
||||
/* TODO */
|
||||
return getLinear(dx, dy, dz, dw);
|
||||
}
|
||||
|
||||
void Texture4D::fill(Color col)
|
||||
{
|
||||
void Texture4D::fill(Color col) {
|
||||
int i, n;
|
||||
n = this->xsize * this->ysize * this->zsize * this->wsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i] = col;
|
||||
}
|
||||
}
|
||||
|
||||
void Texture4D::add(Texture4D* source)
|
||||
{
|
||||
void Texture4D::add(Texture4D *source) {
|
||||
int i, n;
|
||||
|
||||
assert(source->xsize == this->xsize);
|
||||
|
@ -169,8 +173,7 @@ void Texture4D::add(Texture4D* source)
|
|||
assert(source->wsize == this->wsize);
|
||||
|
||||
n = source->xsize * source->ysize * source->zsize * source->wsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
this->data[i].r += source->data[i].r;
|
||||
this->data[i].g += source->data[i].g;
|
||||
this->data[i].b += source->data[i].b;
|
||||
|
@ -178,22 +181,19 @@ void Texture4D::add(Texture4D* source)
|
|||
}
|
||||
}
|
||||
|
||||
void Texture4D::save(PackStream* stream) const
|
||||
{
|
||||
void Texture4D::save(PackStream *stream) const {
|
||||
int i, n;
|
||||
stream->write(&this->xsize);
|
||||
stream->write(&this->ysize);
|
||||
stream->write(&this->zsize);
|
||||
stream->write(&this->wsize);
|
||||
n = this->xsize * this->ysize * this->zsize * this->wsize;
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->save(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Texture4D::load(PackStream* stream)
|
||||
{
|
||||
void Texture4D::load(PackStream *stream) {
|
||||
int i, n;
|
||||
stream->read(&this->xsize);
|
||||
stream->read(&this->ysize);
|
||||
|
@ -202,20 +202,17 @@ void Texture4D::load(PackStream* stream)
|
|||
n = this->xsize * this->ysize * this->zsize * this->wsize;
|
||||
delete[] this->data;
|
||||
this->data = new Color[n];
|
||||
for (i = 0; i < n; i++)
|
||||
{
|
||||
for (i = 0; i < n; i++) {
|
||||
(this->data + i)->load(stream);
|
||||
}
|
||||
}
|
||||
|
||||
class Texture4DWriter : public PictureWriter {
|
||||
public:
|
||||
Texture4DWriter(const Texture4D *tex) : tex(tex) {
|
||||
}
|
||||
|
||||
class Texture4DWriter:public PictureWriter
|
||||
{
|
||||
public:
|
||||
Texture4DWriter(const Texture4D *tex): tex(tex) {}
|
||||
|
||||
virtual unsigned int getPixel(int x, int y) override
|
||||
{
|
||||
virtual unsigned int getPixel(int x, int y) override {
|
||||
int xsize, ysize, zsize, wsize;
|
||||
tex->getSize(&xsize, &ysize, &zsize, &wsize);
|
||||
|
||||
|
@ -227,12 +224,12 @@ public:
|
|||
|
||||
return tex->getPixel(x, y, z, w).to32BitBGRA();
|
||||
}
|
||||
private:
|
||||
|
||||
private:
|
||||
const Texture4D *tex;
|
||||
};
|
||||
|
||||
void Texture4D::saveToFile(const std::string &filepath) const
|
||||
{
|
||||
void Texture4D::saveToFile(const std::string &filepath) const {
|
||||
Texture4DWriter writer(this);
|
||||
writer.save(filepath, xsize * wsize, ysize * zsize);
|
||||
}
|
||||
|
|
|
@ -6,32 +6,30 @@
|
|||
namespace paysages {
|
||||
namespace basics {
|
||||
|
||||
class BASICSSHARED_EXPORT Texture4D
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Texture4D {
|
||||
public:
|
||||
Texture4D(int xsize, int ysize, int zsize, int wsize);
|
||||
~Texture4D();
|
||||
|
||||
void getSize(int* xsize, int* ysize, int* zsize, int* wsize) const;
|
||||
void getSize(int *xsize, int *ysize, int *zsize, int *wsize) const;
|
||||
void setPixel(int x, int y, int z, int w, Color col);
|
||||
Color getPixel(int x, int y, int z, int w) const;
|
||||
Color getNearest(double dx, double dy, double dz, double dw) const;
|
||||
Color getLinear(double dx, double dy, double dz, double dw) const;
|
||||
Color getCubic(double dx, double dy, double dz, double dw) const;
|
||||
void fill(Color col);
|
||||
void add(Texture4D* other);
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void add(Texture4D *other);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void saveToFile(const std::string &filepath) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
int xsize;
|
||||
int ysize;
|
||||
int zsize;
|
||||
int wsize;
|
||||
Color* data;
|
||||
Color *data;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -12,41 +12,31 @@ const Vector3 paysages::basics::VECTOR_SOUTH(0.0, 0.0, 1.0);
|
|||
const Vector3 paysages::basics::VECTOR_WEST(-1.0, 0.0, 0.0);
|
||||
const Vector3 paysages::basics::VECTOR_EAST(1.0, 0.0, 0.0);
|
||||
|
||||
Vector3::Vector3(const VectorSpherical &v):
|
||||
x(v.r * cos(v.phi) * cos(v.theta)), y(v.r * sin(v.theta)), z(-v.r * sin(v.phi) * cos(v.theta))
|
||||
{
|
||||
Vector3::Vector3(const VectorSpherical &v)
|
||||
: x(v.r * cos(v.phi) * cos(v.theta)), y(v.r * sin(v.theta)), z(-v.r * sin(v.phi) * cos(v.theta)) {
|
||||
}
|
||||
|
||||
void Vector3::save(PackStream* stream) const
|
||||
{
|
||||
void Vector3::save(PackStream *stream) const {
|
||||
stream->write(&x);
|
||||
stream->write(&y);
|
||||
stream->write(&z);
|
||||
}
|
||||
void Vector3::load(PackStream* stream)
|
||||
{
|
||||
void Vector3::load(PackStream *stream) {
|
||||
stream->read(&x);
|
||||
stream->read(&y);
|
||||
stream->read(&z);
|
||||
}
|
||||
|
||||
static inline double _euclidGet2DAngle(double x, double y)
|
||||
{
|
||||
static inline double _euclidGet2DAngle(double x, double y) {
|
||||
// TEMP Copy of old euclid.c
|
||||
double nx, ny, d, ret;
|
||||
|
||||
if (x == 0.0)
|
||||
{
|
||||
if (y == 0.0)
|
||||
{
|
||||
if (x == 0.0) {
|
||||
if (y == 0.0) {
|
||||
return 0.0;
|
||||
}
|
||||
else if (y < 0.0)
|
||||
{
|
||||
} else if (y < 0.0) {
|
||||
return 3.0 * M_PI_2;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return M_PI_2;
|
||||
}
|
||||
}
|
||||
|
@ -56,21 +46,18 @@ static inline double _euclidGet2DAngle(double x, double y)
|
|||
ny = y / d;
|
||||
|
||||
ret = asin(ny);
|
||||
if (nx < 0.0)
|
||||
{
|
||||
if (nx < 0.0) {
|
||||
ret = M_PI - ret;
|
||||
}
|
||||
return ret < 0.0 ? ret + 2.0 * M_PI : ret;
|
||||
}
|
||||
|
||||
VectorSpherical Vector3::toSpherical() const
|
||||
{
|
||||
VectorSpherical Vector3::toSpherical() const {
|
||||
VectorSpherical result;
|
||||
|
||||
result.phi = _euclidGet2DAngle(x, -z);
|
||||
result.theta = _euclidGet2DAngle(sqrt(x * x + z * z), y);
|
||||
if (y < 0.0)
|
||||
{
|
||||
if (y < 0.0) {
|
||||
result.theta -= 2.0 * M_PI;
|
||||
}
|
||||
result.r = getNorm();
|
||||
|
@ -78,19 +65,14 @@ VectorSpherical Vector3::toSpherical() const
|
|||
return result;
|
||||
}
|
||||
|
||||
Vector3 Vector3::midPointTo(const Vector3 &other) const
|
||||
{
|
||||
Vector3 Vector3::midPointTo(const Vector3 &other) const {
|
||||
return Vector3((other.x + x) * 0.5, (other.y + y) * 0.5, (other.z + z) * 0.5);
|
||||
}
|
||||
|
||||
Vector3 Vector3::randomInSphere(double radius, bool only_surface)
|
||||
{
|
||||
Vector3 Vector3::randomInSphere(double radius, bool only_surface) {
|
||||
// TODO More uniform spatial repartition
|
||||
// The current randomization clusters result near the center and at the poles
|
||||
VectorSpherical vec = {
|
||||
only_surface ? radius : RandomGenerator::random() * radius,
|
||||
(RandomGenerator::random() - 0.5) * M_PI,
|
||||
RandomGenerator::random() * M_2PI
|
||||
};
|
||||
VectorSpherical vec = {only_surface ? radius : RandomGenerator::random() * radius,
|
||||
(RandomGenerator::random() - 0.5) * M_PI, RandomGenerator::random() * M_2PI};
|
||||
return Vector3(vec);
|
||||
}
|
||||
|
|
|
@ -33,16 +33,14 @@ namespace basics {
|
|||
* X=0 Y=-1 Z=0 => THETA=-PI/2
|
||||
*/
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double r;
|
||||
double theta;
|
||||
double phi;
|
||||
} VectorSpherical;
|
||||
|
||||
class BASICSSHARED_EXPORT Vector3
|
||||
{
|
||||
public:
|
||||
class BASICSSHARED_EXPORT Vector3 {
|
||||
public:
|
||||
Vector3() = default;
|
||||
Vector3(double x, double y, double z);
|
||||
Vector3(const VectorSpherical &v);
|
||||
|
@ -73,9 +71,9 @@ public:
|
|||
*
|
||||
* If *only_surface* is true, produce a vector with *radius* as length.
|
||||
*/
|
||||
static Vector3 randomInSphere(double radius=1.0, bool only_surface=false);
|
||||
static Vector3 randomInSphere(double radius = 1.0, bool only_surface = false);
|
||||
|
||||
public:
|
||||
public:
|
||||
// TODO Make private
|
||||
double x;
|
||||
double y;
|
||||
|
@ -89,7 +87,6 @@ BASICSSHARED_EXPORT extern const Vector3 VECTOR_NORTH;
|
|||
BASICSSHARED_EXPORT extern const Vector3 VECTOR_SOUTH;
|
||||
BASICSSHARED_EXPORT extern const Vector3 VECTOR_EAST;
|
||||
BASICSSHARED_EXPORT extern const Vector3 VECTOR_WEST;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,73 +1,55 @@
|
|||
#define VECTOR3_INLINE_CPP
|
||||
|
||||
#ifdef VECTOR3_H
|
||||
# define METHSPEC inline
|
||||
#define METHSPEC inline
|
||||
#else
|
||||
# include "Vector3.h"
|
||||
# define METHSPEC
|
||||
#include "Vector3.h"
|
||||
#define METHSPEC
|
||||
#endif
|
||||
|
||||
#include <cmath>
|
||||
|
||||
METHSPEC Vector3::Vector3(double x, double y, double z):
|
||||
x(x), y(y), z(z)
|
||||
{
|
||||
METHSPEC Vector3::Vector3(double x, double y, double z) : x(x), y(y), z(z) {
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::add(double x, double y, double z) const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::add(double x, double y, double z) const {
|
||||
return Vector3(this->x + x, this->y + y, this->z + z);
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::add(const Vector3 &other) const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::add(const Vector3 &other) const {
|
||||
return Vector3(x + other.x, y + other.y, z + other.z);
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::sub(const Vector3 &other) const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::sub(const Vector3 &other) const {
|
||||
return Vector3(x - other.x, y - other.y, z - other.z);
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::inverse() const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::inverse() const {
|
||||
return Vector3(-x, -y, -z);
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::scale(double scaling) const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::scale(double scaling) const {
|
||||
return Vector3(x * scaling, y * scaling, z * scaling);
|
||||
}
|
||||
|
||||
METHSPEC double Vector3::getNorm() const
|
||||
{
|
||||
METHSPEC double Vector3::getNorm() const {
|
||||
return sqrt(x * x + y * y + z * z);
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::normalize() const
|
||||
{
|
||||
METHSPEC Vector3 Vector3::normalize() const {
|
||||
double norm = sqrt(x * x + y * y + z * z);
|
||||
if (norm == 0.0)
|
||||
{
|
||||
if (norm == 0.0) {
|
||||
return VECTOR_ZERO;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
norm = 1.0 / norm;
|
||||
return Vector3(x * norm, y * norm, z * norm);
|
||||
}
|
||||
}
|
||||
|
||||
METHSPEC double Vector3:: dotProduct(const Vector3 &other) const
|
||||
{
|
||||
METHSPEC double Vector3::dotProduct(const Vector3 &other) const {
|
||||
return x * other.x + y * other.y + z * other.z;
|
||||
}
|
||||
|
||||
METHSPEC Vector3 Vector3::crossProduct(const Vector3 &other) const
|
||||
{
|
||||
return Vector3(
|
||||
y * other.z - z * other.y,
|
||||
z * other.x - x * other.z,
|
||||
x * other.y - y * other.x
|
||||
);
|
||||
METHSPEC Vector3 Vector3::crossProduct(const Vector3 &other) const {
|
||||
return Vector3(y * other.z - z * other.y, z * other.x - x * other.z, x * other.y - y * other.x);
|
||||
}
|
||||
|
|
|
@ -3,33 +3,33 @@
|
|||
|
||||
#include <QtCore/qglobal.h>
|
||||
#if defined(BASICS_LIBRARY)
|
||||
# define BASICSSHARED_EXPORT Q_DECL_EXPORT
|
||||
#define BASICSSHARED_EXPORT Q_DECL_EXPORT
|
||||
#else
|
||||
# define BASICSSHARED_EXPORT Q_DECL_IMPORT
|
||||
#define BASICSSHARED_EXPORT Q_DECL_IMPORT
|
||||
#endif
|
||||
|
||||
#include "system_global.h"
|
||||
|
||||
namespace paysages {
|
||||
namespace basics {
|
||||
class Vector3;
|
||||
class Matrix4;
|
||||
class BoundingBox;
|
||||
class SpaceGridIterator;
|
||||
class SpaceSegment;
|
||||
class Color;
|
||||
class NoiseGenerator;
|
||||
class NoiseState;
|
||||
class FractalNoise;
|
||||
class Curve;
|
||||
class ColorProfile;
|
||||
class Texture2D;
|
||||
class Texture3D;
|
||||
class Texture4D;
|
||||
class CappedCylinder;
|
||||
class InfiniteRay;
|
||||
class Sphere;
|
||||
class InfinitePlane;
|
||||
class Vector3;
|
||||
class Matrix4;
|
||||
class BoundingBox;
|
||||
class SpaceGridIterator;
|
||||
class SpaceSegment;
|
||||
class Color;
|
||||
class NoiseGenerator;
|
||||
class NoiseState;
|
||||
class FractalNoise;
|
||||
class Curve;
|
||||
class ColorProfile;
|
||||
class Texture2D;
|
||||
class Texture3D;
|
||||
class Texture4D;
|
||||
class CappedCylinder;
|
||||
class InfiniteRay;
|
||||
class Sphere;
|
||||
class InfinitePlane;
|
||||
}
|
||||
}
|
||||
using namespace paysages::basics;
|
||||
|
|
|
@ -5,24 +5,21 @@
|
|||
#include "FloatNode.h"
|
||||
#include "GodRaysDefinition.h"
|
||||
|
||||
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode* parent):
|
||||
DefinitionNode(parent, "atmosphere", "atmosphere")
|
||||
{
|
||||
AtmosphereDefinition::AtmosphereDefinition(DefinitionNode *parent)
|
||||
: DefinitionNode(parent, "atmosphere", "atmosphere") {
|
||||
godrays = new GodRaysDefinition(this);
|
||||
daytime = new FloatNode(this, "daytime");
|
||||
humidity = new FloatNode(this, "humidity");
|
||||
sun_radius = new FloatNode(this, "sun_radius");
|
||||
}
|
||||
|
||||
AtmosphereDefinition::~AtmosphereDefinition()
|
||||
{
|
||||
AtmosphereDefinition::~AtmosphereDefinition() {
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::save(PackStream* stream) const
|
||||
{
|
||||
void AtmosphereDefinition::save(PackStream *stream) const {
|
||||
DefinitionNode::save(stream);
|
||||
|
||||
stream->write((int*)&model);
|
||||
stream->write((int *)&model);
|
||||
sun_color.save(stream);
|
||||
stream->write(&dome_lighting);
|
||||
stream->write(&moon_radius);
|
||||
|
@ -31,19 +28,17 @@ void AtmosphereDefinition::save(PackStream* stream) const
|
|||
|
||||
int star_count = stars.size();
|
||||
stream->write(&star_count);
|
||||
for (const auto &star : stars)
|
||||
{
|
||||
for (const auto &star : stars) {
|
||||
star.location.save(stream);
|
||||
star.col.save(stream);
|
||||
stream->write(&star.radius);
|
||||
}
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::load(PackStream* stream)
|
||||
{
|
||||
void AtmosphereDefinition::load(PackStream *stream) {
|
||||
DefinitionNode::load(stream);
|
||||
|
||||
stream->read((int*)&model);
|
||||
stream->read((int *)&model);
|
||||
sun_color.load(stream);
|
||||
stream->read(&dome_lighting);
|
||||
stream->read(&moon_radius);
|
||||
|
@ -52,8 +47,7 @@ void AtmosphereDefinition::load(PackStream* stream)
|
|||
|
||||
int star_count;
|
||||
stream->read(&star_count);
|
||||
for (int i = 0; i < star_count; i++)
|
||||
{
|
||||
for (int i = 0; i < star_count; i++) {
|
||||
Star star;
|
||||
|
||||
star.location.load(stream);
|
||||
|
@ -66,11 +60,10 @@ void AtmosphereDefinition::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::copy(DefinitionNode* _destination) const
|
||||
{
|
||||
void AtmosphereDefinition::copy(DefinitionNode *_destination) const {
|
||||
DefinitionNode::copy(_destination);
|
||||
|
||||
AtmosphereDefinition* destination = (AtmosphereDefinition*)_destination;
|
||||
AtmosphereDefinition *destination = (AtmosphereDefinition *)_destination;
|
||||
|
||||
destination->model = model;
|
||||
destination->sun_color = sun_color;
|
||||
|
@ -83,25 +76,19 @@ void AtmosphereDefinition::copy(DefinitionNode* _destination) const
|
|||
destination->validate();
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::setDayTime(double value)
|
||||
{
|
||||
void AtmosphereDefinition::setDayTime(double value) {
|
||||
daytime->setValue(value);
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::setDayTime(int hour, int minute, int second)
|
||||
{
|
||||
void AtmosphereDefinition::setDayTime(int hour, int minute, int second) {
|
||||
setDayTime((double)hour / 24.0 + (double)minute / 1440.0 + (double)second / 86400.0);
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const
|
||||
{
|
||||
void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const {
|
||||
double value = daytime->getValue();
|
||||
if (value >= 0.0)
|
||||
{
|
||||
if (value >= 0.0) {
|
||||
value = fmod(value, 1.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
value = 1.0 - fmod(-value, 1.0);
|
||||
}
|
||||
value *= 86400.0;
|
||||
|
@ -111,8 +98,7 @@ void AtmosphereDefinition::getHMS(int *hour, int *minute, int *second) const
|
|||
*second = value - *minute * 60.0;
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
|
||||
{
|
||||
void AtmosphereDefinition::applyPreset(AtmospherePreset preset) {
|
||||
sun_color.r = 1.0;
|
||||
sun_color.g = 0.95;
|
||||
sun_color.b = 0.9;
|
||||
|
@ -124,35 +110,34 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
|
|||
|
||||
model = ATMOSPHERE_MODEL_BRUNETON;
|
||||
|
||||
switch (preset)
|
||||
{
|
||||
case ATMOSPHERE_PRESET_CLEAR_DAY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.1);
|
||||
dome_lighting = 0.2;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
|
||||
setDayTime(17, 45);
|
||||
humidity->setValue(0.1);
|
||||
dome_lighting = 0.3;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_HAZY_MORNING:
|
||||
setDayTime(8, 30);
|
||||
humidity->setValue(0.4);
|
||||
dome_lighting = 0.25;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_FOGGY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.7);
|
||||
dome_lighting = 0.1;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_STORMY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.9);
|
||||
dome_lighting = 0.05;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
switch (preset) {
|
||||
case ATMOSPHERE_PRESET_CLEAR_DAY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.1);
|
||||
dome_lighting = 0.2;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_CLEAR_SUNSET:
|
||||
setDayTime(17, 45);
|
||||
humidity->setValue(0.1);
|
||||
dome_lighting = 0.3;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_HAZY_MORNING:
|
||||
setDayTime(8, 30);
|
||||
humidity->setValue(0.4);
|
||||
dome_lighting = 0.25;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_FOGGY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.7);
|
||||
dome_lighting = 0.1;
|
||||
break;
|
||||
case ATMOSPHERE_PRESET_STORMY:
|
||||
setDayTime(15);
|
||||
humidity->setValue(0.9);
|
||||
dome_lighting = 0.05;
|
||||
break;
|
||||
default:
|
||||
;
|
||||
}
|
||||
|
||||
generateStars(2000);
|
||||
|
@ -160,22 +145,22 @@ void AtmosphereDefinition::applyPreset(AtmospherePreset preset)
|
|||
validate();
|
||||
}
|
||||
|
||||
void AtmosphereDefinition::generateStars(int count)
|
||||
{
|
||||
void AtmosphereDefinition::generateStars(int count) {
|
||||
stars.clear();
|
||||
|
||||
for (int i = 0; i < count; ++i)
|
||||
{
|
||||
for (int i = 0; i < count; ++i) {
|
||||
Star star;
|
||||
|
||||
star.location = Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() * 0.5) * 100000.0, (RandomGenerator::random() - 0.5) * 100000.0);
|
||||
if (star.location.getNorm() < 30000.0)
|
||||
{
|
||||
star.location =
|
||||
Vector3((RandomGenerator::random() - 0.5) * 100000.0, (RandomGenerator::random() * 0.5) * 100000.0,
|
||||
(RandomGenerator::random() - 0.5) * 100000.0);
|
||||
if (star.location.getNorm() < 30000.0) {
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
double brillance = RandomGenerator::random() * 0.05 + 0.1;
|
||||
star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03, 1.0);
|
||||
star.col = Color(brillance + RandomGenerator::random() * 0.03, brillance + RandomGenerator::random() * 0.03,
|
||||
brillance + RandomGenerator::random() * 0.03, 1.0);
|
||||
star.radius = 30.0 + RandomGenerator::random() * 20.0;
|
||||
|
||||
stars.push_back(star);
|
||||
|
|
|
@ -11,24 +11,17 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode
|
||||
{
|
||||
public:
|
||||
typedef struct
|
||||
{
|
||||
class DEFINITIONSHARED_EXPORT AtmosphereDefinition : public DefinitionNode {
|
||||
public:
|
||||
typedef struct {
|
||||
Vector3 location;
|
||||
double radius;
|
||||
Color col;
|
||||
} Star;
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
ATMOSPHERE_MODEL_DISABLED = 0,
|
||||
ATMOSPHERE_MODEL_BRUNETON = 1
|
||||
} AtmosphereModel;
|
||||
typedef enum
|
||||
{
|
||||
public:
|
||||
typedef enum { ATMOSPHERE_MODEL_DISABLED = 0, ATMOSPHERE_MODEL_BRUNETON = 1 } AtmosphereModel;
|
||||
typedef enum {
|
||||
ATMOSPHERE_PRESET_CLEAR_DAY = 0,
|
||||
ATMOSPHERE_PRESET_CLEAR_SUNSET = 1,
|
||||
ATMOSPHERE_PRESET_HAZY_MORNING = 2,
|
||||
|
@ -36,19 +29,27 @@ public:
|
|||
ATMOSPHERE_PRESET_STORMY = 4
|
||||
} AtmospherePreset;
|
||||
|
||||
public:
|
||||
AtmosphereDefinition(DefinitionNode* parent);
|
||||
public:
|
||||
AtmosphereDefinition(DefinitionNode *parent);
|
||||
virtual ~AtmosphereDefinition();
|
||||
|
||||
virtual void save(PackStream* stream) const override;
|
||||
virtual void load(PackStream* stream) override;
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
|
||||
inline GodRaysDefinition *childGodRays() const {return godrays;}
|
||||
inline FloatNode *propDayTime() const {return daytime;}
|
||||
inline FloatNode *propHumidity() const {return humidity;}
|
||||
inline FloatNode *propSunRadius() const {return sun_radius;}
|
||||
inline GodRaysDefinition *childGodRays() const {
|
||||
return godrays;
|
||||
}
|
||||
inline FloatNode *propDayTime() const {
|
||||
return daytime;
|
||||
}
|
||||
inline FloatNode *propHumidity() const {
|
||||
return humidity;
|
||||
}
|
||||
inline FloatNode *propSunRadius() const {
|
||||
return sun_radius;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the daytime from a 0.0-1.0 value.
|
||||
|
@ -57,7 +58,7 @@ public:
|
|||
/**
|
||||
* Set the daytime from hour/minute/second info.
|
||||
*/
|
||||
void setDayTime(int hour, int minute=0, int second=0);
|
||||
void setDayTime(int hour, int minute = 0, int second = 0);
|
||||
/**
|
||||
* Get the daytime info, in hour/minute/second.
|
||||
*/
|
||||
|
@ -66,7 +67,7 @@ public:
|
|||
void applyPreset(AtmospherePreset preset);
|
||||
void generateStars(int count);
|
||||
|
||||
public:
|
||||
public:
|
||||
AtmosphereModel model;
|
||||
|
||||
Color sun_color;
|
||||
|
@ -78,13 +79,12 @@ public:
|
|||
|
||||
std::vector<Star> stars;
|
||||
|
||||
private:
|
||||
private:
|
||||
GodRaysDefinition *godrays;
|
||||
FloatNode *humidity;
|
||||
FloatNode *daytime;
|
||||
FloatNode *sun_radius;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,9 +4,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "BoundingBox.h"
|
||||
|
||||
CameraDefinition::CameraDefinition(DefinitionNode *parent):
|
||||
DefinitionNode(parent, "camera", "camera")
|
||||
{
|
||||
CameraDefinition::CameraDefinition(DefinitionNode *parent) : DefinitionNode(parent, "camera", "camera") {
|
||||
location.x = 0.0;
|
||||
location.y = 0.0;
|
||||
location.z = 0.0;
|
||||
|
@ -25,8 +23,7 @@ CameraDefinition::CameraDefinition(DefinitionNode *parent):
|
|||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::save(PackStream* stream) const
|
||||
{
|
||||
void CameraDefinition::save(PackStream *stream) const {
|
||||
location.save(stream);
|
||||
stream->write(&direction.r);
|
||||
stream->write(&direction.phi);
|
||||
|
@ -35,8 +32,7 @@ void CameraDefinition::save(PackStream* stream) const
|
|||
stream->write(&perspective.yfov);
|
||||
}
|
||||
|
||||
void CameraDefinition::load(PackStream* stream)
|
||||
{
|
||||
void CameraDefinition::load(PackStream *stream) {
|
||||
location.load(stream);
|
||||
stream->read(&direction.r);
|
||||
stream->read(&direction.phi);
|
||||
|
@ -47,9 +43,8 @@ void CameraDefinition::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::copy(DefinitionNode* _destination) const
|
||||
{
|
||||
CameraDefinition* destination = (CameraDefinition*)_destination;
|
||||
void CameraDefinition::copy(DefinitionNode *_destination) const {
|
||||
CameraDefinition *destination = (CameraDefinition *)_destination;
|
||||
|
||||
destination->location = location;
|
||||
destination->direction = direction;
|
||||
|
@ -60,10 +55,8 @@ void CameraDefinition::copy(DefinitionNode* _destination) const
|
|||
destination->validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::validate()
|
||||
{
|
||||
if (location.y > 300.0)
|
||||
{
|
||||
void CameraDefinition::validate() {
|
||||
if (location.y > 300.0) {
|
||||
location.y = 300.0;
|
||||
}
|
||||
|
||||
|
@ -85,7 +78,8 @@ void CameraDefinition::validate()
|
|||
|
||||
target = location.add(direction);
|
||||
|
||||
Matrix4 mperspective = Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
|
||||
Matrix4 mperspective =
|
||||
Matrix4::newPerspective(perspective.yfov, perspective.xratio, perspective.znear, perspective.zfar);
|
||||
unperspective = mperspective.inversed();
|
||||
|
||||
projector = mperspective.mult(Matrix4::newLookAt(location, target, up));
|
||||
|
@ -95,33 +89,28 @@ void CameraDefinition::validate()
|
|||
inv_y_factor = 1.0 / (0.5 * height);
|
||||
}
|
||||
|
||||
double CameraDefinition::getRealDepth(const Vector3 &projected) const
|
||||
{
|
||||
double CameraDefinition::getRealDepth(const Vector3 &projected) const {
|
||||
Vector3 v(projected.x * inv_x_factor - 1.0, -(projected.y * inv_x_factor - 1.0), projected.z);
|
||||
return unperspective.transform(v).z;
|
||||
}
|
||||
|
||||
void CameraDefinition::setLocation(const Vector3 &location)
|
||||
{
|
||||
void CameraDefinition::setLocation(const Vector3 &location) {
|
||||
this->location = location;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setLocationCoords(double x, double y, double z)
|
||||
{
|
||||
void CameraDefinition::setLocationCoords(double x, double y, double z) {
|
||||
location = Vector3(x, y, z);
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setTarget(const Vector3 &target)
|
||||
{
|
||||
void CameraDefinition::setTarget(const Vector3 &target) {
|
||||
Vector3 forward;
|
||||
|
||||
forward = target.sub(location);
|
||||
if (forward.getNorm() < 0.0000001)
|
||||
{
|
||||
if (forward.getNorm() < 0.0000001) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -130,77 +119,66 @@ void CameraDefinition::setTarget(const Vector3 &target)
|
|||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setTargetCoords(double x, double y, double z)
|
||||
{
|
||||
void CameraDefinition::setTargetCoords(double x, double y, double z) {
|
||||
setTarget(Vector3(x, y, z));
|
||||
}
|
||||
|
||||
void CameraDefinition::setRoll(double angle)
|
||||
{
|
||||
void CameraDefinition::setRoll(double angle) {
|
||||
roll = angle;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setZoomToTarget(double zoom)
|
||||
{
|
||||
void CameraDefinition::setZoomToTarget(double zoom) {
|
||||
direction.r = zoom;
|
||||
location = target.add(Vector3(direction).scale(-1.0));
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setFov(double fov)
|
||||
{
|
||||
void CameraDefinition::setFov(double fov) {
|
||||
perspective.yfov = fov;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::strafeForward(double value)
|
||||
{
|
||||
void CameraDefinition::strafeForward(double value) {
|
||||
location = location.add(forward.scale(value));
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::strafeRight(double value)
|
||||
{
|
||||
void CameraDefinition::strafeRight(double value) {
|
||||
location = location.add(right.scale(value));
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::strafeUp(double value)
|
||||
{
|
||||
void CameraDefinition::strafeUp(double value) {
|
||||
location = location.add(up.scale(value));
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::rotateYaw(double value)
|
||||
{
|
||||
void CameraDefinition::rotateYaw(double value) {
|
||||
direction.phi += value;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::rotatePitch(double value)
|
||||
{
|
||||
void CameraDefinition::rotatePitch(double value) {
|
||||
direction.theta += value;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::rotateRoll(double value)
|
||||
{
|
||||
void CameraDefinition::rotateRoll(double value) {
|
||||
roll += value;
|
||||
|
||||
validate();
|
||||
}
|
||||
|
||||
void CameraDefinition::setRenderSize(int width, int height)
|
||||
{
|
||||
void CameraDefinition::setRenderSize(int width, int height) {
|
||||
this->width = (double)width;
|
||||
this->height = (double)height;
|
||||
perspective.xratio = this->width / this->height;
|
||||
|
@ -208,11 +186,9 @@ void CameraDefinition::setRenderSize(int width, int height)
|
|||
validate();
|
||||
}
|
||||
|
||||
Vector3 CameraDefinition::project(const Vector3 &point) const
|
||||
{
|
||||
Vector3 CameraDefinition::project(const Vector3 &point) const {
|
||||
Vector3 tpoint = projector.transform(point);
|
||||
if (tpoint.z < 1.0)
|
||||
{
|
||||
if (tpoint.z < 1.0) {
|
||||
tpoint.x = -tpoint.x;
|
||||
tpoint.y = -tpoint.y;
|
||||
}
|
||||
|
@ -221,19 +197,16 @@ Vector3 CameraDefinition::project(const Vector3 &point) const
|
|||
return tpoint;
|
||||
}
|
||||
|
||||
Vector3 CameraDefinition::unproject(const Vector3 &point) const
|
||||
{
|
||||
Vector3 CameraDefinition::unproject(const Vector3 &point) const {
|
||||
Vector3 tpoint(point.x / (0.5 * width) - 1.0, -(point.y / (0.5 * height) - 1.0), point.z);
|
||||
if (tpoint.z < 1.0)
|
||||
{
|
||||
if (tpoint.z < 1.0) {
|
||||
tpoint.x = -tpoint.x;
|
||||
tpoint.y = -tpoint.y;
|
||||
}
|
||||
return unprojector.transform(tpoint);
|
||||
}
|
||||
|
||||
int CameraDefinition::isBoxInView(const Vector3 ¢er, double xsize, double ysize, double zsize) const
|
||||
{
|
||||
int CameraDefinition::isBoxInView(const Vector3 ¢er, double xsize, double ysize, double zsize) const {
|
||||
BoundingBox box;
|
||||
|
||||
box.pushPoint(center.add(Vector3(-xsize, -ysize, -zsize)));
|
||||
|
@ -242,8 +215,7 @@ int CameraDefinition::isBoxInView(const Vector3 ¢er, double xsize, double ys
|
|||
return isUnprojectedBoxInView(box);
|
||||
}
|
||||
|
||||
int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const
|
||||
{
|
||||
int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const {
|
||||
BoundingBox projected;
|
||||
|
||||
projected.pushPoint(project(Vector3(box.xmin, box.ymin, box.zmin)));
|
||||
|
@ -258,23 +230,19 @@ int CameraDefinition::isUnprojectedBoxInView(const BoundingBox &box) const
|
|||
return isProjectedBoxInView(projected);
|
||||
}
|
||||
|
||||
int CameraDefinition::isProjectedBoxInView(const BoundingBox &box) const
|
||||
{
|
||||
if (box.xmin <= width && box.xmax >= 0.0 && box.ymin <= height && box.ymax >= 0.0 && box.zmax >= perspective.znear)
|
||||
{
|
||||
int CameraDefinition::isProjectedBoxInView(const BoundingBox &box) const {
|
||||
if (box.xmin <= width && box.xmax >= 0.0 && box.ymin <= height && box.ymax >= 0.0 &&
|
||||
box.zmax >= perspective.znear) {
|
||||
double dx = box.xmax - box.xmin;
|
||||
double dy = box.ymax - box.ymin;
|
||||
|
||||
return (int)ceil(dx) * (int)ceil(dy);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, double factor)
|
||||
{
|
||||
bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, double factor) {
|
||||
double dx, dy, dz, dr, dphi, dtheta, droll;
|
||||
|
||||
dx = wanted->location.x - location.x;
|
||||
|
@ -285,12 +253,10 @@ bool CameraDefinition::transitionToAnother(const CameraDefinition *wanted, doubl
|
|||
dtheta = wanted->direction.theta - direction.theta;
|
||||
droll = wanted->roll - roll;
|
||||
|
||||
if (fabs(dx) < 0.000001 && fabs(dy) < 0.000001 && fabs(dz) < 0.000001 && fabs(dr) < 0.000001 && fabs(dphi) < 0.000001 && fabs(dtheta) < 0.000001 && fabs(droll) < 0.000001)
|
||||
{
|
||||
if (fabs(dx) < 0.000001 && fabs(dy) < 0.000001 && fabs(dz) < 0.000001 && fabs(dr) < 0.000001 &&
|
||||
fabs(dphi) < 0.000001 && fabs(dtheta) < 0.000001 && fabs(droll) < 0.000001) {
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
location.x += dx * factor;
|
||||
location.y += dy * factor;
|
||||
location.z += dz * factor;
|
||||
|
|
|
@ -11,36 +11,56 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double yfov;
|
||||
double xratio;
|
||||
double znear;
|
||||
double zfar;
|
||||
} CameraPerspective;
|
||||
|
||||
class DEFINITIONSHARED_EXPORT CameraDefinition: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT CameraDefinition : public DefinitionNode {
|
||||
public:
|
||||
CameraDefinition(DefinitionNode *parent = NULL);
|
||||
|
||||
virtual void save(PackStream* pack) const override;
|
||||
virtual void load(PackStream* pack) override;
|
||||
virtual void save(PackStream *pack) const override;
|
||||
virtual void load(PackStream *pack) override;
|
||||
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
inline const Vector3 &getLocation() const {return location;}
|
||||
inline const Vector3 &getTarget() const {return target;}
|
||||
inline const Vector3 &getUpVector() const {return up;}
|
||||
inline double getRoll() const {return roll;}
|
||||
inline Vector3 getDirection() const {return Vector3(direction);}
|
||||
inline const Vector3 &getDirectionNormalized() const {return forward;}
|
||||
inline const Matrix4 &getTransformationMatrix() const {return projector;}
|
||||
inline const VectorSpherical &getDirectionSpherical() const {return direction;}
|
||||
inline const CameraPerspective &getPerspective() const {return perspective;}
|
||||
inline double getWidth() const {return width;}
|
||||
inline double getHeight() const {return height;}
|
||||
inline const Vector3 &getLocation() const {
|
||||
return location;
|
||||
}
|
||||
inline const Vector3 &getTarget() const {
|
||||
return target;
|
||||
}
|
||||
inline const Vector3 &getUpVector() const {
|
||||
return up;
|
||||
}
|
||||
inline double getRoll() const {
|
||||
return roll;
|
||||
}
|
||||
inline Vector3 getDirection() const {
|
||||
return Vector3(direction);
|
||||
}
|
||||
inline const Vector3 &getDirectionNormalized() const {
|
||||
return forward;
|
||||
}
|
||||
inline const Matrix4 &getTransformationMatrix() const {
|
||||
return projector;
|
||||
}
|
||||
inline const VectorSpherical &getDirectionSpherical() const {
|
||||
return direction;
|
||||
}
|
||||
inline const CameraPerspective &getPerspective() const {
|
||||
return perspective;
|
||||
}
|
||||
inline double getWidth() const {
|
||||
return width;
|
||||
}
|
||||
inline double getHeight() const {
|
||||
return height;
|
||||
}
|
||||
|
||||
double getRealDepth(const Vector3 &projected) const;
|
||||
|
||||
|
@ -68,7 +88,7 @@ public:
|
|||
|
||||
bool transitionToAnother(const CameraDefinition *wanted, double factor);
|
||||
|
||||
private:
|
||||
private:
|
||||
/* Definition */
|
||||
Vector3 location;
|
||||
VectorSpherical direction;
|
||||
|
@ -90,7 +110,6 @@ private:
|
|||
double inv_x_factor;
|
||||
double inv_y_factor;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,9 +6,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode* parent):
|
||||
DefinitionNode(parent, "layer", "cloudlayer")
|
||||
{
|
||||
CloudLayerDefinition::CloudLayerDefinition(DefinitionNode *parent) : DefinitionNode(parent, "layer", "cloudlayer") {
|
||||
type = CIRRUS;
|
||||
altitude = 0.5;
|
||||
scaling = 0.5;
|
||||
|
@ -18,26 +16,22 @@ CloudLayerDefinition::CloudLayerDefinition(DefinitionNode* parent):
|
|||
zoffset = new FloatNode(this, "zoffset");
|
||||
}
|
||||
|
||||
CloudLayerDefinition::~CloudLayerDefinition()
|
||||
{
|
||||
CloudLayerDefinition::~CloudLayerDefinition() {
|
||||
}
|
||||
|
||||
CloudLayerDefinition* CloudLayerDefinition::newCopy(const CloudLayerDefinition& other, DefinitionNode* parent)
|
||||
{
|
||||
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
|
||||
CloudLayerDefinition *CloudLayerDefinition::newCopy(const CloudLayerDefinition &other, DefinitionNode *parent) {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
|
||||
other.copy(layer);
|
||||
return layer;
|
||||
}
|
||||
|
||||
CloudLayerDefinition* CloudLayerDefinition::newCopy(DefinitionNode* parent) const
|
||||
{
|
||||
CloudLayerDefinition* layer = new CloudLayerDefinition(parent);
|
||||
CloudLayerDefinition *CloudLayerDefinition::newCopy(DefinitionNode *parent) const {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(parent);
|
||||
copy(layer);
|
||||
return layer;
|
||||
}
|
||||
|
||||
void CloudLayerDefinition::save(PackStream* stream) const
|
||||
{
|
||||
void CloudLayerDefinition::save(PackStream *stream) const {
|
||||
DefinitionNode::save(stream);
|
||||
|
||||
int clouds_type = (int)type;
|
||||
|
@ -50,8 +44,7 @@ void CloudLayerDefinition::save(PackStream* stream) const
|
|||
noise_state.save(stream);
|
||||
}
|
||||
|
||||
void CloudLayerDefinition::load(PackStream* stream)
|
||||
{
|
||||
void CloudLayerDefinition::load(PackStream *stream) {
|
||||
DefinitionNode::load(stream);
|
||||
|
||||
int clouds_type;
|
||||
|
@ -67,11 +60,10 @@ void CloudLayerDefinition::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
void CloudLayerDefinition::copy(DefinitionNode* _destination) const
|
||||
{
|
||||
void CloudLayerDefinition::copy(DefinitionNode *_destination) const {
|
||||
DefinitionNode::copy(_destination);
|
||||
|
||||
CloudLayerDefinition* destination = (CloudLayerDefinition*)_destination;
|
||||
CloudLayerDefinition *destination = (CloudLayerDefinition *)_destination;
|
||||
|
||||
destination->type = type;
|
||||
destination->altitude = altitude;
|
||||
|
@ -81,12 +73,10 @@ void CloudLayerDefinition::copy(DefinitionNode* _destination) const
|
|||
noise_state.copy(&destination->noise_state);
|
||||
}
|
||||
|
||||
void CloudLayerDefinition::validate()
|
||||
{
|
||||
void CloudLayerDefinition::validate() {
|
||||
DefinitionNode::validate();
|
||||
|
||||
if (scaling < 0.1)
|
||||
{
|
||||
if (scaling < 0.1) {
|
||||
scaling = 0.1;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,28 +10,32 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode
|
||||
{
|
||||
public:
|
||||
CloudLayerDefinition(DefinitionNode* parent);
|
||||
class DEFINITIONSHARED_EXPORT CloudLayerDefinition : public DefinitionNode {
|
||||
public:
|
||||
CloudLayerDefinition(DefinitionNode *parent);
|
||||
virtual ~CloudLayerDefinition();
|
||||
|
||||
inline const NoiseState &getNoiseState() const {return noise_state;}
|
||||
inline FloatNode *propXOffset() const {return xoffset;}
|
||||
inline FloatNode *propZOffset() const {return zoffset;}
|
||||
inline const NoiseState &getNoiseState() const {
|
||||
return noise_state;
|
||||
}
|
||||
inline FloatNode *propXOffset() const {
|
||||
return xoffset;
|
||||
}
|
||||
inline FloatNode *propZOffset() const {
|
||||
return zoffset;
|
||||
}
|
||||
|
||||
static CloudLayerDefinition* newCopy(const CloudLayerDefinition& other, DefinitionNode* parent);
|
||||
CloudLayerDefinition* newCopy(DefinitionNode* parent) const;
|
||||
static CloudLayerDefinition *newCopy(const CloudLayerDefinition &other, DefinitionNode *parent);
|
||||
CloudLayerDefinition *newCopy(DefinitionNode *parent) const;
|
||||
|
||||
virtual void save(PackStream* pack) const override;
|
||||
virtual void load(PackStream* pack) override;
|
||||
virtual void save(PackStream *pack) const override;
|
||||
virtual void load(PackStream *pack) override;
|
||||
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
public:
|
||||
typedef enum {
|
||||
STRATUS,
|
||||
NIMBOSTRATUS,
|
||||
CUMULUS,
|
||||
|
@ -44,18 +48,17 @@ public:
|
|||
CIRRUS
|
||||
} CloudsType;
|
||||
|
||||
public:
|
||||
public:
|
||||
CloudsType type;
|
||||
NoiseState noise_state;
|
||||
double altitude;
|
||||
double scaling;
|
||||
double coverage;
|
||||
|
||||
private:
|
||||
private:
|
||||
FloatNode *xoffset;
|
||||
FloatNode *zoffset;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,23 +2,18 @@
|
|||
|
||||
#include "CloudLayerDefinition.h"
|
||||
|
||||
static DefinitionNode* _layerConstructor(Layers* parent)
|
||||
{
|
||||
static DefinitionNode *_layerConstructor(Layers *parent) {
|
||||
return new CloudLayerDefinition(parent);
|
||||
}
|
||||
|
||||
CloudsDefinition::CloudsDefinition(DefinitionNode* parent):
|
||||
Layers(parent, "clouds", _layerConstructor)
|
||||
{
|
||||
CloudsDefinition::CloudsDefinition(DefinitionNode *parent) : Layers(parent, "clouds", _layerConstructor) {
|
||||
}
|
||||
|
||||
void CloudsDefinition::applyPreset(CloudsPreset preset)
|
||||
{
|
||||
void CloudsDefinition::applyPreset(CloudsPreset preset) {
|
||||
clear();
|
||||
|
||||
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY)
|
||||
{
|
||||
CloudLayerDefinition* layer = new CloudLayerDefinition(this);
|
||||
if (preset == CLOUDS_PRESET_PARTLY_CLOUDY) {
|
||||
CloudLayerDefinition *layer = new CloudLayerDefinition(this);
|
||||
layer->type = CloudLayerDefinition::STRATOCUMULUS;
|
||||
layer->setName("Strato-cumulus");
|
||||
addLayer(layer);
|
||||
|
|
|
@ -8,20 +8,17 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers
|
||||
{
|
||||
public:
|
||||
CloudsDefinition(DefinitionNode* parent);
|
||||
class DEFINITIONSHARED_EXPORT CloudsDefinition : public Layers {
|
||||
public:
|
||||
CloudsDefinition(DefinitionNode *parent);
|
||||
|
||||
inline CloudLayerDefinition* getCloudLayer(int position) const {return (CloudLayerDefinition*)getLayer(position);}
|
||||
inline CloudLayerDefinition *getCloudLayer(int position) const {
|
||||
return (CloudLayerDefinition *)getLayer(position);
|
||||
}
|
||||
|
||||
typedef enum
|
||||
{
|
||||
CLOUDS_PRESET_PARTLY_CLOUDY
|
||||
} CloudsPreset;
|
||||
typedef enum { CLOUDS_PRESET_PARTLY_CLOUDY } CloudsPreset;
|
||||
void applyPreset(CloudsPreset preset);
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,5 @@
|
|||
|
||||
#include "DefinitionNode.h"
|
||||
|
||||
DefinitionDiff::DefinitionDiff(const DefinitionNode *node):
|
||||
type_name(node->getTypeName()), path(node->getPath())
|
||||
{
|
||||
DefinitionDiff::DefinitionDiff(const DefinitionNode *node) : type_name(node->getTypeName()), path(node->getPath()) {
|
||||
}
|
||||
|
|
|
@ -11,19 +11,21 @@ namespace definition {
|
|||
*
|
||||
* Diffs are used to undo/redo changes.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT DefinitionDiff
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT DefinitionDiff {
|
||||
public:
|
||||
DefinitionDiff(const DefinitionNode *node);
|
||||
|
||||
inline const std::string &getTypeName() const {return type_name;}
|
||||
inline const std::string &getPath() const {return path;}
|
||||
inline const std::string &getTypeName() const {
|
||||
return type_name;
|
||||
}
|
||||
inline const std::string &getPath() const {
|
||||
return path;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
std::string type_name;
|
||||
std::string path;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,171 +8,123 @@
|
|||
|
||||
#include <cassert>
|
||||
|
||||
DefinitionNode::DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name):
|
||||
parent(parent), type_name(type_name), name(name)
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
DefinitionNode::DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name)
|
||||
: parent(parent), type_name(type_name), name(name) {
|
||||
if (parent) {
|
||||
root = parent->root;
|
||||
parent->addChild(this);
|
||||
diffs = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
root = this;
|
||||
diffs = new DiffManager(this);
|
||||
}
|
||||
}
|
||||
|
||||
DefinitionNode::~DefinitionNode()
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
DefinitionNode::~DefinitionNode() {
|
||||
if (parent) {
|
||||
parent->removeChild(this);
|
||||
parent = NULL;
|
||||
}
|
||||
|
||||
if (diffs)
|
||||
{
|
||||
if (diffs) {
|
||||
delete diffs;
|
||||
diffs = NULL;
|
||||
}
|
||||
|
||||
// Work on a copy, because the child destructor will modify the array by removing itself using removeChild
|
||||
std::vector<DefinitionNode*> children_copy = children;
|
||||
for (auto child:children_copy)
|
||||
{
|
||||
if (child->getParent() == this)
|
||||
{
|
||||
std::vector<DefinitionNode *> children_copy = children;
|
||||
for (auto child : children_copy) {
|
||||
if (child->getParent() == this) {
|
||||
delete child;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::setName(const std::string &name)
|
||||
{
|
||||
void DefinitionNode::setName(const std::string &name) {
|
||||
this->name = name;
|
||||
}
|
||||
|
||||
Scenery* DefinitionNode::getScenery()
|
||||
{
|
||||
if (parent)
|
||||
{
|
||||
Scenery *DefinitionNode::getScenery() {
|
||||
if (parent) {
|
||||
return parent->getScenery();
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
std::string DefinitionNode::toString(int indent) const
|
||||
{
|
||||
std::string DefinitionNode::toString(int indent) const {
|
||||
std::string result;
|
||||
for (int i = 0; i < indent; i++)
|
||||
{
|
||||
for (int i = 0; i < indent; i++) {
|
||||
result += " ";
|
||||
}
|
||||
result += name;
|
||||
if (not children.empty())
|
||||
{
|
||||
for (auto &child: children)
|
||||
{
|
||||
if (not children.empty()) {
|
||||
for (auto &child : children) {
|
||||
result += "\n" + child->toString(indent + 1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
std::string DefinitionNode::getPath() const
|
||||
{
|
||||
if (parent == root)
|
||||
{
|
||||
std::string DefinitionNode::getPath() const {
|
||||
if (parent == root) {
|
||||
return parent->getPath() + name;
|
||||
}
|
||||
else if (parent)
|
||||
{
|
||||
} else if (parent) {
|
||||
return parent->getPath() + "/" + name;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return "/";
|
||||
}
|
||||
}
|
||||
|
||||
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const
|
||||
{
|
||||
if (path.empty())
|
||||
{
|
||||
DefinitionNode *DefinitionNode::findByPath(const std::string &path) const {
|
||||
if (path.empty()) {
|
||||
return NULL;
|
||||
}
|
||||
else if (path[0] == '/')
|
||||
{
|
||||
if (path.length() == 1)
|
||||
{
|
||||
} else if (path[0] == '/') {
|
||||
if (path.length() == 1) {
|
||||
return root;
|
||||
}
|
||||
else if (root == this)
|
||||
{
|
||||
} else if (root == this) {
|
||||
return findByPath(path.substr(1));
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return root->findByPath(path);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
size_t seppos = path.find("/");
|
||||
std::string child_name = (seppos == std::string::npos) ? path : path.substr(0, seppos);
|
||||
DefinitionNode *child = ((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
|
||||
if (child)
|
||||
{
|
||||
if (seppos == std::string::npos)
|
||||
{
|
||||
DefinitionNode *child =
|
||||
((DefinitionNode *)this)->findChildByName(child_name); // FIXME findChildByName should be const
|
||||
if (child) {
|
||||
if (seppos == std::string::npos) {
|
||||
return child;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return child->findByPath(path.substr(seppos + 1));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool)
|
||||
{
|
||||
bool DefinitionNode::applyDiff(const DefinitionDiff *diff, bool) {
|
||||
// Only do type check, subclasses will do the rest
|
||||
if (diff->getTypeName() == type_name)
|
||||
{
|
||||
if (diff->getTypeName() == type_name) {
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs::error() << "Can't apply " << diff->getTypeName() << " diff to " << getName() << " " << type_name << " node" << std::endl;
|
||||
} else {
|
||||
Logs::error() << "Can't apply " << diff->getTypeName() << " diff to " << getName() << " " << type_name
|
||||
<< " node" << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const
|
||||
{
|
||||
void DefinitionNode::generateInitDiffs(std::vector<const DefinitionDiff *> *) const {
|
||||
}
|
||||
|
||||
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff)
|
||||
{
|
||||
if (root && root->diffs)
|
||||
{
|
||||
if (init_diff)
|
||||
{
|
||||
void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff) {
|
||||
if (root && root->diffs) {
|
||||
if (init_diff) {
|
||||
std::vector<const DefinitionDiff *> diffs;
|
||||
generateInitDiffs(&diffs);
|
||||
|
||||
for (auto diff: diffs)
|
||||
{
|
||||
for (auto diff : diffs) {
|
||||
watcher->nodeChanged(this, diff);
|
||||
delete diff;
|
||||
}
|
||||
|
@ -181,37 +133,29 @@ void DefinitionNode::addWatcher(DefinitionWatcher *watcher, bool init_diff)
|
|||
}
|
||||
}
|
||||
|
||||
int DefinitionNode::getWatcherCount() const
|
||||
{
|
||||
if (root && root->diffs)
|
||||
{
|
||||
int DefinitionNode::getWatcherCount() const {
|
||||
if (root && root->diffs) {
|
||||
return root->diffs->getWatcherCount(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::save(PackStream* stream) const
|
||||
{
|
||||
void DefinitionNode::save(PackStream *stream) const {
|
||||
int children_count = (int)children.size();
|
||||
stream->write(&children_count);
|
||||
|
||||
for (auto child: children)
|
||||
{
|
||||
for (auto child : children) {
|
||||
stream->write(child->name);
|
||||
|
||||
int child_size = child->getStreamSize();
|
||||
if (child_size >= 0)
|
||||
{
|
||||
if (child_size >= 0) {
|
||||
stream->write(&child_size);
|
||||
child->save(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// Child size not known, write it to a temporary stream to know it
|
||||
Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream" << std::endl;
|
||||
Logs::debug() << "Unknown size for child " << child->name << ", unefficient writing to temporary stream"
|
||||
<< std::endl;
|
||||
PackStream substream;
|
||||
child->save(&substream);
|
||||
stream->writeFromBuffer(substream, true);
|
||||
|
@ -219,27 +163,22 @@ void DefinitionNode::save(PackStream* stream) const
|
|||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::load(PackStream* stream)
|
||||
{
|
||||
void DefinitionNode::load(PackStream *stream) {
|
||||
int children_count;
|
||||
|
||||
stream->read(&children_count);
|
||||
|
||||
for (int i = 0; i < children_count; i++)
|
||||
{
|
||||
for (int i = 0; i < children_count; i++) {
|
||||
std::string child_name = stream->readString();
|
||||
|
||||
int child_size;
|
||||
stream->read(&child_size);
|
||||
|
||||
DefinitionNode *child = findChildByName(child_name);
|
||||
if (child)
|
||||
{
|
||||
if (child) {
|
||||
// TODO type check
|
||||
child->load(stream);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
// TODO Ask subclass if it can instanciate a child
|
||||
// Else skip length of unknown child
|
||||
stream->skipBytes(child_size);
|
||||
|
@ -248,85 +187,65 @@ void DefinitionNode::load(PackStream* stream)
|
|||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::copy(DefinitionNode* destination) const
|
||||
{
|
||||
if (destination->getTypeName() == getTypeName())
|
||||
{
|
||||
void DefinitionNode::copy(DefinitionNode *destination) const {
|
||||
if (destination->getTypeName() == getTypeName()) {
|
||||
destination->setName(name);
|
||||
for (auto &child: children)
|
||||
{
|
||||
for (auto &child : children) {
|
||||
DefinitionNode *dest_child = destination->findChildByName(child->name);
|
||||
if (dest_child)
|
||||
{
|
||||
if (dest_child) {
|
||||
child->copy(dest_child);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs::warning() << "Can't copy to child " << child->name << " of " << destination->getTypeName() << std::endl;
|
||||
} else {
|
||||
Logs::warning() << "Can't copy to child " << child->name << " of " << destination->getTypeName()
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::validate()
|
||||
{
|
||||
for (auto child: children)
|
||||
{
|
||||
void DefinitionNode::validate() {
|
||||
for (auto child : children) {
|
||||
child->validate();
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::addChild(DefinitionNode* child)
|
||||
{
|
||||
if (std::find(children.begin(), children.end(), child) == children.end())
|
||||
{
|
||||
void DefinitionNode::addChild(DefinitionNode *child) {
|
||||
if (std::find(children.begin(), children.end(), child) == children.end()) {
|
||||
children.push_back(child);
|
||||
child->parent = this;
|
||||
child->root = this->root;
|
||||
}
|
||||
}
|
||||
|
||||
void DefinitionNode::removeChild(DefinitionNode* child)
|
||||
{
|
||||
std::vector<DefinitionNode*>::iterator it = std::find(children.begin(), children.end(), child);
|
||||
if (it != children.end())
|
||||
{
|
||||
void DefinitionNode::removeChild(DefinitionNode *child) {
|
||||
std::vector<DefinitionNode *>::iterator it = std::find(children.begin(), children.end(), child);
|
||||
if (it != children.end()) {
|
||||
child->parent = NULL;
|
||||
children.erase(it);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'" << std::endl;
|
||||
} else {
|
||||
Logs::warning() << "Trying to remove not found child '" << child->name << "' from '" << name << "'"
|
||||
<< std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
DefinitionNode *DefinitionNode::findChildByName(const std::string name)
|
||||
{
|
||||
for (auto child: children)
|
||||
{
|
||||
if (child->name == name)
|
||||
{
|
||||
DefinitionNode *DefinitionNode::findChildByName(const std::string name) {
|
||||
for (auto child : children) {
|
||||
if (child->name == name) {
|
||||
return child;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int DefinitionNode::getStreamSize() const
|
||||
{
|
||||
int DefinitionNode::getStreamSize() const {
|
||||
return -1;
|
||||
}
|
||||
|
||||
void DefinitionNode::addDiff(const DefinitionDiff *diff)
|
||||
{
|
||||
void DefinitionNode::addDiff(const DefinitionDiff *diff) {
|
||||
assert(diff->getTypeName() == type_name);
|
||||
|
||||
if (root && root->diffs)
|
||||
{
|
||||
if (root && root->diffs) {
|
||||
root->diffs->addDiff(this, diff);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,29 +9,40 @@ namespace definition {
|
|||
/**
|
||||
* Base class for all nodes of the definition tree.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT DefinitionNode
|
||||
{
|
||||
public:
|
||||
DefinitionNode(DefinitionNode* parent, const std::string &name, const std::string &type_name = "");
|
||||
class DEFINITIONSHARED_EXPORT DefinitionNode {
|
||||
public:
|
||||
DefinitionNode(DefinitionNode *parent, const std::string &name, const std::string &type_name = "");
|
||||
virtual ~DefinitionNode();
|
||||
|
||||
virtual void save(PackStream* stream) const;
|
||||
virtual void load(PackStream* stream);
|
||||
virtual void save(PackStream *stream) const;
|
||||
virtual void load(PackStream *stream);
|
||||
|
||||
virtual void copy(DefinitionNode* destination) const;
|
||||
virtual void copy(DefinitionNode *destination) const;
|
||||
virtual void validate();
|
||||
|
||||
inline const std::string &getName() const {return name;}
|
||||
inline const std::string &getName() const {
|
||||
return name;
|
||||
}
|
||||
virtual void setName(const std::string &name);
|
||||
|
||||
inline const std::string &getTypeName() const {return type_name;}
|
||||
inline const std::string &getTypeName() const {
|
||||
return type_name;
|
||||
}
|
||||
|
||||
virtual Scenery* getScenery();
|
||||
virtual Scenery *getScenery();
|
||||
|
||||
inline const DefinitionNode *getParent() const {return parent;}
|
||||
inline const DefinitionNode *getRoot() const {return root;}
|
||||
inline DiffManager *getDiffManager() const {return diffs;}
|
||||
inline int getChildrenCount() const {return children.size();}
|
||||
inline const DefinitionNode *getParent() const {
|
||||
return parent;
|
||||
}
|
||||
inline const DefinitionNode *getRoot() const {
|
||||
return root;
|
||||
}
|
||||
inline DiffManager *getDiffManager() const {
|
||||
return diffs;
|
||||
}
|
||||
inline int getChildrenCount() const {
|
||||
return children.size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a string representation of the tree (mainly for debugging purposes).
|
||||
|
@ -59,7 +70,7 @@ public:
|
|||
*
|
||||
* Return true if the diff could be applied.
|
||||
*/
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false);
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false);
|
||||
|
||||
/**
|
||||
* Fill a diff array to be applied to initialize a proper state for a watcher.
|
||||
|
@ -75,16 +86,16 @@ public:
|
|||
*
|
||||
* If *init_diff* is set to true, a first diff (or several) will be be pushed immediately to initialize the state.
|
||||
*/
|
||||
void addWatcher(DefinitionWatcher *watcher, bool init_diff=false);
|
||||
void addWatcher(DefinitionWatcher *watcher, bool init_diff = false);
|
||||
|
||||
/**
|
||||
* Get the current number of watchers.
|
||||
*/
|
||||
int getWatcherCount() const;
|
||||
|
||||
protected:
|
||||
void addChild(DefinitionNode* child);
|
||||
void removeChild(DefinitionNode* child);
|
||||
protected:
|
||||
void addChild(DefinitionNode *child);
|
||||
void removeChild(DefinitionNode *child);
|
||||
virtual DefinitionNode *findChildByName(const std::string name);
|
||||
|
||||
/**
|
||||
|
@ -104,15 +115,14 @@ protected:
|
|||
*/
|
||||
void addDiff(const DefinitionDiff *diff);
|
||||
|
||||
private:
|
||||
private:
|
||||
DefinitionNode *parent;
|
||||
DefinitionNode *root;
|
||||
DiffManager *diffs;
|
||||
std::string type_name;
|
||||
std::string name;
|
||||
std::vector<DefinitionNode*> children;
|
||||
std::vector<DefinitionNode *> children;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
#include "DefinitionWatcher.h"
|
||||
|
||||
DefinitionWatcher::DefinitionWatcher()
|
||||
{
|
||||
|
||||
DefinitionWatcher::DefinitionWatcher() {
|
||||
}
|
||||
|
||||
|
|
|
@ -11,9 +11,8 @@ namespace definition {
|
|||
*
|
||||
* Watchers will be registered in DiffManager to receive DefinitionDiff objects.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT DefinitionWatcher
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT DefinitionWatcher {
|
||||
public:
|
||||
DefinitionWatcher();
|
||||
|
||||
/**
|
||||
|
@ -21,7 +20,6 @@ public:
|
|||
*/
|
||||
virtual void nodeChanged(const DefinitionNode *node, const DefinitionDiff *diff) = 0;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,38 +4,29 @@
|
|||
#include "DefinitionDiff.h"
|
||||
#include "DefinitionWatcher.h"
|
||||
|
||||
DiffManager::DiffManager(DefinitionNode *tree):
|
||||
tree(tree)
|
||||
{
|
||||
DiffManager::DiffManager(DefinitionNode *tree) : tree(tree) {
|
||||
undone = 0;
|
||||
}
|
||||
|
||||
DiffManager::~DiffManager()
|
||||
{
|
||||
for (auto diff: diffs)
|
||||
{
|
||||
DiffManager::~DiffManager() {
|
||||
for (auto diff : diffs) {
|
||||
delete diff;
|
||||
}
|
||||
diffs.clear();
|
||||
}
|
||||
|
||||
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher)
|
||||
{
|
||||
if (std::find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end())
|
||||
{
|
||||
void DiffManager::addWatcher(const DefinitionNode *node, DefinitionWatcher *watcher) {
|
||||
if (std::find(watchers[node].begin(), watchers[node].end(), watcher) == watchers[node].end()) {
|
||||
watchers[node].push_back(watcher);
|
||||
}
|
||||
}
|
||||
|
||||
int DiffManager::getWatcherCount(const DefinitionNode *node)
|
||||
{
|
||||
int DiffManager::getWatcherCount(const DefinitionNode *node) {
|
||||
return watchers[node].size();
|
||||
}
|
||||
|
||||
void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
|
||||
{
|
||||
while (undone > 0)
|
||||
{
|
||||
void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff) {
|
||||
while (undone > 0) {
|
||||
// truncate diffs ahead
|
||||
delete diffs.back();
|
||||
diffs.pop_back();
|
||||
|
@ -47,16 +38,13 @@ void DiffManager::addDiff(DefinitionNode *node, const DefinitionDiff *diff)
|
|||
// TODO Delayed commit (with merge of consecutive diffs)
|
||||
node->applyDiff(diff);
|
||||
|
||||
for (auto watcher: watchers[node])
|
||||
{
|
||||
for (auto watcher : watchers[node]) {
|
||||
watcher->nodeChanged(node, diff);
|
||||
}
|
||||
}
|
||||
|
||||
void DiffManager::undo()
|
||||
{
|
||||
if (undone < (int)diffs.size())
|
||||
{
|
||||
void DiffManager::undo() {
|
||||
if (undone < (int)diffs.size()) {
|
||||
undone++;
|
||||
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||
|
||||
|
@ -64,18 +52,15 @@ void DiffManager::undo()
|
|||
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||
node->applyDiff(diff, true);
|
||||
|
||||
for (auto watcher: watchers[node])
|
||||
{
|
||||
for (auto watcher : watchers[node]) {
|
||||
// FIXME Reverse diff
|
||||
watcher->nodeChanged(node, diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void DiffManager::redo()
|
||||
{
|
||||
if (undone > 0)
|
||||
{
|
||||
void DiffManager::redo() {
|
||||
if (undone > 0) {
|
||||
const DefinitionDiff *diff = diffs[diffs.size() - undone];
|
||||
undone--;
|
||||
|
||||
|
@ -83,10 +68,8 @@ void DiffManager::redo()
|
|||
DefinitionNode *node = tree->findByPath(diff->getPath());
|
||||
node->applyDiff(diff);
|
||||
|
||||
for (auto watcher: watchers[node])
|
||||
{
|
||||
for (auto watcher : watchers[node]) {
|
||||
watcher->nodeChanged(node, diff);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,9 +14,8 @@ namespace definition {
|
|||
*
|
||||
* Watchers can register themselves to received these diffs.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT DiffManager
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT DiffManager {
|
||||
public:
|
||||
DiffManager(DefinitionNode *tree);
|
||||
~DiffManager();
|
||||
|
||||
|
@ -47,13 +46,12 @@ public:
|
|||
*/
|
||||
void redo();
|
||||
|
||||
private:
|
||||
private:
|
||||
DefinitionNode *tree;
|
||||
int undone;
|
||||
std::vector<const DefinitionDiff *> diffs;
|
||||
std::map<const DefinitionNode *, std::vector<DefinitionWatcher *>> watchers;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include "FloatDiff.h"
|
||||
|
||||
FloatDiff::FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue):
|
||||
DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue)
|
||||
{
|
||||
FloatDiff::FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue)
|
||||
: DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue) {
|
||||
}
|
||||
|
|
|
@ -11,19 +11,21 @@ namespace definition {
|
|||
/**
|
||||
* Diff for a FloatNode.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT FloatDiff: public DefinitionDiff
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT FloatDiff : public DefinitionDiff {
|
||||
public:
|
||||
FloatDiff(const DefinitionNode *node, double oldvalue, double newvalue);
|
||||
|
||||
inline double getOldValue() const {return oldvalue;}
|
||||
inline double getNewValue() const {return newvalue;}
|
||||
inline double getOldValue() const {
|
||||
return oldvalue;
|
||||
}
|
||||
inline double getNewValue() const {
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
double oldvalue;
|
||||
double newvalue;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
FloatNode::FloatNode(DefinitionNode* parent, const std::string &name, double value):
|
||||
DefinitionNode(parent, name, "float"), value(value)
|
||||
{
|
||||
FloatNode::FloatNode(DefinitionNode *parent, const std::string &name, double value)
|
||||
: DefinitionNode(parent, name, "float"), value(value) {
|
||||
}
|
||||
|
||||
std::string FloatNode::toString(int indent) const
|
||||
{
|
||||
std::string FloatNode::toString(int indent) const {
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << DefinitionNode::toString(indent) << " " << value;
|
||||
|
@ -20,47 +18,36 @@ std::string FloatNode::toString(int indent) const
|
|||
return stream.str();
|
||||
}
|
||||
|
||||
void FloatNode::save(PackStream *stream) const
|
||||
{
|
||||
void FloatNode::save(PackStream *stream) const {
|
||||
stream->write(&value);
|
||||
}
|
||||
|
||||
void FloatNode::load(PackStream *stream)
|
||||
{
|
||||
void FloatNode::load(PackStream *stream) {
|
||||
stream->read(&value);
|
||||
}
|
||||
|
||||
void FloatNode::copy(DefinitionNode *destination) const
|
||||
{
|
||||
if (destination->getTypeName() == getTypeName())
|
||||
{
|
||||
void FloatNode::copy(DefinitionNode *destination) const {
|
||||
if (destination->getTypeName() == getTypeName()) {
|
||||
((FloatNode *)destination)->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void FloatNode::setValue(double new_value)
|
||||
{
|
||||
void FloatNode::setValue(double new_value) {
|
||||
addDiff(produceDiff(new_value));
|
||||
}
|
||||
|
||||
const FloatDiff *FloatNode::produceDiff(double new_value) const
|
||||
{
|
||||
const FloatDiff *FloatNode::produceDiff(double new_value) const {
|
||||
return new FloatDiff(this, value, new_value);
|
||||
}
|
||||
|
||||
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const
|
||||
{
|
||||
void FloatNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
||||
diffs->push_back(produceDiff(value));
|
||||
}
|
||||
|
||||
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
||||
{
|
||||
if (!DefinitionNode::applyDiff(diff, backward))
|
||||
{
|
||||
bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||
if (!DefinitionNode::applyDiff(diff, backward)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -70,19 +57,15 @@ bool FloatNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
|||
double previous = backward ? float_diff->getNewValue() : float_diff->getOldValue();
|
||||
double next = backward ? float_diff->getOldValue() : float_diff->getNewValue();
|
||||
|
||||
if (value == previous)
|
||||
{
|
||||
if (value == previous) {
|
||||
value = next;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't apply float diff " << previous << " => " << next << " to " << getName() << std::endl;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
void FloatNode::addValue(double added)
|
||||
{
|
||||
void FloatNode::addValue(double added) {
|
||||
setValue(value + added);
|
||||
}
|
||||
|
|
|
@ -11,17 +11,18 @@ namespace definition {
|
|||
/**
|
||||
* Node with a single floating point numeric value, for the definition tree.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT FloatNode: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
FloatNode(DefinitionNode* parent, const std::string &name, double value = 0.0);
|
||||
class DEFINITIONSHARED_EXPORT FloatNode : public DefinitionNode {
|
||||
public:
|
||||
FloatNode(DefinitionNode *parent, const std::string &name, double value = 0.0);
|
||||
|
||||
inline double getValue() const {return value;}
|
||||
inline double getValue() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual std::string toString(int indent) const override;
|
||||
virtual void save(PackStream* stream) const override;
|
||||
virtual void load(PackStream* stream) override;
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
|
||||
/**
|
||||
* Change the float value stored.
|
||||
|
@ -31,13 +32,13 @@ public:
|
|||
void setValue(double new_value);
|
||||
const FloatDiff *produceDiff(double new_value) const;
|
||||
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||
|
||||
void addValue(double added);
|
||||
private:
|
||||
|
||||
private:
|
||||
double value;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,11 +2,8 @@
|
|||
|
||||
#include "FloatNode.h"
|
||||
|
||||
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent):
|
||||
DefinitionNode(parent, "godrays", "godrays")
|
||||
{
|
||||
GodRaysDefinition::GodRaysDefinition(DefinitionNode *parent) : DefinitionNode(parent, "godrays", "godrays") {
|
||||
penetration = new FloatNode(this, "penetration", 0.01);
|
||||
resistance = new FloatNode(this, "resistance", 0.3);
|
||||
boost = new FloatNode(this, "boost", 8.0);
|
||||
}
|
||||
|
||||
|
|
|
@ -8,21 +8,25 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT GodRaysDefinition: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT GodRaysDefinition : public DefinitionNode {
|
||||
public:
|
||||
GodRaysDefinition(DefinitionNode *parent);
|
||||
|
||||
inline FloatNode *propPenetration() const {return penetration;}
|
||||
inline FloatNode *propResistance() const {return resistance;}
|
||||
inline FloatNode *propBoost() const {return boost;}
|
||||
inline FloatNode *propPenetration() const {
|
||||
return penetration;
|
||||
}
|
||||
inline FloatNode *propResistance() const {
|
||||
return resistance;
|
||||
}
|
||||
inline FloatNode *propBoost() const {
|
||||
return boost;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
FloatNode *penetration;
|
||||
FloatNode *resistance;
|
||||
FloatNode *boost;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,5 @@
|
|||
#include "IntDiff.h"
|
||||
|
||||
IntDiff::IntDiff(const DefinitionNode *node, int oldvalue, int newvalue):
|
||||
DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue)
|
||||
{
|
||||
IntDiff::IntDiff(const DefinitionNode *node, int oldvalue, int newvalue)
|
||||
: DefinitionDiff(node), oldvalue(oldvalue), newvalue(newvalue) {
|
||||
}
|
||||
|
||||
|
|
|
@ -11,19 +11,21 @@ namespace definition {
|
|||
/**
|
||||
* Diff for an IntNode.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT IntDiff: public DefinitionDiff
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT IntDiff : public DefinitionDiff {
|
||||
public:
|
||||
IntDiff(const DefinitionNode *node, int oldvalue, int newvalue);
|
||||
|
||||
inline int getOldValue() const {return oldvalue;}
|
||||
inline int getNewValue() const {return newvalue;}
|
||||
inline int getOldValue() const {
|
||||
return oldvalue;
|
||||
}
|
||||
inline int getNewValue() const {
|
||||
return newvalue;
|
||||
}
|
||||
|
||||
private:
|
||||
private:
|
||||
int oldvalue;
|
||||
int newvalue;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,13 +6,11 @@
|
|||
#include <sstream>
|
||||
#include <cassert>
|
||||
|
||||
IntNode::IntNode(DefinitionNode* parent, const std::string &name, int value):
|
||||
DefinitionNode(parent, name, "int"), value(value)
|
||||
{
|
||||
IntNode::IntNode(DefinitionNode *parent, const std::string &name, int value)
|
||||
: DefinitionNode(parent, name, "int"), value(value) {
|
||||
}
|
||||
|
||||
std::string IntNode::toString(int indent) const
|
||||
{
|
||||
std::string IntNode::toString(int indent) const {
|
||||
std::ostringstream stream;
|
||||
|
||||
stream << DefinitionNode::toString(indent) << " " << value;
|
||||
|
@ -20,47 +18,36 @@ std::string IntNode::toString(int indent) const
|
|||
return stream.str();
|
||||
}
|
||||
|
||||
void IntNode::save(PackStream *stream) const
|
||||
{
|
||||
void IntNode::save(PackStream *stream) const {
|
||||
stream->write(&value);
|
||||
}
|
||||
|
||||
void IntNode::load(PackStream *stream)
|
||||
{
|
||||
void IntNode::load(PackStream *stream) {
|
||||
stream->read(&value);
|
||||
}
|
||||
|
||||
void IntNode::copy(DefinitionNode *destination) const
|
||||
{
|
||||
if (destination->getTypeName() == getTypeName())
|
||||
{
|
||||
void IntNode::copy(DefinitionNode *destination) const {
|
||||
if (destination->getTypeName() == getTypeName()) {
|
||||
((IntNode *)destination)->value = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void IntNode::setValue(int new_value)
|
||||
{
|
||||
void IntNode::setValue(int new_value) {
|
||||
addDiff(produceDiff(new_value));
|
||||
}
|
||||
|
||||
const IntDiff *IntNode::produceDiff(int new_value) const
|
||||
{
|
||||
const IntDiff *IntNode::produceDiff(int new_value) const {
|
||||
return new IntDiff(this, value, new_value);
|
||||
}
|
||||
|
||||
void IntNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const
|
||||
{
|
||||
void IntNode::generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const {
|
||||
diffs->push_back(produceDiff(value));
|
||||
}
|
||||
|
||||
bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
||||
{
|
||||
if (!DefinitionNode::applyDiff(diff, backward))
|
||||
{
|
||||
bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward) {
|
||||
if (!DefinitionNode::applyDiff(diff, backward)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -70,13 +57,10 @@ bool IntNode::applyDiff(const DefinitionDiff *diff, bool backward)
|
|||
double previous = backward ? int_diff->getNewValue() : int_diff->getOldValue();
|
||||
double next = backward ? int_diff->getOldValue() : int_diff->getNewValue();
|
||||
|
||||
if (value == previous)
|
||||
{
|
||||
if (value == previous) {
|
||||
value = next;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't apply int diff " << previous << " => " << next << " to " << getName() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -11,17 +11,18 @@ namespace definition {
|
|||
/**
|
||||
* Node with a single integer value, for the definition tree.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT IntNode: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
IntNode(DefinitionNode* parent, const std::string &name, int value = 0);
|
||||
class DEFINITIONSHARED_EXPORT IntNode : public DefinitionNode {
|
||||
public:
|
||||
IntNode(DefinitionNode *parent, const std::string &name, int value = 0);
|
||||
|
||||
inline int getValue() const {return value;}
|
||||
inline int getValue() const {
|
||||
return value;
|
||||
}
|
||||
|
||||
virtual std::string toString(int indent) const override;
|
||||
virtual void save(PackStream* stream) const override;
|
||||
virtual void load(PackStream* stream) override;
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
|
||||
/**
|
||||
* Change the int value stored.
|
||||
|
@ -31,12 +32,11 @@ public:
|
|||
void setValue(int new_value);
|
||||
const IntDiff *produceDiff(int new_value) const;
|
||||
void generateInitDiffs(std::vector<const DefinitionDiff *> *diffs) const;
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward=false) override;
|
||||
virtual bool applyDiff(const DefinitionDiff *diff, bool backward = false) override;
|
||||
|
||||
private:
|
||||
private:
|
||||
int value;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,57 +3,48 @@
|
|||
#include "PackStream.h"
|
||||
#include "Logs.h"
|
||||
|
||||
Layers::Layers(DefinitionNode* parent, const std::string &name, LayerConstructor layer_constructor):
|
||||
DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor)
|
||||
{
|
||||
Layers::Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor)
|
||||
: DefinitionNode(parent, name, "layers" + name), layer_constructor(layer_constructor) {
|
||||
max_layer_count = 100;
|
||||
null_layer = layer_constructor(this);
|
||||
}
|
||||
|
||||
Layers::~Layers()
|
||||
{
|
||||
Layers::~Layers() {
|
||||
clear();
|
||||
delete null_layer;
|
||||
}
|
||||
|
||||
void Layers::save(PackStream *stream) const
|
||||
{
|
||||
void Layers::save(PackStream *stream) const {
|
||||
int layer_count = (int)layers.size();
|
||||
stream->write(&layer_count);
|
||||
|
||||
for (int i = 0; i < layer_count; i++)
|
||||
{
|
||||
for (int i = 0; i < layer_count; i++) {
|
||||
stream->write(layers[i]->getName());
|
||||
layers[i]->save(stream);
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::load(PackStream *stream)
|
||||
{
|
||||
void Layers::load(PackStream *stream) {
|
||||
int layer_count;
|
||||
stream->read(&layer_count);
|
||||
|
||||
if (layer_count > max_layer_count)
|
||||
{
|
||||
if (layer_count > max_layer_count) {
|
||||
layer_count = max_layer_count;
|
||||
}
|
||||
clear();
|
||||
for (int i = 0; i < layer_count; i++)
|
||||
{
|
||||
for (int i = 0; i < layer_count; i++) {
|
||||
int position = addLayer();
|
||||
if (position >= 0)
|
||||
{
|
||||
if (position >= 0) {
|
||||
layers[position]->setName(stream->readString());
|
||||
layers[position]->load(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::copy(DefinitionNode* destination_) const
|
||||
{
|
||||
void Layers::copy(DefinitionNode *destination_) const {
|
||||
DefinitionNode::copy(destination_);
|
||||
|
||||
Layers* destination = (Layers*)destination_;
|
||||
Layers *destination = (Layers *)destination_;
|
||||
|
||||
destination->clear();
|
||||
|
||||
|
@ -61,142 +52,113 @@ void Layers::copy(DefinitionNode* destination_) const
|
|||
|
||||
null_layer->copy(destination->null_layer);
|
||||
|
||||
for (auto layer: layers)
|
||||
{
|
||||
for (auto layer : layers) {
|
||||
int position = destination->addLayer();
|
||||
DefinitionNode* new_layer = destination->getLayer(position);
|
||||
DefinitionNode *new_layer = destination->getLayer(position);
|
||||
layer->copy(new_layer);
|
||||
}
|
||||
}
|
||||
|
||||
Layers* Layers::newCopy() const
|
||||
{
|
||||
Layers* result = new Layers(NULL, getName(), layer_constructor);
|
||||
Layers *Layers::newCopy() const {
|
||||
Layers *result = new Layers(NULL, getName(), layer_constructor);
|
||||
copy(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
void Layers::setMaxLayerCount(int max_layer_count)
|
||||
{
|
||||
void Layers::setMaxLayerCount(int max_layer_count) {
|
||||
this->max_layer_count = max_layer_count;
|
||||
// TODO Delete overlimit layers ?
|
||||
}
|
||||
|
||||
int Layers::count() const
|
||||
{
|
||||
int Layers::count() const {
|
||||
return layers.size();
|
||||
}
|
||||
|
||||
DefinitionNode* Layers::getLayer(int position) const
|
||||
{
|
||||
if (position >= 0 and position < (int)layers.size())
|
||||
{
|
||||
DefinitionNode *Layers::getLayer(int position) const {
|
||||
if (position >= 0 and position < (int)layers.size()) {
|
||||
return layers[position];
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size() << std::endl;
|
||||
} else {
|
||||
Logs::warning() << "Asked for a undefined layer " << position << " on a total of " << (int)layers.size()
|
||||
<< std::endl;
|
||||
return null_layer;
|
||||
}
|
||||
}
|
||||
|
||||
int Layers::findLayer(DefinitionNode* layer) const
|
||||
{
|
||||
int Layers::findLayer(DefinitionNode *layer) const {
|
||||
int i = 0;
|
||||
for (auto it:layers)
|
||||
{
|
||||
if (it == layer)
|
||||
{
|
||||
for (auto it : layers) {
|
||||
if (it == layer) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
Logs::warning() << "Layer " << layer << " (" << layer->getName() << " not found, on a total of " << (int)layers.size() << std::endl;
|
||||
Logs::warning() << "Layer " << layer << " (" << layer->getName() << " not found, on a total of "
|
||||
<< (int)layers.size() << std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int Layers::addLayer(DefinitionNode* layer)
|
||||
{
|
||||
if ((int)layers.size() < max_layer_count)
|
||||
{
|
||||
int Layers::addLayer(DefinitionNode *layer) {
|
||||
if ((int)layers.size() < max_layer_count) {
|
||||
layers.push_back(layer);
|
||||
addChild(layer);
|
||||
return layers.size() - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::warning() << "Add layer ignored because limit of " << max_layer_count << " reached" << std::endl;
|
||||
delete layer;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
int Layers::addLayer()
|
||||
{
|
||||
int Layers::addLayer() {
|
||||
return addLayer(layer_constructor(this));
|
||||
}
|
||||
|
||||
void Layers::removeLayer(int position)
|
||||
{
|
||||
if (position >= 0 and position < (int)layers.size())
|
||||
{
|
||||
DefinitionNode* removed = layers[position];
|
||||
void Layers::removeLayer(int position) {
|
||||
if (position >= 0 and position < (int)layers.size()) {
|
||||
DefinitionNode *removed = layers[position];
|
||||
removeChild(removed);
|
||||
layers.erase(layers.begin() + position);
|
||||
delete removed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Logs::warning() << "Removing unknown layer " << position << " on " << (int)layers.size() << " from '" << getName() << "'" << std::endl;
|
||||
} else {
|
||||
Logs::warning() << "Removing unknown layer " << position << " on " << (int)layers.size() << " from '"
|
||||
<< getName() << "'" << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::removeLayer(DefinitionNode* layer)
|
||||
{
|
||||
void Layers::removeLayer(DefinitionNode *layer) {
|
||||
removeLayer(findLayer(layer));
|
||||
}
|
||||
|
||||
void Layers::moveLayer(int old_position, int new_position)
|
||||
{
|
||||
if (old_position >= 0 and old_position < (int)layers.size() and new_position >= 0 and new_position < (int)layers.size())
|
||||
{
|
||||
DefinitionNode* layer = layers[old_position];
|
||||
void Layers::moveLayer(int old_position, int new_position) {
|
||||
if (old_position >= 0 and old_position < (int)layers.size() and new_position >= 0 and
|
||||
new_position < (int)layers.size()) {
|
||||
DefinitionNode *layer = layers[old_position];
|
||||
layers.erase(layers.begin() + old_position);
|
||||
layers.insert(layers.begin() + new_position, layer);
|
||||
}
|
||||
}
|
||||
|
||||
void Layers::moveLayer(DefinitionNode* layer, int new_position)
|
||||
{
|
||||
void Layers::moveLayer(DefinitionNode *layer, int new_position) {
|
||||
moveLayer(findLayer(layer), new_position);
|
||||
}
|
||||
|
||||
void Layers::clear()
|
||||
{
|
||||
while (layers.size() > 0)
|
||||
{
|
||||
void Layers::clear() {
|
||||
while (layers.size() > 0) {
|
||||
removeLayer(0);
|
||||
}
|
||||
}
|
||||
|
||||
DefinitionNode *Layers::findChildByName(const std::string name)
|
||||
{
|
||||
DefinitionNode *Layers::findChildByName(const std::string name) {
|
||||
DefinitionNode *result = DefinitionNode::findChildByName(name);
|
||||
if (result)
|
||||
{
|
||||
if (result) {
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
int position = addLayer();
|
||||
if (position >= 0)
|
||||
{
|
||||
if (position >= 0) {
|
||||
result = getLayer(position);
|
||||
result->setName(name);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,27 +8,26 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
typedef DefinitionNode* (*LayerConstructor)(Layers* parent);
|
||||
typedef DefinitionNode *(*LayerConstructor)(Layers *parent);
|
||||
|
||||
/**
|
||||
* @brief Layers of definitions, ideally all of the same type.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT Layers:public DefinitionNode
|
||||
{
|
||||
public:
|
||||
Layers(DefinitionNode* parent, const std::string &name, LayerConstructor layer_constructor);
|
||||
class DEFINITIONSHARED_EXPORT Layers : public DefinitionNode {
|
||||
public:
|
||||
Layers(DefinitionNode *parent, const std::string &name, LayerConstructor layer_constructor);
|
||||
virtual ~Layers();
|
||||
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
Layers* newCopy() const;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
Layers *newCopy() const;
|
||||
|
||||
void setMaxLayerCount(int max_layer_count);
|
||||
|
||||
int count() const;
|
||||
DefinitionNode* getLayer(int position) const;
|
||||
int findLayer(DefinitionNode* layer) const;
|
||||
DefinitionNode *getLayer(int position) const;
|
||||
int findLayer(DefinitionNode *layer) const;
|
||||
|
||||
/**
|
||||
* @brief Add a new layer
|
||||
|
@ -40,22 +39,20 @@ public:
|
|||
int addLayer(DefinitionNode *layer);
|
||||
int addLayer();
|
||||
void removeLayer(int position);
|
||||
void removeLayer(DefinitionNode* layer);
|
||||
void removeLayer(DefinitionNode *layer);
|
||||
void moveLayer(int old_position, int new_position);
|
||||
void moveLayer(DefinitionNode* layer, int new_position);
|
||||
void moveLayer(DefinitionNode *layer, int new_position);
|
||||
void clear();
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual DefinitionNode *findChildByName(const std::string name) override;
|
||||
|
||||
public:
|
||||
public:
|
||||
LayerConstructor layer_constructor;
|
||||
int max_layer_count;
|
||||
std::vector<DefinitionNode*> layers;
|
||||
DefinitionNode* null_layer;
|
||||
|
||||
std::vector<DefinitionNode *> layers;
|
||||
DefinitionNode *null_layer;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,19 +3,15 @@
|
|||
#include "NoiseGenerator.h"
|
||||
#include "Logs.h"
|
||||
|
||||
NoiseNode::NoiseNode(DefinitionNode *parent):
|
||||
DefinitionNode(parent, "noise")
|
||||
{
|
||||
NoiseNode::NoiseNode(DefinitionNode *parent) : DefinitionNode(parent, "noise") {
|
||||
noise = new NoiseGenerator();
|
||||
}
|
||||
|
||||
NoiseNode::~NoiseNode()
|
||||
{
|
||||
NoiseNode::~NoiseNode() {
|
||||
delete noise;
|
||||
}
|
||||
|
||||
void NoiseNode::setLevels(int levels, double min_value, double max_value)
|
||||
{
|
||||
void NoiseNode::setLevels(int levels, double min_value, double max_value) {
|
||||
noise->clearLevels();
|
||||
noise->addLevelsSimple(levels, 1.0, -1.0, 1.0, 0.5);
|
||||
noise->normalizeAmplitude(min_value, max_value, false);
|
||||
|
@ -23,29 +19,22 @@ void NoiseNode::setLevels(int levels, double min_value, double max_value)
|
|||
noise->validate();
|
||||
}
|
||||
|
||||
void NoiseNode::save(PackStream *stream) const
|
||||
{
|
||||
void NoiseNode::save(PackStream *stream) const {
|
||||
noise->save(stream);
|
||||
}
|
||||
|
||||
void NoiseNode::load(PackStream *stream)
|
||||
{
|
||||
void NoiseNode::load(PackStream *stream) {
|
||||
noise->load(stream);
|
||||
}
|
||||
|
||||
void NoiseNode::copy(DefinitionNode *destination) const
|
||||
{
|
||||
if (destination->getTypeName() == getTypeName())
|
||||
{
|
||||
void NoiseNode::copy(DefinitionNode *destination) const {
|
||||
if (destination->getTypeName() == getTypeName()) {
|
||||
noise->copy(((NoiseNode *)destination)->noise);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
Logs::error() << "Can't copy from " << getTypeName() << " to " << destination->getTypeName() << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
void NoiseNode::validate()
|
||||
{
|
||||
void NoiseNode::validate() {
|
||||
noise->validate();
|
||||
}
|
||||
|
|
|
@ -11,30 +11,29 @@ namespace definition {
|
|||
/**
|
||||
* Definition node with noise parameters.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT NoiseNode: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT NoiseNode : public DefinitionNode {
|
||||
public:
|
||||
NoiseNode(DefinitionNode *parent);
|
||||
virtual ~NoiseNode();
|
||||
|
||||
inline const NoiseGenerator *getGenerator() {return noise;}
|
||||
inline const NoiseGenerator *getGenerator() {
|
||||
return noise;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the number of levels to use in the noise generator.
|
||||
*/
|
||||
void setLevels(int levels, double min_value=-1.0, double max_value=1.0);
|
||||
void setLevels(int levels, double min_value = -1.0, double max_value = 1.0);
|
||||
|
||||
protected:
|
||||
protected:
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
private:
|
||||
private:
|
||||
NoiseGenerator *noise;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -6,40 +6,33 @@
|
|||
#include "PaintedGridData.h"
|
||||
#include "PaintedGridBrush.h"
|
||||
|
||||
PaintedGrid::PaintedGrid(DefinitionNode *parent):
|
||||
DefinitionNode(parent, "grid", "grid")
|
||||
{
|
||||
PaintedGrid::PaintedGrid(DefinitionNode *parent) : DefinitionNode(parent, "grid", "grid") {
|
||||
merged_data = new PaintedGridData;
|
||||
brush_data = new PaintedGridData;
|
||||
}
|
||||
|
||||
PaintedGrid::~PaintedGrid()
|
||||
{
|
||||
PaintedGrid::~PaintedGrid() {
|
||||
delete merged_data;
|
||||
delete brush_data;
|
||||
}
|
||||
|
||||
void PaintedGrid::copy(DefinitionNode *_destination) const
|
||||
{
|
||||
PaintedGrid* destination = (PaintedGrid *)_destination;
|
||||
void PaintedGrid::copy(DefinitionNode *_destination) const {
|
||||
PaintedGrid *destination = (PaintedGrid *)_destination;
|
||||
|
||||
merged_data->copy(destination->merged_data);
|
||||
destination->brush_data->clear();
|
||||
}
|
||||
|
||||
void PaintedGrid::save(PackStream *stream) const
|
||||
{
|
||||
void PaintedGrid::save(PackStream *stream) const {
|
||||
merged_data->save(stream);
|
||||
}
|
||||
|
||||
void PaintedGrid::load(PackStream *stream)
|
||||
{
|
||||
void PaintedGrid::load(PackStream *stream) {
|
||||
merged_data->load(stream);
|
||||
brush_data->clear();
|
||||
}
|
||||
|
||||
bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
|
||||
{
|
||||
bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const {
|
||||
int ix, iy;
|
||||
int xlow;
|
||||
int ylow;
|
||||
|
@ -48,27 +41,20 @@ bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
|
|||
ylow = floor(y);
|
||||
|
||||
int hit = 0;
|
||||
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++)
|
||||
{
|
||||
for (iy = ylow - 1; iy <= ylow + 2 && !hit; iy++)
|
||||
{
|
||||
if (getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false))
|
||||
{
|
||||
for (ix = xlow - 1; ix <= xlow + 2 && !hit; ix++) {
|
||||
for (iy = ylow - 1; iy <= ylow + 2 && !hit; iy++) {
|
||||
if (getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false)) {
|
||||
hit = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hit && result)
|
||||
{
|
||||
if (hit && result) {
|
||||
double stencil[16];
|
||||
double value;
|
||||
for (ix = xlow - 1; ix <= xlow + 2; ix++)
|
||||
{
|
||||
for (iy = ylow - 1; iy <= ylow + 2; iy++)
|
||||
{
|
||||
if (!getGridValue(ix, iy, &value))
|
||||
{
|
||||
for (ix = xlow - 1; ix <= xlow + 2; ix++) {
|
||||
for (iy = ylow - 1; iy <= ylow + 2; iy++) {
|
||||
if (!getGridValue(ix, iy, &value)) {
|
||||
value = getInitialValue(ix, iy);
|
||||
}
|
||||
stencil[(iy - (ylow - 1)) * 4 + ix - (xlow - 1)] = value;
|
||||
|
@ -81,67 +67,51 @@ bool PaintedGrid::getInterpolatedValue(double x, double y, double *result) const
|
|||
return hit;
|
||||
}
|
||||
|
||||
bool PaintedGrid::getGridValue(int x, int y, double *result) const
|
||||
{
|
||||
double* dpointer;
|
||||
bool PaintedGrid::getGridValue(int x, int y, double *result) const {
|
||||
double *dpointer;
|
||||
dpointer = getDataPointer(brush_data, x, y, NULL, false);
|
||||
if (dpointer)
|
||||
{
|
||||
if (dpointer) {
|
||||
*result = *dpointer;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
dpointer = getDataPointer(merged_data, x, y, NULL, false);
|
||||
if (dpointer)
|
||||
{
|
||||
if (dpointer) {
|
||||
*result = *dpointer;
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
double PaintedGrid::getFinalValue(double x, double y) const
|
||||
{
|
||||
double PaintedGrid::getFinalValue(double x, double y) const {
|
||||
double result;
|
||||
|
||||
if (getInterpolatedValue(x, y, &result))
|
||||
{
|
||||
if (getInterpolatedValue(x, y, &result)) {
|
||||
return result;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return getInitialValue(x, y);
|
||||
}
|
||||
}
|
||||
|
||||
bool PaintedGrid::hasPainting() const
|
||||
{
|
||||
bool PaintedGrid::hasPainting() const {
|
||||
return merged_data->hasData() || brush_data->hasData();
|
||||
}
|
||||
|
||||
bool PaintedGrid::isPainted(int x, int y) const
|
||||
{
|
||||
bool PaintedGrid::isPainted(int x, int y) const {
|
||||
return getDataPointer(brush_data, x, y, NULL, false) || getDataPointer(merged_data, x, y, NULL, false);
|
||||
}
|
||||
|
||||
unsigned long PaintedGrid::getMemoryStats() const
|
||||
{
|
||||
unsigned long PaintedGrid::getMemoryStats() const {
|
||||
return merged_data->memsize + brush_data->memsize;
|
||||
}
|
||||
|
||||
void PaintedGrid::clearPainting()
|
||||
{
|
||||
void PaintedGrid::clearPainting() {
|
||||
merged_data->clear();
|
||||
brush_data->clear();
|
||||
}
|
||||
|
||||
void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit)
|
||||
{
|
||||
void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit) {
|
||||
int xstart, xend, ystart, yend;
|
||||
|
||||
brush.getArea(x, y, &xstart, &ystart, &xend, ¥d);
|
||||
|
@ -149,41 +119,34 @@ void PaintedGrid::applyBrush(const PaintedGridBrush &brush, double x, double y,
|
|||
int ix, iy;
|
||||
double dx, dy, influence;
|
||||
|
||||
for (ix = xstart; ix <= xend; ix++)
|
||||
{
|
||||
for (ix = xstart; ix <= xend; ix++) {
|
||||
dx = (double)ix;
|
||||
for (iy = ystart; iy <= yend; iy++)
|
||||
{
|
||||
for (iy = ystart; iy <= yend; iy++) {
|
||||
dy = (double)iy;
|
||||
|
||||
influence = brush.getInfluence(x - dx, y - dy);
|
||||
|
||||
if (influence > 0.0)
|
||||
{
|
||||
double* dpointer = getDataPointer(brush_data, ix, iy, merged_data, true);
|
||||
if (influence > 0.0) {
|
||||
double *dpointer = getDataPointer(brush_data, ix, iy, merged_data, true);
|
||||
*dpointer = brush.getValue(this, dx, dy, *dpointer, influence, force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (commit)
|
||||
{
|
||||
if (commit) {
|
||||
endBrushStroke();
|
||||
}
|
||||
}
|
||||
|
||||
void PaintedGrid::endBrushStroke()
|
||||
{
|
||||
void PaintedGrid::endBrushStroke() {
|
||||
int i, j, k;
|
||||
PaintedGridData* data = brush_data;
|
||||
PaintedGridData *data = brush_data;
|
||||
|
||||
for (i = 0; i < data->rows_count; i++)
|
||||
{
|
||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++)
|
||||
{
|
||||
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++)
|
||||
{
|
||||
double* dpointer = getDataPointer(merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].y, NULL, true);
|
||||
for (i = 0; i < data->rows_count; i++) {
|
||||
for (j = 0; j < data->rows[i].pixel_groups_count; j++) {
|
||||
for (k = 0; k < data->rows[i].pixel_groups[j].xend - data->rows[i].pixel_groups[j].xstart + 1; k++) {
|
||||
double *dpointer =
|
||||
getDataPointer(merged_data, data->rows[i].pixel_groups[j].xstart + k, data->rows[i].y, NULL, true);
|
||||
*dpointer = data->rows[i].pixel_groups[j].height[k];
|
||||
}
|
||||
}
|
||||
|
@ -192,63 +155,51 @@ void PaintedGrid::endBrushStroke()
|
|||
brush_data->clear();
|
||||
}
|
||||
|
||||
double PaintedGrid::getInitialValue(double, double) const
|
||||
{
|
||||
double PaintedGrid::getInitialValue(double, double) const {
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const
|
||||
{
|
||||
double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const {
|
||||
int i;
|
||||
|
||||
/* Find row */
|
||||
/* TODO Dichotomic search */
|
||||
PaintedGridData::HeightMapRow* row;
|
||||
PaintedGridData::HeightMapRow *row;
|
||||
i = 0;
|
||||
while (i < data->rows_count && data->rows[i].y < y)
|
||||
{
|
||||
while (i < data->rows_count && data->rows[i].y < y) {
|
||||
i++;
|
||||
}
|
||||
if (i < data->rows_count && data->rows[i].y == y)
|
||||
{
|
||||
if (i < data->rows_count && data->rows[i].y == y) {
|
||||
row = data->rows + i;
|
||||
}
|
||||
else if (grow)
|
||||
{
|
||||
row = (PaintedGridData::HeightMapRow*)Memory::naiveArrayInsert((void**)&data->rows, sizeof(PaintedGridData::HeightMapRow), data->rows_count, i);
|
||||
} else if (grow) {
|
||||
row = (PaintedGridData::HeightMapRow *)Memory::naiveArrayInsert(
|
||||
(void **)&data->rows, sizeof(PaintedGridData::HeightMapRow), data->rows_count, i);
|
||||
|
||||
row->y = y;
|
||||
row->pixel_groups_count = 0;
|
||||
row->pixel_groups = (PaintedGridData::HeightMapPixelGroup*)malloc(1);
|
||||
row->pixel_groups = (PaintedGridData::HeightMapPixelGroup *)malloc(1);
|
||||
|
||||
data->rows_count++;
|
||||
data->memsize += sizeof(PaintedGridData::HeightMapRow);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
/* Check rows */
|
||||
for (i = 1; i < data->rows_count; i++)
|
||||
{
|
||||
for (i = 1; i < data->rows_count; i++) {
|
||||
assert(data->rows[i].y > data->rows[i - 1].y);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Find pixel group */
|
||||
PaintedGridData::HeightMapPixelGroup* pixel_group = NULL;
|
||||
for (i = 0; i < row->pixel_groups_count; i++)
|
||||
{
|
||||
if (x < row->pixel_groups[i].xstart - 1)
|
||||
{
|
||||
PaintedGridData::HeightMapPixelGroup *pixel_group = NULL;
|
||||
for (i = 0; i < row->pixel_groups_count; i++) {
|
||||
if (x < row->pixel_groups[i].xstart - 1) {
|
||||
break;
|
||||
}
|
||||
else if (x <= row->pixel_groups[i].xend + 1)
|
||||
{
|
||||
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 && x == row->pixel_groups[i + 1].xstart)
|
||||
{
|
||||
} else if (x <= row->pixel_groups[i].xend + 1) {
|
||||
if (x == row->pixel_groups[i].xend + 1 && i < row->pixel_groups_count - 1 &&
|
||||
x == row->pixel_groups[i + 1].xstart) {
|
||||
/* Choose next group if it already includes the pixel */
|
||||
i++;
|
||||
}
|
||||
|
@ -258,53 +209,47 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
|
|||
}
|
||||
|
||||
/* Alter pixel group */
|
||||
double* pixel;
|
||||
double *pixel;
|
||||
int added = 1;
|
||||
if (!pixel_group)
|
||||
{
|
||||
if (!grow)
|
||||
{
|
||||
if (!pixel_group) {
|
||||
if (!grow) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Create the pixel group with one pixel */
|
||||
pixel_group = (PaintedGridData::HeightMapPixelGroup*)Memory::naiveArrayInsert((void**)&row->pixel_groups, sizeof(PaintedGridData::HeightMapPixelGroup), row->pixel_groups_count, i);
|
||||
pixel_group = (PaintedGridData::HeightMapPixelGroup *)Memory::naiveArrayInsert(
|
||||
(void **)&row->pixel_groups, sizeof(PaintedGridData::HeightMapPixelGroup), row->pixel_groups_count, i);
|
||||
|
||||
pixel_group->xstart = x;
|
||||
pixel_group->xend = x;
|
||||
pixel_group->height = (double*)malloc(sizeof(double));
|
||||
pixel_group->height = (double *)malloc(sizeof(double));
|
||||
|
||||
pixel = pixel_group->height;
|
||||
|
||||
row->pixel_groups_count++;
|
||||
data->memsize += sizeof(PaintedGridData::HeightMapPixelGroup) + sizeof(double);
|
||||
}
|
||||
else if (x == pixel_group->xstart - 1)
|
||||
{
|
||||
if (!grow)
|
||||
{
|
||||
} else if (x == pixel_group->xstart - 1) {
|
||||
if (!grow) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Extend the rowgroup at start */
|
||||
pixel_group->xstart--;
|
||||
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, 0);
|
||||
pixel = (double *)Memory::naiveArrayInsert((void **)&pixel_group->height, sizeof(double),
|
||||
pixel_group->xend - pixel_group->xstart, 0);
|
||||
data->memsize += sizeof(double);
|
||||
}
|
||||
else if (x == pixel_group->xend + 1)
|
||||
{
|
||||
if (!grow)
|
||||
{
|
||||
} else if (x == pixel_group->xend + 1) {
|
||||
if (!grow) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Extend the rowgroup at end */
|
||||
pixel_group->xend++;
|
||||
pixel = (double*)Memory::naiveArrayInsert((void**)&pixel_group->height, sizeof(double), pixel_group->xend - pixel_group->xstart, pixel_group->xend - pixel_group->xstart);
|
||||
pixel = (double *)Memory::naiveArrayInsert((void **)&pixel_group->height, sizeof(double),
|
||||
pixel_group->xend - pixel_group->xstart,
|
||||
pixel_group->xend - pixel_group->xstart);
|
||||
data->memsize += sizeof(double);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
assert(x >= pixel_group->xstart);
|
||||
assert(x <= pixel_group->xend);
|
||||
pixel = pixel_group->height + x - pixel_group->xstart;
|
||||
|
@ -313,14 +258,11 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
|
|||
|
||||
#ifndef NDEBUG
|
||||
/* Check pixel groups */
|
||||
for (i = 0; i < row->pixel_groups_count; i++)
|
||||
{
|
||||
if (i > 0)
|
||||
{
|
||||
for (i = 0; i < row->pixel_groups_count; i++) {
|
||||
if (i > 0) {
|
||||
assert(row->pixel_groups[i].xstart > row->pixel_groups[i - 1].xend);
|
||||
}
|
||||
if (i < row->pixel_groups_count - 1)
|
||||
{
|
||||
if (i < row->pixel_groups_count - 1) {
|
||||
assert(row->pixel_groups[i].xend < row->pixel_groups[i + 1].xstart);
|
||||
}
|
||||
assert(row->pixel_groups[i].xend >= row->pixel_groups[i].xstart);
|
||||
|
@ -328,22 +270,15 @@ double *PaintedGrid::getDataPointer(PaintedGridData *data, int x, int y, Painted
|
|||
#endif
|
||||
|
||||
/* Reset pixel if it had been added */
|
||||
if (added)
|
||||
{
|
||||
if (fallback)
|
||||
{
|
||||
double* dpointer = getDataPointer(fallback, x, y, NULL, false);
|
||||
if (dpointer)
|
||||
{
|
||||
if (added) {
|
||||
if (fallback) {
|
||||
double *dpointer = getDataPointer(fallback, x, y, NULL, false);
|
||||
if (dpointer) {
|
||||
*pixel = *dpointer;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*pixel = getInitialValue(x, y);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
*pixel = getInitialValue(x, y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,10 +15,9 @@ namespace definition {
|
|||
*
|
||||
* Grid cells are considered to be 1.0-sized.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGrid: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
PaintedGrid(DefinitionNode *parent=0);
|
||||
class DEFINITIONSHARED_EXPORT PaintedGrid : public DefinitionNode {
|
||||
public:
|
||||
PaintedGrid(DefinitionNode *parent = 0);
|
||||
virtual ~PaintedGrid();
|
||||
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
|
@ -67,7 +66,7 @@ public:
|
|||
/**
|
||||
* Apply a brush stroke at a grid location (locating the brush center).
|
||||
*/
|
||||
virtual void applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit=false);
|
||||
virtual void applyBrush(const PaintedGridBrush &brush, double x, double y, double force, bool commit = false);
|
||||
|
||||
/**
|
||||
* Commit previous brush strokes.
|
||||
|
@ -81,14 +80,13 @@ public:
|
|||
*/
|
||||
virtual double getInitialValue(double x, double y) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
double *getDataPointer(PaintedGridData *data, int x, int y, PaintedGridData *fallback, bool grow) const;
|
||||
|
||||
private:
|
||||
private:
|
||||
PaintedGridData *merged_data;
|
||||
PaintedGridData *brush_data;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
#include "NoiseGenerator.h"
|
||||
#include "PaintedGrid.h"
|
||||
|
||||
PaintedGridBrush::PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius):
|
||||
hard_radius(hard_radius), smoothed_size(smoothed_size), total_radius(total_radius)
|
||||
{
|
||||
PaintedGridBrush::PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius)
|
||||
: hard_radius(hard_radius), smoothed_size(smoothed_size), total_radius(total_radius) {
|
||||
}
|
||||
|
||||
void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int *xend, int *yend) const
|
||||
{
|
||||
void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int *xend, int *yend) const {
|
||||
double s = smoothed_size + hard_radius;
|
||||
|
||||
*xstart = (int)floor(x - s);
|
||||
|
@ -19,39 +17,31 @@ void PaintedGridBrush::getArea(double x, double y, int *xstart, int *ystart, int
|
|||
*yend = (int)ceil(y + s);
|
||||
}
|
||||
|
||||
double PaintedGridBrush::getInfluence(double dx, double dy) const
|
||||
{
|
||||
double PaintedGridBrush::getInfluence(double dx, double dy) const {
|
||||
double distance = sqrt(dx * dx + dy * dy);
|
||||
|
||||
if (distance > hard_radius)
|
||||
{
|
||||
if (distance <= hard_radius + smoothed_size)
|
||||
{
|
||||
if (distance > hard_radius) {
|
||||
if (distance <= hard_radius + smoothed_size) {
|
||||
return 1.0 - (distance - hard_radius) / smoothed_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
double PaintedGridBrush::getValue(const PaintedGrid *, double, double, double basevalue, double, double) const
|
||||
{
|
||||
double PaintedGridBrush::getValue(const PaintedGrid *, double, double, double basevalue, double, double) const {
|
||||
return basevalue;
|
||||
}
|
||||
|
||||
double PaintedGridBrushRaiseLower::getValue(const PaintedGrid *, double, double, double basevalue, double influence, double force) const
|
||||
{
|
||||
double PaintedGridBrushRaiseLower::getValue(const PaintedGrid *, double, double, double basevalue, double influence,
|
||||
double force) const {
|
||||
return basevalue + influence * force;
|
||||
}
|
||||
|
||||
double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const
|
||||
{
|
||||
double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
|
||||
double force) const {
|
||||
double ideal, factor;
|
||||
ideal = grid->getFinalValue((x + total_radius * 0.5), y);
|
||||
ideal += grid->getFinalValue((x - total_radius * 0.5), y);
|
||||
|
@ -59,26 +49,25 @@ double PaintedGridBrushSmooth::getValue(const PaintedGrid *grid, double x, doubl
|
|||
ideal += grid->getFinalValue(x, (y + total_radius * 0.5));
|
||||
ideal /= 4.0;
|
||||
factor = influence * force;
|
||||
if (factor > 1.0)
|
||||
{
|
||||
if (factor > 1.0) {
|
||||
factor = 0.0;
|
||||
}
|
||||
return basevalue + (ideal - basevalue) * factor;
|
||||
}
|
||||
|
||||
double PaintedGridBrushAddNoise::getValue(const PaintedGrid *, double x, double y, double basevalue, double influence, double force) const
|
||||
{
|
||||
double PaintedGridBrushAddNoise::getValue(const PaintedGrid *, double x, double y, double basevalue, double influence,
|
||||
double force) const {
|
||||
return basevalue + generator->get2DTotal(x / total_radius, y / total_radius) * influence * force * total_radius;
|
||||
}
|
||||
|
||||
double PaintedGridBrushReset::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const
|
||||
{
|
||||
double PaintedGridBrushReset::getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
|
||||
double force) const {
|
||||
double ideal = grid->getInitialValue(x, y);
|
||||
return basevalue + (ideal - basevalue) * influence * force;
|
||||
}
|
||||
|
||||
double PaintedGridBrushFlatten::getValue(const PaintedGrid *, double, double, double basevalue, double influence, double force) const
|
||||
{
|
||||
double PaintedGridBrushFlatten::getValue(const PaintedGrid *, double, double, double basevalue, double influence,
|
||||
double force) const {
|
||||
double ideal = target;
|
||||
return basevalue + (ideal - basevalue) * influence * force;
|
||||
}
|
||||
|
|
|
@ -9,9 +9,8 @@ namespace definition {
|
|||
/**
|
||||
* Base class for brushes that can be used to paint values on a PaintedGrid.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrush(double hard_radius, double smoothed_size, double total_radius);
|
||||
|
||||
/**
|
||||
|
@ -27,9 +26,10 @@ public:
|
|||
/**
|
||||
* Abstract method to reimplement to get the final value of a brush stroke at a given point.
|
||||
*/
|
||||
virtual double getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence, double force) const;
|
||||
virtual double getValue(const PaintedGrid *grid, double x, double y, double basevalue, double influence,
|
||||
double force) const;
|
||||
|
||||
protected:
|
||||
protected:
|
||||
double hard_radius;
|
||||
double smoothed_size;
|
||||
double total_radius;
|
||||
|
@ -38,57 +38,64 @@ protected:
|
|||
/**
|
||||
* Brush able to raise or lower the grid value.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower: public PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushRaiseLower : public PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrushRaiseLower(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
|
||||
}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
|
||||
double force) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brush able to smooth the value in an area.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth: public PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushSmooth : public PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrushSmooth(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
|
||||
}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
|
||||
double force) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brush able to add random fractal noise.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise: public PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator) : PaintedGridBrush(brush), generator(generator) {}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
|
||||
private:
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushAddNoise : public PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrushAddNoise(const PaintedGridBrush &brush, NoiseGenerator *generator)
|
||||
: PaintedGridBrush(brush), generator(generator) {
|
||||
}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
|
||||
double force) const override;
|
||||
|
||||
private:
|
||||
NoiseGenerator *generator;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brush able to reset to initial value.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushReset: public PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushReset : public PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrushReset(const PaintedGridBrush &brush) : PaintedGridBrush(brush) {
|
||||
}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
|
||||
double force) const override;
|
||||
};
|
||||
|
||||
/**
|
||||
* Brush able to flatten to a specific value.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten: public PaintedGridBrush
|
||||
{
|
||||
public:
|
||||
PaintedGridBrushFlatten(const PaintedGridBrush &brush, double target) : PaintedGridBrush(brush), target(target) {}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence, double force) const override;
|
||||
private:
|
||||
class DEFINITIONSHARED_EXPORT PaintedGridBrushFlatten : public PaintedGridBrush {
|
||||
public:
|
||||
PaintedGridBrushFlatten(const PaintedGridBrush &brush, double target) : PaintedGridBrush(brush), target(target) {
|
||||
}
|
||||
double getValue(const PaintedGrid *grid, double x, double z, double basevalue, double influence,
|
||||
double force) const override;
|
||||
|
||||
private:
|
||||
double target;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,46 +3,40 @@
|
|||
#include <cstring>
|
||||
#include "PackStream.h"
|
||||
|
||||
PaintedGridData::PaintedGridData()
|
||||
{
|
||||
PaintedGridData::PaintedGridData() {
|
||||
rows_count = 0;
|
||||
rows = (HeightMapRow *)malloc(sizeof(HeightMapRow));
|
||||
memsize = 0;
|
||||
}
|
||||
|
||||
PaintedGridData::~PaintedGridData()
|
||||
{
|
||||
PaintedGridData::~PaintedGridData() {
|
||||
clear();
|
||||
free(rows);
|
||||
}
|
||||
|
||||
void PaintedGridData::copy(PaintedGridData *destination) const
|
||||
{
|
||||
void PaintedGridData::copy(PaintedGridData *destination) const {
|
||||
int i, j, n;
|
||||
size_t size;
|
||||
|
||||
destination->clear();
|
||||
|
||||
destination->rows_count = this->rows_count;
|
||||
if (destination->rows_count > 0)
|
||||
{
|
||||
if (destination->rows_count > 0) {
|
||||
size = sizeof(HeightMapRow) * destination->rows_count;
|
||||
destination->rows = (HeightMapRow*)realloc(destination->rows, size);
|
||||
destination->rows = (HeightMapRow *)realloc(destination->rows, size);
|
||||
destination->memsize += size;
|
||||
for (i = 0; i < destination->rows_count; i++)
|
||||
{
|
||||
for (i = 0; i < destination->rows_count; i++) {
|
||||
destination->rows[i].y = this->rows[i].y;
|
||||
destination->rows[i].pixel_groups_count = this->rows[i].pixel_groups_count;
|
||||
size = sizeof(HeightMapPixelGroup) * destination->rows[i].pixel_groups_count;
|
||||
destination->rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
||||
destination->rows[i].pixel_groups = (HeightMapPixelGroup *)malloc(size);
|
||||
destination->memsize += size;
|
||||
for (j = 0; j < destination->rows[i].pixel_groups_count; j++)
|
||||
{
|
||||
for (j = 0; j < destination->rows[i].pixel_groups_count; j++) {
|
||||
destination->rows[i].pixel_groups[j].xstart = this->rows[i].pixel_groups[j].xstart;
|
||||
destination->rows[i].pixel_groups[j].xend = this->rows[i].pixel_groups[j].xend;
|
||||
n = destination->rows[i].pixel_groups[j].xend - destination->rows[i].pixel_groups[j].xstart + 1;
|
||||
size = sizeof(double) * n;
|
||||
destination->rows[i].pixel_groups[j].height = (double*)malloc(size);
|
||||
destination->rows[i].pixel_groups[j].height = (double *)malloc(size);
|
||||
destination->memsize += size;
|
||||
memcpy(destination->rows[i].pixel_groups[j].height, this->rows[i].pixel_groups[j].height, size);
|
||||
}
|
||||
|
@ -50,56 +44,47 @@ void PaintedGridData::copy(PaintedGridData *destination) const
|
|||
}
|
||||
}
|
||||
|
||||
void PaintedGridData::save(PackStream *stream) const
|
||||
{
|
||||
void PaintedGridData::save(PackStream *stream) const {
|
||||
int i, j, k;
|
||||
stream->write(&rows_count);
|
||||
for (i = 0; i < rows_count; i++)
|
||||
{
|
||||
for (i = 0; i < rows_count; i++) {
|
||||
stream->write(&rows[i].y);
|
||||
stream->write(&rows[i].pixel_groups_count);
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++)
|
||||
{
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++) {
|
||||
stream->write(&rows[i].pixel_groups[j].xstart);
|
||||
stream->write(&rows[i].pixel_groups[j].xend);
|
||||
for (k = 0; k < rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart; k++)
|
||||
{
|
||||
for (k = 0; k < rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart; k++) {
|
||||
stream->write(&rows[i].pixel_groups[j].height[k]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PaintedGridData::load(PackStream *stream)
|
||||
{
|
||||
void PaintedGridData::load(PackStream *stream) {
|
||||
int i, j, k, n;
|
||||
size_t size;
|
||||
|
||||
clear();
|
||||
|
||||
stream->read(&rows_count);
|
||||
if (rows_count > 0)
|
||||
{
|
||||
if (rows_count > 0) {
|
||||
size = sizeof(HeightMapRow) * rows_count;
|
||||
rows = (HeightMapRow*)realloc(rows, size);
|
||||
rows = (HeightMapRow *)realloc(rows, size);
|
||||
memsize += size;
|
||||
for (i = 0; i < rows_count; i++)
|
||||
{
|
||||
for (i = 0; i < rows_count; i++) {
|
||||
stream->read(&rows[i].y);
|
||||
stream->read(&rows[i].pixel_groups_count);
|
||||
size = sizeof(HeightMapPixelGroup) * rows[i].pixel_groups_count;
|
||||
rows[i].pixel_groups = (HeightMapPixelGroup*)malloc(size);
|
||||
rows[i].pixel_groups = (HeightMapPixelGroup *)malloc(size);
|
||||
memsize += size;
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++)
|
||||
{
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++) {
|
||||
stream->read(&rows[i].pixel_groups[j].xstart);
|
||||
stream->read(&rows[i].pixel_groups[j].xend);
|
||||
n = rows[i].pixel_groups[j].xend - rows[i].pixel_groups[j].xstart;
|
||||
size = sizeof(double) * n;
|
||||
rows[i].pixel_groups[j].height = (double*)malloc(size);
|
||||
rows[i].pixel_groups[j].height = (double *)malloc(size);
|
||||
memsize += size;
|
||||
for (k = 0; k < n; k++)
|
||||
{
|
||||
for (k = 0; k < n; k++) {
|
||||
stream->read(&rows[i].pixel_groups[j].height[k]);
|
||||
}
|
||||
}
|
||||
|
@ -107,13 +92,10 @@ void PaintedGridData::load(PackStream *stream)
|
|||
}
|
||||
}
|
||||
|
||||
void PaintedGridData::clear()
|
||||
{
|
||||
void PaintedGridData::clear() {
|
||||
int i, j;
|
||||
for (i = 0; i < rows_count; i++)
|
||||
{
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++)
|
||||
{
|
||||
for (i = 0; i < rows_count; i++) {
|
||||
for (j = 0; j < rows[i].pixel_groups_count; j++) {
|
||||
free(rows[i].pixel_groups[j].height);
|
||||
}
|
||||
free(rows[i].pixel_groups);
|
||||
|
|
|
@ -9,11 +9,10 @@ namespace definition {
|
|||
/**
|
||||
* Internal storage class to hold data for a PaintedGrid.
|
||||
*/
|
||||
class PaintedGridData
|
||||
{
|
||||
class PaintedGridData {
|
||||
friend class PaintedGrid;
|
||||
|
||||
public:
|
||||
public:
|
||||
PaintedGridData();
|
||||
~PaintedGridData();
|
||||
|
||||
|
@ -26,28 +25,27 @@ public:
|
|||
*/
|
||||
void clear();
|
||||
|
||||
inline bool hasData() const {return rows_count > 0;}
|
||||
inline bool hasData() const {
|
||||
return rows_count > 0;
|
||||
}
|
||||
|
||||
private:
|
||||
typedef struct
|
||||
{
|
||||
private:
|
||||
typedef struct {
|
||||
int xstart;
|
||||
int xend;
|
||||
double* height;
|
||||
double *height;
|
||||
} HeightMapPixelGroup;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
int y;
|
||||
int pixel_groups_count;
|
||||
HeightMapPixelGroup* pixel_groups;
|
||||
HeightMapPixelGroup *pixel_groups;
|
||||
} HeightMapRow;
|
||||
|
||||
int memsize;
|
||||
int rows_count;
|
||||
HeightMapRow* rows;
|
||||
HeightMapRow *rows;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -15,9 +15,7 @@
|
|||
static const double APP_HEADER = 19866544632.125;
|
||||
static const int DATA_VERSION = 1;
|
||||
|
||||
Scenery::Scenery():
|
||||
DefinitionNode(NULL, "scenery", "scenery")
|
||||
{
|
||||
Scenery::Scenery() : DefinitionNode(NULL, "scenery", "scenery") {
|
||||
atmosphere = new AtmosphereDefinition(this);
|
||||
camera = new CameraDefinition(this);
|
||||
clouds = new CloudsDefinition(this);
|
||||
|
@ -26,21 +24,18 @@ Scenery::Scenery():
|
|||
water = new WaterDefinition(this);
|
||||
}
|
||||
|
||||
void Scenery::validate()
|
||||
{
|
||||
void Scenery::validate() {
|
||||
DefinitionNode::validate();
|
||||
|
||||
keepCameraAboveGround(camera);
|
||||
}
|
||||
|
||||
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const
|
||||
{
|
||||
Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) const {
|
||||
PackStream stream;
|
||||
double app_header = (double)APP_HEADER;
|
||||
double version_header = (double)DATA_VERSION;
|
||||
|
||||
if (not stream.bindToFile(filepath, true))
|
||||
{
|
||||
if (not stream.bindToFile(filepath, true)) {
|
||||
return FILE_OPERATION_IOERROR;
|
||||
}
|
||||
|
||||
|
@ -56,25 +51,21 @@ Scenery::FileOperationResult Scenery::saveGlobal(const std::string &filepath) co
|
|||
return FILE_OPERATION_OK;
|
||||
}
|
||||
|
||||
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
|
||||
{
|
||||
Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath) {
|
||||
PackStream stream;
|
||||
double app_header, version_header;
|
||||
|
||||
if (not stream.bindToFile(filepath, false))
|
||||
{
|
||||
if (not stream.bindToFile(filepath, false)) {
|
||||
return FILE_OPERATION_IOERROR;
|
||||
}
|
||||
|
||||
stream.read(&app_header);
|
||||
if (app_header != APP_HEADER)
|
||||
{
|
||||
if (app_header != APP_HEADER) {
|
||||
return FILE_OPERATION_APP_MISMATCH;
|
||||
}
|
||||
|
||||
stream.read(&version_header);
|
||||
if ((int)version_header != DATA_VERSION)
|
||||
{
|
||||
if ((int)version_header != DATA_VERSION) {
|
||||
return FILE_OPERATION_VERSION_MISMATCH;
|
||||
}
|
||||
|
||||
|
@ -85,14 +76,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
|
|||
version_header = -1;
|
||||
|
||||
stream.read(&version_header);
|
||||
if ((int)version_header != DATA_VERSION)
|
||||
{
|
||||
if ((int)version_header != DATA_VERSION) {
|
||||
return FILE_OPERATION_VERSION_MISMATCH;
|
||||
}
|
||||
|
||||
stream.read(&app_header);
|
||||
if (app_header != APP_HEADER)
|
||||
{
|
||||
if (app_header != APP_HEADER) {
|
||||
return FILE_OPERATION_APP_MISMATCH;
|
||||
}
|
||||
|
||||
|
@ -100,15 +89,12 @@ Scenery::FileOperationResult Scenery::loadGlobal(const std::string &filepath)
|
|||
return FILE_OPERATION_OK;
|
||||
}
|
||||
|
||||
Scenery* Scenery::getScenery()
|
||||
{
|
||||
Scenery *Scenery::getScenery() {
|
||||
return this;
|
||||
}
|
||||
|
||||
void Scenery::autoPreset(int seed)
|
||||
{
|
||||
if (!seed)
|
||||
{
|
||||
void Scenery::autoPreset(int seed) {
|
||||
if (!seed) {
|
||||
seed = time(NULL);
|
||||
}
|
||||
srand(seed);
|
||||
|
@ -127,74 +113,60 @@ void Scenery::autoPreset(int seed)
|
|||
Logs::debug() << "New scenery generated from seed " << seed << std::endl;
|
||||
}
|
||||
|
||||
void Scenery::setAtmosphere(AtmosphereDefinition* atmosphere)
|
||||
{
|
||||
void Scenery::setAtmosphere(AtmosphereDefinition *atmosphere) {
|
||||
atmosphere->copy(this->atmosphere);
|
||||
}
|
||||
|
||||
void Scenery::getAtmosphere(AtmosphereDefinition* atmosphere)
|
||||
{
|
||||
void Scenery::getAtmosphere(AtmosphereDefinition *atmosphere) {
|
||||
this->atmosphere->copy(atmosphere);
|
||||
}
|
||||
|
||||
void Scenery::setCamera(CameraDefinition* camera)
|
||||
{
|
||||
void Scenery::setCamera(CameraDefinition *camera) {
|
||||
camera->copy(this->camera);
|
||||
keepCameraAboveGround(this->camera);
|
||||
}
|
||||
|
||||
void Scenery::getCamera(CameraDefinition* camera)
|
||||
{
|
||||
void Scenery::getCamera(CameraDefinition *camera) {
|
||||
this->camera->copy(camera);
|
||||
}
|
||||
|
||||
void Scenery::setClouds(CloudsDefinition* clouds)
|
||||
{
|
||||
void Scenery::setClouds(CloudsDefinition *clouds) {
|
||||
clouds->copy(this->clouds);
|
||||
}
|
||||
|
||||
void Scenery::getClouds(CloudsDefinition* clouds)
|
||||
{
|
||||
void Scenery::getClouds(CloudsDefinition *clouds) {
|
||||
this->clouds->copy(clouds);
|
||||
}
|
||||
|
||||
void Scenery::setTerrain(TerrainDefinition* terrain)
|
||||
{
|
||||
void Scenery::setTerrain(TerrainDefinition *terrain) {
|
||||
terrain->copy(this->terrain);
|
||||
}
|
||||
|
||||
void Scenery::getTerrain(TerrainDefinition* terrain)
|
||||
{
|
||||
void Scenery::getTerrain(TerrainDefinition *terrain) {
|
||||
this->terrain->copy(terrain);
|
||||
}
|
||||
|
||||
void Scenery::setTextures(TexturesDefinition* textures)
|
||||
{
|
||||
void Scenery::setTextures(TexturesDefinition *textures) {
|
||||
textures->copy(this->textures);
|
||||
}
|
||||
|
||||
void Scenery::getTextures(TexturesDefinition* textures)
|
||||
{
|
||||
void Scenery::getTextures(TexturesDefinition *textures) {
|
||||
this->textures->copy(textures);
|
||||
}
|
||||
|
||||
void Scenery::setWater(WaterDefinition* water)
|
||||
{
|
||||
void Scenery::setWater(WaterDefinition *water) {
|
||||
water->copy(this->water);
|
||||
}
|
||||
|
||||
void Scenery::getWater(WaterDefinition* water)
|
||||
{
|
||||
void Scenery::getWater(WaterDefinition *water) {
|
||||
this->water->copy(water);
|
||||
}
|
||||
|
||||
void Scenery::keepCameraAboveGround(CameraDefinition* camera)
|
||||
{
|
||||
void Scenery::keepCameraAboveGround(CameraDefinition *camera) {
|
||||
Vector3 camera_location = camera->getLocation();
|
||||
double terrain_height = terrain->getInterpolatedHeight(camera_location.x, camera_location.z, true, true) + 1.0;
|
||||
double water_height = 0.5;
|
||||
if (camera_location.y < water_height || camera_location.y < terrain_height)
|
||||
{
|
||||
if (camera_location.y < water_height || camera_location.y < terrain_height) {
|
||||
double diff = ((water_height > terrain_height) ? water_height : terrain_height) - camera_location.y;
|
||||
camera->setLocation(camera_location.add(Vector3(0.0, diff, 0.0)));
|
||||
}
|
||||
|
|
|
@ -13,9 +13,8 @@ namespace definition {
|
|||
*
|
||||
* This class contains the whole scenery definition.
|
||||
*/
|
||||
class DEFINITIONSHARED_EXPORT Scenery: public DefinitionNode
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT Scenery : public DefinitionNode {
|
||||
public:
|
||||
typedef enum {
|
||||
FILE_OPERATION_OK,
|
||||
FILE_OPERATION_IOERROR,
|
||||
|
@ -23,9 +22,9 @@ public:
|
|||
FILE_OPERATION_VERSION_MISMATCH
|
||||
} FileOperationResult;
|
||||
|
||||
typedef void (*SceneryCustomDataCallback)(PackStream* stream, void* data);
|
||||
typedef void (*SceneryCustomDataCallback)(PackStream *stream, void *data);
|
||||
|
||||
public:
|
||||
public:
|
||||
Scenery();
|
||||
|
||||
virtual void validate() override;
|
||||
|
@ -33,45 +32,56 @@ public:
|
|||
FileOperationResult saveGlobal(const std::string &filepath) const;
|
||||
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);
|
||||
inline AtmosphereDefinition* getAtmosphere() const {return atmosphere;}
|
||||
void getAtmosphere(AtmosphereDefinition* atmosphere);
|
||||
void setAtmosphere(AtmosphereDefinition *atmosphere);
|
||||
inline AtmosphereDefinition *getAtmosphere() const {
|
||||
return atmosphere;
|
||||
}
|
||||
void getAtmosphere(AtmosphereDefinition *atmosphere);
|
||||
|
||||
void setCamera(CameraDefinition* camera);
|
||||
inline CameraDefinition* getCamera() const {return camera;}
|
||||
void getCamera(CameraDefinition* camera);
|
||||
void setCamera(CameraDefinition *camera);
|
||||
inline CameraDefinition *getCamera() const {
|
||||
return camera;
|
||||
}
|
||||
void getCamera(CameraDefinition *camera);
|
||||
|
||||
void setClouds(CloudsDefinition* clouds);
|
||||
inline CloudsDefinition* getClouds() const {return clouds;}
|
||||
void getClouds(CloudsDefinition* clouds);
|
||||
void setClouds(CloudsDefinition *clouds);
|
||||
inline CloudsDefinition *getClouds() const {
|
||||
return clouds;
|
||||
}
|
||||
void getClouds(CloudsDefinition *clouds);
|
||||
|
||||
void setTerrain(TerrainDefinition* terrain);
|
||||
inline TerrainDefinition* getTerrain() const {return terrain;}
|
||||
void getTerrain(TerrainDefinition* terrain);
|
||||
void setTerrain(TerrainDefinition *terrain);
|
||||
inline TerrainDefinition *getTerrain() const {
|
||||
return terrain;
|
||||
}
|
||||
void getTerrain(TerrainDefinition *terrain);
|
||||
|
||||
void setTextures(TexturesDefinition* textures);
|
||||
inline TexturesDefinition* getTextures() const {return textures;}
|
||||
void getTextures(TexturesDefinition* textures);
|
||||
void setTextures(TexturesDefinition *textures);
|
||||
inline TexturesDefinition *getTextures() const {
|
||||
return textures;
|
||||
}
|
||||
void getTextures(TexturesDefinition *textures);
|
||||
|
||||
void setWater(WaterDefinition* water);
|
||||
inline WaterDefinition* getWater() const {return water;}
|
||||
void getWater(WaterDefinition* water);
|
||||
void setWater(WaterDefinition *water);
|
||||
inline WaterDefinition *getWater() const {
|
||||
return water;
|
||||
}
|
||||
void getWater(WaterDefinition *water);
|
||||
|
||||
void keepCameraAboveGround(CameraDefinition* camera);
|
||||
void keepCameraAboveGround(CameraDefinition *camera);
|
||||
|
||||
private:
|
||||
AtmosphereDefinition* atmosphere;
|
||||
CameraDefinition* camera;
|
||||
CloudsDefinition* clouds;
|
||||
TerrainDefinition* terrain;
|
||||
TexturesDefinition* textures;
|
||||
WaterDefinition* water;
|
||||
private:
|
||||
AtmosphereDefinition *atmosphere;
|
||||
CameraDefinition *camera;
|
||||
CloudsDefinition *clouds;
|
||||
TerrainDefinition *terrain;
|
||||
TexturesDefinition *textures;
|
||||
WaterDefinition *water;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,13 +5,10 @@
|
|||
|
||||
static SurfaceMaterial DEFAULT;
|
||||
|
||||
SurfaceMaterial::SurfaceMaterial():
|
||||
SurfaceMaterial(COLOR_BLACK)
|
||||
{
|
||||
SurfaceMaterial::SurfaceMaterial() : SurfaceMaterial(COLOR_BLACK) {
|
||||
}
|
||||
|
||||
SurfaceMaterial::SurfaceMaterial(const Color &color)
|
||||
{
|
||||
SurfaceMaterial::SurfaceMaterial(const Color &color) {
|
||||
base = new Color(color);
|
||||
hardness = 0.5;
|
||||
reflection = 0.0;
|
||||
|
@ -19,26 +16,22 @@ SurfaceMaterial::SurfaceMaterial(const Color &color)
|
|||
receive_shadows = 1.0;
|
||||
}
|
||||
|
||||
SurfaceMaterial::~SurfaceMaterial()
|
||||
{
|
||||
SurfaceMaterial::~SurfaceMaterial() {
|
||||
delete base;
|
||||
}
|
||||
|
||||
const SurfaceMaterial &SurfaceMaterial::getDefault()
|
||||
{
|
||||
const SurfaceMaterial &SurfaceMaterial::getDefault() {
|
||||
return DEFAULT;
|
||||
}
|
||||
|
||||
void SurfaceMaterial::setColor(double r, double g, double b, double a)
|
||||
{
|
||||
void SurfaceMaterial::setColor(double r, double g, double b, double a) {
|
||||
base->r = r;
|
||||
base->g = g;
|
||||
base->b = b;
|
||||
base->a = a;
|
||||
}
|
||||
|
||||
void SurfaceMaterial::save(PackStream* stream) const
|
||||
{
|
||||
void SurfaceMaterial::save(PackStream *stream) const {
|
||||
base->save(stream);
|
||||
|
||||
stream->write(&hardness);
|
||||
|
@ -48,8 +41,7 @@ void SurfaceMaterial::save(PackStream* stream) const
|
|||
stream->write(&receive_shadows);
|
||||
}
|
||||
|
||||
void SurfaceMaterial::load(PackStream* stream)
|
||||
{
|
||||
void SurfaceMaterial::load(PackStream *stream) {
|
||||
base->load(stream);
|
||||
|
||||
stream->read(&hardness);
|
||||
|
@ -59,8 +51,7 @@ void SurfaceMaterial::load(PackStream* stream)
|
|||
stream->read(&receive_shadows);
|
||||
}
|
||||
|
||||
void SurfaceMaterial::copy(SurfaceMaterial *destination) const
|
||||
{
|
||||
void SurfaceMaterial::copy(SurfaceMaterial *destination) const {
|
||||
*destination->base = *base;
|
||||
destination->hardness = hardness;
|
||||
destination->reflection = reflection;
|
||||
|
@ -69,6 +60,5 @@ void SurfaceMaterial::copy(SurfaceMaterial *destination) const
|
|||
destination->validate();
|
||||
}
|
||||
|
||||
void SurfaceMaterial::validate()
|
||||
{
|
||||
void SurfaceMaterial::validate() {
|
||||
}
|
||||
|
|
|
@ -6,23 +6,22 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT SurfaceMaterial
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT SurfaceMaterial {
|
||||
public:
|
||||
SurfaceMaterial();
|
||||
SurfaceMaterial(const Color& color);
|
||||
SurfaceMaterial(const Color &color);
|
||||
~SurfaceMaterial();
|
||||
|
||||
static const SurfaceMaterial &getDefault();
|
||||
|
||||
void setColor(double r, double g, double b, double a);
|
||||
|
||||
void save(PackStream* stream) const;
|
||||
void load(PackStream* stream);
|
||||
void save(PackStream *stream) const;
|
||||
void load(PackStream *stream);
|
||||
void copy(SurfaceMaterial *destination) const;
|
||||
void validate();
|
||||
|
||||
public:
|
||||
public:
|
||||
Color *base;
|
||||
|
||||
double hardness;
|
||||
|
@ -31,7 +30,6 @@ public:
|
|||
|
||||
double receive_shadows;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,7 @@
|
|||
#include "PackStream.h"
|
||||
#include "FloatNode.h"
|
||||
|
||||
TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
||||
DefinitionNode(parent, "terrain", "terrain")
|
||||
{
|
||||
TerrainDefinition::TerrainDefinition(DefinitionNode *parent) : DefinitionNode(parent, "terrain", "terrain") {
|
||||
height = 1.0;
|
||||
shadow_smoothing = 0.0;
|
||||
|
||||
|
@ -20,17 +18,14 @@ TerrainDefinition::TerrainDefinition(DefinitionNode* parent):
|
|||
_height_noise = new NoiseGenerator;
|
||||
}
|
||||
|
||||
TerrainDefinition::~TerrainDefinition()
|
||||
{
|
||||
TerrainDefinition::~TerrainDefinition() {
|
||||
delete _height_noise;
|
||||
}
|
||||
|
||||
void TerrainDefinition::validate()
|
||||
{
|
||||
void TerrainDefinition::validate() {
|
||||
_height_noise->validate();
|
||||
|
||||
if (height < 1.0)
|
||||
{
|
||||
if (height < 1.0) {
|
||||
height = 1.0;
|
||||
}
|
||||
|
||||
|
@ -43,9 +38,8 @@ void TerrainDefinition::validate()
|
|||
has_painting = height_map->hasPainting();
|
||||
}
|
||||
|
||||
void TerrainDefinition::copy(DefinitionNode* _destination) const
|
||||
{
|
||||
TerrainDefinition* destination = (TerrainDefinition*)_destination;
|
||||
void TerrainDefinition::copy(DefinitionNode *_destination) const {
|
||||
TerrainDefinition *destination = (TerrainDefinition *)_destination;
|
||||
|
||||
destination->height = height;
|
||||
destination->shadow_smoothing = shadow_smoothing;
|
||||
|
@ -57,8 +51,7 @@ void TerrainDefinition::copy(DefinitionNode* _destination) const
|
|||
destination->validate();
|
||||
}
|
||||
|
||||
void TerrainDefinition::save(PackStream* stream) const
|
||||
{
|
||||
void TerrainDefinition::save(PackStream *stream) const {
|
||||
DefinitionNode::save(stream);
|
||||
|
||||
stream->write(&height);
|
||||
|
@ -66,8 +59,7 @@ void TerrainDefinition::save(PackStream* stream) const
|
|||
_height_noise->save(stream);
|
||||
}
|
||||
|
||||
void TerrainDefinition::load(PackStream* stream)
|
||||
{
|
||||
void TerrainDefinition::load(PackStream *stream) {
|
||||
DefinitionNode::load(stream);
|
||||
|
||||
stream->read(&height);
|
||||
|
@ -77,44 +69,36 @@ void TerrainDefinition::load(PackStream* stream)
|
|||
validate();
|
||||
}
|
||||
|
||||
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting)
|
||||
{
|
||||
double TerrainDefinition::getGridHeight(int x, int z, bool with_painting) {
|
||||
double h;
|
||||
|
||||
if (!with_painting || !has_painting || !height_map->getGridValue(x, z, &h))
|
||||
{
|
||||
if (!with_painting || !has_painting || !height_map->getGridValue(x, z, &h)) {
|
||||
h = _height_noise->get2DTotal((double)x, (double)z);
|
||||
}
|
||||
|
||||
return h;
|
||||
}
|
||||
|
||||
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset)
|
||||
{
|
||||
double TerrainDefinition::getInterpolatedHeight(double x, double z, bool scaled, bool with_painting,
|
||||
bool water_offset) {
|
||||
double h;
|
||||
|
||||
if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h))
|
||||
{
|
||||
if (!with_painting || !has_painting || !height_map->getInterpolatedValue(x, z, &h)) {
|
||||
h = _height_noise->get2DTotal(x, z);
|
||||
}
|
||||
|
||||
if (scaled)
|
||||
{
|
||||
if (scaled) {
|
||||
return (water_offset ? (h - water_height->getValue()) : h) * height;
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
return h;
|
||||
}
|
||||
}
|
||||
|
||||
double TerrainDefinition::getWaterOffset() const
|
||||
{
|
||||
double TerrainDefinition::getWaterOffset() const {
|
||||
return -water_height->getValue() * height;
|
||||
}
|
||||
|
||||
HeightInfo TerrainDefinition::getHeightInfo()
|
||||
{
|
||||
HeightInfo TerrainDefinition::getHeightInfo() {
|
||||
HeightInfo result;
|
||||
|
||||
result.min_height = _min_height;
|
||||
|
@ -124,16 +108,13 @@ HeightInfo TerrainDefinition::getHeightInfo()
|
|||
return result;
|
||||
}
|
||||
|
||||
unsigned long TerrainDefinition::getMemoryStats()
|
||||
{
|
||||
unsigned long TerrainDefinition::getMemoryStats() {
|
||||
return height_map->getMemoryStats();
|
||||
}
|
||||
|
||||
void TerrainDefinition::applyPreset(TerrainPreset preset)
|
||||
{
|
||||
void TerrainDefinition::applyPreset(TerrainPreset preset) {
|
||||
int resolution = 8;
|
||||
switch (preset)
|
||||
{
|
||||
switch (preset) {
|
||||
case TERRAIN_PRESET_STANDARD:
|
||||
_height_noise->randomizeOffsets();
|
||||
_height_noise->clearLevels();
|
||||
|
|
|
@ -8,56 +8,52 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
double min_height;
|
||||
double max_height;
|
||||
double base_height;
|
||||
} HeightInfo;
|
||||
|
||||
class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode
|
||||
{
|
||||
public:
|
||||
TerrainDefinition(DefinitionNode* parent);
|
||||
class DEFINITIONSHARED_EXPORT TerrainDefinition : public DefinitionNode {
|
||||
public:
|
||||
TerrainDefinition(DefinitionNode *parent);
|
||||
virtual ~TerrainDefinition();
|
||||
|
||||
virtual void save(PackStream* stream) const override;
|
||||
virtual void load(PackStream* stream) override;
|
||||
virtual void save(PackStream *stream) const override;
|
||||
virtual void load(PackStream *stream) override;
|
||||
|
||||
virtual void copy(DefinitionNode* destination) const override;
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
virtual void validate() override;
|
||||
|
||||
inline FloatNode *propWaterHeight() const {return water_height;}
|
||||
inline FloatNode *propWaterHeight() const {
|
||||
return water_height;
|
||||
}
|
||||
|
||||
double getGridHeight(int x, int z, bool with_painting);
|
||||
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset=true);
|
||||
double getInterpolatedHeight(double x, double z, bool scaled, bool with_painting, bool water_offset = true);
|
||||
double getWaterOffset() const;
|
||||
unsigned long getMemoryStats();
|
||||
HeightInfo getHeightInfo();
|
||||
|
||||
public:
|
||||
typedef enum
|
||||
{
|
||||
TERRAIN_PRESET_STANDARD
|
||||
} TerrainPreset;
|
||||
public:
|
||||
typedef enum { TERRAIN_PRESET_STANDARD } TerrainPreset;
|
||||
void applyPreset(TerrainPreset preset);
|
||||
|
||||
public:
|
||||
public:
|
||||
double height;
|
||||
double shadow_smoothing;
|
||||
|
||||
TerrainHeightMap* height_map;
|
||||
TerrainHeightMap *height_map;
|
||||
bool has_painting;
|
||||
|
||||
double _detail;
|
||||
NoiseGenerator* _height_noise;
|
||||
NoiseGenerator *_height_noise;
|
||||
double _min_height;
|
||||
double _max_height;
|
||||
|
||||
private:
|
||||
private:
|
||||
FloatNode *water_height;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -3,64 +3,55 @@
|
|||
#include "TerrainDefinition.h"
|
||||
#include "PaintedGridBrush.h"
|
||||
|
||||
TerrainHeightMap::TerrainHeightMap(TerrainDefinition* terrain):
|
||||
PaintedGrid(terrain), terrain(terrain)
|
||||
{
|
||||
TerrainHeightMap::TerrainHeightMap(TerrainDefinition *terrain) : PaintedGrid(terrain), terrain(terrain) {
|
||||
}
|
||||
|
||||
void TerrainHeightMap::copy(DefinitionNode* _destination) const
|
||||
{
|
||||
TerrainHeightMap* destination = (TerrainHeightMap*)_destination;
|
||||
void TerrainHeightMap::copy(DefinitionNode *_destination) const {
|
||||
TerrainHeightMap *destination = (TerrainHeightMap *)_destination;
|
||||
|
||||
destination->terrain = terrain;
|
||||
|
||||
PaintedGrid::copy(destination);
|
||||
}
|
||||
|
||||
double TerrainHeightMap::getInitialValue(double x, double y) const
|
||||
{
|
||||
double TerrainHeightMap::getInitialValue(double x, double y) const {
|
||||
return terrain->getInterpolatedHeight(x, y, false, false);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
|
||||
{
|
||||
void TerrainHeightMap::brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
|
||||
PaintedGridBrushRaiseLower sbrush(brush);
|
||||
applyBrush(sbrush, x, y, value / terrain->height, commit);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force, bool commit)
|
||||
{
|
||||
void TerrainHeightMap::brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force,
|
||||
bool commit) {
|
||||
PaintedGridBrushFlatten sbrush(brush, height);
|
||||
applyBrush(sbrush, x, y, force / terrain->height, commit);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
|
||||
{
|
||||
void TerrainHeightMap::brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
|
||||
PaintedGridBrushSmooth sbrush(brush);
|
||||
applyBrush(sbrush, x, y, value / terrain->height, commit);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator* generator, double value, bool commit)
|
||||
{
|
||||
void TerrainHeightMap::brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator *generator,
|
||||
double value, bool commit) {
|
||||
PaintedGridBrushAddNoise sbrush(brush, generator);
|
||||
applyBrush(sbrush, x, y, value / terrain->height, commit);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit)
|
||||
{
|
||||
void TerrainHeightMap::brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit) {
|
||||
PaintedGridBrushReset sbrush(brush);
|
||||
applyBrush(sbrush, x, y, value / terrain->height, commit);
|
||||
}
|
||||
|
||||
void TerrainHeightMap::clearPainting()
|
||||
{
|
||||
void TerrainHeightMap::clearPainting() {
|
||||
PaintedGrid::clearPainting();
|
||||
|
||||
terrain->validate();
|
||||
}
|
||||
|
||||
void TerrainHeightMap::endBrushStroke()
|
||||
{
|
||||
void TerrainHeightMap::endBrushStroke() {
|
||||
PaintedGrid::endBrushStroke();
|
||||
|
||||
terrain->validate();
|
||||
|
|
|
@ -8,30 +8,32 @@
|
|||
namespace paysages {
|
||||
namespace definition {
|
||||
|
||||
class DEFINITIONSHARED_EXPORT TerrainHeightMap : public PaintedGrid
|
||||
{
|
||||
public:
|
||||
class DEFINITIONSHARED_EXPORT TerrainHeightMap : public PaintedGrid {
|
||||
public:
|
||||
TerrainHeightMap(TerrainDefinition *terrain);
|
||||
|
||||
virtual void copy(DefinitionNode *destination) const override;
|
||||
|
||||
inline TerrainDefinition* getTerrain() const {return terrain;}
|
||||
inline TerrainDefinition *getTerrain() const {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
virtual double getInitialValue(double x, double y) const override;
|
||||
|
||||
void brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
|
||||
void brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
|
||||
void brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator* generator, double value, bool commit=false);
|
||||
void brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit=false);
|
||||
void brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force, bool commit=false);
|
||||
void brushElevation(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
|
||||
void brushSmooth(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
|
||||
void brushAddNoise(const PaintedGridBrush &brush, double x, double y, NoiseGenerator *generator, double value,
|
||||
bool commit = false);
|
||||
void brushReset(const PaintedGridBrush &brush, double x, double y, double value, bool commit = false);
|
||||
void brushFlatten(const PaintedGridBrush &brush, double x, double y, double height, double force,
|
||||
bool commit = false);
|
||||
|
||||
virtual void clearPainting() override;
|
||||
virtual void endBrushStroke() override;
|
||||
|
||||
private:
|
||||
TerrainDefinition* terrain;
|
||||
private:
|
||||
TerrainDefinition *terrain;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,9 +8,8 @@
|
|||
#include "TerrainDefinition.h"
|
||||
#include "Color.h"
|
||||
|
||||
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode* parent):
|
||||
DefinitionNode(parent, "texture", "texturelayer")
|
||||
{
|
||||
TextureLayerDefinition::TextureLayerDefinition(DefinitionNode *parent)
|
||||
: DefinitionNode(parent, "texture", "texturelayer") {
|
||||
terrain_zone = new Zone;
|
||||
_displacement_noise = new NoiseGenerator;
|
||||
_detail_noise = new NoiseGenerator;
|
||||
|
@ -20,20 +19,17 @@ TextureLayerDefinition::TextureLayerDefinition(DefinitionNode* parent):
|
|||
displacement_scaling = 1.0;
|
||||
}
|
||||
|
||||
TextureLayerDefinition::~TextureLayerDefinition()
|
||||
{
|
||||
TextureLayerDefinition::~TextureLayerDefinition() {
|
||||
delete terrain_zone;
|
||||
delete _displacement_noise;
|
||||
delete _detail_noise;
|
||||
delete material;
|
||||
}
|
||||
|
||||
void TextureLayerDefinition::validate()
|
||||
{
|
||||
void TextureLayerDefinition::validate() {
|
||||
DefinitionNode::validate();
|
||||
|
||||
if (displacement_scaling < 0.000001)
|
||||
{
|
||||
if (displacement_scaling < 0.000001) {
|
||||
displacement_scaling = 0.000001;
|
||||
}
|
||||
|
||||
|
@ -50,20 +46,18 @@ void TextureLayerDefinition::validate()
|
|||
material->validate();
|
||||
|
||||
/* Update zone height range */
|
||||
Scenery* scenery = getScenery();
|
||||
if (scenery)
|
||||
{
|
||||
TerrainDefinition* terrain = scenery->getTerrain();
|
||||
Scenery *scenery = getScenery();
|
||||
if (scenery) {
|
||||
TerrainDefinition *terrain = scenery->getTerrain();
|
||||
HeightInfo height_info = terrain->getHeightInfo();
|
||||
terrain_zone->setRelativeHeight(height_info.min_height, height_info.base_height, height_info.max_height);
|
||||
}
|
||||
}
|
||||
|
||||
void TextureLayerDefinition::copy(DefinitionNode *_destination) const
|
||||
{
|
||||
void TextureLayerDefinition::copy(DefinitionNode *_destination) const {
|
||||
DefinitionNode::copy(_destination);
|
||||
|
||||
TextureLayerDefinition* destination = (TextureLayerDefinition*)_destination;
|
||||
TextureLayerDefinition *destination = (TextureLayerDefinition *)_destination;
|
||||
|
||||
terrain_zone->copy(destination->terrain_zone);
|
||||
|
||||
|
@ -76,8 +70,7 @@ void TextureLayerDefinition::copy(DefinitionNode *_destination) const
|
|||
_detail_noise->copy(destination->_detail_noise);
|
||||
}
|
||||
|
||||
void TextureLayerDefinition::save(PackStream* stream) const
|
||||
{
|
||||
void TextureLayerDefinition::save(PackStream *stream) const {
|
||||
DefinitionNode::save(stream);
|
||||
|
||||
terrain_zone->save(stream);
|
||||
|
@ -90,8 +83,7 @@ void TextureLayerDefinition::save(PackStream* stream) const
|
|||
_detail_noise->save(stream);
|
||||
}
|
||||
|
||||
void TextureLayerDefinition::load(PackStream* stream)
|
||||
{
|
||||
void TextureLayerDefinition::load(PackStream *stream) {
|
||||
DefinitionNode::load(stream);
|
||||
|
||||
terrain_zone->load(stream);
|
||||
|
@ -104,64 +96,62 @@ void TextureLayerDefinition::load(PackStream* stream)
|
|||
_detail_noise->load(stream);
|
||||
}
|
||||
|
||||
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset)
|
||||
{
|
||||
void TextureLayerDefinition::applyPreset(TextureLayerPreset preset) {
|
||||
_displacement_noise->randomizeOffsets();
|
||||
_detail_noise->randomizeOffsets();
|
||||
|
||||
terrain_zone->clear();
|
||||
|
||||
switch (preset)
|
||||
{
|
||||
case TEXTURES_LAYER_PRESET_MUD:
|
||||
displacement_height = 0.02;
|
||||
displacement_scaling = 3.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.015, 0.014, 0.014, 1.0);
|
||||
material->reflection = 0.003;
|
||||
material->shininess = 4.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_ROCK:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 1.0, 1.0);
|
||||
displacement_height = 0.3;
|
||||
displacement_scaling = 2.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||
material->reflection = 0.006;
|
||||
material->shininess = 6.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_GRASS:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.45, 0.5, 0.8, 1.0);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.05, 0.4);
|
||||
displacement_height = 0.0;
|
||||
displacement_scaling = 1.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.12, 0.19, 0.035, 1.0);
|
||||
material->reflection = 0.001;
|
||||
material->shininess = 4.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_SAND:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.495, 0.505, 0.56, 0.63);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.1, 0.4);
|
||||
displacement_height = 0.05;
|
||||
displacement_scaling = 5.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(1.2, 1.1, 0.9, 1.0);
|
||||
material->reflection = 0.008;
|
||||
material->shininess = 1.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_SNOW:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.77, 0.85, 1.0, 1.0);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.2, 1.0);
|
||||
displacement_height = 0.1;
|
||||
displacement_scaling = 1.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(5.0, 5.0, 5.0, 1.0);
|
||||
material->reflection = 0.02;
|
||||
material->shininess = 0.6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
switch (preset) {
|
||||
case TEXTURES_LAYER_PRESET_MUD:
|
||||
displacement_height = 0.02;
|
||||
displacement_scaling = 3.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.015, 0.014, 0.014, 1.0);
|
||||
material->reflection = 0.003;
|
||||
material->shininess = 4.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_ROCK:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.6, 0.7, 1.0, 1.0);
|
||||
displacement_height = 0.3;
|
||||
displacement_scaling = 2.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.6, 0.55, 0.57, 1.0);
|
||||
material->reflection = 0.006;
|
||||
material->shininess = 6.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_GRASS:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.45, 0.5, 0.8, 1.0);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.05, 0.4);
|
||||
displacement_height = 0.0;
|
||||
displacement_scaling = 1.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(0.12, 0.19, 0.035, 1.0);
|
||||
material->reflection = 0.001;
|
||||
material->shininess = 4.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_SAND:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.495, 0.505, 0.56, 0.63);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.1, 0.4);
|
||||
displacement_height = 0.05;
|
||||
displacement_scaling = 5.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(1.2, 1.1, 0.9, 1.0);
|
||||
material->reflection = 0.008;
|
||||
material->shininess = 1.0;
|
||||
break;
|
||||
case TEXTURES_LAYER_PRESET_SNOW:
|
||||
terrain_zone->addHeightRangeQuick(1.0, 0.77, 0.85, 1.0, 1.0);
|
||||
terrain_zone->addSlopeRangeQuick(1.0, 0.0, 0.0, 0.2, 1.0);
|
||||
displacement_height = 0.1;
|
||||
displacement_scaling = 1.0;
|
||||
displacement_offset = 0.0;
|
||||
material->setColor(5.0, 5.0, 5.0, 1.0);
|
||||
material->reflection = 0.02;
|
||||
material->shininess = 0.6;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
validate();
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue