Esempio n. 1
0
    private void UpdateRopeSimulation(float deltaTime)
    {
        //actualizar pos1 en la lista por si se ha movido
        CilinderBody lastRopeSection = ropeSegments[ropeSegments.Count - 1];

        lastRopeSection.pos = new Vector3Class(pos1.position);
        ropeSegments[ropeSegments.Count - 1] = lastRopeSection;

        //calcular acceleraciones
        CalculateAccelerations();

        //actualizar la posicion de todos los segmentos excepto el ultimo (top)
        for (int i = 0; i < ropeSegments.Count - 1; i++)
        {
            CilinderBody thisRopeSection = new CilinderBody();

            //Forward Euler
            thisRopeSection.speed = ropeSegments[i].speed + ropeSegments[i].acc * deltaTime;
            thisRopeSection.pos   = ropeSegments[i].pos + ropeSegments[i].speed * deltaTime;

            ropeSegments[i] = thisRopeSection;
        }

        //regular estiramiento de los segmentos, tambien se recomienda ejecutar mas de una vez (para corregir el maximo posible)
        //ya que cuando se cambia la posicion de uno, quiza hace falta regular el resto, y quizá sólo serian accesibles repitiendo el proceso
        int maximumStretchIterations = 2;

        for (int i = 0; i < maximumStretchIterations; i++)
        {
            ImplementMaximumStretch();
        }
    }
Esempio n. 2
0
    private void CalculateAccelerations()
    {
        //calculamos la fuerza de cada muelle y las guardamos en una lista para luego adjudicarla a los segmentos
        List <Vector3Class> springForces = new List <Vector3Class>();

        for (int i = 0; i < ropeSegments.Count - 1; i++)
        {
            Vector3Class p1p2 = ropeSegments[i + 1].pos - ropeSegments[i].pos;

            //elasticity part
            float part1 = kElasticity * (p1p2.Size() - stringPartLength);

            //Damping part
            float part2 = kDamping * ((p1p2.DotProduct(ropeSegments[i + 1].speed - ropeSegments[i].speed, p1p2.Normalize(p1p2))));

            //calculamos total del muelle juntando las 2 partes
            Vector3Class resultForce = p1p2.Normalize(p1p2);
            resultForce *= (part1 + part2) * -1;

            //al estar el orden de pos2 a pos1, este force es el negativo (f2)
            resultForce *= -1;

            springForces.Add(resultForce);
        }

        for (int i = 0; i < ropeSegments.Count - 1; i++)
        {
            Vector3Class springForce = new Vector3Class();
            //spring que corresponde a F1 de la formula
            if (i != 0)
            {
                springForce -= springForces[i - 1];
            }

            //spring que corresponde a F2 de la formula
            springForce += springForces[i];

            //masa del segmento de la cuerda, hacemos variable a parte para añadir el peso de la bola al ultimo
            float springMass = massRopeSegment;
            //segmento con la bola
            if (i == 0)
            {
                springMass = massLastRopeSegment;
            }

            //creamos fuerza de gravedad con la masa
            Vector3Class gravityForce = new Vector3Class(0f, gravity, 0f);
            gravityForce *= springMass;

            //sumamos ambas fuerzas calculadas
            Vector3Class totalForce = springForce + gravityForce;
            //finalmente, calculamos la aceleracion resultante de la fuerza
            Vector3Class acceleration = totalForce / springMass;
            CilinderBody temp         = ropeSegments[i];
            temp.acc        = acceleration;
            ropeSegments[i] = temp;
        }
    }
Esempio n. 3
0
    private void ImplementMaximumStretch()
    {
        //loop por todos los puntos para ajustarlos, de arriba a abajo
        for (int i = ropeSegments.Count - 1; i > 0; i--)
        {
            //recibimos 2 segmentos para comparar
            Vector3Class topSegment    = ropeSegments[i].pos;
            CilinderBody bottomSegment = ropeSegments[i - 1]; //este es CilinderBody porque modificaremos su pos si hace falta

            //distancia entre ambos segmentos
            float dist = (topSegment - bottomSegment.pos).Size();

            //si esta distancia supera el maximo
            if (dist > maxStretch)
            {
                //calculamos la diferencia entre la distancia actual y el maximo fijado
                float diffenceLength = dist - maxStretch;

                //vector normalizado para establecer la direccion del vector para ajustar el segmento
                Vector3Class adjustDirection = topSegment.Normalize(topSegment - bottomSegment.pos);

                //vector resultante para ajustar al segmento
                Vector3Class adjustVec = adjustDirection * diffenceLength;

                //sumamos vector resultante con posicion de bottomsegment y actualizamos pos del segmento
                bottomSegment.pos  += adjustVec;
                ropeSegments[i - 1] = bottomSegment;
            }
            else if (dist < minStretch)
            {
                //calculamos la diferencia entre la distancia actual y el maximo fijado
                float differenceLength = minStretch - dist;

                //vector normalizado para establecer la direccion del vector para ajustar el segmento
                Vector3Class adjustDirection = topSegment.Normalize(bottomSegment.pos - topSegment);

                //vector resultante para ajustar al segmento
                Vector3Class adjustVec = adjustDirection * differenceLength;
                //sumamos vector resultante con posicion de bottomsegment y actualizamos pos del segmento
                bottomSegment.pos  += adjustVec;
                ropeSegments[i - 1] = bottomSegment;
            }
        }
    }