def get_portal_locations(self, obj):
     actor = StubActor(1)
     arb_there = self._get_arb(actor, obj, is_mirrored=False)
     boundary_condition = arb_there.get_boundary_conditions(actor)
     there_entry = Transform.concatenate(
         boundary_condition.pre_condition_transform, obj.transform)
     there_entry = Location(there_entry.translation,
                            orientation=there_entry.orientation,
                            routing_surface=obj.routing_surface)
     there_exit = Transform.concatenate(
         boundary_condition.post_condition_transform, obj.transform)
     there_exit = Location(there_exit.translation,
                           orientation=there_exit.orientation,
                           routing_surface=obj.routing_surface)
     arb_back = self._get_arb(actor, obj, is_mirrored=True)
     boundary_condition = arb_back.get_boundary_conditions(actor)
     back_entry = Transform.concatenate(
         boundary_condition.pre_condition_transform, obj.transform)
     back_entry = Location(back_entry.translation,
                           orientation=back_entry.orientation,
                           routing_surface=obj.routing_surface)
     back_exit = Transform.concatenate(
         boundary_condition.post_condition_transform, obj.transform)
     back_exit = Location(back_exit.translation,
                          orientation=back_exit.orientation,
                          routing_surface=obj.routing_surface)
     return ((there_entry, there_exit, back_entry, back_exit, 0), )
Esempio n. 2
0
 def __str__(self):
     pre_str = '0'
     if self.pre_condition_transform != Transform.IDENTITY():
         n = list(self.pre_condition_transform.translation)
         n.extend(self.pre_condition_transform.orientation)
         pre_str = '({:0.3},{:0.3},{:0.3}/{:0.3},{:0.3},{:0.3},{:0.3})'.format(*n)
     post_str = '0'
     if self.post_condition_transform != Transform.IDENTITY():
         n = list(self.post_condition_transform.translation)
         n.extend(self.post_condition_transform.orientation)
         post_str = '({:0.3},{:0.3},{:0.3}/{:0.3},{:0.3},{:0.3},{:0.3})'.format(*n)
     return '{}+{} -> {}+{} {}'.format(self.pre_condition_reference_object_name, pre_str, self.post_condition_reference_object_name, post_str, self.required_slots)
Esempio n. 3
0
 def get_transforms(self, asm, part):
     pre_condition_transform = self.pre_condition_transform
     post_condition_transform = self.post_condition_transform
     pre_condition_reference_object = asm.get_actor_by_name(self.pre_condition_reference_object_name)
     if pre_condition_reference_object is not None:
         pre_obj_transform = pre_condition_reference_object.transform
         pre_condition_transform = Transform.concatenate(pre_condition_transform, pre_obj_transform)
     if self.post_condition_reference_object_name is None:
         return (pre_condition_transform, pre_condition_transform)
     post_condition_reference_object = asm.get_actor_by_name(self.post_condition_reference_object_name)
     if post_condition_reference_object is not None:
         post_obj_transform = post_condition_reference_object.transform
         post_condition_transform = Transform.concatenate(post_condition_transform, post_obj_transform)
     return (pre_condition_transform, post_condition_transform)
Esempio n. 4
0
 def clone(self,
           *,
           transform=DEFAULT,
           translation=DEFAULT,
           orientation=DEFAULT,
           routing_surface=DEFAULT,
           parent=DEFAULT,
           joint_name_or_hash=DEFAULT,
           slot_hash=DEFAULT):
     if transform is DEFAULT:
         transform = self.transform
     if transform is not None:
         if translation is DEFAULT:
             translation = transform.translation
         if orientation is DEFAULT:
             orientation = transform.orientation
         transform = Transform(translation, orientation)
     if routing_surface is DEFAULT:
         routing_surface = self.routing_surface
     if parent is DEFAULT:
         parent = self.parent
     if joint_name_or_hash is DEFAULT:
         joint_name_or_hash = self.joint_name_or_hash
     if slot_hash is DEFAULT:
         slot_hash = self.slot_hash
     return type(self)(transform, routing_surface, parent,
                       joint_name_or_hash, slot_hash)
