Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Save more on your purchases! discount-offer-chevron-icon
Savings automatically calculated. No voucher code required.
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

7018 Articles
article-image-learn-computer-vision-applications-open-cv
Packt
07 Jun 2011
16 min read
Save for later

Learn computer vision applications in Open CV

Packt
07 Jun 2011
16 min read
  OpenCV 2 Computer Vision Application Programming Cookbook Over 50 recipes to master this library of programming functions for real-time computer vision         Read more about this book       OpenCV (Open Source Computer Vision) is an open source library containing more than 500 optimized algorithms for image and video analysis. Since its introduction in 1999, it has been largely adopted as the primary development tool by the community of researchers and developers in computer vision. OpenCV was originally developed at Intel by a team led by Gary Bradski as an initiative to advance research in vision and promote the development of rich, vision-based CPU-intensive applications. In this article by Robert Laganière, author of OpenCV 2 Computer Vision Application Programming Cookbook, we will cover: Calibrating a camera Computing the fundamental matrix of an image pair Matching images using random sample consensus Computing a homography between two images (For more resources related to the article, see here.) Introduction Images are generally produced using a digital camera that captures a scene by projecting light onto an image sensor going through its lens. The fact that an image is formed through the projection of a 3D scene onto a 2D plane imposes the existence of important relations between a scene and its image, and between different images of the same scene. Projective geometry is the tool that is used to describe and characterize, in mathematical terms, the process of image formation. In this article, you will learn some of the fundamental projective relations that exist in multi-view imagery and how these can be used in computer vision programming. But before we start the recipes, let's explore the basic concepts related to scene projection and image formation. Image formation Fundamentally, the process used to produce images has not changed since the beginning of photography. The light coming from an observed scene is captured by a camera through a frontal aperture and the captured light rays hit an image plane (or image sensor) located on the back of the camera. Additionally, a lens is used to concentrate the rays coming from the different scene elements. This process is illustrated by the following figure: Here, do is the distance from the lens to the observed object, di is the distance from the lens to the image plane, and f is the focal length of the lens. These quantities are related by the so-called thin lens equation: In computer vision, this camera model can be simplified in a number of ways. First, we can neglect the effect of the lens by considering a camera with an infinitesimal aperture since, in theory, this does not change the image. Only the central ray is therefore considered. Second, since most of the time we have do>>di, we can assume that the image plane is located at the focal distance. Finally, we can notice from the geometry of the system, that the image on the plane is inverted. We can obtain an identical but upright image by simply positioning the image plane in front of the lens. Obviously, this is not physically feasible, but from a mathematical point of view, this is completely equivalent. This simplified model is often referred to as the pin-hole camera model and it is represented as follows: From this model, and using the law of similar triangles, we can easily derive the basic projective equation: The size (hi) of the image of an object (of height ho) is therefore inversely proportional to its distance (do) from the camera which is naturally true. This relation allows the position of the image of a 3D scene point to be predicted onto the image plane of a camera. Calibrating a camera From the introduction of this article, we learned that the essential parameters of a camera under the pin-hole model are its focal length and the size of the image plane (which defines the field of view of the camera). Also, since we are dealing with digital images, the number of pixels on the image plane is another important characteristic of a camera. Finally, in order to be able to compute the position of an image's scene point in pixel coordinates, we need one additional piece of information. Considering the line coming from the focal point that is orthogonal to the image plane, we need to know at which pixel position this line pierces the image plane. This point is called the principal point. It could be logical to assume that this principal point is at the center of the image plane, but in practice, this one might be off by few pixels depending at which precision the camera has been manufactured. Camera calibration is the process by which the different camera parameters are obtained. One can obviously use the specifications provided by the camera manufacturer, but for some tasks, such as 3D reconstruction, these specifications are not accurate enough. Camera calibration will proceed by showing known patterns to the camera and analyzing the obtained images. An optimization process will then determine the optimal parameter values that explain the observations. This is a complex process but made easy by the availability of OpenCV calibration functions. How to do it... To calibrate a camera, the idea is show to this camera a set of scene points for which their 3D position is known. You must then determine where on the image these points project. Obviously, for accurate results, we need to observe several of these points. One way to achieve this would be to take one picture of a scene with many known 3D points. A more convenient way would be to take several images from different viewpoints of a set of some 3D points. This approach is simpler but requires computing the position of each camera view, in addition to the computation of the internal camera parameters which fortunately is feasible. OpenCV proposes to use a chessboard pattern to generate the set of 3D scene points required for calibration. This pattern creates points at the corners of each square, and since this pattern is flat, we can freely assume that the board is located at Z=0 with the X and Y axes well aligned with the grid. In this case, the calibration process simply consists of showing the chessboard pattern to the camera from different viewpoints. Here is one example of a calibration pattern image: The nice thing is that OpenCV has a function that automatically detects the corners of this chessboard pattern. You simply provide an image and the size of the chessboard used (number of vertical and horizontal inner corner points). The function will return the position of these chessboard corners on the image. If the function fails to find the pattern, then it simply returns false: // output vectors of image pointsstd::vector<cv::Point2f> imageCorners;// number of corners on the chessboardcv::Size boardSize(6,4);// Get the chessboard cornersbool found = cv::findChessboardCorners(image, boardSize, imageCorners); Note that this function accepts additional parameters if one needs to tune the algorithm, which are not discussed here. There is also a function that draws the detected corners on the chessboard image with lines connecting them in sequence: //Draw the cornerscv::drawChessboardCorners(image, boardSize, imageCorners, found); // corners have been found The image obtained is seen here: The lines connecting the points shows the order in which the points are listed in the vector of detected points. Now to calibrate the camera, we need to input a set of such image points together with the coordinate of the corresponding 3D points. Let's encapsulate the calibration process in a CameraCalibrator class: class CameraCalibrator { // input points: // the points in world coordinates std::vector<std::vector<cv::Point3f>> objectPoints; // the point positions in pixels std::vector<std::vector<cv::Point2f>> imagePoints; // output Matrices cv::Mat cameraMatrix; cv::Mat distCoeffs; // flag to specify how calibration is done int flag; // used in image undistortion cv::Mat map1,map2; bool mustInitUndistort; public: CameraCalibrator() : flag(0), mustInitUndistort(true) {}; As mentioned previously, the 3D coordinates of the points on the chessboard pattern can be easily determined if we conveniently place the reference frame on the board. The method that accomplishes this takes a vector of the chessboard image filename as input: // Open chessboard images and extract corner pointsint CameraCalibrator::addChessboardPoints( const std::vector<std::string>& filelist, cv::Size & boardSize) { // the points on the chessboard std::vector<cv::Point2f> imageCorners; std::vector<cv::Point3f> objectCorners; // 3D Scene Points: // Initialize the chessboard corners // in the chessboard reference frame // The corners are at 3D location (X,Y,Z)= (i,j,0) for (int i=0; i<boardSize.height; i++) { for (int j=0; j<boardSize.width; j++) { objectCorners.push_back(cv::Point3f(i, j, 0.0f)); } } // 2D Image points: cv::Mat image; // to contain chessboard image int successes = 0; // for all viewpoints for (int i=0; i<filelist.size(); i++) { // Open the image image = cv::imread(filelist[i],0); // Get the chessboard corners bool found = cv::findChessboardCorners( image, boardSize, imageCorners); // Get subpixel accuracy on the corners cv::cornerSubPix(image, imageCorners, cv::Size(5,5), cv::Size(-1,-1), cv::TermCriteria(cv::TermCriteria::MAX_ITER + cv::TermCriteria::EPS, 30, // max number of iterations 0.1)); // min accuracy //If we have a good board, add it to our data if (imageCorners.size() == boardSize.area()) { // Add image and scene points from one view addPoints(imageCorners, objectCorners); successes++; } } return successes;} The first loop inputs the 3D coordinates of the chessboard, which are specified in an arbitrary square size unit here. The corresponding image points are the ones provided by the cv::findChessboardCorners function. This is done for all available viewpoints. Moreover, in order to obtain a more accurate image point location, the function cv::cornerSubPix can be used and as the name suggests, the image points will then be localized at sub-pixel accuracy. The termination criterion that is specified by the cv::TermCriteria object defines a maximum number of iterations and a minimum accuracy in sub-pixel coordinates. The first of these two conditions that is reached will stop the corner refinement process. When a set of chessboard corners has been successfully detected, these points are added to our vector of image and scene points: // Add scene points and corresponding image pointsvoid CameraCalibrator::addPoints(const std::vector<cv::Point2f>&imageCorners, const std::vector<cv::Point3f>& objectCorners) { // 2D image points from one view imagePoints.push_back(imageCorners); // corresponding 3D scene points objectPoints.push_back(objectCorners);} The vectors contains std::vector instances. Indeed, each vector element being a vector of points from one view. Once a sufficient number of chessboard images have been processed (and consequently a large number of 3D scene point/2D image point correspondences are available), we can initiate the computation of the calibration parameters: // Calibrate the camera// returns the re-projection errordouble CameraCalibrator::calibrate(cv::Size &imageSize){ // undistorter must be reinitialized mustInitUndistort= true; //Output rotations and translations std::vector<cv::Mat> rvecs, tvecs; // start calibration return calibrateCamera(objectPoints, // the 3D points imagePoints, // the image points imageSize, // image size cameraMatrix,// output camera matrix distCoeffs, // output distortion matrix rvecs, tvecs,// Rs, Ts flag); // set options} In practice, 10 to 20 chessboard images are sufficient, but these must be taken from different viewpoints at different depths. The two important outputs of this function are the camera matrix and the distortion parameters. The camera matrix will be described in the next section. For now, let's consider the distortion parameters. So far, we have mentioned that with the pin-hole camera model, we can neglect the effect of the lens. But this is only possible if the lens used to capture an image does not introduce too important optical distortions. Unfortunately, this is often the case with lenses of lower quality or with lenses having a very short focal length. You may have already noticed that in the image we used for our example, the chessboard pattern shown is clearly distorted. The edges of the rectangular board being curved in the image. It can also be noticed that this distortion becomes more important as we move far from the center of the image. This is a typical distortion observed with fish-eye lens and it is called radial distortion. The lenses that are used in common digital cameras do not exhibit such a high degree of distortion, but in the case of the lens used here, these distortions cannot certainly be ignored. It is possible to compensate for these deformations by introducing an appropriate model. The idea is to represent the distortions induced by a lens by a set of mathematical equations. Once established, these equations can then be reverted in order to undo the distortions visible on the image. Fortunately, the exact parameters of the transformation that will correct the distortions can be obtained together with the other camera parameter during the calibration phase. Once this is done, any image from the newly calibrated camera can be undistorted: // remove distortion in an image (after calibration)cv::Mat CameraCalibrator::remap(const cv::Mat &image) { cv::Mat undistorted; if (mustInitUndistort) { // called once per calibration cv::initUndistortRectifyMap( cameraMatrix, // computed camera matrix distCoeffs, // computed distortion matrix cv::Mat(), // optional rectification (none) cv::Mat(), // camera matrix to generate undistorted image.size(), // size of undistorted CV_32FC1, // type of output map map1, map2); // the x and y mapping functions mustInitUndistort= false; } // Apply mapping functions cv::remap(image, undistorted, map1, map2, cv::INTER_LINEAR); // interpolation type return undistorted;} Which results in the following image: As you can see, once the image is undistorted, we obtain a regular perspective image. How it works... In order to explain the result of the calibration, we need to go back to the figure in the introduction which describes the pin-hole camera model. More specifically, we want to demonstrate the relation between a point in 3D at position (X,Y,Z) and its image (x,y) on a camera specified in pixel coordinates. Let's redraw this figure by adding a reference frame that we position at the center of the projection as seen here: Note that the Y-axis is pointing downward to get a coordinate system compatible with the usual convention that places the image origin at the upper-left corner. We learned previously that the point (X,Y,Z) will be projected onto the image plane at (fX/Z,fY/Z). Now, if we want to translate this coordinate into pixels, we need to divide the 2D image position by, respectively, the pixel width (px) and height (py). We notice that by dividing the focal length f given in world units (most often meters or millimeters) by px, then we obtain the focal length expressed in (horizontal) pixels. Let's then define this term as fx. Similarly, fy =f/py is defined as the focal length expressed in vertical pixel unit. The complete projective equation is therefore: Recall that (u0,v0) is the principal point that is added to the result in order to move the origin to the upper-left corner of the image. These equations can be rewritten in matrix form through the introduction of homogeneous coordinates in which 2D points are represented by 3-vectors, and 3D points represented by 4-vectors (the extra coordinate is simply an arbitrary scale factor that need to be removed when a 2D coordinate needs to be extracted from a homogeneous 3-vector). Here is the projective equation rewritten: The second matrix is a simple projection matrix. The first matrix includes all of the camera parameters which are called the intrinsic parameters of the camera. This 3x3 matrix is one of the output matrices returned by the cv::calibrateCamera function. There is also a function called cv::calibrationMatrixValues that returns the value of the intrinsic parameters given a calibration matrix. More generally, when the reference frame is not at the projection center of the camera, we will need to add a rotation (a 3x3 matrix) and a translation vector (3x1 matrix). These two matrices describe the rigid transformation that must be applied to the 3D points in order to bring them back to the camera reference frame. Therefore, we can rewrite the projection equation in its most general form: Remember that in our calibration example, the reference frame was placed on the chessboard. Therefore, there is a rigid transformation (rotation and translation) that must be computed for each view. These are in the output parameter list of the cv::calibrateCamera function. The rotation and translation components are often called the extrinsic parameters of the calibration and they are different for each view. The intrinsic parameters remain constant for a given camera/lens system. The intrinsic parameters of our test camera obtained from a calibration based on 20 chessboard images are fx=167, fy=178, u0=156, v0=119. These results are obtained by cv::calibrateCamera through an optimization process aimed at finding the intrinsic and extrinsic parameters that will minimize the difference between the predicted image point position, as computed from the projection of the 3D scene points, and the actual image point position, as observed on the image. The sum of this difference for all points specified during the calibration is called the re-projection error. To correct the distortion, OpenCV uses a polynomial function that is applied to the image point in order to move them at their undistorted position. By default, 5 coefficients are used; a model made of 8 coefficients is also available. Once these coefficients are obtained, it is possible to compute 2 mapping functions (one for the x coordinate and one for the y) that will give the new undistorted position of an image point on a distorted image. This is computed by the function cv::initUndistortRectifyMap and the function cv::remap remaps all of the points of an input image to a new image. Note that because of the non-linear transformation, some pixels of the input image now fall outside the boundary of the output image. You can expand the size of the output image to compensate for this loss of pixels, but you will now obtain output pixels that have no values in the input image (they will then be displayed as black pixels). There's more... When a good estimate of the camera intrinsic parameters are known, it could be advantageous to input them to the cv::calibrateCamera function. They will then be used as initial values in the optimization process. To do so, you just need to add the flag CV_CALIB_USE_INTRINSIC_GUESS and input these values in the calibration matrix parameter. It is also possible to impose a fixed value for the principal point (CV_CALIB_ FIX_PRINCIPAL_POINT), which can often be assumed to be the central pixel. You can also impose a fixed ratio for the focal lengths fx and fy (CV_CALIB_FIX_RATIO) in which case you assume pixels of square shape.
