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