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