Exemple #1
0
 public MMDModel(Vert[] vertex, IEnumerable <Material> material, string path)
 {
     DirPath     = path;
     Vertice     = vertex;
     OrigVertice = new Vert[Vertice.Length];
     Vertice.ArrayFullCopy(OrigVertice);
     Materials     = material.ToList();
     GpuData       = new GPUData( );
     GpuData.Alpha = 1;
     Cast          = new SphereCast(Matrix.Zero);
 }
Exemple #2
0
        public MMDModel(string path)
        {
            DirPath = Directory.GetParent(path).FullName;
            string[] lines = File.ReadAllLines(path);
            //;Face,親材質名,面Index,頂点Index1,頂点Index2,頂点Index3
            //Face,"スカート腕ヘドフォン",0,858,840,855
            // のように最初の文字列がVertexだと頂点 Faceだと面になる ;が最初に来るものは説明用のものなので弾く
            var gr = lines.GroupBy(l => l.Split(',')[0]);
            var gs = gr.Where(g => !g.Key.Contains(";")).ToDictionary(s => s.Key, g => g.ToList( ));

            Vertice     = ParseCSV(gs["Vertex"]).ToArray( );
            OrigVertice = new Vert[Vertice.Length];
            Vertice.ArrayFullCopy(OrigVertice);
            // 次の文字列は材質名になるので、材質名のグループを作る
            var faceGr = gs["Face"].GroupBy(s => s.Split(',')[1]).ToDictionary(s => s.Key, g => g.ToList( ));

            Materials = Material.MakeFromCSV(gs["Material"], faceGr, Vertice).ToList();

            GpuData       = new GPUData( );
            GpuData.Alpha = 1;
            Cast          = new SphereCast(Matrix.Zero);
        }
Exemple #3
0
    //頂点グループ以外done 呼んでいない
    void lattice_deform_verts(int count, int id)
    {
        //頂点グループは未対応
        //vgroup && vgroup[0] && use_vgroups
        int len    = verts.Length;
        var nverts = new Vertex[len];

        verts.CopyTo(nverts, 0);
        int s = len / count;

        for (int i = id * len; i < id * len + s; i++)
        {
            if (i >= len)
            {
                break;
            }
            //var pos = verts[i];
            //Debug.DrawLine(pos, pos + n[i]*0.1f);
            calc_latt_deform(ref nverts[i], factor, i);
        }

        mesh.Vertice = nverts;
        //mesh.RecalculateNormals();
    }