Read more
  • 0
  • 1
  • 7175

article-image-working-away3d-cameras
Packt
06 Jun 2011
10 min read
Save for later

Working with Away3D Cameras

Packt
06 Jun 2011
10 min read
Away3D 3.6 Cookbook Over 80 practical recipes for creating stunning graphics and effects with the fascinating Away3D engine Cameras are an absolutely essential part of the 3D world of computer graphics. In fact, no real-time 3D engine can exist without having a camera object. Cameras are our eyes into the 3D world. Away3D has a decent set of cameras, which at the time of writing, consists of Camera3D, TargetCamera3D, HoverCamera3D, and SpringCam classes. Although they have similar base features, each one has some additional functionality to make it different. Creating an FPS controller There are different scenarios where you wish to get a control of the camera in first person, such as in FPS video games. Basically, we want to move and rotate our camera in any horizontal direction defined by the combination of x and y rotation of the user mouse and by keyboard keys input. In this recipe, you will learn how to develop such a class from scratch, which can then be useful in your consequential projects where FPS behavior is needed. Getting ready Set up a basic Away3D scene extending AwayTemplate and give it the name FPSDemo. Then, create one more class which should extend Sprite and give it the name FPSController. How to do it... FPSController class encapsulates all the functionalities of the FPS camera. It is going to receive the reference to the scene camera and apply FPS behavior "behind the curtain". FPSDemo class is a basic Away3D scene setup where we are going to test our FPSController: FPSController.as package utils { public class FPSController extends Sprite { private var _stg:Stage; private var _camera:Object3D private var _moveLeft_Boolean=false; private var _moveRight_Boolean=false; private var _moveForward_Boolean=false; private var _moveBack_Boolean=false; private var _controllerHeigh:Number; private var _camSpeed_Number=0; private static const CAM_ACCEL_Number=2; private var _camSideSpeed_Number=0; private static const CAM_SIDE_ACCEL_Number=2; private var _forwardLook_Vector3D=new Vector3D(); private var _sideLook_Vector3D=new Vector3D(); private var _camTarget_Vector3D=new Vector3D(); private var _oldPan_Number=0; private var _oldTilt_Number=0; private var _pan_Number=0; private var _tilt_Number=0; private var _oldMouseX_Number=0; private var _oldMouseY_Number=0; private var _canMove_Boolean=false; private var _gravity:Number; private var _jumpSpeed_Number=0; private var _jumpStep:Number; private var _defaultGrav:Number; private static const GRAVACCEL_Number=1.2; private static const MAX_JUMP_Number=100; private static const FRICTION_FACTOR_Number=0.75; private static const DEGStoRADs:Number = Math.PI / 180; public function FPSController(camera:Object3D,stg:Stage, height_Number=20,gravity:Number=5,jumpStep:Number=5) { _camera=camera; _stg=stg; _controllerHeigh=height; _gravity=gravity; _defaultGrav=gravity; _jumpStep=jumpStep; init(); } private function init():void{ _camera.y=_controllerHeigh; addListeners(); } private function addListeners():void{ _stg.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown,false,0,true); _stg.addEventListener(MouseEvent.MOUSE_UP, onMouseUp,false,0,true); _stg.addEventListener(KeyboardEvent.KEY_DOWN, onKeyDown,false,0,true); _stg.addEventListener(KeyboardEvent.KEY_UP, onKeyUp,false,0,true); } private function onMouseDown(e:MouseEvent):void{ _oldPan=_pan; _oldTilt=_tilt; _oldMouseX=_stg.mouseX+400; _oldMouseY=_stg.mouseY-300; _canMove=true; } private function onMouseUp(e:MouseEvent):void{ _canMove=false; } private function onKeyDown(e:KeyboardEvent):void{ switch(e.keyCode) { case 65:_moveLeft = true;break; case 68:_moveRight = true;break; case 87:_moveForward = true;break; case 83:_moveBack = true;break; case Keyboard.SPACE: if(_camera.y<MAX_JUMP+_controllerHeigh){ _jumpSpeed=_jumpStep; }else{ _jumpSpeed=0; } break; } } private function onKeyUp(e:KeyboardEvent):void{ switch(e.keyCode) { case 65:_moveLeft = false;break; case 68:_moveRight = false;break; case 87:_moveForward = false;break; case 83:_moveBack = false;break; case Keyboard.SPACE:_jumpSpeed=0;break; } } public function walk():void{ _camSpeed *= FRICTION_FACTOR; _camSideSpeed*= FRICTION_FACTOR; if(_moveForward){ _camSpeed+=CAM_ACCEL;} if(_moveBack){_camSpeed-=CAM_ACCEL;} if(_moveLeft){_camSideSpeed-=CAM_SIDE_ACCEL;} if(_moveRight){_camSideSpeed+=CAM_SIDE_ACCEL;} if (_camSpeed < 2 && _camSpeed > -2){ _camSpeed=0; } if (_camSideSpeed < 0.05 && _camSideSpeed > -0.05){ _camSideSpeed=0; } _forwardLook=_camera.transform.deltaTransformVector(new Vector3D(0,0,1)); _forwardLook.normalize(); _camera.x+=_forwardLook.x*_camSpeed; _camera.z+=_forwardLook.z*_camSpeed; _sideLook=_camera.transform.deltaTransformVector(new Vector3D(1,0,0)); _sideLook.normalize(); _camera.x+=_sideLook.x*_camSideSpeed; _camera.z+=_sideLook.z*_camSideSpeed; _camera.y+=_jumpSpeed; if(_canMove){ _pan = 0.3*(_stg.mouseX+400 - _oldMouseX) + _oldPan; _tilt = -0.3*(_stg.mouseY-300 - _oldMouseY) + _oldTilt; if (_tilt > 70){ _tilt = 70; } if (_tilt < -70){ _tilt = -70; } } var panRADs_Number=_pan*DEGStoRADs; var tiltRADs_Number=_tilt*DEGStoRADs; _camTarget.x = 100*Math.sin( panRADs) * Math.cos (tiltRADs) +_camera.x; _camTarget.z = 100*Math.cos( panRADs) * Math.cos (tiltRADs) +_camera.z; _camTarget.y = 100*Math.sin(tiltRADs) +_camera.y; if(_camera.y>_controllerHeigh){ _gravity*=GRAVACCEL; _camera.y-=_gravity; } if(_camera.y<=_controllerHeigh ){ _camera.y=_controllerHeigh; _gravity=_defaultGrav; } _camera.lookAt(_camTarget); } } } Now let's put it to work in the main application: FPSDemo.as package { public class FPSDemo extends AwayTemplate { [Embed(source="assets/buildings/CityScape.3ds",mimeType=" application/octet-stream")] private var City:Class; [Embed(source="assets/buildings/CityScape.png")] private var CityTexture:Class; private var _cityModel:Object3D; private var _fpsWalker:FPSController; public function FPSDemo() { super(); } override protected function initGeometry() : void{ parse3ds(); } private function parse3ds():void{ var max3ds_Max3DS=new Max3DS(); _cityModel=max3ds.parseGeometry(City); _view.scene.addChild(_cityModel); _cityModel.materialLibrary.getMaterial("bakedAll [Plane0"). material=new BitmapMaterial(Cast.bitmap(new CityTexture())); _cityModel.scale(3); _cityModel.x=0; _cityModel.y=0; _cityModel.z=700; _cityModel.rotate(Vector3D.X_AXIS,-90); _cam.z=-1000; _fpsWalker=new FPSController(_cam,stage,_view,20,12,250); } override protected function onEnterFrame(e:Event) : void{ super.onEnterFrame(e); _fpsWalker.walk(); } } } How it works... FPSController class looks a tad scary, but that is only at first glance. First we pass the following arguments into the constructor: camera: Camera3D reference (here Camera3D, by the way, is the most appropriate one for FPS). stg: References to flash stage because we are going to assign listeners to it from within the class. height: It is the camera distance from the ground. We imply here that the ground is at 0,0,0. gravity: Gravity force for jump. JumpStep: Jump altitude. Next we define listeners for mouse UP and DOWN states as well as events for registering input from A,W,D,S keyboard keys to be able to move the FPSController in four different directions. In the onMouseDown() event handler, we update the old pan, tilt the previous mouseX and mouseY values as well as by assigning the current values when the mouse has been pressed to _oldPan, _oldTilt, _oldMouseX, and _oldMouseY variables accordingly. That is a widely used technique. We need to do this trick in order to have nice and continuous transformation of the camera each time we start moving the FPSController. In the methods onKeyUp() and onKeyDown(), we switch the flags that indicate to the main movement execution code. This will be seen shortly and we will also see which way the camera should be moved according to the relevant key press. The only part that is different here is the block of code inside the Keyboard.SPACE case. This code activates jump behavior when the space key is pressed. On the SPACE bar, the camera jumpSpeed (that, by default, is zero) receives the _jumpStep incremented value and this, in case the camera has not already reached the maximum altitude of the jump defined by MAX_JUMP, is added to the camera ground height. Now it's the walk() function's turn. This method is supposed to be called on each frame in the main class: _camSpeed *= FRICTION_FACTOR; _camSideSpeed*= FRICTION_FACTOR; Two preceding lines slow down, or in other words apply friction to the front and side movements. Without applying the friction. It will take a lot of time for the controller to stop completely after each movement as the velocity decrease is very slow due to the easing. Next we want to accelerate the movements in order to have a more realistic result. Here is acceleration implementation for four possible walk directions: if(_moveForward){ _camSpeed+= CAM_ACCEL;} if(_moveBack){_camSpeed-= CAM_ACCEL;} if(_moveLeft){_camSideSpeed-= CAM_SIDE_ACCEL;} if(_moveRight){_camSideSpeed+= CAM_SIDE_ACCEL;} The problem is that because we slow down the movement by continuously dividing current speed when applying the drag, the speed value actually never becomes zero. Here we define the range of values closest to zero and resetting the side and front speeds to 0 as soon as they enter this range: if (_camSpeed < 2 && _camSpeed > -2){ _camSpeed=0; } if (_camSideSpeed < 0.05 && _camSideSpeed > -0.05){ _camSideSpeed=0; } Now we need to create an ability to move the camera in the direction it is looking. To achieve this we have to transform the forward vector, which present the forward look of the camera, into the camera space denoted by _camera transformation matrix. We use the deltaTransformVector() method as we only need the transformation portion of the matrix dropping out the translation part: _forwardLook=_camera.transform.deltaTransformVector(new Vector3D(0,0,1)); _forwardLook.normalize(); _camera.x+=_forwardLook.x*_camSpeed; _camera.z+=_forwardLook.z*_camSpeed; Here we make pretty much the same change as the previous one but for the sideways movement transforming the side vector by the camera's matrix: _sideLook=_camera.transform.deltaTransformVector(new Vector3D(1, 0,0)); _sideLook.normalize(); _camera.x+=_sideLook.x*_camSideSpeed; _camera.z+=_sideLook.z*_camSideSpeed; And we also have to acquire base values for rotations from mouse movement. _pan is for the horizontal (x-axis) and _tilt is for the vertical (y-axis) rotation: if(_canMove){ _pan = 0.3*(_stg.mouseX+400 - _oldMouseX) + _oldPan; _tilt = -0.3*(_stg.mouseY-300 - _oldMouseY) + _oldTilt; if (_tilt > 70){ _tilt = 70; } if (_tilt < -70){ _tilt = -70; } } We also limit the y-rotation so that the controller would not rotate too low into the ground and conversely, too high into zenith. Notice that this entire block is wrapped into a _canMove Boolean flag that is set to true only when the mouse DOWN event is dispatched. We do it to prevent the rotation when the user doesn't interact with the controller. Finally we need to incorporate the camera local rotations into the movement process. So that while moving, you will be able to rotate the camera view too: var panRADs_Number=_pan*DEGStoRADs; var tiltRADs_Number=_tilt*DEGStoRADs; _camTarget.x = 100*Math.sin( panRADs) * Math.cos(tiltRADs) + _camera.x; _camTarget.z = 100*Math.cos( panRADs) * Math.cos(tiltRADs) + _camera.z; _camTarget.y = 100*Math.sin(tiltRADs) +_camera.y; And the last thing is applying gravity force each time the controller jumps up: if(_camera.y>_controllerHeigh){ _gravity*=GRAVACCEL; _camera.y-=_gravity; } if(_camera.y<=_controllerHeigh ){ _camera.y=_controllerHeigh; _gravity=_defaultGrav; } Here we first check whether the camera y-position is still bigger than its height, this means that the camera is in the "air" now. If true, we apply gravity acceleration to gravity because, as we know, in real life, the falling body constantly accelerates over time. In the second statement, we check whether the camera has reached its default height. If true, we reset the camera to its default y-position and also reset the gravity property as it has grown significantly from the acceleration addition during the last jump. To test it in a real application, we should initiate an instance of the FPSController class. Here is how it is done in FPSDemo.as: _fpsWalker=new FPSController(_cam,stage,20,12,250); We pass to it our scene camera3D instance and the rest of the parameters that were discussed previously. The last thing to do is to set the walk() method to be called on each frame: override protected function onEnterFrame(e:Event) : void{ super.onEnterFrame(e); _fpsWalker.walk(); } Now you can start developing the Away3D version of Unreal Tournament!
Read more
  • 0
  • 0
  • 6425

article-image-customizing-sharepoint-communities-windows-phone-7
Packt
03 Jun 2011
9 min read
Save for later

Customizing SharePoint Communities for Windows Phone 7

