62 return (cache && cache->
is_dirty ==
false);
73 memset(cache, 0,
sizeof(*cache));
137 for (
int i = 0; i < num_curves; i++,
curve++) {
149 for (
int i = 0; i < num_curves; i++,
curve++) {
151 float total_len = 0.0f;
152 float *co_prev =
NULL, *seg_data_first;
153 for (
int j = 0; j <
curve->numpoints; j++) {
157 total_len +=
len_v3v3(co_prev, curve_co[j]);
160 seg_data_first = seg_data;
162 seg_data[3] = total_len;
163 co_prev = curve_co[j];
165 if (total_len > 0.0f) {
167 for (
int j = 0; j <
curve->numpoints; j++, seg_data_first += 4) {
168 seg_data_first[3] /= total_len;
204 for (
int i = 0; i < num_curves; i++,
curve++) {
267 for (
int i = 0; i < num_curves; i++,
curve++) {
268 for (
int k = 0; k < res; k++) {
288 int element_count = (verts_per_hair + 1) * cache->
strands_len;
315 bool need_ft_update =
false;
316 Hair *hair =
object->data;
319 *r_hair_cache = &cache->
hair;
322 (*r_hair_cache)->final[subdiv].strands_res = 1 << (
steps + subdiv);
325 if ((*r_hair_cache)->proc_point_buf ==
NULL) {
328 need_ft_update =
true;
332 if ((*r_hair_cache)->strand_tex ==
NULL) {
337 if ((*r_hair_cache)->final[subdiv].proc_buf ==
NULL) {
339 need_ft_update =
true;
341 if ((*r_hair_cache)->final[subdiv].proc_hairs[thickness_res - 1] ==
NULL) {
345 return need_ft_update;
typedef float(TangentPoint)[2]
General operations for hairs.
@ BKE_HAIR_BATCH_DIRTY_ALL
MINLINE int max_ii(int a, int b)
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v3_v3(float r[3], const float a[3])
Object is a sort of wrapper for general info.
GPUBatch * GPU_batch_create_ex(GPUPrimType prim, GPUVertBuf *vert, GPUIndexBuf *elem, eGPUBatchFlag owns_flag)
void GPU_indexbuf_add_primitive_restart(GPUIndexBufBuilder *)
GPUIndexBuf * GPU_indexbuf_build(GPUIndexBufBuilder *)
void GPU_indexbuf_add_generic_vert(GPUIndexBufBuilder *, uint v)
void GPU_indexbuf_init_ex(GPUIndexBufBuilder *, GPUPrimType, uint index_len, uint vertex_len)
GPUTexture * GPU_texture_create_from_vertbuf(const char *name, struct GPUVertBuf *vert)
#define GPU_vertbuf_create_with_format(format)
struct GPUVertBuf GPUVertBuf
void GPU_vertbuf_data_alloc(GPUVertBuf *, uint v_len)
void GPU_vertbuf_use(GPUVertBuf *)
GPU_INLINE void * GPU_vertbuf_raw_step(GPUVertBufRaw *a)
void GPU_vertbuf_attr_get_raw_data(GPUVertBuf *, uint a_idx, GPUVertBufRaw *access)
Read Guarded memory(de)allocation.
static void hair_batch_cache_fill_segments_proc_pos(Hair *hair, GPUVertBufRaw *attr_step)
void DRW_hair_batch_cache_dirty_tag(Hair *hair, int mode)
int DRW_hair_material_count_get(Hair *hair)
static void hair_batch_cache_init(Hair *hair)
static HairBatchCache * hair_batch_cache_get(Hair *hair)
void DRW_hair_batch_cache_validate(Hair *hair)
static bool hair_batch_cache_valid(Hair *hair)
bool hair_ensure_procedural_data(Object *object, ParticleHairCache **r_hair_cache, int subdiv, int thickness_res)
static void hair_batch_cache_fill_segments_indices(Hair *hair, const int res, GPUIndexBufBuilder *elb)
static void hair_batch_cache_ensure_procedural_pos(Hair *hair, ParticleHairCache *cache)
void DRW_hair_batch_cache_free(Hair *hair)
static void ensure_seg_pt_count(Hair *hair, ParticleHairCache *hair_cache)
static void hair_batch_cache_fill_strands_data(Hair *hair, GPUVertBufRaw *data_step, GPUVertBufRaw *seg_step)
struct HairBatchCache HairBatchCache
static void hair_batch_cache_ensure_procedural_final_points(ParticleHairCache *cache, int subdiv)
static void hair_batch_cache_ensure_procedural_indices(Hair *hair, ParticleHairCache *cache, int thickness_res, int subdiv)
static void hair_batch_cache_clear(Hair *hair)
static void hair_batch_cache_ensure_procedural_strand_data(Hair *hair, ParticleHairCache *cache)
void particle_batch_cache_clear_hair(ParticleHairCache *hair_cache)
void *(* MEM_callocN)(size_t len, const char *str)
struct HairCurve * curves
GPUVertBuf * proc_point_buf
GPUVertBuf * proc_strand_buf
GPUTexture * strand_seg_tex
GPUVertBuf * proc_strand_seg_buf
ParticleHairFinalCache final[MAX_HAIR_SUBDIV]
GPUBatch * proc_hairs[MAX_THICKRES]