Support for loading custom properties added.
git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@7675 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
This commit is contained in:
parent
c410fae0a6
commit
fd2184784c
@ -30,6 +30,7 @@ import com.jme3.scene.plugins.blender.utils.BlenderInputStream;
|
|||||||
import com.jme3.scene.plugins.blender.utils.DataRepository;
|
import com.jme3.scene.plugins.blender.utils.DataRepository;
|
||||||
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.utils.Pointer;
|
import com.jme3.scene.plugins.blender.utils.Pointer;
|
||||||
|
import com.jme3.scene.plugins.blender.utils.Properties;
|
||||||
import com.jme3.scene.shape.Curve;
|
import com.jme3.scene.shape.Curve;
|
||||||
import com.jme3.scene.shape.Surface;
|
import com.jme3.scene.shape.Surface;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
@ -203,6 +204,15 @@ public class CurvesHelper extends AbstractBlenderHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//reading custom properties
|
||||||
|
Properties properties = this.loadProperties(curveStructure, dataRepository);
|
||||||
|
if(properties != null && properties.getValue() != null) {
|
||||||
|
for(Geometry geom : result) {
|
||||||
|
geom.setUserData("properties", properties);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
|
|||||||
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
||||||
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.utils.Pointer;
|
import com.jme3.scene.plugins.blender.utils.Pointer;
|
||||||
|
import com.jme3.scene.plugins.blender.utils.Properties;
|
||||||
import com.jme3.texture.Texture;
|
import com.jme3.texture.Texture;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
@ -292,6 +293,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
BufferUtils.createFloatBuffer(uvCoordinates.toArray(new Vector2f[uvCoordinates.size()])));
|
BufferUtils.createFloatBuffer(uvCoordinates.toArray(new Vector2f[uvCoordinates.size()])));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//reading custom properties
|
||||||
|
Properties properties = this.loadProperties(structure, dataRepository);
|
||||||
|
|
||||||
// generating meshes
|
// generating meshes
|
||||||
FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
|
FloatBuffer verticesColorsBuffer = this.createFloatBuffer(verticesColors);
|
||||||
for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
|
for (Entry<Integer, List<Integer>> meshEntry : meshesMap.entrySet()) {
|
||||||
@ -364,6 +368,9 @@ public class MeshHelper extends AbstractBlenderHelper {
|
|||||||
} else {
|
} else {
|
||||||
geometry.setMaterial(dataRepository.getDefaultMaterial());
|
geometry.setMaterial(dataRepository.getDefaultMaterial());
|
||||||
}
|
}
|
||||||
|
if(properties != null && properties.getValue() != null) {
|
||||||
|
geometry.setUserData("properties", properties);
|
||||||
|
}
|
||||||
geometries.add(geometry);
|
geometries.add(geometry);
|
||||||
}
|
}
|
||||||
dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
dataRepository.addLoadedFeatures(structure.getOldMemoryAddress(), structure.getName(), structure, geometries);
|
||||||
|
@ -62,6 +62,7 @@ import com.jme3.scene.plugins.blender.utils.DataRepository;
|
|||||||
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
import com.jme3.scene.plugins.blender.utils.DataRepository.LoadedFeatureDataType;
|
||||||
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
import com.jme3.scene.plugins.blender.utils.DynamicArray;
|
||||||
import com.jme3.scene.plugins.blender.utils.Pointer;
|
import com.jme3.scene.plugins.blender.utils.Pointer;
|
||||||
|
import com.jme3.scene.plugins.blender.utils.Properties;
|
||||||
import com.jme3.scene.plugins.ogre.AnimData;
|
import com.jme3.scene.plugins.ogre.AnimData;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -259,6 +260,13 @@ public class ObjectHelper extends AbstractBlenderHelper {
|
|||||||
} finally {
|
} finally {
|
||||||
dataRepository.popParent();
|
dataRepository.popParent();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//reading custom properties
|
||||||
|
Properties properties = this.loadProperties(objectStructure, dataRepository);
|
||||||
|
if(properties != null && properties.getValue() != null) {
|
||||||
|
((Node)result).setUserData("properties", properties);
|
||||||
|
}
|
||||||
|
|
||||||
if(result != null) {
|
if(result != null) {
|
||||||
dataRepository.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
dataRepository.addLoadedFeatures(objectStructure.getOldMemoryAddress(), name, objectStructure, result);
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,8 @@ package com.jme3.scene.plugins.blender.utils;
|
|||||||
import java.nio.FloatBuffer;
|
import java.nio.FloatBuffer;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
import com.jme3.scene.plugins.blender.data.Structure;
|
||||||
|
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
||||||
import com.jme3.util.BufferUtils;
|
import com.jme3.util.BufferUtils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -43,62 +45,85 @@ import com.jme3.util.BufferUtils;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractBlenderHelper {
|
public abstract class AbstractBlenderHelper {
|
||||||
|
|
||||||
/** The version of the blend file. */
|
/** The version of the blend file. */
|
||||||
protected final int blenderVersion;
|
protected final int blenderVersion;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
* This constructor parses the given blender version and stores the result. Some functionalities may differ in different blender
|
||||||
* versions.
|
* versions.
|
||||||
* @param blenderVersion
|
* @param blenderVersion
|
||||||
* the version read from the blend file
|
* the version read from the blend file
|
||||||
*/
|
*/
|
||||||
public AbstractBlenderHelper(String blenderVersion) {
|
public AbstractBlenderHelper(String blenderVersion) {
|
||||||
this.blenderVersion = Integer.parseInt(blenderVersion);
|
this.blenderVersion = Integer.parseInt(blenderVersion);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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
|
||||||
* being created and stored in the memory. It can be unwise especially inside loops.
|
* being created and stored in the memory. It can be unwise especially inside loops.
|
||||||
* @param text
|
* @param text
|
||||||
* the text to be checked
|
* the text to be checked
|
||||||
* @return <b>true</b> if the text is blank and <b>false</b> otherwise
|
* @return <b>true</b> if the text is blank and <b>false</b> otherwise
|
||||||
*/
|
*/
|
||||||
protected boolean isBlank(String text) {
|
protected boolean isBlank(String text) {
|
||||||
if (text != null) {
|
if (text != null) {
|
||||||
for (int i = 0; i < text.length(); ++i) {
|
for (int i = 0; i < text.length(); ++i) {
|
||||||
if (!Character.isWhitespace(text.charAt(i))) {
|
if (!Character.isWhitespace(text.charAt(i))) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a new FloatBuffer using the given array of float[4] objects. The FloatBuffer will be 4 * data.length
|
* Generate a new FloatBuffer using the given array of float[4] objects. The FloatBuffer will be 4 * data.length
|
||||||
* long and contain the vector data as data[0][0], data[0][1], data[0][2], data[0][3], data[1][0]... etc.
|
* long and contain the vector data as data[0][0], data[0][1], data[0][2], data[0][3], data[1][0]... etc.
|
||||||
* @param data
|
* @param data
|
||||||
* list of float[4] objects to place into a new FloatBuffer
|
* list of float[4] objects to place into a new FloatBuffer
|
||||||
*/
|
*/
|
||||||
protected FloatBuffer createFloatBuffer(List<float[]> data) {
|
protected FloatBuffer createFloatBuffer(List<float[]> data) {
|
||||||
if (data == null) {
|
if (data == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
FloatBuffer buff = BufferUtils.createFloatBuffer(4 * data.size());
|
FloatBuffer buff = BufferUtils.createFloatBuffer(4 * data.size());
|
||||||
for (float[] v : data) {
|
for (float[] v : data) {
|
||||||
if (v != null) {
|
if (v != null) {
|
||||||
buff.put(v[0]).put(v[1]).put(v[2]).put(v[3]);
|
buff.put(v[0]).put(v[1]).put(v[2]).put(v[3]);
|
||||||
} else {
|
} else {
|
||||||
buff.put(0).put(0).put(0).put(0);
|
buff.put(0).put(0).put(0).put(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
buff.flip();
|
buff.flip();
|
||||||
return buff;
|
return buff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads the properties if they are available and defined for the structure.
|
||||||
|
* @param structure
|
||||||
|
* the structure we read the properties from
|
||||||
|
* @param dataRepository
|
||||||
|
* the data repository
|
||||||
|
* @return loaded properties or null if they are not available
|
||||||
|
* @throws BlenderFileException
|
||||||
|
* an exception is thrown when the blend file is somehow corrupted
|
||||||
|
*/
|
||||||
|
protected Properties loadProperties(Structure structure, DataRepository dataRepository) throws BlenderFileException {
|
||||||
|
Properties properties = null;
|
||||||
|
Structure id = (Structure) structure.getFieldValue("ID");
|
||||||
|
if (id != null) {
|
||||||
|
Pointer pProperties = (Pointer) id.getFieldValue("properties");
|
||||||
|
if (!pProperties.isNull()) {
|
||||||
|
Structure propertiesStructure = pProperties.fetchData(dataRepository.getInputStream()).get(0);
|
||||||
|
properties = new Properties();
|
||||||
|
properties.load(propertiesStructure, dataRepository);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,441 @@
|
|||||||
|
package com.jme3.scene.plugins.blender.utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
|
||||||
|
|
||||||
|
import com.jme3.export.InputCapsule;
|
||||||
|
import com.jme3.export.JmeExporter;
|
||||||
|
import com.jme3.export.JmeImporter;
|
||||||
|
import com.jme3.export.OutputCapsule;
|
||||||
|
import com.jme3.export.Savable;
|
||||||
|
import com.jme3.scene.plugins.blender.data.FileBlockHeader;
|
||||||
|
import com.jme3.scene.plugins.blender.data.Structure;
|
||||||
|
import com.jme3.scene.plugins.blender.exception.BlenderFileException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The blender object's custom properties.
|
||||||
|
* This class is valid for all versions of blender.
|
||||||
|
* @author Marcin Roguski (Kaelthas)
|
||||||
|
*/
|
||||||
|
public class Properties implements Cloneable, Savable {
|
||||||
|
private static final Logger LOGGER = Logger.getLogger(Properties.class.getName());
|
||||||
|
|
||||||
|
// property type
|
||||||
|
public static final int IDP_STRING = 0;
|
||||||
|
public static final int IDP_INT = 1;
|
||||||
|
public static final int IDP_FLOAT = 2;
|
||||||
|
public static final int IDP_ARRAY = 5;
|
||||||
|
public static final int IDP_GROUP = 6;
|
||||||
|
// public static final int IDP_ID = 7;//this is not implemented in blender (yet)
|
||||||
|
public static final int IDP_DOUBLE = 8;
|
||||||
|
// the following are valid for blender 2.5x+
|
||||||
|
public static final int IDP_IDPARRAY = 9;
|
||||||
|
public static final int IDP_NUMTYPES = 10;
|
||||||
|
|
||||||
|
protected static final String RNA_PROPERTY_NAME = "_RNA_UI";
|
||||||
|
/** Default name of the property (used if the name is not specified in blender file). */
|
||||||
|
protected static final String DEFAULT_NAME = "Unnamed property";
|
||||||
|
|
||||||
|
/** The name of the property. */
|
||||||
|
private String name;
|
||||||
|
/** The type of the property. */
|
||||||
|
private int type;
|
||||||
|
/** The subtype of the property. Defines the type of array's elements. */
|
||||||
|
private int subType;
|
||||||
|
/** The value of the property. */
|
||||||
|
private Object value;
|
||||||
|
/** The description of the property. */
|
||||||
|
private String description;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method loads the property from the belnder file.
|
||||||
|
* @param idPropertyStructure
|
||||||
|
* the ID structure constining the property
|
||||||
|
* @param dataRepository
|
||||||
|
* the data repository
|
||||||
|
* @throws BlenderFileException
|
||||||
|
* an exception is thrown when the belnder file is somehow invalid
|
||||||
|
*/
|
||||||
|
public void load(Structure idPropertyStructure, DataRepository dataRepository) throws BlenderFileException {
|
||||||
|
name = idPropertyStructure.getFieldValue("name").toString();
|
||||||
|
if (name == null || name.length() == 0) {
|
||||||
|
name = DEFAULT_NAME;
|
||||||
|
}
|
||||||
|
subType = ((Number) idPropertyStructure.getFieldValue("subtype")).intValue();
|
||||||
|
type = ((Number) idPropertyStructure.getFieldValue("type")).intValue();
|
||||||
|
|
||||||
|
// reading the data
|
||||||
|
Structure data = (Structure) idPropertyStructure.getFieldValue("data");
|
||||||
|
int len = ((Number) idPropertyStructure.getFieldValue("len")).intValue();
|
||||||
|
switch (type) {
|
||||||
|
case IDP_STRING: {
|
||||||
|
Pointer pointer = (Pointer) data.getFieldValue("pointer");
|
||||||
|
BlenderInputStream bis = dataRepository.getInputStream();
|
||||||
|
FileBlockHeader dataFileBlock = dataRepository.getFileBlock(pointer.getOldMemoryAddress());
|
||||||
|
bis.setPosition(dataFileBlock.getBlockPosition());
|
||||||
|
value = bis.readString();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IDP_INT:
|
||||||
|
int intValue = ((Number) data.getFieldValue("val")).intValue();
|
||||||
|
value = Integer.valueOf(intValue);
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
int floatValue = ((Number) data.getFieldValue("val")).intValue();
|
||||||
|
value = Float.valueOf(Float.intBitsToFloat(floatValue));
|
||||||
|
break;
|
||||||
|
case IDP_ARRAY: {
|
||||||
|
Pointer pointer = (Pointer) data.getFieldValue("pointer");
|
||||||
|
BlenderInputStream bis = dataRepository.getInputStream();
|
||||||
|
FileBlockHeader dataFileBlock = dataRepository.getFileBlock(pointer.getOldMemoryAddress());
|
||||||
|
bis.setPosition(dataFileBlock.getBlockPosition());
|
||||||
|
int elementAmount = dataFileBlock.getSize();
|
||||||
|
switch (subType) {
|
||||||
|
case IDP_INT:
|
||||||
|
elementAmount /= 4;
|
||||||
|
int[] intList = new int[elementAmount];
|
||||||
|
for (int i = 0; i < elementAmount; ++i) {
|
||||||
|
intList[i] = bis.readInt();
|
||||||
|
}
|
||||||
|
value = intList;
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
elementAmount /= 4;
|
||||||
|
float[] floatList = new float[elementAmount];
|
||||||
|
for (int i = 0; i < elementAmount; ++i) {
|
||||||
|
floatList[i] = bis.readFloat();
|
||||||
|
}
|
||||||
|
value = floatList;
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
elementAmount /= 8;
|
||||||
|
double[] doubleList = new double[elementAmount];
|
||||||
|
for (int i = 0; i < elementAmount; ++i) {
|
||||||
|
doubleList[i] = bis.readDouble();
|
||||||
|
}
|
||||||
|
value = doubleList;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Invalid array subtype: " + subType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case IDP_GROUP:
|
||||||
|
Structure group = (Structure) data.getFieldValue("group");
|
||||||
|
List<Structure> dataList = group.evaluateListBase(dataRepository);
|
||||||
|
List<Properties> subProperties = new ArrayList<Properties>(len);
|
||||||
|
for (Structure d : dataList) {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
properties.load(d, dataRepository);
|
||||||
|
subProperties.add(properties);
|
||||||
|
}
|
||||||
|
value = subProperties;
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
int doublePart1 = ((Number) data.getFieldValue("val")).intValue();
|
||||||
|
int doublePart2 = ((Number) data.getFieldValue("val2")).intValue();
|
||||||
|
long doubleVal = (long) doublePart2 << 32 | doublePart1;
|
||||||
|
value = Double.valueOf(Double.longBitsToDouble(doubleVal));
|
||||||
|
break;
|
||||||
|
case IDP_IDPARRAY: {
|
||||||
|
Pointer pointer = (Pointer) data.getFieldValue("pointer");
|
||||||
|
List<Structure> arrays = pointer.fetchData(dataRepository.getInputStream());
|
||||||
|
List<Object> result = new ArrayList<Object>(arrays.size());
|
||||||
|
Properties temp = new Properties();
|
||||||
|
for (Structure array : arrays) {
|
||||||
|
temp.load(array, dataRepository);
|
||||||
|
result.add(temp.value);
|
||||||
|
}
|
||||||
|
this.value = result;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case IDP_NUMTYPES:
|
||||||
|
throw new NotImplementedException();
|
||||||
|
// case IDP_ID://not yet implemented in blender
|
||||||
|
// return null;
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unknown custom property type: " + type);
|
||||||
|
}
|
||||||
|
this.completeLoading();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the name of the property.
|
||||||
|
* @return the name of the property
|
||||||
|
*/
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the description of the property.
|
||||||
|
* @return the description of the property
|
||||||
|
*/
|
||||||
|
public String getDescription() {
|
||||||
|
return description;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the type of the property.
|
||||||
|
* @return the type of the property
|
||||||
|
*/
|
||||||
|
public int getType() {
|
||||||
|
return type;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method returns the value of the property.
|
||||||
|
* The type of the value depends on the type of the property.
|
||||||
|
* @return the value of the property
|
||||||
|
*/
|
||||||
|
public Object getValue() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
this.append(sb, new StringBuilder());
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method appends the data of the property to the given string buffer.
|
||||||
|
* @param sb
|
||||||
|
* string buffer
|
||||||
|
* @param indent
|
||||||
|
* indent buffer
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
private void append(StringBuilder sb, StringBuilder indent) {
|
||||||
|
sb.append(indent).append("name: ").append(name).append("\n\r");
|
||||||
|
sb.append(indent).append("type: ").append(type).append("\n\r");
|
||||||
|
sb.append(indent).append("subType: ").append(subType).append("\n\r");
|
||||||
|
sb.append(indent).append("description: ").append(description).append("\n\r");
|
||||||
|
indent.append('\t');
|
||||||
|
sb.append(indent).append("value: ");
|
||||||
|
if (value instanceof Properties) {
|
||||||
|
((Properties) value).append(sb, indent);
|
||||||
|
} else if (value instanceof List) {
|
||||||
|
for (Object v : (List<Object>) value) {
|
||||||
|
if (v instanceof Properties) {
|
||||||
|
sb.append(indent).append("{\n\r");
|
||||||
|
indent.append('\t');
|
||||||
|
((Properties) v).append(sb, indent);
|
||||||
|
indent.deleteCharAt(indent.length() - 1);
|
||||||
|
sb.append(indent).append("}\n\r");
|
||||||
|
} else {
|
||||||
|
sb.append(v);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
sb.append(value);
|
||||||
|
}
|
||||||
|
sb.append("\n\r");
|
||||||
|
indent.deleteCharAt(indent.length() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method should be called after the properties loading.
|
||||||
|
* It loads the properties from the _RNA_UI property and removes this property from the
|
||||||
|
* result list.
|
||||||
|
*/
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
protected void completeLoading() {
|
||||||
|
if (this.type == IDP_GROUP) {
|
||||||
|
List<Properties> groupProperties = (List<Properties>) this.value;
|
||||||
|
Properties rnaUI = null;
|
||||||
|
for (Properties properties : groupProperties) {
|
||||||
|
if (properties.name.equals(RNA_PROPERTY_NAME) && properties.type == IDP_GROUP) {
|
||||||
|
rnaUI = properties;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rnaUI != null) {
|
||||||
|
// removing the RNA from the result list
|
||||||
|
groupProperties.remove(rnaUI);
|
||||||
|
|
||||||
|
// loading the descriptions
|
||||||
|
Map<String, String> descriptions = new HashMap<String, String>(groupProperties.size());
|
||||||
|
List<Properties> propertiesRNA = (List<Properties>) rnaUI.value;
|
||||||
|
for (Properties properties : propertiesRNA) {
|
||||||
|
String name = properties.name;
|
||||||
|
String description = null;
|
||||||
|
List<Properties> rnaData = (List<Properties>) properties.value;
|
||||||
|
for (Properties rna : rnaData) {
|
||||||
|
if ("description".equalsIgnoreCase(rna.name)) {
|
||||||
|
description = (String) rna.value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
descriptions.put(name, description);
|
||||||
|
}
|
||||||
|
|
||||||
|
// applying the descriptions
|
||||||
|
for (Properties properties : groupProperties) {
|
||||||
|
properties.description = descriptions.get(properties.name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void write(JmeExporter ex) throws IOException {
|
||||||
|
OutputCapsule oc = ex.getCapsule(this);
|
||||||
|
oc.write(name, "name", DEFAULT_NAME);
|
||||||
|
oc.write(type, "type", 0);
|
||||||
|
oc.write(subType, "subtype", 0);
|
||||||
|
oc.write(description, "description", null);
|
||||||
|
switch (type) {
|
||||||
|
case IDP_STRING:
|
||||||
|
oc.write((String) value, "value", null);
|
||||||
|
break;
|
||||||
|
case IDP_INT:
|
||||||
|
oc.write((Integer) value, "value", 0);
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
oc.write((Float) value, "value", 0);
|
||||||
|
break;
|
||||||
|
case IDP_ARRAY:
|
||||||
|
switch (subType) {
|
||||||
|
case IDP_INT:
|
||||||
|
oc.write((int[]) value, "value", null);
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
oc.write((float[]) value, "value", null);
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
oc.write((double[]) value, "value", null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGGER.warning("Cannot save the property's value! Invalid array subtype! Property: name: " + name + "; subtype: " + subType);
|
||||||
|
}
|
||||||
|
case IDP_GROUP:
|
||||||
|
oc.write((Properties) value, "value", null);
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
oc.write((Double) value, "value", 0);
|
||||||
|
break;
|
||||||
|
case IDP_IDPARRAY:
|
||||||
|
oc.writeSavableArrayList((ArrayList) value, "value", null);
|
||||||
|
break;
|
||||||
|
case IDP_NUMTYPES:
|
||||||
|
LOGGER.warning("Numtypes value not supported! Cannot write it!");
|
||||||
|
break;
|
||||||
|
// case IDP_ID://not yet implemented in blender
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
LOGGER.warning("Cannot save the property's value! Invalid type! Property: name: " + name + "; type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void read(JmeImporter im) throws IOException {
|
||||||
|
InputCapsule ic = im.getCapsule(this);
|
||||||
|
name = ic.readString("name", DEFAULT_NAME);
|
||||||
|
type = ic.readInt("type", 0);
|
||||||
|
subType = ic.readInt("subtype", 0);
|
||||||
|
description = ic.readString("description", null);
|
||||||
|
switch (type) {
|
||||||
|
case IDP_STRING:
|
||||||
|
value = ic.readString("value", null);
|
||||||
|
break;
|
||||||
|
case IDP_INT:
|
||||||
|
value = Integer.valueOf(ic.readInt("value", 0));
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
value = Float.valueOf(ic.readFloat("value", 0.0f));
|
||||||
|
break;
|
||||||
|
case IDP_ARRAY:
|
||||||
|
switch (subType) {
|
||||||
|
case IDP_INT:
|
||||||
|
value = ic.readIntArray("value", null);
|
||||||
|
break;
|
||||||
|
case IDP_FLOAT:
|
||||||
|
value = ic.readFloatArray("value", null);
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
value = ic.readDoubleArray("value", null);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
LOGGER.warning("Cannot read the property's value! Invalid array subtype! Property: name: " + name + "; subtype: " + subType);
|
||||||
|
}
|
||||||
|
case IDP_GROUP:
|
||||||
|
value = ic.readSavable("value", null);
|
||||||
|
break;
|
||||||
|
case IDP_DOUBLE:
|
||||||
|
value = Double.valueOf(ic.readDouble("value", 0.0));
|
||||||
|
break;
|
||||||
|
case IDP_IDPARRAY:
|
||||||
|
value = ic.readSavableArrayList("value", null);
|
||||||
|
break;
|
||||||
|
case IDP_NUMTYPES:
|
||||||
|
LOGGER.warning("Numtypes value not supported! Cannot read it!");
|
||||||
|
break;
|
||||||
|
// case IDP_ID://not yet implemented in blender
|
||||||
|
// break;
|
||||||
|
default:
|
||||||
|
LOGGER.warning("Cannot read the property's value! Invalid type! Property: name: " + name + "; type: " + type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
final int prime = 31;
|
||||||
|
int result = 1;
|
||||||
|
result = prime * result + (description == null ? 0 : description.hashCode());
|
||||||
|
result = prime * result + (name == null ? 0 : name.hashCode());
|
||||||
|
result = prime * result + subType;
|
||||||
|
result = prime * result + type;
|
||||||
|
result = prime * result + (value == null ? 0 : value.hashCode());
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
if (obj == null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (this.getClass() != obj.getClass()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
Properties other = (Properties) obj;
|
||||||
|
if (description == null) {
|
||||||
|
if (other.description != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!description.equals(other.description)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (name == null) {
|
||||||
|
if (other.name != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!name.equals(other.name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (subType != other.subType) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (type != other.type) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (value == null) {
|
||||||
|
if (other.value != null) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else if (!value.equals(other.value)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user