Sign in to follow this  
  • entries
    45
  • comments
    44
  • views
    50150

Skinned mesh code part 4 - implementation example

Sign in to follow this  
Norman Barrows

1117 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