Why are you here??
Visit the wiki on the new, shinier, and vastly improved Cocos3D website, instead!!
The cocos3d framework is a sophisticated 3D application development framework for the iOS platform. This document describes the framework components and provides guidelines and best practices for building cocos3d iOS applications.
[toc=”2,3,4″ title=”In this Guide:”]
cocos3d is a significant extension to cocos2d, a popular, well-designed framework for building iOS games and applications that play out in 2D (or 2.5D isometric projection). Although on the one hand it is possible to start with the cocos3d Application template and develop a 3D application without knowing too much about the workings of cocos2d, to get the most out of this document, you should familiarize yourself with cocos2d. You can learn more about cocos2d at the cocos2d Wiki.
CC3Layer
CC3Layer
is one of two key classes that each application will subclass and customize. The other class you will subclass and customize in your application is CC3World
, described below.
Although cocos3d is a full 3D modeling and rendering engine, all 3D rendering occurs within CC3Layer
, a special cocos2d CCLayer
subclass. Since it is a type of CCLayer
, instances of CC3Layer
fit seamlessly into the cocos2d CCNode
hierarchy, allowing 2D nodes such as controls, labels, and health bars to be drawn under, over, or beside 3D model objects. With this design, 2D objects, 3D objects, and sound can interact with each other to create a rich, synchronized audio-visual experience. CC3Layer
acts as the bridge between the 2D and 3D worlds.
You can add a CC3Layer
instance anywhere in the visual node hierarchy of a cocos2d application. Although for the purposes of most games, the CC3Layer
instance will usually be sized to cover the complete screen, a CC3Layer
instance can be set to any size and added to a 2D parent visual CCNode
. So, your application could have a 2D scene that contains a smaller 3D scene embedded into it via a small CC3Layer
instance attached to a parent 2D CCLayer
.
Conversely, since CC3Layer
is a type of CCNode
, you can add child CCNode
s to it as well, mixing 2D nodes on top or below the 3D scene that is playing out within the CC3Layer
. Generally, this is the way most applications will combine 2D and 3D components, with a main 3D scene overlaid with 2D controls such as joysticks, fire buttons, dashboards, etc. Any CCNode
that is added to the CC3Layer
using the standard addChild:
method will appear overlaid on top of the 3D scene. You can also add 2D CCNode
s behind the 3D action as well, by using the addChild:z:
method, with a negative Z-order. Although this is generally not a common requirement, it can be used to provide a 2D skybox behind the 3D action.
When customizing your application’s subclass of CC3Layer
, you will typically override the following two template methods:
initializeControls
– this method is where you can add your 2D controls into theCC3Layer
, and otherwise generally initialize your layer. This method is invoked automatically from any of theinit
methods of the layer.update:
– if you have scheduled regular updates using the standardCCNode scheduleUpdate
method, this update: method will be called periodically. This is where you can update any of the 2D controls you’ve added, or pass data from dynamic controls such as sliders or joysticks to yourCC3World
instance. If you override this method, be sure to call invoke the superclass implementation so it can pass the update notice to theCC3World
instance.
CC3World
Although CC3Layer
forms the bridge between the 2D and 3D visual worlds, it remains primarily a cocos2D layer, and no 3D activity actually takes place within CC3Layer
. All 3D activity, from model management to rendering, takes place within, and is the responsibility of, your application’s customized CC3World
subclass.
As with CC3Layer
, there are several key template methods that you will typically override in your application’s subclass of CC3World
:
initializeWorld
– This method is where you populate the 3D models of your world. This can be accomplished through a combination of instantiting model objects directly and loading them from model data files exported from a 3D editor. TheCC3World
instance forms the base of a structural tree of nodes. Model objects are added as nodes to this root node instance using theaddChild:
method.updateBeforeTransform:
andupdateAfterTransform:
– If you have scheduled regular updates throughCCLayer
, theseCC3World
methods will be invoked automatically as part of the scheduled update, respectively before and after the transformation matrices of the nodes of the world have been recalculated, respectively, and before and after the same methods are invoked on the descendants of yourCC3World
.nodeSelected:byTouchEvent:at:
– If your application is configured to support allowing the user to select 3D nodes using touch events, this template callback method will automatically be invoked when a touch event occurs. See the section on touch events for more information about handling the selection of 3D nodes by user touch events.
As the names imply, the difference between the two update methods is that updateBeforeTransform:
is invoked before the transformation matrix of the node is recalculated, whereas the updateAfterTransform:
is invoked after. Therefore, if you want to move, rotate or scale a node, you should do so in the udpateBeforeTransform:
method, to have your changes automatically applied to the transformation matrix of the node.
However, the global transform properties of each node (globalLocation
, globalRotation
, and globalScale
) are determined as part of the calculation of the transformation matrix of that node. Therefore, if you want to make use of the current global properties, you should do so in the updateAfterTransform:
method. The global properties of a node can be used to test for collisions, or end conditions of movements, etc.
Sometimes, you may find the need to change the location
, rotation
, or scale
properties of a node in the updateAfterTransform:
method, for example as part of collision detection and reaction. If you do, you should invoke the updateTransformMatrices
method on the top-most node that is affected, to have those changes immediately applied to the transformation matrix.
You do not need to do anything in either update methods for 3D objects that are acting predictably, such as those on trajectories, or those controlled by CCActions
. Their behaviour is handled by the nodes and actions themselves.
In addition to these main template methods, you may find the following CC3World
methods useful during operation, or simply useful to understand:
addChild
: – Familiar from cocos2d, you can add child nodes (CC3Nodes
) to your 3D world.addContentFromPODResourceFile:
&addContentFromPODFile:
– These are convenience methods for loading POD files directly into theCC3World
, and are added by thePVRPOD
category if your application uses the module for loading 3D models from POD formatted files.getNodeNamed
: – Retrieves the node with the specified name that was previously added to the 3D world. Useful for grabbing hold of a node that was added as part of a file load.activeCamera
– Property returns (or sets) the 3D camera that is viewing the objects in the 3D world. You do not need to set this property. It will be automatically set to the first camera node added via one of theadd..
. methods (even if the camera is buried deep within a loaded node hierarchy). However, if you have multiple cameras, you can flip between them by setting this property.ambientLight
– This is the color of the ambient light of the 3D world. This is independent of any distinct lights that are added as child nodes.createGLBuffers
– This method causes all contained vertex data held by contained mesh nodes to be buffered to Vertex Buffer Objects (VBO’s) in the GL engine and usually into hardware buffers accessible to the GPU. This is an optional step, but highly recommended for improving performance. You can also invoke this method at any level in the node structural hierarchy if for some reason you want to load some, but not all, mesh data in the 3D world into VBO’s.releaseRedundantData
– After thecreateGLBuffer
method has been invoked, this method can be used to release the data in main memory that is now redundant for meshes that have been buffered to the GL engine. You can also invoke this method at any level in the node structural hierarchy if for some reason you want to release some, but not all, mesh data from main memory. You can also exempt individual vertex arrays from releasing data by setting theshouldReleaseRedundantData
property toNO
on the individual vertex array.updateTransformMatrices
– If you make changes to the location, rotation and scale properties of a node within theupdateAfterTransform:
method, those changes will not automatically be applied to the transformation matrix of the node, since it has already been calculated when theudpateAfterTransform:
method is invoked. However, you can use theudpateTransformMatrices
to have those changes immediately applied to the transformation matrices of a node and all its descendants.play
&pause
– these enable the operation of the update: method. When theCC3World
is paused, theupdateBeforeTransform:
andupdateAfterTransform:
methods are skipped, along with updates of all other 3D nodes.cleanCaches
– automatically invoked during low memory conditions within the application. This gives you the chance to dump any unneeded resources, for example, 3D objects that are far away, not part of this scene, etc.
Many of the responsibilities handled by CC3World
are divided by the implementation into private template methods that you can override in your subclass, to customize behaviour in a modular way.
CC3Node
All the objects in the 3D world, including models, cameras, lights, and the CC3World
itself, are known as nodes. CC3Node
is the base of the 3D node class hierarchy. Nodes can be assembled into structural assemblies using parent/child relationships. Moving, rotating, or hiding a node moves, rotates or hides all the children (and other ancestors) in concert.
This design will no doubt feel familiar to you as being analogous to CCNodes
in cocos2d, and the two node hierarchies do follow the same design pattern. However, CCNodes
and CC3Nodes
cannot be mixed in the same structural assembly, primarily because CC3Nodes
must keep track of location, rotation and scaling in three dimensions instead of two. Nevertheless, the structural concepts between the two node families are consistent.
You assemble 3D nodes using the addChild:
method. All nodes have an identifying tag and can have a name. You can retrieve a specified node in an assembly with the getNodeNamed:
and getNodeTagged:
methods.
All nodes have location
, rotation
, and scale
properties (plus a couple of others). You move, rotate, and scale CC3Nodes
by setting these properties. And, again, as with cocos2d nodes, the values of these properties are measured relative to the node’s parent node.
You can override the updateBeforeTransform:
and updateAfterTransform:
methods of a node subclass that acts predictively, such as those following a trajectory, to update these transform properties. See the discussion on CC3World
above regarding the difference between these two methods.
So, the wheels of a car can be child nodes on a car node. Each wheel node can rotate on its axis, and move up and down relative to the car as if on suspension via the location
property of each wheel node, and all the while, the whole car assembly may be travelling and bouncing down a dirt road simply by manipulating the location
property of the car node.
Any node can be the target of a CCAction
, to simply and easily control the movement and behaviour of the node in sophisticated ways. In addition, any node may be configured to respond to finger touch events by the user. See the sections on actions and touch events for more information on this interactivity.
You can use the createGLBuffers
method to cause all contained vertex data held by contained mesh nodes to be buffered to VBO’s in the GL engine. Generally, you should invoke this method at the highest level in the structure, CC3World
, but you can also invoke this method at any level in the node structural hierarchy if for some reason you want to load some, but not all, mesh data in the 3D world into VBO’s. Once data is loaded into GL VBO’s, you can use the releaseRedundantData
method to release the data from your main application memory.
CC3MeshNode
CC3MeshNode
puts the ‘3’ in 3D. An instance of CC3MeshNode
contains the 3D mesh data for a 3D object, plus the material, texture, or solid color that covers the surface of the object.
Each CC3MeshNode
instance can be covered in only a single material, texture, or color. However, like any node, mesh nodes can be assembled into a node structure. Moving the parent node will move all of the child mesh nodes in concert, along with their materials and textures. So, a multi-colored beach-ball could be one parent node and several child mesh nodes, each corresponding to a differently colored panel on the beach-ball. The parent ball node can be moved, rotated and scaled, and all component mesh nodes will be affected in unison.
Materials, Textures and Colors
The visible characteristics of the surface of a mesh node is determined by either the material it is covered with, or the pure, solid color it is painted with. As mentioned above, each mesh node can be covered with only one material, or one solid color.
The mesh node holds an instance of a CC3Material
to describe the visual characteristics of the surface of the mesh. CC3Material
includes properties to set the various coloring characteristics of the surface, including the ambient, diffuse and specular reflective colors, the emissive color, and the surface shininess. It also includes properties to determine how the colors should blend with the colors from objects behind the mesh node, permitting effects such as translucency.
In addition to basic coloring, each CC3Material
instance can hold an instance of CC3Texture
to cover the surface of the mesh with a texture image.
The combination of coloring properties, blending properties, and textures interact with lighting conditions to create complex and realistic surface visual characteristics for the mesh.
There are two mechanisms for changing the coloring and opacity of a material covering a mesh node.
- To achieve the highest level of detail, accuracy and realism, you can individually set the explicit
ambientColor
,diffuseColor
,specularColor
,emissiveColor
,shininess
,sourceBlend
, anddestinationBlend
properties. This suite of properties gives you the most complete control over the appearance of the material and its interaction with lighting conditions and the colors of the objects behind it, allowing you to generate rich visual effects. - At a simpler level,
CC3Material
also supports the cocos2d<CCRGBAProtocol>
protocol. You can use thecolor
andopacity
properties of this protocol to set the most commonly used coloring and blending characteristics simply and easily. Setting thecolor
property changes both the ambient and diffuse colors of the material in tandem. Setting theopacity
property also automatically sets the source and destination blend functions to appropriate values for the opacity level. By using thecolor
andopacity
properties, you will not be able to achieve the complexity and realism that you can by using the more detailed properties, but you can achieve good effect with much less effort. And by supporting the<CCRGBAProtocol>
protocol, the coloring and translucency of nodes with materials can be changed using standard cocos2dCCTint
andCCFade
actions, making it easier for you to add dynamic coloring effects to your nodes.
If the mesh node does not contain a material, it will be painted with the color defined in the pureColor
property. This color is painted as is, pure and solid, and is not affected by the lighting conditions. In most cases, this looks artificial, and is not recommended for realistic scene coloring. But in some circumstances, such as cartoon effects, it may be useful.
CC3MeshModel
Underpinning CC3MeshNode
is CC3MeshModel
, which in turn holds the raw vertex data in several CC3VertexArray
instances. The management of mesh data is spread across these three classes (CC3MeshNode
, CC3MeshModel
, and CC3VertexArray
) to enable data reuse and reduce memory requirements. A single mesh model instance can be used in any number of individual mesh nodes, each covered with a different material, and placed in a different location. Whether you’re talking about hordes of zombies, or a twelve-place dinner setting laid out on a table, a single mesh model instance, with one copy of the raw vertex data can be reused in an number of similar nodes.
CC3VertexArrays
Each mesh model instance (typically an instance of the concrete subclass CC3VertexArrayMeshModel
) holds several CC3VertexArray
instances, one for each type of vertex data, such as vertex locations, normals, vertex colors, texture coordinate mapping, and vertex indices. And reuse can be applied at this level as well. A single vertex array instance can be attached to many mesh models. So, if you have the need for two teapot meshes, one textured, and one painted a solid color, you can use two separate instances of CC3VertexArrayMeshModel
, each containing the same instances of the vertex locations and vertex normals arrays (CC3VertexLocations
and CC3VertexNormals
, respectively), but only the mesh model for the textured teapot would also contain a texture coordinate vertex array (CC3VertexTextureCoordinates
) instance. With this arrangement, there is only ever one copy of the underlying vertex data.
CC3LineNode & CC3PlaneNode
CC3LineNode
and CC3PlaneNode
are specialized subclasses of CC3MeshNode
that simplify the creation and drawing of lines and planes using vertex arrays, respectively.
Duplicating 3D Models
In order to allow you to create hordes of invading armies, the CC3Node
class supports the <NSCopying>
protocol. To duplicate a node is simply a matter of invoking the copy
method on that node. In addition, there is a copyWithName:
method that duplicates the node, and gives the new copy its own name.
Copying a CC3Node
creates a deep copy. This means that not only is the node itself copied, but copies are created of most components of the node, including the material, and any descendant child nodes. This allows the properties and structure of the duplicate node to be changed separately from those of the original node. For instance, the new node can be positioned, rotated, scaled, colored, or assigned a different texture from that of the original. Similarly, the child nodes of the duplicate may be modified separately, without affecting the original, or any other copies. You can copy an automobile node, and remove one of the wheels of the duplicate, while retaining all four wheels on the original. If a deep copy were not performed, changing parameters in the duplicate node, or its children, would result in the same changes appearing in all other copies of the original node.
There is one big exception to this deep copying. Since mesh data is for the most part static, and is designed to be shared between instances of CC3MeshNode
, mesh data is not copied, but is automatically shared between the original node and all its copies. Specifically, when an instance of CC3MeshNode
is copied, a copy is made of the encapsulated CC3Material
instance and is retained by the duplicate node, but the encapsulated CC3MeshModel
is not duplicated. Instead, the single CC3MeshModel
instance is retained by both the original node and the duplicate, and is henceforth shared by both nodes. This shallow-copying of the mesh data ensures that only one copy of the mesh data appears in the device memory.
The following additional rules apply to duplicating a CC3Node
:
- The
tag
property is not copied. The duplicate node is assigned a new unique value for itstag
property. This is to ensure that thetag
property is unique across all nodes, including duplicates, and allows you to identify a duplicate as distinct from the original, even if thename
property is left the same. - The duplicate will initially have no parent. That will automatically be set when the duplicate node is added as a child to a parent node somewhere in the world. This applies to the specific node on which the
copy
orcopyWithName:
method was invoked. Any descendants of this node will be assigned to their parents after they are copied, so that the overall structure of the node assembly below the invoking node will be replicated in its entirety. - Like mesh data, underlying textures are not duplicated (although the
CC3Texture
instance itself is). Nor is node animation data duplicated.
If you create your own subclass of CC3Node
, or any of its existing subclasses, and your new subclass adds state, you must implement the populateFrom:
method, including invoking the same superclass method as part of it, to ensure that state is transferred correctly from the original node to the duplicate, whenever an instance of your node class is duplicated.
CC3Camera & CC3Light
These are special nodes that represent the camera and lights in the 3D world. Cameras and lights are directional, and are examples of CC3TargettingNode
, which, in addition to being able to move and rotate like other nodes, can be assigned a target
or targetLocation
at which to point. A target
can be any other CC3Node
in the scene, and the camera or light can be told to track the target as it moves.
Controlling CC3Nodes with CCActions
If you’ve used cocos2d, you’re no doubt familiar with the family of CCAction
s, used to control the movement, coloring, visibility, and activities of CCNode
s.
In cocos3d, CC3Node
s can similarly be manipulated and controlled by CCAction
s. Some features, such as tinting and fading can manipulated by standard cocos2d actions. However, because the 3D coordinate system is different than the 2D coordinate system, specialized 3D versions of movement, rotation, scaling, and animation actions are required. This family of 3D actions can be found as subclasses of the base CC3TransformTo
interval action. In addition, there are several cocos3d action subclasses that handle material-tinting.
The 3D family of actions can, of course, be used with standard cocos2d combination actions such as the family of ease actions, sequence actions, etc.
CC3Node Animation
Any CC3Node
can be animated with key-frame animation data held in a CC3NodeAnimation
instance within the CC3Node
instance. Typically, this animation data is loaded from the 3D model files exported from your 3D editor, but you can also assemble this data programmatically using the simple CC3ArrayNodeAnimation
subclass of CC3NodeAnimation
. Like mesh data, the CC3NodeAnimation
instances are stateless, and each may be shared by multiple CC3Node
instances, so that animation data need not be duplicated redundantly.
Any or all of the transformation properties: location
, rotation
, and scale
, may be animated using CC3NodeAnimation
or CC3ArrayNodeAnimation
. If you need to animate other characteristics of your nodes, you can subclass these classes to add additional animation capabilities.
Once animation data is associated with a CC3Node
, the node can be animated with repeated invocations of the establishAnimationFrameAt:
method on the node itself, passing in a frame time, which is a floating point value between zero and one, with zero representing the first animation frame, and one representing the last animation frame.
In order to perform smooth animation, by default, the CC3NodeAnimation
will interpolate animation data between frames if the timing value passed in through the establishAnimationFrameAt:
method is between actual frame times. This is controlled by the shouldInterpolate
property on the CC3NodeAnimation
instance. By default, this property is set to YES
, but may be set to NO
if heavy interpolation interferes with frame rates.
For node assemblies, you will typically want to animate the whole assembly in concert. To support this, the establishAnimationFrameAt:
method automatically invokes the same method on each child node, passing the same animation frame time to each child node. Thus, animating a character, by invoking that method on the character node itself, will automatically forward the same invocation to each component child node of the character, such as the character’s limbs, or any weapon the character might be holding. As a result, all components of the character will move in sync with the character, as it is animated.
However, you can turn animation of any node in the assembly off, including selectively turning off animation of specific child nodes, via the disableAnimation
method on that child node. You can turn the animation of whole sub-assemblies of nodes off via the disableAllAnimation
method.
Fractional animation of individual movements is possible by simply limiting the range of frame times that are sent with the establishAnimationFrameAt:
method. For example, if your character animation includes a run frame sequence and a jump frame sequence, you can invoke one or the other by simply starting and ending your animation at the frame times associated with the specific movement you want to invoke.
Controlling Animation with Actions
Although you can arrange to invoke the establishAnimationFrameAt:
method of your animated CC3Node
directly, in most cases it is much easier to use an instance of CC3Animate
to control the animation of a node.
CC3Animate
is a type of CCActionInterval
, and will run through the animation frames automatically over a configurable time duration. Moreover, when instantiating the CC3Animate
, you can restrict the frames to a particular range, to allow fractional animation of specific movements.
Selecting CC3Nodes with User Touch Events
To allow the user to interact with the objects in your 3D world, you can enable the selection of 3D objects using standard iOS finger touch events.
The first step in enabling touch activity is to set the isTouchEnabled
property of the CC3Layer
to YES
. Typically you will do this in the initializeControls
method of your customized CC3Layer
class. This causes the CC3Layer
to register itself to receive touch events from iOS.
As such, your CC3Layer
will receive and process kCCTouchBegan
, kCCTouchEnded
, and kCCTouchCancelled
events. By default, your CC3Layer
will not receive or process kCCTouchMoved
events, because these are both quite voluminous and seldom used. However, you can configure your customized CC3Layer
subclass to receive and handle kCCTouchMoved
events by copying the commented-out ccTouchMoved:withEvent:
method from the CC3Layer
implementation and paste it into the implementation of your customized CC3Layer
subclass, with the commenting removed.
The second step is to set the isTouchEnabled
property to YES
, in any CC3Node
s that you want the user to be able to select with a touch event. So, for example, let’s say your 3D world had a bowl of fruit on a table, you might want the user to be able to select a piece of fruit, but not the bowl or the table objects. In this case, you would set the isTouchEnabled
property to YES
on the CC3Node
instances representing each piece of fruit, but not on the CC3Node
instances that represent the bowl or table. Please also note that, to be touchable, the node must have its visible
property set to YES
.
Once these two steps have been completed, the nodeSelected:byTouchEvent:at:
callback method of your customized CC3World
subclass will automatically be invoked on each touch event. This callback includes the CC3Node
instance that was touched, the type of touch, and the 2D location of the touch point, in the local coordinates of the CC3Layer
.
If the touch occurred at a point under which there is no touchable CC3Node
, the callback nodeSelected:byTouchEvent:at:
method will still be invoked, but the node will be nil
, to indicate that a touch event occurred, but not on a touchable node.
For node assemblies, the node passed to the nodeSelected:byTouchEvent:at:
method will not necessarily be the individual component or leaf node that was touched. Instead, it will be the closest structural ancestor of the leaf node that has its isTouchEnabled
property set to YES
.
For example, if the node representing a wheel of a car is touched, it may be more desireable to identify the car as being the object of interest to be selected, instead of the wheel. In this case, setting the isTouchEnabled
property to YES
on the car, but leaving it as NO
on each wheel, will allow a wheel to be touched, but the node received by the nodeSelected:byTouchEvent:at:
callback will be the node that represents the car as a whole.
Selection Artifacts
When using translucent nodes, you might notice that when a translucent node is displayed over the raw background color of the CC3Layer
, it will appear to flicker slightly when a touch event occurs. This is a side effect of the mechanism used to identify the 3D node that is under the 2D touch point.
The selection mechanism uses a color-picking algorithm, which momentarily paints each node with a unique color and then reads the color at the touch point to identify the node. The scene is then immediately drawn a second time with proper coloring. Since this second scene rendering occurs within the same rendering frame as the first, the second rendering completely overwrites the first, and the user is completely unaware than the first pass occurred.
The only exception to this is when a translucent node has no opaque nodes behind it. In this case, because the underlying layer background color is not redrawn on the second rendering pass, some of the solid coloring used to paint the node during the selection rendering pass will “leak through” the transparency of the second rendering pass. In effect, for one frame, the translucent node does not have the layer background color behind it, causing a momentary flicker.
It is important to realize that this effect does not occur when the translucent node has opaque nodes behind it in the 3D scene. This is because the opaque background nodes will be redrawn as well, and it will be these background nodes that will be seen through the translucent node, as they should be.
Therefore, if you have translucent nodes and are using touch selection, to avoid this slight flicker be sure to include an opaque skybox node at the back of your 3D scene, over which the other nodes of your scene will be drawn.
Projecting 3D Locations to 2D
The
property of projectedLocation
CC3Node
holds the location of the 3D node in the 2D coordinate system of the window. It acts as a bridge between the 3D coordinate system and the 2D coordinate system. Knowing the projectedLocation
of a 3D node allows you to relate it to a 2D controls such as a targetting reticle, or to a touch event.
The projectedLocation
is a 3D vector. As you would expect, the X
– and Y
-components provide the location of the 3D node on the screen, in the 2D coordinate system of the CC3Layer
. If the 3D node is located somewhere out of the view of the camera, and therefore not displayable within the layer, these values will be outside the range given by the contentSize
of the CC3Layer
. Following from this, either coordinate value may be negative, indicating that the node is located to the left, or below, the view of the camera.
The Z
-component of the projectedLocation
contains the straight-line distance between the 3D node and the camera, as measured in the coordinates of your 3D world. This value may be negative, indicating that the 3D node is actually behind the camera. In most cases, of course, you will be interested in nodes that are in front of the camera, and the Z
-component of the projectedLocation
can help you identify that.
CC3Node
also supports the related
property. It is derived from the projectedPosition
projectedLocation
property and, for the most part, contains the same X
– and Y
– coordinates as projectedLocation
, but as a 2D CGPoint
, which is immediately usable by the cocos2d framework.
However, as a 2D point, the projectedPosition
lacks the needed ability to distinguish whether the node is in front of, or behind, the camera. Since this information is almost always needed, the point is encoded so that, if the 3D node is actually behind the plane of the camera, both the X
– and Y
-components of the projectedPosition
will contain the large negative value -CGFLOAT_MAX
. If you use projectedPosition
, you can test for this value to determine whether the 3D node is in front of, or behind, the camera.
For most nodes, these properties are not calculated automatically. In the update:
method of your CC3World
you can have them calculated for a node of interest by passing the node to the projectNode:
method of the activeCamera
.
However, for CC3Billboard
nodes, the projectedLocation
and projectedPosition
properties are calculated automatically on each update. A CC3Billboard
is a 3D node that can hold an instance of a 2D cocos2d CCNode
, and display that 2D node at the projectedPosition
of the CC3Billboard
node. Since the 2D node is drawn in 2D, it always appears to face the camera, and is always drawn over all 3D content. The contained CCNode
can be any cocos2d node, and it can be configured to automatically scale to the correct perspective sizing, shrinking as the CC3Billboard
moves away from the camera, and growing as the CC3Billboard
approaches the camera. A common use of CC3Billboard
is to display information about a 3D node, such as a textual name label or a health-bar for a game character.
Pluggable 3D Model Loading
Sophisticated 3D games are dependent on loading 3D models from resources created in 3D editors such as Blender, Cheetah3D, Maya, 3ds Max, and Cinema 4D. Since the number of possible file formats is significant, and can evolve, the loading of model data is handled by pluggable loaders and frameworks. When building your application with cocos3d, you only need to include the loaders that you use.
The pluggable loading framework is based around two template classes:
- The resource class, which takes care of loading and parsing the 3D data file, creating instances of nodes, mesh models, vertex arrays, materials, textures, cameras, lights, etc., and assembles them into a node hierarchy. This will be a subclass of
CC3Resource
, and is tailored to parsing and assembling a specific data file format. - The resource node class. This will be a subclass of
CC3ResourceNode
, and as such, is actually a type ofCC3Node
. It wraps theCC3Resource
instance, extracts populated nodes from it, and adds them as child nodes to itself. This node can be used like any otherCC3Node
instance, and is usually simply added as a child to yourCC3World
instance. You can move, rotate, scale, or hide all the components loaded from a file simply by manipulating the properties of theCC3ResourceNode
instance.
In addition to these two template classes, a pluggable loading package will usually contain specialized subclasses of CC3MeshNode
, CC3Material
, CC3Camera
, etc., in order to set the properties easily from the data loaded from the file. But once created, these objects behave like any other node of their type.
A pluggable loading package may also add categories to base classes as a convenience. Thus, the PowerVR POD
file loading package adds a category to CC3World
that adds the method addContentFromPODResourceFile:
as a convenience for loading POD files directly into your CC3World
.
The initial loading package available with cocos3d is for PowerVR POD
files.
Automatic Frustum Culling and Bounding Volumes
In a 3D world, the camera is always pointing in some direction, and generally, is only seeing a fraction of the objects in the 3D world. It is therefore a waste of precious time and resources to try to draw all of these objects that will not be seen.
The task of determining which objects don’t need to be drawn, and then removing them from the rendering pipeline is known as culling. There are two types of culling: frustum culling, which is the removal of objects that are not within the field of view of the camera, and occlusion culling, which is the removal of objects that are within the field of view of the camera, but can’t be seen because they are being visually blocked by other objects. For example, they might be located in another room in your the map, or might be hiding behind a large rock. At this time, cocos3d does not perform any kind of occlusion culling.
cocos3d performs frustum culling automatically. Objects that are outside the view of the camera will not be drawn. This is accomplished by specifying a bounding volume for each mesh node. Each node holds onto an instance of a CC3NodeBoundingVolume
, which it delegates to when determining whether it should draw itself to the GL engine. All mesh nodes in cocos3d have a default bounding volume that is reasonably accurate, and for the most part, you won’t even need to think about bounding volumes. However, we’ll describe the operation of bounding volumes here, for those situations where the application may want to improve on the default behaviour.
The trick with bounding volumes is to strike a balance between the time it takes to determine whether a node should be rendered, and the time it would take to simply blindly render the object. To that end, different kinds of bounding volumes can be specified, some of which are very fast, but perhaps less accurate, and others that are very accurate, but time consuming.
Accuracy is important because acn inaccurate bounding volume can either result in the effort of rendering an object being performed when the objects won’t be seen, or worse, an object might be culled, when in fact at least part of it would really be seen if it were drawn. This second type of inaccuracy, over-zealous culling results in objects strangely popping in and out of existence, particularly around the edges of the camera’s field of view. Since this behaviour is generally undesirable, you should stay away from creating bounding volumes that are overly-zealous. The bounding volumes included by default in cocos3d always ensure that all vertices are included within the bounding volume, so that objects are never culled when they are actually partially visible.
The family of cocos3d bounding volumes includes a number of different subclasses, each performing a different type of boundary test. The two most commonly used are a spherical bounding volume, represented by subclasses of CC3NodeSphericalBoundingVolume
, and axially-aligned-bounding-box (AABB) bounding volumes, represented by subclasses of CC3NodeBoundingBoxVolume
.
Checking spherical boundaries against the camera frustum is very fast. However, for most non-spherical real-world 3D objects, such as a human character, or automobile, a sphere that completely envelopes the object is much larger than the object. The result is that near the periphery of the camera’s view, the sphere may be partially inside the frustum, but the object is not. The result is that the object will be rendered (because the sphere can be “seen” by the camera), even though the object itself will not be seen.
Bounding boxes are often more accurate for many real-world objects, but are more expensive to test against the camera frustum, because all eight points that define the volume must be tested against the frustum.
At the extreme end of the scale, the most accurate bounding volume would be to test every single vertex in the mesh against the camera’s frustum. By definition, this will result in almost perfect accuracy, but at the large cost of testing all the vertices. In many cases, since the GPU can generally do this faster than the CPU, there is no cost savings in testing all vertices. For this reason, cocos3d does not yet include a default all-vertex bounding volume test. However, such a bounding volume could easily be added and used by the application.
Bounding volumes, whether they be point, spherical, boxes, or custom, are calculated and defined automatically by the vertices in the mesh node. In addition, they scale automatically as the node is scaled.
Finally, to make use of both fast boundary tests to exclude objects that are clearly far from the camera’s field of view, and also more accurate boundary tests for objects that are at the edges of the camera’s field of view, cocos3d also includes the CC3NodeTighteningBoundingVolumeSequence
bounding volume. Instances of this class hold an array of other bounding volumes, and tests the node against them in sequential order. As soon as one contained bounding volume indicates that the node is definitely outside the camera’s field of view, the node is rejected and not drawn.
The trick is to order the contained bounding volumes so that fast, but broad, tests are performed early in the sequence, so they can reject the node if it is clearly nowhere near the camera’s field of view. Subsequent bounding volumes in the sequence should be less broad, but will not be tested unless the earlier bounding volumes have accepted the node as being visible.
By default, mesh nodes in cocos3d make use of a tightening sequence that contains first a spherical bounding volume and then an AABB bounding volume. For the most part, this will likely be sufficient, and you won’t even have to think about bounding volumes. However, some applications may benefit from custom bounding volumes.
Rendering Order
The underlying OpenGL ES engine uses a pipeline of commands for manipulating the state of the rendering engine. The switching of some states can be a costly exercise. Consequently, it is often useful for the application to consider the order in which objects are rendered to the engine. For example, if several objects make use of the same texture, it is usually beneficial to draw all of these objects one after the other, before drawing an object that is covered with a different texture.
To that end, the drawing order of the objects within a CC3World
can be configured by the application for optimal performance. The CC3World
instance holds onto an instance of a CC3NodeSequencer
, and delegates the ordering of nodes for drawing to that sequencer. If no node sequencer is supplied to the CC3World, the world will draw nodes hierarchically, following the structural hierarchy of its children. In most cases, this will not be the optimal ordering.
As with bounding volumes discussed above, there are a number of different types of node sequencers, and establishing a different ordering is simply a matter of plugging and configuring a different sequencer into your CC3World
.
There are two key types of sequencers, CC3NodeArraySequencer
s, which hold a collection of nodes, grouped in some defined order, and CC3BTreeNodeSequencer
s, which hold a B-tree of other sequencers, allowing groupings of groupings of nodes, ad infinitum. You can assemble a complex sequence definition, by assembling different types of sequencers into a structural B-tree hierarchy.
Every sequencer contains in instance of a CC3NodeEvaluator
subclass. A node evaluator tests a node against some criteria, and returns a boolean result indicating whether the node is accepted or rejected, effectively giving each sequencer a chance to answer the question “Do you want this node?”. Using this mechanism, a B-tree sequencer can determine which of its child sequencers wants to take care of ordering any particular node.
A simple example might help here. Both Imagination Technologies (the supplier of the iOS GPU’s) and Apple recommend that all opaque objects should be drawn before translucent objects. In addition, the translucent objects themselves should be drawn in Z-order, which is the reverse order of distance from the camera, with the farther translucent objects being drawn first, and the nearer translucent objects drawn over them.
This drawing order can be accomplished with a B-tree sequencer containing two array sequencers: the first with an evaluator that tests the node for opacity, and the second with an evaluator that tests the node for translucency. The array sequencer holding the opaque nodes can simply hold them in the order they are added. However, the array sequencer holding the translucent nodes needs to order the nodes by their Z-order.
This structure looks as follows:
CC3BTreeNodeSequencer (CC3LocalContentNodeAcceptor)
CC3NodeArraySequencer (CC3OpaqueNodeAcceptor)
CC3NodeArrayZOrderSequencer (CC3TranslucentNodeAcceptor)
When testing a node, the B-tree sequencer will first ask the child sequencer with the opacity test if it is interested in the node, before asking the second sequencer. The result is that the first sequencer will contain opaque nodes in the order they were added, and the second will contain translucent nodes in Z-order.
Because nodes may be moving around from frame to frame, be aware that Z-ordering requires that the nodes in the CC3NodeArrayZOrderSequencer
be sorted on each and every frame update. This can have significant performance implications if there are a large number of translucent nodes. To improve performance, ensure that translucent nodes really are visibly translucent (don’t waste time sorting translucent nodes that can’t be seen as translucent by the user), and keep the number of translucent nodes to a minimum.
The requirement that this example illustrates is so common that CC3BTreeNodeSequencer
includes the class method sequencerLocalContentOpaqueFirst
, to create just such a sequencer assembly. There are also the class methods sequencerLocalContentOpaqueFirstGroupTextures
and sequencerLocalContentOpaqueFirstGroupMeshes
, which take the concept a bit further and group the opaque nodes so that opaque nodes with the same texture or mesh are drawn together, one after the other, before other opaque nodes are drawn. As above, in each of these sequencers, the translucent nodes are sorted by Z-order.
By default, CC3World
uses a sequencer created by the sequencerLocalContentOpaqueFirst
method, thereby drawing opaque nodes first, in the order they were added, then translucent nodes in Z-order.
Updating vs Drawing
By design, both cocos2d and cocos3d support a clear separation between updating and drawing activities, and each is invoked on a separate loop. In addition to helping to keep your application code organized, there are good performance reasons for separating updating from drawing. OpenGL ES is designed as a state engine pipeline, designed for a steady stream of rendering commands, with ideally no data traveling back upstream to the application. This allows the GPU to keep its own time. Keeping the application rendering loop lean and mean, helps the GPU operate at the full frame rate, and leaves open options for scaling back the update rate separately if needed, or breaking the update loop into several passes, or possibly even multi-threading the updates, in extreme cases.
With all this in mind, you should keep the code you write in the updateBeforeTransform:
and updateAfterTransform:
methods of any CC3Node
subclass free of drawing or rendering operations. Similarly, should you override the drawWithVisitor:
or draw
methods in any CC3Node
subclass, you should only perform rendering operations, and keep those methods free of model updates.
OpenGL ES State Management
As mentioned above in the discussion of rendering order, the performance of the OpenGL ES state machine pipeline is slowed down by frequent state changes. And the OpenGL ES engine incurs costs when performing state machine changes that really didn’t need to happen because the engine already was in that state. To that end, the application should do its best to ensure that GL engine state changes are only made if state really is changing.
To ensure that, cocos3d shadows the state of the GL engine outside of the GL engine itself. When an attempt is made to change state, cocos3d first checks to see if the GL engine is already in that state, by checking the value of the shadow state. Only if the state is changing from that of the shadow state is it propagated to the GL engine.
This state shadow tracking is automatic, and most application developers can safely ignore it. However, some sophisticated applications may need to interact with this framework, so I’ll give an overview of it here.
In cocos3d, this shadow state is managed by a singleton instance of CC3OpenGLES11Engine
. All calls to the GL engine are made through this singleton instance.
The CC3OpenGLES11Engine
singleton instance contains a number of instances of subclasses of CC3OpenGLES11StateTrackerManager
, each geared towards tracking a particular grouping of GL state, such as capabilities, or lighting, materials, etc. Each of these tracker managers is accessed through a property in the CC3OpenGLES11Engine
singleton instance. Each tracker manager exposes individual elements of state through properties.
For shadow tracking to work, it is absolutely critical that all GL state changes are handled by the shadow tracker. So, when adding functionality to cocos3d for your application, if you need to make calls to the GL engine, be sure to do so through the proper shadow tracker! A few examples of how to make a GL call through a shadow tracker, and the GL call that it replaces are:
[[CC3OpenGLES11Engine engine].serverCapabilities.texture2D enable]
<->glEnable(GL_TEXTURE_2D)
[CC3OpenGLES11Engine engine].materials.ambientColor.value = kCCC4FBlue
<->glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat*)&kCCC4FBlue)
[CC3OpenGLES11Engine engine].state.scissor.value = self.activeCamera.viewport
<->glScissor(vp.x, vp.y, vp.w, vp.h)
, wherevp = self.activeCameraViewport
Since it is critical that all GL calls be processed through the state shadow trackers, but cocos2d does not use state shadow tracking, you may be wondering how the shadow trackers know what the value a GL state has at the time that rendering control is passed to the cocos3d framework from cocos2d.
Each primitive state tracker has an originalValueHandling
property, which tells that tracker how to determine the original value. The enumerated value of this property can tell the tracker to do one of the following:
- simply ignore the current state at the beginning of each rendering frame
- read the current state at the beginning of each rendering frame
- read the current state at the beginning of the first rendering frame and assume that value always
In addition, for the last two options, the enumeration can be modified to tell the tracker to restore that original state back to the GL engine, because cocos2d is assuming it to have stayed the same.
The original value state is set to the optimal value for combining cocos2d and cocos3d, generally either ignoring the value, or reading it once on the first frame. However, if your application varies from frame to frame and you find that the initial value can change from frame to frame at the point that cocos3d takes over, you can modify the originalValueHandling
property of the associated state tracker to read the value on every frame.
Keep in mind that this reading interrupts the the flow of the GL pipeline significantly, and should generally be avoided at all costs. A better solution is to ensure that your cocos2d code leaves GL state with consistent values from frame to frame at the time cocos3d takes over.
Comments
184 responses to “cocos3d Programming Guide”
This sounds amazing! I’ve been creating our art assets for our Cocos2D game using Maya 3D and using 2D png snapshots. Can I export a mesh created in Maya as an FBX object? Will my shaders import too? Or do I have to download the Collada plug-in to use my Maya objects with the Cocos3D library? Thanks again for the library, awesome work! 😉 Elizabeth
Hi Elizabeth…
Unfortunately, with this initial release, cocos3d supports importing via the POD file format only. We plan to add other file formats as we move forward.
The PowerVR SDK (link in article above) does include an exporter from Maya to POD files, but not for Mac. If you’re using Mac, It looks like your best bet might be to export your meshes from Maya to Collada, and then use the Collada2POD converter in the PowerVR SDK.
I’ll be posting an article on this site in the next few days, with instructions on configuring the Collada2POD tool for exporting to cocos3d. Keep an eye out for it.
Regarding shaders…no. cocos3d, like cocos2d, uses OpenGLES 1.1, so it doesn’t currently support shaders. Unfortunately, you’ll have to export as meshes, materials and textures for the time being.
Thanks…
…Bill
thanks, looking forward to your next article on using Collada2POD.
Hi Elizabeth…
Well…wait no longer! 🙂
I’ve posted the article here.
…Bill
thanks great job!
some example not available. put some examples. so we can use more!.
Hi Ashok…
After the next release, we will be working on an new website, which will include better explanations, examples, and hopefully tutorials.
In the meantime, your best source of examples is the CC3DemoMashUp demo app that comes with cocos3d. It contains examples of using most of the features.
…Bill
Great!
I’ve been missing this for a while now. I have a question: are other devices supported too? Like iPad, Mac…
Igor
All iOS devices are supported. cocos3d has been tested on iPad.
Mac support has not been tested. Based on the experience of cocos2d, we expect that there will be a few small issues around OpenGL on Mac…but mostly just about changing calls, etc. It’s something we will address at some point if Mac is a popular platform requirement.
…Bill
Very great job! Thanks, Bill.
Does this engine supports things like:
– gabbing a 3D object?
– collision detection between objects?
It looks very cool from the demo app.
Hi Jesus…
Can you clarify what you mean by ‘gabbing’? If you meant ‘grabbing’…as in manipulating or moving an object…then yes. If not, please clarify.
Collision detection is up to the app for now (as with the simple bouncing ball in the CC3DemoMashUp). Each node contains a bounding volume that can help with that.
We will be integrating a proper physics engine into cocos3d in the future. Please refer to the development roadmap for more info.
…Bill
Yes I meant grabbing, such as detecting when an object was touched.
How is this achieved? I didn’t find a class that provides this functionality.
As for collision detection. I think the bounding volume will do for now, thanks. Looking forward to the physics engine 🙂
Hi Jesus…
Ahh…you mean grabbing via a user touch…not programatically.
There’s nothing automatic yet. However…you can do some crude detection as follows:
You can use the
projectedPosition
property of aCC3Node
to determine where on the screen it is. Then you can use some kind of 2D radius measurement from your touch point to determine whether you are close enough to consider it ‘grabbed’.The
projectedPosition
property is not set for all nodes automatically. You can either set it for the nodes you are interested in as part of your customCC3World update:
method (via[self.activeCamera projectNode: myNode]
). Or you can add aCC3Billboard
as a child to yourCC3Node
. TheprojectedPosition
property of allCC3Billboard
s are updated automatically.If your node stays more or less in the same orientation (not rotating about), like, say, a character running around in a game, you could attach a 2D
CCNode
to theCC3Billboard
, and size it so that it visually covers the 3D model. You could then use theboundingBox
of the 2DCCNode
as a visual 2D bounding area of your 3D object. By default, theCCNode
will grow and shrink proportionally as the 3D object moves toward and away from the camera, so it should stay in sync. If you use aCCLayerColor
as the 2D node, then you could color it to show how it covers as you lay it out, and then make it invisible during game play.Have a look at the text label attached to the robot arm in the
CC3DemoMashUp
example project for howCC3Billboards
can be used.Unfortunately, if you have 3D objects that overlap visually, and you want to be able to touch either, this technique will indicate that both have been touched. You’ll have to have some kind of manual ordering to keep track of which object is of more interest to you.
Admittedly, this is a crude technique. You’ve given us some things to think about. This is certainly a feature that needs proper support in a touch device. I’ll make sure it makes it into an upcoming release on the roadmap.
Thanks…
…Bill
> and size it so that it visually covers the 3D model
Hi Bill,
Could you give me a hint how to do that?
Hi Salman…
You would just do it visually. You could used a
CCLayerColor
, configured with a background color so you can see it, as the cocos2d node being held by the billboard.Then play with a combination of sizing that layer and the
unityScaleDistance
property ofCC3Billboard
to line it up with 3D object. Once things are working, turn off the color of theCCLayerColor
node.However…before you run off and do that, I should let you know that we are releasing an update to cocos3d next week that includes proper 3D object picking. Keep an eye out for it.
…Bill
Hi Bill,
Thanks for the touch event support in the current version.
I still have a question regarding the API
– (void) nodeSelected: (CC3Node *) aNode byTouchEvent: (uint) touchTypeat:(CGPoint) touchPoint
The touchPoint is the location in 2D coordinate system of the CC3Layer where the touch occurred.
In case I will move the aNode selected by the touch event, how I can set the aNode.location with the correct CC3Vector?
Basically my question is how to calculate the 3d location of the object based on known desired 2d viewport location?
Hi Salman…
Sorry…there’s no true unproject capabilities yet.
Unproject gets messy fast because ultimately, one is dealing with individual mesh faces, all of which can be oriented in any way. And in keeping with the cocos2d/3d philosophy, we want to make sure we do something that’s easy and straightforward for developers to use.
I’ve added it to the development roadmap, tentatively as part of the 0.7 release (mid year).
In the meantime, if you have something like a floor that you want to move your object to, you can always overlay a series of transparent (don’t make them invisible, otherwise they won’t be detected) smaller rectangular meshes as tiles over your floor. Add the tile nodes as child nodes to the floor. You’ll then get notification of which tile has been touched, and you can move your object to that location.
…Bill
Great stuff! This is a huge step for cocos2d. Big thanks for the good work.
Is it possible to do any kind of character animation at this point, knowing that rigging and skinning isn’t yet available? I know how to do it in blender, but i’m not sure how to go about dividing and exporting the animations in a way that would be controllable through code.
Thanks
Hi Ramus…
Thanks for your encouraging comments.
Unfortunately, we have not yet even begun to address bone rigging, so I can’t give you much help there…yet.
It might help you to look at the way the
CC3DemoMashUp
example in the cococ3d distribution animates the robot arm, which is an assembly ofCC3Nodes
rigged together. It’s not true bone rigging, but it does illustrate how something like an arm can be managed in cococ3d. If you are able to get Blender to export your character models to COLLADA and converted to POD in a similar manner, it should work.I also suggest that you post this question as a new topic in the cocos3d forum, where you might find developers with more real-world bone rigging experience that myself.
Thanks…
…Bill
Hi Bill,
Thanks for the quick reply. I’ll have a look at the example more in depth tomorrow. That should give me an idea.
/Rasmus
Hi Bill. Congrats! Great guide.
I would like to ask if it is possible to do this animation (http://www.box.net/shared/y1qeo8pn2u) with 3 individual models using cocos3d. The animation must start when the piece on the border is touched. The rotation could be either on the rows or columns and always initiated by the touch or click.
Thanks in advance for your help.
Raul.
Sorry, the correct link of the demo animation: http://www.box.net/shared/a96ih83b6u
Hi Raul…
Yes…it’s possible. The rotation is simply a matter of applying a
CC3RotateTo
action to theCC3Node
that is the middle row (or whatever row).The real trick is to handle the touches. At present, cocos3d has no true automatic way to determine which object has been touched. That functionality will be coming in a future release.
In the meantime, if you need to know that the middle row has been touched, you can map it yourself. One technique I can suggest is to attach a
CC3Billboard
, containing a 2D cocos2dCCNode
to the 3D row, and visually size it to be the same size as the row. It will grow and shrink in tandem with the 3D node it is attached to. You can use theboundingBox
of the 2D object as a way of determining whether the row has been touched.…Bill
Hi again Bill.
Could an object be part of a cc3node at one moment and part of another one later? I mean, one object may need to be rotated with the entire row, but later, the same object may rotate with the column.
Thanks in advance.
Raul
Hi Raul…
Yes…you can use
removeChild:
andaddChild:
to move nodes around in your structural hierarchy. You can do this as part of theupdate:
processing.At any one time, though, a node may be added to only one parent…because transformations are processed hierarchically.
…Bill
Hi Again Bill.
Please help! Maybe I’m a little confused with this apparently very simple task.
I’ve created a new Cocos3d project and just change the pod file and get the node called “Monkey” from the new pod file. Just rotated a bit and it’s working just as expected.
This is the changed code:
CC3MeshNode* Monkey = (CC3MeshNode*)[self getNodeNamed: @”Monkey”];
Monkey.rotation = cc3v(90.0, 0.0, 0.0);
CCActionInterval* partialRot = [CC3RotateBy actionWithDuration: 1.0
rotateBy: cc3v(0.0, 30.0, 0.0)];
[Monkey runAction: [CCRepeatForever actionWithAction: partialRot]];
Now I want to add a second “Monkey” as a child of the first, a little bit to the left to make it act as the satellite teapot do in the CC3DemoMashUp project, but I’m totally lost.
Thanks in advance for your help
Raul
Hi Raul…
Have a look at this post in the cocos3d forum.
You might also think about using the forum for future questions of this sort…to get assistance from a larger community.
Also…later this week, we will be releasing an update to cocos3d that greatly simplifies the ability to create copies of nodes. Keep an eye out for it!
…Bill
Hi Bill,
can you help me with a little problem?
I have an 3d object an it rotates on the simulator, but how can I add a texture to this model? where i’ve to put the images etc?
thanks for your help kai
Hi Kai…
The texture images go in the
Resources
folder of your application, as do any POD files that you are using.If you haven’t done so already, have a look at the
CC3DemoMashUp
example in the cocos3d distribution. It includes several textured components.…Bill
Hello Bill, I have a little issue. I want to include a CCNode (a CCSprite actually) attached to a 3d figure, but i dont want the sprite to face the camera automatically. CC3Billboards have an automatic orientation towards the cam, and i want to disable this, or go somehow around.
Thanks a lot for your help and congratulations for this awesome features!
Hello again, never mind I realized that you can do this with populateCenteredRectangle and as texture using the CCSprite, but thanks anyway!
[…] can download the Cocos3D beta here: Cocos3D Beta You can find the cocos3D programming guide here: Cocos3D Programming Guide It looks like Cocos3D has a ways to go, but judging by the impressive start it appears to be in the […]
[…] You can find the cocos3D programming guide here: Cocos3D Programming Guide […]
I’ve made a few games for the iPhone already, but they were all static (i.e. no moving images). I want to now start creating games with movement.
Being new to games with movement, should I start out with cocos*2*d or jump right into cocos*3*d?
Hi Syler…
Well…that all depends on what you want to do!
Full 3D games are very different than 2D games.
3D games provide a much richer user experience. Think flight simulators or first-person shooters. But on smaller devices, 2D games can often be more playable. Think Angry Birds…or Run! (the latter is a cocos2d game).
3D games are more complex to create, both in terms of content creation, and in terms of managing the objects…simply because you have to think in terms of 3 dimensions.
If you’re brand new to dynamic games…start out with cocos2d. That will give you a taste of thinking and working in the dynamic world. Then move to cocos3d when you want to explore a richer user experience.
…Bill
Fantastic guide! 🙂
I hope I’ll be able to do something with that..
Any news about Xcode 4 templates?
thanks
Vincenzo
P.S: I traslated this page in italian…I hope that isn’t a problem..:)
[…] You can find the cocos3D programming guide here: Cocos3D Programming Guide […]
Hi Sir,
I am a new guy to 3d world, and cocos 3d is a great framework,i have a question that how can i render a image in the cocos 3d,does the cocos3d framework always need the pod file? (i just need a static background image).
Thanks in advance.
Hi ris…
Have a look at family of
populateAs...
methods onCC3MeshNode
. Plus the subclassesCC3PlaneNode
andCC3BoxNode
.You can find examples of how to use these in the demos
CC3DemoMashUp
andCC3Performance
. The ground plane inCC3DemoMashUp
is a static background rectangle like you are asking about.…Bill
Hi Bill,
Thanks a lot for your reply,i get it, i am a new guy to the 3d world,and i am plan to use cocos3d to build a 3d book application. But i find that i can not control the camera very well. Now i have no idea about this, Would you like to give me some idea about this? Is it easy to be done by cocos3d? If i can get some reply from,that will be a great help. Thanks in advance.
Ris
Hi ris…
The best thing to do is to become familiar with the
CC3DemoMashUp
andCC3Performance
demos. They include code examples of how to work with many of the features of cocos3d, including controlling the camera.In addition to the basic behaviour of these demos, you’ll also notice that there are a number of sections of code commented out in the demos. You can selectively uncomment these to see how they change the behaviour.
…Bill
Hi Bill,
That is great help,i look into the CC3DemoMashUp,and build some mesh node like
CC3MeshNode* floater = [CC3PlaneNode nodeWithName: kFloaterName];
[floater populateAsCenteredRectangleWithSize: CGSizeMake(500.0, 500.0)
withTexture: [CC3Texture textureFromFile: kFloaterTextureFile]
invertTexture: NO];
But i find i have two problems
1.the image render on the stage is black,when i click it seems appear the original color,how can i get the right color?
2.If i remove the Robot , it seems that the location and direction control do not work,how can i keep the camera function and remove the robot on the stage.
It should be easy problem,but seems to be confuse to me. I hope i can get an answer from you. If it is not correct to post such problem here.Would you like to tell me where i can post the problem.Thanks again for your help.
Thanks,
Ris
Hi ris…
Sorry to see you’re having trouble.
Please start posting your questions to the cocos3d forum. You’ll get answers much faster that way.
Regarding the rendering issue, what is it that is rendering black? Is it the floating ring? Are you substituting your own texture file, or is it one of the textures in the demo?
Regarding the camera and robot, have a look at this forum posting. It explains how to replace the camera when you remove the robot.
…Bill
Hi Bill,
That’s great to see your answer,yes,i have add my own texture as plain node in the project,and it seems render a black color,when i set acts.color = ccWHITE; it appears,but not the real color of my texture, but when i rotate it,it seems get the right color,how can i disappear it correct as render the “ground ” plain node?
Again,thanks for your help,bill.
Thanks,
Ris
[…] cocos3d Programming Guide. […]
I have created project from template (using Xcode 4) and generated project has no target (“0 targets, missing base SDK”).
I have no clue how to fix that – anyone had similar issue?
cocos3d 0.5.4, cocos2d 1.0-rc
cheers!
Hmm… actually I forgot to install cocos2d template in Xcode. Now it works great.
Thanks for the great job!
Awesome ,is there any chance of having a top view game with a 2d physic engine like chipmonk or box2d settind the 3d positioning?
Hi Gil…
It depends on what you want to control. If you just want the 3D for a backdrop, you can control the 2D cocos2d sprites on the top layer with box2d or chipmunk.
But those physics engines wont control the nodes in the 3D world.
…Bill
Do you have a sample code of it running with a Box2d physic engine? Do you think Is it simple to implement?
I will try it, I think it might work good for a race game, I could add springs for curves letting the car rotate 5 degrees on it’s Z on the curves, it might give a nice felling.
I’m thinking something like I did for http://www.formulanova.com but having a 3d Scene without road mountains, just a 2d physic engine top view.
Hi Gil…
I suggest you search the cocos3d forum for both cocos3d and box2d.
Several of the contributors there have integrated the two quite successfully.
…Bill
hello Bill,
im using cocos3d 0.5.2, and im getting build warnings in xcode about having multiple position: getters and setters… one in cocos2d’s CALayer
@property CGPoint position;
and the other in CC3OpenGLES11Lighting:
@property(nonatomic, retain) CC3OpenGLES11StateTrackerLightVector4* position;
it is not creating any problems and everything is running fine but im just wondering what i need to change to remove the warning… or is this fixed in later versions of cocos3d?
Hi Kareem…
It’s extremely unlikely that a
CC3OpenGLES11Lighting
class could be getting mixed up with theCALayer
class. The two classes are completely unrelated.Have a look at how your code is structured. If you still have problems, can you copy the exact error message and paste it here, please?
…Bill
the warning is appearing on any line i use [lang] setPosition: [/lang] on subclasses of CCSprite or CCLayer (not related to cocos3d in anyway). the warning says: “Multiple methods named ‘position’ found”… and they direct me to the properties i mentioned earlier. note that the warning does not appear if i do [lang] mySpriteSub.position [/lang] but only if i do [lang] [mySpriteSub setPosition:aPosition] [/lang]…
I did not start my project using cocos3d templates. It was an old cocos2d project and i simply added cocos3d source files to it. Also i am adding my only CC3Layer as a sub layer to a CClayer.
sorry false alarm… turns out i was calling setPosition: on CCNodes created as id objects… the warning went away with casting. sorry about that.
Hello again Bill,
i am having a problem with the device orientation and cocos3d. When i started my project, i had my autorotation set to kGameAutorotationUIViewController from GameConfig.h… now i want to remove autorotation support and only view things in landscapeLeft… when i changed the cocos2d GAME_AUTOROTATION kGameAutorotationNone, everything was fine with cocos2d but all my 3d objects are now misplaced in Z. I tried playing around with several autorotation values from the RootViewController but nothing seems to work. any ideas?
Hi Kareem…
cocos3d does not use
RootController
. Instead, it usesCCNodeController
, which is compatible with both cocos3d and cocos2d.Please see the
AppDelegate
class in any of the hello, world template, theCC3DemoMashUp
demo, or theCC3Performance
demo for examples of how to control device orientation with theCCNodeController
.You can fix it to a particular orientation, or you can configure it to autorotate.
…Bill
Hi Bill,
wonderful project (and really nice transparent integration witch cc2d), i’m facing a problem and i dunno if its my fault or something in the framework:
i modified the default cc3d project: i created n CC3PlaneNode , each of them uses a texture, i place them on z axis using ground.location = cc3v(rect.origin.x, rect.origin.y, -990.0+(30*i)); where -990 is a nice distance from the camera and i is an incremental number (i=0…1…2…etc) so the distance from the camera decreases but i detected rotating the objects (with an action) that all of them are on the same plane! the z is not affecting them, the z are:
-990
-960
-930 and so on…
Note: the textures are transparent png.
Have you any suggestion?
CC3PlaneNode *ground = [CC3PlaneNode nodeWithName:[NSString stringWithFormat:@”n_%i”,i]];
[ground populateAsCenteredRectangleWithSize: rect.size
withTexture: [CC3Texture textureFromFile:[content objectForKey:@”filename”]]
invertTexture: YES];
ground.isOpaque = NO;
ground.location = cc3v(rect.origin.x, rect.origin.y, -990.0+(30*i));
ground.rotation = cc3v(-180.0, 180, -180);
Hi Neogene…
Please use the cocos3d forum for further questions. You’ll be able to make use of the community for help.
In what direction are you rotating the planes? And where is your camera?
If your camera is looking down the default negative Z-axis, and you are rotating all of the planes around the X or Y axis, they will indeed all appear inline at 90 degrees, because each is rotating along its own axis (eg- try holding out your hands with one covering the other with a bit of space between them, then rotate your wrists).
If you are trying to rotate them all together and retain their spacing, you need to add them all to a parent node and rotate that parent node instead.
Try modifying your code to create a
CC3Node
as a parent (call it saycardHolder
), then add the planes to it atZ = i * 30
. Add thecardHolder
to theCC3World
, and place it atZ = -990
.When you now rotate the parent
cardHolder
node, you’ll see that it maintains the relative spacing of the planes it is holding.You can see something like this in the
LandingCraft
class of theCC3DemoMashUp
demo, where many robot arms are added to a parentCC3Node
.…Bill
Thank you bill, i managed changing the to nil;
I signal probably a bug:
1) create a CC3PlaneNode using a transparent png:
[head populateAsCenteredRectangleWithSize:headRect
withTexture:[CC3Texture textureFromFile:@”first.png”] invertTexture:YES
];
2) set opaque property to NO;
3) change after a touch event or other events the texture using:
[head populateAsCenteredRectangleWithSize:headRect
withTexture:[CC3Texture textureFromFile:@”second.png”] invertTexture:YES
];
The second time i change the texture it shows black in transparent areas, so i have to set the node to opaque=NO again to have the transparent texture again.
Hi Neogene…
The
populateAs...
methods are meant to be constructor methods, so they set a number of default property values.If you want to simply change the texture, do so via the
texture
property ofCC3Material
.…Bill
first row: I managed changing to nil the drawingSequencer;
Nice work!
I already stated using it and I have a problem:
I have 3D object loaded (a thin tube) that’s supposed to be a wire between 2 points (loose, not stretched).
I want to make it swing a bit left-right. How can I modify it to appear as it is swinging?
Thank you very much!
Excellent library!
Hi George…
Please submit your questions to the cocos3d forum to get answers from the cocos3d developer community.
In your case, I guess you could make the two end points the zero-points in your mesh and then just rotate the node back and forth by a few degrees using the
rotate
property.…Bill
Thx! I learned a lot about 3d engines by reading this programing guide. It’s a long time I wish to make a step in the 3d world and I feel I could do it with your engine. Thx again.
how to show game center leadboard in cocos3d?
and how to handle the leadboard orientation?
Hi cocoachina…
Please submit your questions to the cocos3d forum to get answers from the cocos3d developer community. Others there might have dealt with it already.
…Bill
i have showed game center leadboard successfully,
in AppDelegate.m add the line :
window.rootViewController = viewController;
but the leadboard won’t change orientation automaticlly while showing
Great work with cocos3d. Been studying the samples.
I’m still confused as to how one can create a mesh with code.
Basically I want to make a rectangular mesh and split it into triangles and then have access to all the points in order to change their positions during the game thus altering the mesh.
Hi Mihai…
For simple examples of how to construct a mesh from vertices, have a look at the
populateAs...
methods ofCC3MeshNode
. For example, check outpopulateAsSolidBox:
.Once you have constructed a mesh (either using a 3D editor, or programatically), you can manipulate the data on the vertices using accessor methods like
setLocation:at:
,setTexCoord2F:at:
, etc. of the variousCC3VertexArray
subclasses that hold the mesh data.…Bill
Hi there, is it possible to use this software/coding to embed a 3d model viewer into an iphone app? I’m a novice developer looking for a plugin that will allow my users to call an ACTION that will open a small 3D/MD2 model so cached within the app and allow them to rotate zoom and leave model and return to main page. My iphone app knowledge is basic but modelling is good. Appreciate your time and advice. 🙂
Hi Mark…
Yes, cocos3d will do what you describe.
You will need to convert your model to POD file format. See this article for more on that.
…Bill
Thanks Bill, I was able to make a cube programmatically. Is there a way to control the mesh resolution?
Hi Mihai…
If you’re referring to the number of triangles in your mesh, the factory methods for creating planes do allow you to define tessellation. For example, the
populateAsRectangleWithSize:andPivot:andTessellation:
method.Have a look at how that method is structured to develop your own mesh creation.
Going further, you can scan the internet for code algorithms for creating basic shape meshes programmatically.
Alternately, even for a simple cube or ball, you can use a 3D editor to create the mesh for you, in whatever level of mesh structure you want.
…Bill
Thank you for the quick response Bill. Back to your answer on my previous question, all these inner vertices should be accessible through the CC3VertexArray class, am I correct?
Also, am I correct in assuming that a rectangle mesh has only one instance of CC3VertexArray?
Hi Mihai…
Please submit further questions to the cocos3d forum. Others can help answer your questions, and also benefit from seeing the collective answers.
CC3VertexArray
has several subclasses. Typically a mesh will have several arrays, one for vertex locations, another for normals, another for text coordinates…but only one of each type, unless you are using multi-texturing.The arrays can use interleaved data if you want.
The underlying vertex data can be read and manipulated by accessor methods such as
locationAt:
and setLocationAt:. Be sure to familiarize yourself with theshouldAllowVertexBuffering
andshouldReleaseRedundantData
properties to help you retain the data in main memory so you can manipulate it.Again…have a look at the
populateAs...
methods to get an understanding of how they work together.…Bill
Hi Bill, this looks great! This may have been asked before, so I apologize if it has – is there a way to loop through a 3d animation, writing each frame to a sprite-sheet? For instance, I want to make an isometric game, allowing for player customization, so using 3d parts and animations would be great, however for speed purposes I want to stick to animated sprite sheets for each character. Is this something that I can do with cocos3d? Thanks!
Hi James…
Nothing automatic. But there are solid render-to-texture features in cocos2d, and since cocos3d runs inside a cocos2d layer, so you may be able to easily render the 3D scene to a texture through cocos2d capabilities.
…Bill
That’s actually along the lines of what I was thinking Bill, thanks. I’ve been away on my honeymoon & haven’t yet had the chance to actually dig into cocos2d or 3d yet, but is there a way to set up a camera and your character and run through the 3d character’s animation without actually rendering to screen? I’m just assuming here, but I create the 3d character, set it up, but don’t addChild, right? Would I then have to manage the memory myself and dealoc it manually?
Hi James…
No…you should be able to just set everything up as you normally would, 3D models, cameras, lights, animation, etc. You can let cocos3d do all the memory management for you.
Just don’t add the
CC3Layer
to the cocos2d director. Render it to texture instead. I’m not an expert on cocos2d rendering to texture…so I can’t give you much more advice than that. It looks to be fairly straightforward. And if you get stuck, check out the cocos2d forum.…Bill
Yep, that’s the plan 🙂 Even if renderToTexture won’t work there’s more than one way of getting the bitmap data & outputting to a cached file. Thanks for your responses Bill, I’ll try to keep people posted on my progress over the next couple months on your cocos3d forums.
I guess I couldn’t really do what I need without some sort of bones or BIP + skin support though – I know you mentioned it’s something you were working on for future iteration, do you know your proposed timeline for such a feature?
Basically, and this is all theoretical, I’d need a way to export each armor & weapon for each character’s animation, then assemble the character based on current weapons, armor, & character’s customization, and then for each animation render to a spritesheet all of the frames of each animation. With each weapon change I’d have to re-render everything though, so I’m not sure if it would take too long. The other thought is to have every possible combination as single pngs, which can be assembled on the fly to 2d spritesheets. The problem with this is the size of the download would be huge I’d think, so that’s why I thought using iOS support for 3d and then baking on the fly would be best.
Am I completely out of my mind??? 🙂
Hey Bill,
Great job on cocos3d. I’ve found it very useful and easy to use.
I have found an issue with vertex colors that I suspect has gone overlooked due to lack of use.
For some reason PVRFoundation is missing a few PVRT data types including ARGB and RGBA. I have a fix that works that I will post to the forum. It would be nice if these changes could get merged in to the release so I don’t have to insert it every time I upgrade.
Also, I’ve been working on Bone + Skin support for meshes using glMatrixPaletteOES which is nearly integrated with cocos3d. It works, but the transformations are still incorrect, due to my lack of understanding of the way cocos3d handles the matrix stack. Unlike the vertex color issue, bone skinning has been designed as a plugin so I can work on it while you release changes.
Chris
Hi Chris…
Thanks for working on your extensions.
Please post the PVRT data types code to the forum, and I’d be happy to roll it into the next release.
Also, when you get to a point that you’re happy with on the Bone Skinning, I’d be happy to have a look at it, and see if it would make sense to roll it into the main development (giving proper credit to you for your efforts).
As you are working on that, if you have any questions about how the matrix transforms work in cocos3d, or if I can help point you in the right direction about anything, please contact me at support@brenwill.com.
Thanks…
…Bill
Hi again Bill
I’d like to make sure I understand if I am using the setlocation at method properly.
Is the index created by traversing the mesh in the x direction first, then moving to the next row, etc?
Thanks!
Hi Mihai…
The index of
setLocation:at:
is simply the index into the mesh vertex array, which is just one big long array ofCC3Vectors
.If you’ve created the mesh programmatically, the order of that array is whatever you set.
If you’ve created the mesh using a 3D editor, then the order of that array is whatever order the 3D editor laid out for the mesh.
It is not related to the X, Y & Z coordinate system, and is more typically aligned to the drawing order.
…Bill
But the indexing is automatically created by the method “populateAsRectangleWithSize:andPivot:andTessellation:”
, so I was wondering if that follows x/y (e.g. first and second coordinates in the default cc3v argument list)
See sketch here:
http://img710.imageshack.us/img710/9422/2dcoords2index.jpg
Thanks
Hi Mihai…
The best thing I can suggest is review the code in the method you mention to determine the order it lays out the vertices.
If that order is not usable for you, you could consider writing a version of that method that lays out the vertices in a more useful order.
…Bill
So, i installed cocos2d, created new cocos2d project, everything was ok. when i installed cocos3d the demo projects not run: CCDirector.h:32:9: fatal error: ‘kazmath/mat4.h’ file not found
Hi akbar…
Please post your questions to the cocos3d forum.
The file
kazmath/mat4h
is not part of cocos3d.But in any case, have you run the
install-cocos3d.sh
script, as explained in theREADME
file?…Bill
Of course.
Hi, I have the problem, here is how I install cocos3d. The problem is this, the .sh doesn’t copy or link kazmath folder inside cocos2d.
sudo ./install-cocos3d.sh -u -f -2 /Users/me/Documents/Cocos2D/cocos2d-iphone-2.0
Password:
cocos3d installer
Linking cocos2d libraries to workspace
…linking cocos2d files
…linking FontLabel files
…linking CocosDenshion files
…linking cocoslive files
…linking cocoslive dependency files
done!
…creating Xcode 4 cocos3d template folder
Installing Xcode 4 cocos3d iOS template
—————————————————-
…creating destination directory: /Users/marcelanievas/Library/Developer/Xcode/Templates/cocos3d/cocos3d Application.xctemplate
…copying cocos3d Application template files
…creating destination directory: /Users/marcelanievas/Library/Developer/Xcode/Templates/cocos3d/cocos3d Application.xctemplate/Resources
…creating destination directory: /Users/marcelanievas/Library/Developer/Xcode/Templates/cocos3d/cocos3d-base.xctemplate
…copying cocos3d-base template files
…creating destination directory: /Users/marcelanievas/Library/Developer/Xcode/Templates/cocos3d/cocos3d-lib.xctemplate
…copying cocos3d-lib template files
…copying cocos3d files to cocos3d-lib template
done!
Well, Instead of using cocos2d-iphone-2.0, I’ve used cocos2d-iphone-release-1.1-RC0 and It is working !!!! 🙂
So the problem is with cocos2d 2.0
Thanks !!!!
Hi Marce…
There’s a compatibility relationship between versions of cocos3d and cocos2d.
cocos3d 0.x must be used with cocos2d 1.x.
cocos3d 2.0 supports both cocos2d 2.x and cocos2d 1.x.
..Bill
can I do some Crash test on the cocos3d engine?
Hi yilang…
I’m not sure I understand your question.
Do you mean “crash” as in debugging…or do you mean “crash” as in collision detection?
If you mean collision detection, please post your questions to the cocos3d forum. And you can search that forum as well. There are a number of people who have been working on various types of collision detection.
…Bill
It works! There was problem with versions.
Thank you for answer.
Hi all, Im implementing some 3D application for my research and I decided to use cocos3D for its large content. I tried to create a box using populateAsSolidBox
[objc]
CC3MeshNode* makeCube(float xSize, float ySize, float zSize,
float originX, float originY, float originZ, BOOL wired)
{
CC3BoundingBox bounds = makeBounds(xSize, ySize, zSize, originX/2, originY, originZ);
CC3MeshNode *cube = [[[CC3MeshNode alloc] init] autorelease];
[cube populateAsSolidBox:bounds];
if (wired)
{
[cube addChild:makeWire(bounds)];
}
cube.location=cc3v(originX,originY,originZ);
return cube;
}
[/objc]
But the cube is not drawn to the location specified. I am also drawing the boundingbox of the cube and it seems to be in the right location and the cube is drawn to some other location. Is there a problem with the vertices of the cube? may be this needs a fix? when ur not drawing to the origin there is a problem with the location for solidbox thing.
Thanks in advance!!!
Hi Akbar…
Please ask you questions in the cocos3d forum. You’ll get better help there.
There shouldn’t be a problem with mesh nodes. What is your implementation of your
makeBounds()
method? Keep in mind thatCC3BoundingBox
uses a minimum and maximum vertices, not an origin and size.…Bill
Thanks Bill, I will lay out my mesh height by coordinate to see what goes where 🙂
Hi,
i want to run CCShakyTiles3D action in cc3world rather then cc3layer so how can i animate cc3node using CCShakyTiles3D action in cc3world?
Hi Manish…
If you want to shake the 3D world as a “tile”, then you can apply
CCShakyTiles3D
action to theCC3Layer
, which is just aCCLayer
.If you want the layer to stay stationary, and the 3D world to shake around within it, write a 3D version of
CCShakyTiles3D
, using it to move the location of theactiveCamera
around.You can get an understanding of how 3D versions of
CCActions
differ from 2D version (not by much really…each implementation is pretty simple), by reviewing the code for the subclasses of theCC3TransformBy
class in theCC3ActionInterval.m
file.…Bill
[…] http://brenwill.com/2011/cocos3d-programming-guide/ […]
Hi Mr. Hollings
Big thanks for your great work!
I need some objects on the room with complete light but I have problem with world light.
I’m using POD file for my resource objects. I inserted some lights on the world using Blender and when I render it, it shows me great sence. But in iPad I can’t see all objects!
I read your demos carefully, but i can’t understand what is different between my code and yours.
Thanks
Hi Rajabi…
Please post further questions to the cocos3d forum, where you’ll get better help.
Try displaying your exported Collada file in Preview (by simply double-clicking on the
DAE
file), and thePOD
file in PVRShaman that comes with the PVR tools. That will let you know whether the lights are in the files.In cocos3d 0.6.1, you can turn on the
LOGGING_REZLOAD=1
compiler build setting (its on by default in the 0.6.1 template and demos) which will log the details of your POD file as it is loading. That will also show whether the lights are in the POD file.Finally…you can easily recreate your lights programmatically in cocos3d. See the template or the
CC3Performance
demo, each of which programmatically place a light.…Bill
Besides the fact that this next statement would cover my own selfish need, I think a start to finish tutorial on creating a die and multiple dice with a 3d rolling of the cube(s) would increase the adoption rate of cocos3d. I’ve stopped several personal projects based solely on the fact without a user attractive dice rolling, I myself wouldn’t even want to use the games I was making.
Hi Jody…
Have you had a look at the rotating die cube in the
CC3DemoMashUp
demo (as of 0.6.1)?…Bill
Hi Bill,
i am new to cocos3d,can you please provide me guidance regarding to POD file.which software is used for create POD file and from where i can download software to create POD file.
Hi Bill,
I am working on AR with cocos3d and want cocos3d backround as transparent display. Please suggest something different because I had tried every code that makes the cocos3d background transparent.
And I don’t want to use CCNodeController’s isOverlayingDeviceCamera property as NO.
I don’t want to use CCNodeController’s isOverlayingDeviceCamera=YES.
Hi Sandeep…
Why can you not use the
isOverlayingDeviceCamera
property?If you don’t want to use that property directly, have a look at what it does in the source code.
Primarily, you need to open an image picker controller, and set the
glClearColor
to transparent black {0, 0, 0, 0}.…Bill
hi guys!
is there a way to get the api reference incorporated to the xcode cocumentation?
regards
The cocos3d API documentation is created using Doxygen.
You can create your own local copy of the API documentation using the
doxygen.config
file in theDocs/API
folder in the cocos3d distribution.You might be able to adjust the Doxygen configuration to output into an Xcode format. I’ve never tried.
…Bill
Someone can help me? I need an iPhone application that can load .ltd eulumdat files and can show a couple of ambient rendered for giving an idea of what light can do. I have the ltd files, thus can be multiplied till x16 for simulating the number of module on lamps … there’s someone that can help me?
Best regards
Sincerely
Carlo
Hi again Bill.
I’m trying to have some rectangles that face the user.They show up when I am creating them as nodes (populate centered rectangle/ setting a color) and adding them to the world (of course, they don’t auto-orient themselves. sometimes my program crashes but that’s another issue)
But adding them to CC3TargettingNodes and adding those to the world doesn’t work.
I’m pretty sure I am doing the same routine as in demomashup
Are there any limits to CC3TargettingNodes I should be aware of?
Just an update on export from Mac Maya, there now is an exporter for Mac in the PVRGEOPOD download from Imagine so you can go directly from Maya on Mac to a .pod file for importing into Cocos3D.
Cheers
Ian
SundialSoft
Hi Bill. I’m having a little problem. I have a scene that supports node picking. When I run my scene, at the beginning, when I pick one or two nodes, Allocations instrument shows me a memory allocation peak, and the scene frezzes a little. What can I do to avoid this issue? Thanks in advance.
Hi Kotliarov…
Try experimenting with the CC3DemoMashUp.
I expect that the stuttering is a result of the profiler collecting data. It does not seem to occur when the profiler is not running.
There are occasional small jumps in memory, but nothing large, and most of the time they settle back down.
Nothing seems tied to touches, except when touching the ground, which creates new teapot and explosions nodes, and does add a small amount of memory (for the node, not a new mesh).
…Bill
Hi bill, as you say the stuttering happens only once. I preallocate all textures before begin the scene, but this doesn’t fix the problem. Maybe there is some code I didn’t inspect yet. Thanks a lot for your time.
Hello Bill. I have a new problem. I’ve been using CCMotionStreak for a few days, with the
-(void) ccTouchMoved: (UITouch *)touch withEvent: (UIEvent *)event
{
CGPoint touchLocation = [self convertTouchToNodeSpace:touch];
[streak setPosition:touchLocation];
}
approach and I noted that first time it draws Ok, but from second time, the ribbon draws the first visible triangle of the strip inverted. Can you tell me if it could be a bug or I am doing something wrong? Thanks.
Hi Kotliarov…
I haven’t used `CCMotionStreak`, so I can’t really help you there.
It seems very strange that a single triangle would be inverted. The mesh is simply submitted as is to the GL engine.
Try submitting your question to the cocos3d forum.
…Bill
Thanks Bill.
Hi Bill,
first i want to thank you for this great job that you have done, its really amazing !
i’m new to the 3D world but i think i’m doing just fine till now.
i’m creating a CC3MeshNode from a POD file and i want to call [objc] movePivotToCenterOfGeometry [/objc] on it but it throws [objc] reason: ‘-[CC3PODNode movePivotToCenterOfGeometry]: unrecognized selector sent to instance [/objc]. can you provide me the best way to create a CC3MeshNode from a CC3PODNode ?
I just changed the pivot in Blender and it worked. but is there a way to create a CC3MeshNode from a CC3PODNode ?
Hi Alexy…
It’s much better to search for answers and post questions to the cocos3d forum.
In particular, this posting provides an answer and explanation to your question.
…Bill
[…] cocos3d Programming Guide. […]
Hi guys,
I am going to get straight to the point:
I have a plane (x by y dimension) and I want to deform it using a specific formula: z = f(x,y) . Does the new version of Cocos3d support this ?
Thanks in advance!
Hi Alex…
Yes, you can manipulate individual vertices using the
setVertexLocation:at:
family of methods.There are also related method for other vertex content such as normals, colors and texture coordinates.
…Bill
Hi, all I want to do is go into the main class and display a line of text into the cocos3d environment.
Such as “The path was long and curved around the hill” and place this line at say 20,30 xy coordinates.
Thanks, David
Hi, Bill
I’m beginner and stunned by a problem . When nodes(CC3PlaneNode) contains sub-nodes. I used in AR when rotate cc3camera nodes draw not correct.
In link picture black pic is parent node(CC3PlaneNode) sub nodes are labels, userIcons.
http://mng.hotpodcn.com/backend/AppFileMysqlDownload?id=52
thanks!
screen capture: http://mng.hotpodcn.com/backend/AppFileMysqlDownload?id=53
Hi Bill,
I want to create a plane with texture, and the texture png has some transparent part. However, the transparent part is render as black hole in my test. can you help me ? The code is just modified from demoMashUp:
[lang]
ground = [CC3PlaneNode nodeWithName: kGroundName];
[ground populateAsCenteredTexturedRectangleWithSize: CGSizeMake(kPageWidth, kPageHeight)
andTessellation: ccg(1, 1)];
ground.texture = [CC3Texture textureFromFile: kPageTexture];
[ground alignInvertedTextures];
// To experiment with repeating textures, uncomment the following line
// [ground repeatTexture: (ccTex2F){1.0, 3.0}];
ground.material.specularColor = kCCC4FLightGray;
ground.location = cc3v(0.0, 0.0, -kPageHeight);
ground.rotation = cc3v(-90.0, 0.0, 0.0);
ground.shouldCullBackFaces = NO; // Show the ground from below as well.
ground.isTouchEnabled = YES; // Allow the ground to be selected by touch events.
[ground retainVertexLocations]; // Retain location data in main memory, even when it
[/lang]
Hi yorkdu…
It’s much better to search for answers and post questions to the cocos3d forum.
In the
CC3DemoMashUp
demo app, uncomment the following line[objc]
// [self addFloatingRing];
[/objc]
in the
initializeWorld
method ofCC3DemoMashUpWorld
.This will display a transparent floating ring. The
addFloatingRing
method demonstrates how it is created.…Bill
Hi Bill,
You are doing a great job! I tryed cocos3d once ago, but I´ve declined using couse it had no physic engine.
Once ago I did a top view racing game using flash Papervision3D and box2d as physic engine, do you think it´s easy to use box2d and Cocos3d?
I´m thinking on lauching SoccerVirtualCup 2 using a 3d engine, even if it has to do physics on 2d top view.
Please let me know what you think.
Hi Gil…
There a several options for including physics into cocos3d.
As of version 0.7.0, cocos3d now includes simple collision detection, allowing you to tell when a node is colliding with another node, or whether, and where, a ray (such as from a touch, or bullet track) intersects a node.
Beyond that, there are a number of posts on the cocos3d forum from users who have successfully integrated either box2d or Bullet to cocos3d.
Search the forum for references to cocos3d box2d or cocos3d bullet.
…Bill
[…] 作者说明 —— 翻译 […]
[text]Hi Bill..[/text]
[text]I am trying cocos3d for the first time.I have refered your tutorials for that.I have tried to implement cube and sphere and to rotate the same.It is working fine.
But for pod files it is not working I am using blender 2.61 and collada 2.11 to create pod files [/text]
[objc]
rezNode = [CC3PODResourceNode nodeFromFile: @"trial.pod"];
n = [rezNode getNodeNamed: @"trial"]; // This object is returning nil
[n remove];
n.isTouchEnabled = YES;
[templates addObject: n];
[/objc]
[text]In NSLog rezNode is not nil, but n is nil.[/text]
Hi Priyanka…
In future, please ask questions in the cocos3d forum. Your questions will get answered by a larger user community, and others can benefit from the answers.
If you are using the hello, world template application, at the end of your
initializeScene
method, you should see the line:LogCleanInfo(@”The structure of this scene is: %@”, [self structureDescription]);
This line logs the structure of the nodes in your scene, including the names. From that log entry, make sure that the node you want actually exists in your POD, and that the name of the node is the same as the name you are using to retrieve that node. Also, make sure the logs do not contain any ERROR entries indicating that the POD file could not be loaded.
…Bill
Hi Bill..
Thanks for your response.
Yes, From the next time I will surely ask questions on cocos3d forum..:)
I tried what you suggested.
code is crashing at this line:
[objc][templates addObject: n];[/objc]
I have logged rezNode description after this line,
[objc]rezNode = [CC3PODResourceNode nodeFromFile: @"trial.pod"];
NSLog(@"The structure of this scene is: %@",[rezNode structureDescription]);[/objc]
Console is showing this:
[objc]transformation in CCNode : YES
2012-06-06 10:28:23.874 dieCubeDemo[392:cb03] -[CCConfiguration init] : cocos2d: compiled with Profiling Support: NO
2012-06-06 10:28:23.904 dieCubeDemo[392:cb03] -[ES1Renderer resizeFromLayer:] : cocos2d: surface size: 480×320
2012-06-06 10:28:24.024 dieCubeDemo[392:cb03] The structure of this scene is:
CC3PODResourceNode trial.pod:1
2012-06-06 10:28:24.030 dieCubeDemo[392:cb03] *** Terminating app due to uncaught exception ‘NSInvalidArgumentException’, reason: ‘*** -[NSMutableArray insertObject:atIndex:]: attempt to insert nil object at 0’
[/objc]
Hi Priyanka…
As you can see from the log line:
[objc]CC3PODResourceNode trial.pod:1[/objc]
there is nothing in your POD file. Compare that to the log from the hello, world template, or the
CC3DemoMashUp
.Your line:
[objc]n = [rezNode getNodeNamed: @"trial"];[/objc]
is therefore returning
nil
, which again, you can verify by logging, and that is causing the error when you try to add it to yourtemplates
array.…Bill
Could you post this user guide as a .pdf file?
Hello,
Great job !!!
However I have a problem with a UITextField. When I change the orientation of the device all the nodes are moving accordingly (3D, sprites, CCbuttons…) except the UITextfield. On my other apps that only use cocos2d it works fine, it seems that the use of cocos3d changed something but I can not find what and how.
Your help would be appreciated.
Waca
Hi Waca…
In future, please ask questions in the cocos3d forum, where other users can answer your questions and benefit from the answers.
If you want to have the
UIKit
perform the rotation so thatUIKit
components are rotated as well, you’ll need to make use of theRootController
from cocos2d.cocos3d can be used with the cocos2d
RootController
. Have a look at theCC3Demo3DTiles
demo app for an example of doing so.…Bill
Many thanks for your help, and sorry for using the wrong site.
Regards,
Hello,
I just installed the Xcode template and it appears to delete the content of the folder where the project is created (delete, not put in Trash)!!
I just loose all the content of my Desktop folder :'(
I think it would be nice to fix this.
Fabien
Hi Fabien…
Sorry for the delay in responding. I’ve been out of town.
Typically the issue you describe arises when trying to use cocos3d with cocos2d 2.0.
cocos3d requires cocos2d 1.x, and is not compatible with cocos2d 2.0.
Please see the README file in the cocos3d distribution for more compatibility info.
And when saving projects from the templates, be sure to avoid saving the project back to the template directory.
…Bill
Hi Bill,
I am new to 3D game development. When I started to learn cocos2d, tutorials helped me so much. But for cocos3d I haven’t found any. Can u suggest me.
Thanks
Hi Ruchita…
We’re working on a documentation and tutorial web site, but it’s not ready yet.
In the meantime, your best bet is to play with the
CC3DemoMashUp
demo app, and review the code in that app.The programming model of cocos3d is similar to cocos2d, in its use of hierarchical nodes, and
CCActions
.…Bill
Hi Bill,
Thanks for response. Cocos3D is really very good. Now I am comfortable with this engine.
I need your help to implement “Physics with cocos3D”.
Thank you so much
Hi Ruchita…
cocos3d includes basic collision detection. Have a look at the teapot and brick wall in the
CC3DemoMashUp
demo app.If you’re looking for a complete physics engine, there are several initiatives that have integrated cocos3d with Bullet and Box2D. Search the cocos3d forum using keywords cocos3d and either bullet or box2D.
…Bill
[…] 作者说明 —— 翻译 […]
Hi,
When I get the cocos3d zip, demos projects are missing cocos2d sources, is their any configuration to do ?
Thanks,
Sorry for the post, I just collecte those sources from different projects.
Regards,
CC3MeshNode* helloTxt = (CC3MeshNode*)[self getNodeNamed: @”Hello”];
where i can get hello
Please post questions to the cocos3d forum, where the community can help you.
When you do, please clarify your question. I’m afraid that I don’t understand what you are asking.
…Bill
Hi Bill
i create 2 CC3BoxNode instance in my CC3Scene instance. just like:
CC3BoundingBox x;
x.minimum = cc3v(-0.5,-0.5,-0.5);
x.maximum = cc3v(0.5,0.5,0.5);
CC3BoxNode *box1 = [CC3BoxNode nodeWithName:@”box1″];
[box1 populateAsWireBox:x];
box1.location = cc3v(0,2,0);
[self addChild:box];
CC3BoxNode *box2 = [CC3BoxNode nodeWithName:@”box2″];
[box2 populateAsWireBox:x];
box2.location = cc3v(0,-1,0);
[self addChild:box2];
and i want to know does they intersect. so i add this node in update: in my CC3Layer
CC3MeshNode *box1 = (CC3MeshNode*)[self.cc3Scene getNodeNamed:@”box1″];
CC3MeshNode *box2 = (CC3MeshNode*)[self.cc3Scene getNodeNamed:@”box2″];
CC3NodeBoundingVolume *bv1 = [box defaultBoundingVolume];
CC3NodeBoundingVolume *bv2 = [box2 defaultBoundingVolume];
if ([bv1 doesIntersect:bv2]) {
NSLog(@”intersect”);
}
[super update:dt];
and i get “intersect” log every frame,but they are not intersect.
then i move the box and i still get the “intersect”log.why?
if i want to use the AABBbox to check intersect.what should i do?
and i think maybe i find a bug or just my mistake?
in my app.”addContentFromPODFile:withName:” method doesn’t change the name.i don’t know why.
in template,
[self addContentFromPODFile:@”hello-world.pod” withName:@”pod”];
this method doesn’t change this node’s name,name still is “Hello”
so i have to
[self addContentFromPODFile:@”hello-world.pod”];
CC3MeshNode *p = (CC3MeshNode*)[self getNodeName@”Hello”];
p.name = @”newName”;
to change the name.
Thanks!
In future, please post questions to the cocos3d forum, where the community can help you.
Regarding your first question, one of the nice things about having open-source code is that you can look at the implementation of the framework. :^)
Have a look at the implementation of
defaultBoundingVolume
. It creates and returns a bounding volume, but does not configure it for the mesh or the node, and it is not transformed as you move the node.What you want to use is the
boundingVolume
property of the node. It is populated automatically, and is automatically updated as the node moves around.Regarding your other question, have a look at the structural description of your nodes in the log. You’ll see that the
addContentFromPODFile:withName:
has loaded the POD into aCC3PODResourceNode
, which is then dutifully renamed to @”pod”. The mesh node that is named @”Hello” is contained within this resource node (since the POD file may contain many other mesh nodes).To rename the @”Hello” mesh node, you should retrieve it by name as you have done, and give it a new name.
…Bill
When will Cocos2d v 2.x be supported?
Hi Curt…
Please check the cocos3d Development Roadmap for guidance on the delivery of upcoming features.
Support for cocos2d 2.x will happen in conjunction with support for OpenGL ES 2.0, which is under development now, with a expected release by the end of March, 2013.
…Bill
Hi Bill, my first posting here as I’m a cocos3d noob (but a gnarled old iOS dev :). I was just looking into whether shaders are supported in cocos3d and I’m really happy to hear you’re planning this whole ES 2.0 / cocos2d 2.x thing… keep up the good work, and I look forward to the new releases!
Lee
Hi Bill,
I’m learning how to use Cocos3D and like the relative simplicity a lot. Thanks for all the work you’re putting in!
Currently I’m struggling to get an orientingWrapper working, using the teapot mesh example. It works for rotation (to change the pivot point of rotation), as described in the documentation, but I can’t get the wrapper to respond to translations by means of the ‘runAction’ method below. The ‘runAction’ method does work on the teapot itself, but not on the wrapper.
What is wrong? Would most appreciate any suggestions.
Regards,
Voppe
[objc]
//VB Get the teapot
CC3ModelSampleFactory *myFactory = [CC3ModelSampleFactory factory];
CC3MeshNode *myMeshNode = [myFactory makeLogoTexturedTeapotNamed:@"myTeapot"];
//Use an orientingWrapper to move the rotation point to the center of the pot and rotate 90 degrees
CC3Node *myTeapotWrapper = [myMeshNode asOrientingWrapper];
myMeshNode.location = CC3VectorMake(0.,-0.08,0.);
myMeshNode.rotation = CC3VectorMake(0,90.,0.);
[myTeapotWrapper addAxesDirectionMarkers];
myTeapotWrapper.shouldDrawAllDescriptors = YES;
myTeapotWrapper.shouldDrawAllWireframeBoxes = YES;
// ‘self’ is the scene
[self addChild:myTeapotWrapper];
//Move the things around around
CCActionInterval* moveX = [CC3MoveBy actionWithDuration:3. moveBy:cc3v(0.5, 0, 0 )];
CCActionInterval* moveMinZ = [CC3MoveBy actionWithDuration:3. moveBy:cc3v(-0.5, 0, -3 )];
CCActionInterval* moveMinX = [CC3MoveBy actionWithDuration:3. moveBy:cc3v(-0.5, 0., 3 )];
CCActionInterval* moveZ = [CC3MoveBy actionWithDuration:3. moveBy:cc3v(0.5, 0., 0. )];
CCActionInterval* moveActionSequence = [CCSequence actions:moveX, moveMinZ, moveMinX, moveZ, nil];
//Following line does NOT work with wrapper (no movement), but works when used on the teapot (the child of the wrapper). WHY?
[myTeapotWrapper runAction: [CCRepeatForever actionWithAction: moveActionSequence]];
[/objc]
Bill,
I found out that by default the ‘isRunning’ property of the wrapper is ‘NO’. This would explain things, BUT… after setting this to YES and checking in the debugger that it indeed has the value ‘YES’, the wrapper (with the teapot in it) still does not move.
A strange thing is that if I set the ‘isRunning’ property to ‘YES’ just before adding the wrapper to the scene and confirming in the debugger that the value is indeed ‘YES’, after the adding to the scene the value is suddenly ‘NO’ again. Moreover, when I set it to ‘YES’ again just before the ‘runAction’ method is used, the wrapper still does not move and the value is ‘NO’ again right after the runAction call.
Looks as if the wrapper does not move because something is changing the ‘isRunning’ property .
Any thoughts at all?
Regards,
Voppe
Hi Voppe
In future, please post questions to the cocos3d forum. You’ll get better support there.
I’m not sure where you’re having difficulty. If I take the hello, world template project, and replace the line: [objc][self addContentFromPODFile: @"hello-world.pod"];[/objc] with exactly your code above, everything works as advertised. The teapot (and wrapper) moves around as expected from your code.
…Bill
Hi Bill,
Thanks for your quick and very useful response.
Sorry for posting here. I didn’t realize there was a forum as well, but will use this in future.
I replicated what you did and indeed everything worked as expected. With this knowledge I will look into why I have problems in my program, but I am sure that I’ll get that sorted out now.
Again, thanks a lot!
Regards,
Voppe
Hi Bill,
I am familiar with cocos2d platform and just recently start playing around with cocos3d API. it is really exiting stuff! Thank you!!!
So I am wondering if you have a sample tutorial somewhere on the internet that would show us step by step how to upload a 3d Image file (i.e replace the existing 3D Hello world with a 3D cube that comes as a default object in blender) ? I am not concerned about the importing complex 3D models into my cocos3d app. When I do it my app crash unexpectedly. I’d love to learn the right way to import 3D files into cocos 3D app. Any help is greatly appreciated.
Thanks,
Umit
Hi Umit…
Follow these instructions for exporting from Blender to the POD file format.
Then start with the cocos3d Application Xcode template and load your own POD file instead of the hello, world file.
Depending on how big your model is and where it is located, you can use the methods in the
onOpen
method in your customCC3Scene
to move the camera to the right position to view your scene.Remember to read the README files and run the
install_cocos3d.sh
installation script.…Bill
Hi Bill,
I would like to create many trajectory paths using key-frames, the path will be randomly selected and attached to an mesh object, i have the following question base on this usage:
1) Looks like CC3Animation only support one key-frame am i correct? does this mean i will need to marge all my trajectory paths in a single key-frame?
2) How can i assign key-frame to another mesh object? Basically the best method is to load all key-frame and attache to any mesh object of my choice, is it possible?
Thanks..
Hi Aaron…
In future, please ask questions in the cocos3d forum where others can participate in the answers.
1) cocos3d 2.0 supports multi-track animation, and you can blend between the tracks by setting weightings on each track. There are even several blending and cross-fading actions that you can apply. Have a look at the large family of animation methods on
CC3Node
and the animation actions inCC3Actions.h
.2) Instances of
CC3Animation
can be shared between different nodes. You can assign theanimation
property of one node to another.…Bill
Hi Bill,
Many thanks… i didn’t notice Cocos3d forum was under cocos2d forum, i was actually looking for it within cocos3d web but unable to find it. I will post all future technical question in the forum. thanks again.
any developments on fbx loading? or if not; recommended way to get fbx (with animations) into pod format?
Hi infrid…
FBX loading is not currently planned. It is unlikely to be used for production loading because it is quite heavy, and poorly managed and documented (from an external loading perspective).
The POD format supports animation. You can create multi-track animation using multiple PODs (you can even have a POD that just contains animation and no model by saving from
CC3PODResource
). You can also import animation in theCal3D CAF
format.Please see this article for instructions about exporting from Maya or 3DS to POD formats.
…Bill
Hi bill,
I am on my way to create a board game using accelerometer. I cant add cc3scene as custom. When i try to create a new class, i can see only CCNODE class in cocos2d section. Cant see the cocos3d section at all !!! Why it is so ? Did i made any mistake in installation part ??
Hi karan…
Did you run the cocos3d installation script as described in the README?
And how did you create your Xcode project? Did you use one of the cocos3d Application templates?
…Bill
Yes, i did. when i start new project i can find one template in cocos3d section , ie cocos3d Apllication template. I selected it and created some sample projects also. But the problem arises, when i add new file to my project.
Hi bill, i got it. i simply re-installed cocos2d and cocos3d following the readme. Then i tried to add new objectiveC class file. I found all the 3d class types. Thanks Bill for your support
Hi Bill,
First of all, congratz on COCOS3D. I am using the framework and its really powerful.
Let me ask you a question. I have a 2D game build on COCOS2D. This game has several diferent Scenes. I want a specific scene to be a 3D scene. That scene will be my main menu and I will be calling it periodically. All other scenes will be 2D.
I have a GameManager class which is a singleton and all other scenes know about it. The GameManager class is invoked like [[GameManager sharedGameManager] runWithScene:{new scene}].
How can I instantiate a new COCOS3D Scene (and Layer) from inside my GameManager Class?
Thanks in advance.
Rodrigo.
PS. Sorry, I just realized I posted this same post on an unrelated thread. My bad.
Hi Rodrigo…
A 3D scene is a subclass of
CC3Scene
. It displays inside aCC3Layer
, which is a 2DCCLayer
that is specialized to work with theCC3Scene
.As a 2D layer, you can display the
CC3Layer
the same way you by display anyCCLayer
. You can wrap it in a 2DCCScene
, and use theCCDirector replaceScene:
method to move between the 3DCC3Layer
and your 2DCCLayers
.…Bill
Hi Bill,
It seems cocos3d conflights with CCScrollView in cocos2d-iphone.
When I add a CCScrollView and a 3d model into the same scene, the 3d model disappears.
Is this a known problem?
Pu
And I found a hacky solution: adding an additional screen size CCScrollView to the scene after the 3D model is added.
It seems somehow the newest CCScrollview in the scene clips 3D models on the screen.
Hi Bill.
I am wondering:
What if I want to look at objects on a scene simultaneously via 2 cameras from 2 individual aspects?
Since all objects are rendered on the scene and each layer only has its self.scene active, how to make “view from multiple aspects simultaneously” happen ?
Sincere thank!
Best
//btw did I succeed submit this question …?
Hi Ray…
In future, please ask questions in the official Cocos3D forum.
It’s not officially supported, but all that is required is to assign your
CC3Scene
subclass instance to two separateCC3Layer
subclass instances.And since you probably want a different viewpoint on the scene presented in each of those
CC3Layers
, you’ll need to add more than once camera to yourCC3Scene
, and toggle theactiveCamera
property before theCC3Scene drawSceneWithVisitor:
method is invoked. One way to do this is to add the following method to each of yourCC3Layer
subclasses:where you’ve exposed the camera that you want for each view in a distinct property in the
CC3Scene
(in this casecameraABC
).If you use this technique, you’ll need to expose the superclass
drawSceneWithVisitor:
method, by adding the following at the top of your each of yourMyCC3Layer.m
files:If you need follow-up to this question, please re-ask this question in the Cocos3D forum
…Bill
understood. Thank you.
For another questions, I shall go to the cocos3d forum.
Sincere thank.
I am not sure whether this code works. I shall try first
-(void) drawSceneWithVisitor: (CC3NodeDrawingVisitor*) visitor {
CC3DemoMashUpScene* myScene = (MyScene*)self.cc3Scene;
myScene.activeCamera = myScene.cameraABC;
[super drawSceneWithVisitor: visitor];
}
It seems that 2 different scene instance is assigner to 2 layers self.cc3Scene.
I shall try first.
If not solved, I shall re-ask it on the forum.
Best
I tranfer to the forum now. plz ignore above reply.
now It seems to work.
Still some minor issues with my code exit to be fixed..