Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Events
Videos
Audiobooks
Packt Hub
Free Learning
Arrow right icon
timer SALE ENDS IN
0 Days
:
00 Hours
:
00 Minutes
:
00 Seconds

How-To Tutorials

7019 Articles
article-image-papervision3d-external-models-part-1
Packt
18 Nov 2009
22 min read
Save for later

Papervision3D External Models: Part 1

Packt
18 Nov 2009
22 min read
This article covers the following: Modeling for Papervision3D Preparing for loading models Creating and loading models using Autodesk 3ds Max Loading an animation from Autodesk 3ds Max Creating and loading models using SketchUp Creating and loading models using Blender Controlling loaded materials Let's start off by having a look at some general practices to keep in mind when modeling for Papervision3D. Modeling for Papervision3D In this section, we will discuss several techniques that relate to modeling for Papervision3D. As Papervision3D is commonly used for web-based projects, modeling requires a different mindset than modeling for an animated movie, visualization, or game. Most of the techniques discussed relate to improving performance. This section is especially useful for modelers who need to create models for Papervision3D. Papervision3D PreviewerPapervision3D Previewer is a small program that should be part of every modeller's toolbox. This tool comes in handy for testing purposes. It allows a modeler to render an exported model in Papervision3D, and it displays some statistics that show how the model performs. At the time of writing, this tool was not compatible with Papervision3D 2.1, which could result in small problems when loading external models.Papervision3D Previewer can be downloaded from http://code.google.com/p/mrdoob/wiki/pv3dpreviewer Keep your polygon count low Papervision3D is a cutting edge technology that brings 3D to the Flash Player. It does this at an amazing speed relative to the capabilities of the Flash player. However, performance of Papervision3D is just a fraction of the performance that can be achieved with hardware-accelerated engines such as used by console games. Even with hardware-accelerated games there is a limit to the number of polygons that can be rendered, meaning there is always a compromise between detail and performance. This counts even more for Papervision3D, so always try to model using as few polygons as possible. Papervision3D users often wonder what the maximum number of triangles is that the Flash player can handle. There is no generic answer to this question, as performance depends on more factors than just the number of triangles. On average, the total triangle count should be no more than 3000, which equals 1500 polygons (remember that one polygon is made of two triangles). Unlike most 3D modeling programs, Papervision3D is triangle based and not polygon based. Add polygons to resolve artifacts Although this seems to contradict the previous suggestion to keep your polygon count low, sometimes you need more polygons to get rid of texture distortion or to reduce z-sorting artifacts. z-sorting artifacts will often occur in areas where objects intersect or closely intersect each other. Subdividing polygons in those areas can make z-sorting more accurate. Often this needs to be done by creating new polygons for the intersecting triangles of approximately the same size. There are several approaches to prevent z-sorting problems. Depending on the object you're using, it can be very time consuming to tweak and find the optimal amount and location of polygons. The amount of polygons you add in order to solve the problem should still be kept as low as possible. Finding the optimal values for your model will often result in switching a lot between Papervision3D and the 3D modeling program. Keep your textures small Textures used in the 3D modeling tool can be exported along with the model to a format that is readable for Papervision3D. This is a valuable feature as the texture will automatically be loaded by Papervision3D. However, the image, which was defined in the 3D authoring tool, will be used exactly as provided by Papervision3D. If you choose a 1024 by 1024 pixels image as the texture, for example the wheels of a car, Papervision3D loads the entire image and draws it on the wheel of a car that appears on screen at a size of 50 by 50 pixels for example. There are several problems related to this: It's a waste of bandwidth to load such a large image. Loading any image takes time, which should be kept as short as possible. It's a waste of capacity. Papervision3D needs to resize the image from 1024 by 1024 pixels to an image, which will be, for example, maximal 50 by 50 pixels on screen. Always choose texture dimensions that make sense for the application using it, and keep in mind that they have to be power of two. This will enable mipmapping and smoothing, which come without extra performance costs. Use textures that Flash can read 3D modeling programs usually read a variety of image sources. Some even support reading Adobe Photoshop's native file-format PSD. Flash can load only GIF, JPG, or PNG files at run time. Therefore, stick to these formats in your model so that you do not have to convert the textures when the model needs to be exported to Papervision3D. Use UV maps If your model is made up of several objects and textures, it's a good idea to use UV mapping, which is the process of unwrapping the model and defining all its textures into one single image. This way we can speed up initial loading of an application by making one request from Flash to load this image instead of loading dozens of images. UV mapping can also be used to tile or reuse parts of the image. The more parts of the UV-mapped image you can reuse, the more bandwidth you'll save. Always try to keep your UV-mapped image as small as possible, just as with keeping your normal textures small. In case you have a lot of objects sharing the same UV map and you need a large canvas to unwrap the UV map, be aware of the fact that the maximum image size supported by Flash Player 9 is 2880x2880 pixels. With the benefits of power of two textures in mind, the maximum width and height is 2048x2048 pixels. Baking textures Baking textures is the process of integrating shadows, lighting, reflection, or entire 3D objects into a single image. Most 3D modeling tools support this. This contradicts what has been said about tiling images in UV maps, as baking results in images that usually can only be used once because of the baked information on the texture. However, it can increase the level of realism of your application, just like shading does, but without the loss of performance caused by calculating shading in real time. Never use them in combination with a tiling image, as repeated shading, for instance, will result in unnatural looking renders. Therefore, each texture needs to be unique, which will cause longer loading times before you can show a scene. Use recognizable names for objects and materials It is always a good convention to use recognizable names for all your objects. This counts for the classes, methods, and properties in your code, and also for the names of the 3D objects in your modeling tool. Always think twice before renaming an object that is used by an application. The application might use the name of an object as the identifier to do something with it—for example, making it clickable. When working in a team of modelers and programmers, you really need to make this clear to the modelers as changing the name of an object can easily break your application. Size and positioning Maintaining the same relative size for your modeled objects, as you would use for instantiating primitives in your scene, is a good convention. Although you could always adjust the scale property of a loaded 3D model, it is very convenient when both Papervision3D and your modeling tool use the same scale. Remember that Papervision3D doesn't have a metric system defining units of a certain value such as meters, yards, pixels, and so on. It just uses units. Another convention is to position your object or objects at the origin of the 3D space in the modeling tool. Especially when exporting a single object from a 3D modeling tool, it is really helpful if it is located at a position of 0 on all axes. This way you can position the 3D object in Papervision3D by using absolute values, without needing to take the offset into account. You can compare this with adding movie clips to your library in Flash. In most cases, it is pretty useful when the elements of a movie clip are centered on their registration point. Finding the balance between quality and performance For each project you should try to find the balance between lightweight modeling and quality. Because each project is different in requirements, scale, and quality, there is no rule that applies for all. Keep the tips mentioned in the previous sections in mind and try to be creative with them. If you see a way to optimize your model, then do not hesitate to use it. Before we have a look at how to create and export models for Papervision3D, we will create a basic application for this purpose. Creating a template class to load models In order to show an imported 3D model using Papervision3D, we will create a basic application. Based on the orbit example (code bundle-chapter 6, click the following link to download: http://www.packtpub.com/files/code/5722_Code.zip) we create the following class. Each time we load a new model we just have to alter the init() method. First, have a look at the following base code for this example: package { import flash.events.Event; import org.papervision3d.materials.WireframeMaterial; import org.papervision3d.materials.utils.MaterialsList; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.objects.primitives.Cube; import org.papervision3d.view.BasicView; public class ExternalModelsExample extends BasicView { private var model:DisplayObject3D; private var rotX:Number = 0.1; private var rotY:Number = 0.1; private var camPitch:Number = 90; private var camYaw:Number = 270; private var easeOut:Number = 0.1; public function ExternalModelsExample() { stage.frameRate = 40; init(); startRendering(); } private function init():void { model = new Plane(); scene.addChild(model); } private function modelLoaded(e:FileLoadEvent):void { //To be added } override protected function onRenderTick(e:Event=null):void { var xDist:Number = mouseX - stage.stageWidth * 0.5; var yDist:Number = mouseY - stage.stageHeight * 0.5; camPitch += ((yDist * rotX) - camPitch + 90) * easeOut; camYaw += ((xDist * rotY) - camYaw + 270) * easeOut; camera.orbit(camPitch, camYaw); super.onRenderTick(); } }} We have created a new plane using a wireframe as its material. The plane is assigned to a class property named model, which is of the DisplayObject3D type. In fact, any external model is a do3D. No matter what type of model we load in the following examples, we can always assign it to the model property. The classes that we'll use for loading 3D models all inherit from DisplayObject3D. Now that we have created a default application, we are ready to create our first model in 3D Studio Max, export it, and then import it into Papervison3D. Creating models in Autodesk 3ds Max and loading them into Papervision3D Autodesk 3ds Max (also known as 3D Studio Max or 3ds Max) is one of the widely-known commercial 3D modeling and animation programs. This is a good authoring tool to start with, as it can save to two of the file formats Papervision3D can handle. These are: COLLADA (extension *.dae): An open source 3D file type, which is supported by Papervision3D. This is the most advanced format and has been supported since Papervision3D's first release. It also supports animations and is actually just a plain text XML file. 3D Studio (extension *.3ds): As the name suggests, this is one of the formats that 3ds Max natively supports. Generally speaking it is also one of the most common formats to save 3D models in. As of 3ds Max version 9, there is a built-in exporter plugin available that supports exporting to COLLADA. However, you should avoid using this, as at the time of writing, the models it exports are not suitable for Papervision3D. Don't have a license of 3ds Max and want to get along with the following examples? Go to www.autodesk.com to download a 30-day trial. Installing COLLADA Max An exporter that does support COLLADA files suitable for Papervision3D is called COLLADA Max. This is a free and open source exporter that works with all versions of 3ds Max 7 and higher. Installing this exporter is easy. Just follow the steps mentioned below: Make sure you have installed 3ds Max version 7 or higher. Go to http://sourceforge.net/projects/colladamaya/. Click on View all files and select the latest COLLADA Max version. (At the time of writing this is COLLADA Max NextGen 0.9.5, which is still in beta, but is the only version that works with 3ds Max 2010). Save the download somewhere on your computer. Run the installer. Click Next, until the installer confirms that the exporter is installed. Start 3ds Max and double check if we can export using the COLLADA or COLLADA NextGen filetype, as shown in the following screenshot: If the only COLLADA export option is Autodesk Collada, then something went wrong during the installation of COLLADA Max, as this is not the exporter that works with Papervision3D. Now that 3ds Max is configured correctly for exporting a file format that can be read by Papervision3D, we will have a look at how to create a basic textured model in 3ds Max and export it to Papervision3D. Creating the Utah teapot and export it for Papervision3D If you already know how to work with 3ds Max, this step is quite easy. All we need to do is create the Utah teapot, add UV mapping, add a material to it, and export it as COLLADA. However, if you are new to 3ds Max, the following steps needs to be clarified. First, we start 3ds Max and create a new scene. The creation of a new scene happens by default on startup. The Utah teapot is one of the objects that comes as a standard primitive in 3ds Max. This means you can select it from the default primitives menu and draw it in one of the viewports. Draw it in the top viewport so that the teapot will not appear rotated over one of its axes. Give it a Radius of 250 in the properties panel on the right, in order to make it match with the units that we'll use in Papervision3D. Position the teapot at the origin of the scene. You can do this by selecting it and changing the x, y, and z properties at the bottom of your screen. You would expect that you need to set all axes to 0, although this is not the case. In this respect, the teapot differs from other primitives in 3ds Max, as the pivot point is located at the bottom of the teapot. Therefore, we need to define a different value for the teapot on the z-axis. Setting it to approximately -175 is a good value. To map a material to the teapot, we need to define a UV map first. UV mapping is also known as UVW mapping. Some call it UV mapping and others call it UVW mapping. 3ds Max uses the term UVW mapping. While having the teapot still selected, go to modify and then select UVW Mapping from the modifier list. Select Shrink Wrap and click Fit in the Alignment section. This will create a UVW map for us. Open the material editor using keyboard shortcut m. Here we define the materials that we use in 3ds Max. Give the new material a name. Replace 01 – Default with a material name of your choice—for example, teapotMaterial. Provide a bitmap as the diffuse material. You can do this by clicking on the square button, at the right of the Diffuse value within Blinn Basic Parameters section. A new window called Material/Map Browser will open. Double-click Bitmap to load an external image. Select an image of your choice. We will use teapotMaterial.jpg The material editor will now update and show the selected material on an illustrative sphere. This is your newly-created material, which you need to drag on the created teapot. The teapot model can now be exported. Depending on the version of the installed COLLADA exporter, select COLLADA or COLLADA NextGen. Note that you should not export using Autodesk Collada, as this exporter doesn't work properly for Papervision3D. Give it a filename of your choice, for example teapot, and hit Save. The exporter window will pop up. The default settings are fine for exporting to Papervision3D, so click OK to save the file. Save the model in the default 3ds Max file format (.max) somewhere on your local disk, so we can use it later when discussing other ways to export this model to Papervision3D. The model that we have created and exported is now ready to be imported by Papervision3D. Let's take a look at how this works. Importing the Utah teapot into Papervision3D To work with the exported Utah teapot, we will use the ExternalModelsExample project that we created previously in this article. Browse to the folder inside your project where you have saved your document class. Create a new folder called assets and copy to this folder, the created COLLADA file along with the image used as the material of the teapot. The class used to load an external COLLADA file is called DAE, so let's import it. import org.papervision3d.objects.parsers.DAE; This type of class is also known as a parser, as it parses the model from a loaded file. When you have a closer look at the source files of Papervision3D and its model parsers, you will probably find out about the Collada class. This might be a little confusing as we use the DAE parser to load a COLLADA file and we do not use the Collada parser. Although you could use either, this article uses the DAE parser exclusively, as it is a more recent class, supporting more features such as animation. There is no feature that is supported by the Collada parser, and is not supported by the DAE parser. Replace all code inside the init() method with the following code that loads a COLLADA file: model = new DAE();model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);DAE(model).load("assets/teapot.DAE"); Because model is defined as a DisplayObject3D class type, we need to cast it to DAE to make use of its methods so that we can call the load() method. An event listener is defined, waiting for the model to be completely loaded and parsed. Once it is loaded, the modelLoaded() method will be triggered. It is a good convention to add models only to the scene once the model is completely loaded. Add the following line of code to the modelLoaded() method: scene.addChild(model); COLLADA Utah Teapot Example Publishing this code will result in the teapot with the texture as created in 3ds Max. In real-world applications it is good practice to keep your models in one folder and your textures in another. You might want to organize the files similar to the following structure: Models in /assets/models/ Textures in /assets/textures/ By default, textures are loaded from the same folder as the model is loaded from, or optionally from the location as specified in the COLLADA file. To include the /assets/textures/ folder we can add a file search path, which defines to have a look in the specified folder, to see if the file is located there, in case none can be found on the default paths. This can be defined as follows: daeModel.addFileSearchPath("assets/textures"); You can call this method multiple times, in order to have multiple folders defined. Internally, in Papervision3D, it will loop through an array of file paths. Exporting and importing the Utah teapot in 3ds format Now that we have seen how to get an object from 3ds Max into a Papervision3D project, we have a look at another format that is supported by both 3ds Max and Papervision3D. This format is called 3D Studio, using a 3ds extension. It is one of the established 3D file formats that are supported by most 3D modeling tools. Exporting and importing is very similar to COLLADA. Let's first export the file to the 3D Studio format. Open the Utah teapot, which we've modeled earlier in this article. Leave the model as it is, and go straight to export. This time we select 3D Studio (*.3DS) as the file type. Save it into your project folder and name it teapot. Click OK when asked whether to preserve Max's texture coordinates. If your model uses teapotMaterial.jpg, or an image with more than eight characters in its filename, the exporter will output a warning. You can close this warning, but you need to be aware of the output message. It says that the bitmap filename is a non-8.3 filename, that is, a maximum amount of 8 characters for the filename and a 3-character extension. The 3D Studio file is an old format, released at the time when there was a DOS version of 3ds Max. Back then it was an OS naming convention to use short filenames, known as 8.3 filenames. This convention still applies to the 3D Studio format, for the sake of backward compatibility. Therefore, the reference to the bitmap has been renamed inside the exported 3D Studio file. Because the exported 3D Studio file changed only the reference to the bitmap filename internally and it did not affect the file it refers to, we need to create a file using this renamed file reference. Otherwise, it won't be able to find the image. In this case we need to create a version of the image called teapotMa.jpg. Save this file in the same folder as the exported 3D Studio file. As you can see, it is very easy to export a model from 3ds Max to a format Papervision3D can read. Modeling the 3D object is definitely the hardest and most time consuming part, simply because creating models takes a lot of time. Loading the model into Papervision3D is just as easy as exporting it. First, copy the 3D Studio file plus the renamed image to the assets folder of your project. We can then alter the document class in order to load the 3ds file. The class that is used to parse a 3D Studio file is called Max3DS and needs to be imported. import org.papervision3d.objects.parsers.Max3DS; In the init() method you should replace or comment the code that loads the COLLADA model from our previous example, with the following: model = new Max3DS();model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);Max3DS(model).load("assets/teapot.3ds", null, "./assets/"); As the first parameter of the load method, we pass a file reference to the model we want to load. The second parameter defines a materials list, which we will not use for this example. The third and final parameter defines the texture folder. This folder is relative to the location of the published SWF. Note that this works slightly different than the DAE parser, which loads referenced images from the path relative to the folder in which the COLLADA file is located or loads images as specified by the addFileSearchPath() method. ExternalModelsExample Publish the code and you'll see the same teapot. However, this time it's using the 3D Studio file format as its source. Importing animated models The teapot is a static model that we exported from a 3D program and loaded into Papervision3D. It is also possible to load animated models, which contain one or multiple animations. 3ds Max is one of the programs in which you can create an animation for use in Papervision3D. Animating doesn't require any additional steps. You can just create the animation and export it. This also goes for other modeling tools that support exporting animations to COLLADA. For the sake of simplicity, this example will make use of a model that is already animated in 3ds Max. The model contains two animations, which together make up one long animation on a shared timeline. We will export this model and its animation to COLLADA, load it into Papervision3D, and play the two animations. Open animatedMill.max in 3ds Max. This file can be found in the zip file that can be downloaded from: http://www.packtpub.com/files/code/5722_Code.zip. You can see the animation of the model directly in 3ds Max by clicking the play button in the menu at the bottom right corner, which will animate the blades of the mill. The first 180 frames animate the blades from left to right. Frames 181 to 360 animate the blades from right to left. As the model is already animated, we can go ahead with exporting, without making any changes to the model. Export it using the COLLADA filetype and save it somewhere on your computer. When the COLLADA Max exporter settings window pops up, we need to check the Sample animation checkbox. By default Start and End are set to the length of the timeline as it is defined in 3ds Max. In case you just want to export a part of it, you can define the start and end frames you want to export. For this example we leave them as they are: 0 and 360. By completing these steps you have successfully exported an animation in the COLLADA format for Papervision3D. Now, have a look at how we can load the animated model into Papervision3D. First, you need to copy the exported COLLADA and the applied material—Blades.jpg, House.jpg, and Stand.jpg—to the assets folder of your project. To load an animated COLLADA, we can use the DAE class again. We only need to define some parameters at instantiation, so the animation will loop. model = new DAE(true,null,true);model.addEventListener(FileLoadEvent.LOAD_COMPLETE,modelLoaded);DAE(model).load("assets/animatedMill.dae"); Take a look at what these parameters stand for.
Read more
  • 0
  • 0
  • 3013

