Exemple #1
0
        public void ChangeLength(float newLength)
        {
            // clamp new length to sane limits:
            newLength = Mathf.Clamp(newLength, 0, (rope.blueprint.particleCount - 1) * rope.ropeBlueprint.interParticleDistance);

            // calculate the change in rope length:
            float lengthChange = newLength - rope.restLength;

            // remove:
            if (lengthChange < 0)
            {
                lengthChange = -lengthChange;

                while (lengthChange > m_CursorElement.restLength)
                {
                    lengthChange -= m_CursorElement.restLength;

                    int index = rope.elements.IndexOf(m_CursorElement);

                    if (index >= 0)
                    {
                        // positive direction:
                        if (direction)
                        {
                            RemoveParticleAt(rope.solver.particleToActor[m_CursorElement.particle2].indexInActor);
                            rope.elements.RemoveAt(index);

                            if (index < rope.elements.Count && rope.elements[index].particle1 == m_CursorElement.particle2)
                            {
                                rope.elements[index].particle1 = m_CursorElement.particle1;
                            }

                            m_CursorElement = rope.elements[index];
                        }
                        else // negative direction:
                        {
                            RemoveParticleAt(rope.solver.particleToActor[m_CursorElement.particle1].indexInActor);
                            rope.elements.RemoveAt(index);

                            if (index > 0)
                            {
                                if (rope.elements[index - 1].particle2 == m_CursorElement.particle1)
                                {
                                    rope.elements[index - 1].particle2 = m_CursorElement.particle2;
                                }
                                m_CursorElement = rope.elements[index - 1];
                            }
                            else
                            {
                                m_CursorElement = rope.elements[0];
                            }
                        }
                    }
                }

                // the remaining length is subtracted from the current constraint:
                if (lengthChange > 0)
                {
                    m_CursorElement.restLength = Mathf.Max(0, m_CursorElement.restLength - lengthChange);
                }
            }
            // add
            else
            {
                float lengthDelta = Mathf.Min(lengthChange, Mathf.Max(0, rope.ropeBlueprint.interParticleDistance - m_CursorElement.restLength));

                // extend the current element, if possible:
                if (lengthDelta > 0)
                {
                    m_CursorElement.restLength += lengthDelta;
                    lengthChange -= lengthDelta;
                }

                // once the current element has been extended, see if we must add new elements:
                while (m_CursorElement.restLength + lengthChange > rope.ropeBlueprint.interParticleDistance)
                {
                    // calculate added length:
                    lengthDelta   = Mathf.Min(lengthChange, rope.ropeBlueprint.interParticleDistance);
                    lengthChange -= lengthDelta;

                    if (direction)
                    {
                        // add new particle:
                        int newParticleSolverIndex = AddParticleAt(rope.solver.particleToActor[m_CursorElement.particle1].indexInActor);

                        // insert a new element:
                        ObiStructuralElement newElement = new ObiStructuralElement();
                        newElement.restLength     = lengthDelta;
                        newElement.particle1      = m_CursorElement.particle1;
                        newElement.particle2      = newParticleSolverIndex;
                        m_CursorElement.particle1 = newParticleSolverIndex;
                        int index = rope.elements.IndexOf(m_CursorElement);
                        rope.elements.Insert(index, newElement);

                        m_CursorElement = newElement;
                    }
                    else
                    {
                        // add new particle:
                        int newParticleSolverIndex = AddParticleAt(rope.solver.particleToActor[m_CursorElement.particle2].indexInActor);

                        // insert a new element:
                        ObiStructuralElement newElement = new ObiStructuralElement();
                        newElement.restLength     = lengthDelta;
                        newElement.particle1      = newParticleSolverIndex;
                        newElement.particle2      = m_CursorElement.particle2;
                        m_CursorElement.particle2 = newParticleSolverIndex;
                        int index = rope.elements.IndexOf(m_CursorElement);
                        rope.elements.Insert(index + 1, newElement);

                        m_CursorElement = newElement;
                    }
                }

                // the remaining length is added to the current constraint:
                if (lengthChange > 0)
                {
                    m_CursorElement.restLength += lengthChange;
                }
            }

            rope.RebuildConstraintsFromElements();
            rope.RecalculateRestLength();
        }