📄 physique.cpp
字号:
//****************************************************************************//// physique.cpp //// Copyright (C) 2001, 2002 Bruno 'Beosil' Heidelberger ////****************************************************************************//// This library is free software; you can redistribute it and/or modify it //// under the terms of the GNU Lesser General Public License as published by //// the Free Software Foundation; either version 2.1 of the License, or (at //// your option) any later version. ////****************************************************************************//#ifdef HAVE_CONFIG_H#include "config.h"#endif//****************************************************************************//// Includes ////****************************************************************************//#include "cal3d/error.h"#include "cal3d/physique.h"#include "cal3d/coremodel.h"#include "cal3d/model.h"#include "cal3d/mesh.h"#include "cal3d/submesh.h"#include "cal3d/skeleton.h"#include "cal3d/bone.h"#include "cal3d/coresubmesh.h"#include "cal3d/coresubmorphtarget.h" /*****************************************************************************//** Constructs the physique instance. * * This function is the default constructor of the physique instance. *****************************************************************************/CalPhysique::CalPhysique(CalModel* pModel) : m_pModel(0) , m_Normalize(true){ assert(pModel); m_pModel = pModel; m_axisFactorX = 1.0f; m_axisFactorY = 1.0f; m_axisFactorZ = 1.0f;} /*****************************************************************************//** Calculates the transformed vertex data. * * This function calculates and returns the transformed vertex data of a * specific submesh. * * @param pSubmesh A pointer to the submesh from which the vertex data should * be calculated and returned. * @param pVertexBuffer A pointer to the user-provided buffer where the vertex * data is written to. * * @return The number of vertices written to the buffer. *****************************************************************************/int CalPhysique::calculateVertices(CalSubmesh *pSubmesh, float *pVertexBuffer, int stride){ if(stride <= 0) { stride = 3*sizeof(float); } // get bone vector of the skeleton std::vector<CalBone *>& vectorBone = m_pModel->getSkeleton()->getVectorBone(); // get vertex vector of the core submesh std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pSubmesh->getCoreSubmesh()->getVectorVertex(); // get physical property vector of the core submesh std::vector<CalCoreSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty(); // get the number of vertices int vertexCount; vertexCount = pSubmesh->getVertexCount(); // get the sub morph target vector from the core sub mesh std::vector<CalCoreSubMorphTarget*>& vectorSubMorphTarget = pSubmesh->getCoreSubmesh()->getVectorCoreSubMorphTarget(); // calculate the base weight float baseWeight = pSubmesh->getBaseWeight(); // get the number of morph targets int morphTargetCount = pSubmesh->getMorphTargetWeightCount(); // calculate all submesh vertices int vertexId; for(vertexId = 0; vertexId < vertexCount; ++vertexId) { // get the vertex CalCoreSubmesh::Vertex& vertex = vectorVertex[vertexId]; // blend the morph targets CalVector position(0,0,0); if(baseWeight == 1.0f) { position.x = vertex.position.x; position.y = vertex.position.y; position.z = vertex.position.z; } else { position.x = baseWeight*vertex.position.x; position.y = baseWeight*vertex.position.y; position.z = baseWeight*vertex.position.z; int morphTargetId; for(morphTargetId=0; morphTargetId < morphTargetCount;++morphTargetId) { CalCoreSubMorphTarget::BlendVertex& blendVertex = vectorSubMorphTarget[morphTargetId]->getVectorBlendVertex()[vertexId]; float currentWeight = pSubmesh->getMorphTargetWeight(morphTargetId); position.x += currentWeight*blendVertex.position.x; position.y += currentWeight*blendVertex.position.y; position.z += currentWeight*blendVertex.position.z; } } // initialize vertex float x, y, z; x = 0.0f; y = 0.0f; z = 0.0f; // blend together all vertex influences size_t influenceCount=vertex.vectorInfluence.size(); if(influenceCount == 0) { x = position.x; y = position.y; z = position.z; } else { for(size_t influenceId = 0; influenceId < influenceCount; ++influenceId) { // get the influence CalCoreSubmesh::Influence& influence = vertex.vectorInfluence[influenceId]; // get the bone of the influence vertex CalBone *pBone; pBone = vectorBone[influence.boneId]; // transform vertex with current state of the bone CalVector v(position); v *= pBone->getTransformMatrix(); v += pBone->getTranslationBoneSpace(); x += influence.weight * v.x; y += influence.weight * v.y; z += influence.weight * v.z; } } // save vertex position if(pSubmesh->getCoreSubmesh()->getSpringCount() > 0 && pSubmesh->hasInternalData()) { // get the pgysical property of the vertex CalCoreSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // assign new vertex position if there is no vertex weight if(physicalProperty.weight == 0.0f) { pVertexBuffer[0] = x * m_axisFactorX; pVertexBuffer[1] = y * m_axisFactorY; pVertexBuffer[2] = z * m_axisFactorZ; } } else { pVertexBuffer[0] = x * m_axisFactorX; pVertexBuffer[1] = y * m_axisFactorY; pVertexBuffer[2] = z * m_axisFactorZ; } // next vertex position in buffer pVertexBuffer = (float *)(((char *)pVertexBuffer) + stride) ; } return vertexCount;} /*****************************************************************************//** Calculates one transformed vertex. * * This function calculates and returns a transformed vertex of a * specific submesh. * * @param pSubmesh A pointer to the submesh from which the vertex should * be calculated and returned. * @param vertexId The id of the vertex that should be transformed. * * @return The number of vertices written to the buffer. *****************************************************************************/CalVector CalPhysique::calculateVertex(CalSubmesh *pSubmesh, int vertexId){ // get bone vector of the skeleton std::vector<CalBone *>& vectorBone = m_pModel->getSkeleton()->getVectorBone(); // get vertex of the core submesh std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pSubmesh->getCoreSubmesh()->getVectorVertex(); // get physical property vector of the core submesh //std::vector<CalCoreSubmesh::PhysicalProperty>& vectorPhysicalProperty = pSubmesh->getCoreSubmesh()->getVectorPhysicalProperty(); // get the sub morph target vector from the core sub mesh std::vector<CalCoreSubMorphTarget*>& vectorSubMorphTarget = pSubmesh->getCoreSubmesh()->getVectorCoreSubMorphTarget(); // calculate the base weight float baseWeight = pSubmesh->getBaseWeight(); // get the number of morph targets int morphTargetCount = pSubmesh->getMorphTargetWeightCount(); // get the vertex CalCoreSubmesh::Vertex& vertex = vectorVertex[vertexId]; // blend the morph targets CalVector position(0,0,0); if(baseWeight == 1.0f) { position.x = vertex.position.x; position.y = vertex.position.y; position.z = vertex.position.z; } else { position.x = baseWeight*vertex.position.x; position.y = baseWeight*vertex.position.y; position.z = baseWeight*vertex.position.z; int morphTargetId; for(morphTargetId=0; morphTargetId < morphTargetCount;++morphTargetId) { CalCoreSubMorphTarget::BlendVertex& blendVertex = vectorSubMorphTarget[morphTargetId]->getVectorBlendVertex()[vertexId]; float currentWeight = pSubmesh->getMorphTargetWeight(morphTargetId); position.x += currentWeight*blendVertex.position.x; position.y += currentWeight*blendVertex.position.y; position.z += currentWeight*blendVertex.position.z; } } // initialize vertex float x, y, z; x = 0.0f; y = 0.0f; z = 0.0f; // blend together all vertex influences int influenceId; int influenceCount=(int)vertex.vectorInfluence.size(); if(influenceCount == 0) { x = position.x; y = position.y; z = position.z; } else { for(influenceId = 0; influenceId < influenceCount; ++influenceId) { // get the influence CalCoreSubmesh::Influence& influence = vertex.vectorInfluence[influenceId]; // get the bone of the influence vertex CalBone *pBone; pBone = vectorBone[influence.boneId]; // transform vertex with current state of the bone CalVector v(position); v *= pBone->getTransformMatrix(); v += pBone->getTranslationBoneSpace(); x += influence.weight * v.x; y += influence.weight * v.y; z += influence.weight * v.z; } } /* // save vertex position if(pSubmesh->getCoreSubmesh()->getSpringCount() > 0 && pSubmesh->hasInternalData()) { // get the pgysical property of the vertex CalCoreSubmesh::PhysicalProperty& physicalProperty = vectorPhysicalProperty[vertexId]; // assign new vertex position if there is no vertex weight if(physicalProperty.weight == 0.0f) { pVertexBuffer[0] = x; pVertexBuffer[1] = y; pVertexBuffer[2] = z; } } else { pVertexBuffer[0] = x; pVertexBuffer[1] = y; pVertexBuffer[2] = z; } */ // return the vertex //return CalVector(x, y, z); return CalVector(x*m_axisFactorX,y*m_axisFactorY,z*m_axisFactorZ);} /*****************************************************************************//** Calculates the transformed tangent space data. * * This function calculates and returns the transformed tangent space data of a * specific submesh. * * @param pSubmesh A pointer to the submesh from which the tangent space data * should be calculated and returned. * @param mapId * @param pTangentSpaceBuffer A pointer to the user-provided buffer where the tangent * space data is written to. * * @return The number of tangent spaces written to the buffer. *****************************************************************************/int CalPhysique::calculateTangentSpaces(CalSubmesh *pSubmesh, int mapId, float *pTangentSpaceBuffer, int stride){ if((mapId < 0) || (mapId >= (int)pSubmesh->getCoreSubmesh()->getVectorVectorTangentSpace().size())) return false; if(stride <= 0) { stride = 4*sizeof(float); } // get bone vector of the skeleton std::vector<CalBone *>& vectorBone = m_pModel->getSkeleton()->getVectorBone(); // get vertex vector of the submesh std::vector<CalCoreSubmesh::Vertex>& vectorVertex = pSubmesh->getCoreSubmesh()->getVectorVertex(); // get tangent space vector of the submesh std::vector<CalCoreSubmesh::TangentSpace>& vectorTangentSpace = pSubmesh->getCoreSubmesh()->getVectorVectorTangentSpace()[mapId]; // get the number of vertices int vertexCount; vertexCount = pSubmesh->getVertexCount(); // calculate normal for all submesh vertices
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -