1 package com.jme3.scene.plugins.blender.constraints;
2 
3 import com.jme3.animation.Animation;
4 import com.jme3.math.Transform;
5 import com.jme3.math.Vector3f;
6 import com.jme3.scene.Spatial;
7 import com.jme3.scene.plugins.blender.BlenderContext;
8 import com.jme3.scene.plugins.blender.animations.Ipo;
9 import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
10 import com.jme3.scene.plugins.blender.file.Structure;
11 import com.jme3.scene.plugins.ogre.AnimData;
12 
13 /**
14  * This class represents 'Size limit' constraint type in blender.
15  * @author Marcin Roguski (Kaelthas)
16  */
17 /*package*/ class ConstraintSizeLimit extends Constraint {
18 	private static final int LIMIT_XMIN = 0x01;
19 	private static final int LIMIT_XMAX = 0x02;
20 	private static final int LIMIT_YMIN = 0x04;
21 	private static final int LIMIT_YMAX = 0x08;
22 	private static final int LIMIT_ZMIN = 0x10;
23 	private static final int LIMIT_ZMAX = 0x20;
24 
25 	protected float[][] limits = new float[3][2];
26     protected int flag;
27 
28 	/**
29 	 * This constructor creates the constraint instance.
30 	 *
31 	 * @param constraintStructure
32 	 *            the constraint's structure (bConstraint clss in blender 2.49).
33 	 * @param ownerOMA
34 	 *            the old memory address of the constraint owner
35 	 * @param influenceIpo
36 	 *            the ipo curve of the influence factor
37 	 * @param blenderContext
38 	 *            the blender context
39 	 * @throws BlenderFileException
40 	 *             this exception is thrown when the blender file is somehow
41 	 *             corrupted
42 	 */
ConstraintSizeLimit(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)43 	public ConstraintSizeLimit(Structure constraintStructure, Long ownerOMA,
44 			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
45 		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
46 
47 		flag = ((Number) data.getFieldValue("flag")).intValue();
48 		if(blenderContext.getBlenderKey().isFixUpAxis()) {
49 			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
50 			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
51 			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
52 			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
53 			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
54 			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
55 
56 			//swapping Y and X limits flag in the bitwise flag
57 			int ymin = flag & LIMIT_YMIN;
58 			int ymax = flag & LIMIT_YMAX;
59 			int zmin = flag & LIMIT_ZMIN;
60 			int zmax = flag & LIMIT_ZMAX;
61 			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
62 			flag |= ymin << 2;
63 			flag |= ymax << 2;
64 			flag |= zmin >> 2;
65 			flag |= zmax >> 2;
66 		} else {
67 			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
68 			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
69 			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
70 			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
71 			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
72 			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
73 		}
74 	}
75 
76 	@Override
bakeConstraint()77 	protected void bakeConstraint() {
78 		Object owner = this.owner.getObject();
79 		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
80 		if(animData != null) {
81 			for(Animation animation : animData.anims) {
82 				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
83 				Vector3f[] scales = track.getScales();
84 				int maxFrames = scales.length;
85 				for (int frame = 0; frame < maxFrames; ++frame) {
86 					this.sizeLimit(scales[frame], ipo.calculateValue(frame));
87 				}
88 				track.setKeyframes(track.getTimes(), track.getTranslations(), track.getRotations(), scales);
89 			}
90 		}
91 
92 		if(owner instanceof Spatial) {
93 			Transform ownerTransform = this.owner.getTransform();
94 			this.sizeLimit(ownerTransform.getScale(), ipo.calculateValue(0));
95 			this.owner.applyTransform(ownerTransform);
96 		}
97 	}
98 
sizeLimit(Vector3f scale, float influence)99 	private void sizeLimit(Vector3f scale, float influence) {
100 		if ((flag & LIMIT_XMIN) != 0) {
101 			if (scale.x < limits[0][0]) {
102 				scale.x -= (scale.x - limits[0][0]) * influence;
103 			}
104 		}
105 		if ((flag & LIMIT_XMAX) != 0) {
106 			if (scale.x > limits[0][1]) {
107 				scale.x -= (scale.x - limits[0][1]) * influence;
108 			}
109 		}
110 		if ((flag & LIMIT_YMIN) != 0) {
111 			if (scale.y < limits[1][0]) {
112 				scale.y -= (scale.y - limits[1][0]) * influence;
113 			}
114 		}
115 		if ((flag & LIMIT_YMAX) != 0) {
116 			if (scale.y > limits[1][1]) {
117 				scale.y -= (scale.y - limits[1][1]) * influence;
118 			}
119 		}
120 		if ((flag & LIMIT_ZMIN) != 0) {
121 			if (scale.z < limits[2][0]) {
122 				scale.z -= (scale.z - limits[2][0]) * influence;
123 			}
124 		}
125 		if ((flag & LIMIT_ZMAX) != 0) {
126 			if (scale.z > limits[2][1]) {
127 				scale.z -= (scale.z - limits[2][1]) * influence;
128 			}
129 		}
130 	}
131 }
132