159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.constraints;
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.lang.reflect.InvocationTargetException;
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.ArrayList;
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.HashMap;
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.List;
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.Map;
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.logging.Logger;
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.AbstractBlenderHelper;
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext;
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.animations.Ipo;
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.animations.IpoHelper;
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Pointer;
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure;
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class should be used for constraint calculations.
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas)
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic class ConstraintHelper extends AbstractBlenderHelper {
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final Logger LOGGER = Logger.getLogger(ConstraintHelper.class.getName());
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	private static final Map<String, Class<? extends Constraint>> constraintClasses = new HashMap<String, Class<? extends Constraint>>(22);
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	static {
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bActionConstraint", ConstraintAction.class);
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bChildOfConstraint", ConstraintChildOf.class);
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bClampToConstraint", ConstraintClampTo.class);
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bDistLimitConstraint", ConstraintDistLimit.class);
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bFollowPathConstraint", ConstraintFollowPath.class);
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bKinematicConstraint", ConstraintInverseKinematics.class);
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bLockTrackConstraint", ConstraintLockTrack.class);
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bLocateLikeConstraint", ConstraintLocLike.class);
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bLocLimitConstraint", ConstraintLocLimit.class);
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bMinMaxConstraint", ConstraintMinMax.class);
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bNullConstraint", ConstraintNull.class);
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bPythonConstraint", ConstraintPython.class);
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bRigidBodyJointConstraint", ConstraintRigidBodyJoint.class);
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bRotateLikeConstraint", ConstraintRotLike.class);
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bShrinkWrapConstraint", ConstraintShrinkWrap.class);
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bSizeLikeConstraint", ConstraintSizeLike.class);
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bSizeLimitConstraint", ConstraintSizeLimit.class);
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bStretchToConstraint", ConstraintStretchTo.class);
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bTransformConstraint", ConstraintTransform.class);
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bRotLimitConstraint", ConstraintRotLimit.class);
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		//Blender 2.50+
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bSplineIKConstraint", ConstraintSplineInverseKinematic.class);
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bDampTrackConstraint", ConstraintDampTrack.class);
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		constraintClasses.put("bPivotConstraint", ConstraintDampTrack.class);
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * Helper constructor. It's main task is to generate the affection functions. These functions are common to all
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * ConstraintHelper instances. Unfortunately this constructor might grow large. If it becomes too large - I shall
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * consider refactoring. The constructor parses the given blender version and stores the result. Some
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * functionalities may differ in different blender versions.
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderVersion
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *        the version read from the blend file
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param fixUpAxis
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *        a variable that indicates if the Y asxis is the UP axis or not
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public ConstraintHelper(String blenderVersion, BlenderContext blenderContext, boolean fixUpAxis) {
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		super(blenderVersion, fixUpAxis);
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method reads constraints for for the given structure. The
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * constraints are loaded only once for object/bone.
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param objectStructure
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the structure we read constraint's for
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public void loadConstraints(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		LOGGER.fine("Loading constraints.");
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		// reading influence ipos for the constraints
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Map<String, Map<String, Ipo>> constraintsIpos = new HashMap<String, Map<String, Ipo>>();
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Pointer pActions = (Pointer) objectStructure.getFieldValue("action");
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (pActions.isNotNull()) {
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			List<Structure> actions = pActions.fetchData(blenderContext.getInputStream());
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for (Structure action : actions) {
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Structure chanbase = (Structure) action.getFieldValue("chanbase");
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Structure> actionChannels = chanbase.evaluateListBase(blenderContext);
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Structure actionChannel : actionChannels) {
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Map<String, Ipo> ipos = new HashMap<String, Ipo>();
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Structure constChannels = (Structure) actionChannel.getFieldValue("constraintChannels");
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					List<Structure> constraintChannels = constChannels.evaluateListBase(blenderContext);
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					for (Structure constraintChannel : constraintChannels) {
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						Pointer pIpo = (Pointer) constraintChannel.getFieldValue("ipo");
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						if (pIpo.isNotNull()) {
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							String constraintName = constraintChannel.getFieldValue("name").toString();
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							Ipo ipo = ipoHelper.fromIpoStructure(pIpo.fetchData(blenderContext.getInputStream()).get(0), blenderContext);
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta							ipos.put(constraintName, ipo);
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						}
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					String actionName = actionChannel.getFieldValue("name").toString();
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					constraintsIpos.put(actionName, ipos);
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		//loading constraints connected with the object's bones
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Pointer pPose = (Pointer) objectStructure.getFieldValue("pose");
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if (pPose.isNotNull()) {
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			List<Structure> poseChannels = ((Structure) pPose.fetchData(blenderContext.getInputStream()).get(0).getFieldValue("chanbase")).evaluateListBase(blenderContext);
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			for (Structure poseChannel : poseChannels) {
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Constraint> constraintsList = new ArrayList<Constraint>();
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				Long boneOMA = Long.valueOf(((Pointer) poseChannel.getFieldValue("bone")).getOldMemoryAddress());
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				//the name is read directly from structure because bone might not yet be loaded
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				String name = blenderContext.getFileBlock(boneOMA).getStructure(blenderContext).getFieldValue("name").toString();
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				List<Structure> constraints = ((Structure) poseChannel.getFieldValue("constraints")).evaluateListBase(blenderContext);
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				for (Structure constraint : constraints) {
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					String constraintName = constraint.getFieldValue("name").toString();
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Map<String, Ipo> ipoMap = constraintsIpos.get(name);
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					Ipo ipo = ipoMap==null ? null : ipoMap.get(constraintName);
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					if (ipo == null) {
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						ipo = ipoHelper.fromValue(enforce);
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					}
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta					constraintsList.add(this.createConstraint(constraint, boneOMA, ipo, blenderContext));
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				}
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				blenderContext.addConstraints(boneOMA, constraintsList);
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		//loading constraints connected with the object itself
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		List<Structure> constraints = ((Structure)objectStructure.getFieldValue("constraints")).evaluateListBase(blenderContext);
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		for(Structure constraint : constraints) {
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			String constraintName = constraint.getFieldValue("name").toString();
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			String objectName = objectStructure.getName();
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null;
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			if (ipo == null) {
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				ipo = ipoHelper.fromValue(enforce);
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			constraintsList.add(this.createConstraint(constraint, objectStructure.getOldMemoryAddress(), ipo, blenderContext));
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		blenderContext.addConstraints(objectStructure.getOldMemoryAddress(), constraintsList);
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	/**
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * This method creates the constraint instance.
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param constraintStructure
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the constraint's structure (bConstraint clss in blender 2.49).
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param ownerOMA
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the old memory address of the constraint's owner
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param influenceIpo
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the ipo curve of the influence factor
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @param blenderContext
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *            the blender context
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 * @throws BlenderFileException
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             this exception is thrown when the blender file is somehow
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 *             corrupted
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	 */
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected Constraint createConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo,
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						BlenderContext blenderContext) throws BlenderFileException {
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		String constraintClassName = this.getConstraintClassName(constraintStructure, blenderContext);
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Class<? extends Constraint> constraintClass = constraintClasses.get(constraintClassName);
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(constraintClass != null) {
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			try {
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				return (Constraint) constraintClass.getDeclaredConstructors()[0].newInstance(constraintStructure, ownerOMA, influenceIpo,
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta						blenderContext);
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			} catch (IllegalArgumentException e) {
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new BlenderFileException(e.getLocalizedMessage(), e);
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			} catch (SecurityException e) {
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new BlenderFileException(e.getLocalizedMessage(), e);
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			} catch (InstantiationException e) {
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new BlenderFileException(e.getLocalizedMessage(), e);
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			} catch (IllegalAccessException e) {
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new BlenderFileException(e.getLocalizedMessage(), e);
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			} catch (InvocationTargetException e) {
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta				throw new BlenderFileException(e.getLocalizedMessage(), e);
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			}
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		} else {
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			throw new BlenderFileException("Unknown constraint type: " + constraintClassName);
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	protected String getConstraintClassName(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException {
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		Pointer pData = (Pointer)constraintStructure.getFieldValue("data");
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		if(pData.isNotNull()) {
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			Structure data = pData.fetchData(blenderContext.getInputStream()).get(0);
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta			return data.getType();
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		}
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return constraintStructure.getType();
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	@Override
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta		return true;
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta	}
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
204