Packt
03 Jun 2011
9 min read
  Microsoft SharePoint 2010 Enterprise Applications on Windows Phone 7 Create enterprise-ready websites and applications that access Microsoft SharePoint on Windows Phone 7         Read more about this book       (For more resources on Microsoft Sharepoint, see here.) Let's get started with the discussion of SharePoint communities by taking a look at blogs.   Blogs At this point in the 21st century, everyone is familiar with what a blog is. In SharePoint, a blog is a site that is characterized by entries of content being listed from newest at the top of the page to oldest at the bottom. Content is determined by the author and can contain metadata such as the author, date, and keywords or tags to designate the categories in which the content belongs. Creating a blog site in SharePoint A blog site can either be the root site or a site contained within another site. This is consistent with all site types in SharePoint. The reason this is pointed out though, is that when creating a new SharePoint engagement, it is important to truly think of the overall goal of the website as a whole. If the website will essentially be a blog with other content thrown in from time to time, then it makes sense for the root site to be of the type blog. Otherwise, it makes sense to make the root site something else like the team site or a blank site and then add a blog site within that root site. This is important to think about because to add a blog to an existing site is fairly straightforward. Simply, carry out the following steps: From the root site, click on the Site Actions menu. On the Site Actions menu, select the New Site option. From the Installed Items list, select Blog. Give the new blog site a Title and a URL name. Finally, click on the Create button. At this point, SharePoint will create a new blog site. The new blog will contain some seed data to get the blog going. There are three categories named appropriately: Category 1 Category 2 Category 3 The new blog site will also have a location for archives containing the one entry that was seeded in the site titled Welcome to your Blog! This can all be seen in the following screenshot: Customizing a SharePoint blog site Although this blog site is ready to go right now, we will probably want to customize it for our usage scenario. There are several places to customize it, which are as follows: About this blog Categories Blog Tools Links About this blog When new readers reach a blog they look for information about the blog so they can get a high level overview of what to expect from the content of the site. This is usually found in the "about this blog" section of the site. In the SharePoint blog site, the About this blog section is a Wiki Web Part found in the right column. Although we will learn more about Wikis in the next section, for now just know that this web part allows us a what-you-see-is-what-you-get (WYSIWYG) editing surface to enter any content we want. To get into this editing mode, carry out the following steps: From the Site Actions menu, select Edit Page. When the page changes to edit mode, click on the text inside the About this blog section. At this point, the ribbon at the top will have the following four main sections: Editing Tools: This has the basic text editing tools that are familiar to anyone who has used Word. Table Tools: The about section is actually a table with two rows and one column. The top cell has the image, and the bottom has the text. The Table Tools section of the ribbon allows us to manage this table. Page Tools: These are the basic tools that are global to the page and not specific to this section. Web Part Tools:This part of the ribbon contains tools that allow us to minimize, restore, or delete the web part. It also allows us to edit the Web Part Properties. These properties include the title, as well as other appearance features such as height and width. It also includes layout information and some advanced features. Categories The next section to customize on this blog site is the list of categories. When creating a blog entry, we can categorize the contents with a tag. The default categories for a new blog are as follows: Category 1 Category 2 Category 3 The following steps show how to customize these categories: Click on the title Categories in the left column. This will open the list page for the categories. The categories list will display the three default categories. For each category, click on the Edit icon, as shown in the following screenshot: (Move the mouse over the image to enlarge.) Change the Title to something that makes sense for the blog which we are creating. Click on the Save button. Repeat these steps for all three of the default categories. To add more categories, click on the Add new item link below the list of categories. To delete a category, carry out the following steps: Move the pointer over the title of the category. This will trigger an arrow to appear to the right of the title next to the edit icon. Click on this down arrow. In the context menu that appears, select the Delete Item option. A confirmation message will appear asking if we are sure we want to send it to the recycle bin. Click on OK and the category will be deleted. Blog Tools Now that we have a blog, how do we manage the content? This is where the Blog Tools section comes into use. There are 4 links to help us manage the blog, which are as follows: Create a post Manage posts Manage comments Launch blog program to post Create a post Clicking on the Create a post link will open a modal dialog with a form to fill out to create a new blog entry. The fields include the following: Title: This is a plain text field used for the title of the entry. Body: This is a rich text field that utilizes the edit ribbon. Category: Here we can select the categories that the entry is a part of. Published: Here we can set a date for our entry to be published. Publishing an entry in the future is helpful when we have information that isn't supposed to be public knowledge until a specifi c time and date, or when information needs to be published at a specifi c time and date. The preceding fields are shown in the following screenshot: Manage posts Blog entries, like most things in SharePoint, are items in a list. Clicking on the Manage posts link will display all the blog entries. From this list, we can perform many management functions such as the following: Manage approval status Edit entries View entries Manage permissions Delete entries Manage comments All of the comments are managed in a separate list from the blog entries. Clicking on the Manage comments link will display all of the comments for all of the blog entries in this site. From here we can view, edit, or delete the comments, as well as manage permissions. Managing permissions on comments and posts is a lot like managing permissions elsewhere in SharePoint. By default, the list items inherit the parent permissions, but occasionally we will want to have specific permissions for special cases. We could have a blog entry that we only want a small group of people to see, or maybe we want to save a comment, so that only we can see it. The manage permissions section is how we can deal with these cases. More information on managing permissions can be found in the online help or on TechNet at the following URL: http://technet.microsoft.com/en-us/library/cc721640.aspx Launch blog program to post Although creating a blog entry in the web browser works well, sometimes we may want to use a more powerful tool to create entries. The Launch blog program to post link will open Microsoft Word 2007, or a newer version, to edit a new blog entry. Configuring Windows Live Writer There is a link in Blog Tools to launch Microsoft Word 2007 or newer, to create a new blog entry. Although Word does a pretty good job of creating new blog entries, there is a free tool from Microsoft, named Windows Live Writer (http://explore.live.com/windows-live-writer) which is true genius when it comes to editing blog entries. Using this tool can make most, if not all, blog posting tasks much easier within SharePoint. Configuring Windows Live Writer for a SharePoint is simple: When setting up Windows Live Writer, select SharePoint from the What blog service do you use? Click on Next and enter the URL of the SharePoint blog. Click on Next and provide the SharePoint authentication information. That's all there is to it. The Windows Live Writer interface also displays a preview of what the blog entry will look like in the site by clicking on the Preview tab at the bottom, as shown in the following screenshot: Links Finally, the links section allows us to add hyperlinks to the page for easy access to anything. The default entry is to a photo library named Photos. Adding a new link is as simple as the following steps: Click on the Add new link hyperlink. Enter the URL for the link. Optionally, enter a description that will be used in place of the raw URL for display. Optionally, add any notes. Notes show up when viewing the full list of links. The full list of links can be viewed by clicking on the title Links from the home page. Click on Save, as shown in the following screenshot:  
Read more
  • 0
  • 0
  • 2001

article-image-working-user-defined-values-sap-business-one
Packt
03 Jun 2011
8 min read
Save for later

Working with User Defined Values in SAP Business One

Packt
03 Jun 2011
8 min read
  Mastering SQL Queries for SAP Business One Utilize the power of SQL queries to bring Business Intelligence to your small to medium-sized business         Read more about this book       The User-Defined Values function enables SAP Business One users to enter values, originated by a predefined search process, for any field in the system (including user-defined fields). This function enables the user to enter data more efficiently and – perhaps most importantly – more accurately. In fact, the concept is sort of a "Workflow Light" implementation. It can both save user time and reduce data double entries. In this article by Gordon Du, author of Mastering SQL Queries for SAP Business One, we will see how to work with User-Defined Values. (For more resources on Microsoft, see here.) How to work with User-Defined Values To access the User-Defined Values, you can choose menu item Tools | User-Defined Values. You can also use the shortcut key Shift+Alt+F2 instead. Another option is to access it directly from a non-assigned field by using Shift+F2. This will be discussed later. You must notice that the option will not be available until you brought up at least one form. This is because the UDV has to be associated with a form. It can't stand alone. The following screenshots are taken from A/R Down Payment Invoice. It is one of the standard marketing documents. From the UDV point of view, there is no big difference between this and the other types of documents, namely, Sales Order, Purchase Order, Invoice, and so on. After a form is opened, a UDV can be defined. We will start from an empty screen to show you the first step: bringing up a form. When a form is opened, you can define or change any UDV. In this case, we stop our cursor on the Due Date field and then enter Shift+F2. A system message will pop up as shown in the following screenshot: If you click on Yes, it will bring up the same window in the manner you select the menu item mentioned earlier from the Tools menu or press Shift+Alt+F2. When you get the User-Define Values-Setup screen, you have three options. Apart from the default option: Without Search User-Define Values, you actually have only two choices: Search in Existing User-Define Values Search in Existing User-Define Values according to Saved Query Let's go through the last option first: Search in Existing User-Define Values according to Saved Query. The topic related to query will always be assigned with the top priority. There are quite a few screenshots that will help you understand the entire process. Search in existing User-Defined Values according to the saved queries The goal for this example is to input the due date as the current date automatically. The first thing to do for this option is to click on the bottom radio button among three options. The screenshot is shown next: After you have clicked the Search in Existing User-Defined Values according to Saved Query radio button, you will find a long empty textbox in a grey color and a checkbox for Auto Refresh When Field Changes underneath. Don't get confused by the color. Even though in other functions throughout SAP Business One, a gray colored field normally means that you cannot input or enter information into the field. That is not the case here. You can double-click it to get the User-Defined Values. When you double-click on the empty across-window text box, you can bring up the query manager window to select a query. You can then browse the query category that relates to Formatted Searches and find the query you need. The query called Auto Date Today in the showcase is very simple. The query script is as simple as this: SELECT GetDate() This query returns the current date as the result. You need to double-click to select the query and then go back to the previous screen but with the query name, as shown in the following screenshot: It may not be good enough to select only query because if you stop here you have to always manually trigger the FMS query run by entering Shift+F2. To automate the FMS query process, you can click on the checkbox under the selected query. After you check this box, another long text box will be displayed with a drop-down list button. Under the text box, there are two radio buttons for Auto Refresh When Field Changes: Refresh Regularly Display Saved User-Defined Value Display Saved User-Defined Values will be the default selection, if you do not change it. When you click on the drop-down list arrow button, you will get a list of fields that are associated with the current form. You can see in the following screenshot that Customer/Vendor Code field has been selected. For header document UDV, this field is often the most useful field to auto refresh the UDV. In theory, you can select any fields from the list. However, in reality only a few fields are good candidates for the task. These include Customer/Vendor Code, Document Currency, Document Number, and Document Total for document header; Item Code and Quantity for document lines. Choosing the correct data field from this drop-down list is always the most difficult step in Formatted Search, and you should test your data field selection fully. Now, the text box is filled with Customer/Vendor Code for automatically refreshing the UDV. Between two options, this query can only select the default option of Display Saved User-Defined Value. Otherwise, the date will always change to the date you have updated the document on. That will invalidate the usage of this UDV. The Refresh Regularly option is only suitable to the value that is closely related to the changed field that you have selected. In general, Display Saved User-Defined Value is always a better option than Refresh Regularly. At least it gives the system less burden. If you have selected Refresh Regularly, it means you want to get the UDV changed whenever the base field changes. The last step to set up this UDV is by clicking Update. As soon as you click the button, the User-Defined Values–Setup window will be closed. You can find a green message on the bottom-left of the screen saying Operation Completed Successfully. You can find a small "magnifying glass" added to the right corner of the Due Date field. This means the Formatted Search is successfully set up. You can try it for yourself. Sometimes this "magnifying glass" disappears for no reason. Actually, there are reasons but not easy to be understood. The main reason is that you may have assigned some different values to the same field on different forms. Other reasons may be related to add-on, and so on. In order to test this FMS, the first thing to try is to use the menu function or key combination Shift+F2. The other option is to just click on the "magnifying glass". Both functions have the same result. It will force the query to run. You can find that the date is filled by the same date as posting date and document date. You may find some interesting date definitions in SAP Business One, such as Posting Date is held by the field DocDate. Document Date however, is saved under TaxDate. Be careful in dealing with dates. You must follow the system's definition in using those terms, so that you get the correct result. A better way to use this FMS query is by entering the customer code directly without forcing FMS query to run first. The following screenshot shows that the customer code OneTime has been entered. Please note that the DueDate field is still empty. Is there anything wrong? No. That is the system's expected behavior. Only if your cursor leaves the Customer Code field, can the FMS query be triggered. That is a perfect example of When Field Value Changes. The system can only know that the field value is changed when you tab out of the field. When you are working with the field, the field is not changed yet. Be careful to follow system requirements while entering data. Never press Enter in most of the forms unless you are ready for the last step to add or update data. If you do, you may add the wrong documents to the system and they are irrevocable. The previous screenshot shows the complete process of setting up search in Existing User-Define Values according to Saved Query. Now it is time to discuss the $ sign field.
Read more
  • 0
  • 0
  • 18254

article-image-we-blog-you-blog
Packt
02 Jun 2011
1 min read
Save for later

We Blog, You Blog

Packt
02 Jun 2011
1 min read
Below are some examples of the subjects you could write about: AJAX Android BPEL Cloud Computing Content Management Systems (CMS) CRM Drupal /WordPress/Joomla! Dynamics E-Commerce Applications Enterprise E-Learning Flash Games IBM Java JBoss MySQL Mobile Development .NET Networking & Telephony Open Source Oracle PHP Python SAP Sharepoint
Read more
  • 0
  • 0
  • 6480

article-image-exporting-sap-businessobjects-dashboards-different-environments
Packt
02 Jun 2011
7 min read
Save for later

Exporting SAP BusinessObjects Dashboards into Different Environments

