Jelajahi Sumber

Feature: constraint applied to a spatial can now also target a bone

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9854 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 13 tahun lalu
induk
melakukan
3563bbf179

+ 2 - 0
engine/src/blender/com/jme3/scene/plugins/blender/animations/ArmatureHelper.java

@@ -57,6 +57,8 @@ import java.util.logging.Logger;
 public class ArmatureHelper extends AbstractBlenderHelper {
 	private static final Logger	LOGGER		= Logger.getLogger(ArmatureHelper.class.getName());
 
+	public static final String ARMETURE_NODE_MARKER = "armeture-node";
+	
 	/** A map of bones and their old memory addresses. */
 	private Map<Bone, Long>		bonesOMAs	= new HashMap<Bone, Long>();
 

+ 4 - 4
engine/src/blender/com/jme3/scene/plugins/blender/constraints/BoneConstraint.java

@@ -27,7 +27,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 /*package*/ class BoneConstraint extends Constraint {
 	private static final Logger LOGGER = Logger.getLogger(BoneConstraint.class.getName());
 	/** The OMA of the target armature. */
-	private Long targetArmatureOMA;
+	protected Long targetArmatureOMA;
 	
 	public BoneConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
 			throws BlenderFileException {
@@ -82,7 +82,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 		Space[] spaces = new Space[] { ownerSpace, targetSpace };
 		
 		//creating animations for current objects if at least on of their parents have an animation
-		for(int i=0;i<bonesOMAs.length;++i) {
+		for (int i = 0; i < bonesOMAs.length; ++i) {
 			Long oma = bonesOMAs[i];
 			if(this.hasAnimation(oma)) {
 				Bone currentBone = blenderContext.getBoneContext(oma).getBone();
@@ -116,7 +116,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 	 *            OMA of the bone
 	 * @return <b>true</b> if the bone has animations and <b>false</b> otherwise
 	 */
-	private boolean hasAnimation(Long boneOMA) {
+	protected boolean hasAnimation(Long boneOMA) {
 		AnimData animData = blenderContext.getAnimData(boneOMA);
 		if(animData != null) {
 			Bone bone = blenderContext.getBoneContext(boneOMA).getBone();
@@ -143,7 +143,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 	 * @param referenceAnimData
 	 *            the object containing the animations
 	 */
-	private void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) {
+	protected void applyAnimData(BoneContext boneContext, Space space, AnimData referenceAnimData) {
 		ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
 		Transform transform = constraintHelper.getBoneTransform(space, boneContext.getBone());
 		

+ 41 - 13
engine/src/blender/com/jme3/scene/plugins/blender/constraints/SpatialConstraint.java

@@ -3,9 +3,11 @@ package com.jme3.scene.plugins.blender.constraints;
 import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.HashMap;
+import java.util.logging.Logger;
 
 import com.jme3.animation.AnimControl;
 import com.jme3.animation.Animation;
+import com.jme3.animation.Bone;
 import com.jme3.animation.SpatialTrack;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Transform;
@@ -13,6 +15,8 @@ import com.jme3.math.Vector3f;
 import com.jme3.scene.Spatial;
 import com.jme3.scene.plugins.blender.BlenderContext;
 import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
+import com.jme3.scene.plugins.blender.animations.ArmatureHelper;
+import com.jme3.scene.plugins.blender.animations.BoneContext;
 import com.jme3.scene.plugins.blender.animations.Ipo;
 import com.jme3.scene.plugins.blender.constraints.ConstraintHelper.Space;
 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
@@ -24,7 +28,9 @@ import com.jme3.scene.plugins.ogre.AnimData;
  * This includes: nodes, cameras nodes and light nodes.
  * @author Marcin Roguski (Kaelthas)
  */
-/*package*/ class SpatialConstraint extends Constraint {
+/*package*/ class SpatialConstraint extends BoneConstraint {
+	private static final Logger LOGGER = Logger.getLogger(SpatialConstraint.class.getName());
+	
 	/** The owner of the constraint. */
 	private Spatial owner;
 	/** The target of the constraint. */
@@ -33,6 +39,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
 	public SpatialConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
 			throws BlenderFileException {
 		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
+		targetOMA = targetArmatureOMA;//spatial constraint uses only targetOMA and not armatureTargetOMA which is set by BoneConstraint
 	}
 	
 	@Override
@@ -76,20 +83,41 @@ import com.jme3.scene.plugins.ogre.AnimData;
 				AnimData animData = blenderContext.getAnimData(oma);
 				if(animData == null) {
 					Spatial currentSpatial = (Spatial)blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
-					Spatial parent = currentSpatial.getParent();
-					while(parent != null && animData == null) {
-						Structure parentStructure = (Structure)blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE);
-						if(parentStructure == null) {
-							parent = null;
+					if(currentSpatial != null) {
+						if(currentSpatial.getUserData(ArmatureHelper.ARMETURE_NODE_MARKER) == Boolean.TRUE) {//look for it among bones
+							BoneContext currentBoneContext = blenderContext.getBoneByName(subtargetName);
+							Bone currentBone = currentBoneContext.getBone();
+							Bone parent = currentBone.getParent();
+							boolean foundAnimation = false;
+							while(parent != null && !foundAnimation) {
+								BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
+								foundAnimation = this.hasAnimation(boneContext.getBoneOma());
+								animData = blenderContext.getAnimData(boneContext.getBoneOma());
+								parent = parent.getParent();
+							}
+							if(foundAnimation) {
+								this.applyAnimData(currentBoneContext, spaces[i], animData);
+							}
 						} else {
-							Long parentOma = parentStructure.getOldMemoryAddress();
-							animData = blenderContext.getAnimData(parentOma);
-							parent = parent.getParent();
+							Spatial parent = currentSpatial.getParent();
+							while(parent != null && animData == null) {
+								Structure parentStructure = (Structure)blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE);
+								if(parentStructure == null) {
+									parent = null;
+								} else {
+									Long parentOma = parentStructure.getOldMemoryAddress();
+									animData = blenderContext.getAnimData(parentOma);
+									parent = parent.getParent();
+								}
+							}
+							
+							if(animData != null) {//create anim data for the current object
+								this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0));
+							}
 						}
-					}
-					
-					if(animData != null) {//create anim data for the current object
-						this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0));
+					} else {
+						LOGGER.warning("Couldn't find target object for constraint: " + name + 
+									   ". Make sure that the target is on layer that is defined to be loaded in blender key!");
 					}
 				}
 			}

+ 2 - 0
engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

@@ -50,6 +50,7 @@ import com.jme3.scene.Spatial.CullHint;
 import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.BlenderContext;
 import com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType;
+import com.jme3.scene.plugins.blender.animations.ArmatureHelper;
 import com.jme3.scene.plugins.blender.cameras.CameraHelper;
 import com.jme3.scene.plugins.blender.constraints.ConstraintHelper;
 import com.jme3.scene.plugins.blender.curves.CurvesHelper;
@@ -216,6 +217,7 @@ public class ObjectHelper extends AbstractBlenderHelper {
 					//need to create an empty node to properly create parent-children relationships between nodes
 					Node armature = new Node(name);
 					armature.setLocalTransform(t);
+					armature.setUserData(ArmatureHelper.ARMETURE_NODE_MARKER, Boolean.TRUE);
 					//TODO: modifiers for armature ????
 					if(parent instanceof Node) {
 						((Node)parent).attachChild(armature);