Пример #1
0
  @Override
  public void startWalk(final Ray3 walkRay) {
    // store ray
    _walkRay.set(walkRay);

    // simplify access to direction
    final ReadOnlyVector3 direction = _walkRay.getDirection();

    // Move start point to grid space
    final Vector3 start = _walkRay.getOrigin().subtract(_gridOrigin, null);

    _gridLocation[0] = (int) MathUtils.floor(start.getX() / _gridSpacing.getX());
    _gridLocation[1] = (int) MathUtils.floor(start.getY() / _gridSpacing.getY());

    final double invDirX = 1.0 / direction.getX();
    final double invDirY = 1.0 / direction.getY();

    // Check which direction on the X world axis we are moving.
    if (direction.getX() > BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextXIntersection =
          ((_gridLocation[0] + 1) * _gridSpacing.getX() - start.getX()) * invDirX;
      _distBetweenXIntersections = _gridSpacing.getX() * invDirX;
      _stepXDirection = 1;
    } else if (direction.getX() < -BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextXIntersection =
          (start.getX() - _gridLocation[0] * _gridSpacing.getX()) * -direction.getX();
      _distBetweenXIntersections = -_gridSpacing.getX() * invDirX;
      _stepXDirection = -1;
    } else {
      _distToNextXIntersection = Double.MAX_VALUE;
      _distBetweenXIntersections = Double.MAX_VALUE;
      _stepXDirection = 0;
    }

    // Check which direction on the Y world axis we are moving.
    if (direction.getY() > BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextYIntersection =
          ((_gridLocation[1] + 1) * _gridSpacing.getY() - start.getY()) * invDirY;
      _distBetweenYIntersections = _gridSpacing.getY() * invDirY;
      _stepYDirection = 1;
    } else if (direction.getY() < -BresenhamZUpGridTracer.TOLERANCE) {
      _distToNextYIntersection =
          (start.getY() - _gridLocation[1] * _gridSpacing.getY()) * -direction.getY();
      _distBetweenYIntersections = -_gridSpacing.getY() * invDirY;
      _stepYDirection = -1;
    } else {
      _distToNextYIntersection = Double.MAX_VALUE;
      _distBetweenYIntersections = Double.MAX_VALUE;
      _stepYDirection = 0;
    }

    // Reset some variables
    _rayLocation.set(start);
    _totalTravel = 0.0;
    _stepDirection = Direction.None;
  }
Пример #2
0
  @Override
  public void applyFilter(final InteractManager manager) {
    final SpatialState state = manager.getSpatialState();
    final ReadOnlyVector3 scale = state.getTransform().getScale();
    final double x = MathUtils.clamp(scale.getX(), _minScale.getX(), _maxScale.getX());
    final double y = MathUtils.clamp(scale.getY(), _minScale.getY(), _maxScale.getY());
    final double z = MathUtils.clamp(scale.getZ(), _minScale.getZ(), _maxScale.getZ());

    state.getTransform().setScale(x, y, z);
  }
Пример #3
0
 public void set(final double radius, final double start, final double end) {
   final FloatBuffer buf = getMeshData().getVertexBuffer();
   buf.limit(buf.capacity());
   this.getMeshData().updateVertexCount();
   buf.rewind();
   double arc = end - start;
   final int n = buf.limit() / 3;
   for (int i = 0; i < n; i++) {
     double theta = start + arc / (n - 1) * i;
     float x = (float) (MathUtils.cos(theta) * radius);
     float y = (float) (MathUtils.sin(theta) * radius);
     buf.put(x).put(y).put(0);
   }
   getMeshData().updateVertexCount();
 }
Пример #4
0
  public double eval(final double x, final double y, final double z) {
    double value = 0, signal = 0, weight = 1;
    double dx = x * _frequency, dy = y * _frequency, dz = z * _frequency;
    for (int i = 0; i < _octaves; i++) {
      signal = _source.eval(dx, dy, dz);

      signal = Math.abs(signal);
      signal = _offset - signal;

      // Square the signal to increase the sharpness of the ridges.
      signal *= signal;

      // The weighting from the previous octave is applied to the signal.
      // Larger values have higher weights, producing sharp points along the
      // ridges.
      signal *= weight;

      // Weight successive contributions by the previous signal. (clamp to [0, 1])
      weight = MathUtils.clamp(signal * _gain, 0, 1);

      // Add the signal to the output value.
      value += signal * _spectralWeights[i];

      // Next!
      dx *= _lacunarity;
      dy *= _lacunarity;
      dz *= _lacunarity;
    }

    return (value * 1.25) - 1.0;
  }
  @Override
  protected void updateExample(final ReadOnlyTimer timer) {
    if (allowClicks && zoom) {
      if (index > COUNT - 1) {
        index = COUNT - 1;
      } else if (index < 0) {
        index = 0;
      }
      final int currentTile = MathUtils.floor(index);
      final float fract = index - currentTile;

      if (firstTile != currentTile - 1) {
        // update the textures on the tiles
        firstTile = MathUtils.floor(index - 1);

        for (int i = 0; i < views.length; i++) {
          if (firstTile + i >= 0 && firstTile + i < COUNT) {
            views[i].removeAllComponents();
            views[i].add(srcs[firstTile + i]);
            views[i].updateMinimumSizeFromContents();
            views[i].layout();
            views[i].setVisible(true);
          } else {
            views[i].setVisible(false);
          }
        }
      }

      // update the positions of the tiles.
      final int y = (_canvas.getCanvasRenderer().getCamera().getHeight() / 2) - (hside / 2);
      for (int i = 0; i < views.length; i++) {
        final float x = (i - fract) * (wside + padding);
        views[i].setHudXY(Math.round(x), y);
      }

      // check for and apply movement
      index += timer.getTimePerFrame() * speed;
    }

    // update hud input
    hud.updateGeometricState(timer.getTimePerFrame());
  }
  public LwjglPbufferTextureRenderer(
      final DisplaySettings settings,
      final Renderer parentRenderer,
      final ContextCapabilities caps) {
    super(settings, parentRenderer, caps);

    int pTarget = RenderTexture.RENDER_TEXTURE_2D;

    if (!MathUtils.isPowerOfTwo(_width) || !MathUtils.isPowerOfTwo(_height)) {
      pTarget = RenderTexture.RENDER_TEXTURE_RECTANGLE;
    }

    // signature: boolean useRGB, boolean useRGBA, boolean useDepth, boolean isRectangle, int
    // target, int mipmaps
    _texture =
        new RenderTexture(
            false, true, true, pTarget == RenderTexture.RENDER_TEXTURE_RECTANGLE, pTarget, 0);

    setMultipleTargets(false);
  }
