.. highlight:: shell ================================ Non-Cartesian Coordinate Systems ================================ Initial support for volume rendering of data defined in 3D non-cartesian coordinate systems was added in yt_idv 0.5.0 for block-AMR data in spherical coordinates. While not all rendering methods and annotations are supported for spherical coordinates, yt_idv can directly calculate maximum intensity projections, integrative projections and projection with custom transfer functions without any pre-interpolation or re-gridding. .. image:: resources/sph-vr-example.png :align: center The approach for handling data defined in non-cartesian coordinates is to pre-calculate cartesian bounding boxes of the data blocks. The rendering pipeline then uses the cartesian bounding boxes to calculate ray entry/exit points during ray tracing. Between the entry/exit points, the cartesian coordinates of the ray position are converted to the native coordinates of the data, which is used to sample the texture maps (which are stored in native coordinates). The initial implementaiton of the algorithm uses the ray entry/exit points of the cartesian bounding boxes, and so not all points along the ray are gauranteed to lie within the bounds of the data -- though these data points will be discarded during ray tracing, it does mean that a larger number of samples along the ray may be required to ensure the underlying non-cartesian element is properly sampled compared to the standard cartesian data ray tracing (this is controlled by the ``sample_factor`` attribute of the ``BlockRendering`` component). At present, supported non-cartesian coordinate systems include Spherical Coordinates with (r, theta, phi), where r is radius, theta is co-latitude (between 0, pi) and phi is azimuth (between 0, 2pi), following yt conventions. ---------------------------- Notes on further development ---------------------------- Further contributions are welcome for adding support for the remaining 3d non-cartesian coordinate systems that yt supports that are not yet supported here (3d cylindrical, 3d geographic) as well as for adding support for non-cartesian coordinate systems in additional yt_idv components. To add support for additional non-cartesian coordinate systems requires two steps: #. Add methods for calcualting cartesian bounding boxes #. Add support to the rendering pipeline **************************************************** Add methods for calcualting cartesian bounding boxes **************************************************** The cartesian bounding box methods are defined in ``yt_idv/coordinate_utilities.pyx``. When adding support for a new coordiante system, implement a new ``MixedCoordBBox`` child class, following the ``SphericalMixedCoordBBox`` example. The main method is ``get_cartesian_bbox``, which returns the cartesian bounding box for a single non-cartesian element. Once implemented, ``yt_idv.cartesian_bboxes`` can be used to calculate bounding boxes for arrays of elements. Next, ``yt_idv.scene_data.block_collection.BlockCollection`` should be updated (mostly in ``add_data`` and ``_set_geometry_attributes``) to handle the new coordinate system following the example for spherical coordinates. These two steps will handle the CPU-side of the calculations, next you need to update the rendering pipeline. ************************************* Add support to the rendering pipeline ************************************* A number of changes are required related to the rendering pipeline for the ``block_rendering`` shader program. In order to avoid shader code duplication for different coordinate systems and also avoid overly branching code within the shader itself, pre-processor directives are used to provide switches between shader behavior for different coordinate systems. The ``NONCARTESIAN_GEOM`` directive is for functionality that should cover shared behavior between all non-cartesian coordinate systems. For example, ``grid_position.vert.glsl``, ``grid_expand.geom.glsl`` and ``ray_tracing.frag.glsl`` all use ``NONCARTESIAN_GEOM`` for passing along the additional vertex attributes related to the cartesian bounding boxes. Functionality specific to a coordinate system should be defined with a new pre-processor directive flag. For spherical coordinates, this is ``SPHERICAL_GEOM``, and is used in ``ray_tracing.frag.glsl`` for defining and using the functions for transforming from cartesian to spherical coordinates. To add a new one for use in the shaders, add a new entry to the ``yt_idv.scene_components.base_component._geom_directives`` dictionary and then wrap any functionality specific to your new coordinate system within pre-processor checks, for example:: #ifdef SPHERICAL_GEOM vec3 cart_to_sphere_vec3(vec3 v) { // transform a single point in cartesian coords to spherical vec3 vout = vec3(0.,0.,0.); // ---- code trimmed for clarity ---- // return vout; } #endif When the shader program compiles, the above function will only be defined for rendering data in spherical coordinates. At a minimum, you will need to add a function to handle the coordinate conversion from the cartesian position of the ray to the native coordinates of your data.