Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //the glut "render" function
- void render()
- {
- sceneManager.renderFrame(myCamera);
- }
- void SceneManager::renderFrame(Camera *camera)
- {
- //clear screen
- _renderer.clearScreen();
- //static meshes. Ignore this because it isn't in use when I benchmark my app with skeletal animation
- if(_meshProgram && !_staticMeshes.empty()) {
- _renderer.beginRendering(camera, _meshProgram);
- for(unsigned int i = 0; i < _staticMeshes.size(); i++)
- {
- std::vector<SceneNode*> &meshList = _staticMeshes[i]->list;
- for(unsigned int j = 0; j < meshList.size(); j++)
- _renderer.renderSceneNode(meshList[j], _meshProgram);
- }
- _renderer.endRendering(_meshProgram);
- }
- //animated meshes:
- //go through the list of
- if(_skeletalAnimationProgram && !_animatedMeshes.empty()) {
- _animationController.updateAnimations();
- _renderer.beginRendering(camera, _skeletalAnimationProgram);
- for(unsigned int i = 0; i < _animatedMeshes.size(); i++)
- {
- std::vector<SceneNode*> &meshList = _animatedMeshes[i]->list;
- BoneList *boneList = _animatedMeshes[i]->boneList;
- boneList->clearBoneMatrices();
- boneList->fillBoneMatrices();
- _skeletalAnimationProgram->setUniform((GLint)bones_location, boneList->boneMatrices, MAX_BONES_IN_SHADER);
- //render the scene nodes with attached MeshDatas
- for(unsigned int j = 0; j < meshList.size(); j++)
- _renderer.renderSceneNode(meshList[j], _skeletalAnimationProgram);
- }
- _renderer.endRendering(_skeletalAnimationProgram);
- }
- //swap buffers
- _renderer.swapBuffers();
- }
- //this function consumes most of the time. Though I can't think of anything that could speed this more
- void AnimationController::updateAnimations()
- {
- //iterate through active animations
- for(unsigned int i = 0; i < _animations.size(); i++)
- {
- Animation *animation = _animations[i];
- //only process if the animation is running
- if(animation->animationState != ANIMATION_STATE_RUNNING)
- continue;
- //calculate delta time
- double time = ((double)animation->timer.elapsed() / 1000.0) * (animation->animationSet->ticksPerSecond());
- while(time > animation->animationSet->duration()) time -= animation->animationSet->duration();
- //update animation matrices (bone->nodeMatrix)
- std::vector<Bone*> &bones= animation->boneList->bones;
- for(unsigned int j = 0; j < bones.size(); j++)
- {
- Bone *bone = bones[j];
- _calculateNodeMatrix(bones[j], bone->nodeAnimationData(), time, &animation->lastKeyframeIndex);
- }
- }
- //set finalMatrix for each bone (using a recursive method)
- for(unsigned int i = 0; i < _animatedMeshes->size(); i++) {
- SceneNodeList *list = (*_animatedMeshes)[i];
- _updateFinalMatrices(list->sceneNode);
- }
- }
- void AnimationController::_calculateNodeMatrix(Bone *bone, const NodeAnimationData *animData, double time, unsigned int *lastIndex)
- {
- unsigned int currIndex = _getAnimationKeyIndex(&animData->positionKeys, time, *lastIndex);
- unsigned int nextIndex = currIndex + 1;
- *lastIndex = currIndex;
- double factor;
- //rotation
- const QuatKey &currQuatKey = animData->quatKeys[currIndex];
- const QuatKey &nextQuatKey = animData->quatKeys[nextIndex];
- factor = (time - currQuatKey.time) / (nextQuatKey.time - currQuatKey.time);
- factor = glm::clamp(factor, 0.0, 1.0);
- glm::quat rotation_quat = glm::slerp(currQuatKey.quat, nextQuatKey.quat, (float)factor);
- glm::mat4 rotation_mat = glm::mat4_cast(rotation_quat);
- //position
- const VectorKey &currPosKey = animData->positionKeys[currIndex];
- const VectorKey &nextPosKey = animData->positionKeys[nextIndex];
- factor = (time - currPosKey.time) / (nextPosKey.time - currPosKey.time);
- factor = glm::clamp(factor, 0.0, 1.0);
- glm::vec3 position_vec = currPosKey.vec*(1.0f - (float)factor) + nextPosKey.vec * (float)factor;
- glm::mat4 position_mat = glm::translate(position_vec);
- bone->setNodeMatrix(position_mat * rotation_mat);
- }
- void AnimationController::_updateFinalMatrices(SceneNode *sceneNode)
- {
- Bone *bone = sceneNode->bone();
- Bone *parentBone = sceneNode->parent()->bone(); //note there is no check for sceneNode->parent() because the root node isn't supposed to hold a Mesh. add an error check for this later
- if(bone) {
- bone->setNodeMatrix( (parentBone ? parentBone->nodeMatrix() : glm::mat4(1))
- * bone->nodeMatrix() );
- bone->calculateFinalMatrix();
- }
- for(unsigned int i = 0; i < sceneNode->getNumChildren(); i++)
- _updateFinalMatrices(sceneNode->getChildNode(i));
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement