aboutsummaryrefslogtreecommitdiff
path: root/engine/src/blender/com/jme3/scene/plugins/blender/constraints/ConstraintLocLimit.java
blob: 74e2ec1f8c483dafb9702511bb5926d1242a1908 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package com.jme3.scene.plugins.blender.constraints;

import com.jme3.animation.Animation;
import com.jme3.math.Transform;
import com.jme3.math.Vector3f;
import com.jme3.scene.Spatial;
import com.jme3.scene.plugins.blender.BlenderContext;
import com.jme3.scene.plugins.blender.animations.Ipo;
import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
import com.jme3.scene.plugins.blender.file.Structure;
import com.jme3.scene.plugins.ogre.AnimData;

/**
 * This class represents 'Loc limit' constraint type in blender.
 * @author Marcin Roguski (Kaelthas)
 */
/*package*/ class ConstraintLocLimit extends Constraint {
    private static final int LIMIT_XMIN = 0x01;
    private static final int LIMIT_XMAX = 0x02;
    private static final int LIMIT_YMIN = 0x04;
    private static final int LIMIT_YMAX = 0x08;
    private static final int LIMIT_ZMIN = 0x10;
    private static final int LIMIT_ZMAX = 0x20;
    
    protected float[][] limits = new float[3][2];
    protected int flag;
    
	/**
	 * This constructor creates the constraint instance.
	 * 
	 * @param constraintStructure
	 *            the constraint's structure (bConstraint clss in blender 2.49).
	 * @param ownerOMA
	 *            the old memory address of the constraint owner
	 * @param influenceIpo
	 *            the ipo curve of the influence factor
	 * @param blenderContext
	 *            the blender context
	 * @throws BlenderFileException
	 *             this exception is thrown when the blender file is somehow
	 *             corrupted
	 */
	public ConstraintLocLimit(Structure constraintStructure, Long ownerOMA,
			Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
		super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
		
		flag = ((Number) data.getFieldValue("flag")).intValue();
		if(blenderContext.getBlenderKey().isFixUpAxis()) {
			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
			limits[2][0] = -((Number) data.getFieldValue("ymin")).floatValue();
			limits[2][1] = -((Number) data.getFieldValue("ymax")).floatValue();
			limits[1][0] = ((Number) data.getFieldValue("zmin")).floatValue();
			limits[1][1] = ((Number) data.getFieldValue("zmax")).floatValue();
			
			//swapping Y and X limits flag in the bitwise flag
			int ymin = flag & LIMIT_YMIN;
			int ymax = flag & LIMIT_YMAX;
			int zmin = flag & LIMIT_ZMIN;
			int zmax = flag & LIMIT_ZMAX;
			flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
			flag |= ymin << 2;
			flag |= ymax << 2;
			flag |= zmin >> 2;
			flag |= zmax >> 2;
		} else {
			limits[0][0] = ((Number) data.getFieldValue("xmin")).floatValue();
			limits[0][1] = ((Number) data.getFieldValue("xmax")).floatValue();
			limits[1][0] = ((Number) data.getFieldValue("ymin")).floatValue();
			limits[1][1] = ((Number) data.getFieldValue("ymax")).floatValue();
			limits[2][0] = ((Number) data.getFieldValue("zmin")).floatValue();
			limits[2][1] = ((Number) data.getFieldValue("zmax")).floatValue();
		}
	}

	@Override
	protected void bakeConstraint() {
		Object owner = this.owner.getObject();
		AnimData animData = blenderContext.getAnimData(this.owner.getOma());
		if(animData != null) {
			for(Animation animation : animData.anims) {
				BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
				Vector3f[] translations = track.getTranslations();
				int maxFrames = translations.length;
				for (int frame = 0; frame < maxFrames; ++frame) {
					this.locLimit(translations[frame], ipo.calculateValue(frame));
				}
				track.setKeyframes(track.getTimes(), translations, track.getRotations(), track.getScales());
			}
		}
		
		if(owner instanceof Spatial) {
			Transform ownerTransform = this.owner.getTransform();
			Vector3f ownerLocation = ownerTransform.getTranslation();
			this.locLimit(ownerLocation, ipo.calculateValue(0));
			this.owner.applyTransform(ownerTransform);
		}
	}
	
	/**
	 * This method modifies the given translation.
	 * @param translation the translation to be modified.
	 * @param influence the influence value
	 */
	private void locLimit(Vector3f translation, float influence) {
		if ((flag & LIMIT_XMIN) != 0) {
			if (translation.x < limits[0][0]) {
				translation.x -= (translation.x - limits[0][0]) * influence;
			}
		}
		if ((flag & LIMIT_XMAX) != 0) {
			if (translation.x > limits[0][1]) {
				translation.x -= (translation.x - limits[0][1]) * influence;
			}
		}
		if ((flag & LIMIT_YMIN) != 0) {
			if (translation.y < limits[1][0]) {
				translation.y -= (translation.y - limits[1][0]) * influence;
			}
		}
		if ((flag & LIMIT_YMAX) != 0) {
			if (translation.y > limits[1][1]) {
				translation.y -= (translation.y - limits[1][1]) * influence;
			}
		}
		if ((flag & LIMIT_ZMIN) != 0) {
			if (translation.z < limits[2][0]) {
				translation.z -= (translation.z - limits[2][0]) * influence;
			}
		}
		if ((flag & LIMIT_ZMAX) != 0) {
			if (translation.z > limits[2][1]) {
				translation.z -= (translation.z - limits[2][1]) * influence;
			}
		}
	}
}