📄 physique.cpp
字号:
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; } // re-normalize normal if necessary if (m_Normalize) { nx/= m_axisFactorX; ny/= m_axisFactorY; nz/= m_axisFactorZ; float scale; scale = (float)( 1.0f / sqrt(nx * nx + ny * ny + nz * nz)); pVertexBuffer[3] = nx * scale; pVertexBuffer[4] = ny * scale; pVertexBuffer[5] = nz * scale; } else { pVertexBuffer[3] = nx; pVertexBuffer[4] = ny; pVertexBuffer[5] = nz; } // next vertex position in buffer pVertexBuffer = (float *)(((char *)pVertexBuffer) + stride) ; } return vertexCount;} /*****************************************************************************//** Calculates the transformed vertex data. * * This function calculates and returns the transformed vertex, the transformed * normal datadata and the texture coords 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. * * @param NumTexCoords A integer with the number of texture coords * * @return The number of vertices written to the buffer. *****************************************************************************/int CalPhysique::calculateVerticesNormalsAndTexCoords(CalSubmesh *pSubmesh, float *pVertexBuffer,int NumTexCoords){ // 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 the texture coordinate vector vector std::vector<std::vector<CalCoreSubmesh::TextureCoordinate> >& vectorvectorTextureCoordinate = pSubmesh->getCoreSubmesh()->getVectorVectorTextureCoordinate(); int TextureCoordinateCount=(int)vectorvectorTextureCoordinate.size(); // check if the map id is valid if(((NumTexCoords < 0) || (NumTexCoords > TextureCoordinateCount))) { if(TextureCoordinateCount!=0) { CalError::setLastError(CalError::INVALID_HANDLE, __FILE__, __LINE__); return -1; } } // 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); CalVector normal(0,0,0); if(baseWeight == 1.0f) { position.x = vertex.position.x; position.y = vertex.position.y; position.z = vertex.position.z; normal.x = vertex.normal.x; normal.y = vertex.normal.y; normal.z = vertex.normal.z; } else { position.x = baseWeight*vertex.position.x; position.y = baseWeight*vertex.position.y; position.z = baseWeight*vertex.position.z; normal.x = baseWeight*vertex.normal.x; normal.y = baseWeight*vertex.normal.y; normal.z = baseWeight*vertex.normal.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; normal.x += currentWeight*blendVertex.normal.x; normal.y += currentWeight*blendVertex.normal.y; normal.z += currentWeight*blendVertex.normal.z; } } // initialize vertex float x, y, z; x = 0.0f; y = 0.0f; z = 0.0f; // initialize normal float nx, ny, nz; nx = 0.0f; ny = 0.0f; nz = 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; nx = normal.x; ny = normal.y; nz = normal.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; // transform normal with current state of the bone CalVector n(normal); n *= pBone->getTransformMatrix(); nx += influence.weight * n.x; ny += influence.weight * n.y; nz += influence.weight * n.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; } // re-normalize normal if necessary if (m_Normalize) { nx/= m_axisFactorX; ny/= m_axisFactorY; nz/= m_axisFactorZ; float scale; scale = (float) (1.0f / sqrt(nx * nx + ny * ny + nz * nz)); pVertexBuffer[3] = nx * scale; pVertexBuffer[4] = ny * scale; pVertexBuffer[5] = nz * scale; } else { pVertexBuffer[3] = nx; pVertexBuffer[4] = ny; pVertexBuffer[5] = nz; } pVertexBuffer += 6; if(TextureCoordinateCount==0) { pVertexBuffer+=NumTexCoords*2; } else { for(int mapId=0; mapId < NumTexCoords; ++mapId) { pVertexBuffer[0] = vectorvectorTextureCoordinate[mapId][vertexId].u; pVertexBuffer[1] = vectorvectorTextureCoordinate[mapId][vertexId].v; pVertexBuffer += 2; } } } return vertexCount;} /*****************************************************************************//** Updates all the internally handled attached meshes. * * This function updates all the attached meshes of the model that are handled * internally. *****************************************************************************/void CalPhysique::update(){ // get the attached meshes vector std::vector<CalMesh *>& vectorMesh = m_pModel->getVectorMesh(); // loop through all the attached meshes std::vector<CalMesh *>::iterator iteratorMesh; for(iteratorMesh = vectorMesh.begin(); iteratorMesh != vectorMesh.end(); ++iteratorMesh) { // get the submesh vector of the mesh std::vector<CalSubmesh *>& vectorSubmesh = (*iteratorMesh)->getVectorSubmesh(); // loop through all the submeshes of the mesh std::vector<CalSubmesh *>::iterator iteratorSubmesh; for(iteratorSubmesh = vectorSubmesh.begin(); iteratorSubmesh != vectorSubmesh.end(); ++iteratorSubmesh) { // check if the submesh handles vertex data internally if((*iteratorSubmesh)->hasInternalData()) { // calculate the transformed vertices and store them in the submesh std::vector<CalVector>& vectorVertex = (*iteratorSubmesh)->getVectorVertex(); calculateVertices(*iteratorSubmesh, (float *)&vectorVertex[0]); // calculate the transformed normals and store them in the submesh std::vector<CalVector>& vectorNormal = (*iteratorSubmesh)->getVectorNormal(); calculateNormals(*iteratorSubmesh, (float *)&vectorNormal[0]); unsigned mapId; for(mapId=0;mapId< (*iteratorSubmesh)->getVectorVectorTangentSpace().size();mapId++) { if((*iteratorSubmesh)->isTangentsEnabled(mapId)) { std::vector<CalSubmesh::TangentSpace>& vectorTangentSpace = (*iteratorSubmesh)->getVectorVectorTangentSpace()[mapId]; calculateTangentSpaces(*iteratorSubmesh, mapId,(float *)&vectorTangentSpace[0]); } } } } }} /*****************************************************************************//** Sets the normalization flag to true or false. * * This function sets the normalization flag on or off. If off, the normals * calculated by Cal3D will not be normalized. Instead, this transform is left * up to the user. *****************************************************************************/void CalPhysique::setNormalization(bool normalize){ m_Normalize = normalize;}void CalPhysique::setAxisFactorX(float factor){ m_axisFactorX = factor; m_Normalize = true; }void CalPhysique::setAxisFactorY(float factor){ m_axisFactorY = factor; m_Normalize = true; }void CalPhysique::setAxisFactorZ(float factor){ m_axisFactorZ = factor; m_Normalize = true; }//****************************************************************************//
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -