3131 */
3232package com .jme3 .anim ;
3333
34+ import com .jme3 .export .InputCapsule ;
35+ import com .jme3 .export .JmeExporter ;
36+ import com .jme3 .export .JmeImporter ;
37+ import com .jme3 .export .OutputCapsule ;
3438import com .jme3 .export .Savable ;
3539import com .jme3 .material .*;
3640import com .jme3 .renderer .*;
4044import com .jme3 .shader .VarType ;
4145import com .jme3 .util .BufferUtils ;
4246import com .jme3 .util .SafeArrayList ;
43-
47+ import com .jme3 .util .clone .Cloner ;
48+ import java .io .IOException ;
4449import java .nio .FloatBuffer ;
4550import java .util .logging .Level ;
4651import java .util .logging .Logger ;
@@ -59,11 +64,13 @@ public class MorphControl extends AbstractControl implements Savable {
5964 private static final int MAX_MORPH_BUFFERS = 14 ;
6065 private final static float MIN_WEIGHT = 0.005f ;
6166
62- final private SafeArrayList <Geometry > targets = new SafeArrayList <>(Geometry .class );
63- final private TargetLocator targetLocator = new TargetLocator ();
67+ private static final String TAG_APPROXIMATE = "approximateTangents" ;
68+
69+ private SafeArrayList <Geometry > targets = new SafeArrayList <>(Geometry .class );
70+ private TargetLocator targetLocator = new TargetLocator ();
6471
6572 private boolean approximateTangents = true ;
66- final private MatParamOverride nullNumberOfBones = new MatParamOverride (VarType .Int , "NumberOfBones" , null );
73+ private MatParamOverride nullNumberOfBones = new MatParamOverride (VarType .Int , "NumberOfBones" , null );
6774
6875 private float [] tmpPosArray ;
6976 private float [] tmpNormArray ;
@@ -373,6 +380,70 @@ public boolean isApproximateTangents() {
373380 return approximateTangents ;
374381 }
375382
383+ /**
384+ * Callback from {@link com.jme3.util.clone.Cloner} to convert this
385+ * shallow-cloned Control into a deep-cloned one, using the specified Cloner
386+ * and original to resolve copied fields.
387+ *
388+ * @param cloner the Cloner that's cloning this Control (not null, modified)
389+ * @param original the instance from which this Control was shallow-cloned
390+ * (not null, unaffected)
391+ */
392+ @ Override
393+ public void cloneFields (Cloner cloner , Object original ) {
394+ super .cloneFields (cloner , original );
395+
396+ targets = cloner .clone (targets );
397+ targetLocator = new TargetLocator ();
398+ nullNumberOfBones = cloner .clone (nullNumberOfBones );
399+ tmpPosArray = null ;
400+ tmpNormArray = null ;
401+ tmpTanArray = null ;
402+ }
403+
404+ /**
405+ * Create a shallow clone for the JME cloner.
406+ *
407+ * @return a new instance
408+ */
409+ @ Override
410+ public MorphControl jmeClone () {
411+ try {
412+ MorphControl clone = (MorphControl ) super .clone ();
413+ return clone ;
414+ } catch (CloneNotSupportedException exception ) {
415+ throw new RuntimeException (exception );
416+ }
417+ }
418+
419+ /**
420+ * De-serialize this Control from the specified importer, for example when
421+ * loading from a J3O file.
422+ *
423+ * @param importer (not null)
424+ * @throws IOException from the importer
425+ */
426+ @ Override
427+ public void read (JmeImporter importer ) throws IOException {
428+ super .read (importer );
429+ InputCapsule capsule = importer .getCapsule (this );
430+ approximateTangents = capsule .readBoolean (TAG_APPROXIMATE , true );
431+ }
432+
433+ /**
434+ * Serialize this Control to the specified exporter, for example when saving
435+ * to a J3O file.
436+ *
437+ * @param exporter (not null)
438+ * @throws IOException from the exporter
439+ */
440+ @ Override
441+ public void write (JmeExporter exporter ) throws IOException {
442+ super .write (exporter );
443+ OutputCapsule capsule = exporter .getCapsule (this );
444+ capsule .write (approximateTangents , TAG_APPROXIMATE , true );
445+ }
446+
376447 private class TargetLocator extends SceneGraphVisitorAdapter {
377448 @ Override
378449 public void visit (Geometry geom ) {
0 commit comments