#include <simgear/misc/PathOptions.hxx>
#include <simgear/props/props.hxx>
#include <simgear/scene/model/model.hxx>
+#include <simgear/scene/model/SGReaderWriterXMLOptions.hxx>
#include <simgear/scene/util/StateAttributeFactory.hxx>
#include <simgear/scene/util/SGUpdateVisitor.hxx>
"texture"),
"image"),
texture);
- osg::ref_ptr<osgDB::ReaderWriter::Options> options
+ ref_ptr<osgDB::ReaderWriter::Options> options
= makeOptionsFromPath(tex_path);
- if ((effect = makeEffect(pcloudEffect, true, options)))
+ ref_ptr<SGReaderWriterXMLOptions> sgOptions
+ = new SGReaderWriterXMLOptions(*options.get());
+ if ((effect = makeEffect(pcloudEffect, true, sgOptions.get())))
effectMap.insert(EffectMap::value_type(texture, effect));
} else {
effect = iter->second.get();
// The value is squared as we use vector calculations.
float cull_distance_squared = min_sprite_height * min_sprite_height * 0.1f;
- // The number of sprites we actually used is a function of the (user-controlled) density
- int n_sprites = num_sprites * sprite_density;
+ // The number of sprites we actually use is a function of the (user-controlled) density
+ int n_sprites = num_sprites * sprite_density * (0.5 + sg_random());
for (int i = 0; i < n_sprites; i++)
{
// Determine the position of the sprite. Rather than being completely random,
// we place them on the surface of a distorted sphere. However, we place
- // the first and second sprites on the top and bottom, and the third in the
- // center of the sphere (and at maximum size) to ensure good coverage and
- // reduce the chance of there being "holes" in our cloud.
+ // the first sprite in the center of the sphere (and at maximum size) to
+ // ensure good coverage and reduce the chance of there being "holes" in our
+
float x, y, z;
-
+
if (i == 0) {
- x = 0;
- y = 0;
- z = height * 0.5f;
- } else if (i == 1) {
- x = 0;
- y = 0;
- z = - height * 0.5f;
- } else if (i == 2) {
x = 0;
y = 0;
z = 0;
double elev = sg_random() * SGD_PI;
x = width * cos(theta) * 0.5f * sin(elev);
y = width * sin(theta) * 0.5f * sin(elev);
- z = height * cos(elev) * 0.5f;
+ z = height * cos(elev) * 0.5f;
}
// Determine the height and width as scaling factors on the minimum size (used to create the quad).
float sprite_width = 1.0f + sg_random() * (max_sprite_width - min_sprite_width) / min_sprite_width;
float sprite_height = 1.0f + sg_random() * (max_sprite_height - min_sprite_height) / min_sprite_height;
-
- if (i == 2) {
+
+ // Sprites are never taller than square.
+ if (sprite_height * min_sprite_height > sprite_width * min_sprite_width)
+ {
+ sprite_height = sprite_width * min_sprite_width / min_sprite_height;
+ }
+
+ if (i == 0) {
// The center sprite is always maximum size to fill up any holes.
sprite_width = 1.0f + (max_sprite_width - min_sprite_width) / min_sprite_width;
sprite_height = 1.0f + (max_sprite_height - min_sprite_height) / min_sprite_height;
}
-
- // Determine the sprite texture indexes;
+
+ // Determine the sprite texture indexes.
int index_x = (int) floor(sg_random() * num_textures_x);
if (index_x == num_textures_x) { index_x--; }
-
- int index_y = (int) floor(sg_random() * num_textures_y);
+
+ // The y index depends on the positing of the sprite within the cloud.
+ // This allows cloud designers to have particular sprites for the base
+ // and tops of the cloud.
+ int index_y = (int) floor((z / height + 0.5f) * num_textures_y);
if (index_y == num_textures_y) { index_y--; }
sg->addSprite(SGVec3f(x, y, z),