Beispiel #1
0
  /**
   * <code>rotateUpTo</code> is a utility function that alters the local rotation to point the Y
   * axis in the direction given by newUp.
   *
   * @param newUp the up vector to use - assumed to be a unit vector.
   */
  public void rotateUpTo(Vector3f newUp) {
    TempVars vars = TempVars.get();

    Vector3f compVecA = vars.vect1;
    Quaternion q = vars.quat1;

    // First figure out the current up vector.
    Vector3f upY = compVecA.set(Vector3f.UNIT_Y);
    Quaternion rot = localTransform.getRotation();
    rot.multLocal(upY);

    // get angle between vectors
    float angle = upY.angleBetween(newUp);

    // figure out rotation axis by taking cross product
    Vector3f rotAxis = upY.crossLocal(newUp).normalizeLocal();

    // Build a rotation quat and apply current local rotation.
    q.fromAngleNormalAxis(angle, rotAxis);
    q.mult(rot, rot);

    vars.release();

    setTransformRefresh();
  }
Beispiel #2
0
  public Vector3f reflect(Vector3f point, Vector3f store) {
    if (store == null) store = new Vector3f();

    float d = pseudoDistance(point);
    store.set(normal).negateLocal().multLocal(d * 2f);
    store.addLocal(point);
    return store;
  }
Beispiel #3
0
  /**
   * Centers the spatial in the origin of the world bound.
   *
   * @return The spatial on which this method is called, e.g <code>this</code>.
   */
  public Spatial center() {
    Vector3f worldTrans = getWorldTranslation();
    Vector3f worldCenter = getWorldBound().getCenter();

    Vector3f absTrans = worldTrans.subtract(worldCenter);
    setLocalTranslation(absTrans);

    return this;
  }
Beispiel #4
0
 @Override
 public Transform clone() {
   try {
     Transform tq = (Transform) super.clone();
     tq.rot = rot.clone();
     tq.scale = scale.clone();
     tq.translation = translation.clone();
     return tq;
   } catch (CloneNotSupportedException e) {
     throw new AssertionError();
   }
 }
Beispiel #5
0
  public Vector3f transformInverseVector(final Vector3f in, Vector3f store) {
    if (store == null) store = new Vector3f();

    // The author of this code should look above and take the inverse of that
    // But for some reason, they didnt ..
    //        in.subtract(translation, store).divideLocal(scale);
    //        rot.inverse().mult(store, store);

    in.subtract(translation, store);
    rot.inverse().mult(store, store);
    store.divideLocal(scale);

    return store;
  }
Beispiel #6
0
  public Vector3f transformVector(final Vector3f in, Vector3f store) {
    if (store == null) store = new Vector3f();

    // multiply with scale first, then rotate, finally translate (cf.
    // Eberly)
    return rot.mult(store.set(in).multLocal(scale), store).addLocal(translation);
  }
Beispiel #7
0
  /**
   * Changes the values of this matrix acording to it's parent. Very similar to the concept of
   * Node/Spatial transforms.
   *
   * @param parent The parent matrix.
   * @return This matrix, after combining.
   */
  public Transform combineWithParent(Transform parent) {
    scale.multLocal(parent.scale);
    //        rot.multLocal(parent.rot);
    parent.rot.mult(rot, rot);

    // This here, is evil code
    //        parent
    //            .rot
    //            .multLocal(translation)
    //            .multLocal(parent.scale)
    //            .addLocal(parent.translation);

    translation.multLocal(parent.scale);
    parent.rot.multLocal(translation).addLocal(parent.translation);
    return this;
  }
