/////////////////////////////////////////////////////////////////////////////////////////////////// // Calculate the tangent basis for a triangle on the surface of a model // This vector is needed for most normal mapping shaders void m3dCalculateTangentBasis(M3DVector3f vTangent, const M3DVector3f vTriangle[3], const M3DVector2f vTexCoords[3], const M3DVector3f N) { M3DVector3f dv2v1, dv3v1; float dc2c1t, dc2c1b, dc3c1t, dc3c1b; float M; m3dSubtractVectors3(dv2v1, vTriangle[1], vTriangle[0]); m3dSubtractVectors3(dv3v1, vTriangle[2], vTriangle[0]); dc2c1t = vTexCoords[1][0] - vTexCoords[0][0]; dc2c1b = vTexCoords[1][1] - vTexCoords[0][1]; dc3c1t = vTexCoords[2][0] - vTexCoords[0][0]; dc3c1b = vTexCoords[2][1] - vTexCoords[0][1]; M = (dc2c1t * dc3c1b) - (dc3c1t * dc2c1b); M = 1.0f / M; m3dScaleVector3(dv2v1, dc3c1b); m3dScaleVector3(dv3v1, dc2c1b); m3dSubtractVectors3(vTangent, dv2v1, dv3v1); m3dScaleVector3(vTangent, M); // This potentially changes the direction of the vector m3dNormalizeVector3(vTangent); M3DVector3f B; m3dCrossProduct3(B, N, vTangent); m3dCrossProduct3(vTangent, B, N); m3dNormalizeVector3(vTangent); }
//verlet x = vt + 1/2*at^2 void nextPosition(int currentPtc) { M3DVector3f temp; //get last shift: + vt m3dSubtractVectors3(temp, ClothLnk[currentPtc].position, ClothLnk[currentPtc].pre_position); m3dAddVectors3(ClothLnk[currentPtc].next_position, ClothLnk[currentPtc].position, temp); //if (currentPtc==55) // printf(" [%d].shift {%.1f, %.1f, %.1f} \n", currentPtc, shift[0], shift[1], shift[2]); //get accumulation: + 1/2*at^2 m3dCopyVector3(temp, ClothLnk[currentPtc].force); m3dScaleVector3(temp, (GLfloat)TimeStep*TimeStep*AccumulateStiff/ClothLnk[currentPtc].Mass/2); m3dAddVectors3(ClothLnk[currentPtc].next_position, ClothLnk[currentPtc].next_position, temp); //collide //if (adjustPositionByCollision(ClothLnk[currentPtc].next_position) ) { // m3dCopyVector3(ClothLnk[currentPtc].next_position, ClothLnk[currentPtc].position); //} adjustPositionByCollision(ClothLnk[currentPtc].position, ClothLnk[currentPtc].next_position); M3DVector3f shift; m3dSubtractVectors3(shift, ClothLnk[currentPtc].next_position, ClothLnk[currentPtc].position); GLfloat length = (GLfloat)m3dGetVectorLength(shift); if (length >= shiftRange ) { m3dScaleVector3(shift, 1.0f/length); m3dAddVectors3(ClothLnk[currentPtc].next_position, ClothLnk[currentPtc].position, shift); } }
void getForce(int currentPtc) { getInternalForce(currentPtc); //getCollisionForce(currentPtc); M3DVector3f gravity = {0.0f, -ClothLnk[currentPtc].Mass, 0.0f}; m3dScaleVector3(gravity, 0.2f); addForce(currentPtc, gravity); m3dScaleVector3(ClothLnk[currentPtc].force, DampCoefficient); //if (currentPtc==55) // printf("[%d].force {%.1f, %.1f, %.1f} \n", currentPtc, ClothLnk[currentPtc].force[0], ClothLnk[currentPtc].force[1], ClothLnk[currentPtc].force[2]); }
void sewClothModel() { M3DVector3f temp, displacement; for (int i = 0; i < PTCAMT; i ++) { m3dLoadVector3(displacement, 0.0f, 0.0f, 0.0f); clearForce(i); getInternalForce(i); //sew together getTensionForce(i, ClothCenter, 0.01f); m3dScaleVector3(ClothLnk[i].force, TensionCoefficient); nextPosition(i); m3dSubtractVectors3(temp, ClothLnk[i].next_position, ClothLnk[i].position); m3dAddVectors3(displacement, displacement, temp); } m3dScaleVector3(displacement, (GLfloat)800000/PTCAMT); //printf(" total displace: %.1f %.1f %.1f\n", displacement[0], displacement[1], displacement[2]); m3dAddVectors3(ClothCenter, ClothCenter, displacement); //m3dLoadVector3(TotalDisplacement, 0.0f, 0.0f, 0.0f); refreshPosition(); }
/////////////////////////////////////////////////////////////////////////// // Scale of the vertices. The only way to do this is to map the VBO back // into client memory, then back again void CVBOMesh::Scale(GLfloat fScaleValue) { glBindBuffer(GL_ARRAY_BUFFER, bufferObjects[VERTEX_DATA]); M3DVector3f *pVertexData = (M3DVector3f *)glMapBuffer(GL_ARRAY_BUFFER, GL_READ_WRITE); if(pVertexData != NULL) { for(int i = 0; i < nNumVerts; i++) m3dScaleVector3(pVertexData[i], fScaleValue); glUnmapBuffer(GL_ARRAY_BUFFER); } }