Esempio n. 5
0
 def _update_portal_location(self, locations, there_entry, there_exit, obj,
                             other_obj, other_obj_angle_restriction):
     if there_entry.position == there_exit.position:
         return
     entry_in_position = there_entry.position + sims4.math.vector_normalize(
         there_exit.position - there_entry.position) * self.entry_offset
     entry_out_position = there_entry.position + sims4.math.vector_normalize(
         there_exit.position - there_entry.position) * self.exit_offset
     entry_in_position = Vector3(entry_in_position.x,
                                 there_entry.position.y,
                                 entry_in_position.z)
     entry_out_position = Vector3(entry_out_position.x,
                                  there_entry.position.y,
                                  entry_out_position.z)
     entry_angle = sims4.math.vector3_angle(there_exit.position -
                                            entry_in_position)
     exit_angle = sims4.math.vector3_angle(entry_in_position -
                                           there_exit.position)
     entry_orientation = sims4.math.angle_to_yaw_quaternion(entry_angle)
     exit_orientation = sims4.math.angle_to_yaw_quaternion(exit_angle)
     if self.angle_restriction is not None and not self._is_angle_valid(
             entry_orientation, obj, self.angle_restriction):
         return
     if other_obj_angle_restriction is not None and not self._is_angle_valid(
             exit_orientation, other_obj, other_obj_angle_restriction):
         return
     _there_in_entry = Location(entry_in_position, entry_orientation,
                                there_entry.routing_surface)
     _there_out_entry = Location(entry_out_position, entry_orientation,
                                 there_entry.routing_surface)
     there_exit.transform = Transform(there_exit.position, exit_orientation)
     locations.append(
         (_there_in_entry, there_exit, there_exit, _there_out_entry, 0))
Esempio n. 6
0
 def get_location_data_along_segment_gen(self,
                                         first_node_index,
                                         last_node_index,
                                         time_step=0.3):
     if self.nodes is None:
         return
     first_node = self.nodes[first_node_index]
     last_node = self.nodes[last_node_index]
     time = first_node.time
     end_time = last_node.time
     if time == end_time == 0.0:
         routing_surface = first_node.routing_surface_id
         dist = 0.0
         while True:
             while dist < 1.0:
                 pos = sims4.math.vector_interpolate(
                     Vector3(*first_node.position),
                     Vector3(*last_node.position), dist)
                 dist += time_step
                 yield (Transform(pos, Quaternion(*first_node.orientation)),
                        first_node.routing_surface_id, 0.0)
     else:
         while time < end_time:
             (transform,
              routing_surface) = self.get_location_data_at_time(time)
             yield (transform, routing_surface, time)
             time += time_step
Esempio n. 7
0
 def on_finalize_load(self):
     super().on_finalize_load()
     portal_component = self.get_component(PORTAL_COMPONENT)
     if portal_component is None:
         return
     locator_manager = services.locator_manager()
     locators = locator_manager.get(
         OceanTuning.get_beach_locator_definition().id)
     initial_transforms = [locator.transform for locator in locators]
     street_instance = services.current_zone().street
     if street_instance is not None:
         for beach_data in street_instance.beaches:
             beach_forward = Vector3(beach_data.forward.x, 0,
                                     beach_data.forward.y)
             orientation = Quaternion.from_forward_vector(beach_forward)
             transform = Transform(translation=beach_data.position,
                                   orientation=orientation)
             initial_transforms.append(transform)
     if not initial_transforms:
         self._off_lot_portals_created = False
         return
     off_lot_portal_ids = []
     self._create_all_transforms_and_portals_for_initial_transforms(
         initial_transforms, store_portal_ids=off_lot_portal_ids)
     self._off_lot_portals_created = bool(off_lot_portal_ids)
     self._lot_locator_transforms = self._get_lot_locator_transforms()
     if self._lot_locator_transforms:
         self._create_all_transforms_and_portals_for_initial_transforms(
             self._lot_locator_transforms,
             lot_transforms=True,
             prior_lengths=self._lot_constraint_starts_base_lengths,
             store_portal_ids=self._lot_portals)
     if self._off_lot_portals_created or self._lot_portals:
         services.object_manager().add_portal_to_cache(self)