Packt
02 Jun 2011
7 min read
  SAP BusinessObjects Dashboards 4.0 Cookbook Introduction First, the visual model is compiled to a SWF file format. Compiling to a SWF file format ensures that the dashboard plays smoothly on different screen sizes and across different platforms. It also ensures that the users aren't given huge 10+ megabyte files. After compilation of the visual model to a SWF file, developers can then publish it to a format of their choice. The following are the available choices—Flash (SWF), AIR, SAP BusinessObjects Platform, HTML, PDF, PPT, Outlook, and Word. Once publishing is complete, the dashboard is ready to share! Exporting to a standard SWF, PPT, PDF, and so on After developing a Visual Model on Dashboard Design, we will need to somehow share it with users. We want to put it into a format that everyone can see on their machines. The simplest way is to export to a standard SWF file. One of the great features Dashboard Design has is to be able to embed dashboards into different office file formats. For example, a presenter could have a PowerPoint deck, and in the middle of the presentation, have a working dashboard that presents an important set of data values to the audience. Another example could be an executive level user who is viewing a Word document created by an analyst. The analyst could create a written document in Word and then embed a working dashboard with the most updated data to present important data values to the executive level user. You can choose to embed a dashboard in the following file types: PowerPoint Word PDF Outlook HTML Getting ready Make sure your visual model is complete and ready for sharing. How to do it... In the menu toolbar, go to File | Export | Flash (SWF). Select the directory in which you want the SWF to go to and the name of your SWF file How it works... Xcelsius compiles the visual model into an SWF file that everyone is able to see. Once the SWF file has been compiled, the dashboard will then be ready for sharing. It is mandatory that anyone viewing the dashboard have Adobe Flash installed. If not, they can download and install it from http://www.adobe.com/products/flashplayer/. If we export to PPT, we can then edit the PowerPoint file however we desire. If you have an existing PowerPoint presentation deck and want to append the dashboard to it, the easiest way is to first embed the dashboard SWF to a temporary PowerPoint file and then copy that slide to your existing PowerPoint file. There's more... Exporting to an SWF file makes it very easy for distribution, thus making the presentation of mockups great at a business level. Developers are able to work very closely with the business and iteratively come up with a visual model closest to the business goals. It is important though, when distributing SWF files, that everyone viewing the dashboards has the same version, otherwise confusion may occur. Thus, as a best practice, versioning every SWF that is distributed is very important. It is important to note that when the much anticipated Adobe Flash 10.1 was released, there were problems with embedding Dashboard Design dashboards in DOC, PPT, PDF, and so on. However, with the 10.1.82.76 Adobe Flash Player update, this has been fixed. Thus, it is important that if users have Adobe Flash Player 10.1+ installed, the version is higher than or equal to 10.1.82.76. When exporting to PDF, please take the following into account: In Dashboard Design 2008, the default format for exporting to PDF is Acrobat 9.0 (PDF 1.8). If Acrobat Reader 8.0 is installed, the default exported PDF cannot be opened. If using Acrobat Reader 8.0 or older, change the format to "Acrobat 6.0 (PDF 1.5)" before exporting to PDF. Exporting to SAP Business Objects Enterprise After Dashboard Design became a part of BusinessObjects, it was important to be able to export dashboards into the BusinessObjects Enterprise system. Once a dashboard is exported to BusinessObjects Enterprise, users can then easily access their dashboards through InfoView (now BI launch pad). On top of that, administrators are able control dashboard security. Getting ready Make sure your visual model is complete and ready for sharing. How to do it... From the menu toolbar, go to File | Export | Export to SAP BusinessObjects Platform. Enter your BusinessObjects login credentials and then select the location in the SAP BusinessObjects Enterprise system, where you want to store the SWF file, as shown in the following screenshot: Log into BI launch pad (formerly known as InfoView) and verify that you can access the dashboard. (Move the mouse over the image to enlarge.) How it works... When we export a dashboard to SAP BusinessObjects Enterprise, we basically place it in the SAP BusinessObjects Enterprise content management system. From there, we can control accessibility to the dashboard and make sure that we have one source of truth instead of sending out multiple dashboards through e-mail and possibly getting mixed up with what is the latest version. When we log into BI launch pad (formerly known as Infoview), it also passes the login token to the dashboard, so we don't have to enter our credentials again when connecting to SAP BusinessObjects Enterprise data. This is important because we don't have to manually create and pass any additional tokens once we have logged in. There's more... To give a true website type feel, developers can house their dashboards in a website type format using Dashboard Builder. This in turn provides a better experience for users, as they don't have to navigate through many folders in order to access the dashboard that they are looking for. Publishing to SAP BW This recipe shows you how to publish Dashboard Design dashboards to a SAP BW system. Once a dashboard is saved to the SAP BW system, it can be published within a SAP Enterprise Portal iView and made available for the users. Getting ready For this recipe, you will need an Dashboard Design dashboard model. This dashboard does not necessarily have to include a data connection to SAP BW. How to do it... Select Publish in the SAP menu. If you want to save the Xcelsius model with a different name, select the Publish As... option. If you are not yet connected to the SAP BW system, a pop up will appear. Select the appropriate system and fill in your username and password in the dialog box. If you want to disconnect from the SAP BW system and connect to a different system, select the Disconnect option from the SAP menu. Enter the Description and Technical Name of the dashboard. Select the location you want to save the dashboard to and click on Save. The dashboard is now published to the SAP BW system. To launch the dashboard and view it from the SAP BW environment, select the Launch option from the SAP menu. You will be asked to log in to the SAP BW system before you are able to view the dashboard. How it works... As we have seen in this recipe, the publishing of an Dashboard Design dashboard to SAP BW is quite straightforward. As the dashboard is part of the SAP BW environment after publishing, the model can be transported between SAP BW systems like all other SAP BW objects. There is more... After launching step 5, the Dashboard Design dashboard will load in your browser from the SAP BW server. You can add the displayed URL to an SAP Enterprise Portal iView to make the dashboard accessible for portal users.  
Read more
  • 0
  • 0
  • 7527
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-away3d-detecting-collisions
Packt
02 Jun 2011
6 min read
Save for later

Away3D: Detecting Collisions

Packt
02 Jun 2011
6 min read
Away3D 3.6 Cookbook Over 80 practical recipes for creating stunning graphics and effects with the fascinating Away3D engine Introduction In this article, you are going to learn how to check intersection (collision) between 3D objects. Detecting collisions between objects in Away3D This recipe will teach you the fundamentals of collision detection between objects in 3D space. We are going to learn how to perform a few types of intersection tests. These tests can hardly be called collision detection in their physical meaning, as we are not going to deal here with any simulation of collision reaction between two bodies. Instead, the goal of the recipe is to understand the collision tests from a mathematical point of view. Once you are familiar with intersection test techniques,the road to creating of physical collision simulations is much shorter. There are many types of intersection tests in mathematics. These include some simple tests such as AABB (axially aligned bounding box), Sphere - Sphere, or more complex such as Triangle - Triangle, Ray - Plane, Line - Plane, and more. Here, we will cover only those which we can achieve using built-in Away3D functionality. These are AABB and AABS (axially aligned bounding sphere) intersections, as well as Ray-AABS and the more complex Ray- Triangle. The rest of the methods are outside of the scope of this article and you can learn about applying them from various 3D math resources. Getting ready Setup an Away3D scene in a new file extending AwayTemplate. Give the class a name CollisionDemo. How to do it... In the following example, we perform an intersection test between two spheres based on their bounding boxes volumes. You can move one of the spheres along X and Y with arrow keys onto the second sphere. On the objects overlapping, the intersected (static) sphere glows with a red color. AABB test: CollisionDemo.as package { public class CollisionDemo extends AwayTemplate { private var _objA:Sphere; private var _objB:Sphere; private var _matA:ColorMaterial; private var _matB:ColorMaterial; private var _gFilter_GlowFilter=new GlowFilter(); public function CollisionDemo() { super(); _cam.z=-500; } override protected function initMaterials() : void{ _matA=new ColorMaterial(0xFF1255); _matB=new ColorMaterial(0x00FF11); } override protected function initGeometry() : void{ _objA=new Sphere({radius:30,material:_matA}); _objB=new Sphere({radius:30,material:_matB}); _view.scene.addChild(_objA); _view.scene.addChild(_objB); _objB.ownCanvas=true; _objA.debugbb=true; _objB.debugbb=true; _objA.transform.position=new Vector3D(-80,0,400); _objB.transform.position=new Vector3D(80,0,400); } override protected function initListeners() : void{ super.initListeners(); stage.addEventListener(KeyboardEvent.KEY_DOWN,onKeyDown); } override protected function onEnterFrame(e:Event) : void{ super.onEnterFrame(e); if(AABBTest()){ _objB.filters=[_gFilter]; }else{ _objB.filters=[]; } } private function AABBTest():Boolean{ if(_objA.parentMinX>_objB.parentMaxX||_objB.parentMinX>_objA. parentMaxX){ return false; } if(_objA.parentMinY>_objB.parentMaxY||_objB.parentMinY>_objA. parentMaxY){ return false; } if(_objA.parentMinZ>_objB.parentMaxZ||_objB.parentMinZ>_objA. parentMaxZ){ return false; } return true; } private function onKeyDown(e:KeyboardEvent):void{ switch(e.keyCode){ case 38:_objA.moveUp(5); break; case 40:_objA.moveDown(5); break; case 37:_objA.moveLeft(5); break; case 39:_objA.moveRight(5); break; case 65:_objA.rotationZ-=3; break; case 83:_objA.rotationZ+=3; break; default: } } } } In this screenshot, the green sphere bounding box has a red glow while it is being intersected by the red sphere's bounding box: How it works... Testing intersections between two AABBs is really simple. First, we need to acquire the boundaries of the object for each axis. The box boundaries for each axis of any Object3D are defined by a minimum value for that axis and maximum value. So let's look at the AABBTest() method. Axis boundaries are defined by parentMin and parentMax for each axis, which are accessible for each object extending Object3D. You can see that Object3D also has minX,minY,minZ and maxX,maxY,maxZ. These properties define the bounding box boundaries too, but in objects space and therefore aren't helpful in AABB tests between two objects. So in order for a given bounding box to intersect a bounding box of other objects, three conditions have to be met for each of them: Minimal X coordinate for each of the objects should be less than maximum X of another. Minimal Y coordinate for each of the objects should be less than maximum Y of another. Minimal Z coordinate for each of the objects should be less than maximum Z of another. If one of the conditions is not met for any of the two AABBs, there is no intersection. The preceding algorithm is expressed in the AABBTest() function: private function AABBTest():Boolean{ if(_objA.parentMinX>_objB.parentMaxX||_objB.parentMinX>_objA. parentMaxX){ return false; } if(_objA.parentMinY>_objB.parentMaxY||_objB.parentMinY>_objA. parentMaxY){ return false; } if(_objA.parentMinZ>_objB.parentMaxZ||_objB.parentMinZ>_objA. parentMaxZ){ return false; } return true; } As you can see, if all of the conditions we listed previously are met, the execution will skip all the return false blocks and the function will return true, which means the intersection has occurred. There's more... Now let's take a look at the rest of the methods for collision detection, which are AABS-AABS, Ray-AABS, and Ray-Triangle. AABS test The intersection test between two bounding spheres is even simpler to perform than AABBs. The algorithm works as follows. If the distance between the centers of two spheres is less than the sum of their radius, then the objects intersect. Piece of cake! Isn't it? Let's implement it within the code. The AABS collision algorithm gives us the best performance. While there are many other even more sophisticated approaches, try to use this test if you are not after extreme precision. (Most of the casual games can live with this approximation). First, let's switch the debugging mode of _objA and _objB to bounding spheres. In the last application we built, go to the initGeometry() function and change: _objA.debugbb=true; _objB.debugbb=true; To: _objA.debugbs=true; _objB.debugbs=true; Next, we add the function to the class which implements the algorithm we described previously: private function AABSTest():Boolean{ var dist_Number=Vector3D.distance(_objA.position,_objB. position); if(dist<=(_objA.radius+_objB.radius)){ return true; } return false; } Finally, we add the call to the method inside onEnterFrame(): if(AABSTest()){ _objB.filters=[_gFilter]; }else{ _objB.filters=[]; } Each time AABSTest returns true, the intersected sphere is highlighted with a red glow:
Read more
  • 0
  • 0
  • 12164

article-image-netbeans-ide-7-building-ejb-application
Packt
01 Jun 2011
10 min read
Save for later

NetBeans IDE 7: Building an EJB Application

