Fix to OGRE mesh animations (de)serializing

Hi everyone,



I found a problem with (de)serializing OGRE mesh (vertex) animations in binary form, caused by some missing default constructors and type casts that do not work. I therefore suggest the following patch, which has made it possible for me to save and load mesh animated models in binary form.



I made the change and tested in jme2.1, but it appears to me that the same code is also used in jme3.



[patch]

Index: src/com/jmex/model/ogrexml/anim/MeshAnimation.java

===================================================================

ā€” src/com/jmex/model/ogrexml/anim/MeshAnimation.java (revision 7487)

+++ src/com/jmex/model/ogrexml/anim/MeshAnimation.java (working copy)

@@ -52,6 +52,13 @@

private float length;

private Track[] tracks;


  • /**
  • * Serialization-only. Do not use.<br />
    
  • */<br />
    
  • public MeshAnimation()
  • {
  • }

    +

    public MeshAnimation(String name, float length){

    this.name = name;

    this.length = length;

    @@ -92,7 +99,13 @@

    InputCapsule in = i.getCapsule(this);

    name = in.readString("name", "");

    length = in.readFloat("length", -1f);
  •    tracks = (Track[]) in.readSavableArray(&quot;tracks&quot;, null);<br />
    

+

  •    Savable[] readSavableArray = in.readSavableArray(&quot;tracks&quot;, null);<br />
    
  •    if (readSavableArray != null)<br />
    
  •    {<br />
    
  •       tracks = new Track[readSavableArray.length];<br />
    
  •       System.arraycopy(readSavableArray, 0, tracks, 0, readSavableArray.length);<br />
    
  •    }<br />
    

}





Index: src/com/jmex/model/ogrexml/anim/Pose.java

===================================================================

ā€” src/com/jmex/model/ogrexml/anim/Pose.java (revision 7487)

+++ src/com/jmex/model/ogrexml/anim/Pose.java (working copy)

@@ -60,6 +60,13 @@

private transient final Vector3f tempVec = new Vector3f();

private transient final Vector3f tempVec2 = new Vector3f();


  • /**
  • * Serialization-only. Do not use.<br />
    
  • */<br />
    
  • public Pose()
  • {
  • }

    +

    public Pose(String name, int targetMeshIndex, Vector3f[] offsets, int[] indices){

    this.name = name;

    this.targetMeshIndex = targetMeshIndex;

    @@ -108,7 +115,14 @@

    InputCapsule in = i.getCapsule(this);

    name = in.readString("name", "");

    targetMeshIndex = in.readInt("meshIndex", -1);
  •    offsets = (Vector3f[]) in.readSavableArray(&quot;offsets&quot;, null);<br />
    

+

  •    Savable[] readSavableArray = in.readSavableArray(&quot;offsets&quot;, null);<br />
    
  •    if (readSavableArray != null)<br />
    
  •    {<br />
    
  •       offsets = new Vector3f[readSavableArray.length];<br />
    
  •       System.arraycopy(readSavableArray, 0, offsets, 0, readSavableArray.length);<br />
    
  •    }<br />
    

+

indices = in.readIntArray("indices", null);

}



Index: src/com/jmex/model/ogrexml/anim/PoseTrack.java

===================================================================

ā€” src/com/jmex/model/ogrexml/anim/PoseTrack.java (revision 7487)

+++ src/com/jmex/model/ogrexml/anim/PoseTrack.java (working copy)

@@ -32,6 +32,7 @@



package com.jmex.model.ogrexml.anim;



+import com.jme.math.Vector3f;

import com.jme.util.export.InputCapsule;

import com.jme.util.export.JMEExporter;

import com.jme.util.export.JMEImporter;

@@ -57,6 +58,13 @@

Pose[] poses;

float[] weights;


  •    /**<br />
    
  •     * Serialization-only. Do not use.<br />
    
  •     */<br />
    
  •    public PoseFrame()<br />
    
  •    {<br />
    
  •    }<br />
    

+

public PoseFrame(Pose[] poses, float[] weights){

this.poses = poses;

this.weights = weights;

@@ -70,7 +78,14 @@



public void read(JMEImporter i) throws IOException {

InputCapsule in = i.getCapsule(this);

  •        poses = (Pose[]) in.readSavableArray(&quot;poses&quot;, null);<br />
    

+

  •        Savable[] readSavableArray = in.readSavableArray(&quot;poses&quot;, null);<br />
    
  •        if (readSavableArray != null)<br />
    
  •        {<br />
    
  •           poses = new Pose[readSavableArray.length];<br />
    
  •           System.arraycopy(readSavableArray, 0, poses, 0, readSavableArray.length);<br />
    
  •        }<br />
    

+

weights = in.readFloatArray("weights", null);

}



@@ -87,6 +102,13 @@

}

}


  • /**
  • * Serialization-only. Do not use.<br />
    
  • */<br />
    
  • public PoseTrack()
  • {
  • }

    +

    public PoseTrack(int targetMeshIndex, float[] times, PoseFrame[] frames){

    super(targetMeshIndex);

    this.times = times;

    @@ -145,7 +167,14 @@

    @Override

    public void read(JMEImporter i) throws IOException {

    InputCapsule in = i.getCapsule(this);
  •    frames = (PoseFrame[]) in.readSavableArray(&quot;frames&quot;, null);<br />
    

+

  •    Savable[] readSavableArray = in.readSavableArray(&quot;frames&quot;, null);<br />
    
  •    if (readSavableArray != null)<br />
    
  •    {<br />
    
  •       frames = new PoseFrame[readSavableArray.length];<br />
    
  •       System.arraycopy(readSavableArray, 0, frames, 0, readSavableArray.length);<br />
    
  •    }<br />
    

+

times = in.readFloatArray("times", null);

}



Index: src/com/jmex/model/ogrexml/anim/Track.java

===================================================================

ā€” src/com/jmex/model/ogrexml/anim/Track.java (revision 7487)

+++ src/com/jmex/model/ogrexml/anim/Track.java (working copy)

@@ -48,6 +48,13 @@



protected int targetMeshIndex;


  • /**
  • * Serialization-only. Do not use.<br />
    
  • */<br />
    
  • public Track()
  • {
  • }

    +

    public Track(int targetMeshIndex){

    this.targetMeshIndex = targetMeshIndex;

    }

    [/patch]





    I would also suggest the following minor change to MaterialLoader, because exporting from 3ds max seems to produce special characters not otherwise accepted by the loader.



    [patch]

    Index: src/com/jmex/model/ogrexml/MaterialLoader.java

    ===================================================================

    ā€” src/com/jmex/model/ogrexml/MaterialLoader.java (revision 7487)

    +++ src/com/jmex/model/ogrexml/MaterialLoader.java (working copy)

    @@ -437,7 +437,9 @@

    reader.wordChars(ā€˜0ā€™, ā€˜9ā€™);

    reader.wordChars(ā€˜Aā€™, ā€˜Zā€™);

    reader.wordChars(ā€˜aā€™, ā€˜zā€™);
  •    reader.wordChars('/', '/');<br />
    
  •    reader.wordChars('/', '/');<br />
    
  •    // Add also special characters produced by 3ds max export<br />
    
  •    reader.wordChars('#', '&amp;');<br />
    

reader.eolIsSignificant(true);



reader.nextToken();

[/patch]

1 Like

Okay I committed this to jME3, but those particular classes are not used yet. See issue 131.

jME2 does not receive any updates anymore but we will see if some of this applies to jme3, thanks!