Proximity Queries for Crowd Simulation Using ... - ACM Digital Library

0 downloads 0 Views 2MB Size Report
Nov 9, 2013 - Rendering, visual variety, character animation, artificial intelli- gence and motion ..... en Inteligencia Artificial., 319–334. DENNY, M. O. 2003.
Proximity Queries for Crowd Simulation Using Truncated Voronoi Diagrams Oriam De Gyves∗ Tecnol´ogico de Monterrey M´exico

Leonel Toledo† Tencol´ogico de Monterrey M´exico

Abstract

simulations with thousands of agents, while leaving the Central Processing Unit (CPU) free for other important tasks of the game loop.

Crowd simulation has been used in the entertainment industry to create populated environments that seem more realistic than isolated scenes, specially in urban areas. Video games are no exception, but the simulation of large crowds is often restrained by the remaining compute time available in CPUs, which is often used for most part of the game loop. This paper presents a parallel technique, using consumer grade graphics hardware, for proximity queries that is suitable for real-time crowd simulations. We use a truncated Voronoi diagram and a sampling technique, using ray marching, to find agents’ neighbors in an environment texture. The experimental results suggest that our technique has significantly better performance than similar methods and can achieve simulations with thousands of agents in interactive frame rate.

2

1

Related work

Craig Reynolds presented one of the first research works about groups of autonomous virtual agents and their behaviors [Reynolds 1987]. According to his research, a bird is aware of three aspects during flocking, itself, two or three nearest neighbors, and the rest of the flock. These three aspects are important because they allow the birds to be part of a flock, independent of the number of birds in it. This concept extends to groups of people that constitute a crowd. According to the research by Moussaid et al., pedestrians inside a crowd move in groups, such as friends and families [Moussa¨ıd et al. 2010]. Because of the interactions inside the groups, the agents need to be aware of their neighbors. Hierarchical structures, like octrees, subdivide space into several regions containing agents [Hadap et al. 2004]. Some authors [van den Berg and Manocha 2008], [Guy et al. 2010] use kd-trees to make proximity queries a more efficient process. There are parallel kd-trees implementations in both CPU [Choi et al. 2010] and GPU [dos Santos et al. 2009]. Bleiweiss presented a parallel implementation of a popular collision avoidance library, gaining a 4.8X speedup compared to the original implementation [Bleiweiss 2009]. In this version, the author also changed the proximity query method from a kd-tree to a hash based method in order to improve the performance in GPU.

CR Categories: I.6.8 [Simulation and Modeling]: Types of Simulation—Gaming I.6.8 [Simulation and Modeling]: Types of Simulation—Parallel I.3.8 [Computer Graphics]: Applications Keywords: graphics

Isaac Rudom´ın‡ Barcelona Supercomputing Center Spain

Crowd simulation, proximity queries, computer

Introduction

Video games are constantly evolving and pushing technology forward to create more accurate depictions of reality. Some games have used crowd simulations to populate urban areas in order to achieve more realistic and vibrant scenes [Groenewegen 2010], [Szymanezyk et al. 2011]. Crowd simulation research area is growing rapidly and it has become one of the main research directions in computer games, movies and virtual reality [Wang et al. 2012]. Besides video games, crowd simulations have been used for urban planning, education and security, among others [De Gyves et al. 2013].

A topological multi-resolution data structure to find neighbors, which encodes the information for every agent in a cellular structure was presented by Jund et al. [Jund et al. 2012]. Passos et al. store entities inside a sorted matrix and use an extended Moore neighborhood to find neighbors [Passos et al. 2009]. Manocha et al. presented a technique that relies on both geometric localization and image-based proximity queries for finding neighbors [Hoff et al. 2001]. The authors point-sample the geometry, render interest objects and treat overwritten pixels as intersections. Millan et al. proposed an image-based only technique in which every agent paints an influence area in their position that other agents read to move through the environment [Millan et al. 2006].

Rendering, visual variety, character animation, artificial intelligence and motion planning are common problems that researchers try to solve in crowd simulations [Thalmann et al. 2009]. Several problems require the agents to be aware of their nearest neighbors, like collision avoidance and communication. A naive neighbor search algorithm has a complexity of O(n2 ), where n is the number of agents simulated.

