Imath::M44d AlembicInput::transformAtTime( double time ) const { M44d result; if( IXform::matches( m_data->object.getMetaData() ) ) { size_t index0, index1; double lerpFactor = sampleIntervalAtTime( time, index0, index1 ); IXform iXForm( m_data->object, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); if( index0 == index1 ) { XformSample sample; iXFormSchema.get( sample, ISampleSelector( (index_t)index0 ) ); result = sample.getMatrix(); } else { XformSample sample0; iXFormSchema.get( sample0, ISampleSelector( (index_t)index0 ) ); XformSample sample1; iXFormSchema.get( sample1, ISampleSelector( (index_t)index1 ) ); if( sample0.getNumOps() != sample1.getNumOps() || sample0.getNumOpChannels() != sample1.getNumOpChannels() ) { throw IECore::Exception( "Unable to interpolate samples of different sizes" ); } XformSample interpolatedSample; for( size_t opIndex = 0; opIndex < sample0.getNumOps(); opIndex++ ) { XformOp op0 = sample0.getOp( opIndex ); XformOp op1 = sample1.getOp( opIndex ); XformOp interpolatedOp( op0.getType(), op0.getHint() ); for( size_t channelIndex = 0; channelIndex < op0.getNumChannels(); channelIndex++ ) { interpolatedOp.setChannelValue( channelIndex, lerp( op0.getChannelValue( channelIndex ), op1.getChannelValue( channelIndex ), lerpFactor ) ); } interpolatedSample.addOp( interpolatedOp ); } result = interpolatedSample.getMatrix(); } } return result; }
Imath::M44d AlembicInput::transformAtSample( size_t sampleIndex ) const { M44d result; if( IXform::matches( m_data->object.getMetaData() ) ) { IXform iXForm( m_data->object, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); XformSample sample; iXFormSchema.get( sample, ISampleSelector( (index_t)sampleIndex ) ); return sample.getMatrix(); } return result; }
//-***************************************************************************** void accumXform( M44d &xf, IObject obj ) { if ( ISimpleXform::matches( obj.getMetaData() ) ) { ISimpleXform x( obj, kWrapExisting ); xf *= x.getSchema().getValue().getMatrix(); } else if ( IXform::matches( obj.getMetaData() ) ) { IXform x( obj, kWrapExisting ); XformSample xs; x.getSchema().get( xs ); xf *= xs.getMatrix(); } }
IECore::ObjectPtr FromAlembicXFormConverter::doAlembicConversion( const Alembic::Abc::IObject &iObject, const Alembic::Abc::ISampleSelector &sampleSelector, const IECore::CompoundObject *operands ) const { IXform iXForm( iObject, kWrapExisting ); IXformSchema &iXFormSchema = iXForm.getSchema(); XformSample sample; iXFormSchema.get( sample, sampleSelector ); M44d m = sample.getMatrix(); return new M44fData( M44f( m[0][0], m[0][1], m[0][2], m[0][3], m[1][0], m[1][1], m[1][2], m[1][3], m[2][0], m[2][1], m[2][2], m[2][3], m[3][0], m[3][1], m[3][2], m[3][3] ) ); }
void accumXform( Imath::M44d &xf, IObject obj, chrono_t curTime, bool interpolate) { if ( IXform::matches( obj.getHeader() ) ) { Imath::M44d mtx; IXform x( obj, kWrapExisting ); XformSample xs; x.getSchema().get( xs ); if (!x.getSchema().isConstant()) { TimeSamplingPtr timeSampler = x.getSchema().getTimeSampling(); if (interpolate) { //std::pair<index_t, chrono_t> lSamp;// = timeSampler->getFloorIndex(curTime, x.getSchema().getNumSamples()); Alembic::AbcCoreAbstract::index_t floorIdx, ceilIdx; double amt = getWeightAndIndex(curTime, timeSampler, x.getSchema().getNumSamples(), floorIdx, ceilIdx); if (amt != 0 && floorIdx != ceilIdx) { const ISampleSelector iss_start(floorIdx);//lSamp.first); Imath::M44d mtx_start = x.getSchema().getValue(iss_start).getMatrix(); //std::pair<index_t, chrono_t> rSamp = timeSampler->getCeilIndex(curTime, x.getSchema().getNumSamples()); const ISampleSelector iss_end(ceilIdx);//rSamp.first); Imath::M44d mtx_end = x.getSchema().getValue(iss_end).getMatrix(); Imath::V3d s_l,s_r,h_l,h_r,t_l,t_r; Imath::Quatd quat_l,quat_r; DecomposeXForm(mtx_start, s_l, h_l, quat_l, t_l); DecomposeXForm(mtx_end, s_r, h_r, quat_r, t_r); if ((quat_l ^ quat_r) < 0) { quat_r = -quat_r; } mtx = RecomposeXForm(Imath::lerp(s_l, s_r, amt), Imath::lerp(h_l, h_r, amt), Imath::slerp(quat_l, quat_r, amt), Imath::lerp(t_l, t_r, amt)); } else { const ISampleSelector iss(curTime); xs = x.getSchema().getValue(iss); mtx = xs.getMatrix(); } } else { // no interpolation, get nearest sample const ISampleSelector iss(curTime); xs = x.getSchema().getValue(iss); mtx = xs.getMatrix(); } } else { mtx = xs.getMatrix(); } xf *= mtx; } }
//-***************************************************************************** void xformIn() { IArchive archive( Alembic::AbcCoreOgawa::ReadArchive(), "Xform1.abc" ); Abc::M44d identity; XformSample xs; IXform a( IObject( archive, kTop ), "a" ); std::cout << "'a' num samples: " << a.getSchema().getNumSamples() << std::endl; TESTING_ASSERT( a.getSchema().getNumOps() == 1 ); TESTING_ASSERT( a.getSchema().getInheritsXforms() ); for ( index_t i = 0; i < 20; ++i ) { XformSample xs; a.getSchema().get( xs, Abc::ISampleSelector( i ) ); TESTING_ASSERT( xs.getNumOps() == 1 ); TESTING_ASSERT( xs[0].isTranslateOp() ); TESTING_ASSERT( xs[0].isYAnimated() == true ); TESTING_ASSERT( xs[0].isXAnimated() == false ); TESTING_ASSERT( xs[0].isZAnimated() == false ); TESTING_ASSERT( xs.getTranslation() == V3d( 12.0, i+42.0, 20.0 ) ); TESTING_ASSERT( xs.getMatrix() == Abc::M44d().setTranslation( V3d(12.0, i+42.0, 20.0)) ); } IXform b( a, "b" ); b.getSchema().get( xs ); TESTING_ASSERT( b.getSchema().getTimeSampling()->getTimeSamplingType().isUniform() ); // the schema is not static, because set() was called 20 times on it. TESTING_ASSERT( !b.getSchema().isConstant() ); TESTING_ASSERT( b.getSchema().getNumSamples() == 20 ); TESTING_ASSERT( xs.getNumOps() == 0 ); TESTING_ASSERT( b.getSchema().getNumOps() == 0 ); TESTING_ASSERT( xs.getMatrix() == identity ); for (size_t i = 0; i < 20; ++i) { AbcA::index_t j = i; TESTING_ASSERT( b.getSchema().getInheritsXforms( ISampleSelector( j ) ) == (i&1) ); } IXform c( b, "c" ); xs = c.getSchema().getValue(); TESTING_ASSERT( xs.getNumOps() == 0 ); TESTING_ASSERT( c.getSchema().getNumOps() == 0 ); TESTING_ASSERT( xs.getMatrix() == identity ); TESTING_ASSERT( c.getSchema().getInheritsXforms() ); TESTING_ASSERT( c.getSchema().isConstantIdentity() ); IXform d( c, "d" ); xs = d.getSchema().getValue(); TESTING_ASSERT( xs.getNumOps() == 1 ); TESTING_ASSERT( d.getSchema().getNumOps() == 1 ); TESTING_ASSERT( xs[0].isScaleOp() ); TESTING_ASSERT( ! ( xs[0].isXAnimated() || xs[0].isYAnimated() || xs[0].isZAnimated() ) ); TESTING_ASSERT( xs.getScale().equalWithAbsError( V3d( 3.0, 6.0, 9.0 ), VAL_EPSILON ) ); TESTING_ASSERT( xs.getMatrix() == Abc::M44d().setScale( V3d(3.0, 6.0, 9.0)) ); TESTING_ASSERT( d.getSchema().getInheritsXforms() ); IXform e( d, "e" ); TESTING_ASSERT( e.getSchema().isConstantIdentity() ); TESTING_ASSERT( e.getSchema().isConstant() ); TESTING_ASSERT( e.getSchema().getNumOps() == 3 ); IXform f( e, "f" ); TESTING_ASSERT( f.getSchema().isConstant() ); // is constant TESTING_ASSERT( ! f.getSchema().isConstantIdentity() ); // not identity IXform g( f, "g" ); Abc::M44d gmatrix; gmatrix.makeIdentity(); XformSample gsamp = g.getSchema().getValue(); TESTING_ASSERT( gsamp.getNumOps() == 20 ); TESTING_ASSERT( gsamp.getNumOpChannels() == 20 * 16 ); TESTING_ASSERT( g.getSchema().getNumSamples() == 1 ); TESTING_ASSERT( g.getSchema().isConstant() ); TESTING_ASSERT( !g.getSchema().isConstantIdentity() ); for ( size_t i = 0 ; i < 20 ; ++i ) { TESTING_ASSERT( gsamp[i].getChannelValue( 1 ) == (double)i ); } std::cout << "Tested all xforms in first test!" << std::endl; }