Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Current »

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):

void generateKeyPath(SegmentKey& key, KeyPath& kp)
{
	kp += key;
	while (key.Type() == Type::SegmentKey && key.HasOwner())
	{
		SegmentKey segKey = key.Owner();
		kp += segKey;
		key = key.Up();
	}
}

void CHPSView::OnUserCode2()
{
	SegmentKey modelSeg = GetCanvas().GetAttachedLayout().GetAttachedView().GetAttachedModel().GetSegmentKey();

	SegmentKey aSeg = modelSeg.Subsegment("a");
	aSeg.GetMaterialMappingControl().SetFaceColor(HPS::RGBAColor(1, 0, 0));
	aSeg.GetConditionControl().SetCondition("seg a");

	SegmentKey cSeg = aSeg.Subsegment("c");
	SphereKit sphereKit;
	sphereKit.SetCenter(Point(0, 0, 0)).SetRadius(0.5f).SetBasis(Vector(1, 1, 0), Vector(1, 0, 0));
	SphereKey sphereKey = cSeg.InsertSphere(sphereKit);

	SegmentKey bSeg = modelSeg.Subsegment("b");
	bSeg.IncludeSegment(cSeg);
	bSeg.GetModellingMatrixControl().Translate(1.125, 0, 0);
	bSeg.GetConditionControl().SetCondition("seg b");

	KeyPath keyPath;
	SegmentKey myKey;
	SearchResults searchResults;
	SearchOptionsKit sok;
	sok.SetSearchSpace(Search::Space::SubsegmentsAndIncludes)
		.SetCriteria(Search::Type::Sphere)
		.SetBehavior(HPS::Search::Behavior::Exhaustive);
	size_t numResults = modelSeg.Find(sok, searchResults);
	SearchResultsIterator it = searchResults.GetIterator();
	while (it.IsValid())
	{
		Key key = it.GetItem();
		if (key.Type() == Type::SphereKey && key == sphereKey)
		{
			SegmentKey segKey = key.Owner();
			if (segKey.Name() == "c")
				generateKeyPath(segKey, keyPath);
		}
		it.Next();
	}
	// Use the generated KeyPath
	HPS::UTF8Array conditions;
	keyPath.ShowNetConditions(conditions);
	assert(strcmp("seg a", conditions[0].GetBytes()) == 0);

	// Manually define a keypath for the second included instance
	KeyPath keyPathManual;
	keyPathManual.PushBack(cSeg);
	keyPathManual.PushBack(bSeg);
	keyPathManual.PushBack(modelSeg);

	HPS::UTF8Array conditionsManual;
	keyPathManual.ShowNetConditions(conditionsManual);
	assert(strcmp("seg b", conditionsManual[0].GetBytes()) == 0);

	GetCanvas().UpdateWithNotifier().Wait();
}

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.

  • No labels