Using Group Objects
QuickDraw 3D provides functions that you can use to create a group, add objects to a group, remove objects from a group, and dispose of a group. It also provides functions that you can use to count the number of objects in a group, access objects by their position in the group, draw a group, pick objects in a group, and perform other operations on group objects. This section illustrates how to use some of these functions. In particular, it shows:
- how to create groups and add objects to them
- how to operate on all objects in a group, or on all objects of a particular type in a group
Creating Groups
You create a new light group, for example, by calling theQ3LightGroup_New
function. If there is sufficient memory to create the group,Q3LightGroup_New
returns to your application a reference to a group object, which you pass to other group routines. The new group is initially empty, and you add objects to the group by calling QuickDraw 3D routines (such asQ3Group_AddObject
). When an object is added to a group, its reference count is incremented. (QuickDraw 3D uses the reference count to ensure that an object is not prematurely disposed.) If you don't want to maintain references to all the objects inside a group, you can use the technique illustrated in Listing 10-1.
myGroup = Q3LightGroup_New(); myLight = Q3SpotLight_New(mySpotLightData); Q3Group_AddObject(myGroup, myLight); Q3Object_Dispose(myLight);By callingQ3Object_Dispose
, you decrement the light's reference count once it's been added to the light group. When the group itself is later disposed of, QuickDraw 3D decrements the light's reference count, which may cause it also to be disposed of.Accessing Objects by Position
You can iterate through a group by getting the position of its first object and then getting the positions of any subsequent objects. All groups, regardless of type, are stored in a single list which you can step through only by calling QuickDraw 3D routines.Listing 10-2 shows how to access all the lights in a light group. The
MyTurnOnOrOffAllLights
function takes a view parameter and an on/off state value. It turns all the lights in the view's light group on or off, as specified by the state value.Listing 10-2 Accessing all the lights in a light group
TQ3Status MyTurnOnOrOffViewLights (TQ3ViewObject myView, TQ3Boolean myState) { TQ3GroupObject myGroup; /*the view's light group*/ TQ3GroupPosition myPos; /*a group position*/ TQ3Object myLight; /*a light*/ TQ3Status myResult; /*a result code*/ myResult = Q3View_GetLightGroup(myView, &myGroup); if (myResult == kQ3Failure) goto bail; for (Q3Group_GetFirstPosition(myGroup, &myPos); myPos != NULL; Q3Group_GetNextPosition(myGroup, &myPos)) { myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ } return(kQ3Success); bail: return(kQ3Failure); }You can use the looping technique illustrated in Listing 10-2 to traverse ordered display groups as well, as shown in Listing 10-3. The functionMyToggleOrderedGroupLights
traverses an ordered display group and toggles any lights it finds. Notice thatMyToggleOrderedGroupLights
calls theQ3Group_GetFirstPositionOfType
function to find the position of the first light in the group.Listing 10-3 Accessing all the lights in an ordered display group
TQ3Status MyToggleOrderedGroupLights (TQ3GroupObject myGroup) { TQ3GroupPosition myPos; /*a group position*/ TQ3Object myLight; /*a light*/ TQ3Boolean myState; /*a light state*/ TQ3Status myResult; /*a result code*/ for (Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos); myPos != NULL; Q3Group_GetNextPositionOfType(myGroup, kQ3ShapeTypeLight, &myPos)) { myResult = Q3Group_GetPositionObject(myGroup, myPos, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_GetState(myLight, &myState); myState = !myState; /*toggle the light state*/ myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ } return(kQ3Success); bail: return(kQ3Failure); }It's also possible to find the position of the next object in an ordered display group by calling theQ3Group_GetNextPosition
function.Q3Group_GetNextPosition
is not, however, guaranteed to return a position of an object that is of the same type as the object immediately before it. If you useQ3Group_GetNextPosition
to iterate through an ordered display group, you must therefore make sure not to step past the part of the list that contains objects of the type you're interested in. Listing 10-4 shows, in outline, how to callQ3Group_GetNextPosition
to iterate safely through an object type in an ordered display group.Listing 10-4 Accessing all the lights in an ordered display group using
Q3Group_GetNextPosition
TQ3GroupPosition myFirst; /*group position of first light*/ TQ3GroupPosition myLast; /*group position of last light*/ TQ3Object myLight; /*a light*/ TQ3Status myResult; /*a result code*/ Q3Group_GetFirstPositionOfType(myGroup, kQ3ShapeTypeLight, &myFirst); if (myFirst) { Q3Group_GetLastPositionOfType(myGroup, kQ3ShapeTypeLight, &myLast); do { myResult = Q3Group_GetPositionObject(myGroup, myFirst, myLight); if (myResult == kQ3Failure) goto bail; myResult = Q3Light_GetState(myLight, &myState); myState = !myState; /*toggle the light state*/ myResult = Q3Light_SetState(myLight, myState); Q3Object_Dispose(myLight); /*balance reference count of light*/ Q3Group_GetNextPosition(myGroup, &myFirst); } while (myFirst != myLast); }
Main | Top of Section | What's New | Apple Computer, Inc. | Find It | Feedback | Help