Exemple #1
0
    /*
     * private static void FillCap_Method2(List<int> indices)
     * {
     *
     *  // center of the cap
     *  Vector3 center = Vector3.zero;
     *  foreach (var index in indices)
     *      center += _newVerticesCache[index];
     *
     *  center = center / indices.Count;
     *
     *  // you need an axis based on the cap
     *  Vector3 upward = Vector3.zero;
     *  // 90 degree turn
     *  upward.x = _blade.normal.y;
     *  upward.y = -_blade.normal.x;
     *  upward.z = _blade.normal.z;
     *  Vector3 left = Vector3.Cross(_blade.normal, upward);
     *
     *  Vector3 displacement = Vector3.zero;
     *  Vector2 newUV1 = Vector2.zero;
     *  Vector2 newUV2 = Vector2.zero;
     *
     *  for (int i = 0; i < indices.Count - 1; i++)
     *  {
     *
     *      displacement = _newVerticesCache[indices[i]] - center;
     *      newUV1 = Vector3.zero;
     *      newUV1.x = 0.5f + Vector3.Dot(displacement, left);
     *      newUV1.y = 0.5f + Vector3.Dot(displacement, upward);
     *      //newUV1.z = 0.5f + Vector3.Dot(displacement, _blade.normal);
     *
     *      displacement = _newVerticesCache[indices[i + 1]] - center;
     *      newUV2 = Vector3.zero;
     *      newUV2.x = 0.5f + Vector3.Dot(displacement, left);
     *      newUV2.y = 0.5f + Vector3.Dot(displacement, upward);
     *      //newUV2.z = 0.5f + Vector3.Dot(displacement, _blade.normal);
     *
     *
     *
     *      _newTriangleCache.vertices[0] = _newVerticesCache[indices[i]];
     *      _newTriangleCache.uvs[0] = newUV1;
     *      _newTriangleCache.normals[0] = -_blade.normal;
     *      _newTriangleCache.tangents[0] = Vector4.zero;
     *
     *      _newTriangleCache.vertices[1] = _newVerticesCache[indices[i + 1]];
     *      _newTriangleCache.uvs[1] = newUV2;
     *      _newTriangleCache.normals[1] = -_blade.normal;
     *      _newTriangleCache.tangents[1] = Vector4.zero;
     *
     *      _newTriangleCache.vertices[2] = center;
     *      _newTriangleCache.uvs[2] = new Vector2(0.5f, 0.5f);
     *      _newTriangleCache.normals[2] = -_blade.normal;
     *      _newTriangleCache.tangents[2] = Vector4.zero;
     *
     *
     *      NormalCheck(ref _newTriangleCache);
     *
     *      _leftSide.AddTriangle(_newTriangleCache, _capMatSub);
     *
     *      _newTriangleCache.normals[0] = _blade.normal;
     *      _newTriangleCache.normals[1] = _blade.normal;
     *      _newTriangleCache.normals[2] = _blade.normal;
     *
     *      NormalCheck(ref _newTriangleCache);
     *
     *      _rightSide.AddTriangle(_newTriangleCache, _capMatSub);
     *
     *  }
     * }
     */
    #endregion

    #region Misc.
    //法線のチェック(ポリゴンの向きをチェック)
    private static void NormalCheck(ref MeshMaker.Triangle triangle)
    {
        // 2ベクトルの法線ベクトル
        // ポリゴンの法線ベクトルの算出
        Vector3 crossProduct = Vector3.Cross(triangle.vertices[1] - triangle.vertices[0], triangle.vertices[2] - triangle.vertices[0]);
        // 3点の重心から出る法線ベクトル
        Vector3 averageNormal = (triangle.normals[0] + triangle.normals[1] + triangle.normals[2]) / 3.0f;
        // 2ベクトル間の内積を求める
        float dotProduct = Vector3.Dot(averageNormal, crossProduct);

        // 内積が負=面の向きが違う
        if (dotProduct < 0)
        {
            // 3点の始点0と終点2を入れ替えて、表裏を入れ替える
            Vector3 temp = triangle.vertices[2];
            triangle.vertices[2] = triangle.vertices[0];
            triangle.vertices[0] = temp;

            temp = triangle.normals[2];
            triangle.normals[2] = triangle.normals[0];
            triangle.normals[0] = temp;

            Vector2 temp2 = triangle.uvs[2];
            triangle.uvs[2] = triangle.uvs[0];
            triangle.uvs[0] = temp2;

            Vector4 temp3 = triangle.tangents[2];
            triangle.tangents[2] = triangle.tangents[0];
            triangle.tangents[0] = temp3;
        }
    }
