# OGeo¶

The canonical OGeo instance resides in OScene and is
instanciated and has *OGeo::convert* called from *OScene::init*.
*OGeo::convert* loops over the GMergedMesh within GGeo/GGeoLib
converting them into optix::Group or optix::GeometryGroup
and adds them to m_top(optix::Group).

The first ridx 0 GMergedMesh is non-instanced, the rest are instanced and hold the necessary transform and identity buffers.

Details of geometry tree are documented with the OGeo::convert method.

## OGeo Details¶

### Table 2, OptiX Manual¶

Parent Node Type | Child Node Types | Associated Node Types |
---|---|---|

Geometry | None | Material |

Acceleration | None | |

GeometryInstance | Geometry | Material |

GeometryGroup | GeometryInstance | Acceleration |

Transform | GeometryGroup | |

Selector | Transform | |

Group | GeometryGroup | Acceleration |

- Group contains : rtGroup, rtGeometryGroup, rtTransform, or rtSelector
- Transform houses single child : rtGroup, rtGeometryGroup, rtTransform, or rtSelector (NB not GeometryInstance)
- GeometryGroup is a container for an arbitrary number of geometry instances, and must be assigned an Acceleration
- Selector contains : rtGroup, rtGeometryGroup, rtTransform, and rtSelector

### Geometry tree that allows instance identity¶

JUNO has 6 repeated pieces of geometry. The two different types of photomultiplier tubes (PMTs) are by far the most prolific with 20k of one type (20inch) and 36k of another (3inch)

The geometry tree follows that show in OptiX 6.0.0 manual Fig 3.4 x6

```
m_top (Group) m_top_accel
ggg (GeometryGroup) m_ggg_accel global non-instanced geometry from merged mesh 0
ggi (GeometryInstance)
assembly.0 (Group) m_assembly_accel 1:1 with instanced merged mesh (~6 of these for JUNO)
xform.0 (Transform) (at most 20k/36k different transforms)
perxform (GeometryGroup)
accel[0] m_instance_accel common accel within each assembly
pergi (GeometryInstance) distinct pergi for every instance, with instance_index assigned
omm (Geometry) the same omm and mat are child of all xform/perxform/pergi
mat (Material)
xform.1 (Transform)
perxform (GeometryGroup)
pergi (GeometryInstance)
accel[0]
omm (Geometry)
mat (Material)
... for all the many thousands of instances of repeated geometry ...
assembly.1 (Group) (order ~6 repeated assemblies for JUNO)
xform.0
... just like above ...
```

- transforms can only be contained in “group” or another transform so add top level group with another acceleration structure
- transforms must be assigned exactly one child of type rtGroup, rtGeometryGroup, rtTransform, or rtSelector,

### Alternate Tree Layout¶

- (Group)

- (Transform)

- (GeometryGroup)

- (GeometryInstance)

- (Geometry)
- (Material)

### OptiX 7 terminology change¶

OptiX 7 changes terminology in a way which may inform concerning which trees can be handled in RT cores

- Geometry Group -> Geometry AS (only primitives)
- Group -> Instance AS
- Transform -> just input to Instance AS at build

### Why proliferate the *pergi* ? So can assign an instance index to it : ie know which PMT gets hit¶

- Need to assign an index to each instance means need a GeometryInstance beneath the xform ?
- “Geometry” and “Material” can also hold variables, but that doesnt help for instance_index
- as there is only one geometry and material instance for each assembly

### Could the perxform GeometryGroup be common to all ?¶

NO, needs to be a separate GeometryGroup into which to place the distinct pergi GeometryInstance required for instanced identity

### Where to put the RayLOD Selector ? RAYLOD IS NOT CURRENTLY IN USE¶

- LOD : Level Of Detail
- level0 : most precise/expensive used for ray.origin inside instance sphere
- level1 : cheaper alternative used for ray.origin outside instance sphere

The RayLOD idea is to switch geometry based on the distance from it, using radius of outermost solid origin centered bounding sphere with safety margin see notes/issues/can-optix-selector-defer-expensive-csg.rst

Given that the same omm is used for all pergi… it would seem most appropriate to arrange the selector in common also, as all instances have the same simplified version of their geometry too..

TODO: Currently all the accelerations are using Sbvh/Bvh. Investigate if container groups might be better as “pass through” NoAccel as the geometryGroup and groups they contain have all the geometry.

## OGeo::convert¶

Converts the GMergedMesh instances from (m_geolib)GGeoLib into optix::Group and optix::GeometryGroup and adds them to m_top(optix::Group).

## OGeo::makeAnalyticGeometry¶

The GParts instance that this operates from will usually have been concatenated from multiple other GParts instances, one for each NCSG solid. GParts concatenation happens during GMergedMesh formation in GMergedMesh::mergeVolumeAnalytic.

For repeated geometry note how all bar one of the geometry buffers are small. Only the idBuf is large and usage GPU side requires use of the instance_index.