(Java) IrrEdit File Format (.irr) loader for Jirr

Discussion about Irrlicht's Java wrapper
Post Reply
brunogamacatao
Posts: 3
Joined: Mon Nov 29, 2004 6:33 pm

(Java) IrrEdit File Format (.irr) loader for Jirr

Post by brunogamacatao »

Hey guys, I've implemented a very simple scene loader for Jirr. It doen't loads all the features that IrrEdit can export, but it helped me a lot. I hope you enjoy, and I'll hope even more if you could contribute to complete this implementation =D
P.S. It needs the jdom api (www.jdom.org)

Code: Select all

import java.io.IOException;
import java.lang.reflect.Method;
import java.util.StringTokenizer;

import net.sf.jirr.E_LIGHT_TYPE;
import net.sf.jirr.E_MATERIAL_FLAG;
import net.sf.jirr.E_MATERIAL_TYPE;
import net.sf.jirr.ILightSceneNode;
import net.sf.jirr.ISceneManager;
import net.sf.jirr.ISceneNode;
import net.sf.jirr.ISceneNodeAnimator;
import net.sf.jirr.ITexture;
import net.sf.jirr.IVideoDriver;
import net.sf.jirr.IrrlichtDevice;
import net.sf.jirr.SColor;
import net.sf.jirr.SColorf;
import net.sf.jirr.vector3df;

import org.jdom.Document;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;

public class SceneLoader {
	private static final String LIGHTING = "Lighting";
	private static final String TRANS_ADD = "trans_add";
	private static final String TRANS_ALPHACH = "trans_alphach";
	private static final String SOLID = "solid";
	private static final String POINT = "Point";
	private static final String ENUM = "enum";
	private static final String LIGHT_TYPE = "LightType";
	private static final String FLOAT = "float";
	private static final String SPEED = "Speed";
	private static final String RADIUS = "Radius";
	private static final String CENTER = "Center";
	private static final String ROTATION_ATTRIBUTE = "Rotation";
	private static final String FLY_CIRCLE = "flyCircle";
	private static final String ROTATION = "rotation";
	private static final String TYPE_PROPERTY = "Type";
	private static final String MATERIALS = "materials";
	private static final String MESH_PROPERTY = "Mesh";
	private static final String ANIMATORS = "animators";
	private static final String PARTICLE_SYSTEM = "particleSystem";
	private static final String LIGHT = "light";
	private static final String BILL_BOARD = "billBoard";
	private static final String CUBE = "cube";
	private static final String MESH = "mesh";
	private static final String SKY_BOX = "skyBox";
	private static final String TYPE = "type";
	private static final String VALUE_SEPARATOR    = ",";
	private static final String ATTRIBUTES         = "attributes";
	private static final String VALUE              = "value";
	private static final String NAME               = "name";
	private static final String STRING             = "string";
	private static final String INT                = "int";
	private static final String VECTOR3D           = "vector3d";
	private static final String BOOL               = "bool";
	private static final String TRUE               = "true";
	private static final String NON_VALIDATING_DTD = "http://apache.org/xml/features/nonvalidating/load-external-dtd";
	private static final String SET_PREFIX         = "set";

