1 // Copyright 2009-2021 Intel Corporation
2 // SPDX-License-Identifier: Apache-2.0
3 
4 // ospray
5 #include "SciVis.h"
6 #include "lights/AmbientLight.h"
7 #include "lights/HDRILight.h"
8 #include "lights/SunSkyLight.h"
9 // ispc exports
10 #include "common/World_ispc.h"
11 #include "render/scivis/SciVis_ispc.h"
12 
13 namespace ospray {
14 
15 namespace {
16 
addVisibleOnlyToArray(std::vector<void * > & lightIEs,uint32_t & visibleOnly,void * lightIE)17 void addVisibleOnlyToArray(
18     std::vector<void *> &lightIEs, uint32_t &visibleOnly, void *lightIE)
19 {
20   if (visibleOnly == lightIEs.size())
21     lightIEs.push_back(lightIE);
22   else {
23     lightIEs.push_back(lightIEs[visibleOnly]);
24     lightIEs[visibleOnly] = lightIE;
25   }
26   visibleOnly++;
27 }
28 
addLightsToArray(std::vector<void * > & lightIEs,uint32_t & visibleOnly,Ref<const DataT<Light * >> & lights,const void * instanceIE)29 vec3f addLightsToArray(std::vector<void *> &lightIEs,
30     uint32_t &visibleOnly,
31     Ref<const DataT<Light *>> &lights,
32     const void *instanceIE)
33 {
34   vec3f aoColor = vec3f(0.f);
35   for (auto &&light : *lights) {
36     // create ISPC equivalent for the light
37     void *lightIE = light->createIE(instanceIE);
38 
39     // just extract color from ambient lights
40     const auto ambient = dynamic_cast<const AmbientLight *>(light);
41     if (ambient) {
42       addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE);
43       aoColor += ambient->radiance;
44       continue;
45     }
46 
47     // no illumination from HDRI lights
48     const auto hdri = dynamic_cast<const HDRILight *>(light);
49     if (hdri) {
50       addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE);
51       continue;
52     }
53 
54     // sun-sky: only sun illuminates
55     const auto sunsky = dynamic_cast<const SunSkyLight *>(light);
56     if (sunsky) {
57       // just sky visible
58       addVisibleOnlyToArray(lightIEs, visibleOnly, lightIE);
59       lightIEs.push_back(light->createSecondIE(instanceIE)); // sun
60       continue;
61     }
62 
63     // handle the remaining types of lights
64     lightIEs.push_back(lightIE);
65   }
66   return aoColor;
67 }
68 
69 } // namespace
70 
SciVis()71 SciVis::SciVis()
72 {
73   ispcEquivalent = ispc::SciVis_create();
74 }
75 
toString() const76 std::string SciVis::toString() const
77 {
78   return "ospray::render::SciVis";
79 }
80 
commit()81 void SciVis::commit()
82 {
83   Renderer::commit();
84 
85   ispc::SciVis_set(getIE(),
86       getParam<bool>("shadows", false),
87       getParam<bool>("visibleLights", false),
88       getParam<int>("aoSamples", 0),
89       getParam<float>("aoDistance", getParam<float>("aoRadius", 1e20f)),
90       getParam<float>("volumeSamplingRate", 1.f));
91 }
92 
beginFrame(FrameBuffer *,World * world)93 void *SciVis::beginFrame(FrameBuffer *, World *world)
94 {
95   if (!world)
96     return nullptr;
97 
98   if (world->scivisDataValid)
99     return nullptr;
100 
101   std::vector<void *> lightArray;
102   vec3f aoColor = vec3f(0.f);
103   uint32_t visibleOnly = 0;
104 
105   // Add lights not assigned to any instance
106   if (world->lights)
107     aoColor +=
108         addLightsToArray(lightArray, visibleOnly, world->lights, nullptr);
109 
110   // Iterate through all world instances
111   if (world->instances) {
112     for (auto &&inst : *world->instances) {
113       // Skip instances without lights
114       if (!inst->group->lights)
115         continue;
116 
117       // Add instance lights to array
118       aoColor += addLightsToArray(
119           lightArray, visibleOnly, inst->group->lights, inst->getIE());
120     }
121   }
122 
123   ispc::World_setSciVisData(world->getIE(),
124       (ispc::vec3f &)aoColor,
125       lightArray.empty() ? nullptr : lightArray.data(),
126       lightArray.size(),
127       visibleOnly);
128 
129   world->scivisDataValid = true;
130   return nullptr;
131 }
132 
133 } // namespace ospray
134