article-image-plotting-geographical-data-using-basemap
Packt
18 Nov 2009
3 min read
Save for later

Plotting Geographical Data using Basemap

Packt
18 Nov 2009
3 min read
Basemap is a Matplotlib toolkit, a collection of application-specific functions that extends Matplotlib functionalities, and its complete documentation is available at http://matplotlib.sourceforge.net/basemap/doc/html/index.html. Toolkits are not present in the default Matplotlib installation (in fact, they also have a different namespace, mpl_toolkits), so we have to install Basemap separately. We can download it from http://sourceforge.net/projects/matplotlib/, under the matplotlib-toolkits menu of the download section, and then install it following the instructions in the documentation link mentioned previously. Basemap is useful for scientists such as oceanographers and meteorologists, but other users may also find it interesting. For example, we could parse the Apache log and draw a point on a map using GeoIP localization for each connection. We use the 0.99.3 version of Basemap for our examples. First example Let's start playing with the library. It contains a lot of things that are very specific, so we're going to just give an introduction to the basic functions of Basemap. # pyplot module importimport matplotlib.pyplot as plt# basemap importfrom mpl_toolkits.basemap import Basemap# Numpy importimport numpy as np These are the usual imports along with the basemap module. # Lambert Conformal map of USA lower 48 statesm = Basemap(llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64, urcrnrlat=49, projection='lcc', lat_1=33, lat_2=45, lon_0=-95, resolution='h', area_thresh=10000) Here, we initialize a Basemap object, and we can see it has several parameters depending upon the projection chosen. Let's see what a projection is: In order to represent the curved surface of the Earth on a two-dimensional map, a map projection is needed. This conversion cannot be done without distortion. Therefore, there are many map projections available in Basemap, each with its own advantages and disadvantages. Specifically, a projection can be: equal-area (the area of features is preserved) conformal (the shape of features is preserved) No projection can be both (equal-area and conformal) at the same time. In this example, we have used a Lambert Conformal map. This projection requires additional parameters to work with. In this case, they are lat_1, lat_2, and lon_0. Along with the projection, we have to provide the information about the portion of the Earth surface that the map projection will describe. This is done with the help of the following arguments: Argument Description llcrnrlon Longitude of lower-left corner of the desired map domain llcrnrlat Latitude of lower-left corner of the desired map domain urcrnrlon Longitude of upper-right corner of the desired map domain urcrnrlat Latitude of upper-right corner of the desired map domain     The last two arguments are:   Argument Description resolution Specifies what the resolution is of the features added to the map (such as coast lines, borders, and so on), here we have chosen high resolution (h), but crude, low, and intermediate are also available. area_thresh Specifies what the minimum size is for a feature to be plotted. In this case, only features bigger than 10,000 square kilometer
Read more
  • 0
  • 0
  • 6072

article-image-unity-game-development-interactions-part-1
Packt
18 Nov 2009
8 min read
Save for later

Unity Game Development: Interactions (Part 1)

Packt
18 Nov 2009
8 min read
To detect physical interactions between game objects, the most common method is to use a Collider component—an invisible net that surrounds an object's shape and is in charge of detecting collisions with other objects. The act of detecting and retrieving information from these collisions is known as collision detection. Not only can we detect when two colliders interact, but we can also pre-empt a collision and perform many other useful tasks by utilizing a technique called Ray Casting, which draws a Ray—put simply, an invisible (non-rendered) vector line between two points in 3D space—which can also be used to detect an intersection with a game object's collider. Ray casting can also be used to retrieve lots of other useful information such as the length of the ray (therefore—distance), and the point of impact of the end of the line. In the given example, a ray facing the forward direction from our character is demonstrated. In addition to the direction, a ray can also be given a specific length, or allowed to cast until it finds an object. Over the course of the article, we will work with the outpost model. Because this asset has been animated for us, the animation of the outpost's door opening and closing is ready to be triggered—once the model is placed into our scene. This can be done with either collision detection or ray casting, and we will explore what you will need to do to implement either approach. Let's begin by looking at collision detection and when it may be appropriate to use ray casting instead of, or in complement to, collision detection. Exploring collisions When objects collide in any game engine, information about the collision event becomes available. By recording a variety of information upon the moment of impact, the game engine can respond in a realistic manner. For example, in a game involving physics, if an object falls to the ground from a height, then the engine needs to know which part of the object hit the ground first. With that information, it can correctly and realistically control the object's reaction to the impact. Of course, Unity handles these kinds of collisions and stores the information on your behalf, and you only have to retrieve it in order to do something with it. In the example of opening a door, we would need to detect collisions between the player character's collider and a collider on or near the door. It would make little sense to detect collisions elsewhere, as we would likely need to trigger the animation of the door when the player is near enough to walk through it, or to expect it to open for them. As a result, we would check for collisions between the player character's collider and the door's collider. However, we would need to extend the depth of the door's collider so that the player character's collider did not need to be pressed up against the door in order to trigger a collision, as shown in the following illustration. However, the problem with extending the depth of the collider is that the game interaction with it becomes unrealistic. In the example of our door, the extended collider protruding from the visual surface of the door would mean that we would bump into an invisible surface which would cause our character to stop in their tracks, and although we would use this collision to trigger the opening of the door through animation, the initial bump into the extended collider would seem unnatural to the player and thus detract from their immersion in the game. So while collision detection will work perfectly well between the player character collider and the door collider, there are drawbacks that call for us as creative game developers to look for a more intuitive approach, and this is where ray casting comes in. Ray casting While we can detect collisions between the player character's collider and a collider that fits the door object, a more appropriate method may be to check for when the player character is facing the door we are expecting to open and is within a certain distance of this door. This can be done by casting a ray forward from the player's forward direction and restricting its length. This means that when approaching the door, the player needn't walk right up to it—or bump into an extended collider—in order for it to be detected. It also ensures that the player cannot walk up to the door facing away from it and still open it—with ray casting they must be facing the door in order to use it, which makes sense. In common usage, ray casting is done where collision detection is simply too imprecise to respond correctly. For example, reactions that need to occur with a frame-by-frame level of detail may occur too quickly for a collision to take place. In this instance, we need to preemptively detect whether a collision is likely to occur rather than the collision itself. Let's look at a practical example of this problem. The frame miss In the example of a gun in a 3D shooter game, ray casting is used to predict the impact of a gunshot when a gun is fired. Because of the speed of an actual bullet, simulating the flight path of a bullet heading toward a target is very difficult to visually represent in a way that would satisfy and make sense to the player. This is down to the frame-based nature of the way in which games are rendered. If you consider that when a real gun is fired, it takes a tiny amount of time to reach its target—and as far as an observer is concerned it could be said to happen instantly—we can assume that even when rendering over 25 frames of our game per second, the bullet would need to have reached its target within only a few frames. In the example above, a bullet is fired from a gun. In order to make the bullet realistic, it will have to move at a speed of 500 feet per second. If the frame rate is 25 frames per second, then the bullet moves at 20 feet per frame. The problem with this is a person is about 2 feet in diameter, which means that the bullet will very likely miss the enemies shown at 5 and 25 feet away that would be hit. This is where prediction comes into play. Predictive collision detection Instead of checking for a collision with an actual bullet object, we find out whether a fired bullet will hit its target. By casting a ray forward from the gun object (thus using its forward direction) on the same frame that the player presses the fire button, we can immediately check which objects intersect the ray. We can do this because rays are drawn immediately. Think of them like a laser pointer—when you switch on the laser, we do not see the light moving forward because it travels at the speed of light—to us it simply appears. Rays work in the same way, so that whenever the player in a ray-based shooting game presses fire, they draw a ray in the direction that they are aiming. With this ray, they can retrieve information on the collider that is hit. Moreover, by identifying the collider, the game object itself can be addressed and scripted to behave accordingly. Even detailed information, such as the point of impact, can be returned and used to affect the resultant reaction, for example, causing the enemy to recoil in a particular direction. In our shooting game example, we would likely invoke scripting to kill or physically repel the enemy whose collider the ray hits, and as a result of the immediacy of rays, we can do this on the frame after the ray collides with, or intersects the enemy collider. This gives the effect of a real gunshot because the reaction is registered immediately. It is also worth noting that shooting games often use the otherwise invisible rays to render brief visible lines to help with aim and give the player visual feedback, but do not confuse these lines with ray casts because the rays are simply used as a path for line rendering. Adding the outpost Before we begin to use both collision detection and ray casting to open the door of our outpost, we'll need to introduce it to the scene. To begin, drag the outpost model from the Project panel to the Scene view and drop it anywhere—bear in mind you cannot position it when you drag-and-drop; this is done once you have dropped the model (that is, let go off the mouse). Once the outpost is in the Scene, you'll notice its name has also appeared in the Hierarchy panel and that it has automatically become selected. Now you're ready to position and scale it!  
Read more
  • 0
  • 0
  • 3522

article-image-archiva-team-part-1
Packt
18 Nov 2009
11 min read
Save for later

Archiva in a Team: Part 1

Packt
18 Nov 2009
11 min read
Roles and permissions In preparation for the latter sections of this article, let's familiarize ourselves with the user roles and permissions available in Archiva. The list of available roles can be seen by clicking a user account in User Management and then clicking on the Edit Roles link. Some of the roles in Archiva are resource-based with each repository treated as a resource. This means that access is controlled at the repository level. There are eight types of roles available in Archiva. They are: System Administrator: Provides access to Manage and Administration sections, user administration privileges, and read and write permissions to all repositories. User Administrator: Provides access to User Management and User Roles pages. Global Repository Manager: Provides read and write permissions to all repositories. Global Repository Observer: Provides read permission to all repositories. Repository Manager (resource level): Provides read and write permissions to a given repository. Repository Observer (resource level): Provides read permission to a given repository. Registered User: The default role assigned to a user who has registered in Archiva. Guest: Provides the same permissions that are enabled for the built-in guest user account, which we will discuss later on. A user assigned with a Global Repository Manager or resource level Repository Manager role automatically gains the Global Repository Observer or resource level Repository Observer role respectively. Users assigned with a Repository Manager role should be able to access the Find section as well as Upload Artifact and Delete Artifact menu in the web application. On the other hand, users with a Repository Observer role should only be able to access the Find section. Repository-level security applies to each corresponding operation. This means that a user will only be able to search, browse, and upload to or delete artifacts from those repositories that they have permission to access. When managing roles and permissions, another thing to take note of is the guest account. To enable access without authentication for a specific resource or operation, just assign the guest user the appropriate role. By default, the guest user is already assigned the Repository Observer role for internal and snapshots repositories. This allows anyone to be able to browse and search for artifacts from these repositories. If you edit the guest user account, you should be able to see the following configuration: As you can see the guest user doesn't yet have read access to the releases repository. In our examples, we will assume that the repository will be available to everyone that can access Archiva. So to make this consistent with the snapshots repository, check the Repository Observer box for releases and submit the form. You can see for yourself how the guest account works by logging out of Archiva and clicking Browse on the navigation menu. The artifacts that were requested and were downloaded to our proxy repository should be visible in the Browse page, similar to what is seen in the following screenshot: As we work through the rest of the article, we will cover a few more things about access control in Archiva. Now that we are familiar with the security basics, we are ready to tackle some of the more advanced features of Archiva. In the next section, we will learn techniques for configuring our Archiva repositories. Introducing repository groups In Archiva 1.1, the concept of repository groups (also known as virtual repositories) was introduced. Taking the meaning of the term virtual literally, these repositories are physically non-existent repositories. A virtual repository is simply a URL which gives a single interface to a group of managed repositories. Let's visualize this with a simple scenario. For example, we have a Maven 2 project which has dependencies on artifacts that reside in multiple repositories. In this case, we will assume that we have a nearby proxy cache configured in Archiva for each of them. Given this scenario, it would mean that we have to configure each of these repositories in our settings.xml (or POM), in order for us to get the needed artifacts and to be able to build our project. If these repositories are secured, we also need to configure our credentials for each. This leaves us with a long (and possibly messy) settings.xml. Remember, a messy configuration is an attraction for errors. To avoid this problem, we can make use of repository groups in Archiva. We can create a repository group and configure or add multiple repositories under that group. So when an artifact request is made (for example, by Maven) using the repository group URL, the repositories underneath it will be searched until the requested artifact is found and returned to the client. The following section teaches us how to configure repository groups and experience their strength first-hand. Configuring and using repository groups Before jumping into configuration, it is good to see how it will be without the aid of repository groups. As the Centrepoint project refers to the released version—POM Apache Maven 2: Effective Implementations Book, anyone who builds that project must be able to get the organization POM from the releases repository. This is a perfect setup for using repository groups. Let's begin by wiping out our local repository again and building the Centrepoint project. centrepoint$ mvn clean install The build should fail with the following error: [INFO] Scanning for projects...Downloading: http://localhost:8081/archiva/repository/internal/com/effectivemaven/effectivemaven-parent/1/effectivemaven-parent-1.pom[INFO] ----------------------------------------------------------[ERROR] FATAL ERROR[INFO] ----------------------------------------------------------[INFO] Failed to resolve artifact.GroupId: com.effectivemavenArtifactId: effectivemaven-parentVersion: 1Reason: Unable to download the artifact from any repository com.effectivemaven:effectivemaven-parent:pom:1from the specified remote repositories: internal (http://localhost:8081/archiva/repository/internal)   Our organization POM cannot be found because it resides in the Archiva releases repository, and we don't have it configured in our settings.xml. The version in ../effectivemaven-parent/pom.xml is also not used because the versions now differ. To get past this problem, we must add the following configuration in the settings.xml: <profiles> <profile> <id>repositories</id> <activation> <activeByDefault>true</activeByDefault> </activation> <repositories> <repository> <id>releases</id> <name>Archiva Managed Releases Repository</name> <url> http://localhost:8081/archiva/repository/releases </url> <releases> <enabled>true</enabled> </releases> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> </profile> </profiles> We already configured the <server> credentials for the releases repository when we tried deploying to Archiva using Maven so we no longer need to configure that. If you try building Centrepoint again, the build will still fail. Notice that Maven didn't even seem to try looking for the artifact from the releases repository we added previously. This is because we have locked down Maven to use only the local mirror repository internal. This is the effect of the <mirrorOf>*</mirrorOf> configuration in our settings.xml, Staying in Control with Archiva. Just change it to <mirrorOf>*,!releases</mirrorOf> so that Maven would respect the additional repositories. Execute the build again. This time we should be able to get a successful build. However, for every member of the team working on the Centrepoint project, the settings.xml (now over 40 lines long) is needed at the minimum. As the project grows bigger, more artifacts are added. Also, if these new artifacts are located in other repositories, you would need to add this repository to your settings.xml and so on and so forth. We already learned at the start of this section that in situations such as this, a repository group can make things easier for us developers. Let us see how we can create one. Let's go back to our running Archiva instance. Click Repository Groups, then type public in the Identifier field on the upper right-hand corner of the page and click Add Group. We now have a virtual repository named public with the following URL: http://localhost:8081/archiva/repository/public. You may change the name of the repository group to a more appropriate one if the repositories are not really for public consumption. To add managed repositories under the group, just select the repository you would like to add from the list under the created group and click Add Repository. Add the releases and internal repositories (this order is used so that requests for the organization's artifacts are never made on external proxied repositories). Note that we don't want to add the snapshots repository to the group as that might change the behavior of the repository. One example of this is when dealing with version ranges. You might end up getting a snapshot version instead of a released version. Now, with this configuration, we are telling Archiva that if an artifact request is made on the repository group public, it should look for the artifact in these two repositories (based on the order they are listed) and return the first matching artifact it sees. You can change the ordering of the repositories to be searched by moving a repository up or down the repository group configuration via the Up and Down icons. After configuration, the page should look similar to the following: Now that we have a repository group that we can use, let's configure it in our settings.xml. Remove the profile we added previously, and adjust the mirror section as follows: <mirrors> <mirror> <id>public</id> <url>http://localhost:8081/archiva/repository/public</url> <mirrorOf>*</mirrorOf> </mirror> </mirrors> Notice how much shorter and simpler our settings.xml is now. Group credentials The guest user has access to all of the repositories in the group so we don't need a corresponding <server> for the mirror. However, if read access control applies to any repositories in the group, make sure to add a <server> for the ID of the mirror (not the underlying repositories that are no longer visible to Maven). The existing <server> definitions continue to be used for deployment, as deployment cannot be done to a group. Let's try building Centrepoint again, but this time with a clean local repository, using the new settings.xml. We should be able to see both com.effectivemaven: effectivemaven-parent:pom:1 and the other dependencies from the central repository being retrieved from our public repository group, ending with a successful build as follows: [INFO] Scanning for projects...Downloading: http://localhost:8081/archiva/repository/public//com/effectivemaven/effectivemaven-parent/1/effectivemaven-parent-1.pom1K downloaded[INFO] Reactor build order:...[INFO] ----------------------------------------------------------[INFO] Building Centrepoint[INFO] task-segment: [clean, install][INFO] ----------------------------------------------------------Downloading: http://localhost:8081/archiva/repository/public//org/apache/maven/plugins/maven-clean-plugin/2.2/maven-clean-plugin-2.2.pom3K downloadedDownloading: http://localhost:8081/archiva/repository/public//org/apache/maven/plugins/maven-plugins/10/maven-plugins-10.pom What else can we do with repository groups? Consider, for example, that we added new dependencies to our Centrepoint project and these dependencies are projects being worked on by another team within the company. Let's say the other team have their own deployment repository (separate from ours) managed by Archiva as well. We no longer have need to make any changes in our settings.xml (or POM). The repository just needs to be added in the public repository group and the appropriate permissions assigned to the Centrepoint project developers' accounts. Configuration is much simpler now and is concentrated in Archiva itself. Developers and team members won't have to configure their settings.xml each time a new repository is needed.   RSS feeds—discovering new artifacts in your repository RSS has become the de facto standard with regard to news feeds and updates on the web. The Archiva community has seen how the project can take advantage of this current trend by providing RSS feeds for new artifacts in the repository. Projects that use or depend on specific libraries would be able to know when a new release is available or when there is a new build. This is especially useful when a project is dependent on a fix that would be available in the next release or in the next build. A Repository Observer role is required at least in order to subscribe to a feed in Archiva. There are two levels of RSS feeds available in Archiva: repository level and artifact level. In the following sections, we will be using Thunderbird's RSS feed reader for demonstration purposes. You can get Thunderbird from http://www.mozillamessaging.com/en-US/thunderbird/ and can set it up using the installation guides at http://www.mozillamessaging.com/en-US/support/. You can also use other RSS feed readers such as Google Reader. If access to your repositories require authentication, your feed reader must support authentication. If security is lenient, you can just disable authentication for read operations to your repository by granting the guest account the Repository Observer role.
Read more
  • 0
  • 0
  • 1856

article-image-version-management-upk-35-part-1
Packt
18 Nov 2009
12 min read
Save for later

Version Management with UPK 3.5: Part 1

Packt
18 Nov 2009
12 min read
Though this implies multi-user environment client/server setup, this article could still be of use to a single user. If you are a lone developer working in a stand-alone environment (sometimes referred to as a single-user environment), you may want to just skip straight to the section Exporting and importing content, at the end of this article. Sorry, but version management in a stand-alone environment is almost nonexistent, so you're largely on your own. In a client/server environment, all content objects are stored on a central server. Developers create and edit content on their own workstation (typically, a PC), and then send this content to a database on the central server for storage when they have finished with it. This is referred to as checking in a content object. If they subsequently want to change a content object that is on the server, they need to check out the content object, change it, and then check it back in. Checking in a content object When you create a content object in a client/server environment, the content object is stored in your local repository (that is, on the client side of the client/server set-up). It is important to understand that your local repository is located on your local workstation. This means that if you have a content object in your local repository, and then move to another workstation, you will not see your local version of this content object on the new workstation. This is because they are located on the workstation on which you created them or checked them out. You should, therefore, always use the same workstation, or check in all of your content objects before moving to a new workstation. Version Difference In UPK 3.5.1 client/server edition, it is possible to choose a specific location for your local repository. Documents that are checked out to your local repository are identified by a green check-mark () to the left of the object details in the Library. You will need to check these objects in if you want them to be stored in the central library so they will be accessible to other developers. Generally, you should do this whenever you have finished working on a content object. However, there are good reasons for checking in objects more frequently. Your local repository is (typically) in the C: drive of your computer, whereas the central library is on a central server. Unless you are very fastidious about backing up your PC, the chances are that the server is backed up more often than your PC, and is usually backed up automatically. Placing your files in the central library will, therefore, provide greater security in terms of having a backup that you can revert to in the event of a disaster. In addition to this, whenever you check in a content object, a back-up of the previous version is taken. Should you need to back out your changes, you can simply revert to a back-up version of the content object. Related to this, content objects are never really deleted from the server library. Actually, they can be deleted, but only by an Administrator, and typically as part of a cleanup. However, if you delete an object (that has never been checked in to the central server) from your local repository, it is gone. Forever! Finally, it is not unheard of that for a local repository to simply disappear when UPK crashes (which thankfully doesn't happen that often, but it has been known to happen). If this does happen to you, then you may again lose all of the content that you currently have checked out even though the Lost documents view, introduced in UPK 3.5, may save you. For all of these reasons, and more, it is recommended that you check in all of the content that is stored in your local repository to the server at least at the end of each work day. Fortunately, UPK provides a quick way of doing this. If you click the Check In All button (), then all of the content objects that you currently have checked out will be checked in again. The downside of this is that if you do check in all of the documents that you are currently working on at the end of the day, you need to remember which objects these are so that you can check them out again the next day. Before checking the documents in, you can use the All Checked Out view to identify all of the documents that you currently have checked out. You can then print this list, and will know which files you need to check out again the next day. There is one further thing to bear in mind when deciding how often you are going to check in your content objects. As mentioned above, UPK retains every version of a content that has been checked in. These are accessible via the Document History, as we will see later. This means that if you check in a content object ten times, then UPK will retain ten versions of it. This can also make it difficult to identify the "released" versions of the content object in the Document History, should you subsequently need to roll back to the last-released version. The Administrator can clean up the database periodically, but the only way of differentiating between versioned drafts and versioned released content objects is by using the check-in comments. These are explained in the section Step 2: Confirming the scope of the check-in, ahead. UPK Workflow The down-side to checking in content objects that you may not have finished working on is that these objects could be mis-perceived as being final, and actually used or published. In some cases, you may have checked some of them out not because you want to change them, but specifically to stop anyone else from changing them. UPK does not provide you with a simple, automatic solution to these shortcomings, but there is a manual workaround that you can use. This is to use the Workflow properties of the objects. UPK does not have a "real" workflow, it does not have "routing" of content objects based on their status, or automatic email notification of content objects that are due for review, or any of the things that you'd expect from workflow functionality. Of course users can use a Custom View to display content objects according to their Workflow properties, but this is still not really "workflow". If you display the Properties for a content object, by clicking on the Properties button (), the last category of properties (at the end of the Properties list) is the Workflow category. Within this, there are two properties: Assigned To: This property allows you to select (from a drop-down list) the user ID of any developer who is authorized to access the content object. If you select your own user ID in this field, then this is an indication to the other developers that they should not work on this content object themselves. State: This property can be used to specify the current status of a content object. The default values are (blank), Not Started, Draft, In Review, and Final. If you select a status of Draft, then this is an indication that you have not finished with the object. An example of the Properties pane, showing the Workflow category, is in the following screenshot: Of course, these Properties do not provide "hard checks". You still rely on people seeing, and then paying attention to, these Properties but it is a start. Some strong guidance from your Project Manager or Team Leader would help, here. Administrators can add, remove, or rename statuses. It is recommended that a suitable set of statuses are established and defined prior to any development work starting, and that these statuses and their meaning are communicated to all developers. Step 1: Selecting the content objects To select content objects for checking in, carry out the steps described below: In the Library, select the content objects that you want to check in. Normally, you will want to check in specific content objects, so you would only select these. As always, you click on a content object to select it. You can Ctrl-click to select multiple objects, or Shift-click to select a series of objects. You can also select a folder in the Library to check in all of the content objects in that folder. Do not worry if some of the objects that are included in your selection are not checked out; UPK will simply ignore these objects during check-in (it will not "error-out"). You can also check in content objects by selecting them in an Outline Element. Once you have selected all of the content objects that you want to check in, click the Check In button (). Step 2: Confirming the scope of the check-in When you check in one or more specific content objects and have not selected a folder in the Library to check in, UPK will automatically check for any content objects that are related to the object that you are checking in. You will be prompted to check these in, as well. An example of this prompt is shown in the following screenshot: What are related documents? In general, they are Web Pages and Packages used by the content object that you are checking in. For example: If you have created, or changed, an Outline Element (Module or Section) then UPK will automatically select all of the content objects (Modules, Lessons, and Topics) included in this Outline Element, along with any Web Pages used by any of these content objects will be selected as well. If you are checking in a Topic for which you have also created a Web Page that is linked to the Concepts pane, then UPK will automatically select this Web Page as a related document during check-in. If you have created a Glossary and are checking this in, the related documents will be all of the Web Pages for the content definitions used by the Glossary. An example of the Related Documents dialog box is shown in the following screenshot: This list of related documents can be confusing, as it does not match the list that you see in the Related Documents pane for the content object that you are checking in. The list will include Web Pages that have been explicitly linked to from the content object that you are checking, but will not include Glossaries, Templates, Packages, or icons, all of which are listed in the Related Documents pane. This limitation is important to understand. If you checked out, and updated, a Glossary and as a result UPK checked out several content objects during the glossary link regeneration, UPK will not identify all of the Glossary elements (Web Pages) as "related documents". You will need to locate these and check them in separately using custom views. Adding to the confusion, the list of related documents will include all of the explicitly-linked content objects, and not only those objects that are currently checked out to you. Do not worry about this – UPK will only physically check in the content objects that you do have checked out (these are the ones that have your User ID in the Checked Out To column of the Related Documents dialog box). In the example above, we are checking in an Outline Element that contains one Topic, which in turn contains a Web Page. The Topic is checked out, but the Web Page is not. Step 3: Specifying a reason for the change When you check in one or more content objects, you will be prompted to enter a short description of the change, as shown in the following screenshot: The title of the content object that you are checking in is shown above the comment text box. If you are checking in multiple content objects, then this will initially specify the first object and (assuming that you deselect the Apply same comments to all documents option) will specify the next object when you click OK. It then moves on to the next object. In this way, you can provide separate comments for each content object, even though you are checking them all in at the same time. Although it is entirely optional, it is a very good practice to always enter a comment. This comment will appear in the object History, and therefore serves as a useful audit log. Specify a reason for the change by carrying out the steps described below: Enter a suitable comment in the space provided. Note that you do not need to specify the date and time of the change, or your user ID. These are captured automatically by UPK. If you are checking in multiple objects, then UPK will initially suggest applying the same comments to all of the objects. You will see that the Apply same comments to all documents checkbox toward the bottom of the dialog box is selected. If you do not want to use the same comment for all objects that you are checking in, then deselect this checkbox. Now, when you click on OK, the Check In Comment dialog box for the next content object in the check-in selection will be displayed. You can repeat the above processing from Step 3. Once you have entered your description of the change (or reason for the change), click on OK. Once you have specified a comment, and clicked on OK for the last time, then the content objects are checked in, and the Library screen is redisplayed.  
Read more
  • 0
  • 0
  • 1800

article-image-customizing-document-joomla-15-part-2
Packt
18 Nov 2009
3 min read
Save for later

Customizing the Document with Joomla! 1.5: Part 2

Packt
18 Nov 2009
3 min read
Creating a PDF in a component This recipe explains how to create a PDF view in a Joomla! MVC component. Adding PDF views is a relatively quick process, and it significantly improves the functionality of a component. Getting ready Like any other view format, we must create a new JView subclass to create a PDF view. This should be located in the corresponding view's folder and the file should be named view.pdf.php. For example, for the myview view in the mycomponent component, we create the components/com_mycomponent/views/myview/view.pdf.php file, in which we place the MycomponentViewMyview class, which extends JView. How to do it... The first thing we do is override the display() method in order to change the PDF document. We modify the document using the mutator methods. The first method changes the document title, this is the title normally shown in the title bar of the PDF viewer. $document->setTitle($title); The next method changes the filename. This is especially useful if the user is likely to save the file, as this will be the default name the user is prompted to save the file as. $document->setName($filename); The next method sets the document description, sometimes referred to as the subject. This should only be a very brief description of the document. $document->setDescription($description); The next method sets the document metadata. Currently, only keywords are supported. It is possible to set other metadata, but it will not be used in the document. $document->setMetaData('keywords', $keywords); So far, all of the methods do not print anything to the body of the PDF itself. The next method adds a common header to every page. Note that the header text itself is not formatted. $document->setHeader("My PDF Document TitlenMy Subtitle"); Lastly, we can add content to the main body of the PDF document. We achieve this in the normal way by simply outputting the content. echo 'This is my PDF! '; The outputted data can be formatted using some basic HTML tags. The following tags are supported: Type Tags Format <b>, <u>, <i>, <strong>, <em>, <sup>, <sub>, <small>, <font> Heading <h1>, <h2>, <h3>, <h4>, <h5>, <h6> Indentation <blockquote> Linked <a>, <img> List <ol>, <ul>, <li> Spacing <p>, <br>, <hr> Table <table>, <tr>, <td>, <th>
Read more
  • 0
  • 0
  • 1548
Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at €18.99/month. Cancel anytime
article-image-processing-twitter-and-new-york-times-apis-aspnet-ajax-microsoft-cdn
Packt
18 Nov 2009
7 min read
Save for later

Processing Twitter and New York Times APIs with ASP.NET Ajax on Microsoft CDN

Packt
18 Nov 2009
7 min read
APIs (Application Programming Interface) are application-to-application programming interfaces that support harvesting information on the web using the known web standards. These APIs are provided by the entities who wish to expose parts of their resources that a third party can use. The APIs run transparent to the user and exposes just what they want to expose, with some providing access to material for public consumption with others giving access to resources based on authentication. In a sense they may be called a basic form of SAAS. Amazon.com, Google etc have exposed their APIs for some time. Twitter and New York Times have also exposed their API's which can be used to do some digging into the information contained in them, a kind of web mining. Many others such as Netflix have provided their own APIs described on their web sites. What is Twitter API? Twitter API is provided by the Social Networking and Micro-blogging service. Twitter API adheres to the web standards and one can talk to Twitter using HTTP. You can just about access anything on the Twitter web site. One example of creating a Microsoft SQL Server Report using Twitter API is available here - Tweets with Reporting Services, wherein the response from the Twitter API was in XML format. JSON (JavaScript Object Notation) is another format in which data is returned when an API call is made. In this article we will be looking at API call that returns a JSON response. Twitter exposes a large number methods through their API's such as API's for Search, Timeline, Status, User, Direct Message, Friendship and many more. As previously mentioned the responses will be in XML or JSON. Also while some APIs may take parameters others may not. The Twitter API used in this tutorial We will be looking at trends in Twitter API exposed by the url, http://search.twiiter.com/trends.format. We will be using the GET method and we will expect a JSON response. Since the volume of traffic may overwhelm, the calls that you can make to this in an hour are limited (also known as rate limiting) but not critical for the demo in this tutorial. Here is a typical call to the trends method on the Twitter API. Herein we will search for trends on the Twitter site and expect a response in JSON, if we use json instead of Format in the next URL address. Instead of:http://search.twitter.com/trends.Formattype-in, the following for URL address,http://search.twitter.com/trends.json When you plug the above in a web Brower you would get a response trends.json which you may save to your hard drive or, use it in any way you like. The next quoted text is what you get in response (note that this is what I got on Saturday 31, 2009 and what you get will be different), the content of the file trends.json you saved to your computer. Note that presently you get about top ten trends from this API call. {"as_of":"Sat, 31 Oct 2009 20:44:46 +0000","trends":[{"name":"Happy Halloween", "url":"http://search.twitter.com/search?q=%22Happy+Halloween%22+OR+%22Feliz+ Halloween%22"},{"name":"#nxzerosetechaves","url":"http://search.twitter.com/search?q=%23nxzerosetechaves"},{"name":"Danyl","url":"http://search.twitter.com/search?q=Danyl"},{"name":"#HappyHalloween","url":"http://search.twitter.com/search?q=%23HappyHalloween"},{"name":"#potterday","url":"http://search.twitter.com/search?q =%23potterday"},{"name":"X Factor","url":"http://search.twitter.com/search?q=%22X+ Factor%22"},{"name":"It's Halloween","url":"http://search.twitter.com/search?q=%22It %27s+Halloween%22+OR+%22Its+Halloween%22"},{"name":"Trick","url":"http://search.twitter.com/search?q=Trick+OR+%23trick"},{"name":"Paranormal Activity","url":"http://search.twitter.com/search?q=%22Paranormal+Activity%22"},{"name":"This Is It","url":"http://search.twitter.com/search?q=%22This+Is+It%22"}]} First of all what you see returned is a JSON object. If you are new to JSON review this article on my blog. The various elements that you see such as 'name', 'url' etc are fields in the response that are all described in the API documentation(look for Return Values). Some of the API calls can return a ton of information and you will have to know the API method so that you can correctly parse this data. Another thing you would notice is that the JSON object you get out is a nested object with many levels. You may need a JSON Parser to get a clearer picture of this nesting and I recommend using the online parser at this site. Using the above site, the JSON Object would appear as shown (only a portion is shown). New York Times API New York Times made available to the developers sometime in the middle of October 2008 APIs that can search New York Times for various kinds of information . Just like in Twitter there are a large number of APIs that you can use such as: Article Search; Best Sellers; Campaign Finance; Congress; and many others. Interested users can get on to this resource by signing up here requesting what APIs they would like to use. After signing up, New York Times would provide keys for the APIs that you want to access. It is important therefore, that the call should include the keys provided to you. For example, I received keys to access the following resources: Movie Reviews, Article Search, Best Sellers and Times Newswire. The key for the Movies Reviews API appears as shown here (the one shown here has been doctored and will not work). Movie Reviews API Key: b57378910b9fd80ecc73461547c93e8a:10:50673441 Using the New York Times API It is a valuable resource since you can get for example with the Article Search API access to more than 2.8 million articles from 1981. Using this is quite simple, just paste the URL shown below into the address box of your browser. Note that the key shown here is fake (but of correct format). http://api.nytimes.com/svc/search/v1/article?query=India&facets=publication_year&api-key=6c208890a4880093c30020be8fe17a40:0:50633441 This will display in the browser the JSON object that is returned as shown. You can use the previously mentioned site to parse it for more friendly display. {"facets" : {"publication_year" : [{"count" : 2724 , "term" : "2008"} , {"count" : 2345 , "term" : "2006"} , {"count" : 2311 , "term" : "2009"} , {"count" : 2282 , "term" : "2007"} , {"count" : 2144 , "term" : "2002"} ,{"count" : 2111 , "term" : "2001"} , {"count" : 1988 , "term" : "2005"} , {"count" : 1951 , "term" : "2004"} , {"count" : 1921 , "term" : "1985"} , {"count" : 1798 , "term" : "2003"} , {"count" : 1761 , "term" : "1999"} , {"count" : 1720 , "term" : "2000"} , {"count" : 1642 , "term" : "1998"} , {"count" : 1442 , "term" : "1984"} , {"count" : 1382 , "term" : "1986"}]} , "offset" : "0" , "results" : [{"body" : "BARSUR, India — At the edge of the Indravati River, hundreds of miles from the nearest international border, India effectively ends. Indian paramilitary officers point machine guns across the water. The dense jungles and mountains on the other side belong to Maoist rebels dedicated to overthrowing the government. "That is their liberated" , "byline" : "By JIM YARDLEY" , "date" : "20091101" , "title" : "Maoist Rebels Widen Deadly Reach Across India" , "url" : "http://www.nytimes.com/2009/11/01/world/asia /01maoist.html"} ,.........(there is more of this but abbreviated here) Response Format As you can see the responses to the API calls return JSON objects in general of the form shown belo w (this one is of the form returned by the Twiiter API). What we propose to do is to use jQuery's GetJSON() method to get the JSON Objects and use Microsoft AJAX JavaScript files to display the data on the web page. Both jQuery javascript files and Microsoft ASP.NET AJAX files are both available on the Microsoft ECN (CDN). The GetJSON() method as well as the Microsoft ASP.NET AJAX templates can be easily implemented in the Visual Studio 2008 IDE. Alternatively Microsoft AJAX can also be used to retrieve data from the web sites. In this article the GetJSON() method will be used. {"x":{"y":[{"a1":"b1", "c1":"d1"}, {"a2":"b2", "c2":"d2"}]},.... "f":"g",....}
Read more
  • 0
  • 0
  • 3838

article-image-integrating-websphere-extreme-scale-data-grid-relational-database-part-2
Packt
18 Nov 2009
6 min read
Save for later

Integrating Websphere eXtreme Scale Data Grid with Relational Database: Part 2