Packt
01 Jun 2011
10 min read
  NetBeans IDE 7 Cookbook Over 70 highly focused practical recipes to maximize your output with NetBeans         Introduction Enterprise Java Beans (EJB) is a framework of server-side components that encapsulates business logic. These components adhere to strict specifications on how they should behave. This ensures that vendors who wish to implement EJB-compliant code must follow conventions, protocols, and classes ensuring portability. The EJB components are then deployed in EJB containers, also called application servers, which manage persistence, transactions, and security on behalf of the developer. If you wish to learn more about EJBs, visit http://jcp.org/en/jsr/detail?id=318 or https://www.packtpub.com/developer-guide-for-ejb3/book. For our EJB application to run, we will need the application servers. Application servers are responsible for implementing the EJB specifications and creating the perfect environment for our EJBs to run in. Some of the capabilities supported by EJB and enforced by Application Servers are: Remote access Transactions Security Scalability NetBeans 6.9, or higher, supports the new Java EE 6 platform, making it the only IDE so far to bring the full power of EJB 3.1 to a simple IDE interface for easy development. NetBeans makes it easy to develop an EJB application and deploy on different Application Servers without the need to over-configure and mess with different configuration files. It's as easy as a project node right-click. Creating EJB project In this recipe, we will see how to create an EJB project using the wizards provided by NetBeans. Getting ready It is required to have NetBeans with Java EE support installed to continue with this recipe. If this particular NetBeans version is not available in your machine, then you can download it from http://download.netbeans.org. There are two application servers in this installation package, Apache Tomcat or GlassFish, and either one can be chosen, but at least one is necessary. In this recipe, we will use the GlassFish version that comes together with NetBeans 7.0 installation package. How to do it... Lets create a new project by either clicking File and then New Project, or by pressing Ctrl+Shift+N. In the New Project window, in the categories side, choose Java Web and in Projects side, select WebApplication, then click Next. In Name and Location, under Project Name, enter EJBApplication. Tick the Use Dedicated Folder for Storing Libraries option box. Now either type the folder path or select one by clicking on browse. After choosing the folder, we can proceed by clicking Next. In Server and Settings, under Server, choose GlassFish Server 3.1. Tick Enable Contexts and Dependency Injection. Leave the other values with their default values and click Finish. The new project structure is created. How it works... NetBeans creates a complete file structure for our project. It automatically configures the compiler and test libraries and creates the GlassFish deployment descriptor. The deployment descriptor filename specific for the GlassFish web server is glassfish-web.xml.   Adding JPA support The Java Persistence API (JPA) is one of the frameworks that equips Java with object/relational mapping. Within JPA, a query language is provided that supports the developers abstracting the underlying database. With the release of JPA 2.0, there are many areas that were improved, such as: Domain Modeling EntityManager Query interfaces JPA query language and others We are not going to study the inner workings of JPA in this recipe. If you wish to know more about JPA, visit http://jcp.org/en/jsr/detail?id=317 or http://download.oracle.com/javaee/5/tutorial/doc/bnbqa.html. NetBeans provides very good support for enabling your application to quickly create entities annotated with JPA. In this recipe, we will see how to configure your application to use JPA. We will continue to expand the previously-created project. Getting ready We will use GlassFish Server in this recipe since it is the only server that supports Java EE 6 at the moment. We also need to have Java DB configured. GlassFish already includes a copy of Java DB in its installation folder. Another source of installed Java DB is the JDK installation directory. It is not necessary to build on top of the previous recipe, but it is imperative to have a database schema. Feel free to create your own entities by following the steps presented in this recipe. How to do it... Right-click on EJBApplication node and select New Entity Classes from Database.... In Database Tables: Under Data Source, select jdbc/sample and let the IDE initialize Java DB. When Available Tables is populated, select MANUFACTURER, click Add, and then click Next. In Entity Classes: leave all the fields with their default values and only in Package, enter entities and click Finish. How it works... NetBeans then imports and creates our Java class from the database schema, in our case the Manufacturer.java file placed under the entities package. Besides that, NetBeans makes it easy to import and start using the entity straightaway. Many of the most common queries, for example find by name, find by zip, and find all, are already built into the class itself. The JPA queries, which are akin to normal SQL queries, are defined in the entity class itself. Listed below are some of the queries defined in the entity class Manufacturer.java: @Entity @Table(name = "MANUFACTURER") @NamedQueries({ @NamedQuery(name = "Manufacturer.findAll", query = "SELECT m FROM Manufacturer m"), @NamedQuery(name = "Manufacturer.findByManufacturerId", query = "SELECT m FROM Manufacturer m WHERE m.manufacturerId = :manufacturerId"), The @Entity annotation defines that this class, Manufacturer.java, is an entity and when followed by the @Table annotation, which has a name parameter, points out the table in the Database where the information is stored. The @NamedQueries annotation is the place where all the NetBeans-generated JPA queries are stored. There can be as many @NamedQueries as the developer feels necessary. One of the NamedQueries we are using in our example is named Manufacturer.findAll, which is a simple select query. When invoked, the query is translated to: SELECT m FROM Manufacturer m On top of that, NetBeans implements the equals, hashCode, and toString methods. Very useful if the entities need to be used straight away with some collections, such as HashMap. Below is the NetBeans-generated code for both hashCode and the toString methods: @Override public int hashCode() { int hash = 0; hash += (manufacturerId != null ? manufacturerId.hashCode() : 0); return hash; } @Override public boolean equals(Object object) { // TODO: Warning - this method won't work in the case the id fields are not set if (!(object instanceof Manufacturer)) { return false; } Manufacturer other = (Manufacturer) object; if ((this.manufacturerId == null && other.manufacturerId != null) || (this.manufacturerId != null && !this.manufacturerId. equals(other.manufacturerId))) { return false; } return true; } NetBeans also creates a persistence.xml and provides a Visual Editor, simplifying the management of different Persistence Units (in case our project needs to use more than one); thereby making it possible to manage the persistence.xml without even touching the XML code. A persistence unit, or persistence.xml, is the configuration file in JPA which is placed under the configuration files, when the NetBeans view is in Projects mode. This file defines the data source and what name the persistence unit has in our example: <persistence-unit name="EJBApplicationPU" transaction-type="JTA"> <jta-data-source>jdbc/sample</jta-data-source> <properties/> </persistence-unit> The persistence.xml is placed in the configuration folder, when using the Projects view. In our example, our persistence unit name is EJBApplicationPU, using the jdbc/sample as the data source. To add more PUs, click on the Add button that is placed on the uppermost right corner of the Persistence Visual Editor. This is an example of adding another PU to our project:   Creating Stateless Session Bean A Session Bean encapsulates business logic in methods, which in turn are executed by a client. This way, the business logic is separated from the client. Stateless Session Beans do not maintain state. This means that when a client invokes a method in a Stateless bean, the bean is ready to be reused by another client. The information stored in the bean is generally discarded when the client stops accessing the bean. This type of bean is mainly used for persistence purposes, since persistence does not require a conversation with the client. It is not in the scope of this recipe to learn how Stateless Beans work in detail. If you wish to learn more, please visit: http://jcp.org/en/jsr/detail?id=318 or https://www.packtpub.com/developer-guide-for-ejb3/book In this recipe, we will see how to use NetBeans to create a Stateless Session Bean that retrieves information from the database, passes through a servlet and prints this information on a page that is created on-the-fly by our servlet. Getting ready It is required to have NetBeans with Java EE support installed to continue with this recipe. If this particular NetBeans version is not available in your machine, please visit http://download.netbeans.org. We will use the GlassFish Server in this recipe since it is the only Server that supports Java EE 6 at the moment. We also need to have Java DB configured. GlassFish already includes a copy of Java DB in its installation folder. It is possible to follow the steps on this recipe without the previous code, but for better understanding we will continue to build on the top of the previous recipes source code. How to do it... Right-click on EJBApplication node and select New and Session Bean.... For Name and Location: Name the EJB as ManufacturerEJB. Under Package, enter beans. Leave Session Type as Stateless. Leave Create Interface with nothing marked and click Finish. Here are the steps for us to create business methods: Open ManufacturerEJB and inside the class body, enter: @PersistenceUnit EntityManagerFactory emf; public List findAll(){ return emf.createEntityManager().createNamedQuery("Manufacturer. findAll").getResultList(); } Press Ctrl+Shift+I to resolve the following imports: java.util.List; javax.persistence.EntityManagerFactory; javax.persistence.PersistenceUnit; Creating the Servlet: Right-click on the EJBApplication node and select New and Servlet.... For Name and Location: Name the servlet as ManufacturerServlet. Under package, enter servlets. Leave all the other fields with their default values and click Next. For Configure Servlet Deployment: Leave all the default values and click Finish. With the ManufacturerServlet open: After the class declaration and before the processRequest method, add: @EJB ManufacturerEJB manufacturerEJB; Then inside the processRequest method, first line after the try statement, add: List<Manufacturer> l = manufacturerEJB.findAll(); Remove the /* TODO output your page here and also */. And finally replace: out.println("<h1>Servlet ManufacturerServlet at " + request. getContextPath () + "</h1>"); With: for(int i = 0; i < 10; i++ ) out.println("<b>City</b>"+ l.get(i).getCity() +", <b>State</b>"+ l.get(i).getState() +"<br>" ); Resolve all the import errors and save the file. How it works... To execute the code produced in this recipe, right-click on the EJBApplication node and select Run. When the browser launches append to the end of the URL/ManufacturerServlet, hit Enter. Our application will return City and State names. One of the coolest features in Java EE 6 is that usage of web.xml can be avoided if annotating the servlet. The following code does exactly that: @WebServlet(name="ManufacturerServlet", urlPatterns={"/ ManufacturerServlet"}) Since we are working on Java EE 6, our Stateless bean does not need the daunting work of creating interfaces, the @Stateless annotation takes care of that, making it easier to develop EJBs. We then add the persistence unit, represented by the EntityManagerFactory and inserted by the @PersistenceUnit annotation. Finally we have our business method that is used from the servlet. The findAll method uses one of the named queries from our entity to fetch information from the database.  
Read more
  • 0
  • 0
  • 7100

article-image-python-testing-coverage-analysis
Packt
01 Jun 2011
13 min read
Save for later

Python Testing: Coverage Analysis

