Package org.jdesktop.wonderland.modules.avatarbase.client.imi

Source Code of org.jdesktop.wonderland.modules.avatarbase.client.imi.WonderlandCharacterParams$GenderConfigElement

/**
* Project Wonderland
*
* Copyright (c) 2004-2009, Sun Microsystems, Inc., All Rights Reserved
*
* Redistributions in source code form must reproduce the above
* copyright and this condition.
*
* The contents of this file are subject to the GNU General Public
* License, Version 2 (the "License"); you may not use this file
* except in compliance with the License. A copy of the License is
* available at http://www.opensource.org/licenses/gpl-license.php.
*
* Sun designates this particular file as subject to the "Classpath"
* exception as provided by Sun in the License file that accompanied
* this code.
*/
package org.jdesktop.wonderland.modules.avatarbase.client.imi;

import imi.character.AttachmentParams;
import imi.character.CharacterParams;
import imi.character.CharacterParams.SkinnedMeshParams;
import imi.scene.PMatrix;
import java.awt.Color;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import org.jdesktop.wonderland.modules.avatarbase.client.imi.WonderlandCharacterParams.ConfigElement;
import org.jdesktop.wonderland.modules.avatarbase.client.imi.WonderlandCharacterParams.GenderConfigElement;

/**
* Avatar attributes for generating Wonderland avatars.
*
* @author jkaplan
* @author Jordasn Slott <jslott@dev.java.net>
*/
public class WonderlandCharacterParams implements Cloneable {
    private static final Logger logger =
            Logger.getLogger(WonderlandCharacterParams.class.getName());

    // The configuration URL used to load the preset information
    private URL configURL = null;

    // Pointers to the XML files that define the various avatar configurations
    // available.
    private static final String MALE_CONFIGS   = "resources/male-configs-binary.xml";
    private static final String FEMALE_CONFIGS = "resources/female-configs-binary.xml";

    public enum ConfigType {
        GENDER, HAIR, HAIR_COLOR, HEAD, SKIN_COLOR, TORSO,
        SHIRT_COLOR, JACKET, HANDS, LEGS, PANTS_COLOR, FEET,
        SHOE_COLOR
    };

    // Default preset selections for the Male avatar configuration
    private static final Map<ConfigType, String> DEFAULT_MALE_PRESETS = new HashMap();
    static {
        DEFAULT_MALE_PRESETS.put(ConfigType.HAIR, "Male_ChinLengthPartLeftShape");
        DEFAULT_MALE_PRESETS.put(ConfigType.HEAD, "Male C Head");
        DEFAULT_MALE_PRESETS.put(ConfigType.TORSO, "T Shirt");
        DEFAULT_MALE_PRESETS.put(ConfigType.JACKET, "No Jacket");
        DEFAULT_MALE_PRESETS.put(ConfigType.HANDS, "Hands");
        DEFAULT_MALE_PRESETS.put(ConfigType.LEGS, "Jeans");
        DEFAULT_MALE_PRESETS.put(ConfigType.FEET, "Tennis Shoes");
    }

    // Default colors selections for the Male avatar configuration
    private static final Map<ConfigType, Color> DEFAULT_MALE_COLORS = new HashMap();
    static {
        DEFAULT_MALE_COLORS.put(ConfigType.HAIR_COLOR, new Color(183, 100, 42));
        DEFAULT_MALE_COLORS.put(ConfigType.SHIRT_COLOR, new Color(204, 204, 255));
        DEFAULT_MALE_COLORS.put(ConfigType.PANTS_COLOR, new Color(102, 102, 255));
        DEFAULT_MALE_COLORS.put(ConfigType.SHOE_COLOR, new Color(200, 93, 0));
    }

