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:
Diffstat (limited to 'intern/cycles')
-rw-r--r--intern/cycles/blender/CMakeLists.txt1
-rw-r--r--intern/cycles/blender/blender_object.cpp3
-rw-r--r--intern/cycles/blender/blender_smoke.cpp96
-rw-r--r--intern/cycles/blender/blender_sync.h2
-rw-r--r--intern/cycles/blender/blender_util.h8
-rw-r--r--intern/cycles/kernel/kernel_textures.h3
-rw-r--r--intern/cycles/kernel/kernel_types.h1
-rw-r--r--intern/cycles/kernel/svm/svm.h3
-rw-r--r--intern/cycles/kernel/svm/svm_geometry.h17
-rw-r--r--intern/cycles/kernel/svm/svm_types.h7
-rw-r--r--intern/cycles/render/nodes.cpp32
-rw-r--r--intern/cycles/render/nodes.h6
-rw-r--r--intern/cycles/render/object.cpp38
-rw-r--r--intern/cycles/render/object.h5
-rw-r--r--intern/cycles/render/scene.h3
15 files changed, 223 insertions, 2 deletions
diff --git a/intern/cycles/blender/CMakeLists.txt b/intern/cycles/blender/CMakeLists.txt
index a8c7eef89fa..6e77daf6f8d 100644
--- a/intern/cycles/blender/CMakeLists.txt
+++ b/intern/cycles/blender/CMakeLists.txt
@@ -23,6 +23,7 @@ set(SRC
blender_mesh.cpp
blender_object.cpp
blender_particles.cpp
+ blender_smoke.cpp
blender_python.cpp
blender_session.cpp
blender_shader.cpp
diff --git a/intern/cycles/blender/blender_object.cpp b/intern/cycles/blender/blender_object.cpp
index 242f7c8ecef..fe6488efb3f 100644
--- a/intern/cycles/blender/blender_object.cpp
+++ b/intern/cycles/blender/blender_object.cpp
@@ -277,6 +277,9 @@ void BlenderSync::sync_object(BL::Object b_parent, int b_index, BL::Object b_ob,
/* particle sync */
if (object_use_particles(b_ob))
sync_particles(object, b_ob);
+
+ if(object_use_smoke(b_ob))
+ sync_smoke(object, b_ob);
object->tag_update(scene);
}
diff --git a/intern/cycles/blender/blender_smoke.cpp b/intern/cycles/blender/blender_smoke.cpp
new file mode 100644
index 00000000000..e59d9bea01d
--- /dev/null
+++ b/intern/cycles/blender/blender_smoke.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright 2011, Blender Foundation.
+ *
+ * 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.
+ */
+
+#include "object.h"
+
+#include "mesh.h"
+#include "blender_sync.h"
+#include "blender_util.h"
+
+#include "util_foreach.h"
+
+CCL_NAMESPACE_BEGIN
+
+/* Utilities */
+
+
+/* Smoke Sync */
+
+/* Only looking for Smoke domains */
+// TODO DG: disable rendering of smoke flow??
+bool BlenderSync::object_use_smoke(BL::Object b_ob)
+{
+ BL::Object::modifiers_iterator b_modifiers;
+ for(b_ob.modifiers.begin(b_modifiers); b_modifiers != b_ob.modifiers.end(); ++b_modifiers) {
+ BL::Modifier mod = (*b_modifiers);
+
+ if (mod.is_a(&RNA_SmokeModifier)) {
+ BL::SmokeModifier smd(mod);
+
+ if(smd.smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN) {
+ BL::ID key = (BKE_object_is_modified(b_ob))? b_ob: b_ob.data();
+ Mesh *mesh = mesh_map.find(key);
+ if (mesh) {
+ return mesh->need_attribute(scene, ATTR_STD_SMOKE_DENSITY);
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+static BL::SmokeModifier *get_smoke(BL::Object b_ob)
+{
+ BL::Object::modifiers_iterator b_modifiers;
+ for(b_ob.modifiers.begin(b_modifiers); b_modifiers != b_ob.modifiers.end(); ++b_modifiers) {
+ BL::Modifier mod = (*b_modifiers);
+
+ if (mod.is_a(&RNA_SmokeModifier)) {
+ BL::SmokeModifier *smd = (BL::SmokeModifier *)(&mod);
+
+ if(smd->smoke_type() == BL::SmokeModifier::smoke_type_DOMAIN) {
+ return smd;
+ }
+ }
+ }
+
+ return NULL;
+}
+
+void BlenderSync::sync_smoke(Object *ob, BL::Object b_ob)
+{
+ BL::SmokeModifier *smd = get_smoke(b_ob);
+ BL::SmokeDomainSettings sds = smd->domain_settings();
+
+ ob->grid.clear();
+ ob->resolution = get_int3(sds.domain_resolution());
+
+ int length[3];
+ int numcells = rna_SmokeModifier_density_get_length(&sds.ptr, length);
+
+ if(numcells != 0)
+ {
+ vector<float> &grid = ob->grid;
+ grid.reserve(numcells);
+ grid.resize(numcells);
+ rna_SmokeModifier_density_get(&sds.ptr, &grid[0]);
+ }
+}
+
+CCL_NAMESPACE_END
diff --git a/intern/cycles/blender/blender_sync.h b/intern/cycles/blender/blender_sync.h
index 1a6c04db10c..a82c9e29b43 100644
--- a/intern/cycles/blender/blender_sync.h
+++ b/intern/cycles/blender/blender_sync.h
@@ -86,10 +86,12 @@ private:
void sync_mesh_motion(BL::Object b_ob, Mesh *mesh, int motion);
void sync_camera_motion(BL::Object b_ob, int motion);
void sync_particles(Object *ob, BL::Object b_ob);
+ void sync_smoke(Object *ob, BL::Object b_ob);
/* util */
void find_shader(BL::ID id, vector<uint>& used_shaders, int default_shader);
bool BKE_object_is_modified(BL::Object b_ob);
+ bool object_use_smoke(BL::Object b_ob);
bool object_is_mesh(BL::Object b_ob);
bool object_is_light(BL::Object b_ob);
bool object_use_particles(BL::Object b_ob);
diff --git a/intern/cycles/blender/blender_util.h b/intern/cycles/blender/blender_util.h
index ebbd4e1221c..3639d85c03a 100644
--- a/intern/cycles/blender/blender_util.h
+++ b/intern/cycles/blender/blender_util.h
@@ -56,6 +56,9 @@ void rna_Scene_frame_set(void *scene, int frame, float subframe);
void BKE_image_user_frame_calc(void *iuser, int cfra, int fieldnr);
void BKE_image_user_file_path(void *iuser, void *ima, char *path);
+int rna_SmokeModifier_density_get_length(PointerRNA *ptr, int length[3]);
+void rna_SmokeModifier_density_get(PointerRNA *ptr, float *values);
+
}
CCL_NAMESPACE_BEGIN
@@ -155,6 +158,11 @@ static inline int4 get_int4(BL::Array<int, 4> array)
return make_int4(array[0], array[1], array[2], array[3]);
}
+static inline int3 get_int3(BL::Array<int, 3> array)
+{
+ return make_int3(array[0], array[1], array[2]);
+}
+
static inline uint get_layer(BL::Array<int, 20> array)
{
uint layer = 0;
diff --git a/intern/cycles/kernel/kernel_textures.h b/intern/cycles/kernel/kernel_textures.h
index c1b8eed3dff..196dbdc9d60 100644
--- a/intern/cycles/kernel/kernel_textures.h
+++ b/intern/cycles/kernel/kernel_textures.h
@@ -55,6 +55,9 @@ KERNEL_TEX(float2, texture_float2, __light_background_conditional_cdf)
/* particles */
KERNEL_TEX(float4, texture_float4, __particles)
+/* Smoke */
+KERNEL_TEX(float, texture_float, __smoke_density)
+
/* shaders */
KERNEL_TEX(uint4, texture_uint4, __svm_nodes)
KERNEL_TEX(uint, texture_uint, __shader_flag)
diff --git a/intern/cycles/kernel/kernel_types.h b/intern/cycles/kernel/kernel_types.h
index 30d45ad1118..0a7835acd42 100644
--- a/intern/cycles/kernel/kernel_types.h
+++ b/intern/cycles/kernel/kernel_types.h
@@ -363,6 +363,7 @@ typedef enum AttributeStandard {
ATTR_STD_MOTION_PRE,
ATTR_STD_MOTION_POST,
ATTR_STD_PARTICLE,
+ ATTR_STD_SMOKE_DENSITY,
ATTR_STD_NUM,
ATTR_STD_NOT_FOUND = ~0
diff --git a/intern/cycles/kernel/svm/svm.h b/intern/cycles/kernel/svm/svm.h
index 8901e5e9628..1ee5ed21fc7 100644
--- a/intern/cycles/kernel/svm/svm.h
+++ b/intern/cycles/kernel/svm/svm.h
@@ -272,6 +272,9 @@ __device_noinline void svm_eval_nodes(KernelGlobals *kg, ShaderData *sd, ShaderT
case NODE_PARTICLE_INFO:
svm_node_particle_info(kg, sd, stack, node.y, node.z);
break;
+ case NODE_SMOKE_DENSITY:
+ svm_node_smoke_density(kg, sd, stack, node.y, node.z);
+ break;
#endif
case NODE_CONVERT:
svm_node_convert(sd, stack, node.y, node.z, node.w);
diff --git a/intern/cycles/kernel/svm/svm_geometry.h b/intern/cycles/kernel/svm/svm_geometry.h
index 3cfce1d087a..bc4c992f14d 100644
--- a/intern/cycles/kernel/svm/svm_geometry.h
+++ b/intern/cycles/kernel/svm/svm_geometry.h
@@ -122,5 +122,22 @@ __device void svm_node_particle_info(KernelGlobals *kg, ShaderData *sd, float *s
}
}
+
+/* Smoke Density */
+
+__device void svm_node_smoke_density(KernelGlobals *kg, ShaderData *sd, float *stack, uint type, uint out_offset)
+{
+ float data;
+
+ switch(type) {
+ case NODE_INFO_SMO_DEN: {
+ // DG TODO uint particle_id = object_particle_id(kg, sd->object);
+ // DG TODO data = smoke_density(kg, WHICH CELL IN GRID?);
+ // DG TODO stack_store_float(stack, out_offset, data);
+ break;
+ }
+ }
+}
+
CCL_NAMESPACE_END
diff --git a/intern/cycles/kernel/svm/svm_types.h b/intern/cycles/kernel/svm/svm_types.h
index cbff0c099ea..12075179b8b 100644
--- a/intern/cycles/kernel/svm/svm_types.h
+++ b/intern/cycles/kernel/svm/svm_types.h
@@ -89,7 +89,8 @@ typedef enum NodeType {
NODE_MIN_MAX,
NODE_LIGHT_FALLOFF,
NODE_OBJECT_INFO,
- NODE_PARTICLE_INFO
+ NODE_PARTICLE_INFO,
+ NODE_SMOKE_DENSITY
} NodeType;
typedef enum NodeAttributeType {
@@ -119,6 +120,10 @@ typedef enum NodeParticleInfo {
NODE_INFO_PAR_LIFETIME
} NodeParticleInfo;
+typedef enum NodeSmokeDensity {
+ NODE_INFO_SMO_DEN
+} NodeSmokeDensity;
+
typedef enum NodeLightPath {
NODE_LP_camera = 0,
NODE_LP_shadow,
diff --git a/intern/cycles/render/nodes.cpp b/intern/cycles/render/nodes.cpp
index 250570e1d65..d86dbb92267 100644
--- a/intern/cycles/render/nodes.cpp
+++ b/intern/cycles/render/nodes.cpp
@@ -1843,6 +1843,38 @@ void ParticleInfoNode::compile(OSLCompiler& compiler)
compiler.add(this, "node_particle_info");
}
+/* Smoke Density */
+
+SmokeDensityNode::SmokeDensityNode()
+: ShaderNode("particle_info")
+{
+ add_output("Density", SHADER_SOCKET_FLOAT);
+}
+
+void SmokeDensityNode::attributes(AttributeRequestSet *attributes)
+{
+ if(!output("Density")->links.empty())
+ attributes->add(ATTR_STD_SMOKE_DENSITY);
+
+ ShaderNode::attributes(attributes);
+}
+
+void SmokeDensityNode::compile(SVMCompiler& compiler)
+{
+ ShaderOutput *out;
+
+ out = output("Density");
+ if(!out->links.empty()) {
+ compiler.stack_assign(out);
+ compiler.add_node(NODE_SMOKE_DENSITY, NODE_INFO_SMO_DEN, out->stack_offset);
+ }
+}
+
+void SmokeDensityNode::compile(OSLCompiler& compiler)
+{
+ compiler.add(this, "node_smoke_density");
+}
+
/* Value */
ValueNode::ValueNode()
diff --git a/intern/cycles/render/nodes.h b/intern/cycles/render/nodes.h
index efd814e4ae6..f07ab9b3e33 100644
--- a/intern/cycles/render/nodes.h
+++ b/intern/cycles/render/nodes.h
@@ -296,6 +296,12 @@ public:
void attributes(AttributeRequestSet *attributes);
};
+class SmokeDensityNode : public ShaderNode {
+public:
+ SHADER_NODE_CLASS(SmokeDensityNode)
+ void attributes(AttributeRequestSet *attributes);
+};
+
class ValueNode : public ShaderNode {
public:
SHADER_NODE_CLASS(ValueNode)
diff --git a/intern/cycles/render/object.cpp b/intern/cycles/render/object.cpp
index 0fe227fd171..8692f61b3f6 100644
--- a/intern/cycles/render/object.cpp
+++ b/intern/cycles/render/object.cpp
@@ -167,7 +167,7 @@ void ObjectManager::device_update_transforms(Device *device, DeviceScene *dscene
float uniform_scale;
float surface_area = 0.0f;
float pass_id = ob->pass_id;
- float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF);
+ float random_number = (float)ob->random_id * (1.0f/(float)0xFFFFFFFF)+0.5f;
if(transform_uniform_scale(tfm, uniform_scale)) {
map<Mesh*, float>::iterator it = surface_area_map.find(mesh);
@@ -281,6 +281,37 @@ void ObjectManager::device_update_particles(Device *device, DeviceScene *dscene,
device->tex_alloc("__particles", dscene->particles);
}
+void ObjectManager::device_update_smoke(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
+{
+ /* count smoke cells.
+ * adds one dummy particle at the beginning to avoid invalid lookups,
+ * in case a shader uses particle info without actual particle data.
+ */
+ int num_cells = 1;
+ foreach(Object *ob, scene->objects)
+ num_cells += ob->grid.size();
+
+ float *density = dscene->smoke_density.resize(num_cells);
+
+ /* dummy particle */
+ // DG TODO density[0] = 0.0f;
+
+ int i = 0;
+ foreach(Object *ob, scene->objects) {
+ /* pack in texture */
+ for(i = 0; i < ob->grid.size(); i++) {
+
+ // DG TODO: use "*PARTICLE_SIZE"?
+ density[i] = ob->grid[i];
+
+ if(progress.get_cancel()) return;
+
+ }
+ }
+
+ device->tex_alloc("__smoke_density", dscene->smoke_density);
+}
+
void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress)
{
if(!need_update)
@@ -311,6 +342,11 @@ void ObjectManager::device_update(Device *device, DeviceScene *dscene, Scene *sc
if(progress.get_cancel()) return;
+ progress.set_status("Updating Objects", "Copying Smoke Density to device");
+ device_update_smoke(device, dscene, scene, progress);
+
+ if(progress.get_cancel()) return;
+
need_update = false;
}
diff --git a/intern/cycles/render/object.h b/intern/cycles/render/object.h
index 9b2f5bc8768..a15860b4780 100644
--- a/intern/cycles/render/object.h
+++ b/intern/cycles/render/object.h
@@ -58,6 +58,10 @@ public:
int particle_id;
vector<Particle> particles;
+ /* Voxel / 3D volume data */
+ int3 resolution;
+ vector<float> grid;
+
Object();
~Object();
@@ -79,6 +83,7 @@ public:
void device_update(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_transforms(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_update_particles(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
+ void device_update_smoke(Device *device, DeviceScene *dscene, Scene *scene, Progress& progress);
void device_free(Device *device, DeviceScene *dscene);
void tag_update(Scene *scene);
diff --git a/intern/cycles/render/scene.h b/intern/cycles/render/scene.h
index 8b9944cb76e..0cd94dd1e65 100644
--- a/intern/cycles/render/scene.h
+++ b/intern/cycles/render/scene.h
@@ -85,6 +85,9 @@ public:
/* particles */
device_vector<float4> particles;
+ /* smoke */
+ device_vector<float> smoke_density;
+
/* shaders */
device_vector<uint4> svm_nodes;
device_vector<uint> shader_flag;