Fix T51210: Draw Manager: Support for Metaball Drawing
Differential Revision: D2914
This commit is contained in:
parent
562da211c2
commit
88c88c4610
Notes:
blender-bot
2024-01-16 18:05:25 +01:00
Referenced by issue #51210, Implement meta-ball drawing for object & edit mode.
|
@ -75,5 +75,16 @@ struct EvaluationContext;
|
|||
|
||||
void BKE_mball_eval_geometry(const struct EvaluationContext *eval_ctx,
|
||||
struct MetaBall *mball);
|
||||
/* Draw Cache */
|
||||
|
||||
void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4],
|
||||
const float obmat[4][4],
|
||||
const float local_pos[3]);
|
||||
|
||||
enum {
|
||||
BKE_MBALL_BATCH_DIRTY_ALL = 0,
|
||||
};
|
||||
void BKE_mball_batch_cache_dirty(struct MetaBall *mb, int mode);
|
||||
void BKE_mball_batch_cache_free(struct MetaBall *mb);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -75,6 +75,8 @@ void BKE_mball_free(MetaBall *mb)
|
|||
{
|
||||
BKE_animdata_free((ID *)mb, false);
|
||||
|
||||
BKE_mball_batch_cache_free(mb);
|
||||
|
||||
MEM_SAFE_FREE(mb->mat);
|
||||
|
||||
BLI_freelistN(&mb->elems);
|
||||
|
@ -120,6 +122,7 @@ void BKE_mball_copy_data(Main *UNUSED(bmain), MetaBall *mb_dst, const MetaBall *
|
|||
|
||||
mb_dst->editelems = NULL;
|
||||
mb_dst->lastelem = NULL;
|
||||
mb_dst->batch_cache = NULL;
|
||||
}
|
||||
|
||||
MetaBall *BKE_mball_copy(Main *bmain, const MetaBall *mb)
|
||||
|
@ -542,3 +545,47 @@ void BKE_mball_eval_geometry(const struct EvaluationContext *UNUSED(eval_ctx),
|
|||
MetaBall *UNUSED(mball))
|
||||
{
|
||||
}
|
||||
|
||||
/* Draw Engine */
|
||||
|
||||
/* use for draw-manager only. */
|
||||
void BKE_mball_element_calc_display_m3x4(float r_scale_xform[3][4],
|
||||
const float obmat[4][4],
|
||||
const float local_pos[3])
|
||||
{
|
||||
float world_pos[3], scamat[3][3];
|
||||
mul_v3_m4v3(world_pos, obmat, local_pos);
|
||||
copy_m3_m4(scamat, obmat);
|
||||
{
|
||||
/* Get the normalized inverse matrix to extract only
|
||||
* the scale of Scamat */
|
||||
float iscamat[3][3];
|
||||
invert_m3_m3(iscamat, scamat);
|
||||
normalize_m3(iscamat);
|
||||
mul_m3_m3_post(scamat, iscamat);
|
||||
}
|
||||
|
||||
copy_v3_v3(r_scale_xform[0], scamat[0]);
|
||||
copy_v3_v3(r_scale_xform[1], scamat[1]);
|
||||
copy_v3_v3(r_scale_xform[2], scamat[2]);
|
||||
|
||||
r_scale_xform[0][3] = world_pos[0];
|
||||
r_scale_xform[1][3] = world_pos[1];
|
||||
r_scale_xform[2][3] = world_pos[2];
|
||||
}
|
||||
|
||||
void (*BKE_mball_batch_cache_dirty_cb)(MetaBall *mb, int mode) = NULL;
|
||||
void (*BKE_mball_batch_cache_free_cb)(MetaBall *mb) = NULL;
|
||||
|
||||
void BKE_mball_batch_cache_dirty(MetaBall *mb, int mode)
|
||||
{
|
||||
if (mb->batch_cache) {
|
||||
BKE_mball_batch_cache_dirty_cb(mb, mode);
|
||||
}
|
||||
}
|
||||
void BKE_mball_batch_cache_free(MetaBall *mb)
|
||||
{
|
||||
if (mb->batch_cache) {
|
||||
BKE_mball_batch_cache_free_cb(mb);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -58,6 +58,7 @@
|
|||
#include "BKE_pointcache.h"
|
||||
#include "BKE_scene.h"
|
||||
#include "BKE_material.h"
|
||||
#include "BKE_mball.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_image.h"
|
||||
|
||||
|
@ -322,6 +323,9 @@ void BKE_object_eval_uber_data(const EvaluationContext *eval_ctx,
|
|||
case OB_SURF:
|
||||
BKE_curve_batch_cache_dirty(ob->data, BKE_CURVE_BATCH_DIRTY_ALL);
|
||||
break;
|
||||
case OB_MBALL:
|
||||
BKE_mball_batch_cache_dirty(ob->data, BKE_MBALL_BATCH_DIRTY_ALL);
|
||||
break;
|
||||
}
|
||||
|
||||
if (DEG_depsgraph_use_copy_on_write()) {
|
||||
|
|
|
@ -3692,6 +3692,7 @@ static void direct_link_mball(FileData *fd, MetaBall *mb)
|
|||
mb->editelems = NULL;
|
||||
/* mb->edit_elems.first= mb->edit_elems.last= NULL;*/
|
||||
mb->lastelem = NULL;
|
||||
mb->batch_cache = NULL;
|
||||
}
|
||||
|
||||
/* ************ READ WORLD ***************** */
|
||||
|
|
|
@ -59,6 +59,7 @@ set(SRC
|
|||
intern/draw_cache_impl_displist.c
|
||||
intern/draw_cache_impl_lattice.c
|
||||
intern/draw_cache_impl_mesh.c
|
||||
intern/draw_cache_impl_metaball.c
|
||||
intern/draw_cache_impl_particles.c
|
||||
intern/draw_common.c
|
||||
intern/draw_manager.c
|
||||
|
|
|
@ -507,6 +507,8 @@ Gwn_Batch *DRW_cache_object_surface_get(Object *ob)
|
|||
return DRW_cache_surf_surface_get(ob);
|
||||
case OB_FONT:
|
||||
return DRW_cache_text_surface_get(ob);
|
||||
case OB_MBALL:
|
||||
return DRW_cache_mball_surface_get(ob);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
@ -2336,6 +2338,19 @@ Gwn_Batch *DRW_cache_curve_surface_get(Object *ob)
|
|||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name MetaBall
|
||||
* \{ */
|
||||
|
||||
Gwn_Batch *DRW_cache_mball_surface_get(Object *ob)
|
||||
{
|
||||
BLI_assert(ob->type == OB_MBALL);
|
||||
return DRW_metaball_batch_cache_get_triangles_with_normals(ob);
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Font
|
||||
* \{ */
|
||||
|
||||
|
|
|
@ -157,4 +157,7 @@ struct Gwn_Batch *DRW_cache_particles_get_hair(struct ParticleSystem *psys, stru
|
|||
struct Gwn_Batch *DRW_cache_particles_get_dots(struct ParticleSystem *psys);
|
||||
struct Gwn_Batch *DRW_cache_particles_get_prim(int type);
|
||||
|
||||
/* Metaball */
|
||||
struct Gwn_Batch *DRW_cache_mball_surface_get(struct Object *ob);
|
||||
|
||||
#endif /* __DRAW_CACHE_H__ */
|
||||
|
|
|
@ -38,6 +38,9 @@ struct Lattice;
|
|||
struct Mesh;
|
||||
|
||||
/* Expose via BKE callbacks */
|
||||
void DRW_mball_batch_cache_dirty(struct MetaBall *mb, int mode);
|
||||
void DRW_mball_batch_cache_free(struct MetaBall *mb);
|
||||
|
||||
void DRW_curve_batch_cache_dirty(struct Curve *cu, int mode);
|
||||
void DRW_curve_batch_cache_free(struct Curve *cu);
|
||||
|
||||
|
@ -59,6 +62,9 @@ struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_verts(struct Curve *cu);
|
|||
|
||||
struct Gwn_Batch *DRW_curve_batch_cache_get_triangles_with_normals(struct Curve *cu, struct CurveCache *ob_curve_cache);
|
||||
|
||||
/* Metaball */
|
||||
struct Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(struct Object *ob);
|
||||
|
||||
/* Curve (Font) */
|
||||
struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_cursor(struct Curve *cu);
|
||||
struct Gwn_Batch *DRW_curve_batch_cache_get_overlay_select(struct Curve *cu);
|
||||
|
|
|
@ -136,27 +136,31 @@ Gwn_Batch *BLI_displist_batch_calc_surface(ListBase *lb)
|
|||
GWN_indexbuf_init(&elb, GWN_PRIM_TRIS, tri_len, vert_len);
|
||||
|
||||
int ofs = 0;
|
||||
int tri_len_used = 0;
|
||||
for (const DispList *dl = lb->first; dl; dl = dl->next) {
|
||||
if (ELEM(dl->type, DL_INDEX3, DL_INDEX4, DL_SURF)) {
|
||||
const int *idx = dl->index;
|
||||
if (dl->type == DL_INDEX3) {
|
||||
const int *idx = dl->index;
|
||||
const int i_end = dl->parts;
|
||||
for (int i = 0; i < i_end; i++) {
|
||||
for (int i = 0; i < i_end; i++, idx += 3) {
|
||||
GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
|
||||
tri_len_used += 1;
|
||||
idx += 3;
|
||||
}
|
||||
}
|
||||
else if (ELEM(dl->type, DL_INDEX4, DL_SURF)) {
|
||||
const int *idx = dl->index;
|
||||
else if (dl->type == DL_SURF) {
|
||||
const int i_end = dl->totindex;
|
||||
for (int i = 0; i < i_end; i++) {
|
||||
for (int i = 0; i < i_end; i++, idx += 4) {
|
||||
GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
|
||||
tri_len_used += 1;
|
||||
GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
|
||||
tri_len_used += 1;
|
||||
idx += 4;
|
||||
}
|
||||
}
|
||||
else {
|
||||
BLI_assert(dl->type == DL_INDEX4);
|
||||
const int i_end = dl->parts;
|
||||
for (int i = 0; i < i_end; i++, idx += 4) {
|
||||
GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[1] + ofs, idx[2] + ofs);
|
||||
|
||||
if (idx[2] != idx[3]) {
|
||||
GWN_indexbuf_add_tri_verts(&elb, idx[0] + ofs, idx[2] + ofs, idx[3] + ofs);
|
||||
}
|
||||
}
|
||||
}
|
||||
ofs += dl_vert_len(dl);
|
||||
|
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* ***** 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) 2017 by Blender Foundation.
|
||||
* All rights reserved.
|
||||
*
|
||||
* ***** END GPL LICENSE BLOCK *****
|
||||
*/
|
||||
|
||||
/** \file draw_cache_impl_metaball.c
|
||||
* \ingroup draw
|
||||
*
|
||||
* \brief MetaBall API for render engines
|
||||
*/
|
||||
|
||||
#include "MEM_guardedalloc.h"
|
||||
|
||||
#include "BLI_utildefines.h"
|
||||
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_object_types.h"
|
||||
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_mball.h"
|
||||
|
||||
#include "GPU_batch.h"
|
||||
|
||||
#include "draw_cache_impl.h" /* own include */
|
||||
|
||||
|
||||
static void metaball_batch_cache_clear(MetaBall *mb);
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* MetaBall Interface, indirect, partially cached access to complex data. */
|
||||
|
||||
typedef struct MetaBallRenderData {
|
||||
int types;
|
||||
|
||||
/* borrow from 'Object' */
|
||||
CurveCache *ob_curve_cache;
|
||||
} MetaBallRenderData;
|
||||
|
||||
enum {
|
||||
/* Geometry */
|
||||
MBALL_DATATYPE_SURFACE = 1 << 0,
|
||||
// MBALL_DATATYPE_WIRE = 1 << 1,
|
||||
// MBALL_DATATYPE_SHADING = 1 << 2,
|
||||
};
|
||||
|
||||
static MetaBallRenderData *metaball_render_data_create(MetaBall *mb, CurveCache *ob_curve_cache, const int types)
|
||||
{
|
||||
MetaBallRenderData *rdata = MEM_callocN(sizeof(*rdata), __func__);
|
||||
rdata->types = types;
|
||||
rdata->ob_curve_cache = ob_curve_cache;
|
||||
|
||||
/*
|
||||
**TODO**
|
||||
if (types & MBALL_DATATYPE_WIRE) {}
|
||||
if (types & MBALL_DATATYPE_SHADING) {}
|
||||
*/
|
||||
|
||||
return rdata;
|
||||
}
|
||||
|
||||
static void metaball_render_data_free(MetaBallRenderData *rdata)
|
||||
{
|
||||
MEM_freeN(rdata);
|
||||
}
|
||||
|
||||
/* ---------------------------------------------------------------------- */
|
||||
/* MetaBall Gwn_Batch Cache */
|
||||
|
||||
typedef struct MetaBallBatchCache {
|
||||
Gwn_Batch *batch;
|
||||
|
||||
/* settings to determine if cache is invalid */
|
||||
bool is_dirty;
|
||||
} MetaBallBatchCache;
|
||||
|
||||
/* Gwn_Batch cache management. */
|
||||
|
||||
static bool metaball_batch_cache_valid(MetaBall *mb)
|
||||
{
|
||||
MetaBallBatchCache *cache = mb->batch_cache;
|
||||
|
||||
if (cache == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return cache->is_dirty == false;
|
||||
}
|
||||
|
||||
static void metaball_batch_cache_init(MetaBall *mb)
|
||||
{
|
||||
MetaBallBatchCache *cache = mb->batch_cache;
|
||||
|
||||
if (!cache) {
|
||||
cache = mb->batch_cache = MEM_mallocN(sizeof(*cache), __func__);
|
||||
}
|
||||
cache->batch = NULL;
|
||||
cache->is_dirty = false;
|
||||
}
|
||||
|
||||
static MetaBallBatchCache *metaball_batch_cache_get(MetaBall *mb)
|
||||
{
|
||||
if (!metaball_batch_cache_valid(mb)) {
|
||||
metaball_batch_cache_clear(mb);
|
||||
metaball_batch_cache_init(mb);
|
||||
}
|
||||
return mb->batch_cache;
|
||||
}
|
||||
|
||||
void DRW_mball_batch_cache_dirty(MetaBall *mb, int mode)
|
||||
{
|
||||
MetaBallBatchCache *cache = mb->batch_cache;
|
||||
if (cache == NULL) {
|
||||
return;
|
||||
}
|
||||
switch (mode) {
|
||||
case BKE_MBALL_BATCH_DIRTY_ALL:
|
||||
cache->is_dirty = true;
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
static void metaball_batch_cache_clear(MetaBall *mb)
|
||||
{
|
||||
MetaBallBatchCache *cache = mb->batch_cache;
|
||||
if (!cache) {
|
||||
return;
|
||||
}
|
||||
|
||||
GWN_BATCH_DISCARD_SAFE(cache->batch);
|
||||
}
|
||||
|
||||
void DRW_mball_batch_cache_free(MetaBall *mb)
|
||||
{
|
||||
metaball_batch_cache_clear(mb);
|
||||
MEM_SAFE_FREE(mb->batch_cache);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Private MetaBall Cache API
|
||||
* \{ */
|
||||
|
||||
/* Gwn_Batch cache usage. */
|
||||
|
||||
static Gwn_Batch *metaball_batch_cache_get_pos_and_normals(MetaBallRenderData *rdata, MetaBallBatchCache *cache)
|
||||
{
|
||||
BLI_assert(rdata->types & MBALL_DATATYPE_SURFACE);
|
||||
if (cache->batch == NULL) {
|
||||
cache->batch = BLI_displist_batch_calc_surface(&rdata->ob_curve_cache->disp);
|
||||
}
|
||||
return cache->batch;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
||||
/** \name Public Object/MetaBall API
|
||||
* \{ */
|
||||
|
||||
Gwn_Batch *DRW_metaball_batch_cache_get_triangles_with_normals(Object *ob)
|
||||
{
|
||||
if (!BKE_mball_is_basis(ob))
|
||||
return NULL;
|
||||
|
||||
MetaBall *mb = ob->data;
|
||||
MetaBallBatchCache *cache = metaball_batch_cache_get(mb);
|
||||
|
||||
if (cache->batch == NULL) {
|
||||
MetaBallRenderData *rdata = metaball_render_data_create(mb, ob->curve_cache, MBALL_DATATYPE_SURFACE);
|
||||
metaball_batch_cache_get_pos_and_normals(rdata, cache);
|
||||
metaball_render_data_free(rdata);
|
||||
}
|
||||
|
||||
return cache->batch;
|
||||
}
|
|
@ -352,6 +352,19 @@ DRWShadingGroup *shgroup_instance_bone_envelope_solid(DRWPass *pass, struct Gwn_
|
|||
return grp;
|
||||
}
|
||||
|
||||
DRWShadingGroup *shgroup_instance_mball_helpers(DRWPass *pass, struct Gwn_Batch *geom)
|
||||
{
|
||||
GPUShader *sh = GPU_shader_get_builtin_shader(GPU_SHADER_3D_INSTANCE_MBALL_HELPERS);
|
||||
|
||||
DRWShadingGroup *grp = DRW_shgroup_instance_create(sh, pass, geom);
|
||||
DRW_shgroup_attrib_float(grp, "ScaleTranslationMatrix", 12);
|
||||
DRW_shgroup_attrib_float(grp, "radius", 1);
|
||||
DRW_shgroup_attrib_float(grp, "color", 3);
|
||||
DRW_shgroup_uniform_vec3(grp, "screen_vecs[0]", DRW_viewport_screenvecs_get(), 2);
|
||||
|
||||
return grp;
|
||||
}
|
||||
|
||||
|
||||
/* ******************************************** COLOR UTILS *********************************************** */
|
||||
|
||||
|
|
|
@ -104,6 +104,7 @@ struct DRWShadingGroup *shgroup_distance_lines_instance(struct DRWPass *pass, st
|
|||
struct DRWShadingGroup *shgroup_spot_instance(struct DRWPass *pass, struct Gwn_Batch *geom);
|
||||
struct DRWShadingGroup *shgroup_instance_bone_envelope_wire(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]);
|
||||
struct DRWShadingGroup *shgroup_instance_bone_envelope_solid(struct DRWPass *pass, struct Gwn_Batch *geom, float (*obmat)[4]);
|
||||
struct DRWShadingGroup *shgroup_instance_mball_helpers(struct DRWPass *pass, struct Gwn_Batch *geom);
|
||||
|
||||
int DRW_object_wire_theme_get(struct Object *ob, struct SceneLayer *scene_layer, float **r_color);
|
||||
float *DRW_color_background_blend_get(int theme_id);
|
||||
|
|
|
@ -3483,7 +3483,6 @@ void DRW_draw_select_loop(
|
|||
int obedit_mode = 0;
|
||||
if (scene->obedit && scene->obedit->type == OB_MBALL) {
|
||||
use_obedit = true;
|
||||
DRW_engines_cache_populate(scene->obedit);
|
||||
obedit_mode = CTX_MODE_EDIT_METABALL;
|
||||
}
|
||||
else if ((scene->obedit && scene->obedit->type == OB_ARMATURE)) {
|
||||
|
@ -3790,6 +3789,9 @@ void DRW_engines_register(void)
|
|||
|
||||
/* setup callbacks */
|
||||
{
|
||||
/* BKE: mball.c */
|
||||
extern void *BKE_mball_batch_cache_dirty_cb;
|
||||
extern void *BKE_mball_batch_cache_free_cb;
|
||||
/* BKE: curve.c */
|
||||
extern void *BKE_curve_batch_cache_dirty_cb;
|
||||
extern void *BKE_curve_batch_cache_free_cb;
|
||||
|
@ -3803,6 +3805,9 @@ void DRW_engines_register(void)
|
|||
extern void *BKE_particle_batch_cache_dirty_cb;
|
||||
extern void *BKE_particle_batch_cache_free_cb;
|
||||
|
||||
BKE_mball_batch_cache_dirty_cb = DRW_mball_batch_cache_dirty;
|
||||
BKE_mball_batch_cache_free_cb = DRW_mball_batch_cache_free;
|
||||
|
||||
BKE_curve_batch_cache_dirty_cb = DRW_curve_batch_cache_dirty;
|
||||
BKE_curve_batch_cache_free_cb = DRW_curve_batch_cache_free;
|
||||
|
||||
|
|
|
@ -26,8 +26,13 @@
|
|||
#include "DRW_engine.h"
|
||||
#include "DRW_render.h"
|
||||
|
||||
#include "DNA_meta_types.h"
|
||||
|
||||
#include "BKE_mball.h"
|
||||
|
||||
/* If builtin shaders are needed */
|
||||
#include "GPU_shader.h"
|
||||
#include "GPU_select.h"
|
||||
|
||||
#include "draw_common.h"
|
||||
|
||||
|
@ -71,7 +76,7 @@ typedef struct EDIT_METABALL_StorageList {
|
|||
* Only directly MEM_(m/c)allocN'ed blocks because they are
|
||||
* free with MEM_freeN() when viewport is freed.
|
||||
* (not per object) */
|
||||
struct CustomStruct *block;
|
||||
// struct CustomStruct *block;
|
||||
struct EDIT_METABALL_PrivateData *g_data;
|
||||
} EDIT_METABALL_StorageList;
|
||||
|
||||
|
@ -88,14 +93,6 @@ typedef struct EDIT_METABALL_Data {
|
|||
|
||||
/* *********** STATIC *********** */
|
||||
|
||||
static struct {
|
||||
/* Custom shaders :
|
||||
* Add sources to source/blender/draw/modes/shaders
|
||||
* init in EDIT_METABALL_engine_init();
|
||||
* free in EDIT_METABALL_engine_free(); */
|
||||
struct GPUShader *custom_shader;
|
||||
} e_data = {NULL}; /* Engine data */
|
||||
|
||||
typedef struct EDIT_METABALL_PrivateData {
|
||||
/* This keeps the references of the shading groups for
|
||||
* easy access in EDIT_METABALL_cache_populate() */
|
||||
|
@ -104,37 +101,6 @@ typedef struct EDIT_METABALL_PrivateData {
|
|||
|
||||
/* *********** FUNCTIONS *********** */
|
||||
|
||||
/* Init Textures, Framebuffers, Storage and Shaders.
|
||||
* It is called for every frames.
|
||||
* (Optional) */
|
||||
static void EDIT_METABALL_engine_init(void *vedata)
|
||||
{
|
||||
EDIT_METABALL_TextureList *txl = ((EDIT_METABALL_Data *)vedata)->txl;
|
||||
EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl;
|
||||
EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
|
||||
|
||||
UNUSED_VARS(txl, fbl, stl);
|
||||
|
||||
/* Init Framebuffers like this: order is attachment order (for color texs) */
|
||||
/*
|
||||
* DRWFboTexture tex[2] = {{&txl->depth, DRW_TEX_DEPTH_24, 0},
|
||||
* {&txl->color, DRW_TEX_RGBA_8, DRW_TEX_FILTER}};
|
||||
*/
|
||||
|
||||
/* DRW_framebuffer_init takes care of checking if
|
||||
* the framebuffer is valid and has the right size*/
|
||||
/*
|
||||
* float *viewport_size = DRW_viewport_size_get();
|
||||
* DRW_framebuffer_init(&fbl->occlude_wire_fb,
|
||||
* (int)viewport_size[0], (int)viewport_size[1],
|
||||
* tex, 2);
|
||||
*/
|
||||
|
||||
if (!e_data.custom_shader) {
|
||||
e_data.custom_shader = GPU_shader_get_builtin_shader(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
}
|
||||
}
|
||||
|
||||
/* Here init all passes and shading groups
|
||||
* Assume that all Passes are NULL */
|
||||
static void EDIT_METABALL_cache_init(void *vedata)
|
||||
|
@ -153,70 +119,86 @@ static void EDIT_METABALL_cache_init(void *vedata)
|
|||
psl->pass = DRW_pass_create("My Pass", state);
|
||||
|
||||
/* Create a shadingGroup using a function in draw_common.c or custom one */
|
||||
/*
|
||||
* stl->g_data->group = shgroup_dynlines_uniform_color(psl->pass, ts.colorWire);
|
||||
* -- or --
|
||||
* stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
|
||||
*/
|
||||
stl->g_data->group = DRW_shgroup_create(e_data.custom_shader, psl->pass);
|
||||
stl->g_data->group = shgroup_instance_mball_helpers(psl->pass, DRW_cache_screenspace_circle_get());
|
||||
}
|
||||
}
|
||||
|
||||
/* Uniforms need a pointer to it's value so be sure it's accessible at
|
||||
* any given time (i.e. use static vars) */
|
||||
static float color[4] = {0.0f, 1.0f, 0.0f, 1.0};
|
||||
DRW_shgroup_uniform_vec4(stl->g_data->group, "color", color, 1);
|
||||
static void EDIT_METABALL_cache_populate_radius_visualization(
|
||||
DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4],
|
||||
const float *radius, const int selection_id)
|
||||
{
|
||||
const float *color;
|
||||
static const float col_radius[3] = {0.63, 0.19, 0.19}; /* 0x3030A0 */
|
||||
static const float col_radius_select[3] = {0.94, 0.63, 0.63}; /* 0xA0A0F0 */
|
||||
|
||||
if ((ml->flag & SELECT) && (ml->flag & MB_SCALE_RAD)) color = col_radius_select;
|
||||
else color = col_radius;
|
||||
|
||||
if (selection_id != -1) {
|
||||
ml->selcol1 = selection_id;
|
||||
DRW_select_load_id(selection_id);
|
||||
}
|
||||
|
||||
DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color);
|
||||
}
|
||||
|
||||
static void EDIT_METABALL_cache_populate_stiffness_visualization(
|
||||
DRWShadingGroup *group, MetaElem *ml, const float scale_xform[3][4],
|
||||
const float *radius, const int selection_id)
|
||||
{
|
||||
const float *color;
|
||||
static const float col_stiffness[3] = {0.19, 0.63, 0.19}; /* 0x30A030 */
|
||||
static const float col_stiffness_select[3] = {0.63, 0.94, 0.63}; /* 0xA0F0A0 */
|
||||
|
||||
if ((ml->flag & SELECT) && !(ml->flag & MB_SCALE_RAD)) color = col_stiffness_select;
|
||||
else color = col_stiffness;
|
||||
|
||||
if (selection_id != -1) {
|
||||
ml->selcol2 = selection_id;
|
||||
DRW_select_load_id(selection_id);
|
||||
}
|
||||
|
||||
DRW_shgroup_call_dynamic_add(group, scale_xform, radius, color);
|
||||
}
|
||||
|
||||
/* Add geometry to shadingGroups. Execute for each objects */
|
||||
static void EDIT_METABALL_cache_populate(void *vedata, Object *ob)
|
||||
{
|
||||
EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
|
||||
//EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
|
||||
EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
|
||||
|
||||
UNUSED_VARS(psl, stl);
|
||||
if (ob->type == OB_MBALL) {
|
||||
const DRWContextState *draw_ctx = DRW_context_state_get();
|
||||
Scene *scene = draw_ctx->scene;
|
||||
Object *obedit = scene->obedit;
|
||||
DRWShadingGroup *group = stl->g_data->group;
|
||||
|
||||
if (ob->type == OB_MESH) {
|
||||
/* Get geometry cache */
|
||||
struct Gwn_Batch *geom = DRW_cache_mesh_surface_get(ob);
|
||||
if (ob == obedit) {
|
||||
MetaBall *mb = ob->data;
|
||||
|
||||
/* Add geom to a shading group */
|
||||
DRW_shgroup_call_add(stl->g_data->group, geom, ob->obmat);
|
||||
const bool is_select = DRW_state_is_select();
|
||||
|
||||
int selection_id = 0;
|
||||
|
||||
for (MetaElem *ml = mb->editelems->first; ml != NULL; ml = ml->next) {
|
||||
BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x);
|
||||
ml->draw_stiffness_radius = ml->rad * atanf(ml->s) / (float)M_PI_2;
|
||||
|
||||
EDIT_METABALL_cache_populate_radius_visualization(
|
||||
group, ml, ml->draw_scale_xform, &ml->rad, is_select ? ++selection_id : -1);
|
||||
|
||||
EDIT_METABALL_cache_populate_stiffness_visualization(
|
||||
group, ml, ml->draw_scale_xform, &ml->draw_stiffness_radius, is_select ? ++selection_id : -1);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Optional: Post-cache_populate callback */
|
||||
static void EDIT_METABALL_cache_finish(void *vedata)
|
||||
{
|
||||
EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
|
||||
EDIT_METABALL_StorageList *stl = ((EDIT_METABALL_Data *)vedata)->stl;
|
||||
|
||||
/* Do something here! dependant on the objects gathered */
|
||||
UNUSED_VARS(psl, stl);
|
||||
}
|
||||
|
||||
/* Draw time ! Control rendering pipeline from here */
|
||||
static void EDIT_METABALL_draw_scene(void *vedata)
|
||||
{
|
||||
EDIT_METABALL_PassList *psl = ((EDIT_METABALL_Data *)vedata)->psl;
|
||||
EDIT_METABALL_FramebufferList *fbl = ((EDIT_METABALL_Data *)vedata)->fbl;
|
||||
|
||||
/* Default framebuffer and texture */
|
||||
DefaultFramebufferList *dfbl = DRW_viewport_framebuffer_list_get();
|
||||
DefaultTextureList *dtxl = DRW_viewport_texture_list_get();
|
||||
|
||||
UNUSED_VARS(fbl, dfbl, dtxl);
|
||||
|
||||
/* Show / hide entire passes, swap framebuffers ... whatever you fancy */
|
||||
/*
|
||||
* DRW_framebuffer_texture_detach(dtxl->depth);
|
||||
* DRW_framebuffer_bind(fbl->custom_fb);
|
||||
* DRW_draw_pass(psl->pass);
|
||||
* DRW_framebuffer_texture_attach(dfbl->default_fb, dtxl->depth, 0, 0);
|
||||
* DRW_framebuffer_bind(dfbl->default_fb);
|
||||
*/
|
||||
|
||||
/* ... or just render passes on default framebuffer. */
|
||||
/* render passes on default framebuffer. */
|
||||
DRW_draw_pass(psl->pass);
|
||||
|
||||
/* If you changed framebuffer, double check you rebind
|
||||
|
@ -258,11 +240,11 @@ DrawEngineType draw_engine_edit_metaball_type = {
|
|||
NULL, NULL,
|
||||
N_("EditMetaballMode"),
|
||||
&EDIT_METABALL_data_size,
|
||||
&EDIT_METABALL_engine_init,
|
||||
NULL,
|
||||
&EDIT_METABALL_engine_free,
|
||||
&EDIT_METABALL_cache_init,
|
||||
&EDIT_METABALL_cache_populate,
|
||||
&EDIT_METABALL_cache_finish,
|
||||
NULL,
|
||||
NULL, /* draw_background but not needed by mode engines */
|
||||
&EDIT_METABALL_draw_scene,
|
||||
NULL,
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "DNA_camera_types.h"
|
||||
#include "DNA_curve_types.h"
|
||||
#include "DNA_mesh_types.h"
|
||||
#include "DNA_meta_types.h"
|
||||
#include "DNA_object_force.h"
|
||||
#include "DNA_lightprobe_types.h"
|
||||
#include "DNA_particle_types.h"
|
||||
|
@ -43,6 +44,7 @@
|
|||
#include "BKE_camera.h"
|
||||
#include "BKE_curve.h"
|
||||
#include "BKE_global.h"
|
||||
#include "BKE_mball.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_particle.h"
|
||||
#include "BKE_image.h"
|
||||
|
@ -149,6 +151,9 @@ typedef struct OBJECT_PrivateData {
|
|||
DRWShadingGroup *probe_planar;
|
||||
DRWShadingGroup *probe_grid;
|
||||
|
||||
/* MetaBalls */
|
||||
DRWShadingGroup *mball_circle;
|
||||
|
||||
/* Lamps */
|
||||
DRWShadingGroup *lamp_center;
|
||||
DRWShadingGroup *lamp_center_group;
|
||||
|
@ -949,6 +954,13 @@ static void OBJECT_cache_init(void *vedata)
|
|||
stl->g_data->wire_active_group = shgroup_wire(psl->non_meshes, ts.colorGroupActive, sh);
|
||||
}
|
||||
|
||||
{
|
||||
/* Metaballs Helpers */
|
||||
struct Gwn_Batch *geom;
|
||||
geom = DRW_cache_screenspace_circle_get();
|
||||
stl->g_data->mball_circle = shgroup_instance_mball_helpers(psl->non_meshes, geom);
|
||||
}
|
||||
|
||||
{
|
||||
/* Lamps */
|
||||
/* TODO
|
||||
|
@ -1077,6 +1089,20 @@ static void OBJECT_cache_init(void *vedata)
|
|||
}
|
||||
}
|
||||
|
||||
static void DRW_shgroup_mball_helpers(OBJECT_StorageList *stl, Object *ob, SceneLayer *scene_layer)
|
||||
{
|
||||
MetaBall *mb = ob->data;
|
||||
|
||||
float *color;
|
||||
DRW_object_wire_theme_get(ob, scene_layer, &color);
|
||||
|
||||
for (MetaElem *ml = mb->elems.first; ml != NULL; ml = ml->next) {
|
||||
/* draw radius */
|
||||
BKE_mball_element_calc_display_m3x4(ml->draw_scale_xform, ob->obmat, &ml->x);
|
||||
DRW_shgroup_call_dynamic_add(stl->g_data->mball_circle, ml->draw_scale_xform, &ml->rad, color);
|
||||
}
|
||||
}
|
||||
|
||||
static void DRW_shgroup_lamp(OBJECT_StorageList *stl, Object *ob, SceneLayer *scene_layer)
|
||||
{
|
||||
Lamp *la = ob->data;
|
||||
|
@ -1812,6 +1838,14 @@ static void OBJECT_cache_populate(void *vedata, Object *ob)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case OB_MBALL:
|
||||
{
|
||||
Object *obedit = scene->obedit;
|
||||
if (ob != obedit) {
|
||||
DRW_shgroup_mball_helpers(stl, ob, scene_layer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case OB_LAMP:
|
||||
DRW_shgroup_lamp(stl, ob, scene_layer);
|
||||
break;
|
||||
|
|
|
@ -48,6 +48,7 @@
|
|||
#include "BKE_lattice.h"
|
||||
#include "BKE_library.h"
|
||||
#include "BKE_main.h"
|
||||
#include "BKE_mball.h"
|
||||
#include "BKE_mesh.h"
|
||||
#include "BKE_object.h"
|
||||
#include "BKE_scene.h"
|
||||
|
|
|
@ -173,6 +173,7 @@ data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_geom.glsl SRC)
|
|||
data_to_c_simple(shaders/gpu_shader_instance_edges_variying_color_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_solid_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_instance_bone_envelope_wire_vert.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_instance_mball_helpers_vert.glsl SRC)
|
||||
|
||||
data_to_c_simple(shaders/gpu_shader_3D_groundline_geom.glsl SRC)
|
||||
data_to_c_simple(shaders/gpu_shader_3D_groundpoint_vert.glsl SRC)
|
||||
|
|
|
@ -173,6 +173,8 @@ typedef enum GPUBuiltinShader {
|
|||
GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_SOLID,
|
||||
GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE,
|
||||
|
||||
GPU_SHADER_3D_INSTANCE_MBALL_HELPERS,
|
||||
|
||||
GPU_NUM_BUILTIN_SHADERS /* (not an actual shader) */
|
||||
} GPUBuiltinShader;
|
||||
|
||||
|
|
|
@ -98,6 +98,7 @@ extern char datatoc_gpu_shader_instance_edges_variying_color_geom_glsl[];
|
|||
extern char datatoc_gpu_shader_instance_edges_variying_color_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_instance_bone_envelope_solid_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_instance_mball_helpers_vert_glsl[];
|
||||
|
||||
extern char datatoc_gpu_shader_3D_groundpoint_vert_glsl[];
|
||||
extern char datatoc_gpu_shader_3D_groundline_geom_glsl[];
|
||||
|
@ -805,7 +806,7 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
|
|||
datatoc_gpu_shader_point_uniform_color_outline_aa_frag_glsl },
|
||||
|
||||
[GPU_SHADER_INSTANCE_UNIFORM_COLOR] = { datatoc_gpu_shader_instance_vert_glsl, datatoc_gpu_shader_uniform_color_frag_glsl },
|
||||
[GPU_SHADER_INSTANCE_VARIYING_COLOR_VARIYING_SIZE] =
|
||||
[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] =
|
||||
|
@ -819,6 +820,9 @@ GPUShader *GPU_shader_get_builtin_shader(GPUBuiltinShader shader)
|
|||
datatoc_gpu_shader_simple_lighting_frag_glsl },
|
||||
[GPU_SHADER_3D_INSTANCE_BONE_ENVELOPE_WIRE] = { datatoc_gpu_shader_instance_bone_envelope_wire_vert_glsl,
|
||||
datatoc_gpu_shader_flat_color_frag_glsl },
|
||||
|
||||
[GPU_SHADER_3D_INSTANCE_MBALL_HELPERS] = { datatoc_gpu_shader_instance_mball_helpers_vert_glsl,
|
||||
datatoc_gpu_shader_flat_color_frag_glsl },
|
||||
};
|
||||
|
||||
if (builtin_shaders[shader] == NULL) {
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
|
||||
/* This shader takes a 2D shape, puts it in 3D Object space such that is stays aligned with view,
|
||||
* and scales the shape according to per-instance attributes
|
||||
* Note that if the stiffness is zero, it assumes the scale is directly multiplied by the radius */
|
||||
|
||||
|
||||
#define M_PI_2 1.570796f // pi/2
|
||||
|
||||
uniform mat4 ViewProjectionMatrix;
|
||||
uniform vec3 screen_vecs[2];
|
||||
|
||||
/* ---- Instanciated Attribs ---- */
|
||||
in vec2 pos;
|
||||
|
||||
/* ---- Per instance Attribs ---- */
|
||||
in mat3x4 ScaleTranslationMatrix;
|
||||
in float radius;
|
||||
in vec3 color;
|
||||
|
||||
flat out vec4 finalColor;
|
||||
|
||||
void main()
|
||||
{
|
||||
mat3 Scamat = mat3(ScaleTranslationMatrix);
|
||||
vec4 world_pos = vec4(
|
||||
ScaleTranslationMatrix[0][3],
|
||||
ScaleTranslationMatrix[1][3],
|
||||
ScaleTranslationMatrix[2][3],
|
||||
1.0);
|
||||
|
||||
vec3 screen_pos = screen_vecs[0].xyz * pos.x + screen_vecs[1].xyz * pos.y;
|
||||
world_pos.xyz += Scamat * (screen_pos * radius);
|
||||
|
||||
gl_Position = ViewProjectionMatrix * world_pos;
|
||||
finalColor = vec4(color, 1.0);
|
||||
}
|
|
@ -59,7 +59,11 @@ typedef struct MetaElem {
|
|||
float len; /* old, only used for backwards compat. use dimensions now */
|
||||
|
||||
float *mat, *imat; /* matrix and inverted matrix */
|
||||
|
||||
|
||||
/* Draw_Data: stores pointers used for shader attributes */
|
||||
float draw_scale_xform[3][4]; /* Matrix of Scale and Translation */
|
||||
float draw_stiffness_radius; /* stiffness circle radius (only in edit mode) */
|
||||
float pad;
|
||||
} MetaElem;
|
||||
|
||||
typedef struct MetaBall {
|
||||
|
@ -93,6 +97,8 @@ typedef struct MetaBall {
|
|||
/* used in editmode */
|
||||
/*ListBase edit_elems;*/
|
||||
MetaElem *lastelem;
|
||||
|
||||
void *batch_cache;
|
||||
} MetaBall;
|
||||
|
||||
/* **************** METABALL ********************* */
|
||||
|
|
|
@ -49,6 +49,11 @@ static void rna_Meta_transform(struct MetaBall *mb, float *mat)
|
|||
|
||||
DEG_id_tag_update(&mb->id, 0);
|
||||
}
|
||||
|
||||
static void rna_Mball_update_gpu_tag(MetaBall *mb)
|
||||
{
|
||||
BKE_mball_batch_cache_dirty(mb, BKE_MBALL_BATCH_DIRTY_ALL);
|
||||
}
|
||||
#else
|
||||
|
||||
void RNA_api_meta(StructRNA *srna)
|
||||
|
@ -60,6 +65,8 @@ void RNA_api_meta(StructRNA *srna)
|
|||
RNA_def_function_ui_description(func, "Transform meta elements by a matrix");
|
||||
parm = RNA_def_float_matrix(func, "matrix", 4, 4, NULL, 0.0f, 0.0f, "", "Matrix", 0.0f, 0.0f);
|
||||
RNA_def_parameter_flags(parm, 0, PARM_REQUIRED);
|
||||
|
||||
RNA_def_function(srna, "update_gpu_tag", "rna_Mball_update_gpu_tag");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue