Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 75 additions & 4 deletions jme3-core/src/main/java/com/jme3/anim/MorphControl.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
*/
package com.jme3.anim;

import com.jme3.export.InputCapsule;
import com.jme3.export.JmeExporter;
import com.jme3.export.JmeImporter;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.material.*;
import com.jme3.renderer.*;
Expand All @@ -40,7 +44,8 @@
import com.jme3.shader.VarType;
import com.jme3.util.BufferUtils;
import com.jme3.util.SafeArrayList;

import com.jme3.util.clone.Cloner;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.logging.Level;
import java.util.logging.Logger;
Expand All @@ -59,11 +64,13 @@ public class MorphControl extends AbstractControl implements Savable {
private static final int MAX_MORPH_BUFFERS = 14;
private final static float MIN_WEIGHT = 0.005f;

final private SafeArrayList<Geometry> targets = new SafeArrayList<>(Geometry.class);
final private TargetLocator targetLocator = new TargetLocator();
private static final String TAG_APPROXIMATE = "approximateTangents";

private SafeArrayList<Geometry> targets = new SafeArrayList<>(Geometry.class);
private TargetLocator targetLocator = new TargetLocator();

private boolean approximateTangents = true;
final private MatParamOverride nullNumberOfBones = new MatParamOverride(VarType.Int, "NumberOfBones", null);
private MatParamOverride nullNumberOfBones = new MatParamOverride(VarType.Int, "NumberOfBones", null);

private float[] tmpPosArray;
private float[] tmpNormArray;
Expand Down Expand Up @@ -373,6 +380,70 @@ public boolean isApproximateTangents() {
return approximateTangents;
}

/**
* Callback from {@link com.jme3.util.clone.Cloner} to convert this
* shallow-cloned Control into a deep-cloned one, using the specified Cloner
* and original to resolve copied fields.
*
* @param cloner the Cloner that's cloning this Control (not null, modified)
* @param original the instance from which this Control was shallow-cloned
* (not null, unaffected)
*/
@Override
public void cloneFields(Cloner cloner, Object original) {
super.cloneFields(cloner, original);

targets = cloner.clone(targets);
targetLocator = new TargetLocator();
nullNumberOfBones = cloner.clone(nullNumberOfBones);
tmpPosArray = null;
tmpNormArray = null;
tmpTanArray = null;
}

/**
* Create a shallow clone for the JME cloner.
*
* @return a new instance
*/
@Override
public MorphControl jmeClone() {
try {
MorphControl clone = (MorphControl) super.clone();
return clone;
} catch (CloneNotSupportedException exception) {
throw new RuntimeException(exception);
}
}

/**
* De-serialize this Control from the specified importer, for example when
* loading from a J3O file.
*
* @param importer (not null)
* @throws IOException from the importer
*/
@Override
public void read(JmeImporter importer) throws IOException {
super.read(importer);
InputCapsule capsule = importer.getCapsule(this);
approximateTangents = capsule.readBoolean(TAG_APPROXIMATE, true);
}

/**
* Serialize this Control to the specified exporter, for example when saving
* to a J3O file.
*
* @param exporter (not null)
* @throws IOException from the exporter
*/
@Override
public void write(JmeExporter exporter) throws IOException {
super.write(exporter);
OutputCapsule capsule = exporter.getCapsule(this);
capsule.write(approximateTangents, TAG_APPROXIMATE, true);
}

private class TargetLocator extends SceneGraphVisitorAdapter {
@Override
public void visit(Geometry geom) {
Expand Down
16 changes: 15 additions & 1 deletion jme3-examples/src/main/java/jme3test/model/anim/TestMorph.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import com.jme3.anim.MorphControl;
import com.jme3.app.ChaseCameraAppState;
import com.jme3.app.SimpleApplication;
import com.jme3.export.binary.BinaryExporter;
import com.jme3.font.BitmapFont;
import com.jme3.font.BitmapText;
import com.jme3.input.KeyInput;
Expand All @@ -16,7 +17,7 @@
import com.jme3.scene.mesh.MorphTarget;
import com.jme3.scene.shape.Box;
import com.jme3.util.BufferUtils;

import com.jme3.util.clone.Cloner;
import java.nio.FloatBuffer;

public class TestMorph extends SimpleApplication {
Expand Down Expand Up @@ -90,6 +91,19 @@ public void simpleInitApp() {

g.setMorphState(weights);
g.addControl(new MorphControl());
/*
* Attach a clone of the morphing box model, in order to test cloning.
*/
Geometry g2 = Cloner.deepClone(g);
g2.move(-4f, 0f, 0f);
rootNode.attachChild(g2);
/*
* Attach a saveAndLoad() copy of the morphing box model,
* in order to test serialization.
*/
Geometry g3 = BinaryExporter.saveAndLoad(assetManager, g);
g3.move(-4f, 4f, 0f);
rootNode.attachChild(g3);

ChaseCameraAppState chase = new ChaseCameraAppState();
chase.setTarget(rootNode);
Expand Down