[Bf-blender-cvs] [64e3661] gooseberry: Store particle index and randomized value from particle instance modifiers, for use in shaders.
Lukas Tönne
noreply at git.blender.org
Mon Feb 16 14:33:18 CET 2015
Commit: 64e3661434f11b4201c08cac1e99f08853551c86
Author: Lukas Tönne
Date: Mon Feb 16 14:30:07 2015 +0100
Branches: gooseberry
https://developer.blender.org/rB64e3661434f11b4201c08cac1e99f08853551c86
Store particle index and randomized value from particle instance
modifiers, for use in shaders.
The particle instance modifier can now store 2 custom data layers:
- Index: the integer index of the particle
- Value: a randomized floating point number for shader variation
These layers have user-defined names, so multiple particle instance
modifiers can be used without overwriting customdata layers. In Cycles
the data can be accessed using an Attribute node with the same names.
===================================================================
M intern/cycles/blender/blender_mesh.cpp
M release/scripts/startup/bl_ui/properties_data_modifier.py
M source/blender/makesdna/DNA_modifier_types.h
M source/blender/makesrna/intern/rna_modifier.c
M source/blender/modifiers/intern/MOD_particleinstance.c
===================================================================
diff --git a/intern/cycles/blender/blender_mesh.cpp b/intern/cycles/blender/blender_mesh.cpp
index c5e2fa2..7f3752d 100644
--- a/intern/cycles/blender/blender_mesh.cpp
+++ b/intern/cycles/blender/blender_mesh.cpp
@@ -419,6 +419,52 @@ static void attr_create_pointiness(Scene *scene,
}
}
+/* Create vertex custom attributes. */
+static void attr_create_vertex_properties(Scene *scene,
+ Mesh *mesh,
+ BL::Mesh b_mesh)
+{
+ {
+ BL::Mesh::vertex_layers_float_iterator l;
+ for(b_mesh.vertex_layers_float.begin(l); l != b_mesh.vertex_layers_float.end(); ++l) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+
+ BL::MeshVertexFloatPropertyLayer::data_iterator d;
+ float *data = attr->data_float();
+ size_t i = 0;
+
+ for(l->data.begin(d); d != l->data.end(); ++d, ++i) {
+ *data = d->value();
+ data += 1;
+ }
+ }
+ }
+
+ {
+ BL::Mesh::vertex_layers_int_iterator l;
+ for(b_mesh.vertex_layers_int.begin(l); l != b_mesh.vertex_layers_int.end(); ++l) {
+ if(!mesh->need_attribute(scene, ustring(l->name().c_str())))
+ continue;
+
+ Attribute *attr = mesh->attributes.add(
+ ustring(l->name().c_str()), TypeDesc::TypeFloat, ATTR_ELEMENT_VERTEX);
+
+ BL::MeshVertexIntPropertyLayer::data_iterator d;
+ float *data = attr->data_float();
+ size_t i = 0;
+
+ for(l->data.begin(d); d != l->data.end(); ++d, ++i) {
+ *data = (float)d->value();
+ data += 1;
+ }
+ }
+ }
+}
+
/* Create Mesh */
static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<uint>& used_shaders)
@@ -523,6 +569,7 @@ static void create_mesh(Scene *scene, Mesh *mesh, BL::Mesh b_mesh, const vector<
attr_create_vertex_color(scene, mesh, b_mesh, nverts);
attr_create_uv_map(scene, mesh, b_mesh, nverts);
attr_create_pointiness(scene, mesh, b_mesh);
+ attr_create_vertex_properties(scene, mesh, b_mesh);
/* for volume objects, create a matrix to transform from object space to
* mesh texture space. this does not work with deformations but that can
diff --git a/release/scripts/startup/bl_ui/properties_data_modifier.py b/release/scripts/startup/bl_ui/properties_data_modifier.py
index 2a27610..d524d26 100644
--- a/release/scripts/startup/bl_ui/properties_data_modifier.py
+++ b/release/scripts/startup/bl_ui/properties_data_modifier.py
@@ -682,6 +682,10 @@ class DATA_PT_modifiers(ModifierButtonsPanel, Panel):
col.prop(md, "position", slider=True)
col.prop(md, "random_position", text="Random", slider=True)
+ col = layout.column(align=True)
+ col.prop(md, "index_layer_name", text="Index Layer")
+ col.prop(md, "value_layer_name", text="Value Layer")
+
def PARTICLE_SYSTEM(self, layout, ob, md):
layout.label(text="Settings can be found inside the Particle context")
diff --git a/source/blender/makesdna/DNA_modifier_types.h b/source/blender/makesdna/DNA_modifier_types.h
index e603f3e..414d1d7 100644
--- a/source/blender/makesdna/DNA_modifier_types.h
+++ b/source/blender/makesdna/DNA_modifier_types.h
@@ -712,14 +712,14 @@ typedef enum {
} ParticleSystemModifierFlag;
typedef enum {
- eParticleInstanceFlag_Parents = (1 << 0),
- eParticleInstanceFlag_Children = (1 << 1),
- eParticleInstanceFlag_Path = (1 << 2),
- eParticleInstanceFlag_Unborn = (1 << 3),
- eParticleInstanceFlag_Alive = (1 << 4),
- eParticleInstanceFlag_Dead = (1 << 5),
- eParticleInstanceFlag_KeepShape = (1 << 6),
- eParticleInstanceFlag_UseSize = (1 << 7),
+ eParticleInstanceFlag_Parents = (1 << 0),
+ eParticleInstanceFlag_Children = (1 << 1),
+ eParticleInstanceFlag_Path = (1 << 2),
+ eParticleInstanceFlag_Unborn = (1 << 3),
+ eParticleInstanceFlag_Alive = (1 << 4),
+ eParticleInstanceFlag_Dead = (1 << 5),
+ eParticleInstanceFlag_KeepShape = (1 << 6),
+ eParticleInstanceFlag_UseSize = (1 << 7),
} ParticleInstanceModifierFlag;
typedef enum {
@@ -734,6 +734,8 @@ typedef struct ParticleInstanceModifierData {
short psys, flag, axis, space;
float position, random_position;
float particle_amount, particle_offset;
+ char index_layer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
+ char value_layer_name[64]; /* MAX_CUSTOMDATA_LAYER_NAME */
} ParticleInstanceModifierData;
typedef enum {
diff --git a/source/blender/makesrna/intern/rna_modifier.c b/source/blender/makesrna/intern/rna_modifier.c
index 3a72119..8c4c33f 100644
--- a/source/blender/makesrna/intern/rna_modifier.c
+++ b/source/blender/makesrna/intern/rna_modifier.c
@@ -2448,6 +2448,16 @@ static void rna_def_modifier_particleinstance(BlenderRNA *brna)
RNA_def_property_ui_text(prop, "Particle Offset", "Relative offset of particles to use for instancing, to avoid overlap of multiple instances");
RNA_def_property_float_default(prop, 0.0f);
RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "index_layer_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "index_layer_name");
+ RNA_def_property_ui_text(prop, "Index Layer Name", "Custom data layer name for the index");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
+
+ prop = RNA_def_property(srna, "value_layer_name", PROP_STRING, PROP_NONE);
+ RNA_def_property_string_sdna(prop, NULL, "value_layer_name");
+ RNA_def_property_ui_text(prop, "Value Layer Name", "Custom data layer name for the randomized value");
+ RNA_def_property_update(prop, 0, "rna_Modifier_update");
}
static void rna_def_modifier_explode(BlenderRNA *brna)
diff --git a/source/blender/modifiers/intern/MOD_particleinstance.c b/source/blender/modifiers/intern/MOD_particleinstance.c
index f7092c7..853790e 100644
--- a/source/blender/modifiers/intern/MOD_particleinstance.c
+++ b/source/blender/modifiers/intern/MOD_particleinstance.c
@@ -40,6 +40,7 @@
#include "BLI_math.h"
#include "BLI_listbase.h"
#include "BLI_rand.h"
+#include "BLI_string.h"
#include "BLI_utildefines.h"
#include "BKE_cdderivedmesh.h"
@@ -65,6 +66,9 @@ static void initData(ModifierData *md)
pimd->space = eParticleInstanceSpace_Local;
pimd->particle_amount = 1.0f;
pimd->particle_offset = 0.0f;
+
+ BLI_strncpy(pimd->index_layer_name, "particle_index", sizeof(pimd->index_layer_name));
+ BLI_strncpy(pimd->value_layer_name, "particle_value", sizeof(pimd->value_layer_name));
}
static void copyData(ModifierData *md, ModifierData *target)
{
@@ -208,6 +212,8 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
float max_co = 0.0, min_co = 0.0, temp_co[3];
float *size = NULL;
float spacemat[4][4];
+ int *cd_index = NULL;
+ float *cd_value = NULL;
trackneg = ((ob->trackflag > 2) ? 1 : 0);
@@ -313,9 +319,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
mloop = result->getLoopArray(result);
orig_mloop = dm->getLoopArray(dm);
+ /* create customdata layer for particle index storage */
+ if (pimd->index_layer_name[0] != '\0')
+ cd_index = CustomData_add_layer_named(&result->vertData, CD_PROP_INT, CD_CALLOC,
+ NULL, maxvert, pimd->index_layer_name);
+ if (pimd->value_layer_name[0] != '\0')
+ cd_value = CustomData_add_layer_named(&result->vertData, CD_PROP_FLT, CD_CALLOC,
+ NULL, maxvert, pimd->value_layer_name);
+
for (p = 0, p_skip = 0; p < totpart; p++) {
float prev_dir[3];
float frame[4]; /* frame orientation quaternion */
+ float p_random = psys_frand(psys, 77091 + 283*p);
/* skip particle? */
if (particle_skip(pimd, psys, p))
@@ -325,12 +340,18 @@ static DerivedMesh *applyModifier(ModifierData *md, Object *ob,
for (k = 0; k < totvert; k++) {
ParticleKey state;
MVert *inMV;
- MVert *mv = mvert + p_skip * totvert + k;
+ int vindex = p_skip * totvert + k;
+ MVert *mv = mvert + vindex;
inMV = orig_mvert + k;
DM_copy_vert_data(dm, result, k, p_skip * totvert + k, 1);
*mv = *inMV;
+ if (cd_index)
+ cd_index[vindex] = p;
+ if (cd_value)
+ cd_value[vindex] = p_random;
+
/*change orientation based on object trackflag*/
copy_v3_v3(temp_co, mv->co);
mv->co[axis] = temp_co[track];
More information about the Bf-blender-cvs
mailing list