diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
index 40b36ac22..2eedcc37d 100644
--- a/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
+++ b/engine/src/blender/com/jme3/scene/plugins/blender/modifiers/ArmatureModifier.java
@@ -200,6 +200,8 @@ import com.jme3.util.BufferUtils;
                     mesh.setBuffer(buffers[0]);
                     mesh.setBuffer(buffers[1]);
 
+                    //FIXME @Kaelthas this should be replaced by a call to 
+                    //mesh.generateBindPos(true)
                     VertexBuffer bindNormalBuffer = meshContext.getBindNormalBuffer(materialIndex);
                     if (bindNormalBuffer != null) {
                         mesh.setBuffer(bindNormalBuffer);
@@ -212,6 +214,14 @@ import com.jme3.util.BufferUtils;
                     // Static to Stream
                     mesh.getBuffer(Type.Position).setUsage(Usage.Stream);
                     mesh.getBuffer(Type.Normal).setUsage(Usage.Stream);
+                    
+                    
+                    //creating empty buffers for HW skinning 
+                    //the buffers will be setup if ever used.
+                    VertexBuffer verticesWeightsHW = new VertexBuffer(Type.HWBoneWeight);
+                    VertexBuffer verticesWeightsIndicesHW = new VertexBuffer(Type.HWBoneIndex);
+                    mesh.setBuffer(verticesWeightsHW);
+                    mesh.setBuffer(verticesWeightsIndicesHW);
                 }
             } catch (BlenderFileException e) {
                 LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e);
diff --git a/engine/src/core-data/Common/ShaderLib/Skinning.glsllib b/engine/src/core-data/Common/ShaderLib/Skinning.glsllib
index 399e9e3fb..66a9ff73b 100644
--- a/engine/src/core-data/Common/ShaderLib/Skinning.glsllib
+++ b/engine/src/core-data/Common/ShaderLib/Skinning.glsllib
@@ -6,38 +6,38 @@
 
 #define NUM_WEIGHTS_PER_VERT 4
  
-attribute vec4 inBoneWeight;
-attribute vec4 inBoneIndex;
+attribute vec4 inHWBoneWeight;
+attribute vec4 inHWBoneIndex;
 uniform mat4 m_BoneMatrices[NUM_BONES];