We use a truncated Voronoi diagram for accurately querying the nearest neighbors of each agent. There is extensive research in the research community for computing Voronoi diagrams. Hoff et al. used a cone per site and rendering techniques to compute discrete Voronoi diagrams [Hoff et al. 1999]. Denny changed the cones for depth textures in order to improve the performance [Denny 2003]. Strzodka and Telea used splatting techniques to compute distance transforms [Strzodka and Telea 2004]. The splats that the authors used resemble the textures that Denny proposed to compute Voronoi diagrams, but instead of using the Z-Buffer, the authors use the blending stage.

We propose the use of truncated Voronoi diagrams as an efficient data structure for proximity queries. The system presented in this work moves both the proximity queries as well as the agent simulation to the Graphics Processing Units (GPUs) in order to achieve ∗ e-mail:[email protected] † e-mail:[email protected] ‡ e-mail:[email protected]

Permission to make digital or hard copies of part or all of this work for personal or classroom use is granted without fee provided that copies are not made or distributed for commercial advantage and that copies bear this notice and the full citation on the first page. Copyrights for components of this work owned by others than ACM must be honored. Abstracting with credit is permitted. To copy otherwise, to republish, to post on servers, or to redistribute to lists, requires prior specific permission and/or a fee. Request permissions from [email protected]. Motion in Games 2013, November 7 – 9, 2013, Dublin, Ireland. 2013 Copyright held by the Owner/Author. Publication rights licensed to ACM. ACM 978-1-4503-2546-2/13/11 $15.00

Rong and Tan introduced the Jump Flooding Algorithm (JFA) [Rong and Tan 2006]. The authors proposed three modifications to the algorithm: for less errors while computing the diagram, better performance and 3D diagrams [Rong and Tan 2007]. The time required to compute a discrete Voronoi diagram using JFA is inde-

65

Method/Sites Cones Gradient1 Gradient2 Per-Pixel Per-Site JFA

28 0.50 0.32 0.75 62.5 2.85 29.4

212 2.82 1.97 6.75 500 10.2 29.4

214 4.90 7.04 25 N/A 29.4 29.4

216 11.62 26.31 100 N/A 100 29.4

220 125 250 500 N/A 500 29.4

Table 1: Time, in milliseconds, required to compute Voronoi and truncated Voronoi diagrams.

Figure 1: Comparison between a discrete Voronoi diagram and our truncated Voronoi diagram.

seeds in the truncated Voronoi diagram represent the agents in the simulation. By using the diagram as an environment texture, each agent can obtain a local perception of its closest neighbors.

pendent of the number of sites, but dependent on the size of the texture. The same authors proposed a technique for parallel regional reduction on the GPU for evaluating integrals over Voronoi cells [Rong et al. 2011].

4

One important goal of this technique is to be able to simulate several thousand agents at interactive frame rates. However, computing a discrete Voronoi diagram for every frame heavily restrained the system. Several approaches were studied to efficiently compute discrete Voronoi diagrams, as well as truncated Voronoi diagrams, using the graphics hardware. We tested six techniques, three of them using GPGPU and the remaining using the rasterizer. The time required to compute the diagram is the main focus of the comparison among the different techniques, since our method aims at simulating crowds at interactive frame rates.

Algorithms for computing Voronoi diagrams using GPGPU have been proposed in the past. Majdandzic et al. presented an algorithm to compute discrete Voronoi diagrams using NVIDIA’s Compute Unified Device Architecture (CUDA) [Majdandzic et al. 2008]. By using Voronoi diagrams, the GAMMA group computed surface distance maps for each agent, which encodes the distance to the closest neighbors [Sud et al. 2007b]. These maps are used for both proximity queries and path planning. The same research group has used 1st and 2nd order Voronoi diagrams for proximity queries in other works [Sud et al. 2007a], [Sud et al. 2008].

The first technique, by [Hoff et al. 1999], renders a cone per site and uses the depth buffer to compute a discrete Voronoi diagram. The second technique, by [Denny 2003], replaces the cones with radial gradient textures in a quad geometry. The third technique, by [Strzodka and Telea 2004], also uses radial gradient textures but relies on the blending stage of the rasterizer to compute the diagram. We modified these three techniques to generate truncated Voronoi diagrams, by matching the cone radius and the quad size with the tile radius of the Voronoi cells.

