예제 #1
0
def get_collider_aligned_rots(self, context, coords, directions):
    '''
    Takes the location coordinates and the
    corresponding direction vectors.
    Creates a left and a right rotation Matrix
    aligned to the surface of the collider Mesh.
    '''
    mat_rots = []
    for co, direction in zip(coords, directions):
        hit, normal, face, distance = self.bvh.find_nearest(co)
        vec_left = -direction.cross(normal).normalized()
        vec_right = direction.cross(normal).normalized()

        vec_left = direction.lerp(vec_left, self.rot_align_left_right).normalized()
        vec_right = direction.lerp(vec_right, self.rot_align_left_right).normalized()

        vec_left = vec_left.lerp(normal, self.rot_align_normal).normalized()
        vec_right = vec_right.lerp(normal, self.rot_align_normal).normalized()

        vec_left += noise.random_unit_vector() * self.rot_random
        vec_right += noise.random_unit_vector() * self.rot_random

        mat_left = align(vec_left, normal)
        mat_right = align(vec_right, normal)

        mat_rots.extend([mat_left, mat_right])

    return mat_rots
def get_collider_aligned_rots(self, context, coords, directions):
    '''
    Takes the location coordinates and the
    corresponding direction vectors.
    Creates a left and a right rotation Matrix
    aligned to the surface of the collider Mesh.
    '''
    mat_rots = []
    for co, direction in zip(coords, directions):
        hit, normal, face, distance = self.bvh.find_nearest(co)
        vec_left = -direction.cross(normal).normalized()
        vec_right = direction.cross(normal).normalized()

        vec_left = direction.lerp(vec_left,
                                  self.rot_align_left_right).normalized()
        vec_right = direction.lerp(vec_right,
                                   self.rot_align_left_right).normalized()

        vec_left = vec_left.lerp(normal, self.rot_align_normal).normalized()
        vec_right = vec_right.lerp(normal, self.rot_align_normal).normalized()

        vec_left += noise.random_unit_vector() * self.rot_random
        vec_right += noise.random_unit_vector() * self.rot_random

        mat_left = align(vec_left, normal)
        mat_right = align(vec_right, normal)

        mat_rots.extend([mat_left, mat_right])

    return mat_rots
예제 #3
0
    def process(self):

        count_socket = self.inputs['Count']
        seed_socket = self.inputs['Seed']
        scale_socket = self.inputs['Scale']
        random_socket = self.outputs['Random']

        # inputs
        Coun = count_socket.sv_get(deepcopy=False)[0]
        Seed = seed_socket.sv_get(deepcopy=False)[0]
        Scale = scale_socket.sv_get(deepcopy=False, default=[])[0]

        # outputs
        if random_socket.is_linked:
            Random = []
            param = match_long_repeat([Coun, Seed, Scale])
            # set seed, protect against float input
            # seed = 0 is special value for blender which unsets the seed value
            # and starts to use system time making the random values unrepeatable.
            # So when seed = 0 we use a random value far from 0, generated used random.org
            for c, s, sc in zip(*param):
                int_seed = int(round(s))
                if int_seed:
                    seed_set(int_seed)
                else:
                    seed_set(140230)

                Random.append([(random_unit_vector()*sc).to_tuple() for i in range(int(max(1, c)))])

            random_socket.sv_set(Random)
예제 #4
0
def get_offset(seed):
    if seed == 0:
        offset = [0.0, 0.0, 0.0]
    else:
        noise.seed_set(seed)
        offset = noise.random_unit_vector() * 10.0
    return offset
예제 #5
0
def get_offset(seed):
    if seed == 0:
        offset = [0.0, 0.0, 0.0]
    else:
        noise.seed_set(seed)
        offset = noise.random_unit_vector() * 10.0
    return offset
예제 #6
0
    def process(self):
        # inputs
        if 'Count' in self.inputs and self.inputs['Count'].links and \
           type(self.inputs['Count'].links[0].from_socket) == bpy.types.StringsSocket:
            Coun = SvGetSocketAnyType(self, self.inputs['Count'])[0]
        else:
            Coun = [self.count_inner]

        if 'Seed' in self.inputs and self.inputs['Seed'].links and \
           type(self.inputs['Seed'].links[0].from_socket) == bpy.types.StringsSocket:
            Seed = SvGetSocketAnyType(self, self.inputs['Seed'])[0]
        else:
            Seed = [self.seed]

        # outputs
        if 'Random' in self.outputs and self.outputs['Random'].links:
            Random = []
            param = match_long_repeat([Coun, Seed])
            # set seed, protect against float input
            # seed = 0 is special value for blender which unsets the seed value
            # and starts to use system time making the random values unrepeatable.
            # So when seed = 0 we use a random value far from 0, generated used random.org
            for c, s in zip(*param):
                int_seed = int(round(s))
                if int_seed:
                    seed_set(int_seed)
                else:
                    seed_set(140230)

                Random.append([random_unit_vector().to_tuple() for i in range(int(max(1, c)))])

            SvSetSocketAnyType(self, 'Random', Random)
예제 #7
0
    def process(self):
        # inputs
        if 'Count' in self.inputs and self.inputs['Count'].links and \
           type(self.inputs['Count'].links[0].from_socket) == bpy.types.StringsSocket:
            Coun = SvGetSocketAnyType(self, self.inputs['Count'])[0]
        else:
            Coun = [self.count_inner]

        if 'Seed' in self.inputs and self.inputs['Seed'].links and \
           type(self.inputs['Seed'].links[0].from_socket) == bpy.types.StringsSocket:
            Seed = SvGetSocketAnyType(self, self.inputs['Seed'])[0]
        else:
            Seed = [self.seed]

        # outputs
        if 'Random' in self.outputs and self.outputs['Random'].links:
            Random = []
            param = match_long_repeat([Coun, Seed])
            # set seed, protect against float input
            # seed = 0 is special value for blender which unsets the seed value
            # and starts to use system time making the random values unrepeatable.
            # So when seed = 0 we use a random value far from 0, generated used random.org
            for c, s in zip(*param):
                int_seed = int(round(s))
                if int_seed:
                    seed_set(int_seed)
                else:
                    seed_set(140230)

                Random.append([
                    random_unit_vector().to_tuple()
                    for i in range(int(max(1, c)))
                ])

            SvSetSocketAnyType(self, 'Random', Random)
예제 #8
0
    def process(self):

        count_socket = self.inputs['Count']
        seed_socket = self.inputs['Seed']
        scale_socket = self.inputs['Scale']
        random_socket = self.outputs['Random']

        # inputs
        Coun = count_socket.sv_get(deepcopy=False)[0]
        Seed = seed_socket.sv_get(deepcopy=False)[0]
        Scale = scale_socket.sv_get(deepcopy=False, default=[])[0]

        # outputs
        if random_socket.is_linked:
            Random = []
            param = match_long_repeat([Coun, Seed, Scale])
            # set seed, protect against float input
            # seed = 0 is special value for blender which unsets the seed value
            # and starts to use system time making the random values unrepeatable.
            # So when seed = 0 we use a random value far from 0, generated used random.org
            for c, s, sc in zip(*param):
                int_seed = int(round(s))
                if int_seed:
                    seed_set(int_seed)
                else:
                    seed_set(140230)

                Random.append([(random_unit_vector() * sc).to_tuple()
                               for i in range(int(max(1, c)))])

            random_socket.sv_set(Random)
예제 #9
0
def grow_branch(context, branchidx, ivy, bvh=None):
    '''
    Should have two branches maybe.
    Test if only the next coordinate is missing:
        if yes only calculate that one.
        Reduce computation per frame update

        if not recalc spline points from start
        as is done now
    '''
    opt = ivy.ivy
    seed_val = opt.seed + branchidx + 1
    seed(seed_val)
    noise.seed_set(seed_val)

    # GET BRANCH-NUMSTEPS FOR THIS FRAME
    if opt.animated:
        # this is fixed steps along animation range
        anim_frames_total = opt.end - opt.start
        anim_frame_current = context.scene.frame_current - opt.start
        numsteps = int(
            (anim_frame_current / anim_frames_total) * opt.fixed_steps)
    else:
        numsteps = opt.fixed_steps

    # CUTOFF NUMSTEPS
    cutoff = random()
    if opt.steps_random_cutoff <= cutoff:
        # cut this one off
        cutoffamount = (1 - cutoff) * opt.cutoffamount
        cutoff += cutoffamount
        numsteps = int(cutoff * numsteps)

    uvec = noise.random_unit_vector()
    start_co = Vector((uvec.x * opt.root_area.x, uvec.y * opt.root_area.y,
                       uvec.z * opt.root_area.z))
    coords = [start_co]

    #free = [True]

    def recalc_all():
        freefloatinglength = 0
        for step in range(numsteps):
            last_co = coords[-1]
            vec_grow = growvec(opt, coords, bvh, freefloatinglength)
            next_co = last_co + vec_grow
            if opt.has_collider:
                next_co, is_free = collision(opt, last_co, next_co, bvh)
                if is_free:
                    freefloatinglength += (last_co - next_co).length
                else:
                    freefloatinglength = 0
            else:
                freefloatinglength += (last_co - next_co).length

            coords.append(next_co)

    recalc_all()

    return coords
