示例#1
0
  /**
   * Calculates the product of this transform with the given "transformBy" transform (P = this * T)
   * and stores this in store.
   *
   * @param transformBy
   * @return the product
   * @throws NullPointerException if transformBy is null.
   */
  public CCTransform multiply(final CCTransform transformBy, CCTransform theStore) {
    if (theStore == null) theStore = new CCTransform();

    if (_myIsIdentity) {
      return theStore.set(transformBy);
    }

    if (transformBy.isIdentity()) {
      return theStore.set(this);
    }

    if (_myIsRotationMatrix && transformBy.isRotationMatrix() && _myIsUniformScale) {
      theStore._myIsRotationMatrix = true;
      theStore._myMatrix.set(_myMatrix).multiplyLocal(transformBy.getMatrix());

      theStore._myTranslation.set(transformBy.translation());
      theStore._myTranslation.set(_myMatrix.applyPost(theStore._myTranslation));
      // uniform scale, so just use X.
      theStore._myTranslation.multiplyLocal(_myScale.x);
      theStore._myTranslation.addLocal(_myTranslation);

      if (transformBy.isUniformScale()) {
        theStore.scale(_myScale.x * transformBy.scale().x);
      } else {
        final CCVector3 scale = theStore._myScale.set(transformBy.scale());
        scale.multiplyLocal(_myScale.x);
      }

      // update our flags in one place.
      theStore.updateFlags(true);

      return theStore;
    }

    // In all remaining cases, the matrix cannot be written as R*S*X+T.
    final CCMatrix3x3 matrixA =
        isRotationMatrix() ? _myMatrix.multiplyDiagonalPost(_myScale) : _myMatrix;

    final CCMatrix3x3 matrixB =
        transformBy.isRotationMatrix()
            ? transformBy.getMatrix().multiplyDiagonalPost(transformBy.scale())
            : transformBy.getMatrix();

    final CCMatrix3x3 newMatrix = theStore._myMatrix;
    newMatrix.set(matrixA).multiplyLocal(matrixB);

    theStore._myTranslation.set(
        matrixA.applyPost(transformBy.translation()).addLocal(translation()));

    // prevent scale bleeding since we don't set it.
    theStore._myScale.set(1.0f, 1.0f, 1.0f);

    // update our flags in one place.
    theStore.updateFlags(false);

    return theStore;
  }