├── embree.go ├── embree_test.go ├── wrapper.cpp └── wrapper.hpp /embree.go: -------------------------------------------------------------------------------- 1 | package embree 2 | 3 | // #cgo CXXFLAGS: -D__forceinline=inline -std=c++11 -O3 4 | // #cgo LDFLAGS: -lembree3 5 | // #include "wrapper.hpp" 6 | import "C" 7 | import "unsafe" 8 | 9 | func init() { 10 | C.init() 11 | } 12 | 13 | type Vector struct { 14 | X, Y, Z float64 15 | } 16 | 17 | type Triangle struct { 18 | A, B, C Vector 19 | } 20 | 21 | type Mesh struct { 22 | Handle unsafe.Pointer 23 | } 24 | 25 | type Ray struct { 26 | Org, Dir Vector 27 | } 28 | 29 | type Hit struct { 30 | T float64 31 | Index int 32 | } 33 | 34 | func NewMesh(triangles []Triangle) *Mesh { 35 | n := len(triangles) 36 | data := make([]C.float, n*3*3) 37 | for i, t := range triangles { 38 | data[i*9+0] = C.float(t.A.X) 39 | data[i*9+1] = C.float(t.A.Y) 40 | data[i*9+2] = C.float(t.A.Z) 41 | data[i*9+3] = C.float(t.B.X) 42 | data[i*9+4] = C.float(t.B.Y) 43 | data[i*9+5] = C.float(t.B.Z) 44 | data[i*9+6] = C.float(t.C.X) 45 | data[i*9+7] = C.float(t.C.Y) 46 | data[i*9+8] = C.float(t.C.Z) 47 | } 48 | return &Mesh{C.createMesh(C.int(n), &data[0])} 49 | } 50 | 51 | func (m *Mesh) Intersect(ray Ray) Hit { 52 | ox := C.float(ray.Org.X) 53 | oy := C.float(ray.Org.Y) 54 | oz := C.float(ray.Org.Z) 55 | dx := C.float(ray.Dir.X) 56 | dy := C.float(ray.Dir.Y) 57 | dz := C.float(ray.Dir.Z) 58 | t := C.float(-1) 59 | index := C.int(-1) 60 | C.intersectMesh(m.Handle, ox, oy, oz, dx, dy, dz, &t, &index) 61 | return Hit{float64(t), int(index)} 62 | } 63 | -------------------------------------------------------------------------------- /embree_test.go: -------------------------------------------------------------------------------- 1 | package embree 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | ) 7 | 8 | func TestIntersect(t *testing.T) { 9 | triangles := []Triangle{ 10 | Triangle{Vector{0, 0, 0}, Vector{1, 0, 0}, Vector{1, 1, 0}}, 11 | } 12 | 13 | mesh := NewMesh(triangles) 14 | 15 | org := Vector{0, 0, -1} 16 | dir := Vector{0, 0, 1} 17 | ray := Ray{org, dir} 18 | 19 | hit := mesh.Intersect(ray) 20 | fmt.Println(hit) 21 | } 22 | -------------------------------------------------------------------------------- /wrapper.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include "wrapper.hpp" 7 | 8 | RTCDevice device; 9 | 10 | struct Vertex { 11 | float x, y, z, a; 12 | }; 13 | 14 | struct Triangle { 15 | int v0, v1, v2; 16 | }; 17 | 18 | // rtcDeleteGeometry(scene, geomID); 19 | // rtcDeleteScene(scene); 20 | // rtcDeleteDevice(device); 21 | 22 | void init() { 23 | _MM_SET_FLUSH_ZERO_MODE(_MM_FLUSH_ZERO_ON); 24 | _MM_SET_DENORMALS_ZERO_MODE(_MM_DENORMALS_ZERO_ON); 25 | 26 | device = rtcNewDevice(NULL); 27 | } 28 | 29 | void *createMesh(int numTriangles, float *data) { 30 | RTCScene scene = rtcNewScene(device); 31 | RTCGeometry geom = rtcNewGeometry(device, RTC_GEOMETRY_TYPE_TRIANGLE); 32 | 33 | Vertex *vertexBuf = (Vertex *)rtcSetNewGeometryBuffer( 34 | geom, RTC_BUFFER_TYPE_VERTEX, 0, RTC_FORMAT_FLOAT3, 35 | sizeof(Vertex), numTriangles * 3); 36 | for (int i = 0; i < numTriangles; i++) { 37 | vertexBuf[i*3+0] = Vertex{data[i*9+0], data[i*9+1], data[i*9+2]}; 38 | vertexBuf[i*3+1] = Vertex{data[i*9+3], data[i*9+4], data[i*9+5]}; 39 | vertexBuf[i*3+2] = Vertex{data[i*9+6], data[i*9+7], data[i*9+8]}; 40 | } 41 | 42 | Triangle *triangleBuf = (Triangle *)rtcSetNewGeometryBuffer( 43 | geom, RTC_BUFFER_TYPE_INDEX, 0, RTC_FORMAT_UINT3, 44 | sizeof(Triangle), numTriangles); 45 | for (int i = 0; i < numTriangles; i++) { 46 | triangleBuf[i] = Triangle{i*3+0, i*3+1, i*3+2}; 47 | } 48 | 49 | rtcCommitGeometry(geom); 50 | rtcAttachGeometry(scene, geom); 51 | rtcReleaseGeometry(geom); 52 | rtcCommitScene(scene); 53 | 54 | return scene; 55 | } 56 | 57 | void intersectMesh(void *mesh, float ox, float oy, float oz, float dx, float dy, float dz, float *t, int *index) { 58 | RTCScene scene = (RTCScene)mesh; 59 | 60 | RTCIntersectContext context; 61 | rtcInitIntersectContext(&context); 62 | 63 | RTCRayHit r; 64 | r.ray.org_x = ox; r.ray.org_y = oy; r.ray.org_z = oz; 65 | r.ray.dir_x = dx; r.ray.dir_y = dy; r.ray.dir_z = dz; 66 | r.ray.tnear = 0; 67 | r.ray.tfar = 1.0 / 0.0; 68 | r.ray.mask = -1; 69 | r.ray.flags = 0; 70 | r.ray.time = 0; 71 | r.ray.id = 0; 72 | 73 | r.hit.geomID = RTC_INVALID_GEOMETRY_ID; 74 | r.hit.primID = RTC_INVALID_GEOMETRY_ID; 75 | 76 | rtcIntersect1(scene, &context, &r); 77 | 78 | *t = r.ray.tfar; 79 | *index = r.hit.primID; 80 | } 81 | -------------------------------------------------------------------------------- /wrapper.hpp: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | void init(); 6 | void *createMesh(int numTriangles, float *data); 7 | void intersectMesh(void *mesh, float ox, float oy, float oz, float dx, float dy, float dz, float *t, int *index); 8 | 9 | #ifdef __cplusplus 10 | } 11 | #endif 12 | --------------------------------------------------------------------------------