//-***************************************************************************** M44d getFinalMatrix( IObject &iObj ) { M44d xf; xf.makeIdentity(); IObject parent = iObj.getParent(); while ( parent ) { accumXform( xf, parent ); parent = parent.getParent(); } return xf; }
void FrustumFieldMapping::reset() { // Default camera to world --- M44d csToWs; csToWs.makeIdentity(); // Default screen to world --- double near = 1; double far = 2; double fovRadians = 45.0 * M_PI / 180.0; double invTan = 1.0 / std::tan(fovRadians / 2.0); double imageAspectRatio = 1.0; M44d perspective(1, 0, 0, 0, 0, 1, 0, 0, 0, 0, (far) / (far - near), 1, 0, 0, (- far * near) / (far - near), 0); M44d fov; fov.setScale(V3d(invTan / imageAspectRatio, invTan, 1.0)); M44d flipZ; flipZ.setScale(V3d(1.0, 1.0, -1.0)); M44d csToSs = flipZ * perspective * fov; M44d standardSsToWs = csToSs.inverse() * csToWs; // Set default state --- clearCurves(); setTransforms(standardSsToWs, csToWs); m_defaultState = true; computeVoxelSize(); }
//-***************************************************************************** void xformOut() { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), "Xform1.abc" ); OXform a( OObject( archive, kTop ), "a" ); OXform b( a, "b" ); OXform c( b, "c" ); OXform d( c, "d" ); OXform e( d, "e" ); OXform f( e, "f" ); OXform g( f, "g" ); XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformOp matrixop( kMatrixOperation, kMatrixHint ); TESTING_ASSERT( a.getSchema().getNumSamples() == 0 ); OBox3dProperty childBounds = a.getSchema().getChildBoundsProperty(); XformSample asamp; for ( size_t i = 0; i < 20; ++i ) { asamp.addOp( transop, V3d( 12.0, i + 42.0, 20.0 ) ); if ( i >= 18 ) { childBounds.set( Abc::Box3d( V3d( -1.0, -1.0, -1.0 ), V3d( 1.0, 1.0, 1.0 ) ) ); } else { childBounds.set( Abc::Box3d() ); } a.getSchema().set( asamp ); } XformSample bsamp; for ( size_t i = 0 ; i < 20 ; ++i ) { bsamp.setInheritsXforms( (bool)(i&1) ); b.getSchema().set( bsamp ); } // for c we write nothing XformSample dsamp; dsamp.addOp( scaleop, V3d( 3.0, 6.0, 9.0 ) ); d.getSchema().set( dsamp ); XformSample esamp; M44d identmat; identmat.makeIdentity(); esamp.addOp( transop, V3d( 0.0, 0.0, 0.0 ) ); esamp.addOp( XformOp( kMatrixOperation, kMatrixHint ), identmat ); esamp.addOp( scaleop, V3d( 1.0, 1.0, 1.0 ) ); e.getSchema().set( esamp ); XformSample fsamp; fsamp.addOp( transop, V3d( 3.0, -4.0, 5.0 ) ); f.getSchema().set( fsamp ); // this will cause the Xform's values property to be an ArrayProperty, // since there will be 20 * 16 channels. XformSample gsamp; Abc::M44d gmatrix; gmatrix.makeIdentity(); for ( size_t i = 0 ; i < 20 ; ++i ) { gmatrix.x[0][1] = (double)i; gsamp.addOp( matrixop, gmatrix ); } g.getSchema().set( gsamp ); }
//-***************************************************************************** void someOpsXform() { std::string name = "someOpsXform.abc"; { OArchive archive( Alembic::AbcCoreOgawa::WriteArchive(), name ); OXform a( OObject( archive, kTop ), "a" ); OBox3dProperty bnds = CreateOArchiveBounds( archive ); XformOp transop( kTranslateOperation, kTranslateHint ); XformOp scaleop( kScaleOperation, kScaleHint ); XformSample asamp; // scale asamp.addOp( scaleop, V3d( 2.0, 1.0, 2.0 ) ); // Maya-like shear XformOp shearmatrixop( kMatrixOperation, kMayaShearHint ); M44d shearmat; shearmat.makeIdentity(); asamp.addOp( shearmatrixop, shearmat ); // rotate x axis XformOp rotop( kRotateOperation, kRotateHint ); asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ), 1.57 ); // rotate y axis, angle will be animated asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ), 0.125 ); // rotate z axis, use a different hint for fun XformOp rotorientop( kRotateOperation, kRotateOrientationHint ); asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ), 0.1 ); // translate with animated y and z, different hint for fun XformOp transpivotop( kTranslateOperation, kRotatePivotPointHint ); asamp.addOp( transpivotop, V3d( 0.0, 0.0, 0.0 ) ); a.getSchema().set( asamp ); bnds.set( Box3d( V3d( -0.1, -0.1, -0.1 ), V3d( 0.1, 0.1, 0.1 ) ) ); for (size_t i = 1; i < 5 ; ++i) { asamp.addOp( scaleop, V3d( 2 * ( i + 1 ), 1.0, 2.0 ) ); shearmat.x[1][0] = (double)i; shearmat.x[2][0] = (double)( (int)i * -1.0 ); shearmat.x[2][1] = 0.0; asamp.addOp( shearmatrixop, shearmat ); asamp.addOp( rotop, V3d( 1.0, 0.0, 0.0 ), 1.57 ); asamp.addOp( rotop, V3d( 0.0, 1.0, 0.0 ), 0.125 * ( i + 1 ) ); asamp.addOp( rotorientop, V3d( 0.0, 0.0, 1.0 ), 0.1 * ( i + 1 ) ); asamp.addOp( transpivotop, V3d( 0.0, 3.0 * i, 4.0 * i ) ); a.getSchema().set( asamp ); double iVal = static_cast< double >( i ); bnds.set( Box3d( V3d( -iVal, -iVal, -iVal ), V3d( iVal, iVal, iVal ) ) ); } } { IArchive archive( Alembic::AbcCoreOgawa::ReadArchive(), name ); IXform a( IObject( archive, kTop ), "a" ); IBox3dProperty bnds = GetIArchiveBounds( archive ); XformSample asamp; a.getSchema().get( asamp ); TESTING_ASSERT( a.getSchema().getNumOps() == 6 ); TESTING_ASSERT( asamp[0].isScaleOp() ); TESTING_ASSERT( asamp[0].getHint() == kScaleHint ); TESTING_ASSERT( asamp[1].isMatrixOp() ); TESTING_ASSERT( asamp[1].getHint() == kMayaShearHint ); TESTING_ASSERT( asamp[2].isRotateOp() ); TESTING_ASSERT( asamp[2].getHint() == kRotateHint ); TESTING_ASSERT( asamp[3].getType() == kRotateOperation ); TESTING_ASSERT( asamp[3].getHint() == kRotateHint ); TESTING_ASSERT( asamp[4].getType() == kRotateOperation ); TESTING_ASSERT( asamp[4].getHint() == kRotateOrientationHint ); TESTING_ASSERT( asamp[5].getType() == kTranslateOperation ); TESTING_ASSERT( asamp[5].getHint() == kRotatePivotPointHint ); TESTING_ASSERT( asamp[0].isXAnimated() ); TESTING_ASSERT( !asamp[0].isYAnimated() ); TESTING_ASSERT( !asamp[0].isZAnimated() ); TESTING_ASSERT( !asamp[1].isChannelAnimated(0) ); // [0][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(1) ); // [0][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(2) ); // [0][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(3) ); // [0][3] TESTING_ASSERT( asamp[1].isChannelAnimated(4) ); // [1][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(5) ); // [1][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(6) ); // [1][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(7) ); // [1][3] TESTING_ASSERT( asamp[1].isChannelAnimated(8) ); // [2][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(9) ); // [2][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(10) ); // [2][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(11) ); // [2][3] TESTING_ASSERT( !asamp[1].isChannelAnimated(12) ); // [3][0] TESTING_ASSERT( !asamp[1].isChannelAnimated(13) ); // [3][1] TESTING_ASSERT( !asamp[1].isChannelAnimated(14) ); // [3][2] TESTING_ASSERT( !asamp[1].isChannelAnimated(15) ); // [3][3] TESTING_ASSERT( !asamp[2].isXAnimated() ); TESTING_ASSERT( !asamp[2].isYAnimated() ); TESTING_ASSERT( !asamp[2].isZAnimated() ); TESTING_ASSERT( !asamp[2].isAngleAnimated() ); TESTING_ASSERT( !asamp[3].isXAnimated() ); TESTING_ASSERT( !asamp[3].isYAnimated() ); TESTING_ASSERT( !asamp[3].isZAnimated() ); TESTING_ASSERT( asamp[3].isAngleAnimated() ); TESTING_ASSERT( !asamp[4].isXAnimated() ); TESTING_ASSERT( !asamp[4].isYAnimated() ); TESTING_ASSERT( !asamp[4].isZAnimated() ); TESTING_ASSERT( asamp[4].isAngleAnimated() ); TESTING_ASSERT( !asamp[5].isXAnimated() ); TESTING_ASSERT( asamp[5].isYAnimated() ); TESTING_ASSERT( asamp[5].isZAnimated() ); // OK, now check the values came through M44d shearmat; shearmat.makeIdentity(); TESTING_ASSERT( asamp[0].getScale() == V3d( 2.0, 1.0, 2.0 ) ); TESTING_ASSERT( asamp[1].getMatrix() == shearmat ); TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) ); TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[3].getAngle(), 0.125 ) ); TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) ); TESTING_ASSERT( almostEqual( asamp[4].getAngle(), 0.1 ) ); TESTING_ASSERT( asamp[5].getTranslate() == V3d( 0.0, 0.0, 0.0 ) ); TESTING_ASSERT( bnds.getValue() == Box3d( V3d( -0.1, -0.1, -0.1 ), V3d( 0.1, 0.1, 0.1 ) ) ); for ( index_t i = 1; i < 5 ; ++i ) { a.getSchema().get( asamp, ISampleSelector( i ) ); TESTING_ASSERT( asamp[0].getScale() == V3d( 2 * ( i + 1 ), 1.0, 2.0 ) ); shearmat.x[1][0] = (double)i; shearmat.x[2][0] = (double)( (int)i * -1.0 ); shearmat.x[2][1] = 0.0; TESTING_ASSERT( asamp[1].getMatrix() == shearmat ); TESTING_ASSERT( asamp[2].getAxis() == V3d( 1.0, 0.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[2].getAngle(), 1.57 ) ); TESTING_ASSERT( asamp[3].getAxis() == V3d( 0.0, 1.0, 0.0 ) ); TESTING_ASSERT( almostEqual( asamp[3].getAngle(), 0.125 * ( i + 1 ) ) ); TESTING_ASSERT( asamp[4].getAxis() == V3d( 0.0, 0.0, 1.0 ) ); TESTING_ASSERT( almostEqual( asamp[4].getAngle(), 0.1 * ( i + 1 ) ) ); V3d tvec( 0.0, 3.0 * i, 4.0 * i ); TESTING_ASSERT( tvec.equalWithAbsError( asamp[5].getTranslate(), VAL_EPSILON ) ); Box3d b = bnds.getValue( ISampleSelector( i ) ); double iVal = static_cast< double >( i ); TESTING_ASSERT( b == Box3d( V3d( -iVal, -iVal, -iVal ), V3d( iVal, iVal, iVal ) ) ); } std::cout << "tested all xforms in " << name << std::endl; } }