KeyPaths are explained in our documentation. When correctly formed, a key path unambiguously describes the location of a leaf segment in the scene graph hierarchy. A key to the leaf node itself is insufficient because it could theoretically be included in multiple locations in the scene graph.
A key path is needed to correctly take into account cameras and matrix transforms when converting coordinates between systems. The key path is a collection of keys, going from the leaf to the root of the scene graph. The key path can omit some of the keys between the leaf and the root, but MUST contain all the include link between leaf and root.
If you are using Sprockets, consider using a function called GetKeyPath().
Basic Example
Consider the following segment hierarchy;
The model segment contains two child segments βaβ and βbβ. Segment βbβ includes segment βcβ which exists under segment βaβ. Segment βcβ contains a sphere.
Hereβs the sample code (from our HPS mfc_sandbox):
1 void generateKeyPath(SegmentKey& key, KeyPath& kp)
2 {
3 kp += key;
4 while (key.Type() == Type::SegmentKey && key.HasOwner())
5 {
6 SegmentKey segKey = key.Owner();
7 kp += segKey;
8 key = key.Up();
9 }
10 }
11
12void CHPSView::OnUserCode2()
13 {
14 SegmentKey modelSeg = GetCanvas().GetAttachedLayout().GetAttachedView().GetAttachedModel().GetSegmentKey();
15
16 SegmentKey aSeg = modelSeg.Subsegment("a");
17 aSeg.GetMaterialMappingControl().SetFaceColor(HPS::RGBAColor(1, 0, 0));
18 aSeg.GetConditionControl().SetCondition("seg a");
19
20 SegmentKey cSeg = aSeg.Subsegment("c");
21 SphereKit sphereKit;
22 sphereKit.SetCenter(Point(0, 0, 0)).SetRadius(0.5f).SetBasis(Vector(1, 1, 0), Vector(1, 0, 0));
23 SphereKey sphereKey = cSeg.InsertSphere(sphereKit);
24
25 SegmentKey bSeg = modelSeg.Subsegment("b");
26 bSeg.IncludeSegment(cSeg);
27 bSeg.GetModellingMatrixControl().Translate(1.125, 0, 0);
28 bSeg.GetConditionControl().SetCondition("seg b");
29
30 KeyPath keyPath;
31 SegmentKey myKey;
32 SearchResults searchResults;
33 SearchOptionsKit sok;
34 sok.SetSearchSpace(Search::Space::SubsegmentsAndIncludes)
35 .SetCriteria(Search::Type::Sphere)
36 .SetBehavior(HPS::Search::Behavior::Exhaustive);
37 size_t numResults = modelSeg.Find(sok, searchResults);
38 SearchResultsIterator it = searchResults.GetIterator();
39 while (it.IsValid())
40 {
41 Key key = it.GetItem();
42 if (key.Type() == Type::SphereKey && key == sphereKey)
43 {
44 SegmentKey segKey = key.Owner();
45 if (segKey.Name() == "c")
46 generateKeyPath(segKey, keyPath);
47 }
48 it.Next();
49 }
50 // Use the generated KeyPath
51 HPS::UTF8Array conditions;
52 keyPath.ShowNetConditions(conditions);
53 assert(strcmp("seg a", conditions[0].GetBytes()) == 0);
54
55 // Manually define a keypath for the second included instance
56 KeyPath keyPathManual;
57 keyPathManual.PushBack(cSeg);
58 keyPathManual.PushBack(bSeg);
59 keyPathManual.PushBack(modelSeg);
60
61 HPS::UTF8Array conditionsManual;
62 keyPathManual.ShowNetConditions(conditionsManual);
63 assert(strcmp("seg b", conditionsManual[0].GetBytes()) == 0);
64
65 GetCanvas().UpdateWithNotifier().Wait();
66}
The beginning of OnUserCode2()
creates the diagrammed scene including a couple conditions used to illustrate different results based on two KeyPaths.
A condition called βseg aβ is defined in segment βaβ.
Similarly, a condition called βseg bβ is defined in segment βbβ.
The application creates the following simple rendering;
A basic search (modelSeg.Find()
) looks for all spheres under the model in child and include segments. You will notice that numResults
returns 1. There are two instances of the sphere in the scene but they have the same key.
The function generateKeyPath()
walks up the hierarchy building a KeyPath using key.Owner()
. The resulting KeyPath includes segment βcβ, segment βaβ and the model segment. Calling ShowNetConditions()
with this key path returns βseg aβ.
Finally, another KeyPath is built manually with the knowledge that segment βbβ includes segment βcβ. Calling ShowNetConditions()
with this key path (i.e. segment βcβ, segment βbβ and the model segment) returns βseg bβ. This type of knowledge about the scene graph is often required to build the appropriate KeyPath for a particular application.
This example illustrates different results depending on the KeyPath.