元々↓のスレで作ってたモジュールで使うことを目的で作ってたのを単体で使える様にしてみた
>マイクラ的なのを作ってください お願いします。
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