HSPポータル
サイトマップ お問い合わせ


HSPTV!掲示板


未解決 解決 停止 削除要請

2016
0408
暇人hgimg3で使えるx形式データを作ったりテキストデータからテクスチャ画像を一つのバッファに並べて一枚のテクスチャにするモジュール11解決


暇人

リンク

2016/4/8(Fri) 00:04:49|NO.75192

※addXFileTexのxftopt設定値の処理が色々間違ってたので修正しました

元々↓のスレで作ってたモジュールで使うことを目的で作ってたのを単体で使える様にしてみた
>マイクラ的なのを作ってください お願いします。
http://hsp.tv/play/pforum.php?mode=all&num=72583

↓出来ること
モデル作成時にテクスチャファイルを差し替える。(TextureFilenameが有る時のみ)
x形式のファイルからテクスチャファイル名を抜き出して一つのバッファに並べる(TextureFilename行は削除)
それをテクスチャにして登録した全てのモデルを1枚のテクスチャで済むようにUV値が編集される。
編集されたx形式データをモジュール内に保持して複数統合したデータを作れる(移動、回転やスケール変更も可能)
(但しマテリアルが1枚になるので拡散光設定が全て同じになる)
簡単に箱型のx形式テキストデータを作れる(面毎に違うテクチャを張れる)
4頂点1枚の板として複数の板頂点を配列に入れてx形式テキストデータを作れる(UVマッピングは立方体形式?)

↓追加される命令等
StartXFileTex 「モジュールを使用するための設定と準備」
EndXFileTex 「addxfiletex等で登録された画像をテクスチャにする」

SetXFileDiffusedLight 「モデルの拡散光設定」

addXFileTex 「xfileから画像ファイル名を切り取り画像を順番にテクスチャ用バッファに並べてコピーしてUV座標を書き換えモデルを作成します」
addXFileTexVar 「addxfiletexの変数バージョン」

addTexPic 「テクスチャに使用する画像を登録しインデックスをリストにして取得」

MakeXFileBox 「箱型のX形式テキストデータを作成」

PlateDirTex 「面の向き毎に使用するテクスチャを設定する」(6面を超えると面倒になるので)
PlateDirUVFlip 「面の向き毎にテクスチャUV値の回転反転、面の反転、両面化を設定する」(6面を超えると面倒になるので)
PlateHorVerAng 「面が水平、垂直か判断する角度を調整」(座標をUV値にする時XYZどの軸を選択するかが変わる)
GetXFilePlateVec 「X形式のテキストデータの頂点と頂点インデックスから板毎にXYZ座標4頂点を実数型配列に入れる」
MakeXFilePlate 「板を組み合わせてX形式のテキストデータを作成」(makexfileBOXとはテクスチャファイル名の指定方法が違います。)

KeepXFileTexTXT「mergexfiletextxtで利用するxfileデータをモジュール内に保持してデータインデックスを返す」
MergeXFileTexTXT 「keepxfiletextxtで保持したデータを統合させて一つのモデルデータを作成」

//↓の命令はテクスチャ画像登録に変更が無くなってから使う命令
SetupXFileTexData 「 endxfiletex実行時に保存された画像情報と画像を読み込んでテクスチャID取得」(StartXFileTexとEndXFileTexを実行したのと同等)

以下はaddxfileTex、KeepXFileTexTXT命令でサイズ計算指定した時とGetXFilePlateVec命令実行後に使用可能
「サイズ計算したモデルのサイズが入る変数」
XMD_SIZEX
XMD_SIZEY
XMD_SIZEZ
getfvmin_model 「サイズ計算したモデルの最小座標を取得」
getfvmax_model 「サイズ計算したモデルの最大座標を取得」
getScaleFactor_mode 「サイズ計算したモデルをオブジェクトサイズ1.0にするスケール値取得」


使用サンプルはレスに書きます。

