Ejemplo n.º 1
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();
  }
Ejemplo n.º 2
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);
 }
Ejemplo n.º 3
0
 /**
  * Stores this rotation value into the given Quaternion. If quat is null, a new Quaternion is
  * created to hold the value. The value, once stored, is returned.
  *
  * @param quat The store location for this matrix's rotation.
  * @return The value of this matrix's rotation.
  */
 public Quaternion getRotation(Quaternion quat) {
   if (quat == null) quat = new Quaternion();
   quat.set(rot);
   return quat;
 }
Ejemplo n.º 4
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);
    }
  }