diff --git a/demo/main.cpp b/demo/main.cpp index a1f1eacb83bc1c0e69091f2d7ce523d1b4b26a60..677e31b0a12557c49753896223570d98a77478a8 100644 --- a/demo/main.cpp +++ b/demo/main.cpp @@ -82,54 +82,33 @@ int main(int argc, char* argv[]) { ecs.registerComponent<fggl::gfx::MeshToken>(); ecs.registerComponent<fggl::math::Transform>(); - int nCubes = 3; - int nSlopes = 3; - - for (int i=0; i<nCubes; i++) { - // create an entity - auto entity = ecs.createEntity(); - - // set the position - auto result = ecs.addComponent<fggl::math::Transform>(entity); - result->origin( glm::vec3( 0.0f, 0.0f, i * -1.0f) ); - - // in a supprise to no one it's a triangle - auto mesh = fggl::data::make_cube(); - auto token = meshRenderer.upload(mesh); - token.pipeline = shaderNormals; - ecs.addComponent<fggl::gfx::MeshToken>(entity, token); - } + int nCubes = 1; + int nSections = 3; constexpr float HALF_PI = M_PI / 2.0f; - for (int i=0; i<nSlopes; i++) { - // create an entity + + for ( int i=0; i<nCubes; i++ ) { auto entity = ecs.createEntity(); // set the position auto result = ecs.addComponent<fggl::math::Transform>(entity); - result->origin( glm::vec3( 1.0f, 0.0f, i * -1.0f) ); - result->euler( glm::vec3( 0.0f, HALF_PI, 0.0f) ); + result->origin( glm::vec3( 0.0f, 0.0f, i * -1.0f) ); - // in a supprise to no one it's a triangle - auto mesh = fggl::data::make_slope(); - auto token = meshRenderer.upload(mesh); - token.pipeline = shaderNormals; - ecs.addComponent<fggl::gfx::MeshToken>(entity, token); - } + fggl::data::Mesh mesh; + for (int i=-(nSections/2); i<=nSections/2; i++) { + const auto shapeOffset = glm::vec3( 0.0f, 0.0f, i * 1.0f ); - for (int i=0; i<nSlopes; i++) { - // create an entity - auto entity = ecs.createEntity(); + const auto cubeMat = glm::translate( fggl::math::mat4( 1.0f ) , shapeOffset ); + const auto leftSlope = fggl::math::modelMatrix( glm::vec3(-1.0f, 0.0f, 0.0f) + shapeOffset, glm::vec3( 0.0f, -HALF_PI, 0.0f) ); + const auto rightSlope = fggl::math::modelMatrix( glm::vec3( 1.0f, 0.0f, 0.0f) + shapeOffset, glm::vec3( 0.0f, HALF_PI, 0.0f) ); - // set the position - auto result = ecs.addComponent<fggl::math::Transform>(entity); - result->origin( glm::vec3( -1.0f, 0.0f, i * -1.0f) ); - result->euler( glm::vec3( 0.0f, -HALF_PI, 0.0f) ); + fggl::data::make_cube( mesh, cubeMat ); + fggl::data::make_slope( mesh, leftSlope ); + fggl::data::make_slope( mesh, rightSlope ); + } - // in a supprise to no one it's a triangle - auto mesh = fggl::data::make_slope(); - auto token = meshRenderer.upload(mesh); - token.pipeline = shaderNormals; + auto token = meshRenderer.upload( mesh ); + token.pipeline = shaderPhong; ecs.addComponent<fggl::gfx::MeshToken>(entity, token); } @@ -143,12 +122,12 @@ int main(int argc, char* argv[]) { // update step time += dt; -/* float amount = glm::radians( time / 2048.0f * 360.0f ); + float amount = glm::radians( time / 2048.0f * 360.0f ); auto spinners = ecs.getEntityWith<fggl::math::Transform>(); for ( auto entity : spinners ) { auto transform = ecs.getComponent<fggl::math::Transform>(entity); transform->euler(glm::vec3(0.0f, amount, 0.0f)); - }*/ + } // render step ogl.clear(); diff --git a/fggl/data/procedural.cpp b/fggl/data/procedural.cpp index 0c832137143bb24e58055aa17d8869f53cb06f57..0f65c60ef702e0140f33916ef6056643a61fef67 100644 --- a/fggl/data/procedural.cpp +++ b/fggl/data/procedural.cpp @@ -2,7 +2,10 @@ #include "procedural.hpp" #include "model.hpp" +#include <glm/ext/matrix_transform.hpp> +#include <glm/gtc/quaternion.hpp> #include <iostream> + #include <glm/geometric.hpp> using namespace fggl::data; @@ -14,15 +17,17 @@ static glm::vec3 calcSurfaceNormal(glm::vec3 a, glm::vec3 b, glm::vec3 c) { return glm::normalize( glm::cross( u, v ) ); } -static void computeNormals( fggl::data::Mesh& mesh, const int* idx, const int* colIdx, int points) { +static void computeNormals( fggl::data::Mesh& mesh, const int* idx, const int* colIdx, int nPoints) { // we're assuming all the normals are zero... - for (auto& vertex : mesh.vertexList() ) { + // FIXME this will touch any vertex that appears in idx more than once mutliple times... + for ( int i=0; i<nPoints; i++ ) { + auto& vertex = mesh.vertex( colIdx[ idx[i] ] ); vertex.normal = glm::vec3(0.0f); } // each vertex normal should be the sum of the triangles it's part of. - for (int i=0; i<points; i += 3) { + for (int i=0; i<nPoints; i += 3) { auto& v1 = mesh.vertex( colIdx[ idx[i] ] ); auto& v2 = mesh.vertex( colIdx[ idx[i + 1] ] ); auto& v3 = mesh.vertex( colIdx[ idx[i + 2] ] ); @@ -30,9 +35,9 @@ static void computeNormals( fggl::data::Mesh& mesh, const int* idx, const int* c const glm::vec3 normal = calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon ); // v2.normal += calcSurfaceNormal( v2.posititon, v3.posititon, v1.posititon ); // v3.normal += calcSurfaceNormal( v3.posititon, v1.posititon, v2.posititon ); - v1.normal = normal; - v2.normal = normal; - v3.normal = normal; + v1.normal += normal; + v2.normal += normal; + v3.normal += normal; } @@ -43,30 +48,25 @@ static void computeNormals( fggl::data::Mesh& mesh, const int* idx, const int* c } } -static void computeNormalsDirect( fggl::data::Mesh& mesh, const int* colIdx, int points) { +static void computeNormalsDirect( fggl::data::Mesh& mesh, const int* colIdx, int nPoints) { // we're assuming all the normals are zero... - for (auto& vertex : mesh.vertexList() ) { + for ( int i=0; i<nPoints; i++ ) { + auto& vertex = mesh.vertex( colIdx[i] ); vertex.normal = glm::vec3(0.0f); } - // each vertex normal should be the sum of the triangles it's part of. - for (int i=0; i<points; i += 3) { + // We're assuming each vertex appears only once (because we're not indexed) + for (int i=0; i<nPoints; i += 3) { auto& v1 = mesh.vertex( colIdx[ i ] ); auto& v2 = mesh.vertex( colIdx[ i + 1 ] ); auto& v3 = mesh.vertex( colIdx[ i + 2 ] ); - const glm::vec3 normal = calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon ); + const glm::vec3 normal = glm::normalize( calcSurfaceNormal( v1.posititon, v2.posititon, v3.posititon ) ); v1.normal = normal; v2.normal = normal; v3.normal = normal; } - - // each vertex should currently be the sum of every triangle it's part of - // so we need to normalize them - for (auto& vertex : mesh.vertexList() ) { - vertex.normal = glm::normalize( vertex.normal ); - } } fggl::data::Mesh fggl::data::make_triangle() { @@ -153,7 +153,28 @@ fggl::data::Mesh fggl::data::make_quad_xz() { } -fggl::data::Mesh fggl::data::make_cube() { +constexpr float HALF_PI = M_PI / 2.0f; +static void populateMesh(fggl::data::Mesh& mesh, const fggl::math::mat4 transform, + int nIdx, const fggl::math::vec3* pos, const int* idx ) { + int colIdx[nIdx]; + + // generate mesh + for (int i=0; i<nIdx; i++) { + glm::vec3 rawPos = transform * glm::vec4( pos[ idx[i] ], 1.0 ); + + Vertex vert{}; + vert.posititon = rawPos; + vert.normal = glm::vec3(0.0f, 0.0f, 0.0f); + vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); + colIdx[ i ] = mesh.pushVertex( vert ); + mesh.pushIndex( colIdx[i] ); + } + + computeNormalsDirect( mesh, colIdx, nIdx ); +} + + +fggl::data::Mesh fggl::data::make_cube(fggl::data::Mesh& mesh, const fggl::math::mat4& transform) { // done as two loops, top loop is 0,1,2,3, bottom loop is 4,5,6,7 constexpr fggl::math::vec3 pos[] { @@ -183,25 +204,11 @@ fggl::data::Mesh fggl::data::make_cube() { }; int nIdx = sizeof(idx) / sizeof(int); - int colIdx[nIdx]; - - // generate mesh - fggl::data::Mesh mesh; - for (int i=0; i<nIdx; i++) { - Vertex vert{}; - vert.posititon = pos[ idx[i] ]; - vert.normal = glm::vec3(0.0f, 0.0f, 0.0f); - vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); - colIdx[ i ] = mesh.pushVertex( vert ); - mesh.pushIndex( colIdx[i] ); - } - - computeNormalsDirect( mesh, colIdx, nIdx ); - + populateMesh(mesh, transform, nIdx, pos, idx); return mesh; } -fggl::data::Mesh fggl::data::make_slope() { +fggl::data::Mesh fggl::data::make_slope(fggl::data::Mesh& mesh, const fggl::math::mat4& transform) { // done as two loops, top loop is 0,1,2,3, bottom loop is 4,5,6,7 // FIXME remove 2 and 3 and renumber the index list accordingly @@ -228,24 +235,11 @@ fggl::data::Mesh fggl::data::make_slope() { }; int nIdx = sizeof(idx) / sizeof(int); - int colIdx[nIdx]; - - // generate mesh - fggl::data::Mesh mesh; - for (int i=0; i<nIdx; i++) { - Vertex vert{}; - vert.posititon = pos[ idx[i] ]; - vert.normal = glm::vec3(0.0f, 0.0f, 0.0f); - vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); - colIdx[ i ] = mesh.pushVertex( vert ); - mesh.pushIndex( colIdx[i] ); - } - - computeNormalsDirect( mesh, colIdx, nIdx ); + populateMesh(mesh, transform, nIdx, pos, idx); return mesh; } -fggl::data::Mesh fggl::data::make_ditch() { +fggl::data::Mesh fggl::data::make_ditch(fggl::data::Mesh& mesh, const fggl::math::mat4& transform) { // done as two loops, top loop is 0,1,2,3, bottom loop is 4,5,6,7 // FIXME remove 2 and renumber the index list accordingly @@ -274,24 +268,11 @@ fggl::data::Mesh fggl::data::make_ditch() { }; int nIdx = sizeof(idx) / sizeof(int); - int colIdx[nIdx]; - - // generate mesh - fggl::data::Mesh mesh; - for (int i=0; i<nIdx; i++) { - Vertex vert{}; - vert.posititon = pos[ idx[i] ]; - vert.normal = glm::vec3(0.0f, 0.0f, 0.0f); - vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); - colIdx[ i ] = mesh.pushVertex( vert ); - mesh.pushIndex( colIdx[i] ); - } - - computeNormalsDirect( mesh, colIdx, nIdx ); + populateMesh(mesh, transform, nIdx, pos, idx); return mesh; } -fggl::data::Mesh fggl::data::make_point() { +fggl::data::Mesh fggl::data::make_point(fggl::data::Mesh& mesh, const fggl::math::mat4& transform) { // done as two loops, top loop is 0,1,2,3, bottom loop is 4,5,6,7 constexpr fggl::math::vec3 pos[] { @@ -315,20 +296,7 @@ fggl::data::Mesh fggl::data::make_point() { }; int nIdx = sizeof(idx) / sizeof(int); - int colIdx[nIdx]; - - // generate mesh - fggl::data::Mesh mesh; - for (int i=0; i<nIdx; i++) { - Vertex vert{}; - vert.posititon = pos[ idx[i] ]; - vert.normal = glm::vec3(0.0f, 0.0f, 0.0f); - vert.colour = fggl::math::vec3(1.0f, 1.0f, 1.0f); - colIdx[ i ] = mesh.pushVertex( vert ); - mesh.pushIndex( colIdx[i] ); - } - - computeNormalsDirect( mesh, colIdx, nIdx ); + populateMesh(mesh, transform, nIdx, pos, idx); return mesh; } diff --git a/fggl/data/procedural.hpp b/fggl/data/procedural.hpp index 1e39d9437038a8f7b10c9d36f02e44c93e90dacb..35a21800e2650ffb08f7fce9806ec24560eebdea 100644 --- a/fggl/data/procedural.hpp +++ b/fggl/data/procedural.hpp @@ -3,6 +3,8 @@ namespace fggl::data { + constexpr math::mat4 OFFSET_NONE(1.0f); + Mesh make_triangle(); // quads @@ -10,10 +12,24 @@ namespace fggl::data { Mesh make_quad_xz(); // simple shapes - Mesh make_cube(); + Mesh make_cube(Mesh& mesh, const math::mat4& offset); + inline Mesh make_cube(Mesh& mesh) { + return make_cube(mesh, OFFSET_NONE); + } // blockout shapes - Mesh make_slope(); - Mesh make_ditch(); - Mesh make_point(); + Mesh make_slope(Mesh& mesh, const math::mat4& offset); + inline Mesh make_slope(Mesh& mesh) { + return make_slope(mesh, OFFSET_NONE); + } + + Mesh make_ditch(Mesh& mesh, const math::mat4& offset); + inline Mesh make_ditch(Mesh& mesh) { + return make_ditch(mesh, OFFSET_NONE); + } + + Mesh make_point(Mesh& mesh, const math::mat4& offset); + inline Mesh make_point(Mesh& mesh) { + return make_point(mesh, OFFSET_NONE); + } } diff --git a/fggl/math/types.hpp b/fggl/math/types.hpp index 77373e6edb29610c97739fe26f9f46907eb06de7..32d45d308031d4d1b22fb0d4eeca3d68f0d382f3 100644 --- a/fggl/math/types.hpp +++ b/fggl/math/types.hpp @@ -20,6 +20,14 @@ namespace fggl::math { constexpr vec3 FORWARD { 1.0f, 0.0f, 0.0f }; constexpr vec3 RIGHT { 0.0f, 0.0f, 1.0f }; + inline glm::mat4 modelMatrix( const vec3 offset, const quat rotation ) { + return glm::translate( glm::mat4(1.0f), offset ) * glm::toMat4( rotation ); + } + + inline glm::mat4 modelMatrix( glm::vec3 offset, glm::vec3 eulerAngles ) { + return modelMatrix( offset, glm::quat( eulerAngles ) ); + } + struct Transform { Transform() : m_local(1.0f), m_origin(0.0f), m_model(1.0f), m_rotation() {