Beispiel #8
0
  /**
   * <code>lookAt</code> is a convenience method for auto-setting the local rotation based on a
   * position in world space and an up vector. It computes the rotation to transform the z-axis to
   * point onto 'position' and the y-axis to 'up'. Unlike {@link
   * Quaternion#lookAt(com.jme3.math.Vector3f, com.jme3.math.Vector3f) } this method takes a world
   * position to look at and not a relative direction.
   *
   * <p>Note : 28/01/2013 this method has been fixed as it was not taking into account the parent
   * rotation. This was resulting in improper rotation when the spatial had rotated parent nodes.
   * This method is intended to work in world space, so no matter what parent graph the spatial has,
   * it will look at the given position in world space.
   *
   * @param position where to look at in terms of world coordinates
   * @param upVector a vector indicating the (local) up direction. (typically {0, 1, 0} in jME.)
   */
  public void lookAt(Vector3f position, Vector3f upVector) {
    Vector3f worldTranslation = getWorldTranslation();

    TempVars vars = TempVars.get();

    Vector3f compVecA = vars.vect4;

    compVecA.set(position).subtractLocal(worldTranslation);
    getLocalRotation().lookAt(compVecA, upVector);

    if (getParent() != null) {
      Quaternion rot = vars.quat1;
      rot = rot.set(parent.getWorldRotation()).inverseLocal().multLocal(getLocalRotation());
      rot.normalizeLocal();
      setLocalRotation(rot);
    }
    vars.release();
    setTransformRefresh();
  }
Beispiel #9
0
 @Override
 public Plane clone() {
   try {
     Plane p = (Plane) super.clone();
     p.normal = normal.clone();
     return p;
   } catch (CloneNotSupportedException e) {
     throw new AssertionError();
   }
 }
Beispiel #10
0
  /**
   * Uploads the lights in the light list as two uniform arrays.<br>
   * <br>
   * *
   *
   * <p><code>uniform vec4 g_LightColor[numLights];</code><br>
   * // g_LightColor.rgb is the diffuse/specular color of the light.<br>
   * // g_Lightcolor.a is the type of light, 0 = Directional, 1 = Point, <br>
   * // 2 = Spot. <br>
   * <br>
   * <code>uniform vec4 g_LightPosition[numLights];</code><br>
   * // g_LightPosition.xyz is the position of the light (for point lights)<br>
   * // or the direction of the light (for directional lights).<br>
   * // g_LightPosition.w is the inverse radius (1/r) of the light (for attenuation) <br>
   */
  protected void updateLightListUniforms(Shader shader, Geometry g, int numLights) {
    if (numLights == 0) { // this shader does not do lighting, ignore.
      return;
    }

    LightList lightList = g.getWorldLightList();
    Uniform lightColor = shader.getUniform("g_LightColor");
    Uniform lightPos = shader.getUniform("g_LightPosition");
    Uniform lightDir = shader.getUniform("g_LightDirection");
    lightColor.setVector4Length(numLights);
    lightPos.setVector4Length(numLights);
    lightDir.setVector4Length(numLights);

    Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
    ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));

    int lightIndex = 0;

    for (int i = 0; i < numLights; i++) {
      if (lightList.size() <= i) {
        lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
        lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
      } else {
        Light l = lightList.get(i);
        ColorRGBA color = l.getColor();
        lightColor.setVector4InArray(
            color.getRed(), color.getGreen(), color.getBlue(), l.getType().getId(), i);

        switch (l.getType()) {
          case Directional:
            DirectionalLight dl = (DirectionalLight) l;
            Vector3f dir = dl.getDirection();
            lightPos.setVector4InArray(dir.getX(), dir.getY(), dir.getZ(), -1, lightIndex);
            break;
          case Point:
            PointLight pl = (PointLight) l;
            Vector3f pos = pl.getPosition();
            float invRadius = pl.getInvRadius();
            lightPos.setVector4InArray(pos.getX(), pos.getY(), pos.getZ(), invRadius, lightIndex);
            break;
          case Spot:
            SpotLight sl = (SpotLight) l;
            Vector3f pos2 = sl.getPosition();
            Vector3f dir2 = sl.getDirection();
            float invRange = sl.getInvSpotRange();
            float spotAngleCos = sl.getPackedAngleCos();

            lightPos.setVector4InArray(pos2.getX(), pos2.getY(), pos2.getZ(), invRange, lightIndex);
            lightDir.setVector4InArray(
                dir2.getX(), dir2.getY(), dir2.getZ(), spotAngleCos, lightIndex);
            break;
          case Ambient:
            // skip this light. Does not increase lightIndex
            continue;
          default:
            throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
        }
      }

      lightIndex++;
    }

    while (lightIndex < numLights) {
      lightColor.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);
      lightPos.setVector4InArray(0f, 0f, 0f, 0f, lightIndex);

      lightIndex++;
    }
  }
