Ocean Sim modifier patch
by Matt Ebb, Hamed Zaghaghi This adds a new Modifier "Ocean" to simulate large-scale wave motion. Details can be found in the wiki documentation [1], the project homepage [2] and the patch tracker [3] The modifier is disabled by default for now. To enable it, the WITH_OCEANSIM (cmake) / WITH_BF_OCEANSIM (scons) flags have to be set. The code depends on fftw3, so this also has to be enabled. [1] http://wiki.blender.org/index.php/Doc:2.6/Manual/Modifiers/Simulation/Ocean [2] http://www.savetheoceansim.com [3] http://projects.blender.org/tracker/?group_id=9&atid=127&func=detail&aid=28338
This commit is contained in:
parent
b1019a56b5
commit
11c83d8432
@ -171,6 +171,7 @@ option(WITH_MOD_DECIMATE "Enable Decimate Modifier" ON)
|
||||
option(WITH_MOD_BOOLEAN "Enable Boolean Modifier" ON)
|
||||
option(WITH_MOD_CLOTH_ELTOPO "Enable Experemental cloth solver" OFF)
|
||||
mark_as_advanced(WITH_MOD_CLOTH_ELTOPO)
|
||||
option(WITH_OCEANSIM "Enable Ocean Modifier" OFF)
|
||||
|
||||
# Image format support
|
||||
option(WITH_IMAGE_OPENEXR "Enable OpenEXR Support (http://www.openexr.com)" ON)
|
||||
@ -285,6 +286,10 @@ if(WITH_CODEC_QUICKTIME AND MINGW)
|
||||
"line if youre a developer who wants to add support.")
|
||||
endif()
|
||||
|
||||
if(NOT WITH_FFTW3 AND WITH_OCEANSIM)
|
||||
message(FATAL_ERROR "WITH_OCEANSIM requires WITH_FFTW3 to be ON")
|
||||
endif()
|
||||
|
||||
# may as well build python module without a UI
|
||||
if(WITH_PYTHON_MODULE)
|
||||
set(WITH_HEADLESS ON)
|
||||
@ -1562,6 +1567,7 @@ if(FIRST_RUN)
|
||||
info_cfg_option(WITH_MOD_BOOLEAN)
|
||||
info_cfg_option(WITH_MOD_DECIMATE)
|
||||
info_cfg_option(WITH_MOD_FLUID)
|
||||
info_cfg_option(WITH_OCEANSIM)
|
||||
|
||||
info_cfg_text("")
|
||||
|
||||
|
@ -254,6 +254,7 @@ if 'blenderlite' in B.targets:
|
||||
target_env_defs['WITH_BF_BINRELOC'] = False
|
||||
target_env_defs['BF_BUILDINFO'] = False
|
||||
target_env_defs['WITH_BF_FLUID'] = False
|
||||
target_env_defs['WITH_BF_OCEANSIM'] = False
|
||||
target_env_defs['WITH_BF_DECIMATE'] = False
|
||||
target_env_defs['WITH_BF_BOOLEAN'] = False
|
||||
target_env_defs['WITH_BF_PYTHON'] = False
|
||||
@ -329,6 +330,10 @@ if 'blendernogame' in B.targets:
|
||||
if env['WITH_BF_FLUID'] == 1:
|
||||
env['CPPFLAGS'].append('-DWITH_MOD_FLUID')
|
||||
|
||||
# build with ocean sim?
|
||||
if env['WITH_BF_OCEANSIM'] == 1:
|
||||
env['CPPFLAGS'].append('-DWITH_MOD_OCEANSIM')
|
||||
|
||||
|
||||
if btools.ENDIAN == "big":
|
||||
env['CPPFLAGS'].append('-D__BIG_ENDIAN__')
|
||||
|
@ -152,6 +152,7 @@ def validate_arguments(args, bc):
|
||||
'WITH_BF_FLUID',
|
||||
'WITH_BF_DECIMATE',
|
||||
'WITH_BF_BOOLEAN',
|
||||
'WITH_BF_OCEANSIM',
|
||||
'WITH_BF_CXX_GUARDEDALLOC',
|
||||
'WITH_BF_JEMALLOC', 'WITH_BF_STATICJEMALLOC', 'BF_JEMALLOC', 'BF_JEMALLOC_INC', 'BF_JEMALLOC_LIBPATH', 'BF_JEMALLOC_LIB', 'BF_JEMALLOC_LIB_STATIC',
|
||||
'BUILDBOT_BRANCH',
|
||||
@ -259,6 +260,7 @@ def read_opts(env, cfg, args):
|
||||
(BoolVariable('WITH_BF_FLUID', 'Build with Fluid simulation (Elbeem)', True)),
|
||||
(BoolVariable('WITH_BF_DECIMATE', 'Build with decimate modifier', True)),
|
||||
(BoolVariable('WITH_BF_BOOLEAN', 'Build with boolean modifier', True)),
|
||||
(BoolVariable('WITH_BF_OCEANSIM', 'Build with ocean simulation', False)),
|
||||
('BF_PROFILE_FLAGS', 'Profiling compiler flags', ''),
|
||||
(BoolVariable('WITH_BF_OPENAL', 'Use OpenAL if true', False)),
|
||||
('BF_OPENAL', 'Base path for OpenAL', ''),
|
||||
|
@ -414,6 +414,74 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
|
||||
row.operator("object.multires_external_save", text="Save External...")
|
||||
row.label()
|
||||
|
||||
def OCEAN(self, layout, ob, md):
|
||||
col = layout.column()
|
||||
|
||||
if not md.build_enabled:
|
||||
col.label("Built without OceanSim modifier")
|
||||
return
|
||||
|
||||
col.prop(md, "geometry_mode")
|
||||
|
||||
if md.geometry_mode == 'GENERATE':
|
||||
row = col.row()
|
||||
row.prop(md, "repeat_x")
|
||||
row.prop(md, "repeat_y")
|
||||
|
||||
col.separator()
|
||||
|
||||
col.prop(md, "time")
|
||||
col.prop(md, "resolution")
|
||||
colflow = col.column_flow()
|
||||
colflow.prop(md, "spatial_size")
|
||||
colflow.prop(md, "depth")
|
||||
|
||||
|
||||
col.label("Waves:")
|
||||
col.prop(md, "choppiness")
|
||||
col.prop(md, "wave_scale", text="Scale")
|
||||
|
||||
col.prop(md, "wave_alignment", text="Alignment")
|
||||
row = col.row()
|
||||
row.active = md.wave_alignment > 0
|
||||
row.prop(md, "wave_direction", text="Direction")
|
||||
row.prop(md, "damp")
|
||||
|
||||
col.prop(md, "smallest_wave")
|
||||
col.prop(md, "wind_velocity")
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
col.prop(md, "generate_normals")
|
||||
|
||||
split = col.split()
|
||||
split.column().prop(md, "generate_foam")
|
||||
|
||||
col = split.column()
|
||||
col.active = md.generate_foam
|
||||
col.prop(md, "foam_coverage", text="Coverage")
|
||||
|
||||
|
||||
col = layout.column()
|
||||
col.separator()
|
||||
|
||||
if md.is_cached:
|
||||
col.operator("object.ocean_bake", text="Free Bake").free=True
|
||||
else:
|
||||
col.operator("object.ocean_bake")
|
||||
row = col.row()
|
||||
row.enabled = not md.is_cached
|
||||
row.prop(md, "bake_start", text="Start")
|
||||
row.prop(md, "bake_end", text="End")
|
||||
col.prop(md, "cachepath")
|
||||
|
||||
#col.prop(md, "bake_foam_fade")
|
||||
|
||||
|
||||
|
||||
|
||||
def PARTICLE_INSTANCE(self, layout, ob, md):
|
||||
layout.prop(md, "object")
|
||||
layout.prop(md, "particle_system_index", text="Particle System")
|
||||
|
@ -774,6 +774,22 @@ class TEXTURE_PT_pointdensity_turbulence(TextureButtonsPanel, Panel):
|
||||
col.prop(pd, "turbulence_strength")
|
||||
|
||||
|
||||
class TEXTURE_PT_ocean(TextureTypePanel, Panel):
|
||||
bl_label = "Ocean"
|
||||
tex_type = 'OCEAN'
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
|
||||
tex = context.texture
|
||||
ot = tex.ocean
|
||||
|
||||
col = layout.column()
|
||||
col.prop(ot, "ocean_object")
|
||||
col.prop(ot, "output")
|
||||
|
||||
|
||||
class TEXTURE_PT_mapping(TextureSlotPanel, Panel):
|
||||
bl_label = "Mapping"
|
||||
COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
|
||||
|
108
source/blender/blenkernel/BKE_ocean.h
Normal file
108
source/blender/blenkernel/BKE_ocean.h
Normal file
@ -0,0 +1,108 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributors: Matt Ebb
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#ifndef BKE_OCEAN_H
|
||||
#define BKE_OCEAN_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
typedef struct OceanResult {
|
||||
float disp[3];
|
||||
float normal[3];
|
||||
float foam;
|
||||
|
||||
/* raw eigenvalues/vectors */
|
||||
float Jminus;
|
||||
float Jplus;
|
||||
float Eminus[3];
|
||||
float Eplus[3];
|
||||
} OceanResult;
|
||||
|
||||
|
||||
typedef struct OceanCache {
|
||||
struct ImBuf **ibufs_disp;
|
||||
struct ImBuf **ibufs_foam;
|
||||
struct ImBuf **ibufs_norm;
|
||||
|
||||
char *bakepath;
|
||||
|
||||
/* precalculated for time range */
|
||||
float *time;
|
||||
|
||||
/* constant for time range */
|
||||
float wave_scale;
|
||||
float chop_amount;
|
||||
float foam_coverage;
|
||||
float foam_fade;
|
||||
|
||||
int start;
|
||||
int end;
|
||||
int duration;
|
||||
int resolution_x;
|
||||
int resolution_y;
|
||||
|
||||
int baked;
|
||||
} OceanCache;
|
||||
|
||||
|
||||
#define OCEAN_NOT_CACHED 0
|
||||
#define OCEAN_CACHING 1
|
||||
#define OCEAN_CACHED 2
|
||||
|
||||
|
||||
struct Ocean *BKE_add_ocean(void);
|
||||
void BKE_free_ocean_data(struct Ocean *oc);
|
||||
void BKE_free_ocean(struct Ocean *oc);
|
||||
|
||||
void BKE_init_ocean(struct Ocean* o, int M,int N, float Lx, float Lz, float V, float l, float A, float w, float damp,
|
||||
float alignment, float depth, float time, short do_height_field, short do_chop, short do_normals, short do_jacobian, int seed);
|
||||
void BKE_simulate_ocean(struct Ocean *o, float t, float scale, float chop_amount);
|
||||
|
||||
/* sampling the ocean surface */
|
||||
float BKE_ocean_jminus_to_foam(float jminus, float coverage);
|
||||
void BKE_ocean_eval_uv(struct Ocean * oc, struct OceanResult *ocr, float u, float v);
|
||||
void BKE_ocean_eval_uv_catrom(struct Ocean * oc, struct OceanResult *ocr, float u, float v);
|
||||
void BKE_ocean_eval_xz(struct Ocean * oc, struct OceanResult *ocr, float x, float z);
|
||||
void BKE_ocean_eval_xz_catrom(struct Ocean * oc, struct OceanResult *ocr, float x, float z);
|
||||
void BKE_ocean_eval_ij(struct Ocean * oc, struct OceanResult *ocr, int i, int j);
|
||||
|
||||
|
||||
/* ocean cache handling */
|
||||
struct OceanCache *BKE_init_ocean_cache(char *bakepath, int start, int end, float wave_scale,
|
||||
float chop_amount, float foam_coverage, float foam_fade, int resolution);
|
||||
void BKE_simulate_ocean_cache(struct OceanCache *och, int frame);
|
||||
|
||||
void BKE_bake_ocean(struct Ocean *o, struct OceanCache *och, void (*update_cb)(void *, float progress, int *cancel), void *update_cb_data);
|
||||
void BKE_ocean_cache_eval_uv(struct OceanCache *och, struct OceanResult *ocr, int f, float u, float v);
|
||||
void BKE_ocean_cache_eval_ij(struct OceanCache *och, struct OceanResult *ocr, int f, int i, int j);
|
||||
|
||||
void BKE_free_ocean_cache(struct OceanCache *och);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
@ -46,6 +46,7 @@ struct Lamp;
|
||||
struct LampRen;
|
||||
struct Material;
|
||||
struct MTex;
|
||||
struct OceanTex;
|
||||
struct ParticleSettings;
|
||||
struct PluginTex;
|
||||
struct PointDensity;
|
||||
@ -125,6 +126,10 @@ void BKE_free_voxeldata(struct VoxelData *vd);
|
||||
struct VoxelData *BKE_add_voxeldata(void);
|
||||
struct VoxelData *BKE_copy_voxeldata(struct VoxelData *vd);
|
||||
|
||||
void BKE_free_oceantex(struct OceanTex *ot);
|
||||
struct OceanTex *BKE_add_oceantex(void);
|
||||
struct OceanTex *BKE_copy_oceantex(struct OceanTex *ot);
|
||||
|
||||
int BKE_texture_dependsOnTime(const struct Tex *texture);
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
@ -117,6 +117,7 @@ set(SRC
|
||||
intern/multires.c
|
||||
intern/nla.c
|
||||
intern/node.c
|
||||
intern/ocean.c
|
||||
intern/object.c
|
||||
intern/packedFile.c
|
||||
intern/paint.c
|
||||
@ -204,6 +205,7 @@ set(SRC
|
||||
BKE_multires.h
|
||||
BKE_nla.h
|
||||
BKE_node.h
|
||||
BKE_ocean.h
|
||||
BKE_object.h
|
||||
BKE_packedFile.h
|
||||
BKE_paint.h
|
||||
@ -341,6 +343,10 @@ if(WITH_MOD_SMOKE)
|
||||
add_definitions(-DWITH_SMOKE)
|
||||
endif()
|
||||
|
||||
if(WITH_OCEANSIM)
|
||||
add_definitions(-DWITH_OCEANSIM)
|
||||
endif()
|
||||
|
||||
if(WITH_JACK)
|
||||
add_definitions(-DWITH_JACK)
|
||||
endif()
|
||||
@ -378,6 +384,11 @@ if(WITH_LIBMV)
|
||||
add_definitions(-DWITH_LIBMV)
|
||||
endif()
|
||||
|
||||
if(WITH_FFTW3)
|
||||
list(APPEND INC_SYS ${FFTW3_INCLUDE_DIRS})
|
||||
add_definitions(-DFFTW3=1)
|
||||
endif()
|
||||
|
||||
## Warnings as errors, this is too strict!
|
||||
#if(MSVC)
|
||||
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} /WX")
|
||||
|
@ -82,6 +82,9 @@ if env['OURPLATFORM'] == 'darwin':
|
||||
if env['WITH_BF_FLUID']:
|
||||
defs.append('WITH_MOD_FLUID')
|
||||
|
||||
if env['WITH_BF_OCEANSIM']:
|
||||
defs.append('WITH_OCEANSIM')
|
||||
|
||||
if env['WITH_BF_LZO']:
|
||||
incs += ' #/extern/lzo/minilzo'
|
||||
defs.append('WITH_LZO')
|
||||
@ -100,6 +103,10 @@ if env['WITH_BF_LIBMV']:
|
||||
incs += ' #/extern/libmv'
|
||||
defs.append('WITH_LIBMV')
|
||||
|
||||
if env['WITH_BF_FFTW3']:
|
||||
defs.append('FFTW3=1')
|
||||
incs += ' ' + env['BF_FFTW3_INC']
|
||||
|
||||
if env['OURPLATFORM'] in ('win32-vc', 'win32-mingw', 'linuxcross', 'win64-vc'):
|
||||
incs += ' ' + env['BF_PTHREADS_INC']
|
||||
|
||||
|
1407
source/blender/blenkernel/intern/ocean.c
Normal file
1407
source/blender/blenkernel/intern/ocean.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -60,6 +60,7 @@
|
||||
#include "BKE_utildefines.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_ocean.h"
|
||||
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_image.h"
|
||||
@ -71,6 +72,7 @@
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_colortools.h"
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
/* All support for plugin textures: */
|
||||
@ -546,6 +548,7 @@ void free_texture(Tex *tex)
|
||||
if(tex->env) BKE_free_envmap(tex->env);
|
||||
if(tex->pd) BKE_free_pointdensity(tex->pd);
|
||||
if(tex->vd) BKE_free_voxeldata(tex->vd);
|
||||
if(tex->ot) BKE_free_oceantex(tex->ot);
|
||||
BKE_free_animdata((struct ID *)tex);
|
||||
|
||||
BKE_previewimg_free(&tex->preview);
|
||||
@ -628,6 +631,11 @@ void default_tex(Tex *tex)
|
||||
tex->vd->interp_type=TEX_VD_LINEAR;
|
||||
tex->vd->file_format=TEX_VD_SMOKE;
|
||||
}
|
||||
|
||||
if (tex->ot) {
|
||||
tex->ot->output = TEX_OCN_DISPLACEMENT;
|
||||
tex->ot->object = NULL;
|
||||
}
|
||||
pit = tex->plugin;
|
||||
if (pit) {
|
||||
varstr= pit->varstr;
|
||||
@ -662,6 +670,10 @@ void tex_set_type(Tex *tex, int type)
|
||||
if (tex->env == NULL)
|
||||
tex->env = BKE_add_envmap();
|
||||
break;
|
||||
case TEX_OCEAN:
|
||||
if (tex->ot == NULL)
|
||||
tex->ot = BKE_add_oceantex();
|
||||
break;
|
||||
}
|
||||
|
||||
tex->type = type;
|
||||
@ -826,6 +838,7 @@ Tex *copy_texture(Tex *tex)
|
||||
if(texn->env) texn->env= BKE_copy_envmap(texn->env);
|
||||
if(texn->pd) texn->pd= BKE_copy_pointdensity(texn->pd);
|
||||
if(texn->vd) texn->vd= MEM_dupallocN(texn->vd);
|
||||
if(texn->ot) texn->ot= BKE_copy_oceantex(texn->ot);
|
||||
if(tex->preview) texn->preview = BKE_previewimg_copy(tex->preview);
|
||||
|
||||
if(tex->nodetree) {
|
||||
@ -864,6 +877,9 @@ Tex *localize_texture(Tex *tex)
|
||||
if(texn->vd->dataset)
|
||||
texn->vd->dataset= MEM_dupallocN(texn->vd->dataset);
|
||||
}
|
||||
if(texn->ot) {
|
||||
texn->ot= BKE_copy_oceantex(tex->ot);
|
||||
}
|
||||
|
||||
texn->preview = NULL;
|
||||
|
||||
@ -1039,7 +1055,7 @@ void autotexname(Tex *tex)
|
||||
Main *bmain= G.main;
|
||||
char texstr[20][15]= {"None" , "Clouds" , "Wood", "Marble", "Magic" , "Blend",
|
||||
"Stucci", "Noise" , "Image", "Plugin", "EnvMap" , "Musgrave",
|
||||
"Voronoi", "DistNoise", "Point Density", "Voxel Data", "", "", "", ""};
|
||||
"Voronoi", "DistNoise", "Point Density", "Voxel Data", "Ocean", "", "", ""};
|
||||
Image *ima;
|
||||
char di[FILE_MAXDIR], fi[FILE_MAXFILE];
|
||||
|
||||
@ -1469,6 +1485,7 @@ void BKE_free_pointdensity(PointDensity *pd)
|
||||
MEM_freeN(pd);
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void BKE_free_voxeldatadata(struct VoxelData *vd)
|
||||
{
|
||||
@ -1513,6 +1530,31 @@ struct VoxelData *BKE_copy_voxeldata(struct VoxelData *vd)
|
||||
return vdn;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
struct OceanTex *BKE_add_oceantex(void)
|
||||
{
|
||||
OceanTex *ot;
|
||||
|
||||
ot= MEM_callocN(sizeof(struct OceanTex), "ocean texture");
|
||||
ot->output = TEX_OCN_DISPLACEMENT;
|
||||
ot->object = NULL;
|
||||
|
||||
return ot;
|
||||
}
|
||||
|
||||
struct OceanTex *BKE_copy_oceantex(struct OceanTex *ot)
|
||||
{
|
||||
OceanTex *otn= MEM_dupallocN(ot);
|
||||
|
||||
return otn;
|
||||
}
|
||||
|
||||
void BKE_free_oceantex(struct OceanTex *ot)
|
||||
{
|
||||
MEM_freeN(ot);
|
||||
}
|
||||
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
int BKE_texture_dependsOnTime(const struct Tex *texture)
|
||||
|
@ -120,6 +120,7 @@
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_node.h" // for tree type defines
|
||||
#include "BKE_ocean.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_paint.h"
|
||||
#include "BKE_particle.h"
|
||||
@ -3101,6 +3102,8 @@ static void lib_link_texture(FileData *fd, Main *main)
|
||||
if(tex->pd)
|
||||
tex->pd->object= newlibadr(fd, tex->id.lib, tex->pd->object);
|
||||
if(tex->vd) tex->vd->object= newlibadr(fd, tex->id.lib, tex->vd->object);
|
||||
if(tex->ot) tex->ot->object= newlibadr(fd, tex->id.lib, tex->ot->object);
|
||||
|
||||
|
||||
if(tex->nodetree)
|
||||
lib_link_ntree(fd, &tex->id, tex->nodetree);
|
||||
@ -3152,6 +3155,8 @@ static void direct_link_texture(FileData *fd, Tex *tex)
|
||||
tex->vd= MEM_callocN(sizeof(VoxelData), "direct_link_texture VoxelData");
|
||||
}
|
||||
|
||||
tex->ot= newdataadr(fd, tex->ot);
|
||||
|
||||
tex->nodetree= newdataadr(fd, tex->nodetree);
|
||||
if(tex->nodetree)
|
||||
direct_link_nodetree(fd, tex->nodetree);
|
||||
@ -4368,6 +4373,12 @@ static void direct_link_modifiers(FileData *fd, ListBase *lb)
|
||||
SWITCH_INT(mmd->bindcos[a])
|
||||
}
|
||||
}
|
||||
else if (md->type==eModifierType_Ocean) {
|
||||
OceanModifierData *omd = (OceanModifierData*) md;
|
||||
omd->oceancache = NULL;
|
||||
omd->ocean = NULL;
|
||||
omd->refresh = (MOD_OCEAN_REFRESH_ADD|MOD_OCEAN_REFRESH_RESET|MOD_OCEAN_REFRESH_SIM);
|
||||
}
|
||||
else if (md->type==eModifierType_Warp) {
|
||||
WarpModifierData *tmd = (WarpModifierData *) md;
|
||||
|
||||
@ -11846,6 +11857,27 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* put compatibility code here until next subversion bump */
|
||||
if (main->versionfile < 255 || (main->versionfile == 255 && main->subversionfile < 3)) {
|
||||
Object *ob;
|
||||
Tex *tex;
|
||||
|
||||
|
||||
/* ocean res is now squared, reset old ones - will be massive */
|
||||
for(ob = main->object.first; ob; ob = ob->id.next) {
|
||||
ModifierData *md;
|
||||
for(md= ob->modifiers.first; md; md= md->next) {
|
||||
if (md->type == eModifierType_Ocean) {
|
||||
OceanModifierData *omd = (OceanModifierData *)md;
|
||||
omd->resolution = 7;
|
||||
omd->oceancache = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* put compatibility code here until next subversion bump */
|
||||
|
||||
if (main->versionfile < 256) {
|
||||
bScreen *sc;
|
||||
|
@ -1815,6 +1815,7 @@ static void write_textures(WriteData *wd, ListBase *idbase)
|
||||
if(tex->pd->falloff_curve) write_curvemapping(wd, tex->pd->falloff_curve);
|
||||
}
|
||||
if(tex->type == TEX_VOXELDATA) writestruct(wd, DATA, "VoxelData", 1, tex->vd);
|
||||
if(tex->type == TEX_OCEAN && tex->ot) writestruct(wd, DATA, "OceanTex", 1, tex->ot);
|
||||
|
||||
/* nodetree is integral part of texture, no libdata */
|
||||
if(tex->nodetree) {
|
||||
|
@ -159,6 +159,7 @@ void OBJECT_OT_multires_external_save(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_multires_external_pack(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_meshdeform_bind(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_explode_refresh(struct wmOperatorType *ot);
|
||||
void OBJECT_OT_ocean_bake(struct wmOperatorType *ot);
|
||||
|
||||
/* object_constraint.c */
|
||||
void OBJECT_OT_constraint_add(struct wmOperatorType *ot);
|
||||
|
@ -34,6 +34,7 @@
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_anim_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_key_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
@ -48,6 +49,7 @@
|
||||
#include "BLI_editVert.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "BKE_animsys.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_context.h"
|
||||
#include "BKE_depsgraph.h"
|
||||
@ -63,6 +65,7 @@
|
||||
#include "BKE_multires.h"
|
||||
#include "BKE_report.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_ocean.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_softbody.h"
|
||||
|
||||
@ -1404,3 +1407,219 @@ void OBJECT_OT_explode_refresh(wmOperatorType *ot)
|
||||
edit_modifier_properties(ot);
|
||||
}
|
||||
|
||||
|
||||
/****************** ocean bake operator *********************/
|
||||
|
||||
static int ocean_bake_poll(bContext *C)
|
||||
{
|
||||
return edit_modifier_poll_generic(C, &RNA_OceanModifier, 0);
|
||||
}
|
||||
|
||||
/* copied from init_ocean_modifier, MOD_ocean.c */
|
||||
static void init_ocean_modifier_bake(struct Ocean *oc, struct OceanModifierData *omd)
|
||||
{
|
||||
int do_heightfield, do_chop, do_normals, do_jacobian;
|
||||
|
||||
if (!omd || !oc) return;
|
||||
|
||||
do_heightfield = TRUE;
|
||||
do_chop = (omd->chop_amount > 0);
|
||||
do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
|
||||
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
|
||||
|
||||
BKE_init_ocean(oc, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size,
|
||||
omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
|
||||
omd->depth, omd->time,
|
||||
do_heightfield, do_chop, do_normals, do_jacobian,
|
||||
omd->seed);
|
||||
}
|
||||
|
||||
typedef struct OceanBakeJob {
|
||||
/* from wmJob */
|
||||
void *owner;
|
||||
short *stop, *do_update;
|
||||
float *progress;
|
||||
int current_frame;
|
||||
struct OceanCache *och;
|
||||
struct Ocean *ocean;
|
||||
struct OceanModifierData *omd;
|
||||
} OceanBakeJob;
|
||||
|
||||
static void oceanbake_free(void *customdata)
|
||||
{
|
||||
OceanBakeJob *oj= customdata;
|
||||
MEM_freeN(oj);
|
||||
}
|
||||
|
||||
/* called by oceanbake, only to check job 'stop' value */
|
||||
static int oceanbake_breakjob(void *UNUSED(customdata))
|
||||
{
|
||||
//OceanBakeJob *ob= (OceanBakeJob *)customdata;
|
||||
//return *(ob->stop);
|
||||
|
||||
/* this is not nice yet, need to make the jobs list template better
|
||||
* for identifying/acting upon various different jobs */
|
||||
/* but for now we'll reuse the render break... */
|
||||
return (G.afbreek);
|
||||
}
|
||||
|
||||
/* called by oceanbake, wmJob sends notifier */
|
||||
static void oceanbake_update(void *customdata, float progress, int *cancel)
|
||||
{
|
||||
OceanBakeJob *oj= customdata;
|
||||
|
||||
if (oceanbake_breakjob(oj))
|
||||
*cancel = 1;
|
||||
|
||||
*(oj->do_update)= 1;
|
||||
*(oj->progress)= progress;
|
||||
}
|
||||
|
||||
static void oceanbake_startjob(void *customdata, short *stop, short *do_update, float *progress)
|
||||
{
|
||||
OceanBakeJob *oj= customdata;
|
||||
|
||||
oj->stop= stop;
|
||||
oj->do_update = do_update;
|
||||
oj->progress = progress;
|
||||
|
||||
G.afbreek= 0; /* XXX shared with render - replace with job 'stop' switch */
|
||||
|
||||
BKE_bake_ocean(oj->ocean, oj->och, oceanbake_update, (void *)oj);
|
||||
|
||||
*do_update= 1;
|
||||
*stop = 0;
|
||||
}
|
||||
|
||||
static void oceanbake_endjob(void *customdata)
|
||||
{
|
||||
OceanBakeJob *oj= customdata;
|
||||
|
||||
if (oj->ocean) {
|
||||
BKE_free_ocean(oj->ocean);
|
||||
oj->ocean = NULL;
|
||||
}
|
||||
|
||||
oj->omd->oceancache = oj->och;
|
||||
oj->omd->cached = TRUE;
|
||||
}
|
||||
|
||||
static int ocean_bake_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
Object *ob = ED_object_active_context(C);
|
||||
OceanModifierData *omd = (OceanModifierData *)edit_modifier_property_get(op, ob, eModifierType_Ocean);
|
||||
Scene *scene = CTX_data_scene(C);
|
||||
OceanCache *och;
|
||||
struct Ocean *ocean;
|
||||
int f, cfra, i=0;
|
||||
int free= RNA_boolean_get(op->ptr, "free");
|
||||
|
||||
wmJob *steve;
|
||||
OceanBakeJob *oj;
|
||||
|
||||
if (!omd)
|
||||
return OPERATOR_CANCELLED;
|
||||
|
||||
if (free) {
|
||||
omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
och = BKE_init_ocean_cache(omd->cachepath, omd->bakestart, omd->bakeend, omd->wave_scale,
|
||||
omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
|
||||
|
||||
och->time = MEM_mallocN(och->duration*sizeof(float), "foam bake time");
|
||||
|
||||
cfra = scene->r.cfra;
|
||||
|
||||
/* precalculate time variable before baking */
|
||||
for (f=omd->bakestart; f<=omd->bakeend; f++) {
|
||||
/* from physics_fluid.c:
|
||||
|
||||
* XXX: This can't be used due to an anim sys optimisation that ignores recalc object animation,
|
||||
* leaving it for the depgraph (this ignores object animation such as modifier properties though... :/ )
|
||||
* --> BKE_animsys_evaluate_all_animation(G.main, eval_time);
|
||||
* This doesn't work with drivers:
|
||||
* --> BKE_animsys_evaluate_animdata(&fsDomain->id, fsDomain->adt, eval_time, ADT_RECALC_ALL);
|
||||
*/
|
||||
|
||||
/* Modifying the global scene isn't nice, but we can do it in
|
||||
* this part of the process before a threaded job is created */
|
||||
|
||||
//scene->r.cfra = f;
|
||||
//ED_update_for_newframe(CTX_data_main(C), scene, CTX_wm_screen(C), 1);
|
||||
|
||||
/* ok, this doesn't work with drivers, but is way faster.
|
||||
* let's use this for now and hope nobody wants to drive the time value... */
|
||||
BKE_animsys_evaluate_animdata(scene, (ID *)ob, ob->adt, f, ADT_RECALC_ANIM);
|
||||
|
||||
och->time[i] = omd->time;
|
||||
i++;
|
||||
}
|
||||
|
||||
/* make a copy of ocean to use for baking - threadsafety */
|
||||
ocean = BKE_add_ocean();
|
||||
init_ocean_modifier_bake(ocean, omd);
|
||||
|
||||
/*
|
||||
BKE_bake_ocean(ocean, och);
|
||||
|
||||
omd->oceancache = och;
|
||||
omd->cached = TRUE;
|
||||
|
||||
scene->r.cfra = cfra;
|
||||
|
||||
DAG_id_tag_update(&ob->id, OB_RECALC_DATA);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_MODIFIER, ob);
|
||||
*/
|
||||
|
||||
/* job stuff */
|
||||
|
||||
scene->r.cfra = cfra;
|
||||
|
||||
/* setup job */
|
||||
steve= WM_jobs_get(CTX_wm_manager(C), CTX_wm_window(C), scene, "Ocean Simulation", WM_JOB_PROGRESS);
|
||||
oj= MEM_callocN(sizeof(OceanBakeJob), "ocean bake job");
|
||||
oj->ocean = ocean;
|
||||
oj->och = och;
|
||||
oj->omd = omd;
|
||||
|
||||
WM_jobs_customdata(steve, oj, oceanbake_free);
|
||||
WM_jobs_timer(steve, 0.1, NC_OBJECT|ND_MODIFIER, NC_OBJECT|ND_MODIFIER);
|
||||
WM_jobs_callbacks(steve, oceanbake_startjob, NULL, NULL, oceanbake_endjob);
|
||||
|
||||
WM_jobs_start(CTX_wm_manager(C), steve);
|
||||
|
||||
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
static int ocean_bake_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
|
||||
{
|
||||
if (edit_modifier_invoke_properties(C, op))
|
||||
return ocean_bake_exec(C, op);
|
||||
else
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
|
||||
void OBJECT_OT_ocean_bake(wmOperatorType *ot)
|
||||
{
|
||||
ot->name= "Bake Ocean";
|
||||
ot->description= "Bake an image sequence of ocean data";
|
||||
ot->idname= "OBJECT_OT_ocean_bake";
|
||||
|
||||
ot->poll= ocean_bake_poll;
|
||||
ot->invoke= ocean_bake_invoke;
|
||||
ot->exec= ocean_bake_exec;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
edit_modifier_properties(ot);
|
||||
|
||||
RNA_def_boolean(ot->srna, "free", FALSE, "Free", "Free the bake, rather than generating it");
|
||||
}
|
||||
|
||||
|
@ -142,6 +142,7 @@ void ED_operatortypes_object(void)
|
||||
WM_operatortype_append(OBJECT_OT_multires_external_pack);
|
||||
WM_operatortype_append(OBJECT_OT_meshdeform_bind);
|
||||
WM_operatortype_append(OBJECT_OT_explode_refresh);
|
||||
WM_operatortype_append(OBJECT_OT_ocean_bake);
|
||||
|
||||
WM_operatortype_append(OBJECT_OT_constraint_add);
|
||||
WM_operatortype_append(OBJECT_OT_constraint_add_with_targets);
|
||||
|
@ -75,6 +75,7 @@ typedef enum ModifierType {
|
||||
eModifierType_WeightVGProximity,
|
||||
eModifierType_EmptySlot, /* keep so DynamicPaint keep loading, can re-use later */
|
||||
eModifierType_DynamicPaint, /* reserve slot */
|
||||
eModifierType_Ocean,
|
||||
NUM_MODIFIER_TYPES
|
||||
} ModifierType;
|
||||
|
||||
@ -750,6 +751,64 @@ typedef struct ScrewModifierData {
|
||||
#define MOD_SCREW_OBJECT_OFFSET (1<<2)
|
||||
// #define MOD_SCREW_OBJECT_ANGLE (1<<4)
|
||||
|
||||
typedef struct OceanModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
struct Ocean *ocean;
|
||||
struct OceanCache *oceancache;
|
||||
|
||||
int resolution;
|
||||
int spatial_size;
|
||||
|
||||
float wind_velocity;
|
||||
|
||||
float damp;
|
||||
float smallest_wave;
|
||||
float depth;
|
||||
|
||||
float wave_alignment;
|
||||
float wave_direction;
|
||||
float wave_scale;
|
||||
|
||||
float chop_amount;
|
||||
float foam_coverage;
|
||||
float time;
|
||||
|
||||
int seed;
|
||||
int flag;
|
||||
int output;
|
||||
|
||||
int refresh;
|
||||
|
||||
int bakestart;
|
||||
int bakeend;
|
||||
|
||||
char cachepath[240]; // FILE_MAX
|
||||
int cached;
|
||||
|
||||
int geometry_mode;
|
||||
float size;
|
||||
int repeat_x;
|
||||
int repeat_y;
|
||||
|
||||
float foam_fade;
|
||||
|
||||
} OceanModifierData;
|
||||
|
||||
#define MOD_OCEAN_GEOM_GENERATE 0
|
||||
#define MOD_OCEAN_GEOM_DISPLACE 1
|
||||
#define MOD_OCEAN_GEOM_SIM_ONLY 2
|
||||
|
||||
#define MOD_OCEAN_REFRESH_RESET 1
|
||||
#define MOD_OCEAN_REFRESH_SIM 2
|
||||
#define MOD_OCEAN_REFRESH_ADD 4
|
||||
#define MOD_OCEAN_REFRESH_CLEAR_CACHE 8
|
||||
#define MOD_OCEAN_REFRESH_TOPOLOGY 16
|
||||
|
||||
#define MOD_OCEAN_GENERATE_FOAM 1
|
||||
#define MOD_OCEAN_GENERATE_NORMALS 2
|
||||
|
||||
|
||||
typedef struct WarpModifierData {
|
||||
ModifierData modifier;
|
||||
|
||||
|
@ -50,6 +50,7 @@ struct Tex;
|
||||
struct Image;
|
||||
struct PreviewImage;
|
||||
struct ImBuf;
|
||||
struct Ocean;
|
||||
struct CurveMapping;
|
||||
|
||||
typedef struct MTex {
|
||||
@ -206,6 +207,15 @@ typedef struct VoxelData {
|
||||
|
||||
} VoxelData;
|
||||
|
||||
typedef struct OceanTex {
|
||||
struct Object *object;
|
||||
char oceanmod[64];
|
||||
|
||||
int output;
|
||||
int pad;
|
||||
|
||||
} OceanTex;
|
||||
|
||||
typedef struct Tex {
|
||||
ID id;
|
||||
struct AnimData *adt; /* animation data (must be immediately after id for utilities to use it) */
|
||||
@ -261,6 +271,7 @@ typedef struct Tex {
|
||||
struct PreviewImage * preview;
|
||||
struct PointDensity *pd;
|
||||
struct VoxelData *vd;
|
||||
struct OceanTex *ot;
|
||||
|
||||
char use_nodes;
|
||||
char pad[7];
|
||||
@ -318,6 +329,7 @@ typedef struct ColorMapping {
|
||||
#define TEX_DISTNOISE 13
|
||||
#define TEX_POINTDENSITY 14
|
||||
#define TEX_VOXELDATA 15
|
||||
#define TEX_OCEAN 16
|
||||
|
||||
/* musgrave stype */
|
||||
#define TEX_MFRACTAL 0
|
||||
@ -588,6 +600,18 @@ typedef struct ColorMapping {
|
||||
#define TEX_VD_SMOKEHEAT 1
|
||||
#define TEX_VD_SMOKEVEL 2
|
||||
|
||||
/******************** Ocean *****************************/
|
||||
/* output */
|
||||
#define TEX_OCN_DISPLACEMENT 1
|
||||
#define TEX_OCN_FOAM 2
|
||||
#define TEX_OCN_JPLUS 3
|
||||
#define TEX_OCN_EMINUS 4
|
||||
#define TEX_OCN_EPLUS 5
|
||||
|
||||
/* flag */
|
||||
#define TEX_OCN_GENERATE_NORMALS 1
|
||||
#define TEX_OCN_XZ 2
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -348,6 +348,9 @@ extern StructRNA RNA_NorController;
|
||||
extern StructRNA RNA_Object;
|
||||
extern StructRNA RNA_ObjectBase;
|
||||
extern StructRNA RNA_ObstacleFluidSettings;
|
||||
extern StructRNA RNA_OceanModifier;
|
||||
extern StructRNA RNA_OceanTexData;
|
||||
extern StructRNA RNA_OceanTexture;
|
||||
extern StructRNA RNA_Operator;
|
||||
extern StructRNA RNA_OperatorFileListElement;
|
||||
extern StructRNA RNA_OperatorMousePath;
|
||||
|
@ -55,6 +55,9 @@ if env['WITH_BF_PYTHON']:
|
||||
if env['WITH_BF_COLLADA']:
|
||||
defs.append('WITH_COLLADA')
|
||||
|
||||
if env['WITH_BF_OCEANSIM']:
|
||||
defs.append('WITH_OCEANSIM')
|
||||
|
||||
if env['OURPLATFORM'] == 'linux':
|
||||
cflags='-pthread'
|
||||
incs += ' ../../../extern/binreloc/include'
|
||||
|
@ -206,6 +206,10 @@ if(WITH_FFTW3)
|
||||
add_definitions(-DWITH_FFTW3)
|
||||
endif()
|
||||
|
||||
if(WITH_OCEANSIM)
|
||||
add_definitions(-DWITH_OCEANSIM)
|
||||
endif()
|
||||
|
||||
if(WITH_SDL)
|
||||
add_definitions(-DWITH_SDL)
|
||||
endif()
|
||||
|
@ -96,6 +96,7 @@ EnumPropertyItem modifier_type_items[] ={
|
||||
{eModifierType_Softbody, "SOFT_BODY", ICON_MOD_SOFT, "Soft Body", ""},
|
||||
{eModifierType_Surface, "SURFACE", ICON_MOD_PHYSICS, "Surface", ""},
|
||||
{eModifierType_DynamicPaint, "DYNAMIC_PAINT", ICON_MOD_DYNAMICPAINT, "Dynamic Paint", ""},
|
||||
{eModifierType_Ocean, "OCEAN", ICON_MOD_WAVE, "Ocean", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
#ifdef RNA_RUNTIME
|
||||
@ -186,6 +187,8 @@ static StructRNA* rna_Modifier_refine(struct PointerRNA *ptr)
|
||||
return &RNA_SolidifyModifier;
|
||||
case eModifierType_Screw:
|
||||
return &RNA_ScrewModifier;
|
||||
case eModifierType_Ocean:
|
||||
return &RNA_OceanModifier;
|
||||
case eModifierType_Warp:
|
||||
return &RNA_WarpModifier;
|
||||
case eModifierType_WeightVGEdit:
|
||||
@ -649,6 +652,57 @@ static void rna_UVProjectModifier_num_projectors_set(PointerRNA *ptr, int value)
|
||||
md->projectors[a]= NULL;
|
||||
}
|
||||
|
||||
static int rna_OceanModifier_build_enabled_get(PointerRNA *UNUSED(ptr))
|
||||
{
|
||||
#ifdef WITH_OCEANSIM
|
||||
return 1;
|
||||
#else // WITH_OCEANSIM
|
||||
return 0;
|
||||
#endif // WITH_OCEANSIM
|
||||
}
|
||||
|
||||
static void rna_OceanModifier_init_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
OceanModifierData *omd= (OceanModifierData*)ptr->data;
|
||||
|
||||
omd->refresh |= (MOD_OCEAN_REFRESH_RESET|MOD_OCEAN_REFRESH_SIM|MOD_OCEAN_REFRESH_CLEAR_CACHE);
|
||||
|
||||
rna_Modifier_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_OceanModifier_sim_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
OceanModifierData *omd= (OceanModifierData*)ptr->data;
|
||||
|
||||
omd->refresh |= MOD_OCEAN_REFRESH_SIM;
|
||||
|
||||
rna_Modifier_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_OceanModifier_topology_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
OceanModifierData *omd= (OceanModifierData*)ptr->data;
|
||||
|
||||
omd->refresh |= MOD_OCEAN_REFRESH_TOPOLOGY;
|
||||
|
||||
rna_Modifier_update(bmain, scene, ptr);
|
||||
}
|
||||
|
||||
static void rna_OceanModifier_ocean_chop_set(PointerRNA *ptr, float value)
|
||||
{
|
||||
OceanModifierData *omd= (OceanModifierData*)ptr->data;
|
||||
float old_value = omd->chop_amount;
|
||||
|
||||
omd->chop_amount = value;
|
||||
|
||||
if ((old_value == 0.0 && value > 0.0) ||
|
||||
(old_value > 0.0 && value == 0.0))
|
||||
{
|
||||
omd->refresh |= MOD_OCEAN_REFRESH_RESET;
|
||||
omd->refresh |= MOD_OCEAN_REFRESH_CLEAR_CACHE;
|
||||
}
|
||||
}
|
||||
|
||||
static float rna_EdgeSplitModifier_split_angle_get(PointerRNA *ptr)
|
||||
{
|
||||
EdgeSplitModifierData *md= (EdgeSplitModifierData*)ptr->data;
|
||||
@ -2809,6 +2863,181 @@ static void rna_def_modifier_weightvgproximity(BlenderRNA *brna)
|
||||
rna_def_modifier_weightvg_mask(brna, srna);
|
||||
}
|
||||
|
||||
static void rna_def_modifier_ocean(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem geometry_items[]= {
|
||||
{MOD_OCEAN_GEOM_GENERATE, "GENERATE", 0, "Generate", "Generates ocean surface geometry at the specified resolution"},
|
||||
{MOD_OCEAN_GEOM_DISPLACE, "DISPLACE", 0, "Displace", "Displaces existing geometry according to simulation"},
|
||||
//{MOD_OCEAN_GEOM_SIM_ONLY, "SIM_ONLY", 0, "Sim Only", "Leaves geometry unchanged, but still runs simulation (to be used from texture)"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna= RNA_def_struct(brna, "OceanModifier", "Modifier");
|
||||
RNA_def_struct_ui_text(srna, "Ocean Modifier", "Simulate an ocean surface");
|
||||
RNA_def_struct_sdna(srna, "OceanModifierData");
|
||||
RNA_def_struct_ui_icon(srna, ICON_MOD_FLUIDSIM);
|
||||
|
||||
/* General check if OceanSim modifier code is enabled */
|
||||
prop= RNA_def_property(srna, "build_enabled", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_funcs(prop, "rna_OceanModifier_build_enabled_get", NULL);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Build Enabled", "True if the OceanSim modifier is enabled in this build");
|
||||
|
||||
prop= RNA_def_property(srna, "geometry_mode", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "geometry_mode");
|
||||
RNA_def_property_enum_items(prop, geometry_items);
|
||||
RNA_def_property_ui_text(prop, "Geometry", "Method of modifying geometry");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop= RNA_def_property(srna, "size", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "size");
|
||||
RNA_def_property_ui_text(prop, "Size", "");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
|
||||
|
||||
prop= RNA_def_property(srna, "repeat_x", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "repeat_x");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, 1024);
|
||||
RNA_def_property_ui_range(prop, 1, 100, 1, 0);
|
||||
RNA_def_property_ui_text(prop, "Repeat X", "Repetitions of the generated surface in X");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
|
||||
|
||||
prop= RNA_def_property(srna, "repeat_y", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "repeat_y");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, 1024);
|
||||
RNA_def_property_ui_range(prop, 1, 100, 1, 0);
|
||||
RNA_def_property_ui_text(prop, "Repeat Y", "Repetitions of the generated surface in Y");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_topology_update");
|
||||
|
||||
prop= RNA_def_property(srna, "generate_normals", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_OCEAN_GENERATE_NORMALS);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Generate Normals", "Outputs normals for bump mapping - disabling can speed up performance if its not needed");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "generate_foam", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "flag", MOD_OCEAN_GENERATE_FOAM);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Generate Foam", "Generates foam mask as a vertex color channel");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "resolution", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "resolution");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 1, 1024);
|
||||
RNA_def_property_ui_range(prop, 1, 32, 1, 0);
|
||||
RNA_def_property_ui_text(prop, "Resolution", "Resolution of the generated surface");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "spatial_size", PROP_INT, PROP_DISTANCE);
|
||||
RNA_def_property_int_sdna(prop, NULL, "spatial_size");
|
||||
RNA_def_property_ui_range(prop, 1, 512, 2, 0);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Spatial Size", "Physical size of the simulation domain (m)");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wind_velocity", PROP_FLOAT, PROP_VELOCITY);
|
||||
RNA_def_property_float_sdna(prop, NULL, "wind_velocity");
|
||||
RNA_def_property_ui_text(prop, "Wind Velocity", "Wind speed (m/s)");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "damp", PROP_FLOAT, PROP_FACTOR);
|
||||
RNA_def_property_float_sdna(prop, NULL, "damp");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Damping", "Damp reflected waves going in opposite direction to the wind");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "smallest_wave", PROP_FLOAT, PROP_DISTANCE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "smallest_wave");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_range(prop, 0.0, FLT_MAX);
|
||||
RNA_def_property_ui_text(prop, "Smallest Wave", "Shortest allowed wavelength (m)");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wave_alignment", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "wave_alignment");
|
||||
RNA_def_property_range(prop, 0.0, 10.0);
|
||||
RNA_def_property_ui_text(prop, "Wave Alignment", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wave_direction", PROP_FLOAT, PROP_ANGLE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "wave_direction");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Wave Direction", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "wave_scale", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "wave_scale");
|
||||
RNA_def_property_ui_text(prop, "Wave Scale", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
|
||||
|
||||
prop= RNA_def_property(srna, "depth", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "depth");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Depth", "");
|
||||
RNA_def_property_ui_range(prop, 0, 250, 1, 0);
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "foam_coverage", PROP_FLOAT, PROP_NONE);
|
||||
RNA_def_property_float_sdna(prop, NULL, "foam_coverage");
|
||||
RNA_def_property_ui_text(prop, "Foam Coverage", "");
|
||||
RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
|
||||
prop= RNA_def_property(srna, "bake_foam_fade", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "foam_fade");
|
||||
RNA_def_property_ui_text(prop, "Foam Fade", "");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
|
||||
RNA_def_property_update(prop, 0, NULL);
|
||||
|
||||
prop= RNA_def_property(srna, "choppiness", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "chop_amount");
|
||||
RNA_def_property_ui_text(prop, "Choppiness", "");
|
||||
RNA_def_property_ui_range(prop, 0.0, 4.0, 3, 0);
|
||||
RNA_def_property_float_funcs(prop, NULL, "rna_OceanModifier_ocean_chop_set", NULL);
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
|
||||
|
||||
prop= RNA_def_property(srna, "time", PROP_FLOAT, PROP_UNSIGNED);
|
||||
RNA_def_property_float_sdna(prop, NULL, "time");
|
||||
RNA_def_property_ui_text(prop, "Time", "");
|
||||
RNA_def_property_ui_range(prop, -FLT_MAX, FLT_MAX, 1, 0);
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_sim_update");
|
||||
|
||||
prop= RNA_def_property(srna, "random_seed", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "seed");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Random Seed", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "bake_start", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "bakestart");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Bake Start", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "bake_end", PROP_INT, PROP_UNSIGNED);
|
||||
RNA_def_property_int_sdna(prop, NULL, "bakeend");
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Bake End", "");
|
||||
RNA_def_property_update(prop, 0, "rna_OceanModifier_init_update");
|
||||
|
||||
prop= RNA_def_property(srna, "is_cached", PROP_BOOLEAN, PROP_NONE);
|
||||
RNA_def_property_boolean_sdna(prop, NULL, "cached", 1);
|
||||
RNA_def_property_clear_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_ui_text(prop, "Ocean is Cached", "Whether the ocean is useing cached data or simulating");
|
||||
|
||||
|
||||
prop= RNA_def_property(srna, "cachepath", PROP_STRING, PROP_DIRPATH);
|
||||
RNA_def_property_string_sdna(prop, NULL, "cachepath");
|
||||
RNA_def_property_ui_text(prop, "Cache Path", "Path to a folder to store external baked images");
|
||||
//RNA_def_property_update(prop, 0, "rna_Modifier_update");
|
||||
// XXX how to update?
|
||||
}
|
||||
|
||||
|
||||
void RNA_def_modifier(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -2910,6 +3139,7 @@ void RNA_def_modifier(BlenderRNA *brna)
|
||||
rna_def_modifier_weightvgmix(brna);
|
||||
rna_def_modifier_weightvgproximity(brna);
|
||||
rna_def_modifier_dynamic_paint(brna);
|
||||
rna_def_modifier_ocean(brna);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -73,6 +73,7 @@ EnumPropertyItem texture_type_items[] = {
|
||||
{TEX_VORONOI, "VORONOI", ICON_TEXTURE, "Voronoi", "Procedural - Create cell-like patterns based on Worley noise"},
|
||||
{TEX_VOXELDATA, "VOXEL_DATA", ICON_TEXTURE, "Voxel Data", "Create a 3d texture based on volumetric data"},
|
||||
{TEX_WOOD, "WOOD", ICON_TEXTURE, "Wood", "Procedural - Wave generated bands or rings, with optional noise"},
|
||||
{TEX_OCEAN, "OCEAN", ICON_TEXTURE, "Ocean", ""},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
EnumPropertyItem blend_type_items[] = {
|
||||
@ -145,6 +146,8 @@ static StructRNA *rna_Texture_refine(struct PointerRNA *ptr)
|
||||
return &RNA_VoxelDataTexture;
|
||||
case TEX_WOOD:
|
||||
return &RNA_WoodTexture;
|
||||
case TEX_OCEAN:
|
||||
return &RNA_OceanTexture;
|
||||
default:
|
||||
return &RNA_Texture;
|
||||
}
|
||||
@ -435,6 +438,11 @@ static char *rna_VoxelData_path(PointerRNA *UNUSED(ptr))
|
||||
return BLI_sprintfN("voxel_data");
|
||||
}
|
||||
|
||||
static char *rna_OceanTex_path(PointerRNA *ptr)
|
||||
{
|
||||
return BLI_sprintfN("ocean");
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void rna_def_texmapping(BlenderRNA *brna)
|
||||
@ -1860,6 +1868,49 @@ static void rna_def_texture_voxeldata(BlenderRNA *brna)
|
||||
RNA_def_property_update(prop, 0, "rna_Texture_voxeldata_update");
|
||||
}
|
||||
|
||||
static void rna_def_texture_ocean(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
PropertyRNA *prop;
|
||||
|
||||
static EnumPropertyItem ocean_output_items[] = {
|
||||
{TEX_OCN_DISPLACEMENT, "DISPLACEMENT", 0, "Displacement", "Outputs XYZ displacement in RGB channels"},
|
||||
//{TEX_OCN_NORMALS, "NORMALS", 0, "Normals", "Outputs wave normals"}, // these are in nor channel now
|
||||
{TEX_OCN_FOAM, "FOAM", 0, "Foam", "Outputs Foam (wave overlap) amount in single channel"},
|
||||
{TEX_OCN_JPLUS, "JPLUS", 0, "Eigenvalues", "Positive Eigenvalues"},
|
||||
{TEX_OCN_EMINUS, "EMINUS", 0, "Eigenvectors (-)", "Negative Eigenvectors"},
|
||||
{TEX_OCN_EPLUS, "EPLUS", 0, "Eigenvectors (+)", "Positive Eigenvectors"},
|
||||
{0, NULL, 0, NULL, NULL}};
|
||||
|
||||
srna= RNA_def_struct(brna, "OceanTexData", NULL);
|
||||
RNA_def_struct_sdna(srna, "OceanTex");
|
||||
RNA_def_struct_ui_text(srna, "Ocean", "Ocean Texture settings");
|
||||
RNA_def_struct_path_func(srna, "rna_OceanTex_path");
|
||||
|
||||
prop= RNA_def_property(srna, "output", PROP_ENUM, PROP_NONE);
|
||||
RNA_def_property_enum_sdna(prop, NULL, "output");
|
||||
RNA_def_property_enum_items(prop, ocean_output_items);
|
||||
RNA_def_property_clear_flag(prop, PROP_ANIMATABLE);
|
||||
RNA_def_property_ui_text(prop, "Output", "The data that is output by the texture");
|
||||
RNA_def_property_update(prop, 0, "rna_Texture_update");
|
||||
|
||||
prop= RNA_def_property(srna, "ocean_object", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "object");
|
||||
RNA_def_property_ui_text(prop, "Modifier Object", "Object containing the ocean modifier");
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE);
|
||||
RNA_def_property_update(prop, 0, "rna_Texture_update");
|
||||
|
||||
srna= RNA_def_struct(brna, "OceanTexture", "Texture");
|
||||
RNA_def_struct_sdna(srna, "Tex");
|
||||
RNA_def_struct_ui_text(srna, "Ocean", "Settings for the Ocean texture");
|
||||
|
||||
prop= RNA_def_property(srna, "ocean", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_pointer_sdna(prop, NULL, "ot");
|
||||
RNA_def_property_struct_type(prop, "OceanTexData");
|
||||
RNA_def_property_ui_text(prop, "Ocean", "The ocean data associated with this texture");
|
||||
RNA_def_property_update(prop, 0, "rna_Texture_update");
|
||||
}
|
||||
|
||||
static void rna_def_texture(BlenderRNA *brna)
|
||||
{
|
||||
StructRNA *srna;
|
||||
@ -1962,6 +2013,7 @@ static void rna_def_texture(BlenderRNA *brna)
|
||||
rna_def_texture_distorted_noise(brna);
|
||||
rna_def_texture_pointdensity(brna);
|
||||
rna_def_texture_voxeldata(brna);
|
||||
rna_def_texture_ocean(brna);
|
||||
/* XXX add more types here .. */
|
||||
|
||||
RNA_api_texture(srna);
|
||||
|
@ -67,6 +67,7 @@ set(SRC
|
||||
intern/MOD_mirror.c
|
||||
intern/MOD_multires.c
|
||||
intern/MOD_none.c
|
||||
intern/MOD_ocean.c
|
||||
intern/MOD_particleinstance.c
|
||||
intern/MOD_particlesystem.c
|
||||
intern/MOD_screw.c
|
||||
@ -116,6 +117,10 @@ if(WITH_MOD_FLUID)
|
||||
add_definitions(-DWITH_MOD_FLUID)
|
||||
endif()
|
||||
|
||||
if(WITH_OCEANSIM)
|
||||
add_definitions(-DWITH_OCEANSIM)
|
||||
endif()
|
||||
|
||||
if(WITH_GAMEENGINE)
|
||||
# for MOD_navmesh.c
|
||||
add_definitions(-DWITH_GAMEENGINE)
|
||||
@ -125,4 +130,8 @@ if(WITH_GAMEENGINE)
|
||||
)
|
||||
endif()
|
||||
|
||||
if(WITH_OPENMP)
|
||||
add_definitions(-DPARALLEL=1)
|
||||
endif()
|
||||
|
||||
blender_add_lib(bf_modifiers "${SRC}" "${INC}" "${INC_SYS}")
|
||||
|
@ -69,6 +69,7 @@ extern ModifierTypeInfo modifierType_Smoke;
|
||||
extern ModifierTypeInfo modifierType_ShapeKey;
|
||||
extern ModifierTypeInfo modifierType_Solidify;
|
||||
extern ModifierTypeInfo modifierType_Screw;
|
||||
extern ModifierTypeInfo modifierType_Ocean;
|
||||
extern ModifierTypeInfo modifierType_Warp;
|
||||
extern ModifierTypeInfo modifierType_NavMesh;
|
||||
extern ModifierTypeInfo modifierType_WeightVGEdit;
|
||||
|
@ -22,6 +22,9 @@ if env ['WITH_BF_DECIMATE']:
|
||||
if env['WITH_BF_FLUID']:
|
||||
defs.append('WITH_MOD_FLUID')
|
||||
|
||||
if env['WITH_BF_OCEANSIM']:
|
||||
defs.append('WITH_OCEANSIM')
|
||||
|
||||
if env['WITH_BF_GAMEENGINE']:
|
||||
incs += ' #/extern/recastnavigation'
|
||||
defs.append('WITH_GAMEENGINE')
|
||||
|
561
source/blender/modifiers/intern/MOD_ocean.c
Normal file
561
source/blender/modifiers/intern/MOD_ocean.c
Normal file
@ -0,0 +1,561 @@
|
||||
/**
|
||||
* $Id: MOD_ocean.c 28135 2010-04-11 23:20:03Z gsrb3d $
|
||||
*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) Blender Foundation
|
||||
* All rights reserved.
|
||||
*
|
||||
* The Original Code is: all of this file.
|
||||
*
|
||||
* Contributor(s): Matt Ebb
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "DNA_customdata_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_meshdata_types.h"
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_scene_types.h"
|
||||
|
||||
#include "BKE_cdderivedmesh.h"
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_ocean.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_math_inline.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "MOD_util.h"
|
||||
|
||||
#ifdef WITH_OCEANSIM
|
||||
static void init_cache_data(struct OceanModifierData *omd)
|
||||
{
|
||||
omd->oceancache = BKE_init_ocean_cache(omd->cachepath, omd->bakestart, omd->bakeend, omd->wave_scale,
|
||||
omd->chop_amount, omd->foam_coverage, omd->foam_fade, omd->resolution);
|
||||
}
|
||||
|
||||
static void clear_cache_data(struct OceanModifierData *omd)
|
||||
{
|
||||
BKE_free_ocean_cache(omd->oceancache);
|
||||
omd->oceancache = NULL;
|
||||
omd->cached = FALSE;
|
||||
}
|
||||
|
||||
/* keep in sync with init_ocean_modifier_bake(), object_modifier.c */
|
||||
static void init_ocean_modifier(struct OceanModifierData *omd)
|
||||
{
|
||||
int do_heightfield, do_chop, do_normals, do_jacobian;
|
||||
|
||||
if (!omd || !omd->ocean) return;
|
||||
|
||||
do_heightfield = TRUE;
|
||||
do_chop = (omd->chop_amount > 0);
|
||||
do_normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
|
||||
do_jacobian = (omd->flag & MOD_OCEAN_GENERATE_FOAM);
|
||||
|
||||
BKE_free_ocean_data(omd->ocean);
|
||||
BKE_init_ocean(omd->ocean, omd->resolution*omd->resolution, omd->resolution*omd->resolution, omd->spatial_size, omd->spatial_size,
|
||||
omd->wind_velocity, omd->smallest_wave, 1.0, omd->wave_direction, omd->damp, omd->wave_alignment,
|
||||
omd->depth, omd->time,
|
||||
do_heightfield, do_chop, do_normals, do_jacobian,
|
||||
omd->seed);
|
||||
}
|
||||
|
||||
static void simulate_ocean_modifier(struct OceanModifierData *omd)
|
||||
{
|
||||
if (!omd || !omd->ocean) return;
|
||||
|
||||
BKE_simulate_ocean(omd->ocean, omd->time, omd->wave_scale, omd->chop_amount);
|
||||
}
|
||||
#endif // WITH_OCEANSIM
|
||||
|
||||
|
||||
|
||||
/* Modifier Code */
|
||||
|
||||
static void initData(ModifierData *md)
|
||||
{
|
||||
#ifdef WITH_OCEANSIM
|
||||
OceanModifierData *omd = (OceanModifierData*) md;
|
||||
|
||||
omd->resolution = 7;
|
||||
omd->spatial_size = 50;
|
||||
|
||||
omd->wave_alignment = 0.0;
|
||||
omd->wind_velocity = 30.0;
|
||||
|
||||
omd->damp = 0.5;
|
||||
omd->smallest_wave = 0.01;
|
||||
omd->wave_direction= 0.0;
|
||||
omd->depth = 200.0;
|
||||
|
||||
omd->wave_scale = 1.0;
|
||||
|
||||
omd->chop_amount = 1.0;
|
||||
|
||||
omd->foam_coverage = 0.0;
|
||||
|
||||
omd->seed = 0;
|
||||
omd->time = 1.0;
|
||||
|
||||
omd->refresh = 0;
|
||||
|
||||
omd->size = 1.0;
|
||||
omd->repeat_x = 1;
|
||||
omd->repeat_y = 1;
|
||||
|
||||
strcpy(omd->cachepath, "//ocean_cache/");
|
||||
|
||||
omd->cached = 0;
|
||||
omd->bakestart = 1;
|
||||
omd->bakeend = 250;
|
||||
omd->oceancache = NULL;
|
||||
omd->foam_fade = 0.98;
|
||||
|
||||
omd->ocean = BKE_add_ocean();
|
||||
init_ocean_modifier(omd);
|
||||
simulate_ocean_modifier(omd);
|
||||
#else // WITH_OCEANSIM
|
||||
/* unused */
|
||||
(void)md;
|
||||
#endif // WITH_OCEANSIM
|
||||
}
|
||||
|
||||
static void freeData(ModifierData *md)
|
||||
{
|
||||
#ifdef WITH_OCEANSIM
|
||||
OceanModifierData *omd = (OceanModifierData*) md;
|
||||
|
||||
BKE_free_ocean(omd->ocean);
|
||||
if (omd->oceancache)
|
||||
BKE_free_ocean_cache(omd->oceancache);
|
||||
#else // WITH_OCEANSIM
|
||||
/* unused */
|
||||
(void)md;
|
||||
#endif // WITH_OCEANSIM
|
||||
}
|
||||
|
||||
static void copyData(ModifierData *md, ModifierData *target)
|
||||
{
|
||||
#ifdef WITH_OCEANSIM
|
||||
OceanModifierData *omd = (OceanModifierData*) md;
|
||||
OceanModifierData *tomd = (OceanModifierData*) target;
|
||||
|
||||
tomd->resolution = omd->resolution;
|
||||
tomd->spatial_size = omd->spatial_size;
|
||||
|
||||
tomd->wind_velocity = omd->wind_velocity;
|
||||
|
||||
tomd->damp = omd->damp;
|
||||
tomd->smallest_wave = omd->smallest_wave;
|
||||
tomd->depth = omd->depth;
|
||||
|
||||
tomd->wave_alignment = omd->wave_alignment;
|
||||
tomd->wave_direction = omd->wave_direction;
|
||||
tomd->wave_scale = omd->wave_scale;
|
||||
|
||||
tomd->chop_amount = omd->chop_amount;
|
||||
tomd->foam_coverage = omd->foam_coverage;
|
||||
tomd->time = omd->time;
|
||||
|
||||
tomd->seed = omd->seed;
|
||||
tomd->flag = omd->flag;
|
||||
tomd->output = omd->output;
|
||||
|
||||
tomd->refresh = 0;
|
||||
|
||||
|
||||
tomd->size = omd->size;
|
||||
tomd->repeat_x = omd->repeat_x;
|
||||
tomd->repeat_y = omd->repeat_y;
|
||||
|
||||
/* XXX todo: copy cache runtime too */
|
||||
tomd->cached = 0;
|
||||
tomd->bakestart = omd->bakestart;
|
||||
tomd->bakeend = omd->bakeend;
|
||||
tomd->oceancache = NULL;
|
||||
|
||||
tomd->ocean = BKE_add_ocean();
|
||||
init_ocean_modifier(tomd);
|
||||
simulate_ocean_modifier(tomd);
|
||||
#else // WITH_OCEANSIM
|
||||
/* unused */
|
||||
(void)md;
|
||||
(void)target;
|
||||
#endif // WITH_OCEANSIM
|
||||
}
|
||||
|
||||
#ifdef WITH_OCEANSIM
|
||||
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
|
||||
{
|
||||
OceanModifierData *omd = (OceanModifierData *)md;
|
||||
CustomDataMask dataMask = 0;
|
||||
|
||||
if (omd->flag & MOD_OCEAN_GENERATE_FOAM)
|
||||
dataMask |= CD_MASK_MCOL;
|
||||
|
||||
return dataMask;
|
||||
}
|
||||
#else // WITH_OCEANSIM
|
||||
static CustomDataMask requiredDataMask(Object *UNUSED(ob), ModifierData *md)
|
||||
{
|
||||
/* unused */
|
||||
(void)md;
|
||||
return 0;
|
||||
}
|
||||
#endif // WITH_OCEANSIM
|
||||
|
||||
#if 0
|
||||
static void dm_get_bounds(DerivedMesh *dm, float *sx, float *sy, float *ox, float *oy)
|
||||
{
|
||||
/* get bounding box of underlying dm */
|
||||
int v, totvert=dm->getNumVerts(dm);
|
||||
float min[3], max[3], delta[3];
|
||||
|
||||
MVert *mvert = dm->getVertDataArray(dm,0);
|
||||
|
||||
copy_v3_v3(min, mvert->co);
|
||||
copy_v3_v3(max, mvert->co);
|
||||
|
||||
for(v=1; v<totvert; v++, mvert++) {
|
||||
min[0]=MIN2(min[0],mvert->co[0]);
|
||||
min[1]=MIN2(min[1],mvert->co[1]);
|
||||
min[2]=MIN2(min[2],mvert->co[2]);
|
||||
|
||||
max[0]=MAX2(max[0],mvert->co[0]);
|
||||
max[1]=MAX2(max[1],mvert->co[1]);
|
||||
max[2]=MAX2(max[2],mvert->co[2]);
|
||||
}
|
||||
|
||||
sub_v3_v3v3(delta, max, min);
|
||||
|
||||
*sx = delta[0];
|
||||
*sy = delta[1];
|
||||
|
||||
*ox = min[0];
|
||||
*oy = min[1];
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef WITH_OCEANSIM
|
||||
MINLINE float ocean_co(OceanModifierData *omd, float v)
|
||||
{
|
||||
//float scale = 1.0 / (omd->size * omd->spatial_size);
|
||||
//*v = (*v * scale) + 0.5;
|
||||
|
||||
return (v / (omd->size * omd->spatial_size)) + 0.5;
|
||||
}
|
||||
|
||||
#define OMP_MIN_RES 18
|
||||
static DerivedMesh *generate_ocean_geometry(OceanModifierData *omd)
|
||||
{
|
||||
DerivedMesh *result;
|
||||
|
||||
MVert *mv;
|
||||
MFace *mf;
|
||||
MTFace *tf;
|
||||
|
||||
int cdlayer;
|
||||
|
||||
const int rx = omd->resolution*omd->resolution;
|
||||
const int ry = omd->resolution*omd->resolution;
|
||||
const int res_x = rx * omd->repeat_x;
|
||||
const int res_y = ry * omd->repeat_y;
|
||||
|
||||
const int num_verts = (res_x + 1) * (res_y + 1);
|
||||
const int num_edges = (res_x * res_y * 2) + res_x + res_y;
|
||||
const int num_faces = res_x * res_y;
|
||||
|
||||
float sx = omd->size * omd->spatial_size;
|
||||
float sy = omd->size * omd->spatial_size;
|
||||
const float ox = -sx / 2.0;
|
||||
const float oy = -sy / 2.0;
|
||||
|
||||
float ix, iy;
|
||||
|
||||
int x, y;
|
||||
|
||||
sx /= rx;
|
||||
sy /= ry;
|
||||
|
||||
result = CDDM_new(num_verts, num_edges, num_faces);
|
||||
|
||||
mv = CDDM_get_verts(result);
|
||||
mf = CDDM_get_faces(result);
|
||||
|
||||
/* create vertices */
|
||||
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
|
||||
for (y=0; y < res_y+1; y++) {
|
||||
for (x=0; x < res_x+1; x++) {
|
||||
const int i = y*(res_x+1) + x;
|
||||
mv[i].co[0] = ox + (x * sx);
|
||||
mv[i].co[1] = oy + (y * sy);
|
||||
mv[i].co[2] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* create faces */
|
||||
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
|
||||
for (y=0; y < res_y; y++) {
|
||||
for (x=0; x < res_x; x++) {
|
||||
const int fi = y*res_x + x;
|
||||
const int vi = y*(res_x+1) + x;
|
||||
mf[fi].v1 = vi;
|
||||
mf[fi].v2 = vi + 1;
|
||||
mf[fi].v3 = vi + 1 + res_x+1;
|
||||
mf[fi].v4 = vi + res_x+1;
|
||||
|
||||
mf[fi].flag |= ME_SMOOTH;
|
||||
}
|
||||
}
|
||||
|
||||
CDDM_calc_edges(result);
|
||||
|
||||
/* add uvs */
|
||||
cdlayer= CustomData_number_of_layers(&result->faceData, CD_MTFACE);
|
||||
if(cdlayer >= MAX_MTFACE)
|
||||
return result;
|
||||
CustomData_add_layer(&result->faceData, CD_MTFACE, CD_CALLOC, NULL, num_faces);
|
||||
tf = CustomData_get_layer(&result->faceData, CD_MTFACE);
|
||||
|
||||
ix = 1.0 / rx;
|
||||
iy = 1.0 / ry;
|
||||
#pragma omp parallel for private(x, y) if (rx > OMP_MIN_RES)
|
||||
for (y=0; y < res_y; y++) {
|
||||
for (x=0; x < res_x; x++) {
|
||||
const int i = y*res_x + x;
|
||||
tf[i].uv[0][0] = x * ix;
|
||||
tf[i].uv[0][1] = y * iy;
|
||||
|
||||
tf[i].uv[1][0] = (x+1) * ix;
|
||||
tf[i].uv[1][1] = y * iy;
|
||||
|
||||
tf[i].uv[2][0] = (x+1) * ix;
|
||||
tf[i].uv[2][1] = (y+1) * iy;
|
||||
|
||||
tf[i].uv[3][0] = x * ix;
|
||||
tf[i].uv[3][1] = (y+1) * iy;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
|
||||
DerivedMesh *derivedData,
|
||||
int UNUSED(useRenderParams))
|
||||
{
|
||||
OceanModifierData *omd = (OceanModifierData*) md;
|
||||
|
||||
DerivedMesh *dm=NULL;
|
||||
OceanResult ocr;
|
||||
|
||||
MVert *mv;
|
||||
MFace *mf;
|
||||
|
||||
int cdlayer;
|
||||
|
||||
int i, j;
|
||||
|
||||
int num_verts;
|
||||
int num_faces;
|
||||
|
||||
int cfra;
|
||||
|
||||
/* update modifier */
|
||||
if (omd->refresh & MOD_OCEAN_REFRESH_ADD)
|
||||
omd->ocean = BKE_add_ocean();
|
||||
if (omd->refresh & MOD_OCEAN_REFRESH_RESET)
|
||||
init_ocean_modifier(omd);
|
||||
if (omd->refresh & MOD_OCEAN_REFRESH_CLEAR_CACHE)
|
||||
clear_cache_data(omd);
|
||||
|
||||
omd->refresh = 0;
|
||||
|
||||
/* do ocean simulation */
|
||||
if (omd->cached == TRUE) {
|
||||
if (!omd->oceancache) init_cache_data(omd);
|
||||
BKE_simulate_ocean_cache(omd->oceancache, md->scene->r.cfra);
|
||||
} else {
|
||||
simulate_ocean_modifier(omd);
|
||||
}
|
||||
|
||||
if (omd->geometry_mode == MOD_OCEAN_GEOM_GENERATE)
|
||||
dm = generate_ocean_geometry(omd);
|
||||
else if (omd->geometry_mode == MOD_OCEAN_GEOM_DISPLACE) {
|
||||
dm = CDDM_copy(derivedData);
|
||||
}
|
||||
|
||||
cfra = md->scene->r.cfra;
|
||||
CLAMP(cfra, omd->bakestart, omd->bakeend);
|
||||
cfra -= omd->bakestart; // shift to 0 based
|
||||
|
||||
num_verts = dm->getNumVerts(dm);
|
||||
num_faces = dm->getNumFaces(dm);
|
||||
|
||||
/* add vcols before displacement - allows lookup based on position */
|
||||
|
||||
if (omd->flag & MOD_OCEAN_GENERATE_FOAM) {
|
||||
MCol *mc;
|
||||
float foam;
|
||||
char cf;
|
||||
|
||||
float u=0.0, v=0.0;
|
||||
|
||||
cdlayer= CustomData_number_of_layers(&dm->faceData, CD_MCOL);
|
||||
if(cdlayer >= MAX_MCOL)
|
||||
return dm;
|
||||
|
||||
CustomData_add_layer(&dm->faceData, CD_MCOL, CD_CALLOC, NULL, num_faces);
|
||||
|
||||
mc = dm->getFaceDataArray(dm, CD_MCOL);
|
||||
mv = dm->getVertArray(dm);
|
||||
mf = dm->getFaceArray(dm);
|
||||
|
||||
for (i = 0; i < num_faces; i++, mf++) {
|
||||
for (j=0; j<4; j++) {
|
||||
|
||||
if (j == 3 && !mf->v4) continue;
|
||||
|
||||
switch(j) {
|
||||
case 0:
|
||||
u = ocean_co(omd, mv[mf->v1].co[0]);
|
||||
v = ocean_co(omd, mv[mf->v1].co[1]);
|
||||
break;
|
||||
case 1:
|
||||
u = ocean_co(omd, mv[mf->v2].co[0]);
|
||||
v = ocean_co(omd, mv[mf->v2].co[1]);
|
||||
break;
|
||||
case 2:
|
||||
u = ocean_co(omd, mv[mf->v3].co[0]);
|
||||
v = ocean_co(omd, mv[mf->v3].co[1]);
|
||||
break;
|
||||
case 3:
|
||||
u = ocean_co(omd, mv[mf->v4].co[0]);
|
||||
v = ocean_co(omd, mv[mf->v4].co[1]);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (omd->oceancache && omd->cached==TRUE) {
|
||||
BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
|
||||
foam = ocr.foam;
|
||||
CLAMP(foam, 0.0, 1.0);
|
||||
} else {
|
||||
BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
|
||||
foam = BKE_ocean_jminus_to_foam(ocr.Jminus, omd->foam_coverage);
|
||||
}
|
||||
|
||||
cf = (char)(foam*255);
|
||||
mc[i*4 + j].r = mc[i*4 + j].g = mc[i*4 + j].b = cf;
|
||||
mc[i*4 + j].a = 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* displace the geometry */
|
||||
|
||||
mv = dm->getVertArray(dm);
|
||||
|
||||
//#pragma omp parallel for private(i, ocr) if (omd->resolution > OMP_MIN_RES)
|
||||
for (i=0; i< num_verts; i++) {
|
||||
const float u = ocean_co(omd, mv[i].co[0]);
|
||||
const float v = ocean_co(omd, mv[i].co[1]);
|
||||
|
||||
if (omd->oceancache && omd->cached==TRUE)
|
||||
BKE_ocean_cache_eval_uv(omd->oceancache, &ocr, cfra, u, v);
|
||||
else
|
||||
BKE_ocean_eval_uv(omd->ocean, &ocr, u, v);
|
||||
|
||||
mv[i].co[2] += ocr.disp[1];
|
||||
|
||||
if (omd->chop_amount > 0.0) {
|
||||
mv[i].co[0] += ocr.disp[0];
|
||||
mv[i].co[1] += ocr.disp[2];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return dm;
|
||||
}
|
||||
#else // WITH_OCEANSIM
|
||||
static DerivedMesh *doOcean(ModifierData *md, Object *UNUSED(ob),
|
||||
DerivedMesh *derivedData,
|
||||
int UNUSED(useRenderParams))
|
||||
{
|
||||
/* unused */
|
||||
(void)md;
|
||||
return derivedData;
|
||||
}
|
||||
#endif // WITH_OCEANSIM
|
||||
|
||||
static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
|
||||
DerivedMesh *derivedData,
|
||||
int UNUSED(useRenderParams),
|
||||
int UNUSED(isFinalCalc))
|
||||
{
|
||||
DerivedMesh *result;
|
||||
|
||||
result = doOcean(md, ob, derivedData, 0);
|
||||
|
||||
if(result != derivedData)
|
||||
CDDM_calc_normals(result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
static DerivedMesh *applyModifierEM(ModifierData *md, Object *ob,
|
||||
struct EditMesh *UNUSED(editData),
|
||||
DerivedMesh *derivedData)
|
||||
{
|
||||
return applyModifier(md, ob, derivedData, 0, 1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
ModifierTypeInfo modifierType_Ocean = {
|
||||
/* name */ "Ocean",
|
||||
/* structName */ "OceanModifierData",
|
||||
/* structSize */ sizeof(OceanModifierData),
|
||||
/* type */ eModifierTypeType_Constructive,
|
||||
/* flags */ eModifierTypeFlag_AcceptsMesh
|
||||
| eModifierTypeFlag_SupportsEditmode
|
||||
| eModifierTypeFlag_EnableInEditmode,
|
||||
|
||||
/* copyData */ copyData,
|
||||
/* deformMatrices */ 0,
|
||||
/* deformVerts */ 0,
|
||||
/* deformVertsEM */ 0,
|
||||
/* deformMatricesEM */ 0,
|
||||
/* applyModifier */ applyModifier,
|
||||
/* applyModifierEM */ applyModifierEM,
|
||||
/* initData */ initData,
|
||||
/* requiredDataMask */ requiredDataMask,
|
||||
/* freeData */ freeData,
|
||||
/* isDisabled */ 0,
|
||||
/* updateDepgraph */ 0,
|
||||
/* dependsOnTime */ 0,
|
||||
/* dependsOnNormals */ 0,
|
||||
/* foreachObjectLink */ 0,
|
||||
/* foreachIDLink */ 0,
|
||||
};
|
@ -260,6 +260,7 @@ void modifier_type_init(ModifierTypeInfo *types[])
|
||||
INIT_TYPE(Collision);
|
||||
INIT_TYPE(Boolean);
|
||||
INIT_TYPE(MeshDeform);
|
||||
INIT_TYPE(Ocean);
|
||||
INIT_TYPE(ParticleSystem);
|
||||
INIT_TYPE(ParticleInstance);
|
||||
INIT_TYPE(Explode);
|
||||
|
@ -74,6 +74,7 @@ set(SRC
|
||||
intern/source/sss.c
|
||||
intern/source/strand.c
|
||||
intern/source/sunsky.c
|
||||
intern/source/texture_ocean.c
|
||||
intern/source/volume_precache.c
|
||||
intern/source/volumetric.c
|
||||
intern/source/voxeldata.c
|
||||
@ -104,6 +105,7 @@ set(SRC
|
||||
intern/include/strand.h
|
||||
intern/include/sunsky.h
|
||||
intern/include/texture.h
|
||||
intern/include/texture_ocean.h
|
||||
intern/include/volume_precache.h
|
||||
intern/include/volumetric.h
|
||||
intern/include/voxeldata.h
|
||||
|
28
source/blender/render/intern/include/texture_ocean.h
Normal file
28
source/blender/render/intern/include/texture_ocean.h
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributors: Matt Ebb
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
void prepare_ocean_tex_modifier(struct OceanTex *ot);
|
||||
|
||||
int ocean_texture(struct Tex *tex, float *texvec, struct TexResult *texres);
|
@ -79,6 +79,7 @@
|
||||
#include "rendercore.h"
|
||||
#include "shading.h"
|
||||
#include "texture.h"
|
||||
#include "texture_ocean.h"
|
||||
|
||||
#include "renderdatabase.h" /* needed for UV */
|
||||
|
||||
@ -1264,7 +1265,9 @@ static int multitex(Tex *tex, float *texvec, float *dxt, float *dyt, int osatex,
|
||||
case TEX_VOXELDATA:
|
||||
retval= voxeldatatex(tex, texvec, texres);
|
||||
break;
|
||||
|
||||
case TEX_OCEAN:
|
||||
retval= ocean_texture(tex, texvec, texres);
|
||||
break;
|
||||
}
|
||||
|
||||
if (tex->flag & TEX_COLORBAND) {
|
||||
@ -2193,6 +2196,12 @@ void do_material_tex(ShadeInput *shi, Render *re)
|
||||
use_ntap_bump = 0;
|
||||
use_compat_bump = 1;
|
||||
}
|
||||
|
||||
/* case ocean */
|
||||
if(tex->type == TEX_OCEAN) {
|
||||
use_ntap_bump = 0;
|
||||
use_compat_bump = 0;
|
||||
}
|
||||
|
||||
/* which coords */
|
||||
if(mtex->texco==TEXCO_ORCO) {
|
||||
|
162
source/blender/render/intern/source/texture_ocean.c
Normal file
162
source/blender/render/intern/source/texture_ocean.c
Normal file
@ -0,0 +1,162 @@
|
||||
/*
|
||||
* ***** BEGIN GPL LICENSE BLOCK *****
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*
|
||||
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Contributors: Matt Ebb
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_modifier_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
#include "DNA_texture_types.h"
|
||||
|
||||
#include "BKE_global.h" /* XXX */
|
||||
|
||||
#include "BKE_modifier.h"
|
||||
#include "BKE_ocean.h"
|
||||
#include "BKE_utildefines.h"
|
||||
|
||||
#include "render_types.h"
|
||||
#include "RE_shader_ext.h"
|
||||
|
||||
#include "texture.h"
|
||||
|
||||
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
/* defined in pipeline.c, is hardcopy of active dynamic allocated Render */
|
||||
/* only to be used here in this file, it's for speed */
|
||||
extern struct Render R;
|
||||
/* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */
|
||||
|
||||
|
||||
|
||||
|
||||
/* ***** actual texture sampling ***** */
|
||||
int ocean_texture(Tex *tex, float *texvec, TexResult *texres)
|
||||
{
|
||||
int retval = TEX_INT;
|
||||
OceanTex *ot= tex->ot;
|
||||
OceanResult or;
|
||||
const float u = 0.5+0.5*texvec[0];
|
||||
const float v = 0.5+0.5*texvec[1];
|
||||
float foam;
|
||||
int cfra = R.r.cfra;
|
||||
int normals=0;
|
||||
ModifierData *md;
|
||||
|
||||
texres->tin = 0.0f;
|
||||
|
||||
if (!ot || !ot->object || !ot->object->modifiers.first)
|
||||
return 0;
|
||||
|
||||
if ((md = (ModifierData *)modifiers_findByType(ot->object, eModifierType_Ocean))) {
|
||||
OceanModifierData *omd = (OceanModifierData *)md;
|
||||
|
||||
if (!omd->ocean)
|
||||
return 0;
|
||||
|
||||
normals = (omd->flag & MOD_OCEAN_GENERATE_NORMALS);
|
||||
|
||||
if (omd->oceancache && omd->cached==TRUE) {
|
||||
|
||||
CLAMP(cfra, omd->bakestart, omd->bakeend);
|
||||
cfra -= omd->bakestart; // shift to 0 based
|
||||
|
||||
BKE_ocean_cache_eval_uv(omd->oceancache, &or, cfra, u, v);
|
||||
|
||||
} else { // non-cached
|
||||
|
||||
if (G.rendering)
|
||||
BKE_ocean_eval_uv_catrom(omd->ocean, &or, u, v);
|
||||
else
|
||||
BKE_ocean_eval_uv(omd->ocean, &or, u, v);
|
||||
|
||||
or.foam = BKE_ocean_jminus_to_foam(or.Jminus, omd->foam_coverage);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
switch (ot->output) {
|
||||
case TEX_OCN_DISPLACEMENT:
|
||||
/* XYZ displacement */
|
||||
texres->tr = 0.5 + 0.5 * or.disp[0];
|
||||
texres->tg = 0.5 + 0.5 * or.disp[2];
|
||||
texres->tb = 0.5 + 0.5 * or.disp[1];
|
||||
|
||||
texres->tr = MAX2(0.0, texres->tr);
|
||||
texres->tg = MAX2(0.0, texres->tg);
|
||||
texres->tb = MAX2(0.0, texres->tb);
|
||||
|
||||
BRICONTRGB;
|
||||
|
||||
retval = TEX_RGB;
|
||||
break;
|
||||
|
||||
case TEX_OCN_EMINUS:
|
||||
/* -ve eigenvectors ? */
|
||||
texres->tr = or.Eminus[0];
|
||||
texres->tg = or.Eminus[2];
|
||||
texres->tb = or.Eminus[1];
|
||||
retval = TEX_RGB;
|
||||
break;
|
||||
|
||||
case TEX_OCN_EPLUS:
|
||||
/* -ve eigenvectors ? */
|
||||
texres->tr = or.Eplus[0];
|
||||
texres->tg = or.Eplus[2];
|
||||
texres->tb = or.Eplus[1];
|
||||
retval = TEX_RGB;
|
||||
break;
|
||||
|
||||
case TEX_OCN_JPLUS:
|
||||
texres->tin = or.Jplus;
|
||||
retval = TEX_INT;
|
||||
case TEX_OCN_FOAM:
|
||||
|
||||
texres->tin = or.foam;
|
||||
|
||||
BRICONT;
|
||||
|
||||
retval = TEX_INT;
|
||||
break;
|
||||
}
|
||||
|
||||
/* if normals needed */
|
||||
|
||||
if (texres->nor && normals) {
|
||||
|
||||
texres->nor[0] = or.normal[0];
|
||||
texres->nor[1] = or.normal[2];
|
||||
texres->nor[2] = or.normal[1];
|
||||
|
||||
normalize_v3(texres->nor);
|
||||
retval |= TEX_NOR;
|
||||
}
|
||||
|
||||
texres->ta = 1.0;
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user