Packt
18 Nov 2009
6 min read
Removal versus eviction Setting an eviction policy on a BackingMap makes more sense now that we're using a Loader. Imagine that our cache holds only a fraction of the total data stored in the database. Under heavy load, the cache is constantly asked to hold more and more data, but it operates at capacity. What happens when we ask the cache to hold on to one more payment? The BackingMap needs to remove some payments in order to make room for more. BackingMaps have three basic eviction policies: LRU (least-recently used), LFU (least-frequently used), and TTL (time-to-live). Each policy tells the BackingMap which objects should be removed in order to make room for more. In the event that an object is evicted from the cache, its status in the database is not changed. With eviction, objects enter and leave the cache due to cache misses and evictions innumerable times, and their presence in the database remains unchanged. The only thing that affects an object in the database is an explicit call to change (either persist or merge) or remove it as per our application. Removal means the object is removed from the cache, and the Loader executes the delete from SQL to delete the corresponding row(s) from the database. Your data is safe when using evictions. The cache simply provides a window into your data. A remove operation explicitly tells both ObjectGrid and the database to delete an object. Write-through and write-behind Getting back to the slow down due to the Loader configuration, by default, the Loader uses write-through behavior: Now we know the problem. Write-through behavior wraps a database transaction for every write! For every ObjectGrid transaction, we execute one database transaction. On the up side, every object assuredly reaches the database, provided it doesn't violate any relational constraints. Despite this harsh reaction to write-through behavior, it is essential for objects that absolutely must get to the database as fast as possible. The problem is that we hit the database for every write operation on every BackingMap. It would be nice not to incur the cost of a database transaction every time we write to the cache. Write-behind behavior gives us the help we need. Write-behind gives us the speed of an ObjectGrid transaction and the flexibility that comes with storing data in a database: Each ObjectGrid transaction is now separate from a database transaction. BackingMap now has two jobs. The first job is to store our objects as it always does. The second job is to send those objects to the JPAEntityLoader. The JPAEntityLoader then generates SQL statements to insert the data into a database. We configured each BackingMap with its own JPAEntityLoader. Each BackingMap requires its own Loader because each Loader is specific to a JPA entity class. The relationship between JPAEntityLoader and a JPA entity is established when the BackingMap is initialized. The jpaTxCallback we specified in the ObjectGrid configuration coordinates the transactions between ObjectGrid and a JPA EntityManager. In a write-through situation, our database transactions are only as large as our ObjectGrid transactions. Update one object in the BackingMap and one object is written to the database. With write-behind, our ObjectGrid transaction is complete, and our objects are put in a write-behind queue map. That queue map does not immediately synchronize with the database. It waits for some specified time or for some number of updates, to write out its contents to the database: We configure the database synchronization conditions with the setWriteBehind("time;conditions") method on a BackingMap instance. Programmatically the setWriteBehind method looks like this: BackingMap paymentMap = grid.getMap("Payment");paymentMap.setLoader(new JPAEntityLoader());paymentMap.setWriteBehind("T120;C5001"); The same configuration in XML looks like this: <backingMap name="Payment" writeBehind="T120;C5001"pluginCollectionRef="Payment" /> Enabling write-behind is as simple as that. The setWriteBehind method takes one string parameter, but it is actually a two-in-one. At first, the T part is the time in seconds between syncing with the database. Here, we set the payment BackingMap to wait two minutes between syncs. The C part indicates the number (count) of changes made to the BackingMap that triggers a database sync. Between these two parameters, the sync occurs on a whichever comes first basis. If two minutes elapse between syncs, and only 400 changes (persists, merges, or removals) have been put in the write-behind queue map, then those 400 changes are written out to the database. If only 30 seconds elapse, but we reach 5001 changes, then those changes will be written to the database. ObjectGrid does not guarantee that the sync will take place exactly when either of those conditions is met. The sync may happen a little bit before (116 seconds or 4998 changes) or a little bit later (123 seconds or 5005 changes). The sync will happen as close to those conditions as ObjectGrid can reasonably do it. The default value is "T300;C1000". This syncs a BackingMap to the database every five minutes, or 1000 changes to the BackingMap. This default is specified either with the string "T300;C1000" or with an empty string (" "). Omitting either part of the sync parameters is acceptable. The missing part will use the default value. Calling setWriteBehind("T60") has the BackingMap sync to the database every 60 seconds, or 1000 changes. Calling setWriteBehind("C500") syncs every five minutes, or 500 changes. Write-behind behavior is enabled if the setWriteBehind method is called with an empty string. If you do not want write-behind behavior on a BackingMap, then do not call the setWriteBehind method at all. A great feature of the write-behind behavior is that an object changed multiple times in the cache is only written in its final form to the database. If a payment object is changed in three different ObjectGrid transactions, the SQL produced by the JPAEntityLoader will reflect the object's final state before the sync. For example: entityManager.getTransaction().begin();Payment payment = createPayment(line, batch);entityManager.getTransaction().commit();some time later...entityManager.getTransaction().begin();payment.setAmount(new BigDecimal("44.95"));entityManager.getTransaction().commit();some time later...entityManager.getTransaction().begin();payment.setPaymentType(PaymentType.REAUTH);entityManager.getTransaction().commit(); With write-through behavior, this would produce the following SQL: insert into payment (id, amount, batch_id, card_id, payment_type) values (12345, 75.00, 31, 6087, 'AUTH');update payment set (id, amount, batch_id, card_id, payment_type) values (12345, 44.95, 31, 6087, 'AUTH') where id = 12345;update payment set (id, amount, batch_id, card_id, payment_type) values (12345, 44.95, 31, 6087, 'REAUTH') where id = 12345; Now that we're using write-behind, that same application behavior produces just one SQL statement: insert into payment (id, amount, batch_id, card_id, payment_type) values (12345, 44.95, 31, 6087, 'REAUTH');
Read more
  • 0
  • 0
  • 2427

article-image-most-wanted-apache-myfaces-trinidad-12-tags-and-tag-attributes
Packt
18 Nov 2009
6 min read
Save for later

Most Wanted Apache MyFaces Trinidad 1.2 Tags and Tag Attributes

Packt
18 Nov 2009
6 min read
Component library structure Trinidad's approach to web technology is comprehensive: Aimed at full control of all the bits and pieces that make up a web application, little should be left that needs to be added. So based on such a closed world, Trinidad presents itself with a wealth of components and tags that even include very basic XHTML tags as replacements for the real XHTML originals. This is no radical replacement approach, rather it enables Trinidad to remain in full control of mechanisms such as partial-page rendering (PPR, also generally known as Ajax) that otherwise would need to deal with potentially incompatible libraries externally. The following image provides an outline of Trinidad's structural package design: Trinidad is divided into the following two namespaces: tr: It is the usual tag library id that references Trinidad's core library tags. It's a large library of over 100 components ranging from layout components and navigational components, to special viewer components that all implicitly support skinning, partial-page rendering, popup dialogs, error or info messaging, and so on. trh: It is the usual tag library id that references Trinidad's XHTML support library tags, a small companion that offers alternatives for those XHTML tags that are usually applied to build XHTML structures, for example, XHTML tables. Let us take a closer look at both namespaces. The upcoming image shows the core API's hierarchical structure. The tags are backed by two types of Trinidad classes—UIX* classes that deal with the JSF component requirements to implement specific JSF lifecycle processing methods, and Core* classes that deal with the specific properties (getters or setters). Trinidad’s XHTML tag library namespace (trh) Two groups can be distinguished from the trh namespace. The first one deals with the definition of an XHTML page and provides the developer with the following tags: <trh:html>: It is used to define the whole XHTML page, analogous to <html> <trh:head>: It is used to define the header, analogous to <head> <trh:body>: It is used to define the main contents, analogous to <body> <trh:script>: It is used to define a JavaScript to be executed, analogous to <script> <trh:tableLayout>: It is used to define an XHTML table. <trh:rowLayout>: It is used to define an XHTML table line, analogous to <tr>; note that it can also be used to display an arbitrary line, particularly when elements need to be kept in one and the same line. Alternatively, it is particularly interesting to look at the tr namespace as it provides some less heavy structures free from table constructions, for instance panelGroupLayout with a layout set to vertical or a panelBorderLayout, both generating div structures instead. <trh:cellFormat>: It is used to define an XHTML table cell as part of an XHTML table. The attributes of each tag are defined in a most consistent, and thus recognizable way. By the way, there are also tags for the construction of framesets such as trh:frame in case anyone still wants to make use of framesets. However, before we deal with the attributes let us conclude this structural overview by a look at the organization of the functionality of the core tag library. Trinidad’s core tag library namespace (tr) The following groups can be functionally distinguished which is also reflected in the packages structure of Trinidad's API (all beginning with org.apache.myfaces.trinidad.component; which has been left out here to avoid repetition). Note that, for completeness, we will also include information on the pure Java side as well as information on the few components that stem from the trh namespace: Basic document composition tags from the core API: document, stylesheet, form, subform. poll also appears here although it is not a composition tag. Form input and display tags, components from the core.input API: inputText, inputDate, inputListOfValues, and so on. Command or navigation tags from core.nav that includes two tag types: One that is focused on command tags that assumes a given form, presupposing the use of form and display tags from the foregoing group—commandButton, commandLink, goButton, goLink, and so on. The other deals exclusively with navigation: navigationTree, navigationPane, breadCrumbs, and so on. Large input and output component tags from core.data, for example, table, tree, and treeTable components. Layout component tags from core.layout, for example, all the swing-like panel tags, such as panelBorderLayout, panelHorizontalLayout, panelAccordion, showDetail, showDetailItem, and so on. Basic output components from core.output that are almost always used in a web application, for example, messages, outputText, outputLabel, spacer, statusIndicator, and so on. Model objects from core.model devised for various tags ; they provide the corresponding view models for their tag viewer counterparts, for example, SortableModel, CollectionModel and RowKeySet for tr:table, ChildPropertyTreeModel for tr:tree and ChartModel for tr:chart. A couple of converter components from trinidad.convert equip JSF and Trinidad input components with powerful JSF conversion, that is, convertNumber and convertDateTime. Validator components from trinidad.validator equip JSF and Trinidad input components with powerful JSF validation such as range validation (validateDateTimeRange) and validation by regular expression match (validateRegExp). Events and event listeners from trinidad.event add new event types and listeners specific for Trinidad components such as those that support Trinidad's dialog framework, for example, commandButton to launch a popup dialogue using LaunchEvent, ReturnEvent, and ReturnListener. It provides only a few tags, but these can be very utile, for example, fileDownloadActionListener, resetActionListener, returnActionListener, and setActionListener. There is a lot more to be found on the pure Java API side that either surfaces indirectly on the tag library as attributes, or is used implicitly by the tags themselves. Furthermore, there are utility classes and context support classes—RequestContext being probably the most prominent one because it offers a lot of functionality, for example, PPR from the server side. The following figure illustrates the Java side of things (it shows what the structure of some of the classes behind core.input look like): The preceding figure is an outline of the core.input API hierarchy. Again, we can see the typical UIX* and Core* structure. Finally, let us take a closer look at the tag attributes.
Read more
  • 0
  • 0
  • 1913

article-image-joomla-flash-flashy-templates-headers-banners-and-tickers-part-1
Packt
18 Nov 2009
4 min read
Save for later

Joomla! with Flash: Flashy Templates, Headers, Banners, and Tickers: Part 1

Packt
18 Nov 2009
4 min read
In this article, we will mainly focus on the visual design of our site. To acquire the information presented here, it is assumed that you have some basic understanding of Joomla!'s visual design including templates, components, module position, and so on. Adding Flash in templates If you are familiar with Joomla! templates, then you will understand that there are two ways to display Flash in a template: By hardcoded embedding of Flash items By dynamically loading Flash objects at module positions We have seen many modules that can display Flash objects. Therefore, in this section, we will be looking into the embedding of Flash objects within templates. It will also be helpful if we understand the structure of Joomla! templates. Generally templates for Joomla! include headers in Flash. Flash animations are included in the header area of a Joomla! template. Some templates include the mechanism to show images from a specific directory. For example, the template shown in the following screenshot, available for download at http://joomlatp.com/joomla-1.5-templates/Templates-has-flash-header.html, is designed to show a Flash header comprised of the images kept in a directory: The following sections briefly describe the structure of a Joomla! template and the ways to embed a Flash object in this template. Structure of a Joomla! template The look and feel of Joomla! is determined by templates. You can apply a template to the frontend as well as to the backend. Templates for the Joomla! frontend reside in the /templates directory of the Joomla! webroot, while those for the administration panel are found in the /administrator/templates directory. You can install multiple templates and apply one or more templates to the different sections. However, you must designate one default template for the site. To designate a default template, go to Extensions | Template Manager. Select the desired template and click on the Default button on the toolbar. For assigning a template to a specific section of the site, click on a template, except the default template, and then select the section or the menu item for which you want to assign the template from the Menu Assignment section. If you examine the directory structure of a Joomla! template, you will find at least the following subdirectories in the templates directory: Directory Description mx_joofree2 This is the main template directory. It contains some subdirectories and at least the following files under its root: index.php: This is the main file for a template. The basic structure of a Joomla! template is defined in this file. We will examine this file later. templateDetails.xml: This XML file defines the template by mentioning its designer, the different files bundled with it, the positions and parameters available, and so on. params.ini: This file contains the parameters and their default values. For example, a template may use several colors for theming, but users can select a preferred color as a parameter for this template, and that information is stored in this file. mx_joofree2/css This directory contains all the cascading stylesheets to be used for a Joomla! site. This directory will contain at least one stylesheet named template_css.css. It may also contain a stylesheet named template_ie6.css and other stylesheets. mx_joofree2/html This folder may contain some definitions for the custom rendering of certain parts of the site. For example, the mx_joofree2 template contains two files-module.php and pagination.php. These two files define custom module rendering and pagination for Joomla!. For more information on using HTML overrides, refer to http://docs.joomla.org/How_to_override_the_content_from_the_Joomla!_core. mx_joofree2/images This folder contains the images for the template. It may contain a logo image, a background image, and so on. It may also contain some subdirectories, for example, the mx_joofree2 template contains a subdirectory images/headers, where the header images for the template are stored.
Read more
  • 0
  • 0
  • 3098
article-image-datagrid-api-ibm-websphere-extreme-scale-6-part-1
Packt
18 Nov 2009
19 min read
Save for later

The DataGrid API with IBM WebSphere eXtreme Scale 6: Part 1

