A kind reader updated my Objective-C export script for Blender to work with the 2.5 beta 6 version of Blender. You can find the new version on GitHub.
On a related note, if you make a change to your clone of any of my public repositories on Github, you can send me a pull request. I'm happy to take additions, bug fixes, and other updates back into the master repository.
Thanks to John Becker for updating the script!
Tuesday, February 22, 2011
Apple Outsider on the Subscription "Hubbub"
I have a very short list of "must-read" blogs. While I have a much bigger list of blogs I read as time permits, the list of ones that I check every morning before I buckle down to work consists of only about a half-dozen blogs by people in our industry who really know their stuff. One of those blogs is Apple Outside, written by former Apple Evangelist, Cocoa Guru, and all-around nice guy Matt Drance (not to be confused with the more intimidating BatDrance who is most definitely not Matt's alter-ego).
I've been keeping my head low on the whole subscription kerfuffle that's been happening in the iOS dev world. Partially that's just because I'm busy and don't have time to pen a long blog-rant, but it's also because it's a complex situation on which I don't have a fully-formed opinion yet. Matt's even-handed take on the situation does a great job of articulating the situation and is well worth reading.
I've been keeping my head low on the whole subscription kerfuffle that's been happening in the iOS dev world. Partially that's just because I'm busy and don't have time to pen a long blog-rant, but it's also because it's a complex situation on which I don't have a fully-formed opinion yet. Matt's even-handed take on the situation does a great job of articulating the situation and is well worth reading.
Tuesday, February 15, 2011
A Couple CGAffineTransform Goodies
Thanks to Core Animation, we iOS programmers tend to use affine transformations (by way of CGAffineTransform) a lot. By being able to combine multiple 2D transformations into a single matrix, we have the ability to do a lot of cool animation effects with only a few lines of code.
Take the following example, which is fairly typical:
Not bad, right? In just three lines of code, we're able to both scale and translate a view or layer. But in reality, there's actually quite a few operations going on behind these three lines of code. The CGAffineTransformScale() function calls CGAffineTransformConcat() to perform a matrix multiplication operation between two affine matrices. But, as you probably know, you can't multiply a 2x3 matrix by another 2x3 matrix. To multiply affine transformations, they have to be converted back to 3x3 vector matrices first.
On today's devices (even mobile devices), this all takes a trivial amount of processing power. But sometimes, when you're doing a lot of these transformations — say thousand or tens of thousands a second — it can be valuable to be able to avoid that conversion and matrix multiplication.
It just so happens that with certain commonly used CGAffineTransforms, you can cheat. Certain matrices can be joined together without performing matrix multiplication. For example, here are the matrices created by CGAffineTransformMakeScale() and CGAffineTransformMakeTranslation(), respectively:

Go ahead and multiply those two together. Plug in any number for tx, ty, sx, and sy and run the numbers. I'll wait. Okay, you don't have to. This is what you'll get:

So, if that's the result we're going to get, why bother going through the matrix multiplication in the first place? Why not just populate the matrix with both the scale and translate values right from the get-go? Well, we can. We can also do the same thing with translate and rotate.
This is all there is to it:
That's it. It only saves you two lines of code:
But, your stack allocation is considerably smaller (one CGAffineTransform instead of two CGAffineTransforms and an intermediate 3x3 array. It also saves you eighteen floating point multiplications and nine floating point additions. 99.9% of the time, that number of operations is going to have no noticeable affect on your application - it's a trivial amount of both memory and FLOPS under most normal situations.
But… if you're doing a lot per second, they can add up and it's nice to know there's a way that you can save yourself a little overhead in some situations.
Take the following example, which is fairly typical:
CGAffineTransform transform = CGAffineTransformMakeTranslation(0, -translation);
transform = CGAffineTransformScale(transform, scaleFactor, scaleFactor);
view.transform = transform;Not bad, right? In just three lines of code, we're able to both scale and translate a view or layer. But in reality, there's actually quite a few operations going on behind these three lines of code. The CGAffineTransformScale() function calls CGAffineTransformConcat() to perform a matrix multiplication operation between two affine matrices. But, as you probably know, you can't multiply a 2x3 matrix by another 2x3 matrix. To multiply affine transformations, they have to be converted back to 3x3 vector matrices first.
On today's devices (even mobile devices), this all takes a trivial amount of processing power. But sometimes, when you're doing a lot of these transformations — say thousand or tens of thousands a second — it can be valuable to be able to avoid that conversion and matrix multiplication.
It just so happens that with certain commonly used CGAffineTransforms, you can cheat. Certain matrices can be joined together without performing matrix multiplication. For example, here are the matrices created by CGAffineTransformMakeScale() and CGAffineTransformMakeTranslation(), respectively:

Go ahead and multiply those two together. Plug in any number for tx, ty, sx, and sy and run the numbers. I'll wait. Okay, you don't have to. This is what you'll get:

So, if that's the result we're going to get, why bother going through the matrix multiplication in the first place? Why not just populate the matrix with both the scale and translate values right from the get-go? Well, we can. We can also do the same thing with translate and rotate.
This is all there is to it:
static inline CGAffineTransform CGAffineTransformMakeRotateTranslate(CGFloat angle, CGFloat dx, CGFloat dy)
{
return CGAffineTransformMake(cosf(angle), sinf(angle), -sinf(angle), cosf(angle), dx, dy);
}
static inline CGAffineTransform CGAffineTransformMakeScaleTranslate(CGFloat sx, CGFloat sy, CGFloat dx, CGFloat dy)
{
return CGAffineTransformMake(sx, 0.f, 0.f, sy, dx, dy);
}That's it. It only saves you two lines of code:
view.transform = CGAffineTransformMakeScaleTranslate(scaleFactor, scaleFactor, 0, -translation);But, your stack allocation is considerably smaller (one CGAffineTransform instead of two CGAffineTransforms and an intermediate 3x3 array. It also saves you eighteen floating point multiplications and nine floating point additions. 99.9% of the time, that number of operations is going to have no noticeable affect on your application - it's a trivial amount of both memory and FLOPS under most normal situations.
But… if you're doing a lot per second, they can add up and it's nice to know there's a way that you can save yourself a little overhead in some situations.
Sunday, February 13, 2011
Xcode 4 Icons
Well, now that Xcode 4 is GM, it has the same icon as Xcode 3.25. Ordinarily, this wouldn't be an issue, since a GM release means you can throw out the old one and use it full-time.
Only, you may not be able to with all of your projects. Xcode 4 GM has a few issues that make it hard to go full-time with it, including a linker error that can only be worked around by turning some level of code optimization, a change that makes it hard to debug. A few of these problems impact projects I'm working on, so as a result, I have to grudgingly use Xcode 3.25 for some tasks.
Despite a small handful of problems, though, Xcode 4 is where I want to be whenever possible. Having multiple identical icons in your Dock can be a bit of a pain.
Unfortunately, I didn't save the old Xcode 4 installers. If I had, I would have just gone and stolen the old preview icon and continued using that. Since I didn't, I did the same thing I did for beta iOS releases and made a customized version of the app icon for Xcode 4. If you want to use it, you can download it here. To install, you just copy the .icns file into Xcode 4's app bundle, replacing the existing one. And, no, replacing the icon file with a new one doesn't cause problems with Xcode 4 due to code signing, though I feared it might.
This is what it looks like:
Only, you may not be able to with all of your projects. Xcode 4 GM has a few issues that make it hard to go full-time with it, including a linker error that can only be worked around by turning some level of code optimization, a change that makes it hard to debug. A few of these problems impact projects I'm working on, so as a result, I have to grudgingly use Xcode 3.25 for some tasks.
Despite a small handful of problems, though, Xcode 4 is where I want to be whenever possible. Having multiple identical icons in your Dock can be a bit of a pain.
Unfortunately, I didn't save the old Xcode 4 installers. If I had, I would have just gone and stolen the old preview icon and continued using that. Since I didn't, I did the same thing I did for beta iOS releases and made a customized version of the app icon for Xcode 4. If you want to use it, you can download it here. To install, you just copy the .icns file into Xcode 4's app bundle, replacing the existing one. And, no, replacing the icon file with a new one doesn't cause problems with Xcode 4 due to code signing, though I feared it might.
This is what it looks like:
Tuesday, February 8, 2011
MC3D - Platform Agnostic 3D Foundation
Sorry for the lack of posts recently. Things have been, well… you know. Same old story. Super busy. Which is good, but it's murder on blog post frequency.
I've recently had to port some OpenGL ES work I did from iOS to Android. It used to be that doing so would have been insanely painful (as opposed to just painful). I would have had to convert the Objective-C code to Java, and then maintain completely distinct sets of code that do the same exact thing. Fortunately, the Android NDK (Native Development Kit) allows you to write code for Android in C/C++. The version of the NDK supported on 2.2 still requires part of the Activity (Android's counterpart to an iOS view controller) to be written in Java, but does allow you to call C/C++ code using JNI. In 2.3 and 3.0, you can do entire activities in C or C++.
This is a huge step forward for Android for those of us who do performance-critical work on multiple platforms, but it's not without some pain. Debugging across the JNI bridge is… less than easy. But, being able to share code across platforms is a huge win, and being able to get native speeds in the process is teh awseome.
During these projects, I've been taking a lot of my 3D-related code and creating a new set of platform-agnostic C functions and types. I've been cleaning up and making names consistent, and placing appropriate pre-compiler macros to make sure the code compiles correctly everywhere. On iOS, the library will take advantage of the Accelerate Framework in places, but doesn't require Accelerate to function.
I've chosen C because I don't like mixing C++ and Objective-C. The object models are too different for my tastes. But I've also made sure to include proper ifdef'd extern statements so that you can import the MC3D header files from C++ without hassle.
I've dubbed this set of functions MC3D, and I'm making it open source under a simplified version of the simplified BSD license (simplified simplified BSD license?). I've taken out the attribution requirement, so the only requirement is that if you re-distribute the source code, you have to leave the copyright and license text intact. That's it. Otherwise, you can use it for free in any project, commercial or otherwise, without paying anything, without attributing, and without asking (no really, you don't need to ask).
MC3D is still very much a work in progress, and I'm only adding code to the repository that I feel is ready for public consumption. Much of what's in MC3D has been posted here before, sometimes with different names or in slightly different form.
I have other code that I plan to add in the future, including higher-level functionality like model loading, scene management, and skeletal animation, but I won't add anything until its both solid and platform agnostic.
Currently, documentation is very sparse, and I currently can't offer any support or help with using it, so caveat emptor! I will gladly accept contributions, bug fixes, and new functionality back into the MC3D codeline.
MC3D on GitHub.
Link fixed, sorry about that
I've recently had to port some OpenGL ES work I did from iOS to Android. It used to be that doing so would have been insanely painful (as opposed to just painful). I would have had to convert the Objective-C code to Java, and then maintain completely distinct sets of code that do the same exact thing. Fortunately, the Android NDK (Native Development Kit) allows you to write code for Android in C/C++. The version of the NDK supported on 2.2 still requires part of the Activity (Android's counterpart to an iOS view controller) to be written in Java, but does allow you to call C/C++ code using JNI. In 2.3 and 3.0, you can do entire activities in C or C++.
This is a huge step forward for Android for those of us who do performance-critical work on multiple platforms, but it's not without some pain. Debugging across the JNI bridge is… less than easy. But, being able to share code across platforms is a huge win, and being able to get native speeds in the process is teh awseome.
During these projects, I've been taking a lot of my 3D-related code and creating a new set of platform-agnostic C functions and types. I've been cleaning up and making names consistent, and placing appropriate pre-compiler macros to make sure the code compiles correctly everywhere. On iOS, the library will take advantage of the Accelerate Framework in places, but doesn't require Accelerate to function.
I've chosen C because I don't like mixing C++ and Objective-C. The object models are too different for my tastes. But I've also made sure to include proper ifdef'd extern statements so that you can import the MC3D header files from C++ without hassle.
I've dubbed this set of functions MC3D, and I'm making it open source under a simplified version of the simplified BSD license (simplified simplified BSD license?). I've taken out the attribution requirement, so the only requirement is that if you re-distribute the source code, you have to leave the copyright and license text intact. That's it. Otherwise, you can use it for free in any project, commercial or otherwise, without paying anything, without attributing, and without asking (no really, you don't need to ask).
MC3D is still very much a work in progress, and I'm only adding code to the repository that I feel is ready for public consumption. Much of what's in MC3D has been posted here before, sometimes with different names or in slightly different form.
I have other code that I plan to add in the future, including higher-level functionality like model loading, scene management, and skeletal animation, but I won't add anything until its both solid and platform agnostic.
Currently, documentation is very sparse, and I currently can't offer any support or help with using it, so caveat emptor! I will gladly accept contributions, bug fixes, and new functionality back into the MC3D codeline.
MC3D on GitHub.
Link fixed, sorry about that
Thursday, January 27, 2011
Complete Friday Q&A
Mike Ash just announced the availability of his Complete Friday Q&A book. Mike's weekly blog posting is a must read for any Cocoa developer. Mike's knowledge of the language and system internals is amazing, and having all his weekly posts available in one place formatted like a book is a great resource. Go check it out on iTunes or Amazon.
Garage Games
I noticed that Garage Games, the makers of the Torque game engine have recently had a near-death experience. As of the end of last year, it looked like they were shutting down operations. However, they appear to be in the midst of a phoenix-like return to life with, perhaps, some changes in focus and priority. The bad news for iOS folks, is that they've removed the mobile version of their 3D engine from their product list. I don't know if this means it's abandoned, or that they're just not ready to announce/release it. They are actively hiring developers and designers, and from the job descriptions they've posted, it sounds to me like they've got their sights set firmly on mobile.
To celebrate their revival, they're having a sale on all their products - you can get any of their engines, including a full source license for $99.
Now, I honestly don't know how Torque compares to, say, Unity, Sio2, or the UDK in terms of features or ease of development, but there have been a lot of very solid games created with Torque over the years and the demos show the engine is versatile and fairly powerful.
What I do know that $99 is a hell of a price for a source license to a game engine of this size and complexity. For me, it's worth that much money to get to peek around their code. There's a lot to be learned from looking at other people's code.
No word on how long the sale is for, but you can check it out here.
Note: I had an e-mail conversation with Garage Games' community manager about iTorque 3D. Unfortunately, right now the official word is that the product is off their roadmap. They have no announced plans to release it, so if you're targeting the iPhone or mobile devices in general, you're out of luck for now and should probably look at another engine.
That being said, they didn't rule out the possibility of re-introducing iTorque 3D at some future point. Frankly, if you're interested in writing games, I still think it's well worth dropping $99 for a license to be able to see the choices they've made in designing their engine as well as how they've implemented them. It's a pretty good example of a complex cross-platform project.
I have to say, I like the new public face of Garage Games. Their responses to my questions were prompt and candid. I think the new management knows exactly what they want to do and I'm looking forward to seeing where they take things.
To celebrate their revival, they're having a sale on all their products - you can get any of their engines, including a full source license for $99.
Now, I honestly don't know how Torque compares to, say, Unity, Sio2, or the UDK in terms of features or ease of development, but there have been a lot of very solid games created with Torque over the years and the demos show the engine is versatile and fairly powerful.
What I do know that $99 is a hell of a price for a source license to a game engine of this size and complexity. For me, it's worth that much money to get to peek around their code. There's a lot to be learned from looking at other people's code.
No word on how long the sale is for, but you can check it out here.
Note: I had an e-mail conversation with Garage Games' community manager about iTorque 3D. Unfortunately, right now the official word is that the product is off their roadmap. They have no announced plans to release it, so if you're targeting the iPhone or mobile devices in general, you're out of luck for now and should probably look at another engine.
That being said, they didn't rule out the possibility of re-introducing iTorque 3D at some future point. Frankly, if you're interested in writing games, I still think it's well worth dropping $99 for a license to be able to see the choices they've made in designing their engine as well as how they've implemented them. It's a pretty good example of a complex cross-platform project.
I have to say, I like the new public face of Garage Games. Their responses to my questions were prompt and candid. I think the new management knows exactly what they want to do and I'm looking forward to seeing where they take things.
Subscribe to:
Posts (Atom)