/** * 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; }