//----------------------------------------------------------------------------
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;
}
示例#2
0
void SkinController::OnFirstUpdate()
{
    // Get access to the vertex buffer positions to store the blended targets.
    Visual* visual = reinterpret_cast<Visual*>(mObject);
    VertexBuffer* vbuffer = visual->GetVertexBuffer().get();
    if (mNumVertices == static_cast<int>(vbuffer->GetNumElements()))
    {
        // Get the position data.
        VertexFormat vformat = vbuffer->GetFormat();
        int const numAttributes = vformat.GetNumAttributes();
        for (int i = 0; i < numAttributes; ++i)
        {
            VASemantic semantic;
            DFType type;
            unsigned int unit, offset;
            if (vformat.GetAttribute(i, semantic, type, unit, offset))
            {
                if (semantic == VA_POSITION && (type == DF_R32G32B32_FLOAT 
                    || type == DF_R32G32B32A32_FLOAT))
                {
                    mPosition = vbuffer->GetData() + offset;
                    mStride = vformat.GetVertexSize();
                    mCanUpdate = true;
                    break;
                }
            }
        }
    }

    mCanUpdate = (mPosition != nullptr);
}
示例#3
0
bool SkinController::Update(double applicationTime)
{
    if (!Controller::Update(applicationTime))
    {
        return false;
    }

    if (mFirstUpdate)
    {
        mFirstUpdate = false;
        OnFirstUpdate();
    }

    if (mCanUpdate)
    {
        // The skin vertices are calculated in the bone world coordinate system,
        // so the visual's world transform must be the identity.
        Visual* visual = reinterpret_cast<Visual*>(mObject);
        visual->worldTransform = Transform::IDENTITY;
        visual->worldTransformIsCurrent = true;

        // Compute the skin vertex locations.
        char* current = mPosition;
        for (int vertex = 0; vertex < mNumVertices; ++vertex)
        {
            Vector4<float> position{ 0.0f, 0.0f, 0.0f, 0.0f };
            for (int bone = 0; bone < mNumBones; ++bone)
            {
                float weight = mWeights[vertex][bone];
                if (weight != 0.0f)
                {
                    Vector4<float> offset = mOffsets[vertex][bone];
#if defined (GTE_USE_MAT_VEC)
                    Vector4<float> worldOffset =
                        mBones[bone]->worldTransform * offset;
#else
                    Vector4<float> worldOffset =
                        offset * mBones[bone]->worldTransform;
#endif
                    position += weight * worldOffset;
                }
            }

            Vector3<float>* target =
                reinterpret_cast<Vector3<float>*>(current);
            (*target)[0] = position[0];
            (*target)[1] = position[1];
            (*target)[2] = position[2];
            current += mStride;
        }

        visual->UpdateModelBound();
        visual->UpdateModelNormals();
        mPostUpdate(visual->GetVertexBuffer());
        return true;
    }

    return false;
}
示例#4
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;
}
示例#5
0
//----------------------------------------------------------------------------
void Delaunay3D::ChangeTetraStatus (int index, const Float4& color,
    bool enableWire)
{
    Visual* tetra = DynamicCast<Visual>(mScene->GetChild(1 + index));
    assertion(tetra != 0, "Expecting a Visual object.\n");
    VertexBufferAccessor vba(tetra);
    for (int i = 0; i < 4; ++i)
    {
        vba.Color<Float4>(0, i) = color;
    }
    mRenderer->Update(tetra->GetVertexBuffer());

    VisualEffectInstance* instance = tetra->GetEffectInstance();
    instance->GetEffect()->GetWireState(0, 0)->Enabled = enableWire;
}