//必ずhgimg3の後にmod_addxfiletexをインクルードしてください。 #module "mod_addxfileTex" KeepID,MeshVecList,MeshVecMax,MeshVecIndexList,MeshVecIndexMax,MeshVecIndexCnt,MeshUVList,MeshUVMax,MeshNormalsList,MeshNormalsMax,MeshNormalsIndex,MeshNormalsIndexMax #ifndef SYSREQ_CALCNORMAL #define global SYSREQ_CALCNORMAL 17 //何故かhgimg3.as内に定義されてないので //法線再計算だと頂点の並びによっては正常に動作しないから削除してる?(頂点が複数の面で利用されてると間違う感じ) #endif //「regobjを差し替えてsetxinfoでテクスチャを設定するように変更」(addxfiletex以外で作られたモデルには-1が) #undef regobj #define global regobj(%1,%2,%3=0,%4=-1) :regobj@hsp %1,%2,%3,%4 :setxinfo %1,tfcnt_list@mod_addxfileTex(%2),$2000,tex_id@mod_addxfileTex: //「delmodelを差し替えてsetxinf使用フラグをクリアするように変更」 #undef delmodel #define global delmodel(%1) :delmodel@hsp %1 :tfcnt_list@mod_addxfileTex(%1)=-1 : //「addxfileTex命令でUV値変換したXFILEデータ」(メモリストリーム設定されてるのでファイル名"MEM:"でロードも可能) #define global MEM_XFILE xof0302txt@mod_addxfileTex //テクスチャ登録作業用バッファID #define global XFILETEX_BUFFER_ID 256 /////////↓↓↓↓↓サイズ取得用マクロや命令↓↓↓↓↓ //////addxfileTex,KeepXFileTexTXT命令でサイズ計算指定した時とGetXFilePlateVec命令実行後に使用可能 ////「サイズ計算したモデルのサイズが入る変数」 #define global XMD_SIZEX dup_mdsizex@mod_addxfileTex #define global XMD_SIZEY dup_mdsizey@mod_addxfileTex #define global XMD_SIZEZ dup_mdsizez@mod_addxfileTex ////「サイズ計算したモデルの最小座標を取得(配列要素数3)」 #deffunc getfvmin_model array minfv minfv=mvmax,mvmax(1),mvmax(2) return ////「サイズ計算したモデルの最大座標を取得(配列要素数3)」 #deffunc getfvmax_model array maxfv maxfv=mvmin,mvmin(1),mvmin(2) return ////「サイズ計算したモデルをオブジェクトサイズ1.0にするスケール値取得」 ////refdvalに最大サイズが返る #deffunc getScaleFactor_model var ScaleFactor if XMD_SIZEX>XMD_SIZEY { if XMD_SIZEX>XMD_SIZEZ {max_size=XMD_SIZEX}else{max_size=XMD_SIZEZ} } else{ if XMD_SIZEY>XMD_SIZEZ {max_size=XMD_SIZEY} else{max_size=XMD_SIZEZ} } ScaleFactor=1.0/max_size return max_size /////////↑↑↑↑↑サイズ取得用マクロや命令↑↑↑↑↑ /////////↓↓↓↓↓登録テクスチャ情報取得マクロ↓↓↓↓↓ ////「登録済みのテクスチャ画像座標をインデックスを指定して取得」 #define global GetTexPosX(%1) (texpos_u@mod_addxfileTex(%1)/ruvsize@mod_addxfileTex) #define global GetTexPosY(%1) (texpos_v@mod_addxfileTex(%1)/ruvsize@mod_addxfileTex) ////「登録済みのテクスチャのUV値をインデックスを指定して取得」 #define global GetTexU(%1) texpos_u@mod_addxfileTex(%1) #define global GetTexV(%1) texpos_v@mod_addxfileTex(%1) ////「テクスチャ画像座標をUV値に変換」 #define global GetTexUV(%1) (RateUV@mod_addxfileTex*((0.0+%1)/divsize)) ////「今回のaddxfileTexで登録されたテクスチャ画像インデックスを取得」 #define global GetTexDivid(%1) texdivid_list@mod_addxfileTex(%1) /////////↑↑↑↑↑登録テクスチャ情報取得マクロ↑↑↑↑↑ ////「startxfiletexで設定したマテリアルテクスチャサイズとは別のサイズを設定」(addxfiletexのオプションに2を指定した時に使われる) //[ SetMaterialSizeExtra mts] // mts : 標準外のマテリアル一枚のテクチャサイズ(0以下が指定されたとき32)「読み込む画像を拡縮してこのサイズにする」 #deffunc SetMaterialSizeExtra double mts if mts>0.0 {matsize_ex=mts}else{matsize_ex=32.0} return ////「モジュールを使用するための設定と準備を使用するための設定と準備」 //[ StartXFileTex mts, tsize ,sfname, fname, loadf] // tsize : 全体のテクスチャサイズ(省略時2048)「必ず2の累乗にしてください」 // mts : マテリアル一枚のテクチャサイズ(省略時32)「読み込む画像を拡縮してこのサイズにする」 // fname : EndXFileTexで保存されたデータとBMPのファイル名「.dat,.bmpを付けて読み込むので拡張子無しで指定してください」 // loadf : データとBMPを読み込むかのフラグ「0=ファイル名が指定されて存在すれば読み込む、1=読み込まない」 #define global StartXFileTex(%1=2048,%2=32.0,%3="",%4=0) _startXFileTex %1,%2,%3,%4 #deffunc _startXFileTex int tsize,double mts,str fname,int loadf gsel_bak=ginfo_sel if (fname ! "") and (loadf = 0) {loadXFileTexData fname+".dat",fname+".bmp":load_f=stat=0}else{load_f=0} if load_f {gsel gsel_bak RateUVI=RateUV //右下側の変換する倍率 RateUVI-=RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 return} texsize=(tsize=0)*2048+tsize Reverse_posu=0.0+texsize Reverse_posv=Reverse_posu texdiv_index=0 uvofsindex=0 add_ofsv=0 if mts!0.0 {divsize=mts}else{divsize=32.0} if matsize_ex=0.0 {matsize_ex=divsize} divmax=int(texsize/divsize) ddim RateUVIlist,divmax*divmax ddim texpos_u,divmax*divmax ddim texpos_v,divmax*divmax RateUV=divsize/texsize //xfileに設定されてるUV値に掛けて1枚のテクスチャ用に変換する倍率 ruvsize=RateUV/divsize hggetreq filter,SYSREQ_3DFILTER RateUVI=RateUV //右下側の変換する倍率 RateUVI-=RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 MarginUV=(RateUV*(filter>1)/divsize)/2 //テクスチャ補間モードが有効の場合隣のドットを巻き込むのを軽減 RateUVI-=MarginUV*2 sdim tfname_list,30*divmax*divmax dim tfname_index,30*divmax*divmax buffer XFILETEX_BUFFER_ID,texsize,texsize color _tbr, _tbg, _tbb boxf gsel gsel_bak EndXFileTex_f=0 gosub *sub_startxfiletex return ////「addxfiletexで登録された画像をテクスチャにする」 //[ EndXFileTex tid ,fname, savef] // tid : テクスチャID取得用変数 // fname : 登録テクスチャ画像情報とbufferを保存するファイル名「.dat,.bmpを付けて保存するので拡張子無しで指定してください」 // savef : データとBMPを保存するかのフラグ「0=ファイル名が指定されてれば保存、1=既に同名ファイルが存在すれば保存しない、2=同名ファイルが存在すればダイアログ表示して保存、3=同名ファイルが存在すればダイアログで保存するか選択、8=使用してるXFILETEX_BUFFER_IDのbufferを縦横1のサイズにする」 #define global EndXFileTex(%1,%2="",%3=0) _EndXFileTex %1,%2,%3 #deffunc _EndXFileTex var tid ,str fname,int savef selid=ginfo_sel gsel XFILETEX_BUFFER_ID settex texsize,texsize tid=stat tex_id=stat EndXFileTex_f=1 if fname ! "" { if (savef&3) > 0 { exist fname+".dat" if strsize<0 { save_mode=1 }else{ save_mode=0 if (savef&3)=2 {dialog "テクスチャ画像と\nそれに関するデータを保存します。":save_mode=1} if (savef&3)=3 {dialog "テクスチャ画像と\nそれに関するデータを保存しますか?。",2:if stat=6{save_mode=1}} } }else{save_mode=1} if save_mode { bmpsave fname+".bmp" saveXFileTexData fname+".dat" } } if (savef&8) {buffer XFILETEX_BUFFER_ID,1,1} gsel selid return ////「 endxfiletex実行時に保存された画像情報と画像を読み込んでテクスチャID取得」(StartXFileTexとEndXFileTexを実行したのと同等) //[ SetupXFileTexData tid, dfname, pfname ] // tid : テクスチャ画像読み込みが成功したときにテクスチャIDが入る変数「失敗時は-1が入る」 // dfname : 読み込む登録テクスチャ画像情報のファイル名 // pfname : 読み込む登録テクスチャ画像のファイル名 //戻り値:ファイルが無かった場合statに-1が返る #deffunc SetupXFileTexData var tid,str dfname,str pfname loadxfiletexdata dfname, pfname,1 if stat<0 {tid=-1:return -1} tid=stat tex_id=tid EndXFileTex_f=1 hggetreq filter,SYSREQ_3DFILTER RateUVI=RateUV //右下側の変換する倍率 RateUVI-=RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 MarginUV=(RateUV*(filter>1)/divsize)/2 //テクスチャ補間モードが有効の場合隣のドットを巻き込むのを軽減 RateUVI-=MarginUV*2 return 0 *sub_startxfiletex xtxt_id=0 hggetreq MAXMODEL,SYSREQ_MAXMODEL dim tfcnt_list,MAXMODEL memset tfcnt_list,-1,MAXMODEL*4 if diflit=0 { set_Diffused_light="0.8;0.8;0.8;;"} mdsize=1.0,1.0,1.0,1.0 dup dup_mdsizex,mdsize dup dup_mdsizey,mdsize(1) dup dup_mdsizez,mdsize(2) sdim settf_list,64,100 return ////「モデルの拡散光設定」 //[ SetXFileDiffusedLight afdl, difr, difg, difb ] // afdl : 設定を有効にするかどうか「0=無効、1=有効」 // difr : 拡散光赤「整数で指定255で1.0(初期値は204で0.8)になり上限ではない」 // difg : 拡散光緑 // difb : 拡散光青 #deffunc SetXFileDiffusedLight int afdl,int difr,int difg,int difb if afdl=1 {diflit=1:set_Diffused_light=strf("%.3f;%.3f;%.3f;;",1.0*difr/255, 1.0*difg/255, 1.0*difb/255)}else{diflit=0} return ////「テクスチャ画像を登録するバッファの背景色を指定」(背景色を変えても登録される画像には影響しない) //[ SetTexBGcolor tbr, tbg, tbb ] // tbr : 背景色赤 // tbg : 背景色緑 // tbb : 背景色青 //補足 : startxfiletexより前に指定する必要がある #deffunc SetTexBGcolor int tbr,int tbg,int tbb _tbr=tbr:_tbg=tbg:_tbb=tbb return ////「addxfiletexの変数バージョン」 //[ addXFileTexVar mid, xfile, xftopt, settf ] //xfileにファイルネームじゃなくx形式のテキストが入ってる変数を指定 //他はaddxfileTexと同じ #define global addXFileTexVar(%1,%2,%3=0,%4="") _addxfileTex %1,"",%3,%4,%2,1 ////「xfileから画像ファイル名を切り取り画像を順番にテクスチャ用バッファに並べてコピーしてUV座標を書き換えモデルを作成します」 //[ addXFileTex mid, fname, xftopt, settf ] // mid : 作成されたモデルIDが代入される変数名 // fname : 読み込みを行なうファイル名 // xftopt : ズームのモード等のオプション「1=拡縮時にハーフトーンを使う、2=SetMaterialSizeExtraで設定したサイズを使用、4=マイナスUV値に対応(画像は右下に4枚田の様に置かれる)、8=-U値を反転、16=-V値を反転、32=画像を読み込まない、64=行の//以降をコメントとして削除、128=サイズ計算(結果は変数XMD_SIZEX,XMD_SIZEY,XMD_SIZEZで取得)、256=全ての処理を行いモデルは作らない、512=何も処理せずモデルを作りテクスチャ使用フラグを立てる」 // settf : 差し替えるテクスチャファイル(省略時"")「fnameで指定したファイル内で使用されてるテクスチャファイル名を差し替えます。\nで区切り複数差し替え可能」 //戻り値 : statにテクスチャを使用してるマテリアル数が返る(無ければ0、モデル作成に失敗すれば-1) // 登録されたテクスチャ画像インデックスはGetTexDivid()で取得できる(合わせて座標は値はGetTexPosX()で取得可能) //補足1:xftoptに128が指定されてるとgetfvmin_model、getfvmax_model、getScaleFactor_model命令が利用できる //補足2:xftoptに512が指定された場合は、128以外の設定は無視されます。 //補足3:テクスチャファイル差し替え時は面の順番では無くTextureFilenameが設定してあるMaterialの順番になります。なのでTextureFilenameが無いMaterialは指定出来ません。 //補足4:テクスチャファイル名には特殊名があり "buffer.10" と指定するとウィンドウバッファID10の内容をテクスチャに登録します。 //補足5:IDの後にピリオドで区切り数値を指定すると別のバッファIDとして登録されます。("buffer.10.0"と"buffer.10.1"はID10を使った別画像として登録される) //補足6:更にコンマで区切り画像の左上座標とサイズを指定できる 例 "buffer.10,0,0,32,32" 指定する場合は必ずサイズまで指定してください #define global addXFileTex(%1,%2,%3=0,%4="") _addXFileTex %1,%2,%3,%4,temp_xfile@mod_addxfileTex #deffunc _addXFileTex var mid,str fname,int xftopt,str settf,var xfile,int texvar_f gsel_bak=ginfo_sel if texsize=0 {startXFileTex }else{if EndXFileTex_f=0{gsel XFILETEX_BUFFER_ID}} if xftopt&512 { if (xftopt&128){ if texvar_f=0 { notesel xof0302txt noteload fname noteunsel }else{ txtsize=strlen(xfile) sdim xof0302txt,txtsize+1 memcpy xof0302txt,xfile,txtsize } cr_code="\n" index=instr(xof0302txt,0,"}") if index>0 { temp_str=strmid(xof0302txt,0,index) if instr(temp_str,0,cr_code)<0 {wpoke cr_code,0,$A} } Total_Mesh_index=0 if TemplateSearch(Meshmax_str,xof0302txt,Total_Mesh_index,"Mesh ","1",";")<0 {mid=-1: return -1} Mesh_index=stat strrep Meshmax_str,cr_code,"" //改行削除 data_index=instr(xof0302txt,Total_Mesh_index,";;")+2 gosub *_getminmax } if texvar_f=0 {addxfile mid, fname}else{memfile xfile:addxfile mid, "MEM:xfile.x"} gsel gsel_bak if mid<0 {return -1}else{ regobj@hsp temp_id,mid getxinfo nmt,temp_id,-1,16 split nmt,"\n",matl _cnt=-1 repeat stat if (0+matl(cnt))>0 {tfcnt_list(mid)=cnt:break} loop delobj temp_id if tfcnt_list(mid)<0 {return 0}else{return (0+matl(tfcnt_list(mid)))} } } ploadf=(xftopt&32) | EndXFileTex_f zoomf=xftopt&1 if settf ! "" { _settf=settf split _settf,"\n",settf_list settf_max=stat }else{ settf_max=0 } if texvar_f=0 { notesel xof0302txt noteload fname noteunsel _fname=fname if instr(_fname,0,":")<0 {txtsize=strsize}else{txtsize=strlen(xof0302txt)} }else{ txtsize=strlen(xfile) if varptr(xof0302txt)!varptr(xfile){ sdim xof0302txt,txtsize+1 memcpy xof0302txt,xfile,txtsize } } cr_code="\n" index=instr(xof0302txt,0,"}") if index>0 { temp_str=strmid(xof0302txt,0,index) if instr(temp_str,0,cr_code)<0 {wpoke cr_code,0,$A} }else{return -1} if xftopt&64 { //コメント削除 repeat com_index=instr(xof0302txt,0,"//") if com_index<0{break} instr_index=instr(xof0302txt,com_index,cr_code) if instr_index<0{instr_index=txtsize-com_index} memcpy xof0302txt,xof0302txt,txtsize-(com_index+instr_index)+1,com_index,com_index+instr_index txtsize=strlen(xof0302txt) loop } memexpand xof0302txt,txtsize*2 Total_index=instr(xof0302txt,0,"template MeshMaterialList") if Total_index<0 {Total_index=0}else{Total_index+25} if TemplateSearch(mmlist_str,xof0302txt,Total_index,"MeshMaterialList","<","Material ",2)<0 { gsel gsel_bak memfile xof0302txt if xftopt&256 {return 0}else{addxfile mid, "MEM:xfile.x"} if mid<0 {return -1}else{return 0} } MeshMaterialList_index=stat+18 strrep mmlist_str,cr_code,"" //改行削除 split mmlist_str,";",mmmax_str,mmlmax_str,mml_str mmmax=int(mmmax_str) split mml_str,",",MeshMaterialList_str mml_str="1;"+mmlmax_str+";" repeat int(mmlmax_str) MeshMaterialList(cnt)=0+MeshMaterialList_str(cnt) mml_str+"0," loop mml_str+";" poke mml_str,strlen(mml_str)-2,';' mmlstrsize=strlen(mml_str) memcpy xof0302txt,xof0302txt,txtsize-Total_index+1,MeshMaterialList_index+mmlstrsize,Total_index memcpy xof0302txt,mml_str,mmlstrsize,MeshMaterialList_index,0 txtsize=MeshMaterialList_index+mmlstrsize+txtsize-Total_index tfcnt=0 Total_index=0 Total_Mesh_index=0 matno=0 Reverse_uv=(xftopt&4)>0 if (xftopt&24) { if xftopt&8 {MinusU=1.0}else{MinusU=0.0} if xftopt&16 {MinusV=1.0}else{MinusV=0.0} }else{ MinusU=0.0 MinusV=0.0 } if (xftopt&2) or Reverse_uv{ if Reverse_uv{ if (xftopt&2){_matsize_ex=matsize_ex}else{_matsize_ex=divsize} _matsize_exv=_matsize_ex*2.0 }else{ Reverse_uv=2 _matsize_ex=matsize_ex _matsize_exv=matsize_ex } if _matsize_exv>add_ofsv {add_ofsv=0+_matsize_exv} mat_size=0+_matsize_ex _RateUVI=RateUV*(_matsize_ex/divsize) _RateUVI-=_RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 _MarginUV=(RateUV*(filter>1)/divsize)/2 //テクスチャ補間モードが有効の場合隣のドットを巻き込むのを軽減 _RateUVI-=_MarginUV*2 }else{ mat_size=0+divsize _RateUVI=RateUVI _MarginUV=MarginUV } repeat if TemplateSearch(mtdat_str,xof0302txt,Total_index,"Material ","<","}",1)<0 { break} start_index=stat mate_name=strmid(xof0302txt,start_index,instr(xof0302txt,start_index,"{")+1) if matno=0 { if diflit=0 { Diffused_light=mate_name+strmid(mtdat_str,0,instr(mtdat_str,0,";;")+2) }else{ Diffused_light=mate_name+set_Diffused_light } } data_size_index=0 tfn=0 if TemplateSearch(tfname,mtdat_str,data_size_index,"TextureFilename","<","}")>0 { data_size_index-stat index_s=instr(tfname,0,"\"") if index_s>=0 { if matno<settf_max { if settf_list(matno)!"" { tf_name=settf_list(matno) if instr( tf_name,0,".")>=0 { if instr(tf_name,0,"\"")<0{ tfname="\""+tf_name+"\"" }else{ tfname=tf_name } index_s=0 } } } tfname=getpath(strmid(tfname,index_s,instr(tfname,index_s+1,"\"")+2),16)+(xftopt&31) tf_i=instr(tfname_list,0,tfname) if tf_i<0 { tfname_index(strlen(tfname_list))=texdiv_index texdivid_list(matno)=texdiv_index if Reverse_uv { if Reverse_uv=1{ _Reverse_posu=Reverse_posu-_matsize_ex if _Reverse_posu<_matsize_ex { Reverse_posu=0.0+texsize _Reverse_posu=Reverse_posu-_matsize_ex Reverse_posv-add_ofsv add_ofsv=0+_matsize_exv } Reverse_posu-_matsize_exv texpos_u(texdiv_index)=RateUV*(_Reverse_posu/divsize) texpos_v(texdiv_index)=RateUV*((Reverse_posv-_matsize_ex)/divsize) }else{ _Reverse_posu=Reverse_posu-_matsize_ex if _Reverse_posu<_matsize_ex{ Reverse_posu=0.0+texsize _Reverse_posu=Reverse_posu-_matsize_ex Reverse_posv-add_ofsv add_ofsv=0+_matsize_exv } Reverse_posu-_matsize_exv texpos_u(texdiv_index)=RateUV*(_Reverse_posu/divsize) texpos_v(texdiv_index)=RateUV*((Reverse_posv-_matsize_exv)/divsize) } }else{ texpos_u(texdiv_index)=RateUV*(uvofsindex\divmax) texpos_v(texdiv_index)=RateUV*(uvofsindex/divmax) uvofsindex++ } tfname_list+tfname if ploadf=0 { if instr(tfname,0,"buffer.")=1 { if instr(tfname,0,",")<0 { getstr buf_id_str,tfname,8,'\"',2 lux=0 luy=0 buf_id=0+buf_id_str mref BMSCR,96+buf_id }else{ dim BMSCR,3 split tfname,",",bid_str,lux_str,luy_str,sx_str,sy_str getstr buf_id_str,bid_str,8,'""',2 lux=0+lux_str luy=0+luy_str buf_id=0+buf_id_str BMSCR(1)=0+sx_str BMSCR(2)=0+sy_str } }else{ buf_id=3 celload strmid(tfname,1,instr(tfname,1,"\"")),3 mref BMSCR,96+buf_id lux=0 luy=0 } gmode 0,BMSCR(1),BMSCR(2) pos texpos_u(texdiv_index)/ruvsize,texpos_v(texdiv_index)/ruvsize gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf if Reverse_uv=1 { pos ginfo_cx-mat_size,ginfo_cy gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf pos ginfo_cx,ginfo_cy-mat_size gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf pos ginfo_cx+mat_size,ginfo_cy gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf } } RateUVIlist(texdiv_index)=_RateUVI texdiv_index++ }else{ texdivid_list(matno)=tfname_index(tf_i) } mattf_list(tfcnt)=matno tfcnt++ mattf_f(matno)=1 }else{ Total_index-1 mattf_f(matno)=0 } }else{ Total_index-1 mattf_f(matno)=0 } if matno=0 {matsize=strlen(Diffused_light)}else{matsize=0:Total_index+instr(xof0302txt,Total_index,"}")+1} memcpy xof0302txt,xof0302txt,txtsize-Total_index+1,start_index+matsize,Total_index if matno=0 {memcpy xof0302txt,Diffused_light,matsize,start_index,0} txtsize=start_index+matsize+txtsize-Total_index Total_index=start_index+matsize matno++ loop Total_Mesh_index=0 if TemplateSearch(Meshmax_str,xof0302txt,Total_Mesh_index,"Mesh ","1",";")<0 {mid=-1: return -1} Mesh_index=stat strrep Meshmax_str,cr_code,"" //改行削除 data_index=instr(xof0302txt,Total_Mesh_index,";;")+2 if (xftopt&128){ gosub *_getminmax} Total_index=Total_Mesh_index+data_index add_index=instr(xof0302txt,Total_index,";") mvimax_str=strmid(xof0302txt,Total_index,add_index ) //頂点インデック総数 Total_index+add_index+1 strrep mvimax_str,cr_code,"" //改行削除 mvilist_str=strmid(xof0302txt,Total_index,instr(xof0302txt,Total_index,";;") ) //頂点インデックスリスト strrep mvilist_str,cr_code,"" //改行削除 strrep mvilist_str,";,",";" //コンマ削除 split mvilist_str,";",mvilist_str if tfcnt { Total_index=0 if TemplateSearch(mtclist_str,xof0302txt,Total_index,"MeshTextureCoords {","<",";;")<0 { gsel gsel_bak memfile xof0302txt if xftopt&256 {return 0}else{addxfile mid, "MEM:xfile.x"} if mid<0 {return -1}else{return 0} } mtclist_start=stat+19+instr(mtclist_str,0,";")+1 mtclist_end=Total_index strrep mtclist_str,cr_code,"" //改行削除 strrep mtclist_str," ","" //スペース削除 strrep mtclist_str," ","" //タブ削除 strrep mtclist_str,",","" //コンマ削除 add_index=instr(mtclist_str,0,";") mtcmax=0+strmid(mtclist_str,0,add_index ) memexpand xof0302txt,txtsize+mtcmax*40 dupptr mtclist_str_dup,varptr(mtclist_str)+add_index+1,4*50,2 sdim uvlist_str,,mtcmax*2 split mtclist_str_dup,";",uvlist_str sdim uvlist_str2,,mtcmax dim mvitfon_f,int(mvimax_str) cr_str=";,"+cr_code mvi_cnt=0 repeat int(mvimax_str) split mvilist_str(mvi_cnt+1),",",mv3 if mattf_f(MeshMaterialList(cnt)) { tdi=texdivid_list(MeshMaterialList(cnt)) tdiv_u=texpos_u(tdi)+MinusU*_RateUVI+_MarginUV tdiv_v=texpos_v(tdi)+MinusV*_RateUVI+_MarginUV repeat 0+mvilist_str(mvi_cnt) uv_i=0+mv3(cnt) uvlist_str2(uv_i)=""+(tdiv_u+_RateUVI*uvlist_str(uv_i*2))+";"+(tdiv_v+_RateUVI*uvlist_str(uv_i*2+1))+cr_str loop }else{ repeat 0+mvilist_str(mvi_cnt) uv_i=0+mv3(cnt) uvlist_str2(uv_i)=uvlist_str(uv_i*2)+";"+uvlist_str(uv_i*2+1)+cr_str loop } mvi_cnt+2 loop sdim temp_xof0302txt,txtsize-mtclist_end+100 memcpy temp_xof0302txt,xof0302txt,txtsize-mtclist_end,0,mtclist_end dupptr uvlist_dup,varptr(xof0302txt)+mtclist_start,mtcmax*50,2 uvdefstr="0.0;0.0"+cr_str uvdefstr_s=strlen(uvdefstr)+1 repeat mtcmax if peek(uvlist_str2(cnt),0)=0 {memcpy uvlist_str2(cnt),uvdefstr,uvdefstr_s,0} loop cpy_index=0 strrep uvlist_str2(mtcmax-1),";,",";;" repeat mtcmax cpysize=strlen(uvlist_str2(cnt)) memcpy uvlist_dup,uvlist_str2(cnt),cpysize,cpy_index cpy_index+cpysize loop memcpy xof0302txt,temp_xof0302txt,txtsize-mtclist_end+1,mtclist_start+cpy_index } gsel gsel_bak memfile xof0302txt if xftopt&256 {return tfcnt}else{addxfile mid, "MEM:xfile.x"} if mid<0 {return -1} if tfcnt { //ノード数とマテリアル数を取得 regobj@hsp temp_id,mid getxinfo nmt,temp_id,-1,16 split nmt,"\n",matl repeat stat if (0+matl(cnt))>0 {tfcnt_list(mid)=cnt:break} loop delobj temp_id }else{ tfcnt_list(mid)=-1 } return tfcnt *_getminmax mesh_vec_str=strmid(xof0302txt,Total_Mesh_index,data_index-2 ) strrep mesh_vec_str,cr_code,"" //改行削除 fvset mvmin,10000.0,10000.0,10000.0 fvset mvmax,-10000.0,-10000.0,-10000.0 split mesh_vec_str,";,",mesh_vec_str vecxyz=0.0 vecxyz(3*Meshmax_str)=0.0 //文字列の座標を実数にして保存する配列 repeat 0+Meshmax_str split mesh_vec_str(cnt),";",mvx_str,mvy_str,mvz_str dup dup_vecxyz,vecxyz(cnt*3) dup_vecxyz=0.0+mvx_str,0.0+mvy_str,0.0+mvz_str fvmin mvmax,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) fvmax mvmin,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) loop fvset mdsize,mvmax,mvmax(1),mvmax(2) fvsub mdsize,mvmin,mvmin(1),mvmin(2) return ////「テクスチャに使用する画像を登録しインデックスをリストにして取得」 //[ addTexPic texidlist, settf, tf_max, atpopt ] // texidlist : 登録されたテクスチャインデックスを受け取る配列「指定ファイル名にピリオドが無い物は画像ファイル意外と判断し-1が入ります」 // settf : 登録するテクスチャ画像を入れた文字列配列「既に登録されてたり同じ画像が複数指定してる場合登録せずにインデックスを取得します」 // tf_max : 登録する画像の数 // atpopt : ズームのモード等のオプション「1=拡縮時にハーフトーンを使う、2=SetMaterialSizeExtraで設定したサイズを使用、4=マイナスUV値に対応(画像は右下に4枚田の様に置かれる)、8=-U値を反転、16=-V値を反転、32=画像を読み込まない」 //戻り値:statにインデックス取得に成功した数が返る(tf_maxの数と違った場合ファイル名以外が混じってた) //補足1:テクスチャファイル名には特殊名があり "buffer.10" と指定するとウィンドウバッファID10の内容をテクスチャに登録します。 //補足2:bufferで指定できるIDは0〜99までの二桁です。 //補足3:IDの後にピリオドで区切り数値を指定すると別のバッファとして登録されます。("buffer.10.0"と"buffer.10.1"はID10を使った別画像として登録される) //補足4:更にコンマで区切り画像の左上座標とサイズを指定できる 例 "buffer.10,0,0,32,32" 指定する場合は必ずサイズまで指定してください #deffunc addTexPic array texidlist,array settf,int tf_max,int atpopt gsel_bak=ginfo_sel if texsize=0 {startXFileTex}else{gsel XFILETEX_BUFFER_ID} zoomf=atpopt&1 index_s=0 settexcnt=0 Reverse_uv=(atpopt&4)>0 ploadf=(atpopt&32) | EndXFileTex_f if (atpopt&24) { if atpopt&8 {MinusU=1.0}else{MinusU=0.0} if atpopt&16 {MinusV=1.0}else{MinusV=0.0} }else{ MinusU=0.0 MinusV=0.0 } if (atpopt&2) or Reverse_uv{ if Reverse_uv{ if (atpopt&2){_matsize_ex=matsize_ex}else{_matsize_ex=divsize} _matsize_exv=_matsize_ex*2.0 }else{ Reverse_uv=2 _matsize_ex=matsize_ex _matsize_exv=matsize_ex } if _matsize_exv>add_ofsv {add_ofsv=0+_matsize_exv} mat_size=0+_matsize_ex _RateUVI=RateUV*(_matsize_ex/divsize) _RateUVI-=_RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 _MarginUV=(RateUV*(filter>1)/divsize)/2 //テクスチャ補間モードが有効の場合隣のドットを巻き込むのを軽減 _RateUVI-=_MarginUV*2 }else{ mat_size=0+divsize _RateUVI=RateUVI _MarginUV=MarginUV } repeat tf_max tfname=settf(cnt) if instr( tfname,0,".")>0{ if instr(tfname,0,"\"")<0{tfname="\""+tfname+"\""} tfname=getpath(strmid(tfname,0,instr(tfname,1,"\"")+2),16)+(atpopt&31) tf_i=instr(tfname_list,0,tfname) if tf_i<0 { tfname_index(strlen(tfname_list))=texdiv_index texidlist(cnt)=texdiv_index tfname_list+tfname if Reverse_uv { if Reverse_uv=1{ _Reverse_posu=Reverse_posu-_matsize_ex if _Reverse_posu<_matsize_ex { Reverse_posu=0.0+texsize _Reverse_posu=Reverse_posu-_matsize_ex Reverse_posv-add_ofsv add_ofsv=0+_matsize_exv } Reverse_posu-_matsize_exv texpos_u(texdiv_index)=RateUV*(_Reverse_posu/divsize) texpos_v(texdiv_index)=RateUV*((Reverse_posv-_matsize_ex)/divsize) }else{ _Reverse_posu=Reverse_posu-_matsize_ex if _Reverse_posu<0.0 { Reverse_posu=0.0+texsize _Reverse_posu=Reverse_posu-_matsize_ex Reverse_posv-add_ofsv add_ofsv=0+_matsize_exv } Reverse_posu-_matsize_exv texpos_u(texdiv_index)=RateUV*(_Reverse_posu/divsize) texpos_v(texdiv_index)=RateUV*((Reverse_posv-_matsize_exv)/divsize) } }else{ texpos_u(texdiv_index)=RateUV*(uvofsindex\divmax) texpos_v(texdiv_index)=RateUV*(uvofsindex/divmax) uvofsindex++ } RateUVIlist(texdiv_index)=_RateUVI if ploadf=0 { if instr(tfname,0,"buffer.")=1 { if instr(tfname,0,",")<0 { getstr buf_id_str,tfname,8,'\"',2 lux=0 luy=0 buf_id=0+buf_id_str mref BMSCR,96+buf_id }else{ dim BMSCR,3 split tfname,",",bid_str,lux_str,luy_str,sx_str,sy_str getstr buf_id_str,bid_str,8,'""',2 lux=0+lux_str luy=0+luy_str buf_id=0+buf_id_str BMSCR(1)=0+sx_str BMSCR(2)=0+sy_str } }else{ buf_id=3 celload strmid(tfname,1,instr(tfname,1,"\"")),3 mref BMSCR,96+buf_id lux=0 luy=0 } gmode 0,BMSCR(1),BMSCR(2) pos texpos_u(texdiv_index)/ruvsize,texpos_v(texdiv_index)/ruvsize gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf if Reverse_uv=1 { pos ginfo_cx-mat_size,ginfo_cy gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf pos ginfo_cx,ginfo_cy-mat_size gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf pos ginfo_cx+mat_size,ginfo_cy gzoom mat_size,mat_size,buf_id,lux,luy,,,zoomf } } texdiv_index++ }else{ texidlist(cnt)=tfname_index(tf_i) } settexcnt++ }else{ texidlist(cnt)=-1 } loop gsel gsel_bak return settexcnt ////「箱型のX形式モデルテキストデータを作成」(makexfilePLATEとはテクスチャファイル名の指定方法が違います。) //[ MakeXFileBox Meshxbox, texname, texMaxsize, sx, sy, sz ] // Meshxbox : 作られた箱のX形式のモデルデータを取得する文字列型変数 // texname : 使用するテクスチャファイル名。面の順番は上、下、前、後、左、右「\nで区切り面別に指定可能(画像ファイル名は「 .」ピリオドが有るか無いかで判断してます)、 Delete と書くと面を削除」 // texMaxsize : テクスチャ最大サイズ(省略時1.0)「モデルサイズ以下にすると画像がぴったりはられて、大きいと必要部分がはられる」 // msx : モデルのXサイズ(省略時texMaxsizeと同じになる) // msy : モデルのYサイズ(省略時texMaxsizeと同じになる) // msz : モデルのZサイズ(省略時texMaxsizeと同じになる) //補足1:面の向きはモデル中心から見たZプラス方向を向いた時の面方向 //補足2:テクスチャファイルは設定面以降も使われます。"A.bmp\n\nB.bmp" と指定した場合上下面がA、側面全てがBになります。 //補足3:上の例でaddxfiletexvar命令使用時にテクスチャファイルの差し替えしたい場合は、"C.bmp\nD.bmp" と指定すれば上下面がC、側面全てがDになります。 //補足4:差し替え時は面の順番では無くテクスチャファイルを直接設定した順番になります。なので直接設定されて無い面を指定は出来ません。 //補足5:モデルには拡散光が設定されます。デフォルトは204(実際のデータ上は0.8)ですが、SetXFileDiffusedLight命令で変更できます。 #define global MakeXFileBox(%1,%2,%3=1.0,%4=1234567.0,%5=1234567.0,%6=1234567.0) _makexfilebox %1,%2,%3,%4,%5,%6 #deffunc _makexfilebox var Meshxbox,str texname,double texMaxsize,double msx,double msy,double msz if msx=1234567.0 {msx_=texMaxsize}else{msx_=msx} if msy=1234567.0 {msy_=texMaxsize}else{msy_=msy} if msz=1234567.0 {msz_=texMaxsize}else{msz_=msz} Meshon_cnt=6 dim Meshoff_f,Meshon_cnt _settf=texname split _settf,"\n",settf_list settf_max=limit(stat,0,Meshon_cnt) repeat settf_max if settf_list(cnt)="Delete" { Meshoff_f(cnt)=-1 Meshon_cnt-- } loop if vartype(box_Vertex)=4 { box_Vertex= -0.5,0.5,-0.5, -0.5,0.5,0.5,0.5,0.5,0.5, 0.5,0.5,-0.5 box_Vertex(12)= -0.5,-0.5,0.5 ,-0.5,-0.5,-0.5, 0.5,-0.5,-0.5, 0.5,-0.5,0.5 box_Vertex(24)= -0.5,0.5,0.5, -0.5,-0.5,0.5, 0.5,-0.5,0.5 ,0.5,0.5,0.5 box_Vertex(36)= 0.5,0.5,-0.5, 0.5,-0.5,-0.5, -0.5,-0.5,-0.5, -0.5,0.5,-0.5 box_Vertex(60)= 0.5,0.5,0.5, 0.5,-0.5,0.5, 0.5,-0.5,-0.5, 0.5,0.5,-0.5 box_Vertex(48)= -0.5,0.5,-0.5, -0.5,-0.5,-0.5, -0.5,-0.5,0.5 ,-0.5,0.5,0.5 xbox_mn_str="0.0;1.0;0.0;,", "0.0;-1.0;0.0;,", "0.0;0.0;1.0;,","0.0;0.0;-1.0;,","-1.0;0.0;0.0;,","1.0;0.0;0.0;," xbox_mnno_str="4;0,0,0,0;,", "4;1,1,1,1;,", "4;2,2,2,2;,","4;3,3,3,3;,","4;4,4,4,4;,","4;5,5,5,5;," repeat 6 xbox_vindex(cnt)="4;"+cnt*4+","+(cnt*4+1)+","+(cnt*4+2)+","+(cnt*4+3)+";," loop sdim Meshxbox,10240 } MeshNormals_templ=" MeshNormals {\n"+Meshon_cnt+";" MeshNormals_no=""+Meshon_cnt+";" Mesh_index=0 xbox_vindex_str=""+Meshon_cnt+";\n" repeat 6 if Meshoff_f(cnt) = 0 { xbox_vindex_str+xbox_vindex(cnt)+"\n" MeshNormals_templ+xbox_mn_str(cnt)+"\n" MeshNormals_no+xbox_mnno_str(Mesh_index)+"\n" Mesh_index++ } loop poke xbox_vindex_str,strlen(xbox_vindex_str)-3,';' poke MeshNormals_templ,strlen(MeshNormals_templ)-3,';' poke MeshNormals_no,strlen(MeshNormals_no)-3,';' MeshNormals_templ+MeshNormals_no+"}" size_Change=(msx_ ! msx_bak) or (msy_ ! msy_bak) or (msz_ ! msz_bak) if size_Change or (texMaxsize ! texMaxsize_bak) { if size_Change { xbox_Mesh="xof 0302txt 0064 \n Mesh {\n 24;\n" vcnt=0 repeat 24 dup dup_box_Vertex,box_Vertex(vcnt) xbox_Mesh+=""+(dup_box_Vertex*msx_)+";"+(dup_box_Vertex(1)*msy_)+";"+(dup_box_Vertex(2)*msz_)+";,\n" vcnt+3 loop poke xbox_Mesh,strlen(xbox_Mesh)-3,';' msx_bak=msx_ msy_bak=msy_ msz_bak=msz_ } texMaxsize_bak=texMaxsize bmsx=limitf(msx_/texMaxsize,0.0,1.0) bmsy=limitf(msy_/texMaxsize,0.0,1.0) bmsz=limitf(msz_/texMaxsize,0.0,1.0) mtc_u=0.0,0.0, bmsx,bmsx, 0.0,0.0, bmsx,bmsx, 0.0,0.0, bmsx,bmsx, 0.0,0.0, bmsx,bmsx, 0.0,0.0, bmsz,bmsz, 0.0,0.0, bmsz,bmsz mtc_v=0.0,bmsz, bmsz,0.0, 0.0,bmsz, bmsz,0.0, 0.0,bmsy, bmsy,0.0, 0.0,bmsy, bmsy,0.0, 0.0,bmsy, bmsy,0.0, 0.0,bmsy, bmsy,0.0 mtexc="\n MeshTextureCoords {\n 24;\n" repeat 24 mtexc+=""+mtc_u(cnt)+";"+mtc_v(cnt)+";," loop poke mtexc,strlen(mtexc)-1,';' } Meshxbox=xbox_Mesh Meshxbox+xbox_vindex_str+"MeshMaterialList {" if diflit=0 {Diffused_light="Material {0.8;0.8;0.8;;"}else{Diffused_light="Material {"+set_Diffused_light} xbox_mmlnoist="" mat_list="" mat_no=0 _mat_no=0 tfname="" repeat 6 if Meshoff_f(cnt)=0 { if cnt<settf_max { if instr( settf_list(cnt),0,".")>=0 { tfname="TextureFilename {\""+settf_list(cnt)+"\";}" _mat_no=mat_no mat_no++ mat_list+Diffused_light+tfname+"}\n" } } xbox_mmlnoist+=""+_mat_no+"," } loop xbox_mmlnoist+";\n" poke xbox_mmlnoist,strlen(xbox_mmlnoist)-4,';' if mat_no=0 { Meshxbox+=""+1+";"+Meshon_cnt+";"+xbox_mmlnoist+Diffused_light+"}}\n"+MeshNormals_templ }else{ Meshxbox+=""+mat_no+";"+Meshon_cnt+";"+xbox_mmlnoist+mat_list+"}\n"+MeshNormals_templ } Meshxbox+mtexc+"}}" return ///////↓↓↓PlateDirTex、PlateDirUVFlip、PlateHorVerAngの3命令はMakeXFilePlate用の設定を行います。↓↓↓//////////// ////「面の向き毎に使用するテクスチャを設定する」(6面を超えると面倒になるので) //[ PlateDirTex pdtsetf, toptex, Undertex, Fronttex, backtex, Lefttex, Rightex ] // pdtsetf : 設定を有効にするか(省略時0)「0=無効、1=テクスチャファイル名有効、2=テクスチャインデックス有効」 // toptex : 上の面のテクスチャ画像(モデル中心からZプラス方向を向いた時の面方向) // Undertex : 下の面のテクスチャ画像 // Fronttex : 前の面のテクスチャ画像 // backtex : 後ろ面のテクスチャ画像 // Lefttex : 左の面のテクスチャ画像 // Rightex : 右の面のテクスチャ画像 //補足1:テクスチャ画像はファイル名かテクスチャインデックスを指定できます(混合指定は出来ません) #define global PlateDirTex(%1=0,%2="",%3="",%4="",%5="",%6="",%7="") _PlateDirTex %1,""+(%2),""+(%3),""+(%4),""+(%5),""+(%6),""+(%7) #deffunc _PlateDirTex int pdtsetf,str toptex,str Undertex,str Fronttex,str backtex,str Lefttex,str Rightex pdtflist=toptex, Undertex, Fronttex, backtex, Lefttex, Rightex pdtset_f=0 if pdtsetf { repeat 6 pdtf_f(cnt)=(pdtflist(cnt)!"") loop }else{ dim pdtf_f,6 } pdtset_f=pdtsetf return ////「面の向き毎にテクチャUV値の回転反転、面の反転、両面化を設定する」(6面を超えると面倒になるので) //[ PlateDirUVFlip pduvfsetf, topuvf, Underuvf, Frontuvf, backuvf, Leftuvf, Righuvf ] // pduvfsetf : 設定を有効にするか(省略時0)「0=無効、1=有効」 // topuvf : 上の面UV値の回転反転、面の反転設定「0=通常、1=UV右90度回転、2=UV180度回転、3=UV左90度回転、4=U反転、5=V反転、6=UV反転、8=面の反転(1〜6と一緒に指定可能)、256=円筒マッピング(他の設定と同時使用可)」 // Underuvf : 下の面UV値の回転反転、面の反転設定 // Frontuvf : 前の面UV値の回転反転、面の反転設定 // backuvf : 後ろ面UV値の回転反転、面の反転設定 // Leftuvf : 左の面UV値の回転反転、面の反転設定 // Righuvf : 右の面UV値の回転反転、面の反転設定 //補足:面の方向はモデル座標でYプラスが上、Xプラスが左、Zプラスが前になります。 #define global PlateDirUVFlip(%1=0,%2=-1,%3=-1,%4=-1,%5=-1,%6=-1,%7=-1) _PlateDirUVFlip %1,%2,%3,%4,%5,%6,%7 #deffunc _PlateDirUVFlip int pduvfsetf,int topuvf,int Underuvf,int Frontuvf,int backuvf,int Leftuvf,int Righuvf pduvflist=topuvf, Underuvf, Frontuvf, backuvf, Leftuvf, Righuvf if pduvfsetf{ repeat 6 pduvf_f(cnt)=pduvflist(cnt)>=0 loop }else{ dim pduvf_f,6 } pduvfset_f=pduvfsetf return ////「面が水平、垂直か判断する角度を調整」(座標をUV値にする時XYZどの軸を選択するかが変わる) //[ PlateHorVerAng hvaf, hvaxz, hvay ] // hvaf : 設定を有効にするか(省略時0)「0=無効、1=有効」 // hvaxz : 左右前後の垂直面と判断する範囲を調整(省略時0.5)「通常45度以下が前後の面として処理される,0.2を指定すると左右面の範囲が広がる」 // hvay : 水平面と判断する角度を調整(省略時0.5)「0.0(0度)を水平とした時に0.5で45度までの傾きが水平面として処理」 //補足:通常水平面はXZ座標をUVに利用して、垂直面はYZかYXを利用します。 #define global PlateHorVerAng(%1=0,%2=0.5,%3=0.5) _PlateHorVerAng %1,%2,%3 #deffunc _PlateHorVerAng int hvaf,double hvaxz,double hvay hvalist=0.5-hvaxz,sin(M_PI*0.5*(1.0-hvay)),hvaxz-0.5 hvafset_f=hvaf return ///////↑↑↑PlateDirTex、PlateDirUVFlip、PlateHorVerAngの3命令はMakeXFilePlate用の設定を行います。↑↑↑//////////// ////「板を組み合わせてX形式のモデルテキストデータを作成」(makexfileBOXとはテクスチャファイル名の指定方法が違います。) //[ MakeXFilePlate MeshxPlate, Vertexlist, tflist, boxsize, sx, sy, sz ] // MeshxPlate : 作られたX形式のモデルデータを取得する文字列型変数 // Vertexlist : 板の頂点データの入った実数型の1次元配列「XYZで3要素、4頂点で4要素なので一枚の板で要素12個必要、基本的に面を正面にして左上から左回りが表、左上から右回りが裏面で、プラス側が右上手前になる」 // Platemax : 板の数 // tflist : 使用するテクスチャファイル名が入ってる文字列形配列「配列で複数指定できます。画像ファイル名は「.」ピリオドが有るか無いかで判断」 // UVFliplist : UV値の回転反転、面の反転指定をリストにした配列「0=通常、1=UV右90度回転、2=UV180度回転、3=UV左90度回転、4=U反転、5=V反転、6=UV反転、8=面の反転(UV反転なし)、32=両面化、256=円筒マッピング」(1〜6と8,32,256を組み合わせて複数設定可能) // mattexRange : マテリアルテクスチャ範囲(省略時1.0)「頂点間をmattexRangeで区切ってUV値が設定されます(0.0〜mattexRangeまでがUV0.0〜1.0になる)板1枚の最大サイズと考えてもいい」 // mcx : モデルの中心X(省略時0.5)「中心が0.0になるようにVertexlistを移動します」 // mcy : モデルの中心Y(省略時0.5) // mcz : モデルの中心Z(省略時0.5) //補足1:テクスチャファイルは指定面以降も使われます。"A.bmp","","B.bmp" と指定した場合1、2枚目がA、以降が全てBになります。 //補足2:モデルには拡散光が設定されます。デフォルトは204(実際のデータ上は0.8)ですが、SetXFileDiffusedLight命令で変更できます。 //補足3:一つの板がmattexRange区切りを跨ぐ事を考慮してません //補足4:MakeXFilePlateで作られたモデルデータは板同士の頂点共有が無いので見た目フラットシュエーディングになる //注意:tflist、UVFliplistに前回の内容が残ってると意図して無い面にもテクスチャやUV値の回転等が設定されてしまいます。 #define global MakeXFilePlate(%1,%2,%3,%4=temp@mod_addxfileTex,%5=temp@mod_addxfileTex,%6=1.0,%7=0.5,%8=0.5,%9=0.5) _makexfilePlate %1,%2,%3,%4,%5,%6,%7,%8,%9 #deffunc _makexfilePlate var MeshxPlate,var Vertexlist_var,int Platemax,array tflist,array UVFliplist,double mattexRange,double mcx,double mcy,double mcz dup Vertexlist,Vertexlist_var verticesmax=Platemax*4 if varptr(tflist)=varptr(temp@mod_addxfileTex){tflistmax=0}else{tflistmax=length(tflist)} if varptr(UVFliplist)=varptr(temp@mod_addxfileTex){UVFliplistmax=0}else{UVFliplistmax=length(UVFliplist)} if tflistmax=0 { if pdtset_f { tftype=0 if pdtset_f=2 {tftype=1}else{tftype=0} } }else{ tftype=vartype(tflist)!2 } if dupon=0 { if MAXMODEL=0 {gosub *sub_startxfiletex} if pduvfset_f=0{dim pduvf_f,6} if pdtset_f=0 {dim pdtf_f,6} if hvafset_f=0 {PlateHorVerAng} dup dup_hvax,hvalist dup dup_hvay,hvalist(1) dup dup_hvaz,hvalist(2) ddim u_bak,4 ddim v_bak,4 ddim vxyz,4 dup dup_vx,vxyz dup dup_vy,vxyz(1) dup dup_vz,vxyz(2) ddim outer,4 dup dup_outerx,outer dup dup_outery,outer(1) dup dup_outerz,outer(2) dupon=1 mtc_u=0.0 mtc_v=0.0 Platemax_bak=100*2 if Platemax>Platemax_bak {Platemax_bak=Platemax} sdim mnno_str,64,Platemax_bak repeat Platemax_bak mnno_str(cnt)="4;"+cnt+","+cnt+","+cnt+","+cnt+";,\n" loop } if Platemax*2>Platemax_bak { repeat Platemax*2-Platemax_bak,Platemax_bak mnno_str(cnt)="4;"+cnt+","+cnt+","+cnt+","+cnt+";,\n" loop Platemax_bak=Platemax*2 } uvAdjust=1.0/mattexRange MNlist_str="" MNnolist_str="" vecnt=0 uvcnt=0 mtc_u(Platemax*4)=0.0 mtc_v(Platemax*4)=0.0 sdim xbox_vindex,64,Platemax MeshNormals_templ="" MeshNormals_no="" vi_cnt=0 Mesh_index=0 xbox_vindex_str="" if diflit=0 {Diffused_light="Material {0.8;0.8;0.8;;"}else{Diffused_light="Material {"+set_Diffused_light} xbox_mmlnoist="" mat_list="" mat_no=0 mat_no_bak=0 mat_no_str="0," tfname="" mtexc="\n MeshTextureCoords {"+verticesmax+";\n" mtexc_total_strlen=strlen(mtexc) tfid=tflist UVFliplist_f=0 if pdtset_f { if tftype { if pdtset_f=1 {dim pdtf_f,6}else{ sdim pdtf_mtid,,6 repeat 6 if pdtf_f(cnt) { pdtf_mtid(cnt)= pdtflist(cnt) } loop } }else{ if pdtset_f=2 {dim pdtf_f,6}else{ sdim pdtf_mtid,,6 repeat 6 if pdtf_f(cnt) { mat_list+=Diffused_light+"TextureFilename { \""+pdtflist(cnt)+"\";}}\n" pdtf_mtid(cnt)= ""+mat_no+"," mat_no++ } loop } } } UVFliplist_mcp(Platemax)=0 memset UVFliplist_mcp,-1,Platemax*4 if UVFliplistmax {memcpy UVFliplist_mcp,UVFliplist,UVFliplistmax*4} Doublefaced=0 repeat Platemax dup dup_Vertex_x,Vertexlist(vecnt) dup dup_Vertex_y,Vertexlist(vecnt+1) dup dup_Vertex_z,Vertexlist(vecnt+2) memcpy vxyz,dup_Vertex_x,24 fvset outer,dup_Vertex_x(3)-dup_vx,dup_Vertex_y(3)-dup_vy,dup_Vertex_z(3)-dup_vz if dup_vx=dup_Vertex_x(9) and dup_vy=dup_Vertex_y(9) and dup_vz=dup_Vertex_z(9) { fvouter outer,dup_Vertex_x(6)-dup_vx,dup_Vertex_y(6)-dup_vy,dup_Vertex_z(6)-dup_vz veci=3 }else{ veci=4 fvouter outer,dup_Vertex_x(9)-dup_vx,dup_Vertex_y(9)-dup_vy,dup_Vertex_z(9)-dup_vz } fvunit outer dup dup_mtc_u,mtc_u(uvcnt) dup dup_mtc_v,mtc_v(uvcnt) if ((absf(dup_outerz)+dup_hvaz)>(absf(dup_outerx)+dup_hvax)) { if absf(dup_outery)>=dup_hvay {goto *_yside}else{goto *_zside} }else{ if absf(dup_outery)>=dup_hvay {goto *_yside}else{goto *_xside} } #const global M_PI2 M_PI*2 *_xside ui=0+dup_Vertex_z( ((dup_Vertex_z>dup_Vertex_z(3)) | (dup_Vertex_z>dup_Vertex_z(9))*3)*3 )*uvAdjust vi=0+dup_Vertex_y( ( (dup_Vertex_y>dup_Vertex_y(3)) | (dup_Vertex_y>dup_Vertex_y(9))*3 )*3 )*uvAdjust if dup_outerx<0.0{ if pdtf_f(5) {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid(5)}else{pdtf_fon=0} if pduvf_f(5) {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist(5)}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ xi=0+dup_Vertex_x( ( (dup_Vertex_x>dup_Vertex_x(3)) | (dup_Vertex_x>dup_Vertex_x(9))*3 )*3 )*uvAdjust repeat 4 dup_mtc_u(cnt)=(1.0-((atan((dup_Vertex_x(cnt*3)*uvAdjust-xi-0.5),(dup_Vertex_z(cnt*3)*uvAdjust-ui-0.5))+M_PI)/M_PI2)\1.0) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=(dup_Vertex_z(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } }else{ if pdtf_f(4) {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid(4)}else{dtf_fon=0} if pduvf_f(4) {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist(4)}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ xi=0+dup_Vertex_x( ( (dup_Vertex_x>dup_Vertex_x(3)) | (dup_Vertex_x>dup_Vertex_x(9))*3 )*3 )*uvAdjust if dup_outery=1.0 or dup_outery=-1.0{ repeat 4 dup_mtc_u(cnt)=1.0-(atan((dup_Vertex_x(cnt*3)*uvAdjust-xi-0.5),dup_Vertex_z(cnt*3)*uvAdjust-ui-0.5)+M_PI)/M_PI2 dup_mtc_v(cnt)=(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=1.0-(atan((dup_Vertex_x(cnt*3)*uvAdjust-xi-0.5),dup_Vertex_z(cnt*3)*uvAdjust-ui-0.5)+M_PI)/M_PI2 dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } }else{ if dup_outery=1.0 or dup_outery=-1.0{ repeat 4 dup_mtc_u(cnt)=0.99999-(dup_Vertex_z(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=0.99999-(dup_Vertex_z(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } } } goto *@f *_yside ui=0+dup_Vertex_x( ((dup_Vertex_x>dup_Vertex_x(3)) | (dup_Vertex_x>dup_Vertex_x(9))*3)*3 )*uvAdjust vi=0+dup_Vertex_z( ( (dup_Vertex_z>dup_Vertex_z(3)) | (dup_Vertex_z>dup_Vertex_z(9))*3 )*3 )*uvAdjust if dup_outery<0.0 { if pdtf_f(1) {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid(1)}else{pdtf_fon=0} if pduvf_f(1) {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist(1)}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ yi=0+dup_Vertex_y( ( (dup_Vertex_y>dup_Vertex_y(3)) | (dup_Vertex_y>dup_Vertex_y(9))*3 )*3 )*uvAdjust repeat 4 dup_mtc_u(cnt)=(1.0-((atan(dup_Vertex_y(cnt*3)*uvAdjust-yi-0.5,((dup_Vertex_x(cnt*3)*uvAdjust-ui-0.5)))+M_PI)/M_PI2)\1.0) dup_mtc_v(cnt)=0.99999-(dup_Vertex_z(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=(dup_Vertex_x(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=0.99999-(dup_Vertex_z(cnt*3)*uvAdjust-vi) loop } }else{ if pdtf_f {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid}else{pdtf_fon=0} if pduvf_f {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ yi=0+dup_Vertex_y( ( (dup_Vertex_y>dup_Vertex_y(3)) | (dup_Vertex_y>dup_Vertex_y(9))*3 )*3 )*uvAdjust repeat 4 dup_mtc_u(cnt)=1.0-(atan(dup_Vertex_y(cnt*3)*uvAdjust-yi-0.5,(dup_Vertex_x(cnt*3)*uvAdjust-ui-0.5))+M_PI)/M_PI2 dup_mtc_v(cnt)=(dup_Vertex_z(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=(dup_Vertex_x(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=(dup_Vertex_z(cnt*3)*uvAdjust-vi) loop } } goto *@f *_zside ui=0+dup_Vertex_x( ((dup_Vertex_x>dup_Vertex_x(3)) | (dup_Vertex_x>dup_Vertex_x(9))*3)*3 )*uvAdjust vi=0+dup_Vertex_y( ( (dup_Vertex_y>dup_Vertex_y(3)) | (dup_Vertex_y>dup_Vertex_y(9))*3 )*3 )*uvAdjust if dup_outerz<0.0 { if pdtf_f(3) {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid(3)}else{pdtf_fon=0} if pduvf_f(3) {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist(3)}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ zi=0+dup_Vertex_z( ( (dup_Vertex_z>dup_Vertex_z(3)) | (dup_Vertex_z>dup_Vertex_z(9))*3 )*3 )*uvAdjust repeat 4 dup_mtc_u(cnt)=(1.0-((atan(dup_Vertex_z(cnt*3)*uvAdjust-zi-0.5,((dup_Vertex_x(cnt*3)*uvAdjust-ui-0.5)))+M_PI)/M_PI2)\1.0) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=0.99999-(dup_Vertex_x(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } }else{ if pdtf_f(2) {pdtf_fon=1:pdtf_mtid_str=pdtf_mtid(2)}else{pdtf_fon=0} if pduvf_f(2) {if UVFliplist_mcp(cnt)<0 {UVFliplist_f=pduvflist(2)}else{UVFliplist_f=UVFliplist_mcp(cnt)}}else{if UVFliplist_mcp(cnt)<0 {}else{UVFliplist_f=UVFliplist_mcp(cnt)}} if UVFliplist_f & 256{ zi=0+dup_Vertex_z( ( (dup_Vertex_z>dup_Vertex_z(3)) | (dup_Vertex_z>dup_Vertex_z(9))*3 )*3 )*uvAdjust if dup_outery=1.0 or dup_outery=-1.0{ repeat 4 dup_mtc_u(cnt)=((1.0-(atan(dup_Vertex_z(cnt*3)*uvAdjust-0.5-zi,(dup_Vertex_x(cnt*3)*uvAdjust-0.5-ui))+M_PI)/M_PI2)) dup_mtc_v(cnt)=(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ repeat 4 dup_mtc_u(cnt)=((1.0-(atan(dup_Vertex_z(cnt*3)*uvAdjust-0.5-zi,(dup_Vertex_x(cnt*3)*uvAdjust-0.5-ui))+M_PI)/M_PI2)) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } }else{ if dup_outery=1.0 or dup_outery=-1.0{ repeat 4 dup_mtc_u(cnt)=(dup_Vertex_x(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop }else{ vi=0+dup_Vertex_y( ( (dup_Vertex_y>dup_Vertex_y(3)) | (dup_Vertex_y>dup_Vertex_y(9))*3 )*3 )*uvAdjust repeat 4 dup_mtc_u(cnt)=(dup_Vertex_x(cnt*3)*uvAdjust-ui) dup_mtc_v(cnt)=0.99999-(dup_Vertex_y(cnt*3)*uvAdjust-vi) loop } } } *@f on UVFliplist_f & $1f goto *@f,*_R90,*_R180,*_L90,*_UR,*_VR,*_UPR,*_N,*_PR,*_R90,*_R180,*_L90,*_UR,*_VR,*_UPR,*_N goto *@f *_R90//右90度回転 memcpy u_bak,dup_mtc_u,32 memcpy dup_mtc_u,dup_mtc_v,32 memcpy dup_mtc_v,u_bak(2),16 memcpy dup_mtc_v(2),u_bak(0),16 repeat 4: dup_mtc_v(cnt)=absf(u_bak(cnt)-0.99999):loop//1.0にしないのは逆方向にテクスチャが貼られると隣のドットが含まれることがあるので補正(これで問題ないかは分からない) goto *@f *_R180//左180度回転 repeat 4: dup_mtc_u(cnt)=absf(dup_mtc_u(cnt)-0.99999): dup_mtc_v(cnt)=absf(dup_mtc_v(cnt)-0.99999):loop goto *@f *_L90//左90度回転 memcpy v_bak,dup_mtc_v,32 memcpy dup_mtc_v,dup_mtc_u,32 repeat 4:dup_mtc_u(cnt)=absf(v_bak(cnt)-0.99999):loop goto *@f *_VR//上下反転 repeat 4:dup_mtc_v(cnt)=absf(dup_mtc_v(cnt)-0.99999):loop goto *@f *_UR//左右反転 repeat 4: dup_mtc_u(cnt)=absf(dup_mtc_u(cnt)-0.99999): loop goto *@f *_UPR//上下左右反転 repeat 4 : dup_mtc_u(cnt)=absf(dup_mtc_u(cnt)-0.99999): dup_mtc_v(cnt)=absf(dup_mtc_v(cnt)-0.99999) loop *@ if UVFliplist_f&8 { *_PR xbox_vindex_str+="4;"+(uvcnt+3)+","+(uvcnt+2)+","+(uvcnt+1)+","+uvcnt+";,\n" MeshNormals_templ+=""+(-dup_outerx)+";"+(-dup_outery)+";"+(-dup_outerz)+";,\n" }else{ *_N xbox_vindex_str+="4;"+uvcnt+","+(uvcnt+1)+","+(uvcnt+2)+","+(uvcnt+3)+";,\n" MeshNormals_templ+=""+dup_outerx+";"+dup_outery+";"+dup_outerz+";,\n" if UVFliplist_f&32 { if veci=4 { xbox_vindex_str+="4;"+(uvcnt)+","+(uvcnt+3)+","+(uvcnt+2)+","+(uvcnt+1)+";,\n" MeshNormals_templ+=""+0.0+";"+0.0+";"+0.0+";,\n" Doublefaced++ }else{ xbox_vindex_str+="4;"+(uvcnt+3)+","+(uvcnt+2)+","+(uvcnt+1)+","+(uvcnt+0)+";,\n" MeshNormals_templ+=""+0.0+";"+0.0+";"+0.0+";,\n" Doublefaced++ } } } mtexc_="" if tftype { if pdtf_fon { tfid2=0+pdtf_mtid_str tdiv_u=texpos_u(tfid2) tdiv_v=texpos_v(tfid2) }else{ if cnt<tflistmax { if tflist(cnt)>=0 {tfid=tflist(cnt)} } tdiv_u=texpos_u(tfid) tdiv_v=texpos_v(tfid) } _RateUVI=RateUVIlist(tfid) dup dup_mat_no_str,mat_no_str mtexc_+=""+(tdiv_u+_RateUVI*dup_mtc_u)+";"+(tdiv_v+_RateUVI*dup_mtc_v)+";," mtexc_+=""+(tdiv_u+_RateUVI*dup_mtc_u(1))+";"+(tdiv_v+_RateUVI*dup_mtc_v(1))+";," mtexc_+=""+(tdiv_u+_RateUVI*dup_mtc_u(2))+";"+(tdiv_v+_RateUVI*dup_mtc_v(2))+";," mtexc_+=""+(tdiv_u+_RateUVI*dup_mtc_u(3))+";"+(tdiv_v+_RateUVI*dup_mtc_v(3))+";," }else{ if pdtf_fon { if cnt<tflistmax { if tflist(cnt) ! "" { mat_no_str=""+mat_no+"," mat_list+Diffused_light+"TextureFilename { \""+tflist(cnt)+"\";}}\n" mat_no++ dup dup_mat_no_str,mat_no_str }else{dup dup_mat_no_str,pdtf_mtid_str } }else{dup dup_mat_no_str,pdtf_mtid_str } }else{ if cnt<tflistmax { if tflist(cnt) ! "" { mat_no_str=""+mat_no+"," mat_list+Diffused_light+"TextureFilename { \""+tflist(cnt)+"\";}}\n" mat_no++ } dup dup_mat_no_str,mat_no_str }else{dup dup_mat_no_str,mat_no_str} } mtexc_+=""+dup_mtc_u+";"+dup_mtc_v+";," mtexc_+=""+dup_mtc_u(1)+";"+dup_mtc_v(1)+";," mtexc_+=""+dup_mtc_u(2)+";"+dup_mtc_v(2)+";," mtexc_+=""+dup_mtc_u(3)+";"+dup_mtc_v(3)+";," } mtexc_strlen=strlen(mtexc_) memexpand mtexc,mtexc_total_strlen+mtexc_strlen+1 memcpy mtexc,mtexc_,mtexc_strlen+1,mtexc_total_strlen mtexc_total_strlen+mtexc_strlen MeshNormals_no+mnno_str(Mesh_index) Mesh_index++ xbox_mmlnoist+dup_mat_no_str if UVFliplist_f&32 { MeshNormals_no+mnno_str(Mesh_index) Mesh_index++ xbox_mmlnoist+dup_mat_no_str } uvcnt+4 vecnt+12 loop xbox_mmlnoist+";\n" poke xbox_mmlnoist,strlen(xbox_mmlnoist)-4,';' poke xbox_vindex_str,strlen(xbox_vindex_str)-3,';' poke MeshNormals_templ,strlen(MeshNormals_templ)-3,';' poke MeshNormals_no,strlen(MeshNormals_no)-3,';' mtexc_endstr=";}}" memexpand mtexc,mtexc_total_strlen+4 memcpy mtexc,mtexc_endstr,4,mtexc_total_strlen-1 mtexc_total_strlen+2 if mat_no=0 {mat_no=1:mat_list= Diffused_light+"}\n"} MeshxPlate="xof 0302txt 0064 \n Mesh {\n"+verticesmax+";\n" vcnt=0 repeat verticesmax MeshxPlate+=""+(Vertexlist(vcnt)-mcx)+";"+(Vertexlist(vcnt+1)-mcy)+";"+(Vertexlist(vcnt+2)-mcz)+";," vcnt+3 loop poke MeshxPlate,strlen(MeshxPlate)-1,';' MeshxPlate+=""+(Platemax+Doublefaced)+";\n" MeshxPlate+xbox_vindex_str+" MeshMaterialList {" MeshxPlate+=""+mat_no+";"+(Platemax+Doublefaced)+";"+xbox_mmlnoist+mat_list+"}\n"+" MeshNormals {\n"+(Platemax+Doublefaced)+";"+MeshNormals_templ+""+(Platemax+Doublefaced)+";"+MeshNormals_no+"}" MeshxPlate_strlen=strlen(MeshxPlate) memexpand MeshxPlate,MeshxPlate_strlen+mtexc_total_strlen+1 memcpy MeshxPlate,mtexc,mtexc_total_strlen+1,MeshxPlate_strlen return ////「X形式のモデルテキストデータの頂点と頂点インデックスから板毎にXYZ座標4頂点を実数型配列に入れる」 //[ GetXFilePlateVec mvlarr, plamax, xfile, modResizef, modmaxsize ] // mvlarr : 板の頂点データを取得する実数型配列「 makexfilPlate命令でそのまま利用できる 」 // plamax : 取得した板の数「 makexfilPlate命令でそのまま利用できる 」 // xfile : X形式のモデルテキストデータが入った変数「データ全ては必要なく "Mesh {"を含めた頂点リストと頂点インデックスリストが有れば良い」 // modResizef : リサイズと中心に移動させるかのフラグ「0=そのまま、1=modmaxsize指定サイズにする、2=modmaxsizeに満たない幅の軸を中心に移動する、3=1と2を合わせた機能」 // modmaxsize : modResizefに1が指定された時のモデルサイズ(省略時1.0) //補足:基のモデルデータに3頂点が使用された場合3頂点目を4頂点目にコピーして、4頂点にします。 #define global GetXFilePlateVec(%1,%2,%3,%4=0,%5=1.0) _GetXFilePlateVec %1,%2,%3,%4,%5 #deffunc _GetXFilePlateVec array mvlarr,var plamax,var xfile,int modResizef,double modmaxsize if MAXMODEL=0 {gosub *sub_startxfiletex} cr_code="\n" index=instr(xfile,0,"}") if index>0 { temp_str=strmid(xfile,0,index) if instr(temp_str,0,cr_code)<0 {wpoke cr_code,0,$A} } Total_index=0 if TemplateSearch(mvlmax_str,xfile,Total_index,"Mesh ","1",";",0)<0 {return -1} mvlmax=0+mvlmax_str mindex=instr(xfile,Total_index,";;") mvlist_str=strmid(xfile,Total_index,mindex) Total_index+mindex+2 mindex=instr(xfile,Total_index,";") mvilmax_str=strmid(xfile,Total_index,mindex) Total_index+mindex+1 mvilist_str=strmid(xfile,Total_index,instr(xfile,Total_index,";;")) strrep mvlist_str,cr_code,"" strrep mvilist_str,cr_code,"" if length(mesh_vec_str)<mvlmax {sdim mesh_vec_str,,mvlmax} split mvlist_str,";,",mesh_vec_str if length(mesh_mnli_str)<int(mvilmax_str) { sdim mesh_mnli_str,,int(mvilmax_str)} split mvilist_str,";,",mesh_vi_str fvset mvmin,10000.0,10000.0,10000.0 fvset mvmax,-10000.0,-10000.0,-10000.0 split mesh_vec_str,";,",mesh_vec_str vecxyz=0.0 vecxyz(3*mvlmax)=0.0 repeat mvlmax split mesh_vec_str(cnt),";",mvx_str,mvy_str,mvz_str dup dup_vecxyz,vecxyz(cnt*3) dup_vecxyz=0.0+mvx_str,0.0+mvy_str,0.0+mvz_str fvmin mvmax,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) fvmax mvmin,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) loop fvset mdsize,mvmax,mvmax(1),mvmax(2) fvsub mdsize,mvmin,mvmin(1),mvmin(2) getScaleFactor_model sf mmsize=refdval if modResizef & 2{ dif_mx=(mmsize-XMD_SIZEX)/2 dif_my=(mmsize-XMD_SIZEY)/2 dif_mz=(mmsize-XMD_SIZEZ)/2 }else{ dif_mx=0.0 dif_my=0.0 dif_mz=0.0 } if modResizef & 1 {sf*modmaxsize}else{sf=1.0} ddim mvlarr,int(mvilmax_str)*3*4 plamax=0 repeat int(mvilmax_str) split mesh_vi_str(cnt),";",cnt_str,vid_str split vid_str,",",vid_str if 3=cnt_str { repeat 3 dup dup_vecxyz,vecxyz(3*vid_str(cnt)) mvlarr(plamax)=sf*(dif_mx+dup_vecxyz-mvmin),sf*(dif_my+dup_vecxyz(1)-mvmin(1)),sf*(dif_mz+dup_vecxyz(2)-mvmin(2)) //座標は実数型で保持 plamax+3 loop mvlarr(plamax)=mvlarr(plamax-3),mvlarr(plamax-3+1),mvlarr(plamax-3+2) //座標は実数型で保持 plamax+3 }else{ repeat 4 dup dup_vecxyz,vecxyz(3*vid_str(cnt)) mvlarr(plamax)=sf*(dif_mx+dup_vecxyz-mvmin),sf*(dif_my+dup_vecxyz(1)-mvmin(1)),sf*(dif_mz+dup_vecxyz(2)-mvmin(2)) //座標は実数型で保持 plamax+3 loop } loop fvmul XMD_SIZEX,sf,sf,sf fvset mvmin,dif_mx,dif_my,dif_mz fvset mvmax,dif_mx+XMD_SIZEX,dif_my+XMD_SIZEY,dif_mz+XMD_SIZEZ plamax/12 return ////「keepxfiletextxtで保持したデータを統合させて一つのモデルデータを作成」 //[ MergeXFileTexTXT xfile_m, xtxtidlist, xposlist, yposlist, zposlist, xtxtidlistmax, mergef ] // xfile_m : x形式のモデルテキストデータが格納される変数 // xfileidlist : keepxfiletextxtで取得できるデータIDを入れた配列 // xfileidmax : 何個統合するか // mergef : 一度に全て統合するかどうか「0=一回で全て処理、1〜=一度に処理する個数」 // xyzposlist : 移動座標リスト(実数型配列:省略不可)「一つのデータIDでXYZの3軸分必要」 // xyzrotlist : 回転リスト(実数型配列、単位ラジアン:省略可)「一つのデータIDでXYZの3軸分必要」 // xyzscalelist : 移動Z座標(実数型配列:省略可)「一つのデータIDでXYZの3軸分必要」 //戻り値:statに処理済個数が返る(xfileidmaxと同じなら処理終了)-1ならエラー #define global MergeXFileTexTXT(%1,%2,%3,%4,%5,%6=xyztest@mod_addxfileTex,%7=xyztest@mod_addxfileTex) _MergeXFileTexTXT %1,%2,%3,%4,%5,%6,%7 #deffunc _MergeXFileTexTXT var xfile_m,array xfileidlist,int xfileidmax,int mergef,array xyzposlist,array xyzrotlist,array xyzscalelist if xfileidmax<=0 {return -1} if mgindex=0 { mgindex=0 mvilist_m="" xfile_m="xof 0302txt 0064 \n Mesh {\n ;" strlen_xfile_m=strlen(xfile_m) vexmax_i=strlen_xfile_m-10 mtexc_m=";\n" mmlist_m=";\n" mnlist_m=";\n" mnindex_m="" total_mnmax=0 total_mvim=0 total_uvmax=0 total_mvecm=0 mat_no_str="0,","1," } looplimit=limit(xfileidmax-mgindex,0,(mergef=0)*xfileidmax+mergef) rotf=varptr(xyzrotlist)=varptr(xyztest@mod_addxfileTex) scalef=varptr(xyzscalelist)=varptr(xyztest@mod_addxfileTex) if rotf {//回転無し if scalef {//スケール変更無し repeat looplimit xfile_m_="" dup dup_xyzpos,xyzposlist(mgindex*3) mod_getvec Meshdata(xfileidlist(mgindex)), xfile_m_,dup_xyzpos, -dup_xyzpos(1), dup_xyzpos(2) #define mgloop mgindex++ :%c\ strlen_xfile_m_=strlen(xfile_m_) :%c\ memexpand xfile_m,strlen_xfile_m+strlen_xfile_m_+1 :%c\ memcpy xfile_m,xfile_m_,strlen_xfile_m_+1,strlen_xfile_m :%c\ strlen_xfile_m+strlen_xfile_m_ :%c mgloop loop }else{//スケール変更有り repeat looplimit xfile_m_="" dup dup_xyzpos,xyzposlist(mgindex*3) dup dup_xyzscale,xyzscalelist(mgindex*3) mod_getvecscale Meshdata(xfileidlist(mgindex)), xfile_m_,dup_xyzpos, -dup_xyzpos(1), dup_xyzpos(2),dup_xyzscale,dup_xyzscale(1),dup_xyzscale(2) mgloop loop } }else{//回転有り if scalef {//スケール変更無し repeat looplimit xfile_m_="" dup dup_xyzpos,xyzposlist(mgindex*3) dup dup_xyzrot,xyzrotlist(mgindex*3) mod_getvecrot Meshdata(xfileidlist(mgindex)), xfile_m_,dup_xyzpos, -dup_xyzpos(1), dup_xyzpos(2),-dup_xyzrot, -dup_xyzrot(1), -dup_xyzrot(2) mgloop loop }else{//スケール変更有り repeat looplimit xfile_m_="" dup dup_xyzpos,xyzposlist(mgindex*3) dup dup_xyzrot,xyzrotlist(mgindex*3) dup dup_xyzscale,xyzscalelist(mgindex*3) mod_getvecrotscale Meshdata(xfileidlist(mgindex)), xfile_m_,dup_xyzpos, -dup_xyzpos(1), dup_xyzpos(2),-dup_xyzrot, -dup_xyzrot(1), -dup_xyzrot(2),dup_xyzscale,dup_xyzscale(1),dup_xyzscale(2) mgloop loop } } if mgindex>=xfileidmax { poke mnlist_m,strlen(mnlist_m)-1,';' poke mnindex_m,strlen(mnindex_m)-3,';' poke xfile_m,strlen_xfile_m-1,';' poke mtexc_m,strlen(mtexc_m)-1,';' poke mmlist_m,strlen(mmlist_m)-1,';' poke mvilist_m,strlen(mvilist_m)-1,';' total_mvecm=str(total_mvecm) memcpy xfile_m,total_mvecm,strlen(total_mvecm),vexmax_i if diflit=0 { mmlist_m+";\nMaterial {0.8;0.8;0.8;1.0;;}\nMaterial {0.8;0.8;0.8;1.0;;}}" }else{ mmlist_m+";\nMaterial {"+set_Diffused_light+"}\nMaterial {"+set_Diffused_light+"}}" } xfile_m+=""+total_mvim+";"+mvilist_m+"\n"+" MeshMaterialList {\n2;"+total_mvim+mmlist_m+"MeshNormals {"+total_mnmax+mnlist_m+total_mvim+";"+mnindex_m+"}"+"MeshTextureCoords {"+total_uvmax+mtexc_m+"}}" mgindex=0 return xfileidmax } return mgindex ////「mergexfiletextxtで利用するxfileデータをモジュール内に保持してデータインデックスを返す」 //[ KeepXFileTexTXT xfile ,sgf ,msize ] // xfile : 保持するx形式のモデルテキストデータ // sgf : サイズ計算するかどうか「0=しない、1=する(サイズ取得用マクロや命令が使用できる)、2=簡易的に法線を設定する」 // msize : sgfに1を指定した時にmsizeで指定したサイズにして保持します。「0.0が指定された場合サイズ変更はしません」 //戻り値:statにxfileデータインデックスが返る(-1ならエラー) //補足1:sgfに2が指定されて無くても法泉が無い場合は法線を設定します。 //補足2:ここで設定する法泉は簡易的なものなので hgsetreq SYSREQ_CALCNORMAL,1 で法線再計算設定をしてモデルを作る必要があるかもしれません #define global KeepXFileTexTXT(%1,%2=0,%3=0.0) _KeepXFileTexTXT %1,%2,%3 #deffunc _KeepXFileTexTXT var xfile,int sgf,double msize if vartype(vxyz)=4 { ddim vxyz,4 dup dup_vx,vxyz dup dup_vy,vxyz(1) dup dup_vz,vxyz(2) ddim outer,4 dup dup_outerx,outer dup dup_outery,outer(1) dup dup_outerz,outer(2) } sizeget_f=sgf msizeset=msize cr_code="\n" index=instr(xfile,0,"}") if index>0 { temp_str=strmid(xfile,0,index) if instr(temp_str,0,cr_code)<0 {wpoke cr_code,0,$A} } Total_index=0 if TemplateSearch(mvlmax_str,xfile,Total_index,"Mesh ","1",";",0)<0 {return -1} mindex=instr(xfile,Total_index,";;") mvlist_str=strmid(xfile,Total_index,mindex) Total_index+mindex+2 mindex=instr(xfile,Total_index,";") mvilmax_str=strmid(xfile,Total_index,mindex) Total_index+mindex+1 mvilist_str=strmid(xfile,Total_index,instr(xfile,Total_index,";;")) if TemplateSearch(muvlmax_str,xfile,Total_index,"MeshTextureCoords ","1",";",0)<0 { muvlmax_str="0" muvlist_str="" tfonoff=1 }else{ tfonoff=0 muvlist_str=strmid(xfile,Total_index,instr(xfile,Total_index,";;")) } Total_index=0 if TemplateSearch(mnlmax_str,xfile,Total_index,"MeshNormals ","1",";",0)<0 { mnilmax_str="" mnlmax_str="" mnlist_str="" mnilist_str="" }else{ mindex=instr(xfile,Total_index,";;") mnlist_str=strmid(xfile,Total_index,mindex) Total_index+mindex+2 mindex=instr(xfile,Total_index,";") mnilmax_str=strmid(xfile,Total_index,mindex) Total_index+mindex+1 mnilist_str=strmid(xfile,Total_index,instr(xfile,Total_index,";;")) } strrep mvlist_str,cr_code,"" strrep mvilist_str,cr_code,"" strrep muvlist_str,cr_code,"" strrep muvlist_str,cr_code,"" strrep mnlist_str,cr_code,"" strrep mnilist_str,cr_code,"" newmod Meshdata,mod_addxfileTex,mvlist_str,int(mvlmax_str),mvilist_str,int(mvilmax_str),muvlist_str,int(muvlmax_str),mnlist_str,int(mnlmax_str),mnilist_str,int(mnilmax_str) tfonoff_list(stat)=tfonoff return stat ////----------以下は通常単体では使用しない命令等(上の命令内で使用されてる)------------------- ////「keepxfiletextxt内で使用されるモジュール変数初期化データ追加用」(単体では使用しない) //[ newmod 変数,m_MeshVecList, m_MeshVecMax, m_MeshVecIndexList, m_MeshVecIndexMax, m_MeshUVList, m_MeshUVMax, m_MeshNormalsList, m_MeshNormalsMax, m_MeshNormalsIndex, m_MeshNormalsIndexMax] // m_MeshVecList : 頂点XYZ座標リスト(文字列) // m_MeshVecMax : 座標の数 // m_MeshVecIndexList : 頂点インデックスリスト(文字列) // m_MeshVecIndexMax : 頂点インデックス数 // m_MeshUVList : UVリスト(文字列) // m_MeshUVMax : UV数 // m_MeshNormalsList : 法線リスト(文字列) // m_MeshNormalsMax : 法線数 // m_MeshNormalsIndex : 法線インデックスリスト(文字列) // m_MeshNormalsIndexMax : 法線インデックス数 #modinit var m_MeshVecList,int m_MeshVecMax,var m_MeshVecIndexList,int m_MeshVecIndexMax,var m_MeshUVList,int m_MeshUVMax,var m_MeshNormalsList,int m_MeshNormalsMax,var m_MeshNormalsIndex,int m_MeshNormalsIndexMax MeshVecMax=m_MeshVecMax MeshVecIndexMax=m_MeshVecIndexMax if m_MeshUVMax { MeshUVMax=m_MeshUVMax }else{ MeshUVMax=MeshVecMax sdim MeshUVList,MeshVecMax*10 repeat MeshVecMax MeshUVList+"0.0;0.0;," loop } MeshUVList=m_MeshUVList+";," //UV値は文字列のまま保持 mesh_vec_str="" if length(mesh_vec_str)<m_MeshVecMax {mesh_vec_str(m_MeshVecMax)=""} split m_MeshVecList,";,",mesh_vec_str if sizeget_f&1 { fvset mvmin,10000.0,10000.0,10000.0 fvset mvmax,-10000.0,-10000.0,-10000.0 MeshVecList=0.0 MeshVecList(3*m_MeshVecMax)=0.0 //文字列の座標を実数にして保存する配列 repeat m_MeshVecMax split mesh_vec_str(cnt),";",mvx_str,mvy_str,mvz_str dup dup_vecxyz,MeshVecList(cnt*3) dup_vecxyz=0.0+mvx_str,0.0+mvy_str,0.0+mvz_str //座標は実数型で保持 fvmin mvmax,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) fvmax mvmin,dup_vecxyz,dup_vecxyz(1),dup_vecxyz(2) loop fvset mdsize,mvmax,mvmax(1),mvmax(2) fvsub mdsize,mvmin,mvmin(1),mvmin(2) if msizeset ! 0.0 { getScaleFactor_model msf msf*msizeset repeat MeshVecMax*3 MeshVecList(cnt)*msf loop } }else{ MeshVecList=0.0 MeshVecList(3*m_MeshVecMax)=0.0 //文字列の座標を実数にして保存する配列 repeat m_MeshVecMax split mesh_vec_str(cnt),";",mvx_str,mvy_str,mvz_str MeshVecList(cnt*3)=0.0+mvx_str,0.0+mvy_str,0.0+mvz_str //座標は実数型で保持 loop } index_cnt=0 if length(mesh_vi_str)<m_MeshVecIndexMax {sdim mesh_vi_str,,m_MeshVecIndexMax} split m_MeshVecIndexList,";,",mesh_vi_str MeshVecIndexCnt(m_MeshVecIndexMax)=0 MeshVecIndexList(m_MeshVecIndexMax*4)=0 repeat m_MeshVecIndexMax split mesh_vi_str(cnt),";",cnt_str,vid_str split vid_str,",",vid_str MeshVecIndexCnt(cnt)=0+cnt_str repeat MeshVecIndexCnt(cnt) MeshVecIndexList(index_cnt)=0+vid_str(cnt) //インデックスは整数型で保持 index_cnt++ loop loop if sizeget_f&2 or m_MeshNormalsMax=0{ index_cnt=0 mn_index=0 MeshNormalsIndex(m_MeshVecIndexMax*4)=0 MeshNormalsIndexCnt(m_MeshVecIndexMax)=0 sdim MeshNormalsList,m_MeshVecIndexMax*4*15 repeat m_MeshVecIndexMax dup dup_Vertex_A,MeshVecList(MeshVecIndexList(index_cnt)*3) dup dup_Vertex_B,MeshVecList(MeshVecIndexList(index_cnt+1)*3) dup dup_Vertex_C,MeshVecList(MeshVecIndexList(index_cnt+2)*3) if MeshVecIndexCnt(cnt)=4 { dup dup_Vertex_D,MeshVecList(MeshVecIndexList(index_cnt+3)*3) memcpy vxyz,dup_Vertex_A,24 fvset outer,dup_Vertex_B-dup_vx,dup_Vertex_B(1)-dup_vy,dup_Vertex_B(2)-dup_vz if dup_vx=dup_Vertex_D and dup_vy=dup_Vertex_D(1) and dup_vz=dup_Vertex_D(2) { fvouter outer,dup_Vertex_C-dup_vx,dup_Vertex_C(1)-dup_vy,dup_Vertex_C(2)-dup_vz }else{ fvouter outer,dup_Vertex_D-dup_vx,dup_Vertex_D(1)-dup_vy,dup_Vertex_D(2)-dup_vz } fvunit outer MeshNormalsList+=""+dup_outerx+";"+dup_outery+";"+dup_outerz+";," MeshNormalsIndex(index_cnt)=cnt,cnt,cnt,cnt MeshNormalsIndexCnt(cnt)=4 index_cnt+4 }else{ memcpy vxyz,dup_Vertex_A,24 fvset outer,dup_Vertex_B-dup_vx,dup_Vertex_B(1)-dup_vy,dup_Vertex_B(2)-dup_vz fvouter outer,dup_Vertex_C-dup_vx,dup_Vertex_C(1)-dup_vy,dup_Vertex_C(2)-dup_vz fvunit outer MeshNormalsList+=""+dup_outerx+";"+dup_outery+";"+dup_outerz+";," MeshNormalsIndex(index_cnt)=cnt,cnt,cnt MeshNormalsIndexCnt(cnt)=3 index_cnt+3 } loop poke MeshNormalsList,strlen(MeshNormalsList)-2,0 MeshNormalsMax=m_MeshVecIndexMax MeshNormalsIndexMax=m_MeshVecIndexMax }else{ MeshNormalsMax=m_MeshNormalsMax MeshNormalsIndexMax=m_MeshNormalsIndexMax MeshNormalsList_size=strlen(m_MeshNormalsList) sdim MeshNormalsList,MeshNormalsList_size+1 memcpy MeshNormalsList,m_MeshNormalsList,MeshNormalsList_size index_cnt=0 split m_MeshNormalsIndex,";,",mesh_mnli_str MeshNormalsIndex(m_MeshNormalsIndexMax*4)=0 MeshNormalsIndexCnt(m_MeshNormalsIndexMax)=0 repeat m_MeshNormalsIndexMax split mesh_mnli_str(cnt),";",mncnt_str,nid_str split nid_str,",",nid_str MeshNormalsIndexCnt(cnt)=0+mncnt_str repeat MeshNormalsIndexCnt(cnt) MeshNormalsIndex(index_cnt)=0+nid_str(cnt) //インデックスは整数型で保持 index_cnt++ loop loop } KeepID=xtxt_id xtxt_id++ return KeepID ////「mergexfiletextxt内で使用されるモジュール変数取得用」(単体では使用しない) //[ mod_getvec m_xfile, m_xpos, m_ypos, m_ypos ] // m_xfile : x形式のモデルテキストデータが格納される変数 // m_xpos : 移動X座標(実数) // m_ypos : 移動Y座標(実数) // m_ypos : 移動Z座標(実数) #modfunc mod_getvec var m_xfile,double m_xpos,double m_ypos,double m_zpos repeat MeshVecMax dup dup_MeshVecList,MeshVecList(cnt*3) m_xfile+=""+(dup_MeshVecList+m_xpos)+";"+(dup_MeshVecList(1)+m_ypos)+";"+(dup_MeshVecList(2)+m_zpos)+";," loop mod_getvi thismod return //回転付 #modfunc mod_getvecrot var m_xfile,double m_xpos,double m_ypos,double m_zpos,double m_xrot,double m_yrot,double m_zrot if m_xrot!0.0 or m_yrot!0.0 or m_zrot!0.0 { repeat MeshVecMax fvset fv,m_xrot, m_yrot, m_zrot dup dup_MeshVecList,MeshVecList(cnt*3) fvdir fv,dup_MeshVecList,dup_MeshVecList(1),dup_MeshVecList(2) m_xfile+=""+(fv+m_xpos)+";"+(fv(1)+m_ypos)+";"+(fv(2)+m_zpos)+";," loop }else{ repeat MeshVecMax dup dup_MeshVecList,MeshVecList(cnt*3) m_xfile+=""+(dup_MeshVecList+m_xpos)+";"+(dup_MeshVecList(1)+m_ypos)+";"+(dup_MeshVecList(2)+m_zpos)+";," loop } mod_getvi thismod return //回転とスケール付 #modfunc mod_getvecrotscale var m_xfile,double m_xpos,double m_ypos,double m_zpos,double m_xrot,double m_yrot,double m_zrot,double m_xscale,double m_yscale,double m_zscale if m_xrot!0.0 or m_yrot!0.0 or m_zrot!0.0 { repeat MeshVecMax fvset fv,m_xrot, m_yrot, m_zrot dup dup_MeshVecList,MeshVecList(cnt*3) fvdir fv,m_xscale*dup_MeshVecList,m_yscale*dup_MeshVecList(1),m_zscale*dup_MeshVecList(2) m_xfile+=""+(fv+m_xpos)+";"+(fv(1)+m_ypos)+";"+(fv(2)+m_zpos)+";," loop }else{ repeat MeshVecMax dup dup_MeshVecList,MeshVecList(cnt*3) m_xfile+=""+(m_xscale*dup_MeshVecList+m_xpos)+";"+(m_yscale*dup_MeshVecList(1)+m_ypos)+";"+(m_zscale*dup_MeshVecList(2)+m_zpos)+";," loop } mod_getvi thismod return //スケール付 #modfunc mod_getvecscale var m_xfile,double m_xpos,double m_ypos,double m_zpos,double m_xscale,double m_yscale,double m_zscale repeat MeshVecMax dup dup_MeshVecList,MeshVecList(cnt*3) m_xfile+=""+(m_xscale*dup_MeshVecList+m_xpos)+";"+(m_yscale*dup_MeshVecList(1)+m_ypos)+";"+(m_zscale*dup_MeshVecList(2)+m_zpos)+";," loop mod_getvi thismod return //頂点インデックスを文字列化 #modfunc mod_getvi index_cnt=0 mnindex_m_="" mvilist_m_="" mat_no_=mat_no_str(tfonoff_list(KeepID)) repeat MeshVecIndexMax if MeshVecIndexCnt(cnt)>3 { mnindex_m_+="4;"+(MeshNormalsIndex(index_cnt)+total_mnmax)+","+(MeshNormalsIndex(index_cnt+1)+total_mnmax)+","+(MeshNormalsIndex(index_cnt+2)+total_mnmax)+","+(MeshNormalsIndex(index_cnt+3)+total_mnmax)+";,\n" mvilist_m_+="4;"+(MeshVecIndexList(index_cnt)+total_mvecm)+","+(MeshVecIndexList(index_cnt+1)+total_mvecm)+","+(MeshVecIndexList(index_cnt+2)+total_mvecm)+","+(MeshVecIndexList(index_cnt+3)+total_mvecm)+";," index_cnt+4 }else{ mnindex_m_+="3;"+(MeshNormalsIndex(index_cnt)+total_mnmax)+","+(MeshNormalsIndex(index_cnt+1)+total_mnmax)+","+(MeshNormalsIndex(index_cnt+2)+total_mnmax)+";,\n" mvilist_m_+="3;"+(MeshVecIndexList(index_cnt)+total_mvecm)+","+(MeshVecIndexList(index_cnt+1)+total_mvecm)+","+(MeshVecIndexList(index_cnt+2)+total_mvecm)+";," index_cnt+3 } mmlist_m+mat_no_ loop strlen_mnindex_m=strlen(mnindex_m) strlen_mvilist_m=strlen(mvilist_m) memexpand mnindex_m,strlen_mnindex_m+strlen(mnindex_m_)+1 memcpy mnindex_m,mnindex_m_,strlen(mnindex_m_)+1,strlen_mnindex_m memexpand mvilist_m,strlen_mvilist_m+strlen(mvilist_m_)+1 memcpy mvilist_m,mvilist_m_,strlen(mvilist_m_)+1,strlen_mvilist_m mnlist_m+MeshNormalsList+";," mtexc_m+MeshUVList total_uvmax+MeshUVMax total_mvecm+MeshVecMax total_mvim+MeshVecIndexMax total_mnmax+MeshNormalsMax return ////「 endxfiletex実行時に登録テクスチャ画像情報を保存」(通常はendxfiletex実行時に呼び出されるので単体での使用はしない) //[ SaveXFileTexData fname ] // dfname : 登録テクスチャ画像情報を保存するファイル名 #deffunc SaveXFileTexData str fname if EndXFileTex_f { totaldivmax=divmax*divmax int_size=30*totaldivmax*4+10*4 double_size=totaldivmax*3*8+10*8 str_size=30*totaldivmax totalsavesize=int_size+double_size+str_size+4 sdim str_save,totalsavesize dupptr dup_int_save,varptr(str_save),int_size,4 dup_int_save=texsize,divmax,texdiv_index,uvofsindex,add_ofsv memcpy dup_int_save(4),tfname_index,30*totaldivmax*4 dupptr dup_double_save,varptr(str_save)+int_size,double_size,3 dup_double_save=divsize,RateUV,RateUVI,Reverse_posu,Reverse_posv,matsize_ex memcpy dup_double_save(10),texpos_u,totaldivmax*8 memcpy dup_double_save(totaldivmax+10),texpos_v,totaldivmax*8 memcpy dup_double_save(totaldivmax*2+10),RateUVIlist,totaldivmax*8 dupptr dup_str_save,varptr(str_save)+int_size+double_size,str_size,2 memcpy dup_str_save,tfname_list,str_size lpoke str_save,totalsavesize-4,totalsavesize bsave fname,str_save } return ////「 endxfiletex 実行時に保存されたデータファイルと画像を読み込み」(通常はstartxfiletexかsetupxfiletexdata実行時に呼び出されるので単体での使用はしない) //[ LoadXFileTexData dfname , pfname, setf ] // dfname : 登録テクスチャ画像情報のファイル名 // pfname : 登録テクスチャ画像のファイル名 // setf : テクスチャ用画像をbufferに読み込むか直接テクスチャにするか「0=bufferに読み込む、1=texload2でテクスチャ化」 //戻り値:statが-1ならデータファイルが無かった、setfが1の時はテクスチャIDが返る #deffunc LoadXFileTexData str dfname ,str pfname,int setf exist dfname if strsize<0 {return -1} _strsize=strsize texsize=0 EndXFileTex_f=0 sdim str_save,_strsize bload dfname,str_save,_strsize dupptr dup_int_totalsavesize,varptr(str_save)+_strsize-4,4,4 if dup_int_totalsavesize ! _strsize {dialog "データサイズが違うので読み込みを終了します。":return -1} dupptr dup_int_save,varptr(str_save),10*4,4 texsize=dup_int_save divmax=dup_int_save(1) texdiv_index=dup_int_save(2) uvofsindex=dup_int_save(3) add_ofsv=dup_int_save(4) gosub *sub_startxfiletex totaldivmax=divmax*divmax int_size=30*totaldivmax*4+10*4 double_size=totaldivmax*3*8+10*8 str_size=30*totaldivmax totalsavesize=int_size+double_size+str_size+4 dupptr dup_int_save,varptr(str_save),int_size,4 dim tfname_index,30*totaldivmax sdim tfname_list,30*totaldivmax ddim RateUVIlist,totaldivmax ddim texpos_u,totaldivmax ddim texpos_v,totaldivmax memcpy tfname_index,dup_int_save(4),30*totaldivmax*4 dupptr dup_double_save,varptr(str_save)+int_size,double_size,3 divsize=dup_double_save RateUV=dup_double_save(1) MarginUV=dup_double_save(2) Reverse_posu=dup_double_save(3) Reverse_posv=dup_double_save(4) matsize_ex=dup_double_save(5) ruvsize=RateUV/divsize hggetreq filter,SYSREQ_3DFILTER RateUVI=RateUV //右下側の変換する倍率 RateUVI-=RateUVI*0.00001 //逆方向に貼られたテクスチャが1ラインずれるのを軽減 MarginUV=(RateUV*(filter>1)/divsize)/2 //テクスチャ補間モードが有効の場合隣のドットを巻き込むのを軽減 RateUVI-=MarginUV*2 memcpy texpos_u,dup_double_save(10),totaldivmax*8 memcpy texpos_v,dup_double_save(totaldivmax+10),totaldivmax*8 memcpy RateUVIlist,dup_double_save(totaldivmax*2+10),totaldivmax*8 dupptr dup_str_save,varptr(str_save)+int_size+double_size,str_size,2 memcpy tfname_list,dup_str_save,str_size if setf=0 { celload pfname,XFILETEX_BUFFER_ID}else{ gsel_bak=ginfo_sel buffer XFILETEX_BUFFER_ID,1,1 gsel gsel_bak texload2 pfname,texsize,texsize:return stat} return 0 //「テンプレート検索して位置を返し区切り文字までを取得」(addxfiletex内で使用される関数) //変数 = TemplateSearch(文字列取得変数 ,検索する文字列型変数,検索開始位置, 検索文字列, tplからSeparatorまでに含まれてたらスキップする文字列, 文字列取得区切り文字列, 取得時の区切り文字の扱い) //NotIncが1以上の数字だった場合その数字以上なら検索成功とする //取得成功したら検索開始位置が区切り文字を含めた位置の右まで移動します //statにも検索文字位置が返り //取得できなかった場合-1 //addendの設定値は0,1,2「0=Separator文字は含め無い、1=Separator文字も含めて取得、2=txt_indexにSeparatorの文字数を加算しない」 #defcfunc TemplateSearch var _refstr,var xtxt,var txt_index,str tpl,str NotInc,str Separator,int addend spadd=strlen(Separator) nv=int(NotInc) repeat tpl_addindex=instr(xtxt,txt_index,tpl) if tpl_addindex<0 { _refstr="" _stat=-1 break }else{ _stat=txt_index+tpl_addindex txt_index=_stat+instr(xtxt,_stat,"{")+1 addindex=instr(xtxt,txt_index,Separator) _refstr=strmid(xtxt,txt_index,addindex+spadd*(addend=1)) if nv=0 { if instr(_refstr,0,NotInc)<0 { txt_index+=addindex+spadd*(addend!2) break } }else{ if nv<=_refstr { txt_index+=addindex+spadd*(addend!2) break } } } txt_index+addindex+spadd loop return _stat #global