Exemple #4
0
    //リサイズ部分以外終わり
    // latice割数を増やす
    void BKE_lattice_resize(int uNew, int vNew, int wNew)    //, Object *ltOb)
    {
        //頂点ウェイトグループはすべて開放される
        if (dvert.Length != 0)
        {
            //BKE_defvert_array_free(lt->dvert, lt->pntsu * lt->pntsv * lt->pntsw);
            //lt->dvert = NULL;
        }
        while (uNew * vNew * wNew > 32000)
        {
            if (uNew >= vNew && uNew >= wNew)
            {
                uNew--;
            }
            else if (vNew >= uNew && vNew >= wNew)
            {
                vNew--;
            }
            else
            {
                wNew--;
            }
        }

        var vertexCos = new Vertex[uNew * vNew * wNew];  //tmp_vcos
        var fudu      = calc_lat_fudu(gridFlag, uNew);
        var fvdv      = calc_lat_fudu(gridFlag, vNew);
        var fwdw      = calc_lat_fudu(gridFlag, wNew);

        if (alreadyCreate)
        {
            //1分割まで減らされたり、元から1分割でないなら
            if (uNew != 1 && UVW[0] != 1)
            {
                du = (UVW[0] - 1) * du / (uNew - 1);
            }

            if (vNew != 1 && UVW[1] != 1)
            {
                dv = (UVW[1] - 1) * dv / (vNew - 1);
            }

            if (wNew != 1 && UVW[2] != 1)
            {
                dw = (UVW[2] - 1) * dw / (wNew - 1);
            }
        }

        var co = vertexCos;

        fu = fudu[0];
        du = fudu[1];
        fv = fvdv[0];
        dv = fvdv[1];
        fw = fwdw[0];
        dw = fwdw[1];

        float wc  = fw;
        float vc  = fv;
        float uc  = fu;
        int   coi = 0;

        for (int w = 0; w < wNew; w++, wc += dw)
        {
            vc = fv;
            for (int v = 0; v < vNew; v++, vc += dv)
            {
                uc = fu;
                for (int u = 0; u < uNew; u++, coi++, uc += du)
                {
                    var cv = new Vector3(-uc, -vc, -wc);
                    // todo 同じかどうかよく調べる
                    co[coi].Position = (cv);
                }
            }
        }
        if (alreadyCreate)
        {
            //var mat = new float[4, 4];
            var typeu = keytype; //lt->typeu, typev = lt->typev, typew = lt->typew;

            //endpointsがマッチするので強制的にlinに変える
            //lt->typeu = lt->typev = lt->typew
            keytype = KEYType.KEY_LINEAR;

            //変更された座標を使わないように
            //BKE_displist_free(&ltOb->curve_cache->disp);

            //オブジェクトの行列を退避、デフォームさせてから戻す
            //copy_m4_m4(mat, ltOb->obmat);
            //unit_m4(ltOb->obmat);

#if false
            var mat = transform.localToWorldMatrix;
#endif
            //transform.localToWorldMatrix = Matrix4x4.identity;
            lattice_deform_vertsFull( );
            //copy_m4_m4(ltOb->obmat, mat);
            keytype = typeu;
            //lt->typeu = typeu;
            //lt->typev = typev;
            //lt->typew = typew;
        }
        alreadyCreate = true;
        // pntsu
        UVW[0] = uNew;
        UVW[1] = vNew;
        UVW[2] = wNew;
        actbp  = LT_ACTBP_NONE;
        //bpの処理をしていないが、これでいいはず
        LatticeString   = co.Select(x => new ReactiveProperty <string>(x.ToString( ))).ToList( );
        LatticeData     = LatticeString.Select(reactiveProperty).ToArray( );
        RelativeLattice = new LatticeType[LatticeData.Length];
    }
Exemple #5
0
    //頂点数だけculcする,done
    void calc_latt_deform(ref Vertex co, float weight, int ind)
    {
        //obは対象オブジェクト
        int     defgrp_index = -1;
        var     co_pre       = co;
        Vector3 co_prev;// = sv( 0 );
        float   weight_blend = 0;

        if (EnableVertexGroup)
        {
            co_prev = co.Position;
        }
        //coはモデルのローカル頂点、ラティスの座標系に移動する
        var   vec = latma.TransByMat(co.Position);
        float u, v, w;
        int   ui, vi, wi;

        if (UVW[0] > 1)
        {
            u  = (vec[0] - fu) / du;
            ui = Util.FloorToInt(u);
            u -= ui;
            key_curve_position_weights(u, tu, keytype);
        }
        else
        {
            tu[0] = tu[2] = tu[3] = 0.0f;
            tu[1] = 1.0f;
            ui    = 0;
        }

        if (UVW[1] > 1)
        {
            v  = (vec[1] - fv) / dv;
            vi = Util.FloorToInt(v);
            v -= vi;
            key_curve_position_weights(v, tv, keytype);
        }
        else
        {
            tv[0] = tv[2] = tv[3] = 0.0f;
            tv[1] = 1.0f;
            vi    = 0;
        }
        if (UVW[2] > 1)
        {
            w  = (vec[2] - fw) / dw;
            wi = Util.FloorToInt(w);
            w -= wi;
            key_curve_position_weights(w, tw, keytype);
        }
        else
        {
            tw[0] = tw[2] = tw[3] = 0.0f;
            tw[1] = 1.0f;
            wi    = 0;
        }
        int idx_w = 0, idx_v, idx_u;
        int uu, vv, ww;

        for (ww = wi - 1; ww <= wi + 2; ww++)
        {
            //tw[0~3]
            w = tw[ww - wi + 1];

            if (w != 0.0f)
            {
                if (ww > 0)
                {
                    //idx_wをwi-1 * uの分割 *vの分割
                    if (ww < UVW[2])
                    {
                        idx_w = ww * UVW[0] * UVW[1];
                    }
                    else
                    {
                        idx_w = (UVW[2] - 1) * UVW[0] * UVW[1];
                    }
                }
                else
                {
                    idx_w = 0;
                }
                for (vv = vi - 1; vv <= vi + 2; vv++)
                {
                    v = w * tv[vv - vi + 1];
                    if (v != 0.0f)
                    {
                        if (vv > 0)
                        {
                            if (vv < UVW[1])
                            {
                                idx_v = idx_w + vv * UVW[0];
                            }
                            else
                            {
                                idx_v = idx_w + (UVW[1] - 1) * UVW[0];
                            }
                        }
                        else
                        {
                            idx_v = idx_w;
                        }

                        for (uu = ui - 1; uu <= ui + 2; uu++)
                        {
                            u = weight * v * tu[uu - ui + 1];
                            if (u != 0.0f)
                            {
                                if (uu > 0)
                                {
                                    if (uu < UVW[0])
                                    {
                                        idx_u = idx_v + uu;
                                    }
                                    else
                                    {
                                        idx_u = idx_v + (UVW[0] - 1);
                                    }
                                }
                                else
                                {
                                    idx_u = idx_v;
                                }
                                int     v1      = LatticeData.Length - idx_u - 1;
                                var     ldata   = LatticeData[v1];
                                Vector3 vector3 = (ldata.Value.Position * u);

                                co.Position += vector3;

                                //co += transform.localPosition;
                                //頂点グループが設定されているならウェイトをもらってきて計算に入れる
                                if (defgrp_index != -1)    //恐らくdvert[idx_u]
                                {
                                    weight_blend += (u);   //* defvert_find_weight(dvert + idx_u, defgrp_index));
                                }
                            }
                        }
                    }
                }
            }
        }
        // 異様にuが小さくなってしまう
        co.Position += co_pre.Position;

        //if (defgrp_index != -1)  //math_vector.c  weight_blendで線形補完
        //  interp_v3_v3v3(co, co_prev, co, weight_blend);
    }