Beispiel #11
0
 public Vector3f getClosestPoint(Vector3f point, Vector3f store) {
   //        float t = constant - normal.dot(point);
   //        return store.set(normal).multLocal(t).addLocal(point);
   float t = (constant - normal.dot(point)) / normal.dot(normal);
   return store.set(normal).multLocal(t).addLocal(point);
 }
Beispiel #12
0
 /** Loads the identity. Equal to translation=0,0,0 scale=1,1,1 rot=0,0,0,1. */
 public void loadIdentity() {
   translation.set(0, 0, 0);
   scale.set(1, 1, 1);
   rot.set(0, 0, 0, 1);
 }
Beispiel #13
0
 /**
  * Sets this matrix's scale to the given x,y,z values.
  *
  * @param x This matrix's new x scale.
  * @param y This matrix's new y scale.
  * @param z This matrix's new z scale.
  * @return this
  */
 public Transform setScale(float x, float y, float z) {
   scale.set(x, y, z);
   return this;
 }
Beispiel #14
0
 /**
  * <code>pseudoDistance</code> calculates the distance from this plane to a provided point. If the
  * point is on the negative side of the plane the distance returned is negative, otherwise it is
  * positive. If the point is on the plane, it is zero.
  *
  * @param point the point to check.
  * @return the signed distance from the plane to a point.
  */
 public float pseudoDistance(Vector3f point) {
   return normal.dot(point) - constant;
 }
Beispiel #15
0
 /**
  * Sets this matrix's translation to the given x,y,z values.
  *
  * @param x This matrix's new x translation.
  * @param y This matrix's new y translation.
  * @param z This matrix's new z translation.
  * @return this
  */
 public Transform setTranslation(float x, float y, float z) {
   translation.set(x, y, z);
   return this;
 }
Beispiel #16
0
 /**
  * Initialize the Plane using the given 3 points as coplanar.
  *
  * @param v1 the first point
  * @param v2 the second point
  * @param v3 the third point
  */
 public void setPlanePoints(Vector3f v1, Vector3f v2, Vector3f v3) {
   normal.set(v2).subtractLocal(v1);
   normal.crossLocal(v3.x - v1.x, v3.y - v1.y, v3.z - v1.z).normalizeLocal();
   constant = normal.dot(v1);
 }
Beispiel #17
0
 /**
  * Stores this scale value into the given vector3f. If scale is null, a new vector3f is created to
  * hold the value. The value, once stored, is returned.
  *
  * @param scale The store location for this matrix's scale.
  * @return The value of this matrix's scale.
  */
 public Vector3f getScale(Vector3f scale) {
   if (scale == null) scale = new Vector3f();
   scale.set(this.scale);
   return scale;
 }
Beispiel #18
0
 /**
  * Stores this translation value into the given vector3f. If trans is null, a new vector3f is
  * created to hold the value. The value, once stored, is returned.
  *
  * @param trans The store location for this matrix's translation.
  * @return The value of this matrix's translation.
  */
 public Vector3f getTranslation(Vector3f trans) {
   if (trans == null) trans = new Vector3f();
   trans.set(this.translation);
   return trans;
 }