Esempio n. 8
0
 def get_world_transform(parent, transform, joint_name_or_hash):
     if parent.is_part:
         parent_transform = parent.part_owner.transform
     else:
         parent_transform = parent.transform
     if joint_name_or_hash is None:
         if transform is None:
             return parent_transform
         return Transform.concatenate(transform, parent_transform)
     try:
         joint_transform = native.animation.get_joint_transform_from_rig(parent.rig, joint_name_or_hash)
     except (KeyError, ValueError) as e:
         return parent_transform
     if transform is None:
         return Transform.concatenate(joint_transform, parent_transform)
     local_transform = Transform.concatenate(transform, joint_transform)
     return Transform.concatenate(local_transform, parent_transform)
 def _get_carry_system_target(self, callback):
     (transform,
      routing_surface) = self._get_best_location(self.carry_target,
                                                 self.target)
     transform = Transform(transform.translation, self.sim.orientation)
     surface_height = services.terrain_service.terrain_object(
     ).get_routing_surface_height_at(transform.translation.x,
                                     transform.translation.z,
                                     routing_surface)
     transform.translation = Vector3(transform.translation.x,
                                     surface_height,
                                     transform.translation.z)
     return CarrySystemTerrainTarget(self.sim,
                                     self.carry_target,
                                     True,
                                     transform,
                                     routing_surface=routing_surface,
                                     custom_event_callback=callback)
Esempio n. 10
0
 def transform(self):
     if self._joint_transform is None:
         try:
             self._joint_transform = get_joint_transform_from_rig(
                 self.rig, ArbElement._BASE_ROOT_STRING)
         except KeyError:
             raise KeyError('Unable to find joint {} on {}'.format(
                 ArbElement._BASE_ROOT_STRING, self))
     return Transform.concatenate(self._joint_transform,
                                  self._location.world_transform)
Esempio n. 11
0
 def get_transforms_gen(self,
                        actor,
                        target,
                        fallback_routing_surface=None,
                        fgl_kwargs=None,
                        **kwargs):
     reserved_space_a = get_default_reserve_space(actor.species, actor.age)
     reserved_space_b = get_default_reserve_space(target.species,
                                                  target.age)
     fgl_kwargs = fgl_kwargs if fgl_kwargs is not None else {}
     ignored_objects = {actor.id, target.id}
     ignored_ids = fgl_kwargs.get('ignored_object_ids')
     if ignored_ids is not None:
         ignored_objects.update(ignored_ids)
     fgl_kwargs['ignored_object_ids'] = ignored_objects
     for (transform,
          jig_params) in self._get_available_transforms_gen(actor, target):
         actor_angle = yaw_quaternion_to_angle(transform.orientation)
         (translation_a, orientation_a, translation_b, orientation_b,
          routing_surface) = generate_jig_polygon(
              actor.location,
              transform.translation,
              actor_angle,
              target.location,
              Vector2.ZERO(),
              0,
              reserved_space_a.left,
              reserved_space_a.right,
              reserved_space_a.front,
              reserved_space_a.back,
              reserved_space_b.left,
              reserved_space_b.right,
              reserved_space_b.front,
              reserved_space_b.back,
              fallback_routing_surface=fallback_routing_surface,
              reverse_nonreletive_sim_orientation=self.
              reverse_actor_sim_orientation,
              **fgl_kwargs)
         if translation_a is None:
             continue
         yield (Transform(translation_a, orientation_a),
                Transform(translation_b,
                          orientation_b), routing_surface, jig_params)
Esempio n. 12
0
 def get_initial_offset(self,
                        actor,
                        to_state_name,
                        from_state_name='entry'):
     arb = NativeArb()
     self.traverse(from_state_name,
                   to_state_name,
                   arb,
                   from_boundary_conditions=True)
     offset = arb.get_initial_offset(actor)
     return Transform(Vector3(*offset[0]), Quaternion(*offset[1]))
