;///////////////////////////////////////////////////////// ;// ;// マウスで、ボーンをドラッグして、IKで、ポーズを作るサンプルです。 ;// マウス左ボタンドラッグで、回転し、右ドラッグで、移動します。 ;// ポーズのセットは、MouseDePose というラベル以下で、行っています。 ;// ;// カメラの動きは、e3dhsp_toolscamera.asと同じです。 ;// 矢印キーで、注視点を周りに回転します。 ;// Shift + 矢印キーで、視点と注視点が、平行移動(画面に対して平行に)します。 ;// Z, Xキーで、注視点に接近したり、遠ざかったりします。 ;// カメラの位置のプレフィックスは、campos、 ;// 注視点のプレフィックスは、targetです。 ;// ;// E3DHSP ver1.0.9.1で、マウスのホイールによる、ボーンのツイスト機能を追加しました。 ;// TwistBone以下で、処理しています。 ;// ;////////////////////////////////////////////////////////// ; e3dhsp.dll test script #include "e3dhsp3.as" #module #deffunc waitbyfps int p1, var fps E3DWaitbyFPS@ p1, fps await 0 return #global dim keybuf, 256 ;file のpath 用のバッファーの作成 pathlen = 2048 sdim mediadir, pathlen mediadir = dir_cur + "\\Media" sdim pathbuf, pathlen, 2 chgdegx = 0.0 : chkdegy = 0.0 : chkdegz = 0.0 screenw = 640 : screenh = 480 screen 0, screenw, screenh, 1 pointmax = 100 title "Easy3D for HSP3 sample" ;開発中は下の行のコメントアウトを外すことを推奨します。 ;E3DEnableDbgFile ;初期化 E3DInit 0, -1, 0, 16, 0, scid1 ;カメラの初期化 eye_y = 800.0 E3DSetCameraPos camposx, camposy, camposz camposx = 0.0 : camposy = eye_y : camposz = 2800.0 camdegxz = 0.0 : camdegy = 0.0 E3DSetCameraDeg camdegxz, camdegy targetx = 0.0 targety = eye_y targetz = 0.0 cameradist = 2000.0 ;projectionの変更をしたいときは、以下の2行を有効にしてください。 proj_near = 100.0 : proj_far = 30000.0 : proj_fov = 60.0 E3DSetProjection proj_near, proj_far, proj_fov E3DCreateProgressBar E3DSetProgressBar 0 ;地面データのロード pathbuf.0 = mediadir + "\\ground.mqo" E3DLoadMQOFileAsGround pathbuf.0, 10.0, hsid0 posx0 = 0.0 : posy0 = 0.0 : posz0 = 0.0 degx0 = 0.0 : degy0 = 0.0 : degz0 = 0.0 E3DSetPos hsid0, posx0, posy0, posz0 E3DSetDir hsid0, degx0, degy0, degz0 frameno0 = 0 E3DSetProgressBar 30 ;キャラクターデータの読み込み pathbuf.0 = mediadir + "\\poo\\poo.sig" E3DSigLoad pathbuf.0, hsid1 posx1 = 0.0 posy1 = 0.0 posz1 = 0.0 E3DSetPos hsid1, posx1, posy1, posz1 ;キャラクターのモーションの読み込み pathbuf.0 = mediadir + "\\poo\\init.qua" E3DAddMotion hsid1, pathbuf.0, motid, maxframe E3DSetMotionKind hsid1, motid ;キャラクターのジョイント情報の取得 E3DGetJointNum hsid1, jointnum sdim jointname, 256, jointnum dim jointinfo, JI_MAX, jointnum E3DGetJointInfo hsid1, jointnum, jointname, jointinfo, jointgetnum ;ボーンマーク pathbuf.0 = mediadir + "\\bonemark.mqo" E3DLoadMQOFileAsGround pathbuf.0, 1.0, hsid2 ;E3DLoadMQOFileAsGroundで、EXTLINE_ で始まるオブジェクト名を含むmqoを読み込むと、 ;そのオブジェクトは、ボーンでなく、ラインとして、読み込まれます。 E3DSetRenderState hsid2, -1, D3DRS_ZFUNC, 8 ;この設定をすると、モデルデータの奥行き情報に関係なく、必ず、描画されるようになります。 ;ボーンマークの線が、3Dオブジェクトに隠れてしまわないように、この設定をします。 E3DCreateQ qid2 ;ボーンマークの向きを設定するためのクォータニオン ;ポーズ編集用変数 Ldragflag = 0 ;マウスの左ボタンをドラッグしている間、1になる。それ以外は0 Rdragflag = 0 ;マウスの右ボタンをドラッグしている間、1になる。それ以外は0 pickboneno = 0 ;マウスのボタンを押したときに、マウスの位置の近くにジョイントがあれば、その番号が代入される。なければ0 clickoffsetx = 0 ;マウスのボタンを押したときの、マウスのX座標と、pickしたジョイントのX座標のずれ。 clickoffsety = 0 ;マウスのボタンを押したときの、マウスのY座標と、pickしたジョイントのY座標のずれ。 E3DSetProgressBar 60 ; スプライトデータの読み込み pathbuf.0 = mediadir + "\\circle.bmp" E3DCreateSprite pathbuf.0, 1, spid1 E3DGetSpriteSize spid1, spw1, sph1 ;ライト lightdirx1 = 0.0 lightdiry1 = 0.0 lightdirz1 = 1.0 lightr1 = 255 lightg1 = 255 lightb1 = 255 E3DCreateLight lid1 E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1 /////////////////////// E3DCreateQ camq E3DCreateQ invcamq chkfps1 = 0 E3DDestroyProgressBar *main ; keybuf変数は、メインループの外で、dim keybuf, 256 として、確保しておいてください。 E3DGetKeyboardState keybuf if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了 E3DSetMotionFrameNo hsid1, motid, 0 ;このサンプルでは、常に、フレーム0を表示する。 E3DSetNewPose hsid1, frameno1 gosub *MoveCamera E3DBeginScene scid1 E3DChkInView scid1, hsid0 E3DChkInView scid1, hsid1 E3DRender scid1, hsid0, 0, 0, 0 E3DRender scid1, hsid1, 0, 0, 0 E3DRender scid1, hsid1, 1, 0, 0 gosub *DrawSprite gosub *DrawBoneMark gosub *DrawText E3DEndScene E3DPresent scid1 gosub *MouseDePose gosub *WheelTwist waitbyfps 60, chkfps1 goto *main *bye E3DBye end *MoveCamera ; VK_ が頭につく、定数の詳細は、e3dhsp_vk.as をご覧ください。 ; keybuf は、GetKeyboardState 命令で、セットされます。 k=0 if keybuf.VK_LEFT = 1 : k+=1 ; 矢印左 if keybuf.VK_UP = 1 : k+=2 ; 矢印上 if keybuf.VK_RIGHT = 1 : k+=4 ; 矢印右 if keybuf.VK_DOWN = 1 : k+=8 ; 矢印下 if keybuf.VK_SHIFT = 1 : k+= 16 shift = 20.0 deg = 2.0 if ( k&16 ) { if( k&1 ){ //左平行移動 deg = camdegxz + 90.0 E3DSin deg, shiftx E3DCos deg, shiftz shiftx *= shift shiftz *= shift targetx += shiftx targetz -= shiftz } if( k&4 ){ //右平行移動 deg = camdegxz - 90.0 E3DSin deg, shiftx E3DCos deg, shiftz shiftx *= shift shiftz *= shift targetx += shiftx targetz -= shiftz } if( k&2 ){ //上平行移動 E3DGetCameraQ camq E3DInvQ camq, invcamq E3DMultQVec invcamq, 0.0, shift, 0.0, shiftx, shifty, shiftz targetx += shiftx targety += shifty targetz += shiftz eye_y = targety } if( k&8 ){ //下平行移動 E3DGetCameraQ camq E3DInvQ camq, invcamq E3DMultQVec invcamq, 0.0, -shift, 0.0, shiftx, shifty, shiftz targetx += shiftx targety += shifty targetz += shiftz eye_y = targety } } else { //左右回転 if k&1 : camdegxz += deg if k&4 : camdegxz -= deg if( camdegxz > 360.0 ){ camdegxz -= 360.0 } if( camdegxz < 0.0 ) { camdegxz += 360.0 } //上下回転 if k&2 : camdegy += deg if k&8 : camdegy -= deg if( camdegy >= 90.0 ){ camdegy = 89.0 } if( camdegy <= -90.0 ){ camdegy = -89.0 } } if( keybuf.'Z' == 1 ){ cameradist -= 100.0 if( cameradist < 500.0 ){ cameradist = 500.0 } } if( keybuf.'X' == 1 ){ cameradist += 100.0 } //targetの場所と角度から、カメラの位置を計算する E3DSin camdegxz, sinxz E3DCos camdegxz, cosxz E3DSin camdegy, siny E3DCos camdegy, cosy camposx = sinxz * cosy * cameradist + targetx camposy = eye_y + siny * cameradist camposz = -cosxz * cosy * cameradist + targetz E3DSetCameraPos camposx, camposy, camposz E3DSetCameraTarget targetx, targety, targetz, 0.0, 1.0, 0.0 return *DrawText sdim strchk, 1024 textr = 255 : textg = 255 : textb = 255 textscale = 1 textposx = 10 : textposy = 10 strchk = "chkfps1 " + chkfps1 E3DDrawText textposx, textposy, textscale, textr, textg, textb, strchk textposy += 20 strchk = "Ldragflag " + Ldragflag E3DDrawText textposx, textposy, textscale, textr, textg, textb, strchk textposy += 20 strchk = "Rdragflag " + Rdragflag E3DDrawText textposx, textposy, textscale, textr, textg, textb, strchk textposy += 20 strchk = "pickboneno " + pickboneno E3DDrawText textposx, textposy, textscale, textr, textg, textb, strchk return *DrawSprite ;ジョイントの位置の2D座標を取得して、その位置に、丸印のスプライトを表示する。 E3DBeginSprite repeat jointgetnum jointno = jointinfo.JI_SERIAL.cnt E3DGetBonePos hsid1, jointno, 1, motid, 0, posx, posy, posz, 1 E3DGetScreenPos2 scid1, posx, posy, posz, scx, scy, validflag scale = 0.07 sizediv = 1.0 / scale scx1 = scx - (spw1 / sizediv / 2) scy1 = scy - (spw1 / sizediv / 2) if ( validflag != 0 ) { E3DRenderSprite spid1, scale, scale, scx1, scy1 } loop E3DEndSprite return *MouseDePose ; 左ドラッグは、回転 if( keybuf.VK_LBUTTON == 1 ){ if( Ldragflag == 0 ){ E3DPickBone hsid1, mousex, mousey, pickboneno if( pickboneno > 0 ){ E3DGetBonePos hsid1, pickboneno, 1, motid, 0, posx, posy, posz, 1 E3DGetScreenPos2 scid1, posx, posy, posz, scx, scy, validflag if( validflag != 0 ){ clickoffsetx = mousex - scx clickoffsety = mousey - scy } } } Ldragflag = 1 } else { Ldragflag = 0 } if( (Ldragflag == 1) & (pickboneno > 0) ){ E3DIKRotateBeta2D scid1, hsid1, pickboneno, motid, 0, 5, 2, 0, 0, 1, 3, mousex - clickoffsetx, mousey - clickoffsety, resx, resy, resz, lastparent } //////////// ;右ドラッグは、移動 if( keybuf.VK_RBUTTON == 1 ){ if( Rdragflag == 0 ){ E3DPickBone hsid1, mousex, mousey, pickboneno if( pickboneno > 0 ){ E3DGetBonePos hsid1, pickboneno, 1, motid, 0, posx, posy, posz, 1 E3DGetScreenPos2 scid1, posx, posy, posz, scx, scy, validflag if( validflag != 0 ){ clickoffsetx = mousex - scx clickoffsety = mousey - scy } } } Rdragflag = 1 } else { Rdragflag = 0 } if( (Rdragflag == 1) & (pickboneno > 0) ){ E3DShiftBoneTree2D scid1, hsid1, pickboneno, motid, 0, mousex - clickoffsetx, mousey - clickoffsety } return *DrawBoneMark ;親ジョイントから子供ジョイントに向かって、ボーンマークが表示されるようにする。 dim childarray, 100 repeat jointgetnum parentno = jointinfo.JI_SERIAL.cnt E3DGetBonePos hsid1, parentno, 1, motid, 0, parx, pary, parz, 1 E3DGetChildJoint hsid1, parentno, 100, childarray, childnum index = 0 repeat childnum childno = childarray.index E3DGetBonePos hsid1, childno, 1, motid, 0, chilx, chily, chilz, 1 E3DInitQ qid2 vecx = chilx - parx vecy = chily - pary vecz = chilz - parz E3DLookAtQ qid2, vecx, vecy, vecz, 0, 0, 1, 3, 1 E3DSetDirQ2 hsid2, qid2 E3DSetPos hsid2, parx, pary, parz E3DVec3Length vecx, vecy, vecz, leng scale = leng / 50.0 E3DSetScale hsid2, -1, scale, scale, scale, 2 if( childno == pickboneno ) { E3DSetLineColor hsid2, 255, 255, 0, 0 } else { E3DSetLineColor hsid2, 255, 64, 128, 128 } E3DChkInView scid1, hsid2 E3DRender scid1, hsid2, 0, 0, 0 index++ loop loop return *WheelTwist savemousew = mousew if ( (pickboneno > 0) & (savemousew != 0) ) { scroll = double( savemousew ) / 300.0 E3DTwistBone hsid1, motid, 0, pickboneno, scroll } return