diff --git a/CMake/Common.cmake b/CMake/Common.cmake index 65561eb2..ac75bcb4 100644 --- a/CMake/Common.cmake +++ b/CMake/Common.cmake @@ -19,15 +19,28 @@ endif (USE_DOUBLE_PRECISION) cmake_dependent_option(USE_AVX "Use AVX" ON "NOT USE_DOUBLE_PRECISION" OFF) if (USE_AVX) - include(avx) - set_avx_flags() - if (FOUND_AVX2) - message(STATUS "Using AVX2") + set(FOUND_ACCELERATE OFF) + if (APPLE) + find_library(ACCELERATE Accelerate) + endif() + if (ACCELERATE) + set(FOUND_ACCELERATE ON) + message(STATUS "Using Accelerate") + link_libraries(${ACCELERATE}) + else() + include(avx) + set_avx_flags() + if (FOUND_AVX2) + message(STATUS "Using AVX2") + endif() + endif() + if (FOUND_ACCELERATE OR FOUND_AVX2) + set(FOUND_SIMD ON) add_definitions(-DUSE_AVX) endif() endif() -cmake_dependent_option(USE_PERFORMANCE_OPTIMIZATION "Optimize performance (higher memory consumption)" ON "FOUND_AVX2" OFF) +cmake_dependent_option(USE_PERFORMANCE_OPTIMIZATION "Optimize performance (higher memory consumption)" ON "FOUND_SIMD" OFF) if (USE_PERFORMANCE_OPTIMIZATION) add_definitions( -DUSE_PERFORMANCE_OPTIMIZATION) endif (USE_PERFORMANCE_OPTIMIZATION) @@ -64,8 +77,12 @@ option(USE_OpenMP "Use OpenMP" ON) if(USE_OpenMP) FIND_PACKAGE(OpenMP) if(OPENMP_FOUND) - SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") - SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + if (CMAKE_VERSION VERSION_GREATER "3.8") + link_libraries(OpenMP::OpenMP_CXX) + else() + SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}") + SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}") + endif() endif() endif() @@ -86,6 +103,9 @@ if (UNIX OR MINGW) if (CI_BUILD) set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=x86-64") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -DNDEBUG -march=x86-64") + elseif (CMAKE_SYSTEM_PROCESSOR STREQUAL "arm64") + set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -mcpu=native") + set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -DNDEBUG -mcpu=native") else() set(CMAKE_CXX_FLAGS_RELEASE "-O3 -DNDEBUG -march=native") set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -DNDEBUG -march=native") @@ -101,6 +121,7 @@ endif(MINGW) if(APPLE) set(CMAKE_MACOSX_RPATH 1) + add_definitions(-DGL_SILENCE_DEPRECATION) endif() if (MSVC) diff --git a/CMake/NeighborhoodSearch.cmake b/CMake/NeighborhoodSearch.cmake index de87929c..c59b6a0f 100644 --- a/CMake/NeighborhoodSearch.cmake +++ b/CMake/NeighborhoodSearch.cmake @@ -32,8 +32,8 @@ else(USE_GPU_NEIGHBORHOOD_SEARCH) ExternalProject_Add( Ext_NeighborhoodSearch PREFIX "${CMAKE_BINARY_DIR}/extern/CompactNSearch" - GIT_REPOSITORY https://github.com/InteractiveComputerGraphics/CompactNSearch.git - GIT_TAG "3f11ece16a419fc1cc5795d6aa87cb7fe6b86960" + GIT_REPOSITORY https://github.com/ruberith/CompactNSearch.git + GIT_TAG "847c2c22fad4fdae9b99d62d21646db79ff88ef2" INSTALL_DIR ${ExternalInstallDir}/NeighborhoodSearch CMAKE_ARGS -DCMAKE_BUILD_TYPE=${EXT_CMAKE_BUILD_TYPE} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} -DCMAKE_CXX_FLAGS_RELEASE=${CMAKE_CXX_FLAGS_RELEASE} -DCMAKE_INSTALL_PREFIX:PATH=${ExternalInstallDir}/NeighborhoodSearch -DUSE_DOUBLE_PRECISION:BOOL=${USE_DOUBLE_PRECISION} -DBUILD_DEMO:BOOL=OFF ) diff --git a/CMake/SetUpExternalProjects.cmake b/CMake/SetUpExternalProjects.cmake index 6a98a022..9c6ae484 100644 --- a/CMake/SetUpExternalProjects.cmake +++ b/CMake/SetUpExternalProjects.cmake @@ -14,7 +14,7 @@ ExternalProject_Add( Ext_Discregrid PREFIX "${CMAKE_BINARY_DIR}/extern/Discregrid" GIT_REPOSITORY https://github.com/InteractiveComputerGraphics/Discregrid.git - GIT_TAG "0b69062ff9c56fbb6dcecd296652028bedbacf0e" + GIT_TAG "4c27e1cc88be828c6ac5b8a05759ac7e01cf79e9" INSTALL_DIR ${ExternalInstallDir}/Discregrid CMAKE_ARGS -DCMAKE_BUILD_TYPE:STRING=${EXT_CMAKE_BUILD_TYPE} -DCMAKE_INSTALL_PREFIX:PATH=${ExternalInstallDir}/Discregrid -DBUILD_CMD_EXECUTABLE:BOOL=0 -DEIGEN3_INCLUDE_DIR:PATH=${EIGEN3_INCLUDE_DIR} -DCMAKE_CXX_FLAGS=${CMAKE_CXX_FLAGS} ) diff --git a/CMakeLists.txt b/CMakeLists.txt index e978d745..8247f4eb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -40,6 +40,9 @@ endif() ## Eigen3 is used by most of the libraries that follow find_package(Eigen3 REQUIRED) add_definitions(-DEIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT) +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -idirafter${EIGEN3_INCLUDE_DIR}") +endif() ################################################################################ # own external libraries diff --git a/GUI/OpenGL/MiniGL.cpp b/GUI/OpenGL/MiniGL.cpp index 61cf6904..f65cf23f 100644 --- a/GUI/OpenGL/MiniGL.cpp +++ b/GUI/OpenGL/MiniGL.cpp @@ -13,10 +13,8 @@ #ifdef __APPLE__ #include -#include #else #include "GL/gl.h" -#include "GL/glu.h" #endif #define _USE_MATH_DEFINES @@ -36,6 +34,9 @@ MiniGL::DestroyFct MiniGL::destroyfunc = nullptr; void (*MiniGL::exitfunc)(void) = NULL; int MiniGL::m_width = 0; int MiniGL::m_height = 0; +int MiniGL::m_windowWidth = 0; +int MiniGL::m_windowHeight = 0; +Real MiniGL::m_devicePixelRatio = 1.0; Quaternionr MiniGL::m_rotation; Real MiniGL::m_zoom = 1.0; Vector3r MiniGL::m_translation; @@ -62,7 +63,6 @@ GLint MiniGL::m_context_minor_version = 0; GLint MiniGL::m_context_profile = 0; bool MiniGL::m_breakPointActive = true; bool MiniGL::m_breakPointLoop = false; -GLUquadricObj* MiniGL::m_sphereQuadric = nullptr; std::vector MiniGL::m_reshapeFct; std::vector MiniGL::m_keyboardFct; std::vector MiniGL::m_charFct; @@ -72,6 +72,20 @@ std::vector MiniGL::m_mouseWheelFct; GLFWwindow* MiniGL::m_glfw_window = nullptr; bool MiniGL::m_vsync = false; double MiniGL::m_lastTime; +Shader MiniGL::m_shader; +Shader MiniGL::m_shader_screen; +Matrix4r MiniGL::m_modelview_matrix; +Matrix4r MiniGL::m_projection_matrix; +Vector3f MiniGL::m_ambientIntensity; +unsigned int MiniGL::m_numLights = 0; +VectorXf MiniGL::m_diffuseIntensity; +VectorXf MiniGL::m_specularIntensity; +VectorXf MiniGL::m_lightPosition; +GLuint MiniGL::m_vao = 0; +GLuint MiniGL::m_vbo_vertices = 0; +GLuint MiniGL::m_vbo_normals = 0; +GLuint MiniGL::m_vbo_texcoords = 0; +GLuint MiniGL::m_vbo_faces = 0; void MiniGL::bindTexture() { @@ -91,143 +105,164 @@ void MiniGL::getOpenGLVersion(int &major_version, int &minor_version) void MiniGL::coordinateSystem() { - Vector3f a(0,0,0); - Vector3f b(2,0,0); - Vector3f c(0,2,0); - Vector3f d(0,0,2); - - float diffcolor [4] = {1,0,0,1}; - float speccolor [4] = {1,1,1,1}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glLineWidth (2); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&b[0]); - glEnd (); - - float diffcolor2[4] = { 0, 1, 0, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor2); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor2); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&c[0]); - glEnd (); - - float diffcolor3[4] = { 0, 0, 1, 1 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, diffcolor3); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, diffcolor3); - - glBegin (GL_LINES); - glVertex3fv (&a[0]); - glVertex3fv (&d[0]); - glEnd (); - glLineWidth (1); + Vector3r a(0,0,0); + Vector3r b(2,0,0); + Vector3r c(0,2,0); + Vector3r d(0,0,2); + float lineWidth = 3.0; + Vector3f color; + + color << 1,0,0; + drawVector(a, b, lineWidth, &color(0)); + color << 0,1,0; + drawVector(a, c, lineWidth, &color(0)); + color << 0,0,1; + drawVector(a, d, lineWidth, &color(0)); } void MiniGL::drawVector(const Vector3r &a, const Vector3r &b, const float w, float *color) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); + float thickness = 0.005f * w; - glLineWidth (w); + // Draw a thick line as a cylinder with constant color. + drawCylinder(a, b, color, thickness, 32, false); +} - glBegin (GL_LINES); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glEnd (); - - glLineWidth (1); -} - -void MiniGL::drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius, const unsigned int subdivisions) -{ - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - Real vx = (b.x() - a.x()); - Real vy = (b.y() - a.y()); - Real vz = (b.z() - a.z()); - //handle the degenerate case with an approximation - if (vz == 0) - vz = .00000001; - Real v = sqrt(vx*vx + vy*vy + vz*vz); - Real ax = static_cast(57.2957795)*acos(vz / v); - if (vz < 0.0) - ax = -ax; - Real rx = -vy*vz; - Real ry = vx*vz; - - GLUquadricObj *quadric = gluNewQuadric(); - gluQuadricNormals(quadric, GLU_SMOOTH); - - glPushMatrix(); - glTranslatef((float)a.x(), (float)a.y(), (float)a.z()); - glRotatef((float)ax, (float)rx, (float)ry, 0.0f); - //draw the cylinder - gluCylinder(quadric, radius, radius, v, subdivisions, 1); - gluQuadricOrientation(quadric, GLU_INSIDE); - //draw the first cap - gluDisk(quadric, 0.0, radius, subdivisions, 1); - glTranslatef(0, 0, (float)v); - //draw the second cap - gluQuadricOrientation(quadric, GLU_OUTSIDE); - gluDisk(quadric, 0.0, radius, subdivisions, 1); - glPopMatrix(); - - gluDeleteQuadric(quadric); +void MiniGL::drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius, const unsigned int subdivisions, const bool lighting) +{ + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + // To simplify computations, the cylinder of height v is generated + // along the z axis from z=0 to z=v and then transformed to the axis ab. + Vector3r ab = b - a; + Real v = ab.norm(); + Eigen::Transform transform = + Eigen::Translation(a) * + Quaternionr::FromTwoVectors(Vector3r(0.0, 0.0, v), ab); + Vector3r xMid = transform * Vector3r(0.0, 0.0, 0.5 * v); + + // Both the lateral surface and the base disks are subdivided into n slices (cf. gluCylinder & gluDisk). + // For this purpose, the base circle is parametrized as a function of the angle theta. + // The lateral slices are again subdivided into two triangles each for rendering. + // Smooth normals are obtained by going outward from the midpoint. + unsigned int n = subdivisions; + VectorXr vertices((n+1) * 2 * 3); + VectorXr normals((n+1) * 2 * 3); + std::vector faces; + unsigned int iMidBottom = 2 * n; + unsigned int iMidTop = 2 * n + 1; + for (unsigned int i = 0; i < n; i++) + { + Real theta = (Real)i / (Real)n * 2.0 * M_PI; + Vector3r x(radius * cos(theta), radius * sin(theta), 0.0); + Vector3r xBottom = transform * x; + x(2) = v; + Vector3r xTop = transform * x; + vertices.segment<3>(2 * 3 * i) = xBottom; + vertices.segment<3>(2 * 3 * i + 3) = xTop; + normals.segment<3>(2 * 3 * i) = (xBottom - xMid).normalized(); + normals.segment<3>(2 * 3 * i + 3) = (xTop - xMid).normalized(); + + // [TESSELLATION] + // iMidTop + // / \ + // iTop ---- iNextTop + // | \ | + // | \ | + // iBottom - iNextBottom + // \ / + // iMidBottom + unsigned int iBottom = 2 * i; + unsigned int iTop = 2 * i + 1; + unsigned int iNextBottom = (2 * (i+1)) % (2 * n); + unsigned int iNextTop = (2 * (i+1) + 1) % (2 * n); + faces.insert(faces.end(), {iTop, iNextTop, iMidTop}); + faces.insert(faces.end(), {iBottom, iNextBottom, iTop}); + faces.insert(faces.end(), {iTop, iNextBottom, iNextTop}); + faces.insert(faces.end(), {iBottom, iMidBottom, iNextBottom}); + } + Vector3r xMidBottom = transform * Vector3r(0.0, 0.0, 0.0); + Vector3r xMidTop = transform * Vector3r(0.0, 0.0, v); + vertices.segment<3>(3 * iMidBottom) = xMidBottom; + vertices.segment<3>(3 * iMidTop) = xMidTop; + normals.segment<3>(3 * iMidBottom) = (xMidBottom - xMid).normalized(); + normals.segment<3>(3 * iMidTop) = (xMidTop - xMid).normalized(); + + enableShader(diffcolor, diffcolor, speccolor, 100.0); + if (!lighting) glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (n+1) * 2, &vertices(0)); + supplyNormals(1, (n+1) * 2, &normals(0)); + supplyFaces(faces.size(), &faces[0]); + glDrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + disableShader(); } void MiniGL::drawSphere(const Vector3r &translation, float radius, float *color, const unsigned int subDivision) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - if (m_sphereQuadric == nullptr) + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + // The surface of the sphere is subdivided into n slices and stacks (cf. gluSphere). + // For this purpose, it is parametrized as a function of the longitude theta and the colatitude phi. + // The slices and stacks are again subdivided into two triangles each for rendering. + // Smooth normals are obtained by going outward from the midpoint. + unsigned int n = subDivision; + VectorXr vertices((n+1) * n * 3); + VectorXr normals((n+1) * n * 3); + std::vector faces; + for (unsigned int i = 0; i <= n; i++) { - m_sphereQuadric = gluNewQuadric(); - gluQuadricNormals(m_sphereQuadric, GLU_SMOOTH); - } + Real phi = (Real)i / (Real)n * M_PI; + Real xy = radius * sin(phi); + Vector3r x(xy, xy, radius * cos(phi)); + for (unsigned int j = 0; j < n; j++) + { + Real theta = (Real)j / (Real)n * 2.0 * M_PI; + x(0) = xy * cos(theta); + x(1) = xy * sin(theta); + vertices.segment<3>(n * 3 * i + 3 * j) = x + translation; + normals.segment<3>(n * 3 * i + 3 * j) = x.normalized(); - glPushMatrix (); - glTranslated ((translation)[0], (translation)[1], (translation)[2]); + if (i < n) + { + // [TESSELATION] + // iTop ---- iNextTop + // | \ | + // | \ | + // iBottom - iNextBottom + unsigned int iBottom = n * i + j; + unsigned int iTop = n * (i+1) + j; + unsigned int iNextBottom = n * i + ((j+1) % n); + unsigned int iNextTop = n * (i+1) + ((j+1) % n); + faces.insert(faces.end(), {iBottom, iNextBottom, iTop}); + faces.insert(faces.end(), {iTop, iNextBottom, iNextTop}); + } + } + } - gluSphere(m_sphereQuadric, radius, subDivision, subDivision); - glPopMatrix(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + supplyVertices(0, (n+1) * n, &vertices(0)); + supplyNormals(1, (n+1) * n, &normals(0)); + supplyFaces(faces.size(), &faces[0]); + glDrawElements(GL_TRIANGLES, faces.size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + disableShader(); } void MiniGL::drawPoint(const Vector3r &translation, const float pointSize, const float * const color) { - float speccolor [4] = {1.0, 1.0, 1.0, 1.0}; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(color); - - glPointSize(pointSize); - - glBegin (GL_POINTS); - glVertex3v(&translation[0]); - glEnd (); - - glPointSize(1); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); + + enableShader(diffcolor, diffcolor, speccolor, 100.0, pointSize); + supplyVertices(0, 1, &translation(0)); + glDrawArrays(GL_POINTS, 0, 1); + glDisableVertexAttribArray(0); + disableShader(); } @@ -239,119 +274,57 @@ void MiniGL::drawMesh(const TriangleMesh &mesh, const float * const color) const Vector3r *vertices = mesh.getVertices().data(); const Vector3r *vertexNormals = mesh.getVertexNormals().data(); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &mesh.getVertices()[0]); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); - glColor3fv(color); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_REAL, 0, &vertices[0][0]); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } + supplyVertices(0, mesh.getVertices().size(), &vertices[0][0]); + supplyNormals(2, mesh.getVertexNormals().size(), &vertexNormals[0][0]); + supplyFaces(3 * nFaces, faces); - glDrawElements(GL_TRIANGLES, (GLsizei)3 * mesh.numFaces(), GL_UNSIGNED_INT, mesh.getFaces().data()); + glDrawElements(GL_TRIANGLES, 3 * nFaces, GL_UNSIGNED_INT, (void*)0); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); } void MiniGL::drawMesh(const std::vector &vertices, const std::vector &faces, const std::vector &vertexNormals, const float * const color) { // draw mesh - if (MiniGL::checkOpenGLVersion(3, 3)) + supplyVertices(0, vertices.size(), &vertices[0][0]); + if (vertexNormals.size() > 0) { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &vertices[0][0]); - if (vertexNormals.size() > 0) - { - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); - glColor3fv(color); - - glEnableClientState(GL_VERTEX_ARRAY); - glVertexPointer(3, GL_REAL, 0, &vertices[0][0]); - if (vertexNormals.size() > 0) - { - glEnableClientState(GL_NORMAL_ARRAY); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } + supplyNormals(2, vertexNormals.size(), &vertexNormals[0][0]); } + supplyFaces(faces.size(), faces.data()); - glDrawElements(GL_TRIANGLES, (GLsizei) faces.size(), GL_UNSIGNED_INT, faces.data()); + glDrawElements(GL_TRIANGLES, (GLsizei) faces.size(), GL_UNSIGNED_INT, (void*)0); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - } + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); } void MiniGL::drawQuad(const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, const Vector3r &norm, float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - - glBegin (GL_QUADS); - glNormal3v(&norm[0]); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glVertex3v(&c[0]); - glVertex3v(&d[0]); - glEnd (); + // The quad is subdivided into two triangles for rendering. + drawTriangle(a, b, c, norm, color); + drawTriangle(a, c, d, norm, color); } void MiniGL::drawTriangle (const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &norm, float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv (GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv (GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + VectorXr triangle(3 * 3); + triangle << a, b, c; + + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); - glBegin (GL_TRIANGLES); - glNormal3v(&norm[0]); - glVertex3v(&a[0]); - glVertex3v(&b[0]); - glVertex3v(&c[0]); - glEnd (); + glVertexAttrib3rv(1, &norm(0)); + + enableShader(diffcolor, diffcolor, speccolor, 100.0); + supplyVertices(0, 3, &triangle(0)); + glDrawArrays(GL_TRIANGLES, 0, 3); + glDisableVertexAttribArray(0); + disableShader(); + + glVertexAttrib3r(1, 0.0, 0.0, 1.0); } void MiniGL::drawTetrahedron(const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, float *color) @@ -368,60 +341,62 @@ void MiniGL::drawTetrahedron(const Vector3r &a, const Vector3r &b, const Vector3 void MiniGL::drawGrid_xz(float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); const int size = 5; - glBegin(GL_LINES); + VectorXr grid((2*size + 1) * 4 * 3); for (int i = -size; i <= size; i++) { - glVertex3f((float) i, 0.0f, (float) -size); - glVertex3f((float) i, 0.0f, (float) size); - glVertex3f((float) -size, 0.0f, (float) i); - glVertex3f((float) size, 0.0f, (float) i); + grid.segment<12>((i+size) * 12) << (float) i, 0.0f, (float) -size, + (float) i, 0.0f, (float) size, + (float) -size, 0.0f, (float) i, + (float) size, 0.0f, (float) i; } - glEnd(); - - glLineWidth(3.0f); - glBegin(GL_LINES); - glVertex3f((float)-size, 0.0f, 0.0f); - glVertex3f((float)size, 0.0f, 0.0f); - glVertex3f(0.0f, 0.0f, (float) -size); - glVertex3f(0.0f, 0.0f, (float) size); - glEnd(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (2*size + 1) * 4, &grid(0)); + glDrawArrays(GL_LINES, 0, (2*size + 1) * 4); + glDisableVertexAttribArray(0); + disableShader(); + + float lineWidth = 3.0; + + drawVector(Vector3r(-size, 0.0, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(2.0, 0.0, 0.0), Vector3r(size, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 0.0, -size), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 0.0, 2.0), Vector3r(0.0, 0.0, size), lineWidth, color); } void MiniGL::drawGrid_xy(float *color) { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); + Vector3f diffcolor(color); + Vector3f speccolor(1.0, 1.0, 1.0); const int size = 5; - glBegin(GL_LINES); + VectorXr grid((2*size + 1) * 4 * 3); for (int i = -size; i <= size; i++) { - glVertex3f((float)i, (float)-size, 0.0f ); - glVertex3f((float)i, (float)size, 0.0f); - glVertex3f((float)-size, (float)i, 0.0f); - glVertex3f((float)size, (float)i, 0.0f); + grid.segment<12>((i+size) * 12) << (float)i, (float)-size, 0.0f, + (float)i, (float)size, 0.0f, + (float)-size, (float)i, 0.0f, + (float)size, (float)i, 0.0f; } - glEnd(); - - glLineWidth(3.0f); - glBegin(GL_LINES); - glVertex3f((float)-size, 0.0f, 0.0f); - glVertex3f((float)size, 0.0f, 0.0f); - glVertex3f(0.0f, (float)-size, 0.0f); - glVertex3f(0.0f, (float)size, 0.0f); - glEnd(); + enableShader(diffcolor, diffcolor, speccolor, 100.0); + glUniform1i(m_shader.getUniform("lighting"), GL_FALSE); + supplyVertices(0, (2*size + 1) * 4, &grid(0)); + glDrawArrays(GL_LINES, 0, (2*size + 1) * 4); + glDisableVertexAttribArray(0); + disableShader(); + + float lineWidth = 3.0; + + drawVector(Vector3r(-size, 0.0, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(2.0, 0.0, 0.0), Vector3r(size, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, -size, 0.0), Vector3r(0.0, 0.0, 0.0), lineWidth, color); + drawVector(Vector3r(0.0, 2.0, 0.0), Vector3r(0.0, size, 0.0), lineWidth, color); } void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r &peyepoint, const Vector3r &plookat) @@ -430,13 +405,20 @@ void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r znear = pznear; zfar = pzfar; - glLoadIdentity (); - gluLookAt (peyepoint [0], peyepoint [1], peyepoint [2], plookat[0], plookat[1], plookat[2], 0, 1, 0); - - Matrix4r transformation; - Real *lookAtMatrix = transformation.data(); - glGetRealv(GL_MODELVIEW_MATRIX, &lookAtMatrix[0]); + // Compute the lookAt modelview matrix (cf. gluLookAt). + Vector3r f = (plookat - peyepoint).normalized(); + Vector3r up(0.0, 1.0, 0.0); + Vector3r s = f.cross(up); + Vector3r u = s.normalized().cross(f); + m_modelview_matrix.setIdentity(); + m_modelview_matrix.block<1,3>(0,0) = s; + m_modelview_matrix.block<1,3>(1,0) = u; + m_modelview_matrix.block<1,3>(2,0) = -f; + m_modelview_matrix(0,3) = -s.dot(peyepoint); + m_modelview_matrix(1,3) = -u.dot(peyepoint); + m_modelview_matrix(2,3) = f.dot(peyepoint); + const Matrix4r& transformation = m_modelview_matrix; Matrix3r rot; Vector3r scale; @@ -454,8 +436,6 @@ void MiniGL::setViewport(float pfovy, float pznear, float pzfar, const Vector3r m_zoom = scale[0]; m_rotation = Quaternionr(rot); - - glLoadIdentity (); } void MiniGL::setViewport(float pfovy, float pznear, float pzfar) @@ -487,16 +467,18 @@ void MiniGL::init(const int width, const int height, const char *name, const boo if (!glfwInit()) exit(EXIT_FAILURE); - //glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); - //glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); - //glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); + glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); + glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE); + glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); + glfwWindowHint(GLFW_SAMPLES, 4); if (maximized) glfwWindowHint(GLFW_MAXIMIZED, GLFW_TRUE); if (m_vsync) glfwWindowHint(GLFW_DOUBLEBUFFER, GL_TRUE); - else + else glfwWindowHint(GLFW_DOUBLEBUFFER, GL_FALSE); m_glfw_window = glfwCreateWindow(width, height, name, NULL, NULL); if (!m_glfw_window) @@ -519,9 +501,8 @@ void MiniGL::init(const int width, const int height, const char *name, const boo LOG_INFO << "Renderer: " << glGetString(GL_RENDERER); LOG_INFO << "Version: " << glGetString(GL_VERSION); + glEnable(GL_MULTISAMPLE); glEnable (GL_DEPTH_TEST); - glEnable (GL_NORMALIZE); - glShadeModel (GL_SMOOTH); glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); @@ -535,6 +516,15 @@ void MiniGL::init(const int width, const int height, const char *name, const boo glPolygonMode (GL_FRONT_AND_BACK, GL_FILL); + glGenVertexArrays(1, &m_vao); + glBindVertexArray(m_vao); + glGenBuffers(1, &m_vbo_vertices); + glGenBuffers(1, &m_vbo_normals); + glGenBuffers(1, &m_vbo_texcoords); + glGenBuffers(1, &m_vbo_faces); + // Set the default normal (cf. glNormal). + glVertexAttrib3r(1, 0.0, 0.0, 1.0); + m_lastTime = glfwGetTime(); } @@ -559,18 +549,13 @@ void MiniGL::initTexture() glGenTextures(1, &m_texId); glBindTexture(GL_TEXTURE_2D, m_texId); - glTexImage2D(GL_TEXTURE_2D, 0, 3, IMAGE_COLS, IMAGE_ROWS, 0, GL_RGB, + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, IMAGE_COLS, IMAGE_ROWS, 0, GL_RGB, GL_UNSIGNED_BYTE, texData); // Create texture from image data glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glEnable(GL_TEXTURE_2D); // Enable 2D texture - - // Correct texture distortion in perpective projection - glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); - glBindTexture(GL_TEXTURE_2D, 0); } @@ -589,7 +574,11 @@ void MiniGL::setSelectionFunc(void(*func) (const Vector2i&, const Vector2i&, voi void MiniGL::destroy () { - gluDeleteQuadric(m_sphereQuadric); + glDeleteBuffers(1, &m_vbo_vertices); + glDeleteBuffers(1, &m_vbo_normals); + glDeleteBuffers(1, &m_vbo_texcoords); + glDeleteBuffers(1, &m_vbo_faces); + glDeleteVertexArrays(1, &m_vao); } void MiniGL::reshape (GLFWwindow* glfw_window, int w, int h) @@ -686,77 +675,165 @@ void MiniGL::char_callback(GLFWwindow* window, unsigned int codepoint) } void MiniGL::setProjectionMatrix (int width, int height) -{ - glMatrixMode(GL_PROJECTION); - glLoadIdentity(); - gluPerspective(fovy, (Real)width / (Real)height, znear, zfar); +{ + // Compute the perspective projection matrix (cf. gluPerspective). + Real aspect = (Real)width / (Real)height; + Real fovy_rad = fovy * M_PI / 180.0; + Real f = cos(0.5 * fovy_rad) / sin(0.5 * fovy_rad); + m_projection_matrix.setZero(); + m_projection_matrix(0,0) = f / aspect; + m_projection_matrix(1,1) = f; + m_projection_matrix(2,2) = (zfar + znear) / (znear - zfar); + m_projection_matrix(2,3) = 2.0 * zfar * znear / (znear - zfar); + m_projection_matrix(3,2) = -1.0; } void MiniGL::viewport () { glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - glRenderMode (GL_RENDER); glfwGetFramebufferSize(m_glfw_window, &m_width, &m_height); + getWindowSize(m_windowWidth, m_windowHeight); + m_devicePixelRatio = static_cast(m_width) / static_cast(m_windowWidth); glViewport (0, 0, m_width, m_height); - glMatrixMode (GL_PROJECTION); - glLoadIdentity (); setProjectionMatrix (m_width, m_height); - glMatrixMode (GL_MODELVIEW); - glTranslatef((float)m_translation[0], (float)m_translation[1], (float)m_translation[2]); Matrix3r rot; rot = m_rotation.toRotationMatrix(); - Matrix4r transform(Matrix4r::Identity()); + Matrix4r& transform = m_modelview_matrix; + transform.setIdentity(); Vector3r scale(m_zoom, m_zoom, m_zoom); transform.block<3,3>(0,0) = rot; transform.block<3,1>(0,3) = m_translation; transform(0,0) *= scale[0]; transform(1,1) *= scale[1]; transform(2,2) *= scale[2]; - Real *transformMatrix = transform.data(); - glLoadMatrix(&transformMatrix[0]); } void MiniGL::initLights () { - float t = 0.9f; - float a = 0.2f; - float amb0 [4] = {a,a,a,1}; - float diff0 [4] = {t,0,0,1}; - float spec0 [4] = {1,1,1,1}; - float pos0 [4] = {-10,10,10,1}; - glLightfv(GL_LIGHT0, GL_AMBIENT, amb0); - glLightfv(GL_LIGHT0, GL_DIFFUSE, diff0); - glLightfv(GL_LIGHT0, GL_SPECULAR, spec0); - glLightfv(GL_LIGHT0, GL_POSITION, pos0); - glEnable(GL_LIGHT0); - - float amb1 [4] = {a,a,a,1}; - float diff1 [4] = {0,0,t,1}; - float spec1 [4] = {1,1,1,1}; - float pos1 [4] = {10,10,10,1}; - glLightfv(GL_LIGHT1, GL_AMBIENT, amb1); - glLightfv(GL_LIGHT1, GL_DIFFUSE, diff1); - glLightfv(GL_LIGHT1, GL_SPECULAR, spec1); - glLightfv(GL_LIGHT1, GL_POSITION, pos1); - glEnable(GL_LIGHT1); - - float amb2 [4] = {a,a,a,1}; - float diff2 [4] = {0,t,0,1}; - float spec2 [4] = {1,1,1,1}; - float pos2 [4] = {0,10,10,1}; - glLightfv(GL_LIGHT2, GL_AMBIENT, amb2); - glLightfv(GL_LIGHT2, GL_DIFFUSE, diff2); - glLightfv(GL_LIGHT2, GL_SPECULAR, spec2); - glLightfv(GL_LIGHT2, GL_POSITION, pos2); - glEnable(GL_LIGHT2); - - - glEnable(GL_LIGHTING); - glLightModelf(GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE); - glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, GL_FALSE); + m_ambientIntensity << 0.2f, 0.2f, 0.2f; + + m_numLights = 3; + m_diffuseIntensity.resize(m_numLights * 3); + m_specularIntensity.resize(m_numLights * 3); + m_lightPosition.resize(m_numLights * 3); + + m_diffuseIntensity.segment<3>(0) << 0.9f, 0.0f, 0.0f; + m_specularIntensity.segment<3>(0) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(0) << -10.0f, 10.0f, 10.0f; + + m_diffuseIntensity.segment<3>(1 * 3) << 0.0f, 0.0f, 0.9f; + m_specularIntensity.segment<3>(1 * 3) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(1 * 3) << 10.0f, 10.0f, 10.0f; + + m_diffuseIntensity.segment<3>(2 * 3) << 0.0f, 0.9f, 0.0f; + m_specularIntensity.segment<3>(2 * 3) << 1.0f, 1.0f, 1.0f; + m_lightPosition.segment<3>(2 * 3) << 0.0f, 10.0f, 10.0f; +} + +void MiniGL::initShaders(const std::string& shaderPath) +{ + Shader& shader = m_shader; + shader.compileShaderFile(GL_VERTEX_SHADER, shaderPath + "/mini.vert"); + shader.compileShaderFile(GL_FRAGMENT_SHADER, shaderPath + "/mini.frag"); + shader.createAndLinkProgram(); + shader.begin(); + shader.addUniform("modelview_matrix"); + shader.addUniform("projection_matrix"); + shader.addUniform("pointSize"); + shader.addUniform("lighting"); + shader.addUniform("ambientIntensity"); + shader.addUniform("diffuseIntensity"); + shader.addUniform("specularIntensity"); + shader.addUniform("lightPosition"); + shader.addUniform("ambientReflectance"); + shader.addUniform("diffuseReflectance"); + shader.addUniform("specularReflectance"); + shader.addUniform("shininess"); + shader.end(); + + Shader& screenShader = m_shader_screen; + screenShader.compileShaderFile(GL_VERTEX_SHADER, shaderPath + "/mini_screen.vert"); + screenShader.compileShaderFile(GL_FRAGMENT_SHADER, shaderPath + "/mini_screen.frag"); + screenShader.createAndLinkProgram(); + screenShader.begin(); + screenShader.addUniform("width"); + screenShader.addUniform("height"); + screenShader.addUniform("color"); + screenShader.end(); +} + +void MiniGL::destroyShaders() +{ + m_shader.destroy(); + m_shader_screen.destroy(); +} + +void MiniGL::enableShader(const Vector3f& ambientReflectance, const Vector3f& diffuseReflectance, const Vector3f& specularReflectance, const float shininess, const float pointSize) +{ + Shader& shader = m_shader; + shader.begin(); + const Matrix4f modelview_matrix(m_modelview_matrix.cast()); + glUniformMatrix4fv(shader.getUniform("modelview_matrix"), 1, GL_FALSE, &modelview_matrix(0,0)); + const Matrix4f projection_matrix(m_projection_matrix.cast()); + glUniformMatrix4fv(shader.getUniform("projection_matrix"), 1, GL_FALSE, &projection_matrix(0,0)); + glUniform1f(shader.getUniform("pointSize"), pointSize); + glUniform1i(shader.getUniform("lighting"), GL_TRUE); + glUniform3fv(shader.getUniform("ambientIntensity"), 1, &m_ambientIntensity(0)); + glUniform3fv(shader.getUniform("diffuseIntensity"), m_numLights, &m_diffuseIntensity(0)); + glUniform3fv(shader.getUniform("specularIntensity"), m_numLights, &m_specularIntensity(0)); + glUniform3fv(shader.getUniform("lightPosition"), m_numLights, &m_lightPosition(0)); + glUniform3fv(shader.getUniform("ambientReflectance"), 1, &ambientReflectance(0)); + glUniform3fv(shader.getUniform("diffuseReflectance"), 1, &diffuseReflectance(0)); + glUniform3fv(shader.getUniform("specularReflectance"), 1, &specularReflectance(0)); + glUniform1f(shader.getUniform("shininess"), shininess); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_PROGRAM_POINT_SIZE); +} + +void MiniGL::disableShader() +{ + Shader& shader = m_shader; + shader.end(); +} + +void MiniGL::enableScreenShader(const Vector3f& color) +{ + Shader& shader = m_shader_screen; + shader.begin(); + glUniform1f(shader.getUniform("width"), static_cast(m_windowWidth)); + glUniform1f(shader.getUniform("height"), static_cast(m_windowHeight)); + glUniform3fv(shader.getUniform("color"), 1, &color(0)); +} +void MiniGL::disableScreenShader() +{ + Shader& shader = m_shader_screen; + shader.end(); +} + +void MiniGL::supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const float* data) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, n * dim * sizeof(float), data, GL_STREAM_DRAW); + glVertexAttribPointer(index, dim, GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(index); +} + +void MiniGL::supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const double* data) +{ + glBindBuffer(GL_ARRAY_BUFFER, vbo); + glBufferData(GL_ARRAY_BUFFER, n * dim * sizeof(double), data, GL_STREAM_DRAW); + glVertexAttribPointer(index, dim, GL_DOUBLE, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(index); +} + +void MiniGL::supplyIndices(GLuint vbo, unsigned int n, const unsigned int* data) +{ + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, n * sizeof(unsigned int), data, GL_STREAM_DRAW); } void MiniGL::move(Real x, Real y, Real z) @@ -885,16 +962,34 @@ void MiniGL::mouseMove (GLFWwindow* window, double x, double y) void MiniGL::unproject(const int x, const int y, Vector3r &pos) { GLint viewport[4]; - GLdouble mv[16], pm[16]; glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mv); - glGetDoublev(GL_PROJECTION_MATRIX, pm); - GLdouble resx, resy, resz; - gluUnProject(x, viewport[3] - y, znear, mv, pm, viewport, &resx, &resy, &resz); - pos[0] = (Real) resx; - pos[1] = (Real) resy; - pos[2] = (Real) resz; + unproject( + Vector3r( + static_cast(x) * m_devicePixelRatio, + static_cast(viewport[3]) - static_cast(y) * m_devicePixelRatio, + static_cast(znear) + ), + pos + ); +} + +void MiniGL::unproject(const Vector3r& win, Vector3r& pos) +{ + GLint viewport[4]; + glGetIntegerv(GL_VIEWPORT, viewport); + + // Map the specified window coordinates to object coordinates (cf. gluUnProject). + Vector4r ndc; + ndc(0) = static_cast(2.0) * (win(0) - static_cast(viewport[0])) / static_cast(viewport[2]) - static_cast(1.0); + ndc(1) = static_cast(2.0) * (win(1) - static_cast(viewport[1])) / static_cast(viewport[3]) - static_cast(1.0); + ndc(2) = static_cast(2.0) * win(2) - static_cast(1.0); + ndc(3) = static_cast(1.0); + Vector4r obj = (m_projection_matrix * m_modelview_matrix).inverse() * ndc; + if (obj(3) == static_cast(0.0)) obj.setZero(); + else obj /= obj(3); + + pos = obj.segment<3>(0); } float MiniGL::getZNear() @@ -936,20 +1031,16 @@ bool MiniGL::checkOpenGLVersion(const int major_version, const int minor_version Shader *MiniGL::createShader(const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader) { - if (checkOpenGLVersion(3,3)) - { - Shader *shader = new Shader(); - - if (vertexShader != "") - shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); - if (geometryShader != "") - shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); - if (fragmentShader != "") - shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); - shader->createAndLinkProgram(); - return shader; - } - return NULL; + Shader *shader = new Shader(); + + if (vertexShader != "") + shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); + if (geometryShader != "") + shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); + if (fragmentShader != "") + shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); + shader->createAndLinkProgram(); + return shader; } void MiniGL::setBreakPointActive(const bool active) { @@ -968,25 +1059,17 @@ void MiniGL::error_callback(int error, const char* description) void MiniGL::drawSelectionRect() { - glDisable(GL_LIGHTING); - glPushMatrix(); - glLoadIdentity(); - glMatrixMode(GL_PROJECTION); - glPushMatrix(); - glLoadIdentity(); - glOrtho(0.0f, m_width, m_height, 0.0f, -1.0f, 1.0f); - glBegin(GL_LINE_LOOP); - glColor3f(1, 0, 0); //Set the colour to red - glVertex2f(static_cast(m_selectionStart[0]), static_cast(m_selectionStart[1])); - glVertex2f(static_cast(m_selectionStart[0]), static_cast(mouse_pos_y_old)); - glVertex2f(mouse_pos_x_old, mouse_pos_y_old); - glVertex2f(mouse_pos_x_old, m_selectionStart[1]); - glEnd(); - glPopMatrix(); - glMatrixMode(GL_MODELVIEW); - - glPopMatrix(); - glEnable(GL_LIGHTING); + Real selectionRect[] = { + static_cast(m_selectionStart[0]), static_cast(m_selectionStart[1]), + static_cast(m_selectionStart[0]), static_cast(mouse_pos_y_old), + static_cast(mouse_pos_x_old), static_cast(mouse_pos_y_old), + static_cast(mouse_pos_x_old), static_cast(m_selectionStart[1]) + }; + enableScreenShader(Vector3f(1, 0, 0)); + supplyVectors(0, m_vbo_vertices, 2, 4, &selectionRect[0]); + glDrawArrays(GL_LINE_LOOP, 0, 4); + glDisableVertexAttribArray(0); + disableScreenShader(); } void MiniGL::mainLoop() @@ -1022,11 +1105,11 @@ void MiniGL::mainLoop() if (destroyfunc != nullptr) destroyfunc(); + destroy(); + glfwDestroyWindow(m_glfw_window); glfwTerminate(); - - destroy(); } void MiniGL::leaveMainLoop() @@ -1071,7 +1154,7 @@ void MiniGL::setWindowMaximized(const bool b) { if (b) glfwRestoreWindow(m_glfw_window); - else + else glfwRestoreWindow(m_glfw_window); } diff --git a/GUI/OpenGL/MiniGL.h b/GUI/OpenGL/MiniGL.h index 6b871371..4806dde2 100644 --- a/GUI/OpenGL/MiniGL.h +++ b/GUI/OpenGL/MiniGL.h @@ -7,27 +7,16 @@ #include "SPlisHSPlasH/TriangleMesh.h" #ifdef USE_DOUBLE -#define glNormal3v glNormal3dv -#define glVertex3v glVertex3dv -#define glVertex3 glVertex3d -#define glMultMatrix glMultMatrixd -#define glGetRealv glGetDoublev -#define glLoadMatrix glLoadMatrixd -#define glTranslate glTranslated #define GL_REAL GL_DOUBLE +#define glVertexAttrib3r glVertexAttrib3d +#define glVertexAttrib3rv glVertexAttrib3dv #else -#define glNormal3v glNormal3fv -#define glVertex3v glVertex3fv -#define glVertex3 glVertex3f -#define glMultMatrix glMultMatrixf -#define glGetRealv glGetFloatv -#define glLoadMatrix glLoadMatrixf -#define glTranslate glTranslatef #define GL_REAL GL_FLOAT +#define glVertexAttrib3r glVertexAttrib3f +#define glVertexAttrib3rv glVertexAttrib3fv #endif struct GLFWwindow; -typedef class GLUquadric GLUquadricObj; namespace SPH { @@ -93,6 +82,9 @@ namespace SPH static std::vector m_mouseWheelFct; static int m_width; static int m_height; + static int m_windowWidth; + static int m_windowHeight; + static Real m_devicePixelRatio; static Vector3r m_translation; static Quaternionr m_rotation; static Real m_zoom; @@ -118,10 +110,23 @@ namespace SPH static int m_context_profile; static bool m_breakPointActive; static bool m_breakPointLoop; - static GLUquadricObj* m_sphereQuadric; static GLFWwindow* m_glfw_window; static bool m_vsync; static double m_lastTime; + static Shader m_shader; + static Shader m_shader_screen; + static Matrix4r m_modelview_matrix; + static Matrix4r m_projection_matrix; + static Vector3f m_ambientIntensity; + static unsigned int m_numLights; + static VectorXf m_diffuseIntensity; + static VectorXf m_specularIntensity; + static VectorXf m_lightPosition; + static GLuint m_vao; + static GLuint m_vbo_vertices; + static GLuint m_vbo_normals; + static GLuint m_vbo_texcoords; + static GLuint m_vbo_faces; static void reshape (GLFWwindow* glfw_window, int w, int h); static void keyboard(GLFWwindow* window, int key, int scancode, int action, int mods); @@ -139,7 +144,7 @@ namespace SPH static void drawVector(const Vector3r &a, const Vector3r &b, const float w, float *color); /** Renders a closed cylinder between two points. */ - static void drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius = 0.02, const unsigned int subdivisions = 8); + static void drawCylinder(const Vector3r &a, const Vector3r &b, const float *color, const float radius = 0.02, const unsigned int subdivisions = 8, const bool lighting = true); static void drawSphere(const Vector3r &translation, float radius, float *color, const unsigned int subDivision = 16); static void drawQuad (const Vector3r &a, const Vector3r &b, const Vector3r &c, const Vector3r &d, const Vector3r &norm, float *color); /** Draw a tetrahedron. @@ -174,6 +179,7 @@ namespace SPH static void setSelectionFunc(void(*func) (const Vector2i&, const Vector2i&, void*), void *clientData); static void setMouseMoveFunc(int button, void(*func) (int, int, void*)); static void unproject(const int x, const int y, Vector3r &pos); + static void unproject(const Vector3r& win, Vector3r& pos); static float getZNear(); static float getZFar(); static void hsvToRgb(float h, float s, float v, float *rgb); @@ -199,6 +205,7 @@ namespace SPH static int getWidth() { return m_width; } static int getHeight() { return m_height; } + static Real getDevicePixelRatio() { return m_devicePixelRatio; } static int getDrawMode() { return drawMode; } static void setDrawMode(int val) { drawMode = val; } @@ -217,6 +224,51 @@ namespace SPH static void setWindowSize(int w, int h); static bool getWindowMaximized(); static void setWindowMaximized(const bool b); + + static const Matrix4r& getModelviewMatrix() { return m_modelview_matrix; } + static const Matrix4r& getProjectionMatrix() { return m_projection_matrix; } + + static void initShaders(const std::string& shaderPath); + static void destroyShaders(); + static void enableShader(const Vector3f& ambientReflectance, const Vector3f& diffuseReflectance, const Vector3f& specularReflectance, const float shininess, const float pointSize=1.0); + static void disableShader(); + static void enableScreenShader(const Vector3f& color); + static void disableScreenShader(); + + static const GLuint getVao() { return m_vao; } + static const GLuint getVboVertices() { return m_vbo_vertices; } + static const GLuint getVboNormals() { return m_vbo_normals; } + static const GLuint getVboTexcoords() { return m_vbo_texcoords; } + static const GLuint getVboFaces() { return m_vbo_faces; } + + // Fill a VBO with vector data and map to the VAO attribute at the specified index. + static void supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const float* data); + static void supplyVectors(GLuint index, GLuint vbo, unsigned int dim, unsigned int n, const double* data); + // Fill the dedicated VBO with 3D vertex data and map to the VAO attribute at the specified index. + template + static void supplyVertices(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_vertices, 3, numVectors, data); + } + // Fill the dedicated VBO with 3D normal data and map to the VAO attribute at the specified index. + template + static void supplyNormals(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_normals, 3, numVectors, data); + } + // Fill the dedicated VBO with 2D texcoord data and map to the VAO attribute at the specified index. + template + static void supplyTexcoords(GLuint index, unsigned int numVectors, const T* data) + { + supplyVectors(index, m_vbo_texcoords, 2, numVectors, data); + } + // Fill a VBO with index data. + static void supplyIndices(GLuint vbo, unsigned int n, const unsigned int* data); + // Fill the dedicated VBO with face index data. + static void supplyFaces(unsigned int numIndices, const unsigned int* data) + { + supplyIndices(m_vbo_faces, numIndices, data); + } }; } diff --git a/GUI/OpenGL/Selection.h b/GUI/OpenGL/Selection.h index aa4bb286..c2e86480 100644 --- a/GUI/OpenGL/Selection.h +++ b/GUI/OpenGL/Selection.h @@ -11,10 +11,8 @@ #ifdef __APPLE__ #include -#include #else #include "GL/gl.h" -#include "GL/glu.h" #endif #include @@ -44,34 +42,25 @@ namespace SPH int itop = ip1y > ip2y ? ip1y : ip2y; int ibottom = ip1y < ip2y ? ip1y : ip2y; - float left = (float)ileft; - float right = (float)iright; - float top = (float)itop; - float bottom = (float)ibottom; + float left = (float)ileft * MiniGL::getDevicePixelRatio(); + float right = (float)iright * MiniGL::getDevicePixelRatio(); + float top = (float)itop * MiniGL::getDevicePixelRatio(); + float bottom = (float)ibottom * MiniGL::getDevicePixelRatio(); if (left != right && top != bottom) { GLint viewport[4]; - GLdouble mv[16],pm[16]; glGetIntegerv(GL_VIEWPORT, viewport); - glGetDoublev(GL_MODELVIEW_MATRIX, mv); - glGetDoublev(GL_PROJECTION_MATRIX, pm); - GLdouble resx,resy,resz; float zNear = MiniGL::getZNear(); float zFar = MiniGL::getZFar(); - gluUnProject(left, viewport[3] - top, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector0((Real)resx, (Real)resy, (Real)resz); - gluUnProject(left, viewport[3] - top, zFar , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector1((Real)resx, (Real)resy, (Real)resz); - gluUnProject(left, viewport[3] - bottom, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector2((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - top, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector3((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - bottom, zNear , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector4((Real)resx, (Real)resy, (Real)resz); - gluUnProject(right, viewport[3] - bottom, zFar , mv, pm, viewport, &resx, &resy, &resz); - const Vector3r vector5((Real)resx, (Real)resy, (Real)resz); + Vector3r vector0, vector1, vector2, vector3, vector4, vector5; + MiniGL::unproject(Vector3r(left, viewport[3] - top, zNear), vector0); + MiniGL::unproject(Vector3r(left, viewport[3] - top, zFar), vector1); + MiniGL::unproject(Vector3r(left, viewport[3] - bottom, zNear), vector2); + MiniGL::unproject(Vector3r(right, viewport[3] - top, zNear), vector3); + MiniGL::unproject(Vector3r(right, viewport[3] - bottom, zNear), vector4); + MiniGL::unproject(Vector3r(right, viewport[3] - bottom, zFar), vector5); SelectionPlane plane[4]; plane[0].normal = (vector3-vector0).cross(vector1-vector0); diff --git a/GUI/OpenGL/Shader.cpp b/GUI/OpenGL/Shader.cpp index 32e6cbe0..26b30298 100644 --- a/GUI/OpenGL/Shader.cpp +++ b/GUI/OpenGL/Shader.cpp @@ -17,11 +17,7 @@ Shader::Shader(void) Shader::~Shader(void) { - m_initialized = false; - m_attributes.clear(); - m_uniforms.clear(); - if (m_program) - glDeleteProgram(m_program); + destroy(); } void Shader::compileShaderString(GLenum type, const std::string &source) @@ -85,6 +81,18 @@ void Shader::createAndLinkProgram() glDeleteShader(m_shaders[i]); } +void Shader::destroy() +{ + m_initialized = false; + m_attributes.clear(); + m_uniforms.clear(); + if (m_program) + { + glDeleteProgram(m_program); + m_program = 0; + } +} + void Shader::begin() { if (m_initialized) diff --git a/GUI/OpenGL/Shader.h b/GUI/OpenGL/Shader.h index abcc1fc0..08ccf50c 100644 --- a/GUI/OpenGL/Shader.h +++ b/GUI/OpenGL/Shader.h @@ -16,6 +16,7 @@ namespace SPH void compileShaderString(GLenum whichShader, const std::string &source); void compileShaderFile(GLenum whichShader, const std::string &filename); void createAndLinkProgram(); + void destroy(); void addAttribute(const std::string &attribute); void addUniform(const std::string &uniform); bool isInitialized(); diff --git a/SPlisHSPlasH/Common.h b/SPlisHSPlasH/Common.h index e06110b3..ad5b9042 100644 --- a/SPlisHSPlasH/Common.h +++ b/SPlisHSPlasH/Common.h @@ -37,12 +37,14 @@ using Vector2i = Eigen::Matrix; using Vector3f = Eigen::Matrix; using Vector4f = Eigen::Matrix; using Matrix3f = Eigen::Matrix; +using Matrix4f = Eigen::Matrix; using AlignedBox2r = Eigen::AlignedBox; using AlignedBox3r = Eigen::AlignedBox; using AngleAxisr = Eigen::AngleAxis; using Quaternionr = Eigen::Quaternion; using VectorXr = Eigen::Matrix; using MatrixXr = Eigen::Matrix; +using VectorXf = Eigen::Matrix; #if defined(WIN32) || defined(_WIN32) || defined(WIN64) // Enable memory leak detection diff --git a/SPlisHSPlasH/Utilities/AVX_math.h b/SPlisHSPlasH/Utilities/AVX_math.h index 674fc4ca..240b9532 100644 --- a/SPlisHSPlasH/Utilities/AVX_math.h +++ b/SPlisHSPlasH/Utilities/AVX_math.h @@ -5,7 +5,11 @@ #include #include #include +#ifndef __APPLE__ #include +#else +#include +#endif #include "SPlisHSPlasH/Common.h" @@ -15,58 +19,112 @@ class Scalarf8 { public: +#ifndef __APPLE__ __m256 v; +#else + simd::float8 v; +#endif Scalarf8() {} - Scalarf8(float f) { v = _mm256_set1_ps(f); } + Scalarf8(float f) + { +#ifndef __APPLE__ + v = _mm256_set1_ps(f); +#else + v = f; +#endif + } // Scalarf8(float f0, float f1, float f2, float f3, float f4, float f5, float f6, float f7) { // v = _mm256_setr_ps(f0, f1, f2, f3, f4, f5, f6, f7); // } - Scalarf8(Real f0, Real f1, Real f2, Real f3, Real f4, Real f5, Real f6, Real f7) + Scalarf8(Real f0, Real f1, Real f2, Real f3, Real f4, Real f5, Real f6, Real f7) { +#ifndef __APPLE__ v = _mm256_setr_ps((float)f0, (float)f1, (float)f2, (float)f3, (float)f4, (float)f5, (float)f6, (float)f7); +#else + v = { (float)f0, (float)f1, (float)f2, (float)f3, + (float)f4, (float)f5, (float)f6, (float)f7 }; +#endif } - Scalarf8(float const * p) + Scalarf8(float const * p) { +#ifndef __APPLE__ v = _mm256_loadu_ps(p); +#else + v = *(simd::packed::float8*)p; +#endif } - Scalarf8(__m256 const & x) { +#ifndef __APPLE__ + Scalarf8(__m256 const & x) +#else + Scalarf8(simd::float8 const & x) +#endif + { v = x; } - inline void setZero() { v = _mm256_setzero_ps(); } + inline void setZero() + { +#ifndef __APPLE__ + v = _mm256_setzero_ps(); +#else + v = 0.0f; +#endif + } - Scalarf8 & operator = (__m256 const & x) { +#ifndef __APPLE__ + Scalarf8 & operator = (__m256 const & x) +#else + Scalarf8 & operator = (simd::float8 const & x) +#endif + { v = x; return *this; } - inline Scalarf8 sqrt() const + inline Scalarf8 sqrt() const { +#ifndef __APPLE__ return _mm256_sqrt_ps(v); +#else + return simd::sqrt(v); +#endif } inline Scalarf8 rsqrt() const { +#ifndef __APPLE__ return _mm256_rsqrt_ps(v); +#else + return simd::rsqrt(v); +#endif } Scalarf8 & load(float const * p) { +#ifndef __APPLE__ v = _mm256_loadu_ps(p); +#else + v = *(simd::packed::float8*)p; +#endif return *this; } void store(float * p) const { +#ifndef __APPLE__ _mm256_storeu_ps(p, v); +#else + *(simd::packed::float8*)p = v; +#endif } inline float reduce() const { +#ifndef __APPLE__ /* ( x3+x7, x2+x6, x1+x5, x0+x4 ) */ const __m128 x128 = _mm_add_ps(_mm256_extractf128_ps(v, 1), _mm256_castps256_ps128(v)); /* ( -, -, x1+x3+x5+x7, x0+x2+x4+x6 ) */ @@ -75,92 +133,172 @@ class Scalarf8 const __m128 x32 = _mm_add_ss(x64, _mm_shuffle_ps(x64, x64, 0x55)); /* Conversion to float is a no-op on x86-64 */ return _mm_cvtss_f32(x32); +#else + return simd_reduce_add(v); +#endif } }; inline Scalarf8 operator - (Scalarf8& a) { +#ifndef __APPLE__ return _mm256_sub_ps(_mm256_set1_ps(0.0), a.v); +#else + return -a.v; +#endif } static inline Scalarf8 multiplyAndAdd(const Scalarf8& a, const Scalarf8& b, const Scalarf8& c) { +#ifndef __APPLE__ return _mm256_fmadd_ps(a.v, b.v, c.v); +#else + return simd::fma(a.v, b.v, c.v); +#endif } static inline Scalarf8 multiplyAndSubtract(const Scalarf8& a, const Scalarf8& b, const Scalarf8& c) { +#ifndef __APPLE__ return _mm256_fmsub_ps(a.v, b.v, c.v); +#else + return simd::fma(a.v, b.v, -c.v); +#endif } static inline Scalarf8 operator + (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_add_ps(a.v, b.v); +#else + return a.v + b.v; +#endif } static inline Scalarf8 & operator += (Scalarf8 & a, Scalarf8 const & b) { +#ifndef __APPLE__ a.v = _mm256_add_ps(a.v, b.v); +#else + a.v += b.v; +#endif return a; } static inline Scalarf8 operator - (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_sub_ps(a.v, b.v); +#else + return a.v - b.v; +#endif } static inline Scalarf8 & operator -= (Scalarf8 & a, Scalarf8 const & b) { +#ifndef __APPLE__ a.v = _mm256_sub_ps(a.v, b.v); +#else + a.v -= b.v; +#endif return a; } static inline Scalarf8 operator * (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_mul_ps(a.v, b.v); +#else + return a.v * b.v; +#endif } static inline Scalarf8 & operator *= (Scalarf8 & a, Scalarf8 const & b) { +#ifndef __APPLE__ a.v = _mm256_mul_ps(a.v, b.v); +#else + a.v *= b.v; +#endif return a; } static inline Scalarf8 operator / (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_div_ps(a.v, b.v); +#else + return a.v / b.v; +#endif } static inline Scalarf8 & operator /= (Scalarf8 & a, Scalarf8 const & b) { +#ifndef __APPLE__ a.v = _mm256_div_ps(a.v, b.v); +#else + a.v /= b.v; +#endif return a; } static inline Scalarf8 operator == (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(a.v, b.v, 0); +#else + return simd::convert(a.v == b.v); +#endif } static inline Scalarf8 operator != (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(a.v, b.v, 4); +#else + return simd::convert(a.v != b.v); +#endif } static inline Scalarf8 operator < (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(a.v, b.v, 1); +#else + return simd::convert(a.v < b.v); +#endif } static inline Scalarf8 operator <= (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(a.v, b.v, 2); +#else + return simd::convert(a.v <= b.v); +#endif } static inline Scalarf8 operator > (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(b.v, a.v, 1); +#else + return simd::convert(a.v > b.v); +#endif } static inline Scalarf8 operator >= (Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_cmp_ps(b.v, a.v, 2); +#else + return simd::convert(a.v >= b.v); +#endif } static inline Scalarf8 min(Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_min_ps(a.v, b.v); +#else + return simd::min(a.v, b.v); +#endif } static inline Scalarf8 max(Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_max_ps(a.v, b.v); +#else + return simd::max(a.v, b.v); +#endif } +#ifndef __APPLE__ template static inline __m256 constant8f() { static const union { @@ -169,16 +307,25 @@ static inline __m256 constant8f() { } u = { { i0,i1,i2,i3,i4,i5,i6,i7 } }; return u.ymm; } +#endif static inline Scalarf8 abs(Scalarf8 const & a) { +#ifndef __APPLE__ __m256 mask = constant8f<0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF, 0x7FFFFFFF>(); return _mm256_and_ps(a.v, mask); +#else + return simd::abs(a.v); +#endif } //does the same as for (int i = 0; i < 8; i++) result[i] = c[i] ? a[i] : b[i]; //the elemets in c must be either 0 (false) or 0xFFFFFFFF (true) static inline Scalarf8 blend(Scalarf8 const & c, Scalarf8 const & a, Scalarf8 const & b) { +#ifndef __APPLE__ return _mm256_blendv_ps(b.v, a.v, c.v); +#else + return simd::select(b.v, a.v, simd::convert(c.v)); +#endif } static inline Scalarf8 convert_zero(const unsigned int *idx, const Real *x, const unsigned char count = 8u) @@ -186,6 +333,7 @@ static inline Scalarf8 convert_zero(const unsigned int *idx, const Real *x, cons Scalarf8 v; switch (count) { +#ifndef __APPLE__ case 1u: v.v = _mm256_setr_ps(x[idx[0]], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); break; case 2u: @@ -202,6 +350,24 @@ static inline Scalarf8 convert_zero(const unsigned int *idx, const Real *x, cons v.v = _mm256_setr_ps(x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], 0.0f); break; case 8u: v.v = _mm256_setr_ps(x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], x[idx[7]]); break; +#else + case 1u: + v.v = { x[idx[0]], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 2u: + v.v = { x[idx[0]], x[idx[1]], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 3u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 4u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 5u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], 0.0f, 0.0f, 0.0f }; break; + case 6u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], 0.0f, 0.0f }; break; + case 7u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], 0.0f }; break; + case 8u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], x[idx[7]] }; break; +#endif } return v; } @@ -211,6 +377,7 @@ static inline Scalarf8 convert_zero(const Real x, const unsigned char count = 8u Scalarf8 v; switch (count) { +#ifndef __APPLE__ case 1u: v.v = _mm256_setr_ps(x, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); break; case 2u: @@ -227,6 +394,24 @@ static inline Scalarf8 convert_zero(const Real x, const unsigned char count = 8u v.v = _mm256_setr_ps(x, x, x, x, x, x, x, 0.0f); break; case 8u: v.v = _mm256_setr_ps(x, x, x, x, x, x, x, x); break; +#else + case 1u: + v.v = { x, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 2u: + v.v = { x, x, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 3u: + v.v = { x, x, x, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 4u: + v.v = { x, x, x, x, 0.0f, 0.0f, 0.0f, 0.0f }; break; + case 5u: + v.v = { x, x, x, x, x, 0.0f, 0.0f, 0.0f }; break; + case 6u: + v.v = { x, x, x, x, x, x, 0.0f, 0.0f }; break; + case 7u: + v.v = { x, x, x, x, x, x, x, 0.0f }; break; + case 8u: + v.v = { x, x, x, x, x, x, x, x }; break; +#endif } return v; } @@ -236,6 +421,7 @@ static inline Scalarf8 convert_one(const unsigned int *idx, const Real *x, const Scalarf8 v; switch (count) { +#ifndef __APPLE__ case 1u: v.v = _mm256_setr_ps(x[idx[0]], 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f); break; case 2u: @@ -252,6 +438,24 @@ static inline Scalarf8 convert_one(const unsigned int *idx, const Real *x, const v.v = _mm256_setr_ps(x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], 1.0f); break; case 8u: v.v = _mm256_setr_ps(x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], x[idx[7]]); break; +#else + case 1u: + v.v = { x[idx[0]], 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; break; + case 2u: + v.v = { x[idx[0]], x[idx[1]], 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; break; + case 3u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], 1.0f, 1.0f, 1.0f, 1.0f, 1.0f }; break; + case 4u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], 1.0f, 1.0f, 1.0f, 1.0f }; break; + case 5u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], 1.0f, 1.0f, 1.0f }; break; + case 6u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], 1.0f, 1.0f }; break; + case 7u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], 1.0f }; break; + case 8u: + v.v = { x[idx[0]], x[idx[1]], x[idx[2]], x[idx[3]], x[idx[4]], x[idx[5]], x[idx[6]], x[idx[7]] }; break; +#endif } return v; } @@ -270,9 +474,15 @@ class Vector3f8 Vector3f8(const Scalarf8 &x) { v[0] = v[1] = v[2] = x; } Vector3f8(const Vector3f &x) { +#ifndef __APPLE__ v[0].v = _mm256_set1_ps(x[0]); v[1].v = _mm256_set1_ps(x[1]); v[2].v = _mm256_set1_ps(x[2]); +#else + v[0].v = x[0]; + v[1].v = x[1]; + v[2].v = x[2]; +#endif } Vector3f8(const Vector3f &v0, const Vector3f &v1, const Vector3f &v2, const Vector3f &v3, const Vector3f &v4, const Vector3f &v5, const Vector3f &v6, const Vector3f &v7) { @@ -289,7 +499,13 @@ class Vector3f8 v[0] = vx; v[1] = vy; v[2] = vz; } - inline void setZero() { v[0].v = _mm256_setzero_ps(); v[1].v = _mm256_setzero_ps(); v[2].v = _mm256_setzero_ps(); + inline void setZero() + { +#ifndef __APPLE__ + v[0].v = _mm256_setzero_ps(); v[1].v = _mm256_setzero_ps(); v[2].v = _mm256_setzero_ps(); +#else + v[0].v = 0.0f; v[1].v = 0.0f; v[2].v = 0.0f; +#endif } inline Scalarf8& operator [] (int i) { return v[i]; } @@ -304,17 +520,25 @@ class Vector3f8 inline const Scalarf8& z() const { return v[2]; } inline Scalarf8 dot(const Vector3f8& a) const { - Scalarf8 res; + Scalarf8 res; +#ifndef __APPLE__ //res.v = _mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(v[0].v, a.v[0].v), _mm256_mul_ps(v[1].v, a.v[1].v)), _mm256_mul_ps(v[2].v, a.v[2].v)); res.v = _mm256_fmadd_ps(v[0].v, a.v[0].v, _mm256_fmadd_ps(v[1].v, a.v[1].v, _mm256_mul_ps(v[2].v, a.v[2].v))); +#else + res.v = simd::fma(v[0].v, a.v[0].v, simd::fma(v[1].v, a.v[1].v, v[2].v * a.v[2].v)); +#endif return res; } //dot product inline Scalarf8 operator * (const Vector3f8& a) const { Scalarf8 res; +#ifndef __APPLE__ //res.v = _mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(v[0].v, a.v[0].v), _mm256_mul_ps(v[1].v, a.v[1].v)), _mm256_mul_ps(v[2].v, a.v[2].v)); res.v = _mm256_fmadd_ps(v[0].v, a.v[0].v, _mm256_fmadd_ps(v[1].v, a.v[1].v, _mm256_mul_ps(v[2].v, a.v[2].v))); +#else + res.v = simd::fma(v[0].v, a.v[0].v, simd::fma(v[1].v, a.v[1].v, v[2].v * a.v[2].v)); +#endif return res; } @@ -354,14 +578,22 @@ class Vector3f8 } inline Scalarf8 squaredNorm() const { +#ifndef __APPLE__ //return _mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(v[0].v, v[0].v), _mm256_mul_ps(v[1].v, v[1].v)), _mm256_mul_ps(v[2].v, v[2].v)); return _mm256_fmadd_ps(v[0].v, v[0].v, _mm256_fmadd_ps(v[1].v, v[1].v, _mm256_mul_ps(v[2].v, v[2].v))); +#else + return simd::fma(v[0].v, v[0].v, simd::fma(v[1].v, v[1].v, v[2].v * v[2].v)); +#endif } inline Scalarf8 norm() const { +#ifndef __APPLE__ //return _mm256_sqrt_ps(_mm256_add_ps(_mm256_add_ps(_mm256_mul_ps(v[0].v, v[0].v), _mm256_mul_ps(v[1].v, v[1].v)), _mm256_mul_ps(v[2].v, v[2].v))); return _mm256_sqrt_ps(_mm256_fmadd_ps(v[0].v, v[0].v, _mm256_fmadd_ps(v[1].v, v[1].v, _mm256_mul_ps(v[2].v, v[2].v)))); +#else + return simd::sqrt(simd::fma(v[0].v, v[0].v, simd::fma(v[1].v, v[1].v, v[2].v * v[2].v))); +#endif } inline void normalize() @@ -377,9 +609,15 @@ class Vector3f8 //the elements in c must be either 0 (false) or 0xFFFFFFFF (true) static inline Vector3f8 blend(Scalarf8 const & c, Vector3f8 const & a, Vector3f8 const & b) { Vector3f8 result; +#ifndef __APPLE__ result.x() = _mm256_blendv_ps(b.x().v, a.x().v, c.v); result.y() = _mm256_blendv_ps(b.y().v, a.y().v, c.v); result.z() = _mm256_blendv_ps(b.z().v, a.z().v, c.v); +#else + result.x() = simd::select(b.x().v, a.x().v, simd::convert(c.v)); + result.y() = simd::select(b.y().v, a.y().v, simd::convert(c.v)); + result.z() = simd::select(b.z().v, a.z().v, simd::convert(c.v)); +#endif return result; } @@ -416,39 +654,69 @@ class Vector3f8 inline Vector3f8 operator + (Vector3f8 const& a, Vector3f8 const& b) { Vector3f8 res; +#ifndef __APPLE__ res.v[0].v = _mm256_add_ps(a[0].v, b[0].v); res.v[1].v = _mm256_add_ps(a[1].v, b[1].v); res.v[2].v = _mm256_add_ps(a[2].v, b[2].v); +#else + res.v[0].v = a[0].v + b[0].v; + res.v[1].v = a[1].v + b[1].v; + res.v[2].v = a[2].v + b[2].v; +#endif return res; } inline Vector3f8 operator - (Vector3f8 const& a, Vector3f8 const& b) { Vector3f8 res; +#ifndef __APPLE__ res.v[0].v = _mm256_sub_ps(a[0].v, b[0].v); res.v[1].v = _mm256_sub_ps(a[1].v, b[1].v); res.v[2].v = _mm256_sub_ps(a[2].v, b[2].v); +#else + res.v[0].v = a[0].v - b[0].v; + res.v[1].v = a[1].v - b[1].v; + res.v[2].v = a[2].v - b[2].v; +#endif return res; } inline Vector3f8& operator += (Vector3f8& a, Vector3f8 const& b) { +#ifndef __APPLE__ a[0].v = _mm256_add_ps(a[0].v, b[0].v); a[1].v = _mm256_add_ps(a[1].v, b[1].v); a[2].v = _mm256_add_ps(a[2].v, b[2].v); +#else + a[0].v += b[0].v; + a[1].v += b[1].v; + a[2].v += b[2].v; +#endif return a; } inline Vector3f8& operator -= (Vector3f8& a, Vector3f8 const& b) { +#ifndef __APPLE__ a[0].v = _mm256_sub_ps(a[0].v, b[0].v); a[1].v = _mm256_sub_ps(a[1].v, b[1].v); a[2].v = _mm256_sub_ps(a[2].v, b[2].v); +#else + a[0].v -= b[0].v; + a[1].v -= b[1].v; + a[2].v -= b[2].v; +#endif return a; } inline Vector3f8 operator * (Vector3f8 const& a, const Scalarf8& s) { Vector3f8 res; +#ifndef __APPLE__ res.v[0].v = _mm256_mul_ps(a[0].v, s.v); res.v[1].v = _mm256_mul_ps(a[1].v, s.v); res.v[2].v = _mm256_mul_ps(a[2].v, s.v); +#else + res.v[0].v = a[0].v * s.v; + res.v[1].v = a[1].v * s.v; + res.v[2].v = a[2].v * s.v; +#endif return res; } @@ -457,6 +725,7 @@ inline Vector3f8 convertVec_zero(const unsigned int* idx, const Real* v, const u Vector3f8 x; switch (count) { +#ifndef __APPLE__ case 1u: x.v[0].v = _mm256_setr_ps(v[3*idx[0]+0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); x.v[1].v = _mm256_setr_ps(v[3*idx[0]+1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); @@ -496,6 +765,47 @@ inline Vector3f8 convertVec_zero(const unsigned int* idx, const Real* v, const u x.v[0].v = _mm256_setr_ps(v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], v[3*idx[4]+0], v[3*idx[5]+0], v[3*idx[6]+0], v[3*idx[7]+0]); x.v[1].v = _mm256_setr_ps(v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], v[3*idx[4]+1], v[3*idx[5]+1], v[3*idx[6]+1], v[3*idx[7]+1]); x.v[2].v = _mm256_setr_ps(v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], v[3*idx[4]+2], v[3*idx[5]+2], v[3*idx[6]+2], v[3*idx[7]+2]); +#else + case 1u: + x.v[0].v = { v[3*idx[0]+0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 2u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 3u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 4u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 5u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], v[3*idx[4]+0], 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], v[3*idx[4]+1], 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], v[3*idx[4]+2], 0.0f, 0.0f, 0.0f }; + break; + case 6u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], v[3*idx[4]+0], v[3*idx[5]+0], 0.0f, 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], v[3*idx[4]+1], v[3*idx[5]+1], 0.0f, 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], v[3*idx[4]+2], v[3*idx[5]+2], 0.0f, 0.0f }; + break; + case 7u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], v[3*idx[4]+0], v[3*idx[5]+0], v[3*idx[6]+0], 0.0f }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], v[3*idx[4]+1], v[3*idx[5]+1], v[3*idx[6]+1], 0.0f }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], v[3*idx[4]+2], v[3*idx[5]+2], v[3*idx[6]+2], 0.0f }; + break; + case 8u: + x.v[0].v = { v[3*idx[0]+0], v[3*idx[1]+0], v[3*idx[2]+0], v[3*idx[3]+0], v[3*idx[4]+0], v[3*idx[5]+0], v[3*idx[6]+0], v[3*idx[7]+0] }; + x.v[1].v = { v[3*idx[0]+1], v[3*idx[1]+1], v[3*idx[2]+1], v[3*idx[3]+1], v[3*idx[4]+1], v[3*idx[5]+1], v[3*idx[6]+1], v[3*idx[7]+1] }; + x.v[2].v = { v[3*idx[0]+2], v[3*idx[1]+2], v[3*idx[2]+2], v[3*idx[3]+2], v[3*idx[4]+2], v[3*idx[5]+2], v[3*idx[6]+2], v[3*idx[7]+2] }; +#endif } return x; } @@ -505,6 +815,7 @@ static inline Vector3f8 convertVec_zero(const unsigned int *idx, const Vector3r Vector3f8 x; switch (count) { +#ifndef __APPLE__ case 1u: x.v[0].v = _mm256_setr_ps(v[idx[0]][0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); x.v[1].v = _mm256_setr_ps(v[idx[0]][1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); @@ -544,6 +855,47 @@ static inline Vector3f8 convertVec_zero(const unsigned int *idx, const Vector3r x.v[0].v = _mm256_setr_ps(v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], v[idx[4]][0], v[idx[5]][0], v[idx[6]][0], v[idx[7]][0]); x.v[1].v = _mm256_setr_ps(v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], v[idx[4]][1], v[idx[5]][1], v[idx[6]][1], v[idx[7]][1]); x.v[2].v = _mm256_setr_ps(v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], v[idx[4]][2], v[idx[5]][2], v[idx[6]][2], v[idx[7]][2]); +#else + case 1u: + x.v[0].v = { v[idx[0]][0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 2u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 3u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 4u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], 0.0f, 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 5u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], v[idx[4]][0], 0.0f, 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], v[idx[4]][1], 0.0f, 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], v[idx[4]][2], 0.0f, 0.0f, 0.0f }; + break; + case 6u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], v[idx[4]][0], v[idx[5]][0], 0.0f, 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], v[idx[4]][1], v[idx[5]][1], 0.0f, 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], v[idx[4]][2], v[idx[5]][2], 0.0f, 0.0f }; + break; + case 7u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], v[idx[4]][0], v[idx[5]][0], v[idx[6]][0], 0.0f }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], v[idx[4]][1], v[idx[5]][1], v[idx[6]][1], 0.0f }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], v[idx[4]][2], v[idx[5]][2], v[idx[6]][2], 0.0f }; + break; + case 8u: + x.v[0].v = { v[idx[0]][0], v[idx[1]][0], v[idx[2]][0], v[idx[3]][0], v[idx[4]][0], v[idx[5]][0], v[idx[6]][0], v[idx[7]][0] }; + x.v[1].v = { v[idx[0]][1], v[idx[1]][1], v[idx[2]][1], v[idx[3]][1], v[idx[4]][1], v[idx[5]][1], v[idx[6]][1], v[idx[7]][1] }; + x.v[2].v = { v[idx[0]][2], v[idx[1]][2], v[idx[2]][2], v[idx[3]][2], v[idx[4]][2], v[idx[5]][2], v[idx[6]][2], v[idx[7]][2] }; +#endif } return x; } @@ -592,7 +944,8 @@ class Matrix3f8 } inline void setZero() - { + { +#ifndef __APPLE__ m[0][0].v = _mm256_setzero_ps(); m[1][0].v = _mm256_setzero_ps(); m[2][0].v = _mm256_setzero_ps(); @@ -604,6 +957,19 @@ class Matrix3f8 m[0][2].v = _mm256_setzero_ps(); m[1][2].v = _mm256_setzero_ps(); m[2][2].v = _mm256_setzero_ps(); +#else + m[0][0].v = 0.0f; + m[1][0].v = 0.0f; + m[2][0].v = 0.0f; + + m[0][1].v = 0.0f; + m[1][1].v = 0.0f; + m[2][1].v = 0.0f; + + m[0][2].v = 0.0f; + m[1][2].v = 0.0f; + m[2][2].v = 0.0f; +#endif } inline Scalarf8& operator()(int i, int j) { return m[i][j]; } @@ -734,6 +1100,7 @@ class Matrix3f8 }; inline Matrix3f8& operator -= (Matrix3f8& a, Matrix3f8 const& b) { +#ifndef __APPLE__ a.m[0][0].v = _mm256_sub_ps(a.m[0][0].v, b.m[0][0].v); a.m[0][1].v = _mm256_sub_ps(a.m[0][1].v, b.m[0][1].v); a.m[0][2].v = _mm256_sub_ps(a.m[0][2].v, b.m[0][2].v); @@ -745,6 +1112,19 @@ inline Matrix3f8& operator -= (Matrix3f8& a, Matrix3f8 const& b) { a.m[2][0].v = _mm256_sub_ps(a.m[2][0].v, b.m[2][0].v); a.m[2][1].v = _mm256_sub_ps(a.m[2][1].v, b.m[2][1].v); a.m[2][2].v = _mm256_sub_ps(a.m[2][2].v, b.m[2][2].v); +#else + a.m[0][0].v -= b.m[0][0].v; + a.m[0][1].v -= b.m[0][1].v; + a.m[0][2].v -= b.m[0][2].v; + + a.m[1][0].v -= b.m[1][0].v; + a.m[1][1].v -= b.m[1][1].v; + a.m[1][2].v -= b.m[1][2].v; + + a.m[2][0].v -= b.m[2][0].v; + a.m[2][1].v -= b.m[2][1].v; + a.m[2][2].v -= b.m[2][2].v; +#endif return a; } @@ -754,6 +1134,7 @@ static inline Matrix3f8 convertMat_zero(const unsigned int* idx, const Matrix3r* Matrix3f8 x; switch (count) { +#ifndef __APPLE__ case 1u: x.m[0][0] = _mm256_setr_ps(v[idx[0]](0, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); x.m[0][1] = _mm256_setr_ps(v[idx[0]](0, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f); @@ -841,6 +1222,95 @@ static inline Matrix3f8 convertMat_zero(const unsigned int* idx, const Matrix3r* x.m[2][0] = _mm256_setr_ps(v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), v[idx[4]](2, 0), v[idx[5]](2, 0), v[idx[6]](2, 0), v[idx[7]](2, 0)); x.m[2][1] = _mm256_setr_ps(v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), v[idx[4]](2, 1), v[idx[5]](2, 1), v[idx[6]](2, 1), v[idx[7]](2, 1)); x.m[2][2] = _mm256_setr_ps(v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), v[idx[4]](2, 2), v[idx[5]](2, 2), v[idx[6]](2, 2), v[idx[7]](2, 2)); +#else + case 1u: + x.m[0][0] = { v[idx[0]](0, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 2u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 3u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), 0.0f, 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 4u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), v[idx[3]](0, 0), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), v[idx[3]](0, 1), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), v[idx[3]](0, 2), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), v[idx[3]](1, 0), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), v[idx[3]](1, 1), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), v[idx[3]](1, 2), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), 0.0f, 0.0f, 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), 0.0f, 0.0f, 0.0f, 0.0f }; + break; + case 5u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), v[idx[3]](0, 0), v[idx[4]](0, 0), 0.0f, 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), v[idx[3]](0, 1), v[idx[4]](0, 1), 0.0f, 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), v[idx[3]](0, 2), v[idx[4]](0, 2), 0.0f, 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), v[idx[3]](1, 0), v[idx[4]](1, 0), 0.0f, 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), v[idx[3]](1, 1), v[idx[4]](1, 1), 0.0f, 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), v[idx[3]](1, 2), v[idx[4]](1, 2), 0.0f, 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), v[idx[4]](2, 0), 0.0f, 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), v[idx[4]](2, 1), 0.0f, 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), v[idx[4]](2, 2), 0.0f, 0.0f, 0.0f }; + break; + case 6u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), v[idx[3]](0, 0), v[idx[4]](0, 0), v[idx[5]](0, 0), 0.0f, 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), v[idx[3]](0, 1), v[idx[4]](0, 1), v[idx[5]](0, 1), 0.0f, 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), v[idx[3]](0, 2), v[idx[4]](0, 2), v[idx[5]](0, 2), 0.0f, 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), v[idx[3]](1, 0), v[idx[4]](1, 0), v[idx[5]](1, 0), 0.0f, 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), v[idx[3]](1, 1), v[idx[4]](1, 1), v[idx[5]](1, 1), 0.0f, 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), v[idx[3]](1, 2), v[idx[4]](1, 2), v[idx[5]](1, 2), 0.0f, 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), v[idx[4]](2, 0), v[idx[5]](2, 0), 0.0f, 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), v[idx[4]](2, 1), v[idx[5]](2, 1), 0.0f, 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), v[idx[4]](2, 2), v[idx[5]](2, 2), 0.0f, 0.0f }; + break; + case 7u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), v[idx[3]](0, 0), v[idx[4]](0, 0), v[idx[5]](0, 0), v[idx[6]](0, 0), 0.0f }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), v[idx[3]](0, 1), v[idx[4]](0, 1), v[idx[5]](0, 1), v[idx[6]](0, 1), 0.0f }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), v[idx[3]](0, 2), v[idx[4]](0, 2), v[idx[5]](0, 2), v[idx[6]](0, 2), 0.0f }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), v[idx[3]](1, 0), v[idx[4]](1, 0), v[idx[5]](1, 0), v[idx[6]](1, 0), 0.0f }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), v[idx[3]](1, 1), v[idx[4]](1, 1), v[idx[5]](1, 1), v[idx[6]](1, 1), 0.0f }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), v[idx[3]](1, 2), v[idx[4]](1, 2), v[idx[5]](1, 2), v[idx[6]](1, 2), 0.0f }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), v[idx[4]](2, 0), v[idx[5]](2, 0), v[idx[6]](2, 0), 0.0f }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), v[idx[4]](2, 1), v[idx[5]](2, 1), v[idx[6]](2, 1), 0.0f }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), v[idx[4]](2, 2), v[idx[5]](2, 2), v[idx[6]](2, 2), 0.0f }; + break; + case 8u: + x.m[0][0] = { v[idx[0]](0, 0), v[idx[1]](0, 0), v[idx[2]](0, 0), v[idx[3]](0, 0), v[idx[4]](0, 0), v[idx[5]](0, 0), v[idx[6]](0, 0), v[idx[7]](0, 0) }; + x.m[0][1] = { v[idx[0]](0, 1), v[idx[1]](0, 1), v[idx[2]](0, 1), v[idx[3]](0, 1), v[idx[4]](0, 1), v[idx[5]](0, 1), v[idx[6]](0, 1), v[idx[7]](0, 1) }; + x.m[0][2] = { v[idx[0]](0, 2), v[idx[1]](0, 2), v[idx[2]](0, 2), v[idx[3]](0, 2), v[idx[4]](0, 2), v[idx[5]](0, 2), v[idx[6]](0, 2), v[idx[7]](0, 2) }; + x.m[1][0] = { v[idx[0]](1, 0), v[idx[1]](1, 0), v[idx[2]](1, 0), v[idx[3]](1, 0), v[idx[4]](1, 0), v[idx[5]](1, 0), v[idx[6]](1, 0), v[idx[7]](1, 0) }; + x.m[1][1] = { v[idx[0]](1, 1), v[idx[1]](1, 1), v[idx[2]](1, 1), v[idx[3]](1, 1), v[idx[4]](1, 1), v[idx[5]](1, 1), v[idx[6]](1, 1), v[idx[7]](1, 1) }; + x.m[1][2] = { v[idx[0]](1, 2), v[idx[1]](1, 2), v[idx[2]](1, 2), v[idx[3]](1, 2), v[idx[4]](1, 2), v[idx[5]](1, 2), v[idx[6]](1, 2), v[idx[7]](1, 2) }; + x.m[2][0] = { v[idx[0]](2, 0), v[idx[1]](2, 0), v[idx[2]](2, 0), v[idx[3]](2, 0), v[idx[4]](2, 0), v[idx[5]](2, 0), v[idx[6]](2, 0), v[idx[7]](2, 0) }; + x.m[2][1] = { v[idx[0]](2, 1), v[idx[1]](2, 1), v[idx[2]](2, 1), v[idx[3]](2, 1), v[idx[4]](2, 1), v[idx[5]](2, 1), v[idx[6]](2, 1), v[idx[7]](2, 1) }; + x.m[2][2] = { v[idx[0]](2, 2), v[idx[1]](2, 2), v[idx[2]](2, 2), v[idx[3]](2, 2), v[idx[4]](2, 2), v[idx[5]](2, 2), v[idx[6]](2, 2), v[idx[7]](2, 2) }; +#endif } return x; } @@ -848,9 +1318,15 @@ static inline Matrix3f8 convertMat_zero(const unsigned int* idx, const Matrix3r* inline void dyadicProduct(const Vector3f8 &a, const Vector3f8 &b, Matrix3f8 &res) { +#ifndef __APPLE__ res.m[0][0] = _mm256_mul_ps(a.x().v, b.x().v); res.m[0][1] = _mm256_mul_ps(a.x().v, b.y().v); res.m[0][2] = _mm256_mul_ps(a.x().v, b.z().v); res.m[1][0] = _mm256_mul_ps(a.y().v, b.x().v); res.m[1][1] = _mm256_mul_ps(a.y().v, b.y().v); res.m[1][2] = _mm256_mul_ps(a.y().v, b.z().v); res.m[2][0] = _mm256_mul_ps(a.z().v, b.x().v); res.m[2][1] = _mm256_mul_ps(a.z().v, b.y().v); res.m[2][2] = _mm256_mul_ps(a.z().v, b.z().v); +#else + res.m[0][0] = a.x().v * b.x().v; res.m[0][1] = a.x().v * b.y().v; res.m[0][2] = a.x().v * b.z().v; + res.m[1][0] = a.y().v * b.x().v; res.m[1][1] = a.y().v * b.y().v; res.m[1][2] = a.y().v * b.z().v; + res.m[2][0] = a.z().v * b.x().v; res.m[2][1] = a.z().v * b.y().v; res.m[2][2] = a.z().v * b.z().v; +#endif } // ---------------------------------------------------------------------------------------------- @@ -907,7 +1383,7 @@ class Quaternion8f const Scalarf8 tyz = tz*q[1]; const Scalarf8 tzz = tz*q[2]; - R.m[0][0] = Scalarf8(1.0) - (tyy + tzz); + R.m[0][0] = Scalarf8(1.0) - (tyy + tzz); R.m[0][1] = txy - twz; R.m[0][2] = txz + twy; R.m[1][0] = txy + twz; @@ -1035,7 +1511,7 @@ class AlignmentAllocator { inline pointer allocate(size_type n) { #ifdef _WIN32 return (pointer)_aligned_malloc(n * sizeof(value_type), N); -#elif __linux__ +#elif defined(__linux__) || defined(__APPLE__) // NB! Argument order is opposite from MSVC/Windows return (pointer) aligned_alloc(N, n * sizeof(value_type)); #else @@ -1046,7 +1522,7 @@ class AlignmentAllocator { inline void deallocate(pointer p, size_type) { #ifdef _WIN32 _aligned_free(p); -#elif __linux__ +#elif defined(__linux__) || defined(__APPLE__) free(p); #else #error "Unknown platform" diff --git a/SPlisHSPlasH/Utilities/SDFFunctions.cpp b/SPlisHSPlasH/Utilities/SDFFunctions.cpp index 9f4d5a81..4a4070a6 100644 --- a/SPlisHSPlasH/Utilities/SDFFunctions.cpp +++ b/SPlisHSPlasH/Utilities/SDFFunctions.cpp @@ -66,7 +66,7 @@ Discregrid::CubicLagrangeDiscreteGrid* SDFFunctions::generateSDF(const unsigned Discregrid::TriangleMesh sdfMesh(&doubleVec[0], faces, numVertices, numFaces); #endif - Discregrid::MeshDistance md(sdfMesh); + Discregrid::TriangleMeshDistance md(sdfMesh); Eigen::AlignedBox3d domain; domain.extend(bbox.min().cast()); domain.extend(bbox.max().cast()); @@ -78,7 +78,7 @@ Discregrid::CubicLagrangeDiscreteGrid* SDFFunctions::generateSDF(const unsigned Real factor = 1.0; if (invert) factor = -1.0; - func = [&md,&factor](Eigen::Vector3d const& xi) {return factor * md.signedDistanceCached(xi); }; + func = [&md,&factor](Eigen::Vector3d const& xi) {return factor * md.signed_distance(xi).distance; }; distanceField->addFunction(func, false); STOP_TIMING_PRINT; diff --git a/Simulator/GUI/OpenGL/Simulator_OpenGL.cpp b/Simulator/GUI/OpenGL/Simulator_OpenGL.cpp index 5d920ab4..6765a679 100644 --- a/Simulator/GUI/OpenGL/Simulator_OpenGL.cpp +++ b/Simulator/GUI/OpenGL/Simulator_OpenGL.cpp @@ -33,6 +33,8 @@ Simulator_OpenGL::~Simulator_OpenGL(void) void Simulator_OpenGL::initShaders(const std::string &shaderPath) { + MiniGL::initShaders(shaderPath); + string vertFile = shaderPath + "/vs_points_vector.glsl"; string fragFile = shaderPath + "/fs_points.glsl"; m_shader_vector.compileShaderFile(GL_VERTEX_SHADER, vertFile); @@ -93,6 +95,15 @@ void Simulator_OpenGL::initShaders(const std::string &shaderPath) glGenTextures(1, &m_textureMap); } +void Simulator_OpenGL::destroyShaders() +{ + glDeleteTextures(1, &m_textureMap); + m_shader_vector.destroy(); + m_shader_scalar.destroy(); + m_shader_scalar_map.destroy(); + m_meshShader.destroy(); + MiniGL::destroyShaders(); +} void Simulator_OpenGL::meshShaderBegin(const float *col) { @@ -100,12 +111,10 @@ void Simulator_OpenGL::meshShaderBegin(const float *col) glUniform1f(m_meshShader.getUniform("shininess"), 5.0f); glUniform1f(m_meshShader.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_meshShader.getUniform("surface_color"), 1, col); } @@ -139,18 +148,12 @@ void Simulator_OpenGL::pointShaderBegin(Shader *shader, const Real particleRadiu } - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(shader->getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(shader->getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(shader->getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(shader->getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glEnable(GL_DEPTH_TEST); - // Point sprites do not have to be explicitly enabled since OpenGL 3.2 where - // they are enabled by default. Moreover GL_POINT_SPRITE is deprecate and only - // supported before OpenGL 3.2 or with compatibility profile enabled. - glEnable(GL_POINT_SPRITE); glEnable(GL_PROGRAM_POINT_SIZE); glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); } @@ -172,82 +175,51 @@ void Simulator_OpenGL::renderFluid(FluidModel *model, float *fluidColor, if (nParticles == 0) return; - float surfaceColor[4] = { 0.2f, 0.6f, 0.8f, 1 }; - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, surfaceColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, surfaceColor); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0); - glColor3fv(surfaceColor); - const Real particleRadius = sim->getParticleRadius(); const Real supportRadius = sim->getSupportRadius(); - Real vmax = static_cast(0.4*2.0)*supportRadius / TimeManager::getCurrent()->getTimeStepSize(); - Real vmin = 0.0; - if (MiniGL::checkOpenGLVersion(3, 3)) + Shader *shader_scalar = &m_shader_scalar_map; + float const *color_map = nullptr; + if (colorMapType == 1) + color_map = reinterpret_cast(colormap_jet); + else if (colorMapType == 2) + color_map = reinterpret_cast(colormap_plasma); + else if (colorMapType == 3) + color_map = reinterpret_cast(colormap_coolwarm); + else if (colorMapType == 4) + color_map = reinterpret_cast(colormap_bwr); + else if (colorMapType == 5) + color_map = reinterpret_cast(colormap_seismic); + + if (colorMapType == 0) + shader_scalar = &m_shader_scalar; + + if (!useScalarField) + pointShaderBegin(shader_scalar, particleRadius, &fluidColor[0], renderMinValue, renderMaxValue, false); + else + pointShaderBegin(shader_scalar, particleRadius, &fluidColor[0], renderMinValue, renderMaxValue, true, color_map); + + if (model->numActiveParticles() > 0) { - Shader *shader_scalar = &m_shader_scalar_map; - float const *color_map = nullptr; - if (colorMapType == 1) - color_map = reinterpret_cast(colormap_jet); - else if (colorMapType == 2) - color_map = reinterpret_cast(colormap_plasma); - else if (colorMapType == 3) - color_map = reinterpret_cast(colormap_coolwarm); - else if (colorMapType == 4) - color_map = reinterpret_cast(colormap_bwr); - else if (colorMapType == 5) - color_map = reinterpret_cast(colormap_seismic); - - if (colorMapType == 0) - shader_scalar = &m_shader_scalar; - - if (!useScalarField) - pointShaderBegin(shader_scalar, particleRadius, &fluidColor[0], renderMinValue, renderMaxValue, false); - else - pointShaderBegin(shader_scalar, particleRadius, &fluidColor[0], renderMinValue, renderMaxValue, true, color_map); - - if (model->numActiveParticles() > 0) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &model->getPosition(0)); - - if (useScalarField) - { - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, &scalarField[0]); - } - - glDrawArrays(GL_POINTS, 0, model->numActiveParticles()); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - } + MiniGL::supplyVertices(0, model->numActiveParticles(), &model->getPosition(0)(0)); - if (!useScalarField) - pointShaderEnd(shader_scalar, false); - else - pointShaderEnd(shader_scalar, true); - } - else - { - glPointSize(4.0); - glDisable(GL_LIGHTING); - glBegin(GL_POINTS); - for (unsigned int i = 0; i < nParticles; i++) + if (useScalarField) { - Real v = model->getVelocity(i).norm(); - v = static_cast(0.5)*((v - vmin) / (vmax - vmin)); - v = min(static_cast(128.0)*v*v, static_cast(0.5)); - float fluidColor[4] = { 0.2f, 0.2f, 0.2f, 1.0 }; - MiniGL::hsvToRgb(0.55f, 1.0f, 0.5f + (float)v, fluidColor); - - glColor3fv(fluidColor); - glVertex3v(&model->getPosition(i)[0]); + glBindBuffer(GL_ARRAY_BUFFER, MiniGL::getVboNormals()); + glBufferData(GL_ARRAY_BUFFER, model->numActiveParticles() * sizeof(float), &scalarField[0], GL_STREAM_DRAW); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(1); } - glEnd(); - glEnable(GL_LIGHTING); + + glDrawArrays(GL_POINTS, 0, model->numActiveParticles()); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); } + + if (!useScalarField) + pointShaderEnd(shader_scalar, false); + else + pointShaderEnd(shader_scalar, true); } void Simulator_OpenGL::renderSelectedParticles(FluidModel *model, const std::vector>& selectedParticles, @@ -258,40 +230,20 @@ void Simulator_OpenGL::renderSelectedParticles(FluidModel *model, const std::vec const unsigned int fluidIndex = model->getPointSetIndex(); Simulation *sim = Simulation::getCurrent(); const Real particleRadius = sim->getParticleRadius(); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - if ((selectedParticles.size() > 0) && ((selectedParticles[fluidIndex].size() > 0))) - { - pointShaderBegin(&m_shader_vector, particleRadius, &red[0], renderMinValue, renderMaxValue); - const Real radius = sim->getValue(Simulation::PARTICLE_RADIUS); - glUniform1f(m_shader_vector.getUniform("radius"), (float)radius*1.05f); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &model->getPosition(0)); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_REAL, GL_FALSE, 0, &model->getVelocity(0)); - glDrawElements(GL_POINTS, (GLsizei)selectedParticles[fluidIndex].size(), GL_UNSIGNED_INT, selectedParticles[fluidIndex].data()); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - pointShaderEnd(&m_shader_vector); - } - } - else + + if ((selectedParticles.size() > 0) && ((selectedParticles[fluidIndex].size() > 0))) { - if (selectedParticles.size() > 0) - { - glPointSize(4.0); - glDisable(GL_LIGHTING); - glBegin(GL_POINTS); - for (unsigned int i = 0; i < selectedParticles[fluidIndex].size(); i++) - { - glColor3fv(red); - glVertex3v(&model->getPosition(selectedParticles[fluidIndex][i])[0]); - } - glEnd(); - glEnable(GL_LIGHTING); - } + pointShaderBegin(&m_shader_vector, particleRadius, &red[0], renderMinValue, renderMaxValue); + const Real radius = sim->getValue(Simulation::PARTICLE_RADIUS); + glUniform1f(m_shader_vector.getUniform("radius"), (float)radius*1.05f); + MiniGL::supplyVertices(0, model->numActiveParticles(), &model->getPosition(0)(0)); + MiniGL::supplyNormals(1, model->numActiveParticles(), &model->getVelocity(0)(0)); + MiniGL::supplyFaces(selectedParticles[fluidIndex].size(), selectedParticles[fluidIndex].data()); + glDrawElements(GL_POINTS, (GLsizei)selectedParticles[fluidIndex].size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + pointShaderEnd(&m_shader_vector); } - } void Simulator_OpenGL::renderBoundaryParticles(BoundaryModel_Akinci2012 *model, const float *col, @@ -300,32 +252,13 @@ void Simulator_OpenGL::renderBoundaryParticles(BoundaryModel_Akinci2012 *model, Simulation *sim = Simulation::getCurrent(); const Real particleRadius = sim->getParticleRadius(); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - Simulator_OpenGL::pointShaderBegin(&m_shader_vector, particleRadius, col, renderMinValue, renderMaxValue); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &model->getPosition(0)[0]); - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 3, GL_REAL, GL_FALSE, 0, &model->getVelocity(0)[0]); - glDrawArrays(GL_POINTS, 0, model->numberOfParticles()); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - Simulator_OpenGL::pointShaderEnd(&m_shader_vector); - } - else - { - glDisable(GL_LIGHTING); - glPointSize(4.0f); - - glBegin(GL_POINTS); - for (unsigned int i = 0; i < model->numberOfParticles(); i++) - { - glColor3fv(col); - glVertex3v(&model->getPosition(i)[0]); - } - glEnd(); - glEnable(GL_LIGHTING); - } + Simulator_OpenGL::pointShaderBegin(&m_shader_vector, particleRadius, col, renderMinValue, renderMaxValue); + MiniGL::supplyVertices(0, model->numberOfParticles(), &model->getPosition(0)(0)); + MiniGL::supplyNormals(1, model->numberOfParticles(), &model->getVelocity(0)(0)); + glDrawArrays(GL_POINTS, 0, model->numberOfParticles()); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); + Simulator_OpenGL::pointShaderEnd(&m_shader_vector); } void Simulator_OpenGL::renderBoundary(BoundaryModel *model, const float *col) @@ -334,12 +267,10 @@ void Simulator_OpenGL::renderBoundary(BoundaryModel *model, const float *col) glUniform1f(m_meshShader.getUniform("shininess"), 5.0f); glUniform1f(m_meshShader.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_meshShader.getUniform("surface_color"), 1, col); diff --git a/Simulator/GUI/OpenGL/Simulator_OpenGL.h b/Simulator/GUI/OpenGL/Simulator_OpenGL.h index b01dbfcf..f15f5f29 100644 --- a/Simulator/GUI/OpenGL/Simulator_OpenGL.h +++ b/Simulator/GUI/OpenGL/Simulator_OpenGL.h @@ -25,6 +25,7 @@ namespace SPH virtual ~Simulator_OpenGL(); static void initShaders(const std::string &shaderPath); + static void destroyShaders(); static Shader& getShaderVector() { return m_shader_vector; } static Shader& getShaderScalar() { return m_shader_scalar; } static Shader& getMeshShader() { return m_meshShader; } diff --git a/Simulator/GUI/imgui/Simulator_GUI_imgui.cpp b/Simulator/GUI/imgui/Simulator_GUI_imgui.cpp index 1ee50093..0911541d 100644 --- a/Simulator/GUI/imgui/Simulator_GUI_imgui.cpp +++ b/Simulator/GUI/imgui/Simulator_GUI_imgui.cpp @@ -80,8 +80,7 @@ void Simulator_GUI_imgui::init(const char *name) MiniGL::addKeyFunc(GLFW_KEY_W, GLFW_MOD_CONTROL, std::bind(&SimulatorBase::writeScene, m_simulatorBase)); MiniGL::addKeyFunc(GLFW_KEY_KP_ADD, 0, std::bind(&SimulatorBase::singleTimeStep, m_simulatorBase)); - if (MiniGL::checkOpenGLVersion(3, 3)) - Simulator_OpenGL::initShaders(m_simulatorBase->getExePath() + "/resources/shaders"); + Simulator_OpenGL::initShaders(m_simulatorBase->getExePath() + "/resources/shaders"); const int width = MiniGL::getWidth(); const int height = MiniGL::getHeight(); @@ -597,6 +596,7 @@ void Simulator_GUI_imgui::destroy() ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); + Simulator_OpenGL::destroyShaders(); } void Simulator_GUI_imgui::cleanup() diff --git a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp index 80e6d5d9..7fcdbeb5 100644 --- a/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp +++ b/Simulator/PositionBasedDynamicsWrapper/PBDWrapper.cpp @@ -267,7 +267,7 @@ void PBDWrapper::readScene(const std::string &sceneFileName, const std::vector< doubleVec[3 * i + j] = vd.getPosition(i)[j]; Discregrid::TriangleMesh sdfMesh(&doubleVec[0], faces.data(), vd.size(), nFaces); #endif - Discregrid::MeshDistance md(sdfMesh); + Discregrid::TriangleMeshDistance md(sdfMesh); Eigen::AlignedBox3d domain; for (auto const& x : sdfMesh.vertices()) { @@ -279,7 +279,7 @@ void PBDWrapper::readScene(const std::string &sceneFileName, const std::vector< LOG_INFO << "Set SDF resolution: " << rbd.m_resolutionSDF[0] << ", " << rbd.m_resolutionSDF[1] << ", " << rbd.m_resolutionSDF[2]; distanceFields[sdfFileName] = std::make_shared(domain, std::array({ rbd.m_resolutionSDF[0], rbd.m_resolutionSDF[1], rbd.m_resolutionSDF[2] })); auto func = Discregrid::DiscreteGrid::ContinuousFunction{}; - func = [&md](Eigen::Vector3d const& xi) {return md.signedDistanceCached(xi); }; + func = [&md](Eigen::Vector3d const& xi) {return md.signed_distance(xi).distance; }; LOG_INFO << "Generate SDF for " << rbd.m_modelFile; distanceFields[sdfFileName]->addFunction(func, true); if (Utilities::FileSystem::makeDir(cachePath) == 0) diff --git a/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.cpp b/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.cpp index f57ac73e..61f7871b 100644 --- a/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.cpp +++ b/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.cpp @@ -47,20 +47,16 @@ void PBD_Simulator_GUI_imgui::render() SPH::Shader *PBD_Simulator_GUI_imgui::createShader(const std::string &vertexShader, const std::string &geometryShader, const std::string &fragmentShader) { - if (SPH::MiniGL::checkOpenGLVersion(3, 3)) - { - SPH::Shader *shader = new SPH::Shader(); - - if (vertexShader != "") - shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); - if (geometryShader != "") - shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); - if (fragmentShader != "") - shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); - shader->createAndLinkProgram(); - return shader; - } - return NULL; + SPH::Shader *shader = new SPH::Shader(); + + if (vertexShader != "") + shader->compileShaderFile(GL_VERTEX_SHADER, vertexShader); + if (geometryShader != "") + shader->compileShaderFile(GL_GEOMETRY_SHADER, geometryShader); + if (fragmentShader != "") + shader->compileShaderFile(GL_FRAGMENT_SHADER, fragmentShader); + shader->createAndLinkProgram(); + return shader; } void PBD_Simulator_GUI_imgui::initShader() @@ -91,12 +87,10 @@ void PBD_Simulator_GUI_imgui::shaderBegin(const float *col) glUniform1f(m_shader->getUniform("shininess"), 5.0f); glUniform1f(m_shader->getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_shader->getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_shader->getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(SPH::MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_shader->getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(SPH::MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_shader->getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_shader->getUniform("surface_color"), 1, col); } } @@ -109,15 +103,14 @@ void PBD_Simulator_GUI_imgui::shaderEnd() void PBD_Simulator_GUI_imgui::renderAABB(PBD::AABB &aabb) { + float color[4] = { 0.5f, 0.5f, 0.5f, 0.3f }; + Vector3r p1, p2; - glBegin(GL_LINES); for (unsigned char i = 0; i < 12; i++) { PBD::AABB::getEdge(aabb, i, p1, p2); - glVertex3d(p1[0], p1[1], p1[2]); - glVertex3d(p2[0], p2[1], p2[2]); + SPH::MiniGL::drawVector(p1, p2, 1.0f, color); } - glEnd(); } void PBD_Simulator_GUI_imgui::renderBVH() diff --git a/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.h b/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.h index 2a390d95..0fb98f8e 100644 --- a/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.h +++ b/Simulator/PositionBasedDynamicsWrapper/PBD_Simulator_GUI_imgui.h @@ -72,40 +72,14 @@ namespace SPH const unsigned int nFaces = mesh.numFaces(); const Vector3r *vertexNormals = mesh.getVertexNormals().data(); - if (SPH::MiniGL::checkOpenGLVersion(3, 3)) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_REAL, GL_FALSE, 0, &pd.getPosition(offset)[0]); - glEnableVertexAttribArray(2); - glVertexAttribPointer(2, 3, GL_REAL, GL_FALSE, 0, &vertexNormals[0][0]); - } - else - { - float speccolor[4] = { 1.0, 1.0, 1.0, 1.0 }; - glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, color); - glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, speccolor); - glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, 100.0f); - glColor3fv(color); - - glEnableClientState(GL_VERTEX_ARRAY); - glEnableClientState(GL_NORMAL_ARRAY); - glVertexPointer(3, GL_REAL, 0, &pd.getPosition(0)[0]); - glNormalPointer(GL_REAL, 0, &vertexNormals[0][0]); - } - - glDrawElements(GL_TRIANGLES, (GLsizei)3 * mesh.numFaces(), GL_UNSIGNED_INT, mesh.getFaces().data()); - - if (SPH::MiniGL::checkOpenGLVersion(3, 3)) - { - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(2); - } - else - { - glDisableClientState(GL_VERTEX_ARRAY); - glDisableClientState(GL_NORMAL_ARRAY); - } + SPH::MiniGL::supplyVertices(0, mesh.numVertices(), &pd.getPosition(offset)[0]); + SPH::MiniGL::supplyNormals(2, mesh.numVertices(), &vertexNormals[0][0]); + SPH::MiniGL::supplyFaces(3 * nFaces, faces); + + glDrawElements(GL_TRIANGLES, (GLsizei)3 * nFaces, GL_UNSIGNED_INT, (void*)0); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(2); } } diff --git a/Simulator/SimulatorBase.cpp b/Simulator/SimulatorBase.cpp index 0fbf78be..1910e106 100644 --- a/Simulator/SimulatorBase.cpp +++ b/Simulator/SimulatorBase.cpp @@ -2387,7 +2387,7 @@ void SimulatorBase::initDensityMap(std::vector &x, std::vector &x, std::vectormapInvert) sign = -1.0; - func = [&md, &sign, &tolerance](Eigen::Vector3d const& xi) {return sign * (md.signedDistanceCached(xi) - tolerance); }; + func = [&md, &sign, &tolerance](Eigen::Vector3d const& xi) {return sign * (md.signed_distance(xi).distance - tolerance); }; LOG_INFO << "Generate SDF"; START_TIMING("SDF Construction"); @@ -2575,7 +2575,7 @@ void SimulatorBase::initVolumeMap(std::vector &x, std::vector &x, std::vectorgetParticleRadius(); // subtract 0.5 * particle radius to prevent penetration of particles and the boundary - func = [&md, &sign, &tolerance, &particleRadius](Eigen::Vector3d const& xi) {return sign * (md.signedDistanceCached(xi) - tolerance ); }; + func = [&md, &sign, &tolerance, &particleRadius](Eigen::Vector3d const& xi) {return sign * (md.signed_distance(xi).distance - tolerance ); }; LOG_INFO << "Generate SDF"; START_TIMING("SDF Construction"); diff --git a/Tests/CMakeLists.txt b/Tests/CMakeLists.txt index c8260280..917acf82 100644 --- a/Tests/CMakeLists.txt +++ b/Tests/CMakeLists.txt @@ -1,5 +1,5 @@ add_subdirectory(Kernel) add_subdirectory(ReadWriteState) -if (FOUND_AVX2) +if (FOUND_SIMD) add_subdirectory(AVX) endif() diff --git a/Tools/MeshSkinning/main.cpp b/Tools/MeshSkinning/main.cpp index f1607929..fe04ff57 100644 --- a/Tools/MeshSkinning/main.cpp +++ b/Tools/MeshSkinning/main.cpp @@ -111,11 +111,13 @@ unsigned int getNeighbor(const unsigned int pointSetIndex, const unsigned int in return neighborhoodSearch->point_set(0).neighbor(pointSetIndex, index, k); } +namespace std { std::ostream& operator << (std::ostream& out, const Vector3r& r) { out << r[0] << ", " << r[1] << ", " << r[2]; return out; } +} // main @@ -216,18 +218,18 @@ int main( int argc, char **argv ) } if (result.count("scale")) - scale = Vector3r(result["scale"].as>().data()); + scale = Vector3r(result["scale"].as>().data()); LOG_INFO << "Scale: " << scale; if (result.count("translation")) - translation = Vector3r(result["translation"].as>().data()); + translation = Vector3r(result["translation"].as>().data()); LOG_INFO << "Translation: " << translation; Vector3r axis = Vector3r::Zero(); Real angle = 0.0; rotation = Matrix3r::Identity(); if (result.count("axis")) - axis = Vector3r(result["axis"].as>().data()); + axis = Vector3r(result["axis"].as>().data()); if (result.count("angle")) { angle = result["angle"].as(); diff --git a/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.cpp b/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.cpp index 557a542c..b3ec7411 100644 --- a/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.cpp +++ b/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.cpp @@ -55,6 +55,8 @@ void PartioViewer_OpenGL::getImage(int width, int height, unsigned char *image) void PartioViewer_OpenGL::initShaders(const std::string &shaderPath) { + MiniGL::initShaders(shaderPath); + string vertFile = shaderPath + "/vs_points_vector.glsl"; string fragFile = shaderPath + "/fs_points.glsl"; m_shader_vector.compileShaderFile(GL_VERTEX_SHADER, vertFile); @@ -115,6 +117,15 @@ void PartioViewer_OpenGL::initShaders(const std::string &shaderPath) glGenTextures(1, &m_textureMap); } +void PartioViewer_OpenGL::destroyShaders() +{ + glDeleteTextures(1, &m_textureMap); + m_shader_vector.destroy(); + m_shader_scalar.destroy(); + m_shader_scalar_map.destroy(); + m_meshShader.destroy(); + MiniGL::destroyShaders(); +} void PartioViewer_OpenGL::pointShaderBegin(Shader *shader, const Real particleRadius, const float *col, const Real minVal, const Real maxVal, const bool useTexture, float const* color_map) { @@ -141,18 +152,12 @@ void PartioViewer_OpenGL::pointShaderBegin(Shader *shader, const Real particleRa } - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(shader->getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(shader->getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(shader->getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(shader->getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glEnable(GL_DEPTH_TEST); - // Point sprites do not have to be explicitly enabled since OpenGL 3.2 where - // they are enabled by default. Moreover GL_POINT_SPRITE is deprecate and only - // supported before OpenGL 3.2 or with compatibility profile enabled. - glEnable(GL_POINT_SPRITE); glEnable(GL_PROGRAM_POINT_SIZE); glPointParameterf(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT); } @@ -211,148 +216,89 @@ void PartioViewer_OpenGL::render(const Fluid &fluid, const Real particleRadius, fluid.partioData->attributeInfo(fluid.posIndex, posAttr); const float* partioX = fluid.partioData->data(posAttr, 0); - if (MiniGL::checkOpenGLVersion(3, 3)) - { - Shader *shader_s = &m_shader_scalar_map; - float const *color_map = nullptr; - if (colorMapType == 1) - color_map = reinterpret_cast(colormap_jet); - else if (colorMapType == 2) - color_map = reinterpret_cast(colormap_plasma); - else if (colorMapType == 3) - color_map = reinterpret_cast(colormap_coolwarm); - else if (colorMapType == 4) - color_map = reinterpret_cast(colormap_bwr); - else if (colorMapType == 5) - color_map = reinterpret_cast(colormap_seismic); - - if (colorMapType == 0) - shader_s = &m_shader_scalar; - - if (fluid.partioData->numAttributes() == 0) - pointShaderBegin(shader_s, particleRadius, fluidColor, renderMinValue, renderMaxValue, false); - else - pointShaderBegin(shader_s, particleRadius, fluidColor, renderMinValue, renderMaxValue, true, color_map); - - if (nParticles > 0) - { - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, partioX); - - if (fluid.partioData->numAttributes() > 0) - { - glEnableVertexAttribArray(1); - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, &scalarField[0]); - } - - if (usePlane) - glDrawElements(GL_POINTS, (GLsizei)fluid.visibleParticles.size(), GL_UNSIGNED_INT, fluid.visibleParticles.data()); - else - glDrawArrays(GL_POINTS, 0, nParticles); - - glDisableVertexAttribArray(0); - // glDisableVertexAttribArray(1); - } - - if (fluid.partioData->numAttributes() == 0) - pointShaderEnd(shader_s, false); - else - pointShaderEnd(shader_s, true); - } + Shader *shader_s = &m_shader_scalar_map; + float const *color_map = nullptr; + if (colorMapType == 1) + color_map = reinterpret_cast(colormap_jet); + else if (colorMapType == 2) + color_map = reinterpret_cast(colormap_plasma); + else if (colorMapType == 3) + color_map = reinterpret_cast(colormap_coolwarm); + else if (colorMapType == 4) + color_map = reinterpret_cast(colormap_bwr); + else if (colorMapType == 5) + color_map = reinterpret_cast(colormap_seismic); + + if (colorMapType == 0) + shader_s = &m_shader_scalar; + + if (fluid.partioData->numAttributes() == 0) + pointShaderBegin(shader_s, particleRadius, fluidColor, renderMinValue, renderMaxValue, false); else + pointShaderBegin(shader_s, particleRadius, fluidColor, renderMinValue, renderMaxValue, true, color_map); + + if (nParticles > 0) { - const Real supportRadius = particleRadius * static_cast(4.0); - float fluidColor[4] = { 0.1f, 0.2f, 0.6f, 1.0f }; + MiniGL::supplyVertices(0, nParticles, partioX); - Partio::ParticleAttribute attr; if (fluid.partioData->numAttributes() > 0) - fluid.partioData->attributeInfo(colorField, attr); + { + glBindBuffer(GL_ARRAY_BUFFER, MiniGL::getVboNormals()); + glBufferData(GL_ARRAY_BUFFER, nParticles * sizeof(float), &scalarField[0], GL_STREAM_DRAW); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(1); + } - glPointSize(4.0); - glDisable(GL_LIGHTING); - glBegin(GL_POINTS); - for (unsigned int i = 0; i < nParticles; i++) + if (usePlane) { - if (fluid.partioData->numAttributes() > 0) - { - float v = 0.0; - const float* partioVals = NULL; - if (attr.type == Partio::VECTOR) - { - partioVals = fluid.partioData->data(attr, 0); - v = sqrt(partioVals[3 * i] * partioVals[3 * i] + partioVals[3 * i + 1] * partioVals[3 * i + 1] + partioVals[3 * i + 2] * partioVals[3 * i + 2]); - } - else if (attr.type == Partio::FLOAT) - { - partioVals = fluid.partioData->data(attr, 0); - v = partioVals[3 * i]; - } - - v = 0.5f*((v - renderMinValue) / (renderMaxValue - renderMinValue)); - v = min(128.0f*v*v, 0.5f); - float fluidColor[4] = { 0.2f, 0.2f, 0.2f, 1.0f }; - MiniGL::hsvToRgb(0.55f, 1.0f, 0.5f + v, fluidColor); - glColor3fv(fluidColor); - } - else - glColor3fv(fluidColor); - glVertex3fv(&partioX[3 * i]); + MiniGL::supplyFaces(fluid.visibleParticles.size(), fluid.visibleParticles.data()); + glDrawElements(GL_POINTS, (GLsizei)fluid.visibleParticles.size(), GL_UNSIGNED_INT, (void*)0); } - glEnd(); - glEnable(GL_LIGHTING); + else + glDrawArrays(GL_POINTS, 0, nParticles); + + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); } + if (fluid.partioData->numAttributes() == 0) + pointShaderEnd(shader_s, false); + else + pointShaderEnd(shader_s, true); + float red[4] = { 0.8f, 0.0f, 0.0f, 1 }; - if (MiniGL::checkOpenGLVersion(3, 3)) + pointShaderBegin(&m_shader_vector, particleRadius, &red[0], renderMinValue, renderMaxValue); + if (fluid.selectedParticles.size() > 0) { - pointShaderBegin(&m_shader_vector, particleRadius, &red[0], renderMinValue, renderMaxValue); - if (fluid.selectedParticles.size() > 0) - { - glUniform1f(m_shader_vector.getUniform("radius"), (float)particleRadius*1.05f); - glEnableVertexAttribArray(0); - glVertexAttribPointer(0, 3, GL_FALSE, GL_FALSE, 0, partioX); + glUniform1f(m_shader_vector.getUniform("radius"), (float)particleRadius*1.05f); + MiniGL::supplyVertices(0, nParticles, partioX); - if (fluid.partioData->numAttributes() > 0) + if (fluid.partioData->numAttributes() > 0) + { + Partio::ParticleAttribute attr; + fluid.partioData->attributeInfo(colorField, attr); + const float* partioVals = NULL; + if (attr.type == Partio::VECTOR) { - Partio::ParticleAttribute attr; - fluid.partioData->attributeInfo(colorField, attr); - const float* partioVals = NULL; - if (attr.type == Partio::VECTOR) - { - glEnableVertexAttribArray(1); - partioVals = fluid.partioData->data(attr, 0); - glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, &partioVals[0]); - } - else if (attr.type == Partio::FLOAT) - { - glEnableVertexAttribArray(1); - partioVals = fluid.partioData->data(attr, 0); - glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, &partioVals[0]); - } + partioVals = fluid.partioData->data(attr, 0); + MiniGL::supplyNormals(1, nParticles, partioVals); } - - glDrawElements(GL_POINTS, (GLsizei)fluid.selectedParticles.size(), GL_UNSIGNED_INT, fluid.selectedParticles.data()); - glDisableVertexAttribArray(0); - glDisableVertexAttribArray(1); - } - pointShaderEnd(&m_shader_vector); - } - else - { - if (fluid.selectedParticles.size() > 0) - { - glPointSize(4.0); - glDisable(GL_LIGHTING); - glBegin(GL_POINTS); - for (unsigned int i = 0; i < fluid.selectedParticles.size(); i++) + else if (attr.type == Partio::FLOAT) { - glColor3fv(red); - glVertex3fv(&partioX[3 * fluid.selectedParticles[i]]); + partioVals = fluid.partioData->data(attr, 0); + glBindBuffer(GL_ARRAY_BUFFER, MiniGL::getVboNormals()); + glBufferData(GL_ARRAY_BUFFER, nParticles * sizeof(float), partioVals, GL_STREAM_DRAW); + glVertexAttribPointer(1, 1, GL_FLOAT, GL_FALSE, 0, (void*)0); + glEnableVertexAttribArray(1); } - glEnd(); - glEnable(GL_LIGHTING); } + + MiniGL::supplyFaces(fluid.selectedParticles.size(), fluid.selectedParticles.data()); + glDrawElements(GL_POINTS, (GLsizei)fluid.selectedParticles.size(), GL_UNSIGNED_INT, (void*)0); + glDisableVertexAttribArray(0); + glDisableVertexAttribArray(1); } + pointShaderEnd(&m_shader_vector); } @@ -364,12 +310,10 @@ void PartioViewer_OpenGL::render(const Boundary &boundary, const bool renderWall glUniform1f(m_meshShader.getUniform("shininess"), 5.0f); glUniform1f(m_meshShader.getUniform("specular_factor"), 0.2f); - GLfloat matrix[16]; - glGetFloatv(GL_MODELVIEW_MATRIX, matrix); - glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, matrix); - GLfloat pmatrix[16]; - glGetFloatv(GL_PROJECTION_MATRIX, pmatrix); - glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, pmatrix); + const Matrix4f matrix(MiniGL::getModelviewMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("modelview_matrix"), 1, GL_FALSE, &matrix(0,0)); + const Matrix4f pmatrix(MiniGL::getProjectionMatrix().cast()); + glUniformMatrix4fv(m_meshShader.getUniform("projection_matrix"), 1, GL_FALSE, &pmatrix(0,0)); glUniform3fv(m_meshShader.getUniform("surface_color"), 1, &boundary.color[0]); diff --git a/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.h b/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.h index b0b69b16..46973357 100644 --- a/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.h +++ b/Tools/PartioViewer/GUI/OpenGL/PartioViewer_OpenGL.h @@ -25,6 +25,7 @@ namespace SPH static void flipImage(int width, int height, unsigned char *image); static void getImage(int width, int height, unsigned char *image); static void initShaders(const std::string &shaderPath); + static void destroyShaders(); static void pointShaderBegin(Shader *shader, const Real particleRadius, const float *col, const Real minVal, const Real maxVal, const bool useTexture = false, float const* color_map = nullptr); static void pointShaderEnd(Shader *shader, const bool useTexture = false); static void renderGrid(); diff --git a/Tools/PartioViewer/GUI/imgui/PartioViewer_GUI_imgui.cpp b/Tools/PartioViewer/GUI/imgui/PartioViewer_GUI_imgui.cpp index 441d1b1f..bf351ff6 100644 --- a/Tools/PartioViewer/GUI/imgui/PartioViewer_GUI_imgui.cpp +++ b/Tools/PartioViewer/GUI/imgui/PartioViewer_GUI_imgui.cpp @@ -318,8 +318,7 @@ void PartioViewer_GUI_imgui::initParameterGUI() iparam->setFct = [this](int v) { m_viewer->setFPS(v); }; imguiParameters::addParam("Export", "", iparam); - if (MiniGL::checkOpenGLVersion(3, 3)) - PartioViewer_OpenGL::initShaders(m_viewer->getExePath() + "/resources/shaders"); + PartioViewer_OpenGL::initShaders(m_viewer->getExePath() + "/resources/shaders"); MiniGL::setClientSceneFunc(std::bind(&PartioViewer_GUI_imgui::renderScene, this)); } @@ -421,6 +420,7 @@ void PartioViewer_GUI_imgui::destroy() ImGui_ImplOpenGL3_Shutdown(); ImGui_ImplGlfw_Shutdown(); ImGui::DestroyContext(); + PartioViewer_OpenGL::destroyShaders(); } diff --git a/Tools/VolumeSampling/SamplingBase.cpp b/Tools/VolumeSampling/SamplingBase.cpp index 3cb48ea9..e01d1dcd 100644 --- a/Tools/VolumeSampling/SamplingBase.cpp +++ b/Tools/VolumeSampling/SamplingBase.cpp @@ -334,7 +334,7 @@ void SamplingBase::generateSDF(SPH::TriangleMesh& mesh) Discregrid::TriangleMesh sdfMesh(&doubleVec[0], mesh.getFaces().data(), mesh.numVertices(), mesh.numFaces()); #endif - Discregrid::MeshDistance md(sdfMesh); + Discregrid::TriangleMeshDistance md(sdfMesh); Eigen::AlignedBox3d domain; domain.extend(m_bbmin.cast()); domain.extend(m_bbmax.cast()); @@ -347,9 +347,9 @@ void SamplingBase::generateSDF(SPH::TriangleMesh& mesh) // invert the distance field since the particles should stay inside if (!m_invert) - func = [&md](Eigen::Vector3d const& xi) {return -md.signedDistanceCached(xi); }; + func = [&md](Eigen::Vector3d const& xi) {return -md.signed_distance(xi).distance; }; else - func = [&md](Eigen::Vector3d const& xi) {return md.signedDistanceCached(xi); }; + func = [&md](Eigen::Vector3d const& xi) {return md.signed_distance(xi).distance; }; LOG_INFO << "Generate SDF"; m_distanceField->addFunction(func, false); diff --git a/Tools/VolumeSampling/main.cpp b/Tools/VolumeSampling/main.cpp index eebeab69..f4e0b33b 100644 --- a/Tools/VolumeSampling/main.cpp +++ b/Tools/VolumeSampling/main.cpp @@ -62,6 +62,7 @@ bool useCache = true; std::shared_ptr distanceField; +namespace std { std::ostream& operator << (std::ostream& out, const Eigen::Matrix& r) { out << r[0] << ", " << r[1] << ", " << r[2]; @@ -73,6 +74,7 @@ std::ostream& operator << (std::ostream& out, const Vector3r& r) out << r[0] << ", " << r[1] << ", " << r[2]; return out; } +} // main int main(int argc, char **argv) @@ -161,7 +163,7 @@ int main(int argc, char **argv) LOG_INFO << "Radius: " << radius; if (result.count("scale")) - scale = Vector3r(result["scale"].as>().data()); + scale = Vector3r(result["scale"].as>().data()); LOG_INFO << "Scale: " << scale; if (result.count("steps")) @@ -209,7 +211,7 @@ int main(int argc, char **argv) const std::vector &v = result["region"].as>(); if (v.size() == 6) region = SamplingBase::Region(v[0], v[1], v[2], v[3], v[4], v[5]); - else + else LOG_WARN << "Region parameter has wrong number of elements."; useRegion = true; LOG_INFO << "Region - min: " << region.m_min.transpose(); @@ -418,7 +420,7 @@ void generateSDF(SPH::TriangleMesh &mesh) Discregrid::TriangleMesh sdfMesh(&doubleVec[0], mesh.getFaces().data(), mesh.numVertices(), mesh.numFaces()); #endif - Discregrid::MeshDistance md(sdfMesh); + Discregrid::TriangleMeshDistance md(sdfMesh); Eigen::AlignedBox3d domain; domain.extend(bbmin.cast()); domain.extend(bbmax.cast()); @@ -432,7 +434,7 @@ void generateSDF(SPH::TriangleMesh &mesh) auto func = Discregrid::DiscreteGrid::ContinuousFunction{}; // invert the distance field since the particles should stay inside - func = [&md](Eigen::Vector3d const& xi) {return -md.signedDistanceCached(xi); }; + func = [&md](Eigen::Vector3d const& xi) {return -md.signed_distance(xi).distance; }; LOG_INFO << "Generate SDF"; distanceField->addFunction(func, false); diff --git a/Utilities/CMakeLists.txt b/Utilities/CMakeLists.txt index dd9d2199..0cf9929c 100644 --- a/Utilities/CMakeLists.txt +++ b/Utilities/CMakeLists.txt @@ -29,5 +29,9 @@ add_library(Utilities ) add_dependencies(Utilities partio zlib) -target_include_directories(Utilities PUBLIC ${TOPLEVEL_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR}) +if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") + target_compile_options(Utilities PUBLIC -idirafter${TOPLEVEL_INCLUDE_DIR} -idirafter${EIGEN3_INCLUDE_DIR}) +else() + target_include_directories(Utilities PUBLIC ${TOPLEVEL_INCLUDE_DIR} ${EIGEN3_INCLUDE_DIR}) +endif() target_link_libraries(Utilities INTERFACE partio zlib MD5) diff --git a/Utilities/FileSystem.h b/Utilities/FileSystem.h index b0eeb93e..fc935249 100644 --- a/Utilities/FileSystem.h +++ b/Utilities/FileSystem.h @@ -13,6 +13,9 @@ #include #include #endif +#ifdef __APPLE__ +#include +#endif #ifndef S_ISDIR #define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) @@ -217,6 +220,9 @@ namespace Utilities char buffer[1000]; #ifdef WIN32 GetModuleFileName(NULL, buffer, 1000); +#elif defined(__APPLE__) + uint32_t bufferSize = sizeof(buffer); + _NSGetExecutablePath(buffer, &bufferSize); #else char szTmp[32]; sprintf(szTmp, "/proc/%d/exe", getpid()); diff --git a/data/shaders/mini.frag b/data/shaders/mini.frag new file mode 100644 index 00000000..95ee4f6d --- /dev/null +++ b/data/shaders/mini.frag @@ -0,0 +1,52 @@ +#version 330 + +#define NUM_LIGHTS 3 + +uniform bool lighting; +uniform vec3 ambientIntensity; +uniform vec3 diffuseIntensity[NUM_LIGHTS]; +uniform vec3 specularIntensity[NUM_LIGHTS]; +uniform vec3 lightPosition[NUM_LIGHTS]; +uniform vec3 ambientReflectance; +uniform vec3 diffuseReflectance; +uniform vec3 specularReflectance; +uniform float shininess; + +in VertexData { + vec3 position; + vec3 normal; +} IN; + +out vec4 outColor; + +void main() +{ + if (lighting) + { + vec3 view = normalize(-IN.position); + vec3 normal = normalize(IN.normal); + + // Compute the ambient lighting. + vec3 color = ambientReflectance * ambientIntensity; + + for (int i = 0; i < NUM_LIGHTS; i++) + { + vec3 light = normalize(lightPosition[i] - IN.position); + float diffuseFactor = max(dot(normal, light), 0.0); + if (diffuseFactor > 0.0) + { + // Compute the diffuse lighting using the Lambertian model. + color += diffuseFactor * diffuseReflectance * diffuseIntensity[i]; + + vec3 halfway = normalize(light + view); + float specularFactor = pow(max(dot(halfway, normal), 0.0), shininess); + + // Compute the specular lighting using the Blinn-Phong model. + color += specularFactor * specularReflectance * specularIntensity[i]; + } + } + + outColor = vec4(color, 1.0); + } + else outColor = vec4(diffuseReflectance, 1.0); +} \ No newline at end of file diff --git a/data/shaders/mini.vert b/data/shaders/mini.vert new file mode 100644 index 00000000..dc80d99d --- /dev/null +++ b/data/shaders/mini.vert @@ -0,0 +1,22 @@ +#version 330 + +uniform mat4 modelview_matrix; +uniform mat4 projection_matrix; +uniform float pointSize; + +layout(location = 0) in vec3 position; +layout(location = 1) in vec3 normal; + +out VertexData { + vec3 position; + vec3 normal; +} OUT; + +void main() +{ + vec4 vertexPosition = modelview_matrix * vec4(position, 1.0); + OUT.position = vertexPosition.xyz / vertexPosition.w; + OUT.normal = mat3(modelview_matrix) * normal; + gl_Position = projection_matrix * vertexPosition; + gl_PointSize = pointSize; +} \ No newline at end of file diff --git a/data/shaders/mini_screen.frag b/data/shaders/mini_screen.frag new file mode 100644 index 00000000..1b4d9e41 --- /dev/null +++ b/data/shaders/mini_screen.frag @@ -0,0 +1,10 @@ +#version 330 + +uniform vec3 color; + +out vec4 outColor; + +void main() +{ + outColor = vec4(color, 1.0); +} \ No newline at end of file diff --git a/data/shaders/mini_screen.vert b/data/shaders/mini_screen.vert new file mode 100644 index 00000000..6a098bd8 --- /dev/null +++ b/data/shaders/mini_screen.vert @@ -0,0 +1,12 @@ +#version 330 + +uniform float width; +uniform float height; + +layout(location = 0) in vec2 position; + +void main() +{ + // Project the screen position to NDC (cf. glOrtho). + gl_Position = vec4(2.0 * (position.x / width) - 1.0, -2.0 * (position.y / height) + 1.0, -1.0, 1.0); +} \ No newline at end of file diff --git a/pySPlisHSPlasH/UtilitiesModule.cpp b/pySPlisHSPlasH/UtilitiesModule.cpp index 7bdeec52..661d4e3d 100644 --- a/pySPlisHSPlasH/UtilitiesModule.cpp +++ b/pySPlisHSPlasH/UtilitiesModule.cpp @@ -276,12 +276,12 @@ void UtilitiesModule(py::module m) { py::class_(m_sub_sub, "BoundaryData") .def(py::init<>()) .def(py::init, std::string, bool, Real, + Vector4r, std::string, bool, Real, Eigen::Matrix, unsigned int, bool>(), "samplesFile"_a = "", "meshFile"_a = "", "translation"_a = Vector3r::Zero(), "axis"_a = Vector3r(1,0,0), "angle"_a = 0.0, "scale"_a = Vector3r::Ones(), "isDynamic"_a = false, "isWall"_a = false, - "color"_a = Eigen::Vector4f(1.f, 0.f, 0.f, 0.f), + "color"_a = Vector4r(1., 0., 0., 0.), "mapFile"_a = "", "mapInvert"_a = false, "mapThickness"_a = 0.0, "mapResolution"_a = Eigen::Matrix(20, 20, 20), "samplingMode"_a = 0, "isAnimated"_a = false)