159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.scene.plugins.blender.constraints; 259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.animation.Bone; 459b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Matrix4f; 559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Quaternion; 659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Transform; 759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.Vector3f; 859b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.Spatial; 959b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext; 1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.BlenderContext.LoadedFeatureDataType; 1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.constraints.Constraint.Space; 1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.DynamicArray; 1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.scene.plugins.blender.file.Structure; 1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/** 1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This class represents either owner or target of the constraint. It has the 1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * common methods that take the evalueation space of the feature. 1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Marcin Roguski (Kaelthas) 2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/* package */class Feature { 2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** The evalueation space. */ 2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Space space; 2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** Old memory address of the feature. */ 2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Long oma; 2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** The spatial that is hold by the Feature. */ 2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Spatial spatial; 2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** The bone that is hold by the Feature. */ 2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Bone bone; 3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** The blender context. */ 3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected BlenderContext blenderContext; 3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Constructs the feature. This object should be loaded later 3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * when it is read from the blender file. 3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * The update method should be called before the feature is used. 3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param space 3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the spatial's evaluation space 4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param oma 4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the spatial's old memory address 4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param blenderContext 4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the blender context 4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Feature(Space space, Long oma, BlenderContext blenderContext) { 4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.space = space; 4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.oma = oma; 4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.blenderContext = blenderContext; 4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Constructs the feature based on spatial. 5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param spatial 5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the spatial 5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param space 5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the spatial's evaluation space 5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param oma 5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the spatial's old memory address 6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param blenderContext 6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the blender context 6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Feature(Spatial spatial, Space space, Long oma, BlenderContext blenderContext) { 6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(space, oma, blenderContext); 6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.blenderContext = blenderContext; 6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Constructs the feature based on bone. 7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param bone 7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the bone 7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param space 7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the bone evaluation space 7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param oma 7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the bone old memory address 7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param blenderContext 7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the blender context 7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Feature(Bone bone, Space space, Long oma, BlenderContext blenderContext) { 8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this(space, oma, blenderContext); 8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.bone = bone; 8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This method should be called before the feature is used. 8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * It may happen that the object this feature refers to was not yet loaded from blend file 8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * when the instance of this class was created. 8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void update() { 9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Object owner = blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE); 9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if(owner instanceof Spatial) { 9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.spatial = (Spatial) owner; 9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else if(owner instanceof Bone) { 9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta this.bone = (Bone) owner; 9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else { 9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Unknown type of owner: " + owner.getClass()); 9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the feature's old memory address 10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Long getOma() { 10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return oma; 10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the object held by the feature (either bone or spatial) 11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Object getObject() { 11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial != null) { 11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return spatial; 11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return bone; 11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return the feature's transform depending on the evaluation space 12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta @SuppressWarnings("unchecked") 12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Transform getTransform() { 12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial != null) { 12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (space) { 12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_LOCAL: 12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Structure targetStructure = (Structure) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_STRUCTURE); 12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta DynamicArray<Number> locArray = ((DynamicArray<Number>) targetStructure.getFieldValue("loc")); 12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f loc = new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), locArray.get(2).floatValue()); 13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta DynamicArray<Number> rotArray = ((DynamicArray<Number>) targetStructure.getFieldValue("rot")); 13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Quaternion rot = new Quaternion(new float[] { rotArray.get(0).floatValue(), rotArray.get(1).floatValue(), rotArray.get(2).floatValue() }); 13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta DynamicArray<Number> sizeArray = ((DynamicArray<Number>) targetStructure.getFieldValue("size")); 13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f size = new Vector3f(sizeArray.get(0).floatValue(), sizeArray.get(1).floatValue(), sizeArray.get(2).floatValue()); 13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (blenderContext.getBlenderKey().isFixUpAxis()) { 13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float y = loc.y; 13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta loc.y = loc.z; 13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta loc.z = -y; 13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta y = rot.getY(); 14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float z = rot.getZ(); 14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta rot.set(rot.getX(), z, -y, rot.getW()); 14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta y = size.y; 14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta size.y = size.z; 14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta size.z = y; 14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform result = new Transform(loc, rot); 15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setScale(size); 15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_WORLD: 15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return spatial.getWorldTransform(); 15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Invalid space type for target object: " + space.toString()); 15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Bone 15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (space) { 16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_LOCAL: 16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); 16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta localTransform.setScale(bone.getLocalScale()); 16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return localTransform; 16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_WORLD: 16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform worldTransform = new Transform(bone.getWorldBindPosition(), bone.getWorldBindRotation()); 16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta worldTransform.setScale(bone.getWorldBindScale()); 16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return worldTransform; 16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_POSE: 16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform poseTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); 17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta poseTransform.setScale(bone.getLocalScale()); 17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return poseTransform; 17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_PARLOCAL: 17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform parentLocalTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation()); 17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta parentLocalTransform.setScale(bone.getLocalScale()); 17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return parentLocalTransform; 17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Invalid space type for target object: " + space.toString()); 17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * This method applies the given transform to the feature in the proper 18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * evaluation space. 18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param transform 18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the transform to be applied 18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public void applyTransform(Transform transform) { 18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial != null) { 19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (space) { 19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_LOCAL: 19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform ownerLocalTransform = spatial.getLocalTransform(); 19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ownerLocalTransform.getTranslation().addLocal(transform.getTranslation()); 19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ownerLocalTransform.getRotation().multLocal(transform.getRotation()); 19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta ownerLocalTransform.getScale().multLocal(transform.getScale()); 19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_WORLD: 19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f m = this.getParentWorldTransformMatrix(); 19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.invertLocal(); 20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f matrix = this.toMatrix(transform); 20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta m.multLocal(matrix); 20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float scaleX = (float) Math.sqrt(m.m00 * m.m00 + m.m10 * m.m10 + m.m20 * m.m20); 20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float scaleY = (float) Math.sqrt(m.m01 * m.m01 + m.m11 * m.m11 + m.m21 * m.m21); 20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta float scaleZ = (float) Math.sqrt(m.m02 * m.m02 + m.m12 * m.m12 + m.m22 * m.m22); 20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setTranslation(m.toTranslationVector()); 20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setRotation(m.toRotationQuat()); 20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setScale(scaleX, scaleY, scaleZ); 21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta spatial.setLocalTransform(transform); 21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_PARLOCAL: 21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_POSE: 21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Invalid space type (" + space.toString() + ") for owner object."); 21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Invalid space type for target object: " + space.toString()); 21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else {// Bone 21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta switch (space) { 22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_LOCAL: 22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); 22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_WORLD: 22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f m = this.getParentWorldTransformMatrix(); 22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// m.invertLocal(); 22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setTranslation(m.mult(transform.getTranslation())); 22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setRotation(m.mult(transform.getRotation(), null)); 22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta transform.setScale(transform.getScale()); 22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); 23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float x = FastMath.HALF_PI/2; 23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float y = -FastMath.HALF_PI; 23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// float z = -FastMath.HALF_PI/2; 23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta// bone.setBindTransforms(new Vector3f(0,0,0), new Quaternion().fromAngles(x, y, z), new Vector3f(1,1,1)); 23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_PARLOCAL: 23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Vector3f parentLocalTranslation = bone.getLocalPosition().add(transform.getTranslation()); 23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Quaternion parentLocalRotation = bone.getLocalRotation().mult(transform.getRotation()); 23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bone.setBindTransforms(parentLocalTranslation, parentLocalRotation, transform.getScale()); 23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta case CONSTRAINT_SPACE_POSE: 24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale()); 24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta break; 24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta default: 24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta throw new IllegalStateException("Invalid space type for target object: " + space.toString()); 24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return world transform matrix of the feature 25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Matrix4f getWorldTransformMatrix() { 25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial != null) { 25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f result = new Matrix4f(); 25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform t = spatial.getWorldTransform(); 25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix()); 25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta // Bone 26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f result = new Matrix4f(); 26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setTransform(bone.getWorldBindPosition(), bone.getWorldBindScale(), bone.getWorldBindRotation().toRotationMatrix()); 26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return world transform matrix of the feature's parent or identity matrix 26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * if the feature has no parent 26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta public Matrix4f getParentWorldTransformMatrix() { 27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f result = new Matrix4f(); 27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial != null) { 27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (spatial.getParent() != null) { 27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Transform t = spatial.getParent().getWorldTransform(); 27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setTransform(t.getTranslation(), t.getScale(), t.getRotation().toRotationMatrix()); 27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } else {// Bone 27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Bone parent = bone.getParent(); 27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (parent != null) { 27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setTransform(parent.getWorldBindPosition(), parent.getWorldBindScale(), parent.getWorldBindRotation().toRotationMatrix()); 28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta 28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta /** 28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Converts given transform to the matrix. 28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * 28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @param transform 28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the transform to be converted 29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @return 4x4 matri that represents the given transform 29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */ 29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta protected Matrix4f toMatrix(Transform transform) { 29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta Matrix4f result = Matrix4f.IDENTITY; 29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta if (transform != null) { 29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result = new Matrix4f(); 29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setTranslation(transform.getTranslation()); 29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setRotationQuaternion(transform.getRotation()); 29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta result.setScale(transform.getScale()); 29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta return result; 30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta } 30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta} 303