Packt
01 Jun 2011
13 min read
Python Testing Cookbook Over 70 simple but incredibly effective recipes for taking control of automated testing using powerful Python testing tools Introduction A coverage analyzer can be used while running a system in production, but what are the pros and cons, if we used it this way? What about using a coverage analyzer when running test suites? What benefits would this approach provide compared to checking systems in production? Coverage helps us to see if we are adequately testing our system. But it must be performed with a certain amount of skepticism. This is because, even if we achieve 100 percent coverage, meaning every line of our system was exercised, in no way does this guarantee us having no bugs. A quick example involves a code we write and what it processes is the return value from a system call. What if there are three possible values, but we only handle two of them? We may write two test cases covering our handling of it, and this could certainly achieve 100 percent statement coverage. However, it doesn't mean we have handled the third possible return value; thus, leaving us with a potentially undiscovered bug. 100 percent code coverage can also be obtained by condition coverage but may not be achieved with statement coverage. The kind of coverage we are planning to target should be clear. Another key point is that not all testing is aimed at bug fixing. Another key purpose is to make sure that the application meets our customer's needs. This means that, even if we have 100 percent code coverage, we can't guarantee that we are covering all the scenarios expected by our users. This is the difference between 'building it right' and 'building the right thing'. In this article, we will explore various recipes to build a network management application, run coverage tools, and harvest the results. We will discuss how coverage can introduce noise, and show us more than we need to know, as well as introduce performance issues when it instruments our code. We will also see how to trim out information we don't need to get a concise, targeted view of things. This article uses several third-party tools in many recipes. Spring Python (http://springpython.webfactional.com) contains many useful abstractions. The one used in this article is its DatabaseTemplate, which offers easy ways to write SQL queries and updates without having to deal with Python's verbose API. Install it by typing pip install springpython. Install the coverage tool by typing pip install coverage. This may fail because other plugins may install an older version of coverage. If so, uninstall coverage by typing pip uninstall coverage, and then install it again with pip install coverage. Nose is a useful test runner.   Building a network management application For this article, we will build a very simple network management application, and then write different types of tests and check their coverage. This network management application is focused on digesting alarms, also referred to as network events. This is different from certain other network management tools that focus on gathering SNMP alarms from devices. For reasons of simplicity, this correlation engine doesn't contain complex rules, but instead contains simple mapping of network events onto equipment and customer service inventory. We'll explore this in the next few paragraphs as we dig through the code. How to do it... With the following steps, we will build a simple network management application. Create a file called network.py to store the network application. Create a class definition to represent a network event. class Event(object): def __init__(self, hostname, condition, severity, event_time): self.hostname = hostname self.condition = condition self.severity = severity self.id = -1 def __str__(self): return "(ID:%s) %s:%s - %s" % (self.id, self.hostname, self.condition, self.severity) hostname: It is assumed that all network alarms originate from pieces of equipment that have a hostname. condition: Indicates the type of alarm being generated. Two different alarming conditions can come from the same device. severity: 1 indicates a clear, green status; and 5 indicates a faulty, red status. id: The primary key value used when the event is stored in a database. Create a new file called network.sql to contain the SQL code. Create a SQL script that sets up the database and adds the definition for storing network events. CREATE TABLE EVENTS ( ID INTEGER PRIMARY KEY, HOST_NAME TEXT, SEVERITY INTEGER, EVENT_CONDITION TEXT ); Code a high-level algorithm where events are assessed for impact to equipment and customer services and add it to network.py. from springpython.database.core import* class EventCorrelator(object): def __init__(self, factory): self.dt = DatabaseTemplate(factory) def __del__(self): del(self.dt) def process(self, event): stored_event, is_active = self.store_event(event) affected_services, affected_equip = self.impact(event) updated_services = [ self.update_service(service, event) for service in affected_services] updated_equipment = [ self.update_equipment(equip, event) for equip in affected_equip] return (stored_event, is_active, updated_services, updated_equipment) The __init__ method contains some setup code to create a DatabaseTemplate. This is a Spring Python utility class used for database operations. See http://static.springsource.org/spring- python/1.2.x/sphinx/html/dao.html for more details. We are also using sqlite3 as our database engine, since it is a standard part of Python. The process method contains some simple steps to process an incoming event. We first need to store the event in the EVENTS table. This includes evaluating whether or not it is an active event, meaning that it is actively impacting a piece of equipment. Then we determine what equipment and what services the event impacts. Next, we update the affected services by determining whether it causes any service outages or restorations. Then we update the affected equipment by determining whether it fails or clears a device. Finally, we return a tuple containing all the affected assets to support any screen interfaces that could be developed on top of this. Implement the store_event algorithm. def store_event(self, event): try: max_id = self.dt.query_for_int("""select max(ID) from EVENTS""") except DataAccessException, e: max_id = 0 event.id = max_id+1 self.dt.update("""insert into EVENTS (ID, HOST_NAME, SEVERITY, EVENT_CONDITION) values (?,?,?,?)""", (event.id, event.hostname, event.severity, event.condition)) is_active = self.add_or_remove_from_active_events(event) return (event, is_active) This method stores every event that is processed. This supports many things including data mining and post mortem analysis of outages. It is also the authoritative place where other event-related data can point back using a foreign key. The store_event method looks up the maximum primary key value from the EVENTS table. It increments it by one. It assigns it to event.id. It then inserts it into the EVENTS table. Next, it calls a method to evaluate whether or not the event should be add to the list of active events, or if it clears out existing active events. Active events are events that are actively causing a piece of equipment to be unclear. Finally, it returns a tuple containing the event and whether or not it was classified as an active event. For a more sophisticated system, some sort of partitioning solution needs to be implemented. Querying against a table containing millions of rows is very inefficient. However, this is for demonstration purposes only, so we will skip scaling as well as performance and security. Implement the method to evaluate whether to add or remove active events. def add_or_remove_from_active_events(self, event): """Active events are current ones that cause equipment and/or services to be down.""" if event.severity == 1: self.dt.update("""delete from ACTIVE_EVENTS where EVENT_FK in ( select ID from EVENTS where HOST_NAME = ? and EVENT_CONDITION = ?)""", (event.hostname,event.condition)) return False else: self.dt.execute("""insert into ACTIVE_EVENTS (EVENT_FK) values (?)""", (event.id,)) return True When a device fails, it sends a severity 5 event. This is an active event and in this method, a row is inserted into the ACTIVE_EVENTS table, with a foreign key pointing back to the EVENTS table. Then we return back True, indicating this is an active event. Add the table definition for ACTIVE_EVENTS to the SQL script. CREATE TABLE ACTIVE_EVENTS ( ID INTEGER PRIMARY KEY, EVENT_FK, FOREIGN KEY(EVENT_FK) REFERENCES EVENTS(ID) ); This table makes it easy to query what events are currently causing equipment failures. Later, when the failing condition on the device clears, it sends a severity 1 event. This means that severity 1 events are never active, since they aren't contributing to a piece of equipment being down. In our previous method, we search for any active events that have the same hostname and condition, and delete them. Then we return False, indicating this is not an active event. Write the method that evaluates the services and pieces of equipment that are affected by the network event. def impact(self, event): """Look up this event has impact on either equipment or services.""" affected_equipment = self.dt.query( """select * from EQUIPMENT where HOST_NAME = ?""", (event.hostname,), rowhandler=DictionaryRowMapper()) affected_services = self.dt.query( """select SERVICE.* from SERVICE join SERVICE_MAPPING SM on (SERVICE.ID = SM.SERVICE_FK) join EQUIPMENT on (SM.EQUIPMENT_FK = EQUIPMENT.ID where EQUIPMENT.HOST_NAME = ?""", (event.hostname,), rowhandler=DictionaryRowMapper()) return (affected_services, affected_equipment) We first query the EQUIPMENT table to see if event.hostname matches anything. Next, we join the SERVICE table to the EQUIPMENT table through a many-to many relationship tracked by the SERVICE_MAPPING table. Any service that is related to the equipment that the event was reported on is captured. Finally, we return a tuple containing both the list of equipment and list of services that are potentially impacted. Spring Python provides a convenient query operation that returns a list of objects mapped to every row of the query. It also provides an out-of-the-box DictionaryRowMapper that converts each row into a Python dictionary, with the keys matching the column names. Add the table definitions to the SQL script for EQUIPMENT, SERVICE, and SERVICE_MAPPING. CREATE TABLE EQUIPMENT ( ID INTEGER PRIMARY KEY, HOST_NAME TEXT UNIQUE, STATUS INTEGER ); CREATE TABLE SERVICE ( ID INTEGER PRIMARY KEY, NAME TEXT UNIQUE, STATUS TEXT ); CREATE TABLE SERVICE_MAPPING ( ID INTEGER PRIMARY KEY, SERVICE_FK, EQUIPMENT_FK, FOREIGN KEY(SERVICE_FK) REFERENCES SERVICE(ID), FOREIGN KEY(EQUIPMENT_FK) REFERENCES EQUIPMENT(ID) ); Write the update_service method that stores or clears service-related even and then updates the service's status based on the remaining active events. def update_service(self, service, event): if event.severity == 1: self.dt.update("""delete from SERVICE_EVENTS where EVENT_FK in ( select ID from EVENTS where HOST_NAME = ? and EVENT_CONDITION = ?)""", (event.hostname,event.condition)) else: self.dt.execute("""insert into SERVICE_EVENTS (EVENT_FK, SERVICE_FK) values (?,?)""", (event.id,service["ID"])) try: max = self.dt.query_for_int( """select max(EVENTS.SEVERITY) from SERVICE_EVENTS SE join EVENTS on (EVENTS.ID = SE.EVENT_FK) join SERVICE on (SERVICE.ID = SE.SERVICE_FK) where SERVICE.NAME = ?""", (service["NAME"],)) except DataAccessException, e: max = 1 if max > 1 and service["STATUS"] == "Operational": service["STATUS"] = "Outage" self.dt.update("""update SERVICE set STATUS = ? where ID = ?""", (service["STATUS"], service["ID"])) if max == 1 and service["STATUS"] == "Outage": service["STATUS"] = "Operational" self.dt.update("""update SERVICE set STATUS = ? where ID = ?""", (service["STATUS"], service["ID"])) if event.severity == 1: return {"service":service, "is_active":False} else: return {"service":service, "is_active":True} Service-related events are active events related to a service. A single event can be related to many services. For example, what if we were monitoring a wireless router that provided Internet service to a lot of users, and it reported a critical error? This one event would be mapped as an impact to all the end users. When a new active event is processed, it is stored in SERVICE_EVENTS for each related service. Then, when a clearing event is processed, the previous service event must be deleted from the SERVICE_EVENTS table. Add the table defnition for SERVICE_EVENTS to the SQL script. CREATE TABLE SERVICE_EVENTS ( ID INTEGER PRIMARY KEY, SERVICE_FK, EVENT_FK, FOREIGN KEY(SERVICE_FK) REFERENCES SERVICE(ID), FOREIGN KEY(EVENT_FK) REFERENCES EVENTS(ID) ); It is important to recognize that deleting an entry from SERVICE_EVENTS doesn't mean that we delete the original event from the EVENTS table. Instead, we are merely indicating that the original active event is no longer active and it does not impact the related service. Prepend the entire SQL script with drop statements, making it possible to run the script for several recipes DROP TABLE IF EXISTS SERVICE_MAPPING; DROP TABLE IF EXISTS SERVICE_EVENTS; DROP TABLE IF EXISTS ACTIVE_EVENTS; DROP TABLE IF EXISTS EQUIPMENT; DROP TABLE IF EXISTS SERVICE; DROP TABLE IF EXISTS EVENTS; Append the SQL script used for database setup with inserts to preload some equipment and services. INSERT into EQUIPMENT (ID, HOST_NAME, STATUS) values (1, 'pyhost1', 1); INSERT into EQUIPMENT (ID, HOST_NAME, STATUS) values (2, 'pyhost2', 1); INSERT into EQUIPMENT (ID, HOST_NAME, STATUS) values (3, 'pyhost3', 1); INSERT into SERVICE (ID, NAME, STATUS) values (1, 'service-abc', 'Operational'); INSERT into SERVICE (ID, NAME, STATUS) values (2, 'service-xyz', 'Outage'); INSERT into SERVICE_MAPPING (SERVICE_FK, EQUIPMENT_FK) values (1,1); INSERT into SERVICE_MAPPING (SERVICE_FK, EQUIPMENT_FK) values (1,2); INSERT into SERVICE_MAPPING (SERVICE_FK, EQUIPMENT_FK) values (2,1); INSERT into SERVICE_MAPPING (SERVICE_FK, EQUIPMENT_FK) values (2,3); Finally, write the method that updates equipment status based on the current active events. def update_equipment(self, equip, event): try: max = self.dt.query_for_int( """select max(EVENTS.SEVERITY) from ACTIVE_EVENTS AE join EVENTS on (EVENTS.ID = AE.EVENT_FK) where EVENTS.HOST_NAME = ?""", (event.hostname,)) except DataAccessException: max = 1 if max != equip["STATUS"]: equip["STATUS"] = max self.dt.update("""update EQUIPMENT set STATUS = ?""", (equip["STATUS"],)) return equip Here, we need to find the maximum severity from the list of active events for a given host name. If there are no active events, then Spring Python raises a DataAccessException and we translate that to a severity of 1. We check if this is different from the existing device's status. If so, we issue a SQL update. Finally, we return the record for the device, with its status updated appropriately. How it works... This application uses a database-backed mechanism to process incoming network events, and checks them against the inventory of equipment and services to evaluate failures and restorations. Our application doesn't handle specialized devices or unusual types of services. This real-world complexity has been traded in for a relatively simple application, which can be used to write various test recipes. Events typically map to a single piece of equipment and to zero or more services. A service can be thought of as a string of equipment used to provide a type of service to the customer. New failing events are considered active until a clearing event arrives. Active events, when aggregated against a piece of equipment, define its current status. Active events, when aggregated against a service, defines the service's current status.  
Read more
  • 0
  • 0
  • 3472

article-image-html5-generic-containers
Packt
01 Jun 2011
15 min read
Save for later

HTML5: Generic Containers

Packt
01 Jun 2011
15 min read
  HTML5 Multimedia Development Cookbook Recipes for practical, real-world HTML5 multimedia driven development.         Read more about this book       (For more resources on Multimedia development, see here.) Introduction "On the web, a man should not be judged by the color of his skin but by the content of his content." - Internet meme To be correct according to the specification semantically, we need to know what the content is so we can wrap it with the most appropriate new element tag. While this may mean we developers have to think differently, a new challenge is exactly why we're here. In this article we'll look at some examples of how to do just that using several of HTML5's new elements. "In case of conflict, consider users over authors over implementers over specifiers over theoretical purity." - Priority of Constituencies Throughout this article, we'll show you how to use the new <article> element to mark up both blog posts and comments, add a meaningful publication date to an <article>, use the new <mark> element to highlight text, and how to note visual elements using the new <figure> element. We'll then turn our attention to some new methods of styling text with font replacement techniques, as well as adding drop shadows and gradients to our text.   Structuring a blog article "The <article> element represents a self-contained composition in a document, page, application, or site and that is, in principle, independently distributable or reusable, e.g. in syndication. This could be a forum post, a magazine or newspaper article, a blog entry, a user-submitted comment, an interactive widget or gadget, or any other independent item of content." - WHATWG's HTML5 Draft Standard - http://whatwg.org/html5 Getting ready Blog entries are perfect candidates for the new <article> element, which is designed for syndicated content. For this recipe, let's start by identifying the major elements of a blog <article>: There's usually a headline in the form of a heading tag, the blog entry itself consisting of several paragraphs and perhaps one or more images, and some information that usually includes the author's name and other related metadata. Notice this is all self-contained related content. How to do it... We're going to continue using the new HTML5 <header> and <footer> elements. The headline, entry and meta-information should be wrapped in their own unique tags, like <h2>, multiple <p>s and the new &ltfooter>. Let's start with a foundation and add our new <article> element twice: <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Blog Title</title> <!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"> </script>[endif]--> <meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body><article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer></article><article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer></article></body></html> Put your code on a diet? Ready for a shocker? Want to have your mind blown? The <html> and <head> and <body> tags (as well as their closing tags) are now optional in the HTML5 specification. Sure, you could leave them in there, and your pages will validate just fine, but why should we? If remove them from the previous code, we are left with the spartan: <!DOCTYPE html><meta charset="UTF-8"><title>Blog Title</title><!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"> </script>[endif]--><meta name="viewport" content="width=device-width, initial-scale=1.0"><article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer></article><article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer></article> Don't believe me? Run that code through the World Wide Web Consortium's validator at: http://validator.w3.org, and you'll see it displays correctly in the browser. Well, not so fast buster. The problem is that removing those elements breaks our code for screen readers. Uh oh. Strike one. Also, removing the <body> tag breaks our new HTML5-enabling JavaScript for Internet Explorer. Strike two. And guess what? You can see it coming, can't you? Yes, removing the <html> tag removes the language of the page. There it is: Strike three. So let's add those elements back in, shall we? <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title>Blog Title</title> <!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"> </script>[endif]--> <meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body> <article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article> <article> <header> <h2>Headline</h2> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article></body></html> There, that's better. How it works... Remember, the new <article> element is a collection of related information intended for syndication via RSS or another means. There's more... Richer, more meaningful semantics is perhaps the most significant goal for HTML5. It's better for machines, better for authors, and most importantly, better for our audiences. Validation as an aid, not a crutch As we saw previously, removing the &lthtml> and <head> and <body> tags render a still valid page. So that begs the question of how valid validators are. Unlike the XML world, HTML5 can use incorrect syntax and still render just fine. The author makes every effort to validate his code whenever possible. It's not necessary to be slavish to the validator, but it's always a good quality control check. And the closer you get to valid code, the better chance browsers will display your work in as consistent a manner as possible. Eric Meyer's funny The author loves how CSS guru Eric Meyer thinks about validators: Where to find validators You can make good use of code validators at: http://validator.nu http://validator.w3.org   Highlighting text using the mark element "The &ltmark> element represents a run of text in one document marked or highlighted for reference purposes, due to its relevance in another context. When used in a quotation or other block of text referred to from the prose, it indicates a highlight that was not originally present but which has been added to bring the reader's attention to a part of the text that might not have been considered important by the original author when the block was originally written, but which is now under previously unexpected scrutiny. When used in the main prose of a document, it indicates a part of the document that has been highlighted due to its likely relevance to the user's current activity." - WHATWG's HTML5 Draft Standard - http://whatwg.org/html5 Getting ready When viewing search results, you'll often find the term for which you searched highlighted. Instead of relying on a semantically meaningless tag, we can now use the more meaningful <mark> element. How to do it... In this recipe, you'll see HTML5doctor.com has an excellent example of how to use the new <mark> element to highlight a search results term. This gives a useful semantic hook not only for styling but also for the machine tracking the results. <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title> <!--[if lt IE 9]><script src="http://html5shiv.googlecode.com/svn/trunk/html5.js"> </script>[endif]--> <meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body> <h1>716,000,000 search results for the query "<mark>HTML 5</mark>"</h1> <section id="search-results"> <article> <h2><a href="http://en.wikipedia.org/wiki/HTML_5"> <mark>HTML 5</mark> - Wikipedia, the free encyclopedia</a></h2> <p><mark>HTML 5</mark> is the next major revision of <mark>HTML</mark> ("hypertext markup language"), the core markup language of the World Wide Web. The WHATWG started work on the ... <a href="http://en.wikipedia.org/wiki/HTML_5"> Read more</a></p> </article> <article> <h2><a href="http://dev.w3.org/html5/spec/Overview.html"> <mark>HTML 5</mark></a></h2> <p>A vocabulary and associated APIs for <mark>HTML</mark> and XHTML. Editor's Draft 16 August 2009. Latest Published Version: http://w3.org/TR/<mark>html5</mark>/; Latest Editor's ... <a href="http://dev.w3.org/html5/spec/Overview.html"> Read more</a></p> </article> </section></body></html> Adding a simple style declaration like: <style type="text/css"> mark {background-color: yellow; font-weight: bold;}</style> in the <head> section helps us render this highlighted text: How it works... The new <mark> element simply highlights a word or phrase to draw the reader's attention. To do this, simply specify the <mark> to be bold or italicized or highlighted in some way in your corresponding Cascading Style Sheet. There's more... Sure, you could mark up and style a search-results page to use the <b> or <i> or even <span> tags to indicate for which term the search took place, but each of those tags only affects the presentation layer. They lack meaning. The new &ltmark> element can accomplish the same visual effect, while also adding that extra meaning to your markup. In fact, the new &ltmark> element is full of win. <Mark> long and prosper Another great use of the new <mark> element is highlighting a date in a calendar picker, as we often see on any date-based reservation system website like Priceline.com. Priceline.com highlights the current date by default when booking your itinerary. Instead of using a semantically meaningless tag to achieve this, the new <mark> element could be a perfect candidate to use. Waiting for browsers The new <mark> element isn't fully supported by any web browser at the time of this writing. Though the extra semantic meaning may not be apparent to machine readers, we can still use the new <mark> element as a stylistic "hook" until the day its meaning is fully supported by a variety of browsers. Is "future proof" a word? Remember that HTML5's new elements attempt to add extra meaning to our markup. The goal is never to take away meaning or break pages. With this in mind, it becomes much more palatable to layer on new elements like the <mark> element that's not fully implemented by browsers yet. Even if its meaning is not fully understood by machines yet, it certainly does not hurt to add it and make our pages as "future proof" as we possibly can. See also In 2001, Carrie Bickner prepared the "New York Public Library Online Style Guide" (http://legacy.www.nypl.org/styleguide) for branches of the NYPL to use when updating their websites. In this seminal publication, Bickner made the case for web standards by separating content (markup) from presentation (Cascading Style Sheets) from behavior (JavaScript). The publication was extremely forward-thinking for the time and was in use for many years.   Using the time element "The &lttime> element represents either a time on a 24-hour clock, or a precise date in the proleptic Gregorian calendar, optionally with a time and a time-zone offset." - WHATWG's HTML5 Draft Standard - http://whatwg.org/html5 Getting ready The new <time> element is a powerful way to display time or a specific date. How to do it... In this recipe we'll display dates and times that will be readable for both humans and machines. Let's look at four examples. <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8"> <title></title> <!--[if lt IE 9]><script src=http://html5shiv.googlecode.com/svn/trunk/html5.js> </script>[endif]--> <meta name="viewport" content="width=device-width, initial-scale=1.0"></head><body> <article> <header> <h2>Headline</h2> <time datetime="2010-11-29">November 29, 2010</time> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article> <article> <header> <h2>Headline</h2> <time datetime="2010-11-29">Nov. 29</time> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article> <article> <header> <h2>Headline</h2> <time datetime="2010-11-29">the date this was written</time> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article> <article> <header> <h2>Headline</h2> <time datetime="2010-11-29T11:34">the date and time this was written</time> </header> <p>First paragraph</p> <p>Second paragraph</p> <footer>Meta information.</footer> </article></body></html> How it works... We can use the new <time> element to indicate specific dates, times, or both. There's more... The new &lttime> element specifies an exact moment in time—not a time period. Odd rules One interesting aspect of the new <time> element is that you can't use a date before the Christian Era. You also can't use a date like "November 2010." Whatever date we specify must be a positive, specific date—not a relative one. The HTML5 Working Group continues to address this seemingly arbitrary restriction. <time>'s Time will come Browsers display the new <time> element but don't do anything special with it—yet. Always remember SEO Time. Why are we so obsessed with it? One very valid reason to focus on time and dates on the web is Search Engine Optimization. SEO, once seen as some sort of mysterious voodoo only black hatted wizards understood, is now everyone's responsibility online. You spend time creating good code and expect a writer to create content worth reading. Now go one step further and ensure that your intended audience can actually find the content you have taken the time to create. And the new <time> element is just one of the ways search engines draw attention to the most recent content. See also The new HTML5 <time> element is a possible addition to the Microformats movement. Microformats promise to add additional semantic meaning to our markup. Though not officially a standard, Microformats are slowly gaining acceptance in the web development community. Learn more at Microformats.org.  
Read more
  • 0
  • 0
  • 3477
article-image-installing-data-protection-manager-2010
Packt
01 Jun 2011
6 min read
Save for later

Installing Data Protection Manager 2010

Packt
01 Jun 2011
6 min read
With the DPM upgrade you will face some of the same issues as with the installation such as what are the prerequisites? is your operating system patched? and is DPM 2007 fully patched and ready for the upgrade? This article will walk you through each step of the DPM installation process during the first half and the DPM 2007 to DPM 2010 upgrade in the second half. After reading this article you should know what to look for when working through the prerequisites and requirements. The goal is to ensure that your install or upgrade goes smoothly. Prerequisites In this section we will jump right into the prerequisites for DPM and how to install them as well as the two different ways to install DPM. We will also go through the DPM 2007 to DPM 2010 upgrade process. We will first visit the hardware and software requirements, and a pre-install that is needed before you are able to actually install DPM 2010. Hardware requirements DPM 2010 requires a processor of 1 GHz (dual-core or faster), 4 GB of RAM or higher, the page file should be set to 1.5 or 2 times the amount of RAM on the computer. The DPM disk space requirements are as follows: DPM installation location needs 3 GB free Database file drive needs 900 MB free System drive needs 1 GB free Disk space for protected data should be 2.5 to 3 times the size of the protected data DPM also needs to be on a dedicated, single purpose computer. Software requirements DPM has requirements of both the operating system as well as software that needs to be on the server before DPM can be installed. Let's take a look at what these requirements are. Operating system DPM 2007 can be installed on both a 32-bit and an x64-bit operating systems. However, DPM 2010 is only supported on an x64-bit operating systems. DPM can be installed on a Windows Server 2008 and Windows Server 2008 R2. It is recommended that you install DPM 2010 on Windows Server 2008 R2. DPM can be deployed in a Windows Server 2008, Windows Server 2008 R2, or Windows Server 2003 Active Directory domain. Be sure to launch the Windows update and completely patch the server before you start the DPM installation, no matter what operating system you decide to use. If you end up using Windows 2008 Server for your DPM deployment you will need to install some hotfixes before you start the DPM installation. The hotfixes are as follows: FIX: You are prompted to format the volume when a formatted volume is mounted on a NTFS folder that is located on a computer that is running Windows Server 2008 or Windows Vista (KB971254). Dynamic disks are marked as "Invalid" on a computer that is running Windows Server 2008 or Windows Vista. When you bring the disks online, take the disks offline, or restart the computer if Data Protection Manager is installed (KB962975). An application or service that uses a file system filter driver may experience function failure on a computer that is running Windows Vista, Windows Server 2003, or Windows Server 2008 (KB975759). Software By default, DPM will install any software prerequisites automatically if it is not enabled or installed. Sometimes these software prerequisites might fail during the DPM setup. If they do, you can install these manually. Visit the Microsoft TechNet site for detailed information on installing the software prerequisites. The following is a list of the software that DPM requires before it can be installed: Microsoft .NET Framework 3.5 with Service Pack 1 (SP1) Microsoft Visual C++ 2008 Redistributable Windows PowerShell 2.0 Windows Installer 4.5 or later versions Windows Single Instance Store (SIS) Microsoft Application Error Reporting NOTE: It is recommended that you manually install Single Instance Store on your server before you even begin the DPM 2010 installation. We shall see a step by step installation along with a detailed explanation of Single Instance Store. User privilege requirement The server that you plan to install DPM on must be joined to a domain before you install the DPM software. In order to join the server to the domain you need to have at least domain administrative privileges. You also need to have administrative privileges on the local server to install the DPM software. Restrictions DPM has to be installed on a dedicated server. It is best to make sure that DPM is the only server role running on the server you use for it. You will run into issues if you try to install DPM on a server with other roles on it. The following are the restrictions you need to pay attention to when installing DPM: DPM should not be installed on a domain controller (not recommended) DPM cannot be installed on an Exchange server DPM cannot be installed on a server with System Center Operations Manager installed on it The server you install on cannot be a node in a cluster There is one exception—you can install DPM on a domain controller and make it work but this is not supported by Microsoft. Single Instance Store Before you install DPM on your server, it is important to install a technology called Single Instance Store (SIS). SIS will ensure you get the maximum performance out of your disk space and reduce bandwidth needs on DPM. SIS is a technology that keeps the overhead of handling duplicate files low. This is often referred to as de-duplication. SIS is used to eliminate data duplication by storing only one copy of files on backup storage media. SIS is used in storage, mail, and backup solutions such as DPM. SIS helps to lower the costs of bandwidth when copying data across a network as well as needed storage space. Microsoft has used a single installation store in Exchange since version 4.0. SIS searches a hard disk and identifies duplicate files. SIS then saves only one copy of the files to a central location such as a DPM storage pool. SIS will then replace other copies of the files with pointers that direct you to the copy of the files the SIS repository already has stored. Installing Single Instance Store (SIS) The following procedure walks you through the steps required to install SIS: Click on Start and then click on Run. In the Run dialog box, type CMD.exe and press OK: At the command prompt type the following: start /wait ocsetup.exe SIS-Limited /quiet /norestart And then press Enter. (Move the mouse over the image to enlarge it.) Restart the server. To ensure the installation of SIS went okay, check for the existence of the SIS registry key. Click on Start, then click Run. In the Run dialog box, type regedit and press OK. Navigate to HKEY_LOCAL_MACHINESYSTEMCurrentControlSetServices SIS: If the SIS key is shown (as in the screenshot) in the registry it would mean that Single Instance Store (SIS) is installed properly and you can be sure to get the maximum performance out of your disk space on the DPM server.
Read more
  • 0
  • 0
  • 10231

article-image-importing-3d-formats-away3d
Packt
31 May 2011
5 min read
Save for later

Importing 3D Formats into Away3D

Packt
31 May 2011
5 min read
Away3D 3.6 Cookbook Over 80 practical recipes for creating stunning graphics and effects with the fascinating Away3D engine Introduction The Away3D library contains a large set of 3D geometric primitives such as Cube, Sphere, Plane, and many more. Nevertheless, when we think of developing breathtaking and cutting edge 3D applications, there is really no way to get it done without using more sophisticated models than just basic primitives. Therefore, we need to use external 3D modeling programs such as Autodesk 3DsMax and Maya, or Blender to create complex models. The Power of Away3D is that it allows us to import a wide range of 3D formats for static meshes as well as for animations. Besides the models, the not less important part of the 3D world is textures. They are critical in making the model look cool and influencing the ultimate user experience. In this article, you will learn essential techniques to import different 3D formats into Away3D. Exporting models from 3DsMax/Maya/Blender You can export the following modeling formats from 3D programs: (Wavefront), Obj, DAE (Collada), 3ds, Ase (ASCII), MD2, Kmz, 3DsMax, and Maya can export natively Obj, DAE, 3ds, and ASCII. One of the favorite 3D formats of Away3D developers is DAE (Collada), although it is not the best in terms of performance because the file is basically an XML which becomes slow to parse when containing a lot of data. The problem is that although 3DsMax and Maya have got a built-in Collada exporter, the models from the output do not work in Away3D. The work around is to use open source Collada exporters such as ColladaMax/ColladaMaya, OpenCollada. The only difference between these two is the software versions support. Getting ready Go to http://opencollada.org/download.html and download the OpenCollada plugin for the appropriate software (3DsMax or Maya). Go to http://sourceforge.net/projects/colladamaya/files/ and download the ColladaMax or colladamaya plugin. Follow the instructions of the installation dialog of the plugin. The plugin will get installed automatically in the 3dsMax/Maya plugins directory (taking into account that the software was installed into the default path). How to do it... 3DsMax: Here is how to export Collada using OpenCollada plugin in 3DsMax2011. In order to export Collada (DAE) from 3DsMax, you should do the following: In 3DsMax, go to File and click on Export or Export Selected (target model selected). Select the OpenCOLLADA(*.DAE) format from the formats drop-down list. ColladaMax export settings: (Currently 3DsMax 2009 and lower) ColladaMax export settings are almost the same as those of OpenCollada. The only difference you can see in the exporting interface is the lack of Copy Images and Export user defined properties checkboxes. Select the checkboxes as is shown in the previous screenshot. Relative paths: Makes sure the texture paths are relative. Normals: Exporting object's normals. Copy Images: Is optional. If we select this option, the exporter outputs a folder with related textures into the same directory as the exported object. Triangulate: In case some parts of the mesh consist of more than three angled polygons, they get triangulated. Animation settings: Away3D supports bones animations from external assets. If you set bones animation and wish to export it, then check the Sample animation and set the begin and end frame for animation span that you want to export from the 3DsMax animation timeline. Maya: For showcase purposes, you can download a 30-day trial version of Autodesk Maya 2011. The installation process in Maya is slightly different: Open Maya. Go to top menu bar and select Window. In the drop-down list, select Settings/Preferences, in the new drop-down list, select Plug-in manager. Now you should see the Plug-in Manager interface: Now click on the Browse button and navigate to the directory where you extracted the OpenCollada ZIP archive. Select the COLLADAMaya.mll file and open it. Now you should see the OpenCollada plugin under the Other Registered Plugins category. Check the AutoLoad checkbox if you wish for the plugin to be loaded automatically the next time you start the program. After your model is ready for export, click on File | Export All or Export selected. The export settings for ColladaMaya are the same as for 3DsMax. How it works... The Collada file is just another XML but with a different format name (.dae). When exporting a model in a Collada format, the exporter writes into the XML nodes tree all essential data describing the model structure as well as animation data when one exports bone-based animated models. When deploying your DAE models to the web hosting directory, don't forget to change the .DAE extension to .XML. Forgetting will result in the file not being able to load because .DAE extension is ignored by most servers by default. There's more... Besides the Collada, you can also export OBJ, 3Ds, and ASE. Fortunately, for exporting these formats, you don't need any third party plugins but only those already located in the software. Free programs such as Blender also serve as an alternative to expansive commercial software such as Maya, or 3DsMax Blender comes with already built-in Collada exporter. Actually, it has two such exporters. At the time of this writing, these are 1.3 and 1.4. You should use 1.4 as 1.3 seems to output corrupted files that are not parsed in Away3D. The export process looks exactly like the one for 3dsMax. Select your model. Go to File, then Export. In the drop-down list of different formats, select Collada 1.4. The following interface opens: Select Triangles, Only Export Selection (if you wish to export only selected object), and Sample Animation. Set exporting destination path and click on Export and close. You are done.
Read more
  • 0
  • 0
  • 10361

article-image-packt-podcasts-enterprise
Packt
31 May 2011
3 min read
Save for later

Packt Podcasts: Enterprise

Packt
31 May 2011
3 min read
The latest OTN ArchBeat Podcast features a conversation with those five Fusion Middleware experts (three of them members of the Oracle ACE program), in which they talk about why they wrote the book, what they learned in researching and writing the book, about how they divide their time between development and architecture, and a lot more.  For further info on Oracle Service Bus 11g Development Cookbook click here In this second ‘teaser’ show leading up to the Share Conference in Johannesburg, Ruven Gotz discusses the topics he will be presenting on, including his keynote on better understanding metadata – what it is, why it’s important and how to get more of it! We also discuss the Search enhancements in SharePoint 2010, working disconnected and a few other things. For further info on Microsoft SharePoint 2010 and Windows PowerShell 2.0: Expert Cookbook click here   Christian Screen, Solutions Engineer and Consultant for the BI Consulting Group chats with John P. Jeffries about GoldenGate, his experiences and his new book content courtesy of artofbi.com For further info on the Oracle GoldenGate 11g Implementer's Guide click here     Duncan Mills, Senior Director of Product Management for Oracle's Development tools and Sten Vesterli Oracle ACE and author discuss Sten's new book Oracle ADF Enterprise Application Development-Made Simple, the growth of ADF's popularity and hints and tips for the aspiring ADF developer content courtesy of Oracle For further info on Oracle ADF Enterprise Application Development - Made Simple click here Joyce Davis, Susan Bulloch and Barry Rosen join Darren and Stuart McIntyre to discuss Lotusphere 2012 sessions, tracks and social events, Barry tells us about his upcoming Notes&Domino 8.5.3 book and Darren goes awfully quiet! For further info on IBM Lotus Notes and Domino 8.5.3: Upgrader's Guide   Jeff Laskowski is a Certified Senior Solutions Architect with IBM, who is dedicated to securing IT networks, endpoints, and data. Jeff is also a certified ethical hacker with EC-Council as well as Master IT Specials certified with the Open Group. Given his remarkable accomplishments to the field of computing, he has written the book "Agile IT Security Implementation Methodology", has published numerous technical articles, and has lectured extensively around the world to many audiences, both technical as well as non-technical. For further info on Agile IT Security Implementation Methodology click here     Join an interview with Bob Griesemer, author of Oracle Warehouse Builder 11gR2: Getting Started, and Dain Hansen, Director of Product Marketing for Oracle Fusion Middleware, to hear about new trends in data integration and how Oracle Warehouse Builder 11g in particular can help customers improve efficiencies for building and loading their data warehouses content courtesy of Oracle For further info on Oracle Warehouse Builder 11gR2: Getting Started 2011 click here     In a two-part podcast Oracle SOA Suite 11gR1 Developer's Guide authors Matt Wright and Anthony Reynolds talk about their latest book and about SOA's evolution  content courtesy of Oracle For further info on Oracle SOA Suite 11g R1 Developer's Guide click here     Service-Oriented Architecture: An Integration Blueprint co-author Guido Schmutz talks about his book and about the ongoing challenges of implementing SOA content courtesy of Oracle For further info on Service Orientated Architecture: An Integrated Blueprint click here     The latest ArchBeat Podcast features a conversation with three people behind the recently published book Oracle Information Integration, Migration, and Consolidation: author Jason Williamson, co-author Tom Laszewksi, and book contributor Marc Herbert. content courtesy of Oracle For further info on Oracle Information Integration, Migration, and Consolidation click here  
Read more
  • 0
  • 0
  • 4954
article-image-overview-data-protection-manager-2010
Packt
30 May 2011
9 min read
Save for later

Overview of Data Protection Manager 2010

Packt
30 May 2011
9 min read
  Microsoft Data Protection Manager 2010 A practical step-by-step guide to planning deployment, installation, configuration, and troubleshooting of Data Protection Manager 2010         Read more about this book       (For more resources on Microsoft, see here.) DPM structure In this section we will look at the DPM file structure in order to have a better understanding of where DPM stores its components. We will also look at important processes that DPM runs and what they are used for. There will be some hints and tips that you should know about that will be useful when administering DPM. DPM file locations It is important to know not only how DPM operates, but also to know the structure that is underneath the application. Understanding the structure of where the DPM components are will help you with administering and troubleshooting DPM if the need arises. The following are some important locations: The DPM database backups are stored in the following location. Also when you make backup shadow copies for the replicas these will be stored in this directory. You would make backup show copies of your replicas if you were archiving them using a third-party backup solution: C:Program FilesMicrosoft DPMDPMVolumesShadowCopyDatabase Backups The following directory is where DPM is installed: C:Program FilesMicrosoft DPM The following directory contains PowerShell scripts that come with DPM. There are many scripts that can be used for performing common DPM tasks. C:Program FilesMicrosoft DPMDPMbin The following folder contains the database and files for SQL reporting services: C:Program FilesMicrosoft DPMSQL The following directory contains the SQL DPM database. MDF and LDF files: C:Program FilesMicrosoft DPMDPMDPMDB The following directory stores shadow copy volumes that are recovery points for a data source. These essentially are the changed blocks of VSS (Volume Shadow Copy Service) (Shadow Copy). C:Program FilesMicrosoft DPMDPMVolumesDiffArea The following folder contains mounted replica volumes. Mounted replica volumes are essentially pointers for every protected data object that points to the partition in a DPM storage pool. Think of these mounted replica points as a map from DPM to the protected data on the hard drives where the actual protected data lives. C:Program FilesMicrosoft DPMDPMVolumesReplica DPM processes We are now going to explore DPM processes. The executable files for these are all located in C:Program FilesMicrosoft DPMDPMbin. You can view these processes in Windows Task Manager and they show up in Windows Services as well: The following screenshot shows the DPM services as they appear in Windows Services: We will look at what each of these processes are and what they do. We will also look at the processes that have an impact on the performance of your DPM server. The processes are as follows: DPMAMService.exe: In Windows Services this is listed as the DPM AccessManager Service. This manages access to DPM. DpmWriter.exe: This is a service as well, so you will see it on the services list. This service is used for archiving. It manages the backup shadow copies or replicas, backups of report databases, as well as DPM backups. Msdpm.exe: The DPM service is the core component of DPM. The DPM service manages all core DPM operations, including replica creation, synchronization, and recovery point creation. This service implements and manages synchronization and shadow copy creation for protected file servers. DPMLA.exe: This is the DPM Library Agent Service. DPMRA.exe: This is the DPM Replication Agent. It helps to back up and recover file and application data to DPM. Dpmac.exe: This is known as the DPM Agent Coordinator Service. This manages the installations, uninstallations, and upgrades of DPM protection agents on remote computers that you need to protect. DPM processes that impact DPM performance The Msdpm.exe, MsDpmProtectionAgent.exe, Microsoft$DPM$Acct.exe, and mmc.exe processes take a toll on DPM performance. mmc.exe is a standard Windows service. "MMC" stands for Microsoft Management Console application and is used to display various management plug-ins. Not all but a good amount of Microsoft server applications run in the MMC such as Exchange, ISA, IIS, System Center, and the Microsoft Server Manager. The DPM Administrator Console runs in an MMC as well. mmc.exe can cause high memory usage. The best way to ensure that this process does not overload your memory is to close the DPM Administrator Console when not using it. MsDpmProtectionAgent.exe is the DPM Protection Agent service and affects both CPU and memory usage when DPM jobs and consistency checks are run. There is nothing you can do to get the usage down for this service. You just need to be aware of this and try not to schedule any other resource intensive applications such as antivirus scans at the same time as DPM jobs or consistency checks. Mspdpm.exe is a service that runs synchronization and shadow copy creations as stated previously. Like MsDpmProtectionAgent.exe, Mspdpm.exe also affects CPU and memory usage when running synchronizations and shadow copies. Like MsDpmProtectionAgent.exe there is nothing you can do to the Mspdpm. exe service to reduce memory and CPU usage. Just make sure to keep the system clear of resource intensive applications when the Mspdpm.exe is running jobs. If you are running a local SQL instance for your DPM deployment you will notice a Microsoft$DPM$Acct.exe process. The SQL Server and SQL Agent services use a Microsoft$DPM$Acct account. This normally runs on a high level. This service reserves part of your system's memory for cache. If the system memory goes low, the Microsoft$DPM$Acct.exe process will let go of the memory cache it has reserved. Important DPM terms In this section you will learn some important terms used commonly in DPM. You will need to understand these terms as you begin to administer DPM on a regular basis. You can read the full list of terms at this site: http://technet.microsoft.com/en-us/library/bb795543.aspx We group the terms in a way that each group relates to an area of DPM. The following are some important terms: Bare metal recovery: This is a restore technique that allows one to restore a complete system onto bare metal, without any requirements, to the previous hardware. This allows restoring to dissimilar hardware. Change journal: A feature that tracks changes to NTFS (New Technology File System) volumes, including additions, deletions, and modifications. The change journal exists on the volume as a sparse file. Sparse files are used to make disk space usage more efficient in NTFS. A sparse file allocates disk space only when it is needed. This allows files to be created even when there is insufficient space on a hard drive. These files contain zeroes instead of disk blocks. Consistency check: The process by which DPM checks for and corrects inconsistencies between a protected data source and its replica. A consistency check is only performed when normal mechanisms for recording changes to protected data, and for applying those changes to replicas, have been interrupted. Express full backup: A synchronization operation in which the protection agent transfers a snapshot of all the blocks that have changed since the previous express full backup (or initial replica creation, for the first express full backup). Shadow copy: A point-in-time copy of files and folders that is stored on the DPM server. Shadow copies are sometimes referred to as snapshots. Shadow copy client software: Client software that enables an end-user to independently recover data by retrieving a shadow copy. Replica: A complete copy of the protected data on a single volume, database, or storage group. Each member of a protection group is associated with a replica on the DPM server. Replica creation: The process by which a full copy of data sources, selected for inclusion in a protection group, is transferred to the DPM storage pool. The replica can be created over the network from data on the protected computer or from a tape backup system. Replica creation is an initialization process that is performed for each data source when the data source is added to a protection group. Replica volume: A volume on the DPM server that contains the replica for a protected data source. Custom volume: A volume that is not in the DPM storage pool and is specified to store the replica and recovery points for a protection group member. Dismount: To remove a removable tape or disc from a drive. DPM Alerts log: A log that stores DPM alerts as Windows events so that the alerts can be displayed in Microsoft System Center Operations Manager (SCOM). DPMDB.mdf: The filename of the DPM database, the SQL Server database that stores DPM settings and configuration information. DPMDBReaders group: A group, created during DPM installation, that contains all accounts that have read-only access to the DPM database. The DPMReport account is a member of this group. DPMReport account: The account that the Web and NT services of SQL Server Reporting Services use to access the DPM database. This account is created when an administrator configures DPM reporting. MICROSOFT$DPM$: The name that the DPM setup assigns to the SQL Server instance used by DPM. Microsoft$DPMWriter$ account: The low-privilege account under which DPM runs the DPM Writer service. This account is created during the DPM installation. MSDPMTrustedMachines group: A group that contains the domain accounts for computers that are authorized to communicate with the DPM server. DPM uses this group to ensure that only computers that have the DPM protection agent installed from a specific DPM server can respond to calls from that server. Protection configuration: The collection of settings that is common to a protection group; specifically, the protection group name, disk allocations, replica creation method, and on-the-wire compression. Protection group: A collection of data sources that share the same protection configuration. Protection group member: A data source within a protection group. Protected computer: A computer that contains data sources that are protection group members. Synchronization: The process by which DPM transfers changes from the protected computer to the DPM server, and applies the changes to the replica of the protected volume. Recovery goals: The retention range, data loss tolerance, and frequency of recovery points for protected data. Recovery collection: The aggregate of all recovery jobs associated with a single recovery operation. Recovery point: The date and time of a previous version of a data source that is available for recovery from media that is managed by DPM. Report database: The SQL Server database that stores DPM reporting information (ReportServer.mdf). ReportServer.mdf: In DPM, the filename for the report database—a SQL Server database that stores reporting information. Retention range: Duration of time for which the data should be available for recovery.
Read more
  • 0
  • 0
  • 13140

article-image-getting-started-gnucash
Packt
30 May 2011
8 min read
Save for later

Getting Started with GnuCash

Packt
30 May 2011
8 min read
  Gnucash 2.4 Small Business Accounting: Beginner's Guide Manage your accounts with this desktop financial manager application How do I pronounce GnuCash? Some people use the proper "Guh-noo-cash" and others prefer the easier "NewCash". Go by whatever works for you. Installing GnuCash on Windows Before you can use GnuCash, you have to install it. We will walk you through the steps needed to get it installed successfully on your Windows PC, whether you have Windows 7, Vista, or XP. Time for action – installing GnuCash on Windows Let us go through the steps for downloading and installing GnuCash: GnuCash is an open source software developed by volunteers, often for their own use, and shared with the community. It can be downloaded for free. Download the latest stable release of the installer for Microsoft Windows XP/Vista/7 from the www.gnucash.org website. The file should have a name like gnucash-2.4.1- setup.exe. The size of the file should be about 90MB. Save the file to a convenient location on your PC, such as the Temp folder in your C drive. The GnuCash website will also have other development versions of the software. These are unstable and are for testing purposes only. These are not suitable for business use. Make sure you download the stable release. Launch the GnuCash setup program by double-clicking this file in Windows Explorer. Windows security might pop a message like The publisher could not be verified. Are you sure you want to run this software? or Do you want to allow the following program from an unknown publisher to make changes to this computer?. Click on Run or Yes to continue. The language selection dialog will appear with English already selected. Click on OK to continue. The Welcome screen of the GnuCash setup wizard will appear. Close any other application that may be running and click on Next. The License Agreement will appear. Select I accept the agreement and click on Next. The location dialog will show that GnuCash will be installed in C:Program Files gnucash. It will also tell you how much free space is required on your hard disk for installing the program (about 350 MB). Make sure you have the required free space and click on Next. On Windows 7, the default location will be C:Program Files (x86)gnucash. The next screen will show that a Full Installation will be done. Click on Next to continue. The next screen will show that a GnuCash folder will be created for the menu items. Click on Next to continue. The next screen will show that a desktop icon and a start menu link will be created. Click on Next to continue. The next screen is simply a recap of all the selections made by you so far. Click on Install to start the installation. This may take several minutes, giving you time for a coffee break. When the installation is completed successfully, you should see a window with the title Information. Click on Next to continue. Next, the Completing the GnuCash Setup Wizard window will appear. The Run GnuCash now box will be checked. Click on Finish to complete the installation. The GnuCash Tip of the Day will pop up. You can close this. You should see the Welcome to GnuCash window with Create a new set of accounts checked. We are going to do that soon. But for now, click on Cancel. Say No to the Display Welcome Dialog Again? question. You should see the Unsaved book – GnuCash window: What just happened? Congratulations! You have just installed GnuCash successfully and you are ready to start learning, hands-on, how to use it. Other operating systems In addition to Windows, GnuCash runs on Mac OS X (on the newer Intel as well as the older Power PC) and several flavors of Linux. If you have one of those operating systems, you can download the install package and get installation instructions for those operating systems from the GnuCash.org website. Other download locations In addition to the GnuCash.org website, you can also download GnuCash from popular open source repositories such as SourceForge. Wherever you download from, be careful that you are downloading from a genuine site and that the download is free of viruses and malware. But first, a tip to make your life easier with auto-save Before we start the main show, here is a quick tip to make your life easier. GnuCash has a friendly feature to auto-save changes every few minutes. Some people find this very useful while entering transactions. However, at the time of going through the tutorial, you don't want this auto-save to kick in. Why? You want to have some breathing time to recover from any errors and correct any mistakes and then save it at your convenience. It is even possible, heaven forbid, that you might want to abandon the changes instead of trying to rectify them. To do this, you might want to exit GnuCash without saving the changes. So, let us politely tell GnuCash, "STOP HELPING ME"! Launch the GnuCash Preferences dialog from Edit | Preferences. Select the General tab. As shown in the following image, set the Auto-save time interval to 0 minutes. By setting this to 0, the auto-save feature is turned off. Also, uncheck the Show auto-save confirmation question, if it is checked. As we said, users have found that this ability to auto-save is a big life saver. So, don't forget to turn this back on when you are done with the tutorials and start keeping your business books. Taking the drudgery out of setting up accounts Even the smallest of businesses may need as many as a hundred accounts. If your business is somewhat larger, you may need to create a lot more than a hundred accounts. Am I going to make you create that many accounts one by one? No, I am going to show you how you can create the entire set of accounts needed for a typical small business in under a dozen clicks. Time for action – creating the default business accounts We are going to create the account hierarchy for our sample business, Mid Atlantic Computer Services (MACS). This will give you the hands-on feel to create accounts for your business, when you are ready to do that. Select from the menu File | New | New File. This will launch the New Account Hierarchy Setup assistant. GnuCash uses the term assistant to describe what you may have seen in other Windows applications called a wizard. Assistants help you perform tasks that are complex or not frequently performed. Assistants present you with a sequence of dialog boxes that lead you through a series of well-defined steps. Click on Forward to go to the Choose Currency screen. You will find that US Dollar is selected by default. You can leave it as it is and click Forward to go to the Choose accounts to create screen. You will find that Common Accounts is checked by default. This option is for users who want to set up personal accounts. We want to set up a business account. So, uncheck this and check Business Accounts, as shown in the next screenshot and then click on Forward: In the Setup selected accounts screen, click on the Checking Account line and it will become highlighted. Click under the Opening Balance column in this line, a text box will appear allowing you to enter data. Enter an opening balance of 2000, as shown in the next screenshot, tab out, and click on Forward. In the Finish Account Setup screen, click on Apply. With the previous step, the New Account Hierarchy Setup assistant has completed its job. You should now be back in the GnuCash main window showing the freshly minted set of accounts with the title Unsaved Book - Accounts. The Save As dialog should open. If it doesn't, select File | Save As… change the Save in folder to your desired folder, put in the filename MACS without any extension, and click on Save As. If your screen looks like the following screenshot, you have now successfully created the default business account hierarchy for MACS: Most Windows applications require you to save files with a 3 or 4 letter extension. Microsoft Word, for example, requires a .docx or .doc file extension. However, GnuCash uses the longer .gnucash extension. If you fill in the file name, GnuCash will automatically add the .gnucash extension. What just happened? There you are. With a small amount of effort, you have not only created a complete set of accounts that would be needed for a typical small business, but you have also learned how to enter opening balances as well. Now that we have that under our belt, let us discuss the key aspects of setting up accounts.
Read more
  • 0
  • 0
  • 5245
Modal Close icon
Modal Close icon