Packt
18 Nov 2009
19 min read
In a client-server ObjectGrid interaction, local ObjectGrid instances run in the same memory process as the business application. Access to objects stored in the grid is extremely fast, and there are no network hops or routing done on ObjectGrid operations. The disadvantage with a local ObjectGrid instance is that all objects stored in the grid must fit into the heap space of one JVM. The client-server distributed ObjectGrid instances overcomes that single heap space disadvantage by combining the resources of multiple JVMs on multiple servers. These combined resources hide behind the façade of an ObjectGrid instance. The ObjectGrid instance has far more CPU, memory, and network I/O available to it than the resources available to any single client. In this article, we'll learn how to use those resources held by the ObjectGrid instance to co-locate data and business logic on a single JVM. The client-server model relies on a client pulling objects across a network from an ObjectGrid shard. The client performs some operations on those objects. Any object whose state has changed must be sent back across the network to the appropriate shard. The client-server programming model co-locates data and code by moving data to the code. The data grid programming model does the opposite by moving code to the data. Rather than dragging megabytes of objects from an ObjectGrid shard to a client, only to send it right back to the ObjectGrid, we instead send our much smaller application code to an ObjectGrid shard to operate on the data in place. The end result is the same: code and data are co-located. We now have the resources of an entire data grid available to run that code instead of one client process. What does DataGrid do for me? The DataGrid API provides encapsulation to send application-specific methods into the grid and operate directly on the objects in shards. The API consists of only five public classes. These five classes provide us with several patterns to make an ObjectGrid instance do the heavy lifting for a client application. The client application did a lot of work by operating on the objects in the grid. The client requires a network hop to get an object from the grid and performs an operation on it, persisting that the object requires another network hop to the grid. In a single client environment, the probable bottlenecks in dealing with ObjectGrid are all on the client side. A single client will not stress the resources in the ObjectGrid deployment. The client application is most likely the bottleneck. With all computers in a deployment being equal, one client application on one computer will not stress the combined resources of the grid. In a naïve application that performs single object get and put operations, our application will first notice a bottleneck due to data starvation. This is where a client cannot get the data it needs fast enough, caused by network latency. Single object get and put operations (and the corresponding Entity API calls) won't saturate a gigabit ethernet connection by any means, but the latency in making the RPC is higher than what the CPU can handle. The application works, but it's slow. A smarter application would use the ObjectMap#getAll method. This would go out to the grid and get an object for every key in the list. Instead of waiting for each individual object, the client application waits for the entire list to come over the network. While the cost of network RPC is amortized over the size of the list, the client still incurs that cost. In addition to these network latency concerns, we may not want a near-cache that eats up client-side memory. Turning off the near-cache means that every get operation is an RPC. Turning it on means that some of our JVM heap space is used to store objects, which we may not need after the first use. The fundamental problem is that our objects and client application are architecturally separated. For our application to do anything, it needs to operate on objects that exist in the grid. In the client-server model, we copy data from the server to the client. At this point, our data and code are co-located, and the application can perform some business logic with that data. This model breaks down when there are huge data sets copied between boxes. Databases co-locate data and code with stored procedures. The processing power of the stored procedure is a product of the CPU and memory resources of the computer running the database. The stored procedure is code compiled into a module and executed by the database. Within that process, the stored procedure accesses data available in the same process. ObjectGrid gives us the ability to run code in the same process that gives an object access via the DataGrid API. Unlike the database example, where the throughput and latency of getting the store procedure result is limited to the power of the server it's on, ObjectGrid's power is limited by the number of CPUs in the deployment, and it can scale out at any time. ObjectGrid co-locates our code and objects by sending serialized classes with our application code methods to primary partitions in the grid. There are two ways to do this. The first way sends the code to every primary partition in the grid. The code executes and returns a result to the client. In the second way, we supply a collection of keys to the DataGrid API. With a list of keys, ObjectGrid only sends the application code to the partitions that contain at least one object with a key in the list. This reduces the amount of container processes doing the work for our client application, and is preferred instead of making the entire grid service on one client request. Let's look at finding an object by key in the client-server distributed model. The client has a key for an object. Calling the ObjectMap#get(key) method creates some work for the client. It first needs to determine to which partition the key belongs. The partition is important because the ClientClusterContext, already obtained by the client, knows how to get to the container that holds the primary shard in one hop. We find out the partition ID (pID) for a key with the PartitionManager class: BackingMap bMap = grid.getMap("Payment");PartitionManager pm = bMap.getPartitionManager();int pId = pm.getPartition(key); After obtaining the partition ID and the host running the container process, the client performs a network hop to request the object. The object is serialized and sent back to the client, where the client performs some operation with the object. Persisting an updated object requires one more network hop to put it back in the primary shard. We can now repeat that process for every object in our multi-million object collection. On second thought, that may not be such a great idea. Instead, we'll create an agent that we send to the grid. The agent encapsulates the logic we want to perform. An AgentManager serializes the agent and sends it to each primary shard in the deployment. Once on a primary shard, the agent executes and produces a result which is sent back to the client.   Borrowing from functional programming The DataGrid API borrows the "map" and "reduce" concepts from the world of functional programming. Just so we're all on the same page, let's go over the concepts behind these two functions. Functional programming focuses more on what a program does, instead of how it does it. This is in contrast to the most imperative programming we do in the C family of languages. That's not to say we can't follow a functional programming model, it's just that we don't. Other languages, like Lisp and its descendants, make functional programming the natural thing to do. Map and reduce are commonly found in functional programming. They are known as higher-order functions because they take functions as arguments. This is similar to how we would use a function pointer in C, or an anonymous inner class in Java, to implement callbacks. Though the focus is on what to do, at some point, we need to tell our program how to do it. We do this with the function passed as an argument to map or reduce. Let's look at a simple example in Ruby, which has both functional and imperative programming influences: >> numbers = [0,1,2,3,4,5,6,7,8,9]>> numbers.map { |number| number * 2 }=> [0, 2, 4, 6, 8, 10, 12, 14, 16, 18] We assign an array of numbers 0-9 to the variable numbers. The array has a method called map that we call in the second line. Map is a higher-order function and accepts a function as its argument. The Array#map method calls the passed-in function for each element in the array. It passes the element in the variable numbers. In this way, we return a new array that contains the results of each call to our function which performs number * 2. Let's look at the reduce method. In Ruby, reduce is called inject but the concept is the same: >> numbers = [0,1,2,3,4,5,6,7,8,9]>> numbers.inject(0) { |sum, number| sum = sum + number }=> 45 The inject (read as reduce) method takes a function that performs a running total on the numbers in the array. Instead of an array as our return type, we only get one number. The reduce operation returns a single result for an entire data set. The map operation returns a new set based on running the original set through a given function. These concepts are relevant in the data grid environment because we work with large data sets where we frequently need to work with large segments of data. Pulling raw data across the network, and operating over the data set on one client, are both too slow. Map and reduce helps us by using the remote CPU resources of the grid to cut down on the data sent across the network and the CPU power required on the client. This help comes from writing methods that work like map and reduce and sending them to our objects in the grid. java.util.M  ap, BackingMaps, ObjectMaps, HashMaps, like we need one more use for the word "map". We just saw the functional origin of the map concept. Let's take a look at a Java implementation. Map implements an algorithm that performs an operation on each element in a collection and returns a new collection of results: public Collection doubleOddInts(Collection c) {Collection results = new HashSet();Iterator iter = c.iterator();while (iter.hasNext()) {int i = (Integer)iter.next();if (i % 2 == 0) {[ 172 ]results.add(i);} else {results.add(i*2);}}return results;} Our needs go beyond performing a map function over an array. In order to be useful in a DataGrid environment, the map function must operate on a distributed collection of objects in an ObjectGrid instance. The DataGrid API supports this by giving us the MapGridAgent interface. A business logic class implements the two methods in MapGridAgent to encapsulate the code we intend to run in the grid. Classes that implement MapGridAgent must implement two methods, namely, MapGridAgent#process(Session session, ObjectMap map, Object key) and MapGridAgent#processAllEntries(Session session, ObjectMap map). Let's implement the doubleOddInts algorithm with MapGridAgent. We first create a class that implements the MapGridAgent interface. We give this class a meaningful name that describes the map operation implemented in the process methods: public class DoubleOddIntsMapAgent implements Serializable,MapGridAgent {public Object process(Session session, ObjectMap map, Object key){int i = (Integer)map.get(key);if (i % 2 == 0) {return i;} else {return i*2;}}public Map processAllEntries(Session session, ObjectMap map) {// nothing to do here for now!}} The map function itself is called by our client code. The process (session, map, key) method performs the how in the map function. Because ObjectGrid gives us the what for free (the map function), we only need to implement the how part. Like the Ruby example, this process (session, map, key) method is performed for each element in a collection. The Session and ObjectMap arguments are supplied by the AgentManager based on the current session and ObjectMap that starts the map function. The key is the crucial object for a given value in the collection, and that collection is supplied by us when we run the DoubleOddIntsMapAgent. After implementing the MapGridAgent#process(session, map, key) method, the DoubleOddIntsMapAgent is ready to run. We want it to run on each shard in an ObjectGrid instance that has a key in the collection we pass to it. We do this with an instance of the AgentManager class. The AgentManager class has two methods to send a MapGridAgent to the grid: AgentManager#callMapAgent(MapGridAgent agent, Collection keys) and AgentManager#callMapAgent(MapGridAgent agent). The first method provides a set of keys for our agent to use when run on each partition. Using this method is preferable to the non-keyed version because the non-keyed version runs the code on every primary shard in the grid. The Agent Manager#callMapAgent(agent, keys) method only runs the code on primary partitions that contain at least one key in the key collection. Whenever we have the choice to use part of the grid instead of the entire grid, we should take the choice that uses only part of the grid. Whenever we use the entire grid for one operation, we limit scalability and throughput. The AgentManager serializes the DoubleOddIntsMapAgent agent and sends it to each partition that has a key in the keys collection. Once on the primary partition, the process (session, map, key) method is called for each key in the keys collection supplied to AgentManager#callMapAgent(agent, keys). This set of keys is a subset of all of the keys in the BackingMap, and likely a subset of keys in each partition. Let's create an instance of this agent and submit it to the grid: Collection numbers = new ArrayList();for(int i = 0; i < 10000; i++) {numbers.add(i);}MapGridAgent agent = new DoubleOddIntsAgent();AgentManager am = session.getMap("Integer").getAgentManager();am.callMapAgent(agent, numbers); This example assumes that we have a BackingMap of Integer for both the key and value objects. The numbers collection is a list of keys to use. Once we create the agent, we submit it to the grid with the 10,000 keys to operate on. Before running the agent, the AgentManager sorts the keys by partition. The agent only runs on partitions that have a list of keys that hash to that partition. The agent runs on each partition that has a list of keys that hash to it. In each primary partition, the DoubleOddIntsMapAgent#process(session, map, key) method is called only for the keys that map to that partition. GridAgent and Entity GridAgent works with Entity classes as well. We don't directly use key objects when working with Entity objects. The Entity API hides the key/value implementation from us to make working with Entity objects easier than working with the ObjectMap API. The method definition for MapGridAgent#process(session, map, key) normally expects an object to be used as a key for an ObjectMap. We can still find the value object by converting key and value objects to their Tuple representations, but the DataGrid API makes it much easier for us. Instead of passing a key to the process method, we can convince the primary shard to pass us the Entity object itself, rather than a key using the EntityAgentMixin interface. EntityAgentMixin has one method, namely, EntityAgentMixin#getClassForEntity(). The implementation of this method should return the class object of the Entity. DataGrid needs this method defined in the grid agent implementation so it can provide the Entity object itself, rather than its key to the MapGridAgent#process(session, map, key) method. Let's assume that we have an Entity MyInteger that acts as a wrapper for Integer: public class DoubleOddIntsMapAgent implements Serializable,MapGridAgent, EntityAgentMixin {public Object process(Session session, ObjectMap map, Object key){MyInteger myInt = (MyInteger)key;if (myInt.mod(2) == 0) {return myInt;} else {return myInt.multiplyBy(2);}}public Map processAllEntries(Session session, ObjectMap map) {// nothing to do here for now!}public Class getClassForEntity() {return MyInteger.class;}} Our agent now implements the EntityAgentMixin interface and the getClassForEntity() method. The key is converted to the correct class before the MapGridAgent#process(session, map, key) method is called. Instead of the Tuple key for an Entity, the process method is passed a reference to the Entity itself. Because it is passed as an object, we must cast the Entity to its defined class. There is no need to look up for the Entity in its BackingMap because it's already the Entity we want to work with. This means the collection of keys passed to AgentManager#callMapAgent(agent, keys) is a collection with all elements of the c lass returned by getClassForEntity(). GridAgent with an unknown key set We may not always know the keys for each object we want to submit to an agent. In this situation, we send an agent into the grid without a key set. The grid agent cannot call the process (session, map, key) method because we don't know which keys to use. Instead, our grid agent method relies on the Query API to narrow the number of objects in each partition we work with. The MapGridAgent interface gives us the MapGridAgent#processAllEntries(Session session, ObjectMap map) method for this situation. The MapGridAgent#processAllEntries(session, map) method lets us specify what to do when we potentially need to work with all objects in a partition. Particularly, it lets us narrow the field with a query. In the past, we used a query to find card and address objects in a local ObjectGrid instance. This was fine for local instances with only one partition. The real power of the Query API is revealed when used with the DataGrid API. Query does not work across partitions when called from an ObjectGrid client in a distributed environment. It works with just one partition. In a distributed deployment, where we use the DataGrid API, a grid agent instance runs on one partition. Each partition has an instance of the grid agent running in it and each agent can see the objects in its partition. If we have 20 partitions, then we have 20 grid agents running, one in each partition. Because we're working with a single partition in each grid agent, we use the Query API to determine which objects are of interest to the business logic. Now that we know how to run code in the grid, the Query API is suddenly much more useful. Now, we want a query to run against just one partition. Using a query in a GridAgent is a natural fit. Each agent runs on one partition, and each query runs on that partition in the primary shard container process: public class DoubleOddIntsMapAgent implements Serializable,MapGridAgent, EntityAgentMixin {public Object process(Session session, ObjectMap map, Object key){MyInteger myInt = (MyInteger)key;if (myInt.mod(2) == 0) {return myInt;} else {return myInt.multiplyBy(2);}}public Map processAllEntries(Session session, ObjectMap map) {EntityManager em = session.getEntityManager();Query q = em.createQuery("select m from MyInteger m " +"where m.integer > 0 " +"and m.integer < 10000");Iterator iter = q.getResultIterator();Map<MyInteger, Integer> results =new HashMap<MyInteger, Integer)();while (iter.hasNext()) {MyInteger mi = (MyInteger)iter.next();results.put(mi, (Integer)process(session, map, mi));}return results;}public Class getClassForEntity() {return MyInteger.class;}} The MapGridAgent#processAllEntries(session, map) method generally follows the same pattern when implemented: Narrow the scope of objects in the partition. This is important in the MapGridAgent because it returns a result for every object it processes. This can result in hundreds of megabytes of objects sent back to a client from every partition for an indiscriminate query. Create a map to hold the results of each process operation. This map is keyed with the key object, or the value object, when using ObjectMap. The client application can perform its own gets if the keys are returned. Otherwise, it works directly with the value objects. We can also return a map of key/value objects. The map is keyed with the Entity class itself when using Entity. Iterate over the query results calling MapGridAgent#process(session, map, key) for each result. Calling the process method is required here since we didn't pass a collection of keys to the AgentManager#callMapAgent(agent) method. The key set is unknown before the agent runs. The agent finds all objects in a partition that meet our criteria for processing, and then we call process to get each result. Return the results. This map contains an entry for each object that meets our processing criteria in this partition. This map is merged, client-side, with the maps from every other partition where the agent ran. The merged map is the final result, and it is the return value to the AgentManager#callMapAgent(agent) method. Following the call to AgentManager#callMapAgent(agent), we have a Map that contains the combined agent results from every partition. We also split the workload between N partitions rather than performing all of the processing on the client. The ObjectGrid deployment performed our business logic because we passed the business logic to the grid rather than pulling objects out of the grid. One of the great things about this pattern is that our task on many partitions completes in about 1/Nth the amount of time it would take for one huge partition containing the same objects running on one computer. Of course, there is the overhead of the merge operation and network connections, but this is amortized over the number of primary partitions used by the agent. This is distinctly different than scaling up a database server when it needs more CPU speed for stored procedures. Instead of incurred downtime for database server migration, we simply add more containers on additional computers. The power of our grid increases as easily as starting a few more JVMs. >> Continue Reading: The DataGrid API with IBM WebSphere eXtreme Scale 6: Part 2
Read more
  • 0
  • 0
  • 1388

