diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2017-04-10 23:22:37 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2017-04-10 23:23:50 +0300 |
commit | 4f063dc4dd127c9945b345dff7f316645a2470a4 (patch) | |
tree | c06eb5b6bf344ad34291212dd1f2604d7218f9c5 /source/blender | |
parent | fb1ecbc2da9fe8ca569fc507275712a7645859fe (diff) |
Object Engine: Ported Force Field object drawing.
Diffstat (limited to 'source/blender')
-rw-r--r-- | source/blender/draw/intern/draw_cache.c | 255 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache.h | 8 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.c | 50 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_common.h | 3 | ||||
-rw-r--r-- | source/blender/draw/modes/object_mode.c | 143 | ||||
-rw-r--r-- | source/blender/gpu/CMakeLists.txt | 2 | ||||
-rw-r--r-- | source/blender/gpu/GPU_shader.h | 4 | ||||
-rw-r--r-- | source/blender/gpu/intern/gpu_shader.c | 11 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl (renamed from source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl) | 7 | ||||
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl | 4 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_object_force.h | 6 |
11 files changed, 486 insertions, 7 deletions
diff --git a/source/blender/draw/intern/draw_cache.c b/source/blender/draw/intern/draw_cache.c index 892df42072d..89ffa010145 100644 --- a/source/blender/draw/intern/draw_cache.c +++ b/source/blender/draw/intern/draw_cache.c @@ -40,6 +40,7 @@ static struct DRWShapeCache { Batch *drw_single_vertice; Batch *drw_fullscreen_quad; + Batch *drw_screenspace_circle; Batch *drw_plain_axes; Batch *drw_single_arrow; Batch *drw_cube; @@ -51,6 +52,11 @@ static struct DRWShapeCache { Batch *drw_empty_cone; Batch *drw_arrows; Batch *drw_axis_names; + Batch *drw_field_wind; + Batch *drw_field_force; + Batch *drw_field_vortex; + Batch *drw_field_tube_limit; + Batch *drw_field_cone_limit; Batch *drw_lamp; Batch *drw_lamp_sunrays; Batch *drw_lamp_area; @@ -96,6 +102,16 @@ void DRW_shape_cache_free(void) Batch_discard_all(SHC.drw_arrows); if (SHC.drw_axis_names) Batch_discard_all(SHC.drw_axis_names); + if (SHC.drw_field_wind) + Batch_discard_all(SHC.drw_field_wind); + if (SHC.drw_field_force) + Batch_discard_all(SHC.drw_field_force); + if (SHC.drw_field_vortex) + Batch_discard_all(SHC.drw_field_vortex); + if (SHC.drw_field_tube_limit) + Batch_discard_all(SHC.drw_field_tube_limit); + if (SHC.drw_field_cone_limit) + Batch_discard_all(SHC.drw_field_cone_limit); if (SHC.drw_lamp) Batch_discard_all(SHC.drw_lamp); if (SHC.drw_lamp_sunrays) @@ -399,7 +415,6 @@ Batch *DRW_cache_single_line_get(void) return SHC.drw_line; } - Batch *DRW_cache_single_line_endpoints_get(void) { /* Z axis line */ @@ -425,6 +440,34 @@ Batch *DRW_cache_single_line_endpoints_get(void) return SHC.drw_line_endpoints; } +Batch *DRW_cache_screenspace_circle_get(void) +{ +#define CIRCLE_RESOL 32 + if (!SHC.drw_screenspace_circle) { + float v[3] = {0.0f, 0.0f, 0.0f}; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, CIRCLE_RESOL + 1); + + for (int a = 0; a <= CIRCLE_RESOL; a++) { + v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + VertexBuffer_set_attrib(vbo, pos_id, a, v); + } + + SHC.drw_screenspace_circle = Batch_create(PRIM_LINE_STRIP, vbo, NULL); + } + return SHC.drw_screenspace_circle; +#undef CIRCLE_RESOL +} + /* Empties */ Batch *DRW_cache_plain_axes_get(void) { @@ -627,6 +670,216 @@ Batch *DRW_cache_axis_names_get(void) return SHC.drw_axis_names; } +/* Force Field */ +Batch *DRW_cache_field_wind_get(void) +{ +#define CIRCLE_RESOL 32 + if (!SHC.drw_field_wind) { + float v[3] = {0.0f, 0.0f, 0.0f}; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 4); + + for (int i = 0; i < 4; i++) { + float z = 0.05f * (float)i; + for (int a = 0; a < CIRCLE_RESOL; a++) { + v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2, v); + + v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); + } + } + + SHC.drw_field_wind = Batch_create(PRIM_LINES, vbo, NULL); + } + return SHC.drw_field_wind; +#undef CIRCLE_RESOL +} + +Batch *DRW_cache_field_force_get(void) +{ +#define CIRCLE_RESOL 32 + if (!SHC.drw_field_force) { + float v[3] = {0.0f, 0.0f, 0.0f}; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 3); + + for (int i = 0; i < 3; i++) { + float radius = 1.0f + 0.5f * (float)i; + for (int a = 0; a < CIRCLE_RESOL; a++) { + v[0] = radius * sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[1] = radius * cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[2] = 0.0f; + VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2, v); + + v[0] = radius * sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[1] = radius * cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[2] = 0.0f; + VertexBuffer_set_attrib(vbo, pos_id, i * CIRCLE_RESOL * 2 + a * 2 + 1, v); + } + } + + SHC.drw_field_force = Batch_create(PRIM_LINES, vbo, NULL); + } + return SHC.drw_field_force; +#undef CIRCLE_RESOL +} + +Batch *DRW_cache_field_vortex_get(void) +{ +#define SPIRAL_RESOL 32 + if (!SHC.drw_field_vortex) { + float v[3] = {0.0f, 0.0f, 0.0f}; + unsigned int v_idx = 0; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, SPIRAL_RESOL * 2 + 1); + + for (int a = SPIRAL_RESOL; a > -1; a--) { + v[0] = sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); + v[1] = cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); + + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + + for (int a = 1; a <= SPIRAL_RESOL; a++) { + v[0] = -sinf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); + v[1] = -cosf((2.0f * M_PI * a) / ((float)SPIRAL_RESOL)) * (a / (float)SPIRAL_RESOL); + + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + + SHC.drw_field_vortex = Batch_create(PRIM_LINE_STRIP, vbo, NULL); + } + return SHC.drw_field_vortex; +#undef SPIRAL_RESOL +} + +Batch *DRW_cache_field_tube_limit_get(void) +{ +#define CIRCLE_RESOL 32 + if (!SHC.drw_field_tube_limit) { + float v[3] = {0.0f, 0.0f, 0.0f}; + unsigned int v_idx = 0; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8); + + /* Caps */ + for (int i = 0; i < 2; i++) { + float z = (float)i * 2.0f - 1.0f; + for (int a = 0; a < CIRCLE_RESOL; a++) { + v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + + v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + } + /* Side Edges */ + for (int a = 0; a < 4; a++) { + for (int i = 0; i < 2; i++) { + float z = (float)i * 2.0f - 1.0f; + v[0] = sinf((2.0f * M_PI * a) / 4.0f); + v[1] = cosf((2.0f * M_PI * a) / 4.0f); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + } + + SHC.drw_field_tube_limit = Batch_create(PRIM_LINES, vbo, NULL); + } + return SHC.drw_field_tube_limit; +#undef CIRCLE_RESOL +} + +Batch *DRW_cache_field_cone_limit_get(void) +{ +#define CIRCLE_RESOL 32 + if (!SHC.drw_field_cone_limit) { + float v[3] = {0.0f, 0.0f, 0.0f}; + unsigned int v_idx = 0; + + /* Position Only 3D format */ + static VertexFormat format = { 0 }; + static unsigned int pos_id; + if (format.attrib_ct == 0) { + pos_id = VertexFormat_add_attrib(&format, "pos", COMP_F32, 3, KEEP_FLOAT); + } + + VertexBuffer *vbo = VertexBuffer_create_with_format(&format); + VertexBuffer_allocate_data(vbo, CIRCLE_RESOL * 2 * 2 + 8); + + /* Caps */ + for (int i = 0; i < 2; i++) { + float z = (float)i * 2.0f - 1.0f; + for (int a = 0; a < CIRCLE_RESOL; a++) { + v[0] = sinf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * a) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + + v[0] = sinf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[1] = cosf((2.0f * M_PI * (a + 1)) / ((float)CIRCLE_RESOL)); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + } + /* Side Edges */ + for (int a = 0; a < 4; a++) { + for (int i = 0; i < 2; i++) { + float z = (float)i * 2.0f - 1.0f; + v[0] = z * sinf((2.0f * M_PI * a) / 4.0f); + v[1] = z * cosf((2.0f * M_PI * a) / 4.0f); + v[2] = z; + VertexBuffer_set_attrib(vbo, pos_id, v_idx++, v); + } + } + + SHC.drw_field_cone_limit = Batch_create(PRIM_LINES, vbo, NULL); + } + return SHC.drw_field_cone_limit; +#undef CIRCLE_RESOL +} + /* Lamps */ Batch *DRW_cache_lamp_get(void) { diff --git a/source/blender/draw/intern/draw_cache.h b/source/blender/draw/intern/draw_cache.h index 0af7f3d08b1..94d3f57a832 100644 --- a/source/blender/draw/intern/draw_cache.h +++ b/source/blender/draw/intern/draw_cache.h @@ -36,6 +36,7 @@ struct Batch *DRW_cache_fullscreen_quad_get(void); struct Batch *DRW_cache_single_vert_get(void); struct Batch *DRW_cache_single_line_get(void); struct Batch *DRW_cache_single_line_endpoints_get(void); +struct Batch *DRW_cache_screenspace_circle_get(void); /* Empties */ struct Batch *DRW_cache_plain_axes_get(void); @@ -48,6 +49,13 @@ struct Batch *DRW_cache_empty_cone_get(void); struct Batch *DRW_cache_arrows_get(void); struct Batch *DRW_cache_axis_names_get(void); +/* Force Field */ +struct Batch *DRW_cache_field_wind_get(void); +struct Batch *DRW_cache_field_force_get(void); +struct Batch *DRW_cache_field_vortex_get(void); +struct Batch *DRW_cache_field_tube_limit_get(void); +struct Batch *DRW_cache_field_cone_limit_get(void); + /* Lamps */ struct Batch *DRW_cache_lamp_get(void); struct Batch *DRW_cache_lamp_sunrays_get(void); diff --git a/source/blender/draw/intern/draw_common.c b/source/blender/draw/intern/draw_common.c index 0ec2ed67ca2..e463956c9b2 100644 --- a/source/blender/draw/intern/draw_common.c +++ b/source/blender/draw/intern/draw_common.c @@ -187,6 +187,19 @@ DRWShadingGroup *shgroup_instance_objspace_wire(DRWPass *pass, struct Batch *geo return grp; } +DRWShadingGroup *shgroup_instance_screen_aligned(DRWPass *pass, struct Batch *geom) +{ + GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom); + DRW_shgroup_attrib_float(grp, "color", 3); + DRW_shgroup_attrib_float(grp, "size", 1); + DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + DRW_shgroup_uniform_vec3(grp, "screen_vecs", DRW_viewport_screenvecs_get(), 2); + + return grp; +} + DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom) { GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS); @@ -200,6 +213,18 @@ DRWShadingGroup *shgroup_instance_axis_names(DRWPass *pass, struct Batch *geom) return grp; } +DRWShadingGroup *shgroup_instance_scaled(DRWPass *pass, struct Batch *geom) +{ + GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE); + + DRWShadingGroup *grp = DRW_shgroup_instance_create(sh_inst, pass, geom); + DRW_shgroup_attrib_float(grp, "color", 3); + DRW_shgroup_attrib_float(grp, "size", 3); + DRW_shgroup_attrib_float(grp, "InstanceModelMatrix", 16); + + return grp; +} + DRWShadingGroup *shgroup_instance(DRWPass *pass, struct Batch *geom) { GPUShader *sh_inst = GPU_shader_get_builtin_shader(GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE); @@ -324,3 +349,28 @@ int DRW_object_wire_theme_get(Object *ob, SceneLayer *sl, float **color) return theme_id; } + +/* XXX This is utter shit, better find something more general */ +float *DRW_color_background_blend_get(int theme_id) +{ + static float colors[11][4]; + float *ret; + + switch (theme_id) { + case TH_WIRE_EDIT: ret = colors[0]; break; + case TH_ACTIVE: ret = colors[1]; break; + case TH_SELECT: ret = colors[2]; break; + case TH_GROUP: ret = colors[3]; break; + case TH_GROUP_ACTIVE: ret = colors[4]; break; + case TH_TRANSFORM: ret = colors[5]; break; + case OB_SPEAKER: ret = colors[6]; break; + case OB_CAMERA: ret = colors[7]; break; + case OB_EMPTY: ret = colors[8]; break; + case OB_LAMP: ret = colors[9]; break; + default: ret = colors[10]; break; + } + + UI_GetThemeColorBlendShade4fv(theme_id, TH_BACK, 0.5, -16, ret); + + return ret; +}
\ No newline at end of file diff --git a/source/blender/draw/intern/draw_common.h b/source/blender/draw/intern/draw_common.h index e8e7cf40432..be41103f907 100644 --- a/source/blender/draw/intern/draw_common.h +++ b/source/blender/draw/intern/draw_common.h @@ -92,13 +92,16 @@ struct DRWShadingGroup *shgroup_groundpoints_uniform_color(struct DRWPass *pass, struct DRWShadingGroup *shgroup_instance_screenspace(struct DRWPass *pass, struct Batch *geom, float *size); struct DRWShadingGroup *shgroup_instance_objspace_solid(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]); struct DRWShadingGroup *shgroup_instance_objspace_wire(struct DRWPass *pass, struct Batch *geom, float (*obmat)[4]); +struct DRWShadingGroup *shgroup_instance_screen_aligned(struct DRWPass *pass, struct Batch *geom); struct DRWShadingGroup *shgroup_instance_axis_names(struct DRWPass *pass, struct Batch *geom); +struct DRWShadingGroup *shgroup_instance_scaled(struct DRWPass *pass, struct Batch *geom); struct DRWShadingGroup *shgroup_instance(struct DRWPass *pass, struct Batch *geom); struct DRWShadingGroup *shgroup_camera_instance(struct DRWPass *pass, struct Batch *geom); struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, struct Batch *geom); struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Batch *geom); int DRW_object_wire_theme_get(struct Object *ob, struct SceneLayer *sl, float **color); +float *DRW_color_background_blend_get(int theme_id); /* draw_armature.c */ void DRW_shgroup_armature_object( diff --git a/source/blender/draw/modes/object_mode.c b/source/blender/draw/modes/object_mode.c index 5588a8075fe..1d89455e3ee 100644 --- a/source/blender/draw/modes/object_mode.c +++ b/source/blender/draw/modes/object_mode.c @@ -29,10 +29,14 @@ #include "DNA_userdef_types.h" #include "DNA_armature_types.h" #include "DNA_camera_types.h" +#include "DNA_curve_types.h" +#include "DNA_object_force.h" #include "DNA_view3d_types.h" #include "DNA_world_types.h" +#include "BKE_anim.h" #include "BKE_camera.h" +#include "BKE_curve.h" #include "BKE_global.h" #include "ED_view3d.h" @@ -114,6 +118,15 @@ typedef struct g_data{ DRWShadingGroup *arrows; DRWShadingGroup *axis_names; + /* Force Field */ + DRWShadingGroup *field_wind; + DRWShadingGroup *field_force; + DRWShadingGroup *field_vortex; + DRWShadingGroup *field_curve_sta; + DRWShadingGroup *field_curve_end; + DRWShadingGroup *field_tube_limit; + DRWShadingGroup *field_cone_limit; + /* Speaker */ DRWShadingGroup *speaker; @@ -572,6 +585,19 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_axis_names_get(); stl->g_data->axis_names = shgroup_instance_axis_names(psl->non_meshes, geom); + /* Force Field */ + geom = DRW_cache_field_wind_get(); + stl->g_data->field_wind = shgroup_instance_scaled(psl->non_meshes, geom); + + geom = DRW_cache_field_force_get(); + stl->g_data->field_force = shgroup_instance_screen_aligned(psl->non_meshes, geom); + + geom = DRW_cache_field_vortex_get(); + stl->g_data->field_vortex = shgroup_instance_scaled(psl->non_meshes, geom); + + geom = DRW_cache_screenspace_circle_get(); + stl->g_data->field_curve_sta = shgroup_instance_screen_aligned(psl->non_meshes, geom); + /* Speaker */ geom = DRW_cache_speaker_get(); stl->g_data->speaker = shgroup_instance(psl->non_meshes, geom); @@ -640,9 +666,23 @@ static void OBJECT_cache_init(void *vedata) geom = DRW_cache_square_get(); stl->g_data->lamp_spot_blend_rect = shgroup_instance(psl->non_meshes, geom); + /* -------- STIPPLES ------- */ + /* TODO port to shader stipple */ + /* Relationship Lines */ stl->g_data->relationship_lines = shgroup_dynlines_uniform_color(psl->non_meshes, ts.colorWire); DRW_shgroup_state_set(stl->g_data->relationship_lines, DRW_STATE_STIPPLE_3); + + /* Force Field Curve Guide End (here because of stipple) */ + geom = DRW_cache_screenspace_circle_get(); + stl->g_data->field_curve_end = shgroup_instance_screen_aligned(psl->non_meshes, geom); + + /* Force Field Limits */ + geom = DRW_cache_field_tube_limit_get(); + stl->g_data->field_tube_limit = shgroup_instance_scaled(psl->non_meshes, geom); + + geom = DRW_cache_field_cone_limit_get(); + stl->g_data->field_cone_limit = shgroup_instance_scaled(psl->non_meshes, geom); } { @@ -889,6 +929,105 @@ static void DRW_shgroup_empty(OBJECT_StorageList *stl, Object *ob, SceneLayer *s } } +static void DRW_shgroup_forcefield(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl) +{ + int theme_id = DRW_object_wire_theme_get(ob, sl, NULL); + float *color = DRW_color_background_blend_get(theme_id); + PartDeflect *pd = ob->pd; + Curve *cu = (ob->type == OB_CURVE) ? ob->data : NULL; + + /* TODO Move this to depsgraph */ + float tmp[3]; + copy_v3_fl(pd->drawvec1, ob->empty_drawsize); + + switch (pd->forcefield) { + case PFIELD_WIND: + pd->drawvec1[2] = pd->f_strength; + break; + case PFIELD_VORTEX: + if (pd->f_strength < 0.0f) { + pd->drawvec1[1] = -pd->drawvec1[1]; + } + break; + case PFIELD_GUIDE: + if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + where_on_path(ob, 0.0f, pd->drawvec1, tmp, NULL, NULL, NULL); + where_on_path(ob, 1.0f, pd->drawvec2, tmp, NULL, NULL, NULL); + } + break; + } + + if (pd->falloff == PFIELD_FALL_TUBE) { + pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = (pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f; + pd->drawvec_falloff_max[2] = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; + + pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = (pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f; + pd->drawvec_falloff_min[2] = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; + } + else if (pd->falloff == PFIELD_FALL_CONE) { + float radius, distance; + + radius = DEG2RADF((pd->flag & PFIELD_USEMAXR) ? pd->maxrad : 1.0f); + distance = (pd->flag & PFIELD_USEMAX) ? pd->maxdist : 0.0f; + pd->drawvec_falloff_max[0] = pd->drawvec_falloff_max[1] = distance * sinf(radius); + pd->drawvec_falloff_max[2] = distance * cosf(radius); + + radius = DEG2RADF((pd->flag & PFIELD_USEMINR) ? pd->minrad : 1.0f); + distance = (pd->flag & PFIELD_USEMIN) ? pd->mindist : 0.0f; + + pd->drawvec_falloff_min[0] = pd->drawvec_falloff_min[1] = distance * sinf(radius); + pd->drawvec_falloff_min[2] = distance * cosf(radius); + } + /* End of things that should go to depthgraph */ + + switch (pd->forcefield) { + case PFIELD_WIND: + DRW_shgroup_dynamic_call_add(stl->g_data->field_wind, color, &pd->drawvec1, ob->obmat); + break; + case PFIELD_FORCE: + DRW_shgroup_dynamic_call_add(stl->g_data->field_force, color, &pd->drawvec1, ob->obmat); + break; + case PFIELD_VORTEX: + DRW_shgroup_dynamic_call_add(stl->g_data->field_vortex, color, &pd->drawvec1, ob->obmat); + break; + case PFIELD_GUIDE: + if (cu && (cu->flag & CU_PATH) && ob->curve_cache->path && ob->curve_cache->path->data) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_sta, color, &pd->f_strength, ob->obmat); + DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->f_strength, ob->obmat); + } + break; + } + + if (pd->falloff == PFIELD_FALL_SPHERE) { + /* as last, guide curve alters it */ + if ((pd->flag & PFIELD_USEMAX) != 0) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->maxdist, ob->obmat); + } + + if ((pd->flag & PFIELD_USEMIN) != 0) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_curve_end, color, &pd->mindist, ob->obmat); + } + } + else if (pd->falloff == PFIELD_FALL_TUBE) { + if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_max, ob->obmat); + } + + if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_tube_limit, color, &pd->drawvec_falloff_min, ob->obmat); + } + } + else if (pd->falloff == PFIELD_FALL_CONE) { + if (pd->flag & (PFIELD_USEMAX | PFIELD_USEMAXR)) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_max, ob->obmat); + } + + if (pd->flag & (PFIELD_USEMIN | PFIELD_USEMINR)) { + DRW_shgroup_dynamic_call_add(stl->g_data->field_cone_limit, color, &pd->drawvec_falloff_min, ob->obmat); + } + } +} + static void DRW_shgroup_speaker(OBJECT_StorageList *stl, Object *ob, SceneLayer *sl) { float *color; @@ -980,6 +1119,10 @@ static void OBJECT_cache_populate(void *vedata, Object *ob) break; } + if (ob->pd && ob->pd->forcefield) { + DRW_shgroup_forcefield(stl, ob, sl); + } + DRW_shgroup_object_center(stl, ob); DRW_shgroup_relationship_lines(stl, ob); } diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt index 6a61b93e621..f2b13d860dd 100644 --- a/source/blender/gpu/CMakeLists.txt +++ b/source/blender/gpu/CMakeLists.txt @@ -157,7 +157,7 @@ data_to_c_simple(shaders/gpu_shader_instance_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_objectspace_variying_color_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_screenspace_variying_color_vert.glsl SRC) -data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl SRC) +data_to_c_simple(shaders/gpu_shader_instance_screen_aligned_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_camera_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_distance_line_vert.glsl SRC) data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC) diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h index 5eb137c69c6..6783dee7201 100644 --- a/source/blender/gpu/GPU_shader.h +++ b/source/blender/gpu/GPU_shader.h @@ -155,9 +155,11 @@ typedef enum GPUBuiltinShader { GPU_SHADER_DISTANCE_LINES, /* axis name */ GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS, + GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED, /* instance */ GPU_SHADER_INSTANCE_UNIFORM_COLOR, - GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, + GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE, /* Uniformly scaled */ + GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE, GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR, GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */ diff --git a/source/blender/gpu/intern/gpu_shader.c b/source/blender/gpu/intern/gpu_shader.c index 984bad1f6c0..7ea148e15d6 100644 --- a/source/blender/gpu/intern/gpu_shader.c +++ b/source/blender/gpu/intern/gpu_shader.c @@ -80,7 +80,7 @@ extern char datatoc_gpu_shader_instance_vert_glsl[]; extern char datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl[]; extern char datatoc_gpu_shader_instance_objectspace_variying_color_vert_glsl[]; extern char datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl[]; -extern char datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl[]; +extern char datatoc_gpu_shader_instance_screen_aligned_vert_glsl[]; extern char datatoc_gpu_shader_instance_camera_vert_glsl[]; extern char datatoc_gpu_shader_instance_distance_line_vert_glsl[]; extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[]; @@ -712,8 +712,10 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) datatoc_gpu_shader_flat_color_frag_glsl}, [GPU_SHADER_3D_SCREENSPACE_VARIYING_COLOR] = { datatoc_gpu_shader_instance_screenspace_variying_color_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl}, - [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_axis_name_vert_glsl, + [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl}, + [GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED] = { datatoc_gpu_shader_instance_screen_aligned_vert_glsl, + datatoc_gpu_shader_flat_color_frag_glsl}, [GPU_SHADER_CAMERA] = { datatoc_gpu_shader_instance_camera_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl}, @@ -754,6 +756,9 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] = { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl }, + [GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SCALE] = + { datatoc_gpu_shader_instance_variying_size_variying_color_vert_glsl, + datatoc_gpu_shader_flat_color_frag_glsl }, [GPU_SHADER_INSTANCE_EDGES_VARIYING_COLOR] = { datatoc_gpu_shader_instance_edges_variying_color_vert_glsl, datatoc_gpu_shader_flat_color_frag_glsl, datatoc_gpu_shader_instance_edges_variying_color_geom_glsl}, @@ -763,6 +768,8 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader) /* just a few special cases */ const char *defines = (shader == GPU_SHADER_SMOKE_COBA) ? "#define USE_COBA;\n" : (shader == GPU_SHADER_SIMPLE_LIGHTING) ? "#define USE_NORMALS;\n" : + (shader == GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE) ? "#define UNIFORM_SCALE;\n" : + (shader == GPU_SHADER_3D_INSTANCE_SCREEN_ALIGNED_AXIS) ? "#define AXIS_NAME;\n" : (shader == GPU_SHADER_3D_OBJECTSPACE_SIMPLE_LIGHTING_VARIYING_COLOR) ? "#define USE_INSTANCE_COLOR;\n" : NULL; const GPUShaderStages *stages = builtin_shader_stages + shader; diff --git a/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl index a39bfde41ee..2ee74b3eae0 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_axis_name_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_screen_aligned_vert.glsl @@ -14,16 +14,19 @@ flat out vec4 finalColor; void main() { - vec3 offset; + vec3 offset = vec3(0.0); +#ifdef AXIS_NAME if (pos.z == 0.0) offset = vec3(1.125, 0.0, 0.0); else if (pos.z == 1.0) offset = vec3(0.0, 1.125, 0.0); else offset = vec3(0.0, 0.0, 1.125); + offset *= size; +#endif vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y; - gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset * size, 1.0) + vec4(screen_pos * size, 0.0)); + gl_Position = ViewProjectionMatrix * (InstanceModelMatrix * vec4(offset, 1.0) + vec4(screen_pos * size, 0.0)); finalColor = vec4(color, 1.0); } diff --git a/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl index 9ade68644fe..10a2ba61a2c 100644 --- a/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl +++ b/source/blender/gpu/shaders/gpu_shader_instance_variying_size_variying_color_vert.glsl @@ -7,7 +7,11 @@ in vec3 pos; /* ---- Per instance Attribs ---- */ in mat4 InstanceModelMatrix; in vec3 color; +#ifdef UNIFORM_SCALE in float size; +#else +in vec3 size; +#endif flat out vec4 finalColor; diff --git a/source/blender/makesdna/DNA_object_force.h b/source/blender/makesdna/DNA_object_force.h index ed14c4b9311..9413a21633b 100644 --- a/source/blender/makesdna/DNA_object_force.h +++ b/source/blender/makesdna/DNA_object_force.h @@ -112,6 +112,12 @@ typedef struct PartDeflect { float f_noise; /* noise of force */ int seed; /* noise random seed */ + /* Display Size */ + float drawvec1[4]; /* Runtime only : start of the curve or draw scale */ + float drawvec2[4]; /* Runtime only : end of the curve */ + float drawvec_falloff_min[3], pad1; /* Runtime only */ + float drawvec_falloff_max[3], pad2; /* Runtime only */ + struct Object *f_source; /* force source object */ } PartDeflect; |