File: SciVisData.cpp

package info (click to toggle)
ospray 3.2.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 10,048 kB
  • sloc: cpp: 80,569; ansic: 951; sh: 805; makefile: 170; python: 69
file content (115 lines) | stat: -rw-r--r-- 3,242 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
// Copyright 2021 Intel Corporation
// SPDX-License-Identifier: Apache-2.0

#include "SciVisData.h"
#include "common/Instance.h"
#include "common/World.h"
#include "lights/AmbientLight.h"
#include "lights/HDRILight.h"
#include "lights/SunSkyLight.h"
// ispc shared
#include "lights/LightShared.h"

namespace ospray {

namespace {

void addVisibleOnlyToArray(std::vector<ispc::Light *> &lightShs,
    uint32_t &visibleOnly,
    ispc::Light *lightSh)
{
  if (visibleOnly == lightShs.size())
    lightShs.push_back(lightSh);
  else {
    // insert light at the visibleOnly index
    lightShs.push_back(lightShs[visibleOnly]);
    lightShs[visibleOnly] = lightSh;
  }
  visibleOnly++;
}

vec3f addLightsToArray(std::vector<ispc::Light *> &lightShs,
    uint32_t &visibleOnly,
    Ref<const DataT<Light *>> lights,
    const ispc::Instance *instanceSh)
{
  vec3f aoColor = vec3f(0.f);
  for (auto &&light : *lights) {
    // just extract color from ambient lights
    const auto ambient = dynamic_cast<const AmbientLight *>(light);
    if (ambient) {
      addVisibleOnlyToArray(
          lightShs, visibleOnly, light->createSh(0, instanceSh));
      aoColor += ambient->radiance;
      continue;
    }

    // no illumination from HDRI lights
    const auto hdri = dynamic_cast<const HDRILight *>(light);
    if (hdri) {
      addVisibleOnlyToArray(
          lightShs, visibleOnly, light->createSh(0, instanceSh));
      continue;
    }

    // sun-sky: only sun illuminates
    const auto sunsky = dynamic_cast<const SunSkyLight *>(light);
    if (sunsky) {
      addVisibleOnlyToArray(lightShs,
          visibleOnly,
          light->createSh(0, instanceSh)); // sky visible only
      lightShs.push_back(light->createSh(1, instanceSh)); // sun
      continue;
    }

    // handle the remaining types of lights
    for (uint32_t id = 0; id < light->getShCount(); id++)
      lightShs.push_back(light->createSh(id, instanceSh));
  }
  return aoColor;
}

} // namespace

SciVisData::SciVisData(const World &world)
    : AddStructShared(world.getISPCDevice().getDRTDevice())
{
  std::vector<ispc::Light *> lightShs;
  vec3f aoColor = vec3f(0.f);
  uint32_t visibleOnly = 0;

  // Add lights not assigned to any instance
  if (world.lights)
    aoColor += addLightsToArray(lightShs, visibleOnly, world.lights, nullptr);

  // Iterate through all world instances
  if (world.instances) {
    for (auto &&inst : *world.instances) {
      // Skip instances without lights
      if (!inst->group->lights)
        continue;

      // Add instance lights to array
      aoColor += addLightsToArray(
          lightShs, visibleOnly, inst->group->lights, inst->getSh());
    }
  }

  // Then create shared buffer from the temporary std::vector
  lightArray = devicert::make_buffer_shared_unique<ispc::Light *>(
      world.getISPCDevice().getDRTDevice(), lightShs);
  getSh()->lights = lightArray->sharedPtr();
  getSh()->numLights = lightArray->size();
  getSh()->numLightsVisibleOnly = visibleOnly;
  getSh()->aoColorPi = aoColor * float(pi);
}

SciVisData::~SciVisData()
{
  // Delete all lights structures
  devicert::Device &device = lightArray->getDevice();
  for (ispc::Light *lptr : *lightArray)
    device.free(lptr);
}

} // namespace ospray