float4x4 Curve::GetAngle(float t) { // Get direction at point t float3 x = GetTangent(t); float3 y = Utils::GramSchmidt2(x,float3(0,1,0)); y.Normalize(); float3 z = Utils::GramSchmidt3(x,y,float3(0,0,1)); z.Normalize(); // Create I matrix float4x4 result; result.Identity(); // Compute rotation matrix for Y = A(result) result._11 = x.x; result._12 = x.y; result._13 = x.z; result._21 = y.x; result._22 = y.y; result._23 = y.z; result._31 = z.x; result._32 = z.y; result._33 = z.z; // Flip or swap one if determinant = -1... if(Utils::fequals(result.Determinant(),-1)) { // lame epsilon trick result._31 = -z.x; result._32 = -z.y; result._33 = -z.z; } return result; }
void csTerrainCell::RecalculateTangentData () { if (!needTangentsUpdate) return; needTangentsUpdate = false; tangentmap.SetSize (gridWidth * gridHeight); bitangentmap.SetSize (gridWidth * gridHeight); csVector3* tData = tangentmap.GetArray (); csVector3* bData = bitangentmap.GetArray (); for (int y = 0; y < gridWidth; ++y) { csVector3* tRow = tData + y * gridHeight; csVector3* bRow = bData + y * gridHeight; for (int x = 0; x < gridHeight; ++x) { *tRow++ = GetTangent (x, y); *bRow++ = GetBinormal (x, y); } } }
void FBXScene::ProcessMesh(FbxNode* pNode) { FbxMesh* pFBXMesh = pNode->GetMesh(); if( !pFBXMesh ) return; if ( pFBXMesh->GetPolygonVertexCount() != pFBXMesh->GetPolygonCount() * 3 ) { FbxGeometryConverter GeometryConverter(pNode->GetFbxManager()); if( !GeometryConverter.TriangulateInPlace( pNode ) ) { return; } pFBXMesh = pNode->GetMesh(); } pFBXMesh->InitNormals(); pFBXMesh->ComputeVertexNormals(true); pFBXMesh->GenerateTangentsDataForAllUVSets(); int nVertexCount = pFBXMesh->GetControlPointsCount(); if( nVertexCount <= 0 ) return; std::vector<BoneWeights> boneWeights(nVertexCount); ProcessBoneWeights(pFBXMesh, boneWeights); Model* pModel = new Model(pNode->GetName(), m_Models.GetCount(), false); FbxVector4* aControlPoints = pFBXMesh->GetControlPoints(); for( int pi = 0; pi < pFBXMesh->GetPolygonCount(); ++pi ) // Whole for-loop takes some time too, investigate further. { // Material Material* pMaterial = NULL; for( unsigned int pvi = 0; pvi < 3; ++pvi ) { int nVertexIndex = pFBXMesh->GetPolygonVertex(pi, pvi); if( nVertexIndex < 0 || nVertexIndex >= nVertexCount ) continue; // Material if( pMaterial == NULL ) pMaterial = GetMaterialLinkedWithPolygon(pFBXMesh, 0, pi, 0, nVertexIndex); // Position FbxVector4 fbxPosition = aControlPoints[nVertexIndex]; // Normals And Tangents FbxVector4 fbxNormal, fbxTangent; fbxNormal = GetNormal(pFBXMesh, 0, pi, pvi, nVertexIndex); fbxTangent = GetTangent(pFBXMesh, 0, pi, pvi, nVertexIndex); // Add Vertex pModel->AddVertex(pMaterial, FbxVector4ToBTHFBX_VEC3(fbxPosition), FbxVector4ToBTHFBX_VEC3(fbxNormal), FbxVector4ToBTHFBX_VEC3(fbxTangent), GetTexCoord(pFBXMesh, 0, pi, pvi, nVertexIndex), boneWeights[nVertexIndex]); // Update Bounding Box UpdateBoundingBoxDataFromVertex(FbxVector4ToBTHFBX_VEC3(fbxPosition)); } } // Geometric Offset pModel->SetGeometricOffset2(GetGeometricOffset2(pNode)); // Insert Model m_Models.Add(pModel->GetName(), pModel); }