159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.constraints;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.nio.FloatBuffer;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.animation.Animation;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Quaternion;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f;
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Geometry;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Mesh;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Node;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.VertexBuffer.Type;
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext;
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.animations.Ipo;
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure;
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.ogre.AnimData;
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class represents 'Shrink wrap' constraint type in blender.
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*package*/ class ConstraintShrinkWrap extends Constraint {
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This constructor creates the constraint instance.
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param constraintStructure
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the constraint's structure (bConstraint clss in blender 2.49).
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param ownerOMA
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the old memory address of the constraint owner
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param influenceIpo
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the ipo curve of the influence factor
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             this exception is thrown when the blender file is somehow
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             corrupted
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA,
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected void bakeConstraint() {
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		//loading mesh points (blender ensures that the target is a mesh-object)
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		List<Vector3f> pts = new ArrayList<Vector3f>();
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Node target = (Node) this.target.getObject();
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		for(Spatial spatial : target.getChildren()) {
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if(spatial instanceof Geometry) {
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Mesh mesh = ((Geometry) spatial).getMesh();
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position);
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for(int i=0;i<floatBuffer.limit();i+=3) {
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					pts.add(new Vector3f(floatBuffer.get(i), floatBuffer.get(i + 1), floatBuffer.get(i + 2)));
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(animData != null) {
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Object owner = this.owner.getObject();
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for(Animation animation : animData.anims) {
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Vector3f[] translations = track.getTranslations();
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Quaternion[] rotations = track.getRotations();
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				int maxFrames = translations.length;
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (int frame = 0; frame < maxFrames; ++frame) {
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Vector3f currentTranslation = translations[frame];
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					//looking for minimum distanced point
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Vector3f minDistancePoint = null;
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					float distance = Float.MAX_VALUE;
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					for(Vector3f p : pts) {
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						float temp = currentTranslation.distance(p);
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						if(temp < distance) {
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							distance = temp;
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							minDistancePoint = p;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					translations[frame] = minDistancePoint.clone();
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				track.setKeyframes(track.getTimes(), translations, rotations, track.getScales());
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		//TODO: static constraint for spatials
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
93