Spline::InterpolatedPT LoopingCubicHermiteSpline::getTangent(double x) const { //use modular arithmetic to bring x into an acceptable range x = fmod(x, numSegments); if(x < 0) x += numSegments; //find the interpolation data for this t value InterpolationData segment = segmentData.at(getSegmentIndex(x)); double t = (x - segment.t0) * segment.tDistanceInverse; return InterpolatedPT( computePosition(t, segment), computeTangent(t, segment) ); }
Spline::InterpolatedPTCW LoopingCubicHermiteSpline::getWiggle(double x) const { //use modular arithmetic to bring x into an acceptable range x = fmod(x, numSegments); if(x < 0) x += numSegments; InterpolationData segment = segmentData.at(getSegmentIndex(x)); double t = (x - segment.t0) * segment.tDistanceInverse; return InterpolatedPTCW( computePosition(t, segment), computeTangent(t, segment), computeCurvature(t, segment), computeWiggle(segment) ); }
void generateTangents(MSubMesh * subMesh) { MVector3 * vertices = subMesh->getVertices(); MVector3 * normals = subMesh->getNormals(); MVector2 * texCoords = subMesh->getTexCoords(); if(! (vertices && normals && texCoords)) return; bool generate = false; unsigned int mapChannel; // find normal mapChannel unsigned int d; unsigned int dSize = subMesh->getDisplaysNumber(); for(d=0; d<dSize; d++) { MDisplay * display = subMesh->getDisplay(d); MMaterial * material = display->getMaterial(); if(material) { if(material->getType() == 1) // standard { if(material->getTexturesPassNumber() > 2) { MTexturePass * texturePass = material->getTexturePass(2); // Normal map pass if(texturePass) { mapChannel = texturePass->getMapChannel(); generate = true; } } } else { unsigned tSize = material->getTexturesPassNumber(); unsigned int t; for(t=0; t<tSize; t++) { MTexturePass * texturePass = material->getTexturePass(t); if(texturePass) { if(texturePass->getCombineMode() == M_TEX_COMBINE_DOT) { mapChannel = texturePass->getMapChannel(); generate = true; } } } } } } // generate if(generate) { M_TYPES indicesType = subMesh->getIndicesType(); void * indices = subMesh->getIndices(); MVector3 * tangents = subMesh->allocTangents(subMesh->getNormalsSize()); // texCoord offset unsigned int offset = 0; if(subMesh->isMapChannelExist(mapChannel)) offset = subMesh->getMapChannelOffset(mapChannel); texCoords = texCoords + offset; // scan triangles to generate tangents from vertices and texCoords for(d=0; d<dSize; d++) { MDisplay * display = subMesh->getDisplay(d); if(display->getPrimitiveType() == M_PRIMITIVE_TRIANGLES) { unsigned int begin = display->getBegin(); unsigned int size = display->getSize(); if(! indices) { for(unsigned int i=begin; i<(begin+size); i+=3) { MVector3 * P1 = &vertices[i]; MVector3 * P2 = &vertices[i+1]; MVector3 * P3 = &vertices[i+2]; MVector3 * N1 = &normals[i]; MVector3 * N2 = &normals[i+1]; MVector3 * N3 = &normals[i+2]; MVector2 * UV1 = &texCoords[i]; MVector2 * UV2 = &texCoords[i+1]; MVector2 * UV3 = &texCoords[i+2]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[i] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[i+1] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[i+2] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } else if(indicesType == M_USHORT) { unsigned short * _indices = (unsigned short *)indices; for(unsigned int i=begin; i<(begin+size); i+=3) { unsigned short A = _indices[i]; unsigned short B = _indices[i+1]; unsigned short C = _indices[i+2]; MVector3 * P1 = &vertices[A]; MVector3 * P2 = &vertices[B]; MVector3 * P3 = &vertices[C]; MVector3 * N1 = &normals[A]; MVector3 * N2 = &normals[B]; MVector3 * N3 = &normals[C]; MVector2 * UV1 = &texCoords[A]; MVector2 * UV2 = &texCoords[B]; MVector2 * UV3 = &texCoords[C]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } else if(indicesType == M_UINT) { unsigned int * _indices = (unsigned int *)indices; for(unsigned int i=begin; i<(begin+size); i+=3) { unsigned int A = _indices[i]; unsigned int B = _indices[i+1]; unsigned int C = _indices[i+2]; MVector3 * P1 = &vertices[A]; MVector3 * P2 = &vertices[B]; MVector3 * P3 = &vertices[C]; MVector3 * N1 = &normals[A]; MVector3 * N2 = &normals[B]; MVector3 * N3 = &normals[C]; MVector2 * UV1 = &texCoords[A]; MVector2 * UV2 = &texCoords[B]; MVector2 * UV3 = &texCoords[C]; MVector3 tangent = computeTangent(*P1, *P2, *P3, *UV1, *UV2, *UV3); tangents[A] = (tangent - ((*N1) * tangent.dotProduct(*N1))).getNormalized(); tangents[B] = (tangent - ((*N2) * tangent.dotProduct(*N2))).getNormalized(); tangents[C] = (tangent - ((*N3) * tangent.dotProduct(*N3))).getNormalized(); } } } } } }