この記事に返信する


暇人

リンク

2016/4/8(Fri) 00:06:09|NO.75193

とりあえず簡単なサンプル

NO.75192のモジュールをファイル名 mod_addxfiletex.hsp として保存して実行してください


#include "hgimg3.as" //必ずhgimg3の後にmod_addxfiletexをインクルードしてください。 #include "mod_addxfiletex.hsp" screen 0,800,600,0 hgini dircur=dir_cur chdir dir_exe+"\\sample\\hgimg3\\" //xfileのあるディレクトリに移動 divsize=64 //マテリアル1枚の画像サイズ texsize=2048 //全体のテクスチャサイズ //StartXFileTex 全体のテクスチャサイズ,マテリアル1枚の画像サイズ」 StartXFileTex texsize,divsize //テクスチャサイズを設定して登録開始(必ずhginiの後に実行) //通常のaddXFileと同等の使い方(テクスチャサイズはdivsize設定値になる) addXFileTex m_sb_bg,"sb_bg1.x" //これでsb_bg1.x内にあるテクスチャ画像が登録されて編集されたUV値でモデルが作られる notesel xfile noteload "font_a.x" //変数内のX形式データでモデル作成 addXFileTexVar m_font_a,xfile //上で処理したデータがMEM_XFILEに入ってるので板の頂点データにして配列に入れる //「GetXFilePlateVec 受け取る実数型配列,取得した板の数,X形式データ,リサイズ+中心に配置,最大サイズ」 font_a_size=15.0 //マテリアルサイズとしても使用 GetXFilePlateVec font_a_vec,font_a_max,MEM_XFILE,1+2,font_a_size //三角形も4頂点にするので、1面3頂点で作られたモデルの場合頂点数が増える //--------板の頂点データをX形式データにする。ついでにテクスチャを張る PlateDirTex 1,"chrome.bmp","chrome.bmp","btex.bmp","btex.bmp","chrome.bmp","chrome.bmp" //面方向ごとに使用する画像ファイル //「MakeXFilePlate 受け取る変数,頂点データ配列,作る板の数, 省略 , 省略 ,マテリアルサイズ,モデルの中心X,モデルの中心Y,モデルの中心Z」 MakeXFilePlate font_a_xfile,font_a_vec,font_a_max, , ,font_a_size,font_a_size/2,font_a_size/2,font_a_size/2 //MakeXFilePlateで作られたモデルデータは板同士の頂点共有が無いので見た目フラットシェーディングになる addXFileTexVar m_Plate_font_a,font_a_xfile //通常とは別のサイズでマテリアルテクスチャ画像を登録する設定 SetMaterialSizeExtra 256 //「addXFileTex ID受け取り変数,XFile名,ハーフトーン+追加サイズを使用」 addXFileTex m_skybox,"skybox.x",1+2 //画像が長方形でも登録は正方形になる(追加サイズを使用した場合右下から埋められる) //MakeXFileBoxで使用する画像とバッファ //bufferID3は、このモジュール内やhgimg3.as内で作業用に使われてるのでメイン側でID3は使用しないようにしてください celload dir_exe+"\\hsptv\\hsptv_img.bmp",1 //画像ファイルとバッファ内画像を指定する変数 tfname={" sb_bg1.bmp btex.bmp buffer.1,128,320,64,64 buffer.1,192,320,64,64 buffer.1,256,320,64,64 buffer.1,320,320,64,64 "} box_size=10.0 //テクスチャサイズに使用(モデルサイズを省略するのでモデルサイズとしても使われる) //「MakeXFileBox 受け取る変数, テクスチャファイル名, テクスチャ最大サイズ」 MakeXFileBox xfile_box, tfname,box_size addXFileTexVar m_box,xfile_box // 上のMakeXFileBoxで作ったBOXデータの画像ファイル名を全て差し替える addXFileTexVar m_efx,xfile_box,1,"efx.bmp\nefx.bmp\nefx.bmp\nefx.bmp\nefx.bmp\nefx.bmp" chdir dircur //移動前に戻す //「EndXFileTex テクスチャID受け取り変数」 EndXFileTex id //テクスチャ画像登録終了 //オブジェクト作成はEndXFileTex実行後にしないと正しいテクスチャIDが設定されません modelshade m_skybox,0 regobj skybox, m_skybox setscale skybox,30,30,30 setpos skybox,0,20,0 setefx skybox,$500 ; Zバッファを更新しない objproj skybox,1 ; 通常のZクリップを無効にする regobj sb_bg, m_sb_bg setscale sb_bg,3,3,3 setpos sb_bg,0,100,0 regobj font_a, m_font_a setpos font_a,-30,-70,-80 regobj Plate_font_a, m_Plate_font_a setpos Plate_font_a,-10,-70,-80 regobj box, m_box setpos box,10,-70,-80 modelshade m_efx,0 regobj efx, m_efx,OBJ_LATE setpos efx,30,-70,-80 setefx efx,512+255 setdir HGOBJ_LIGHT,80,80,80 setang HGOBJ_CAMERA, -0.2, 0, 0 setpos HGOBJ_CAMERA, 0, -100, 0 screen 2,512,512,0,ginfo_wx2,ginfo_wy1//登録された画像を別ウィンドウにコピー gzoom 512,512,XFILETEX_BUFFER_ID,0,0,texsize,texsize,1 gsel 0 *main stick key,$ff if key&128 : end ; モデルを回転させる addang font_a,0.01,0.005 addang Plate_font_a,0.01,0.005 addang box,0.01,0.005 addang efx,0.01,0.005 hgdraw ; 描画 hgsync 15 ; 時間待ち if key&64 { if key&1 : addpos HGOBJ_CAMERA, -0.5, 0.0 if key&4 : addpos HGOBJ_CAMERA, 0.5, 0.0 if key&2 : addpos HGOBJ_CAMERA, 0.0,, -0.5 if key&8 : addpos HGOBJ_CAMERA, 0.0,, 0.5 } else { if key&2 : addang HGOBJ_CAMERA, -0.01, 0.0 if key&8 : addang HGOBJ_CAMERA, 0.01, 0.0 if key&4 : addang HGOBJ_CAMERA, 0.0, 0.01 if key&1 : addang HGOBJ_CAMERA, 0.0, -0.01 } goto *main



