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 */ ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)42 public ConstraintShrinkWrap(Structure constraintStructure, Long ownerOMA, 43 Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException { 44 super(constraintStructure, ownerOMA, influenceIpo, blenderContext); 45 } 46 47 @Override bakeConstraint()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