	public static void loadScene(String sceneFilename, IrrlichtDevice device) throws JDOMException, IOException {
		IVideoDriver driver = device.getVideoDriver();
		ISceneManager smgr  = device.getSceneManager();
		Document document   = getDocument(sceneFilename);
		
		Element irrScene = document.getRootElement();
		
		if (irrScene.getChild(ATTRIBUTES) != null) {
			//Reading the root scene node attributes
			Element attributes = irrScene.getChild(ATTRIBUTES);
			ISceneNode root    = smgr.getRootSceneNode();
			readAttributes(attributes, root);
		}
		
		for (Object obj : irrScene.getChildren()) {
			Element node = (Element)obj;
			
			if (ATTRIBUTES.equals(node.getName())) {
				continue;
			}
			
			Element attributes = node.getChild(ATTRIBUTES);
			
			String type = node.getAttributeValue(TYPE);
			ISceneNode sceneNode = null;
			
			if (type.equals(SKY_BOX)) {
				Element materials = node.getChild(MATERIALS);
				
				ITexture left  = getTexture(driver, (Element)materials.getChildren().get(0));
				ITexture front = getTexture(driver, (Element)materials.getChildren().get(1));
				ITexture right = getTexture(driver, (Element)materials.getChildren().get(2));
				ITexture back  = getTexture(driver, (Element)materials.getChildren().get(3));
				ITexture top   = getTexture(driver, (Element)materials.getChildren().get(4));
				ITexture down  = getTexture(driver, (Element)materials.getChildren().get(5));
				
				sceneNode = smgr.addSkyBoxSceneNode(top, down, front, back, left, right);
			} else if (type.equals(MESH)) {
				String meshName = getStringValue(attributes, MESH_PROPERTY);
				sceneNode = smgr.addAnimatedMeshSceneNode(smgr.getMesh(meshName));
				readAttributes(attributes, sceneNode);
				readMaterials(driver, node, sceneNode);
			} else if (type.equals(CUBE)) {
				sceneNode = smgr.addTestSceneNode();
				readAttributes(attributes, sceneNode);
				readMaterials(driver, node, sceneNode);
			} else if (type.equals(BILL_BOARD)) {
				sceneNode = smgr.addBillboardSceneNode();
				readAttributes(attributes, sceneNode);
				readMaterials(driver, node, sceneNode);
			} else if (type.equals(LIGHT)) {
				sceneNode = smgr.addLightSceneNode();
				readAttributes(attributes, sceneNode);
				readAttributes(attributes, ((ILightSceneNode)sceneNode).getLightData());
				
				ILightSceneNode light = (ILightSceneNode)sceneNode;
				String lightType = getValue(attributes, LIGHT_TYPE, ENUM);
				if (lightType.equals(POINT)) {
					light.getLightData().setType(E_LIGHT_TYPE.ELT_POINT);
				} else {
					light.getLightData().setType(E_LIGHT_TYPE.ELT_DIRECTIONAL);
				}
			} else if (type.equals(PARTICLE_SYSTEM)) {
				sceneNode = smgr.addParticleSystemSceneNode();
				readAttributes(attributes, sceneNode);
				readMaterials(driver, node, sceneNode);
			}
			
			if (sceneNode != null) {
				if (node.getChild(ANIMATORS) != null) {
					Element animators = node.getChild(ANIMATORS);
					for (Object o : animators.getChildren()) {
						Element el      = (Element)o;
						String animType = getStringValue(el, TYPE_PROPERTY);
						
						if (animType.equals(ROTATION)) {
							vector3df rotation = getVector3DValue(el, ROTATION_ATTRIBUTE);
							ISceneNodeAnimator anim = smgr.createRotationAnimator(rotation);
							sceneNode.addAnimator(anim);
							anim.drop();
						} else if (animType.equals(FLY_CIRCLE)) {
							vector3df center = getVector3DValue(el, CENTER);
							float radius     = getFloatValue(el, RADIUS);
							float speed      = getFloatValue(el, SPEED);
							ISceneNodeAnimator anim = smgr.createFlyCircleAnimator(center, radius, speed);
							sceneNode.addAnimator(anim);
							anim.drop();
						}
					}
				}
			}
		}
	}

