Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--release/scripts/startup/bl_ui/properties_physics_field.py4
-rw-r--r--source/blender/draw/intern/draw_cache.c255
-rw-r--r--source/blender/draw/intern/draw_cache.h8
-rw-r--r--source/blender/draw/intern/draw_common.c50
-rw-r--r--source/blender/draw/intern/draw_common.h3
-rw-r--r--source/blender/draw/modes/object_mode.c143
-rw-r--r--source/blender/gpu/CMakeLists.txt2
-rw-r--r--source/blender/gpu/GPU_shader.h4
-rw-r--r--source/blender/gpu/intern/gpu_shader.c11
-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.glsl4
-rw-r--r--source/blender/makesdna/DNA_object_force.h6
12 files changed, 488 insertions, 9 deletions
diff --git a/release/scripts/startup/bl_ui/properties_physics_field.py b/release/scripts/startup/bl_ui/properties_physics_field.py
index 2b12fcf982d..c01b9b939d5 100644
--- a/release/scripts/startup/bl_ui/properties_physics_field.py
+++ b/release/scripts/startup/bl_ui/properties_physics_field.py
@@ -39,7 +39,7 @@ class PhysicButtonsPanel:
class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
bl_label = "Force Fields"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'}
@classmethod
def poll(cls, context):
@@ -177,7 +177,7 @@ class PHYSICS_PT_field(PhysicButtonsPanel, Panel):
class PHYSICS_PT_collision(PhysicButtonsPanel, Panel):
bl_label = "Collision"
- COMPAT_ENGINES = {'BLENDER_RENDER'}
+ COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_CLAY'}
@classmethod
def poll(cls, context):
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;