Procházet zdrojové kódy

* Small javadoc fixes
* Formatting for com.jme3.effect package
* Formatting for blender importer and networking tests
* All networking tests ported to new SpiderMonkey
* Removed all mentions of java.util.Serializable
* RMI now works under new SpiderMonkey

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7593 75d07b2b-3a1a-0410-a2c5-0572b91ccdca

sha..rd před 14 roky
rodič
revize
8cbb0f210d
50 změnil soubory, kde provedl 3449 přidání a 3451 odebrání
  1. 4 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java
  2. 20 12
      engine/src/core/com/jme3/animation/AnimChannel.java
  3. 14 4
      engine/src/core/com/jme3/animation/AnimControl.java
  4. 39 16
      engine/src/core/com/jme3/animation/Bone.java
  5. 7 3
      engine/src/core/com/jme3/animation/BoneAnimation.java
  6. 1 4
      engine/src/core/com/jme3/animation/MeshAnimation.java
  7. 1 4
      engine/src/core/com/jme3/animation/Pose.java
  8. 0 5
      engine/src/core/com/jme3/animation/PoseTrack.java
  9. 1 4
      engine/src/core/com/jme3/animation/Track.java
  10. 60 59
      engine/src/core/com/jme3/effect/influencers/DefaultParticleInfluencer.java
  11. 38 33
      engine/src/core/com/jme3/effect/influencers/EmptyParticleInfluencer.java
  12. 124 123
      engine/src/core/com/jme3/effect/influencers/NewtonianParticleInfluencer.java
  13. 47 46
      engine/src/core/com/jme3/effect/influencers/ParticleInfluencer.java
  14. 11 12
      engine/src/core/com/jme3/effect/shapes/EmitterBoxShape.java
  15. 45 43
      engine/src/core/com/jme3/effect/shapes/EmitterMeshConvexHullShape.java
  16. 77 75
      engine/src/core/com/jme3/effect/shapes/EmitterMeshFaceShape.java
  17. 116 114
      engine/src/core/com/jme3/effect/shapes/EmitterMeshVertexShape.java
  18. 9 11
      engine/src/core/com/jme3/effect/shapes/EmitterPointShape.java
  19. 20 20
      engine/src/core/com/jme3/effect/shapes/EmitterShape.java
  20. 12 14
      engine/src/core/com/jme3/effect/shapes/EmitterSphereShape.java
  21. 1 2
      engine/src/core/com/jme3/math/ColorRGBA.java
  22. 0 3
      engine/src/core/com/jme3/math/Line.java
  23. 518 523
      engine/src/core/com/jme3/math/LineSegment.java
  24. 0 1
      engine/src/core/com/jme3/math/Ray.java
  25. 1 3
      engine/src/core/com/jme3/math/Rectangle.java
  26. 1 3
      engine/src/core/com/jme3/math/Ring.java
  27. 0 2
      engine/src/core/com/jme3/math/Vector2f.java
  28. 0 2
      engine/src/core/com/jme3/scene/shape/Box.java
  29. 0 2
      engine/src/core/com/jme3/scene/shape/PQTorus.java
  30. 88 65
      engine/src/networking/com/jme3/network/rmi/ObjectStore.java
  31. 2 2
      engine/src/networking/com/jme3/network/rmi/RemoteMethodCallMessage.java
  32. 2 3
      engine/src/networking/com/jme3/network/rmi/RemoteMethodReturnMessage.java
  33. 3 4
      engine/src/networking/com/jme3/network/rmi/RemoteObject.java
  34. 2 4
      engine/src/networking/com/jme3/network/rmi/RemoteObjectDefMessage.java
  35. 72 74
      engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java
  36. 157 154
      engine/src/test/jme3test/blender/ManualBlenderTester.java
  37. 333 328
      engine/src/test/jme3test/blender/config/AbstractConfigDialog.java
  38. 410 396
      engine/src/test/jme3test/blender/config/ConfigDialog.java
  39. 1 1
      engine/src/test/jme3test/blender/config/ConfigExecutable.java
  40. 928 935
      engine/src/test/jme3test/blender/config/NoiseConstantsGenerator.java
  41. 33 32
      engine/src/test/jme3test/blender/scene/Pivot.java
  42. 25 24
      engine/src/test/jme3test/blender/scene/VisibleBone.java
  43. 70 84
      engine/src/test/jme3test/network/TestChatClient.java
  44. 40 55
      engine/src/test/jme3test/network/TestChatServer.java
  45. 0 58
      engine/src/test/jme3test/network/TestHostDiscovery.java
  46. 34 29
      engine/src/test/jme3test/network/TestLatency.java
  47. 10 7
      engine/src/test/jme3test/network/TestMessages.java
  48. 16 14
      engine/src/test/jme3test/network/TestNetworkStress.java
  49. 29 7
      engine/src/test/jme3test/network/TestRemoteCall.java
  50. 27 31
      engine/src/test/jme3test/network/TestThroughput.java

+ 4 - 1
engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java

@@ -260,7 +260,10 @@ public class MaterialHelper extends AbstractBlenderHelper {
                             Texture texture = textureHelper.getTexture(tex, dataRepository);
                             if (texture != null) {
                                 if ((mapto & 0x01) != 0) {// Col
-                                    result.setBoolean("UseMaterialColors", Boolean.FALSE);
+                                    if (!shadeless){
+                                        result.setBoolean("UseMaterialColors", false);
+                                    }
+                                    
                                     // blending the texture with material color and texture's defined color
                                     int blendType = ((Number) textureLink.getFieldValue("blendtype")).intValue();
                                     float[] color = new float[]{((Number) textureLink.getFieldValue("r")).floatValue(), ((Number) textureLink.getFieldValue("g")).floatValue(), ((Number) textureLink.getFieldValue("b")).floatValue()};

+ 20 - 12
engine/src/core/com/jme3/animation/AnimChannel.java

@@ -48,6 +48,8 @@ import java.util.BitSet;
  */
 public final class AnimChannel {
 
+    private static final float DEFAULT_BLEND_TIME = 0.15f;
+    
     private AnimControl control;
 
 //    private ArrayList<Integer> affectedBones;
@@ -61,7 +63,7 @@ public final class AnimChannel {
     private float speedBlendFrom;
 
     private LoopMode loopMode, loopModeBlendFrom;
-    private float defaultBlendTime = 0.15f;
+    
 
     private float blendAmount = 1f;
     private float blendRate   = 0;
@@ -95,6 +97,15 @@ public final class AnimChannel {
         this.control = control;
     }
 
+    /**
+     * Returns the parent control of this AnimChannel.
+     * @return the parent control of this AnimChannel.
+     * @see AnimControl
+     */
+    public AnimControl getControl() {
+        return control;
+    }
+    
     /**
      * @return The name of the currently playing animation, or null if
      * none is assigned.
@@ -180,6 +191,7 @@ public final class AnimChannel {
 
     /**
      * Set the current animation that is played by this AnimChannel.
+     * <p>
      * This resets the time to zero, and optionally blends the animation
      * over <code>blendTime</code> seconds with the currently playing animation.
      * Notice that this method will reset the control's speed to 1.0.
@@ -219,11 +231,15 @@ public final class AnimChannel {
     }
 
     /**
-     *
-     * @param name
+     * Set the current animation that is played by this AnimChannel.
+     * <p>
+     * See {@link #setAnim(java.lang.String, float) }.
+     * The blendTime argument by default is 150 milliseconds.
+     * 
+     * @param name The name of the animation to play
      */
     public void setAnim(String name){
-        setAnim(name, defaultBlendTime);
+        setAnim(name, DEFAULT_BLEND_TIME);
     }
 
     /**
@@ -294,7 +310,6 @@ public final class AnimChannel {
         }
     }
 
-
     void reset(){
         animation = null;
         blendFrom = null;
@@ -340,11 +355,4 @@ public final class AnimChannel {
 
         
     }
-
-    public AnimControl getControl() {
-        return control;
-    }
-
-    
-
 }

+ 14 - 4
engine/src/core/com/jme3/animation/AnimControl.java

@@ -110,13 +110,14 @@ public final class AnimControl extends AbstractControl implements Savable, Clone
     }
 
     /**
-     * Used only for Saving/Loading models (all parameters of the non-default
-     * constructor are restored from the saved model, but the object must be
-     * constructed beforehand)
+     * Serialization only. Do not use.
      */
     public AnimControl() {
     }
 
+    /**
+     * Internal use only.
+     */
     public Control cloneForSpatial(Spatial spatial) {
         try {
             AnimControl clone = (AnimControl) super.clone();
@@ -268,6 +269,9 @@ public final class AnimControl extends AbstractControl implements Savable, Clone
         }
     }
 
+    /**
+     * Internal use only.
+     */
     @Override
     public void setSpatial(Spatial spatial) {
         if (spatial == null && skeletonControl != null){
@@ -310,7 +314,10 @@ public final class AnimControl extends AbstractControl implements Savable, Clone
 
         return a.getLength();
     }
-
+    
+    /**
+     * Internal use only.
+     */
     @Override
     protected void controlUpdate(float tpf) {
         skeleton.reset(); // reset skeleton to bind pose
@@ -322,6 +329,9 @@ public final class AnimControl extends AbstractControl implements Savable, Clone
         skeleton.updateWorldVectors();
     }
 
+    /**
+     * Internal use only.
+     */
     @Override
     protected void controlRender(RenderManager rm, ViewPort vp) {
     }

+ 39 - 16
engine/src/core/com/jme3/animation/Bone.java

@@ -93,9 +93,8 @@ public final class Bone implements Savable {
     private Vector3f worldPos = new Vector3f();
     private Quaternion worldRot = new Quaternion();
     private Vector3f worldScale = new Vector3f();
-    
     //used for getCombinedTransform 
-    private Transform tmpTransform=new Transform();
+    private Transform tmpTransform = new Transform();
 
     /**
      * Creates a new bone with the given name.
@@ -143,6 +142,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the name of the bone, set in the constructor.
+     * 
      * @return The name of the bone, set in the constructor.
      */
     public String getName() {
@@ -150,6 +151,7 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns parent bone of this bone, or null if it is a root bone.
      * @return The parent bone of this bone, or null if it is a root bone.
      */
     public Bone getParent() {
@@ -157,6 +159,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns all the children bones of this bone.
+     * 
      * @return All the children bones of this bone.
      */
     public ArrayList<Bone> getChildren() {
@@ -164,6 +168,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the local position of the bone, relative to the parent bone.
+     * 
      * @return The local position of the bone, relative to the parent bone.
      */
     public Vector3f getLocalPosition() {
@@ -171,6 +177,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the local rotation of the bone, relative to the parent bone.
+     * 
      * @return The local rotation of the bone, relative to the parent bone.
      */
     public Quaternion getLocalRotation() {
@@ -178,6 +186,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the local scale of the bone, relative to the parent bone.
+     * 
      * @return The local scale of the bone, relative to the parent bone.
      */
     public Vector3f getLocalScale() {
@@ -185,6 +195,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the position of the bone in model space.
+     * 
      * @return The position of the bone in model space.
      */
     public Vector3f getModelSpacePosition() {
@@ -192,6 +204,8 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the rotation of the bone in model space.
+     * 
      * @return The rotation of the bone in model space.
      */
     public Quaternion getModelSpaceRotation() {
@@ -199,20 +213,37 @@ public final class Bone implements Savable {
     }
 
     /**
+     * Returns the scale of the bone in model space.
+     * 
      * @return The scale of the bone in model space.
      */
     public Vector3f getModelSpaceScale() {
         return worldScale;
     }
 
+    /**
+     * Returns the inverse world bind pose position.
+     * 
+     * @return the inverse world bind pose position.
+     */
     public Vector3f getWorldBindInversePosition() {
         return worldBindInversePos;
     }
 
+    /**
+     * Returns the inverse world bind pose rotation.
+     * 
+     * @return the inverse world bind pose rotation.
+     */
     public Quaternion getWorldBindInverseRotation() {
         return worldBindInverseRot;
     }
 
+    /**
+     * Returns the inverse world bind pose scale.
+     * 
+     * @return the inverse world bind pose scale.
+     */
     public Vector3f getWorldBindInverseScale() {
         return worldBindInverseScale;
     }
@@ -375,18 +406,18 @@ public final class Bone implements Savable {
         worldPos.set(translation);
         worldRot.set(rotation);
     }
-    
+
     /**
      * Returns the local transform of this bone combined with the given position and rotation
      * @param position a position
      * @param rotation a rotation
      */
-    public Transform getCombinedTransform(Vector3f position, Quaternion rotation){
-            rotation.mult(localPos, tmpTransform.getTranslation()).addLocal(position);
-            tmpTransform.setRotation(rotation).getRotation().multLocal(localRot);
-            return tmpTransform;
+    public Transform getCombinedTransform(Vector3f position, Quaternion rotation) {
+        rotation.mult(localPos, tmpTransform.getTranslation()).addLocal(position);
+        tmpTransform.setRotation(rotation).getRotation().multLocal(localRot);
+        return tmpTransform;
     }
-    
+
     /**
      * Returns the attachment node.
      * Attach models and effects to this node to make
@@ -477,14 +508,6 @@ public final class Bone implements Savable {
         }
     }
 
-    void setAnimTransforms(Vector3f translation, Quaternion rotation) {
-        this.setAnimTransforms(translation, rotation, Vector3f.UNIT_XYZ);
-    }
-
-    public void setBindTransforms(Vector3f translation, Quaternion rotation) {
-        this.setBindTransforms(translation, rotation, Vector3f.UNIT_XYZ);
-    }
-
     private String toString(int depth) {
         StringBuilder sb = new StringBuilder();
         for (int i = 0; i < depth; i++) {

+ 7 - 3
engine/src/core/com/jme3/animation/BoneAnimation.java

@@ -41,18 +41,22 @@ import java.io.IOException;
 import java.util.BitSet;
 
 /**
- * Bone animation updates each of it's tracks with the skeleton and time
+ * Bone animation updates each of its tracks with the skeleton and time
  * to apply the animation.
  */
 public final class BoneAnimation implements Savable {
 
-    private static final long serialVersionUID = 1L;
-
     private String name;
     private float length;
 
     private BoneTrack[] tracks;
 
+    /**
+     * Creates a new BoneAnimation with the given name and length.
+     * 
+     * @param name The name of the bone animation.
+     * @param length Length in seconds of the bone animation.
+     */
     public BoneAnimation(String name, float length){
         this.name = name;
         this.length = length;

+ 1 - 4
engine/src/core/com/jme3/animation/MeshAnimation.java

@@ -39,11 +39,8 @@ import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
 import com.jme3.scene.Mesh;
 import java.io.IOException;
-import java.io.Serializable;
 
-public class MeshAnimation implements Serializable, Savable {
-
-    private static final long serialVersionUID = 1L;
+public class MeshAnimation implements Savable {
 
     private String name;
     private float length;

+ 1 - 4
engine/src/core/com/jme3/animation/Pose.java

@@ -40,15 +40,12 @@ import com.jme3.export.Savable;
 import com.jme3.math.Vector3f;
 import com.jme3.util.BufferUtils;
 import java.io.IOException;
-import java.io.Serializable;
 import java.nio.FloatBuffer;
 
 /**
  * A pose is a list of offsets that say where a mesh verticles should be for this pose.
  */
-public final class Pose implements Serializable, Savable {
-
-    private static final long serialVersionUID = 1L;
+public final class Pose implements Savable {
 
     private String name;
     private int targetMeshIndex;

+ 0 - 5
engine/src/core/com/jme3/animation/PoseTrack.java

@@ -41,7 +41,6 @@ import com.jme3.scene.Mesh;
 import com.jme3.scene.VertexBuffer;
 import com.jme3.scene.VertexBuffer.Type;
 import java.io.IOException;
-import java.io.Serializable;
 import java.nio.FloatBuffer;
 
 /**
@@ -49,15 +48,11 @@ import java.nio.FloatBuffer;
  */
 public final class PoseTrack extends Track {
     
-    private static final long serialVersionUID = 1L;
-
     private PoseFrame[] frames;
     private float[]     times;
 
     public static class PoseFrame implements Savable {
 
-        private static final long serialVersionUID = 1L;
-
         Pose[] poses;
         float[] weights;
 

+ 1 - 4
engine/src/core/com/jme3/animation/Track.java

@@ -37,15 +37,12 @@ import com.jme3.export.JmeImporter;
 import com.jme3.export.Savable;
 import com.jme3.scene.Mesh;
 import java.io.IOException;
-import java.io.Serializable;
 
 /**
  * A single track of mesh animation (either morph or pose based).
  * Currently morph animations are not supported (only pose).
  */
-public abstract class Track implements Serializable, Savable {
-    
-    private static final long serialVersionUID = 1L;
+public abstract class Track implements Savable {
 
     protected int targetMeshIndex;
 

+ 60 - 59
engine/src/core/com/jme3/effect/influencers/DefaultParticleInfluencer.java

@@ -18,72 +18,73 @@ import com.jme3.math.Vector3f;
  * @author Marcin Roguski (Kaelthas)
  */
 public class DefaultParticleInfluencer implements ParticleInfluencer {
-	/** Temporary variable used to help with calculations. */
-	protected transient Vector3f	temp				= new Vector3f();
-	/** The initial velocity of the particles. */
-	protected Vector3f				startVelocity		= new Vector3f();
-	/** The velocity's variation of the particles. */
-	protected float					velocityVariation	= 0.2f;
 
-	@Override
-	public void influenceParticle(Particle particle, EmitterShape emitterShape) {
-		emitterShape.getRandomPoint(particle.position);
-		this.applyVelocityVariation(particle);
-	}
+    /** Temporary variable used to help with calculations. */
+    protected transient Vector3f temp = new Vector3f();
+    /** The initial velocity of the particles. */
+    protected Vector3f startVelocity = new Vector3f();
+    /** The velocity's variation of the particles. */
+    protected float velocityVariation = 0.2f;
 
-	/**
-	 * This method applies the variation to the particle with already set velocity.
-	 * @param particle
-	 *        the particle to be affected
-	 */
-	protected void applyVelocityVariation(Particle particle) {
-		temp.set(FastMath.nextRandomFloat(), FastMath.nextRandomFloat(), FastMath.nextRandomFloat());
-		temp.multLocal(2f);
-		temp.subtractLocal(1f, 1f, 1f);
-		temp.multLocal(startVelocity.length());
-		particle.velocity.interpolate(temp, velocityVariation);
-	}
+    @Override
+    public void influenceParticle(Particle particle, EmitterShape emitterShape) {
+        emitterShape.getRandomPoint(particle.position);
+        this.applyVelocityVariation(particle);
+    }
 
-	@Override
-	public void write(JmeExporter ex) throws IOException {
-		OutputCapsule oc = ex.getCapsule(this);
-		oc.write(startVelocity, "startVelocity", Vector3f.ZERO);
-		oc.write(velocityVariation, "variation", 0.2f);
-	}
+    /**
+     * This method applies the variation to the particle with already set velocity.
+     * @param particle
+     *        the particle to be affected
+     */
+    protected void applyVelocityVariation(Particle particle) {
+        temp.set(FastMath.nextRandomFloat(), FastMath.nextRandomFloat(), FastMath.nextRandomFloat());
+        temp.multLocal(2f);
+        temp.subtractLocal(1f, 1f, 1f);
+        temp.multLocal(startVelocity.length());
+        particle.velocity.interpolate(temp, velocityVariation);
+    }
 
-	@Override
-	public void read(JmeImporter im) throws IOException {
-		InputCapsule ic = im.getCapsule(this);
-		startVelocity = (Vector3f) ic.readSavable("startVelocity", Vector3f.ZERO);
-		velocityVariation = ic.readFloat("variation", 0.2f);
-	}
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        OutputCapsule oc = ex.getCapsule(this);
+        oc.write(startVelocity, "startVelocity", Vector3f.ZERO);
+        oc.write(velocityVariation, "variation", 0.2f);
+    }
 
-	@Override
-	public ParticleInfluencer clone() {
-		try {
-			return (ParticleInfluencer) super.clone();
-		} catch (CloneNotSupportedException e) {
-			return null;
-		}
-	}
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        InputCapsule ic = im.getCapsule(this);
+        startVelocity = (Vector3f) ic.readSavable("startVelocity", Vector3f.ZERO);
+        velocityVariation = ic.readFloat("variation", 0.2f);
+    }
 
-	@Override
-	public void setInitialVelocity(Vector3f initialVelocity) {
-		this.startVelocity.set(initialVelocity);
-	}
+    @Override
+    public ParticleInfluencer clone() {
+        try {
+            return (ParticleInfluencer) super.clone();
+        } catch (CloneNotSupportedException e) {
+            return null;
+        }
+    }
 
-	@Override
-	public Vector3f getInitialVelocity() {
-		return startVelocity;
-	}
+    @Override
+    public void setInitialVelocity(Vector3f initialVelocity) {
+        this.startVelocity.set(initialVelocity);
+    }
 
-	@Override
-	public void setVelocityVariation(float variation) {
-		this.velocityVariation = variation;
-	}
+    @Override
+    public Vector3f getInitialVelocity() {
+        return startVelocity;
+    }
 
-	@Override
-	public float getVelocityVariation() {
-		return velocityVariation;
-	}
+    @Override
+    public void setVelocityVariation(float variation) {
+        this.velocityVariation = variation;
+    }
+
+    @Override
+    public float getVelocityVariation() {
+        return velocityVariation;
+    }
 }

+ 38 - 33
engine/src/core/com/jme3/effect/influencers/EmptyParticleInfluencer.java

@@ -15,37 +15,42 @@ import com.jme3.math.Vector3f;
  */
 public class EmptyParticleInfluencer implements ParticleInfluencer {
 
-	@Override
-	public void write(JmeExporter ex) throws IOException {}
-
-	@Override
-	public void read(JmeImporter im) throws IOException {}
-
-	@Override
-	public void influenceParticle(Particle particle, EmitterShape emitterShape) {}
-
-	@Override
-	public void setInitialVelocity(Vector3f initialVelocity) {}
-
-	@Override
-	public Vector3f getInitialVelocity() {
-		return null;
-	}
-
-	@Override
-	public void setVelocityVariation(float variation) {}
-
-	@Override
-	public float getVelocityVariation() {
-		return 0;
-	}
-
-	@Override
-	public ParticleInfluencer clone() {
-		try {
-			return (ParticleInfluencer) super.clone();
-		} catch (CloneNotSupportedException e) {
-			return new EmptyParticleInfluencer();
-		}
-	}
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+    }
+
+    @Override
+    public void read(JmeImporter im) throws IOException {
+    }
+
+    @Override
+    public void influenceParticle(Particle particle, EmitterShape emitterShape) {
+    }
+
+    @Override
+    public void setInitialVelocity(Vector3f initialVelocity) {
+    }
+
+    @Override
+    public Vector3f getInitialVelocity() {
+        return null;
+    }
+
+    @Override
+    public void setVelocityVariation(float variation) {
+    }
+
+    @Override
+    public float getVelocityVariation() {
+        return 0;
+    }
+
+    @Override
+    public ParticleInfluencer clone() {
+        try {
+            return (ParticleInfluencer) super.clone();
+        } catch (CloneNotSupportedException e) {
+            return new EmptyParticleInfluencer();
+        }
+    }
 }

+ 124 - 123
engine/src/core/com/jme3/effect/influencers/NewtonianParticleInfluencer.java

@@ -16,127 +16,128 @@ import com.jme3.math.Matrix3f;
  * @author Marcin Roguski (Kaelthas)
  */
 public class NewtonianParticleInfluencer extends DefaultParticleInfluencer {
-	/** Normal to emitter's shape factor. */
-	protected float	normalVelocity;
-	/** Emitter's surface tangent factor. */
-	protected float	surfaceTangentFactor;
-	/** Emitters tangent rotation factor. */
-	protected float	surfaceTangentRotation;
-
-	/**
-	 * Constructor. Sets velocity variation to 0.0f.
-	 */
-	public NewtonianParticleInfluencer() {
-		this.velocityVariation = 0.0f;
-	}
-
-	@Override
-	public void influenceParticle(Particle particle, EmitterShape emitterShape) {
-		emitterShape.getRandomPointAndNormal(particle.position, particle.velocity);
-		// influencing the particle's velocity
-		if (surfaceTangentFactor == 0.0f) {
-			particle.velocity.multLocal(normalVelocity);
-		} else {
-			// calculating surface tangent (velocity contains the 'normal' value)
-			temp.set(particle.velocity.z * surfaceTangentFactor, particle.velocity.y * surfaceTangentFactor, -particle.velocity.x * surfaceTangentFactor);
-			if (surfaceTangentRotation != 0.0f) {// rotating the tangent
-				Matrix3f m = new Matrix3f();
-				m.fromAngleNormalAxis(FastMath.PI * surfaceTangentRotation, particle.velocity);
-				temp = m.multLocal(temp);
-			}
-			// applying normal factor (this must be done first)
-			particle.velocity.multLocal(normalVelocity);
-			// adding tangent vector
-			particle.velocity.addLocal(temp);
-		}
-		if (velocityVariation != 0.0f) {
-			this.applyVelocityVariation(particle);
-		}
-	}
-
-	/**
-	 * This method returns the normal velocity factor.
-	 * @return the normal velocity factor
-	 */
-	public float getNormalVelocity() {
-		return normalVelocity;
-	}
-
-	/**
-	 * This method sets the normal velocity factor.
-	 * @param normalVelocity
-	 *        the normal velocity factor
-	 */
-	public void setNormalVelocity(float normalVelocity) {
-		this.normalVelocity = normalVelocity;
-	}
-
-	/**
-	 * This method sets the surface tangent factor.
-	 * @param surfaceTangentFactor
-	 *        the surface tangent factor
-	 */
-	public void setSurfaceTangentFactor(float surfaceTangentFactor) {
-		this.surfaceTangentFactor = surfaceTangentFactor;
-	}
-
-	/**
-	 * This method returns the surface tangent factor.
-	 * @return the surface tangent factor
-	 */
-	public float getSurfaceTangentFactor() {
-		return surfaceTangentFactor;
-	}
-
-	/**
-	 * This method sets the surface tangent rotation factor.
-	 * @param surfaceTangentRotation
-	 *        the surface tangent rotation factor
-	 */
-	public void setSurfaceTangentRotation(float surfaceTangentRotation) {
-		this.surfaceTangentRotation = surfaceTangentRotation;
-	}
-
-	/**
-	 * This method returns the surface tangent rotation factor.
-	 * @return the surface tangent rotation factor
-	 */
-	public float getSurfaceTangentRotation() {
-		return surfaceTangentRotation;
-	}
-
-	@Override
-	protected void applyVelocityVariation(Particle particle) {
-		temp.set(FastMath.nextRandomFloat() * velocityVariation, FastMath.nextRandomFloat() * velocityVariation, FastMath.nextRandomFloat() * velocityVariation);
-		particle.velocity.addLocal(temp);
-	}
-
-	@Override
-	public ParticleInfluencer clone() {
-		NewtonianParticleInfluencer result = new NewtonianParticleInfluencer();
-		result.normalVelocity = normalVelocity;
-		result.startVelocity = startVelocity;
-		result.velocityVariation = velocityVariation;
-		result.surfaceTangentFactor = surfaceTangentFactor;
-		result.surfaceTangentRotation = surfaceTangentRotation;
-		return result;
-	}
-
-	@Override
-	public void write(JmeExporter ex) throws IOException {
-		super.write(ex);
-		OutputCapsule oc = ex.getCapsule(this);
-		oc.write(normalVelocity, "normalVelocity", 0.0f);
-		oc.write(surfaceTangentFactor, "surfaceTangentFactor", 0.0f);
-		oc.write(surfaceTangentRotation, "surfaceTangentRotation", 0.0f);
-	}
-
-	@Override
-	public void read(JmeImporter im) throws IOException {
-		super.read(im);
-		InputCapsule ic = im.getCapsule(this);
-		normalVelocity = ic.readFloat("normalVelocity", 0.0f);
-		surfaceTangentFactor = ic.readFloat("surfaceTangentFactor", 0.0f);
-		surfaceTangentRotation = ic.readFloat("surfaceTangentRotation", 0.0f);
-	}
+
+    /** Normal to emitter's shape factor. */
+    protected float normalVelocity;
+    /** Emitter's surface tangent factor. */
+    protected float surfaceTangentFactor;
+    /** Emitters tangent rotation factor. */
+    protected float surfaceTangentRotation;
+
+    /**
+     * Constructor. Sets velocity variation to 0.0f.
+     */
+    public NewtonianParticleInfluencer() {
+        this.velocityVariation = 0.0f;
+    }
+
+    @Override
+    public void influenceParticle(Particle particle, EmitterShape emitterShape) {
+        emitterShape.getRandomPointAndNormal(particle.position, particle.velocity);
+        // influencing the particle's velocity
+        if (surfaceTangentFactor == 0.0f) {
+            particle.velocity.multLocal(normalVelocity);
+        } else {
+            // calculating surface tangent (velocity contains the 'normal' value)
+            temp.set(particle.velocity.z * surfaceTangentFactor, particle.velocity.y * surfaceTangentFactor, -particle.velocity.x * surfaceTangentFactor);
+            if (surfaceTangentRotation != 0.0f) {// rotating the tangent
+                Matrix3f m = new Matrix3f();
+                m.fromAngleNormalAxis(FastMath.PI * surfaceTangentRotation, particle.velocity);
+                temp = m.multLocal(temp);
+            }
+            // applying normal factor (this must be done first)
+            particle.velocity.multLocal(normalVelocity);
+            // adding tangent vector
+            particle.velocity.addLocal(temp);
+        }
+        if (velocityVariation != 0.0f) {
+            this.applyVelocityVariation(particle);
+        }
+    }
+
+    /**
+     * This method returns the normal velocity factor.
+     * @return the normal velocity factor
+     */
+    public float getNormalVelocity() {
+        return normalVelocity;
+    }
+
+    /**
+     * This method sets the normal velocity factor.
+     * @param normalVelocity
+     *        the normal velocity factor
+     */
+    public void setNormalVelocity(float normalVelocity) {
+        this.normalVelocity = normalVelocity;
+    }
+
+    /**
+     * This method sets the surface tangent factor.
+     * @param surfaceTangentFactor
+     *        the surface tangent factor
+     */
+    public void setSurfaceTangentFactor(float surfaceTangentFactor) {
+        this.surfaceTangentFactor = surfaceTangentFactor;
+    }
+
+    /**
+     * This method returns the surface tangent factor.
+     * @return the surface tangent factor
+     */
+    public float getSurfaceTangentFactor() {
+        return surfaceTangentFactor;
+    }
+
+    /**
+     * This method sets the surface tangent rotation factor.
+     * @param surfaceTangentRotation
+     *        the surface tangent rotation factor
+     */
+    public void setSurfaceTangentRotation(float surfaceTangentRotation) {
+        this.surfaceTangentRotation = surfaceTangentRotation;
+    }
+
+    /**
+     * This method returns the surface tangent rotation factor.
+     * @return the surface tangent rotation factor
+     */
+    public float getSurfaceTangentRotation() {
+        return surfaceTangentRotation;
+    }
+
+    @Override
+    protected void applyVelocityVariation(Particle particle) {
+        temp.set(FastMath.nextRandomFloat() * velocityVariation, FastMath.nextRandomFloat() * velocityVariation, FastMath.nextRandomFloat() * velocityVariation);
+        particle.velocity.addLocal(temp);
+    }
+
+    @Override
+    public ParticleInfluencer clone() {
+        NewtonianParticleInfluencer result = new NewtonianParticleInfluencer();
+        result.normalVelocity = normalVelocity;
+        result.startVelocity = startVelocity;
+        result.velocityVariation = velocityVariation;
+        result.surfaceTangentFactor = surfaceTangentFactor;
+        result.surfaceTangentRotation = surfaceTangentRotation;
+        return result;
+    }
+
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        super.write(ex);
+        OutputCapsule oc = ex.getCapsule(this);
+        oc.write(normalVelocity, "normalVelocity", 0.0f);
+        oc.write(surfaceTangentFactor, "surfaceTangentFactor", 0.0f);
+        oc.write(surfaceTangentRotation, "surfaceTangentRotation", 0.0f);
+    }
+
+    @Override
+    public void read(JmeImporter im) throws IOException {
+        super.read(im);
+        InputCapsule ic = im.getCapsule(this);
+        normalVelocity = ic.readFloat("normalVelocity", 0.0f);
+        surfaceTangentFactor = ic.readFloat("surfaceTangentFactor", 0.0f);
+        surfaceTangentRotation = ic.readFloat("surfaceTangentRotation", 0.0f);
+    }
 }

+ 47 - 46
engine/src/core/com/jme3/effect/influencers/ParticleInfluencer.java

@@ -11,50 +11,51 @@ import com.jme3.math.Vector3f;
  * @author Marcin Roguski (Kaelthas)
  */
 public interface ParticleInfluencer extends Savable, Cloneable {
-	/**
-	 * This method influences the particle.
-	 * @param particle
-	 *        particle to be influenced
-	 * @param emitterShape
-	 *        the shape of it emitter
-	 */
-	void influenceParticle(Particle particle, EmitterShape emitterShape);
-
-	/**
-	 * This method clones the influencer instance.
-	 * @return cloned instance
-	 */
-	public ParticleInfluencer clone();
-
-	/**
-	 * @param initialVelocity
-	 *        Set the initial velocity a particle is spawned with,
-	 *        the initial velocity given in the parameter will be varied according
-	 *        to the velocity variation set in {@link ParticleEmitter#setVelocityVariation(float) }.
-	 *        A particle will move toward its velocity unless it is effected by the
-	 *        gravity.
-	 */
-	void setInitialVelocity(Vector3f initialVelocity);
-
-	/**
-	 * This method returns the initial velocity.
-	 * @return the initial velocity
-	 */
-	Vector3f getInitialVelocity();
-
-	/**
-	 * @param variation
-	 *        Set the variation by which the initial velocity
-	 *        of the particle is determined. <code>variation</code> should be a value
-	 *        from 0 to 1, where 0 means particles are to spawn with exactly
-	 *        the velocity given in {@link ParticleEmitter#setStartVel(com.jme3.math.Vector3f) },
-	 *        and 1 means particles are to spawn with a completely random velocity.
-	 */
-	void setVelocityVariation(float variation);
-
-	/**
-	 * This method returns the velocity variation.
-	 * @return the velocity variation
-	 */
-	float getVelocityVariation();
+
+    /**
+     * This method influences the particle.
+     * @param particle
+     *        particle to be influenced
+     * @param emitterShape
+     *        the shape of it emitter
+     */
+    void influenceParticle(Particle particle, EmitterShape emitterShape);
+
+    /**
+     * This method clones the influencer instance.
+     * @return cloned instance
+     */
+    public ParticleInfluencer clone();
+
+    /**
+     * @param initialVelocity
+     *        Set the initial velocity a particle is spawned with,
+     *        the initial velocity given in the parameter will be varied according
+     *        to the velocity variation set in {@link ParticleEmitter#setVelocityVariation(float) }.
+     *        A particle will move toward its velocity unless it is effected by the
+     *        gravity.
+     */
+    void setInitialVelocity(Vector3f initialVelocity);
+
+    /**
+     * This method returns the initial velocity.
+     * @return the initial velocity
+     */
+    Vector3f getInitialVelocity();
+
+    /**
+     * @param variation
+     *        Set the variation by which the initial velocity
+     *        of the particle is determined. <code>variation</code> should be a value
+     *        from 0 to 1, where 0 means particles are to spawn with exactly
+     *        the velocity given in {@link ParticleEmitter#setStartVel(com.jme3.math.Vector3f) },
+     *        and 1 means particles are to spawn with a completely random velocity.
+     */
+    void setVelocityVariation(float variation);
+
+    /**
+     * This method returns the velocity variation.
+     * @return the velocity variation
+     */
+    float getVelocityVariation();
 }

+ 11 - 12
engine/src/core/com/jme3/effect/shapes/EmitterBoxShape.java

@@ -29,7 +29,6 @@
  * 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.effect.shapes;
 
 import com.jme3.export.JmeExporter;
@@ -44,26 +43,26 @@ public class EmitterBoxShape implements EmitterShape {
 
     private Vector3f min, len;
 
-    public EmitterBoxShape(){
+    public EmitterBoxShape() {
     }
 
     public EmitterBoxShape(Vector3f min, Vector3f max) {
         if (min == null || max == null) {
-			throw new NullPointerException();
-		}
+            throw new NullPointerException();
+        }
 
         this.min = min;
         this.len = new Vector3f();
         this.len.set(max).subtractLocal(min);
     }
-    
+
     @Override
-	public void getRandomPoint(Vector3f store) {
+    public void getRandomPoint(Vector3f store) {
         store.x = min.x + len.x * FastMath.nextRandomFloat();
         store.y = min.y + len.y * FastMath.nextRandomFloat();
         store.z = min.z + len.z * FastMath.nextRandomFloat();
     }
-    
+
     /**
      * This method fills the point with data.
      * It does not fill the normal.
@@ -72,11 +71,11 @@ public class EmitterBoxShape implements EmitterShape {
      */
     @Override
     public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-    	this.getRandomPoint(store);
+        this.getRandomPoint(store);
     }
 
     @Override
-	public EmitterShape deepClone(){
+    public EmitterShape deepClone() {
         try {
             EmitterBoxShape clone = (EmitterBoxShape) super.clone();
             clone.min = min.clone();
@@ -104,16 +103,16 @@ public class EmitterBoxShape implements EmitterShape {
     }
 
     @Override
-	public void write(JmeExporter ex) throws IOException {
+    public void write(JmeExporter ex) throws IOException {
         OutputCapsule oc = ex.getCapsule(this);
         oc.write(min, "min", null);
         oc.write(len, "length", null);
     }
+
     @Override
-	public void read(JmeImporter im) throws IOException {
+    public void read(JmeImporter im) throws IOException {
         InputCapsule ic = im.getCapsule(this);
         min = (Vector3f) ic.readSavable("min", null);
         len = (Vector3f) ic.readSavable("length", null);
     }
-
 }

+ 45 - 43
engine/src/core/com/jme3/effect/shapes/EmitterMeshConvexHullShape.java

@@ -13,50 +13,52 @@ import com.jme3.scene.Mesh;
  * @author Marcin Roguski (Kaelthas)
  */
 public class EmitterMeshConvexHullShape extends EmitterMeshFaceShape {
-	/**
-	 * Empty constructor. Sets nothing.
-	 */
-	public EmitterMeshConvexHullShape() {}
 
-	/**
-	 * Constructor. It stores a copy of vertex list of all meshes.
-	 * @param meshes
-	 *        a list of meshes that will form the emitter's shape
-	 */
-	public EmitterMeshConvexHullShape(List<Mesh> meshes) {
-		super(meshes);
-	}
+    /**
+     * Empty constructor. Sets nothing.
+     */
+    public EmitterMeshConvexHullShape() {
+    }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected point inside a convex hull
-	 * of randomly selected mesh.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected selected point inside a convex hull
-	 *        of randomly selected mesh
-	 */
-	@Override
-	public void getRandomPoint(Vector3f store) {
-		super.getRandomPoint(store);
-		// now move the point from the meshe's face towards the center of the mesh
-		// the center is in (0, 0, 0) in the local coordinates
-		store.multLocal(FastMath.nextRandomFloat());
-	}
+    /**
+     * Constructor. It stores a copy of vertex list of all meshes.
+     * @param meshes
+     *        a list of meshes that will form the emitter's shape
+     */
+    public EmitterMeshConvexHullShape(List<Mesh> meshes) {
+        super(meshes);
+    }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected point inside a convex hull
-	 * of randomly selected mesh.
-	 * The normal param is not used.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected selected point inside a convex hull
-	 *        of randomly selected mesh
-	 * @param normal
-	 *        not used in this class
-	 */
-	@Override
-	public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-		super.getRandomPointAndNormal(store, normal);
-		// now move the point from the meshe's face towards the center of the mesh
-		// the center is in (0, 0, 0) in the local coordinates
-		store.multLocal(FastMath.nextRandomFloat());
-	}
+    /**
+     * This method fills the point with coordinates of randomly selected point inside a convex hull
+     * of randomly selected mesh.
+     * @param store
+     *        the variable to store with coordinates of randomly selected selected point inside a convex hull
+     *        of randomly selected mesh
+     */
+    @Override
+    public void getRandomPoint(Vector3f store) {
+        super.getRandomPoint(store);
+        // now move the point from the meshe's face towards the center of the mesh
+        // the center is in (0, 0, 0) in the local coordinates
+        store.multLocal(FastMath.nextRandomFloat());
+    }
+
+    /**
+     * This method fills the point with coordinates of randomly selected point inside a convex hull
+     * of randomly selected mesh.
+     * The normal param is not used.
+     * @param store
+     *        the variable to store with coordinates of randomly selected selected point inside a convex hull
+     *        of randomly selected mesh
+     * @param normal
+     *        not used in this class
+     */
+    @Override
+    public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
+        super.getRandomPointAndNormal(store, normal);
+        // now move the point from the meshe's face towards the center of the mesh
+        // the center is in (0, 0, 0) in the local coordinates
+        store.multLocal(FastMath.nextRandomFloat());
+    }
 }

+ 77 - 75
engine/src/core/com/jme3/effect/shapes/EmitterMeshFaceShape.java

@@ -14,83 +14,85 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class EmitterMeshFaceShape extends EmitterMeshVertexShape {
-	/**
-	 * Empty constructor. Sets nothing.
-	 */
-	public EmitterMeshFaceShape() {}
 
-	/**
-	 * Constructor. It stores a copy of vertex list of all meshes.
-	 * @param meshes
-	 *        a list of meshes that will form the emitter's shape
-	 */
-	public EmitterMeshFaceShape(List<Mesh> meshes) {
-		super(meshes);
-	}
+    /**
+     * Empty constructor. Sets nothing.
+     */
+    public EmitterMeshFaceShape() {
+    }
 
-	@Override
-	public void setMeshes(List<Mesh> meshes) {
-		this.vertices = new ArrayList<List<Vector3f>>(meshes.size());
-		this.normals = new ArrayList<List<Vector3f>>(meshes.size());
-		for (Mesh mesh : meshes) {
-			Vector3f[] vertexTable = BufferUtils.getVector3Array(mesh.getFloatBuffer(Type.Position));
-			int[] indices = new int[3];
-			List<Vector3f> vertices = new ArrayList<Vector3f>(mesh.getTriangleCount() * 3);
-			List<Vector3f> normals = new ArrayList<Vector3f>(mesh.getTriangleCount());
-			for (int i = 0; i < mesh.getTriangleCount(); ++i) {
-				mesh.getTriangle(i, indices);
-				vertices.add(vertexTable[indices[0]]);
-				vertices.add(vertexTable[indices[1]]);
-				vertices.add(vertexTable[indices[2]]);
-				normals.add(FastMath.computeNormal(vertexTable[indices[0]], vertexTable[indices[1]], vertexTable[indices[2]]));
-			}
-			this.vertices.add(vertices);
-			this.normals.add(normals);
-		}
-	}
+    /**
+     * Constructor. It stores a copy of vertex list of all meshes.
+     * @param meshes
+     *        a list of meshes that will form the emitter's shape
+     */
+    public EmitterMeshFaceShape(List<Mesh> meshes) {
+        super(meshes);
+    }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected point on a random face.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected selected point on a random face
-	 */
-	@Override
-	public void getRandomPoint(Vector3f store) {
-		int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
-		// the index of the first vertex of a face (must be dividable by 3)
-		int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() / 3 - 1) * 3;
-		// put the point somewhere between the first and the second vertex of a face
-		float moveFactor = FastMath.nextRandomFloat();
-		store.set(Vector3f.ZERO);
-		store.addLocal(vertices.get(meshIndex).get(vertIndex));
-		store.addLocal((vertices.get(meshIndex).get(vertIndex + 1).x - vertices.get(meshIndex).get(vertIndex).x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).y - vertices.get(meshIndex).get(vertIndex).y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).z - vertices.get(meshIndex).get(vertIndex).z) * moveFactor);
-		// move the result towards the last face vertex
-		moveFactor = FastMath.nextRandomFloat();
-		store.addLocal((vertices.get(meshIndex).get(vertIndex + 2).x - store.x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).y - store.y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).z - store.z) * moveFactor);
-	}
+    @Override
+    public void setMeshes(List<Mesh> meshes) {
+        this.vertices = new ArrayList<List<Vector3f>>(meshes.size());
+        this.normals = new ArrayList<List<Vector3f>>(meshes.size());
+        for (Mesh mesh : meshes) {
+            Vector3f[] vertexTable = BufferUtils.getVector3Array(mesh.getFloatBuffer(Type.Position));
+            int[] indices = new int[3];
+            List<Vector3f> vertices = new ArrayList<Vector3f>(mesh.getTriangleCount() * 3);
+            List<Vector3f> normals = new ArrayList<Vector3f>(mesh.getTriangleCount());
+            for (int i = 0; i < mesh.getTriangleCount(); ++i) {
+                mesh.getTriangle(i, indices);
+                vertices.add(vertexTable[indices[0]]);
+                vertices.add(vertexTable[indices[1]]);
+                vertices.add(vertexTable[indices[2]]);
+                normals.add(FastMath.computeNormal(vertexTable[indices[0]], vertexTable[indices[1]], vertexTable[indices[2]]));
+            }
+            this.vertices.add(vertices);
+            this.normals.add(normals);
+        }
+    }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected point on a random face.
-	 * The normal param is filled with selected face's normal.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected selected point on a random face
-	 * @param normal
-	 *        filled with selected face's normal
-	 */
-	@Override
-	public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-		int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
-		// the index of the first vertex of a face (must be dividable by 3)
-		int faceIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() / 3 - 1);
-		int vertIndex = faceIndex * 3;
-		// put the point somewhere between the first and the second vertex of a face
-		float moveFactor = FastMath.nextRandomFloat();
-		store.set(Vector3f.ZERO);
-		store.addLocal(vertices.get(meshIndex).get(vertIndex));
-		store.addLocal((vertices.get(meshIndex).get(vertIndex + 1).x - vertices.get(meshIndex).get(vertIndex).x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).y - vertices.get(meshIndex).get(vertIndex).y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).z - vertices.get(meshIndex).get(vertIndex).z) * moveFactor);
-		// move the result towards the last face vertex
-		moveFactor = FastMath.nextRandomFloat();
-		store.addLocal((vertices.get(meshIndex).get(vertIndex + 2).x - store.x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).y - store.y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).z - store.z) * moveFactor);
-		normal.set(normals.get(meshIndex).get(faceIndex));
-	}
+    /**
+     * This method fills the point with coordinates of randomly selected point on a random face.
+     * @param store
+     *        the variable to store with coordinates of randomly selected selected point on a random face
+     */
+    @Override
+    public void getRandomPoint(Vector3f store) {
+        int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
+        // the index of the first vertex of a face (must be dividable by 3)
+        int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() / 3 - 1) * 3;
+        // put the point somewhere between the first and the second vertex of a face
+        float moveFactor = FastMath.nextRandomFloat();
+        store.set(Vector3f.ZERO);
+        store.addLocal(vertices.get(meshIndex).get(vertIndex));
+        store.addLocal((vertices.get(meshIndex).get(vertIndex + 1).x - vertices.get(meshIndex).get(vertIndex).x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).y - vertices.get(meshIndex).get(vertIndex).y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).z - vertices.get(meshIndex).get(vertIndex).z) * moveFactor);
+        // move the result towards the last face vertex
+        moveFactor = FastMath.nextRandomFloat();
+        store.addLocal((vertices.get(meshIndex).get(vertIndex + 2).x - store.x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).y - store.y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).z - store.z) * moveFactor);
+    }
+
+    /**
+     * This method fills the point with coordinates of randomly selected point on a random face.
+     * The normal param is filled with selected face's normal.
+     * @param store
+     *        the variable to store with coordinates of randomly selected selected point on a random face
+     * @param normal
+     *        filled with selected face's normal
+     */
+    @Override
+    public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
+        int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
+        // the index of the first vertex of a face (must be dividable by 3)
+        int faceIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() / 3 - 1);
+        int vertIndex = faceIndex * 3;
+        // put the point somewhere between the first and the second vertex of a face
+        float moveFactor = FastMath.nextRandomFloat();
+        store.set(Vector3f.ZERO);
+        store.addLocal(vertices.get(meshIndex).get(vertIndex));
+        store.addLocal((vertices.get(meshIndex).get(vertIndex + 1).x - vertices.get(meshIndex).get(vertIndex).x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).y - vertices.get(meshIndex).get(vertIndex).y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 1).z - vertices.get(meshIndex).get(vertIndex).z) * moveFactor);
+        // move the result towards the last face vertex
+        moveFactor = FastMath.nextRandomFloat();
+        store.addLocal((vertices.get(meshIndex).get(vertIndex + 2).x - store.x) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).y - store.y) * moveFactor, (vertices.get(meshIndex).get(vertIndex + 2).z - store.z) * moveFactor);
+        normal.set(normals.get(meshIndex).get(faceIndex));
+    }
 }

+ 116 - 114
engine/src/core/com/jme3/effect/shapes/EmitterMeshVertexShape.java

@@ -21,129 +21,131 @@ import com.jme3.util.BufferUtils;
  * @author Marcin Roguski (Kaelthas)
  */
 public class EmitterMeshVertexShape implements EmitterShape {
-	protected List<List<Vector3f>>	vertices;
-	protected List<List<Vector3f>>	normals;
 
-	/**
-	 * Empty constructor. Sets nothing.
-	 */
-	public EmitterMeshVertexShape() {}
+    protected List<List<Vector3f>> vertices;
+    protected List<List<Vector3f>> normals;
 
-	/**
-	 * Constructor. It stores a copy of vertex list of all meshes.
-	 * @param meshes
-	 *        a list of meshes that will form the emitter's shape
-	 */
-	public EmitterMeshVertexShape(List<Mesh> meshes) {
-		this.setMeshes(meshes);
-	}
+    /**
+     * Empty constructor. Sets nothing.
+     */
+    public EmitterMeshVertexShape() {
+    }
 
-	/**
-	 * This method sets the meshes that will form the emiter's shape.
-	 * @param meshes
-	 *        a list of meshes that will form the emitter's shape
-	 */
-	public void setMeshes(List<Mesh> meshes) {
-		Map<Vector3f, Vector3f> vertToNormalMap = new HashMap<Vector3f, Vector3f>();
+    /**
+     * Constructor. It stores a copy of vertex list of all meshes.
+     * @param meshes
+     *        a list of meshes that will form the emitter's shape
+     */
+    public EmitterMeshVertexShape(List<Mesh> meshes) {
+        this.setMeshes(meshes);
+    }
 
-		this.vertices = new ArrayList<List<Vector3f>>(meshes.size());
-		this.normals = new ArrayList<List<Vector3f>>(meshes.size());
-		for (Mesh mesh : meshes) {
-			// fetching the data
-			float[] vertexTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Position));
-			float[] normalTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Normal));
+    /**
+     * This method sets the meshes that will form the emiter's shape.
+     * @param meshes
+     *        a list of meshes that will form the emitter's shape
+     */
+    public void setMeshes(List<Mesh> meshes) {
+        Map<Vector3f, Vector3f> vertToNormalMap = new HashMap<Vector3f, Vector3f>();
 
-			// unifying normals
-			for (int i = 0; i < vertexTable.length; i += 3) {// the tables should have the same size and be dividable by 3
-				Vector3f vert = new Vector3f(vertexTable[i], vertexTable[i + 1], vertexTable[i + 2]);
-				Vector3f norm = vertToNormalMap.get(vert);
-				if (norm == null) {
-					norm = new Vector3f(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
-					vertToNormalMap.put(vert, norm);
-				} else {
-					norm.addLocal(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
-				}
-			}
+        this.vertices = new ArrayList<List<Vector3f>>(meshes.size());
+        this.normals = new ArrayList<List<Vector3f>>(meshes.size());
+        for (Mesh mesh : meshes) {
+            // fetching the data
+            float[] vertexTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Position));
+            float[] normalTable = BufferUtils.getFloatArray(mesh.getFloatBuffer(Type.Normal));
 
-			// adding data to vertices and normals
-			List<Vector3f> vertices = new ArrayList<Vector3f>(vertToNormalMap.size());
-			List<Vector3f> normals = new ArrayList<Vector3f>(vertToNormalMap.size());
-			for (Entry<Vector3f, Vector3f> entry : vertToNormalMap.entrySet()) {
-				vertices.add(entry.getKey());
-				normals.add(entry.getValue().normalizeLocal());
-			}
-			this.vertices.add(vertices);
-			this.normals.add(normals);
-		}
-	}
+            // unifying normals
+            for (int i = 0; i < vertexTable.length; i += 3) {// the tables should have the same size and be dividable by 3
+                Vector3f vert = new Vector3f(vertexTable[i], vertexTable[i + 1], vertexTable[i + 2]);
+                Vector3f norm = vertToNormalMap.get(vert);
+                if (norm == null) {
+                    norm = new Vector3f(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
+                    vertToNormalMap.put(vert, norm);
+                } else {
+                    norm.addLocal(normalTable[i], normalTable[i + 1], normalTable[i + 2]);
+                }
+            }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected mesh vertex.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected mesh vertex
-	 */
-	@Override
-	public void getRandomPoint(Vector3f store) {
-		int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
-		int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() - 1);
-		store.set(vertices.get(meshIndex).get(vertIndex));
-	}
+            // adding data to vertices and normals
+            List<Vector3f> vertices = new ArrayList<Vector3f>(vertToNormalMap.size());
+            List<Vector3f> normals = new ArrayList<Vector3f>(vertToNormalMap.size());
+            for (Entry<Vector3f, Vector3f> entry : vertToNormalMap.entrySet()) {
+                vertices.add(entry.getKey());
+                normals.add(entry.getValue().normalizeLocal());
+            }
+            this.vertices.add(vertices);
+            this.normals.add(normals);
+        }
+    }
 
