示例#1
0
        protected override void RebuildElementsFromConstraintsInternal()
        {
            var dc = GetConstraintsByType(Oni.ConstraintType.StretchShear) as ObiConstraints <ObiStretchShearConstraintsBatch>;

            if (dc == null)
            {
                return;
            }

            int constraintCount = dc.batches[0].activeConstraintCount + dc.batches[1].activeConstraintCount;

            elements = new List <ObiStructuralElement>(constraintCount);

            for (int i = 0; i < constraintCount; ++i)
            {
                var batch           = dc.batches[i % 2] as ObiStretchShearConstraintsBatch;
                int constraintIndex = i / 2;

                var e = new ObiStructuralElement();
                e.particle1  = batch.particleIndices[constraintIndex * 2];
                e.particle2  = batch.particleIndices[constraintIndex * 2 + 1];
                e.restLength = batch.restLengths[constraintIndex];
                elements.Add(e);
            }

            if (dc.batches.Count > 2)
            {
                var batch = dc.batches[2];
                var e     = new ObiStructuralElement();
                e.particle1  = batch.particleIndices[0];
                e.particle2  = batch.particleIndices[1];
                e.restLength = batch.restLengths[0];
                elements.Add(e);
            }
        }
        public bool Tear(ObiStructuralElement element)
        {
            // don't allow splitting if there are no free particles left in the pool.
            if (activeParticleCount >= m_RopeBlueprint.particleCount)
            {
                return(false);
            }

            // Cannot split fixed particles:
            if (m_Solver.invMasses[element.particle1] == 0)
            {
                return(false);
            }

            // Or particles that have been already split.
            int index = elements.IndexOf(element);

            if (index > 0 && elements[index - 1].particle2 != element.particle1)
            {
                return(false);
            }

            element.particle1 = SplitParticle(element.particle1);

            return(true);
        }
示例#3
0
 public void UpdateCursor()
 {
     rope            = GetComponent <ObiRope>();
     m_CursorElement = null;
     if (rope.isLoaded)
     {
         float elmMu;
         m_CursorElement = rope.GetElementAt(cursorMu, out elmMu);
     }
 }
示例#4
0
        protected override void RebuildElementsFromConstraintsInternal()
        {
            var dc = GetConstraintsByType(Oni.ConstraintType.Distance) as ObiConstraints <ObiDistanceConstraintsBatch>;

            if (dc == null || dc.GetBatchCount() < 2)
            {
                return;
            }

            int constraintCount = dc.batches[0].activeConstraintCount + dc.batches[1].activeConstraintCount;

            elements = new List <ObiStructuralElement>(constraintCount);

            for (int i = 0; i < constraintCount; ++i)
            {
                var batch           = dc.batches[i % 2] as ObiDistanceConstraintsBatch;
                int constraintIndex = i / 2;

                var e = new ObiStructuralElement();
                e.particle1      = solverIndices[batch.particleIndices[constraintIndex * 2]];
                e.particle2      = solverIndices[batch.particleIndices[constraintIndex * 2 + 1]];
                e.restLength     = batch.restLengths[constraintIndex];
                e.tearResistance = 1;
                elements.Add(e);
            }

            // loop-closing element:
            if (dc.batches.Count > 2)
            {
                var batch = dc.batches[2];
                var e     = new ObiStructuralElement();
                e.particle1      = solverIndices[batch.particleIndices[0]];
                e.particle2      = solverIndices[batch.particleIndices[1]];
                e.restLength     = batch.restLengths[0];
                e.tearResistance = 1;
                elements.Add(e);
            }
        }
        public void UpdateRenderer(ObiActor actor)
        {
            using (m_UpdateChainRopeRendererChunksPerfMarker.Auto())
            {
                var rope = actor as ObiRopeBase;

                // In case there are no link prefabs to instantiate:
                if (linkPrefabs.Count == 0)
                {
                    return;
                }

                // Regenerate instances if needed:
                if (linkInstances == null || linkInstances.Count < rope.particleCount)
                {
                    CreateChainLinkInstances(rope);
                }

                var blueprint    = rope.blueprint;
                int elementCount = rope.elements.Count;

                float twist = -sectionTwist * elementCount * twistAnchor;

                //we will define and transport a reference frame along the curve using parallel transport method:
                frame.Reset();
                frame.SetTwist(twist);

                int lastParticle = -1;

                for (int i = 0; i < elementCount; ++i)
                {
                    ObiStructuralElement elm = rope.elements[i];

                    Vector3 pos        = rope.GetParticlePosition(elm.particle1);
                    Vector3 nextPos    = rope.GetParticlePosition(elm.particle2);
                    Vector3 linkVector = nextPos - pos;
                    Vector3 tangent    = linkVector.normalized;

                    if (rope.blueprint.usesOrientedParticles)
                    {
                        frame.Transport(nextPos, tangent, rope.GetParticleOrientation(elm.particle1) * Vector3.up, twist);
                        twist += sectionTwist;
                    }
                    else
                    {
                        frame.Transport(nextPos, tangent, sectionTwist);
                    }

                    if (linkInstances[i] != null)
                    {
                        linkInstances[i].SetActive(true);
                        Transform linkTransform = linkInstances[i].transform;
                        linkTransform.position   = pos + linkVector * 0.5f;
                        linkTransform.localScale = rope.GetParticleMaxRadius(elm.particle1) * 2 * linkScale;
                        linkTransform.rotation   = Quaternion.LookRotation(tangent, frame.normal);
                    }

                    lastParticle = elm.particle2;
                }

                for (int i = elementCount; i < linkInstances.Count; ++i)
                {
                    if (linkInstances[i] != null)
                    {
                        linkInstances[i].SetActive(false);
                    }
                }
            }
        }
示例#6
0
            public int particleIndex;               /**< index of the particle being torn*/

            public ObiRopeTornEventArgs(ObiStructuralElement element, int particle)
            {
                this.element       = element;
                this.particleIndex = particle;
            }
示例#7
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();
        }