int rec(const string &s) { StringIntMap::const_iterator it = M.find(s); if (it != M.end()) { return it->second; } char temp[64]; strcpy(temp, s.c_str()); char *fg = strchr(temp, 'G'); char *rr = strrchr(temp, 'R'); int f = 0; int r = 0; if (rr > fg) { if (fg != NULL) { *fg = 'R'; f = rec(temp) + 1; *fg = 'G'; } if (rr != NULL) { *rr = 'G'; r = rec(temp) + 1; } } int result = min(f, r); M[s] = result; return result; }
ForceValidationResult* ValidateOpenMMForces::compareForce(Context& context, std::vector<int>& compareForces, Platform& platform1, Platform& platform2 ) const { // --------------------------------------------------------------------------------------- //static const std::string methodName = "ValidateOpenMMForces::compareForce"; // --------------------------------------------------------------------------------------- // note if platforms are identical if( getLog() && platform1.getName().compare( platform2.getName() ) == 0 ){ (void) fprintf( getLog(), "Note: Platforms to compares %s are identical.\n", platform1.getName().c_str() ); (void) fflush( getLog() ); } const System& system = context.getSystem(); // collect systemForceNameMap[forceName] = index in system // systemForceNameIndex[index] = force name StringIntMap systemForceNameMap; StringVector systemForceNameIndex; systemForceNameIndex.resize( system.getNumForces() ); for( int ii = 0; ii < system.getNumForces(); ii++ ){ std::string forceName = getForceName( system.getForce( ii ) ); if( forceName.compare( "NA" ) == 0 ){ std::stringstream message; message << "Force at index=" << ii << " not found -- aborting!"; std::cerr << message.str() << std::endl; throw OpenMM::OpenMMException(message.str()); } systemForceNameMap[forceName] = ii; systemForceNameIndex[ii] = forceName; } // diagnostics if( 0 && getLog() ){ for( StringIntMapI ii = systemForceNameMap.begin(); ii != systemForceNameMap.end(); ii++ ){ int index = (*ii).second; (void) fprintf( getLog(), " System force map %s index=%d reverse map=%s\n", (*ii).first.c_str(), index, systemForceNameIndex[index].c_str() ); } for( unsigned int ii = 0; ii < compareForces.size(); ii++ ){ (void) fprintf( getLog(), " ValidateOpenMMForces %u %s\n", ii, systemForceNameIndex[compareForces[ii]].c_str() ); } (void) fflush( getLog() ); } // get system copy and add forces to system System* validationSystem = copySystemExcludingForces( system ); StringUIntMap forceNamesMap; for( unsigned int ii = 0; ii < compareForces.size(); ii++ ){ const Force& forceToCopy = system.getForce( compareForces[ii] ); Force* force = copyForce( forceToCopy ); validationSystem->addForce( force ); forceNamesMap[systemForceNameIndex[compareForces[ii]]] = ii; } // include any missing dependencies (e.g, OBC force requires NB force for Cuda platform) for( StringUIntMapI ii = forceNamesMap.begin(); ii != forceNamesMap.end(); ii++ ){ std::string forceName = (*ii).first; StringVector dependencyVector; getForceDependencies( forceName, dependencyVector ); for( unsigned int jj = 0; jj < dependencyVector.size(); jj++ ){ std::string dependentForceName = dependencyVector[jj]; StringUIntMapCI dependent = forceNamesMap.find( dependentForceName ); if( dependent == forceNamesMap.end() ){ forceNamesMap[dependentForceName] = 1; int forceIndex = systemForceNameMap[dependentForceName]; const Force& forceToCopy = system.getForce( forceIndex ); validationSystem->addForce( copyForce( forceToCopy ) ); } } } // create contexts VerletIntegrator verletIntegrator( 0.001 ); Context* validationContext1 = new Context( *validationSystem, verletIntegrator, platform1); Context* validationContext2 = new Context( *validationSystem, verletIntegrator, platform2); // set positions synchContexts( context, *validationContext1 ); synchContexts( context, *validationContext2 ); // diagnostics if( 0 && getLog() ){ std::stringstream forceNames; (void) fprintf( getLog(), " Validating system forces=%d\n", validationSystem->getNumForces() ); for( int ii = 0; ii < validationSystem->getNumForces(); ii++ ){ std::string forceName = getForceName( validationSystem->getForce( ii ) ); forceNames << forceName; if( ii < (validationSystem->getNumForces()-1) ){ forceNames << "_"; } else { forceNames << "Parameters.txt"; } (void) fprintf( getLog(), " force %d %s\n", ii, forceName.c_str() ); } writeParameterFile( *validationContext1, forceNames.str() ); (void) fflush( getLog() ); } // calculate forces & build return result ForceValidationResult* forceValidationResult = new ForceValidationResult( *validationContext1, *validationContext2, forceNamesMap ); delete validationContext1; delete validationContext2; delete validationSystem; return forceValidationResult; }
bool AnimationExport::exportController() { vector<Niflib::ControllerLink> blocks = seq->GetControlledBlocks(); int nbones = skeleton->m_bones.getSize(); if (AnimationExport::noRootSiblings) { // Remove bones not children of root. This is a bit of a kludge. // Basically search for the first node after the root which also has no parent // This is typically Camera3. We then truncate tracks to exclude nodes appearing after. for (int i=1; i<nbones; ++i) { if (skeleton->m_parentIndices[i] < 0) { nbones = i; break; } } } int numTracks = nbones; float duration = seq->GetStopTime() - seq->GetStartTime(); int nframes = (int)roundf(duration / FramesIncrement); int nCurrentFrame = 0; hkRefPtr<hkaInterleavedUncompressedAnimation> tempAnim = new hkaInterleavedUncompressedAnimation(); tempAnim->m_duration = duration; tempAnim->m_numberOfTransformTracks = numTracks; tempAnim->m_numberOfFloatTracks = 0;//anim->m_numberOfFloatTracks; tempAnim->m_transforms.setSize(numTracks*nframes, hkQsTransform::getIdentity()); tempAnim->m_floats.setSize(tempAnim->m_numberOfFloatTracks); tempAnim->m_annotationTracks.setSize(numTracks); hkArray<hkQsTransform>& transforms = tempAnim->m_transforms; typedef map<string, int, ltstr> StringIntMap; StringIntMap boneMap; for (int i=0; i<nbones; ++i) { string name = skeleton->m_bones[i].m_name; boneMap[name] = i; } for ( vector<Niflib::ControllerLink>::iterator bitr = blocks.begin(); bitr != blocks.end(); ++bitr) { StringIntMap::iterator boneitr = boneMap.find((*bitr).nodeName); if (boneitr == boneMap.end()) { Log::Warn("Unknown bone '%s' found in animation. Skipping.", (*bitr).nodeName.c_str()); continue; } int boneIdx = boneitr->second; hkQsTransform localTransform = skeleton->m_referencePose[boneIdx]; FillTransforms(transforms, boneIdx, nbones, localTransform); // prefill transforms with bindpose if ( NiTransformInterpolatorRef interpolator = DynamicCast<NiTransformInterpolator>((*bitr).interpolator) ) { if (NiTransformDataRef data = interpolator->GetData()) { if ( data->GetTranslateType() == Niflib::LINEAR_KEY ) { vector<Vector3Key> keys = data->GetTranslateKeys(); int n = keys.size(); if (n > 0) { int frame = 0; float currentTime = 0.0f; Vector3Key* itr = &keys[0], *last = &keys[n-1]; SetTransformPositionRange(transforms, nbones, boneIdx, currentTime, (*itr).time, frame, *itr, *itr); for (int i=1; i<n; ++i) { Vector3Key* next = &keys[i]; SetTransformPositionRange(transforms, nbones, boneIdx, currentTime, (*next).time, frame, *itr, *next); itr = next; } SetTransformPositionRange(transforms, nbones, boneIdx, currentTime, duration, frame, *last, *last); } } else { Log::Verbose("Missing transform data for %s", boneitr->first.c_str()); } if ( data->GetRotateType() == Niflib::QUADRATIC_KEY ) { vector<QuatKey> keys = data->GetQuatRotateKeys(); int n = keys.size(); if (n > 0) { int frame = 0; float currentTime = 0.0f; QuatKey* itr = &keys[0], *last = &keys[n-1]; SetTransformRotationRange(transforms, nbones, boneIdx, currentTime, itr->time, frame, *itr, *itr); for (int i=1; i<n; ++i) { QuatKey* next = &keys[i]; SetTransformRotationRange(transforms, nbones, boneIdx, currentTime, next->time, frame, *itr, *next); itr = next; } SetTransformRotationRange(transforms, nbones, boneIdx, currentTime, duration, frame, *last, *last); } } else { Log::Verbose("Missing rotation data for %s", boneitr->first.c_str()); } if ( data->GetScaleType() == Niflib::LINEAR_KEY ) { vector<FloatKey> keys = data->GetScaleKeys(); int n = keys.size(); if (n > 0) { int frame = 0; float currentTime = 0.0f; FloatKey* itr = &keys[0], *last = &keys[n-1]; SetTransformScaleRange(transforms, nbones, boneIdx, currentTime, itr->time, frame, *itr, *itr); for (int i=1; i<n; ++i) { FloatKey* next = &keys[i]; SetTransformScaleRange(transforms, nbones, boneIdx, currentTime, next->time, frame, *itr, *next); itr = next; } SetTransformScaleRange(transforms, nbones, boneIdx, currentTime, duration, frame, *last, *last); } } else { Log::Verbose("Missing scaling data for %s", boneitr->first.c_str()); } } else { } } else { } } hkaSkeletonUtils::normalizeRotations (transforms.begin(), transforms.getSize()); // create the animation with default settings { hkaSplineCompressedAnimation::TrackCompressionParams tparams; hkaSplineCompressedAnimation::AnimationCompressionParams aparams; tparams.m_rotationTolerance = 0.001f; tparams.m_rotationQuantizationType = hkaSplineCompressedAnimation::TrackCompressionParams::THREECOMP40; hkRefPtr<hkaSplineCompressedAnimation> outAnim = new hkaSplineCompressedAnimation( *tempAnim.val(), tparams, aparams ); binding->m_animation = outAnim; } return true; }