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:
authorLukas Toenne <lukas.toenne@googlemail.com>2012-08-31 23:38:59 +0400
committerLukas Toenne <lukas.toenne@googlemail.com>2012-08-31 23:38:59 +0400
commit9e3fa15d4b3e22127471a7451a49b594cf6275a0 (patch)
tree5891c5922401980fbb0843a60abd45278278f0c5
parentf0d247748408bd10f49c54d3a28a925e37683c4b (diff)
Added a bunch of additional particle state attributes to the Cycles particle info node:
* Location: Basically the same as the location from Object Info node for object instances on particles, but in principle there could be additional offsets for dupli objects, so included for completeness. * Size: Single float scale of the particle. Also directly translates to object scale for current dupli objects, but handy to have as a single float to start with instead of a scale vector (currently not even exposed in Object Info). * Rotation: This is a quaternion, which are not yet supported by Cycles nodes. The float4 is copied to internal Cycles data and stored in the particles texture data, but the node doesn't have a socket for it yet and the data is not yet written to the stack. Code is just commented out so could be enabled quickly if/when rotation support is added to cycles. * Velocity: Linear velocity vector of particles. * Angular Velocity: Angular velocity around principle axes. The texture data is currently packed tightly into the particles texture, which saves a few bytes, but requires an additional texture lookup for some vector attributes which spread over two float4s. Could also add another float4 to particle size to avoid this.
-rw-r--r--intern/cycles/blender/blender_particles.cpp5
-rw-r--r--intern/cycles/blender/blender_util.h5
-rw-r--r--intern/cycles/kernel/kernel_object.h43
-rw-r--r--intern/cycles/kernel/kernel_types.h2
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h38
-rw-r--r--intern/cycles/kernel/svm/svm_types.h7
-rw-r--r--intern/cycles/render/nodes.cpp51
-rw-r--r--intern/cycles/render/particles.cpp6
-rw-r--r--intern/cycles/render/particles.h5
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_particle_info.c7
10 files changed, 155 insertions, 14 deletions
diff --git a/intern/cycles/blender/blender_particles.cpp b/intern/cycles/blender/blender_particles.cpp
index 337ec36d107..74142f481ed 100644
--- a/intern/cycles/blender/blender_particles.cpp
+++ b/intern/cycles/blender/blender_particles.cpp
@@ -168,6 +168,11 @@ void BlenderSync::sync_particles(BL::Object b_ob, BL::ParticleSystem b_psys)
pa.index = index;
pa.age = b_scene.frame_current() - b_pa->birth_time();
pa.lifetime = b_pa->lifetime();
+ pa.location = get_float3(b_pa->location());
+ pa.rotation = get_float4(b_pa->rotation());
+ pa.size = b_pa->size();
+ pa.velocity = get_float3(b_pa->velocity());
+ pa.angular_velocity = get_float3(b_pa->angular_velocity());
psys->particles.push_back(pa);
}
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index b6609377561..2e9b201c0e2 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -150,6 +150,11 @@ static inline float3 get_float3(BL::Array<float, 4> array)
return make_float3(array[0], array[1], array[2]);
}
+static inline float4 get_float4(BL::Array<float, 4> array)
+{
+ return make_float4(array[0], array[1], array[2], array[3]);
+}
+
static inline int4 get_int4(BL::Array<int, 4> array)
{
return make_int4(array[0], array[1], array[2], array[3]);
diff --git a/intern/cycles/kernel/kernel_object.h b/intern/cycles/kernel/kernel_object.h
index 4ff315ca265..222ade504cc 100644
--- a/intern/cycles/kernel/kernel_object.h
+++ b/intern/cycles/kernel/kernel_object.h
@@ -172,24 +172,61 @@ __device int shader_pass_id(KernelGlobals *kg, ShaderData *sd)
__device_inline float particle_index(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.x;
}
__device float particle_age(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.y;
}
__device float particle_lifetime(KernelGlobals *kg, int particle)
{
int offset = particle*PARTICLE_SIZE;
- float4 f = kernel_tex_fetch(__particles, offset);
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
return f.z;
}
+__device float particle_size(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 0);
+ return f.w;
+}
+
+__device float4 particle_rotation(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 1);
+ return f;
+}
+
+__device float3 particle_location(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f = kernel_tex_fetch(__particles, offset + 2);
+ return make_float3(f.x, f.y, f.z);
+}
+
+__device float3 particle_velocity(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f2 = kernel_tex_fetch(__particles, offset + 2);
+ float4 f3 = kernel_tex_fetch(__particles, offset + 3);
+ return make_float3(f2.w, f3.x, f3.y);
+}
+
+__device float3 particle_angular_velocity(KernelGlobals *kg, int particle)
+{
+ int offset = particle*PARTICLE_SIZE;
+ float4 f3 = kernel_tex_fetch(__particles, offset + 3);
+ float4 f4 = kernel_tex_fetch(__particles, offset + 4);
+ return make_float3(f3.z, f3.w, f4.x);
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 30d45ad1118..488c6de3a42 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -33,7 +33,7 @@ CCL_NAMESPACE_BEGIN
#define LIGHT_SIZE 4
#define FILTER_TABLE_SIZE 256
#define RAMP_TABLE_SIZE 256
-#define PARTICLE_SIZE 1
+#define PARTICLE_SIZE 5
#define TIME_INVALID FLT_MAX
/* device capabilities */
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 3cfce1d087a..22741bdb067 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -98,25 +98,47 @@ __device void svm_node_object_info(KernelGlobals *kg, ShaderData *sd, float *sta
__device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
{
- 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);
+ stack_store_float(stack, out_offset, particle_index(kg, particle_id));
break;
}
case NODE_INFO_PAR_AGE: {
uint particle_id = object_particle_id(kg, sd->object);
- data = particle_age(kg, particle_id);
- stack_store_float(stack, out_offset, data);
+ stack_store_float(stack, out_offset, particle_age(kg, particle_id));
break;
}
case NODE_INFO_PAR_LIFETIME: {
uint particle_id = object_particle_id(kg, sd->object);
- data = particle_lifetime(kg, particle_id);
- stack_store_float(stack, out_offset, data);
+ stack_store_float(stack, out_offset, particle_lifetime(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_LOCATION: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_location(kg, particle_id));
+ break;
+ }
+ #if 0 /* XXX float4 currently not supported in SVM stack */
+ case NODE_INFO_PAR_ROTATION: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float4(stack, out_offset, particle_rotation(kg, particle_id));
+ break;
+ }
+ #endif
+ case NODE_INFO_PAR_SIZE: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float(stack, out_offset, particle_size(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_VELOCITY: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_velocity(kg, particle_id));
+ break;
+ }
+ case NODE_INFO_PAR_ANGULAR_VELOCITY: {
+ uint particle_id = object_particle_id(kg, sd->object);
+ stack_store_float3(stack, out_offset, particle_angular_velocity(kg, particle_id));
break;
}
}
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index 38232eb9c04..16c726e7faa 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -116,7 +116,12 @@ typedef enum NodeObjectInfo {
typedef enum NodeParticleInfo {
NODE_INFO_PAR_INDEX,
NODE_INFO_PAR_AGE,
- NODE_INFO_PAR_LIFETIME
+ NODE_INFO_PAR_LIFETIME,
+ NODE_INFO_PAR_LOCATION,
+ NODE_INFO_PAR_ROTATION,
+ NODE_INFO_PAR_SIZE,
+ NODE_INFO_PAR_VELOCITY,
+ NODE_INFO_PAR_ANGULAR_VELOCITY
} NodeParticleInfo;
typedef enum NodeLightPath {
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index b35fe151bac..3d9055119ed 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1801,6 +1801,13 @@ ParticleInfoNode::ParticleInfoNode()
add_output("Index", SHADER_SOCKET_FLOAT);
add_output("Age", SHADER_SOCKET_FLOAT);
add_output("Lifetime", SHADER_SOCKET_FLOAT);
+ add_output("Location", SHADER_SOCKET_POINT);
+ #if 0 /* not yet supported */
+ add_output("Rotation", SHADER_SOCKET_QUATERNION);
+ #endif
+ add_output("Size", SHADER_SOCKET_FLOAT);
+ add_output("Velocity", SHADER_SOCKET_VECTOR);
+ add_output("Angular Velocity", SHADER_SOCKET_VECTOR);
}
void ParticleInfoNode::attributes(AttributeRequestSet *attributes)
@@ -1811,6 +1818,18 @@ void ParticleInfoNode::attributes(AttributeRequestSet *attributes)
attributes->add(ATTR_STD_PARTICLE);
if(!output("Lifetime")->links.empty())
attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Location")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ #if 0 /* not yet supported */
+ if(!output("Rotation")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ #endif
+ if(!output("Size")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
+ if(!output("Angular Velocity")->links.empty())
+ attributes->add(ATTR_STD_PARTICLE);
ShaderNode::attributes(attributes);
}
@@ -1836,6 +1855,38 @@ void ParticleInfoNode::compile(SVMCompiler& compiler)
compiler.stack_assign(out);
compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LIFETIME, out->stack_offset);
}
+
+ out = output("Location");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_LOCATION, out->stack_offset);
+ }
+
+ #if 0 /* XXX Quaternion data is not yet supported by Cycles */
+ out = output("Rotation");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ROTATION, out->stack_offset);
+ }
+ #endif
+
+ out = output("Size");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_SIZE, out->stack_offset);
+ }
+
+ out = output("Velocity");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_VELOCITY, out->stack_offset);
+ }
+
+ out = output("Angular Velocity");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_PARTICLE_INFO, NODE_INFO_PAR_ANGULAR_VELOCITY, out->stack_offset);
+ }
}
void ParticleInfoNode::compile(OSLCompiler& compiler)
diff --git a/intern/cycles/render/particles.cpp b/intern/cycles/render/particles.cpp
index 539a2333506..c3e4b9510de 100644
--- a/intern/cycles/render/particles.cpp
+++ b/intern/cycles/render/particles.cpp
@@ -74,7 +74,11 @@ void ParticleSystemManager::device_update_particles(Device *device, DeviceScene
/* pack in texture */
int offset = i*PARTICLE_SIZE;
- particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, 0.0f);
+ particles[offset] = make_float4(pa.index, pa.age, pa.lifetime, pa.size);
+ particles[offset+1] = pa.rotation;
+ particles[offset+2] = make_float4(pa.location.x, pa.location.y, pa.location.z, pa.velocity.x);
+ particles[offset+3] = make_float4(pa.velocity.y, pa.velocity.z, pa.angular_velocity.x, pa.angular_velocity.y);
+ particles[offset+4] = make_float4(pa.angular_velocity.z, 0.0f, 0.0f, 0.0f);
i++;
diff --git a/intern/cycles/render/particles.h b/intern/cycles/render/particles.h
index e5481ad4c24..afc8b2b2dcb 100644
--- a/intern/cycles/render/particles.h
+++ b/intern/cycles/render/particles.h
@@ -35,6 +35,11 @@ struct Particle {
int index;
float age;
float lifetime;
+ float3 location;
+ float4 rotation;
+ float size;
+ float3 velocity;
+ float3 angular_velocity;
};
class ParticleSystem {
diff --git a/source/blender/nodes/shader/nodes/node_shader_particle_info.c b/source/blender/nodes/shader/nodes/node_shader_particle_info.c
index 5be8925b556..ddfcb9476f4 100644
--- a/source/blender/nodes/shader/nodes/node_shader_particle_info.c
+++ b/source/blender/nodes/shader/nodes/node_shader_particle_info.c
@@ -31,6 +31,13 @@ static bNodeSocketTemplate outputs[] = {
{ SOCK_FLOAT, 0, "Index" },
{ SOCK_FLOAT, 0, "Age" },
{ SOCK_FLOAT, 0, "Lifetime" },
+ { SOCK_VECTOR, 0, "Location" },
+ #if 0 /* quaternion sockets not yet supported */
+ { SOCK_QUATERNION, 0, "Rotation" },
+ #endif
+ { SOCK_FLOAT, 0, "Size" },
+ { SOCK_VECTOR, 0, "Velocity" },
+ { SOCK_VECTOR, 0, "Angular Velocity" },
{ -1, 0, "" }
};