/*
* SPDX-FileCopyrightText: Copyright 2022-2023 Julian Amann <dev@vertexwahn.de>
* SPDX-License-Identifier: Apache-2.0
*/
#include "boost/predef.h"
#include "embree4/rtcore.h"
#if BOOST_ARCH_X86_64
#include <pmmintrin.h>
#include <xmmintrin.h> // SIMD Extensions intrinsics
#endif
#include "gmock/gmock.h"
// Many nice tests:
// https://git.hfs.rub.de/garten/blazert/-/tree/2b46b4874e572fefbf0878d61b971caa4190169b/test/test_embree_primitives
// see: https://gist.github.com/jcowles/af59657e884ecd839f37809f7fdf95e4
TEST(Embree, Embree_initialization) {
#if BOOST_ARCH_X86_64
// Setup SIMD Extensions intrinsics
_MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON);
_MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON);
#endif
RTCDevice device = rtcNewDevice("verbose=1");
EXPECT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
// create scene
RTCScene scene = rtcNewScene(device);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
ASSERT_TRUE(scene);
// application vertex and index layout
struct Vertex { float x, y, z; };
struct Triangle { int v0, v1, v2; };
Vertex v[3];
v[0].x = -10; v[0].y = -10; v[0].z = 10;
v[1].x = 10; v[1].y = -10; v[1].z = 10;
v[2].x = 0; v[2].y = 10; v[2].z = 10;
Triangle t[1];
t[0].v0 = 0;
t[0].v1 = 1;
t[0].v2 = 2;
Vertex *vertex_ptr = v;
Triangle *index_ptr = t;
// create triangle mesh
RTCGeometry mesh = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
ASSERT_TRUE(mesh);
// share data buffers
size_t vertex_count = 3;
size_t index_count = 3;
rtcSetSharedGeometryBuffer(mesh,
RTC_BUFFER_TYPE_VERTEX,
0,
RTC_FORMAT_FLOAT3,
vertex_ptr,
0,
sizeof(Vertex),
vertex_count);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
rtcSetSharedGeometryBuffer(mesh,
RTC_BUFFER_TYPE_INDEX,
0,
RTC_FORMAT_UINT3,
index_ptr,
0,
3*sizeof(unsigned int),
index_count/3);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
rtcCommitGeometry(mesh);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
unsigned int geom_id = 42;
rtcAttachGeometryByID(scene, mesh, geom_id);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
rtcReleaseGeometry(mesh);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
rtcCommitScene(scene);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
RTCRayHit rayhit;
rayhit.ray.org_x = 0.f;
rayhit.ray.org_y = 0.f;
rayhit.ray.org_z = 0.f;
rayhit.ray.dir_x = 0.f;
rayhit.ray.dir_y = 0.f;
rayhit.ray.dir_z = 1.f;
rayhit.ray.tnear = 0.f;
rayhit.ray.tfar = std::numeric_limits<float>::infinity();
rayhit.ray.time = 0.f;
rayhit.ray.mask = -1;
rayhit.ray.flags = 0;
rayhit.hit.geomID = RTC_INVALID_GEOMETRY_ID;
rayhit.hit.instID[0] = RTC_INVALID_GEOMETRY_ID;
RTCIntersectArguments args;
rtcInitIntersectArguments(&args);
args.feature_mask = (RTCFeatureFlags) (RTC_FEATURE_FLAG_TRIANGLE);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
rtcIntersect1(scene, &rayhit, &args);
ASSERT_THAT(rtcGetDeviceError(device), RTC_ERROR_NONE);
EXPECT_THAT(rayhit.hit.primID, 0);
EXPECT_THAT(rayhit.hit.geomID, 42);
EXPECT_THAT(rayhit.ray.tfar, testing::FloatNear(10.f, 0.001f));
// release objects
rtcReleaseScene(scene);
rtcReleaseDevice(device);
}
Embree