1 /*
2  * Copyright (c) 2009-2012 jMonkeyEngine
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are
7  * met:
8  *
9  * * Redistributions of source code must retain the above copyright
10  *   notice, this list of conditions and the following disclaimer.
11  *
12  * * Redistributions in binary form must reproduce the above copyright
13  *   notice, this list of conditions and the following disclaimer in the
14  *   documentation and/or other materials provided with the distribution.
15  *
16  * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
17  *   may be used to endorse or promote products derived from this software
18  *   without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
21  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
24  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
25  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
26  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
27  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
28  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
29  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
30  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 package com.jme3.asset;
33 
34 import com.jme3.bounding.BoundingVolume;
35 import com.jme3.collision.Collidable;
36 import com.jme3.collision.CollisionResults;
37 import com.jme3.collision.UnsupportedCollisionException;
38 import com.jme3.export.InputCapsule;
39 import com.jme3.export.JmeExporter;
40 import com.jme3.export.JmeImporter;
41 import com.jme3.export.OutputCapsule;
42 import com.jme3.light.AmbientLight;
43 import com.jme3.light.Light;
44 import com.jme3.material.Material;
45 import com.jme3.material.RenderState.FaceCullMode;
46 import com.jme3.renderer.Camera;
47 import com.jme3.scene.Node;
48 import com.jme3.scene.SceneGraphVisitor;
49 import com.jme3.scene.Spatial;
50 import com.jme3.scene.plugins.ogre.AnimData;
51 import com.jme3.texture.Texture;
52 import java.io.IOException;
53 import java.util.ArrayList;
54 import java.util.List;
55 import java.util.Queue;
56 
57 /**
58  * Blender key. Contains path of the blender file and its loading properties.
59  * @author Marcin Roguski (Kaelthas)
60  */
61 public class BlenderKey extends ModelKey {
62 
63 	protected static final int					DEFAULT_FPS				= 25;
64 	/**
65 	 * FramesPerSecond parameter describe how many frames there are in each second. It allows to calculate the time
66 	 * between the frames.
67 	 */
68 	protected int								fps						= DEFAULT_FPS;
69 	/** Width of generated textures (in pixels). */
70 	protected int								generatedTextureWidth	= 60;
71 	/** Height of generated textures (in pixels). */
72 	protected int								generatedTextureHeight	= 60;
73 	/** Depth of generated textures (in pixels). */
74 	protected int								generatedTextureDepth	= 60;
75 	/**
76 	 * This variable is a bitwise flag of FeatureToLoad interface values; By default everything is being loaded.
77 	 */
78 	protected int								featuresToLoad			= FeaturesToLoad.ALL;
79 	/** This variable determines if assets that are not linked to the objects should be loaded. */
80 	protected boolean							loadUnlinkedAssets;
81 	/** The root path for all the assets. */
82 	protected String							assetRootPath;
83 	/** This variable indicate if Y axis is UP axis. If not then Z is up. By default set to true. */
84 	protected boolean							fixUpAxis				= true;
85 	/**
86 	 * The name of world settings that the importer will use. If not set or specified name does not occur in the file
87 	 * then the first world settings in the file will be used.
88 	 */
89 	protected String							usedWorld;
90 	/**
91 	 * User's default material that is set fo objects that have no material definition in blender. The default value is
92 	 * null. If the value is null the importer will use its own default material (gray color - like in blender).
93 	 */
94 	protected Material							defaultMaterial;
95 	/** Face cull mode. By default it is disabled. */
96 	protected FaceCullMode						faceCullMode			= FaceCullMode.Off;
97 	/**
98 	 * Variable describes which layers will be loaded. N-th bit set means N-th layer will be loaded.
99 	 * If set to -1 then the current layer will be loaded.
100 	 */
101 	protected int								layersToLoad			= -1;
102 
103 	/**
104 	 * Constructor used by serialization mechanisms.
105 	 */
BlenderKey()106 	public BlenderKey() {}
107 
108 	/**
109 	 * Constructor. Creates a key for the given file name.
110 	 * @param name
111 	 *        the name (path) of a file
112 	 */
BlenderKey(String name)113 	public BlenderKey(String name) {
114 		super(name);
115 	}
116 
117 	/**
118 	 * This method returns frames per second amount. The default value is BlenderKey.DEFAULT_FPS = 25.
119 	 * @return the frames per second amount
120 	 */
getFps()121 	public int getFps() {
122 		return fps;
123 	}
124 
125 	/**
126 	 * This method sets frames per second amount.
127 	 * @param fps
128 	 *        the frames per second amount
129 	 */
setFps(int fps)130 	public void setFps(int fps) {
131 		this.fps = fps;
132 	}
133 
134 	/**
135 	 * This method sets the width of generated texture (in pixels). By default the value is 140 px.
136 	 * @param generatedTextureWidth
137 	 *        the width of generated texture
138 	 */
setGeneratedTextureWidth(int generatedTextureWidth)139 	public void setGeneratedTextureWidth(int generatedTextureWidth) {
140 		this.generatedTextureWidth = generatedTextureWidth;
141 	}
142 
143 	/**
144 	 * This method returns the width of generated texture (in pixels). By default the value is 140 px.
145 	 * @return the width of generated texture
146 	 */
getGeneratedTextureWidth()147 	public int getGeneratedTextureWidth() {
148 		return generatedTextureWidth;
149 	}
150 
151 	/**
152 	 * This method sets the height of generated texture (in pixels). By default the value is 20 px.
153 	 * @param generatedTextureHeight
154 	 *        the height of generated texture
155 	 */
setGeneratedTextureHeight(int generatedTextureHeight)156 	public void setGeneratedTextureHeight(int generatedTextureHeight) {
157 		this.generatedTextureHeight = generatedTextureHeight;
158 	}
159 
160 	/**
161 	 * This method returns the height of generated texture (in pixels). By default the value is 20 px.
162 	 * @return the height of generated texture
163 	 */
getGeneratedTextureHeight()164 	public int getGeneratedTextureHeight() {
165 		return generatedTextureHeight;
166 	}
167 
168 	/**
169 	 * This method sets the depth of generated texture (in pixels). By default the value is 20 px.
170 	 * @param generatedTextureDepth
171 	 *        the depth of generated texture
172 	 */
setGeneratedTextureDepth(int generatedTextureDepth)173 	public void setGeneratedTextureDepth(int generatedTextureDepth) {
174 		this.generatedTextureDepth = generatedTextureDepth;
175 	}
176 
177 	/**
178 	 * This method returns the depth of generated texture (in pixels). By default the value is 20 px.
179 	 * @return the depth of generated texture
180 	 */
getGeneratedTextureDepth()181 	public int getGeneratedTextureDepth() {
182 		return generatedTextureDepth;
183 	}
184 
185 	/**
186 	 * This method returns the face cull mode.
187 	 * @return the face cull mode
188 	 */
getFaceCullMode()189 	public FaceCullMode getFaceCullMode() {
190 		return faceCullMode;
191 	}
192 
193 	/**
194 	 * This method sets the face cull mode.
195 	 * @param faceCullMode
196 	 *        the face cull mode
197 	 */
setFaceCullMode(FaceCullMode faceCullMode)198 	public void setFaceCullMode(FaceCullMode faceCullMode) {
199 		this.faceCullMode = faceCullMode;
200 	}
201 
202 	/**
203 	 * This method sets layers to be loaded.
204 	 * @param layersToLoad
205 	 *        layers to be loaded
206 	 */
setLayersToLoad(int layersToLoad)207 	public void setLayersToLoad(int layersToLoad) {
208 		this.layersToLoad = layersToLoad;
209 	}
210 
211 	/**
212 	 * This method returns layers to be loaded.
213 	 * @return layers to be loaded
214 	 */
getLayersToLoad()215 	public int getLayersToLoad() {
216 		return layersToLoad;
217 	}
218 
219 	/**
220 	 * This method sets the asset root path.
221 	 * @param assetRootPath
222 	 *        the assets root path
223 	 */
setAssetRootPath(String assetRootPath)224 	public void setAssetRootPath(String assetRootPath) {
225 		this.assetRootPath = assetRootPath;
226 	}
227 
228 	/**
229 	 * This method returns the asset root path.
230 	 * @return the asset root path
231 	 */
getAssetRootPath()232 	public String getAssetRootPath() {
233 		return assetRootPath;
234 	}
235 
236 	/**
237 	 * This method adds features to be loaded.
238 	 * @param featuresToLoad
239 	 *        bitwise flag of FeaturesToLoad interface values
240 	 */
includeInLoading(int featuresToLoad)241 	public void includeInLoading(int featuresToLoad) {
242 		this.featuresToLoad |= featuresToLoad;
243 	}
244 
245 	/**
246 	 * This method removes features from being loaded.
247 	 * @param featuresNotToLoad
248 	 *        bitwise flag of FeaturesToLoad interface values
249 	 */
excludeFromLoading(int featuresNotToLoad)250 	public void excludeFromLoading(int featuresNotToLoad) {
251 		this.featuresToLoad &= ~featuresNotToLoad;
252 	}
253 
254 	/**
255 	 * This method returns bitwise value of FeaturesToLoad interface value. It describes features that will be loaded by
256 	 * the blender file loader.
257 	 * @return features that will be loaded by the blender file loader
258 	 */
getFeaturesToLoad()259 	public int getFeaturesToLoad() {
260 		return featuresToLoad;
261 	}
262 
263 	/**
264 	 * This method determines if unlinked assets should be loaded.
265 	 * If not then only objects on selected layers will be loaded and their assets if required.
266 	 * If yes then all assets will be loaded even if they are on inactive layers or are not linked
267 	 * to anything.
268 	 * @return <b>true</b> if unlinked assets should be loaded and <b>false</b> otherwise
269 	 */
isLoadUnlinkedAssets()270 	public boolean isLoadUnlinkedAssets() {
271 		return loadUnlinkedAssets;
272 	}
273 
274 	/**
275 	 * This method sets if unlinked assets should be loaded.
276 	 * If not then only objects on selected layers will be loaded and their assets if required.
277 	 * If yes then all assets will be loaded even if they are on inactive layers or are not linked
278 	 * to anything.
279 	 * @param loadUnlinkedAssets
280 	 *        <b>true</b> if unlinked assets should be loaded and <b>false</b> otherwise
281 	 */
setLoadUnlinkedAssets(boolean loadUnlinkedAssets)282 	public void setLoadUnlinkedAssets(boolean loadUnlinkedAssets) {
283 		this.loadUnlinkedAssets = loadUnlinkedAssets;
284 	}
285 
286 	/**
287 	 * This method creates an object where loading results will be stores. Only those features will be allowed to store
288 	 * that were specified by features-to-load flag.
289 	 * @return an object to store loading results
290 	 */
prepareLoadingResults()291 	public LoadingResults prepareLoadingResults() {
292 		return new LoadingResults(featuresToLoad);
293 	}
294 
295 	/**
296 	 * This method sets the fix up axis state. If set to true then Y is up axis. Otherwise the up i Z axis. By default Y
297 	 * is up axis.
298 	 * @param fixUpAxis
299 	 *        the up axis state variable
300 	 */
setFixUpAxis(boolean fixUpAxis)301 	public void setFixUpAxis(boolean fixUpAxis) {
302 		this.fixUpAxis = fixUpAxis;
303 	}
304 
305 	/**
306 	 * This method returns the fix up axis state. If set to true then Y is up axis. Otherwise the up i Z axis. By
307 	 * default Y is up axis.
308 	 * @return the up axis state variable
309 	 */
isFixUpAxis()310 	public boolean isFixUpAxis() {
311 		return fixUpAxis;
312 	}
313 
314 	/**
315 	 * This mehtod sets the name of the WORLD data block taht should be used during file loading. By default the name is
316 	 * not set. If no name is set or the given name does not occur in the file - the first WORLD data block will be used
317 	 * during loading (assumin any exists in the file).
318 	 * @param usedWorld
319 	 *        the name of the WORLD block used during loading
320 	 */
setUsedWorld(String usedWorld)321 	public void setUsedWorld(String usedWorld) {
322 		this.usedWorld = usedWorld;
323 	}
324 
325 	/**
326 	 * This mehtod returns the name of the WORLD data block taht should be used during file loading.
327 	 * @return the name of the WORLD block used during loading
328 	 */
getUsedWorld()329 	public String getUsedWorld() {
330 		return usedWorld;
331 	}
332 
333 	/**
334 	 * This method sets the default material for objects.
335 	 * @param defaultMaterial
336 	 *        the default material
337 	 */
setDefaultMaterial(Material defaultMaterial)338 	public void setDefaultMaterial(Material defaultMaterial) {
339 		this.defaultMaterial = defaultMaterial;
340 	}
341 
342 	/**
343 	 * This method returns the default material.
344 	 * @return the default material
345 	 */
getDefaultMaterial()346 	public Material getDefaultMaterial() {
347 		return defaultMaterial;
348 	}
349 
350 	@Override
write(JmeExporter e)351 	public void write(JmeExporter e) throws IOException {
352 		super.write(e);
353 		OutputCapsule oc = e.getCapsule(this);
354 		oc.write(fps, "fps", DEFAULT_FPS);
355 		oc.write(generatedTextureWidth, "generated-texture-width", 20);
356 		oc.write(generatedTextureHeight, "generated-texture-height", 20);
357 		oc.write(generatedTextureDepth, "generated-texture-depth", 20);
358 		oc.write(featuresToLoad, "features-to-load", FeaturesToLoad.ALL);
359 		oc.write(loadUnlinkedAssets, "load-unlinked-assets", false);
360 		oc.write(assetRootPath, "asset-root-path", null);
361 		oc.write(fixUpAxis, "fix-up-axis", true);
362 		oc.write(usedWorld, "used-world", null);
363 		oc.write(defaultMaterial, "default-material", null);
364 		oc.write(faceCullMode, "face-cull-mode", FaceCullMode.Off);
365 		oc.write(layersToLoad, "layers-to-load", -1);
366 	}
367 
368 	@Override
read(JmeImporter e)369 	public void read(JmeImporter e) throws IOException {
370 		super.read(e);
371 		InputCapsule ic = e.getCapsule(this);
372 		fps = ic.readInt("fps", DEFAULT_FPS);
373 		generatedTextureWidth = ic.readInt("generated-texture-width", 20);
374 		generatedTextureHeight = ic.readInt("generated-texture-height", 20);
375 		generatedTextureDepth = ic.readInt("generated-texture-depth", 20);
376 		featuresToLoad = ic.readInt("features-to-load", FeaturesToLoad.ALL);
377 		loadUnlinkedAssets = ic.readBoolean("load-unlinked-assets", false);
378 		assetRootPath = ic.readString("asset-root-path", null);
379 		fixUpAxis = ic.readBoolean("fix-up-axis", true);
380 		usedWorld = ic.readString("used-world", null);
381 		defaultMaterial = (Material) ic.readSavable("default-material", null);
382 		faceCullMode = ic.readEnum("face-cull-mode", FaceCullMode.class, FaceCullMode.Off);
383 		layersToLoad = ic.readInt("layers-to=load", -1);
384 	}
385 
386 	@Override
hashCode()387 	public int hashCode() {
388 		final int prime = 31;
389 		int result = super.hashCode();
390 		result = prime * result + (assetRootPath == null ? 0 : assetRootPath.hashCode());
391 		result = prime * result + (defaultMaterial == null ? 0 : defaultMaterial.hashCode());
392 		result = prime * result + (faceCullMode == null ? 0 : faceCullMode.hashCode());
393 		result = prime * result + featuresToLoad;
394 		result = prime * result + (fixUpAxis ? 1231 : 1237);
395 		result = prime * result + fps;
396 		result = prime * result + generatedTextureDepth;
397 		result = prime * result + generatedTextureHeight;
398 		result = prime * result + generatedTextureWidth;
399 		result = prime * result + layersToLoad;
400 		result = prime * result + (loadUnlinkedAssets ? 1231 : 1237);
401 		result = prime * result + (usedWorld == null ? 0 : usedWorld.hashCode());
402 		return result;
403 	}
404 
405 	@Override
equals(Object obj)406 	public boolean equals(Object obj) {
407 		if (this == obj) {
408 			return true;
409 		}
410 		if (!super.equals(obj)) {
411 			return false;
412 		}
413 		if (this.getClass() != obj.getClass()) {
414 			return false;
415 		}
416 		BlenderKey other = (BlenderKey) obj;
417 		if (assetRootPath == null) {
418 			if (other.assetRootPath != null) {
419 				return false;
420 			}
421 		} else if (!assetRootPath.equals(other.assetRootPath)) {
422 			return false;
423 		}
424 		if (defaultMaterial == null) {
425 			if (other.defaultMaterial != null) {
426 				return false;
427 			}
428 		} else if (!defaultMaterial.equals(other.defaultMaterial)) {
429 			return false;
430 		}
431 		if (faceCullMode != other.faceCullMode) {
432 			return false;
433 		}
434 		if (featuresToLoad != other.featuresToLoad) {
435 			return false;
436 		}
437 		if (fixUpAxis != other.fixUpAxis) {
438 			return false;
439 		}
440 		if (fps != other.fps) {
441 			return false;
442 		}
443 		if (generatedTextureDepth != other.generatedTextureDepth) {
444 			return false;
445 		}
446 		if (generatedTextureHeight != other.generatedTextureHeight) {
447 			return false;
448 		}
449 		if (generatedTextureWidth != other.generatedTextureWidth) {
450 			return false;
451 		}
452 		if (layersToLoad != other.layersToLoad) {
453 			return false;
454 		}
455 		if (loadUnlinkedAssets != other.loadUnlinkedAssets) {
456 			return false;
457 		}
458 		if (usedWorld == null) {
459 			if (other.usedWorld != null) {
460 				return false;
461 			}
462 		} else if (!usedWorld.equals(other.usedWorld)) {
463 			return false;
464 		}
465 		return true;
466 	}
467 
468 	/**
469 	 * This interface describes the features of the scene that are to be loaded.
470 	 * @author Marcin Roguski (Kaelthas)
471 	 */
472 	public static interface FeaturesToLoad {
473 
474 		int	SCENES		= 0x0000FFFF;
475 		int	OBJECTS		= 0x0000000B;
476 		int	ANIMATIONS	= 0x00000004;
477 		int	MATERIALS	= 0x00000003;
478 		int	TEXTURES	= 0x00000001;
479 		int	CAMERAS		= 0x00000020;
480 		int	LIGHTS		= 0x00000010;
481 		int	ALL			= 0xFFFFFFFF;
482 	}
483 
484 	/**
485 	 * This class holds the loading results according to the given loading flag.
486 	 * @author Marcin Roguski (Kaelthas)
487 	 */
488 	public static class LoadingResults extends Spatial {
489 
490 		/** Bitwise mask of features that are to be loaded. */
491 		private final int		featuresToLoad;
492 		/** The scenes from the file. */
493 		private List<Node>		scenes;
494 		/** Objects from all scenes. */
495 		private List<Node>		objects;
496 		/** Materials from all objects. */
497 		private List<Material>	materials;
498 		/** Textures from all objects. */
499 		private List<Texture>	textures;
500 		/** Animations of all objects. */
501 		private List<AnimData>	animations;
502 		/** All cameras from the file. */
503 		private List<Camera>	cameras;
504 		/** All lights from the file. */
505 		private List<Light>		lights;
506 
507 		/**
508 		 * Private constructor prevents users to create an instance of this class from outside the
509 		 * @param featuresToLoad
510 		 *        bitwise mask of features that are to be loaded
511 		 * @see FeaturesToLoad FeaturesToLoad
512 		 */
LoadingResults(int featuresToLoad)513 		private LoadingResults(int featuresToLoad) {
514 			this.featuresToLoad = featuresToLoad;
515 			if ((featuresToLoad & FeaturesToLoad.SCENES) != 0) {
516 				scenes = new ArrayList<Node>();
517 			}
518 			if ((featuresToLoad & FeaturesToLoad.OBJECTS) != 0) {
519 				objects = new ArrayList<Node>();
520 				if ((featuresToLoad & FeaturesToLoad.MATERIALS) != 0) {
521 					materials = new ArrayList<Material>();
522 					if ((featuresToLoad & FeaturesToLoad.TEXTURES) != 0) {
523 						textures = new ArrayList<Texture>();
524 					}
525 				}
526 				if ((featuresToLoad & FeaturesToLoad.ANIMATIONS) != 0) {
527 					animations = new ArrayList<AnimData>();
528 				}
529 			}
530 			if ((featuresToLoad & FeaturesToLoad.CAMERAS) != 0) {
531 				cameras = new ArrayList<Camera>();
532 			}
533 			if ((featuresToLoad & FeaturesToLoad.LIGHTS) != 0) {
534 				lights = new ArrayList<Light>();
535 			}
536 		}
537 
538 		/**
539 		 * This method returns a bitwise flag describing what features of the blend file will be included in the result.
540 		 * @return bitwise mask of features that are to be loaded
541 		 * @see FeaturesToLoad FeaturesToLoad
542 		 */
getLoadedFeatures()543 		public int getLoadedFeatures() {
544 			return featuresToLoad;
545 		}
546 
547 		/**
548 		 * This method adds a scene to the result set.
549 		 * @param scene
550 		 *        scene to be added to the result set
551 		 */
addScene(Node scene)552 		public void addScene(Node scene) {
553 			if (scenes != null) {
554 				scenes.add(scene);
555 			}
556 		}
557 
558 		/**
559 		 * This method adds an object to the result set.
560 		 * @param object
561 		 *        object to be added to the result set
562 		 */
addObject(Node object)563 		public void addObject(Node object) {
564 			if (objects != null) {
565 				objects.add(object);
566 			}
567 		}
568 
569 		/**
570 		 * This method adds a material to the result set.
571 		 * @param material
572 		 *        material to be added to the result set
573 		 */
addMaterial(Material material)574 		public void addMaterial(Material material) {
575 			if (materials != null) {
576 				materials.add(material);
577 			}
578 		}
579 
580 		/**
581 		 * This method adds a texture to the result set.
582 		 * @param texture
583 		 *        texture to be added to the result set
584 		 */
addTexture(Texture texture)585 		public void addTexture(Texture texture) {
586 			if (textures != null) {
587 				textures.add(texture);
588 			}
589 		}
590 
591 		/**
592 		 * This method adds a camera to the result set.
593 		 * @param camera
594 		 *        camera to be added to the result set
595 		 */
addCamera(Camera camera)596 		public void addCamera(Camera camera) {
597 			if (cameras != null) {
598 				cameras.add(camera);
599 			}
600 		}
601 
602 		/**
603 		 * This method adds a light to the result set.
604 		 * @param light
605 		 *        light to be added to the result set
606 		 */
607 		@Override
addLight(Light light)608 		public void addLight(Light light) {
609 			if (lights != null) {
610 				lights.add(light);
611 			}
612 		}
613 
614 		/**
615 		 * This method returns all loaded scenes.
616 		 * @return all loaded scenes
617 		 */
getScenes()618 		public List<Node> getScenes() {
619 			return scenes;
620 		}
621 
622 		/**
623 		 * This method returns all loaded objects.
624 		 * @return all loaded objects
625 		 */
getObjects()626 		public List<Node> getObjects() {
627 			return objects;
628 		}
629 
630 		/**
631 		 * This method returns all loaded materials.
632 		 * @return all loaded materials
633 		 */
getMaterials()634 		public List<Material> getMaterials() {
635 			return materials;
636 		}
637 
638 		/**
639 		 * This method returns all loaded textures.
640 		 * @return all loaded textures
641 		 */
getTextures()642 		public List<Texture> getTextures() {
643 			return textures;
644 		}
645 
646 		/**
647 		 * This method returns all loaded animations.
648 		 * @return all loaded animations
649 		 */
getAnimations()650 		public List<AnimData> getAnimations() {
651 			return animations;
652 		}
653 
654 		/**
655 		 * This method returns all loaded cameras.
656 		 * @return all loaded cameras
657 		 */
getCameras()658 		public List<Camera> getCameras() {
659 			return cameras;
660 		}
661 
662 		/**
663 		 * This method returns all loaded lights.
664 		 * @return all loaded lights
665 		 */
getLights()666 		public List<Light> getLights() {
667 			return lights;
668 		}
669 
670 		@Override
collideWith(Collidable other, CollisionResults results)671 		public int collideWith(Collidable other, CollisionResults results) throws UnsupportedCollisionException {
672 			return 0;
673 		}
674 
675 		@Override
updateModelBound()676 		public void updateModelBound() {}
677 
678 		@Override
setModelBound(BoundingVolume modelBound)679 		public void setModelBound(BoundingVolume modelBound) {}
680 
681 		@Override
getVertexCount()682 		public int getVertexCount() {
683 			return 0;
684 		}
685 
686 		@Override
getTriangleCount()687 		public int getTriangleCount() {
688 			return 0;
689 		}
690 
691 		@Override
deepClone()692 		public Spatial deepClone() {
693 			return null;
694 		}
695 
696 		@Override
depthFirstTraversal(SceneGraphVisitor visitor)697 		public void depthFirstTraversal(SceneGraphVisitor visitor) {}
698 
699 		@Override
breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue)700 		protected void breadthFirstTraversal(SceneGraphVisitor visitor, Queue<Spatial> queue) {}
701 	}
702 
703 	/**
704 	 * The WORLD file block contains various data that could be added to the scene. The contained data includes: ambient
705 	 * light.
706 	 * @author Marcin Roguski (Kaelthas)
707 	 */
708 	public static class WorldData {
709 
710 		/** The ambient light. */
711 		private AmbientLight	ambientLight;
712 
713 		/**
714 		 * This method returns the world's ambient light.
715 		 * @return the world's ambient light
716 		 */
getAmbientLight()717 		public AmbientLight getAmbientLight() {
718 			return ambientLight;
719 		}
720 
721 		/**
722 		 * This method sets the world's ambient light.
723 		 * @param ambientLight
724 		 *        the world's ambient light
725 		 */
setAmbientLight(AmbientLight ambientLight)726 		public void setAmbientLight(AmbientLight ambientLight) {
727 			this.ambientLight = ambientLight;
728 		}
729 	}
730 }
731