Refactoring: tabs replaced by spaces in blender importer sources. (4 spaces for each tab)
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@10401 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
9f4544a3a8
commit
ecc8d8387b
@ -100,7 +100,7 @@ public class BlenderKey extends ModelKey {
|
|||||||
protected int layersToLoad = -1;
|
protected int layersToLoad = -1;
|
||||||
/** A variable that toggles the object custom properties loading. */
|
/** A variable that toggles the object custom properties loading. */
|
||||||
protected boolean loadObjectProperties = true;
|
protected boolean loadObjectProperties = true;
|
||||||
/** Maximum texture size. Might be dependant on the graphic card.*/
|
/** Maximum texture size. Might be dependant on the graphic card. */
|
||||||
protected int maxTextureSize = -1;
|
protected int maxTextureSize = -1;
|
||||||
/** Allows to toggle generated textures loading. Disabled by default because it very often takes too much memory and needs to be used wisely. */
|
/** Allows to toggle generated textures loading. Disabled by default because it very often takes too much memory and needs to be used wisely. */
|
||||||
protected boolean loadGeneratedTextures;
|
protected boolean loadGeneratedTextures;
|
||||||
@ -110,7 +110,8 @@ public class BlenderKey extends ModelKey {
|
|||||||
/**
|
/**
|
||||||
* Constructor used by serialization mechanisms.
|
* Constructor used by serialization mechanisms.
|
||||||
*/
|
*/
|
||||||
public BlenderKey() {}
|
public BlenderKey() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Creates a key for the given file name.
|
* Constructor. Creates a key for the given file name.
|
||||||
@ -175,7 +176,8 @@ public class BlenderKey extends ModelKey {
|
|||||||
/**
|
/**
|
||||||
* This method sets the properies loading policy.
|
* This method sets the properies loading policy.
|
||||||
* By default the value is true.
|
* By default the value is true.
|
||||||
* @param loadObjectProperties true to load properties and false to suspend their loading
|
* @param loadObjectProperties
|
||||||
|
* true to load properties and false to suspend their loading
|
||||||
*/
|
*/
|
||||||
public void setLoadObjectProperties(boolean loadObjectProperties) {
|
public void setLoadObjectProperties(boolean loadObjectProperties) {
|
||||||
this.loadObjectProperties = loadObjectProperties;
|
this.loadObjectProperties = loadObjectProperties;
|
||||||
@ -192,11 +194,11 @@ public class BlenderKey extends ModelKey {
|
|||||||
* @return maximum texture size (width/height)
|
* @return maximum texture size (width/height)
|
||||||
*/
|
*/
|
||||||
public int getMaxTextureSize() {
|
public int getMaxTextureSize() {
|
||||||
if(maxTextureSize <= 0) {
|
if (maxTextureSize <= 0) {
|
||||||
try {
|
try {
|
||||||
maxTextureSize = GL11.glGetInteger(GL11.GL_MAX_TEXTURE_SIZE);
|
maxTextureSize = GL11.glGetInteger(GL11.GL_MAX_TEXTURE_SIZE);
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
//this is in case this method was called before openGL initialization
|
// this is in case this method was called before openGL initialization
|
||||||
return 8192;
|
return 8192;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -205,7 +207,8 @@ public class BlenderKey extends ModelKey {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the maximum texture size.
|
* This method sets the maximum texture size.
|
||||||
* @param maxTextureSize the maximum texture size
|
* @param maxTextureSize
|
||||||
|
* the maximum texture size
|
||||||
*/
|
*/
|
||||||
public void setMaxTextureSize(int maxTextureSize) {
|
public void setMaxTextureSize(int maxTextureSize) {
|
||||||
this.maxTextureSize = maxTextureSize;
|
this.maxTextureSize = maxTextureSize;
|
||||||
@ -213,7 +216,8 @@ public class BlenderKey extends ModelKey {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the flag that toggles the generated textures loading.
|
* This method sets the flag that toggles the generated textures loading.
|
||||||
* @param loadGeneratedTextures <b>true</b> if generated textures should be loaded and <b>false</b> otherwise
|
* @param loadGeneratedTextures
|
||||||
|
* <b>true</b> if generated textures should be loaded and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
public void setLoadGeneratedTextures(boolean loadGeneratedTextures) {
|
public void setLoadGeneratedTextures(boolean loadGeneratedTextures) {
|
||||||
this.loadGeneratedTextures = loadGeneratedTextures;
|
this.loadGeneratedTextures = loadGeneratedTextures;
|
||||||
@ -323,7 +327,8 @@ public class BlenderKey extends ModelKey {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the generated textures resolution.
|
* This method sets the generated textures resolution.
|
||||||
* @param generatedTexturePPU the generated textures resolution
|
* @param generatedTexturePPU
|
||||||
|
* the generated textures resolution
|
||||||
*/
|
*/
|
||||||
public void setGeneratedTexturePPU(int generatedTexturePPU) {
|
public void setGeneratedTexturePPU(int generatedTexturePPU) {
|
||||||
this.generatedTexturePPU = generatedTexturePPU;
|
this.generatedTexturePPU = generatedTexturePPU;
|
||||||
@ -401,7 +406,7 @@ public class BlenderKey extends ModelKey {
|
|||||||
oc.write(defaultMaterial, "default-material", null);
|
oc.write(defaultMaterial, "default-material", null);
|
||||||
oc.write(faceCullMode, "face-cull-mode", FaceCullMode.Off);
|
oc.write(faceCullMode, "face-cull-mode", FaceCullMode.Off);
|
||||||
oc.write(layersToLoad, "layers-to-load", -1);
|
oc.write(layersToLoad, "layers-to-load", -1);
|
||||||
oc.write(mipmapGenerationMethod , "mipmap-generation-method", MipmapGenerationMethod.GENERATE_WHEN_NEEDED);
|
oc.write(mipmapGenerationMethod, "mipmap-generation-method", MipmapGenerationMethod.GENERATE_WHEN_NEEDED);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -496,16 +501,11 @@ public class BlenderKey extends ModelKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This enum tells the importer if the mipmaps for textures will be generated by jme.
|
* This enum tells the importer if the mipmaps for textures will be generated by jme. <li>NEVER_GENERATE and ALWAYS_GENERATE are quite understandable <li>GENERATE_WHEN_NEEDED is an option that checks if the texture had 'Generate mipmaps' option set in blender, mipmaps are generated only when the option is set
|
||||||
* <li> NEVER_GENERATE and ALWAYS_GENERATE are quite understandable
|
|
||||||
* <li> GENERATE_WHEN_NEEDED is an option that checks if the texture had 'Generate mipmaps' option set
|
|
||||||
* in blender, mipmaps are generated only when the option is set
|
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public static enum MipmapGenerationMethod {
|
public static enum MipmapGenerationMethod {
|
||||||
NEVER_GENERATE,
|
NEVER_GENERATE, ALWAYS_GENERATE, GENERATE_WHEN_NEEDED;
|
||||||
ALWAYS_GENERATE,
|
|
||||||
GENERATE_WHEN_NEEDED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -543,7 +543,7 @@ public class BlenderKey extends ModelKey {
|
|||||||
/** Animations of all objects. */
|
/** Animations of all objects. */
|
||||||
private List<AnimData> animations;
|
private List<AnimData> animations;
|
||||||
/** All cameras from the file. */
|
/** All cameras from the file. */
|
||||||
private List<CameraNode>cameras;
|
private List<CameraNode> cameras;
|
||||||
/** All lights from the file. */
|
/** All lights from the file. */
|
||||||
private List<LightNode> lights;
|
private List<LightNode> lights;
|
||||||
|
|
||||||
@ -714,10 +714,12 @@ public class BlenderKey extends ModelKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void updateModelBound() {}
|
public void updateModelBound() {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setModelBound(BoundingVolume modelBound) {}
|
public void setModelBound(BoundingVolume modelBound) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getVertexCount() {
|
public int getVertexCount() {
|
||||||
@ -735,10 +737,12 @@ public class BlenderKey extends ModelKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void depthFirstTraversal(SceneGraphVisitor visitor) {}
|
public void depthFirstTraversal(SceneGraphVisitor visitor) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue) {}
|
protected void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,8 @@ public class GeneratedTextureKey extends TextureKey {
|
|||||||
* Constructor. Stores the name. Extension and folder name are empty
|
* Constructor. Stores the name. Extension and folder name are empty
|
||||||
* strings.
|
* strings.
|
||||||
*
|
*
|
||||||
* @param name the name of the texture
|
* @param name
|
||||||
|
* the name of the texture
|
||||||
*/
|
*/
|
||||||
public GeneratedTextureKey(String name) {
|
public GeneratedTextureKey(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
|
@ -68,7 +68,7 @@ public abstract class AbstractBlenderHelper {
|
|||||||
public AbstractBlenderHelper(String blenderVersion, boolean fixUpAxis) {
|
public AbstractBlenderHelper(String blenderVersion, boolean fixUpAxis) {
|
||||||
this.blenderVersion = Integer.parseInt(blenderVersion);
|
this.blenderVersion = Integer.parseInt(blenderVersion);
|
||||||
this.fixUpAxis = fixUpAxis;
|
this.fixUpAxis = fixUpAxis;
|
||||||
if(fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
upAxisRotationQuaternion = new Quaternion().fromAngles(-FastMath.HALF_PI, 0, 0);
|
upAxisRotationQuaternion = new Quaternion().fromAngles(-FastMath.HALF_PI, 0, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -76,7 +76,8 @@ public abstract class AbstractBlenderHelper {
|
|||||||
/**
|
/**
|
||||||
* This method clears the state of the helper so that it can be used for different calculations of another feature.
|
* This method clears the state of the helper so that it can be used for different calculations of another feature.
|
||||||
*/
|
*/
|
||||||
public void clearState() {}
|
public void clearState() {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should be used to check if the text is blank. Avoid using text.trim().length()==0. This causes that more strings are
|
* This method should be used to check if the text is blank. Avoid using text.trim().length()==0. This causes that more strings are
|
||||||
@ -133,20 +134,19 @@ public abstract class AbstractBlenderHelper {
|
|||||||
*/
|
*/
|
||||||
protected void applyProperties(Spatial spatial, Properties properties) {
|
protected void applyProperties(Spatial spatial, Properties properties) {
|
||||||
List<String> propertyNames = properties.getSubPropertiesNames();
|
List<String> propertyNames = properties.getSubPropertiesNames();
|
||||||
if(propertyNames != null && propertyNames.size() > 0) {
|
if (propertyNames != null && propertyNames.size() > 0) {
|
||||||
for(String propertyName : propertyNames) {
|
for (String propertyName : propertyNames) {
|
||||||
Object value = properties.findValue(propertyName);
|
Object value = properties.findValue(propertyName);
|
||||||
if(value instanceof Savable || value instanceof Boolean || value instanceof String ||
|
if (value instanceof Savable || value instanceof Boolean || value instanceof String || value instanceof Float || value instanceof Integer || value instanceof Long) {
|
||||||
value instanceof Float || value instanceof Integer || value instanceof Long) {
|
|
||||||
spatial.setUserData(propertyName, value);
|
spatial.setUserData(propertyName, value);
|
||||||
} else if(value instanceof Double) {
|
} else if (value instanceof Double) {
|
||||||
spatial.setUserData(propertyName, ((Double) value).floatValue());
|
spatial.setUserData(propertyName, ((Double) value).floatValue());
|
||||||
} else if(value instanceof int[]) {
|
} else if (value instanceof int[]) {
|
||||||
spatial.setUserData(propertyName, Arrays.toString((int[])value));
|
spatial.setUserData(propertyName, Arrays.toString((int[]) value));
|
||||||
} else if(value instanceof float[]) {
|
} else if (value instanceof float[]) {
|
||||||
spatial.setUserData(propertyName, Arrays.toString((float[])value));
|
spatial.setUserData(propertyName, Arrays.toString((float[]) value));
|
||||||
} else if(value instanceof double[]) {
|
} else if (value instanceof double[]) {
|
||||||
spatial.setUserData(propertyName, Arrays.toString((double[])value));
|
spatial.setUserData(propertyName, Arrays.toString((double[]) value));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
* This class converts blender file blocks into jMonkeyEngine data structures.
|
* This class converts blender file blocks into jMonkeyEngine data structures.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/* package */ abstract class AbstractBlenderLoader implements AssetLoader {
|
/* package */abstract class AbstractBlenderLoader implements AssetLoader {
|
||||||
private static final Logger LOGGER = Logger.getLogger(AbstractBlenderLoader.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(AbstractBlenderLoader.class.getName());
|
||||||
|
|
||||||
protected BlenderContext blenderContext;
|
protected BlenderContext blenderContext;
|
||||||
@ -74,14 +74,14 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
}
|
}
|
||||||
Node result = new Node(structure.getName());
|
Node result = new Node(structure.getName());
|
||||||
try {
|
try {
|
||||||
List<Structure> base = ((Structure)structure.getFieldValue("base")).evaluateListBase(blenderContext);
|
List<Structure> base = ((Structure) structure.getFieldValue("base")).evaluateListBase(blenderContext);
|
||||||
for(Structure b : base) {
|
for (Structure b : base) {
|
||||||
Pointer pObject = (Pointer) b.getFieldValue("object");
|
Pointer pObject = (Pointer) b.getFieldValue("object");
|
||||||
if(pObject.isNotNull()) {
|
if (pObject.isNotNull()) {
|
||||||
Structure objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0);
|
Structure objectStructure = pObject.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
Object object = this.toObject(objectStructure);
|
Object object = this.toObject(objectStructure);
|
||||||
if(object instanceof LightNode && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
if (object instanceof LightNode && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
||||||
result.addLight(((LightNode)object).getLight());
|
result.addLight(((LightNode) object).getLight());
|
||||||
result.attachChild((LightNode) object);
|
result.attachChild((LightNode) object);
|
||||||
} else if (object instanceof Node && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
} else if (object instanceof Node && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
||||||
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
||||||
@ -153,19 +153,19 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
// * This method converts the given structure to a material.
|
// * This method converts the given structure to a material.
|
||||||
// * @param structure
|
// * @param structure
|
||||||
// * structure of a material
|
// * structure of a material
|
||||||
// * @return material's node
|
// * @return material's node
|
||||||
// */
|
// */
|
||||||
// public Material toMaterial(Structure structure) throws BlenderFileException {
|
// public Material toMaterial(Structure structure) throws BlenderFileException {
|
||||||
// MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
// MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
||||||
// if (materialHelper.shouldBeLoaded(structure, blenderContext)) {
|
// if (materialHelper.shouldBeLoaded(structure, blenderContext)) {
|
||||||
// return materialHelper.toMaterial(structure, blenderContext);
|
// return materialHelper.toMaterial(structure, blenderContext);
|
||||||
// }
|
// }
|
||||||
// return null;
|
// return null;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the data read from the WORLD file block. The block contains data that can be stored as
|
* This method returns the data read from the WORLD file block. The block contains data that can be stored as
|
||||||
|
@ -175,6 +175,7 @@ public class BlenderContext {
|
|||||||
public DnaBlockData getDnaBlockData() {
|
public DnaBlockData getDnaBlockData() {
|
||||||
return dnaBlockData;
|
return dnaBlockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the scene structure data.
|
* This method sets the scene structure data.
|
||||||
*
|
*
|
||||||
@ -515,7 +516,7 @@ public class BlenderContext {
|
|||||||
*/
|
*/
|
||||||
public List<Constraint> getAllConstraints() {
|
public List<Constraint> getAllConstraints() {
|
||||||
List<Constraint> result = new ArrayList<Constraint>();
|
List<Constraint> result = new ArrayList<Constraint>();
|
||||||
for(Entry<Long, List<Constraint>> entry : constraints.entrySet()) {
|
for (Entry<Long, List<Constraint>> entry : constraints.entrySet()) {
|
||||||
result.addAll(entry.getValue());
|
result.addAll(entry.getValue());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -625,9 +626,9 @@ public class BlenderContext {
|
|||||||
* @return found bone or null if none bone of a given name exists
|
* @return found bone or null if none bone of a given name exists
|
||||||
*/
|
*/
|
||||||
public BoneContext getBoneByName(String name) {
|
public BoneContext getBoneByName(String name) {
|
||||||
for(Entry<Long, BoneContext> entry : boneContexts.entrySet()) {
|
for (Entry<Long, BoneContext> entry : boneContexts.entrySet()) {
|
||||||
Bone bone = entry.getValue().getBone();
|
Bone bone = entry.getValue().getBone();
|
||||||
if(bone != null && name.equals(bone.getName())) {
|
if (bone != null && name.equals(bone.getName())) {
|
||||||
return entry.getValue();
|
return entry.getValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,22 +87,22 @@ public class BlenderLoader extends AbstractBlenderLoader {
|
|||||||
switch (block.getCode()) {
|
switch (block.getCode()) {
|
||||||
case FileBlockHeader.BLOCK_OB00:// Object
|
case FileBlockHeader.BLOCK_OB00:// Object
|
||||||
Object object = this.toObject(block.getStructure(blenderContext));
|
Object object = this.toObject(block.getStructure(blenderContext));
|
||||||
if(object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
if (object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
||||||
loadingResults.addLight((LightNode) object);
|
loadingResults.addLight((LightNode) object);
|
||||||
} else if (object instanceof CameraNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0) {
|
} else if (object instanceof CameraNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.CAMERAS) != 0) {
|
||||||
loadingResults.addCamera((CameraNode) object);
|
loadingResults.addCamera((CameraNode) object);
|
||||||
} else if (object instanceof Node && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
} else if (object instanceof Node && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
||||||
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
||||||
if (this.isRootObject(loadingResults, (Node)object)) {
|
if (this.isRootObject(loadingResults, (Node) object)) {
|
||||||
loadingResults.addObject((Node) object);
|
loadingResults.addObject((Node) object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
// case FileBlockHeader.BLOCK_MA00:// Material
|
// case FileBlockHeader.BLOCK_MA00:// Material
|
||||||
// if (blenderKey.isLoadUnlinkedAssets() && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
|
// if (blenderKey.isLoadUnlinkedAssets() && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.MATERIALS) != 0) {
|
||||||
// loadingResults.addMaterial(this.toMaterial(block.getStructure(blenderContext)));
|
// loadingResults.addMaterial(this.toMaterial(block.getStructure(blenderContext)));
|
||||||
// }
|
// }
|
||||||
// break;
|
// break;
|
||||||
case FileBlockHeader.BLOCK_SC00:// Scene
|
case FileBlockHeader.BLOCK_SC00:// Scene
|
||||||
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) {
|
if ((blenderKey.getFeaturesToLoad() & FeaturesToLoad.SCENES) != 0) {
|
||||||
sceneBlocks.add(block);
|
sceneBlocks.add(block);
|
||||||
@ -123,12 +123,12 @@ public class BlenderLoader extends AbstractBlenderLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//bake constraints after everything is loaded
|
// bake constraints after everything is loaded
|
||||||
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
||||||
constraintHelper.bakeConstraints(blenderContext);
|
constraintHelper.bakeConstraints(blenderContext);
|
||||||
|
|
||||||
//load the scene at the very end so that the root nodes have no parent during loading or constraints applying
|
// load the scene at the very end so that the root nodes have no parent during loading or constraints applying
|
||||||
for(FileBlockHeader sceneBlock : sceneBlocks) {
|
for (FileBlockHeader sceneBlock : sceneBlocks) {
|
||||||
loadingResults.addScene(this.toScene(sceneBlock.getStructure(blenderContext)));
|
loadingResults.addScene(this.toScene(sceneBlock.getStructure(blenderContext)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,11 +153,11 @@ public class BlenderLoader extends AbstractBlenderLoader {
|
|||||||
* <b>false</b> otherwise
|
* <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean isRootObject(LoadingResults loadingResults, Spatial spatial) {
|
protected boolean isRootObject(LoadingResults loadingResults, Spatial spatial) {
|
||||||
if(spatial.getParent() == null) {
|
if (spatial.getParent() == null) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
for(Node scene : loadingResults.getScenes()) {
|
for (Node scene : loadingResults.getScenes()) {
|
||||||
if(spatial.getParent().equals(scene)) {
|
if (spatial.getParent().equals(scene)) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,19 +65,19 @@ public class BlenderModelLoader extends BlenderLoader {
|
|||||||
if (block.getCode() == FileBlockHeader.BLOCK_OB00) {
|
if (block.getCode() == FileBlockHeader.BLOCK_OB00) {
|
||||||
Object object = this.toObject(block.getStructure(blenderContext));
|
Object object = this.toObject(block.getStructure(blenderContext));
|
||||||
|
|
||||||
if(object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
if (object instanceof LightNode && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.LIGHTS) != 0) {
|
||||||
modelRoot.addLight(((LightNode)object).getLight());
|
modelRoot.addLight(((LightNode) object).getLight());
|
||||||
modelRoot.attachChild((LightNode)object);
|
modelRoot.attachChild((LightNode) object);
|
||||||
} else if (object instanceof Node && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
} else if (object instanceof Node && (blenderKey.getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0) {
|
||||||
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
LOGGER.log(Level.FINE, "{0}: {1}--> {2}", new Object[] { ((Node) object).getName(), ((Node) object).getLocalTranslation().toString(), ((Node) object).getParent() == null ? "null" : ((Node) object).getParent().getName() });
|
||||||
if (((Node) object).getParent() == null) {
|
if (((Node) object).getParent() == null) {
|
||||||
modelRoot.attachChild((Node)object);
|
modelRoot.attachChild((Node) object);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//bake constraints after everything is loaded
|
// bake constraints after everything is loaded
|
||||||
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
||||||
constraintHelper.bakeConstraints(blenderContext);
|
constraintHelper.bakeConstraints(blenderContext);
|
||||||
|
|
||||||
|
@ -240,7 +240,7 @@ public class ArmatureHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
Bone bone = skeleton.getBone(boneIndex);
|
Bone bone = skeleton.getBone(boneIndex);
|
||||||
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
|
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
|
||||||
if(ipo != null) {
|
if (ipo != null) {
|
||||||
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalRotation(), 0, ipo.getLastFrame(), fps, false));
|
tracks.add((BoneTrack) ipo.calculateTrack(boneIndex, bone.getLocalRotation(), 0, ipo.getLastFrame(), fps, false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -95,7 +95,7 @@ public class BoneContext {
|
|||||||
this.boneStructure = boneStructure;
|
this.boneStructure = boneStructure;
|
||||||
this.armatureObjectOMA = armatureObjectOMA;
|
this.armatureObjectOMA = armatureObjectOMA;
|
||||||
boneName = boneStructure.getFieldValue("name").toString();
|
boneName = boneStructure.getFieldValue("name").toString();
|
||||||
length = ((Number)boneStructure.getFieldValue("length")).floatValue();
|
length = ((Number) boneStructure.getFieldValue("length")).floatValue();
|
||||||
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||||
armatureMatrix = objectHelper.getMatrix(boneStructure, "arm_mat", true);
|
armatureMatrix = objectHelper.getMatrix(boneStructure, "arm_mat", true);
|
||||||
|
|
||||||
|
@ -32,7 +32,7 @@ public class CalculationBone extends Node {
|
|||||||
this.startTranslation = bone.getModelSpacePosition().clone();
|
this.startTranslation = bone.getModelSpacePosition().clone();
|
||||||
this.startScale = bone.getModelSpaceScale().clone();
|
this.startScale = bone.getModelSpaceScale().clone();
|
||||||
this.reset();
|
this.reset();
|
||||||
if(boneFramesCount > 0) {
|
if (boneFramesCount > 0) {
|
||||||
this.translations = new Vector3f[boneFramesCount];
|
this.translations = new Vector3f[boneFramesCount];
|
||||||
this.rotations = new Quaternion[boneFramesCount];
|
this.rotations = new Quaternion[boneFramesCount];
|
||||||
this.scales = new Vector3f[boneFramesCount];
|
this.scales = new Vector3f[boneFramesCount];
|
||||||
@ -59,7 +59,7 @@ public class CalculationBone extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getBoneFramesCount() {
|
public int getBoneFramesCount() {
|
||||||
return this.translations==null ? 0 : this.translations.length;
|
return this.translations == null ? 0 : this.translations.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,7 +68,7 @@ public class CalculationBone extends Node {
|
|||||||
* to be 1 point up along Y axis (scale is applied if set to != 1.0);
|
* to be 1 point up along Y axis (scale is applied if set to != 1.0);
|
||||||
* @return the end point of this bone
|
* @return the end point of this bone
|
||||||
*/
|
*/
|
||||||
//TODO: set to Z axis if user defined it this way
|
// TODO: set to Z axis if user defined it this way
|
||||||
public Vector3f getEndPoint() {
|
public Vector3f getEndPoint() {
|
||||||
if (this.getParent() == null) {
|
if (this.getParent() == null) {
|
||||||
return new Vector3f(0, this.getLocalScale().y, 0);
|
return new Vector3f(0, this.getLocalScale().y, 0);
|
||||||
@ -111,7 +111,7 @@ public class CalculationBone extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void applyCalculatedTracks() {
|
public void applyCalculatedTracks() {
|
||||||
if(track != null) {
|
if (track != null) {
|
||||||
track.setKeyframes(track.getTimes(), translations, rotations, scales);
|
track.setKeyframes(track.getTimes(), translations, rotations, scales);
|
||||||
} else {
|
} else {
|
||||||
bone.setUserControl(true);
|
bone.setUserControl(true);
|
||||||
|
@ -151,14 +151,14 @@ public class Ipo {
|
|||||||
Vector3f[] scales = new Vector3f[framesAmount + 1];
|
Vector3f[] scales = new Vector3f[framesAmount + 1];
|
||||||
float[] scale = new float[] { 1.0f, 1.0f, 1.0f };
|
float[] scale = new float[] { 1.0f, 1.0f, 1.0f };
|
||||||
float degreeToRadiansFactor = 1;
|
float degreeToRadiansFactor = 1;
|
||||||
if(blenderVersion < 250) {//in blender earlier than 2.50 the values are stored in degrees
|
if (blenderVersion < 250) {// in blender earlier than 2.50 the values are stored in degrees
|
||||||
degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;// the values in blender are divided by 10, so we need to mult it here
|
degreeToRadiansFactor *= FastMath.DEG_TO_RAD * 10;// the values in blender are divided by 10, so we need to mult it here
|
||||||
}
|
}
|
||||||
|
|
||||||
// calculating track data
|
// calculating track data
|
||||||
for (int frame = startFrame; frame <= stopFrame; ++frame) {
|
for (int frame = startFrame; frame <= stopFrame; ++frame) {
|
||||||
int index = frame - startFrame;
|
int index = frame - startFrame;
|
||||||
times[index] = index * timeBetweenFrames;//start + (frame - 1) * timeBetweenFrames;
|
times[index] = index * timeBetweenFrames;// start + (frame - 1) * timeBetweenFrames;
|
||||||
for (int j = 0; j < bezierCurves.length; ++j) {
|
for (int j = 0; j < bezierCurves.length; ++j) {
|
||||||
double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE);
|
double value = bezierCurves[j].evaluate(frame, BezierCurve.Y_VALUE);
|
||||||
switch (bezierCurves[j].getType()) {
|
switch (bezierCurves[j].getType()) {
|
||||||
|
@ -175,7 +175,7 @@ public class IpoHelper extends AbstractBlenderHelper {
|
|||||||
* the constant value of this ipo
|
* the constant value of this ipo
|
||||||
*/
|
*/
|
||||||
public ConstIpo(float constValue) {
|
public ConstIpo(float constValue) {
|
||||||
super(null, false, 0);//the version is not important here
|
super(null, false, 0);// the version is not important here
|
||||||
this.constValue = constValue;
|
this.constValue = constValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,9 +67,9 @@ public class CameraHelper extends AbstractBlenderHelper {
|
|||||||
int width = DEFAULT_CAM_WIDTH;
|
int width = DEFAULT_CAM_WIDTH;
|
||||||
int height = DEFAULT_CAM_HEIGHT;
|
int height = DEFAULT_CAM_HEIGHT;
|
||||||
if (sceneStructure != null) {
|
if (sceneStructure != null) {
|
||||||
Structure renderData = (Structure)sceneStructure.getFieldValue("r");
|
Structure renderData = (Structure) sceneStructure.getFieldValue("r");
|
||||||
width = ((Number)renderData.getFieldValue("xsch")).shortValue();
|
width = ((Number) renderData.getFieldValue("xsch")).shortValue();
|
||||||
height = ((Number)renderData.getFieldValue("ysch")).shortValue();
|
height = ((Number) renderData.getFieldValue("ysch")).shortValue();
|
||||||
}
|
}
|
||||||
Camera camera = new Camera(width, height);
|
Camera camera = new Camera(width, height);
|
||||||
int type = ((Number) structure.getFieldValue("type")).intValue();
|
int type = ((Number) structure.getFieldValue("type")).intValue();
|
||||||
@ -77,9 +77,9 @@ public class CameraHelper extends AbstractBlenderHelper {
|
|||||||
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
|
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
|
||||||
type = 0;
|
type = 0;
|
||||||
}
|
}
|
||||||
//type==0 - perspective; type==1 - orthographic; perspective is used as default
|
// type==0 - perspective; type==1 - orthographic; perspective is used as default
|
||||||
camera.setParallelProjection(type == 1);
|
camera.setParallelProjection(type == 1);
|
||||||
float aspect = width / (float)height;
|
float aspect = width / (float) height;
|
||||||
float fovY; // Vertical field of view in degrees
|
float fovY; // Vertical field of view in degrees
|
||||||
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
|
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
|
||||||
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
|
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
|
||||||
@ -88,7 +88,7 @@ public class CameraHelper extends AbstractBlenderHelper {
|
|||||||
// Default sensor size prior to 2.60 was 32.
|
// Default sensor size prior to 2.60 was 32.
|
||||||
float sensor = 32.0f;
|
float sensor = 32.0f;
|
||||||
boolean sensorVertical = false;
|
boolean sensorVertical = false;
|
||||||
Number sensorFit = (Number)structure.getFieldValue("sensor_fit");
|
Number sensorFit = (Number) structure.getFieldValue("sensor_fit");
|
||||||
if (sensorFit != null) {
|
if (sensorFit != null) {
|
||||||
// If sensor_fit is vert (2), then sensor_y is used
|
// If sensor_fit is vert (2), then sensor_y is used
|
||||||
sensorVertical = sensorFit.byteValue() == 2;
|
sensorVertical = sensorFit.byteValue() == 2;
|
||||||
@ -131,7 +131,7 @@ public class CameraHelper extends AbstractBlenderHelper {
|
|||||||
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
|
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
|
||||||
type = 0;
|
type = 0;
|
||||||
}
|
}
|
||||||
//type==0 - perspective; type==1 - orthographic; perspective is used as default
|
// type==0 - perspective; type==1 - orthographic; perspective is used as default
|
||||||
camera.setParallelProjection(type == 1);
|
camera.setParallelProjection(type == 1);
|
||||||
float aspect = 0;
|
float aspect = 0;
|
||||||
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
|
float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
|
||||||
|
@ -26,7 +26,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
* Constraint applied on the bone.
|
* Constraint applied on the bone.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class BoneConstraint extends Constraint {
|
/* package */class BoneConstraint extends Constraint {
|
||||||
private static final Logger LOGGER = Logger.getLogger(BoneConstraint.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(BoneConstraint.class.getName());
|
||||||
|
|
||||||
protected boolean isNodeTarget;
|
protected boolean isNodeTarget;
|
||||||
@ -45,20 +45,19 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
* @throws BlenderFileException
|
* @throws BlenderFileException
|
||||||
* exception thrown when problems with blender file occur
|
* exception thrown when problems with blender file occur
|
||||||
*/
|
*/
|
||||||
public BoneConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
|
public BoneConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
throws BlenderFileException {
|
|
||||||
super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean validate() {
|
protected boolean validate() {
|
||||||
if(targetOMA != null) {
|
if (targetOMA != null) {
|
||||||
Spatial nodeTarget = (Spatial)blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
Spatial nodeTarget = (Spatial) blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
//the second part of the if expression verifies if the found node (if any) is an armature node
|
// the second part of the if expression verifies if the found node (if any) is an armature node
|
||||||
if(nodeTarget == null || nodeTarget.getUserData(ArmatureHelper.ARMETURE_NODE_MARKER) != null) {
|
if (nodeTarget == null || nodeTarget.getUserData(ArmatureHelper.ARMETURE_NODE_MARKER) != null) {
|
||||||
//if the target is not an object node then it is an Armature, so make sure the bone is in the current skeleton
|
// if the target is not an object node then it is an Armature, so make sure the bone is in the current skeleton
|
||||||
BoneContext boneContext = blenderContext.getBoneContext(ownerOMA);
|
BoneContext boneContext = blenderContext.getBoneContext(ownerOMA);
|
||||||
if(targetOMA.longValue() != boneContext.getArmatureObjectOMA().longValue()) {
|
if (targetOMA.longValue() != boneContext.getArmatureObjectOMA().longValue()) {
|
||||||
LOGGER.log(Level.WARNING, "Bone constraint {0} must target bone in the its own skeleton! Targeting bone in another skeleton is not supported!", name);
|
LOGGER.log(Level.WARNING, "Bone constraint {0} must target bone in the its own skeleton! Targeting bone in another skeleton is not supported!", name);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -74,13 +73,13 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
public void performBakingOperation() {
|
public void performBakingOperation() {
|
||||||
Bone owner = blenderContext.getBoneContext(ownerOMA).getBone();
|
Bone owner = blenderContext.getBoneContext(ownerOMA).getBone();
|
||||||
|
|
||||||
if(targetOMA != null) {
|
if (targetOMA != null) {
|
||||||
if(isNodeTarget) {
|
if (isNodeTarget) {
|
||||||
Spatial target = (Spatial) blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
Spatial target = (Spatial) blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
this.prepareTracksForApplyingConstraints();
|
this.prepareTracksForApplyingConstraints();
|
||||||
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
||||||
Transform targetTransform = constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext);
|
Transform targetTransform = constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext);
|
||||||
|
|
||||||
@ -97,8 +96,8 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
|
|
||||||
this.prepareTracksForApplyingConstraints();
|
this.prepareTracksForApplyingConstraints();
|
||||||
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
||||||
Transform targetTransform = constraintHelper.getBoneTransform(targetSpace, target);
|
Transform targetTransform = constraintHelper.getBoneTransform(targetSpace, target);
|
||||||
|
|
||||||
@ -112,8 +111,8 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
} else {
|
} else {
|
||||||
this.prepareTracksForApplyingConstraints();
|
this.prepareTracksForApplyingConstraints();
|
||||||
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
Transform ownerTransform = constraintHelper.getBoneTransform(ownerSpace, owner);
|
||||||
Track boneTrack = constraintHelper.getTrack(owner, animData.skeleton, animation);
|
Track boneTrack = constraintHelper.getTrack(owner, animData.skeleton, animation);
|
||||||
|
|
||||||
@ -128,29 +127,29 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
Long[] bonesOMAs = new Long[] { ownerOMA, targetOMA };
|
Long[] bonesOMAs = new Long[] { ownerOMA, targetOMA };
|
||||||
Space[] spaces = new Space[] { ownerSpace, targetSpace };
|
Space[] spaces = new Space[] { ownerSpace, targetSpace };
|
||||||
|
|
||||||
//creating animations for current objects if at least on of their parents have an animation
|
// creating animations for current objects if at least on of their parents have an animation
|
||||||
for (int i = 0; i < bonesOMAs.length; ++i) {
|
for (int i = 0; i < bonesOMAs.length; ++i) {
|
||||||
Long oma = bonesOMAs[i];
|
Long oma = bonesOMAs[i];
|
||||||
if(this.hasAnimation(oma)) {
|
if (this.hasAnimation(oma)) {
|
||||||
Bone currentBone = blenderContext.getBoneContext(oma).getBone();
|
Bone currentBone = blenderContext.getBoneContext(oma).getBone();
|
||||||
Bone parent = currentBone.getParent();
|
Bone parent = currentBone.getParent();
|
||||||
boolean foundAnimation = false;
|
boolean foundAnimation = false;
|
||||||
AnimData animData = null;
|
AnimData animData = null;
|
||||||
while(parent != null && !foundAnimation) {
|
while (parent != null && !foundAnimation) {
|
||||||
BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
|
BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
|
||||||
foundAnimation = this.hasAnimation(boneContext.getBoneOma());
|
foundAnimation = this.hasAnimation(boneContext.getBoneOma());
|
||||||
animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(foundAnimation) {
|
if (foundAnimation) {
|
||||||
this.applyAnimData(blenderContext.getBoneContext(oma), spaces[i], animData);
|
this.applyAnimData(blenderContext.getBoneContext(oma), spaces[i], animData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//creating animation for owner if it doesn't have one already and if the target has it
|
// creating animation for owner if it doesn't have one already and if the target has it
|
||||||
if(!this.hasAnimation(ownerOMA) && this.hasAnimation(targetOMA)) {
|
if (!this.hasAnimation(ownerOMA) && this.hasAnimation(targetOMA)) {
|
||||||
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
||||||
this.applyAnimData(blenderContext.getBoneContext(ownerOMA), ownerSpace, targetAnimData);
|
this.applyAnimData(blenderContext.getBoneContext(ownerOMA), ownerSpace, targetAnimData);
|
||||||
}
|
}
|
||||||
@ -165,13 +164,13 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
*/
|
*/
|
||||||
protected boolean hasAnimation(Long animOwnerOMA) {
|
protected boolean hasAnimation(Long animOwnerOMA) {
|
||||||
AnimData animData = blenderContext.getAnimData(animOwnerOMA);
|
AnimData animData = blenderContext.getAnimData(animOwnerOMA);
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
if(!isNodeTarget) {
|
if (!isNodeTarget) {
|
||||||
Bone bone = blenderContext.getBoneContext(animOwnerOMA).getBone();
|
Bone bone = blenderContext.getBoneContext(animOwnerOMA).getBone();
|
||||||
int boneIndex = animData.skeleton.getBoneIndex(bone);
|
int boneIndex = animData.skeleton.getBoneIndex(bone);
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
for(Track track : animation.getTracks()) {
|
for (Track track : animation.getTracks()) {
|
||||||
if(track instanceof BoneTrack && ((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
|
if (track instanceof BoneTrack && ((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -200,7 +199,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
|
|
||||||
AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
AnimData animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
||||||
|
|
||||||
for(Animation animation : referenceAnimData.anims) {
|
for (Animation animation : referenceAnimData.anims) {
|
||||||
BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0];
|
BoneTrack parentTrack = (BoneTrack) animation.getTracks()[0];
|
||||||
|
|
||||||
float[] times = parentTrack.getTimes();
|
float[] times = parentTrack.getTimes();
|
||||||
@ -210,7 +209,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
Arrays.fill(translations, transform.getTranslation());
|
Arrays.fill(translations, transform.getTranslation());
|
||||||
Arrays.fill(rotations, transform.getRotation());
|
Arrays.fill(rotations, transform.getRotation());
|
||||||
Arrays.fill(scales, transform.getScale());
|
Arrays.fill(scales, transform.getScale());
|
||||||
for(Animation anim : animData.anims) {
|
for (Animation anim : animData.anims) {
|
||||||
anim.addTrack(new BoneTrack(animData.skeleton.getBoneIndex(boneContext.getBone()), times, translations, rotations, scales));
|
anim.addTrack(new BoneTrack(animData.skeleton.getBoneIndex(boneContext.getBone()), times, translations, rotations, scales));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -62,17 +62,17 @@ public abstract class Constraint {
|
|||||||
if (pData.isNotNull()) {
|
if (pData.isNotNull()) {
|
||||||
Structure data = pData.fetchData(blenderContext.getInputStream()).get(0);
|
Structure data = pData.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, blenderContext);
|
constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(data, blenderContext);
|
||||||
Pointer pTar = (Pointer)data.getFieldValue("tar");
|
Pointer pTar = (Pointer) data.getFieldValue("tar");
|
||||||
if(pTar!= null && pTar.isNotNull()) {
|
if (pTar != null && pTar.isNotNull()) {
|
||||||
this.targetOMA = pTar.getOldMemoryAddress();
|
this.targetOMA = pTar.getOldMemoryAddress();
|
||||||
this.targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue());
|
this.targetSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("tarspace")).byteValue());
|
||||||
Object subtargetValue = data.getFieldValue("subtarget");
|
Object subtargetValue = data.getFieldValue("subtarget");
|
||||||
if(subtargetValue != null) {//not all constraint data have the subtarget field
|
if (subtargetValue != null) {// not all constraint data have the subtarget field
|
||||||
subtargetName = subtargetValue.toString();
|
subtargetName = subtargetValue.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//Null constraint has no data, so create it here
|
// Null constraint has no data, so create it here
|
||||||
constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, blenderContext);
|
constraintDefinition = ConstraintDefinitionFactory.createConstraintDefinition(null, blenderContext);
|
||||||
}
|
}
|
||||||
this.ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue());
|
this.ownerSpace = Space.valueOf(((Number) constraintStructure.getFieldValue("ownspace")).byteValue());
|
||||||
@ -87,14 +87,14 @@ public abstract class Constraint {
|
|||||||
* order is kept.
|
* order is kept.
|
||||||
*/
|
*/
|
||||||
public void bake() {
|
public void bake() {
|
||||||
if(!this.validate()) {
|
if (!this.validate()) {
|
||||||
LOGGER.warning("The constraint " + name + " is invalid and will not be applied.");
|
LOGGER.warning("The constraint " + name + " is invalid and will not be applied.");
|
||||||
} else if(!baked) {
|
} else if (!baked) {
|
||||||
if(targetOMA != null) {
|
if (targetOMA != null) {
|
||||||
List<Constraint> targetConstraints = blenderContext.getConstraints(targetOMA);
|
List<Constraint> targetConstraints = blenderContext.getConstraints(targetOMA);
|
||||||
if(targetConstraints != null && targetConstraints.size() > 0) {
|
if (targetConstraints != null && targetConstraints.size() > 0) {
|
||||||
LOGGER.log(Level.FINE, "Baking target constraints of constraint: {0}", name);
|
LOGGER.log(Level.FINE, "Baking target constraints of constraint: {0}", name);
|
||||||
for(Constraint targetConstraint : targetConstraints) {
|
for (Constraint targetConstraint : targetConstraints) {
|
||||||
targetConstraint.bake();
|
targetConstraint.bake();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//loading constraints connected with the object's bones
|
// loading constraints connected with the object's bones
|
||||||
Pointer pPose = (Pointer) objectStructure.getFieldValue("pose");
|
Pointer pPose = (Pointer) objectStructure.getFieldValue("pose");
|
||||||
if (pPose.isNotNull()) {
|
if (pPose.isNotNull()) {
|
||||||
List<Structure> poseChannels = ((Structure) pPose.fetchData(blenderContext.getInputStream()).get(0).getFieldValue("chanbase")).evaluateListBase(blenderContext);
|
List<Structure> poseChannels = ((Structure) pPose.fetchData(blenderContext.getInputStream()).get(0).getFieldValue("chanbase")).evaluateListBase(blenderContext);
|
||||||
@ -95,13 +95,13 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
List<Constraint> constraintsList = new ArrayList<Constraint>();
|
List<Constraint> constraintsList = new ArrayList<Constraint>();
|
||||||
Long boneOMA = Long.valueOf(((Pointer) poseChannel.getFieldValue("bone")).getOldMemoryAddress());
|
Long boneOMA = Long.valueOf(((Pointer) poseChannel.getFieldValue("bone")).getOldMemoryAddress());
|
||||||
|
|
||||||
//the name is read directly from structure because bone might not yet be loaded
|
// the name is read directly from structure because bone might not yet be loaded
|
||||||
String name = blenderContext.getFileBlock(boneOMA).getStructure(blenderContext).getFieldValue("name").toString();
|
String name = blenderContext.getFileBlock(boneOMA).getStructure(blenderContext).getFieldValue("name").toString();
|
||||||
List<Structure> constraints = ((Structure) poseChannel.getFieldValue("constraints")).evaluateListBase(blenderContext);
|
List<Structure> constraints = ((Structure) poseChannel.getFieldValue("constraints")).evaluateListBase(blenderContext);
|
||||||
for (Structure constraint : constraints) {
|
for (Structure constraint : constraints) {
|
||||||
String constraintName = constraint.getFieldValue("name").toString();
|
String constraintName = constraint.getFieldValue("name").toString();
|
||||||
Map<String, Ipo> ipoMap = constraintsIpos.get(name);
|
Map<String, Ipo> ipoMap = constraintsIpos.get(name);
|
||||||
Ipo ipo = ipoMap==null ? null : ipoMap.get(constraintName);
|
Ipo ipo = ipoMap == null ? null : ipoMap.get(constraintName);
|
||||||
if (ipo == null) {
|
if (ipo == null) {
|
||||||
float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
|
float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
|
||||||
ipo = ipoHelper.fromValue(enforce);
|
ipo = ipoHelper.fromValue(enforce);
|
||||||
@ -112,19 +112,19 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//loading constraints connected with the object itself
|
// loading constraints connected with the object itself
|
||||||
List<Structure> constraints = ((Structure)objectStructure.getFieldValue("constraints")).evaluateListBase(blenderContext);
|
List<Structure> constraints = ((Structure) objectStructure.getFieldValue("constraints")).evaluateListBase(blenderContext);
|
||||||
if(constraints != null && constraints.size() > 0) {
|
if (constraints != null && constraints.size() > 0) {
|
||||||
Pointer pData = (Pointer) objectStructure.getFieldValue("data");
|
Pointer pData = (Pointer) objectStructure.getFieldValue("data");
|
||||||
String dataType = pData.isNotNull() ? pData.fetchData(blenderContext.getInputStream()).get(0).getType() : null;
|
String dataType = pData.isNotNull() ? pData.fetchData(blenderContext.getInputStream()).get(0).getType() : null;
|
||||||
List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
|
List<Constraint> constraintsList = new ArrayList<Constraint>(constraints.size());
|
||||||
|
|
||||||
for(Structure constraint : constraints) {
|
for (Structure constraint : constraints) {
|
||||||
String constraintName = constraint.getFieldValue("name").toString();
|
String constraintName = constraint.getFieldValue("name").toString();
|
||||||
String objectName = objectStructure.getName();
|
String objectName = objectStructure.getName();
|
||||||
|
|
||||||
Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
|
Map<String, Ipo> objectConstraintsIpos = constraintsIpos.get(objectName);
|
||||||
Ipo ipo = objectConstraintsIpos!=null ? objectConstraintsIpos.get(constraintName) : null;
|
Ipo ipo = objectConstraintsIpos != null ? objectConstraintsIpos.get(constraintName) : null;
|
||||||
if (ipo == null) {
|
if (ipo == null) {
|
||||||
float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
|
float enforce = ((Number) constraint.getFieldValue("enforce")).floatValue();
|
||||||
ipo = ipoHelper.fromValue(enforce);
|
ipo = ipoHelper.fromValue(enforce);
|
||||||
@ -156,9 +156,9 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* thrown when problems with blender file occured
|
* thrown when problems with blender file occured
|
||||||
*/
|
*/
|
||||||
private Constraint getConstraint(String dataType, Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
private Constraint getConstraint(String dataType, Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
if(dataType == null || "Mesh".equalsIgnoreCase(dataType) || "Camera".equalsIgnoreCase(dataType) || "Lamp".equalsIgnoreCase(dataType)) {
|
if (dataType == null || "Mesh".equalsIgnoreCase(dataType) || "Camera".equalsIgnoreCase(dataType) || "Lamp".equalsIgnoreCase(dataType)) {
|
||||||
return new SpatialConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
return new SpatialConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
||||||
} else if("Armature".equalsIgnoreCase(dataType)) {
|
} else if ("Armature".equalsIgnoreCase(dataType)) {
|
||||||
return new SkeletonConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
return new SkeletonConstraint(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Unsupported data type for applying constraints: " + dataType);
|
throw new IllegalArgumentException("Unsupported data type for applying constraints: " + dataType);
|
||||||
@ -172,7 +172,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* the blender context
|
* the blender context
|
||||||
*/
|
*/
|
||||||
public void bakeConstraints(BlenderContext blenderContext) {
|
public void bakeConstraints(BlenderContext blenderContext) {
|
||||||
for(Constraint constraint : blenderContext.getAllConstraints()) {
|
for (Constraint constraint : blenderContext.getAllConstraints()) {
|
||||||
constraint.bake();
|
constraint.bake();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* @return track for the given bone that was found among the given
|
* @return track for the given bone that was found among the given
|
||||||
* animations or null if none is found
|
* animations or null if none is found
|
||||||
*/
|
*/
|
||||||
/*package*/ BoneTrack getTrack(Bone bone, Skeleton skeleton, Animation animation) {
|
/* package */BoneTrack getTrack(Bone bone, Skeleton skeleton, Animation animation) {
|
||||||
int boneIndex = skeleton.getBoneIndex(bone);
|
int boneIndex = skeleton.getBoneIndex(bone);
|
||||||
for (Track track : animation.getTracks()) {
|
for (Track track : animation.getTracks()) {
|
||||||
if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
|
if (((BoneTrack) track).getTargetBoneIndex() == boneIndex) {
|
||||||
@ -209,10 +209,10 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* @return track for the given spatial that was found among the given
|
* @return track for the given spatial that was found among the given
|
||||||
* animations or null if none is found
|
* animations or null if none is found
|
||||||
*/
|
*/
|
||||||
/*package*/ SpatialTrack getTrack(Spatial spatial, Animation animation) {
|
/* package */SpatialTrack getTrack(Spatial spatial, Animation animation) {
|
||||||
Track[] tracks = animation.getTracks();
|
Track[] tracks = animation.getTracks();
|
||||||
if(tracks != null && tracks.length == 1) {
|
if (tracks != null && tracks.length == 1) {
|
||||||
return (SpatialTrack)tracks[0];
|
return (SpatialTrack) tracks[0];
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -231,7 +231,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* @return the object's transform in a given space
|
* @return the object's transform in a given space
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
/*package*/ Transform getNodeObjectTransform(Space space, Long spatialOMA, BlenderContext blenderContext) {
|
/* package */Transform getNodeObjectTransform(Space space, Long spatialOMA, BlenderContext blenderContext) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case CONSTRAINT_SPACE_LOCAL:
|
case CONSTRAINT_SPACE_LOCAL:
|
||||||
Structure targetStructure = (Structure) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_STRUCTURE);
|
Structure targetStructure = (Structure) blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_STRUCTURE);
|
||||||
@ -260,11 +260,11 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
Transform result = new Transform(loc, rot);
|
Transform result = new Transform(loc, rot);
|
||||||
result.setScale(size);
|
result.setScale(size);
|
||||||
return result;
|
return result;
|
||||||
case CONSTRAINT_SPACE_WORLD://TODO: get it from the object structure ???
|
case CONSTRAINT_SPACE_WORLD:// TODO: get it from the object structure ???
|
||||||
Object feature = blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
Object feature = blenderContext.getLoadedFeature(spatialOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
if(feature instanceof Spatial) {
|
if (feature instanceof Spatial) {
|
||||||
return ((Spatial) feature).getWorldTransform();
|
return ((Spatial) feature).getWorldTransform();
|
||||||
} else if(feature instanceof Skeleton) {
|
} else if (feature instanceof Skeleton) {
|
||||||
LOGGER.warning("Trying to get transformation for skeleton. This is not supported. Returning null.");
|
LOGGER.warning("Trying to get transformation for skeleton. This is not supported. Returning null.");
|
||||||
return null;
|
return null;
|
||||||
} else {
|
} else {
|
||||||
@ -285,7 +285,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* the bone we get the transform from
|
* the bone we get the transform from
|
||||||
* @return the transform of the given bone
|
* @return the transform of the given bone
|
||||||
*/
|
*/
|
||||||
/*package*/ Transform getBoneTransform(Space space, Bone bone) {
|
/* package */Transform getBoneTransform(Space space, Bone bone) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case CONSTRAINT_SPACE_LOCAL:
|
case CONSTRAINT_SPACE_LOCAL:
|
||||||
Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
|
Transform localTransform = new Transform(bone.getLocalPosition(), bone.getLocalRotation());
|
||||||
@ -319,7 +319,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* @param transform
|
* @param transform
|
||||||
* the transform being applied
|
* the transform being applied
|
||||||
*/
|
*/
|
||||||
/*package*/ void applyTransform(Spatial spatial, Space space, Transform transform) {
|
/* package */void applyTransform(Spatial spatial, Space space, Transform transform) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case CONSTRAINT_SPACE_LOCAL:
|
case CONSTRAINT_SPACE_LOCAL:
|
||||||
Transform ownerLocalTransform = spatial.getLocalTransform();
|
Transform ownerLocalTransform = spatial.getLocalTransform();
|
||||||
@ -361,7 +361,7 @@ public class ConstraintHelper extends AbstractBlenderHelper {
|
|||||||
* @param transform
|
* @param transform
|
||||||
* the transform being applied
|
* the transform being applied
|
||||||
*/
|
*/
|
||||||
/*package*/ void applyTransform(Bone bone, Space space, Transform transform) {
|
/* package */void applyTransform(Bone bone, Space space, Transform transform) {
|
||||||
switch (space) {
|
switch (space) {
|
||||||
case CONSTRAINT_SPACE_LOCAL:
|
case CONSTRAINT_SPACE_LOCAL:
|
||||||
bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
|
bone.setBindTransforms(transform.getTranslation(), transform.getRotation(), transform.getScale());
|
||||||
|
@ -15,7 +15,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class SkeletonConstraint extends Constraint {
|
/* package */class SkeletonConstraint extends Constraint {
|
||||||
private static final Logger LOGGER = Logger.getLogger(SkeletonConstraint.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(SkeletonConstraint.class.getName());
|
||||||
|
|
||||||
public SkeletonConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
public SkeletonConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
@ -33,5 +33,6 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void prepareTracksForApplyingConstraints() { }
|
protected void prepareTracksForApplyingConstraints() {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
* This includes: nodes, cameras nodes and light nodes.
|
* This includes: nodes, cameras nodes and light nodes.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class SpatialConstraint extends BoneConstraint {
|
/* package */class SpatialConstraint extends BoneConstraint {
|
||||||
private static final Logger LOGGER = Logger.getLogger(SpatialConstraint.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(SpatialConstraint.class.getName());
|
||||||
|
|
||||||
/** The owner of the constraint. */
|
/** The owner of the constraint. */
|
||||||
@ -36,8 +36,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
/** The target of the constraint. */
|
/** The target of the constraint. */
|
||||||
private Object target;
|
private Object target;
|
||||||
|
|
||||||
public SpatialConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext)
|
public SpatialConstraint(Structure constraintStructure, Long ownerOMA, Ipo influenceIpo, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
throws BlenderFileException {
|
|
||||||
super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
super(constraintStructure, ownerOMA, influenceIpo, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -47,22 +46,22 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
this.target = targetOMA != null ? blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE) : null;
|
this.target = targetOMA != null ? blenderContext.getLoadedFeature(targetOMA, LoadedFeatureDataType.LOADED_FEATURE) : null;
|
||||||
this.prepareTracksForApplyingConstraints();
|
this.prepareTracksForApplyingConstraints();
|
||||||
|
|
||||||
//apply static constraint
|
// apply static constraint
|
||||||
Transform ownerTransform = constraintHelper.getNodeObjectTransform(ownerSpace, ownerOMA, blenderContext);
|
Transform ownerTransform = constraintHelper.getNodeObjectTransform(ownerSpace, ownerOMA, blenderContext);
|
||||||
Transform targetTransform = targetOMA != null ? constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext) : null;
|
Transform targetTransform = targetOMA != null ? constraintHelper.getNodeObjectTransform(targetSpace, targetOMA, blenderContext) : null;
|
||||||
constraintDefinition.bake(ownerTransform, targetTransform, null, null, this.ipo);
|
constraintDefinition.bake(ownerTransform, targetTransform, null, null, this.ipo);
|
||||||
constraintHelper.applyTransform(owner, ownerSpace, ownerTransform);
|
constraintHelper.applyTransform(owner, ownerSpace, ownerTransform);
|
||||||
|
|
||||||
//apply dynamic constraint
|
// apply dynamic constraint
|
||||||
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
if(animData != null) {
|
if (animData != null) {
|
||||||
for(Animation animation : animData.anims) {
|
for (Animation animation : animData.anims) {
|
||||||
SpatialTrack ownerTrack = constraintHelper.getTrack(owner, animation);
|
SpatialTrack ownerTrack = constraintHelper.getTrack(owner, animation);
|
||||||
|
|
||||||
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
||||||
SpatialTrack targetTrack = null;
|
SpatialTrack targetTrack = null;
|
||||||
if(targetAnimData != null) {
|
if (targetAnimData != null) {
|
||||||
targetTrack = constraintHelper.getTrack((Spatial)target, targetAnimData.anims.get(0));
|
targetTrack = constraintHelper.getTrack((Spatial) target, targetAnimData.anims.get(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
constraintDefinition.bake(ownerTransform, targetTransform, ownerTrack, targetTrack, this.ipo);
|
constraintDefinition.bake(ownerTransform, targetTransform, ownerTrack, targetTrack, this.ipo);
|
||||||
@ -75,33 +74,33 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
Long[] spatialsOMAs = new Long[] { ownerOMA, targetOMA };
|
Long[] spatialsOMAs = new Long[] { ownerOMA, targetOMA };
|
||||||
Space[] spaces = new Space[] { ownerSpace, targetSpace };
|
Space[] spaces = new Space[] { ownerSpace, targetSpace };
|
||||||
|
|
||||||
//creating animations for current objects if at least on of their parents have an animation
|
// creating animations for current objects if at least on of their parents have an animation
|
||||||
for (int i = 0; i < spatialsOMAs.length; ++i) {
|
for (int i = 0; i < spatialsOMAs.length; ++i) {
|
||||||
Long oma = spatialsOMAs[i];
|
Long oma = spatialsOMAs[i];
|
||||||
if(oma != null && oma > 0L) {
|
if (oma != null && oma > 0L) {
|
||||||
AnimData animData = blenderContext.getAnimData(oma);
|
AnimData animData = blenderContext.getAnimData(oma);
|
||||||
if(animData == null) {
|
if (animData == null) {
|
||||||
Spatial currentSpatial = (Spatial)blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
|
Spatial currentSpatial = (Spatial) blenderContext.getLoadedFeature(oma, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
if(currentSpatial != null) {
|
if (currentSpatial != null) {
|
||||||
if(currentSpatial.getUserData(ArmatureHelper.ARMETURE_NODE_MARKER) == Boolean.TRUE) {//look for it among bones
|
if (currentSpatial.getUserData(ArmatureHelper.ARMETURE_NODE_MARKER) == Boolean.TRUE) {// look for it among bones
|
||||||
BoneContext currentBoneContext = blenderContext.getBoneByName(subtargetName);
|
BoneContext currentBoneContext = blenderContext.getBoneByName(subtargetName);
|
||||||
Bone currentBone = currentBoneContext.getBone();
|
Bone currentBone = currentBoneContext.getBone();
|
||||||
Bone parent = currentBone.getParent();
|
Bone parent = currentBone.getParent();
|
||||||
boolean foundAnimation = false;
|
boolean foundAnimation = false;
|
||||||
while(parent != null && !foundAnimation) {
|
while (parent != null && !foundAnimation) {
|
||||||
BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
|
BoneContext boneContext = blenderContext.getBoneByName(parent.getName());
|
||||||
foundAnimation = this.hasAnimation(boneContext.getBoneOma());
|
foundAnimation = this.hasAnimation(boneContext.getBoneOma());
|
||||||
animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
animData = blenderContext.getAnimData(boneContext.getBoneOma());
|
||||||
parent = parent.getParent();
|
parent = parent.getParent();
|
||||||
}
|
}
|
||||||
if(foundAnimation) {
|
if (foundAnimation) {
|
||||||
this.applyAnimData(currentBoneContext, spaces[i], animData);
|
this.applyAnimData(currentBoneContext, spaces[i], animData);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Spatial parent = currentSpatial.getParent();
|
Spatial parent = currentSpatial.getParent();
|
||||||
while(parent != null && animData == null) {
|
while (parent != null && animData == null) {
|
||||||
Structure parentStructure = (Structure)blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE);
|
Structure parentStructure = (Structure) blenderContext.getLoadedFeature(parent.getName(), LoadedFeatureDataType.LOADED_STRUCTURE);
|
||||||
if(parentStructure == null) {
|
if (parentStructure == null) {
|
||||||
parent = null;
|
parent = null;
|
||||||
} else {
|
} else {
|
||||||
Long parentOma = parentStructure.getOldMemoryAddress();
|
Long parentOma = parentStructure.getOldMemoryAddress();
|
||||||
@ -110,23 +109,22 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(animData != null) {//create anim data for the current object
|
if (animData != null) {// create anim data for the current object
|
||||||
this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0));
|
this.applyAnimData(currentSpatial, oma, spaces[i], animData.anims.get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warning("Couldn't find target object for constraint: " + name +
|
LOGGER.warning("Couldn't find target object for constraint: " + name + ". Make sure that the target is on layer that is defined to be loaded in blender key!");
|
||||||
". Make sure that the target is on layer that is defined to be loaded in blender key!");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//creating animation for owner if it doesn't have one already and if the target has it
|
// creating animation for owner if it doesn't have one already and if the target has it
|
||||||
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
if(animData == null) {
|
if (animData == null) {
|
||||||
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
AnimData targetAnimData = blenderContext.getAnimData(targetOMA);
|
||||||
if(targetAnimData != null) {
|
if (targetAnimData != null) {
|
||||||
this.applyAnimData(owner, ownerOMA, ownerSpace, targetAnimData.anims.get(0));
|
this.applyAnimData(owner, ownerOMA, ownerSpace, targetAnimData.anims.get(0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,9 +22,9 @@ public abstract class ConstraintDefinition {
|
|||||||
protected int flag;
|
protected int flag;
|
||||||
|
|
||||||
public ConstraintDefinition(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinition(Structure constraintData, BlenderContext blenderContext) {
|
||||||
if(constraintData != null) {//Null constraint has no data
|
if (constraintData != null) {// Null constraint has no data
|
||||||
Number flag = (Number)constraintData.getFieldValue("flag");
|
Number flag = (Number) constraintData.getFieldValue("flag");
|
||||||
if(flag != null) {
|
if (flag != null) {
|
||||||
this.flag = flag.intValue();
|
this.flag = flag.intValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -34,9 +34,9 @@ public abstract class ConstraintDefinition {
|
|||||||
TrackWrapper ownerWrapperTrack = ownerTrack != null ? new TrackWrapper(ownerTrack) : null;
|
TrackWrapper ownerWrapperTrack = ownerTrack != null ? new TrackWrapper(ownerTrack) : null;
|
||||||
TrackWrapper targetWrapperTrack = targetTrack != null ? new TrackWrapper(targetTrack) : null;
|
TrackWrapper targetWrapperTrack = targetTrack != null ? new TrackWrapper(targetTrack) : null;
|
||||||
|
|
||||||
//uruchamiamy bake dla transformat zalenie od tego, ktre argumenty s nullami, a ktre - nie
|
// uruchamiamy bake dla transformat zalenie od tego, ktre argumenty s nullami, a ktre - nie
|
||||||
this.bake(ownerTransform, targetTransform, influenceIpo.calculateValue(0));
|
this.bake(ownerTransform, targetTransform, influenceIpo.calculateValue(0));
|
||||||
if(ownerWrapperTrack != null) {
|
if (ownerWrapperTrack != null) {
|
||||||
float[] ownerTimes = ownerWrapperTrack.getTimes();
|
float[] ownerTimes = ownerWrapperTrack.getTimes();
|
||||||
Vector3f[] translations = ownerWrapperTrack.getTranslations();
|
Vector3f[] translations = ownerWrapperTrack.getTranslations();
|
||||||
Quaternion[] rotations = ownerWrapperTrack.getRotations();
|
Quaternion[] rotations = ownerWrapperTrack.getRotations();
|
||||||
@ -50,15 +50,15 @@ public abstract class ConstraintDefinition {
|
|||||||
Quaternion rotation = new Quaternion();
|
Quaternion rotation = new Quaternion();
|
||||||
|
|
||||||
Transform ownerTemp = new Transform(), targetTemp = new Transform();
|
Transform ownerTemp = new Transform(), targetTemp = new Transform();
|
||||||
for (int i = 0; i <ownerTimes.length; ++i) {
|
for (int i = 0; i < ownerTimes.length; ++i) {
|
||||||
float t = ownerTimes[i];
|
float t = ownerTimes[i];
|
||||||
ownerTemp.setTranslation(translations[i]);
|
ownerTemp.setTranslation(translations[i]);
|
||||||
ownerTemp.setRotation(rotations[i]);
|
ownerTemp.setRotation(rotations[i]);
|
||||||
ownerTemp.setScale(scales[i]);
|
ownerTemp.setScale(scales[i]);
|
||||||
if(targetWrapperTrack == null) {
|
if (targetWrapperTrack == null) {
|
||||||
this.bake(ownerTemp, targetTransform, influenceIpo.calculateValue(i));
|
this.bake(ownerTemp, targetTransform, influenceIpo.calculateValue(i));
|
||||||
} else {
|
} else {
|
||||||
//getting the values that are the interpolation of the target track for the time 't'
|
// getting the values that are the interpolation of the target track for the time 't'
|
||||||
this.interpolate(targetTranslations, targetTimes, t, translation);
|
this.interpolate(targetTranslations, targetTimes, t, translation);
|
||||||
this.interpolate(targetRotations, targetTimes, t, rotation);
|
this.interpolate(targetRotations, targetTimes, t, rotation);
|
||||||
this.interpolate(targetScales, targetTimes, t, scale);
|
this.interpolate(targetScales, targetTimes, t, scale);
|
||||||
@ -69,7 +69,7 @@ public abstract class ConstraintDefinition {
|
|||||||
|
|
||||||
this.bake(ownerTemp, targetTemp, influenceIpo.calculateValue(i));
|
this.bake(ownerTemp, targetTemp, influenceIpo.calculateValue(i));
|
||||||
}
|
}
|
||||||
//need to clone here because each of the arrays will reference the same instance if they hold the same value in the compact array
|
// need to clone here because each of the arrays will reference the same instance if they hold the same value in the compact array
|
||||||
translations[i] = ownerTemp.getTranslation().clone();
|
translations[i] = ownerTemp.getTranslation().clone();
|
||||||
rotations[i] = ownerTemp.getRotation().clone();
|
rotations[i] = ownerTemp.getRotation().clone();
|
||||||
scales[i] = ownerTemp.getScale().clone();
|
scales[i] = ownerTemp.getScale().clone();
|
||||||
@ -83,20 +83,20 @@ public abstract class ConstraintDefinition {
|
|||||||
private void interpolate(Vector3f[] targetVectors, float[] targetTimes, float currentTime, Vector3f result) {
|
private void interpolate(Vector3f[] targetVectors, float[] targetTimes, float currentTime, Vector3f result) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 1; i < targetTimes.length; ++i) {
|
for (int i = 1; i < targetTimes.length; ++i) {
|
||||||
if(targetTimes[i] < currentTime) {
|
if (targetTimes[i] < currentTime) {
|
||||||
++index;
|
++index;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(index >= targetTimes.length - 1) {
|
if (index >= targetTimes.length - 1) {
|
||||||
result.set(targetVectors[targetTimes.length - 1]);
|
result.set(targetVectors[targetTimes.length - 1]);
|
||||||
} else {
|
} else {
|
||||||
float delta = targetTimes[index + 1] - targetTimes[index];
|
float delta = targetTimes[index + 1] - targetTimes[index];
|
||||||
if(delta == 0.0f) {
|
if (delta == 0.0f) {
|
||||||
result.set(targetVectors[index + 1]);
|
result.set(targetVectors[index + 1]);
|
||||||
} else {
|
} else {
|
||||||
float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]);
|
float scale = (currentTime - targetTimes[index]) / (targetTimes[index + 1] - targetTimes[index]);
|
||||||
FastMath.interpolateLinear(scale, targetVectors[index], targetVectors[index + 1], result);
|
FastMath.interpolateLinear(scale, targetVectors[index], targetVectors[index + 1], result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,20 +105,20 @@ public abstract class ConstraintDefinition {
|
|||||||
private void interpolate(Quaternion[] targetQuaternions, float[] targetTimes, float currentTime, Quaternion result) {
|
private void interpolate(Quaternion[] targetQuaternions, float[] targetTimes, float currentTime, Quaternion result) {
|
||||||
int index = 0;
|
int index = 0;
|
||||||
for (int i = 1; i < targetTimes.length; ++i) {
|
for (int i = 1; i < targetTimes.length; ++i) {
|
||||||
if(targetTimes[i] < currentTime) {
|
if (targetTimes[i] < currentTime) {
|
||||||
++index;
|
++index;
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(index >= targetTimes.length - 1) {
|
if (index >= targetTimes.length - 1) {
|
||||||
result.set(targetQuaternions[targetTimes.length - 1]);
|
result.set(targetQuaternions[targetTimes.length - 1]);
|
||||||
} else {
|
} else {
|
||||||
float delta = targetTimes[index + 1] - targetTimes[index];
|
float delta = targetTimes[index + 1] - targetTimes[index];
|
||||||
if(delta == 0.0f) {
|
if (delta == 0.0f) {
|
||||||
result.set(targetQuaternions[index + 1]);
|
result.set(targetQuaternions[index + 1]);
|
||||||
} else {
|
} else {
|
||||||
float scale = (currentTime - targetTimes[index])/(targetTimes[index + 1] - targetTimes[index]);
|
float scale = (currentTime - targetTimes[index]) / (targetTimes[index + 1] - targetTimes[index]);
|
||||||
result.slerp(targetQuaternions[index], targetQuaternions[index + 1], scale);
|
result.slerp(targetQuaternions[index], targetQuaternions[index + 1], scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,18 +137,16 @@ public abstract class ConstraintDefinition {
|
|||||||
private BoneTrack boneTrack;
|
private BoneTrack boneTrack;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs the object using the given track. The track must be of one of the types:
|
* Constructs the object using the given track. The track must be of one of the types: <li>BoneTrack <li>SpatialTrack
|
||||||
* <li> BoneTrack
|
|
||||||
* <li> SpatialTrack
|
|
||||||
*
|
*
|
||||||
* @param track
|
* @param track
|
||||||
* the animation track
|
* the animation track
|
||||||
*/
|
*/
|
||||||
public TrackWrapper(Track track) {
|
public TrackWrapper(Track track) {
|
||||||
if(track instanceof SpatialTrack) {
|
if (track instanceof SpatialTrack) {
|
||||||
this.spatialTrack = (SpatialTrack)track;
|
this.spatialTrack = (SpatialTrack) track;
|
||||||
} else if(track instanceof BoneTrack) {
|
} else if (track instanceof BoneTrack) {
|
||||||
this.boneTrack = (BoneTrack)track;
|
this.boneTrack = (BoneTrack) track;
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalStateException("Unknown track type!");
|
throw new IllegalStateException("Unknown track type!");
|
||||||
}
|
}
|
||||||
@ -206,8 +204,7 @@ public abstract class ConstraintDefinition {
|
|||||||
* @param scales
|
* @param scales
|
||||||
* the scale of the bone for each frame
|
* the scale of the bone for each frame
|
||||||
*/
|
*/
|
||||||
public void setKeyframes(float[] times, Vector3f[] translations,
|
public void setKeyframes(float[] times, Vector3f[] translations, Quaternion[] rotations, Vector3f[] scales) {
|
||||||
Quaternion[] rotations, Vector3f[] scales) {
|
|
||||||
if (boneTrack != null) {
|
if (boneTrack != null) {
|
||||||
boneTrack.setKeyframes(times, translations, rotations, scales);
|
boneTrack.setKeyframes(times, translations, rotations, scales);
|
||||||
} else {
|
} else {
|
||||||
@ -216,15 +213,14 @@ public abstract class ConstraintDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void write(JmeExporter ex) throws IOException {
|
public void write(JmeExporter ex) throws IOException {
|
||||||
//no need to implement this one (the TrackWrapper is used internally and never serialized)
|
// no need to implement this one (the TrackWrapper is used internally and never serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
public void read(JmeImporter im) throws IOException {
|
public void read(JmeImporter im) throws IOException {
|
||||||
//no need to implement this one (the TrackWrapper is used internally and never serialized)
|
// no need to implement this one (the TrackWrapper is used internally and never serialized)
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTime(float time, float weight, AnimControl control,
|
public void setTime(float time, float weight, AnimControl control, AnimChannel channel, TempVars vars) {
|
||||||
AnimChannel channel, TempVars vars) {
|
|
||||||
if (boneTrack != null) {
|
if (boneTrack != null) {
|
||||||
boneTrack.setTime(time, weight, control, channel, vars);
|
boneTrack.setTime(time, weight, control, channel, vars);
|
||||||
} else {
|
} else {
|
||||||
@ -233,8 +229,7 @@ public abstract class ConstraintDefinition {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public float getLength() {
|
public float getLength() {
|
||||||
return spatialTrack == null ? boneTrack.getLength() : spatialTrack
|
return spatialTrack == null ? boneTrack.getLength() : spatialTrack.getLength();
|
||||||
.getLength();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Action' constraint type in blender.
|
* This class represents 'Action' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionAction extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionAction extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionAction(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionAction(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Camera solver' constraint type in blender.
|
* This class represents 'Camera solver' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionCameraSolver extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionCameraSolver extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionCameraSolver(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionCameraSolver(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'ChildOf' constraint type in blender.
|
* This class represents 'ChildOf' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionChildOf extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionChildOf extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionChildOf.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionChildOf.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionChildOf(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionChildOf(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Clamp to' constraint type in blender.
|
* This class represents 'Clamp to' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionClampTo extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionClampTo extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionClampTo.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionClampTo.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionClampTo(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionClampTo(Structure constraintData, BlenderContext blenderContext) {
|
||||||
@ -20,7 +20,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
||||||
//TODO: implement when curves are implemented
|
// TODO: implement when curves are implemented
|
||||||
LOGGER.log(Level.WARNING, "'Clamp to' not yet implemented!");
|
LOGGER.log(Level.WARNING, "'Clamp to' not yet implemented!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* The damp track constraint. Available for blender 2.50+.
|
* The damp track constraint. Available for blender 2.50+.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionDampTrack extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionDampTrack extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionDampTrack.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionDampTrack.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionDampTrack(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionDampTrack(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -9,7 +9,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Dist limit' constraint type in blender.
|
* This class represents 'Dist limit' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionDistLimit extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionDistLimit extends ConstraintDefinition {
|
||||||
private static final int LIMITDIST_INSIDE = 0;
|
private static final int LIMITDIST_INSIDE = 0;
|
||||||
private static final int LIMITDIST_OUTSIDE = 1;
|
private static final int LIMITDIST_OUTSIDE = 1;
|
||||||
private static final int LIMITDIST_ONSURFACE = 2;
|
private static final int LIMITDIST_ONSURFACE = 2;
|
||||||
@ -41,7 +41,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
v.normalizeLocal();
|
v.normalizeLocal();
|
||||||
v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
|
v.multLocal(dist + (currentDistance - dist) * (1.0f - influence));
|
||||||
ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation()));
|
ownerTransform.getTranslation().set(v.addLocal(targetTransform.getTranslation()));
|
||||||
} else if(currentDistance < dist) {
|
} else if (currentDistance < dist) {
|
||||||
v.normalizeLocal().multLocal(dist * influence);
|
v.normalizeLocal().multLocal(dist * influence);
|
||||||
ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v));
|
ownerTransform.getTranslation().set(targetTransform.getTranslation().add(v));
|
||||||
}
|
}
|
||||||
|
@ -62,15 +62,15 @@ public class ConstraintDefinitionFactory {
|
|||||||
CONSTRAINT_CLASSES.put("bStretchToConstraint", ConstraintDefinitionStretchTo.class);
|
CONSTRAINT_CLASSES.put("bStretchToConstraint", ConstraintDefinitionStretchTo.class);
|
||||||
CONSTRAINT_CLASSES.put("bTransformConstraint", ConstraintDefinitionTransform.class);
|
CONSTRAINT_CLASSES.put("bTransformConstraint", ConstraintDefinitionTransform.class);
|
||||||
CONSTRAINT_CLASSES.put("bRotLimitConstraint", ConstraintDefinitionRotLimit.class);
|
CONSTRAINT_CLASSES.put("bRotLimitConstraint", ConstraintDefinitionRotLimit.class);
|
||||||
//Blender 2.50+
|
// Blender 2.50+
|
||||||
CONSTRAINT_CLASSES.put("bSplineIKConstraint", ConstraintDefinitionSplineInverseKinematic.class);
|
CONSTRAINT_CLASSES.put("bSplineIKConstraint", ConstraintDefinitionSplineInverseKinematic.class);
|
||||||
CONSTRAINT_CLASSES.put("bDampTrackConstraint", ConstraintDefinitionDampTrack.class);
|
CONSTRAINT_CLASSES.put("bDampTrackConstraint", ConstraintDefinitionDampTrack.class);
|
||||||
CONSTRAINT_CLASSES.put("bPivotConstraint", ConstraintDefinitionDampTrack.class);
|
CONSTRAINT_CLASSES.put("bPivotConstraint", ConstraintDefinitionDampTrack.class);
|
||||||
//Blender 2.56+
|
// Blender 2.56+
|
||||||
CONSTRAINT_CLASSES.put("bTrackToConstraint", ConstraintDefinitionTrackTo.class);
|
CONSTRAINT_CLASSES.put("bTrackToConstraint", ConstraintDefinitionTrackTo.class);
|
||||||
CONSTRAINT_CLASSES.put("bSameVolumeConstraint", ConstraintDefinitionSameVolume.class);
|
CONSTRAINT_CLASSES.put("bSameVolumeConstraint", ConstraintDefinitionSameVolume.class);
|
||||||
CONSTRAINT_CLASSES.put("bTransLikeConstraint", ConstraintDefinitionTransLike.class);
|
CONSTRAINT_CLASSES.put("bTransLikeConstraint", ConstraintDefinitionTransLike.class);
|
||||||
//Blender 2.62+
|
// Blender 2.62+
|
||||||
CONSTRAINT_CLASSES.put("bCameraSolverConstraint", ConstraintDefinitionCameraSolver.class);
|
CONSTRAINT_CLASSES.put("bCameraSolverConstraint", ConstraintDefinitionCameraSolver.class);
|
||||||
CONSTRAINT_CLASSES.put("bObjectSolverConstraint", ConstraintDefinitionObjectSolver.class);
|
CONSTRAINT_CLASSES.put("bObjectSolverConstraint", ConstraintDefinitionObjectSolver.class);
|
||||||
CONSTRAINT_CLASSES.put("bFollowTrackConstraint", ConstraintDefinitionFollowTrack.class);
|
CONSTRAINT_CLASSES.put("bFollowTrackConstraint", ConstraintDefinitionFollowTrack.class);
|
||||||
@ -88,12 +88,12 @@ public class ConstraintDefinitionFactory {
|
|||||||
* corrupted
|
* corrupted
|
||||||
*/
|
*/
|
||||||
public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException {
|
public static ConstraintDefinition createConstraintDefinition(Structure constraintStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
if(constraintStructure == null) {
|
if (constraintStructure == null) {
|
||||||
return new ConstraintDefinitionNull(null, blenderContext);
|
return new ConstraintDefinitionNull(null, blenderContext);
|
||||||
}
|
}
|
||||||
String constraintClassName = constraintStructure.getType();
|
String constraintClassName = constraintStructure.getType();
|
||||||
Class<? extends ConstraintDefinition> constraintDefinitionClass = CONSTRAINT_CLASSES.get(constraintClassName);
|
Class<? extends ConstraintDefinition> constraintDefinitionClass = CONSTRAINT_CLASSES.get(constraintClassName);
|
||||||
if(constraintDefinitionClass != null) {
|
if (constraintDefinitionClass != null) {
|
||||||
try {
|
try {
|
||||||
return (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, blenderContext);
|
return (ConstraintDefinition) constraintDefinitionClass.getDeclaredConstructors()[0].newInstance(constraintStructure, blenderContext);
|
||||||
} catch (IllegalArgumentException e) {
|
} catch (IllegalArgumentException e) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Follow path' constraint type in blender.
|
* This class represents 'Follow path' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionFollowPath extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionFollowPath extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionFollowPath.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionFollowPath.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionFollowPath(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionFollowPath(Structure constraintData, BlenderContext blenderContext) {
|
||||||
@ -20,7 +20,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
||||||
//TODO: implement when curves are implemented
|
// TODO: implement when curves are implemented
|
||||||
LOGGER.log(Level.WARNING, "'Follow path' not implemented! Curves not yet implemented!");
|
LOGGER.log(Level.WARNING, "'Follow path' not implemented! Curves not yet implemented!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Follow track' constraint type in blender.
|
* This class represents 'Follow track' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionFollowTrack extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionFollowTrack extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionFollowTrack(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionFollowTrack(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,9 +11,9 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Inverse kinematics' constraint type in blender.
|
* This class represents 'Inverse kinematics' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionInverseKinematics extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionInverseKinematics extends ConstraintDefinition {
|
||||||
//private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionInverseKinematics.class.getName());
|
// private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionInverseKinematics.class.getName());
|
||||||
//private static final float IK_SOLVER_ERROR = 0.5f;
|
// private static final float IK_SOLVER_ERROR = 0.5f;
|
||||||
|
|
||||||
public ConstraintDefinitionInverseKinematics(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionInverseKinematics(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
@ -21,92 +21,92 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
||||||
// try {
|
// try {
|
||||||
// IK solver is only attached to bones
|
// IK solver is only attached to bones
|
||||||
// Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
// Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
// AnimData animData = blenderContext.getAnimData(ownerOMA);
|
// AnimData animData = blenderContext.getAnimData(ownerOMA);
|
||||||
// if(animData == null) {
|
// if(animData == null) {
|
||||||
//TODO: to nie moxe byx null, utworzyx dane bez ruchu, w zalexnoxci czy target six rusza
|
// TODO: to nie moxe byx null, utworzyx dane bez ruchu, w zalexnoxci czy target six rusza
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//prepare a list of all parents of this bone
|
// prepare a list of all parents of this bone
|
||||||
// CalculationBone[] bones = this.getBonesToCalculate(skeleton, boneAnimation);
|
// CalculationBone[] bones = this.getBonesToCalculate(skeleton, boneAnimation);
|
||||||
|
|
||||||
// get the target point
|
// get the target point
|
||||||
// Object targetObject = this.getTarget(LoadedFeatureDataType.LOADED_FEATURE);
|
// Object targetObject = this.getTarget(LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
// Vector3f pt = null;// Point Target
|
// Vector3f pt = null;// Point Target
|
||||||
// if (targetObject instanceof Bone) {
|
// if (targetObject instanceof Bone) {
|
||||||
// pt = ((Bone) targetObject).getModelSpacePosition();
|
// pt = ((Bone) targetObject).getModelSpacePosition();
|
||||||
// } else if (targetObject instanceof Spatial) {
|
// } else if (targetObject instanceof Spatial) {
|
||||||
// pt = ((Spatial) targetObject).getWorldTranslation();
|
// pt = ((Spatial) targetObject).getWorldTranslation();
|
||||||
// } else if (targetObject instanceof Skeleton) {
|
// } else if (targetObject instanceof Skeleton) {
|
||||||
// Structure armatureNodeStructure = (Structure) this.getTarget(LoadedFeatureDataType.LOADED_STRUCTURE);
|
// Structure armatureNodeStructure = (Structure) this.getTarget(LoadedFeatureDataType.LOADED_STRUCTURE);
|
||||||
// ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
// ObjectHelper objectHelper = blenderContext.getHelper(ObjectHelper.class);
|
||||||
// Transform transform = objectHelper.getTransformation(armatureNodeStructure, blenderContext);
|
// Transform transform = objectHelper.getTransformation(armatureNodeStructure, blenderContext);
|
||||||
// pt = transform.getTranslation();
|
// pt = transform.getTranslation();
|
||||||
// } else {
|
// } else {
|
||||||
// throw new IllegalStateException(
|
// throw new IllegalStateException(
|
||||||
// "Unknown target object type! Should be Node, Bone or Skeleton and there is: "
|
// "Unknown target object type! Should be Node, Bone or Skeleton and there is: "
|
||||||
// + targetObject.getClass().getName());
|
// + targetObject.getClass().getName());
|
||||||
// }
|
// }
|
||||||
|
|
||||||
//fetching the owner's bone track
|
// fetching the owner's bone track
|
||||||
// BoneTrack ownerBoneTrack = null;
|
// BoneTrack ownerBoneTrack = null;
|
||||||
// int boneIndex = skeleton.getBoneIndex(ownerBone);
|
// int boneIndex = skeleton.getBoneIndex(ownerBone);
|
||||||
// for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
|
// for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
|
||||||
// if (boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) {
|
// if (boneAnimation.getTracks()[i].getTargetBoneIndex() == boneIndex) {
|
||||||
// ownerBoneTrack = boneAnimation.getTracks()[i];
|
// ownerBoneTrack = boneAnimation.getTracks()[i];
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// int ownerBoneFramesCount = ownerBoneTrack==null ? 0 : ownerBoneTrack.getTimes().length;
|
// int ownerBoneFramesCount = ownerBoneTrack==null ? 0 : ownerBoneTrack.getTimes().length;
|
||||||
//
|
//
|
||||||
// // preparing data
|
// // preparing data
|
||||||
// int maxIterations = ((Number) data.getFieldValue("iterations")).intValue();
|
// int maxIterations = ((Number) data.getFieldValue("iterations")).intValue();
|
||||||
// CalculationBone[] bones = this.getBonesToCalculate(ownerBone, skeleton, boneAnimation);
|
// CalculationBone[] bones = this.getBonesToCalculate(ownerBone, skeleton, boneAnimation);
|
||||||
// for (int i = 0; i < bones.length; ++i) {
|
// for (int i = 0; i < bones.length; ++i) {
|
||||||
// System.out.println(Arrays.toString(bones[i].track.getTranslations()));
|
// System.out.println(Arrays.toString(bones[i].track.getTranslations()));
|
||||||
// System.out.println(Arrays.toString(bones[i].track.getRotations()));
|
// System.out.println(Arrays.toString(bones[i].track.getRotations()));
|
||||||
// System.out.println("===============================");
|
// System.out.println("===============================");
|
||||||
// }
|
// }
|
||||||
// Quaternion rotation = new Quaternion();
|
// Quaternion rotation = new Quaternion();
|
||||||
// //all tracks should have the same amount of frames
|
// //all tracks should have the same amount of frames
|
||||||
// int framesCount = bones[0].getBoneFramesCount();
|
// int framesCount = bones[0].getBoneFramesCount();
|
||||||
// assert framesCount >=1;
|
// assert framesCount >=1;
|
||||||
// for (int frame = 0; frame < framesCount; ++frame) {
|
// for (int frame = 0; frame < framesCount; ++frame) {
|
||||||
// float error = IK_SOLVER_ERROR;
|
// float error = IK_SOLVER_ERROR;
|
||||||
// int iteration = 0;
|
// int iteration = 0;
|
||||||
// while (error >= IK_SOLVER_ERROR && iteration <= maxIterations) {
|
// while (error >= IK_SOLVER_ERROR && iteration <= maxIterations) {
|
||||||
// // rotating the bones
|
// // rotating the bones
|
||||||
// for (int i = 0; i < bones.length - 1; ++i) {
|
// for (int i = 0; i < bones.length - 1; ++i) {
|
||||||
// Vector3f pe = bones[i].getEndPoint();
|
// Vector3f pe = bones[i].getEndPoint();
|
||||||
// Vector3f pc = bones[i + 1].getWorldTranslation().clone();
|
// Vector3f pc = bones[i + 1].getWorldTranslation().clone();
|
||||||
//
|
//
|
||||||
// Vector3f peSUBpc = pe.subtract(pc).normalizeLocal();
|
// Vector3f peSUBpc = pe.subtract(pc).normalizeLocal();
|
||||||
// Vector3f ptSUBpc = pt.subtract(pc).normalizeLocal();
|
// Vector3f ptSUBpc = pt.subtract(pc).normalizeLocal();
|
||||||
//
|
//
|
||||||
// float theta = FastMath.acos(peSUBpc.dot(ptSUBpc));
|
// float theta = FastMath.acos(peSUBpc.dot(ptSUBpc));
|
||||||
// Vector3f direction = peSUBpc.cross(ptSUBpc).normalizeLocal();
|
// Vector3f direction = peSUBpc.cross(ptSUBpc).normalizeLocal();
|
||||||
// bones[i].rotate(rotation.fromAngleAxis(theta, direction), frame);
|
// bones[i].rotate(rotation.fromAngleAxis(theta, direction), frame);
|
||||||
// }
|
// }
|
||||||
// error = pt.subtract(bones[0].getEndPoint()).length();
|
// error = pt.subtract(bones[0].getEndPoint()).length();
|
||||||
// ++iteration;
|
// ++iteration;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// for (CalculationBone bone : bones) {
|
// for (CalculationBone bone : bones) {
|
||||||
// bone.applyCalculatedTracks();
|
// bone.applyCalculatedTracks();
|
||||||
// }
|
// }
|
||||||
//
|
//
|
||||||
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
|
// System.out.println("&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&");
|
||||||
// for (int i = 0; i < bones.length; ++i) {
|
// for (int i = 0; i < bones.length; ++i) {
|
||||||
// System.out.println(Arrays.toString(bones[i].track.getTranslations()));
|
// System.out.println(Arrays.toString(bones[i].track.getTranslations()));
|
||||||
// System.out.println(Arrays.toString(bones[i].track.getRotations()));
|
// System.out.println(Arrays.toString(bones[i].track.getRotations()));
|
||||||
// System.out.println("===============================");
|
// System.out.println("===============================");
|
||||||
// }
|
// }
|
||||||
// } catch(BlenderFileException e) {
|
// } catch(BlenderFileException e) {
|
||||||
// LOGGER.severe(e.getLocalizedMessage());
|
// LOGGER.severe(e.getLocalizedMessage());
|
||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -120,25 +120,25 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* @return a list of bones to imitate the bone's movement during IK solving
|
* @return a list of bones to imitate the bone's movement during IK solving
|
||||||
*/
|
*/
|
||||||
private CalculationBone[] getBonesToCalculate(Skeleton skeleton, Animation boneAnimation) {
|
private CalculationBone[] getBonesToCalculate(Skeleton skeleton, Animation boneAnimation) {
|
||||||
// Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
// Bone ownerBone = (Bone) blenderContext.getLoadedFeature(ownerOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
// List<CalculationBone> bonesList = new ArrayList<CalculationBone>();
|
// List<CalculationBone> bonesList = new ArrayList<CalculationBone>();
|
||||||
// do {
|
// do {
|
||||||
// bonesList.add(new CalculationBone(ownerBone, 1));
|
// bonesList.add(new CalculationBone(ownerBone, 1));
|
||||||
// int boneIndex = skeleton.getBoneIndex(ownerBone);
|
// int boneIndex = skeleton.getBoneIndex(ownerBone);
|
||||||
// for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
|
// for (int i = 0; i < boneAnimation.getTracks().length; ++i) {
|
||||||
// if (((BoneTrack[])boneAnimation.getTracks())[i].getTargetBoneIndex() == boneIndex) {
|
// if (((BoneTrack[])boneAnimation.getTracks())[i].getTargetBoneIndex() == boneIndex) {
|
||||||
// bonesList.add(new CalculationBone(ownerBone, (BoneTrack)boneAnimation.getTracks()[i]));
|
// bonesList.add(new CalculationBone(ownerBone, (BoneTrack)boneAnimation.getTracks()[i]));
|
||||||
// break;
|
// break;
|
||||||
// }
|
// }
|
||||||
// }
|
// }
|
||||||
// ownerBone = ownerBone.getParent();
|
// ownerBone = ownerBone.getParent();
|
||||||
// } while (ownerBone != null);
|
// } while (ownerBone != null);
|
||||||
// //attaching children
|
// //attaching children
|
||||||
// CalculationBone[] result = bonesList.toArray(new CalculationBone[bonesList.size()]);
|
// CalculationBone[] result = bonesList.toArray(new CalculationBone[bonesList.size()]);
|
||||||
// for (int i = result.length - 1; i > 0; --i) {
|
// for (int i = result.length - 1; i > 0; --i) {
|
||||||
// result[i].attachChild(result[i - 1]);
|
// result[i].attachChild(result[i - 1]);
|
||||||
// }
|
// }
|
||||||
// return result;
|
// return result;
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,11 +9,11 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Loc like' constraint type in blender.
|
* This class represents 'Loc like' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionLocLike extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionLocLike extends ConstraintDefinition {
|
||||||
private static final int LOCLIKE_X = 0x01;
|
private static final int LOCLIKE_X = 0x01;
|
||||||
private static final int LOCLIKE_Y = 0x02;
|
private static final int LOCLIKE_Y = 0x02;
|
||||||
private static final int LOCLIKE_Z = 0x04;
|
private static final int LOCLIKE_Z = 0x04;
|
||||||
//protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender
|
// protected static final int LOCLIKE_TIP = 0x08;//this is deprecated in blender
|
||||||
private static final int LOCLIKE_X_INVERT = 0x10;
|
private static final int LOCLIKE_X_INVERT = 0x10;
|
||||||
private static final int LOCLIKE_Y_INVERT = 0x20;
|
private static final int LOCLIKE_Y_INVERT = 0x20;
|
||||||
private static final int LOCLIKE_Z_INVERT = 0x40;
|
private static final int LOCLIKE_Z_INVERT = 0x40;
|
||||||
@ -21,13 +21,13 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
public ConstraintDefinitionLocLike(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionLocLike(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
||||||
//swapping Y and X limits flag in the bitwise flag
|
// swapping Y and X limits flag in the bitwise flag
|
||||||
int y = flag & LOCLIKE_Y;
|
int y = flag & LOCLIKE_Y;
|
||||||
int invY = flag & LOCLIKE_Y_INVERT;
|
int invY = flag & LOCLIKE_Y_INVERT;
|
||||||
int z = flag & LOCLIKE_Z;
|
int z = flag & LOCLIKE_Z;
|
||||||
int invZ = flag & LOCLIKE_Z_INVERT;
|
int invZ = flag & LOCLIKE_Z_INVERT;
|
||||||
flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;//clear the other flags to swap them
|
flag &= LOCLIKE_X | LOCLIKE_X_INVERT | LOCLIKE_OFFSET;// clear the other flags to swap them
|
||||||
flag |= y << 1;
|
flag |= y << 1;
|
||||||
flag |= invY << 1;
|
flag |= invY << 1;
|
||||||
flag |= z >> 1;
|
flag |= z >> 1;
|
||||||
@ -42,7 +42,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
Vector3f startLocation = ownerTransform.getTranslation().clone();
|
Vector3f startLocation = ownerTransform.getTranslation().clone();
|
||||||
Vector3f offset = Vector3f.ZERO;
|
Vector3f offset = Vector3f.ZERO;
|
||||||
if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original location to the copied location
|
if ((flag & LOCLIKE_OFFSET) != 0) {// we add the original location to the copied location
|
||||||
offset = startLocation;
|
offset = startLocation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +66,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
}
|
}
|
||||||
ownerLocation.addLocal(offset);
|
ownerLocation.addLocal(offset);
|
||||||
|
|
||||||
if(influence < 1.0f) {
|
if (influence < 1.0f) {
|
||||||
startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
|
startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
|
||||||
ownerLocation.addLocal(startLocation);
|
ownerLocation.addLocal(startLocation);
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Loc limit' constraint type in blender.
|
* This class represents 'Loc limit' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionLocLimit extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionLocLimit extends ConstraintDefinition {
|
||||||
private static final int LIMIT_XMIN = 0x01;
|
private static final int LIMIT_XMIN = 0x01;
|
||||||
private static final int LIMIT_XMAX = 0x02;
|
private static final int LIMIT_XMAX = 0x02;
|
||||||
private static final int LIMIT_YMIN = 0x04;
|
private static final int LIMIT_YMIN = 0x04;
|
||||||
@ -21,7 +21,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
public ConstraintDefinitionLocLimit(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionLocLimit(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
||||||
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
||||||
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
||||||
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
||||||
@ -29,12 +29,12 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
|
limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
|
||||||
limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
|
limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
|
||||||
|
|
||||||
//swapping Y and X limits flag in the bitwise flag
|
// swapping Y and X limits flag in the bitwise flag
|
||||||
int ymin = flag & LIMIT_YMIN;
|
int ymin = flag & LIMIT_YMIN;
|
||||||
int ymax = flag & LIMIT_YMAX;
|
int ymax = flag & LIMIT_YMAX;
|
||||||
int zmin = flag & LIMIT_ZMIN;
|
int zmin = flag & LIMIT_ZMIN;
|
||||||
int zmax = flag & LIMIT_ZMAX;
|
int zmax = flag & LIMIT_ZMAX;
|
||||||
flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
|
flag &= LIMIT_XMIN | LIMIT_XMAX;// clear the other flags to swap them
|
||||||
flag |= ymin << 2;
|
flag |= ymin << 2;
|
||||||
flag |= ymax << 2;
|
flag |= ymax << 2;
|
||||||
flag |= zmin >> 2;
|
flag |= zmin >> 2;
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Action' constraint type in blender.
|
* This class represents 'Action' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionLockTrack extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionLockTrack extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionLockTrack.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionLockTrack.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionLockTrack(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionLockTrack(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Min max' constraint type in blender.
|
* This class represents 'Min max' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionMinMax extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionMinMax extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionMinMax.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionMinMax.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionMinMax(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionMinMax(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -8,7 +8,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Null' constraint type in blender.
|
* This class represents 'Null' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionNull extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionNull extends ConstraintDefinition {
|
||||||
|
|
||||||
public ConstraintDefinitionNull(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionNull(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
@ -16,6 +16,6 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
||||||
//null constraint does nothing so no need to implement this one
|
// null constraint does nothing so no need to implement this one
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Object solver' constraint type in blender.
|
* This class represents 'Object solver' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionObjectSolver extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionObjectSolver extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionObjectSolver(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionObjectSolver(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* The pivot constraint. Available for blender 2.50+.
|
* The pivot constraint. Available for blender 2.50+.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionPivot extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionPivot extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPivot.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPivot.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionPivot(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionPivot(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Python' constraint type in blender.
|
* This class represents 'Python' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionPython extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionPython extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPython.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionPython.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionPython(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionPython(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Rigid body joint' constraint type in blender.
|
* This class represents 'Rigid body joint' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionRigidBodyJoint extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionRigidBodyJoint extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionRigidBodyJoint.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionRigidBodyJoint.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionRigidBodyJoint(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionRigidBodyJoint(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -9,7 +9,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Rot like' constraint type in blender.
|
* This class represents 'Rot like' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionRotLike extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionRotLike extends ConstraintDefinition {
|
||||||
private static final int ROTLIKE_X = 0x01;
|
private static final int ROTLIKE_X = 0x01;
|
||||||
private static final int ROTLIKE_Y = 0x02;
|
private static final int ROTLIKE_Y = 0x02;
|
||||||
private static final int ROTLIKE_Z = 0x04;
|
private static final int ROTLIKE_Z = 0x04;
|
||||||
@ -33,7 +33,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
Quaternion startRotation = ownerRotation.clone();
|
Quaternion startRotation = ownerRotation.clone();
|
||||||
Quaternion offset = Quaternion.IDENTITY;
|
Quaternion offset = Quaternion.IDENTITY;
|
||||||
if ((flag & ROTLIKE_OFFSET) != 0) {//we add the original rotation to the copied rotation
|
if ((flag & ROTLIKE_OFFSET) != 0) {// we add the original rotation to the copied rotation
|
||||||
offset = startRotation;
|
offset = startRotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,11 +57,11 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
}
|
}
|
||||||
ownerRotation.fromAngles(ownerAngles).multLocal(offset);
|
ownerRotation.fromAngles(ownerAngles).multLocal(offset);
|
||||||
|
|
||||||
if(influence < 1.0f) {
|
if (influence < 1.0f) {
|
||||||
|
|
||||||
// startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
|
// startLocation.subtractLocal(ownerLocation).normalizeLocal().mult(influence);
|
||||||
// ownerLocation.addLocal(startLocation);
|
// ownerLocation.addLocal(startLocation);
|
||||||
//TODO
|
// TODO
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
public ConstraintDefinitionRotLimit(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionRotLimit(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
if (blenderContext.getBlenderKey().isFixUpAxis()/* && owner.spatial != null*/) {//FIXME: !!!!!!!!
|
if (blenderContext.getBlenderKey().isFixUpAxis()/* && owner.spatial != null */) {// FIXME: !!!!!!!!
|
||||||
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
||||||
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
||||||
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
||||||
|
@ -12,7 +12,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionSameVolume extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionSameVolume extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSameVolume.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSameVolume.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionSameVolume(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionSameVolume(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -8,7 +8,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Shrink wrap' constraint type in blender.
|
* This class represents 'Shrink wrap' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionShrinkWrap extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionShrinkWrap extends ConstraintDefinition {
|
||||||
|
|
||||||
public ConstraintDefinitionShrinkWrap(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionShrinkWrap(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
@ -16,47 +16,46 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
public void bake(Transform ownerTransform, Transform targetTransform, float influence) {
|
||||||
//loading mesh points (blender ensures that the target is a mesh-object)
|
// loading mesh points (blender ensures that the target is a mesh-object)
|
||||||
/*List<Vector3f> pts = new ArrayList<Vector3f>();
|
/*
|
||||||
Node target = (Node) this.target.getObject();
|
* List<Vector3f> pts = new ArrayList<Vector3f>();
|
||||||
for(Spatial spatial : target.getChildren()) {
|
* Node target = (Node) this.target.getObject();
|
||||||
if(spatial instanceof Geometry) {
|
* for(Spatial spatial : target.getChildren()) {
|
||||||
Mesh mesh = ((Geometry) spatial).getMesh();
|
* if(spatial instanceof Geometry) {
|
||||||
FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position);
|
* Mesh mesh = ((Geometry) spatial).getMesh();
|
||||||
for(int i=0;i<floatBuffer.limit();i+=3) {
|
* FloatBuffer floatBuffer = mesh.getFloatBuffer(Type.Position);
|
||||||
pts.add(new Vector3f(floatBuffer.get(i), floatBuffer.get(i + 1), floatBuffer.get(i + 2)));
|
* for(int i=0;i<floatBuffer.limit();i+=3) {
|
||||||
}
|
* pts.add(new Vector3f(floatBuffer.get(i), floatBuffer.get(i + 1), floatBuffer.get(i + 2)));
|
||||||
}
|
* }
|
||||||
}
|
* }
|
||||||
|
* }
|
||||||
|
* AnimData animData = blenderContext.getAnimData(this.owner.getOma());
|
||||||
|
* if(animData != null) {
|
||||||
|
* Object owner = this.owner.getObject();
|
||||||
|
* for(Animation animation : animData.anims) {
|
||||||
|
* BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
|
||||||
|
* Vector3f[] translations = track.getTranslations();
|
||||||
|
* Quaternion[] rotations = track.getRotations();
|
||||||
|
* int maxFrames = translations.length;
|
||||||
|
* for (int frame = 0; frame < maxFrames; ++frame) {
|
||||||
|
* Vector3f currentTranslation = translations[frame];
|
||||||
|
* //looking for minimum distanced point
|
||||||
|
* Vector3f minDistancePoint = null;
|
||||||
|
* float distance = Float.MAX_VALUE;
|
||||||
|
* for(Vector3f p : pts) {
|
||||||
|
* float temp = currentTranslation.distance(p);
|
||||||
|
* if(temp < distance) {
|
||||||
|
* distance = temp;
|
||||||
|
* minDistancePoint = p;
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* translations[frame] = minDistancePoint.clone();
|
||||||
|
* }
|
||||||
|
* track.setKeyframes(track.getTimes(), translations, rotations, track.getScales());
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
|
||||||
AnimData animData = blenderContext.getAnimData(this.owner.getOma());
|
// TODO: static constraint for spatials
|
||||||
if(animData != null) {
|
|
||||||
Object owner = this.owner.getObject();
|
|
||||||
for(Animation animation : animData.anims) {
|
|
||||||
BlenderTrack track = this.getTrack(owner, animData.skeleton, animation);
|
|
||||||
Vector3f[] translations = track.getTranslations();
|
|
||||||
Quaternion[] rotations = track.getRotations();
|
|
||||||
int maxFrames = translations.length;
|
|
||||||
for (int frame = 0; frame < maxFrames; ++frame) {
|
|
||||||
Vector3f currentTranslation = translations[frame];
|
|
||||||
|
|
||||||
//looking for minimum distanced point
|
|
||||||
Vector3f minDistancePoint = null;
|
|
||||||
float distance = Float.MAX_VALUE;
|
|
||||||
for(Vector3f p : pts) {
|
|
||||||
float temp = currentTranslation.distance(p);
|
|
||||||
if(temp < distance) {
|
|
||||||
distance = temp;
|
|
||||||
minDistancePoint = p;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
translations[frame] = minDistancePoint.clone();
|
|
||||||
}
|
|
||||||
|
|
||||||
track.setKeyframes(track.getTimes(), translations, rotations, track.getScales());
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
//TODO: static constraint for spatials
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Size like' constraint type in blender.
|
* This class represents 'Size like' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionSizeLike extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionSizeLike extends ConstraintDefinition {
|
||||||
private static final int SIZELIKE_X = 0x01;
|
private static final int SIZELIKE_X = 0x01;
|
||||||
private static final int SIZELIKE_Y = 0x02;
|
private static final int SIZELIKE_Y = 0x02;
|
||||||
private static final int SIZELIKE_Z = 0x04;
|
private static final int SIZELIKE_Z = 0x04;
|
||||||
@ -17,11 +17,11 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
public ConstraintDefinitionSizeLike(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionSizeLike(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
||||||
//swapping Y and X limits flag in the bitwise flag
|
// swapping Y and X limits flag in the bitwise flag
|
||||||
int y = flag & SIZELIKE_Y;
|
int y = flag & SIZELIKE_Y;
|
||||||
int z = flag & SIZELIKE_Z;
|
int z = flag & SIZELIKE_Z;
|
||||||
flag &= SIZELIKE_X | LOCLIKE_OFFSET;//clear the other flags to swap them
|
flag &= SIZELIKE_X | LOCLIKE_OFFSET;// clear the other flags to swap them
|
||||||
flag |= y << 1;
|
flag |= y << 1;
|
||||||
flag |= z >> 1;
|
flag |= z >> 1;
|
||||||
}
|
}
|
||||||
@ -33,7 +33,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
Vector3f targetScale = targetTransform.getScale();
|
Vector3f targetScale = targetTransform.getScale();
|
||||||
|
|
||||||
Vector3f offset = Vector3f.ZERO;
|
Vector3f offset = Vector3f.ZERO;
|
||||||
if ((flag & LOCLIKE_OFFSET) != 0) {//we add the original scale to the copied scale
|
if ((flag & LOCLIKE_OFFSET) != 0) {// we add the original scale to the copied scale
|
||||||
offset = ownerScale.clone();
|
offset = ownerScale.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Size limit' constraint type in blender.
|
* This class represents 'Size limit' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionSizeLimit extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionSizeLimit extends ConstraintDefinition {
|
||||||
private static final int LIMIT_XMIN = 0x01;
|
private static final int LIMIT_XMIN = 0x01;
|
||||||
private static final int LIMIT_XMAX = 0x02;
|
private static final int LIMIT_XMAX = 0x02;
|
||||||
private static final int LIMIT_YMIN = 0x04;
|
private static final int LIMIT_YMIN = 0x04;
|
||||||
@ -21,7 +21,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
|
|
||||||
public ConstraintDefinitionSizeLimit(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionSizeLimit(Structure constraintData, BlenderContext blenderContext) {
|
||||||
super(constraintData, blenderContext);
|
super(constraintData, blenderContext);
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
||||||
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
limits[0][0] = ((Number) constraintData.getFieldValue("xmin")).floatValue();
|
||||||
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
limits[0][1] = ((Number) constraintData.getFieldValue("xmax")).floatValue();
|
||||||
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
limits[2][0] = -((Number) constraintData.getFieldValue("ymin")).floatValue();
|
||||||
@ -29,12 +29,12 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
|
limits[1][0] = ((Number) constraintData.getFieldValue("zmin")).floatValue();
|
||||||
limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
|
limits[1][1] = ((Number) constraintData.getFieldValue("zmax")).floatValue();
|
||||||
|
|
||||||
//swapping Y and X limits flag in the bitwise flag
|
// swapping Y and X limits flag in the bitwise flag
|
||||||
int ymin = flag & LIMIT_YMIN;
|
int ymin = flag & LIMIT_YMIN;
|
||||||
int ymax = flag & LIMIT_YMAX;
|
int ymax = flag & LIMIT_YMAX;
|
||||||
int zmin = flag & LIMIT_ZMIN;
|
int zmin = flag & LIMIT_ZMIN;
|
||||||
int zmax = flag & LIMIT_ZMAX;
|
int zmax = flag & LIMIT_ZMAX;
|
||||||
flag &= LIMIT_XMIN | LIMIT_XMAX;//clear the other flags to swap them
|
flag &= LIMIT_XMIN | LIMIT_XMAX;// clear the other flags to swap them
|
||||||
flag |= ymin << 2;
|
flag |= ymin << 2;
|
||||||
flag |= ymax << 2;
|
flag |= ymax << 2;
|
||||||
flag |= zmin >> 2;
|
flag |= zmin >> 2;
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* The spline inverse kinematic constraint. Available for blender 2.50+.
|
* The spline inverse kinematic constraint. Available for blender 2.50+.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionSplineInverseKinematic extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionSplineInverseKinematic extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSplineInverseKinematic.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionSplineInverseKinematic.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionSplineInverseKinematic(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionSplineInverseKinematic(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Stretch to' constraint type in blender.
|
* This class represents 'Stretch to' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionStretchTo extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionStretchTo extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionStretchTo.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionStretchTo.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionStretchTo(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionStretchTo(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -12,7 +12,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionTransLike extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionTransLike extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTransLike.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionTransLike.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionTransLike(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionTransLike(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -11,7 +11,7 @@ import com.jme3.scene.plugins.blender.file.Structure;
|
|||||||
* This class represents 'Transform' constraint type in blender.
|
* This class represents 'Transform' constraint type in blender.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ConstraintDefinitionTransform extends ConstraintDefinition {
|
/* package */class ConstraintDefinitionTransform extends ConstraintDefinition {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ConstraintDefinitionAction.class.getName());
|
||||||
|
|
||||||
public ConstraintDefinitionTransform(Structure constraintData, BlenderContext blenderContext) {
|
public ConstraintDefinitionTransform(Structure constraintData, BlenderContext blenderContext) {
|
||||||
|
@ -35,9 +35,9 @@ public class BezierCurve {
|
|||||||
}
|
}
|
||||||
this.type = type;
|
this.type = type;
|
||||||
this.dimension = dimension;
|
this.dimension = dimension;
|
||||||
//first index of the bezierPoints table has the length of triples amount
|
// first index of the bezierPoints table has the length of triples amount
|
||||||
//the second index points to a table od three points of a bezier triple (handle, point, handle)
|
// the second index points to a table od three points of a bezier triple (handle, point, handle)
|
||||||
//the third index specifies the coordinates of the specific point in a bezier triple
|
// the third index specifies the coordinates of the specific point in a bezier triple
|
||||||
bezierPoints = new float[bezTriples.size()][3][dimension];
|
bezierPoints = new float[bezTriples.size()][3][dimension];
|
||||||
radiuses = new float[bezTriples.size()];
|
radiuses = new float[bezTriples.size()];
|
||||||
int i = 0, j, k;
|
int i = 0, j, k;
|
||||||
@ -48,7 +48,7 @@ public class BezierCurve {
|
|||||||
bezierPoints[i][j][k] = vec.get(j, k).floatValue();
|
bezierPoints[i][j][k] = vec.get(j, k).floatValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
radiuses[i++] = ((Number)bezTriple.getFieldValue("radius")).floatValue();
|
radiuses[i++] = ((Number) bezTriple.getFieldValue("radius")).floatValue();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +74,7 @@ public class BezierCurve {
|
|||||||
}
|
}
|
||||||
if (frame < bezierPoints[0][1][0]) {
|
if (frame < bezierPoints[0][1][0]) {
|
||||||
return bezierPoints[0][1][1];
|
return bezierPoints[0][1][1];
|
||||||
} else { //frame>bezierPoints[bezierPoints.length-1][1][0]
|
} else { // frame>bezierPoints[bezierPoints.length-1][1][0]
|
||||||
return bezierPoints[bezierPoints.length - 1][1][1];
|
return bezierPoints[bezierPoints.length - 1][1][1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -138,13 +138,9 @@ public class BezierCurve {
|
|||||||
*/
|
*/
|
||||||
private String toStringBezTriple(int tripleIndex) {
|
private String toStringBezTriple(int tripleIndex) {
|
||||||
if (this.dimension == 2) {
|
if (this.dimension == 2) {
|
||||||
return "[(" + bezierPoints[tripleIndex][0][0] + ", " + bezierPoints[tripleIndex][0][1] + ") ("
|
return "[(" + bezierPoints[tripleIndex][0][0] + ", " + bezierPoints[tripleIndex][0][1] + ") (" + bezierPoints[tripleIndex][1][0] + ", " + bezierPoints[tripleIndex][1][1] + ") (" + bezierPoints[tripleIndex][2][0] + ", " + bezierPoints[tripleIndex][2][1] + ")]";
|
||||||
+ bezierPoints[tripleIndex][1][0] + ", " + bezierPoints[tripleIndex][1][1] + ") ("
|
|
||||||
+ bezierPoints[tripleIndex][2][0] + ", " + bezierPoints[tripleIndex][2][1] + ")]";
|
|
||||||
} else {
|
} else {
|
||||||
return "[(" + bezierPoints[tripleIndex][0][0] + ", " + bezierPoints[tripleIndex][0][1] + ", " + bezierPoints[tripleIndex][0][2] + ") ("
|
return "[(" + bezierPoints[tripleIndex][0][0] + ", " + bezierPoints[tripleIndex][0][1] + ", " + bezierPoints[tripleIndex][0][2] + ") (" + bezierPoints[tripleIndex][1][0] + ", " + bezierPoints[tripleIndex][1][1] + ", " + bezierPoints[tripleIndex][1][2] + ") (" + bezierPoints[tripleIndex][2][0] + ", " + bezierPoints[tripleIndex][2][1] + ", " + bezierPoints[tripleIndex][2][2] + ")]";
|
||||||
+ bezierPoints[tripleIndex][1][0] + ", " + bezierPoints[tripleIndex][1][1] + ", " + bezierPoints[tripleIndex][1][2] + ") ("
|
|
||||||
+ bezierPoints[tripleIndex][2][0] + ", " + bezierPoints[tripleIndex][2][1] + ", " + bezierPoints[tripleIndex][2][2] + ")]";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -113,13 +113,13 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
boolean isFront = (flag & 0x02) != 0 && !is3D;
|
boolean isFront = (flag & 0x02) != 0 && !is3D;
|
||||||
boolean isBack = (flag & 0x04) != 0 && !is3D;
|
boolean isBack = (flag & 0x04) != 0 && !is3D;
|
||||||
if (isFront) {
|
if (isFront) {
|
||||||
LOGGER.warning("No front face in curve implemented yet!");//TODO: implement front face
|
LOGGER.warning("No front face in curve implemented yet!");// TODO: implement front face
|
||||||
}
|
}
|
||||||
if (isBack) {
|
if (isBack) {
|
||||||
LOGGER.warning("No back face in curve implemented yet!");//TODO: implement back face
|
LOGGER.warning("No back face in curve implemented yet!");// TODO: implement back face
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading nurbs (and sorting them by material)
|
// reading nurbs (and sorting them by material)
|
||||||
List<Structure> nurbStructures = ((Structure) curveStructure.getFieldValue("nurb")).evaluateListBase(blenderContext);
|
List<Structure> nurbStructures = ((Structure) curveStructure.getFieldValue("nurb")).evaluateListBase(blenderContext);
|
||||||
Map<Number, List<Structure>> nurbs = new HashMap<Number, List<Structure>>();
|
Map<Number, List<Structure>> nurbs = new HashMap<Number, List<Structure>>();
|
||||||
for (Structure nurb : nurbStructures) {
|
for (Structure nurb : nurbStructures) {
|
||||||
@ -132,7 +132,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
nurbList.add(nurb);
|
nurbList.add(nurb);
|
||||||
}
|
}
|
||||||
|
|
||||||
//getting materials
|
// getting materials
|
||||||
MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
MaterialHelper materialHelper = blenderContext.getHelper(MaterialHelper.class);
|
||||||
MaterialContext[] materialContexts = materialHelper.getMaterials(curveStructure, blenderContext);
|
MaterialContext[] materialContexts = materialHelper.getMaterials(curveStructure, blenderContext);
|
||||||
Material defaultMaterial = null;
|
Material defaultMaterial = null;
|
||||||
@ -145,7 +145,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
defaultMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
|
defaultMaterial.getAdditionalRenderState().setFaceCullMode(FaceCullMode.Off);
|
||||||
}
|
}
|
||||||
|
|
||||||
//getting or creating bevel object
|
// getting or creating bevel object
|
||||||
List<Geometry> bevelObject = null;
|
List<Geometry> bevelObject = null;
|
||||||
Pointer pBevelObject = (Pointer) curveStructure.getFieldValue("bevobj");
|
Pointer pBevelObject = (Pointer) curveStructure.getFieldValue("bevobj");
|
||||||
if (pBevelObject.isNotNull()) {
|
if (pBevelObject.isNotNull()) {
|
||||||
@ -195,16 +195,14 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
bevelObject = new ArrayList<Geometry>(1);
|
bevelObject = new ArrayList<Geometry>(1);
|
||||||
bevelObject.add(new Geometry("", bevelCurve));
|
bevelObject.add(new Geometry("", bevelCurve));
|
||||||
} else if (extrude > 0.0f) {
|
} else if (extrude > 0.0f) {
|
||||||
Spline bevelSpline = new Spline(SplineType.Linear, new Vector3f[]{
|
Spline bevelSpline = new Spline(SplineType.Linear, new Vector3f[] { new Vector3f(0, 0, -extrude), new Vector3f(0, 0, extrude) }, 1, false);
|
||||||
new Vector3f(0, 0, -extrude), new Vector3f(0, 0, extrude)
|
|
||||||
}, 1, false);
|
|
||||||
Curve bevelCurve = new Curve(bevelSpline, bevResol);
|
Curve bevelCurve = new Curve(bevelSpline, bevResol);
|
||||||
bevelObject = new ArrayList<Geometry>(1);
|
bevelObject = new ArrayList<Geometry>(1);
|
||||||
bevelObject.add(new Geometry("", bevelCurve));
|
bevelObject.add(new Geometry("", bevelCurve));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//getting taper object
|
// getting taper object
|
||||||
Spline taperObject = null;
|
Spline taperObject = null;
|
||||||
Pointer pTaperObject = (Pointer) curveStructure.getFieldValue("taperobj");
|
Pointer pTaperObject = (Pointer) curveStructure.getFieldValue("taperobj");
|
||||||
if (bevelObject != null && pTaperObject.isNotNull()) {
|
if (bevelObject != null && pTaperObject.isNotNull()) {
|
||||||
@ -214,20 +212,20 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vector3f loc = this.getLoc(curveStructure);
|
Vector3f loc = this.getLoc(curveStructure);
|
||||||
//creating the result curves
|
// creating the result curves
|
||||||
List<Geometry> result = new ArrayList<Geometry>(nurbs.size());
|
List<Geometry> result = new ArrayList<Geometry>(nurbs.size());
|
||||||
for (Entry<Number, List<Structure>> nurbEntry : nurbs.entrySet()) {
|
for (Entry<Number, List<Structure>> nurbEntry : nurbs.entrySet()) {
|
||||||
for (Structure nurb : nurbEntry.getValue()) {
|
for (Structure nurb : nurbEntry.getValue()) {
|
||||||
int type = ((Number) nurb.getFieldValue("type")).intValue();
|
int type = ((Number) nurb.getFieldValue("type")).intValue();
|
||||||
List<Geometry> nurbGeoms = null;
|
List<Geometry> nurbGeoms = null;
|
||||||
if ((type & 0x01) != 0) {//Bezier curve
|
if ((type & 0x01) != 0) {// Bezier curve
|
||||||
nurbGeoms = this.loadBezierCurve(loc, nurb, bevelObject, taperObject, blenderContext);
|
nurbGeoms = this.loadBezierCurve(loc, nurb, bevelObject, taperObject, blenderContext);
|
||||||
} else if ((type & 0x04) != 0) {//NURBS
|
} else if ((type & 0x04) != 0) {// NURBS
|
||||||
nurbGeoms = this.loadNurb(loc, nurb, bevelObject, taperObject, blenderContext);
|
nurbGeoms = this.loadNurb(loc, nurb, bevelObject, taperObject, blenderContext);
|
||||||
}
|
}
|
||||||
if (nurbGeoms != null) {//setting the name and assigning materials
|
if (nurbGeoms != null) {// setting the name and assigning materials
|
||||||
for (Geometry nurbGeom : nurbGeoms) {
|
for (Geometry nurbGeom : nurbGeoms) {
|
||||||
if(materialContexts != null) {
|
if (materialContexts != null) {
|
||||||
materialContexts[nurbEntry.getKey().intValue()].applyMaterial(nurbGeom, curveStructure.getOldMemoryAddress(), null, blenderContext);
|
materialContexts[nurbEntry.getKey().intValue()].applyMaterial(nurbGeom, curveStructure.getOldMemoryAddress(), null, blenderContext);
|
||||||
} else {
|
} else {
|
||||||
nurbGeom.setMaterial(defaultMaterial);
|
nurbGeom.setMaterial(defaultMaterial);
|
||||||
@ -239,11 +237,11 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading custom properties
|
// reading custom properties
|
||||||
if(blenderContext.getBlenderKey().isLoadObjectProperties()) {
|
if (blenderContext.getBlenderKey().isLoadObjectProperties()) {
|
||||||
Properties properties = this.loadProperties(curveStructure, blenderContext);
|
Properties properties = this.loadProperties(curveStructure, blenderContext);
|
||||||
//the loaded property is a group property, so we need to get each value and set it to Spatial
|
// the loaded property is a group property, so we need to get each value and set it to Spatial
|
||||||
if(result instanceof Spatial && properties != null && properties.getValue() != null) {
|
if (result instanceof Spatial && properties != null && properties.getValue() != null) {
|
||||||
this.applyProperties((Spatial) result, properties);
|
this.applyProperties((Spatial) result, properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -267,8 +265,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
* @throws BlenderFileException
|
* @throws BlenderFileException
|
||||||
* an exception is thrown when there are problems with the blender file
|
* an exception is thrown when there are problems with the blender file
|
||||||
*/
|
*/
|
||||||
protected List<Geometry> loadBezierCurve(Vector3f loc, Structure nurb, List<Geometry> bevelObject, Spline taperObject,
|
protected List<Geometry> loadBezierCurve(Vector3f loc, Structure nurb, List<Geometry> bevelObject, Spline taperObject, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
BlenderContext blenderContext) throws BlenderFileException {
|
|
||||||
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
|
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
|
||||||
List<Geometry> result = new ArrayList<Geometry>();
|
List<Geometry> result = new ArrayList<Geometry>();
|
||||||
if (pBezierTriple.isNotNull()) {
|
if (pBezierTriple.isNotNull()) {
|
||||||
@ -276,11 +273,11 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
int resolution = ((Number) nurb.getFieldValue("resolu")).intValue();
|
int resolution = ((Number) nurb.getFieldValue("resolu")).intValue();
|
||||||
boolean cyclic = (((Number) nurb.getFieldValue("flagu")).intValue() & 0x01) != 0;
|
boolean cyclic = (((Number) nurb.getFieldValue("flagu")).intValue() & 0x01) != 0;
|
||||||
|
|
||||||
//creating the curve object
|
// creating the curve object
|
||||||
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(blenderContext.getInputStream()), 3);
|
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(blenderContext.getInputStream()), 3);
|
||||||
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
|
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
|
||||||
if(fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
for(Vector3f v : controlPoints) {
|
for (Vector3f v : controlPoints) {
|
||||||
float y = v.y;
|
float y = v.y;
|
||||||
v.y = v.z;
|
v.y = v.z;
|
||||||
v.z = -y;
|
v.z = -y;
|
||||||
@ -297,23 +294,23 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cyclic) {
|
if (cyclic) {
|
||||||
//copy the first three points at the end
|
// copy the first three points at the end
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
controlPoints.add(controlPoints.get(i));
|
controlPoints.add(controlPoints.get(i));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//removing the first and last handles
|
// removing the first and last handles
|
||||||
controlPoints.remove(0);
|
controlPoints.remove(0);
|
||||||
controlPoints.remove(controlPoints.size() - 1);
|
controlPoints.remove(controlPoints.size() - 1);
|
||||||
|
|
||||||
//creating curve
|
// creating curve
|
||||||
Spline spline = new Spline(SplineType.Bezier, controlPoints, 0, false);
|
Spline spline = new Spline(SplineType.Bezier, controlPoints, 0, false);
|
||||||
Curve curve = new Curve(spline, resolution);
|
Curve curve = new Curve(spline, resolution);
|
||||||
if (bevelObject == null) {//creating a normal curve
|
if (bevelObject == null) {// creating a normal curve
|
||||||
Geometry curveGeometry = new Geometry(null, curve);
|
Geometry curveGeometry = new Geometry(null, curve);
|
||||||
result.add(curveGeometry);
|
result.add(curveGeometry);
|
||||||
//TODO: use front and back flags; surface excluding algorithm for bezier circles should be added
|
// TODO: use front and back flags; surface excluding algorithm for bezier circles should be added
|
||||||
} else {//creating curve with bevel and taper shape
|
} else {// creating curve with bevel and taper shape
|
||||||
result = this.applyBevelAndTaper(curve, bevelObject, taperObject, smooth, blenderContext);
|
result = this.applyBevelAndTaper(curve, bevelObject, taperObject, smooth, blenderContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -337,11 +334,10 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
* an exception is throw when problems with blender loaded data occurs
|
* an exception is throw when problems with blender loaded data occurs
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
protected List<Geometry> loadNurb(Vector3f loc, Structure nurb, List<Geometry> bevelObject, Spline taperObject,
|
protected List<Geometry> loadNurb(Vector3f loc, Structure nurb, List<Geometry> bevelObject, Spline taperObject, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
BlenderContext blenderContext) throws BlenderFileException {
|
// loading the knots
|
||||||
//loading the knots
|
|
||||||
List<Float>[] knots = new List[2];
|
List<Float>[] knots = new List[2];
|
||||||
Pointer[] pKnots = new Pointer[]{(Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv")};
|
Pointer[] pKnots = new Pointer[] { (Pointer) nurb.getFieldValue("knotsu"), (Pointer) nurb.getFieldValue("knotsv") };
|
||||||
for (int i = 0; i < knots.length; ++i) {
|
for (int i = 0; i < knots.length; ++i) {
|
||||||
if (pKnots[i].isNotNull()) {
|
if (pKnots[i].isNotNull()) {
|
||||||
FileBlockHeader fileBlockHeader = blenderContext.getFileBlock(pKnots[i].getOldMemoryAddress());
|
FileBlockHeader fileBlockHeader = blenderContext.getFileBlock(pKnots[i].getOldMemoryAddress());
|
||||||
@ -355,13 +351,13 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//loading the flags and orders (basis functions degrees)
|
// loading the flags and orders (basis functions degrees)
|
||||||
int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
|
int flagU = ((Number) nurb.getFieldValue("flagu")).intValue();
|
||||||
int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
|
int flagV = ((Number) nurb.getFieldValue("flagv")).intValue();
|
||||||
int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
|
int orderU = ((Number) nurb.getFieldValue("orderu")).intValue();
|
||||||
int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
|
int orderV = ((Number) nurb.getFieldValue("orderv")).intValue();
|
||||||
|
|
||||||
//loading control points and their weights
|
// loading control points and their weights
|
||||||
int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
|
int pntsU = ((Number) nurb.getFieldValue("pntsu")).intValue();
|
||||||
int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
|
int pntsV = ((Number) nurb.getFieldValue("pntsv")).intValue();
|
||||||
List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData(blenderContext.getInputStream());
|
List<Structure> bPoints = ((Pointer) nurb.getFieldValue("bp")).fetchData(blenderContext.getInputStream());
|
||||||
@ -391,17 +387,17 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
int resolu = ((Number) nurb.getFieldValue("resolu")).intValue() + 1;
|
int resolu = ((Number) nurb.getFieldValue("resolu")).intValue() + 1;
|
||||||
List<Geometry> result;
|
List<Geometry> result;
|
||||||
if (knots[1] == null) {//creating the curve
|
if (knots[1] == null) {// creating the curve
|
||||||
Spline nurbSpline = new Spline(controlPoints.get(0), knots[0]);
|
Spline nurbSpline = new Spline(controlPoints.get(0), knots[0]);
|
||||||
Curve nurbCurve = new Curve(nurbSpline, resolu);
|
Curve nurbCurve = new Curve(nurbSpline, resolu);
|
||||||
if (bevelObject != null) {
|
if (bevelObject != null) {
|
||||||
result = this.applyBevelAndTaper(nurbCurve, bevelObject, taperObject, true, blenderContext);//TODO: smooth
|
result = this.applyBevelAndTaper(nurbCurve, bevelObject, taperObject, true, blenderContext);// TODO: smooth
|
||||||
} else {
|
} else {
|
||||||
result = new ArrayList<Geometry>(1);
|
result = new ArrayList<Geometry>(1);
|
||||||
Geometry nurbGeometry = new Geometry("", nurbCurve);
|
Geometry nurbGeometry = new Geometry("", nurbCurve);
|
||||||
result.add(nurbGeometry);
|
result.add(nurbGeometry);
|
||||||
}
|
}
|
||||||
} else {//creating the nurb surface
|
} else {// creating the nurb surface
|
||||||
int resolv = ((Number) nurb.getFieldValue("resolv")).intValue() + 1;
|
int resolv = ((Number) nurb.getFieldValue("resolv")).intValue() + 1;
|
||||||
Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, resolu, resolv, orderU, orderV);
|
Surface nurbSurface = Surface.createNurbsSurface(controlPoints, knots, resolu, resolv, orderU, orderV);
|
||||||
Geometry nurbGeometry = new Geometry("", nurbSurface);
|
Geometry nurbGeometry = new Geometry("", nurbSurface);
|
||||||
@ -421,8 +417,8 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
* @return scale on the pointed place along the curve
|
* @return scale on the pointed place along the curve
|
||||||
*/
|
*/
|
||||||
protected float getTaperScale(Spline taper, float percent) {
|
protected float getTaperScale(Spline taper, float percent) {
|
||||||
if(taper == null) {
|
if (taper == null) {
|
||||||
return 1;//return scale = 1 if no taper is applied
|
return 1;// return scale = 1 if no taper is applied
|
||||||
}
|
}
|
||||||
percent = FastMath.clamp(percent, 0, 1);
|
percent = FastMath.clamp(percent, 0, 1);
|
||||||
List<Float> segmentLengths = taper.getSegmentsLength();
|
List<Float> segmentLengths = taper.getSegmentsLength();
|
||||||
@ -463,8 +459,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
* the blender context
|
* the blender context
|
||||||
* @return a list of geometries representing the beveled and/or tapered curve
|
* @return a list of geometries representing the beveled and/or tapered curve
|
||||||
*/
|
*/
|
||||||
protected List<Geometry> applyBevelAndTaper(Curve curve, List<Geometry> bevelObject, Spline taperObject,
|
protected List<Geometry> applyBevelAndTaper(Curve curve, List<Geometry> bevelObject, Spline taperObject, boolean smooth, BlenderContext blenderContext) {
|
||||||
boolean smooth, BlenderContext blenderContext) {
|
|
||||||
Vector3f[] curvePoints = BufferUtils.getVector3Array(curve.getFloatBuffer(Type.Position));
|
Vector3f[] curvePoints = BufferUtils.getVector3Array(curve.getFloatBuffer(Type.Position));
|
||||||
Vector3f subtractResult = new Vector3f();
|
Vector3f subtractResult = new Vector3f();
|
||||||
float curveLength = curve.getLength();
|
float curveLength = curve.getLength();
|
||||||
@ -488,14 +483,14 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
bevelPoints = this.transformBevel(bevelPoints, curvePoints[curvePoints.length - 2], curvePoints[curvePoints.length - 1], null);
|
bevelPoints = this.transformBevel(bevelPoints, curvePoints[curvePoints.length - 2], curvePoints[curvePoints.length - 1], null);
|
||||||
bevels.add(bevelPoints);
|
bevels.add(bevelPoints);
|
||||||
|
|
||||||
if(bevels.size() > 2) {
|
if (bevels.size() > 2) {
|
||||||
//changing the first and last bevel so that they are parallel to their neighbours (blender works this way)
|
// changing the first and last bevel so that they are parallel to their neighbours (blender works this way)
|
||||||
//notice this implicates that the distances of every corresponding point in th two bevels must be identical and
|
// notice this implicates that the distances of every corresponding point in th two bevels must be identical and
|
||||||
//equal to the distance between the points on curve that define the bevel position
|
// equal to the distance between the points on curve that define the bevel position
|
||||||
//so instead doing complicated rotations on each point we will simply properly translate each of them
|
// so instead doing complicated rotations on each point we will simply properly translate each of them
|
||||||
|
|
||||||
int[][] pointIndexes = new int[][] { { 0, 1 }, { curvePoints.length - 1, curvePoints.length - 2 } };
|
int[][] pointIndexes = new int[][] { { 0, 1 }, { curvePoints.length - 1, curvePoints.length - 2 } };
|
||||||
for(int[] indexes : pointIndexes) {
|
for (int[] indexes : pointIndexes) {
|
||||||
float distance = curvePoints[indexes[1]].subtract(curvePoints[indexes[0]], subtractResult).length();
|
float distance = curvePoints[indexes[1]].subtract(curvePoints[indexes[0]], subtractResult).length();
|
||||||
Vector3f[] bevel = bevels.get(indexes[0]);
|
Vector3f[] bevel = bevels.get(indexes[0]);
|
||||||
Vector3f[] nextBevel = bevels.get(indexes[1]);
|
Vector3f[] nextBevel = bevels.get(indexes[1]);
|
||||||
@ -507,28 +502,28 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//apply scales to the bevels
|
// apply scales to the bevels
|
||||||
float lengthAlongCurve = 0;
|
float lengthAlongCurve = 0;
|
||||||
for(int i=0;i<curvePoints.length; ++i) {
|
for (int i = 0; i < curvePoints.length; ++i) {
|
||||||
if(i > 0) {
|
if (i > 0) {
|
||||||
lengthAlongCurve += curvePoints[i].subtract(curvePoints[i - 1], subtractResult).length();
|
lengthAlongCurve += curvePoints[i].subtract(curvePoints[i - 1], subtractResult).length();
|
||||||
}
|
}
|
||||||
float taperScale = this.getTaperScale(taperObject, i == 0 ? 0 : lengthAlongCurve / curveLength);
|
float taperScale = this.getTaperScale(taperObject, i == 0 ? 0 : lengthAlongCurve / curveLength);
|
||||||
this.applyScale(bevels.get(i), curvePoints[i], taperScale);
|
this.applyScale(bevels.get(i), curvePoints[i], taperScale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(smooth) {//add everything to the buffer
|
if (smooth) {// add everything to the buffer
|
||||||
for(Vector3f[] bevel : bevels) {
|
for (Vector3f[] bevel : bevels) {
|
||||||
for(Vector3f d : bevel) {
|
for (Vector3f d : bevel) {
|
||||||
vertexBuffers[geomIndex].put(d.x);
|
vertexBuffers[geomIndex].put(d.x);
|
||||||
vertexBuffers[geomIndex].put(d.y);
|
vertexBuffers[geomIndex].put(d.y);
|
||||||
vertexBuffers[geomIndex].put(d.z);
|
vertexBuffers[geomIndex].put(d.z);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {//add vertices to the buffer duplicating them so that every vertex belongs only to a single triangle
|
} else {// add vertices to the buffer duplicating them so that every vertex belongs only to a single triangle
|
||||||
for (int i = 0; i < curvePoints.length - 1; ++i) {
|
for (int i = 0; i < curvePoints.length - 1; ++i) {
|
||||||
for (int j = 0; j < bevelPoints.length - 1; ++j) {
|
for (int j = 0; j < bevelPoints.length - 1; ++j) {
|
||||||
//first triangle
|
// first triangle
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j].x);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j].x);
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j].y);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j].y);
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j].z);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j].z);
|
||||||
@ -539,7 +534,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
vertexBuffers[geomIndex].put(bevels.get(i + 1)[j].y);
|
vertexBuffers[geomIndex].put(bevels.get(i + 1)[j].y);
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i + 1)[j].z);
|
vertexBuffers[geomIndex].put(bevels.get(i + 1)[j].z);
|
||||||
|
|
||||||
//second triangle
|
// second triangle
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].x);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].x);
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].y);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].y);
|
||||||
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].z);
|
vertexBuffers[geomIndex].put(bevels.get(i)[j + 1].z);
|
||||||
@ -557,16 +552,16 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
normalBuffers[geomIndex] = this.generateNormals(indexBuffers[geomIndex], vertexBuffers[geomIndex], smooth);
|
normalBuffers[geomIndex] = this.generateNormals(indexBuffers[geomIndex], vertexBuffers[geomIndex], smooth);
|
||||||
}
|
}
|
||||||
|
|
||||||
//creating and returning the result
|
// creating and returning the result
|
||||||
List<Geometry> result = new ArrayList<Geometry>(vertexBuffers.length);
|
List<Geometry> result = new ArrayList<Geometry>(vertexBuffers.length);
|
||||||
Float oneReferenceToCurveLength = new Float(curveLength);//its important for array modifier to use one reference here
|
Float oneReferenceToCurveLength = new Float(curveLength);// its important for array modifier to use one reference here
|
||||||
for (int i = 0; i < vertexBuffers.length; ++i) {
|
for (int i = 0; i < vertexBuffers.length; ++i) {
|
||||||
Mesh mesh = new Mesh();
|
Mesh mesh = new Mesh();
|
||||||
mesh.setBuffer(Type.Position, 3, vertexBuffers[i]);
|
mesh.setBuffer(Type.Position, 3, vertexBuffers[i]);
|
||||||
if(indexBuffers[i].getBuffer() instanceof IntBuffer) {
|
if (indexBuffers[i].getBuffer() instanceof IntBuffer) {
|
||||||
mesh.setBuffer(Type.Index, 3, (IntBuffer)indexBuffers[i].getBuffer());
|
mesh.setBuffer(Type.Index, 3, (IntBuffer) indexBuffers[i].getBuffer());
|
||||||
} else {
|
} else {
|
||||||
mesh.setBuffer(Type.Index, 3, (ShortBuffer)indexBuffers[i].getBuffer());
|
mesh.setBuffer(Type.Index, 3, (ShortBuffer) indexBuffers[i].getBuffer());
|
||||||
}
|
}
|
||||||
mesh.setBuffer(Type.Normal, 3, normalBuffers[i]);
|
mesh.setBuffer(Type.Normal, 3, normalBuffers[i]);
|
||||||
Geometry g = new Geometry("g" + i, mesh);
|
Geometry g = new Geometry("g" + i, mesh);
|
||||||
@ -649,7 +644,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
*/
|
*/
|
||||||
private IndexBuffer generateIndexes(int bevelShapeVertexCount, int bevelRepeats, boolean smooth) {
|
private IndexBuffer generateIndexes(int bevelShapeVertexCount, int bevelRepeats, boolean smooth) {
|
||||||
int putIndex = 0;
|
int putIndex = 0;
|
||||||
if(smooth) {
|
if (smooth) {
|
||||||
int indexBufferSize = (bevelRepeats - 1) * (bevelShapeVertexCount - 1) * 6;
|
int indexBufferSize = (bevelRepeats - 1) * (bevelShapeVertexCount - 1) * 6;
|
||||||
IndexBuffer result = IndexBuffer.createIndexBuffer(indexBufferSize, indexBufferSize);
|
IndexBuffer result = IndexBuffer.createIndexBuffer(indexBufferSize, indexBufferSize);
|
||||||
|
|
||||||
@ -666,11 +661,11 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
} else {
|
} else {
|
||||||
//every pair of bevel vertices belongs to two triangles
|
// every pair of bevel vertices belongs to two triangles
|
||||||
//we have the same amount of pairs as the amount of vertices in bevel
|
// we have the same amount of pairs as the amount of vertices in bevel
|
||||||
//so the amount of triangles is: bevelShapeVertexCount * 2 * (bevelRepeats - 1)
|
// so the amount of triangles is: bevelShapeVertexCount * 2 * (bevelRepeats - 1)
|
||||||
//and this gives the amount of vertices in non smooth shape as below ...
|
// and this gives the amount of vertices in non smooth shape as below ...
|
||||||
int indexBufferSize = bevelShapeVertexCount * bevelRepeats * 6;//6 = 2 * 3 where 2 is stated above and 3 is the count of vertices for each triangle
|
int indexBufferSize = bevelShapeVertexCount * bevelRepeats * 6;// 6 = 2 * 3 where 2 is stated above and 3 is the count of vertices for each triangle
|
||||||
IndexBuffer result = IndexBuffer.createIndexBuffer(indexBufferSize, indexBufferSize);
|
IndexBuffer result = IndexBuffer.createIndexBuffer(indexBufferSize, indexBufferSize);
|
||||||
for (int i = 0; i < indexBufferSize; ++i) {
|
for (int i = 0; i < indexBufferSize; ++i) {
|
||||||
result.put(putIndex++, i);
|
result.put(putIndex++, i);
|
||||||
@ -696,28 +691,28 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
private Vector3f[] transformBevel(Vector3f[] bevel, Vector3f prevPos, Vector3f currPos, Vector3f nextPos) {
|
private Vector3f[] transformBevel(Vector3f[] bevel, Vector3f prevPos, Vector3f currPos, Vector3f nextPos) {
|
||||||
bevel = bevel.clone();
|
bevel = bevel.clone();
|
||||||
|
|
||||||
//currPos and directionVector define the line in 3D space
|
// currPos and directionVector define the line in 3D space
|
||||||
Vector3f directionVector = prevPos != null ? currPos.subtract(prevPos) : nextPos.subtract(currPos);
|
Vector3f directionVector = prevPos != null ? currPos.subtract(prevPos) : nextPos.subtract(currPos);
|
||||||
directionVector.normalizeLocal();
|
directionVector.normalizeLocal();
|
||||||
|
|
||||||
//plane is described by equation: Ax + By + Cz + D = 0 where planeNormal = [A, B, C] and D = -(Ax + By + Cz)
|
// plane is described by equation: Ax + By + Cz + D = 0 where planeNormal = [A, B, C] and D = -(Ax + By + Cz)
|
||||||
Vector3f planeNormal = null;
|
Vector3f planeNormal = null;
|
||||||
if(prevPos != null) {
|
if (prevPos != null) {
|
||||||
planeNormal = currPos.subtract(prevPos).normalizeLocal();
|
planeNormal = currPos.subtract(prevPos).normalizeLocal();
|
||||||
if(nextPos != null) {
|
if (nextPos != null) {
|
||||||
planeNormal.addLocal(nextPos.subtract(currPos).normalizeLocal()).normalizeLocal();
|
planeNormal.addLocal(nextPos.subtract(currPos).normalizeLocal()).normalizeLocal();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
planeNormal = nextPos.subtract(currPos).normalizeLocal();
|
planeNormal = nextPos.subtract(currPos).normalizeLocal();
|
||||||
}
|
}
|
||||||
float D = -planeNormal.dot(currPos);//D = -(Ax + By + Cz)
|
float D = -planeNormal.dot(currPos);// D = -(Ax + By + Cz)
|
||||||
|
|
||||||
//now we need to compute paralell cast of each bevel point on the plane, the leading line is already known
|
// now we need to compute paralell cast of each bevel point on the plane, the leading line is already known
|
||||||
//parametric equation of a line: x = px + vx * t; y = py + vy * t; z = pz + vz * t
|
// parametric equation of a line: x = px + vx * t; y = py + vy * t; z = pz + vz * t
|
||||||
//where p = currPos and v = directionVector
|
// where p = currPos and v = directionVector
|
||||||
//using x, y and z in plane equation we get value of 't' that will allow us to compute the point where plane and line cross
|
// using x, y and z in plane equation we get value of 't' that will allow us to compute the point where plane and line cross
|
||||||
float temp = planeNormal.dot(directionVector);
|
float temp = planeNormal.dot(directionVector);
|
||||||
for(int i=0;i<bevel.length;++i) {
|
for (int i = 0; i < bevel.length; ++i) {
|
||||||
float t = -(planeNormal.dot(bevel[i]) + D) / temp;
|
float t = -(planeNormal.dot(bevel[i]) + D) / temp;
|
||||||
if (fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
bevel[i] = new Vector3f(bevel[i].x + directionVector.x * t, bevel[i].y + directionVector.y * t, bevel[i].z + directionVector.z * t);
|
bevel[i] = new Vector3f(bevel[i].x + directionVector.x * t, bevel[i].y + directionVector.y * t, bevel[i].z + directionVector.z * t);
|
||||||
@ -744,7 +739,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
Vector3f planeNormal = secondCurvePoint.subtract(firstCurvePoint).normalizeLocal();
|
Vector3f planeNormal = secondCurvePoint.subtract(firstCurvePoint).normalizeLocal();
|
||||||
|
|
||||||
float angle = FastMath.acos(planeNormal.dot(Vector3f.UNIT_Y));
|
float angle = FastMath.acos(planeNormal.dot(Vector3f.UNIT_Y));
|
||||||
planeNormal.crossLocal(Vector3f.UNIT_Y).normalizeLocal();//planeNormal is the rotation axis now
|
planeNormal.crossLocal(Vector3f.UNIT_Y).normalizeLocal();// planeNormal is the rotation axis now
|
||||||
Quaternion pointRotation = new Quaternion();
|
Quaternion pointRotation = new Quaternion();
|
||||||
pointRotation.fromAngleAxis(angle, planeNormal);
|
pointRotation.fromAngleAxis(angle, planeNormal);
|
||||||
|
|
||||||
@ -758,7 +753,7 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
temp[0] = startingLinePoints[j].x;
|
temp[0] = startingLinePoints[j].x;
|
||||||
temp[1] = startingLinePoints[j].y;
|
temp[1] = startingLinePoints[j].y;
|
||||||
temp[2] = startingLinePoints[j].z;
|
temp[2] = startingLinePoints[j].z;
|
||||||
temp = m.mult(temp);//the result is stored in the array
|
temp = m.mult(temp);// the result is stored in the array
|
||||||
if (fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
verts[j] = new Vector3f(temp[0], -temp[2], temp[1]);
|
verts[j] = new Vector3f(temp[0], -temp[2], temp[1]);
|
||||||
} else {
|
} else {
|
||||||
@ -803,19 +798,19 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
* @throws BlenderFileException
|
* @throws BlenderFileException
|
||||||
*/
|
*/
|
||||||
protected Spline loadTaperObject(Structure taperStructure, BlenderContext blenderContext) throws BlenderFileException {
|
protected Spline loadTaperObject(Structure taperStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
//reading nurbs
|
// reading nurbs
|
||||||
List<Structure> nurbStructures = ((Structure) taperStructure.getFieldValue("nurb")).evaluateListBase(blenderContext);
|
List<Structure> nurbStructures = ((Structure) taperStructure.getFieldValue("nurb")).evaluateListBase(blenderContext);
|
||||||
for (Structure nurb : nurbStructures) {
|
for (Structure nurb : nurbStructures) {
|
||||||
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
|
Pointer pBezierTriple = (Pointer) nurb.getFieldValue("bezt");
|
||||||
if (pBezierTriple.isNotNull()) {
|
if (pBezierTriple.isNotNull()) {
|
||||||
//creating the curve object
|
// creating the curve object
|
||||||
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(blenderContext.getInputStream()), 3);
|
BezierCurve bezierCurve = new BezierCurve(0, pBezierTriple.fetchData(blenderContext.getInputStream()), 3);
|
||||||
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
|
List<Vector3f> controlPoints = bezierCurve.getControlPoints();
|
||||||
//removing the first and last handles
|
// removing the first and last handles
|
||||||
controlPoints.remove(0);
|
controlPoints.remove(0);
|
||||||
controlPoints.remove(controlPoints.size() - 1);
|
controlPoints.remove(controlPoints.size() - 1);
|
||||||
|
|
||||||
//return the first taper curve that has more than 3 control points
|
// return the first taper curve that has more than 3 control points
|
||||||
if (controlPoints.size() > 3) {
|
if (controlPoints.size() > 3) {
|
||||||
return new Spline(SplineType.Bezier, controlPoints, 0, false);
|
return new Spline(SplineType.Bezier, controlPoints, 0, false);
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@ public class BlenderFileException extends Exception {
|
|||||||
* Constructor. Creates an exception with no description.
|
* Constructor. Creates an exception with no description.
|
||||||
*/
|
*/
|
||||||
public BlenderFileException() {
|
public BlenderFileException() {
|
||||||
//this constructor has no message
|
// this constructor has no message
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -48,7 +48,7 @@ public class BlenderInputStream extends InputStream {
|
|||||||
|
|
||||||
private static final Logger LOGGER = Logger.getLogger(BlenderInputStream.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(BlenderInputStream.class.getName());
|
||||||
/** The default size of the blender buffer. */
|
/** The default size of the blender buffer. */
|
||||||
private static final int DEFAULT_BUFFER_SIZE = 1048576; //1MB
|
private static final int DEFAULT_BUFFER_SIZE = 1048576; // 1MB
|
||||||
/**
|
/**
|
||||||
* Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes and '-' means 8 bytes.
|
* Size of a pointer; all pointers in the file are stored in this format. '_' means 4 bytes and '-' means 8 bytes.
|
||||||
*/
|
*/
|
||||||
@ -74,7 +74,7 @@ public class BlenderInputStream extends InputStream {
|
|||||||
* this exception is thrown if the file header has some invalid data
|
* this exception is thrown if the file header has some invalid data
|
||||||
*/
|
*/
|
||||||
public BlenderInputStream(InputStream inputStream) throws BlenderFileException {
|
public BlenderInputStream(InputStream inputStream) throws BlenderFileException {
|
||||||
//the size value will canche while reading the file; the available() method cannot be counted on
|
// the size value will canche while reading the file; the available() method cannot be counted on
|
||||||
try {
|
try {
|
||||||
size = inputStream.available();
|
size = inputStream.available();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
@ -84,7 +84,7 @@ public class BlenderInputStream extends InputStream {
|
|||||||
size = BlenderInputStream.DEFAULT_BUFFER_SIZE;
|
size = BlenderInputStream.DEFAULT_BUFFER_SIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
//buffered input stream is used here for much faster file reading
|
// buffered input stream is used here for much faster file reading
|
||||||
BufferedInputStream bufferedInputStream;
|
BufferedInputStream bufferedInputStream;
|
||||||
if (inputStream instanceof BufferedInputStream) {
|
if (inputStream instanceof BufferedInputStream) {
|
||||||
bufferedInputStream = (BufferedInputStream) inputStream;
|
bufferedInputStream = (BufferedInputStream) inputStream;
|
||||||
@ -106,7 +106,7 @@ public class BlenderInputStream extends InputStream {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
this.readFileHeader();
|
this.readFileHeader();
|
||||||
} catch (BlenderFileException e) {//the file might be packed, don't panic, try one more time ;)
|
} catch (BlenderFileException e) {// the file might be packed, don't panic, try one more time ;)
|
||||||
this.decompressFile();
|
this.decompressFile();
|
||||||
this.position = 0;
|
this.position = 0;
|
||||||
this.readFileHeader();
|
this.readFileHeader();
|
||||||
@ -124,9 +124,9 @@ public class BlenderInputStream extends InputStream {
|
|||||||
private void readStreamToCache(InputStream inputStream) throws IOException {
|
private void readStreamToCache(InputStream inputStream) throws IOException {
|
||||||
int data = inputStream.read();
|
int data = inputStream.read();
|
||||||
cachedBuffer = new byte[size];
|
cachedBuffer = new byte[size];
|
||||||
size = 0;//this will count the actual size
|
size = 0;// this will count the actual size
|
||||||
while (data != -1) {
|
while (data != -1) {
|
||||||
if (size >= cachedBuffer.length) {//widen the cached array
|
if (size >= cachedBuffer.length) {// widen the cached array
|
||||||
byte[] newBuffer = new byte[cachedBuffer.length + (cachedBuffer.length >> 1)];
|
byte[] newBuffer = new byte[cachedBuffer.length + (cachedBuffer.length >> 1)];
|
||||||
System.arraycopy(cachedBuffer, 0, newBuffer, 0, cachedBuffer.length);
|
System.arraycopy(cachedBuffer, 0, newBuffer, 0, cachedBuffer.length);
|
||||||
cachedBuffer = newBuffer;
|
cachedBuffer = newBuffer;
|
||||||
@ -146,8 +146,7 @@ public class BlenderInputStream extends InputStream {
|
|||||||
gis = new GZIPInputStream(new ByteArrayInputStream(cachedBuffer));
|
gis = new GZIPInputStream(new ByteArrayInputStream(cachedBuffer));
|
||||||
this.readStreamToCache(gis);
|
this.readStreamToCache(gis);
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new IllegalStateException("IO errors occured where they should NOT! "
|
throw new IllegalStateException("IO errors occured where they should NOT! " + "The data is already buffered at this point!", e);
|
||||||
+ "The data is already buffered at this point!", e);
|
|
||||||
} finally {
|
} finally {
|
||||||
try {
|
try {
|
||||||
if (gis != null) {
|
if (gis != null) {
|
||||||
@ -366,10 +365,10 @@ public class BlenderInputStream extends InputStream {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
//this method is unimplemented because some loaders (ie. TGALoader) have flaws that close the stream given from the outside
|
// this method is unimplemented because some loaders (ie. TGALoader) have flaws that close the stream given from the outside
|
||||||
//because the images can be stored directly in the blender file then this stream is properly positioned and given to the loader
|
// because the images can be stored directly in the blender file then this stream is properly positioned and given to the loader
|
||||||
//to read the image file, that is why we do not want it to be closed before the reading is done
|
// to read the image file, that is why we do not want it to be closed before the reading is done
|
||||||
//to properly close the stream use forceClose() method
|
// to properly close the stream use forceClose() method
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,11 +42,11 @@ import java.util.Map;
|
|||||||
*/
|
*/
|
||||||
public class DnaBlockData {
|
public class DnaBlockData {
|
||||||
|
|
||||||
private static final int SDNA_ID = 'S' << 24 | 'D' << 16 | 'N' << 8 | 'A'; //SDNA
|
private static final int SDNA_ID = 'S' << 24 | 'D' << 16 | 'N' << 8 | 'A'; // SDNA
|
||||||
private static final int NAME_ID = 'N' << 24 | 'A' << 16 | 'M' << 8 | 'E'; //NAME
|
private static final int NAME_ID = 'N' << 24 | 'A' << 16 | 'M' << 8 | 'E'; // NAME
|
||||||
private static final int TYPE_ID = 'T' << 24 | 'Y' << 16 | 'P' << 8 | 'E'; //TYPE
|
private static final int TYPE_ID = 'T' << 24 | 'Y' << 16 | 'P' << 8 | 'E'; // TYPE
|
||||||
private static final int TLEN_ID = 'T' << 24 | 'L' << 16 | 'E' << 8 | 'N'; //TLEN
|
private static final int TLEN_ID = 'T' << 24 | 'L' << 16 | 'E' << 8 | 'N'; // TLEN
|
||||||
private static final int STRC_ID = 'S' << 24 | 'T' << 16 | 'R' << 8 | 'C'; //STRC
|
private static final int STRC_ID = 'S' << 24 | 'T' << 16 | 'R' << 8 | 'C'; // STRC
|
||||||
/** Structures available inside the file. */
|
/** Structures available inside the file. */
|
||||||
private final Structure[] structures;
|
private final Structure[] structures;
|
||||||
/** A map that helps finding a structure by type. */
|
/** A map that helps finding a structure by type. */
|
||||||
@ -64,17 +64,15 @@ public class DnaBlockData {
|
|||||||
public DnaBlockData(BlenderInputStream inputStream, BlenderContext blenderContext) throws BlenderFileException {
|
public DnaBlockData(BlenderInputStream inputStream, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
int identifier;
|
int identifier;
|
||||||
|
|
||||||
//reading 'SDNA' identifier
|
// reading 'SDNA' identifier
|
||||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
|
|
||||||
if (identifier != SDNA_ID) {
|
if (identifier != SDNA_ID) {
|
||||||
throw new BlenderFileException("Invalid identifier! '" + this.toString(SDNA_ID) + "' expected and found: " + this.toString(identifier));
|
throw new BlenderFileException("Invalid identifier! '" + this.toString(SDNA_ID) + "' expected and found: " + this.toString(identifier));
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading names
|
// reading names
|
||||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
if (identifier != NAME_ID) {
|
if (identifier != NAME_ID) {
|
||||||
throw new BlenderFileException("Invalid identifier! '" + this.toString(NAME_ID) + "' expected and found: " + this.toString(identifier));
|
throw new BlenderFileException("Invalid identifier! '" + this.toString(NAME_ID) + "' expected and found: " + this.toString(identifier));
|
||||||
}
|
}
|
||||||
@ -87,10 +85,9 @@ public class DnaBlockData {
|
|||||||
names[i] = inputStream.readString();
|
names[i] = inputStream.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//reding types
|
// reding types
|
||||||
inputStream.alignPosition(4);
|
inputStream.alignPosition(4);
|
||||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
if (identifier != TYPE_ID) {
|
if (identifier != TYPE_ID) {
|
||||||
throw new BlenderFileException("Invalid identifier! '" + this.toString(TYPE_ID) + "' expected and found: " + this.toString(identifier));
|
throw new BlenderFileException("Invalid identifier! '" + this.toString(TYPE_ID) + "' expected and found: " + this.toString(identifier));
|
||||||
}
|
}
|
||||||
@ -103,22 +100,20 @@ public class DnaBlockData {
|
|||||||
types[i] = inputStream.readString();
|
types[i] = inputStream.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading lengths
|
// reading lengths
|
||||||
inputStream.alignPosition(4);
|
inputStream.alignPosition(4);
|
||||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
if (identifier != TLEN_ID) {
|
if (identifier != TLEN_ID) {
|
||||||
throw new BlenderFileException("Invalid identifier! '" + this.toString(TLEN_ID) + "' expected and found: " + this.toString(identifier));
|
throw new BlenderFileException("Invalid identifier! '" + this.toString(TLEN_ID) + "' expected and found: " + this.toString(identifier));
|
||||||
}
|
}
|
||||||
int[] lengths = new int[amount];//theamount is the same as int types
|
int[] lengths = new int[amount];// theamount is the same as int types
|
||||||
for (int i = 0; i < amount; ++i) {
|
for (int i = 0; i < amount; ++i) {
|
||||||
lengths[i] = inputStream.readShort();
|
lengths[i] = inputStream.readShort();
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading structures
|
// reading structures
|
||||||
inputStream.alignPosition(4);
|
inputStream.alignPosition(4);
|
||||||
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
identifier = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
if (identifier != STRC_ID) {
|
if (identifier != STRC_ID) {
|
||||||
throw new BlenderFileException("Invalid identifier! '" + this.toString(STRC_ID) + "' expected and found: " + this.toString(identifier));
|
throw new BlenderFileException("Invalid identifier! '" + this.toString(STRC_ID) + "' expected and found: " + this.toString(identifier));
|
||||||
}
|
}
|
||||||
|
@ -138,8 +138,8 @@ public class DynamicArray<T> implements Cloneable {
|
|||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
if (array instanceof Character[]) {//in case of character array we convert it to String
|
if (array instanceof Character[]) {// in case of character array we convert it to String
|
||||||
for (int i = 0; i < array.length && (Character) array[i] != '\0'; ++i) {//strings are terminater with '0'
|
for (int i = 0; i < array.length && (Character) array[i] != '\0'; ++i) {// strings are terminater with '0'
|
||||||
result.append(array[i]);
|
result.append(array[i]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -11,7 +11,7 @@ import java.util.List;
|
|||||||
* another structure.
|
* another structure.
|
||||||
* @author Marcin Roguski
|
* @author Marcin Roguski
|
||||||
*/
|
*/
|
||||||
/*package*/
|
/* package */
|
||||||
class Field implements Cloneable {
|
class Field implements Cloneable {
|
||||||
|
|
||||||
private static final int NAME_LENGTH = 24;
|
private static final int NAME_LENGTH = 24;
|
||||||
@ -107,9 +107,9 @@ class Field implements Cloneable {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CHARACTER:
|
case CHARACTER:
|
||||||
//character is also stored as a number, because sometimes the new blender version uses
|
// character is also stored as a number, because sometimes the new blender version uses
|
||||||
//other number type instead of character as a field type
|
// other number type instead of character as a field type
|
||||||
//and characters are very often used as byte number stores instead of real chars
|
// and characters are very often used as byte number stores instead of real chars
|
||||||
if (dataToRead == 1) {
|
if (dataToRead == 1) {
|
||||||
value = Byte.valueOf((byte) blenderInputStream.readByte());
|
value = Byte.valueOf((byte) blenderInputStream.readByte());
|
||||||
} else {
|
} else {
|
||||||
@ -206,22 +206,22 @@ class Field implements Cloneable {
|
|||||||
*/
|
*/
|
||||||
private void parseField(StringBuilder nameBuilder) throws BlenderFileException {
|
private void parseField(StringBuilder nameBuilder) throws BlenderFileException {
|
||||||
this.removeWhitespaces(nameBuilder);
|
this.removeWhitespaces(nameBuilder);
|
||||||
//veryfying if the name is a pointer
|
// veryfying if the name is a pointer
|
||||||
int pointerIndex = nameBuilder.indexOf("*");
|
int pointerIndex = nameBuilder.indexOf("*");
|
||||||
while (pointerIndex >= 0) {
|
while (pointerIndex >= 0) {
|
||||||
++pointerLevel;
|
++pointerLevel;
|
||||||
nameBuilder.deleteCharAt(pointerIndex);
|
nameBuilder.deleteCharAt(pointerIndex);
|
||||||
pointerIndex = nameBuilder.indexOf("*");
|
pointerIndex = nameBuilder.indexOf("*");
|
||||||
}
|
}
|
||||||
//veryfying if the name is a function pointer
|
// veryfying if the name is a function pointer
|
||||||
if (nameBuilder.indexOf("(") >= 0) {
|
if (nameBuilder.indexOf("(") >= 0) {
|
||||||
function = true;
|
function = true;
|
||||||
this.removeCharacter(nameBuilder, '(');
|
this.removeCharacter(nameBuilder, '(');
|
||||||
this.removeCharacter(nameBuilder, ')');
|
this.removeCharacter(nameBuilder, ')');
|
||||||
} else {
|
} else {
|
||||||
//veryfying if the name is a table
|
// veryfying if the name is a table
|
||||||
int tableStartIndex = 0;
|
int tableStartIndex = 0;
|
||||||
List<Integer> lengths = new ArrayList<Integer>(3);//3 dimensions will be enough in most cases
|
List<Integer> lengths = new ArrayList<Integer>(3);// 3 dimensions will be enough in most cases
|
||||||
do {
|
do {
|
||||||
tableStartIndex = nameBuilder.indexOf("[");
|
tableStartIndex = nameBuilder.indexOf("[");
|
||||||
if (tableStartIndex > 0) {
|
if (tableStartIndex > 0) {
|
||||||
@ -306,10 +306,10 @@ class Field implements Cloneable {
|
|||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
result.append(this.getFullName());
|
result.append(this.getFullName());
|
||||||
|
|
||||||
//insert appropriate amount of spaces to format the output corrently
|
// insert appropriate amount of spaces to format the output corrently
|
||||||
int nameLength = result.length();
|
int nameLength = result.length();
|
||||||
result.append(' ');//at least one space is a must
|
result.append(' ');// at least one space is a must
|
||||||
for (int i = 1; i < NAME_LENGTH - nameLength; ++i) {//we start from i=1 because one space is already added
|
for (int i = 1; i < NAME_LENGTH - nameLength; ++i) {// we start from i=1 because one space is already added
|
||||||
result.append(' ');
|
result.append(' ');
|
||||||
}
|
}
|
||||||
result.append(type);
|
result.append(type);
|
||||||
|
@ -41,23 +41,23 @@ import com.jme3.scene.plugins.blender.exceptions.BlenderFileException;
|
|||||||
*/
|
*/
|
||||||
public class FileBlockHeader {
|
public class FileBlockHeader {
|
||||||
|
|
||||||
public static final int BLOCK_TE00 = 'T' << 24 | 'E' << 16; //TE00
|
public static final int BLOCK_TE00 = 'T' << 24 | 'E' << 16; // TE00
|
||||||
public static final int BLOCK_ME00 = 'M' << 24 | 'E' << 16; //ME00
|
public static final int BLOCK_ME00 = 'M' << 24 | 'E' << 16; // ME00
|
||||||
public static final int BLOCK_SR00 = 'S' << 24 | 'R' << 16; //SR00
|
public static final int BLOCK_SR00 = 'S' << 24 | 'R' << 16; // SR00
|
||||||
public static final int BLOCK_CA00 = 'C' << 24 | 'A' << 16; //CA00
|
public static final int BLOCK_CA00 = 'C' << 24 | 'A' << 16; // CA00
|
||||||
public static final int BLOCK_LA00 = 'L' << 24 | 'A' << 16; //LA00
|
public static final int BLOCK_LA00 = 'L' << 24 | 'A' << 16; // LA00
|
||||||
public static final int BLOCK_OB00 = 'O' << 24 | 'B' << 16; //OB00
|
public static final int BLOCK_OB00 = 'O' << 24 | 'B' << 16; // OB00
|
||||||
public static final int BLOCK_MA00 = 'M' << 24 | 'A' << 16; //MA00
|
public static final int BLOCK_MA00 = 'M' << 24 | 'A' << 16; // MA00
|
||||||
public static final int BLOCK_SC00 = 'S' << 24 | 'C' << 16; //SC00
|
public static final int BLOCK_SC00 = 'S' << 24 | 'C' << 16; // SC00
|
||||||
public static final int BLOCK_WO00 = 'W' << 24 | 'O' << 16; //WO00
|
public static final int BLOCK_WO00 = 'W' << 24 | 'O' << 16; // WO00
|
||||||
public static final int BLOCK_TX00 = 'T' << 24 | 'X' << 16; //TX00
|
public static final int BLOCK_TX00 = 'T' << 24 | 'X' << 16; // TX00
|
||||||
public static final int BLOCK_IP00 = 'I' << 24 | 'P' << 16; //IP00
|
public static final int BLOCK_IP00 = 'I' << 24 | 'P' << 16; // IP00
|
||||||
public static final int BLOCK_AC00 = 'A' << 24 | 'C' << 16; //AC00
|
public static final int BLOCK_AC00 = 'A' << 24 | 'C' << 16; // AC00
|
||||||
public static final int BLOCK_GLOB = 'G' << 24 | 'L' << 16 | 'O' << 8 | 'B'; //GLOB
|
public static final int BLOCK_GLOB = 'G' << 24 | 'L' << 16 | 'O' << 8 | 'B'; // GLOB
|
||||||
public static final int BLOCK_REND = 'R' << 24 | 'E' << 16 | 'N' << 8 | 'D'; //REND
|
public static final int BLOCK_REND = 'R' << 24 | 'E' << 16 | 'N' << 8 | 'D'; // REND
|
||||||
public static final int BLOCK_DATA = 'D' << 24 | 'A' << 16 | 'T' << 8 | 'A'; //DATA
|
public static final int BLOCK_DATA = 'D' << 24 | 'A' << 16 | 'T' << 8 | 'A'; // DATA
|
||||||
public static final int BLOCK_DNA1 = 'D' << 24 | 'N' << 16 | 'A' << 8 | '1'; //DNA1
|
public static final int BLOCK_DNA1 = 'D' << 24 | 'N' << 16 | 'A' << 8 | '1'; // DNA1
|
||||||
public static final int BLOCK_ENDB = 'E' << 24 | 'N' << 16 | 'D' << 8 | 'B'; //ENDB
|
public static final int BLOCK_ENDB = 'E' << 24 | 'N' << 16 | 'D' << 8 | 'B'; // ENDB
|
||||||
/** Identifier of the file-block [4 bytes]. */
|
/** Identifier of the file-block [4 bytes]. */
|
||||||
private int code;
|
private int code;
|
||||||
/** Total length of the data after the file-block-header [4 bytes]. */
|
/** Total length of the data after the file-block-header [4 bytes]. */
|
||||||
@ -85,8 +85,7 @@ public class FileBlockHeader {
|
|||||||
*/
|
*/
|
||||||
public FileBlockHeader(BlenderInputStream inputStream, BlenderContext blenderContext) throws BlenderFileException {
|
public FileBlockHeader(BlenderInputStream inputStream, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
inputStream.alignPosition(4);
|
inputStream.alignPosition(4);
|
||||||
code = inputStream.readByte() << 24 | inputStream.readByte() << 16
|
code = inputStream.readByte() << 24 | inputStream.readByte() << 16 | inputStream.readByte() << 8 | inputStream.readByte();
|
||||||
| inputStream.readByte() << 8 | inputStream.readByte();
|
|
||||||
size = inputStream.readInt();
|
size = inputStream.readInt();
|
||||||
oldMemoryAddress = inputStream.readPointer();
|
oldMemoryAddress = inputStream.readPointer();
|
||||||
sdnaIndex = inputStream.readInt();
|
sdnaIndex = inputStream.readInt();
|
||||||
|
@ -90,9 +90,8 @@ public class Pointer {
|
|||||||
}
|
}
|
||||||
List<Structure> structures = null;
|
List<Structure> structures = null;
|
||||||
FileBlockHeader dataFileBlock = blenderContext.getFileBlock(oldMemoryAddress);
|
FileBlockHeader dataFileBlock = blenderContext.getFileBlock(oldMemoryAddress);
|
||||||
if(dataFileBlock == null) {
|
if (dataFileBlock == null) {
|
||||||
throw new BlenderFileException("No data stored for address: " +oldMemoryAddress +
|
throw new BlenderFileException("No data stored for address: " + oldMemoryAddress + ". Rarely blender makes mistakes when storing data. Try resaving the model after making minor changes. This usually helps.");
|
||||||
". Rarely blender makes mistakes when storing data. Try resaving the model after making minor changes. This usually helps.");
|
|
||||||
}
|
}
|
||||||
if (pointerLevel > 1) {
|
if (pointerLevel > 1) {
|
||||||
int pointersAmount = dataFileBlock.getSize() / inputStream.getPointerSize() * dataFileBlock.getCount();
|
int pointersAmount = dataFileBlock.getSize() / inputStream.getPointerSize() * dataFileBlock.getCount();
|
||||||
@ -108,9 +107,9 @@ public class Pointer {
|
|||||||
structures.addAll(p.fetchData(inputStream));
|
structures.addAll(p.fetchData(inputStream));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//it is necessary to put null's if the pointer is null, ie. in materials array that is attached to the mesh, the index
|
// it is necessary to put null's if the pointer is null, ie. in materials array that is attached to the mesh, the index
|
||||||
//of the material is important, that is why we need null's to indicate that some materials' slots are empty
|
// of the material is important, that is why we need null's to indicate that some materials' slots are empty
|
||||||
if(structures == null) {
|
if (structures == null) {
|
||||||
structures = new ArrayList<Structure>();
|
structures = new ArrayList<Structure>();
|
||||||
}
|
}
|
||||||
structures.add(null);
|
structures.add(null);
|
||||||
|
@ -153,7 +153,7 @@ public class Structure implements Cloneable {
|
|||||||
return value;
|
return value;
|
||||||
} else if (value instanceof Structure) {
|
} else if (value instanceof Structure) {
|
||||||
value = ((Structure) value).getFlatFieldValue(fieldName);
|
value = ((Structure) value).getFlatFieldValue(fieldName);
|
||||||
if (value != null) {//we can compare references here, since we use one static object as a NULL field value
|
if (value != null) {// we can compare references here, since we use one static object as a NULL field value
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -248,16 +248,16 @@ public class Structure implements Cloneable {
|
|||||||
return oldMemoryAddress;
|
return oldMemoryAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method returns the name of the structure. If the structure has an ID field then the name is returned.
|
* This method returns the name of the structure. If the structure has an ID field then the name is returned.
|
||||||
* Otherwise the name does not exists and the method returns null.
|
* Otherwise the name does not exists and the method returns null.
|
||||||
* @return the name of the structure read from the ID field or null
|
* @return the name of the structure read from the ID field or null
|
||||||
*/
|
*/
|
||||||
public String getName() {
|
public String getName() {
|
||||||
Object fieldValue = this.getFieldValue("ID");
|
Object fieldValue = this.getFieldValue("ID");
|
||||||
if(fieldValue instanceof Structure) {
|
if (fieldValue instanceof Structure) {
|
||||||
Structure id = (Structure)fieldValue;
|
Structure id = (Structure) fieldValue;
|
||||||
return id == null ? null : id.getFieldValue("name").toString().substring(2);//blender adds 2-charactes as a name prefix
|
return id == null ? null : id.getFieldValue("name").toString().substring(2);// blender adds 2-charactes as a name prefix
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
@ -280,7 +280,7 @@ public class Structure implements Cloneable {
|
|||||||
* This enum enumerates all known data types that can be found in the blend file.
|
* This enum enumerates all known data types that can be found in the blend file.
|
||||||
* @author Marcin Roguski
|
* @author Marcin Roguski
|
||||||
*/
|
*/
|
||||||
/*package*/
|
/* package */
|
||||||
static enum DataType {
|
static enum DataType {
|
||||||
|
|
||||||
CHARACTER, SHORT, INTEGER, LONG, FLOAT, DOUBLE, VOID, STRUCTURE, POINTER;
|
CHARACTER, SHORT, INTEGER, LONG, FLOAT, DOUBLE, VOID, STRUCTURE, POINTER;
|
||||||
|
@ -75,32 +75,32 @@ public class LightHelper extends AbstractBlenderHelper {
|
|||||||
Light light = null;
|
Light light = null;
|
||||||
int type = ((Number) structure.getFieldValue("type")).intValue();
|
int type = ((Number) structure.getFieldValue("type")).intValue();
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 0://Lamp
|
case 0:// Lamp
|
||||||
light = new PointLight();
|
light = new PointLight();
|
||||||
float distance = ((Number) structure.getFieldValue("dist")).floatValue();
|
float distance = ((Number) structure.getFieldValue("dist")).floatValue();
|
||||||
((PointLight) light).setRadius(distance);
|
((PointLight) light).setRadius(distance);
|
||||||
break;
|
break;
|
||||||
case 1://Sun
|
case 1:// Sun
|
||||||
LOGGER.log(Level.WARNING, "'Sun' lamp is not supported in jMonkeyEngine.");
|
LOGGER.log(Level.WARNING, "'Sun' lamp is not supported in jMonkeyEngine.");
|
||||||
break;
|
break;
|
||||||
case 2://Spot
|
case 2:// Spot
|
||||||
light = new SpotLight();
|
light = new SpotLight();
|
||||||
//range
|
// range
|
||||||
((SpotLight)light).setSpotRange(((Number) structure.getFieldValue("dist")).floatValue());
|
((SpotLight) light).setSpotRange(((Number) structure.getFieldValue("dist")).floatValue());
|
||||||
//outer angle
|
// outer angle
|
||||||
float outerAngle = ((Number) structure.getFieldValue("spotsize")).floatValue()*FastMath.DEG_TO_RAD * 0.5f;
|
float outerAngle = ((Number) structure.getFieldValue("spotsize")).floatValue() * FastMath.DEG_TO_RAD * 0.5f;
|
||||||
((SpotLight)light).setSpotOuterAngle(outerAngle);
|
((SpotLight) light).setSpotOuterAngle(outerAngle);
|
||||||
|
|
||||||
//inner angle
|
// inner angle
|
||||||
float spotblend = ((Number) structure.getFieldValue("spotblend")).floatValue();
|
float spotblend = ((Number) structure.getFieldValue("spotblend")).floatValue();
|
||||||
spotblend = FastMath.clamp(spotblend, 0, 1);
|
spotblend = FastMath.clamp(spotblend, 0, 1);
|
||||||
float innerAngle = outerAngle * (1 - spotblend);
|
float innerAngle = outerAngle * (1 - spotblend);
|
||||||
((SpotLight)light).setSpotInnerAngle(innerAngle);
|
((SpotLight) light).setSpotInnerAngle(innerAngle);
|
||||||
break;
|
break;
|
||||||
case 3://Hemi
|
case 3:// Hemi
|
||||||
LOGGER.log(Level.WARNING, "'Hemi' lamp is not supported in jMonkeyEngine.");
|
LOGGER.log(Level.WARNING, "'Hemi' lamp is not supported in jMonkeyEngine.");
|
||||||
break;
|
break;
|
||||||
case 4://Area
|
case 4:// Area
|
||||||
light = new DirectionalLight();
|
light = new DirectionalLight();
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -4,7 +4,7 @@ package com.jme3.scene.plugins.blender.materials;
|
|||||||
* An interface used in calculating alpha mask during particles' texture calculations.
|
* An interface used in calculating alpha mask during particles' texture calculations.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ interface IAlphaMask {
|
/* package */interface IAlphaMask {
|
||||||
/**
|
/**
|
||||||
* This method sets the size of the texture's image.
|
* This method sets the size of the texture's image.
|
||||||
* @param width
|
* @param width
|
||||||
|
@ -38,7 +38,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
public final class MaterialContext {
|
public final class MaterialContext {
|
||||||
private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MaterialContext.class.getName());
|
||||||
|
|
||||||
//texture mapping types
|
// texture mapping types
|
||||||
public static final int MTEX_COL = 0x01;
|
public static final int MTEX_COL = 0x01;
|
||||||
public static final int MTEX_NOR = 0x02;
|
public static final int MTEX_NOR = 0x02;
|
||||||
public static final int MTEX_SPEC = 0x04;
|
public static final int MTEX_SPEC = 0x04;
|
||||||
@ -72,7 +72,7 @@ public final class MaterialContext {
|
|||||||
int diff_shader = ((Number) structure.getFieldValue("diff_shader")).intValue();
|
int diff_shader = ((Number) structure.getFieldValue("diff_shader")).intValue();
|
||||||
diffuseShader = DiffuseShader.values()[diff_shader];
|
diffuseShader = DiffuseShader.values()[diff_shader];
|
||||||
|
|
||||||
if(this.shadeless) {
|
if (this.shadeless) {
|
||||||
float r = ((Number) structure.getFieldValue("r")).floatValue();
|
float r = ((Number) structure.getFieldValue("r")).floatValue();
|
||||||
float g = ((Number) structure.getFieldValue("g")).floatValue();
|
float g = ((Number) structure.getFieldValue("g")).floatValue();
|
||||||
float b = ((Number) structure.getFieldValue("b")).floatValue();
|
float b = ((Number) structure.getFieldValue("b")).floatValue();
|
||||||
@ -119,49 +119,46 @@ public final class MaterialContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//loading the textures and merging them
|
// loading the textures and merging them
|
||||||
Map<Number, List<TextureData>> textureDataMap = this.sortAndFilterTextures(texturesList);
|
Map<Number, List<TextureData>> textureDataMap = this.sortAndFilterTextures(texturesList);
|
||||||
loadedTextures = new HashMap<Number, CombinedTexture>();
|
loadedTextures = new HashMap<Number, CombinedTexture>();
|
||||||
float[] diffuseColorArray = new float[] {diffuseColor.r, diffuseColor.g, diffuseColor.b, diffuseColor.a};
|
float[] diffuseColorArray = new float[] { diffuseColor.r, diffuseColor.g, diffuseColor.b, diffuseColor.a };
|
||||||
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
||||||
for(Entry<Number, List<TextureData>> entry : textureDataMap.entrySet()) {
|
for (Entry<Number, List<TextureData>> entry : textureDataMap.entrySet()) {
|
||||||
if(entry.getValue().size()>0) {
|
if (entry.getValue().size() > 0) {
|
||||||
CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue());
|
CombinedTexture combinedTexture = new CombinedTexture(entry.getKey().intValue());
|
||||||
for(TextureData textureData : entry.getValue()) {
|
for (TextureData textureData : entry.getValue()) {
|
||||||
int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
|
int texflag = ((Number) textureData.mtex.getFieldValue("texflag")).intValue();
|
||||||
boolean negateTexture = (texflag & 0x04) != 0;
|
boolean negateTexture = (texflag & 0x04) != 0;
|
||||||
Texture texture = textureHelper.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
|
Texture texture = textureHelper.getTexture(textureData.textureStructure, textureData.mtex, blenderContext);
|
||||||
if(texture != null) {
|
if (texture != null) {
|
||||||
int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
|
int blendType = ((Number) textureData.mtex.getFieldValue("blendtype")).intValue();
|
||||||
float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(),
|
float[] color = new float[] { ((Number) textureData.mtex.getFieldValue("r")).floatValue(), ((Number) textureData.mtex.getFieldValue("g")).floatValue(), ((Number) textureData.mtex.getFieldValue("b")).floatValue() };
|
||||||
((Number) textureData.mtex.getFieldValue("g")).floatValue(),
|
|
||||||
((Number) textureData.mtex.getFieldValue("b")).floatValue() };
|
|
||||||
float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
|
float colfac = ((Number) textureData.mtex.getFieldValue("colfac")).floatValue();
|
||||||
TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(),
|
TextureBlender textureBlender = TextureBlenderFactory.createTextureBlender(texture.getImage().getFormat(), texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
|
||||||
texflag, negateTexture, blendType, diffuseColorArray, color, colfac);
|
|
||||||
combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, blenderContext);
|
combinedTexture.add(texture, textureBlender, textureData.uvCoordinatesType, textureData.projectionType, textureData.textureStructure, blenderContext);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(combinedTexture.getTexturesCount() > 0) {
|
if (combinedTexture.getTexturesCount() > 0) {
|
||||||
loadedTextures.put(entry.getKey(), combinedTexture);
|
loadedTextures.put(entry.getKey(), combinedTexture);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//veryfying if the transparency is present
|
// veryfying if the transparency is present
|
||||||
//(in blender transparent mask is 0x10000 but its better to verify it because blender can indicate transparency when
|
// (in blender transparent mask is 0x10000 but its better to verify it because blender can indicate transparency when
|
||||||
//it is not required
|
// it is not required
|
||||||
boolean transparent = false;
|
boolean transparent = false;
|
||||||
if(diffuseColor != null) {
|
if (diffuseColor != null) {
|
||||||
transparent = diffuseColor.a < 1.0f;
|
transparent = diffuseColor.a < 1.0f;
|
||||||
if(textureDataMap.size() > 0) {//texutre covers the material color
|
if (textureDataMap.size() > 0) {// texutre covers the material color
|
||||||
diffuseColor.set(1, 1, 1, 1);
|
diffuseColor.set(1, 1, 1, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(specularColor != null) {
|
if (specularColor != null) {
|
||||||
transparent = transparent || specularColor.a < 1.0f;
|
transparent = transparent || specularColor.a < 1.0f;
|
||||||
}
|
}
|
||||||
if(ambientColor != null) {
|
if (ambientColor != null) {
|
||||||
transparent = transparent || ambientColor.a < 1.0f;
|
transparent = transparent || ambientColor.a < 1.0f;
|
||||||
}
|
}
|
||||||
this.transparent = transparent;
|
this.transparent = transparent;
|
||||||
@ -195,14 +192,14 @@ public final class MaterialContext {
|
|||||||
material.setFloat("Shininess", shininess);
|
material.setFloat("Shininess", shininess);
|
||||||
}
|
}
|
||||||
|
|
||||||
//applying textures
|
// applying textures
|
||||||
if(loadedTextures != null && loadedTextures.size() > 0) {
|
if (loadedTextures != null && loadedTextures.size() > 0) {
|
||||||
Entry<Number, CombinedTexture> basicUVSOwner = null;
|
Entry<Number, CombinedTexture> basicUVSOwner = null;
|
||||||
for(Entry<Number, CombinedTexture> entry : loadedTextures.entrySet()) {
|
for (Entry<Number, CombinedTexture> entry : loadedTextures.entrySet()) {
|
||||||
CombinedTexture combinedTexture = entry.getValue();
|
CombinedTexture combinedTexture = entry.getValue();
|
||||||
combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext);
|
combinedTexture.flatten(geometry, geometriesOMA, userDefinedUVCoordinates, blenderContext);
|
||||||
|
|
||||||
if(basicUVSOwner == null) {
|
if (basicUVSOwner == null) {
|
||||||
basicUVSOwner = entry;
|
basicUVSOwner = entry;
|
||||||
} else {
|
} else {
|
||||||
combinedTexture.castToUVS(basicUVSOwner.getValue(), blenderContext);
|
combinedTexture.castToUVS(basicUVSOwner.getValue(), blenderContext);
|
||||||
@ -210,26 +207,25 @@ public final class MaterialContext {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(basicUVSOwner != null) {
|
if (basicUVSOwner != null) {
|
||||||
this.setTexture(material, basicUVSOwner.getKey().intValue(), basicUVSOwner.getValue().getResultTexture());
|
this.setTexture(material, basicUVSOwner.getKey().intValue(), basicUVSOwner.getValue().getResultTexture());
|
||||||
List<Vector2f> basicUVS = basicUVSOwner.getValue().getResultUVS();
|
List<Vector2f> basicUVS = basicUVSOwner.getValue().getResultUVS();
|
||||||
VertexBuffer uvCoordsBuffer = new VertexBuffer(VertexBuffer.Type.TexCoord);
|
VertexBuffer uvCoordsBuffer = new VertexBuffer(VertexBuffer.Type.TexCoord);
|
||||||
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(basicUVS.toArray(new Vector2f[basicUVS.size()])));
|
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(basicUVS.toArray(new Vector2f[basicUVS.size()])));
|
||||||
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
||||||
}
|
}
|
||||||
} else if(userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
} else if (userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
||||||
VertexBuffer uvCoordsBuffer = new VertexBuffer(VertexBuffer.Type.TexCoord);
|
VertexBuffer uvCoordsBuffer = new VertexBuffer(VertexBuffer.Type.TexCoord);
|
||||||
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float,
|
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(userDefinedUVCoordinates.toArray(new Vector2f[userDefinedUVCoordinates.size()])));
|
||||||
BufferUtils.createFloatBuffer(userDefinedUVCoordinates.toArray(new Vector2f[userDefinedUVCoordinates.size()])));
|
|
||||||
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
//applying additional data
|
// applying additional data
|
||||||
material.setName(name);
|
material.setName(name);
|
||||||
if (vertexColor) {
|
if (vertexColor) {
|
||||||
material.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true);
|
material.setBoolean(shadeless ? "VertexColor" : "UseVertexColor", true);
|
||||||
}
|
}
|
||||||
if(this.faceCullMode != null) {
|
if (this.faceCullMode != null) {
|
||||||
material.getAdditionalRenderState().setFaceCullMode(faceCullMode);
|
material.getAdditionalRenderState().setFaceCullMode(faceCullMode);
|
||||||
} else {
|
} else {
|
||||||
material.getAdditionalRenderState().setFaceCullMode(blenderContext.getBlenderKey().getFaceCullMode());
|
material.getAdditionalRenderState().setFaceCullMode(blenderContext.getBlenderKey().getFaceCullMode());
|
||||||
@ -268,7 +264,7 @@ public final class MaterialContext {
|
|||||||
material.setTexture(MaterialHelper.TEXTURE_TYPE_GLOW, texture);
|
material.setTexture(MaterialHelper.TEXTURE_TYPE_GLOW, texture);
|
||||||
break;
|
break;
|
||||||
case MTEX_ALPHA:
|
case MTEX_ALPHA:
|
||||||
if(!shadeless) {
|
if (!shadeless) {
|
||||||
material.setTexture(MaterialHelper.TEXTURE_TYPE_ALPHA, texture);
|
material.setTexture(MaterialHelper.TEXTURE_TYPE_ALPHA, texture);
|
||||||
} else {
|
} else {
|
||||||
LOGGER.warning("JME does not support alpha map on unshaded material. Material name is " + name);
|
LOGGER.warning("JME does not support alpha map on unshaded material. Material name is " + name);
|
||||||
@ -283,9 +279,9 @@ public final class MaterialContext {
|
|||||||
* @return <b>true</b> if the material has at least one generated texture and <b>false</b> otherwise
|
* @return <b>true</b> if the material has at least one generated texture and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
public boolean hasGeneratedTextures() {
|
public boolean hasGeneratedTextures() {
|
||||||
if(loadedTextures != null) {
|
if (loadedTextures != null) {
|
||||||
for(Entry<Number, CombinedTexture> entry : loadedTextures.entrySet()) {
|
for (Entry<Number, CombinedTexture> entry : loadedTextures.entrySet()) {
|
||||||
if(entry.getValue().hasGeneratedTextures()) {
|
if (entry.getValue().hasGeneratedTextures()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -308,7 +304,7 @@ public final class MaterialContext {
|
|||||||
for (TextureData data : textures) {
|
for (TextureData data : textures) {
|
||||||
Number mapto = (Number) data.mtex.getFieldValue("mapto");
|
Number mapto = (Number) data.mtex.getFieldValue("mapto");
|
||||||
for (int i = 0; i < mappings.length; ++i) {
|
for (int i = 0; i < mappings.length; ++i) {
|
||||||
if((mappings[i] & mapto.intValue()) != 0) {
|
if ((mappings[i] & mapto.intValue()) != 0) {
|
||||||
List<TextureData> datas = result.get(mappings[i]);
|
List<TextureData> datas = result.get(mappings[i]);
|
||||||
if (datas == null) {
|
if (datas == null) {
|
||||||
datas = new ArrayList<TextureData>();
|
datas = new ArrayList<TextureData>();
|
||||||
@ -323,7 +319,8 @@ public final class MaterialContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method sets the face cull mode.
|
* This method sets the face cull mode.
|
||||||
* @param faceCullMode the face cull mode
|
* @param faceCullMode
|
||||||
|
* the face cull mode
|
||||||
*/
|
*/
|
||||||
public void setFaceCullMode(FaceCullMode faceCullMode) {
|
public void setFaceCullMode(FaceCullMode faceCullMode) {
|
||||||
this.faceCullMode = faceCullMode;
|
this.faceCullMode = faceCullMode;
|
||||||
@ -339,8 +336,10 @@ public final class MaterialContext {
|
|||||||
/**
|
/**
|
||||||
* This method returns the diffuse color.
|
* This method returns the diffuse color.
|
||||||
*
|
*
|
||||||
* @param materialStructure the material structure
|
* @param materialStructure
|
||||||
* @param diffuseShader the diffuse shader
|
* the material structure
|
||||||
|
* @param diffuseShader
|
||||||
|
* the diffuse shader
|
||||||
* @return the diffuse color
|
* @return the diffuse color
|
||||||
*/
|
*/
|
||||||
private ColorRGBA readDiffuseColor(Structure materialStructure, DiffuseShader diffuseShader) {
|
private ColorRGBA readDiffuseColor(Structure materialStructure, DiffuseShader diffuseShader) {
|
||||||
|
@ -100,7 +100,8 @@ public class MaterialHelper extends AbstractBlenderHelper {
|
|||||||
super(blenderVersion, false);
|
super(blenderVersion, false);
|
||||||
// setting alpha masks
|
// setting alpha masks
|
||||||
alphaMasks.put(ALPHA_MASK_NONE, new IAlphaMask() {
|
alphaMasks.put(ALPHA_MASK_NONE, new IAlphaMask() {
|
||||||
public void setImageSize(int width, int height) {}
|
public void setImageSize(int width, int height) {
|
||||||
|
}
|
||||||
|
|
||||||
public byte getAlpha(float x, float y) {
|
public byte getAlpha(float x, float y) {
|
||||||
return (byte) 255;
|
return (byte) 255;
|
||||||
|
@ -12,7 +12,7 @@ import com.jme3.math.Vector2f;
|
|||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
/*package*/ class MeshBuilder {
|
/*package*/class MeshBuilder {
|
||||||
private static final Logger LOGGER = Logger.getLogger(MeshBuilder.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MeshBuilder.class.getName());
|
||||||
|
|
||||||
/** An array of reference vertices. */
|
/** An array of reference vertices. */
|
||||||
@ -22,8 +22,10 @@ import com.jme3.util.BufferUtils;
|
|||||||
/** A variable that indicates if the model uses generated textures. */
|
/** A variable that indicates if the model uses generated textures. */
|
||||||
private boolean usesGeneratedTextures;
|
private boolean usesGeneratedTextures;
|
||||||
|
|
||||||
/** This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
|
/**
|
||||||
positions (it simply tells which vertex is referenced where in the result list). */
|
* This map's key is the vertex index from 'vertices 'table and the value are indices from 'vertexList'
|
||||||
|
* positions (it simply tells which vertex is referenced where in the result list).
|
||||||
|
*/
|
||||||
private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
|
private Map<Integer, Map<Integer, List<Integer>>> globalVertexReferenceMap;
|
||||||
|
|
||||||
/** A map between vertex index and its UV coordinates. */
|
/** A map between vertex index and its UV coordinates. */
|
||||||
@ -37,14 +39,16 @@ import com.jme3.util.BufferUtils;
|
|||||||
/** The following map sorts indexes by material number (because in jme Mesh can have only one material). */
|
/** The following map sorts indexes by material number (because in jme Mesh can have only one material). */
|
||||||
private Map<Integer, List<Integer>> indexMap = new HashMap<Integer, List<Integer>>();
|
private Map<Integer, List<Integer>> indexMap = new HashMap<Integer, List<Integer>>();
|
||||||
/** A map between material number and UV coordinates of mesh that has this material applied. */
|
/** A map between material number and UV coordinates of mesh that has this material applied. */
|
||||||
private Map<Integer, List<Vector2f>> uvCoordinates = new HashMap<Integer, List<Vector2f>>();//<material_number; list of uv coordinates for mesh's vertices>
|
private Map<Integer, List<Vector2f>> uvCoordinates = new HashMap<Integer, List<Vector2f>>(); // <material_number; list of uv coordinates for mesh's vertices>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor. Stores the given array (not copying it).
|
* Constructor. Stores the given array (not copying it).
|
||||||
* The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
|
* The second argument describes if the model uses generated textures. If yes then no vertex amount optimisation is applied.
|
||||||
* The amount of vertices is always faceCount * 3.
|
* The amount of vertices is always faceCount * 3.
|
||||||
* @param verticesAndNormals the reference vertices and normals array
|
* @param verticesAndNormals
|
||||||
* @param usesGeneratedTextures a variable that indicates if the model uses generated textures or not
|
* the reference vertices and normals array
|
||||||
|
* @param usesGeneratedTextures
|
||||||
|
* a variable that indicates if the model uses generated textures or not
|
||||||
*/
|
*/
|
||||||
public MeshBuilder(Vector3f[][] verticesAndNormals, List<byte[]> verticesColors, boolean usesGeneratedTextures) {
|
public MeshBuilder(Vector3f[][] verticesAndNormals, List<byte[]> verticesColors, boolean usesGeneratedTextures) {
|
||||||
this.verticesAndNormals = verticesAndNormals;
|
this.verticesAndNormals = verticesAndNormals;
|
||||||
@ -55,41 +59,55 @@ import com.jme3.util.BufferUtils;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method adds a point to the mesh.
|
* This method adds a point to the mesh.
|
||||||
* @param coordinates the coordinates of the point
|
* @param coordinates
|
||||||
* @param normal the point's normal vector
|
* the coordinates of the point
|
||||||
* @param materialNumber the material number for this point
|
* @param normal
|
||||||
|
* the point's normal vector
|
||||||
|
* @param materialNumber
|
||||||
|
* the material number for this point
|
||||||
*/
|
*/
|
||||||
public void appendPoint(Vector3f coordinates, Vector3f normal, int materialNumber) {
|
public void appendPoint(Vector3f coordinates, Vector3f normal, int materialNumber) {
|
||||||
LOGGER.warning("Appending single point not yet supported!");//TODO
|
LOGGER.warning("Appending single point not yet supported!");// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method adds a line to the mesh.
|
* This method adds a line to the mesh.
|
||||||
* @param v1 index of the 1'st vertex from the reference vertex table
|
* @param v1
|
||||||
* @param v2 index of the 2'nd vertex from the reference vertex table
|
* index of the 1'st vertex from the reference vertex table
|
||||||
* @param smooth indicates if this face should have smooth shading or flat shading
|
* @param v2
|
||||||
|
* index of the 2'nd vertex from the reference vertex table
|
||||||
|
* @param smooth
|
||||||
|
* indicates if this face should have smooth shading or flat shading
|
||||||
*/
|
*/
|
||||||
public void appendEdge(int v1, int v2, boolean smooth) {
|
public void appendEdge(int v1, int v2, boolean smooth) {
|
||||||
LOGGER.warning("Appending single line not yet supported!");//TODO
|
LOGGER.warning("Appending single line not yet supported!");// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method adds a face to the mesh.
|
* This method adds a face to the mesh.
|
||||||
* @param v1 index of the 1'st vertex from the reference vertex table
|
* @param v1
|
||||||
* @param v2 index of the 2'nd vertex from the reference vertex table
|
* index of the 1'st vertex from the reference vertex table
|
||||||
* @param v3 index of the 3'rd vertex from the reference vertex table
|
* @param v2
|
||||||
* @param smooth indicates if this face should have smooth shading or flat shading
|
* index of the 2'nd vertex from the reference vertex table
|
||||||
* @param materialNumber the material number for this face
|
* @param v3
|
||||||
* @param uvs a 3-element array of vertices UV coordinates
|
* index of the 3'rd vertex from the reference vertex table
|
||||||
* @param quad indicates if the appended face is a part of a quad face (used for creating vertex colors buffer)
|
* @param smooth
|
||||||
* @param faceIndex the face index (used for creating vertex colors buffer)
|
* indicates if this face should have smooth shading or flat shading
|
||||||
|
* @param materialNumber
|
||||||
|
* the material number for this face
|
||||||
|
* @param uvs
|
||||||
|
* a 3-element array of vertices UV coordinates
|
||||||
|
* @param quad
|
||||||
|
* indicates if the appended face is a part of a quad face (used for creating vertex colors buffer)
|
||||||
|
* @param faceIndex
|
||||||
|
* the face index (used for creating vertex colors buffer)
|
||||||
*/
|
*/
|
||||||
public void appendFace(int v1, int v2, int v3, boolean smooth, int materialNumber, Vector2f[] uvs, boolean quad, int faceIndex) {
|
public void appendFace(int v1, int v2, int v3, boolean smooth, int materialNumber, Vector2f[] uvs, boolean quad, int faceIndex) {
|
||||||
if(uvs != null && uvs.length != 3) {
|
if (uvs != null && uvs.length != 3) {
|
||||||
throw new IllegalArgumentException("UV coordinates must be a 3-element array!");
|
throw new IllegalArgumentException("UV coordinates must be a 3-element array!");
|
||||||
}
|
}
|
||||||
|
|
||||||
//getting the required lists
|
// getting the required lists
|
||||||
List<Integer> indexList = indexMap.get(materialNumber);
|
List<Integer> indexList = indexMap.get(materialNumber);
|
||||||
if (indexList == null) {
|
if (indexList == null) {
|
||||||
indexList = new ArrayList<Integer>();
|
indexList = new ArrayList<Integer>();
|
||||||
@ -102,7 +120,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
}
|
}
|
||||||
List<byte[]> vertexColorsList = vertexColorsMap != null ? vertexColorsMap.get(materialNumber) : null;
|
List<byte[]> vertexColorsList = vertexColorsMap != null ? vertexColorsMap.get(materialNumber) : null;
|
||||||
int[] vertexColorIndex = new int[] { 0, 1, 2 };
|
int[] vertexColorIndex = new int[] { 0, 1, 2 };
|
||||||
if(vertexColorsList == null && vertexColorsMap != null) {
|
if (vertexColorsList == null && vertexColorsMap != null) {
|
||||||
vertexColorsList = new ArrayList<byte[]>();
|
vertexColorsList = new ArrayList<byte[]>();
|
||||||
vertexColorsMap.put(materialNumber, vertexColorsList);
|
vertexColorsMap.put(materialNumber, vertexColorsList);
|
||||||
}
|
}
|
||||||
@ -112,55 +130,55 @@ import com.jme3.util.BufferUtils;
|
|||||||
normalMap.put(materialNumber, normalList);
|
normalMap.put(materialNumber, normalList);
|
||||||
}
|
}
|
||||||
Map<Integer, List<Integer>> vertexReferenceMap = globalVertexReferenceMap.get(materialNumber);
|
Map<Integer, List<Integer>> vertexReferenceMap = globalVertexReferenceMap.get(materialNumber);
|
||||||
if(vertexReferenceMap == null) {
|
if (vertexReferenceMap == null) {
|
||||||
vertexReferenceMap = new HashMap<Integer, List<Integer>>();
|
vertexReferenceMap = new HashMap<Integer, List<Integer>>();
|
||||||
globalVertexReferenceMap.put(materialNumber, vertexReferenceMap);
|
globalVertexReferenceMap.put(materialNumber, vertexReferenceMap);
|
||||||
}
|
}
|
||||||
List<Vector2f> uvCoordinatesList = null;
|
List<Vector2f> uvCoordinatesList = null;
|
||||||
if(uvs != null) {
|
if (uvs != null) {
|
||||||
uvCoordinatesList = uvCoordinates.get(Integer.valueOf(materialNumber));
|
uvCoordinatesList = uvCoordinates.get(Integer.valueOf(materialNumber));
|
||||||
if(uvCoordinatesList == null) {
|
if (uvCoordinatesList == null) {
|
||||||
uvCoordinatesList = new ArrayList<Vector2f>();
|
uvCoordinatesList = new ArrayList<Vector2f>();
|
||||||
uvCoordinates.put(Integer.valueOf(materialNumber), uvCoordinatesList);
|
uvCoordinates.put(Integer.valueOf(materialNumber), uvCoordinatesList);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
faceIndex *= 4;
|
faceIndex *= 4;
|
||||||
if(quad) {
|
if (quad) {
|
||||||
vertexColorIndex[1] = 2;
|
vertexColorIndex[1] = 2;
|
||||||
vertexColorIndex[2] = 3;
|
vertexColorIndex[2] = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
//creating faces
|
// creating faces
|
||||||
Integer[] index = new Integer[] {v1, v2, v3};
|
Integer[] index = new Integer[] { v1, v2, v3 };
|
||||||
if(smooth && !usesGeneratedTextures) {
|
if (smooth && !usesGeneratedTextures) {
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
if(!vertexReferenceMap.containsKey(index[i])) {
|
if (!vertexReferenceMap.containsKey(index[i])) {
|
||||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||||
if(verticesColors != null) {
|
if (verticesColors != null) {
|
||||||
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
||||||
}
|
}
|
||||||
normalList.add(verticesAndNormals[index[i]][1]);
|
normalList.add(verticesAndNormals[index[i]][1]);
|
||||||
if(uvCoordinatesList != null) {
|
if (uvCoordinatesList != null) {
|
||||||
uvsMap.put(vertexList.size(), uvs[i]);
|
uvsMap.put(vertexList.size(), uvs[i]);
|
||||||
uvCoordinatesList.add(uvs[i]);
|
uvCoordinatesList.add(uvs[i]);
|
||||||
}
|
}
|
||||||
index[i] = vertexList.size() - 1;
|
index[i] = vertexList.size() - 1;
|
||||||
} else if(uvCoordinatesList != null) {
|
} else if (uvCoordinatesList != null) {
|
||||||
boolean vertexAlreadyUsed = false;
|
boolean vertexAlreadyUsed = false;
|
||||||
for(Integer vertexIndex : vertexReferenceMap.get(index[i])) {
|
for (Integer vertexIndex : vertexReferenceMap.get(index[i])) {
|
||||||
if(uvs[i].equals(uvsMap.get(vertexIndex))) {
|
if (uvs[i].equals(uvsMap.get(vertexIndex))) {
|
||||||
vertexAlreadyUsed = true;
|
vertexAlreadyUsed = true;
|
||||||
index[i] = vertexIndex;
|
index[i] = vertexIndex;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(!vertexAlreadyUsed) {
|
if (!vertexAlreadyUsed) {
|
||||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||||
uvsMap.put(vertexList.size(), uvs[i]);
|
uvsMap.put(vertexList.size(), uvs[i]);
|
||||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||||
if(verticesColors != null) {
|
if (verticesColors != null) {
|
||||||
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
||||||
}
|
}
|
||||||
normalList.add(verticesAndNormals[index[i]][1]);
|
normalList.add(verticesAndNormals[index[i]][1]);
|
||||||
@ -177,12 +195,12 @@ import com.jme3.util.BufferUtils;
|
|||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
indexList.add(vertexList.size());
|
indexList.add(vertexList.size());
|
||||||
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
this.appendVertexReference(index[i], vertexList.size(), vertexReferenceMap);
|
||||||
if(uvCoordinatesList != null) {
|
if (uvCoordinatesList != null) {
|
||||||
uvCoordinatesList.add(uvs[i]);
|
uvCoordinatesList.add(uvs[i]);
|
||||||
uvsMap.put(vertexList.size(), uvs[i]);
|
uvsMap.put(vertexList.size(), uvs[i]);
|
||||||
}
|
}
|
||||||
vertexList.add(verticesAndNormals[index[i]][0]);
|
vertexList.add(verticesAndNormals[index[i]][0]);
|
||||||
if(verticesColors != null) {
|
if (verticesColors != null) {
|
||||||
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
vertexColorsList.add(verticesColors.get(faceIndex + vertexColorIndex[i]));
|
||||||
}
|
}
|
||||||
normalList.add(smooth ? verticesAndNormals[index[i]][1] : n);
|
normalList.add(smooth ? verticesAndNormals[index[i]][1] : n);
|
||||||
@ -238,7 +256,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
if (v != null) {
|
if (v != null) {
|
||||||
result.put(v[0]).put(v[1]).put(v[2]).put(v[3]);
|
result.put(v[0]).put(v[1]).put(v[2]).put(v[3]);
|
||||||
} else {
|
} else {
|
||||||
result.put((byte)0).put((byte)0).put((byte)0).put((byte)0);
|
result.put((byte) 0).put((byte) 0).put((byte) 0).put((byte) 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
result.flip();
|
result.flip();
|
||||||
|
@ -27,15 +27,18 @@ public class MeshContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Adds a geometry for the specified material index.
|
* Adds a geometry for the specified material index.
|
||||||
* @param materialIndex the material index
|
* @param materialIndex
|
||||||
* @param geometry the geometry
|
* the material index
|
||||||
|
* @param geometry
|
||||||
|
* the geometry
|
||||||
*/
|
*/
|
||||||
public void putGeometry(Integer materialIndex, Geometry geometry) {
|
public void putGeometry(Integer materialIndex, Geometry geometry) {
|
||||||
geometries.put(materialIndex, geometry);
|
geometries.put(materialIndex, geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param materialIndex the material index
|
* @param materialIndex
|
||||||
|
* the material index
|
||||||
* @return vertices amount that is used by mesh with the specified material
|
* @return vertices amount that is used by mesh with the specified material
|
||||||
*/
|
*/
|
||||||
public int getVertexCount(int materialIndex) {
|
public int getVertexCount(int materialIndex) {
|
||||||
@ -44,13 +47,15 @@ public class MeshContext {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns material index for the geometry.
|
* Returns material index for the geometry.
|
||||||
* @param geometry the geometry
|
* @param geometry
|
||||||
|
* the geometry
|
||||||
* @return material index
|
* @return material index
|
||||||
* @throws IllegalStateException this exception is thrown when no material is found for the specified geometry
|
* @throws IllegalStateException
|
||||||
|
* this exception is thrown when no material is found for the specified geometry
|
||||||
*/
|
*/
|
||||||
public int getMaterialIndex(Geometry geometry) {
|
public int getMaterialIndex(Geometry geometry) {
|
||||||
for(Entry<Integer, Geometry> entry : geometries.entrySet()) {
|
for (Entry<Integer, Geometry> entry : geometries.entrySet()) {
|
||||||
if(entry.getValue().equals(geometry)) {
|
if (entry.getValue().equals(geometry)) {
|
||||||
return entry.getKey();
|
return entry.getKey();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -107,8 +112,7 @@ public class MeshContext {
|
|||||||
* @param bindNormalBuffer
|
* @param bindNormalBuffer
|
||||||
* the bind buffer for vertices
|
* the bind buffer for vertices
|
||||||
*/
|
*/
|
||||||
public void setBindNormalBuffer(int materialIndex,
|
public void setBindNormalBuffer(int materialIndex, VertexBuffer bindNormalBuffer) {
|
||||||
VertexBuffer bindNormalBuffer) {
|
|
||||||
this.bindNormalBuffer.put(materialIndex, bindNormalBuffer);
|
this.bindNormalBuffer.put(materialIndex, bindNormalBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -75,7 +75,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
* a variable that indicates if the Y asxis is the UP axis or not
|
* a variable that indicates if the Y asxis is the UP axis or not
|
||||||
*/
|
*/
|
||||||
public MeshHelper(String blenderVersion, boolean fixUpAxis) {
|
public MeshHelper(String blenderVersion, boolean fixUpAxis) {
|
||||||
super(blenderVersion,fixUpAxis);
|
super(blenderVersion, fixUpAxis);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -114,13 +114,13 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
MeshBuilder meshBuilder = new MeshBuilder(verticesAndNormals, verticesColors, this.areGeneratedTexturesPresent(materials));
|
MeshBuilder meshBuilder = new MeshBuilder(verticesAndNormals, verticesColors, this.areGeneratedTexturesPresent(materials));
|
||||||
|
|
||||||
if(this.isBMeshCompatible(structure)) {
|
if (this.isBMeshCompatible(structure)) {
|
||||||
this.readBMesh(meshBuilder, structure, blenderContext);
|
this.readBMesh(meshBuilder, structure, blenderContext);
|
||||||
} else {
|
} else {
|
||||||
this.readTraditionalFaces(meshBuilder, structure, blenderContext);
|
this.readTraditionalFaces(meshBuilder, structure, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(meshBuilder.isEmpty()) {
|
if (meshBuilder.isEmpty()) {
|
||||||
geometries = new ArrayList<Geometry>(0);
|
geometries = new ArrayList<Geometry>(0);
|
||||||
blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
||||||
blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
||||||
@ -142,19 +142,19 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
// creating the result meshes
|
// creating the result meshes
|
||||||
geometries = new ArrayList<Geometry>(meshBuilder.getMeshesPartAmount());
|
geometries = new ArrayList<Geometry>(meshBuilder.getMeshesPartAmount());
|
||||||
|
|
||||||
//reading custom properties
|
// reading custom properties
|
||||||
Properties properties = this.loadProperties(structure, blenderContext);
|
Properties properties = this.loadProperties(structure, blenderContext);
|
||||||
|
|
||||||
// generating meshes
|
// generating meshes
|
||||||
for (Entry<Integer, List<Integer>> meshEntry : meshBuilder.getMeshesMap().entrySet()) {
|
for (Entry<Integer, List<Integer>> meshEntry : meshBuilder.getMeshesMap().entrySet()) {
|
||||||
int materialIndex = meshEntry.getKey();
|
int materialIndex = meshEntry.getKey();
|
||||||
//key is the material index (or -1 if the material has no texture)
|
// key is the material index (or -1 if the material has no texture)
|
||||||
//value is a list of vertex indices
|
// value is a list of vertex indices
|
||||||
Mesh mesh = new Mesh();
|
Mesh mesh = new Mesh();
|
||||||
|
|
||||||
// creating vertices indices for this mesh
|
// creating vertices indices for this mesh
|
||||||
List<Integer> indexList = meshEntry.getValue();
|
List<Integer> indexList = meshEntry.getValue();
|
||||||
if(meshBuilder.getVerticesAmount(materialIndex) <= Short.MAX_VALUE) {
|
if (meshBuilder.getVerticesAmount(materialIndex) <= Short.MAX_VALUE) {
|
||||||
short[] indices = new short[indexList.size()];
|
short[] indices = new short[indexList.size()];
|
||||||
for (int i = 0; i < indexList.size(); ++i) {
|
for (int i = 0; i < indexList.size(); ++i) {
|
||||||
indices[i] = indexList.get(i).shortValue();
|
indices[i] = indexList.get(i).shortValue();
|
||||||
@ -183,7 +183,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
normalsBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.createFloatBuffer(meshBuilder.getNormals(materialIndex)));
|
normalsBind.setupData(Usage.CpuOnly, 3, Format.Float, BufferUtils.createFloatBuffer(meshBuilder.getNormals(materialIndex)));
|
||||||
|
|
||||||
mesh.setBuffer(verticesBuffer);
|
mesh.setBuffer(verticesBuffer);
|
||||||
meshContext.setBindPoseBuffer(materialIndex, verticesBind);//this is stored in the context and applied when needed (when animation is applied to the mesh)
|
meshContext.setBindPoseBuffer(materialIndex, verticesBind);// this is stored in the context and applied when needed (when animation is applied to the mesh)
|
||||||
|
|
||||||
// setting vertices colors
|
// setting vertices colors
|
||||||
if (verticesColors != null) {
|
if (verticesColors != null) {
|
||||||
@ -193,7 +193,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
// setting faces' normals
|
// setting faces' normals
|
||||||
mesh.setBuffer(normalsBuffer);
|
mesh.setBuffer(normalsBuffer);
|
||||||
meshContext.setBindNormalBuffer(materialIndex, normalsBind);//this is stored in the context and applied when needed (when animation is applied to the mesh)
|
meshContext.setBindNormalBuffer(materialIndex, normalsBind);// this is stored in the context and applied when needed (when animation is applied to the mesh)
|
||||||
|
|
||||||
// creating the result
|
// creating the result
|
||||||
Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
Geometry geometry = new Geometry(name + (geometries.size() + 1), mesh);
|
||||||
@ -204,37 +204,35 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
meshContext.putGeometry(materialIndex, geometry);
|
meshContext.putGeometry(materialIndex, geometry);
|
||||||
}
|
}
|
||||||
|
|
||||||
//store the data in blender context before applying the material
|
// store the data in blender context before applying the material
|
||||||
blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
blenderContext.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
||||||
blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
blenderContext.setMeshContext(structure.getOldMemoryAddress(), meshContext);
|
||||||
|
|
||||||
//apply materials only when all geometries are in place
|
// apply materials only when all geometries are in place
|
||||||
if(materials != null) {
|
if (materials != null) {
|
||||||
for(Geometry geometry : geometries) {
|
for (Geometry geometry : geometries) {
|
||||||
int materialNumber = meshContext.getMaterialIndex(geometry);
|
int materialNumber = meshContext.getMaterialIndex(geometry);
|
||||||
if(materials[materialNumber] != null) {
|
if (materials[materialNumber] != null) {
|
||||||
List<Vector2f> uvCoordinates = meshBuilder.getUVCoordinates(materialNumber);
|
List<Vector2f> uvCoordinates = meshBuilder.getUVCoordinates(materialNumber);
|
||||||
MaterialContext materialContext = materials[materialNumber];
|
MaterialContext materialContext = materials[materialNumber];
|
||||||
materialContext.applyMaterial(geometry, structure.getOldMemoryAddress(), uvCoordinates, blenderContext);
|
materialContext.applyMaterial(geometry, structure.getOldMemoryAddress(), uvCoordinates, blenderContext);
|
||||||
} else {
|
} else {
|
||||||
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
||||||
LOGGER.warning("The importer came accross mesh that points to a null material. Default material is used to prevent loader from crashing, " +
|
LOGGER.warning("The importer came accross mesh that points to a null material. Default material is used to prevent loader from crashing, " + "but the model might look not the way it should. Sometimes blender does not assign materials properly. " + "Enter the edit mode and assign materials once more to your faces.");
|
||||||
"but the model might look not the way it should. Sometimes blender does not assign materials properly. " +
|
|
||||||
"Enter the edit mode and assign materials once more to your faces.");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//add UV coordinates if they are defined even if the material is not applied to the model
|
// add UV coordinates if they are defined even if the material is not applied to the model
|
||||||
VertexBuffer uvCoordsBuffer = null;
|
VertexBuffer uvCoordsBuffer = null;
|
||||||
if(meshBuilder.hasUVCoordinates()) {
|
if (meshBuilder.hasUVCoordinates()) {
|
||||||
List<Vector2f> uvs = meshBuilder.getUVCoordinates(0);
|
List<Vector2f> uvs = meshBuilder.getUVCoordinates(0);
|
||||||
uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
|
uvCoordsBuffer = new VertexBuffer(Type.TexCoord);
|
||||||
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
|
uvCoordsBuffer.setupData(Usage.Static, 2, Format.Float, BufferUtils.createFloatBuffer(uvs.toArray(new Vector2f[uvs.size()])));
|
||||||
}
|
}
|
||||||
|
|
||||||
for(Geometry geometry : geometries) {
|
for (Geometry geometry : geometries) {
|
||||||
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
geometry.setMaterial(blenderContext.getDefaultMaterial());
|
||||||
if(uvCoordsBuffer != null) {
|
if (uvCoordsBuffer != null) {
|
||||||
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
geometry.getMesh().setBuffer(uvCoordsBuffer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -404,9 +402,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
* @return <b>true</b> if the material has at least one generated component and <b>false</b> otherwise
|
* @return <b>true</b> if the material has at least one generated component and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
private boolean areGeneratedTexturesPresent(MaterialContext[] materials) {
|
private boolean areGeneratedTexturesPresent(MaterialContext[] materials) {
|
||||||
if(materials != null) {
|
if (materials != null) {
|
||||||
for(MaterialContext material : materials) {
|
for (MaterialContext material : materials) {
|
||||||
if(material != null && material.hasGeneratedTextures()) {
|
if (material != null && material.hasGeneratedTextures()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -433,11 +431,11 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
verticesColors = new ArrayList<byte[]>();
|
verticesColors = new ArrayList<byte[]>();
|
||||||
mCol = pMCol.fetchData(blenderContext.getInputStream());
|
mCol = pMCol.fetchData(blenderContext.getInputStream());
|
||||||
for (Structure color : mCol) {
|
for (Structure color : mCol) {
|
||||||
byte r = ((Number)color.getFieldValue("r")).byteValue();
|
byte r = ((Number) color.getFieldValue("r")).byteValue();
|
||||||
byte g = ((Number)color.getFieldValue("g")).byteValue();
|
byte g = ((Number) color.getFieldValue("g")).byteValue();
|
||||||
byte b = ((Number)color.getFieldValue("b")).byteValue();
|
byte b = ((Number) color.getFieldValue("b")).byteValue();
|
||||||
byte a = ((Number)color.getFieldValue("a")).byteValue();
|
byte a = ((Number) color.getFieldValue("a")).byteValue();
|
||||||
verticesColors.add(new byte[]{b, g, r, a});
|
verticesColors.add(new byte[] { b, g, r, a });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return verticesColors;
|
return verticesColors;
|
||||||
@ -464,13 +462,13 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
|
|
||||||
Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
|
Pointer pMVert = (Pointer) meshStructure.getFieldValue("mvert");
|
||||||
List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
|
List<Structure> mVerts = pMVert.fetchData(blenderContext.getInputStream());
|
||||||
if(this.fixUpAxis) {
|
if (this.fixUpAxis) {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
|
DynamicArray<Number> coordinates = (DynamicArray<Number>) mVerts.get(i).getFieldValue("co");
|
||||||
result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
|
result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(2).floatValue(), -coordinates.get(1).floatValue());
|
||||||
|
|
||||||
DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
|
DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
|
||||||
result[i][1] = new Vector3f(normals.get(0).shortValue()/32767.0f, normals.get(2).shortValue()/32767.0f, -normals.get(1).shortValue()/32767.0f);
|
result[i][1] = new Vector3f(normals.get(0).shortValue() / 32767.0f, normals.get(2).shortValue() / 32767.0f, -normals.get(1).shortValue() / 32767.0f);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
@ -478,7 +476,7 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
|
result[i][0] = new Vector3f(coordinates.get(0).floatValue(), coordinates.get(1).floatValue(), coordinates.get(2).floatValue());
|
||||||
|
|
||||||
DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
|
DynamicArray<Number> normals = (DynamicArray<Number>) mVerts.get(i).getFieldValue("no");
|
||||||
result[i][1] = new Vector3f(normals.get(0).shortValue()/32767.0f, normals.get(1).shortValue()/32767.0f, normals.get(2).shortValue()/32767.0f);
|
result[i][1] = new Vector3f(normals.get(0).shortValue() / 32767.0f, normals.get(1).shortValue() / 32767.0f, normals.get(2).shortValue() / 32767.0f);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -44,7 +44,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
*/
|
*/
|
||||||
/* package */class ArmatureModifier extends Modifier {
|
/* package */class ArmatureModifier extends Modifier {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ArmatureModifier.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ArmatureModifier.class.getName());
|
||||||
private static final int MAXIMUM_WEIGHTS_PER_VERTEX = 4;//JME limitation
|
private static final int MAXIMUM_WEIGHTS_PER_VERTEX = 4; // JME limitation
|
||||||
|
|
||||||
private Skeleton skeleton;
|
private Skeleton skeleton;
|
||||||
private Structure objectStructure;
|
private Structure objectStructure;
|
||||||
@ -123,7 +123,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
String actionName = actionStructure.getName();
|
String actionName = actionStructure.getName();
|
||||||
|
|
||||||
BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, skeleton, blenderContext);
|
BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, skeleton, blenderContext);
|
||||||
if(tracks != null && tracks.length > 0) {
|
if (tracks != null && tracks.length > 0) {
|
||||||
// determining the animation time
|
// determining the animation time
|
||||||
float maximumTrackLength = 0;
|
float maximumTrackLength = 0;
|
||||||
for (BoneTrack track : tracks) {
|
for (BoneTrack track : tracks) {
|
||||||
@ -139,14 +139,14 @@ import com.jme3.util.BufferUtils;
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//fetching action defined in object
|
// fetching action defined in object
|
||||||
Pointer pAction = (Pointer) objectStructure.getFieldValue("action");
|
Pointer pAction = (Pointer) objectStructure.getFieldValue("action");
|
||||||
if (pAction.isNotNull()) {
|
if (pAction.isNotNull()) {
|
||||||
Structure actionStructure = pAction.fetchData(blenderContext.getInputStream()).get(0);
|
Structure actionStructure = pAction.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
String actionName = actionStructure.getName();
|
String actionName = actionStructure.getName();
|
||||||
|
|
||||||
BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, skeleton, blenderContext);
|
BoneTrack[] tracks = armatureHelper.getTracks(actionStructure, skeleton, blenderContext);
|
||||||
if(tracks != null && tracks.length > 0) {
|
if (tracks != null && tracks.length > 0) {
|
||||||
// determining the animation time
|
// determining the animation time
|
||||||
float maximumTrackLength = 0;
|
float maximumTrackLength = 0;
|
||||||
for (BoneTrack track : tracks) {
|
for (BoneTrack track : tracks) {
|
||||||
@ -203,14 +203,14 @@ import com.jme3.util.BufferUtils;
|
|||||||
mesh.setBuffer(buffers[1]);
|
mesh.setBuffer(buffers[1]);
|
||||||
|
|
||||||
VertexBuffer bindNormalBuffer = (meshContext.getBindNormalBuffer(materialIndex));
|
VertexBuffer bindNormalBuffer = (meshContext.getBindNormalBuffer(materialIndex));
|
||||||
if(bindNormalBuffer != null) {
|
if (bindNormalBuffer != null) {
|
||||||
mesh.setBuffer(bindNormalBuffer);
|
mesh.setBuffer(bindNormalBuffer);
|
||||||
}
|
}
|
||||||
VertexBuffer bindPoseBuffer = (meshContext.getBindPoseBuffer(materialIndex));
|
VertexBuffer bindPoseBuffer = (meshContext.getBindPoseBuffer(materialIndex));
|
||||||
if(bindPoseBuffer != null) {
|
if (bindPoseBuffer != null) {
|
||||||
mesh.setBuffer(bindPoseBuffer);
|
mesh.setBuffer(bindPoseBuffer);
|
||||||
}
|
}
|
||||||
//change the usage type of vertex and normal buffers from Static to Stream
|
// change the usage type of vertex and normal buffers from Static to Stream
|
||||||
mesh.getBuffer(Type.Position).setUsage(Usage.Stream);
|
mesh.getBuffer(Type.Position).setUsage(Usage.Stream);
|
||||||
mesh.getBuffer(Type.Normal).setUsage(Usage.Stream);
|
mesh.getBuffer(Type.Normal).setUsage(Usage.Stream);
|
||||||
}
|
}
|
||||||
@ -251,16 +251,14 @@ import com.jme3.util.BufferUtils;
|
|||||||
* this exception is thrown when the blend file structure is
|
* this exception is thrown when the blend file structure is
|
||||||
* somehow invalid or corrupted
|
* somehow invalid or corrupted
|
||||||
*/
|
*/
|
||||||
private VertexBuffer[] readVerticesWeightsData(Structure objectStructure, Structure meshStructure, Skeleton skeleton, int materialIndex,
|
private VertexBuffer[] readVerticesWeightsData(Structure objectStructure, Structure meshStructure, Skeleton skeleton, int materialIndex, int[] bonesGroups, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
int[] bonesGroups, BlenderContext blenderContext) throws BlenderFileException {
|
|
||||||
ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
|
ArmatureHelper armatureHelper = blenderContext.getHelper(ArmatureHelper.class);
|
||||||
Structure defBase = (Structure) objectStructure.getFieldValue("defbase");
|
Structure defBase = (Structure) objectStructure.getFieldValue("defbase");
|
||||||
Map<Integer, Integer> groupToBoneIndexMap = armatureHelper.getGroupToBoneIndexMap(defBase, skeleton, blenderContext);
|
Map<Integer, Integer> groupToBoneIndexMap = armatureHelper.getGroupToBoneIndexMap(defBase, skeleton, blenderContext);
|
||||||
|
|
||||||
MeshContext meshContext = blenderContext.getMeshContext(meshStructure.getOldMemoryAddress());
|
MeshContext meshContext = blenderContext.getMeshContext(meshStructure.getOldMemoryAddress());
|
||||||
|
|
||||||
return this.getBoneWeightAndIndexBuffer(meshStructure, meshContext.getVertexCount(materialIndex),
|
return this.getBoneWeightAndIndexBuffer(meshStructure, meshContext.getVertexCount(materialIndex), bonesGroups, meshContext.getVertexReferenceMap(materialIndex), groupToBoneIndexMap, blenderContext);
|
||||||
bonesGroups, meshContext.getVertexReferenceMap(materialIndex), groupToBoneIndexMap, blenderContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -292,8 +290,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
* this exception is thrown when the blend file structure is
|
* this exception is thrown when the blend file structure is
|
||||||
* somehow invalid or corrupted
|
* somehow invalid or corrupted
|
||||||
*/
|
*/
|
||||||
private VertexBuffer[] getBoneWeightAndIndexBuffer(Structure meshStructure, int vertexListSize, int[] bonesGroups, Map<Integer, List<Integer>> vertexReferenceMap, Map<Integer, Integer> groupToBoneIndexMap, BlenderContext blenderContext)
|
private VertexBuffer[] getBoneWeightAndIndexBuffer(Structure meshStructure, int vertexListSize, int[] bonesGroups, Map<Integer, List<Integer>> vertexReferenceMap, Map<Integer, Integer> groupToBoneIndexMap, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
throws BlenderFileException {
|
|
||||||
bonesGroups[0] = 0;
|
bonesGroups[0] = 0;
|
||||||
Pointer pDvert = (Pointer) meshStructure.getFieldValue("dvert");// dvert = DeformVERTices
|
Pointer pDvert = (Pointer) meshStructure.getFieldValue("dvert");// dvert = DeformVERTices
|
||||||
FloatBuffer weightsFloatData = BufferUtils.createFloatBuffer(vertexListSize * MAXIMUM_WEIGHTS_PER_VERTEX);
|
FloatBuffer weightsFloatData = BufferUtils.createFloatBuffer(vertexListSize * MAXIMUM_WEIGHTS_PER_VERTEX);
|
||||||
@ -303,12 +300,12 @@ import com.jme3.util.BufferUtils;
|
|||||||
boolean warnAboutTooManyVertexWeights = false;
|
boolean warnAboutTooManyVertexWeights = false;
|
||||||
List<Structure> dverts = pDvert.fetchData(blenderContext.getInputStream());// dverts.size() == verticesAmount (one dvert per vertex in blender)
|
List<Structure> dverts = pDvert.fetchData(blenderContext.getInputStream());// dverts.size() == verticesAmount (one dvert per vertex in blender)
|
||||||
int vertexIndex = 0;
|
int vertexIndex = 0;
|
||||||
//use tree map to sort weights from the lowest to the highest ones
|
// use tree map to sort weights from the lowest to the highest ones
|
||||||
TreeMap<Float, Integer> weightToIndexMap = new TreeMap<Float, Integer>();
|
TreeMap<Float, Integer> weightToIndexMap = new TreeMap<Float, Integer>();
|
||||||
|
|
||||||
for (Structure dvert : dverts) {
|
for (Structure dvert : dverts) {
|
||||||
List<Integer> vertexIndices = vertexReferenceMap.get(Integer.valueOf(vertexIndex));// we fetch the referenced vertices here
|
List<Integer> vertexIndices = vertexReferenceMap.get(Integer.valueOf(vertexIndex));// we fetch the referenced vertices here
|
||||||
if(vertexIndices != null) {
|
if (vertexIndices != null) {
|
||||||
int totweight = ((Number) dvert.getFieldValue("totweight")).intValue();// total amount of weights assignet to the vertex (max. 4 in JME)
|
int totweight = ((Number) dvert.getFieldValue("totweight")).intValue();// total amount of weights assignet to the vertex (max. 4 in JME)
|
||||||
Pointer pDW = (Pointer) dvert.getFieldValue("dw");
|
Pointer pDW = (Pointer) dvert.getFieldValue("dw");
|
||||||
if (totweight > 0 && groupToBoneIndexMap != null) {
|
if (totweight > 0 && groupToBoneIndexMap != null) {
|
||||||
@ -320,7 +317,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
// null here means that we came accross group that has no bone attached to
|
// null here means that we came accross group that has no bone attached to
|
||||||
if (boneIndex != null) {
|
if (boneIndex != null) {
|
||||||
float weight = ((Number) deformWeight.getFieldValue("weight")).floatValue();
|
float weight = ((Number) deformWeight.getFieldValue("weight")).floatValue();
|
||||||
if(weightIndex < MAXIMUM_WEIGHTS_PER_VERTEX) {
|
if (weightIndex < MAXIMUM_WEIGHTS_PER_VERTEX) {
|
||||||
if (weight == 0.0f) {
|
if (weight == 0.0f) {
|
||||||
boneIndex = Integer.valueOf(0);
|
boneIndex = Integer.valueOf(0);
|
||||||
}
|
}
|
||||||
@ -331,10 +328,10 @@ import com.jme3.util.BufferUtils;
|
|||||||
}
|
}
|
||||||
weightToIndexMap.put(weight, weightIndex);
|
weightToIndexMap.put(weight, weightIndex);
|
||||||
bonesGroups[0] = Math.max(bonesGroups[0], weightIndex + 1);
|
bonesGroups[0] = Math.max(bonesGroups[0], weightIndex + 1);
|
||||||
} else if(weight > 0) {//if weight is zero the simply ignore it
|
} else if (weight > 0) {// if weight is zero the simply ignore it
|
||||||
warnAboutTooManyVertexWeights = true;
|
warnAboutTooManyVertexWeights = true;
|
||||||
Entry<Float, Integer> lowestWeightAndIndex = weightToIndexMap.firstEntry();
|
Entry<Float, Integer> lowestWeightAndIndex = weightToIndexMap.firstEntry();
|
||||||
if(lowestWeightAndIndex != null && lowestWeightAndIndex.getKey() < weight) {
|
if (lowestWeightAndIndex != null && lowestWeightAndIndex.getKey() < weight) {
|
||||||
weightsFloatData.put(lowestWeightAndIndex.getValue(), weight);
|
weightsFloatData.put(lowestWeightAndIndex.getValue(), weight);
|
||||||
indicesData.put(lowestWeightAndIndex.getValue(), boneIndex.byteValue());
|
indicesData.put(lowestWeightAndIndex.getValue(), boneIndex.byteValue());
|
||||||
weightToIndexMap.remove(lowestWeightAndIndex.getKey());
|
weightToIndexMap.remove(lowestWeightAndIndex.getKey());
|
||||||
@ -355,7 +352,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
++vertexIndex;
|
++vertexIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(warnAboutTooManyVertexWeights) {
|
if (warnAboutTooManyVertexWeights) {
|
||||||
LOGGER.log(Level.WARNING, "{0} has vertices with more than 4 weights assigned. The model may not behave as it should.", meshStructure.getName());
|
LOGGER.log(Level.WARNING, "{0} has vertices with more than 4 weights assigned. The model may not behave as it should.", meshStructure.getName());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -29,7 +29,7 @@ import java.util.logging.Logger;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ArrayModifier extends Modifier {
|
/* package */class ArrayModifier extends Modifier {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ArrayModifier.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ArrayModifier.class.getName());
|
||||||
|
|
||||||
/** Parameters of the modifier. */
|
/** Parameters of the modifier. */
|
||||||
@ -52,7 +52,7 @@ import java.util.logging.Logger;
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public ArrayModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException {
|
public ArrayModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
if(this.validate(modifierStructure, blenderContext)) {
|
if (this.validate(modifierStructure, blenderContext)) {
|
||||||
Number fittype = (Number) modifierStructure.getFieldValue("fit_type");
|
Number fittype = (Number) modifierStructure.getFieldValue("fit_type");
|
||||||
modifierData.put("fittype", fittype);
|
modifierData.put("fittype", fittype);
|
||||||
switch (fittype.intValue()) {
|
switch (fittype.intValue()) {
|
||||||
@ -76,8 +76,8 @@ import java.util.logging.Logger;
|
|||||||
if (mesh instanceof Curve) {
|
if (mesh instanceof Curve) {
|
||||||
length += ((Curve) mesh).getLength();
|
length += ((Curve) mesh).getLength();
|
||||||
} else {
|
} else {
|
||||||
//if bevel object has several parts then each mesh will have the same reference
|
// if bevel object has several parts then each mesh will have the same reference
|
||||||
//to length value (and we should use only one)
|
// to length value (and we should use only one)
|
||||||
Number curveLength = spatial.getUserData("curveLength");
|
Number curveLength = spatial.getUserData("curveLength");
|
||||||
if (curveLength != null && !referencesToCurveLengths.contains(curveLength)) {
|
if (curveLength != null && !referencesToCurveLengths.contains(curveLength)) {
|
||||||
length += curveLength.floatValue();
|
length += curveLength.floatValue();
|
||||||
@ -98,12 +98,12 @@ import java.util.logging.Logger;
|
|||||||
int offsettype = ((Number) modifierStructure.getFieldValue("offset_type")).intValue();
|
int offsettype = ((Number) modifierStructure.getFieldValue("offset_type")).intValue();
|
||||||
if ((offsettype & 0x01) != 0) {// Constant offset
|
if ((offsettype & 0x01) != 0) {// Constant offset
|
||||||
DynamicArray<Number> offsetArray = (DynamicArray<Number>) modifierStructure.getFieldValue("offset");
|
DynamicArray<Number> offsetArray = (DynamicArray<Number>) modifierStructure.getFieldValue("offset");
|
||||||
float[] offset = new float[]{offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue()};
|
float[] offset = new float[] { offsetArray.get(0).floatValue(), offsetArray.get(1).floatValue(), offsetArray.get(2).floatValue() };
|
||||||
modifierData.put("offset", offset);
|
modifierData.put("offset", offset);
|
||||||
}
|
}
|
||||||
if ((offsettype & 0x02) != 0) {// Relative offset
|
if ((offsettype & 0x02) != 0) {// Relative offset
|
||||||
DynamicArray<Number> scaleArray = (DynamicArray<Number>) modifierStructure.getFieldValue("scale");
|
DynamicArray<Number> scaleArray = (DynamicArray<Number>) modifierStructure.getFieldValue("scale");
|
||||||
float[] scale = new float[]{scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue()};
|
float[] scale = new float[] { scaleArray.get(0).floatValue(), scaleArray.get(1).floatValue(), scaleArray.get(2).floatValue() };
|
||||||
modifierData.put("scale", scale);
|
modifierData.put("scale", scale);
|
||||||
}
|
}
|
||||||
if ((offsettype & 0x04) != 0) {// Object offset
|
if ((offsettype & 0x04) != 0) {// Object offset
|
||||||
@ -127,18 +127,18 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node apply(Node node, BlenderContext blenderContext) {
|
public Node apply(Node node, BlenderContext blenderContext) {
|
||||||
if(invalid) {
|
if (invalid) {
|
||||||
LOGGER.log(Level.WARNING, "Array modifier is invalid! Cannot be applied to: {0}", node.getName());
|
LOGGER.log(Level.WARNING, "Array modifier is invalid! Cannot be applied to: {0}", node.getName());
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
int fittype = ((Number) modifierData.get("fittype")).intValue();
|
int fittype = ((Number) modifierData.get("fittype")).intValue();
|
||||||
float[] offset = (float[]) modifierData.get("offset");
|
float[] offset = (float[]) modifierData.get("offset");
|
||||||
if (offset == null) {// the node will be repeated several times in the same place
|
if (offset == null) {// the node will be repeated several times in the same place
|
||||||
offset = new float[]{0.0f, 0.0f, 0.0f};
|
offset = new float[] { 0.0f, 0.0f, 0.0f };
|
||||||
}
|
}
|
||||||
float[] scale = (float[]) modifierData.get("scale");
|
float[] scale = (float[]) modifierData.get("scale");
|
||||||
if (scale == null) {// the node will be repeated several times in the same place
|
if (scale == null) {// the node will be repeated several times in the same place
|
||||||
scale = new float[]{0.0f, 0.0f, 0.0f};
|
scale = new float[] { 0.0f, 0.0f, 0.0f };
|
||||||
} else {
|
} else {
|
||||||
// getting bounding box
|
// getting bounding box
|
||||||
node.updateModelBound();
|
node.updateModelBound();
|
||||||
@ -158,7 +158,7 @@ import java.util.logging.Logger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// adding object's offset
|
// adding object's offset
|
||||||
float[] objectOffset = new float[]{0.0f, 0.0f, 0.0f};
|
float[] objectOffset = new float[] { 0.0f, 0.0f, 0.0f };
|
||||||
Pointer pOffsetObject = (Pointer) modifierData.get("offsetob");
|
Pointer pOffsetObject = (Pointer) modifierData.get("offsetob");
|
||||||
if (pOffsetObject != null) {
|
if (pOffsetObject != null) {
|
||||||
FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
|
FileBlockHeader offsetObjectBlock = blenderContext.getFileBlock(pOffsetObject.getOldMemoryAddress());
|
||||||
@ -175,8 +175,8 @@ import java.util.logging.Logger;
|
|||||||
}
|
}
|
||||||
|
|
||||||
// getting start and end caps
|
// getting start and end caps
|
||||||
Node[] caps = new Node[]{null, null};
|
Node[] caps = new Node[] { null, null };
|
||||||
Pointer[] pCaps = new Pointer[]{(Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap")};
|
Pointer[] pCaps = new Pointer[] { (Pointer) modifierData.get("startcap"), (Pointer) modifierData.get("endcap") };
|
||||||
for (int i = 0; i < pCaps.length; ++i) {
|
for (int i = 0; i < pCaps.length; ++i) {
|
||||||
if (pCaps[i] != null) {
|
if (pCaps[i] != null) {
|
||||||
caps[i] = (Node) blenderContext.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
caps[i] = (Node) blenderContext.getLoadedFeature(pCaps[i].getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
|
@ -30,7 +30,7 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class MirrorModifier extends Modifier {
|
/* package */class MirrorModifier extends Modifier {
|
||||||
private static final Logger LOGGER = Logger.getLogger(MirrorModifier.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(MirrorModifier.class.getName());
|
||||||
|
|
||||||
/** Parameters of the modifier. */
|
/** Parameters of the modifier. */
|
||||||
@ -53,7 +53,7 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
* corrupted
|
* corrupted
|
||||||
*/
|
*/
|
||||||
public MirrorModifier(Structure modifierStructure, BlenderContext blenderContext) {
|
public MirrorModifier(Structure modifierStructure, BlenderContext blenderContext) {
|
||||||
if(this.validate(modifierStructure, blenderContext)) {
|
if (this.validate(modifierStructure, blenderContext)) {
|
||||||
modifierData.put("flag", modifierStructure.getFieldValue("flag"));
|
modifierData.put("flag", modifierStructure.getFieldValue("flag"));
|
||||||
modifierData.put("tolerance", modifierStructure.getFieldValue("tolerance"));
|
modifierData.put("tolerance", modifierStructure.getFieldValue("tolerance"));
|
||||||
Pointer pMirrorOb = (Pointer) modifierStructure.getFieldValue("mirror_ob");
|
Pointer pMirrorOb = (Pointer) modifierStructure.getFieldValue("mirror_ob");
|
||||||
@ -65,23 +65,19 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node apply(Node node, BlenderContext blenderContext) {
|
public Node apply(Node node, BlenderContext blenderContext) {
|
||||||
if(invalid) {
|
if (invalid) {
|
||||||
LOGGER.log(Level.WARNING, "Mirror modifier is invalid! Cannot be applied to: {0}", node.getName());
|
LOGGER.log(Level.WARNING, "Mirror modifier is invalid! Cannot be applied to: {0}", node.getName());
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flag = ((Number) modifierData.get("flag")).intValue();
|
int flag = ((Number) modifierData.get("flag")).intValue();
|
||||||
float[] mirrorFactor = new float[]{
|
float[] mirrorFactor = new float[] { (flag & 0x08) != 0 ? -1.0f : 1.0f, (flag & 0x10) != 0 ? -1.0f : 1.0f, (flag & 0x20) != 0 ? -1.0f : 1.0f };
|
||||||
(flag & 0x08) != 0 ? -1.0f : 1.0f,
|
if (blenderContext.getBlenderKey().isFixUpAxis()) {
|
||||||
(flag & 0x10) != 0 ? -1.0f : 1.0f,
|
|
||||||
(flag & 0x20) != 0 ? -1.0f : 1.0f
|
|
||||||
};
|
|
||||||
if(blenderContext.getBlenderKey().isFixUpAxis()) {
|
|
||||||
float temp = mirrorFactor[1];
|
float temp = mirrorFactor[1];
|
||||||
mirrorFactor[1] = mirrorFactor[2];
|
mirrorFactor[1] = mirrorFactor[2];
|
||||||
mirrorFactor[2] = temp;
|
mirrorFactor[2] = temp;
|
||||||
}
|
}
|
||||||
float[] center = new float[]{0.0f, 0.0f, 0.0f};
|
float[] center = new float[] { 0.0f, 0.0f, 0.0f };
|
||||||
Pointer pObject = (Pointer) modifierData.get("mirrorob");
|
Pointer pObject = (Pointer) modifierData.get("mirrorob");
|
||||||
if (pObject != null) {
|
if (pObject != null) {
|
||||||
Structure objectStructure;
|
Structure objectStructure;
|
||||||
@ -102,7 +98,7 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
float tolerance = ((Number) modifierData.get("tolerance")).floatValue();
|
float tolerance = ((Number) modifierData.get("tolerance")).floatValue();
|
||||||
boolean mirrorU = (flag & 0x01) != 0;
|
boolean mirrorU = (flag & 0x01) != 0;
|
||||||
boolean mirrorV = (flag & 0x02) != 0;
|
boolean mirrorV = (flag & 0x02) != 0;
|
||||||
// boolean mirrorVGroup = (flag & 0x20) != 0;
|
// boolean mirrorVGroup = (flag & 0x20) != 0;
|
||||||
|
|
||||||
Set<Integer> modifiedIndexes = new HashSet<Integer>();
|
Set<Integer> modifiedIndexes = new HashSet<Integer>();
|
||||||
List<Geometry> geometriesToAdd = new ArrayList<Geometry>();
|
List<Geometry> geometriesToAdd = new ArrayList<Geometry>();
|
||||||
@ -124,9 +120,9 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
Buffer cloneIndexes = clone.getBuffer(Type.Index).getData();
|
Buffer cloneIndexes = clone.getBuffer(Type.Index).getData();
|
||||||
|
|
||||||
for (int i = 0; i < cloneIndexes.limit(); ++i) {
|
for (int i = 0; i < cloneIndexes.limit(); ++i) {
|
||||||
int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer)cloneIndexes).get(i) : ((IntBuffer)cloneIndexes).get(i);
|
int index = cloneIndexes instanceof ShortBuffer ? ((ShortBuffer) cloneIndexes).get(i) : ((IntBuffer) cloneIndexes).get(i);
|
||||||
if(!modifiedIndexes.contains((int)index)) {
|
if (!modifiedIndexes.contains((int) index)) {
|
||||||
modifiedIndexes.add((int)index);
|
modifiedIndexes.add((int) index);
|
||||||
int valueIndex = index * 3 + mirrorIndex;
|
int valueIndex = index * 3 + mirrorIndex;
|
||||||
|
|
||||||
float value = clonePosition.get(valueIndex);
|
float value = clonePosition.get(valueIndex);
|
||||||
@ -134,37 +130,37 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
|
|||||||
|
|
||||||
if (Math.abs(d) <= tolerance) {
|
if (Math.abs(d) <= tolerance) {
|
||||||
clonePosition.put(valueIndex, center[mirrorIndex]);
|
clonePosition.put(valueIndex, center[mirrorIndex]);
|
||||||
if(cloneBindPosePosition != null) {
|
if (cloneBindPosePosition != null) {
|
||||||
cloneBindPosePosition.put(valueIndex, center[mirrorIndex]);
|
cloneBindPosePosition.put(valueIndex, center[mirrorIndex]);
|
||||||
}
|
}
|
||||||
position.put(valueIndex, center[mirrorIndex]);
|
position.put(valueIndex, center[mirrorIndex]);
|
||||||
if(bindPosePosition != null) {
|
if (bindPosePosition != null) {
|
||||||
bindPosePosition.put(valueIndex, center[mirrorIndex]);
|
bindPosePosition.put(valueIndex, center[mirrorIndex]);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
clonePosition.put(valueIndex, value + 2.0f * d);
|
clonePosition.put(valueIndex, value + 2.0f * d);
|
||||||
if(cloneBindPosePosition != null) {
|
if (cloneBindPosePosition != null) {
|
||||||
cloneBindPosePosition.put(valueIndex, value + 2.0f * d);
|
cloneBindPosePosition.put(valueIndex, value + 2.0f * d);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cloneNormals.put(valueIndex, -cloneNormals.get(valueIndex));
|
cloneNormals.put(valueIndex, -cloneNormals.get(valueIndex));
|
||||||
if(cloneBindPoseNormals != null) {
|
if (cloneBindPoseNormals != null) {
|
||||||
cloneBindPoseNormals.put(valueIndex, -cloneNormals.get(valueIndex));
|
cloneBindPoseNormals.put(valueIndex, -cloneNormals.get(valueIndex));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
modifiedIndexes.clear();
|
modifiedIndexes.clear();
|
||||||
|
|
||||||
//flipping index order
|
// flipping index order
|
||||||
for (int i = 0; i < cloneIndexes.limit(); i += 3) {
|
for (int i = 0; i < cloneIndexes.limit(); i += 3) {
|
||||||
if(cloneIndexes instanceof ShortBuffer) {
|
if (cloneIndexes instanceof ShortBuffer) {
|
||||||
short index = ((ShortBuffer)cloneIndexes).get(i + 2);
|
short index = ((ShortBuffer) cloneIndexes).get(i + 2);
|
||||||
((ShortBuffer)cloneIndexes).put(i + 2, ((ShortBuffer)cloneIndexes).get(i + 1));
|
((ShortBuffer) cloneIndexes).put(i + 2, ((ShortBuffer) cloneIndexes).get(i + 1));
|
||||||
((ShortBuffer)cloneIndexes).put(i + 1, index);
|
((ShortBuffer) cloneIndexes).put(i + 1, index);
|
||||||
} else {
|
} else {
|
||||||
int index = ((IntBuffer)cloneIndexes).get(i + 2);
|
int index = ((IntBuffer) cloneIndexes).get(i + 2);
|
||||||
((IntBuffer)cloneIndexes).put(i + 2, ((IntBuffer)cloneIndexes).get(i + 1));
|
((IntBuffer) cloneIndexes).put(i + 2, ((IntBuffer) cloneIndexes).get(i + 1));
|
||||||
((IntBuffer)cloneIndexes).put(i + 1, index);
|
((IntBuffer) cloneIndexes).put(i + 1, index);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,7 +63,7 @@ public abstract class Modifier {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected boolean validate(Structure modifierStructure, BlenderContext blenderContext) {
|
protected boolean validate(Structure modifierStructure, BlenderContext blenderContext) {
|
||||||
Structure modifierData = (Structure)modifierStructure.getFieldValue("modifier");
|
Structure modifierData = (Structure) modifierStructure.getFieldValue("modifier");
|
||||||
Pointer pError = (Pointer) modifierData.getFieldValue("error");
|
Pointer pError = (Pointer) modifierData.getFieldValue("error");
|
||||||
invalid = pError.isNotNull();
|
invalid = pError.isNotNull();
|
||||||
return !invalid;
|
return !invalid;
|
||||||
|
@ -86,7 +86,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
List<Structure> modifiers = modifiersListBase.evaluateListBase(blenderContext);
|
List<Structure> modifiers = modifiersListBase.evaluateListBase(blenderContext);
|
||||||
for (Structure modifierStructure : modifiers) {
|
for (Structure modifierStructure : modifiers) {
|
||||||
String modifierType = modifierStructure.getType();
|
String modifierType = modifierStructure.getType();
|
||||||
if(!Modifier.canBeAppliedMultipleTimes(modifierType) && alreadyReadModifiers.contains(modifierType)) {
|
if (!Modifier.canBeAppliedMultipleTimes(modifierType) && alreadyReadModifiers.contains(modifierType)) {
|
||||||
LOGGER.log(Level.WARNING, "Modifier {0} can only be applied once to object: {1}", new Object[] { modifierType, objectStructure.getName() });
|
LOGGER.log(Level.WARNING, "Modifier {0} can only be applied once to object: {1}", new Object[] { modifierType, objectStructure.getName() });
|
||||||
} else {
|
} else {
|
||||||
Modifier modifier = null;
|
Modifier modifier = null;
|
||||||
@ -101,7 +101,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (modifier != null) {
|
if (modifier != null) {
|
||||||
if(modifier.isModifying()) {
|
if (modifier.isModifying()) {
|
||||||
result.add(modifier);
|
result.add(modifier);
|
||||||
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), modifier);
|
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), modifier);
|
||||||
alreadyReadModifiers.add(modifierType);
|
alreadyReadModifiers.add(modifierType);
|
||||||
@ -153,7 +153,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
||||||
Structure ipoStructure = pIpo.fetchData(blenderContext.getInputStream()).get(0);
|
Structure ipoStructure = pIpo.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
|
Ipo ipo = ipoHelper.fromIpoStructure(ipoStructure, blenderContext);
|
||||||
if(ipo != null) {
|
if (ipo != null) {
|
||||||
result = new ObjectAnimationModifier(ipo, objectStructure.getName(), objectStructure.getOldMemoryAddress(), blenderContext);
|
result = new ObjectAnimationModifier(ipo, objectStructure.getName(), objectStructure.getOldMemoryAddress(), blenderContext);
|
||||||
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), result);
|
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), result);
|
||||||
}
|
}
|
||||||
@ -184,7 +184,7 @@ public class ModifierHelper extends AbstractBlenderHelper {
|
|||||||
Structure actionStructure = pAction.fetchData(blenderContext.getInputStream()).get(0);
|
Structure actionStructure = pAction.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
IpoHelper ipoHelper = blenderContext.getHelper(IpoHelper.class);
|
||||||
Ipo ipo = ipoHelper.fromAction(actionStructure, blenderContext);
|
Ipo ipo = ipoHelper.fromAction(actionStructure, blenderContext);
|
||||||
if(ipo != null) {//ipo can be null if it has no curves applied, ommit such modifier then
|
if (ipo != null) {// ipo can be null if it has no curves applied, ommit such modifier then
|
||||||
result = new ObjectAnimationModifier(ipo, actionStructure.getName(), objectStructure.getOldMemoryAddress(), blenderContext);
|
result = new ObjectAnimationModifier(ipo, actionStructure.getName(), objectStructure.getOldMemoryAddress(), blenderContext);
|
||||||
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), result);
|
blenderContext.addModifier(objectStructure.getOldMemoryAddress(), result);
|
||||||
}
|
}
|
||||||
|
@ -54,7 +54,7 @@ import com.jme3.scene.plugins.ogre.AnimData;
|
|||||||
// calculating track
|
// calculating track
|
||||||
SpatialTrack track = (SpatialTrack) ipo.calculateTrack(-1, object.getLocalRotation(), 0, ipo.getLastFrame(), fps, true);
|
SpatialTrack track = (SpatialTrack) ipo.calculateTrack(-1, object.getLocalRotation(), 0, ipo.getLastFrame(), fps, true);
|
||||||
|
|
||||||
Animation animation = new Animation(objectAnimationName, ipo.getLastFrame() / (float)fps);
|
Animation animation = new Animation(objectAnimationName, ipo.getLastFrame() / (float) fps);
|
||||||
animation.setTracks(new SpatialTrack[] { track });
|
animation.setTracks(new SpatialTrack[] { track });
|
||||||
ArrayList<Animation> animations = new ArrayList<Animation>(1);
|
ArrayList<Animation> animations = new ArrayList<Animation>(1);
|
||||||
animations.add(animation);
|
animations.add(animation);
|
||||||
|
@ -43,7 +43,7 @@ import java.util.logging.Logger;
|
|||||||
* blender file
|
* blender file
|
||||||
*/
|
*/
|
||||||
public ParticlesModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException {
|
public ParticlesModifier(Structure modifierStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
if(this.validate(modifierStructure, blenderContext)) {
|
if (this.validate(modifierStructure, blenderContext)) {
|
||||||
Pointer pParticleSystem = (Pointer) modifierStructure.getFieldValue("psys");
|
Pointer pParticleSystem = (Pointer) modifierStructure.getFieldValue("psys");
|
||||||
if (pParticleSystem.isNotNull()) {
|
if (pParticleSystem.isNotNull()) {
|
||||||
ParticlesHelper particlesHelper = blenderContext.getHelper(ParticlesHelper.class);
|
ParticlesHelper particlesHelper = blenderContext.getHelper(ParticlesHelper.class);
|
||||||
@ -55,7 +55,7 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Node apply(Node node, BlenderContext blenderContext) {
|
public Node apply(Node node, BlenderContext blenderContext) {
|
||||||
if(invalid) {
|
if (invalid) {
|
||||||
LOGGER.log(Level.WARNING, "Particles modifier is invalid! Cannot be applied to: {0}", node.getName());
|
LOGGER.log(Level.WARNING, "Particles modifier is invalid! Cannot be applied to: {0}", node.getName());
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
@ -80,8 +80,7 @@ import java.util.logging.Logger;
|
|||||||
Mesh mesh = ((Geometry) spatial).getMesh();
|
Mesh mesh = ((Geometry) spatial).getMesh();
|
||||||
if (mesh != null) {
|
if (mesh != null) {
|
||||||
meshes.add(mesh);
|
meshes.add(mesh);
|
||||||
Material material = materialHelper.getParticlesMaterial(
|
Material material = materialHelper.getParticlesMaterial(((Geometry) spatial).getMaterial(), alphaFunction, blenderContext);
|
||||||
((Geometry) spatial).getMaterial(), alphaFunction, blenderContext);
|
|
||||||
emitter.setMaterial(material);// TODO: divide into several pieces
|
emitter.setMaterial(material);// TODO: divide into several pieces
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,24 +106,24 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
*/
|
*/
|
||||||
public Object toObject(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
|
public Object toObject(Structure objectStructure, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
Object loadedResult = blenderContext.getLoadedFeature(objectStructure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
Object loadedResult = blenderContext.getLoadedFeature(objectStructure.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
if(loadedResult != null) {
|
if (loadedResult != null) {
|
||||||
return loadedResult;
|
return loadedResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
blenderContext.pushParent(objectStructure);
|
blenderContext.pushParent(objectStructure);
|
||||||
|
|
||||||
//get object data
|
// get object data
|
||||||
int type = ((Number)objectStructure.getFieldValue("type")).intValue();
|
int type = ((Number) objectStructure.getFieldValue("type")).intValue();
|
||||||
String name = objectStructure.getName();
|
String name = objectStructure.getName();
|
||||||
LOGGER.log(Level.FINE, "Loading obejct: {0}", name);
|
LOGGER.log(Level.FINE, "Loading obejct: {0}", name);
|
||||||
|
|
||||||
int restrictflag = ((Number)objectStructure.getFieldValue("restrictflag")).intValue();
|
int restrictflag = ((Number) objectStructure.getFieldValue("restrictflag")).intValue();
|
||||||
boolean visible = (restrictflag & 0x01) != 0;
|
boolean visible = (restrictflag & 0x01) != 0;
|
||||||
Node result = null;
|
Node result = null;
|
||||||
|
|
||||||
Pointer pParent = (Pointer)objectStructure.getFieldValue("parent");
|
Pointer pParent = (Pointer) objectStructure.getFieldValue("parent");
|
||||||
Object parent = blenderContext.getLoadedFeature(pParent.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
Object parent = blenderContext.getLoadedFeature(pParent.getOldMemoryAddress(), LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
if(parent == null && pParent.isNotNull()) {
|
if (parent == null && pParent.isNotNull()) {
|
||||||
Structure parentStructure = pParent.fetchData(blenderContext.getInputStream()).get(0);
|
Structure parentStructure = pParent.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
parent = this.toObject(parentStructure, blenderContext);
|
parent = this.toObject(parentStructure, blenderContext);
|
||||||
}
|
}
|
||||||
@ -131,12 +131,12 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
Transform t = this.getTransformation(objectStructure, blenderContext);
|
Transform t = this.getTransformation(objectStructure, blenderContext);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
switch(type) {
|
switch (type) {
|
||||||
case OBJECT_TYPE_EMPTY:
|
case OBJECT_TYPE_EMPTY:
|
||||||
LOGGER.log(Level.FINE, "Importing empty.");
|
LOGGER.log(Level.FINE, "Importing empty.");
|
||||||
Node empty = new Node(name);
|
Node empty = new Node(name);
|
||||||
empty.setLocalTransform(t);
|
empty.setLocalTransform(t);
|
||||||
if(parent instanceof Node) {
|
if (parent instanceof Node) {
|
||||||
((Node) parent).attachChild(empty);
|
((Node) parent).attachChild(empty);
|
||||||
}
|
}
|
||||||
result = empty;
|
result = empty;
|
||||||
@ -146,47 +146,47 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
Node node = new Node(name);
|
Node node = new Node(name);
|
||||||
node.setCullHint(visible ? CullHint.Always : CullHint.Inherit);
|
node.setCullHint(visible ? CullHint.Always : CullHint.Inherit);
|
||||||
|
|
||||||
//reading mesh
|
// reading mesh
|
||||||
MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
|
MeshHelper meshHelper = blenderContext.getHelper(MeshHelper.class);
|
||||||
Pointer pMesh = (Pointer)objectStructure.getFieldValue("data");
|
Pointer pMesh = (Pointer) objectStructure.getFieldValue("data");
|
||||||
List<Structure> meshesArray = pMesh.fetchData(blenderContext.getInputStream());
|
List<Structure> meshesArray = pMesh.fetchData(blenderContext.getInputStream());
|
||||||
List<Geometry> geometries = meshHelper.toMesh(meshesArray.get(0), blenderContext);
|
List<Geometry> geometries = meshHelper.toMesh(meshesArray.get(0), blenderContext);
|
||||||
if (geometries != null){
|
if (geometries != null) {
|
||||||
for(Geometry geometry : geometries) {
|
for (Geometry geometry : geometries) {
|
||||||
node.attachChild(geometry);
|
node.attachChild(geometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
node.setLocalTransform(t);
|
node.setLocalTransform(t);
|
||||||
|
|
||||||
//setting the parent
|
// setting the parent
|
||||||
if(parent instanceof Node) {
|
if (parent instanceof Node) {
|
||||||
((Node)parent).attachChild(node);
|
((Node) parent).attachChild(node);
|
||||||
}
|
}
|
||||||
result = node;
|
result = node;
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE_SURF:
|
case OBJECT_TYPE_SURF:
|
||||||
case OBJECT_TYPE_CURVE:
|
case OBJECT_TYPE_CURVE:
|
||||||
LOGGER.log(Level.FINE, "Importing curve/nurb.");
|
LOGGER.log(Level.FINE, "Importing curve/nurb.");
|
||||||
Pointer pCurve = (Pointer)objectStructure.getFieldValue("data");
|
Pointer pCurve = (Pointer) objectStructure.getFieldValue("data");
|
||||||
if(pCurve.isNotNull()) {
|
if (pCurve.isNotNull()) {
|
||||||
CurvesHelper curvesHelper = blenderContext.getHelper(CurvesHelper.class);
|
CurvesHelper curvesHelper = blenderContext.getHelper(CurvesHelper.class);
|
||||||
Structure curveData = pCurve.fetchData(blenderContext.getInputStream()).get(0);
|
Structure curveData = pCurve.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
List<Geometry> curves = curvesHelper.toCurve(curveData, blenderContext);
|
List<Geometry> curves = curvesHelper.toCurve(curveData, blenderContext);
|
||||||
result = new Node(name);
|
result = new Node(name);
|
||||||
for(Geometry curve : curves) {
|
for (Geometry curve : curves) {
|
||||||
((Node)result).attachChild(curve);
|
((Node) result).attachChild(curve);
|
||||||
}
|
}
|
||||||
((Node)result).setLocalTransform(t);
|
((Node) result).setLocalTransform(t);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE_LAMP:
|
case OBJECT_TYPE_LAMP:
|
||||||
LOGGER.log(Level.FINE, "Importing lamp.");
|
LOGGER.log(Level.FINE, "Importing lamp.");
|
||||||
Pointer pLamp = (Pointer)objectStructure.getFieldValue("data");
|
Pointer pLamp = (Pointer) objectStructure.getFieldValue("data");
|
||||||
if(pLamp.isNotNull()) {
|
if (pLamp.isNotNull()) {
|
||||||
LightHelper lightHelper = blenderContext.getHelper(LightHelper.class);
|
LightHelper lightHelper = blenderContext.getHelper(LightHelper.class);
|
||||||
List<Structure> lampsArray = pLamp.fetchData(blenderContext.getInputStream());
|
List<Structure> lampsArray = pLamp.fetchData(blenderContext.getInputStream());
|
||||||
LightNode light = lightHelper.toLight(lampsArray.get(0), blenderContext);
|
LightNode light = lightHelper.toLight(lampsArray.get(0), blenderContext);
|
||||||
if(light!=null) {
|
if (light != null) {
|
||||||
light.setName(name);
|
light.setName(name);
|
||||||
light.setLocalTransform(t);
|
light.setLocalTransform(t);
|
||||||
}
|
}
|
||||||
@ -194,8 +194,8 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE_CAMERA:
|
case OBJECT_TYPE_CAMERA:
|
||||||
Pointer pCamera = (Pointer)objectStructure.getFieldValue("data");
|
Pointer pCamera = (Pointer) objectStructure.getFieldValue("data");
|
||||||
if(pCamera.isNotNull()) {
|
if (pCamera.isNotNull()) {
|
||||||
CameraHelper cameraHelper = blenderContext.getHelper(CameraHelper.class);
|
CameraHelper cameraHelper = blenderContext.getHelper(CameraHelper.class);
|
||||||
List<Structure> camerasArray = pCamera.fetchData(blenderContext.getInputStream());
|
List<Structure> camerasArray = pCamera.fetchData(blenderContext.getInputStream());
|
||||||
CameraNode camera = cameraHelper.toCamera(camerasArray.get(0), blenderContext);
|
CameraNode camera = cameraHelper.toCamera(camerasArray.get(0), blenderContext);
|
||||||
@ -205,13 +205,13 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case OBJECT_TYPE_ARMATURE:
|
case OBJECT_TYPE_ARMATURE:
|
||||||
//need to create an empty node to properly create parent-children relationships between nodes
|
// need to create an empty node to properly create parent-children relationships between nodes
|
||||||
Node armature = new Node(name);
|
Node armature = new Node(name);
|
||||||
armature.setLocalTransform(t);
|
armature.setLocalTransform(t);
|
||||||
armature.setUserData(ArmatureHelper.ARMETURE_NODE_MARKER, Boolean.TRUE);
|
armature.setUserData(ArmatureHelper.ARMETURE_NODE_MARKER, Boolean.TRUE);
|
||||||
|
|
||||||
if(parent instanceof Node) {
|
if (parent instanceof Node) {
|
||||||
((Node)parent).attachChild(armature);
|
((Node) parent).attachChild(armature);
|
||||||
}
|
}
|
||||||
result = armature;
|
result = armature;
|
||||||
break;
|
break;
|
||||||
@ -222,28 +222,28 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
blenderContext.popParent();
|
blenderContext.popParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
if(result != null) {
|
if (result != null) {
|
||||||
result.updateModelBound();//I prefer do compute bounding box here than read it from the file
|
result.updateModelBound();// I prefer do compute bounding box here than read it from the file
|
||||||
|
|
||||||
blenderContext.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
blenderContext.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
||||||
|
|
||||||
//applying modifiers
|
// applying modifiers
|
||||||
LOGGER.log(Level.FINE, "Reading and applying object's modifiers.");
|
LOGGER.log(Level.FINE, "Reading and applying object's modifiers.");
|
||||||
ModifierHelper modifierHelper = blenderContext.getHelper(ModifierHelper.class);
|
ModifierHelper modifierHelper = blenderContext.getHelper(ModifierHelper.class);
|
||||||
Collection<Modifier> modifiers = modifierHelper.readModifiers(objectStructure, blenderContext);
|
Collection<Modifier> modifiers = modifierHelper.readModifiers(objectStructure, blenderContext);
|
||||||
for(Modifier modifier : modifiers) {
|
for (Modifier modifier : modifiers) {
|
||||||
modifier.apply(result, blenderContext);
|
modifier.apply(result, blenderContext);
|
||||||
}
|
}
|
||||||
|
|
||||||
//loading constraints connected with this object
|
// loading constraints connected with this object
|
||||||
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
ConstraintHelper constraintHelper = blenderContext.getHelper(ConstraintHelper.class);
|
||||||
constraintHelper.loadConstraints(objectStructure, blenderContext);
|
constraintHelper.loadConstraints(objectStructure, blenderContext);
|
||||||
|
|
||||||
//reading custom properties
|
// reading custom properties
|
||||||
if(blenderContext.getBlenderKey().isLoadObjectProperties()) {
|
if (blenderContext.getBlenderKey().isLoadObjectProperties()) {
|
||||||
Properties properties = this.loadProperties(objectStructure, blenderContext);
|
Properties properties = this.loadProperties(objectStructure, blenderContext);
|
||||||
//the loaded property is a group property, so we need to get each value and set it to Spatial
|
// the loaded property is a group property, so we need to get each value and set it to Spatial
|
||||||
if(result instanceof Spatial && properties != null && properties.getValue() != null) {
|
if (result instanceof Spatial && properties != null && properties.getValue() != null) {
|
||||||
this.applyProperties((Spatial) result, properties);
|
this.applyProperties((Spatial) result, properties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -259,27 +259,27 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
*/
|
*/
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Transform getTransformation(Structure objectStructure, BlenderContext blenderContext) {
|
public Transform getTransformation(Structure objectStructure, BlenderContext blenderContext) {
|
||||||
//these are transformations in global space
|
// these are transformations in global space
|
||||||
DynamicArray<Number> loc = (DynamicArray<Number>)objectStructure.getFieldValue("loc");
|
DynamicArray<Number> loc = (DynamicArray<Number>) objectStructure.getFieldValue("loc");
|
||||||
DynamicArray<Number> size = (DynamicArray<Number>)objectStructure.getFieldValue("size");
|
DynamicArray<Number> size = (DynamicArray<Number>) objectStructure.getFieldValue("size");
|
||||||
DynamicArray<Number> rot = (DynamicArray<Number>)objectStructure.getFieldValue("rot");
|
DynamicArray<Number> rot = (DynamicArray<Number>) objectStructure.getFieldValue("rot");
|
||||||
|
|
||||||
//load parent inverse matrix
|
// load parent inverse matrix
|
||||||
Pointer pParent = (Pointer) objectStructure.getFieldValue("parent");
|
Pointer pParent = (Pointer) objectStructure.getFieldValue("parent");
|
||||||
Matrix4f parentInv = pParent.isNull() ? Matrix4f.IDENTITY : this.getMatrix(objectStructure, "parentinv");
|
Matrix4f parentInv = pParent.isNull() ? Matrix4f.IDENTITY : this.getMatrix(objectStructure, "parentinv");
|
||||||
|
|
||||||
//create the global matrix (without the scale)
|
// create the global matrix (without the scale)
|
||||||
Matrix4f globalMatrix = new Matrix4f();
|
Matrix4f globalMatrix = new Matrix4f();
|
||||||
globalMatrix.setTranslation(loc.get(0).floatValue(), loc.get(1).floatValue(), loc.get(2).floatValue());
|
globalMatrix.setTranslation(loc.get(0).floatValue(), loc.get(1).floatValue(), loc.get(2).floatValue());
|
||||||
globalMatrix.setRotationQuaternion(new Quaternion().fromAngles(rot.get(0).floatValue(), rot.get(1).floatValue(), rot.get(2).floatValue()));
|
globalMatrix.setRotationQuaternion(new Quaternion().fromAngles(rot.get(0).floatValue(), rot.get(1).floatValue(), rot.get(2).floatValue()));
|
||||||
//compute local matrix
|
// compute local matrix
|
||||||
Matrix4f localMatrix = parentInv.mult(globalMatrix);
|
Matrix4f localMatrix = parentInv.mult(globalMatrix);
|
||||||
|
|
||||||
Vector3f translation = localMatrix.toTranslationVector();
|
Vector3f translation = localMatrix.toTranslationVector();
|
||||||
Quaternion rotation = localMatrix.toRotationQuat();
|
Quaternion rotation = localMatrix.toRotationQuat();
|
||||||
Vector3f scale = this.getScale(parentInv).multLocal(size.get(0).floatValue(), size.get(1).floatValue(), size.get(2).floatValue());
|
Vector3f scale = this.getScale(parentInv).multLocal(size.get(0).floatValue(), size.get(1).floatValue(), size.get(2).floatValue());
|
||||||
|
|
||||||
if(fixUpAxis) {
|
if (fixUpAxis) {
|
||||||
float y = translation.y;
|
float y = translation.y;
|
||||||
translation.y = translation.z;
|
translation.y = translation.z;
|
||||||
translation.z = -y;
|
translation.z = -y;
|
||||||
@ -288,12 +288,12 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
float z = rotation.getZ();
|
float z = rotation.getZ();
|
||||||
rotation.set(rotation.getX(), z, -y, rotation.getW());
|
rotation.set(rotation.getX(), z, -y, rotation.getW());
|
||||||
|
|
||||||
y=scale.y;
|
y = scale.y;
|
||||||
scale.y = scale.z;
|
scale.y = scale.z;
|
||||||
scale.z = y;
|
scale.z = y;
|
||||||
}
|
}
|
||||||
|
|
||||||
//create the result
|
// create the result
|
||||||
Transform t = new Transform(translation, rotation);
|
Transform t = new Transform(translation, rotation);
|
||||||
t.setScale(scale);
|
t.setScale(scale);
|
||||||
return t;
|
return t;
|
||||||
@ -324,14 +324,14 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public Matrix4f getMatrix(Structure structure, String matrixName, boolean applyFixUpAxis) {
|
public Matrix4f getMatrix(Structure structure, String matrixName, boolean applyFixUpAxis) {
|
||||||
Matrix4f result = new Matrix4f();
|
Matrix4f result = new Matrix4f();
|
||||||
DynamicArray<Number> obmat = (DynamicArray<Number>)structure.getFieldValue(matrixName);
|
DynamicArray<Number> obmat = (DynamicArray<Number>) structure.getFieldValue(matrixName);
|
||||||
int rowAndColumnSize = Math.abs((int)Math.sqrt(obmat.getTotalSize()));//the matrix must be square
|
int rowAndColumnSize = Math.abs((int) Math.sqrt(obmat.getTotalSize()));// the matrix must be square
|
||||||
for(int i = 0; i < rowAndColumnSize; ++i) {
|
for (int i = 0; i < rowAndColumnSize; ++i) {
|
||||||
for(int j = 0; j < rowAndColumnSize; ++j) {
|
for (int j = 0; j < rowAndColumnSize; ++j) {
|
||||||
result.set(i, j, obmat.get(j, i).floatValue());
|
result.set(i, j, obmat.get(j, i).floatValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(applyFixUpAxis && fixUpAxis) {
|
if (applyFixUpAxis && fixUpAxis) {
|
||||||
Vector3f translation = result.toTranslationVector();
|
Vector3f translation = result.toTranslationVector();
|
||||||
Quaternion rotation = result.toRotationQuat();
|
Quaternion rotation = result.toRotationQuat();
|
||||||
Vector3f scale = this.getScale(result);
|
Vector3f scale = this.getScale(result);
|
||||||
@ -344,7 +344,7 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
float z = rotation.getZ();
|
float z = rotation.getZ();
|
||||||
rotation.set(rotation.getX(), z, -y, rotation.getW());
|
rotation.set(rotation.getX(), z, -y, rotation.getW());
|
||||||
|
|
||||||
y=scale.y;
|
y = scale.y;
|
||||||
scale.y = scale.z;
|
scale.y = scale.z;
|
||||||
scale.z = y;
|
scale.z = y;
|
||||||
|
|
||||||
@ -378,7 +378,6 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
@Override
|
@Override
|
||||||
public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
|
public boolean shouldBeLoaded(Structure structure, BlenderContext blenderContext) {
|
||||||
int lay = ((Number) structure.getFieldValue("lay")).intValue();
|
int lay = ((Number) structure.getFieldValue("lay")).intValue();
|
||||||
return (lay & blenderContext.getBlenderKey().getLayersToLoad()) != 0
|
return (lay & blenderContext.getBlenderKey().getLayersToLoad()) != 0 && (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0;
|
||||||
&& (blenderContext.getBlenderKey().getFeaturesToLoad() & FeaturesToLoad.OBJECTS) != 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -195,11 +195,11 @@ public class Properties implements Cloneable {
|
|||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
public List<String> getSubPropertiesNames() {
|
public List<String> getSubPropertiesNames() {
|
||||||
List<String> result = null;
|
List<String> result = null;
|
||||||
if(this.type == IDP_GROUP) {
|
if (this.type == IDP_GROUP) {
|
||||||
List<Properties> properties = (List<Properties>)this.value;
|
List<Properties> properties = (List<Properties>) this.value;
|
||||||
if(properties != null && properties.size() > 0) {
|
if (properties != null && properties.size() > 0) {
|
||||||
result = new ArrayList<String>(properties.size());
|
result = new ArrayList<String>(properties.size());
|
||||||
for(Properties property : properties) {
|
for (Properties property : properties) {
|
||||||
result.add(property.getName());
|
result.add(property.getName());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,45 +27,45 @@ public class ParticlesHelper extends AbstractBlenderHelper {
|
|||||||
public static final int PART_FLUID = 3;
|
public static final int PART_FLUID = 3;
|
||||||
|
|
||||||
// part->flag
|
// part->flag
|
||||||
public static final int PART_REACT_STA_END =1;
|
public static final int PART_REACT_STA_END = 1;
|
||||||
public static final int PART_REACT_MULTIPLE =2;
|
public static final int PART_REACT_MULTIPLE = 2;
|
||||||
public static final int PART_LOOP =4;
|
public static final int PART_LOOP = 4;
|
||||||
//public static final int PART_LOOP_INSTANT =8;
|
// public static final int PART_LOOP_INSTANT =8;
|
||||||
public static final int PART_HAIR_GEOMETRY =16;
|
public static final int PART_HAIR_GEOMETRY = 16;
|
||||||
public static final int PART_UNBORN =32; //show unborn particles
|
public static final int PART_UNBORN = 32; // show unborn particles
|
||||||
public static final int PART_DIED =64; //show died particles
|
public static final int PART_DIED = 64; // show died particles
|
||||||
public static final int PART_TRAND =128;
|
public static final int PART_TRAND = 128;
|
||||||
public static final int PART_EDISTR =256; // particle/face from face areas
|
public static final int PART_EDISTR = 256; // particle/face from face areas
|
||||||
public static final int PART_STICKY =512; //collided particles can stick to collider
|
public static final int PART_STICKY = 512; // collided particles can stick to collider
|
||||||
public static final int PART_DIE_ON_COL =1<<12;
|
public static final int PART_DIE_ON_COL = 1 << 12;
|
||||||
public static final int PART_SIZE_DEFL =1<<13; // swept sphere deflections
|
public static final int PART_SIZE_DEFL = 1 << 13; // swept sphere deflections
|
||||||
public static final int PART_ROT_DYN =1<<14; // dynamic rotation
|
public static final int PART_ROT_DYN = 1 << 14; // dynamic rotation
|
||||||
public static final int PART_SIZEMASS =1<<16;
|
public static final int PART_SIZEMASS = 1 << 16;
|
||||||
public static final int PART_ABS_LENGTH =1<<15;
|
public static final int PART_ABS_LENGTH = 1 << 15;
|
||||||
public static final int PART_ABS_TIME =1<<17;
|
public static final int PART_ABS_TIME = 1 << 17;
|
||||||
public static final int PART_GLOB_TIME =1<<18;
|
public static final int PART_GLOB_TIME = 1 << 18;
|
||||||
public static final int PART_BOIDS_2D =1<<19;
|
public static final int PART_BOIDS_2D = 1 << 19;
|
||||||
public static final int PART_BRANCHING =1<<20;
|
public static final int PART_BRANCHING = 1 << 20;
|
||||||
public static final int PART_ANIM_BRANCHING =1<<21;
|
public static final int PART_ANIM_BRANCHING = 1 << 21;
|
||||||
public static final int PART_SELF_EFFECT =1<<22;
|
public static final int PART_SELF_EFFECT = 1 << 22;
|
||||||
public static final int PART_SYMM_BRANCHING =1<<24;
|
public static final int PART_SYMM_BRANCHING = 1 << 24;
|
||||||
public static final int PART_HAIR_BSPLINE =1024;
|
public static final int PART_HAIR_BSPLINE = 1024;
|
||||||
public static final int PART_GRID_INVERT =1<<26;
|
public static final int PART_GRID_INVERT = 1 << 26;
|
||||||
public static final int PART_CHILD_EFFECT =1<<27;
|
public static final int PART_CHILD_EFFECT = 1 << 27;
|
||||||
public static final int PART_CHILD_SEAMS =1<<28;
|
public static final int PART_CHILD_SEAMS = 1 << 28;
|
||||||
public static final int PART_CHILD_RENDER =1<<29;
|
public static final int PART_CHILD_RENDER = 1 << 29;
|
||||||
public static final int PART_CHILD_GUIDE =1<<30;
|
public static final int PART_CHILD_GUIDE = 1 << 30;
|
||||||
|
|
||||||
// part->from
|
// part->from
|
||||||
public static final int PART_FROM_VERT =0;
|
public static final int PART_FROM_VERT = 0;
|
||||||
public static final int PART_FROM_FACE =1;
|
public static final int PART_FROM_FACE = 1;
|
||||||
public static final int PART_FROM_VOLUME =2;
|
public static final int PART_FROM_VOLUME = 2;
|
||||||
public static final int PART_FROM_PARTICLE =3;
|
public static final int PART_FROM_PARTICLE = 3;
|
||||||
public static final int PART_FROM_CHILD =4;
|
public static final int PART_FROM_CHILD = 4;
|
||||||
|
|
||||||
// part->phystype
|
// part->phystype
|
||||||
public static final int PART_PHYS_NO = 0;
|
public static final int PART_PHYS_NO = 0;
|
||||||
public static final int PART_PHYS_NEWTON= 1;
|
public static final int PART_PHYS_NEWTON = 1;
|
||||||
public static final int PART_PHYS_KEYED = 2;
|
public static final int PART_PHYS_KEYED = 2;
|
||||||
public static final int PART_PHYS_BOIDS = 3;
|
public static final int PART_PHYS_BOIDS = 3;
|
||||||
|
|
||||||
@ -97,18 +97,18 @@ public class ParticlesHelper extends AbstractBlenderHelper {
|
|||||||
public ParticleEmitter toParticleEmitter(Structure particleSystem, BlenderContext blenderContext) throws BlenderFileException {
|
public ParticleEmitter toParticleEmitter(Structure particleSystem, BlenderContext blenderContext) throws BlenderFileException {
|
||||||
ParticleEmitter result = null;
|
ParticleEmitter result = null;
|
||||||
Pointer pParticleSettings = (Pointer) particleSystem.getFieldValue("part");
|
Pointer pParticleSettings = (Pointer) particleSystem.getFieldValue("part");
|
||||||
if(pParticleSettings.isNotNull()) {
|
if (pParticleSettings.isNotNull()) {
|
||||||
Structure particleSettings = pParticleSettings.fetchData(blenderContext.getInputStream()).get(0);
|
Structure particleSettings = pParticleSettings.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
|
|
||||||
int totPart = ((Number) particleSettings.getFieldValue("totpart")).intValue();
|
int totPart = ((Number) particleSettings.getFieldValue("totpart")).intValue();
|
||||||
|
|
||||||
//draw type will be stored temporarily in the name (it is used during modifier applying operation)
|
// draw type will be stored temporarily in the name (it is used during modifier applying operation)
|
||||||
int drawAs = ((Number)particleSettings.getFieldValue("draw_as")).intValue();
|
int drawAs = ((Number) particleSettings.getFieldValue("draw_as")).intValue();
|
||||||
char nameSuffix;//P - point, L - line, N - None, B - Bilboard
|
char nameSuffix;// P - point, L - line, N - None, B - Bilboard
|
||||||
switch(drawAs) {
|
switch (drawAs) {
|
||||||
case PART_DRAW_NOT:
|
case PART_DRAW_NOT:
|
||||||
nameSuffix = 'N';
|
nameSuffix = 'N';
|
||||||
totPart = 0;//no need to generate particles in this case
|
totPart = 0;// no need to generate particles in this case
|
||||||
break;
|
break;
|
||||||
case PART_DRAW_BB:
|
case PART_DRAW_BB:
|
||||||
nameSuffix = 'B';
|
nameSuffix = 'B';
|
||||||
@ -116,22 +116,22 @@ public class ParticlesHelper extends AbstractBlenderHelper {
|
|||||||
case PART_DRAW_OB:
|
case PART_DRAW_OB:
|
||||||
case PART_DRAW_GR:
|
case PART_DRAW_GR:
|
||||||
nameSuffix = 'P';
|
nameSuffix = 'P';
|
||||||
LOGGER.warning("Neither object nor group particles supported yet! Using point representation instead!");//TODO: support groups and aobjects
|
LOGGER.warning("Neither object nor group particles supported yet! Using point representation instead!");// TODO: support groups and aobjects
|
||||||
break;
|
break;
|
||||||
case PART_DRAW_LINE:
|
case PART_DRAW_LINE:
|
||||||
nameSuffix = 'L';
|
nameSuffix = 'L';
|
||||||
LOGGER.warning("Lines not yet supported! Using point representation instead!");//TODO: support lines
|
LOGGER.warning("Lines not yet supported! Using point representation instead!");// TODO: support lines
|
||||||
default://all others are rendered as points in blender
|
default:// all others are rendered as points in blender
|
||||||
nameSuffix = 'P';
|
nameSuffix = 'P';
|
||||||
}
|
}
|
||||||
result = new ParticleEmitter(particleSettings.getName()+nameSuffix, Type.Triangle, totPart);
|
result = new ParticleEmitter(particleSettings.getName() + nameSuffix, Type.Triangle, totPart);
|
||||||
if(nameSuffix=='N') {
|
if (nameSuffix == 'N') {
|
||||||
return result;//no need to set anything else
|
return result;// no need to set anything else
|
||||||
}
|
}
|
||||||
|
|
||||||
//setting the emitters shape (the shapes meshes will be set later during modifier applying operation)
|
// setting the emitters shape (the shapes meshes will be set later during modifier applying operation)
|
||||||
int from = ((Number)particleSettings.getFieldValue("from")).intValue();
|
int from = ((Number) particleSettings.getFieldValue("from")).intValue();
|
||||||
switch(from) {
|
switch (from) {
|
||||||
case PART_FROM_VERT:
|
case PART_FROM_VERT:
|
||||||
result.setShape(new EmitterMeshVertexShape());
|
result.setShape(new EmitterMeshVertexShape());
|
||||||
break;
|
break;
|
||||||
@ -145,40 +145,40 @@ public class ParticlesHelper extends AbstractBlenderHelper {
|
|||||||
LOGGER.warning("Default shape used! Unknown emitter shape value ('from' parameter: " + from + ')');
|
LOGGER.warning("Default shape used! Unknown emitter shape value ('from' parameter: " + from + ')');
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading acceleration
|
// reading acceleration
|
||||||
DynamicArray<Number> acc = (DynamicArray<Number>) particleSettings.getFieldValue("acc");
|
DynamicArray<Number> acc = (DynamicArray<Number>) particleSettings.getFieldValue("acc");
|
||||||
result.setGravity(-acc.get(0).floatValue(), -acc.get(1).floatValue(), -acc.get(2).floatValue());
|
result.setGravity(-acc.get(0).floatValue(), -acc.get(1).floatValue(), -acc.get(2).floatValue());
|
||||||
|
|
||||||
//setting the colors
|
// setting the colors
|
||||||
result.setEndColor(new ColorRGBA(1f, 1f, 1f, 1f));
|
result.setEndColor(new ColorRGBA(1f, 1f, 1f, 1f));
|
||||||
result.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
|
result.setStartColor(new ColorRGBA(1f, 1f, 1f, 1f));
|
||||||
|
|
||||||
//reading size
|
// reading size
|
||||||
float sizeFactor = nameSuffix=='B' ? 1.0f : 0.3f;
|
float sizeFactor = nameSuffix == 'B' ? 1.0f : 0.3f;
|
||||||
float size = ((Number)particleSettings.getFieldValue("size")).floatValue() * sizeFactor;
|
float size = ((Number) particleSettings.getFieldValue("size")).floatValue() * sizeFactor;
|
||||||
result.setStartSize(size);
|
result.setStartSize(size);
|
||||||
result.setEndSize(size);
|
result.setEndSize(size);
|
||||||
|
|
||||||
//reading lifetime
|
// reading lifetime
|
||||||
int fps = blenderContext.getBlenderKey().getFps();
|
int fps = blenderContext.getBlenderKey().getFps();
|
||||||
float lifetime = ((Number)particleSettings.getFieldValue("lifetime")).floatValue() / fps;
|
float lifetime = ((Number) particleSettings.getFieldValue("lifetime")).floatValue() / fps;
|
||||||
float randlife = ((Number)particleSettings.getFieldValue("randlife")).floatValue() / fps;
|
float randlife = ((Number) particleSettings.getFieldValue("randlife")).floatValue() / fps;
|
||||||
result.setLowLife(lifetime * (1.0f - randlife));
|
result.setLowLife(lifetime * (1.0f - randlife));
|
||||||
result.setHighLife(lifetime);
|
result.setHighLife(lifetime);
|
||||||
|
|
||||||
//preparing influencer
|
// preparing influencer
|
||||||
ParticleInfluencer influencer;
|
ParticleInfluencer influencer;
|
||||||
int phystype = ((Number)particleSettings.getFieldValue("phystype")).intValue();
|
int phystype = ((Number) particleSettings.getFieldValue("phystype")).intValue();
|
||||||
switch(phystype) {
|
switch (phystype) {
|
||||||
case PART_PHYS_NEWTON:
|
case PART_PHYS_NEWTON:
|
||||||
influencer = new NewtonianParticleInfluencer();
|
influencer = new NewtonianParticleInfluencer();
|
||||||
((NewtonianParticleInfluencer)influencer).setNormalVelocity(((Number)particleSettings.getFieldValue("normfac")).floatValue());
|
((NewtonianParticleInfluencer) influencer).setNormalVelocity(((Number) particleSettings.getFieldValue("normfac")).floatValue());
|
||||||
((NewtonianParticleInfluencer)influencer).setVelocityVariation(((Number)particleSettings.getFieldValue("randfac")).floatValue());
|
((NewtonianParticleInfluencer) influencer).setVelocityVariation(((Number) particleSettings.getFieldValue("randfac")).floatValue());
|
||||||
((NewtonianParticleInfluencer)influencer).setSurfaceTangentFactor(((Number)particleSettings.getFieldValue("tanfac")).floatValue());
|
((NewtonianParticleInfluencer) influencer).setSurfaceTangentFactor(((Number) particleSettings.getFieldValue("tanfac")).floatValue());
|
||||||
((NewtonianParticleInfluencer)influencer).setSurfaceTangentRotation(((Number)particleSettings.getFieldValue("tanphase")).floatValue());
|
((NewtonianParticleInfluencer) influencer).setSurfaceTangentRotation(((Number) particleSettings.getFieldValue("tanphase")).floatValue());
|
||||||
break;
|
break;
|
||||||
case PART_PHYS_BOIDS:
|
case PART_PHYS_BOIDS:
|
||||||
case PART_PHYS_KEYED://TODO: support other influencers
|
case PART_PHYS_KEYED:// TODO: support other influencers
|
||||||
LOGGER.warning("Boids and Keyed particles physic not yet supported! Empty influencer used!");
|
LOGGER.warning("Boids and Keyed particles physic not yet supported! Empty influencer used!");
|
||||||
case PART_PHYS_NO:
|
case PART_PHYS_NO:
|
||||||
default:
|
default:
|
||||||
|
@ -267,7 +267,7 @@ public class ColorBand {
|
|||||||
|
|
||||||
private ColorBandData getColorbandData(int index, Map<Integer, ColorBandData> cbDataMap) {
|
private ColorBandData getColorbandData(int index, Map<Integer, ColorBandData> cbDataMap) {
|
||||||
ColorBandData result = cbDataMap.get(index);
|
ColorBandData result = cbDataMap.get(index);
|
||||||
if(result == null) {
|
if (result == null) {
|
||||||
result = new ColorBandData();
|
result = new ColorBandData();
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -84,8 +84,8 @@ public class CombinedTexture {
|
|||||||
if (!(texture instanceof GeneratedTexture) && !(texture instanceof Texture2D)) {
|
if (!(texture instanceof GeneratedTexture) && !(texture instanceof Texture2D)) {
|
||||||
throw new IllegalArgumentException("Unsupported texture type: " + (texture == null ? "null" : texture.getClass()));
|
throw new IllegalArgumentException("Unsupported texture type: " + (texture == null ? "null" : texture.getClass()));
|
||||||
}
|
}
|
||||||
if(!(texture instanceof GeneratedTexture) || blenderContext.getBlenderKey().isLoadGeneratedTextures()) {
|
if (!(texture instanceof GeneratedTexture) || blenderContext.getBlenderKey().isLoadGeneratedTextures()) {
|
||||||
if(UVCoordinatesGenerator.isTextureCoordinateTypeSupported(UVCoordinatesType.valueOf(uvCoordinatesType))) {
|
if (UVCoordinatesGenerator.isTextureCoordinateTypeSupported(UVCoordinatesType.valueOf(uvCoordinatesType))) {
|
||||||
TextureData textureData = new TextureData();
|
TextureData textureData = new TextureData();
|
||||||
textureData.texture = texture;
|
textureData.texture = texture;
|
||||||
textureData.textureBlender = textureBlender;
|
textureData.textureBlender = textureBlender;
|
||||||
@ -137,7 +137,7 @@ public class CombinedTexture {
|
|||||||
} else if (textureData.texture instanceof Texture2D) {
|
} else if (textureData.texture instanceof Texture2D) {
|
||||||
resultTexture = textureData.texture;
|
resultTexture = textureData.texture;
|
||||||
|
|
||||||
if(textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
||||||
resultUVS = userDefinedUVCoordinates;
|
resultUVS = userDefinedUVCoordinates;
|
||||||
} else {
|
} else {
|
||||||
List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(geometriesOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(geometriesOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
@ -172,7 +172,7 @@ public class CombinedTexture {
|
|||||||
}
|
}
|
||||||
// first triangulate the current texture
|
// first triangulate the current texture
|
||||||
List<Vector2f> textureUVS = null;
|
List<Vector2f> textureUVS = null;
|
||||||
if(textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
if (textureData.uvCoordinatesType == UVCoordinatesType.TEXCO_UV && userDefinedUVCoordinates != null && userDefinedUVCoordinates.size() > 0) {
|
||||||
textureUVS = userDefinedUVCoordinates;
|
textureUVS = userDefinedUVCoordinates;
|
||||||
} else {
|
} else {
|
||||||
List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(geometriesOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
List<Geometry> geometries = (List<Geometry>) blenderContext.getLoadedFeature(geometriesOMA, LoadedFeatureDataType.LOADED_FEATURE);
|
||||||
@ -188,10 +188,10 @@ public class CombinedTexture {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (resultTexture instanceof TriangulatedTexture) {
|
if (resultTexture instanceof TriangulatedTexture) {
|
||||||
if(mappingType == MaterialContext.MTEX_NOR) {
|
if (mappingType == MaterialContext.MTEX_NOR) {
|
||||||
for(int i=0;i<((TriangulatedTexture) resultTexture).getFaceTextureCount();++i) {
|
for (int i = 0; i < ((TriangulatedTexture) resultTexture).getFaceTextureCount(); ++i) {
|
||||||
TriangleTextureElement triangleTextureElement = ((TriangulatedTexture) resultTexture).getFaceTextureElement(i);
|
TriangleTextureElement triangleTextureElement = ((TriangulatedTexture) resultTexture).getFaceTextureElement(i);
|
||||||
triangleTextureElement.image = textureHelper.convertToNormalMapTexture(triangleTextureElement.image, 1);//TODO: get proper strength factor
|
triangleTextureElement.image = textureHelper.convertToNormalMapTexture(triangleTextureElement.image, 1);// TODO: get proper strength factor
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
resultUVS = ((TriangulatedTexture) resultTexture).getResultUVS();
|
resultUVS = ((TriangulatedTexture) resultTexture).getResultUVS();
|
||||||
@ -272,8 +272,7 @@ public class CombinedTexture {
|
|||||||
targetSize[0] = imageRectangle[2] - imageRectangle[0];
|
targetSize[0] = imageRectangle[2] - imageRectangle[0];
|
||||||
targetSize[1] = imageRectangle[3] - imageRectangle[1];
|
targetSize[1] = imageRectangle[3] - imageRectangle[1];
|
||||||
for (int j = 0; j < 3; ++j) {
|
for (int j = 0; j < 3; ++j) {
|
||||||
partImageUVS.get(j).set((basicUVSOwner.resultTexture.getImage().getWidth() * destinationUVS[j].x - imageRectangle[0]) / targetSize[0],
|
partImageUVS.get(j).set((basicUVSOwner.resultTexture.getImage().getWidth() * destinationUVS[j].x - imageRectangle[0]) / targetSize[0], (basicUVSOwner.resultTexture.getImage().getHeight() * destinationUVS[j].y - imageRectangle[1]) / targetSize[1]);
|
||||||
(basicUVSOwner.resultTexture.getImage().getHeight() * destinationUVS[j].y - imageRectangle[1]) / targetSize[1]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// source size and UVS (translate UVS to (0,0) and stretch it to
|
// source size and UVS (translate UVS to (0,0) and stretch it to
|
||||||
@ -377,9 +376,9 @@ public class CombinedTexture {
|
|||||||
* @return <b>true</b> if the texture has at least one generated texture component and <b>false</b> otherwise
|
* @return <b>true</b> if the texture has at least one generated texture component and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
public boolean hasGeneratedTextures() {
|
public boolean hasGeneratedTextures() {
|
||||||
if(textureDatas != null) {
|
if (textureDatas != null) {
|
||||||
for(TextureData textureData : textureDatas) {
|
for (TextureData textureData : textureDatas) {
|
||||||
if(textureData.texture instanceof GeneratedTexture) {
|
if (textureData.texture instanceof GeneratedTexture) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -397,7 +396,7 @@ public class CombinedTexture {
|
|||||||
* the source texture
|
* the source texture
|
||||||
*/
|
*/
|
||||||
private void merge(Texture2D target, Texture2D source) {
|
private void merge(Texture2D target, Texture2D source) {
|
||||||
if(target.getImage().getDepth() != source.getImage().getDepth()) {
|
if (target.getImage().getDepth() != source.getImage().getDepth()) {
|
||||||
throw new IllegalArgumentException("Cannot merge images with different depths!");
|
throw new IllegalArgumentException("Cannot merge images with different depths!");
|
||||||
}
|
}
|
||||||
Image sourceImage = source.getImage();
|
Image sourceImage = source.getImage();
|
||||||
|
@ -45,7 +45,7 @@ import java.util.logging.Logger;
|
|||||||
*
|
*
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class ImageLoader extends AWTLoader {
|
/* package */class ImageLoader extends AWTLoader {
|
||||||
private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(ImageLoader.class.getName());
|
||||||
|
|
||||||
protected DDSLoader ddsLoader = new DDSLoader(); // DirectX image loader
|
protected DDSLoader ddsLoader = new DDSLoader(); // DirectX image loader
|
||||||
|
@ -143,7 +143,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
if (pImage.isNotNull()) {
|
if (pImage.isNotNull()) {
|
||||||
Structure image = pImage.fetchData(blenderContext.getInputStream()).get(0);
|
Structure image = pImage.fetchData(blenderContext.getInputStream()).get(0);
|
||||||
Texture loadedTexture = this.loadTexture(image, imaflag, blenderContext);
|
Texture loadedTexture = this.loadTexture(image, imaflag, blenderContext);
|
||||||
if(loadedTexture != null) {
|
if (loadedTexture != null) {
|
||||||
result = loadedTexture;
|
result = loadedTexture;
|
||||||
this.applyColorbandAndColorFactors(tex, result.getImage(), blenderContext);
|
this.applyColorbandAndColorFactors(tex, result.getImage(), blenderContext);
|
||||||
}
|
}
|
||||||
@ -176,21 +176,20 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
result.setName(tex.getName());
|
result.setName(tex.getName());
|
||||||
result.setWrap(WrapMode.Repeat);
|
result.setWrap(WrapMode.Repeat);
|
||||||
|
|
||||||
//decide if the mipmaps will be generated
|
// decide if the mipmaps will be generated
|
||||||
switch(blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
|
switch (blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
|
||||||
case ALWAYS_GENERATE:
|
case ALWAYS_GENERATE:
|
||||||
result.setMinFilter(MinFilter.Trilinear);
|
result.setMinFilter(MinFilter.Trilinear);
|
||||||
break;
|
break;
|
||||||
case NEVER_GENERATE:
|
case NEVER_GENERATE:
|
||||||
break;
|
break;
|
||||||
case GENERATE_WHEN_NEEDED:
|
case GENERATE_WHEN_NEEDED:
|
||||||
if((imaflag & 0x04) != 0) {
|
if ((imaflag & 0x04) != 0) {
|
||||||
result.setMinFilter(MinFilter.Trilinear);
|
result.setMinFilter(MinFilter.Trilinear);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown mipmap generation method: " +
|
throw new IllegalStateException("Unknown mipmap generation method: " + blenderContext.getBlenderKey().getMipmapGenerationMethod());
|
||||||
blenderContext.getBlenderKey().getMipmapGenerationMethod());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != TEX_IMAGE) {// only generated textures should have this key
|
if (type != TEX_IMAGE) {// only generated textures should have this key
|
||||||
@ -262,7 +261,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
public Image decompress(Image image) {
|
public Image decompress(Image image) {
|
||||||
Format format = image.getFormat();
|
Format format = image.getFormat();
|
||||||
int depth = image.getDepth();
|
int depth = image.getDepth();
|
||||||
if(depth == 0) {
|
if (depth == 0) {
|
||||||
depth = 1;
|
depth = 1;
|
||||||
}
|
}
|
||||||
ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
|
ArrayList<ByteBuffer> dataArray = new ArrayList<ByteBuffer>(depth);
|
||||||
@ -272,14 +271,14 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
|
for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
|
||||||
ByteBuffer data = image.getData(dataLayerIndex);
|
ByteBuffer data = image.getData(dataLayerIndex);
|
||||||
data.rewind();
|
data.rewind();
|
||||||
if(sizes.length == 1) {
|
if (sizes.length == 1) {
|
||||||
sizes[0] = data.remaining();
|
sizes[0] = data.remaining();
|
||||||
}
|
}
|
||||||
float widthToHeightRatio = image.getWidth() / image.getHeight();//this should always be constant for each mipmap
|
float widthToHeightRatio = image.getWidth() / image.getHeight();// this should always be constant for each mipmap
|
||||||
List<DDSTexelData> texelDataList = new ArrayList<DDSTexelData>(sizes.length);
|
List<DDSTexelData> texelDataList = new ArrayList<DDSTexelData>(sizes.length);
|
||||||
int maxPosition = 0, resultSize = 0;
|
int maxPosition = 0, resultSize = 0;
|
||||||
|
|
||||||
for(int sizeIndex=0;sizeIndex<sizes.length;++sizeIndex) {
|
for (int sizeIndex = 0; sizeIndex < sizes.length; ++sizeIndex) {
|
||||||
maxPosition += sizes[sizeIndex];
|
maxPosition += sizes[sizeIndex];
|
||||||
DDSTexelData texelData = new DDSTexelData(sizes[sizeIndex], widthToHeightRatio, format);
|
DDSTexelData texelData = new DDSTexelData(sizes[sizeIndex], widthToHeightRatio, format);
|
||||||
texelDataList.add(texelData);
|
texelDataList.add(texelData);
|
||||||
@ -409,10 +408,10 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
byte[] bytes = new byte[resultSize];
|
byte[] bytes = new byte[resultSize];
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
byte[] pixelBytes = new byte[4];
|
byte[] pixelBytes = new byte[4];
|
||||||
for(DDSTexelData texelData : texelDataList) {
|
for (DDSTexelData texelData : texelDataList) {
|
||||||
for (int i = 0; i < texelData.getPixelWidth(); ++i) {
|
for (int i = 0; i < texelData.getPixelWidth(); ++i) {
|
||||||
for (int j = 0; j < texelData.getPixelHeight(); ++j) {
|
for (int j = 0; j < texelData.getPixelHeight(); ++j) {
|
||||||
if(texelData.getRGBA8(i, j, pixelBytes)) {
|
if (texelData.getRGBA8(i, j, pixelBytes)) {
|
||||||
bytes[offset + (j * texelData.getPixelWidth() + i) * 4] = pixelBytes[0];
|
bytes[offset + (j * texelData.getPixelWidth() + i) * 4] = pixelBytes[0];
|
||||||
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 1] = pixelBytes[1];
|
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 1] = pixelBytes[1];
|
||||||
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 2] = pixelBytes[2];
|
bytes[offset + (j * texelData.getPixelWidth() + i) * 4 + 2] = pixelBytes[2];
|
||||||
@ -427,9 +426,8 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
dataArray.add(BufferUtils.createByteBuffer(bytes));
|
dataArray.add(BufferUtils.createByteBuffer(bytes));
|
||||||
}
|
}
|
||||||
|
|
||||||
Image result = depth > 1 ? new Image(Format.RGBA8, image.getWidth(), image.getHeight(), depth, dataArray) :
|
Image result = depth > 1 ? new Image(Format.RGBA8, image.getWidth(), image.getHeight(), depth, dataArray) : new Image(Format.RGBA8, image.getWidth(), image.getHeight(), dataArray.get(0));
|
||||||
new Image(Format.RGBA8, image.getWidth(), image.getHeight(), dataArray.get(0));
|
if (newMipmapSizes != null) {
|
||||||
if(newMipmapSizes != null) {
|
|
||||||
result.setMipMapSizes(newMipmapSizes);
|
result.setMipMapSizes(newMipmapSizes);
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
@ -696,9 +694,12 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
* failed load can be reported by the AssetManagers callback methods for
|
* failed load can be reported by the AssetManagers callback methods for
|
||||||
* failed assets.
|
* failed assets.
|
||||||
*
|
*
|
||||||
* @param name the path to the image
|
* @param name
|
||||||
* @param imaflag the image flag
|
* the path to the image
|
||||||
* @param blenderContext the blender context
|
* @param imaflag
|
||||||
|
* the image flag
|
||||||
|
* @param blenderContext
|
||||||
|
* the blender context
|
||||||
* @return the loaded image or null if the image cannot be found
|
* @return the loaded image or null if the image cannot be found
|
||||||
*/
|
*/
|
||||||
protected Texture loadImageFromFile(String name, int imaflag, BlenderContext blenderContext) {
|
protected Texture loadImageFromFile(String name, int imaflag, BlenderContext blenderContext) {
|
||||||
@ -710,9 +711,9 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
return null; // no extension means not a valid image
|
return null; // no extension means not a valid image
|
||||||
}
|
}
|
||||||
|
|
||||||
//decide if the mipmaps will be generated
|
// decide if the mipmaps will be generated
|
||||||
boolean generateMipmaps = false;
|
boolean generateMipmaps = false;
|
||||||
switch(blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
|
switch (blenderContext.getBlenderKey().getMipmapGenerationMethod()) {
|
||||||
case ALWAYS_GENERATE:
|
case ALWAYS_GENERATE:
|
||||||
generateMipmaps = true;
|
generateMipmaps = true;
|
||||||
break;
|
break;
|
||||||
@ -722,8 +723,7 @@ public class TextureHelper extends AbstractBlenderHelper {
|
|||||||
generateMipmaps = (imaflag & 0x04) != 0;
|
generateMipmaps = (imaflag & 0x04) != 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown mipmap generation method: " +
|
throw new IllegalStateException("Unknown mipmap generation method: " + blenderContext.getBlenderKey().getMipmapGenerationMethod());
|
||||||
blenderContext.getBlenderKey().getMipmapGenerationMethod());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
AssetManager assetManager = blenderContext.getAssetManager();
|
AssetManager assetManager = blenderContext.getAssetManager();
|
||||||
|
@ -231,7 +231,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
Integer[] currentPositions = new Integer[] { currentXPos, currentYPos };
|
Integer[] currentPositions = new Integer[] { currentXPos, currentYPos };
|
||||||
imageLayoutData.put(currentElement, currentPositions);
|
imageLayoutData.put(currentElement, currentPositions);
|
||||||
|
|
||||||
if(keepIdenticalTextures) {// removing identical images
|
if (keepIdenticalTextures) {// removing identical images
|
||||||
for (int i = 0; i < list.size(); ++i) {
|
for (int i = 0; i < list.size(); ++i) {
|
||||||
if (currentElement.image.equals(list.get(i).image)) {
|
if (currentElement.image.equals(list.get(i).image)) {
|
||||||
duplicatedFaceIndexes.add(list.get(i).faceIndex);
|
duplicatedFaceIndexes.add(list.get(i).faceIndex);
|
||||||
@ -394,9 +394,7 @@ import com.jme3.util.BufferUtils;
|
|||||||
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
TextureHelper textureHelper = blenderContext.getHelper(TextureHelper.class);
|
||||||
this.faceIndex = faceIndex;
|
this.faceIndex = faceIndex;
|
||||||
|
|
||||||
uv = wholeUVList ?
|
uv = wholeUVList ? new Vector2f[] { uvCoordinates.get(faceIndex * 3).clone(), uvCoordinates.get(faceIndex * 3 + 1).clone(), uvCoordinates.get(faceIndex * 3 + 2).clone() } : new Vector2f[] { uvCoordinates.get(0).clone(), uvCoordinates.get(1).clone(), uvCoordinates.get(2).clone() };
|
||||||
new Vector2f[] { uvCoordinates.get(faceIndex * 3).clone(), uvCoordinates.get(faceIndex * 3 + 1).clone(), uvCoordinates.get(faceIndex * 3 + 2).clone() } :
|
|
||||||
new Vector2f[] { uvCoordinates.get(0).clone(), uvCoordinates.get(1).clone(), uvCoordinates.get(2).clone() };
|
|
||||||
|
|
||||||
// be careful here, floating point operations might cause the
|
// be careful here, floating point operations might cause the
|
||||||
// texture positions to be inapropriate
|
// texture positions to be inapropriate
|
||||||
@ -502,11 +500,11 @@ import com.jme3.util.BufferUtils;
|
|||||||
// create the result image
|
// create the result image
|
||||||
Format imageFormat = texture.getImage().getFormat();
|
Format imageFormat = texture.getImage().getFormat();
|
||||||
int imageWidth = (int) (envelope.width * blenderContext.getBlenderKey().getGeneratedTexturePPU());
|
int imageWidth = (int) (envelope.width * blenderContext.getBlenderKey().getGeneratedTexturePPU());
|
||||||
if(imageWidth == 0) {
|
if (imageWidth == 0) {
|
||||||
imageWidth = 1;
|
imageWidth = 1;
|
||||||
}
|
}
|
||||||
int imageHeight = (int) (envelope.height * blenderContext.getBlenderKey().getGeneratedTexturePPU());
|
int imageHeight = (int) (envelope.height * blenderContext.getBlenderKey().getGeneratedTexturePPU());
|
||||||
if(imageHeight == 0) {
|
if (imageHeight == 0) {
|
||||||
imageHeight = 1;
|
imageHeight = 1;
|
||||||
}
|
}
|
||||||
ByteBuffer data = BufferUtils.createByteBuffer(imageWidth * imageHeight * (imageFormat.getBitsPerPixel() >> 3));
|
ByteBuffer data = BufferUtils.createByteBuffer(imageWidth * imageHeight * (imageFormat.getBitsPerPixel() >> 3));
|
||||||
@ -574,11 +572,11 @@ import com.jme3.util.BufferUtils;
|
|||||||
* the result UV coordinates
|
* the result UV coordinates
|
||||||
*/
|
*/
|
||||||
private void toTextureUV(BoundingBox boundingBox, Vector3f point, float[] uvs) {
|
private void toTextureUV(BoundingBox boundingBox, Vector3f point, float[] uvs) {
|
||||||
uvs[0] = (point.x - boundingBox.getCenter().x)/(boundingBox.getXExtent() == 0 ? 1 : boundingBox.getXExtent());
|
uvs[0] = (point.x - boundingBox.getCenter().x) / (boundingBox.getXExtent() == 0 ? 1 : boundingBox.getXExtent());
|
||||||
uvs[1] = (point.y - boundingBox.getCenter().y)/(boundingBox.getYExtent() == 0 ? 1 : boundingBox.getYExtent());
|
uvs[1] = (point.y - boundingBox.getCenter().y) / (boundingBox.getYExtent() == 0 ? 1 : boundingBox.getYExtent());
|
||||||
uvs[2] = (point.z - boundingBox.getCenter().z)/(boundingBox.getZExtent() == 0 ? 1 : boundingBox.getZExtent());
|
uvs[2] = (point.z - boundingBox.getCenter().z) / (boundingBox.getZExtent() == 0 ? 1 : boundingBox.getZExtent());
|
||||||
//UVS cannot go outside <0, 1> range, but since we are generating texture for triangle envelope it might happen that
|
// UVS cannot go outside <0, 1> range, but since we are generating texture for triangle envelope it might happen that
|
||||||
//some points of the envelope will exceet the bounding box of the mesh thus generating uvs outside the range
|
// some points of the envelope will exceet the bounding box of the mesh thus generating uvs outside the range
|
||||||
for (int i = 0; i < 3; ++i) {
|
for (int i = 0; i < 3; ++i) {
|
||||||
uvs[i] = FastMath.clamp(uvs[i], 0, 1);
|
uvs[i] = FastMath.clamp(uvs[i], 0, 1);
|
||||||
}
|
}
|
||||||
|
@ -55,23 +55,9 @@ public class UVCoordinatesGenerator {
|
|||||||
private static final Logger LOGGER = Logger.getLogger(UVCoordinatesGenerator.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(UVCoordinatesGenerator.class.getName());
|
||||||
|
|
||||||
public static enum UVCoordinatesType {
|
public static enum UVCoordinatesType {
|
||||||
TEXCO_ORCO(1),
|
TEXCO_ORCO(1), TEXCO_REFL(2), TEXCO_NORM(4), TEXCO_GLOB(8), TEXCO_UV(16), TEXCO_OBJECT(32), TEXCO_LAVECTOR(64), TEXCO_VIEW(128), TEXCO_STICKY(256), TEXCO_OSA(512), TEXCO_WINDOW(1024), NEED_UV(2048), TEXCO_TANGENT(4096),
|
||||||
TEXCO_REFL(2),
|
|
||||||
TEXCO_NORM(4),
|
|
||||||
TEXCO_GLOB(8),
|
|
||||||
TEXCO_UV(16),
|
|
||||||
TEXCO_OBJECT(32),
|
|
||||||
TEXCO_LAVECTOR(64),
|
|
||||||
TEXCO_VIEW(128),
|
|
||||||
TEXCO_STICKY(256),
|
|
||||||
TEXCO_OSA(512),
|
|
||||||
TEXCO_WINDOW(1024),
|
|
||||||
NEED_UV(2048),
|
|
||||||
TEXCO_TANGENT(4096),
|
|
||||||
// still stored in vertex->accum, 1 D
|
// still stored in vertex->accum, 1 D
|
||||||
TEXCO_PARTICLE_OR_STRAND(8192),
|
TEXCO_PARTICLE_OR_STRAND(8192), TEXCO_STRESS(16384), TEXCO_SPEED(32768);
|
||||||
TEXCO_STRESS(16384),
|
|
||||||
TEXCO_SPEED(32768);
|
|
||||||
|
|
||||||
public final int blenderValue;
|
public final int blenderValue;
|
||||||
|
|
||||||
|
@ -18,10 +18,7 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public static enum UVProjectionType {
|
public static enum UVProjectionType {
|
||||||
PROJECTION_FLAT(0),
|
PROJECTION_FLAT(0), PROJECTION_CUBE(1), PROJECTION_TUBE(2), PROJECTION_SPHERE(3);
|
||||||
PROJECTION_CUBE(1),
|
|
||||||
PROJECTION_TUBE(2),
|
|
||||||
PROJECTION_SPHERE(3);
|
|
||||||
|
|
||||||
public final int blenderValue;
|
public final int blenderValue;
|
||||||
|
|
||||||
@ -30,8 +27,8 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static UVProjectionType valueOf(int blenderValue) {
|
public static UVProjectionType valueOf(int blenderValue) {
|
||||||
for(UVProjectionType projectionType : UVProjectionType.values()) {
|
for (UVProjectionType projectionType : UVProjectionType.values()) {
|
||||||
if(projectionType.blenderValue == blenderValue) {
|
if (projectionType.blenderValue == blenderValue) {
|
||||||
return projectionType;
|
return projectionType;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -77,9 +74,9 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
Vector3f min = bb.getMin(null);
|
Vector3f min = bb.getMin(null);
|
||||||
float[] ext = new float[] { bb.getXExtent() * 2.0f, bb.getYExtent() * 2.0f, bb.getZExtent() * 2.0f };
|
float[] ext = new float[] { bb.getXExtent() * 2.0f, bb.getYExtent() * 2.0f, bb.getZExtent() * 2.0f };
|
||||||
|
|
||||||
float[] uvCoordinates = new float[positions.length/3*2];
|
float[] uvCoordinates = new float[positions.length / 3 * 2];
|
||||||
float borderAngle = (float) Math.sqrt(2.0f) / 2.0f;
|
float borderAngle = (float) Math.sqrt(2.0f) / 2.0f;
|
||||||
for (int i = 0, pointIndex = 0; i < positions.length; i+=9) {
|
for (int i = 0, pointIndex = 0; i < positions.length; i += 9) {
|
||||||
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
||||||
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
||||||
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
||||||
@ -143,7 +140,7 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
float vBase = bt.getCenter().y - bt.getHeight() * 0.5f;
|
float vBase = bt.getCenter().y - bt.getHeight() * 0.5f;
|
||||||
for (int i = 0, j = 0; i < positions.length; i += 3, j += 2) {
|
for (int i = 0, j = 0; i < positions.length; i += 3, j += 2) {
|
||||||
// calculating U
|
// calculating U
|
||||||
v.set(positions[i]-cx, 0, positions[i + 2]-cz);
|
v.set(positions[i] - cx, 0, positions[i + 2] - cz);
|
||||||
v.normalizeLocal();
|
v.normalizeLocal();
|
||||||
float angle = v.angleBetween(uBase);// result between [0; PI]
|
float angle = v.angleBetween(uBase);// result between [0; PI]
|
||||||
if (v.x < 0) {// the angle should be greater than PI, we're on the other part of the image then
|
if (v.x < 0) {// the angle should be greater than PI, we're on the other part of the image then
|
||||||
@ -156,28 +153,26 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
uvCoordinates[j + 1] = (y - vBase) / bt.getHeight();
|
uvCoordinates[j + 1] = (y - vBase) / bt.getHeight();
|
||||||
}
|
}
|
||||||
|
|
||||||
//looking for splitted triangles
|
// looking for splitted triangles
|
||||||
Triangle triangle = new Triangle();
|
Triangle triangle = new Triangle();
|
||||||
for (int i = 0; i < positions.length; i+=9) {
|
for (int i = 0; i < positions.length; i += 9) {
|
||||||
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
||||||
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
||||||
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
||||||
float sgn1 = Math.signum(triangle.get1().x-cx);
|
float sgn1 = Math.signum(triangle.get1().x - cx);
|
||||||
float sgn2 = Math.signum(triangle.get2().x-cx);
|
float sgn2 = Math.signum(triangle.get2().x - cx);
|
||||||
float sgn3 = Math.signum(triangle.get3().x-cx);
|
float sgn3 = Math.signum(triangle.get3().x - cx);
|
||||||
float xSideFactor = sgn1 + sgn2 + sgn3;
|
float xSideFactor = sgn1 + sgn2 + sgn3;
|
||||||
float ySideFactor = Math.signum(triangle.get1().z-cz)+
|
float ySideFactor = Math.signum(triangle.get1().z - cz) + Math.signum(triangle.get2().z - cz) + Math.signum(triangle.get3().z - cz);
|
||||||
Math.signum(triangle.get2().z-cz)+
|
if ((xSideFactor > -3 || xSideFactor < 3) && ySideFactor < 0) {// the triangle is on the splitting plane
|
||||||
Math.signum(triangle.get3().z-cz);
|
if (sgn1 == 1.0f) {
|
||||||
if((xSideFactor>-3 || xSideFactor<3) && ySideFactor<0) {//the triangle is on the splitting plane
|
uvCoordinates[i / 3 * 2] += 1.0f;
|
||||||
if(sgn1==1.0f) {
|
|
||||||
uvCoordinates[i/3*2] += 1.0f;
|
|
||||||
}
|
}
|
||||||
if(sgn2==1.0f) {
|
if (sgn2 == 1.0f) {
|
||||||
uvCoordinates[(i/3+1)*2] += 1.0f;
|
uvCoordinates[(i / 3 + 1) * 2] += 1.0f;
|
||||||
}
|
}
|
||||||
if(sgn3==1.0f) {
|
if (sgn3 == 1.0f) {
|
||||||
uvCoordinates[(i/3+2)*2] += 1.0f;
|
uvCoordinates[(i / 3 + 2) * 2] += 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -193,7 +188,7 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
* the bounding box for projecting
|
* the bounding box for projecting
|
||||||
* @return UV coordinates after the projection
|
* @return UV coordinates after the projection
|
||||||
*/
|
*/
|
||||||
public static float[] sphereProjection(float[] positions, BoundingSphere bs) {//TODO: rotate it to be vertical
|
public static float[] sphereProjection(float[] positions, BoundingSphere bs) {// TODO: rotate it to be vertical
|
||||||
float[] uvCoordinates = new float[positions.length / 3 * 2];
|
float[] uvCoordinates = new float[positions.length / 3 * 2];
|
||||||
Vector3f v = new Vector3f();
|
Vector3f v = new Vector3f();
|
||||||
float cx = bs.getCenter().x, cy = bs.getCenter().y, cz = bs.getCenter().z;
|
float cx = bs.getCenter().x, cy = bs.getCenter().y, cz = bs.getCenter().z;
|
||||||
@ -202,7 +197,7 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
|
|
||||||
for (int i = 0, j = 0; i < positions.length; i += 3, j += 2) {
|
for (int i = 0, j = 0; i < positions.length; i += 3, j += 2) {
|
||||||
// calculating U
|
// calculating U
|
||||||
v.set(positions[i]-cx, positions[i + 1] - cy, 0);
|
v.set(positions[i] - cx, positions[i + 1] - cy, 0);
|
||||||
v.normalizeLocal();
|
v.normalizeLocal();
|
||||||
float angle = v.angleBetween(uBase);// result between [0; PI]
|
float angle = v.angleBetween(uBase);// result between [0; PI]
|
||||||
if (v.x < 0) {// the angle should be greater than PI, we're on the other part of the image then
|
if (v.x < 0) {// the angle should be greater than PI, we're on the other part of the image then
|
||||||
@ -211,34 +206,32 @@ import com.jme3.scene.plugins.blender.textures.UVCoordinatesGenerator.BoundingTu
|
|||||||
uvCoordinates[j] = angle / FastMath.TWO_PI;
|
uvCoordinates[j] = angle / FastMath.TWO_PI;
|
||||||
|
|
||||||
// calculating V
|
// calculating V
|
||||||
v.set(positions[i]-cx, positions[i + 1]-cy, positions[i + 2]-cz);
|
v.set(positions[i] - cx, positions[i + 1] - cy, positions[i + 2] - cz);
|
||||||
v.normalizeLocal();
|
v.normalizeLocal();
|
||||||
angle = v.angleBetween(vBase);// result between [0; PI]
|
angle = v.angleBetween(vBase);// result between [0; PI]
|
||||||
uvCoordinates[j+1] = angle / FastMath.PI;
|
uvCoordinates[j + 1] = angle / FastMath.PI;
|
||||||
}
|
}
|
||||||
|
|
||||||
//looking for splitted triangles
|
// looking for splitted triangles
|
||||||
Triangle triangle = new Triangle();
|
Triangle triangle = new Triangle();
|
||||||
for (int i = 0; i < positions.length; i+=9) {
|
for (int i = 0; i < positions.length; i += 9) {
|
||||||
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
triangle.set(0, positions[i], positions[i + 1], positions[i + 2]);
|
||||||
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
triangle.set(1, positions[i + 3], positions[i + 4], positions[i + 5]);
|
||||||
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
triangle.set(2, positions[i + 6], positions[i + 7], positions[i + 8]);
|
||||||
float sgn1 = Math.signum(triangle.get1().x-cx);
|
float sgn1 = Math.signum(triangle.get1().x - cx);
|
||||||
float sgn2 = Math.signum(triangle.get2().x-cx);
|
float sgn2 = Math.signum(triangle.get2().x - cx);
|
||||||
float sgn3 = Math.signum(triangle.get3().x-cx);
|
float sgn3 = Math.signum(triangle.get3().x - cx);
|
||||||
float xSideFactor = sgn1 + sgn2 + sgn3;
|
float xSideFactor = sgn1 + sgn2 + sgn3;
|
||||||
float ySideFactor = Math.signum(triangle.get1().y-cy)+
|
float ySideFactor = Math.signum(triangle.get1().y - cy) + Math.signum(triangle.get2().y - cy) + Math.signum(triangle.get3().y - cy);
|
||||||
Math.signum(triangle.get2().y-cy)+
|
if ((xSideFactor > -3 || xSideFactor < 3) && ySideFactor < 0) {// the triangle is on the splitting plane
|
||||||
Math.signum(triangle.get3().y-cy);
|
if (sgn1 == 1.0f) {
|
||||||
if((xSideFactor>-3 || xSideFactor<3) && ySideFactor<0) {//the triangle is on the splitting plane
|
uvCoordinates[i / 3 * 2] += 1.0f;
|
||||||
if(sgn1==1.0f) {
|
|
||||||
uvCoordinates[i/3*2] += 1.0f;
|
|
||||||
}
|
}
|
||||||
if(sgn2==1.0f) {
|
if (sgn2 == 1.0f) {
|
||||||
uvCoordinates[(i/3+1)*2] += 1.0f;
|
uvCoordinates[(i / 3 + 1) * 2] += 1.0f;
|
||||||
}
|
}
|
||||||
if(sgn3==1.0f) {
|
if (sgn3 == 1.0f) {
|
||||||
uvCoordinates[(i/3+2)*2] += 1.0f;
|
uvCoordinates[(i / 3 + 2) * 2] += 1.0f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -102,7 +102,7 @@ import jme3tools.converters.MipMapGenerator;
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void copyBlendingData(TextureBlender textureBlender) {
|
public void copyBlendingData(TextureBlender textureBlender) {
|
||||||
if(textureBlender instanceof AbstractTextureBlender) {
|
if (textureBlender instanceof AbstractTextureBlender) {
|
||||||
this.flag = ((AbstractTextureBlender) textureBlender).flag;
|
this.flag = ((AbstractTextureBlender) textureBlender).flag;
|
||||||
this.negateTexture = ((AbstractTextureBlender) textureBlender).negateTexture;
|
this.negateTexture = ((AbstractTextureBlender) textureBlender).negateTexture;
|
||||||
this.blendType = ((AbstractTextureBlender) textureBlender).blendType;
|
this.blendType = ((AbstractTextureBlender) textureBlender).blendType;
|
||||||
|
@ -43,25 +43,7 @@ import java.nio.ByteBuffer;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class that is responsible for blending the following texture types:
|
* The class that is responsible for blending the following texture types: <li>RGBA8 <li>ABGR8 <li>BGR8 <li>RGB8 Not yet supported (but will be): <li>ARGB4444: <li>RGB10: <li>RGB111110F: <li>RGB16: <li>RGB16F: <li>RGB16F_to_RGB111110F: <li>RGB16F_to_RGB9E5: <li>RGB32F: <li>RGB565: <li>RGB5A1: <li>RGB9E5: <li>RGBA16: <li>RGBA16F
|
||||||
* <li> RGBA8
|
|
||||||
* <li> ABGR8
|
|
||||||
* <li> BGR8
|
|
||||||
* <li> RGB8
|
|
||||||
* Not yet supported (but will be):
|
|
||||||
* <li> ARGB4444:
|
|
||||||
* <li> RGB10:
|
|
||||||
* <li> RGB111110F:
|
|
||||||
* <li> RGB16:
|
|
||||||
* <li> RGB16F:
|
|
||||||
* <li> RGB16F_to_RGB111110F:
|
|
||||||
* <li> RGB16F_to_RGB9E5:
|
|
||||||
* <li> RGB32F:
|
|
||||||
* <li> RGB565:
|
|
||||||
* <li> RGB5A1:
|
|
||||||
* <li> RGB9E5:
|
|
||||||
* <li> RGBA16:
|
|
||||||
* <li> RGBA16F
|
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public class TextureBlenderAWT extends AbstractTextureBlender {
|
public class TextureBlenderAWT extends AbstractTextureBlender {
|
||||||
@ -78,7 +60,7 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
|
|||||||
PixelInputOutput basePixelIO = null, pixelReader = PixelIOFactory.getPixelIO(format);
|
PixelInputOutput basePixelIO = null, pixelReader = PixelIOFactory.getPixelIO(format);
|
||||||
TexturePixel basePixel = null, pixel = new TexturePixel();
|
TexturePixel basePixel = null, pixel = new TexturePixel();
|
||||||
float[] materialColor = this.materialColor;
|
float[] materialColor = this.materialColor;
|
||||||
if(baseImage != null) {
|
if (baseImage != null) {
|
||||||
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
||||||
materialColor = new float[this.materialColor.length];
|
materialColor = new float[this.materialColor.length];
|
||||||
basePixel = new TexturePixel();
|
basePixel = new TexturePixel();
|
||||||
@ -100,13 +82,13 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
|
|||||||
|
|
||||||
int dataIndex = 0, x = 0, y = 0, index = 0;
|
int dataIndex = 0, x = 0, y = 0, index = 0;
|
||||||
while (index < data.limit()) {
|
while (index < data.limit()) {
|
||||||
//getting the proper material color if the base texture is applied
|
// getting the proper material color if the base texture is applied
|
||||||
if(basePixelIO != null) {
|
if (basePixelIO != null) {
|
||||||
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
|
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
|
||||||
basePixel.toRGBA(materialColor);
|
basePixel.toRGBA(materialColor);
|
||||||
}
|
}
|
||||||
|
|
||||||
//reading the current texture's pixel
|
// reading the current texture's pixel
|
||||||
pixelReader.read(image, dataLayerIndex, pixel, index);
|
pixelReader.read(image, dataLayerIndex, pixel, index);
|
||||||
index += image.getFormat().getBitsPerPixel() >> 3;
|
index += image.getFormat().getBitsPerPixel() >> 3;
|
||||||
pixel.toRGBA(pixelColor);
|
pixel.toRGBA(pixelColor);
|
||||||
@ -121,7 +103,7 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
|
|||||||
newData.put(dataIndex++, (byte) (pixelColor[3] * 255.0f));
|
newData.put(dataIndex++, (byte) (pixelColor[3] * 255.0f));
|
||||||
|
|
||||||
++x;
|
++x;
|
||||||
if(x >= width) {
|
if (x >= width) {
|
||||||
x = 0;
|
x = 0;
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
@ -130,7 +112,7 @@ public class TextureBlenderAWT extends AbstractTextureBlender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
|
Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
|
||||||
if(image.getMipMapSizes() != null) {
|
if (image.getMipMapSizes() != null) {
|
||||||
result.setMipMapSizes(image.getMipMapSizes().clone());
|
result.setMipMapSizes(image.getMipMapSizes().clone());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -12,11 +12,7 @@ import java.util.ArrayList;
|
|||||||
import jme3tools.converters.RGB565;
|
import jme3tools.converters.RGB565;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class that is responsible for blending the following texture types:
|
* The class that is responsible for blending the following texture types: <li>DXT1 <li>DXT1A <li>DXT3 <li>DXT5
|
||||||
* <li> DXT1
|
|
||||||
* <li> DXT1A
|
|
||||||
* <li> DXT3
|
|
||||||
* <li> DXT5
|
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public class TextureBlenderDDS extends TextureBlenderAWT {
|
public class TextureBlenderDDS extends TextureBlenderAWT {
|
||||||
@ -40,7 +36,7 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
|||||||
PixelInputOutput basePixelIO = null;
|
PixelInputOutput basePixelIO = null;
|
||||||
float[][] compressedMaterialColor = null;
|
float[][] compressedMaterialColor = null;
|
||||||
TexturePixel[] baseTextureColors = null;
|
TexturePixel[] baseTextureColors = null;
|
||||||
if(baseImage != null) {
|
if (baseImage != null) {
|
||||||
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
||||||
compressedMaterialColor = new float[2][4];
|
compressedMaterialColor = new float[2][4];
|
||||||
baseTextureColors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
baseTextureColors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
||||||
@ -50,28 +46,28 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
|||||||
float[] pixelColor = new float[4];
|
float[] pixelColor = new float[4];
|
||||||
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
TexturePixel[] colors = new TexturePixel[] { new TexturePixel(), new TexturePixel() };
|
||||||
int baseXTexelIndex = 0, baseYTexelIndex = 0;
|
int baseXTexelIndex = 0, baseYTexelIndex = 0;
|
||||||
float[] alphas = new float[] {1, 1};
|
float[] alphas = new float[] { 1, 1 };
|
||||||
for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
|
for (int dataLayerIndex = 0; dataLayerIndex < depth; ++dataLayerIndex) {
|
||||||
ByteBuffer data = image.getData(dataLayerIndex);
|
ByteBuffer data = image.getData(dataLayerIndex);
|
||||||
data.rewind();
|
data.rewind();
|
||||||
ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining());
|
ByteBuffer newData = BufferUtils.createByteBuffer(data.remaining());
|
||||||
while (data.hasRemaining()) {
|
while (data.hasRemaining()) {
|
||||||
if(format == Format.DXT3) {
|
if (format == Format.DXT3) {
|
||||||
long alpha = data.getLong();
|
long alpha = data.getLong();
|
||||||
//get alpha for first and last pixel that is compressed in the texel
|
// get alpha for first and last pixel that is compressed in the texel
|
||||||
byte alpha0 = (byte)(alpha << 4 & 0xFF);
|
byte alpha0 = (byte) (alpha << 4 & 0xFF);
|
||||||
byte alpha1 = (byte)(alpha >> 60 & 0xFF);
|
byte alpha1 = (byte) (alpha >> 60 & 0xFF);
|
||||||
alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
||||||
alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f;
|
alphas[1] = alpha1 >= 0 ? alpha1 / 255.0f : 1.0f - ~alpha1 / 255.0f;
|
||||||
newData.putLong(alpha);
|
newData.putLong(alpha);
|
||||||
} else if(format == Format.DXT5) {
|
} else if (format == Format.DXT5) {
|
||||||
byte alpha0 = data.get();
|
byte alpha0 = data.get();
|
||||||
byte alpha1 = data.get();
|
byte alpha1 = data.get();
|
||||||
alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
alphas[0] = alpha0 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
||||||
alphas[1] = alpha1 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
alphas[1] = alpha1 >= 0 ? alpha0 / 255.0f : 1.0f - ~alpha0 / 255.0f;
|
||||||
newData.put(alpha0);
|
newData.put(alpha0);
|
||||||
newData.put(alpha1);
|
newData.put(alpha1);
|
||||||
//only read the next 6 bytes (these are alpha indexes)
|
// only read the next 6 bytes (these are alpha indexes)
|
||||||
newData.putInt(data.getInt());
|
newData.putInt(data.getInt());
|
||||||
newData.putShort(data.getShort());
|
newData.putShort(data.getShort());
|
||||||
}
|
}
|
||||||
@ -80,11 +76,11 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
|||||||
colors[0].fromARGB8(col0);
|
colors[0].fromARGB8(col0);
|
||||||
colors[1].fromARGB8(col1);
|
colors[1].fromARGB8(col1);
|
||||||
|
|
||||||
//compressing 16 pixels from the base texture as if they belonged to a texel
|
// compressing 16 pixels from the base texture as if they belonged to a texel
|
||||||
if(baseImage != null) {
|
if (baseImage != null) {
|
||||||
//reading pixels (first and last of the 16 colors array)
|
// reading pixels (first and last of the 16 colors array)
|
||||||
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);//first pixel
|
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[0], baseXTexelIndex << 2, baseYTexelIndex << 2);// first pixel
|
||||||
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);//last pixel
|
basePixelIO.read(baseImage, dataLayerIndex, baseTextureColors[1], baseXTexelIndex << 2 + 4, baseYTexelIndex << 2 + 4);// last pixel
|
||||||
baseTextureColors[0].toRGBA(compressedMaterialColor[0]);
|
baseTextureColors[0].toRGBA(compressedMaterialColor[0]);
|
||||||
baseTextureColors[1].toRGBA(compressedMaterialColor[1]);
|
baseTextureColors[1].toRGBA(compressedMaterialColor[1]);
|
||||||
}
|
}
|
||||||
@ -107,7 +103,7 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
|||||||
newData.putInt(data.getInt());
|
newData.putInt(data.getInt());
|
||||||
|
|
||||||
++baseXTexelIndex;
|
++baseXTexelIndex;
|
||||||
if(baseXTexelIndex > image.getWidth() >> 2) {
|
if (baseXTexelIndex > image.getWidth() >> 2) {
|
||||||
baseXTexelIndex = 0;
|
baseXTexelIndex = 0;
|
||||||
++baseYTexelIndex;
|
++baseYTexelIndex;
|
||||||
}
|
}
|
||||||
@ -116,7 +112,7 @@ public class TextureBlenderDDS extends TextureBlenderAWT {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image result = dataArray.size() > 1 ? new Image(format, width, height, depth, dataArray) : new Image(format, width, height, dataArray.get(0));
|
Image result = dataArray.size() > 1 ? new Image(format, width, height, depth, dataArray) : new Image(format, width, height, dataArray.get(0));
|
||||||
if(image.getMipMapSizes() != null) {
|
if (image.getMipMapSizes() != null) {
|
||||||
result.setMipMapSizes(image.getMipMapSizes().clone());
|
result.setMipMapSizes(image.getMipMapSizes().clone());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -14,15 +14,7 @@ import java.util.logging.Level;
|
|||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The class that is responsible for blending the following texture types:
|
* The class that is responsible for blending the following texture types: <li>Luminance8 <li>Luminance8Alpha8 Not yet supported (but will be): <li>Luminance16: <li>Luminance16Alpha16: <li>Luminance16F: <li>Luminance16FAlpha16F: <li>Luminance32F:
|
||||||
* <li> Luminance8
|
|
||||||
* <li> Luminance8Alpha8
|
|
||||||
* Not yet supported (but will be):
|
|
||||||
* <li> Luminance16:
|
|
||||||
* <li> Luminance16Alpha16:
|
|
||||||
* <li> Luminance16F:
|
|
||||||
* <li> Luminance16FAlpha16F:
|
|
||||||
* <li> Luminance32F:
|
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
public class TextureBlenderLuminance extends AbstractTextureBlender {
|
public class TextureBlenderLuminance extends AbstractTextureBlender {
|
||||||
@ -39,7 +31,7 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
|
|||||||
PixelInputOutput basePixelIO = null;
|
PixelInputOutput basePixelIO = null;
|
||||||
TexturePixel basePixel = null;
|
TexturePixel basePixel = null;
|
||||||
float[] materialColor = this.materialColor;
|
float[] materialColor = this.materialColor;
|
||||||
if(baseImage != null) {
|
if (baseImage != null) {
|
||||||
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
basePixelIO = PixelIOFactory.getPixelIO(baseImage.getFormat());
|
||||||
materialColor = new float[this.materialColor.length];
|
materialColor = new float[this.materialColor.length];
|
||||||
basePixel = new TexturePixel();
|
basePixel = new TexturePixel();
|
||||||
@ -62,8 +54,8 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
|
|||||||
|
|
||||||
int dataIndex = 0, x = 0, y = 0;
|
int dataIndex = 0, x = 0, y = 0;
|
||||||
while (data.hasRemaining()) {
|
while (data.hasRemaining()) {
|
||||||
//getting the proper material color if the base texture is applied
|
// getting the proper material color if the base texture is applied
|
||||||
if(basePixelIO != null) {
|
if (basePixelIO != null) {
|
||||||
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
|
basePixelIO.read(baseImage, dataLayerIndex, basePixel, x, y);
|
||||||
basePixel.toRGBA(materialColor);
|
basePixel.toRGBA(materialColor);
|
||||||
}
|
}
|
||||||
@ -76,7 +68,7 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
|
|||||||
newData.put(dataIndex++, (byte) (tinAndAlpha[1] * 255.0f));
|
newData.put(dataIndex++, (byte) (tinAndAlpha[1] * 255.0f));
|
||||||
|
|
||||||
++x;
|
++x;
|
||||||
if(x >= width) {
|
if (x >= width) {
|
||||||
x = 0;
|
x = 0;
|
||||||
++y;
|
++y;
|
||||||
}
|
}
|
||||||
@ -85,7 +77,7 @@ public class TextureBlenderLuminance extends AbstractTextureBlender {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
|
Image result = depth > 1 ? new Image(Format.RGBA8, width, height, depth, dataArray) : new Image(Format.RGBA8, width, height, dataArray.get(0));
|
||||||
if(image.getMipMapSizes() != null) {
|
if (image.getMipMapSizes() != null) {
|
||||||
result.setMipMapSizes(image.getMipMapSizes().clone());
|
result.setMipMapSizes(image.getMipMapSizes().clone());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
@ -51,7 +51,7 @@ import java.util.logging.Logger;
|
|||||||
* It is only used by TextureHelper.
|
* It is only used by TextureHelper.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class NoiseGenerator extends AbstractBlenderHelper {
|
/* package */class NoiseGenerator extends AbstractBlenderHelper {
|
||||||
private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());
|
private static final Logger LOGGER = Logger.getLogger(NoiseGenerator.class.getName());
|
||||||
|
|
||||||
// tex->stype
|
// tex->stype
|
||||||
@ -531,7 +531,7 @@ import java.util.logging.Logger;
|
|||||||
int xi = (int) FastMath.floor(x);
|
int xi = (int) FastMath.floor(x);
|
||||||
int yi = (int) FastMath.floor(y);
|
int yi = (int) FastMath.floor(y);
|
||||||
int zi = (int) FastMath.floor(z);
|
int zi = (int) FastMath.floor(z);
|
||||||
da[0] = da[1] = da[2] = da[3] = Float.MAX_VALUE;//1e10f;
|
da[0] = da[1] = da[2] = da[3] = Float.MAX_VALUE;// 1e10f;
|
||||||
for (int i = xi - 1; i <= xi + 1; ++i) {
|
for (int i = xi - 1; i <= xi + 1; ++i) {
|
||||||
for (int j = yi - 1; j <= yi + 1; ++j) {
|
for (int j = yi - 1; j <= yi + 1; ++j) {
|
||||||
for (int k = zi - 1; k <= zi + 1; ++k) {
|
for (int k = zi - 1; k <= zi + 1; ++k) {
|
||||||
@ -598,7 +598,7 @@ import java.util.logging.Logger;
|
|||||||
x -= floorX;
|
x -= floorX;
|
||||||
y -= floorY;
|
y -= floorY;
|
||||||
z -= floorZ;
|
z -= floorZ;
|
||||||
//computing fading curves
|
// computing fading curves
|
||||||
floorX = NoiseMath.npfade(x);
|
floorX = NoiseMath.npfade(x);
|
||||||
floorY = NoiseMath.npfade(y);
|
floorY = NoiseMath.npfade(y);
|
||||||
floorZ = NoiseMath.npfade(z);
|
floorZ = NoiseMath.npfade(z);
|
||||||
@ -608,14 +608,8 @@ import java.util.logging.Logger;
|
|||||||
B = hash[intX + 1] + intY;
|
B = hash[intX + 1] + intY;
|
||||||
BA = hash[B] + intZ;
|
BA = hash[B] + intZ;
|
||||||
BB = hash[B + 1] + intZ;
|
BB = hash[B + 1] + intZ;
|
||||||
return NoiseMath.lerp(floorZ, NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA], x, y, z),
|
return NoiseMath.lerp(floorZ, NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA], x, y, z), NoiseMath.grad(hash[BA], x - 1, y, z)), NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB], x, y - 1, z), NoiseMath.grad(hash[BB], x - 1, y - 1, z))),
|
||||||
NoiseMath.grad(hash[BA], x - 1, y, z)),
|
NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA + 1], x, y, z - 1), NoiseMath.grad(hash[BA + 1], x - 1, y, z - 1)), NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB + 1], x, y - 1, z - 1), NoiseMath.grad(hash[BB + 1], x - 1, y - 1, z - 1))));
|
||||||
NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB], x, y - 1, z),
|
|
||||||
NoiseMath.grad(hash[BB], x - 1, y - 1, z))),
|
|
||||||
NoiseMath.lerp(floorY, NoiseMath.lerp(floorX, NoiseMath.grad(hash[AA + 1], x, y, z - 1),
|
|
||||||
NoiseMath.grad(hash[BA + 1], x - 1, y, z - 1)),
|
|
||||||
NoiseMath.lerp(floorX, NoiseMath.grad(hash[AB + 1], x, y - 1, z - 1),
|
|
||||||
NoiseMath.grad(hash[BB + 1], x - 1, y - 1, z - 1))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static float noise3Perlin(float x, float y, float z) {
|
public static float noise3Perlin(float x, float y, float z) {
|
||||||
@ -707,23 +701,22 @@ import java.util.logging.Logger;
|
|||||||
cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;
|
cn4 = 1.0f - 3.0f * cn4 - 2.0f * cn4 * jx;
|
||||||
cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
|
cn5 = 1.0f - 3.0f * cn5 - 2.0f * cn5 * jy;
|
||||||
cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
|
cn6 = 1.0f - 3.0f * cn6 - 2.0f * cn6 * jz;
|
||||||
float[] cn = new float[] {cn1 * cn2 * cn3, cn1 * cn2 * cn6, cn1 * cn5 * cn3, cn1 * cn5 * cn6,
|
float[] cn = new float[] { cn1 * cn2 * cn3, cn1 * cn2 * cn6, cn1 * cn5 * cn3, cn1 * cn5 * cn6, cn4 * cn2 * cn3, cn4 * cn2 * cn6, cn4 * cn5 * cn3, cn4 * cn5 * cn6, };
|
||||||
cn4 * cn2 * cn3, cn4 * cn2 * cn6, cn4 * cn5 * cn3, cn4 * cn5 * cn6,};
|
|
||||||
|
|
||||||
int b00 = hash[hash[ix & 0xFF] + (iy & 0xFF)];
|
int b00 = hash[hash[ix & 0xFF] + (iy & 0xFF)];
|
||||||
int b01 = hash[hash[ix & 0xFF] + (iy + 1 & 0xFF)];
|
int b01 = hash[hash[ix & 0xFF] + (iy + 1 & 0xFF)];
|
||||||
int b10 = hash[hash[ix + 1 & 0xFF] + (iy & 0xFF)];
|
int b10 = hash[hash[ix + 1 & 0xFF] + (iy & 0xFF)];
|
||||||
int b11 = hash[hash[ix + 1 & 0xFF] + (iy + 1 & 0xFF)];
|
int b11 = hash[hash[ix + 1 & 0xFF] + (iy + 1 & 0xFF)];
|
||||||
int[] b1 = new int[] {b00, b00, b01, b01, b10, b10, b11, b11};
|
int[] b1 = new int[] { b00, b00, b01, b01, b10, b10, b11, b11 };
|
||||||
|
|
||||||
int[] b2 = new int[] {iz & 0xFF, iz + 1 & 0xFF};
|
int[] b2 = new int[] { iz & 0xFF, iz + 1 & 0xFF };
|
||||||
|
|
||||||
float[] xFactor = new float[] {ox, ox, ox, ox, jx, jx, jx, jx};
|
float[] xFactor = new float[] { ox, ox, ox, ox, jx, jx, jx, jx };
|
||||||
float[] yFactor = new float[] {oy, oy, jy, jy, oy, oy, jy, jy};
|
float[] yFactor = new float[] { oy, oy, jy, jy, oy, oy, jy, jy };
|
||||||
float[] zFactor = new float[] {oz, jz, oz, jz, oz, jz, oz, jz};
|
float[] zFactor = new float[] { oz, jz, oz, jz, oz, jz, oz, jz };
|
||||||
|
|
||||||
for(int i=0;i<8;++i) {
|
for (int i = 0; i < 8; ++i) {
|
||||||
int hIndex = 3 * hash[b1[i] + b2[i%2]];
|
int hIndex = 3 * hash[b1[i] + b2[i % 2]];
|
||||||
n += cn[i] * (hashvectf[hIndex] * xFactor[i] + hashvectf[hIndex + 1] * yFactor[i] + hashvectf[hIndex + 2] * zFactor[i]);
|
n += cn[i] * (hashvectf[hIndex] * xFactor[i] + hashvectf[hIndex + 1] * yFactor[i] + hashvectf[hIndex + 2] * zFactor[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,7 +61,7 @@ public abstract class TextureGenerator {
|
|||||||
flag = ((Number) tex.getFieldValue("flag")).intValue();
|
flag = ((Number) tex.getFieldValue("flag")).intValue();
|
||||||
colorBand = new ColorBand(tex, blenderContext).computeValues();
|
colorBand = new ColorBand(tex, blenderContext).computeValues();
|
||||||
bacd = new BrightnessAndContrastData(tex);
|
bacd = new BrightnessAndContrastData(tex);
|
||||||
if(colorBand != null) {
|
if (colorBand != null) {
|
||||||
imageFormat = Format.RGBA8;
|
imageFormat = Format.RGBA8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,7 +70,8 @@ public abstract class TextureGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* This method applies brightness and contrast for RGB textures.
|
* This method applies brightness and contrast for RGB textures.
|
||||||
* @param tex texture structure
|
* @param tex
|
||||||
|
* texture structure
|
||||||
* @param texres
|
* @param texres
|
||||||
*/
|
*/
|
||||||
protected void applyBrightnessAndContrast(BrightnessAndContrastData bacd, TexturePixel texres) {
|
protected void applyBrightnessAndContrast(BrightnessAndContrastData bacd, TexturePixel texres) {
|
||||||
@ -78,7 +79,7 @@ public abstract class TextureGenerator {
|
|||||||
if (texres.red < 0.0f) {
|
if (texres.red < 0.0f) {
|
||||||
texres.red = 0.0f;
|
texres.red = 0.0f;
|
||||||
}
|
}
|
||||||
texres.green =(texres.green - 0.5f) * bacd.contrast + bacd.brightness;
|
texres.green = (texres.green - 0.5f) * bacd.contrast + bacd.brightness;
|
||||||
if (texres.green < 0.0f) {
|
if (texres.green < 0.0f) {
|
||||||
texres.green = 0.0f;
|
texres.green = 0.0f;
|
||||||
}
|
}
|
||||||
@ -116,7 +117,8 @@ public abstract class TextureGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor reads the required data from the given structure.
|
* Constructor reads the required data from the given structure.
|
||||||
* @param tex texture structure
|
* @param tex
|
||||||
|
* texture structure
|
||||||
*/
|
*/
|
||||||
public BrightnessAndContrastData(Structure tex) {
|
public BrightnessAndContrastData(Structure tex) {
|
||||||
contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
|
contrast = ((Number) tex.getFieldValue("contrast")).floatValue();
|
||||||
|
@ -45,18 +45,18 @@ public final class TextureGeneratorBlend extends TextureGenerator {
|
|||||||
|
|
||||||
private static final IntensityFunction INTENSITY_FUNCTION[] = new IntensityFunction[7];
|
private static final IntensityFunction INTENSITY_FUNCTION[] = new IntensityFunction[7];
|
||||||
static {
|
static {
|
||||||
INTENSITY_FUNCTION[0] = new IntensityFunction() {//Linear: stype = 0 (TEX_LIN)
|
INTENSITY_FUNCTION[0] = new IntensityFunction() {// Linear: stype = 0 (TEX_LIN)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
return (1.0f + x) * 0.5f;
|
return (1.0f + x) * 0.5f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[1] = new IntensityFunction() {//Quad: stype = 1 (TEX_QUAD)
|
INTENSITY_FUNCTION[1] = new IntensityFunction() {// Quad: stype = 1 (TEX_QUAD)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
float result = (1.0f + x) * 0.5f;
|
float result = (1.0f + x) * 0.5f;
|
||||||
return result * result;
|
return result * result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[2] = new IntensityFunction() {//Ease: stype = 2 (TEX_EASE)
|
INTENSITY_FUNCTION[2] = new IntensityFunction() {// Ease: stype = 2 (TEX_EASE)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
float result = (1.0f + x) * 0.5f;
|
float result = (1.0f + x) * 0.5f;
|
||||||
if (result <= 0.0f) {
|
if (result <= 0.0f) {
|
||||||
@ -64,28 +64,28 @@ public final class TextureGeneratorBlend extends TextureGenerator {
|
|||||||
} else if (result >= 1.0f) {
|
} else if (result >= 1.0f) {
|
||||||
return 1.0f;
|
return 1.0f;
|
||||||
} else {
|
} else {
|
||||||
return result * result *(3.0f - 2.0f * result);
|
return result * result * (3.0f - 2.0f * result);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[3] = new IntensityFunction() {//Diagonal: stype = 3 (TEX_DIAG)
|
INTENSITY_FUNCTION[3] = new IntensityFunction() {// Diagonal: stype = 3 (TEX_DIAG)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
return (2.0f + x + y) * 0.25f;
|
return (2.0f + x + y) * 0.25f;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[4] = new IntensityFunction() {//Sphere: stype = 4 (TEX_SPHERE)
|
INTENSITY_FUNCTION[4] = new IntensityFunction() {// Sphere: stype = 4 (TEX_SPHERE)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
|
float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
|
||||||
return result < 0.0f ? 0.0f : result;
|
return result < 0.0f ? 0.0f : result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[5] = new IntensityFunction() {//Halo: stype = 5 (TEX_HALO)
|
INTENSITY_FUNCTION[5] = new IntensityFunction() {// Halo: stype = 5 (TEX_HALO)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
|
float result = 1.0f - (float) Math.sqrt(x * x + y * y + z * z);
|
||||||
return result <= 0.0f ? 0.0f : result * result;
|
return result <= 0.0f ? 0.0f : result * result;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
INTENSITY_FUNCTION[6] = new IntensityFunction() {//Radial: stype = 6 (TEX_RAD)
|
INTENSITY_FUNCTION[6] = new IntensityFunction() {// Radial: stype = 6 (TEX_RAD)
|
||||||
public float getIntensity(float x, float y, float z) {
|
public float getIntensity(float x, float y, float z) {
|
||||||
return (float) Math.atan2(y, x) * FastMath.INV_TWO_PI + 0.5f;
|
return (float) Math.atan2(y, x) * FastMath.INV_TWO_PI + 0.5f;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ public class TextureGeneratorClouds extends TextureGenerator {
|
|||||||
noiseType = ((Number) tex.getFieldValue("noisetype")).intValue();
|
noiseType = ((Number) tex.getFieldValue("noisetype")).intValue();
|
||||||
isHard = noiseType != TEX_NOISESOFT;
|
isHard = noiseType != TEX_NOISESOFT;
|
||||||
sType = ((Number) tex.getFieldValue("stype")).intValue();
|
sType = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
if(sType == TEX_COLOR) {
|
if (sType == TEX_COLOR) {
|
||||||
this.imageFormat = Format.RGBA8;
|
this.imageFormat = Format.RGBA8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,6 +106,6 @@ public class TextureGeneratorDistnoise extends TextureGenerator {
|
|||||||
float rx = abstractNoiseFunc1.execute(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;
|
float rx = abstractNoiseFunc1.execute(x + 13.5f, y + 13.5f, z + 13.5f) * distortion;
|
||||||
float ry = abstractNoiseFunc1.execute(x, y, z) * distortion;
|
float ry = abstractNoiseFunc1.execute(x, y, z) * distortion;
|
||||||
float rz = abstractNoiseFunc1.execute(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;
|
float rz = abstractNoiseFunc1.execute(x - 13.5f, y - 13.5f, z - 13.5f) * distortion;
|
||||||
return abstractNoiseFunc2.executeSigned(x + rx, y + ry, z + rz); //distorted-domain noise
|
return abstractNoiseFunc2.executeSigned(x + rx, y + ry, z + rz); // distorted-domain noise
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,7 @@ public class TextureGeneratorFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TextureGenerator createTextureGenerator(int generatedTexture) {
|
public TextureGenerator createTextureGenerator(int generatedTexture) {
|
||||||
switch(generatedTexture) {
|
switch (generatedTexture) {
|
||||||
case TextureHelper.TEX_BLEND:
|
case TextureHelper.TEX_BLEND:
|
||||||
return new TextureGeneratorBlend(noiseGenerator);
|
return new TextureGeneratorBlend(noiseGenerator);
|
||||||
case TextureHelper.TEX_CLOUDS:
|
case TextureHelper.TEX_CLOUDS:
|
||||||
|
@ -135,7 +135,7 @@ public class TextureGeneratorMagic extends TextureGenerator {
|
|||||||
xyz[0] *= turb;
|
xyz[0] *= turb;
|
||||||
xyz[1] *= turb;
|
xyz[1] *= turb;
|
||||||
xyz[2] *= turb;
|
xyz[2] *= turb;
|
||||||
for (int m=0;m<noisedepth;++m) {
|
for (int m = 0; m < noisedepth; ++m) {
|
||||||
noiseDepthFunctions[m].compute(xyz, turb);
|
noiseDepthFunctions[m].compute(xyz, turb);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,7 +63,7 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
|
|||||||
stype = ((Number) tex.getFieldValue("stype")).intValue();
|
stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
noisesize = ((Number) tex.getFieldValue("noisesize")).floatValue();
|
||||||
musgraveFunction = NoiseGenerator.musgraveFunctions.get(Integer.valueOf(musgraveData.stype));
|
musgraveFunction = NoiseGenerator.musgraveFunctions.get(Integer.valueOf(musgraveData.stype));
|
||||||
if(musgraveFunction==null) {
|
if (musgraveFunction == null) {
|
||||||
throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
|
throw new IllegalStateException("Unknown type of musgrave texture: " + stype);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,9 +71,9 @@ public class TextureGeneratorMusgrave extends TextureGenerator {
|
|||||||
@Override
|
@Override
|
||||||
public void getPixel(TexturePixel pixel, float x, float y, float z) {
|
public void getPixel(TexturePixel pixel, float x, float y, float z) {
|
||||||
pixel.intensity = musgraveData.outscale * musgraveFunction.execute(musgraveData, x, y, z);
|
pixel.intensity = musgraveData.outscale * musgraveFunction.execute(musgraveData, x, y, z);
|
||||||
if(pixel.intensity>1) {
|
if (pixel.intensity > 1) {
|
||||||
pixel.intensity = 1.0f;
|
pixel.intensity = 1.0f;
|
||||||
} else if(pixel.intensity < 0) {
|
} else if (pixel.intensity < 0) {
|
||||||
pixel.intensity = 0.0f;
|
pixel.intensity = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,7 +68,7 @@ public class TextureGeneratorStucci extends TextureGenerator {
|
|||||||
turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
|
turbul = ((Number) tex.getFieldValue("turbul")).floatValue();
|
||||||
isHard = noisetype != TEX_NOISESOFT;
|
isHard = noisetype != TEX_NOISESOFT;
|
||||||
stype = ((Number) tex.getFieldValue("stype")).intValue();
|
stype = ((Number) tex.getFieldValue("stype")).intValue();
|
||||||
if(noisesize<=0.001f) {//the texture goes black if this value is lower than 0.001f
|
if (noisesize <= 0.001f) {// the texture goes black if this value is lower than 0.001f
|
||||||
noisesize = 0.001f;
|
noisesize = 0.001f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -96,6 +96,6 @@ public class TextureGeneratorStucci extends TextureGenerator {
|
|||||||
if (pixel.intensity < 0.0f) {
|
if (pixel.intensity < 0.0f) {
|
||||||
pixel.intensity = 0.0f;
|
pixel.intensity = 0.0f;
|
||||||
}
|
}
|
||||||
//no brightness and contrast needed for stucci (it doesn't affect the texture)
|
// no brightness and contrast needed for stucci (it doesn't affect the texture)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -80,23 +80,23 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
|
|||||||
if (weightSum != 0.0f) {
|
if (weightSum != 0.0f) {
|
||||||
weightSum = outscale / weightSum;
|
weightSum = outscale / weightSum;
|
||||||
}
|
}
|
||||||
if(voronoiColorType != 0 || colorBand != null) {
|
if (voronoiColorType != 0 || colorBand != null) {
|
||||||
this.imageFormat = Format.RGBA8;
|
this.imageFormat = Format.RGBA8;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void getPixel(TexturePixel pixel, float x, float y, float z) {
|
public void getPixel(TexturePixel pixel, float x, float y, float z) {
|
||||||
//for voronoi we need to widen the range a little
|
// for voronoi we need to widen the range a little
|
||||||
NoiseGenerator.NoiseFunctions.voronoi(x * 4, y * 4, z * 4, da, pa, mexp, distanceType);
|
NoiseGenerator.NoiseFunctions.voronoi(x * 4, y * 4, z * 4, da, pa, mexp, distanceType);
|
||||||
pixel.intensity = weightSum * FastMath.abs(voronoiWeights[0] * da[0] + voronoiWeights[1] * da[1] + voronoiWeights[2] * da[2] + voronoiWeights[3] * da[3]);
|
pixel.intensity = weightSum * FastMath.abs(voronoiWeights[0] * da[0] + voronoiWeights[1] * da[1] + voronoiWeights[2] * da[2] + voronoiWeights[3] * da[3]);
|
||||||
if(pixel.intensity>1.0f) {
|
if (pixel.intensity > 1.0f) {
|
||||||
pixel.intensity = 1.0f;
|
pixel.intensity = 1.0f;
|
||||||
} else if(pixel.intensity<0.0f) {
|
} else if (pixel.intensity < 0.0f) {
|
||||||
pixel.intensity = 0.0f;
|
pixel.intensity = 0.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (colorBand != null) {//colorband ALWAYS goes first and covers the color (if set)
|
if (colorBand != null) {// colorband ALWAYS goes first and covers the color (if set)
|
||||||
int colorbandIndex = (int) (pixel.intensity * 1000.0f);
|
int colorbandIndex = (int) (pixel.intensity * 1000.0f);
|
||||||
pixel.red = colorBand[colorbandIndex][0];
|
pixel.red = colorBand[colorbandIndex][0];
|
||||||
pixel.green = colorBand[colorbandIndex][1];
|
pixel.green = colorBand[colorbandIndex][1];
|
||||||
@ -105,9 +105,9 @@ public class TextureGeneratorVoronoi extends TextureGenerator {
|
|||||||
} else if (voronoiColorType != 0) {
|
} else if (voronoiColorType != 0) {
|
||||||
pixel.red = pixel.green = pixel.blue = 0.0f;
|
pixel.red = pixel.green = pixel.blue = 0.0f;
|
||||||
pixel.alpha = 1.0f;
|
pixel.alpha = 1.0f;
|
||||||
for(int m=0; m<12; m+=3) {
|
for (int m = 0; m < 12; m += 3) {
|
||||||
float weight = voronoiWeights[m/3];
|
float weight = voronoiWeights[m / 3];
|
||||||
NoiseMath.hash((int)pa[m], (int)pa[m + 1], (int)pa[m + 2], hashPoint);
|
NoiseMath.hash((int) pa[m], (int) pa[m + 1], (int) pa[m + 2], hashPoint);
|
||||||
pixel.red += weight * hashPoint[0];
|
pixel.red += weight * hashPoint[0];
|
||||||
pixel.green += weight * hashPoint[1];
|
pixel.green += weight * hashPoint[1];
|
||||||
pixel.blue += weight * hashPoint[2];
|
pixel.blue += weight * hashPoint[2];
|
||||||
|
@ -60,7 +60,8 @@ public class TextureGeneratorWood extends TextureGenerator {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor stores the given noise generator.
|
* Constructor stores the given noise generator.
|
||||||
* @param noiseGenerator the noise generator
|
* @param noiseGenerator
|
||||||
|
* the noise generator
|
||||||
*/
|
*/
|
||||||
public TextureGeneratorWood(NoiseGenerator noiseGenerator) {
|
public TextureGeneratorWood(NoiseGenerator noiseGenerator) {
|
||||||
super(noiseGenerator, Format.Luminance8);
|
super(noiseGenerator, Format.Luminance8);
|
||||||
@ -119,15 +120,18 @@ public class TextureGeneratorWood extends TextureGenerator {
|
|||||||
/**
|
/**
|
||||||
* Computes basic wood intensity value at x,y,z.
|
* Computes basic wood intensity value at x,y,z.
|
||||||
* @param woodIntData
|
* @param woodIntData
|
||||||
* @param x X coordinate of the texture pixel
|
* @param x
|
||||||
* @param y Y coordinate of the texture pixel
|
* X coordinate of the texture pixel
|
||||||
* @param z Z coordinate of the texture pixel
|
* @param y
|
||||||
|
* Y coordinate of the texture pixel
|
||||||
|
* @param z
|
||||||
|
* Z coordinate of the texture pixel
|
||||||
* @return wood intensity at position [x, y, z]
|
* @return wood intensity at position [x, y, z]
|
||||||
*/
|
*/
|
||||||
public float woodIntensity(WoodIntensityData woodIntData, float x, float y, float z) {
|
public float woodIntensity(WoodIntensityData woodIntData, float x, float y, float z) {
|
||||||
float result;
|
float result;
|
||||||
|
|
||||||
switch(woodIntData.woodType) {
|
switch (woodIntData.woodType) {
|
||||||
case TEX_BAND:
|
case TEX_BAND:
|
||||||
result = woodIntData.waveformFunction.execute((x + y + z) * 10.0f);
|
result = woodIntData.waveformFunction.execute((x + y + z) * 10.0f);
|
||||||
break;
|
break;
|
||||||
@ -162,7 +166,7 @@ public class TextureGeneratorWood extends TextureGenerator {
|
|||||||
public final boolean isHard;
|
public final boolean isHard;
|
||||||
|
|
||||||
public WoodIntensityData(Structure tex) {
|
public WoodIntensityData(Structure tex) {
|
||||||
int waveform = ((Number) tex.getFieldValue("noisebasis2")).intValue();//wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2
|
int waveform = ((Number) tex.getFieldValue("noisebasis2")).intValue();// wave form: TEX_SIN=0, TEX_SAW=1, TEX_TRI=2
|
||||||
if (waveform > TEX_TRI || waveform < TEX_SIN) {
|
if (waveform > TEX_TRI || waveform < TEX_SIN) {
|
||||||
waveform = 0; // check to be sure noisebasis2 is initialized ahead of time
|
waveform = 0; // check to be sure noisebasis2 is initialized ahead of time
|
||||||
}
|
}
|
||||||
|
@ -10,10 +10,10 @@ import jme3tools.converters.RGB565;
|
|||||||
* Implemens read/write operations for AWT images.
|
* Implemens read/write operations for AWT images.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class AWTPixelInputOutput implements PixelInputOutput {
|
/* package */class AWTPixelInputOutput implements PixelInputOutput {
|
||||||
public void read(Image image, int layer, TexturePixel pixel, int index) {
|
public void read(Image image, int layer, TexturePixel pixel, int index) {
|
||||||
ByteBuffer data = image.getData(layer);
|
ByteBuffer data = image.getData(layer);
|
||||||
switch(image.getFormat()) {
|
switch (image.getFormat()) {
|
||||||
case RGBA8:
|
case RGBA8:
|
||||||
pixel.fromARGB8(data.get(index + 3), data.get(index), data.get(index + 1), data.get(index + 2));
|
pixel.fromARGB8(data.get(index + 3), data.get(index), data.get(index + 1), data.get(index + 2));
|
||||||
break;
|
break;
|
||||||
@ -21,10 +21,10 @@ import jme3tools.converters.RGB565;
|
|||||||
pixel.fromARGB8(data.get(index), data.get(index + 3), data.get(index + 2), data.get(index + 1));
|
pixel.fromARGB8(data.get(index), data.get(index + 3), data.get(index + 2), data.get(index + 1));
|
||||||
break;
|
break;
|
||||||
case BGR8:
|
case BGR8:
|
||||||
pixel.fromARGB8((byte)0xFF, data.get(index + 2), data.get(index + 1), data.get(index));
|
pixel.fromARGB8((byte) 0xFF, data.get(index + 2), data.get(index + 1), data.get(index));
|
||||||
break;
|
break;
|
||||||
case RGB8:
|
case RGB8:
|
||||||
pixel.fromARGB8((byte)0xFF, data.get(index), data.get(index + 1), data.get(index + 2));
|
pixel.fromARGB8((byte) 0xFF, data.get(index), data.get(index + 1), data.get(index + 2));
|
||||||
break;
|
break;
|
||||||
case RGB565:
|
case RGB565:
|
||||||
pixel.fromARGB8(RGB565.RGB565_to_ARGB8(data.getShort(index)));
|
pixel.fromARGB8(RGB565.RGB565_to_ARGB8(data.getShort(index)));
|
||||||
@ -35,10 +35,10 @@ import jme3tools.converters.RGB565;
|
|||||||
int r = (rgb5a1 & 0xf800) >> 11 << 3;
|
int r = (rgb5a1 & 0xf800) >> 11 << 3;
|
||||||
int g = (rgb5a1 & 0x07c0) >> 6 << 3;
|
int g = (rgb5a1 & 0x07c0) >> 6 << 3;
|
||||||
int b = (rgb5a1 & 0x001f) >> 1 << 3;
|
int b = (rgb5a1 & 0x001f) >> 1 << 3;
|
||||||
pixel.fromARGB8(a == 1 ? (byte)255 : 0, (byte)r, (byte)g, (byte)b);
|
pixel.fromARGB8(a == 1 ? (byte) 255 : 0, (byte) r, (byte) g, (byte) b);
|
||||||
break;
|
break;
|
||||||
case RGB16:
|
case RGB16:
|
||||||
pixel.fromARGB16((short)0xFFFF, data.getShort(index), data.getShort(index + 2), data.getShort(index + 4));
|
pixel.fromARGB16((short) 0xFFFF, data.getShort(index), data.getShort(index + 2), data.getShort(index + 4));
|
||||||
break;
|
break;
|
||||||
case RGBA16:
|
case RGBA16:
|
||||||
pixel.fromARGB16(data.getShort(index + 6), data.getShort(index), data.getShort(index + 2), data.getShort(index + 4));
|
pixel.fromARGB16(data.getShort(index + 6), data.getShort(index), data.getShort(index + 2), data.getShort(index + 4));
|
||||||
@ -46,25 +46,19 @@ import jme3tools.converters.RGB565;
|
|||||||
case RGB16F:
|
case RGB16F:
|
||||||
case RGB16F_to_RGB111110F:
|
case RGB16F_to_RGB111110F:
|
||||||
case RGB16F_to_RGB9E5:
|
case RGB16F_to_RGB9E5:
|
||||||
pixel.fromARGB(1, FastMath.convertHalfToFloat(data.getShort(index)),
|
pixel.fromARGB(1, FastMath.convertHalfToFloat(data.getShort(index)), FastMath.convertHalfToFloat(data.getShort(index + 2)), FastMath.convertHalfToFloat(data.getShort(index + 4)));
|
||||||
FastMath.convertHalfToFloat(data.getShort(index + 2)),
|
|
||||||
FastMath.convertHalfToFloat(data.getShort(index + 4)));
|
|
||||||
break;
|
break;
|
||||||
case RGBA16F:
|
case RGBA16F:
|
||||||
pixel.fromARGB(FastMath.convertHalfToFloat(data.getShort(index + 6)), FastMath.convertHalfToFloat(data.getShort(index)),
|
pixel.fromARGB(FastMath.convertHalfToFloat(data.getShort(index + 6)), FastMath.convertHalfToFloat(data.getShort(index)), FastMath.convertHalfToFloat(data.getShort(index + 2)), FastMath.convertHalfToFloat(data.getShort(index + 4)));
|
||||||
FastMath.convertHalfToFloat(data.getShort(index + 2)), FastMath.convertHalfToFloat(data.getShort(index + 4)));
|
|
||||||
break;
|
break;
|
||||||
case RGBA32F:
|
case RGBA32F:
|
||||||
pixel.fromARGB(Float.intBitsToFloat(data.getInt(index + 12)), Float.intBitsToFloat(data.getInt(index)),
|
pixel.fromARGB(Float.intBitsToFloat(data.getInt(index + 12)), Float.intBitsToFloat(data.getInt(index)), Float.intBitsToFloat(data.getInt(index + 4)), Float.intBitsToFloat(data.getInt(index + 8)));
|
||||||
Float.intBitsToFloat(data.getInt(index + 4)), Float.intBitsToFloat(data.getInt(index + 8)));
|
|
||||||
break;
|
break;
|
||||||
case RGB111110F://the data is stored as 32-bit unsigned int, that is why we cast the read data to long and remove MSB-bytes to get the positive value
|
case RGB111110F:// the data is stored as 32-bit unsigned int, that is why we cast the read data to long and remove MSB-bytes to get the positive value
|
||||||
pixel.fromARGB(1, (float)Double.longBitsToDouble((long)data.getInt(index) & 0x00000000FFFFFFFF),
|
pixel.fromARGB(1, (float) Double.longBitsToDouble((long) data.getInt(index) & 0x00000000FFFFFFFF), (float) Double.longBitsToDouble((long) data.getInt(index + 4) & 0x00000000FFFFFFFF), (float) Double.longBitsToDouble((long) data.getInt(index + 8) & 0x00000000FFFFFFFF));
|
||||||
(float)Double.longBitsToDouble((long)data.getInt(index + 4) & 0x00000000FFFFFFFF),
|
|
||||||
(float)Double.longBitsToDouble((long)data.getInt(index + 8) & 0x00000000FFFFFFFF));
|
|
||||||
break;
|
break;
|
||||||
case RGB10:
|
case RGB10:
|
||||||
case RGB9E5://TODO: support these
|
case RGB9E5:// TODO: support these
|
||||||
throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat());
|
throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat());
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown image format: " + image.getFormat());
|
throw new IllegalStateException("Unknown image format: " + image.getFormat());
|
||||||
@ -78,7 +72,7 @@ import jme3tools.converters.RGB565;
|
|||||||
|
|
||||||
public void write(Image image, int layer, TexturePixel pixel, int index) {
|
public void write(Image image, int layer, TexturePixel pixel, int index) {
|
||||||
ByteBuffer data = image.getData(layer);
|
ByteBuffer data = image.getData(layer);
|
||||||
switch(image.getFormat()) {
|
switch (image.getFormat()) {
|
||||||
case RGBA8:
|
case RGBA8:
|
||||||
data.put(index, pixel.getR8());
|
data.put(index, pixel.getR8());
|
||||||
data.put(index + 1, pixel.getG8());
|
data.put(index + 1, pixel.getG8());
|
||||||
@ -137,7 +131,7 @@ import jme3tools.converters.RGB565;
|
|||||||
data.putShort(index + 6, FastMath.convertFloatToHalf(pixel.blue));
|
data.putShort(index + 6, FastMath.convertFloatToHalf(pixel.blue));
|
||||||
break;
|
break;
|
||||||
case RGB32F:
|
case RGB32F:
|
||||||
case RGB111110F://this data is stored as 32-bit unsigned int
|
case RGB111110F:// this data is stored as 32-bit unsigned int
|
||||||
data.putInt(index, Float.floatToIntBits(pixel.red));
|
data.putInt(index, Float.floatToIntBits(pixel.red));
|
||||||
data.putInt(index + 2, Float.floatToIntBits(pixel.green));
|
data.putInt(index + 2, Float.floatToIntBits(pixel.green));
|
||||||
data.putInt(index + 4, Float.floatToIntBits(pixel.blue));
|
data.putInt(index + 4, Float.floatToIntBits(pixel.blue));
|
||||||
@ -149,7 +143,7 @@ import jme3tools.converters.RGB565;
|
|||||||
data.putInt(index + 6, Float.floatToIntBits(pixel.alpha));
|
data.putInt(index + 6, Float.floatToIntBits(pixel.alpha));
|
||||||
break;
|
break;
|
||||||
case RGB10:
|
case RGB10:
|
||||||
case RGB9E5://TODO: support these
|
case RGB9E5:// TODO: support these
|
||||||
throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat());
|
throw new IllegalStateException("Not supported image type for IO operations: " + image.getFormat());
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Unknown image format: " + image.getFormat());
|
throw new IllegalStateException("Unknown image format: " + image.getFormat());
|
||||||
|
@ -11,7 +11,7 @@ import jme3tools.converters.RGB565;
|
|||||||
* This class currently implements only read operation.
|
* This class currently implements only read operation.
|
||||||
* @author Marcin Roguski (Kaelthas)
|
* @author Marcin Roguski (Kaelthas)
|
||||||
*/
|
*/
|
||||||
/*package*/ class DDSPixelInputOutput implements PixelInputOutput {
|
/* package */class DDSPixelInputOutput implements PixelInputOutput {
|
||||||
/**
|
/**
|
||||||
* For this class the index should be considered as a pixel index in AWT image format.
|
* For this class the index should be considered as a pixel index in AWT image format.
|
||||||
*/
|
*/
|
||||||
@ -33,7 +33,7 @@ import jme3tools.converters.RGB565;
|
|||||||
|
|
||||||
switch (image.getFormat()) {
|
switch (image.getFormat()) {
|
||||||
case DXT1: // BC1
|
case DXT1: // BC1
|
||||||
case DXT1A:{
|
case DXT1A: {
|
||||||
data.position(texelIndex * 8);
|
data.position(texelIndex * 8);
|
||||||
short c0 = data.getShort();
|
short c0 = data.getShort();
|
||||||
short c1 = data.getShort();
|
short c1 = data.getShort();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user