暇人

リンク

2016/4/8(Fri) 22:49:49|NO.75196

モジュールの仕様上の制限を書いてなかったので書いてみる
オブジェクトにテクスチャIDが設定されるのは最初にテクスチャが設定されてるノードのみです。
モデル一つに設定できる拡散光は一つです。(なのでサンプルフォルダhgimg3内にあるeye.xは真っ白)
二つ以上のノードにテクスチャIDを設定したい場合は個別に対応してください。
KeepXFileTexTXTで保持されるのは頂点座標、頂点インデックス、法線、法線インデックス、UV値です。
アニメーションデータは保持しません。
MergeXFileTexTXTで回転させたモデルデータの法線は回転してないのでhgsetreqで法線再計算を設定してください
まだあった気がするけど思い出せない・・・


KeepXFileTexTXTとMergeXFileTexTXTを使うサンプル

#include "hgimg3.as" //必ずhgimg3の後にmod_addxfiletexをインクルードしてください。 #include "mod_addxfiletex.hsp" screen 0,1024,768,0 hgini hgsetreq SYSREQ_CALCNORMAL,1 //法線再計算 dircur=dir_cur chdir dir_exe+"\\sample\\hgimg3\\" //xfileのあるディレクトリに移動 divsize=64 //マテリアル1枚の画像サイズ texsize=2048 //全体のテクスチャサイズ //StartXFileTex 全体のテクスチャサイズ,マテリアル1枚の画像サイズ」 StartXFileTex texsize,divsize //テクスチャサイズを設定して登録開始(必ずhginiの後に実行) //通常とは別のサイズでマテリアルテクスチャ画像を登録する設定 SetMaterialSizeExtra 256 //「addXFileTex ID受け取り変数,XFile名,ハーフトーン+追加サイズを使用」 addXFileTex m_skybox,"skybox.x",1+2 //画像が長方形でも登録は正方形になる(追加サイズを使用した場合右下から埋められる) //「addXFileTex ID,モデルファイル名,追加サイズ使用+マイナスV値反転」 addXFileTex m_tamane,"tamane_w.x",2+16 //UV値編集済みデータ(MEM_XFILE)をサイズ計算ありでモジュール内に保持 //「KeepXFileTexTXT 保持するモデルデータ,サイズ計算」 KeepXFileTexTXT MEM_XFILE,1 XFileID_tamane=stat //データID getScaleFactor_model tamane_sf //サイズ計算したモデルをサイズ1.0にするスケールを取得 //12面ダイスを作る buffer 11,512,512 color 200,0,255 boxf picload dir_exe+"\\sample\\hgimg4\\res\\ball64.png",1 //ball64.pngに真っ黒が使われてるため色が抜けてしまうので修正する buffer 10,512,512 color 2,2,2 boxf gmode 2 gcopy 11,0,0,512,512 repeat 12//使用する画像リスト作成 settf(cnt)="buffer.10,"+((cnt+1)\8)*64+","+((cnt+1)/8)*64+",64,64" loop //「addTexPic 取得する配列,画像ファイル名が入ってる配列,登録する画像の枚数」 addTexPic tex_idlist,settf,12 //画像を登録してインデックスリスト取得 //12面ダイスの1面の座標 R720=deg2rad(72.0) siz=1.0/2 //面の半径 repeat 5 vecx(cnt)=sin(-R720*cnt)*siz+siz vecy(cnt)=cos(-R720*cnt)*siz+siz loop ddim xyzvec,12*2 xyzvec=vecx(0),vecy(0),0.0 ,vecx(1),vecy(1),0.0 ,vecx(4),vecy(4),0.0 ,vecx(0),vecy(0),0.0 //4頂点で5角形の上の三角形 xyzvec(4*3)=vecx(1),vecy(1),0.0 ,vecx(2),vecy(2),0.0 ,vecx(3),vecy(3),0.0 ,vecx(4),vecy(4),0.0//4頂点で下の台形 //12面ダイスの1面毎にmakexfilePlateでXfileデータ化してKeepXFileTexTXTで保持して、面毎の座標と角度を配列に入れる R635=deg2rad(63.5) ddim xyzposlist,12*3+1 //fv系の命令がfv(3)までいじってるからか終了時にエラーが出るので余分に確保 repeat 12 //1の裏側が12、2の裏側が11になるようにテクスチャインデックス取り出し if xfileidmax\2 {tex_index=tex_idlist(11-xfileidmax/2)}else{tex_index=tex_idlist(xfileidmax/2)} //実数配列の頂点座標をXfileデータ化 makexfilePlate xfile,xyzvec,2,tex_index, ,siz*2,siz,siz,0.0 //画像がファイル名じゃ無くインデックスの場合UV値はテクスチャ1枚用になる KeepXFileTexTXT xfile //Xfileデータを保持してデータID取得 xfiteid(xfileidmax)=stat //面毎の位置と回転角度を配列に入れる dup dup_fv,xyzposlist(xfileidmax*3) //奇数回は偶数の裏側の座標を算出 fvset dup_fv,M_PI/2.0-R635*(cnt>1)+M_PI*(cnt\2),M_PI*(cnt>1)-R720*limit(cnt/2-1,0,6),0.0 fvdir dup_fv,0,0,siz*0.6535*2.0 xyzrotlist(xfileidmax*3)=M_PI/2.0-R635*(cnt>1)+M_PI*(cnt\2),M_PI*(cnt>1)+R720*limit(cnt/2-1,0,6),0.0 xfileidmax++ loop //12面分のデータを統合(統合時に法線は回転しないのでhgsetreqで法線再計算を設定してください) MergeXFileTexTXT xfile_dice12, xfiteid,xfileidmax, 0, xyzposlist, xyzrotlist //「addXFileTexVar ID取得用変数,UV値編集済みモデルデータ,画像登録等処理せずにモデル作成してテクスチャ使用フラグを立てる」 addXFileTexVar m_dice12,xfile_dice12,512 //UV値編集済みデータの時は512を指定 //完成したモデルデータをサイズ計算ありでモジュール内に保持 //「KeepXFileTexTXT 保持するモデルデータ,サイズ計算」 KeepXFileTexTXT xfile_dice12,1 XFileID_dice12=stat getScaleFactor_model dice12_sf //サイズ計算したモデルをサイズ1.0にするスケールを取得 chdir dircur EndXFileTex id //オブジェクト作成はEndXFileTex実行後にしないと正しいテクスチャIDが設定されません gsel 0 modelshade m_skybox,0 regobj skybox, m_skybox setscale skybox,30,30,30 setpos skybox,0,20,0 setefx skybox,$500 ; Zバッファを更新しない objproj skybox,1 ; 通常のZクリップを無効にする //MergeXFileTexTXTで回転させて統合させる場合デフォルトのモデルと同じ回転順にする必要がある modelorder m_dice12,0 regobj dice12, m_dice12 setpos dice12,-1,0,0 setscale dice12,dice12_sf,dice12_sf,dice12_sf modelorder m_tamane,0 regobj tamane, m_tamane setpos tamane,1,0,0 setscale tamane,tamane_sf,tamane_sf,tamane_sf setdir HGOBJ_LIGHT,100,100,100 clscolor $4444 ; 背景色の設定 setang HGOBJ_CAMERA, -0.0, 0, 0 setpos HGOBJ_CAMERA, 0, -0, 5 objsize 150,24 button gosub "統合モデル作成",*_Merge screen 2,512,512,0,ginfo_wx2,ginfo_wy1 gzoom 512,512,XFILETEX_BUFFER_ID,0,0,texsize,texsize,1 gsel 0 *main stick key,$ff if key&128 : goto *owari ; モデルを回転させる addang dice12,0.01,0.005 addang tamane,0.01,0.005 hgdraw ; 描画 hgsync 15 ; 時間待ち if key&64 { if key&1 : addpos HGOBJ_CAMERA, -0.1, 0.0 if key&4 : addpos HGOBJ_CAMERA, 0.1, 0.0 if key&2 : addpos HGOBJ_CAMERA, 0.0,, -0.1 if key&8 : addpos HGOBJ_CAMERA, 0.0,, 0.1 } else { if key&2 : addang HGOBJ_CAMERA, -0.01, 0.0 if key&8 : addang HGOBJ_CAMERA, 0.01, 0.0 if key&4 : addang HGOBJ_CAMERA, 0.0, 0.01 if key&1 : addang HGOBJ_CAMERA, 0.0, -0.01 } goto *main *_Merge if m_Merge {delmodel m_Merge} pxyz=0.0 axyz=0.0 sxyz=0.0 getpos tamane,pxyz,pxyz(1),pxyz(2) //実数型に初期化されてないと配列にデータは入らない getang tamane,axyz,axyz(1),axyz(2) getscale tamane,sxyz,sxyz(1),sxyz(2) getpos dice12,pxyz(3),pxyz(4),pxyz(5) getang dice12,axyz(3),axyz(4),axyz(5) getscale dice12,sxyz(3),sxyz(4),sxyz(5) XFileID_list=XFileID_tamane,XFileID_dice12 MergeXFileTexTXT xfile_Merge, XFileID_list ,2, 0, pxyz, axyz, sxyz //100頂点で1ms程度かかる addXFileTexVar m_Merge,xfile_Merge,512 //addXFile命令自体が200ポリゴンで10ms程度かかる regobj Merge, m_Merge setpos Merge,0,-1,0 return *owari end



