Flex form with a 3d twist

I just started experimenting with Papervision and wanted to try something I have not seen yet, integrating a Flex view into the 3d realm. There are plenty of samples of really neat looking cars, animals and shapes getting rotated every which way but nothing that shows how to blend something applicationish (is that word?) like a data entry form with 3d to give the user a new experience.

I created a simple component that gets bound to a ViewStack, generates the six sides of a cube and then renders the new cube form. Even though Papervision depends on Bitmaps and static snapshots of things to perform the rendering I was able work editable Flex UI's into the 3d by performing a bit of magic with the ViewStack and positioning.

 

 

I have to say, using Papervision to do this stuff is so nice. It only took a few hours to work out the kinks to get this working, and that included figuring out how to use Papervision in the first place. The team who created it deserves a ton of kudos. I'll release the source code soon, I just need to do some cleanup and commenting.

Papervision really opens up a whole new world of potential in Flash/Flex, not just for displaying things, but for how users can even interact with interfaces (even boring data entry forms). It will be exciting to see what people come up with, imagination is the only limit.

19 Comments:

  1. Dan Wilson

    What a sweet demo!

    The only way to make it sweeter would be to enable 'view source'.


    DW

  2. Mike

    Hi Derrick,
    Can you please tell us whats the difference from this and the one done by Alex Uhlmann from Adobe Consulting a long time ago.

    Post
    http://weblogs.macromedia.com/auhlmann/archives/effects/index.cfm

    Example:
    http://www.alex-uhlmann.de/flash/adobe/blog/distortionEffects/effectCube/

    And he gives us source code.
    Thanks,
    Mike

  3. Mike P

    Hi Derrick, Can you please tell us whats the difference from this and the one done by Alex Uhlmann from Adobe Consulting a long time ago:

    http://weblogs.macromedia.com/auhlmann/archives/effects/index.cfm

    http://www.alex-uhlmann.de/flash/adobe/blog/distortionEffects/effectCube/

  4. Derrick

    The difference is that my version is using Papervision for the 3d rendering, which means I'm not relying on any Flash/Flex effects, transitions etc to get the 3d effect. The actual 'cube' and 'forms' are completely seperate. The cube is only for the visual, while the 'forms' are hidden until the cube hits a stop point, and then the proper 'form' gets displayed over the cube. The only work I had to do was to create a component to convert a view stack into a Papervision cube, and manage the logic of when to display the correct view from the viewstack. The Papervision engine takes care of all the rotating, turning, rendering etc, with absolutely no work on my part.



    Alex's samples are pretty neat, I'd never seen them before, thanks for sharing the link.

  5. C

    Mike, I think the difference here is that by the looks of it Alex's example was built using distortion tricks, whereas Derrick's is built as a true 3d object in Papervision. For instance, the transition between pages 4 and 5 in Derrick's model can't really be done effectively with the distortion methods used in Alex's example.

  6. Daniel Wabyick

    This is a *very* cool example of applying real content to the 3D API's. I would love to see the source for this.

  7. Derrick

    Source code for the 3d flex form. Enjoy.

  8. Tink

    This stuff might be of interest to anyone looking at this.

    http://www.tink.ws/blog/papervision3d-effects-for-flex-source/
    http://www.lfpug.com/pv3d-effects-for-flex/

  9. Todd

    This is pretty awesome, in particular that there's an actual 3D rendering rather than a faux 3D finish like Uhlmann's distortion effects--which are also awesome.

    I have a bit of a problem though. With Uhlmann's distortion effects I couldn't figure out how to get the examples up and running, but managed to get a mock-up running on my main app. It's got some funny business going on (like showing other indexes through the selectedIndex--like layers) and I don't quite follow how you're supposed to use it because I can't do anything with the examples.

    On the other hand, in the process of trying to figure that problem out, I stumbled across this and two things caught my attention 1) "I have to say, using Papervision to do this stuff is so nice. It only took a few hours to work out the kinks to get this working, and that included figuring out how to use Papervision in the first place...."
    and 2) "... Alex's example was built using distortion tricks, whereas Derrick's is built as a true 3d object in Papervision."

    Sure enough it took me about an hour to find/figure out what I needed to download & figure out where it needed to go/how to "wire it up." And by about 2:30 am I had Derrick's cubeForm example to "trueForm" and I was playing with the rotation parameters to see how to control the cube's motion. (I hit a few problems like putting createPlane(... 90,90,90) & destRotation( ..., 270,270,270) on an index would cause the flip to perform to about 95%--and then freeze, but that's another bridge that I don't need to worry about right now.)

    When I was satisfied that understood how to control the cube, I decided to attempt to implement it in my current project. I opened my main file, deleted the distortion effects cube component, created another component file based on mx:Canvas, copied and pasted Derrick's main.mxml file, removed the Application tags, added the xmlns @, copied the "com.dgrigg.containers.CubeForm.as, org.papervision3d.flex.Canvas3d.as, " folder/file structures into the project, added the src file to the build path--and got rid of all the errors.--AWESOME, it's 3:15 I'm chuggin along... time for the acid test.

    I launch my app. sure enough the ?cube? is there--at least the "start" mx:Panel is. But when I clicked the button to see the magic--I got:

    "TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at Components::TestCube/___Button1_click():"

    instead. It seems like it's refusing to accept the "views" viewstack and assemble the array. Flex gives me the viewStack & viewStack.selectedIndex options with the autocomplete, but at compile time it says that it can't access them.

    What really gets me is that (as far as I know) I didn't change ANY of THAT stuff. I just wanted the identical cube running, with my app in the background????

    Sorry if it seems like a round-a-bout way of asking for help, but I wanted to try and give as much detail as I thought could be relevant.

    Cheers from Flatland,
    Todd

    (PS to reader, You may find this same post in a couple of places since the last post was a month ago and almost a year ago before that.)

  10. Derrick

    Hey Todd,

    I think the problem may be that the viewstack you are using does not have the creationPolicy set to all. Make sure you have that set, otherwise the CubeForm instance will not be able to grab all six views to create the cube properly.

    Hope that helps.

    Derrick

  11. Todd

    Wow, I didn't think anyone would reply--let lone the man himself!

    Unfortunately that attribute is already in in the ViewStack tag. Here's the first part of the file:


    pageTitle="PaperVision3D Flex Example" frameRate="60" >


    import Components.com.dgrigg.containers.CubeForm;

    [Bindable] private var cubeForm:CubeForm;

    private function init():void
    {
    cubeForm = new CubeForm(paperCanvas.canvas);
    cubeForm.viewStack = this.views;
    }

    ]]>









    This is a sample 3D Flex Form using PaperVision3D. Use the 'prev' and 'next' buttons to work through the form. Don't worry, none of the information in the form is saved anywhere.


    ]]>








    ...

    I did add the "Components" folder to the beginning of the import statement (and changed it in the package file) to reflect its current location & here I've changed the click action to try and derive SOME additional information , but other than that and the "header material" (changing mx:Application to mx:Canvas) it was a straight cut & paste.

    The Panel in the code above renders, but the click action returns:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at Components::TestCube/__b1_click()

    I'm not completely sure that I have the file/import structure right, but I don't get any compile errors as it is.

    Thanks again! I really appreciate any help you can offer. Otherwise I'm just scanning the code hoping I can find any name mismatches or anything else that's obvious.

    Todd

  12. Todd

    I had to remove all the opening < 's so that the contents wouldn't get stripped out.

    "mx:Canvas xmlns:mx="http://www.adobe.com/2006/mxml" width="550" height="550" xmlns:flex="org.papervision3d.flex.*"
    pageTitle="PaperVision3D Flex Example" frameRate="60" >

    mx:Script>
    ![CDATA[
    import Components.com.dgrigg.containers.CubeForm;

    [Bindable] private var cubeForm:CubeForm;

    private function init():void
    {
    cubeForm = new CubeForm(paperCanvas.canvas);
    cubeForm.viewStack = this.views;
    }

    ]]>
    /mx:Script>

    Canvas3D canvas property should be used as the container for the scene

    flex:Canvas3D id="paperCanvas" backgroundColor="#000000" backgroundAlpha="1" width="550" height="550"/>

    mx:ViewStack id="views" creationPolicy="all" width="550" height="550" >
    mx:Panel id="panel1" title="Start" width="550" height="550" layout="absolute">
    mx:Form x="0" y="0">
    mx:TextArea id="TA" width="240" height="120" borderStyle="none" selectable="false">
    mx:htmlText>![CDATA[
    p>This is a sample 3D Flex Form using PaperVision3D. Use the 'prev' and 'next' buttons to work through the form. Don't worry, none of the information in the form is saved anywhere./p>
    ]]>
    /mx:htmlText>
    /mx:TextArea>

    mx:Button id="b1" label="Next" click="this.b1.label = cubeForm.selectedIndex.toString();"/>
    /mx:Form>
    /mx:Panel>

    mx:Panel id="panel2"
    "

  13. Todd

    Well I've got it narrowed down to line 113 of CubeForm.as:

    109 private function init():void
    110 {
    111
    112 var s:Stage = sprite.stage;
    113 s.quality = StageQuality.BEST;
    114 setupScene();
    115 }

    The debugger throws the error on 113 saying:

    TypeError: Error #1009: Cannot access a property or method of a null object reference.
    at Components.com.dgrigg.containers::CubeForm/Components.com.dgrigg.containers:CubeForm::init()[
    ...

    The import for flash.display.StageQuality is there, so it's not that it's not importing the Class.

    If I comment 113 out, the application works, but the cube face has the panel--in an inert form (you can't click the button) and Flex renders the viewStack panel about 60% of the width to the right & 40% of the height down. On the "offset" panel the button works and it flips to all sides--all of which are distorted in the same way.

    Thanks again
    Todd

  14. Derrick

    Hey Todd,

    Have you tried to trace out the 'sprite' object on line 112 of your code to make sure it has a reference to some object. That would be a huge issue, and based on the error you are getting it sort of sounds like that could be the case. Not sure why all the stuff is skewed, but again, if the sprite is null that would likely cause display issues also.

    Derrick

  15. Todd

    I stepped the debugger through the app about 10 times last night which is how I found the problem on line 113. I have to admit the level that most of this is happening on is over my head. I know that a sprite is a graphic object and a stage is a "stage" but that's about it when it comes to the UIComponent class stuff. So, I just commented it out and fiddled with the Panel, ViewStack, & Canvas3D dimensions until I hit the right combination & it looked right.

    I feel like it's fundamentally broken but I don't know why. I just took your creature and put it in my pin to see how it would play. The only point I had made up to that point was to change the collars (swap mx:Application for mx:Canvas in the root tag of main.mxml).

    Once I had it "working" I just kinda ran with it. I've been working on this app for about 2 months now & I personally am up to I'd guess 5-7000 lines of mxml & as3 code between the components involved, 8 PHP scripts, & 18 Db tables and I still have to figure out how to support *EVERY* language. So after 6 hours of tinkering I was ready to get back to the original task.

    I looked at what you have on your portfolio page--pretty nice!! The FedExStories app-- F'n sweet!

    What's REALLY crazy is how incredibly similar it is to the app I've been working on. In fact, about the same day I found your cubeForm example I had been trying to think up a way to render a 3D globe for almost the same exact purpose.

    I did see a sphere in one of the papervision folders and I saw an tutorial which stretched a picture around a cone and was thinking...yeah, I bet I can use this to pull it off!!! I have a feeling that I'll have to figure out that sprite thing by then. Who knows? I'll cross that bridge when I get there.

    Do you happen to know any open source/free resources for translation like a webservice to ping text to which returns it translated?

    Thanks Derrick!
    /*!@*/ Awesome work /*!@*/

  16. Todd

    I hate to feel bothersome, but I WAS content to leave well enough alone until I read your blog on learning Flex fast. Three months ago I'd never even heard of Flex & had just gotten "Flash 8 Actionscript--Training from the Source" when I was introduced to a guy who's my buddy now. He was looking for someone who could work with php & actionscript to help him do a project he'd been trying to bring to fruition for three years. When we met he asked me if I'd ever heard of Flex. I thought it might be some rinky dink open source stuff (not to knock open source in the slightest). Anyway, I then found out what Flex was & that there was AS3--so my "new" book was obsolete before I opened it. I was pleasantly surprised, then I found Flex.org's showcase--and I was sold (particularly taggraph.com).

    The initial learning curve was horrible, I was used to loosely typed & more forgiving languages. The first month was just shear irritation. I bought & worked through "Flex 2 with Actionscript 3.0" (Brown) in a week, the "Flex Solutions" (Casario) & "Adobe Flex 2--Training from the source" (both very nice) & I bought the Documentation set from Adobe (I have to have a real book to write in, underline, & flag).

    I'm at what I think of as a "learning plateau" right now. I'm pretty competent--less than graceful, but ?considerably capable? However, I know that there's still all the stuff "behind the scenes," the overrides, UIComponents, FDS (LCDS now), and a whole mish-mosh of other things that if I even begin to tinker with will set off errors-a-plenty (which I won't know how to deal with/what to look for as is the case with my present "error set"). Anyway, now that I feel like you'll think that I've turned YOUR blog into MY blog... After I read your article/blog on learning Flex fast, it won't stop eating at me that the component isn't "right." Especially since I've decided that I'm definitely going to figure out how to bust-out a rotating globe like the one on the FedEx site--SO AWESOME!

    so...

    I debugged a little more & you're right. The "var s:Stage = sprite.stage; " does result in s=null, but I don't get it because in the function before:

    104 public function CubeForm(canvas:Sprite)
    105 {
    106 sprite = canvas;
    107 init();
    108 }

    I get sprite = flash.display.Sprite(@1be80661) & sprite.stage = null (before this function both are null). I tried adding a "this." in front(--cause I really don't know what I'm doing)

    109
    110 private function init():void
    111 {
    112 var s:Stage = this.sprite.stage;
    113 s.quality = StageQuality.BEST;
    114 setupScene();
    115 }

    But still s=null & 113 throws an error attempting to assign to a null object. The src I added to my build path is PV 1.5 (cuz that's what I found to download). I've seen v2.0 mentioned on a forum. Do I have the wrong version? Would that even matter??? (Doesn't seem like it would).

    Anyway, your post inspired me to walk into the fray (the next major learning curve) rather than maintain a status quo.

    Any help is sincerely appreciated.
    Todd

  17. Mayur

    I have downloaded the source code and tried to run on Flex 3, its giving me compile time syntax error . Is this code is not compatible for Flex 3?


    Mayur

  18. Derrick

    Hey Mayur,

    The code was written for Flex 2 and I have not had a chance to test it in Flex 3. Sorry.

    Derrick

  19. cauce

    This code doesn't compile in PV3D 2.0 (GreatWhite). I have tried to make something easier in GreatWhite (a simple form in a plane), and it runs but whitout interactivity with the form. Has someone tried this at PV3D 2.0 making the form interactive?


Leave a comment

Name: (required)

Email: (required)

URL:

Captcha test: (required)
Comments: (required)