private static XForm morphXForms(Prefs pPrefs, XForm pXForm1, XForm pXForm2, double pFScl, int pFrame, int pFrames) {
pXForm1 = pXForm1.makeCopy();
pXForm2 = pXForm2.makeCopy();
prepareMorphXForm(pXForm1);
prepareMorphXForm(pXForm2);
XForm res = new XForm();
res.setWeight(morphValue(pXForm1.getWeight(), pXForm2.getWeight(), pFScl));
res.setColor(morphValue(pXForm1.getColor(), pXForm2.getColor(), pFScl));
res.setColorSymmetry(morphValue(pXForm1.getColorSymmetry(), pXForm2.getColorSymmetry(), pFScl));
res.setCoeff00(morphValue(pXForm1.getCoeff00(), pXForm2.getCoeff00(), pFScl));
res.setCoeff01(morphValue(pXForm1.getCoeff01(), pXForm2.getCoeff01(), pFScl));
res.setCoeff10(morphValue(pXForm1.getCoeff10(), pXForm2.getCoeff10(), pFScl));
res.setCoeff11(morphValue(pXForm1.getCoeff11(), pXForm2.getCoeff11(), pFScl));
res.setCoeff20(morphValue(pXForm1.getCoeff20(), pXForm2.getCoeff20(), pFScl));
res.setCoeff21(morphValue(pXForm1.getCoeff21(), pXForm2.getCoeff21(), pFScl));
res.setOpacity(morphValue(pXForm1.getOpacity(), pXForm2.getOpacity(), pFScl));
res.setPostCoeff00(morphValue(pXForm1.getPostCoeff00(), pXForm2.getPostCoeff00(), pFScl));
res.setPostCoeff01(morphValue(pXForm1.getPostCoeff01(), pXForm2.getPostCoeff01(), pFScl));
res.setPostCoeff10(morphValue(pXForm1.getPostCoeff10(), pXForm2.getPostCoeff10(), pFScl));
res.setPostCoeff11(morphValue(pXForm1.getPostCoeff11(), pXForm2.getPostCoeff11(), pFScl));
res.setPostCoeff20(morphValue(pXForm1.getPostCoeff20(), pXForm2.getPostCoeff20(), pFScl));
res.setPostCoeff21(morphValue(pXForm1.getPostCoeff21(), pXForm2.getPostCoeff21(), pFScl));
res.setOpacity(morphValue(pXForm1.getOpacity(), pXForm2.getOpacity(), pFScl));
res.setDrawMode(pFScl >= 0.5 ? pXForm2.getDrawMode() : pXForm1.getDrawMode());
for (int i = 0; i < pXForm1.getModifiedWeights().length; i++) {
res.getModifiedWeights()[i] = morphValue(pXForm1.getModifiedWeights()[i], pXForm2.getModifiedWeights()[i], pFScl);
}
res.clearVariations();
List<Variation> vars1 = new ArrayList<Variation>();
List<Variation> vars2 = new ArrayList<Variation>();
HashMap<String, String> processed = new HashMap<String, String>();
for (int i = 0; i < pXForm1.getVariationCount(); i++) {
Variation var1 = pXForm1.getVariation(i);
String fncName = var1.getFunc().getName();
processed.put(fncName, fncName);
vars1.add(var1);
// search the same func in xForm2
Variation var2 = null;
for (int j = 0; j < pXForm2.getVariationCount(); j++) {
var2 = pXForm2.getVariation(j);
if (var2.getFunc().getName().equals(fncName)) {
break;
}
else {
var2 = null;
}
}
if (var2 != null) {
vars2.add(var2);
}
else {
vars2.add(new Variation(0.0, VariationFuncList.getVariationFuncInstance(var1.getFunc().getName(), true)));
}
}
for (int i = 0; i < pXForm2.getVariationCount(); i++) {
Variation var2 = pXForm2.getVariation(i);
String fncName = var2.getFunc().getName();
if (processed.get(fncName) == null) {
vars2.add(var2);
vars1.add(new Variation(0.0, VariationFuncList.getVariationFuncInstance(var2.getFunc().getName(), true)));
}
}
if (vars1.size() != vars2.size()) {
throw new IllegalStateException();
}
for (int i = 0; i < vars1.size(); i++) {
Variation var1 = vars1.get(i);
Variation var2 = vars2.get(i);
if (!var1.getFunc().getName().equals(var2.getFunc().getName())) {
throw new IllegalStateException();
}
// System.out.println(i + ": " + var1.getFunc().getName() + " " + var1.getAmount() + " " + var2.getAmount());
double amount = morphValue(var1.getAmount(), var2.getAmount(), pFScl);
Variation var = res.addVariation(amount, var1.getFunc());
// params
if (var.getFunc().getParameterNames() != null && var.getFunc().getParameterNames().length > 0) {
Object val[] = var.getFunc().getParameterValues();
Object val1[] = var1.getFunc().getParameterValues();
Object val2[] = var2.getFunc().getParameterValues();