def raylength(): """ Objects can only be grabbed if they are hit by the Ray-Sensor called 'Ray'. Set the ray's length , so that it hits objects in a certain radius around the human's z-axis """ co = logic.getCurrentController() cam = co.owner ray = co.sensors['Ray'] dir = Vector(ray.rayDirection) xy = Matrix.OrthoProjection('XY', 3) * dir # API Change in 2.59 builds - Vectors are now column vectors ray.range = 0.8 / xy.length
def interact(cont): """ Script for opening doors, drawers and grabbing objects press left mousebutton to open, close or grab press right mousebutton to drop the currently selected object """ ow = cont.owner # get the suffix of the human to reference the right objects suffix = ow.name[-4:] if ow.name[-4] == "." else "" right_hand = objects['IK_Target_Empty.R' + suffix] look = objects['Target_Empty' + suffix] human = objects[ow.parent.parent.parent.name + suffix] # if the human is external, do nothing if human.get('External_Robot_Tag') or human['disable_keyboard_control']: return lmb = cont.sensors['LMB'] ray = cont.sensors['Ray'] cam = ray.owner lay_down_ray = cont.sensors['LayDownRay'] rmb = cont.sensors['RMB'] space = cont.sensors['SPACEBAR'] head = objects['Head_Empty' + suffix] hand = objects['Hand.R' + suffix] # Get the focusing object: # A ray sensor is attached to the HumanCamera sensor. # It returns all colliding objects in a 10 cm range of the hand. # We filter the result to keep only objects that have the 'Object' # property or that have children with the 'Object' property. focus = None prox_obj = ray.hitObject # focused object if prox_obj: if 'Object' in prox_obj: focus = prox_obj elif 'Door' in prox_obj or 'Drawer' in prox_obj or 'Switch' in prox_obj: focus = prox_obj else: for obj in prox_obj.children: if 'Object' in obj: focus = obj # set the overlay scene and change the displayed text # and texture if human['Manipulate'] and focus: can_be_manipulated = False if focus in passive_objects.graspable_objects(): can_be_manipulated = True if not ow['selected']: ow['Status'] = 'Pick up ' + passive_objects.label(focus) else: ow['Status'] = passive_objects.label(focus) elif 'Door' in focus or 'Drawer' in focus: can_be_manipulated = True try: if focus['Open']: ow['Status'] = 'Close ' + str(focus['Description']) else: ow['Status'] = 'Open ' + str(focus['Description']) except KeyError: logger.warning('Key missing in focused Object ' + focus.name + ' --- no description given') elif 'Switch' in focus: can_be_manipulated = True if objects[focus['Switch']]['On']: ow['Status'] = "Turn off " + focus['Switch'] else: ow['Status'] = "Turn on " + focus['Switch'] else: ow['Status'] = None else: ow['Status'] = None if human['Manipulate']: if not crosshairs in scene.post_draw: scene.post_draw.append(crosshairs) else: if crosshairs in scene.post_draw: scene.post_draw.remove(crosshairs) if ow['Status']: if not write_interaction_status in scene.post_draw: scene.post_draw.append(write_interaction_status) if not status_image in scene.post_draw: scene.post_draw.append(status_image) else: if write_interaction_status in scene.post_draw: scene.post_draw.remove(write_interaction_status) if status_image in scene.post_draw: scene.post_draw.remove(status_image) if space.positive: # blocks mouse movement if interactable object is focused try: if ('Door' in focus or 'Object' in focus or 'Drawer' in focus) and not ow['selected']: human['FOCUSED'] = True vect = Matrix.OrthoProjection('XY', 3) * human.getVectTo(focus)[1] human.alignAxisToVect(vect, 0, 1.0) # align the local x axis to point to the focused object else: human['FOCUSED'] = False except TypeError: human['FOCUSED'] = False else: human['FOCUSED'] = False try: if focus in passive_objects.graspable_objects(): if lmb.positive and not ow['selected']: # set a property - a property-sensor will fire the grab-function ow['grabbing'] = focus elif 'Door' in focus and lmb.positive: open_door(focus) # if you decide to use IPOs for the doors, # comment the previous line and uncomment the next line # the logic can be set with code in morse utils, which is currently # commented # focus['Open'] = not focus['Open'] elif 'Drawer' in focus and lmb.positive: focus['Open'] = not focus['Open'] elif 'Switch' in focus and lmb.positive: objects[focus['Switch']]['On'] = not objects[focus['Switch']]['On'] except TypeError: pass if rmb.positive: #drop selected Object ow['grabbing'] = None focused_object = lay_down_ray.hitObject if focused_object != None: actor_focused = blenderapi.objectdata( focused_object.name).game.use_actor # accurate placing of objects under certain conditions if human['Manipulate'] and lay_down_ray.positive \ and focused_object != ow['selected'] \ and actor_focused: # check not to lay the object on itself if ow['selected']: right_hand['LayDown'] = lay_down_ray.hitPosition right_hand['LayDownObj'] = focused_object # otherwise just drop the object else: if ow['selected']: ow['selected'].removeParent() ow['selected'] = None right_hand['moveArm'] = True
def to_base_vertices(deform_verts: bmesh.types.BMVertSeq, to_world_matrix, target_direction, target_origin, deform_vertex_index_weights: Dict[int, float], base_area_factor: float, project_vertically: bool) -> List[Vector]: ortho_projection_matrix = Matrix.OrthoProjection(target_direction, 4) f_l = 1 intrinsic_matrix = Matrix([ [f_l, 0.0, 0.0, 0.0], [0.0, f_l, 0.0, 0.0], [0.0, 0.0, f_l, 0.0], [0.0, 0.0, 0.0, 1.0] ]) wide_projection_matrix: Matrix = intrinsic_matrix @ ortho_projection_matrix @ Matrix.Translation(-target_origin) wide_project_2d_vertices: Set[Tuple[float, float]] = set() wide_project_3d_vertices: List[Vector] = [] deform_verts.ensure_lookup_table() for deform_vertex_index, deform_vertex_weight in deform_vertex_index_weights.items(): wide_project_3d_vertex = wide_projection_matrix @ (to_world_matrix @ deform_verts[deform_vertex_index].co) wide_project_2d_vertex = wide_project_3d_vertex / wide_project_3d_vertex[2] wide_project_2d_vertices.add(wide_project_2d_vertex[0:2]) wide_project_3d_vertices.append(wide_project_3d_vertex * (deform_vertex_weight**base_area_factor)) box_fit_angle: float = mathutils.geometry.box_fit_2d(list(wide_project_2d_vertices)) rotate_matrix: Matrix = Matrix.Rotation(+box_fit_angle, 4, target_direction) @ ortho_projection_matrix x_min = float('+inf') x_max = float('-inf') z_min = float('+inf') z_max = float('-inf') for vertex in wide_project_3d_vertices: rotate_vertex: Vector = rotate_matrix @ vertex if x_min > rotate_vertex.x: x_min = rotate_vertex.x if x_max < rotate_vertex.x: x_max = rotate_vertex.x if z_min > rotate_vertex.z: z_min = rotate_vertex.z if z_max < rotate_vertex.z: z_max = rotate_vertex.z rotate_matrix_invert: Matrix if project_vertically: front_vector = Vector([0, -1, 0]) rotate_matrix_invert = Matrix.Rotation(-box_fit_angle, 4, front_vector) @ Matrix.OrthoProjection(front_vector, 4) else: rotate_matrix_invert = Matrix.Rotation(-box_fit_angle, 4, target_direction) @ ortho_projection_matrix base_vertices: List[Vector] = [ rotate_matrix_invert @ Vector([x_min, 0, 0]), rotate_matrix_invert @ Vector([0, 0, z_min]), rotate_matrix_invert @ Vector([x_max, 0, 0]), rotate_matrix_invert @ Vector([0, 0, z_max]), ] return base_vertices