article-image-make-spacecraft-fly-and-shoot-special-effects-using-blender-3d-249
Packt
18 Nov 2009
4 min read
Save for later

Make Spacecraft Fly and Shoot with Special Effects using Blender 3D 2.49

Packt
18 Nov 2009
4 min read
Blender particles In the last versions of Blender 3D, the particle system received a huge upgrade, making it more complex and powerful than before. This upgrade, however, made it necessary to create more parameters and options in order for the system to acts. What didn't change was the need for an object that works as emitter of the particles. The shape and look of this object will be directly related to the type of effects we want to create. Before we discuss the effects that we will be creating, let's look at how the particles work in Blender. To create any type of particle system, go to the Objects panel and find the Particles button. This is where we will set up and change our particles for a variety of effects. The first time we open this menu, nothing will be displayed. But, if we select a mesh object and press the Add New button, this object will immediately turn into a new emitter. When a new emitter is created, we have to choose the type of behavior this emitter has in the particle system. In the top-left part of the menu, we will find a selector that lets us choose the type of interaction of the emitter. These are the three types of emitters: Emitter: This is the standard type, which is a single object that emits particles according to the parameters and rules that we set up in the particles controls. Hair: Here, we have a type of particle emitter that creates particles as thin lines for representing hair and fur. Since this is more related to characters, we won't use this type of emitter in this book. Reactor: With this emitter, we can create particle systems that interact with each other. It works by setting up a particle system that interferes with the motion and changes the trajectories of other particles. In our projects, we will use only the emitter type. However, you can create indirect animations and use particles to interact with each other. For instance, if you want to create a set of asteroids that block the path of our spacecraft, we could create this type of animation easily with a reactor particle system. How particles work To create and use a particle system, we will look at the most important features and parameters of each menu and create some pre-systems to use later in this article for the spacecraft. To fully understand how particles work, we have to become familiar with the forces or parameters that control the look and feel of particles. For each of those parameters and forces, we have a corresponding menu in Blender. Here corresponding parameters that control the particle system: Quantity: This is a basic feature of any particle system that allows us to set up how many particles will be in the system. Life: As a particle system is based on animation parameters, we have to know from how many frames the particle will be visible in the 3D world. Mesh emitting: Our emitters are all meshes, and we have to determine from which part of those 3D objects the particles will be emitted. We have several options to choose from, such as vertices or parts of the objects delimited by vertex groups. Motion: If we set up our particle system and don't give it enough force to make the particles move, nothing will happen to the system. So, even more important than setting up the appearance of the particles is choosing the right forces for the initial velocity of the particles. Physics and forces: Along with the forces that we use in the motion option, we will also apply some force fields and deflectors to particles to simulate and change the trajectories of the objects based on physical reactions. Visualization: A standard particle system has only small dots as particles, but we can change the way particles look in a variety of ways. To create flares and special effects such as the ones we need, we can use mesh objects that have Halo effects and many more. Interaction: At the end of the particle life, we can use several types of actions and behaviors to control the destiny of a particle. Should it spawn a new particle or simply die when it hits a special object? These are the things we have to consider before we begin setting up the animation.
Read more
  • 0
  • 0
  • 6976

article-image-joomla-flash-showing-maps-using-yos-ammap
Packt
18 Nov 2009
12 min read
Save for later

Joomla! with Flash: Showing maps using YOS amMap

Packt
18 Nov 2009
12 min read
Showing maps using YOS amMap Adding a map to your site may be a necessity in some cases. For example, you want to show the population of countries, or you want to show a world map to your students for teaching geography. Flash maps are always interesting as you can interact with them and can view them as you like. amMap provides tools for showing Flash maps. The amMap tool is ported as a Joomla! component by yOpensource, and the component is released with the name YOS amMap. This component has two versions—free and commercial. The commercial or pro version has some advanced features that are not available in the free version. The YOS amMap component, together with its module, allows you to display a map of the world, a region, or a country. You can choose the map to be displayed, which areas or countries are to be highlighted, and the way in which the viewers can control the map. Generally, maps displayed through the YOS amMap component can be zoomed, centered, or scrolled to left, right, top, or bottom. You can also specify a color in which a region or a country should be displayed. Installing and configuring YOS amMap To use YOS amMap with your Joomla! website, you must first download it from http://yopensource.com/en/component/remository/?func=fileinfo&id=3. After downloading and extracting the compressed package, you get the component and module packages. Install the component and module from the Extensions | Install/Uninstall screen. Once installed, you can administer the YOS amMap component from Components | YOS amMap. This shows the YOS amMap Control Panel, as shown in the following screenshot: YOS amMap Control Panel displays several icons through which you can configure and publish maps. The first thing you should do is to configure the global settings for amMap. In order to do this, click on the Parameters icon in the toolbar. Doing so brings up the dialog box, as shown in the following screenshot: In the Global Configuration section, you can enter a license key if you have purchased the commercial or the pro version of this component. For the free version, this is not needed. In this section, you can also configure the legal extensions of files that can be uploaded through this component, the maximum file size for uploads, the legal image extensions, and the allowed MIME types of all uploads. You can also specify whether the Flash uploader will be used or not. Once you have configured these fields, click on the Save button and return to YOS amMap Control Panel. Adding map files You can see the list of available maps by clicking on the Maps icon on the YOS amMap Control Panel screen or by clicking on Components | amMap | Maps. This shows the Maps Manager screen, as shown in the next screenshot. As you can see, the Maps Manager screen displays the list of available maps. By default, you find the world.swf, continents.swf, and world_with_antartica.swf map files. You will find some extra maps with the amMap bundle. You can also download the original amMap package from http://www.ammap.com/download. After downloading the ZIP package, extract it, and you will find many maps in the maps subfolder. Any map from this folder can be uploaded to the Joomla! site from the Maps Manager screen. Creating a map There are several steps for creating a map using YOS amMap. First we need to upload the package for the map. For example, if we want to display the map of the United States of America, then we need to upload the map template, the map data file, and the map settings file for the United States of America. To do this first upload the map template from the Maps Manager screen. You will find the map template for USA in the ammap/maps folder. Then we need to upload the data and the settings files. For doing so, click on the Upload link on the YOS amMap Control Panel screen. Then, in the Upload amMap screen, which is shown in the next screenshot, type the map's title (United States) in the Title field. Before clicking on the Browse button besides the Package File field, you first add the ammap_data.xml and the ammap_settings.xml files to a single ZIP file, unitedstates.zip. Now, click on the Browse button, and select this unitedstates.zip file. Then click on the Upload File & Install button. Once uploaded successfully, you see this map listed in the YOS amMap Manager screen, as shown in the next screenshot. You get this screen by clicking on the amMaps link on the toolbar. As you can see, the map that we have added is now listed in the YOS amMap Manager screen. However, the map is yet in an unpublished state, and we need to configure the map before publishing it. We need to configure its data and settings files, which are discussed in the following sections. Map data file The different regions of a map are identified by the map data file. This is an XML file and it defines the areas to be displayed on the map. The typical structure of a map data file can be understood by examining ammap_data.xml. The file has many comments that explain its structure. This file looks like as follows: <?xml version="1.0" encoding="UTF-8"?><map map_file="maps/world.swf" tl_long="-168.49" tl_lat="83.63" br_long="190.3" br_lat="-55.58" zoom_x="0%" zoom_y="0%" zoom="100%"><areas> <area title="AFGHANISTAN" mc_name="AF"></area> <area title="ALAND ISLANDS" mc_name="AX"></area> <area title="BANGLADESH" mc_name="BD"></area> <area title="BHUTAN" mc_name="BT"></area> <area title="CANADA" mc_name="CA"></area> <area title="UNITED ARAB EMIRATES" mc_name="AE"></area> <area title="UNITED KINGDOM" mc_name="GB"></area> <area title="UNITED STATES" mc_name="US"></area> <area title="borders" mc_name="borders" color="#FFFFFF" balloon="false"></area></areas><movies> <movie lat="51.3025" long="-0.0739" file="target" width="10" height="10" color="#CC0000" fixed_size="true" title="build-in movie usage example"></movie> <movie x="59.6667%" y="77.5%" file="icons/pin.swf" title="loaded movie usage example" text_box_width="250" text_box_height="140"> <description> <![CDATA[You can add description text here. This text will appear the user clicks on the movie. this description text can be html-formatted (for a list which html tags are supported, visit <u><a href="http://livedocs.adobe.com/flash/8/main/00001459.html">this page</a></u>. You can add descriptions to areas and labels too.]]> </description> </movie></movies><labels> <label x="0" y="50" width="100%" align="center" text_size="16" color="#FFFFFF"> <text><![CDATA[<b>World Map]]></text> <description><![CDATA[]]></description></label></labels><lines> <line long="-0.0739, -74" lat="51.3025, 40.43" arrow="end" width="1" alpha="40"></line> </lines></map> This code is a stripped-down version of the default ammap_data.xml file. Let us examine its structure and try to understand the meaning of each markup: <map> </map>: You define the map's structure using this markup. First, by using the map_file attribute, we declare the map file that should be used to display this map. This markup has some other attributes through which we declare the top and the left offset in longitude and latitude. We can also specify the zooming level using the zoom_x, zoom_y, and zoom attributes. <areas> </areas>: Areas are the regions or countries on a map. These are defined in the map. We only need to define the areas that we want to display. For example, in the sample, we have defined eight countries to be displayed and one straight line. Each area element has several attributes, among which you need to mention mc_name and title. You specify the area's name in mc_name, which is predefined in the map template. The title element will be displayed as the title of that map area. For example, <area mc_name="BD" title="Bangladesh"></area> means the areas marked as BD in the map template will be displayed with the title Bangladesh. In order to specify the mc_name element, you need to follow the map template designer's instructions. <movies> </movies>: Movies are some extra clips that can be displayed as a separate layer on the map. For example, to display the capital of each country, a movie clip could be displayed in the specified latitude and longitude. You can also display some other animations or text using a movie definition. <labels> </labels>: The <labels> markup contains the text to be displayed on the map. You can add any text on a map by defining a label element. To view and edit the map data file, ammap_data.xml, click on the map name on the YOS amMap Manager screen. This opens-up the amMap: [Edit] screen, as shown in the following screenshot: The amMap: [Edit] screen displays several configurations for the map. From the Details section you can change the map name, publish the map, and enable security. From the Design section you can view and edit the data and the settings files. Clicking on Data will show the data file. You can edit the data file from the online editor. As we want to display the map of USA, we will make the following changes on this screen: Select usa.swf in the Maps list. Change the data file as follows: <?xml version="1.0" encoding="UTF-8"?><map map_file="maps/usa.swf" zoom="100%" zoom_x="7.8%"zoom_y="0.18%"><areas> <area mc_name="AL" title="Alabama"/> <area mc_name="AK" title="Alaska"/> <area mc_name="AZ" title="Arizona"/> <area mc_name="AR" title="Arkansas"/> <area mc_name="CA" title="California"/> <area mc_name="CO" title="Colorado"/> <area mc_name="CT" title="Connecticut"/> <area mc_name="DE" title="Delaware"/> <area mc_name="DC" title="District of Columbia"/> <area mc_name="FL" title="Florida"/> <area mc_name="GA" title="Georgia"/> <area mc_name="HI" title="Hawaii"/> <area mc_name="ID" title="Idaho"/> <area mc_name="IL" title="Illinois"/> <area mc_name="IN" title="Indiana"/> <area mc_name="IA" title="Iowa"/> <area mc_name="KS" title="Kansas"/> <area mc_name="KY" title="Kentucky"/> <area mc_name="LA" title="Louisiana"/> <area mc_name="ME" title="Maine"/> <area mc_name="MD" title="Maryland"/> <area mc_name="MA" title="Massachusetts"/> <area mc_name="MI" title="Michigan"/> <area mc_name="MN" title="Minnesota"/> <area mc_name="MS" title="Mississippi"/> <area mc_name="MO" title="Missouri"/> <area mc_name="MT" title="Montana"/> <area mc_name="NE" title="Nebraska"/> <area mc_name="NV" title="Nevada"/> <area mc_name="NH" title="New Hampshire"/> <area mc_name="NJ" title="New Jersey"/> <area mc_name="NM" title="New Mexico"/> <area mc_name="NY" title="New York"/> <area mc_name="NC" title="North Carolina"/> <area mc_name="ND" title="North Dakota"/> <area mc_name="OH" title="Ohio"/> <area mc_name="OK" title="Oklahoma"/> <area mc_name="OR" title="Oregon"/> <area mc_name="PA" title="Pennsylvania"/> <area mc_name="RI" title="Rhode Island"/> <area mc_name="SC" title="South Carolina"/> <area mc_name="SD" title="South Dakota"/> <area mc_name="TN" title="Tennessee"/> <area mc_name="TX" title="Texas"/> <area mc_name="UT" title="Utah"/> <area mc_name="VT" title="Vermont"/> <area mc_name="VA" title="Virginia"/> <area mc_name="WA" title="Washington"/> <area mc_name="WV" title="West Virginia"/> <area mc_name="WI" title="Wisconsin"/><area mc_name="WY" title="Wyoming"/></areas><labels> <label x="0" y="60" width="100%" color="#FFFFFF" text_size="18"> <text>Map of the United States of America</text> </label></labels></map> As you can see, we have defined regions (states) on the map of USA, and towards the end of the file, we have added a label for the map. Select Yes for the Published field in the Details section. When you are done making these changes click on the Save button to save these changes. Now we will look into the map settings file. Map data files for countries are available with the amMap package. Thus, if you download amMap 2.5.1, you will get the map settings files for different countries. For example, the map data file for USA will be in the amMap_2.5.1/examples/_countries/usa folder.  
Read more
  • 0
  • 0
  • 4599
