diff --git a/engine/src/blender/com/jme3/asset/BlenderKey.java b/engine/src/blender/com/jme3/asset/BlenderKey.java index bb85950cb..0ceabe305 100644 --- a/engine/src/blender/com/jme3/asset/BlenderKey.java +++ b/engine/src/blender/com/jme3/asset/BlenderKey.java @@ -114,7 +114,12 @@ public class BlenderKey extends ModelKey { /** The radius of a shape that will be used while creating the generated texture for the sky. The higher it is the larger part of the texture will be seen. */ protected float skyGeneratedTextureRadius = 1; /** The shape against which the generated texture for the sky will be created. */ - protected SkyGeneratedTextureShape skyGeneratedTextureShape = SkyGeneratedTextureShape.SPHERE; + protected SkyGeneratedTextureShape skyGeneratedTextureShape = SkyGeneratedTextureShape.SPHERE; + /** + * This field tells if the importer should optimise the use of textures or not. If set to true, then textures of the same mapping type will be merged together + * and textures that in the final result will never be visible - will be discarded. + */ + protected boolean optimiseTextures; /** * Constructor used by serialization mechanisms. @@ -273,7 +278,7 @@ public class BlenderKey extends ModelKey { public void excludeFromLoading(int featuresNotToLoad) { featuresToLoad &= ~featuresNotToLoad; } - + public boolean shouldLoad(int featureToLoad) { return (featuresToLoad & featureToLoad) != 0; } @@ -414,12 +419,29 @@ public class BlenderKey extends ModelKey { * the shape against which the generated texture for the sky will be created */ public void setSkyGeneratedTextureShape(SkyGeneratedTextureShape skyGeneratedTextureShape) { - if(skyGeneratedTextureShape == null) { + if (skyGeneratedTextureShape == null) { throw new IllegalArgumentException("The sky generated shape type cannot be null!"); } this.skyGeneratedTextureShape = skyGeneratedTextureShape; } + /** + * If set to true, then textures of the same mapping type will be merged together + * and textures that in the final result will never be visible - will be discarded. + * @param optimiseTextures + * the variable that tells if the textures should be optimised or not + */ + public void setOptimiseTextures(boolean optimiseTextures) { + this.optimiseTextures = optimiseTextures; + } + + /** + * @return the variable that tells if the textures should be optimised or not (by default the optimisation is disabled) + */ + public boolean isOptimiseTextures() { + return optimiseTextures; + } + /** * This mehtod sets the name of the WORLD data block taht should be used during file loading. By default the name is * not set. If no name is set or the given name does not occur in the file - the first WORLD data block will be used @@ -474,6 +496,7 @@ public class BlenderKey extends ModelKey { oc.write(skyGeneratedTextureSize, "sky-generated-texture-size", 1000); oc.write(skyGeneratedTextureRadius, "sky-generated-texture-radius", 1f); oc.write(skyGeneratedTextureShape, "sky-generated-texture-shape", SkyGeneratedTextureShape.SPHERE); + oc.write(optimiseTextures, "optimise-textures", false); } @Override @@ -494,6 +517,7 @@ public class BlenderKey extends ModelKey { skyGeneratedTextureSize = ic.readInt("sky-generated-texture-size", 1000); skyGeneratedTextureRadius = ic.readFloat("sky-generated-texture-radius", 1f); skyGeneratedTextureShape = ic.readEnum("sky-generated-texture-shape", SkyGeneratedTextureShape.class, SkyGeneratedTextureShape.SPHERE); + optimiseTextures = ic.readBoolean("optimise-textures", false); } @Override @@ -507,14 +531,15 @@ public class BlenderKey extends ModelKey { result = prime * result + (fixUpAxis ? 1231 : 1237); result = prime * result + fps; result = prime * result + generatedTexturePPU; - result = prime * result + (skyGeneratedTextureShape == null ? 0 : skyGeneratedTextureShape.hashCode()); result = prime * result + layersToLoad; result = prime * result + (loadGeneratedTextures ? 1231 : 1237); result = prime * result + (loadObjectProperties ? 1231 : 1237); result = prime * result + (loadUnlinkedAssets ? 1231 : 1237); result = prime * result + maxTextureSize; result = prime * result + (mipmapGenerationMethod == null ? 0 : mipmapGenerationMethod.hashCode()); + result = prime * result + (optimiseTextures ? 1231 : 1237); result = prime * result + Float.floatToIntBits(skyGeneratedTextureRadius); + result = prime * result + (skyGeneratedTextureShape == null ? 0 : skyGeneratedTextureShape.hashCode()); result = prime * result + skyGeneratedTextureSize; result = prime * result + (usedWorld == null ? 0 : usedWorld.hashCode()); return result; @@ -561,9 +586,6 @@ public class BlenderKey extends ModelKey { if (generatedTexturePPU != other.generatedTexturePPU) { return false; } - if (skyGeneratedTextureShape != other.skyGeneratedTextureShape) { - return false; - } if (layersToLoad != other.layersToLoad) { return false; } @@ -582,9 +604,15 @@ public class BlenderKey extends ModelKey { if (mipmapGenerationMethod != other.mipmapGenerationMethod) { return false; } + if (optimiseTextures != other.optimiseTextures) { + return false; + } if (Float.floatToIntBits(skyGeneratedTextureRadius) != Float.floatToIntBits(other.skyGeneratedTextureRadius)) { return false; } + if (skyGeneratedTextureShape != other.skyGeneratedTextureShape) { + return false; + } if (skyGeneratedTextureSize != other.skyGeneratedTextureSize) { return false; } @@ -598,6 +626,8 @@ public class BlenderKey extends ModelKey { return true; } + + /** * This enum tells the importer if the mipmaps for textures will be generated by jme.
  • NEVER_GENERATE and ALWAYS_GENERATE are quite understandable
  • GENERATE_WHEN_NEEDED is an option that checks if the texture had 'Generate mipmaps' option set in blender, mipmaps are generated only when the option is set * @author Marcin Roguski (Kaelthas) diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/landscape/LandscapeHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/landscape/LandscapeHelper.java index 6b8685c79..1be4c4475 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/landscape/LandscapeHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/landscape/LandscapeHelper.java @@ -2,7 +2,6 @@ package com.jme3.scene.plugins.blender.landscape; import java.util.ArrayList; import java.util.List; -import java.util.Map; import java.util.logging.Level; import java.util.logging.Logger; @@ -101,7 +100,7 @@ public class LandscapeHelper extends AbstractBlenderHelper { blenderContext.getBlenderKey().setLoadGeneratedTextures(true); TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class); - Map loadedTextures = null; + List loadedTextures = null; try { loadedTextures = textureHelper.readTextureData(worldStructure, new float[] { horizontalColor.r, horizontalColor.g, horizontalColor.b, horizontalColor.a }, true); } finally { @@ -113,7 +112,7 @@ public class LandscapeHelper extends AbstractBlenderHelper { if (loadedTextures.size() > 1) { throw new IllegalStateException("There should be only one combined texture for sky!"); } - CombinedTexture combinedTexture = loadedTextures.get(1); + CombinedTexture combinedTexture = loadedTextures.get(0); texture = combinedTexture.generateSkyTexture(horizontalColor, zenithColor, blenderContext); } else { LOGGER.fine("Preparing colors for colorband."); @@ -169,7 +168,7 @@ public class LandscapeHelper extends AbstractBlenderHelper { pixelIO.write(image, 3, pixel, x, y); } } - + LOGGER.fine("Creating bottom texture."); pixelIO.read(image, 0, pixel, 0, 0); for (int y = 0; y < size; ++y) { diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java index c56276b12..8132d038b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java @@ -2,7 +2,6 @@ package com.jme3.scene.plugins.blender.materials; import java.util.LinkedHashMap; import java.util.List; -import java.util.Map; import java.util.Map.Entry; import java.util.logging.Level; import java.util.logging.Logger; @@ -32,30 +31,30 @@ import com.jme3.util.BufferUtils; * @author Marcin Roguski (Kaelthas) */ public final class MaterialContext { - private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName()); + private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName()); // texture mapping types - public static final int MTEX_COL = 0x01; - public static final int MTEX_NOR = 0x02; - public static final int MTEX_SPEC = 0x04; - public static final int MTEX_EMIT = 0x40; - public static final int MTEX_ALPHA = 0x80; - public static final int MTEX_AMB = 0x800; + public static final int MTEX_COL = 0x01; + public static final int MTEX_NOR = 0x02; + public static final int MTEX_SPEC = 0x04; + public static final int MTEX_EMIT = 0x40; + public static final int MTEX_ALPHA = 0x80; + public static final int MTEX_AMB = 0x800; - /* package */final String name; - /* package */final Map loadedTextures; + /* package */final String name; + /* package */final List loadedTextures; - /* package */final ColorRGBA diffuseColor; - /* package */final DiffuseShader diffuseShader; - /* package */final SpecularShader specularShader; - /* package */final ColorRGBA specularColor; - /* package */final ColorRGBA ambientColor; - /* package */final float shininess; - /* package */final boolean shadeless; - /* package */final boolean vertexColor; - /* package */final boolean transparent; - /* package */final boolean vTangent; - /* package */FaceCullMode faceCullMode; + /* package */final ColorRGBA diffuseColor; + /* package */final DiffuseShader diffuseShader; + /* package */final SpecularShader specularShader; + /* package */final ColorRGBA specularColor; + /* package */final ColorRGBA ambientColor; + /* package */final float shininess; + /* package */final boolean shadeless; + /* package */final boolean vertexColor; + /* package */final boolean transparent; + /* package */final boolean vTangent; + /* package */FaceCullMode faceCullMode; /* package */MaterialContext(Structure structure, BlenderContext blenderContext) throws BlenderFileException { name = structure.getName(); @@ -68,7 +67,7 @@ public final class MaterialContext { int diff_shader = ((Number) structure.getFieldValue("diff_shader")).intValue(); diffuseShader = DiffuseShader.values()[diff_shader]; - if (this.shadeless) { + if (shadeless) { float r = ((Number) structure.getFieldValue("r")).floatValue(); float g = ((Number) structure.getFieldValue("g")).floatValue(); float b = ((Number) structure.getFieldValue("b")).floatValue(); @@ -84,9 +83,9 @@ public final class MaterialContext { int spec_shader = ((Number) structure.getFieldValue("spec_shader")).intValue(); specularShader = SpecularShader.values()[spec_shader]; specularColor = this.readSpecularColor(structure); - float shininess = ((Number) structure.getFieldValue("har")).floatValue();//this is (probably) the specular hardness in blender + float shininess = ((Number) structure.getFieldValue("har")).floatValue();// this is (probably) the specular hardness in blender this.shininess = shininess > 0.0f ? shininess : MaterialHelper.DEFAULT_SHININESS; - + float r = ((Number) structure.getFieldValue("ambr")).floatValue(); float g = ((Number) structure.getFieldValue("ambg")).floatValue(); float b = ((Number) structure.getFieldValue("ambb")).floatValue(); @@ -159,16 +158,15 @@ public final class MaterialContext { // applying textures if (loadedTextures != null && loadedTextures.size() > 0) { int textureIndex = 0; - if(loadedTextures.size() > TextureHelper.TEXCOORD_TYPES.length) { + if (loadedTextures.size() > TextureHelper.TEXCOORD_TYPES.length) { LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different textures. JME supports only {0} UV mappings.", TextureHelper.TEXCOORD_TYPES.length); } - for (Entry entry : loadedTextures.entrySet()) { - if(textureIndex < TextureHelper.TEXCOORD_TYPES.length) { - CombinedTexture combinedTexture = entry.getValue(); + for (CombinedTexture combinedTexture : loadedTextures) { + if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) { combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext); - this.setTexture(material, entry.getKey().intValue(), combinedTexture.getResultTexture()); - List uvs = entry.getValue().getResultUVS(); + this.setTexture(material, combinedTexture.getMappingType(), combinedTexture.getResultTexture()); + List uvs = combinedTexture.getResultUVS(); VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]); uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()]))); geometry.getMesh().setBuffer(uvCoordsBuffer); @@ -176,14 +174,14 @@ public final class MaterialContext { LOGGER.log(Level.WARNING, "The texture could not be applied because JME only supports up to {0} different UV's.", TextureHelper.TEXCOORD_TYPES.length); } } - } else if(userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) { + } else if (userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) { LOGGER.fine("No textures found for the mesh, but UV coordinates are applied."); int textureIndex = 0; - if(userDefinedUVCoordinates.size() > TextureHelper.TEXCOORD_TYPES.length) { + if (userDefinedUVCoordinates.size() > TextureHelper.TEXCOORD_TYPES.length) { LOGGER.log(Level.WARNING, "The blender file has defined more than {0} different UV coordinates for the mesh. JME supports only {0} UV coordinates buffers.", TextureHelper.TEXCOORD_TYPES.length); } - for(Entry> entry : userDefinedUVCoordinates.entrySet()) { - if(textureIndex < TextureHelper.TEXCOORD_TYPES.length) { + for (Entry> entry : userDefinedUVCoordinates.entrySet()) { + if (textureIndex < TextureHelper.TEXCOORD_TYPES.length) { List uvs = entry.getValue(); VertexBuffer uvCoordsBuffer = new VertexBuffer(TextureHelper.TEXCOORD_TYPES[textureIndex++]); uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()]))); @@ -253,8 +251,8 @@ public final class MaterialContext { */ public boolean hasGeneratedTextures() { if (loadedTextures != null) { - for (Entry entry : loadedTextures.entrySet()) { - if (entry.getValue().hasGeneratedTextures()) { + for (CombinedTexture generatedTextures : loadedTextures) { + if (generatedTextures.hasGeneratedTextures()) { return true; } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/CombinedTexture.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/CombinedTexture.java index 37a650255..344d65e31 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/CombinedTexture.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/CombinedTexture.java @@ -379,6 +379,13 @@ public class CombinedTexture { return textureDatas.size(); } + /** + * @return the texture's mapping type + */ + public int getMappingType() { + return mappingType; + } + /** * @return true if the texture has at least one generated texture component and false otherwise */ @@ -392,7 +399,7 @@ public class CombinedTexture { } return false; } - + /** * This method determines if the given texture has no alpha channel. * diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java index f6dafcb00..61a384ef7 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureHelper.java @@ -77,29 +77,29 @@ import com.jme3.util.BufferUtils; * @author Marcin Roguski */ public class TextureHelper extends AbstractBlenderHelper { - private static final Logger LOGGER = Logger.getLogger(TextureHelper.class.getName()); + private static final Logger LOGGER = Logger.getLogger(TextureHelper.class.getName()); // texture types - public static final int TEX_NONE = 0; - public static final int TEX_CLOUDS = 1; - public static final int TEX_WOOD = 2; - public static final int TEX_MARBLE = 3; - public static final int TEX_MAGIC = 4; - public static final int TEX_BLEND = 5; - public static final int TEX_STUCCI = 6; - public static final int TEX_NOISE = 7; - public static final int TEX_IMAGE = 8; - public static final int TEX_PLUGIN = 9; - public static final int TEX_ENVMAP = 10; - public static final int TEX_MUSGRAVE = 11; - public static final int TEX_VORONOI = 12; - public static final int TEX_DISTNOISE = 13; - public static final int TEX_POINTDENSITY = 14; // v. 25+ - public static final int TEX_VOXELDATA = 15; // v. 25+ - public static final int TEX_OCEAN = 16; // v. 26+ - - public static final Type[] TEXCOORD_TYPES = new Type[] { Type.TexCoord, Type.TexCoord2, Type.TexCoord3, Type.TexCoord4, Type.TexCoord5, Type.TexCoord6, Type.TexCoord7, Type.TexCoord8 }; - + public static final int TEX_NONE = 0; + public static final int TEX_CLOUDS = 1; + public static final int TEX_WOOD = 2; + public static final int TEX_MARBLE = 3; + public static final int TEX_MAGIC = 4; + public static final int TEX_BLEND = 5; + public static final int TEX_STUCCI = 6; + public static final int TEX_NOISE = 7; + public static final int TEX_IMAGE = 8; + public static final int TEX_PLUGIN = 9; + public static final int TEX_ENVMAP = 10; + public static final int TEX_MUSGRAVE = 11; + public static final int TEX_VORONOI = 12; + public static final int TEX_DISTNOISE = 13; + public static final int TEX_POINTDENSITY = 14; // v. 25+ + public static final int TEX_VOXELDATA = 15; // v. 25+ + public static final int TEX_OCEAN = 16; // v. 26+ + + public static final Type[] TEXCOORD_TYPES = new Type[] { Type.TexCoord, Type.TexCoord2, Type.TexCoord3, Type.TexCoord4, Type.TexCoord5, Type.TexCoord6, Type.TexCoord7, Type.TexCoord8 }; + private TextureGeneratorFactory textureGeneratorFactory = new TextureGeneratorFactory(); /** @@ -523,9 +523,9 @@ public class TextureHelper extends AbstractBlenderHelper { return result; } - + @SuppressWarnings("unchecked") - public Map readTextureData(Structure structure, float[] diffuseColorArray, boolean skyTexture) throws BlenderFileException { + public List readTextureData(Structure structure, float[] diffuseColorArray, boolean skyTexture) throws BlenderFileException { DynamicArray mtexsArray = (DynamicArray) structure.getFieldValue("mtex"); int separatedTextures = skyTexture ? 0 : ((Number) structure.getFieldValue("septex")).intValue(); List texturesList = new ArrayList(); @@ -537,10 +537,10 @@ public class TextureHelper extends AbstractBlenderHelper { textureData.uvCoordinatesType = skyTexture ? UVCoordinatesType.TEXCO_ORCO.blenderValue : ((Number) textureData.mtex.getFieldValue("texco")).intValue(); textureData.projectionType = ((Number) textureData.mtex.getFieldValue("mapping")).intValue(); textureData.uvCoordinatesName = textureData.mtex.getFieldValue("uvName").toString(); - if(textureData.uvCoordinatesName != null && textureData.uvCoordinatesName.trim().length() == 0) { + if (textureData.uvCoordinatesName != null && textureData.uvCoordinatesName.trim().length() == 0) { textureData.uvCoordinatesName = null; } - + Pointer pTex = (Pointer) textureData.mtex.getFieldValue("tex"); if (pTex.isNotNull()) { Structure tex = pTex.fetchData(blenderContext.getInputStream()).get(0); @@ -550,33 +550,62 @@ public class TextureHelper extends AbstractBlenderHelper { } } - // loading the textures and merging them - Map> textureDataMap = this.sortTextures(texturesList); - Map loadedTextures = new HashMap(); - for (Entry> entry : textureDataMap.entrySet()) { - if (entry.getValue().size() > 0) { - CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue(), !skyTexture); - for (TextureData textureData : entry.getValue()) { + LOGGER.info("Loading model's textures."); + List loadedTextures = new ArrayList(); + if (blenderContext.getBlenderKey().isOptimiseTextures()) { + LOGGER.fine("Optimising the useage of model's textures."); + Map> textureDataMap = this.sortTextures(texturesList); + for (Entry> entry : textureDataMap.entrySet()) { + if (entry.getValue().size() > 0) { + CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue(), !skyTexture); + for (TextureData textureData : entry.getValue()) { + int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue(); + boolean negateTexture = (texflag & 0x04) != 0; + Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext); + if (texture != null) { + int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue(); + float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() }; + float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue(); + TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac); + combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext); + } + } + if (combinedTexture.getTexturesCount() > 0) { + loadedTextures.add(combinedTexture); + } + } + } + } else { + LOGGER.fine("No textures optimisation applied."); + int[] mappings = new int[] { MaterialContext.MTEX_COL, MaterialContext.MTEX_NOR, MaterialContext.MTEX_EMIT, MaterialContext.MTEX_SPEC, MaterialContext.MTEX_ALPHA, MaterialContext.MTEX_AMB }; + for (TextureData textureData : texturesList) { + Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext); + if (texture != null) { + Number mapto = (Number) textureData.mtex.getFieldValue("mapto"); int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue(); boolean negateTexture = (texflag & 0x04) != 0; - Texture texture = this.getTexture(textureData.textureStructure, textureData.mtex, blenderContext); - if (texture != null) { - int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue(); - float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() }; - float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue(); - TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac); - combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, - textureData.textureStructure, textureData.uvCoordinatesName, blenderContext); + + for (int i = 0; i < mappings.length; ++i) { + if ((mappings[i] & mapto.intValue()) != 0) { + CombinedTexture combinedTexture = new CombinedTexture(mappings[i], !skyTexture); + int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue(); + float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() }; + float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue(); + TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac); + combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, textureData.uvCoordinatesName, blenderContext); + if (combinedTexture.getTexturesCount() > 0) {// the added texture might not have been accepted (if for example loading generated textures is disabled) + loadedTextures.add(combinedTexture); + } + } } } - if (combinedTexture.getTexturesCount() > 0) { - loadedTextures.put(entry.getKey(), combinedTexture); - } + } } + return loadedTextures; } - + /** * This method sorts the textures by their mapping type. In each group only * textures of one type are put (either two- or three-dimensional). @@ -601,7 +630,7 @@ public class TextureHelper extends AbstractBlenderHelper { } return result; } - + private static class TextureData { public Structure mtex; public Structure textureStructure;