From d6574a8cc7a164fb620bbe1008aaf6d174d18994 Mon Sep 17 00:00:00 2001 From: "Kae..pl" Date: Fri, 19 Aug 2011 23:16:32 +0000 Subject: [PATCH] Importing generated textures as 3D textures. UV coordinates generator added (will handle different UV coordinates generation methods in the future). MaterialHelper refactoring. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@8039 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../blender/com/jme3/asset/BlenderKey.java | 22 +- .../plugins/blender/materials/IAlphaMask.java | 26 ++ .../blender/materials/MaterialContext.java | 113 ++++++ .../blender/materials/MaterialHelper.java | 298 +++++++--------- .../plugins/blender/meshes/MeshHelper.java | 75 +--- .../blender/textures/TextureGenerator.java | 16 +- .../textures/TextureGeneratorBlend.java | 114 +++--- .../textures/TextureGeneratorClouds.java | 83 +++-- .../textures/TextureGeneratorDistnoise.java | 59 ++-- .../textures/TextureGeneratorMagic.java | 114 +++--- .../textures/TextureGeneratorMarble.java | 58 ++-- .../textures/TextureGeneratorMusgrave.java | 68 ++-- .../textures/TextureGeneratorNoise.java | 57 +-- .../textures/TextureGeneratorStucci.java | 88 ++--- .../textures/TextureGeneratorVoronoi.java | 137 ++++---- .../textures/TextureGeneratorWood.java | 49 +-- .../blender/textures/TextureHelper.java | 23 +- .../textures/UVCoordinatesGenerator.java | 324 ++++++++++++++++++ 18 files changed, 1104 insertions(+), 620 deletions(-) create mode 100644 engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java create mode 100644 engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java create mode 100644 engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java diff --git a/engine/src/blender/com/jme3/asset/BlenderKey.java b/engine/src/blender/com/jme3/asset/BlenderKey.java index 48560b467..86311aae9 100644 --- a/engine/src/blender/com/jme3/asset/BlenderKey.java +++ b/engine/src/blender/com/jme3/asset/BlenderKey.java @@ -78,10 +78,12 @@ public class BlenderKey extends ModelKey { * between the frames. */ protected int fps = DEFAULT_FPS; - /** Width of generated textures (in pixels). Blender uses 140x140 by default. */ - protected int generatedTextureWidth = 140; - /** Height of generated textures (in pixels). Blender uses 140x140 by default. */ - protected int generatedTextureHeight = 140; + /** Width of generated textures (in pixels). */ + protected int generatedTextureWidth = 20; + /** Height of generated textures (in pixels). */ + protected int generatedTextureHeight = 20; + /** Depth of generated textures (in pixels). */ + protected int generatedTextureDepth = 20; /** * This variable is a bitwise flag of FeatureToLoad interface values; By default everything is being loaded. */ @@ -228,7 +230,7 @@ public class BlenderKey extends ModelKey { } /** - * This method sets the height of generated texture (in pixels). By default the value is 140 px. + * This method sets the height of generated texture (in pixels). By default the value is 20 px. * @param generatedTextureHeight * the height of generated texture */ @@ -237,12 +239,20 @@ public class BlenderKey extends ModelKey { } /** - * This method returns the height of generated texture (in pixels). By default the value is 140 px. + * This method returns the height of generated texture (in pixels). By default the value is 20 px. * @return the height of generated texture */ public int getGeneratedTextureHeight() { return generatedTextureHeight; } + + /** + * This method returns the depth of generated texture (in pixels). By default the value is 20 px. + * @return the depth of generated texture + */ + public int getGeneratedTextureDepth() { + return generatedTextureDepth; + } /** * This method returns the face cull mode. diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java new file mode 100644 index 000000000..45e6f3585 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/IAlphaMask.java @@ -0,0 +1,26 @@ +package com.jme3.scene.plugins.blender.materials; + +/** + * An interface used in calculating alpha mask during particles' texture calculations. + * @author Marcin Roguski (Kaelthas) + */ +/*package*/ interface IAlphaMask { + /** + * This method sets the size of the texture's image. + * @param width + * the width of the image + * @param height + * the height of the image + */ + void setImageSize(int width, int height); + + /** + * This method returns the alpha value for the specified texture position. + * @param x + * the X coordinate of the texture position + * @param y + * the Y coordinate of the texture position + * @return the alpha value for the specified texture position + */ + byte getAlpha(float x, float y); +} \ No newline at end of file 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 new file mode 100644 index 000000000..c8f41b5a9 --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialContext.java @@ -0,0 +1,113 @@ +package com.jme3.scene.plugins.blender.materials; + +import java.util.ArrayList; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import com.jme3.scene.plugins.blender.DataRepository; +import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; +import com.jme3.scene.plugins.blender.file.DynamicArray; +import com.jme3.scene.plugins.blender.file.Pointer; +import com.jme3.scene.plugins.blender.file.Structure; +import com.jme3.scene.plugins.blender.textures.TextureHelper; +import com.jme3.texture.Texture.Type; + +/*package*/final class MaterialContext { + private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName()); + + public final String name; + public final List mTexs; + public final List textures; + public final int texturesCount; + public final Type textureType; + public final int textureCoordinatesType; + + public final boolean shadeless; + public final boolean vertexColor; + public final boolean transparent; + public final boolean vtangent; + + @SuppressWarnings("unchecked") + public MaterialContext(Structure structure, DataRepository dataRepository) throws BlenderFileException { + name = structure.getName(); + + int mode = ((Number) structure.getFieldValue("mode")).intValue(); + shadeless = (mode & 0x4) != 0; + vertexColor = (mode & 0x80) != 0; + transparent = (mode & 0x10000) != 0; + vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents + + mTexs = new ArrayList(); + textures = new ArrayList(); + DynamicArray mtexsArray = (DynamicArray) structure.getFieldValue("mtex"); + int separatedTextures = ((Number) structure.getFieldValue("septex")).intValue(); + Type firstTextureType = null; + int texco = -1; + for (int i = 0; i < mtexsArray.getTotalSize(); ++i) { + Pointer p = mtexsArray.get(i); + if (p.isNotNull() && (separatedTextures & 1 << i) == 0) { + Structure mtex = p.fetchData(dataRepository.getInputStream()).get(0); + + //the first texture determines the texture coordinates type + if(texco == -1) { + texco = ((Number) mtex.getFieldValue("texco")).intValue(); + } else if(texco != ((Number) mtex.getFieldValue("texco")).intValue()) { + LOGGER.log(Level.WARNING, "The texture with index: {0} has different UV coordinates type than the first texture! This texture will NOT be loaded!", i+1); + continue; + } + + Pointer pTex = (Pointer) mtex.getFieldValue("tex"); + if(pTex.isNotNull()) { + Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0); + int type = ((Number) tex.getFieldValue("type")).intValue(); + Type textureType = this.getType(type); + if(textureType != null) { + if(firstTextureType == null) { + firstTextureType = textureType; + mTexs.add(mtex); + textures.add(tex); + } else if(firstTextureType == textureType) { + mTexs.add(mtex); + textures.add(tex); + } else { + LOGGER.log(Level.WARNING, "The texture with index: {0} is of different dimension than the first one! This texture will NOT be loaded!", i+1); + } + } + } + } + } + + this.texturesCount = mTexs.size(); + this.textureCoordinatesType = texco; + this.textureType = firstTextureType; + } + + private Type getType(int texType) { + switch (texType) { + case TextureHelper.TEX_IMAGE:// (it is first because probably this will be most commonly used) + return Type.TwoDimensional; + case TextureHelper.TEX_CLOUDS: + case TextureHelper.TEX_WOOD: + case TextureHelper.TEX_MARBLE: + case TextureHelper.TEX_MAGIC: + case TextureHelper.TEX_BLEND: + case TextureHelper.TEX_STUCCI: + case TextureHelper.TEX_NOISE: + case TextureHelper.TEX_MUSGRAVE: + case TextureHelper.TEX_VORONOI: + case TextureHelper.TEX_DISTNOISE: + return Type.ThreeDimensional; + case TextureHelper.TEX_NONE:// No texture, do nothing + return null; + case TextureHelper.TEX_POINTDENSITY: + case TextureHelper.TEX_VOXELDATA: + case TextureHelper.TEX_PLUGIN: + case TextureHelper.TEX_ENVMAP: + LOGGER.log(Level.WARNING, "Texture type NOT supported: {0}", texType); + return null; + default: + throw new IllegalStateException("Unknown texture type: " + texType); + } + } +} diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java index 42e96747e..905f016e6 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/materials/MaterialHelper.java @@ -52,7 +52,6 @@ import com.jme3.scene.plugins.blender.AbstractBlenderHelper; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.DataRepository.LoadedFeatureDataType; import com.jme3.scene.plugins.blender.exceptions.BlenderFileException; -import com.jme3.scene.plugins.blender.file.DynamicArray; import com.jme3.scene.plugins.blender.file.Pointer; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper; @@ -61,6 +60,7 @@ import com.jme3.texture.Image; import com.jme3.texture.Image.Format; import com.jme3.texture.Texture; import com.jme3.texture.Texture.MinFilter; +import com.jme3.texture.Texture.Type; import com.jme3.texture.Texture.WrapMode; import com.jme3.util.BufferUtils; @@ -68,6 +68,7 @@ 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_3D = "Texture"; public static final String TEXTURE_TYPE_COLOR = "ColorMap"; public static final String TEXTURE_TYPE_DIFFUSE = "DiffuseMap"; public static final String TEXTURE_TYPE_NORMAL = "NormalMap"; @@ -177,7 +178,6 @@ public class MaterialHelper extends AbstractBlenderHelper { this.faceCullMode = faceCullMode; } - @SuppressWarnings("unchecked") public Material toMaterial(Structure structure, DataRepository dataRepository) throws BlenderFileException { LOGGER.log(Level.INFO, "Loading material."); if (structure == null) { @@ -187,153 +187,139 @@ public class MaterialHelper extends AbstractBlenderHelper { if (result != null) { return result; } - - int mode = ((Number) structure.getFieldValue("mode")).intValue(); - boolean shadeless = (mode & 0x4) != 0; - boolean vertexColor = (mode & 0x80) != 0; - boolean transparent = (mode & 0x10000) != 0; - boolean vtangent = (mode & 0x4000000) != 0; // NOTE: Requires tangents - - if (shadeless) { - result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); - } else { - result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); - } - - //System.out.println("Mode: \n" + - // "Shadeless: " + shadeless + "\n" + - // "VColor: " + vertexColor + "\n" + - // "ZTrans: " + transparent + "\n" + - // "VTangent: " + vtangent); - - result.getAdditionalRenderState().setFaceCullMode(faceCullMode); - - if (transparent) { - result.setTransparent(true); - result.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); - } - - String name = structure.getName(); - LOGGER.log(Level.INFO, "Material's name: {0}", name); - if (vertexColor) { - result.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true); - } - - MaterialHelper materialHelper = dataRepository.getHelper(MaterialHelper.class); - ColorRGBA diffuseColor = null; - if (shadeless) { - // color of shadeless? doesn't seem to work in blender .. - diffuseColor = ColorRGBA.White.clone(); - } else { - result.setBoolean("UseMaterialColors", Boolean.TRUE); - - // setting the colors - DiffuseShader diffuseShader = materialHelper.getDiffuseShader(structure); - result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT); - diffuseColor = materialHelper.getDiffuseColor(structure, diffuseShader); - if (!transparent){ - diffuseColor.a = 1; - } - result.setColor("Diffuse", diffuseColor); - - SpecularShader specularShader = materialHelper.getSpecularShader(structure); - result.setBoolean("WardIso", specularShader == SpecularShader.WARDISO); - result.setColor("Specular", materialHelper.getSpecularColor(structure, specularShader)); - - result.setColor("Ambient", materialHelper.getAmbientColor(structure)); - result.setFloat("Shininess", materialHelper.getShininess(structure)); - - - } + + MaterialContext materialContext = new MaterialContext(structure, dataRepository); + LOGGER.log(Level.INFO, "Material's name: {0}", materialContext.name); // texture + Map texturesMap = new HashMap(); + Type firstTextureType = null; if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0) { TextureHelper textureHelper = dataRepository.getHelper(TextureHelper.class); - DynamicArray mtexs = (DynamicArray) structure.getFieldValue("mtex"); - int separatedTextures = ((Number)structure.getFieldValue("septex")).intValue(); - for (int i = 0; i < mtexs.getTotalSize(); ++i) { - Pointer p = mtexs.get(i); - if (p.isNotNull() && (separatedTextures & (1 << i)) == 0) { - List mtex = p.fetchData(dataRepository.getInputStream()); - if (mtex.size() == 1) { - Structure textureLink = mtex.get(0); - int texflag = ((Number) textureLink.getFieldValue("texflag")).intValue(); - // int texco = ((Number) textureLink.getFieldValue("texco")).intValue(); - boolean negateTexture = (texflag & 0x04) == 0; - - // if(texco == 0x10) {//TEXCO_UV (this is only supported now) - int mapto = ((Number) textureLink.getFieldValue("mapto")).intValue(); - if (mapto != 0) { - Pointer pTex = (Pointer) textureLink.getFieldValue("tex"); - Structure tex = pTex.fetchData(dataRepository.getInputStream()).get(0); - Texture texture = textureHelper.getTexture(tex, dataRepository); - - if (texture != null) { - // NOTE: Enable mipmaps FOR ALL TEXTURES EVER - texture.setMinFilter(MinFilter.Trilinear); - - if ((mapto & 0x01) != 0) {// Col - // Map to COLOR channel or DIFFUSE - // Set diffuse to white so it doesn't get multiplied by texture - diffuseColor.r = diffuseColor.g = diffuseColor.b = 1.0f; - result.setColor(shadeless ? "Color" : "Diffuse", diffuseColor); - //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 colfac = ((Number) textureLink.getFieldValue("colfac")).floatValue(); - texture = textureHelper.blendTexture(diffuseColor.getColorArray(), texture, color, colfac, blendType, negateTexture, dataRepository); - texture.setMinFilter(MinFilter.Trilinear); - texture.setWrap(WrapMode.Repeat); - if (shadeless) { - result.setTexture(TEXTURE_TYPE_COLOR, texture); - } else { - result.setTexture(TEXTURE_TYPE_DIFFUSE, texture); - } - } - if ((mapto & 0x02) != 0 && !shadeless) {// Nor - Texture normalMapTexture; - if(texture.getKey() instanceof GeneratedTextureKey) { - normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number)textureLink.getFieldValue("norfac")).floatValue()); - normalMapTexture.setMinFilter(MinFilter.Trilinear); - } else { - normalMapTexture = texture; - } - result.setTexture(TEXTURE_TYPE_NORMAL, normalMapTexture); - if (vertexColor) { - result.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", false); - } - } - if ((mapto & 0x04) != 0 && !shadeless) {// Spec - // Map to SPECULAR - result.setTexture(TEXTURE_TYPE_SPECULAR, texture); - } - if ((mapto & 0x40) != 0) {// Emit - result.setTexture(TEXTURE_TYPE_GLOW, texture); - } - if ((mapto & 0x80) != 0 && !shadeless) {// Alpha - result.setTexture(TEXTURE_TYPE_ALPHA, texture); - } + for (int i=0;i texs = pTex.fetchData(dataRepository.getInputStream()); - // Structure tex = texs.get(0); - // LOGGER.log(Level.WARNING, "Unsupported texture type: " + texco); - // } } else { - LOGGER.log(Level.WARNING, "Many textures. Not solved yet!");// TODO + LOGGER.log(Level.WARNING, "Texture not found!"); } } } } + + //creating the material + if(firstTextureType==Type.ThreeDimensional) { + result = new Material(dataRepository.getAssetManager(), "jme3test/texture/tex3D.j3md"); + } else { + if (materialContext.shadeless) { + result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md"); + } else { + result = new Material(dataRepository.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md"); + } + + if (materialContext.vertexColor) { + result.setBoolean(materialContext.shadeless ? "VertexColor" : "UseVertexColor", true); + } + ColorRGBA diffuseColor = null; + if (materialContext.shadeless) { + // color of shadeless? doesn't seem to work in blender .. + diffuseColor = ColorRGBA.White.clone(); + } else { + result.setBoolean("UseMaterialColors", Boolean.TRUE); + + // setting the colors + DiffuseShader diffuseShader = this.getDiffuseShader(structure); + result.setBoolean("Minnaert", diffuseShader == DiffuseShader.MINNAERT); + diffuseColor = this.getDiffuseColor(structure, diffuseShader); + if (!materialContext.transparent) { + diffuseColor.a = 1; + } + result.setColor("Diffuse", diffuseColor); + + SpecularShader specularShader = this.getSpecularShader(structure); + result.setBoolean("WardIso", specularShader == SpecularShader.WARDISO); + result.setColor("Specular", this.getSpecularColor(structure, specularShader)); + + result.setColor("Ambient", this.getAmbientColor(structure)); + result.setFloat("Shininess", this.getShininess(structure)); + } + } + + //applying textures + for(Entry textureEntry : texturesMap.entrySet()) { + result.setTexture(textureEntry.getKey(), textureEntry.getValue()); + } + + //applying other data + result.getAdditionalRenderState().setFaceCullMode(faceCullMode); + if (materialContext.transparent) { + result.setTransparent(true); + result.getAdditionalRenderState().setBlendMode(BlendMode.Alpha); + } + dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, result); return result; } - + /** * This method returns a material similar to the one given but without textures. If the material has no textures it is not cloned but * returned itself. @@ -428,7 +414,7 @@ public class MaterialHelper extends AbstractBlenderHelper { } return result; } - + /** * This method indicates if the material has any kind of texture. * @@ -438,22 +424,25 @@ public class MaterialHelper extends AbstractBlenderHelper { */ public boolean hasTexture(Material material) { if (material != null) { - if(material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) { + if (material.getTextureParam(TEXTURE_TYPE_3D) != null) { + return true; + } + if (material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) { return true; } - if(material.getTextureParam(TEXTURE_TYPE_COLOR) != null) { + if (material.getTextureParam(TEXTURE_TYPE_COLOR) != null) { return true; } - if(material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) { + if (material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) { return true; } - if(material.getTextureParam(TEXTURE_TYPE_GLOW) != null) { + if (material.getTextureParam(TEXTURE_TYPE_GLOW) != null) { return true; } - if(material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) { + if (material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) { return true; } - if(material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) { + if (material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) { return true; } } @@ -475,7 +464,7 @@ public class MaterialHelper extends AbstractBlenderHelper { } return false; } - + /** * This method returns the diffuse color * @@ -743,29 +732,4 @@ public class MaterialHelper extends AbstractBlenderHelper { public boolean shouldBeLoaded(Structure structure, DataRepository dataRepository) { return (dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0; } - - /** - * An interface used in calculating alpha mask during particles' texture calculations. - * @author Marcin Roguski (Kaelthas) - */ - protected static interface IAlphaMask { - /** - * This method sets the size of the texture's image. - * @param width - * the width of the image - * @param height - * the height of the image - */ - void setImageSize(int width, int height); - - /** - * This method returns the alpha value for the specified texture position. - * @param x - * the X coordinate of the texture position - * @param y - * the Y coordinate of the texture position - * @return the alpha value for the specified texture position - */ - byte getAlpha(float x, float y); - } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java index 317e44edd..8064b7ccd 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/meshes/MeshHelper.java @@ -44,10 +44,8 @@ import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.bounding.BoundingBox; import com.jme3.bounding.BoundingSphere; import com.jme3.bounding.BoundingVolume; -import com.jme3.collision.CollisionResults; import com.jme3.material.Material; import com.jme3.math.FastMath; -import com.jme3.math.Ray; import com.jme3.math.Vector2f; import com.jme3.math.Vector3f; import com.jme3.renderer.queue.RenderQueue.Bucket; @@ -68,6 +66,7 @@ import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.materials.MaterialHelper; import com.jme3.scene.plugins.blender.objects.Properties; import com.jme3.scene.plugins.blender.textures.TextureHelper; +import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator; import com.jme3.texture.Texture; import com.jme3.util.BufferUtils; @@ -127,10 +126,13 @@ public class MeshHelper extends AbstractBlenderHelper { // the following map sorts faces by material number (because in jme Mesh can have only one material) Map> meshesMap = new HashMap>(); Pointer pMFace = (Pointer) structure.getFieldValue("mface"); - List mFaces = null; - if (pMFace.isNotNull()){ - mFaces = pMFace.fetchData(dataRepository.getInputStream()); - } + List mFaces = null; + if (pMFace.isNotNull()){ + mFaces = pMFace.fetchData(dataRepository.getInputStream()); + if(mFaces==null || mFaces.size()==0) { + return new ArrayList(0); + } + } Pointer pMTFace = (Pointer) structure.getFieldValue("mtface"); List uvCoordinates = null; @@ -142,7 +144,7 @@ public class MeshHelper extends AbstractBlenderHelper { if (mtFaces.size() != facesAmount) { throw new BlenderFileException("The amount of faces uv coordinates is not equal to faces amount!"); } - uvCoordinates = new ArrayList();// TODO: calculate the amount of coordinates if possible + uvCoordinates = new ArrayList(); } // normalMap merges normals of faces that will be rendered smooth @@ -156,9 +158,6 @@ public class MeshHelper extends AbstractBlenderHelper { // positions (it simply tells which vertex is referenced where in the result list) Map> vertexReferenceMap = new HashMap>(verticesAmount); int vertexColorIndex = 0; - if (mFaces == null){ - return null; - } for (int i = 0; i < mFaces.size(); ++i) { Structure mFace = mFaces.get(i); boolean smooth = (((Number) mFace.getFieldValue("flag")).byteValue() & 0x01) != 0x00; @@ -392,54 +391,9 @@ public class MeshHelper extends AbstractBlenderHelper { for(Geometry geom : geometries) { geom.getMesh().setBuffer(uvCoordsBuffer); } - } else { - Vector2f[] uvTable = new Vector2f[vertexList.size()]; - Ray ray = new Ray(); - CollisionResults cr = new CollisionResults(); - Vector3f yVec = new Vector3f(); - Vector3f zVec = new Vector3f(); - for(Geometry geom : geometries) { - if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture - geom.getMesh().updateBound(); - BoundingSphere bs = this.getBoundingSphere(geom.getMesh()); - float r2 = bs.getRadius() * bs.getRadius(); - yVec.set(0, -bs.getRadius(), 0); - zVec.set(0, 0, -bs.getRadius()); - Vector3f center = bs.getCenter(); - ray.setOrigin(center); - //we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates - for(int i=0;i mVerts = pMVert.fetchData(dataRepository.getInputStream()); diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java index 162929043..f479b5626 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGenerator.java @@ -14,14 +14,14 @@ import com.jme3.texture.Texture; * @author Marcin Roguski (Kaelthas) */ /* package */abstract class TextureGenerator { - private static final Logger LOGGER = Logger.getLogger(TextureGenerator.class.getName()); - - protected NoiseGenerator noiseGenerator; - + private static final Logger LOGGER = Logger.getLogger(TextureGenerator.class.getName()); + + protected NoiseGenerator noiseGenerator; + public TextureGenerator(NoiseGenerator noiseGenerator) { this.noiseGenerator = noiseGenerator; } - + /** * This method generates the texture. * @param tex @@ -30,12 +30,14 @@ import com.jme3.texture.Texture; * the width of the result texture * @param height * the height of the result texture + * @param depth + * the depth of the texture * @param dataRepository * the data repository * @return newly generated texture */ - protected abstract Texture generate(Structure tex, int width, int height, DataRepository dataRepository); - + protected abstract Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository); + /** * This method reads the colorband data from the given texture structure. * diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java index 52e4ecb60..f72d48c93 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorBlend.java @@ -1,6 +1,7 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.DataRepository; @@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -21,85 +22,92 @@ public final class TextureGeneratorBlend extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorBlend(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { int flag = ((Number) tex.getFieldValue("flag")).intValue(); int stype = ((Number) tex.getFieldValue("stype")).intValue(); float contrast = ((Number) tex.getFieldValue("contrast")).floatValue(); float brightness = ((Number) tex.getFieldValue("bright")).floatValue(); - float wDelta = 1.0f / width, hDelta = 1.0f / height, x, y, t; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, x, y, t; float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); - int halfW = width, halfH = height; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j; - if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) { - x = texvec[1]; - y = texvec[0]; - } else { - x = texvec[0]; - y = texvec[1]; - } - - if (stype == NoiseGenerator.TEX_LIN) { /* lin */ - texres.tin = (1.0f + x) / 2.0f; - } else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */ - texres.tin = (1.0f + x) / 2.0f; - if (texres.tin < 0.0f) { - texres.tin = 0.0f; + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + if ((flag & NoiseGenerator.TEX_FLIPBLEND) != 0) { + x = texvec[1]; + y = texvec[0]; } else { - texres.tin *= texres.tin; + x = texvec[0]; + y = texvec[1]; } - } else if (stype == NoiseGenerator.TEX_EASE) { /* ease */ - texres.tin = (1.0f + x) / 2.0f; - if (texres.tin <= 0.0f) { - texres.tin = 0.0f; - } else if (texres.tin >= 1.0f) { - texres.tin = 1.0f; - } else { - t = texres.tin * texres.tin; - texres.tin = 3.0f * t - 2.0f * t * texres.tin; + + if (stype == NoiseGenerator.TEX_LIN) { /* lin */ + texres.tin = (1.0f + x) / 2.0f; + } else if (stype == NoiseGenerator.TEX_QUAD) { /* quad */ + texres.tin = (1.0f + x) / 2.0f; + if (texres.tin < 0.0f) { + texres.tin = 0.0f; + } else { + texres.tin *= texres.tin; + } + } else if (stype == NoiseGenerator.TEX_EASE) { /* ease */ + texres.tin = (1.0f + x) / 2.0f; + if (texres.tin <= 0.0f) { + texres.tin = 0.0f; + } else if (texres.tin >= 1.0f) { + texres.tin = 1.0f; + } else { + t = texres.tin * texres.tin; + texres.tin = 3.0f * t - 2.0f * t * texres.tin; + } + } else if (stype == NoiseGenerator.TEX_DIAG) { /* diag */ + texres.tin = (2.0f + x + y) / 4.0f; + } else if (stype == NoiseGenerator.TEX_RAD) { /* radial */ + texres.tin = (float) Math.atan2(y, x) / FastMath.TWO_PI + 0.5f; + } else { /* sphere TEX_SPHERE */ + texres.tin = 1.0f - (float) Math.sqrt(x * x + y * y + texvec[2] * texvec[2]); + if (texres.tin < 0.0f) { + texres.tin = 0.0f; + } + if (stype == NoiseGenerator.TEX_HALO) { + texres.tin *= texres.tin; + } /* halo */ } - } else if (stype == NoiseGenerator.TEX_DIAG) { /* diag */ - texres.tin = (2.0f + x + y) / 4.0f; - } else if (stype == NoiseGenerator.TEX_RAD) { /* radial */ - texres.tin = (float) Math.atan2(y, x) / FastMath.TWO_PI + 0.5f; - } else { /* sphere TEX_SPHERE */ - texres.tin = 1.0f - (float) Math.sqrt(x * x + y * y + texvec[2] * texvec[2]); - if (texres.tin < 0.0f) { - texres.tin = 0.0f; + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, brightness); + data.put((byte) (texres.tin * 255.0f)); } - if (stype == NoiseGenerator.TEX_HALO) { - texres.tin *= texres.tin; - } /* halo */ - } - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, brightness); - data.put((byte) (texres.tin * 255.0f)); } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java index 5c3af9e57..7d0100bba 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorClouds.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -20,16 +21,17 @@ public class TextureGeneratorClouds extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorClouds(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { // preparing the proper data - float wDelta = 1.0f / width, hDelta = 1.0f / height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); @@ -42,50 +44,55 @@ public class TextureGeneratorClouds extends TextureGenerator { float bright = ((Number) tex.getFieldValue("bright")).floatValue(); boolean isHard = noiseType != NoiseGenerator.TEX_NOISESOFT; int sType = ((Number) tex.getFieldValue("stype")).intValue(); - int halfW = width, halfH = height; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = sType == NoiseGenerator.TEX_COLOR || colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { - texvec[0] = wDelta * i;// x + texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { - texvec[1] = hDelta * j;// y (z is always = 0) - - texres.tin = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis); - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) { - float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); - // calculate bumpnormal - texres.nor[0] = noiseGenerator.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis); - texres.nor[1] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis); - texres.nor[2] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis); - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + texvec[1] = hDelta * j; + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + texres.tin = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2], noiseDepth, isHard, noiseBasis); + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) { + float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); + // calculate bumpnormal + texres.nor[0] = noiseGenerator.bliGTurbulence(noisesize, texvec[0] + nabla, texvec[1], texvec[2], noiseDepth, isHard, noiseBasis); + texres.nor[1] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1] + nabla, texvec[2], noiseDepth, isHard, noiseBasis); + texres.nor[2] = noiseGenerator.bliGTurbulence(noisesize, texvec[0], texvec[1], texvec[2] + nabla, noiseDepth, isHard, noiseBasis); + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + } + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else if (sType == NoiseGenerator.TEX_COLOR) { + // in this case, int. value should really be computed from color, + // and bumpnormal from that, would be too slow, looks ok as is + texres.tr = texres.tin; + texres.tg = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis); + texres.tb = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis); + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, bright); + data.put((byte) (texres.tin * 255)); } - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else if (sType == NoiseGenerator.TEX_COLOR) { - // in this case, int. value should really be computed from color, - // and bumpnormal from that, would be too slow, looks ok as is - texres.tr = texres.tin; - texres.tg = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[0], texvec[2], noiseDepth, isHard, noiseBasis); - texres.tb = noiseGenerator.bliGTurbulence(noisesize, texvec[1], texvec[2], texvec[0], noiseDepth, isHard, noiseBasis); - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, bright); - data.put((byte) (texres.tin * 255)); } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java index 8fb9b6961..68afce5fd 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorDistnoise.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -20,14 +21,15 @@ public class TextureGeneratorDistnoise extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorDistnoise(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue(); float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); float distAmount = ((Number) tex.getFieldValue("dist_amount")).floatValue(); @@ -38,42 +40,47 @@ public class TextureGeneratorDistnoise extends TextureGenerator { TexResult texres = new TexResult(); float[] texvec = new float[] { 0, 0, 0 }; - float wDelta = 1.0f / width, hDelta = 1.0f / height; - int halfW = width, halfH = height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i / noisesize; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j / noisesize; + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k;// z + texres.tin = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2); + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) { + float offs = nabla / noisesize; // also scaling of texvec + /* calculate bumpnormal */ + texres.nor[0] = noiseGenerator.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2); + texres.nor[1] = noiseGenerator.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2); + texres.nor[2] = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2); + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + } - texres.tin = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2], distAmount, noisebasis, noisebasis2); - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) { - float offs = nabla / noisesize; // also scaling of texvec - /* calculate bumpnormal */ - texres.nor[0] = noiseGenerator.mgVLNoise(texvec[0] + offs, texvec[1], texvec[2], distAmount, noisebasis, noisebasis2); - texres.nor[1] = noiseGenerator.mgVLNoise(texvec[0], texvec[1] + offs, texvec[2], distAmount, noisebasis, noisebasis2); - texres.nor[2] = noiseGenerator.mgVLNoise(texvec[0], texvec[1], texvec[2] + offs, distAmount, noisebasis, noisebasis2); - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, brightness); + data.put((byte) (texres.tin * 255.0f)); } - - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, brightness); - data.put((byte) (texres.tin * 255.0f)); } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java index 7cecf7667..4d327945b 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMagic.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -20,62 +21,67 @@ public class TextureGeneratorMagic extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorMagic(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { float x, y, z, turb; int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue(); float turbul = ((Number) tex.getFieldValue("turbul")).floatValue() / 5.0f; float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); - float wDelta = 1.0f / width, hDelta = 1.0f / height; - int halfW = width, halfH = height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); - ByteBuffer data = BufferUtils.createByteBuffer(width * height * 4); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * 4); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { - turb = turbul; texvec[1] = hDelta * j; - x = (float) Math.sin((texvec[0] + texvec[1]) * 5.0f);// in blender: Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f); - y = (float) Math.cos((-texvec[0] + texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f); - z = -(float) Math.cos((-texvec[0] - texvec[1]) * 5.0f);// in blender: Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f); + for (int k = -halfD; k < halfD; ++k) { + turb = turbul; + texvec[2] = dDelta * k;// z + x = (float) Math.sin((texvec[0] + texvec[1] + texvec[2]) * 5.0f); + y = (float) Math.cos((-texvec[0] + texvec[1] - texvec[2]) * 5.0f); + z = -(float) Math.cos((-texvec[0] - texvec[1] + texvec[2]) * 5.0f); - if (colorBand != null) { - texres.tin = 0.3333f * (x + y + z); - noiseGenerator.doColorband(colorBand, texres, dataRepository); - } else { - if (noisedepth > 0) { - x *= turb; - y *= turb; - z *= turb; - y = -(float) Math.cos(x - y + z) * turb; - if (noisedepth > 1) { - x = (float) Math.cos(x - y - z) * turb; - if (noisedepth > 2) { - z = (float) Math.sin(-x - y - z) * turb; - if (noisedepth > 3) { - x = -(float) Math.cos(-x + y - z) * turb; - if (noisedepth > 4) { - y = -(float) Math.sin(-x + y + z) * turb; - if (noisedepth > 5) { - y = -(float) Math.cos(-x + y + z) * turb; - if (noisedepth > 6) { - x = (float) Math.cos(x + y + z) * turb; - if (noisedepth > 7) { - z = (float) Math.sin(x + y - z) * turb; - if (noisedepth > 8) { - x = -(float) Math.cos(-x - y + z) * turb; - if (noisedepth > 9) { - y = -(float) Math.sin(x - y + z) * turb; + if (colorBand != null) { + texres.tin = 0.3333f * (x + y + z); + noiseGenerator.doColorband(colorBand, texres, dataRepository); + } else { + if (noisedepth > 0) { + x *= turb; + y *= turb; + z *= turb; + y = -(float) Math.cos(x - y + z) * turb; + if (noisedepth > 1) { + x = (float) Math.cos(x - y - z) * turb; + if (noisedepth > 2) { + z = (float) Math.sin(-x - y - z) * turb; + if (noisedepth > 3) { + x = -(float) Math.cos(-x + y - z) * turb; + if (noisedepth > 4) { + y = -(float) Math.sin(-x + y + z) * turb; + if (noisedepth > 5) { + y = -(float) Math.cos(-x + y + z) * turb; + if (noisedepth > 6) { + x = (float) Math.cos(x + y + z) * turb; + if (noisedepth > 7) { + z = (float) Math.sin(x + y - z) * turb; + if (noisedepth > 8) { + x = -(float) Math.cos(-x - y + z) * turb; + if (noisedepth > 9) { + y = -(float) Math.sin(x - y + z) * turb; + } } } } @@ -85,25 +91,27 @@ public class TextureGeneratorMagic extends TextureGenerator { } } } - } - if (turb != 0.0f) { - turb *= 2.0f; - x /= turb; - y /= turb; - z /= turb; + if (turb != 0.0f) { + turb *= 2.0f; + x /= turb; + y /= turb; + z /= turb; + } + texres.tr = 0.5f - x; + texres.tg = 0.5f - y; + texres.tb = 0.5f - z; } - texres.tr = 0.5f - x; - texres.tg = 0.5f - y; - texres.tb = 0.5f - z; + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tin * 255)); + data.put((byte) (texres.tb * 255)); + data.put((byte) (texres.tg * 255)); + data.put((byte) (texres.tr * 255)); } - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tin * 255)); - data.put((byte) (texres.tb * 255)); - data.put((byte) (texres.tg * 255)); - data.put((byte) (texres.tr * 255)); } } - return new Texture2D(new Image(Format.ABGR8, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(Format.ABGR8, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java index 7e774692e..e8047adf4 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMarble.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -17,56 +18,63 @@ import com.jme3.util.BufferUtils; * @author Marcin Roguski (Kaelthas) */ public class TextureGeneratorMarble extends TextureGenerator { - + /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorMarble(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { // preparing the proper data float contrast = ((Number) tex.getFieldValue("contrast")).floatValue(); float bright = ((Number) tex.getFieldValue("bright")).floatValue(); float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); - float wDelta = 1.0f / width, hDelta = 1.0f / height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); - int halfW = width, halfH = height; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j; - texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository); - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) {// calculate bumpnormal - texres.nor[0] = noiseGenerator.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository); - texres.nor[1] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository); - texres.nor[2] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository); - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); - } + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + texres.tin = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2], dataRepository); + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) {// calculate bumpnormal + texres.nor[0] = noiseGenerator.marbleInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository); + texres.nor[1] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository); + texres.nor[2] = noiseGenerator.marbleInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository); + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + } - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, bright); - data.put((byte) (texres.tin * 255.0f)); + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, bright); + data.put((byte) (texres.tin * 255.0f)); + } } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java index 8289d4dad..3bb8a512f 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorMusgrave.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -20,56 +21,63 @@ public class TextureGeneratorMusgrave extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorMusgrave(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { int stype = ((Number) tex.getFieldValue("stype")).intValue(); float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue(); TexResult texres = new TexResult(); float[] texvec = new float[] { 0, 0, 0 }; - float wDelta = 1.0f / width, hDelta = 1.0f / height; - int halfW = width, halfH = height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i / noisesize; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j / noisesize; - switch (stype) { - case NoiseGenerator.TEX_MFRACTAL: - case NoiseGenerator.TEX_FBM: - noiseGenerator.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository); - break; - case NoiseGenerator.TEX_RIDGEDMF: - case NoiseGenerator.TEX_HYBRIDMF: - noiseGenerator.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository); - break; - case NoiseGenerator.TEX_HTERRAIN: - noiseGenerator.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository); - break; - default: - throw new IllegalStateException("Unknown type of musgrave texture: " + stype); - } - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - data.put((byte) (texres.tin * 255.0f)); + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + switch (stype) { + case NoiseGenerator.TEX_MFRACTAL: + case NoiseGenerator.TEX_FBM: + noiseGenerator.mgMFractalOrfBmTex(tex, texvec, colorBand, texres, dataRepository); + break; + case NoiseGenerator.TEX_RIDGEDMF: + case NoiseGenerator.TEX_HYBRIDMF: + noiseGenerator.mgRidgedOrHybridMFTex(tex, texvec, colorBand, texres, dataRepository); + break; + case NoiseGenerator.TEX_HTERRAIN: + noiseGenerator.mgHTerrainTex(tex, texvec, colorBand, texres, dataRepository); + break; + default: + throw new IllegalStateException("Unknown type of musgrave texture: " + stype); + } + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + data.put((byte) (texres.tin * 255.0f)); + } } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java index 413f1cb61..3d4a9d270 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorNoise.java @@ -1,6 +1,7 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.DataRepository; @@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -21,52 +22,58 @@ public class TextureGeneratorNoise extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorNoise(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { float div = 3.0f; int val, ran, loop; int noisedepth = ((Number) tex.getFieldValue("noisedepth")).intValue(); float contrast = ((Number) tex.getFieldValue("contrast")).floatValue(); float brightness = ((Number) tex.getFieldValue("bright")).floatValue(); TexResult texres = new TexResult(); - int halfW = width, halfH = height; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { for (int j = -halfH; j < halfH; ++j) { - ran = FastMath.rand.nextInt();// BLI_rand(); - val = ran & 3; + for (int k = -halfD; k < halfD; ++k) { + ran = FastMath.rand.nextInt();// BLI_rand(); + val = ran & 3; - loop = noisedepth; - while (loop-- != 0) { - ran = ran >> 2; - val *= ran & 3; - div *= 3.0f; - } - texres.tin = val;// / div; - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, brightness); - data.put((byte) (texres.tin * 255.0f)); + loop = noisedepth; + while (loop-- != 0) { + ran = ran >> 2; + val *= ran & 3; + div *= 3.0f; + } + texres.tin = val;// / div; + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, brightness); + data.put((byte) (texres.tin * 255.0f)); + } } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java index 696c90245..ebcb64e21 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorStucci.java @@ -1,15 +1,16 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -20,14 +21,15 @@ public class TextureGeneratorStucci extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorStucci(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { float noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue(); int noisebasis = ((Number) tex.getFieldValue("noisebasis")).intValue(); int noisetype = ((Number) tex.getFieldValue("noisetype")).intValue(); @@ -37,59 +39,65 @@ public class TextureGeneratorStucci extends TextureGenerator { float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); - float wDelta = 1.0f / width, hDelta = 1.0f / height, b2, ofs; - int halfW = width, halfH = height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth, b2, ofs; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { - texvec[0] = wDelta * i;// x + texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { - texvec[1] = hDelta * j;// y (z is always = 0) - b2 = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis); + texvec[1] = hDelta * j; + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + b2 = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2], isHard, noisebasis); - ofs = turbul / 200.0f; + ofs = turbul / 200.0f; - if (stype != 0) { - ofs *= b2 * b2; - } + if (stype != 0) { + ofs *= b2 * b2; + } - texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2] - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) { - texres.nor[0] = noiseGenerator.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis); - texres.nor[1] = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis); - texres.nor[2] = texres.tin; - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + texres.tin = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1], texvec[2] + ofs, isHard, noisebasis);// ==nor[2] + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) { + texres.nor[0] = noiseGenerator.bliGNoise(noisesize, texvec[0] + ofs, texvec[1], texvec[2], isHard, noisebasis); + texres.nor[1] = noiseGenerator.bliGNoise(noisesize, texvec[0], texvec[1] + ofs, texvec[2], isHard, noisebasis); + texres.nor[2] = texres.tin; + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); - if (stype == NoiseGenerator.TEX_WALLOUT) { - texres.nor[0] = -texres.nor[0]; - texres.nor[1] = -texres.nor[1]; - texres.nor[2] = -texres.nor[2]; + if (stype == NoiseGenerator.TEX_WALLOUT) { + texres.nor[0] = -texres.nor[0]; + texres.nor[1] = -texres.nor[1]; + texres.nor[2] = -texres.nor[2]; + } } } - } - if (stype == NoiseGenerator.TEX_WALLOUT) { - texres.tin = 1.0f - texres.tin; - } - if (texres.tin < 0.0f) { - texres.tin = 0.0f; - } - if (colorBand != null) { - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - data.put((byte) (texres.tin * 255.0f)); + if (stype == NoiseGenerator.TEX_WALLOUT) { + texres.tin = 1.0f - texres.tin; + } + if (texres.tin < 0.0f) { + texres.tin = 0.0f; + } + if (colorBand != null) { + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + data.put((byte) (texres.tin * 255.0f)); + } } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java index 809e5cad7..5612107b3 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorVoronoi.java @@ -1,6 +1,7 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.math.FastMath; import com.jme3.scene.plugins.blender.DataRepository; @@ -8,9 +9,9 @@ import com.jme3.scene.plugins.blender.file.Structure; import com.jme3.scene.plugins.blender.textures.TextureHelper.ColorBand; import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; -import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; import com.jme3.texture.Image.Format; +import com.jme3.texture.Texture; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -21,14 +22,15 @@ public class TextureGeneratorVoronoi extends TextureGenerator { /** * Constructor stores the given noise generator. - * @param noiseGenerator the noise generator + * @param noiseGenerator + * the noise generator */ public TextureGeneratorVoronoi(NoiseGenerator noiseGenerator) { super(noiseGenerator); } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { float vn_w1 = ((Number) tex.getFieldValue("vn_w1")).floatValue(); float vn_w2 = ((Number) tex.getFieldValue("vn_w2")).floatValue(); float vn_w3 = ((Number) tex.getFieldValue("vn_w3")).floatValue(); @@ -44,10 +46,11 @@ public class TextureGeneratorVoronoi extends TextureGenerator { TexResult texres = new TexResult(); float[] texvec = new float[] { 0, 0, 0 }; - float wDelta = 1.0f / width, hDelta = 1.0f / height; - int halfW = width, halfH = height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; + int halfW = width, halfH = height, halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = vn_coltype != 0 || colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = vn_coltype != 0 || colorBand != null ? 3 : 1; @@ -63,76 +66,80 @@ public class TextureGeneratorVoronoi extends TextureGenerator { sc = ns_outscale / sc; } - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i / noisesize; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j / noisesize; - - noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2], da, pa, vn_mexp, vn_distm); - texres.tin = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); - if (vn_coltype != 0) { - noiseGenerator.cellNoiseV(pa[0], pa[1], pa[2], ca); - texres.tr = aw1 * ca[0]; - texres.tg = aw1 * ca[1]; - texres.tb = aw1 * ca[2]; - noiseGenerator.cellNoiseV(pa[3], pa[4], pa[5], ca); - texres.tr += aw2 * ca[0]; - texres.tg += aw2 * ca[1]; - texres.tb += aw2 * ca[2]; - noiseGenerator.cellNoiseV(pa[6], pa[7], pa[8], ca); - texres.tr += aw3 * ca[0]; - texres.tg += aw3 * ca[1]; - texres.tb += aw3 * ca[2]; - noiseGenerator.cellNoiseV(pa[9], pa[10], pa[11], ca); - texres.tr += aw4 * ca[0]; - texres.tg += aw4 * ca[1]; - texres.tb += aw4 * ca[2]; - if (vn_coltype >= 2) { - float t1 = (da[1] - da[0]) * 10.0f; - if (t1 > 1) { - t1 = 1.0f; - } - if (vn_coltype == 3) { - t1 *= texres.tin; + for (int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2], da, pa, vn_mexp, vn_distm); + texres.tin = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); + if (vn_coltype != 0) { + noiseGenerator.cellNoiseV(pa[0], pa[1], pa[2], ca); + texres.tr = aw1 * ca[0]; + texres.tg = aw1 * ca[1]; + texres.tb = aw1 * ca[2]; + noiseGenerator.cellNoiseV(pa[3], pa[4], pa[5], ca); + texres.tr += aw2 * ca[0]; + texres.tg += aw2 * ca[1]; + texres.tb += aw2 * ca[2]; + noiseGenerator.cellNoiseV(pa[6], pa[7], pa[8], ca); + texres.tr += aw3 * ca[0]; + texres.tg += aw3 * ca[1]; + texres.tb += aw3 * ca[2]; + noiseGenerator.cellNoiseV(pa[9], pa[10], pa[11], ca); + texres.tr += aw4 * ca[0]; + texres.tg += aw4 * ca[1]; + texres.tb += aw4 * ca[2]; + if (vn_coltype >= 2) { + float t1 = (da[1] - da[0]) * 10.0f; + if (t1 > 1) { + t1 = 1.0f; + } + if (vn_coltype == 3) { + t1 *= texres.tin; + } else { + t1 *= sc; + } + texres.tr *= t1; + texres.tg *= t1; + texres.tb *= t1; } else { - t1 *= sc; + texres.tr *= sc; + texres.tg *= sc; + texres.tb *= sc; } - texres.tr *= t1; - texres.tg *= t1; - texres.tb *= t1; - } else { - texres.tr *= sc; - texres.tg *= sc; - texres.tb *= sc; } - } - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) { - float offs = nabla / noisesize; // also scaling of texvec - // calculate bumpnormal - noiseGenerator.voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, vn_mexp, vn_distm); - texres.nor[0] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); - noiseGenerator.voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, vn_mexp, vn_distm); - texres.nor[1] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); - noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, vn_mexp, vn_distm); - texres.nor[2] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) { + float offs = nabla / noisesize; // also scaling of texvec + // calculate bumpnormal + noiseGenerator.voronoi(texvec[0] + offs, texvec[1], texvec[2], da, pa, vn_mexp, vn_distm); + texres.nor[0] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); + noiseGenerator.voronoi(texvec[0], texvec[1] + offs, texvec[2], da, pa, vn_mexp, vn_distm); + texres.nor[1] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); + noiseGenerator.voronoi(texvec[0], texvec[1], texvec[2] + offs, da, pa, vn_mexp, vn_distm); + texres.nor[2] = sc * FastMath.abs(vn_w1 * da[0] + vn_w2 * da[1] + vn_w3 * da[2] + vn_w4 * da[3]); + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + } } - } - if (vn_coltype != 0 || colorBand != null) { - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f));// tin or tr?? - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, brightness); - data.put((byte) (texres.tin * 255.0f)); + if (vn_coltype != 0 || colorBand != null) { + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f));// tin or tr?? + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, brightness); + data.put((byte) (texres.tin * 255.0f)); + } } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java index db2461fff..e8db07330 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/TextureGeneratorWood.java @@ -1,6 +1,7 @@ package com.jme3.scene.plugins.blender.textures; import java.nio.ByteBuffer; +import java.util.ArrayList; import com.jme3.scene.plugins.blender.DataRepository; import com.jme3.scene.plugins.blender.file.Structure; @@ -9,7 +10,7 @@ import com.jme3.scene.plugins.blender.textures.TextureHelper.TexResult; import com.jme3.texture.Image; import com.jme3.texture.Image.Format; import com.jme3.texture.Texture; -import com.jme3.texture.Texture2D; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -27,46 +28,54 @@ public class TextureGeneratorWood extends TextureGenerator { } @Override - protected Texture generate(Structure tex, int width, int height, DataRepository dataRepository) { + protected Texture generate(Structure tex, int width, int height, int depth, DataRepository dataRepository) { // preparing the proper data float contrast = ((Number) tex.getFieldValue("contrast")).floatValue(); float bright = ((Number) tex.getFieldValue("bright")).floatValue(); float nabla = ((Number) tex.getFieldValue("nabla")).floatValue(); - float wDelta = 1.0f / width, hDelta = 1.0f / height; + float wDelta = 1.0f / width, hDelta = 1.0f / height, dDelta = 1.0f / depth; float[] texvec = new float[] { 0, 0, 0 }; TexResult texres = new TexResult(); int halfW = width; int halfH = height; + int halfD = depth; width <<= 1; height <<= 1; + depth <<= 1; + ColorBand colorBand = this.readColorband(tex, dataRepository); Format format = colorBand != null ? Format.RGB8 : Format.Luminance8; int bytesPerPixel = colorBand != null ? 3 : 1; - ByteBuffer data = BufferUtils.createByteBuffer(width * height * bytesPerPixel); + ByteBuffer data = BufferUtils.createByteBuffer(width * height * depth * bytesPerPixel); for (int i = -halfW; i < halfW; ++i) { texvec[0] = wDelta * i; for (int j = -halfH; j < halfH; ++j) { texvec[1] = hDelta * j; - texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository); - if (colorBand != null) { - noiseGenerator.doColorband(colorBand, texres, dataRepository); - if (texres.nor != null) {// calculate bumpnormal - texres.nor[0] = noiseGenerator.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository); - texres.nor[1] = noiseGenerator.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository); - texres.nor[2] = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository); - noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + for(int k = -halfD; k < halfD; ++k) { + texvec[2] = dDelta * k; + texres.tin = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2], dataRepository); + if (colorBand != null) { + noiseGenerator.doColorband(colorBand, texres, dataRepository); + if (texres.nor != null) {// calculate bumpnormal + texres.nor[0] = noiseGenerator.woodInt(tex, texvec[0] + nabla, texvec[1], texvec[2], dataRepository); + texres.nor[1] = noiseGenerator.woodInt(tex, texvec[0], texvec[1] + nabla, texvec[2], dataRepository); + texres.nor[2] = noiseGenerator.woodInt(tex, texvec[0], texvec[1], texvec[2] + nabla, dataRepository); + noiseGenerator.texNormalDerivate(colorBand, texres, dataRepository); + } + noiseGenerator.brightnesAndContrastRGB(tex, texres); + data.put((byte) (texres.tr * 255.0f)); + data.put((byte) (texres.tg * 255.0f)); + data.put((byte) (texres.tb * 255.0f)); + } else { + noiseGenerator.brightnesAndContrast(texres, contrast, bright); + data.put((byte) (texres.tin * 255)); } - noiseGenerator.brightnesAndContrastRGB(tex, texres); - data.put((byte) (texres.tr * 255.0f)); - data.put((byte) (texres.tg * 255.0f)); - data.put((byte) (texres.tb * 255.0f)); - } else { - noiseGenerator.brightnesAndContrast(texres, contrast, bright); - data.put((byte) (texres.tin * 255)); } } } - return new Texture2D(new Image(format, width, height, data)); + ArrayList dataArray = new ArrayList(1); + dataArray.add(data); + return new Texture3D(new Image(format, width, height, depth, dataArray)); } } 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 94d65de36..327c6e08e 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 @@ -41,6 +41,7 @@ import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; import java.nio.ByteBuffer; +import java.util.ArrayList; import java.util.HashMap; import java.util.Map; import java.util.logging.Level; @@ -68,6 +69,7 @@ import com.jme3.texture.Image.Format; import com.jme3.texture.Texture; import com.jme3.texture.Texture.WrapMode; import com.jme3.texture.Texture2D; +import com.jme3.texture.Texture3D; import com.jme3.util.BufferUtils; /** @@ -194,7 +196,8 @@ public class TextureHelper extends AbstractBlenderHelper { int type = ((Number) tex.getFieldValue("type")).intValue(); int width = dataRepository.getBlenderKey().getGeneratedTextureWidth(); int height = dataRepository.getBlenderKey().getGeneratedTextureHeight(); - + int depth = dataRepository.getBlenderKey().getGeneratedTextureDepth(); + switch (type) { case TEX_IMAGE:// (it is first because probably this will be most commonly used) Pointer pImage = (Pointer) tex.getFieldValue("ima"); @@ -214,7 +217,7 @@ public class TextureHelper extends AbstractBlenderHelper { case TEX_VORONOI: case TEX_DISTNOISE: TextureGenerator textureGenerator = textureGenerators.get(Integer.valueOf(type)); - result = textureGenerator.generate(tex, width, height, dataRepository); + result = textureGenerator.generate(tex, width, height, depth, dataRepository); break; case TEX_NONE:// No texture, do nothing break; @@ -266,7 +269,11 @@ public class TextureHelper extends AbstractBlenderHelper { data.rewind(); int width = texture.getImage().getWidth(); int height = texture.getImage().getHeight(); - ByteBuffer newData = BufferUtils.createByteBuffer(width * height * 4); + int depth = texture.getImage().getDepth(); + if(depth==0) { + depth = 1; + } + ByteBuffer newData = BufferUtils.createByteBuffer(width * height * depth * 4); float[] resultPixel = new float[4]; int dataIndex = 0; @@ -276,9 +283,15 @@ public class TextureHelper extends AbstractBlenderHelper { newData.put(dataIndex++, (byte) (resultPixel[0] * 255.0f)); newData.put(dataIndex++, (byte) (resultPixel[1] * 255.0f)); newData.put(dataIndex++, (byte) (resultPixel[2] * 255.0f)); - newData.put(dataIndex++, (byte) (1.0 * 255.0f)); + newData.put(dataIndex++, (byte) 255.0f);//1.0f * 255.0f + } + if(texture.getType()==Texture.Type.TwoDimensional) { + return new Texture2D(new Image(Format.RGBA8, width, height, newData)); + } else { + ArrayList dataArray = new ArrayList(1); + dataArray.add(newData); + return new Texture3D(new Image(Format.RGBA8, width, height, depth, dataArray)); } - return new Texture2D(new Image(Format.RGBA8, width, height, newData)); } /** diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java new file mode 100644 index 000000000..e4fcf684e --- /dev/null +++ b/engine/src/blender/com/jme3/scene/plugins/blender/textures/UVCoordinatesGenerator.java @@ -0,0 +1,324 @@ +/* + * Copyright (c) 2009-2010 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.textures; + +import java.nio.FloatBuffer; +import java.util.List; +import java.util.logging.Logger; + +import com.jme3.bounding.BoundingBox; +import com.jme3.bounding.BoundingSphere; +import com.jme3.bounding.BoundingVolume; +import com.jme3.math.Vector2f; +import com.jme3.math.Vector3f; +import com.jme3.scene.Geometry; +import com.jme3.scene.Mesh; +import com.jme3.scene.VertexBuffer; +import com.jme3.scene.VertexBuffer.Format; +import com.jme3.scene.VertexBuffer.Usage; +import com.jme3.texture.Texture.Type; +import com.jme3.util.BufferUtils; + +/** + * This class is used for UV coordinates generation. + * @author Marcin Roguski (Kaelthas) + */ +public class UVCoordinatesGenerator { + private static final Logger LOGGER = Logger.getLogger(UVCoordinatesGenerator.class.getName()); + + public static final int TEXCO_ORCO = 1; + public static final int TEXCO_REFL = 2; + public static final int TEXCO_NORM = 4; + public static final int TEXCO_GLOB = 8; + public static final int TEXCO_UV = 16; + public static final int TEXCO_OBJECT = 32; + public static final int TEXCO_LAVECTOR = 64; + public static final int TEXCO_VIEW = 128; + public static final int TEXCO_STICKY = 256; + public static final int TEXCO_OSA = 512; + public static final int TEXCO_WINDOW = 1024; + public static final int NEED_UV = 2048; + public static final int TEXCO_TANGENT = 4096; + // still stored in vertex->accum, 1 D + public static final int TEXCO_PARTICLE_OR_STRAND = 8192; // strand is used + // for normal + // materials, + // particle for halo + // materials + public static final int TEXCO_STRESS = 16384; + public static final int TEXCO_SPEED = 32768; + + /** + * This method generates UV coordinates for the given geometries. + * @param texco + * texture coordinates type + * @param textureType + * the type of the texture (only 2D and 3D) + * @param geometries + * a list of geometries that will have coordinates applied + */ + public static void generateUVCoordinates(int texco, Type textureType, List geometries) { + for (Geometry geometry : geometries) { + UVCoordinatesGenerator.generateUVCoordinates(texco, textureType, geometry.getMesh()); + } + } + + /** + * This method generates UV coordinates for the given mesh. + * @param texco + * texture coordinates type + * @param textureType + * the type of the texture (only 2D and 3D) + * @param mesh + * a mesh that will have coordinates applied + */ + public static void generateUVCoordinates(int texco, Type textureType, Mesh mesh) { + VertexBuffer result = null; + switch (texco) { + case TEXCO_ORCO: + if (textureType == Type.TwoDimensional) { + + } else if (textureType == Type.ThreeDimensional) { + BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(mesh); + + result = new VertexBuffer(com.jme3.scene.VertexBuffer.Type.TexCoord); + FloatBuffer positions = mesh.getFloatBuffer(com.jme3.scene.VertexBuffer.Type.Position); + float[] uvCoordinates = BufferUtils.getFloatArray(positions); + Vector3f min = bb.getMin(null); + float[] ext = new float[] { bb.getXExtent() * 2, bb.getYExtent() * 2, bb.getZExtent() * 2 }; + + // now transform the coordinates so that they are in the range of <0; 1> + for (int i = 0; i < uvCoordinates.length; i += 3) { + uvCoordinates[i] = (uvCoordinates[i] - min.x) / ext[0]; + uvCoordinates[i + 1] = (uvCoordinates[i + 1] - min.y) / ext[1]; + uvCoordinates[i + 2] = (uvCoordinates[i + 2] - min.z) / ext[2]; + } + + result.setupData(Usage.Static, 3, Format.Float, BufferUtils.createFloatBuffer(uvCoordinates)); + } else { + throw new IllegalStateException("Unsupported texture type: " + textureType); + } + break; + case TEXCO_GLOB: + + break; + case TEXCO_TANGENT: + + break; + case TEXCO_UV: + break; + case TEXCO_STRESS: + + break; + case TEXCO_NORM: + + break; + case TEXCO_LAVECTOR: + case TEXCO_OBJECT: + case TEXCO_OSA: + case TEXCO_PARTICLE_OR_STRAND: + case TEXCO_REFL: + case TEXCO_SPEED: + case TEXCO_STICKY: + case TEXCO_VIEW: + case TEXCO_WINDOW: + LOGGER.warning("Texture coordinates type not currently supported: " + texco); + break; + default: + throw new IllegalStateException("Unknown texture coordinates value: " + texco); + } + + mesh.clearBuffer(VertexBuffer.Type.TexCoord);// in case there are coordinates already set + mesh.setBuffer(result); + } + + /** + * Flat projection for 2D textures. + * @param mesh + * mesh that is to be projected + * @return UV coordinates after the projection + */ + public Vector2f[] flatProjection(Mesh mesh) { + return null;// TODO: implement + } + + /** + * Cube projection for 2D textures. + * @param mesh + * mesh that is to be projected + * @return UV coordinates after the projection + */ + public Vector2f[] cubeProjection(Mesh mesh) { + return null;// TODO: implement + } + + /** + * Tube projection for 2D textures. + * @param mesh + * mesh that is to be projected + * @return UV coordinates after the projection + */ + + public Vector2f[] tubeProjection(Mesh mesh) { + return null;// TODO: implement + } + + /** + * Sphere projection for 2D textures. + * @param mesh + * mesh that is to be projected + * @return UV coordinates after the projection + */ + public Vector2f[] sphereProjection(Mesh mesh) { + return null;// TODO: implement + // Vector2f[] uvTable = new Vector2f[vertexList.size()]; + // Ray ray = new Ray(); + // CollisionResults cr = new CollisionResults(); + // Vector3f yVec = new Vector3f(); + // Vector3f zVec = new Vector3f(); + // for(Geometry geom : geometries) { + // if(materialHelper.hasTexture(geom.getMaterial())) {//generate only when material has a texture + // geom.getMesh().updateBound(); + // BoundingSphere bs = this.getBoundingSphere(geom.getMesh()); + // float r2 = bs.getRadius() * bs.getRadius(); + // yVec.set(0, -bs.getRadius(), 0); + // zVec.set(0, 0, -bs.getRadius()); + // Vector3f center = bs.getCenter(); + // ray.setOrigin(center); + // //we cast each vertex of the current mesh on the bounding box to determine the UV-coordinates + // for(int i=0;i geometries) { + BoundingBox result = null; + for (Geometry geometry : geometries) { + BoundingBox bb = UVCoordinatesGenerator.getBoundingBox(geometry.getMesh()); + if (result == null) { + result = bb; + } else { + result.merge(bb); + } + } + return result; + } + + /** + * This method returns the bounding box of the given mesh. + * @param mesh + * the mesh + * @return bounding box of the given mesh + */ + private static BoundingBox getBoundingBox(Mesh mesh) { + mesh.updateBound(); + BoundingVolume bv = mesh.getBound(); + if (bv instanceof BoundingBox) { + return (BoundingBox) bv; + } else if (bv instanceof BoundingSphere) { + BoundingSphere bs = (BoundingSphere) bv; + float r = bs.getRadius(); + return new BoundingBox(bs.getCenter(), r, r, r); + } else { + throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName()); + } + } + + /** + * This method returns the bounding sphere of the given geometries. + * @param geometries + * the list of geometries + * @return bounding spheres of the given geometries + */ + private static BoundingSphere getBoundingSphere(List geometries) { + BoundingSphere result = null; + for (Geometry geometry : geometries) { + BoundingSphere bs = UVCoordinatesGenerator.getBoundingSphere(geometry.getMesh()); + if (result == null) { + result = bs; + } else { + result.merge(bs); + } + } + return result; + } + + /** + * This method returns the bounding sphere of the given mesh. + * @param mesh + * the mesh + * @return bounding sphere of the given mesh + */ + private static BoundingSphere getBoundingSphere(Mesh mesh) { + mesh.updateBound(); + BoundingVolume bv = mesh.getBound(); + if (bv instanceof BoundingBox) { + BoundingBox bb = (BoundingBox) bv; + float r = Math.max(bb.getXExtent(), bb.getYExtent()); + r = Math.max(r, bb.getZExtent()); + return new BoundingSphere(r, bb.getCenter()); + } else if (bv instanceof BoundingSphere) { + return (BoundingSphere) bv; + } else { + throw new IllegalStateException("Unknown bounding volume type: " + bv.getClass().getName()); + } + } +}