//----------------------------------------------------------------------------
bool MorphController::Update (double applicationTime)
{
    // The key interpolation uses linear interpolation.  To get higher-order
    // interpolation, you need to provide a more sophisticated key (Bezier
    // cubic or TCB spline, for example).

    if (!Controller::Update(applicationTime))
    {
        return false;
    }

    // Get access to the vertex buffer to store the blended targets.
    Visual* visual = StaticCast<Visual>(mObject);
    assertion(visual->GetVertexBuffer()->GetNumElements() == mNumVertices,
        "Mismatch in number of vertices.\n");

    VertexBufferAccessor vba(visual);

    // Set vertices to target[0].
    APoint* baseTarget = mVertices[0];
    int i;
    for (i = 0; i < mNumVertices; ++i)
    {
        vba.Position<Float3>(i) = baseTarget[i];
    }

    // Look up the bounding keys.
    float ctrlTime = (float)GetControlTime(applicationTime);
    float normTime;
    int i0, i1;
    GetKeyInfo(ctrlTime, normTime, i0, i1);

    // Add the remaining components in the convex composition.
    float* weights0 = mWeights[i0];
    float* weights1 = mWeights[i1];
    for (i = 1; i < mNumTargets; ++i)
    {
        // Add in the delta-vertices of target[i].
        float coeff = (1.0f-normTime)*weights0[i-1] + normTime*weights1[i-1];
        AVector* target = (AVector*)mVertices[i];
        for (int j = 0; j < mNumVertices; ++j)
        {
            APoint position = vba.Position<Float3>(j);
            position += coeff*target[j];
            vba.Position<Float3>(j) = position;
        }
    }

    visual->UpdateModelSpace(Visual::GU_NORMALS);
    Renderer::UpdateAll(visual->GetVertexBuffer());
    return true;
}
Esempio n. 2
0
//----------------------------------------------------------------------------
bool SkinController::Update (double applicationTime)
{
    if (!Controller::Update(applicationTime))
    {
        return false;
    }

    // Get access to the vertex buffer to store the blended targets.
    Visual* visual = StaticCast<Visual>(mObject);
    assertion(mNumVertices == visual->GetVertexBuffer()->GetNumElements(),
        "Controller must have the same number of vertices as the buffer\n");
    VertexBufferAccessor vba(visual);

    // The skin vertices are calculated in the bone world coordinate system,
    // so the visual's world transform must be the identity.
    visual->WorldTransform = Transform::IDENTITY;
    visual->WorldTransformIsCurrent = true;

    // Compute the skin vertex locations.
    for (int vertex = 0; vertex < mNumVertices; ++vertex)
    {
        APoint position = APoint::ORIGIN;
        for (int bone = 0; bone < mNumBones; ++bone)
        {
            float weight = mWeights[vertex][bone];
            if (weight != 0.0f)
            {
                APoint offset = mOffsets[vertex][bone];
                APoint worldOffset = mBones[bone]->WorldTransform*offset;
                position += weight*worldOffset;
            }
        }
        vba.Position<Float3>(vertex) = position;
    }

    visual->UpdateModelSpace(Visual::GU_NORMALS);
    Renderer::UpdateAll(visual->GetVertexBuffer());
    return true;
}