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
This commit is contained in:
parent
cc27b5bcf6
commit
d6574a8cc7
@ -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.
|
||||
|
@ -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);
|
||||
}
|
@ -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<Structure> mTexs;
|
||||
public final List<Structure> 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<Structure>();
|
||||
textures = new ArrayList<Structure>();
|
||||
DynamicArray<Pointer> mtexsArray = (DynamicArray<Pointer>) 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);
|
||||
}
|
||||
}
|
||||
}
|
@ -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<String, Texture> texturesMap = new HashMap<String, Texture>();
|
||||
Type firstTextureType = null;
|
||||
if ((dataRepository.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.TEXTURES) != 0) {
|
||||
TextureHelper textureHelper = dataRepository.getHelper(TextureHelper.class);
|
||||
DynamicArray<Pointer> mtexs = (DynamicArray<Pointer>) 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<Structure> 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;
|
||||
for (int i=0;i<materialContext.texturesCount;++i) {
|
||||
Structure mtex = materialContext.mTexs.get(i);
|
||||
|
||||
int texflag = ((Number) mtex.getFieldValue("texflag")).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);
|
||||
}
|
||||
int mapto = ((Number) mtex.getFieldValue("mapto")).intValue();
|
||||
if (mapto != 0) {
|
||||
Structure tex = materialContext.textures.get(i);
|
||||
Texture texture = textureHelper.getTexture(tex, dataRepository);
|
||||
if (texture != null) {
|
||||
if(firstTextureType == null) {
|
||||
firstTextureType = texture.getType();
|
||||
} else if(firstTextureType != texture.getType()) {
|
||||
LOGGER.warning("The texture with the name: " + texture.getName() + " is of different type than the first applied texture! It will not be applied!");
|
||||
continue;
|
||||
}
|
||||
|
||||
// NOTE: Enable mipmaps FOR ALL TEXTURES EVER
|
||||
texture.setMinFilter(MinFilter.Trilinear);
|
||||
//TODO: textures merging
|
||||
if ((mapto & 0x01) != 0) {// Col
|
||||
// Map to COLOR channel or DIFFUSE
|
||||
// Set diffuse to white so it doesn't get multiplied by texture
|
||||
// result.setColor(shadeless ? "Color" : "Diffuse", ColorRGBA.White.clone());
|
||||
// result.setBoolean("UseMaterialColors", Boolean.FALSE);
|
||||
// blending the texture with material color and texture's defined color
|
||||
int blendType = ((Number) mtex.getFieldValue("blendtype")).intValue();
|
||||
float[] color = new float[] { ((Number) mtex.getFieldValue("r")).floatValue(), ((Number) mtex.getFieldValue("g")).floatValue(), ((Number) mtex.getFieldValue("b")).floatValue() };
|
||||
float colfac = ((Number) mtex.getFieldValue("colfac")).floatValue();
|
||||
texture = textureHelper.blendTexture(new float[] {1, 1, 1}, texture, color, colfac, blendType, negateTexture, dataRepository);
|
||||
texture.setWrap(WrapMode.Repeat);
|
||||
|
||||
if (materialContext.shadeless) {
|
||||
texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_COLOR, texture);
|
||||
} else {
|
||||
LOGGER.log(Level.WARNING, "Texture not found!");
|
||||
texturesMap.put(firstTextureType==Type.ThreeDimensional ? TEXTURE_TYPE_3D : TEXTURE_TYPE_DIFFUSE, texture);
|
||||
}
|
||||
}
|
||||
// } else {
|
||||
// Pointer pTex = (Pointer)textureLink.getFieldValue("tex");
|
||||
// List<Structure> texs = pTex.fetchData(dataRepository.getInputStream());
|
||||
// Structure tex = texs.get(0);
|
||||
// LOGGER.log(Level.WARNING, "Unsupported texture type: " + texco);
|
||||
// }
|
||||
if(firstTextureType == Type.TwoDimensional) {//for now other mappings available for images only
|
||||
if ((mapto & 0x02) != 0 && !materialContext.shadeless) {// Nor
|
||||
Texture normalMapTexture;
|
||||
if (texture.getKey() instanceof GeneratedTextureKey) {
|
||||
normalMapTexture = textureHelper.convertToNormalMapTexture(texture, ((Number) mtex.getFieldValue("norfac")).floatValue());
|
||||
normalMapTexture.setMinFilter(MinFilter.Trilinear);
|
||||
} else {
|
||||
normalMapTexture = texture;
|
||||
}
|
||||
texturesMap.put(TEXTURE_TYPE_NORMAL, normalMapTexture);
|
||||
}
|
||||
if ((mapto & 0x04) != 0 && !materialContext.shadeless) {// Spec
|
||||
// Map to SPECULAR
|
||||
texturesMap.put(TEXTURE_TYPE_SPECULAR, texture);
|
||||
}
|
||||
if ((mapto & 0x40) != 0) {// Emit
|
||||
texturesMap.put(TEXTURE_TYPE_GLOW, texture);
|
||||
}
|
||||
if ((mapto & 0x80) != 0 && !materialContext.shadeless) {// Alpha
|
||||
texturesMap.put(TEXTURE_TYPE_ALPHA, texture);
|
||||
}
|
||||
} else {
|
||||
LOGGER.warning("The following mappings: [Nor, Spec, Alpha] are available for 2D textures only!");
|
||||
}
|
||||
} 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<String, Texture> 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_COLOR) != null) {
|
||||
if (material.getTextureParam(TEXTURE_TYPE_ALPHA) != null) {
|
||||
return true;
|
||||
}
|
||||
if(material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) {
|
||||
if (material.getTextureParam(TEXTURE_TYPE_COLOR) != null) {
|
||||
return true;
|
||||
}
|
||||
if(material.getTextureParam(TEXTURE_TYPE_GLOW) != null) {
|
||||
if (material.getTextureParam(TEXTURE_TYPE_DIFFUSE) != null) {
|
||||
return true;
|
||||
}
|
||||
if(material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) {
|
||||
if (material.getTextureParam(TEXTURE_TYPE_GLOW) != null) {
|
||||
return true;
|
||||
}
|
||||
if(material.getTextureParam(TEXTURE_TYPE_SPECULAR) != null) {
|
||||
if (material.getTextureParam(TEXTURE_TYPE_NORMAL) != null) {
|
||||
return true;
|
||||
}
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
@ -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<Integer, List<Integer>> meshesMap = new HashMap<Integer, List<Integer>>();
|
||||
Pointer pMFace = (Pointer) structure.getFieldValue("mface");
|
||||
List<Structure> mFaces = null;
|
||||
if (pMFace.isNotNull()){
|
||||
mFaces = pMFace.fetchData(dataRepository.getInputStream());
|
||||
}
|
||||
List<Structure> mFaces = null;
|
||||
if (pMFace.isNotNull()){
|
||||
mFaces = pMFace.fetchData(dataRepository.getInputStream());
|
||||
if(mFaces==null || mFaces.size()==0) {
|
||||
return new ArrayList<Geometry>(0);
|
||||
}
|
||||
}
|
||||
|
||||
Pointer pMTFace = (Pointer) structure.getFieldValue("mtface");
|
||||
List<Vector2f> 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<Vector2f>();// TODO: calculate the amount of coordinates if possible
|
||||
uvCoordinates = new ArrayList<Vector2f>();
|
||||
}
|
||||
|
||||
// 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<Integer, List<Integer>> vertexReferenceMap = new HashMap<Integer, List<Integer>>(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<geom.getMesh().getIndexBuffer().size();++i) {
|
||||
int index = geom.getMesh().getIndexBuffer().get(i);
|
||||
|
||||
ray.setOrigin(vertexList.get(index));
|
||||
ray.setDirection(normalList.get(index));
|
||||
|
||||
//finding collision point
|
||||
cr.clear();
|
||||
bs.collideWith(ray, cr);//there is ALWAYS one collision
|
||||
Vector3f p = cr.getCollision(0).getContactPoint();
|
||||
p.subtractLocal(center);
|
||||
//arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r <- an arc length on the sphere (from top to the point on the sphere)
|
||||
//but yVec.length == r and p.length == r so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
|
||||
//U coordinate is as follows: u = arcLength / PI*r
|
||||
//so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
|
||||
float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
|
||||
//we use similiar method to compute v
|
||||
//the only difference is that we need to cast the p vector on ZX plane
|
||||
//and use its length instead of r
|
||||
p.y = 0;
|
||||
float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
|
||||
uvTable[index] = new Vector2f(u, v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//creating and applying the buffer
|
||||
uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
|
||||
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvTable));
|
||||
for(Geometry geom : geometries) {
|
||||
geom.getMesh().setBuffer(uvCoordsBuffer);
|
||||
}
|
||||
} else {//TODO: get the proper texture coordinates type
|
||||
UVCoordinatesGenerator.generateUVCoordinates(UVCoordinatesGenerator.TEXCO_ORCO,
|
||||
com.jme3.texture.Texture.Type.ThreeDimensional, geometries);
|
||||
}
|
||||
|
||||
dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
||||
@ -550,8 +504,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
||||
public Vector3f[] getVertices(Structure meshStructure, DataRepository dataRepository) throws BlenderFileException {
|
||||
int verticesAmount = ((Number) meshStructure.getFieldValue("totvert")).intValue();
|
||||
Vector3f[] vertices = new Vector3f[verticesAmount];
|
||||
if (verticesAmount == 0)
|
||||
return vertices;
|
||||
if (verticesAmount == 0) {
|
||||
return vertices;
|
||||
}
|
||||
|
||||
Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
|
||||
List<Structure> mVerts = pMVert.fetchData(dataRepository.getInputStream());
|
||||
|
@ -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.
|
||||
*
|
||||
|
@ -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];
|
||||
}
|
||||
for (int k = -halfD; k < halfD; ++k) {
|
||||
texvec[2] = dDelta * k;
|
||||
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;
|
||||
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 */
|
||||
}
|
||||
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 {
|
||||
texres.tin *= texres.tin;
|
||||
noiseGenerator.brightnesAndContrast(texres, contrast, brightness);
|
||||
data.put((byte) (texres.tin * 255.0f));
|
||||
}
|
||||
} 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 */
|
||||
}
|
||||
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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(Format.ABGR8, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(1);
|
||||
dataArray.add(data);
|
||||
return new Texture3D(new Image(format, width, height, depth, dataArray));
|
||||
}
|
||||
}
|
||||
|
@ -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<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -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<Geometry> 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<geom.getMesh().getIndexBuffer().size();++i) {
|
||||
// int index = geom.getMesh().getIndexBuffer().get(i);
|
||||
//
|
||||
// ray.setOrigin(vertexList.get(index));
|
||||
// ray.setDirection(normalList.get(index));
|
||||
//
|
||||
// //finding collision point
|
||||
// cr.clear();
|
||||
// bs.collideWith(ray, cr);//there is ALWAYS one collision
|
||||
// Vector3f p = cr.getCollision(0).getContactPoint();
|
||||
// p.subtractLocal(center);
|
||||
// //arcLength = FastMath.acos(p.dot(yVec)/(p.length * yVec.length)) * r <- an arc length on the sphere (from top to the point on
|
||||
// the sphere)
|
||||
// //but yVec.length == r and p.length == r so: arcLength = FastMath.acos(p.dot(yVec)/r^2)/r
|
||||
// //U coordinate is as follows: u = arcLength / PI*r
|
||||
// //so to compute it faster we just write: u = FastMath.acos(p.dot(yVec)/r^2) / PI;
|
||||
// float u = FastMath.acos(p.dot(yVec)/r2) / FastMath.PI;
|
||||
// //we use similiar method to compute v
|
||||
// //the only difference is that we need to cast the p vector on ZX plane
|
||||
// //and use its length instead of r
|
||||
// p.y = 0;
|
||||
// float v = FastMath.acos(p.dot(zVec)/(bs.getRadius()*p.length())) / FastMath.PI;
|
||||
// uvTable[index] = new Vector2f(u, v);
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the bounding box of the given geometries.
|
||||
* @param geometries
|
||||
* the list of geometries
|
||||
* @return bounding box of the given geometries
|
||||
*/
|
||||
private static BoundingBox getBoundingBox(List<Geometry> 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<Geometry> 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());
|
||||
}
|
||||
}
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user