暇人

リンク

2016/4/14(Thu) 00:26:29|NO.75221

NO.75192のモジュールにまだバグがありました
再度StartXFileTexした時にモジュール変数を初期化してなかった
>*sub_startxfiletex
の下に

dimtype Meshdata,5,xtxt_id
を追加

MakeXFileBoxで使用してる変数をMakeXFilePlate内で初期化してしまってた
>sdim xbox_vindex,64,Platemax
を検索して削除



エリア分けしてカーソルが無い所は1モデルにするサンプル(上の修正をしなくても動きます)
通常1万個ぐらいのオブジェクトが必要な所を300個ぐらいに抑える
1エリア1モデルの所は少し赤っぽくしてます

#include "hgimg3.as" #module //[---モジュールの初期化---] //cnvsptowp_init //必ずhginiの後に実行(カメラのefxグループを変更したりスクリーンサイズを変更した時も実行する必要がある) //返り値refdvalにスクリーン座標系から3D座標系に変換する実数値が返る //refdval*スクリーン座標*カメラからの距離で2Dから3Dに出来る #deffunc cnvsptowp_init getefx HGOBJ_CAMERA,FOV,NearZ,FarZ ssx=1.0*ginfo_sx ssy=1.0*ginfo_sy whsx=0.5*ssx whsy=0.5*ssy wwx=ssx/ginfo_winx wwy=ssy/ginfo_winy tc=sin(0.5*FOV)/cos(0.5*FOV)/whsy return tc //[---スクリーン座標をワールド座標に変換---] //fvstw wp, sx, sy, cdz // wp = 3D座標を取得する配列(wp=x,y,z) // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 // cdz = カメラからの距離を3D座標系で指定(プラスがカメラの前方向) //カメラの移動回転に対応 #deffunc fvstw array wp,double sx,double sy,double cdz getpos HGOBJ_CAMERA,cpx,cpy,cpz getang HGOBJ_CAMERA,crx,cry,crz fvset wp,crx,-cry,crz fvdir wp,(((sx-whsx/wwx)*cdz*tc)*wwx),(sy-whsy/wwy)*cdz*tc*wwy,-cdz fvadd wp,cpx,cpy,cpz return //[---スクリーン座標からレイを飛ばすベクトルを取得---] //fvray rvec, sx, sy, cdz // rvec = レイのベクトル(rvec=vx,vy,vz) // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 // cdz = カメラからの距離を3D座標系で指定 //カメラの移動回転に対応 #deffunc fvray array rvec,double sx,double sy getang HGOBJ_CAMERA,crx,cry,crz fvset rvec,crx,-cry,crz fvdir rvec,(((sx-whsx/wwx)*tc)*wwx),(sy-whsy/wwy)*tc*wwy,-1.0 return //[---スクリーン座標からレイを飛ばしてワールドY座標が0になる時のワールドX,Z座標を取得---] //getRayPos wpx, wpy, wpz, sx, sy // wpx = 3DX座標を取得 // wpy = 3DY座標を取得 // wpz = 3DZ座標を取得 // sx = スクリーンX座標指定 // sy = スクリーンY座標指定 //カメラの移動回転に対応 #deffunc getRayPos var wpx,var wpy,var wpz,double sx,double sy fvray _rvec, sx, sy getpos HGOBJ_CAMERA,cpx,cpy,cpz if 0.0 = _rvec(1) {_rvec(1)=0.00000001}//_rvec(1)が0.0だと次の行で割り算に使えないので適当な小さい数値を入れる(これは地面方向の傾きが0の時の対策) dis=-cpy/_rvec(1) //カメラの高さをレイのYで割るとY座標0までのカメラからの距離が出る fvmul _rvec,dis,dis,dis //レイの方向ベクトルに距離を掛ければワールド座標になる fvadd _rvec,cpx,cpy,cpz //カメラ座標を足してカメラを基準にした座標にする (この二行は fvstw _rvec,sx,sy,dis に置き換ても同等の事が出来る) wpx=_rvec wpy=_rvec(1) wpz=_rvec(2) return #global #module //[---上右下左の順にエリアインデックスを取得するための設定初期化---] //「 setAreaIndex AMax, AStartX, AStartY 」 // AMax : 一列のエリア数 // ARMax : 取得するエリア範囲 // AStartX : エリアインデックスを取得する最初の横インデックス // AStartY : エリアインデックスを取得する最初の縦インデックス #deffunc setAreaIndex int AMax,int ARMax,int AStartX,int AStartY AreaMax=AMax AreaRangeMax=limit(ARMax,2,AMax) looptotal= AreaRangeMax*AreaRangeMax-(AreaRangeMax-2)*(AreaRangeMax-2) loopindex=0 loopline=0 loopmax=0 loopend=0 AreaStartX=AStartX AreaStartY=AStartY return //[---エリアインデックスを上右下左の順に取得---] //「 getAreaIndex AreaX, AreaY 」 // AreaX : 横のエリアインデックス // AreaY : 縦のエリアインデックス //戻り値 : statが0なら続きが有る1なら終了 //補足1:取得するエリア範囲が偶数の場合 // 12, 4, 8, 13 // 11, 0, 1, 5 // 7, 3, 2, 9 // 15,10, 6, 14 //補足2:取得するエリア範囲が奇数の場合 // 8,1,5 // 4,0,2 // 7,3,6 //の順でインデックスが返る #deffunc getAreaIndex var AreaX,var AreaY repeat if loopindex>=looptotal {loopend=1:break } if loopindex>=loopmax { loopindex=0 if loopline=0 {if AreaRangeMax\2 {loopline=1}else{loopline=2}}else{loopline+2} loopmax= loopline*loopline-(loopline-2)*(loopline-2) } dir=loopindex\4 loopcnt=loopindex/4 if ((loopindex+2)\8)<4{looppos=-((1+loopcnt)/2)}else{looppos=((1+loopcnt)/2)} if (AreaRangeMax\2) { if (dir\2)=0 { if dir=0 {AreaX=looppos:AreaY=-(loopline/2)}else{AreaX=looppos:AreaY=((loopline)/2)} }else{ if dir=1 {AreaX=((loopline)/2):AreaY=looppos}else{AreaX=(-loopline/2):AreaY=looppos} } }else{ if (dir\2)=0 { if dir=0 {AreaX=looppos-1:AreaY=-(loopline/2)}else{AreaX=looppos:AreaY=((loopline-1)/2)} }else{ if dir=1 {AreaX=((loopline-1)/2):AreaY=looppos-1}else{AreaX==(-(loopline)/2):AreaY=looppos} } } loopindex++ AreaX+AreaStartX if AreaX<0 or AreaX>=AreaMax {continue } AreaY+AreaStartY if AreaY<0 or AreaY>=AreaMax {continue } break loop return loopend #global #include "mod_addxfiletex.hsp" screen 0,1280,720,0 AreaSize=8 //1エリアの一辺のオブジェクト数 AreaMax=10 //マップ一列のエリア数 mapmax=AreaSize*AreaMax //マップ一列のオブジェクト数 dim mapdat,mapmax,mapmax,2 dim Areadat,AreaMax,AreaMax memset Areadat,-1,AreaMax*AreaMax*4 ddim objpxyz,3*AreaSize*AreaSize*2 //エリアモデルデータ作成時に使用する座標用配列 hgsetreq SYSREQ_MAXOBJ,AreaSize*AreaSize*2+AreaMax*AreaMax+1000 hgsetreq SYSREQ_COLORKEY hgini //必ずhginiの後に実行(カメラのefxグループを変更したりスクリーンサイズを変更した時も実行) cnvsptowp_init dircur=dir_cur chdir dir_exe+"\\sample\\hgimg3\\" //画像ファイルのあるディレクトリに移動 divsize=64 //マテリアル1枚の画像サイズ texsize=2048 //全体のテクスチャサイズ chpsize=1.0 //モデル一つのサイズ //StartXFileTex 全体のテクスチャサイズ,マテリアル1枚の画像サイズ」 StartXFileTex texsize,divsize //テクスチャサイズを設定して登録開始(必ずhginiの後に実行) xyzvec=0.0,0.0,0.0, 0.0,0.0,chpsize, chpsize,0.0,chpsize, chpsize,0.0,0.0 //板一枚の頂点座標 tf="temp.bmp" //TextureFilenameを使用するので適当にファイル名を指定(モデルを作るときに差し替える) makexfilePlate xfile,xyzvec,1,tf, ,chpsize,chpsize/2,0.0,chpsize/2 //settfに使用するファイル名を入れておく settf(settf_cnt)="btex.bmp" settf_cnt++ //bufferに画像を読み込んでsettfにbufferをファイル名として入れておく celload dir_exe+"\\hsptv\\hsptv_img.bmp",1 repeat 11,5*8+2 settf(settf_cnt)="buffer.1,"+(cnt\8)*64+","+(cnt/8)*64+",64,64" //画像のオフセットとサイズも指定 settf_cnt++ loop CharIndex=1 //キャラのインデックス(0は無しなので1から) repeat 12 //地面用に12枚の板モデルを作る addXFileTexVar mid_list(CharIndex),xfile,0,settf(cnt) //テクスチャファイルをsettfに差し替え modelorder mid_list(CharIndex),HGMODEL_ROTORDER_ZYX KeepXFileTexTXT MEM_XFILE //作られたモデルの基データをモジュール内に保持(モデル作成と対で実行してるのでモデルIDとデータインデックスが同じになる) CharIndex++ loop MakeXFileBox xfile_bax, "",chpsize //箱モデルテキストデータ作成(頂点データ抜き出し用) boxsize=chpsize/2 //上物用の箱のサイズ GetXFilePlateVec xyzvec,vecmax,xfile_bax,1,boxsize //リサイズして頂点座標取得 makexfilePlate xfile,xyzvec,vecmax,tf, ,boxsize,boxsize/2,0.0,boxsize/2 //上物用の箱データをY軸の中心を下にして作成 ObjectStartIndex=CharIndex //最初の上物キャラインデックス repeat 6,7*8+2 addXFileTexVar mid_list(CharIndex),xfile,0,"buffer.1,"+((cnt\8)*64)+","+((cnt/8)*64)+",64,64" modelorder mid_list(CharIndex),HGMODEL_ROTORDER_ZYX KeepXFileTexTXT MEM_XFILE CharIndex++ loop xyzvec=0.0,chpsize,chpsize/2, 0.0,0.0,chpsize/2, chpsize,0.0,chpsize/2, chpsize,chpsize,chpsize/2 //板一枚の頂点座標 xyzvec(12)=chpsize/2,chpsize,0.0, chpsize/2,0.0,0.0, chpsize/2,0.0,chpsize, chpsize/2,chpsize,chpsize //板一枚の頂点座標 tf="tree.tga" //テクスチャファイル flip=32 //面を両面化 makexfilePlate xfile_tree,xyzvec,2,tf,flip,chpsize,chpsize/2,0.0,chpsize/2 //ターゲットカーソルモデルデータ作成 addXFileTexVar mid_list(CharIndex),xfile_tree,0 modelorder mid_list(CharIndex),HGMODEL_ROTORDER_ZYX KeepXFileTexTXT MEM_XFILE CharIndex++ //ターゲットカーソル用画像 buffer 1,divsize,divsize color 0,255,0 gradf 0,0,divsize,divsize color 0,0,0 gradf 2,2,divsize-4,divsize-4 gsel 0 tcsize=chpsize*1.01 //ターゲットカーソル用に少し大きくする GetXFilePlateVec xyzvec,vecmax,xfile_bax,1,tcsize //上で作っといた箱データをリサイズして頂点座標取得 tf="buffer.1" //テクスチャファイル flip=32 //全ての面を両面化 makexfilePlate xfile_box,xyzvec,vecmax,tf,flip,tcsize,tcsize/2,0.0,tcsize/2 //ターゲットカーソルモデルデータ作成 addXFileTexVar m_tcid,xfile_box modelshade m_tcid,0 chdir dircur EndXFileTex id //適当にキャラIDセット repeat mapmax y=cnt repeat mapmax cid=1+rnd(ObjectStartIndex-1) mapdat(cnt,y,0)=cid if rnd(100)<50 {//上物 cid=ObjectStartIndex+rnd(CharIndex-ObjectStartIndex) mapdat(cnt,y,1)=cid } loop loop //オブジェクト削除用イベント newevent ev_objdel event_delobj ev_objdel //描画してから削除されるのを利用する //ターゲットカーソル用半透イベント newevent ev_efx event_setefx ev_efx,512+255 event_efx ev_efx,20,512+100 event_wait ev_efx,20 event_efx ev_efx,20,512+255 event_wait ev_efx,20 event_jump ev_efx,1 //3Dカーソル用イベント newevent ev_Cursor event_addang ev_Cursor,0.0,0.1,0.0 event_wait ev_Cursor,1 event_jump ev_Cursor,0 addbox mbid,chpsize*0.1,chpsize*0.1 regobj bid,mbid ,,ev_Cursor//3Dカーソル代わりのボックス regobj tcid,m_tcid,OBJ_LATE,ev_efx //ターゲットカーソル setpos HGOBJ_CAMERA,chpsize*mapmax/2,-chpsize*20,chpsize*mapmax/2 setang HGOBJ_CAMERA,-1.4 clscolor $4444 ; 背景色の設定 setscale HGOBJ_LIGHT,255,255,255 setdir HGOBJ_LIGHT,90,90,90 gsel 0 screen 4,512,512,0,ginfo_wx2,ginfo_wy1 gzoom 512,512,XFILETEX_BUFFER_ID,0,0,texsize,texsize,1 gsel 0 setAreaIndex AreaMax,AreaMax/2,AreaMax/2,AreaMax/2 repeat stick k,$fff sx=mousex sy=mousey if k&1 {addpos HGOBJ_CAMERA,-0.1,0.0,0.0} if k&4 {addpos HGOBJ_CAMERA,0.1,0.0,0.0} if k&2 {addpos HGOBJ_CAMERA,0.0,0.0,-0.1} if k&8 {addpos HGOBJ_CAMERA,0.0,0.0,0.1} addpos HGOBJ_CAMERA,0.0,-0.01*mousew,-0.01*mousew if k&512 { if rc=0{ sx1=sx sy1=sy rc=1 }else{ addang HGOBJ_CAMERA,0.01*(sy1-sy),0.01*(sx1-sx),0.0 sx1=sx sy1=sy } }else{ rc=0 } //カメラ操作が終ってから実行 getRayPos wpx, wpy, wpz, sx, sy setpos bid,wpx, wpy, wpz mapx=limit((wpx+chpsize/2)/chpsize,0,mapmax-1) mapy=limit((wpz+chpsize/2)/chpsize,0,mapmax-1) //3Dカーソルがあるエリアインデックス算出 AreaX=mapx/AreaSize AreaY=mapy/AreaSize AreaRegobjON=0 //エリアモデルが作られたら1にする if AMMax { AMMax-- if Areadat(AreaX_list(AMMax),AreaY_list(AMMax))=$7fffffff { addXFileTexVar m_Merge,xfile_Merge(AMMax),512 regobj oid,m_Merge //3Dカーソル代わりのボックス Areadat(AreaX_list(AMMax),AreaY_list(AMMax))=oid //エリアモデル一つならオブジェクトIDをセット AreaRegobjON=1 } } if ((AreaX_bak ! AreaX) or (AreaY_bak ! AreaY)) {//前回の選択エリアと違った if (Areadat(AreaX_bak,AreaY_bak)=0){//前回の選択エリアが個別オブジェクトだった repeat aoid_max oid=Areaobjid(cnt) getobjmodel objdid_list(cnt),oid dup dup_objpxyz,objpxyz(cnt*3) getpos oid,dup_objpxyz,dup_objpxyz(1),dup_objpxyz(2) setevent oid,ev_objdel,-1 //このフレームでは描画されるので次のフレームでエリアモデルを作れば良い loop SetXFileDiffusedLight 1,255,150,150 //赤っぽい拡散光設定 MergeXFileTexTXT xfile_Merge(AMMax), objdid_list ,aoid_max, 0, objpxyz //エリアモデルデータ作成してリストに保持 AreaX_list(AMMax)=AreaX_bak //エリアモデルのインデックスをリストに保持 AreaY_list(AMMax)=AreaY_bak AMMax++ //保持中のエリアモデルデータ数 Areadat(AreaX_bak,AreaY_bak)=$7fffffff //モデルデータが作られた AreaRegobjON=1//次のフレームでこのエリアモデル作成したいので未処理エリアの処理を飛ばすフラグ } //現在のエリアインデックスを設定して未処理エリアインデックス取得用の設定にする setAreaIndex AreaMax,AreaMax/2,AreaX,AreaY oid=Areadat(AreaX,AreaY) if oid ! 0 {//個別オブジェクトエリア以外だった if oid>0 {//エリアオブジェクトかもしれない if oid!$7fffffff {//エリアオブジェクトだったので削除 getobjmodel mid,oid delobj oid delmodel mid } } //個別オブジェクトエリア処理 AreaX_bak = AreaX AreaY_bak = AreaY Areadat(AreaX,AreaY) =0 //個別オブジェクトエリアなので0をセット aoid_max=0 //いまから作る個別オブジェクト数用 index_x=AreaX*AreaSize index_y=AreaY*AreaSize x=AreaX*AreaSize y=index_y repeat AreaSize //マップ縦方向 repeat AreaSize,index_x //マップ横方向 cid=mapdat(cnt,y,0) regobj pid,mid_list(cid) setcoli pid,128,1 setpos pid,chpsize*cnt,0.0,chpsize*y Areaobjid(aoid_max)=pid aoid_max++ cid=mapdat(cnt,y,1) if cid{ regobj pid,mid_list(cid)//, OBJ_SORT setcoli pid,256,1 setpos pid,chpsize*cnt,0.0,chpsize*y Areaobjid(aoid_max)=pid aoid_max++ } loop y++ loop } } if AreaRegobjON=0 {//今フレームではエリアモデルは作られてない(モデルデータ作成とモデル作成が交互になるように) getAreaIndex AreaX,AreaY //今回処理するエリアインデックス取得 if stat=0 { //未処理エリアをモデル一つで作る if Areadat(AreaX,AreaY)<0 {//未処理エリアだった Mergemax=0 index_x=AreaX*AreaSize index_y=AreaY*AreaSize x=AreaX*AreaSize y=index_y repeat AreaSize //マップ縦方向 repeat AreaSize,index_x //マップ横方向 cid=mapdat(cnt,y,0) did_list(Mergemax)=mid_list(cid) pxyz(Mergemax*3)=1.0*cnt,0.0,1.0*y Mergemax++ cid=mapdat(cnt,y,1) if cid{ did_list(Mergemax)=mid_list(cid) pxyz(Mergemax*3)=1.0*cnt,0.0,1.0*y Mergemax++ } loop y++ loop SetXFileDiffusedLight 1,255,150,150 //赤っぽい拡散光設定 MergeXFileTexTXT xfile_Merge(AMMax), did_list ,Mergemax, 0, pxyz //エリアモデルデータ作成してリストに保持 AreaX_list(AMMax)=AreaX //エリアモデルのインデックスをリストに保持 AreaY_list(AMMax)=AreaY AMMax++ //保持中のエリアモデルデータ数 Areadat(AreaX,AreaY)=$7fffffff //モデルデータが作られた } } } //3Dカーソルとの当たり判定 repeat 2 setcoli bid,1,256-cnt*128 //上物から判定 getcoli tid,bid,chpsize/2 if tid>0 { getpos tid,tpx,tpy,tpz setpos tcid,tpx,tpy+chpsize*cnt,tpz break } loop hgdraw hgsync 15 loop



