Introduction

For a quick introduction to creating crowds of figures using POV-Person, see the Quick Start Guide to Crowd Control. This section is more of a discussion about the crowd macros and control variables that are used to create a crowd of figures. It also delves a little into how they work.

Defining Figure Positions

The ppCrowdPositions macro uses the concept of a platform object. This object is often an object that appears in your POV-Ray scene, but does not have to be. It could be a tailored object, such as a part of an object from your scene, or an object that does not appear at all in your scene. The object definition is passed into the macro by setting ppCrowdPlatform .

The ppCrowdPositions macro finds the extents of this platform object, then shoots a series of rays vertically downwards within the rectangle defined by the minimum and maximum 'x' and 'z' extents. The < x,z > coordinates of each ray are selected at random. Some of these rays will subsequently be rejected for any of the following reasons:

  1. The ray doesn't hit a part of the surface of the object
  2. The position at which the ray hits the surface is too close to one of the other positions that has already been chosen
  3. The gradient of the surface at the point where the ray hits the surface is too steep to position a figure on
  4. The position at which the ray hits the surface is too close to an edge or drop-off

If a 'good' position is found it is added to a pair of arrays that hold the positions and the surface normals at those positions. These arrays can subsequently be used to place an object at each of the recorded locations. The macro uses the ppFigurePositions array to store positions.

It is quite possible for you to specify a platform object that is too small to support the requested number of positions, given the parameters and settings that you pass to the ppCrowdPositions macro. The macro therefore uses a counter to record the number of successive 'misses' and compares this with the ppCrowdPositionMaxTries control variable that places a limit on the number of unsuccessful attempt, preventing infinite loops. The default value for ppCrowdPositionMaxTries is 100, but you can override this default from your scene file.

The macro uses the ppCrowdFigureSeparation control variable to determine the acceptable distance from other positions for its proximity calculations. The surface gradient and the edge proximity calculations are performed by sampling a small number of points around the position being tested. The number of samples is controlled using ppCrowdEdgeDetectionSamples , the distance of the sample from the position being tested is controlled using the ppCrowdDistanceFromEdge variable and the drop that is permitted before a change in level is considered to be too much is controlled by the ppCrowdPermittedDrop variable.

The random numbers used for selecting positions are generated based upon a seed held in ppCrowdRand . It is set when ppCrowdPositions is called to start a pseudo random number sequence. It is only is called the first time and subsequently not reset. This means that a scene will consistently generate the same crowd, but two calls to the macro within a scene will generate different crowds. If you wish to change this seed you can set it in your scene file before calling the macro.

The following control variables can be used in conjunction with the ppCrowdPositions macro:

ppCrowdRand Default value = seed(38)
ppCrowdPositionMaxTries Default value = 100
ppFigurePositions Default value = array[Number of New Figures]
ppFigureCounter Default value = 0
ppCrowdFigureSeparation Default value = 0.5
ppCrowdDistanceFromEdge Default value = 0.25
ppCrowdPermittedDrop Default value = 0.1
ppCrowdEdgeDetectionSamples Default value = 4
ppCrowdPlatform Default value = box{<0,-0.001,0>,<10,0,10>}

You can explicitly assign positions to the ppFigurePositions array if you wish, or develop your own algorithm for assigning positions into the array.

You can also define some positions explicitly and have the ppCrowdPositions macro fill in the rest, taking account of the positions you have defined when it performs its positioning algorithms helping you to avoid having a randomly positioned character that intercepts characters that you wish to position explicitly.

Members of a Crowd

To create a POV-Person crowd you can use a single figure, duplicated to make the required number of clones or you can use a range of different characters. Potentially, each member of the crowd could be unique, which could be required for fairly small crowds.

Once a crowd gets larger, you can probably use a restricted number of unique figures to improve performance and accept that there will be duplicates.

You can call the ppFigure macro multiple times, assigning the generated figures to elements of the ppCrowdFigureList array. You can also make this assignment within a loop using the POV_Person randomising control files to generate a unique figure each time the ppFigure macro is called. The following example illustrates the use of the randomising control files to create an array of figure objects with a potentially different figure assigned to each element of the array.

#local I = 0;
#declare ppCrowdFigureList = array[40];
#while (I     #declare ppCrowdFigureList[I] = ppFigure("pprandomcharacter.inc","pprandomstyle.inc","pprandomexpression.inc","pprandompose.inc","pprandomoutfit.inc");
    #local I = I + 1;
#end

You can also use a combination of these techniques, for example you could use random characters all wearing the same outfit. You could manually populate the first few positions of the ppCrowdFigureList array and use a loop to populate the remaining elements of the array with random figures.

Making a Crowd

Once you have defined a series of positions and an array of figure objects to place at those positions you can use the ppCrowd macro to place a figure at each of those positions. The ppCrowd macro will step through the sequence of positions held in the ppFigurePositions array and will step through the sequence of figure objects in the ppCrowdFigureList array positioning one figure at each position. If the figure list is smaller than the list of positions the ppCrowd macro will restart at the beginning of the ppCrowdFigureList array and will loop through it as many times as required to fill the required number of positions.

Because the positions and the list of figures are both processed sequentialy, any explicitly defined positions at the start of the ppFigurePositions array will map to any explicitly defined figure objects defined at the start of the ppCrowdFigureList array, enabling you to pose specific figures at specific locations while using the POV-Person crowd macros to position other figures around and about them.


Copyright Chris Bartlett 2005.
You are authorised to re-use this document in original or modified form for both commercial or non-commercial purposes, with or without credit being given to the author, provided that such re-use does not in any way prevent others from re-using this document in either original or modified form.