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