indexing description: "[ Animation objects hold a list of keyframes, defining a sequence of animation steps. Animatable properties include position, rotation and scaling. The shape of objects can be animated through repeating image sequences. Given a specific time, properties are smoothly interpolated between keyframes. This class is part of the XAE Extended Adventure Engine Project. ]" author: "Ralph Wiedemeier, ralphw@student.ethz.ch" date: "$Date$" revision: "$Revision$" class ANIMATION create make_empty, make_with_keyframe feature -- Initialization make_empty is -- Create new empty animation do create keyframes.make end make_with_keyframe (a_key: KEYFRAME) is -- Create new animation with first keyframe do make_empty extend (a_key) end feature -- Operation set_interpolation_request (a_time: INTEGER) is -- Set time for current interpolation require at_least_one_keyframe: count > 0 positive_time: a_time >= 0 local previous: KEYFRAME do time := a_time \\ (duration + 1) valid_request := True if key_a = Void or else time < key_a.time or else time > key_b.time then from keyframes.start until keyframes.item.time >= time or else keyframes.after loop previous := keyframes.item keyframes.forth end if keyframes.after then key_b := previous else key_b := keyframes.item end if previous = Void then key_a := key_b else key_a := previous end end if key_a.time = key_b.time then t := 0 else t := (time - key_a.time) / (key_b.time - key_a.time) end end total_number_of_images_used: INTEGER is -- Returns total number of images used by this animation -- (can be used for caching purposes) local number: INTEGER do Result := 1 from keyframes.start until keyframes.after loop number := keyframes.item.cycle_base_image + keyframes.item.cycle_image_count if number < 1 then number := 1 end if number > Result then Result := number end keyframes.forth end end feature -- Status x: INTEGER is -- Returns interpolated horizontal position require valid_request do if key_a.x /= key_b.x then result := ((1-t) * key_a.x + t * key_b.x).truncated_to_integer else result := key_a.x end end y: INTEGER is -- Returns interpolated vertical position require valid_request do if key_a.y /= key_b.y then result := ((1-t) * key_a.y + t * key_b.y).truncated_to_integer else result := key_b.y end end rotation: INTEGER is -- Returns interpolated rotation angle require valid_request do result := ((1-t) * key_a.rotation + t * key_b.rotation).truncated_to_integer end scaling: DOUBLE is -- Returns interpolated scaling factor require valid_request do result := (1-t) * key_a.scaling + t * key_b.scaling end image_number: INTEGER is -- Returns number of currently active image require valid_request: valid_request do if key_a.cycle_image_count > 1 and then key_a.cycle_phase_interval > 1 then result := key_a.cycle_base_image + (time // key_a.cycle_phase_interval) \\ key_a.cycle_image_count else Result := key_a.cycle_base_image end end duration: INTEGER -- Duration of whole animation count: INTEGER is -- Total number of keyframes do result := keyframes.count end valid_request: BOOLEAN -- You must first set an interpolation request for a specific time -- to set 'valid_request' to True and to be ready for requesting -- interpolated values feature -- Element change extend (a_key: KEYFRAME) is -- Append keyframe to the end of the keyframe list -- Time of kf must be greater than time of last kf in the list require key_not_void: a_key /= Void valid_time: a_key.time > duration do keyframes.extend (a_key) duration := a_key.time valid_request := False end insert (a_key: KEYFRAME) is -- Insert keyframe at correct time position local done: BOOLEAN do from keyframes.start until done or else keyframes.after loop if keyframes.item.time > a_key.time then keyframes.put_left (a_key) done := True end keyframes.forth end if not done then keyframes.extend (a_key) end valid_request := False end feature {NONE} -- Implementation keyframes: LINKED_LIST [KEYFRAME] -- List of keyframes time: INTEGER -- Current time key_a: KEYFRAME -- Left key of interpolation window key_b: KEYFRAME -- Right key of interpolation window t: DOUBLE -- Interpolation point (0..1) end -- class ANIMATION