Example #1
0
  public void setUserData(String key, Object data) {
    if (userData == null) {
      userData = new HashMap<String, Savable>();
    }

    if (data == null) {
      userData.remove(key);
    } else if (data instanceof Savable) {
      userData.put(key, (Savable) data);
    } else {
      userData.put(key, new UserData(UserData.getObjectType(data), data));
    }
  }
Example #2
0
  public Collection<String> getUserDataKeys() {
    if (userData != null) {
      return userData.keySet();
    }

    return Collections.EMPTY_SET;
  }
Example #3
0
  @SuppressWarnings("unchecked")
  public <T> T getUserData(String key) {
    if (userData == null) {
      return null;
    }

    Savable s = userData.get(key);
    if (s instanceof UserData) {
      return (T) ((UserData) s).getValue();
    } else {
      return (T) s;
    }
  }
Example #4
0
  /**
   * @return A clone of this Spatial, the scene graph in its entirety is cloned and can be altered
   *     independently of the original scene graph.
   *     <p>Note that meshes of geometries are not cloned explicitly, they are shared if static, or
   *     specially cloned if animated.
   *     <p>All controls will be cloned using the Control.cloneForSpatial method on the clone.
   * @see Mesh#cloneForAnim()
   */
  public Spatial clone(boolean cloneMaterial) {
    try {
      Spatial clone = (Spatial) super.clone();
      if (worldBound != null) {
        clone.worldBound = worldBound.clone();
      }
      clone.worldLights = worldLights.clone();
      clone.localLights = localLights.clone();

      // Set the new owner of the light lists
      clone.localLights.setOwner(clone);
      clone.worldLights.setOwner(clone);

      // No need to force cloned to update.
      // This node already has the refresh flags
      // set below so it will have to update anyway.
      clone.worldTransform = worldTransform.clone();
      clone.localTransform = localTransform.clone();

      if (clone instanceof Node) {
        Node node = (Node) this;
        Node nodeClone = (Node) clone;
        nodeClone.children = new SafeArrayList<Spatial>(Spatial.class);
        for (Spatial child : node.children) {
          Spatial childClone = child.clone(cloneMaterial);
          childClone.parent = nodeClone;
          nodeClone.children.add(childClone);
        }
      }

      clone.parent = null;
      clone.setBoundRefresh();
      clone.setTransformRefresh();
      clone.setLightListRefresh();

      clone.controls = new SafeArrayList<Control>(Control.class);
      for (int i = 0; i < controls.size(); i++) {
        Control newControl = controls.get(i).cloneForSpatial(clone);
        newControl.setSpatial(clone);
        clone.controls.add(newControl);
      }

      if (userData != null) {
        clone.userData = (HashMap<String, Savable>) userData.clone();
      }

      return clone;
    } catch (CloneNotSupportedException ex) {
      throw new AssertionError();
    }
  }
Example #5
0
  /**
   * Select the technique to use for rendering this material.
   *
   * <p>If <code>name</code> is "Default", then one of the {@link MaterialDef#getDefaultTechniques()
   * default techniques} on the material will be selected. Otherwise, the named technique will be
   * found in the material definition.
   *
   * <p>Any candidate technique for selection (either default or named) must be verified to be
   * compatible with the system, for that, the <code>renderManager</code> is queried for
   * capabilities.
   *
   * @param name The name of the technique to select, pass "Default" to select one of the default
   *     techniques.
   * @param renderManager The {@link RenderManager render manager} to query for capabilities.
   * @throws IllegalArgumentException If "Default" is passed and no default techniques are available
   *     on the material definition, or if a name is passed but there's no technique by that name.
   * @throws UnsupportedOperationException If no candidate technique supports the system
   *     capabilities.
   */
  public void selectTechnique(String name, RenderManager renderManager) {
    // check if already created
    Technique tech = techniques.get(name);
    // When choosing technique, we choose one that
    // supports all the caps.
    EnumSet<Caps> rendererCaps = renderManager.getRenderer().getCaps();
    if (tech == null) {

      if (name.equals("Default")) {
        List<TechniqueDef> techDefs = def.getDefaultTechniques();
        if (techDefs == null || techDefs.isEmpty()) {
          throw new IllegalArgumentException(
              "No default techniques are available on material '" + def.getName() + "'");
        }

        TechniqueDef lastTech = null;
        for (TechniqueDef techDef : techDefs) {
          if (rendererCaps.containsAll(techDef.getRequiredCaps())) {
            // use the first one that supports all the caps
            tech = new Technique(this, techDef);
            techniques.put(name, tech);
            break;
          }
          lastTech = techDef;
        }
        if (tech == null) {
          throw new UnsupportedOperationException(
              "No default technique on material '"
                  + def.getName()
                  + "'\n"
                  + " is supported by the video hardware. The caps "
                  + lastTech.getRequiredCaps()
                  + " are required.");
        }

      } else {
        // create "special" technique instance
        TechniqueDef techDef = def.getTechniqueDef(name);
        if (techDef == null) {
          throw new IllegalArgumentException(
              "For material " + def.getName() + ", technique not found: " + name);
        }

        if (!rendererCaps.containsAll(techDef.getRequiredCaps())) {
          throw new UnsupportedOperationException(
              "The explicitly chosen technique '"
                  + name
                  + "' on material '"
                  + def.getName()
                  + "'\n"
                  + "requires caps "
                  + techDef.getRequiredCaps()
                  + " which are not "
                  + "supported by the video renderer");
        }

        tech = new Technique(this, techDef);
        techniques.put(name, tech);
      }
    } else if (technique == tech) {
      // attempting to switch to an already
      // active technique.
      return;
    }

    technique = tech;
    tech.makeCurrent(def.getAssetManager(), true, rendererCaps);

    // shader was changed
    sortingId = -1;
  }