Exemple #6
0
    //lattice_deform_vertsから呼ばれる,notested done
    void init_latt_deform()
    {
        MMDModel  ob = null;
        Matrix4x4 latmat;
        Matrix4x4 imat;

        if (ob == null)
        {
            //デフォームスペースの行列
            latmat = latma.Inverted();
            //デフォーム配列に戻す
            imat = latmat.Inverted();
        }
        //今のところここに入るパターンが無い
        else
        {
            imat = latma.Inverted( );
            //latmat = imat * myself;
            latmat = Matrix4x4.Identity;
            //imat = latmat.inverse;
        }

        //BPoint bp;//頂点だけ参照している、lattice
        int           id       = 0;
        var           ffu      = fu;
        var           ffv      = fv;
        var           ffw      = fw;
        List <Vertex> vertices = new List <Vertex>( );

        for (int w = 0; w < UVW[2]; w++, fw += dw)
        {
            for (int v = 0; v < UVW[1]; v++, fv += dv)
            {
                for (int u = 0; u < UVW[0]; u++,
                     //bp++, co += 3, fp += 3,
                     fu += du)
                {
                    //coはlattice座標 fpは初期fu,fv,fwで引かれて0になる
                    Vertex value = LatticeData[id].Value;

#if true
                    value.Position = (mul_mat3_m4_v3(imat,  value.Position));
                    vertices.Add(value);
#else
                    Vector3 pos = value.Position - new Vector3(fu, fv, fw);
                    //latmatをかけて行列を戻す
                    value.Position = (mul_mat3_m4_v3(imat,  pos));
                    vertices.Add(value);
                    // ちゃんと変更
                    RelativeLattice[id] = new LatticeType(value);
                    // 常に相対になりたい
                    //                                                  0 0 0 -> -1 -1 -1
                    //RelativeLattice[ id ].ToReactivePropertyAsSynchronized( x => x.Value ,
                    //	convert :x => x + value ,convertBack: x => x - value );
#endif
                    id++;
                }
                fu = ffu;
            }
            fv = ffv;
        }
        fw = ffw;

        RelativeLattice = LatticeData.Select(
            (lat, i) => lat.Select(
                // x => x.Value , convert:
                x => LatticeData[i].Value - vertices[i]
                //, convertBack: x => vertices[ i ] - LatticeData[i].Value)
                ).ToReactiveProperty()).ToArray();
        latma = latmat;
    }