Delaunay triangulations are also used for proximity queries, as they link each site with its closest sites in the Voronoi diagram. To the best of our knowledge, [Rong et al. 2008] algorithm is still the fastest 2D Delaunay triangulator. However, it is still unsuitable for real-time crowd simulations in terms of performance.

3

Voronoi diagrams for real-time simulations

Truncated Voronoi diagrams

The three remaining techniques compute discrete Voronoi diagrams and were implemented using GPGPU. The first one launches a thread per pixel and iterates over the available sites. The second technique launches a thread per site and the site’s color is propagated to neighbor pixels. The latter technique required a depth buffer technique to be used. Both techniques have an overall poor performance for real-time simulations. The last technique, by [Rong and Tan 2006], has near constant performance for any number of sites, but the diagram’s texture size heavily impacts on its performance.

Given a set of S seed points, a Voronoi diagram is a division of a space into |S| tiles, called Voronoi tiles, such that all points p inside a tile are closer to a particular seed than to any other seed [Majdandzic et al. 2008]. Formally, a Voronoi diagram VD(S) is a decomposition of Rd into Voronoi tiles V (s, S) = {p ∈ Rd | d(p, s) ≤ d(p, s0 )∀s0 ∈ S}. The technique presented in this paper relies on truncated Voronoi diagrams, an approximate diagram with the following characteristics: given a set of S seed points, divide a plane into |S| tiles such that all points p inside a tile are closer to a particular seed than to any other seed and are within a predefined radius, called tile radius r, per seed, using the seed coordinates as a center. Formally, a truncated Voronoi diagram tVD(S) is a decomposition of R2 into truncated Voronoi tiles tV (s, S) = {p ∈ R2 | d(p, s) ≤ d(p, s0 ) ∧ d(p, s) ≤ r∀s0 ∈ S}.

The time, in milliseconds, required for the diagram generation is detailed in Table 1, where Gradient1 stands for the technique by [Denny 2003] and Grandient2 is the technique by [Strzodka and Telea 2004]. The time reported in this section includes rendering the diagram into a texture and not to the default framebuffer, for further use by our method. Based on the data gathered in our tests, Figure 2, we found that computing truncated Voronoi diagrams over discrete Voronoi diagrams increased the simulation performance. In every test, we generated a 1,024 square Voronoi diagram texture. For less than 250,000 agents, the best techniques are [Hoff et al. 1999] and [Denny 2003]. For more than 250,000 agents, [Rong and Tan 2006] has the best performance and JFA can be used in this case without further impact on the simulation performance, since the output of the sampling stage (Section 5) is not modified if a discrete Voronoi diagram is used. A Level-of-Detail system is used to compute the

The visual difference between a Voronoi diagram and the truncated Voronoi diagram that we use can be seen in Figure 1. Both diagrams have the same configuration with 16 sites. The image to the left represents a common discrete Voronoi diagram. The image to the right represents a truncated Voronoi diagram. When the separation between seeds is greater than the tile radius, the truncated Voronoi diagram is composed of |S| circles. On the other hand, when the separation between all seeds is less than the tile radius, the diagram behaves as a discrete Voronoi diagram. The

66

Figure 4: Elements of the ray marching configuration used in this work. Figure 2: Semi-logarithmic base 10 of the time required to compute Voronoi and truncated Voronoi diagrams. inside its viewing area, without the need to partition the space or exhaustively search for them. In order to accurately detect all the neighbors in the vicinity, the separation between samples and the number of rays required is determined by the truncated tile radius. The maximum separation between rays, and samples, must be less than two times the tile radius. The truncated Voronoi tile is used as the area where an agent can be detected by other agents. Because of this, the practical restriction for the minimum tile radius is ri ≥ Gri , where ri and Gri represent the tile radius and the model’s geometry radius of agent i, respectively. The sampling configuration that we used can be seen in Figure 4. The red circle represents a truncated Voronoi tile and the purple circle represents the model’s geometry. The black lines are the rays scanning the agent’s visual field and the blue dots are sampling points. Assuming T is the set of all tile radii in the simulation, we define rs as the smallest element in the set, s as the desired number of samples per ray, a = Gri is the distance from the center of the tile to the first sample, b = rs is the length between samples, M = rs is the maximum separation between rays and R = a + (s − 1) · b is the length of each ray. This configuration forms the triangle 4RRM .