예제 #10
0
def grow_branch(context, branchidx, ivy, bvh=None):
    '''
    Should have two branches maybe.
    Test if only the next coordinate is missing:
        if yes only calculate that one.
        Reduce computation per frame update

        if not recalc spline points from start
        as is done now
    '''
    opt = ivy.ivy
    seed_val = opt.seed + branchidx + 1
    seed(seed_val)
    noise.seed_set(seed_val)

    # GET BRANCH-NUMSTEPS FOR THIS FRAME
    if opt.animated:
        # this is fixed steps along animation range
        anim_frames_total = opt.end - opt.start
        anim_frame_current = context.scene.frame_current - opt.start
        numsteps = int((anim_frame_current / anim_frames_total) * opt.fixed_steps)
    else:
        numsteps = opt.fixed_steps

    # CUTOFF NUMSTEPS
    cutoff = random()
    if opt.steps_random_cutoff <= cutoff:
        # cut this one off
        cutoffamount = (1 - cutoff) * opt.cutoffamount
        cutoff += cutoffamount
        numsteps = int(cutoff * numsteps)

    uvec = noise.random_unit_vector()
    start_co = Vector((uvec.x * opt.root_area.x,
                       uvec.y * opt.root_area.y,
                       uvec.z * opt.root_area.z))
    coords = [start_co]
    #free = [True]

    def recalc_all():
        freefloatinglength = 0
        for step in range(numsteps):
            last_co = coords[-1]
            vec_grow = growvec(opt, coords, bvh, freefloatinglength)
            next_co = last_co + vec_grow
            if opt.has_collider:
                next_co, is_free = collision(opt, last_co, next_co, bvh)
                if is_free:
                    freefloatinglength += (last_co - next_co).length
                else:
                    freefloatinglength = 0
            else:
                freefloatinglength += (last_co - next_co).length

            coords.append(next_co)

    recalc_all()

    return coords
예제 #11
0
파일: meshx.py 프로젝트: inconvergent/meshx
  def grow(self):

    self.itt += 1

    self.to_mesh()

    nfaces = len(self.obj.data.polygons)

    face_ind = randint(0,nfaces-1)

    if self.hits[face_ind]>HITMAX:
      #print(self.itt,self.faces,'added nothing. hit count reached')
      return

    face = self.obj.data.polygons[face_ind]

    vertices = self.obj.data.vertices

    fv = face.vertices

    normal = face.normal.copy()
    scaled_normal = normal*self.height

    ru = random_unit_vector()*NOISE

    xyz_loc = Vector((0,0,0))
    for v in fv:
      xyz_loc += vertices[v].co

    xyzn_loc = xyz_loc/3.+scaled_normal+ru

    pos_loc = self.closest_point(xyzn_loc)

    if (xyzn_loc-pos_loc).length<=scaled_normal.length*SEPARATION:
      self.hits[face_ind] += 1
      #print(self.itt,self.faces,'added nothing.')
      return

    xyzn_glob = self.obj.matrix_world*xyzn_loc

    if not self.is_on_geom(xyzn_glob,GEOM_DISTANCE):
      self.hits[face_ind] += 1
      #print(self.itt,self.faces,'added nothing. too far from geometry')
      return

    bm = self.get_bmesh()

    new_face = bmesh.ops.extrude_discrete_faces(bm,
                 faces=[bm.faces[face_ind]])['faces'].pop()

    for v in new_face.verts:
      v.co = xyzn_loc

    bmesh.ops.remove_doubles(bm,verts=new_face.verts,dist=1000)

    self.hits[face_ind] = HITMAX+1
    self.faces += 3

    print(self.itt,self.faces,'new tetrahedron *')
예제 #12
0
def shake(cont):
    own = cont.owner
    
    t = bge.logic.getRealTime()
    n = noise.random_unit_vector()

    own.worldPosition = own.worldPosition + n*own["shake_amount"]
    
예제 #13
0
def random_orientation_matrix(size=4):
    if size == 2:
        V = random_unit_vector(2)
        N = Vector((V.y, -V.x))
        return Matrix([V, N])

    N, V = random_unit_vector(), random_unit_vector()
    E1 = N.cross(V).normalized()
    E2 = N.cross(E1).normalized()
    if (N.length == 0 or E1.length == 0 or E2.length == 0):
        return random_orientation_matrix()

    if size == 3:
        return Matrix([E1, E2, N])
    elif size == 4:
        return Matrix([E1, E2, N]).to_4x4()
    else:
        raise ValueError('can only return 2x2, 3x3 or 4x4 matrix')
예제 #14
0
 def grow_from(self, p):
     growvec = p.direction().normalized()
     growvec += random_unit_vector(size=3) * 0.5
     growvec = growvec.normalized() * 0.1
     child = Particle(id=self.particles[-1].id + 1,
                      co=p.rest.translation + growvec,
                      parent=p)
     p.children.append(child)
     self.particles.append(child)
     print('added particle {id}'.format(id=child.id))
    def __init__(self, index, scale, location=Vector()):
        targ_vel = 0.005 * scale
        self.MAX_VEL = gauss(targ_vel, targ_vel / 10)

        self.location = location.copy()
        self.velocity = noise.random_unit_vector() * self.MAX_VEL
        self.guide_index = index

        self.noise_seed = noise.random_unit_vector()

        self.active = True

        self.direction = randint(0,1)*2-1

#        if index > guide_len/2:
#            self.direction = -1
#        else:
#            self.direction = 1


        self.behaviour = 0.6 # 1 = guide ; 0 = turbulence
예제 #16
0
    def __init__(self, index, scale, location=Vector()):
        targ_vel = 0.005 * scale
        self.MAX_VEL = gauss(targ_vel, targ_vel / 10)
        
        self.location = location.copy()
        self.velocity = noise.random_unit_vector() * self.MAX_VEL
        self.guide_index = index

        self.noise_seed = noise.random_unit_vector()
        
        self.active = True
        
        self.direction = randint(0,1)*2-1
        
#        if index > guide_len/2:
#            self.direction = -1
#        else:
#            self.direction = 1

        
        self.behaviour = 0.6 # 1 = guide ; 0 = turbulence
예제 #17
0
    def process(self):
        # inputs
        if (
            "Count" in self.inputs
            and self.inputs["Count"].links
            and type(self.inputs["Count"].links[0].from_socket) == bpy.types.StringsSocket
        ):
            Coun = SvGetSocketAnyType(self, self.inputs["Count"])[0]
        else:
            Coun = [self.count_inner]

        if (
            "Seed" in self.inputs
            and self.inputs["Seed"].links
            and type(self.inputs["Seed"].links[0].from_socket) == bpy.types.StringsSocket
        ):
            Seed = SvGetSocketAnyType(self, self.inputs["Seed"])[0]
        else:
            Seed = [self.seed]
        if (
            "Scale" in self.inputs
            and self.inputs["Scale"].links
            and type(self.inputs["Scale"].links[0].from_socket) == bpy.types.StringsSocket
        ):
            Scale = self.inputs["Scale"].sv_get(deepcopy=False, default=[])[0]
        else:
            Scale = [self.scale]
        # outputs
        if "Random" in self.outputs and self.outputs["Random"].links:
            Random = []
            param = match_long_repeat([Coun, Seed, Scale])
            # set seed, protect against float input
            # seed = 0 is special value for blender which unsets the seed value
            # and starts to use system time making the random values unrepeatable.
            # So when seed = 0 we use a random value far from 0, generated used random.org
            for c, s, sc in zip(*param):
                int_seed = int(round(s))
                if int_seed:
                    seed_set(int_seed)
                else:
                    seed_set(140230)

                Random.append([(random_unit_vector() * sc).to_tuple() for i in range(int(max(1, c)))])

            SvSetSocketAnyType(self, "Random", Random)
