//---------------------------------------------------------------------------- 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; }
//---------------------------------------------------------------------------- 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; }