[Bf-blender-cvs] [db26a326018] functions: store emit location in particles

Jacques Lucke noreply at git.blender.org
Wed Dec 4 14:28:23 CET 2019


Commit: db26a326018926a54cc7789aa0a9a700e427622b
Author: Jacques Lucke
Date:   Wed Dec 4 14:27:11 2019 +0100
Branches: functions
https://developer.blender.org/rBdb26a326018926a54cc7789aa0a9a700e427622b

store emit location in particles

===================================================================

M	release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
M	source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
M	source/blender/simulations/bparticles/emitters.cpp
M	source/blender/simulations/bparticles/node_frontend.cpp

===================================================================

diff --git a/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
index ea3b4237a03..576eda9a488 100644
--- a/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
+++ b/release/scripts/startup/nodes/bparticle_nodes/particle_inputs.py
@@ -13,3 +13,4 @@ class ParticleInfoNode(bpy.types.Node, SimulationNode):
         builder.fixed_output("position", "Position", "Vector")
         builder.fixed_output("velocity", "Velocity", "Vector")
         builder.fixed_output("birth_time", "Birth Time", "Float")
+        builder.fixed_output("emit_location", "Emit Location", "Surface Location")
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
index 7bed07f0424..18627164f8a 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
@@ -6,6 +6,8 @@
 
 #include "BLI_math_cxx.h"
 
+#include "BKE_surface_location.h"
+
 namespace FN {
 
 using BLI::float3;
@@ -354,6 +356,12 @@ static void INSERT_particle_info(VNodeMFNetworkBuilder &builder)
     MFBuilderFunctionNode &node = network_builder.add_function(fn);
     network_builder.map_sockets(xnode.output(3), node.output(0));
   }
+  {
+    const MultiFunction &fn = network_builder.construct_fn<MF_ParticleAttributes>(
+        "Emit Location", CPP_TYPE<BKE::SurfaceLocation>());
+    MFBuilderFunctionNode &node = network_builder.add_function(fn);
+    network_builder.map_sockets(xnode.output(4), node.output(0));
+  }
 }
 
 static void INSERT_closest_location_on_object(VNodeMFNetworkBuilder &builder)
diff --git a/source/blender/simulations/bparticles/emitters.cpp b/source/blender/simulations/bparticles/emitters.cpp
index eb0894ae834..3aae5d620ef 100644
--- a/source/blender/simulations/bparticles/emitters.cpp
+++ b/source/blender/simulations/bparticles/emitters.cpp
@@ -6,6 +6,7 @@
 #include "BKE_curve.h"
 #include "BKE_mesh_runtime.h"
 #include "BKE_deform.h"
+#include "BKE_surface_location.h"
 
 #include "BLI_math_geom.h"
 #include "BLI_vector_adaptor.h"
@@ -15,6 +16,7 @@
 
 namespace BParticles {
 
+using BKE::SurfaceLocation;
 using BLI::VectorAdaptor;
 
 static float random_float()
@@ -49,18 +51,17 @@ void PointEmitter::emit(EmitterInterface &interface)
   }
 }
 
