| /* |
| * Copyright 2015 Google Inc. All Rights Reserved. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| #include "cobalt/renderer/test/scenes/spinning_sprites_scene.h" |
| |
| #include <cmath> |
| #include <vector> |
| |
| #include "base/debug/trace_event.h" |
| #include "base/file_path.h" |
| #include "base/file_util.h" |
| #include "base/path_service.h" |
| #include "base/rand_util.h" |
| #include "cobalt/base/cobalt_paths.h" |
| #include "cobalt/math/point_f.h" |
| #include "cobalt/math/transform_2d.h" |
| #include "cobalt/render_tree/composition_node.h" |
| #include "cobalt/render_tree/image.h" |
| #include "cobalt/render_tree/image_node.h" |
| #include "cobalt/render_tree/matrix_transform_node.h" |
| #include "cobalt/renderer/test/png_utils/png_decode.h" |
| |
| using cobalt::math::Matrix3F; |
| using cobalt::math::PointF; |
| using cobalt::math::RectF; |
| using cobalt::math::RotateMatrix; |
| using cobalt::math::ScaleMatrix; |
| using cobalt::math::SizeF; |
| using cobalt::math::TranslateMatrix; |
| using cobalt::render_tree::animations::AnimateNode; |
| using cobalt::render_tree::animations::Animation; |
| using cobalt::render_tree::animations::AnimationList; |
| using cobalt::render_tree::CompositionNode; |
| using cobalt::render_tree::Image; |
| using cobalt::render_tree::ImageNode; |
| using cobalt::render_tree::MatrixTransformNode; |
| using cobalt::render_tree::Node; |
| using cobalt::render_tree::ResourceProvider; |
| using cobalt::renderer::test::png_utils::DecodePNGToRenderTreeImage; |
| |
| namespace cobalt { |
| namespace renderer { |
| namespace test { |
| namespace scenes { |
| |
| namespace { |
| |
| struct SpriteInfo { |
| float scale; |
| float rotation_speed; // In revolutions per second. |
| PointF position; // In normalized device coordinates. |
| }; |
| |
| float RandRange(float lower, float upper) { |
| return base::RandDouble() * (upper - lower) + lower; |
| } |
| |
| void AnimateSprite(base::TimeDelta start_time, const SpriteInfo& sprite_info, |
| const RectF& child_rect, |
| MatrixTransformNode::Builder* transform_node, |
| base::TimeDelta time) { |
| // Setup child node's scale and rotation and translation. |
| float theta = |
| (time - start_time).InSecondsF() * sprite_info.rotation_speed * 2 * M_PI; |
| transform_node->transform = |
| transform_node->transform * RotateMatrix(theta) * |
| ScaleMatrix(sprite_info.scale) * |
| TranslateMatrix( // Set child center as origin. |
| -0.5 * child_rect.width(), -0.5 * child_rect.height()); |
| } |
| |
| std::vector<SpriteInfo> CreateSpriteInfos() { |
| // Create a set of randomly positioned and sized sprites. |
| std::vector<SpriteInfo> sprite_infos; |
| const int kNumSprites = 40; |
| for (int i = 0; i < kNumSprites; ++i) { |
| const float kMinScale = 0.1f; |
| const float kMaxScale = 0.7f; |
| SpriteInfo sprite_info; |
| sprite_info.scale = RandRange(kMinScale, kMaxScale); |
| |
| sprite_info.position.set_x(static_cast<float>(base::RandDouble())); |
| sprite_info.position.set_y(static_cast<float>(base::RandDouble())); |
| |
| const float kMinRotationSpeed = 0.01f; |
| const float kMaxRotationSpeed = 0.3f; |
| sprite_info.rotation_speed = |
| RandRange(kMinRotationSpeed, kMaxRotationSpeed); |
| |
| sprite_infos.push_back(sprite_info); |
| } |
| return sprite_infos; |
| } |
| |
| scoped_refptr<Image> GetTestImage(ResourceProvider* resource_provider) { |
| // Load a test image from disk. |
| FilePath data_directory; |
| CHECK(PathService::Get(base::DIR_SOURCE_ROOT, &data_directory)); |
| return DecodePNGToRenderTreeImage( |
| data_directory.Append(FILE_PATH_LITERAL("test")) |
| .Append(FILE_PATH_LITERAL("scenes")) |
| .Append(FILE_PATH_LITERAL("demo_image.png")), |
| resource_provider); |
| } |
| |
| } // namespace |
| |
| scoped_refptr<render_tree::Node> CreateSpinningSpritesScene( |
| ResourceProvider* resource_provider, const math::SizeF& output_dimensions, |
| base::TimeDelta start_time) { |
| // Create an image for each SpriteInfo we have in our sprite_infos vector. |
| // They will be positioned and scaled according to their SpriteInfo settings, |
| // and rotated according to time. |
| CompositionNode::Builder spinning_sprites_scene_builder; |
| AnimateNode::Builder animations; |
| |
| // Now, setup a plurality of spinning images that contain the test image. |
| std::vector<SpriteInfo> sprite_infos = CreateSpriteInfos(); |
| scoped_refptr<Image> test_image = GetTestImage(resource_provider); |
| AnimationList<CompositionNode>::Builder sprite_animation_list; |
| for (int i = 0; i < sprite_infos.size(); ++i) { |
| const SpriteInfo& sprite_info = sprite_infos[i]; |
| |
| // Create the child image node that references the image data |
| scoped_refptr<ImageNode> image_node(new ImageNode(test_image)); |
| |
| scoped_refptr<MatrixTransformNode> transformed_node(new MatrixTransformNode( |
| image_node, |
| TranslateMatrix( // Place the image within the scene. |
| sprite_info.position.x() * output_dimensions.width(), |
| sprite_info.position.y() * output_dimensions.height()))); |
| |
| // Add the child image node to the list of composed nodes. |
| spinning_sprites_scene_builder.AddChild(transformed_node); |
| |
| animations.Add(transformed_node, |
| base::Bind(&AnimateSprite, start_time, sprite_info, |
| image_node->data().destination_rect)); |
| } |
| |
| scoped_refptr<CompositionNode> spinning_sprites_composition( |
| new CompositionNode(spinning_sprites_scene_builder.Pass())); |
| |
| return new AnimateNode(animations, spinning_sprites_composition); |
| } |
| |
| } // namespace scenes |
| } // namespace test |
| } // namespace renderer |
| } // namespace cobalt |