<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Brenwill Workshop</title>
	<atom:link href="http://brenwill.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://brenwill.com</link>
	<description>Software and Media Expertise</description>
	<lastBuildDate>Sun, 01 Jan 2012 19:18:43 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1.3</generator>
		<item>
		<title>cocos3d Importing: Converting COLLADA to POD</title>
		<link>http://brenwill.com/2011/cocos3d-importing-converting-collada-to-pod/</link>
		<comments>http://brenwill.com/2011/cocos3d-importing-converting-collada-to-pod/#comments</comments>
		<pubDate>Sat, 31 Dec 2011 12:00:39 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[cocos3d]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=127</guid>
		<description><![CDATA[<p>cocos3d is able to directly import files formatted in the PowerVR POD file format from Imagination Technologies, the supplier of the GPU used in iOS devices. The POD format is a dense binary format, suitable for the fast loading and minimal memory requirements of a mobile device.</p> <p>This article describes how to create POD <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2011/cocos3d-importing-converting-collada-to-pod/">cocos3d Importing: Converting COLLADA to POD</a></span>]]></description>
			<content:encoded><![CDATA[<p><a href="http://brenwill.com/cocos3d">cocos3d</a> is able to directly import files formatted in the <a href="http://www.imgtec.com/powervr/insider/sdk/KhronosOpenGLES1xMBX.asp">PowerVR POD</a> file format from <a href="http://www.imgtec.com/">Imagination Technologies</a>, the supplier of the <a href="http://en.wikipedia.org/wiki/GPU">GPU</a> used in iOS devices. The POD format is a dense binary format, suitable for the fast loading and minimal memory requirements of a mobile device.</p>
<p>This article describes how to create POD files from COLLADA files for loading into <strong>cocos3d</strong>. <a href="http://en.wikipedia.org/wiki/Collada">COLLADA</a> is an industry-standard exchange format for specifying 3D model data, and most 3D editors support exporting into the COLLADA file format.<span id="more-127"></span></p>
<h3>Acquiring the <code>Collada2POD</code> Converter</h3>
<p>The <a href="http://www.imgtec.com/powervr/insider/sdk/KhronosOpenGLES1xMBX.asp">PowerVR SDK</a> from Imagination Technologies includes several useful tools for working with POD assets. You can download the SDK <a href="http://www.imgtec.com/powervr/insider/powervr-login.asp?SDK=iPhoneOGLES1.1">here</a>. You will need to register and log-in to the PowerVR  site (it&#8217;s a free registration). Once the download is complete, unzip  the contents. The <code>Collada2POD</code> tools are in the <code>Utilities/Collada2POD/MacOS</code> folder (or alternate if you are not using a Mac).</p>
<p>The <code>Collada2POD</code> converter is also available by itself, as a much smaller download <a href="http://www.imgtec.com/powervr/insider/powervr-collada2pod.asp">here</a>. However, because this stand-alone download is packaged as a <code>zip</code> archive, the executable permissions on the utilities are missing. To remedy this after downloading, open a <code>Terminal</code> session, navigate to the <code>Collada2POD/MacOS</code> directory, and run the command &#8220;<code>chmod 755 Collada2POD Collada2PODGUI</code>&#8221; (without the quotes). After that, you will be able to double-click on <code>Collada2PODGUI</code> to run the application, or be able to run the <code>Collada2POD</code> utility from the command line. This step is not necessary when downloading <code>Collada2POD</code> as part of the SDK, because it is packaged as a <code>tar</code>, which preserves the file executable permissions.</p>
<p>You can also have a look at the other PowerVR tools available <a href="http://www.imgtec.com/powervr/insider/powervr-utilities.asp">here</a>, and download them if they strike your fancy. If you&#8217;ve downloaded the full SDK, you should already have them.</p>
<p>Before going any further, I should point out that the PowerVR SDK also includes several 3D editor plug-ins that directly export to POD format, bypassing the COLLADA step. These include plug-ins for <em>3ds Max</em>, <em>Maya</em>, and <em>Blender</em>. However, for the most part, these are not supported on the Mac platform.</p>
<h3>Generating the COLLADA File</h3>
<p>The first step is to generate a COLLADA file from your 3D editor. I discuss how to do this using <a href="http://www.blender.org/">Blender</a>, <a href="#Collada-from-Blender">below</a>. Exporting to COLLADA from other 3D editors is left as an exercise for the reader, but you can use the <em>Blender</em> example below as a guide to understanding the data that should be exported.</p>
<p>There are several evolutionary versions of the COLLADA file format. Creating POD files from COLLADA version 1.4 files has been well tested, but you may experiment with other COLLADA versions as well, if your editor supports exporting to those versions.</p>
<h3>Running the <code>Collada2POD</code> Converter</h3>
<p>The <code>Collada2POD</code> utility can be run either from a <code>Terminal</code> command line, using a configuration file for input, or it can be run as a GUI application. The GUI application is the best way to get started, then once you&#8217;re familiar with the structure and options, you can switch to the command line utility if you prefer that mode of operation (I still use the GUI because it is well laid out and gives dynamic feedback). The two utilities, <code>Collada2POD</code> and <code>Collada2PODGUI</code> are found in the <code>Utilities/Collada2POD/MacOS</code> folder (or alternate if you are not using a Mac) of the SDK, or just the <code>MacOS</code> folder if you downloaded <code>Collada2POD</code> by itself.</p>
<p>The main window of the <code>Collada2PODGUI</code> application looks like this:</p>
<div id="attachment_319" class="wp-caption aligncenter" style="width: 599px"><a href="http://brenwill.com/wp-content/uploads/Collada2POD-2.08.png"><img class="size-full wp-image-319" title="Collada2POD" src="http://brenwill.com/wp-content/uploads/Collada2POD-2.08.png" alt="" width="589" height="815" /></a><p class="wp-caption-text">The main window of the Collada2PODGUI utility, showing the settings used to create POD files for importing into cocos3d.</p></div>
<p>This screenshot illustrates suitable settings for importing into <strong>cocos3d</strong>. For convenience, these settings are captured in the <code>Tools/Collada2PODSettings.txt</code> configuration file in the <strong>cocos3d</strong> distribution, which you can load into the <code>Collada2PODGUI</code> tool using the <code>Load</code> button. You can also use this same configuration file when running the <code>Collada2POD</code> command line utility.</p>
<p>One annoyance is that, for some reason, the <code>Collada2PODGUI</code> tool does not acknowledge the <strong><em>Invert transparency</em></strong> flag in the configuration file, so you will need to manually set this flag after loading the configuration file. If your model is not visible in <strong>cocos3d</strong> when you load your <code>POD</code> file, the first thing you should check is that the <em><strong>Invert transparency</strong></em> flag is set on in <code>Collada2PODGUI</code>.</p>
<p>On the positive side, you can leave the <code>Collada2PODGUI</code> tool open and run it over and over on the same, or different, models using the same configuration settings.</p>
<p>The <code>Collada2POD</code> folder contains a <em>User Manual</em> in the <code>Documentation</code> folder, that explains each of these configuration options, and you can hover your mouse pointer over any of the fields for more information.</p>
<p>You can play with some of these settings, but to avoid frustration, keep in mind the following points regarding how <strong>cocos3d</strong> interacts with these configuration settings:</p>
<ul>
<li><strong>cocos3d</strong>, <em>cocos2d</em>, and the iOS OpenGL ES implementation all use floating point values for vertex coordinates, as the PVR GPU is optimized for floating point operations. So make sure the <em><strong>Fixed Point</strong></em> flag is turned off.</li>
<li>You can choose to <em><strong>Export materials</strong></em>, or not. Typically, you will always want materials, unless you are coloring vertices using color pointers.</li>
<li>The <strong><em>Invert transparency</em></strong> flag must be set on, otherwise  most of your models will not be visible. Also, see the comments above  regarding checking this flag after loading the settings file.</li>
<li>If the file includes animation information, you can choose to include it by turning on the <em><strong>Export animation</strong></em> flag, and <strong>cocos3d</strong> will make use of it to animate your models. To engage animation, you need to set up the appropriate <code>CCAction</code>. See the <code>CC3DemoMashUp</code> example application in the <strong>cocos3d</strong> distribution for an example of how to do this.</li>
<li>You can choose to export <em><strong>Normals</strong></em>, <em><strong>Vertex colours</strong></em>, and <em><strong>Mapping channels</strong></em> (texture coordinates), depending on the content of your model.</li>
<li>Textures on iOS are generally loaded upside-down. With this in mind, you&#8217;ll want to make sure the <strong><em>Flip V Coordinates</em></strong> flag is turned on.</li>
<li><strong>cocos3d</strong> does not make use of tangents or binormals, so you can leave the <em><strong>Generate tangent-space</strong></em> option turned off.</li>
<li><strong>cocos3d</strong> can work with either interleaved, or non-interleaved data. Both <em>Apple</em> and <em>Imagination Technologies</em> recommend interleaving for performance, but you can choose not to, if appropriate for your model. Use the <em><strong>Interleave vectors</strong></em> flag to make this choice. The <em><strong>Align vertex data (to 32 bit)</strong></em> flag does what is says, and will improve performance somewhat, at the cost of increased file size and memory requirements.</li>
<li><strong></strong>If you have constructed your model to use vertex skinning to perform soft-body mesh deformations using bone rigging, turn the <em><strong>Export skin modifiers</strong></em> option on. The <em><strong>Matrix palette size</strong></em> setting indicates the number of matrices available for mesh deformati<em><strong></strong></em>on, and is limited by the GPU in the device. For the <em>PowerVR MBX</em> GPU found on earlier <em>iPod Touch</em> and <em>iPhone</em> models, the matrix palette size is 9, and for the <em>PowerVR SGX</em> GPU found on all later devices, the size of the matrix palette is 11. For most purposes, you can simply leave the value of this property at 9.<strong></strong></li>
<li><strong>cocos3d</strong> currently expects that each POD file only contains one vertex skinned model, so if you are using vertex skinning as described in the previous point, you should ensure that each such model is stored in its own POD file.</li>
<li>For the <em><strong>Primitive Type</strong></em> option, <strong>cocos3d</strong> can make use of either a <em><strong>Triangle list</strong></em> or <em><strong>Triangle strips</strong></em>. <em>Imagination Technologies</em> recommends that <em><strong>Triangle list</strong></em> is a much faster option, because it involves only one OpenGL call to draw the complete mesh. But it does involve some redundant vertex data, resulting in more memory use. Similarly, setting the <em><strong>Indexed</strong></em> option on is recommended, as it will improve performance, usually at the cost of memory.</li>
<li>It is recommended that you sort both triangles and vertices to improve the performance of the hardware data caches. Use the <em><strong>Triangle sort</strong></em> and <em><strong>Sort vertices</strong></em> options to enable this.</li>
<li>The <em><strong>Vertex vector formats</strong></em> option allows you to choose the data that will be exported for each format. Unless you have some special requirements, and really know what you are doing, you can leave these all with their default values.</li>
</ul>
<p>Once you have all your settings configured, in the bottom area of the window, select the COLLADA file (<code>*.dae</code>) that you want to convert, choose the location and name of the output POD file (<code>*.pod</code>), and click the <em><strong>Convert</strong></em> button. The window will flip to the <em><strong>Output</strong></em> tab, so that you can see the conversion status and results.</p>
<p>Finally, drag the resulting POD file to the <code>Resources</code> group in your <code>Xcode</code> project window, and select the option to copy the file to your project directory from the resulting dialog box.</p>
<h3><strong>Coordinate Systems<br />
</strong></h3>
<p>Different 3D editors will use different coordinate systems (<a href="http://en.wikipedia.org/wiki/Cartesian_coordinate_system#In_three_dimensions">left-handed or right-handed</a>), and may orient your model space so that any of the <code>X</code>, <code>Y</code> or <code>Z</code> axes represents the world &#8216;up&#8217; direction.</p>
<p>Please also note that the <code>Collada2POD</code> tool rotates data so that the <code>Z</code>-axis is &#8216;up&#8217;. Since the OpenGL ES default is to have the <code>Y</code>-axis as &#8216;up&#8217;, and the camera looking down the negative <code>Z</code>-axis, it is usually more convenient to use the OpenGL orientation in <strong>cocos3d</strong> (although there&#8217;s nothing stopping you from rotating everything by 90 degrees within <strong>cocos3d</strong>).</p>
<p>With this in mind, in your 3D editor, orient your model world so that &#8216;up&#8217; is along the <code>Z</code>-axis. The <code>Collada2POD</code> tool will then rotate the axes so that &#8216;up&#8217; is along the <code>Y</code>-axis when the model is imported into <strong>cocos3d</strong>. However, depending on your 3D editor, you may need to play with this to get the right combination of 3D editor, COLLADA, <code>Collada2POD</code>, <strong>cocos3d</strong>, and OpenGL ES orientations.</p>
<hr style="width: 90%;" />
<h3><a name="Collada-from-Blender"></a>Generating COLLADA Files From Blender</h3>
<p>During the initial development of <strong>cocos3d</strong>, we used <a href="http://www.blender.org/">Blender</a> version 2.4.9 to create some of our 3D models. So I thought I&#8217;d add some pointers on how to export from <em>Blender</em> to COLLADA in order to get the right data to be converted by <code>Collada2POD</code> and imported into <strong>cocos3d</strong>.</p>
<p>The COLLADA exporter bundled with <em>Blender 2.4.9</em> supports up to COLLADA version 1.4. Choosing <em><strong>File-&gt;Export-&gt;COLLADA 1.4 (.dae)&#8230;</strong></em> from the menu results in the following window opening:</p>
<div id="attachment_143" class="wp-caption aligncenter" style="width: 619px"><a href="http://brenwill.com/wp-content/uploads/Blender-Collada-1.4-Export.png"><img class="size-full wp-image-143 " title="Blender-Collada-1.4-Export" src="http://brenwill.com/wp-content/uploads/Blender-Collada-1.4-Export.png" alt="" width="609" height="729" /></a><p class="wp-caption-text">Exporting your 3D model from Blender to a COLLADA 1.4 file.</p></div>
<p>These settings are used as follows in an export destined for <strong>cocos3d</strong>:</p>
<ul>
<li>Export your mesh as triangles. Polygons are not supported. Make sure that the <em><strong>Triangles</strong></em> option is selected.</li>
<li>You can choose to export only part of your model, or your complete model, by turning the <em><strong>Only Export Selection</strong></em> option on or off.</li>
<li>Matrices are not imported into <strong>cocos3d</strong>. Leave <em><strong>Bake Matrices</strong></em> unselected.</li>
<li>If your model is animated, and you want to export the animation into <strong>cocos3d</strong>, select<em><strong> Sample Animation</strong></em>. However, please be aware that exporting animation has not yet been tested in the full trip through <em>Blender</em> -&gt; COLLADA -&gt; POD -&gt; <strong>cocos3d</strong>.</li>
<li><strong>cocos3d</strong> does not yet import physics information, so select the <em><strong>Disable Physics</strong></em> option to exclude physics information from the COLLADA file.</li>
<li>Select the <em><strong>Use Relative Paths</strong></em> option so that file names for textures will be relative to the exported file, which is how they are referenced in the <code>Resources</code> folder under iOS.</li>
<li>Leave the <em><strong>UV Image Mats</strong></em> option selection off. <strong>cocos3d</strong> does support UV maps, but does so via the mesh data and materials. To make use of UV maps, within <em>Blender</em>, you should attach a material to each mesh and cover it with a UV-mapped texture.</li>
<li>Leave the <em><strong>Only Current Scene</strong></em> and <em><strong>Apply modifiers</strong></em> selections off, as <strong>cocos3d</strong> makes no use of them.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2011/cocos3d-importing-converting-collada-to-pod/feed/</wfw:commentRss>
		<slash:comments>73</slash:comments>
		</item>
		<item>
		<title>cocos3d Development Roadmap</title>
		<link>http://brenwill.com/2011/cocos3d-development-roadmap/</link>
		<comments>http://brenwill.com/2011/cocos3d-development-roadmap/#comments</comments>
		<pubDate>Sat, 12 Nov 2011 20:00:53 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[cocos3d]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=98</guid>
		<description><![CDATA[<p>This post outlines the intended release of new features and functionality to cocos3d. Please note that all delivery timeframes are estimates, and do not reflect commitments on the part of the cocos3d development team.</p> <p>If you have any suggestions or requests, we invite you to add comments below.</p> 0.6 Detection of 3D objects under <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2011/cocos3d-development-roadmap/">cocos3d Development Roadmap</a></span>]]></description>
			<content:encoded><![CDATA[<p>This post outlines the intended release of new features and functionality to <a href="/cocos3d">cocos3d</a>.<span id="more-98"></span> Please note that all delivery timeframes are estimates, and do not reflect commitments on the part of the <strong>cocos3d</strong> development team.</p>
<p>If you have any suggestions or requests, we invite you to add comments below.</p>
<ul>
<li><strong>0.6</strong>
<ul>
<li>Detection of 3D objects under an iOS touch <em>(<span style="text-decoration: underline;">Update:</span> released as part of 0.5.1 on 2011-02-24. Touch positioning released as part of 0.5.3 on 2011-04-05)</em>.</li>
</ul>
<ul>
<li>Retina support <em>(<span style="text-decoration: underline;">Update:</span> released as part of 0.5.2 on 2011-03-13)</em>.</li>
<li>3D particle system
<ul>
<li>Point-particles to be released in <strong>cocos3d 0.6.2</strong> (mid-October 2011).</li>
<li>Mesh particles to be included in future <strong>0.6.x</strong> release.</li>
</ul>
</li>
<li>cocos2d 2D particle systems attached to CC3Billboards (can use Particle Designer)</li>
</ul>
<ul>
<li><code>CC3TargettingNodes</code> as 3D halo objects &#8211; 3D objects that always face camera, but can be obscured by other objects (different from <code>CC3Billboards</code>, which always overlay all 3D objects).</li>
<li>Add any node to a <code>CC3TargettingNode</code> to have the child node always face a target node.</li>
<li>Multi-textuing.</li>
<li>Lighting enhancements, including attenuation and spotlights.</li>
<li>Fog effect.</li>
<li>Released Aug-Oct 2011.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>0.7</strong>
<ul>
<li>Vertex skinning and bone rigging <em>(Update: released as part of 0.6.3 on 2011-11-12)</em>.</li>
<li>Shadowing.</li>
<li>3D Mesh-particles (point-particles were released in <em>0.6.2</em>).</li>
<li>Identify location of touch event on an object.</li>
<li>Simple collision detection.</li>
<li>Expected delivery: Dec 2011.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>0.8</strong>
<ul>
<li>Additional 3D model file loaders.</li>
<li>MacOS support.</li>
<li>Expected delivery: Q1/2012.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>0.9</strong>
<ul>
<li>3D physics engine. The design intention is to build a  pluggable physics engine architecture that would provide the application  developer with choices as to the actual physics library used, including  using a third-party library, such as <a href="http://bulletphysics.org">Bullet</a> or <a href="http://newtondynamics.com">Newton</a>, or a simpler, bespoke library developed for the application. The initial release is expected to include the Bullet library.</li>
</ul>
<ul>
<li>Expected delivery: Q2/2012.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>2.x</strong>
<ul>
<li>Support for OpenGLES 2.0.</li>
<li>Expected delivery: 2012.</li>
</ul>
</li>
</ul>
<ul>
<li><strong>TBD</strong>
<ul>
<li>Further 3D model file loaders.</li>
<li>Scripting.</li>
<li>Delivery to be prioritized and scheduled based on developer-community needs.</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2011/cocos3d-development-roadmap/feed/</wfw:commentRss>
		<slash:comments>66</slash:comments>
		</item>
		<item>
		<title>cocos3d Programming Guide</title>
		<link>http://brenwill.com/2011/cocos3d-programming-guide/</link>
		<comments>http://brenwill.com/2011/cocos3d-programming-guide/#comments</comments>
		<pubDate>Tue, 15 Mar 2011 16:00:53 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[cocos3d]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=102</guid>
		<description><![CDATA[<p>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.</p> In this Guide: CC3Layer CC3World CC3Node CC3MeshNode Materials, Textures and Colors CC3MeshModel CC3VertexArrays CC3LineNode &#38; CC3PlaneNode Duplicating 3D Models CC3Camera &#38; CC3Light Controlling <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2011/cocos3d-programming-guide/">cocos3d Programming Guide</a></span>]]></description>
			<content:encoded><![CDATA[<p>The <a href="/cocos3d">cocos3d</a> 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 <strong>cocos3d</strong> iOS applications.<span id="more-102"></span></p>
<div id='toc' class='post-102'><div id='toc_title'>In this Guide:</div>
<ul><li><a href="#CC3Layer">CC3Layer</a></li>
<li><a href="#CC3World">CC3World</a></li>
<li><a href="#CC3Node">CC3Node</a></li>
<li><a href="#CC3MeshNode">CC3MeshNode</a>
<ul><li><a href="#Materials-Textures-and-Colors">Materials, Textures and Colors</a></li>
<li><a href="#CC3MeshModel">CC3MeshModel</a></li>
<li><a href="#CC3VertexArrays">CC3VertexArrays</a></li>
<li><a href="#CC3LineNode-amp-CC3PlaneNode">CC3LineNode &amp; CC3PlaneNode</a></li></ul></li>
<li><a href="#Duplicating-3D-Models">Duplicating 3D Models</a></li>
<li><a href="#CC3Camera-amp-CC3Light">CC3Camera &amp; CC3Light</a></li>
<li><a href="#Controlling-CC3Nodes-with-CCActions">Controlling CC3Nodes with CCActions</a></li>
<li><a href="#CC3Node-Animation">CC3Node Animation</a>
<ul><li><a href="#Controlling-Animation-with-Actions">Controlling Animation with Actions</a></li></ul></li>
<li><a href="#Selecting-CC3Nodes-with-User-Touch-Events">Selecting CC3Nodes with User Touch Events</a>
<ul><li><a href="#Selection-Artifacts">Selection Artifacts</a></li></ul></li>
<li><a href="#Projecting-3D-Locations-to-2D">Projecting 3D Locations to 2D</a></li>
<li><a href="#Pluggable-3D-Model-Loading">Pluggable 3D Model Loading</a></li>
<li><a href="#Automatic-Frustum-Culling-and-Bounding-Volumes">Automatic Frustum Culling and Bounding Volumes</a></li>
<li><a href="#Rendering-Order">Rendering Order</a></li>
<li><a href="#Updating-vs-Drawing">Updating vs Drawing</a></li>
<li><a href="#OpenGL-ES-State-Management">OpenGL ES State Management</a></li>
</ul></li></ul>
</div>
<p><strong>cocos3d</strong> is a significant extension to <a href="http://www.cocos2d-iphone.org/">cocos2d</a>, a popular, well-designed framework for building iOS games and applications that play out in 2D (or <a href="http://en.wikipedia.org/wiki/2.5D">2.5D</a> <a href="http://en.wikipedia.org/wiki/Isometric_perspective">isometric projection</a>). Although on the one hand it is possible to start with the <strong><em>cocos3d Application</em></strong> template and develop a 3D application without knowing too much about the workings of <em>cocos2d</em>, to get the most out of this document, you should familiarize yourself with <em>cocos2d</em>. You can learn more about <em>cocos2d</em> at the <a href="http://www.cocos2d-iphone.org/wiki/doku.php/">cocos2d Wiki</a>.</p>
<h3 id='CC3Layer'><a name="CC3Layer"></a>CC3Layer</h3>
<p><code>CC3Layer</code> 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 <code>CC3World</code>, described <a href="#CC3World">below</a>.</p>
<p>Although <strong>cocos3d</strong> is a full 3D modeling and rendering engine, all 3D rendering occurs within <code>CC3Layer</code>, a special <em>cocos2d</em> <code>CCLayer</code> subclass. Since it is a type of <code>CCLayer</code>, instances of <code>CC3Layer</code> fit seamlessly into the <em>cocos2d</em> <code>CCNode</code> 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. <code>CC3Layer</code> acts as the bridge between the 2D and 3D worlds.</p>
<p>You can add a <code>CC3Layer</code> instance anywhere in the visual node hierarchy of a <em>cocos2d</em> application. Although for the purposes of most games, the <code>CC3Layer</code> instance will usually be sized to cover the complete screen, a <code>CC3Layer</code> instance can be set to any size and added to a 2D parent visual <code>CCNode</code>. So, your application could have a 2D scene that contains a smaller 3D scene embedded into it via a small <code>CC3Layer</code> instance attached to a parent 2D <code>CCLayer</code>.</p>
<p>Conversely, since <code>CC3Layer</code> is a type of <code>CCNode</code>, you can add child <code>CCNode</code>s to it as well, mixing 2D nodes on top or below the 3D scene that is playing out within the <code>CC3Layer</code>. 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 <code>CCNode</code> that is added to the <code>CC3Layer</code> using the standard <code>addChild:</code> method will appear overlaid on top of the 3D scene. You can also add 2D <code>CCNode</code>s behind the 3D action as well, by using the <code>addChild:z:</code> 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.</p>
<p>When customizing your application&#8217;s subclass of <code>CC3Layer</code>, you will typically override the following two template methods:</p>
<ul>
<li><code>initializeControls</code> &#8211; this method is where you can add your 2D controls into the <code>CC3Layer</code>, and otherwise generally initialize your layer. This method is invoked automatically from any of the <code>init</code> methods of the layer.</li>
<li><code>update:</code> &#8211; if you have scheduled regular updates using the standard <code>CCNode scheduleUpdate</code> method, this update: method will be called periodically. This is where you can update any of the 2D controls you&#8217;ve added, or pass data from dynamic controls such as sliders or joysticks to your <code>CC3World</code> instance. If you override this method, be sure to call invoke the superclass implementation so it can pass the update notice to the <code>CC3World</code> instance.</li>
</ul>
<h3 id='CC3World'><a name="CC3World"></a>CC3World</h3>
<p>Although <code>CC3Layer</code> forms the bridge between the 2D and 3D visual worlds, it remains primarily a <em>cocos2D</em> layer, and no 3D activity actually takes place within <code>CC3Layer</code>. All 3D activity, from model management to rendering, takes place within, and is the responsibility of, your application&#8217;s customized <code>CC3World</code> subclass.</p>
<p>As with <code>CC3Layer</code>, there are several key template methods that you will typically override in your application&#8217;s subclass of <code>CC3World</code>:</p>
<ul>
<li><code>initializeWorld</code> &#8211; 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. The <code>CC3World</code> instance forms the base of a structural tree of nodes. Model objects are added as nodes to this root node instance using the <code>addChild:</code> method.</li>
<li><code>updateBeforeTransform:</code> and <code>updateAfterTransform:</code> &#8211; If you have scheduled regular updates through <code>CCLayer</code>, these <code>CC3World</code> 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 your <code>CC3World</code>.</li>
<li><code>nodeSelected:byTouchEvent:at:</code> &#8211; 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 <a href="#TouchEvents">touch events</a> for more information about handling the selection of 3D nodes by user touch events.</li>
</ul>
<p>As the names imply, the difference between the two update methods is that <code>updateBeforeTransform:</code> is invoked before the transformation matrix of the node is recalculated, whereas the <code>updateAfterTransform:</code> is invoked after. Therefore, if you want to move, rotate or scale a node, you should do so in the <code>udpateBeforeTransform:</code> method, to have your changes automatically applied to the transformation matrix of the node.</p>
<p>However, the <em>global</em> transform properties of each node (<code>globalLocation</code>, <code>globalRotation</code>, and <code>globalScale</code>)  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 <code>updateAfterTransform:</code> method. The global properties of a node can be used to test for collisions, or end conditions of movements, etc.</p>
<p>Sometimes, you may find the need to change the <code>location</code>, <code>rotation</code>, or <code>scale</code> properties of a node in the <code>updateAfterTransform:</code> method, for example as part of collision detection and reaction. If you do, you should invoke the <code>updateTransformMatrices</code> method on the top-most node that is affected, to have those changes immediately applied to the transformation matrix.</p>
<p>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 <code>CCActions</code>. Their behaviour is handled by the nodes and actions themselves.</p>
<p>In addition to these main template methods, you may find the following <code>CC3World</code> methods useful during operation, or simply useful to understand:</p>
<ul>
<li><code>addChild</code>: &#8211; Familiar from <em>cocos2d</em>, you can add child nodes (<code>CC3Nodes</code>) to your 3D world.</li>
<li><code>addContentFromPODResourceFile:</code> &amp; <code>addContentFromPODFile:</code> -  These are convenience methods for loading POD files directly into the <code>CC3World</code>, and are added by the <code>PVRPOD</code> category if your application uses the module for loading 3D models from POD formatted files.</li>
<li><code>getNodeNamed</code>: &#8211; 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.</li>
<li><code>activeCamera</code> &#8211; Property returns (or sets) the <a href="#CameraAndLights">3D camera</a> 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 the <code>add..</code>. 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.</li>
<li><code>ambientLight</code> &#8211; This is the color of the ambient light of the 3D world. This is independent of any distinct <a href="post.php?post=102&amp;action=edit&amp;message=5&amp;revision=104#CameraAndLights">lights</a> that are added as child nodes.</li>
<li><code>createGLBuffers</code> &#8211; This method causes all contained vertex data held by contained mesh nodes to be buffered to Vertex Buffer Objects (VBO&#8217;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&#8217;s.</li>
<li><code>releaseRedundantData</code> &#8211; After the <code>createGLBuffer</code> 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 the <code>shouldReleaseRedundantData</code> property to <code>NO</code> on the individual vertex array.</li>
<li><code>updateTransformMatrices</code> &#8211; If you make changes to the location, rotation and scale properties of a node within the <code>updateAfterTransform:</code> method, those changes will not automatically be applied to the transformation matrix of the node, since it has already been calculated when the <code>udpateAfterTransform:</code> method is invoked. However, you can use the <code>udpateTransformMatrices</code> to have those changes immediately applied to the transformation matrices of a node and all its descendants.</li>
<li><code>play</code> &amp; <code>pause</code> &#8211; these enable the operation of the update: method. When the <code>CC3World</code> is paused, the <code>updateBeforeTransform:</code> and <code>updateAfterTransform:</code> methods are skipped, along with updates of all other 3D nodes.</li>
<li><code>cleanCaches</code> &#8211; 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.</li>
</ul>
<p>Many of the responsibilities handled by <code>CC3World</code> are divided by the implementation into private template methods that you can override in your subclass, to customize behaviour in a modular way.</p>
<h3 id='CC3Node'><a name="CC3Node"></a>CC3Node</h3>
<p>All the objects in the 3D world, including models, cameras, lights, and the <code>CC3World</code> itself, are known as nodes. <code>CC3Node</code> 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.</p>
<p>This design will no doubt feel familiar to you as being analogous to <code>CCNodes</code> in <em>cocos2d</em>, and the two node hierarchies do follow the same design pattern. However, <code>CCNodes</code> and <code>CC3Nodes</code> cannot be mixed in the same structural assembly, primarily because <code>CC3Nodes</code> 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.</p>
<p>You assemble 3D nodes using the <code>addChild:</code> method. All nodes have an identifying tag and can have a name. You can retrieve a specified node in an assembly with the <code>getNodeNamed:</code> and <code>getNodeTagged:</code> methods.</p>
<p>All nodes have <code>location</code>, <code>rotation</code>, and <code>scale</code> properties (plus a couple of others). You move, rotate, and scale <code>CC3Nodes</code> by setting these properties. And, again, as with <em>cocos2d</em> nodes, the values of these properties are measured relative to the node&#8217;s parent node.</p>
<p>You can override the <code>updateBeforeTransform:</code> and <code>updateAfterTransform:</code> methods of a node subclass that acts predictively, such as those following a trajectory, to update these transform properties. See the discussion on <code>CC3World</code> <a href="#CC3World">above</a> regarding the difference between these two methods.</p>
<p>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 <code>location</code> 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 <code>location</code> property of the car node.</p>
<p>Any node can be the target of a <code>CCAction</code>, 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 <a href="#CCActions">actions</a> and <a href="#TouchEvents">touch events</a> for more information on this interactivity.</p>
<p>You can use the <code>createGLBuffers</code> method to cause all contained vertex data held by contained mesh nodes to be buffered to VBO&#8217;s in the GL engine. Generally, you should invoke this method at the highest level in the structure, <code>CC3World</code>, 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&#8217;s. Once data is loaded into GL VBO&#8217;s, you can use the <code>releaseRedundantData</code> method to release the data from your main application memory.</p>
<h3 id='CC3MeshNode'><a name="CC3MeshNode"></a>CC3MeshNode</h3>
<p><code>CC3MeshNode</code> puts the &#8217;3&#8242; in 3D. An instance of <code>CC3MeshNode</code> contains the 3D mesh data for a 3D object, plus the material, texture, or solid color that covers the surface of the object.</p>
<p>Each <code>CC3MeshNode</code> 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.</p>
<h4 id='Materials-Textures-and-Colors'>Materials, Textures and Colors</h4>
<p>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.</p>
<p>The mesh node holds an instance of a <code>CC3Material</code> to describe the visual characteristics of the surface of the mesh. <code>CC3Material</code> 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.</p>
<p>In addition to basic coloring, each <code>CC3Material</code> instance can hold an instance of <code>CC3Texture</code> to cover the surface of the mesh with a texture image.</p>
<p>The combination of coloring properties, blending properties, and textures interact with lighting conditions to create complex and realistic surface visual characteristics for the mesh.</p>
<p>There are two mechanisms for changing the coloring and opacity of a material covering a mesh node.</p>
<ul>
<li>To achieve the highest level of detail, accuracy and realism, you can individually set the explicit <code>ambientColor</code>, <code>diffuseColor</code>, <code>specularColor</code>, <code>emissiveColor</code>, <code>shininess</code>, <code>sourceBlend</code>, and <code>destinationBlend</code> 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.</li>
<li>At a simpler level, <code>CC3Material</code> also supports the <em>cocos2d</em> <code>&lt;CCRGBAProtocol&gt;</code> protocol. You can use the <code>color</code> and <code>opacity</code> properties of this protocol to set the most commonly used coloring and blending characteristics simply and easily. Setting the <code>color</code> property changes both the ambient and diffuse colors of the material in tandem. Setting the <code>opacity</code> property also automatically sets the source and destination blend functions to appropriate values for the opacity level. By using the <code>color</code> and <code>opacity</code> 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 <code>&lt;CCRGBAProtocol&gt;</code> protocol, the coloring and translucency of nodes with materials can be changed using standard <em>cocos2d</em> <code>CCTint</code> and <code>CCFade</code> actions, making it easier for you to add dynamic coloring effects to your nodes.</li>
</ul>
<p>If the mesh node does not contain a material, it will be painted with the color defined in the <code>pureColor</code> 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.</p>
<h4 id='CC3MeshModel'>CC3MeshModel</h4>
<p>Underpinning <code>CC3MeshNode</code> is <code>CC3MeshModel</code>, which in turn holds the raw vertex data in several <code>CC3VertexArray</code> instances. The management of mesh data is spread across these three classes (<code>CC3MeshNode</code>, <code>CC3MeshModel</code>, and <code>CC3VertexArray</code>) 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&#8217;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.</p>
<h4 id='CC3VertexArrays'>CC3VertexArrays</h4>
<p>Each mesh model instance (typically an instance of the concrete subclass <code>CC3VertexArrayMeshModel</code>) holds several <code>CC3VertexArray</code> 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 <code>CC3VertexArrayMeshModel</code>, each containing the same instances of the vertex locations and vertex normals arrays (<code>CC3VertexLocations</code> and <code>CC3VertexNormals</code>, respectively), but only the mesh model for the textured teapot would also contain a texture coordinate vertex array (<code>CC3VertexTextureCoordinates</code>) instance. With this arrangement, there is only ever one copy of the underlying vertex data.</p>
<h4 id='CC3LineNode-amp-CC3PlaneNode'>CC3LineNode &amp; CC3PlaneNode</h4>
<p><code>CC3LineNode</code> and <code>CC3PlaneNode</code> are specialized subclasses of <code>CC3MeshNode</code> that simplify the creation and drawing of lines and planes using vertex arrays, respectively.</p>
<h3 id='Duplicating-3D-Models'><a name="DuplicatingNodes"></a>Duplicating 3D Models</h3>
<p>In order to allow you to create hordes of invading armies, the <code>CC3Node</code> class supports the <code>&lt;NSCopying&gt;</code> protocol. To duplicate a node is simply a matter of invoking the <code>copy</code> method on that node. In addition, there is a <code>copyWithName:</code> method that duplicates the node, and gives the new copy its own name.</p>
<p>Copying a <code>CC3Node</code> creates a <em>deep</em> 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.</p>
<p>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 <code>CC3MeshNode</code>, mesh data is not copied, but is automatically shared between the original node and all its copies. Specifically, when an instance of <code>CC3MeshNode</code> is copied, a copy is made of the encapsulated <code>CC3Material</code> instance and is retained by the duplicate node, but the encapsulated <code>CC3MeshModel</code> is not duplicated. Instead, the single <code>CC3MeshModel</code> 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.</p>
<p>The following additional rules apply to duplicating a <code>CC3Node</code>:</p>
<ul>
<li>The <code>tag</code> property is not copied. The duplicate node is assigned a new unique value for its <code>tag</code> property. This is to ensure that the <code>tag</code> property is unique across all nodes, including duplicates, and allows you to identify a duplicate as distinct from the original, even if the <code>name</code> property is left the same.</li>
<li>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 <code>copy</code> or <code>copyWithName:</code> 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.</li>
<li>Like mesh data, underlying textures are not duplicated (although the <code>CC3Texture</code> instance itself is). Nor is node animation data duplicated.</li>
</ul>
<p>If you create your own subclass of <code>CC3Node</code>, or any of its existing subclasses, and your new subclass adds state, you must implement the <code>populateFrom:</code> 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.</p>
<h3 id='CC3Camera-amp-CC3Light'><a name="CameraAndLights"></a>CC3Camera &amp; CC3Light</h3>
<p>These are special nodes that represent the camera and lights in the  3D world. Cameras and lights are directional, and are examples of <code>CC3TargettingNode</code>, which, in addition to being able to move and rotate like other nodes, can be assigned a <code>target</code> or <code>targetLocation</code> at which to point. A <code>target</code> can be any other <code>CC3Node</code> in the scene, and the camera or light can be told to track the target as it moves.</p>
<h3 id='Controlling-CC3Nodes-with-CCActions'><a name="CCActions"></a>Controlling CC3Nodes with CCActions</h3>
<p>If you&#8217;ve used <em>cocos2d</em>, you&#8217;re no doubt familiar with the family of <code>CCAction</code>s, used to control the movement, coloring, visibility, and activities of <code>CCNode</code>s.</p>
<p>In <strong>cocos3d</strong>, <code>CC3Node</code>s can similarly be manipulated and controlled by <code>CCAction</code>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 <code>CC3TransformTo</code> interval action. In addition, there are several <strong>cocos3d</strong> action subclasses that handle material-tinting.</p>
<p>The 3D family of actions can, of course, be used with standard <em>cocos2d</em> combination actions such as the family of ease actions, sequence actions, etc.</p>
<h3 id='CC3Node-Animation'><a name="Animation"></a>CC3Node Animation</h3>
<p>Any <code>CC3Node</code> can be animated with key-frame animation data held in a <code>CC3NodeAnimation</code> instance within the <code>CC3Node</code> 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 <code>CC3ArrayNodeAnimation</code> subclass of <code>CC3NodeAnimation</code>. Like mesh data, the <code>CC3NodeAnimation</code> instances are stateless, and each may be shared by multiple <code>CC3Node</code> instances, so that animation data need not be duplicated redundantly.</p>
<p>Any or all of the transformation properties: <code>location</code>, <code>rotation</code>, and <code>scale</code>, may be animated using <code>CC3NodeAnimation</code> or <code>CC3ArrayNodeAnimation</code>.  If you need to animate other characteristics of your nodes, you can  subclass these classes to add additional animation capabilities.</p>
<p>Once animation data is associated with a <code>CC3Node</code>, the node can be animated with repeated invocations of the <code>establishAnimationFrameAt:</code> 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.</p>
<p>In order to perform smooth animation, by default, the <code>CC3NodeAnimation</code> will interpolate animation data between frames if the timing value passed in through the <code>establishAnimationFrameAt:</code> method is between actual frame times. This is controlled by the <code>shouldInterpolate</code> property on the <code>CC3NodeAnimation</code> instance. By default, this property is set to <code>YES</code>, but may be set to <code>NO</code> if heavy interpolation interferes with frame rates.</p>
<p>For node assemblies, you will typically want to animate the whole assembly in concert. To support this, the <code>establishAnimationFrameAt:</code> 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&#8217;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.</p>
<p>However, you can turn animation of any node in the assembly off, including selectively turning off animation of specific child nodes, via the <code>disableAnimation</code> method on that child node. You can turn the animation of whole sub-assemblies of nodes off via the <code>disableAllAnimation</code> method.</p>
<p>Fractional animation of individual movements is possible by simply limiting the range of frame times that are sent with the <code>establishAnimationFrameAt:</code> 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.</p>
<h4 id='Controlling-Animation-with-Actions'>Controlling Animation with Actions</h4>
<p>Although you can arrange to invoke the <code>establishAnimationFrameAt:</code> method of your animated <code>CC3Node</code> directly, in most cases it is much easier to use an instance of <code>CC3Animate</code> to control the animation of a node.</p>
<p><code>CC3Animate</code> is a type of <code>CCActionInterval</code>, and will run through the animation frames automatically over a configurable time duration. Moreover, when instantiating the <code>CC3Animate</code>, you can restrict the frames to a particular range, to allow fractional animation of specific movements.</p>
<h3 id='Selecting-CC3Nodes-with-User-Touch-Events'><a name="TouchEvents"></a>Selecting CC3Nodes with User Touch Events</h3>
<p>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.</p>
<p>The first step in enabling touch activity is to set the <code>isTouchEnabled</code> property of the <code>CC3Layer</code> to <code>YES</code>. Typically you will do this in the <code>initializeControls</code> method of your customized <code>CC3Layer</code> class. This causes the <code>CC3Layer</code> to register itself to receive touch events from iOS.</p>
<p>As such, your <code>CC3Layer</code> will receive and process <code>kCCTouchBegan</code>, <code>kCCTouchEnded</code>, and <code>kCCTouchCancelled</code> events. By default, your <code>CC3Layer</code> will not receive or process <code>kCCTouchMoved</code> events, because these are both quite voluminous and seldom used. However, you can configure your customized <code>CC3Layer</code> subclass to receive and handle <code>kCCTouchMoved</code> events by copying the commented-out <code>ccTouchMoved:withEvent:</code> method from the <code>CC3Layer</code> implementation and paste it into the implementation of your customized <code>CC3Layer</code> subclass, with the commenting removed.</p>
<p>The second step is to set the <code>isTouchEnabled</code> property to <code>YES</code>, in any <code>CC3Node</code>s that you want the user to be able to select with a touch event. So, for example, let&#8217;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 <code>isTouchEnabled</code> property to <code>YES</code> on the <code>CC3Node</code> instances representing each piece of fruit, but not on the <code>CC3Node</code> instances that represent the bowl or table. Please also note that, to be touchable, the node must have its <code>visible</code> property set to <code>YES</code>.</p>
<p>Once these two steps have been completed, the <code>nodeSelected:byTouchEvent:at:</code> callback method of your customized <code>CC3World</code> subclass will automatically be invoked on each touch event. This callback includes the <code>CC3Node</code> instance that was touched, the type of touch, and the 2D location of the touch point, in the local coordinates of the <code>CC3Layer</code>.</p>
<p>If the touch occurred at a point under which there is no touchable <code>CC3Node</code>, the callback <code>nodeSelected:byTouchEvent:at:</code> method will still be invoked, but the node will be <code>nil</code>, to indicate that a touch event occurred, but not on a touchable node.</p>
<p>For node assemblies, the node passed to the <code>nodeSelected:byTouchEvent:at:</code> 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 <code>isTouchEnabled</code> property set to <code>YES</code>.</p>
<p>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 <code>isTouchEnabled</code> property to <code>YES</code> on the car, but leaving it as <code>NO</code> on each wheel, will allow a wheel to be touched, but the node received by the <code>nodeSelected:byTouchEvent:at:</code> callback will be the node that represents the car as a whole.</p>
<h4 id='Selection-Artifacts'>Selection Artifacts</h4>
<p>When using translucent nodes, you might notice that when a translucent node is displayed over the raw background color of the <code>CC3Layer</code>, 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.</p>
<p>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.</p>
<p>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 &#8220;leak through&#8221; 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.</p>
<p>It is important to realize that this effect does <em>not</em> 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.</p>
<p>Therefore, if you have translucent nodes and are using touch selection, to avoid this slight flicker be sure to include an opaque <em>skybox</em> node at the back of your 3D scene, over which the other nodes of your scene will be drawn.</p>
<h3 id='Projecting-3D-Locations-to-2D'><a name="CC3Billboard"></a>Projecting 3D Locations to 2D</h3>
<p>The <code><code>projectedLocation</code></code> property of <code>CC3Node</code> 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 <code>projectedLocation</code> of a 3D node allows you to relate it to a 2D controls such as a targetting reticle, or to a touch event.</p>
<p>The <code>projectedLocation</code> is a 3D vector. As you would expect, the <code>X</code>- and <code>Y</code>-components provide the location of the 3D node on the screen, in the 2D coordinate system of the <code>CC3Layer</code>.  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 <code>contentSize</code> of the <code>CC3Layer</code>.  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.</p>
<p>The <code>Z</code>-component of the <code>projectedLocation</code> 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 <code>Z</code>-component of the <code>projectedLocation</code> can help you identify that.</p>
<p><code>CC3Node</code> also supports the related <code><code>projectedPosition</code></code> property. It is derived from the <code>projectedLocation</code> property and, for the most part, contains the same <code>X</code>- and <code>Y</code>- coordinates as <code>projectedLocation</code>, but as a 2D <code>CGPoint</code>, which is immediately usable by the <em>cocos2d</em> framework.</p>
<p>However, as a 2D point, the <code>projectedPosition</code> 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, <em>both</em> the <code>X</code>- and <code>Y</code>-components of the <code>projectedPosition</code> will contain the large negative value <code>-CGFLOAT_MAX</code>. If you use <code>projectedPosition</code>, you can test for this value to determine whether the 3D node is in front of, or behind, the camera.</p>
<p>For most nodes, these properties are not calculated automatically. In the <code>update:</code> method of your <code>CC3World</code> you can have them calculated for a node of interest by passing the node to the <code>projectNode:</code> method of the <code>activeCamera</code>.</p>
<p>However, for <code>CC3Billboard</code> nodes, the <code>projectedLocation</code> and <code>projectedPosition</code> <em> </em>properties <em>are</em> calculated automatically on each update. A <code>CC3Billboard</code> is a 3D node that can hold an instance of a 2D <em>cocos2d</em> <code>CCNode</code>, and display that 2D node at the <code>projectedPosition</code> of the <code>CC3Billboard</code> 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 <code>CCNode</code> can be any <em>cocos2d</em> node, and it can be configured to automatically scale to the correct perspective sizing, shrinking as the <code>CC3Billboard</code> moves away from the camera, and growing as the <code>CC3Billboard</code> approaches the camera. A common use of <code>CC3Billboard</code> is to display information about a 3D node, such as a textual name label or a health-bar for a game character.</p>
<h3 id='Pluggable-3D-Model-Loading'><a name="ModelLoading"></a>Pluggable 3D Model Loading</h3>
<p>Sophisticated 3D games are dependent on loading 3D models from resources created in 3D editors such as <a href="http://www.blender.org/">Blender</a>, <a href="http://www.cheetah3d.com/">Cheetah3D</a>, <a href="http://www.autodesk.com/maya">Maya</a>, <a href="http://www.autodesk.com/3dsmax">3ds Max</a>, and <a href="http://www.maxon.net/products.html">Cinema 4D</a>.  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 <strong>cocos3d</strong>, you only need to include the loaders that you use.</p>
<p>The pluggable loading framework is based around two template classes:</p>
<ul>
<li>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 <code>CC3Resource</code>, and is tailored to parsing and assembling a specific data file format.</li>
<li>The resource node class. This will be a subclass of <code>CC3ResourceNode</code>, and as such, is actually a type of <code>CC3Node</code>.  It wraps the <code>CC3Resource</code> instance, extracts populated nodes from it, and adds them as child nodes to itself. This node can be used  like any other <code>CC3Node</code> instance, and is usually simply added as a child to your <code>CC3World</code> instance. You can move, rotate, scale, or hide all the components  loaded from a file simply by manipulating the properties of the <code>CC3ResourceNode</code> instance.</li>
</ul>
<p>In addition to these two template classes, a pluggable loading package will usually contain specialized subclasses of  <code>CC3MeshNode</code>, <code>CC3Material</code>, <code>CC3Camera</code>,  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.</p>
<p>A pluggable loading package may also add categories to base classes  as a convenience. Thus, the PowerVR <code>POD</code> file loading package adds a  category to <code>CC3World</code> that adds the method <code>addContentFromPODResourceFile:</code> as a convenience for loading POD files directly into your <code>CC3World</code>.</p>
<p>The initial loading package available with <strong>cocos3d</strong> is for PowerVR <code>POD</code> files.</p>
<h3 id='Automatic-Frustum-Culling-and-Bounding-Volumes'><a name="Culling"></a>Automatic Frustum Culling and Bounding Volumes</h3>
<p>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.</p>
<p>The task of determining which objects don&#8217;t need to be drawn, and then removing them from the rendering pipeline is known as <em>culling</em>. There are two types of culling: <em>frustum culling</em>, which is the removal of objects that are not within the field of view of the camera, and <em>occlusion culling</em>, which is the removal of objects that are within the field of view of the camera, but can&#8217;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, <strong>cocos3d</strong> does not perform any kind of <em>occlusion culling</em>.</p>
<p><strong>cocos3d</strong> performs <em>frustum culling</em> automatically. Objects that are outside the view of the camera will not be drawn. This is accomplished by specifying a <em>bounding volume</em> for each mesh node. Each node holds onto an instance of a <code>CC3NodeBoundingVolume</code>, which it delegates to when determining whether it should draw itself to the GL engine. All mesh nodes in <strong>cocos3d</strong> have a default bounding volume that is reasonably accurate, and for the most part, you won&#8217;t even need to think about bounding volumes. However, we&#8217;ll describe the operation of bounding volumes here, for those situations where the application may want to improve on the default behaviour.</p>
<p>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.</p>
<p>Accuracy is important because acn inaccurate bounding volume can either result in the effort of rendering an object being performed when the objects won&#8217;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&#8217;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 <strong>cocos3d</strong> always ensure that all vertices are included within the bounding volume, so that objects are never culled when they are actually partially visible.</p>
<p>The family of <strong>cocos3d</strong> 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 <code>CC3NodeSphericalBoundingVolume</code>, and axially-aligned-bounding-box (AABB) bounding volumes, represented by subclasses of <code>CC3NodeBoundingBoxVolume</code>.</p>
<p>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&#8217;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 &#8220;seen&#8221; by the camera), even though the object itself will not be seen.</p>
<p>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.</p>
<p>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&#8217;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, <strong>cocos3d</strong> 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.</p>
<p>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.</p>
<p>Finally, to make use of both fast boundary tests to exclude objects that are clearly far from the camera&#8217;s field of view, and also more accurate boundary tests for objects that are at the edges of the camera&#8217;s field of view, <strong>cocos3d</strong> also includes the <code>CC3NodeTighteningBoundingVolumeSequence</code> 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&#8217;s field of view, the node is rejected and not drawn.</p>
<p>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&#8217;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.</p>
<p>By default, mesh nodes in <strong>cocos3d</strong> 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&#8217;t even have to think about bounding volumes. However, some applications may benefit from custom bounding volumes.</p>
<h3 id='Rendering-Order'><a name="RenderingOrder"></a>Rendering Order</h3>
<p>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.</p>
<p>To that end, the drawing order of the objects within a <code>CC3World</code> can be configured by the application for optimal performance. The <code>CC3World</code> instance holds onto an instance of a <code>CC3NodeSequencer</code>, 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.</p>
<p>As with bounding volumes discussed <a href="#Culling">above</a>, 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 <code>CC3World</code>.</p>
<p>There are two key types of sequencers, <code>CC3NodeArraySequencer</code>s, which hold a collection of nodes, grouped in some defined order, and <code>CC3BTreeNodeSequencer</code>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.</p>
<p>Every sequencer contains in instance of a <code>CC3NodeEvaluator</code> 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 &#8220;Do you want this node?&#8221;. Using this mechanism, a B-tree sequencer can determine which of its child sequencers wants to take care of ordering any particular node.</p>
<p>A simple example might help here. Both Imagination Technologies (the supplier of the iOS GPU&#8217;s) and Apple recommend that all opaque objects should be drawn before translucent objects. In addition, the translucent objects themselves should be drawn in <em>Z-order</em>, 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.</p>
<p>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 <em>Z-order</em>.</p>
<p>This structure looks as follows:</p>
<ul>
<li><code>CC3BTreeNodeSequencer (CC3LocalContentNodeAcceptor)</code>
<ul>
<li><code>CC3NodeArraySequencer (CC3OpaqueNodeAcceptor)</code></li>
<li><code>CC3NodeArrayZOrderSequencer (CC3TranslucentNodeAcceptor)</code></li>
</ul>
</li>
</ul>
<p>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 <em>Z-order</em>.</p>
<p>Because nodes may be  moving around from frame to frame, be aware that <em>Z-ordering</em> requires that the nodes in the <code>CC3NodeArrayZOrderSequencer</code> 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&#8217;t  waste time sorting translucent nodes that can&#8217;t be seen as translucent  by the user), and keep the number of translucent nodes to a minimum.</p>
<p>The requirement that this example illustrates is so common that <code>CC3BTreeNodeSequencer</code> includes the class method <code>sequencerLocalContentOpaqueFirst</code>, to create just such a sequencer assembly. There are also the class methods <code>sequencerLocalContentOpaqueFirstGroupTextures</code> and <code>sequencerLocalContentOpaqueFirstGroupMeshes</code>, 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 <em>Z-order</em>.</p>
<p>By default, <code>CC3World</code> uses a sequencer created by the <code>sequencerLocalContentOpaqueFirst</code> method, thereby drawing opaque nodes first, in the order they were added, then translucent nodes in <em>Z-order</em>.</p>
<h3 id='Updating-vs-Drawing'><a name="UpdatingVsDrawing"></a>Updating vs Drawing</h3>
<p>By design, both <em>cocos2d</em> and <strong>cocos3d</strong> 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.</p>
<p>With all this in mind, you should keep the code you write in the <code>updateBeforeTransform:</code> and <code>updateAfterTransform:</code> methods of any <code>CC3Node</code> subclass free of drawing or rendering operations. Similarly, should you override the <code>drawWithVisitor:</code> or <code>draw</code> methods in any <code>CC3Node</code> subclass, you should only perform rendering operations, and keep those methods free of model updates.</p>
<h3 id='OpenGL-ES-State-Management'><a name="GLStateMgmt"></a>OpenGL ES State Management</h3>
<p>As mentioned <a href="#RenderingOrder">above</a> 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&#8217;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.</p>
<p>To ensure that, <strong>cocos3d</strong> shadows the state of the GL engine outside of the GL engine itself. When an attempt is made to change state, <strong>cocos3d</strong> 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.</p>
<p>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&#8217;ll give an overview of it here.</p>
<p>In <strong>cocos3d</strong>, this shadow state is managed by a singleton instance of <code>CC3OpenGLES11Engine</code>. All calls to the GL engine are made through this singleton instance.</p>
<p>The <code>CC3OpenGLES11Engine</code> singleton instance contains a number of instances of subclasses of <code>CC3OpenGLES11StateTrackerManager</code>, 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 <code>CC3OpenGLES11Engine</code> singleton instance. Each tracker manager exposes individual elements of state through properties.</p>
<p>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 <strong>cocos3d</strong> 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:</p>
<ul>
<li><code>[[CC3OpenGLES11Engine engine].serverCapabilities.texture2D enable]</code> &lt;-&gt; <code>glEnable(GL_TEXTURE_2D)</code></li>
<li><code>[CC3OpenGLES11Engine engine].materials.ambientColor.value = kCCC4FBlue</code> &lt;-&gt; <code>glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, (GLfloat*)&amp;kCCC4FBlue)</code></li>
<li><code>[CC3OpenGLES11Engine engine].state.scissor.value = self.activeCamera.viewport</code> &lt;-&gt; <code>glScissor(vp.x, vp.y, vp.w, vp.h)</code>, where <code>vp = self.activeCameraViewport</code></li>
</ul>
<p>Since it is critical that <em>all</em> GL calls be processed through the state shadow trackers, but <em>cocos2d</em> 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 <strong>cocos3d</strong> framework from <em>cocos2d</em>.</p>
<p>Each primitive state tracker has an <code>originalValueHandling</code> 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:</p>
<ul>
<li>simply ignore the current state at the beginning of each rendering frame</li>
<li>read the current state at the beginning of each rendering frame</li>
<li>read the current state at the beginning of the first rendering frame and assume that value always</li>
</ul>
<p>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 <em>cocos2d</em> is assuming it to have stayed the same.</p>
<p>The original value state is set to the optimal value for combining cocos2d and <strong>cocos3d</strong>, 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 <strong>cocos3d</strong> takes over, you can modify the <code>originalValueHandling</code> property of the associated state tracker to read the value on every frame.</p>
<p>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 <em>cocos2d</em> code leaves GL state with consistent values from frame to frame at the time <strong>cocos3d</strong> takes over.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2011/cocos3d-programming-guide/feed/</wfw:commentRss>
		<slash:comments>124</slash:comments>
		</item>
		<item>
		<title>Adding SIO2 to an Existing Xcode iOS Project</title>
		<link>http://brenwill.com/2010/adding-sio2-to-an-existing-xcode-ios-project/</link>
		<comments>http://brenwill.com/2010/adding-sio2-to-an-existing-xcode-ios-project/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 22:44:16 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[iOS Development]]></category>
		<category><![CDATA[SIO2]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=68</guid>
		<description><![CDATA[<p>Updated (2011/01/16) &#8211; Please note that this article covers SIO2 v1.4, which was the original free/low-cost version of SIO2. This article does not cover SIO2 v2.x.</p> <p>SIO2 is an interesting and useful library for building 3D OpenGL ES applications under Apple&#8217;s iOS. While not strictly object-oriented like Apple&#8217;s Cocoa, much of the OpenGL functionality is <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2010/adding-sio2-to-an-existing-xcode-ios-project/">Adding SIO2 to an Existing Xcode iOS Project</a></span>]]></description>
			<content:encoded><![CDATA[<p><strong><span style="text-decoration: underline;">Updated</span></strong> (2011/01/16) &#8211; Please note that this article covers SIO2 v1.4, which was the original free/low-cost version of SIO2. This article does not cover SIO2 v2.x.</p>
<p><a href="http://www.sio2interactive.com/">SIO2</a> is an interesting and useful library for building 3D <a href="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a> applications under Apple&#8217;s iOS. While not strictly object-oriented like Apple&#8217;s Cocoa, much of the OpenGL functionality is abstracted into a collection of useful structures and related higher-level functions.</p>
<p>For historic and performance reasons, SIO2 is written in <code>C++</code>, not <code>Objective-C</code>. Bridging between pure <code>C++</code> and <code>Objective-C</code> is not always as straightforward as it should be, and there are a few things to take into consideration when combining <code>C++</code> libraries with <code>Objective-C</code>.</p>
<p>To aid with that issue, SIO2 comes with a customized <code>Xcode</code> template project, which provides a stable base for beginning the development of an iOS application that combines the SIO2 library with <code>Objective-C</code> and Cocoa. However, it&#8217;s not always practical or even recommended to begin all <code>Xcode</code> projects from the SIO2 template, and if you already have an existing <code>Xcode</code> project, it can be a challenge importing the SIO2 library into it. This article outlines the steps needed to import SIO2 into your existing <code>Xcode</code> Objective-C project.<span id="more-68"></span></p>
<ol>
<li>Open your existing <code>Xcode</code> project.</li>
<li>From a <code>Finder</code> window, drag the SIO2 <code>src</code> directory onto your project in the <code>Xcode</code> <em><strong>Groups &amp; Files</strong></em> pane, making sure to select the <em><strong>Recursively create groups for any added folders</strong></em> option in the import dialog box that opens up. Depending on how you organize your third-party libraries, you might also want to select the <em><strong>Copy these items into destination group&#8217;s folder</strong></em> option for the SIO2 library. Selecting this option will copy the whole SIO2 library into your project directory. Leaving it unselected will create references to the library. Personally, I recommend leaving this option unselected when importing SIO2. Using references avoids having multiple copies of the SIO2 library spread around your <code>Xcode</code> projects, and allows you to use symlinks to quickly swap out different versions of the library. But it depends on your approach to working with <code>Xcode</code> projects and library code.</li>
<li>In the <code>Xcode</code> <em><strong>Groups &amp; Files</strong></em> pane, rename the new <code>src</code> group to something more informative (like <code>SIO2</code>). In the remaining steps below, I assume you&#8217;ve renamed it to <code>SIO2</code>. If you choose a different name, simply substitute accordingly.</li>
<li>In the <code>Xcode</code> <em><strong>Groups &amp; Files</strong></em> pane, under the <code>SIO2/lua</code> folder, delete the <code>swig</code> folder and the file <code>sio2_wrap.c</code>. In the confirmation dialog that pops up, if you left the <em><strong>Copy these items into destination group&#8217;s folder</strong></em> option unchecked in <em>Step 2</em>, be sure to delete only the references. Otherwise if you copied the files into your project, go ahead and delete the files as well. If in doubt, just delete the references.</li>
<li>In the <code>Xcode</code> <em><strong>Groups &amp; Files</strong></em> pane, drag the <code>libsio2_dev.a</code> and <code>l</code><code>ibsio2_sim.a</code> files in the <code>SIO2/sio2</code> folder to the <code>Frameworks</code> folder. This action moves the references, not the files themselves.</li>
<li>Here&#8217;s where we need to start to compensate for the SIO2 library being written in <code>C++</code>. Compiling now will generate thousands of errors, because <code>Xcode</code> considers all of the <code>SIO2/sio2/sio2*.cc</code> files to be regular <code>C++</code> files, and does not take into consideration that these files reference some <code>Objective-C</code> syntax via the <code>sio2.h</code> header file. <code>Xcode</code> needs to be told these files are of a different type. We do that in the next two of steps.</li>
<li>In the <code>Xcode</code> <em><strong>Groups &amp; Files</strong></em> pane, select the <code>SIO2/sio2</code> folder so the contents of that folder appear in the <code>Xcode</code> <em><strong>Detail</strong></em> pane, and sort the list by the &#8220;hammer&#8221; column so all the <code>sio2*.cc</code> files are grouped together.</li>
<li>Carefully select all the <code>sio2*.cc</code> files (but none of the <code>sio2*.h</code> files) and choose <em><strong>Get Info</strong></em> from the right-click menu. Under the <em><strong>General</strong></em> tab you will see the file type of these files is <code>sourcecode.cpp.cpp</code>. Change this to <code>sourcecode.cpp.objcpp</code> to tell <code>Xcode</code> to expect both <code>C++</code> and <code>Objective-C</code> code in these files (and any included files).</li>
<li>You should now be able to successfully <em><strong>Clean</strong></em> and <em><strong>Build</strong></em> your project. However, at this point, you will receive several dozen warnings along the lines of <em>warning: deprecated conversion from string constant to &#8216;char*&#8217;</em>. These have to do with some non-strict string casting within the SIO2 library and its sub-libraries, and can be safely ignored. I describe in the following two steps how to configure the <code>Xcode</code> compiler build settings to have these warnings ignored automatically.</li>
<li>Before attempting to change any compiler build settings, make sure the full suite of build settings is visible by setting the active <code>SDK</code> in <code>Xcode</code> to one of the <em>device</em> <code>SDK</code>&#8216;s. If the active <code>Xcode</code> <code>SDK</code> is set to one of the <em>simulator</em> <code>SDK</code>&#8216;s, many of the build settings will not be directly visible in the settings editors. I have no idea why <code>Xcode</code> has this ludicrous limitation, but it is what it is. You can set the active <code>SDK</code> in the <em><strong>Project-&gt;Set Active SDK</strong></em> menu within <code>Xcode</code>.</li>
<li>Once you&#8217;ve done that, open the <em><strong>Project-&gt;Edit Project Settings</strong></em> dialog. On the <em><strong>Build</strong></em> tab, make sure <em><strong>All Settings</strong></em> is selected in the <em><strong>Show</strong></em> list in the header area, then scroll down to the <em><strong>GCC 4.2 &#8211; Warnings</strong></em> section. In the <code>Other Warning Flags</code> field, add the value <code>-Wno-write-strings</code>. This field may also be labeled <code>WARNING_CFLAGS</code>, which is the actual compiler flag name. If you cannot find this field, you can add it as a user-defined setting field.</li>
<li>Now <em><strong>Clean</strong></em> and <em><strong>Build</strong></em> your project. If the active <code>SDK</code> is a <em>device</em> <code>SDK</code>, you should get a single warning indicating that the <code>libsio2_sim.a</code> file is not of required architecture. That file is used only by the <code>iOS Simulator</code>, and you can ignore the warning when compiling for a device. If the active <code>SDK</code> is a <em>simulator</em> <code>SDK</code>, you will not see this warning at all.</li>
<li>If you continue to receive a number of further warning messages, this may be due to additional warning settings within the compiler tripping over some of the <code>C++</code> code within the SIO2 libraries. Make sure the <code>Warning Flags</code> field of the <em><strong>Project-&gt;Edit Project Settings-&gt;Build</strong></em> tab does not contain any warning flags other than <code>-Wno-write-strings</code>. In particular, make sure it does not contain <code>-Wall</code> (show all warnings). If it does, remove it. Do the same for the the <code>Other C Flags</code> field (aka <code>OTHER_CFLAGS</code>) in the <em><strong>GCC 4.2 &#8211; Language</strong></em> section of the <em><strong>Build</strong></em> tab, making sure it does not contain any <code>-W...</code> warning flags (this field may contain other legitimate non-warning flags, so just remove flags starting with <code>-W</code>). Then open the <em><strong>Project-&gt;Edit Active Target</strong></em> dialog, select the <em><strong>Build</strong></em> tab, and make sure both the <code>Warning Flags</code> and <code>Other C Flags</code> fields there are free of any unnecessary warning flags. If the <code>Warning Flags</code> field is empty in the <em><strong>Project-&gt;Edit Active Target</strong></em> dialog, do not leave it blank, because this will override the <code>-Wno-write-strings</code> setting at the project level. In the <em><strong>Project-&gt;Edit Active Target</strong></em> dialog, select <em><strong>Delete Definition at This Level</strong></em> from the choice of edit commands in the lower left corner of the <em><strong>Build</strong></em> tab.</li>
<li>Finally, for SIO2, and Open GL ES in general, there are some important optimizations you should establish via the build settings. In the <em><strong>Project-&gt;Edit Project Settings-&gt;Build</strong></em> tab, add the following values to the <code>Other C Flags</code> (aka <code>OTHER_CFLAGS</code>) field in the <em><strong>GCC 4.2 &#8211; Language</strong></em> section:<code> -fno-regmove -falign-loops=16 -fvisibility=default</code> (this last <code>visibility</code> flag is not for performance, but actually to avoid some other warnings related to function visibility and is included here for completeness on this build setting). Similarly, in the <em><strong>GCC 4.2 &#8211; Code Generation</strong></em> section you should turn off the <code>Compile for Thumb</code> settings for both <code>ARMv6</code> and <code>ARMv7</code> to improve OpenGL floating point performance. Make sure the settings in the <em><strong>Project-&gt;Edit Active Target</strong></em> dialog do not override these settings.</li>
</ol>
<p>That&#8217;s it! There are a number of steps listed here, but I hope I&#8217;ve explained them well enough to make them fairly straightforward and easy to follow.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2010/adding-sio2-to-an-existing-xcode-ios-project/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>cocos2d and UIViewControllers</title>
		<link>http://brenwill.com/2010/cocos2d-and-uiviewcontrollers/</link>
		<comments>http://brenwill.com/2010/cocos2d-and-uiviewcontrollers/#comments</comments>
		<pubDate>Tue, 10 Aug 2010 21:13:46 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[iOS Components]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[iPhone camera]]></category>
		<category><![CDATA[View rotation]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=51</guid>
		<description><![CDATA[ <p>This cocos2d framework package is a wonderful framework for working with OpenGL ES within iOS. Since it focuses on high performance OpenGL ES code, for the most part cocos2d bypasses Apple&#8217;s Cocoa UIViewController hierarchy. This makes sense, since within iOS, OpenGL ES usually plays out on a single UIView, and typically in a <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2010/cocos2d-and-uiviewcontrollers/">cocos2d and UIViewControllers</a></span>]]></description>
			<content:encoded><![CDATA[
<p>This <a href="http://www.cocos2d-iphone.org/">cocos2d</a> framework package is a wonderful framework for working with <a href="http://en.wikipedia.org/wiki/OpenGL_ES">OpenGL ES</a> within iOS. Since it focuses on high performance OpenGL ES code, for the most part cocos2d bypasses Apple&#8217;s Cocoa <code>UIViewController</code> hierarchy. This makes sense, since within iOS, OpenGL ES usually plays out on a single <code>UIView</code>, and typically in a single display orientation, so there&#8217;s usually not much to control.</p>
<p>However, there are occasions where the functionality provided by <code>UIViewController</code> can be quite useful. In particular, the following functionality is best handled by adding a <code>UIViewController</code> into the mix:</p>
<ul>
<li><a href="#auto-rotation">Auto-rotation</a> &#8211; in some games, or other OpenGL ES applications, it makes sense to change the orientation of the application display to match changes in the orientation of the physical device. This means that when the user flips the device from landscape to portrait mode, or back again, the application display will adjust itself accordingly. The auto-rotation works on cocos2d nodes directly and does <em>not</em> rotate the underlying iOS Cocoa <code>UIView</code>. If you are interested in combining cocos2d nodes with <code>UIViews</code> <em>and</em> having them auto-rotate together, please review cocos2d support for that <a href="http://www.cocos2d-iphone.org/archives/1053">here</a>.</li>
<li><a href="#camera-overlay">Device camera overlay</a> &#8211; an increasingly popular use for iOS devices is to overlay a game or app view on top of the image visible through the device&#8217;s camera. This is known as <a href="http://en.wikipedia.org/wiki/Augmented_reality">augmented reality</a>, and provides the user with a combined view of the real world overlaid with images generated by the application. For this use, a <code>UIViewController</code> is mandatory, since it controls the merging of the real-world and generated image streams.</li>
</ul>
<p>Here at <em>The Brenwill Workshop</em>, some of our iOS applications actually use both of these features, and we&#8217;ve developed a small framework that can easily add the capabilities above to any cocos2d application. This article describes the design and use of this framework.<br />
<span id="more-51"></span></p>
<h3>Examples</h3>
<p>Since a picture is worth a thousand words, let&#8217;s start with sample screenshots from the <a href="#installing">example game</a>, showing the automatic rotation of the game layer when the device orientation is changed, and the game layer overlaying the device camera image:</p>
<div class="mceTemp">
<div id="attachment_48" class="wp-caption alignnone" style="width: 210px"><a href="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-portrait.png"><img class="size-medium wp-image-48" title="Game layer in portrait orientation with colored backdrop" src="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-portrait-200x300.png" alt="Game layer in portrait orientation with colored backdrop" width="200" height="300" /></a><p class="wp-caption-text">Game layer in portrait orientation with colored backdrop.</p></div>
<div id="attachment_47" class="wp-caption alignnone" style="width: 310px"><a href="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-landscape.png"><img class="size-medium wp-image-47" title="Game layer in landscape orientation with colored backdrop" src="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-landscape-300x200.png" alt="Game layer in landscape orientation with colored backdrop" width="300" height="200" /></a><p class="wp-caption-text">Game layer rotated to landscape orientation. The player and sunshine button have moved to their correct positions relative to the new orientation.</p></div>
<div id="attachment_49" class="wp-caption alignnone" style="width: 310px"><a href="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-overlay.png"><img class="size-medium wp-image-49" title="Game layer overlaying the device camera image" src="http://brenwill.com/wp-content/uploads/ccnodecontroller-example-overlay-300x200.png" alt="Game layer overlaying the device camera image" width="300" height="200" /></a><p class="wp-caption-text">Game layer overlaying the device camera image.</p></div>
</div>
<p>Although it is not shown here, the two features are compatible, of course, and the device camera overlay will also rotate along with changes in the device orientation.</p>
<p>Notice that, in the rotation from portrait to landscape orientation, the player image on the left has moved to the vertical center of the new orientation and the sunshine button in the lower right corner has stayed on-screen and in the same position relative to that corner. The game layer subclass is automatically <a href="#auto-rotation">notified of changes in the device orientation</a> to give it a chance to adjust the positions of its child nodes to suit the new orientation.</p>
<h3>Quick Start</h3>
<p>This framework is centered on two classes: a node controller, <code>CCNodeController</code>, and a controlled layer, <code>ControllableCCLayer</code>. Setting up the controller is simple, and is handled in the <code>applicationDidFinishLaunching:</code> method of your <code>UIApplicationDelegate</code> implementation, during normal cocos2d startup. Add the following code at the end of this method (replacing the existing line: <code>[[CCDirector sharedDirector] runWithScene: [[CCScene node] addChild: myLayer]];</code>):</p>
<pre class="brush: objc; title: ; notranslate">
GamePlayLayer* gamePlayLayer = [GamePlayLayer node];
controller = [[CCNodeController controller] retain];
controller.doesAutoRotate = YES;
controller.isOverlayingDeviceCamera = YES;
[controller runSceneOnNode: gamePlayLayer];
</pre>
<p>That&#8217;s it! You now have a cocos2d application that will rotate itself automatically as the device is rotated, and display itself over the camera view if the device has a camera.</p>
<p>In the first line of code above, <code>GamePlayLayer</code> is your subclass of <code>ControllableCCLayer</code>. In the second line, you create and retain the controller in a <code>controller</code> <em>instance variable</em> you add to your <code>UIApplicationDelegate</code> class (don&#8217;t forget to release it in the <code>dealloc</code> method).</p>
<p>In the third and forth lines you tell the controller to automatically rotate the game layers and overlay those layers on top of the device camera. No need to worry about whether the device actually has a camera. The <code>isOverlayingDeviceCamera</code> property can only be set to <code>YES</code> if the device has a camera, and it will be ignored otherwise.</p>
<p>In the last line, the controller sets the <code>GamePlayLayer</code> as its controlled node, wraps it in a <code>CCScene</code>, and tells <code>CCDirector</code> to run the scene. This last line replaces the typical <code>[[CCDirector sharedDirector] runWithScene: [[CCScene node] addChild: myLayer]];</code> line normally found at the end of the <code>applicationDidFinishLaunching:</code> method within a cocos2d application.</p>
<h3><code>CCNodeController</code>, <code>ControlledCCNodeProtocol</code>, and <code>ControllableCCLayer</code></h3>
<p>Central to this framework is the <code>CCNodeController</code> class, which is a subclass of <code>UIViewController</code> and provides the bridge to iOS to receive automatic notifications of changes in the orientation of the device and to control the device camera display. When using this framework, you will need to instantiate a <code>CCNodeController</code>, but you will usually have no need to subclass <code>CCNodeController</code>, unless you have very specialized requirements.</p>
<p>As the name suggests, <code>UIViewController</code> is designed to control a <code>UIView</code>, also from Apple&#8217;s Cocoa <code>UIKit</code> framework. Although cocos2d does make use of a <code>UIView</code> under the covers and the <code>CCNodeController</code> does in fact control that <code>UIView</code>, practical OpenGL rendering is handled by the cocos2d <code>CCNode</code> hierarchy. Therefore, to make the controller useful to cocos2d, we need a bridge between the controller and the <code>CCNode</code> hierarchy.</p>
<p>Enter the <code>ControlledCCNodeProtocol</code> protocol, which defines the requirements that a <code>CCNode</code> must support for it to be controlled by a <code>CCNodeController</code>. These requirements are actually relatively simple, amounting to tracking the controller itself via a <code>controller</code> property, and handling notification of changes in the device orientation through a <code>deviceOrientationDidChange:</code> method.</p>
<p>In Apple&#8217;s <code>UIKit</code> framework, although a <code>UIViewController</code> can control <em>any</em> <code>UIView</code> subclass, in practice controllers are almost always applied to control the top-most <code>UIView</code> within a window scene. Similarly, although a <code>CCNodeController</code> can control <em>any</em> <code>CCNode</code> subclass that supports <code>ControlledCCNodeProtocol</code>, in practice it is the main <code>CCLayer</code> at the level of the scene that is of most interest.</p>
<p>In recognition of this, the framework here includes a <code>ControllableCCLayer</code> class that adds the behaviour defined by <code>ControlledCCNodeProtocol</code> to <code>CCLayer</code>. This class is subclassed from <code>CCColorLayer</code> and supports initialization either with or without a background color. In your application, you derive subclasses of <code>ControllableCCLayer</code> instead of <code>CCLayer</code>, to allow your layers to rotate automatically and overlay the device camera.</p>
<p><code>ControllableCCLayer</code> automatically resizes as it rotates, and there are hooks for the subclasses to latch onto to reposition child nodes if needed. It is also smart enough to know that if it has been configured with a colored background, it should not draw it when overlaying the device camera, but should present a transparent background instead.</p>
<p>Typically, your cocos2d application will have a number of scenes, each with a primary layer. Since cocos2d reuses a single <code>UIView</code> instance on which to draw scenes, you will need only a single <code>CCNodeController</code> instance. But as the layers are swapped in and out during game play by the <code>CCDirector</code>, the <code>CCNodeController</code> must be kept in sync so that it knows which layer is currently active. You can use the <code>controlledNode</code> property on the <code>CCNodeController</code> to set the active layer. Or, to make this synchronization task easier, your application can use <code>runSceneOnNode:</code>, a convenience method on <code>CCNodeController</code>, to start or swap out a layer in both the <code>CCDirector</code> and the <code>CCNodeController</code> simultaneously with a single call.</p>
<h3><a name="auto-rotation"></a>Auto-rotation on Device Orientation Changes</h3>
<p>The <code>doesAutoRotate</code> property of the <code>CCNodeController</code> enables and disables automatic rotation of the controlled node. When this property is set to <code>YES</code>, the controller will start to listen for notifications of device orientation change from iOS and propagate those notifications to the cocos2d framework as they arrive. When this property is set to NO, the controller will stop listening for iOS notifications. To automatically rotate a <code>ControllableCCLayer</code> in your application, all you need to do is set this property to <code>YES</code>, and attach the layer to the controller, typically using the controller&#8217;s <code>runSceneOnNode:</code> method, as described in the previous section.</p>
<p>With the <code>doesAutoRotate</code> property active, when the <code>CCNodeController</code> is notified by iOS that the device orientation has changed, it informs the cocos2d framework of the change, and also calls the <code>deviceOrientationDidChange:</code> method on the controlled node.﻿</p>
<p><code>ControllableCCLayer</code> is the most commonly used controlled node class. In most cocos2d applications, layers cover most or all of the device screen and, when the device orientation changes, the <code>contentSize</code> of the layer should generally change to match the new orientation. The <code>ControllableCCLayer</code> property <code>alignContentSizeWithDeviceOrientation</code> controls whether the layer will automatically adjust its <code>contentSize</code> to align with the new orientation. In particular, if this property is set to <code>YES</code>, and the device orientation changes from portrait to landscape or vice versa, the <code>contentSize</code> of the layer will automatically change to its transpose. When changing between two landscape orientations (landscape-right or landscape-left) or two portrait orientations (normal or upside down), the <code>contentSize</code> will remain unchanged. This property is initially set to <code>YES</code>. However, if your application has a layer subclass that is smaller than full screen, you might find occasion to set this property to <code>NO</code> so that the <code>contentSize</code> (and shape aspect) will remain steady through rotations between portrait and landscape orientations.</p>
<p>To provide a hook for subclasses of the <code>ControllableCCLayer</code> to know when the <code>contentSize</code> has changed, the <code>ControllableCCLayer</code> method <code>didUpdateContentSizeFrom:</code> is called automatically whenever the <code>contentSize</code> of the layer changes. Your subclass can override this method to adjust the positions of any child nodes after a rotation. For example, to keep a button or label in, say, the center or the bottom-right corner of the layer after a change in the <code>contentSize</code> of the layer, the subclass can update the position of the button or label accordingly in <code>didUpdateContentSizeFrom:</code>.</p>
<p>Finally, note that the auto-rotation works on cocos2d nodes directly and does <em>not</em> rotate the underlying iOS Cocoa <code>UIView</code>. If you are interested in combining cocos2d nodes with <code>UIViews</code> <em>and</em> having them auto-rotate together, please review cocos2d support for that <a href="http://www.cocos2d-iphone.org/archives/1053">here</a>.</p>
<h3><a name="camera-overlay"></a>Overlay the Device Camera View</h3>
<p>The <code>CCNodeController</code> property <code>isOverlayingDeviceCamera</code> controls whether the controlled node will be displayed over the view of the device camera. Your application only need only toggle this value to cause the overlaying effect to be applied or removed. The <code>CCNodeController</code> takes care of coordinating all the activities needed to make it happen. This property cannot be set to <code>YES</code> if the device does not actually have a camera. Attempting to do so is safe, because the action is simply ignored and the controlled node will continue to behave as it does when not overlaying the device camera. To find out if this property can successfully be set, you can check the <code>isDeviceCameraAvailable</code> property of <code>CCNodeController</code>, or you can simply set the <code>isOverlayingDeviceCamera</code> property and then check its value to see if the change was successful. The value of the <code>isOverlayingDeviceCamera</code> property can be changed at any time, and it is up to your application to determine when, if ever, that should happen. For instance, you might change it upon a scene transition, or even during active game play via a user-controlled on-screen button.</p>
<p>Within iOS, applying or removing an overlay on the device camera is not a trivial activity. Although your application interacts only with the <code>isOverlayingDeviceCamera</code> property, a lot happens under the covers. One important aspect is that in order to display an overlay on the camera image, a second specialized <code>UIViewController</code> (<code>UIImagePickerController</code>) is created and displayed modally. This does not specifically affect the use of cocos2d, but may impact applications that combine cocos2d visual components with standard <code>UIKit</code> views and controls. It also impacts the visual flow of your game, since going from not overlaying to overlaying can take a few seconds and involves a mandatory display of a camera iris image by iOS.</p>
<p>Another important aspect of swapping the device camera overlay in and out is that the running scene must be stopped and restarted on each change between overlaying and not overlaying or back again. This is needed to ensure that active actions and touch events are cleaned up correctly between transitions. For the most part, this effect is typically transparent to the application. As part of the stopping and restarting of the scene, the <code>onExit</code> and <code>onEnter</code> methods on the controlled node are called just before and just after the switchover, respectively. Your controlled node can make use of these calls as hooks to know when the switchover occurs in order to update state accordingly. Typically this might include hiding some visual items and showing others. For example, when the device camera image is visible, you might hide a background image or skybox and show some camera controls.</p>
<h3><a name="installing"></a>Fantastic! Where Can I Get Me Some of That?</h3>
<p>You can download the source code for this framework in the <a href="#download">download area</a> at the top-right of this article. It is distributed under an <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a>, which makes it free for you to use in your projects. However, if you find this code is useful, please remember to make a donation <a href="#donate">above</a> to help us fund the ongoing development and support of frameworks such as this.</p>
<p>Once downloaded, unzip the file, and drag the extracted directory to your <code>Classes</code> group within your <code>Xcode</code> project. On the dialog that pops up when you do that, make sure both the <em><strong>Copy items into destination group&#8217;s folder</strong></em> and <em><strong>Recursively create groups for any added folders</strong></em> options are both selected.</p>
<p>You can also download a full <code>Xcode</code> project of a simple <a href="#download-example-game">example game</a> that demonstrates the use of node controllers for both auto-rotation and device camera overlay. Simply unzip the downloaded file to extract the full project directory. The game is based on an example developed by <a href="http://www.raywenderlich.com/">Ray Wenderlich</a> and published by him as a <a href="http://www.raywenderlich.com/352/how-to-make-a-simple-iphone-game-with-cocos2d-tutorial">tutorial</a>. Our version also makes use of a framework of <a href="/2010/cocos2d-ui-controls/">cocos2d UI Controls</a> that we developed, and which also may be of interest to you for your cocos2d projects.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2010/cocos2d-and-uiviewcontrollers/feed/</wfw:commentRss>
		<slash:comments>12</slash:comments>
		</item>
		<item>
		<title>cocos2d UI Controls</title>
		<link>http://brenwill.com/2010/cocos2d-ui-controls/</link>
		<comments>http://brenwill.com/2010/cocos2d-ui-controls/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 03:45:30 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[iOS Components]]></category>
		<category><![CDATA[cocos2d]]></category>
		<category><![CDATA[UI Controls]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=38</guid>
		<description><![CDATA[ <p>This cocos2d framework package includes several useful cocos2d user interface controls and frameworks, including:</p> Joystick &#8211; a flexible joystick for user control in two dimensions with a single finger CCNodeAdornments &#8211; a framework for assigning adornments to CCNodes to temporarily change the appearance of the CCNode, such as scaling, fading, adding visual embellishments, <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2010/cocos2d-ui-controls/">cocos2d UI Controls</a></span>]]></description>
			<content:encoded><![CDATA[
<p>This <a href="http://www.cocos2d-iphone.org/">cocos2d</a> framework package includes several useful cocos2d user interface controls and frameworks, including:</p>
<ul>
<li><a href="#joystick">Joystick</a> &#8211; a flexible joystick for user control in two dimensions with a single finger</li>
<li><a href="#adornments">CCNodeAdornments</a> &#8211; a framework for assigning <em>adornments</em> to <code>CCNodes</code> to temporarily change the appearance of the <code>CCNode</code>, such as scaling, fading, adding visual embellishments, etc. This is most useful when used with menu items to temporarily change the appearance of the menu item during user selection.</li>
</ul>
<h3><span id="more-38"></span><a name="joystick"></a>Joystick</h3>
<p>For many games, controlling the action using a joystick is an integral and indispensable part of the game.</p>
<p>The joystick developed by us here is a subclass of <code>CCLayer</code> that contains two <code>CCNode</code> children, each of which is typically a <code>CCSprite</code> image. The <em>thumb</em> image is a smaller image that the user moves by touching and dragging. The second is an optional background image over which the thumb image is moved. The sizes of the thumb and background nodes can be set independently, or in the case of a joystick with no background image, the size of the <code>Joystick</code> node itself is set during initialization instead.</p>
<p>The following figure shows a <code>Joystick</code> control with a round green thumb and no background image controlling the player movement in a first-person game within a three-dimensional world. Like most first-person games, the player can be moved forward or backward and turn left or right by user movement of the joystick control.</p>
<div id="attachment_37" class="wp-caption alignnone" style="width: 310px"><a href="http://brenwill.com/wp-content/uploads/joystick-example.png"><img class="size-medium wp-image-37" title="Example of a Joystick control in use" src="http://brenwill.com/wp-content/uploads/joystick-example-300x200.png" alt="Example of a Joystick control in use" width="300" height="200" /></a><p class="wp-caption-text">A simple round green Joystick thumb, without a background image, controlling player motion in a simple first-person perspective game.</p></div>
<p>This is a visually trivial example of the Joystick control, stripped to the basics. In a real game, much more interesting thumb and background images would of course be applied to match the look and feel of the game.</p>
<p>To use the joystick, the user touches within the bounds of the <code>Joystick</code> node. Movement of the thumb image is constrained to the size of the <code>Joystick</code> node, however, the user may continue dragging outside the bounds of the joystick without losing control of the joystick. When the user lifts the finger from the screen, the joystick thumb will glide smoothly back to the center of the joystick (complete with a little bounce as it centers), just like a real physical joystick.</p>
<p>Creating a <code>Joystick</code> in your code is simple, as shown in the following, which sets up the <code>Joystick</code> shown above:</p>
<pre class="brush: objc; title: ; notranslate">
CCSprite* jsThumb = [CCSprite spriteWithFile: kJoystickThumbFileName];
// jsThumb.scale = 0.80; // change thumb size if you like
joystick = [Joystick joystickWithThumb: jsThumb
andSize: CGSizeMake(kJoystickSideLength, kJoystickSideLength)];
joystick.position = ccp(kJoystickPadding, kJoystickPadding);
[self addChild: joystick];
</pre>
<p>If a <code>Joystick</code> with a background image is desired instead, just use a different creation method:</p>
<pre class="brush: objc; title: ; notranslate">
CCSprite* jsThumb = [CCSprite spriteWithFile: kJoystickThumbFileName];
//  jsThumb.scale = 0.80;       // change thumb size if you like
CCSprite* jsBackdrop = [CCSprite spriteWithFile: kJoystickBackdropFileName];
joystick = [Joystick joystickWithThumb: jsThumb
andBackdrop: jsBackdrop];
joystick.position = ccp(kJoystickPadding, kJoystickPadding);
[self addChild: joystick];
</pre>
<p>The application can read the position of the <code>Joystick</code> thumb, relative to its resting position, at any time from either the <code>velocity</code> property or the <code>angularVelocity</code> property.</p>
<p>The <code>velocity</code> property returns a <code>CGPoint</code> reporting the relative position of the thumb in cartesian X-Y coordinates. The X-Y values returned range from <code>-1</code> to <code>+1</code>, with zero being the center position. However, the <em>magnitude</em> of the <code>velocity</code> vector is clamped to unit length, so the set of possible points returned by the <code>velocity</code> property therefore covers the area of a circle of unit radius, centered on zero. This means, for instance, that pulling the thumb as far as it will go up and right will not take both X and Y each to a value of one at the same time. Instead, the thumb will stop when the radial distance from the origin is equal to one. This design provides a more natural range of values for controlling motion within a game.</p>
<p>The <code>angularVelocity</code> property returns a structure reporting the position of the thumb in an angular coordinate system, in terms of an angle plus a radius. The angle is given in positive or negative degrees from vertical (forward), and the radius ranges from zero to one. As with the <code>velocity</code> property, the set of points returned by the <code>angularVelocity</code> property therefore also covers the area of a circle of unit radius.</p>
<p>To add a <code>Joystick</code> to your game, download and install the <em>cocos2d UI Controls</em> framework code into your <code>Xcode</code> project as described <a href="#installing">below</a>, then <code>#import</code> the <code>Joystick.h</code> file into your code where it is needed, typically into a custom <code>CCLayer</code> subclass file. The <code>Joystick.h</code> header file contains extensive documentation on the <code>Joystick</code> API and is your best source for understanding how to use it in your project.</p>
<h3><a name="adornments"></a>CCNodeAdornments</h3>
<p>Adornments are visual components that can be added to a subclass of <code>CCNode</code> to provide a visual appearance that can be <em>activated</em> and <em>deactivated</em> on demand. Familiar examples of this might be the icon tags associated with <code>iOS</code> app icons. Or within a cocos2d game, adornments can provide visual feedback when a user touches a game element, menu item, or other button-like nodes. The example shown below is the same scene shown in the <code>Joystick</code> description above, but in this case, the user is currently pressing the sunshine button (actually a<code> CCMenuImageToggle</code>) on the right. Doing so has <em>activated</em> the adornment and a yellow ring has faded in around the button. When the user releases the button, or drags his finger away from the button, the adornment will be <em>deactivated</em>, and the ring will fade away again.</p>
<div id="attachment_36" class="wp-caption alignnone" style="width: 310px"><a href="http://brenwill.com/wp-content/uploads/adorned-button-example.png"><img class="size-medium wp-image-36" title="Example of an adorned button" src="http://brenwill.com/wp-content/uploads/adorned-button-example-300x200.png" alt="Example of an adorned button" width="300" height="200" /></a><p class="wp-caption-text">The sunshine button on the right is being pressed by the user and a yellow ring adornment has faded in around the button.</p></div>
<p>To be clear, this image shown here is not the alternate <em>toggled</em> image of the <code>CCMenuItemToggle</code>. Nor is it the <code>selected</code> image of a <code>CCMenuItemImage</code>, which cannot be made to fade in and out in an animated manner. The adornment is a separate image that appears over or under the basic images of the menu item. In fact, in the action above, once the user releases the button, the <code>CCMenuItemToggle</code> itself will toggle to a different image altogether to show the changed state. The adornment is displayed only during the transitional stage while the user is actually pressing the button.</p>
<p>Instead of a ring, the adornment image could also have been a semi-transparent colored &#8220;shine&#8221; image that faded in and out over the main button image as the user touches and releases the button.</p>
<p>Another type of adornment scales the adorned node when activated. For example, the button could be made to grow in size when touched, and shrink back again when released, with the scaling up and down being animated for effect. Should fading and scaling seem boring to you, other adornment effects can easily be developed should you have other interesting effects in mind (spinning, changing color, etc).</p>
<p>Using adornments is fairly straightforward. At the very basic level, an adornment can simply be added as a child to any <code>CCNode</code>, and then tracked, activated and deactivated manually by the application. But where adornments really become interesting is when a <code>CCNode</code> is made <em>adornable</em> so it can automatically <code>activate</code> and <code>deactivate</code> its adornment at the appropriate times.</p>
<p>To make a <code>CCNode</code> adornable, you first create a subclass of the <code>CCNode</code> and add the <code>AdornableCCNodeProtocol</code> protocol to it. In this framework, we&#8217;ve done that already for <code>CCMenuItemToggle</code> and <code>CCMenuItemImage</code>, and tied the activation and deactivation of its adornment to the <code>selected</code> and <code>unselected</code> actions of the adornable subclasses. So when an <code>AdornableMenuItemToggle</code> is selected by the user, its adornment is automatically activated, and when the menu item is unselected, the adornment is automatically deactivated. As described above, depending on the adornment type, when the user selects and unselects the menu item, this might expand and shrink the menu item, or might fade in and out a shine or ring on top of the menu item.</p>
<p>The adornments themselves are <code>CCNode</code>s that support the <code>CCNodeAdornmentProtocol</code> protocol. To support development of new adornments, we&#8217;ve included in the framework an abstract <code>CCNodeAdornmentBase</code> class, along with concrete <code>CCNodeAdornmentOverlayFader</code> and <code>CCNodeAdornmentScaler</code> classes to perform the overlay fading and node scaling I&#8217;ve been describing above.</p>
<p>Putting this into practice then, the scene displayed in the picture above, with the yellow adornment ring, was created with the following code in the custom <code>CCLayer</code> that forms the scene:</p>
<pre class="brush: objc; title: ; notranslate">
// Toggle between two subitems: one for shutter button, one for sky button
CCMenuItem* camMI = [CCMenuItemImage itemFromNormalImage: kShutterButtonFileName
selectedImage: kShutterButtonFileName];
CCMenuItem* skyMI = [CCMenuItemImage itemFromNormalImage: kSkyButtonFileName
selectedImage: kSkyButtonFileName];
backdropToggleMI = [AdornableMenuItemToggle itemWithTarget: self
selector: @selector(changeBackdropSelected:)
items: camMI, skyMI, nil];
backdropToggleMI.position = ccp(self.contentSize.width - kBackdropToggleMenuInset, kBackdropToggleMenuInset);

 // Instead of having different normal and selected images, the toggle menu item uses an
// adornment, which is displayed whenever an item is selected.
 CCNodeAdornmentBase* adornment;

 // The adornment is a ring that fades in around the menu item and then fades out when
 // the menu item is no longer selected.
CCSprite* ringSprite = [CCSprite spriteWithFile: kButtonRingFileName];
adornment = [CCNodeAdornmentOverlayFader adornmentWithAdornmentNode: ringSprite];
 adornment.zOrder = kAdornmentUnderZOrder;

 // Attach the adornment to the menu item and center it on the menu item
 adornment.position = backdropToggleMI.anchorPointInPixels;
 backdropToggleMI.adornment = adornment;

CCMenu* bgMenu = [CCMenu menuWithItems: backdropToggleMI, nil];
bgMenu.position = CGPointZero;
[self addChild: bgMenu];
</pre>
<p>If you would rather see the &#8220;shine&#8221; adornment described above, replace lines <code>17-19</code> above with:</p>
<pre class="brush: objc; first-line: 17; title: ; notranslate">
CCSprite* shineSprite = [CCSprite spriteWithFile: kButtonShineFileName];
shineSprite.color = ccYELLOW;
adornment = [CCNodeAdornmentOverlayFader adornmentWithAdornmentNode: shineSprite
peakOpacity: kPeakShineOpacity];
</pre>
<p>Or to have the menu item grow and shrink when pressed by the user, replace the original lines <code>17-19</code> above with:</p>
<pre class="brush: objc; first-line: 17; title: ; notranslate">

adornment = [CCNodeAdornmentScaler adornmentToScaleUniformlyBy: kButtonAdornmentScale];
</pre>
<p>To add adornments to your project, download and install the <em>cocos2d UI Controls</em> framework code into your <code>Xcode</code> project as described <a href="#installing">below</a>, then <code>#import</code> the <code>CCNodeAdornments.h</code> file into your code where it is needed. That header file also contains extensive documentation on the adornments API and is your best source for understanding the adornments framework. And once you get some experience with the framework, don&#8217;t be timid about extending the framework by inventing your own adornments!</p>
<h3><a name="installing"></a>Fantastic! Where Can I Get Me Some of That?</h3>
<p>You can download the source code for this framework in the <a href="#download">download area</a> at the top-right of this article. It is distributed under an <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a>, which makes it free for you to use in your projects. However, if you find this code is useful, please remember to make a donation <a href="#donate">above</a> to help us fund the ongoing development and support of frameworks such as this.</p>
<p>Once downloaded, unzip the file, and drag the extracted directory to your <code>Classes</code> group within your <code>Xcode</code> project. On the dialog that pops up when you do that, make sure both the <em><strong>Copy items into destination group&#8217;s folder</strong></em> and <em><strong>Recursively create groups for any added folders</strong></em> options are both selected.</p>
<h3>Credit Where Credit is Due</h3>
<p>Our Joystick code was inspired by code donated to the cocos2d community by cocos2d user <em>adunsmoor</em>. The original inspirational code can be found <a href="http://www.cocos2d-iphone.org/forum/topic/1418">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2010/cocos2d-ui-controls/feed/</wfw:commentRss>
		<slash:comments>25</slash:comments>
		</item>
		<item>
		<title>Flexible iOS Logging</title>
		<link>http://brenwill.com/2010/flexible-ios-logging/</link>
		<comments>http://brenwill.com/2010/flexible-ios-logging/#comments</comments>
		<pubDate>Sat, 24 Jul 2010 02:58:01 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[iOS Components]]></category>
		<category><![CDATA[Logging]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=26</guid>
		<description><![CDATA[ <p>Apple&#8217;s Cocoa SDK framework for the iOS provides basic logging capabilities through the NSLog function. This allows the developer to log simple text messages to the development console.</p> <p>However, the use of NSLog suffers from two drawbacks:</p> There is only one level of logging with NSLog. So during development, you get a record <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2010/flexible-ios-logging/">Flexible iOS Logging</a></span>]]></description>
			<content:encoded><![CDATA[
<p>Apple&#8217;s Cocoa SDK framework for the iOS provides basic logging capabilities through the <code>NSLog</code> function. This allows the developer to log simple text messages to the development console.</p>
<p>However, the use of <code>NSLog</code> suffers from two drawbacks:</p>
<ol>
<li>There is only one <em>level</em> of logging with <code>NSLog</code>. So during development, you get a record of <em>all</em> of the <code>NSLog</code> calls that you&#8217;ve inserted, some of which might be quite detailed and frequent, and it&#8217;s easy to be overwhelmed by the clutter. There is no way of selectively turning off some of the output.</li>
<li>The <code>NSLog</code> function is called every time it is encountered, including within executing production release code. To avoid this, developers must typically remove all calls to <code>NSLog</code> before compiling for a production release. This is a headache fraught with possible mistakes and inhibits debugging future releases.</li>
</ol>
<p>To remedy this, we&#8217;ve developed a logging framework that solves both of these issues. This library consists of a single <code>Logging.h</code> header file which adds, to iOS, flexible, non-intrusive logging capabilities that are efficiently enabled or disabled via compile switches.<span id="more-26"></span></p>
<h3>Quick Start</h3>
<p>To use this enhanced logging functionality, simply <code>#import</code> the <code>Logging.h</code> header file into any code file to which you want to add enhanced logging, and set the compiler switch <code>LOGGING_ENABLED=1</code>, either in a <code>#define</code> statement or in the <code>Xcode</code> build setting <code>GCC_PREPROCESSOR_DEFINITIONS</code>.</p>
<h3>Logging Levels</h3>
<p>To address the first issue described above, that of a single level of logging, this library defines four levels of logging: <code>Trace</code>, <code>Info</code>, <code>Error</code> and <code>Debug</code>, and each is enabled independently via a distinct compiler switch. Invoking any level is as simple as calling the appropriate variadic (variable number of arguments) function as shown in the following examples:</p>
<pre class="brush: objc; title: ; notranslate">
LogTrace(@&quot;Simple message&quot;);
LogTrace(@&quot;Message with %i argument...oops I mean %.1f arguments&quot;, 1, 2.0f);
LogInfo(@&quot;Do you object to this %@ date object?&quot;, [NSDate new]);
LogDebug(@&quot;I'll take this out if ever I solve this bug&quot;);
LogError(@&quot;Don't do that: %@&quot;, [NSException exceptionWithName: @&quot;CRYING&quot; reason: @&quot;Spilled milk&quot; userInfo:nil]);
</pre>
<p>In the examples above, you can see the four logging levels in action, along with the use of variable arguments that match against templates in the message string, in exactly the same manner as the <code>NSLog</code> or <code>printf</code> functions. The first argument is an <code>NSString</code> that optionally includes embedded <em>format specifiers</em>, and subsequent optional arguments indicate data to be formatted and inserted into that string. As with <code>NSLog</code> and <code>printf</code>, there must be an equal number of embedded <em>format specifiers</em> and optional arguments. For more information on string formatting, see the documentation for <code><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Reference/Foundation/Miscellaneous/Foundation_Functions/Reference/reference.html#//apple_ref/doc/uid/20000055-BCIJAAIA">NSLog</a></code>, <em><a href="http://developer.apple.com/iphone/library/documentation/Cocoa/Conceptual/Strings/Articles/formatSpecifiers.html">String Format Specifiers</a></em> and <a href="http://en.wikipedia.org/wiki/Printf#printf_format_placeholders"><code>printf</code> formatting</a>.</p>
<p>The output of the above code is:</p>
<pre class="brush: plain; title: ; notranslate">
2010-07-23 18:27:23.398 Logging Sample[35700:20b] [trace] Simple message
2010-07-23 18:27:23.399 Logging Sample[35700:20b] [trace] Message with 1 argument...oops I mean 2.0 arguments
2010-07-23 18:27:23.402 Logging Sample[35700:20b] [info] Do you object to this 2010-07-23 18:27:23 -0400 date object?
2010-07-23 18:27:23.402 Logging Sample[35700:20b] [DEBUG] I'll take this out if ever I solve this bug
2010-07-23 18:27:23.403 Logging Sample[35700:20b] [***ERROR***] Don't do that: Spilled milk
</pre>
<p>In this output listing, <code>Logging Sample</code> is just the name of the <code>Xcode</code> project. As you can see, each log message identifies the level of logging. <em>Trace</em> logging is recommended for detailed tracing of program flow, such as inside a loop, or on each frame render in a graphic engine. <em>Info</em> logging is recommended for general, infrequent, information messages such as initialization or shutdown activities, file loads, or user settings changes. <em>Error</em> logging, as the name suggests, is recommended for use only when there is an error to be logged. And finally, <em>debug</em> logging is recommended for temporary use during debugging. When trying to track down a coding error, you might temporarily sprinkle even your most detailed code with <em>debug</em> log messages. But once the problem is resolved, you should remove them, or possibly convert the most useful of them into <em>info</em> or <em>trace</em> logs.</p>
<p>Each of the logging levels is independently turned on or off by setting a boolean compiler switch to either <code>1</code> or <code>0</code>, respectively, as follows:</p>
<ul>
<li><code>LOGGING_LEVEL_TRACE</code> enables or disables the <code>LogTrace</code> function.</li>
<li><code>LOGGING_LEVEL_INFO</code> enables or disables the <code>LogInfo</code> function.</li>
<li><code>LOGGING_LEVEL_ERROR</code> enables or disables the <code>LogError</code> function.</li>
<li><code>LOGGING_LEVEL_DEBUG</code> enables or disables the <code>LogDebug</code> function.</li>
</ul>
<p>By selectively turning on or off each of these switches, you could choose to output only <em>error</em> log messages so that logging will only occur if something goes wrong, or perhaps include <em>info</em> messages, so that you can keep track of high-level events such as file loads, or initialization and shutdown code. And when attempting to debug the details of a module, where you want more copious and detailed logging, you might enable either or both of the <em>trace</em> or <em>debug</em> logging levels.</p>
<p>The <code>LOGGING_ENABLED</code> compiler switch controls overall logging. This is normally turned on in development code to make use of the logging functionality. But in production code, you can disable all logging in one fell swoop by turning off the <code>LOGGING_ENABLED</code> compiler switch. This has the effect of overriding all the individual level switches, and disables all logging. None of the levels will produce log messages with the <code>LOGGING_ENABLED</code> compiler switch turned off.</p>
<p>To assist with tracking down bugs, you can opt to have each logged entry automatically include class, method and line information by turning on the <code>LOGGING_INCLUDE_CODE_LOCATION</code> compiler switch. Doing so will modify the log output above to appear as:</p>
<pre class="brush: plain; title: ; notranslate">
2010-07-23 18:28:17.238 Logging Sample[35732:20b] -[Logging_SampleAppDelegate applicationDidFinishLaunching:][Line 20] [trace] Simple message
2010-07-23 18:28:17.239 Logging Sample[35732:20b] -[Logging_SampleAppDelegate applicationDidFinishLaunching:][Line 21] [trace] Message with 1 argument...oops I mean 2.0 arguments
2010-07-23 18:28:17.247 Logging Sample[35732:20b] -[Logging_SampleAppDelegate applicationDidFinishLaunching:][Line 22] [info] Do you object to this 2010-07-23 18:28:17 -0400 date object?
2010-07-23 18:28:17.248 Logging Sample[35732:20b] -[Logging_SampleAppDelegate applicationDidFinishLaunching:][Line 23] [DEBUG] I'll take this out if ever I solve this bug
2010-07-23 18:28:17.249 Logging Sample[35732:20b] -[Logging_SampleAppDelegate applicationDidFinishLaunching:][Line 24] [***ERROR***] Don't do that: Spilled milk
</pre>
<p>Like most compiler switches, each of the switches discussed in this article is turned on by setting its value to <code>1</code> and turned off by setting its value to <code>0</code>. This can be done via <code>#define</code> statements in your code (or in <code>Logging.h</code>), or via the compiler build setting <code>GCC_PREPROCESSOR_DEFINITIONS</code> in your <code>Xcode</code> build configuration. Using the <code>GCC_PREPROCESSOR_DEFINITIONS</code> <code>Xcode</code> setting is the preferred choice, so that logging can be configured differently for different <code>Xcode</code> <em>targets</em> or build configurations, and particularly to ensure that logging is not accidentally left enabled in production release builds.</p>
<h3>Logging Overhead</h3>
<p>To address the second issue described above, namely the memory and processing overhead of the logging function calls themselves, the logging functions are implemented here via macros. Disabling logging, either entirely, or at a specific level, completely removes the corresponding log invocations from the compiled code, thereby eliminating both the memory and CPU overhead that the logging calls would add. So, there is absolutely no runtime penalty to be paid by leaving copious quantities of <code>LogTrace</code> calls spread thickly throughout your code, as long as you simply disable either <em>trace</em> logging or <em>all</em> logging by turning off the <code>LOGGING_LEVEL_TRACE </code>or <code>LOGGING_ENABLED</code> compiler switch, respectively, at build time.</p>
<h3>Fantastic! Where Can I Get Me Some of That?</h3>
<p>You can download this logging framework (a single <code>Logging.h</code> file) in the <a href="#download">download area</a> at the top-right of this article. It is distributed under an <a href="http://en.wikipedia.org/wiki/MIT_License">MIT license</a>, which makes it free for you to use in your projects. However, if you find this code is useful, please remember to make a donation <a href="#donate">above</a> to help us fund the ongoing development and support of frameworks such as this.</p>
<h3>Credit Where Credit is Due</h3>
<p>Thanks to <a href="http://iphoneincubator.com/blog/debugging/the-evolution-of-a-replacement-for-nslog">Nick Dalton</a> for outlining the underlying ideas for using variadic macros as well as for outputting the code location as part of the log entry.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2010/flexible-ios-logging/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>Colophon</title>
		<link>http://brenwill.com/2010/colophon/</link>
		<comments>http://brenwill.com/2010/colophon/#comments</comments>
		<pubDate>Tue, 20 Jul 2010 04:21:28 +0000</pubDate>
		<dc:creator>Bill Hollings</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[About this site]]></category>
		<category><![CDATA[Colophon]]></category>

		<guid isPermaLink="false">http://brenwill.com/?p=13</guid>
		<description><![CDATA[<p>I thought I would describe how we constructed this site. There are a lot of useful site-construction tools out there, and it&#8217;s always useful to see what works for a particular site.</p> WordPress <p>We used the wonderful WordPress publishing platform to build this site. In case you are unfamiliar with WordPress, let me include <span style="color:#777"> . . . &#8594; Read More: <a href="http://brenwill.com/2010/colophon/">Colophon</a></span>]]></description>
			<content:encoded><![CDATA[<p>I thought I would describe how we constructed this site. There are a lot of useful site-construction tools out there, and it&#8217;s always useful to see what works for a particular site.<span id="more-13"></span></p>
<h3>WordPress</h3>
<p>We used the wonderful <em><a href="http://wordpress.org/">WordPress</a></em> publishing platform to build this site. In case you are unfamiliar with <em>WordPress</em>, let me include a shameless plug for it here. <em>WordPress </em>is a well-architected, extremely flexible, extensible, pluggable, developer-friendly publishing platform. <em>WordPress </em>originated primarily as a blogging platform, but has since evolved to become more like a general<a href="http://en.wikipedia.org/wiki/Content_management_system"> Content Management System </a>(CMS). However, it is nowhere near as complex as some of the &#8220;enterprise&#8221; CMS platforms out there, and for small-to-medium sized websites, <em>WordPress </em>provides an excellent combination of ease-of-use and extensibility.</p>
<p>One of the strengths of <em>WordPress</em> is its well-designed, pluggable architecture, under which additional functionality and skinning can be added via plug-ins and themes developed by the third-party <em>WordPress</em> community. And this community is very active! There are literally thousands of third-party plug-ins and themes available for <em>WordPress</em>, providing everything from sophisticated, snazzy user-experiences, to enhanced editors, automatic formatters, shopping carts, bulletin-boards, and beyond. If you can imagine it, then there is likely a <em>WordPress </em>plug-in available for it. And if that is not enough, should you need to uniquely customize your site, with a little <a href="http://en.wikipedia.org/wiki/PHP">PHP</a> coding it is a fairly straightforward exercise to write your own plug-in.</p>
<h3>Atahualpa Theme</h3>
<p>On top of the core <em>WordPress </em>environment, this site uses the <em><a href="http://wordpress.bytesforall.com/">Atahualpa</a></em> visual theme, which we&#8217;ve found (and you can hopefully see) provides a clean, well-laid-out, professional look. The <em>Atahualpa</em> theme supports widgets and an incredibly diverse number of layout and formatting options.</p>
<h3>Plug-Ins</h3>
<p>Like any site based on <em>WordPress</em>, we make use of several plug-ins to enhance this site with useful functionality, and we&#8217;ve even developed our own plug-in to provide features and capabilities that we found were unique to our site. Here is a list of the <em>WordPress </em>plug-ins in use on this site:</p>
<ul>
<li><em><a href="http://wordpress.org/extend/plugins/akismet/">Akismet</a></em> is a popular anti-spam filter for article comments. It uses a centralized web repository of templates and known spam structures to identify potential spam in article comments. <em>Akismet</em> is bundled with <em>WordPress</em>.</li>
<li><em><a href="http://wordpress.org/extend/plugins/nospamnx/">NoSpamNX</a></em> is another anti-spam comment filter that uses invisible fields that are blindly filled out by spam-bots, but not by human users.</li>
<li><em><a href="http://wordpress.org/extend/plugins/spam-stopper/">Spam Stopper</a></em> is yet another anti-spam comment filter that uses a simple challenge-response question to prove that the user really is a human being. However, since this adds a minor inconvenience for users who fill out comments, we have decided to keep this plug-in disabled until we determine it to be necessary to bolster the other anti-spam methods.</li>
<li><a href="http://wordpress.org/extend/plugins/configurable-tag-cloud-widget/"><em>Configurable Tag Cloud</em></a> is a widget that displays a cloud of topics linked to articles. The font size and color of each topic is proportional to the number of articles that are identified by that topic.</li>
<li><a href="http://wordpress.org/extend/plugins/tinymce-advanced/"><em>TinyMCE Advanced</em></a> is a visual <a href="http://en.wikipedia.org/wiki/WYSIWYG">WYSIWYG</a> editor for writing articles and pages. It adds a number of editing features to the base <em>WordPress</em> visual editor, including tables and superior font styling.</li>
<li><a href="http://wordpress.org/extend/plugins/syntaxhighlighter/"><em>Syntax Highlighter Evolved</em></a> is a syntax formatter for source code samples contained in some of the articles. It formats source code text in a mono-spaced font as it would appear in a source code editor, including highlighting programming language keywords, and optional line numbering.</li>
<li><em><a href="http://wordpress.org/extend/plugins/download-monitor/">WordPress Download Monitor</a></em> keeps track of how many times any downloadable file on the site has been downloaded, and can tally the results by week or month.</li>
<li><em><a href="http://wordpress.org/extend/plugins/after-the-deadline/">After the Deadline</a><a href="http://wordpress.org/extend/plugins/author-info-widget/"></a></em> is a better spell/grammar checker for the <em>WordPress</em> visual editor.</li>
<li><em><a href="http://wordpress.org/extend/plugins/author-info-widget/">Author Information Widget</a></em> displays the picture, bio, and optional contact info about the author of an article.</li>
<li><em><a href="http://wordpress.org/extend/plugins/wp-super-cache/">WP Super Cache</a></em> generates static HTML files from the dynamic <em>WordPress</em> pages. After the static file is generated, the web server will serve it instead of repeatedly processing the comparatively heavier and more expensive <em>WordPress</em> PHP scripts.</li>
<li><a href="http://wordpress.org/extend/plugins/ie6-upgrade-option/"><em>IE6 Upgrade Option</em></a> sits and waits for a user to come along who is still using a version of Internet Explorer at version 6 or lower as their web browser. It then displays a slick pop-up warning to the user, explaining that IE 6 suffers from poor security and stability, and may not support some of the features of this (or frankly any modern) web site, and presents the user several links to download a more modern browser.</li>
<li><em>Brenwill Add-ons</em> is a bespoke plug-in designed and developed here at The Brenwill Workshop to provide specific customized functionality for our website. This includes the download and PayPal donation components seen in some of the articles, as well as a wrapper that floats other components on the left or right of an article.</li>
</ul>
<h3>Extras</h3>
<p>The images displayed across the header on each page, in rotation, were retrieved under a <a href="http://en.wikipedia.org/wiki/Creative_Commons_licenses">Creative Commons license</a> from <a href="http://www.zonescreen.eu/blog/2010/02/20/atahualpa-theme-header-images/">Thoughts from beardyland… </a>and <a href="http://www.americaneer.com/atahualpaheaderimages/">Americaneer</a>.</p>
<h3>Costs and Attribution</h3>
<p>All of the components listed above are available for free on the web. Much good, competent effort has gone into creating these components by their respective developers. We here at The Brenwill Workshop continue to recognize and appreciate their efforts. In addition to the attributions above, wherever possible we support this work by making a financial donation to each developer. We encourage you to do the same with any components that you use.</p>
]]></content:encoded>
			<wfw:commentRss>http://brenwill.com/2010/colophon/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>

