From 1e12b8ac9c5df71b3a0b84bd1c1b7685250292a6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Lemaire?= Date: Wed, 4 Nov 2015 01:08:48 +0100 Subject: [PATCH] vegetation: Now using sphere cap for leaves, to avoid flat effect --- src/definition/VegetationModelDefinition.cpp | 3 +- .../software/VegetationModelRenderer.cpp | 33 ++++++++++++++----- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/definition/VegetationModelDefinition.cpp b/src/definition/VegetationModelDefinition.cpp index f30baa4..78f917e 100644 --- a/src/definition/VegetationModelDefinition.cpp +++ b/src/definition/VegetationModelDefinition.cpp @@ -158,9 +158,10 @@ void VegetationModelDefinition::randomize() for (int i = 0; i < 50; i++) { double radius = 0.15; + double scale = randomizeValue(radius, 0.5, 1.0); Vector3 dir = Vector3::randomInSphere(1.0 - radius); 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); } } diff --git a/src/render/software/VegetationModelRenderer.cpp b/src/render/software/VegetationModelRenderer.cpp index 1fe6eb2..8ca8ab3 100644 --- a/src/render/software/VegetationModelRenderer.cpp +++ b/src/render/software/VegetationModelRenderer.cpp @@ -69,11 +69,26 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment, for (const auto &leaf: model->getFoliageItems()) { - Disk sized_leaf(leaf.getPoint(), leaf.getNormal(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius()); - if (sized_leaf.checkRayIntersection(subray, &near) == 1) + Sphere leafcap(leaf.getPoint(), leaf.getRadius() * leaf.getRadius() / foliage.getRadius()); + // 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()); - distance = ray.getCursor(near); + if (capnear.sub(leaf.getPoint()).normalize().dotProduct(leaf.getNormal()) < 0.5) + { + 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) { @@ -89,8 +104,8 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment, nearest = distance; hit = true; - location = near; - normal = sized_leaf.getNormal(); + location = capnear; + normal = capnormal; if (normal.dotProduct(location.sub(segment.getStart())) > 0.0) { @@ -109,9 +124,9 @@ VegetationResult VegetationModelRenderer::getResult(const SpaceSegment &segment, if (hit) { SurfaceMaterial material(result); - material.reflection = 0.003; - material.shininess = 3.0; - material.hardness = 0.3; + material.reflection = 0.001; + material.shininess = 2.0; + material.hardness = 0.1; material.validate(); return VegetationResult(location, normal, material); }