Пример #7
0
  /**
   * Update the vertices for this particle, taking size, spin and viewer into consideration. In the
   * case of particle type ParticleType.GeomMesh, the original triangle normal is maintained rather
   * than rotating it to face the camera or parent vectors.
   *
   * @param cam Camera to use in determining viewer aspect. If null, or if parent is not set to
   *     camera facing, parent's left and up vectors are used.
   */
  public void updateVerts(final Camera cam) {
    final double orient = parent.getParticleOrientation() + values[VAL_CURRENT_SPIN];
    final double currSize = values[VAL_CURRENT_SIZE];

    if (type == ParticleSystem.ParticleType.GeomMesh
        || type == ParticleSystem.ParticleType.Point) {; // nothing to do
    } else if (cam != null && parent.isCameraFacing()) {
      final ReadOnlyVector3 camUp = cam.getUp();
      final ReadOnlyVector3 camLeft = cam.getLeft();
      final ReadOnlyVector3 camDir = cam.getDirection();
      if (parent.isVelocityAligned()) {
        bbX.set(_velocity).normalizeLocal().multiplyLocal(currSize);
        camDir.cross(bbX, bbY).normalizeLocal().multiplyLocal(currSize);
      } else if (orient == 0) {
        bbX.set(camLeft).multiplyLocal(currSize);
        bbY.set(camUp).multiplyLocal(currSize);
      } else {
        final double cA = MathUtils.cos(orient) * currSize;
        final double sA = MathUtils.sin(orient) * currSize;
        bbX.set(camLeft)
            .multiplyLocal(cA)
            .addLocal(camUp.getX() * sA, camUp.getY() * sA, camUp.getZ() * sA);
        bbY.set(camLeft)
            .multiplyLocal(-sA)
            .addLocal(camUp.getX() * cA, camUp.getY() * cA, camUp.getZ() * cA);
      }
    } else {
      bbX.set(parent.getLeftVector()).multiplyLocal(0);
      bbY.set(parent.getUpVector()).multiplyLocal(0);
    }

    final Vector3 tempVec3 = Vector3.fetchTempInstance();
    final FloatBuffer vertexBuffer = parent.getParticleGeometry().getMeshData().getVertexBuffer();
    switch (type) {
      case Quad:
        {
          _position.subtract(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.subtract(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).addLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 3);
          break;
        }
      case GeomMesh:
        {
          final Quaternion tempQuat = Quaternion.fetchTempInstance();
          final ReadOnlyVector3 norm = triModel.getNormal();
          if (orient != 0) {
            tempQuat.fromAngleNormalAxis(orient, norm);
          }

          for (int x = 0; x < 3; x++) {
            if (orient != 0) {
              tempQuat.apply(triModel.get(x), tempVec3);
            } else {
              tempVec3.set(triModel.get(x));
            }
            tempVec3.multiplyLocal(currSize).addLocal(_position);
            BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + x);
          }
          Quaternion.releaseTempInstance(tempQuat);
          break;
        }
      case Triangle:
        {
          _position
              .subtract(3 * bbX.getX(), 3 * bbX.getY(), 3 * bbX.getZ(), tempVec3)
              .subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 0);

          _position.add(bbX, tempVec3).addLocal(3 * bbY.getX(), 3 * bbY.getY(), 3 * bbY.getZ());
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);

          _position.add(bbX, tempVec3).subtractLocal(bbY);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 2);
          break;
        }
      case Line:
        {
          _position.subtract(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex);

          _position.add(bbX, tempVec3);
          BufferUtils.setInBuffer(tempVec3, vertexBuffer, startIndex + 1);
          break;
        }
      case Point:
        {
          BufferUtils.setInBuffer(_position, vertexBuffer, startIndex);
          break;
        }
    }
    Vector3.releaseTempInstance(tempVec3);
  }
