2
0
Эх сурвалжийг харах

Implementation of shrinkwrap constraint (+ several bugfixes and updated test asset file).

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7686 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
Kae..pl 14 жил өмнө
parent
commit
4a9f7ab979

+ 53 - 4
engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java

@@ -1,9 +1,11 @@
 package com.jme3.scene.plugins.blender.helpers.v249;
 
+import java.nio.FloatBuffer;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
+import java.util.logging.Level;
 
 import com.jme3.animation.Bone;
 import com.jme3.animation.BoneAnimation;
@@ -12,8 +14,11 @@ import com.jme3.animation.Skeleton;
 import com.jme3.math.FastMath;
 import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
+import com.jme3.scene.Geometry;
+import com.jme3.scene.Mesh;
 import com.jme3.scene.Node;
 import com.jme3.scene.Spatial;
+import com.jme3.scene.VertexBuffer.Type;
 import com.jme3.scene.plugins.blender.data.Structure;
 import com.jme3.scene.plugins.blender.exception.BlenderFileException;
 import com.jme3.scene.plugins.blender.structures.AbstractInfluenceFunction;
@@ -23,8 +28,8 @@ import com.jme3.scene.plugins.blender.structures.ConstraintType;
 import com.jme3.scene.plugins.blender.structures.Ipo;
 import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
 import com.jme3.scene.plugins.blender.utils.DataRepository;
+import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
 import com.jme3.scene.plugins.blender.utils.Pointer;
-import java.util.logging.Level;
 
 /**
  * This class should be used for constraint calculations.
@@ -404,7 +409,6 @@ public class ConstraintHelper extends AbstractBlenderHelper {
 
 			//ROTLIMIT constraint
 			influenceFunctions[ConstraintType.CONSTRAINT_TYPE_ROTLIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_ROTLIMIT, dataRepository) {
-
 				@Override
 				public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
 					Structure constraintStructure = constraint.getData();
@@ -459,11 +463,57 @@ public class ConstraintHelper extends AbstractBlenderHelper {
 
 			//SHRINKWRAP constraint (TODO: to implement)
 			influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP, dataRepository) {
+				@Override
+				public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
+					Structure constraintStructure = constraint.getData();
+					this.validateConstraintType(constraintStructure);
+					
+					//loading mesh points (blender ensures that the target is a mesh-object)
+					List<Vector3f> pts = new ArrayList<Vector3f>();
+					try {
+						Node node = (Node)this.getTarget(constraint, LoadedFeatureDataType.LOADED_FEATURE);
+						for(Spatial spatial : node.getChildren()) {
+							if(spatial instanceof Geometry) {
+								Mesh mesh = ((Geometry) spatial).getMesh();
+								FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position);
+								for(int i=0;i<floatBuffer.limit();i+=3) {
+									pts.add(new Vector3f(floatBuffer.get(i), floatBuffer.get(i + 1), floatBuffer.get(i + 2)));
+								}
+							}
+						}
+						
+						//modifying traces
+						BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
+						if (boneTrack != null) {
+							Vector3f[] translations = boneTrack.getTranslations();
+							Quaternion[] rotations = boneTrack.getRotations();
+							int maxFrames = translations.length;
+							for (int frame = 0; frame < maxFrames; ++frame) {
+								Vector3f currentTranslation = translations[frame];
+								
+								//looking for minimum distanced point
+								Vector3f minDistancePoint = null;
+								float distance = Float.MAX_VALUE;
+								for(Vector3f p : pts) {
+									float temp = currentTranslation.distance(p);
+									if(temp < distance) {
+										distance = temp;
+										minDistancePoint = p;
+									}
+								}
+								translations[frame] = minDistancePoint.clone();
+							}
+							
+							boneTrack.setKeyframes(boneTrack.getTimes(), translations, rotations, boneTrack.getScales());
+						}
+					} catch (BlenderFileException e) {
+						LOGGER.severe(e.getLocalizedMessage());
+					}
+				}
 			};
 
 			//SIZELIKE constraint
 			influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SIZELIKE.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SIZELIKE, dataRepository) {
-
 				@Override
 				public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
 					Structure constraintData = constraint.getData();
@@ -497,7 +547,6 @@ public class ConstraintHelper extends AbstractBlenderHelper {
 
 			//SIZELIMIT constraint
 			influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SIZELIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SIZELIMIT, dataRepository) {
-
 				@Override
 				public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
 					Structure constraintStructure = constraint.getData();

+ 16 - 6
engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java

@@ -10,6 +10,8 @@ import com.jme3.math.Quaternion;
 import com.jme3.math.Vector3f;
 import com.jme3.scene.Node;
 import com.jme3.scene.plugins.blender.data.Structure;
+import com.jme3.scene.plugins.blender.exception.BlenderFileException;
+import com.jme3.scene.plugins.blender.helpers.v249.ObjectHelper;
 import com.jme3.scene.plugins.blender.structures.Constraint.Space;
 import com.jme3.scene.plugins.blender.utils.DataRepository;
 import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
@@ -134,15 +136,23 @@ public abstract class AbstractInfluenceFunction {
      * @param constraint
      *        the constraint instance
      * @return target or subtarget feature
+     * @throws BlenderFileException this exception is thrown if the blend file is somehow corrupted
      */
-    protected Object getTarget(Constraint constraint, LoadedFeatureDataType loadedFeatureDataType) {
-        Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
-        Object targetObject = dataRepository.getLoadedFeature(targetOMA, loadedFeatureDataType);
-        String subtargetName = constraint.getData().getFieldValue("subtarget").toString();
-        if (subtargetName.length() > 0) {
+    protected Object getTarget(Constraint constraint, LoadedFeatureDataType loadedFeatureDataType) throws BlenderFileException {
+    	//TODO: load the feature through objectHelper, this way we are certain the object loads and has
+    	//his own constraints applied to traces
+    	ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
+    	//subtarget goes first
+    	Object subtarget = constraint.getData().getFieldValue("subtarget");
+    	String subtargetName = subtarget==null ? null : subtarget.toString();
+        if (subtargetName!=null && subtargetName.length() > 0) {
+        	//TODO: what if it is not yet loaded ???
             return dataRepository.getLoadedFeature(subtargetName, loadedFeatureDataType);
         }
-        return targetObject;
+        //and now use the target
+        Long targetOMA = ((Pointer) constraint.getData().getFieldValue("target")).getOldMemoryAddress();
+        Structure objectStructure = dataRepository.getFileBlock(targetOMA).getStructure(dataRepository);
+        return objectHelper.toObject(objectStructure, dataRepository);
     }
 
     /**

BIN
engine/src/test-data/Blender/2.4x/constraints.blend