Jump to content


  • Posts

  • Joined

  • Last visited

About UbiAssassin

Contact Methods

Profile Information

  • Gender
  • Location
    Montréal, Quebec
  • Interests
    Running, Hiking, Snowboarding, Soccer, Caving, Skydiving, Level Design, Web Design, Games, and outdoor activities.

Recent Profile Visitors

4,182 profile views

UbiAssassin's Achievements

  • Week One Done
  • One Month Later
  • One Year In

Recent Badges



  1. @Carl That is exactly the video that I stumbled across and it was an eye opener. The first thing that I thought of was all of the duplicated animation calls in heavy switch case usages to manipulate the 3D models, materials and matching 2D shapes. I was able to just nest it all into 4 RegisterEffect functions like this one: gsap.registerEffect({ name: "FlashPlateTweenEngine", effect: (targets, config) => { let tlFlashPlateTweenControl = gsap.timeline(); tlFlashPlateTweenControl.set(targets, { x: config.x, y: config.y }) .to(targets, .25, { autoAlpha: 1 }) .to(targets, .75, { autoAlpha: 0, ease: flashPlateBlendOutEase }); return tlFlashPlateTweenControl; }, extendTimeline: true }); From there, I was able to collapse all of the previous code into a number of simpler GridPlate Functions using a single master timeLine to control the entire animation. I used the .addLabel and .add statements to time the insertion and flow of each set of the 26 overall object animation calls and it is so much easier to tweak now!!! I am sure that I can leverage this even more, and I it will be incredibly easy to tack on more animation complexity and detail now that the base is more efficient and straightforward Great stuff!!!
  2. Hello everyone :) I have been way to busy over the last year to really put much effort into my ongoing website project due to my work. I hopped on since I started my holiday vacation, got the latest Club Greensock files (GSAP 3) and I have to thank you for gsap.effects and the smooth nature of how they can be injected into Timeline structures!!! I had started animation grid of material and 3D model fades, scale and transition animations along with some basic photoShop graphic elements that fade, flicker and transition with the models and their materials a little over a year ago. Needless to say, I was structuring test code that was heavy and included a lot of switch cases and duplicated code within each switch case. It was working, but quite heavy and messy. Not to mention the fact that it was hard to iterate on O.o After a day of looking into Gsap.Effects, I managed to redefine all of the animations for the models, model materials, and photoshop graphic elements in two RegisterEffect Functions. I then just nested these into a master timeLine as I saw fit and "BOOM" many, many, many lines of code , switches and switch cases removed! It is easy and quick to iterate on and my code is far easier to navigate! @Carl All I can say and holy crap Thanks!!!! You guys are incredible!
  3. Oh sweet! Thanks Jack! I figured that it was something simple that I was completely overlooking.
  4. Hello everyone! It has been way to long. I am in the process of re-creating my website from the ground up in in Visual Studio 2017, using Bootstrap. I just purchased the Shockingly Green Membership to really start making my site shine from the beginning. My first issue, and I am sorry if it is a common one, is that a number of my statements are now erroring out at runtime. I really wish the Visual Studio compiler could find these errors during compile and before debugging, but at least we have runtime debugging Specifically, none of my pre-defined Ease variables are working. Here is one of the variables: var armorPlateEaseIn = SlowMo.ease.config(0.3, 0.4, false); This worked in the GSAP v2 code that I ported from the previous site re-design, but definitely no longer works. It just errors out on me at runtime and brings the site to a stop. This is the error (WebsiteStructureAnimations.js:517 Uncaught ReferenceError: SlowMo is not defined). If I add Gsap, like so: var armorPlateEaseIn = gsap.SlowMo.ease.config(0.3, 0.4, false); I get this error: Uncaught TypeError: Cannot read property 'ease' of undefined Here is how I am referencing the code base: <script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/3.0.4/gsap.min.js"></script> <script type="module" src="~/js/GSAP Resources/CustomEase.min.js"></script> <script type="module" src="~/js/GSAP Resources/EasePack.min.js"></script> I am pointing to the correct directories and I have included the Javascript files in my solution. My guess is that I am just no longer using the correct variable declaration statement of SlowMo.ease.config? Perhaps this has changed a fair amount since V2 of Gsap or maybe I did not install my source files correctly? Thanks ahead of time and I am really sorry, I know that this question is likely super simple but I am just trying to get my site to run again (re-working the code to fit the new standards along the way). Happy New Year!!!
  5. No problem Carl I am glad to help when I can! I will put together a small project that preloads a model, then loads it into a content page and finally applies textures dynamically. I will probably have some time this weekend to put it together. -Cheers
  6. So I thought about this a bit and I think it would be far more useful if I explained my end of project workflow from 3DsMax to Flash and why I felt the need to use switches in the last bit of my code. So I will start with my end of modeling workflow: 1. Separate the main mesh into layers using the 3DsMax Layer Tool according to my needs. I might want to animate specific parts of the model in my website code or apply unique textures to each different part of the mesh. 2. Go through each mesh layer and make sure that the smoothing groups are set up well and re-build them if they are not. 3. Use a checkerboard texture to create good UV maps for all meshes in all layers. I use the checkerboard texture because it is easier to see if the UV's match well across the entire object instead of just mesh by mesh / layer by layer. Easier to create a uniform UV consistency. 4. Save the model as myModelA or myModel1 or whatever the next letter or number happens to be in your iterative naming convention. 5. Here is where I replace whatever textures that I am using for 3DsMax viewing with just a default standard texture. I make sure that this default is the only texture on all meshes / layers of the model. This is because I like to dynamically apply my textures with code, but you may want to skip this step. 6. Select all meshes within all layers of the model, make sure that the model overall is at 0,0,0, Reset X-Form, then convert all meshes back to Edit-able Poly afterward. 7. Just as a final check, select all meshes, enter vertex mode and weld to make sure that everything is tight before export. 8. Export the model as Obj. Make sure to hide any trash geometry layers or delete them before export. Now you will have an Obj model file and its material file. I have already made a point about adjusting the obj file .mtl path if these assets are placed in a special folder. Failing to do this will spit the dreaded network stream error for the .mtl file. The Two code Switches in my code snippet: 1. Switch 1: This switch catches the AssetEvent for each layer in the model. Each event from the DataLoader will be 1 of three things. I only care about the Mesh asset, but it will also provide both the Material and Geometry Assets. This is why I have the first switch. Example: I export a model with 3 layers, my switch will catch three different passes for each layer, so 9 passes. I only care about the Mesh pass, and I push the code that converts the string information to a mesh and then apply my textures accordingly when the Mesh case is true. If I do not detect for the other two cases, however, I will more often than not catch the wrong information and receive a null object error when trying to convert the string to a mesh (in the cases of Material or Geometry). This is the simple and quick explanation for the first switch. 2. Switch 2: I am going to use the same example of a 3 layer model and I want a different texture applied to each different layer (mesh section). This is the reason that I use the second switch. You can tell which layer (mesh section) will come in what order by opening your Obj file in notepad and looking at the Object: someName instances. Let's say that my 3 layer model lists the the Object names as follows from top to bottom on the file (Frame, Text, Base). I know what geometry the names link to since they are the layers that I created in 3DsMax . Case 0 = Frame, Case 1 = Text and Case 2 = Base. I now know what material to apply in each case instance. Voila!!! I am texturing or animating the correct part of the mesh using a switch statement There are many ways to do this I imagine, and I am the first to admit that I am not an expert. So feel free to get creative with your methods.
  7. Hello Everyone and Happy New year! I have been fully re-working my website using Greensock (Flash) to leverage the Starling Away3D framework. I have found that many people ask the same questions about how to use the incredible power of the Greensock code to take care of the loading of Starling and Away3D assets: Here are some code examples from the Preloader ClassFile: 1. LoaderMax loader that queues and loads a 3DSMax (Obj) model, myModel, for a second Content Classfile: //======================================================== //*** Variable declarations for Main Loader.*** // //======================================================== private var mainQueue:LoaderMax = new LoaderMax({name: "mainQueue", rawProgress: 1, onProgress: ProgressHandler, onComplete: completeHandler}); //========================================================== //*** LoaderMax Loader.*** // //========================================================== LoaderMax.defaultAuditSize = false; mainQueue.append(myModel); mainQueue.load(); mainQueue.addEventListener(LoaderEvent.COMPLETE, completeHandler); mainQueue.addEventListener(LoaderEvent.PROGRESS, ProgressHandler); 2. Here is a close look at the DataLoader Variable that I am using in the Loader above. The DataLoader has the model path (assets/myModel.obj) and the name (SkyScraper) that I am giving the model, so that I can access it in the other class file //========================================================================= //*** Variable declarations for Away3D Model Preloading.*** // //========================================================================= private var myModel:DataLoader = new DataLoader("assets/myModel.obj", {name: "SkyScraper", format: "text", rawProgress: 1, autoPlay: false}); This is all that is needed in the preloader class. The 3DSMax model will be loaded by the DataLoader in text format. The next step is important and must be done before testing: 1. Open the .obj file in notepad and make sure that the path to the .mtl file is correct. In my example I had to re-write the path from Object: myModel to Object: assets/myModel since the .obj file and its .mtl file were added to the assets folder for my website. If you do not do this, you have the chance of encountering a Network streaming error complaining about the inability to resolve your .mtl file location when testing your flash page. I will now show you how to access the model information that we need in the content class. Here are the code examples from my Content Class File, which needs to access the model data so that it can be shown in the content page: //======================================================== // //*** DataLoaders for Model Meshes.*** //*** Mesh Variable Declarations.*** // //======================================================== private var skyScraperModelText:String = LoaderMax.getContent("SkyScraper"); private var modelMesh:Mesh; In the code chunk above, I have asked to getContent on the name of the DataLoader from the Preloader classfile and that information has been stored in the new string variable skyScraperModelText. I have also declared a new mesh variable "modelMesh" for later usage. //=========================================================== // //*** Loader for the Portfolio Mesh *** // //=========================================================== meshLoader = new Loader3D(); meshLoader.loadData(skyScraperModelText); meshLoader.addEventListener(AssetEvent.ASSET_COMPLETE, modelLoaderHandler); This chunk of code allows the Loader3D (Away3D) to have access to the Obj model data that we have already pre-loaded using Greensock. The new eventListener will then fire our last chunk of code, which will load the Obj data from the String variable and start applying textures to each 3DsMax model layer that I created when setting the model up: NOTE: Most of the code below is extraneous to the act of loading the model into the content class so that it can be rendered on a webpage. I have left it in so that you can see the process that I am using to dynamically apply my own texture to the mesh layer. There are actually 9 case switches in my real code that apply 8 different textures to the 8 different model layers, but 1 is enough for the example. private function modelLoaderHandler(e:AssetEvent):void { trace("Portfolio Symbol Mesh Loaded!"); //============================================================== // //*** Set up Away3D Model Textures and Assign the Lights. *** // //============================================================== var boxModelCubeTexBase:Texture2DBase = new BitmapTexture(boxModelCube.rawContent.bitmapData); var boxModelOuterRingTexBase:Texture2DBase = new BitmapTexture(boxModelOuterRing.rawContent.bitmapData); var boxModelInnerRingTexBase:Texture2DBase = new BitmapTexture(boxModelInnerRing.rawContent.bitmapData); var boxModelLettersTexBase:Texture2DBase = new BitmapTexture(boxModelLetters.rawContent.bitmapData); switch (String(profileMeshVar)) { case "0": runFirstMaterialSwitchPA(); // MaxBody Mesh break; case "1": meshLoader.removeEventListener(AssetEvent.ASSET_COMPLETE, modelLoaderHandler); trace("Profile Model Ready for Render Engine!!!"); break; } function runFirstMaterialSwitchPA():void { trace("Applying First Profile Model Material!") //======================================================================== // //*** First Material is applied to the Main Box Object *** // //======================================================================== switch (String(e.asset.assetType)) { case "mesh": // Assign mesh modelMesh = e.asset as Mesh; // Loop through mesh assigning materials to the sub meshes for each (var m:SubMesh in modelMesh.subMeshes) { trace("APPLYING PROFILE MATERIAL TO SURFACE 0!!!!!"); //============================================================= // //*** Set up Away3D Model Textures and Assign the Lights. *** // //============================================================= var cubeMaterial:ColorMaterial = new ColorMaterial(0xffffff); cubeMaterial.ambientColor = 0xdd5525; cubeMaterial.ambient = 1; //0xdd5525; cubeMaterial.specular = .5; cubeMaterial.diffuseMethod = new CelDiffuseMethod(3); cubeMaterial.specularMethod = new CelSpecularMethod(); cubeMaterial.addMethod(new OutlineMethod(0x000000, 5, true)); CelSpecularMethod(cubeMaterial.specularMethod).smoothness = .01; CelDiffuseMethod(cubeMaterial.diffuseMethod).smoothness = .01; cubeMaterial.normalMap = Cast.bitmapTexture(boxModelCubeTexBase); cubeMaterial.repeat = true; cubeMaterial.lightPicker = lightPicker; //============================================================= // //*** Find the Model Assets using the Loader and their Level. * // //============================================================= m.material = cubeMaterial; } break; case "material": trace("This is a material and not a model!!!"); break; default: trace("UNHANDLED ASSET TYPE: " + e.asset.assetType); break; } } The true take-away chunk of code from the bit above is part of the first switch statement: switch (String(e.asset.assetType)) { case "mesh": // Assign mesh modelMesh = e.asset as Mesh; blah blah blah more code { The e.asset String is being converted to a mesh and my modelMesh variable is being declared equal to it and therefore now contains the important Obj model asset information. Voila!!! The later code uses switch statements to apply different textures to the different Obj model layers, but that is for another topic I hope that someone else finds this useful and wastes less time searching for answers -Cheers
  8. Hello everyone, I am sorry that this is offtopic and not specific to Greensock, but I get a lot of great help and responses here, so I thought I would try My problem is that I shuffle my array of 16 images and then pick from that array to place an image on a thumbplate. It works perfectly most of the time. Sometimes, however, one of the already loaded images gets removed from the array and therefore removed from its image plate during another shuffle pass. I am loading images on to 6 plates, so the shuffle runs 6 times. Here is my shuffle code: public function shuffleArray(input:Array):void { for (var i:int = input.length - 1; i > 0; i--) { var randomIndex:int = Math.floor(Math.random() * (i + 1)); var itemAtIndex:Object = input[randomIndex]; input[randomIndex] = input[i]; input[i] = itemAtIndex; } } Does anyone see a way that I can avoid already placed images from getting removed? Here is the PickFromArray code I am using, in case the issue is in there: public function pickFromScreenArray():void { trace("Grab a New Image"); var imageArray:Array = ["AssassImageSA", "AssassImageSB", "AssassImageSC", "AssassImageSD", "AssassImageSE", "AssassImageSF", "AssassImageSG", "AssassImageSH", "AssassImageSI", "AssassImageSJ", "AssassImageSK", "AssassImageSL", "AssassImageSM", "AssassImageSN", "AssassImageSO", "AssassImageSP", "AssassImageSQ"]; shuffleArray(imageArray); addChildAt(LoaderMax.getContent(imageArray[0]), 1); var currentImage:DisplayObject = getChildAt(1); currentImage.alpha = 0; TweenMax.fromTo(currentImage, 2, {autoAlpha: 0}, {autoAlpha: 1, ease: Quad.easeIn}); } Thanks for looking
  9. After some toying I found my answer!!! public function findTheImage(e:MouseEvent):void { trace("Check for ImageA"); var currentScreenImageOnA:DisplayObject = ScreenButtonA.getChildAt(1); trace(currentScreenImageOnA.name); trace(screenImageA); trace(screenImageB); trace(screenImageC); trace(screenImageD); trace(screenImageE); trace(screenImageF); if (currentScreenImageOnA.name == "AssassImageSA") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_A.png")); } if (currentScreenImageOnA.name == "AssassImageSB") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_B.png")); } if (currentScreenImageOnA.name == "AssassImageSC") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_C.png")); } if (currentScreenImageOnA.name == "AssassImageSD") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_D.png")); } if (currentScreenImageOnA.name == "AssassImageSE") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_E.png")); } if (currentScreenImageOnA.name == "AssassImageSF") { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_F.png")); } } So after running some traces to see what was actually showing up for comparison, I decided to compare the name strings and voila!!! I get the exact large image link perfectly on every instance comparison. Woohoo!
  10. Cool, thank you for the quick reply. I do have both class files and the test movie that I could send to you if you want to see all of it together? Sadly my explanations of what is going on are probably quite limiting. My main problem is that I don't have the best way to load images onto my thumbPlates. If I try and run that PickFromArray function without the shuffle, it will only load an image onto one instance called to the stage and spit null errors for the other instances called. I am just not as clear on array usage as I should be >.<. I would also rather keep these class files separate so that I can use the ScreenButtonScript class in multiple movies.
  11. Ok after a bit more work I have everything working except for one thing. I am using this function to try and find the image that was loaded into child level 1 of the thumbnail (Level 0 = backplate, level 1 = randomly loaded thumbnail, level 2 = mouse detection plates). Once found it is compared to all 6 image variables. Itis supposed to be = to one and then fire off the correct link: public function findTheImage(e:MouseEvent):void { trace("Check for ImageA"); var currentScreenImageOnA:DisplayObject = ScreenButtonA.getChildAt(1); trace(currentScreenImageOnA); if (currentScreenImageOnA == screenImageA) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_A.png")); } if (currentScreenImageOnA == screenImageB) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_B.png")); } if (currentScreenImageOnA == screenImageC) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_C.png")); } if (currentScreenImageOnA == screenImageD) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_D.png")); } if (currentScreenImageOnA == screenImageE) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_E.png")); } if (currentScreenImageOnA == screenImageF) { navigateToURL(new URLRequest("http://levelforge.com/images/WebsiteFlash10/AssassinsCreedIII_F.png")); } } This is my attempt to find what the random image placed into this thumbnail plate is, compare it to all six possibilities, and then link the correct larger version of the image. Sadly my code does not throw any errors, but it also does not do anything. I know that the if statements work, because they have compared and detected the correct image in previous setups where other things did not work. I assume I have done something wrong with the "var currentScreenImageOnA:DisplayObject = ScreenButtonA.getChildAt(1);" which is meant to examine the thumbnail instance on the stage "ScreenButtonA" and get the image on level 1 of this thumbplate to compare to all of the image possibilities. Has anyone else tried anything like this and maybe have some advice on what I am missing? Thanks!
  12. Thanks a bunch. It was not actually that yours does not do what I am after. I was just already trying the other option, so I finished my test. I am going to try yours next time I dig into it actually since my attempt is a bit on the tweaky half-functional side. Thanks again and I will tell you how it works out
  13. I actually don't have access to the transformAroundCenter code yet, but I am trying something that is showing promise: public function ScreenButtonScript() { // This is the base button image. trace("Load the Base Image"); addChildAt(screenBase, 0); screenBase.centerRegistration = true; screenBase.alpha = 1; // This is the right hitbox on top of the base button image. hitRight.x = 30; hitRight.y = -5; addChildAt(hitRight, 1); hitRight.alpha = 1; // This is the topright hitbox on top of the base button image. hitTopRight.x = 30; hitTopRight.y = -30; addChildAt(hitTopRight, 1); hitTopRight.alpha = 1; mouseChildren = true; buttonMode = true; } // These are the deformation functions for the two plates I have loaded. private function deformRight(e:MouseEvent):void { trace("Deformations for Right Button"); TweenMax.to(screenBase, .5, {z: -15}); TweenMax.to(screenBase, .5, {rotationY: 15}); TweenMax.to(screenBase, .5, {rotationX: 0}); } private function deformTopRight(e:MouseEvent):void { trace("Deformations for TopRight Button"); TweenMax.to(screenBase, .5, {z: -15}); TweenMax.to(screenBase, .5, {rotationY: 15}); TweenMax.to(screenBase, .5, {rotationX: 15}); } // Deformation deblur I call later to remove the blur. private function screenDeBlur():void { var currentX = screenBase.x; var currentY = screenBase.y; screenBase.transform.matrix3D = null; screenBase.x = currentX; screenBase.y = currentY; } So that is not all the code calling each function, but I have two right side deformations set up (Right and TopRight) using two small movie squares (lvl 1) that I am loading on top of the main button (lvl 0). This seems to work well but I lose the mouse arrow when I am over top of one of the movie instances that calls for the deform, even though I set mouseChildren: true;. Is there something I can do to keep the little hand mousebutton cursor even when I am over the other eventListener movie plates that call the button deforms? It is also a bit tweaky as the plates that call for the deformations do not seem to always catch the mouseOver events. I assume this is because the main button also has mouseOver EventListeners as well. Maybe they fight for priority from time to time? Thanks.
  14. Thank you very much! I will poke around with this. I really appreciate your time
  15. Has anyone ever tried to create a button that transform adjusts to the position of the mousecursor as you mouseOver it? I am looking to create the same basic effect as the Dell Stage app buttons: I already have a couple of buttons that react to mouseOver in one direction, but they do not adjust in real-time to the exact cursor position as you move over the button in one direction or the other. Here is my code that does the simple transform in one direction: private function buttonReactOver(e:MouseEvent):void { TweenMax.to(this, .5, {z: -15}); TweenMax.to(this, .5, {rotationY: -15}); } } My initial thought would be to create 8 invisible hitboxes in my button (4 for each side) and (4 for each corner). I could then use eventListeners for each to call functions like the one above. Each would rotate the main visual in the correct direction depending on the hitbox I am inside of at the time. There must be a more efficient way to go about this though? Thanks