diff --git a/examples/cray_eye.cpp b/examples/cray_eye.cpp index a949f580..25d0cbcb 100644 --- a/examples/cray_eye.cpp +++ b/examples/cray_eye.cpp @@ -27,11 +27,12 @@ int main (int argc, char** argv) eyefile = std::string (argv[1]); } + // Compound eyes are tiny. We make them larger in our scene by this factor + constexpr float eye_scaleup = 1000.0f; + float psrad = 0.5f; if (argc > 2) { psrad = std::atof (argv[2]); } - auto v = mplot::Visual<>(1024, 768, "mplot::compoundray::EyeVisual"); - // We read the information from the eye file into a vector of Ommatidium objects. Ommatidium is // defined in "cameras/CompoundEyeDataTypes.h" in compound ray, mplot::Ommatidium is a // mplot/Seb's maths style equivalent. It contains 2 3D float vectors and two scalar floating point @@ -43,6 +44,18 @@ int main (int argc, char** argv) // using it, but for this example we instead make use of mplot::compoundray::readEye if (mplot::compoundray::readEye (ommatidia.get(), eyefile) == nullptr) { std::cout << "Failed to read eye\n"; return -1; } + sm::range> ommspan = sm::range>::search_initialized(); + // Use the eye spacing to control the size of the coord arrows + for (auto omm : *ommatidia.get()) { + // omm is an Ommatidium. Want to know the x, y and z spans + ommspan.update (omm.relativePosition); + } + float ca_len = eye_scaleup * ommspan.span().max() / 3.0f; + auto v = mplot::Visual<>(1024, 768, "mplot::compoundray::EyeVisual"); + v.showCoordArrows (true); + v.coordArrowsInScene (true); + v.updateCoordLengths ({ ca_len, ca_len, ca_len }, 1.0f); + // Make some dummy data to demo the eye sm::vvec ommatidiaData; ommatidiaData.linspace (0, 1, ommatidia->size()); @@ -70,7 +83,7 @@ int main (int argc, char** argv) [[maybe_unused]] auto ep = v.addVisualModel (eyevm); // ep->reinitColours(); - ep->scaleViewMatrix (1000.0f); + ep->scaleViewMatrix (eye_scaleup); v.keepOpen(); } diff --git a/mplot/NavMesh.h b/mplot/NavMesh.h index 19449ada..3557e4a3 100644 --- a/mplot/NavMesh.h +++ b/mplot/NavMesh.h @@ -794,11 +794,20 @@ namespace mplot * * \param model_to_scene The model to scene transformation for the parent of the navmesh * + * \param search_dist_mult a multiplier on the search distance. The length of vdir in this + * function should cross the landscape model. By default it's the vector from the camera + * location in the model frame of reference to the middle of the bounding box. If the vector + * is too long when finding the surface of a convex hull, such as a model of a rock, it is + * possible to mis-identify the back side of the model. However, for finding a location on a + * large, flat, one-sided landscape, we want to make vdir long. search_dist_mult is applied + * to vdir. + * * \return tuple containing: the hit point in scene coordinates; the triangle normal of the * triangle we hit; and the indices of the triangle we hit. */ std::tuple, sm::vec, std::array> - find_triangle_hit (const sm::mat44& camspace, const sm::mat44& model_to_scene) + find_triangle_hit (const sm::mat44& camspace, const sm::mat44& model_to_scene, + const float search_dist_mult = 1.0f) { sm::mat44 scene_to_model = model_to_scene.inverse(); // use camera location in gltf to start from, then find model surface. @@ -807,15 +816,16 @@ namespace mplot this->tn0 = {}; sm::vec hit = {}; sm::vec vdir = this->bb.mid() - camloc_mf; - std::tie (hit, this->ti0, this->tn0) = this->find_triangle_crossing (camloc_mf , vdir); + vdir *= search_dist_mult; + std::tie (hit, this->ti0, this->tn0) = this->find_triangle_crossing (camloc_mf, vdir); if (this->ti0[0] == std::numeric_limits::max()) { std::cout << __func__ << ": No hit\n"; } sm::vec hp_scene = (model_to_scene * hit).less_one_dim(); - constexpr bool debug = false; + constexpr bool debug = true; if constexpr (debug) { - std::cout << "found hit at " << hit << " (model); " << hp_scene << " (scene)\n"; + std::cout << "found hit at " << hit << " (model); " << hp_scene << " (scene) in direction " << vdir << "\n"; // Check we'll get a hit when we compute_mesh_movement: sm::vec, 3> tv_mf = this->triangle_vertices (this->ti0); std::cout << "tn0: " << this->tn0 << ", length " << this->tn0.length() << std::endl;