diff --git a/engine/src/blender/com/jme3/asset/BlenderKey.java b/engine/src/blender/com/jme3/asset/BlenderKey.java index da4c26301..bb85950cb 100644 --- a/engine/src/blender/com/jme3/asset/BlenderKey.java +++ b/engine/src/blender/com/jme3/asset/BlenderKey.java @@ -273,6 +273,10 @@ public class BlenderKey extends ModelKey { public void excludeFromLoading(int featuresNotToLoad) { featuresToLoad &= ~featuresNotToLoad; } + + public boolean shouldLoad(int featureToLoad) { + return (featuresToLoad & featureToLoad) != 0; + } /** * This method returns bitwise value of FeaturesToLoad interface value. It describes features that will be loaded by diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java deleted file mode 100644 index 8b68e76ae..000000000 --- a/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java +++ /dev/null @@ -1,166 +0,0 @@ -/* - * Copyright (c) 2009-2012 jMonkeyEngine - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are - * met: - * - * * Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * * Neither the name of 'jMonkeyEngine' nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * 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.scene.plugins.blender; - -import java.util.List; -import java.util.logging.Level; -import java.util.logging.Logger; - -import com.jme3.asset.AssetLoader; -import com.jme3.asset.BlenderKey.FeaturesToLoad; -import com.jme3.scene.CameraNode; -import com.jme3.scene.Geometry; -import com.jme3.scene.LightNode; -import com.jme3.scene.Node; -import com.jme3.scene.Spatial; -import com.jme3.scene.plugins.blender.cameras.CameraHelper; -import com.jme3.scene.plugins.blender.file.BlenderFileException; -import com.jme3.scene.plugins.blender.file.Pointer; -import com.jme3.scene.plugins.blender.file.Structure; -import com.jme3.scene.plugins.blender.lights.LightHelper; -import com.jme3.scene.plugins.blender.meshes.MeshHelper; -import com.jme3.scene.plugins.blender.objects.ObjectHelper; - -/** - * This class converts blender file blocks into jMonkeyEngine data structures. - * @author Marcin Roguski (Kaelthas) - */ -/* package */abstract class AbstractBlenderLoader implements AssetLoader { - private static final Logger LOGGER = Logger.getLogger(AbstractBlenderLoader.class.getName()); - - protected BlenderContext blenderContext; - - /** - * This method converts the given structure to a scene node. - * @param structure - * structure of a scene - * @return scene's node - */ - public Node toScene(Structure structure) { - if ((blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.SCENES) == 0) { - return null; - } - Node result = new Node(structure.getName()); - try { - List base = ((Structure) structure.getFieldValue("base")).evaluateListBase(blenderContext); - for (Structure b : base) { - Pointer pObject = (Pointer) b.getFieldValue("object"); - if (pObject.isNotNull()) { - Structure objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0); - Object object = this.toObject(objectStructure); - if (object instanceof LightNode && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) { - result.addLight(((LightNode) object).getLight()); - result.attachChild((LightNode) object); - } else if (object instanceof Node && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) { - LOGGER.log(Level.FINE, "{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) { - result.attachChild((Spatial) object); - } - } - } - } - } catch (BlenderFileException e) { - LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e); - } - return result; - } - - /** - * This method converts the given structure to a camera. - * @param structure - * structure of a camera - * @return camera's node - */ - public CameraNode toCamera(Structure structure) throws BlenderFileException { - CameraHelper cameraHelper = blenderContext.getHelper(CameraHelper.class); - if (cameraHelper.shouldBeLoaded(structure, blenderContext)) { - return cameraHelper.toCamera(structure, blenderContext); - } - return null; - } - - /** - * This method converts the given structure to a light. - * @param structure - * structure of a light - * @return light's node - */ - public LightNode toLight(Structure structure) throws BlenderFileException { - LightHelper lightHelper = blenderContext.getHelper(LightHelper.class); - if (lightHelper.shouldBeLoaded(structure, blenderContext)) { - return lightHelper.toLight(structure, blenderContext); - } - return null; - } - - /** - * This method converts the given structure to a node. - * @param structure - * structure of an object - * @return object's node - */ - public Object toObject(Structure structure) throws BlenderFileException { - ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); - if (objectHelper.shouldBeLoaded(structure, blenderContext)) { - return objectHelper.toObject(structure, blenderContext); - } - return null; - } - - /** - * This method converts the given structure to a list of geometries. - * @param structure - * structure of a mesh - * @return list of geometries - */ - public List toMesh(Structure structure) throws BlenderFileException { - MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class); - if (meshHelper.shouldBeLoaded(structure, blenderContext)) { - return meshHelper.toMesh(structure, blenderContext); - } - return null; - } - - // /** - // * This method converts the given structure to a material. - // * @param structure - // * structure of a material - // * @return material's node - // */ - // public Material toMaterial(Structure structure) throws BlenderFileException { - // MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class); - // if (materialHelper.shouldBeLoaded(structure, blenderContext)) { - // return materialHelper.toMaterial(structure, blenderContext); - // } - // return null; - // } -} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java index 30a55601e..4ea9b020a 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java @@ -38,6 +38,7 @@ import java.util.logging.Level; import java.util.logging.Logger; import com.jme3.asset.AssetInfo; +import com.jme3.asset.AssetLoader; import com.jme3.asset.BlenderKey; import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.asset.BlenderKey.LoadingResults; @@ -54,6 +55,7 @@ import com.jme3.scene.plugins.blender.curves.CurvesHelper; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.BlenderInputStream; import com.jme3.scene.plugins.blender.file.FileBlockHeader; +import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.landscape.LandscapeHelper; import com.jme3.scene.plugins.blender.lights.LightHelper; @@ -68,12 +70,13 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper; * This is the main loading class. Have in notice that asset manager needs to have loaders for resources like textures. * @author Marcin Roguski (Kaelthas) */ -public class BlenderLoader extends AbstractBlenderLoader { - +public class BlenderLoader implements AssetLoader { private static final Logger LOGGER = Logger.getLogger(BlenderLoader.class.getName()); /** The blocks read from the file. */ protected List blocks; + /** The blender context. */ + protected BlenderContext blenderContext; public Spatial load(AssetInfo assetInfo) throws IOException { try { @@ -85,30 +88,35 @@ public class BlenderLoader extends AbstractBlenderLoader { for (FileBlockHeader block : blocks) { switch (block.getCode()) { case FileBlockHeader.BLOCK_OB00:// Object - Object object = this.toObject(block.getStructure(blenderContext)); - if (object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) { + ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); + Object object = objectHelper.toObject(block.getStructure(blenderContext), blenderContext); + if (object instanceof LightNode) { loadingResults.addLight((LightNode) object); - } else if (object instanceof CameraNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0) { + } else if (object instanceof CameraNode) { loadingResults.addCamera((CameraNode) object); - } else if (object instanceof Node && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) { - LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() }); + } else if (object instanceof Node) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() }); + } if (this.isRootObject(loadingResults, (Node) object)) { loadingResults.addObject((Node) object); } } break; - // case FileBlockHeader.BLOCK_MA00:// Material - // if (blenderKey.isLoadUnlinkedAssets() && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) { - // loadingResults.addMaterial(this.toMaterial(block.getStructure(blenderContext))); - // } - // break; +// case FileBlockHeader.BLOCK_MA00:// Material +// MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class); +// MaterialContext materialContext = materialHelper.toMaterialContext(block.getStructure(blenderContext), blenderContext); +// if (blenderKey.isLoadUnlinkedAssets() && blenderKey.shouldLoad(FeaturesToLoad.MATERIALS)) { +// loadingResults.addMaterial(this.toMaterial(block.getStructure(blenderContext))); +// } +// break; case FileBlockHeader.BLOCK_SC00:// Scene - if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) { + if (blenderKey.shouldLoad(FeaturesToLoad.SCENES)) { sceneBlocks.add(block); } break; case FileBlockHeader.BLOCK_WO00:// World - if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.WORLD) != 0) { + if (blenderKey.shouldLoad(FeaturesToLoad.WORLD)) { Structure worldStructure = block.getStructure(blenderContext); String worldName = worldStructure.getName(); if (blenderKey.getUsedWorld() == null || blenderKey.getUsedWorld().equals(worldName)) { @@ -162,6 +170,42 @@ public class BlenderLoader extends AbstractBlenderLoader { return false; } + /** + * This method converts the given structure to a scene node. + * @param structure + * structure of a scene + * @return scene's node + */ + private Node toScene(Structure structure) { + ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); + Node result = new Node(structure.getName()); + try { + List base = ((Structure) structure.getFieldValue("base")).evaluateListBase(blenderContext); + for (Structure b : base) { + Pointer pObject = (Pointer) b.getFieldValue("object"); + if (pObject.isNotNull()) { + Structure objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0); + + Object object = objectHelper.toObject(objectStructure, blenderContext); + if (object instanceof LightNode) { + result.addLight(((LightNode) object).getLight()); + result.attachChild((LightNode) object); + } else if (object instanceof Node) { + if (LOGGER.isLoggable(Level.FINE)) { + LOGGER.log(Level.FINE, "{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) { + result.attachChild((Spatial) object); + } + } + } + } + } catch (BlenderFileException e) { + LOGGER.log(Level.SEVERE, e.getLocalizedMessage(), e); + } + return result; + } + /** * This method sets up the loader. * @param assetInfo @@ -206,7 +250,7 @@ public class BlenderLoader extends AbstractBlenderLoader { blenderContext.putHelper(IpoHelper.class, new IpoHelper(inputStream.getVersionNumber(), blenderContext)); blenderContext.putHelper(ParticlesHelper.class, new ParticlesHelper(inputStream.getVersionNumber(), blenderContext)); blenderContext.putHelper(LandscapeHelper.class, new LandscapeHelper(inputStream.getVersionNumber(), blenderContext)); - + // reading the blocks (dna block is automatically saved in the blender context when found) FileBlockHeader sceneFileBlock = null; do { diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java index e4fe0974f..cb9b62bba 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderModelLoader.java @@ -44,10 +44,12 @@ import com.jme3.scene.Spatial; import com.jme3.scene.plugins.blender.constraints.ConstraintHelper; import com.jme3.scene.plugins.blender.file.BlenderFileException; import com.jme3.scene.plugins.blender.file.FileBlockHeader; +import com.jme3.scene.plugins.blender.objects.ObjectHelper; /** * This is the main loading class. Have in notice that asset manager needs to have loaders for resources like textures. - * @author Marcin Roguski + * + * @author Marcin Roguski (Kaelthas) */ public class BlenderModelLoader extends BlenderLoader { @@ -63,8 +65,8 @@ public class BlenderModelLoader extends BlenderLoader { for (FileBlockHeader block : blocks) { if (block.getCode() == FileBlockHeader.BLOCK_OB00) { - Object object = this.toObject(block.getStructure(blenderContext)); - + ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class); + Object object = objectHelper.toObject(block.getStructure(blenderContext), blenderContext); if (object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) { modelRoot.addLight(((LightNode) object).getLight()); modelRoot.attachChild((LightNode) object); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java index a6c869fd7..75f05a54f 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java @@ -44,7 +44,6 @@ import com.jme3.math.Transform; import com.jme3.math.Vector3f; import com.jme3.scene.Geometry; import com.jme3.scene.Node; -import com.jme3.scene.Spatial; import com.jme3.scene.Spatial.CullHint; import com.jme3.scene.plugins.blender.AbstractBlenderHelper; import com.jme3.scene.plugins.blender.BlenderContext; @@ -93,21 +92,36 @@ public class ObjectHelper extends AbstractBlenderHelper { * the object's structure * @param blenderContext * the blender context - * @return blener's object representation + * @return blener's object representation or null if its type is excluded from loading * @throws BlenderFileException * an exception is thrown when the given data is inapropriate */ public Object toObject(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException { + LOGGER.fine("Loading blender object."); + + int type = ((Number) objectStructure.getFieldValue("type")).intValue(); + ObjectType objectType = ObjectType.valueOf(type); + LOGGER.log(Level.FINE, "Type of the object: {0}.", objectType); + if(objectType == ObjectType.LAMP && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.LIGHTS)) { + LOGGER.fine("Lamps are not included in loading."); + return null; + } + if(objectType == ObjectType.CAMERA && !blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.CAMERAS)) { + LOGGER.fine("Cameras are not included in loading."); + return null; + } + if(!blenderContext.getBlenderKey().shouldLoad(FeaturesToLoad.OBJECTS)) { + LOGGER.fine("Objects are not included in loading."); + return null; + } + + LOGGER.fine("Checking if the object has not been already loaded."); Object loadedResult = blenderContext.getLoadedFeature(objectStructure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE); if (loadedResult != null) { return loadedResult; } blenderContext.pushParent(objectStructure); - - // get object data - int type = ((Number) objectStructure.getFieldValue("type")).intValue(); - ObjectType objectType = ObjectType.valueOf(type); String name = objectStructure.getName(); LOGGER.log(Level.FINE, "Loading obejct: {0}", name);