	private static void readMaterials(IVideoDriver driver, Element node, ISceneNode sceneNode) {
		if (node.getChild(MATERIALS) != null) {
			Element materials = node.getChild(MATERIALS);
			int index = 0;
			for (Object o : materials.getChildren()) {
				Element el = (Element)o;
				sceneNode.setMaterialTexture(index, getTexture(driver, el));
				readAttributes(el, sceneNode.getMaterial(index));
				
				String materialType = getValue(el, TYPE_PROPERTY, ENUM);
				
				if (materialType.equals(SOLID)) {
					sceneNode.getMaterial(index).setMaterialType(E_MATERIAL_TYPE.EMT_SOLID);
				} else if (materialType.equals(TRANS_ALPHACH)) {
					sceneNode.getMaterial(index).setMaterialType(E_MATERIAL_TYPE.EMT_TRANSPARENT_ALPHA_CHANNEL);
				} else if (materialType.equals(TRANS_ADD)) {
					sceneNode.getMaterial(index).setMaterialType(E_MATERIAL_TYPE.EMT_TRANSPARENT_ADD_COLOR);
				}
				
				sceneNode.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, getBooleanValue(el, LIGHTING));
				
				index++;
			}
		}
	}
	
	private static boolean getBooleanValue(Element attributes, String elementName) {
		return TRUE.equals(getValue(attributes, elementName, BOOL));
	}

	private static String getStringValue(Element attributes, String elementName) {
		return getValue(attributes, elementName, STRING);
	}
	
	private static String getValue(Element attributes, String elementName, String type) {
		for (Object o : attributes.getChildren(type)) {
			Element el = (Element)o;
			if (el.getAttributeValue(NAME).equals(elementName)) {
				return el.getAttributeValue(VALUE);
			}
		}
		
		return "";
	}
	
	private static vector3df getVector3DValue(Element attributes, String elementName) {
		String value = getValue(attributes, elementName, VECTOR3D);
		StringTokenizer tokens = new StringTokenizer(value, VALUE_SEPARATOR);
		
		float x = Float.parseFloat(tokens.nextToken());
		float y = Float.parseFloat(tokens.nextToken());
		float z = Float.parseFloat(tokens.nextToken());
		
		return new vector3df(x, y, z);
	}
	
	private static float getFloatValue(Element attributes, String elementName) {
		String value = getValue(attributes, elementName, FLOAT);
		return Float.parseFloat(value);
	}

	private static ITexture getTexture(IVideoDriver driver, Element eTexture) {
		String textureName = "";
		
		for (Object o : eTexture.getChildren("texture")) {
			Element te = (Element)o;
			if ("Texture1".equals(te.getAttributeValue("name"))) {
				textureName = te.getAttributeValue("value");
				break;
			}
		}
		
		return driver.getTexture(textureName);
	}

	private static void readAttributes(Element attributes, Object root) {
		for (Object obj : attributes.getChildren()) {
			Element child = (Element)obj;
			
			String name       = child.getAttributeValue(NAME);
			String value      = child.getAttributeValue(VALUE);
			String methodName = SET_PREFIX + name;
			Method method     = getMethod(root, methodName);
			
			if (method == null) {
				continue;
			}
			
			if (child.getName().equals(STRING)) {
				Object[] args = {value};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if (child.getName().equals(INT)) {
				Object[] args = {Integer.parseInt(value)};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if (child.getName().equals(VECTOR3D)) {
				StringTokenizer tokens = new StringTokenizer(value, VALUE_SEPARATOR);
				
				float x = Float.parseFloat(tokens.nextToken());
				float y = Float.parseFloat(tokens.nextToken());
				float z = Float.parseFloat(tokens.nextToken());
				
				Object[] args = {new vector3df(x, y, z)};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if (child.getName().equals(BOOL)) {
				Object[] args = {TRUE.equals(value)};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if (child.getName().equals("colorf")) {
				StringTokenizer tokens = new StringTokenizer(value, VALUE_SEPARATOR);
				
				float x = Float.parseFloat(tokens.nextToken());
				float y = Float.parseFloat(tokens.nextToken());
				float z = Float.parseFloat(tokens.nextToken());
				
				Object[] args = {new SColorf(x, y, z)};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			} else if (child.getName().equals("color")) {
				int a = Integer.parseInt(value.substring(0, 2), 16);
				int r = Integer.parseInt(value.substring(2, 4), 16);
				int g = Integer.parseInt(value.substring(4, 6), 16);
				int b = Integer.parseInt(value.substring(6, 8), 16);
				
				Object[] args = {new SColor(a, r, g, b)};
				
				try {
					method.invoke(root, args);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}
	}
	
	private static Method getMethod(Object obj, String methodName) {
		for (Method method : obj.getClass().getMethods()) {
			if (method.getName().equalsIgnoreCase(methodName)) {
				return method;
			}
		}
		
		return null;
	}
	
	private static Document getDocument(String filename) throws JDOMException, IOException {
		SAXBuilder builder = new SAXBuilder();
		builder.setFeature(NON_VALIDATING_DTD, false);
		return builder.build(filename);
	}
}

In order to use this class you'll just have to do something like that:
SceneLoader.loadScene("scenes/myscene.irr", device);

:wink:
Post Reply