示例#1
0
    //-------

    public Verlet(Plant.InitPoint[] init_data, Transform parent)
    {
        _parent = parent;

        // init from init data
        //--------------------------------------------------
        _points = new Point[init_data.Length];
        for (int i = 0; i < init_data.Length; ++i)
        {
            if (init_data[i].parent < 0)
            {
                init_data[i].is_fixed = true;
            }

            // transform

            init_data[i].pos *= Plant.SCALE;

            _points[i] = new Point();
            _points[i].curr_mat.SetTRS(init_data[i].pos, Quaternion.identity, Vector3.one);
            _points[i].prev_mat = _points[i].curr_mat;
            _points[i].is_fixed = init_data[i].is_fixed;
        }

        BetterList <ConstraintPosition> new_const_pos = new BetterList <ConstraintPosition>();

        for (int i = 0; i < init_data.Length; ++i)
        {
            if (init_data[i].parent >= 0)
            {
                ConstraintPosition cp = new ConstraintPosition();
                cp.index_0 = i;
                cp.index_1 = init_data[i].parent;
                new_const_pos.Add(cp);
            }
        }
        _pos_constraints = new ConstraintPosition[0];
        if (new_const_pos.size > 0)
        {
            _pos_constraints = new_const_pos.ToArray();
        }

        BetterList <ConstraintSoft> new_const_soft = new BetterList <ConstraintSoft>();

        for (int i = 0; i < init_data.Length; ++i)
        {
            if (init_data[i].soft_clamp)
            {
                ConstraintSoft cs = new ConstraintSoft();
                cs.index_0      = i;
                cs.index_parent = init_data[i].parent;
                cs.min_dist     = init_data[i].soft_min * Plant.SCALE;
                cs.max_dist     = init_data[i].soft_max * Plant.SCALE;
                new_const_soft.Add(cs);
            }
        }
        _soft_constraints = new ConstraintSoft[0];
        if (new_const_soft.size > 0)
        {
            _soft_constraints = new_const_soft.ToArray();
        }

        //--------------------------------------------------

        for (int i = 0; i < _pos_constraints.Length; ++i)
        {
            Vector3 p0 = _points[_pos_constraints[i].index_0].curr_mat.GetColumn(3);
            Vector3 p1 = _points[_pos_constraints[i].index_1].curr_mat.GetColumn(3);

            float d = Vector3.Distance(p0, p1);
            _pos_constraints[i].rest_length = d;
        }

        for (int i = 0; i < _soft_constraints.Length; ++i)
        {
            Vector3 p0 = _points[_soft_constraints[i].index_0].curr_mat.GetColumn(3);
            Vector3 p1 = _points[_soft_constraints[i].index_parent].curr_mat.GetColumn(3);

            Vector3 offset = p0 - p1;

            _soft_constraints[i].target_offset = offset;
        }
    }
示例#2
0
    void FillAngleConstraintBuffer()
    {
        _angle_constraint_force.Clear();
        for (int i = 0; i < _points.Length; ++i)
        {
            _angle_constraint_force.Add(Vector3.zero);
        }

        for (int a = 0; a < _soft_constraints.Length; a++)
        {
            ConstraintSoft con = _soft_constraints[a];

            Vector3 p0 = _points[con.index_0].curr_mat.GetColumn(3);
            Vector3 p1 = _points[con.index_parent].curr_mat.GetColumn(3);

            Vector3 force = Vector3.zero;

            Vector3 curr_offset = p0 - p1;
            Vector3 target      = _points[con.index_parent].curr_mat.inverse.MultiplyVector(_soft_constraints[a].target_offset);

            Vector3 diff = target - curr_offset;
            float   dist = diff.magnitude;

            float multi = 0f;
            if (dist > con.min_dist)
            {
                multi = (dist - con.min_dist) / Mathf.Max(0.01f, con.max_dist);
            }

            force = diff * multi;

            //---

            _angle_constraint_force[con.index_0] += force;

            //Vector3 tp = transform.position;
            //Debug.DrawLine(tp + p0, tp + p0 + force, Color.yellow);
            //Debug.DrawLine(tp + p1, tp + p1 + target, Color.cyan);
        }

        // force for segments

        /*
         * if (PlantManager.Exists)
         * {
         *      for(int a = 0; a < PlantManager.Instance._avoids.Count; ++a)
         *      {
         *              PlantAvoid pa = PlantManager.Instance._avoids[a];
         *
         *              // segments
         *              for (int v = 0; v < _pos_constraints.Length; v++)
         *              {
         *                      int i0 = _pos_constraints[v].index_0;
         *                      int i1 = _pos_constraints[v].index_1;
         *
         *                      Vector3 p0 = _parent.position + GetPointPos(i0);
         *                      Vector3 p1 = _parent.position + GetPointPos(i1);
         *
         *                      Vector3 closest = UtilMath.ClosestPointOnLineSegment3D(p0, p1, pa.transform.position);
         *                      Vector3 dist = closest - pa.transform.position;
         *
         *                      if (dist.magnitude < pa.radius)
         *                      {
         *                              float multi = 1f - (dist.magnitude / pa.radius);
         *
         *                              Vector3 push = (dist.normalized * pa.radius) * multi;
         *
         *                              _angle_constraint_force[i0] += push;
         *                              _angle_constraint_force[i1] += push;
         *                      }
         *              }
         *      }
         * }*/
    }