article-image-quality-assurance-asterisk-16
Packt
18 Nov 2009
10 min read
Save for later

Quality Assurance in Asterisk 1.6

Packt
18 Nov 2009
10 min read
The world has changed quite a bit in the last 150 years. Over this time, the telephone system has been invented, improved, and automated. Telephone switches no longer refer to people sitting in a large room connecting wires between the appropriate jacks. Flexible and powerful telephone service has moved from a dream to an expectation in large businesses, and for most of us it is a necessity. Today, telephone systems are the lifeblood of business. They are how we take orders, acquire supplies, and even call for emergency assistance. With the increase in prominence of telephones, the expectations of telephone users have increased proportionally. Not only have the technological expectations for telephone systems increased dramatically, but consumers are expecting more and more out of the businesses they call. Customers expect to be helped quickly and professionally. They want to know everything in a matter of minutes. Roads do not hold the only rage our society is facing today. As a business we have a variety of questions relating to our telephone system such as: How are our personnel handling angry callers? Are our employees answering the calls in a reasonable amount of time? Do we have any workers using the phone system for personal calls when they should be doing their job? We will never be able to make sure everybody does what they are supposed to do all of the time. What we will be able to do at the end of this article is perform spot-checks on how we are doing on customer service, and make sure our phone service isn't being used for unauthorized purposes. Ultimately, it comes down to a matter of trust; however, some people do not know better because they haven't been fully trained. Most will always act honorably; however, some just cannot and should not be trusted. We will try to find out who is who. Call Detail Records When we talk about security, what images come to mind? May be a big, burly guard? Perhaps a bunch of guys in green, carrying machine guns? Do we imagine a person with a metal-detecting wand? Or do we think of thick glass window panes? All of these are security features. It is just that some are a little more intrusive than others. Each time we increase security, we become a little bit less friendly. We all have to decide how far we are willing (and able) to go. In the continuum of security, Call Detail Records are the least intrusive. No special usernames or passwords have to be remembered. No fear of big brother breathing down your customers' and users' necks need be felt. We are simply doing the same thing telephone companies do—tracking what calls were made, when they were made, how long they lasted, where they came from, and a few other bits of information. This information is then available for us to review at our leisure. Asterisk gives us a few options on how we track this information. The two major choices are flat-file logging and database logging. Flat-file CDR logging By default, Asterisk includes a module called cdr_csv. Right out of the box, Asterisk logs all calls coming in and going out. The information for these calls is placed in a Comma Separated Value (CSV) file. This CSV file is located in var/log/asterisk/cdr-csv. All information is available in Master.csv, and some channels can be configured to send some information to other files as well. The benefit of using a CSV file is the simplicity. Right after compiling and installing Asterisk, this method will work. No additional configuration is required. Also, no additional network traffic is generated, and no additional services have to be installed on our server. When using the CSV form of CDR, we will see lists and lists of values. They are not very easy to parse, so here is the format, in the order in which they appear: account code: As determined by the channel (for DAHDI) or the user (for IAX and SIP) source: The source of the call destination: The destination of the call destination context caller ID channel: The channel of the source destination channel: If applicable last application: The last application run on the channel last application argument: The last argument to the last application on the channel start time: The time the call commenced answer time: The time the call was answered end time: The time the call ended duration: The difference between start time and end time billable seconds: The difference between answer time and end time, which must be less than the duration disposition: Either ANSWERED, NO ANSWER, or BUSY amaflags: As set for the channel or user, like account code uniqueid: A unique call identifier userfield: A user field set by the SetCDRUserField command We see that there are many items of information logged for each and every call. We can compare the billable seconds with our phone bill at the end of the month to make sure they're close. We can look at the destination and figure out if the calls were authorized. This gives us enough information to answer most questions we may have about a phone call. While we have enough information to answer questions, finding that answer is not very easy. We would have to scan through the entire file to try to find anything. If we are going to use an accounting package or reporting software, CSV may be exactly what we need. However, if we wish to use it in a more ad hoc sort of way, it is not very readable. Database CDR logging If we wish to read our CDR logs, it is most easily accomplished when the records are sortable. The easiest way to do this is to store our CDR records in a database. Even in this, Asterisk gives us choices. Included with Asterisk is support for PostgreSQL databases. In order to be able to install this, we must first have the postgresql-devel package installed on our system. If you have to install this package, you'll need to reinstall Asterisk. The automake system will automatically detect that we have the capability to use PostgreSQL and compile that module for us. Aside from the development packages we have installed, we will also need a PostgreSQL server somewhere in our network. It can be the same machine as the Asterisk server, but it doesn't necessarily need to be. In fact, it probably makes sense to have only one such database server on our network, and we don't want to tie up too much of our PBX's resources with database maintenance and storage. There is a script in /usr/src/asterisk/contrib/scripts/ called postgres_cdr.sql, which creates the correct table structure for us. This script should be run from the database server. If we get an error message while rebuilding that says something like "cannot find-lz", then we need to install zlib-devel. Now that we have set up our database and installed the CDR module, we must configure Asterisk to use the correct database. In order to do this, we need to edit /etc/asterisk/cdr_pgsql.conf. All of the configuration variables are in the global section. Our file should look like the following: [global]hostname=dbserver.mydomain.tldport=5432dbname=asteriskpassword=supersecretuser=asteriskuser Once we have these variables set, the next time we restart Asterisk, all CDR records will be logged in the database. If PostgreSQL is not our database of choice, we can use MySQL. This is not a part of the normal distribution of Asterisk. But as we have already installed asterisk-addons, we should already have the ability to use MySQL for CDR logging. Before we compile, we need to make sure that we have mysql-devel installed. First, we need to decide which version we're going to use. Because of some license quibbles, MySQL version 4.0 and later is not in the automatic package distribution chain. Instead, if we do need to download it, we will have to get it directly from www.mysql.com. However, the older version (3.x) will work with Asterisk and hence, you may wish to take a look at the differences between what version 3 offered and what later versions give us. Other than the development package mentioned, we will also need a MySQL server somewhere in our network. Just as with PostgreSQL, we can choose to have it on the same server as Asterisk, but for the same reasons, we probably shouldn't. Next, on the database server, we need to create the database with a user and a table for the CDR data. We do this by running the following code: # mysqladmin create database asteriskcdrdb # mysqlmysql> GRANT ALL PRIVILEGES   -> ON asteriskcdrdb.*   -> TO asteriskcdruser   -> IDENTIFIED BY 'changethis2yourpassword';mysql> USE asteriskcdrdb;mysql> CREATE TABLE cdr (   -> uniqueid varchar(32) NOT NULL default '',   -> userfield varchar(255) NOT NULL default '',   -> accountcode varchar(20) NOT NULL default '',   -> src varchar(80) NOT NULL default '',   -> dst varchar(80) NOT NULL default '',   -> dcontext varchar(80) NOT NULL default '',   -> clid varchar(80) NOT NULL default '',   -> channel varchar(80) NOT NULL default '',   -> dstchannel varchar(80) NOT NULL default '',   -> lastapp varchar(80) NOT NULL default '',   -> lastdata varchar(80) NOT NULL default '',   -> calldate datetime NOT NULL default '0000-00-00 00:00:00',   -> duration int(11) NOT NULL default '0',   -> billsec int(11) NOT NULL default '0',   -> disposition varchar(45) NOT NULL default '',   -> amaflags int(11) NOT NULL default '0'-> ); That's all there is to it! We only have to do this once, so it's really not so bad. Next, we have to modify the /etc/asterisk/cdr_mysql.conf file to correctly reflect our choices. [global]hostname=ourdbserver.ourdomain.tlddbname=asteriskcdrdbpassword=changethis2yourpassworduser=asteriskcdruserport=3306userfield=1 The next time we restart Asterisk, our CDR information will be stored in the MySQL database. What does that give us? We now have the ability to use a number of very powerful tools to search our CDR records to find trends and patterns.
Read more
  • 0
  • 0
  • 1680

article-image-formatting-and-enhancing-your-moodle-materials-part-2
Packt
18 Nov 2009
8 min read
Save for later

Formatting and Enhancing Your Moodle Materials: Part 2

Packt
18 Nov 2009
8 min read
Images If you've taken digital images, or scanned images onto your computer, it's likely that they'll be high resolution images, ready for printing. We don't need high resolution images on our computer screens for two good reasons: screen resolutions can't show so much detail and they take up a lot of storage space. There's a process called optimization which you can use to make your images more usable for your language learning activities. You can either use a program like Photoshop Elements (commercial), or Google's Picasa, which is free from http://picasa.google.com. These will enable you to edit your pictures and get the best quality with the smallest storage size. Let's look at a few things you can do to enhance your images using Picasa. Cropping Imagine we've taken this picture, but we're only interested in using the picture of the mug for a vocabulary exercise. Open up Picasa. Click on the photo we want to edit. Click on Basic Fixes and then on Crop. Click on Manual in the drop-down menu, then select the bit of the image we want to crop (cut out). Then click on Apply. The result will be: Color balance As it stands, the picture is too dark. There is too little contrast. Picasa will also allow us to create a stronger contrast, just by clicking on Tuning and Fill light and then moving the button across to brighten up the picture. The final picture looks like this: It's smaller and brighter than the original and more appropriate for our Moodle page. Optimization and image size The picture above is 340 kb in storage size, which is pretty big. The reason it's so big in storage size is that its real size is 837 px in width and 960 px in height. In case you're new to image measurement, px stands for pixels, which are the dots on your screen. So we have an unnecessarily large image. We can reduce the image size when we insert an image, but it's a much better idea to reduce the dimensions to what we actually need before we import the image into Moodle. That will reduce the storage size at the same time. Another reason for resizing images is that if you're using several photos on the same page, you'll achieve a much greater sense of balance and therefore effectiveness if all your images are the same size. If we reduce the mug to 100 px in width, the final version is only 92 kb in size. We can resize images in Picasa by exporting, emailing, or uploading our photos to Picasa Web Albums. When we select File | Export, we can select what size we want. Videos One exciting way of enhancing your web pages in Moodle is to use video. You can either upload videos to your own Moodle site or upload them to a site like YouTube, or TeacherTube. Mashable at http://mashable.com/category/video is an excellent source of ideas and resources for editing, uploading, and sharing your videos. If you decide to upload your videos onto your Moodle site, you'll need to check their size and the upload limits on your Moodle site. The default limits are usually quite low, but you can get your administrator to change them. You can also get round this problem by uploading your videos direct to the server using an FTP program. You will need to ask your Moodle administrator for help with that. Embedding videos will save your server's storage space and traffic. Adding subtitles to your videos One way of making video content more accessible for language learners is to add same-language subtitles. This would work well as an extension to the read and listen activity. Alternatively, you could get students to produce the subtitles, a rather glamorous type of dictation. If you want to add subtitles to your own videos, this is quite straightforward in free programs like Movie Maker (for Windows) or iMovie (for Macs). Look up "subtitles" in the help files. If you want to add subtitles to a YouTube video, http://www.overstream.net/ allows you to do just that. You can then embed the final product in your website. Here's what a video with added subtitles could look like: Sound If you're not happy with the quality of sound, there are various things you can do to improve it. The six examples below are created with the audio program called Audacity, but most audio editing programs will offer the same tools. The first four edits are in the Effect menu. Remove noise Effect | Noise removal If there is an unwelcome background noise on your recording, Audacity has a tool for reducing it. Open Audacity. Open your recording. Select the whole sound track or part of the track that has too much noise by highlighting it with your mouse cursor. Select click on Effect | Noise removal to get to the noise removal tool. On-screen instructions will guide you through the rest of the process. Be careful not to reduce the noise too much, as this sometimes creates distortion. Fade in and fade out Effect | Fade in/out If you want the sound to fade in and out, use your mouse to select the part of the sound track where you want the effect. Then select Effect | Fade in/out to create the effect. This could be useful for a presentation to avoid having a burst of sound at the beginning of the recording. Change tempo without changing pitch Effect | Change tempo This can be very useful, particularly for lower-level learners. It's useful to create two versions of your recordings: one fast and one slow. You can upload both and give students the choice of which one they listen to. The great thing about this tool is that the pitch doesn't change. Change pitch without changing tempo Effect | Change pitch Sometimes you might want to lower or raise the pitch of a voice to make it more audible. This tool lets you do that without the speed changing. It can even be used to simulate a dialog, with you speaking both parts, keeping one at your normal pitch and the other one at a higher or lower pitch. You'll find the next two settings in the Preferences menu. Sample rate This helps determine the quality of your recording. You can think of it as the number of times per second you capture a snapshot of sound while you're recording. Higher sample rates give you more detail. In other words, it's a fuller sound. 8 KHz is the lowest sampling rate you should select for voice recordings. 16 KHz is more likely to produce an acceptable sound. If you have music as well, you'll need a higher sample rate, like 44 KHz. Bit rate This is the number of bits (digital 1s and 0s) that are used each second to represent the sound signal. The bit-rate for digital audio is represented in thousands of bits per second (kbps). The higher the bit-rate is, the larger the file size and the better the sound quality. Lower bit rates result in smaller files but poorer sound quality. A good bit rate for recording in Audacity is 32. Audacity offers many more possibilities, and it's well worth exploring it in detail. Go to http://audacity.sourceforge.net/help/ for more help. Navigation Most of the navigation work—that is, menus and links—is done for you in Moodle. However, there are things you can do to improve it. Here's a list of tips: Font size and color Make consistent use of font size and color with headings so that users recognize the relative importance of different sections. For example, make topics big and bold so that they stand out. Remember that the default font and color is the same as for all other text. You have to make the difference yourself. For example: User control Allow users to move ahead if necessary, so that they feel in control. You can do this by providing explicit headings in your course topics. Don't call an activity "activity". Give it a more specific name, like "Second prepositions grammar exercise". Here are some options for navigation maps: Use the Topics view on your course pages Use Book to organize a syllabus. There's an example of this in the introduction to this article. Use a flowchart program to create a plan. Then import it into your Moodle web page. For example:   Many flowchart programs allow you to include hyperlinks to the actual activities. To do that, first copy and paste the target web page address from the address bar. Then paste that address into the hyperlink in your flowchart program. Here's an example using gliffy: Create a web page with a menu on it, as in the following screenshots. To make your new web page appear with blocks to the left and right, click on Show the course blocks on the set-up page—it's at the bottom of the next screenshot. The final page would look like this. Students will see all the other navigation blocks in the left and right-hand columns.
Read more
  • 0
  • 0
  • 1545
Modal Close icon
Modal Close icon