Пример #8
0
  private void setGeometryData() {
    final FloatBuffer verts = _meshData.getVertexBuffer();
    final FloatBuffer norms = _meshData.getNormalBuffer();
    final FloatBuffer texs = _meshData.getTextureBuffer(0);
    verts.rewind();
    norms.rewind();
    texs.rewind();

    // generate geometry
    final double inverseRadial = 1.0 / radialSamples;
    final double inverseSphere = 1.0 / sphereSamples;
    final double halfHeight = 0.5 * height;

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    final double[] sin = new double[radialSamples + 1];
    final double[] cos = new double[radialSamples + 1];

    for (int radialCount = 0; radialCount < radialSamples; radialCount++) {
      final double angle = MathUtils.TWO_PI * inverseRadial * radialCount;
      cos[radialCount] = MathUtils.cos(angle);
      sin[radialCount] = MathUtils.sin(angle);
    }
    sin[radialSamples] = sin[0];
    cos[radialSamples] = cos[0];

    final Vector3 tempA = new Vector3();

    // top point.
    verts.put(0).put((float) (radius + halfHeight)).put(0);
    norms.put(0).put(1).put(0);
    texs.put(1).put(1);

    // generating the top dome.
    for (int i = 0; i < sphereSamples; i++) {
      final double center = radius * (1 - (i + 1) * (inverseSphere));
      final double lengthFraction = (center + height + radius) / (height + 2 * radius);

      // compute radius of slice
      final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center));

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(fSliceRadius);
        verts.put(kRadial.getXf()).put((float) (center + halfHeight)).put(kRadial.getZf());
        kRadial.setY(center);
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // generate cylinder... but no need to add points for first and last
    // samples as they are already part of domes.
    for (int i = 1; i < axisSamples; i++) {
      final double center = halfHeight - (i * height / axisSamples);
      final double lengthFraction = (center + halfHeight + radius) / (height + 2 * radius);

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(radius);
        verts.put(kRadial.getXf()).put((float) center).put(kRadial.getZf());
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // generating the bottom dome.
    for (int i = 0; i < sphereSamples; i++) {
      final double center = i * (radius / sphereSamples);
      final double lengthFraction = (radius - center) / (height + 2 * radius);

      // compute radius of slice
      final double fSliceRadius = Math.sqrt(Math.abs(radius * radius - center * center));

      for (int j = 0; j <= radialSamples; j++) {
        final Vector3 kRadial = tempA.set(cos[j], 0, sin[j]);
        kRadial.multiplyLocal(fSliceRadius);
        verts.put(kRadial.getXf()).put((float) (-center - halfHeight)).put(kRadial.getZf());
        kRadial.setY(-center);
        kRadial.normalizeLocal();
        norms.put(kRadial.getXf()).put(kRadial.getYf()).put(kRadial.getZf());
        final double radialFraction = 1 - (j * inverseRadial); // in [0,1)
        texs.put((float) radialFraction).put((float) lengthFraction);
      }
    }

    // bottom point.
    verts.put(0).put((float) (-radius - halfHeight)).put(0);
    norms.put(0).put(-1).put(0);
    texs.put(0).put(0);
  }
