def __init__(self, **kwargs): super().__init__( distance=TunableInterval( description= '\n The distance range relative to origin point that \n the generated point should be in.\n ', tunable_type=float, minimum=0, default_lower=1, default_upper=5), angle=TunableAngle( description= '\n The slice of the donut/circle in degrees.\n ', default=TWO_PI), offset=TunableAngle( description= '\n An offset (rotation) in degrees, affecting where the start\n of the angle is. This has no effect if angle is 360 degrees.\n ', default=0), axis=TunableVariant( description= '\n Around which axis the position will be located.\n ', default='y', locked_args={ 'x': Vector3.X_AXIS(), 'y': Vector3.Y_AXIS(), 'z': Vector3.Z_AXIS() }), **kwargs)
def get_slot_pos(self, index=None): if index is None or not 0 <= index <= WorldSpawnPoint.SPAWN_POINT_SLOTS - 1: logger.warn('Slot Index {} for Spawn Point is out of range.', index) return self.center offset_from_start = WorldSpawnPoint.SLOT_START_OFFSET_FROM_CENTER offset = Vector3(offset_from_start.x, offset_from_start.y, offset_from_start.z) if index >= WorldSpawnPoint.SPAWN_POINT_SLOT_COLUMNS: pass return self._transform_position(offset)
def _create_object(self, definition_id, position=Vector3.ZERO(), orientation=Quaternion.IDENTITY(), level=0): obj = objects.system.create_object(definition_id) if obj is not None: transform = Transform(position, orientation) location = Location(transform, self.context.pick.routing_surface) obj.location = location self.created_objects.add(obj) return obj
def __init__(self, *args, **kwargs): super().__init__( *args, fixed=TunableVector3( description= '\n A fixed offset.\n ', default=Vector3.ZERO()), random_in_circle=TunableRandomOffsetInCircle( description= '\n Specify a random offset within given full/partial circle/donut.\n ' ), default='fixed', **kwargs)
def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self._attachment_chain = [] formation_count = self.master.get_routing_slave_data_count( self._formation_cls) self._formation_offset = self.formation_offsets[formation_count] self._setup_right_angle_connections() self._offset = Vector3.ZERO() for attachment_info in self._attachment_chain: self._offset.x = self._offset.x + attachment_info.parent_offset.x - attachment_info.offset.x self._offset.z = self._offset.z + attachment_info.parent_offset.y - attachment_info.offset.y self._slave_constraint = None self._slave_lock = None self._final_transform = None
def __new__(cls, *args): total_string = ''.join(args) try: transform_str = find_substring_in_repr(total_string, TRANSFORM_STR, TRANSFORM_END_STR, early_out=True) if not transform_str: raise transform_str = transform_str.replace(VECTOR3_STR, '') float_list = extract_floats(transform_str) return Transform( Vector3(float_list[0], float_list[1], float_list[2]), Quaternion(float_list[3], float_list[4], float_list[5], float_list[6])) except: logger.warn( 'Failed to parse TransformParam from {}'.format(total_string)) return total_string
def parse_node_string(cls, *args): total_string = ''.join(args) try: vector_substr = find_substring_in_repr(total_string, VECTOR3_STR, VECTOR_END_STR, early_out=True) if not vector_substr: raise float_list = extract_floats(vector_substr) node_position = Vector3(float_list[0], float_list[1], float_list[2]) total_string = total_string.replace(VECTOR3_STR, '') total_string = total_string.replace(vector_substr, '') node_portal_object_id = extract_ints(total_string)[0] return PathNode(position=node_position, portal_object_id=node_portal_object_id) except: logger.warn( 'Failed to parse path node from {} in PathParam'.format( total_string))
def __new__(cls, *args): total_string = ' '.join(args) try: vector_str = find_substring_in_repr(total_string, cls.begin_str, cls.end_str, early_out=True) if vector_str: vector_str = vector_str.replace(VECTOR3_STR, '') vector_str = vector_str.replace(VECTOR2_STR, '') float_list = extract_floats(vector_str) else: float_list = [float(arg) for arg in args] if len(float_list) == 2: return Vector2(float_list[0], float_list[1]) if len(float_list) == 3: return Vector3(float_list[0], float_list[1], float_list[2]) except: logger.warn( 'Failed to parse VectorParam from {}'.format(total_string)) return total_string
def find_good_location_for_slave(self, master_location): restrictions = [] fgl_kwargs = {} fgl_flags = 0 fgl_tuning = self.fgl_on_routes slave_position = master_location.transform.transform_point( self._offset) orientation = master_location.transform.orientation routing_surface = master_location.routing_surface if routing_surface is None: master_parent = master_location.parent if master_parent: routing_surface = master_parent.routing_surface if self.slave.is_sim or isinstance(self.slave, StubActor): (min_water_depth, max_water_depth ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim( routing_surface, self.slave) else: min_water_depth = None max_water_depth = None (min_water_depth, max_water_depth ) = OceanTuning.make_depth_bounds_safe_for_surface_and_sim( routing_surface, self.master, min_water_depth=min_water_depth, max_water_depth=max_water_depth) fgl_kwargs.update({ 'min_water_depth': min_water_depth, 'max_water_depth': max_water_depth }) if fgl_tuning.height_tolerance is not None: fgl_kwargs['height_tolerance'] = fgl_tuning.height_tolerance if fgl_tuning.slave_should_face_master: restrictions.append( RelativeFacingRange(master_location.transform.translation, 0)) fgl_kwargs.update({ 'raytest_radius': self.RAYTRACE_RADIUS, 'raytest_start_offset': self.RAYTRACE_HEIGHT, 'raytest_end_offset': self.RAYTRACE_HEIGHT, 'ignored_object_ids': {self.master.id, self.slave.id}, 'raytest_start_point_override': master_location.transform.translation }) fgl_flags = FGLSearchFlag.SHOULD_RAYTEST orientation_offset = sims4.math.angle_to_yaw_quaternion( sims4.math.vector3_angle( sims4.math.vector_normalize(self._offset))) orientation = Quaternion.concatenate(orientation, orientation_offset) starting_location = placement.create_starting_location( position=slave_position, orientation=orientation, routing_surface=routing_surface) if self.slave.is_sim: fgl_flags |= FGLSearchFlagsDefaultForSim fgl_context = placement.create_fgl_context_for_sim( starting_location, self.slave, search_flags=fgl_flags, restrictions=restrictions, **fgl_kwargs) else: fgl_flags |= FGLSearchFlagsDefault footprint = self.slave.get_footprint() master_position = master_location.position if hasattr( master_location, 'position') else master_location.transform.translation fgl_context = FindGoodLocationContext( starting_location, object_id=self.slave.id, object_footprints=(footprint, ) if footprint is not None else None, search_flags=fgl_flags, restrictions=restrictions, connectivity_group_override_point=master_position, **fgl_kwargs) (new_position, new_orientation) = placement.find_good_location(fgl_context) if new_position is None or new_orientation is None: logger.warn( 'No good location found for {} after slaved in a routing formation headed to {}.', self.slave, starting_location, owner='rmccord') return sims4.math.Transform( Vector3(*starting_location.position), Quaternion(*starting_location.orientation)) new_position.y = services.terrain_service.terrain_object( ).get_routing_surface_height_at(new_position.x, new_position.z, master_location.routing_surface) final_transform = sims4.math.Transform(new_position, new_orientation) return final_transform
def _get_close_to_deploy(self, timeline, vehicle): sim = self._interaction.sim constraint = self._get_deployment_constraint() if not constraint.valid: return InteractionQueuePreparationStatus.FAILURE yield handles = constraint.get_connectivity_handles(sim) goals = [] for handle in handles: goals.extend(handle.get_goals(single_goal_only=True)) if not goals: return InteractionQueuePreparationStatus.FAILURE yield if sim.posture.unconstrained: source_constraint = Position(sim.position, routing_surface=sim.routing_surface) else: source_constraint = Circle(sim.position, self.SOURCE_CONNECTIVITY_HANDLE_RADIUS, sim.routing_surface) source_handles = source_constraint.get_connectivity_handles(sim) if not source_handles: return InteractionQueuePreparationStatus.FAILURE yield source_goals = source_handles[0].get_goals(single_goal_only=True) if not source_goals: return InteractionQueuePreparationStatus.FAILURE yield source_goal = source_goals[0] if source_goal.position == goals[0].position and source_goal.routing_surface_id == goals[0].routing_surface_id: return InteractionQueuePreparationStatus.SUCCESS yield route = routing.Route(source_goal.location, goals, routing_context=sim.routing_context) plan_primitive = PlanRoute(route, sim, interaction=self._interaction) result = yield from element_utils.run_child(timeline, plan_primitive) if not result and not (not plan_primitive.path.nodes and not plan_primitive.path.nodes.plan_success): return InteractionQueuePreparationStatus.FAILURE yield cur_path = plan_primitive.path if not cur_path.nodes: return InteractionQueuePreparationStatus.FAILURE yield def get_start_node_index_for_path(vehicle, path): nodes = list(path.nodes) object_manager = services.object_manager() prev_node = None for node in nodes[::-1]: portal_obj_id = node.portal_object_id portal_obj = object_manager.get(portal_obj_id) if portal_obj_id else None if node.portal_id: if portal_obj: if not vehicle.vehicle_component.can_transition_through_portal(portal_obj, node.portal_id): break prev_node = node else: return 0 return prev_node.index split_paths = False while cur_path.next_path is not None: split_paths = True cur_path = cur_path.next_path if not cur_path.nodes: return InteractionQueuePreparationStatus.FAILURE yield start_node_index = get_start_node_index_for_path(vehicle, cur_path) start_node = cur_path.nodes[start_node_index] start_location = sims4.math.Location(Transform(Vector3(*start_node.position), Quaternion(*start_node.orientation)), start_node.routing_surface_id) if not split_paths and start_node_index == 0 and (start_location.transform.translation - source_goal.location.position).magnitude_squared() < vehicle.vehicle_component.minimum_route_distance: return InteractionQueuePreparationStatus.SUCCESS yield deploy_constraint = Position(start_location.transform.translation, routing_surface=start_location.routing_surface) depended_on_si = self._interaction affordance = self.get_close_affordance if self.get_close_affordance is not None else VehicleLiability.GET_CLOSE_AFFORDANCE aop = AffordanceObjectPair(affordance, None, affordance, None, route_fail_on_transition_fail=False, constraint_to_satisfy=deploy_constraint, allow_posture_changes=True, depended_on_si=depended_on_si) context = InteractionContext(sim, InteractionContext.SOURCE_SCRIPT, Priority.High, insert_strategy=QueueInsertStrategy.FIRST, must_run_next=True, group_id=depended_on_si.group_id) if not aop.test_and_execute(context): return InteractionQueuePreparationStatus.FAILURE yield return InteractionQueuePreparationStatus.NEEDS_DERAIL yield
def _factory(*args, distance, angle, offset, axis, **kwargs): rotation_radians = random.uniform(0, angle) + offset distance_vector = Vector3(distance.random_float(), 0, 0) return vector3_rotate_axis_angle(distance_vector, rotation_radians, axis)
def __new__(cls, x: float, y: float, z: float) -> 'CommonVector3': # noinspection PyTypeChecker return Vector3(x, y, z)