    // Default preset selections for the Female avatar configuration
    private static final Map<ConfigType, String> DEFAULT_FEMALE_PRESETS = new HashMap();
    static {
        DEFAULT_FEMALE_PRESETS.put(ConfigType.HAIR, "Layered_bangShape");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.HEAD, "Female C Head");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.TORSO, "T Shirt");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.JACKET, "No Jacket");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.HANDS, "Hands");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.LEGS, "Jeans");
        DEFAULT_FEMALE_PRESETS.put(ConfigType.FEET, "Converse");
    }

    // Default colors selections for the Female avatar configuration
    private static final Map<ConfigType, Color> DEFAULT_FEMALE_COLORS = new HashMap();
    static {
        DEFAULT_FEMALE_COLORS.put(ConfigType.HAIR_COLOR, new Color(183, 100, 42));
        DEFAULT_FEMALE_COLORS.put(ConfigType.SHIRT_COLOR, new Color(204, 204, 255));
        DEFAULT_FEMALE_COLORS.put(ConfigType.PANTS_COLOR, new Color(102, 102, 255));
        DEFAULT_FEMALE_COLORS.put(ConfigType.SHOE_COLOR, new Color(200, 93, 0));
    }

    private final Map<ConfigType, List<ConfigElement>> allElements =
            new EnumMap<ConfigType, List<ConfigElement>>(ConfigType.class);
    private final Map<ConfigType, ConfigElement> elements =
            new EnumMap<ConfigType, ConfigElement>(ConfigType.class);

    // A set of key-value meta-data for the
    // The JAXB context to (un)marshall (from)to XML
    private static JAXBContext jaxbContext = null;
    static {
        try {
            jaxbContext = JAXBContext.newInstance(ConfigList.class);
        } catch (javax.xml.bind.JAXBException excp) {
            logger.log(Level.WARNING, "Error creating JAXB context", excp);
        }
    }

    public WonderlandCharacterParams(URL configURL) {
        this.configURL = configURL;
        loadConfig(configURL);
    }

    public static WonderlandCharacterParams loadMale() throws IOException {
        // Load the male configuration file and instantiate a params object
        URL maleURL = WonderlandCharacterParams.class.getResource(MALE_CONFIGS);
        WonderlandCharacterParams params = new WonderlandCharacterParams(maleURL);

        // Set the default male presets
        for (ConfigType type : DEFAULT_MALE_PRESETS.keySet()) {
            params.setElementPreset(type, DEFAULT_MALE_PRESETS.get(type));
        }

        // Set the default male colors
        for (ConfigType type : DEFAULT_MALE_COLORS.keySet()) {
            params.setElementColor(type, DEFAULT_MALE_COLORS.get(type));
        }
        return params;
    }

    public static WonderlandCharacterParams loadFemale() throws IOException {
        // Load the female configuration file and instantiate a params object
        URL femaleURL = WonderlandCharacterParams.class.getResource(FEMALE_CONFIGS);
        WonderlandCharacterParams params = new WonderlandCharacterParams(femaleURL);

        // Set the default female presets
        for (ConfigType type : DEFAULT_FEMALE_PRESETS.keySet()) {
            params.setElementPreset(type, DEFAULT_FEMALE_PRESETS.get(type));
        }

        // Set the default female colors
        for (ConfigType type : DEFAULT_FEMALE_COLORS.keySet()) {
            params.setElementColor(type, DEFAULT_FEMALE_COLORS.get(type));
        }
        return params;
    }

    /**
     * Returns the IMI avatar character params that correspond to the current
     * settings.
     *
     * @return A CharacterParms
     */
    @XmlTransient
    public CharacterParams getCharacterParams() {
        // Take all of the configuration elements and apply them to the params
        CharacterParams out = new CharacterParams();
        for (ConfigElement element : getElements()) {
            element.apply(out);
        }

        return out;
    }

    /**
     * Takes a set of IMI character parameters and updates the settings in this
     * set of attributes according to the presets stored in the given params.
     *
     * @param A CharacterParams
     */
    public void setCharacterParams(CharacterParams params) {
        // For all of the config type elements that use presets, take from
        // the IMI character params and set as elements in the settings here
        setAsPreset(params, ConfigType.HEAD);
        setAsPreset(params, ConfigType.HAIR);
        setAsPreset(params, ConfigType.TORSO);
        setAsPreset(params, ConfigType.JACKET);
        setAsPreset(params, ConfigType.HANDS);
        setAsPreset(params, ConfigType.LEGS);
        setAsPreset(params, ConfigType.FEET);
        setAsPreset(params, ConfigType.HANDS);

        // Set the colors
        setAsColor(params, ConfigType.HAIR_COLOR);
        setAsColor(params, ConfigType.PANTS_COLOR);
        setAsColor(params, ConfigType.SHIRT_COLOR);
        setAsColor(params, ConfigType.SHOE_COLOR);
        setAsColor(params, ConfigType.SKIN_COLOR);
    }

    /**
     * A utility routine to fetch the preset from the IMI character params meta
     * data and set the config element in this set of attributes.
     */
    private void setAsPreset(CharacterParams params, ConfigType type) {
        String presetName = params.getMetaData().get(type.toString());
        if (presetName == null) {
            logger.warning("No preset found for config type " + type);
            setElement(type, 0);
            return;
        }

        int index = setElementPreset(type, presetName);
        if (index == -1) {
            logger.warning("Preset for config type " + type + " is not in " +
                    "set of config elements " + presetName);
            setElement(type, 0);
            return;
        }
        logger.info("For config type " + type + ", using preset " + presetName);
    }

    /**
     * A utility routine to fetch the color from the IMI character params meta
     * data and set the config element in this set of attributes.
     */
    private void setAsColor(CharacterParams params, ConfigType type) {
        String colorString = params.getMetaData().get(type.toString());
        if (colorString == null) {
            logger.warning("No color found for config type " + type);
            return;
        }

        // The color string is of the format RRR GGG BBB where the values are
        // between 0 - 255 for each color component.
        String rgb[] = colorString.split(" ");
        float r = (float)Integer.parseInt(rgb[0]) / 255.0f;
        float g = (float)Integer.parseInt(rgb[1]) / 255.0f;
        float b = (float)Integer.parseInt(rgb[2]) / 255.0f;

        logger.info("For color type " + type + ", using color " + r + " " +
                g + " " + b);

        ColorConfigElement e = null;
        switch (type) {
            case HAIR_COLOR:
                e = new HairColorConfigElement();
                e.setRGB(r, g, b);
                break;

            case PANTS_COLOR:
                e = new PantsColorConfigElement();
                e.setRGB(r, g, b);
                break;

            case SHIRT_COLOR:
                e = new ShirtColorConfigElement();
                e.setRGB(r, g, b);
                break;

            case SHOE_COLOR:
                e = new ShoeColorConfigElement();
                e.setRGB(r, g, b);
                break;

            case SKIN_COLOR:
                e = new SkinColorConfigElement();
                e.setRGB(r, g, b);
                break;

            default:
                break;
        }

        if (e != null) {
            setElement(type, e);
        }
    }

    @XmlTransient
    public Collection<ConfigElement> getElements() {
        return elements.values();
    }

    public ConfigElement getElement(ConfigType type) {
        return elements.get(type);
    }

    /**
     * Returns the index in the list of the currently selected configuration
     * element for a particular element type.
     *
     * @param type The configuration element type
     * @return The index in the list of all elements
     */
    public int getElementIndex(ConfigType type) {
        ConfigElement ce = getElement(type);
        List<ConfigElement> el = getElements(type);
        return el.indexOf(ce);
    }

    public ConfigElement getElement(ConfigType type, int index) {
        List<ConfigElement> el = getElements(type);
        return el.get(index);
    }

    public void setElement(ConfigType type, int index) {
        List<ConfigElement> el = getElements(type);
        ConfigElement ce = el.get(index);
        elements.put(type, ce);
    }

    public void setElement(ConfigType type, ConfigElement element) {
        elements.put(type, element);
    }

    /**
     * Sets the current element preset given the configuration type and the
     * name of the present. Returns the index of the element set, or -1 if
     * the preset name did not exist.
     *
     * @param type The configuration element type
     * @param name The name given to the preset
     * @return The index of the preset, or -1 if it does not exist
     */
    public int setElementPreset(ConfigType type, String presetName) {
        // Loop through all of the elements for the type. If we found one
        // then set it and return the index.
        int i = 0;
        for (ConfigElement ce : getElements(type)) {
            if (presetName.equals(ce.getName()) == true) {
                setElement(type, ce);
                return i;
            }
            i++;
        }

        // If we've reached here, it means we did not find the preset name in
        // the configuration list, so we return -1
        return -1;
    }

    /**
     * Sets the current element color given the configuration type and the
     * Color. If the element is not a color, this method does nothing.
     *
     * @param type The configuration element type
     * @param color The color of the configuration element
     */
    public void setElementColor(ConfigType type, Color color) {
        switch (type) {
            case HAIR_COLOR:
                ColorConfigElement hair = new HairColorConfigElement();
                hair.setColor(color);
                setElement(type, hair);
                break;

            case PANTS_COLOR:
                ColorConfigElement pants = new PantsColorConfigElement();
                pants.setColor(color);
                setElement(type, pants);
                break;

            case SHIRT_COLOR:
                ColorConfigElement shirt = new ShirtColorConfigElement();
                shirt.setColor(color);
                setElement(type, shirt);
                break;

            case SHOE_COLOR:
                ColorConfigElement shoe = new ShoeColorConfigElement();
                shoe.setColor(color);
                setElement(type, shoe);
                break;

            case SKIN_COLOR:
                ColorConfigElement skin = new SkinColorConfigElement();
                skin.setColor(color);
                setElement(type, skin);
                break;

            default:
                // Do nothing
                break;
        }
    }
   
    public int getElementCount(ConfigType type) {
        return getElements(type).size();
    }

    public List<ConfigElement> getElements(ConfigType type) {
        List<ConfigElement> el = allElements.get(type);
        if (el == null) {
            el = Collections.emptyList();
        }

        return el;
    }

    /**
     * Randomizes the settings for this set of character parameters.
     */
    public void randomize() {
        for (ConfigType type : ConfigType.values()) {
            List<ConfigElement> el = getElements(type);
            if (el.size() > 0) {
                int rand = (int) (Math.random() * 100) % el.size();
                setElement(type, rand);
            }
        }

        // XXX What about randomizing the colors?
    }

    /**
     * Make a deep copy of this object.
     *
     * @return A clone of this object
     */
    @Override
    public WonderlandCharacterParams clone() {
        // Create a new object, since we give it a configURL, it will re-load
        // the 'allElements' map
        WonderlandCharacterParams attributes = new WonderlandCharacterParams(configURL);

        // Make a copy of the currently-set elements
        for (ConfigType type : elements.keySet()) {
            attributes.elements.put(type, elements.get(type).clone(null));
        }

        return attributes;
    }

    /**
     * Loads the configuration (the set of available presets) from a URL that
     * points to an XML configuration file.
     *
     * @param configURL The URL of an XML configuration file
     */
    protected void loadConfig(URL configURL) {
        // First clear the list of existing avatar presets
        allElements.clear();

        // Sort based upon the description of the present (rather than the name)
        // since it is the description that appears in the list.
        Comparator comparator = new Comparator() {
            public int compare(Object o1, Object o2) {
                ConfigElement c1 = (ConfigElement) o1;
                ConfigElement c2 = (ConfigElement) o2;
                return c1.getDescription().compareTo(c2.getDescription());
            }
        };

        // Attempt to load the configuration file, upon error log and return
        ConfigList config = null;
        try {
            config = ConfigList.decode(configURL.openStream());
        } catch (IOException ioe) {
            logger.log(Level.WARNING, "Error loading config from " + configURL, ioe);
            return;
        }

        allElements.put(ConfigType.GENDER, Arrays.asList((ConfigElement[]) config.getGenders()));

        // Add all of the HEAD elements, sorted alphabetically.
        List<ConfigElement> headList = Arrays.asList((ConfigElement[]) config.getHeads());
        Collections.sort(headList, comparator);
        allElements.put(ConfigType.HEAD, headList);

        // Add all of the HAIR elements, sorted alphabetically.
        List<ConfigElement> hairList = Arrays.asList((ConfigElement[]) config.getHair());
        Collections.sort(hairList, comparator);
        allElements.put(ConfigType.HAIR, hairList);

        // Add all of the TORSO elements, sorted alphabetically.
        List<ConfigElement> torsoList = Arrays.asList((ConfigElement[]) config.getTorsos());
        Collections.sort(torsoList, comparator);
        allElements.put(ConfigType.TORSO, torsoList);

        // Add all of the JACKET elements, sorted alphabetically.
        List<ConfigElement> jacketList = Arrays.asList((ConfigElement[]) config.getJackets());
        Collections.sort(jacketList, comparator);
        allElements.put(ConfigType.JACKET, jacketList);

        // Add all of the HANDS elements, sorted alphabetically.
        List<ConfigElement> handsList = Arrays.asList((ConfigElement[]) config.getHands());
        Collections.sort(handsList, comparator);
        allElements.put(ConfigType.HANDS, handsList);

        // Add all of the LEGS elements, sorted alphabetically.
        List<ConfigElement> legsList = Arrays.asList((ConfigElement[]) config.getLegs());
        Collections.sort(legsList, comparator);
        allElements.put(ConfigType.LEGS, legsList);

        // Add all of the FEET elements, sorted alphabetically.
        List<ConfigElement> feetList = Arrays.asList((ConfigElement[]) config.getFeet());
        Collections.sort(feetList, comparator);
        allElements.put(ConfigType.FEET, feetList);

        // Load the first element of each type and a base-level default. Further
        // defaults are set depending upon whether it is a male or female.
        for (ConfigType type : ConfigType.values()) {
            List<ConfigElement> el = getElements(type);
            if (el.size() > 0) {
                setElement(type, 0);
            }
        }
    }

    /**
     * An abstract base class that represents some preset for an avatar. Each
     * has a name, which is unique within the same kind of preset.
     */
    public static abstract class ConfigElement {
        private String name;
        private String description;
        private URL previewImage;

        @XmlElement
        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        @XmlElement
        public String getDescription() {
            return description;
        }

        public void setDescription(String description) {
            this.description = description;
        }

        @XmlElement
        public URL getPreviewImage() {
            return previewImage;
        }

        public void setPreviewImage(URL previewImage) {
            this.previewImage = previewImage;
        }

        public abstract void apply(CharacterParams attrs);

        // compare ConfigElements by name.  Each element should have a unique
        // name.
        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final ConfigElement other = (ConfigElement) obj;
            if ((this.name == null) ? (other.name != null) : !this.name.equals(other.name)) {
                return false;
            }
            return true;
        }

        /**
         * {@inheritDoc}
         */
        @Override
        public int hashCode() {
            int hash = 7;
            hash = 31 * hash + (this.name != null ? this.name.hashCode() : 0);
            return hash;
        }

        /**
         * Clones this ConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        public ConfigElement clone(ConfigElement element) {
            element.name = name;
            element.description = description;
            element.previewImage = previewImage;
            return element;
        }
    }

    public static class GenderConfigElement extends ConfigElement {

        /** Enumeration of Gender types */
        public static final int MALE  = 1;
        public static final int FEMALE = 2;

        private int gender;

        @XmlElement
        public int getGender() {
            return gender;
        }

        public void setGender(int gender) {
            this.gender = gender;
        }

        @Override
        public void apply(CharacterParams attrs) {
            attrs.setGender(gender).setUsePhongLightingForHead(true);
        }

        /**
         * Clones this GenderConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new GenderConfigElement();
            }
            ((GenderConfigElement)element).gender = gender;
            return super.clone(element);
        }
    }

    public static abstract class ModelConfigElement extends ConfigElement {
        private String model;

        @XmlElement
        public String getModel() {
            return model;
        }

        public void setModel(String model) {
            this.model = model;
        }

        /**
         * Clones this ModelConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            element = super.clone(element);
            ((ModelConfigElement)element).model = model;
            return element;
        }
    }

    public static class HeadConfigElement extends ModelConfigElement {
        private SkinColorConfigElement skinTone;

        @XmlElement(name = "skin-tone")
        public SkinColorConfigElement getSkinTone() {
            return skinTone;
        }

        public void setSkinTone(SkinColorConfigElement skinTone) {
            this.skinTone = skinTone;
        }


        @Override
        public void apply(CharacterParams attrs) {
            attrs.setHeadAttachment(getModel());
            attrs.getMetaData().put(ConfigType.HEAD.toString(), getName());
            if (skinTone != null) {
                attrs.setSkinTone(skinTone.getR(), skinTone.getG(), skinTone.getB());
                attrs.setUsePhongLightingForHead(true);
            }
        }

        /**
         * Clones this HeadConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new HeadConfigElement();
            }

            if (skinTone != null) {
                ((HeadConfigElement) element).skinTone = (SkinColorConfigElement) skinTone.clone(null);
            }
            return super.clone(element);
        }
    }

    public static abstract class ShapesConfigElement extends ModelConfigElement {
        private String[] shapes;

        @XmlElement
        public String[] getShapes() {
            return shapes;
        }

        public void setShapes(String[] shapes) {
            this.shapes = shapes;
        }

        /**
         * Clones this ShapesConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (shapes != null) {
                ((ShapesConfigElement) element).shapes = new String[shapes.length];
                for (int i = 0; i < shapes.length; i++) {
                    ((ShapesConfigElement) element).shapes[i] = shapes[i];
                }
            }
            return super.clone(element);
        }
    }

    public static class HairConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            String model = getModel();
            if (model != null && model.equals("") == false) {
                attrs.addLoadInstruction(model);
                attrs.getMetaData().put(ConfigType.HAIR.toString(), getName());

                // Take the first shape as the mesh to use for the hair. We
                // assume there is at least one
                AttachmentParams params = new AttachmentParams(
                        getShapes()[0], // Mesh
                        "HairAttach", // Parent Joint
                        PMatrix.IDENTITY, // Orientation
                        "HairAttachmentJoint", // Attachment Joint Name
                        model);              // Owning File Name
                attrs.addAttachmentInstruction(params);
            }
        }

        /**
         * Clones this HairConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new HairConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class HandsConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // add hands
            attrs.addLoadInstruction(getModel());
            attrs.getMetaData().put(ConfigType.HANDS.toString(), getName());

            for (String shape : getShapes()) {
                attrs.addSkinnedMeshParams(new SkinnedMeshParams(shape, "Hands", getModel()));
            }
        }

        /**
         * Clones this HandsConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new HandsConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class TorsoConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            attrs.addLoadInstruction(getModel());
            attrs.getMetaData().put(ConfigType.TORSO.toString(), getName());

            for (String shape : getShapes())
                attrs.addSkinnedMeshParams(new SkinnedMeshParams(shape, "UpperBody", getModel()));
        }

        /**
         * Clones this TorsoConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new TorsoConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class JacketConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            if (getModel() == null) {
                return;
            }

            attrs.addLoadInstruction(getModel());
            attrs.getMetaData().put(ConfigType.JACKET.toString(), getName());

            for (String shape : getShapes()) {
                attrs.addSkinnedMeshParams(new SkinnedMeshParams(shape, "UpperBody", getModel()));
            }
        }

        /**
         * Clones this JacketConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new JacketConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class LegsConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            attrs.addLoadInstruction(getModel());
            attrs.getMetaData().put(ConfigType.LEGS.toString(), getName());

            for (String shape : getShapes()) {
                attrs.addSkinnedMeshParams(new SkinnedMeshParams(shape, "LowerBody", getModel()));
            }
        }

        /**
         * Clones this LegsConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new LegsConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class FeetConfigElement extends ShapesConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            attrs.addLoadInstruction(getModel());
            attrs.getMetaData().put(ConfigType.FEET.toString(), getName());

            for (String shape : getShapes()) {
                attrs.addSkinnedMeshParams(new SkinnedMeshParams(shape, "Feet", getModel()));
            }
        }

        /**
         * Clones this FeetConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new FeetConfigElement();
            }
            return super.clone(element);
        }
    }

    /**
     * Represents a configuration attributes that is an RGB color. Each color
     * component is a floating point between 0.0 and 1.0, inclusive.
     */
    public static abstract class ColorConfigElement extends ConfigElement {
        private float r;
        private float g;
        private float b;

        public void setRGB(float r, float g, float b) {
            this.r = r;
            this.g = g;
            this.b = b;
        }

        public void setColor(Color color) {
            float components[] = new float[3];
            color.getColorComponents(components);
            setR(components[0]);
            setG(components[1]);
            setB(components[2]);
        }

        @XmlElement
        public float getR() {
            return r;
        }

        public void setR(float r) {
            this.r = r;
        }

        @XmlElement
        public float getG() {
            return g;
        }

        public void setG(float g) {
            this.g = g;
        }

        @XmlElement
        public float getB() {
            return b;
        }

        public void setB(float b) {
            this.b = b;
        }

        /**
         * Clones this ColorConfigElement object, making a deep copy. Takes an
         * instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            element = super.clone(element);
            ((ColorConfigElement)element).r = r;
            ((ColorConfigElement)element).g = g;
            ((ColorConfigElement)element).b = b;
            return element;
        }
    }

    public static class SkinColorConfigElement extends ColorConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // XXX Settings the attributes does nothing XXX
//            attrs.setSkinTone(getR(), getG(), getB());

            String rgb = "" + (int) (getR() * 255) + " " + (int) (getG() * 255) +
                    " " + (int) (getB() * 255);
            attrs.getMetaData().put(ConfigType.SKIN_COLOR.toString(), rgb);
        }

        /**
         * Clones this SkinColorConfigElement object, making a deep copy. Takes
         * an instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new SkinColorConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class HairColorConfigElement extends ColorConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // XXX Settings the attributes does nothing XXX
//            attrs.setHairColor(getR(), getG(), getB());
            String rgb = "" + (int)(getR() * 255) + " " +(int)(getG() * 255) +
                    " " + (int)(getB() * 255);
            attrs.getMetaData().put(ConfigType.HAIR_COLOR.toString(), rgb);
        }

        /**
         * Clones this HairColorConfigElement object, making a deep copy. Takes
         * an instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new HairColorConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class ShirtColorConfigElement extends ColorConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // XXX Settings the attributes does nothing XXX
//            attrs.setShirtColor(getR(), getG(), getB(), 0f, 0f, 0f);

            String rgb = "" + (int) (getR() * 255) + " " + (int) (getG() * 255) +
                    " " + (int) (getB() * 255);
            attrs.getMetaData().put(ConfigType.SHIRT_COLOR.toString(), rgb);
        }

        /**
         * Clones this ShirtColorConfigElement object, making a deep copy. Takes
         * an instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new ShirtColorConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class PantsColorConfigElement extends ColorConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // XXX Settings the attributes does nothing XXX
//            attrs.setPantsColor(getR(), getG(), getB(), 0f, 0f, 0f);

            String rgb = "" + (int) (getR() * 255) + " " + (int) (getG() * 255) +
                    " " + (int) (getB() * 255);
            attrs.getMetaData().put(ConfigType.PANTS_COLOR.toString(), rgb);
        }

        /**
         * Clones this PantsColorConfigElement object, making a deep copy. Takes
         * an instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new PantsColorConfigElement();
            }
            return super.clone(element);
        }
    }

    public static class ShoeColorConfigElement extends ColorConfigElement {
        @Override
        public void apply(CharacterParams attrs) {
            // XXX Settings the attributes does nothing XXX
//            attrs.setShirtColor(getR(), getG(), getB(), 0f, 0f, 0f);

            String rgb = "" + (int) (getR() * 255) + " " + (int) (getG() * 255) +
                    " " + (int) (getB() * 255);
            attrs.getMetaData().put(ConfigType.SHOE_COLOR.toString(), rgb);
        }

        /**
         * Clones this ShoeColorConfigElement object, making a deep copy. Takes
         * an instance of the concrete class to be cloned, returns the cloned
         * objects.
         */
        @Override
        public ConfigElement clone(ConfigElement element) {
            if (element == null) {
                element = new ShoeColorConfigElement();
            }
            return super.clone(element);
        }
    }
   
    @XmlRootElement(name="config-list")
    public static class ConfigList {
        private GenderConfigElement[] genders = new GenderConfigElement[0];
        private HeadConfigElement[]   heads   = new HeadConfigElement[0];
        private HairConfigElement[]   hair    = new HairConfigElement[0];
        private TorsoConfigElement[]  torsos  = new TorsoConfigElement[0];
        private JacketConfigElement[] jackets = new JacketConfigElement[0];
        private HandsConfigElement[]  hands   = new HandsConfigElement[0];
        private LegsConfigElement[]   legs    = new LegsConfigElement[0];
        private FeetConfigElement[]   feet    = new FeetConfigElement[0];

        public GenderConfigElement[] getGenders() {
            return genders;
        }
       
        public void setGenders(GenderConfigElement[] genders) {
            this.genders = genders;
        }

        public HeadConfigElement[] getHeads() {
            return heads;
        }

        public void setHeads(HeadConfigElement[] heads) {
            this.heads = heads;
        }

        public HairConfigElement[] getHair() {
            return hair;
        }

        public void setHair(HairConfigElement[] hair) {
            this.hair = hair;
        }

        public TorsoConfigElement[] getTorsos() {
            return torsos;
        }

        public void setTorsos(TorsoConfigElement[] torsos) {
            this.torsos = torsos;
        }

        public JacketConfigElement[] getJackets() {
            return jackets;
        }

        public void setJackets(JacketConfigElement[] jackets) {
            this.jackets = jackets;
        }

        public HandsConfigElement[] getHands() {
            return hands;
        }

        public void setHands(HandsConfigElement[] hands) {
            this.hands = hands;
        }

        public FeetConfigElement[] getFeet() {
            return feet;
        }

        public void setFeet(FeetConfigElement[] feet) {
            this.feet = feet;
        }

        public LegsConfigElement[] getLegs() {
            return legs;
        }

        public void setLegs(LegsConfigElement[] legs) {
            this.legs = legs;
        }

        public static ConfigList decode(InputStream is) throws IOException {
            try {
                Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
                return (ConfigList) unmarshaller.unmarshal(is);
            } catch (JAXBException ex) {
                IOException ioe = new IOException("Unmarshalling error");
                ioe.initCause(ex);
                throw ioe;
            }
        }
    }
}
TOP

Related Classes of org.jdesktop.wonderland.modules.avatarbase.client.imi.WonderlandCharacterParams$GenderConfigElement

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.