Figure 3: Sampling, using a ray marching technique, that scans for the closest neighbors of an agent using a truncated Voronoi diagram.

The angle between two rays, θ can be obtained using the law of cosines (Equation (1)) while the number of rays required for sampling is obtained by dividing the agent’s vision angle ϑ by θ (Equation (2)).   M2 θ = arccos 1 − (1) 2 · R2

diagram based on the number of agents in the simulation, selecting the appropriate method for the current necessities. However, currently we are not using the last technique in our simulation, but we are leaving it as future work.

5

Nrays =

Proximity queries using truncated Voronoi diagrams

6

To detect neighbors using the truncated Voronoi diagrams, we take samples in the local vicinity of the agents. To sample its neighborhood, an agent a performs a ray marching technique over the diagram to sense the viewing area in the direction of its movement. Figure 3 shows a graphic representation of the ray marching process. The circles represent the agents in the simulation; the purple agent is the one currently looking for its nearest neighbors and the green agents are the nearest neighbors. The red agents are not considered by the purple agent because are currently out of its viewing area.

ϑ θ

(2)

Experiments and results

We have tested the technique presented in this work with collision avoidance scenarios. While none of the following scenarios resemble a complex environment where a real crowd typically moves through, they were chosen to increase the number of possible collisions and stress the system as much as possible. We also decided not to include global planning in order to increase the density in the congestion areas. The first scenario is the Circle-N test, where N agents in a circle move to their diametrically opposite position. There is a high density point at the center of the circle. Bidirectional movement is the

By using this approach each agent obtains the closest neighbors

67

Figure 6: Bidirectional scenario.

Figure 5: Circle-N scenario.

following test scenario, in which the agents navigate in opposite directions. As in the first test, the bidirectional movement test has a high density point where the agents meet. The last test scenario is the intersection of two main roads. Agents walk in two directions, meeting at the intersection point, and successfully evading each other. Figure 7: Intersection scenario.

Our method is capable of simulating thousands of autonomous agents at interactive frame rates, while performing accurate collision avoidance. It is important to note that the proximity queries are performed in the graphics hardware, which allows us to implement the collision avoidance also in the graphics card. This Section presents the results of our method in several test scenarios.

memory. Bleiweiss used an NVIDIA GTX 280 graphics card with 240 CUDA cores. In comparison with the graphics card that we use, the GTX 280 has overall better system specifications and performance.

We tested the aforementioned scenarios ranging from 256 agents to 16,384 agents in real time. The techniques described in this work are implemented using C++ for the CPU code and OpenGL for the simulation and rendering techniques, on a Windows 7 x64 operating system with an Intel i7-2630QM quad core processor at 2.00 GHz and 8GB of memory. An NVIDIA GT 540M graphics card was used to test the system. The GT 540M is a Fermi-family graphics card with 96 CUDA cores and is OpenGL 4.3 capable; it is considered a low to mid-range GPU.

We tested bidirectional movement with 4,096 autonomous agents and achieved around 200 frames per second. The same test achieved around 60 frames per second for 16,384 agents. It is important to remark the high density area, near the center, where the agents meet in different directions, as seen in Figure 6. The last test scenario is the intersection of two main roads, which can be seen in Figure 7. Agents walk in two directions, meeting at the intersection point while successfully evading each other. This scenario shows basic interaction with obstacles (walls), which can be detected using the same technique, but placing the truncated Voronoi tiles along the obstacle’s perimeter.

[van den Berg and Manocha 2008] achieved 50 frames per second in a Circle-N test with 250 agents. For 256 agents, we achieved over 700 frames per second in this test, using a similar algorithm to RVO. Figure 5 shows this test scenario in seven still images. According to Bleiweiss, their parallel implementation of RVO has a 4.8X speedup compared to the original implementation [Bleiweiss 2009]. Bleiweiss also changed the proximity query method for a hash based method in order to improve the performance in GPU. Bleiweiss reports simulating 10,000 agents at 18 frames per second. In our experiments, we have simulated 16,384 agents at 60 frames per second, including the visualization. However, supposing the performance between 10,000 agents and 16,384 agents is linear, we have achieved a 5.4X speedup over Bleiweiss implementation with lower end hardware. The original authors of RVO used a 16-core Intel X7350 processor at 2.93 GHz and 8GB of system