Esempio n. 13
0
 def get_location_data_at_time(self, time):
     if self.nodes is None:
         return
     routing_surface = self.node_at_time(time).routing_surface_id
     translation = Vector3(*self.nodes.position_at_time(time))
     translation.y = services.terrain_service.terrain_object(
     ).get_routing_surface_height_at(translation.x, translation.z,
                                     routing_surface)
     orientation = Quaternion(
         *self.nodes.orientation_at_time(time, self.blended_orientation))
     return (Transform(translation, orientation), routing_surface)
 def get_portal_locations(self, obj):
     locations = []
     for portal_entry in self.object_portals:
         there_entry = portal_entry.location_entry(obj)
         there_exit = portal_entry.location_exit(obj)
         if not self._is_offset_from_object(there_entry, obj):
             if self._is_offset_from_object(there_exit, obj):
                 continue
             if not self._is_object_routing_surface_overlap(
                     there_entry, obj):
                 if self._is_object_routing_surface_overlap(
                         there_exit, obj):
                     continue
                 entry_angle = sims4.math.vector3_angle(
                     there_exit.position - there_entry.position)
                 there_entry.transform = Transform(
                     there_entry.position,
                     sims4.math.angle_to_yaw_quaternion(entry_angle))
                 exit_angle = sims4.math.vector3_angle(
                     there_entry.position - there_exit.position)
                 there_exit.transform = Transform(
                     there_exit.position,
                     sims4.math.angle_to_yaw_quaternion(exit_angle))
                 if portal_entry.is_bidirectional:
                     offset_entry = self._get_offset_positions(
                         there_entry, there_exit, entry_angle)
                     offset_exit = self._get_offset_positions(
                         there_exit, there_entry, exit_angle)
                     if not self._is_object_routing_surface_overlap(
                             offset_entry, obj
                     ) and not self._is_object_routing_surface_overlap(
                             offset_exit, obj):
                         locations.append((offset_entry, offset_exit,
                                           there_exit, there_entry, 0))
                         locations.append(
                             (there_entry, there_exit, None, None, 0))
                 else:
                     locations.append(
                         (there_entry, there_exit, None, None, 0))
     return locations
 def _get_best_location(self, obj, target):
     routing_surface = getattr(self.target, 'provided_routing_surface',
                               None)
     if routing_surface is None:
         routing_surface = target.routing_surface
     if self._transform is UNSET:
         if target.is_terrain:
             self._transform = target.transform
         else:
             (translation,
              orientation) = CarryingObject.get_good_location_on_floor(
                  obj,
                  starting_transform=target.transform,
                  starting_routing_surface=routing_surface,
                  additional_search_flags=FGLSearchFlag.
                  STAY_IN_CURRENT_BLOCK)
             if translation is None:
                 self._transform = None
             else:
                 self._transform = Transform(translation, orientation)
     return (self._transform, routing_surface)
Esempio n. 16
0
 def clone(self, *, transform=DEFAULT, translation=DEFAULT, orientation=DEFAULT, routing_surface=DEFAULT, parent=DEFAULT, joint_name_or_hash=DEFAULT, slot_hash=DEFAULT):
     if transform is DEFAULT:
         if translation is DEFAULT:
             translation = self.transform.translation
         if orientation is DEFAULT:
             orientation = self.transform.orientation
     else:
         if transform is None:
             raise ValueError('Attempt to pass a None transform into a location clone.')
         if translation is DEFAULT:
             translation = transform.translation
         if orientation is DEFAULT:
             orientation = transform.orientation
     transform = Transform(translation, orientation)
     if routing_surface is DEFAULT:
         routing_surface = self.routing_surface
     if parent is DEFAULT:
         parent = self.parent
     if joint_name_or_hash is DEFAULT:
         joint_name_or_hash = self.joint_name_or_hash
     if slot_hash is DEFAULT:
         slot_hash = self.slot_hash
     return type(self)(transform, routing_surface, parent, joint_name_or_hash, slot_hash)
Esempio n. 17
0
 def _get_transform_2(p, n0, n1):
     return Transform(p,
                      Quaternion.from_forward_vector(n0 * 0.5 + n1 * 0.5))
Esempio n. 18
0
 def get_joint_transform_for_joint(self, joint_name):
     transform = get_joint_transform_from_rig(self.rig, joint_name)
     transform = Transform.concatenate(transform, self.transform)
     return transform