-static float3 random_point_in_triangle(float3 a, float3 b, float3 c)
+static float3 random_uniform_bary_coords()
 {
-  float3 dir1 = b - a;
-  float3 dir2 = c - a;
-  float rand1, rand2;
+  float rand1 = random_float();
+  float rand2 = random_float();
 
-  do {
-    rand1 = random_float();
-    rand2 = random_float();
-  } while (rand1 + rand2 > 1.0f);
+  if (rand1 + rand2 > 1.0f) {
+    rand1 = 1.0f - rand1;
+    rand2 = 1.0f - rand2;
+  }
 
-  return a + dir1 * rand1 + dir2 * rand2;
+  return float3(rand1, rand2, 1.0f - rand1 - rand2);
 }
 
 static BLI_NOINLINE void get_average_triangle_weights(const Mesh *mesh,
@@ -199,7 +200,8 @@ static BLI_NOINLINE void sample_looptris(Mesh *mesh,
                                          ArrayRef<MLoopTri> triangles,
                                          ArrayRef<uint> triangles_to_sample,
                                          MutableArrayRef<float3> r_sampled_positions,
-                                         MutableArrayRef<float3> r_sampled_normals)
+                                         MutableArrayRef<float3> r_sampled_normals,
+                                         MutableArrayRef<float3> r_sampled_bary_coords)
 {
   BLI_assert(triangles_to_sample.size() == r_sampled_positions.size());
 
@@ -214,12 +216,17 @@ static BLI_NOINLINE void sample_looptris(Mesh *mesh,
     float3 v2 = verts[loops[triangle.tri[1]].v].co;
     float3 v3 = verts[loops[triangle.tri[2]].v].co;
 
-    float3 position = random_point_in_triangle(v1, v2, v3);
+    float3 bary_coords = random_uniform_bary_coords();
+
+    float3 position;
+    interp_v3_v3v3v3(position, v1, v2, v3, bary_coords);
+
     float3 normal;
     normal_tri_v3(normal, v1, v2, v3);
 
     r_sampled_positions[i] = position;
     r_sampled_normals[i] = normal;
+    r_sampled_bary_coords[i] = bary_coords;
   }
 }
 
@@ -270,7 +277,9 @@ void SurfaceEmitter::emit(EmitterInterface &interface)
 
   TemporaryArray<float3> local_positions(particles_to_emit);
   TemporaryArray<float3> local_normals(particles_to_emit);
-  sample_looptris(mesh, triangles, triangles_to_sample, local_positions, local_normals);
+  TemporaryArray<float3> bary_coords(particles_to_emit);
+  sample_looptris(
+      mesh, triangles, triangles_to_sample, local_positions, local_normals, bary_coords);
 
   float epsilon = 0.01f;
   TemporaryArray<float4x4> transforms_at_birth(particles_to_emit);
@@ -295,11 +304,18 @@ void SurfaceEmitter::emit(EmitterInterface &interface)
   TemporaryArray<float> birth_times(particles_to_emit);
   interface.time_span().interpolate(birth_moments, birth_times);
 
+  TemporaryArray<SurfaceLocation> emit_locations(particles_to_emit);
+  BKE::ObjectIDHandle object_handle(m_object);
+  for (uint i = 0; i < particles_to_emit; i++) {
+    emit_locations[i] = SurfaceLocation(object_handle, triangles_to_sample[i], bary_coords[i]);
+  }
+
   for (StringRef system_name : m_systems_to_emit) {
     auto new_particles = interface.particle_allocator().request(system_name,
                                                                 positions_at_birth.size());
     new_particles.set<float3>("Position", positions_at_birth);
     new_particles.set<float>("Birth Time", birth_times);
+    new_particles.set<SurfaceLocation>("Emit Location", emit_locations);
 
     m_on_birth_action.execute_from_emitter<MeshSurfaceContext>(
         new_particles, interface, [&](IndexRange range, void *dst) {
diff --git a/source/blender/simulations/bparticles/node_frontend.cpp b/source/blender/simulations/bparticles/node_frontend.cpp
index cb1f09d9e43..1dc6407809d 100644
--- a/source/blender/simulations/bparticles/node_frontend.cpp
+++ b/source/blender/simulations/bparticles/node_frontend.cpp
@@ -800,6 +800,7 @@ static void collect_influences(VTreeData &inlined_tree_data,
     attributes.add<float3>("Velocity", float3(0, 0, 0));
     attributes.add<float>("Size", 0.05f);
     attributes.add<rgba_f>("Color", rgba_f(1, 1, 1, 1));
+    attributes.add<BKE::SurfaceLocation>("Emit Location", {});
 
     ArrayRef<Force *> forces = collector.m_forces.lookup_default(system_name);
     EulerIntegrator *integrator = new EulerIntegrator(forces);



More information about the Bf-blender-cvs mailing list