|
|
|
@ -32,6 +32,7 @@ |
|
|
|
|
package com.jme3.gde.core.util; |
|
|
|
|
|
|
|
|
|
import com.jme3.animation.AnimControl; |
|
|
|
|
import com.jme3.animation.SkeletonControl; |
|
|
|
|
import com.jme3.gde.core.scene.ApplicationLogHandler.LogLevel; |
|
|
|
|
import com.jme3.scene.Geometry; |
|
|
|
|
import com.jme3.scene.Node; |
|
|
|
@ -39,11 +40,14 @@ import com.jme3.scene.SceneGraphVisitor; |
|
|
|
|
import com.jme3.scene.SceneGraphVisitorAdapter; |
|
|
|
|
import com.jme3.scene.Spatial; |
|
|
|
|
import java.util.ArrayList; |
|
|
|
|
import java.util.concurrent.atomic.AtomicBoolean; |
|
|
|
|
import java.util.logging.Level; |
|
|
|
|
import java.util.logging.Logger; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Various utilities, mostly for operating on Spatials recursively. |
|
|
|
|
* Various utilities, mostly for operating on Spatials recursively and to copy |
|
|
|
|
* data over from "original" spatials (meshes, animations etc.). Mainly used by |
|
|
|
|
* the "external changes" scanner for models. |
|
|
|
|
* |
|
|
|
|
* @author normenhansen |
|
|
|
|
*/ |
|
|
|
@ -79,8 +83,8 @@ public class SpatialUtil { |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Stores ORIGINAL_NAME and ORIGINAL_PATH UserData to all Geometry in loaded |
|
|
|
|
* spatial |
|
|
|
|
* Stores ORIGINAL_NAME and ORIGINAL_PATH UserData to given Spatial and all |
|
|
|
|
* sub-Spatials. |
|
|
|
|
* |
|
|
|
|
* @param spat |
|
|
|
|
*/ |
|
|
|
@ -231,7 +235,7 @@ public class SpatialUtil { |
|
|
|
|
if (other instanceof Node) { |
|
|
|
|
logger.log(Level.INFO, "Attaching {0} to {1} in root {2} to add leaf {3}", new Object[]{s, other, root, leaf}); |
|
|
|
|
//set original path data to leaf and new parents
|
|
|
|
|
for(Spatial spt = leaf; spt != parent; spt = spt.getParent()){ |
|
|
|
|
for (Spatial spt = leaf; spt != parent; spt = spt.getParent()) { |
|
|
|
|
spt.setUserData(ORIGINAL_NAME, spt.getName()); |
|
|
|
|
spt.setUserData(ORIGINAL_PATH, getSpatialPath(spt)); |
|
|
|
|
spt = spt.getParent(); |
|
|
|
@ -254,16 +258,33 @@ public class SpatialUtil { |
|
|
|
|
original.depthFirstTraversal(new SceneGraphVisitor() { |
|
|
|
|
@Override |
|
|
|
|
public void visit(Spatial spat) { |
|
|
|
|
AnimControl animContol = spat.getControl(AnimControl.class); |
|
|
|
|
if (animContol != null) { |
|
|
|
|
Spatial otherSpatial = findTaggedSpatial(root, spat); |
|
|
|
|
if (otherSpatial != null) { |
|
|
|
|
AnimControl myControl = otherSpatial.getControl(AnimControl.class); |
|
|
|
|
if (myControl != null) { |
|
|
|
|
//copy control data
|
|
|
|
|
AnimControl animControl = spat.getControl(AnimControl.class); |
|
|
|
|
if (animControl != null) { |
|
|
|
|
Spatial mySpatial = findTaggedSpatial(root, spat); |
|
|
|
|
if (mySpatial != null) { |
|
|
|
|
//TODO: move attachments: have to scan through all nodes and find the ones
|
|
|
|
|
//where UserData "AttachedBone" == Bone and move it to new Bone
|
|
|
|
|
AnimControl myAnimControl = mySpatial.getControl(AnimControl.class); |
|
|
|
|
SkeletonControl mySkeletonControl = spat.getControl(SkeletonControl.class); |
|
|
|
|
if (mySkeletonControl != null) { |
|
|
|
|
mySpatial.removeControl(mySkeletonControl); |
|
|
|
|
} |
|
|
|
|
if (myAnimControl != null) { |
|
|
|
|
mySpatial.removeControl(myAnimControl); |
|
|
|
|
} |
|
|
|
|
AnimControl newControl = (AnimControl)animControl.cloneForSpatial(mySpatial); |
|
|
|
|
if (mySpatial.getControl(SkeletonControl.class) == null) { |
|
|
|
|
logger.log(Level.INFO, "Adding control for {0}", mySpatial.getName()); |
|
|
|
|
mySpatial.addControl(newControl); |
|
|
|
|
}else{ |
|
|
|
|
logger.log(Level.INFO, "Control for {0} was added automatically", mySpatial.getName()); |
|
|
|
|
} |
|
|
|
|
if (mySpatial.getControl(SkeletonControl.class) == null) { |
|
|
|
|
mySpatial.addControl(new SkeletonControl(animControl.getSkeleton())); |
|
|
|
|
} else { |
|
|
|
|
//copy control
|
|
|
|
|
logger.log(Level.INFO, "SkeletonControl for {0} was added by AnimControl already", mySpatial.getName()); |
|
|
|
|
} |
|
|
|
|
logger.log(LogLevel.USERINFO, "Updated animation for {0}", mySpatial.getName()); |
|
|
|
|
} else { |
|
|
|
|
logger.log(Level.WARNING, "Could not find sibling for {0} in root {1} when trying to apply AnimControl data", new Object[]{spat, root}); |
|
|
|
|
} |
|
|
|
@ -278,6 +299,23 @@ public class SpatialUtil { |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Finds out if a spatial has animations. |
|
|
|
|
* |
|
|
|
|
* @param root |
|
|
|
|
*/ |
|
|
|
|
public static boolean hasAnimations(final Spatial root) { |
|
|
|
|
final AtomicBoolean animFound = new AtomicBoolean(false); |
|
|
|
|
root.depthFirstTraversal(new SceneGraphVisitor() { |
|
|
|
|
public void visit(Spatial spatial) { |
|
|
|
|
if (spatial.getControl(AnimControl.class) != null) { |
|
|
|
|
animFound.set(true); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
return animFound.get(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static class SpatialHolder { |
|
|
|
|
|
|
|
|
|
Spatial spatial; |
|
|
|
|