Exemple #2
0
    // Functions
    private static void Cut_this_Face(ref MeshMaker.Triangle triangle, int submesh)
    {
        // ブレードの表(左側)にあればtrue,違うならfalse
        isLeftSides[0] = blade.GetSide(triangle.vertices[0]); // true = left
        isLeftSides[1] = blade.GetSide(triangle.vertices[1]);
        isLeftSides[2] = blade.GetSide(triangle.vertices[2]);


        int leftCount  = 0;
        int rightCount = 0;

        for (int i = 0; i < 3; i++)
        {
            // もし頂点が左側なら
            if (isLeftSides[i])
            { // left
                // 左側頂点リストに追加
                _leftTriangleCache.vertices[leftCount] = triangle.vertices[i];
                _leftTriangleCache.uvs[leftCount]      = triangle.uvs[i];
                _leftTriangleCache.normals[leftCount]  = triangle.normals[i];
                _leftTriangleCache.tangents[leftCount] = triangle.tangents[i];
                // 左側頂点カウントを +1
                leftCount++;
            }
            else // それ以外(頂点が右側)なら
            { // right
                // 右側頂点リストに追加
                _rightTriangleCache.vertices[rightCount] = triangle.vertices[i];
                _rightTriangleCache.uvs[rightCount]      = triangle.uvs[i];
                _rightTriangleCache.normals[rightCount]  = triangle.normals[i];
                _rightTriangleCache.tangents[rightCount] = triangle.tangents[i];
                // 右側頂点カウントを +1
                rightCount++;
            }
        }

        // find the new triangles X 3
        // first the new vertices

        // this will give me a triangle with the solo point as first
        // 頂点の割合が1:2(左側が1)の時
        // 左側の頂点を始点としたトライアングルを生成
        if (leftCount == 1)
        {
            tmpTriangle.vertices[0] = _leftTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _leftTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _leftTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _leftTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _rightTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _rightTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _rightTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _rightTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _rightTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _rightTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _rightTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _rightTriangleCache.tangents[1];
        }
        else
        {
            // 頂点の割合が2:1(左側が2)の時
            // 右側の頂点を始点としたトライアングルを生成

            tmpTriangle.vertices[0] = _rightTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _rightTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _rightTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _rightTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _leftTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _leftTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _leftTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _leftTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _leftTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _leftTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _leftTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _leftTriangleCache.tangents[1];
        }

        // now to find the intersection points between the solo point and the others
        // 1つ側の頂点から、残り2点までの間にあるブレードの交点を求める
        float   distance           = 0;
        float   normalizedDistance = 0.0f;
        Vector3 edgeVector         = Vector3.zero; // contains edge length and direction

        // 頂点0から頂点1までのベクトルをedgeVectorへ
        edgeVector = tmpTriangle.vertices[1] - tmpTriangle.vertices[0];
        // Raycast(頂点0からedgeVector(単位ベクトルへ変換)に向けて)レイを照射、距離を取得
        blade.Raycast(new Ray(tmpTriangle.vertices[0], edgeVector.normalized), out distance);

        // edgeVector.magunitude = ベクトルの距離
        // normalizedDistance = ベクトルの距離の比(頂点0から頂点1までの距離を1とした時のブレードまでの距離)
        normalizedDistance = distance / edgeVector.magnitude;
        // lerp(点1,点2,割合)で、頂点0から頂点1までのベクトルをnormalizedDistanceの割合で作成する
        _newTriangleCache.vertices[0] = Vector3.Lerp(tmpTriangle.vertices[0], tmpTriangle.vertices[1], normalizedDistance);
        // ↑のuvバージョン
        _newTriangleCache.uvs[0] = Vector2.Lerp(tmpTriangle.uvs[0], tmpTriangle.uvs[1], normalizedDistance);
        // ↑の法線ベクトルバージョン
        _newTriangleCache.normals[0] = Vector3.Lerp(tmpTriangle.normals[0], tmpTriangle.normals[1], normalizedDistance);
        // ↑の接線ベクトルバージョン
        _newTriangleCache.tangents[0] = Vector4.Lerp(tmpTriangle.tangents[0], tmpTriangle.tangents[1], normalizedDistance);

        // さっきの処理を頂点0と頂点2で行う
        edgeVector = tmpTriangle.vertices[2] - tmpTriangle.vertices[0];
        blade.Raycast(new Ray(tmpTriangle.vertices[0], edgeVector.normalized), out distance);

        normalizedDistance            = distance / edgeVector.magnitude;
        _newTriangleCache.vertices[1] = Vector3.Lerp(tmpTriangle.vertices[0], tmpTriangle.vertices[2], normalizedDistance);
        _newTriangleCache.uvs[1]      = Vector2.Lerp(tmpTriangle.uvs[0], tmpTriangle.uvs[2], normalizedDistance);
        _newTriangleCache.normals[1]  = Vector3.Lerp(tmpTriangle.normals[0], tmpTriangle.normals[2], normalizedDistance);
        _newTriangleCache.tangents[1] = Vector4.Lerp(tmpTriangle.tangents[0], tmpTriangle.tangents[2], normalizedDistance);

        // 新しく作った頂点がお互い異なるなら成功
        if (_newTriangleCache.vertices[0] != _newTriangleCache.vertices[1])
        {
            //新しい頂点を新ポリゴンリストに追加
            //tracking newly created points
            newVertices.Add(_newTriangleCache.vertices[0]);
            newVertices.Add(_newTriangleCache.vertices[1]);
        }
        // make the new triangles
        // one side will get 1 the other will get 2
        // 頂点の割合が1:2(左側が1)の時
        if (leftCount == 1)
        {
            // first one on the left
            // ブレードの左部分ポリゴン
            tmpTriangle.vertices[0] = _leftTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _leftTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _leftTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _leftTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _newTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _newTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _newTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _newTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            // ポリゴンの表面が裏を向いていないかチェック
            NormalCheck(ref tmpTriangle);

            // add it
            //ポリゴンを左側ポリゴンリストに追加
            leftMeshMaker.AddTriangle(tmpTriangle, submesh);


            // other two on the right
            // 右側の4角形を3角形のポリゴン2つにする。

            //一つ目
            tmpTriangle.vertices[0] = _rightTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _rightTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _rightTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _rightTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _newTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _newTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _newTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _newTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            NormalCheck(ref tmpTriangle);

            // add it
            rightMeshMaker.AddTriangle(tmpTriangle, submesh);

            // third
            // 右側2つ目
            tmpTriangle.vertices[0] = _rightTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _rightTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _rightTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _rightTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _rightTriangleCache.vertices[1];
            tmpTriangle.uvs[1]      = _rightTriangleCache.uvs[1];
            tmpTriangle.normals[1]  = _rightTriangleCache.normals[1];
            tmpTriangle.tangents[1] = _rightTriangleCache.tangents[1];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            NormalCheck(ref tmpTriangle);

            // add it
            rightMeshMaker.AddTriangle(tmpTriangle, submesh);
        }
        else //上の処理の左右逆パターン
        {
            // first one on the right
            tmpTriangle.vertices[0] = _rightTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _rightTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _rightTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _rightTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _newTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _newTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _newTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _newTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            NormalCheck(ref tmpTriangle);

            // add it
            rightMeshMaker.AddTriangle(tmpTriangle, submesh);


            // other two on the left
            tmpTriangle.vertices[0] = _leftTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _leftTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _leftTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _leftTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _newTriangleCache.vertices[0];
            tmpTriangle.uvs[1]      = _newTriangleCache.uvs[0];
            tmpTriangle.normals[1]  = _newTriangleCache.normals[0];
            tmpTriangle.tangents[1] = _newTriangleCache.tangents[0];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            NormalCheck(ref tmpTriangle);

            // add it
            leftMeshMaker.AddTriangle(tmpTriangle, submesh);

            // third
            tmpTriangle.vertices[0] = _leftTriangleCache.vertices[0];
            tmpTriangle.uvs[0]      = _leftTriangleCache.uvs[0];
            tmpTriangle.normals[0]  = _leftTriangleCache.normals[0];
            tmpTriangle.tangents[0] = _leftTriangleCache.tangents[0];

            tmpTriangle.vertices[1] = _leftTriangleCache.vertices[1];
            tmpTriangle.uvs[1]      = _leftTriangleCache.uvs[1];
            tmpTriangle.normals[1]  = _leftTriangleCache.normals[1];
            tmpTriangle.tangents[1] = _leftTriangleCache.tangents[1];

            tmpTriangle.vertices[2] = _newTriangleCache.vertices[1];
            tmpTriangle.uvs[2]      = _newTriangleCache.uvs[1];
            tmpTriangle.normals[2]  = _newTriangleCache.normals[1];
            tmpTriangle.tangents[2] = _newTriangleCache.tangents[1];

            // check if it is facing the right way
            NormalCheck(ref tmpTriangle);

            // add it
            leftMeshMaker.AddTriangle(tmpTriangle, submesh);
        }
    }