;///////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////// ; ; 位置座標と、クォータニオンの、スプライン補間計算のサンプル ; ; スプライン計算には、4つの連続した制御点の設定が必要です。 ; 4つの制御点には、それぞれ、変数のプレフィックスに、bef, start, end, aftを付けています。 ; startとendの間にある点を、スプライン補間計算します。 ; befは、startのひとつ前の制御点を、aftは、endのひとつ後の制御点を表しています。 ; ; このサンプルでは、slimenum個のスライムの、位置座標と、向きを、 ; それぞれ、スプライン補間して、表示しています。 ; ; Z字型に、4つの制御点を配置しています。 ; befがZの右下のスライム、startがZの左下のスライム、endがZの右上のスライム、aftがZの左上のスライムです。 ; MoveSlime関数内で、4つの制御点の設定と、startからendの間のスライムの補間計算をしています。 ; ; 制御点が3つしかない場合は、befをstartと同じにするか、または、aftをendと同じにして、計算してください。 ; 制御点が2つしかない場合は、スプライン補間は、使わないでください。 ; ; ; E3DSquadQは、姿勢が大きく変化するクォータニオンの補間には、向いていません。 ; 大きく変化する場合は、E3DSlerpQをお使いください。 ; ;///////////////////////////////////////////////////////// ;///////////////////////////////////////////////////////// ; e3dhsp.dll test script #include "e3dhsp3.as" #module #deffunc waitbyfps int p1, var fps E3DWaitbyFPS@ p1, fps await 0 return #global dim keybuf, 256 screenw = 640 : screenh = 480 screen 0, screenw, screenh, 1 title "Easy3D for HSP3 sample" ;開発中は下の行のコメントアウトを外すことを推奨します。 ;E3DEnableDbgFile ;初期化 E3DInit 0, -1, 0, 16, 0, scid1 ;カメラ変数の初期化 cameradist = 12000.0 cameraheight = 400.0 camdegxz = 180.0 camposx = 0.0 camposy = cameraheight camposz = 0.0 ;file のpath 用のバッファーの作成 pathlen = 2048 sdim mediadir, pathlen mediadir = dir_cur + "\\Media" sdim pathbuf, pathlen, 2 ;projectionの変更をしたいときは、以下の2行を有効にしてください。 proj_near = 100.0 : proj_far = 20000.0 : proj_fov = 60.0 E3DSetProjection proj_near, proj_far, proj_fov E3DCreateProgressBar E3DSetProgressBar 0 ;地面データのロード pathbuf.0 = mediadir + "\\groundplane1_p_small.sig" E3DSigLoad pathbuf.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 E3DSetProgressBar 50 ;slimeデータのロード pathbuf.0 = mediadir + "\\slime25.sig" pathbuf.1 = mediadir + "\\slime_paku.qua" slimenum = 15 dim slimehsid, slimenum slimeno = 0 repeat slimenum E3DSigLoad pathbuf.0, slimehsid.slimeno E3DSetPos slimehsid.slimeno, 0.0, 0.0, 0.0 E3DAddMotion slimehsid.slimeno, pathbuf.1, motid1, framemax1 E3DSetMotionKind slimehsid.slimeno, motid1 slimeno++ loop ; 座標系算用のメモリの確保 ddim befpos, 3 ddim startpos, 3 ddim endpos, 3 ddim aftpos, 3 ddim respos, 3 start_posy = -4000.0 end_posy = 4000.0 ; 向きの計算用のクォータニオンの確保 E3DCreateQ befqid E3DCreateQ startqid E3DCreateQ endqid E3DCreateQ aftqid E3DCreateQ resqid start_rotz = -40.0 end_rotz = 40.0 E3DSetProgressBar 80 ;以下、ライトの設定 lightdirx1 = 0.0 lightdiry1 = 0.0 lightdirz1 = 1.0 lightr1 = 128 lightg1 = 128 lightb1 = 128 ;平行光源 E3DCreateLight lid1 E3DSetDirectionalLight lid1, lightdirx1, lightdiry1, lightdirz1, lightr1, lightg1, lightb1 chkfps1 = 0 E3DDestroyProgressBar *main ; keybuf変数は、メインループの外で、dim keybuf, 256 として、確保しておいてください。 E3DGetKeyboardState keybuf if keybuf.VK_ESCAPE = 1 : goto *bye ; [ESC]で終了 gosub *MoveCamera gosub *MoveSlime E3DBeginScene scid1 E3DChkInView scid1, hsid0 slimeno = 0 repeat slimenum E3DChkInView scid1, slimehsid.slimeno slimeno++ loop E3DRender scid1, hsid0, 0, 0, 0 slimeno = 0 repeat slimenum E3DRender scid1, slimehsid.slimeno, 0, 0, 0 slimeno++ loop gosub *DrawText E3DEndScene E3DPresent scid1 waitbyfps 100, chkfps1 goto *main *bye E3DBye end *MoveCamera E3DSin camdegxz, camposx E3DCos camdegxz, camposz camposx *= cameradist camposz *= cameradist E3DSetCameraPos camposx, camposy, camposz E3DSetCameraTarget 0.0, camposy, 0.0, 0.0, 1.0, 0.0 return *MoveSlime ; Spline計算に必要な、befpos, startpos, endpos, aftposを初期化する。 xstep = 800.0 minxpos = ( double(slimenum) / 2.0 ) * -1.0 * xstep maxxpos = minxpos + ( ( slimenum - 1 ) * xstep ) befpos.0 = maxxpos + 1000.0 befpos.1 = start_posy - 2000.0 befpos.2 = 0.0 startpos.0 = minxpos startpos.1 = start_posy startpos.2 = 0.0 endpos.0 = maxxpos endpos.1 = end_posy endpos.2 = 0.0 aftpos.0 = minxpos - 1000.0 aftpos.1 = end_posy + 2000.0 aftpos.2 = 0.0 E3DSetPos slimehsid.0, befpos.0, befpos.1, befpos.2 aftslimeno = slimenum - 1 E3DSetPos slimehsid.aftslimeno, aftpos.0, aftpos.1, aftpos.2 ; slimeno 1 から、slimeno (slimenum - 1)までの座標を、スプライン補間計算する。 calcno = 0 slimeno = 1 repeat ( slimenum - 2 ) E3DSplineVec befpos, startpos, endpos, aftpos, double(calcno) / (slimenum - 3), respos E3DSetPos slimehsid.slimeno, respos.0, respos.1, respos.2 slimeno++ calcno++ loop ; Squad命令に必要な、befq, startq, endq, aftqを初期化する。 E3DSetQAxisAndDeg befqid, 0.0, 0.0, 1.0, end_rotz E3DSetQAxisAndDeg startqid, 0.0, 0.0, 1.0, start_rotz E3DSetQAxisAndDeg endqid, 0.0, 0.0, 1.0, end_rotz E3DSetQAxisAndDeg aftqid, 0.0, 0.0, 1.0, start_rotz E3DSetDirQ2 slimehsid.0, befqid aftslimeno = slimenum - 1 E3DSetDirQ2 slimehsid.aftslimeno, aftqid ; slimeno 1 から、slimeno (slimenum - 1)までの向きを、スプライン補間計算する。 calcno = 0 slimeno = 1 repeat ( slimenum - 2 ) E3DSquadQ befqid, startqid, endqid, aftqid, double(calcno) / (slimenum - 3), resqid E3DSetDirQ2 slimehsid.slimeno, resqid slimeno++ calcno++ loop ;以下は、球面線形補間の場合 ;calcno = 0 ;slimeno = 1 ;repeat ( slimenum - 2 ) ; E3DSlerpQ startqid, endqid, calcno, slimenum - 3, resqid ; E3DSetDirQ2 slimehsid.slimeno, resqid ; slimeno++ ; calcno++ ;loop ; slimeのポーズを更新する slimeno = 0 repeat slimenum E3DSetNewPose slimehsid.slimeno, frameno slimeno++ loop return *DrawText textposx = 10 : textposy = 10 textr = 255 : textg = 255 : textb = 255 textscale = 1 textposx = 10 : textposy = 10 str5 = "chkfps1 " + chkfps1 E3DDrawText textposx, textposy, textscale, textr, textg, textb, str5 slimeno = 0 repeat slimenum E3DGetPos slimehsid.slimeno, chkposx, chkposy, chkposz str6 = " slime " + slimeno + " " + "x " + chkposx + " y " + chkposy + " z " + chkposz textposy += 15 E3DDrawText textposx, textposy, textscale, textr, textg, textb, str6 slimeno++ loop return