暇人

リンク

2016/4/16(Sat) 23:01:19|NO.75234

addmeshで作りmeshmapで起伏変化させたモデルと同形状のモデルテキストデータを作って
テクスチャを貼るサンプル(但しメッシュのXZ座標はデフォルトのまま使用してるもの)


#include "hgimg3.as" #include "mod_addxfiletex.hsp" //addmeshで作ったモデルと同形状の頂点座標取得と法線を再設定するモジュール(これはmod_addxfiletexの方に統合するかも) #module //[---makexfileplateで使用した頂点座標と出来たxfileデータを基に頂点共有で法線再設定する---] //「 meshPlateCalcNormalTXT xfile_Plate, xyzvec, sx, sy 」 // xfile_Plate : makexfileplateで作ったデータ // xyzvec : 板頂点座標↑を作るときに使った座標 // sx : 横の分割数 // sy : 縦の分割数 //補足:頂点インデックス側では頂点共有してません。テクスチャ画像を複数使用する場合でもマテリアル1枚になるので共有できない(一枚で良いなら共有できますが・・・) #deffunc meshPlateCalcNormalTXT var xfile_Plate,array xyzvec,int sx,int sy dim vec_index,sx*sy*4 vecindex=str(sx*sy)+";" vec_index=0,1,2,3 repeat sx-1,1 vec_index(cnt*4)=vec_index((cnt)*4-1),vec_index((cnt)*4-2),cnt*4+2,cnt*4+3 loop repeat sy-1,1 vec_index(cnt*4*sx)=vec_index(cnt*4*sx-sx*4+1),cnt*4*sx+1,cnt*4*sx+2,vec_index(cnt*4*sx-sx*4+2) loop repeat sy-1,1 y=cnt*sx*4 repeat sx-1,1 vec_index(cnt*4+y)=vec_index(cnt*4+y-1),vec_index(cnt*4+y-2),cnt*4+2+y,vec_index(cnt*4+y-sx*4+2) loop loop repeat sy*sx vecindex+="4;"+vec_index(cnt*4)+","+vec_index(cnt*4+1)+","+vec_index(cnt*4+2)+","+vec_index(cnt*4+3)+";,\n" loop poke vecindex,strlen(vecindex)-3,';' ddim vxyz,4 dup dup_vx,vxyz dup dup_vy,vxyz(1) dup dup_vz,vxyz(2) ddim outer,4 dup dup_outerx,outer dup dup_outery,outer(1) dup dup_outerz,outer(2) outer_str="" ddim outer_list,3*sx*sy*4+1 dim MeshNormalscnt,4*sx*sy index_cnt=0 repeat sx*sy dup dup_Vertex_A,xyzvec(vec_index(index_cnt)*3) dup dup_Vertex_B,xyzvec(vec_index(index_cnt+1)*3) dup dup_Vertex_C,xyzvec(vec_index(index_cnt+2)*3) dup dup_Vertex_D,xyzvec(vec_index(index_cnt+3)*3) memcpy vxyz,dup_Vertex_A,24 fvset outer,dup_Vertex_B-dup_vx,dup_Vertex_B(1)-dup_vy,dup_Vertex_B(2)-dup_vz fvouter outer,dup_Vertex_C-dup_vx,dup_Vertex_C(1)-dup_vy,dup_Vertex_C(2)-dup_vz fvunit outer dup dup_outer,outer_list(vec_index(index_cnt)*3) fvadd dup_outer,outer,outer(1),outer(2) dup dup_outer,outer_list(vec_index(index_cnt+1)*3) fvadd dup_outer,outer,outer(1),outer(2) dup dup_outer,outer_list(vec_index(index_cnt+2)*3) fvadd dup_outer,outer,outer(1),outer(2) memcpy vxyz,dup_Vertex_C,24 fvset outer,-(dup_Vertex_B-dup_vx),-(dup_Vertex_B(1)-dup_vy),-(dup_Vertex_B(2)-dup_vz) fvouter outer,dup_Vertex_D-dup_vx,dup_Vertex_D(1)-dup_vy,dup_Vertex_D(2)-dup_vz fvunit outer dup dup_outer,outer_list(vec_index(index_cnt+1)*3) fvadd dup_outer,outer,outer(1),outer(2) dup dup_outer,outer_list(vec_index(index_cnt+2)*3) fvadd dup_outer,outer,outer(1),outer(2) dup dup_outer,outer_list(vec_index(index_cnt+3)*3) fvadd dup_outer,outer,outer(1),outer(2) MeshNormalscnt(vec_index(index_cnt))+2 MeshNormalscnt(vec_index(index_cnt+1))+2 MeshNormalscnt(vec_index(index_cnt+2))+2 MeshNormalscnt(vec_index(index_cnt+3))++ index_cnt+4 loop repeat sx*sy*4 dup dup_mnc,MeshNormalscnt(cnt) if dup_mnc { dup dup_outer,outer_list(cnt*3) fvdiv dup_outer,dup_mnc,dup_mnc,dup_mnc } outer_str+=""+dup_outer+";"+dup_outer(1)+";"+dup_outer(2)+";," loop poke outer_str,strlen(outer_str)-1,';' MeshNormals="MeshNormals {"+(sx*sy*4)+";\n"+outer_str+"\n"+vecindex+"}" mn_index=0 mnindex=TemplateSearch(mnmax_str, xfile_Plate, mn_index, "MeshNormals {", "1", ";", 1) mnindex_end=instr(xfile_Plate,mnindex,"}")+1 xfilesize=strlen(xfile_Plate) memexpand xfile_Plate,xfilesize*2 sdim temp_xfile_Plate,xfilesize memcpy temp_xfile_Plate,xfile_Plate,xfilesize-(mnindex+mnindex_end),0,(mnindex+mnindex_end) memcpy xfile_Plate,MeshNormals,strlen(MeshNormals),mnindex memcpy xfile_Plate,temp_xfile_Plate,strlen(temp_xfile_Plate)+1,mnindex+strlen(MeshNormals) return //[---addmeshで作ったmeshに設定するデータを基に頂点座標を受け取る---] //「 getVecMap xyzvec, vmap, meshscaly, meshms 」 // xyzvec : 頂点座標を受け取る配列 // vmap : meshmap命令のメッシュのY座標設定で使用した配列 // meshscaly : meshmap命令のfactorに設定した数値 // meshms : addmesh命令で設定したサイズ //戻り値1:statに板の数が返る //戻り値2:refdvalに板1枚のサイズが返る #deffunc getVecMap array xyzvec,array vmap,double meshscaly,double meshms lenx=length(vmap)-1 leny=length2(vmap)-1 mesh_gs=meshms/lenx ddim xyzvec,lenx*leny*3*4 index_cnt=0 repeat lenx*leny dup dup_xyzvec,xyzvec(index_cnt) ix=cnt\lenx iy=cnt/lenx dx=mesh_gs*ix dy=mesh_gs*iy dup_xyzvec(0)=dx,meshscaly*vmap(ix,iy),dy dup_xyzvec(3)=dx,meshscaly*vmap(ix,iy+1),dy+mesh_gs dup_xyzvec(6)=dx+mesh_gs,meshscaly*vmap(ix+1,iy+1),dy+mesh_gs dup_xyzvec(9)=dx+mesh_gs,meshscaly*vmap(ix+1,iy),dy index_cnt+12 loop mref _stat_,64 _stat_=lenx*leny return mesh_gs #global dircur=dir_cur hgini divsize=64 //マテリアル1枚の画像サイズ texsize=2048 //全体のテクスチャサイズ //StartXFileTex 全体のテクスチャサイズ,マテリアル1枚の画像サイズ」 StartXFileTex texsize,divsize //テクスチャサイズを設定して登録開始(必ずhginiの後に実行) SetMaterialSizeExtra 256 //追加サイズ tf=dir_exe+"\\sample\\hgimg3\\chrome.bmp" //本来はファイル名だけで指定出来るようにした方が良い(登録ファイルに重複してるのがあるかをファイル名で検索するので) addTexPic tdid,tf,1,2 chdir dir_exe+"\\hsptv" //画像ファイルのあるディレクトリに移動 tf="sozai7.jpg","sozai8.jpg","sozai10.jpg","sozai11.jpg","sozai12.jpg","sozai12.jpg","sozai12.jpg","sozai12.jpg" addTexPic tdid2,tf,8,1+4 //頂点の共有はしてないので起伏のあるmeshでテクスチャ補間ありの場合繋ぎ目が補完されて隙間が出来るので4を指定 chdir dircur EndXFileTex id chdir dir_exe+"\\sample\\hgimg3\\" //読み込みファイルのあるディレクトリに移動 ; バッファサイズ sx=32:sy=32 dim vmap,sx+1,sy+1 wave_init sx,sy addxfile m_xmodel,"eye.x" regobj mychr, m_xmodel,OBJ_BORDER|OBJ_FLIP|OBJ_STAND|OBJ_MOVE|OBJ_GRAVITY objfloor mychr,8 ; 地面からのオフセット値を指定する ; モデル登録(影) addeprim m_sd,EPRIM_CIRCLE seteprim m_sd,0,2 seteprim m_sd,1,12 seteprim m_sd,2,4 seteprim m_sd,3,4 seteprim m_sd,16,$80000000 seteprim m_sd,17,$80000000 seteprim m_sd,18,$80000000 seteprim m_sd,19,$00000000 regobj mysdw, m_sd, OBJ_LATE|OBJ_LAND|OBJ_STAND; 半透明なのでOBJ_LATEを指定する setefx mysdw,$500 ; 半透明(色減算)の指定 objchild mychr, mysdw ; 目玉の子供として影を登録 mesh_size=160.0 setuv 0,0,128,128 addmesh m_mesh,sx,sy,0,mesh_size,mesh_size texload "mapbg4.bmp" regobj obj, m_mesh,OBJ_GROUND|OBJ_HIDE; 地面として登録(非表示) setborder 150,150,150 ; 移動範囲の設定 ; 高さ、UVマップの設定 ; gsel 3 picload "g_road.bmp" getvarmap vmap,sx,sy,1 picload "g_river.bmp" getvarmap vmap,sx,sy,2 meshmap vmap,m_mesh,$100 repeat sx*sy uvid=vmap(cnt\sx,cnt/sx) tdid_list(cnt)=tdid2(uvid) //メッシュのテクスチャをマッピングをインデックスとしてテクスチャデータインデックスを取り出してリストにする loop PlateHorVerAng 1,0.0,1.0 //面が45度以上傾くと縦の面として処理されるので全て上下方向を向いてる面として処理するように設定 picload "g_height1.bmp" getvarmap vmap,sx,sy mesh_scaley=0.1 meshmap vmap,m_mesh,0,mesh_scaley getVecMap xyzvec,vmap,mesh_scaley,mesh_size vecmax=stat //頂点数 mesh_gs=refdval //1マスのサイズ //一枚の画像で作る地面 makexfilePlate xfile_Plate,xyzvec,vecmax,tdid,,mesh_size,mesh_size/2,0.0,mesh_size/2 meshPlateCalcNormalTXT xfile_Plate,xyzvec,sx,sy //頂点の共有はせずに法線の再設定をしてるのでhgsetreqの法線再計算有効にするとフラットシェーディングになります addXFileTexVar m_Plate,xfile_Plate,512 regobj obj_mesh, m_Plate //表示する地面 //4枚の画像で作る地面 makexfilePlate xfile_Plate,xyzvec,vecmax,tdid_list,,mesh_gs,mesh_size/2,50.0,mesh_size/2 meshPlateCalcNormalTXT xfile_Plate,xyzvec,sx,sy addXFileTexVar m_Plate2,xfile_Plate,512 regobj obj_mesh2, m_Plate2 gsel 0 screen 2,512,512,0,ginfo_wx2,ginfo_wy1 gzoom 512,512,XFILETEX_BUFFER_ID,0,0,texsize,texsize,1 gsel 0 clscolor $4444 ; 背景色の設定 setpos HGOBJ_CAMERA, 0,-50,150 ; カメラ位置の設定 setangr HGOBJ_CAMERA, -15,0,0 ; カメラ角度の設定 *main stick key,$3ff if key&128 : end if key&64 {//Ctrl if key&1 {addpos HGOBJ_CAMERA,-0.5,0.0,0.0} if key&4 {addpos HGOBJ_CAMERA,0.5,0.0,0.0} if key&2 {addpos HGOBJ_CAMERA,0.0,0.0,-0.5} if key&8 {addpos HGOBJ_CAMERA,0.0,0.0,0.5} }else{ if key&2 : adddir mychr,0,0,-0.1 if key&8 : adddir mychr,0,0,0.1 if key&1 : adddir mychr,-0.1,0,0 if key&4 : adddir mychr,0.1,0,0 } msx=mousex msy=mousey addpos HGOBJ_CAMERA,0.0,-0.01*mousew,-0.01*mousew if key&512 { if rc=0{ msx1=msx msy1=msy rc=1 }else{ addang HGOBJ_CAMERA,0.01*(msy1-msy),0.01*(msx1-msx),0.0 msx1=msx msy1=msy } }else{ rc=0 } hgdraw ; 描画 hgsync 15 ; 時間待ち goto *main