Пример #9
0
  /**
   * Find and apply the given material to the given Mesh.
   *
   * @param materialName our material name
   * @param mesh the mesh to apply material to.
   */
  public void applyMaterial(final String materialName, final Mesh mesh) {
    if (materialName == null) {
      logger.warning("materialName is null");
      return;
    }

    Element mat = _dataCache.getBoundMaterial(materialName);
    if (mat == null) {
      logger.warning("material not bound: " + materialName + ", trying search with id.");
      mat = _colladaDOMUtil.findTargetWithId(materialName);
    }
    if (mat == null || !"material".equals(mat.getName())) {
      logger.warning("material not found: " + materialName);
      return;
    }

    final String originalMaterial = mat.getAttributeValue("id");
    MaterialInfo mInfo = null;
    if (!_dataCache.getMaterialInfoMap().containsKey(originalMaterial)) {
      mInfo = new MaterialInfo();
      mInfo.setMaterialName(originalMaterial);
      _dataCache.getMaterialInfoMap().put(originalMaterial, mInfo);
    }
    _dataCache.getMeshMaterialMap().put(mesh, originalMaterial);

    final Element child = mat.getChild("instance_effect");
    final Element effectNode = _colladaDOMUtil.findTargetWithId(child.getAttributeValue("url"));
    if (effectNode == null) {
      logger.warning(
          "material effect not found: "
              + mat.getChild("instance_material").getAttributeValue("url"));
      return;
    }

    if ("effect".equals(effectNode.getName())) {
      /*
       * temp cache for textures, we do not want to add textures twice (for example, transparant map might point
       * to diffuse texture)
       */
      final HashMap<String, Texture> loadedTextures = new HashMap<String, Texture>();
      final Element effect = effectNode;
      // XXX: For now, just grab the common technique:
      if (effect.getChild("profile_COMMON") != null) {
        if (mInfo != null) {
          mInfo.setProfile("COMMON");
        }
        final Element technique = effect.getChild("profile_COMMON").getChild("technique");
        String type = "blinn";
        if (technique.getChild(type) == null) {
          type = "phong";
          if (technique.getChild(type) == null) {
            type = "lambert";
            if (technique.getChild(type) == null) {
              type = "constant";
              if (technique.getChild(type) == null) {
                ColladaMaterialUtils.logger.warning(
                    "COMMON material has unusuable techinque. " + child.getAttributeValue("url"));
                return;
              }
            }
          }
        }
        final Element blinnPhongLambert = technique.getChild(type);
        if (mInfo != null) {
          mInfo.setTechnique(type);
        }
        final MaterialState mState = new MaterialState();

        // TODO: implement proper transparency handling
        Texture diffuseTexture = null;
        ColorRGBA transparent = new ColorRGBA(1.0f, 1.0f, 1.0f, 1.0f);
        float transparency = 1.0f;
        boolean useTransparency = false;
        String opaqueMode = "A_ONE";

        /*
         * place holder for current property, we import material properties in fixed order (for texture order)
         */
        Element property = null;
        /* Diffuse property */
        property = blinnPhongLambert.getChild("diffuse");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("color".equals(propertyValue.getName())) {
            final ColorRGBA color = _colladaDOMUtil.getColor(propertyValue.getText());
            mState.setDiffuse(MaterialFace.FrontAndBack, color);
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            diffuseTexture =
                populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "diffuse");
          }
        }
        /* Ambient property */
        property = blinnPhongLambert.getChild("ambient");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("color".equals(propertyValue.getName())) {
            final ColorRGBA color = _colladaDOMUtil.getColor(propertyValue.getText());
            mState.setAmbient(MaterialFace.FrontAndBack, color);
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "ambient");
          }
        }
        /* Transparent property */
        property = blinnPhongLambert.getChild("transparent");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("color".equals(propertyValue.getName())) {
            transparent = _colladaDOMUtil.getColor(propertyValue.getText());
            // TODO: use this
            useTransparency = true;
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "transparent");
          }
          opaqueMode = property.getAttributeValue("opaque", "A_ONE");
        }
        /* Transparency property */
        property = blinnPhongLambert.getChild("transparency");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("float".equals(propertyValue.getName())) {
            transparency = Float.parseFloat(propertyValue.getText().replace(",", "."));
            // TODO: use this
            if (_flipTransparency) {
              transparency = 1f - transparency;
            }
            useTransparency = true;
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(
                mesh, propertyValue, effect, loadedTextures, mInfo, "transparency");
          }
        }
        /* Emission property */
        property = blinnPhongLambert.getChild("emission");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("color".equals(propertyValue.getName())) {
            mState.setEmissive(
                MaterialFace.FrontAndBack, _colladaDOMUtil.getColor(propertyValue.getText()));
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "emissive");
          }
        }
        /* Specular property */
        property = blinnPhongLambert.getChild("specular");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("color".equals(propertyValue.getName())) {
            mState.setSpecular(
                MaterialFace.FrontAndBack, _colladaDOMUtil.getColor(propertyValue.getText()));
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "specular");
          }
        }
        /* Shininess property */
        property = blinnPhongLambert.getChild("shininess");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("float".equals(propertyValue.getName())) {
            float shininess = Float.parseFloat(propertyValue.getText().replace(",", "."));
            if (shininess >= 0.0f && shininess <= 1.0f) {
              final float oldShininess = shininess;
              shininess *= 128;
              logger.finest(
                  "Shininess - "
                      + oldShininess
                      + " - was in the [0,1] range. Scaling to [0, 128] - "
                      + shininess);
            } else if (shininess < 0 || shininess > 128) {
              final float oldShininess = shininess;
              shininess = MathUtils.clamp(shininess, 0, 128);
              logger.warning(
                  "Shininess must be between 0 and 128. Shininess "
                      + oldShininess
                      + " was clamped to "
                      + shininess);
            }
            mState.setShininess(MaterialFace.FrontAndBack, shininess);
          } else if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            populateTextureState(mesh, propertyValue, effect, loadedTextures, mInfo, "shininess");
          }
        }
        /* Reflectivity property */
        float reflectivity = 1.0f;
        property = blinnPhongLambert.getChild("reflectivity");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("float".equals(propertyValue.getName())) {
            reflectivity = Float.parseFloat(propertyValue.getText().replace(",", "."));
          }
        }
        /* Reflective property. Texture only */
        property = blinnPhongLambert.getChild("reflective");
        if (property != null) {
          final Element propertyValue = (Element) property.getChildren().get(0);
          if ("texture".equals(propertyValue.getName()) && _loadTextures) {
            final Texture reflectiveTexture =
                populateTextureState(
                    mesh, propertyValue, effect, loadedTextures, mInfo, "reflective");

            reflectiveTexture.setEnvironmentalMapMode(Texture.EnvironmentalMapMode.SphereMap);
            reflectiveTexture.setApply(ApplyMode.Combine);

            reflectiveTexture.setCombineFuncRGB(CombinerFunctionRGB.Interpolate);
            // color 1
            reflectiveTexture.setCombineSrc0RGB(CombinerSource.CurrentTexture);
            reflectiveTexture.setCombineOp0RGB(CombinerOperandRGB.SourceColor);
            // color 2
            reflectiveTexture.setCombineSrc1RGB(CombinerSource.Previous);
            reflectiveTexture.setCombineOp1RGB(CombinerOperandRGB.SourceColor);
            // interpolate param will come from alpha of constant color
            reflectiveTexture.setCombineSrc2RGB(CombinerSource.Constant);
            reflectiveTexture.setCombineOp2RGB(CombinerOperandRGB.SourceAlpha);

            reflectiveTexture.setConstantColor(new ColorRGBA(1, 1, 1, reflectivity));
          }
        }

        /*
         * An extra tag defines some materials not part of the collada standard. Since we're not able to parse
         * we simply extract the textures from the element (such that shaders etc can at least pick up on them)
         */
        property = technique.getChild("extra");
        if (property != null) {
          getTexturesFromElement(mesh, property, effect, loadedTextures, mInfo);
        }

        // XXX: There are some issues with clarity on how to use alpha blending in OpenGL FFP.
        // The best interpretation I have seen is that if transparent has a texture == diffuse,
        // Turn on alpha blending and use diffuse alpha.

        // check to make sure we actually need this.
        // testing separately for a transparency of 0.0 is to hack around erroneous exports, since
        // usually
        // there is no use in exporting something with 100% transparency.
        if ("A_ONE".equals(opaqueMode) && ColorRGBA.WHITE.equals(transparent) && transparency == 1.0
            || transparency == 0.0) {
          useTransparency = false;
        }

        if (useTransparency) {
          if (diffuseTexture != null) {
            final BlendState blend = new BlendState();
            blend.setBlendEnabled(true);
            blend.setTestEnabled(true);
            blend.setSourceFunction(BlendState.SourceFunction.SourceAlpha);
            blend.setDestinationFunction(BlendState.DestinationFunction.OneMinusSourceAlpha);
            mesh.setRenderState(blend);
          } else {
            final BlendState blend = new BlendState();
            blend.setBlendEnabled(true);
            blend.setTestEnabled(true);
            transparent.setAlpha(transparent.getAlpha() * transparency);
            blend.setConstantColor(transparent);
            blend.setSourceFunction(BlendState.SourceFunction.ConstantAlpha);
            blend.setDestinationFunction(BlendState.DestinationFunction.OneMinusConstantAlpha);
            mesh.setRenderState(blend);
          }

          mesh.getSceneHints().setRenderBucketType(RenderBucketType.Transparent);
        }

        if (mInfo != null) {
          if (useTransparency) {
            mInfo.setUseTransparency(useTransparency);
            if (diffuseTexture == null) {
              mInfo.setTransparency(transparent.getAlpha() * transparency);
            }
          }
          mInfo.setMaterialState(mState);
        }
        mesh.setRenderState(mState);
      }
    } else {
      ColladaMaterialUtils.logger.warning(
          "material effect not found: "
              + mat.getChild("instance_material").getAttributeValue("url"));
    }
  }
