Ejemplo n.º 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;
        }
    }
			/// <summary>
			/// Resets the field storing constraint information and the logical position to OutsideConstraint.
			/// </summary>
			public void ResetConstraintData()
			{
				CurrentConstraintStart = -1;
				CurrentParameters.Clear();
				CurrentConstraintName = string.Empty;
				IsMasked = false;
				LogicalPosition = ConstraintPosition.OutsideConstraint;
			}
Ejemplo n.º 3
0
    void SatisfyConstraints()
    {
        const int numIterations = 5;

        for (int i = 0; i < numIterations; i++)
        {
            // Constraint (avoids)
            if (PlantManager.Exists)
            {
                for (int a = 0; a < PlantManager.Instance._avoids.Count; ++a)
                {
                    PlantAvoid pa = PlantManager.Instance._avoids[a];

                    // points
                    for (int v = 0; v < _points.Length; v++)
                    {
                        Vector3 pos = _parent.position + GetPointPos(v);

                        Vector3 dist = pos - pa.transform.position;

                        float r = pa.radius + Plant.SCALE * 0.3f;

                        if (dist.magnitude < r)
                        {
                            pos = (pa.transform.position + (dist.normalized * r)) - _parent.position;

                            _points[v].curr_mat.SetColumn(3,
                                                          new Vector4(pos.x, pos.y, pos.z, 1f));
                        }
                    }

                    // 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;

                        float r = pa.radius + Plant.SCALE * 0.1f;

                        if (dist.magnitude < r)
                        {
                            dist = (dist.normalized * r) - dist;

                            // set point
                            p0 = GetPointPos(i0) + dist;
                            p1 = GetPointPos(i1) + dist;

                            SetPointPos(i0, p0);
                            SetPointPos(i1, p1);

                            // force
                            //float multi = 1f - (dist.magnitude / pa.radius);
                            //Vector3 push = (dist.normalized * pa.radius) * multi;
                            //_angle_constraint_force[i0] += push;
                            //_angle_constraint_force[i1] += push;
                        }
                    }
                }
            }

            // Constraint (floor)
            for (int v = 0; v < _points.Length; v++)
            {
                Vector3 cp = _points[v].curr_mat.GetColumn(3);
                if (cp.y + _parent.position.y < 0f)
                {
                    _points[v].curr_mat.SetColumn(3, new Vector4(cp.x, -_parent.position.y, cp.z, 1f));
                }
            }

            for (int k = 0; k < _pos_constraints.Length; k++)
            {
                ConstraintPosition c = _pos_constraints[k];

                // positions constraint
                Vector3 p0    = _points[c.index_0].curr_mat.GetColumn(3);
                Vector3 p1    = _points[c.index_1].curr_mat.GetColumn(3);
                Vector3 delta = p1 - p0;

                float len = delta.magnitude;

                float diff = (len - c.rest_length) / len;
                //p0 += delta * 0.5f * diff;
                //p1 -= delta * 0.5f * diff;

                // mass change
                // push child more than parent
                p0 += delta * 0.8f * diff;
                p1 -= delta * 0.2f * diff;

                _points[c.index_0].curr_mat.SetColumn(3, new Vector4(p0.x, p0.y, p0.z, 1f));
                _points[c.index_1].curr_mat.SetColumn(3, new Vector4(p1.x, p1.y, p1.z, 1f));


                if (_points[c.index_0].is_fixed)
                {
                    _points[c.index_0].curr_mat = _points[c.index_0].prev_mat;
                }
                if (_points[c.index_1].is_fixed)
                {
                    _points[c.index_1].curr_mat = _points[c.index_1].prev_mat;
                }
            }
        }
    }
			/// <summary>
			/// Initializes a new instance of the ParserContext class with the specified constraint string.
			/// </summary>
			/// <param name="constraintString">The constraint string to parse.</param>
			/// <param name="dataType">The data type of the parameter.</param>
			internal ParserContext(string constraintString, ParameterDataType dataType)
			{
				ConstraintString = constraintString;
				DataType = dataType;
				Constraints = new List<Constraint>();
				LogicalPosition = ConstraintPosition.OutsideConstraint;
				CurrentConstraintStart = -1;
				StringPosition = -1;
				CurrentParameters = new List<string>();
				CurrentConstraintName = string.Empty;
				IsMasked = false;
				CurrentParameter = new StringBuilder();
				CurrentCharacter = char.MinValue;
				StringLength = constraintString.Length;
			}