geometry_mesh make_box_geometry(const float3 & min_bounds, const float3 & max_bounds) { const auto a = min_bounds, b = max_bounds; geometry_mesh mesh; mesh.vertices = { {{a.x, a.y, a.z}, {-1,0,0}, {1,0}}, {{a.x, a.y, b.z}, {-1,0,0}, {0,0}}, {{a.x, b.y, b.z}, {-1,0,0}, {0,1}}, {{a.x, b.y, a.z}, {-1,0,0}, {1,1}}, {{b.x, a.y, a.z}, {+1,0,0}, {0,0}}, {{b.x, b.y, a.z}, {+1,0,0}, {1,0}}, {{b.x, b.y, b.z}, {+1,0,0}, {1,1}}, {{b.x, a.y, b.z}, {+1,0,0}, {0,1}}, {{a.x, a.y, a.z}, {0,-1,0}, {1,0}}, {{b.x, a.y, a.z}, {0,-1,0}, {0,0}}, {{b.x, a.y, b.z}, {0,-1,0}, {0,1}}, {{a.x, a.y, b.z}, {0,-1,0}, {1,1}}, {{a.x, b.y, a.z}, {0,+1,0}, {0,0}}, {{a.x, b.y, b.z}, {0,+1,0}, {1,0}}, {{b.x, b.y, b.z}, {0,+1,0}, {1,1}}, {{b.x, b.y, a.z}, {0,+1,0}, {0,1}}, {{a.x, a.y, a.z}, {0,0,-1}, {1,0}}, {{a.x, b.y, a.z}, {0,0,-1}, {0,0}}, {{b.x, b.y, a.z}, {0,0,-1}, {0,1}}, {{b.x, a.y, a.z}, {0,0,-1}, {1,1}}, {{a.x, a.y, b.z}, {0,0,+1}, {0,0}}, {{b.x, a.y, b.z}, {0,0,+1}, {1,0}}, {{b.x, b.y, b.z}, {0,0,+1}, {1,1}}, {{a.x, b.y, b.z}, {0,0,+1}, {0,1}}, }; mesh.triangles = {{0,1,2}, {0,2,3}, {4,5,6}, {4,6,7}, {8,9,10}, {8,10,11}, {12,13,14}, {12,14,15}, {16,17,18}, {16,18,19}, {20,21,22}, {20,22,23}}; compute_tangents(mesh); return mesh; }
geometry_mesh make_cylinder_geometry(const float3 & axis, const float3 & arm1, const float3 & arm2, int slices) { // Generated curved surface geometry_mesh mesh; for(int i=0; i<=slices; ++i) { const float tex_s = static_cast<float>(i) / slices, angle = (float)(i%slices) * tau / slices; const float3 arm = arm1 * std::cos(angle) + arm2 * std::sin(angle); mesh.vertices.push_back({arm, normalize(arm), {tex_s,0}}); mesh.vertices.push_back({arm + axis, normalize(arm), {tex_s,1}}); } for(int i=0; i<slices; ++i) { mesh.triangles.push_back({i*2, i*2+2, i*2+3}); mesh.triangles.push_back({i*2, i*2+3, i*2+1}); } // Generate caps int base = mesh.vertices.size(); for(int i=0; i<slices; ++i) { const float angle = static_cast<float>(i%slices) * tau / slices, c = std::cos(angle), s = std::sin(angle); const float3 arm = arm1 * c + arm2 * s; mesh.vertices.push_back({arm + axis, normalize(axis), {c*0.5f+0.5f, s*0.5f+0.5f}}); mesh.vertices.push_back({arm, -normalize(axis), {c*0.5f+0.5f, 0.5f-s*0.5f}}); } for(int i=2; i<slices; ++i) { mesh.triangles.push_back({base, base+i*2-2, base+i*2}); mesh.triangles.push_back({base+1, base+i*2+1, base+i*2-1}); } compute_tangents(mesh); return mesh; }
/* virtual */ void sphere::do_changed(field::base& f) { TRACE("hugh::scene::object::geometry::do_changed"); if (&f == &subdivision) { attribute_list_.clear(); index_list_ .clear(); octahedron const oct; for (auto const& a : oct.attributes.get()) { // why doesn't '*oct.attributes' work here? add_point(a.position, attribute_list_); } unsigned running_idx(unsigned((*oct.attributes).size())); for (unsigned i(0); i < (*oct.indices).size(); i += 3) { subdivide_triangle((*oct.indices)[i+0], (*oct.indices)[i+1], (*oct.indices)[i+2], *subdivision, attribute_list_, index_list_, running_idx); } compute_bounds(); compute_tangents(); } else { base::do_changed(f); } }
/* explicit */ octahedron::octahedron() : node::geometry() { TRACE("scene::primitive::octahedron::octahedron"); make_octahedron(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
/* explicit */ tetrahedron::tetrahedron() : base() { TRACE("hugh::scene::object::geometry::tetrahedron::tetrahedron"); attribute_list_.clear(); index_list_ .clear(); make_tetrahedron(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
/* explicit */ cube::cube() : base() { TRACE("hugh::scene::object::geometry::cube::cube"); attribute_list_.clear(); index_list_ .clear(); make_cube(attribute_list_, index_list_); compute_bounds(); compute_tangents(); }
/* virtual */ void cylinder::do_changed(field::base& f) { TRACE("scene::primitive::cylinder::do_changed"); if (&f == &sides) { make_cylinder(*sides, attribute_list_, index_list_); compute_bounds(); compute_tangents(); } else { node::geometry::do_changed(f); } }