Пример #10
0
  private void setGeometryData() {
    // generate geometry
    final double inverseRadial = 1.0 / _radialSamples;
    final double inverseAxisLess = 1.0 / (_closed ? _axisSamples - 3 : _axisSamples - 1);
    final double inverseAxisLessTexture = 1.0 / (_axisSamples - 1);
    final double halfHeight = 0.5 * _height;

    // Generate points on the unit circle to be used in computing the mesh
    // points on a cylinder slice.
    final double[] sin = new double[_radialSamples + 1];
    final double[] cos = new double[_radialSamples + 1];

    for (int radialCount = 0; radialCount < _radialSamples; radialCount++) {
      final double angle = MathUtils.TWO_PI * inverseRadial * radialCount;
      cos[radialCount] = MathUtils.cos(angle);
      sin[radialCount] = MathUtils.sin(angle);
    }
    sin[_radialSamples] = sin[0];
    cos[_radialSamples] = cos[0];

    // generate the cylinder itself
    final Vector3 tempNormal = new Vector3();
    for (int axisCount = 0, i = 0; axisCount < _axisSamples; axisCount++) {
      double axisFraction;
      double axisFractionTexture;
      int topBottom = 0;
      if (!_closed) {
        axisFraction = axisCount * inverseAxisLess; // in [0,1]
        axisFractionTexture = axisFraction;
      } else {
        if (axisCount == 0) {
          topBottom = -1; // bottom
          axisFraction = 0;
          axisFractionTexture = inverseAxisLessTexture;
        } else if (axisCount == _axisSamples - 1) {
          topBottom = 1; // top
          axisFraction = 1;
          axisFractionTexture = 1 - inverseAxisLessTexture;
        } else {
          axisFraction = (axisCount - 1) * inverseAxisLess;
          axisFractionTexture = axisCount * inverseAxisLessTexture;
        }
      }
      final double z = -halfHeight + _height * axisFraction;

      // compute center of slice
      final Vector3 sliceCenter = new Vector3(0, 0, z);

      // compute slice vertices with duplication at end point
      final int save = i;
      for (int radialCount = 0; radialCount < _radialSamples; radialCount++) {
        final double radialFraction = radialCount * inverseRadial; // in [0,1)
        tempNormal.set(cos[radialCount], sin[radialCount], 0);
        if (topBottom == 0) {
          if (!_inverted) {
            _meshData
                .getNormalBuffer()
                .put(tempNormal.getXf())
                .put(tempNormal.getYf())
                .put(tempNormal.getZf());
          } else {
            _meshData
                .getNormalBuffer()
                .put(-tempNormal.getXf())
                .put(-tempNormal.getYf())
                .put(-tempNormal.getZf());
          }
        } else {
          _meshData.getNormalBuffer().put(0).put(0).put(topBottom * (_inverted ? -1 : 1));
        }

        tempNormal
            .multiplyLocal((_radius - _radius2) * axisFraction + _radius2)
            .addLocal(sliceCenter);
        _meshData
            .getVertexBuffer()
            .put(tempNormal.getXf())
            .put(tempNormal.getYf())
            .put(tempNormal.getZf());

        _meshData
            .getTextureCoords(0)
            .getBuffer()
            .put((float) (_inverted ? 1 - radialFraction : radialFraction))
            .put((float) axisFractionTexture);
        i++;
      }

      BufferUtils.copyInternalVector3(_meshData.getVertexBuffer(), save, i);
      BufferUtils.copyInternalVector3(_meshData.getNormalBuffer(), save, i);

      _meshData
          .getTextureCoords(0)
          .getBuffer()
          .put((_inverted ? 0.0f : 1.0f))
          .put((float) axisFractionTexture);

      i++;
    }

    if (_closed) {
      _meshData.getVertexBuffer().put(0).put(0).put((float) -halfHeight); // bottom center
      _meshData.getNormalBuffer().put(0).put(0).put(-1 * (_inverted ? -1 : 1));
      _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(0);
      _meshData.getVertexBuffer().put(0).put(0).put((float) halfHeight); // top center
      _meshData.getNormalBuffer().put(0).put(0).put(1 * (_inverted ? -1 : 1));
      _meshData.getTextureCoords(0).getBuffer().put(0.5f).put(1);
    }
  }
