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 116 117 118 119 120 121
|
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// ospray
#include "GeometricModel.h"
#include "render/Material.h"
namespace ospray {
GeometricModel::GeometricModel(api::ISPCDevice &device, Geometry *_geometry)
: AddStructShared(device.getDRTDevice(), device), geomAPI(_geometry)
{
managedObjectType = OSP_GEOMETRIC_MODEL;
}
std::string GeometricModel::toString() const
{
return "ospray::GeometricModel";
}
void GeometricModel::commit()
{
geom = getParamObject<Geometry>("geometry", geomAPI.ptr);
if (!geom)
throw std::runtime_error(toString() + " received NULL 'geometry'");
materialData = getParamDataT<Material *>("material", false, true);
materialArray = nullptr;
materialIDArray = nullptr;
getSh()->material = nullptr;
getSh()->materialID = nullptr;
getSh()->numMaterials = 0;
featureFlagsOther = FFO_NONE;
if (materialData) {
for (auto &&mat : materialData->as<Material *>())
featureFlagsOther |= mat->getFeatureFlags().other;
materialArray = devicert::make_buffer_shared_unique<ispc::Material *>(
getISPCDevice().getDRTDevice(),
createArrayOfSh<ispc::Material>(materialData->as<Material *>()));
getSh()->material = materialArray->sharedPtr();
getSh()->numMaterials = materialArray->size();
} else {
materialData = getParamDataT<uint32_t>("material", false, true);
if (materialData) {
materialIDArray = devicert::make_buffer_shared_unique<uint32_t>(
getISPCDevice().getDRTDevice(),
materialData->as<uint32_t>().data(),
materialData->size());
getSh()->materialID = materialIDArray->sharedPtr();
getSh()->numMaterials = materialIDArray->size();
}
}
colorData = getParamDataT<vec4f>("color", false, true);
indexData = getParamDataT<uint8_t>("index");
size_t maxItems = geom->numPrimitives();
if (indexData && indexData->size() < maxItems) {
postStatusMsg(OSP_LOG_INFO)
<< toString()
<< " not enough 'index' elements for 'geometry', clamping";
}
if (indexData)
maxItems = 256; // conservative, should actually go over the index
if (materialData && materialData->size() > 1
&& materialData->size() < maxItems) {
postStatusMsg(OSP_LOG_INFO)
<< toString()
<< " potentially not enough 'material' elements for "
"'geometry', clamping";
}
if (colorData && colorData->size() > 1 && colorData->size() < maxItems) {
postStatusMsg(OSP_LOG_INFO)
<< toString()
<< " potentially not enough 'color' elements for 'geometry', clamping";
}
getSh()->geom = geom->getSh();
getSh()->color = *ispc(colorData);
getSh()->index = *ispc(indexData);
getSh()->invertedNormals = getParam<bool>("invertNormals", false);
getSh()->userID = getParam<uint32>("id", RTC_INVALID_GEOMETRY_ID);
}
bool GeometricModel::hasEmissiveMaterials(
Ref<const DataT<Material *>> rendererMaterials) const
{
// No materials used - nothing to check
if (!materialData)
return false;
// Check geometry model materials
bool hasEmissive = false;
if (materialArray) {
for (auto &&mat : materialData->as<Material *>())
if (mat->isEmissive()) {
hasEmissive = true;
break;
}
}
// Check renderer materials referenced from geometry model
else if (materialIDArray) {
for (auto matIdx : materialData->as<uint32_t>())
if ((matIdx < rendererMaterials->size())
&& ((*rendererMaterials)[matIdx]->isEmissive())) {
hasEmissive = true;
break;
}
}
// Done
return hasEmissive;
}
OSPTYPEFOR_DEFINITION(GeometricModel *);
} // namespace ospray
|