Added a particle index output to the Particle Info Cycles node. This is required...
authorLukas Toenne <lukas.toenne@googlemail.com>
Thu, 26 Jul 2012 11:40:58 +0000 (11:40 +0000)
committerLukas Toenne <lukas.toenne@googlemail.com>
Thu, 26 Jul 2012 11:40:58 +0000 (11:40 +0000)
The particle index is always the same for a specific particle. Randomized values can be generated from this with the use of a noise texture.

intern/cycles/blender/blender_particles.cpp
intern/cycles/kernel/kernel_object.h
intern/cycles/kernel/svm/svm_geometry.h
intern/cycles/kernel/svm/svm_types.h
intern/cycles/render/nodes.cpp
intern/cycles/render/object.cpp
intern/cycles/render/object.h
source/blender/nodes/shader/nodes/node_shader_particle_info.c

index f591aaa6d835bb8c0aa05c211e3d84729f37ef7f..d669aa34a68621dce99304bf2582c589fcd8c4b1 100644 (file)
@@ -144,16 +144,20 @@ void BlenderSync::sync_particles(Object *ob, BL::Object b_ob)
        BL::Object::particle_systems_iterator b_psys;
        for(b_ob.particle_systems.begin(b_psys); b_psys != b_ob.particle_systems.end(); ++b_psys) {
                if (use_particle_system(*b_psys)) {
+                       int pa_index = 0;
                        BL::ParticleSystem::particles_iterator b_pa;
                        for(b_psys->particles.begin(b_pa), index = 0; b_pa != b_psys->particles.end(); ++b_pa, ++index) {
                                if(use_particle(*b_pa)) {
                                        Particle pa;
                                        
+                                       pa.index = pa_index;
                                        pa.age = b_scene.frame_current() - b_pa->birth_time();
                                        pa.lifetime = b_pa->lifetime();
                                        
                                        ob->particles.push_back(pa);
                                }
+                               
+                               ++pa_index;
                        }
                }
        }
index 18e0b1e8a8771f3439b13c15da5dec88cf4e31bc..4ff315ca265e498337bd450a41bfd7cf6a82ac81 100644 (file)
@@ -169,20 +169,27 @@ __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
        return kernel_tex_fetch(__shader_flag, (sd->shader & SHADER_MASK)*2 + 1);
 }
 
-__device float particle_age(KernelGlobals *kg, int particle)
+__device_inline float particle_index(KernelGlobals *kg, int particle)
 {
        int offset = particle*PARTICLE_SIZE;
        float4 f = kernel_tex_fetch(__particles, offset);
        return f.x;
 }
 
-__device float particle_lifetime(KernelGlobals *kg, int particle)
+__device float particle_age(KernelGlobals *kg, int particle)
 {
        int offset = particle*PARTICLE_SIZE;
        float4 f = kernel_tex_fetch(__particles, offset);
        return f.y;
 }
 
+__device float particle_lifetime(KernelGlobals *kg, int particle)
+{
+       int offset = particle*PARTICLE_SIZE;
+       float4 f = kernel_tex_fetch(__particles, offset);
+       return f.z;
+}
+
 
 CCL_NAMESPACE_END
 
index 88127b56474c7bd04b6dac60d48e4357fced46e8..3cfce1d087ae32491d552f7d76a4ee347b4da0dd 100644 (file)
@@ -101,6 +101,12 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
        float data;
 
        switch(type) {
+               case NODE_INFO_PAR_INDEX: {
+                       uint particle_id = object_particle_id(kg, sd->object);
+                       data = particle_index(kg, particle_id);
+                       stack_store_float(stack, out_offset, data);
+                       break;
+               }
                case NODE_INFO_PAR_AGE: {
                        uint particle_id = object_particle_id(kg, sd->object);
                        data = particle_age(kg, particle_id);
index c1eeeb55268c2a26062cded04725a27e113f3bda..cbff0c099ea37de296c15210a4b6f25917e26943 100644 (file)
@@ -114,6 +114,7 @@ typedef enum NodeObjectInfo {
 } NodeObjectInfo;
 
 typedef enum NodeParticleInfo {
+       NODE_INFO_PAR_INDEX,
        NODE_INFO_PAR_AGE,
        NODE_INFO_PAR_LIFETIME
 } NodeParticleInfo;
index e4a4b87496487cbe20c38f8ce37f72446986ab23..250570e1d65ce2c4c4b3d5f3466f0b4051c6fb12 100644 (file)
@@ -1798,12 +1798,15 @@ void ObjectInfoNode::compile(OSLCompiler& compiler)
 ParticleInfoNode::ParticleInfoNode()
 : ShaderNode("particle_info")
 {
+       add_output("Index", SHADER_SOCKET_FLOAT);
        add_output("Age", SHADER_SOCKET_FLOAT);
        add_output("Lifetime", SHADER_SOCKET_FLOAT);
 }
 
 void ParticleInfoNode::attributes(AttributeRequestSet *attributes)
 {
+       if(!output("Index")->links.empty())
+               attributes->add(ATTR_STD_PARTICLE);
        if(!output("Age")->links.empty())
                attributes->add(ATTR_STD_PARTICLE);
        if(!output("Lifetime")->links.empty())
@@ -1816,6 +1819,12 @@ void ParticleInfoNode::compile(SVMCompiler& compiler)
 {
        ShaderOutput *out;
        
+       out = output("Index");
+       if(!out->links.empty()) {
+               compiler.stack_assign(out);
+               compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_INDEX, out->stack_offset);
+       }
+       
        out = output("Age");
        if(!out->links.empty()) {
                compiler.stack_assign(out);
index 6de7eaea343bab71eb32acfcbd53072b91e37601..c4b25e633bf24eeb8da164af8520651674aeab92 100644 (file)
@@ -269,7 +269,7 @@ void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene,
                        /* pack in texture */
                        int offset = i*PARTICLE_SIZE;
                        
-                       particles[offset] = make_float4(pa.age, pa.lifetime, 0.0f, 0.0f);
+                       particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f);
                        
                        i++;
                        
index 6d674731b07e7d38f914b573455f3798d2fdbdd4..9b2f5bc876847fc1d410cf9537169c7f5a10efa9 100644 (file)
@@ -36,6 +36,7 @@ struct Transform;
 /* Object */
 
 struct Particle {
+       int index;
        float age;
        float lifetime;
 };
index beefc0b6eaedcf9c5b7f33687c335cf4fdb1e0bb..5be8925b55647a67686cdf5875600fde89ab09a3 100644 (file)
 #include "../node_shader_util.h"
 
 static bNodeSocketTemplate outputs[] = {
-        { SOCK_FLOAT,  0, "Age" },
-        { SOCK_FLOAT,  0, "Lifetime" },
-        { -1, 0, "" }
+    { SOCK_FLOAT,  0, "Index" },
+    { SOCK_FLOAT,  0, "Age" },
+    { SOCK_FLOAT,  0, "Lifetime" },
+    { -1, 0, "" }
 };
 
 /* node type definition */