Jump to content
  • Advertisement
Sign in to follow this  
  • entries
    45
  • comments
    44
  • views
    51018

Skinned mesh code part 4 - implementation example

Sign in to follow this  
Norman Barrows

1251 views

Skinned mesh code part 4 - implementation example

An implementation example from Caveman 3.0:


// called by draw_skinmesh_caveman // draws eyeballs attached to the headbone with an offset.// to draw a static mesh relative to the root of a bone, // start with the transform matrix for the object relative to the root of the bone, // then concatenate on the bone`s CombinedTransformationMatrix// don`t forget to call update_ani and add_world_transform_to_skeleton first!// use get_bone to get a D3DXFRAME pointer to the bone by name, and save it for // later use when drawing meshes attached to that bone.void draw_eyeballs2(int skmeshID,int texID){Zdrawinfo a;Zcdi(&a);a.meshID=146;a.texID=texID;a.cull=1;D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED *)skinned_mesh_pool[skmeshID].headbone;// use matrix manipulator to create bone to right eyeball transform matrix...Mstart();switch (skmeshID) { case 5: case 6: case 9: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(0.0318f,0.1831f,0.082f); break; case 7: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(0.0318f,0.1833f,0.0835f); break; case 8: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(0.0318f,0.1833f,0.082f); break; default:// skmeshID 0,1,2,3,4 Mscale(0.015f,0.015f,-0.015f); Mrotate(0,-20); Mmove(0.036f,0.099f,0.076f); break; }// cat combined matrix onto matrix manipulator mat to get world mat... D3DXMatrixMultiply(&a.mWorld,&Mmat,&pFrame->CombinedTransformationMatrix);// add to render queue... Zdraw2(&a);// use matrix manipulator to create bone to left eyeball transform matrix... Mstart(); switch (skmeshID) { case 5: case 6: case 9: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(-0.0318f,0.1831f,0.082f); break; case 7: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(-0.0337f,0.1825f,0.0828f); break; case 8: Mscale(0.013f,0.013f,-0.013f); Mrotate(0,-17); Mmove(-0.0337f,0.1825f,0.082f); break; default:// skmeshID 0,1,2,3,4 Mscale(0.015f,0.015f,-0.015f); Mrotate(0,-20); Mmove(-0.035f,0.098f,0.076f); break; }// cat combined matrix onto matrix manipulator mat to get world mat... D3DXMatrixMultiply(&a.mWorld,&Mmat,&pFrame->CombinedTransformationMatrix);// add to render queue... Zdraw2(&a); } // draws hair mesh attached to the headbone with an offset.// to draw a static mesh relative to the root of a bone, // start with the transform matrix for the object relative to the root of the bone, // then concatenate on the bone`s CombinedTransformationMatrix// don`t forget to call update_ani and add_world_transform_to_skeleton first!// use get_bone to get a D3DXFRAME pointer to the bone by name, and save it for // later use when drawing meshes attached to that bone.void draw_girl_hair(int skmeshID,int hmeshID,int texID){Zdrawinfo a; Zcdi(&a); a.meshID=hmeshID; a.texID=texID;D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED *)skinned_mesh_pool[skmeshID].headbone;// use matrix manipulator to create bone to hair mesh transform matrix...// start w/ identity matrix... Mstart(); switch (hmeshID) { case 154:// long messy Mscale(0.925f,1.317f,1.2203f); Mrotate(0,-5); Mmove(0.002f,-0.032f,-0.07f); break; case 254:// short ponytail Mscale(1.2f,1.5f,1.15f); Mmove(-0.002f,0.103f,-0.05f); break; case 255:// short Mscale(1.09f,1.41f,1.1f); Mmove(-0.004f,0.051f,-0.028f); break; case 258:// short afro Mscale(1.224f,1.28f,1.15f); Mmove(-0.002f,0.06f,-0.032f); break; case 259:// long afro / dreads Mscale(1.23f,1.66f,1.27f); Mmove(0.004f,0.059f,-0.02f); break; default:// tex 260 - long straight Mscale(0.996f,1.381f,1.403f); Mrotate(0,-10); Mmove(0.002f,0.059f,-0.039f); break; }// cat combined matrix onto matrix manipulator mat to get world mat...D3DXMatrixMultiply(&a.mWorld,&Mmat,&pFrame->CombinedTransformationMatrix);// add to render queue...Zdraw2(&a);} // draws hair mesh attached to the head bone with an offset.// to draw a static mesh relative to the root of a bone, // start with the transform matrix for the object relative to the root of the bone, // then concatenate on the bone`s CombinedTransformationMatrix// don`t forget to call update_ani and add_world_transform_to_skeleton first!// use get_bone to get a D3DXFRAME pointer to the bone by name, and save it for // later use when drawing meshes attached to that bone.void draw_guy_hair(int skmeshID,int hmeshID,int texID){Zdrawinfo a;Zcdi(&a);a.meshID=hmeshID;a.texID=texID;D3DXFRAME_DERIVED *pFrame = (D3DXFRAME_DERIVED *)skinned_mesh_pool[skmeshID].headbone;// use matrix manipulator to create bone to hair mesh transform matrix...// start w/ identity matrix...Mstart();switch (hmeshID) { case 258: case 259: Mscale(1.11f,1.2f,1.2f); Mmove(0.0f,0.152f,-0.005f); break; case 250: Mscale(1.08f,1.073f,1.078f); Mmove(-0.0047f,0.177f,0.016f); break; case 265: Mscale(0.818f,0.815f,1.028f); Mmove(-0.0023f,0.143f,-0.039f); break; case 266: Mscale(1.07f,1.18f,0.8876f); Mrotate(0,-13); Mmove(-0.0023f,0.215f,-0.005f); break; default:// -1 = bald return; break; }// cat combined matrix onto matrix manipulator mat to get world mat...D3DXMatrixMultiply(&a.mWorld,&Mmat,&pFrame->CombinedTransformationMatrix);// add to render queue...Zdraw2(&a);} void draw_hair(int sex,int skmeshID,int hmeshID,int texID){if (sex == 0) { draw_guy_hair(skmeshID,hmeshID,texID); }else { draw_girl_hair(skmeshID,hmeshID,texID); }} // draws a caveperson using the specified hair mesh, textures, and animationvoid draw_skinmesh_caveman(int sex,int hair,int bodT,int hairT,int eyeT,int clothT,int ani,int ctrl,double dt,D3DXMATRIX *mWorld){// sex: 0=male 1=female// hair is hair mesh ID. -1 = bald.// bodT is body mesh texture ID// hairT is hair texture ID// eyeT is eye texture ID// clothT is clothing texture ID// ani is which ani should be playing// ctrl is the index of the character`s controllerint a;// a is the skinned_mesh_pool index of the body mesha=controller_pool[ctrl].mesh_index;// 1. set textures in the skinned mesh poolskinned_mesh_pool[a].body->texID=bodT;skinned_mesh_pool[a].loincloth->texID=clothT;if (sex == 1) { skinned_mesh_pool[a].bra->texID=clothT; }// 2. set animationcontroller_pool_setani(ctrl,ani);// 3. draw instance ( controllerID, dt, mWorld )draw_skinned_mesh_instance(ctrl,dt,mWorld);// set z3d state manager current mesh to none...Zcurrentmesh=-1;// reset FVF back to z3d FVF...Zd3d_device_ptr->SetFVF(ZFVF);// 4. draw eyesdraw_eyeballs2(a,eyeT);// 5. draw hairdraw_hair(sex,a,hair,hairT);} // tests drawing 100 instances of a skinned mesh, each with its own controller// uses update_and_draw_skinned_mesh w/ drawmeshcontainer5void skinned_mesh_test3(){// hair is which hair mesh to use. 0 through num hair meshes - 1.int i,quit,et,fps,num_anisets,hair,hairmeshID,cx,cz,xr,sex,bodT,eyeT,hairT,clothT;float x,z;char s[100],s2[100];bodT=0;eyeT=0;hairT=0;clothT=0;sex=0;xr=0;hair=0;hairmeshID=154;cx=0;cz=-100;// no need to init stuff - its done in initprog now.// c init_controller_pool// c load_all_skinned_meshesnum_anisets=(int)skinned_mesh_pool[0].controller->GetNumAnimationSets();// ss s "num anisets: "// c i2s num_anisets s2// s+ s s2// c msg3 sfor (i=0; i<100; i++) { activate_controller(i%10);// set it to play a random ani... controller_pool_setani(i,i%num_anisets); }// set a directional light...Zsetlite(0,0.0f,-1.0f,1.0f,1.0f);// turn it on...Zlite(0,1);quit=0;// set material to z3d default material....Zsetmaterial(0);et=0;fps=0;// init matrix editorAAinit();// turn on matrix editorAAturnon();while (!quit) {// timer 8 is used for framerate limiter.// like Caveman 3.0, the test runs at 15fps. i`ve also run it at 60 fps no problem. Zstarttimer(8);// set view matrix.... Zsetcam((float)cx/10.0f,5.0f,(float)cz/10.0f,0.0f,0.0f,0.0f); Zclearscreen(32,0,32); Zclearzbuf(); Zbeginscene(); Zcleardrawlist(); x=-10.0f; z=0.0f; for (i=0; i<100; i++) { sex=i%10; if (sex < 5) { sex=1; } else { sex=0; } if (sex == 0) {// male skin textures: 299 = mideastern 389 = sm_guy1.bmp bodT=389; eyeT=300; hairT=267; clothT=159; switch (hair) { case 0: hairmeshID=258; break; case 1: hairmeshID=259; break; case 2: hairmeshID=250; break; case 3: hairmeshID=265; break; case 4: hairmeshID=266; break; case 5: hairmeshID=-1; break; } } else {// girl skin textures: 387, 388 bodT=387;// eye textures: 292=blue 300=brown eyeT=292;// hair textures: 291=blonde 267=black hairT=291;// cloth textures: 159=light hide 192=dark hide clothT=159; switch (hair) { case 0: hairmeshID=154; break; case 1: hairmeshID=254; break; case 2: hairmeshID=255; break; case 3: hairmeshID=258; break; case 4: hairmeshID=259; break; case 5: hairmeshID=260; break; } } Mstart(); Mrotate(1,xr); Mmove(x,0.0f,z); draw_skinmesh_caveman(sex,hairmeshID,bodT,hairT,eyeT,clothT,i%num_anisets,i,0.066,&Mmat); x+=2.0f; if (x >= 10.0f) { x=-10.0f; z+=2.0f; } } Zdrawlist(); Zbeginsprite(); tx2(100,0,"press ESC to quit press SPACE to change hair mesh"); tx2(100,50,"use wasd to move camera L/R arrows: rotate models"); strcpy_s(s,100,"frame time: "); i2s(et,s2); strcat_s(s,100,s2); strcat_s(s,100," ms"); tx2(100,700,s); if (et == 0) { fps=0; } else { fps=1000/et; } strcpy_s(s,100,"fps: "); i2s(fps,s2); strcat_s(s,100,s2); tx2(100,750,s); Zendsprite();// draw matrix editor AAdraw();// end scene and present... Zshowscene();// process matrix editor input AAprocess_input(); if (Zkeypressed(VK_SPACE)) {// c change_ani ani_controller_ptr2 num_anis hair++; if (hair > 5) { hair=0; } while (Zkeypressed(VK_SPACE)) { } }// if they hit escape, quit the test... if (Zkeypressed(VK_ESCAPE)) { quit=1; } if (Zkeypressed(0x57)) {// w key cz++;// wh Zkeypressed(0x57)// . } if (Zkeypressed(0x41)) {// a key cx--;// wh Zkeypressed(0x41)// . } if (Zkeypressed(0x53)) {// s key cz--;// wh Zkeypressed(0x53)// . } if (Zkeypressed(0x44)) {// d key cx++;// wh Zkeypressed(0x44)// . } if (Zkeypressed(VK_LEFT)) { xr-=2; if (xr < 0) { xr=359; } } if (Zkeypressed(VK_RIGHT)) { xr+=2; if (xr > 359) { xr=0; } }// framerate limiter: wait until 66 millisconds has passed before beginning next frame...// wh Zelapsedtime(8)<66// . et=Zelapsedtime(8); }// c msg3 "unloading stuff..."// turn off matrix editorAAturnoff();// no need to uninit stuff now - its done by endprog.// c deactivate_all_controllers// c unload_all_skinned_meshes// c msg3 "all done!"} // enum ani_type: stand, walk, run, backstep; #define ANI_STAND 0#define ANI_WALKBACK 1#define ANI_WALK 2#define ANI_RUN 3 // set skinned mesh ani for a npcvoid set_sm_npc_ani(int a,int ani){// a is animal #// ani is the animation # to playint n;// n is npc #int c;// c is controller #n=animal[a].butchered;c=npc[n].controllerID;controller_pool_setani(c,ani);} // set skinned mesh ani for a player character (a band member)void set_sm_pc_ani(int a,int ani){// a is band member #// ani is the animation # to playcontroller_pool_setani(cm[a].controllerID,ani);} // ------------------------ end skinned mesh --------------------------
Sign in to follow this  


  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

Participate in the game development conversation and more when you create an account on GameDev.net!

Sign me up!