예제 #1
0
 /**
  * Linearly interpolates between this {@link Matrix4} and the given {@link Matrix4} by the given
  * factor.
  *
  * @param matrix {@link Matrix4} The other matrix.
  * @param t {@code double} The interpolation ratio. The result is weighted to this value on the
  *     {@link Matrix4}.
  * @return A reference to this {@link Matrix4} to facilitate chaining.
  */
 @NonNull
 public Matrix4 lerp(@NonNull Matrix4 matrix, double t) {
   matrix.toArray(mTmp);
   for (int i = 0; i < 16; ++i) {
     m[i] = m[i] * (1.0 - t) + t * mTmp[i];
   }
   return this;
 }
예제 #2
0
    private Matrix4 createLightViewProjectionMatrix(DirectionalLight light) {
      //
      // -- Get the frustum corners in world space
      //
      mCamera.getFrustumCorners(mFrustumCorners, true);
      //
      // -- Get the frustum centroid
      //
      mFrustumCentroid.setAll(0, 0, 0);
      for (int i = 0; i < 8; i++) mFrustumCentroid.add(mFrustumCorners[i]);
      mFrustumCentroid.divide(8.0);

      //
      // --
      //

      BoundingBox lightBox = new BoundingBox(mFrustumCorners);
      double distance = mFrustumCentroid.distanceTo(lightBox.getMin());
      Vector3 lightDirection = light.getDirectionVector().clone();
      lightDirection.normalize();
      Vector3 lightPosition =
          Vector3.subtractAndCreate(
              mFrustumCentroid, Vector3.multiplyAndCreate(lightDirection, distance));

      //
      // --
      //

      mLightViewMatrix.setToLookAt(lightPosition, mFrustumCentroid, Vector3.Y);

      for (int i = 0; i < 8; i++) mFrustumCorners[i].multiply(mLightViewMatrix);

      BoundingBox b = new BoundingBox(mFrustumCorners);
      mLightProjectionMatrix.setToOrthographic(
          b.getMin().x, b.getMax().x, b.getMin().y, b.getMax().y, -b.getMax().z, -b.getMin().z);

      mLightModelViewProjectionMatrix.setAll(mLightProjectionMatrix);
      mLightModelViewProjectionMatrix.multiply(mLightViewMatrix);
      return mLightModelViewProjectionMatrix;
    }
    public Vector3 calculatePos(int x, int y, Object3D object3D) {
      Matrix4 mViewMatrix = getCurrentCamera().getViewMatrix();
      Matrix4 mProjectionMatrix = getCurrentCamera().getProjectionMatrix();
      double[] mNearPos4 = new double[4];
      double[] mFarPos4 = new double[4];
      Vector3 mNearPos = new Vector3();
      Vector3 mFarPos = new Vector3();
      Vector3 mNewObjPos = new Vector3();

      int[] mViewport = new int[] {0, 0, getViewportWidth(), getViewportHeight()};

      GLU.gluUnProject(
          x,
          getViewportHeight() - y,
          0,
          mViewMatrix.getDoubleValues(),
          0,
          mProjectionMatrix.getDoubleValues(),
          0,
          mViewport,
          0,
          mNearPos4,
          0);

      GLU.gluUnProject(
          x,
          getViewportHeight() - y,
          1.f,
          mViewMatrix.getDoubleValues(),
          0,
          mProjectionMatrix.getDoubleValues(),
          0,
          mViewport,
          0,
          mFarPos4,
          0);

      mNearPos.setAll(
          mNearPos4[0] / mNearPos4[3], mNearPos4[1] / mNearPos4[3], mNearPos4[2] / mNearPos4[3]);
      mFarPos.setAll(
          mFarPos4[0] / mFarPos4[3], mFarPos4[1] / mFarPos4[3], mFarPos4[2] / mFarPos4[3]);

      double factor =
          (Math.abs(object3D.getZ()) + mNearPos.z)
              / (getCurrentCamera().getFarPlane() - getCurrentCamera().getNearPlane());

      mNewObjPos.setAll(mFarPos);
      mNewObjPos.subtract(mNearPos);
      mNewObjPos.multiply(factor);
      mNewObjPos.add(mNearPos);

      return mNewObjPos;
    }
