/** * Copyright (c) 2014, jMonkeyEngine All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * * Redistributions of source code must retain the above copyright notice, this * list of conditions and the following disclaimer. * * Redistributions in binary form must reproduce the above copyright notice, * this list of conditions and the following disclaimer in the documentation * and/or other materials provided with the distribution. * * Neither the name of 'jMonkeyEngine' nor the names of its contributors may be * used to endorse or promote products derived from this software without * specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE * POSSIBILITY OF SUCH DAMAGE. */ package com.jme3.ai.agents.behaviors.npc.steering; import com.jme3.ai.agents.Agent; import com.jme3.math.FastMath; import com.jme3.math.Vector3f; import com.jme3.scene.Spatial; /** * This behavior is based on a easy implementation that "generates random * steering force each frame, but this produces rather uninteresting motion. * It is 'twitchy' and produces no sustained turns. <br><br> * * Steer forces changes durring time. * * @see AbstractWander * * @author Jesús Martín Berlanga * @version 1.0 */ public class SimpleWanderBehavior extends AbstractWanderBehavior { /** * Current steer force. */ protected Vector3f currentSteer = Vector3f.ZERO; /** * Current time. */ protected float time = -1; /** * Random offset */ protected class MaxRandSteer { public float x; public float y; public float z; } /** * @see Offset */ protected MaxRandSteer maxRandSteer = new MaxRandSteer(); private float constantMod = -1; private boolean hasConstantMod = false; /** * @param agent to whom behavior belongs * @param rX max x-random steer * @param rY max y-random steer * @param rZ max z-random steer */ public SimpleWanderBehavior(Agent agent, float rX, float rY, float rZ) { super(agent); velocity = new Vector3f(); timeInterval = 2f; maxRandSteer.x = rX; maxRandSteer.y = rY; maxRandSteer.z = rZ; } /** * @param spatial active spatial during excecution of behavior * @see SimpleWanderBehavior#SimpleWanderBehavior(com.jme3.ai.agents.Agent, float, float, float) */ public SimpleWanderBehavior(Agent agent, float rX, float rY, float rZ, Spatial spatial) { super(agent, spatial); velocity = new Vector3f(); timeInterval = 2f; maxRandSteer.x = rX; maxRandSteer.y = rY; maxRandSteer.z = rZ; } /** * Calculate steering vector. * * @return steering vector */ @Override protected Vector3f calculateRawSteering() { changeSteer(timePerFrame); if(getHasConstantMod()) currentSteer.normalizeLocal().multLocal(constantMod); return currentSteer; } /** * Metod for changing the steer force. * * @param tpf time per frame */ protected void changeSteer(float tpf) { time -= tpf; if (time <= 0) { currentSteer = newRandomSteer(); time = timeInterval; } } /** * @return A new random steer force */ protected Vector3f newRandomSteer() { float rX = (FastMath.nextRandomFloat() - 0.5f)*2 * maxRandSteer.x; float rY = (FastMath.nextRandomFloat() - 0.5f)*2 * maxRandSteer.y; float rZ = (FastMath.nextRandomFloat() - 0.5f)*2 * maxRandSteer.z; return new Vector3f(rX, rY, rZ); } /** * Setting random steer * * @param rX max x-random steer * @param rY max y-random steer * @param rZ max z-random steer */ public void setMaxRandSteer(float rX, float rY, float rZ) { this.maxRandSteer.x = rX; this.maxRandSteer.y = rY; this.maxRandSteer.z = rZ; } /** * The generated steer module will be a constant value. * If the distance is 0 or lower, there will be no constant steer module. * * @param distance Target-Agent distance */ public void setConstantMod(float value) { if(value > 0){ this.constantMod = value; this.hasConstantMod = true; } else { this.constantMod = -1; this.hasConstantMod = false; } } /** * @return If the generated steer module is a constant value. */ public boolean getHasConstantMod() { return this.hasConstantMod; } }