/** * 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; }
/** * Calculates the inverse of this transform. * * @return the inverted transform */ public CCTransform invert() { CCTransform result = new CCTransform(); if (_myIsIdentity) { result.setIdentity(); return result; } result._myMatrix.set(_myMatrix); if (_myIsRotationMatrix) { if (_myIsUniformScale) { final double sx = _myScale.x; result._myMatrix.transposeLocal(); if (sx != 1.0) { result._myMatrix.multiplyLocal(1.0f / sx); } } else { result._myMatrix.set(result._myMatrix.multiplyDiagonalPost(_myScale).invertLocal()); } } else { result._myMatrix.invertLocal(); } result._myTranslation.set(result._myMatrix.applyPost(_myTranslation).negateLocal()); result.updateFlags(_myIsRotationMatrix); return result; }
/** * 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; }
public void rotate( final double theAngle, final double theX, final double theY, final double theZ) { _myMatrix.applyRotation(theAngle, theX, theY, theZ); updateFlags(true); // rotation(new CCQuaternion().applyRotation(theAngle, theX, theY, theZ)); }
public void rotation(final double theAngle, final CCVector3 theAxis) { _myMatrix.fromAngleNormalAxis(theAngle, theAxis); updateFlags(true); // rotation(new CCQuaternion().applyRotation(theAngle, theAxis.x, theAxis.y, theAxis.z)); }
/** * Sets the matrix portion of this transform to the rotational value of the given Quaternion. * Calling this allows scale to be set and used. * * @param theRotation * @return this transform for chaining. * @throws NullPointerException if rotation is null. */ public CCTransform rotation(final CCQuaternion theRotation) { _myMatrix.set(theRotation); updateFlags(true); return this; }
/** * Sets the matrix portion of this transform to the given value. * * <p>NB: Calling this with a matrix that is not purely rotational (orthonormal) will result in a * Transform whose scale comes from its matrix. Further attempts to set scale directly will throw * an error. * * @param theRotation our new matrix. * @return this transform for chaining. * @throws NullPointerException if rotation is null. * @see CCMatrix3x3#isOrthonormal() */ public CCTransform rotation(final CCMatrix3x3 theRotation) { _myMatrix.set(theRotation); updateFlags(false); return this; }