Example #6
0
  public void read(JmeImporter im) throws IOException {
    InputCapsule ic = im.getCapsule(this);

    additionalState = (RenderState) ic.readSavable("render_state", null);
    transparent = ic.readBoolean("is_transparent", false);

    // Load the material def
    String defName = ic.readString("material_def", null);
    HashMap<String, MatParam> params =
        (HashMap<String, MatParam>) ic.readStringSavableMap("parameters", null);

    boolean enableVcolor = false;
    boolean separateTexCoord = false;
    boolean applyDefaultValues = false;
    boolean guessRenderStateApply = false;

    int ver = ic.getSavableVersion(Material.class);
    if (ver < 1) {
      applyDefaultValues = true;
    }
    if (ver < 2) {
      guessRenderStateApply = true;
    }
    if (im.getFormatVersion() == 0) {
      // Enable compatibility with old models
      if (defName.equalsIgnoreCase("Common/MatDefs/Misc/VertexColor.j3md")) {
        // Using VertexColor, switch to Unshaded and set VertexColor=true
        enableVcolor = true;
        defName = "Common/MatDefs/Misc/Unshaded.j3md";
      } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/SimpleTextured.j3md")
          || defName.equalsIgnoreCase("Common/MatDefs/Misc/SolidColor.j3md")) {
        // Using SimpleTextured/SolidColor, just switch to Unshaded
        defName = "Common/MatDefs/Misc/Unshaded.j3md";
      } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/WireColor.j3md")) {
        // Using WireColor, set wireframe renderstate = true and use Unshaded
        getAdditionalRenderState().setWireframe(true);
        defName = "Common/MatDefs/Misc/Unshaded.j3md";
      } else if (defName.equalsIgnoreCase("Common/MatDefs/Misc/Unshaded.j3md")) {
        // Uses unshaded, ensure that the proper param is set
        MatParam value = params.get("SeperateTexCoord");
        if (value != null && ((Boolean) value.getValue()) == true) {
          params.remove("SeperateTexCoord");
          separateTexCoord = true;
        }
      }
      assert applyDefaultValues && guessRenderStateApply;
    }

    def = (MaterialDef) im.getAssetManager().loadAsset(new AssetKey(defName));
    paramValues = new ListMap<String, MatParam>();

    // load the textures and update nextTexUnit
    for (Map.Entry<String, MatParam> entry : params.entrySet()) {
      MatParam param = entry.getValue();
      if (param instanceof MatParamTexture) {
        MatParamTexture texVal = (MatParamTexture) param;

        if (nextTexUnit < texVal.getUnit() + 1) {
          nextTexUnit = texVal.getUnit() + 1;
        }

        // the texture failed to load for this param
        // do not add to param values
        if (texVal.getTextureValue() == null || texVal.getTextureValue().getImage() == null) {
          continue;
        }
      }

      if (im.getFormatVersion() == 0 && param.getName().startsWith("m_")) {
        // Ancient version of jME3 ...
        param.setName(param.getName().substring(2));
      }

      checkSetParam(param.getVarType(), param.getName());
      paramValues.put(param.getName(), param);
    }

    if (applyDefaultValues) {
      // compatability with old versions where default vars were
      // not available
      for (MatParam param : def.getMaterialParams()) {
        if (param.getValue() != null && paramValues.get(param.getName()) == null) {
          setParam(param.getName(), param.getVarType(), param.getValue());
        }
      }
    }
    if (guessRenderStateApply && additionalState != null) {
      // Try to guess values of "apply" render state based on defaults
      // if value != default then set apply to true
      additionalState.applyPolyOffset = additionalState.offsetEnabled;
      additionalState.applyAlphaFallOff = additionalState.alphaTest;
      additionalState.applyAlphaTest = additionalState.alphaTest;
      additionalState.applyBlendMode = additionalState.blendMode != BlendMode.Off;
      additionalState.applyColorWrite = !additionalState.colorWrite;
      additionalState.applyCullMode = additionalState.cullMode != FaceCullMode.Back;
      additionalState.applyDepthTest = !additionalState.depthTest;
      additionalState.applyDepthWrite = !additionalState.depthWrite;
      additionalState.applyPointSprite = additionalState.pointSprite;
      additionalState.applyStencilTest = additionalState.stencilTest;
      additionalState.applyWireFrame = additionalState.wireframe;
    }
    if (enableVcolor) {
      setBoolean("VertexColor", true);
    }
    if (separateTexCoord) {
      setBoolean("SeparateTexCoord", true);
    }
  }