Пример #12
0
 private double calcNewJitter() {
   return ((MathUtils.nextRandomFloat() * 2.0f) - 1.0f) * _wanderJitter;
 }
Пример #13
0
  // 4D simplex noise
  double noise(final double x, final double y, final double z, final double w) {

    // The skewing and unskewing factors are hairy again for the 4D case
    final double F4 = (Math.sqrt(5.0) - 1.0) / 4.0;
    final double G4 = (5.0 - Math.sqrt(5.0)) / 20.0;
    double n0, n1, n2, n3, n4; // Noise contributions from the five corners
    // Skew the (x,y,z,w) space to determine which cell of 24 simplices we're in
    final double s = (x + y + z + w) * F4; // Factor for 4D skewing
    final int i = (int) MathUtils.floor(x + s);
    final int j = (int) MathUtils.floor(y + s);
    final int k = (int) MathUtils.floor(z + s);
    final int l = (int) MathUtils.floor(w + s);
    final double t = (i + j + k + l) * G4; // Factor for 4D unskewing
    final double X0 = i - t; // Unskew the cell origin back to (x,y,z,w) space
    final double Y0 = j - t;
    final double Z0 = k - t;
    final double W0 = l - t;
    final double x0 = x - X0; // The x,y,z,w distances from the cell origin
    final double y0 = y - Y0;
    final double z0 = z - Z0;
    final double w0 = w - W0;
    // For the 4D case, the simplex is a 4D shape I won't even try to describe.
    // To find out which of the 24 possible simplices we're in, we need to
    // determine the magnitude ordering of x0, y0, z0 and w0.
    // The method below is a good way of finding the ordering of x,y,z,w and
    // then find the correct traversal order for the simplex we’re in.
    // First, six pair-wise comparisons are performed between each possible pair
    // of the four coordinates, and the results are used to add up binary bits
    // for an integer index.
    final int c1 = (x0 > y0) ? 32 : 0;
    final int c2 = (x0 > z0) ? 16 : 0;
    final int c3 = (y0 > z0) ? 8 : 0;
    final int c4 = (x0 > w0) ? 4 : 0;
    final int c5 = (y0 > w0) ? 2 : 0;
    final int c6 = (z0 > w0) ? 1 : 0;
    final int c = c1 + c2 + c3 + c4 + c5 + c6;
    int i1, j1, k1, l1; // The integer offsets for the second simplex corner
    int i2, j2, k2, l2; // The integer offsets for the third simplex corner
    int i3, j3, k3, l3; // The integer offsets for the fourth simplex corner
    // simplex[c] is a 4-vector with the numbers 0, 1, 2 and 3 in some order.
    // Many values of c will never occur, since e.g. x>y>z>w makes x<z, y<w and x<w
    // impossible. Only the 24 indices which have non-zero entries make any sense.
    // We use a thresholding to set the coordinates in turn from the largest magnitude.
    // The number 3 in the "simplex" array is at the position of the largest coordinate.
    i1 = simplex[c][0] >= 3 ? 1 : 0;
    j1 = simplex[c][1] >= 3 ? 1 : 0;
    k1 = simplex[c][2] >= 3 ? 1 : 0;
    l1 = simplex[c][3] >= 3 ? 1 : 0;
    // The number 2 in the "simplex" array is at the second largest coordinate.
    i2 = simplex[c][0] >= 2 ? 1 : 0;
    j2 = simplex[c][1] >= 2 ? 1 : 0;
    k2 = simplex[c][2] >= 2 ? 1 : 0;
    l2 = simplex[c][3] >= 2 ? 1 : 0;
    // The number 1 in the "simplex" array is at the second smallest coordinate.
    i3 = simplex[c][0] >= 1 ? 1 : 0;
    j3 = simplex[c][1] >= 1 ? 1 : 0;
    k3 = simplex[c][2] >= 1 ? 1 : 0;
    l3 = simplex[c][3] >= 1 ? 1 : 0;
    // The fifth corner has all coordinate offsets = 1, so no need to look that up.
    final double x1 = x0 - i1 + G4; // Offsets for second corner in (x,y,z,w) coords
    final double y1 = y0 - j1 + G4;
    final double z1 = z0 - k1 + G4;
    final double w1 = w0 - l1 + G4;
    final double x2 = x0 - i2 + 2.0 * G4; // Offsets for third corner in (x,y,z,w) coords
    final double y2 = y0 - j2 + 2.0 * G4;
    final double z2 = z0 - k2 + 2.0 * G4;
    final double w2 = w0 - l2 + 2.0 * G4;
    final double x3 = x0 - i3 + 3.0 * G4; // Offsets for fourth corner in (x,y,z,w) coords
    final double y3 = y0 - j3 + 3.0 * G4;
    final double z3 = z0 - k3 + 3.0 * G4;
    final double w3 = w0 - l3 + 3.0 * G4;
    final double x4 = x0 - 1.0 + 4.0 * G4; // Offsets for last corner in (x,y,z,w) coords
    final double y4 = y0 - 1.0 + 4.0 * G4;
    final double z4 = z0 - 1.0 + 4.0 * G4;
    final double w4 = w0 - 1.0 + 4.0 * G4;
    // Work out the hashed gradient indices of the five simplex corners
    final int ii = i & 255;
    final int jj = j & 255;
    final int kk = k & 255;
    final int ll = l & 255;
    final int gi0 = perm[ii + perm[jj + perm[kk + perm[ll]]]] % 32;
    final int gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1 + perm[ll + l1]]]] % 32;
    final int gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2 + perm[ll + l2]]]] % 32;
    final int gi3 = perm[ii + i3 + perm[jj + j3 + perm[kk + k3 + perm[ll + l3]]]] % 32;
    final int gi4 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1 + perm[ll + 1]]]] % 32;
    // Calculate the contribution from the five corners
    double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0 - w0 * w0;
    if (t0 < 0) {
      n0 = 0.0;
    } else {
      t0 *= t0;
      n0 = t0 * t0 * dot(grad4[gi0], x0, y0, z0, w0);
    }
    double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1 - w1 * w1;
    if (t1 < 0) {
      n1 = 0.0;
    } else {
      t1 *= t1;
      n1 = t1 * t1 * dot(grad4[gi1], x1, y1, z1, w1);
    }
    double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2 - w2 * w2;
    if (t2 < 0) {
      n2 = 0.0;
    } else {
      t2 *= t2;
      n2 = t2 * t2 * dot(grad4[gi2], x2, y2, z2, w2);
    }
    double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3 - w3 * w3;
    if (t3 < 0) {
      n3 = 0.0;
    } else {
      t3 *= t3;
      n3 = t3 * t3 * dot(grad4[gi3], x3, y3, z3, w3);
    }
    double t4 = 0.6 - x4 * x4 - y4 * y4 - z4 * z4 - w4 * w4;
    if (t4 < 0) {
      n4 = 0.0;
    } else {
      t4 *= t4;
      n4 = t4 * t4 * dot(grad4[gi4], x4, y4, z4, w4);
    }
    // Sum up and scale the result to cover the range [-1,1]
    return 27.0 * (n0 + n1 + n2 + n3 + n4);
  }