As we have shown, the technique proposed is capable of simulating thousands of agents at interactive frame rates. This technique outperforms the 16-thread CPU implementation of the RVO authors and other GPU implementations. On the other hand, there is a limitation imposed by the size of the truncated Voronoi diagram; the number of agents is limited on the number of pixels available in the texture, however, increasing the number of available pixels impacts negatively on the performance. A level of detail technique to overcome this limitation is left as future work.

68

A Comparative Study. In 2009 21st International Symposium on Computer Architecture and High Performance Computing, IEEE, 41–48. G ROENEWEGEN , S. 2010. Improving crowd behaviour for games and virtual worlds. In Proceedings of the Fifth International Conference on the Foundations of Digital Games - FDG ’10, ACM Press, New York, New York, USA, 256–258. G UY, S. J., C HHUGANI , J., C URTIS , S., D UBEY, P., L IN , M., AND M ANOCHA , D. 2010. PLEdestrians: a least-effort approach to crowd simulation. Proceedings of the 2010 ACM SIGGRAPH/Eurographics Symposium on Computer Animation, 119–128. H ADAP, S., E BERLE , D., VOLINO , P., L IN , M. C., R EDON , S., AND E RICSON , C. 2004. Collision detection and proximity queries. In Proceedings of the conference on SIGGRAPH 2004 course notes - GRAPH ’04, ACM Press, New York, New York, USA, 15–es.

Figure 8: Crowd simulation, using our proximity queries technique, rendering complex and animated 3D characters.

7

H OFF , K. E., K EYSER , J., L IN , M., M ANOCHA , D., AND C UL VER , T. 1999. Fast computation of generalized Voronoi diagrams using graphics hardware. In Proceedings of the 26th annual conference on Computer graphics and interactive techniques - SIGGRAPH ’99, ACM Press, New York, New York, USA, 277–286.

Conclusions

Crowd simulation can be used to create immersive and realistic experiences for a wide variety of video game genres. It has been used in the past, but only for the simulation of a small number of agents because of hardware limitations. We have presented a parallel technique for proximity queries in microscopic crowd simulations that can be used for real time applications, such as video games, as seen in Figure 8.

H OFF , K. E., Z AFERAKIS , A., L IN , M., AND M ANOCHA , D. 2001. Fast and simple 2D geometric proximity queries using graphics hardware. In Proceedings of the 2001 symposium on Interactive 3D graphics - SI3D ’01, ACM Press, New York, New York, USA, vol. 31, 145–148. J UND , T., K RAEMER , P., AND C AZIER , D. 2012. A unified structure for crowd simulation. Computer Animation and Virtual Worlds 23, 3-4 (May), 311–320.

In our technique, we compute a truncated Voronoi diagram to efficiently query for the nearest neighbors in the local vicinity of the agents. This process takes advantage of the graphics hardware, of both the rendering and compute stages. By moving the proximity queries to the graphics card, other stages of the simulation can be moved too, like the collision avoidance. This helps alleviate some resources of the CPU and main system memory.

M AJDANDZIC , I., T REFFTZ , C., AND W OLFFE , G. 2008. Computation of Voronoi diagrams using a graphics processing unit. In 2008 IEEE International Conference on Electro/Information Technology, IEEE, 437–441. M ILLAN , E., H ERNANDEZ , B., AND RUDOMIN , I. 2006. Large Crowds of Autonomous Animated Characters Using Fragment Shaders and Level of Detail. In ShaderX5: Advanced Rendering Techniques, Wolfgang Engel, Ed. Charles River Media, ch. Beyond Pix, 501—-510.

As we have shown, the complete technique is able to outperform similar techniques. The experimental results show that 16,384 agents can be simulated at 60 frames per second; usually a crowded scene in a video game will require less agents than that when taking into account occlusion from buildings and terrain.

M OUSSA¨I D , M., P EROZO , N., G ARNIER , S., H ELBING , D., AND T HERAULAZ , G. 2010. The walking behaviour of pedestrian social groups and its impact on crowd dynamics. PloS one 5, 4 (Jan.), e10047.

References B LEIWEISS , A. 2009. Multi agent navigation on GPU. White paper, GDC.

