[ Pobierz całość w formacie PDF ]
.The rotating blue directional light from Hour 14 was replaced with a stationary whitedirectional light to allow you to see the models better.Reading the ModelAs mentioned before, we let the CD3DFile object do the work and load the X files intothe application for us.The application has a new object for the helicopter.This objectholds a pointer to a CD3DFile object, and it contains information about the helicopter,such as position, angle, and velocity.Because the car is stationary, the file is simplyloaded and rendered during the render loop.Listing 15.16 shows the code used in thesample application to read in the files.22 1634xCH15 11/13/99 11:10 AM Page 302302 Hour 15LISTING 15.16 Reading a Direct3D X File1: // load the car model2:3: lpXFileCar=new CD3DFile();4: if( FAILED( lpXFileCar->Load( car.x ))){5:6: // Set error string.7: ErrStr=Err_LoadingXFile;8:9: return FALSE;10:11: } else {12: lpXFileCar->Scale(5.0f);13: };14:15: // load the helicopter model16:17: lpXFileHelo=new CD3DFile();18: if( FAILED( lpXFileHelo->Load( heli.x ))){19:20: // Set error string.21: ErrStr=Err_LoadingXFile;22:23: return FALSE;24:25: } else {26: lpXFileHelo->Scale(5.0f);27: };28:29: // create helicopter object30: chopper=new CHelicopter(D3DVECTOR(0,250,0),31: D3DVECTOR(0.0f,0.0f,0.0f),32: lpXFileHelo);33:34: //.Setting Up the HierarchyBecause two new objects are in the application, you must be careful where you placethem or else they will intersect with other objects in the world.You want to render eachobject with respect to the rest of the scene.To render the car with respect to the rest ofthe scene, you will perform an additional transformation on the car.The same principleapplies to the helicopter.In the case of the sample application, things have been keptsimple.Because the car is stationary, there is simply a translation to place it in the appro-priate position.The helicopter, on the other hand, is slightly more complex.The heli-copter is flying around the rooftops of the buildings.Instead of a simple translation, the22 1634xCH15 11/13/99 11:10 AM Page 303Importing 3D Objects and Animations Into the Scene 303helicopter body also needs to be rotated on its central axis.Otherwise, it would appearthat the helicopter wasn t really flying at all.Because the car and helicopter modify the15world transformation matrix before they are rendered, they must restore the originalmatrix after they are rendered.This hierarchical model is working on many other levels in the application.If you haveexamined the car and helicopter X files, you will notice that each object is split into itscomponent pieces.For example, the car separates the body from the lights and thewheels.Each of these component pieces of the car and helicopter might also performsome additional transformation so that they are rendered in the appropriate place.It allgoes back to the use of Frame templates.Each frame can provide a transformation matrixthat is applied to the current transformation matrix.In this way, each object is renderedwith respect to all the matrix transformations applied before it.This is an important con-cept to understand.Listing 15.17 shows the code used in the sample application that isused to set up the world transformation matrix for the helicopter.LISTING 15.17 Placing the Helicopter in the Scene: TheCHelicopter::calc_move() Function1: D3DMATRIX CHelicopter::calc_move(float delt)2: {3: cur_ang.x=-pitch*4.5f;4: cur_ang.y+=steer*delt*0.05f;5: cur_ang.z=-steer*0.01f;6:7: cur_pos.y+=lift*delt*12.0f;8: cur_pos.x+=sin(cur_ang.y)*-cur_ang.x*75.0f*delt;9: cur_pos.z+=cos(cur_ang.y)*-cur_ang.x*75.0f*delt;10:11: // calculate a decay factor based on time12: float decay=1.0f-delt*0.2f;13:14: // decay the speed and control positions gradually back towards zero15: lift*=decay;16: pitch*=decay;17: steer*=decay;18:19: // settle towards clear and level flight20: cur_ang.x*=decay;21: cur_ang.z*=decay;22:23: // set up rotations and combine into view transform matrix24: D3DMATRIX matTrans,matRotateY,matRotateZ,matRotateX,view;25:26: D3DUtil_SetTranslateMatrix(matTrans,cur_pos.x,cur_pos.y,cur_pos.z);27:continues22 1634xCH15 11/13/99 11:10 AM Page 304304 Hour 15LISTING 15.17 continued28: D3DUtil_SetRotateXMatrix( matRotateX,cur_ang.x);29: D3DUtil_SetRotateYMatrix( matRotateY,cur_ang.y);30: D3DUtil_SetRotateZMatrix( matRotateZ,cur_ang.z);31:32: D3DMath_MatrixMultiply(view,matRotateY,matTrans);33: D3DMath_MatrixMultiply(view,matRotateZ,view);34: D3DMath_MatrixMultiply(view,matRotateX,view);35:36: // return view matrix37: return view;38: }Adding the Object to the SceneAfter the world matrix has been changed to take into account the position of the object,the object needs to be rendered.After an object is rendered, the proper world transforma-tion matrix needs to be restored.All this takes place in the render_frame() function andthe CHelicopter::draw() function.Listing 15.18 shows the code snippets from the sam-ple application.LISTING 15.18 Rendering the Car and Helicopter1: void render_frame(float elapsed)2: {3: //.4:5: if (chopper)6: chopper->draw(lpDevice,elapsed);7:8: D3DMATRIX world;9: if (lpXFileCar) {10: // just translate the car to the appropriate position in the world.11: D3DUtil_SetTranslateMatrix(world,0,10,-120);12: lpDevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&world);13: lpXFileCar->Render(lpDevice);14: D3DUtil_SetIdentityMatrix(world);15: lpDevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&world);16:17: //.18: }19:20: void CHelicopter::draw(LPDIRECT3DDEVICE7 dev,float delt)21: {22:23: //.24:25: if (meshPtr) {22 1634xCH15 11/13/99 11:10 AM Page 305Importing 3D Objects and Animations Into the Scene 30526: world=calc_move(delt);27: lpDevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&world);1528: meshPtr->Render(lpDevice);29: D3DUtil_SetIdentityMatrix(world);30: lpDevice->SetTransform(D3DTRANSFORMSTATE_WORLD,&world);31: }32:33: //.34: }Cleaning UpCleanup is a breeze.You simply need to delete the CHelicopter object and the twoCD3DFile objects.Listing 15.19 shows the Cleanup() function used by the sample appli-cation.LISTING 15.19 The New Cleanup() Function1: void Cleanup()2: {3: // unload animated object classes4: SafeDelete(chopper);5:6: // unload 3D models7: SafeDelete(lpXFileCar);8: SafeDelete(lpXFileHelo);9:10: // de-allocate block objects11:12: for (int i=0;ix) + (u->y * v->y) + (u->z * v->z));}void CrossProduct(D3DVECTOR *v, D3DVECTOR *v, D3DVECTOR *result){result->x = (u->y * v->z) - (u->z * v->y);result->y = (u->z * v->x) - (u->x * v->z);result->z = (u->x * v->y) - (u->y * v->x);}For now, just get a good grip on how to calculate these two functions [ Pobierz całość w formacie PDF ]