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
|
// Copyright 2009 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
// ospray
#include "Spheres.h"
#include "common/Data.h"
#ifndef OSPRAY_TARGET_SYCL
// ispc-generated files
#include "geometry/Spheres_ispc.h"
#else
namespace ispc {
void *Spheres_sampleArea_addr();
void *Spheres_getAreas_addr();
} // namespace ispc
#endif
namespace ospray {
static std::map<OSPSphereType, FeatureFlagsGeometry> sphereFeatureFlags = {
{OSP_SPHERE, FFG_SPHERE},
{OSP_DISC, FFG_DISC_POINT},
{OSP_ORIENTED_DISC, FFG_ORIENTED_DISC_POINT}};
Spheres::Spheres(api::ISPCDevice &device)
: AddStructShared(device.getDRTDevice(), device, FFG_NONE)
{
#ifndef OSPRAY_TARGET_SYCL
getSh()->super.postIntersect =
reinterpret_cast<ispc::Geometry_postIntersectFct>(
ispc::Spheres_postIntersect_addr());
#endif
getSh()->super.getAreas = reinterpret_cast<ispc::Geometry_GetAreasFct>(
ispc::Spheres_getAreas_addr());
// We also set the sampleArea function ptr so that
// Geometry::supportAreaLighting will be true, but in SYCL we'll never call it
// through the function pointer on the device
getSh()->super.sampleArea = reinterpret_cast<ispc::Geometry_SampleAreaFct>(
ispc::Spheres_sampleArea_addr());
}
std::string Spheres::toString() const
{
return "ospray::Spheres";
}
void Spheres::commit()
{
sphereType = (OSPSphereType)getParam<uint32_t>("type", OSP_SPHERE);
radius = getParam<float>("radius", 0.01f);
vertexData = getParamDataT<vec3f>("sphere.position", true);
radiusData = getParamDataT<float>("sphere.radius");
texcoordData = getParamDataT<vec2f>("sphere.texcoord");
normalData = nullptr;
if (sphereType == OSP_ORIENTED_DISC) {
normalData = getParamDataT<vec3f>("sphere.normal", true);
}
// If the application's data is already interleaved and they just passed us
// separate views into the interleaved data to make the sphere.position and
// sphere.radius arrays we can detect this and use the interleaved array
// directly to avoid copying it. If not, we need to make a new interleaved
// data array for Embree
if (radiusData && vertexData
&& reinterpret_cast<uint8_t *>(vertexData->data()) + sizeof(vec3f)
== reinterpret_cast<uint8_t *>(radiusData->data())
&& vertexData->stride() == radiusData->stride()) {
auto interleaved = new Data(getISPCDevice(),
vertexData->data(),
OSP_VEC4F,
vertexData->numItems,
vec3l(sizeof(vec4f), 0, 0));
sphereData = &interleaved->as<vec4f, 1>();
interleaved->refDec();
} else {
// To maintain OSPRay 2.x compatibility we need to create the interleaved
// position/radius array that Embree expects from the separate
// position/radius (or global radius) that the OSPRay geometry takes
auto interleaved =
new Data(getISPCDevice(), OSP_VEC4F, vertexData->numItems);
sphereData = &interleaved->as<vec4f, 1>();
interleaved->refDec();
// For now default to always create the interleaved buffer since we
// don't expose the interleaved data yet
for (size_t i = 0; i < vertexData->size(); ++i) {
float ptRadius = radius;
if (radiusData) {
ptRadius = (*radiusData)[i];
}
interleaved->as<vec4f, 1>()[i] = vec4f((*vertexData)[i], ptRadius);
}
}
createEmbreeGeometry((RTCGeometryType)sphereType);
featureFlagsGeometry = sphereFeatureFlags[sphereType];
setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_VERTEX, sphereData);
setEmbreeGeometryBuffer(embreeGeometry, RTC_BUFFER_TYPE_NORMAL, normalData);
rtcCommitGeometry(embreeGeometry);
getSh()->sphere = *ispc(sphereData);
getSh()->texcoord = *ispc(texcoordData);
getSh()->super.numPrimitives = numPrimitives();
getSh()->normalData = *ispc(normalData);
getSh()->sphereType = sphereType;
postCreationInfo(numPrimitives());
}
size_t Spheres::numPrimitives() const
{
return sphereData ? sphereData->size() : 0;
}
} // namespace ospray
|