Package toxi.physics3d

Source Code of toxi.physics3d.VerletSpring3D

/*
*   __               .__       .__  ._____.          
* _/  |_  _______  __|__| ____ |  | |__\_ |__   ______
* \   __\/  _ \  \/  /  |/ ___\|  | |  || __ \ /  ___/
*  |  | (  <_> >    <|  \  \___|  |_|  || \_\ \\___ \
*  |__|  \____/__/\_ \__|\___  >____/__||___  /____  >
*                   \/       \/             \/     \/
*
* Copyright (c) 2006-2011 Karsten Schmidt
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* http://creativecommons.org/licenses/LGPL/2.1/
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
*/

package toxi.physics3d;

import toxi.geom.Vec3D;

/**
* <p>
* A spring class connecting two VerletParticles in space. Based on the
* configuration of the spring instance and that of the physics engine, the
* behaviour of the spring can vary between springy and stiff/stick like.
* </p>
*
* <p>
* The simulation takes particle weights into account and can be configured to
* lock either particle in space in order to force the other one to move. This
* is sometimes handy for resolving collisions (currently outside the scope of
* this library).
* </p>
*
* @see toxi.physics3d.VerletPhysics3D
*/
public class VerletSpring3D {

    protected static final float EPS = 1e-6f;

    /**
     * Spring end points / particles
     */
    public VerletParticle3D a, b;

    /**
     * Spring rest length to which it always wants to return too
     */
    protected float restLength, restLengthSquared;

    /**
     * Spring strength, possible value range depends on engine configuration
     * (time step, drag)
     */
    protected float strength;

    /**
     * Flag, if either particle is locked in space (only within the scope of
     * this spring)
     */
    protected boolean isALocked, isBLocked;

    /**
     * @param a
     *            1st particle
     * @param b
     *            2nd particle
     * @param len
     *            desired rest length
     * @param str
     *            spring strength
     */
    public VerletSpring3D(VerletParticle3D a, VerletParticle3D b, float len, float str) {
        this.a = a;
        this.b = b;
        restLength = len;
        strength = str;
    }

    public final float getRestLength() {
        return restLength;
    }

    public final float getStrength() {
        return strength;
    }

    /**
     * (Un)Locks the 1st end point of the spring. <b>NOTE: this acts purely
     * within the scope of this spring instance and does NOT call
     * {@link VerletParticle3D#lock()}</b>
     *
     * @param s
     * @return itself
     */
    public VerletSpring3D lockA(boolean s) {
        isALocked = s;
        return this;
    }

    /**
     * (Un)Locks the 2nd end point of the spring
     *
     * @param s
     * @return itself
     */

    public VerletSpring3D lockB(boolean s) {
        isBLocked = s;
        return this;
    }

    public VerletSpring3D setRestLength(float len) {
        restLength = len;
        restLengthSquared = len * len;
        return this;
    }

    public VerletSpring3D setStrength(float strength) {
        this.strength = strength;
        return this;
    }

    /**
     * Updates both particle positions (if not locked) based on their current
     * distance, weight and spring configuration *
     */
    protected void update(boolean applyConstraints) {
        Vec3D delta = b.sub(a);
        // add minute offset to avoid div-by-zero errors
        float dist = delta.magnitude() + EPS;
        float normDistStrength = (dist - restLength)
                / (dist * (a.invWeight + b.invWeight)) * strength;
        if (!a.isLocked && !isALocked) {
            a.addSelf(delta.scale(normDistStrength * a.invWeight));
            if (applyConstraints) {
                a.applyConstraints();
            }
        }
        if (!b.isLocked && !isBLocked) {
            b.addSelf(delta.scale(-normDistStrength * b.invWeight));
            if (applyConstraints) {
                b.applyConstraints();
            }
        }
    }
}
TOP

Related Classes of toxi.physics3d.VerletSpring3D

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.