예제 #18
0
 def update(self):
     # inputs
     if 'Count' in self.inputs and len(self.inputs['Count'].links)>0 and \
         type(self.inputs['Count'].links[0].from_socket) == bpy.types.StringsSocket:
         if not self.inputs['Count'].node.socket_value_update:
             self.inputs['Count'].node.update()
         Coun = eval(self.inputs['Count'].links[0].from_socket.StringsProperty)
     else:
         Coun = [[self.count_inner]]
         
     if 'Seed' in self.inputs and len(self.inputs['Seed'].links)>0 and \
          type(self.inputs['Seed'].links[0].from_socket) == bpy.types.StringsSocket:
         if not self.inputs['Seed'].node.socket_value_update:
             self.inputs['Seed'].node.update()
         
         Seed = eval(self.inputs['Seed'].links[0].from_socket.StringsProperty)[0][0]
     else:
         Seed = self.seed
   
     
     # outputs 
     if 'Random' in self.outputs and len(self.outputs['Random'].links)>0:
         Random = []          
         # set seed, protect against float input
         # seed = 0 is special value for blender which unsets the seed value
         # and starts to use system time making the random values unrepeatable.
         # So when seed = 0 we use a random value far from 0, generated used random.org
         int_seed = int(round(Seed))
         if int_seed:
             seed_set(int_seed)
         else:
             seed_set(140230)  
             
         # Coun[0], only takes first list
         for number in Coun[0]:
             if number > 0:
                 Random.append( [random_unit_vector().to_tuple() \
                                     for i in range(int(number))])
         SvSetSocketAnyType(self,'Random',Random)
예제 #19
0
  def make_random_sources_on_geom(self,sinit,init_dist,noise):

    from numpy import row_stack, all, zeros
    from numpy.random import randint
    from scipy.spatial import distance
    cdist = distance.cdist

    self.sinit = sinit
    geom = bpy.data.objects[self.trace_geom]
    verts = geom.data.vertices
    num_verts = len(verts)

    mat = geom.matrix_world

    source_vectors = []
    for i in range(sinit):
      k = randint(0,num_verts)
      v_loc = verts[k]
      v_glob = mat*v_loc.co
      v_glob += random_unit_vector()*noise
      source_vectors.append(v_glob)

    sources = row_stack(source_vectors)
    dss = cdist(sources,sources,'euclidean')
    mask = zeros(sinit,'bool')
    for i in range(sinit-1):
      d = dss[i,i+1:]>init_dist
      ok = all(d)
      if ok:
        mask[i] = True

    self.sources = sources[mask]
    self.dead_sources = []
    self.num_sources = sum(mask)

    return
예제 #20
0
def cell_fracture_objects(
        scene,
        obj,
        source={'PARTICLE_OWN'},
        source_limit=0,
        source_noise=0.0,
        clean=True,
        # operator options
        use_smooth_faces=False,
        use_data_match=False,
        use_debug_points=False,
        margin=0.0,
        material_index=0,
        use_debug_redraw=False,
        cell_scale=(1.0, 1.0, 1.0),
):

    from . import fracture_cell_calc

    # -------------------------------------------------------------------------
    # GET POINTS

    points = _points_from_object(obj, source)

    if not points:
        # print using fallback
        points = _points_from_object(obj, {'VERT_OWN'})

    if not points:
        print("no points found")
        return []

    # apply optional clamp
    if source_limit != 0 and source_limit < len(points):
        import random
        random.shuffle(points)
        points[source_limit:] = []

    # saddly we cant be sure there are no doubles
    from mathutils import Vector
    to_tuple = Vector.to_tuple
    points = list({to_tuple(p, 4): p for p in points}.values())
    del to_tuple
    del Vector

    # end remove doubles
    # ------------------

    if source_noise > 0.0:
        from random import random
        # boundbox approx of overall scale
        from mathutils import Vector
        matrix = obj.matrix_world.copy()
        bb_world = [matrix * Vector(v) for v in obj.bound_box]
        scalar = source_noise * ((bb_world[0] - bb_world[6]).length / 2.0)

        from mathutils.noise import random_unit_vector

        points[:] = [
            p + (random_unit_vector() * (scalar * random())) for p in points
        ]

    if use_debug_points:
        bm = bmesh.new()
        for p in points:
            bm.verts.new(p)
        mesh_tmp = bpy.data.meshes.new(name="DebugPoints")
        bm.to_mesh(mesh_tmp)
        bm.free()
        obj_tmp = bpy.data.objects.new(name=mesh_tmp.name,
                                       object_data=mesh_tmp)
        scene.objects.link(obj_tmp)
        del obj_tmp, mesh_tmp

    mesh = obj.data
    matrix = obj.matrix_world.copy()
    verts = [matrix * v.co for v in mesh.vertices]

    cells = fracture_cell_calc.points_as_bmesh_cells(verts,
                                                     points,
                                                     cell_scale,
                                                     margin_cell=margin)

    # some hacks here :S
    cell_name = obj.name + "_cell"

    objects = []

    for center_point, cell_points in cells:

        # ---------------------------------------------------------------------
        # BMESH

        # create the convex hulls
        bm = bmesh.new()

        # WORKAROUND FOR CONVEX HULL BUG/LIMIT
        # XXX small noise
        import random

        def R():
            return (random.random() - 0.5) * 0.001

        # XXX small noise

        for i, co in enumerate(cell_points):

            # XXX small noise
            co.x += R()
            co.y += R()
            co.z += R()
            # XXX small noise

            bm_vert = bm.verts.new(co)

        import mathutils
        bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.005)
        try:
            bmesh.ops.convex_hull(bm, input=bm.verts)
        except RuntimeError:
            import traceback
            traceback.print_exc()

        if clean:
            bm.normal_update()
            try:
                bmesh.ops.dissolve_limit(bm, verts=bm.verts, angle_limit=0.001)
            except RuntimeError:
                import traceback
                traceback.print_exc()

        if use_smooth_faces:
            for bm_face in bm.faces:
                bm_face.smooth = True

        if material_index != 0:
            for bm_face in bm.faces:
                bm_face.material_index = material_index

        # ---------------------------------------------------------------------
        # MESH
        mesh_dst = bpy.data.meshes.new(name=cell_name)

        bm.to_mesh(mesh_dst)
        bm.free()
        del bm

        if use_data_match:
            # match materials and data layers so boolean displays them
            # currently only materials + data layers, could do others...
            mesh_src = obj.data
            for mat in mesh_src.materials:
                mesh_dst.materials.append(mat)
            for lay_attr in ("vertex_colors", "uv_textures"):
                lay_src = getattr(mesh_src, lay_attr)
                lay_dst = getattr(mesh_dst, lay_attr)
                for key in lay_src.keys():
                    lay_dst.new(name=key)

        # ---------------------------------------------------------------------
        # OBJECT

        obj_cell = bpy.data.objects.new(name=cell_name, object_data=mesh_dst)
        scene.objects.link(obj_cell)
        # scene.objects.active = obj_cell
        obj_cell.location = center_point

        objects.append(obj_cell)

        # support for object materials
        if use_data_match:
            for i in range(len(mesh_dst.materials)):
                slot_src = obj.material_slots[i]
                slot_dst = obj_cell.material_slots[i]

                slot_dst.link = slot_src.link
                slot_dst.material = slot_src.material

        if use_debug_redraw:
            scene.update()
            _redraw_yasiamevil()

    scene.update()

    # move this elsewhere...
    for obj_cell in objects:
        game = obj_cell.game
        game.physics_type = 'RIGID_BODY'
        game.use_collision_bounds = True
        game.collision_bounds_type = 'CONVEX_HULL'

    return objects
예제 #21
0
    def __init__(self, location=Vector()):
        self.location = location.copy()
        self.velocity = noise.random_unit_vector()

        self.active = True
    def __init__(self, location=Vector()):
        self.location = location.copy()
        self.velocity = noise.random_unit_vector()

        self.active = True