PASSOS , E. B., J OSELLI , M., Z AMITH , M., C LUA , E. W. G., M ONTENEGRO , A., C ONCI , A., AND F EIJO , B. 2009. A bidimensional data structure and spatial optimization for supermassive crowd simulation on GPU. Computers in Entertainment 7, 4 (Dec.), 1.

C HOI , B., KOMURAVELLI , R., L U , V., S UNG , H., B OCCHINO , R. L., A DVE , S. V., AND H ART, J. C. 2010. Parallel SAH k-D tree construction. HPG ’10 Proceedings of the Conference on High Performance Graphics, 77–86. D E G YVES , O., T OLEDO , L., AND RUDOM´I N , I. 2013. Comportamientos en simulaci´on de multitudes : revisi´on del estado del arte. Research in Computer Science. 62, Special Issue: Avances en Inteligencia Artificial., 319–334.

R EYNOLDS , C. W. 1987. Flocks, herds and schools: A distributed behavioral model. ACM SIGGRAPH Computer Graphics 21, 4 (Aug.), 25–34. RONG , G., AND TAN , T.-S. 2006. Jump flooding in GPU with applications to Voronoi diagram and distance transform. In Proceedings of the 2006 symposium on Interactive 3D graphics and games - SI3D ’06, ACM Press, New York, New York, USA, 109.

D ENNY, M. O. 2003. Algorithmic geometry via graphics hardware. PhD thesis, Naturwissenschaftlich-Technische Fakult¨at I. S ANTOS , A. L., T EIXEIRA , J. M. X., DE FARIAS , T. S., T EICHRIEB , V., AND K ELNER , J. 2009. kD-Tree Traversal Implementations for Ray Tracing on Massive Multiprocessors:

DOS

RONG , G., AND TAN , T.-S. 2007. Variants of Jump Flooding Algorithm for Computing Discrete Voronoi Diagrams. In 4th

69

International Symposium on Voronoi Diagrams in Science and Engineering (ISVD 2007), IEEE, 176–181. RONG , G., TAN , T.- S ., AND C AO , T.- T. 2008. Computing twodimensional Delaunay triangulation using graphics hardware. In Proceedings of the 2008 symposium on Interactive 3D graphics and games - SI3D ’08, ACM Press, New York, New York, USA, 89. RONG , G., L IU , Y., WANG , W., Y IN , X., G U , X. D., AND G UO , X. 2011. GPU-assisted computation of centroidal Voronoi tessellation. IEEE transactions on visualization and computer graphics 17, 3 (Mar.), 345–56. S TRZODKA , R., AND T ELEA , A. 2004. Generalized distance transforms and skeletons in graphics hardware. In IEEE TCVG Symposium on Visualization. S UD , A., A NDERSEN , E., C URTIS , S., L IN , M., AND M ANOCHA , D. 2007. Real-time Path Planning for Virtual Agents in Dynamic Environments. In 2007 IEEE Virtual Reality Conference, IEEE, 91–98. S UD , A., G OVINDARAJU , N., G AYLE , R., A NDERSEN , E., AND M ANOCHA , D. 2007. Surface distance maps. In Proceedings of Graphics Interface 2007 on - GI ’07, ACM Press, New York, New York, USA, 35. S UD , A., A NDERSEN , E., C URTIS , S., L IN , M. C., AND M ANOCHA , D. 2008. Real-time path planning in dynamic virtual environments using multiagent navigation graphs. IEEE transactions on visualization and computer graphics 14, 3, 526– 38. S ZYMANEZYK , O., D ICKINSON , P., AND D UCKETT, T. 2011. From Individual Characters to Large Crowds : Augmenting the Believability of Open-World Games through Exploring Social Emotion in Pedestrian Groups. In Think Design Play: DiGRA Conference. T HALMANN , D., G RILLON , H., M AIM , J., AND Y ERSIN , B. 2009. Challenges in Crowd Simulation. In 2009 International Conference on CyberWorlds, IEEE, 1–12. B ERG , J., AND M ANOCHA , D. 2008. Reciprocal Velocity Obstacles for real-time multi-agent navigation. In 2008 IEEE International Conference on Robotics and Automation, IEEE, 1928–1935.

VAN DEN

WANG , X., Z HANG , J., AND S CALIA , M. 2012. Parallel Motion Simulation of Large-Scale Real-Time Crowd in a Hierarchical Environmental Model. Mathematical Problems in Engineering 2012, 1–15.

70

Suggest Documents