Beispiel #19
0
  protected void renderMultipassLighting(Shader shader, Geometry g, RenderManager rm) {

    Renderer r = rm.getRenderer();
    LightList lightList = g.getWorldLightList();
    Uniform lightDir = shader.getUniform("g_LightDirection");
    Uniform lightColor = shader.getUniform("g_LightColor");
    Uniform lightPos = shader.getUniform("g_LightPosition");
    Uniform ambientColor = shader.getUniform("g_AmbientLightColor");
    boolean isFirstLight = true;
    boolean isSecondLight = false;

    for (int i = 0; i < lightList.size(); i++) {
      Light l = lightList.get(i);
      if (l instanceof AmbientLight) {
        continue;
      }

      if (isFirstLight) {
        // set ambient color for first light only
        ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
        isFirstLight = false;
        isSecondLight = true;
      } else if (isSecondLight) {
        ambientColor.setValue(VarType.Vector4, ColorRGBA.Black);
        // apply additive blending for 2nd and future lights
        r.applyRenderState(additiveLight);
        isSecondLight = false;
      }

      TempVars vars = TempVars.get();
      Quaternion tmpLightDirection = vars.quat1;
      Quaternion tmpLightPosition = vars.quat2;
      ColorRGBA tmpLightColor = vars.color;
      Vector4f tmpVec = vars.vect4f;

      ColorRGBA color = l.getColor();
      tmpLightColor.set(color);
      tmpLightColor.a = l.getType().getId();
      lightColor.setValue(VarType.Vector4, tmpLightColor);

      switch (l.getType()) {
        case Directional:
          DirectionalLight dl = (DirectionalLight) l;
          Vector3f dir = dl.getDirection();

          tmpLightPosition.set(dir.getX(), dir.getY(), dir.getZ(), -1);
          lightPos.setValue(VarType.Vector4, tmpLightPosition);
          tmpLightDirection.set(0, 0, 0, 0);
          lightDir.setValue(VarType.Vector4, tmpLightDirection);
          break;
        case Point:
          PointLight pl = (PointLight) l;
          Vector3f pos = pl.getPosition();
          float invRadius = pl.getInvRadius();

          tmpLightPosition.set(pos.getX(), pos.getY(), pos.getZ(), invRadius);
          lightPos.setValue(VarType.Vector4, tmpLightPosition);
          tmpLightDirection.set(0, 0, 0, 0);
          lightDir.setValue(VarType.Vector4, tmpLightDirection);
          break;
        case Spot:
          SpotLight sl = (SpotLight) l;
          Vector3f pos2 = sl.getPosition();
          Vector3f dir2 = sl.getDirection();
          float invRange = sl.getInvSpotRange();
          float spotAngleCos = sl.getPackedAngleCos();

          tmpLightPosition.set(pos2.getX(), pos2.getY(), pos2.getZ(), invRange);
          lightPos.setValue(VarType.Vector4, tmpLightPosition);

          // We transform the spot directoin in view space here to save 5 varying later in the
          // lighting shader
          // one vec4 less and a vec4 that becomes a vec3
          // the downside is that spotAngleCos decoding happen now in the frag shader.
          tmpVec.set(dir2.getX(), dir2.getY(), dir2.getZ(), 0);
          rm.getCurrentCamera().getViewMatrix().mult(tmpVec, tmpVec);
          tmpLightDirection.set(tmpVec.getX(), tmpVec.getY(), tmpVec.getZ(), spotAngleCos);

          lightDir.setValue(VarType.Vector4, tmpLightDirection);

          break;
        default:
          throw new UnsupportedOperationException("Unknown type of light: " + l.getType());
      }
      vars.release();
      r.setShader(shader);
      r.renderMesh(g.getMesh(), g.getLodLevel(), 1);
    }

    if (isFirstLight && lightList.size() > 0) {
      // There are only ambient lights in the scene. Render
      // a dummy "normal light" so we can see the ambient
      ambientColor.setValue(VarType.Vector4, getAmbientColor(lightList));
      lightColor.setValue(VarType.Vector4, ColorRGBA.BlackNoAlpha);
      lightPos.setValue(VarType.Vector4, nullDirLight);
      r.setShader(shader);
      r.renderMesh(g.getMesh(), g.getLodLevel(), 1);
    }
  }