Пример #14
0
 // 3D simplex noise
 public static double noise(final double xin, final double yin, final double zin) {
   double n0, n1, n2, n3; // Noise contributions from the four corners
   // Skew the input space to determine which simplex cell we're in
   final double F3 = 1.0 / 3.0;
   final double s = (xin + yin + zin) * F3; // Very nice and simple skew factor for 3D
   final int i = (int) MathUtils.floor(xin + s);
   final int j = (int) MathUtils.floor(yin + s);
   final int k = (int) MathUtils.floor(zin + s);
   final double G3 = 1.0 / 6.0; // Very nice and simple unskew factor, too
   final double t = (i + j + k) * G3;
   final double X0 = i - t; // Unskew the cell origin back to (x,y,z) space
   final double Y0 = j - t;
   final double Z0 = k - t;
   final double x0 = xin - X0; // The x,y,z distances from the cell origin
   final double y0 = yin - Y0;
   final double z0 = zin - Z0;
   // For the 3D case, the simplex shape is a slightly irregular tetrahedron.
   // Determine which simplex we are in.
   int i1, j1, k1; // Offsets for second corner of simplex in (i,j,k) coords
   int i2, j2, k2; // Offsets for third corner of simplex in (i,j,k) coords
   if (x0 >= y0) {
     if (y0 >= z0) {
       i1 = 1;
       j1 = 0;
       k1 = 0;
       i2 = 1;
       j2 = 1;
       k2 = 0;
     } // X Y Z order
     else if (x0 >= z0) {
       i1 = 1;
       j1 = 0;
       k1 = 0;
       i2 = 1;
       j2 = 0;
       k2 = 1;
     } // X Z Y order
     else {
       i1 = 0;
       j1 = 0;
       k1 = 1;
       i2 = 1;
       j2 = 0;
       k2 = 1;
     } // Z X Y order
   } else { // x0<y0
     if (y0 < z0) {
       i1 = 0;
       j1 = 0;
       k1 = 1;
       i2 = 0;
       j2 = 1;
       k2 = 1;
     } // Z Y X order
     else if (x0 < z0) {
       i1 = 0;
       j1 = 1;
       k1 = 0;
       i2 = 0;
       j2 = 1;
       k2 = 1;
     } // Y Z X order
     else {
       i1 = 0;
       j1 = 1;
       k1 = 0;
       i2 = 1;
       j2 = 1;
       k2 = 0;
     } // Y X Z order
   }
   // A step of (1,0,0) in (i,j,k) means a step of (1-c,-c,-c) in (x,y,z),
   // a step of (0,1,0) in (i,j,k) means a step of (-c,1-c,-c) in (x,y,z), and
   // a step of (0,0,1) in (i,j,k) means a step of (-c,-c,1-c) in (x,y,z), where
   // c = 1/6.
   final double x1 = x0 - i1 + G3; // Offsets for second corner in (x,y,z) coords
   final double y1 = y0 - j1 + G3;
   final double z1 = z0 - k1 + G3;
   final double x2 = x0 - i2 + 2.0 * G3; // Offsets for third corner in (x,y,z) coords
   final double y2 = y0 - j2 + 2.0 * G3;
   final double z2 = z0 - k2 + 2.0 * G3;
   final double x3 = x0 - 1.0 + 3.0 * G3; // Offsets for last corner in (x,y,z) coords
   final double y3 = y0 - 1.0 + 3.0 * G3;
   final double z3 = z0 - 1.0 + 3.0 * G3;
   // Work out the hashed gradient indices of the four simplex corners
   final int ii = i & 255;
   final int jj = j & 255;
   final int kk = k & 255;
   final int gi0 = perm[ii + perm[jj + perm[kk]]] % 12;
   final int gi1 = perm[ii + i1 + perm[jj + j1 + perm[kk + k1]]] % 12;
   final int gi2 = perm[ii + i2 + perm[jj + j2 + perm[kk + k2]]] % 12;
   final int gi3 = perm[ii + 1 + perm[jj + 1 + perm[kk + 1]]] % 12;
   // Calculate the contribution from the four corners
   double t0 = 0.6 - x0 * x0 - y0 * y0 - z0 * z0;
   if (t0 < 0) {
     n0 = 0.0;
   } else {
     t0 *= t0;
     n0 = t0 * t0 * dot(grad3[gi0], x0, y0, z0);
   }
   double t1 = 0.6 - x1 * x1 - y1 * y1 - z1 * z1;
   if (t1 < 0) {
     n1 = 0.0;
   } else {
     t1 *= t1;
     n1 = t1 * t1 * dot(grad3[gi1], x1, y1, z1);
   }
   double t2 = 0.6 - x2 * x2 - y2 * y2 - z2 * z2;
   if (t2 < 0) {
     n2 = 0.0;
   } else {
     t2 *= t2;
     n2 = t2 * t2 * dot(grad3[gi2], x2, y2, z2);
   }
   double t3 = 0.6 - x3 * x3 - y3 * y3 - z3 * z3;
   if (t3 < 0) {
     n3 = 0.0;
   } else {
     t3 *= t3;
     n3 = t3 * t3 * dot(grad3[gi3], x3, y3, z3);
   }
   // Add contributions from each corner to get the final noise value.
   // The result is scaled to stay just inside [-1,1]
   return 32.0 * (n0 + n1 + n2 + n3);
 }
