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:
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.
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.
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.
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.