void reduction_entropy:: update_normal(shared_surfel target_surfel_ptr, shared_entropy_surfel_vector const neighbour_ptrs) const{ vec3f new_normal(0.0, 0.0, 0.0); real weight_sum = 0.f; new_normal = target_surfel_ptr->normal(); weight_sum = 1.0; for(auto const neighbour_ptr : neighbour_ptrs){ shared_surfel target_surfel_ptr = neighbour_ptr->contained_surfel; real weight = target_surfel_ptr->radius(); weight_sum += weight; new_normal += weight * target_surfel_ptr->normal(); } if( weight_sum != 0.0 ) { new_normal /= weight_sum; } else { new_normal = vec3r(0.0, 0.0, 0.0); } target_surfel_ptr->normal() = scm::math::normalize(new_normal); }
inline Eigen::Affine3f tf_from_plane_model(float a, float b, float c, float d) { Eigen::Vector3f new_normal(a, b, c); Eigen::Vector3f old_normal(0, 0, 1); Eigen::Vector3f v = old_normal.cross(new_normal); float s2 = v.squaredNorm(); float cc = old_normal.dot(new_normal); Eigen::Matrix3f v_cross; v_cross << 0, -v(2), v(1), v(2), 0, -v(0), -v(1), v(0), 0; Eigen::Matrix3f rot = Eigen::Matrix3f::Identity() + v_cross + v_cross * v_cross * (1 - cc) / s2; Eigen::Affine3f arot(rot); // Create a transform where the rotation component is given by the rotation axis as the normal vector (a, b, c) // and some arbitrary angle about that axis and the translation component is -d in the z direction after // that rotation (not the original z direction, which is how transforms are usually defined). auto result = Eigen::Translation3f(0, 0, d) * arot.inverse(); return result; }
void cylinder(ProtectedPtr<Mesh> mesh, float diameter, float length, int32_t segments, int32_t stacks) { float radius = diameter * 0.5; float delta_angle = (kmPI * 2.0) / (float) segments; float delta_height = length / (float) stacks; int offset = 0; auto smi = mesh->new_submesh(); auto* buffer = mesh->submesh(smi); for(auto i = 0; i <= stacks; ++i) { for(auto j = 0; j <= segments; ++j) { float x0 = radius * cosf(delta_angle * j); float z0 = radius * sinf(delta_angle * j); kglt::Vec3 new_point(x0, delta_height * i, z0); kglt::Vec3 new_normal = kglt::Vec3(x0, 0, z0).normalized(); kglt::Vec2 new_uv = kglt::Vec2(j / (float) segments, i / (float) stacks); mesh->shared_data().position(new_point); mesh->shared_data().diffuse(kglt::Colour::WHITE); mesh->shared_data().normal(new_normal); mesh->shared_data().tex_coord0(new_uv); mesh->shared_data().move_next(); if(i != stacks) { buffer->index_data().index(offset + segments + 1); buffer->index_data().index(offset); buffer->index_data().index(offset + segments); buffer->index_data().index(offset + segments + 1); buffer->index_data().index(offset + 1); buffer->index_data().index(offset); } ++offset; } } // Now cap the cylinder auto center_index = offset; // Add a central point at the base mesh->shared_data().position(kglt::Vec3()); mesh->shared_data().normal(kglt::Vec3(0, -1, 0)); mesh->shared_data().tex_coord0(kglt::Vec2()); mesh->shared_data().move_next(); ++offset; for(auto j = 0; j <= segments; ++j) { float x0 = cosf(j * delta_angle); float z0 = sinf(j * delta_angle); kglt::Vec3 new_point(x0 * radius, 0, z0 * radius); kglt::Vec3 new_normal(0, -1, 0); kglt::Vec2 new_uv(x0, z0); mesh->shared_data().position(new_point); mesh->shared_data().normal(new_normal); mesh->shared_data().tex_coord0(new_uv); mesh->shared_data().move_next(); if(j != segments) { buffer->index_data().index(center_index); buffer->index_data().index(offset); buffer->index_data().index(offset + 1); } } center_index = offset; // Add a central point at the top mesh->shared_data().position(kglt::Vec3(0, length, 0)); mesh->shared_data().normal(kglt::Vec3(0, 1, 0)); mesh->shared_data().tex_coord0(kglt::Vec2()); mesh->shared_data().move_next(); ++offset; for(auto j = 0; j <= segments; ++j) { float x0 = cosf(j * delta_angle); float z0 = sinf(j * delta_angle); kglt::Vec3 new_point(x0 * radius, length, z0 * radius); kglt::Vec3 new_normal(0, 1, 0); kglt::Vec2 new_uv(x0, z0); mesh->shared_data().position(new_point); mesh->shared_data().normal(new_normal); mesh->shared_data().tex_coord0(new_uv); mesh->shared_data().move_next(); if(j != segments) { buffer->index_data().index(center_index); buffer->index_data().index(offset + 1); buffer->index_data().index(offset); } } mesh->shared_data().done(); buffer->index_data().done(); }