-	/**
-	 * This method fills the point with coordinates of randomly selected mesh vertex.
-	 * The normal param is filled with selected vertex's normal.
-	 * @param store
-	 *        the variable to store with coordinates of randomly selected mesh vertex
-	 * @param normal
-	 *        filled with selected vertex's normal
-	 */
-	@Override
-	public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-		int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
-		int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() - 1);
-		store.set(vertices.get(meshIndex).get(vertIndex));
-		normal.set(normals.get(meshIndex).get(vertIndex));
-	}
+    /**
+     * This method fills the point with coordinates of randomly selected mesh vertex.
+     * @param store
+     *        the variable to store with coordinates of randomly selected mesh vertex
+     */
+    @Override
+    public void getRandomPoint(Vector3f store) {
+        int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
+        int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() - 1);
+        store.set(vertices.get(meshIndex).get(vertIndex));
+    }
 
-	@Override
-	public EmitterShape deepClone() {
-		try {
-			EmitterMeshVertexShape clone = (EmitterMeshVertexShape) super.clone();
-			if (this.vertices != null) {
-				clone.vertices = new ArrayList<List<Vector3f>>(vertices.size());
-				for (List<Vector3f> list : vertices) {
-					List<Vector3f> vectorList = new ArrayList<Vector3f>(list.size());
-					for (Vector3f vector : list) {
-						vectorList.add(vector.clone());
-					}
-					clone.vertices.add(vectorList);
-				}
-			}
-			if (this.normals != null) {
-				clone.normals = new ArrayList<List<Vector3f>>(normals.size());
-				for (List<Vector3f> list : normals) {
-					List<Vector3f> vectorList = new ArrayList<Vector3f>(list.size());
-					for (Vector3f vector : list) {
-						vectorList.add(vector.clone());
-					}
-					clone.normals.add(vectorList);
-				}
-			}
-			return clone;
-		} catch (CloneNotSupportedException e) {
-			throw new AssertionError();
-		}
-	}
+    /**
+     * This method fills the point with coordinates of randomly selected mesh vertex.
+     * The normal param is filled with selected vertex's normal.
+     * @param store
+     *        the variable to store with coordinates of randomly selected mesh vertex
+     * @param normal
+     *        filled with selected vertex's normal
+     */
+    @Override
+    public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
+        int meshIndex = FastMath.nextRandomInt(0, vertices.size() - 1);
+        int vertIndex = FastMath.nextRandomInt(0, vertices.get(meshIndex).size() - 1);
+        store.set(vertices.get(meshIndex).get(vertIndex));
+        normal.set(normals.get(meshIndex).get(vertIndex));
+    }
 
-	@Override
-	public void write(JmeExporter ex) throws IOException {
-		OutputCapsule oc = ex.getCapsule(this);
-		oc.writeSavableArrayList((ArrayList<List<Vector3f>>) vertices, "vertices", null);
-	}
+    @Override
+    public EmitterShape deepClone() {
+        try {
+            EmitterMeshVertexShape clone = (EmitterMeshVertexShape) super.clone();
+            if (this.vertices != null) {
+                clone.vertices = new ArrayList<List<Vector3f>>(vertices.size());
+                for (List<Vector3f> list : vertices) {
+                    List<Vector3f> vectorList = new ArrayList<Vector3f>(list.size());
+                    for (Vector3f vector : list) {
+                        vectorList.add(vector.clone());
+                    }
+                    clone.vertices.add(vectorList);
+                }
+            }
+            if (this.normals != null) {
+                clone.normals = new ArrayList<List<Vector3f>>(normals.size());
+                for (List<Vector3f> list : normals) {
+                    List<Vector3f> vectorList = new ArrayList<Vector3f>(list.size());
+                    for (Vector3f vector : list) {
+                        vectorList.add(vector.clone());
+                    }
+                    clone.normals.add(vectorList);
+                }
+            }
+            return clone;
+        } catch (CloneNotSupportedException e) {
+            throw new AssertionError();
+        }
+    }
 
-	@Override
-	@SuppressWarnings("unchecked")
-	public void read(JmeImporter im) throws IOException {
-		this.vertices = im.getCapsule(this).readSavableArrayList("vertices", null);
-	}
+    @Override
+    public void write(JmeExporter ex) throws IOException {
+        OutputCapsule oc = ex.getCapsule(this);
+        oc.writeSavableArrayList((ArrayList<List<Vector3f>>) vertices, "vertices", null);
+    }
+
+    @Override
+    @SuppressWarnings("unchecked")
+    public void read(JmeImporter im) throws IOException {
+        this.vertices = im.getCapsule(this).readSavableArrayList("vertices", null);
+    }
 }

+ 9 - 11
engine/src/core/com/jme3/effect/shapes/EmitterPointShape.java

@@ -29,7 +29,6 @@
  * 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.effect.shapes;
 
 import com.jme3.export.JmeExporter;
