int main( int argc, char *argv[] ) { int size; int minsize = 2, count; MPI_Comm comm; int *buf, *bufout; MPI_Op op; MPI_Datatype mattype; MTest_Init( &argc, &argv ); MPI_Op_create( uop, 0, &op ); while (MTestGetIntracommGeneral( &comm, minsize, 1 )) { if (comm == MPI_COMM_NULL) { continue; } MPI_Comm_size( comm, &size ); matSize = size; /* Only one matrix for now */ count = 1; /* A single matrix, the size of the communicator */ MPI_Type_contiguous( size*size, MPI_INT, &mattype ); MPI_Type_commit( &mattype ); max_offset = count * size * size; buf = (int *)malloc( max_offset * sizeof(int) ); if (!buf) { MPI_Abort( MPI_COMM_WORLD, 1 ); } bufout = (int *)malloc( max_offset * sizeof(int) ); if (!bufout) { MPI_Abort( MPI_COMM_WORLD, 1 ); } initMat( comm, buf ); MPI_Allreduce( buf, bufout, count, mattype, op, comm ); errs += isIdentity( comm, bufout ); /* Try the same test, but using MPI_IN_PLACE */ initMat( comm, bufout ); MPI_Allreduce( MPI_IN_PLACE, bufout, count, mattype, op, comm ); errs += isIdentity( comm, bufout ); free( buf ); free( bufout ); //MPI_Type_free( &mattype ); MTestFreeComm( &comm ); } // MPI_Op_free( &op ); MTest_Finalize( errs ); MPI_Finalize(); return 0; }
//////////////////////////////////////////////////////////////////////////////// // The main function static OfxStatus pluginMain(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) { // cast to appropriate type OfxImageEffectHandle effect = (OfxImageEffectHandle ) handle; if(strcmp(action, kOfxActionDescribe) == 0) { return describe(effect); } else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) { return describeInContext(effect, inArgs); } else if(strcmp(action, kOfxActionCreateInstance) == 0) { return createInstance(effect); } else if(strcmp(action, kOfxActionDestroyInstance) == 0) { return destroyInstance(effect); } else if(strcmp(action, kOfxImageEffectActionIsIdentity) == 0) { return isIdentity(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionRender) == 0) { return render(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionGetClipPreferences) == 0) { return getClipPreferences(effect, inArgs, outArgs); } // other actions to take the default value return kOfxStatReplyDefault; }
void TransformationMatrix::blend(const TransformationMatrix& from, double progress) { if (from.isIdentity() && isIdentity()) return; // decompose DecomposedType fromDecomp; DecomposedType toDecomp; from.decompose(fromDecomp); decompose(toDecomp); // interpolate blendFloat(fromDecomp.scaleX, toDecomp.scaleX, progress); blendFloat(fromDecomp.scaleY, toDecomp.scaleY, progress); blendFloat(fromDecomp.scaleZ, toDecomp.scaleZ, progress); blendFloat(fromDecomp.skewXY, toDecomp.skewXY, progress); blendFloat(fromDecomp.skewXZ, toDecomp.skewXZ, progress); blendFloat(fromDecomp.skewYZ, toDecomp.skewYZ, progress); blendFloat(fromDecomp.translateX, toDecomp.translateX, progress); blendFloat(fromDecomp.translateY, toDecomp.translateY, progress); blendFloat(fromDecomp.translateZ, toDecomp.translateZ, progress); blendFloat(fromDecomp.perspectiveX, toDecomp.perspectiveX, progress); blendFloat(fromDecomp.perspectiveY, toDecomp.perspectiveY, progress); blendFloat(fromDecomp.perspectiveZ, toDecomp.perspectiveZ, progress); blendFloat(fromDecomp.perspectiveW, toDecomp.perspectiveW, progress); slerp(&fromDecomp.quaternionX, &toDecomp.quaternionX, progress); // recompose recompose(fromDecomp); }
void GetNonzerosSlice::simplifyMe(MX& ex) { // Simplify if identity if (isIdentity()) { MX t = dep(0); ex = t; } }
WPainterPath WTransform::map(const WPainterPath& path) const { if (isIdentity()) return path; WPainterPath result; if (isJavaScriptBound() || path.isJavaScriptBound()) { const WJavaScriptExposableObject *o = this; if (!isJavaScriptBound()) o = &path; result.assignBinding(*o, WT_CLASS ".gfxUtils.transform_apply(" + jsRef() + ',' + path.jsRef() + ')'); } const std::vector<WPainterPath::Segment> &sourceSegments = path.segments(); for (std::size_t i = 0; i < sourceSegments.size(); ++i) { double tx, ty; if (sourceSegments[i].type() == WPainterPath::Segment::ArcR || sourceSegments[i].type() == WPainterPath::Segment::ArcAngleSweep) { result.segments_.push_back(sourceSegments[i]); } else { map(sourceSegments[i].x(), sourceSegments[i].y(), &tx, &ty); result.segments_.push_back(WPainterPath::Segment(tx, ty, sourceSegments[i].type())); } } return result; }
WebTransformationMatrix WebTransformOperations::blend(const WebTransformOperations& from, double progress) const { WebTransformationMatrix toReturn; bool fromIdentity = from.isIdentity(); bool toIdentity = isIdentity(); if (fromIdentity && toIdentity) return toReturn; if (matchesTypes(from)) { size_t numOperations = max(fromIdentity ? 0 : from.m_private->operations.size(), toIdentity ? 0 : m_private->operations.size()); for (size_t i = 0; i < numOperations; ++i) { WebTransformationMatrix blended = blendTransformOperations( fromIdentity ? 0 : &from.m_private->operations[i], toIdentity ? 0 : &m_private->operations[i], progress); toReturn.multiply(blended); } } else { toReturn = apply(); WebTransformationMatrix fromTransform = from.apply(); toReturn.blend(fromTransform, progress); } return toReturn; }
WRectF WTransform::map(const WRectF& rect) const { if (isIdentity()) return rect; double minX, minY, maxX, maxY; WPointF p = map(rect.topLeft()); minX = maxX = p.x(); minY = maxY = p.y(); for (unsigned i = 0; i < 3; ++i) { WPointF p2 = map(i == 0 ? rect.bottomLeft() : i == 1 ? rect.topRight() : rect.bottomRight()); minX = std::min(minX, p2.x()); maxX = std::max(maxX, p2.x()); minY = std::min(minY, p2.y()); maxY = std::max(maxY, p2.y()); } WRectF result(minX, minY, maxX - minX, maxY - minY); if (isJavaScriptBound() || rect.isJavaScriptBound()) { const WJavaScriptExposableObject *o = this; if (rect.isJavaScriptBound()) o = ▭ result.assignBinding(*o, WT_CLASS ".gfxUtils.transform_mult(" + jsRef() + ',' + rect.jsRef() + ')'); } return result; }
//! Let this matrix be left-multiplied by m. Returns reference to self. matrix4<Type>& multLeft(const matrix4<Type>& m) { // Trivial cases if (m.isIdentity()) return *this; else if (isIdentity()) return (*this = m); matrix4<Type> tmp; tmp[0][0] = m.m_data[0][0] * m_data[0][0] + m.m_data[0][1] * m_data[1][0] + m.m_data[0][2] * m_data[2][0] + m.m_data[0][3] * m_data[3][0]; tmp[0][1] = m.m_data[0][0] * m_data[0][1] + m.m_data[0][1] * m_data[1][1] + m.m_data[0][2] * m_data[2][1] + m.m_data[0][3] * m_data[3][1]; tmp[0][2] = m.m_data[0][0] * m_data[0][2] + m.m_data[0][1] * m_data[1][2] + m.m_data[0][2] * m_data[2][2] + m.m_data[0][3] * m_data[3][2]; tmp[0][3] = m.m_data[0][0] * m_data[0][3] + m.m_data[0][1] * m_data[1][3] + m.m_data[0][2] * m_data[2][3] + m.m_data[0][3] * m_data[3][3]; tmp[1][0] = m.m_data[1][0] * m_data[0][0] + m.m_data[1][1] * m_data[1][0] + m.m_data[1][2] * m_data[2][0] + m.m_data[1][3] * m_data[3][0]; tmp[1][1] = m.m_data[1][0] * m_data[0][1] + m.m_data[1][1] * m_data[1][1] + m.m_data[1][2] * m_data[2][1] + m.m_data[1][3] * m_data[3][1]; tmp[1][2] = m.m_data[1][0] * m_data[0][2] + m.m_data[1][1] * m_data[1][2] + m.m_data[1][2] * m_data[2][2] + m.m_data[1][3] * m_data[3][2]; tmp[1][3] = m.m_data[1][0] * m_data[0][3] + m.m_data[1][1] * m_data[1][3] + m.m_data[1][2] * m_data[2][3] + m.m_data[1][3] * m_data[3][3]; tmp[2][0] = m.m_data[2][0] * m_data[0][0] + m.m_data[2][1] * m_data[1][0] + m.m_data[2][2] * m_data[2][0] + m.m_data[2][3] * m_data[3][0]; tmp[2][1] = m.m_data[2][0] * m_data[0][1] + m.m_data[2][1] * m_data[1][1] + m.m_data[2][2] * m_data[2][1] + m.m_data[2][3] * m_data[3][1]; tmp[2][2] = m.m_data[2][0] * m_data[0][2] + m.m_data[2][1] * m_data[1][2] + m.m_data[2][2] * m_data[2][2] + m.m_data[2][3] * m_data[3][2]; tmp[2][3] = m.m_data[2][0] * m_data[0][3] + m.m_data[2][1] * m_data[1][3] + m.m_data[2][2] * m_data[2][3] + m.m_data[2][3] * m_data[3][3]; tmp[3][0] = m.m_data[3][0] * m_data[0][0] + m.m_data[3][1] * m_data[1][0] + m.m_data[3][2] * m_data[2][0] + m.m_data[3][3] * m_data[3][0]; tmp[3][1] = m.m_data[3][0] * m_data[0][1] + m.m_data[3][1] * m_data[1][1] + m.m_data[3][2] * m_data[2][1] + m.m_data[3][3] * m_data[3][1]; tmp[3][2] = m.m_data[3][0] * m_data[0][2] + m.m_data[3][1] * m_data[1][2] + m.m_data[3][2] * m_data[2][2] + m.m_data[3][3] * m_data[3][2]; tmp[3][3] = m.m_data[3][0] * m_data[0][3] + m.m_data[3][1] * m_data[1][3] + m.m_data[3][2] * m_data[2][3] + m.m_data[3][3] * m_data[3][3]; return (*this = tmp); }
QRegion QMatrix::mapToRegion(const QRect &rect) const { QRegion result; if (isIdentity()) { result = rect; } else if (m12() == 0.0F && m21() == 0.0F) { int x = qRound(m11()*rect.x() + dx()); int y = qRound(m22()*rect.y() + dy()); int w = qRound(m11()*rect.width()); int h = qRound(m22()*rect.height()); if (w < 0) { w = -w; x -= w - 1; } if (h < 0) { h = -h; y -= h - 1; } result = QRect(x, y, w, h); } else { result = QRegion(mapToPolygon(rect)); } return result; }
static BOOLEAN factorGroupElt( const PermGroup *const G, /* The permutation group, as above. */ Permutation *const perm, /* The permutation to factor, as above. */ Permutation *const h, /* Set to the permutation h, as above. Must be preallocated of correct degree. */ Unsigned *const finalLevel) /* The value of j, as above. */ { Unsigned level, img; copyPermutation( perm, h); for ( level = 1 ; level <= G->baseSize ; ++level ) { img = h->image[G->base[level]]; if ( G->schreierVec[level][img] ) while ( G->schreierVec[level][img] != FIRST_IN_ORBIT ) { rightMultiplyInv( h, G->schreierVec[level][img]); img = h->image[G->base[level]]; } else break; } *finalLevel = level; if ( *finalLevel == G->baseSize+1 ) return isIdentity( h); else return FALSE; }
void Matrix4::mapRect(Rect& r) const { if (isIdentity()) return; if (isSimple()) { MUL_ADD_STORE(r.left, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.right, data[kScaleX], data[kTranslateX]); MUL_ADD_STORE(r.top, data[kScaleY], data[kTranslateY]); MUL_ADD_STORE(r.bottom, data[kScaleY], data[kTranslateY]); if (r.left > r.right) { float x = r.left; r.left = r.right; r.right = x; } if (r.top > r.bottom) { float y = r.top; r.top = r.bottom; r.bottom = y; } return; } float vertices[] = { r.left, r.top, r.right, r.top, r.right, r.bottom, r.left, r.bottom }; float x, y, z; for (int i = 0; i < 8; i+= 2) { float px = vertices[i]; float py = vertices[i + 1]; x = px * data[kScaleX] + py * data[kSkewX] + data[kTranslateX]; y = px * data[kSkewY] + py * data[kScaleY] + data[kTranslateY]; z = px * data[kPerspective0] + py * data[kPerspective1] + data[kPerspective2]; if (z) z = 1.0f / z; vertices[i] = x * z; vertices[i + 1] = y * z; } r.left = r.right = vertices[0]; r.top = r.bottom = vertices[1]; for (int i = 2; i < 8; i += 2) { x = vertices[i]; y = vertices[i + 1]; if (x < r.left) r.left = x; else if (x > r.right) r.right = x; if (y < r.top) r.top = y; else if (y > r.bottom) r.bottom = y; } }
bool IdentityToGroupTraverser::isTransformToReplace( const NodeSharedPtr & nh ) { bool ok = false; if( std::dynamic_pointer_cast<Transform>(nh) ) { TransformSharedPtr t = std::static_pointer_cast<Transform>(nh); ok = ( getIgnoreNames() || t->getName().empty() ) && optimizationAllowed( t ) && !t->isJoint() && isIdentity( t->getTrafo().getMatrix() ); } return( ok ); }
Transform Transform::relativeTransform(const Transform& worldTransform) const { if (isIdentity()) { return worldTransform; } if (*this == worldTransform) { return Transform(); } Transform result; inverseMult(result, *this, worldTransform); return result; }
Transform Transform::worldTransform(const Transform& relativeTransform) const { if (relativeTransform.isIdentity()) { return *this; } if (isIdentity()) { return relativeTransform; } Transform result; mult(result, *this, relativeTransform); return result; }
bool TransformationMatrix::decompose(DecomposedType& decomp) const { if (isIdentity()) { memset(&decomp, 0, sizeof(decomp)); decomp.perspectiveW = 1; decomp.scaleX = 1; decomp.scaleY = 1; decomp.scaleZ = 1; } if (!WebCore::decompose(m_matrix, decomp)) return false; return true; }
WTransform& WTransform::operator*= (const WTransform& Y) { if (isIdentity()) return operator=(Y); if (Y.isIdentity()) return *this; // conceptually: Z = Y * X // our transposed representation: Z = X * Y const WTransform& X = *this; if (isJavaScriptBound() || Y.isJavaScriptBound()) { const WJavaScriptExposableObject *o = this; if (!isJavaScriptBound()) o = &Y; assignBinding(*o, WT_CLASS ".gfxUtils.transform_mult(" + jsRef() + ',' + Y.jsRef() + ')'); } double z11 = X.m_[M11] * Y.m_[M11] + X.m_[M12] * Y.m_[M21] /* + X.m_[M13] * Y.m_[M31]=0*/; double z12 = X.m_[M11] * Y.m_[M12] + X.m_[M12] * Y.m_[M22] /* + X.m_[M13] * Y.m_[M32]=0*/; double z13 = X.m_[M11] * Y.m_[M13] + X.m_[M12] * Y.m_[M23] + X.m_[M13] /* * Y.m_[M33]=1*/; double z21 = X.m_[M21] * Y.m_[M11] + X.m_[M22] * Y.m_[M21] /* + X.m_[M23] * Y.m_[M31]=0*/; double z22 = X.m_[M21] * Y.m_[M12] + X.m_[M22] * Y.m_[M22] /* + X.m_[M23] * Y.m_[M32]=0*/; double z23 = X.m_[M21] * Y.m_[M13] + X.m_[M22] * Y.m_[M23] + X.m_[M23] /* * Y.m_[M33]=1*/; m_[M11] = z11; m_[M12] = z12; m_[M13] = z13; m_[M21] = z21; m_[M22] = z22; m_[M23] = z23; return *this; }
//////////////////////////////////////////////////////////////////////////////// // The main function static OfxStatus pluginMain(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) { // cast to appropriate type OfxImageEffectHandle effect = (OfxImageEffectHandle) handle; if(strcmp(action, kOfxActionDescribe) == 0) { return describe(effect); } else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) { return describeInContext(effect, inArgs); } else if(strcmp(action, kOfxActionLoad) == 0) { return onLoad(); } else if(strcmp(action, kOfxActionUnload) == 0) { return onUnLoad(); } else if(strcmp(action, kOfxActionCreateInstance) == 0) { return createInstance(effect); } else if(strcmp(action, kOfxActionDestroyInstance) == 0) { return destroyInstance(effect); } else if(strcmp(action, kOfxImageEffectActionIsIdentity) == 0) { return isIdentity(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionRender) == 0) { return render(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionGetRegionOfDefinition) == 0) { return getSpatialRoD(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionGetRegionsOfInterest) == 0) { return getSpatialRoI(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionGetClipPreferences) == 0) { return getClipPreferences(effect, inArgs, outArgs); } else if(strcmp(action, kOfxActionInstanceChanged) == 0) { return instanceChanged(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionGetTimeDomain) == 0) { return getTemporalDomain(effect, inArgs, outArgs); } // other actions to take the default value return kOfxStatReplyDefault; }
bool WebTransformOperations::matchesTypes(const WebTransformOperations& other) const { if (isIdentity() || other.isIdentity()) return true; if (m_private->operations.size() != other.m_private->operations.size()) return false; for (size_t i = 0; i < m_private->operations.size(); ++i) { if (m_private->operations[i].type != other.m_private->operations[i].type && !m_private->operations[i].isIdentity() && !other.m_private->operations[i].isIdentity()) return false; } return true; }
WPointF WTransform::map(const WPointF& p) const { if (isIdentity()) return p; double x, y; map(p.x(), p.y(), &x, &y); WPointF result(x, y); if (isJavaScriptBound() || p.isJavaScriptBound()) { const WJavaScriptExposableObject *o = this; if (p.isJavaScriptBound()) o = &p; result.assignBinding(*o, WT_CLASS ".gfxUtils.transform_mult(" + jsRef() + ',' + p.jsRef() + ')'); } return result; }
//////////////////////////////////////////////////////////////////////////////// // The main function static OfxStatus pluginMain(const char *action, const void *handle, OfxPropertySetHandle inArgs, OfxPropertySetHandle outArgs) { try { // cast to appropriate type OfxImageEffectHandle effect = (OfxImageEffectHandle) handle; if(strcmp(action, kOfxActionDescribe) == 0) { return describe(effect); } else if(strcmp(action, kOfxImageEffectActionDescribeInContext) == 0) { return describeInContext(effect, inArgs); } else if(strcmp(action, kOfxActionCreateInstance) == 0) { return createInstance(effect); } else if(strcmp(action, kOfxActionDestroyInstance) == 0) { return destroyInstance(effect); } else if(strcmp(action, kOfxImageEffectActionIsIdentity) == 0) { return isIdentity(effect, inArgs, outArgs); } else if(strcmp(action, kOfxImageEffectActionRender) == 0) { return render(effect, inArgs, outArgs); } } catch (std::bad_alloc) { // catch memory //std::cout << "OFX Plugin Memory error." << std::endl; return kOfxStatErrMemory; } catch ( const std::exception& e ) { // standard exceptions //std::cout << "OFX Plugin error: " << e.what() << std::endl; return kOfxStatErrUnknown; } catch (int err) { // ho hum, gone wrong somehow return err; } catch ( ... ) { // everything else //std::cout << "OFX Plugin error" << std::endl; return kOfxStatErrUnknown; } // other actions to take the default value return kOfxStatReplyDefault; }
void removeIdentityGens( PermGroup *const G) /* The group G mentioned above. */ { Permutation *gen, *tempGen; for ( gen = G->generator ; gen ; gen = gen->next ) if ( isIdentity( gen) ) { tempGen = gen; if ( tempGen->last ) { tempGen->last->next = tempGen->next; gen = tempGen->last; } else { G->generator = tempGen->next; gen = G->generator; } if ( tempGen->next ) tempGen->next->last = tempGen->last; deletePermutation( tempGen); } }
void GenericOCIO::apply(double time, const OfxRectI& renderWindow, float *pixelData, const OfxRectI& bounds, OFX::PixelComponentEnum pixelComponents, int pixelComponentCount, int rowBytes) { assert(_created); #ifdef OFX_IO_USING_OCIO if (!_config) { return; } if (isIdentity(time)) { return; } // are we in the image bounds if(renderWindow.x1 < bounds.x1 || renderWindow.x1 >= bounds.x2 || renderWindow.y1 < bounds.y1 || renderWindow.y1 >= bounds.y2 || renderWindow.x2 <= bounds.x1 || renderWindow.x2 > bounds.x2 || renderWindow.y2 <= bounds.y1 || renderWindow.y2 > bounds.y2) { _parent->setPersistentMessage(OFX::Message::eMessageError, "","OCIO: render window outside of image bounds"); OFX::throwSuiteStatusException(kOfxStatFailed); } if (pixelComponents != OFX::ePixelComponentRGBA && pixelComponents != OFX::ePixelComponentRGB) { _parent->setPersistentMessage(OFX::Message::eMessageError, "","OCIO: invalid components (only RGB and RGBA are supported)"); OFX::throwSuiteStatusException(kOfxStatFailed); } OCIOProcessor processor(*_parent); // set the images processor.setDstImg(pixelData, bounds, pixelComponents, pixelComponentCount, OFX::eBitDepthFloat, rowBytes); std::string inputSpace; getInputColorspaceAtTime(time, inputSpace); std::string outputSpace; getOutputColorspaceAtTime(time, outputSpace); OCIO::ConstContextRcPtr context = getLocalContext(time);//_config->getCurrentContext(); processor.setValues(_config, context, inputSpace, outputSpace); // set the render window processor.setRenderWindow(renderWindow); // Call the base class process member, this will call the derived templated process code processor.process(); #endif }
static bool shareSameAxis(const WebTransformOperation* from, const WebTransformOperation* to, double& axisX, double& axisY, double& axisZ, double& angleFrom) { if (isIdentity(from) && isIdentity(to)) return false; if (isIdentity(from) && !isIdentity(to)) { axisX = to->rotate.axis.x; axisY = to->rotate.axis.y; axisZ = to->rotate.axis.z; angleFrom = 0; return true; } if (!isIdentity(from) && isIdentity(to)) { axisX = from->rotate.axis.x; axisY = from->rotate.axis.y; axisZ = from->rotate.axis.z; angleFrom = from->rotate.angle; return true; } double length2 = from->rotate.axis.x * from->rotate.axis.x + from->rotate.axis.y * from->rotate.axis.y + from->rotate.axis.z * from->rotate.axis.z; double otherLength2 = to->rotate.axis.x * to->rotate.axis.x + to->rotate.axis.y * to->rotate.axis.y + to->rotate.axis.z * to->rotate.axis.z; if (length2 <= EPSILON || otherLength2 <= EPSILON) return false; double dot = to->rotate.axis.x * from->rotate.axis.x + to->rotate.axis.y * from->rotate.axis.y + to->rotate.axis.z * from->rotate.axis.z; double error = fabs(1.0 - (dot * dot) / (length2 * otherLength2)); bool result = error < EPSILON; if (result) { axisX = to->rotate.axis.x; axisY = to->rotate.axis.y; axisZ = to->rotate.axis.z; // If the axes are pointing in opposite directions, we need to reverse // the angle. angleFrom = dot > 0 ? from->rotate.angle : -from->rotate.angle; } return result; }
/*! Using an algorithm from Graphics Gems IV (p554), * Gauss-Jordan elimination with partial pivoting. * Source copied from Aqsis renderer * \retval mat The inverse matrix * \return true: Inverse could be calculated, false: otherwise */ bool TMatrix3D::getInverse(RtMatrix &mat) const { if ( isIdentity() ) { get(mat); return true; } TMatrix3D b; // b evolves from identity into inverse(a) TMatrix3D a(*this); // a evolves from original matrix into identity b.identity(); int i; int j; int i1; // Loop over cols of a from left to right, eliminating above and below diag for (j = 0; j < 4; j++) // Find largest pivot in column j among rows j..3 { i1 = j; for(i = j + 1; i < 4; i++) { if(fabs(a.m_Matrix[i][j]) > fabs(a.m_Matrix[i1][j])) { i1 = i; } } if (i1 != j) { // Swap rows i1 and j in a and b to put pivot on diagonal RtFloat temp; temp = a.m_Matrix[i1][0]; a.m_Matrix[i1][0] = a.m_Matrix[j][0]; a.m_Matrix[j][0] = temp; temp = a.m_Matrix[i1][1]; a.m_Matrix[i1][1] = a.m_Matrix[j][1]; a.m_Matrix[j][1] = temp; temp = a.m_Matrix[i1][2]; a.m_Matrix[i1][2] = a.m_Matrix[j][2]; a.m_Matrix[j][2] = temp; temp = a.m_Matrix[i1][3]; a.m_Matrix[i1][3] = a.m_Matrix[j][3]; a.m_Matrix[j][3] = temp; temp = b.m_Matrix[i1][0]; b.m_Matrix[i1][0] = b.m_Matrix[j][0]; b.m_Matrix[j][0] = temp; temp = b.m_Matrix[i1][1]; b.m_Matrix[i1][1] = b.m_Matrix[j][1]; b.m_Matrix[j][1] = temp; temp = b.m_Matrix[i1][2]; b.m_Matrix[i1][2] = b.m_Matrix[j][2]; b.m_Matrix[j][2] = temp; temp = b.m_Matrix[i1][3]; b.m_Matrix[i1][3] = b.m_Matrix[j][3]; b.m_Matrix[j][3] = temp; } // Scale row j to have a unit diagonal if( a.m_Matrix[j][j] == 0.0 ) { // Can't invert a singular matrix! return false; } RtFloat scale = (RtFloat)(1.0 / a.m_Matrix[j][j]); b.m_Matrix[j][0] *= scale; b.m_Matrix[j][1] *= scale; b.m_Matrix[j][2] *= scale; b.m_Matrix[j][3] *= scale; // all elements to left of a[j][j] are already zero for (i1=j+1; i1<4; i1++) { a.m_Matrix[j][i1] *= scale; } a.m_Matrix[j][j] = 1.0; // Eliminate off-diagonal elements in column j of a, doing identical ops to b for(i = 0; i < 4; i++) { if(i != j) { scale = a.m_Matrix[i][j]; b.m_Matrix[i][0] -= scale * b.m_Matrix[j][0]; b.m_Matrix[i][1] -= scale * b.m_Matrix[j][1]; b.m_Matrix[i][2] -= scale * b.m_Matrix[j][2]; b.m_Matrix[i][3] -= scale * b.m_Matrix[j][3]; // all elements to left of a[j][j] are zero // a[j][j] is 1.0 for (i1=j+1; i1<4; i1++) { a.m_Matrix[i][i1] -= scale * a.m_Matrix[j][i1]; } a.m_Matrix[i][j] = 0.0; } } } b.get(mat); return true; }
bool MatrixOpData::isNoOp() const { return (getInputBitDepth() == getOutputBitDepth()) && isIdentity(); }
RiCPPInvertMatrix (const RtMatrix matrix, RtMatrix inverse) { if ( isIdentity(matrix) ) { memcpy(inverse, matrix, sizeof(16*sizeof(RtFloat))); return RI_TRUE; } RtMatrix b; // b evolves from identity into inverse(a) RtMatrix a; // a evolves from original matrix into identity memcpy(a, matrix, sizeof(16*sizeof(RtFloat))); setIdentity(b); int i; int j; int i1; // Loop over cols of a from left to right, eliminating above and below diag for (j = 0; j < 4; j++) // Find largest pivot in column j among rows j..3 { i1 = j; for(i = j + 1; i < 4; i++) { if(fabs(a[i][j]) > fabs(a[i1][j])) { i1 = i; } } if (i1 != j) { // Swap rows i1 and j in a and b to put pivot on diagonal RtFloat temp; temp = a[i1][0]; a[i1][0] = a[j][0]; a[j][0] = temp; temp = a[i1][1]; a[i1][1] = a[j][1]; a[j][1] = temp; temp = a[i1][2]; a[i1][2] = a[j][2]; a[j][2] = temp; temp = a[i1][3]; a[i1][3] = a[j][3]; a[j][3] = temp; temp = b[i1][0]; b[i1][0] = b[j][0]; b[j][0] = temp; temp = b[i1][1]; b[i1][1] = b[j][1]; b[j][1] = temp; temp = b[i1][2]; b[i1][2] = b[j][2]; b[j][2] = temp; temp = b[i1][3]; b[i1][3] = b[j][3]; b[j][3] = temp; } // Scale row j to have a unit diagonal if( a[j][j] == 0.0 ) { // Can't invert a singular matrix! return RI_FALSE; } RtFloat scale = (RtFloat)(1.0 / a[j][j]); b[j][0] *= scale; b[j][1] *= scale; b[j][2] *= scale; b[j][3] *= scale; // all elements to left of a[j][j] are already zero for (i1=j+1; i1<4; i1++) { a[j][i1] *= scale; } a[j][j] = 1.0; // Eliminate off-diagonal elements in column j of a, doing identical ops to b for(i = 0; i < 4; i++) { if(i != j) { scale = a[i][j]; b[i][0] -= scale * b[j][0]; b[i][1] -= scale * b[j][1]; b[i][2] -= scale * b[j][2]; b[i][3] -= scale * b[j][3]; // all elements to left of a[j][j] are zero // a[j][j] is 1.0 for (i1=j+1; i1<4; i1++) { a[i][i1] -= scale * a[j][i1]; } a[i][j] = 0.0; } } } memcpy(inverse, b, sizeof(b)); return RI_TRUE; }
static WebTransformationMatrix blendTransformOperations(const WebTransformOperation* from, const WebTransformOperation* to, double progress) { WebTransformationMatrix toReturn; if (isIdentity(from) && isIdentity(to)) return toReturn; WebTransformOperation::Type interpolationType = WebTransformOperation::WebTransformOperationIdentity; if (isIdentity(to)) interpolationType = from->type; else interpolationType = to->type; switch (interpolationType) { case WebTransformOperation::WebTransformOperationTranslate: { double fromX = isIdentity(from) ? 0 : from->translate.x; double fromY = isIdentity(from) ? 0 : from->translate.y; double fromZ = isIdentity(from) ? 0 : from->translate.z; double toX = isIdentity(to) ? 0 : to->translate.x; double toY = isIdentity(to) ? 0 : to->translate.y; double toZ = isIdentity(to) ? 0 : to->translate.z; toReturn.translate3d(blendDoubles(fromX, toX, progress), blendDoubles(fromY, toY, progress), blendDoubles(fromZ, toZ, progress)); break; } case WebTransformOperation::WebTransformOperationRotate: { double axisX = 0; double axisY = 0; double axisZ = 1; double fromAngle = 0; double toAngle = isIdentity(to) ? 0 : to->rotate.angle; if (shareSameAxis(from, to, axisX, axisY, axisZ, fromAngle)) toReturn.rotate3d(axisX, axisY, axisZ, blendDoubles(fromAngle, toAngle, progress)); else { WebTransformationMatrix toMatrix; if (!isIdentity(to)) toMatrix = to->matrix; WebTransformationMatrix fromMatrix; if (!isIdentity(from)) fromMatrix = from->matrix; toReturn = toMatrix; toReturn.blend(fromMatrix, progress); } break; } case WebTransformOperation::WebTransformOperationScale: { double fromX = isIdentity(from) ? 1 : from->scale.x; double fromY = isIdentity(from) ? 1 : from->scale.y; double fromZ = isIdentity(from) ? 1 : from->scale.z; double toX = isIdentity(to) ? 1 : to->scale.x; double toY = isIdentity(to) ? 1 : to->scale.y; double toZ = isIdentity(to) ? 1 : to->scale.z; toReturn.scale3d(blendDoubles(fromX, toX, progress), blendDoubles(fromY, toY, progress), blendDoubles(fromZ, toZ, progress)); break; } case WebTransformOperation::WebTransformOperationSkew: { double fromX = isIdentity(from) ? 0 : from->skew.x; double fromY = isIdentity(from) ? 0 : from->skew.y; double toX = isIdentity(to) ? 0 : to->skew.x; double toY = isIdentity(to) ? 0 : to->skew.y; toReturn.skewX(blendDoubles(fromX, toX, progress)); toReturn.skewY(blendDoubles(fromY, toY, progress)); break; } case WebTransformOperation::WebTransformOperationPerspective: { double fromPerspectiveDepth = isIdentity(from) ? numeric_limits<double>::max() : from->perspectiveDepth; double toPerspectiveDepth = isIdentity(to) ? numeric_limits<double>::max() : to->perspectiveDepth; toReturn.applyPerspective(blendDoubles(fromPerspectiveDepth, toPerspectiveDepth, progress)); break; } case WebTransformOperation::WebTransformOperationMatrix: { WebTransformationMatrix toMatrix; if (!isIdentity(to)) toMatrix = to->matrix; WebTransformationMatrix fromMatrix; if (!isIdentity(from)) fromMatrix = from->matrix; toReturn = toMatrix; toReturn.blend(fromMatrix, progress); break; } case WebTransformOperation::WebTransformOperationIdentity: // Do nothing. break; } return toReturn; }