diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ArmatureHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ArmatureHelper.java index fab1b6069..56726c828 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ArmatureHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ArmatureHelper.java @@ -267,9 +267,9 @@ public class ArmatureHelper extends AbstractBlenderHelper { } /** - * This method returns bone transformation data for the bone of a given name. - * @param boneName - * the name of the bone + * This method returns bone transformation data for the bone of a given index. + * @param index + * the index of the bone * @return bone's transformation data */ public BoneTransformationData getBoneTransformationDataRoot(int index) { @@ -368,4 +368,9 @@ public class ArmatureHelper extends AbstractBlenderHelper { bonesMap.clear(); boneDataRoots.clear(); } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CameraHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CameraHelper.java index 25ceb3fd7..1446bac63 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CameraHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CameraHelper.java @@ -3,10 +3,12 @@ package com.jme3.scene.plugins.blender.helpers.v249; import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.renderer.Camera; import com.jme3.scene.plugins.blender.data.Structure; import com.jme3.scene.plugins.blender.exception.BlenderFileException; import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper; +import com.jme3.scene.plugins.blender.utils.DataRepository; /** * A class that is used in light calculations. @@ -55,4 +57,9 @@ public class CameraHelper extends AbstractBlenderHelper { result.setFrustumPerspective(angle, aspect, clipsta, clipend); return result; } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java index 5f2bf1ca9..491d6161d 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java @@ -2,6 +2,7 @@ package com.jme3.scene.plugins.blender.helpers.v249; import java.nio.FloatBuffer; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -13,6 +14,7 @@ import com.jme3.animation.BoneTrack; import com.jme3.animation.Skeleton; import com.jme3.math.FastMath; import com.jme3.math.Quaternion; +import com.jme3.math.Transform; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Mesh; @@ -22,6 +24,7 @@ import com.jme3.scene.VertexBuffer.Type; import com.jme3.scene.plugins.blender.data.Structure; import com.jme3.scene.plugins.blender.exception.BlenderFileException; import com.jme3.scene.plugins.blender.structures.AbstractInfluenceFunction; +import com.jme3.scene.plugins.blender.structures.CalculationBone; import com.jme3.scene.plugins.blender.structures.Constraint; import com.jme3.scene.plugins.blender.structures.Constraint.Space; import com.jme3.scene.plugins.blender.structures.ConstraintType; @@ -146,70 +149,89 @@ public class ConstraintHelper extends AbstractBlenderHelper { @Override public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) { - Structure constraintStructure = constraint.getData(); - this.validateConstraintType(constraintStructure); - /*Long boneOMA = constraint.getBoneOMA(); - //IK solver is only attached to bones - Bone ownerBone = (Bone)dataRepository.getLoadedFeature(boneOMA, LoadedFeatureDataType.LOADED_FEATURE); - - //get the target point - Object targetObject = this.getTarget(constraint, LoadedFeatureDataType.LOADED_FEATURE); - Vector3f pt = null;//Point Target - if(targetObject instanceof Bone) { - pt = ((Bone)targetObject).getModelSpacePosition(); - } else if(targetObject instanceof Node) { - pt = ((Node)targetObject).getWorldTranslation(); - } else if(targetObject instanceof Skeleton) { - Structure armatureNodeStructure = (Structure)this.getTarget(constraint, LoadedFeatureDataType.LOADED_STRUCTURE); - ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); - Transform transform = objectHelper.getTransformation(armatureNodeStructure); - pt = transform.getTranslation(); - } else { - throw new IllegalStateException("Unknown target object type! Should be Node, Bone or Skeleton and there is: " + targetObject.getClass().getName()); - } - //preparing data - int maxIterations = ((Number)constraintStructure.getFieldValue("iterations")).intValue(); - CalculationBone[] bones = this.getBonesToCalculate(ownerBone, skeleton, boneAnimation); - for(int i=0;i= IK_SOLVER_ERROR && iteration <= maxIterations) { - //rotating the bones - for(int i = 0; i < bones.length - 1; ++i) { - Vector3f pe = bones[i].getEndPoint(); - Vector3f pc = bones[i + 1].getWorldTranslation().clone(); - - Vector3f peSUBpc = pe.subtract(pc).normalizeLocal(); - Vector3f ptSUBpc = pt.subtract(pc).normalizeLocal(); - - float theta = FastMath.acos(peSUBpc.dot(ptSUBpc)); - Vector3f direction = peSUBpc.cross(ptSUBpc).normalizeLocal(); - bones[i].rotate(rotation.fromAngleAxis(theta, direction), frame); - } - error = pt.subtract(bones[0].getEndPoint()).length(); - ++iteration; - } - System.out.println("error = " + error + " iterations = " + iteration); - } - - for(CalculationBone bone : bones) { - bone.applyCalculatedTracks(); - } - - System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); - for(int i=0;i=1; + for (int frame = 0; frame < framesCount; ++frame) { + float error = IK_SOLVER_ERROR; + int iteration = 0; + while (error >= IK_SOLVER_ERROR && iteration <= maxIterations) { + // rotating the bones + for (int i = 0; i < bones.length - 1; ++i) { + Vector3f pe = bones[i].getEndPoint(); + Vector3f pc = bones[i + 1].getWorldTranslation().clone(); + + Vector3f peSUBpc = pe.subtract(pc).normalizeLocal(); + Vector3f ptSUBpc = pt.subtract(pc).normalizeLocal(); + + float theta = FastMath.acos(peSUBpc.dot(ptSUBpc)); + Vector3f direction = peSUBpc.cross(ptSUBpc).normalizeLocal(); + bones[i].rotate(rotation.fromAngleAxis(theta, direction), frame); + } + error = pt.subtract(bones[0].getEndPoint()).length(); + ++iteration; + } + System.out.println("error = " + error + " iterations = " + iteration); + } + + for (CalculationBone bone : bones) { + bone.applyCalculatedTracks(); + } + +// System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&"); +// for (int i = 0; i < bones.length; ++i) { +// System.out.println(Arrays.toString(bones[i].track.getTranslations())); +// System.out.println(Arrays.toString(bones[i].track.getRotations())); +// System.out.println("==============================="); +// } + } catch(BlenderFileException e) { + LOGGER.severe(e.getLocalizedMessage()); + } } /** @@ -226,13 +248,14 @@ public class ConstraintHelper extends AbstractBlenderHelper { List bonesList = new ArrayList(); Bone currentBone = bone; do { - int boneIndex = skeleton.getBoneIndex(currentBone); - for (int i = 0; i < boneAnimation.getTracks().length; ++i) { - if (boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) { - bonesList.add(new CalculationBone(currentBone, boneAnimation.getTracks()[i])); - break; - } - } + bonesList.add(new CalculationBone(currentBone, 1)); +// int boneIndex = skeleton.getBoneIndex(currentBone); +// for (int i = 0; i < boneAnimation.getTracks().length; ++i) { +// if (boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) { +// bonesList.add(new CalculationBone(currentBone, boneAnimation.getTracks()[i])); +// break; +// } +// } currentBone = currentBone.getParent(); } while (currentBone != null); //attaching children @@ -725,101 +748,9 @@ public class ConstraintHelper extends AbstractBlenderHelper { public void clearState() { constraints.clear(); } - - /** - * The purpose of this class is to imitate bone's movement when calculating inverse kinematics. - * @author Marcin Roguski - */ - private static class CalculationBone extends Node { - - /** The name of the bone. Only to be used in toString method. */ - private String boneName; - /** The bone's tracks. Will be altered at the end of calculation process. */ - private BoneTrack track; - /** The starting position of the bone. */ - private Vector3f startTranslation; - /** The starting rotation of the bone. */ - private Quaternion startRotation; - /** The starting scale of the bone. */ - private Vector3f startScale; - private Vector3f[] translations; - private Quaternion[] rotations; - private Vector3f[] scales; - - /** - * Constructor. Stores the track, starting transformation and sets the transformation to the starting positions. - * @param bone - * the bone this class will imitate - * @param track - * the bone's tracks - */ - public CalculationBone(Bone bone, BoneTrack track) { - this.boneName = bone.getName(); - this.track = track; - this.startRotation = bone.getModelSpaceRotation().clone(); - this.startTranslation = bone.getModelSpacePosition().clone(); - this.startScale = bone.getModelSpaceScale().clone(); - this.translations = track.getTranslations(); - this.rotations = track.getRotations(); - this.scales = track.getScales(); - this.reset(); - } - - /** - * This method returns the end point of the bone. If the bone has parent it is calculated from the start point - * of parent to the start point of this bone. If the bone doesn't have a parent the end location is considered - * to be 1 point up along Y axis (scale is applied if set to != 1.0); - * @return the end point of this bone - */ - //TODO: set to Z axis if user defined it this way - public Vector3f getEndPoint() { - if (this.getParent() == null) { - return new Vector3f(0, this.getLocalScale().y, 0); - } else { - Node parent = this.getParent(); - return parent.getWorldTranslation().subtract(this.getWorldTranslation()).multLocal(this.getWorldScale()); - } - } - - /** - * This method resets the calculation bone to the starting position. - */ - public void reset() { - this.setLocalTranslation(startTranslation); - this.setLocalRotation(startRotation); - this.setLocalScale(startScale); - } - - @Override - public int attachChild(Spatial child) { - if (this.getChildren() != null && this.getChildren().size() > 1) { - throw new IllegalStateException(this.getClass().getName() + " class instance can only have one child!"); - } - return super.attachChild(child); - } - - public Spatial rotate(Quaternion rot, int frame) { - Spatial spatial = super.rotate(rot); - this.updateWorldTransforms(); - if (this.getChildren() != null && this.getChildren().size() > 0) { - CalculationBone child = (CalculationBone) this.getChild(0); - child.updateWorldTransforms(); - } - rotations[frame].set(this.getLocalRotation()); - translations[frame].set(this.getLocalTranslation()); - if (scales != null) { - scales[frame].set(this.getLocalScale()); - } - return spatial; - } - - public void applyCalculatedTracks() { - track.setKeyframes(track.getTimes(), translations, rotations);//TODO:scales - } - - @Override - public String toString() { - return boneName + ": " + this.getLocalRotation() + " " + this.getLocalTranslation(); - } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CurvesHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CurvesHelper.java index ffc954348..a331d5303 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CurvesHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CurvesHelper.java @@ -599,4 +599,9 @@ public class CurvesHelper extends AbstractBlenderHelper { return new Vector3f(locArray.get(0).floatValue(), locArray.get(2).floatValue(), locArray.get(1).floatValue()); } } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/IpoHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/IpoHelper.java index 280299e25..7712bcd0a 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/IpoHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/IpoHelper.java @@ -71,6 +71,11 @@ public class IpoHelper extends AbstractBlenderHelper { return new ConstIpo(constValue); } + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } + /** * Ipo constant curve. This is a curve with only one value and no specified type. This type of ipo cannot be used to * calculate tracks. It should only be used to calculate single value for a given frame. diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/LightHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/LightHelper.java index 95878907a..a02b2abbe 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/LightHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/LightHelper.java @@ -34,6 +34,7 @@ package com.jme3.scene.plugins.blender.helpers.v249; import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.light.DirectionalLight; import com.jme3.light.Light; import com.jme3.light.PointLight; @@ -97,4 +98,9 @@ public class LightHelper extends AbstractBlenderHelper { } return result; } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java index 7d3095639..018cde33d 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java @@ -685,6 +685,11 @@ public class MaterialHelper extends AbstractBlenderHelper { } } + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0; + } + /** * An interface used in calculating alpha mask during particles' texture calculations. * @author Marcin Roguski (Kaelthas) diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java index 955a3349f..6350e5332 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java @@ -605,4 +605,9 @@ public class MeshHelper extends AbstractBlenderHelper { // mesh.setMaxNumWeights(maxWeightsPerVert); return maxWeightsPerVert; } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java index dd9a038a5..22b971232 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java @@ -352,7 +352,7 @@ public class ModifierHelper extends AbstractBlenderHelper { //preparing the object's bone ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); - Transform t = objectHelper.getTransformation(objectStructure); + Transform t = objectHelper.getTransformation(objectStructure, dataRepository); Bone bone = new Bone(null); bone.setBindTransforms(t.getTranslation(), t.getRotation(), t.getScale()); @@ -545,7 +545,7 @@ public class ModifierHelper extends AbstractBlenderHelper { ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); try {// we take the structure in case the object was not yet loaded Structure offsetStructure = offsetObjectBlock.getStructure(dataRepository); - Vector3f translation = objectHelper.getTransformation(offsetStructure).getTranslation(); + Vector3f translation = objectHelper.getTransformation(offsetStructure, dataRepository).getTranslation(); objectOffset[0] = translation.x; objectOffset[1] = translation.y; objectOffset[2] = translation.z; @@ -754,4 +754,9 @@ public class ModifierHelper extends AbstractBlenderHelper { } return new Skeleton(bones.toArray(new Bone[bones.size()])); } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/NoiseHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/NoiseHelper.java index 711054016..b85b42b6f 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/NoiseHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/NoiseHelper.java @@ -1529,6 +1529,11 @@ public class NoiseHelper extends AbstractBlenderHelper { return rx * q[0] + ry * q[1] + rz * q[2]; } } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } /** * This interface is used for distance calculation classes. Distance metrics for voronoi. e parameter only used in diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ObjectHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ObjectHelper.java index 4b2e72043..daca5c6ae 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ObjectHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ObjectHelper.java @@ -31,10 +31,13 @@ */ package com.jme3.scene.plugins.blender.helpers.v249; +import java.util.ArrayList; +import java.util.Collection; import java.util.List; import java.util.logging.Level; import java.util.logging.Logger; +import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.light.DirectionalLight; import com.jme3.light.Light; import com.jme3.light.PointLight; @@ -77,6 +80,16 @@ public class ObjectHelper extends AbstractBlenderHelper { protected static final int OBJECT_TYPE_LATTICE = 22; protected static final int OBJECT_TYPE_ARMATURE = 25; + /** + * This collection contains types of features that are not visible to the user. + * These will be loaded regardless the layer they reside in. + */ + protected static final Collection invisibleTypes = new ArrayList(); + static { + invisibleTypes.add(OBJECT_TYPE_EMPTY); + invisibleTypes.add(OBJECT_TYPE_ARMATURE); + } + /** This variable indicates if the Y asxis is the UP axis or not. */ protected boolean fixUpAxis; /** Quaternion used to rotate data when Y is up axis. */ @@ -149,7 +162,7 @@ public class ObjectHelper extends AbstractBlenderHelper { parent = this.toObject(parentStructure, dataRepository); } - Transform t = objectHelper.getTransformation(objectStructure); + Transform t = objectHelper.getTransformation(objectStructure, dataRepository); try { switch(type) { @@ -268,15 +281,23 @@ public class ObjectHelper extends AbstractBlenderHelper { * @return objects transformation relative to its parent */ @SuppressWarnings("unchecked") - public Transform getTransformation(Structure objectStructure) { + public Transform getTransformation(Structure objectStructure, DataRepository dataRepository) { //these are transformations in global space DynamicArray loc = (DynamicArray)objectStructure.getFieldValue("loc"); DynamicArray size = (DynamicArray)objectStructure.getFieldValue("size"); DynamicArray rot = (DynamicArray)objectStructure.getFieldValue("rot"); //load parent inverse matrix - Pointer parent = (Pointer) objectStructure.getFieldValue("parent"); - Matrix4f parentInv = parent.isNull() ? Matrix4f.IDENTITY : this.getMatrix(objectStructure, "parentinv"); + Pointer pParent = (Pointer) objectStructure.getFieldValue("parent"); + Structure parent = null; + if(pParent.isNotNull()) { + try { + parent = pParent.fetchData(dataRepository.getInputStream()).get(0); + } catch (BlenderFileException e) { + LOGGER.log(Level.WARNING, "Cannot fetch parent for object! Reason: {0}", e.getLocalizedMessage()); + } + } + Matrix4f parentInv = pParent.isNull() ? Matrix4f.IDENTITY : this.getMatrix(objectStructure, "parentinv"); //create the global matrix (without the scale) Matrix4f globalMatrix = new Matrix4f(); @@ -296,7 +317,7 @@ public class ObjectHelper extends AbstractBlenderHelper { size.get(2).floatValue() * scaleZ); //the root object is transformed if the Y axis is UP - if(parent.isNull() && fixUpAxis) { + if(fixUpAxis && (pParent.isNull() || (parent!=null && !this.shouldBeLoaded(parent, dataRepository)))) { float y = translation.y; translation.y = translation.z; translation.z = -y; @@ -343,4 +364,11 @@ public class ObjectHelper extends AbstractBlenderHelper { public void clearState() { fixUpAxis = false; } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + int lay = ((Number) structure.getFieldValue("lay")).intValue(); + return ((lay & dataRepository.getBlenderKey().getLayersToLoad()) != 0 + && (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0); + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ParticlesHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ParticlesHelper.java index 3fbdc79e2..682b1d05c 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ParticlesHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ParticlesHelper.java @@ -187,4 +187,9 @@ public class ParticlesHelper extends AbstractBlenderHelper { } return result; } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return true; + } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/TextureHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/TextureHelper.java index 13e28b0e6..aaaabef7f 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/TextureHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/TextureHelper.java @@ -42,6 +42,7 @@ import java.util.logging.Logger; import com.jme3.asset.AssetNotFoundException; import com.jme3.asset.TextureKey; +import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.data.FileBlockHeader; import com.jme3.scene.plugins.blender.data.Structure; @@ -1779,6 +1780,11 @@ public class TextureHelper extends AbstractBlenderHelper { return result; } } + + @Override + public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { + return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0; + } /** * Image types that can be loaded. AWT: png, jpg, jped or bmp TGA: tga DDS: DirectX image files diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java b/engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java index 930363cde..8e2b4234b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java @@ -139,20 +139,21 @@ public abstract class AbstractInfluenceFunction { * @throws BlenderFileException this exception is thrown if the blend file is somehow corrupted */ protected Object getTarget(Constraint constraint, LoadedFeatureDataType loadedFeatureDataType) throws BlenderFileException { - //TODO: load the feature through objectHelper, this way we are certain the object loads and has + //load the feature through objectHelper, this way we are certain the object loads and has //his own constraints applied to traces ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class); - //subtarget goes first + //always load the target first + Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress(); + Structure objectStructure = dataRepository.getFileBlock(targetOMA).getStructure(dataRepository); + Object result = objectHelper.toObject(objectStructure, dataRepository); + + //subtarget should be loaded alogn with target Object subtarget = constraint.getData().getFieldValue("subtarget"); String subtargetName = subtarget==null ? null : subtarget.toString(); if (subtargetName!=null && subtargetName.length() > 0) { - //TODO: what if it is not yet loaded ??? - return dataRepository.getLoadedFeature(subtargetName, loadedFeatureDataType); + result = dataRepository.getLoadedFeature(subtargetName, loadedFeatureDataType); } - //and now use the target - Long targetOMA = ((Pointer) constraint.getData().getFieldValue("target")).getOldMemoryAddress(); - Structure objectStructure = dataRepository.getFileBlock(targetOMA).getStructure(dataRepository); - return objectHelper.toObject(objectStructure, dataRepository); + return result; } /** diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/structures/CalculationBone.java b/engine/src/blender/com/jme3/scene/plugins/blender/structures/CalculationBone.java new file mode 100644 index 000000000..cc0abd33c --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/structures/CalculationBone.java @@ -0,0 +1,129 @@ +package com.jme3.scene.plugins.blender.structures; + +import java.util.Arrays; + +import com.jme3.animation.Bone; +import com.jme3.animation.BoneTrack; +import com.jme3.math.Quaternion; +import com.jme3.math.Vector3f; +import com.jme3.scene.Node; +import com.jme3.scene.Spatial; + +/** + * The purpose of this class is to imitate bone's movement when calculating inverse kinematics. + * @author Marcin Roguski + */ +public class CalculationBone extends Node { + private Bone bone; + /** The bone's tracks. Will be altered at the end of calculation process. */ + private BoneTrack track; + /** The starting position of the bone. */ + private Vector3f startTranslation; + /** The starting rotation of the bone. */ + private Quaternion startRotation; + /** The starting scale of the bone. */ + private Vector3f startScale; + private Vector3f[] translations; + private Quaternion[] rotations; + private Vector3f[] scales; + + public CalculationBone(Bone bone, int boneFramesCount) { + this.bone = bone; + this.startRotation = bone.getModelSpaceRotation().clone(); + this.startTranslation = bone.getModelSpacePosition().clone(); + this.startScale = bone.getModelSpaceScale().clone(); + this.reset(); + if(boneFramesCount > 0) { + this.translations = new Vector3f[boneFramesCount]; + this.rotations = new Quaternion[boneFramesCount]; + this.scales = new Vector3f[boneFramesCount]; + + Arrays.fill(this.translations, 0, boneFramesCount, this.startTranslation); + Arrays.fill(this.rotations, 0, boneFramesCount, this.startRotation); + Arrays.fill(this.scales, 0, boneFramesCount, this.startScale); + } + } + + /** + * Constructor. Stores the track, starting transformation and sets the transformation to the starting positions. + * @param bone + * the bone this class will imitate + * @param track + * the bone's tracks + */ + public CalculationBone(Bone bone, BoneTrack track) { + this(bone, 0); + this.track = track; + this.translations = track.getTranslations(); + this.rotations = track.getRotations(); + this.scales = track.getScales(); + } + + public int getBoneFramesCount() { + return this.translations==null ? 0 : this.translations.length; + } + + /** + * This method returns the end point of the bone. If the bone has parent it is calculated from the start point + * of parent to the start point of this bone. If the bone doesn't have a parent the end location is considered + * to be 1 point up along Y axis (scale is applied if set to != 1.0); + * @return the end point of this bone + */ + //TODO: set to Z axis if user defined it this way + public Vector3f getEndPoint() { + if (this.getParent() == null) { + return new Vector3f(0, this.getLocalScale().y, 0); + } else { + Node parent = this.getParent(); + return parent.getWorldTranslation().subtract(this.getWorldTranslation()).multLocal(this.getWorldScale()); + } + } + + /** + * This method resets the calculation bone to the starting position. + */ + public void reset() { + this.setLocalTranslation(startTranslation); + this.setLocalRotation(startRotation); + this.setLocalScale(startScale); + } + + @Override + public int attachChild(Spatial child) { + if (this.getChildren() != null && this.getChildren().size() > 1) { + throw new IllegalStateException(this.getClass().getName() + " class instance can only have one child!"); + } + return super.attachChild(child); + } + + public Spatial rotate(Quaternion rot, int frame) { + Spatial spatial = super.rotate(rot); + this.updateWorldTransforms(); + if (this.getChildren() != null && this.getChildren().size() > 0) { + CalculationBone child = (CalculationBone) this.getChild(0); + child.updateWorldTransforms(); + } + rotations[frame].set(this.getLocalRotation()); + translations[frame].set(this.getLocalTranslation()); + if (scales != null) { + scales[frame].set(this.getLocalScale()); + } + return spatial; + } + + public void applyCalculatedTracks() { + if(track != null) { + track.setKeyframes(track.getTimes(), translations, rotations);//TODO:scales + } else { + bone.setUserControl(true); + bone.setUserTransforms(translations[0], rotations[0], scales[0]); + bone.setUserControl(false); + bone.updateWorldVectors(); + } + } + + @Override + public String toString() { + return bone.getName() + ": " + this.getLocalRotation() + " " + this.getLocalTranslation(); + } +} \ No newline at end of file diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/utils/AbstractBlenderHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/utils/AbstractBlenderHelper.java index 4a348b24e..0acf7bd11 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/utils/AbstractBlenderHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/utils/AbstractBlenderHelper.java @@ -127,4 +127,15 @@ public abstract class AbstractBlenderHelper { } return properties; } + + /** + * This method analyzes the given structure and the data contained within + * data repository and decides if the feature should be loaded. + * @param structure + * structure to be analyzed + * @param dataRepository + * the data repository + * @return true if the feature should be loaded and false otherwise + */ + public abstract boolean shouldBeLoaded(Structure structure, DataRepository dataRepository); } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/utils/JmeConverter.java b/engine/src/blender/com/jme3/scene/plugins/blender/utils/JmeConverter.java index f7c7af49f..0fc42277d 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/utils/JmeConverter.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/utils/JmeConverter.java @@ -32,7 +32,6 @@ package com.jme3.scene.plugins.blender.utils; import java.util.List; -import java.util.logging.Logger; import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.asset.BlenderKey.WorldData; @@ -57,7 +56,6 @@ import com.jme3.scene.plugins.blender.helpers.ObjectHelper; */ public class JmeConverter implements BlenderConverter, Material> { - private static final Logger LOGGER = Logger.getLogger(JmeConverter.class.getName()); private final DataRepository dataRepository; /** @@ -104,46 +102,47 @@ public class JmeConverter implements BlenderConverter toMesh(Structure structure) throws BlenderFileException { MeshHelper meshHelper = dataRepository.getHelper(MeshHelper.class); - return meshHelper.toMesh(structure, dataRepository); + if(meshHelper.shouldBeLoaded(structure, dataRepository)) { + return meshHelper.toMesh(structure, dataRepository); + } + return null; } @Override public Material toMaterial(Structure structure) throws BlenderFileException { - if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) == 0) { - return null; + MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class); + if (materialHelper.shouldBeLoaded(structure, dataRepository)) { + return materialHelper.toMaterial(structure, dataRepository); } - MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class); - return materialHelper.toMaterial(structure, dataRepository); + return null; } /**