Recently I needed to write some code that would allow me to interactively rotate a camera around a Papervision3D sphere in a Flex app. My first idea was convert the (x,y,z) location of the camera to a spherical coordinate — that is (rho, phi, theta). To actually move the camera around the center of the sphere, I could just change the phi and theta angles, re-convert the spherical coordinate to a cartesian coordinate, and use this cartesian coordinate as the camera’s new position.
I messed around with approach this some, and was getting close to having it work, but then I ran across a post on the Papervision3D forums which greatly simplifies the whole operation by taking advantage of a few built-in methods to the FreeCamera3D class (here is a link to the original post):
1. Determine yAngle, the angle by which you want to rotate the camera up
2. Determine xAngle, the angle by which you want to rotate the camera right
3. Determine cameraDistance, the distance the camera is from the center of the sphere
4. Move the camera to the center of the sphere using the moveForward function: camera.moveForward(cameraDistance)
5. Tilt the camera up: camera.tilt(yAngle)
6. Pan the camera right: camera.pan(xAngle)
7. Move the camera back using the moveBackward function:
camera.moveBackward(cameraDistance)
These operations should successfully position the camera wherever you want around the outside of the sphere, and it has the benefit of being super simple.
One note: I could only get this to work with the FreeCamera3D class, not the Camera3D class.
Categorized in flex and papervision3D
In my overzealous attempt to learn Ruby on Rails and RESTful design while using Edge Rails, I have once again been bitten by a change that wasn’t obvious to me until I read the CHANGELOG. Feeling pretty macho, I decided to create some nested resources in my application. The code I added to config/routes.rb went like this:
map.resources :users do |users|
users.resources :projects
end
Then, when trying to create a new project for a user, I created a link that looked like this:
<%= link_to 'New project', new_project_path( @user ) %>
Of course, because nothing ever works on the first try (oh the pain I must endure), this gave me an error:
undefined method `new_project_path' ...
Once again, I commenced beating my head against the wall and crying out about the various injustices done to me in life: “But I’m doing it just like all of the tutorials say I should!” and “I thought that method would get generated for me!” After much drama, I decided to check the CHANGELOG again. Bingo:
* Added :name_prefix as standard for nested resources [DHH].
WARNING: May be backwards incompatible with your app
Before:
map.resources :emails do |emails|
emails.resources :comments, :name_prefix => "email_"
emails.resources :attachments, :name_prefix => "email_"
end
After:
map.resources :emails do |emails|
emails.resources :comments
emails.resources :attachments
end
This does mean that if you intended to have comments_url go to /emails/5/comments,
then you'll have to set :name_prefix to nil explicitly.
All this is to say, once I changed my code to the following, everything worked just fine:
<%= link_to 'New project', new_user_project_path( @user ) %>
And all was well with the world.
Categorized in Uncategorized
I’m a newbie to Ruby on Rails. Delirious and unphased, I decided to compound this precarious position by writing my first Rails web app using Edge rails instead of the standard 1.2.x build. Three things have confused me to this point, and I’m sure more are to come. If you’re using Edge Rails, here’s hoping I can save you a few moments of frustration:
- script/generate scaffold_resource model_name (the command given in the REST Peepcode to generate a scaffold for a RESTful resource), no longer works. Instead, do this: script/generate scaffold model_name.
- When I finally did get a RESTful scaffold going, the view files for the various controller actions were given file names such as “edit.html.erb” instead of “edit.rhtml” as I was expecting. This is because .rhtml has been deprecated in Rails 2.0 (I guess because, since edit.rhtml isn’t strictly HTML, it shouldn’t have a file name that makes it look like it is; I’m not sure I buy this, but that’s the way the Rails file extensions crumble, kids). As a side-note, “.rxml” files are also deprecated in favor of “.builder” files.
- Finally, in this new “edit.html.erb” view file, I noticed that the form_for declaration looks like this: <% form_for(@modelname) do |f| %>. I had never seen this form_for syntax documented anywhere, so I proceeded to rant and rave and beat my head against the wall for awhile before I searched my own project in Textmate, and noticed that the Edge Rails CHANGELOG contained this note:
* Added record identifications to FormHelper#form_for and PrototypeHelper#remote_form_for [DHH]. Examples:
<% form_for(@post) do |f| %>
…
<% end %>
This will expand to be the same as:
<% form_for :post, @post, :url => post_path(@post), :html => { :method => :put, :class => “edit_post”, :id => “edit_post_45″ } do |f| %>
…
<% end %>
Categorized in edge rails and ruby on rails
The ViewStack component in the Flex framework operates by setting the visibility on one of its children — the child with index specified by ViewStack.selectedIndex — to true, and the visibility of all the other children to false. It is not difficult to imagine a scenario where ViewStack.selectedIndex is bound to a variable that sometimes changes; as that variable changes, the ViewStack dutifully follows along, changing to match. Nice and easy, right? Right.
Careful, though. Something bit me the other day when I was using a setup like this. I needed a particular child Canvas of the ViewStack to become momentarily invisible so that I could do some animation on a canvas floating above it. No problem, I thought, I’ll just manually set that Canvas’s visibility to false. So I did, and was quite befuddled by the results: the Canvas’s visibility, when set to false, was immediately set back to true, making the animation on top of it look really wacky.
It took me awhile to realize that binding the ViewStack’s selectedIndex property was causing it to reset the visibility on the child in question back to true, without my wanting it to do so. Thus, the Canvas I wanted to disappear… well, it never did.
Solution? Set the visibility of the entire ViewStack to false, not just the one particular child in question. That did the trick. Ahhh, much better!
Categorized in ViewStack, debug and flex 2
Having problems with excessive memory usage in Flex 2 or Apollo? As long as an object in memory is still referenced, it won’t be deleted. Since there are so many references floating around, especially given binding and effects, it’s easy to think you’ve purged all references to an object when you actually haven’t. Thus, that something won’t get cleaned up.
I was recently working on a project for which the view rotated through a constant amount of data: as new data entered the screen, an equal amount of old data exited. Every time new data came into view and old data went out, I created a new DisplayObject to use as the new data’s visual representation. As for the exiting old data… well, I tried to remove all references to it. I watched, frustrated, as the memory usage climbed each time new data came into the view.
Then I tried this: re-using objects. Since I new there would only ever be 10 or less objects on screen, I created ten of those objects, reusing old instances whenever I needed to visually represent some new data. That did the trick — my memory usage dropped dramatically.
This may require a little finagling with your code, but it’s worth it when you watch your total memory usage drop. Give it a go, and let me know if it helps.
Categorized in debug, flex 2 and memory
If you’re using an Observer in Flex 2, but its handler doesn’t seem to be executing when you’d expect it to, make sure that the variable the Observer watches isn’t getting reset to the same value it already has. In this case, the Observer’s handler function won’t run.
Example: pretend that A and B are empty arrays. C is an array reference, currently null. D is an Observer, observing C. D’s handler does this: whenever C is set to an array, a random number is added to that array. Now pretend C is set from null to array A. The handler adds a random number to A, as expected. Now, C is set to array B. A random number is added to B. Now, and here’s the part to be careful about, assume C is again set to B — even that’s the same value it already has. Nothing happens! No random number will be added to B, and when we print out our arrays A and B at the end of the program, we’ll be a little confused why we see two instead of three values.
Dumb example? Yes. Obvious? Yes. Easy to get tripped up by and waste time on? Yes.
There you have it, kids.
Categorized in debug, flex 2 and observer
I hate those elusive bugs that cause me to spend an hour or more pulling out my hair, only to eventually realize that it was a simple typo all along. Here’s my hot tip for the day: if you’re expecting a setter function in Flex 2 to do something, but that something never happens, make sure you’re not accidentally using the == comparison operator where you intended to use the = assignment operator.
Let’s all say it together: UGH. Can I go to bed now?
Categorized in debug, flex 2 and setter