Esempio n. 19
0
    def _create_all_transforms_and_portals_for_initial_transforms(
            self,
            initial_transforms,
            lot_transforms=False,
            prior_lengths=None,
            store_portal_ids=None):
        portal_component = self.get_component(PORTAL_COMPONENT)
        if portal_component is None:
            return

        def _store_transforms(species, ages, interval, transforms):
            for age in ages:
                key = (species, age, interval)
                if key in self._constraint_starts:
                    if prior_lengths is not None:
                        prior_lengths[key] = len(self._constraint_starts[key])
                    self._constraint_starts[key].extend(transforms)
                else:
                    if prior_lengths is not None:
                        prior_lengths[key] = 0
                    self._constraint_starts[key] = transforms

        routing_surface = SurfaceIdentifier(services.current_zone_id(), 0,
                                            SurfaceType.SURFACETYPE_WORLD)
        edge_transforms = adjust_locations_for_coastline(initial_transforms)

        def _get_water_depth_at_edge(i):
            transform = edge_transforms[i]
            translation = transform.translation + transform.orientation.transform_vector(
                Ocean.EDGE_TEST_POINT_OFFSET)
            return get_water_depth(translation.x, translation.z)

        for (species, age_data) in OceanTuning.OCEAN_DATA.items():
            required_pack = SpeciesExtended.get_required_pack(species)
            if required_pack is not None and not is_available_pack(
                    required_pack):
                continue
            for age_ocean_data in age_data:
                ocean_data = age_ocean_data.ocean_data
                beach_portal = ocean_data.beach_portal_data
                wading_depth = ocean_data.wading_interval.lower_bound
                max_wading_depth = wading_depth + ocean_data.water_depth_error
                swim_depth = ocean_data.wading_interval.upper_bound
                min_swim_depth = swim_depth - ocean_data.water_depth_error
                transforms = adjust_locations_for_target_water_depth(
                    wading_depth, ocean_data.water_depth_error,
                    initial_transforms)
                wading_transforms = []
                for i in range(len(transforms) - 1):
                    transform = transforms[i]
                    if transform.translation == VECTOR3_ZERO:
                        depth = _get_water_depth_at_edge(i)
                        if depth <= max_wading_depth:
                            wading_transforms.append(edge_transforms[i])
                            wading_transforms.append(transform)
                    else:
                        wading_transforms.append(transform)
                transforms = adjust_locations_for_target_water_depth(
                    swim_depth, ocean_data.water_depth_error,
                    initial_transforms)
                portal_transforms = []
                for i in range(len(transforms) - 1):
                    transform = transforms[i]
                    if transform.translation == VECTOR3_ZERO:
                        depth = _get_water_depth_at_edge(i)
                        if min_swim_depth <= depth:
                            edge_transform = edge_transforms[i]
                            translation = edge_transform.translation + edge_transform.orientation.transform_vector(
                                Ocean.EDGE_PORTAL_BACKSET)
                            portal_transforms.append(
                                Transform(translation,
                                          edge_transform.orientation))
                    else:
                        portal_transforms.append(transform)
                _store_transforms(species, age_ocean_data.ages,
                                  WaterDepthIntervals.WET,
                                  edge_transforms.copy())
                _store_transforms(species, age_ocean_data.ages,
                                  WaterDepthIntervals.WADE, wading_transforms)
                _store_transforms(species, age_ocean_data.ages,
                                  WaterDepthIntervals.SWIM, portal_transforms)
                if beach_portal is None:
                    pass
                else:
                    if lot_transforms:
                        portal_transforms = self._reorient_lot_transforms(
                            portal_transforms)
                    portal_creation_mask = SpeciesExtended.get_portal_flag(
                        species)
                    for portal_transform in portal_transforms:
                        portal_location = Location(
                            portal_transform, routing_surface=routing_surface)
                        portal_ids = portal_component.add_custom_portal(
                            OceanPoint(portal_location), beach_portal,
                            portal_creation_mask)
                        add_portals = []
                        remove_portals = []
                        for portal_id in portal_ids:
                            portal_instance = portal_component.get_portal_by_id(
                                portal_id)
                            if portal_instance is not None:
                                location = None
                                if portal_id == portal_instance.there:
                                    location = portal_instance.there_entry
                                elif portal_id == portal_instance.back:
                                    location = portal_instance.back_exit
                                if location and build_buy.is_location_natural_ground(
                                        location.position,
                                        location.routing_surface.secondary_id):
                                    add_portals.append(portal_id)
                                else:
                                    remove_portals.append(portal_id)
                        if remove_portals:
                            portal_component.remove_custom_portals(
                                remove_portals)
                        if add_portals and store_portal_ids is not None:
                            store_portal_ids.extend(add_portals)
 def _get_bone_transform(self):
     joint_transform = get_joint_transform_from_rig(self._owner.rig, self._bone_name)
     offset_from_joint = joint_transform.transform_point(self._bone_offset)
     final_transform = Transform.concatenate(Transform(offset_from_joint), self._owner.transform)
     return final_transform
Esempio n. 21
0
def get_difference_transform(transform_a, transform_b):
    v = transform_b.translation - transform_a.translation
    a_q_i = invert_quaternion(transform_a.orientation)
    q = Quaternion.concatenate(transform_b.orientation, a_q_i)
    v_prime = Quaternion.transform_vector(a_q_i, v)
    return Transform(v_prime, q)
Esempio n. 22
0
 def _get_transform_1(p, n0):
     return Transform(p, Quaternion.from_forward_vector(n0))
Esempio n. 23
0
 def _get_transform_3(p, n0, n1, n2):
     return Transform(
         p,
         Quaternion.from_forward_vector(n0 * 0.25 + n1 * 0.5 + n2 * 0.25))