extract Mesh and GLMesh
This commit is contained in:
parent
07ed96f16d
commit
e16915428c
@ -2,8 +2,7 @@
|
|||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
#include "Shader.h"
|
#include "Shader.h"
|
||||||
|
|
||||||
#include <glad/glad.h>
|
#include "gl.h"
|
||||||
#include <GLFW/glfw3.h>
|
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/mat3x3.hpp>
|
#include <glm/mat3x3.hpp>
|
||||||
@ -27,30 +26,6 @@ using glm::uvec3;
|
|||||||
using std::map;
|
using std::map;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
|
||||||
static bool glck(const char* call) {
|
|
||||||
int err = glGetError();
|
|
||||||
if (err == 0) {
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
switch (err) {
|
|
||||||
case GL_INVALID_VALUE:
|
|
||||||
printf("GL_INVALID_VALUE: %s\n", call);
|
|
||||||
break;
|
|
||||||
case GL_INVALID_ENUM:
|
|
||||||
printf("GL_INVALID_ENUM: %s\n", call);
|
|
||||||
break;
|
|
||||||
case GL_INVALID_OPERATION:
|
|
||||||
printf("GL_INVALID_OPERATION: %s\n", call);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("UNKNOWN Error: %s\n", call);
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#define GLCK(a) {a; assert(glck(#a));}
|
|
||||||
|
|
||||||
static void error_callback(int error, const char* description) {
|
static void error_callback(int error, const char* description) {
|
||||||
fprintf(stderr, "Error: %s\n", description);
|
fprintf(stderr, "Error: %s\n", description);
|
||||||
}
|
}
|
||||||
@ -80,12 +55,11 @@ static void char_callback(GLFWwindow* window, unsigned int c) {
|
|||||||
Application::Application() :
|
Application::Application() :
|
||||||
window(0), density(), densityIsolevel(0.2), polygonizer(density,
|
window(0), density(), densityIsolevel(0.2), polygonizer(density,
|
||||||
densityIsolevel), textureSize(512), texturemapper(density,
|
densityIsolevel), textureSize(512), texturemapper(density,
|
||||||
textureSize), programId(0), vPositionLoc(-1), vTexCoordLoc(-1), vNormalLoc(
|
textureSize), programId(0), meteoridCount(1000), meteroidMinRadius(
|
||||||
-1), meteoridCount(1000), meteroidMinRadius(0.005), meteroidMaxRadius(
|
0.005), meteroidMaxRadius(0.2), meteroidSizeExponent(2048), densityFrequency(
|
||||||
0.2), meteroidSizeExponent(2048), densityFrequency(2), densityOctave(
|
2), densityOctave(2), densityScale(1.0f), resolution(0.1), smoothMesh(
|
||||||
2), densityScale(1.0f), resolution(0.1), smoothMesh(true), viewDistance(
|
true), viewDistance(3.0f), fpsMode(false), meshUploadRequest(
|
||||||
3.0f), fpsMode(false), meshUploadRequest(false), textureUploadRequest(
|
false), textureUploadRequest(false) {
|
||||||
false) {
|
|
||||||
init();
|
init();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -145,31 +119,20 @@ void Application::init() {
|
|||||||
|
|
||||||
ImGui_ImplGlfwGL3_Init(window, false);
|
ImGui_ImplGlfwGL3_Init(window, false);
|
||||||
|
|
||||||
GLCK(glGenVertexArrays(1, &vertexArrayId))
|
|
||||||
GLCK(glGenBuffers(1, &vPositionId))
|
|
||||||
GLCK(glGenBuffers(1, &vTexCoordId))
|
|
||||||
GLCK(glGenBuffers(1, &vNormalId))
|
|
||||||
GLCK(glGenBuffers(1, &indexBufferId))
|
|
||||||
|
|
||||||
GLCK(glGenTextures(1, &tAlbedoId))
|
GLCK(glGenTextures(1, &tAlbedoId))
|
||||||
GLCK(glGenTextures(1, &tNormalId))
|
GLCK(glGenTextures(1, &tNormalId))
|
||||||
GLCK(glGenTextures(1, &tRoughnessId))
|
GLCK(glGenTextures(1, &tRoughnessId))
|
||||||
GLCK(glGenTextures(1, &tMetalicId))
|
GLCK(glGenTextures(1, &tMetalicId))
|
||||||
|
|
||||||
loadShader();
|
loadShader();
|
||||||
updateVertexArrayObject();
|
glMesh.create();
|
||||||
|
glMesh.update(vPositionLoc, vNormalLoc, vTexCoordLoc);
|
||||||
generateAsteroid();
|
generateAsteroid();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::shutdown() {
|
void Application::shutdown() {
|
||||||
ImGui_ImplGlfwGL3_Shutdown();
|
ImGui_ImplGlfwGL3_Shutdown();
|
||||||
|
|
||||||
GLCK(glDeleteBuffers(1, &vPositionId))
|
|
||||||
GLCK(glDeleteBuffers(1, &vTexCoordId))
|
|
||||||
GLCK(glDeleteBuffers(1, &vNormalId))
|
|
||||||
GLCK(glDeleteBuffers(1, &indexBufferId))
|
|
||||||
GLCK(glDeleteVertexArrays(1, &vertexArrayId))
|
|
||||||
|
|
||||||
glfwDestroyWindow(window);
|
glfwDestroyWindow(window);
|
||||||
glfwTerminate();
|
glfwTerminate();
|
||||||
}
|
}
|
||||||
@ -217,15 +180,16 @@ void Application::toogleFpsMode() {
|
|||||||
|
|
||||||
void Application::generateAsteroid() {
|
void Application::generateAsteroid() {
|
||||||
if (meshProgress.begin("Random Impacts", 1)) {
|
if (meshProgress.begin("Random Impacts", 1)) {
|
||||||
//if (density.getImpacts().size() == 0)
|
if (density.getImpacts().size() == 0)
|
||||||
density.addRandomImpacts(1000, densityIsolevel, 0.01, 0.005, 0.2, 256);
|
density.addRandomImpacts(1000, densityIsolevel, 0.01, 0.005, 0.2,
|
||||||
|
256);
|
||||||
|
|
||||||
//density.saveCrossSection("density.png", 512);
|
//density.saveCrossSection("density.png", 512);
|
||||||
}
|
}
|
||||||
polygonizer.polygonize(resolution, meshProgress);
|
polygonizer.polygonize(resolution, meshProgress);
|
||||||
|
|
||||||
if (smoothMesh && meshProgress.begin("Smooth", 1)) {
|
if (smoothMesh && meshProgress.begin("Smooth", 1)) {
|
||||||
smooth(polygonizer.vertices, polygonizer.indices);
|
polygonizer.mesh.smooth();
|
||||||
// {
|
// {
|
||||||
// std::ofstream out("stage2.obj");
|
// std::ofstream out("stage2.obj");
|
||||||
// saveAttrib(out, "v ", polygonizer.vertices);
|
// saveAttrib(out, "v ", polygonizer.vertices);
|
||||||
@ -233,72 +197,40 @@ void Application::generateAsteroid() {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
uvec4v_t edges;
|
if (meshProgress.begin("Generate Edges", 1)) {
|
||||||
if (meshProgress.begin("Find Edges", 1)) {
|
polygonizer.mesh.generateEdges();
|
||||||
findEdges(polygonizer.vertices, polygonizer.indices, edges);
|
|
||||||
}
|
|
||||||
uvec3v_t adjacents;
|
|
||||||
if (meshProgress.begin("Find Adjacent", 1)) {
|
|
||||||
findAdjacent(edges, polygonizer.indices.size(), adjacents);
|
|
||||||
}
|
|
||||||
vec3v_t faceNormals;
|
|
||||||
calculateFaceNormals(polygonizer.vertices, polygonizer.indices,
|
|
||||||
faceNormals);
|
|
||||||
|
|
||||||
vec3v_t positions;
|
|
||||||
uvec3v_t indices;
|
|
||||||
uintv_t patches;
|
|
||||||
|
|
||||||
createPatches(polygonizer.vertices, polygonizer.indices, faceNormals,
|
|
||||||
adjacents, positions, indices, patches, 0.9);
|
|
||||||
{
|
|
||||||
std::ofstream out("stage1.obj");
|
|
||||||
saveAttrib(out, "v ", positions);
|
|
||||||
saveFaces(out, indices, 1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meshProgress.begin("Calculate Vertex Normals", 1)) {
|
if (meshProgress.begin("Generate Adjacent", 1)) {
|
||||||
calculateVertexNormals(polygonizer.vertices, polygonizer.indices,
|
polygonizer.mesh.generateAdjacent();
|
||||||
normals);
|
|
||||||
// {
|
|
||||||
// std::ofstream out("stage3.obj");
|
|
||||||
// saveAttrib(out, "v ", polygonizer.vertices);
|
|
||||||
// saveAttrib(out, "vn ", normals);
|
|
||||||
// saveFaces(out, polygonizer.indices, 2);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::cout << "Vertices: " << polygonizer.vertices.size() << std::endl;
|
if (meshProgress.begin("Generate Face Normals", 1)) {
|
||||||
std::cout << "Triangles: " << polygonizer.indices.size() << std::endl;
|
polygonizer.mesh.generateFaceNormals();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshProgress.begin("Generate Vertex Normals", 1)) {
|
||||||
|
polygonizer.mesh.generateNormals();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshProgress.begin("Generate Patched", 1)) {
|
||||||
|
mesh = polygonizer.mesh.createPatched(0.9);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (meshProgress.begin("Save Patched", 1)) {
|
||||||
|
mesh.save("patched.obj");
|
||||||
|
}
|
||||||
|
|
||||||
if (meshProgress.begin("Map Textures", 1)) {
|
if (meshProgress.begin("Map Textures", 1)) {
|
||||||
texturemapper.map(polygonizer.vertices, normals, polygonizer.indices);
|
texturemapper.map(mesh.positions, mesh.normals, mesh.indices);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meshProgress.begin("Move To Mean", 1)) {
|
if (meshProgress.begin("Move To Mean", 1)) {
|
||||||
moveToMean(texturemapper.vertices);
|
mesh.moveToMean();
|
||||||
|
|
||||||
// {
|
|
||||||
// std::ofstream out("stage4.obj");
|
|
||||||
// saveAttrib(out, "v ", texturemapper.vertices);
|
|
||||||
// saveAttrib(out, "vn ", texturemapper.normals);
|
|
||||||
// saveAttrib(out, "vt ", texturemapper.texcoords);
|
|
||||||
// saveFaces(out, texturemapper.indices, 3);
|
|
||||||
// }
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (meshProgress.begin("Save", 4)) {
|
if (meshProgress.begin("Save", 4)) {
|
||||||
std::ofstream out("asteroid.obj");
|
mesh.save("final.obj");
|
||||||
saveAttrib(out, "v ", texturemapper.vertices);
|
|
||||||
meshProgress.advance();
|
|
||||||
saveAttrib(out, "vn ", texturemapper.normals);
|
|
||||||
meshProgress.advance();
|
|
||||||
saveAttrib(out, "vt ", texturemapper.texcoords);
|
|
||||||
meshProgress.advance();
|
|
||||||
saveFaces(out, texturemapper.indices, 3);
|
|
||||||
meshProgress.advance();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
meshProgress.finish();
|
meshProgress.finish();
|
||||||
@ -310,40 +242,6 @@ void Application::generateAsteroid() {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Application::bindVertexAttrib(GLuint id, GLint loc, GLuint size) {
|
|
||||||
if (loc < 0)
|
|
||||||
return false;
|
|
||||||
GLCK(glBindBuffer(GL_ARRAY_BUFFER, id))
|
|
||||||
GLCK(glEnableVertexAttribArray(loc))
|
|
||||||
GLCK(glVertexAttribPointer(loc, // attribute
|
|
||||||
size,// size
|
|
||||||
GL_FLOAT,// type
|
|
||||||
GL_FALSE,// normalized?
|
|
||||||
0,// stride
|
|
||||||
(void* ) 0// array buffer offset
|
|
||||||
))
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::updateVertexArrayObject() {
|
|
||||||
GLCK(glBindVertexArray(vertexArrayId))
|
|
||||||
|
|
||||||
if (vPositionLoc >= 0)
|
|
||||||
GLCK(glDisableVertexAttribArray(vPositionLoc))
|
|
||||||
if (vNormalLoc >= 0)
|
|
||||||
GLCK(glDisableVertexAttribArray(vNormalLoc))
|
|
||||||
if (vTexCoordLoc >= 0)
|
|
||||||
GLCK(glDisableVertexAttribArray(vTexCoordLoc))
|
|
||||||
|
|
||||||
bindVertexAttrib(vPositionId, vPositionLoc, 3);
|
|
||||||
bindVertexAttrib(vNormalId, vNormalLoc, 3);
|
|
||||||
bindVertexAttrib(vTexCoordId, vTexCoordLoc, 2);
|
|
||||||
|
|
||||||
GLCK(glBindVertexArray(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Application::loadShader() {
|
void Application::loadShader() {
|
||||||
if (programId >= 0)
|
if (programId >= 0)
|
||||||
GLCK(glDeleteProgram(programId))
|
GLCK(glDeleteProgram(programId))
|
||||||
@ -365,29 +263,6 @@ void Application::loadShader() {
|
|||||||
GLCK(tMetalicLoc = glGetAttribLocation(programId, "tMetalic"))
|
GLCK(tMetalicLoc = glGetAttribLocation(programId, "tMetalic"))
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::uploadMesh() {
|
|
||||||
printf("upload mesh\n");
|
|
||||||
GLCK(glBindVertexArray(vertexArrayId))
|
|
||||||
|
|
||||||
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vPositionId))
|
|
||||||
GLCK(
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, texturemapper.vertices.size() * sizeof(vec3), texturemapper.vertices.data(), GL_STATIC_DRAW))
|
|
||||||
|
|
||||||
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vTexCoordId))
|
|
||||||
GLCK(
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, texturemapper.texcoords.size() * sizeof(glm::vec2), texturemapper.texcoords.data(), GL_STATIC_DRAW))
|
|
||||||
|
|
||||||
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vNormalId))
|
|
||||||
GLCK(
|
|
||||||
glBufferData(GL_ARRAY_BUFFER, texturemapper.normals.size() * sizeof(vec3), texturemapper.normals.data(), GL_STATIC_DRAW))
|
|
||||||
|
|
||||||
GLCK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId))
|
|
||||||
GLCK(
|
|
||||||
glBufferData(GL_ELEMENT_ARRAY_BUFFER, texturemapper.indices.size() * sizeof(uvec3), texturemapper.indices.data(), GL_STATIC_DRAW))
|
|
||||||
|
|
||||||
GLCK(glBindVertexArray(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
void Application::uploadTexture() {
|
void Application::uploadTexture() {
|
||||||
printf("upload texture\n");
|
printf("upload texture\n");
|
||||||
glBindTexture(GL_TEXTURE_2D, tAlbedoId);
|
glBindTexture(GL_TEXTURE_2D, tAlbedoId);
|
||||||
@ -399,11 +274,11 @@ void Application::uploadTexture() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Application::renderMesh() {
|
void Application::renderMesh() {
|
||||||
GLCK(glBindVertexArray(vertexArrayId))
|
glEnable(GL_DEPTH_TEST);
|
||||||
GLCK(
|
glDepthFunc(GL_LESS);
|
||||||
glDrawElements(GL_TRIANGLES, texturemapper.indices.size() * 3, GL_UNSIGNED_INT, (void* ) 0))
|
glEnable(GL_CULL_FACE);
|
||||||
GLCK(glBindVertexArray(0))
|
|
||||||
|
|
||||||
|
glMesh.render();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::prepareShader() {
|
void Application::prepareShader() {
|
||||||
@ -507,8 +382,8 @@ void Application::prepareShader() {
|
|||||||
|
|
||||||
void Application::gui() {
|
void Application::gui() {
|
||||||
ImGui::Begin("Mesh Generation");
|
ImGui::Begin("Mesh Generation");
|
||||||
ImGui::Text("Vertices: %lu, Triangles: %lu", polygonizer.vertices.size(),
|
ImGui::Text("Vertices: %lu, Triangles: %lu", mesh.positions.size(),
|
||||||
polygonizer.indices.size());
|
mesh.indices.size());
|
||||||
//ImGui::InputFloat("Resolution", &resolution);
|
//ImGui::InputFloat("Resolution", &resolution);
|
||||||
ImGui::SliderFloat("Resolution", &resolution, 0.1, 0.001, "%.3f", 0.1);
|
ImGui::SliderFloat("Resolution", &resolution, 0.1, 0.001, "%.3f", 0.1);
|
||||||
if (ImGui::SliderFloat("Frequency", &densityFrequency, 1, 10, "%.0f", 1))
|
if (ImGui::SliderFloat("Frequency", &densityFrequency, 1, 10, "%.0f", 1))
|
||||||
@ -546,7 +421,7 @@ void Application::gui() {
|
|||||||
ImGui::Begin("Rendering");
|
ImGui::Begin("Rendering");
|
||||||
if (ImGui::Button("Reload Shader")) {
|
if (ImGui::Button("Reload Shader")) {
|
||||||
loadShader();
|
loadShader();
|
||||||
updateVertexArrayObject();
|
glMesh.update(vPositionLoc, vNormalLoc, vTexCoordLoc);
|
||||||
}
|
}
|
||||||
if (ImGui::Button("Wireframe"))
|
if (ImGui::Button("Wireframe"))
|
||||||
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
@ -574,12 +449,9 @@ void Application::run() {
|
|||||||
|
|
||||||
glViewport(0, 0, width, height);
|
glViewport(0, 0, width, height);
|
||||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||||
glEnable(GL_DEPTH_TEST);
|
|
||||||
glDepthFunc(GL_LESS);
|
|
||||||
glEnable(GL_CULL_FACE);
|
|
||||||
|
|
||||||
if (meshUploadRequest) {
|
if (meshUploadRequest) {
|
||||||
uploadMesh();
|
glMesh.upload(mesh);
|
||||||
meshUploadRequest = false;
|
meshUploadRequest = false;
|
||||||
}
|
}
|
||||||
if (textureUploadRequest) {
|
if (textureUploadRequest) {
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
#include "Polygoniser.h"
|
#include "Polygoniser.h"
|
||||||
#include "TextureMapper.h"
|
#include "TextureMapper.h"
|
||||||
#include "ProgressMonitor.h"
|
#include "ProgressMonitor.h"
|
||||||
|
#include "gl.h"
|
||||||
|
|
||||||
#include <glm/mat4x4.hpp>
|
#include <glm/mat4x4.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
@ -23,18 +24,14 @@ class Application {
|
|||||||
float textureSize;
|
float textureSize;
|
||||||
TextureMapper texturemapper;
|
TextureMapper texturemapper;
|
||||||
|
|
||||||
unsigned int vertexArrayId, vPositionId, vTexCoordId, vNormalId,
|
int vPositionLoc, vTexCoordLoc, vNormalLoc;
|
||||||
indexBufferId, programId, tAlbedoId, tNormalId, tRoughnessId,
|
unsigned int programId, tAlbedoId, tNormalId, tRoughnessId, tMetalicId;
|
||||||
tMetalicId;
|
|
||||||
|
|
||||||
int MVPloc, Vloc, Mloc, MVloc, LightPosition_worldspaceloc;
|
int MVPloc, Vloc, Mloc, MVloc, LightPosition_worldspaceloc;
|
||||||
int vPositionLoc, vTexCoordLoc, vNormalLoc, tAlbedoLoc, tNormalLoc,
|
int tAlbedoLoc, tNormalLoc, tRoughnessLoc, tMetalicLoc;
|
||||||
tRoughnessLoc, tMetalicLoc;
|
|
||||||
|
|
||||||
vec3v_t vertices;
|
Mesh mesh;
|
||||||
vec3v_t normals;
|
GLMesh glMesh;
|
||||||
vec2v_t texcoords;
|
|
||||||
uvec3v_t indices;
|
|
||||||
|
|
||||||
size_t meteoridCount;
|
size_t meteoridCount;
|
||||||
float meteroidMinRadius;
|
float meteroidMinRadius;
|
||||||
|
274
src/Mesh.cpp
274
src/Mesh.cpp
@ -1,10 +1,12 @@
|
|||||||
#include "Mesh.h"
|
#include "Mesh.h"
|
||||||
|
#include "gl.h"
|
||||||
|
|
||||||
#include <glm/geometric.hpp>
|
#include <glm/geometric.hpp>
|
||||||
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <stack>
|
#include <stack>
|
||||||
|
#include <fstream>
|
||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
using namespace glm;
|
using namespace glm;
|
||||||
@ -12,8 +14,56 @@ using namespace glm;
|
|||||||
static const uvec3::value_type InvalidIndex =
|
static const uvec3::value_type InvalidIndex =
|
||||||
numeric_limits<uvec3::value_type>::max();
|
numeric_limits<uvec3::value_type>::max();
|
||||||
|
|
||||||
void calculateVertexNormals(const vec3v_t &positions, uvec3v_t &indices,
|
Mesh::Mesh() {
|
||||||
vec3v_t &normals) {
|
|
||||||
|
}
|
||||||
|
Mesh::Mesh(Mesh &other) {
|
||||||
|
positions = other.positions;
|
||||||
|
normals = other.normals;
|
||||||
|
texcoords = other.texcoords;
|
||||||
|
|
||||||
|
faceNormals = other.faceNormals;
|
||||||
|
indices = other.indices;
|
||||||
|
patches = other.patches;
|
||||||
|
edges = other.edges;
|
||||||
|
|
||||||
|
adjacents = other.adjacents;
|
||||||
|
tangents = other.tangents;
|
||||||
|
bitangents = other.bitangents;
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh::Mesh(Mesh &&other) {
|
||||||
|
positions.swap(other.positions);
|
||||||
|
normals.swap(other.normals);
|
||||||
|
texcoords.swap(other.texcoords);
|
||||||
|
|
||||||
|
faceNormals.swap(other.faceNormals);
|
||||||
|
indices.swap(other.indices);
|
||||||
|
patches.swap(other.patches);
|
||||||
|
edges.swap(other.edges);
|
||||||
|
|
||||||
|
adjacents.swap(other.adjacents);
|
||||||
|
tangents.swap(other.tangents);
|
||||||
|
bitangents.swap(other.bitangents);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh& Mesh::operator=(Mesh &&other) {
|
||||||
|
positions.swap(other.positions);
|
||||||
|
normals.swap(other.normals);
|
||||||
|
texcoords.swap(other.texcoords);
|
||||||
|
|
||||||
|
faceNormals.swap(other.faceNormals);
|
||||||
|
indices.swap(other.indices);
|
||||||
|
patches.swap(other.patches);
|
||||||
|
edges.swap(other.edges);
|
||||||
|
|
||||||
|
adjacents.swap(other.adjacents);
|
||||||
|
tangents.swap(other.tangents);
|
||||||
|
bitangents.swap(other.bitangents);
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::generateNormals() {
|
||||||
normals.clear();
|
normals.clear();
|
||||||
normals.resize(positions.size(), vec3(0));
|
normals.resize(positions.size(), vec3(0));
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
@ -31,99 +81,19 @@ void calculateVertexNormals(const vec3v_t &positions, uvec3v_t &indices,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void calculateFaceNormals(const vec3v_t &positions, uvec3v_t &indices,
|
void Mesh::generateFaceNormals() {
|
||||||
vec3v_t &normals) {
|
faceNormals.clear();
|
||||||
normals.clear();
|
faceNormals.resize(indices.size(), vec3(uninitialize));
|
||||||
normals.resize(indices.size(), vec3(uninitialize));
|
|
||||||
#pragma omp parallel for
|
#pragma omp parallel for
|
||||||
for (size_t i = 0; i < indices.size(); i++) {
|
for (size_t i = 0; i < indices.size(); i++) {
|
||||||
int a = indices[i].x, b = indices[i].y, c = indices[i].z;
|
int a = indices[i].x, b = indices[i].y, c = indices[i].z;
|
||||||
normals[i] = normalize(
|
faceNormals[i] = normalize(
|
||||||
cross(positions[b] - positions[a],
|
cross(positions[b] - positions[a],
|
||||||
positions[c] - positions[a]));
|
positions[c] - positions[a]));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void moveToMean(vec3v_t &positions) {
|
void Mesh::generateEdges() {
|
||||||
vec3 mean(0);
|
|
||||||
for (size_t i = 0; i < positions.size(); i++) {
|
|
||||||
mean += positions[i];
|
|
||||||
}
|
|
||||||
mean *= vec3(1.f / positions.size());
|
|
||||||
for (size_t i = 0; i < positions.size(); i++) {
|
|
||||||
positions[i] -= mean;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void smooth(vec3v_t &positions, const uvec3v_t &indices) {
|
|
||||||
vec3v_t cogs(positions.size(), vec3(0.f));
|
|
||||||
vector<int> valence(positions.size(), 0);
|
|
||||||
|
|
||||||
for (size_t iTri = 0; iTri < indices.size(); iTri++) {
|
|
||||||
const uvec3 &idx = indices[iTri];
|
|
||||||
for (size_t iE = 0; iE < 3; iE++) {
|
|
||||||
valence[idx[iE]] += 2;
|
|
||||||
cogs[idx[iE]] += positions[idx[(iE + 1) % 3]];
|
|
||||||
cogs[idx[iE]] += positions[idx[(iE + 2) % 3]];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) {
|
|
||||||
cog[0] = cog[1] = cog[2] = valence = 0.0;
|
|
||||||
|
|
||||||
for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) {
|
|
||||||
cog += mesh.point(*vv_it);
|
|
||||||
++valence;
|
|
||||||
}
|
|
||||||
cogs.push_back(cog / valence);
|
|
||||||
}
|
|
||||||
for (v_it = mesh.vertices_begin(), cog_it = cogs.begin(); v_it != v_end;
|
|
||||||
++v_it, ++cog_it)
|
|
||||||
if (!mesh.is_boundary(*v_it))
|
|
||||||
mesh.set_point(*v_it, *cog_it);
|
|
||||||
|
|
||||||
*/
|
|
||||||
#pragma omp parallel for
|
|
||||||
for (size_t i = 0; i < positions.size(); i++) {
|
|
||||||
// vtx[i] = vtx[i] * vec3(0.8)
|
|
||||||
// + cogs[i] * vec3(0.2f / valence[i]);
|
|
||||||
positions[i] = cogs[i] * vec3(1.f / valence[i]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveAttrib(std::ostream &out, const char *prefix, vec3v_t &elements) {
|
|
||||||
for (size_t i = 0; i < elements.size(); i++) {
|
|
||||||
out << prefix << elements[i].x << " " << elements[i].y << " "
|
|
||||||
<< elements[i].z << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveAttrib(std::ostream &out, const char *prefix, vec2v_t &elements) {
|
|
||||||
for (size_t i = 0; i < elements.size(); i++) {
|
|
||||||
out << prefix << elements[i].x << " " << elements[i].y << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void saveFaces(std::ostream &out, const uvec3v_t &incdices, size_t attribs) {
|
|
||||||
for (size_t i = 0; i < incdices.size(); i++) {
|
|
||||||
out << "f";
|
|
||||||
|
|
||||||
for (size_t j = 0; j < 3; j++) {
|
|
||||||
int v = incdices[i][j] + 1;
|
|
||||||
out << " " << v;
|
|
||||||
if (attribs > 1)
|
|
||||||
out << "/" << v;
|
|
||||||
if (attribs > 2)
|
|
||||||
out << "/" << v;
|
|
||||||
out << " ";
|
|
||||||
}
|
|
||||||
|
|
||||||
out << "\n";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void findEdges(const vec3v_t &positions, const uvec3v_t &indices,
|
|
||||||
uvec4v_t &edges) {
|
|
||||||
edges.clear();
|
edges.clear();
|
||||||
map<pair<uint32_t, uint32_t>, uint32_t> edgeMap;
|
map<pair<uint32_t, uint32_t>, uint32_t> edgeMap;
|
||||||
for (size_t iTri = 0; iTri < indices.size(); iTri++) {
|
for (size_t iTri = 0; iTri < indices.size(); iTri++) {
|
||||||
@ -145,8 +115,7 @@ void findEdges(const vec3v_t &positions, const uvec3v_t &indices,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void computeTangentBasis(vec3v_t & positions, vec2v_t & texcoords,
|
void Mesh::generateTangentBasis() {
|
||||||
vec3v_t & normals, vec3v_t & tangents, vec3v_t & bitangents) {
|
|
||||||
|
|
||||||
for (size_t i = 0; i < positions.size(); i += 3) {
|
for (size_t i = 0; i < positions.size(); i += 3) {
|
||||||
|
|
||||||
@ -185,9 +154,8 @@ void computeTangentBasis(vec3v_t & positions, vec2v_t & texcoords,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void findAdjacent(const uvec4v_t &edges, size_t nFaces, uvec3v_t &adjacents) {
|
void Mesh::generateAdjacent() {
|
||||||
printf("findAdjacent: %lu\n", nFaces);
|
adjacents.resize(indices.size(), uvec3(InvalidIndex));
|
||||||
adjacents.resize(nFaces, uvec3(InvalidIndex));
|
|
||||||
for (size_t i = 0; i < edges.size(); i++) {
|
for (size_t i = 0; i < edges.size(); i++) {
|
||||||
int a = edges[i].z;
|
int a = edges[i].z;
|
||||||
int b = edges[i].w;
|
int b = edges[i].w;
|
||||||
@ -209,14 +177,93 @@ void findAdjacent(const uvec4v_t &edges, size_t nFaces, uvec3v_t &adjacents) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void createPatches(const vec3v_t &positions, const uvec3v_t &indices,
|
void Mesh::moveToMean() {
|
||||||
const vec3v_t &faceNormals, const uvec3v_t &adjacents,
|
vec3 mean(0);
|
||||||
vec3v_t &oPositions, uvec3v_t &oIndices, uintv_t &patches,
|
for (size_t i = 0; i < positions.size(); i++) {
|
||||||
float threshold) {
|
mean += positions[i];
|
||||||
|
}
|
||||||
|
mean *= vec3(1.f / positions.size());
|
||||||
|
for (size_t i = 0; i < positions.size(); i++) {
|
||||||
|
positions[i] -= mean;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::smooth() {
|
||||||
|
if (positions.size() == 0 || indices.size() == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
vec3v_t cogs(positions.size(), vec3(0.f));
|
||||||
|
vector<int> valence(positions.size(), 0);
|
||||||
|
|
||||||
|
for (size_t iTri = 0; iTri < indices.size(); iTri++) {
|
||||||
|
const uvec3 &idx = indices[iTri];
|
||||||
|
for (size_t iE = 0; iE < 3; iE++) {
|
||||||
|
valence[idx[iE]] += 2;
|
||||||
|
cogs[idx[iE]] += positions[idx[(iE + 1) % 3]];
|
||||||
|
cogs[idx[iE]] += positions[idx[(iE + 2) % 3]];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
|
for (v_it = mesh.vertices_begin(); v_it != v_end; ++v_it) {
|
||||||
|
cog[0] = cog[1] = cog[2] = valence = 0.0;
|
||||||
|
|
||||||
|
for (vv_it = mesh.vv_iter(*v_it); vv_it.is_valid(); ++vv_it) {
|
||||||
|
cog += mesh.point(*vv_it);
|
||||||
|
++valence;
|
||||||
|
}
|
||||||
|
cogs.push_back(cog / valence);
|
||||||
|
}
|
||||||
|
for (v_it = mesh.vertices_begin(), cog_it = cogs.begin(); v_it != v_end;
|
||||||
|
++v_it, ++cog_it)
|
||||||
|
if (!mesh.is_boundary(*v_it))
|
||||||
|
mesh.set_point(*v_it, *cog_it);
|
||||||
|
|
||||||
|
*/
|
||||||
|
#pragma omp parallel for
|
||||||
|
for (size_t i = 0; i < positions.size(); i++) {
|
||||||
|
// vtx[i] = vtx[i] * vec3(0.8)
|
||||||
|
// + cogs[i] * vec3(0.2f / valence[i]);
|
||||||
|
positions[i] = cogs[i] * vec3(1.f / valence[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::saveAttrib(std::ostream &out, const char *prefix,
|
||||||
|
const vec3v_t &elements) const {
|
||||||
|
for (size_t i = 0; i < elements.size(); i++) {
|
||||||
|
out << prefix << elements[i].x << " " << elements[i].y << " "
|
||||||
|
<< elements[i].z << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::saveAttrib(std::ostream &out, const char *prefix,
|
||||||
|
const vec2v_t &elements) const {
|
||||||
|
for (size_t i = 0; i < elements.size(); i++) {
|
||||||
|
out << prefix << elements[i].x << " " << elements[i].y << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::saveFaces(std::ostream &out, const uvec3v_t &incdices,
|
||||||
|
size_t attribs) const {
|
||||||
|
for (size_t i = 0; i < incdices.size(); i++) {
|
||||||
|
out << "f";
|
||||||
|
|
||||||
|
for (size_t j = 0; j < 3; j++) {
|
||||||
|
int v = incdices[i][j] + 1;
|
||||||
|
out << " " << v;
|
||||||
|
if (attribs > 1)
|
||||||
|
out << "/" << v;
|
||||||
|
if (attribs > 2)
|
||||||
|
out << "/" << v;
|
||||||
|
out << " ";
|
||||||
|
}
|
||||||
|
|
||||||
|
out << "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Mesh Mesh::createPatched(float threshold) const {
|
||||||
assert(adjacents.size() == indices.size());
|
assert(adjacents.size() == indices.size());
|
||||||
patches.clear();
|
Mesh mesh;
|
||||||
oPositions.clear();
|
|
||||||
oIndices.clear();
|
|
||||||
vector<bool> processed(indices.size(), false);
|
vector<bool> processed(indices.size(), false);
|
||||||
|
|
||||||
for (size_t i = 0; i < indices.size(); i++) {
|
for (size_t i = 0; i < indices.size(); i++) {
|
||||||
@ -251,18 +298,39 @@ void createPatches(const vec3v_t &positions, const uvec3v_t &indices,
|
|||||||
for (size_t k = 0; k < 3; k++) {
|
for (size_t k = 0; k < 3; k++) {
|
||||||
auto it = vertexMap.find(idx[k]);
|
auto it = vertexMap.find(idx[k]);
|
||||||
if (it == vertexMap.end()) {
|
if (it == vertexMap.end()) {
|
||||||
uint32_t newIdx = oPositions.size();
|
uint32_t newIdx = mesh.positions.size();
|
||||||
oPositions.push_back(positions[idx[k]]);
|
mesh.positions.push_back(positions[idx[k]]);
|
||||||
|
if (normals.size())
|
||||||
|
mesh.normals.push_back(normals[idx[k]]);
|
||||||
vertexMap[idx[k]] = newIdx;
|
vertexMap[idx[k]] = newIdx;
|
||||||
idx[k] = newIdx;
|
idx[k] = newIdx;
|
||||||
} else {
|
} else {
|
||||||
idx[k] = it->second;
|
idx[k] = it->second;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
oIndices.push_back(idx);
|
mesh.indices.push_back(idx);
|
||||||
}
|
}
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::save(std::ostream &out) const {
|
||||||
|
size_t nAttribs = 1;
|
||||||
|
saveAttrib(out, "v ", positions);
|
||||||
|
if (normals.size()) {
|
||||||
|
nAttribs++;
|
||||||
|
saveAttrib(out, "vn ", normals);
|
||||||
|
}
|
||||||
|
if (texcoords.size()) {
|
||||||
|
nAttribs++;
|
||||||
|
saveAttrib(out, "vt ", texcoords);
|
||||||
|
}
|
||||||
|
saveFaces(out, indices, nAttribs);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Mesh::save(std::string filename) const {
|
||||||
|
std::ofstream out(filename.c_str());
|
||||||
|
save(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
54
src/Mesh.h
54
src/Mesh.h
@ -5,31 +5,43 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <ostream>
|
#include <ostream>
|
||||||
|
|
||||||
void calculateVertexNormals(const vec3v_t &positions, uvec3v_t &indices,
|
struct Mesh {
|
||||||
vec3v_t &normals);
|
vec3v_t positions;
|
||||||
void calculateFaceNormals(const vec3v_t &positions, uvec3v_t &indices,
|
vec3v_t normals;
|
||||||
vec3v_t &normals);
|
vec2v_t texcoords;
|
||||||
void findEdges(const vec3v_t &positions, const uvec3v_t &indices,
|
|
||||||
uvec4v_t &edges);
|
|
||||||
//void createPatches(const vec3v_t &positions, const uvec3v_t &indices,
|
|
||||||
// const uvec4v_t &edges, vec3v_t &oPositions, uvec3v_t &oIndices,
|
|
||||||
// uvec4v_t &oEdges, uintv_t &patches, float threshold);
|
|
||||||
|
|
||||||
void moveToMean(vec3v_t &positions);
|
vec3v_t faceNormals;
|
||||||
|
uvec3v_t indices;
|
||||||
|
uintv_t patches;
|
||||||
|
uvec4v_t edges;
|
||||||
|
uvec3v_t adjacents;
|
||||||
|
vec3v_t tangents;
|
||||||
|
vec3v_t bitangents;
|
||||||
|
|
||||||
void smooth(vec3v_t &positions, const uvec3v_t &indices);
|
Mesh();
|
||||||
|
Mesh(Mesh &other);
|
||||||
|
Mesh(Mesh &&other);
|
||||||
|
|
||||||
void saveAttrib(std::ostream &out, const char *prefix, vec3v_t &elements);
|
Mesh& operator=(Mesh&&);
|
||||||
|
|
||||||
void saveAttrib(std::ostream &out, const char *prefix, vec2v_t &elements);
|
void generateNormals();
|
||||||
|
void generateTangentBasis();
|
||||||
|
|
||||||
void saveFaces(std::ostream &out, const uvec3v_t &indicess, size_t attributes);
|
void generateAdjacent();
|
||||||
|
void generateFaceNormals();
|
||||||
|
void generateEdges();
|
||||||
|
|
||||||
void findAdjacent(const uvec4v_t &edges, size_t nFaces, uvec3v_t &adjacents);
|
void moveToMean();
|
||||||
|
void smooth();
|
||||||
|
|
||||||
void computeTangentBasis(vec3v_t & vertices, vec2v_t & texcoords,
|
Mesh createPatched(float threshold) const;
|
||||||
vec3v_t & normals, vec3v_t & tangents, vec3v_t & bitangents);
|
|
||||||
void createPatches(const vec3v_t &positions, const uvec3v_t &indices,
|
void saveAttrib(std::ostream &out, const char *prefix,
|
||||||
const vec3v_t &faceNormals, const uvec3v_t &adjacents,
|
const vec3v_t &elements) const;
|
||||||
vec3v_t &oPositions, uvec3v_t &oIndices, uintv_t &patches,
|
void saveAttrib(std::ostream &out, const char *prefix,
|
||||||
float threshold);
|
const vec2v_t &elements) const;
|
||||||
|
void saveFaces(std::ostream &out, const uvec3v_t &indicess,
|
||||||
|
size_t attributes) const;
|
||||||
|
void save(std::ostream &out) const;
|
||||||
|
void save(std::string filename) const;
|
||||||
|
};
|
||||||
|
@ -114,7 +114,7 @@ void Polygonizer::polygonize(const vec3 &lower, const vec3 &upper,
|
|||||||
for (int iTri = 0; iTri < nTris; iTri++) {
|
for (int iTri = 0; iTri < nTris; iTri++) {
|
||||||
vec3 *ps = tris[iTri].p;
|
vec3 *ps = tris[iTri].p;
|
||||||
|
|
||||||
// skip degenerate vertices
|
// skip degenerate positions
|
||||||
if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
||||||
|| all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
|| all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
||||||
|| all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
|| all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
||||||
@ -128,8 +128,8 @@ void Polygonizer::polygonize(const vec3 &lower, const vec3 &upper,
|
|||||||
if (vit != vertexLookup.end()) {
|
if (vit != vertexLookup.end()) {
|
||||||
idc[k] = vit->second;
|
idc[k] = vit->second;
|
||||||
} else {
|
} else {
|
||||||
idc[k] = vertices.size();
|
idc[k] = positions.size();
|
||||||
vertices.push_back(p);
|
positions.push_back(p);
|
||||||
vertexLookup[p] = idc[k];
|
vertexLookup[p] = idc[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -142,7 +142,7 @@ void Polygonizer::polygonize(const vec3 &lower, const vec3 &upper,
|
|||||||
|
|
||||||
void Polygonizer::polygonize(float resolution) {
|
void Polygonizer::polygonize(float resolution) {
|
||||||
vertexLookup.clear();
|
vertexLookup.clear();
|
||||||
vertices.clear();
|
positions.clear();
|
||||||
indices.clear();
|
indices.clear();
|
||||||
|
|
||||||
const float isocellSize = 1.f / isocells;
|
const float isocellSize = 1.f / isocells;
|
||||||
@ -187,11 +187,11 @@ void Polygonizer::calculateLayer(std::vector<float> &layer, float resolution,
|
|||||||
|
|
||||||
void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
||||||
vertexLookup.clear();
|
vertexLookup.clear();
|
||||||
vertices.clear();
|
mesh.positions.clear();
|
||||||
indices.clear();
|
mesh.indices.clear();
|
||||||
|
|
||||||
vertices.reserve(pow(1. / resolution, 2) * 8);
|
mesh.positions.reserve(pow(1. / resolution, 2) * 8);
|
||||||
indices.reserve(pow(1. / resolution, 2) * 8);
|
mesh.indices.reserve(pow(1. / resolution, 2) * 8);
|
||||||
size_t nSteps = 1.f / resolution;
|
size_t nSteps = 1.f / resolution;
|
||||||
size_t nSamples = nSteps + 1;
|
size_t nSamples = nSteps + 1;
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
|||||||
for (int iTri = 0; iTri < nTris; iTri++) {
|
for (int iTri = 0; iTri < nTris; iTri++) {
|
||||||
vec3 *ps = tris[iTri].p;
|
vec3 *ps = tris[iTri].p;
|
||||||
|
|
||||||
// skip degenerate vertices
|
// skip degenerate positions
|
||||||
if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
||||||
|| all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
|| all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
||||||
|| all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
|| all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
||||||
@ -272,12 +272,12 @@ void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
|||||||
if (vit != vertexLookup.end()) {
|
if (vit != vertexLookup.end()) {
|
||||||
idc[k] = vit->second;
|
idc[k] = vit->second;
|
||||||
} else {
|
} else {
|
||||||
idc[k] = vertices.size();
|
idc[k] = mesh.positions.size();
|
||||||
vertices.push_back(p);
|
mesh.positions.push_back(p);
|
||||||
vertexLookup[p] = idc[k];
|
vertexLookup[p] = idc[k];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
indices.push_back(idc);
|
mesh.indices.push_back(idc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -287,7 +287,7 @@ void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
|||||||
|
|
||||||
//void Polygonizer::polygonize(float resolution) {
|
//void Polygonizer::polygonize(float resolution) {
|
||||||
// vertexLookup.clear();
|
// vertexLookup.clear();
|
||||||
// vertices.clear();
|
// positions.clear();
|
||||||
// indices.clear();
|
// indices.clear();
|
||||||
//
|
//
|
||||||
// size_t nSteps = 1.f / resolution;
|
// size_t nSteps = 1.f / resolution;
|
||||||
@ -329,7 +329,7 @@ void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
|||||||
// for (int iTri = 0; iTri < nTris; iTri++) {
|
// for (int iTri = 0; iTri < nTris; iTri++) {
|
||||||
// vec3 *ps = tris[iTri].p;
|
// vec3 *ps = tris[iTri].p;
|
||||||
//
|
//
|
||||||
// // skip degenerate vertices
|
// // skip degenerate positions
|
||||||
// if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
// if (all(epsilonEqual(ps[0], ps[1], 1e-8f))
|
||||||
// || all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
// || all(epsilonEqual(ps[0], ps[2], 1e-8f))
|
||||||
// || all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
// || all(epsilonEqual(ps[2], ps[1], 1e-8f)))
|
||||||
@ -343,8 +343,8 @@ void Polygonizer::polygonize(float resolution, ProgressMonitor &progress) {
|
|||||||
// if (vit != vertexLookup.end()) {
|
// if (vit != vertexLookup.end()) {
|
||||||
// idc[k] = vit->second;
|
// idc[k] = vit->second;
|
||||||
// } else {
|
// } else {
|
||||||
// idc[k] = vertices.size();
|
// idc[k] = positions.size();
|
||||||
// vertices.push_back(p);
|
// positions.push_back(p);
|
||||||
// vertexLookup[p] = idc[k];
|
// vertexLookup[p] = idc[k];
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
#include <vector>
|
#include <vector>
|
||||||
#include <map>
|
#include <map>
|
||||||
|
|
||||||
#include "types.h"
|
#include "Mesh.h"
|
||||||
#include "Density.h"
|
#include "Density.h"
|
||||||
#include "ProgressMonitor.h"
|
#include "ProgressMonitor.h"
|
||||||
|
|
||||||
@ -47,8 +47,7 @@ class Polygonizer {
|
|||||||
void calculateLayer(std::vector<float> &layer, float resolution, size_t nSamples, float z);
|
void calculateLayer(std::vector<float> &layer, float resolution, size_t nSamples, float z);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
vec3v_t vertices;
|
Mesh mesh;
|
||||||
uvec3v_t indices;
|
|
||||||
std::map<glm::vec3, int, CompareVec3> vertexLookup;
|
std::map<glm::vec3, int, CompareVec3> vertexLookup;
|
||||||
|
|
||||||
|
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
|
|
||||||
using namespace std;
|
using namespace std;
|
||||||
|
|
||||||
SkyBox::SkyBox() {
|
SkyBox::SkyBox() :
|
||||||
|
textureId(GL_INVALID_INDEX), programId(GL_INVALID_INDEX) {
|
||||||
glGenTextures(1, &textureId);
|
glGenTextures(1, &textureId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
121
src/gl.h
Normal file
121
src/gl.h
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <glad/glad.h>
|
||||||
|
#include <GLFW/glfw3.h>
|
||||||
|
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
|
static bool glck(const char* call) {
|
||||||
|
int err = glGetError();
|
||||||
|
if (err == 0) {
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
switch (err) {
|
||||||
|
case GL_INVALID_VALUE:
|
||||||
|
printf("GL_INVALID_VALUE: %s\n", call);
|
||||||
|
break;
|
||||||
|
case GL_INVALID_ENUM:
|
||||||
|
printf("GL_INVALID_ENUM: %s\n", call);
|
||||||
|
break;
|
||||||
|
case GL_INVALID_OPERATION:
|
||||||
|
printf("GL_INVALID_OPERATION: %s\n", call);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
printf("UNKNOWN Error: %s\n", call);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define GLCK(a) {a; assert(glck(#a));}
|
||||||
|
|
||||||
|
class GLMesh {
|
||||||
|
unsigned int vertexArrayId, vPositionId, vTexCoordId, vNormalId,
|
||||||
|
indexBufferId;
|
||||||
|
unsigned int indexCount;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
GLMesh() :
|
||||||
|
vertexArrayId(0), vPositionId(0), vTexCoordId(0), vNormalId(0), indexBufferId(
|
||||||
|
0), indexCount(0) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
~GLMesh() {
|
||||||
|
GLCK(glDeleteBuffers(1, &vPositionId))
|
||||||
|
GLCK(glDeleteBuffers(1, &vTexCoordId))
|
||||||
|
GLCK(glDeleteBuffers(1, &vNormalId))
|
||||||
|
GLCK(glDeleteBuffers(1, &indexBufferId))
|
||||||
|
GLCK(glDeleteVertexArrays(1, &vertexArrayId))
|
||||||
|
}
|
||||||
|
|
||||||
|
void create() {
|
||||||
|
GLCK(glGenVertexArrays(1, &vertexArrayId))
|
||||||
|
GLCK(glGenBuffers(1, &vPositionId))
|
||||||
|
GLCK(glGenBuffers(1, &vTexCoordId))
|
||||||
|
GLCK(glGenBuffers(1, &vNormalId))
|
||||||
|
GLCK(glGenBuffers(1, &indexBufferId))
|
||||||
|
}
|
||||||
|
|
||||||
|
void upload(const Mesh &mesh) {
|
||||||
|
printf("upload mesh\n");
|
||||||
|
GLCK(glBindVertexArray(vertexArrayId))
|
||||||
|
|
||||||
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vPositionId))
|
||||||
|
GLCK(
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.positions.size() * sizeof(glm::vec3), mesh.positions.data(), GL_STATIC_DRAW))
|
||||||
|
|
||||||
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vTexCoordId))
|
||||||
|
GLCK(
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.texcoords.size() * sizeof(glm::vec2), mesh.texcoords.data(), GL_STATIC_DRAW))
|
||||||
|
|
||||||
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, vNormalId))
|
||||||
|
GLCK(
|
||||||
|
glBufferData(GL_ARRAY_BUFFER, mesh.normals.size() * sizeof(glm::vec3), mesh.normals.data(), GL_STATIC_DRAW))
|
||||||
|
|
||||||
|
GLCK(glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId))
|
||||||
|
GLCK(
|
||||||
|
glBufferData(GL_ELEMENT_ARRAY_BUFFER, mesh.indices.size() * sizeof(glm::uvec3), mesh.indices.data(), GL_STATIC_DRAW))
|
||||||
|
|
||||||
|
GLCK(glBindVertexArray(0))
|
||||||
|
|
||||||
|
indexCount = mesh.indices.size() * 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
void render() {
|
||||||
|
GLCK(glBindVertexArray(vertexArrayId))
|
||||||
|
GLCK(
|
||||||
|
glDrawElements(GL_TRIANGLES, indexCount, GL_UNSIGNED_INT, (void* ) 0))
|
||||||
|
GLCK(glBindVertexArray(0))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
bool bindVertexAttrib(GLuint id, GLint loc, GLuint size) const {
|
||||||
|
if (loc < 0) {
|
||||||
|
GLCK(glDisableVertexAttribArray(loc))
|
||||||
|
} else {
|
||||||
|
GLCK(glBindBuffer(GL_ARRAY_BUFFER, id))
|
||||||
|
GLCK(glEnableVertexAttribArray(loc))
|
||||||
|
GLCK(glVertexAttribPointer(loc, // attribute
|
||||||
|
size,// size
|
||||||
|
GL_FLOAT,// type
|
||||||
|
GL_FALSE,// normalized?
|
||||||
|
0,// stride
|
||||||
|
(void* ) 0// array buffer offset
|
||||||
|
))
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void update(int vPositionLoc, int vNormalLoc, int vTexCoordLoc) const {
|
||||||
|
GLCK(glBindVertexArray(vertexArrayId))
|
||||||
|
|
||||||
|
bindVertexAttrib(vPositionId, vPositionLoc, 3);
|
||||||
|
bindVertexAttrib(vNormalId, vNormalLoc, 3);
|
||||||
|
bindVertexAttrib(vTexCoordId, vTexCoordLoc, 2);
|
||||||
|
|
||||||
|
GLCK(glBindVertexArray(0))
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -3,6 +3,7 @@
|
|||||||
#include "AlignedAllocator.h"
|
#include "AlignedAllocator.h"
|
||||||
#include <glm/vec4.hpp>
|
#include <glm/vec4.hpp>
|
||||||
#include <glm/vec3.hpp>
|
#include <glm/vec3.hpp>
|
||||||
|
#include <glm/vec2.hpp>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
typedef glm::tvec4<uint8_t> ucvec4_t;
|
typedef glm::tvec4<uint8_t> ucvec4_t;
|
||||||
|
Loading…
Reference in New Issue
Block a user