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
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)
def _is_angle_valid(self, entry_orientation, obj, angle_restriction): rel_orientation = Quaternion.concatenate( sims4.math.invert_quaternion(obj.transform.orientation), entry_orientation) angle = sims4.math.yaw_quaternion_to_angle(rel_orientation) if sims4.math.is_angle_in_between(angle, angle_restriction.start_angle, angle_restriction.end_angle): return True return False
def __init__(self, position, orientation=None, routing_surface=None): if orientation is None: orientation = Quaternion.ZERO() if routing_surface is None: import sims4.log sims4.log.callstack( 'Routing', 'Attempting to create a location without a routing_surface.') routing_surface = SurfaceIdentifier(0, 0) super().__init__(position, orientation, routing_surface)
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]))
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_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)
def invert_quaternion(q): d = 1.0 / (q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w) return Quaternion(-d * q.x, -d * q.y, -d * q.z, d * q.w)
def angle_to_yaw_quaternion(angle): return Quaternion.from_axis_angle(angle, UP_AXIS)
def vector3_rotate_axis_angle(v, angle, axis): q = Quaternion.from_axis_angle(angle, axis) return q.transform_vector(v)
def get_orientation(self, obj): if self._tuned_orientation: return Quaternion.concatenate( obj.orientation, angle_to_yaw_quaternion(self._tuned_orientation))
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)
def angle_to_yaw_quaternion(angle): return Quaternion.from_axis_angle(angle, UP_AXIS)
def vector3_rotate_axis_angle(v, angle, axis): q = Quaternion.from_axis_angle(angle, axis) return q.transform_vector(v)
def _get_transform_1(p, n0): return Transform(p, Quaternion.from_forward_vector(n0))
def _get_transform_2(p, n0, n1): return Transform(p, Quaternion.from_forward_vector(n0 * 0.5 + n1 * 0.5))
def _get_transform_3(p, n0, n1, n2): return Transform( p, Quaternion.from_forward_vector(n0 * 0.25 + n1 * 0.5 + n2 * 0.25))