暇人

リンク

2016/4/24(Sun) 00:46:43|NO.75300

fv系の命令にクローン配列は使わない方が良かったかも・・・
勝手に4番目が書き換わる・・・(余分に確保してアプリエラーを回避するだけじゃダメだった)
NO.75234のサンプルはたまたま問題ないように見えてるだけだった・・・



暇人

リンク

2016/5/11(Wed) 22:44:02|NO.75464

NO.75234の
>addTexPic tdid2,tf,8,1+4 //頂点の共有はしてないので起伏のあるmeshでテクスチャ補間ありの場合繋ぎ目が補完されて隙間が出来るので4を指定
は間違いでテクスチャデータインデックスを使用して
makexfilePlateでモデルデータを作った時に補正してなかった
なのでv1.0で修正

他にも
MakeXFilePlateでUVFliplistの256を円筒じゃなく円柱マッピングにした(球形にも貼れるがV方向は伸ばさない)
setMergeXFileNormalsRotONでMergeXFileTexTXTの回転リスト使用時に法線も回転するかを設定できるようにした(1,2割重くなるけど)
GetXFilePlateVecの名前をGetXFilePlateVertexに変更(変更前のも使用可能)
GetXFilePlateVertexのmodResizefに8を追加してマテリアル毎に頂点座標をソートし簡単に分けられるようにした
PlateNormalsType命令を追加してMakeXFilePlateの法線方法を設定(三角形一枚か二枚の平均を使うか)
DeleteKeepXFile命令を追加してKeepXFileTexTXTで保持したデータを削除できるようにした
KeepXFileTexTXTのsgf設定値に4を追加して4頂点の三角形二つで向きが違う場合スムージングするようにした

NO.75234で使用してるmeshPlateCalcNormalTXTとgetVecMap命令をmod_addxfiletexの方に追加
meshPlateCalcNormalTXT 「makexfileplateで使用した頂点座標と出来たxfileデータを基に頂点共有で法線再設定する」
NO.75234のとは違い頂点の共有の種類と同じ頂点とする距離、スムージング適用角度を指定出来るように変更(重いけど・・・)


画像を一枚のテクスチャに纏めたり簡単なX形式のモデルデータを作るモジュール v1.0
http://ux.getuploader.com/himajin130414/download/30/mod_addxfiletex.hsp

NO.75234のサンプル以外そのまま動きます。
NO.75234もサンプル内に直接書かれてるモジュールを削除すれば動きます。



暇人

リンク

2016/5/14(Sat) 20:12:26|NO.75491

バグがあったので修正
meshPlateCalcNormalTXTのvifに2を指定した時に頂点インデックス数がなくなってたのを修正
PlateDirTexのインデックス指定やPlateHorVerAngの設定や無効にしたときに問題があったのを修正
getfvmin_modelとgetfvmax_modelの機能が逆になってたのを修正
MergeXFileTexTXTのxyzposlistを省略出来るように修正

画像を一枚のテクスチャに纏めたり簡単なX形式のモデルデータを作るモジュール v1.01
http://ux.getuploader.com/himajin130414/download/31/mod_addxfiletex.hsp



GetXFilePlateVertex,GetMPIndex(),GetMPCount(),getVecMap,meshPlateCalcNormalTXTの使用サンプル

