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