cluster_system - ryzom/ryzomcore GitHub Wiki


title: Cluster and Portal Systems description: A complete solution for clipping indoor scenes using clusters and portals published: true date: 2023-03-01T05:21:34.907Z tags: editor: markdown dateCreated: 2022-03-13T22:28:42.962Z

Cluster Systems

A Cluster System (CS for short) is a set of clusters and portals. Cluster systems is associated with one instance group (or IG for short.) Various CS information is saved into the IG, such as the description. A CS is used to clip objects referenced in the associated IG or other objects. Other objects can be unrelated to the associated instance group but must be inserted into the CS at runtime to be included in the CS.

Cluster systems can be placed into hierarchies of cluster systems such that one cluster system could have one or more child cluster systems and the landscape is the parent of all cluster systems in the engine. Linking to a cluster system can be done using the IG user implementation:

bool NL3D::UInstanceGroup::linkToParentCluster(UInstanceGroup *father)

When exporting objects you must make sure that the Clusterize option is flagged on objects referenced in the instance group that's linked to the cluster system.

Clusters

A cluster is a convex polyhedron. It can be created in 3DSMAX using a mesh flagged as cluster with NeLExport. All the objects referenced in the IG associated with the CS that intersects the cluster are associated with the cluster. At least one vertex of an object must be in the cluster to consider this object is associated with the cluster. A given object can be associated with more than one cluster.

At runtime 3D objects that are not associated with a cluster are tested against the view frustum (VF) to check if they are visible. In the same way, clusters are tested against the VF. When a cluster is tested against a VF, the objects associated with the cluster are tested against the VF too. If an object associated with a cluster never intersects the VF, it won't be rendered.

If the camera is placed into a CS, the cluster that contains the camera will be tested against the VF. To place the camera into a CS, use:

void NL3D::UTransform::setClusterSystem(UInstanceGroup *pIG)

A cluster can be flagged as "Parent Visible" with NeLExport, it means that if this cluster is tested against the VF, the parent cluster will be tested by the VF too.

A cluster can be flagged as "Visible From Parent" with NeLExport, it means that if its parent cluster is tested against the VF, the cluster will be tested by the VF too.

Two clusters in the same CS can be linked together using a portal.

Portals

A portal is a convex and flat polygon. It can be created in 3DSMAX using a mesh flagged as portal with NeLExport.

A portal must be placed between two clusters,all the vertices must be completly enclosed in the intersection of two clusters.

When a cluster is tested against the VF, for each portal in this cluster, the VF is clipped against the portal, and if the VF is not empty, the second cluster is tested against the remainder of the VF. A VF (called vf0) clipped against a portal is the smallest VF enclosed by vf0 that encloses the portal.

Hierarchical organization of CS depends on the properties of at least one cluster within the CS. A cluster with both 'Visible From Parent' and 'Parent Visible' must exists in order for a CS to be linked with its parent in the CS hierarchy. This specific cluster must also obey an additional constraint : a camera placed in the parent cluster should see the FRONT FACE of the portals contained in the specific cluster and not the back face.

A portal can be dynamic, ie, it can be opened / closed at runtime. (When a door is open / close for exemple). If you want to set the dynamic aspect of a portal, flag it "Dynamic portal" in NelExport. At runtime, you can get / set it using:

void NL3D::UTransform::getDynamicPortals(std::vector<std::string> &names)
bool NL3D::UTransform::getDynamicPortal(std::string &name)
void NL3D::UTransform::setDynamicPortal(std::string &name, bool opened)

Runtime

At run time, the only thing to do, after loading and organizing the CS into a hierarchy, is to place each movable instances into the CS it belongs to.

There is no information related to moving objects in a CS, hence NeL has no way to know which moving object should be placed in a given CS.

Moving objects use the PACS collision informations for this purpose. In addition they are pre-calculated and use less CPU than testing intersection of the moving object with the CS.

To place a moving object within a CS, use an indoor collision mesh per CS. If your moving object is over the collision mesh, then insert it into the corresponding CS. To place a NeL instance into a CS, use:

void NL3D::UTransform::setClusterSystem(UInstanceGroup *pIG)

Credits

  • Original document by Cyril Corvazier
  • Corrections by Matthieu Besson and Loic Dachary
  • Transcribed to Wiki by Matt Raykowski
⚠️ **GitHub.com Fallback** ⚠️