@@ -42,15 +41,15 @@ public class EmitterPointShape implements EmitterShape {
 
     private Vector3f point;
 
-    public EmitterPointShape(){
+    public EmitterPointShape() {
     }
 
-    public EmitterPointShape(Vector3f point){
+    public EmitterPointShape(Vector3f point) {
         this.point = point;
     }
 
     @Override
-	public EmitterShape deepClone(){
+    public EmitterShape deepClone() {
         try {
             EmitterPointShape clone = (EmitterPointShape) super.clone();
             clone.point = point.clone();
@@ -61,10 +60,10 @@ public class EmitterPointShape implements EmitterShape {
     }
 
     @Override
-	public void getRandomPoint(Vector3f store) {
-       store.set(point);
+    public void getRandomPoint(Vector3f store) {
+        store.set(point);
     }
-    
+
     /**
      * This method fills the point with data.
      * It does not fill the normal.
@@ -73,7 +72,7 @@ public class EmitterPointShape implements EmitterShape {
      */
     @Override
     public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-    	store.set(point);
+        store.set(point);
     }
 
     public Vector3f getPoint() {
@@ -85,14 +84,13 @@ public class EmitterPointShape implements EmitterShape {
     }
 
     @Override
-	public void write(JmeExporter ex) throws IOException {
+    public void write(JmeExporter ex) throws IOException {
         OutputCapsule oc = ex.getCapsule(this);
         oc.write(point, "point", null);
     }
 
     @Override
-	public void read(JmeImporter im) throws IOException {
+    public void read(JmeImporter im) throws IOException {
         this.point = (Vector3f) im.getCapsule(this).readSavable("point", null);
     }
-
 }

+ 20 - 20
engine/src/core/com/jme3/effect/shapes/EmitterShape.java

@@ -29,7 +29,6 @@
  * 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.effect.shapes;
 
 import com.jme3.export.Savable;
@@ -40,25 +39,26 @@ import com.jme3.math.Vector3f;
  * @author Kirill
  */
 public interface EmitterShape extends Savable, Cloneable {
-	/**
-	 * This method fills in the initial position of the particle.
-	 * @param store
-	 *        store variable for initial position
-	 */
-	public void getRandomPoint(Vector3f store);
 
-	/**
-	 * This method fills in the initial position of the particle and its normal vector.
-	 * @param store
-	 *        store variable for initial position
-	 * @param normal
-	 *        store variable for initial normal
-	 */
-	public void getRandomPointAndNormal(Vector3f store, Vector3f normal);
+    /**
+     * This method fills in the initial position of the particle.
+     * @param store
+     *        store variable for initial position
+     */
+    public void getRandomPoint(Vector3f store);
+
+    /**
+     * This method fills in the initial position of the particle and its normal vector.
+     * @param store
+     *        store variable for initial position
+     * @param normal
+     *        store variable for initial normal
+     */
+    public void getRandomPointAndNormal(Vector3f store, Vector3f normal);
 
-	/**
-	 * This method creates a deep clone of the current instance of the emitter shape.
-	 * @return deep clone of the current instance of the emitter shape
-	 */
-	public EmitterShape deepClone();
+    /**
+     * This method creates a deep clone of the current instance of the emitter shape.
+     * @return deep clone of the current instance of the emitter shape
+     */
+    public EmitterShape deepClone();
 }

+ 12 - 14
engine/src/core/com/jme3/effect/shapes/EmitterSphereShape.java

@@ -29,7 +29,6 @@
  * 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.effect.shapes;
 
 import com.jme3.export.JmeExporter;
@@ -45,24 +44,24 @@ public class EmitterSphereShape implements EmitterShape {
     private Vector3f center;
     private float radius;
 
-    public EmitterSphereShape(){
+    public EmitterSphereShape() {
     }
 
     public EmitterSphereShape(Vector3f center, float radius) {
         if (center == null) {
-			throw new NullPointerException();
-		}
+            throw new NullPointerException();
+        }
 
         if (radius <= 0) {
-			throw new IllegalArgumentException("Radius must be greater than 0");
-		}
+            throw new IllegalArgumentException("Radius must be greater than 0");
+        }
 
         this.center = center;
         this.radius = radius;
     }
 
     @Override
-    public EmitterShape deepClone(){
+    public EmitterShape deepClone() {
         try {
             EmitterSphereShape clone = (EmitterSphereShape) super.clone();
             clone.center = center.clone();
@@ -73,17 +72,17 @@ public class EmitterSphereShape implements EmitterShape {
     }
 
     @Override
-	public void getRandomPoint(Vector3f store) {
+    public void getRandomPoint(Vector3f store) {
         do {
             store.x = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
             store.y = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
             store.z = (FastMath.nextRandomFloat() * 2f - 1f) * radius;
         } while (store.distance(center) > radius);
     }
-    
+
     @Override
     public void getRandomPointAndNormal(Vector3f store, Vector3f normal) {
-    	this.getRandomPoint(store);
+        this.getRandomPoint(store);
     }
 
     public Vector3f getCenter() {
@@ -101,19 +100,18 @@ public class EmitterSphereShape implements EmitterShape {
     public void setRadius(float radius) {
         this.radius = radius;
     }
-    
+
     @Override
-	public void write(JmeExporter ex) throws IOException {
+    public void write(JmeExporter ex) throws IOException {
         OutputCapsule oc = ex.getCapsule(this);
         oc.write(center, "center", null);
         oc.write(radius, "radius", 0);
     }
 
     @Override
-	public void read(JmeImporter im) throws IOException {
+    public void read(JmeImporter im) throws IOException {
         InputCapsule ic = im.getCapsule(this);
         center = (Vector3f) ic.readSavable("center", null);
         radius = ic.readFloat("radius", 0);
     }
-
 }

+ 1 - 2
engine/src/core/com/jme3/math/ColorRGBA.java

@@ -55,8 +55,7 @@ import java.io.IOException;
  * @version $Id: ColorRGBA.java,v 1.29 2007/09/09 18:25:14 irrisor Exp $
  */
 public final class ColorRGBA implements Savable, Cloneable {
-
-    private static final long serialVersionUID = 1L;
+    
     /**
      * the color black (0,0,0).
      */

+ 0 - 3
engine/src/core/com/jme3/math/Line.java

@@ -40,7 +40,6 @@ import com.jme3.export.Savable;
 import com.jme3.util.BufferUtils;
 import com.jme3.util.TempVars;
 import java.io.IOException;
-import java.io.Serializable;
 import java.nio.FloatBuffer;
 
 /**
@@ -51,8 +50,6 @@ import java.nio.FloatBuffer;
  * @author Joshua Slack
  */
 public class Line implements Savable, Cloneable {
-    //todo: merge with Ray?
-    private static final long serialVersionUID = 1L;
 
     private Vector3f origin;
     private Vector3f direction;

Rozdílová data souboru nebyla zobrazena, protože soubor je příliš velký
+ 518 - 523
engine/src/core/com/jme3/math/LineSegment.java


+ 0 - 1
engine/src/core/com/jme3/math/Ray.java

@@ -57,7 +57,6 @@ import java.io.IOException;
 public final class Ray implements Savable, Cloneable, Collidable {
 
     //todo: merge with Line?
-    private static final long serialVersionUID = 1L;
 
     /** The ray's begining point. */
     public Vector3f origin;

+ 1 - 3
engine/src/core/com/jme3/math/Rectangle.java

@@ -38,7 +38,6 @@ import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
 import java.io.IOException;
-import java.io.Serializable;
 
 
 /**
@@ -51,8 +50,7 @@ import java.io.Serializable;
  * @author Joshua Slack
  */
 
-public final class Rectangle implements Serializable, Savable, Cloneable {
-    private static final long serialVersionUID = 1L;
+public final class Rectangle implements Savable, Cloneable {
 
     private Vector3f a, b, c;
 

+ 1 - 3
engine/src/core/com/jme3/math/Ring.java

@@ -38,7 +38,6 @@ import com.jme3.export.JmeImporter;
 import com.jme3.export.OutputCapsule;
 import com.jme3.export.Savable;
 import java.io.IOException;
-import java.io.Serializable;
 
 
 /**
@@ -50,8 +49,7 @@ import java.io.Serializable;
  * @author Joshua Slack
  */
 
-public final class Ring implements Serializable, Savable, Cloneable {
-    private static final long serialVersionUID = 1L;
+public final class Ring implements Savable, Cloneable {
     
     private Vector3f center, up;
     private float innerRadius, outerRadius;

+ 0 - 2
engine/src/core/com/jme3/math/Vector2f.java

@@ -52,8 +52,6 @@ import java.util.logging.Logger;
 public final class Vector2f implements Savable, Cloneable {
     private static final Logger logger = Logger.getLogger(Vector2f.class.getName());
 
-    private static final long serialVersionUID = 1L;
-
     public static final Vector2f ZERO = new Vector2f(0f, 0f);
     public static final Vector2f UNIT_XY = new Vector2f(1f, 1f);
     

+ 0 - 2
engine/src/core/com/jme3/scene/shape/Box.java

@@ -73,8 +73,6 @@ public class Box extends AbstractBox {
         1, 0, 0, 0, 0, 1, 1, 1  // bottom
     };
 
-    private static final long serialVersionUID = 1L;
-
     /**
      * Creates a new box.
      * <p>

+ 0 - 2
engine/src/core/com/jme3/scene/shape/PQTorus.java

@@ -56,8 +56,6 @@ import java.nio.ShortBuffer;
  */
 public class PQTorus extends Mesh {
 
-    private static final long serialVersionUID = 1L;
-
     private float p, q;
 
     private float radius, width;

+ 88 - 65
engine/src/networking/com/jme3/network/rmi/ObjectStore.java

@@ -32,12 +32,14 @@
 
 package com.jme3.network.rmi;
 
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.ConnectionListener;
-import com.jme3.network.events.MessageListener;
-import com.jme3.network.message.Message;
+import com.jme3.network.Client;
+import com.jme3.network.ClientStateListener;
+import com.jme3.network.ClientStateListener.DisconnectInfo;
+import com.jme3.network.ConnectionListener;
+import com.jme3.network.HostedConnection;
+import com.jme3.network.Message;
+import com.jme3.network.MessageListener;
+import com.jme3.network.Server;
 import com.jme3.network.serializing.Serializer;
 import com.jme3.util.IntMap;
 import com.jme3.util.IntMap.Entry;
@@ -45,11 +47,12 @@ import java.io.IOException;
 import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
+import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-public class ObjectStore implements MessageListener, ConnectionListener {
+public class ObjectStore {
 
     private static final Logger logger = Logger.getLogger(ObjectStore.class.getName());
 
@@ -66,6 +69,9 @@ public class ObjectStore implements MessageListener, ConnectionListener {
 
     private Client client;
     private Server server;
+    
+    private ClientEventHandler clientEventHandler = new ClientEventHandler();
+    private ServerEventHandler serverEventHandler = new ServerEventHandler();
 
     // Local object ID counter
     private volatile short objectIdCounter = 0;
@@ -85,6 +91,38 @@ public class ObjectStore implements MessageListener, ConnectionListener {
 
     private final Object receiveObjectLock = new Object();
 
+    public class ServerEventHandler implements MessageListener<HostedConnection>,
+                                                      ConnectionListener {
+
+        public void messageReceived(HostedConnection source, Message m) {
+            onMessage(source, m);
+        }
+
+        public void connectionAdded(Server server, HostedConnection conn) {
+            onConnection(conn);
+        }
+
+        public void connectionRemoved(Server server, HostedConnection conn) {
+        }
+        
+    } 
+    
+    public class ClientEventHandler implements MessageListener,
+                                                      ClientStateListener {
+
+        public void messageReceived(Object source, Message m) {
+            onMessage(null, m);
+        }
+
+        public void clientConnected(Client c) {
+            onConnection(null);
+        }
+
+        public void clientDisconnected(Client c, DisconnectInfo info) {
+        }
+        
+    }
+    
     static {
         Serializer s = new RmiSerializer();
         Serializer.registerClass(RemoteObjectDefMessage.class, s);
@@ -92,20 +130,22 @@ public class ObjectStore implements MessageListener, ConnectionListener {
         Serializer.registerClass(RemoteMethodReturnMessage.class, s);
     }
 
-    public ObjectStore(Client client){
+    public ObjectStore(Client client) {
         this.client = client;
-        client.addMessageListener(this, RemoteObjectDefMessage.class, 
-                                        RemoteMethodCallMessage.class,
-                                        RemoteMethodReturnMessage.class);
-        client.addConnectionListener(this);
+        client.addMessageListener(clientEventHandler, 
+                RemoteObjectDefMessage.class,
+                RemoteMethodCallMessage.class,
+                RemoteMethodReturnMessage.class);
+        client.addClientStateListener(clientEventHandler);
     }
 
-    public ObjectStore(Server server){
+    public ObjectStore(Server server) {
         this.server = server;
-        server.addMessageListener(this, RemoteObjectDefMessage.class, 
-                                        RemoteMethodCallMessage.class,
-                                        RemoteMethodReturnMessage.class);
-        server.addConnectionListener(this);
+        server.addMessageListener(serverEventHandler, 
+                RemoteObjectDefMessage.class,
+                RemoteMethodCallMessage.class,
+                RemoteMethodReturnMessage.class);
+        server.addConnectionListener(serverEventHandler);
     }
 
     private ObjectDef makeObjectDef(LocalObject localObj){
@@ -122,7 +162,15 @@ public class ObjectStore implements MessageListener, ConnectionListener {
         localObj.objectName = name;
         localObj.objectId  = objectIdCounter++;
         localObj.theObject = obj;
-        localObj.methods   = obj.getClass().getMethods();
+        //localObj.methods   = obj.getClass().getMethods();
+        
+        ArrayList<Method> methodList = new ArrayList<Method>();
+        for (Method method : obj.getClass().getMethods()){
+            if (method.getDeclaringClass() == obj.getClass()){
+                methodList.add(method);
+            }
+        }
+        localObj.methods = methodList.toArray(new Method[methodList.size()]);  
         
         // Put it in the store
         localObjects.put(localObj.objectId, localObj);
@@ -180,18 +228,14 @@ public class ObjectStore implements MessageListener, ConnectionListener {
             pendingInvocations.put(call.invocationId, invoke);
         }
 
-        try{
-            if (server != null){
-                remoteObj.client.send(call);
-                logger.log(Level.INFO, "Server: Sending {0}", call);
-            }else{
-                client.send(call);
-                logger.log(Level.INFO, "Client: Sending {0}", call);
-            }
-        } catch (IOException ex){
-            ex.printStackTrace();
+        if (server != null){
+            remoteObj.client.send(call);
+            logger.log(Level.INFO, "Server: Sending {0}", call);
+        }else{
+            client.send(call);
+            logger.log(Level.INFO, "Client: Sending {0}", call);
         }
-
+       
         if (invoke != null){
             synchronized(invoke){
                 while (!invoke.available){
@@ -210,7 +254,7 @@ public class ObjectStore implements MessageListener, ConnectionListener {
         }
     }
 
-    public void messageReceived(Message message) {
+    private void onMessage(HostedConnection source, Message message) {
         // Might want to do more strict validation of the data
         // in the message to prevent crashes
 
@@ -219,7 +263,7 @@ public class ObjectStore implements MessageListener, ConnectionListener {
 
             ObjectDef[] defs = defMsg.objects;
             for (ObjectDef def : defs){
-                RemoteObject remoteObject = new RemoteObject(this, message.getClient());
+                RemoteObject remoteObject = new RemoteObject(this, source);
                 remoteObject.objectId = (short)def.objectId;
                 remoteObject.methodDefs = def.methodDefs;
                 remoteObjects.put(def.objectName, remoteObject);
@@ -257,16 +301,12 @@ public class ObjectStore implements MessageListener, ConnectionListener {
                 RemoteMethodReturnMessage retMsg = new RemoteMethodReturnMessage();
                 retMsg.invocationID = call.invocationId;
                 retMsg.retVal = ret;
-                try {
-                    if (server != null){
-                        call.getClient().send(retMsg);
-                        logger.log(Level.INFO, "Server: Sending {0}", retMsg);
-                    } else{
-                        client.send(retMsg);
-                        logger.log(Level.INFO, "Client: Sending {0}", retMsg);
-                    }
-                } catch (IOException ex){
-                    ex.printStackTrace();
+                if (server != null){
+                    source.send(retMsg);
+                    logger.log(Level.INFO, "Server: Sending {0}", retMsg);
+                } else{
+                    client.send(retMsg);
+                    logger.log(Level.INFO, "Client: Sending {0}", retMsg);
                 }
             }
         }else if (message instanceof RemoteMethodReturnMessage){
@@ -285,7 +325,7 @@ public class ObjectStore implements MessageListener, ConnectionListener {
         }
     }
 
-    public void clientConnected(Client client) {
+    private void onConnection(HostedConnection conn) {
         if (localObjects.size() > 0){
             // send a object definition message
             ObjectDef[] defs = new ObjectDef[localObjects.size()];
@@ -297,31 +337,14 @@ public class ObjectStore implements MessageListener, ConnectionListener {
 
             RemoteObjectDefMessage defMsg = new RemoteObjectDefMessage();
             defMsg.objects = defs;
-            try {
-                if (this.client != null){
-                    this.client.send(defMsg);
-                    logger.log(Level.INFO, "Client: Sending {0}", defMsg);
-                } else{
-                    client.send(defMsg);
-                    logger.log(Level.INFO, "Server: Sending {0}", defMsg);
-                }
-            } catch (IOException ex){
-                ex.printStackTrace();
+            if (this.client != null){
+                this.client.send(defMsg);
+                logger.log(Level.INFO, "Client: Sending {0}", defMsg);
+            } else{
+                conn.send(defMsg);
+                logger.log(Level.INFO, "Server: Sending {0}", defMsg);
             }
         }
     }
 
-    public void clientDisconnected(Client client) {
-
-    }
-
-    public void messageSent(Message message) {
-    }
-
-    public void objectReceived(Object object) {
-    }
-
-    public void objectSent(Object object) {
-    }
-
 }

+ 2 - 2
engine/src/networking/com/jme3/network/rmi/RemoteMethodCallMessage.java

@@ -32,7 +32,7 @@
 
 package com.jme3.network.rmi;
 
-import com.jme3.network.message.Message;
+import com.jme3.network.AbstractMessage;
 import com.jme3.network.serializing.Serializable;
 
 /**
@@ -41,7 +41,7 @@ import com.jme3.network.serializing.Serializable;
  * @author Kirill Vainer
  */
 @Serializable
-public class RemoteMethodCallMessage extends Message {
+public class RemoteMethodCallMessage extends AbstractMessage {
 
     public RemoteMethodCallMessage(){
         super(true);

+ 2 - 3
engine/src/networking/com/jme3/network/rmi/RemoteMethodReturnMessage.java

@@ -32,8 +32,7 @@
 
 package com.jme3.network.rmi;
 
-
-import com.jme3.network.message.Message;
+import com.jme3.network.AbstractMessage;
 import com.jme3.network.serializing.Serializable;
 
 /**
@@ -43,7 +42,7 @@ import com.jme3.network.serializing.Serializable;
  * @author Kirill Vainer.
  */
 @Serializable
-public class RemoteMethodReturnMessage extends Message {
+public class RemoteMethodReturnMessage extends AbstractMessage {
 
     public RemoteMethodReturnMessage(){
         super(true);

+ 3 - 4
engine/src/networking/com/jme3/network/rmi/RemoteObject.java

@@ -32,8 +32,7 @@
 
 package com.jme3.network.rmi;
 
-
-import com.jme3.network.connection.Client;
+import com.jme3.network.HostedConnection;
 import java.lang.reflect.InvocationHandler;
 import java.lang.reflect.Method;
 import java.util.ArrayList;
@@ -72,9 +71,9 @@ public class RemoteObject implements InvocationHandler {
      * The client who exposed the RMI interface, or null if the server
      * exposed it.
      */
-    Client client;
+    HostedConnection client;
 
-    public RemoteObject(ObjectStore store, Client client){
+    public RemoteObject(ObjectStore store, HostedConnection client){
         this.store = store;
         this.client = client;
     }

+ 2 - 4
engine/src/networking/com/jme3/network/rmi/RemoteObjectDefMessage.java

@@ -32,9 +32,7 @@
 
 package com.jme3.network.rmi;
 
-
-
-import com.jme3.network.message.Message;
+import com.jme3.network.AbstractMessage;
 import com.jme3.network.serializing.Serializable;
 
 /**
@@ -42,7 +40,7 @@ import com.jme3.network.serializing.Serializable;
  * @author Kirill Vainer
  */
 @Serializable
-public class RemoteObjectDefMessage extends Message {
+public class RemoteObjectDefMessage extends AbstractMessage {
 
     public ObjectDef[] objects;
     

+ 72 - 74
engine/src/terrain/com/jme3/terrain/geomipmap/LRUCache.java

@@ -17,7 +17,6 @@ package com.jme3.terrain.geomipmap;
 //
 // Please contact the author if you need another license.
 // This module is provided "as is", without warranties of any kind.
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedHashMap;
@@ -40,85 +39,84 @@ import java.util.Map;
  */
 public class LRUCache<K, V> {
 
-	private static final float hashTableLoadFactor = 0.75f;
-
-	private LinkedHashMap<K, V> map;
-	private int cacheSize;
+    private static final float hashTableLoadFactor = 0.75f;
+    private LinkedHashMap<K, V> map;
+    private int cacheSize;
 
-	/**
-	 * Creates a new LRU cache.
-	 * 
-	 * @param cacheSize
-	 *            the maximum number of entries that will be kept in this cache.
-	 */
-	public LRUCache(int cacheSize) {
-		this.cacheSize = cacheSize;
-		int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1;
-		this.map = new LinkedHashMap<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) {
-			// (an anonymous inner class)
-			private static final long serialVersionUID = 1;
+    /**
+     * Creates a new LRU cache.
+     * 
+     * @param cacheSize
+     *            the maximum number of entries that will be kept in this cache.
+     */
+    public LRUCache(int cacheSize) {
+        this.cacheSize = cacheSize;
+        int hashTableCapacity = (int) Math.ceil(cacheSize / LRUCache.hashTableLoadFactor) + 1;
+        this.map = new LinkedHashMap<K, V>(hashTableCapacity, LRUCache.hashTableLoadFactor, true) {
+            // (an anonymous inner class)
 
-			@Override
-			protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
-				return this.size() > LRUCache.this.cacheSize;
-			}
-		};
-	}
+            private static final long serialVersionUID = 1;
 
-	/**
-	 * Retrieves an entry from the cache.<br>
-	 * The retrieved entry becomes the MRU (most recently used) entry.
-	 * 
-	 * @param key
-	 *            the key whose associated value is to be returned.
-	 * @return the value associated to this key, or null if no value with this
-	 *         key exists in the cache.
-	 */
-	public synchronized V get(K key) {
-		return this.map.get(key);
-	}
+            @Override
+            protected boolean removeEldestEntry(Map.Entry<K, V> eldest) {
+                return this.size() > LRUCache.this.cacheSize;
+            }
+        };
+    }
 
-	/**
-	 * Adds an entry to this cache.
-	 * The new entry becomes the MRU (most recently used) entry.
-	 * If an entry with the specified key already exists in the cache, it is
-	 * replaced by the new entry.
-	 * If the cache is full, the LRU (least recently used) entry is removed from
-	 * the cache.
-	 * 
-	 * @param key
-	 *            the key with which the specified value is to be associated.
-	 * @param value
-	 *            a value to be associated with the specified key.
-	 */
-	public synchronized void put(K key, V value) {
-		this.map.put(key, value);
-	}
+    /**
+     * Retrieves an entry from the cache.<br>
+     * The retrieved entry becomes the MRU (most recently used) entry.
+     * 
+     * @param key
+     *            the key whose associated value is to be returned.
+     * @return the value associated to this key, or null if no value with this
+     *         key exists in the cache.
+     */
+    public synchronized V get(K key) {
+        return this.map.get(key);
+    }
 
-	/**
-	 * Clears the cache.
-	 */
-	public synchronized void clear() {
-		this.map.clear();
-	}
+    /**
+     * Adds an entry to this cache.
+     * The new entry becomes the MRU (most recently used) entry.
+     * If an entry with the specified key already exists in the cache, it is
+     * replaced by the new entry.
+     * If the cache is full, the LRU (least recently used) entry is removed from
+     * the cache.
+     * 
+     * @param key
+     *            the key with which the specified value is to be associated.
+     * @param value
+     *            a value to be associated with the specified key.
+     */
+    public synchronized void put(K key, V value) {
+        this.map.put(key, value);
+    }
 
-	/**
-	 * Returns the number of used entries in the cache.
-	 * 
-	 * @return the number of entries currently in the cache.
-	 */
-	public synchronized int usedEntries() {
-		return this.map.size();
-	}
+    /**
+     * Clears the cache.
+     */
+    public synchronized void clear() {
+        this.map.clear();
+    }
 
-	/**
-	 * Returns a <code>Collection</code> that contains a copy of all cache
-	 * entries.
-	 * 
-	 * @return a <code>Collection</code> with a copy of the cache content.
-	 */
-	public synchronized Collection<Map.Entry<K, V>> getAll() {
-		return new ArrayList<Map.Entry<K, V>>(this.map.entrySet());
-	}
+    /**
+     * Returns the number of used entries in the cache.
+     * 
+     * @return the number of entries currently in the cache.
+     */
+    public synchronized int usedEntries() {
+        return this.map.size();
+    }
 
+    /**
+     * Returns a <code>Collection</code> that contains a copy of all cache
+     * entries.
+     * 
+     * @return a <code>Collection</code> with a copy of the cache content.
+     */
+    public synchronized Collection<Map.Entry<K, V>> getAll() {
+        return new ArrayList<Map.Entry<K, V>>(this.map.entrySet());
+    }
 } // end class LRUCache

+ 157 - 154
engine/src/test/jme3test/blender/ManualBlenderTester.java

@@ -41,7 +41,7 @@ import java.util.logging.Level;
 import java.util.logging.Logger;
 
 import jme3test.blender.config.ConfigDialog;
-import jme3test.blender.config.IConfigExecutable;
+import jme3test.blender.config.ConfigExecutable;
 import jme3test.blender.scene.Pivot;
 
 import com.jme3.animation.AnimControl;
@@ -67,157 +67,160 @@ import com.jme3.texture.plugins.AWTLoader;
  * @author Marcin Roguski (Kaelthas)
  */
 public class ManualBlenderTester extends SimpleApplication {
-	private static final Logger	LOGGER	= Logger.getLogger(ManualBlenderTester.class.getName());
-	private ModelKey modelKey;//the key that holds the test file configuration
-	private final boolean debug;
-	
-	/**
-	 * Starting method
-	 * @param args input parameters; the following options can be passed to the application:
-	 * <li> -debug   : this one indicates if the application runs in debug or not (it is used under linux
-	 * 				   in order to enable the mouse in debug mode since linuxes tend not to give the cursor back
-	 * 				   to eclipse)
-	 */
-	public static void main(String[] args) {
-		//veryfying if the application is in debug mode
-		boolean debug = false;
-		for(String arg : args) {
-			if("-debug".equalsIgnoreCase(arg)) {
-				debug = true;
-				break;
-			}
-		}
-		final boolean debugMode = debug;
-		//running the application
-		new ConfigDialog("./src/test-data/Blender", new IConfigExecutable() {
-			@Override
-			public void execute(ModelKey modelKey, Level logLevel) {
-				new ManualBlenderTester(modelKey, logLevel, debugMode).start();
-			}
-		});
-	}
-	
-	/**
-	 * Constructor stores the given key and disables the settings screen.
-	 * @param modelKey the key to be stored
-	 * @param logLevel the jme logger log level
-	 * @param debug variable that indicates if the application runs in debug mode
-	 * (this is required on linux to show release the mouse to be used in debug mode)
-	 */
-	public ManualBlenderTester(ModelKey modelKey, Level logLevel, boolean debug) {
-		this.debug = debug;
-		Logger.getLogger("com.jme3").setLevel(logLevel);
-		this.modelKey = modelKey;
-		this.showSettings = false;
-	}
-
-	@Override
-	public void simpleInitApp() {
-		if(debug) {
-			mouseInput.setCursorVisible(true);
-		}
-		assetManager.registerLocator(".", FileLocator.class);
-		assetManager.registerLoader(BlenderLoader.class, "blend");
-		assetManager.registerLoader(AWTLoader.class, "png");
-
-		viewPort.setBackgroundColor(ColorRGBA.Gray);
-
-		flyCam.setMoveSpeed(20);
-		cam.setFrustumFar(1000.0f);
-		cam.setFrustumNear(1.0f);
-		AssetInfo ai = new AssetInfo(assetManager, modelKey) {
-			@Override
-			public InputStream openStream() {
-				try {
-					return new FileInputStream(this.key.getName());
-				} catch(FileNotFoundException e) {
-					LOGGER.log(Level.SEVERE, e.getMessage(), e);
-					return null;
-				}
-			}
-		};
-		rootNode.attachChild(new Pivot(assetManager));
-		if(modelKey instanceof BlenderKey) {
-			Node blenderModel = this.testBlenderLoader(ai);
-			Map<String, Map<String, int[]>> animations = ((BlenderKey) modelKey).getAnimations();
-			//setting the first animation as active
-			if(((BlenderKey) modelKey).getAnimations()!=null) {
-				for(Entry<String, Map<String, int[]>> animEntry : animations.entrySet()) {
-					for(Entry<String, int[]> anim : animEntry.getValue().entrySet()) {
-						Spatial animatedSpatial = this.findNode(blenderModel, animEntry.getKey());
-						animatedSpatial.getControl(AnimControl.class).createChannel().setAnim(anim.getKey());
-						break;
-					}
-					break;
-				}
-			}
-		} else {
-			this.testBlenderModelLoader(ai);
-		}
-		
-		DirectionalLight sun = new DirectionalLight();
-		sun.setDirection(new Vector3f(0, -10, 0).normalizeLocal());
-		sun.setColor(ColorRGBA.White);
-		rootNode.addLight(sun);
-	}
-	
-	/**
-	 * This method finds a node of a given name.
-	 * @param rootNode the root node to search
-	 * @param name the name of the searched node
-	 * @return the found node or null
-	 */
-	private Spatial findNode(Node rootNode, String name) {
-		if(name.equals(rootNode.getName())) {
-			return rootNode;
-		}
-		return rootNode.getChild(name);
-	}
-
-	/**
-	 * This method loads the model using blenderLoader.
-	 * @param assetInfo
-	 *        the asset info
-	 * @return the loaded model
-	 */
-	private Node testBlenderLoader(AssetInfo assetInfo) {
-		Node blenderModel = null;
-		BlenderLoader blenderLoader = new BlenderLoader();
-		try {
-			LoadingResults loadingResults = blenderLoader.load(assetInfo);
-			for(Node object : loadingResults.getObjects()) {
-				this.rootNode.attachChild(object);
-				blenderModel = object;
-			}
-			for(Light light : loadingResults.getLights()) {
-				this.rootNode.addLight(light);
-			}
-			for(Camera camera : loadingResults.getCameras()) {
-				LOGGER.info(camera.toString());
-			}
-		} catch(IOException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		}
-		return blenderModel;
-	}
-
-	/**
-	 * This method loads the model using blenderModelLoader.
-	 * @param assetInfo
-	 *        the asset info
-	 * @return the loaded model
-	 */
-	private Node testBlenderModelLoader(AssetInfo assetInfo) {
-		BlenderModelLoader blenderLoader = new BlenderModelLoader();
-		try {
-			Spatial loadingResults = blenderLoader.load(assetInfo);
-			this.rootNode.attachChild(loadingResults);
-			if(loadingResults instanceof Node) {
-				return (Node)loadingResults;
-			}
-		} catch(IOException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		}
-		return null;
-	}
+
+    private static final Logger LOGGER = Logger.getLogger(ManualBlenderTester.class.getName());
+    private ModelKey modelKey;//the key that holds the test file configuration
+    private final boolean debug;
+
+    /**
+     * Starting method
+     * @param args input parameters; the following options can be passed to the application:
+     * <li> -debug   : this one indicates if the application runs in debug or not (it is used under linux
+     * 				   in order to enable the mouse in debug mode since linuxes tend not to give the cursor back
+     * 				   to eclipse)
+     */
+    public static void main(String[] args) {
+        //veryfying if the application is in debug mode
+        boolean debug = false;
+        for (String arg : args) {
+            if ("-debug".equalsIgnoreCase(arg)) {
+                debug = true;
+                break;
+            }
+        }
+        final boolean debugMode = debug;
+        //running the application
+        new ConfigDialog("./src/test-data/Blender", new ConfigExecutable() {
+
+            @Override
+            public void execute(ModelKey modelKey, Level logLevel) {
+                new ManualBlenderTester(modelKey, logLevel, debugMode).start();
+            }
+        });
+    }
+
+    /**
+     * Constructor stores the given key and disables the settings screen.
+     * @param modelKey the key to be stored
+     * @param logLevel the jme logger log level
+     * @param debug variable that indicates if the application runs in debug mode
+     * (this is required on linux to show release the mouse to be used in debug mode)
+     */
+    public ManualBlenderTester(ModelKey modelKey, Level logLevel, boolean debug) {
+        this.debug = debug;
+        Logger.getLogger("com.jme3").setLevel(logLevel);
+        this.modelKey = modelKey;
+        this.showSettings = false;
+    }
+
+    @Override
+    public void simpleInitApp() {
+        if (debug) {
+            mouseInput.setCursorVisible(true);
+        }
+        assetManager.registerLocator(".", FileLocator.class);
+        assetManager.registerLoader(BlenderLoader.class, "blend");
+        assetManager.registerLoader(AWTLoader.class, "png");
+
+        viewPort.setBackgroundColor(ColorRGBA.Gray);
+
+        flyCam.setMoveSpeed(20);
+        cam.setFrustumFar(1000.0f);
+        cam.setFrustumNear(1.0f);
+        AssetInfo ai = new AssetInfo(assetManager, modelKey) {
+
+            @Override
+            public InputStream openStream() {
+                try {
+                    return new FileInputStream(this.key.getName());
+                } catch (FileNotFoundException e) {
+                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                    return null;
+                }
+            }
+        };
+        rootNode.attachChild(new Pivot(assetManager));
+        if (modelKey instanceof BlenderKey) {
+            Node blenderModel = this.testBlenderLoader(ai);
+            Map<String, Map<String, int[]>> animations = ((BlenderKey) modelKey).getAnimations();
+            //setting the first animation as active
+            if (((BlenderKey) modelKey).getAnimations() != null) {
+                for (Entry<String, Map<String, int[]>> animEntry : animations.entrySet()) {
+                    for (Entry<String, int[]> anim : animEntry.getValue().entrySet()) {
+                        Spatial animatedSpatial = this.findNode(blenderModel, animEntry.getKey());
+                        animatedSpatial.getControl(AnimControl.class).createChannel().setAnim(anim.getKey());
+                        break;
+                    }
+                    break;
+                }
+            }
+        } else {
+            this.testBlenderModelLoader(ai);
+        }
+
+        DirectionalLight sun = new DirectionalLight();
+        sun.setDirection(new Vector3f(0, -10, 0).normalizeLocal());
+        sun.setColor(ColorRGBA.White);
+        rootNode.addLight(sun);
+    }
+
+    /**
+     * This method finds a node of a given name.
+     * @param rootNode the root node to search
+     * @param name the name of the searched node
+     * @return the found node or null
+     */
+    private Spatial findNode(Node rootNode, String name) {
+        if (name.equals(rootNode.getName())) {
+            return rootNode;
+        }
+        return rootNode.getChild(name);
+    }
+
+    /**
+     * This method loads the model using blenderLoader.
+     * @param assetInfo
+     *        the asset info
+     * @return the loaded model
+     */
+    private Node testBlenderLoader(AssetInfo assetInfo) {
+        Node blenderModel = null;
+        BlenderLoader blenderLoader = new BlenderLoader();
+        try {
+            LoadingResults loadingResults = blenderLoader.load(assetInfo);
+            for (Node object : loadingResults.getObjects()) {
+                this.rootNode.attachChild(object);
+                blenderModel = object;
+            }
+            for (Light light : loadingResults.getLights()) {
+                this.rootNode.addLight(light);
+            }
+            for (Camera camera : loadingResults.getCameras()) {
+                LOGGER.info(camera.toString());
+            }
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        }
+        return blenderModel;
+    }
+
+    /**
+     * This method loads the model using blenderModelLoader.
+     * @param assetInfo
+     *        the asset info
+     * @return the loaded model
+     */
+    private Node testBlenderModelLoader(AssetInfo assetInfo) {
+        BlenderModelLoader blenderLoader = new BlenderModelLoader();
+        try {
+            Spatial loadingResults = blenderLoader.load(assetInfo);
+            this.rootNode.attachChild(loadingResults);
+            if (loadingResults instanceof Node) {
+                return (Node) loadingResults;
+            }
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        }
+        return null;
+    }
 }

+ 333 - 328
engine/src/test/jme3test/blender/config/AbstractConfigDialog.java

@@ -45,332 +45,337 @@ import javax.swing.table.TableCellEditor;
  * @author Marcin Roguski (Kaelthas)
  */
 public abstract class AbstractConfigDialog extends JFrame {
-	private static final long serialVersionUID = -3677493125861310310L;
-	private static final Logger LOGGER = Logger.getLogger(AbstractConfigDialog.class.getName());
-	
-	protected JComboBox jComboBoxVersionSelection;
-	protected JList jListBlenderFiles;
-	protected JTable jTableProperties;
-	protected JTable jTableAnimations;
-	protected JButton jButtonAddAnimation;
-	protected JButton jButtonRemoveAnimation;
-	protected JCheckBox jCheckBoxUseModelKey;
-	protected JButton jButtonOK;
-	protected JButton jButtonCancel;
-	
-	/**
-	 * Cionstructor initializes the gui.
-	 */
-	public AbstractConfigDialog() {
-		this.init();
-	}
-	
-	/**
-	 * This method initializes the window.
-	 */
-	private void init() {
-		try {//setting the system Look And Feel
-			UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
-		} catch (ClassNotFoundException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		} catch (InstantiationException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		} catch (IllegalAccessException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		} catch (UnsupportedLookAndFeelException e) {
-			LOGGER.log(Level.SEVERE, e.getMessage(), e);
-		}
-		this.setLayout(new BorderLayout());
-		
-		this.add(this.prepareBlenderFilesAndLogLevelPanel(), BorderLayout.WEST);
-		this.add(this.prepareFilePropertiesPanel(), BorderLayout.CENTER);
-		this.add(this.prepareButtonsPanel(), BorderLayout.SOUTH);
-		
-		this.pack();
-		this.setLocationRelativeTo(null);
-		this.setVisible(true);
-		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
-	}
-	
-	/**
-	 * This method prepares a swing panel containing the list of blender files
-	 * and log level chooser.
-	 * @return prepared swing panel
-	 */
-	private JPanel prepareBlenderFilesAndLogLevelPanel() {
-		JPanel jPanelBlenderFilesListAndLogLevel = new JPanel();
-		jPanelBlenderFilesListAndLogLevel.setBorder(new TitledBorder("Blender test files"));
-		jPanelBlenderFilesListAndLogLevel.setLayout(new BorderLayout());
-		
-		//blender version selection combo box
-		jComboBoxVersionSelection = new JComboBox(new DefaultComboBoxModel());
-		jComboBoxVersionSelection.setEditable(false);
-		jPanelBlenderFilesListAndLogLevel.add(jComboBoxVersionSelection, BorderLayout.NORTH);
-		
-		//blender list files
-		jListBlenderFiles = new JList(new DefaultListModel());
-		jListBlenderFiles.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
-		JScrollPane listScroller = new JScrollPane(jListBlenderFiles);
-		jPanelBlenderFilesListAndLogLevel.add(listScroller, BorderLayout.CENTER);
-		
-		//Log Level list
-		Box box = Box.createVerticalBox();
-		box.add(new Label("Log level:"));
-		ButtonGroup buttonGroup = new ButtonGroup();
-		
-		Level[] levels = new Level[] {Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO, 
-									  Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST, Level.ALL};
-		for(Level level : levels) {
-			JRadioButtonLevel jRadioButtonLevel = new JRadioButtonLevel(level);
-			buttonGroup.add(jRadioButtonLevel);
-			box.add(jRadioButtonLevel);
-		}
-		jPanelBlenderFilesListAndLogLevel.add(box, BorderLayout.SOUTH);
-		
-		return jPanelBlenderFilesListAndLogLevel;
-	}
-	
-	/**
-	 * This method prepares a swing panel containing the file's animations.
-	 * @return prepared swing panel
-	 */
-	protected JPanel prepareFilePropertiesPanel() {
-		//properties table
-		JPanel jPanelProperties = new JPanel();
-		jPanelProperties.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
-		jPanelProperties.setLayout(new BorderLayout());
-		jPanelProperties.add(new JLabel("Properties"), BorderLayout.NORTH);
-		
-		jTableProperties = new JTable();
-		jTableProperties.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
-		jTableProperties.setModel(new BlenderTableModel(new Object[] {"Name", "Value"}));
-		jTableProperties.getColumnModel().getColumn(1).setCellEditor(new BlenderTableCellEditor());
-		JScrollPane jScrollPaneProperties = new JScrollPane(jTableProperties);
-		jTableProperties.setFillsViewportHeight(true);
-		
-		jPanelProperties.add(jScrollPaneProperties, BorderLayout.CENTER);
-		
-		//animations table
-		JPanel jPanelAnimations = new JPanel();
-		jPanelAnimations.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
-		jPanelAnimations.setLayout(new BorderLayout());
-		jPanelAnimations.add(new JLabel("Animations"), BorderLayout.NORTH);
-		
-		jTableAnimations = new JTable();
-		jTableAnimations.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
-		jTableAnimations.setModel(new DefaultTableModel(new Object[] {"Object", "Name", "Start frame", "Stop frame"}, 0));
-		for(int i=0;i<jTableAnimations.getColumnModel().getColumnCount();++i) {
-			jTableAnimations.getColumnModel().getColumn(i).setCellEditor(new BlenderTableCellEditor());
-		}
-		JScrollPane jScrollPaneAnimations = new JScrollPane(jTableAnimations);
-		jTableAnimations.setFillsViewportHeight(true);
-		
-		JPanel jPanelTableButtons = new JPanel();
-		jPanelTableButtons.setLayout(new FlowLayout(FlowLayout.LEFT));
-		jButtonAddAnimation = new JButton("Add animation");
-		jButtonAddAnimation.setEnabled(false);
-		jButtonRemoveAnimation = new JButton("Remove animation");
-		jButtonRemoveAnimation.setEnabled(false);
-		jPanelTableButtons.add(jButtonAddAnimation);
-		jPanelTableButtons.add(jButtonRemoveAnimation);
-		
-		jPanelAnimations.add(jScrollPaneAnimations, BorderLayout.CENTER);
-		jPanelAnimations.add(jPanelTableButtons, BorderLayout.SOUTH);
-		
-		//model key check-box
-		jCheckBoxUseModelKey = new JCheckBox();
-		jCheckBoxUseModelKey.setText("Use ModelKey to start the test");
-		jCheckBoxUseModelKey.setToolTipText("All BlenderKey settings will remain here, but the application will be " +
-				"started using a model key. So only the path to the file will be given!");
-		
-		//building the result panel
-		JPanel jPanelResult = new JPanel();
-		jPanelResult.setBorder(new TitledBorder("Loading properties"));
-		jPanelResult.setLayout(new BorderLayout());
-		
-		jPanelResult.add(jPanelProperties, BorderLayout.WEST);
-		jPanelResult.add(jPanelAnimations, BorderLayout.CENTER);
-		jPanelResult.add(jCheckBoxUseModelKey, BorderLayout.SOUTH);
-		return jPanelResult;
-	}
-	
-	/**
-	 * This method prepares a swing panel containing the buttons.
-	 * @return prepared swing panel
-	 */
-	protected JPanel prepareButtonsPanel() {
-		JPanel jPanelButtons = new JPanel();
-		jButtonOK = new JButton("OK");
-		jButtonOK.setEnabled(false);
-		jPanelButtons.add(jButtonOK);
-		jButtonCancel = new JButton("Cancel");
-		jPanelButtons.add(jButtonCancel);
-		return jPanelButtons;
-	}
-	
-	/**
-	 * This class was made only to make the selection of a level radio button easier.
-	 * @author Marcin Roguski
-	 */
-	protected static class JRadioButtonLevel extends JRadioButton {
-		private static final long serialVersionUID = 8874525909060993518L;
-		private static Level selectedLevel;
-		private static Map<Level, JRadioButtonLevel> radioButtons = new HashMap<Level, AbstractConfigDialog.JRadioButtonLevel>();
-		private Level level;
-		
-		/**
-		 * Constructor. Creates the radio button.
-		 * Stores it inside the buttons map.
-		 * @param level the level of log info
-		 */
-		public JRadioButtonLevel(Level level) {
-			super(level.getName());
-			this.level = level;
-			radioButtons.put(level, this);
-			this.addActionListener(new ActionListener() {
-				@Override
-				public void actionPerformed(ActionEvent e) {
-					JRadioButtonLevel.selectedLevel = JRadioButtonLevel.this.level;
-				}
-			});
-		}
-		
-		/**
-		 * This method returns the currently selected info level.
-		 * @return currently selected info level
-		 */
-		public static Level getSelectedLevel() {
-			return selectedLevel;
-		}
-		
-		/**
-		 * This method sets the current info level.
-		 * @param level the current info level
-		 */
-		public static synchronized void setSelectedLevel(Level level) {
-			radioButtons.get(level).setSelected(true);
-		}
-	}
-	
-	/**
-	 * This class is an item that should be stored in the files' list.
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class FileListItem {
-		private File file;				//the file to be stored
-		/**
-		 * Constructore. Stores the given file.
-		 * @param file the file to be stored
-		 */
-		public FileListItem(File file) {
-			this.file = file;
-		}
-		
-		/**
-		 * This method returns the stored file.
-		 * @return the stored file
-		 */
-		public File getFile() {
-			return file;
-		}
-		
-		@Override
-		public String toString() {
-			return file.getName();
-		}
-	}
-	
-	/**
-	 * The model for properties table.
-	 * It makes left column ineditable.
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class BlenderTableModel extends DefaultTableModel {
-		private static final long serialVersionUID = -4211206550875326553L;
-
-		/**
-		 * Constructor only calls super-constuctor.
-		 * @param columnNames the names of table columns
-		 */
-		public BlenderTableModel(Object[] columnNames) {
-			super(columnNames, 0);
-		}
-		
-		@Override
-		public void addRow(Object[] rowData) {
-			for(int i=0;i<rowData.length;++i) {
-				if(rowData[i]==null) {
-					rowData[i] = "";
-				}
-			}
-			super.addRow(rowData);
-		}
-		
-		@Override
-		public boolean isCellEditable(int row, int column) {
-			return column>0;
-		}
-	}
-	
-	/**
-	 * A cell editor tah improves data input to the table.
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	protected static class BlenderTableCellEditor extends AbstractCellEditor implements TableCellEditor {
-		private static final long serialVersionUID = -8601975203921608519L;
-		private JCheckBox jCheckBox		= new JCheckBox();
-		private JTextField jTextField	= new JTextField();
-		private JComboBox jComboBox		= new JComboBox();
-		private Object lastValue;
-		
-		@Override
-		public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
-			this.lastValue = value;
-			if(value instanceof Boolean) {
-				jCheckBox.setSelected(((Boolean) value).booleanValue());
-				return jCheckBox;
-			} else if(value instanceof String || value instanceof Number || value instanceof Character) {
-				jTextField.setText(value.toString());
-				return jTextField;
-			} else if(value instanceof Enum<?>) {
-				DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel)jComboBox.getModel();
-				defaultComboBoxModel.removeAllElements();
-				for(Object object : value.getClass().getEnumConstants()) {
-					defaultComboBoxModel.addElement(object);
-				}
-				return jComboBox;
-			}
-			else {
-				jTextField.setText(value==null ? "" : value.toString());
-				return jTextField;
-			}
-		}
-
-		@Override
-		public Object getCellEditorValue() {
-			if(lastValue instanceof Boolean) {
-				return Boolean.valueOf(jCheckBox.isSelected());
-			} else if(lastValue instanceof String) {
-				return jTextField.getText();
-			} else if(lastValue instanceof Character) {
-				return Character.valueOf(jTextField.getText().charAt(0));
-			} else if(lastValue instanceof Byte) {
-				return Byte.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Short) {
-				return Short.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Integer) {
-				return Integer.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Long) {
-				return Long.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Float) {
-				return Float.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Double) {
-				return Double.valueOf(jTextField.getText());
-			} else if(lastValue instanceof Enum<?>) {
-				return jComboBox.getSelectedItem();
-			}
-			//TODO: savable objects
-			return null;
-		}
-	}
+
+    private static final long serialVersionUID = -3677493125861310310L;
+    private static final Logger LOGGER = Logger.getLogger(AbstractConfigDialog.class.getName());
+    protected JComboBox jComboBoxVersionSelection;
+    protected JList jListBlenderFiles;
+    protected JTable jTableProperties;
+    protected JTable jTableAnimations;
+    protected JButton jButtonAddAnimation;
+    protected JButton jButtonRemoveAnimation;
+    protected JCheckBox jCheckBoxUseModelKey;
+    protected JButton jButtonOK;
+    protected JButton jButtonCancel;
+
+    /**
+     * Cionstructor initializes the gui.
+     */
+    public AbstractConfigDialog() {
+        this.init();
+    }
+
+    /**
+     * This method initializes the window.
+     */
+    private void init() {
+        try {//setting the system Look And Feel
+            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+        } catch (ClassNotFoundException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        } catch (InstantiationException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        } catch (IllegalAccessException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        } catch (UnsupportedLookAndFeelException e) {
+            LOGGER.log(Level.SEVERE, e.getMessage(), e);
+        }
+        this.setLayout(new BorderLayout());
+
+        this.add(this.prepareBlenderFilesAndLogLevelPanel(), BorderLayout.WEST);
+        this.add(this.prepareFilePropertiesPanel(), BorderLayout.CENTER);
+        this.add(this.prepareButtonsPanel(), BorderLayout.SOUTH);
+
+        this.pack();
+        this.setLocationRelativeTo(null);
+        this.setVisible(true);
+        this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+    }
+
+    /**
+     * This method prepares a swing panel containing the list of blender files
+     * and log level chooser.
+     * @return prepared swing panel
+     */
+    private JPanel prepareBlenderFilesAndLogLevelPanel() {
+        JPanel jPanelBlenderFilesListAndLogLevel = new JPanel();
+        jPanelBlenderFilesListAndLogLevel.setBorder(new TitledBorder("Blender test files"));
+        jPanelBlenderFilesListAndLogLevel.setLayout(new BorderLayout());
+
+        //blender version selection combo box
+        jComboBoxVersionSelection = new JComboBox(new DefaultComboBoxModel());
+        jComboBoxVersionSelection.setEditable(false);
+        jPanelBlenderFilesListAndLogLevel.add(jComboBoxVersionSelection, BorderLayout.NORTH);
+
+        //blender list files
+        jListBlenderFiles = new JList(new DefaultListModel());
+        jListBlenderFiles.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        JScrollPane listScroller = new JScrollPane(jListBlenderFiles);
+        jPanelBlenderFilesListAndLogLevel.add(listScroller, BorderLayout.CENTER);
+
+        //Log Level list
+        Box box = Box.createVerticalBox();
+        box.add(new Label("Log level:"));
+        ButtonGroup buttonGroup = new ButtonGroup();
+
+        Level[] levels = new Level[]{Level.OFF, Level.SEVERE, Level.WARNING, Level.INFO,
+            Level.CONFIG, Level.FINE, Level.FINER, Level.FINEST, Level.ALL};
+        for (Level level : levels) {
+            JRadioButtonLevel jRadioButtonLevel = new JRadioButtonLevel(level);
+            buttonGroup.add(jRadioButtonLevel);
+            box.add(jRadioButtonLevel);
+        }
+        jPanelBlenderFilesListAndLogLevel.add(box, BorderLayout.SOUTH);
+
+        return jPanelBlenderFilesListAndLogLevel;
+    }
+
+    /**
+     * This method prepares a swing panel containing the file's animations.
+     * @return prepared swing panel
+     */
+    protected JPanel prepareFilePropertiesPanel() {
+        //properties table
+        JPanel jPanelProperties = new JPanel();
+        jPanelProperties.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
+        jPanelProperties.setLayout(new BorderLayout());
+        jPanelProperties.add(new JLabel("Properties"), BorderLayout.NORTH);
+
+        jTableProperties = new JTable();
+        jTableProperties.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
+        jTableProperties.setModel(new BlenderTableModel(new Object[]{"Name", "Value"}));
+        jTableProperties.getColumnModel().getColumn(1).setCellEditor(new BlenderTableCellEditor());
+        JScrollPane jScrollPaneProperties = new JScrollPane(jTableProperties);
+        jTableProperties.setFillsViewportHeight(true);
+
+        jPanelProperties.add(jScrollPaneProperties, BorderLayout.CENTER);
+
+        //animations table
+        JPanel jPanelAnimations = new JPanel();
+        jPanelAnimations.setBorder(new EmptyBorder(new Insets(0, 5, 0, 5)));
+        jPanelAnimations.setLayout(new BorderLayout());
+        jPanelAnimations.add(new JLabel("Animations"), BorderLayout.NORTH);
+
+        jTableAnimations = new JTable();
+        jTableAnimations.setSelectionMode(DefaultListSelectionModel.SINGLE_SELECTION);
+        jTableAnimations.setModel(new DefaultTableModel(new Object[]{"Object", "Name", "Start frame", "Stop frame"}, 0));
+        for (int i = 0; i < jTableAnimations.getColumnModel().getColumnCount(); ++i) {
+            jTableAnimations.getColumnModel().getColumn(i).setCellEditor(new BlenderTableCellEditor());
+        }
+        JScrollPane jScrollPaneAnimations = new JScrollPane(jTableAnimations);
+        jTableAnimations.setFillsViewportHeight(true);
+
+        JPanel jPanelTableButtons = new JPanel();
+        jPanelTableButtons.setLayout(new FlowLayout(FlowLayout.LEFT));
+        jButtonAddAnimation = new JButton("Add animation");
+        jButtonAddAnimation.setEnabled(false);
+        jButtonRemoveAnimation = new JButton("Remove animation");
+        jButtonRemoveAnimation.setEnabled(false);
+        jPanelTableButtons.add(jButtonAddAnimation);
+        jPanelTableButtons.add(jButtonRemoveAnimation);
+
+        jPanelAnimations.add(jScrollPaneAnimations, BorderLayout.CENTER);
+        jPanelAnimations.add(jPanelTableButtons, BorderLayout.SOUTH);
+
+        //model key check-box
+        jCheckBoxUseModelKey = new JCheckBox();
+        jCheckBoxUseModelKey.setText("Use ModelKey to start the test");
+        jCheckBoxUseModelKey.setToolTipText("All BlenderKey settings will remain here, but the application will be "
+                + "started using a model key. So only the path to the file will be given!");
+
+        //building the result panel
+        JPanel jPanelResult = new JPanel();
+        jPanelResult.setBorder(new TitledBorder("Loading properties"));
+        jPanelResult.setLayout(new BorderLayout());
+
+        jPanelResult.add(jPanelProperties, BorderLayout.WEST);
+        jPanelResult.add(jPanelAnimations, BorderLayout.CENTER);
+        jPanelResult.add(jCheckBoxUseModelKey, BorderLayout.SOUTH);
+        return jPanelResult;
+    }
+
+    /**
+     * This method prepares a swing panel containing the buttons.
+     * @return prepared swing panel
+     */
+    protected JPanel prepareButtonsPanel() {
+        JPanel jPanelButtons = new JPanel();
+        jButtonOK = new JButton("OK");
+        jButtonOK.setEnabled(false);
+        jPanelButtons.add(jButtonOK);
+        jButtonCancel = new JButton("Cancel");
+        jPanelButtons.add(jButtonCancel);
+        return jPanelButtons;
+    }
+
+    /**
+     * This class was made only to make the selection of a level radio button easier.
+     * @author Marcin Roguski
+     */
+    protected static class JRadioButtonLevel extends JRadioButton {
+
+        private static final long serialVersionUID = 8874525909060993518L;
+        private static Level selectedLevel;
+        private static Map<Level, JRadioButtonLevel> radioButtons = new HashMap<Level, AbstractConfigDialog.JRadioButtonLevel>();
+        private Level level;
+
+        /**
+         * Constructor. Creates the radio button.
+         * Stores it inside the buttons map.
+         * @param level the level of log info
+         */
+        public JRadioButtonLevel(Level level) {
+            super(level.getName());
+            this.level = level;
+            radioButtons.put(level, this);
+            this.addActionListener(new ActionListener() {
+
+                @Override
+                public void actionPerformed(ActionEvent e) {
+                    JRadioButtonLevel.selectedLevel = JRadioButtonLevel.this.level;
+                }
+            });
+        }
+
+        /**
+         * This method returns the currently selected info level.
+         * @return currently selected info level
+         */
+        public static Level getSelectedLevel() {
+            return selectedLevel;
+        }
+
+        /**
+         * This method sets the current info level.
+         * @param level the current info level
+         */
+        public static synchronized void setSelectedLevel(Level level) {
+            radioButtons.get(level).setSelected(true);
+        }
+    }
+
+    /**
+     * This class is an item that should be stored in the files' list.
+     * @author Marcin Roguski (Kaelthas)
+     */
+    protected static class FileListItem {
+
+        private File file;				//the file to be stored
+
+        /**
+         * Constructore. Stores the given file.
+         * @param file the file to be stored
+         */
+        public FileListItem(File file) {
+            this.file = file;
+        }
+
+        /**
+         * This method returns the stored file.
+         * @return the stored file
+         */
+        public File getFile() {
+            return file;
+        }
+
+        @Override
+        public String toString() {
+            return file.getName();
+        }
+    }
+
+    /**
+     * The model for properties table.
+     * It makes left column ineditable.
+     * @author Marcin Roguski (Kaelthas)
+     */
+    protected static class BlenderTableModel extends DefaultTableModel {
+
+        private static final long serialVersionUID = -4211206550875326553L;
+
+        /**
+         * Constructor only calls super-constuctor.
+         * @param columnNames the names of table columns
+         */
+        public BlenderTableModel(Object[] columnNames) {
+            super(columnNames, 0);
+        }
+
+        @Override
+        public void addRow(Object[] rowData) {
+            for (int i = 0; i < rowData.length; ++i) {
+                if (rowData[i] == null) {
+                    rowData[i] = "";
+                }
+            }
+            super.addRow(rowData);
+        }
+
+        @Override
+        public boolean isCellEditable(int row, int column) {
+            return column > 0;
+        }
+    }
+
+    /**
+     * A cell editor tah improves data input to the table.
+     * @author Marcin Roguski (Kaelthas)
+     */
+    protected static class BlenderTableCellEditor extends AbstractCellEditor implements TableCellEditor {
+
+        private static final long serialVersionUID = -8601975203921608519L;
+        private JCheckBox jCheckBox = new JCheckBox();
+        private JTextField jTextField = new JTextField();
+        private JComboBox jComboBox = new JComboBox();
+        private Object lastValue;
+
+        @Override
+        public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) {
+            this.lastValue = value;
+            if (value instanceof Boolean) {
+                jCheckBox.setSelected(((Boolean) value).booleanValue());
+                return jCheckBox;
+            } else if (value instanceof String || value instanceof Number || value instanceof Character) {
+                jTextField.setText(value.toString());
+                return jTextField;
+            } else if (value instanceof Enum<?>) {
+                DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel) jComboBox.getModel();
+                defaultComboBoxModel.removeAllElements();
+                for (Object object : value.getClass().getEnumConstants()) {
+                    defaultComboBoxModel.addElement(object);
+                }
+                return jComboBox;
+            } else {
+                jTextField.setText(value == null ? "" : value.toString());
+                return jTextField;
+            }
+        }
+
+        @Override
+        public Object getCellEditorValue() {
+            if (lastValue instanceof Boolean) {
+                return Boolean.valueOf(jCheckBox.isSelected());
+            } else if (lastValue instanceof String) {
+                return jTextField.getText();
+            } else if (lastValue instanceof Character) {
+                return Character.valueOf(jTextField.getText().charAt(0));
+            } else if (lastValue instanceof Byte) {
+                return Byte.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Short) {
+                return Short.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Integer) {
+                return Integer.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Long) {
+                return Long.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Float) {
+                return Float.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Double) {
+                return Double.valueOf(jTextField.getText());
+            } else if (lastValue instanceof Enum<?>) {
+                return jComboBox.getSelectedItem();
+            }
+            //TODO: savable objects
+            return null;
+        }
+    }
 }

+ 410 - 396
engine/src/test/jme3test/blender/config/ConfigDialog.java

@@ -41,400 +41,414 @@ import com.jme3.export.binary.BinaryImporter;
  * @author Marcin Roguski (Kaelthas)
  */
 public class ConfigDialog extends AbstractConfigDialog {
-	private static final long serialVersionUID = 2863364888664674247L;
-	private static final Logger LOGGER = Logger.getLogger(ConfigDialog.class.getName());
-	
-	private String baseFolderName;
-	private File configFile;								//the config file
-	private Map<String, BlenderKeyConfiguration> configMap;	//the blender key configuration map
-	private BlenderKeyConfiguration blenderKeyConfiguration;//the configuration for the files
-	private IConfigExecutable		configExecutable;		//this is called after clicking the 'OK' button
-	
-	/**
-	 * Constructor. Builds the whole window and stores its data.
-	 * @param testAssetsFolderName the path to test files folder
-	 */
-	public ConfigDialog(String baseFolderName, IConfigExecutable configExecutable) {
-		if(baseFolderName==null) {
-			throw new IllegalArgumentException("No test asset folder given!");
-		}
-		if(configExecutable==null) {
-			throw new IllegalArgumentException("No config executable given!");
-		}
-		this.baseFolderName = baseFolderName;
-		this.configExecutable = configExecutable;
-		this.configMap = new HashMap<String, ConfigDialog.BlenderKeyConfiguration>();
-		
-		//setting up version selection (as a folder list in a compo box)
-		File baseFolder = new File(baseFolderName);
-		if(!baseFolder.exists() || !baseFolder.isDirectory()) {
-			throw new IllegalArgumentException("The given base folder path either does not exists or does not point to a directory!");
-		}
-		File[] folders = baseFolder.listFiles(new FileFilter() {
-			@Override
-			public boolean accept(File file) {
-				return file.isDirectory() && file.getName().charAt(0)!='.';
-			}
-		});
-		for(File folder : folders) {
-			((DefaultComboBoxModel)jComboBoxVersionSelection.getModel()).addElement(folder.getName());
-			configMap.put(folder.getName(), null);
-		}
-		this.initListeners();
-		
-		jComboBoxVersionSelection.setSelectedIndex(0);
-	}
-	
-	/**
-	 * This method returns the selected blender key.
-	 * @return the selected blender key
-	 */
-	public BlenderKey getSelectedBlenderKey() {
-		return blenderKeyConfiguration.lastUsedKey;
-	}
-	
-	/**
-	 * This method prepares the blender files' list.
-	 * @param testAssetsFolderName the path to test files folder
-	 * @return array of blender files
-	 */
-	private File[] prepareFilesList(String testAssetsFolderName) {
-		File testAssetsFolder = new File(testAssetsFolderName);
-		
-		//loading blender files
-		File[] blenderFiles = testAssetsFolder.listFiles(new FileFilter() {
-			@Override
-			public boolean accept(File file) {
-				return file.isFile() && file.canRead() && file.getName().endsWith(".blend");
-			}
-		});
-		
-		//loading the blender files configuration
-		File[] files = testAssetsFolder.listFiles(new FileFilter() {
-			@Override
-			public boolean accept(File file) {
-				return file.isFile() && file.canRead() && file.getName().endsWith(".conf");
-			}
-		});
-		if (files == null || files.length == 0) {
-			blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length);
-			
-		} else {
-			BinaryImporter jmeImporter = new BinaryImporter();
-			String instructionToUser = files.length==1 ?
-					"No other config file to load! No configuration set!" :
-					"Please choose different config file!";
-			do {
-				if (files.length > 1) {
-					configFile = (File) JOptionPane.showInputDialog(null, "Choose the config file!", "Config file selection",
-							JOptionPane.INFORMATION_MESSAGE, null, files, files[0]);
-				} else {
-					configFile = files[0];
-				}
-				if(configFile==null) {
-					JOptionPane.showMessageDialog(this, "No config file selected!\nEmpty configuration will be created!",
-							  "No configuration selected", JOptionPane.INFORMATION_MESSAGE);
-					blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length);
-				} else {
-					try {
-						Savable loadedData = jmeImporter.load(configFile);
-						if (loadedData instanceof BlenderKeyConfiguration) {
-							blenderKeyConfiguration = (BlenderKeyConfiguration) loadedData;
-						} else {
-							LOGGER.warning("Cannot load data drom the given file!");
-							JOptionPane.showMessageDialog(this, "The data stored in the config file is of invalid type!\n"
-																+ instructionToUser, "Config data error", JOptionPane.ERROR_MESSAGE);
-						}
-					} catch (IOException e) {
-						JOptionPane.showMessageDialog(this, "Unable to load configuration! Reason: " + e.getLocalizedMessage(),
-								  "Loading data error", JOptionPane.ERROR_MESSAGE);
-						LOGGER.severe("Unable to load configuration");
-					} catch (Exception e) {
-						JOptionPane.showMessageDialog(this, "Unable to load configuration!",
-								  "Loading data error", JOptionPane.ERROR_MESSAGE);
-						LOGGER.log(Level.SEVERE, "Unable to load configuration due to unpredicted error!", e);
-					}
-				}
-			} while (blenderKeyConfiguration == null && files.length>1);
-		}
-		configFile = new File(testAssetsFolder, "test.conf");
-		
-		jCheckBoxUseModelKey.setSelected(blenderKeyConfiguration.useModelKey);
-		
-		//enlisting the files in the list
-		DefaultListModel defaultListModel = (DefaultListModel) jListBlenderFiles.getModel();
-		defaultListModel.removeAllElements();
-		for(int i=0; i<blenderFiles.length; ++i) {
-			defaultListModel.addElement(new FileListItem(blenderFiles[i]));
-		}
-		return blenderFiles;
-	}
-
-	/**
-	 * This method fills the properties panel with blender key data.
-	 * @param blenderKey the belnder key data
-	 */
-	private void setBlenderKey(BlenderKey blenderKey) {
-		//setting properties
-		BlenderTableModel propertiesModel = (BlenderTableModel) jTableProperties.getModel();
-		int rowCount = propertiesModel.getRowCount();
-		for(int i=0;i<rowCount;++i) {
-			propertiesModel.removeRow(0);
-		}
-		Field[] fields = blenderKey.getClass().getDeclaredFields();
-		for(Field field : fields) {
-			
-			field.setAccessible(true);
-			if(!"animations".equalsIgnoreCase(field.getName()) && 
-			   (field.getModifiers() & Modifier.STATIC)==0) {
-				try {
-					propertiesModel.addRow(new Object[] {field.getName(), field.get(blenderKey)});
-				} catch (IllegalArgumentException e) {
-					LOGGER.log(Level.SEVERE, e.getMessage(), e);
-				} catch (IllegalAccessException e) {
-					LOGGER.log(Level.SEVERE, e.getMessage(), e);
-				}
-			}
-		}
-		
-		//setting animations
-		DefaultTableModel animationsModel = (DefaultTableModel) jTableAnimations.getModel();
-		rowCount = animationsModel.getRowCount();
-		for(int i=0;i<rowCount;++i) {
-			animationsModel.removeRow(0);
-		}
-		Map<String, Map<String, int[]>> animations = blenderKey.getAnimations();
-		if(animations!=null) {
-			for(Entry<String, Map<String, int[]>> animationEntry : animations.entrySet()) {
-				for(Entry<String, int[]> animDataEntry : animationEntry.getValue().entrySet()) {
-					int[] frames = animDataEntry.getValue();
-					animationsModel.addRow(new Object[] {animationEntry.getKey(), animDataEntry.getKey(),
-														 Integer.valueOf(frames[0]), Integer.valueOf(frames[1])});
-				}
-			}
-		}
-		
-		this.jButtonOK.setEnabled(true);
-		this.jButtonOK.requestFocusInWindow();
-		this.jButtonAddAnimation.setEnabled(true);
-	}
-	
-	/**
-	 * This method stores the current blender config.
-	 * @param configuration the blender config to store
-	 */
-	private void storeConfig(BlenderKeyConfiguration configuration) {
-		if(configuration.lastUsedKey!=null) {//reading animations
-			DefaultTableModel animationsTableModel = (DefaultTableModel)jTableAnimations.getModel();
-			if(configuration.lastUsedKey.getAnimations()!=null) {
-				configuration.lastUsedKey.getAnimations().clear();
-			}
-			int animCounter = 0;
-			for(int i=0;i<animationsTableModel.getRowCount();++i) {
-				String objectName = (String)animationsTableModel.getValueAt(i, 0);
-				String animName = (String)animationsTableModel.getValueAt(i, 1);
-				Number startFrame = (Number)animationsTableModel.getValueAt(i, 2);
-				Number stopFrame = (Number)animationsTableModel.getValueAt(i, 3);
-				if(objectName!=null && animName!=null && startFrame.intValue()<=stopFrame.intValue()) {
-					configuration.lastUsedKey.addAnimation(objectName, animName, startFrame.intValue(), stopFrame.intValue());
-					++animCounter;
-				}
-			}
-			if(animCounter<animationsTableModel.getRowCount()) {
-				JOptionPane.showMessageDialog(ConfigDialog.this, "Some animations had errors!\nThey had not been added!", 
-						"Invalid animations definitions", JOptionPane.WARNING_MESSAGE);
-			}
-		}
-		//getting the key type
-		configuration.useModelKey = jCheckBoxUseModelKey.isSelected();
-		configuration.logLevel = JRadioButtonLevel.getSelectedLevel();
-		
-		//storing the config
-		JmeExporter jmeExporter = new BinaryExporter();
-		try {
-			if(!jmeExporter.save(configuration, configFile)) {
-				JOptionPane.showMessageDialog(ConfigDialog.this, "Unable to save the config data!", "Config save problem", JOptionPane.ERROR_MESSAGE);
-			}
-		} catch (IOException e) {
-			JOptionPane.showMessageDialog(ConfigDialog.this, "Error occured during config saving!\nReason: " + e.getLocalizedMessage(),
-					"Config save problem", JOptionPane.ERROR_MESSAGE);
-		}
-	}
-	
-	/**
-	 * This method initiates components listeners.
-	 */
-	private void initListeners() {
-		//selection of blender version
-		jComboBoxVersionSelection.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				//save the previous congifuration
-				if(blenderKeyConfiguration!=null) {
-					ConfigDialog.this.storeConfig(blenderKeyConfiguration);
-					blenderKeyConfiguration = null;
-				}
-				
-				//load new configuration
-				File[] blenderFiles = ConfigDialog.this.prepareFilesList(baseFolderName+'/'+jComboBoxVersionSelection.getSelectedItem().toString());
-				if(blenderKeyConfiguration.lastUsedKey!=null) {
-					for(int i=0;i<blenderFiles.length; ++i) {
-						if(blenderFiles[i].getPath().equalsIgnoreCase(blenderKeyConfiguration.lastUsedKey.getName())) {
-							jListBlenderFiles.setSelectedIndex(i);
-							break;
-						}
-					}
-				}
-				if(blenderKeyConfiguration.logLevel==null) {
-					blenderKeyConfiguration.logLevel = Level.INFO;
-				}
-				JRadioButtonLevel.setSelectedLevel(blenderKeyConfiguration.logLevel);
-			}
-		});
-		//selection of the file changes the config on the right
-		jListBlenderFiles.addListSelectionListener(new ListSelectionListener() {
-			@Override
-			public void valueChanged(ListSelectionEvent evt) {
-				BlenderKeyConfiguration config = ConfigDialog.this.blenderKeyConfiguration;
-				FileListItem selectedItem = (FileListItem) ConfigDialog.this.jListBlenderFiles.getSelectedValue();
-				if(selectedItem != null) {
-					String fileName = selectedItem.getFile().getName();
-					config.lastUsedKey = config.blenderKeys.get(fileName);
-					if(config.lastUsedKey==null) {
-						config.lastUsedKey = new BlenderKey(selectedItem.getFile().getPath());
-						config.blenderKeys.put(fileName, config.lastUsedKey);
-					}
-					ConfigDialog.this.setBlenderKey(config.lastUsedKey);
-				} else {
-					config.lastUsedKey = null;
-				}
-			}
-		});
-		jTableProperties.getModel().addTableModelListener(new TableModelListener() {
-			@Override
-			public void tableChanged(TableModelEvent evt) {
-				if(evt.getType()==TableModelEvent.UPDATE) {
-					BlenderKeyConfiguration config = ConfigDialog.this.blenderKeyConfiguration;
-					int row = evt.getFirstRow();
-					String name = (String)jTableProperties.getModel().getValueAt(row, 0);
-					Object value = jTableProperties.getModel().getValueAt(row, 1);
-					try {
-						Field field = config.lastUsedKey.getClass().getDeclaredField(name);
-						field.setAccessible(true);
-						field.set(config.lastUsedKey, value);
-					} catch (IllegalArgumentException e) {
-						LOGGER.log(Level.SEVERE, e.getMessage(), e);
-					} catch (SecurityException e) {
-						LOGGER.log(Level.SEVERE, e.getMessage(), e);
-					} catch (IllegalAccessException e) {
-						LOGGER.log(Level.SEVERE, e.getMessage(), e);
-					} catch (NoSuchFieldException e) {
-						LOGGER.log(Level.SEVERE, e.getMessage(), e);
-					}
-				}
-			}
-		});
-		jTableAnimations.getModel().addTableModelListener(new TableModelListener() {
-			@Override
-			public void tableChanged(TableModelEvent evt) {
-				if(evt.getType()==TableModelEvent.INSERT) {
-					jButtonRemoveAnimation.setEnabled(true);
-				} else if(evt.getType()==TableModelEvent.DELETE && jTableAnimations.getModel().getRowCount()==0) {
-					jButtonRemoveAnimation.setEnabled(false);
-				}
-			}
-		});
-		jButtonAddAnimation.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				((DefaultTableModel)jTableAnimations.getModel()).addRow(new Object[] {"", "", Integer.valueOf(-1), Integer.valueOf(-1)});
-			}
-		});
-		jButtonRemoveAnimation.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				int row = jTableAnimations.getSelectedRow();
-				if(row>=0) {
-					((DefaultTableModel)jTableAnimations.getModel()).removeRow(row);
-				}
-			}
-		});
-		
-		//button listeners
-		jButtonOK.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				ConfigDialog.this.storeConfig(blenderKeyConfiguration);
-				//running the test
-				SwingUtilities.invokeLater(new Runnable() {
-					@Override
-					public void run() {
-						configExecutable.execute(ConfigDialog.this.blenderKeyConfiguration.getKeyToUse(),
-												 ConfigDialog.this.blenderKeyConfiguration.logLevel);
-					}
-				});
-				//disposing the config window
-				ConfigDialog.this.dispose();
-			}
-		});
-		jButtonCancel.addActionListener(new ActionListener() {
-			@Override
-			public void actionPerformed(ActionEvent evt) {
-				ConfigDialog.this.dispose();
-			}
-		});
-	}
-	
-	/**
-	 * This class holds the configuration for all the files.
-	 * It can be saved and loaded using jme mechanisms.
-	 * @author Marcin Roguski (Kaelthas)
-	 */
-	public static class BlenderKeyConfiguration implements Savable {
-		private Map<String, BlenderKey> blenderKeys;
-		private BlenderKey	lastUsedKey;
-		private Level		logLevel;
-		private boolean		useModelKey;
-		
-		/**
-		 * Constructor for jme serialization.
-		 */
-		public BlenderKeyConfiguration() {}
-		
-		/**
-		 * Constructor that creates new empty configuration for every blender file.
-		 * @param blenderFilesAmount the amount of blender files
-		 */
-		public BlenderKeyConfiguration(int blenderFilesAmount) {
-			blenderKeys = new HashMap<String, BlenderKey>(blenderFilesAmount);
-		}
-		
-		/**
-		 * This method returns the key that will be used during the test.
-		 * @return the key that will be used during the test
-		 */
-		public ModelKey getKeyToUse() {
-			return useModelKey ? new ModelKey(lastUsedKey.getName()) : lastUsedKey;
-		}
-		
-		@Override
-		public void write(JmeExporter ex) throws IOException {
-			OutputCapsule oc = ex.getCapsule(this);
-			oc.writeStringSavableMap(blenderKeys, "keys", null);
-			oc.write(lastUsedKey, "last-key", null);
-			oc.write(useModelKey, "use-model-key", false);
-			oc.write(logLevel==null ? null : logLevel.getName(), "log-level", Level.INFO.getName());
-		}
-
-		@Override
-		@SuppressWarnings("unchecked")
-		public void read(JmeImporter im) throws IOException {
-			InputCapsule ic = im.getCapsule(this);
-			blenderKeys =  (Map<String, BlenderKey>) ic.readStringSavableMap("keys", null);
-			lastUsedKey = (BlenderKey) ic.readSavable("last-key", null);
-			useModelKey = ic.readBoolean("use-model-key", false);
-			String logLevelName = ic.readString("log-level", Level.INFO.getName());
-			logLevel = logLevelName==null ? Level.INFO : Level.parse(logLevelName);
-		}
-	}
+
+    private static final long serialVersionUID = 2863364888664674247L;
+    private static final Logger LOGGER = Logger.getLogger(ConfigDialog.class.getName());
+    private String baseFolderName;
+    private File configFile;								//the config file
+    private Map<String, BlenderKeyConfiguration> configMap;	//the blender key configuration map
+    private BlenderKeyConfiguration blenderKeyConfiguration;//the configuration for the files
+    private ConfigExecutable configExecutable;		//this is called after clicking the 'OK' button
+
+    /**
+     * Constructor. Builds the whole window and stores its data.
+     * @param testAssetsFolderName the path to test files folder
+     */
+    public ConfigDialog(String baseFolderName, ConfigExecutable configExecutable) {
+        if (baseFolderName == null) {
+            throw new IllegalArgumentException("No test asset folder given!");
+        }
+        if (configExecutable == null) {
+            throw new IllegalArgumentException("No config executable given!");
+        }
+        this.baseFolderName = baseFolderName;
+        this.configExecutable = configExecutable;
+        this.configMap = new HashMap<String, ConfigDialog.BlenderKeyConfiguration>();
+
+        //setting up version selection (as a folder list in a compo box)
+        File baseFolder = new File(baseFolderName);
+        if (!baseFolder.exists() || !baseFolder.isDirectory()) {
+            throw new IllegalArgumentException("The given base folder path either does not exists or does not point to a directory!");
+        }
+        File[] folders = baseFolder.listFiles(new FileFilter() {
+
+            @Override
+            public boolean accept(File file) {
+                return file.isDirectory() && file.getName().charAt(0) != '.';
+            }
+        });
+        for (File folder : folders) {
+            ((DefaultComboBoxModel) jComboBoxVersionSelection.getModel()).addElement(folder.getName());
+            configMap.put(folder.getName(), null);
+        }
+        this.initListeners();
+
+        jComboBoxVersionSelection.setSelectedIndex(0);
+    }
+
+    /**
+     * This method returns the selected blender key.
+     * @return the selected blender key
+     */
+    public BlenderKey getSelectedBlenderKey() {
+        return blenderKeyConfiguration.lastUsedKey;
+    }
+
+    /**
+     * This method prepares the blender files' list.
+     * @param testAssetsFolderName the path to test files folder
+     * @return array of blender files
+     */
+    private File[] prepareFilesList(String testAssetsFolderName) {
+        File testAssetsFolder = new File(testAssetsFolderName);
+
+        //loading blender files
+        File[] blenderFiles = testAssetsFolder.listFiles(new FileFilter() {
+
+            @Override
+            public boolean accept(File file) {
+                return file.isFile() && file.canRead() && file.getName().endsWith(".blend");
+            }
+        });
+
+        //loading the blender files configuration
+        File[] files = testAssetsFolder.listFiles(new FileFilter() {
+
+            @Override
+            public boolean accept(File file) {
+                return file.isFile() && file.canRead() && file.getName().endsWith(".conf");
+            }
+        });
+        if (files == null || files.length == 0) {
+            blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length);
+
+        } else {
+            BinaryImporter jmeImporter = new BinaryImporter();
+            String instructionToUser = files.length == 1
+                    ? "No other config file to load! No configuration set!"
+                    : "Please choose different config file!";
+            do {
+                if (files.length > 1) {
+                    configFile = (File) JOptionPane.showInputDialog(null, "Choose the config file!", "Config file selection",
+                            JOptionPane.INFORMATION_MESSAGE, null, files, files[0]);
+                } else {
+                    configFile = files[0];
+                }
+                if (configFile == null) {
+                    JOptionPane.showMessageDialog(this, "No config file selected!\nEmpty configuration will be created!",
+                            "No configuration selected", JOptionPane.INFORMATION_MESSAGE);
+                    blenderKeyConfiguration = new BlenderKeyConfiguration(blenderFiles.length);
+                } else {
+                    try {
+                        Savable loadedData = jmeImporter.load(configFile);
+                        if (loadedData instanceof BlenderKeyConfiguration) {
+                            blenderKeyConfiguration = (BlenderKeyConfiguration) loadedData;
+                        } else {
+                            LOGGER.warning("Cannot load data drom the given file!");
+                            JOptionPane.showMessageDialog(this, "The data stored in the config file is of invalid type!\n"
+                                    + instructionToUser, "Config data error", JOptionPane.ERROR_MESSAGE);
+                        }
+                    } catch (IOException e) {
+                        JOptionPane.showMessageDialog(this, "Unable to load configuration! Reason: " + e.getLocalizedMessage(),
+                                "Loading data error", JOptionPane.ERROR_MESSAGE);
+                        LOGGER.severe("Unable to load configuration");
+                    } catch (Exception e) {
+                        JOptionPane.showMessageDialog(this, "Unable to load configuration!",
+                                "Loading data error", JOptionPane.ERROR_MESSAGE);
+                        LOGGER.log(Level.SEVERE, "Unable to load configuration due to unpredicted error!", e);
+                    }
+                }
+            } while (blenderKeyConfiguration == null && files.length > 1);
+        }
+        configFile = new File(testAssetsFolder, "test.conf");
+
+        jCheckBoxUseModelKey.setSelected(blenderKeyConfiguration.useModelKey);
+
+        //enlisting the files in the list
+        DefaultListModel defaultListModel = (DefaultListModel) jListBlenderFiles.getModel();
+        defaultListModel.removeAllElements();
+        for (int i = 0; i < blenderFiles.length; ++i) {
+            defaultListModel.addElement(new FileListItem(blenderFiles[i]));
+        }
+        return blenderFiles;
+    }
+
+    /**
+     * This method fills the properties panel with blender key data.
+     * @param blenderKey the belnder key data
+     */
+    private void setBlenderKey(BlenderKey blenderKey) {
+        //setting properties
+        BlenderTableModel propertiesModel = (BlenderTableModel) jTableProperties.getModel();
+        int rowCount = propertiesModel.getRowCount();
+        for (int i = 0; i < rowCount; ++i) {
+            propertiesModel.removeRow(0);
+        }
+        Field[] fields = blenderKey.getClass().getDeclaredFields();
+        for (Field field : fields) {
+
+            field.setAccessible(true);
+            if (!"animations".equalsIgnoreCase(field.getName())
+                    && (field.getModifiers() & Modifier.STATIC) == 0) {
+                try {
+                    propertiesModel.addRow(new Object[]{field.getName(), field.get(blenderKey)});
+                } catch (IllegalArgumentException e) {
+                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                } catch (IllegalAccessException e) {
+                    LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                }
+            }
+        }
+
+        //setting animations
+        DefaultTableModel animationsModel = (DefaultTableModel) jTableAnimations.getModel();
+        rowCount = animationsModel.getRowCount();
+        for (int i = 0; i < rowCount; ++i) {
+            animationsModel.removeRow(0);
+        }
+        Map<String, Map<String, int[]>> animations = blenderKey.getAnimations();
+        if (animations != null) {
+            for (Entry<String, Map<String, int[]>> animationEntry : animations.entrySet()) {
+                for (Entry<String, int[]> animDataEntry : animationEntry.getValue().entrySet()) {
+                    int[] frames = animDataEntry.getValue();
+                    animationsModel.addRow(new Object[]{animationEntry.getKey(), animDataEntry.getKey(),
+                                Integer.valueOf(frames[0]), Integer.valueOf(frames[1])});
+                }
+            }
+        }
+
+        this.jButtonOK.setEnabled(true);
+        this.jButtonOK.requestFocusInWindow();
+        this.jButtonAddAnimation.setEnabled(true);
+    }
+
+    /**
+     * This method stores the current blender config.
+     * @param configuration the blender config to store
+     */
+    private void storeConfig(BlenderKeyConfiguration configuration) {
+        if (configuration.lastUsedKey != null) {//reading animations
+            DefaultTableModel animationsTableModel = (DefaultTableModel) jTableAnimations.getModel();
+            if (configuration.lastUsedKey.getAnimations() != null) {
+                configuration.lastUsedKey.getAnimations().clear();
+            }
+            int animCounter = 0;
+            for (int i = 0; i < animationsTableModel.getRowCount(); ++i) {
+                String objectName = (String) animationsTableModel.getValueAt(i, 0);
+                String animName = (String) animationsTableModel.getValueAt(i, 1);
+                Number startFrame = (Number) animationsTableModel.getValueAt(i, 2);
+                Number stopFrame = (Number) animationsTableModel.getValueAt(i, 3);
+                if (objectName != null && animName != null && startFrame.intValue() <= stopFrame.intValue()) {
+                    configuration.lastUsedKey.addAnimation(objectName, animName, startFrame.intValue(), stopFrame.intValue());
+                    ++animCounter;
+                }
+            }
+            if (animCounter < animationsTableModel.getRowCount()) {
+                JOptionPane.showMessageDialog(ConfigDialog.this, "Some animations had errors!\nThey had not been added!",
+                        "Invalid animations definitions", JOptionPane.WARNING_MESSAGE);
+            }
+        }
+        //getting the key type
+        configuration.useModelKey = jCheckBoxUseModelKey.isSelected();
+        configuration.logLevel = JRadioButtonLevel.getSelectedLevel();
+
+        //storing the config
+        JmeExporter jmeExporter = new BinaryExporter();
+        try {
+            if (!jmeExporter.save(configuration, configFile)) {
+                JOptionPane.showMessageDialog(ConfigDialog.this, "Unable to save the config data!", "Config save problem", JOptionPane.ERROR_MESSAGE);
+            }
+        } catch (IOException e) {
+            JOptionPane.showMessageDialog(ConfigDialog.this, "Error occured during config saving!\nReason: " + e.getLocalizedMessage(),
+                    "Config save problem", JOptionPane.ERROR_MESSAGE);
+        }
+    }
+
+    /**
+     * This method initiates components listeners.
+     */
+    private void initListeners() {
+        //selection of blender version
+        jComboBoxVersionSelection.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent evt) {
+                //save the previous congifuration
+                if (blenderKeyConfiguration != null) {
+                    ConfigDialog.this.storeConfig(blenderKeyConfiguration);
+                    blenderKeyConfiguration = null;
+                }
+
+                //load new configuration
+                File[] blenderFiles = ConfigDialog.this.prepareFilesList(baseFolderName + '/' + jComboBoxVersionSelection.getSelectedItem().toString());
+                if (blenderKeyConfiguration.lastUsedKey != null) {
+                    for (int i = 0; i < blenderFiles.length; ++i) {
+                        if (blenderFiles[i].getPath().equalsIgnoreCase(blenderKeyConfiguration.lastUsedKey.getName())) {
+                            jListBlenderFiles.setSelectedIndex(i);
+                            break;
+                        }
+                    }
+                }
+                if (blenderKeyConfiguration.logLevel == null) {
+                    blenderKeyConfiguration.logLevel = Level.INFO;
+                }
+                JRadioButtonLevel.setSelectedLevel(blenderKeyConfiguration.logLevel);
+            }
+        });
+        //selection of the file changes the config on the right
+        jListBlenderFiles.addListSelectionListener(new ListSelectionListener() {
+
+            @Override
+            public void valueChanged(ListSelectionEvent evt) {
+                BlenderKeyConfiguration config = ConfigDialog.this.blenderKeyConfiguration;
+                FileListItem selectedItem = (FileListItem) ConfigDialog.this.jListBlenderFiles.getSelectedValue();
+                if (selectedItem != null) {
+                    String fileName = selectedItem.getFile().getName();
+                    config.lastUsedKey = config.blenderKeys.get(fileName);
+                    if (config.lastUsedKey == null) {
+                        config.lastUsedKey = new BlenderKey(selectedItem.getFile().getPath());
+                        config.blenderKeys.put(fileName, config.lastUsedKey);
+                    }
+                    ConfigDialog.this.setBlenderKey(config.lastUsedKey);
+                } else {
+                    config.lastUsedKey = null;
+                }
+            }
+        });
+        jTableProperties.getModel().addTableModelListener(new TableModelListener() {
+
+            @Override
+            public void tableChanged(TableModelEvent evt) {
+                if (evt.getType() == TableModelEvent.UPDATE) {
+                    BlenderKeyConfiguration config = ConfigDialog.this.blenderKeyConfiguration;
+                    int row = evt.getFirstRow();
+                    String name = (String) jTableProperties.getModel().getValueAt(row, 0);
+                    Object value = jTableProperties.getModel().getValueAt(row, 1);
+                    try {
+                        Field field = config.lastUsedKey.getClass().getDeclaredField(name);
+                        field.setAccessible(true);
+                        field.set(config.lastUsedKey, value);
+                    } catch (IllegalArgumentException e) {
+                        LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                    } catch (SecurityException e) {
+                        LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                    } catch (IllegalAccessException e) {
+                        LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                    } catch (NoSuchFieldException e) {
+                        LOGGER.log(Level.SEVERE, e.getMessage(), e);
+                    }
+                }
+            }
+        });
+        jTableAnimations.getModel().addTableModelListener(new TableModelListener() {
+
+            @Override
+            public void tableChanged(TableModelEvent evt) {
+                if (evt.getType() == TableModelEvent.INSERT) {
+                    jButtonRemoveAnimation.setEnabled(true);
+                } else if (evt.getType() == TableModelEvent.DELETE && jTableAnimations.getModel().getRowCount() == 0) {
+                    jButtonRemoveAnimation.setEnabled(false);
+                }
+            }
+        });
+        jButtonAddAnimation.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent evt) {
+                ((DefaultTableModel) jTableAnimations.getModel()).addRow(new Object[]{"", "", Integer.valueOf(-1), Integer.valueOf(-1)});
+            }
+        });
+        jButtonRemoveAnimation.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent evt) {
+                int row = jTableAnimations.getSelectedRow();
+                if (row >= 0) {
+                    ((DefaultTableModel) jTableAnimations.getModel()).removeRow(row);
+                }
+            }
+        });
+
+        //button listeners
+        jButtonOK.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent evt) {
+                ConfigDialog.this.storeConfig(blenderKeyConfiguration);
+                //running the test
+                SwingUtilities.invokeLater(new Runnable() {
+
+                    @Override
+                    public void run() {
+                        configExecutable.execute(ConfigDialog.this.blenderKeyConfiguration.getKeyToUse(),
+                                ConfigDialog.this.blenderKeyConfiguration.logLevel);
+                    }
+                });
+                //disposing the config window
+                ConfigDialog.this.dispose();
+            }
+        });
+        jButtonCancel.addActionListener(new ActionListener() {
+
+            @Override
+            public void actionPerformed(ActionEvent evt) {
+                ConfigDialog.this.dispose();
+            }
+        });
+    }
+
+    /**
+     * This class holds the configuration for all the files.
+     * It can be saved and loaded using jme mechanisms.
+     * @author Marcin Roguski (Kaelthas)
+     */
+    public static class BlenderKeyConfiguration implements Savable {
+
+        private Map<String, BlenderKey> blenderKeys;
+        private BlenderKey lastUsedKey;
+        private Level logLevel;
+        private boolean useModelKey;
+
+        /**
+         * Constructor for jme serialization.
+         */
+        public BlenderKeyConfiguration() {
+        }
+
+        /**
+         * Constructor that creates new empty configuration for every blender file.
+         * @param blenderFilesAmount the amount of blender files
+         */
+        public BlenderKeyConfiguration(int blenderFilesAmount) {
+            blenderKeys = new HashMap<String, BlenderKey>(blenderFilesAmount);
+        }
+
+        /**
+         * This method returns the key that will be used during the test.
+         * @return the key that will be used during the test
+         */
+        public ModelKey getKeyToUse() {
+            return useModelKey ? new ModelKey(lastUsedKey.getName()) : lastUsedKey;
+        }
+
+        @Override
+        public void write(JmeExporter ex) throws IOException {
+            OutputCapsule oc = ex.getCapsule(this);
+            oc.writeStringSavableMap(blenderKeys, "keys", null);
+            oc.write(lastUsedKey, "last-key", null);
+            oc.write(useModelKey, "use-model-key", false);
+            oc.write(logLevel == null ? null : logLevel.getName(), "log-level", Level.INFO.getName());
+        }
+
+        @Override
+        @SuppressWarnings("unchecked")
+        public void read(JmeImporter im) throws IOException {
+            InputCapsule ic = im.getCapsule(this);
+            blenderKeys = (Map<String, BlenderKey>) ic.readStringSavableMap("keys", null);
+            lastUsedKey = (BlenderKey) ic.readSavable("last-key", null);
+            useModelKey = ic.readBoolean("use-model-key", false);
+            String logLevelName = ic.readString("log-level", Level.INFO.getName());
+            logLevel = logLevelName == null ? Level.INFO : Level.parse(logLevelName);
+        }
+    }
 }

+ 1 - 1
engine/src/test/jme3test/blender/config/IConfigExecutable.java → engine/src/test/jme3test/blender/config/ConfigExecutable.java

@@ -9,7 +9,7 @@ import com.jme3.asset.ModelKey;
  * itself.
  * @author Marcin Roguski (Kaelthas)
  */
-public interface IConfigExecutable {
+public interface ConfigExecutable {
 	/**
 	 * This method runs the test with the given blender key.
 	 * @param modelKey

+ 928 - 935
engine/src/test/jme3test/blender/config/NoiseConstantsGenerator.java

@@ -7,948 +7,941 @@ import java.io.ObjectOutputStream;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-
 public class NoiseConstantsGenerator {
-	private static final Logger			LOGGER		= Logger.getLogger(NoiseConstantsGenerator.class.getName());
-	private static final String FILE_NAME = "noiseconstants.dat";
-	
-	public static void main(String[] args) {
-		NoiseConstantsGenerator noiseConstantsGenerator = new NoiseConstantsGenerator();
-		noiseConstantsGenerator.setFilePath("./src/com/jme3/scene/plugins/blender/helpers/" + FILE_NAME);
-		noiseConstantsGenerator.execute();
-		LOGGER.info("Noise data generation successfull!");
-	}
-	
-	private String filePath;
 
-	public void execute() {
-		if(filePath==null) {
-			throw new IllegalStateException("The output file path cannot be null!");
-		}
-		
-		FileOutputStream fos = null;
-		try {
-			
-			fos = new FileOutputStream(filePath);
-			ObjectOutputStream oos = new ObjectOutputStream(fos);
-			oos.writeObject(hashpntf);
-			oos.writeObject(hash);
-			oos.writeObject(hashvectf);
-			oos.writeObject(p);
-			oos.writeObject(g);
-			oos.flush();
-		} catch (FileNotFoundException e) {
-			LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
-		} catch (IOException e) {
-			LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
-		} finally {
-			if(fos!=null) {
-				try {
-					fos.close();
-				} catch (IOException e) {
-					LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
-				}
-			}
-		}
-	}
-	
-	public String getFilePath() {
-		return filePath;
-	}
+    private static final Logger LOGGER = Logger.getLogger(NoiseConstantsGenerator.class.getName());
+    private static final String FILE_NAME = "noiseconstants.dat";
 
-	public void setFilePath(String filePath) {
-		this.filePath = filePath;
-	}
-	
-	/*
-	 * Constants to be stored.
-	 */
-	private static float[] hashpntf = new float[] { 0.536902f, 0.020915f,
-			0.501445f, 0.216316f, 0.517036f, 0.822466f, 0.965315f, 0.377313f,
-			0.678764f, 0.744545f, 0.097731f, 0.396357f, 0.247202f, 0.520897f,
-			0.613396f, 0.542124f, 0.146813f, 0.255489f, 0.810868f, 0.638641f,
-			0.980742f, 0.292316f, 0.357948f, 0.114382f, 0.861377f, 0.629634f,
-			0.722530f, 0.714103f, 0.048549f, 0.075668f, 0.564920f, 0.162026f,
-			0.054466f, 0.411738f, 0.156897f, 0.887657f, 0.599368f, 0.074249f,
-			0.170277f, 0.225799f, 0.393154f, 0.301348f, 0.057434f, 0.293849f,
-			0.442745f, 0.150002f, 0.398732f, 0.184582f, 0.915200f, 0.630984f,
-			0.974040f, 0.117228f, 0.795520f, 0.763238f, 0.158982f, 0.616211f,
-			0.250825f, 0.906539f, 0.316874f, 0.676205f, 0.234720f, 0.667673f,
-			0.792225f, 0.273671f, 0.119363f, 0.199131f, 0.856716f, 0.828554f,
-			0.900718f, 0.705960f, 0.635923f, 0.989433f, 0.027261f, 0.283507f,
-			0.113426f, 0.388115f, 0.900176f, 0.637741f, 0.438802f, 0.715490f,
-			0.043692f, 0.202640f, 0.378325f, 0.450325f, 0.471832f, 0.147803f,
-			0.906899f, 0.524178f, 0.784981f, 0.051483f, 0.893369f, 0.596895f,
-			0.275635f, 0.391483f, 0.844673f, 0.103061f, 0.257322f, 0.708390f,
-			0.504091f, 0.199517f, 0.660339f, 0.376071f, 0.038880f, 0.531293f,
-			0.216116f, 0.138672f, 0.907737f, 0.807994f, 0.659582f, 0.915264f,
-			0.449075f, 0.627128f, 0.480173f, 0.380942f, 0.018843f, 0.211808f,
-			0.569701f, 0.082294f, 0.689488f, 0.573060f, 0.593859f, 0.216080f,
-			0.373159f, 0.108117f, 0.595539f, 0.021768f, 0.380297f, 0.948125f,
-			0.377833f, 0.319699f, 0.315249f, 0.972805f, 0.792270f, 0.445396f,
-			0.845323f, 0.372186f, 0.096147f, 0.689405f, 0.423958f, 0.055675f,
-			0.117940f, 0.328456f, 0.605808f, 0.631768f, 0.372170f, 0.213723f,
-			0.032700f, 0.447257f, 0.440661f, 0.728488f, 0.299853f, 0.148599f,
-			0.649212f, 0.498381f, 0.049921f, 0.496112f, 0.607142f, 0.562595f,
-			0.990246f, 0.739659f, 0.108633f, 0.978156f, 0.209814f, 0.258436f,
-			0.876021f, 0.309260f, 0.600673f, 0.713597f, 0.576967f, 0.641402f,
-			0.853930f, 0.029173f, 0.418111f, 0.581593f, 0.008394f, 0.589904f,
-			0.661574f, 0.979326f, 0.275724f, 0.111109f, 0.440472f, 0.120839f,
-			0.521602f, 0.648308f, 0.284575f, 0.204501f, 0.153286f, 0.822444f,
-			0.300786f, 0.303906f, 0.364717f, 0.209038f, 0.916831f, 0.900245f,
-			0.600685f, 0.890002f, 0.581660f, 0.431154f, 0.705569f, 0.551250f,
-			0.417075f, 0.403749f, 0.696652f, 0.292652f, 0.911372f, 0.690922f,
-			0.323718f, 0.036773f, 0.258976f, 0.274265f, 0.225076f, 0.628965f,
-			0.351644f, 0.065158f, 0.080340f, 0.467271f, 0.130643f, 0.385914f,
-			0.919315f, 0.253821f, 0.966163f, 0.017439f, 0.392610f, 0.478792f,
-			0.978185f, 0.072691f, 0.982009f, 0.097987f, 0.731533f, 0.401233f,
-			0.107570f, 0.349587f, 0.479122f, 0.700598f, 0.481751f, 0.788429f,
-			0.706864f, 0.120086f, 0.562691f, 0.981797f, 0.001223f, 0.192120f,
-			0.451543f, 0.173092f, 0.108960f, 0.549594f, 0.587892f, 0.657534f,
-			0.396365f, 0.125153f, 0.666420f, 0.385823f, 0.890916f, 0.436729f,
-			0.128114f, 0.369598f, 0.759096f, 0.044677f, 0.904752f, 0.088052f,
-			0.621148f, 0.005047f, 0.452331f, 0.162032f, 0.494238f, 0.523349f,
-			0.741829f, 0.698450f, 0.452316f, 0.563487f, 0.819776f, 0.492160f,
-			0.004210f, 0.647158f, 0.551475f, 0.362995f, 0.177937f, 0.814722f,
-			0.727729f, 0.867126f, 0.997157f, 0.108149f, 0.085726f, 0.796024f,
-			0.665075f, 0.362462f, 0.323124f, 0.043718f, 0.042357f, 0.315030f,
-			0.328954f, 0.870845f, 0.683186f, 0.467922f, 0.514894f, 0.809971f,
-			0.631979f, 0.176571f, 0.366320f, 0.850621f, 0.505555f, 0.749551f,
-			0.750830f, 0.401714f, 0.481216f, 0.438393f, 0.508832f, 0.867971f,
-			0.654581f, 0.058204f, 0.566454f, 0.084124f, 0.548539f, 0.902690f,
-			0.779571f, 0.562058f, 0.048082f, 0.863109f, 0.079290f, 0.713559f,
-			0.783496f, 0.265266f, 0.672089f, 0.786939f, 0.143048f, 0.086196f,
-			0.876129f, 0.408708f, 0.229312f, 0.629995f, 0.206665f, 0.207308f,
-			0.710079f, 0.341704f, 0.264921f, 0.028748f, 0.629222f, 0.470173f,
-			0.726228f, 0.125243f, 0.328249f, 0.794187f, 0.741340f, 0.489895f,
-			0.189396f, 0.724654f, 0.092841f, 0.039809f, 0.860126f, 0.247701f,
-			0.655331f, 0.964121f, 0.672536f, 0.044522f, 0.690567f, 0.837238f,
-			0.631520f, 0.953734f, 0.352484f, 0.289026f, 0.034152f, 0.852575f,
-			0.098454f, 0.795529f, 0.452181f, 0.826159f, 0.186993f, 0.820725f,
-			0.440328f, 0.922137f, 0.704592f, 0.915437f, 0.738183f, 0.733461f,
-			0.193798f, 0.929213f, 0.161390f, 0.318547f, 0.888751f, 0.430968f,
-			0.740837f, 0.193544f, 0.872253f, 0.563074f, 0.274598f, 0.347805f,
-			0.666176f, 0.449831f, 0.800991f, 0.588727f, 0.052296f, 0.714761f,
-			0.420620f, 0.570325f, 0.057550f, 0.210888f, 0.407312f, 0.662848f,
-			0.924382f, 0.895958f, 0.775198f, 0.688605f, 0.025721f, 0.301913f,
-			0.791408f, 0.500602f, 0.831984f, 0.828509f, 0.642093f, 0.494174f,
-			0.525880f, 0.446365f, 0.440063f, 0.763114f, 0.630358f, 0.223943f,
-			0.333806f, 0.906033f, 0.498306f, 0.241278f, 0.427640f, 0.772683f,
-			0.198082f, 0.225379f, 0.503894f, 0.436599f, 0.016503f, 0.803725f,
-			0.189878f, 0.291095f, 0.499114f, 0.151573f, 0.079031f, 0.904618f,
-			0.708535f, 0.273900f, 0.067419f, 0.317124f, 0.936499f, 0.716511f,
-			0.543845f, 0.939909f, 0.826574f, 0.715090f, 0.154864f, 0.750150f,
-			0.845808f, 0.648108f, 0.556564f, 0.644757f, 0.140873f, 0.799167f,
-			0.632989f, 0.444245f, 0.471978f, 0.435910f, 0.359793f, 0.216241f,
-			0.007633f, 0.337236f, 0.857863f, 0.380247f, 0.092517f, 0.799973f,
-			0.919000f, 0.296798f, 0.096989f, 0.854831f, 0.165369f, 0.568475f,
-			0.216855f, 0.020457f, 0.835511f, 0.538039f, 0.999742f, 0.620226f,
-			0.244053f, 0.060399f, 0.323007f, 0.294874f, 0.988899f, 0.384919f,
-			0.735655f, 0.773428f, 0.549776f, 0.292882f, 0.660611f, 0.593507f,
-			0.621118f, 0.175269f, 0.682119f, 0.794493f, 0.868197f, 0.632150f,
-			0.807823f, 0.509656f, 0.482035f, 0.001780f, 0.259126f, 0.358002f,
-			0.280263f, 0.192985f, 0.290367f, 0.208111f, 0.917633f, 0.114422f,
-			0.925491f, 0.981110f, 0.255570f, 0.974862f, 0.016629f, 0.552599f,
-			0.575741f, 0.612978f, 0.615965f, 0.803615f, 0.772334f, 0.089745f,
-			0.838812f, 0.634542f, 0.113709f, 0.755832f, 0.577589f, 0.667489f,
-			0.529834f, 0.325660f, 0.817597f, 0.316557f, 0.335093f, 0.737363f,
-			0.260951f, 0.737073f, 0.049540f, 0.735541f, 0.988891f, 0.299116f,
-			0.147695f, 0.417271f, 0.940811f, 0.524160f, 0.857968f, 0.176403f,
-			0.244835f, 0.485759f, 0.033353f, 0.280319f, 0.750688f, 0.755809f,
-			0.924208f, 0.095956f, 0.962504f, 0.275584f, 0.173715f, 0.942716f,
-			0.706721f, 0.078464f, 0.576716f, 0.804667f, 0.559249f, 0.900611f,
-			0.646904f, 0.432111f, 0.927885f, 0.383277f, 0.269973f, 0.114244f,
-			0.574867f, 0.150703f, 0.241855f, 0.272871f, 0.199950f, 0.079719f,
-			0.868566f, 0.962833f, 0.789122f, 0.320025f, 0.905554f, 0.234876f,
-			0.991356f, 0.061913f, 0.732911f, 0.785960f, 0.874074f, 0.069035f,
-			0.658632f, 0.309901f, 0.023676f, 0.791603f, 0.764661f, 0.661278f,
-			0.319583f, 0.829650f, 0.117091f, 0.903124f, 0.982098f, 0.161631f,
-			0.193576f, 0.670428f, 0.857390f, 0.003760f, 0.572578f, 0.222162f,
-			0.114551f, 0.420118f, 0.530404f, 0.470682f, 0.525527f, 0.764281f,
-			0.040596f, 0.443275f, 0.501124f, 0.816161f, 0.417467f, 0.332172f,
-			0.447565f, 0.614591f, 0.559246f, 0.805295f, 0.226342f, 0.155065f,
-			0.714630f, 0.160925f, 0.760001f, 0.453456f, 0.093869f, 0.406092f,
-			0.264801f, 0.720370f, 0.743388f, 0.373269f, 0.403098f, 0.911923f,
-			0.897249f, 0.147038f, 0.753037f, 0.516093f, 0.739257f, 0.175018f,
-			0.045768f, 0.735857f, 0.801330f, 0.927708f, 0.240977f, 0.591870f,
-			0.921831f, 0.540733f, 0.149100f, 0.423152f, 0.806876f, 0.397081f,
-			0.061100f, 0.811630f, 0.044899f, 0.460915f, 0.961202f, 0.822098f,
-			0.971524f, 0.867608f, 0.773604f, 0.226616f, 0.686286f, 0.926972f,
-			0.411613f, 0.267873f, 0.081937f, 0.226124f, 0.295664f, 0.374594f,
-			0.533240f, 0.237876f, 0.669629f, 0.599083f, 0.513081f, 0.878719f,
-			0.201577f, 0.721296f, 0.495038f, 0.079760f, 0.965959f, 0.233090f,
-			0.052496f, 0.714748f, 0.887844f, 0.308724f, 0.972885f, 0.723337f,
-			0.453089f, 0.914474f, 0.704063f, 0.823198f, 0.834769f, 0.906561f,
-			0.919600f, 0.100601f, 0.307564f, 0.901977f, 0.468879f, 0.265376f,
-			0.885188f, 0.683875f, 0.868623f, 0.081032f, 0.466835f, 0.199087f,
-			0.663437f, 0.812241f, 0.311337f, 0.821361f, 0.356628f, 0.898054f,
-			0.160781f, 0.222539f, 0.714889f, 0.490287f, 0.984915f, 0.951755f,
-			0.964097f, 0.641795f, 0.815472f, 0.852732f, 0.862074f, 0.051108f,
-			0.440139f, 0.323207f, 0.517171f, 0.562984f, 0.115295f, 0.743103f,
-			0.977914f, 0.337596f, 0.440694f, 0.535879f, 0.959427f, 0.351427f,
-			0.704361f, 0.010826f, 0.131162f, 0.577080f, 0.349572f, 0.774892f,
-			0.425796f, 0.072697f, 0.500001f, 0.267322f, 0.909654f, 0.206176f,
-			0.223987f, 0.937698f, 0.323423f, 0.117501f, 0.490308f, 0.474372f,
-			0.689943f, 0.168671f, 0.719417f, 0.188928f, 0.330464f, 0.265273f,
-			0.446271f, 0.171933f, 0.176133f, 0.474616f, 0.140182f, 0.114246f,
-			0.905043f, 0.713870f, 0.555261f, 0.951333f };
+    public static void main(String[] args) {
+        NoiseConstantsGenerator noiseConstantsGenerator = new NoiseConstantsGenerator();
+        noiseConstantsGenerator.setFilePath("./src/com/jme3/scene/plugins/blender/helpers/" + FILE_NAME);
+        noiseConstantsGenerator.execute();
+        LOGGER.info("Noise data generation successfull!");
+    }
+    private String filePath;
 
-	private static short[] hash = new short[] {// 512
-	0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
-			0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35,
-			0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59,
-			0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2,
-			0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
-			0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B,
-			0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55,
-			0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4,
-			0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1,
-			0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84,
-			0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1,
-			0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9,
-			0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
-			0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F,
-			0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69,
-			0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56,
-			0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
-			0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE,
-			0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D,
-			0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF,
-			0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41,
-			0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF,
-			0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88,
-			0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3,
-			0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
-			0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79,
-			0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4,
-			0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48,
-			0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
-			0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25,
-			0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB,
-			0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C,
-			0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
-			0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7,
-			0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33,
-			0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B,
-			0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
-			0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47,
-			0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE,
-			0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3,
-			0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68,
-			0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70,
-			0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E,
-			0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5,
-			0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
-			0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF,
-			0x75, 0xA4, 0x88, 0xFB, 0x5D };
+    public void execute() {
+        if (filePath == null) {
+            throw new IllegalStateException("The output file path cannot be null!");
+        }
 
-	private static float[] hashvectf = new float[] {// 768
-	0.33783f, 0.715698f, -0.611206f, -0.944031f, -0.326599f, -0.045624f,
-			-0.101074f, -0.416443f, -0.903503f, 0.799286f, 0.49411f,
-			-0.341949f, -0.854645f, 0.518036f, 0.033936f, 0.42514f, -0.437866f,
-			-0.792114f, -0.358948f, 0.597046f, 0.717377f, -0.985413f,
-			0.144714f, 0.089294f, -0.601776f, -0.33728f, -0.723907f,
-			-0.449921f, 0.594513f, 0.666382f, 0.208313f, -0.10791f, 0.972076f,
-			0.575317f, 0.060425f, 0.815643f, 0.293365f, -0.875702f, -0.383453f,
-			0.293762f, 0.465759f, 0.834686f, -0.846008f, -0.233398f, -0.47934f,
-			-0.115814f, 0.143036f, -0.98291f, 0.204681f, -0.949036f,
-			-0.239532f, 0.946716f, -0.263947f, 0.184326f, -0.235596f,
-			0.573822f, 0.784332f, 0.203705f, -0.372253f, -0.905487f, 0.756989f,
-			-0.651031f, 0.055298f, 0.497803f, 0.814697f, -0.297363f, -0.16214f,
-			0.063995f, -0.98468f, -0.329254f, 0.834381f, 0.441925f, 0.703827f,
-			-0.527039f, -0.476227f, 0.956421f, 0.266113f, 0.119781f, 0.480133f,
-			0.482849f, 0.7323f, -0.18631f, 0.961212f, -0.203125f, -0.748474f,
-			-0.656921f, -0.090393f, -0.085052f, -0.165253f, 0.982544f,
-			-0.76947f, 0.628174f, -0.115234f, 0.383148f, 0.537659f, 0.751068f,
-			0.616486f, -0.668488f, -0.415924f, -0.259979f, -0.630005f,
-			0.73175f, 0.570953f, -0.087952f, 0.816223f, -0.458008f, 0.023254f,
-			0.888611f, -0.196167f, 0.976563f, -0.088287f, -0.263885f,
-			-0.69812f, -0.665527f, 0.437134f, -0.892273f, -0.112793f,
-			-0.621674f, -0.230438f, 0.748566f, 0.232422f, 0.900574f,
-			-0.367249f, 0.22229f, -0.796143f, 0.562744f, -0.665497f, -0.73764f,
-			0.11377f, 0.670135f, 0.704803f, 0.232605f, 0.895599f, 0.429749f,
-			-0.114655f, -0.11557f, -0.474243f, 0.872742f, 0.621826f, 0.604004f,
-			-0.498444f, -0.832214f, 0.012756f, 0.55426f, -0.702484f, 0.705994f,
-			-0.089661f, -0.692017f, 0.649292f, 0.315399f, -0.175995f,
-			-0.977997f, 0.111877f, 0.096954f, -0.04953f, 0.994019f, 0.635284f,
-			-0.606689f, -0.477783f, -0.261261f, -0.607422f, -0.750153f,
-			0.983276f, 0.165436f, 0.075958f, -0.29837f, 0.404083f, -0.864655f,
-			-0.638672f, 0.507721f, 0.578156f, 0.388214f, 0.412079f, 0.824249f,
-			0.556183f, -0.208832f, 0.804352f, 0.778442f, 0.562012f, 0.27951f,
-			-0.616577f, 0.781921f, -0.091522f, 0.196289f, 0.051056f, 0.979187f,
-			-0.121216f, 0.207153f, -0.970734f, -0.173401f, -0.384735f,
-			0.906555f, 0.161499f, -0.723236f, -0.671387f, 0.178497f,
-			-0.006226f, -0.983887f, -0.126038f, 0.15799f, 0.97934f, 0.830475f,
-			-0.024811f, 0.556458f, -0.510132f, -0.76944f, 0.384247f, 0.81424f,
-			0.200104f, -0.544891f, -0.112549f, -0.393311f, -0.912445f,
-			0.56189f, 0.152222f, -0.813049f, 0.198914f, -0.254517f, -0.946381f,
-			-0.41217f, 0.690979f, -0.593811f, -0.407257f, 0.324524f, 0.853668f,
-			-0.690186f, 0.366119f, -0.624115f, -0.428345f, 0.844147f,
-			-0.322296f, -0.21228f, -0.297546f, -0.930756f, -0.273071f,
-			0.516113f, 0.811798f, 0.928314f, 0.371643f, 0.007233f, 0.785828f,
-			-0.479218f, -0.390778f, -0.704895f, 0.058929f, 0.706818f,
-			0.173248f, 0.203583f, 0.963562f, 0.422211f, -0.904297f, -0.062469f,
-			-0.363312f, -0.182465f, 0.913605f, 0.254028f, -0.552307f,
-			-0.793945f, -0.28891f, -0.765747f, -0.574554f, 0.058319f,
-			0.291382f, 0.954803f, 0.946136f, -0.303925f, 0.111267f, -0.078156f,
-			0.443695f, -0.892731f, 0.182098f, 0.89389f, 0.409515f, -0.680298f,
-			-0.213318f, 0.701141f, 0.062469f, 0.848389f, -0.525635f, -0.72879f,
-			-0.641846f, 0.238342f, -0.88089f, 0.427673f, 0.202637f, -0.532501f,
-			-0.21405f, 0.818878f, 0.948975f, -0.305084f, 0.07962f, 0.925446f,
-			0.374664f, 0.055817f, 0.820923f, 0.565491f, 0.079102f, 0.25882f,
-			0.099792f, -0.960724f, -0.294617f, 0.910522f, 0.289978f, 0.137115f,
-			0.320038f, -0.937408f, -0.908386f, 0.345276f, -0.235718f,
-			-0.936218f, 0.138763f, 0.322754f, 0.366577f, 0.925934f, -0.090637f,
-			0.309296f, -0.686829f, -0.657684f, 0.66983f, 0.024445f, 0.742065f,
-			-0.917999f, -0.059113f, -0.392059f, 0.365509f, 0.462158f,
-			-0.807922f, 0.083374f, 0.996399f, -0.014801f, 0.593842f, 0.253143f,
-			-0.763672f, 0.974976f, -0.165466f, 0.148285f, 0.918976f, 0.137299f,
-			0.369537f, 0.294952f, 0.694977f, 0.655731f, 0.943085f, 0.152618f,
-			-0.295319f, 0.58783f, -0.598236f, 0.544495f, 0.203796f, 0.678223f,
-			0.705994f, -0.478821f, -0.661011f, 0.577667f, 0.719055f, -0.1698f,
-			-0.673828f, -0.132172f, -0.965332f, 0.225006f, -0.981873f,
-			-0.14502f, 0.121979f, 0.763458f, 0.579742f, 0.284546f, -0.893188f,
-			0.079681f, 0.442474f, -0.795776f, -0.523804f, 0.303802f, 0.734955f,
-			0.67804f, -0.007446f, 0.15506f, 0.986267f, -0.056183f, 0.258026f,
-			0.571503f, -0.778931f, -0.681549f, -0.702087f, -0.206116f,
-			-0.96286f, -0.177185f, 0.203613f, -0.470978f, -0.515106f,
-			0.716095f, -0.740326f, 0.57135f, 0.354095f, -0.56012f, -0.824982f,
-			-0.074982f, -0.507874f, 0.753204f, 0.417969f, -0.503113f,
-			0.038147f, 0.863342f, 0.594025f, 0.673553f, -0.439758f, -0.119873f,
-			-0.005524f, -0.992737f, 0.098267f, -0.213776f, 0.971893f,
-			-0.615631f, 0.643951f, 0.454163f, 0.896851f, -0.441071f, 0.032166f,
-			-0.555023f, 0.750763f, -0.358093f, 0.398773f, 0.304688f, 0.864929f,
-			-0.722961f, 0.303589f, 0.620544f, -0.63559f, -0.621948f,
-			-0.457306f, -0.293243f, 0.072327f, 0.953278f, -0.491638f,
-			0.661041f, -0.566772f, -0.304199f, -0.572083f, -0.761688f,
-			0.908081f, -0.398956f, 0.127014f, -0.523621f, -0.549683f,
-			-0.650848f, -0.932922f, -0.19986f, 0.299408f, 0.099426f, 0.140869f,
-			0.984985f, -0.020325f, -0.999756f, -0.002319f, 0.952667f,
-			0.280853f, -0.11615f, -0.971893f, 0.082581f, 0.220337f, 0.65921f,
-			0.705292f, -0.260651f, 0.733063f, -0.175537f, 0.657043f,
-			-0.555206f, 0.429504f, -0.712189f, 0.400421f, -0.89859f, 0.179352f,
-			0.750885f, -0.19696f, 0.630341f, 0.785675f, -0.569336f, 0.241821f,
-			-0.058899f, -0.464111f, 0.883789f, 0.129608f, -0.94519f, 0.299622f,
-			-0.357819f, 0.907654f, 0.219238f, -0.842133f, -0.439117f,
-			-0.312927f, -0.313477f, 0.84433f, 0.434479f, -0.241211f, 0.053253f,
-			0.968994f, 0.063873f, 0.823273f, 0.563965f, 0.476288f, 0.862152f,
-			-0.172516f, 0.620941f, -0.298126f, 0.724915f, 0.25238f, -0.749359f,
-			-0.612122f, -0.577545f, 0.386566f, 0.718994f, -0.406342f,
-			-0.737976f, 0.538696f, 0.04718f, 0.556305f, 0.82959f, -0.802856f,
-			0.587463f, 0.101166f, -0.707733f, -0.705963f, 0.026428f, 0.374908f,
-			0.68457f, 0.625092f, 0.472137f, 0.208405f, -0.856506f, -0.703064f,
-			-0.581085f, -0.409821f, -0.417206f, -0.736328f, 0.532623f,
-			-0.447876f, -0.20285f, -0.870728f, 0.086945f, -0.990417f,
-			0.107086f, 0.183685f, 0.018341f, -0.982788f, 0.560638f, -0.428864f,
-			0.708282f, 0.296722f, -0.952576f, -0.0672f, 0.135773f, 0.990265f,
-			0.030243f, -0.068787f, 0.654724f, 0.752686f, 0.762604f, -0.551758f,
-			0.337585f, -0.819611f, -0.407684f, 0.402466f, -0.727844f,
-			-0.55072f, -0.408539f, -0.855774f, -0.480011f, 0.19281f, 0.693176f,
-			-0.079285f, 0.716339f, 0.226013f, 0.650116f, -0.725433f, 0.246704f,
-			0.953369f, -0.173553f, -0.970398f, -0.239227f, -0.03244f,
-			0.136383f, -0.394318f, 0.908752f, 0.813232f, 0.558167f, 0.164368f,
-			0.40451f, 0.549042f, -0.731323f, -0.380249f, -0.566711f, 0.730865f,
-			0.022156f, 0.932739f, 0.359741f, 0.00824f, 0.996552f, -0.082306f,
-			0.956635f, -0.065338f, -0.283722f, -0.743561f, 0.008209f,
-			0.668579f, -0.859589f, -0.509674f, 0.035767f, -0.852234f,
-			0.363678f, -0.375977f, -0.201965f, -0.970795f, -0.12915f,
-			0.313477f, 0.947327f, 0.06546f, -0.254028f, -0.528259f, 0.81015f,
-			0.628052f, 0.601105f, 0.49411f, -0.494385f, 0.868378f, 0.037933f,
-			0.275635f, -0.086426f, 0.957336f, -0.197937f, 0.468903f,
-			-0.860748f, 0.895599f, 0.399384f, 0.195801f, 0.560791f, 0.825012f,
-			-0.069214f, 0.304199f, -0.849487f, 0.43103f, 0.096375f, 0.93576f,
-			0.339111f, -0.051422f, 0.408966f, -0.911072f, 0.330444f, 0.942841f,
-			-0.042389f, -0.452362f, -0.786407f, 0.420563f, 0.134308f,
-			-0.933472f, -0.332489f, 0.80191f, -0.566711f, -0.188934f,
-			-0.987946f, -0.105988f, 0.112518f, -0.24408f, 0.892242f,
-			-0.379791f, -0.920502f, 0.229095f, -0.316376f, 0.7789f, 0.325958f,
-			0.535706f, -0.912872f, 0.185211f, -0.36377f, -0.184784f, 0.565369f,
-			-0.803833f, -0.018463f, 0.119537f, 0.992615f, -0.259247f,
-			-0.935608f, 0.239532f, -0.82373f, -0.449127f, -0.345947f,
-			-0.433105f, 0.659515f, 0.614349f, -0.822754f, 0.378845f,
-			-0.423676f, 0.687195f, -0.674835f, -0.26889f, -0.246582f,
-			-0.800842f, 0.545715f, -0.729187f, -0.207794f, 0.651978f,
-			0.653534f, -0.610443f, -0.447388f, 0.492584f, -0.023346f,
-			0.869934f, 0.609039f, 0.009094f, -0.79306f, 0.962494f, -0.271088f,
-			-0.00885f, 0.2659f, -0.004913f, 0.963959f, 0.651245f, 0.553619f,
-			-0.518951f, 0.280548f, -0.84314f, 0.458618f, -0.175293f,
-			-0.983215f, 0.049805f, 0.035339f, -0.979919f, 0.196045f,
-			-0.982941f, 0.164307f, -0.082245f, 0.233734f, -0.97226f,
-			-0.005005f, -0.747253f, -0.611328f, 0.260437f, 0.645599f,
-			0.592773f, 0.481384f, 0.117706f, -0.949524f, -0.29068f, -0.535004f,
-			-0.791901f, -0.294312f, -0.627167f, -0.214447f, 0.748718f,
-			-0.047974f, -0.813477f, -0.57959f, -0.175537f, 0.477264f,
-			-0.860992f, 0.738556f, -0.414246f, -0.53183f, 0.562561f,
-			-0.704071f, 0.433289f, -0.754944f, 0.64801f, -0.100586f, 0.114716f,
-			0.044525f, -0.992371f, 0.966003f, 0.244873f, -0.082764f };
+        FileOutputStream fos = null;
+        try {
 
-	/* ********************* FROM PERLIN HIMSELF: ******************** */
+            fos = new FileOutputStream(filePath);
+            ObjectOutputStream oos = new ObjectOutputStream(fos);
+            oos.writeObject(hashpntf);
+            oos.writeObject(hash);
+            oos.writeObject(hashvectf);
+            oos.writeObject(p);
+            oos.writeObject(g);
+            oos.flush();
+        } catch (FileNotFoundException e) {
+            LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+        } catch (IOException e) {
+            LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+        } finally {
+            if (fos != null) {
+                try {
+                    fos.close();
+                } catch (IOException e) {
+                    LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
+                }
+            }
+        }
+    }
 
-	// 512 + 2
-	private static short[] p = new short[] { 0xA2, 0xA0, 0x19, 0x3B, 0xF8,
-			0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
-			0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36,
-			0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63,
-			0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51,
-			0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
-			0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8,
-			0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3,
-			0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB,
-			0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
-			0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78,
-			0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9,
-			0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6,
-			0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71,
-			0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1,
-			0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7,
-			0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37,
-			0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
-			0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2,
-			0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60,
-			0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29,
-			0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
-			0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66,
-			0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0,
-			0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D,
-			0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
-			0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4,
-			0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F,
-			0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80,
-			0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
-			0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74,
-			0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC,
-			0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81,
-			0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
-			0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58,
-			0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94,
-			0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27,
-			0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
-			0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5,
-			0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF,
-			0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9,
-			0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
-			0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99,
-			0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53,
-			0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26,
-			0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA,
-			0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB,
-			0x5D, 0xA2, 0xA0 };
+    public String getFilePath() {
+        return filePath;
+    }
 
-	// [512+2][3]
-	private static float[][] g = new float[][] {
-			{ 0.33783f, 0.715698f, -0.611206f },
-			{ -0.944031f, -0.326599f, -0.045624f },
-			{ -0.101074f, -0.416443f, -0.903503f },
-			{ 0.799286f, 0.49411f, -0.341949f },
-			{ -0.854645f, 0.518036f, 0.033936f },
-			{ 0.42514f, -0.437866f, -0.792114f },
-			{ -0.358948f, 0.597046f, 0.717377f },
-			{ -0.985413f, 0.144714f, 0.089294f },
-			{ -0.601776f, -0.33728f, -0.723907f },
-			{ -0.449921f, 0.594513f, 0.666382f },
-			{ 0.208313f, -0.10791f, 0.972076f },
-			{ 0.575317f, 0.060425f, 0.815643f },
-			{ 0.293365f, -0.875702f, -0.383453f },
-			{ 0.293762f, 0.465759f, 0.834686f },
-			{ -0.846008f, -0.233398f, -0.47934f },
-			{ -0.115814f, 0.143036f, -0.98291f },
-			{ 0.204681f, -0.949036f, -0.239532f },
-			{ 0.946716f, -0.263947f, 0.184326f },
-			{ -0.235596f, 0.573822f, 0.784332f },
-			{ 0.203705f, -0.372253f, -0.905487f },
-			{ 0.756989f, -0.651031f, 0.055298f },
-			{ 0.497803f, 0.814697f, -0.297363f },
-			{ -0.16214f, 0.063995f, -0.98468f },
-			{ -0.329254f, 0.834381f, 0.441925f },
-			{ 0.703827f, -0.527039f, -0.476227f },
-			{ 0.956421f, 0.266113f, 0.119781f },
-			{ 0.480133f, 0.482849f, 0.7323f },
-			{ -0.18631f, 0.961212f, -0.203125f },
-			{ -0.748474f, -0.656921f, -0.090393f },
-			{ -0.085052f, -0.165253f, 0.982544f },
-			{ -0.76947f, 0.628174f, -0.115234f },
-			{ 0.383148f, 0.537659f, 0.751068f },
-			{ 0.616486f, -0.668488f, -0.415924f },
-			{ -0.259979f, -0.630005f, 0.73175f },
-			{ 0.570953f, -0.087952f, 0.816223f },
-			{ -0.458008f, 0.023254f, 0.888611f },
-			{ -0.196167f, 0.976563f, -0.088287f },
-			{ -0.263885f, -0.69812f, -0.665527f },
-			{ 0.437134f, -0.892273f, -0.112793f },
-			{ -0.621674f, -0.230438f, 0.748566f },
-			{ 0.232422f, 0.900574f, -0.367249f },
-			{ 0.22229f, -0.796143f, 0.562744f },
-			{ -0.665497f, -0.73764f, 0.11377f },
-			{ 0.670135f, 0.704803f, 0.232605f },
-			{ 0.895599f, 0.429749f, -0.114655f },
-			{ -0.11557f, -0.474243f, 0.872742f },
-			{ 0.621826f, 0.604004f, -0.498444f },
-			{ -0.832214f, 0.012756f, 0.55426f },
-			{ -0.702484f, 0.705994f, -0.089661f },
-			{ -0.692017f, 0.649292f, 0.315399f },
-			{ -0.175995f, -0.977997f, 0.111877f },
-			{ 0.096954f, -0.04953f, 0.994019f },
-			{ 0.635284f, -0.606689f, -0.477783f },
-			{ -0.261261f, -0.607422f, -0.750153f },
-			{ 0.983276f, 0.165436f, 0.075958f },
-			{ -0.29837f, 0.404083f, -0.864655f },
-			{ -0.638672f, 0.507721f, 0.578156f },
-			{ 0.388214f, 0.412079f, 0.824249f },
-			{ 0.556183f, -0.208832f, 0.804352f },
-			{ 0.778442f, 0.562012f, 0.27951f },
-			{ -0.616577f, 0.781921f, -0.091522f },
-			{ 0.196289f, 0.051056f, 0.979187f },
-			{ -0.121216f, 0.207153f, -0.970734f },
-			{ -0.173401f, -0.384735f, 0.906555f },
-			{ 0.161499f, -0.723236f, -0.671387f },
-			{ 0.178497f, -0.006226f, -0.983887f },
-			{ -0.126038f, 0.15799f, 0.97934f },
-			{ 0.830475f, -0.024811f, 0.556458f },
-			{ -0.510132f, -0.76944f, 0.384247f },
-			{ 0.81424f, 0.200104f, -0.544891f },
-			{ -0.112549f, -0.393311f, -0.912445f },
-			{ 0.56189f, 0.152222f, -0.813049f },
-			{ 0.198914f, -0.254517f, -0.946381f },
-			{ -0.41217f, 0.690979f, -0.593811f },
-			{ -0.407257f, 0.324524f, 0.853668f },
-			{ -0.690186f, 0.366119f, -0.624115f },
-			{ -0.428345f, 0.844147f, -0.322296f },
-			{ -0.21228f, -0.297546f, -0.930756f },
-			{ -0.273071f, 0.516113f, 0.811798f },
-			{ 0.928314f, 0.371643f, 0.007233f },
-			{ 0.785828f, -0.479218f, -0.390778f },
-			{ -0.704895f, 0.058929f, 0.706818f },
-			{ 0.173248f, 0.203583f, 0.963562f },
-			{ 0.422211f, -0.904297f, -0.062469f },
-			{ -0.363312f, -0.182465f, 0.913605f },
-			{ 0.254028f, -0.552307f, -0.793945f },
-			{ -0.28891f, -0.765747f, -0.574554f },
-			{ 0.058319f, 0.291382f, 0.954803f },
-			{ 0.946136f, -0.303925f, 0.111267f },
-			{ -0.078156f, 0.443695f, -0.892731f },
-			{ 0.182098f, 0.89389f, 0.409515f },
-			{ -0.680298f, -0.213318f, 0.701141f },
-			{ 0.062469f, 0.848389f, -0.525635f },
-			{ -0.72879f, -0.641846f, 0.238342f },
-			{ -0.88089f, 0.427673f, 0.202637f },
-			{ -0.532501f, -0.21405f, 0.818878f },
-			{ 0.948975f, -0.305084f, 0.07962f },
-			{ 0.925446f, 0.374664f, 0.055817f },
-			{ 0.820923f, 0.565491f, 0.079102f },
-			{ 0.25882f, 0.099792f, -0.960724f },
-			{ -0.294617f, 0.910522f, 0.289978f },
-			{ 0.137115f, 0.320038f, -0.937408f },
-			{ -0.908386f, 0.345276f, -0.235718f },
-			{ -0.936218f, 0.138763f, 0.322754f },
-			{ 0.366577f, 0.925934f, -0.090637f },
-			{ 0.309296f, -0.686829f, -0.657684f },
-			{ 0.66983f, 0.024445f, 0.742065f },
-			{ -0.917999f, -0.059113f, -0.392059f },
-			{ 0.365509f, 0.462158f, -0.807922f },
-			{ 0.083374f, 0.996399f, -0.014801f },
-			{ 0.593842f, 0.253143f, -0.763672f },
-			{ 0.974976f, -0.165466f, 0.148285f },
-			{ 0.918976f, 0.137299f, 0.369537f },
-			{ 0.294952f, 0.694977f, 0.655731f },
-			{ 0.943085f, 0.152618f, -0.295319f },
-			{ 0.58783f, -0.598236f, 0.544495f },
-			{ 0.203796f, 0.678223f, 0.705994f },
-			{ -0.478821f, -0.661011f, 0.577667f },
-			{ 0.719055f, -0.1698f, -0.673828f },
-			{ -0.132172f, -0.965332f, 0.225006f },
-			{ -0.981873f, -0.14502f, 0.121979f },
-			{ 0.763458f, 0.579742f, 0.284546f },
-			{ -0.893188f, 0.079681f, 0.442474f },
-			{ -0.795776f, -0.523804f, 0.303802f },
-			{ 0.734955f, 0.67804f, -0.007446f },
-			{ 0.15506f, 0.986267f, -0.056183f },
-			{ 0.258026f, 0.571503f, -0.778931f },
-			{ -0.681549f, -0.702087f, -0.206116f },
-			{ -0.96286f, -0.177185f, 0.203613f },
-			{ -0.470978f, -0.515106f, 0.716095f },
-			{ -0.740326f, 0.57135f, 0.354095f },
-			{ -0.56012f, -0.824982f, -0.074982f },
-			{ -0.507874f, 0.753204f, 0.417969f },
-			{ -0.503113f, 0.038147f, 0.863342f },
-			{ 0.594025f, 0.673553f, -0.439758f },
-			{ -0.119873f, -0.005524f, -0.992737f },
-			{ 0.098267f, -0.213776f, 0.971893f },
-			{ -0.615631f, 0.643951f, 0.454163f },
-			{ 0.896851f, -0.441071f, 0.032166f },
-			{ -0.555023f, 0.750763f, -0.358093f },
-			{ 0.398773f, 0.304688f, 0.864929f },
-			{ -0.722961f, 0.303589f, 0.620544f },
-			{ -0.63559f, -0.621948f, -0.457306f },
-			{ -0.293243f, 0.072327f, 0.953278f },
-			{ -0.491638f, 0.661041f, -0.566772f },
-			{ -0.304199f, -0.572083f, -0.761688f },
-			{ 0.908081f, -0.398956f, 0.127014f },
-			{ -0.523621f, -0.549683f, -0.650848f },
-			{ -0.932922f, -0.19986f, 0.299408f },
-			{ 0.099426f, 0.140869f, 0.984985f },
-			{ -0.020325f, -0.999756f, -0.002319f },
-			{ 0.952667f, 0.280853f, -0.11615f },
-			{ -0.971893f, 0.082581f, 0.220337f },
-			{ 0.65921f, 0.705292f, -0.260651f },
-			{ 0.733063f, -0.175537f, 0.657043f },
-			{ -0.555206f, 0.429504f, -0.712189f },
-			{ 0.400421f, -0.89859f, 0.179352f },
-			{ 0.750885f, -0.19696f, 0.630341f },
-			{ 0.785675f, -0.569336f, 0.241821f },
-			{ -0.058899f, -0.464111f, 0.883789f },
-			{ 0.129608f, -0.94519f, 0.299622f },
-			{ -0.357819f, 0.907654f, 0.219238f },
-			{ -0.842133f, -0.439117f, -0.312927f },
-			{ -0.313477f, 0.84433f, 0.434479f },
-			{ -0.241211f, 0.053253f, 0.968994f },
-			{ 0.063873f, 0.823273f, 0.563965f },
-			{ 0.476288f, 0.862152f, -0.172516f },
-			{ 0.620941f, -0.298126f, 0.724915f },
-			{ 0.25238f, -0.749359f, -0.612122f },
-			{ -0.577545f, 0.386566f, 0.718994f },
-			{ -0.406342f, -0.737976f, 0.538696f },
-			{ 0.04718f, 0.556305f, 0.82959f },
-			{ -0.802856f, 0.587463f, 0.101166f },
-			{ -0.707733f, -0.705963f, 0.026428f },
-			{ 0.374908f, 0.68457f, 0.625092f },
-			{ 0.472137f, 0.208405f, -0.856506f },
-			{ -0.703064f, -0.581085f, -0.409821f },
-			{ -0.417206f, -0.736328f, 0.532623f },
-			{ -0.447876f, -0.20285f, -0.870728f },
-			{ 0.086945f, -0.990417f, 0.107086f },
-			{ 0.183685f, 0.018341f, -0.982788f },
-			{ 0.560638f, -0.428864f, 0.708282f },
-			{ 0.296722f, -0.952576f, -0.0672f },
-			{ 0.135773f, 0.990265f, 0.030243f },
-			{ -0.068787f, 0.654724f, 0.752686f },
-			{ 0.762604f, -0.551758f, 0.337585f },
-			{ -0.819611f, -0.407684f, 0.402466f },
-			{ -0.727844f, -0.55072f, -0.408539f },
-			{ -0.855774f, -0.480011f, 0.19281f },
-			{ 0.693176f, -0.079285f, 0.716339f },
-			{ 0.226013f, 0.650116f, -0.725433f },
-			{ 0.246704f, 0.953369f, -0.173553f },
-			{ -0.970398f, -0.239227f, -0.03244f },
-			{ 0.136383f, -0.394318f, 0.908752f },
-			{ 0.813232f, 0.558167f, 0.164368f },
-			{ 0.40451f, 0.549042f, -0.731323f },
-			{ -0.380249f, -0.566711f, 0.730865f },
-			{ 0.022156f, 0.932739f, 0.359741f },
-			{ 0.00824f, 0.996552f, -0.082306f },
-			{ 0.956635f, -0.065338f, -0.283722f },
-			{ -0.743561f, 0.008209f, 0.668579f },
-			{ -0.859589f, -0.509674f, 0.035767f },
-			{ -0.852234f, 0.363678f, -0.375977f },
-			{ -0.201965f, -0.970795f, -0.12915f },
-			{ 0.313477f, 0.947327f, 0.06546f },
-			{ -0.254028f, -0.528259f, 0.81015f },
-			{ 0.628052f, 0.601105f, 0.49411f },
-			{ -0.494385f, 0.868378f, 0.037933f },
-			{ 0.275635f, -0.086426f, 0.957336f },
-			{ -0.197937f, 0.468903f, -0.860748f },
-			{ 0.895599f, 0.399384f, 0.195801f },
-			{ 0.560791f, 0.825012f, -0.069214f },
-			{ 0.304199f, -0.849487f, 0.43103f },
-			{ 0.096375f, 0.93576f, 0.339111f },
-			{ -0.051422f, 0.408966f, -0.911072f },
-			{ 0.330444f, 0.942841f, -0.042389f },
-			{ -0.452362f, -0.786407f, 0.420563f },
-			{ 0.134308f, -0.933472f, -0.332489f },
-			{ 0.80191f, -0.566711f, -0.188934f },
-			{ -0.987946f, -0.105988f, 0.112518f },
-			{ -0.24408f, 0.892242f, -0.379791f },
-			{ -0.920502f, 0.229095f, -0.316376f },
-			{ 0.7789f, 0.325958f, 0.535706f },
-			{ -0.912872f, 0.185211f, -0.36377f },
-			{ -0.184784f, 0.565369f, -0.803833f },
-			{ -0.018463f, 0.119537f, 0.992615f },
-			{ -0.259247f, -0.935608f, 0.239532f },
-			{ -0.82373f, -0.449127f, -0.345947f },
-			{ -0.433105f, 0.659515f, 0.614349f },
-			{ -0.822754f, 0.378845f, -0.423676f },
-			{ 0.687195f, -0.674835f, -0.26889f },
-			{ -0.246582f, -0.800842f, 0.545715f },
-			{ -0.729187f, -0.207794f, 0.651978f },
-			{ 0.653534f, -0.610443f, -0.447388f },
-			{ 0.492584f, -0.023346f, 0.869934f },
-			{ 0.609039f, 0.009094f, -0.79306f },
-			{ 0.962494f, -0.271088f, -0.00885f },
-			{ 0.2659f, -0.004913f, 0.963959f },
-			{ 0.651245f, 0.553619f, -0.518951f },
-			{ 0.280548f, -0.84314f, 0.458618f },
-			{ -0.175293f, -0.983215f, 0.049805f },
-			{ 0.035339f, -0.979919f, 0.196045f },
-			{ -0.982941f, 0.164307f, -0.082245f },
-			{ 0.233734f, -0.97226f, -0.005005f },
-			{ -0.747253f, -0.611328f, 0.260437f },
-			{ 0.645599f, 0.592773f, 0.481384f },
-			{ 0.117706f, -0.949524f, -0.29068f },
-			{ -0.535004f, -0.791901f, -0.294312f },
-			{ -0.627167f, -0.214447f, 0.748718f },
-			{ -0.047974f, -0.813477f, -0.57959f },
-			{ -0.175537f, 0.477264f, -0.860992f },
-			{ 0.738556f, -0.414246f, -0.53183f },
-			{ 0.562561f, -0.704071f, 0.433289f },
-			{ -0.754944f, 0.64801f, -0.100586f },
-			{ 0.114716f, 0.044525f, -0.992371f },
-			{ 0.966003f, 0.244873f, -0.082764f },
-			{ 0.33783f, 0.715698f, -0.611206f },
-			{ -0.944031f, -0.326599f, -0.045624f },
-			{ -0.101074f, -0.416443f, -0.903503f },
-			{ 0.799286f, 0.49411f, -0.341949f },
-			{ -0.854645f, 0.518036f, 0.033936f },
-			{ 0.42514f, -0.437866f, -0.792114f },
-			{ -0.358948f, 0.597046f, 0.717377f },
-			{ -0.985413f, 0.144714f, 0.089294f },
-			{ -0.601776f, -0.33728f, -0.723907f },
-			{ -0.449921f, 0.594513f, 0.666382f },
-			{ 0.208313f, -0.10791f, 0.972076f },
-			{ 0.575317f, 0.060425f, 0.815643f },
-			{ 0.293365f, -0.875702f, -0.383453f },
-			{ 0.293762f, 0.465759f, 0.834686f },
-			{ -0.846008f, -0.233398f, -0.47934f },
-			{ -0.115814f, 0.143036f, -0.98291f },
-			{ 0.204681f, -0.949036f, -0.239532f },
-			{ 0.946716f, -0.263947f, 0.184326f },
-			{ -0.235596f, 0.573822f, 0.784332f },
-			{ 0.203705f, -0.372253f, -0.905487f },
-			{ 0.756989f, -0.651031f, 0.055298f },
-			{ 0.497803f, 0.814697f, -0.297363f },
-			{ -0.16214f, 0.063995f, -0.98468f },
-			{ -0.329254f, 0.834381f, 0.441925f },
-			{ 0.703827f, -0.527039f, -0.476227f },
-			{ 0.956421f, 0.266113f, 0.119781f },
-			{ 0.480133f, 0.482849f, 0.7323f },
-			{ -0.18631f, 0.961212f, -0.203125f },
-			{ -0.748474f, -0.656921f, -0.090393f },
-			{ -0.085052f, -0.165253f, 0.982544f },
-			{ -0.76947f, 0.628174f, -0.115234f },
-			{ 0.383148f, 0.537659f, 0.751068f },
-			{ 0.616486f, -0.668488f, -0.415924f },
-			{ -0.259979f, -0.630005f, 0.73175f },
-			{ 0.570953f, -0.087952f, 0.816223f },
-			{ -0.458008f, 0.023254f, 0.888611f },
-			{ -0.196167f, 0.976563f, -0.088287f },
-			{ -0.263885f, -0.69812f, -0.665527f },
-			{ 0.437134f, -0.892273f, -0.112793f },
-			{ -0.621674f, -0.230438f, 0.748566f },
-			{ 0.232422f, 0.900574f, -0.367249f },
-			{ 0.22229f, -0.796143f, 0.562744f },
-			{ -0.665497f, -0.73764f, 0.11377f },
-			{ 0.670135f, 0.704803f, 0.232605f },
-			{ 0.895599f, 0.429749f, -0.114655f },
-			{ -0.11557f, -0.474243f, 0.872742f },
-			{ 0.621826f, 0.604004f, -0.498444f },
-			{ -0.832214f, 0.012756f, 0.55426f },
-			{ -0.702484f, 0.705994f, -0.089661f },
-			{ -0.692017f, 0.649292f, 0.315399f },
-			{ -0.175995f, -0.977997f, 0.111877f },
-			{ 0.096954f, -0.04953f, 0.994019f },
-			{ 0.635284f, -0.606689f, -0.477783f },
-			{ -0.261261f, -0.607422f, -0.750153f },
-			{ 0.983276f, 0.165436f, 0.075958f },
-			{ -0.29837f, 0.404083f, -0.864655f },
-			{ -0.638672f, 0.507721f, 0.578156f },
-			{ 0.388214f, 0.412079f, 0.824249f },
-			{ 0.556183f, -0.208832f, 0.804352f },
-			{ 0.778442f, 0.562012f, 0.27951f },
-			{ -0.616577f, 0.781921f, -0.091522f },
-			{ 0.196289f, 0.051056f, 0.979187f },
-			{ -0.121216f, 0.207153f, -0.970734f },
-			{ -0.173401f, -0.384735f, 0.906555f },
-			{ 0.161499f, -0.723236f, -0.671387f },
-			{ 0.178497f, -0.006226f, -0.983887f },
-			{ -0.126038f, 0.15799f, 0.97934f },
-			{ 0.830475f, -0.024811f, 0.556458f },
-			{ -0.510132f, -0.76944f, 0.384247f },
-			{ 0.81424f, 0.200104f, -0.544891f },
-			{ -0.112549f, -0.393311f, -0.912445f },
-			{ 0.56189f, 0.152222f, -0.813049f },
-			{ 0.198914f, -0.254517f, -0.946381f },
-			{ -0.41217f, 0.690979f, -0.593811f },
-			{ -0.407257f, 0.324524f, 0.853668f },
-			{ -0.690186f, 0.366119f, -0.624115f },
-			{ -0.428345f, 0.844147f, -0.322296f },
-			{ -0.21228f, -0.297546f, -0.930756f },
-			{ -0.273071f, 0.516113f, 0.811798f },
-			{ 0.928314f, 0.371643f, 0.007233f },
-			{ 0.785828f, -0.479218f, -0.390778f },
-			{ -0.704895f, 0.058929f, 0.706818f },
-			{ 0.173248f, 0.203583f, 0.963562f },
-			{ 0.422211f, -0.904297f, -0.062469f },
-			{ -0.363312f, -0.182465f, 0.913605f },
-			{ 0.254028f, -0.552307f, -0.793945f },
-			{ -0.28891f, -0.765747f, -0.574554f },
-			{ 0.058319f, 0.291382f, 0.954803f },
-			{ 0.946136f, -0.303925f, 0.111267f },
-			{ -0.078156f, 0.443695f, -0.892731f },
-			{ 0.182098f, 0.89389f, 0.409515f },
-			{ -0.680298f, -0.213318f, 0.701141f },
-			{ 0.062469f, 0.848389f, -0.525635f },
-			{ -0.72879f, -0.641846f, 0.238342f },
-			{ -0.88089f, 0.427673f, 0.202637f },
-			{ -0.532501f, -0.21405f, 0.818878f },
-			{ 0.948975f, -0.305084f, 0.07962f },
-			{ 0.925446f, 0.374664f, 0.055817f },
-			{ 0.820923f, 0.565491f, 0.079102f },
-			{ 0.25882f, 0.099792f, -0.960724f },
-			{ -0.294617f, 0.910522f, 0.289978f },
-			{ 0.137115f, 0.320038f, -0.937408f },
-			{ -0.908386f, 0.345276f, -0.235718f },
-			{ -0.936218f, 0.138763f, 0.322754f },
-			{ 0.366577f, 0.925934f, -0.090637f },
-			{ 0.309296f, -0.686829f, -0.657684f },
-			{ 0.66983f, 0.024445f, 0.742065f },
-			{ -0.917999f, -0.059113f, -0.392059f },
-			{ 0.365509f, 0.462158f, -0.807922f },
-			{ 0.083374f, 0.996399f, -0.014801f },
-			{ 0.593842f, 0.253143f, -0.763672f },
-			{ 0.974976f, -0.165466f, 0.148285f },
-			{ 0.918976f, 0.137299f, 0.369537f },
-			{ 0.294952f, 0.694977f, 0.655731f },
-			{ 0.943085f, 0.152618f, -0.295319f },
-			{ 0.58783f, -0.598236f, 0.544495f },
-			{ 0.203796f, 0.678223f, 0.705994f },
-			{ -0.478821f, -0.661011f, 0.577667f },
-			{ 0.719055f, -0.1698f, -0.673828f },
-			{ -0.132172f, -0.965332f, 0.225006f },
-			{ -0.981873f, -0.14502f, 0.121979f },
-			{ 0.763458f, 0.579742f, 0.284546f },
-			{ -0.893188f, 0.079681f, 0.442474f },
-			{ -0.795776f, -0.523804f, 0.303802f },
-			{ 0.734955f, 0.67804f, -0.007446f },
-			{ 0.15506f, 0.986267f, -0.056183f },
-			{ 0.258026f, 0.571503f, -0.778931f },
-			{ -0.681549f, -0.702087f, -0.206116f },
-			{ -0.96286f, -0.177185f, 0.203613f },
-			{ -0.470978f, -0.515106f, 0.716095f },
-			{ -0.740326f, 0.57135f, 0.354095f },
-			{ -0.56012f, -0.824982f, -0.074982f },
-			{ -0.507874f, 0.753204f, 0.417969f },
-			{ -0.503113f, 0.038147f, 0.863342f },
-			{ 0.594025f, 0.673553f, -0.439758f },
-			{ -0.119873f, -0.005524f, -0.992737f },
-			{ 0.098267f, -0.213776f, 0.971893f },
-			{ -0.615631f, 0.643951f, 0.454163f },
-			{ 0.896851f, -0.441071f, 0.032166f },
-			{ -0.555023f, 0.750763f, -0.358093f },
-			{ 0.398773f, 0.304688f, 0.864929f },
-			{ -0.722961f, 0.303589f, 0.620544f },
-			{ -0.63559f, -0.621948f, -0.457306f },
-			{ -0.293243f, 0.072327f, 0.953278f },
-			{ -0.491638f, 0.661041f, -0.566772f },
-			{ -0.304199f, -0.572083f, -0.761688f },
-			{ 0.908081f, -0.398956f, 0.127014f },
-			{ -0.523621f, -0.549683f, -0.650848f },
-			{ -0.932922f, -0.19986f, 0.299408f },
-			{ 0.099426f, 0.140869f, 0.984985f },
-			{ -0.020325f, -0.999756f, -0.002319f },
-			{ 0.952667f, 0.280853f, -0.11615f },
-			{ -0.971893f, 0.082581f, 0.220337f },
-			{ 0.65921f, 0.705292f, -0.260651f },
-			{ 0.733063f, -0.175537f, 0.657043f },
-			{ -0.555206f, 0.429504f, -0.712189f },
-			{ 0.400421f, -0.89859f, 0.179352f },
-			{ 0.750885f, -0.19696f, 0.630341f },
-			{ 0.785675f, -0.569336f, 0.241821f },
-			{ -0.058899f, -0.464111f, 0.883789f },
-			{ 0.129608f, -0.94519f, 0.299622f },
-			{ -0.357819f, 0.907654f, 0.219238f },
-			{ -0.842133f, -0.439117f, -0.312927f },
-			{ -0.313477f, 0.84433f, 0.434479f },
-			{ -0.241211f, 0.053253f, 0.968994f },
-			{ 0.063873f, 0.823273f, 0.563965f },
-			{ 0.476288f, 0.862152f, -0.172516f },
-			{ 0.620941f, -0.298126f, 0.724915f },
-			{ 0.25238f, -0.749359f, -0.612122f },
-			{ -0.577545f, 0.386566f, 0.718994f },
-			{ -0.406342f, -0.737976f, 0.538696f },
-			{ 0.04718f, 0.556305f, 0.82959f },
-			{ -0.802856f, 0.587463f, 0.101166f },
-			{ -0.707733f, -0.705963f, 0.026428f },
-			{ 0.374908f, 0.68457f, 0.625092f },
-			{ 0.472137f, 0.208405f, -0.856506f },
-			{ -0.703064f, -0.581085f, -0.409821f },
-			{ -0.417206f, -0.736328f, 0.532623f },
-			{ -0.447876f, -0.20285f, -0.870728f },
-			{ 0.086945f, -0.990417f, 0.107086f },
-			{ 0.183685f, 0.018341f, -0.982788f },
-			{ 0.560638f, -0.428864f, 0.708282f },
-			{ 0.296722f, -0.952576f, -0.0672f },
-			{ 0.135773f, 0.990265f, 0.030243f },
-			{ -0.068787f, 0.654724f, 0.752686f },
-			{ 0.762604f, -0.551758f, 0.337585f },
-			{ -0.819611f, -0.407684f, 0.402466f },
-			{ -0.727844f, -0.55072f, -0.408539f },
-			{ -0.855774f, -0.480011f, 0.19281f },
-			{ 0.693176f, -0.079285f, 0.716339f },
-			{ 0.226013f, 0.650116f, -0.725433f },
-			{ 0.246704f, 0.953369f, -0.173553f },
-			{ -0.970398f, -0.239227f, -0.03244f },
-			{ 0.136383f, -0.394318f, 0.908752f },
-			{ 0.813232f, 0.558167f, 0.164368f },
-			{ 0.40451f, 0.549042f, -0.731323f },
-			{ -0.380249f, -0.566711f, 0.730865f },
-			{ 0.022156f, 0.932739f, 0.359741f },
-			{ 0.00824f, 0.996552f, -0.082306f },
-			{ 0.956635f, -0.065338f, -0.283722f },
-			{ -0.743561f, 0.008209f, 0.668579f },
-			{ -0.859589f, -0.509674f, 0.035767f },
-			{ -0.852234f, 0.363678f, -0.375977f },
-			{ -0.201965f, -0.970795f, -0.12915f },
-			{ 0.313477f, 0.947327f, 0.06546f },
-			{ -0.254028f, -0.528259f, 0.81015f },
-			{ 0.628052f, 0.601105f, 0.49411f },
-			{ -0.494385f, 0.868378f, 0.037933f },
-			{ 0.275635f, -0.086426f, 0.957336f },
-			{ -0.197937f, 0.468903f, -0.860748f },
-			{ 0.895599f, 0.399384f, 0.195801f },
-			{ 0.560791f, 0.825012f, -0.069214f },
-			{ 0.304199f, -0.849487f, 0.43103f },
-			{ 0.096375f, 0.93576f, 0.339111f },
-			{ -0.051422f, 0.408966f, -0.911072f },
-			{ 0.330444f, 0.942841f, -0.042389f },
-			{ -0.452362f, -0.786407f, 0.420563f },
-			{ 0.134308f, -0.933472f, -0.332489f },
-			{ 0.80191f, -0.566711f, -0.188934f },
-			{ -0.987946f, -0.105988f, 0.112518f },
-			{ -0.24408f, 0.892242f, -0.379791f },
-			{ -0.920502f, 0.229095f, -0.316376f },
-			{ 0.7789f, 0.325958f, 0.535706f },
-			{ -0.912872f, 0.185211f, -0.36377f },
-			{ -0.184784f, 0.565369f, -0.803833f },
-			{ -0.018463f, 0.119537f, 0.992615f },
-			{ -0.259247f, -0.935608f, 0.239532f },
-			{ -0.82373f, -0.449127f, -0.345947f },
-			{ -0.433105f, 0.659515f, 0.614349f },
-			{ -0.822754f, 0.378845f, -0.423676f },
-			{ 0.687195f, -0.674835f, -0.26889f },
-			{ -0.246582f, -0.800842f, 0.545715f },
-			{ -0.729187f, -0.207794f, 0.651978f },
-			{ 0.653534f, -0.610443f, -0.447388f },
-			{ 0.492584f, -0.023346f, 0.869934f },
-			{ 0.609039f, 0.009094f, -0.79306f },
-			{ 0.962494f, -0.271088f, -0.00885f },
-			{ 0.2659f, -0.004913f, 0.963959f },
-			{ 0.651245f, 0.553619f, -0.518951f },
-			{ 0.280548f, -0.84314f, 0.458618f },
-			{ -0.175293f, -0.983215f, 0.049805f },
-			{ 0.035339f, -0.979919f, 0.196045f },
-			{ -0.982941f, 0.164307f, -0.082245f },
-			{ 0.233734f, -0.97226f, -0.005005f },
-			{ -0.747253f, -0.611328f, 0.260437f },
-			{ 0.645599f, 0.592773f, 0.481384f },
-			{ 0.117706f, -0.949524f, -0.29068f },
-			{ -0.535004f, -0.791901f, -0.294312f },
-			{ -0.627167f, -0.214447f, 0.748718f },
-			{ -0.047974f, -0.813477f, -0.57959f },
-			{ -0.175537f, 0.477264f, -0.860992f },
-			{ 0.738556f, -0.414246f, -0.53183f },
-			{ 0.562561f, -0.704071f, 0.433289f },
-			{ -0.754944f, 0.64801f, -0.100586f },
-			{ 0.114716f, 0.044525f, -0.992371f },
-			{ 0.966003f, 0.244873f, -0.082764f },
-			{ 0.33783f, 0.715698f, -0.611206f },
-			{ -0.944031f, -0.326599f, -0.045624f } };
+    public void setFilePath(String filePath) {
+        this.filePath = filePath;
+    }
+    /*
+     * Constants to be stored.
+     */
+    private static float[] hashpntf = new float[]{0.536902f, 0.020915f,
+        0.501445f, 0.216316f, 0.517036f, 0.822466f, 0.965315f, 0.377313f,
+        0.678764f, 0.744545f, 0.097731f, 0.396357f, 0.247202f, 0.520897f,
+        0.613396f, 0.542124f, 0.146813f, 0.255489f, 0.810868f, 0.638641f,
+        0.980742f, 0.292316f, 0.357948f, 0.114382f, 0.861377f, 0.629634f,
+        0.722530f, 0.714103f, 0.048549f, 0.075668f, 0.564920f, 0.162026f,
+        0.054466f, 0.411738f, 0.156897f, 0.887657f, 0.599368f, 0.074249f,
+        0.170277f, 0.225799f, 0.393154f, 0.301348f, 0.057434f, 0.293849f,
+        0.442745f, 0.150002f, 0.398732f, 0.184582f, 0.915200f, 0.630984f,
+        0.974040f, 0.117228f, 0.795520f, 0.763238f, 0.158982f, 0.616211f,
+        0.250825f, 0.906539f, 0.316874f, 0.676205f, 0.234720f, 0.667673f,
+        0.792225f, 0.273671f, 0.119363f, 0.199131f, 0.856716f, 0.828554f,
+        0.900718f, 0.705960f, 0.635923f, 0.989433f, 0.027261f, 0.283507f,
+        0.113426f, 0.388115f, 0.900176f, 0.637741f, 0.438802f, 0.715490f,
+        0.043692f, 0.202640f, 0.378325f, 0.450325f, 0.471832f, 0.147803f,
+        0.906899f, 0.524178f, 0.784981f, 0.051483f, 0.893369f, 0.596895f,
+        0.275635f, 0.391483f, 0.844673f, 0.103061f, 0.257322f, 0.708390f,
+        0.504091f, 0.199517f, 0.660339f, 0.376071f, 0.038880f, 0.531293f,
+        0.216116f, 0.138672f, 0.907737f, 0.807994f, 0.659582f, 0.915264f,
+        0.449075f, 0.627128f, 0.480173f, 0.380942f, 0.018843f, 0.211808f,
+        0.569701f, 0.082294f, 0.689488f, 0.573060f, 0.593859f, 0.216080f,
+        0.373159f, 0.108117f, 0.595539f, 0.021768f, 0.380297f, 0.948125f,
+        0.377833f, 0.319699f, 0.315249f, 0.972805f, 0.792270f, 0.445396f,
+        0.845323f, 0.372186f, 0.096147f, 0.689405f, 0.423958f, 0.055675f,
+        0.117940f, 0.328456f, 0.605808f, 0.631768f, 0.372170f, 0.213723f,
+        0.032700f, 0.447257f, 0.440661f, 0.728488f, 0.299853f, 0.148599f,
+        0.649212f, 0.498381f, 0.049921f, 0.496112f, 0.607142f, 0.562595f,
+        0.990246f, 0.739659f, 0.108633f, 0.978156f, 0.209814f, 0.258436f,
+        0.876021f, 0.309260f, 0.600673f, 0.713597f, 0.576967f, 0.641402f,
+        0.853930f, 0.029173f, 0.418111f, 0.581593f, 0.008394f, 0.589904f,
+        0.661574f, 0.979326f, 0.275724f, 0.111109f, 0.440472f, 0.120839f,
+        0.521602f, 0.648308f, 0.284575f, 0.204501f, 0.153286f, 0.822444f,
+        0.300786f, 0.303906f, 0.364717f, 0.209038f, 0.916831f, 0.900245f,
+        0.600685f, 0.890002f, 0.581660f, 0.431154f, 0.705569f, 0.551250f,
+        0.417075f, 0.403749f, 0.696652f, 0.292652f, 0.911372f, 0.690922f,
+        0.323718f, 0.036773f, 0.258976f, 0.274265f, 0.225076f, 0.628965f,
+        0.351644f, 0.065158f, 0.080340f, 0.467271f, 0.130643f, 0.385914f,
+        0.919315f, 0.253821f, 0.966163f, 0.017439f, 0.392610f, 0.478792f,
+        0.978185f, 0.072691f, 0.982009f, 0.097987f, 0.731533f, 0.401233f,
+        0.107570f, 0.349587f, 0.479122f, 0.700598f, 0.481751f, 0.788429f,
+        0.706864f, 0.120086f, 0.562691f, 0.981797f, 0.001223f, 0.192120f,
+        0.451543f, 0.173092f, 0.108960f, 0.549594f, 0.587892f, 0.657534f,
+        0.396365f, 0.125153f, 0.666420f, 0.385823f, 0.890916f, 0.436729f,
+        0.128114f, 0.369598f, 0.759096f, 0.044677f, 0.904752f, 0.088052f,
+        0.621148f, 0.005047f, 0.452331f, 0.162032f, 0.494238f, 0.523349f,
+        0.741829f, 0.698450f, 0.452316f, 0.563487f, 0.819776f, 0.492160f,
+        0.004210f, 0.647158f, 0.551475f, 0.362995f, 0.177937f, 0.814722f,
+        0.727729f, 0.867126f, 0.997157f, 0.108149f, 0.085726f, 0.796024f,
+        0.665075f, 0.362462f, 0.323124f, 0.043718f, 0.042357f, 0.315030f,
+        0.328954f, 0.870845f, 0.683186f, 0.467922f, 0.514894f, 0.809971f,
+        0.631979f, 0.176571f, 0.366320f, 0.850621f, 0.505555f, 0.749551f,
+        0.750830f, 0.401714f, 0.481216f, 0.438393f, 0.508832f, 0.867971f,
+        0.654581f, 0.058204f, 0.566454f, 0.084124f, 0.548539f, 0.902690f,
+        0.779571f, 0.562058f, 0.048082f, 0.863109f, 0.079290f, 0.713559f,
+        0.783496f, 0.265266f, 0.672089f, 0.786939f, 0.143048f, 0.086196f,
+        0.876129f, 0.408708f, 0.229312f, 0.629995f, 0.206665f, 0.207308f,
+        0.710079f, 0.341704f, 0.264921f, 0.028748f, 0.629222f, 0.470173f,
+        0.726228f, 0.125243f, 0.328249f, 0.794187f, 0.741340f, 0.489895f,
+        0.189396f, 0.724654f, 0.092841f, 0.039809f, 0.860126f, 0.247701f,
+        0.655331f, 0.964121f, 0.672536f, 0.044522f, 0.690567f, 0.837238f,
+        0.631520f, 0.953734f, 0.352484f, 0.289026f, 0.034152f, 0.852575f,
+        0.098454f, 0.795529f, 0.452181f, 0.826159f, 0.186993f, 0.820725f,
+        0.440328f, 0.922137f, 0.704592f, 0.915437f, 0.738183f, 0.733461f,
+        0.193798f, 0.929213f, 0.161390f, 0.318547f, 0.888751f, 0.430968f,
+        0.740837f, 0.193544f, 0.872253f, 0.563074f, 0.274598f, 0.347805f,
+        0.666176f, 0.449831f, 0.800991f, 0.588727f, 0.052296f, 0.714761f,
+        0.420620f, 0.570325f, 0.057550f, 0.210888f, 0.407312f, 0.662848f,
+        0.924382f, 0.895958f, 0.775198f, 0.688605f, 0.025721f, 0.301913f,
+        0.791408f, 0.500602f, 0.831984f, 0.828509f, 0.642093f, 0.494174f,
+        0.525880f, 0.446365f, 0.440063f, 0.763114f, 0.630358f, 0.223943f,
+        0.333806f, 0.906033f, 0.498306f, 0.241278f, 0.427640f, 0.772683f,
+        0.198082f, 0.225379f, 0.503894f, 0.436599f, 0.016503f, 0.803725f,
+        0.189878f, 0.291095f, 0.499114f, 0.151573f, 0.079031f, 0.904618f,
+        0.708535f, 0.273900f, 0.067419f, 0.317124f, 0.936499f, 0.716511f,
+        0.543845f, 0.939909f, 0.826574f, 0.715090f, 0.154864f, 0.750150f,
+        0.845808f, 0.648108f, 0.556564f, 0.644757f, 0.140873f, 0.799167f,
+        0.632989f, 0.444245f, 0.471978f, 0.435910f, 0.359793f, 0.216241f,
+        0.007633f, 0.337236f, 0.857863f, 0.380247f, 0.092517f, 0.799973f,
+        0.919000f, 0.296798f, 0.096989f, 0.854831f, 0.165369f, 0.568475f,
+        0.216855f, 0.020457f, 0.835511f, 0.538039f, 0.999742f, 0.620226f,
+        0.244053f, 0.060399f, 0.323007f, 0.294874f, 0.988899f, 0.384919f,
+        0.735655f, 0.773428f, 0.549776f, 0.292882f, 0.660611f, 0.593507f,
+        0.621118f, 0.175269f, 0.682119f, 0.794493f, 0.868197f, 0.632150f,
+        0.807823f, 0.509656f, 0.482035f, 0.001780f, 0.259126f, 0.358002f,
+        0.280263f, 0.192985f, 0.290367f, 0.208111f, 0.917633f, 0.114422f,
+        0.925491f, 0.981110f, 0.255570f, 0.974862f, 0.016629f, 0.552599f,
+        0.575741f, 0.612978f, 0.615965f, 0.803615f, 0.772334f, 0.089745f,
+        0.838812f, 0.634542f, 0.113709f, 0.755832f, 0.577589f, 0.667489f,
+        0.529834f, 0.325660f, 0.817597f, 0.316557f, 0.335093f, 0.737363f,
+        0.260951f, 0.737073f, 0.049540f, 0.735541f, 0.988891f, 0.299116f,
+        0.147695f, 0.417271f, 0.940811f, 0.524160f, 0.857968f, 0.176403f,
+        0.244835f, 0.485759f, 0.033353f, 0.280319f, 0.750688f, 0.755809f,
+        0.924208f, 0.095956f, 0.962504f, 0.275584f, 0.173715f, 0.942716f,
+        0.706721f, 0.078464f, 0.576716f, 0.804667f, 0.559249f, 0.900611f,
+        0.646904f, 0.432111f, 0.927885f, 0.383277f, 0.269973f, 0.114244f,
+        0.574867f, 0.150703f, 0.241855f, 0.272871f, 0.199950f, 0.079719f,
+        0.868566f, 0.962833f, 0.789122f, 0.320025f, 0.905554f, 0.234876f,
+        0.991356f, 0.061913f, 0.732911f, 0.785960f, 0.874074f, 0.069035f,
+        0.658632f, 0.309901f, 0.023676f, 0.791603f, 0.764661f, 0.661278f,
+        0.319583f, 0.829650f, 0.117091f, 0.903124f, 0.982098f, 0.161631f,
+        0.193576f, 0.670428f, 0.857390f, 0.003760f, 0.572578f, 0.222162f,
+        0.114551f, 0.420118f, 0.530404f, 0.470682f, 0.525527f, 0.764281f,
+        0.040596f, 0.443275f, 0.501124f, 0.816161f, 0.417467f, 0.332172f,
+        0.447565f, 0.614591f, 0.559246f, 0.805295f, 0.226342f, 0.155065f,
+        0.714630f, 0.160925f, 0.760001f, 0.453456f, 0.093869f, 0.406092f,
+        0.264801f, 0.720370f, 0.743388f, 0.373269f, 0.403098f, 0.911923f,
+        0.897249f, 0.147038f, 0.753037f, 0.516093f, 0.739257f, 0.175018f,
+        0.045768f, 0.735857f, 0.801330f, 0.927708f, 0.240977f, 0.591870f,
+        0.921831f, 0.540733f, 0.149100f, 0.423152f, 0.806876f, 0.397081f,
+        0.061100f, 0.811630f, 0.044899f, 0.460915f, 0.961202f, 0.822098f,
+        0.971524f, 0.867608f, 0.773604f, 0.226616f, 0.686286f, 0.926972f,
+        0.411613f, 0.267873f, 0.081937f, 0.226124f, 0.295664f, 0.374594f,
+        0.533240f, 0.237876f, 0.669629f, 0.599083f, 0.513081f, 0.878719f,
+        0.201577f, 0.721296f, 0.495038f, 0.079760f, 0.965959f, 0.233090f,
+        0.052496f, 0.714748f, 0.887844f, 0.308724f, 0.972885f, 0.723337f,
+        0.453089f, 0.914474f, 0.704063f, 0.823198f, 0.834769f, 0.906561f,
+        0.919600f, 0.100601f, 0.307564f, 0.901977f, 0.468879f, 0.265376f,
+        0.885188f, 0.683875f, 0.868623f, 0.081032f, 0.466835f, 0.199087f,
+        0.663437f, 0.812241f, 0.311337f, 0.821361f, 0.356628f, 0.898054f,
+        0.160781f, 0.222539f, 0.714889f, 0.490287f, 0.984915f, 0.951755f,
+        0.964097f, 0.641795f, 0.815472f, 0.852732f, 0.862074f, 0.051108f,
+        0.440139f, 0.323207f, 0.517171f, 0.562984f, 0.115295f, 0.743103f,
+        0.977914f, 0.337596f, 0.440694f, 0.535879f, 0.959427f, 0.351427f,
+        0.704361f, 0.010826f, 0.131162f, 0.577080f, 0.349572f, 0.774892f,
+        0.425796f, 0.072697f, 0.500001f, 0.267322f, 0.909654f, 0.206176f,
+        0.223987f, 0.937698f, 0.323423f, 0.117501f, 0.490308f, 0.474372f,
+        0.689943f, 0.168671f, 0.719417f, 0.188928f, 0.330464f, 0.265273f,
+        0.446271f, 0.171933f, 0.176133f, 0.474616f, 0.140182f, 0.114246f,
+        0.905043f, 0.713870f, 0.555261f, 0.951333f};
+    private static short[] hash = new short[]{// 512
+        0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28,
+        0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35,
+        0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59,
+        0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2,
+        0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8,
+        0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B,
+        0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55,
+        0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4,
+        0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1,
+        0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84,
+        0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1,
+        0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9,
+        0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30,
+        0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F,
+        0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69,
+        0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56,
+        0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10,
+        0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE,
+        0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D,
+        0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF,
+        0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41,
+        0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF,
+        0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88,
+        0xFB, 0x5D, 0xA2, 0xA0, 0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3,
+        0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F,
+        0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79,
+        0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4,
+        0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48,
+        0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57,
+        0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25,
+        0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB,
+        0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C,
+        0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C,
+        0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7,
+        0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33,
+        0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B,
+        0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F,
+        0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47,
+        0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE,
+        0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3,
+        0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68,
+        0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70,
+        0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E,
+        0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5,
+        0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD,
+        0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF,
+        0x75, 0xA4, 0x88, 0xFB, 0x5D};
+    private static float[] hashvectf = new float[]{// 768
+        0.33783f, 0.715698f, -0.611206f, -0.944031f, -0.326599f, -0.045624f,
+        -0.101074f, -0.416443f, -0.903503f, 0.799286f, 0.49411f,
+        -0.341949f, -0.854645f, 0.518036f, 0.033936f, 0.42514f, -0.437866f,
+        -0.792114f, -0.358948f, 0.597046f, 0.717377f, -0.985413f,
+        0.144714f, 0.089294f, -0.601776f, -0.33728f, -0.723907f,
+        -0.449921f, 0.594513f, 0.666382f, 0.208313f, -0.10791f, 0.972076f,
+        0.575317f, 0.060425f, 0.815643f, 0.293365f, -0.875702f, -0.383453f,
+        0.293762f, 0.465759f, 0.834686f, -0.846008f, -0.233398f, -0.47934f,
+        -0.115814f, 0.143036f, -0.98291f, 0.204681f, -0.949036f,
+        -0.239532f, 0.946716f, -0.263947f, 0.184326f, -0.235596f,
+        0.573822f, 0.784332f, 0.203705f, -0.372253f, -0.905487f, 0.756989f,
+        -0.651031f, 0.055298f, 0.497803f, 0.814697f, -0.297363f, -0.16214f,
+        0.063995f, -0.98468f, -0.329254f, 0.834381f, 0.441925f, 0.703827f,
+        -0.527039f, -0.476227f, 0.956421f, 0.266113f, 0.119781f, 0.480133f,
+        0.482849f, 0.7323f, -0.18631f, 0.961212f, -0.203125f, -0.748474f,
+        -0.656921f, -0.090393f, -0.085052f, -0.165253f, 0.982544f,
+        -0.76947f, 0.628174f, -0.115234f, 0.383148f, 0.537659f, 0.751068f,
+        0.616486f, -0.668488f, -0.415924f, -0.259979f, -0.630005f,
+        0.73175f, 0.570953f, -0.087952f, 0.816223f, -0.458008f, 0.023254f,
+        0.888611f, -0.196167f, 0.976563f, -0.088287f, -0.263885f,
+        -0.69812f, -0.665527f, 0.437134f, -0.892273f, -0.112793f,
+        -0.621674f, -0.230438f, 0.748566f, 0.232422f, 0.900574f,
+        -0.367249f, 0.22229f, -0.796143f, 0.562744f, -0.665497f, -0.73764f,
+        0.11377f, 0.670135f, 0.704803f, 0.232605f, 0.895599f, 0.429749f,
+        -0.114655f, -0.11557f, -0.474243f, 0.872742f, 0.621826f, 0.604004f,
+        -0.498444f, -0.832214f, 0.012756f, 0.55426f, -0.702484f, 0.705994f,
+        -0.089661f, -0.692017f, 0.649292f, 0.315399f, -0.175995f,
+        -0.977997f, 0.111877f, 0.096954f, -0.04953f, 0.994019f, 0.635284f,
+        -0.606689f, -0.477783f, -0.261261f, -0.607422f, -0.750153f,
+        0.983276f, 0.165436f, 0.075958f, -0.29837f, 0.404083f, -0.864655f,
+        -0.638672f, 0.507721f, 0.578156f, 0.388214f, 0.412079f, 0.824249f,
+        0.556183f, -0.208832f, 0.804352f, 0.778442f, 0.562012f, 0.27951f,
+        -0.616577f, 0.781921f, -0.091522f, 0.196289f, 0.051056f, 0.979187f,
+        -0.121216f, 0.207153f, -0.970734f, -0.173401f, -0.384735f,
+        0.906555f, 0.161499f, -0.723236f, -0.671387f, 0.178497f,
+        -0.006226f, -0.983887f, -0.126038f, 0.15799f, 0.97934f, 0.830475f,
+        -0.024811f, 0.556458f, -0.510132f, -0.76944f, 0.384247f, 0.81424f,
+        0.200104f, -0.544891f, -0.112549f, -0.393311f, -0.912445f,
+        0.56189f, 0.152222f, -0.813049f, 0.198914f, -0.254517f, -0.946381f,
+        -0.41217f, 0.690979f, -0.593811f, -0.407257f, 0.324524f, 0.853668f,
+        -0.690186f, 0.366119f, -0.624115f, -0.428345f, 0.844147f,
+        -0.322296f, -0.21228f, -0.297546f, -0.930756f, -0.273071f,
+        0.516113f, 0.811798f, 0.928314f, 0.371643f, 0.007233f, 0.785828f,
+        -0.479218f, -0.390778f, -0.704895f, 0.058929f, 0.706818f,
+        0.173248f, 0.203583f, 0.963562f, 0.422211f, -0.904297f, -0.062469f,
+        -0.363312f, -0.182465f, 0.913605f, 0.254028f, -0.552307f,
+        -0.793945f, -0.28891f, -0.765747f, -0.574554f, 0.058319f,
+        0.291382f, 0.954803f, 0.946136f, -0.303925f, 0.111267f, -0.078156f,
+        0.443695f, -0.892731f, 0.182098f, 0.89389f, 0.409515f, -0.680298f,
+        -0.213318f, 0.701141f, 0.062469f, 0.848389f, -0.525635f, -0.72879f,
+        -0.641846f, 0.238342f, -0.88089f, 0.427673f, 0.202637f, -0.532501f,
+        -0.21405f, 0.818878f, 0.948975f, -0.305084f, 0.07962f, 0.925446f,
+        0.374664f, 0.055817f, 0.820923f, 0.565491f, 0.079102f, 0.25882f,
+        0.099792f, -0.960724f, -0.294617f, 0.910522f, 0.289978f, 0.137115f,
+        0.320038f, -0.937408f, -0.908386f, 0.345276f, -0.235718f,
+        -0.936218f, 0.138763f, 0.322754f, 0.366577f, 0.925934f, -0.090637f,
+        0.309296f, -0.686829f, -0.657684f, 0.66983f, 0.024445f, 0.742065f,
+        -0.917999f, -0.059113f, -0.392059f, 0.365509f, 0.462158f,
+        -0.807922f, 0.083374f, 0.996399f, -0.014801f, 0.593842f, 0.253143f,
+        -0.763672f, 0.974976f, -0.165466f, 0.148285f, 0.918976f, 0.137299f,
+        0.369537f, 0.294952f, 0.694977f, 0.655731f, 0.943085f, 0.152618f,
+        -0.295319f, 0.58783f, -0.598236f, 0.544495f, 0.203796f, 0.678223f,
+        0.705994f, -0.478821f, -0.661011f, 0.577667f, 0.719055f, -0.1698f,
+        -0.673828f, -0.132172f, -0.965332f, 0.225006f, -0.981873f,
+        -0.14502f, 0.121979f, 0.763458f, 0.579742f, 0.284546f, -0.893188f,
+        0.079681f, 0.442474f, -0.795776f, -0.523804f, 0.303802f, 0.734955f,
+        0.67804f, -0.007446f, 0.15506f, 0.986267f, -0.056183f, 0.258026f,
+        0.571503f, -0.778931f, -0.681549f, -0.702087f, -0.206116f,
+        -0.96286f, -0.177185f, 0.203613f, -0.470978f, -0.515106f,
+        0.716095f, -0.740326f, 0.57135f, 0.354095f, -0.56012f, -0.824982f,
+        -0.074982f, -0.507874f, 0.753204f, 0.417969f, -0.503113f,
+        0.038147f, 0.863342f, 0.594025f, 0.673553f, -0.439758f, -0.119873f,
+        -0.005524f, -0.992737f, 0.098267f, -0.213776f, 0.971893f,
+        -0.615631f, 0.643951f, 0.454163f, 0.896851f, -0.441071f, 0.032166f,
+        -0.555023f, 0.750763f, -0.358093f, 0.398773f, 0.304688f, 0.864929f,
+        -0.722961f, 0.303589f, 0.620544f, -0.63559f, -0.621948f,
+        -0.457306f, -0.293243f, 0.072327f, 0.953278f, -0.491638f,
+        0.661041f, -0.566772f, -0.304199f, -0.572083f, -0.761688f,
+        0.908081f, -0.398956f, 0.127014f, -0.523621f, -0.549683f,
+        -0.650848f, -0.932922f, -0.19986f, 0.299408f, 0.099426f, 0.140869f,
+        0.984985f, -0.020325f, -0.999756f, -0.002319f, 0.952667f,
+        0.280853f, -0.11615f, -0.971893f, 0.082581f, 0.220337f, 0.65921f,
+        0.705292f, -0.260651f, 0.733063f, -0.175537f, 0.657043f,
+        -0.555206f, 0.429504f, -0.712189f, 0.400421f, -0.89859f, 0.179352f,
+        0.750885f, -0.19696f, 0.630341f, 0.785675f, -0.569336f, 0.241821f,
+        -0.058899f, -0.464111f, 0.883789f, 0.129608f, -0.94519f, 0.299622f,
+        -0.357819f, 0.907654f, 0.219238f, -0.842133f, -0.439117f,
+        -0.312927f, -0.313477f, 0.84433f, 0.434479f, -0.241211f, 0.053253f,
+        0.968994f, 0.063873f, 0.823273f, 0.563965f, 0.476288f, 0.862152f,
+        -0.172516f, 0.620941f, -0.298126f, 0.724915f, 0.25238f, -0.749359f,
+        -0.612122f, -0.577545f, 0.386566f, 0.718994f, -0.406342f,
+        -0.737976f, 0.538696f, 0.04718f, 0.556305f, 0.82959f, -0.802856f,
+        0.587463f, 0.101166f, -0.707733f, -0.705963f, 0.026428f, 0.374908f,
+        0.68457f, 0.625092f, 0.472137f, 0.208405f, -0.856506f, -0.703064f,
+        -0.581085f, -0.409821f, -0.417206f, -0.736328f, 0.532623f,
+        -0.447876f, -0.20285f, -0.870728f, 0.086945f, -0.990417f,
+        0.107086f, 0.183685f, 0.018341f, -0.982788f, 0.560638f, -0.428864f,
+        0.708282f, 0.296722f, -0.952576f, -0.0672f, 0.135773f, 0.990265f,
+        0.030243f, -0.068787f, 0.654724f, 0.752686f, 0.762604f, -0.551758f,
+        0.337585f, -0.819611f, -0.407684f, 0.402466f, -0.727844f,
+        -0.55072f, -0.408539f, -0.855774f, -0.480011f, 0.19281f, 0.693176f,
+        -0.079285f, 0.716339f, 0.226013f, 0.650116f, -0.725433f, 0.246704f,
+        0.953369f, -0.173553f, -0.970398f, -0.239227f, -0.03244f,
+        0.136383f, -0.394318f, 0.908752f, 0.813232f, 0.558167f, 0.164368f,
+        0.40451f, 0.549042f, -0.731323f, -0.380249f, -0.566711f, 0.730865f,
+        0.022156f, 0.932739f, 0.359741f, 0.00824f, 0.996552f, -0.082306f,
+        0.956635f, -0.065338f, -0.283722f, -0.743561f, 0.008209f,
+        0.668579f, -0.859589f, -0.509674f, 0.035767f, -0.852234f,
+        0.363678f, -0.375977f, -0.201965f, -0.970795f, -0.12915f,
+        0.313477f, 0.947327f, 0.06546f, -0.254028f, -0.528259f, 0.81015f,
+        0.628052f, 0.601105f, 0.49411f, -0.494385f, 0.868378f, 0.037933f,
+        0.275635f, -0.086426f, 0.957336f, -0.197937f, 0.468903f,
+        -0.860748f, 0.895599f, 0.399384f, 0.195801f, 0.560791f, 0.825012f,
+        -0.069214f, 0.304199f, -0.849487f, 0.43103f, 0.096375f, 0.93576f,
+        0.339111f, -0.051422f, 0.408966f, -0.911072f, 0.330444f, 0.942841f,
+        -0.042389f, -0.452362f, -0.786407f, 0.420563f, 0.134308f,
+        -0.933472f, -0.332489f, 0.80191f, -0.566711f, -0.188934f,
+        -0.987946f, -0.105988f, 0.112518f, -0.24408f, 0.892242f,
+        -0.379791f, -0.920502f, 0.229095f, -0.316376f, 0.7789f, 0.325958f,
+        0.535706f, -0.912872f, 0.185211f, -0.36377f, -0.184784f, 0.565369f,
+        -0.803833f, -0.018463f, 0.119537f, 0.992615f, -0.259247f,
+        -0.935608f, 0.239532f, -0.82373f, -0.449127f, -0.345947f,
+        -0.433105f, 0.659515f, 0.614349f, -0.822754f, 0.378845f,
+        -0.423676f, 0.687195f, -0.674835f, -0.26889f, -0.246582f,
+        -0.800842f, 0.545715f, -0.729187f, -0.207794f, 0.651978f,
+        0.653534f, -0.610443f, -0.447388f, 0.492584f, -0.023346f,
+        0.869934f, 0.609039f, 0.009094f, -0.79306f, 0.962494f, -0.271088f,
+        -0.00885f, 0.2659f, -0.004913f, 0.963959f, 0.651245f, 0.553619f,
+        -0.518951f, 0.280548f, -0.84314f, 0.458618f, -0.175293f,
+        -0.983215f, 0.049805f, 0.035339f, -0.979919f, 0.196045f,
+        -0.982941f, 0.164307f, -0.082245f, 0.233734f, -0.97226f,
+        -0.005005f, -0.747253f, -0.611328f, 0.260437f, 0.645599f,
+        0.592773f, 0.481384f, 0.117706f, -0.949524f, -0.29068f, -0.535004f,
+        -0.791901f, -0.294312f, -0.627167f, -0.214447f, 0.748718f,
+        -0.047974f, -0.813477f, -0.57959f, -0.175537f, 0.477264f,
+        -0.860992f, 0.738556f, -0.414246f, -0.53183f, 0.562561f,
+        -0.704071f, 0.433289f, -0.754944f, 0.64801f, -0.100586f, 0.114716f,
+        0.044525f, -0.992371f, 0.966003f, 0.244873f, -0.082764f};
 
+    /* ********************* FROM PERLIN HIMSELF: ******************** */
+    // 512 + 2
+    private static short[] p = new short[]{0xA2, 0xA0, 0x19, 0x3B, 0xF8,
+        0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D, 0xED, 0x0, 0xDE,
+        0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D, 0x6C, 0xBA, 0x36,
+        0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4, 0x8, 0x8B, 0x63,
+        0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F, 0x18, 0xC7, 0x51,
+        0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80, 0xB5, 0x40, 0x13,
+        0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D, 0x86, 0x4C, 0xC8,
+        0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74, 0x50, 0xCD, 0xB3,
+        0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC, 0xFD, 0x98, 0xB,
+        0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81, 0x61, 0xE1, 0xC4,
+        0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34, 0x38, 0xAB, 0x78,
+        0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58, 0xA9, 0x31, 0xF9,
+        0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94, 0xA3, 0x85, 0x6,
+        0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27, 0x2B, 0x1B, 0x71,
+        0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2, 0xC0, 0xE, 0xB1,
+        0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5, 0xE9, 0xE6, 0xE7,
+        0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF, 0x12, 0xA5, 0x37,
+        0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9, 0xCE, 0xC9, 0x8D,
+        0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4, 0xA, 0xCC, 0xD2,
+        0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99, 0xD8, 0xD, 0x60,
+        0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53, 0x7, 0xE0, 0x29,
+        0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26, 0x6A, 0x16, 0x5E,
+        0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA, 0x54, 0xFA, 0x66,
+        0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB, 0x5D, 0xA2, 0xA0,
+        0x19, 0x3B, 0xF8, 0xEB, 0xAA, 0xEE, 0xF3, 0x1C, 0x67, 0x28, 0x1D,
+        0xED, 0x0, 0xDE, 0x95, 0x2E, 0xDC, 0x3F, 0x3A, 0x82, 0x35, 0x4D,
+        0x6C, 0xBA, 0x36, 0xD0, 0xF6, 0xC, 0x79, 0x32, 0xD1, 0x59, 0xF4,
+        0x8, 0x8B, 0x63, 0x89, 0x2F, 0xB8, 0xB4, 0x97, 0x83, 0xF2, 0x8F,
+        0x18, 0xC7, 0x51, 0x14, 0x65, 0x87, 0x48, 0x20, 0x42, 0xA8, 0x80,
+        0xB5, 0x40, 0x13, 0xB2, 0x22, 0x7E, 0x57, 0xBC, 0x7F, 0x6B, 0x9D,
+        0x86, 0x4C, 0xC8, 0xDB, 0x7C, 0xD5, 0x25, 0x4E, 0x5A, 0x55, 0x74,
+        0x50, 0xCD, 0xB3, 0x7A, 0xBB, 0xC3, 0xCB, 0xB6, 0xE2, 0xE4, 0xEC,
+        0xFD, 0x98, 0xB, 0x96, 0xD3, 0x9E, 0x5C, 0xA1, 0x64, 0xF1, 0x81,
+        0x61, 0xE1, 0xC4, 0x24, 0x72, 0x49, 0x8C, 0x90, 0x4B, 0x84, 0x34,
+        0x38, 0xAB, 0x78, 0xCA, 0x1F, 0x1, 0xD7, 0x93, 0x11, 0xC1, 0x58,
+        0xA9, 0x31, 0xF9, 0x44, 0x6D, 0xBF, 0x33, 0x9C, 0x5F, 0x9, 0x94,
+        0xA3, 0x85, 0x6, 0xC6, 0x9A, 0x1E, 0x7B, 0x46, 0x15, 0x30, 0x27,
+        0x2B, 0x1B, 0x71, 0x3C, 0x5B, 0xD6, 0x6F, 0x62, 0xAC, 0x4F, 0xC2,
+        0xC0, 0xE, 0xB1, 0x23, 0xA7, 0xDF, 0x47, 0xB0, 0x77, 0x69, 0x5,
+        0xE9, 0xE6, 0xE7, 0x76, 0x73, 0xF, 0xFE, 0x6E, 0x9B, 0x56, 0xEF,
+        0x12, 0xA5, 0x37, 0xFC, 0xAE, 0xD9, 0x3, 0x8E, 0xDD, 0x10, 0xB9,
+        0xCE, 0xC9, 0x8D, 0xDA, 0x2A, 0xBD, 0x68, 0x17, 0x9F, 0xBE, 0xD4,
+        0xA, 0xCC, 0xD2, 0xE8, 0x43, 0x3D, 0x70, 0xB7, 0x2, 0x7D, 0x99,
+        0xD8, 0xD, 0x60, 0x8A, 0x4, 0x2C, 0x3E, 0x92, 0xE5, 0xAF, 0x53,
+        0x7, 0xE0, 0x29, 0xA6, 0xC5, 0xE3, 0xF5, 0xF7, 0x4A, 0x41, 0x26,
+        0x6A, 0x16, 0x5E, 0x52, 0x2D, 0x21, 0xAD, 0xF0, 0x91, 0xFF, 0xEA,
+        0x54, 0xFA, 0x66, 0x1A, 0x45, 0x39, 0xCF, 0x75, 0xA4, 0x88, 0xFB,
+        0x5D, 0xA2, 0xA0};
+    // [512+2][3]
+    private static float[][] g = new float[][]{
+        {0.33783f, 0.715698f, -0.611206f},
+        {-0.944031f, -0.326599f, -0.045624f},
+        {-0.101074f, -0.416443f, -0.903503f},
+        {0.799286f, 0.49411f, -0.341949f},
+        {-0.854645f, 0.518036f, 0.033936f},
+        {0.42514f, -0.437866f, -0.792114f},
+        {-0.358948f, 0.597046f, 0.717377f},
+        {-0.985413f, 0.144714f, 0.089294f},
+        {-0.601776f, -0.33728f, -0.723907f},
+        {-0.449921f, 0.594513f, 0.666382f},
+        {0.208313f, -0.10791f, 0.972076f},
+        {0.575317f, 0.060425f, 0.815643f},
+        {0.293365f, -0.875702f, -0.383453f},
+        {0.293762f, 0.465759f, 0.834686f},
+        {-0.846008f, -0.233398f, -0.47934f},
+        {-0.115814f, 0.143036f, -0.98291f},
+        {0.204681f, -0.949036f, -0.239532f},
+        {0.946716f, -0.263947f, 0.184326f},
+        {-0.235596f, 0.573822f, 0.784332f},
+        {0.203705f, -0.372253f, -0.905487f},
+        {0.756989f, -0.651031f, 0.055298f},
+        {0.497803f, 0.814697f, -0.297363f},
+        {-0.16214f, 0.063995f, -0.98468f},
+        {-0.329254f, 0.834381f, 0.441925f},
+        {0.703827f, -0.527039f, -0.476227f},
+        {0.956421f, 0.266113f, 0.119781f},
+        {0.480133f, 0.482849f, 0.7323f},
+        {-0.18631f, 0.961212f, -0.203125f},
+        {-0.748474f, -0.656921f, -0.090393f},
+        {-0.085052f, -0.165253f, 0.982544f},
+        {-0.76947f, 0.628174f, -0.115234f},
+        {0.383148f, 0.537659f, 0.751068f},
+        {0.616486f, -0.668488f, -0.415924f},
+        {-0.259979f, -0.630005f, 0.73175f},
+        {0.570953f, -0.087952f, 0.816223f},
+        {-0.458008f, 0.023254f, 0.888611f},
+        {-0.196167f, 0.976563f, -0.088287f},
+        {-0.263885f, -0.69812f, -0.665527f},
+        {0.437134f, -0.892273f, -0.112793f},
+        {-0.621674f, -0.230438f, 0.748566f},
+        {0.232422f, 0.900574f, -0.367249f},
+        {0.22229f, -0.796143f, 0.562744f},
+        {-0.665497f, -0.73764f, 0.11377f},
+        {0.670135f, 0.704803f, 0.232605f},
+        {0.895599f, 0.429749f, -0.114655f},
+        {-0.11557f, -0.474243f, 0.872742f},
+        {0.621826f, 0.604004f, -0.498444f},
+        {-0.832214f, 0.012756f, 0.55426f},
+        {-0.702484f, 0.705994f, -0.089661f},
+        {-0.692017f, 0.649292f, 0.315399f},
+        {-0.175995f, -0.977997f, 0.111877f},
+        {0.096954f, -0.04953f, 0.994019f},
+        {0.635284f, -0.606689f, -0.477783f},
+        {-0.261261f, -0.607422f, -0.750153f},
+        {0.983276f, 0.165436f, 0.075958f},
+        {-0.29837f, 0.404083f, -0.864655f},
+        {-0.638672f, 0.507721f, 0.578156f},
+        {0.388214f, 0.412079f, 0.824249f},
+        {0.556183f, -0.208832f, 0.804352f},
+        {0.778442f, 0.562012f, 0.27951f},
+        {-0.616577f, 0.781921f, -0.091522f},
+        {0.196289f, 0.051056f, 0.979187f},
+        {-0.121216f, 0.207153f, -0.970734f},
+        {-0.173401f, -0.384735f, 0.906555f},
+        {0.161499f, -0.723236f, -0.671387f},
+        {0.178497f, -0.006226f, -0.983887f},
+        {-0.126038f, 0.15799f, 0.97934f},
+        {0.830475f, -0.024811f, 0.556458f},
+        {-0.510132f, -0.76944f, 0.384247f},
+        {0.81424f, 0.200104f, -0.544891f},
+        {-0.112549f, -0.393311f, -0.912445f},
+        {0.56189f, 0.152222f, -0.813049f},
+        {0.198914f, -0.254517f, -0.946381f},
+        {-0.41217f, 0.690979f, -0.593811f},
+        {-0.407257f, 0.324524f, 0.853668f},
+        {-0.690186f, 0.366119f, -0.624115f},
+        {-0.428345f, 0.844147f, -0.322296f},
+        {-0.21228f, -0.297546f, -0.930756f},
+        {-0.273071f, 0.516113f, 0.811798f},
+        {0.928314f, 0.371643f, 0.007233f},
+        {0.785828f, -0.479218f, -0.390778f},
+        {-0.704895f, 0.058929f, 0.706818f},
+        {0.173248f, 0.203583f, 0.963562f},
+        {0.422211f, -0.904297f, -0.062469f},
+        {-0.363312f, -0.182465f, 0.913605f},
+        {0.254028f, -0.552307f, -0.793945f},
+        {-0.28891f, -0.765747f, -0.574554f},
+        {0.058319f, 0.291382f, 0.954803f},
+        {0.946136f, -0.303925f, 0.111267f},
+        {-0.078156f, 0.443695f, -0.892731f},
+        {0.182098f, 0.89389f, 0.409515f},
+        {-0.680298f, -0.213318f, 0.701141f},
+        {0.062469f, 0.848389f, -0.525635f},
+        {-0.72879f, -0.641846f, 0.238342f},
+        {-0.88089f, 0.427673f, 0.202637f},
+        {-0.532501f, -0.21405f, 0.818878f},
+        {0.948975f, -0.305084f, 0.07962f},
+        {0.925446f, 0.374664f, 0.055817f},
+        {0.820923f, 0.565491f, 0.079102f},
+        {0.25882f, 0.099792f, -0.960724f},
+        {-0.294617f, 0.910522f, 0.289978f},
+        {0.137115f, 0.320038f, -0.937408f},
+        {-0.908386f, 0.345276f, -0.235718f},
+        {-0.936218f, 0.138763f, 0.322754f},
+        {0.366577f, 0.925934f, -0.090637f},
+        {0.309296f, -0.686829f, -0.657684f},
+        {0.66983f, 0.024445f, 0.742065f},
+        {-0.917999f, -0.059113f, -0.392059f},
+        {0.365509f, 0.462158f, -0.807922f},
+        {0.083374f, 0.996399f, -0.014801f},
+        {0.593842f, 0.253143f, -0.763672f},
+        {0.974976f, -0.165466f, 0.148285f},
+        {0.918976f, 0.137299f, 0.369537f},
+        {0.294952f, 0.694977f, 0.655731f},
+        {0.943085f, 0.152618f, -0.295319f},
+        {0.58783f, -0.598236f, 0.544495f},
+        {0.203796f, 0.678223f, 0.705994f},
+        {-0.478821f, -0.661011f, 0.577667f},
+        {0.719055f, -0.1698f, -0.673828f},
+        {-0.132172f, -0.965332f, 0.225006f},
+        {-0.981873f, -0.14502f, 0.121979f},
+        {0.763458f, 0.579742f, 0.284546f},
+        {-0.893188f, 0.079681f, 0.442474f},
+        {-0.795776f, -0.523804f, 0.303802f},
+        {0.734955f, 0.67804f, -0.007446f},
+        {0.15506f, 0.986267f, -0.056183f},
+        {0.258026f, 0.571503f, -0.778931f},
+        {-0.681549f, -0.702087f, -0.206116f},
+        {-0.96286f, -0.177185f, 0.203613f},
+        {-0.470978f, -0.515106f, 0.716095f},
+        {-0.740326f, 0.57135f, 0.354095f},
+        {-0.56012f, -0.824982f, -0.074982f},
+        {-0.507874f, 0.753204f, 0.417969f},
+        {-0.503113f, 0.038147f, 0.863342f},
+        {0.594025f, 0.673553f, -0.439758f},
+        {-0.119873f, -0.005524f, -0.992737f},
+        {0.098267f, -0.213776f, 0.971893f},
+        {-0.615631f, 0.643951f, 0.454163f},
+        {0.896851f, -0.441071f, 0.032166f},
+        {-0.555023f, 0.750763f, -0.358093f},
+        {0.398773f, 0.304688f, 0.864929f},
+        {-0.722961f, 0.303589f, 0.620544f},
+        {-0.63559f, -0.621948f, -0.457306f},
+        {-0.293243f, 0.072327f, 0.953278f},
+        {-0.491638f, 0.661041f, -0.566772f},
+        {-0.304199f, -0.572083f, -0.761688f},
+        {0.908081f, -0.398956f, 0.127014f},
+        {-0.523621f, -0.549683f, -0.650848f},
+        {-0.932922f, -0.19986f, 0.299408f},
+        {0.099426f, 0.140869f, 0.984985f},
+        {-0.020325f, -0.999756f, -0.002319f},
+        {0.952667f, 0.280853f, -0.11615f},
+        {-0.971893f, 0.082581f, 0.220337f},
+        {0.65921f, 0.705292f, -0.260651f},
+        {0.733063f, -0.175537f, 0.657043f},
+        {-0.555206f, 0.429504f, -0.712189f},
+        {0.400421f, -0.89859f, 0.179352f},
+        {0.750885f, -0.19696f, 0.630341f},
+        {0.785675f, -0.569336f, 0.241821f},
+        {-0.058899f, -0.464111f, 0.883789f},
+        {0.129608f, -0.94519f, 0.299622f},
+        {-0.357819f, 0.907654f, 0.219238f},
+        {-0.842133f, -0.439117f, -0.312927f},
+        {-0.313477f, 0.84433f, 0.434479f},
+        {-0.241211f, 0.053253f, 0.968994f},
+        {0.063873f, 0.823273f, 0.563965f},
+        {0.476288f, 0.862152f, -0.172516f},
+        {0.620941f, -0.298126f, 0.724915f},
+        {0.25238f, -0.749359f, -0.612122f},
+        {-0.577545f, 0.386566f, 0.718994f},
+        {-0.406342f, -0.737976f, 0.538696f},
+        {0.04718f, 0.556305f, 0.82959f},
+        {-0.802856f, 0.587463f, 0.101166f},
+        {-0.707733f, -0.705963f, 0.026428f},
+        {0.374908f, 0.68457f, 0.625092f},
+        {0.472137f, 0.208405f, -0.856506f},
+        {-0.703064f, -0.581085f, -0.409821f},
+        {-0.417206f, -0.736328f, 0.532623f},
+        {-0.447876f, -0.20285f, -0.870728f},
+        {0.086945f, -0.990417f, 0.107086f},
+        {0.183685f, 0.018341f, -0.982788f},
+        {0.560638f, -0.428864f, 0.708282f},
+        {0.296722f, -0.952576f, -0.0672f},
+        {0.135773f, 0.990265f, 0.030243f},
+        {-0.068787f, 0.654724f, 0.752686f},
+        {0.762604f, -0.551758f, 0.337585f},
+        {-0.819611f, -0.407684f, 0.402466f},
+        {-0.727844f, -0.55072f, -0.408539f},
+        {-0.855774f, -0.480011f, 0.19281f},
+        {0.693176f, -0.079285f, 0.716339f},
+        {0.226013f, 0.650116f, -0.725433f},
+        {0.246704f, 0.953369f, -0.173553f},
+        {-0.970398f, -0.239227f, -0.03244f},
+        {0.136383f, -0.394318f, 0.908752f},
+        {0.813232f, 0.558167f, 0.164368f},
+        {0.40451f, 0.549042f, -0.731323f},
+        {-0.380249f, -0.566711f, 0.730865f},
+        {0.022156f, 0.932739f, 0.359741f},
+        {0.00824f, 0.996552f, -0.082306f},
+        {0.956635f, -0.065338f, -0.283722f},
+        {-0.743561f, 0.008209f, 0.668579f},
+        {-0.859589f, -0.509674f, 0.035767f},
+        {-0.852234f, 0.363678f, -0.375977f},
+        {-0.201965f, -0.970795f, -0.12915f},
+        {0.313477f, 0.947327f, 0.06546f},
+        {-0.254028f, -0.528259f, 0.81015f},
+        {0.628052f, 0.601105f, 0.49411f},
+        {-0.494385f, 0.868378f, 0.037933f},
+        {0.275635f, -0.086426f, 0.957336f},
+        {-0.197937f, 0.468903f, -0.860748f},
+        {0.895599f, 0.399384f, 0.195801f},
+        {0.560791f, 0.825012f, -0.069214f},
+        {0.304199f, -0.849487f, 0.43103f},
+        {0.096375f, 0.93576f, 0.339111f},
+        {-0.051422f, 0.408966f, -0.911072f},
+        {0.330444f, 0.942841f, -0.042389f},
+        {-0.452362f, -0.786407f, 0.420563f},
+        {0.134308f, -0.933472f, -0.332489f},
+        {0.80191f, -0.566711f, -0.188934f},
+        {-0.987946f, -0.105988f, 0.112518f},
+        {-0.24408f, 0.892242f, -0.379791f},
+        {-0.920502f, 0.229095f, -0.316376f},
+        {0.7789f, 0.325958f, 0.535706f},
+        {-0.912872f, 0.185211f, -0.36377f},
+        {-0.184784f, 0.565369f, -0.803833f},
+        {-0.018463f, 0.119537f, 0.992615f},
+        {-0.259247f, -0.935608f, 0.239532f},
+        {-0.82373f, -0.449127f, -0.345947f},
+        {-0.433105f, 0.659515f, 0.614349f},
+        {-0.822754f, 0.378845f, -0.423676f},
+        {0.687195f, -0.674835f, -0.26889f},
+        {-0.246582f, -0.800842f, 0.545715f},
+        {-0.729187f, -0.207794f, 0.651978f},
+        {0.653534f, -0.610443f, -0.447388f},
+        {0.492584f, -0.023346f, 0.869934f},
+        {0.609039f, 0.009094f, -0.79306f},
+        {0.962494f, -0.271088f, -0.00885f},
+        {0.2659f, -0.004913f, 0.963959f},
+        {0.651245f, 0.553619f, -0.518951f},
+        {0.280548f, -0.84314f, 0.458618f},
+        {-0.175293f, -0.983215f, 0.049805f},
+        {0.035339f, -0.979919f, 0.196045f},
+        {-0.982941f, 0.164307f, -0.082245f},
+        {0.233734f, -0.97226f, -0.005005f},
+        {-0.747253f, -0.611328f, 0.260437f},
+        {0.645599f, 0.592773f, 0.481384f},
+        {0.117706f, -0.949524f, -0.29068f},
+        {-0.535004f, -0.791901f, -0.294312f},
+        {-0.627167f, -0.214447f, 0.748718f},
+        {-0.047974f, -0.813477f, -0.57959f},
+        {-0.175537f, 0.477264f, -0.860992f},
+        {0.738556f, -0.414246f, -0.53183f},
+        {0.562561f, -0.704071f, 0.433289f},
+        {-0.754944f, 0.64801f, -0.100586f},
+        {0.114716f, 0.044525f, -0.992371f},
+        {0.966003f, 0.244873f, -0.082764f},
+        {0.33783f, 0.715698f, -0.611206f},
+        {-0.944031f, -0.326599f, -0.045624f},
+        {-0.101074f, -0.416443f, -0.903503f},
+        {0.799286f, 0.49411f, -0.341949f},
+        {-0.854645f, 0.518036f, 0.033936f},
+        {0.42514f, -0.437866f, -0.792114f},
+        {-0.358948f, 0.597046f, 0.717377f},
+        {-0.985413f, 0.144714f, 0.089294f},
+        {-0.601776f, -0.33728f, -0.723907f},
+        {-0.449921f, 0.594513f, 0.666382f},
+        {0.208313f, -0.10791f, 0.972076f},
+        {0.575317f, 0.060425f, 0.815643f},
+        {0.293365f, -0.875702f, -0.383453f},
+        {0.293762f, 0.465759f, 0.834686f},
+        {-0.846008f, -0.233398f, -0.47934f},
+        {-0.115814f, 0.143036f, -0.98291f},
+        {0.204681f, -0.949036f, -0.239532f},
+        {0.946716f, -0.263947f, 0.184326f},
+        {-0.235596f, 0.573822f, 0.784332f},
+        {0.203705f, -0.372253f, -0.905487f},
+        {0.756989f, -0.651031f, 0.055298f},
+        {0.497803f, 0.814697f, -0.297363f},
+        {-0.16214f, 0.063995f, -0.98468f},
+        {-0.329254f, 0.834381f, 0.441925f},
+        {0.703827f, -0.527039f, -0.476227f},
+        {0.956421f, 0.266113f, 0.119781f},
+        {0.480133f, 0.482849f, 0.7323f},
+        {-0.18631f, 0.961212f, -0.203125f},
+        {-0.748474f, -0.656921f, -0.090393f},
+        {-0.085052f, -0.165253f, 0.982544f},
+        {-0.76947f, 0.628174f, -0.115234f},
+        {0.383148f, 0.537659f, 0.751068f},
+        {0.616486f, -0.668488f, -0.415924f},
+        {-0.259979f, -0.630005f, 0.73175f},
+        {0.570953f, -0.087952f, 0.816223f},
+        {-0.458008f, 0.023254f, 0.888611f},
+        {-0.196167f, 0.976563f, -0.088287f},
+        {-0.263885f, -0.69812f, -0.665527f},
+        {0.437134f, -0.892273f, -0.112793f},
+        {-0.621674f, -0.230438f, 0.748566f},
+        {0.232422f, 0.900574f, -0.367249f},
+        {0.22229f, -0.796143f, 0.562744f},
+        {-0.665497f, -0.73764f, 0.11377f},
+        {0.670135f, 0.704803f, 0.232605f},
+        {0.895599f, 0.429749f, -0.114655f},
+        {-0.11557f, -0.474243f, 0.872742f},
+        {0.621826f, 0.604004f, -0.498444f},
+        {-0.832214f, 0.012756f, 0.55426f},
+        {-0.702484f, 0.705994f, -0.089661f},
+        {-0.692017f, 0.649292f, 0.315399f},
+        {-0.175995f, -0.977997f, 0.111877f},
+        {0.096954f, -0.04953f, 0.994019f},
+        {0.635284f, -0.606689f, -0.477783f},
+        {-0.261261f, -0.607422f, -0.750153f},
+        {0.983276f, 0.165436f, 0.075958f},
+        {-0.29837f, 0.404083f, -0.864655f},
+        {-0.638672f, 0.507721f, 0.578156f},
+        {0.388214f, 0.412079f, 0.824249f},
+        {0.556183f, -0.208832f, 0.804352f},
+        {0.778442f, 0.562012f, 0.27951f},
+        {-0.616577f, 0.781921f, -0.091522f},
+        {0.196289f, 0.051056f, 0.979187f},
+        {-0.121216f, 0.207153f, -0.970734f},
+        {-0.173401f, -0.384735f, 0.906555f},
+        {0.161499f, -0.723236f, -0.671387f},
+        {0.178497f, -0.006226f, -0.983887f},
+        {-0.126038f, 0.15799f, 0.97934f},
+        {0.830475f, -0.024811f, 0.556458f},
+        {-0.510132f, -0.76944f, 0.384247f},
+        {0.81424f, 0.200104f, -0.544891f},
+        {-0.112549f, -0.393311f, -0.912445f},
+        {0.56189f, 0.152222f, -0.813049f},
+        {0.198914f, -0.254517f, -0.946381f},
+        {-0.41217f, 0.690979f, -0.593811f},
+        {-0.407257f, 0.324524f, 0.853668f},
+        {-0.690186f, 0.366119f, -0.624115f},
+        {-0.428345f, 0.844147f, -0.322296f},
+        {-0.21228f, -0.297546f, -0.930756f},
+        {-0.273071f, 0.516113f, 0.811798f},
+        {0.928314f, 0.371643f, 0.007233f},
+        {0.785828f, -0.479218f, -0.390778f},
+        {-0.704895f, 0.058929f, 0.706818f},
+        {0.173248f, 0.203583f, 0.963562f},
+        {0.422211f, -0.904297f, -0.062469f},
+        {-0.363312f, -0.182465f, 0.913605f},
+        {0.254028f, -0.552307f, -0.793945f},
+        {-0.28891f, -0.765747f, -0.574554f},
+        {0.058319f, 0.291382f, 0.954803f},
+        {0.946136f, -0.303925f, 0.111267f},
+        {-0.078156f, 0.443695f, -0.892731f},
+        {0.182098f, 0.89389f, 0.409515f},
+        {-0.680298f, -0.213318f, 0.701141f},
+        {0.062469f, 0.848389f, -0.525635f},
+        {-0.72879f, -0.641846f, 0.238342f},
+        {-0.88089f, 0.427673f, 0.202637f},
+        {-0.532501f, -0.21405f, 0.818878f},
+        {0.948975f, -0.305084f, 0.07962f},
+        {0.925446f, 0.374664f, 0.055817f},
+        {0.820923f, 0.565491f, 0.079102f},
+        {0.25882f, 0.099792f, -0.960724f},
+        {-0.294617f, 0.910522f, 0.289978f},
+        {0.137115f, 0.320038f, -0.937408f},
+        {-0.908386f, 0.345276f, -0.235718f},
+        {-0.936218f, 0.138763f, 0.322754f},
+        {0.366577f, 0.925934f, -0.090637f},
+        {0.309296f, -0.686829f, -0.657684f},
+        {0.66983f, 0.024445f, 0.742065f},
+        {-0.917999f, -0.059113f, -0.392059f},
+        {0.365509f, 0.462158f, -0.807922f},
+        {0.083374f, 0.996399f, -0.014801f},
+        {0.593842f, 0.253143f, -0.763672f},
+        {0.974976f, -0.165466f, 0.148285f},
+        {0.918976f, 0.137299f, 0.369537f},
+        {0.294952f, 0.694977f, 0.655731f},
+        {0.943085f, 0.152618f, -0.295319f},
+        {0.58783f, -0.598236f, 0.544495f},
+        {0.203796f, 0.678223f, 0.705994f},
+        {-0.478821f, -0.661011f, 0.577667f},
+        {0.719055f, -0.1698f, -0.673828f},
+        {-0.132172f, -0.965332f, 0.225006f},
+        {-0.981873f, -0.14502f, 0.121979f},
+        {0.763458f, 0.579742f, 0.284546f},
+        {-0.893188f, 0.079681f, 0.442474f},
+        {-0.795776f, -0.523804f, 0.303802f},
+        {0.734955f, 0.67804f, -0.007446f},
+        {0.15506f, 0.986267f, -0.056183f},
+        {0.258026f, 0.571503f, -0.778931f},
+        {-0.681549f, -0.702087f, -0.206116f},
+        {-0.96286f, -0.177185f, 0.203613f},
+        {-0.470978f, -0.515106f, 0.716095f},
+        {-0.740326f, 0.57135f, 0.354095f},
+        {-0.56012f, -0.824982f, -0.074982f},
+        {-0.507874f, 0.753204f, 0.417969f},
+        {-0.503113f, 0.038147f, 0.863342f},
+        {0.594025f, 0.673553f, -0.439758f},
+        {-0.119873f, -0.005524f, -0.992737f},
+        {0.098267f, -0.213776f, 0.971893f},
+        {-0.615631f, 0.643951f, 0.454163f},
+        {0.896851f, -0.441071f, 0.032166f},
+        {-0.555023f, 0.750763f, -0.358093f},
+        {0.398773f, 0.304688f, 0.864929f},
+        {-0.722961f, 0.303589f, 0.620544f},
+        {-0.63559f, -0.621948f, -0.457306f},
+        {-0.293243f, 0.072327f, 0.953278f},
+        {-0.491638f, 0.661041f, -0.566772f},
+        {-0.304199f, -0.572083f, -0.761688f},
+        {0.908081f, -0.398956f, 0.127014f},
+        {-0.523621f, -0.549683f, -0.650848f},
+        {-0.932922f, -0.19986f, 0.299408f},
+        {0.099426f, 0.140869f, 0.984985f},
+        {-0.020325f, -0.999756f, -0.002319f},
+        {0.952667f, 0.280853f, -0.11615f},
+        {-0.971893f, 0.082581f, 0.220337f},
+        {0.65921f, 0.705292f, -0.260651f},
+        {0.733063f, -0.175537f, 0.657043f},
+        {-0.555206f, 0.429504f, -0.712189f},
+        {0.400421f, -0.89859f, 0.179352f},
+        {0.750885f, -0.19696f, 0.630341f},
+        {0.785675f, -0.569336f, 0.241821f},
+        {-0.058899f, -0.464111f, 0.883789f},
+        {0.129608f, -0.94519f, 0.299622f},
+        {-0.357819f, 0.907654f, 0.219238f},
+        {-0.842133f, -0.439117f, -0.312927f},
+        {-0.313477f, 0.84433f, 0.434479f},
+        {-0.241211f, 0.053253f, 0.968994f},
+        {0.063873f, 0.823273f, 0.563965f},
+        {0.476288f, 0.862152f, -0.172516f},
+        {0.620941f, -0.298126f, 0.724915f},
+        {0.25238f, -0.749359f, -0.612122f},
+        {-0.577545f, 0.386566f, 0.718994f},
+        {-0.406342f, -0.737976f, 0.538696f},
+        {0.04718f, 0.556305f, 0.82959f},
+        {-0.802856f, 0.587463f, 0.101166f},
+        {-0.707733f, -0.705963f, 0.026428f},
+        {0.374908f, 0.68457f, 0.625092f},
+        {0.472137f, 0.208405f, -0.856506f},
+        {-0.703064f, -0.581085f, -0.409821f},
+        {-0.417206f, -0.736328f, 0.532623f},
+        {-0.447876f, -0.20285f, -0.870728f},
+        {0.086945f, -0.990417f, 0.107086f},
+        {0.183685f, 0.018341f, -0.982788f},
+        {0.560638f, -0.428864f, 0.708282f},
+        {0.296722f, -0.952576f, -0.0672f},
+        {0.135773f, 0.990265f, 0.030243f},
+        {-0.068787f, 0.654724f, 0.752686f},
+        {0.762604f, -0.551758f, 0.337585f},
+        {-0.819611f, -0.407684f, 0.402466f},
+        {-0.727844f, -0.55072f, -0.408539f},
+        {-0.855774f, -0.480011f, 0.19281f},
+        {0.693176f, -0.079285f, 0.716339f},
+        {0.226013f, 0.650116f, -0.725433f},
+        {0.246704f, 0.953369f, -0.173553f},
+        {-0.970398f, -0.239227f, -0.03244f},
+        {0.136383f, -0.394318f, 0.908752f},
+        {0.813232f, 0.558167f, 0.164368f},
+        {0.40451f, 0.549042f, -0.731323f},
+        {-0.380249f, -0.566711f, 0.730865f},
+        {0.022156f, 0.932739f, 0.359741f},
+        {0.00824f, 0.996552f, -0.082306f},
+        {0.956635f, -0.065338f, -0.283722f},
+        {-0.743561f, 0.008209f, 0.668579f},
+        {-0.859589f, -0.509674f, 0.035767f},
+        {-0.852234f, 0.363678f, -0.375977f},
+        {-0.201965f, -0.970795f, -0.12915f},
+        {0.313477f, 0.947327f, 0.06546f},
+        {-0.254028f, -0.528259f, 0.81015f},
+        {0.628052f, 0.601105f, 0.49411f},
+        {-0.494385f, 0.868378f, 0.037933f},
+        {0.275635f, -0.086426f, 0.957336f},
+        {-0.197937f, 0.468903f, -0.860748f},
+        {0.895599f, 0.399384f, 0.195801f},
+        {0.560791f, 0.825012f, -0.069214f},
+        {0.304199f, -0.849487f, 0.43103f},
+        {0.096375f, 0.93576f, 0.339111f},
+        {-0.051422f, 0.408966f, -0.911072f},
+        {0.330444f, 0.942841f, -0.042389f},
+        {-0.452362f, -0.786407f, 0.420563f},
+        {0.134308f, -0.933472f, -0.332489f},
+        {0.80191f, -0.566711f, -0.188934f},
+        {-0.987946f, -0.105988f, 0.112518f},
+        {-0.24408f, 0.892242f, -0.379791f},
+        {-0.920502f, 0.229095f, -0.316376f},
+        {0.7789f, 0.325958f, 0.535706f},
+        {-0.912872f, 0.185211f, -0.36377f},
+        {-0.184784f, 0.565369f, -0.803833f},
+        {-0.018463f, 0.119537f, 0.992615f},
+        {-0.259247f, -0.935608f, 0.239532f},
+        {-0.82373f, -0.449127f, -0.345947f},
+        {-0.433105f, 0.659515f, 0.614349f},
+        {-0.822754f, 0.378845f, -0.423676f},
+        {0.687195f, -0.674835f, -0.26889f},
+        {-0.246582f, -0.800842f, 0.545715f},
+        {-0.729187f, -0.207794f, 0.651978f},
+        {0.653534f, -0.610443f, -0.447388f},
+        {0.492584f, -0.023346f, 0.869934f},
+        {0.609039f, 0.009094f, -0.79306f},
+        {0.962494f, -0.271088f, -0.00885f},
+        {0.2659f, -0.004913f, 0.963959f},
+        {0.651245f, 0.553619f, -0.518951f},
+        {0.280548f, -0.84314f, 0.458618f},
+        {-0.175293f, -0.983215f, 0.049805f},
+        {0.035339f, -0.979919f, 0.196045f},
+        {-0.982941f, 0.164307f, -0.082245f},
+        {0.233734f, -0.97226f, -0.005005f},
+        {-0.747253f, -0.611328f, 0.260437f},
+        {0.645599f, 0.592773f, 0.481384f},
+        {0.117706f, -0.949524f, -0.29068f},
+        {-0.535004f, -0.791901f, -0.294312f},
+        {-0.627167f, -0.214447f, 0.748718f},
+        {-0.047974f, -0.813477f, -0.57959f},
+        {-0.175537f, 0.477264f, -0.860992f},
+        {0.738556f, -0.414246f, -0.53183f},
+        {0.562561f, -0.704071f, 0.433289f},
+        {-0.754944f, 0.64801f, -0.100586f},
+        {0.114716f, 0.044525f, -0.992371f},
+        {0.966003f, 0.244873f, -0.082764f},
+        {0.33783f, 0.715698f, -0.611206f},
+        {-0.944031f, -0.326599f, -0.045624f}};
 }

+ 33 - 32
engine/src/test/jme3test/blender/scene/Pivot.java

@@ -14,40 +14,41 @@ import com.jme3.scene.shape.Sphere;
  * @author Marcin Roguski
  */
 public class Pivot extends Node {
-	public Pivot(AssetManager assetManager) {
-		this.attachChild(this.getAxis("x", new Vector3f(10, 0, 0), ColorRGBA.Red, assetManager));
-		this.attachChild(this.getAxis("y", new Vector3f(0, 10, 0), ColorRGBA.Green, assetManager));
-		this.attachChild(this.getAxis("z", new Vector3f(0, 0, 10), ColorRGBA.Blue, assetManager));
-		this.assignPoints(assetManager);
-	}
 
-	private void assignPoints(AssetManager assetManager) {
-		Material defaultMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		defaultMaterial.setColor("Color", ColorRGBA.DarkGray);
-		for(int i = -10; i <= 10; ++i) {
-			Geometry g = new Geometry("", new Sphere(3, 3, 0.05f));
-			g.setLocalTranslation(i, 0, 0);
-			g.setMaterial(defaultMaterial);
-			this.attachChild(g);
+    public Pivot(AssetManager assetManager) {
+        this.attachChild(this.getAxis("x", new Vector3f(10, 0, 0), ColorRGBA.Red, assetManager));
+        this.attachChild(this.getAxis("y", new Vector3f(0, 10, 0), ColorRGBA.Green, assetManager));
+        this.attachChild(this.getAxis("z", new Vector3f(0, 0, 10), ColorRGBA.Blue, assetManager));
+        this.assignPoints(assetManager);
+    }
 
-			g = new Geometry("", new Sphere(3, 3, 0.05f));
-			g.setLocalTranslation(0, i, 0);
-			g.setMaterial(defaultMaterial);
-			this.attachChild(g);
+    private void assignPoints(AssetManager assetManager) {
+        Material defaultMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        defaultMaterial.setColor("Color", ColorRGBA.DarkGray);
+        for (int i = -10; i <= 10; ++i) {
+            Geometry g = new Geometry("", new Sphere(3, 3, 0.05f));
+            g.setLocalTranslation(i, 0, 0);
+            g.setMaterial(defaultMaterial);
+            this.attachChild(g);
 
-			g = new Geometry("", new Sphere(3, 3, 0.05f));
-			g.setLocalTranslation(0, 0, i);
-			g.setMaterial(defaultMaterial);
-			this.attachChild(g);
-		}
-	}
+            g = new Geometry("", new Sphere(3, 3, 0.05f));
+            g.setLocalTranslation(0, i, 0);
+            g.setMaterial(defaultMaterial);
+            this.attachChild(g);
 
-	private Geometry getAxis(String name, Vector3f endPoint, ColorRGBA color, AssetManager assetManager) {
-		Line axis = new Line(new Vector3f(0, 0, 0), endPoint);
-		Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		mat.setColor("Color", color);
-		Geometry geom = new Geometry(name, axis);
-		geom.setMaterial(mat);
-		return geom;
-	}
+            g = new Geometry("", new Sphere(3, 3, 0.05f));
+            g.setLocalTranslation(0, 0, i);
+            g.setMaterial(defaultMaterial);
+            this.attachChild(g);
+        }
+    }
+
+    private Geometry getAxis(String name, Vector3f endPoint, ColorRGBA color, AssetManager assetManager) {
+        Line axis = new Line(new Vector3f(0, 0, 0), endPoint);
+        Material mat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        mat.setColor("Color", color);
+        Geometry geom = new Geometry(name, axis);
+        geom.setMaterial(mat);
+        return geom;
+    }
 }

+ 25 - 24
engine/src/test/jme3test/blender/scene/VisibleBone.java

@@ -16,32 +16,33 @@ import com.jme3.scene.shape.Sphere;
  * @author Marcin Roguski
  */
 public class VisibleBone extends Node {
-	private Vector3f	globalPosition;
 
-	public VisibleBone(Bone bone, Vector3f parentLocation, Quaternion parentRotation, AssetManager assetManager) {
-		Material redMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		redMat.setColor("Color", ColorRGBA.Red);
+    private Vector3f globalPosition;
 
-		Material whiteMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
-		whiteMat.setColor("Color", ColorRGBA.White);
+    public VisibleBone(Bone bone, Vector3f parentLocation, Quaternion parentRotation, AssetManager assetManager) {
+        Material redMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        redMat.setColor("Color", ColorRGBA.Red);
 
-		Geometry g = new Geometry(bone.getName(), new Sphere(9, 9, 0.01f));
-		globalPosition = bone.getLocalPosition().add(parentLocation);
-		g.setLocalTranslation(globalPosition);
-		g.setLocalRotation(bone.getLocalRotation().mult(parentRotation));
-		g.setMaterial(redMat);
-		this.attachChild(g);
+        Material whiteMat = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
+        whiteMat.setColor("Color", ColorRGBA.White);
 
-		if(bone.getChildren() != null) {
-			for(Bone child : bone.getChildren()) {
-				VisibleBone vb = new VisibleBone(child, bone.getLocalPosition(), bone.getLocalRotation(), assetManager);
-				this.attachChild(vb);
-				Line line = new Line(globalPosition, vb.globalPosition);
-				line.setLineWidth(2);
-				Geometry geom = new Geometry("", line);
-				geom.setMaterial(whiteMat);
-				this.attachChild(geom);
-			}
-		}
-	}
+        Geometry g = new Geometry(bone.getName(), new Sphere(9, 9, 0.01f));
+        globalPosition = bone.getLocalPosition().add(parentLocation);
+        g.setLocalTranslation(globalPosition);
+        g.setLocalRotation(bone.getLocalRotation().mult(parentRotation));
+        g.setMaterial(redMat);
+        this.attachChild(g);
+
+        if (bone.getChildren() != null) {
+            for (Bone child : bone.getChildren()) {
+                VisibleBone vb = new VisibleBone(child, bone.getLocalPosition(), bone.getLocalRotation(), assetManager);
+                this.attachChild(vb);
+                Line line = new Line(globalPosition, vb.globalPosition);
+                line.setLineWidth(2);
+                Geometry geom = new Geometry("", line);
+                geom.setMaterial(whiteMat);
+                this.attachChild(geom);
+            }
+        }
+    }
 }

+ 70 - 84
engine/src/test/jme3test/network/TestChatClient.java

@@ -29,7 +29,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package jme3test.network;
 
 import java.awt.Dimension;
@@ -38,19 +37,13 @@ import java.awt.Component;
 import java.io.IOException;
 import javax.swing.*;
 
-import com.jme3.network.AbstractMessage;
 import com.jme3.network.Client;
-import com.jme3.network.HostedConnection;
 import com.jme3.network.Message;
 import com.jme3.network.MessageListener;
 import com.jme3.network.Network;
-import com.jme3.network.Server;
-import com.jme3.network.serializing.Serializable;
-import com.jme3.network.serializing.Serializer;
 
 import jme3test.network.TestChatServer.ChatMessage;
 
-
 /**
  *  A simple test chat server.  When SM implements a set
  *  of standard chat classes this can become a lot simpler.
@@ -58,115 +51,108 @@ import jme3test.network.TestChatServer.ChatMessage;
  *  @version   $Revision$
  *  @author    Paul Speed
  */
-public class TestChatClient extends JFrame
-{
+public class TestChatClient extends JFrame {
+
     private Client client;
     private JEditorPane chatLog;
     private StringBuilder chatMessages = new StringBuilder();
     private JTextField nameField;
-    private JTextField messageField; 
-    
-    public TestChatClient( String host ) throws IOException
-    {
-        super( "jME3 Test Chat Client - to:" + host );
-        
+    private JTextField messageField;
+
+    public TestChatClient(String host) throws IOException {
+        super("jME3 Test Chat Client - to:" + host);
+
         // Build out the UI       
-        setDefaultCloseOperation( DISPOSE_ON_CLOSE );
-        setSize( 800, 600 );
-        
+        setDefaultCloseOperation(DISPOSE_ON_CLOSE);
+        setSize(800, 600);
+
         chatLog = new JEditorPane();
         chatLog.setEditable(false);
         chatLog.setContentType("text/html");
-        chatLog.setText( "<html><body>" );
-        
-        getContentPane().add( new JScrollPane(chatLog), "Center" );
- 
+        chatLog.setText("<html><body>");
+
+        getContentPane().add(new JScrollPane(chatLog), "Center");
+
         // A crude form       
         JPanel p = new JPanel();
-        p.setLayout( new BoxLayout(p, BoxLayout.X_AXIS) );
-        p.add( new JLabel( "Name:" ) );
-        nameField = new JTextField( System.getProperty( "user.name", "yourname" ) );
+        p.setLayout(new BoxLayout(p, BoxLayout.X_AXIS));
+        p.add(new JLabel("Name:"));
+        nameField = new JTextField(System.getProperty("user.name", "yourname"));
         Dimension d = nameField.getPreferredSize();
-        nameField.setMaximumSize( new Dimension(120, d.height + 6) );
-        p.add( nameField );
-        p.add( new JLabel( "  Message:" ) );
+        nameField.setMaximumSize(new Dimension(120, d.height + 6));
+        p.add(nameField);
+        p.add(new JLabel("  Message:"));
         messageField = new JTextField();
-        p.add( messageField );
-        p.add( new JButton(new SendAction(true)) );       
-        p.add( new JButton(new SendAction(false)) );       
-        
-        getContentPane().add( p, "South" );
-        
-        client = Network.connectToServer( TestChatServer.NAME, TestChatServer.VERSION,
-                                          host, TestChatServer.PORT, TestChatServer.UDP_PORT );                                          
-        client.addMessageListener( new ChatHandler(), ChatMessage.class );                                             
-        client.start();                                                                               
+        p.add(messageField);
+        p.add(new JButton(new SendAction(true)));
+        p.add(new JButton(new SendAction(false)));
+
+        getContentPane().add(p, "South");
+
+        client = Network.connectToServer(TestChatServer.NAME, TestChatServer.VERSION,
+                host, TestChatServer.PORT, TestChatServer.UDP_PORT);
+        client.addMessageListener(new ChatHandler(), ChatMessage.class);
+        client.start();
     }
- 
-    public static String getString( Component owner, String title, String message, String initialValue )
-    {
-        return (String)JOptionPane.showInputDialog( owner, message, title, JOptionPane.PLAIN_MESSAGE,
-                                                     null, null, initialValue );
+
+    public static String getString(Component owner, String title, String message, String initialValue) {
+        return (String) JOptionPane.showInputDialog(owner, message, title, JOptionPane.PLAIN_MESSAGE,
+                null, null, initialValue);
     }
-   
-    public static void main( String... args ) throws Exception
-    {
+
+    public static void main(String... args) throws Exception {
         TestChatServer.initializeClasses();
 
         // Grab a host string from the user
-        String s = getString( null, "Host Info", "Enter chat host:", "localhost" );
-        if( s == null ) {
-            System.out.println( "User cancelled." );
+        String s = getString(null, "Host Info", "Enter chat host:", "localhost");
+        if (s == null) {
+            System.out.println("User cancelled.");
             return;
         }
-    
-        TestChatClient test = new TestChatClient( s );
-        test.setVisible( true );
+
+        TestChatClient test = new TestChatClient(s);
+        test.setVisible(true);
     }
- 
-    private class ChatHandler implements MessageListener<Client>
-    {
-        public void messageReceived( Client source, Message m ) 
-        {
-            ChatMessage chat = (ChatMessage)m;
- 
-            System.out.println( "Received:" + chat );
-                       
+
+    private class ChatHandler implements MessageListener<Client> {
+
+        public void messageReceived(Client source, Message m) {
+            ChatMessage chat = (ChatMessage) m;
+
+            System.out.println("Received:" + chat);
+
             // One of the least efficient ways to add text to a
             // JEditorPane
-            chatMessages.append( "<font color='#00a000'>" + (m.isReliable() ? "TCP" : "UDP") + "</font>" );
-            chatMessages.append( " -- <font color='#000080'><b>" + chat.getName() + "</b></font> : " ); 
-            chatMessages.append( chat.getMessage() );
-            chatMessages.append( "<br />" ); 
-            String s = "<html><body>" + chatMessages + "</body></html>"; 
-            chatLog.setText( s );
-            
+            chatMessages.append("<font color='#00a000'>" + (m.isReliable() ? "TCP" : "UDP") + "</font>");
+            chatMessages.append(" -- <font color='#000080'><b>" + chat.getName() + "</b></font> : ");
+            chatMessages.append(chat.getMessage());
+            chatMessages.append("<br />");
+            String s = "<html><body>" + chatMessages + "</body></html>";
+            chatLog.setText(s);
+
             // Set selection to the end so that the scroll panel will scroll
             // down.
-            chatLog.select( s.length(), s.length() );
+            chatLog.select(s.length(), s.length());
         }
     }
-    
-    private class SendAction extends AbstractAction
-    {
+
+    private class SendAction extends AbstractAction {
+
         private boolean reliable;
-        
-        public SendAction( boolean reliable )
-        {
-            super( reliable ? "TCP" : "UDP" );
+
+        public SendAction(boolean reliable) {
+            super(reliable ? "TCP" : "UDP");
             this.reliable = reliable;
         }
-        
-        public void actionPerformed( ActionEvent evt )
-        {
+
+        public void actionPerformed(ActionEvent evt) {
             String name = nameField.getText();
             String message = messageField.getText();
-            
-            ChatMessage chat = new ChatMessage( name, message );
+
+            ChatMessage chat = new ChatMessage(name, message);
             chat.setReliable(reliable);
-            System.out.println( "Sending:" + chat );
-            client.send( chat ); 
+            System.out.println("Sending:" + chat);
+            client.send(chat);
         }
     }
 }
-

+ 40 - 55
engine/src/test/jme3test/network/TestChatServer.java

@@ -29,7 +29,6 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package jme3test.network;
 
 import com.jme3.network.Message;
@@ -41,7 +40,6 @@ import com.jme3.network.Server;
 import com.jme3.network.serializing.Serializable;
 import com.jme3.network.serializing.Serializer;
 
-
 /**
  *  A simple test chat server.  When SM implements a set
  *  of standard chat classes this can become a lot simpler.
@@ -49,105 +47,92 @@ import com.jme3.network.serializing.Serializer;
  *  @version   $Revision$
  *  @author    Paul Speed
  */
-public class TestChatServer
-{
+public class TestChatServer {
     // Normally these and the initialized method would
     // be in shared constants or something.
+
     public static final String NAME = "Test Chat Server";
     public static final int VERSION = 1;
-
     public static final int PORT = 5110;
     public static final int UDP_PORT = 5110;
 
-    public static void initializeClasses()
-    {
+    public static void initializeClasses() {
         // Doing it here means that the client code only needs to
         // call our initialize. 
         Serializer.registerClass(ChatMessage.class);
     }
-    
-    public static void main( String... args ) throws Exception
-    {
+
+    public static void main(String... args) throws Exception {
         initializeClasses();
-    
+
         // Use this to test the client/server name version check
-        Server server = Network.createServer( NAME, VERSION, PORT, UDP_PORT );
+        Server server = Network.createServer(NAME, VERSION, PORT, UDP_PORT);
         server.start();
 
         ChatHandler handler = new ChatHandler();
-        server.addMessageListener( handler, ChatMessage.class );
- 
+        server.addMessageListener(handler, ChatMessage.class);
+
         // Keep running basically forever
-        synchronized( NAME ) {
+        synchronized (NAME) {
             NAME.wait();
-        }           
+        }
     }
-    
-    private static class ChatHandler implements MessageListener<HostedConnection>
-    {
-        public ChatHandler() 
-        {
+
+    private static class ChatHandler implements MessageListener<HostedConnection> {
+
+        public ChatHandler() {
         }
-    
-        public void messageReceived( HostedConnection source, Message m )
-        {
-            if( m instanceof ChatMessage ) {
+
+        public void messageReceived(HostedConnection source, Message m) {
+            if (m instanceof ChatMessage) {
                 // Keep track of the name just in case we 
                 // want to know it for some other reason later and it's
                 // a good example of session data
-                source.setAttribute( "name", ((ChatMessage)m).getName() );
- 
-                System.out.println( "Broadcasting:" + m + "  reliable:" + m.isReliable() );
-                                   
+                source.setAttribute("name", ((ChatMessage) m).getName());
+
+                System.out.println("Broadcasting:" + m + "  reliable:" + m.isReliable());
+
                 // Just rebroadcast... the reliable flag will stay the
                 // same so if it came in on UDP it will go out on that too
-                source.getServer().broadcast( m ); 
+                source.getServer().broadcast(m);
             } else {
-                System.err.println( "Received odd message:" + m );
-            }            
+                System.err.println("Received odd message:" + m);
+            }
         }
     }
 
     @Serializable
-    public static class ChatMessage extends AbstractMessage 
-    {
+    public static class ChatMessage extends AbstractMessage {
+
         private String name;
         private String message;
- 
-        public ChatMessage()
-        {
+
+        public ChatMessage() {
         }
 
-        public ChatMessage( String name, String message )
-        {
+        public ChatMessage(String name, String message) {
             setName(name);
             setMessage(message);
         }
-        
-        public void setName( String name )
-        {
+
+        public void setName(String name) {
             this.name = name;
         }
-        
-        public String getName()
-        {
+
+        public String getName() {
             return name;
         }
-        
-        public void setMessage( String s )
-        {
+
+        public void setMessage(String s) {
             this.message = s;
         }
-        
-        public String getMessage()
-        {
+
+        public String getMessage() {
             return message;
         }
-        
-        public String toString()
-        {
+
+        public String toString() {
             return name + ":" + message;
         }
     }
 }
-

+ 0 - 58
engine/src/test/jme3test/network/TestHostDiscovery.java

@@ -1,58 +0,0 @@
-/*
- * Copyright (c) 2009-2010 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 OWNER 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 jme3test.network;
-
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.util.List;
-
-public class TestHostDiscovery {
-    public static void main(String[] args) throws IOException, InterruptedException{
-        Server server = new Server(5110, 5110);
-        server.start();
-
-        Client client = new Client();
-        client.start();
-
-        List<InetAddress> hosts = client.discoverHosts(5110, 5000);
-        for (InetAddress host : hosts){
-            System.out.println("Found host: " + host);
-            System.out.println("Reachable? " + host.isReachable(5000));
-        }
-
-        System.out.println("Connecting to: "+ hosts.get(0));
-        client.connect(hosts.get(0).getCanonicalHostName(), 5110, 5110);
-    }
-}

+ 34 - 29
engine/src/test/jme3test/network/TestLatency.java

@@ -32,16 +32,18 @@
 
 package jme3test.network;
 
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.MessageAdapter;
-import com.jme3.network.message.Message;
+import com.jme3.network.Client;
+import com.jme3.network.HostedConnection;
+import com.jme3.network.MessageListener;
+import com.jme3.network.Network;
+import com.jme3.network.Server;
+import com.jme3.network.Message;
 import com.jme3.network.serializing.Serializable;
 import com.jme3.network.serializing.Serializer;
 import com.jme3.network.sync.MovingAverage;
 import java.io.IOException;
 
-public class TestLatency extends MessageAdapter {
+public class TestLatency {
 
     private static long startTime;
     private static Client client;
@@ -56,7 +58,7 @@ public class TestLatency extends MessageAdapter {
     }
 
     @Serializable
-    public static class TimestampMessage extends Message {
+    public static class TimestampMessage extends com.jme3.network.message.Message {
 
         long timeSent     = 0;
         long timeReceived = 0;
@@ -73,14 +75,19 @@ public class TestLatency extends MessageAdapter {
 
     }
 
-    @Override
-    public void messageReceived(Message msg){
-        TimestampMessage timeMsg = (TimestampMessage) msg;
-        try {
-            if (timeMsg.timeReceived == 0){
-                TimestampMessage outMsg = new TimestampMessage(timeMsg.timeSent, getTime());
-                msg.getClient().send(outMsg);
-            }else{
+    public static void main(String[] args) throws IOException, InterruptedException{
+        Serializer.registerClass(TimestampMessage.class);
+
+        Server server = Network.createServer(5110);
+        server.start();
+
+        client = Network.connectToServer("localhost", 5110);
+        client.start();
+        
+        client.addMessageListener(new MessageListener<Client>(){
+            public void messageReceived(Client source, Message m) {
+                TimestampMessage timeMsg = (TimestampMessage) m;
+
                 long curTime = getTime();
                 //System.out.println("Time sent: " + timeMsg.timeSent);
                 //System.out.println("Time received by server: " + timeMsg.timeReceived);
@@ -99,26 +106,24 @@ public class TestLatency extends MessageAdapter {
 
                 client.send(new TimestampMessage(getTime(), 0));
             }
-        } catch (IOException ex) {
-            ex.printStackTrace();
-        }
-    }
+        }, TimestampMessage.class);
 
-    public static void main(String[] args) throws IOException, InterruptedException{
-        Serializer.registerClass(TimestampMessage.class);
-
-        Server server = new Server(5110, 5110);
-        server.start();
-
-        client = new Client("localhost", 5110, 5110);
-        client.start();
-
-        client.addMessageListener(new TestLatency(), TimestampMessage.class);
-        server.addMessageListener(new TestLatency(), TimestampMessage.class);
+        server.addMessageListener(new MessageListener<HostedConnection>(){
+            public void messageReceived(HostedConnection source, Message m) {
+                TimestampMessage timeMsg = (TimestampMessage) m;
+                TimestampMessage outMsg = new TimestampMessage(timeMsg.timeSent, getTime());
+                source.send(outMsg);
+            }
+        }, TimestampMessage.class);
 
         Thread.sleep(1);
 
         client.send(new TimestampMessage(getTime(), 0));
+        
+        Object obj = new Object();
+        synchronized(obj){
+            obj.wait();
+        }
     }
 
 }

+ 10 - 7
engine/src/test/jme3test/network/TestMessages.java

@@ -32,12 +32,12 @@
 
 package jme3test.network;
 
+import com.jme3.network.AbstractMessage;
 import com.jme3.network.Client;
 import com.jme3.network.HostedConnection;
 import com.jme3.network.MessageListener;
 import com.jme3.network.Network;
 import com.jme3.network.Server;
-import com.jme3.network.message.Message;
 import com.jme3.network.serializing.Serializable;
 import com.jme3.network.serializing.Serializer;
 import java.io.IOException;
@@ -45,11 +45,11 @@ import java.io.IOException;
 public class TestMessages {
 
     @Serializable
-    public static class PingMessage extends Message {
+    public static class PingMessage extends AbstractMessage {
     }
 
     @Serializable
-    public static class PongMessage extends Message {
+    public static class PongMessage extends AbstractMessage {
     }
 
     private static class ServerPingResponder implements MessageListener<HostedConnection> {
@@ -76,15 +76,18 @@ public class TestMessages {
         Server server = Network.createServer(5110);
         server.start();
 
-        Client client = Network.connectToServer("192.168.1.101", 5110, 5111);
+        Client client = Network.connectToServer("localhost", 5110);
         client.start();
 
         server.addMessageListener(new ServerPingResponder(), PingMessage.class);
         client.addMessageListener(new ClientPingResponder(), PongMessage.class);
 
-        Thread.sleep(100);
-
-        System.out.println("Sending ping message..");
+        System.out.println("Client: Sending ping message..");
         client.send(new PingMessage());
+        
+        Object obj = new Object();
+        synchronized (obj){
+            obj.wait();
+        }
     }
 }

+ 16 - 14
engine/src/test/jme3test/network/TestNetworkStress.java

@@ -32,37 +32,39 @@
 
 package jme3test.network;
 
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
-import com.jme3.network.events.ConnectionAdapter;
+import com.jme3.network.Client;
+import com.jme3.network.ConnectionListener;
+import com.jme3.network.HostedConnection;
+import com.jme3.network.Network;
+import com.jme3.network.Server;
 import java.io.IOException;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
-public class TestNetworkStress extends ConnectionAdapter {
+public class TestNetworkStress implements ConnectionListener {
     
-    @Override
-    public void clientConnected(Client client) {
-        System.out.println("CLIENT CONNECTED: "+client.getClientID());
-        try {
-            client.kick("goodbye");
-        } catch (IOException ex) {
-            ex.printStackTrace();
-        }
+    public void connectionAdded(Server server, HostedConnection conn) {
+        System.out.println("Client Connected: "+conn.getId());
+        //conn.close("goodbye");
+    }
+
+    public void connectionRemoved(Server server, HostedConnection conn) {
     }
     
     public static void main(String[] args) throws IOException, InterruptedException{
         Logger.getLogger("").getHandlers()[0].setLevel(Level.OFF);
         
-        Server server = new Server(5110, 5110);
+        Server server = Network.createServer(5110);
         server.start();
         server.addConnectionListener(new TestNetworkStress());
 
         for (int i = 0; i < 1000; i++){
-            Client client = new Client("localhost", 5110, 5110);
+            Client client = Network.connectToServer("localhost", 5110);
             client.start();
 
             Thread.sleep(10);
+            
+            client.close();
         }
     }
 }

+ 29 - 7
engine/src/test/jme3test/network/TestRemoteCall.java

@@ -34,25 +34,45 @@ package jme3test.network;
 
 import com.jme3.app.SimpleApplication;
 import com.jme3.export.Savable;
-import com.jme3.network.connection.Client;
-import com.jme3.network.connection.Server;
+import com.jme3.network.Client;
+import com.jme3.network.Network;
+import com.jme3.network.Server;
+import com.jme3.network.rmi.ObjectDef;
 import com.jme3.network.rmi.ObjectStore;
+import com.jme3.network.rmi.RemoteObjectDefMessage;
 import com.jme3.network.serializing.Serializer;
 import com.jme3.network.serializing.serializers.SavableSerializer;
 import com.jme3.scene.Spatial;
 import java.io.IOException;
+import java.lang.reflect.Method;
 import java.util.concurrent.Callable;
 
 public class TestRemoteCall {
 
     private static SimpleApplication serverApp;
 
+    /**
+     * Interface implemented by the server, exposing
+     * RMI calls that clients can use.
+     */
     public static interface ServerAccess {
-        public void attachChild(String model);
+        /**
+         * Attaches the model with the given name to the server's scene.
+         * 
+         * @param model The model name
+         * 
+         * @return True if the model was attached.
+         * 
+         * @throws RuntimeException If some error occurs.
+         */
+        public boolean attachChild(String model);
     }
 
     public static class ServerAccessImpl implements ServerAccess {
-        public void attachChild(String model) {
+        public boolean attachChild(String model) {
+            if (model == null)
+                throw new RuntimeException("Cannot be null. .. etc");
+
             final String finalModel = model;
             serverApp.enqueue(new Callable<Void>() {
                 public Void call() throws Exception {
@@ -61,6 +81,7 @@ public class TestRemoteCall {
                     return null;
                 }
             });
+            return true;
         }
     }
 
@@ -73,7 +94,7 @@ public class TestRemoteCall {
         serverApp.start();
 
         try {
-            Server server = new Server(5110, 5110);
+            Server server = Network.createServer(5110);
             server.start();
 
             ObjectStore store = new ObjectStore(server);
@@ -88,11 +109,12 @@ public class TestRemoteCall {
 
         createServer();
 
-        Client client = new Client("localhost", 5110, 5110);
+        Client client = Network.connectToServer("localhost", 5110);
         client.start();
 
         ObjectStore store = new ObjectStore(client);
         ServerAccess access = store.getExposedObject("access", ServerAccess.class, true);
-        access.attachChild("Models/Ferrari/WheelBackLeft.mesh.xml");
+        boolean result = access.attachChild("Models/Oto/Oto.mesh.xml");
+        System.out.println(result);
     }
 }

+ 27 - 31
engine/src/test/jme3test/network/TestThroughput.java

@@ -29,9 +29,9 @@
  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
-
 package jme3test.network;
 
+import com.jme3.network.AbstractMessage;
 import com.jme3.network.Client;
 import com.jme3.network.Message;
 import com.jme3.network.MessageConnection;
@@ -47,59 +47,64 @@ public class TestThroughput implements MessageListener<MessageConnection> { //ex
     private static long lastTime = -1;
     private static long counter = 0;
     private static long total = 0;
-    private static Client client;
-
     // Change this flag to test UDP instead of TCP
     private static boolean testReliable = false;
-    
     private boolean isOnServer;
 
-    public TestThroughput( boolean isOnServer ) {
+    public TestThroughput(boolean isOnServer) {
         this.isOnServer = isOnServer;
-    } 
+    }
+    
+    @Serializable
+    public static class TestMessage extends AbstractMessage {
+
+        public TestMessage() {
+            setReliable(testReliable);
+        }
+    }
 
     @Override
-    public void messageReceived( MessageConnection source, Message msg){
-    
-        if( !isOnServer ) {
+    public void messageReceived(MessageConnection source, Message msg) {
+
+        if (!isOnServer) {
             // It's local to the client so we got it back
             counter++;
             total++;
             long time = System.currentTimeMillis();
 //System.out.println( "total:" + total + "  counter:" + counter + "  lastTime:" + lastTime + "  time:" + time );
-            if( lastTime < 0 ) {
+            if (lastTime < 0) {
                 lastTime = time;
-            } else if( time - lastTime > 1000 ) {
+            } else if (time - lastTime > 1000) {
                 long delta = time - lastTime;
                 double scale = delta / 1000.0;
                 double pps = counter / scale;
-                System.out.println( "messages per second:" + pps + "  total messages:" + total );
+                System.out.println("messages per second:" + pps + "  total messages:" + total);
                 counter = 0;
                 lastTime = time;
             }
         } else {
-            if( source == null ) {
-                System.out.println( "Received a message from a not fully connected source, msg:"+ msg );
+            if (source == null) {
+                System.out.println("Received a message from a not fully connected source, msg:" + msg);
             } else {
 //System.out.println( "sending:" + msg + " back to client:" + source );
                 // The 'reliable' flag is transient and the server doesn't
                 // (yet) reset this value for us.
-                ((com.jme3.network.message.Message)msg).setReliable(testReliable);
+                ((com.jme3.network.Message) msg).setReliable(testReliable);
                 source.send(msg);
             }
         }
     }
 
-    public static void main(String[] args) throws IOException, InterruptedException{
-    
+    public static void main(String[] args) throws IOException, InterruptedException {
+
         Serializer.registerClass(TestMessage.class);
 
         // Use this to test the client/server name version check
         //Server server = Network.createServer( "bad name", 42, 5110, 5110 );
-        Server server = Network.createServer( 5110, 5110 );
+        Server server = Network.createServer(5110, 5110);
         server.start();
 
-        Client client = Network.connectToServer( "localhost", 5110 );
+        Client client = Network.connectToServer("localhost", 5110);
         client.start();
 
         client.addMessageListener(new TestThroughput(false), TestMessage.class);
@@ -109,20 +114,11 @@ public class TestThroughput implements MessageListener<MessageConnection> { //ex
 
         TestMessage test = new TestMessage();
 //        for( int i = 0; i < 10; i++ ) {
-        while( true ) {
+        while (true) {
 //System.out.println( "sending." );
             client.send(test);
-        }            
- 
-        //Thread.sleep(5000);
-    }
-
-    @Serializable
-    public static class TestMessage extends com.jme3.network.message.Message {
-
-        public TestMessage(){
-            setReliable(testReliable);
         }
-    }
 
+        //Thread.sleep(5000);
+    }
 }

Některé soubory nejsou zobrazeny, neboť je v těchto rozdílových datech změněno mnoho souborů