Пример #15
0
 // 2D simplex noise
 public static double noise(final double xin, final double yin) {
   double n0, n1, n2; // Noise contributions from the three corners
   // Skew the input space to determine which simplex cell we're in
   final double F2 = 0.5 * (Math.sqrt(3.0) - 1.0);
   final double s = (xin + yin) * F2; // Hairy factor for 2D
   final int i = (int) MathUtils.floor(xin + s);
   final int j = (int) MathUtils.floor(yin + s);
   final double G2 = (3.0 - Math.sqrt(3.0)) / 6.0;
   final double t = (i + j) * G2;
   final double X0 = i - t; // Unskew the cell origin back to (x,y) space
   final double Y0 = j - t;
   final double x0 = xin - X0; // The x,y distances from the cell origin
   final double y0 = yin - Y0;
   // For the 2D case, the simplex shape is an equilateral triangle.
   // Determine which simplex we are in.
   int i1, j1; // Offsets for second (middle) corner of simplex in (i,j) coords
   if (x0 > y0) {
     i1 = 1;
     j1 = 0;
   } // lower triangle, XY order: (0,0)->(1,0)->(1,1)
   else {
     i1 = 0;
     j1 = 1;
   } // upper triangle, YX order: (0,0)->(0,1)->(1,1)
   // A step of (1,0) in (i,j) means a step of (1-c,-c) in (x,y), and
   // a step of (0,1) in (i,j) means a step of (-c,1-c) in (x,y), where
   // c = (3-sqrt(3))/6
   final double x1 = x0 - i1 + G2; // Offsets for middle corner in (x,y) unskewed coords
   final double y1 = y0 - j1 + G2;
   final double x2 = x0 - 1.0 + 2.0 * G2; // Offsets for last corner in (x,y) unskewed coords
   final double y2 = y0 - 1.0 + 2.0 * G2;
   // Work out the hashed gradient indices of the three simplex corners
   final int ii = i & 255;
   final int jj = j & 255;
   final int gi0 = perm[ii + perm[jj]] % 12;
   final int gi1 = perm[ii + i1 + perm[jj + j1]] % 12;
   final int gi2 = perm[ii + 1 + perm[jj + 1]] % 12;
   // Calculate the contribution from the three corners
   double t0 = 0.5 - x0 * x0 - y0 * y0;
   if (t0 < 0) {
     n0 = 0.0;
   } else {
     t0 *= t0;
     n0 = t0 * t0 * dot(grad3[gi0], x0, y0); // (x,y) of grad3 used for 2D gradient
   }
   double t1 = 0.5 - x1 * x1 - y1 * y1;
   if (t1 < 0) {
     n1 = 0.0;
   } else {
     t1 *= t1;
     n1 = t1 * t1 * dot(grad3[gi1], x1, y1);
   }
   double t2 = 0.5 - x2 * x2 - y2 * y2;
   if (t2 < 0) {
     n2 = 0.0;
   } else {
     t2 *= t2;
     n2 = t2 * t2 * dot(grad3[gi2], x2, y2);
   }
   // Add contributions from each corner to get the final noise value.
   // The result is scaled to return values in the interval [-1,1].
   return 70.0 * (n0 + n1 + n2);
 }