Beispiel #1
0
	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;
	}
Beispiel #2
0
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;
}