paysages : Refactoring terrain and textures - WIP.
git-svn-id: https://subversion.assembla.com/svn/thunderk/paysages@206 b1fd45b6-86a6-48da-8261-f70d1f35bdcc
Before Width: | Height: | Size: 1.5 MiB |
Before Width: | Height: | Size: 1.1 MiB |
Before Width: | Height: | Size: 716 KiB |
Before Width: | Height: | Size: 1.3 MiB |
Before Width: | Height: | Size: 1.9 MiB |
Before Width: | Height: | Size: 728 KiB |
Before Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 1.6 MiB |
Before Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 306 B |
|
@ -2,8 +2,11 @@
|
|||
|
||||
#include "common.h"
|
||||
#include "lib_paysages/shared/functions.h"
|
||||
#include "lib_paysages/terrain.h"
|
||||
#include "lib_paysages/textures.h"
|
||||
|
||||
static SmallPreview* _preview;
|
||||
static TerrainDefinition _definition;
|
||||
|
||||
static Color _cbPreviewRenderPixel(SmallPreview* preview, double x, double y, double xoffset, double yoffset, double scaling)
|
||||
{
|
||||
|
@ -11,20 +14,25 @@ static Color _cbPreviewRenderPixel(SmallPreview* preview, double x, double y, do
|
|||
|
||||
result.r = result.g = result.b = terrainGetHeightNormalized(x, y);
|
||||
result.a = 1.0;
|
||||
|
||||
|
||||
/* TEMP */
|
||||
//result = terrainGetColor(x, y, 0.01);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static void _cbEditNoiseDone(NoiseGenerator* generator)
|
||||
{
|
||||
terrainSetNoiseGenerator(generator);
|
||||
noiseCopy(generator, _definition.height_noise);
|
||||
terrainSetDefinition(_definition);
|
||||
|
||||
/* TODO Redraw only affected by terrain */
|
||||
guiPreviewRedrawAll();
|
||||
}
|
||||
|
||||
static void _cbEditNoise(GtkWidget* widget, gpointer data)
|
||||
{
|
||||
guiNoiseEdit(terrainGetNoiseGenerator(), _cbEditNoiseDone);
|
||||
guiNoiseEdit(texturesGetDefinition(0).bump_noise, _cbEditNoiseDone);
|
||||
}
|
||||
|
||||
void guiTerrainInit()
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#include <QColor>
|
||||
#include <math.h>
|
||||
|
||||
#include "../lib_paysages/terrain.h"
|
||||
#include "../lib_paysages/water.h"
|
||||
#include "../lib_paysages/shared/functions.h"
|
||||
#include "../lib_paysages/shared/constants.h"
|
||||
|
|
|
@ -82,7 +82,7 @@
|
|||
<value key="ProjectExplorer.ProjectConfiguration.DisplayName" type="QString"></value>
|
||||
<value key="ProjectExplorer.ProjectConfiguration.Id" type="QString">Qt4ProjectManager.Qt4BuildConfiguration</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildConfiguration" type="int">0</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/michael/coding/paysages/gui_qt</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.BuildDirectory" type="QString">/home/michael/workspace/paysages/gui_qt</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.QtVersionId" type="int">3</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.ToolChain" type="QString">ProjectExplorer.ToolChain.Gcc:/usr/bin/g++.x86-linux-generic-elf-32bit.</value>
|
||||
<value key="Qt4ProjectManager.Qt4BuildConfiguration.UseShadowBuild" type="bool">false</value>
|
||||
|
@ -133,9 +133,7 @@
|
|||
<value key="Qt4ProjectManager.Qt4RunConfiguration.ProFile" type="QString">paysages-qt.pro</value>
|
||||
<value key="Qt4ProjectManager.Qt4RunConfiguration.UseDyldImageSuffix" type="bool">false</value>
|
||||
<value key="Qt4ProjectManager.Qt4RunConfiguration.UseTerminal" type="bool">false</value>
|
||||
<valuelist key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges" type="QVariantList">
|
||||
<value type="QString">LD_LIBRARY_PATH=../lib_paysages</value>
|
||||
</valuelist>
|
||||
<valuelist key="Qt4ProjectManager.Qt4RunConfiguration.UserEnvironmentChanges" type="QVariantList"/>
|
||||
<value key="Qt4ProjectManager.Qt4RunConfiguration.UserWorkingDirectory" type="QString"></value>
|
||||
<value key="RunConfiguration.QmlDebugServerPort" type="uint">3768</value>
|
||||
<value key="RunConfiguration.UseCppDebugger" type="bool">true</value>
|
||||
|
@ -150,7 +148,7 @@
|
|||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.EnvironmentId</variable>
|
||||
<value type="QString">{8abe6662-5ded-4243-9d4d-dbf8a3c19b83}</value>
|
||||
<value type="QString">{d5145163-5b06-43da-aefd-e689d7a52ef8}</value>
|
||||
</data>
|
||||
<data>
|
||||
<variable>ProjectExplorer.Project.Updater.FileVersion</variable>
|
||||
|
|
|
@ -12,6 +12,8 @@
|
|||
#include "water.h"
|
||||
#include "clouds.h"
|
||||
#include "sky.h"
|
||||
#include "terrain.h"
|
||||
#include "textures.h"
|
||||
|
||||
static int _cpu_count = 1;
|
||||
static int _is_rendering = 0;
|
||||
|
@ -100,6 +102,7 @@ void autoSetDaytimeFraction(double daytime)
|
|||
|
||||
void autoSetRenderQuality(int quality)
|
||||
{
|
||||
TerrainQuality terrain;
|
||||
WaterQuality water;
|
||||
CloudsQuality clouds;
|
||||
|
||||
|
@ -114,7 +117,9 @@ void autoSetRenderQuality(int quality)
|
|||
|
||||
renderSetQuality(quality);
|
||||
|
||||
terrainSetChunkSize(0.1 / (double)render_quality, 0.05 / (double)render_quality);
|
||||
terrain.min_chunk_size = 0.1 / (double)render_quality;
|
||||
terrain.visible_chunk_size = 0.05 / (double)render_quality;
|
||||
terrainSetQuality(terrain);
|
||||
|
||||
water.detail_boost = 5.0;
|
||||
water.force_detail = 0.0;
|
||||
|
@ -126,14 +131,14 @@ void autoSetRenderQuality(int quality)
|
|||
|
||||
void autoGenRealisticLandscape(int seed)
|
||||
{
|
||||
Texture* tex;
|
||||
TerrainDefinition terrain;
|
||||
WaterDefinition water;
|
||||
CloudsDefinition cloud;
|
||||
SkyDefinition sky;
|
||||
TextureDefinition texture;
|
||||
int layer;
|
||||
HeightModifier* mod;
|
||||
Zone* zone;
|
||||
NoiseGenerator* noise;
|
||||
|
||||
if (!seed)
|
||||
{
|
||||
|
@ -166,7 +171,7 @@ void autoGenRealisticLandscape(int seed)
|
|||
noiseAddLevelSimple(cloud.noise, 50.0 / 800.0, 0.001);
|
||||
noiseAddLevelSimple(cloud.noise, 50.0 / 1000.0, 0.0005);
|
||||
layer = cloudsAddLayer();
|
||||
cloudsSetDefinition(layer, cloud);
|
||||
//cloudsSetDefinition(layer, cloud);
|
||||
|
||||
/* Water */
|
||||
water.height = 0.0;
|
||||
|
@ -215,14 +220,22 @@ void autoGenRealisticLandscape(int seed)
|
|||
sky.sun_radius = 0.02;
|
||||
skySetDefinition(sky);
|
||||
|
||||
noise = noiseCreateGenerator();
|
||||
noiseGenerateBaseNoise(noise, 1048576);
|
||||
noiseAddLevelsSimple(noise, 10, 10.0, 1.0);
|
||||
noiseNormalizeHeight(noise, -12.0, 12.0, 0);
|
||||
terrainSetNoiseGenerator(noise);
|
||||
noiseDeleteGenerator(noise);
|
||||
|
||||
tex = textureCreateFromFile("./data/textures/rock3.jpg");
|
||||
terrain = terrainCreateDefinition();
|
||||
noiseGenerateBaseNoise(terrain.height_noise, 1048576);
|
||||
noiseAddLevelsSimple(terrain.height_noise, 8, 10.0, 1.0);
|
||||
noiseNormalizeHeight(terrain.height_noise, -12.0, 12.0, 0);
|
||||
terrainSetDefinition(terrain);
|
||||
terrainDeleteDefinition(terrain);
|
||||
|
||||
layer = texturesAddLayer();
|
||||
texture = texturesCreateDefinition();
|
||||
noiseGenerateBaseNoise(texture.bump_noise, 102400);
|
||||
noiseAddLevelsSimple(texture.bump_noise, 6, 0.01, 0.01);
|
||||
texture.color = COLOR_WHITE;
|
||||
texturesSetDefinition(layer, texture);
|
||||
texturesDeleteDefinition(texture);
|
||||
|
||||
/*tex = textureCreateFromFile("./data/textures/rock3.jpg");
|
||||
tex->scaling_x = 0.003;
|
||||
tex->scaling_y = 0.003;
|
||||
tex->scaling_z = 0.003;
|
||||
|
@ -236,7 +249,7 @@ void autoGenRealisticLandscape(int seed)
|
|||
zone = zoneCreate(0.0);
|
||||
zoneAddHeightRange(zone, 1.0, -1.0, 0.0, 3.0, 15.0);
|
||||
zoneAddSteepnessRange(zone, 1.0, 0.0, 0.0, 0.3, 0.4);
|
||||
terrainAddTexture(tex, 0.15, zone, 0.05);
|
||||
terrainAddTexture(tex, 0.15, zone, 0.05);*/
|
||||
|
||||
/*tex = textureCreateFromFile("./data/textures/snow1.jpg");
|
||||
tex->scaling_x = 0.001;
|
||||
|
@ -247,7 +260,7 @@ void autoGenRealisticLandscape(int seed)
|
|||
terrainAddTexture(tex, 0.5, zone, 0.1);*/
|
||||
|
||||
/* DEBUG */
|
||||
mod = modifierCreate();
|
||||
/*mod = modifierCreate();
|
||||
zone = modifierGetZone(mod);
|
||||
zoneIncludeCircleArea(zone, 0.4, 0.0, 0.0, 8.0, 20.0);
|
||||
modifierActionFixValue(mod, -2.0);
|
||||
|
@ -261,7 +274,7 @@ void autoGenRealisticLandscape(int seed)
|
|||
zone = modifierGetZone(mod);
|
||||
zoneIncludeCircleArea(zone, 0.8, 0.0, 0.0, 0.3, 4.0);
|
||||
modifierActionFixValue(mod, -8.0);
|
||||
terrainAddModifier(mod);
|
||||
terrainAddModifier(mod);*/
|
||||
|
||||
fogSetDistance(20.0, 100.0);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ void cloudsLoad(FILE* f)
|
|||
{
|
||||
int i;
|
||||
CloudsDefinition* layer;
|
||||
|
||||
/* FIXME Delete unused noise generators and add missing ones */
|
||||
|
||||
_layers_count = toolsLoadInt(f);
|
||||
for (i = 0; i < _layers_count; i++)
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "shared/constants.h"
|
||||
#include "shared/functions.h"
|
||||
#include "shared/globals.h"
|
||||
#include "terrain.h"
|
||||
|
||||
void paysagesInit()
|
||||
{
|
||||
|
@ -25,4 +26,17 @@ void paysagesInit()
|
|||
autoSetRenderQuality(5);
|
||||
autoGenRealisticLandscape(0);
|
||||
autoSetDaytime(8, 30);
|
||||
|
||||
// DEBUG
|
||||
double last_height, height, x;
|
||||
last_height = height = 0.0;
|
||||
x = 0.0;
|
||||
while (height <= 1.0 || height >= last_height || last_height < 0.1)
|
||||
{
|
||||
last_height = height;
|
||||
height = terrainGetHeight(x, 0.0);
|
||||
x += 0.1;
|
||||
}
|
||||
cameraSetLocation(x - 2.0, height, 0.0);
|
||||
cameraSetTarget(x - 1.0, height, 0.0);
|
||||
}
|
||||
|
|
|
@ -172,28 +172,6 @@ Color skyProjectRay(Vector3 start, Vector3 direction);
|
|||
void skySetGradation(ColorGradation grad);
|
||||
void skyRender(RenderProgressCallback callback);
|
||||
|
||||
/* terrain.c */
|
||||
void terrainSave(FILE* f);
|
||||
void terrainLoad(FILE* f);
|
||||
void terrainInit();
|
||||
NoiseGenerator* terrainGetNoiseGenerator();
|
||||
void terrainSetNoiseGenerator(NoiseGenerator* generator);
|
||||
void terrainAddTexture(Texture* tex, double subsurf_scale, Zone* zone, double border_scaling);
|
||||
void terrainAddModifier(HeightModifier* modifier);
|
||||
double terrainGetHeight(double x, double z);
|
||||
double terrainGetHeightNormalized(double x, double z);
|
||||
Color terrainGetColor(double x, double z, double precision);
|
||||
double terrainGetShadow(Vector3 start, Vector3 direction);
|
||||
int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
|
||||
void terrainSetChunkSize(double min_size, double visible_size);
|
||||
void terrainRender(RenderProgressCallback callback);
|
||||
|
||||
/* textures.c */
|
||||
void texturesSave(FILE* f);
|
||||
void texturesLoad(FILE* f);
|
||||
Texture* textureCreateFromFile(const char* filename);
|
||||
Color textureApply(Texture* tex, Vector3 location, Vector3 normal);
|
||||
|
||||
/* tools.c */
|
||||
double toolsRandom();
|
||||
double toolsBicubicInterpolate(double stencil[16], double x, double y);
|
||||
|
@ -209,6 +187,7 @@ Zone* zoneCreate();
|
|||
void zoneDelete(Zone* zone);
|
||||
void zoneSave(Zone* zone, FILE* f);
|
||||
void zoneLoad(Zone* zone, FILE* f);
|
||||
void zoneCopy(Zone* source, Zone* destination);
|
||||
void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double centerz, double softradius, double hardradius);
|
||||
void zoneExcludeCircleArea(Zone* zone, double centerx, double centerz, double softradius, double hardradius);
|
||||
void zoneAddHeightRange(Zone* zone, double value, double hardmin, double softmin, double softmax, double hardmax);
|
||||
|
|
|
@ -87,16 +87,6 @@ typedef struct
|
|||
void* data;
|
||||
} Array;
|
||||
|
||||
typedef struct {
|
||||
void* pixels;
|
||||
int bytes_per_pixel;
|
||||
int picture_width;
|
||||
int picture_height;
|
||||
double scaling_x;
|
||||
double scaling_y;
|
||||
double scaling_z;
|
||||
} Texture;
|
||||
|
||||
struct NoiseLevel
|
||||
{
|
||||
double scaling;
|
||||
|
|
|
@ -6,118 +6,103 @@
|
|||
#include "shared/globals.h"
|
||||
#include "shared/constants.h"
|
||||
|
||||
#include "textures.h"
|
||||
#include "water.h"
|
||||
#include "terrain.h"
|
||||
|
||||
#define MAX_TEXTURES 10
|
||||
#define MAX_MODIFIERS 50
|
||||
|
||||
typedef struct {
|
||||
Texture* tex;
|
||||
double subsurf_scale;
|
||||
Zone* zone;
|
||||
double border_scaling;
|
||||
} TerrainTexture;
|
||||
|
||||
static NoiseGenerator* _noise_height;
|
||||
static NoiseGenerator* _noise_texture_borders;
|
||||
static TerrainDefinition _definition;
|
||||
static TerrainQuality _quality;
|
||||
static TerrainEnvironment _environment;
|
||||
static double _max_height = 1.0;
|
||||
static double _base_chunk_size = 1.0, _visible_chunk_size = 1.0;
|
||||
static int _texture_count = 0;
|
||||
static TerrainTexture _textures[MAX_TEXTURES];
|
||||
|
||||
static int _modifiers_count = 0;
|
||||
static HeightModifier* _modifiers[MAX_MODIFIERS];
|
||||
|
||||
void terrainInit()
|
||||
{
|
||||
_definition = terrainCreateDefinition();
|
||||
_max_height = noiseGetMaxValue(_definition.height_noise);
|
||||
}
|
||||
|
||||
void terrainSave(FILE* f)
|
||||
{
|
||||
noiseSave(_noise_height, f);
|
||||
noiseSave(_noise_texture_borders, f);
|
||||
noiseSave(_definition.height_noise, f);
|
||||
|
||||
toolsSaveDouble(f, _max_height);
|
||||
toolsSaveDouble(f, _base_chunk_size);
|
||||
toolsSaveDouble(f, _visible_chunk_size);
|
||||
|
||||
/* TODO Textures */
|
||||
/* TODO Modifiers */
|
||||
}
|
||||
|
||||
void terrainLoad(FILE* f)
|
||||
{
|
||||
noiseLoad(_noise_height, f);
|
||||
noiseLoad(_noise_texture_borders, f);
|
||||
|
||||
_max_height = toolsLoadDouble(f);
|
||||
_base_chunk_size = toolsLoadDouble(f);
|
||||
_visible_chunk_size = toolsLoadDouble(f);
|
||||
noiseLoad(_definition.height_noise, f);
|
||||
_max_height = noiseGetMaxValue(_definition.height_noise);
|
||||
}
|
||||
|
||||
void terrainInit()
|
||||
TerrainDefinition terrainCreateDefinition()
|
||||
{
|
||||
_noise_height = noiseCreateGenerator();
|
||||
_max_height = noiseGetMaxValue(_noise_height);
|
||||
|
||||
_noise_texture_borders = noiseCreateGenerator();
|
||||
noiseGenerateBaseNoise(_noise_texture_borders, 100);
|
||||
noiseAddLevelsSimple(_noise_texture_borders, 10, 1.0, 1.0);
|
||||
noiseNormalizeHeight(_noise_texture_borders, 0.0, 1.0, 0);
|
||||
TerrainDefinition definition;
|
||||
|
||||
definition.height_noise = noiseCreateGenerator();
|
||||
|
||||
return definition;
|
||||
}
|
||||
|
||||
NoiseGenerator* terrainGetNoiseGenerator()
|
||||
void terrainDeleteDefinition(TerrainDefinition definition)
|
||||
{
|
||||
return _noise_height;
|
||||
noiseDeleteGenerator(definition.height_noise);
|
||||
}
|
||||
|
||||
void terrainSetNoiseGenerator(NoiseGenerator* generator)
|
||||
void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination)
|
||||
{
|
||||
noiseCopy(generator, _noise_height);
|
||||
_max_height = noiseGetMaxValue(_noise_height);
|
||||
/* FIXME Max height depends on modifiers*/
|
||||
noiseCopy(source.height_noise, destination->height_noise);
|
||||
}
|
||||
|
||||
void terrainAddTexture(Texture* tex, double subsurf_scale, Zone* zone, double border_scaling)
|
||||
void terrainSetDefinition(TerrainDefinition definition)
|
||||
{
|
||||
TerrainTexture ttex;
|
||||
if (_texture_count < MAX_TEXTURES)
|
||||
{
|
||||
ttex.tex = tex;
|
||||
ttex.subsurf_scale = subsurf_scale;
|
||||
ttex.zone = zone;
|
||||
ttex.border_scaling = border_scaling;
|
||||
|
||||
_textures[_texture_count++] = ttex;
|
||||
}
|
||||
terrainCopyDefinition(definition, &_definition);
|
||||
_max_height = noiseGetMaxValue(_definition.height_noise);
|
||||
/* FIXME _max_height depends on modifiers */
|
||||
}
|
||||
|
||||
void terrainAddModifier(HeightModifier* modifier)
|
||||
TerrainDefinition terrainGetDefinition()
|
||||
{
|
||||
if (_modifiers_count < MAX_MODIFIERS)
|
||||
{
|
||||
_modifiers[_modifiers_count++] = modifier;
|
||||
}
|
||||
return _definition;
|
||||
}
|
||||
|
||||
static inline double _getHeight(double x, double z, double precision)
|
||||
void terrainSetQuality(TerrainQuality quality)
|
||||
{
|
||||
_quality = quality;
|
||||
}
|
||||
|
||||
TerrainQuality terrainGetQuality()
|
||||
{
|
||||
return _quality;
|
||||
}
|
||||
|
||||
static inline double _getHeight(TerrainDefinition* definition, double x, double z, double detail)
|
||||
{
|
||||
Vector3 location;
|
||||
int i;
|
||||
/*int i;*/
|
||||
|
||||
location.x = x;
|
||||
location.y = noiseGet2DDetail(_noise_height, x, z, precision);
|
||||
location.y = noiseGet2DDetail(definition->height_noise, x, z, detail);
|
||||
location.z = z;
|
||||
|
||||
for (i = 0; i < _modifiers_count; i++)
|
||||
/*for (i = 0; i < _modifiers_count; i++)
|
||||
{
|
||||
location = modifierApply(_modifiers[i], location);
|
||||
}
|
||||
}*/
|
||||
|
||||
return location.y;
|
||||
}
|
||||
|
||||
static inline Vector3 _getPoint(double x, double z, double precision)
|
||||
static inline Vector3 _getPoint(TerrainDefinition* definition, double x, double z, double detail)
|
||||
{
|
||||
Vector3 result;
|
||||
|
||||
result.x = x;
|
||||
result.y = _getHeight(x, z, precision);
|
||||
result.y = _getHeight(definition, x, z, detail);
|
||||
result.z = z;
|
||||
|
||||
return result;
|
||||
|
@ -143,7 +128,7 @@ double terrainGetShadow(Vector3 start, Vector3 direction)
|
|||
inc_vector = v3Scale(direction, inc_value);
|
||||
length += v3Norm(inc_vector);
|
||||
start = v3Add(start, inc_vector);
|
||||
height = _getHeight(start.x, start.z, inc_value);
|
||||
height = _getHeight(&_definition, start.x, start.z, inc_value);
|
||||
diff = start.y - height;
|
||||
if (diff < 0.0)
|
||||
{
|
||||
|
@ -175,78 +160,12 @@ double terrainGetShadow(Vector3 start, Vector3 direction)
|
|||
}
|
||||
}
|
||||
|
||||
static inline Vector3 _getNormal(Vector3 point, double scale)
|
||||
static Color _getColor(TerrainDefinition* definition, Vector3 point, double precision)
|
||||
{
|
||||
Vector3 dpoint, ref, normal;
|
||||
|
||||
ref.x = 0.0;
|
||||
ref.y = 0.0;
|
||||
|
||||
dpoint = _getPoint(point.x - scale, point.z, scale * 0.3);
|
||||
ref.z = -1.0;
|
||||
normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point)));
|
||||
|
||||
dpoint = _getPoint(point.x + scale, point.z, scale * 0.3);
|
||||
ref.z = 1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
ref.z = 0.0;
|
||||
|
||||
dpoint = _getPoint(point.x, point.z - scale, scale * 0.3);
|
||||
ref.x = 1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
dpoint = _getPoint(point.x, point.z + scale, scale * 0.3);
|
||||
ref.x = -1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
return v3Normalize(normal);
|
||||
}
|
||||
|
||||
static Color _getColor(Vector3 point, double precision)
|
||||
{
|
||||
Vector3 normal;
|
||||
Color color, tex_color;
|
||||
int i;
|
||||
double shadowed, coverage, value;
|
||||
|
||||
shadowed = terrainGetShadow(point, sun_direction_inv);
|
||||
|
||||
/* Apply textures and subsurface lighting */
|
||||
color = COLOR_GREEN;
|
||||
for (i = 0; i < _texture_count; i++)
|
||||
{
|
||||
/* TODO Don't recalculate normals for same precision */
|
||||
/* TODO Don't compute textures that will be totally covered */
|
||||
normal = _getNormal(point, precision * _textures[i].subsurf_scale);
|
||||
|
||||
coverage = zoneGetValue(_textures[i].zone, point, normal);
|
||||
if (coverage > 0.0)
|
||||
{
|
||||
if (coverage < 1.0)
|
||||
{
|
||||
value = noiseGet2DTotal(_noise_texture_borders, point.x / _textures[i].border_scaling, point.z / _textures[i].border_scaling);
|
||||
if (value < coverage)
|
||||
{
|
||||
/* TODO Make smoothness precision-dependant */
|
||||
value = (coverage - value) / 0.1;
|
||||
coverage = (value > 1.0) ? 1.0 : value;
|
||||
}
|
||||
else
|
||||
{
|
||||
coverage = 0.0;
|
||||
}
|
||||
}
|
||||
if (coverage > 0.0)
|
||||
{
|
||||
tex_color = textureApply(_textures[i].tex, point, normal);
|
||||
tex_color = lightingApply(point, normal, shadowed, tex_color, 0.1, 0.1);
|
||||
tex_color.a = coverage;
|
||||
colorMask(&color, &tex_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
Color color;
|
||||
|
||||
/* FIXME Environment for textures should be customized */
|
||||
color = texturesGetColor(point);
|
||||
color = fogApplyToLocation(point, color);
|
||||
//color = cloudsApplySegmentResult(color, camera_location, point);
|
||||
|
||||
|
@ -269,13 +188,13 @@ int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Colo
|
|||
inc_vector = v3Scale(direction, inc_value);
|
||||
length += v3Norm(inc_vector);
|
||||
start = v3Add(start, inc_vector);
|
||||
height = _getHeight(start.x, start.z, inc_value);
|
||||
height = _getHeight(&_definition, start.x, start.z, inc_value);
|
||||
diff = start.y - height;
|
||||
if (diff < 0.0)
|
||||
{
|
||||
start.y = height;
|
||||
*hit_point = start;
|
||||
*hit_color = _getColor(start, inc_value);
|
||||
*hit_color = _getColor(&_definition, start, inc_value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -304,19 +223,19 @@ static int _postProcessFragment(RenderFragment* fragment)
|
|||
point = fragment->vertex.location;
|
||||
precision = renderGetPrecision(point);
|
||||
|
||||
point = _getPoint(point.x, point.z, precision);
|
||||
point = _getPoint(&_definition, point.x, point.z, precision);
|
||||
|
||||
fragment->vertex.color = _getColor(point, precision);
|
||||
fragment->vertex.color = _getColor(&_definition, point, precision);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static Vertex _getFirstPassVertex(double x, double z, double precision)
|
||||
static Vertex _getFirstPassVertex(double x, double z, double detail)
|
||||
{
|
||||
Vertex result;
|
||||
double value;
|
||||
|
||||
result.location = _getPoint(x, z, 0.0);
|
||||
result.location = _getPoint(&_definition, x, z, 0.0);
|
||||
value = sin(x) * sin(x) * cos(z) * cos(z);
|
||||
result.color.r = value;
|
||||
result.color.g = value;
|
||||
|
@ -341,23 +260,22 @@ static void _renderQuad(double x, double z, double size)
|
|||
|
||||
double terrainGetHeight(double x, double z)
|
||||
{
|
||||
return _getHeight(x, z, 0.01 / (double)render_quality);
|
||||
return _getHeight(&_definition, x, z, 0.01 / (double)render_quality);
|
||||
}
|
||||
|
||||
double terrainGetHeightNormalized(double x, double z)
|
||||
{
|
||||
return 0.5 + _getHeight(x, z, 0.01 / (double)render_quality) / (_max_height * 2.0);
|
||||
return 0.5 + _getHeight(&_definition, x, z, 0.01 / (double)render_quality) / (_max_height * 2.0);
|
||||
}
|
||||
|
||||
Color terrainGetColor(double x, double z, double precision)
|
||||
Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment)
|
||||
{
|
||||
return _getColor(_getPoint(x, z, precision), precision);
|
||||
return _getColor(definition, _getPoint(definition, x, z, detail), detail);
|
||||
}
|
||||
|
||||
void terrainSetChunkSize(double min_size, double visible_size)
|
||||
Color terrainGetColor(double x, double z, double detail)
|
||||
{
|
||||
_base_chunk_size = min_size;
|
||||
_visible_chunk_size = visible_size;
|
||||
return terrainGetColorCustom(x, z, detail, &_definition, &_quality, &_environment);
|
||||
}
|
||||
|
||||
void terrainRender(RenderProgressCallback callback)
|
||||
|
@ -370,8 +288,8 @@ void terrainRender(RenderProgressCallback callback)
|
|||
chunk_factor = 1;
|
||||
chunk_count = 2;
|
||||
radius_int = 0.0;
|
||||
radius_ext = _base_chunk_size;
|
||||
chunk_size = _base_chunk_size;
|
||||
radius_ext = _quality.min_chunk_size;
|
||||
chunk_size = _quality.min_chunk_size;
|
||||
|
||||
while (radius_ext < 1000.0)
|
||||
{
|
||||
|
@ -388,14 +306,14 @@ void terrainRender(RenderProgressCallback callback)
|
|||
_renderQuad(cx - radius_ext, cz + radius_int - chunk_size * i, chunk_size);
|
||||
}
|
||||
|
||||
if (chunk_count % 64 == 0 && chunk_size / radius_int < _visible_chunk_size)
|
||||
if (chunk_count % 64 == 0 && chunk_size / radius_int < _quality.visible_chunk_size)
|
||||
{
|
||||
chunk_count /= 2;
|
||||
chunk_factor *= 2;
|
||||
/* TODO Fill in gaps with triangles */
|
||||
}
|
||||
chunk_count += 2;
|
||||
chunk_size = _base_chunk_size * chunk_factor;
|
||||
chunk_size = _quality.min_chunk_size * chunk_factor;
|
||||
radius_int = radius_ext;
|
||||
radius_ext += chunk_size;
|
||||
}
|
||||
|
|
54
lib_paysages/terrain.h
Normal file
|
@ -0,0 +1,54 @@
|
|||
#ifndef _PAYSAGES_TERRAIN_H_
|
||||
#define _PAYSAGES_TERRAIN_H_
|
||||
|
||||
#include "shared/types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
NoiseGenerator* height_noise;
|
||||
} TerrainDefinition;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
double min_chunk_size;
|
||||
double visible_chunk_size;
|
||||
} TerrainQuality;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int unused;
|
||||
} TerrainEnvironment;
|
||||
|
||||
void terrainInit();
|
||||
void terrainSave(FILE* f);
|
||||
void terrainLoad(FILE* f);
|
||||
|
||||
TerrainDefinition terrainCreateDefinition();
|
||||
void terrainDeleteDefinition(TerrainDefinition definition);
|
||||
void terrainCopyDefinition(TerrainDefinition source, TerrainDefinition* destination);
|
||||
void terrainSetDefinition(TerrainDefinition definition);
|
||||
TerrainDefinition terrainGetDefinition();
|
||||
|
||||
void terrainSetQuality(TerrainQuality quality);
|
||||
TerrainQuality terrainGetQuality();
|
||||
|
||||
double terrainGetShadow(Vector3 start, Vector3 direction);
|
||||
int terrainProjectRay(Vector3 start, Vector3 direction, Vector3* hit_point, Color* hit_color);
|
||||
double terrainGetHeightCustom(double x, double z, TerrainDefinition* definition);
|
||||
double terrainGetHeight(double x, double z);
|
||||
double terrainGetHeightNormalizedCustom(double x, double z, TerrainDefinition* definition);
|
||||
double terrainGetHeightNormalized(double x, double z);
|
||||
Color terrainGetColorCustom(double x, double z, double detail, TerrainDefinition* definition, TerrainQuality* quality, TerrainEnvironment* environment);
|
||||
Color terrainGetColor(double x, double z, double detail);
|
||||
void terrainRender(RenderProgressCallback callback);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -1,137 +1,201 @@
|
|||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "shared/types.h"
|
||||
#include "shared/functions.h"
|
||||
#include "shared/constants.h"
|
||||
#include "shared/globals.h"
|
||||
|
||||
#include "IL/il.h"
|
||||
#include "IL/ilu.h"
|
||||
#include "textures.h"
|
||||
#include "terrain.h"
|
||||
|
||||
#define TEXTURES_MAX 50
|
||||
static TextureQuality _quality;
|
||||
static TextureEnvironment _environment;
|
||||
static int _textures_count = 0;
|
||||
static Texture _textures[TEXTURES_MAX];
|
||||
static TextureDefinition _textures[TEXTURES_MAX];
|
||||
|
||||
void texturesInit()
|
||||
{
|
||||
_textures_count = 0;
|
||||
}
|
||||
|
||||
void texturesSave(FILE* f)
|
||||
{
|
||||
int i;
|
||||
|
||||
toolsSaveInt(f, _textures_count);
|
||||
for (i = 0; i < _textures_count; i++)
|
||||
{
|
||||
zoneSave(_textures[i].zone, f);
|
||||
noiseSave(_textures[i].bump_noise, f);
|
||||
colorSave(_textures[i].color, f);
|
||||
}
|
||||
}
|
||||
|
||||
void texturesLoad(FILE* f)
|
||||
{
|
||||
// TODO
|
||||
}
|
||||
|
||||
Texture* textureCreateFromFile(const char* filename)
|
||||
int texturesGetLayerCount()
|
||||
{
|
||||
Texture* result;
|
||||
ILuint imageid;
|
||||
return _textures_count;
|
||||
}
|
||||
|
||||
if (_textures_count >= TEXTURES_MAX)
|
||||
int texturesAddLayer()
|
||||
{
|
||||
if (_textures_count < TEXTURES_MAX)
|
||||
{
|
||||
return _textures + (TEXTURES_MAX - 1);
|
||||
_textures[_textures_count] = texturesCreateDefinition();
|
||||
|
||||
return _textures_count++;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = _textures + _textures_count;
|
||||
_textures_count++;
|
||||
|
||||
ilGenImages(1, &imageid);
|
||||
ilBindImage(imageid);
|
||||
ilLoadImage(filename);
|
||||
|
||||
result->bytes_per_pixel = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
|
||||
result->picture_width = ilGetInteger(IL_IMAGE_WIDTH);
|
||||
result->picture_height = ilGetInteger(IL_IMAGE_HEIGHT);
|
||||
result->pixels = malloc(result->bytes_per_pixel * result->picture_width * result->picture_height);
|
||||
memcpy(result->pixels, ilGetData(), result->bytes_per_pixel * result->picture_width * result->picture_height);
|
||||
result->scaling_x = 1.0;
|
||||
result->scaling_y = 1.0;
|
||||
result->scaling_z = 1.0;
|
||||
|
||||
ilDeleteImages(1, &imageid);
|
||||
|
||||
return result;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static inline Color _getRawValue(Texture* tex, int x, int y)
|
||||
void texturesDeleteLayer(int layer)
|
||||
{
|
||||
Color result;
|
||||
void* texdata;
|
||||
// TODO
|
||||
}
|
||||
|
||||
x = x % tex->picture_width;
|
||||
if (x < 0)
|
||||
{
|
||||
x += tex->picture_width;
|
||||
}
|
||||
y = y % tex->picture_height;
|
||||
if (y < 0)
|
||||
{
|
||||
y += tex->picture_height;
|
||||
}
|
||||
TextureDefinition texturesCreateDefinition()
|
||||
{
|
||||
TextureDefinition result;
|
||||
|
||||
texdata = tex->pixels + (y * tex->picture_width + x) * tex->bytes_per_pixel;
|
||||
|
||||
result.r = ((double)(unsigned int)*((unsigned char*)texdata)) / 255.0;
|
||||
result.g = ((double)(unsigned int)*((unsigned char*)(texdata + 1))) / 255.0;
|
||||
result.b = ((double)(unsigned int)*((unsigned char*)(texdata + 2))) / 255.0;
|
||||
result.zone = zoneCreate();
|
||||
result.bump_noise = noiseCreateGenerator();
|
||||
result.color = COLOR_GREEN;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline Color _getInterpolatedValue(Texture* tex, double fx, double fy)
|
||||
void texturesDeleteDefinition(TextureDefinition definition)
|
||||
{
|
||||
zoneDelete(definition.zone);
|
||||
noiseDeleteGenerator(definition.bump_noise);
|
||||
}
|
||||
|
||||
void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination)
|
||||
{
|
||||
destination->color = source.color;
|
||||
noiseCopy(source.bump_noise, destination->bump_noise);
|
||||
zoneCopy(source.zone, destination->zone);
|
||||
}
|
||||
|
||||
void texturesSetDefinition(int layer, TextureDefinition definition)
|
||||
{
|
||||
TextureDefinition* destination;
|
||||
|
||||
if (layer >= 0 && layer < _textures_count)
|
||||
{
|
||||
destination = _textures + layer;
|
||||
texturesCopyDefinition(definition, destination);
|
||||
}
|
||||
}
|
||||
|
||||
TextureDefinition texturesGetDefinition(int layer)
|
||||
{
|
||||
assert(layer >= 0);
|
||||
assert(layer < _textures_count);
|
||||
|
||||
return _textures[layer];
|
||||
}
|
||||
|
||||
void texturesSetQuality(TextureQuality quality)
|
||||
{
|
||||
_quality = quality;
|
||||
}
|
||||
|
||||
TextureQuality texturesGetQuality()
|
||||
{
|
||||
return _quality;
|
||||
}
|
||||
|
||||
static inline Vector3 _getNormal(TextureDefinition* definition, Vector3 point, double scale)
|
||||
{
|
||||
Vector3 dpoint, ref, normal;
|
||||
|
||||
ref.x = 0.0;
|
||||
ref.y = 0.0;
|
||||
|
||||
dpoint.x = point.x - scale;
|
||||
dpoint.z = point.z;
|
||||
dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z);
|
||||
ref.z = -1.0;
|
||||
normal = v3Normalize(v3Cross(ref, v3Sub(dpoint, point)));
|
||||
|
||||
dpoint.x = point.x + scale;
|
||||
dpoint.z = point.z;
|
||||
dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z);
|
||||
ref.z = 1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
ref.z = 0.0;
|
||||
|
||||
dpoint.x = point.x;
|
||||
dpoint.z = point.z - scale;
|
||||
dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z);
|
||||
ref.x = 1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
dpoint.x = point.x;
|
||||
dpoint.z = point.z + scale;
|
||||
dpoint.y = terrainGetHeight(dpoint.x, dpoint.z) + noiseGet2DTotal(definition->bump_noise, dpoint.x, dpoint.z);
|
||||
ref.x = -1.0;
|
||||
normal = v3Add(normal, v3Normalize(v3Cross(ref, v3Sub(dpoint, point))));
|
||||
|
||||
return v3Normalize(normal);
|
||||
}
|
||||
|
||||
Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment)
|
||||
{
|
||||
Color result;
|
||||
double r[16];
|
||||
double g[16];
|
||||
double b[16];
|
||||
int ix, iy;
|
||||
int sx, sy;
|
||||
Vector3 normal;
|
||||
double coverage;
|
||||
|
||||
result.a = 0.0;
|
||||
normal = _getNormal(definition, location, detail * 0.3);
|
||||
|
||||
ix = (int)floor(fx);
|
||||
iy = (int)floor(fy);
|
||||
fx -= (double)ix;
|
||||
fy -= (double)iy;
|
||||
|
||||
for (sy = 0; sy < 4; sy++)
|
||||
coverage = zoneGetValue(definition->zone, location, normal);
|
||||
if (coverage > 0.0)
|
||||
{
|
||||
for (sx = 0; sx < 4; sx++)
|
||||
result = lightingApply(location, normal, shadowing, definition->color, 0.1, 0.1);
|
||||
result.a = coverage;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment)
|
||||
{
|
||||
Color result, tex_color;
|
||||
int i;
|
||||
|
||||
result = COLOR_GREEN;
|
||||
for (i = 0; i < _textures_count; i++)
|
||||
{
|
||||
/* TODO Do not compute layers fully covered */
|
||||
tex_color = texturesGetLayerColorCustom(location, shadowing, detail, _textures + i, quality, environment);
|
||||
if (tex_color.a > 0.0001)
|
||||
{
|
||||
result = _getRawValue(tex, ix + sx - 1, iy + sy - 1);
|
||||
r[sy * 4 + sx] = result.r;
|
||||
g[sy * 4 + sx] = result.g;
|
||||
b[sy * 4 + sx] = result.b;
|
||||
colorMask(&result, &tex_color);
|
||||
}
|
||||
}
|
||||
|
||||
result.r = toolsBicubicInterpolate(r, fx, fy);
|
||||
result.g = toolsBicubicInterpolate(g, fx, fy);
|
||||
result.b = toolsBicubicInterpolate(b, fx, fy);
|
||||
result.a = 1.0;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Color textureApply(Texture* tex, Vector3 location, Vector3 normal)
|
||||
Color texturesGetColor(Vector3 location)
|
||||
{
|
||||
Color col_x, col_y, col_z, result;
|
||||
double x, y, z;
|
||||
double distance;
|
||||
|
||||
distance = v3Norm(v3Sub(camera_location, location)) / 10.0;
|
||||
|
||||
x = location.x / (tex->scaling_x * distance);
|
||||
y = location.y / (tex->scaling_y * distance);
|
||||
z = location.z / (tex->scaling_z * distance);
|
||||
|
||||
col_x = _getInterpolatedValue(tex, y, z);
|
||||
col_y = _getInterpolatedValue(tex, x, z);
|
||||
col_z = _getInterpolatedValue(tex, x, y);
|
||||
|
||||
result.r = (col_x.r + col_y.r + col_z.r) / 3.0;
|
||||
result.g = (col_x.g + col_y.g + col_z.g) / 3.0;
|
||||
result.b = (col_x.b + col_y.b + col_z.b) / 3.0;
|
||||
result.a = (col_x.a + col_y.a + col_z.a) / 3.0;
|
||||
return result;
|
||||
double shadowing;
|
||||
|
||||
/* TODO Use environment to get lights to apply */
|
||||
shadowing = terrainGetShadow(location, sun_direction_inv);
|
||||
|
||||
return texturesGetColorCustom(location, shadowing, renderGetPrecision(location), &_quality, &_environment);
|
||||
}
|
||||
|
||||
|
|
53
lib_paysages/textures.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
#ifndef _PAYSAGES_TEXTURES_H_
|
||||
#define _PAYSAGES_TEXTURES_H_
|
||||
|
||||
#include "shared/types.h"
|
||||
#include <stdio.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct
|
||||
{
|
||||
Zone* zone;
|
||||
NoiseGenerator* bump_noise;
|
||||
Color color;
|
||||
} TextureDefinition;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int unused;
|
||||
} TextureQuality;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
int unused;
|
||||
} TextureEnvironment;
|
||||
|
||||
void texturesInit();
|
||||
void texturesSave(FILE* f);
|
||||
void texturesLoad(FILE* f);
|
||||
|
||||
int texturesGetLayerCount();
|
||||
int texturesAddLayer();
|
||||
void texturesDeleteLayer(int layer);
|
||||
|
||||
TextureDefinition texturesCreateDefinition();
|
||||
void texturesDeleteDefinition(TextureDefinition definition);
|
||||
void texturesCopyDefinition(TextureDefinition source, TextureDefinition* destination);
|
||||
void texturesSetDefinition(int layer, TextureDefinition definition);
|
||||
TextureDefinition texturesGetDefinition(int layer);
|
||||
|
||||
void texturesSetQuality(TextureQuality quality);
|
||||
TextureQuality texturesGetQuality();
|
||||
|
||||
Color texturesGetLayerColorCustom(Vector3 location, double shadowing, double detail, TextureDefinition* definition, TextureQuality* quality, TextureEnvironment* environment);
|
||||
Color texturesGetColorCustom(Vector3 location, double shadowing, double detail, TextureQuality* quality, TextureEnvironment* environment);
|
||||
Color texturesGetColor(Vector3 location);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
|
@ -2,7 +2,9 @@
|
|||
#include "shared/functions.h"
|
||||
#include "shared/constants.h"
|
||||
#include "shared/globals.h"
|
||||
|
||||
#include "water.h"
|
||||
#include "terrain.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
|
|
@ -39,14 +39,6 @@ struct Zone {
|
|||
#include "shared/types.h"
|
||||
#include "shared/functions.h"
|
||||
|
||||
void zoneSave(Zone* zone, FILE* f)
|
||||
{
|
||||
}
|
||||
|
||||
void zoneLoad(Zone* zone, FILE* f)
|
||||
{
|
||||
}
|
||||
|
||||
Zone* zoneCreate()
|
||||
{
|
||||
Zone* result;
|
||||
|
@ -56,7 +48,7 @@ Zone* zoneCreate()
|
|||
result->steepness_ranges_count = 0;
|
||||
result->circles_included_count = 0;
|
||||
result->circles_excluded_count = 0;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -65,6 +57,101 @@ void zoneDelete(Zone* zone)
|
|||
free(zone);
|
||||
}
|
||||
|
||||
void zoneSave(Zone* zone, FILE* f)
|
||||
{
|
||||
int i;
|
||||
|
||||
toolsSaveInt(f, zone->height_ranges_count);
|
||||
for (i = 0; i < zone->height_ranges_count; i++)
|
||||
{
|
||||
toolsSaveDouble(f, zone->height_ranges[i].value);
|
||||
toolsSaveDouble(f, zone->height_ranges[i].hardmin);
|
||||
toolsSaveDouble(f, zone->height_ranges[i].softmin);
|
||||
toolsSaveDouble(f, zone->height_ranges[i].softmax);
|
||||
toolsSaveDouble(f, zone->height_ranges[i].hardmax);
|
||||
}
|
||||
|
||||
toolsSaveInt(f, zone->steepness_ranges_count);
|
||||
for (i = 0; i < zone->steepness_ranges_count; i++)
|
||||
{
|
||||
toolsSaveDouble(f, zone->steepness_ranges[i].value);
|
||||
toolsSaveDouble(f, zone->steepness_ranges[i].hardmin);
|
||||
toolsSaveDouble(f, zone->steepness_ranges[i].softmin);
|
||||
toolsSaveDouble(f, zone->steepness_ranges[i].softmax);
|
||||
toolsSaveDouble(f, zone->steepness_ranges[i].hardmax);
|
||||
}
|
||||
|
||||
toolsSaveInt(f, zone->circles_included_count);
|
||||
for (i = 0; i < zone->circles_included_count; i++)
|
||||
{
|
||||
toolsSaveDouble(f, zone->circles_included[i].value);
|
||||
toolsSaveDouble(f, zone->circles_included[i].centerx);
|
||||
toolsSaveDouble(f, zone->circles_included[i].centerz);
|
||||
toolsSaveDouble(f, zone->circles_included[i].softradius);
|
||||
toolsSaveDouble(f, zone->circles_included[i].hardradius);
|
||||
}
|
||||
|
||||
toolsSaveInt(f, zone->circles_excluded_count);
|
||||
for (i = 0; i < zone->circles_excluded_count; i++)
|
||||
{
|
||||
toolsSaveDouble(f, zone->circles_excluded[i].value);
|
||||
toolsSaveDouble(f, zone->circles_excluded[i].centerx);
|
||||
toolsSaveDouble(f, zone->circles_excluded[i].centerz);
|
||||
toolsSaveDouble(f, zone->circles_excluded[i].softradius);
|
||||
toolsSaveDouble(f, zone->circles_excluded[i].hardradius);
|
||||
}
|
||||
}
|
||||
|
||||
void zoneLoad(Zone* zone, FILE* f)
|
||||
{
|
||||
int i;
|
||||
|
||||
zone->height_ranges_count = toolsLoadInt(f);
|
||||
for (i = 0; i < zone->height_ranges_count; i++)
|
||||
{
|
||||
zone->height_ranges[i].value = toolsLoadDouble(f);
|
||||
zone->height_ranges[i].hardmin = toolsLoadDouble(f);
|
||||
zone->height_ranges[i].softmin = toolsLoadDouble(f);
|
||||
zone->height_ranges[i].softmax = toolsLoadDouble(f);
|
||||
zone->height_ranges[i].hardmax = toolsLoadDouble(f);
|
||||
}
|
||||
|
||||
zone->steepness_ranges_count = toolsLoadInt(f);
|
||||
for (i = 0; i < zone->steepness_ranges_count; i++)
|
||||
{
|
||||
zone->steepness_ranges[i].value = toolsLoadDouble(f);
|
||||
zone->steepness_ranges[i].hardmin = toolsLoadDouble(f);
|
||||
zone->steepness_ranges[i].softmin = toolsLoadDouble(f);
|
||||
zone->steepness_ranges[i].softmax = toolsLoadDouble(f);
|
||||
zone->steepness_ranges[i].hardmax = toolsLoadDouble(f);
|
||||
}
|
||||
|
||||
zone->circles_included_count = toolsLoadInt(f);
|
||||
for (i = 0; i < zone->circles_included_count; i++)
|
||||
{
|
||||
zone->circles_included[i].value = toolsLoadDouble(f);
|
||||
zone->circles_included[i].centerx = toolsLoadDouble(f);
|
||||
zone->circles_included[i].centerz = toolsLoadDouble(f);
|
||||
zone->circles_included[i].softradius = toolsLoadDouble(f);
|
||||
zone->circles_included[i].hardradius = toolsLoadDouble(f);
|
||||
}
|
||||
|
||||
zone->circles_excluded_count = toolsLoadInt(f);
|
||||
for (i = 0; i < zone->circles_excluded_count; i++)
|
||||
{
|
||||
zone->circles_excluded[i].value = toolsLoadDouble(f);
|
||||
zone->circles_excluded[i].centerx = toolsLoadDouble(f);
|
||||
zone->circles_excluded[i].centerz = toolsLoadDouble(f);
|
||||
zone->circles_excluded[i].softradius = toolsLoadDouble(f);
|
||||
zone->circles_excluded[i].hardradius = toolsLoadDouble(f);
|
||||
}
|
||||
}
|
||||
|
||||
void zoneCopy(Zone* source, Zone* destination)
|
||||
{
|
||||
*source = *destination;
|
||||
}
|
||||
|
||||
void zoneIncludeCircleArea(Zone* zone, double value, double centerx, double centerz, double softradius, double hardradius)
|
||||
{
|
||||
Circle circle = {value, centerx, centerz, softradius, hardradius};
|
||||
|
|