Internal support for rotating duplis according to the ground slope normal.
authorLukas Tönne <lukas.toenne@gmail.com>
Tue, 16 Dec 2014 10:17:44 +0000 (11:17 +0100)
committerLukas Tönne <lukas.toenne@gmail.com>
Tue, 16 Dec 2014 10:17:44 +0000 (11:17 +0100)
object_physics_meadow/blob.py
object_physics_meadow/duplimesh.py

index c622ddb..3eb135b 100644 (file)
@@ -202,6 +202,8 @@ def object_free_blob_data(ob):
         del ob.meadow['blobs']
 
 def make_blob_visualizer(context, groundob, blobs, display_radius, hide, hide_render=True):
+    slope_factor = 1.0
+
     # common parent empty for blobs
     blob_parent = get_blob_parent(context, groundob.matrix_world, _sampleviz_parent_name)
     blob_parent.hide = hide
@@ -212,8 +214,14 @@ def make_blob_visualizer(context, groundob, blobs, display_radius, hide, hide_re
     # before creating the actual duplicator blob meshes
     for index, blob in enumerate(blobs):
         if blob:
-            samples = [(loc, nor) for loc, nor, _, _, _ in blob.samples]
-            ob = make_blob_object(context, index, blob.loc, samples, display_radius)
+            # generator for duplimesh, yielding (loc, rot) pairs
+            def mesh_samples():
+                up = Vector((0,0,1))
+                for loc, nor, _, _, _ in blob.samples:
+                    mat = (slope_factor * up.rotation_difference(nor)).to_matrix()
+                    mat.resize_4x4()
+                    yield loc, mat
+            ob = make_blob_object(context, index, blob.loc, mesh_samples(), display_radius)
             # put it in the blob group
             blob_group_assign(context, ob)
             # use parent to keep the outliner clean
@@ -313,6 +321,8 @@ def assign_sample_patches(groundob, blob, patches):
     return vgroup_samples
 
 def setup_blob_duplis(context, groundob, display_radius):
+    slope_factor = 0.0
+
     blobs = blobs_from_customprops(groundob.meadow)
 
     patches = [ob for ob in patch_objects(context) if blobs[ob.meadow.blob_index] is not None]
@@ -339,11 +349,19 @@ def setup_blob_duplis(context, groundob, display_radius):
                 del_patches.add(ob)
                 continue
             
+            # generator for duplimesh, yielding (loc, rot) pairs
+            def mesh_samples():
+                up = Vector((0,0,1))
+                for loc, nor in samples:
+                    mat = (slope_factor * up.rotation_difference(nor)).to_matrix()
+                    mat.resize_4x4()
+                    yield loc, mat
+
             if ob.meadow.use_as_dupli:
                 # make a duplicator for the patch object
                 # XXX use a tiny radius here to hide them in the viewport as much as possible
                 # this is not ideal, but we can't easily separate duplicator visibility and dupli visibility
-                dob = make_blob_object(context, blob_index, blob.loc, samples, 0.0001)
+                dob = make_blob_object(context, blob_index, blob.loc, mesh_samples(), 0.0001)
                 # put the duplicator in the patch group,
                 # so it gets removed together with patch copies
                 patch_group_assign(context, dob)
index b0f2658..e84a115 100644 (file)
@@ -42,33 +42,35 @@ def project_on_ground(groundob, co):
 
 
 def make_dupli_mesh(name, obmat, samples, scale):
-    tot = len(samples)
     scalemat = Matrix()
     scalemat[0][0] = scalemat[1][1] = scalemat[2][2] = scale
     scalemat[3][3] = 1.0
     
     invobmat = obmat.inverted()
     
-    def verts():
-        for loc, nor in samples:
-            mat = Matrix.Translation(loc) * invobmat * scalemat
-            yield ( mat * Vector((-0.86603, -0.5, 0.0)) )[:]
-            yield ( mat * Vector(( 0.86603, -0.5, 0.0)) )[:]
-            yield ( mat * Vector(( 0.0,      1.0, 0.0)) )[:]
+    def make_verts():
+        verts = []
+        for i, (loc, rot) in enumerate(samples):
+            mat = Matrix.Translation(loc) * invobmat * rot * scalemat
+            verts.append(mat * Vector((-0.86603, -0.5, 0.0)))
+            verts.append(mat * Vector(( 0.86603, -0.5, 0.0)))
+            verts.append(mat * Vector(( 0.0,      1.0, 0.0)))
+        return i, verts
     
-    def edges():
+    def edges(tot):
         for i in range(tot):
             yield (i*3 + 0, i*3 + 1)
             yield (i*3 + 1, i*3 + 2)
             yield (i*3 + 2, i*3 + 0)
     
-    def faces():
+    def faces(tot):
         for i in range(tot):
             yield (i*3 + 0, i*3 + 1, i*3 + 2)
     
+    tot, verts = make_verts()
     mesh = bpy.data.meshes.new(name)
     # XXX edges somehow are broken, but can be calculated automatically
-    #mesh.from_pydata([v for v in verts()], [e for e in edges()], [f for f in faces()])
-    mesh.from_pydata([v for v in verts()], [], [f for f in faces()])
+    #mesh.from_pydata(verts, [e for e in edges(tot)], [f for f in faces(tot)])
+    mesh.from_pydata(verts, [], [f for f in faces(tot)])
     mesh.update()
     return mesh