How do I create a custom page curl Core Animation? - iphone

I'm trying to create a "page curl" animation of an image in my iPhone application. I t UIViewAnimationTransitionCurlUp, and it's undocumented Core Animation siblings, however the image I need to animate is a transparent PNG, with "uneven" (some alpha pixels) outlines. When using the aforementioned pre-made transition, those alpha pixels are painted black as soon as the animation starts, which looks terribly ugly.
Therefore, I seek to create a Core Animation of my own. I have tried to research the subject, but have been unable to find a good overview of the techniques involved. The implementation would of course have to be more complex than a single property change, I get the feeling that even CATransform3D would be to limited for this purpose, as the image needs to have different 3D transformations applied in different parts of it - changing over time. How would one then go about this subject? I'm very grateful for any thoughts or ideas!
Best,
Eli

As Corey points out, you'll probably need to go with OpenGL ES for this one. Core Animation exposes the ability to work with layers, even in 3-D, but all layers are just rectangles and they are manipulated as such. You can animate the flipping of a layer about an axis, even with a perspective distortion, but the kind of curving you want to do is more complex than you can manage using the Core Animation APIs.
You might be able to split your image up into a mesh of tiny layers and manipulate each using a CATransform3D to create this curving effect, but at that point you might as well be using OpenGL ES to create the same effect.

The book Core Animation for Mac OS X and the iPhone: Creating Compelling Dynamic User Interfaces from Pragmatic Programmer may help you write custom Core Animation animations.

Related

Elements/Wired Style 3D Animation

I am trying to implement the style of 3D rotational animation you see in the Elements and the Wired iPad applications. The animation has the UIScrollView style acceleration so it looks like they have connected a UIScrollView to a sequence of images.
I have tried implementing it in UIKit, using an "empty" UIScrollView to increment through an array of images and set the contents of a UIImageView, based on the content offset. This works but even with scaled down images on the simulator, it is very sluggish. I am not sure how I could optimise it to make it run faster.
Source Code on GitHub
I have also tried doing something similar in Cocos2D. Cocos could animate the sequence very smoothly but I couldn't control the animation. I tried using a scroll view and setDisplayFrame to step through an animation but it didn't work.
Any help or suggestions on either option would be greatly appreciated.
I'm not 100% sure I understand the effect you're trying to achieve, but if you're referring to the images in "The Elements" app which you can spin around, then yeah, you probably don't want to be doing that with an UIScrollView.
You can control the animation of content in Cocos2d. While you can set an animation to "just run", you can also manually set frames directly out of an animation, so if you can get smooth animation out of Cocos, you should be able to do it interactively. Look at the atlas sprite object - you can set the rect of an animation frame directly.
However, again, I'm not sure this is the best approach, either, since that's a lot of frames for a texture. If you're going to be doing a lot of 3D photographic objects, you might consider looking into the video codecs and scrubbing along a video instead of trying to pack all the frames of a rotation animation into a series of textures.
Just so you know, the guy who made "The Elements" wrote an article about the development of the app, and here's what he had to say about the 3D rotatable objects:
"Creating fluidly spinning objects with the level of crystal clear photographic quality I demanded is actually harder than it might seem. A number of the obvious things the more technical of you might think of turn out not to work for reasons too complicated to get into here. Suffice to say that John designed a brilliant solution that uses the iPad's excellent graphics subsystem to lend a hand in ways it's not normally intended to."
I don't know how exactly they achieved the 3D objects, but perhaps that "uses the iPad's excellent graphics subsystem" mention gives you a clue where to head from here...

Need some guidelines on iPad animation programming

I'm creating an interactive e-book for the iPad. This book will contain multiple pages that will consist of a lot of animations (frame and motion animations), transitions,... I was wondering what my development options are, should I use OpenGL, Quartz,...?
I've use UIImageView.animationImages before and found that it had really bad performance. What's the best way to draw frame based animations?
Does anybody have some good pointers to resources on this?
thanks in advance,
Thomas
I guess that depends a bit on what you'll be drawing. If you have a need for 3D, then OpenGL is the way to go, but it doesn't sound like it. I have a feeling Quartz2D is going to be just fine for your 2D drawing needs. I've done drawing with both and they have a very similar API. I think the downside of using all the raw power of OpenGL is that you have then signed up for doing most of the work yourself. I don't recommend attempting to using Core Animation high level APIs to manipulate OpenGL views.
If you do use Quartz2D and "normal" UIViews instead of OpenGL/EAGLView, then you can take advantage the many pre-canned animations Apple already build with Core Animation. This include the card flip left/right, resizing, moving (x/y translation), rotation and the ever popular e-book page curl.
The best example of iBook like custom page curl functionality I could find is this example code from High Caffeine Content. However, you don't have to bring that much math to the table if you just want to use the out of the box Core Animation stuff. The bad performance you may have encountered could have been due to anything, including older/slower hardware. They have revved the graphics chips on the new devices.

Can this type of wiggle image deformation be done on iPhone without using openGL

