Character Animation with Direct3D- P5 potx

20 317 0
Character Animation with Direct3D- P5 potx

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

Thông tin tài liệu

// set up bone transforms int numBones = boneMesh->pSkinInfo->GetNumBones(); for(int i=0;i < numBones;i++) { D3DXMatrixMultiply(&boneMesh->currentBoneMatrices[i], &boneMesh->boneOffsetMatrices[i], boneMesh->boneMatrixPtrs[i]); } //Set HW Matrix Palette D3DXMATRIX view, proj; pEffect->SetMatrixArray( "MatrixPalette", boneMesh->currentBoneMatrices, boneMesh->pSkinInfo->GetNumBones()); //Render the mesh for(int i=0;i < boneMesh->NumAttributeGroups;i++) { int mtrl = boneMesh->attributeTable[i].AttribId; pEffect->SetTexture("texDiffuse", boneMesh->textures[mtrl]); D3DXHANDLE hTech = pEffect->GetTechniqueByName("Skinning"); pEffect->SetTechnique(hTech); pEffect->Begin(NULL, NULL); pEffect->BeginPass(0); boneMesh->MeshData.pMesh->DrawSubset(mtrl); pEffect->EndPass(); pEffect->End(); } } } if(bone->pFrameSibling != NULL) Render((Bone*)bone->pFrameSibling); if(bone->pFrameFirstChild != NULL) Render((Bone*)bone->pFrameFirstChild); } 66 Character Animation with Direct3D Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Not much has changed in this function compared to the software skinning example. Most notable, of course, is the use of the shader and uploading the Matrix Palette to it. Otherwise, you loop through the different attribute groups of the mesh and render it using the shader. RENDERING STATIC MESHES IN BONE HIERARCHIES Sometimes you might not want the character skinned. Making animated machinery is a prime example. Machinery rarely has “soft” parts; thus you don’t really need to skin a mesh to make mechanical creations in your games. Nonetheless, you might want to have a bone hierarchy controlling the different parts of the “machine.” Take the example of a robot arm, as shown in Figure 3.7. Chapter 3 Skinned Meshes 67 EXAMPLE 3.3 Check out Example 3.3 on the accompanying CD-ROM. Onscreen, you won’t see much difference compared to the previous example, but behind the scenes many things are indeed completely different. As always, study the code and don’t move forward until you understand it completely. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. Another case where you need rigid/solid objects is when they are combined with skinned meshes. In the previous examples of the skinned soldier, you may have noticed that he was missing both helmet and rifle. That’s because these two objects have been rigid objects containing no skinning information. One way to include these objects would be to assign all vertices in them to one bone (the head bone, for example, in the case of the helmet). However, that would be a serious waste of CPU/GPU power. In this section, you’ll learn how to load and render both skinned meshes and static meshes from the same .x. file—although, to be frank, you have already covered the loading. Loading the meshes in the CreateMeshContainer() function is actually already done. So here’s another high-level look at this function: HRESULT BoneHierarchyLoader::CreateMeshContainer( ) { //Create new Bone Mesh //Get mesh data here //Copy materials and load textures (like with a static mesh) 68 Character Animation with Direct3D FIGURE 3.7 As you can see, each part of the robot arm is rigid and therefore does not require skinning. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. if(pSkinInfo != NULL) { //Store Skin Info and convert mesh to Index Blended Mesh } //Set ppNewMeshContainer to newly created boneMesh container } As you can see, you only convert the mesh to an Index Blended Mesh if the pSkinInfo parameter to this function is not NULL. But in the case of the helmet and the rifle for the soldier, the pSkinInfo parameter will of course be NULL, and as a result the mesh doesn’t get converted. However, mesh data and the belonging materials and textures have still been copied. So all you really need to do is render them! And to do that you need only to add the case of rendering static meshes to the SkinnedMesh::Render() function. void SkinnedMesh::Render(Bone *bone) { if(bone == NULL)bone = (Bone*)m_pRootBone; //If there is a mesh to render if(bone->pMeshContainer != NULL) { BoneMesh *boneMesh = (BoneMesh*)bone->pMeshContainer; if(boneMesh->pSkinInfo != NULL) { //Here’s where the skinned mesh is rendered //only if the pSkinInfo variable isn’t NULL } else { //Normal Static Mesh pEffect->SetMatrix("matW", &bone->CombinedTransformationMatrix); D3DXHANDLE hTech; hTech = pEffect->GetTechniqueByName("Lighting"); pEffect->SetTechnique(hTech); Chapter 3 Skinned Meshes 69 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. //Render the static mesh for(int i=0;i < boneMesh->materials.size();i++) { pEffect->SetTexture("texDiffuse", boneMesh->textures[i]); pEffect->Begin(NULL, NULL); pEffect->BeginPass(0); boneMesh->OriginalMesh->DrawSubset(i); pEffect->EndPass(); pEffect->End(); } } } if(bone->pFrameSibling != NULL) Render((Bone*)bone->pFrameSibling); if(bone->pFrameFirstChild != NULL) Render((Bone*)bone->pFrameFirstChild); } The static mesh is still locked to the bone hierarchy. As you can see, you use the combined transformation matrix of the bone to which the mesh is linked when you set the world matrix of the static mesh. So when you animate the neck bone of the character, the helmet will follow automatically. You can now use this code to render a robot character that has no skinned parts at all or a hybrid character like the soldier that has both skinned and static meshes. 70 Character Animation with Direct3D Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CONCLUSIONS Congratulations! If you’re still reading, you’ve covered the meatiest chapter of the entire book. Hopefully you’ve managed to learn something along the way. It is a long process to attach a few vertices to a skeleton, isn’t it? At the end of this chapter you don’t have much more to show for your work than you had in Chapter 2. Well, to be honest, it is in the next chapter that you will really experience the payoff—when you animate the skeleton (and with it the character). Take time to look at each of the examples again; most likely, you’ll learn a lot from playing with the code. Chapter 3 Skinned Meshes 71 EXAMPLE 3.4 Example 3.4 contains the code just covered. The soldier finally looks like he did when the soldier.x file was rendered as a static mesh in Chapter 2. However, the major difference now is that the character has the underlying bone hierarchy and the mesh is connected to it. In this example, pay extra attention to the SkinnedMesh class and especially its rendering function. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. CHAPTER 3 EXERCISES Implement your own Skinned Mesh class, and support both hardware and software skinning with it. Check out the implementation of the character shadow in the software skinning examples. Implement it also for the hardware-skinned character. If you have access to 3D modeling software, create a skinned character, export it to the .x file format, and read it into your application. Access the Matrix Palette and multiply a small transformation (rotation/scale) to the neck bone’s transformation matrix. Try to make the character turn his head. Study the RenderSkeleton() function in the SkinnedMesh class. Try also to visu- alize which bone has a BoneMesh attached to it. Implement your own version of the Bone, BoneMesh, and BoneHierarchyLoader classes. Add new members to these classes that you initialize in your own CreateMeshContainer() function. FURTHER READING [Ditchburn06] Ditchburn, Keith, “X File Hierarchy Loading.” Available online at http://www.toymaker.info/Games/html/load_x_hierarchy.html, 2006. [Germishuys] Germishuys, Pieter, “HLSL Tutorials.” Available online at http://www.pieterg.com/Tutorials.php. [Jurecka04] Jurecka, Jason, “Working with the DirectX .X File Format and Animation in DirectX 9.0.” Available online at http://www.gamedev.net/reference/articles/ article2079.asp, 2004. [Luna04] Luna, Frank, “Skinned Mesh Character Animation with Direct3D 9.0c.” Available online at http://www.moon-labs.com/resources/d3dx_skinnedmesh.pdf, 2004. [Taylor03], Taylor, Phil, “Modular D3D SkinnedMesh.” Available online at http://www.flipcode.com/articles/article_dx9skinmeshmod.shtml, 2003. 72 Character Animation with Direct3D Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. 73 Skeletal Animation4 The previous chapter covered the basics of skinned meshes, as well as how to load them from an .x file. Apart from the added bone hierarchy, these meshes were still not animated and therefore not much more interesting to look at than a regular sta- tic mesh. That will change in this chapter, and you’ll learn how to load animation data and apply it to a skinned mesh. This chapter covers the following: Keyframe animation basics Loading animation data The ID3DXAnimationController Having multiple controllers affecting the same mesh Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. KEYFRAME ANIMATION As you might know, a movie is made up of several still images running quickly and therefore creating the illusion of a moving picture. These still images are known as frames. Each frame has a certain place in time as well as a picture of how the “world” looks at this specific time step. Keyframe animation has been around for quite some time. In fact, it was used in the very first TV cartoons, for example. The way it worked was that the senior animator would draw two images containing the poses of a cartoon character at two different time steps (these frames are the so-called keyframes). The senior animator would then give these keyframes to a junior animator and have him fill out the rest of the frames in between, a process also known as tweening (from “in-between-ing”). In many cases the keyframes are drawn by one artist in company A, and then the rest of the frames are drawn by another artist in company B (which might even be located in a completely different country). Each Simpson’s episode, for example, is drawn mostly in India. What makes keyframing so powerful is that it can be applied to almost anything (see Figure 4.1). 74 Character Animation with Direct3D FIGURE 4.1 Several examples using the keyframing technique. Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. In Figure 4.1 the two keyframes are highlighted with gray background. Now take a minute and try to imagine what the little square would look like if all the transformations were applied at the same time across these two keyframes. In computer animation this technique is very powerful. Even if the time step varies in length and regularity (as the frame rate often does in games), this technique can still be used to calculate the current frame based on two keyframes. DirectX uses these two structures to describe keyframes. The D3DXKEY_VECTOR3 structure can describe translation and scale keyframes. Rotation, on the other hand, is described by the D3DXKEY_QUATERNION structure, since using Euler angles can result in a Gimbal lock. A Gimbal lock occurs when an object is rotated along one axis in such a way that it aligns two of the x, y, and z axes. As soon as this happens, one degree of freedom is lost and the condition can’t be reversed no matter what rotation operation is performed on the object. Quaternions are a much safer option than Euler angles (although somewhat harder to comprehend). Anyhow, here are the two DirectX keyframe structures: struct D3DXKEY_VECTOR3 { FLOAT Time; D3DXVECTOR3 Value; }; struct D3DXKEY_QUATERNION { FLOAT Time; D3DXQUATERNION Value; }; As you can see, they both contain a timestamp as well as a value describing the translation, scale, or rotation of the object at that time. If you’re not familiar with quaternions at the moment, don’t worry; these will be looked into in more depth when you reach Chapter 6. The time of these key structures is in animation ticks, not in seconds. The amount of ticks an animation uses is equivalent to the time resolution used by the animation. Next, check out how to combine lots of these keyframes into an animation! Chapter 4 Skeletal Animation 75 Please purchase PDF Split-Merge on www.verypdf.com to remove this watermark. [...]... any animations stored in an ID3DXAnimationController: void SkinnedMesh::GetAnimations(vector &animations) { ID3DXAnimationSet *anim = NULL; for(int i=0;iGetMaxNumAnimationSets();i++) ease purchase PDF Split-Merge on www.verypdf.com to remove this watermark 80 Character Animation with Direct3D { anim = NULL; m_pAnimControl->GetAnimationSet(i, &anim); if(anim != NULL) { animations.push_back(anim->GetName());... SKINNEDMESH class fills a vector with all the names of the animation sets stored in the character s ID3DXAnimationController First the GetMaxNumAnimationSets() function is used to query the number of animation sets, and then the GetAnimationSet() function can be used to get an actual animation set An ID3DXAnimationController object has several tracks, where each track is a slot for an animation set This means... which animation to play, simply use the GetAnimationSet() function to retrieve the animation set, and then use the SetTrackAnimationSet() to activate it Once you’ve set the animation set for one (or more) tracks, you’re ready to start the actual animation You can update/play the animations using the following function: HRESULT AdvanceTime( DOUBLE TimeDelta, //Time to advance animation with LPD3DXANIMATIONCALLBACKHANDLER...76 Character Animation with Direct3D A NIMATION S ETS Animation sets are simply collections of animations, where an animation is a collection of keyframes Now that you know the theory behind keyframe animation, it is time to turn to the practical side of things In this section you’ll get familiar with the ID3DXKeyframedAnimationSet interface This interface contains... to add new keyframes, set animation speed, etc Connect the Animation class to a mesh Make use of the scale, rotation, and translation you get from the animation set Play around with the ID3DXAnimationController you retrieved from the Soldier See if you can create a new animation set in code and register it with the controller (Hint: The RegisterAnimationSet() and RegisterAnimationOutput() functions... several active animations at the same time, and even blend between them The animation controller’s tracks will be covered in more detail in the next chapter For now, just assume that you have only one track with one active animation In this case you set the active animation for a track using this function: HRESULT SetTrackAnimationSet( UINT Track, LPD3DXANIMATIONSET pAnimSet ); //Track index / /Animation. .. NIMATION C ONTROLLER I NTERFACE Okay, you already know how to create a set of different animations Why is an animation controller interface needed? Well, the ID3DXAnimationController interface controls all aspects of keyframed animation It deals with anything from setting the active animation to blending multiple animations, animation callbacks, and so on (more on this in Chapter 5) In this chapter you’ll... Split-Merge on www.verypdf.com to remove this watermark 82 Character Animation with Direct3D M ULTIPLE A NIMATION C ONTROLLERS So far, so good You have one mesh, one animation controller, and, all in all, one working character What if you need two characters? Hmmm… The naïve way would be to have two meshes and two animation controllers No real problem with that However, what if you need an army? Clearly,... can clone the character s animation controller using the following function: HRESULT CloneAnimationController( UINT MaxNumAnimationOutputs, UINT MaxNumAnimationSets, UINT MaxNumTracks, UINT MaxNumEvents, LPD3DXANIMATIONCONTROLLER * ppAnimController ); //Num outputs (i.e bones) //Num animation sets //Num tracks //Num events //Anim controller copy Once a clone has been created from an animation controller,... of character animation LOADING THE ANIMATION DATA You have already come in contact with the function used to load the ID3DXAnimationobject in the previous chapter If you remember, the D3DXLoadMeshHierarchyFromX() function was used to load the bone hierarchy from an x file One of the output parameters from this function is an ID3DXAnimationController object containing all the animation data stored with . watermark. 82 Character Animation with Direct3D MULTIPLE ANIMATION CONTROLLERS So far, so good. You have one mesh, one animation controller, and, all in all, one working character. What if you need two characters?. of the character bones. Here’s how you would obtain any animations stored in an ID3DXAnimationController: void SkinnedMesh::GetAnimations(vector<string> &animations) { ID3DXAnimationSet. the character s animation controller using the following function: HRESULT CloneAnimationController( UINT MaxNumAnimationOutputs, //Num outputs (i.e. bones) UINT MaxNumAnimationSets, //Num animation

Ngày đăng: 03/07/2014, 05:20

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan