Пример #1
0
  /**
   * Locally applies the inverse of this transform to the given point: P' = M^{-1}*(P-T)
   *
   * @param thePoint
   * @return the transformed point.
   * @throws NullPointerException if point is null.
   */
  public CCVector3 applyInverse(final CCVector3 thePoint, CCVector3 theStore) {
    if (thePoint == null) {
      throw new NullPointerException();
    }
    if (theStore == null) theStore = new CCVector3(thePoint);

    if (_myIsIdentity) {
      // No need to make changes
      // P' = P
      return theStore;
    }

    // Back track translation
    theStore.subtractLocal(_myTranslation);

    if (_myIsRotationMatrix) {
      // Scale is separate from matrix so...
      // P' = S^{-1}*R^t*(P - T)
      theStore = _myMatrix.applyPre(theStore);
      if (_myIsUniformScale) {
        theStore.divideLocal(_myScale.x);
      } else {
        theStore.x = theStore.x / _myScale.x;
        theStore.y = theStore.y / _myScale.y;
        theStore.z = theStore.z / _myScale.z;
      }
    } else {
      // P' = M^{-1}*(P - T)
      final CCMatrix3x3 invertedMatrix = _myMatrix.invert();
      theStore = invertedMatrix.applyPost(theStore);
    }

    return theStore;
  }
Пример #2
0
  /**
   * Locally applies this transform to the given point: P' = M*P+T
   *
   * @param point
   * @return the transformed point.
   * @throws NullPointerException if point is null.
   */
  public CCVector3 applyForward(CCVector3 point, CCVector3 theStore) {
    if (point == null) {
      throw new NullPointerException();
    }
    if (theStore == null) theStore = new CCVector3();

    if (_myIsIdentity) {
      // No need to make changes
      // Y = X
      theStore.set(point);
      return theStore;
    }

    if (_myIsRotationMatrix) {
      // Scale is separate from matrix
      // Y = R*S*X + T
      theStore.set(point.x * _myScale.x, point.y * _myScale.y, point.z * _myScale.z);
      _myMatrix.applyPost(theStore, theStore);
      theStore.addLocal(_myTranslation);
      return theStore;
    }

    // scale is part of matrix.
    // Y = M*X + T
    _myMatrix.applyPost(point, theStore);
    theStore.addLocal(_myTranslation);
    return theStore;
  }
Пример #3
0
  /**
   * Locally applies this transform to the given vector: V' = M*V
   *
   * @param vector
   * @return the transformed vector.
   * @throws NullPointerException if vector is null.
   */
  public CCVector3 applyForwardVector(CCVector3 theVector, CCVector3 theStore) {
    if (theVector == null) {
      throw new NullPointerException();
    }
    if (theStore == null) {
      theStore = new CCVector3();
    }

    if (_myIsIdentity) {
      // No need to make changes
      // V' = V
      theStore.set(theVector);
      return theStore;
    }

    if (_myIsRotationMatrix) {
      // Scale is separate from matrix
      // V' = R*S*V
      theStore.set(theVector.x * _myScale.x, theVector.y * _myScale.y, theVector.z * _myScale.z);
      theStore = _myMatrix.applyPost(theStore);
      return theStore;
    }

    // scale is part of matrix.
    // V' = M*V
    theStore = _myMatrix.applyPost(theVector);
    return theStore;
  }
Пример #4
0
  /**
   * Locally applies the inverse of this transform to the given vector: V' = M^{-1}*V
   *
   * @param theVector
   * @return the transformed theVector.
   * @throws NullPointerException if vector is null.
   */
  public CCVector3 applyInverseVector(CCVector3 theVector) {
    if (theVector == null) {
      throw new NullPointerException();
    }

    theVector = theVector.clone();

    if (_myIsIdentity) {
      // No need to make changes
      // V' = V
      return theVector;
    }

    if (_myIsRotationMatrix) {
      // Scale is separate from matrix so...
      // V' = S^{-1}*R^t*V
      theVector = _myMatrix.applyPre(theVector);
      if (_myIsUniformScale) {
        theVector.divideLocal(_myScale.x);
      } else {
        theVector.x = theVector.x / _myScale.x;
        theVector.y = theVector.y / _myScale.y;
        theVector.z = theVector.z / _myScale.z;
      }
    } else {
      // V' = M^{-1}*V
      final CCMatrix3x3 invertedMatrix = _myMatrix.invert();
      theVector = invertedMatrix.applyPost(theVector);
    }

    return theVector;
  }
Пример #5
0
 /**
  * Resets this transform to identity and resets all flags.
  *
  * @return this Transform for chaining.
  */
 public CCTransform setIdentity() {
   _myMatrix.set(CCMatrix3x3.IDENTITY);
   _myScale.set(CCVector3.ONE);
   _myTranslation.set(CCVector3.ZERO);
   _myIsIdentity = true;
   _myIsRotationMatrix = true;
   _myIsUniformScale = true;
   return this;
 }
Пример #6
0
  /**
   * Constructs a new Transform object from the information stored in the given source Transform.
   *
   * @param theSource
   * @throws NullPointerException if source is null.
   */
  public CCTransform(final CCTransform theSource) {
    _myMatrix.set(theSource.getMatrix());
    _myScale.set(theSource.scale());
    _myTranslation.set(theSource.translation());

    _myIsIdentity = theSource.isIdentity();
    _myIsRotationMatrix = theSource.isRotationMatrix();
    _myIsUniformScale = theSource.isUniformScale();
  }
Пример #7
0
 /**
  * Used with serialization. Not to be called manually.
  *
  * @param in ObjectInput
  * @throws IOException
  * @throws ClassNotFoundException
  */
 @Override
 public void readExternal(final ObjectInput in) throws IOException, ClassNotFoundException {
   _myMatrix.set((CCMatrix3x3) in.readObject());
   _myScale.set((CCVector3) in.readObject());
   _myTranslation.set((CCVector3) in.readObject());
   _myIsIdentity = in.readBoolean();
   _myIsRotationMatrix = in.readBoolean();
   _myIsUniformScale = in.readBoolean();
 }
Пример #8
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;
  }
Пример #9
0
  /** @return returns a unique code for this transform object based on its values. */
  @Override
  public int hashCode() {
    int result = 17;

    result += 31 * result + _myMatrix.hashCode();
    result += 31 * result + _myScale.hashCode();
    result += 31 * result + _myTranslation.hashCode();

    return result;
  }
Пример #10
0
 /**
  * @param o the object to compare for equality
  * @return true if this transform and the provided transform have the exact same double values.
  */
 public boolean strictEquals(final Object o) {
   if (this == o) {
     return true;
   }
   if (!(o instanceof CCTransform)) {
     return false;
   }
   final CCTransform comp = (CCTransform) o;
   return _myMatrix.strictEquals(comp.getMatrix())
       && _myScale.equals(comp.scale())
       && _myTranslation.equals(comp.translation());
 }
Пример #11
0
  /**
   * Check a transform... if it is null or one of its members are invalid, return false. Else return
   * true.
   *
   * @param transform the transform to check
   * @return true or false as stated above.
   */
  public static boolean isValid(final CCTransform transform) {
    if (transform == null) {
      return false;
    }
    if (!CCVector3.isValid(transform.scale())
        || !CCVector3.isValid(transform.translation())
        || !CCMatrix3x3.isValid(transform.getMatrix())) {
      return false;
    }

    return true;
  }
Пример #12
0
 /**
  * Updates _rotationMatrix, _uniformScale and _identity based on the current contents of this
  * Transform.
  *
  * @param rotationMatrixGuaranteed true if we know for sure that the _matrix component is
  *     rotational.
  */
 protected void updateFlags(final boolean rotationMatrixGuaranteed) {
   _myIsIdentity =
       _myTranslation.equals(CCVector3.ZERO)
           && _myMatrix.isIdentity()
           && _myScale.equals(CCVector3.ONE);
   if (_myIsIdentity) {
     _myIsRotationMatrix = true;
     _myIsUniformScale = true;
   } else {
     _myIsRotationMatrix = rotationMatrixGuaranteed ? true : _myMatrix.isOrthonormal();
     _myIsUniformScale =
         _myIsRotationMatrix && _myScale.x == _myScale.y && _myScale.y == _myScale.z;
   }
 }
Пример #13
0
  /**
   * Copies the given transform values into this transform object.
   *
   * @param source
   * @return this transform for chaining.
   * @throws NullPointerException if source is null.
   */
  public CCTransform set(final CCTransform source) {
    if (source.isIdentity()) {
      setIdentity();
    } else {
      _myMatrix.set(source.getMatrix());
      _myScale.set(source.scale());
      _myTranslation.set(source.translation());

      _myIsIdentity = false;
      _myIsRotationMatrix = source.isRotationMatrix();
      _myIsUniformScale = source.isUniformScale();
    }
    return this;
  }
Пример #14
0
  /**
   * Internal only constructor, generally used for making an immutable transform.
   *
   * @param theMatrix
   * @param theScale
   * @param theTranslation
   * @param theIsIdentity
   * @param theIsRotationMatrix
   * @param theIsUniformScale
   * @throws NullPointerException if a param is null.
   */
  protected CCTransform(
      final CCMatrix3x3 theMatrix,
      final CCVector3 theScale,
      final CCVector3 theTranslation,
      final boolean theIsIdentity,
      final boolean theIsRotationMatrix,
      final boolean theIsUniformScale) {
    _myMatrix.set(theMatrix);
    _myScale.set(theScale);
    _myTranslation.set(theTranslation);

    _myIsIdentity = theIsIdentity;
    _myIsRotationMatrix = theIsRotationMatrix;
    _myIsUniformScale = theIsUniformScale;
  }
Пример #15
0
  /**
   * Sets the scale portion of this transform to the given values.
   *
   * @param x
   * @param y
   * @param z
   * @return this transform for chaining.
   * @throws NullPointerException if scale is null.
   * @throws CCTransformException if this transform has a generic 3x3 matrix set.
   * @throws IllegalArgumentException if scale is (0,0,0)
   */
  public CCTransform scale(final double x, final double y, final double z) {
    if (!_myIsRotationMatrix) {
      throw new CCTransformException(
          "Scale is already provided by 3x3 matrix.  If this is a mistake, consider using setRotation instead of setMatrix.");
    }
    if (x == 0.0 && y == 0.0 && z == 0.0) {
      throw new IllegalArgumentException("scale may not be ZERO.");
    }

    _myScale.set(x, y, z);
    _myIsIdentity = _myIsIdentity && x == 1.0 && y == 1.0 && z == 1.0;
    _myIsUniformScale = x == y && y == z;
    return this;
  }
Пример #16
0
  /**
   * Reads in a 4x4 matrix as a 3x3 matrix and translation.
   *
   * @param matrix
   * @return this matrix for chaining.
   * @throws NullPointerException if matrix is null.
   */
  public CCTransform fromHomogeneousMatrix(final CCMatrix4x4 matrix) {
    _myMatrix.set(
        matrix.m00,
        matrix.m10,
        matrix.m20,
        matrix.m01,
        matrix.m11,
        matrix.m21,
        matrix.m02,
        matrix.m12,
        matrix.m22);
    _myTranslation.set(matrix.m03, matrix.m13, matrix.m23);

    updateFlags(false);
    return this;
  }
Пример #17
0
 /**
  * Sets the translation portion of this transform to the given values.
  *
  * @param x
  * @param y
  * @param z
  * @return this transform for chaining.
  */
 public CCTransform translation(final double x, final double y, final double z) {
   _myTranslation.set(x, y, z);
   _myIsIdentity = false;
   return this;
 }
Пример #18
0
 /**
  * Locally adds to the translation of this transform.
  *
  * @param x
  * @param y
  * @param z
  * @return this transform for chaining.
  */
 public CCTransform translate(final double x, final double y, final double z) {
   _myTranslation.addLocal(x, y, z);
   _myIsIdentity = _myIsIdentity && _myTranslation.equals(CCVector3.ZERO);
   return this;
 }
Пример #19
0
 /**
  * Locally adds to the translation of this transform.
  *
  * @param vec
  * @return this transform for chaining.
  */
 public CCTransform translate(final CCVector3 vec) {
   _myTranslation.addLocal(vec);
   _myIsIdentity = _myIsIdentity && _myTranslation.equals(CCVector3.ZERO);
   return this;
 }