CC3World is a CC3Node that manages a 3D scene. More...
#import <CC3World.h>
Public Member Functions | |
(void) | - addContentFromPODFile: |
(void) | - addContentFromPODResourceFile: |
(void) | - cleanCaches |
(void) | - initializeWorld |
(void) | - pause |
(void) | - play |
(void) | - updateWorld: |
(void) | - visit |
Static Public Member Functions | |
(id) | + world |
Properties | |
CC3Camera * | activeCamera |
ccColor4F | ambientLight |
CC3NodeSequencer * | drawingSequencer |
BOOL | isRunning |
BOOL | isUsingDrawingSequence |
ccTime | maxUpdateInterval |
CC3World has the following responsibilities:
When creating a 3D application, you will almost always create a subclass of CC3World to define the control, features, and behaviour of your 3D world suitable to your application. In your CC3World subclass, your will typically override the following two template methods:
In these two methods, you can manipulate most nodes by setting their properties. You can move and orient nodes using the node's location, rotation and scale properties, and can show or hide nodes with the node's visible property.
To access nodes in your world, you can use the method getNodeNamed: on the CC3World (or any node). However, if you need to access the same node repeatedly, for example to update it on every frame, it's highly recommended that you retrieve it once and then cache it in an instance variable in your CC3World instance.
By default, both the initializeWorld and update: methods do nothing. Subclasses do not need to invoke this default superclass implementations in the overridden methods. The update: method is defined in the CC3Node class. See the documentation there.
During drawing, the nodes can be traversed in the hierarchical order of the node structural assembly, starting at the CC3World instance that forms the root node of the node assembly. Alternately, and preferrably, the CC3World can use a CC3NodeSequencer instance to arrange the nodes into a linear sequence, ordered and grouped based on definable sorting priorities. This is beneficial, because it allows the application to order and group drawing operations in ways that reduce the number and scope of state changes within the GL engine, thereby improving performance and throughput.
For example, when drawing, nodes could be grouped by the drawing sequencer so that opaque objects are drawn prior to blended objects, and an application with many objects that use the same material or mesh can be sorted so that nodes with like materials or meshes are grouped together. It is highly recommended that you use a CC3NodeSequencer, and this is the default configuration for CC3World instances.
The CC3World maintains this drawing sequence separately from the hierarchical node assembly. This allows the maintenance of the hierarchical parent-child relationships for operations such as movement and transformations, while simultaneously enabling more efficient drawing operations through node drawing sequencing.
An instance of CC3World is held by an instance of CC3Layer, which is a subclass of the cocos2d CCLayer class, and can participate with other cocos2d layers and CCNodes in an overall cocos2d scene. During drawing, the CC3Layer delegates all 3D operations to its CC3World instance. You will also typically create a subclass of CC3Layer that is customized for your application. In most cases, you will add methods and state to both your CC3World and CC3Layer subclasses to facilitate user interaction.
Depending on the complexity of the application, it may instantiate a single CC3World, instance, or multiple instances if the application progresses from scene to scene. Similarly, the application may have a single CC3Layer, or multiple CC3Layers. Each CC3Layer may have its own CC3World instance, or may share a single instance.
You must add at least one CC3Camera to your 3D world to make it viewable.
To maximize GL throughput, all OpenGL ES 1.1 state is tracked by the singleton instance [CC3OpenGLES11Engine engine]. CC3OpenGLES11Engine only sends state change calls to the GL engine if GL state really is changing. It is critical that all changes to GL state are made through the CC3OpenGLES11Engine singleton. When adding or overriding functionality in this framework, do NOT make gl* function calls directly if there is a corresponding state change tracker in the CC3OpenGLES11Engine singleton. Route the state change request through the CC3OpenGLES11Engine singleton instead.
- (void) addContentFromPODFile: | (NSString *) | aFilepath |
Loads the POD file at the specified path, extracts the assembled and configured nodes from the file into an instance of CC3PODResourceNode, and adds the CC3PODResourceNode as child node to this CC3World instance.
The specified file path must be an absolute path.
- (void) addContentFromPODResourceFile: | (NSString *) | aRezPath |
Loads the POD file at the specified resource path, extracts the assembled and configured nodes from the file into an instance of CC3PODResourceNode, and adds the CC3PODResourceNode as child node to this CC3World instance.
The specified file path is a path relative to the resource directory. Typically this means that the specified path can just be the name of the file, with no path information.
- (void) cleanCaches |
Forces a purging of any unneeded cached model data.
This is invoked when the application receives a memory warning. Subclasses should override to release any unneeded cached model data, and call this superclass implementation to allow for further cleanup.
- (void) initializeWorld |
This template method is where a subclass should populate the 3D world models.
This can be accomplished through a combination of instantiting model objects directly and loading them from model data files exported from a 3D editor.
This CC3World instance forms the base of a structural tree of nodes. Model objects are added as nodes to this root node instance using the addChild: method.
When loading from files, or adding large node assemblies, you can access individual nodes using the getNodeNamed: method, if you need to set futher initial state.
If you will need to access the same node repeatedly, for example to update it on every frame, it's highly recommended that you retrieve it once in this method, and cache it in an instance variable in your CC3World subclass instance.
You must add at least one CC3Camera to your 3D world to make it viewable. This can be instantiated directly, or loaded from a file as part of a node assembly.
By default, this method does nothing. Subclasses do not need to invoke this default superclass implementation in the overridden method.
- (void) pause |
Pauses the dynamics of the 3D world model by setting the isRunning property to NO.
This does not affect the movement of nodes controlled by CCIntervalActions.
- (void) play |
Starts the dynamics of the 3D world model by setting the isRunning property to YES.
- (void) updateWorld: | (ccTime) | dt |
This method is invoked periodically when the components in the CC3World are to be updated.
Typcially this method is invoked automatically from a CC3Layer instance via a scheduled update, but may also be invoked by some other periodic operation, or even directly by the application.
This method is invoked asynchronously to the frame rendering animation loop, to keep the processing of model updates separate from OpenGL ES drawing.
The dt argument gives the interval, in seconds, since the previous update. This value can be used to create realistic real-time motion that is independent of specific frame or update rates. If the maxUpdateInterval property has been set, this method will clamp dt to that limit. See the description of maxUpdateInterval for more information about clamping the update interval.
If this instance is not running, as indicated by the isRunning property, this method does nothing.
As implemented, this method performs the following processing steps, in order:
To customize the behaviour of the 3D model world, sublcasses should override the update: method. Sublcasses should not override this updateWorld: method.
- (void) visit |
This method is invoked periodically when the objects in the CC3World are to be drawn.
Typcially this method is invoked automatically from the draw method of the CC3Layer instance. This method is invoked asynchronously to the model updating loop, to keep the processing of OpenGL ES drawing separate from model updates.
This implementation invokes visitWithVisitor: with a CC3NodeDrawingVisitor containing the activeCamera's frustum. Does nothing if the visible property of this instance is NO.
To maximize GL throughput, all OpenGL ES 1.1 state is tracked by the singleton instance [CC3OpenGLES11Engine engine]. CC3OpenGLES11Engine only sends state change calls to the GL engine if GL state really is changing. It is critical that all changes to GL state are made through the CC3OpenGLES11Engine singleton. When overriding this method, or any other 3D drawing features, do NOT make gl* function calls directly if there is a corresponding state change tracker in the CC3OpenGLES11Engine singleton. Route the state change request through the CC3OpenGLES11Engine singleton instead.
+ (id) world |
Allocates and initializes an autoreleased unnamed instance with an automatically generated unique tag value.
The tag value is generated using a call to nextTag.
- (CC3Camera *) activeCamera [read, write, retain] |
The 3D camera that is currently displaying the scene of this world.
You can set this property directly, or if this property is not set directly, it will be set automatically to the first CC3Camera added to this world via the addChild: method, including cameras contained somewhere in a structural assembly of nodes whose root node was added to this instance via addChild:. In this way, adding the root node of a node assembly loaded from a file will set the activeCamera property to the first camera found in the assembly, if the property was not already set.
The converse occurs when a camera is removed from the world using the removeChild: method. The camera will be removed as the activeCamera, and the second camera that was previously added (assuming more than one was added) will automatically be set as the activeCamera. Again, this is true even if the root node of a large assembly containing the active camera is removed from the world using the removeChild: method.
The initial value is nil. You must add at least one CC3Camera to your 3D world to make it viewable.
- (ccColor4F) ambientLight [read, write, assign] |
The color of the ambient light of the world.
This is independent of any CC3Light nodes that are added as child nodes. You can use this to provide general flat lighting in your world without having to add light nodes.
The initial value is set to kCC3DefaultLightColorAmbientWorld.
- (CC3NodeSequencer *) drawingSequencer [read, write, retain] |
The node sequencer being used by this instance to order the drawing of child nodes.
During drawing, the nodes can be traversed in the hierarchical order of the node structural assembly, starting at the CC3World instance that forms the root node of the node assembly. Alternately, and preferrably, the CC3World can use a CC3NodeSequencer instance to arrange the nodes into a linear sequence, ordered and grouped based on definable sorting priorities. This is beneficial, because it allows the application to order and group drawing operations in ways that reduce the number and scope of state changes within the GL engine, thereby improving performance and throughput.
For example, when drawing, nodes could be grouped by the drawing sequencer so that opaque objects are drawn prior to blended objects, and an application with many objects that use the same material or mesh can be sorted so that nodes with like materials or meshes are grouped together. It is highly recommended that you use a CC3NodeSequencer.
The default drawing sequencer includes only nodes with local content, and groups them so that opaque nodes are drawn first, then nodes with blending.
- (BOOL) isRunning [read, write, assign] |
Indicates whether the dynamics of this 3D model world are running.
If this property is set to NO, calls to the update: method will be effectively ignored. The play and pause methods set this property to YES and NO respectively.
This does not affect the movement of nodes controlled by CCIntervalActions. They will continue to move, irrespective of the state of this property.
- (BOOL) isUsingDrawingSequence [read, assign] |
Returns whether this instance is using a drawing sequencer.
- (ccTime) maxUpdateInterval [read, write, assign] |
If the value of this property is greater than zero, it will be used as the upper limit accepted by the updateWorld: method.
Values sent to the udpateWorld: method that are larger than this maximum will be clamped to this limit. If the value of this property is zero (or negative), the updateWorld: method will use the value that is passed to it unchanged.
Resource limitations, and activities around start-up and shut-down, can sometimes cause an occasional large interval between consecutive calls to the update: method. These large intervals can sometimes cause object in the world to appear to jump around, and if you are using physics simulation, might cause collisions to be missed.
Setting a maximum update interval can help eliminate both concerns, but the trade-off may be less realistic real-time behaviour. With a limit in place, larger intervals between updates will make the world appear to run in slow motion, rather than jump around.
The initial value of this property is set to kCC3DefaultMaximumUpdateInterval.
The behaviour described here does not apply to nodes controlled by CCIntervalActions, which are not affected by the value passed to the update: method, or the value of this property.