I have a straight image and I want to deform it in a wave-like manner.
Original image:
straight texture http://img145.imageshack.us/img145/107/woodstraight.png
and I want it to look like this (except animated):
bent texture http://img145.imageshack.us/img145/8496/woodbent.png
I haven't tackled the learning curve of openGL yet so if I can do this with Core Animation it would be great.
Is this possible?
Unfortunately, I think this is a job for OpenGL. You could achieve the same affect in Quartz by slicing the image up vertically and drawing segments with different vertical offsets... but I don't think you'd be able to achieve good enough performance to animate it. (At least, with 1px or 2px wide slices)
You could also leave the image stationary, and use Quartz to animate a masking path that would create the waving edges. That probably wouldn't look too natural, though.
As far as I know, Core Animation on the iPhone isn't capable of doing this, either. On the Mac it comes with some more advanced filters, but I think you'd probably see a lot more stuff like this if the iPhone filters could do it :-)
OpenGL does have quite a learning curve, but here's what you'd want to do to achieve the effect: Create a flat rectangle in OpenGL with several verticies along it's length. Point the camera at the rectangle so that it appears flat. Then, use a sine() function of some sort to animate the verticies back and forth in place.
This approach is also used to achieve the rippling-water effect, and you might be able find an example or two of it.
Sorry to bring bad news :-) Hope that helps!

Need help optimizing my 2d drawing on iPhone

I'm writing a game that displays 56 hexagon pieces filling the screen in the shape of a board. I'm currently drawing each piece using a singleton rendering class that when called to draw a piece, creates a path from 6 points based of the coordinate passed in. This path is filled with a solid color and then a 59x59 png with an alpha to white gradient is overlayed over the drawing to give the piece a shiny look. Note I'm currently doing this in Core Graphics.
My first thought is that creating a path everytime I draw is costly and seems like I can somehow do this once and then reuse it, but I'm not sure of the best approach for this. When I look at the bottlenecks with Shark, it looks like the drawing of the png is the most taxing part of the process. I've tried just rendering the png overlay or just rendering the path without the overlay and both give me some frame gains, although removing the png overlay yields the most frames.
My current thought is that at startup, I should render 6 paths (1 for each color piece I have) and overlay them with the png and then store an image of these pieces and then just redraw the pieces each time I need them. Is there an effecient machanism for storing something you've drawn once and redrawing it? It kinda just sounds like I'd be running into the whole drawing pngs too often thing again, but maybe there's a less taxing method that does a similar thing...
Any suggestions are much appreciated.
Thanks!
You might try CGLayer or CALayer.
General thoughts:
Game programming on iPhone usually necessitates OpenGL. Core Graphics is a bit easier to work with, but OpenGL is optimized for speed.
Prerender this "shiny look" into the textures as much as is possible (as in: do it in Photoshop before you even insert them into your project). Alpha blending is hell on performance.
Maybe try PVRTC (also this tutorial) as it's a format used by iPhone's GPU's manufacturer. Then again, this could make things worse depending on where your bottleneck is.
If you really need speed you have to go the OpenGL route. Be careful if you want to mix OpenGL and Core Animation, they can conflict.
OpenGL is a pain if you haven't done much with it. It sounds like you could use Core Animation and make each tile a layer. CA doesn't call the redraw again unless you change something, so you should be able to just move that layer around without taking a big hit. Also note that CA stores the layer in the texture memory so it should be much faster.
Some others have mentioned that you should use OpenGL. Here's a nice introduction specifically for the iPhone: OpenGL ES from the Ground Up: Table of Contents
You might also want to look at cocos2d. It seems to be significantly faster than using CoreAnimation in my tests, and provides lots of useful stuff for games.

What's the best way to create a "magnifying glass" on a 2D scene?

I'm working on a game where I need to let the player look at a plane (e.g., a wall) through a lens (e.g., a magnifying glass). The game is to run on the iPhone, so my choices are Core Animation or OpenGL ES.
My first idea (that I have not yet tried) is to do this using Core Animation.
Create the wall and objects on it using CALayers.
Use CALayer's renderInContext: method to create an image of the wall as a background layer.
Crop the image to the lens shape, scale it up, then draw it over the background.
Draw the lens frame and "shiny glass" layer on top of all that.
Notes:
I am a lot more familiar with Core Animation than OpenGL, so maybe there is a much better way to do this with OpenGL. (Please tell me!)
If I am using CALayers that are not attached to a view, do I have to manage all animations myself? Or is there a straightforward way to run them manually?
3D perspective is not important; I'm just magnifying a flat wall.
I'm concerned that doing all of the above will be too slow for smooth animation.
Before I commit a lot of code to writing this, my question is do you see any pitfalls in the plan above or can you recommend an easier way to do this?
I have implemented a magnifying glass on the iPhone using a UIView. CA was way too slow.
You can draw a CGImage into a UIView using it's drawRect method. Here's the steps in my drawRect:
get the current context
create a path for clipping the view (circle)
scale the current transformation matrix (CTM)
move the current transformation matrix
draw the CGimage
You can have the CGImage prerendered, then it's in the graphics memory.
If you want something dynamic, draw it from scratch instead of drawing a CGImage.
Very fast, looks great.
That is how I'd do it, it sounds like a good plan.
Whether you choose OGL or CA the basic principle is the same so I would stick with what you're more comfortable with.
Identify the region you wish to magnify
Render this region to a separate surface
Render any border/overlay onto of the surface
Render your surface enlarged onto the main scene, clipping appropriately.
In terms of performance you will have to try it and see (just make sure you test on actual hardware, because the simulator is far faster than the hardware). If it IS to slow then you can look at doing steps 2/3 less frequently, e.g every 2-3 frames. This will give some magnification lag but it may be perfectly acceptable.
I suspect that performance between OGL / CA will be roughly equivalent. CA is built ontop of the OGL libraries but your cost is going to be doing the actual rendering, not the time spent in the layers.