- 
+
 void Skinning_Compute(inout vec4 position){
-    if (inBoneWeight.x != 0.0) {
+    if (inHWBoneWeight.x != 0.0) {
 #if NUM_WEIGHTS_PER_VERT == 1
-        position = m_BoneMatrices[int(inBoneIndex.x)] * position;
+        position = m_BoneMatrices[int(inHWBoneIndex.x)] * position;
 #else
         mat4 mat = mat4(0.0);
-        mat += m_BoneMatrices[int(inBoneIndex.x)] * inBoneWeight.x;
-        mat += m_BoneMatrices[int(inBoneIndex.y)] * inBoneWeight.y;
-        mat += m_BoneMatrices[int(inBoneIndex.z)] * inBoneWeight.z;
-        mat += m_BoneMatrices[int(inBoneIndex.w)] * inBoneWeight.w;
+        mat += m_BoneMatrices[int(inHWBoneIndex.x)] * inHWBoneWeight.x;
+        mat += m_BoneMatrices[int(inHWBoneIndex.y)] * inHWBoneWeight.y;
+        mat += m_BoneMatrices[int(inHWBoneIndex.z)] * inHWBoneWeight.z;
+        mat += m_BoneMatrices[int(inHWBoneIndex.w)] * inHWBoneWeight.w;
         position = mat * position;
 #endif
     }
 }
  
 void Skinning_Compute(inout vec4 position, inout vec3 normal){
-    if (inBoneWeight.x != 0.0) {
+    if (inHWBoneWeight.x != 0.0) {
 #if NUM_WEIGHTS_PER_VERT == 1
-        position = m_BoneMatrices[int(inBoneIndex.x)] * position;
-        normal = (mat3(m_BoneMatrices[int(inBoneIndex.x)][0].xyz,
-                       m_BoneMatrices[int(inBoneIndex.x)][1].xyz,
-                       m_BoneMatrices[int(inBoneIndex.x)][2].xyz) * normal);
+        position = m_BoneMatrices[int(inHWBoneIndex.x)] * position;
+        normal = (mat3(m_BoneMatrices[int(inHWBoneIndex.x)][0].xyz,
+                       m_BoneMatrices[int(inHWBoneIndex.x)][1].xyz,
+                       m_BoneMatrices[int(inHWBoneIndex.x)][2].xyz) * normal);
 #else
         mat4 mat = mat4(0.0);
-        mat += m_BoneMatrices[int(inBoneIndex.x)] * inBoneWeight.x;
-        mat += m_BoneMatrices[int(inBoneIndex.y)] * inBoneWeight.y;
-        mat += m_BoneMatrices[int(inBoneIndex.z)] * inBoneWeight.z;
-        mat += m_BoneMatrices[int(inBoneIndex.w)] * inBoneWeight.w;
+        mat += m_BoneMatrices[int(inHWBoneIndex.x)] * inHWBoneWeight.x;
+        mat += m_BoneMatrices[int(inHWBoneIndex.y)] * inHWBoneWeight.y;
+        mat += m_BoneMatrices[int(inHWBoneIndex.z)] * inHWBoneWeight.z;
+        mat += m_BoneMatrices[int(inHWBoneIndex.w)] * inHWBoneWeight.w;
         position = mat * position;
 
         mat3 rotMat = mat3(mat[0].xyz, mat[1].xyz, mat[2].xyz);
@@ -47,19 +47,19 @@ void Skinning_Compute(inout vec4 position, inout vec3 normal){
 }
  
 void Skinning_Compute(inout vec4 position, inout vec3 tangent, inout vec3 normal){
-    if (inBoneWeight.x != 0.0) {
+    if (inHWBoneWeight.x != 0.0) {
 #if NUM_WEIGHTS_PER_VERT == 1
-        position = m_BoneMatrices[int(inBoneIndex.x)] * position;
-        tangent = m_BoneMatrices[int(inBoneIndex.x)] * tangent;
-        normal = (mat3(m_BoneMatrices[int(inBoneIndex.x)][0].xyz,
-                       m_BoneMatrices[int(inBoneIndex.x)][1].xyz,
-                       m_BoneMatrices[int(inBoneIndex.x)][2].xyz) * normal);
+        position = m_BoneMatrices[int(inHWBoneIndex.x)] * position;
+        tangent = m_BoneMatrices[int(inHWBoneIndex.x)] * tangent;
+        normal = (mat3(m_BoneMatrices[int(inHWBoneIndex.x)][0].xyz,
+                       m_BoneMatrices[int(inHWBoneIndex.x)][1].xyz,
+                       m_BoneMatrices[int(inHWBoneIndex.x)][2].xyz) * normal);
 #else
         mat4 mat = mat4(0.0);
-        mat += m_BoneMatrices[int(inBoneIndex.x)] * inBoneWeight.x;
-        mat += m_BoneMatrices[int(inBoneIndex.y)] * inBoneWeight.y;
-        mat += m_BoneMatrices[int(inBoneIndex.z)] * inBoneWeight.z;
-        mat += m_BoneMatrices[int(inBoneIndex.w)] * inBoneWeight.w;
+        mat += m_BoneMatrices[int(inHWBoneIndex.x)] * inHWBoneWeight.x;
+        mat += m_BoneMatrices[int(inHWBoneIndex.y)] * inHWBoneWeight.y;
+        mat += m_BoneMatrices[int(inHWBoneIndex.z)] * inHWBoneWeight.z;
+        mat += m_BoneMatrices[int(inHWBoneIndex.w)] * inHWBoneWeight.w;
         position = mat * position;
 
         mat3 rotMat = mat3(mat[0].xyz, mat[1].xyz, mat[2].xyz);
diff --git a/engine/src/core/com/jme3/scene/Mesh.java b/engine/src/core/com/jme3/scene/Mesh.java
index 7076b7fdc..527e103c5 100644
--- a/engine/src/core/com/jme3/scene/Mesh.java
+++ b/engine/src/core/com/jme3/scene/Mesh.java
@@ -353,28 +353,6 @@ public class Mesh implements Savable, Cloneable {
      */
     public void prepareForAnim(boolean forSoftwareAnim){
         if (forSoftwareAnim) {
-            // convert indices to ubytes on the heap
-            VertexBuffer indices = getBuffer(Type.BoneIndex);
-            if (!indices.getData().hasArray()) {
-                ByteBuffer originalIndex = (ByteBuffer) indices.getData();
-                ByteBuffer arrayIndex = ByteBuffer.allocate(originalIndex.capacity());
-                originalIndex.clear();
-                arrayIndex.put(originalIndex);
-                indices.updateData(arrayIndex);
-            }
-            indices.setUsage(Usage.CpuOnly);
-
-            // convert weights on the heap
-            VertexBuffer weights = getBuffer(Type.BoneWeight);
-            if (!weights.getData().hasArray()) {
-                FloatBuffer originalWeight = (FloatBuffer) weights.getData();
-                FloatBuffer arrayWeight = FloatBuffer.allocate(originalWeight.capacity());
-                originalWeight.clear();
-                arrayWeight.put(originalWeight);
-                weights.updateData(arrayWeight);
-            }
-            weights.setUsage(Usage.CpuOnly);
-            
             // position, normal, and tanget buffers to be in "Stream" mode
             VertexBuffer positions = getBuffer(Type.Position);
             VertexBuffer normals = getBuffer(Type.Normal);
@@ -387,25 +365,27 @@ public class Mesh implements Savable, Cloneable {
                 tangents.setUsage(Usage.Stream);
             }
         } else {
-            VertexBuffer indices = getBuffer(Type.BoneIndex);
-            if (!indices.getData().isDirect()) {
+            //if HWBoneIndex and HWBoneWieght are empty, we setup them as direct
+            //buffers with software anim buffers data 
+            VertexBuffer indicesHW = getBuffer(Type.HWBoneIndex);
+            if(indicesHW.getData() == null){
+                VertexBuffer indices = getBuffer(Type.BoneIndex);
                 ByteBuffer originalIndex = (ByteBuffer) indices.getData();
                 ByteBuffer directIndex = BufferUtils.createByteBuffer(originalIndex.capacity());
                 originalIndex.clear();
                 directIndex.put(originalIndex);
-                indices.updateData(directIndex);
+                indicesHW.setupData(Usage.Static, indices.getNumComponents(), indices.getFormat(), directIndex);
             }
-            indices.setUsage(Usage.Static);
             
-            VertexBuffer weights = getBuffer(Type.BoneWeight);
-            if (!weights.getData().isDirect()) {
+            VertexBuffer weightsHW = getBuffer(Type.HWBoneWeight);
+             if(weightsHW.getData() == null){
+                VertexBuffer weights = getBuffer(Type.BoneWeight);
                 FloatBuffer originalWeight = (FloatBuffer) weights.getData();
                 FloatBuffer directWeight = BufferUtils.createFloatBuffer(originalWeight.capacity());
                 originalWeight.clear();
                 directWeight.put(originalWeight);
-                weights.updateData(directWeight);
-            }
-            weights.setUsage(Usage.Static);
+                weightsHW.setupData(Usage.Static, weights.getNumComponents(), weights.getFormat(), directWeight);       
+            }           
             
             // position, normal, and tanget buffers to be in "Static" mode
             VertexBuffer positions = getBuffer(Type.Position);
diff --git a/engine/src/core/com/jme3/scene/VertexBuffer.java b/engine/src/core/com/jme3/scene/VertexBuffer.java
index 6405fd7aa..2ea6ab871 100644
--- a/engine/src/core/com/jme3/scene/VertexBuffer.java
+++ b/engine/src/core/com/jme3/scene/VertexBuffer.java
@@ -135,7 +135,7 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
          
         /** 
          * Bone weights, used with animation (4 floats).
-         * If used with software skinning, the usage should be 
+         * Only used for software skinning, the usage should be 
          * {@link Usage#CpuOnly}, and the buffer should be allocated
          * on the heap.
          */
@@ -143,10 +143,9 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
 
         /** 
          * Bone indices, used with animation (4 ubytes).
-         * If used with software skinning, the usage should be 
+         * Only used for software skinning, the usage should be 
          * {@link Usage#CpuOnly}, and the buffer should be allocated
-         * on the heap as a ubytes buffer. For Hardware skinning this should be
-         * either an int or float buffer due to shader attribute types restrictions.
+         * on the heap as a ubytes buffer.
          */
         BoneIndex,
 
@@ -193,6 +192,19 @@ public class VertexBuffer extends NativeObject implements Savable, Cloneable {
          * on the heap.
          */
         BindPoseTangent,
+        
+        /** 
+         * Bone weights, used with animation (4 floats).
+         * for Hardware Skinning only
+         */
+        HWBoneWeight,
+
+        /** 
+         * Bone indices, used with animation (4 ubytes).
+         * for Hardware Skinning only
+         * either an int or float buffer due to shader attribute types restrictions.
+         */
+        HWBoneIndex,
     }
 
     /**
diff --git a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
index 70e73709b..5f2653281 100644
--- a/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
+++ b/engine/src/ogre/com/jme3/scene/plugins/ogre/MeshLoader.java
@@ -72,7 +72,6 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
 
     private static final Logger logger = Logger.getLogger(MeshLoader.class.getName());
     public static boolean AUTO_INTERLEAVE = true;
-    public static boolean HARDWARE_SKINNING = false;
     private static final Type[] TEXCOORD_TYPES =
             new Type[]{
         Type.TexCoord,
@@ -371,24 +370,28 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
         // each vertex has
         // - 4 bone weights
         // - 4 bone indices
-        if (HARDWARE_SKINNING) {
-            weightsFloatData = BufferUtils.createFloatBuffer(vertCount * 4);
-            indicesData = BufferUtils.createByteBuffer(vertCount * 4);
-        } else {
-            // create array-backed buffers if software skinning for access speed
-            weightsFloatData = FloatBuffer.allocate(vertCount * 4);
-            indicesData = ByteBuffer.allocate(vertCount * 4);
-        }
+        // create array-backed buffers for software skinning for access speed
+        weightsFloatData = FloatBuffer.allocate(vertCount * 4);
+        indicesData = ByteBuffer.allocate(vertCount * 4);
 
         VertexBuffer weights = new VertexBuffer(Type.BoneWeight);
         VertexBuffer indices = new VertexBuffer(Type.BoneIndex);
 
-        Usage usage = HARDWARE_SKINNING ? Usage.Static : Usage.CpuOnly;
-        weights.setupData(usage, 4, Format.Float, weightsFloatData);
-        indices.setupData(usage, 4, Format.UnsignedByte, indicesData);
-
+        weights.setupData(Usage.CpuOnly, 4, Format.Float, weightsFloatData);
+        indices.setupData(Usage.CpuOnly, 4, Format.UnsignedByte, indicesData);
+        
         mesh.setBuffer(weights);
         mesh.setBuffer(indices);
+        
+        //creating empty buffers for HW skinning 
+        //the buffers will be setup if ever used.
+        VertexBuffer weightsHW = new VertexBuffer(Type.HWBoneWeight);
+        VertexBuffer indicesHW = new VertexBuffer(Type.HWBoneIndex);
+        //setting usage to cpuOnly so that the buffer is not send empty to the GPU
+        indicesHW.setUsage(Usage.CpuOnly);
+        weightsHW.setUsage(Usage.CpuOnly);
+        mesh.setBuffer(weightsHW);
+        mesh.setBuffer(indicesHW);
     }
 
     private void startVertexBuffer(Attributes attribs) throws SAXException {
@@ -773,10 +776,6 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
                 m.extractVertexData(sharedMesh);
             }
 
-            // Old code for buffer sharer
-            //if (sharedMesh != null && isUsingSharedVerts(g)) {
-            //    m.setBound(sharedMesh.getBound().clone());
-            //}
             model.attachChild(geoms.get(i));
         }
 
@@ -785,26 +784,19 @@ public class MeshLoader extends DefaultHandler implements AssetLoader {
         if (animData != null) {
             // This model uses animation
 
-            // Old code for buffer sharer
-            // generate bind pose for mesh
-            // ONLY if not using shared geometry
-            // This includes the shared geoemtry itself actually
-            //if (sharedMesh != null) {
-            //    sharedMesh.generateBindPose(!HARDWARE_SKINNING);
-            //}
-
             for (int i = 0; i < geoms.size(); i++) {
                 Geometry g = geoms.get(i);
                 Mesh m = geoms.get(i).getMesh();
+                
+                //FIXME the parameter is now useless.
+                //It was !HADWARE_SKINNING before, but since toggleing 
+                //HW skinning does not happen at load time it was always true.
+                //We should use something similar as for the HWBoneIndex and 
+                //HWBoneWeight : create the vertex buffers empty so that they 
+                //are put in the cache, and really populate them the first time 
+                //software skinning is used on the mesh.
+                m.generateBindPose(true);
 
-                m.generateBindPose(!HARDWARE_SKINNING);
-
-                // Old code for buffer sharer
-                //boolean useShared = isUsingSharedVerts(g);
-                //if (!useShared) {
-                // create bind pose
-                //m.generateBindPose(!HARDWARE_SKINNING);
-                //}
             }
 
             // Put the animations in the AnimControl