vegetation: Now using sphere cap for leaves, to avoid flat effect
This commit is contained in:
parent
f68bba75bb
commit
1e12b8ac9c
2 changed files with 26 additions and 10 deletions
|
@ -158,9 +158,10 @@ void VegetationModelDefinition::randomize()
|
||||||
for (int i = 0; i < 50; i++)
|
for (int i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
double radius = 0.15;
|
double radius = 0.15;
|
||||||
|
double scale = randomizeValue(radius, 0.5, 1.0);
|
||||||
Vector3 dir = Vector3::randomInSphere(1.0 - radius);
|
Vector3 dir = Vector3::randomInSphere(1.0 - radius);
|
||||||
Vector3 normal = dir.add(Vector3::randomInSphere(0.4)).add(Vector3(0.0, 0.3, 0.0)).normalize();
|
Vector3 normal = dir.add(Vector3::randomInSphere(0.4)).add(Vector3(0.0, 0.3, 0.0)).normalize();
|
||||||
Disk leaf(dir, normal, randomizeValue(radius, 0.8, 1.0));
|
Disk leaf(dir, normal, scale);
|
||||||
foliage_items.push_back(leaf);
|
foliage_items.push_back(leaf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -69,11 +69,26 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
|
||||||
|
|
||||||
for (const auto &leaf: model->getFoliageItems())
|
for (const auto &leaf: model->getFoliageItems())
|
||||||
{
|
{
|
||||||
Disk sized_leaf(leaf.getPoint(), leaf.getNormal(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius());
|
Sphere leafcap(leaf.getPoint(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius());
|
||||||
if (sized_leaf.checkRayIntersection(subray, &near) == 1)
|
// TODO Add cap intersection to Sphere class
|
||||||
|
Vector3 capnear, capfar;
|
||||||
|
if (leafcap.checkRayIntersection(subray, &capnear, &capfar) == 2)
|
||||||
{
|
{
|
||||||
near = near.scale(foliage.getRadius()).add(foliage.getCenter());
|
if (capnear.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5)
|
||||||
distance = ray.getCursor(near);
|
{
|
||||||
|
if (capfar.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
capnear = capfar;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Vector3 capnormal = capnear.sub(leaf.getPoint()).normalize();
|
||||||
|
capnear = capnear.scale(foliage.getRadius()).add(foliage.getCenter());
|
||||||
|
distance = ray.getCursor(capnear);
|
||||||
|
|
||||||
if (distance >= 0.0 and distance <= maximal)
|
if (distance >= 0.0 and distance <= maximal)
|
||||||
{
|
{
|
||||||
|
@ -89,8 +104,8 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
|
||||||
nearest = distance;
|
nearest = distance;
|
||||||
|
|
||||||
hit = true;
|
hit = true;
|
||||||
location = near;
|
location = capnear;
|
||||||
normal = sized_leaf.getNormal();
|
normal = capnormal;
|
||||||
|
|
||||||
if (normal.dotProduct(location.sub(segment.getStart())) > 0.0)
|
if (normal.dotProduct(location.sub(segment.getStart())) > 0.0)
|
||||||
{
|
{
|
||||||
|
@ -109,9 +124,9 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment,
|
||||||
if (hit)
|
if (hit)
|
||||||
{
|
{
|
||||||
SurfaceMaterial material(result);
|
SurfaceMaterial material(result);
|
||||||
material.reflection = 0.003;
|
material.reflection = 0.001;
|
||||||
material.shininess = 3.0;
|
material.shininess = 2.0;
|
||||||
material.hardness = 0.3;
|
material.hardness = 0.1;
|
||||||
material.validate();
|
material.validate();
|
||||||
return VegetationResult(location, normal, material);
|
return VegetationResult(location, normal, material);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue