* Javadocs for com.jme3.material

* Formatted the blender loader files according to NetBeans
 * Removed any "I" prefixes on interfaces
 * Small javadoc fixes

git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7592 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
3.0
sha..rd 14 years ago
parent d03683deca
commit 95cdde7f53
  1. 74
      engine/src/blender/com/jme3/asset/BlenderKey.java
  2. 53
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java
  3. 33
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java
  4. 66
      engine/src/blender/com/jme3/scene/plugins/blender/data/DnaBlockData.java
  5. 93
      engine/src/blender/com/jme3/scene/plugins/blender/data/Field.java
  6. 17
      engine/src/blender/com/jme3/scene/plugins/blender/data/FileBlockHeader.java
  7. 53
      engine/src/blender/com/jme3/scene/plugins/blender/data/Structure.java
  8. 4
      engine/src/blender/com/jme3/scene/plugins/blender/exception/BlenderFileException.java
  9. 26
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/ArmatureHelper.java
  10. 19
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/CameraHelper.java
  11. 3
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/ConstraintHelper.java
  12. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/CurvesHelper.java
  13. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/IpoHelper.java
  14. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/LightHelper.java
  15. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/MaterialHelper.java
  16. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/MeshHelper.java
  17. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/ModifierHelper.java
  18. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/NoiseHelper.java
  19. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/ObjectHelper.java
  20. 1
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/ParticlesHelper.java
  21. 8
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/TextureHelper.java
  22. 53
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ArmatureHelper.java
  23. 21
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CameraHelper.java
  24. 303
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ConstraintHelper.java
  25. 246
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/CurvesHelper.java
  26. 14
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/IpoHelper.java
  27. 21
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/LightHelper.java
  28. 38
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MaterialHelper.java
  29. 7
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/MeshHelper.java
  30. 181
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/ModifierHelper.java
  31. 481
      engine/src/blender/com/jme3/scene/plugins/blender/helpers/v249/NoiseHelper.java
  32. 44
      engine/src/blender/com/jme3/scene/plugins/blender/structures/AbstractInfluenceFunction.java
  33. 26
      engine/src/blender/com/jme3/scene/plugins/blender/structures/BezierCurve.java
  34. 14
      engine/src/blender/com/jme3/scene/plugins/blender/structures/Constraint.java
  35. 14
      engine/src/blender/com/jme3/scene/plugins/blender/structures/ConstraintType.java
  36. 32
      engine/src/blender/com/jme3/scene/plugins/blender/structures/Ipo.java
  37. 3
      engine/src/blender/com/jme3/scene/plugins/blender/structures/Modifier.java
  38. 10
      engine/src/blender/com/jme3/scene/plugins/blender/utils/AbstractBlenderHelper.java
  39. 3
      engine/src/blender/com/jme3/scene/plugins/blender/utils/BlenderConverter.java
  40. 58
      engine/src/blender/com/jme3/scene/plugins/blender/utils/BlenderInputStream.java
  41. 32
      engine/src/blender/com/jme3/scene/plugins/blender/utils/DataRepository.java
  42. 25
      engine/src/blender/com/jme3/scene/plugins/blender/utils/DynamicArray.java
  43. 38
      engine/src/blender/com/jme3/scene/plugins/blender/utils/JmeConverter.java
  44. 25
      engine/src/blender/com/jme3/scene/plugins/blender/utils/Pointer.java
  45. 4
      engine/src/core/com/jme3/animation/Bone.java
  46. 2
      engine/src/core/com/jme3/animation/CompactArray.java
  47. 70
      engine/src/core/com/jme3/app/package.html
  48. 1
      engine/src/core/com/jme3/app/state/AppStateManager.java
  49. 2
      engine/src/core/com/jme3/asset/AssetLocator.java
  50. 14
      engine/src/core/com/jme3/asset/AssetManager.java
  51. 2
      engine/src/core/com/jme3/asset/TextureKey.java
  52. 2
      engine/src/core/com/jme3/audio/AudioRenderer.java
  53. 25
      engine/src/core/com/jme3/bounding/BoundingBox.java
  54. 8
      engine/src/core/com/jme3/bounding/BoundingSphere.java
  55. 2
      engine/src/core/com/jme3/input/controls/MouseButtonTrigger.java
  56. 3
      engine/src/core/com/jme3/light/Light.java
  57. 136
      engine/src/core/com/jme3/material/Material.java
  58. 19
      engine/src/core/com/jme3/material/Technique.java
  59. 272
      engine/src/core/com/jme3/material/TechniqueDef.java
  60. 2
      engine/src/core/com/jme3/material/package.html
  61. 3
      engine/src/core/com/jme3/math/Matrix4f.java
  62. 3
      engine/src/core/com/jme3/math/Ray.java
  63. 6
      engine/src/core/com/jme3/math/Spline.java
  64. 91
      engine/src/core/com/jme3/math/Triangle.java
  65. 3
      engine/src/core/com/jme3/math/Vector2f.java
  66. 2
      engine/src/core/com/jme3/math/Vector4f.java
  67. 23
      engine/src/core/com/jme3/post/Filter.java
  68. 4
      engine/src/core/com/jme3/renderer/Camera.java
  69. 3
      engine/src/core/com/jme3/renderer/GLObject.java
  70. 6
      engine/src/core/com/jme3/renderer/RenderManager.java
  71. 3
      engine/src/core/com/jme3/renderer/Renderer.java
  72. 6
      engine/src/core/com/jme3/renderer/queue/GeometryList.java
  73. 6
      engine/src/core/com/jme3/scene/Geometry.java
  74. 6
      engine/src/core/com/jme3/scene/Node.java
  75. 3
      engine/src/core/com/jme3/scene/Spatial.java
  76. 5
      engine/src/core/com/jme3/scene/VertexBuffer.java
  77. 2
      engine/src/core/com/jme3/scene/control/Control.java
  78. 4
      engine/src/core/com/jme3/scene/control/LightControl.java
  79. 2
      engine/src/core/com/jme3/shader/Shader.java
  80. 1
      engine/src/core/com/jme3/system/JmeContext.java

@ -64,8 +64,8 @@ import com.jme3.texture.Texture;
* @author Marcin Roguski (Kaelthas)
*/
public class BlenderKey extends ModelKey {
protected static final int DEFAULT_FPS = 25;
protected static final int DEFAULT_FPS = 25;
/**
* Animation definitions. The key is the object name that owns the animation. The value is a map between animation
* name and its start and stop frames. Blender stores a pointer for animation within object. Therefore one object
@ -111,7 +111,8 @@ public class BlenderKey extends ModelKey {
/**
* Constructor used by serialization mechanisms.
*/
public BlenderKey() {}
public BlenderKey() {
}
/**
* Constructor. Creates a key for the given file name.
@ -134,25 +135,25 @@ public class BlenderKey extends ModelKey {
* the stop frame of the animation
*/
public synchronized void addAnimation(String objectName, String name, int start, int stop) {
if(objectName == null) {
if (objectName == null) {
throw new IllegalArgumentException("Object name cannot be null!");
}
if(name == null) {
if (name == null) {
throw new IllegalArgumentException("Animation name cannot be null!");
}
if(start > stop) {
if (start > stop) {
throw new IllegalArgumentException("Start frame cannot be greater than stop frame!");
}
if(animations == null) {
if (animations == null) {
animations = new HashMap<String, Map<String, int[]>>();
animations.put(objectName, new HashMap<String, int[]>());
}
Map<String, int[]> objectAnimations = animations.get(objectName);
if(objectAnimations == null) {
if (objectAnimations == null) {
objectAnimations = new HashMap<String, int[]>();
animations.put(objectName, objectAnimations);
}
objectAnimations.put(name, new int[] {start, stop});
objectAnimations.put(name, new int[]{start, stop});
}
/**
@ -387,13 +388,13 @@ public class BlenderKey extends ModelKey {
OutputCapsule oc = e.getCapsule(this);
//saving animations
oc.write(animations == null ? 0 : animations.size(), "anim-size", 0);
if(animations != null) {
if (animations != null) {
int objectCounter = 0;
for(Entry<String, Map<String, int[]>> animEntry : animations.entrySet()) {
for (Entry<String, Map<String, int[]>> animEntry : animations.entrySet()) {
oc.write(animEntry.getKey(), "animated-object-" + objectCounter, null);
int animsAmount = animEntry.getValue().size();
oc.write(animsAmount, "anims-amount-" + objectCounter, 0);
for(Entry<String, int[]> animsEntry : animEntry.getValue().entrySet()) {
for (Entry<String, int[]> animsEntry : animEntry.getValue().entrySet()) {
oc.write(animsEntry.getKey(), "anim-name-" + objectCounter, null);
oc.write(animsEntry.getValue(), "anim-frames-" + objectCounter, null);
}
@ -417,17 +418,17 @@ public class BlenderKey extends ModelKey {
InputCapsule ic = e.getCapsule(this);
//reading animations
int animSize = ic.readInt("anim-size", 0);
if(animSize > 0) {
if(animations == null) {
if (animSize > 0) {
if (animations == null) {
animations = new HashMap<String, Map<String, int[]>>(animSize);
} else {
animations.clear();
}
for(int i = 0; i < animSize; ++i) {
for (int i = 0; i < animSize; ++i) {
String objectName = ic.readString("animated-object-" + i, null);
int animationsAmount = ic.readInt("anims-amount-" + i, 0);
Map<String, int[]> objectAnimations = new HashMap<String, int[]>(animationsAmount);
for(int j = 0; j < animationsAmount; ++j) {
for (int j = 0; j < animationsAmount; ++j) {
String animName = ic.readString("anim-name-" + i, null);
int[] animFrames = ic.readIntArray("anim-frames-" + i, null);
objectAnimations.put(animName, animFrames);
@ -442,7 +443,7 @@ public class BlenderKey extends ModelKey {
assetRootPath = ic.readString("asset-root-path", null);
fixUpAxis = ic.readBoolean("fix-up-axis", true);
usedWorld = ic.readString("used-world", null);
defaultMaterial = (Material)ic.readSavable("default-material", null);
defaultMaterial = (Material) ic.readSavable("default-material", null);
faceCullMode = ic.readEnum("face-cull-mode", FaceCullMode.class, FaceCullMode.Off);
layersToLoad = ic.readInt("layers-to=load", -1);
}
@ -534,6 +535,7 @@ public class BlenderKey extends ModelKey {
* @author Marcin Roguski (Kaelthas)
*/
public static interface FeaturesToLoad {
int SCENES = 0x0000FFFF;
int OBJECTS = 0x0000000B;
int ANIMATIONS = 0x00000004;
@ -549,6 +551,7 @@ public class BlenderKey extends ModelKey {
* @author Marcin Roguski (Kaelthas)
*/
public static class LoadingResults extends Spatial {
/** Bitwise mask of features that are to be loaded. */
private final int featuresToLoad;
/** The scenes from the file. */
@ -574,25 +577,25 @@ public class BlenderKey extends ModelKey {
*/
private LoadingResults(int featuresToLoad) {
this.featuresToLoad = featuresToLoad;
if((featuresToLoad & FeaturesToLoad.SCENES) != 0) {
if ((featuresToLoad & FeaturesToLoad.SCENES) != 0) {
scenes = new ArrayList<Node>();
}
if((featuresToLoad & FeaturesToLoad.OBJECTS) != 0) {
if ((featuresToLoad & FeaturesToLoad.OBJECTS) != 0) {
objects = new ArrayList<Node>();
if((featuresToLoad & FeaturesToLoad.MATERIALS) != 0) {
if ((featuresToLoad & FeaturesToLoad.MATERIALS) != 0) {
materials = new ArrayList<Material>();
if((featuresToLoad & FeaturesToLoad.TEXTURES) != 0) {
if ((featuresToLoad & FeaturesToLoad.TEXTURES) != 0) {
textures = new ArrayList<Texture>();
}
}
if((featuresToLoad & FeaturesToLoad.ANIMATIONS) != 0) {
if ((featuresToLoad & FeaturesToLoad.ANIMATIONS) != 0) {
animations = new ArrayList<AnimData>();
}
}
if((featuresToLoad & FeaturesToLoad.CAMERAS) != 0) {
if ((featuresToLoad & FeaturesToLoad.CAMERAS) != 0) {
cameras = new ArrayList<Camera>();
}
if((featuresToLoad & FeaturesToLoad.LIGHTS) != 0) {
if ((featuresToLoad & FeaturesToLoad.LIGHTS) != 0) {
lights = new ArrayList<Light>();
}
}
@ -612,7 +615,7 @@ public class BlenderKey extends ModelKey {
* scene to be added to the result set
*/
public void addScene(Node scene) {
if(scenes != null) {
if (scenes != null) {
scenes.add(scene);
}
}
@ -623,7 +626,7 @@ public class BlenderKey extends ModelKey {
* object to be added to the result set
*/
public void addObject(Node object) {
if(objects != null) {
if (objects != null) {
objects.add(object);
}
}
@ -634,7 +637,7 @@ public class BlenderKey extends ModelKey {
* material to be added to the result set
*/
public void addMaterial(Material material) {
if(materials != null) {
if (materials != null) {
materials.add(material);
}
}
@ -645,7 +648,7 @@ public class BlenderKey extends ModelKey {
* texture to be added to the result set
*/
public void addTexture(Texture texture) {
if(textures != null) {
if (textures != null) {
textures.add(texture);
}
}
@ -656,7 +659,7 @@ public class BlenderKey extends ModelKey {
* camera to be added to the result set
*/
public void addCamera(Camera camera) {
if(cameras != null) {
if (cameras != null) {
cameras.add(camera);
}
}
@ -668,7 +671,7 @@ public class BlenderKey extends ModelKey {
*/
@Override
public void addLight(Light light) {
if(lights != null) {
if (lights != null) {
lights.add(light);
}
}
@ -735,10 +738,12 @@ public class BlenderKey extends ModelKey {
}
@Override
public void updateModelBound() {}
public void updateModelBound() {
}
@Override
public void setModelBound(BoundingVolume modelBound) {}
public void setModelBound(BoundingVolume modelBound) {
}
@Override
public int getVertexCount() {
@ -756,10 +761,12 @@ public class BlenderKey extends ModelKey {
}
@Override
public void depthFirstTraversal(SceneGraphVisitor visitor) {}
public void depthFirstTraversal(SceneGraphVisitor visitor) {
}
@Override
protected void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue) {}
protected void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue) {
}
}
/**
@ -768,6 +775,7 @@ public class BlenderKey extends ModelKey {
* @author Marcin Roguski (Kaelthas)
*/
public static class WorldData {
/** The ambient light. */
private AmbientLight ambientLight;

@ -72,16 +72,17 @@ import com.jme3.scene.plugins.blender.utils.JmeConverter;
* @author Marcin Roguski
*/
public class BlenderLoader implements AssetLoader {
private static final Logger LOGGER = Logger.getLogger(BlenderLoader.class.getName());
@Override
public LoadingResults load(AssetInfo assetInfo) throws IOException {
try {
//registering loaders
ModelKey modelKey = (ModelKey)assetInfo.getKey();
ModelKey modelKey = (ModelKey) assetInfo.getKey();
BlenderKey blenderKey;
if(modelKey instanceof BlenderKey) {
blenderKey = (BlenderKey)modelKey;
if (modelKey instanceof BlenderKey) {
blenderKey = (BlenderKey) modelKey;
} else {
blenderKey = new BlenderKey(modelKey.getName());
blenderKey.setAssetRootPath(modelKey.getFolder());
@ -114,7 +115,7 @@ public class BlenderLoader implements AssetLoader {
dataRepository.putHelper(ParticlesHelper.class, new ParticlesHelper(inputStream.getVersionNumber()));
//setting additional data to helpers
if(blenderKey.isFixUpAxis()) {
if (blenderKey.isFixUpAxis()) {
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
objectHelper.setyIsUpAxis(true);
CurvesHelper curvesHelper = dataRepository.getHelper(CurvesHelper.class);
@ -126,52 +127,52 @@ public class BlenderLoader implements AssetLoader {
//reading the blocks (dna block is automatically saved in the data repository when found)//TODO: zmienić to
do {
fileBlock = new FileBlockHeader(inputStream, dataRepository);
if(!fileBlock.isDnaBlock()) {
if (!fileBlock.isDnaBlock()) {
blocks.add(fileBlock);
}
} while(!fileBlock.isLastBlock());
} while (!fileBlock.isLastBlock());
JmeConverter converter = new JmeConverter(dataRepository);
LoadingResults loadingResults = blenderKey.prepareLoadingResults();
WorldData worldData = null;//a set of data used in different scene aspects
for(FileBlockHeader block : blocks) {
switch(block.getCode()) {
for (FileBlockHeader block : blocks) {
switch (block.getCode()) {
case FileBlockHeader.BLOCK_OB00://Object
Object object = converter.toObject(block.getStructure(dataRepository));
if(object instanceof Node) {
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
LOGGER.log(Level.INFO, ((Node)object).getName() + ": " + ((Node)object).getLocalTranslation().toString() + "--> " + (((Node)object).getParent() == null ? "null" : ((Node)object).getParent().getName()));
if(((Node)object).getParent() == null) {
loadingResults.addObject((Node)object);
if (object instanceof Node) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
LOGGER.log(Level.INFO, "{0}: {1}--> {2}", new Object[]{((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName()});
if (((Node) object).getParent() == null) {
loadingResults.addObject((Node) object);
}
}
} else if(object instanceof Camera) {
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0) {
loadingResults.addCamera((Camera)object);
} else if (object instanceof Camera) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0) {
loadingResults.addCamera((Camera) object);
}
} else if(object instanceof Light) {
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
loadingResults.addLight((Light)object);
} else if (object instanceof Light) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
loadingResults.addLight((Light) object);
}
}
break;
case FileBlockHeader.BLOCK_MA00://Material
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
loadingResults.addMaterial(converter.toMaterial(block.getStructure(dataRepository)));
}
break;
case FileBlockHeader.BLOCK_SC00://Scene
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) {
loadingResults.addScene(converter.toScene(block.getStructure(dataRepository)));
}
break;
case FileBlockHeader.BLOCK_WO00://World
if(worldData == null) {//onlu one world data is used
if (worldData == null) {//onlu one world data is used
Structure worldStructure = block.getStructure(dataRepository);
String worldName = worldStructure.getName();
if(blenderKey.getUsedWorld() == null || blenderKey.getUsedWorld().equals(worldName)) {
if (blenderKey.getUsedWorld() == null || blenderKey.getUsedWorld().equals(worldName)) {
worldData = converter.toWorldData(worldStructure);
if((blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
loadingResults.addLight(worldData.getAmbientLight());
}
}
@ -181,11 +182,11 @@ public class BlenderLoader implements AssetLoader {
}
try {
inputStream.close();
} catch(IOException e) {
} catch (IOException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
return loadingResults;
} catch(BlenderFileException e) {
} catch (BlenderFileException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
return null;

@ -69,16 +69,17 @@ import com.jme3.scene.plugins.blender.utils.JmeConverter;
* @author Marcin Roguski
*/
public class BlenderModelLoader implements AssetLoader {
private static final Logger LOGGER = Logger.getLogger(BlenderModelLoader.class.getName());
@Override
public Spatial load(AssetInfo assetInfo) throws IOException {
try {
//registering loaders
ModelKey modelKey = (ModelKey)assetInfo.getKey();
ModelKey modelKey = (ModelKey) assetInfo.getKey();
BlenderKey blenderKey;
if(modelKey instanceof BlenderKey) {
blenderKey = (BlenderKey)modelKey;
if (modelKey instanceof BlenderKey) {
blenderKey = (BlenderKey) modelKey;
} else {
blenderKey = new BlenderKey(modelKey.getName());
blenderKey.setAssetRootPath(modelKey.getFolder());
@ -107,7 +108,7 @@ public class BlenderModelLoader implements AssetLoader {
dataRepository.putHelper(ParticlesHelper.class, new ParticlesHelper(inputStream.getVersionNumber()));
//setting additional data to helpers
if(blenderKey.isFixUpAxis()) {
if (blenderKey.isFixUpAxis()) {
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
objectHelper.setyIsUpAxis(true);
CurvesHelper curvesHelper = dataRepository.getHelper(CurvesHelper.class);
@ -119,37 +120,37 @@ public class BlenderModelLoader implements AssetLoader {
//reading the blocks (dna block is automatically saved in the data repository when found)//TODO: zmienić to
do {
fileBlock = new FileBlockHeader(inputStream, dataRepository);
if(!fileBlock.isDnaBlock()) {
if (!fileBlock.isDnaBlock()) {
blocks.add(fileBlock);
}
} while(!fileBlock.isLastBlock());
} while (!fileBlock.isLastBlock());
JmeConverter converter = new JmeConverter(dataRepository);
LoadingResults loadingResults = blenderKey.prepareLoadingResults();
for(FileBlockHeader block : blocks) {
if(block.getCode() == FileBlockHeader.BLOCK_OB00) {
for (FileBlockHeader block : blocks) {
if (block.getCode() == FileBlockHeader.BLOCK_OB00) {
Object object = converter.toObject(block.getStructure(dataRepository));
if(object instanceof Node) {
LOGGER.log(Level.INFO, ((Node)object).getName() + ": " + ((Node)object).getLocalTranslation().toString() + "--> " + (((Node)object).getParent() == null ? "null" : ((Node)object).getParent().getName()));
if(((Node)object).getParent() == null) {
loadingResults.addObject((Node)object);
if (object instanceof Node) {
LOGGER.log(Level.INFO, "{0}: {1}--> {2}", new Object[]{((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName()});
if (((Node) object).getParent() == null) {
loadingResults.addObject((Node) object);
}
}
}
}
inputStream.close();
List<Node> objects = loadingResults.getObjects();
if(objects.size() > 0) {
if (objects.size() > 0) {
Node modelNode = new Node(blenderKey.getName());
for(Iterator<Node> it = objects.iterator(); it.hasNext();) {
for (Iterator<Node> it = objects.iterator(); it.hasNext();) {
Node node = it.next();
modelNode.attachChild(node);
}
return modelNode;
} else if(objects.size() == 1) {
} else if (objects.size() == 1) {
return objects.get(0);
}
} catch(BlenderFileException e) {
} catch (BlenderFileException e) {
LOGGER.log(Level.SEVERE, e.getMessage(), e);
}
return null;

@ -43,12 +43,12 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
* @author Marcin Roguski
*/
public class DnaBlockData {
private static final int SDNA_ID = 'S' << 24 | 'D' << 16 | 'N' << 8 | 'A'; //SDNA
private static final int NAME_ID = 'N' << 24 | 'A' << 16 | 'M' << 8 | 'E'; //NAME
private static final int TYPE_ID = 'T' << 24 | 'Y' << 16 | 'P' << 8 | 'E'; //TYPE
private static final int TLEN_ID = 'T' << 24 | 'L' << 16 | 'E' << 8 | 'N'; //TLEN
private static final int STRC_ID = 'S' << 24 | 'T' << 16 | 'R' << 8 | 'C'; //STRC
/** Structures available inside the file. */
private final Structure[] structures;
/** A map that helps finding a structure by type. */
@ -67,72 +67,72 @@ public class DnaBlockData {
int identifier;
//reading 'SDNA' identifier
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
if(identifier != SDNA_ID) {
if (identifier != SDNA_ID) {
throw new BlenderFileException("Invalid identifier! '" + this.toString(SDNA_ID) + "' expected and found: " + this.toString(identifier));
}
//reading names
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
if(identifier != NAME_ID) {
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
if (identifier != NAME_ID) {
throw new BlenderFileException("Invalid identifier! '" + this.toString(NAME_ID) + "' expected and found: " + this.toString(identifier));
}
int amount = inputStream.readInt();
if(amount <= 0) {
if (amount <= 0) {
throw new BlenderFileException("The names amount number should be positive!");
}
String[] names = new String[amount];
for(int i = 0; i < amount; ++i) {
for (int i = 0; i < amount; ++i) {
names[i] = inputStream.readString();
}
//reding types
inputStream.alignPosition(4);
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
if(identifier != TYPE_ID) {
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
if (identifier != TYPE_ID) {
throw new BlenderFileException("Invalid identifier! '" + this.toString(TYPE_ID) + "' expected and found: " + this.toString(identifier));
}
amount = inputStream.readInt();
if(amount <= 0) {
if (amount <= 0) {
throw new BlenderFileException("The types amount number should be positive!");
}
String[] types = new String[amount];
for(int i = 0; i < amount; ++i) {
for (int i = 0; i < amount; ++i) {
types[i] = inputStream.readString();
}
//reading lengths
inputStream.alignPosition(4);
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
if(identifier != TLEN_ID) {
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
if (identifier != TLEN_ID) {
throw new BlenderFileException("Invalid identifier! '" + this.toString(TLEN_ID) + "' expected and found: " + this.toString(identifier));
}
int[] lengths = new int[amount];//theamount is the same as int types
for(int i = 0; i < amount; ++i) {
for (int i = 0; i < amount; ++i) {
lengths[i] = inputStream.readShort();
}
//reading structures
inputStream.alignPosition(4);
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
if(identifier != STRC_ID) {
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
if (identifier != STRC_ID) {
throw new BlenderFileException("Invalid identifier! '" + this.toString(STRC_ID) + "' expected and found: " + this.toString(identifier));
}
amount = inputStream.readInt();
if(amount <= 0) {
if (amount <= 0) {
throw new BlenderFileException("The structures amount number should be positive!");
}
structures = new Structure[amount];
structuresMap = new HashMap<String, Structure>(amount);
for(int i = 0; i < amount; ++i) {
for (int i = 0; i < amount; ++i) {
structures[i] = new Structure(inputStream, names, types, dataRepository);
if(structuresMap.containsKey(structures[i].getType())) {
if (structuresMap.containsKey(structures[i].getType())) {
throw new BlenderFileException("Blend file seems to be corrupted! The type " + structures[i].getType() + " is defined twice!");
}
structuresMap.put(structures[i].getType(), structures[i]);
@ -155,8 +155,8 @@ public class DnaBlockData {
*/
public Structure getStructure(int index) {
try {
return (Structure)structures[index].clone();
} catch(CloneNotSupportedException e) {
return (Structure) structures[index].clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException("Structure should be clonable!!!", e);
}
}
@ -169,8 +169,8 @@ public class DnaBlockData {
*/
public Structure getStructure(String name) {
try {
return (Structure)structuresMap.get(name).clone();
} catch(CloneNotSupportedException e) {
return (Structure) structuresMap.get(name).clone();
} catch (CloneNotSupportedException e) {
throw new IllegalStateException(e.getMessage(), e);
}
}
@ -192,17 +192,17 @@ public class DnaBlockData {
* @return the string value of the identifier
*/
private String toString(int code) {
char c1 = (char)((code & 0xFF000000) >> 24);
char c2 = (char)((code & 0xFF0000) >> 16);
char c3 = (char)((code & 0xFF00) >> 8);
char c4 = (char)(code & 0xFF);
char c1 = (char) ((code & 0xFF000000) >> 24);
char c2 = (char) ((code & 0xFF0000) >> 16);
char c3 = (char) ((code & 0xFF00) >> 8);
char c4 = (char) (code & 0xFF);
return String.valueOf(c1) + c2 + c3 + c4;
}
@Override
public String toString() {
StringBuilder stringBuilder = new StringBuilder("=============== ").append(SDNA_ID).append('\n');
for(Structure structure : structures) {
for (Structure structure : structures) {
stringBuilder.append(structure.toString()).append('\n');
}
return stringBuilder.append("===============").toString();

@ -15,10 +15,11 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* another structure.
* @author Marcin Roguski
*/
/*package*/class Field implements Cloneable {
/*package*/
class Field implements Cloneable {
private static final int NAME_LENGTH = 24;
private static final int TYPE_LENGTH = 16;
/** The data repository. */
public DataRepository dataRepository;
/** The type of the field. */
@ -64,7 +65,7 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
name = field.name;
dataRepository = field.dataRepository;
pointerLevel = field.pointerLevel;
if(field.tableSizes != null) {
if (field.tableSizes != null) {
tableSizes = field.tableSizes.clone();
}
function = field.function;
@ -84,24 +85,24 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
*/
public void fill(BlenderInputStream blenderInputStream) throws BlenderFileException {
int dataToRead = 1;
if(tableSizes != null && tableSizes.length > 0) {
for(int size : tableSizes) {
if(size <= 0) {
if (tableSizes != null && tableSizes.length > 0) {
for (int size : tableSizes) {
if (size <= 0) {
throw new BlenderFileException("The field " + name + " has invalid table size: " + size);
}
dataToRead *= size;
}
}
DataType dataType = pointerLevel == 0 ? DataType.getDataType(type, dataRepository) : DataType.POINTER;
switch(dataType) {
switch (dataType) {
case POINTER:
if(dataToRead == 1) {
if (dataToRead == 1) {
Pointer pointer = new Pointer(pointerLevel, function, dataRepository);
pointer.fill(blenderInputStream);
value = pointer;
} else {
Pointer[] data = new Pointer[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
Pointer pointer = new Pointer(pointerLevel, function, dataRepository);
pointer.fill(blenderInputStream);
data[i] = pointer;
@ -113,66 +114,66 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
//character is also stored as a number, because sometimes the new blender version uses
//other number type instead of character as a field type
//and characters are very often used as byte number stores instead of real chars
if(dataToRead == 1) {
value = Byte.valueOf((byte)blenderInputStream.readByte());
if (dataToRead == 1) {
value = Byte.valueOf((byte) blenderInputStream.readByte());
} else {
Character[] data = new Character[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
data[i] = Character.valueOf((char)blenderInputStream.readByte());
for (int i = 0; i < dataToRead; ++i) {
data[i] = Character.valueOf((char) blenderInputStream.readByte());
}
value = new DynamicArray<Character>(tableSizes, data);
}
break;
case SHORT:
if(dataToRead == 1) {
if (dataToRead == 1) {
value = Integer.valueOf(blenderInputStream.readShort());
} else {
Number[] data = new Number[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
data[i] = Integer.valueOf(blenderInputStream.readShort());
}
value = new DynamicArray<Number>(tableSizes, data);
}
break;
case INTEGER:
if(dataToRead == 1) {
if (dataToRead == 1) {
value = Integer.valueOf(blenderInputStream.readInt());
} else {
Number[] data = new Number[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
data[i] = Integer.valueOf(blenderInputStream.readInt());
}
value = new DynamicArray<Number>(tableSizes, data);
}
break;
case LONG:
if(dataToRead == 1) {
if (dataToRead == 1) {
value = Long.valueOf(blenderInputStream.readLong());
} else {
Number[] data = new Number[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
data[i] = Long.valueOf(blenderInputStream.readLong());
}
value = new DynamicArray<Number>(tableSizes, data);
}
break;
case FLOAT:
if(dataToRead == 1) {
if (dataToRead == 1) {
value = Float.valueOf(blenderInputStream.readFloat());
} else {
Number[] data = new Number[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
data[i] = Float.valueOf(blenderInputStream.readFloat());
}
value = new DynamicArray<Number>(tableSizes, data);
}
break;
case DOUBLE:
if(dataToRead == 1) {
if (dataToRead == 1) {
value = Double.valueOf(blenderInputStream.readDouble());
} else {
Number[] data = new Number[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
data[i] = Double.valueOf(blenderInputStream.readDouble());
}
value = new DynamicArray<Number>(tableSizes, data);
@ -181,13 +182,13 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
case VOID:
break;
case STRUCTURE:
if(dataToRead == 1) {
if (dataToRead == 1) {
Structure structure = dataRepository.getDnaBlockData().getStructure(type);
structure.fill(blenderInputStream);
value = structure;
} else {
Structure[] data = new Structure[dataToRead];
for(int i = 0; i < dataToRead; ++i) {
for (int i = 0; i < dataToRead; ++i) {
Structure structure = dataRepository.getDnaBlockData().getStructure(type);
structure.fill(blenderInputStream);
data[i] = structure;
@ -211,13 +212,13 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
this.removeWhitespaces(nameBuilder);
//veryfying if the name is a pointer
int pointerIndex = nameBuilder.indexOf("*");
while(pointerIndex >= 0) {
while (pointerIndex >= 0) {
++pointerLevel;
nameBuilder.deleteCharAt(pointerIndex);
pointerIndex = nameBuilder.indexOf("*");
}
//veryfying if the name is a function pointer
if(nameBuilder.indexOf("(") >= 0) {
if (nameBuilder.indexOf("(") >= 0) {
function = true;
this.removeCharacter(nameBuilder, '(');
this.removeCharacter(nameBuilder, ')');
@ -227,22 +228,22 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
List<Integer> lengths = new ArrayList<Integer>(3);//3 dimensions will be enough in most cases
do {
tableStartIndex = nameBuilder.indexOf("[");
if(tableStartIndex > 0) {
if (tableStartIndex > 0) {
int tableStopIndex = nameBuilder.indexOf("]");
if(tableStopIndex < 0) {
if (tableStopIndex < 0) {
throw new BlenderFileException("Invalid structure name: " + name);
}
try {
lengths.add(Integer.valueOf(nameBuilder.substring(tableStartIndex + 1, tableStopIndex)));
} catch(NumberFormatException e) {
} catch (NumberFormatException e) {
throw new BlenderFileException("Invalid structure name caused by invalid table length: " + name, e);
}
nameBuilder.delete(tableStartIndex, tableStopIndex + 1);
}
} while(tableStartIndex > 0);
if(!lengths.isEmpty()) {
} while (tableStartIndex > 0);
if (!lengths.isEmpty()) {
tableSizes = new int[lengths.size()];
for(int i = 0; i < tableSizes.length; ++i) {
for (int i = 0; i < tableSizes.length; ++i) {
tableSizes[i] = lengths.get(i).intValue();
}
}
@ -258,8 +259,8 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* the character to be removed
*/
private void removeCharacter(StringBuilder text, char toRemove) {
for(int i = 0; i < text.length(); ++i) {
if(text.charAt(i) == toRemove) {
for (int i = 0; i < text.length(); ++i) {
if (text.charAt(i) == toRemove) {
text.deleteCharAt(i);
--i;
}
@ -272,8 +273,8 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* the text we remove whitespaces from
*/
private void removeWhitespaces(StringBuilder text) {
for(int i = 0; i < text.length(); ++i) {
if(Character.isWhitespace(text.charAt(i))) {
for (int i = 0; i < text.length(); ++i) {
if (Character.isWhitespace(text.charAt(i))) {
text.deleteCharAt(i);
--i;
}
@ -283,34 +284,34 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
@Override
public String toString() {
StringBuilder result = new StringBuilder();
if(function) {
if (function) {
result.append('(');
}
for(int i = 0; i < pointerLevel; ++i) {
for (int i = 0; i < pointerLevel; ++i) {
result.append('*');
}
result.append(name);
if(tableSizes != null) {
for(int i = 0; i < tableSizes.length; ++i) {
if (tableSizes != null) {
for (int i = 0; i < tableSizes.length; ++i) {
result.append('[').append(tableSizes[i]).append(']');
}
}
if(function) {
if (function) {
result.append(")()");
}
//insert appropriate amount of spaces to format the output corrently
int nameLength = result.length();
result.append(' ');//at least one space is a must
for(int i = 1; i < NAME_LENGTH - nameLength; ++i) {//we start from i=1 because one space is already added
for (int i = 1; i < NAME_LENGTH - nameLength; ++i) {//we start from i=1 because one space is already added
result.append(' ');
}
result.append(type);
nameLength = result.length();
for(int i = 0; i < NAME_LENGTH + TYPE_LENGTH - nameLength; ++i) {
for (int i = 0; i < NAME_LENGTH + TYPE_LENGTH - nameLength; ++i) {
result.append(' ');
}
if(value instanceof Character) {
result.append(" = ").append((int)((Character)value).charValue());
if (value instanceof Character) {
result.append(" = ").append((int) ((Character) value).charValue());
} else {
result.append(" = ").append(value != null ? value.toString() : "null");
}

@ -41,6 +41,7 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
* @author Marcin Roguski
*/
public class FileBlockHeader {
public static final int BLOCK_TE00 = 'T' << 24 | 'E' << 16; //TE00
public static final int BLOCK_ME00 = 'M' << 24 | 'E' << 16; //ME00
public static final int BLOCK_SR00 = 'S' << 24 | 'R' << 16; //SR00
@ -53,13 +54,11 @@ public class FileBlockHeader {
public static final int BLOCK_TX00 = 'T' << 24 | 'X' << 16; //TX00
public static final int BLOCK_IP00 = 'I' << 24 | 'P' << 16; //IP00
public static final int BLOCK_AC00 = 'A' << 24 | 'C' << 16; //AC00
public static final int BLOCK_GLOB = 'G' << 24 | 'L' << 16 | 'O' << 8 | 'B'; //GLOB
public static final int BLOCK_REND = 'R' << 24 | 'E' << 16 | 'N' << 8 | 'D'; //REND
public static final int BLOCK_DATA = 'D' << 24 | 'A' << 16 | 'T' << 8 | 'A'; //DATA
public static final int BLOCK_DNA1 = 'D' << 24 | 'N' << 16 | 'A' << 8 | '1'; //DNA1
public static final int BLOCK_ENDB = 'E' << 24 | 'N' << 16 | 'D' << 8 | 'B'; //ENDB
/** Identifier of the file-block [4 bytes]. */
private int code;
/** Total length of the data after the file-block-header [4 bytes]. */
@ -87,14 +86,14 @@ public class FileBlockHeader {
*/
public FileBlockHeader(BlenderInputStream inputStream, DataRepository dataRepository) throws BlenderFileException {
inputStream.alignPosition(4);
code = inputStream.readByte() << 24 | inputStream.readByte() << 16 |
inputStream.readByte() << 8 | inputStream.readByte();
code = inputStream.readByte() << 24 | inputStream.readByte() << 16
| inputStream.readByte() << 8 | inputStream.readByte();
size = inputStream.readInt();
oldMemoryAddress = inputStream.readPointer();
sdnaIndex = inputStream.readInt();
count = inputStream.readInt();
blockPosition = inputStream.getPosition();
if(FileBlockHeader.BLOCK_DNA1 == code) {
if (FileBlockHeader.BLOCK_DNA1 == code) {
dataRepository.setBlockData(new DnaBlockData(inputStream, dataRepository));
} else {
inputStream.setPosition(blockPosition + size);
@ -192,10 +191,10 @@ public class FileBlockHeader {
* @return the string value of the block id
*/
protected String codeToString(int code) {
char c1 = (char)((code & 0xFF000000) >> 24);
char c2 = (char)((code & 0xFF0000) >> 16);
char c3 = (char)((code & 0xFF00) >> 8);
char c4 = (char)(code & 0xFF);
char c1 = (char) ((code & 0xFF000000) >> 24);
char c2 = (char) ((code & 0xFF0000) >> 16);
char c3 = (char) ((code & 0xFF00) >> 8);
char c4 = (char) (code & 0xFF);
return String.valueOf(c1) + c2 + c3 + c4;
}
}

@ -46,6 +46,7 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* @author Marcin Roguski
*/
public class Structure implements Cloneable {
/** The data repository. */
private DataRepository dataRepository;
/** The address of the block that fills the structure. */
@ -69,8 +70,8 @@ public class Structure implements Cloneable {
private Structure(Structure structure, DataRepository dataRepository) throws CloneNotSupportedException {
type = structure.type;
fields = new Field[structure.fields.length];
for(int i = 0; i < fields.length; ++i) {
fields[i] = (Field)structure.fields[i].clone();
for (int i = 0; i < fields.length; ++i) {
fields[i] = (Field) structure.fields[i].clone();
}
this.dataRepository = dataRepository;
this.oldMemoryAddress = structure.oldMemoryAddress;
@ -94,12 +95,12 @@ public class Structure implements Cloneable {
type = types[nameIndex];
this.dataRepository = dataRepository;
int fieldsAmount = inputStream.readShort();
if(fieldsAmount < 0) {
if (fieldsAmount < 0) {
throw new BlenderFileException("The amount of fields of " + this.type + " structure cannot be negative!");
}
if(fieldsAmount > 0) {
if (fieldsAmount > 0) {
fields = new Field[fieldsAmount];
for(int i = 0; i < fieldsAmount; ++i) {
for (int i = 0; i < fieldsAmount; ++i) {
int typeIndex = inputStream.readShort();
nameIndex = inputStream.readShort();
fields[i] = new Field(names[nameIndex], types[typeIndex], dataRepository);
@ -121,7 +122,7 @@ public class Structure implements Cloneable {
inputStream.setPosition(position - 8 - inputStream.getPointerSize());
this.oldMemoryAddress = Long.valueOf(inputStream.readPointer());
inputStream.setPosition(position);
for(Field field : fields) {
for (Field field : fields) {
field.fill(inputStream);
}
}
@ -133,8 +134,8 @@ public class Structure implements Cloneable {
* @return the value of the field or null if no field with a given name is found
*/
public Object getFieldValue(String fieldName) {
for(Field field : fields) {
if(field.name.equalsIgnoreCase(fieldName)) {
for (Field field : fields) {
if (field.name.equalsIgnoreCase(fieldName)) {
return field.value;
}
}
@ -149,13 +150,13 @@ public class Structure implements Cloneable {
* @return the value of the field or null if no field with a given name is found
*/
public Object getFlatFieldValue(String fieldName) {
for(Field field : fields) {
for (Field field : fields) {
Object value = field.value;
if(field.name.equalsIgnoreCase(fieldName)) {
if (field.name.equalsIgnoreCase(fieldName)) {
return value;
} else if(value instanceof Structure) {
value = ((Structure)value).getFlatFieldValue(fieldName);
if(value != null) {//we can compare references here, since we use one static object as a NULL field value
} else if (value instanceof Structure) {
value = ((Structure) value).getFlatFieldValue(fieldName);
if (value != null) {//we can compare references here, since we use one static object as a NULL field value
return value;
}
}
@ -175,19 +176,19 @@ public class Structure implements Cloneable {
* this exception is thrown if the type of the structure is not 'ListBase'
*/
public List<Structure> evaluateListBase(DataRepository dataRepository) throws BlenderFileException {
if(!"ListBase".equals(this.type)) {
if (!"ListBase".equals(this.type)) {
throw new IllegalStateException("This structure is not of type: 'ListBase'");
}
Pointer first = (Pointer)this.getFieldValue("first");
Pointer last = (Pointer)this.getFieldValue("last");
Pointer first = (Pointer) this.getFieldValue("first");
Pointer last = (Pointer) this.getFieldValue("last");
long currentAddress = 0;
long lastAddress = last.getOldMemoryAddress();
List<Structure> result = new LinkedList<Structure>();
while(currentAddress != lastAddress) {
while (currentAddress != lastAddress) {
currentAddress = first.getOldMemoryAddress();
Structure structure = first.fetchData(dataRepository.getInputStream()).get(0);
result.add(structure);
first = (Pointer)structure.getFlatFieldValue("next");
first = (Pointer) structure.getFlatFieldValue("next");
}
return result;
}
@ -234,7 +235,7 @@ public class Structure implements Cloneable {
* @return the address of the feature stored in this structure
*/
public Long getOldMemoryAddress() {
if(oldMemoryAddress.longValue() == -1L) {
if (oldMemoryAddress.longValue() == -1L) {
throw new IllegalStateException("Call the 'fill' method and fill the structure with data first!");
}
return oldMemoryAddress;
@ -246,14 +247,14 @@ public class Structure implements Cloneable {
* @return the name of the structure read from the ID field or null
*/
public String getName() {
Structure id = (Structure)this.getFieldValue("ID");
Structure id = (Structure) this.getFieldValue("ID");
return id == null ? null : id.getFieldValue("name").toString().substring(2);//blender adds 2-charactes as a name prefix
}
@Override
public String toString() {
StringBuilder result = new StringBuilder("struct ").append(type).append(" {\n");
for(int i = 0; i < fields.length; ++i) {
for (int i = 0; i < fields.length; ++i) {
result.append(fields[i].toString()).append('\n');
}
return result.append('}').toString();
@ -268,11 +269,13 @@ public class Structure implements Cloneable {
* This enum enumerates all known data types that can be found in the blend file.
* @author Marcin Roguski
*/
/*package*/static enum DataType {
CHARACTER, SHORT, INTEGER, LONG, FLOAT, DOUBLE, VOID, STRUCTURE, POINTER;
/*package*/
static enum DataType {
CHARACTER, SHORT, INTEGER, LONG, FLOAT, DOUBLE, VOID, STRUCTURE, POINTER;
/** The map containing the known primary types. */
private static final Map<String, DataType> PRIMARY_TYPES = new HashMap<String, DataType>(10);
static {
PRIMARY_TYPES.put("char", CHARACTER);
PRIMARY_TYPES.put("uchar", CHARACTER);
@ -299,10 +302,10 @@ public class Structure implements Cloneable {
*/
public static DataType getDataType(String type, DataRepository dataRepository) throws BlenderFileException {
DataType result = PRIMARY_TYPES.get(type);
if(result != null) {
if (result != null) {
return result;
}
if(dataRepository.getDnaBlockData().hasStructure(type)) {
if (dataRepository.getDnaBlockData().hasStructure(type)) {
return STRUCTURE;
}
throw new BlenderFileException("Unknown data type: " + type);

@ -36,12 +36,14 @@ package com.jme3.scene.plugins.blender.exception;
* @author Marcin Roguski
*/
public class BlenderFileException extends Exception {
private static final long serialVersionUID = 7573482836437866767L;
/**
* Constructor. Creates an exception with no description.
*/
public BlenderFileException() {}
public BlenderFileException() {
}
/**
* Constructor. Creates an exception containing the given message.

@ -46,12 +46,12 @@ import com.jme3.scene.plugins.blender.utils.BlenderInputStream;
import com.jme3.scene.plugins.blender.utils.DataRepository;
import com.jme3.scene.plugins.blender.utils.Pointer;
/**
* This class defines the methods to calculate certain aspects of animation and armature functionalities.
* @author Marcin Roguski
*/
public class ArmatureHelper extends com.jme3.scene.plugins.blender.helpers.v249.ArmatureHelper {
private static final Logger LOGGER = Logger.getLogger(ArmatureHelper.class.getName());
/**
@ -66,27 +66,27 @@ public class ArmatureHelper extends com.jme3.scene.plugins.blender.helpers.v249.
@Override
public BoneTrack[] getTracks(Structure actionStructure, DataRepository dataRepository, String objectName, String animationName) throws BlenderFileException {
if(blenderVersion<250) {
if (blenderVersion < 250) {
return super.getTracks(actionStructure, dataRepository, objectName, animationName);
}
LOGGER.log(Level.INFO, "Getting tracks!");
int fps = dataRepository.getBlenderKey().getFps();
int[] animationFrames = dataRepository.getBlenderKey().getAnimationFrames(objectName, animationName);
Structure groups = (Structure)actionStructure.getFieldValue("groups");
Structure groups = (Structure) actionStructure.getFieldValue("groups");
List<Structure> actionGroups = groups.evaluateListBase(dataRepository);//bActionGroup
if(actionGroups != null && actionGroups.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
if (actionGroups != null && actionGroups.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
}
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
for(Structure actionGroup : actionGroups) {
for (Structure actionGroup : actionGroups) {
String name = actionGroup.getFieldValue("name").toString();
Integer boneIndex = bonesMap.get(name);
if(boneIndex != null) {
List<Structure> channels = ((Structure)actionGroup.getFieldValue("channels")).evaluateListBase(dataRepository);
if (boneIndex != null) {
List<Structure> channels = ((Structure) actionGroup.getFieldValue("channels")).evaluateListBase(dataRepository);
BezierCurve[] bezierCurves = new BezierCurve[channels.size()];
int channelCounter = 0;
for(Structure c : channels) {
for (Structure c : channels) {
//reading rna path first
BlenderInputStream bis = dataRepository.getInputStream();
int currentPosition = bis.getPosition();
@ -95,10 +95,10 @@ public class ArmatureHelper extends com.jme3.scene.plugins.blender.helpers.v249.
bis.setPosition(dataFileBlock.getBlockPosition());
String rnaPath = bis.readString();
bis.setPosition(currentPosition);
int arrayIndex = ((Number)c.getFieldValue("array_index")).intValue();
int arrayIndex = ((Number) c.getFieldValue("array_index")).intValue();
int type = this.getCurveType(rnaPath, arrayIndex);
Pointer pBezTriple = (Pointer)c.getFieldValue("bezt");
Pointer pBezTriple = (Pointer) c.getFieldValue("bezt");
List<Structure> bezTriples = pBezTriple.fetchData(dataRepository.getInputStream());
bezierCurves[channelCounter++] = new BezierCurve(type, bezTriples, 2);
}
@ -118,13 +118,13 @@ public class ArmatureHelper extends com.jme3.scene.plugins.blender.helpers.v249.
* @return the type of the curve
*/
protected int getCurveType(String rnaPath, int arrayIndex) {
if(rnaPath.endsWith(".location")) {
if (rnaPath.endsWith(".location")) {
return Ipo.AC_LOC_X + arrayIndex;
}
if(rnaPath.endsWith(".rotation_quaternion")) {
if (rnaPath.endsWith(".rotation_quaternion")) {
return Ipo.AC_QUAT_W + arrayIndex;
}
if(rnaPath.endsWith(".scale")) {
if (rnaPath.endsWith(".scale")) {
return Ipo.AC_SIZE_X + arrayIndex;
}
throw new IllegalStateException("Unknown curve rna path: " + rnaPath);

@ -12,6 +12,7 @@ import com.jme3.scene.plugins.blender.exception.BlenderFileException;
* @author Marcin Roguski
*/
public class CameraHelper extends com.jme3.scene.plugins.blender.helpers.v249.CameraHelper {
private static final Logger LOGGER = Logger.getLogger(CameraHelper.class.getName());
/**
@ -26,24 +27,24 @@ public class CameraHelper extends com.jme3.scene.plugins.blender.helpers.v249.Ca
@Override
public Camera toCamera(Structure structure) throws BlenderFileException {
if(blenderVersion<250) {
if (blenderVersion < 250) {
return super.toCamera(structure);
}
Camera result = new Camera(DEFAULT_CAM_WIDTH, DEFAULT_CAM_HEIGHT);
int type = ((Number)structure.getFieldValue("type")).intValue();
if(type != 0 && type != 1) {
LOGGER.log(Level.WARNING, "Unknown camera type: " + type + ". Perspective camera is being used!");
int type = ((Number) structure.getFieldValue("type")).intValue();
if (type != 0 && type != 1) {
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
type = 0;
}
//type==0 - perspective; type==1 - orthographic; perspective is used as default
result.setParallelProjection(type == 1);
float aspect = 0;
float clipsta = ((Number)structure.getFieldValue("clipsta")).floatValue();
float clipend = ((Number)structure.getFieldValue("clipend")).floatValue();
if(type == 0) {
aspect = ((Number)structure.getFieldValue("lens")).floatValue();
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
if (type == 0) {
aspect = ((Number) structure.getFieldValue("lens")).floatValue();
} else {
aspect = ((Number)structure.getFieldValue("ortho_scale")).floatValue();
aspect = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
}
result.setFrustumPerspective(45, aspect, clipsta, clipend);
return result;

@ -11,6 +11,7 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
* @author Marcin Roguski
*/
public class ConstraintHelper extends com.jme3.scene.plugins.blender.helpers.v249.ConstraintHelper {
private static final Logger LOGGER = Logger.getLogger(ConstraintHelper.class.getName());
/**
@ -27,7 +28,7 @@ public class ConstraintHelper extends com.jme3.scene.plugins.blender.helpers.v24
@Override
public void loadConstraints(Structure objectStructure, DataRepository dataRepository) throws BlenderFileException {
if(blenderVersion<250) {
if (blenderVersion < 250) {
super.loadConstraints(objectStructure, dataRepository);
} else {
LOGGER.warning("Loading of constraints not yet implemented for version 2.5x !");

@ -5,6 +5,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class CurvesHelper extends com.jme3.scene.plugins.blender.helpers.v249.CurvesHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -6,6 +6,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class IpoHelper extends com.jme3.scene.plugins.blender.helpers.v249.IpoHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -36,6 +36,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class LightHelper extends com.jme3.scene.plugins.blender.helpers.v249.LightHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -32,6 +32,7 @@
package com.jme3.scene.plugins.blender.helpers;
public class MaterialHelper extends com.jme3.scene.plugins.blender.helpers.v249.MaterialHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -36,6 +36,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class MeshHelper extends com.jme3.scene.plugins.blender.helpers.v249.MeshHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -36,6 +36,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class ModifierHelper extends com.jme3.scene.plugins.blender.helpers.v249.ModifierHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -39,6 +39,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski (Kaelthas)
*/
public class NoiseHelper extends com.jme3.scene.plugins.blender.helpers.v249.NoiseHelper {
/**
* Constructor. Stores the blender version number and loads the constants needed for computations.
*

@ -36,6 +36,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski
*/
public class ObjectHelper extends com.jme3.scene.plugins.blender.helpers.v249.ObjectHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -5,6 +5,7 @@ package com.jme3.scene.plugins.blender.helpers;
* @author Marcin Roguski (Kaelthas)
*/
public class ParticlesHelper extends com.jme3.scene.plugins.blender.helpers.v249.ParticlesHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.

@ -44,9 +44,11 @@ import com.jme3.texture.Texture;
* @author Marcin Roguski
*/
public class TextureHelper extends com.jme3.scene.plugins.blender.helpers.v249.TextureHelper {
private static final Logger LOGGER = Logger.getLogger(TextureHelper.class.getName());
public static final int TEX_POINTDENSITY = 14;
public static final int TEX_VOXELDATA = 15;
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.
@ -59,15 +61,15 @@ public class TextureHelper extends com.jme3.scene.plugins.blender.helpers.v249.T
@Override
public Texture getTexture(Structure tex, DataRepository dataRepository) throws BlenderFileException {
if(blenderVersion<250) {
if (blenderVersion < 250) {
return super.getTexture(tex, dataRepository);
}
Texture result = (Texture) dataRepository.getLoadedFeature(tex.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
if (result != null) {
return result;
}
int type = ((Number)tex.getFieldValue("type")).intValue();
switch(type) {
int type = ((Number) tex.getFieldValue("type")).intValue();
switch (type) {
case TEX_POINTDENSITY:
LOGGER.warning("Point density texture loading currently not supported!");
break;

@ -60,8 +60,8 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* @author Marcin Roguski
*/
public class ArmatureHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(ArmatureHelper.class.getName());
private static final Logger LOGGER = Logger.getLogger(ArmatureHelper.class.getName());
/**
* The map of the bones. Maps a bone name to its index in the armature. Should be cleared after the object had been
* read. TODO: probably bones can have identical names in different armatures
@ -91,7 +91,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
*/
public Long getBoneOMA(Bone bone) {
Long result = bonesOMAs.get(bone);
if(result == null) {
if (result == null) {
result = Long.valueOf(0);
}
return result;
@ -109,9 +109,9 @@ public class ArmatureHelper extends AbstractBlenderHelper {
*/
public Skeleton toArmature(Structure structure, DataRepository dataRepository) throws BlenderFileException {
LOGGER.log(Level.INFO, "Converting structure to Armature!");
Structure bonebase = (Structure)structure.getFieldValue("bonebase");
Structure bonebase = (Structure) structure.getFieldValue("bonebase");
List<Structure> bonesStructures = bonebase.evaluateListBase(dataRepository);
for(Structure boneStructure : bonesStructures) {
for (Structure boneStructure : bonesStructures) {
BoneTransformationData rootBoneTransformationData = this.readBoneAndItsChildren(boneStructure, null, dataRepository);
boneDataRoots.add(rootBoneTransformationData);
}
@ -129,14 +129,14 @@ public class ArmatureHelper extends AbstractBlenderHelper {
*/
public Map<Integer, Integer> getGroupToBoneIndexMap(Structure defBaseStructure, DataRepository dataRepository) throws BlenderFileException {
Map<Integer, Integer> result = null;
if(bonesMap != null && bonesMap.size() != 0) {
if (bonesMap != null && bonesMap.size() != 0) {
result = new HashMap<Integer, Integer>();
List<Structure> deformGroups = defBaseStructure.evaluateListBase(dataRepository);//bDeformGroup
int groupIndex = 0;//TODO: consider many armatures attached to one object in the future !!!
for(Structure deformGroup : deformGroups) {
for (Structure deformGroup : deformGroups) {
String deformGroupName = deformGroup.getFieldValue("name").toString();
Integer boneIndex = bonesMap.get(deformGroupName);
if(boneIndex != null) {
if (boneIndex != null) {
result.put(Integer.valueOf(groupIndex), boneIndex);
}
++groupIndex;
@ -163,18 +163,18 @@ public class ArmatureHelper extends AbstractBlenderHelper {
IpoHelper ipoHelper = dataRepository.getHelper(IpoHelper.class);
int fps = dataRepository.getBlenderKey().getFps();
int[] animationFrames = dataRepository.getBlenderKey().getAnimationFrames(objectName, animationName);
Structure chanbase = (Structure)actionStructure.getFieldValue("chanbase");
Structure chanbase = (Structure) actionStructure.getFieldValue("chanbase");
List<Structure> actionChannels = chanbase.evaluateListBase(dataRepository);//bActionChannel
if(actionChannels != null && actionChannels.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
if (actionChannels != null && actionChannels.size() > 0 && (bonesMap == null || bonesMap.size() == 0)) {
throw new IllegalStateException("No bones found! Cannot proceed to calculating tracks!");
}
List<BoneTrack> tracks = new ArrayList<BoneTrack>();
for(Structure bActionChannel : actionChannels) {
for (Structure bActionChannel : actionChannels) {
String name = bActionChannel.getFieldValue("name").toString();
Integer boneIndex = bonesMap.get(name);
if(boneIndex != null) {
Pointer p = (Pointer)bActionChannel.getFieldValue("ipo");
if(!p.isNull()) {
if (boneIndex != null) {
Pointer p = (Pointer) bActionChannel.getFieldValue("ipo");
if (!p.isNull()) {
Structure ipoStructure = p.fetchData(dataRepository.getInputStream()).get(0);
Ipo ipo = ipoHelper.createIpo(ipoStructure, dataRepository);
tracks.add(ipo.calculateTrack(boneIndex.intValue(), animationFrames[0], animationFrames[1], fps));
@ -192,10 +192,10 @@ public class ArmatureHelper extends AbstractBlenderHelper {
*/
@SuppressWarnings("unchecked")
protected Matrix4f getArmatureMatrix(Structure boneStructure) {
DynamicArray<Number> boneMat = (DynamicArray<Number>)boneStructure.getFieldValue("arm_mat");
DynamicArray<Number> boneMat = (DynamicArray<Number>) boneStructure.getFieldValue("arm_mat");
Matrix4f m = new Matrix4f();
for(int i = 0; i < 4; ++i) {
for(int j = 0; j < 4; ++j) {
for (int i = 0; i < 4; ++i) {
for (int j = 0; j < 4; ++j) {
m.set(i, j, boneMat.get(j, i).floatValue());
}
}
@ -220,7 +220,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
Bone bone = new Bone(name);
int bonesAmount = bonesOMAs.size();
bonesOMAs.put(bone, boneStructure.getOldMemoryAddress());
if(bonesAmount == bonesOMAs.size()) {
if (bonesAmount == bonesOMAs.size()) {
throw new IllegalStateException("Two bones has the same hash value and thereforw a bone was overriden in the bones<->OMA map! Improve the hash algorithm!");
}
Matrix4f boneArmatureMatrix = this.getArmatureMatrix(boneStructure);
@ -229,9 +229,9 @@ public class ArmatureHelper extends AbstractBlenderHelper {
BoneTransformationData boneTransformationData = new BoneTransformationData(boneArmatureMatrix, size, bone, parent);
dataRepository.addLoadedFeatures(boneStructure.getOldMemoryAddress(), name, boneStructure, bone);
Structure childbase = (Structure)boneStructure.getFieldValue("childbase");
Structure childbase = (Structure) boneStructure.getFieldValue("childbase");
List<Structure> children = childbase.evaluateListBase(dataRepository);//Bone
for(Structure boneChild : children) {
for (Structure boneChild : children) {
this.readBoneAndItsChildren(boneChild, boneTransformationData, dataRepository);
}
return boneTransformationData;
@ -258,8 +258,8 @@ public class ArmatureHelper extends AbstractBlenderHelper {
btd.bone.setBindTransforms(restMatrix.toTranslationVector(), restMatrix.toRotationQuat(), btd.size);
boneList.add(btd.bone);
bonesMap.put(btd.bone.getName(), Integer.valueOf(boneList.size() - 1));
if(btd.children != null && btd.children.size() > 0) {
for(BoneTransformationData child : btd.children) {
if (btd.children != null && btd.children.size() > 0) {
for (BoneTransformationData child : btd.children) {
this.assignBonesMatrices(child, additionalRootBoneTransformation, boneList);
btd.bone.addChild(child.bone);
}
@ -289,6 +289,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
* @author Marcin Roguski
*/
private static class BoneTransformationData {
/** Inverse matrix of bone's parent bone. */
private Matrix4f totalInverseBoneParentMatrix;
/** Bone's matrix in armature's space. */
@ -319,7 +320,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
this.bone = bone;
this.parent = parent;
this.children = new ArrayList<ArmatureHelper.BoneTransformationData>();
if(this.parent != null) {
if (this.parent != null) {
this.parent.children.add(this);
}
}
@ -337,7 +338,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
public Bone[] buildBonesStructure(Long armatureOMA, Matrix4f additionalRootBoneTransformation) {//TODO: uwzględnić wiele szkieletów
List<Bone> bones = new ArrayList<Bone>(boneDataRoots.size() + 1);
bones.add(new Bone(null));
for(BoneTransformationData btd : boneDataRoots) {
for (BoneTransformationData btd : boneDataRoots) {
this.assignBonesMatrices(btd, additionalRootBoneTransformation, bones);
}
return bones.toArray(new Bone[bones.size()]);
@ -354,9 +355,9 @@ public class ArmatureHelper extends AbstractBlenderHelper {
public void assignBoneToOrphanedVertices(byte immovableBoneIndex, Mesh[] meshes) {
//bone indices are common for all the object's meshes (vertex indices specify which are to be used)
VertexBuffer boneIndices = meshes[0].getBuffer(Type.BoneIndex);//common buffer to all the meshes
ByteBuffer data = (ByteBuffer)boneIndices.getData();
for(int i = 0; i < boneIndices.getNumElements(); ++i) {
if(data.get(i) == -1) {
ByteBuffer data = (ByteBuffer) boneIndices.getData();
for (int i = 0; i < boneIndices.getNumElements(); ++i) {
if (data.get(i) == -1) {
data.put(i, immovableBoneIndex);
}
}

@ -13,10 +13,11 @@ import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
* @author Marcin Roguski
*/
public class CameraHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(CameraHelper.class.getName());
private static final Logger LOGGER = Logger.getLogger(CameraHelper.class.getName());
protected static final int DEFAULT_CAM_WIDTH = 100;
protected static final int DEFAULT_CAM_HEIGHT = 100;
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.
@ -35,21 +36,21 @@ public class CameraHelper extends AbstractBlenderHelper {
*/
public Camera toCamera(Structure structure) throws BlenderFileException {
Camera result = new Camera(DEFAULT_CAM_WIDTH, DEFAULT_CAM_HEIGHT);
int type = ((Number)structure.getFieldValue("type")).intValue();
if(type != 0 && type != 1) {
LOGGER.log(Level.WARNING, "Unknown camera type: " + type + ". Perspective camera is being used!");
int type = ((Number) structure.getFieldValue("type")).intValue();
if (type != 0 && type != 1) {
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
type = 0;
}
//type==0 - perspective; type==1 - orthographic; perspective is used as default
result.setParallelProjection(type == 1);
float angle = ((Number)structure.getFieldValue("angle")).floatValue();
float angle = ((Number) structure.getFieldValue("angle")).floatValue();
float aspect = 0;
float clipsta = ((Number)structure.getFieldValue("clipsta")).floatValue();
float clipend = ((Number)structure.getFieldValue("clipend")).floatValue();
if(type == 0) {
aspect = ((Number)structure.getFieldValue("lens")).floatValue();
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
if (type == 0) {
aspect = ((Number) structure.getFieldValue("lens")).floatValue();
} else {
aspect = ((Number)structure.getFieldValue("ortho_scale")).floatValue();
aspect = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
}
result.setFrustumPerspective(angle, aspect, clipsta, clipend);
return result;

@ -24,18 +24,19 @@ import com.jme3.scene.plugins.blender.structures.Ipo;
import com.jme3.scene.plugins.blender.utils.AbstractBlenderHelper;
import com.jme3.scene.plugins.blender.utils.DataRepository;
import com.jme3.scene.plugins.blender.utils.Pointer;
import java.util.logging.Level;
/**
* This class should be used for constraint calculations.
* @author Marcin Roguski
*/
public class ConstraintHelper extends AbstractBlenderHelper {
/**
* A table containing implementations of influence functions for constraints. It should contain functions for
* blender at least 249 and higher.
*/
protected static AbstractInfluenceFunction[] influenceFunctions;
/**
* Constraints stored for object with the given old memory address.
*/
@ -51,47 +52,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
*/
public ConstraintHelper(String blenderVersion, DataRepository dataRepository) {
super(blenderVersion);
if(influenceFunctions == null) {
if (influenceFunctions == null) {
//TODO: synchronization
influenceFunctions = new AbstractInfluenceFunction[ConstraintType.getLastDefinedTypeValue() + 1];
//ACTION constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_ACTION.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_ACTION, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_ACTION.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_ACTION, dataRepository) {
};
//CHILDOF constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_CHILDOF.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_CHILDOF, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_CHILDOF.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_CHILDOF, dataRepository) {
};
//CLAMPTO constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_CLAMPTO.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_CLAMPTO, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
this.validateConstraintType(constraint.getData());
LOGGER.info(constraint.getName() + " not active! Curves not yet implemented!");//TODO: implement when curves are implemented
LOGGER.log(Level.INFO, "{0} not active! Curves not yet implemented!", constraint.getName());//TODO: implement when curves are implemented
}
};
//DISTLIMIT constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_DISTLIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_DISTLIMIT, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintStructure = constraint.getData();
this.validateConstraintType(constraintStructure);
Vector3f targetLocation = this.getTargetLocation(constraint);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
if (boneTrack != null) {
//TODO: target vertex group !!!
float dist = ((Number)constraintStructure.getFieldValue("dist")).floatValue();
int mode = ((Number)constraintStructure.getFieldValue("mode")).intValue();
float dist = ((Number) constraintStructure.getFieldValue("dist")).floatValue();
int mode = ((Number) constraintStructure.getFieldValue("mode")).intValue();
int maxFrames = boneTrack.getTimes().length;
Vector3f[] translations = boneTrack.getTranslations();
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
Vector3f v = translations[frame].subtract(targetLocation);
float currentDistance = v.length();
float influence = constraint.getIpo().calculateValue(frame);
float modifier = 0.0f;
switch(mode) {
switch (mode) {
case LIMITDIST_INSIDE:
if(currentDistance >= dist) {
if (currentDistance >= dist) {
modifier = (dist - currentDistance) / currentDistance;
}
break;
@ -99,7 +104,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
modifier = (dist - currentDistance) / currentDistance;
break;
case LIMITDIST_OUTSIDE:
if(currentDistance <= dist) {
if (currentDistance <= dist) {
modifier = (dist - currentDistance) / currentDistance;
}
break;
@ -115,15 +120,17 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//FOLLOWPATH constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_FOLLOWPATH.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_FOLLOWPATH, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
this.validateConstraintType(constraint.getData());
LOGGER.info(constraint.getName() + " not active! Curves not yet implemented!");//TODO: implement when curves are implemented
LOGGER.log(Level.INFO, "{0} not active! Curves not yet implemented!", constraint.getName());//TODO: implement when curves are implemented
}
};
//KINEMATIC constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_KINEMATIC.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_KINEMATIC, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintStructure = constraint.getData();
@ -207,17 +214,17 @@ public class ConstraintHelper extends AbstractBlenderHelper {
Bone currentBone = bone;
do {
int boneIndex = skeleton.getBoneIndex(currentBone);
for(int i = 0; i < boneAnimation.getTracks().length; ++i) {
if(boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) {
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);
} while (currentBone != null);
//attaching children
CalculationBone[] result = bonesList.toArray(new CalculationBone[bonesList.size()]);
for(int i = result.length - 1; i > 0; --i) {
for (int i = result.length - 1; i > 0; --i) {
result[i].attachChild(result[i - 1]);
}
return result;
@ -225,39 +232,41 @@ public class ConstraintHelper extends AbstractBlenderHelper {
};
//LOCKTRACK constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_LOCKTRACK.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_LOCKTRACK, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_LOCKTRACK.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_LOCKTRACK, dataRepository) {
};
//LOCLIKE constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_LOCLIKE.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_LOCLIKE, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintData = constraint.getData();
this.validateConstraintType(constraintData);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
if (boneTrack != null) {
Vector3f targetLocation = this.getTargetLocation(constraint);
int flag = ((Number)constraintData.getFieldValue("flag")).intValue();
int flag = ((Number) constraintData.getFieldValue("flag")).intValue();
Vector3f[] translations = boneTrack.getTranslations();
int maxFrames = translations.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
Vector3f offset = Vector3f.ZERO;
if((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
offset = translations[frame].clone();
}
if((flag & LOCLIKE_X) != 0) {
if ((flag & LOCLIKE_X) != 0) {
translations[frame].x = targetLocation.x;
if((flag & LOCLIKE_X_INVERT) != 0) {
if ((flag & LOCLIKE_X_INVERT) != 0) {
translations[frame].x = -translations[frame].x;
}
} else if((flag & LOCLIKE_Y) != 0) {
} else if ((flag & LOCLIKE_Y) != 0) {
translations[frame].y = targetLocation.y;
if((flag & LOCLIKE_Y_INVERT) != 0) {
if ((flag & LOCLIKE_Y_INVERT) != 0) {
translations[frame].y = -translations[frame].y;
}
} else if((flag & LOCLIKE_Z) != 0) {
} else if ((flag & LOCLIKE_Z) != 0) {
translations[frame].z = targetLocation.z;
if((flag & LOCLIKE_Z_INVERT) != 0) {
if ((flag & LOCLIKE_Z_INVERT) != 0) {
translations[frame].z = -translations[frame].z;
}
}
@ -270,50 +279,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//LOCLIMIT constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_LOCLIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_LOCLIMIT, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintStructure = constraint.getData();
this.validateConstraintType(constraintStructure);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
int flag = ((Number)constraintStructure.getFieldValue("flag")).intValue();
if (boneTrack != null) {
int flag = ((Number) constraintStructure.getFieldValue("flag")).intValue();
Vector3f[] translations = boneTrack.getTranslations();
int maxFrames = translations.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
float influence = constraint.getIpo().calculateValue(frame);
if((flag & LIMIT_XMIN) != 0) {
float xmin = ((Number)constraintStructure.getFieldValue("xmin")).floatValue();
if(translations[frame].x < xmin) {
if ((flag & LIMIT_XMIN) != 0) {
float xmin = ((Number) constraintStructure.getFieldValue("xmin")).floatValue();
if (translations[frame].x < xmin) {
translations[frame].x -= (translations[frame].x - xmin) * influence;
}
}
if((flag & LIMIT_XMAX) != 0) {
float xmax = ((Number)constraintStructure.getFieldValue("xmax")).floatValue();
if(translations[frame].x > xmax) {
if ((flag & LIMIT_XMAX) != 0) {
float xmax = ((Number) constraintStructure.getFieldValue("xmax")).floatValue();
if (translations[frame].x > xmax) {
translations[frame].x -= (translations[frame].x - xmax) * influence;
}
}
if((flag & LIMIT_YMIN) != 0) {
float ymin = ((Number)constraintStructure.getFieldValue("ymin")).floatValue();
if(translations[frame].y < ymin) {
if ((flag & LIMIT_YMIN) != 0) {
float ymin = ((Number) constraintStructure.getFieldValue("ymin")).floatValue();
if (translations[frame].y < ymin) {
translations[frame].y -= (translations[frame].y - ymin) * influence;
}
}
if((flag & LIMIT_YMAX) != 0) {
float ymax = ((Number)constraintStructure.getFieldValue("ymax")).floatValue();
if(translations[frame].y > ymax) {
if ((flag & LIMIT_YMAX) != 0) {
float ymax = ((Number) constraintStructure.getFieldValue("ymax")).floatValue();
if (translations[frame].y > ymax) {
translations[frame].y -= (translations[frame].y - ymax) * influence;
}
}
if((flag & LIMIT_ZMIN) != 0) {
float zmin = ((Number)constraintStructure.getFieldValue("zmin")).floatValue();
if(translations[frame].z < zmin) {
if ((flag & LIMIT_ZMIN) != 0) {
float zmin = ((Number) constraintStructure.getFieldValue("zmin")).floatValue();
if (translations[frame].z < zmin) {
translations[frame].z -= (translations[frame].z - zmin) * influence;
}
}
if((flag & LIMIT_ZMAX) != 0) {
float zmax = ((Number)constraintStructure.getFieldValue("zmax")).floatValue();
if(translations[frame].z > zmax) {
if ((flag & LIMIT_ZMAX) != 0) {
float zmax = ((Number) constraintStructure.getFieldValue("zmax")).floatValue();
if (translations[frame].z > zmax) {
translations[frame].z -= (translations[frame].z - zmax) * influence;
}
}//TODO: consider constraint space !!!
@ -324,51 +334,56 @@ public class ConstraintHelper extends AbstractBlenderHelper {
};
//MINMAX constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_MINMAX.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_MINMAX, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_MINMAX.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_MINMAX, dataRepository) {
};
//NULL constraint - does nothing
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_NULL.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_NULL, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_NULL.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_NULL, dataRepository) {
};
//PYTHON constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_PYTHON.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_PYTHON, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_PYTHON.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_PYTHON, dataRepository) {
};
//RIGIDBODYJOINT constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_RIGIDBODYJOINT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_RIGIDBODYJOINT, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_RIGIDBODYJOINT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_RIGIDBODYJOINT, dataRepository) {
};
//ROTLIKE constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_ROTLIKE.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_ROTLIKE, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintData = constraint.getData();
this.validateConstraintType(constraintData);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
if (boneTrack != null) {
Quaternion targetRotation = this.getTargetRotation(constraint);
int flag = ((Number)constraintData.getFieldValue("flag")).intValue();
int flag = ((Number) constraintData.getFieldValue("flag")).intValue();
float[] targetAngles = targetRotation.toAngles(null);
Quaternion[] rotations = boneTrack.getRotations();
int maxFrames = rotations.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
float[] angles = rotations[frame].toAngles(null);
Quaternion offset = Quaternion.IDENTITY;
if((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation
if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation
offset = rotations[frame].clone();
}
if((flag & ROTLIKE_X) != 0) {
if ((flag & ROTLIKE_X) != 0) {
angles[0] = targetAngles[0];
if((flag & ROTLIKE_X_INVERT) != 0) {
if ((flag & ROTLIKE_X_INVERT) != 0) {
angles[0] = -angles[0];
}
} else if((flag & ROTLIKE_Y) != 0) {
} else if ((flag & ROTLIKE_Y) != 0) {
angles[1] = targetAngles[1];
if((flag & ROTLIKE_Y_INVERT) != 0) {
if ((flag & ROTLIKE_Y_INVERT) != 0) {
angles[1] = -angles[1];
}
} else if((flag & ROTLIKE_Z) != 0) {
} else if ((flag & ROTLIKE_Z) != 0) {
angles[2] = targetAngles[2];
if((flag & ROTLIKE_Z_INVERT) != 0) {
if ((flag & ROTLIKE_Z_INVERT) != 0) {
angles[2] = -angles[2];
}
}
@ -381,47 +396,48 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//ROTLIMIT constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_ROTLIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_ROTLIMIT, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintStructure = constraint.getData();
this.validateConstraintType(constraintStructure);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
int flag = ((Number)constraintStructure.getFieldValue("flag")).intValue();
if (boneTrack != null) {
int flag = ((Number) constraintStructure.getFieldValue("flag")).intValue();
Quaternion[] rotations = boneTrack.getRotations();
int maxFrames = rotations.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
float[] angles = rotations[frame].toAngles(null);
float influence = constraint.getIpo().calculateValue(frame);
if((flag & LIMIT_XROT) != 0) {
float xmin = ((Number)constraintStructure.getFieldValue("xmin")).floatValue() * FastMath.DEG_TO_RAD;
float xmax = ((Number)constraintStructure.getFieldValue("xmax")).floatValue() * FastMath.DEG_TO_RAD;
if ((flag & LIMIT_XROT) != 0) {
float xmin = ((Number) constraintStructure.getFieldValue("xmin")).floatValue() * FastMath.DEG_TO_RAD;
float xmax = ((Number) constraintStructure.getFieldValue("xmax")).floatValue() * FastMath.DEG_TO_RAD;
float difference = 0.0f;
if(angles[0] < xmin) {
if (angles[0] < xmin) {
difference = (angles[0] - xmin) * influence;
} else if(angles[0] > xmax) {
} else if (angles[0] > xmax) {
difference = (angles[0] - xmax) * influence;
}
angles[0] -= difference;
}
if((flag & LIMIT_YROT) != 0) {
float ymin = ((Number)constraintStructure.getFieldValue("ymin")).floatValue() * FastMath.DEG_TO_RAD;
float ymax = ((Number)constraintStructure.getFieldValue("ymax")).floatValue() * FastMath.DEG_TO_RAD;
if ((flag & LIMIT_YROT) != 0) {
float ymin = ((Number) constraintStructure.getFieldValue("ymin")).floatValue() * FastMath.DEG_TO_RAD;
float ymax = ((Number) constraintStructure.getFieldValue("ymax")).floatValue() * FastMath.DEG_TO_RAD;
float difference = 0.0f;
if(angles[1] < ymin) {
if (angles[1] < ymin) {
difference = (angles[1] - ymin) * influence;
} else if(angles[1] > ymax) {
} else if (angles[1] > ymax) {
difference = (angles[1] - ymax) * influence;
}
angles[1] -= difference;
}
if((flag & LIMIT_ZROT) != 0) {
float zmin = ((Number)constraintStructure.getFieldValue("zmin")).floatValue() * FastMath.DEG_TO_RAD;
float zmax = ((Number)constraintStructure.getFieldValue("zmax")).floatValue() * FastMath.DEG_TO_RAD;
if ((flag & LIMIT_ZROT) != 0) {
float zmin = ((Number) constraintStructure.getFieldValue("zmin")).floatValue() * FastMath.DEG_TO_RAD;
float zmax = ((Number) constraintStructure.getFieldValue("zmax")).floatValue() * FastMath.DEG_TO_RAD;
float difference = 0.0f;
if(angles[2] < zmin) {
if (angles[2] < zmin) {
difference = (angles[2] - zmin) * influence;
} else if(angles[2] > zmax) {
} else if (angles[2] > zmax) {
difference = (angles[2] - zmax) * influence;
}
angles[2] -= difference;
@ -434,31 +450,33 @@ public class ConstraintHelper extends AbstractBlenderHelper {
};
//SHRINKWRAP constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SHRINKWRAP, dataRepository) {
};
//SIZELIKE constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SIZELIKE.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SIZELIKE, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintData = constraint.getData();
this.validateConstraintType(constraintData);
Vector3f targetScale = this.getTargetLocation(constraint);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
int flag = ((Number)constraintData.getFieldValue("flag")).intValue();
if (boneTrack != null) {
int flag = ((Number) constraintData.getFieldValue("flag")).intValue();
Vector3f[] scales = boneTrack.getScales();
int maxFrames = scales.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
Vector3f offset = Vector3f.ZERO;
if((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale
if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale
offset = scales[frame].clone();
}
if((flag & SIZELIKE_X) != 0) {
if ((flag & SIZELIKE_X) != 0) {
scales[frame].x = targetScale.x;
} else if((flag & SIZELIKE_Y) != 0) {
} else if ((flag & SIZELIKE_Y) != 0) {
scales[frame].y = targetScale.y;
} else if((flag & SIZELIKE_Z) != 0) {
} else if ((flag & SIZELIKE_Z) != 0) {
scales[frame].z = targetScale.z;
}
scales[frame].addLocal(offset);//TODO: ipo influence
@ -471,50 +489,51 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//SIZELIMIT constraint
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_SIZELIMIT.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_SIZELIMIT, dataRepository) {
@Override
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Structure constraintStructure = constraint.getData();
this.validateConstraintType(constraintStructure);
BoneTrack boneTrack = this.getBoneTrack(skeleton, boneAnimation, constraint);
if(boneTrack != null) {
int flag = ((Number)constraintStructure.getFieldValue("flag")).intValue();
if (boneTrack != null) {
int flag = ((Number) constraintStructure.getFieldValue("flag")).intValue();
Vector3f[] scales = boneTrack.getScales();
int maxFrames = scales.length;
for(int frame = 0; frame < maxFrames; ++frame) {
for (int frame = 0; frame < maxFrames; ++frame) {
float influence = constraint.getIpo().calculateValue(frame);
if((flag & LIMIT_XMIN) != 0) {
float xmin = ((Number)constraintStructure.getFieldValue("xmin")).floatValue();
if(scales[frame].x < xmin) {
if ((flag & LIMIT_XMIN) != 0) {
float xmin = ((Number) constraintStructure.getFieldValue("xmin")).floatValue();
if (scales[frame].x < xmin) {
scales[frame].x -= (scales[frame].x - xmin) * influence;
}
}
if((flag & LIMIT_XMAX) != 0) {
float xmax = ((Number)constraintStructure.getFieldValue("xmax")).floatValue();
if(scales[frame].x > xmax) {
if ((flag & LIMIT_XMAX) != 0) {
float xmax = ((Number) constraintStructure.getFieldValue("xmax")).floatValue();
if (scales[frame].x > xmax) {
scales[frame].x -= (scales[frame].x - xmax) * influence;
}
}
if((flag & LIMIT_YMIN) != 0) {
float ymin = ((Number)constraintStructure.getFieldValue("ymin")).floatValue();
if(scales[frame].y < ymin) {
if ((flag & LIMIT_YMIN) != 0) {
float ymin = ((Number) constraintStructure.getFieldValue("ymin")).floatValue();
if (scales[frame].y < ymin) {
scales[frame].y -= (scales[frame].y - ymin) * influence;
}
}
if((flag & LIMIT_YMAX) != 0) {
float ymax = ((Number)constraintStructure.getFieldValue("ymax")).floatValue();
if(scales[frame].y > ymax) {
if ((flag & LIMIT_YMAX) != 0) {
float ymax = ((Number) constraintStructure.getFieldValue("ymax")).floatValue();
if (scales[frame].y > ymax) {
scales[frame].y -= (scales[frame].y - ymax) * influence;
}
}
if((flag & LIMIT_ZMIN) != 0) {
float zmin = ((Number)constraintStructure.getFieldValue("zmin")).floatValue();
if(scales[frame].z < zmin) {
if ((flag & LIMIT_ZMIN) != 0) {
float zmin = ((Number) constraintStructure.getFieldValue("zmin")).floatValue();
if (scales[frame].z < zmin) {
scales[frame].z -= (scales[frame].z - zmin) * influence;
}
}
if((flag & LIMIT_ZMAX) != 0) {
float zmax = ((Number)constraintStructure.getFieldValue("zmax")).floatValue();
if(scales[frame].z > zmax) {
if ((flag & LIMIT_ZMAX) != 0) {
float zmax = ((Number) constraintStructure.getFieldValue("zmax")).floatValue();
if (scales[frame].z > zmax) {
scales[frame].z -= (scales[frame].z - zmax) * influence;
}
}//TODO: consider constraint space !!!
@ -525,10 +544,12 @@ public class ConstraintHelper extends AbstractBlenderHelper {
};
//STRETCHTO constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_STRETCHTO.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_STRETCHTO, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_STRETCHTO.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_STRETCHTO, dataRepository) {
};
//TRANSFORM constraint (TODO: to implement)
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_TRANSFORM.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_TRANSFORM, dataRepository) {};
influenceFunctions[ConstraintType.CONSTRAINT_TYPE_TRANSFORM.getConstraintId()] = new AbstractInfluenceFunction(ConstraintType.CONSTRAINT_TYPE_TRANSFORM, dataRepository) {
};
}
}
@ -546,19 +567,19 @@ public class ConstraintHelper extends AbstractBlenderHelper {
// reading influence ipos for the constraints
IpoHelper ipoHelper = dataRepository.getHelper(IpoHelper.class);
Map<String, Map<String, Ipo>> constraintsIpos = new HashMap<String, Map<String, Ipo>>();
Pointer pActions = (Pointer)objectStructure.getFieldValue("action");
if(!pActions.isNull()) {
Pointer pActions = (Pointer) objectStructure.getFieldValue("action");
if (!pActions.isNull()) {
List<Structure> actions = pActions.fetchData(dataRepository.getInputStream());
for(Structure action : actions) {
Structure chanbase = (Structure)action.getFieldValue("chanbase");
for (Structure action : actions) {
Structure chanbase = (Structure) action.getFieldValue("chanbase");
List<Structure> actionChannels = chanbase.evaluateListBase(dataRepository);
for(Structure actionChannel : actionChannels) {
for (Structure actionChannel : actionChannels) {
Map<String, Ipo> ipos = new HashMap<String, Ipo>();
Structure constChannels = (Structure)actionChannel.getFieldValue("constraintChannels");
Structure constChannels = (Structure) actionChannel.getFieldValue("constraintChannels");
List<Structure> constraintChannels = constChannels.evaluateListBase(dataRepository);
for(Structure constraintChannel : constraintChannels) {
Pointer pIpo = (Pointer)constraintChannel.getFieldValue("ipo");
if(!pIpo.isNull()) {
for (Structure constraintChannel : constraintChannels) {
Pointer pIpo = (Pointer) constraintChannel.getFieldValue("ipo");
if (!pIpo.isNull()) {
String constraintName = constraintChannel.getFieldValue("name").toString();
Ipo ipo = ipoHelper.createIpo(pIpo.fetchData(dataRepository.getInputStream()).get(0), dataRepository);
ipos.put(constraintName, ipo);
@ -572,25 +593,25 @@ public class ConstraintHelper extends AbstractBlenderHelper {
//loading constraints connected with the object's bones
List<Constraint> constraintsList = new ArrayList<Constraint>();
Pointer pPose = (Pointer)objectStructure.getFieldValue("pose");//TODO: what if the object has two armatures ????
if(!pPose.isNull()) {
Pointer pPose = (Pointer) objectStructure.getFieldValue("pose");//TODO: what if the object has two armatures ????
if (!pPose.isNull()) {
//getting pose channels
List<Structure> poseChannels = ((Structure)pPose.fetchData(dataRepository.getInputStream()).get(0).getFieldValue("chanbase")).evaluateListBase(dataRepository);
for(Structure poseChannel : poseChannels) {
Long boneOMA = Long.valueOf(((Pointer)poseChannel.getFieldValue("bone")).getOldMemoryAddress());
List<Structure> poseChannels = ((Structure) pPose.fetchData(dataRepository.getInputStream()).get(0).getFieldValue("chanbase")).evaluateListBase(dataRepository);
for (Structure poseChannel : poseChannels) {
Long boneOMA = Long.valueOf(((Pointer) poseChannel.getFieldValue("bone")).getOldMemoryAddress());
//the name is read directly from structure because bone might not yet be loaded
String name = dataRepository.getFileBlock(boneOMA).getStructure(dataRepository).getFieldValue("name").toString();
List<Structure> constraints = ((Structure)poseChannel.getFieldValue("constraints")).evaluateListBase(dataRepository);
for(Structure constraint : constraints) {
int type = ((Number)constraint.getFieldValue("type")).intValue();
List<Structure> constraints = ((Structure) poseChannel.getFieldValue("constraints")).evaluateListBase(dataRepository);
for (Structure constraint : constraints) {
int type = ((Number) constraint.getFieldValue("type")).intValue();
String constraintName = constraint.getFieldValue("name").toString();
Ipo ipo = constraintsIpos.get(name).get(constraintName);
if(ipo == null) {
float enforce = ((Number)constraint.getFieldValue("enforce")).floatValue();
if (ipo == null) {
float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
ipo = ipoHelper.createIpo(enforce);
}
Space ownerSpace = Space.valueOf(((Number)constraint.getFieldValue("ownspace")).byteValue());
Space targetSpace = Space.valueOf(((Number)constraint.getFieldValue("tarspace")).byteValue());
Space ownerSpace = Space.valueOf(((Number) constraint.getFieldValue("ownspace")).byteValue());
Space targetSpace = Space.valueOf(((Number) constraint.getFieldValue("tarspace")).byteValue());
Constraint c = new Constraint(constraint, influenceFunctions[type], boneOMA, ownerSpace, targetSpace, ipo, dataRepository);
constraintsList.add(c);
}
@ -615,7 +636,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
this.constraints.put(objectStructure.getOldMemoryAddress(), result);
}
*/
if(constraintsList.size() > 0) {
if (constraintsList.size() > 0) {
this.constraints.put(objectStructure.getOldMemoryAddress(), constraintsList.toArray(new Constraint[constraintsList.size()]));
}
}
@ -640,6 +661,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
* @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. */
@ -650,7 +672,6 @@ public class ConstraintHelper extends AbstractBlenderHelper {
private Quaternion startRotation;
/** The starting scale of the bone. */
private Vector3f startScale;
private Vector3f[] translations;
private Quaternion[] rotations;
private Vector3f[] scales;
@ -682,7 +703,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
*/
//TODO: set to Z axis if user defined it this way
public Vector3f getEndPoint() {
if(this.getParent() == null) {
if (this.getParent() == null) {
return new Vector3f(0, this.getLocalScale().y, 0);
} else {
Node parent = this.getParent();
@ -701,7 +722,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
@Override
public int attachChild(Spatial child) {
if(this.getChildren() != null && this.getChildren().size() > 1) {
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);
@ -710,13 +731,13 @@ public class ConstraintHelper extends AbstractBlenderHelper {
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);
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) {
if (scales != null) {
scales[frame].set(this.getLocalScale());
}
return spatial;
@ -728,7 +749,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
@Override
public String toString() {
return boneName+ ": " + this.getLocalRotation() + " " + this.getLocalTranslation();
return boneName + ": " + this.getLocalRotation() + " " + this.getLocalTranslation();
}
}
}

@ -39,8 +39,8 @@ import com.jme3.util.BufferUtils;
* @author Marcin Roguski
*/
public class CurvesHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(CurvesHelper.class.getName());
private static final Logger LOGGER = Logger.getLogger(CurvesHelper.class.getName());
/** This variable indicates if the Y asxis is the UP axis or not. */
protected boolean fixUpAxis;
/** Minimum basis U function degree for NURBS curves and surfaces. */
@ -79,24 +79,24 @@ public class CurvesHelper extends AbstractBlenderHelper {
*/
public List<Geometry> toCurve(Structure curveStructure, DataRepository dataRepository) throws BlenderFileException {
String name = curveStructure.getName();
int flag = ((Number)curveStructure.getFieldValue("flag")).intValue();
int flag = ((Number) curveStructure.getFieldValue("flag")).intValue();
boolean is3D = (flag & 0x01) != 0;
boolean isFront = (flag & 0x02) != 0 && !is3D;
boolean isBack = (flag & 0x04) != 0 && !is3D;
if(isFront) {
if (isFront) {
LOGGER.warning("No front face in curve implemented yet!");//TODO: implement front face
}
if(isBack) {
if (isBack) {
LOGGER.warning("No back face in curve implemented yet!");//TODO: implement back face
}
//reading nurbs (and sorting them by material)
List<Structure> nurbStructures = ((Structure)curveStructure.getFieldValue("nurb")).evaluateListBase(dataRepository);
List<Structure> nurbStructures = ((Structure) curveStructure.getFieldValue("nurb")).evaluateListBase(dataRepository);
Map<Number, List<Structure>> nurbs = new HashMap<Number, List<Structure>>();
for(Structure nurb : nurbStructures) {
for (Structure nurb : nurbStructures) {
Number matNumber = (Number) nurb.getFieldValue("mat_nr");
List<Structure> nurbList = nurbs.get(matNumber);
if(nurbList==null) {
if (nurbList == null) {
nurbList = new ArrayList<Structure>();
nurbs.put(matNumber, nurbList);
}
@ -106,65 +106,65 @@ public class CurvesHelper extends AbstractBlenderHelper {
//getting materials
MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
Material[] materials = materialHelper.getMaterials(curveStructure, dataRepository);
if(materials==null) {
materials = new Material[] { dataRepository.getDefaultMaterial().clone() };
if (materials == null) {
materials = new Material[]{dataRepository.getDefaultMaterial().clone()};
}
for(Material material : materials) {
for (Material material : materials) {
material.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
}
//getting or creating bevel object
List<Geometry> bevelObject = null;
Pointer pBevelObject = (Pointer) curveStructure.getFieldValue("bevobj");
if(!pBevelObject.isNull()) {
if (!pBevelObject.isNull()) {
Pointer pBevelStructure = (Pointer) pBevelObject.fetchData(dataRepository.getInputStream()).get(0).getFieldValue("data");
Structure bevelStructure = pBevelStructure.fetchData(dataRepository.getInputStream()).get(0);
bevelObject = this.toCurve(bevelStructure, dataRepository);
} else {
int bevResol = ((Number)curveStructure.getFieldValue("bevresol")).intValue();
float extrude = ((Number)curveStructure.getFieldValue("ext1")).floatValue();
float bevelDepth = ((Number)curveStructure.getFieldValue("ext2")).floatValue();
if(bevelDepth>0.0f) {
float handlerLength = bevelDepth/2.0f;
int bevResol = ((Number) curveStructure.getFieldValue("bevresol")).intValue();
float extrude = ((Number) curveStructure.getFieldValue("ext1")).floatValue();
float bevelDepth = ((Number) curveStructure.getFieldValue("ext2")).floatValue();
if (bevelDepth > 0.0f) {
float handlerLength = bevelDepth / 2.0f;
List<Vector3f> conrtolPoints = new ArrayList<Vector3f>(extrude>0.0f ? 19 : 13);
conrtolPoints.add(new Vector3f(-bevelDepth,extrude,0));
conrtolPoints.add(new Vector3f(-bevelDepth,handlerLength+extrude,0));
List<Vector3f> conrtolPoints = new ArrayList<Vector3f>(extrude > 0.0f ? 19 : 13);
conrtolPoints.add(new Vector3f(-bevelDepth, extrude, 0));
conrtolPoints.add(new Vector3f(-bevelDepth, handlerLength + extrude, 0));
conrtolPoints.add(new Vector3f(-handlerLength,bevelDepth+extrude,0));
conrtolPoints.add(new Vector3f(0,bevelDepth+extrude,0));
conrtolPoints.add(new Vector3f(handlerLength,bevelDepth+extrude,0));
conrtolPoints.add(new Vector3f(-handlerLength, bevelDepth + extrude, 0));
conrtolPoints.add(new Vector3f(0, bevelDepth + extrude, 0));
conrtolPoints.add(new Vector3f(handlerLength, bevelDepth + extrude, 0));
conrtolPoints.add(new Vector3f(bevelDepth,extrude + handlerLength,0));
conrtolPoints.add(new Vector3f(bevelDepth,extrude,0));
conrtolPoints.add(new Vector3f(bevelDepth,extrude - handlerLength,0));
conrtolPoints.add(new Vector3f(bevelDepth, extrude + handlerLength, 0));
conrtolPoints.add(new Vector3f(bevelDepth, extrude, 0));
conrtolPoints.add(new Vector3f(bevelDepth, extrude - handlerLength, 0));
if(extrude>0.0f) {
conrtolPoints.add(new Vector3f(bevelDepth,-extrude + handlerLength,0));
conrtolPoints.add(new Vector3f(bevelDepth,-extrude,0));
conrtolPoints.add(new Vector3f(bevelDepth,-extrude-handlerLength,0));
if (extrude > 0.0f) {
conrtolPoints.add(new Vector3f(bevelDepth, -extrude + handlerLength, 0));
conrtolPoints.add(new Vector3f(bevelDepth, -extrude, 0));
conrtolPoints.add(new Vector3f(bevelDepth, -extrude - handlerLength, 0));
}
conrtolPoints.add(new Vector3f(handlerLength,-bevelDepth-extrude,0));
conrtolPoints.add(new Vector3f(0,-bevelDepth-extrude,0));
conrtolPoints.add(new Vector3f(-handlerLength,-bevelDepth-extrude,0));
conrtolPoints.add(new Vector3f(handlerLength, -bevelDepth - extrude, 0));
conrtolPoints.add(new Vector3f(0, -bevelDepth - extrude, 0));
conrtolPoints.add(new Vector3f(-handlerLength, -bevelDepth - extrude, 0));
conrtolPoints.add(new Vector3f(-bevelDepth,-handlerLength - extrude,0));
conrtolPoints.add(new Vector3f(-bevelDepth,-extrude,0));
conrtolPoints.add(new Vector3f(-bevelDepth, -handlerLength - extrude, 0));
conrtolPoints.add(new Vector3f(-bevelDepth, -extrude, 0));
if(extrude>0.0f) {
conrtolPoints.add(new Vector3f(-bevelDepth,handlerLength - extrude,0));
if (extrude > 0.0f) {
conrtolPoints.add(new Vector3f(-bevelDepth, handlerLength - extrude, 0));
conrtolPoints.add(new Vector3f(-bevelDepth,-handlerLength + extrude,0));
conrtolPoints.add(new Vector3f(-bevelDepth,extrude,0));
conrtolPoints.add(new Vector3f(-bevelDepth, -handlerLength + extrude, 0));
conrtolPoints.add(new Vector3f(-bevelDepth, extrude, 0));
}
Spline bevelSpline = new Spline(SplineType.Bezier, conrtolPoints, 0, false);
Curve bevelCurve = new Curve(bevelSpline, bevResol);
bevelObject = new ArrayList<Geometry>(1);
bevelObject.add(new Geometry("", bevelCurve));
} else if(extrude>0.0f) {
Spline bevelSpline = new Spline(SplineType.Linear, new Vector3f[] {
} else if (extrude > 0.0f) {
Spline bevelSpline = new Spline(SplineType.Linear, new Vector3f[]{
new Vector3f(0, extrude, 0), new Vector3f(0, -extrude, 0)
}, 1, false);
Curve bevelCurve = new Curve(bevelSpline, bevResol);
@ -176,7 +176,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
//getting taper object
Curve taperObject = null;
Pointer pTaperObject = (Pointer) curveStructure.getFieldValue("taperobj");
if(bevelObject!=null && !pTaperObject.isNull()) {
if (bevelObject != null && !pTaperObject.isNull()) {
Pointer pTaperStructure = (Pointer) pTaperObject.fetchData(dataRepository.getInputStream()).get(0).getFieldValue("data");
Structure taperStructure = pTaperStructure.fetchData(dataRepository.getInputStream()).get(0);
taperObject = this.loadTaperObject(taperStructure, dataRepository);
@ -185,17 +185,17 @@ public class CurvesHelper extends AbstractBlenderHelper {
Vector3f loc = this.getLoc(curveStructure);
//creating the result curves
List<Geometry> result = new ArrayList<Geometry>(nurbs.size());
for(Entry<Number, List<Structure>> nurbEntry : nurbs.entrySet()) {
for(Structure nurb : nurbEntry.getValue()) {
int type = ((Number)nurb.getFieldValue("type")).intValue();
for (Entry<Number, List<Structure>> nurbEntry : nurbs.entrySet()) {
for (Structure nurb : nurbEntry.getValue()) {
int type = ((Number) nurb.getFieldValue("type")).intValue();
List<Geometry> nurbGeoms = null;
if((type & 0x01)!=0) {//Bezier curve
if ((type & 0x01) != 0) {//Bezier curve
nurbGeoms = this.loadBezierCurve(loc, nurb, bevelObject, taperObject, dataRepository);
} else if((type & 0x04)!=0) {//NURBS
} else if ((type & 0x04) != 0) {//NURBS
nurbGeoms = this.loadNurb(loc, nurb, bevelObject, taperObject, dataRepository);
}
if(nurbGeoms!=null) {//setting the name and assigning materials
for(Geometry nurbGeom : nurbGeoms) {
if (nurbGeoms != null) {//setting the name and assigning materials
for (Geometry nurbGeom : nurbGeoms) {
nurbGeom.setMaterial(materials[nurbEntry.getKey().intValue()]);
nurbGeom.setName(name);
result.add(nurbGeom);
@ -226,28 +226,28 @@ public class CurvesHelper extends AbstractBlenderHelper {
DataRepository dataRepository) throws BlenderFileException {
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
List<Geometry> result = new ArrayList<Geometry>();
if(!pBezierTriple.isNull()) {
boolean smooth = (((Number)nurb.getFlatFieldValue("flag")).intValue() & 0x01) !=0;
int resolution = ((Number)nurb.getFieldValue("resolu")).intValue();
boolean cyclic = (((Number)nurb.getFieldValue("flagu")).intValue() & 0x01) != 0;
if (!pBezierTriple.isNull()) {
boolean smooth = (((Number) nurb.getFlatFieldValue("flag")).intValue() & 0x01) != 0;
int resolution = ((Number) nurb.getFieldValue("resolu")).intValue();
boolean cyclic = (((Number) nurb.getFieldValue("flagu")).intValue() & 0x01) != 0;
//creating the curve object
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(dataRepository.getInputStream()), 3);
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
if(cyclic) {
if (cyclic) {
//copy the first three points at the end
for(int i=0;i<3;++i) {
for (int i = 0; i < 3; ++i) {
controlPoints.add(controlPoints.get(i));
}
}
//removing the first and last handles
controlPoints.remove(0);
controlPoints.remove(controlPoints.size()-1);
controlPoints.remove(controlPoints.size() - 1);
//creating curve
Spline spline = new Spline(SplineType.Bezier, controlPoints, 0, false);
Curve curve = new Curve(spline, resolution);
if(bevelObject==null) {//creating a normal curve
if (bevelObject == null) {//creating a normal curve
Geometry curveGeometry = new Geometry(null, curve);
result.add(curveGeometry);
//TODO: use front and back flags; surface excluding algorithm for bezier circles should be added
@ -279,60 +279,60 @@ public class CurvesHelper extends AbstractBlenderHelper {
DataRepository dataRepository) throws BlenderFileException {
//loading the knots
List<Float>[] knots = new List[2];
Pointer[] pKnots = new Pointer[] { (Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv") };
for(int i=0;i<knots.length; ++i) {
if(!pKnots[i].isNull()) {
Pointer[] pKnots = new Pointer[]{(Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv")};
for (int i = 0; i < knots.length; ++i) {
if (!pKnots[i].isNull()) {
FileBlockHeader fileBlockHeader = dataRepository.getFileBlock(pKnots[i].getOldMemoryAddress());
BlenderInputStream blenderInputStream = dataRepository.getInputStream();
blenderInputStream.setPosition(fileBlockHeader.getBlockPosition());
int knotsAmount = fileBlockHeader.getCount() * fileBlockHeader.getSize() / 4;
knots[i] = new ArrayList<Float>(knotsAmount);
for(int j=0;j<knotsAmount;++j) {
for (int j = 0; j < knotsAmount; ++j) {
knots[i].add(Float.valueOf(blenderInputStream.readFloat()));
}
}
}
//loading the flags and orders (basis functions degrees)
int flagU = ((Number)nurb.getFieldValue("flagu")).intValue();
int flagV = ((Number)nurb.getFieldValue("flagv")).intValue();
int orderU = ((Number)nurb.getFieldValue("orderu")).intValue();
int orderV = ((Number)nurb.getFieldValue("orderv")).intValue();
int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
//loading control points and their weights
int pntsU = ((Number)nurb.getFieldValue("pntsu")).intValue();
int pntsV = ((Number)nurb.getFieldValue("pntsv")).intValue();
List<Structure> bPoints = ((Pointer)nurb.getFieldValue("bp")).fetchData(dataRepository.getInputStream());
int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData(dataRepository.getInputStream());
List<List<Vector4f>> controlPoints = new ArrayList<List<Vector4f>>(pntsV);
for(int i=0;i<pntsV;++i) {
for (int i = 0; i < pntsV; ++i) {
List<Vector4f> uControlPoints = new ArrayList<Vector4f>(pntsU);
for(int j=0;j<pntsU;++j) {
DynamicArray<Float> vec = (DynamicArray<Float>)bPoints.get(j + i*pntsU).getFieldValue("vec");
if(fixUpAxis) {
for (int j = 0; j < pntsU; ++j) {
DynamicArray<Float> vec = (DynamicArray<Float>) bPoints.get(j + i * pntsU).getFieldValue("vec");
if (fixUpAxis) {
uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(2).floatValue(), -vec.get(1).floatValue(), vec.get(3).floatValue()));
} else {
uControlPoints.add(new Vector4f(vec.get(0).floatValue(), vec.get(1).floatValue(), vec.get(2).floatValue(), vec.get(3).floatValue()));
}
}
if((flagU & 0x01) != 0) {
for(int k=0;k<orderU - 1;++k) {
if ((flagU & 0x01) != 0) {
for (int k = 0; k < orderU - 1; ++k) {
uControlPoints.add(uControlPoints.get(k));
}
}
controlPoints.add(uControlPoints);
}
if((flagV & 0x01) != 0) {
for(int k=0;k<orderV - 1;++k) {
if ((flagV & 0x01) != 0) {
for (int k = 0; k < orderV - 1; ++k) {
controlPoints.add(controlPoints.get(k));
}
}
int resolu = ((Number)nurb.getFieldValue("resolu")).intValue() + 1;
int resolu = ((Number) nurb.getFieldValue("resolu")).intValue() + 1;
List<Geometry> result;
if(knots[1]==null) {//creating the curve
if (knots[1] == null) {//creating the curve
Spline nurbSpline = new Spline(controlPoints.get(0), knots[0]);
Curve nurbCurve = new Curve(nurbSpline, resolu);
if(bevelObject!=null) {
if (bevelObject != null) {
result = this.applyBevelAndTaper(nurbCurve, bevelObject, taperObject, true, dataRepository);//TODO: smooth
} else {
result = new ArrayList<Geometry>(1);
@ -340,7 +340,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
result.add(nurbGeometry);
}
} else {//creating the nurb surface
int resolv = ((Number)nurb.getFieldValue("resolv")).intValue() + 1;
int resolv = ((Number) nurb.getFieldValue("resolv")).intValue() + 1;
Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, resolu, resolv, orderU, orderV);
Geometry nurbGeometry = new Geometry("", nurbSurface);
result = new ArrayList<Geometry>(1);
@ -365,17 +365,17 @@ public class CurvesHelper extends AbstractBlenderHelper {
float currentLength = 0;
Vector3f p = new Vector3f();
int i;
for(i=0;i<taperPoints.length-6 && currentLength < length; i += 3) {
p.set(taperPoints[i], taperPoints[i+1], taperPoints[i+2]);
p.subtractLocal(taperPoints[i+3], taperPoints[i+4], taperPoints[i+5]);
for (i = 0; i < taperPoints.length - 6 && currentLength < length; i += 3) {
p.set(taperPoints[i], taperPoints[i + 1], taperPoints[i + 2]);
p.subtractLocal(taperPoints[i + 3], taperPoints[i + 4], taperPoints[i + 5]);
currentLength += p.length();
}
currentLength -= p.length();
float leftLength = length - currentLength;
float percentOnSegment = p.length()==0 ? 0 : leftLength / p.length();
float percentOnSegment = p.length() == 0 ? 0 : leftLength / p.length();
Vector3f store = FastMath.interpolateLinear(percentOnSegment,
new Vector3f(taperPoints[i], taperPoints[i+1], taperPoints[i+2]),
new Vector3f(taperPoints[i+3], taperPoints[i+4], taperPoints[i+5]));
new Vector3f(taperPoints[i], taperPoints[i + 1], taperPoints[i + 2]),
new Vector3f(taperPoints[i + 3], taperPoints[i + 4], taperPoints[i + 5]));
return store.y;
}
@ -403,43 +403,43 @@ public class CurvesHelper extends AbstractBlenderHelper {
//taper data
float[] taperPoints = null;
float taperLength = 0;
if(taperObject!=null) {
if (taperObject != null) {
taperPoints = BufferUtils.getFloatArray(taperObject.getFloatBuffer(Type.Position));
taperLength = taperObject.getLength();
}
//several objects can be allocated only once
Vector3f p = new Vector3f();
Vector3f z = new Vector3f(0,0,1);
Vector3f z = new Vector3f(0, 0, 1);
Vector3f negativeY = new Vector3f(0, -1, 0);
Matrix4f m = new Matrix4f();
float lengthAlongCurve = 0, taperScale = 1.0f;
Quaternion planeRotation = new Quaternion();
Quaternion zRotation = new Quaternion();
float[] temp = new float[] {0,0,0,1};
float[] temp = new float[]{0, 0, 0, 1};
Map<Vector3f, Vector3f> normalMap = new HashMap<Vector3f, Vector3f>();//normalMap merges normals of faces that will be rendered smooth
FloatBuffer[] vertexBuffers = new FloatBuffer[bevelObject.size()];
FloatBuffer[] normalBuffers = new FloatBuffer[bevelObject.size()];
IntBuffer[] indexBuffers = new IntBuffer[bevelObject.size()];
for(int geomIndex = 0;geomIndex<bevelObject.size();++geomIndex) {
for (int geomIndex = 0; geomIndex < bevelObject.size(); ++geomIndex) {
Mesh mesh = bevelObject.get(geomIndex).getMesh();
FloatBuffer positions = mesh.getFloatBuffer(Type.Position);
float[] vertices = BufferUtils.getFloatArray(positions);
for(int i=0;i<curvePoints.length;i+=3) {
p.set(curvePoints[i], curvePoints[i+1], curvePoints[i+2]);
for (int i = 0; i < curvePoints.length; i += 3) {
p.set(curvePoints[i], curvePoints[i + 1], curvePoints[i + 2]);
Vector3f v;
if(i==0) {
if (i == 0) {
v = new Vector3f(curvePoints[3] - p.x, curvePoints[4] - p.y, curvePoints[5] - p.z);
} else if(i+3>=curvePoints.length) {
v = new Vector3f(p.x - curvePoints[i-3], p.y - curvePoints[i-2], p.z - curvePoints[i-1]);
} else if (i + 3 >= curvePoints.length) {
v = new Vector3f(p.x - curvePoints[i - 3], p.y - curvePoints[i - 2], p.z - curvePoints[i - 1]);
lengthAlongCurve += v.length();
} else {
v = new Vector3f(curvePoints[i+3] - curvePoints[i-3],
curvePoints[i+4] - curvePoints[i-2],
curvePoints[i+5] - curvePoints[i-1]);
lengthAlongCurve += new Vector3f(curvePoints[i+3] - p.x, curvePoints[i+4] - p.y, curvePoints[i+5] - p.z).length();
v = new Vector3f(curvePoints[i + 3] - curvePoints[i - 3],
curvePoints[i + 4] - curvePoints[i - 2],
curvePoints[i + 5] - curvePoints[i - 1]);
lengthAlongCurve += new Vector3f(curvePoints[i + 3] - p.x, curvePoints[i + 4] - p.y, curvePoints[i + 5] - p.z).length();
}
v.normalizeLocal();
@ -452,7 +452,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
zRotation.fromAngleAxis(zAxisRotationAngle, zAxisRotationVector);
//point transformation matrix
if(taperPoints!=null) {
if (taperPoints != null) {
taperScale = this.getTaperScale(taperPoints, taperLength, lengthAlongCurve / curveLength);
}
m.set(Matrix4f.IDENTITY);
@ -461,19 +461,19 @@ public class CurvesHelper extends AbstractBlenderHelper {
//these vertices need to be thrown on XY plane
//and moved to the origin of [p1.x, p1.y] on the plane
Vector3f[] verts = new Vector3f[vertices.length/3];
for(int j=0;j<verts.length;++j) {
temp[0] = vertices[j*3] * taperScale;
temp[1] = vertices[j*3+1] * taperScale;
Vector3f[] verts = new Vector3f[vertices.length / 3];
for (int j = 0; j < verts.length; ++j) {
temp[0] = vertices[j * 3] * taperScale;
temp[1] = vertices[j * 3 + 1] * taperScale;
temp[2] = 0;
m.mult(temp);//the result is stored in the array
if(fixUpAxis) {
if (fixUpAxis) {
verts[j] = new Vector3f(temp[0], temp[1], temp[2]);
} else {
verts[j] = new Vector3f(temp[0], temp[2], -temp[1]);
}
}
if(vertexBuffers[geomIndex]==null) {
if (vertexBuffers[geomIndex] == null) {
vertexBuffers[geomIndex] = BufferUtils.createFloatBuffer(verts.length * curvePoints.length);
}
FloatBuffer buffer = BufferUtils.createFloatBuffer(verts);
@ -481,20 +481,20 @@ public class CurvesHelper extends AbstractBlenderHelper {
//adding indexes
IntBuffer indexBuffer = indexBuffers[geomIndex];
if(indexBuffer==null) {
if (indexBuffer == null) {
//the amount of faces in the final mesh is the amount of edges in the bevel curve
//(which is less by 1 than its number of vertices)
//multiplied by 2 (because each edge has two faces assigned on both sides)
//and multiplied by the amount of bevel curve repeats which is equal to the amount of vertices on the target curve
//finally we need to subtract the bevel edges amount 2 times because the border edges have only one face attached
//and at last multiply everything by 3 because each face needs 3 indexes to be described
int bevelCurveEdgesAmount = verts.length-1;
int bevelCurveEdgesAmount = verts.length - 1;
indexBuffer = BufferUtils.createIntBuffer(((bevelCurveEdgesAmount << 1) * curvePoints.length - bevelCurveEdgesAmount << 1) * 3);
indexBuffers[geomIndex] = indexBuffer;
}
int pointOffset = i/3 * verts.length;
if(i+3<curvePoints.length) {
for(int index=0;index<verts.length-1;++index) {
int pointOffset = i / 3 * verts.length;
if (i + 3 < curvePoints.length) {
for (int index = 0; index < verts.length - 1; ++index) {
indexBuffer.put(index + pointOffset);
indexBuffer.put(index + pointOffset + 1);
indexBuffer.put(verts.length + index + pointOffset);
@ -507,17 +507,17 @@ public class CurvesHelper extends AbstractBlenderHelper {
}
//calculating the normals
for(int geomIndex = 0;geomIndex<bevelObject.size();++geomIndex) {
for (int geomIndex = 0; geomIndex < bevelObject.size(); ++geomIndex) {
Vector3f[] allVerts = BufferUtils.getVector3Array(vertexBuffers[geomIndex]);
int[] allIndices = BufferUtils.getIntArray(indexBuffers[geomIndex]);
for(int i=0;i<allIndices.length-3;i+=3) {
for (int i = 0; i < allIndices.length - 3; i += 3) {
Vector3f n = FastMath.computeNormal(allVerts[allIndices[i]], allVerts[allIndices[i + 1]], allVerts[allIndices[i + 2]]);
meshHelper.addNormal(n, normalMap, smooth, allVerts[allIndices[i]], allVerts[allIndices[i + 1]], allVerts[allIndices[i + 2]]);
}
if(normalBuffers[geomIndex]==null) {
if (normalBuffers[geomIndex] == null) {
normalBuffers[geomIndex] = BufferUtils.createFloatBuffer(allVerts.length * 3);
}
for(Vector3f v : allVerts) {
for (Vector3f v : allVerts) {
Vector3f n = normalMap.get(v);
normalBuffers[geomIndex].put(n.x);
normalBuffers[geomIndex].put(n.y);
@ -526,7 +526,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
}
List<Geometry> result = new ArrayList<Geometry>(vertexBuffers.length);
for(int i=0;i<vertexBuffers.length;++i) {
for (int i = 0; i < vertexBuffers.length; ++i) {
Mesh mesh = new Mesh();
mesh.setBuffer(Type.Position, 3, vertexBuffers[i]);
mesh.setBuffer(Type.Index, 3, indexBuffers[i]);
@ -550,21 +550,21 @@ public class CurvesHelper extends AbstractBlenderHelper {
*/
protected Curve loadTaperObject(Structure taperStructure, DataRepository dataRepository) throws BlenderFileException {
//reading nurbs
List<Structure> nurbStructures = ((Structure)taperStructure.getFieldValue("nurb")).evaluateListBase(dataRepository);
for(Structure nurb : nurbStructures) {
List<Structure> nurbStructures = ((Structure) taperStructure.getFieldValue("nurb")).evaluateListBase(dataRepository);
for (Structure nurb : nurbStructures) {
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
if(!pBezierTriple.isNull()) {
if (!pBezierTriple.isNull()) {
//creating the curve object
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(dataRepository.getInputStream()), 3);
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
//removing the first and last handles
controlPoints.remove(0);
controlPoints.remove(controlPoints.size()-1);
controlPoints.remove(controlPoints.size() - 1);
//return the first taper curve that has more than 3 control points
if(controlPoints.size()>3) {
if (controlPoints.size() > 3) {
Spline spline = new Spline(SplineType.Bezier, controlPoints, 0, false);
int resolution = ((Number)taperStructure.getFieldValue("resolu")).intValue();
int resolution = ((Number) taperStructure.getFieldValue("resolu")).intValue();
return new Curve(spline, resolution);
}
}
@ -580,8 +580,8 @@ public class CurvesHelper extends AbstractBlenderHelper {
*/
@SuppressWarnings("unchecked")
protected Vector3f getLoc(Structure curveStructure) {
DynamicArray<Number> locArray = (DynamicArray<Number>)curveStructure.getFieldValue("loc");
if(fixUpAxis) {
DynamicArray<Number> locArray = (DynamicArray<Number>) curveStructure.getFieldValue("loc");
if (fixUpAxis) {
return new Vector3f(locArray.get(0).floatValue(), locArray.get(1).floatValue(), -locArray.get(2).floatValue());
} else {
return new Vector3f(locArray.get(0).floatValue(), locArray.get(2).floatValue(), locArray.get(1).floatValue());

@ -17,6 +17,7 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* @author Marcin Roguski
*/
public class IpoHelper extends AbstractBlenderHelper {
/**
* This constructor parses the given blender version and stores the result. Some functionalities may differ in
* different blender versions.
@ -38,18 +39,18 @@ public class IpoHelper extends AbstractBlenderHelper {
* this exception is thrown when the blender file is somehow corrupted
*/
public Ipo createIpo(Structure ipoStructure, DataRepository dataRepository) throws BlenderFileException {
Structure curvebase = (Structure)ipoStructure.getFieldValue("curve");
Structure curvebase = (Structure) ipoStructure.getFieldValue("curve");
//preparing bezier curves
Ipo result = null;
List<Structure> curves = curvebase.evaluateListBase(dataRepository);//IpoCurve
if(curves.size() > 0) {
if (curves.size() > 0) {
BezierCurve[] bezierCurves = new BezierCurve[curves.size()];
int frame = 0;
for(Structure curve : curves) {
Pointer pBezTriple = (Pointer)curve.getFieldValue("bezt");
for (Structure curve : curves) {
Pointer pBezTriple = (Pointer) curve.getFieldValue("bezt");
List<Structure> bezTriples = pBezTriple.fetchData(dataRepository.getInputStream());
int type = ((Number)curve.getFieldValue("adrcode")).intValue();
int type = ((Number) curve.getFieldValue("adrcode")).intValue();
bezierCurves[frame++] = new BezierCurve(type, bezTriples, 2);
}
curves.clear();
@ -70,14 +71,13 @@ public class IpoHelper extends AbstractBlenderHelper {
return new ConstIpo(constValue);
}
/**
* 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.
* @author Marcin Roguski
*/
private class ConstIpo extends Ipo {
/** The constant value of this ipo. */
private float constValue;

@ -49,6 +49,7 @@ import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType
* @author Marcin Roguski
*/
public class LightHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(LightHelper.class.getName());
/**
@ -62,16 +63,16 @@ public class LightHelper extends AbstractBlenderHelper {
}
public Light toLight(Structure structure, DataRepository dataRepository) throws BlenderFileException {
Light result = (Light)dataRepository.getLoadedFeature(structure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
if(result != null) {
Light result = (Light) dataRepository.getLoadedFeature(structure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
if (result != null) {
return result;
}
int type = ((Number)structure.getFieldValue("type")).intValue();
switch(type) {
int type = ((Number) structure.getFieldValue("type")).intValue();
switch (type) {
case 0://Lamp
result = new PointLight();
float distance = ((Number)structure.getFieldValue("dist")).floatValue();
((PointLight)result).setRadius(distance);
float distance = ((Number) structure.getFieldValue("dist")).floatValue();
((PointLight) result).setRadius(distance);
break;
case 1://Sun
LOGGER.log(Level.WARNING, "'Sun' lamp is not supported in jMonkeyEngine.");
@ -88,10 +89,10 @@ public class LightHelper extends AbstractBlenderHelper {
default:
throw new BlenderFileException("Unknown light source type: " + type);
}
if(result != null) {
float r = ((Number)structure.getFieldValue("r")).floatValue();
float g = ((Number)structure.getFieldValue("g")).floatValue();
float b = ((Number)structure.getFieldValue("b")).floatValue();
if (result != null) {
float r = ((Number) structure.getFieldValue("r")).floatValue();
float g = ((Number) structure.getFieldValue("g")).floatValue();
float b = ((Number) structure.getFieldValue("b")).floatValue();
result.setColor(new ColorRGBA(r, g, b, 0.0f));//TODO: 0 czy 1 ???
}
return result;

@ -62,26 +62,26 @@ import com.jme3.texture.Texture.WrapMode;
import com.jme3.util.BufferUtils;
public class MaterialHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(MaterialHelper.class.getName());
protected static final float DEFAULT_SHININESS = 20.0f;
public static final String TEXTURE_TYPE_COLOR = "ColorMap";
public static final String TEXTURE_TYPE_DIFFUSE = "DiffuseMap";
public static final String TEXTURE_TYPE_NORMAL = "NormalMap";
public static final String TEXTURE_TYPE_SPECULAR = "SpecularMap";
public static final String TEXTURE_TYPE_GLOW = "GlowMap";
public static final String TEXTURE_TYPE_ALPHA = "AlphaMap";
public static final Integer ALPHA_MASK_NONE = Integer.valueOf(0);
public static final Integer ALPHA_MASK_CIRCLE = Integer.valueOf(1);
public static final Integer ALPHA_MASK_CONE = Integer.valueOf(2);
public static final Integer ALPHA_MASK_HYPERBOLE = Integer.valueOf(3);
protected final Map<Integer, IAlphaMask> alphaMasks = new HashMap<Integer, IAlphaMask>();
protected final Map<Integer, AlphaMask> alphaMasks = new HashMap<Integer, AlphaMask>();
/**
* The type of the material's diffuse shader.
*/
public static enum DiffuseShader {
LAMBERT, ORENNAYAR, TOON, MINNAERT, FRESNEL
}
@ -89,9 +89,9 @@ public class MaterialHelper extends AbstractBlenderHelper {
* The type of the material's specular shader.
*/
public static enum SpecularShader {
COOKTORRENCE, PHONG, BLINN, TOON, WARDISO
}
/** Face cull mode. Should be excplicitly set before this helper is used. */
protected FaceCullMode faceCullMode;
@ -105,23 +105,26 @@ public class MaterialHelper extends AbstractBlenderHelper {
public MaterialHelper(String blenderVersion) {
super(blenderVersion);
// setting alpha masks
alphaMasks.put(ALPHA_MASK_NONE, new IAlphaMask() {
alphaMasks.put(ALPHA_MASK_NONE, new AlphaMask() {
@Override
public void setImageSize(int width, int height) {}
public void setImageSize(int width, int height) {
}
@Override
public byte getAlpha(float x, float y) {
return (byte) 255;
}
});
alphaMasks.put(ALPHA_MASK_CIRCLE, new IAlphaMask() {
alphaMasks.put(ALPHA_MASK_CIRCLE, new AlphaMask() {
private float r;
private float[] center;
@Override
public void setImageSize(int width, int height) {
r = Math.min(width, height) * 0.5f;
center = new float[] { width * 0.5f, height * 0.5f };
center = new float[]{width * 0.5f, height * 0.5f};
}
@Override
@ -130,14 +133,15 @@ public class MaterialHelper extends AbstractBlenderHelper {
return (byte) (d >= r ? 0 : 255);
}
});
alphaMasks.put(ALPHA_MASK_CONE, new IAlphaMask() {
alphaMasks.put(ALPHA_MASK_CONE, new AlphaMask() {
private float r;
private float[] center;
@Override
public void setImageSize(int width, int height) {
r = Math.min(width, height) * 0.5f;
center = new float[] { width * 0.5f, height * 0.5f };
center = new float[]{width * 0.5f, height * 0.5f};
}
@Override
@ -146,14 +150,15 @@ public class MaterialHelper extends AbstractBlenderHelper {
return (byte) (d >= r ? 0 : -255.0f * d / r + 255.0f);
}
});
alphaMasks.put(ALPHA_MASK_HYPERBOLE, new IAlphaMask() {
alphaMasks.put(ALPHA_MASK_HYPERBOLE, new AlphaMask() {
private float r;
private float[] center;
@Override
public void setImageSize(int width, int height) {
r = Math.min(width, height) * 0.5f;
center = new float[] { width * 0.5f, height * 0.5f };
center = new float[]{width * 0.5f, height * 0.5f};
}
@Override
@ -258,7 +263,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
result.setBoolean("UseMaterialColors", Boolean.FALSE);
// blending the texture with material color and texture's defined color
int blendType = ((Number) textureLink.getFieldValue("blendtype")).intValue();
float[] color = new float[] { ((Number) textureLink.getFieldValue("r")).floatValue(), ((Number) textureLink.getFieldValue("g")).floatValue(), ((Number) textureLink.getFieldValue("b")).floatValue() };
float[] color = new float[]{((Number) textureLink.getFieldValue("r")).floatValue(), ((Number) textureLink.getFieldValue("g")).floatValue(), ((Number) textureLink.getFieldValue("b")).floatValue()};
float colfac = ((Number) textureLink.getFieldValue("colfac")).floatValue();
texture = textureHelper.blendTexture(diffuseColor.getColorArray(), texture, color, colfac, blendType, negateTexture, dataRepository);
texture.setWrap(WrapMode.Repeat);
@ -311,7 +316,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
* @return material without textures of a specified type
*/
public Material getNonTexturedMaterial(Material material, int imageType) {
String[] textureParamNames = new String[] { TEXTURE_TYPE_DIFFUSE, TEXTURE_TYPE_NORMAL, TEXTURE_TYPE_GLOW, TEXTURE_TYPE_SPECULAR, TEXTURE_TYPE_ALPHA };
String[] textureParamNames = new String[]{TEXTURE_TYPE_DIFFUSE, TEXTURE_TYPE_NORMAL, TEXTURE_TYPE_GLOW, TEXTURE_TYPE_SPECULAR, TEXTURE_TYPE_ALPHA};
Map<String, Texture> textures = new HashMap<String, Texture>(textureParamNames.length);
for (String textureParamName : textureParamNames) {
MatParamTexture matParamTexture = material.getTextureParam(textureParamName);
@ -368,7 +373,7 @@ public class MaterialHelper extends AbstractBlenderHelper {
int w = image.getWidth();
int h = image.getHeight();
ByteBuffer bb = BufferUtils.createByteBuffer(w * h * 4);
IAlphaMask iAlphaMask = alphaMasks.get(alphaMaskIndex);
AlphaMask iAlphaMask = alphaMasks.get(alphaMaskIndex);
iAlphaMask.setImageSize(w, h);
for (int x = 0; x < w; ++x) {
@ -678,7 +683,8 @@ public class MaterialHelper extends AbstractBlenderHelper {
* An interface used in calculating alpha mask during particles' texture calculations.
* @author Marcin Roguski (Kaelthas)
*/
protected static interface IAlphaMask {
protected static interface AlphaMask {
/**
* This method sets the size of the texture's image.
* @param width

@ -67,6 +67,7 @@ import com.jme3.util.BufferUtils;
* @author Marcin Roguski (Kaelthas)
*/
public class MeshHelper extends AbstractBlenderHelper {
protected static final int MAXIMUM_WEIGHTS_PER_VERTEX = 4; // have no idea why 4, could someone please explain ?
/**
@ -254,7 +255,7 @@ public class MeshHelper extends AbstractBlenderHelper {
Map<Integer, Integer> groupToBoneIndexMap = armatureHelper.getGroupToBoneIndexMap(defBase, dataRepository);
VertexBuffer verticesWeights = null, verticesWeightsIndices = null;
int[] bonesGroups = new int[] { 0 };
int[] bonesGroups = new int[]{0};
VertexBuffer[] boneWeightsAndIndex = this.getBoneWeightAndIndexBuffer(structure, vertexList.size(), bonesGroups,
vertexReferenceMap, groupToBoneIndexMap, dataRepository);
verticesWeights = boneWeightsAndIndex[0];
@ -439,7 +440,7 @@ public class MeshHelper extends AbstractBlenderHelper {
float g = ((Number) color.getFieldValue("g")).byteValue() / 256.0f;
float b = ((Number) color.getFieldValue("b")).byteValue() / 256.0f;
float a = ((Number) color.getFieldValue("a")).byteValue() / 256.0f;
verticesColors.add(new float[] { b, g, r, a });
verticesColors.add(new float[]{b, g, r, a});
}
}
return verticesColors;
@ -558,7 +559,7 @@ public class MeshHelper extends AbstractBlenderHelper {
VertexBuffer verticesWeightsIndices = new VertexBuffer(Type.BoneIndex);
verticesWeightsIndices.setupData(Usage.CpuOnly, bonesGroups[0], Format.UnsignedByte, indicesData);
return new VertexBuffer[] { verticesWeights, verticesWeightsIndices };
return new VertexBuffer[]{verticesWeights, verticesWeightsIndices};
}
/**

@ -77,6 +77,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
* @author Marcin Roguski
*/
public class ModifierHelper extends AbstractBlenderHelper {
private static final Logger LOGGER = Logger.getLogger(ModifierHelper.class.getName());
/**
@ -100,11 +101,11 @@ public class ModifierHelper extends AbstractBlenderHelper {
* @return the node to whom the modifier was applied
*/
public Node applyModifier(Node node, Modifier modifier, DataRepository dataRepository) {
if(Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {
if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {
return this.applyArmatureModifierData(node, modifier, dataRepository);
} else if(Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {
} else if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {
return this.applyArrayModifierData(node, modifier, dataRepository);
} else if(Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {
return this.applyParticleSystemModifierData(node, modifier, dataRepository);
} else {
LOGGER.warning("Modifier: " + modifier.getType() + " not yet implemented!!!");
@ -125,17 +126,17 @@ public class ModifierHelper extends AbstractBlenderHelper {
*/
@SuppressWarnings("unchecked")
public void readModifiers(Structure objectStructure, DataRepository dataRepository) throws BlenderFileException {
Structure modifiersListBase = (Structure)objectStructure.getFieldValue("modifiers");
Structure modifiersListBase = (Structure) objectStructure.getFieldValue("modifiers");
List<Structure> modifiers = modifiersListBase.evaluateListBase(dataRepository);
for(Structure modifier : modifiers) {
for (Structure modifier : modifiers) {
Object loadedModifier = null;
Object modifierAdditionalData = null;
if(Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {//****************ARRAY MODIFIER
if (Modifier.ARRAY_MODIFIER_DATA.equals(modifier.getType())) {//****************ARRAY MODIFIER
Map<String, Object> params = new HashMap<String, Object>();
Number fittype = (Number) modifier.getFieldValue("fit_type");
params.put("fittype", fittype);
switch(fittype.intValue()) {
switch (fittype.intValue()) {
case 0://FIXED COUNT
params.put("count", modifier.getFieldValue("count"));
break;
@ -151,39 +152,39 @@ public class ModifierHelper extends AbstractBlenderHelper {
//offset parameters
int offsettype = ((Number) modifier.getFieldValue("offset_type")).intValue();
if((offsettype & 0x01) != 0) {//Constant offset
DynamicArray<Number> offsetArray = (DynamicArray<Number>)modifier.getFieldValue("offset");
float[] offset = new float[] {offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue()};
if ((offsettype & 0x01) != 0) {//Constant offset
DynamicArray<Number> offsetArray = (DynamicArray<Number>) modifier.getFieldValue("offset");
float[] offset = new float[]{offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue()};
params.put("offset", offset);
}
if((offsettype & 0x02) != 0) {//Relative offset
DynamicArray<Number> scaleArray = (DynamicArray<Number>)modifier.getFieldValue("scale");
float[] scale = new float[] {scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue()};
if ((offsettype & 0x02) != 0) {//Relative offset
DynamicArray<Number> scaleArray = (DynamicArray<Number>) modifier.getFieldValue("scale");
float[] scale = new float[]{scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue()};
params.put("scale", scale);
}
if((offsettype & 0x04) != 0) {//Object offset
Pointer pOffsetObject = (Pointer)modifier.getFieldValue("offset_ob");
if(!pOffsetObject.isNull()) {
if ((offsettype & 0x04) != 0) {//Object offset
Pointer pOffsetObject = (Pointer) modifier.getFieldValue("offset_ob");
if (!pOffsetObject.isNull()) {
params.put("offsetob", pOffsetObject);
}
}
//start cap and end cap
Pointer pStartCap = (Pointer)modifier.getFieldValue("start_cap");
if(!pStartCap.isNull()) {
Pointer pStartCap = (Pointer) modifier.getFieldValue("start_cap");
if (!pStartCap.isNull()) {
params.put("startcap", pStartCap);
}
Pointer pEndCap = (Pointer)modifier.getFieldValue("end_cap");
if(!pEndCap.isNull()) {
Pointer pEndCap = (Pointer) modifier.getFieldValue("end_cap");
if (!pEndCap.isNull()) {
params.put("endcap", pEndCap);
}
loadedModifier = params;
} else if(Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {//****************ARMATURE MODIFIER
Pointer pArmatureObject = (Pointer)modifier.getFieldValue("object");
if(!pArmatureObject.isNull()) {
} else if (Modifier.ARMATURE_MODIFIER_DATA.equals(modifier.getType())) {//****************ARMATURE MODIFIER
Pointer pArmatureObject = (Pointer) modifier.getFieldValue("object");
if (!pArmatureObject.isNull()) {
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
Structure armatureObject = (Structure)dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE);
if(armatureObject == null) {//we check this first not to fetch the structure unnecessary
Structure armatureObject = (Structure) dataRepository.getLoadedFeature(pArmatureObject.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_STRUCTURE);
if (armatureObject == null) {//we check this first not to fetch the structure unnecessary
armatureObject = pArmatureObject.fetchData(dataRepository.getInputStream()).get(0);
objectHelper.toObject(armatureObject, dataRepository);
}
@ -198,17 +199,17 @@ public class ModifierHelper extends AbstractBlenderHelper {
String objectName = objectStructure.getName();
Set<String> animationNames = dataRepository.getBlenderKey().getAnimationNames(objectName);
if(animationNames != null && animationNames.size() > 0) {
if (animationNames != null && animationNames.size() > 0) {
ArrayList<BoneAnimation> animations = new ArrayList<BoneAnimation>();
List<FileBlockHeader> actionHeaders = dataRepository.getFileBlocks(Integer.valueOf(FileBlockHeader.BLOCK_AC00));
for(FileBlockHeader header : actionHeaders) {
for (FileBlockHeader header : actionHeaders) {
Structure actionStructure = header.getStructure(dataRepository);
String actionName = actionStructure.getName();
if(animationNames.contains(actionName)) {
if (animationNames.contains(actionName)) {
int[] animationFrames = dataRepository.getBlenderKey().getAnimationFrames(objectName, actionName);
int fps = dataRepository.getBlenderKey().getFps();
float start = (float)animationFrames[0] / (float)fps;
float stop = (float)animationFrames[1] / (float)fps;
float start = (float) animationFrames[0] / (float) fps;
float stop = (float) animationFrames[1] / (float) fps;
BoneAnimation boneAnimation = new BoneAnimation(actionName, stop - start);
boneAnimation.setTracks(armatureHelper.getTracks(actionStructure, dataRepository, objectName, actionName));
animations.add(boneAnimation);
@ -219,16 +220,16 @@ public class ModifierHelper extends AbstractBlenderHelper {
} else {
LOGGER.warning("Unsupported modifier type: " + modifier.getType());
}
} else if(Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {//****************PARTICLES MODIFIER
} else if (Modifier.PARTICLE_MODIFIER_DATA.equals(modifier.getType())) {//****************PARTICLES MODIFIER
Pointer pParticleSystem = (Pointer) modifier.getFieldValue("psys");
if(!pParticleSystem.isNull()) {
if (!pParticleSystem.isNull()) {
ParticlesHelper particlesHelper = dataRepository.getHelper(ParticlesHelper.class);
Structure particleSystem = pParticleSystem.fetchData(dataRepository.getInputStream()).get(0);
loadedModifier = particlesHelper.toParticleEmitter(particleSystem, dataRepository);
}
}
//adding modifier to the modifier's lists
if(loadedModifier != null) {
if (loadedModifier != null) {
dataRepository.addModifier(objectStructure.getOldMemoryAddress(), modifier.getType(), loadedModifier, modifierAdditionalData);
modifierAdditionalData = null;
}
@ -249,27 +250,27 @@ public class ModifierHelper extends AbstractBlenderHelper {
//veryfying the alpha function for particles' texture
Integer alphaFunction = MaterialHelper.ALPHA_MASK_HYPERBOLE;
char nameSuffix = emitter.getName().charAt(emitter.getName().length()-1);
if(nameSuffix=='B' || nameSuffix=='N') {
char nameSuffix = emitter.getName().charAt(emitter.getName().length() - 1);
if (nameSuffix == 'B' || nameSuffix == 'N') {
alphaFunction = MaterialHelper.ALPHA_MASK_NONE;
}
//removing the type suffix from the name
emitter.setName(emitter.getName().substring(0, emitter.getName().length()-1));
emitter.setName(emitter.getName().substring(0, emitter.getName().length() - 1));
//applying emitter shape
EmitterShape emitterShape = emitter.getShape();
List<Mesh> meshes = new ArrayList<Mesh>();
for(Spatial spatial : node.getChildren()) {
if(spatial instanceof Geometry) {
for (Spatial spatial : node.getChildren()) {
if (spatial instanceof Geometry) {
Mesh mesh = ((Geometry) spatial).getMesh();
if(mesh != null) {
if (mesh != null) {
meshes.add(mesh);
Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, dataRepository);
emitter.setMaterial(material);//TODO: divide into several pieces
}
}
}
if(meshes.size()>0 && emitterShape instanceof EmitterMeshVertexShape) {
if (meshes.size() > 0 && emitterShape instanceof EmitterMeshVertexShape) {
((EmitterMeshVertexShape) emitterShape).setMeshes(meshes);
}
@ -288,19 +289,19 @@ public class ModifierHelper extends AbstractBlenderHelper {
* @return the node to whom the modifier was applied
*/
protected Node applyArmatureModifierData(Node node, Modifier modifier, DataRepository dataRepository) {
AnimData ad = (AnimData)modifier.getJmeModifierRepresentation();
AnimData ad = (AnimData) modifier.getJmeModifierRepresentation();
ArrayList<BoneAnimation> animList = ad.anims;
Long modifierArmatureObject = (Long)modifier.getAdditionalData();
if(animList != null && animList.size() > 0) {
Long modifierArmatureObject = (Long) modifier.getAdditionalData();
if (animList != null && animList.size() > 0) {
ConstraintHelper constraintHelper = dataRepository.getHelper(ConstraintHelper.class);
Constraint[] constraints = constraintHelper.getConstraints(modifierArmatureObject);
HashMap<String, BoneAnimation> anims = new HashMap<String, BoneAnimation>();
for(int i = 0; i < animList.size(); ++i) {
for (int i = 0; i < animList.size(); ++i) {
BoneAnimation boneAnimation = this.cloneBoneAnimation(animList.get(i));
//baking constraints into animations
if(constraints != null && constraints.length > 0) {
for(Constraint constraint : constraints) {
if (constraints != null && constraints.length > 0) {
for (Constraint constraint : constraints) {
constraint.affectAnimation(ad.skeleton, boneAnimation);
}
}
@ -312,12 +313,12 @@ public class ModifierHelper extends AbstractBlenderHelper {
Mesh[] meshes = null;
List<Mesh> meshesList = new ArrayList<Mesh>();
List<Spatial> children = node.getChildren();
for(Spatial child : children) {
if(child instanceof Geometry) {
meshesList.add(((Geometry)child).getMesh());
for (Spatial child : children) {
if (child instanceof Geometry) {
meshesList.add(((Geometry) child).getMesh());
}
}
if(meshesList.size() > 0) {
if (meshesList.size() > 0) {
meshes = meshesList.toArray(new Mesh[meshesList.size()]);
}
@ -325,7 +326,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
SkeletonControl skeletonControl = new SkeletonControl(meshes, ad.skeleton);
AnimControl control = node.getControl(AnimControl.class);
if(control == null) {
if (control == null) {
control = new AnimControl(ad.skeleton);
} else {
//merging skeletons
@ -335,12 +336,12 @@ public class ModifierHelper extends AbstractBlenderHelper {
//merging animations
HashMap<String, BoneAnimation> animations = new HashMap<String, BoneAnimation>();
for(String animationName : control.getAnimationNames()) {
for (String animationName : control.getAnimationNames()) {
animations.put(animationName, control.getAnim(animationName));
}
for(Entry<String, BoneAnimation> animEntry : anims.entrySet()) {
for (Entry<String, BoneAnimation> animEntry : anims.entrySet()) {
BoneAnimation ba = animEntry.getValue();
for(int i = 0; i < ba.getTracks().length; ++i) {
for (int i = 0; i < ba.getTracks().length; ++i) {
BoneTrack bt = ba.getTracks()[i];
int newBoneIndex = bt.getTargetBoneIndex() + boneIndexIncrease;
ba.getTracks()[i] = new BoneTrack(newBoneIndex, bt.getTimes(), bt.getTranslations(), bt.getRotations(), bt.getScales());
@ -372,23 +373,23 @@ public class ModifierHelper extends AbstractBlenderHelper {
@SuppressWarnings("unchecked")
protected Node applyArrayModifierData(Node node, Modifier modifier, DataRepository dataRepository) {
Map<String, Object> modifierData = (Map<String, Object>) modifier.getJmeModifierRepresentation();
int fittype = ((Number)modifierData.get("fittype")).intValue();
float[] offset = (float[])modifierData.get("offset");
if(offset==null) {//the node will be repeated several times in the same place
offset = new float[] {0.0f, 0.0f, 0.0f};
}
float[] scale = (float[])modifierData.get("scale");
if(scale==null) {//the node will be repeated several times in the same place
scale = new float[] {0.0f, 0.0f, 0.0f};
int fittype = ((Number) modifierData.get("fittype")).intValue();
float[] offset = (float[]) modifierData.get("offset");
if (offset == null) {//the node will be repeated several times in the same place
offset = new float[]{0.0f, 0.0f, 0.0f};
}
float[] scale = (float[]) modifierData.get("scale");
if (scale == null) {//the node will be repeated several times in the same place
scale = new float[]{0.0f, 0.0f, 0.0f};
} else {
//getting bounding box
node.updateModelBound();
BoundingVolume boundingVolume = node.getWorldBound();
if(boundingVolume instanceof BoundingBox) {
if (boundingVolume instanceof BoundingBox) {
scale[0] *= ((BoundingBox) boundingVolume).getXExtent() * 2.0f;
scale[1] *= ((BoundingBox) boundingVolume).getYExtent() * 2.0f;
scale[2] *= ((BoundingBox) boundingVolume).getZExtent() * 2.0f;
} else if(boundingVolume instanceof BoundingSphere) {
} else if (boundingVolume instanceof BoundingSphere) {
float radius = ((BoundingSphere) boundingVolume).getRadius();
scale[0] *= radius * 2.0f;
scale[1] *= radius * 2.0f;
@ -399,9 +400,9 @@ public class ModifierHelper extends AbstractBlenderHelper {
}
//adding object's offset
float[] objectOffset = new float[] {0.0f, 0.0f, 0.0f};
float[] objectOffset = new float[]{0.0f, 0.0f, 0.0f};
Pointer pOffsetObject = (Pointer) modifierData.get("offsetob");
if(pOffsetObject!=null) {
if (pOffsetObject != null) {
FileBlockHeader offsetObjectBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress());
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
try {//we take the structure in case the object was not yet loaded
@ -416,12 +417,12 @@ public class ModifierHelper extends AbstractBlenderHelper {
}
//getting start and end caps
Node[] caps = new Node[] {null, null};
Pointer[] pCaps = new Pointer[] {(Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap")};
for(int i=0;i<pCaps.length;++i) {
if(pCaps[i]!=null) {
Node[] caps = new Node[]{null, null};
Pointer[] pCaps = new Pointer[]{(Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap")};
for (int i = 0; i < pCaps.length; ++i) {
if (pCaps[i] != null) {
caps[i] = (Node) dataRepository.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
if(caps[i]!=null) {
if (caps[i] != null) {
caps[i] = (Node) caps[i].clone();
} else {
FileBlockHeader capBlock = dataRepository.getFileBlock(pOffsetObject.getOldMemoryAddress());
@ -429,7 +430,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
Structure capStructure = capBlock.getStructure(dataRepository);
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
caps[i] = (Node) objectHelper.toObject(capStructure, dataRepository);
if(caps[i]==null) {
if (caps[i] == null) {
LOGGER.warning("Cap object '" + capStructure.getName() + "' couldn't be loaded!");
}
} catch (BlenderFileException e) {
@ -445,37 +446,37 @@ public class ModifierHelper extends AbstractBlenderHelper {
//getting/calculating repeats amount
int count = 0;
if(fittype==0) {//Fixed count
count = ((Number)modifierData.get("count")).intValue() - 1;
} else if(fittype==1) {//Fixed length
float length = ((Number)modifierData.get("length")).floatValue();
if(translationVector.length()>0.0f) {
count = (int)(length / translationVector.length()) - 1;
}
} else if(fittype==2) {//Fit curve
if (fittype == 0) {//Fixed count
count = ((Number) modifierData.get("count")).intValue() - 1;
} else if (fittype == 1) {//Fixed length
float length = ((Number) modifierData.get("length")).floatValue();
if (translationVector.length() > 0.0f) {
count = (int) (length / translationVector.length()) - 1;
}
} else if (fittype == 2) {//Fit curve
LOGGER.warning("Fit curve mode in array modifier not yet implemented!");//TODO: implement fit curve
} else {
throw new IllegalStateException("Unknown fit type: " + fittype);
}
//adding translated nodes and caps
if(count>0) {
if (count > 0) {
Node[] arrayNodes = new Node[count];
Vector3f newTranslation = node.getLocalTranslation().clone();
for(int i=0;i<count;++i) {
for (int i = 0; i < count; ++i) {
newTranslation.addLocal(translationVector);
Node nodeClone = (Node) node.clone();
nodeClone.setLocalTranslation(newTranslation);
arrayNodes[i] = nodeClone;
}
for(Node nodeClone : arrayNodes) {
for (Node nodeClone : arrayNodes) {
node.attachChild(nodeClone);
}
if(caps[0]!=null) {
if (caps[0] != null) {
caps[0].getLocalTranslation().set(node.getLocalTranslation()).subtractLocal(translationVector);
node.attachChild(caps[0]);
}
if(caps[1]!=null) {
if (caps[1] != null) {
caps[1].getLocalTranslation().set(newTranslation).addLocal(translationVector);
node.attachChild(caps[1]);
}
@ -495,7 +496,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
//copying tracks and applying constraints
BoneTrack[] sourceTracks = source.getTracks();
BoneTrack[] boneTracks = new BoneTrack[sourceTracks.length];
for(int i = 0; i < sourceTracks.length; ++i) {
for (int i = 0; i < sourceTracks.length; ++i) {
int tablesLength = sourceTracks[i].getTimes().length;
Vector3f[] sourceTranslations = sourceTracks[i].getTranslations();
@ -505,10 +506,10 @@ public class ModifierHelper extends AbstractBlenderHelper {
Vector3f[] translations = new Vector3f[tablesLength];
Quaternion[] rotations = new Quaternion[tablesLength];
Vector3f[] scales = sourceScales == null ? null : new Vector3f[tablesLength];
for(int j = 0; j < tablesLength; ++j) {
for (int j = 0; j < tablesLength; ++j) {
translations[j] = sourceTranslations[j].clone();
rotations[j] = sourceRotations[j].clone();
if(sourceScales != null) {//only scales may not be applied
if (sourceScales != null) {//only scales may not be applied
scales[j] = sourceScales[j].clone();
}
}
@ -530,10 +531,10 @@ public class ModifierHelper extends AbstractBlenderHelper {
*/
protected Skeleton merge(Skeleton s1, Skeleton s2) {
List<Bone> bones = new ArrayList<Bone>(s1.getBoneCount() + s2.getBoneCount());
for(int i = 0; i < s1.getBoneCount(); ++i) {
for (int i = 0; i < s1.getBoneCount(); ++i) {
bones.add(s1.getBone(i));
}
for(int i = 1; i < s2.getBoneCount(); ++i) {//ommit objectAnimationBone
for (int i = 1; i < s2.getBoneCount(); ++i) {//ommit objectAnimationBone
bones.add(s2.getBone(i));
}
return new Skeleton(bones.toArray(new Bone[bones.size()]));

@ -21,20 +21,17 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* @author Marcin Roguski
*/
public abstract class AbstractInfluenceFunction {
protected static final Logger LOGGER = Logger.getLogger(AbstractInfluenceFunction.class.getName());
protected static final Logger LOGGER = Logger.getLogger(AbstractInfluenceFunction.class.getName());
protected static final float IK_SOLVER_ERROR = 0.5f;
//DISTLIMIT
protected static final int LIMITDIST_INSIDE = 0;
protected static final int LIMITDIST_OUTSIDE = 1;
protected static final int LIMITDIST_ONSURFACE = 2;
//CONSTRAINT_TYPE_LOCLIKE
protected static final int LOCLIKE_X = 0x01;
protected static final int LOCLIKE_Y = 0x02;
protected static final int LOCLIKE_Z = 0x04;
//ROTLIKE
protected static final int ROTLIKE_X = 0x01;
protected static final int ROTLIKE_Y = 0x02;
@ -43,7 +40,6 @@ public abstract class AbstractInfluenceFunction {
protected static final int ROTLIKE_Y_INVERT = 0x20;
protected static final int ROTLIKE_Z_INVERT = 0x40;
protected static final int ROTLIKE_OFFSET = 0x80;
//SIZELIKE
protected static final int SIZELIKE_X = 0x01;
protected static final int SIZELIKE_Y = 0x02;
@ -56,7 +52,6 @@ public abstract class AbstractInfluenceFunction {
protected static final int LOCLIKE_Y_INVERT = 0x20;
protected static final int LOCLIKE_Z_INVERT = 0x40;
protected static final int LOCLIKE_OFFSET = 0x80;
//LOCLIMIT, SIZELIMIT
protected static final int LIMIT_XMIN = 0x01;
protected static final int LIMIT_XMAX = 0x02;
@ -64,12 +59,10 @@ public abstract class AbstractInfluenceFunction {
protected static final int LIMIT_YMAX = 0x08;
protected static final int LIMIT_ZMIN = 0x10;
protected static final int LIMIT_ZMAX = 0x20;
//ROTLIMIT
protected static final int LIMIT_XROT = 0x01;
protected static final int LIMIT_YROT = 0x02;
protected static final int LIMIT_ZROT = 0x04;
/** The type of the constraint. */
protected ConstraintType constraintType;
/** The data repository. */
@ -94,7 +87,7 @@ public abstract class AbstractInfluenceFunction {
* the structure with constraint data
*/
protected void validateConstraintType(Structure constraintStructure) {
if(!constraintType.getClassName().equalsIgnoreCase(constraintStructure.getType())) {
if (!constraintType.getClassName().equalsIgnoreCase(constraintStructure.getType())) {
throw new IllegalArgumentException("Invalud structure type (" + constraintStructure.getType() + ") for the constraint: " + constraintType.getClassName() + '!');
}
}
@ -108,7 +101,8 @@ public abstract class AbstractInfluenceFunction {
* @param constraint
* the constraint
*/
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {}
public void affectAnimation(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
}
/**
* This method returns the bone traces for the bone that is affected by the given constraint.
@ -122,12 +116,12 @@ public abstract class AbstractInfluenceFunction {
*/
protected BoneTrack getBoneTrack(Skeleton skeleton, BoneAnimation boneAnimation, Constraint constraint) {
Long boneOMA = constraint.getBoneOMA();
Bone bone = (Bone)dataRepository.getLoadedFeature(boneOMA, LoadedFeatureDataType.LOADED_FEATURE);
Bone bone = (Bone) dataRepository.getLoadedFeature(boneOMA, LoadedFeatureDataType.LOADED_FEATURE);
int boneIndex = skeleton.getBoneIndex(bone);
if(boneIndex != -1) {
if (boneIndex != -1) {
//searching for track for this bone
for(BoneTrack boneTrack : boneAnimation.getTracks()) {
if(boneTrack.getTargetBoneIndex() == boneIndex) {
for (BoneTrack boneTrack : boneAnimation.getTracks()) {
if (boneTrack.getTargetBoneIndex() == boneIndex) {
return boneTrack;
}
}
@ -142,10 +136,10 @@ public abstract class AbstractInfluenceFunction {
* @return target or subtarget feature
*/
protected Object getTarget(Constraint constraint, LoadedFeatureDataType loadedFeatureDataType) {
Long targetOMA = ((Pointer)constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Object targetObject = dataRepository.getLoadedFeature(targetOMA, loadedFeatureDataType);
String subtargetName = constraint.getData().getFieldValue("subtarget").toString();
if(subtargetName.length() > 0) {
if (subtargetName.length() > 0) {
return dataRepository.getLoadedFeature(subtargetName, loadedFeatureDataType);
}
return targetObject;
@ -158,10 +152,10 @@ public abstract class AbstractInfluenceFunction {
* @return target's object location
*/
protected Vector3f getTargetLocation(Constraint constraint) {
Long targetOMA = ((Pointer)constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Space targetSpace = constraint.getTargetSpace();
Node targetObject = (Node)dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch(targetSpace) {
Node targetObject = (Node) dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch (targetSpace) {
case CONSTRAINT_SPACE_LOCAL:
return targetObject.getLocalTranslation();
case CONSTRAINT_SPACE_WORLD:
@ -190,10 +184,10 @@ public abstract class AbstractInfluenceFunction {
* @return target's object rotation
*/
protected Quaternion getTargetRotation(Constraint constraint) {
Long targetOMA = ((Pointer)constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Space targetSpace = constraint.getTargetSpace();
Node targetObject = (Node)dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch(targetSpace) {
Node targetObject = (Node) dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch (targetSpace) {
case CONSTRAINT_SPACE_LOCAL:
return targetObject.getLocalRotation();
case CONSTRAINT_SPACE_WORLD:
@ -210,10 +204,10 @@ public abstract class AbstractInfluenceFunction {
* @return target's object scale
*/
protected Vector3f getTargetScale(Constraint constraint) {
Long targetOMA = ((Pointer)constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Long targetOMA = ((Pointer) constraint.getData().getFieldValue("tar")).getOldMemoryAddress();
Space targetSpace = constraint.getTargetSpace();
Node targetObject = (Node)dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch(targetSpace) {
Node targetObject = (Node) dataRepository.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
switch (targetSpace) {
case CONSTRAINT_SPACE_LOCAL:
return targetObject.getLocalScale();
case CONSTRAINT_SPACE_WORLD:

@ -13,10 +13,10 @@ import com.jme3.scene.plugins.blender.utils.DynamicArray;
* @author Marcin Roguski
*/
public class BezierCurve {
public static final int X_VALUE = 0;
public static final int Y_VALUE = 1;
public static final int Z_VALUE = 2;
/**
* The type of the curve. Describes the data it modifies.
* Used in ipos calculations.
@ -29,7 +29,7 @@ public class BezierCurve {
@SuppressWarnings("unchecked")
public BezierCurve(final int type, final List<Structure> bezTriples, final int dimension) {
if(dimension != 2 && dimension != 3) {
if (dimension != 2 && dimension != 3) {
throw new IllegalArgumentException("The dimension of the curve should be 2 or 3!");
}
this.type = type;
@ -39,10 +39,10 @@ public class BezierCurve {
//the third index specifies the coordinates of the specific point in a bezier triple
bezierPoints = new float[bezTriples.size()][3][dimension];
int i = 0, j, k;
for(Structure bezTriple : bezTriples) {
DynamicArray<Number> vec = (DynamicArray<Number>)bezTriple.getFieldValue("vec");
for(j = 0; j < 3; ++j) {
for(k = 0; k < dimension; ++k) {
for (Structure bezTriple : bezTriples) {
DynamicArray<Number> vec = (DynamicArray<Number>) bezTriple.getFieldValue("vec");
for (j = 0; j < 3; ++j) {
for (k = 0; k < dimension; ++k) {
bezierPoints[i][j][k] = vec.get(j, k).floatValue();
}
}
@ -61,8 +61,8 @@ public class BezierCurve {
* @return the value of the curve
*/
public float evaluate(int frame, int valuePart) {
for(int i = 0; i < bezierPoints.length - 1; ++i) {
if(frame >= bezierPoints[i][1][0] && frame <= bezierPoints[i + 1][1][0]) {
for (int i = 0; i < bezierPoints.length - 1; ++i) {
if (frame >= bezierPoints[i][1][0] && frame <= bezierPoints[i + 1][1][0]) {
float t = (frame - bezierPoints[i][1][0]) / (bezierPoints[i + 1][1][0] - bezierPoints[i][1][0]);
float oneMinusT = 1.0f - t;
float oneMinusT2 = oneMinusT * oneMinusT;
@ -70,7 +70,7 @@ public class BezierCurve {
return bezierPoints[i][1][valuePart] * oneMinusT2 * oneMinusT + 3.0f * bezierPoints[i][2][valuePart] * t * oneMinusT2 + 3.0f * bezierPoints[i + 1][0][valuePart] * t2 * oneMinusT + bezierPoints[i + 1][1][valuePart] * t2 * t;
}
}
if(frame < bezierPoints[0][1][0]) {
if (frame < bezierPoints[0][1][0]) {
return bezierPoints[0][1][1];
} else { //frame>bezierPoints[bezierPoints.length-1][1][0]
return bezierPoints[bezierPoints.length - 1][1][1];
@ -82,7 +82,7 @@ public class BezierCurve {
* @return the frame number of the last defined bezier triple point for the curve
*/
public int getLastFrame() {
return (int)bezierPoints[bezierPoints.length - 1][1][0];
return (int) bezierPoints[bezierPoints.length - 1][1][0];
}
/**
@ -100,7 +100,7 @@ public class BezierCurve {
*/
public List<Vector3f> getControlPoints() {
List<Vector3f> controlPoints = new ArrayList<Vector3f>(bezierPoints.length * 3);
for(int i = 0;i<bezierPoints.length;++i) {
for (int i = 0; i < bezierPoints.length; ++i) {
controlPoints.add(new Vector3f(bezierPoints[i][0][0], bezierPoints[i][0][1], bezierPoints[i][0][2]));
controlPoints.add(new Vector3f(bezierPoints[i][1][0], bezierPoints[i][1][1], bezierPoints[i][1][2]));
controlPoints.add(new Vector3f(bezierPoints[i][2][0], bezierPoints[i][2][1], bezierPoints[i][2][2]));
@ -111,7 +111,7 @@ public class BezierCurve {
@Override
public String toString() {
StringBuilder sb = new StringBuilder("Bezier curve: ").append(type).append('\n');
for(int i = 0; i < bezierPoints.length; ++i) {
for (int i = 0; i < bezierPoints.length; ++i) {
sb.append(this.toStringBezTriple(i)).append('\n');
}
return sb.toString();
@ -124,7 +124,7 @@ public class BezierCurve {
* @return text representation of the triple
*/
private String toStringBezTriple(int tripleIndex) {
if(this.dimension==2) {
if (this.dimension == 2) {
return "[(" + bezierPoints[tripleIndex][0][0] + ", " + bezierPoints[tripleIndex][0][1] + ") ("
+ bezierPoints[tripleIndex][1][0] + ", " + bezierPoints[tripleIndex][1][1] + ") ("
+ bezierPoints[tripleIndex][2][0] + ", " + bezierPoints[tripleIndex][2][1] + ")]";

@ -12,15 +12,14 @@ import com.jme3.scene.plugins.blender.utils.Pointer;
* @author Marcin Roguski
*/
public class Constraint {
/** The type of this constraint. */
private final ConstraintType type;
/** The name of this constraint. */
private final String name;
/** The old memory address of the constraint's owner. */
private final Long boneOMA;
private final Space ownerSpace;
private final Space targetSpace;
/** The structure with constraint's data. */
private final Structure data;
@ -44,17 +43,17 @@ public class Constraint {
* @throws BlenderFileException
*/
public Constraint(Structure constraintStructure, AbstractInfluenceFunction influenceFunction, Long boneOMA, Space ownerSpace, Space targetSpace, Ipo influenceIpo, DataRepository dataRepository) throws BlenderFileException {
if(influenceFunction == null) {
if (influenceFunction == null) {
throw new IllegalArgumentException("Influence function is not defined!");
}
Pointer pData = (Pointer)constraintStructure.getFieldValue("data");
if(!pData.isNull()) {
Pointer pData = (Pointer) constraintStructure.getFieldValue("data");
if (!pData.isNull()) {
data = pData.fetchData(dataRepository.getInputStream()).get(0);
} else {
throw new BlenderFileException("The constraint has no data specified!");
}
this.boneOMA = boneOMA;
this.type = ConstraintType.valueOf(((Number)constraintStructure.getFieldValue("type")).intValue());
this.type = ConstraintType.valueOf(((Number) constraintStructure.getFieldValue("type")).intValue());
this.name = constraintStructure.getFieldValue("name").toString();
this.ownerSpace = ownerSpace;
this.targetSpace = targetSpace;
@ -136,6 +135,7 @@ public class Constraint {
* @author Marcin Roguski
*/
public static enum Space {
CONSTRAINT_SPACE_WORLD, CONSTRAINT_SPACE_LOCAL, CONSTRAINT_SPACE_POSE, CONSTRAINT_SPACE_PARLOCAL, CONSTRAINT_SPACE_INVALID;
/**
@ -145,7 +145,7 @@ public class Constraint {
* @return the scape enum instance
*/
public static Space valueOf(byte c) {
switch(c) {
switch (c) {
case 0:
return CONSTRAINT_SPACE_WORLD;
case 1:

@ -11,6 +11,7 @@ import java.util.Map;
*/
public enum ConstraintType {
/* Invalid/legacy constraint */
CONSTRAINT_TYPE_NULL(0, "bNullConstraint"),
/* Unimplemented non longer :) - during constraints recode, Aligorith */
CONSTRAINT_TYPE_CHILDOF(1, "bChildOfConstraint"),
@ -44,15 +45,15 @@ public enum ConstraintType {
CONSTRAINT_TYPE_TRANSFORM(19, "bTransformConstraint"),
/* shrinkwrap (loc/rot) constraint */
CONSTRAINT_TYPE_SHRINKWRAP(20, "bShrinkwrapConstraint");
/** The constraint's id (in blender known as 'type'). */
private int constraintId;
/** The name of constraint class used by blender. */
private String className;
/** The map containing class names and types of constraints. */
private static Map<String, ConstraintType> typesMap = new HashMap<String, ConstraintType>(ConstraintType.values().length);
private static final Map<String, ConstraintType> typesMap = new HashMap<String, ConstraintType>(ConstraintType.values().length);
/** The map containing class names and types of constraints. */
private static Map<Integer, ConstraintType> idsMap = new HashMap<Integer, ConstraintType>(ConstraintType.values().length);
private static final Map<Integer, ConstraintType> idsMap = new HashMap<Integer, ConstraintType>(ConstraintType.values().length);
static {
idsMap.put(Integer.valueOf(CONSTRAINT_TYPE_NULL.constraintId), CONSTRAINT_TYPE_NULL);
idsMap.put(Integer.valueOf(CONSTRAINT_TYPE_CHILDOF.constraintId), CONSTRAINT_TYPE_CHILDOF);
@ -75,6 +76,7 @@ public enum ConstraintType {
idsMap.put(Integer.valueOf(CONSTRAINT_TYPE_TRANSFORM.constraintId), CONSTRAINT_TYPE_TRANSFORM);
idsMap.put(Integer.valueOf(CONSTRAINT_TYPE_SHRINKWRAP.constraintId), CONSTRAINT_TYPE_SHRINKWRAP);
}
/**
* Constructor. Stores constraint type and class name.
* @param constraintId
@ -121,10 +123,10 @@ public enum ConstraintType {
*/
public static ConstraintType getByBlenderClassName(String className) {
ConstraintType result = typesMap.get(className);
if(result == null) {
if (result == null) {
ConstraintType[] constraints = ConstraintType.values();
for(ConstraintType constraint : constraints) {
if(constraint.className.equals(className)) {
for (ConstraintType constraint : constraints) {
if (constraint.className.equals(className)) {
return constraint;
}
}

@ -10,6 +10,7 @@ import com.jme3.math.Vector3f;
* @author Marcin Roguski
*/
public class Ipo {
public static final int AC_LOC_X = 1;
public static final int AC_LOC_Y = 2;
public static final int AC_LOC_Z = 3;
@ -23,7 +24,6 @@ public class Ipo {
public static final int AC_QUAT_X = 26;
public static final int AC_QUAT_Y = 27;
public static final int AC_QUAT_Z = 28;
/** A list of bezier curves for this interpolation object. */
private BezierCurve[] bezierCurves;
/** Each ipo contains one bone track. */
@ -75,9 +75,9 @@ public class Ipo {
*/
public int getLastFrame() {
int result = 1;
for(int i = 0; i < bezierCurves.length; ++i) {
for (int i = 0; i < bezierCurves.length; ++i) {
int tempResult = bezierCurves[i].getLastFrame();
if(tempResult > result) {
if (tempResult > result) {
result = tempResult;
}
}
@ -85,19 +85,19 @@ public class Ipo {
}
public void modifyTranslation(int frame, Vector3f translation) {
if(calculatedTrack!=null) {
if (calculatedTrack != null) {
calculatedTrack.getTranslations()[frame].set(translation);
}
}
public void modifyRotation(int frame, Quaternion rotation) {
if(calculatedTrack!=null) {
if (calculatedTrack != null) {
calculatedTrack.getRotations()[frame].set(rotation);
}
}
public void modifyScale(int frame, Vector3f scale) {
if(calculatedTrack!=null) {
if (calculatedTrack != null) {
calculatedTrack.getScales()[frame].set(scale);
}
}
@ -131,43 +131,43 @@ public class Ipo {
float[] scale = new float[3];
//calculating track data
for(int frame = startFrame; frame <= stopFrame; ++frame) {
for (int frame = startFrame; frame <= stopFrame; ++frame) {
int index = frame - startFrame;
times[index] = start + (frame - 1) * timeBetweenFrames;
for(int j = 0; j < bezierCurves.length; ++j) {
for (int j = 0; j < bezierCurves.length; ++j) {
double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE);
switch(bezierCurves[j].getType()) {
switch (bezierCurves[j].getType()) {
case AC_LOC_X:
case AC_LOC_Y:
case AC_LOC_Z:
translation[bezierCurves[j].getType() - 1] = (float)value;
translation[bezierCurves[j].getType() - 1] = (float) value;
break;
case OB_ROT_X:
case OB_ROT_Y:
case OB_ROT_Z:
objectRotation[bezierCurves[j].getType() - 7] = (float)value;
objectRotation[bezierCurves[j].getType() - 7] = (float) value;
bObjectRotation = true;
break;
case AC_SIZE_X:
case AC_SIZE_Y:
case AC_SIZE_Z:
scale[bezierCurves[j].getType() - 13] = (float)value;
scale[bezierCurves[j].getType() - 13] = (float) value;
break;
case AC_QUAT_W:
quaternionRotation[3] = (float)value;
quaternionRotation[3] = (float) value;
break;
case AC_QUAT_X:
case AC_QUAT_Y:
case AC_QUAT_Z:
quaternionRotation[bezierCurves[j].getType() - 26] = (float)value;
quaternionRotation[bezierCurves[j].getType() - 26] = (float) value;
break;
default:
//TODO: error? info? warning?
}
}
translations[index] = new Vector3f(translation[0], translation[1], translation[2]);
rotations[index] = bObjectRotation ? new Quaternion().fromAngles(objectRotation) :
new Quaternion(quaternionRotation[0], quaternionRotation[1], quaternionRotation[2], quaternionRotation[3]);
rotations[index] = bObjectRotation ? new Quaternion().fromAngles(objectRotation)
: new Quaternion(quaternionRotation[0], quaternionRotation[1], quaternionRotation[2], quaternionRotation[3]);
scales[index] = new Vector3f(scale[0], scale[1], scale[2]);
}
calculatedTrack = new BoneTrack(boneIndex, times, translations, rotations, scales);

@ -7,16 +7,17 @@ package com.jme3.scene.plugins.blender.structures;
* @author Marcin Roguski (Kaelthas)
*/
public class Modifier {
public static final String ARRAY_MODIFIER_DATA = "ArrayModifierData";
public static final String ARMATURE_MODIFIER_DATA = "ArmatureModifierData";
public static final String PARTICLE_MODIFIER_DATA = "ParticleSystemModifierData";
/** Blender's type of modifier. */
private String type;
/** JME modifier representation object. */
private Object jmeModifierRepresentation;
/** Various additional data used by modifiers.*/
private Object additionalData;
/**
* Constructor. Creates modifier object.
* @param type

@ -42,6 +42,7 @@ import com.jme3.util.BufferUtils;
* @author Marcin Roguski
*/
public abstract class AbstractBlenderHelper {
/** The version of the blend file. */
protected final int blenderVersion;
@ -58,7 +59,8 @@ public abstract class AbstractBlenderHelper {
/**
* This method clears the state of the helper so that it can be used for different calculations of another feature.
*/
public void clearState() { }
public void clearState() {
}
/**
* This method should be used to check if the text is blank. Avoid using text.trim().length()==0. This causes that more strings are
@ -85,12 +87,12 @@ public abstract class AbstractBlenderHelper {
* list of float[4] objects to place into a new FloatBuffer
*/
protected FloatBuffer createFloatBuffer(List<float[]> data) {
if(data == null) {
if (data == null) {
return null;
}
FloatBuffer buff = BufferUtils.createFloatBuffer(4 * data.size());
for(float[] v : data) {
if(v != null) {
for (float[] v : data) {
if (v != null) {
buff.put(v[0]).put(v[1]).put(v[2]).put(v[3]);
} else {
buff.put(0).put(0).put(0).put(0);

@ -52,7 +52,8 @@ import com.jme3.scene.plugins.blender.exception.BlenderFileException;
* the type of material element
*/
//TODO: ujednolicić wyrzucane wyjątki
public interface IBlenderConverter<NodeType, CameraType, LightType, ObjectType, MeshType, MaterialType> {
public interface BlenderConverter<NodeType, CameraType, LightType, ObjectType, MeshType, MaterialType> {
/**
* This method reads converts the given structure into scene. The given structure needs to be filled with the
* appropriate data.

@ -46,8 +46,8 @@ import com.jme3.scene.plugins.blender.exception.BlenderFileException;
* @author Marcin Roguski
*/
public class BlenderInputStream extends InputStream {
private static final Logger LOGGER = Logger.getLogger(BlenderInputStream.class.getName());
private static final Logger LOGGER = Logger.getLogger(BlenderInputStream.class.getName());
/** The default size of the blender buffer. */
private static final int DEFAULT_BUFFER_SIZE = 1048576; //1MB
/** The application's asset manager. */
@ -88,14 +88,14 @@ public class BlenderInputStream extends InputStream {
} catch (IOException e) {
size = 0;
}
if(size <= 0) {
if (size <= 0) {
size = BlenderInputStream.DEFAULT_BUFFER_SIZE;
}
//buffered input stream is used here for much faster file reading
BufferedInputStream bufferedInputStream;
if(inputStream instanceof BufferedInputStream) {
bufferedInputStream = (BufferedInputStream)inputStream;
if (inputStream instanceof BufferedInputStream) {
bufferedInputStream = (BufferedInputStream) inputStream;
} else {
bufferedInputStream = new BufferedInputStream(inputStream);
}
@ -108,7 +108,7 @@ public class BlenderInputStream extends InputStream {
try {
this.readFileHeader();
} catch(BlenderFileException e) {//the file might be packed, don't panic, try one more time ;)
} catch (BlenderFileException e) {//the file might be packed, don't panic, try one more time ;)
this.decompressFile();
this.position = 0;
this.readFileHeader();
@ -127,9 +127,9 @@ public class BlenderInputStream extends InputStream {
int data = inputStream.read();
cachedBuffer = new byte[size];
size = 0;//this will count the actual size
while(data != -1) {
cachedBuffer[size++] = (byte)data;
if(size >= cachedBuffer.length) {//widen the cached array
while (data != -1) {
cachedBuffer[size++] = (byte) data;
if (size >= cachedBuffer.length) {//widen the cached array
byte[] newBuffer = new byte[cachedBuffer.length + (cachedBuffer.length >> 1)];
System.arraycopy(cachedBuffer, 0, newBuffer, 0, cachedBuffer.length);
cachedBuffer = newBuffer;
@ -148,14 +148,14 @@ public class BlenderInputStream extends InputStream {
gis = new GZIPInputStream(new ByteArrayInputStream(cachedBuffer));
this.readStreamToCache(gis);
} catch (IOException e) {
throw new IllegalStateException("IO errors occured where they should NOT! " +
"The data is already buffered at this point!", e);
throw new IllegalStateException("IO errors occured where they should NOT! "
+ "The data is already buffered at this point!", e);
} finally {
try {
if(gis!=null) {
if (gis != null) {
gis.close();
}
} catch(IOException e) {
} catch (IOException e) {
LOGGER.warning(e.getMessage());
}
}
@ -171,28 +171,28 @@ public class BlenderInputStream extends InputStream {
private void readFileHeader() throws BlenderFileException {
byte[] identifier = new byte[7];
int bytesRead = this.readBytes(identifier);
if(bytesRead != 7) {
if (bytesRead != 7) {
throw new BlenderFileException("Error reading header identifier. Only " + bytesRead + " bytes read and there should be 7!");
}
String strIdentifier = new String(identifier);
if(!"BLENDER".equals(strIdentifier)) {
if (!"BLENDER".equals(strIdentifier)) {
throw new BlenderFileException("Wrong file identifier: " + strIdentifier + "! Should be 'BLENDER'!");
}
char pointerSizeSign = (char)this.readByte();
if(pointerSizeSign == '-') {
char pointerSizeSign = (char) this.readByte();
if (pointerSizeSign == '-') {
pointerSize = 8;
} else if(pointerSizeSign == '_') {
} else if (pointerSizeSign == '_') {
pointerSize = 4;
} else {
throw new BlenderFileException("Invalid pointer size character! Should be '_' or '-' and there is: " + pointerSizeSign);
}
endianess = (char)this.readByte();
if(endianess != 'v' && endianess != 'V') {
endianess = (char) this.readByte();
if (endianess != 'v' && endianess != 'V') {
throw new BlenderFileException("Unknown endianess value! 'v' or 'V' expected and found: " + endianess);
}
byte[] versionNumber = new byte[3];
bytesRead = this.readBytes(versionNumber);
if(bytesRead != 3) {
if (bytesRead != 3) {
throw new BlenderFileException("Error reading version numberr. Only " + bytesRead + " bytes read and there should be 3!");
}
this.versionNumber = new String(versionNumber);
@ -222,7 +222,7 @@ public class BlenderInputStream extends InputStream {
* @return number of read bytes (a length of array actually)
*/
private int readBytes(byte[] bytes) {
for(int i=0;i<bytes.length;++i) {
for (int i = 0; i < bytes.length; ++i) {
bytes[i] = (byte) this.readByte();
}
return bytes.length;
@ -235,7 +235,7 @@ public class BlenderInputStream extends InputStream {
public int readShort() {
int part1 = this.readByte();
int part2 = this.readByte();
if(endianess == 'v') {
if (endianess == 'v') {
return (part2 << 8) + part1;
} else {
return (part1 << 8) + part2;
@ -251,7 +251,7 @@ public class BlenderInputStream extends InputStream {
int part2 = this.readByte();
int part3 = this.readByte();
int part4 = this.readByte();
if(endianess == 'v') {
if (endianess == 'v') {
return (part4 << 24) + (part3 << 16) + (part2 << 8) + part1;
} else {
return (part1 << 24) + (part2 << 16) + (part3 << 8) + part4;
@ -275,7 +275,7 @@ public class BlenderInputStream extends InputStream {
long part1 = this.readInt();
long part2 = this.readInt();
long result = -1;
if(endianess == 'v') {
if (endianess == 'v') {
result = part2 << 32 | part1;
} else {
result = part1 << 32 | part2;
@ -298,7 +298,7 @@ public class BlenderInputStream extends InputStream {
* @return the pointer value
*/
public long readPointer() {
if(pointerSize == 4) {
if (pointerSize == 4) {
return this.readInt();
}
return this.readLong();
@ -311,8 +311,8 @@ public class BlenderInputStream extends InputStream {
public String readString() {
StringBuilder stringBuilder = new StringBuilder();
int data = this.readByte();
while(data != 0) {
stringBuilder.append((char)data);
while (data != 0) {
stringBuilder.append((char) data);
data = this.readByte();
}
return stringBuilder.toString();
@ -365,11 +365,11 @@ public class BlenderInputStream extends InputStream {
* the byte amount to which we aligh the cursor
*/
public void alignPosition(int bytesAmount) {
if(bytesAmount <= 0) {
if (bytesAmount <= 0) {
throw new IllegalArgumentException("Alignment byte number shoulf be positivbe!");
}
long move = position % bytesAmount;
if(move > 0) {
if (move > 0) {
position += bytesAmount - move;
}
}

@ -54,6 +54,7 @@ import com.jme3.scene.plugins.blender.structures.Modifier;
* @author Marcin Roguski
*/
public class DataRepository {
/** The blender key. */
private BlenderKey blenderKey;
/** The header of the file block. */
@ -164,7 +165,7 @@ public class DataRepository {
public void addFileBlockHeader(Long oldMemoryAddress, FileBlockHeader fileBlockHeader) {
fileBlockHeadersByOma.put(oldMemoryAddress, fileBlockHeader);
List<FileBlockHeader> headers = fileBlockHeadersByCode.get(Integer.valueOf(fileBlockHeader.getCode()));
if(headers == null) {
if (headers == null) {
headers = new ArrayList<FileBlockHeader>();
fileBlockHeadersByCode.put(Integer.valueOf(fileBlockHeader.getCode()), headers);
}
@ -215,10 +216,9 @@ public class DataRepository {
@SuppressWarnings("unchecked")
public <T> T getHelper(Class<?> clazz) {
return (T)helpers.get(clazz.getSimpleName());
return (T) helpers.get(clazz.getSimpleName());
}
/**
* This method adds a loaded feature to the map. The key is its unique old memory address.
* @param oldMemoryAddress
@ -230,12 +230,12 @@ public class DataRepository {
* the feature we want to store
*/
public void addLoadedFeatures(Long oldMemoryAddress, String featureName, Structure structure, Object feature) {
if(oldMemoryAddress == null || structure == null || feature == null) {
if (oldMemoryAddress == null || structure == null || feature == null) {
throw new IllegalArgumentException("One of the given arguments is null!");
}
Object[] storedData = new Object[] {structure, feature};
Object[] storedData = new Object[]{structure, feature};
loadedFeatures.put(oldMemoryAddress, storedData);
if(featureName!=null) {
if (featureName != null) {
loadedFeaturesByName.put(featureName, storedData);
}
}
@ -251,7 +251,7 @@ public class DataRepository {
*/
public Object getLoadedFeature(Long oldMemoryAddress, LoadedFeatureDataType loadedFeatureDataType) {
Object[] result = loadedFeatures.get(oldMemoryAddress);
if(result != null) {
if (result != null) {
return result[loadedFeatureDataType.getIndex()];
}
return null;
@ -268,7 +268,7 @@ public class DataRepository {
*/
public Object getLoadedFeature(String featureName, LoadedFeatureDataType loadedFeatureDataType) {
Object[] result = loadedFeaturesByName.get(featureName);
if(result != null) {
if (result != null) {
return result[loadedFeatureDataType.getIndex()];
}
return null;
@ -297,7 +297,7 @@ public class DataRepository {
public Structure popParent() {
try {
return parentStack.pop();
} catch(EmptyStackException e) {
} catch (EmptyStackException e) {
return null;
}
}
@ -309,7 +309,7 @@ public class DataRepository {
public Structure peekParent() {
try {
return parentStack.peek();
} catch(EmptyStackException e) {
} catch (EmptyStackException e) {
return null;
}
}
@ -337,7 +337,7 @@ public class DataRepository {
*/
public void addModifier(Long ownerOMA, String modifierType, Object loadedModifier, Object additionalModifierData) {
List<Modifier> objectModifiers = this.modifiers.get(ownerOMA);
if(objectModifiers == null) {
if (objectModifiers == null) {
objectModifiers = new ArrayList<Modifier>();
this.modifiers.put(ownerOMA, objectModifiers);
}
@ -356,9 +356,9 @@ public class DataRepository {
public List<Modifier> getModifiers(Long objectOMA, String type) {
List<Modifier> result = new ArrayList<Modifier>();
List<Modifier> readModifiers = modifiers.get(objectOMA);
if(readModifiers != null && readModifiers.size() > 0) {
for(Modifier modifier : readModifiers) {
if(type==null || type.isEmpty() || modifier.getType().equals(type)) {
if (readModifiers != null && readModifiers.size() > 0) {
for (Modifier modifier : readModifiers) {
if (type == null || type.isEmpty() || modifier.getType().equals(type)) {
result.add(modifier);
}
}
@ -371,7 +371,7 @@ public class DataRepository {
* @return the default material
*/
public synchronized Material getDefaultMaterial() {
if(blenderKey.getDefaultMaterial() == null) {
if (blenderKey.getDefaultMaterial() == null) {
Material defaultMaterial = new Material(assetManager, "Common/MatDefs/Misc/Unshaded.j3md");
defaultMaterial.setColor("Color", ColorRGBA.DarkGray);
blenderKey.setDefaultMaterial(defaultMaterial);
@ -385,8 +385,8 @@ public class DataRepository {
* @author Marcin Roguski
*/
public static enum LoadedFeatureDataType {
LOADED_STRUCTURE(0), LOADED_FEATURE(1);
LOADED_STRUCTURE(0), LOADED_FEATURE(1);
private int index;
private LoadedFeatureDataType(int index) {

@ -40,6 +40,7 @@ import com.jme3.scene.plugins.blender.exception.BlenderFileException;
* the type of stored data in the array
*/
public class DynamicArray<T> implements Cloneable {
/** An array object that holds the required data. */
private T[] array;
/**
@ -60,13 +61,13 @@ public class DynamicArray<T> implements Cloneable {
public DynamicArray(int[] tableSizes) throws BlenderFileException {
this.tableSizes = tableSizes;
int totalSize = 1;
for(int size : tableSizes) {
if(size <= 0) {
for (int size : tableSizes) {
if (size <= 0) {
throw new BlenderFileException("The size of the table must be positive!");
}
totalSize *= size;
}
this.array = (T[])new Object[totalSize];
this.array = (T[]) new Object[totalSize];
}
/**
@ -79,13 +80,13 @@ public class DynamicArray<T> implements Cloneable {
public DynamicArray(int[] tableSizes, T[] data) throws BlenderFileException {
this.tableSizes = tableSizes;
int totalSize = 1;
for(int size : tableSizes) {
if(size <= 0) {
for (int size : tableSizes) {
if (size <= 0) {
throw new BlenderFileException("The size of the table must be positive!");
}
totalSize *= size;
}
if(totalSize != data.length) {
if (totalSize != data.length) {
throw new IllegalArgumentException("The size of the table does not match the size of the given data!");
}
this.array = data;
@ -115,11 +116,11 @@ public class DynamicArray<T> implements Cloneable {
* @return required data required data
*/
public T get(int... position) {
if(position.length != tableSizes.length) {
if (position.length != tableSizes.length) {
throw new ArrayIndexOutOfBoundsException("The table accepts " + tableSizes.length + " indexing number(s)!");
}
int index = 0;
for(int i = 0; i < position.length - 1; ++i) {
for (int i = 0; i < position.length - 1; ++i) {
index += position[i] * tableSizes[i + 1];
}
index += position[position.length - 1];
@ -137,15 +138,15 @@ public class DynamicArray<T> implements Cloneable {
@Override
public String toString() {
StringBuilder result = new StringBuilder();
if(array instanceof Character[]) {//in case of character array we convert it to String
for(int i = 0; i < array.length && (Character)array[i] != '\0'; ++i) {//strings are terminater with '0'
if (array instanceof Character[]) {//in case of character array we convert it to String
for (int i = 0; i < array.length && (Character) array[i] != '\0'; ++i) {//strings are terminater with '0'
result.append(array[i]);
}
} else {
result.append('[');
for(int i = 0; i < array.length; ++i) {
for (int i = 0; i < array.length; ++i) {
result.append(array[i].toString());
if(i + 1 < array.length) {
if (i + 1 < array.length) {
result.append(',');
}
}

@ -55,9 +55,9 @@ import com.jme3.scene.plugins.blender.helpers.ObjectHelper;
* This class converts blender file blocks into jMonkeyEngine data structures.
* @author Marcin Roguski
*/
public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Object, List<Geometry>, Material> {
private static final Logger LOGGER = Logger.getLogger(JmeConverter.class.getName());
public class JmeConverter implements BlenderConverter<Node, Camera, Light, Object, List<Geometry>, Material> {
private static final Logger LOGGER = Logger.getLogger(JmeConverter.class.getName());
private final DataRepository dataRepository;
/**
@ -71,16 +71,16 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
*/
public JmeConverter(DataRepository dataRepository) {
//validating the given data first
if(dataRepository.getAssetManager() == null) {
if (dataRepository.getAssetManager() == null) {
throw new IllegalArgumentException("Cannot find asset manager!");
}
if(dataRepository.getBlenderKey() == null) {
if (dataRepository.getBlenderKey() == null) {
throw new IllegalArgumentException("Cannot find blender key!");
}
if(dataRepository.getDnaBlockData() == null) {
if (dataRepository.getDnaBlockData() == null) {
throw new IllegalArgumentException("Cannot find dna block!");
}
if(dataRepository.getInputStream() == null) {
if (dataRepository.getInputStream() == null) {
throw new IllegalArgumentException("Cannot find blender file stream!");
}
this.dataRepository = dataRepository;
@ -88,15 +88,15 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
@Override
public Node toScene(Structure structure) {//TODO: poprawny import sceny
if((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.SCENES) == 0) {
if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.SCENES) == 0) {
return null;
}
Structure id = (Structure)structure.getFieldValue("id");
Structure id = (Structure) structure.getFieldValue("id");
String sceneName = id.getFieldValue("name").toString();
//veryfying layers to be loaded
if(dataRepository.getBlenderKey().getLayersToLoad()<0) {
int lay = ((Number)structure.getFieldValue("lay")).intValue();
if (dataRepository.getBlenderKey().getLayersToLoad() < 0) {
int lay = ((Number) structure.getFieldValue("lay")).intValue();
dataRepository.getBlenderKey().setLayersToLoad(lay);//load only current layer
}
return new Node(sceneName);
@ -104,7 +104,7 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
@Override
public Camera toCamera(Structure structure) throws BlenderFileException {
if((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.CAMERAS) == 0) {
if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.CAMERAS) == 0) {
return null;
}
CameraHelper cameraHelper = dataRepository.getHelper(CameraHelper.class);
@ -113,7 +113,7 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
@Override
public Light toLight(Structure structure) throws BlenderFileException {
if((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) == 0) {
if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) == 0) {
return null;
}
LightHelper lightHelper = dataRepository.getHelper(LightHelper.class);
@ -122,9 +122,9 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
@Override
public Object toObject(Structure structure) throws BlenderFileException {
int lay = ((Number)structure.getFieldValue("lay")).intValue();
if((lay & dataRepository.getBlenderKey().getLayersToLoad()) == 0 ||
(dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) == 0) {
int lay = ((Number) structure.getFieldValue("lay")).intValue();
if ((lay & dataRepository.getBlenderKey().getLayersToLoad()) == 0
|| (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) == 0) {
return null;
}
ObjectHelper objectHelper = dataRepository.getHelper(ObjectHelper.class);
@ -139,7 +139,7 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
@Override
public Material toMaterial(Structure structure) throws BlenderFileException {
if((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) == 0) {
if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) == 0) {
return null;
}
MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class);
@ -158,9 +158,9 @@ public class JmeConverter implements IBlenderConverter<Node, Camera, Light, Obje
//reading ambient light
AmbientLight ambientLight = new AmbientLight();
float ambr = ((Number)structure.getFieldValue("ambr")).floatValue();
float ambg = ((Number)structure.getFieldValue("ambg")).floatValue();
float ambb = ((Number)structure.getFieldValue("ambb")).floatValue();
float ambr = ((Number) structure.getFieldValue("ambr")).floatValue();
float ambg = ((Number) structure.getFieldValue("ambg")).floatValue();
float ambb = ((Number) structure.getFieldValue("ambb")).floatValue();
ambientLight.setColor(new ColorRGBA(ambr, ambg, ambb, 0.0f));
result.setAmbientLight(ambientLight);

@ -43,6 +43,7 @@ import com.jme3.scene.plugins.blender.exception.BlenderFileException;
* @author Marcin Roguski
*/
public class Pointer {
/** The data repository. */
private DataRepository dataRepository;
/** The level of the pointer. */
@ -88,20 +89,20 @@ public class Pointer {
* this exception is thrown when the blend file structure is somehow invalid or corrupted
*/
public List<Structure> fetchData(BlenderInputStream inputStream) throws BlenderFileException {
if(oldMemoryAddress == 0) {
if (oldMemoryAddress == 0) {
throw new NullPointerException("The pointer points to nothing!");
}
List<Structure> structures = null;
FileBlockHeader dataFileBlock = dataRepository.getFileBlock(oldMemoryAddress);
if(pointerLevel > 1) {
if (pointerLevel > 1) {
int pointersAmount = dataFileBlock.getSize() / inputStream.getPointerSize() * dataFileBlock.getCount();
for(int i = 0; i < pointersAmount; ++i) {
for (int i = 0; i < pointersAmount; ++i) {
inputStream.setPosition(dataFileBlock.getBlockPosition() + inputStream.getPointerSize() * i);
long oldMemoryAddress = inputStream.readPointer();
if(oldMemoryAddress != 0L) {
if (oldMemoryAddress != 0L) {
Pointer p = new Pointer(pointerLevel - 1, this.function, dataRepository);
p.oldMemoryAddress = oldMemoryAddress;
if(structures == null) {
if (structures == null) {
structures = p.fetchData(inputStream);
} else {
structures.addAll(p.fetchData(inputStream));
@ -111,7 +112,7 @@ public class Pointer {
} else {
inputStream.setPosition(dataFileBlock.getBlockPosition());
structures = new ArrayList<Structure>(dataFileBlock.getCount());
for(int i = 0; i < dataFileBlock.getCount(); ++i) {
for (int i = 0; i < dataFileBlock.getCount(); ++i) {
Structure structure = dataRepository.getDnaBlockData().getStructure(dataFileBlock.getSdnaIndex());
structure.fill(inputStream);
structures.add(structure);
@ -152,22 +153,22 @@ public class Pointer {
@Override
public int hashCode() {
return 31 + (int)(oldMemoryAddress ^ oldMemoryAddress >>> 32);
return 31 + (int) (oldMemoryAddress ^ oldMemoryAddress >>> 32);
}
@Override
public boolean equals(Object obj) {
if(this == obj) {
if (this == obj) {
return true;
}
if(obj == null) {
if (obj == null) {
return false;
}
if(this.getClass() != obj.getClass()) {
if (this.getClass() != obj.getClass()) {
return false;
}
Pointer other = (Pointer)obj;
if(oldMemoryAddress != other.oldMemoryAddress) {
Pointer other = (Pointer) obj;
if (oldMemoryAddress != other.oldMemoryAddress) {
return false;
}
return true;

@ -347,7 +347,6 @@ public final class Bone implements Savable {
/**
* Set user transform.
* Combine the given transforms to bone's current transforms
* @see setUserControl
*/
public void setUserTransforms(Vector3f translation, Quaternion rotation, Vector3f scale) {
if (!userControl) {
@ -378,10 +377,9 @@ public final class Bone implements Savable {
}
/**
* Returns teh local transform of this bone combined with the given position and rotation
* Returns the local transform of this bone combined with the given position and rotation
* @param position a position
* @param rotation a rotation
* @return
*/
public Transform getCombinedTransform(Vector3f position, Quaternion rotation){
rotation.mult(localPos, tmpTransform.getTranslation()).addLocal(position);

@ -234,13 +234,11 @@ public abstract class CompactArray<T> {
* deserialize object
* @param compactIndex compacted object index
* @param store
* @return
*/
protected abstract T deserialize(int compactIndex, T store);
/**
* serialized size of one object element
* @return
*/
protected abstract int getTupleSize();

@ -10,7 +10,7 @@
The <code>com.jme3.application</code> provides a toolset for jME3 applications
to interact with various components of the engine. Typically, the
{@link com.jme3.app.Application} class will be extended and the update() method
implemented to provide functionality for the main loop. <br/>
implemented to provide functionality for the main loop. <br>
<p>
An <code>Application</code> will typically provide the following services:
<ul>
@ -37,42 +37,42 @@ An <code>Application</code> will typically provide the following services:
<h3>Usage</h3>
An example use of the Application class is as follows<br/>
<br/>
An example use of the Application class is as follows<br>
<br>
<code>
public class ExampleUse extends Application {<br/>
<br/>
private Node rootNode = new Node("Root Node");<br/>
<br/>
public static void main(String[] args){<br/>
ExampleUse app = new ExampleUse();<br/>
app.start();<br/>
}<br/>
<br/>
@Override<br/>
public void initialize(){<br/>
super.initialize();<br/>
<br/>
// attach root node to viewport<br/>
viewPort.attachScene(rootNode);<br/>
}<br/>
<br/>
@Override<br/>
public void update(){<br/>
super.update();<br/>
<br/>
float tpf = timer.getTimePerFrame();<br/>
<br/>
// update rootNode<br/>
rootNode.updateLogicalState(tpf);<br/>
rootNode.updateGeometricState();<br/>
<br/>
// render the viewports<br/>
renderManager.render(tpf);<br/>
}<br/>
}<br/>
<br/>
public class ExampleUse extends Application {<br>
<br>
private Node rootNode = new Node("Root Node");<br>
<br>
public static void main(String[] args){<br>
ExampleUse app = new ExampleUse();<br>
app.start();<br>
}<br>
<br>
@Override<br>
public void initialize(){<br>
super.initialize();<br>
<br>
// attach root node to viewport<br>
viewPort.attachScene(rootNode);<br>
}<br>
<br>
@Override<br>
public void update(){<br>
super.update();<br>
<br>
float tpf = timer.getTimePerFrame();<br>
<br>
// update rootNode<br>
rootNode.updateLogicalState(tpf);<br>
rootNode.updateGeometricState();<br>
<br>
// render the viewports<br>
renderManager.render(tpf);<br>
}<br>
}<br>
<br>
</code>
</body>

@ -173,7 +173,6 @@ public class AppStateManager {
/**
* Calls render for all attached states, do not call directly.
* @param rm The RenderManager
*/
public void postRender(){
AppState[] array = getArray();

@ -54,7 +54,7 @@ public interface AssetLocator {
*
* @param manager
* @param key
* @return
* @return The {@link AssetInfo} that was located, or null if not found.
*/
public AssetInfo locate(AssetManager manager, AssetKey key);
}

@ -159,7 +159,7 @@ public interface AssetManager {
* TGA and DDS.
*
* @param name The name of the texture to load.
* @return
* @return The texture that was loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -168,7 +168,7 @@ public interface AssetManager {
/**
* Load audio file, supported types are WAV or OGG.
* @param key
* @return
* @return The audio data loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -178,7 +178,7 @@ public interface AssetManager {
* Load audio file, supported types are WAV or OGG.
* The file is loaded without stream-mode.
* @param name
* @return
* @return The audio data loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -188,7 +188,7 @@ public interface AssetManager {
* Loads a named model. Models can be jME3 object files (J3O) or
* OgreXML/OBJ files.
* @param key
* @return
* @return The model that was loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -198,7 +198,7 @@ public interface AssetManager {
* Loads a named model. Models can be jME3 object files (J3O) or
* OgreXML/OBJ files.
* @param name
* @return
* @return The model that was loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -207,7 +207,7 @@ public interface AssetManager {
/**
* Load a material (J3M) file.
* @param name
* @return
* @return The material that was loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/
@ -225,7 +225,7 @@ public interface AssetManager {
* and are with the extension "fnt".
*
* @param name
* @return
* @return The font loaded
*
* @see AssetManager#loadAsset(com.jme3.asset.AssetKey)
*/

@ -70,7 +70,7 @@ public class TextureKey extends AssetKey<Texture> {
/**
* Enable smart caching for textures
* @return
* @return true to enable smart cache
*/
@Override
public boolean useSmartCache(){

@ -48,7 +48,7 @@ public interface AudioRenderer {
/**
* Sets the environment, used for reverb effects.
*
* @see PointAudioSource#setReverbEnabled(boolean)
* @see AudioNode#setReverbEnabled(boolean)
* @param env The environment to set.
*/
public void setEnvironment(Environment env);

@ -259,12 +259,8 @@ public class BoundingBox extends BoundingVolume {
* <code>transform</code> modifies the center of the box to reflect the
* change made via a rotation, translation and scale.
*
* @param rotate
* the rotation change.
* @param translate
* the translation change.
* @param scale
* the size change.
* @param trans
* the transform to apply
* @param store
* box to store result in
*/
@ -570,7 +566,7 @@ public class BoundingBox extends BoundingVolume {
* intersects determines if this Bounding Box intersects with another given
* bounding volume. If so, true is returned, otherwise, false is returned.
*
* @see com.jme.bounding.BoundingVolume#intersects(com.jme.bounding.BoundingVolume)
* @see BoundingVolume#intersects(com.jme3.bounding.BoundingVolume)
*/
public boolean intersects(BoundingVolume bv) {
return bv.intersectsBoundingBox(this);
@ -579,7 +575,7 @@ public class BoundingBox extends BoundingVolume {
/**
* determines if this bounding box intersects a given bounding sphere.
*
* @see com.jme.bounding.BoundingVolume#intersectsSphere(com.jme.bounding.BoundingSphere)
* @see BoundingVolume#intersectsSphere(com.jme3.bounding.BoundingSphere)
*/
public boolean intersectsSphere(BoundingSphere bs) {
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bs.center);
@ -600,7 +596,7 @@ public class BoundingBox extends BoundingVolume {
* two boxes intersect in any way, true is returned. Otherwise, false is
* returned.
*
* @see com.jme.bounding.BoundingVolume#intersectsBoundingBox(com.jme.bounding.BoundingBox)
* @see BoundingVolume#intersectsBoundingBox(com.jme3.bounding.BoundingBox)
*/
public boolean intersectsBoundingBox(BoundingBox bb) {
assert Vector3f.isValidVector(center) && Vector3f.isValidVector(bb.center);
@ -632,7 +628,7 @@ public class BoundingBox extends BoundingVolume {
* determines if this bounding box intersects with a given ray object. If an
* intersection has occurred, true is returned, otherwise false is returned.
*
* @see com.jme.bounding.BoundingVolume#intersects(com.jme.math.Ray)
* @see BoundingVolume#intersects(com.jme3.math.Ray)
*/
public boolean intersects(Ray ray) {
assert Vector3f.isValidVector(center);
@ -766,10 +762,11 @@ public class BoundingBox extends BoundingVolume {
/**
* C code ported from http://www.cs.lth.se/home/Tomas_Akenine_Moller/code/tribox3.txt
*
* @param v1
* @param v2
* @param v3
* @return
* @param v1 The first point in the triangle
* @param v2 The second point in the triangle
* @param v3 The third point in the triangle
* @return True if the bounding box intersects the triangle, false
* otherwise.
*/
public boolean intersects(Vector3f v1, Vector3f v2, Vector3f v3){
return Intersection.intersect(this, v1, v2, v3);

@ -387,12 +387,8 @@ public class BoundingSphere extends BoundingVolume {
* <code>transform</code> modifies the center of the sphere to reflect the
* change made via a rotation, translation and scale.
*
* @param rotate
* the rotation change.
* @param translate
* the translation change.
* @param scale
* the size change.
* @param trans
* the transform to apply
* @param store
* sphere to store result in
* @return BoundingVolume

@ -32,6 +32,8 @@
package com.jme3.input.controls;
import com.jme3.input.MouseInput;
/**
* A <code>MouseButtonTrigger</code> is used as a mapping to receive events
* from mouse buttons. It is generally expected for a mouse to have at least

@ -160,7 +160,8 @@ public abstract class Light implements Savable, Cloneable {
this.color.set(color);
}
/**
/*
* Returns true if the light is enabled
*
* @return true if the light is enabled

@ -193,8 +193,7 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Clones this material. The result
* @return
* Clones this material. The result is returned.
*/
@Override
public Material clone() {
@ -219,10 +218,27 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
}
/**
* Returns the currently active technique.
* <p>
* The technique is selected automatically by the {@link RenderManager}
* based on system capabilities. Users may select their own
* technique by using
* {@link #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager) }.
*
* @return the currently active technique.
*
* @see #selectTechnique(java.lang.String, com.jme3.renderer.RenderManager)
*/
public Technique getActiveTechnique() {
return technique;
}
/**
* Check if the transparent value marker is set on this material.
* @return True if the transparent value marker is set on this material.
* @see #setTransparent(boolean)
*/
public boolean isTransparent() {
return transparent;
}
@ -296,6 +312,13 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
return def;
}
/**
* Returns the parameter set on this material with the given name,
* returns <code>null</code> if the parameter is not set.
*
* @param name The parameter name to look up.
* @return The MatParam if set, or null if not set.
*/
public MatParam getParam(String name) {
MatParam param = paramValues.get(name);
if (param instanceof MatParam) {
@ -304,6 +327,13 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
return null;
}
/**
* Returns the texture parameter set on this material with the given name,
* returns <code>null</code> if the parameter is not set.
*
* @param name The parameter name to look up.
* @return The MatParamTexture if set, or null if not set.
*/
public MatParamTexture getTextureParam(String name) {
MatParam param = paramValues.get(name);
if (param instanceof MatParamTexture) {
@ -312,6 +342,13 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
return null;
}
/**
* Returns a collection of all parameters set on this material.
*
* @return a collection of all parameters set on this material.
*
* @see #setParam(java.lang.String, com.jme3.shader.VarType, java.lang.Object)
*/
public Collection<MatParam> getParams() {
return paramValues.values();
}
@ -342,10 +379,11 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a parameter to the material shader
* Pass a parameter to the material shader.
*
* @param name the name of the parameter defined in the material definition (j3md)
* @param type the type of the parameter @see com.jme3.shaderVarType
* @param value the value of the param
* @param type the type of the parameter {@link VarType}
* @param value the value of the parameter
*/
public void setParam(String name, VarType type, Object value) {
name = checkSetParam(type, name);
@ -363,7 +401,7 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Clear a parameter from this material. The param must exist
* Clear a parameter from this material. The parameter must exist
* @param name the name of the parameter to clear
*/
public void clearParam(String name) {
@ -416,9 +454,18 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
sortingId = -1;
}
/**
* Set a texture parameter.
*
* @param name The name of the parameter
* @param type The variable type {@link VarType}
* @param value The texture value of the parameter.
*
* @throws IllegalArgumentException is value is null
*/
public void setTextureParam(String name, VarType type, Texture value) {
if (value == null) {
throw new NullPointerException();
throw new IllegalArgumentException();
}
name = checkSetParam(type, name);
@ -438,8 +485,10 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a texture to the material shader
* @param name the name of the texture defined in the material definition (j3md) (for example Texture for Lighting.j3md)
* Pass a texture to the material shader.
*
* @param name the name of the texture defined in the material definition
* (j3md) (for example Texture for Lighting.j3md)
* @param value the Texture object previously loaded by the asset manager
*/
public void setTexture(String name, Texture value) {
@ -471,7 +520,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a Matrix4f to the material shader
* Pass a Matrix4f to the material shader.
*
* @param name the name of the matrix defined in the material definition (j3md)
* @param value the Matrix4f object
*/
@ -480,7 +530,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a boolean to the material shader
* Pass a boolean to the material shader.
*
* @param name the name of the boolean defined in the material definition (j3md)
* @param value the boolean value
*/
@ -489,7 +540,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a float to the material shader
* Pass a float to the material shader.
*
* @param name the name of the float defined in the material definition (j3md)
* @param value the float value
*/
@ -498,7 +550,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass an int to the material shader
* Pass an int to the material shader.
*
* @param name the name of the int defined in the material definition (j3md)
* @param value the int value
*/
@ -507,7 +560,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a Color to the material shader
* Pass a Color to the material shader.
*
* @param name the name of the color defined in the material definition (j3md)
* @param value the ColorRGBA value
*/
@ -516,7 +570,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a Vector2f to the material shader
* Pass a Vector2f to the material shader.
*
* @param name the name of the Vector2f defined in the material definition (j3md)
* @param value the Vector2f value
*/
@ -525,7 +580,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a Vector3f to the material shader
* Pass a Vector3f to the material shader.
*
* @param name the name of the Vector3f defined in the material definition (j3md)
* @param value the Vector3f value
*/
@ -534,7 +590,8 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Pass a Vector4f to the material shader
* Pass a Vector4f to the material shader.
*
* @param name the name of the Vector4f defined in the material definition (j3md)
* @param value the Vector4f value
*/
@ -567,9 +624,6 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
* // or the direction of the light (for directional lights).<br/>
* // g_LightPosition.w is the inverse radius (1/r) of the light (for attenuation) <br/>
* </p>
*
* @param shader
* @param lightList
*/
protected void updateLightListUniforms(Shader shader, Geometry g, int numLights) {
if (numLights == 0){ // this shader does not do lighting, ignore.
@ -719,6 +773,29 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
}
/**
* Select the technique to use for rendering this material.
* <p>
* If <code>name</code> is "Default", then one of the
* {@link MaterialDef#getDefaultTechniques() default techniques}
* on the material will be selected. Otherwise, the named technique
* will be found in the material definition.
* <p>
* Any candidate technique for selection (either default or named)
* must be verified to be compatible with the system, for that, the
* <code>renderManager</code> is queried for capabilities.
*
* @param name The name of the technique to select, pass "Default" to
* select one of the default techniques.
* @param renderManager The {@link RenderManager render manager}
* to query for capabilities.
*
* @throws IllegalArgumentException If "Default" is passed and no default
* techniques are available on the material definition, or if a name
* is passed but there's no technique by that name.
* @throws UnsupportedOperationException If no candidate technique supports
* the system capabilities.
*/
public void selectTechnique(String name, RenderManager renderManager) {
// check if already created
Technique tech = techniques.get(name);
@ -730,7 +807,7 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
if (name.equals("Default")) {
List<TechniqueDef> techDefs = def.getDefaultTechniques();
if (techDefs == null || techDefs.isEmpty()) {
throw new IllegalStateException("No default techniques are available on material '" + def.getName() + "'");
throw new IllegalArgumentException("No default techniques are available on material '" + def.getName() + "'");
}
TechniqueDef lastTech = null;
@ -794,8 +871,13 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* "Pre-load" the material, including textures and shaders, to the
* renderer.
* Preloads this material for the given render manager.
* <p>
* Preloading the material can ensure that when the material is first
* used for rendering, there won't be any delay since the material has
* been already been setup for rendering.
*
* @param rm The render manager to preload for
*/
public void preload(RenderManager rm) {
autoSelectTechnique(rm);
@ -844,9 +926,11 @@ public class Material implements Cloneable, Savable, Comparable<Material> {
}
/**
* Should be called after selectTechnique()
* @param geom
* @param r
* Called by {@link RenderManager} to render the geometry by
* using this material.
*
* @param geom The geometry to render
* @param rm The render manager requesting the rendering
*/
public void render(Geometry geom, RenderManager rm) {
autoSelectTechnique(rm);

@ -176,6 +176,15 @@ public class Technique implements Savable {
updateUniformParam(paramName, type, value, false);
}
/**
* Returns true if the technique must be reloaded.
* <p>
* If a technique needs to reload, then the {@link Material} should
* call {@link #makeCurrent(com.jme3.asset.AssetManager) } on this
* technique.
*
* @return true if the technique must be reloaded.
*/
public boolean isNeedReload() {
return needReload;
}
@ -183,8 +192,10 @@ public class Technique implements Savable {
/**
* Prepares the technique for use by loading the shader and setting
* the proper defines based on material parameters.
*
* @param assetManager The asset manager to use for loading shaders.
*/
public void makeCurrent(AssetManager manager) {
public void makeCurrent(AssetManager assetManager) {
// check if reload is needed..
if (def.isUsingShaders()) {
DefineList newDefines = new DefineList();
@ -203,7 +214,7 @@ public class Technique implements Savable {
defines.clear();
defines.addFrom(newDefines);
// defines changed, recompile needed
loadShader(manager);
loadShader(assetManager);
}
}
}
@ -214,8 +225,8 @@ public class Technique implements Savable {
allDefines.addFrom(def.getShaderPresetDefines());
allDefines.addFrom(defines);
ShaderKey key = new ShaderKey(def.getVertName(),
def.getFragName(),
ShaderKey key = new ShaderKey(def.getVertexShaderName(),
def.getFragmentShaderName(),
allDefines,
def.getShaderLanguage());
shader = manager.loadShader(key);

@ -38,6 +38,7 @@ import com.jme3.export.InputCapsule;
import com.jme3.export.OutputCapsule;
import com.jme3.export.Savable;
import com.jme3.renderer.Caps;
import com.jme3.renderer.Renderer;
import com.jme3.shader.DefineList;
import com.jme3.shader.UniformBinding;
import com.jme3.shader.VarType;
@ -47,12 +48,49 @@ import java.util.EnumSet;
import java.util.HashMap;
import java.util.List;
/**
* Describes a technique definition.
*
* @author Kirill Vainer
*/
public class TechniqueDef implements Savable {
/**
* Describes light rendering mode.
*/
public enum LightMode {
/**
* Disable light-based rendering
*/
Disable,
/**
* Enable light rendering by using a single pass.
* <p>
* An array of light positions and light colors is passed to the shader
* containing the world light list for the geometry being rendered.
*/
SinglePass,
/**
* Enable light rendering by using multi-pass rendering.
* <p>
* The geometry will be rendered once for each light. Each time the
* light position and light color uniforms are updated to contain
* the values for the current light. The ambient light color uniform
* is only set to the ambient light color on the first pass, future
* passes have it set to black.
*/
MultiPass,
/**
* Enable light rendering by using the
* {@link Renderer#setLighting(com.jme3.light.LightList) renderer's setLighting}
* method.
* <p>
* The specific details of rendering the lighting is up to the
* renderer implementation.
*/
FixedPipeline,
}
@ -78,97 +116,140 @@ public class TechniqueDef implements Savable {
private HashMap<String, String> defineParams;
private ArrayList<UniformBinding> worldBinds;
/**
* Creates a new technique definition.
* <p>
* Used internally by the J3M/J3MD loader.
*
* @param name The name of the technique, should be set to <code>null</code>
* for default techniques.
*/
public TechniqueDef(String name){
this.name = name == null ? "Default" : name;
}
/**
* Do not use this constructor.
* Serialization only. Do not use.
*/
public TechniqueDef(){
}
public void write(JmeExporter ex) throws IOException{
OutputCapsule oc = ex.getCapsule(this);
oc.write(name, "name", null);
oc.write(vertName, "vertName", null);
oc.write(fragName, "fragName", null);
oc.write(shaderLang, "shaderLang", null);
oc.write(presetDefines, "presetDefines", null);
oc.write(lightMode, "lightMode", LightMode.Disable);
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
oc.write(renderState, "renderState", null);
oc.write(usesShaders, "usesShaders", false);
// TODO: Finish this when Map<String, String> export is available
// oc.write(defineParams, "defineParams", null);
// TODO: Finish this when List<Enum> export is available
// oc.write(worldBinds, "worldBinds", null);
}
public void read(JmeImporter im) throws IOException{
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", null);
vertName = ic.readString("vertName", null);
fragName = ic.readString("fragName", null);
shaderLang = ic.readString("shaderLang", null);
presetDefines = (DefineList) ic.readSavable("presetDefines", null);
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
renderState = (RenderState) ic.readSavable("renderState", null);
usesShaders = ic.readBoolean("usesShaders", false);
}
/**
* Returns the name of this technique as specified in the J3MD file.
* Default techniques have the name "Default".
*
* @return the name of this technique
*/
public String getName(){
return name;
}
/**
* Returns the light mode.
* @return the light mode.
* @see LightMode
*/
public LightMode getLightMode() {
return lightMode;
}
/**
* Set the light mode
*
* @param lightMode the light mode
*
* @see LightMode
*/
public void setLightMode(LightMode lightMode) {
this.lightMode = lightMode;
}
/**
* Returns the shadow mode.
* @return the shadow mode.
*/
public ShadowMode getShadowMode() {
return shadowMode;
}
/**
* Set the shadow mode.
*
* @param shadowMode the shadow mode.
*
* @see ShadowMode
*/
public void setShadowMode(ShadowMode shadowMode) {
this.shadowMode = shadowMode;
}
/**
* Returns the render state that this technique is using
* @return the render state that this technique is using
* @see #setRenderState(com.jme3.material.RenderState)
*/
public RenderState getRenderState() {
return renderState;
}
/**
* Sets the render state that this technique is using.
*
* @param renderState the render state that this technique is using.
*
* @see RenderState
*/
public void setRenderState(RenderState renderState) {
this.renderState = renderState;
}
/**
* Returns true if this technique uses shaders, false otherwise.
*
* @return true if this technique uses shaders, false otherwise.
*
* @see #setShaderFile(java.lang.String, java.lang.String, java.lang.String)
*/
public boolean isUsingShaders(){
return usesShaders;
}
/**
* Gets the {@link Caps renderer capabilities} that are required
* by this technique.
*
* @return the required renderer capabilities
*/
public EnumSet<Caps> getRequiredCaps() {
return requiredCaps;
}
public void setShaderFile(String vert, String frag, String lang){
this.vertName = vert;
this.fragName = frag;
this.shaderLang = lang;
/**
* Sets the shaders that this technique definition will use.
*
* @param vertexShader The name of the vertex shader
* @param fragmentShader The name of the fragment shader
* @param shaderLanguage The shader language
*/
public void setShaderFile(String vertexShader, String fragmentShader, String shaderLanguage){
this.vertName = vertexShader;
this.fragName = fragmentShader;
this.shaderLang = shaderLanguage;
Caps langCap = Caps.valueOf(lang);
Caps langCap = Caps.valueOf(shaderLanguage);
requiredCaps.add(langCap);
usesShaders = true;
}
public DefineList getShaderPresetDefines() {
return presetDefines;
}
/**
* Returns the define name which the given material parameter influences.
*
* @param paramName The parameter name to look up
* @return The define name
*
* @see #addShaderParamDefine(java.lang.String, java.lang.String)
*/
public String getShaderParamDefine(String paramName){
if (defineParams == null)
return null;
@ -176,6 +257,18 @@ public class TechniqueDef implements Savable {
return defineParams.get(paramName);
}
/**
* Adds a define linked to a material parameter.
* <p>
* Any time the material parameter on the parent material is altered,
* the appropriate define on the technique will be modified as well.
* See the method
* {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) }
* on the exact details of how the material parameter changes the define.
*
* @param paramName The name of the material parameter to link to.
* @param defineName The name of the define parameter, e.g. USE_LIGHTING
*/
public void addShaderParamDefine(String paramName, String defineName){
if (defineParams == null)
defineParams = new HashMap<String, String>();
@ -183,6 +276,30 @@ public class TechniqueDef implements Savable {
defineParams.put(paramName, defineName);
}
/**
* Returns the {@link DefineList} for the preset defines.
*
* @return the {@link DefineList} for the preset defines.
*
* @see #addShaderPresetDefine(java.lang.String, com.jme3.shader.VarType, java.lang.Object)
*/
public DefineList getShaderPresetDefines() {
return presetDefines;
}
/**
* Adds a preset define.
* <p>
* Preset defines do not depend upon any parameters to be activated,
* they are always passed to the shader as long as this technique is used.
*
* @param defineName The name of the define parameter, e.g. USE_LIGHTING
* @param type The type of the define. See
* {@link DefineList#set(java.lang.String, com.jme3.shader.VarType, java.lang.Object) }
* to see why it matters.
*
* @param value The value of the define
*/
public void addShaderPresetDefine(String defineName, VarType type, Object value){
if (presetDefines == null)
presetDefines = new DefineList();
@ -190,33 +307,94 @@ public class TechniqueDef implements Savable {
presetDefines.set(defineName, type, value);
}
public String getFragName() {
/**
* Returns the name of the fragment shader used by the technique, or null
* if no fragment shader is specified.
*
* @return the name of the fragment shader to be used.
*/
public String getFragmentShaderName() {
return fragName;
}
public String getVertName() {
/**
* Returns the name of the vertex shader used by the technique, or null
* if no vertex shader is specified.
*
* @return the name of the vertex shader to be used.
*/
public String getVertexShaderName() {
return vertName;
}
/**
* Returns the shader language of the shaders used in this technique.
*
* @return the shader language of the shaders used in this technique.
*/
public String getShaderLanguage() {
return shaderLang;
}
/**
* Adds a new world parameter by the given name.
*
* @param name The world parameter to add.
* @return True if the world parameter name was found and added
* to the list of world parameters, false otherwise.
*/
public boolean addWorldParam(String name) {
if (worldBinds == null){
worldBinds = new ArrayList<UniformBinding>();
}
for (UniformBinding binding : UniformBinding.values()) {
if (binding.name().equals(name)) {
worldBinds.add(binding);
try {
worldBinds.add( UniformBinding.valueOf(name) );
return true;
}
}
} catch (IllegalArgumentException ex){
return false;
}
}
/**
* Returns a list of world parameters that are used by this
* technique definition.
*
* @return The list of world parameters
*/
public List<UniformBinding> getWorldBindings() {
return worldBinds;
}
public void write(JmeExporter ex) throws IOException{
OutputCapsule oc = ex.getCapsule(this);
oc.write(name, "name", null);
oc.write(vertName, "vertName", null);
oc.write(fragName, "fragName", null);
oc.write(shaderLang, "shaderLang", null);
oc.write(presetDefines, "presetDefines", null);
oc.write(lightMode, "lightMode", LightMode.Disable);
oc.write(shadowMode, "shadowMode", ShadowMode.Disable);
oc.write(renderState, "renderState", null);
oc.write(usesShaders, "usesShaders", false);
// TODO: Finish this when Map<String, String> export is available
// oc.write(defineParams, "defineParams", null);
// TODO: Finish this when List<Enum> export is available
// oc.write(worldBinds, "worldBinds", null);
}
public void read(JmeImporter im) throws IOException{
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", null);
vertName = ic.readString("vertName", null);
fragName = ic.readString("fragName", null);
shaderLang = ic.readString("shaderLang", null);
presetDefines = (DefineList) ic.readSavable("presetDefines", null);
lightMode = ic.readEnum("lightMode", LightMode.class, LightMode.Disable);
shadowMode = ic.readEnum("shadowMode", ShadowMode.class, ShadowMode.Disable);
renderState = (RenderState) ic.readSavable("renderState", null);
usesShaders = ic.readBoolean("usesShaders", false);
}
}

@ -9,7 +9,7 @@
The <code>com.jme3.material</code> package contains classes for manipulating
jMonkeyEngine materials.
Materials are applied to {@link com.jme3.scene.Geoemtry geometries} in the
Materials are applied to {@link com.jme3.scene.Geometry geometries} in the
scene.
Each geometry has a single material which is used to render that
geometry.

@ -1197,8 +1197,7 @@ public final class Matrix4f implements Savable, Cloneable {
*
* @param vec
* vec to multiply against.
* @param store
* a vector to store the result in. created if null is passed.
*
* @return the rotated vector.
*/
public Vector4f multAcross(Vector4f vec) {

@ -455,7 +455,8 @@ public final class Ray implements Savable, Cloneable, Collidable {
* <code>getLimit</code> returns the limit or the ray, aka the length.
* If the limit is not infinity, then this ray is a line with length <code>
* limit</code>.
* @return
*
* @return the limit or the ray, aka the length.
*/
public float getLimit(){
return limit;

@ -277,7 +277,6 @@ public class Spline implements Savable {
/**
* returns the curve tension
* @return
*/
public float getCurveTension() {
return curveTension;
@ -297,7 +296,6 @@ public class Spline implements Savable {
/**
* returns true if the spline cycle
* @return
*/
public boolean isCycle() {
return cycle;
@ -326,7 +324,6 @@ public class Spline implements Savable {
/**
* return the total lenght of the spline
* @return
*/
public float getTotalLength() {
return totalLength;
@ -334,7 +331,6 @@ public class Spline implements Savable {
/**
* return the type of the spline
* @return
*/
public SplineType getType() {
return type;
@ -351,7 +347,6 @@ public class Spline implements Savable {
/**
* returns this spline control points
* @return
*/
public List<Vector3f> getControlPoints() {
return controlPoints;
@ -359,7 +354,6 @@ public class Spline implements Savable {
/**
* returns a list of float representing the segments lenght
* @return
*/
public List<Float> getSegmentsLength() {
return segmentsLength;

@ -29,7 +29,6 @@
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package com.jme3.math;
import com.jme3.export.JmeExporter;
@ -50,15 +49,13 @@ public class Triangle extends AbstractTriangle implements Savable {
private Vector3f pointa = new Vector3f();
private Vector3f pointb = new Vector3f();
private Vector3f pointc = new Vector3f();
private transient Vector3f center;
private transient Vector3f normal;
private float projection;
private int index;
public Triangle() {}
public Triangle() {
}
/**
* Constructor instantiates a new <Code>Triangle</code> object with the
@ -84,22 +81,26 @@ public class Triangle extends AbstractTriangle implements Savable {
*/
public Vector3f get(int i) {
switch (i) {
case 0: return pointa;
case 1: return pointb;
case 2: return pointc;
default: return null;
case 0:
return pointa;
case 1:
return pointb;
case 2:
return pointc;
default:
return null;
}
}
public Vector3f get1(){
public Vector3f get1() {
return pointa;
}
public Vector3f get2(){
public Vector3f get2() {
return pointb;
}
public Vector3f get3(){
public Vector3f get3() {
return pointc;
}
@ -112,9 +113,15 @@ public class Triangle extends AbstractTriangle implements Savable {
*/
public void set(int i, Vector3f point) {
switch (i) {
case 0: pointa.set(point); break;
case 1: pointb.set(point); break;
case 2: pointc.set(point); break;
case 0:
pointa.set(point);
break;
case 1:
pointb.set(point);
break;
case 2:
pointc.set(point);
break;
}
}
@ -123,29 +130,34 @@ public class Triangle extends AbstractTriangle implements Savable {
* <code>set</code> sets one of the triangles points to that specified as
* a parameter.
* @param i the index to place the point.
* @param point the point to set.
*/
public void set(int i, float x, float y, float z) {
switch (i) {
case 0: pointa.set(x,y,z); break;
case 1: pointb.set(x,y,z); break;
case 2: pointc.set(x,y,z); break;
case 0:
pointa.set(x, y, z);
break;
case 1:
pointb.set(x, y, z);
break;
case 2:
pointc.set(x, y, z);
break;
}
}
public void set1(Vector3f v){
public void set1(Vector3f v) {
pointa.set(v);
}
public void set2(Vector3f v){
public void set2(Vector3f v) {
pointb.set(v);
}
public void set3(Vector3f v){
public void set3(Vector3f v) {
pointc.set(v);
}
public void set(Vector3f v1, Vector3f v2, Vector3f v3){
public void set(Vector3f v1, Vector3f v2, Vector3f v3) {
pointa.set(v1);
pointb.set(v2);
pointc.set(v3);
@ -156,9 +168,11 @@ public class Triangle extends AbstractTriangle implements Savable {
*
*/
public void calculateCenter() {
if (center == null)
if (center == null) {
center = new Vector3f(pointa);
else center.set(pointa);
} else {
center.set(pointa);
}
center.addLocal(pointb).addLocal(pointc).multLocal(FastMath.ONE_THIRD);
}
@ -167,10 +181,12 @@ public class Triangle extends AbstractTriangle implements Savable {
*
*/
public void calculateNormal() {
if (normal == null)
if (normal == null) {
normal = new Vector3f(pointb);
else normal.set(pointb);
normal.subtractLocal(pointa).crossLocal(pointc.x-pointa.x, pointc.y-pointa.y, pointc.z-pointa.z);
} else {
normal.set(pointb);
}
normal.subtractLocal(pointa).crossLocal(pointc.x - pointa.x, pointc.y - pointa.y, pointc.z - pointa.z);
normal.normalizeLocal();
}
@ -179,7 +195,7 @@ public class Triangle extends AbstractTriangle implements Savable {
* @return the center point.
*/
public Vector3f getCenter() {
if(center == null) {
if (center == null) {
calculateCenter();
}
return center;
@ -200,7 +216,7 @@ public class Triangle extends AbstractTriangle implements Savable {
* @return the normal vector
*/
public Vector3f getNormal() {
if(normal == null) {
if (normal == null) {
calculateNormal();
}
return normal;
@ -246,13 +262,14 @@ public class Triangle extends AbstractTriangle implements Savable {
this.index = index;
}
public static Vector3f computeTriangleNormal(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f store){
if (store == null)
public static Vector3f computeTriangleNormal(Vector3f v1, Vector3f v2, Vector3f v3, Vector3f store) {
if (store == null) {
store = new Vector3f(v2);
else
} else {
store.set(v2);
}
store.subtractLocal(v1).crossLocal(v3.x-v1.x, v3.y-v1.y, v3.z-v1.z);
store.subtractLocal(v1).crossLocal(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z);
return store.normalizeLocal();
}
@ -263,9 +280,9 @@ public class Triangle extends AbstractTriangle implements Savable {
}
public void read(JmeImporter e) throws IOException {
pointa = (Vector3f)e.getCapsule(this).readSavable("pointa", Vector3f.ZERO.clone());
pointb = (Vector3f)e.getCapsule(this).readSavable("pointb", Vector3f.ZERO.clone());
pointc = (Vector3f)e.getCapsule(this).readSavable("pointc", Vector3f.ZERO.clone());
pointa = (Vector3f) e.getCapsule(this).readSavable("pointa", Vector3f.ZERO.clone());
pointb = (Vector3f) e.getCapsule(this).readSavable("pointb", Vector3f.ZERO.clone());
pointc = (Vector3f) e.getCapsule(this).readSavable("pointc", Vector3f.ZERO.clone());
}
@Override

@ -320,7 +320,8 @@ public final class Vector2f implements Savable, Cloneable {
* <code>distanceSquared</code> calculates the distance squared between
* this vector and vector v.
*
* @param v the second vector to determine the distance squared.
* @param otherX The X coordinate of the v vector
* @param otherY The Y coordinate of the v vector
* @return the distance squared between the two vectors.
*/
public float distanceSquared(float otherX, float otherY) {

@ -677,7 +677,7 @@ public final class Vector4f implements Savable, Cloneable {
* the y value to subtract.
* @param subtractZ
* the z value to subtract.
* @param subtract@
* @param subtractW
* the w value to subtract.
* @return this
*/

@ -189,9 +189,10 @@ public abstract class Filter implements Savable {
public abstract void cleanUpFilter(Renderer r);
/**
* this method should return the material used for this filter.
* this method is called every frames
* @return
* Returns the material used for this filter.
* this method is called every frame.
*
* @return the material used for this filter.
*/
public abstract Material getMaterial();
@ -232,16 +233,14 @@ public abstract class Filter implements Savable {
}
/**
* Override this method if you want to load extra properties when the filter is loaded else only basic properties of the filter will be loaded
* This method should always begin by super.read(ex);
* @param ex
* @throws IOException
* Override this method if you want to load extra properties when the filter
* is loaded else only basic properties of the filter will be loaded
* This method should always begin by super.read(im);
*/
public void read(JmeImporter im) throws IOException {
InputCapsule ic = im.getCapsule(this);
name = ic.readString("name", "");
enabled = ic.readBoolean("enabled", true);
}
public String getName() {
@ -269,8 +268,9 @@ public abstract class Filter implements Savable {
}
/**
* Override this method and retrun true if your Filter need the depth texture
* @return
* Override this method and return true if your Filter need the depth texture
*
* @return true if your Filter need the depth texture
*/
public boolean isRequiresDepthTexture() {
return false;
@ -278,7 +278,8 @@ public abstract class Filter implements Savable {
/**
* Override this method and return false if your Filter does not need the scene texture
* @return
*
* @return false if your Filter does not need the scene texture
*/
public boolean isRequiresSceneTexture() {
return true;

@ -599,7 +599,6 @@ public class Camera implements Savable, Cloneable {
* <code>setLocation</code> sets the position of the camera.
*
* @param location the position of the camera.
* @see Camera#setLocation(com.jme.math.Vector3f)
*/
public void setLocation(Vector3f location) {
this.location.set(location);
@ -660,7 +659,8 @@ public class Camera implements Savable, Cloneable {
* @param left the left axis of the camera.
* @param up the up axis of the camera.
* @param direction the direction the camera is facing.
* @see Camera#setAxes(com.jme.math.Vector3f,com.jme.math.Vector3f,com.jme.math.Vector3f)
*
* @see Camera#setAxes(com.jme3.math.Quaternion)
*/
public void setAxes(Vector3f left, Vector3f up, Vector3f direction) {
this.rotation.fromAxes(left, up, direction);

@ -154,9 +154,8 @@ public abstract class GLObject implements Cloneable {
/**
* This should create a deep clone. For a shallow clone, use
* createDestructableClone().
*
* @return
*/
@Override
protected GLObject clone(){
try{
GLObject obj = (GLObject) super.clone();

@ -181,9 +181,6 @@ public class RenderManager {
/**
* Creates a new viewport, to display the given camera's content.
* The view will be processed before the primary viewport.
* @param viewName
* @param cam
* @return
*/
public ViewPort createPreView(String viewName, Camera cam) {
ViewPort vp = new ViewPort(viewName, cam);
@ -491,9 +488,6 @@ public class RenderManager {
/**
* Render scene graph
* @param s
* @param r
* @param cam
*/
public void renderScene(Spatial scene, ViewPort vp) {
if (scene.getParent() == null) {

@ -99,7 +99,7 @@ public interface Renderer {
public void onFrame();
/**
* @param transform The world transform to use. This changes
* @param worldMatrix The world transform to use. This changes
* the world matrix given in the shader.
*/
public void setWorldMatrix(Matrix4f worldMatrix);
@ -171,7 +171,6 @@ public interface Renderer {
/**
* Deletes a texture from the GPU.
* @param tex
*/
public void deleteImage(Image image);

@ -70,10 +70,10 @@ public class GeometryList {
}
/**
* Adds a spatial to the list. List size is doubled if there is no room.
* Adds a geometry to the list. List size is doubled if there is no room.
*
* @param s
* The spatial to add.
* @param g
* The geometry to add.
*/
public void add(Geometry g) {
if (size == geometries.length) {

@ -177,7 +177,7 @@ public class Geometry extends Spatial {
* this geometry. The location of the geometry is based on the location of
* all this node's parents.
*
* @see com.jme.scene.Spatial#updateWorldBound()
* @see Spatial#updateWorldBound()
*/
@Override
protected void updateWorldBound() {
@ -282,7 +282,6 @@ public class Geometry extends Spatial {
* Exception: if the mesh is marked as being a software
* animated mesh, (bind pose is set) then the positions
* and normals are deep copied.
* @return
*/
@Override
public Geometry clone(boolean cloneMaterial){
@ -308,8 +307,8 @@ public class Geometry extends Spatial {
* Exception: if the mesh is marked as being a software
* animated mesh, (bind pose is set) then the positions
* and normals are deep copied.
* @return
*/
@Override
public Geometry clone(){
return clone(true);
}
@ -318,7 +317,6 @@ public class Geometry extends Spatial {
* Creates a deep clone of the geometry,
* this creates an identical copy of the mesh
* with the vertexbuffer data duplicated.
* @return
*/
@Override
public Spatial deepClone(){

@ -526,7 +526,7 @@ public class Node extends Spatial implements Savable {
* @return Non-null, but possibly 0-element, list of matching Spatials (also Instances extending Spatials).
*
* @see java.util.regex.Pattern
* @see Spatial#matches(Class<? extends Spatial>, String)
* @see Spatial#matches(java.lang.Class, java.lang.String)
*/
@SuppressWarnings("unchecked")
public <T extends Spatial>List<T> descendantMatches(
@ -546,7 +546,7 @@ public class Node extends Spatial implements Savable {
/**
* Convenience wrapper.
*
* @see #descendantMatches(Class<? extends Spatial>, String)
* @see #descendantMatches(java.lang.Class, java.lang.String)
*/
public <T extends Spatial>List<T> descendantMatches(
Class<T> spatialSubclass) {
@ -556,7 +556,7 @@ public class Node extends Spatial implements Savable {
/**
* Convenience wrapper.
*
* @see #descendantMatches(Class<? extends Spatial>, String)
* @see #descendantMatches(java.lang.Class, java.lang.String)
*/
public <T extends Spatial>List<T> descendantMatches(String nameRegex) {
return descendantMatches(null, nameRegex);

@ -784,9 +784,6 @@ public abstract class Spatial implements Savable, Cloneable, Collidable {
/**
* <code>setLocalScale</code> sets the local scale of this node.
*
* @param localScale
* the new local scale
*/
public void setLocalScale(float x, float y, float z) {
localTransform.setScale(x, y, z);

@ -664,11 +664,6 @@ public class VertexBuffer extends GLObject implements Savable, Cloneable {
* of the parameters. The buffer will be of the type specified by
* {@link Format format} and would be able to contain the given number
* of elements with the given number of components in each element.
*
* @param format
* @param components
* @param numElements
* @return
*/
public static Buffer createBuffer(Format format, int components, int numElements){
if (components < 1 || components > 4)

@ -48,7 +48,7 @@ public interface Control extends Savable {
* Creates a clone of the Control, the given Spatial is the cloned
* version of the spatial to which this control is attached to.
* @param spatial
* @return
* @return A clone of this control for the spatial
*/
public Control cloneForSpatial(Spatial spatial);

@ -76,14 +76,14 @@ public class LightControl extends AbstractControl {
}
/**
* @param camera The Camera to be synced.
* @param light The light to be synced.
*/
public LightControl(Light light) {
this.light = light;
}
/**
* @param camera The Camera to be synced.
* @param light The light to be synced.
*/
public LightControl(Light light, ControlDirection controlDir) {
this.light = light;

@ -380,7 +380,6 @@ public final class Shader extends GLObject implements Savable {
/**
* Returns true if this program and all it's shaders have been compiled,
* linked and validated successfuly.
* @return
*/
public boolean isUsable(){
return usable;
@ -417,7 +416,6 @@ public final class Shader extends GLObject implements Savable {
/**
* Called by the object manager to reset all object IDs. This causes
* the shader to be reuploaded to the GPU incase the display was restarted.
* @param r
*/
@Override
public void resetObject() {

@ -37,6 +37,7 @@ import com.jme3.input.KeyInput;
import com.jme3.input.MouseInput;
import com.jme3.input.TouchInput;
import com.jme3.renderer.Renderer;
import com.jme3.system.JmeCanvasContext;
/**
* Represents a rendering context within the engine.

Loading…
Cancel
Save