AssetLinkNode.java 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185
  1. /*
  2. * Copyright (c) 2009-2010 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.scene;
  33. import com.jme3.asset.AssetInfo;
  34. import com.jme3.asset.AssetManager;
  35. import com.jme3.asset.ModelKey;
  36. import com.jme3.export.InputCapsule;
  37. import com.jme3.export.JmeExporter;
  38. import com.jme3.export.JmeImporter;
  39. import com.jme3.export.OutputCapsule;
  40. import com.jme3.export.binary.BinaryImporter;
  41. import com.jme3.util.SafeArrayList;
  42. import java.io.IOException;
  43. import java.util.*;
  44. import java.util.Map.Entry;
  45. import java.util.logging.Level;
  46. import java.util.logging.Logger;
  47. /**
  48. * The AssetLinkNode does not store its children when exported to file.
  49. * Instead, you can add a list of AssetKeys that will be loaded and attached
  50. * when the AssetLinkNode is restored.
  51. *
  52. * @author normenhansen
  53. */
  54. public class AssetLinkNode extends Node {
  55. protected ArrayList<ModelKey> assetLoaderKeys = new ArrayList<ModelKey>();
  56. protected Map<ModelKey, Spatial> assetChildren = new HashMap<ModelKey, Spatial>();
  57. public AssetLinkNode() {
  58. }
  59. public AssetLinkNode(ModelKey key) {
  60. this(key.getName(), key);
  61. }
  62. public AssetLinkNode(String name, ModelKey key) {
  63. super(name);
  64. assetLoaderKeys.add(key);
  65. }
  66. /**
  67. * Add a "linked" child. These are loaded from the assetManager when the
  68. * AssetLinkNode is loaded from a binary file.
  69. * @param key
  70. */
  71. public void addLinkedChild(ModelKey key) {
  72. if (assetLoaderKeys.contains(key)) {
  73. return;
  74. }
  75. assetLoaderKeys.add(key);
  76. }
  77. public void removeLinkedChild(ModelKey key) {
  78. assetLoaderKeys.remove(key);
  79. }
  80. public ArrayList<ModelKey> getAssetLoaderKeys() {
  81. return assetLoaderKeys;
  82. }
  83. public void attachLinkedChild(AssetManager manager, ModelKey key) {
  84. addLinkedChild(key);
  85. Spatial child = manager.loadAsset(key);
  86. assetChildren.put(key, child);
  87. attachChild(child);
  88. }
  89. public void attachLinkedChild(Spatial spat, ModelKey key) {
  90. addLinkedChild(key);
  91. assetChildren.put(key, spat);
  92. attachChild(spat);
  93. }
  94. public void detachLinkedChild(ModelKey key) {
  95. Spatial spatial = assetChildren.get(key);
  96. if (spatial != null) {
  97. detachChild(spatial);
  98. }
  99. removeLinkedChild(key);
  100. assetChildren.remove(key);
  101. }
  102. public void detachLinkedChild(Spatial child, ModelKey key) {
  103. removeLinkedChild(key);
  104. assetChildren.remove(key);
  105. detachChild(child);
  106. }
  107. /**
  108. * Loads the linked children AssetKeys from the AssetManager and attaches them to the Node<br>
  109. * If they are already attached, they will be reloaded.
  110. * @param manager
  111. */
  112. public void attachLinkedChildren(AssetManager manager) {
  113. detachLinkedChildren();
  114. for (Iterator<ModelKey> it = assetLoaderKeys.iterator(); it.hasNext();) {
  115. ModelKey assetKey = it.next();
  116. Spatial curChild = assetChildren.get(assetKey);
  117. if (curChild != null) {
  118. curChild.removeFromParent();
  119. }
  120. Spatial child = manager.loadAsset(assetKey);
  121. attachChild(child);
  122. assetChildren.put(assetKey, child);
  123. }
  124. }
  125. public void detachLinkedChildren() {
  126. Set<Entry<ModelKey, Spatial>> set = assetChildren.entrySet();
  127. for (Iterator<Entry<ModelKey, Spatial>> it = set.iterator(); it.hasNext();) {
  128. Entry<ModelKey, Spatial> entry = it.next();
  129. entry.getValue().removeFromParent();
  130. it.remove();
  131. }
  132. }
  133. @Override
  134. public void read(JmeImporter e) throws IOException {
  135. super.read(e);
  136. InputCapsule capsule = e.getCapsule(this);
  137. BinaryImporter importer = BinaryImporter.getInstance();
  138. AssetManager loaderManager = e.getAssetManager();
  139. assetLoaderKeys = (ArrayList<ModelKey>) capsule.readSavableArrayList("assetLoaderKeyList", new ArrayList<ModelKey>());
  140. for (Iterator<ModelKey> it = assetLoaderKeys.iterator(); it.hasNext();) {
  141. ModelKey modelKey = it.next();
  142. AssetInfo info = loaderManager.locateAsset(modelKey);
  143. Spatial child = null;
  144. if (info != null) {
  145. child = (Spatial) importer.load(info);
  146. }
  147. if (child != null) {
  148. child.parent = this;
  149. children.add(child);
  150. assetChildren.put(modelKey, child);
  151. } else {
  152. Logger.getLogger(this.getClass().getName()).log(Level.WARNING, "Cannot locate {0} for asset link node {1}",
  153. new Object[]{ modelKey, key });
  154. }
  155. }
  156. }
  157. @Override
  158. public void write(JmeExporter e) throws IOException {
  159. SafeArrayList<Spatial> childs = children;
  160. children = new SafeArrayList<Spatial>(Spatial.class);
  161. super.write(e);
  162. OutputCapsule capsule = e.getCapsule(this);
  163. capsule.writeSavableArrayList(assetLoaderKeys, "assetLoaderKeyList", null);
  164. children = childs;
  165. }
  166. }