1package com.jme3.scene.plugins.blender.constraints;
2
3import java.nio.FloatBuffer;
4import java.util.ArrayList;
5import java.util.List;
6
7import com.jme3.animation.Animation;
8import com.jme3.math.Quaternion;
9import com.jme3.math.Vector3f;
10import com.jme3.scene.Geometry;
11import com.jme3.scene.Mesh;
12import com.jme3.scene.Node;
13import com.jme3.scene.Spatial;
14import com.jme3.scene.VertexBuffer.Type;
15import com.jme3.scene.plugins.blender.BlenderContext;
16import com.jme3.scene.plugins.blender.animations.Ipo;
17import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
18import com.jme3.scene.plugins.blender.file.Structure;
19import 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