예제 #23
0
def noise_gen(coords, props):

    terrain_name = props[0]
    cursor = props[1]
    smooth = props[2]
    triface = props[3]
    sphere = props[4]
    land_mat = props[5]
    water_mat = props[6]
    texture_name = props[7]
    subd_x = props[8]
    subd_y = props[9]
    meshsize_x = props[10]
    meshsize_y = props[11]
    meshsize = props[12]
    rseed = props[13]
    x_offset = props[14]
    y_offset = props[15]
    z_offset = props[16]
    size_x = props[17]
    size_y = props[18]
    size_z = props[19]
    nsize = props[20]
    ntype = props[21]
    nbasis = props[22]
    vlbasis = props[23]
    distortion = props[24]
    hardnoise = int(props[25])
    depth = props[26]
    amp = props[27]
    freq = props[28]
    dimension = props[29]
    lacunarity = props[30]
    offset = props[31]
    gain = props[32]
    marblebias = int(props[33])
    marblesharpnes = int(props[34])
    marbleshape = int(props[35])
    height = props[36]
    height_invert = props[37]
    height_offset = props[38]
    maximum = props[39]
    minimum = props[40]
    falloff = int(props[41])
    edge_level = props[42]
    falloffsize_x = props[43]
    falloffsize_y = props[44]
    stratatype = props[45]
    strata = props[46]
    addwater = props[47]
    waterlevel = props[48]
    vert_group = props[49]
    remove_double = props[50]
    fx_mixfactor = props[51]
    fx_mix_mode = props[52]
    fx_type = props[53]
    fx_bias = props[54]
    fx_turb = props[55]
    fx_depth = props[56]
    fx_frequency = props[57]
    fx_amplitude = props[58]
    fx_size = props[59]
    fx_loc_x = props[60]
    fx_loc_y = props[61]
    fx_height = props[62]
    fx_offset = props[63]
    fx_invert = props[64]

    x, y, z = coords

    # Origin
    if rseed == 0:
        origin = x_offset, y_offset, z_offset
        origin_x = x_offset
        origin_y = y_offset
        origin_z = z_offset
        o_range = 1.0
    else:
        # Randomise origin
        o_range = 100
        seed_set(rseed)
        origin = random_unit_vector()
        ox = (origin[0] * o_range)
        oy = (origin[1] * o_range)
        oz = 0
        origin_x = (ox - (ox * 0.5)) + x_offset
        origin_y = (oy - (oy * 0.5)) + y_offset
        origin_z = oz + z_offset

    ncoords = (x / (nsize * size_x) + origin_x,
               y / (nsize * size_y) + origin_y,
               z / (nsize * size_z) + origin_z)

    # Noise type's
    if ntype in [0, 'multi_fractal']:
        value = multi_fractal(
            ncoords, dimension, lacunarity, depth, noise_basis=nbasis) * 0.5

    elif ntype in [1, 'ridged_multi_fractal']:
        value = ridged_multi_fractal(ncoords,
                                     dimension,
                                     lacunarity,
                                     depth,
                                     offset,
                                     gain,
                                     noise_basis=nbasis) * 0.5

    elif ntype in [2, 'hybrid_multi_fractal']:
        value = hybrid_multi_fractal(ncoords,
                                     dimension,
                                     lacunarity,
                                     depth,
                                     offset,
                                     gain,
                                     noise_basis=nbasis) * 0.5

    elif ntype in [3, 'hetero_terrain']:
        value = hetero_terrain(
            ncoords, dimension, lacunarity, depth, offset,
            noise_basis=nbasis) * 0.25

    elif ntype in [4, 'fractal']:
        value = fractal(ncoords,
                        dimension,
                        lacunarity,
                        depth,
                        noise_basis=nbasis)

    elif ntype in [5, 'turbulence_vector']:
        value = turbulence_vector(ncoords,
                                  depth,
                                  hardnoise,
                                  noise_basis=nbasis,
                                  amplitude_scale=amp,
                                  frequency_scale=freq)[0]

    elif ntype in [6, 'variable_lacunarity']:
        value = variable_lacunarity(ncoords,
                                    distortion,
                                    noise_type1=nbasis,
                                    noise_type2=vlbasis)

    elif ntype in [7, 'marble_noise']:
        value = marble_noise(
            (ncoords[0] - origin_x + x_offset),
            (ncoords[1] - origin_y + y_offset),
            (ncoords[2] - origin_z + z_offset),
            (origin[0] + x_offset, origin[1] + y_offset, origin[2] + z_offset),
            nsize, marbleshape, marblebias, marblesharpnes, distortion, depth,
            hardnoise, nbasis, amp, freq)
    elif ntype in [8, 'shattered_hterrain']:
        value = shattered_hterrain(ncoords, dimension, lacunarity, depth,
                                   offset, distortion, nbasis)

    elif ntype in [9, 'strata_hterrain']:
        value = strata_hterrain(ncoords, dimension, lacunarity, depth, offset,
                                distortion, nbasis)

    elif ntype in [10, 'ant_turbulence']:
        value = ant_turbulence(ncoords, depth, hardnoise, nbasis, amp, freq,
                               distortion)

    elif ntype in [11, 'vl_noise_turbulence']:
        value = vl_noise_turbulence(ncoords, distortion, depth, nbasis,
                                    vlbasis, hardnoise, amp, freq)

    elif ntype in [12, 'vl_hTerrain']:
        value = vl_hTerrain(ncoords, dimension, lacunarity, depth, offset,
                            nbasis, vlbasis, distortion)

    elif ntype in [13, 'distorted_heteroTerrain']:
        value = distorted_heteroTerrain(ncoords, dimension, lacunarity, depth,
                                        offset, distortion, nbasis, vlbasis)

    elif ntype in [14, 'double_multiFractal']:
        value = double_multiFractal(ncoords, dimension, lacunarity, depth,
                                    offset, gain, nbasis, vlbasis)

    elif ntype in [15, 'rocks_noise']:
        value = rocks_noise(ncoords, depth, hardnoise, nbasis, distortion)

    elif ntype in [16, 'slick_rock']:
        value = slick_rock(ncoords, dimension, lacunarity, depth, offset, gain,
                           distortion, nbasis, vlbasis)

    elif ntype in [17, 'planet_noise']:
        value = planet_noise(ncoords, depth, hardnoise, nbasis)[2] * 0.5 + 0.5

    elif ntype in [18, 'blender_texture']:
        if texture_name != "" and texture_name in bpy.data.textures:
            value = bpy.data.textures[texture_name].evaluate(ncoords)[3]
        else:
            value = 0.0
    else:
        value = 0.5

    # Effect mix
    val = value
    if fx_type in [0, "0"]:
        fx_mixfactor = -1.0
        fxval = val
    else:
        fxcoords = Trans_Effect((x, y, z), fx_size, (fx_loc_x, fx_loc_y))
        effect = Effect_Function(fxcoords, fx_type, fx_bias, fx_turb, fx_depth,
                                 fx_frequency, fx_amplitude)
        effect = Height_Scale(effect, fx_height, fx_offset, fx_invert)
        fxval = Mix_Modes(val, effect, fx_mixfactor, fx_mix_mode)
    value = fxval

    # Adjust height
    value = Height_Scale(value, height, height_offset, height_invert)

    # Edge falloff:
    if not sphere:
        if falloff:
            ratio_x, ratio_y = abs(x) * 2 / meshsize_x, abs(y) * 2 / meshsize_y
            fallofftypes = [
                0,
                sqrt(ratio_y**falloffsize_y),
                sqrt(ratio_x**falloffsize_x),
                sqrt(ratio_x**falloffsize_x + ratio_y**falloffsize_y)
            ]
            dist = fallofftypes[falloff]
            value -= edge_level
            if (dist < 1.0):
                dist = (dist * dist * (3 - 2 * dist))
                value = (value - value * dist) + edge_level
            else:
                value = edge_level

    # Strata / terrace / layers
    if stratatype not in [0, "0"]:
        if stratatype in [1, "1"]:
            strata = strata / height
            strata *= 2
            steps = (sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [2, "2"]:
            strata = strata / height
            steps = -abs(sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [3, "3"]:
            strata = strata / height
            steps = abs(sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [4, "4"]:
            strata = strata / height
            value = int(value * strata) * 1.0 / strata

        elif stratatype in [5, "5"]:
            strata = strata / height
            steps = (int(value * strata) * 1.0 / strata)
            value = (value * (1.0 - 0.5) + steps * 0.5)

    # Clamp height min max
    if (value < minimum):
        value = minimum
    if (value > maximum):
        value = maximum

    return value
예제 #24
0
def generate_random_unitvectors():
    # may need many more directions to increase accuracy
    # generate up to 6 directions, filter later
    seed_set(140230)
    return [random_unit_vector() for i in range(6)]
예제 #25
0
def points_to_cells(context,
                    original,
                    original_xyz_minmax,
                    points,
                    source_limit=0,
                    source_noise=0.0,
                    use_smooth_faces=False,
                    use_data_match=False,
                    use_debug_points=False,
                    margin=0.0,
                    material_index=0,
                    use_debug_redraw=False,
                    cell_scale=(1.0, 1.0, 1.0),
                    clean=True):

    from . import cell_calc
    collection = context.collection
    view_layer = context.view_layer

    # apply optional clamp
    if source_limit != 0 and source_limit < len(points):
        points = _limit_source(points, source_limit)

    # saddly we cant be sure there are no doubles
    from mathutils import Vector
    to_tuple = Vector.to_tuple

    # To remove doubles, round the values.
    points = [(Vector(to_tuple(p[0], 4)), p[1]) for p in points]
    del to_tuple
    del Vector

    if source_noise > 0.0:
        from random import random
        # boundbox approx of overall scale
        from mathutils import Vector
        matrix = original.matrix_world.copy()
        bb_world = [matrix @ Vector(v) for v in original.bound_box]
        scalar = source_noise * ((bb_world[0] - bb_world[6]).length / 2.0)

        from mathutils.noise import random_unit_vector
        points[:] = [(p[0] + (random_unit_vector() * (scalar * random())),
                      p[1]) for p in points]

    if use_debug_points:
        bm = bmesh.new()
        for p in points:
            bm.verts.new(p[0])
        mesh_tmp = bpy.data.meshes.new(name="DebugPoints")
        bm.to_mesh(mesh_tmp)
        bm.free()
        obj_tmp = bpy.data.objects.new(name=mesh_tmp.name,
                                       object_data=mesh_tmp)
        collection.objects.link(obj_tmp)
        del obj_tmp, mesh_tmp

    cells_verts = cell_calc.points_to_verts(original_xyz_minmax,
                                            points,
                                            cell_scale,
                                            margin_cell=margin)
    # some hacks here :S
    cell_name = original.name + "_cell"
    cells = []
    for center_point, cell_verts in cells_verts:
        # ---------------------------------------------------------------------
        # BMESH
        # create the convex hulls
        bm = bmesh.new()

        # WORKAROUND FOR CONVEX HULL BUG/LIMIT
        # XXX small noise
        import random

        def R():
            return (random.random() - 0.5) * 0.001

        for i, co in enumerate(cell_verts):
            co.x += R()
            co.y += R()
            co.z += R()
            bm_vert = bm.verts.new(co)

        import mathutils
        bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.005)
        try:
            # Making cell meshes as convex full here!
            bmesh.ops.convex_hull(bm, input=bm.verts)
        except RuntimeError:
            import traceback
            traceback.print_exc()

        if clean:
            bm.normal_update()
            try:
                bmesh.ops.dissolve_limit(bm, verts=bm.verts, angle_limit=0.001)
            except RuntimeError:
                import traceback
                traceback.print_exc()
        # smooth faces will remain only inner faces, after appling boolean modifier.
        if use_smooth_faces:
            for bm_face in bm.faces:
                bm_face.smooth = True

        if material_index != 0:
            for bm_face in bm.faces:
                bm_face.material_index = material_index

        # ---------------------------------------------------------------------
        # MESH
        mesh_dst = bpy.data.meshes.new(name=cell_name)

        bm.to_mesh(mesh_dst)
        bm.free()
        del bm

        if use_data_match:
            # match materials and data layers so boolean displays them
            # currently only materials + data layers, could do others...
            mesh_src = original.data
            for mat in mesh_src.materials:
                mesh_dst.materials.append(mat)
            for lay_attr in ("vertex_colors", "uv_layers"):
                lay_src = getattr(mesh_src, lay_attr)
                lay_dst = getattr(mesh_dst, lay_attr)
                for key in lay_src.keys():
                    lay_dst.new(name=key)

        # ---------------------------------------------------------------------
        # OBJECT
        cell = bpy.data.objects.new(name=cell_name, object_data=mesh_dst)
        collection.objects.link(cell)
        cell.location = center_point
        cells.append(cell)

        # support for object materials
        if use_data_match:
            for i in range(len(mesh_dst.materials)):
                slot_src = original.material_slots[i]
                slot_dst = cell.material_slots[i]

                slot_dst.link = slot_src.link
                slot_dst.material = slot_src.material

        if use_debug_redraw:
            view_layer.update()
            _redraw_yasiamevil()

    view_layer.update()
    # move this elsewhere...
    # Blender 2.8: BGE integration was disabled, --
    # -- because BGE was deleted in Blender 2.8.
    '''
    for cell in cells:
        game = cell.game
        game.physics_type = 'RIGID_BODY'
        game.use_collision_bounds = True
        game.collision_bounds_type = 'CONVEX_HULL'
    '''
    return cells
예제 #26
0
def get_mats_for_segment(self, context, segment, splinetype):
    '''
    Creates the Matrizies for a spline segment.
    '''
    #printd('Creating transforms for segment', splinetype)
    mats = []

    p1 = segment[0]
    p2 = segment[1]


    count = self.leafs_per_segment
    if self.bvh:
        count *= 2

    ### TRANSLATION #################
    if splinetype == 'BEZIER':
        coordsb = interpolate_bezier(p1.co, p1.handle_right, p2.handle_left, p2.co, count+1)
        coords = [coordsb[i].lerp(coordsb[i+1], random()*self.loc_random)
                  for i in range(len(coordsb)-1)]

    elif splinetype == 'POLY':
        if count > 1:
            positions = [i / count for i in range(count)]
        else:
            positions = [0.5]
        #printd('POLY-segment: Lerp-positions', positions)
        coords = [p1.co.lerp(p2.co, positions[i]+(random() * self.loc_random)).to_3d()
                  for i in range(count)]

    mat_locs = [Matrix.Translation(co) for co in coords]


    ### SCALE #################
    mat_scales = [Matrix.Scale(self.scale+(random()*self.scale_random), 4)
                  for i in range(len(mat_locs))]

    ### ROTATION #################
    if splinetype == 'BEZIER':
        directions = [(coordsb[i+1] - coordsb[i]).normalized()
                      for i in range(len(coordsb)-1)]
    elif splinetype == 'POLY':
        directions = [(p2.co - p1.co).to_3d().normalized()]*len(coords)

    #COLLISION -> align leaves to surface
    if self.bvh:
        #printd('COLLISION')
        mat_rots = get_collider_aligned_rots(self, context, coords[:int(count/2)], directions)

    #NO COLLISION
    else:
        vecs_target = directions.copy()

        #direction + random for y alignment
        vecs_target = [vt.lerp(vt+noise.random_unit_vector(), self.rot_random).normalized()
                       for vt in vecs_target]

        #up versus random for z alignment
        vecs_alignz = [Vector((0,0,1)).lerp(noise.random_unit_vector(), self.rot_align_normal_random).normalized()
                       for i in range(len(directions))]

        #return alignz towards the direction vector
        vecs_alignz = [va.lerp(d, self.rot_align_normal).normalized()
                       for va, d in zip(vecs_alignz, directions)]

        mat_rots = [align(vt, va) for vt, va in zip(vecs_target, vecs_alignz)]
        #printd('FREE ROTATION Mats:', len(mat_rots))

    #COMBINED
    mats = [l*s*r for l,s,r in zip(mat_locs, mat_scales, mat_rots)]
    mats = [m for m in mats if not random() > self.leafs_per_segment_random]
    #printd('MATS: ', len(mats), len(mat_locs), len(mat_scales), len(mat_rots))
    return mats
예제 #27
0
def noise_gen(coords, props):

    terrain_name = props[0]
    cursor = props[1]
    smooth = props[2]
    triface = props[3]
    sphere = props[4]
    land_mat = props[5]
    water_mat = props[6]
    texture_name = props[7]
    subd_x = props[8]
    subd_y = props[9]
    meshsize_x = props[10]
    meshsize_y = props[11]
    meshsize = props[12]
    rseed = props[13]
    x_offset = props[14]
    y_offset = props[15]
    z_offset = props[16]
    size_x = props[17]
    size_y = props[18]
    size_z = props[19]
    nsize = props[20]
    ntype = props[21]
    nbasis = int(props[22])
    vlbasis = int(props[23])
    distortion = props[24]
    hardnoise = int(props[25])
    depth = props[26]
    amp = props[27]
    freq = props[28]
    dimension = props[29]
    lacunarity = props[30]
    offset = props[31]
    gain = props[32]
    marblebias = int(props[33])
    marblesharpnes = int(props[34])
    marbleshape = int(props[35])
    height = props[36]
    height_invert = props[37]
    height_offset = props[38]
    maximum = props[39]
    minimum = props[40]
    falloff = int(props[41])
    edge_level = props[42]
    falloffsize_x = props[43]
    falloffsize_y = props[44]
    stratatype = props[45]
    strata = props[46]
    addwater = props[47]
    waterlevel = props[48]
    vert_group = props[49]
    remove_double = props[50]
    fx_mixfactor = props[51]
    fx_mix_mode = props[52]
    fx_type = props[53]
    fx_bias = props[54]
    fx_turb = props[55]
    fx_depth = props[56]
    fx_frequency = props[57]
    fx_amplitude = props[58]
    fx_size = props[59]
    fx_loc_x = props[60]
    fx_loc_y = props[61]
    fx_height = props[62]
    fx_offset = props[63]
    fx_invert = props[64]

    x, y, z = coords

    # Origin
    if rseed is 0:
        origin = x_offset, y_offset, z_offset
        origin_x = x_offset
        origin_y = y_offset
        origin_z = z_offset
        o_range = 1.0
    else:
        # Randomise origin
        o_range = 10000.0
        seed_set(rseed)
        origin = random_unit_vector()
        ox = (origin[0] * o_range)
        oy = (origin[1] * o_range)
        oz = (origin[2] * o_range)
        origin_x = (ox - (ox / 2)) + x_offset
        origin_y = (oy - (oy / 2)) + y_offset
        origin_z = (oz - (oz / 2)) + z_offset

    ncoords = (x / (nsize * size_x) + origin_x, y / (nsize * size_y) + origin_y, z / (nsize * size_z) + origin_z)

    # Noise basis type's
    if nbasis == 9:
        nbasis = 14  # Cellnoise
    if vlbasis == 9:
        vlbasis = 14

    # Noise type's
    if ntype in [0, 'multi_fractal']:
        value = multi_fractal(ncoords, dimension, lacunarity, depth, nbasis) * 0.5

    elif ntype in [1, 'ridged_multi_fractal']:
        value = ridged_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5

    elif ntype in [2, 'hybrid_multi_fractal']:
        value = hybrid_multi_fractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis) * 0.5

    elif ntype in [3, 'hetero_terrain']:
        value = hetero_terrain(ncoords, dimension, lacunarity, depth, offset, nbasis) * 0.25

    elif ntype in [4, 'fractal']:
        value = fractal(ncoords, dimension, lacunarity, depth, nbasis)

    elif ntype in [5, 'turbulence_vector']:
        value = turbulence_vector(ncoords, depth, hardnoise, nbasis, amp, freq)[0]

    elif ntype in [6, 'variable_lacunarity']:
        value = variable_lacunarity(ncoords, distortion, nbasis, vlbasis)

    elif ntype in [7, 'marble_noise']:
        value = marble_noise(
                        (ncoords[0] - origin_x + x_offset),
                        (ncoords[1] - origin_y + y_offset),
                        (ncoords[2] - origin_z + z_offset),
                        (origin[0] + x_offset, origin[1] + y_offset, origin[2] + z_offset), nsize,
                        marbleshape, marblebias, marblesharpnes,
                        distortion, depth, hardnoise, nbasis, amp, freq
                        )
    elif ntype in [8, 'shattered_hterrain']:
        value = shattered_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis)

    elif ntype in [9, 'strata_hterrain']:
        value = strata_hterrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis)

    elif ntype in [10, 'ant_turbulence']:
        value = ant_turbulence(ncoords, depth, hardnoise, nbasis, amp, freq, distortion)

    elif ntype in [11, 'vl_noise_turbulence']:
        value = vl_noise_turbulence(ncoords, distortion, depth, nbasis, vlbasis, hardnoise, amp, freq)

    elif ntype in [12, 'vl_hTerrain']:
        value = vl_hTerrain(ncoords, dimension, lacunarity, depth, offset, nbasis, vlbasis, distortion)

    elif ntype in [13, 'distorted_heteroTerrain']:
        value = distorted_heteroTerrain(ncoords, dimension, lacunarity, depth, offset, distortion, nbasis, vlbasis)

    elif ntype in [14, 'double_multiFractal']:
        value = double_multiFractal(ncoords, dimension, lacunarity, depth, offset, gain, nbasis, vlbasis)

    elif ntype in [15, 'rocks_noise']:
        value = rocks_noise(ncoords, depth, hardnoise, nbasis, distortion)

    elif ntype in [16, 'slick_rock']:
        value = slick_rock(ncoords,dimension, lacunarity, depth, offset, gain, distortion, nbasis, vlbasis)

    elif ntype in [17, 'planet_noise']:
        value = planet_noise(ncoords, depth, hardnoise, nbasis)[2] * 0.5 + 0.5

    elif ntype in [18, 'blender_texture']:
        if texture_name != "" and texture_name in bpy.data.textures:
            value = bpy.data.textures[texture_name].evaluate(ncoords)[3]
        else:
            value = 0.0
    else:
        value = 0.5

    # Effect mix
    val = value
    if fx_type in [0,"0"]:
        fx_mixfactor = -1.0
        fxval = val
    else:
        fxcoords = Trans_Effect((x, y, z), fx_size, (fx_loc_x, fx_loc_y))
        effect = Effect_Function(fxcoords, fx_type, fx_bias, fx_turb, fx_depth, fx_frequency, fx_amplitude)
        effect = Height_Scale(effect, fx_height, fx_offset, fx_invert)
        fxval = Mix_Modes(val, effect, fx_mixfactor, fx_mix_mode)
    value = fxval

    # Adjust height
    value = Height_Scale(value, height, height_offset, height_invert)

    # Edge falloff:
    if not sphere:
        if falloff:
            ratio_x, ratio_y = abs(x) * 2 / meshsize_x, abs(y) * 2 / meshsize_y
            fallofftypes = [0,
                            sqrt(ratio_y**falloffsize_y),
                            sqrt(ratio_x**falloffsize_x),
                            sqrt(ratio_x**falloffsize_x + ratio_y**falloffsize_y)
                           ]
            dist = fallofftypes[falloff]
            value -= edge_level
            if(dist < 1.0):
                dist = (dist * dist * (3 - 2 * dist))
                value = (value - value * dist) + edge_level
            else:
                value = edge_level

    # Strata / terrace / layers
    if stratatype not in [0, "0"]:
        if stratatype in [1, "1"]:
            strata = strata / height
            strata *= 2
            steps = (sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [2, "2"]:
            strata = strata / height
            steps = -abs(sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [3, "3"]:
            strata = strata / height
            steps = abs(sin(value * strata * pi) * (0.1 / strata * pi))
            value = (value * 0.5 + steps * 0.5) * 2.0

        elif stratatype in [4, "4"]:
            strata = strata / height
            value = int( value * strata ) * 1.0 / strata

        elif stratatype in [5, "5"]:
            strata = strata / height
            steps = (int( value * strata ) * 1.0 / strata)
            value = (value * (1.0 - 0.5) + steps * 0.5)

    # Clamp height min max
    if (value < minimum):
        value = minimum
    if (value > maximum):
        value = maximum

    return value
def get_mats_for_segment(self, context, segment, splinetype):
    '''
    Creates the Matrizies for a spline segment.
    '''
    #printd('Creating transforms for segment', splinetype)
    mats = []

    p1 = segment[0]
    p2 = segment[1]

    count = self.leafs_per_segment
    if self.bvh:
        count *= 2

    ### TRANSLATION #################
    if splinetype == 'BEZIER':
        coordsb = interpolate_bezier(p1.co, p1.handle_right, p2.handle_left,
                                     p2.co, count + 1)
        coords = [
            coordsb[i].lerp(coordsb[i + 1],
                            random() * self.loc_random)
            for i in range(len(coordsb) - 1)
        ]

    elif splinetype == 'POLY':
        if count > 1:
            positions = [i / count for i in range(count)]
        else:
            positions = [0.5]
        #printd('POLY-segment: Lerp-positions', positions)
        coords = [
            p1.co.lerp(p2.co,
                       positions[i] + (random() * self.loc_random)).to_3d()
            for i in range(count)
        ]

    mat_locs = [Matrix.Translation(co) for co in coords]

    ### SCALE #################
    mat_scales = [
        Matrix.Scale(self.scale + (random() * self.scale_random), 4)
        for i in range(len(mat_locs))
    ]

    ### ROTATION #################
    if splinetype == 'BEZIER':
        directions = [(coordsb[i + 1] - coordsb[i]).normalized()
                      for i in range(len(coordsb) - 1)]
    elif splinetype == 'POLY':
        directions = [(p2.co - p1.co).to_3d().normalized()] * len(coords)

    #COLLISION -> align leaves to surface
    if self.bvh:
        #printd('COLLISION')
        mat_rots = get_collider_aligned_rots(self, context,
                                             coords[:int(count / 2)],
                                             directions)

    #NO COLLISION
    else:
        vecs_target = directions.copy()

        #direction + random for y alignment
        vecs_target = [
            vt.lerp(vt + noise.random_unit_vector(),
                    self.rot_random).normalized() for vt in vecs_target
        ]

        #up versus random for z alignment
        vecs_alignz = [
            Vector((0, 0, 1)).lerp(noise.random_unit_vector(),
                                   self.rot_align_normal_random).normalized()
            for i in range(len(directions))
        ]

        #return alignz towards the direction vector
        vecs_alignz = [
            va.lerp(d, self.rot_align_normal).normalized()
            for va, d in zip(vecs_alignz, directions)
        ]

        mat_rots = [align(vt, va) for vt, va in zip(vecs_target, vecs_alignz)]
        #printd('FREE ROTATION Mats:', len(mat_rots))

    #COMBINED
    mats = [l * s * r for l, s, r in zip(mat_locs, mat_scales, mat_rots)]
    mats = [m for m in mats if not random() > self.leafs_per_segment_random]
    #printd('MATS: ', len(mats), len(mat_locs), len(mat_scales), len(mat_rots))
    return mats
예제 #29
0
 def __init__(self):
     self.bodies = []
     for i in range(self.N):
         self.bodies.append(Packer(10 * noise.random_unit_vector()))
예제 #30
0
def landscape_gen(x, y, z, falloffsize, options):

    # options = [0, 1.0, 'multi_fractal', 0, 0, 1.0, 0, 6, 1.0, 2.0, 1.0, 2.0,
    #            0, 0, 0, 1.0, 0.0, 1, 0.0, 1.0, 0, 0, 0, 0.0, 0.0]
    rseed = options[0]
    nsize = options[1]
    ntype = options[2]
    nbasis = int(options[3][0])
    vlbasis = int(options[4][0])
    distortion = options[5]
    hardnoise = options[6]
    depth = options[7]
    dimension = options[8]
    lacunarity = options[9]
    offset = options[10]
    gain = options[11]
    marblebias = int(options[12][0])
    marblesharpnes = int(options[13][0])
    marbleshape = int(options[14][0])
    invert = options[15]
    height = options[16]
    heightoffset = options[17]
    falloff = int(options[18][0])
    sealevel = options[19]
    platlevel = options[20]
    strata = options[21]
    stratatype = options[22]
    sphere = options[23]
    x_offset = options[24]
    y_offset = options[25]

    # origin
    if rseed == 0:
        origin = 0.0 + x_offset, 0.0 + y_offset, 0.0
        origin_x = x_offset
        origin_y = y_offset
        origin_z = 0.0
    else:
        # randomise origin
        seed_set(rseed)
        origin = random_unit_vector()
        origin[0] += x_offset
        origin[1] += y_offset
        origin_x = ((0.5 - origin[0]) * 1000.0) + x_offset
        origin_y = ((0.5 - origin[1]) * 1000.0) + y_offset
        origin_z = (0.5 - origin[2]) * 1000.0

    # adjust noise size and origin
    ncoords = (x / nsize + origin_x, y / nsize + origin_y,
               z / nsize + origin_z)

    # noise basis type's
    if nbasis == 9:
        nbasis = 14  # to get cellnoise basis you must set 14 instead of 9
    if vlbasis == 9:
        vlbasis = 14

    # noise type's
    if ntype == 'multi_fractal':
        value = multi_fractal(ncoords, dimension, lacunarity, depth,
                              nbasis) * 0.5

    elif ntype == 'ridged_multi_fractal':
        value = ridged_multi_fractal(ncoords, dimension, lacunarity, depth,
                                     offset, gain, nbasis) * 0.5

    elif ntype == 'hybrid_multi_fractal':
        value = hybrid_multi_fractal(ncoords, dimension, lacunarity, depth,
                                     offset, gain, nbasis) * 0.5

    elif ntype == 'hetero_terrain':
        value = hetero_terrain(ncoords, dimension, lacunarity, depth, offset,
                               nbasis) * 0.25

    elif ntype == 'fractal':
        value = fractal(ncoords, dimension, lacunarity, depth, nbasis)

    elif ntype == 'turbulence_vector':
        value = turbulence_vector(ncoords, depth, hardnoise, nbasis)[0]

    elif ntype == 'variable_lacunarity':
        value = variable_lacunarity(ncoords, distortion, nbasis, vlbasis) + 0.5

    elif ntype == 'marble_noise':
        value = marble_noise(x * 2.0 / falloffsize, y * 2.0 / falloffsize,
                             z * 2 / falloffsize, origin, nsize, marbleshape,
                             marblebias, marblesharpnes, distortion, depth,
                             hardnoise, nbasis)

    elif ntype == 'shattered_hterrain':
        value = shattered_hterrain(ncoords[0], ncoords[1], ncoords[2],
                                   dimension, lacunarity, depth, offset,
                                   distortion, nbasis)

    elif ntype == 'strata_hterrain':
        value = strata_hterrain(ncoords[0], ncoords[1], ncoords[2], dimension,
                                lacunarity, depth, offset, distortion, nbasis)

    elif ntype == 'planet_noise':
        value = planet_noise(ncoords, depth, hardnoise, nbasis)[2] * 0.5 + 0.5
    else:
        value = 0.0

    # adjust height
    if invert != 0:
        value = (1 - value) * height + heightoffset
    else:
        value = value * height + heightoffset

    # edge falloff
    if sphere == 0:  # no edge falloff if spherical
        if falloff != 0:
            fallofftypes = [
                0, hypot(x * x, y * y),
                hypot(x, y),
                abs(y), abs(x)
            ]
            dist = fallofftypes[falloff]
            if falloff == 1:
                radius = (falloffsize / 2)**2
            else:
                radius = falloffsize / 2

            value = value - sealevel
            if (dist < radius):
                dist = dist / radius
                dist = (dist * dist * (3 - 2 * dist))
                value = (value - value * dist) + sealevel
            else:
                value = sealevel

    # strata / terrace / layered
    if stratatype != '0':
        strata = strata / height

    if stratatype == '1':
        strata *= 2
        steps = (sin(value * strata * pi) * (0.1 / strata * pi))
        value = (value * (1.0 - 0.5) + steps * 0.5) * 2.0

    elif stratatype == '2':
        steps = -abs(sin(value * strata * pi) * (0.1 / strata * pi))
        value = (value * (1.0 - 0.5) + steps * 0.5) * 2.0

    elif stratatype == '3':
        steps = abs(sin(value * strata * pi) * (0.1 / strata * pi))
        value = (value * (1.0 - 0.5) + steps * 0.5) * 2.0

    else:
        value = value

    # clamp height
    if (value < sealevel):
        value = sealevel
    if (value > platlevel):
        value = platlevel

    return value
def cell_fracture_objects(scene, obj, material_index):
    
    from . import fracture_cell_calc
    
    ctx = obj.destruction.cell_fracture
    source = ctx.source
    source_limit = ctx.source_limit
    source_noise = ctx.source_noise
    clean = True
    
    # operator options
    use_smooth_faces = ctx.use_smooth_faces
    use_data_match = ctx.use_data_match
    use_island_split = True
    margin = ctx.margin
    use_debug_points = ctx.use_debug_points
    cell_scale = ctx.cell_scale
    
    re_unwrap = obj.destruction.re_unwrap
    smart_angle = obj.destruction.smart_angle

    # -------------------------------------------------------------------------
    # GET POINTS

    points = _points_from_object(obj, source)

    if not points:
        # print using fallback
        points = _points_from_object(obj, {'VERT_OWN'})

    if not points:
        print("no points found")
        return []

    # apply optional clamp
    if source_limit != 0 and source_limit < len(points):
        import random
        random.shuffle(points)
        points[source_limit:] = []


    # saddly we cant be sure there are no doubles
    from mathutils import Vector
    to_tuple = Vector.to_tuple
    points = list({to_tuple(p, 4): p for p in points}.values())
    del to_tuple
    del Vector

    # end remove doubles
    # ------------------

    if source_noise > 0.0:
        from random import random
        # boundbox approx of overall scale
        from mathutils import Vector
        matrix = obj.matrix_world.copy()
        bb_world = [matrix * Vector(v) for v in obj.bound_box]
        scalar = source_noise * ((bb_world[0] - bb_world[6]).length / 2.0)

        from mathutils.noise import random_unit_vector
        
        points[:] = [p + (random_unit_vector() * (scalar * random())) for p in points]


    if use_debug_points:
        bm = bmesh.new()
        for p in points:
            bm.verts.new(p)
        mesh_tmp = bpy.data.meshes.new(name="DebugPoints")
        bm.to_mesh(mesh_tmp)
        bm.free()
        obj_tmp = bpy.data.objects.new(name=mesh_tmp.name, object_data=mesh_tmp)
        scene.objects.link(obj_tmp)
        del obj_tmp, mesh_tmp

    mesh = obj.data
    matrix = obj.matrix_world.copy()
    verts = [matrix * v.co for v in mesh.vertices]

    cells = fracture_cell_calc.points_as_bmesh_cells(verts,
                                                     points,
                                                     cell_scale,
                                                     margin_cell=margin)

    # some hacks here :S
    cell_name = obj.name #+ "_cell"
    
    objects = []
    
    for center_point, cell_points in cells:

        # ---------------------------------------------------------------------
        # BMESH

        # create the convex hulls
        bm = bmesh.new()
        
        # WORKAROUND FOR CONVEX HULL BUG/LIMIT
        # XXX small noise
        import random
        def R(): return (random.random() - 0.5) * 0.001
        # XXX small noise

        for i, co in enumerate(cell_points):
            
            # XXX small noise
            co.x += R()
            co.y += R()
            co.z += R()
            # XXX small noise
            
            bm_vert = bm.verts.new(co)

        import mathutils
        bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.005)
        try:
            bmesh.ops.convex_hull(bm, input=bm.verts)
        except RuntimeError:
            import traceback
            traceback.print_exc()

        if clean:
            bm.normal_update()
            try:
                bmesh.ops.dissolve_limit(bm, verts=bm.verts, angle_limit=0.001)
            except RuntimeError:
                import traceback
                traceback.print_exc()

        if use_smooth_faces:
            for bm_face in bm.faces:
                bm_face.smooth = True

        if material_index != 0:
            for bm_face in bm.faces:
                bm_face.material_index = material_index


        # ---------------------------------------------------------------------
        # MESH

        mesh_dst = bpy.data.meshes.new(name=cell_name)

        bm.to_mesh(mesh_dst)
        bm.free()
        del bm

        if use_data_match:
            # match materials and data layers so boolean displays them
            # currently only materials + data layers, could do others...
            mesh_src = obj.data
            for mat in mesh_src.materials:
                mesh_dst.materials.append(mat)
            for lay_attr in ("vertex_colors", "uv_textures"):
                lay_src = getattr(mesh_src, lay_attr)
                lay_dst = getattr(mesh_dst, lay_attr)
                for key in lay_src.keys():
                    lay_dst.new(name=key)

        # ---------------------------------------------------------------------
        # OBJECT

        obj_cell = bpy.data.objects.new(name=cell_name, object_data=mesh_dst)
        scene.objects.link(obj_cell)
        # scene.objects.active = obj_cell
        obj_cell.location = center_point
        
        #needed for parenting system
        obj_cell.parent = bpy.context.scene.objects[cell_name].parent

        objects.append(obj_cell)
        
        if re_unwrap:
           scene.objects.active = obj_cell
           bpy.ops.object.mode_set(mode = 'EDIT')
           bpy.ops.mesh.select_all(action = 'SELECT')
           bpy.ops.mesh.dissolve_limited(angle_limit = 0.001)
           bpy.ops.mesh.mark_seam()
           bpy.ops.uv.smart_project(angle_limit = smart_angle)
           bpy.ops.object.mode_set(mode = 'OBJECT')
        
        if obj.destruction.use_debug_redraw:
            scene.update()
            obj.destruction._redraw_yasiamevil()

    scene.update()


    # move this elsewhere...
   # for obj_cell in objects:
#        game = obj_cell.game
 #       game.physics_type = 'RIGID_BODY'
  #      game.use_collision_bounds = True
   #     game.collision_bounds_type = 'CONVEX_HULL'

    return objects
예제 #32
0
def generate_random_unitvectors():
    # may need many more directions to increase accuracy
    # generate up to 6 directions, filter later
    seed_set(140230)
    return [random_unit_vector() for i in range(6)]
예제 #33
0
  def grow(self):

    from numpy import sum, all, ones

    self.itt += 1

    stp = self.stp
    killzone = self.killzone
    noise = self.noise

    v_xyz,s_xyz = self.get_positions()
    dvv,dvs = self.get_distances(v_xyz,s_xyz)
    vs_map,sv_map = self.make_maps(dvv,dvs,killzone)

    nv,ns = dvs.shape

    self.select_seed()
    bm = self.get_bmesh()
    nodes = [v for v in bm.verts]

    for i,jj in vs_map.items():

      v = Vector(sum(s_xyz[jj,:]-v_xyz[i,:],axis=0))

      v.normalize()

      # this is flawed. particularly for "flat" geometries
      p,pn = self.closest_point_on_geom(nodes[i].co)
      projected = pn.cross(v.cross(pn))
      projected += random_unit_vector()*noise
      projected.normalize()

      new = nodes[i].co + projected*stp

      verts = [nodes[i]]
      new_vert = bmesh.ops.extrude_vert_indiv(
        bm,
        verts=verts)['verts'].pop()
      new_vert.co = new

    ## mask out dead sources
    mask = ones(ns,'bool')
    for j,ii in sv_map.items():

      if all(dvs[ii,j]<=killzone):
        mask[j] = False
        self.num_sources -= 1

        print('merging:',len(ii),'deleted source:',j)
        new_verts = []
        for i in ii:
          new = bmesh.ops.extrude_vert_indiv(
            bm,
            verts=[nodes[i]])['verts'].pop()
          new.co = self.sources[j]
          new_verts.append(new)

        bmesh.ops.remove_doubles(bm,verts=new_verts,dist=0.01)

        self.dead_sources.append(self.sources[j])

    self.to_mesh()

    self.sources = self.sources[mask,:]
    return
예제 #34
0
  def grow(self):

    from numpy import sum, all, ones

    self.itt += 1

    v_xyz,s_xyz = self.get_positions()
    dvv,dvs = self.get_distances(v_xyz,s_xyz)
    vs_map,sv_map = self.make_maps(dvv,dvs)

    nv,ns = dvs.shape

    nodes = self.nodes
    stp = self.stp
    killzone = self.killzone
    noise = self.noise
    spawn_count = self.spawn_count

    new_node_pos = []

    for i,jj in vs_map.items():

      if spawn_count[i]>2:
        continue

      mask = dvs[i,jj]>=killzone
      if all(mask):

        spawn_count[i] += 1

        v = Vector(sum(s_xyz[jj,:]-v_xyz[i,:],axis=0))
        v.normalize()

        p,pn = self.closest_point_on_geom(nodes[i])

        projected = pn.cross(v.cross(pn))
        projected.normalize()

        if v.dot(projected)<0.85:
          new = projected
        else:
          new = v

        new += random_unit_vector()*noise
        new.normalize()

        new = nodes[i] + new*stp
        new_node_pos.append(new)

        bpy.ops.mesh.primitive_ico_sphere_add(
          size=0.3,
          subdivisions=1,
          location=new)

        self.rotate(v)
        self.boolean_union(bpy.context.object)

    ## mask out dead source nodes
    mask = ones(ns,'bool')
    for j,ii in sv_map.items():

      if all(dvs[ii,j]<=killzone):
        mask[j] = False
        self.num_sources -= 1

        bpy.ops.mesh.primitive_ico_sphere_add(
          size=0.3,
          subdivisions=1,
          location=self.sources[j])
        self.boolean_union(bpy.context.object)

        print('deleted source:',j)
        self.dead_sources.append(self.sources[j])

    self.nodes.extend(new_node_pos)
    self.sources = self.sources[mask,:]
    return