Home | History | Annotate | Download | only in constraints
      1 package com.jme3.scene.plugins.blender.constraints;
      2 
      3 import java.nio.FloatBuffer;
      4 import java.util.ArrayList;
      5 import java.util.List;
      6 
      7 import com.jme3.animation.Animation;
      8 import com.jme3.math.Quaternion;
      9 import com.jme3.math.Vector3f;
     10 import com.jme3.scene.Geometry;
     11 import com.jme3.scene.Mesh;
     12 import com.jme3.scene.Node;
     13 import com.jme3.scene.Spatial;
     14 import com.jme3.scene.VertexBuffer.Type;
     15 import com.jme3.scene.plugins.blender.BlenderContext;
     16 import com.jme3.scene.plugins.blender.animations.Ipo;
     17 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
     18 import com.jme3.scene.plugins.blender.file.Structure;
     19 import com.jme3.scene.plugins.ogre.AnimData;
     20 
     21 /**
     22  * This class represents 'Shrink wrap' constraint type in blender.
     23  * @author Marcin Roguski (Kaelthas)
     24  */
     25 /*package*/ class ConstraintShrinkWrap extends Constraint {
     26 
     27 	/**
     28 	 * This constructor creates the constraint instance.
     29 	 *
     30 	 * @param constraintStructure
     31 	 *            the constraint's structure (bConstraint clss in blender 2.49).
     32 	 * @param ownerOMA
     33 	 *            the old memory address of the constraint owner
     34 	 * @param influenceIpo
     35 	 *            the ipo curve of the influence factor
     36 	 * @param blenderContext
     37 	 *            the blender context
     38 	 * @throws BlenderFileException
     39 	 *             this exception is thrown when the blender file is somehow
     40 	 *             corrupted
     41 	 */
     42 	public ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA,
     43 			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
     44 		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
     45 	}
     46 
     47 	@Override
     48 	protected void bakeConstraint() {
     49 		//loading mesh points (blender ensures that the target is a mesh-object)
     50 		List<Vector3f> pts = new ArrayList<Vector3f>();
     51 		Node target = (Node) this.target.getObject();
     52 		for(Spatial spatial : target.getChildren()) {
     53 			if(spatial instanceof Geometry) {
     54 				Mesh mesh = ((Geometry) spatial).getMesh();
     55 				FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position);
     56 				for(int i=0;i<floatBuffer.limit();i+=3) {
     57 					pts.add(new Vector3f(floatBuffer.get(i), floatBuffer.get(i + 1), floatBuffer.get(i + 2)));
     58 				}
     59 			}
     60 		}
     61 
     62 		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
     63 		if(animData != null) {
     64 			Object owner = this.owner.getObject();
     65 			for(Animation animation : animData.anims) {
     66 				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
     67 				Vector3f[] translations = track.getTranslations();
     68 				Quaternion[] rotations = track.getRotations();
     69 				int maxFrames = translations.length;
     70 				for (int frame = 0; frame < maxFrames; ++frame) {
     71 					Vector3f currentTranslation = translations[frame];
     72 
     73 					//looking for minimum distanced point
     74 					Vector3f minDistancePoint = null;
     75 					float distance = Float.MAX_VALUE;
     76 					for(Vector3f p : pts) {
     77 						float temp = currentTranslation.distance(p);
     78 						if(temp < distance) {
     79 							distance = temp;
     80 							minDistancePoint = p;
     81 						}
     82 					}
     83 					translations[frame] = minDistancePoint.clone();
     84 				}
     85 
     86 				track.setKeyframes(track.getTimes(), translations, rotations, track.getScales());
     87 			}
     88 		}
     89 
     90 		//TODO: static constraint for spatials
     91 	}
     92 }
     93