예제 #4
0
 /**
  * Subtracts the given {@link Matrix4} to this one.
  *
  * @param matrix {@link Matrix4} The matrix to subtract.
  * @return A reference to this {@link Matrix4} to facilitate chaining.
  */
 @NonNull
 public Matrix4 subtract(@NonNull Matrix4 matrix) {
   // @formatter:off
   matrix.toArray(mTmp);
   m[0] -= mTmp[0];
   m[1] -= mTmp[1];
   m[2] -= mTmp[2];
   m[3] -= mTmp[3];
   m[4] -= mTmp[4];
   m[5] -= mTmp[5];
   m[6] -= mTmp[6];
   m[7] -= mTmp[7];
   m[8] -= mTmp[8];
   m[9] -= mTmp[9];
   m[10] -= mTmp[10];
   m[11] -= mTmp[11];
   m[12] -= mTmp[12];
   m[13] -= mTmp[13];
   m[14] -= mTmp[14];
   m[15] -= mTmp[15];
   return this;
   // @formatter:on
 }
예제 #5
0
 /**
  * Adds the given {@link Matrix4} to this one.
  *
  * @param matrix {@link Matrix4} The matrix to add.
  * @return A reference to this {@link Matrix4} to facilitate chaining.
  */
 @NonNull
 public Matrix4 add(@NonNull Matrix4 matrix) {
   // @formatter:off
   matrix.toArray(mTmp);
   m[0] += mTmp[0];
   m[1] += mTmp[1];
   m[2] += mTmp[2];
   m[3] += mTmp[3];
   m[4] += mTmp[4];
   m[5] += mTmp[5];
   m[6] += mTmp[6];
   m[7] += mTmp[7];
   m[8] += mTmp[8];
   m[9] += mTmp[9];
   m[10] += mTmp[10];
   m[11] += mTmp[11];
   m[12] += mTmp[12];
   m[13] += mTmp[13];
   m[14] += mTmp[14];
   m[15] += mTmp[15];
   return this;
   // @formatter:on
 }
예제 #6
0
  public void render(
      long ellapsedTime, double deltaTime, RenderTarget renderTarget, Material sceneMaterial) {
    // Scene color-picking requests are relative to the prior frame's render
    // state, so handle any pending request before applying this frame's updates...
    if (mPickerInfo != null) {
      doColorPicking(mPickerInfo);
      // One-shot, once per frame at most
      mPickerInfo = null;
    }

    performFrameTasks(); // Handle the task queue

    synchronized (mFrameTaskQueue) {
      if (mLightsDirty) {
        updateMaterialsWithLights();
        mLightsDirty = false;
      }
    }

    synchronized (mNextSkyboxLock) {
      // Check if we need to switch the skybox, and if so, do it.
      if (mNextSkybox != null) {
        mSkybox = mNextSkybox;
        mNextSkybox = null;
      }
    }
    synchronized (mNextCameraLock) {
      // Check if we need to switch the camera, and if so, do it.
      if (mNextCamera != null) {
        mCamera = mNextCamera;
        mCamera.setProjectionMatrix(mRenderer.getViewportWidth(), mRenderer.getViewportHeight());
        mNextCamera = null;
      }
    }

    int clearMask = mAlwaysClearColorBuffer ? GLES20.GL_COLOR_BUFFER_BIT : 0;

    if (renderTarget != null) {
      renderTarget.bind();
      GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha);
    } else {
      //			GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
      GLES20.glClearColor(mRed, mGreen, mBlue, mAlpha);
    }

    if (mEnableDepthBuffer) {
      clearMask |= GLES20.GL_DEPTH_BUFFER_BIT;
      GLES20.glEnable(GLES20.GL_DEPTH_TEST);
      GLES20.glDepthFunc(GLES20.GL_LESS);
      GLES20.glDepthMask(true);
      GLES20.glClearDepthf(1.0f);
    }
    if (mAntiAliasingConfig.equals(ISurface.ANTI_ALIASING_CONFIG.COVERAGE)) {
      clearMask |= GL_COVERAGE_BUFFER_BIT_NV;
    }

    GLES20.glClear(clearMask);

    // Execute onPreFrame callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int preCount = mPreCallbacks.size();
    if (preCount > 0) {
      synchronized (mPreCallbacks) {
        for (int i = 0; i < preCount; ++i) {
          mPreCallbacks.get(i).onPreFrame(ellapsedTime, deltaTime);
        }
      }
    }

    // Update all registered animations
    synchronized (mAnimations) {
      for (int i = 0, j = mAnimations.size(); i < j; ++i) {
        Animation anim = mAnimations.get(i);
        if (anim.isPlaying()) anim.update(deltaTime);
      }
    }

    // We are beginning the render process so we need to update the camera matrix before fetching
    // its values
    mCamera.onRecalculateModelMatrix(null);

    // Get the view and projection matrices in advance
    mVMatrix = mCamera.getViewMatrix();
    mPMatrix = mCamera.getProjectionMatrix();
    // Pre-multiply View and Projection matrices once for speed
    mVPMatrix.setAll(mPMatrix).multiply(mVMatrix);
    mInvVPMatrix.setAll(mVPMatrix).inverse();
    mCamera.updateFrustum(mInvVPMatrix); // Update frustum plane

    // Update the model matrices of all the lights
    synchronized (mLights) {
      final int numLights = mLights.size();
      for (int i = 0; i < numLights; ++i) {
        mLights.get(i).onRecalculateModelMatrix(null);
      }
    }

    // Execute onPreDraw callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int preDrawCount = mPreDrawCallbacks.size();
    if (preDrawCount > 0) {
      synchronized (mPreDrawCallbacks) {
        for (int i = 0; i < preDrawCount; ++i) {
          mPreDrawCallbacks.get(i).onPreDraw(ellapsedTime, deltaTime);
        }
      }
    }

    if (mSkybox != null) {
      GLES20.glDisable(GLES20.GL_DEPTH_TEST);
      GLES20.glDepthMask(false);

      mSkybox.setPosition(mCamera.getX(), mCamera.getY(), mCamera.getZ());
      // Model matrix updates are deferred to the render method due to parent matrix needs
      // Render the skybox
      mSkybox.render(mCamera, mVPMatrix, mPMatrix, mVMatrix, null);

      if (mEnableDepthBuffer) {
        GLES20.glEnable(GLES20.GL_DEPTH_TEST);
        GLES20.glDepthMask(true);
      }
    }

    if (sceneMaterial != null) {
      sceneMaterial.useProgram();
      sceneMaterial.bindTextures();
    }

    synchronized (mChildren) {
      for (int i = 0, j = mChildren.size(); i < j; ++i) {
        // Model matrix updates are deferred to the render method due to parent matrix needs
        mChildren.get(i).render(mCamera, mVPMatrix, mPMatrix, mVMatrix, sceneMaterial);
      }
    }

    if (mDisplaySceneGraph) {
      mSceneGraph.displayGraph(mCamera, mVPMatrix, mPMatrix, mVMatrix);
    }

    if (sceneMaterial != null) {
      sceneMaterial.unbindTextures();
    }

    synchronized (mPlugins) {
      for (int i = 0, j = mPlugins.size(); i < j; i++) mPlugins.get(i).render();
    }

    if (renderTarget != null) {
      renderTarget.unbind();
    }

    // Execute onPostFrame callbacks
    // We explicitly break out the steps here to help the compiler optimize
    final int postCount = mPostCallbacks.size();
    if (postCount > 0) {
      synchronized (mPostCallbacks) {
        for (int i = 0; i < postCount; ++i) {
          mPostCallbacks.get(i).onPostFrame(ellapsedTime, deltaTime);
        }
      }
    }
  }
예제 #7
0
 /**
  * Left multiplies this {@link Matrix4} with the given one, storing the result in this {@link
  * Matrix}.
  *
  * <pre>
  * A.leftMultiply(B) results in A = BA.
  * </pre>
  *
  * @param matrix {@link Matrix4} The LHS {@link Matrix4}.
  * @return A reference to this {@link Matrix4} to facilitate chaining.
  */
 @NonNull
 public Matrix4 leftMultiply(@NonNull Matrix4 matrix) {
   System.arraycopy(m, 0, mTmp, 0, 16);
   Matrix.multiplyMM(m, 0, matrix.getDoubleValues(), 0, mTmp, 0);
   return this;
 }
예제 #8
0
 /**
  * Sets the elements of this {@link Matrix4} based on the elements of the provided {@link
  * Matrix4}.
  *
  * @param matrix {@link Matrix4} to copy.
  * @return A reference to this {@link Matrix4} to facilitate chaining.
  */
 @NonNull
 public Matrix4 setAll(@NonNull Matrix4 matrix) {
   matrix.toArray(m);
   return this;
 }
 /**
  * Calculates the model matrix for this {@link ATransformable3D} object.
  *
  * @param parentMatrix {@link Matrix4} The parent matrix, if any, to apply to this object.
  */
 public void calculateModelMatrix(final Matrix4 parentMatrix) {
   mMMatrix.setAll(mPosition, mScale, mOrientation);
   if (parentMatrix != null) {
     mMMatrix.leftMultiply(parentMatrix);
   }
 }