Ejemplo n.º 1
0
  /**
   * Convert a <texture> element to an Ardor3D representation and store in the given state.
   *
   * @param mesh the Ardor3D Mesh to add the Texture to.
   * @param daeTexture our <texture> element
   * @param effect our <instance_effect> element
   * @return the created Texture.
   */
  private Texture populateTextureState(
      final Mesh mesh,
      final Element daeTexture,
      final Element effect,
      final HashMap<String, Texture> loadedTextures,
      final MaterialInfo info,
      String textureSlot) {
    // TODO: Use vert data to determine which texcoords and set to use.
    // final String uvName = daeTexture.getAttributeValue("texcoord");
    TextureState tState = (TextureState) mesh.getLocalRenderState(RenderState.StateType.Texture);
    if (tState == null) {
      tState = new TextureState();
      mesh.setRenderState(tState);
    }

    // Use texture attrib to find correct sampler
    final String textureReference = daeTexture.getAttributeValue("texture");
    if (textureSlot == null) {
      // if we have no texture slot defined (like in the case of an "extra" texture), we'll use the
      // textureReference.
      textureSlot = textureReference;
    }

    /* only add the texture to the state once */
    if (loadedTextures.containsKey(textureReference)) {
      final Texture tex = loadedTextures.get(textureReference);
      if (info != null) {
        info.setTextureSlot(textureSlot, textureReference, tex, null);
      }
      return tex;
    }

    Element node = _colladaDOMUtil.findTargetWithSid(textureReference);
    if (node == null) {
      // Not sure if this is quite right, but spec seems to indicate looking for global id
      node = _colladaDOMUtil.findTargetWithId("#" + textureReference);
    }

    if ("newparam".equals(node.getName())) {
      node = (Element) node.getChildren().get(0);
    }

    Element sampler = null;
    Element surface = null;
    Element image = null;

    Texture.MinificationFilter min = Texture.MinificationFilter.BilinearNoMipMaps;
    if ("sampler2D".equals(node.getName())) {
      sampler = node;
      if (sampler.getChild("minfilter") != null) {
        final String minfilter = sampler.getChild("minfilter").getText();
        min = Enum.valueOf(SamplerTypes.MinFilterType.class, minfilter).getArdor3dFilter();
      }
      // Use sampler to get correct surface
      node = _colladaDOMUtil.findTargetWithSid(sampler.getChild("source").getText());
      // node = resolveSid(effect, sampler.getSource());
    }

    if ("newparam".equals(node.getName())) {
      node = (Element) node.getChildren().get(0);
    }

    if ("surface".equals(node.getName())) {
      surface = node;
      // image(s) will come from surface.
    } else if ("image".equals(node.getName())) {
      image = node;
    }

    // Ok, a few possibilities here...
    Texture texture = null;
    String fileName = null;
    if (surface == null && image != null) {
      // Only an image found (no sampler). Assume 2d texture. Load.
      fileName = image.getChild("init_from").getText();
      texture = loadTexture2D(fileName, min);
    } else if (surface != null) {
      // We have a surface, pull images from that.
      if ("2D".equals(surface.getAttributeValue("type"))) {
        // look for an init_from with lowest mip and use that. (usually 0)

        // TODO: mip?
        final Element lowest = (Element) surface.getChildren("init_from").get(0);
        // Element lowest = null;
        // for (final Element i : (List<Element>) surface.getChildren("init_from")) {
        // if (lowest == null || lowest.getMip() > i.getMip()) {
        // lowest = i;
        // }
        // }

        if (lowest == null) {
          logger.warning("surface given with no usable init_from: " + surface);
          return null;
        }

        image = _colladaDOMUtil.findTargetWithId("#" + lowest.getText());
        // image = (DaeImage) root.resolveUrl("#" + lowest.getValue());
        if (image != null) {
          fileName = image.getChild("init_from").getText();
          texture = loadTexture2D(fileName, min);
        }

        // TODO: add support for mip map levels other than 0.
      }
      // TODO: add support for the other texture types.
    } else {
      // No surface OR image... warn.
      logger.warning("texture given with no matching <sampler*> or <image> found.");
      if (info != null) {
        info.setTextureSlot(textureSlot, textureReference, null, null);
      }
      return null;
    }

    if (texture != null) {
      if (sampler != null) {
        // Apply params from our sampler.
        applySampler(sampler, texture);
      }

      // Add to texture state.
      tState.setTexture(texture, tState.getNumberOfSetTextures());
      loadedTextures.put(textureReference, texture);
      if (info != null) {
        info.setTextureSlot(textureSlot, textureReference, texture, fileName);
      }
    } else {
      logger.warning("unable to load texture: " + daeTexture);
      if (info != null) {
        info.setTextureSlot(textureSlot, textureReference, null, fileName);
      }
    }

    return texture;
  }