#include "hgimg3.as" #include "mod_addxfiletex.hsp" if mod_addxfileTex_Version<1.01 {dialog "Version 1.01 以上を使って下さい":end} dircur=dir_cur hgini divsize=128 //マテリアル1枚の画像サイズ texsize=2048 //全体のテクスチャサイズ //StartXFileTex 全体のテクスチャサイズ,マテリアル1枚の画像サイズ」 StartXFileTex texsize,divsize //テクスチャサイズを設定して登録開始(必ずhginiの後に実行) chdir dir_exe+"\\hsptv" //画像ファイルのあるディレクトリに移動 tf="sozai7.jpg","sozai8.jpg","sozai10.jpg","sozai11.jpg","sozai12.jpg","sozai13.jpg","sozai14.jpg","sozai15.jpg" //使用する画像を前もって登録 addTexPic tdid,tf,8,1 //eyeモデル用のテクスチャ画像 buffer 1,4,1 color 255,255,255 gradf 0,0,1,1 color 32,32,32 gradf 1,0,1,1 color 33+32,18+32,20+32 gradf 2,0,1,1 color 252+3, 209+12, 197+12 gradf 3,0,1,1 SetMaterialSizeExtra 1 //追加サイズ(単色のテクスチャとして使用するので1ドット) tf="buffer.1,0,0,1,1","buffer.1,1,0,1,1","buffer.1,2,0,1,1","buffer.1,3,0,1,1" addTexPic eye_tdid,tf,4,2 chdir dircur //EndXFileTexにはオプションでデータセーブ機能があるので念のため起動時のディレクトリに戻す //登録された画像をテクスチャにする EndXFileTex id chdir dir_exe+"\\sample\\hgimg3\\" //モデルファイルのあるディレクトリに移動 //比較用に通常のモデル作成 addxfile m_eye,"eye.x" regobj o_eye, m_eye,OBJ_BORDER|OBJ_FLIP|OBJ_STAND|OBJ_MOVE|OBJ_GRAVITY setpos o_eye,0,-15,30 objfloor o_eye,8 ; 地面からのオフセット値を指定する SetXFileDiffusedLight 1,255,255,255 //他でもモデルデータを使うので変数に読み込み notesel eye_xfile noteload "eye.x" //X形式データを変数から読み込んでモデル作成(マテリアルが一つになるので一色になる) addXFileTexVar m_eye(1),eye_xfile //X形式データを頂点座標と板の数を取り出し(中心に移動とマテリアル順にソートを設定) GetXFilePlateVertex xyzvec,vmax,eye_xfile,2+8 //今回はマテリアル情報が必要なので加工済みのmem_xfileは使えない //サイズ計算したモデルをサイズ1.0にするスケールを取得 getScaleFactor_model eye_sf eye_msize=refdval //モデル最大サイズ //テクスチャ無しのモデルデータ作成(スムージング無しの面法泉になる) makexfilePlate eye_xfile,xyzvec,vmax, , ,eye_msize,eye_msize/2,eye_msize/2,eye_msize/2 //上で作ったデータでモデル作成 addXFileTexVar m_eye(2),eye_xfile //eye.xのマテリアル順 0=眼球、1=レンズ内側、2=レンズ表面、3=まつげ、4=外側の面 //vc_index = 眼球 、 レンズ表面 、 まつげ、 外側の面 vc_index=12*GetMPIndex(0),12*GetMPIndex(2),12*GetMPIndex(3),12*GetMPIndex(4) //板のインデックスなので3軸4頂点分で12を掛ける //(眼球とレンズ内側は繋がりをスムージングするので一緒にする) //vc_max = 眼球+レンズ内側 、 レンズ表面 、 まつげ 、 外側の面 vc_max=GetMPCount(0)+GetMPCount(1),GetMPCount(2),GetMPCount(3),GetMPCount(4) namg= 90.0, 20.0, 40.0, 90.0//パーツ別のスムージング適用角度 repeat 4 td_id=eye_tdid(cnt) vc_i=vc_index(cnt) //パーツ別に画像データIDを指定してモデルデータにする makexfilePlate xfile,xyzvec(vc_i),vc_max(cnt),td_id , ,eye_msize,eye_msize/2,eye_msize/2,eye_msize/2 //パーツ別にスムージング meshPlateCalcNormalTXT xfile,xyzvec(vc_i),0,0,1,0.00,namg(cnt) //頂点の共有はせずに法線の再設定をしてるのでhgsetreqの法線再計算有効にするとフラットシェーディングになります //パーツ別にデータIDにする KeepXFileTexTXT xfile //Xfileデータを保持してデータID取得 eye_kdid(cnt)=stat loop //外側から組み立てた方がZバッファの精度の問題で内側が見えてしまうのを軽減できる //Merge_idlist = 外側の面、 まつげ 、 レンズ表面 、 眼球+レンズ内側 Merge_idlist = eye_kdid(3), eye_kdid(2), eye_kdid(1), eye_kdid(0) //パーツ別のデータを統合する MergeXFileTexTXT eye_xfile, Merge_idlist,4 //UV値変換済みのデータなので512を指定してモデル作成 addXFileTexvar m_eye(3),eye_xfile,512 //レンズ表面、眼球+レンズ内側を統合しモデル作成 Merge_idlist = eye_kdid(1), eye_kdid(0) MergeXFileTexTXT eye_xfile, Merge_idlist,2 addXFileTexvar m_eyeA,eye_xfile,512 //まつげと外側を統合したモデル作成 repeat GetMPCount(3) //まつげ部分 td_id(cnt)=tdid(1)//eye_tdid(2) //まつげのテクスチャ設定(PlateHorVerAngを有効にして特定の部分だけ違うテクスチャにしたい場合) loop PlateHorVerAng 1,0.0,1.0 //全て上下方向を向いてる面として処理するように設定 PlateDirTex 2,tdid(0),tdid(0) //上下方向のテクスチャデータインデックスを設定 PlateDirUVFlip 1,0,5 //下方向の面はV反転設定 vc_i=12*GetMPIndex(3) //まつげ vc_max=GetMPCount(3)+GetMPCount(4) //まつげ+外側の面 makexfilePlate xfile,xyzvec(vc_i),vc_max,td_id , ,eye_msize,eye_msize/2,eye_msize/2,eye_msize/2 meshPlateCalcNormalTXT xfile,xyzvec(vc_i),0,0,1,0.00,90 //頂点の共有はせずに法線の再設定をしてるのでhgsetreqの法線再計算有効にするとフラットシェーディングになります addXFileTexvar m_eyeB,xfile,512 addXFileTex m_font_a,"font_b.x" GetXFilePlateVertex xyzvec,vmax,mem_xfile,2 getScaleFactor_model font_a_sf font_a_msize=refdval //モデル最大サイズ PlateHorVerAng 1,0.5,-1.0 //上下向きの面も前後左右の向きになるように設定 PlateDirTex 2,,,tdid(0),tdid(0),tdid(1),tdid(1) //前後左右のテクスチャデータインデックスを設定 PlateDirUVFlip 0 //通常に戻す makexfilePlate xfile,xyzvec,vmax, , ,font_a_msize,font_a_msize/2,font_a_msize/2,font_a_msize/2 meshPlateCalcNormalTXT xfile,xyzvec,,,1,0.0,89.0 addXFileTexVar m_font_a(1),xfile,512 ; バッファサイズ sx=32:sy=32 dim vmap,sx+1,sy+1 wave_init sx,sy ; モデル登録(影) addeprim m_sd,EPRIM_CIRCLE seteprim m_sd,0,2 seteprim m_sd,1,12 seteprim m_sd,2,4 seteprim m_sd,3,4 seteprim m_sd,16,$80000000 seteprim m_sd,17,$80000000 seteprim m_sd,18,$80000000 seteprim m_sd,19,$00000000 regobj mysdw, m_sd, OBJ_LATE|OBJ_LAND|OBJ_STAND; 半透明なのでOBJ_LATEを指定する setefx mysdw,$500 ; 半透明(色減算)の指定 objchild mychr, mysdw ; 目玉の子供として影を登録 mesh_size=160.0 setuv 0,0,128,128 addmesh m_mesh,sx,sy,0,mesh_size,mesh_size texload "mapbg4.bmp" regobj obj, m_mesh,OBJ_GROUND|OBJ_HIDE; 地面として登録(非表示) setborder 150,150,150 ; 移動範囲の設定 setpos obj, 0,-10,0 ; カメラ位置の設定 ; 高さ、UVマップの設定 ; gsel 3 picload "g_road.bmp" getvarmap vmap,sx,sy,1 picload "g_river.bmp" getvarmap vmap,sx,sy,2 meshmap vmap,m_mesh,$100 repeat sx*sy uvid=vmap(cnt\sx,cnt/sx) tdid_list(cnt)=tdid(uvid) //メッシュのテクスチャをマッピングをインデックスとしてテクスチャデータインデックスを取り出してリストにする loop PlateHorVerAng 1,0.0,1.0 //面が45度以上傾くと縦の面として処理されるので全て上下方向を向いてる面として処理するように設定 picload "g_height1.bmp" getvarmap vmap,sx,sy mesh_scaley=0.1 meshmap vmap,m_mesh,0,mesh_scaley getVecMap xyzvec,vmap,mesh_scaley,mesh_size,mesh_size vecmax=stat //頂点数 mesh_gs=refdval //1マスのサイズ //4枚の画像で作る地面 makexfilePlate xfile_Plate,xyzvec,vecmax,tdid_list,,mesh_gs,mesh_size/2,0.0,mesh_size/2 //meshmap用の設定でスムージング法線を設定 meshPlateCalcNormalTXT xfile_Plate,xyzvec,sx,sy,0,0.00,90 addXFileTexVar m_Plate2,xfile_Plate,512 regobj o_Plate2, m_Plate2 repeat 3,1 regobj o_eye(cnt), m_eye(cnt) setpos o_eye(cnt),-15+15*(cnt-1),-30,0 loop regobj o_eyeB, m_eyeB//,OBJ_MOVE setpos o_eyeB,0,-10,0 regobj o_eyeA, m_eyeA,OBJ_MOVE setpos o_eyeA,0,-10,0 modelorder m_eyeA,0 modelorder m_eyeB,0 repeat 2 regobj o_font_a(cnt), m_font_a(cnt) setpos o_font_a(cnt),-15+30*cnt,-10,0 setscale o_font_a(cnt),2,2,2 loop gsel 0 screen 2,512,512,0,ginfo_wx2,ginfo_wy1 gzoom 512,512,XFILETEX_BUFFER_ID,0,0,texsize,texsize,1 gsel 0 clscolor $ff4444 ; 背景色の設定 setpos HGOBJ_CAMERA, 0,-50,100 setang HGOBJ_CAMERA, -0.4,0,0 setang HGOBJ_LIGHT, -0.6,0,0 *main stick key,$3ff if key&128 : end if key&64 {//Ctrl if key&1 {addpos HGOBJ_CAMERA,-0.5,0.0,0.0} if key&4 {addpos HGOBJ_CAMERA,0.5,0.0,0.0} if key&2 {addpos HGOBJ_CAMERA,0.0,0.0,-0.5} if key&8 {addpos HGOBJ_CAMERA,0.0,0.0,0.5} }else{ if key&2 : adddir o_eye,0,0,-0.1 if key&8 : adddir o_eye,0,0,0.1 if key&1 : adddir o_eye,-0.1,0,0 if key&4 : adddir o_eye,0.1,0,0 } getpos o_eye,ox,oy,oz getpos o_eyeA,oxa,oya,oza fv=oxa,oya,oza fvface fv,ox,oy,oz setang o_eyeA,-fv,-fv(1),fv(2) getang o_eyeA,ax,ay,az getang o_eyeB,axb,ayb,azb M_PI2 = M_PI*2 addax=(ax-axb+M_PI2)\M_PI2 adday=(ay-(ayb\M_PI2)+M_PI2)\M_PI2 if addax >= M_PI {addax-M_PI2} if adday >= M_PI {adday-M_PI2} addang o_eyeB,addax*0.15,adday*0.15 repeat 4 addang o_eye(cnt), 0.00,0.01,0 ; カメラ角度の設定 loop repeat 2 addang o_font_a(cnt), 0.01,0.01,0 ; カメラ角度の設定 loop msx=mousex msy=mousey addpos HGOBJ_CAMERA,0.0,-0.01*mousew,-0.01*mousew if key&512 { if rc=0{ msx1=msx msy1=msy rc=1 }else{ addang HGOBJ_CAMERA,0.01*(msy1-msy),0.01*(msx1-msx),0.0 msx1=msx msy1=msy } }else{ rc=0 } hgdraw ; 描画 hgsync 15 ; 時間待ち goto *main



暇人

リンク

2016/6/12(Sun) 00:48:24|NO.75846

hgimg3のバグなのかaddxfileの仕様なのか分からないが
Materialのパラメータを省略するとモデル作成時(addxfile)にアプリケーションエラーになる
(最初は使用してないMaterialが原因かと思った)
ポリゴン数の異なるモデルの作成、削除を繰り返すとアプリケーションエラーになりやすい?

モジュールで設定押してるのは

Material { 1.000000;1.000000;1.000000;;}

metaseqの場合

Material { 1.000000;1.000000;1.000000;1.000000;; 0.000000; 0.000000;0.000000;0.000000;; 0.000000;0.000000;0.000000;; }
になってるので、面の色はR;G;Bだけですが
下の3行も指定するように変更する予定

今20分ぐらい放置して6万個ぐらい作成削除を繰り返してるけどエラーは出てない
テストで作ったもので試してるだけなので実際のゲーム上で使用してもエラーが出ないか
確かめてから修正してアップロードします。



暇人

リンク

2016/6/12(Sun) 14:24:20|NO.75854

>hgimg3のバグなのかaddxfileの仕様なのか分からないが
これはデフォルトのテンプテレートが設定されてる状態で
設定値が少ない時に問題が出る感じ

template Material { <3D82AB4D-62DA-11cf-AB39-0020AF71E433> ColorRGBA faceColor; [...] }
を追加すればエラーにならなくなった(少ししかテストしてないが)

でもテンプレートを全て削除する感じで組んでるので
Materialの方をデフォルトテンプレートに合わせるように修正


(v1.02)画像を一枚のテクスチャに纏めたり簡単なX形式のモデルデータを作るモジュール
http://ux.getuploader.com/himajin130414/download/35/mod_addxfiletex.hsp

・変更点
MaterialのfaceColor以外の設定 power; specularColor; ;emissiveColor; ; を全て0で設定するように変更
通常endxfiletex実行後は画像の追加は出来ませんがaddTexPicのみ画像追加出きる様に変更(追加時にsettexが実行される)
・追加命令
SetTexNode //複数ノード使用時に自動じゃ無く自分でテクスチャを設定するノードを指定



暇人

リンク

2016/6/30(Thu) 00:31:31|NO.76031

GetTex系のマクロにctypeの指定を忘れてたので修正
MakeXFilePlateの両面化時に法線の設定が間違ってたのを修正
meshPlateCalcNormalTXTで 頂点数/4=面数 にならない場合は頂点共有ありとして直ぐに終了するように修正
UVサイズ=GetTexUVSize(TI) 「登録済みのテクスチャのUVサイズをインデックスを指定して取得」を追加

モデルのUV値や頂点座標を直接変更してアニメーションやスクロール、頂点移動をする命令を追加
使用できるのは1面4頂点使用のモデルのみ
モデルで使用してる面数、頂点数を超えないようにしてください

AddUVScroll 「モデルIDを指定してuvscrollanimation実行時にスクロールするモデルを登録設定」
AddUVAnimation 「モデルIDを指定してuvscrollanimation実行時にアニメーションするモデルを登録設定」
UVScrollAnimation 「adduvanimation、adduvscrollで設定したアニメーションを反映」
オブジェクトID =GetUVAOID(UVAI) 「登録されたUVアニメーションインデックスを指定して使用してるオブジェククトIDを取得」
SetUVScrollOffset 「adduvscroll設定時に元のUV値を移動する」
StopUVScrollAnimation 「UVScrollAnimationの処理を個別に一時停止と解除します」
AllClearUVScrollAnimation 「adduvanimation、adduvscrollで登録したものを全て削除します」
DelUVScrollAnimation 「adduvanimation、adduvscrollで登録したものを個別に削除します」

SetObjUVTexIndex 「オブジェクトIDとテクスチャインデックスを指定してUVを変更」
SetObjUVTexIndexes 「オブジェクトIDとテクスチャインデックスを複数指定してUVを変更」
GetObjPlateUV 「オブジェクトIDと板インデックスを指定してUV値を取得(UV値はテクスチャ全体のでは無く板内のローカルUV値)」
MoveObjPlateUV 「オブジェクトIDと板インデックスを指定してUV値を変更」
SetObjPlateUV 「オブジェクトIDと板インデックスを指定してUV値を設定」

GetObjVertex 「オブジェクトIDと頂点インデックスを指定して頂点座標取得」
MoveObjVertex 「オブジェクトIDと頂点インデックスを指定して頂点座標移動」
SetObjVertex 「オブジェクトIDと頂点インデックスを指定して頂点座標設定」

(v1.1)画像を一枚のテクスチャに纏めたり簡単なX形式のモデルデータを作るモジュール
http://ux.getuploader.com/himajin130414/download/37/mod_addxfiletex.hsp

AddUVScroll、AddUVAnimation、UVScrollAnimation、SetUVScrollOffset、StopUVScrollAnimation
GetObjVertex、MoveObjVertexを使用したサンプル

#include "hgimg3.as" #include "mod_addxfiletex.hsp" if mod_addxfileTex_Version<1.1 {dialog "Version 1.1 以上を使って下さい":end} screen 0,800,600,0 hgsetreq SYSREQ_3DFILTER,D3DTEXF_POINT //補間ありだとスクロール時に繋ぎ目が見えるので補間なし設定 hgsetreq SYSREQ_MAXOBJ, 5000 boxsize=1.0 hgini startXFileTex 1024,64 SetXFileDiffusedLight 1,255,255,255 celload dir_exe+"\\hsptv\\hsptv_img.bmp",1 repeat 8*5 //X0,Y192からサイズ64*64刻みで X512,Y512 までを配列に入れる settf(cnt)="buffer.1,"+(64*(cnt\8))+","+(64*(3+(cnt/8)) )+","+64+","+64 loop addTexPic texidlist,settf,8*5//画像を登録してテクスチャインデックス取得 wtf=settf(8*2+3) //水面用の画像ファイル名 addTexPic water_ti,wtf,1,4 //スクロール用に縦横二枚並べて読み込める4を指定 //上と側面の画像を指定して下の面は削除を指定 btf=settf(8*4+4)+"\nDelete\n"+settf(8*2+2) //MakeXFileBoxはテクスチャインデックスを使用できないのでファイル名を指定 MakeXFileBox box_xfile,btf,boxsize, boxsize,boxsize,boxsize //地面用ブロック addxfileTexVar box_mid,box_xfile //水底用の板を作る mx=32 my=32 repeat mx*my vx=boxsize*(cnt\mx) vz=boxsize*(cnt/mx) vxyz(cnt*3*4)=vx,0.0,vz vxyz(cnt*3*4+3)=vx,0.0,vz+boxsize vxyz(cnt*3*4+6)=vx+boxsize,0.0,vz+boxsize vxyz(cnt*3*4+9)=vx+boxsize,0.0,vz loop //水底の画像をテクスチャインデックスで指定 ti=texidlist(8*4+5) makexfilePlate bottom_xfile,vxyz,mx*my,ti,, boxsize, mx/2, 0.5, my/2 //水底用板 addxfileTexVar bottom_mid,bottom_xfile,512 //テクスチャインデックスを使用したデータなので512を指定 //水面用の板を作る vxyz=0.0,0.0,0.0 vxyz(3)=0.0,0.0,boxsize vxyz(6)=boxsize,0.0,boxsize vxyz(9)=boxsize,0.0,0.0 makexfilePlate water_xfile,vxyz,1,water_ti,,boxsize,0,0.0,0 addxfileTexVar water_mid,water_xfile,512 //テクスチャインデックスを使用したデータなので512を指定 //キャラを作る btf="Delete\nDelete\n"+settf(0)+"\n"+settf(3)+"\nDelete\nDelete" //前と後ろだけ画像指定して他は削除指定 MakeXFileBox Cara_xfile,btf,boxsize, boxsize,boxsize,0.0 //Zサイズは0 addxfileTexVar Cara_mid,Cara_xfile modelshade Cara_mid,0 EndXFileTex modt_id //横スクロール開始位置を左に100%分移動(左方向にスクロールさせる時に必要)、縦は上下に移動させるので-50%移動 SetUVScrollOffset -100.0,-50.0 scrun=1 //横スクロールの設定数 scru=1.0 //1コマの横スクロール速度(左方向に0.5%スクロール、カメラが右に移動する感じ) scruf=0 //スクロールコマ数(指定が一つなら無限スクロールになるので無視される) scrvn=-1 //縦スクロールの設定数(-1の場合サイン波を使ったスクロール) scrv=-0.05 //scrvnが-1なので1コマの回転角度(単位ラジアン) scrvf=2 //最大でマテリアル1/4移動する(2で半分になる) //[ AddUVScroll モデルID, 1コマのフレーム数, 横スクロール設定数, 横スクロール量リスト, 横コマ数,縦スクロール設定数, 縦スクロールにサイン波指定, 縦コマ数リスト,面数 ] AddUVScroll water_mid,2,scrun,scru,scruf,scrvn,scrv,scrvf,1 //水面スクロール uvsi=stat ati=texidlist(0),texidlist(1) //キャラ表用テクスチャインデックス //[ AddUVAnimation モデルID, 1コマのフレーム数, アニメーヨン設定数, テクスチャインデックスリスト, アニメーションさせる面数 ] AddUVAnimation Cara_mid,20,2,ati,1,0 //キャラ表アニメーション uvai=stat ati=texidlist(3),texidlist(2) //キャラ裏用テクスチャインデックス //[ AddUVAnimation モデルID, 1コマのフレーム数, アニメーヨン設定数, テクスチャインデックスリスト, アニメーションさせる面数,面のインデックス ] AddUVAnimation Cara_mid,20,2,ati,1,1 //キャラ裏アニメーション uvai(1)=stat regobj obj, bottom_mid ;水底 repeat 6*6 regobj obj, box_mid ;地面 setpos obj,-3.0+(cnt\6),0.0,-3.0+(cnt/6) loop repeat mx*my regobj obj, water_mid ;水面 setpos obj,-mx/2+(cnt\mx),0.0,-my/2+(cnt/mx) setefx obj,150 loop regobj Cara_obj, Cara_mid ;キャラ setpos Cara_obj,0.0,-1.0,0.0 //オブジェクトの頂点座標取得 vil=0,3 ,4,7 //キャラの上2頂点表裏で4頂点 GetObjVertex pxyzl, Cara_obj, 4,vil //pxyzlには1頂点XYZの3軸分入る clscolor $4444 ; 背景色の設定 cammode CAM_MODE_LOOKAT repeat 2 GetObjPlateUV uv(cnt*8),obj,cnt loop ry=0.0 py=-6.0 pz=7.0 objsize 200,24 button gosub "スクロール停止解除",*sstop button gosub "アニメーション停止解除",*astop *main stick key,$3ff if key&128 : goto *owari if key&1 : ry+0.01 if key&4 : ry-0.01 if key&64 { if key&2 : pz-0.1 if key&8 : pz+0.1 pz=limitf(pz,0.0,100) }else{ if key&2 : py-0.1 if key&8 : py+0.1 } fvset fv,0,ry,0 fvdir fv,0,py,pz setpos HGOBJ_CAMERA,fv,fv(1),fv(2) UVScrollAnimation //アニメーション反映 //頂点移動 repeat 4 MoveObjVertex Cara_obj, pxyzl(3*cnt), vil(cnt), sin(0.1*fps)*0.1, 0.0, 0.0 loop fps++ hgdraw hgsync 16 goto *main *sstop StopUVScrollAnimation uvsi return *astop StopUVScrollAnimation uvai StopUVScrollAnimation uvai(1) return *owari end



jsa120

リンク

2016/6/30(Thu) 07:50:03|NO.76033

独壇場ですね(笑)



ONION software Copyright 1997-2023(c) All rights reserved.