本文整理汇总了C++中VertexBufferAccessor::HasTangent方法的典型用法代码示例。如果您正苦于以下问题:C++ VertexBufferAccessor::HasTangent方法的具体用法?C++ VertexBufferAccessor::HasTangent怎么用?C++ VertexBufferAccessor::HasTangent使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类VertexBufferAccessor
的用法示例。
在下文中一共展示了VertexBufferAccessor::HasTangent方法的2个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: UpdateModelTangentsUseTCoords
//----------------------------------------------------------------------------
void Triangles::UpdateModelTangentsUseTCoords (VertexBufferAccessor& vba)
{
// Each vertex can be visited multiple times, so compute the tangent
// space only on the first visit. Use the zero vector as a flag for the
// tangent vector not being computed.
const int numVertices = vba.GetNumVertices();
bool hasTangent = vba.HasTangent();
Float3 zero(0.0f, 0.0f, 0.0f);
int i;
if (hasTangent)
{
for (i = 0; i < numVertices; ++i)
{
vba.Tangent<Float3>(i) = zero;
}
}
else
{
for (i = 0; i < numVertices; ++i)
{
vba.Binormal<Float3>(i) = zero;
}
}
const int numTriangles = GetNumTriangles();
for (i = 0; i < numTriangles; i++)
{
// Get the triangle vertices' positions, normals, tangents, and
// texture coordinates.
int v0, v1, v2;
if (!GetTriangle(i, v0, v1, v2))
{
continue;
}
APoint locPosition[3] =
{
vba.Position<Float3>(v0),
vba.Position<Float3>(v1),
vba.Position<Float3>(v2)
};
AVector locNormal[3] =
{
vba.Normal<Float3>(v0),
vba.Normal<Float3>(v1),
vba.Normal<Float3>(v2)
};
AVector locTangent[3] =
{
(hasTangent ? vba.Tangent<Float3>(v0) : vba.Binormal<Float3>(v0)),
(hasTangent ? vba.Tangent<Float3>(v1) : vba.Binormal<Float3>(v1)),
(hasTangent ? vba.Tangent<Float3>(v2) : vba.Binormal<Float3>(v2))
};
Float2 locTCoord[3] =
{
vba.TCoord<Float2>(0, v0),
vba.TCoord<Float2>(0, v1),
vba.TCoord<Float2>(0, v2)
};
for (int curr = 0; curr < 3; ++curr)
{
Float3 currLocTangent = (Float3)locTangent[curr];
if (currLocTangent != zero)
{
// This vertex has already been visited.
continue;
}
// Compute the tangent space at the vertex.
AVector norvec = locNormal[curr];
int prev = ((curr + 2) % 3);
int next = ((curr + 1) % 3);
AVector tanvec = ComputeTangent(
locPosition[curr], locTCoord[curr],
locPosition[next], locTCoord[next],
locPosition[prev], locTCoord[prev]);
// Project T into the tangent plane by projecting out the surface
// normal N, and then making it unit length.
tanvec -= norvec.Dot(tanvec)*norvec;
tanvec.Normalize();
// Compute the bitangent B, another tangent perpendicular to T.
AVector binvec = norvec.UnitCross(tanvec);
if (vba.HasTangent())
{
locTangent[curr] = tanvec;
if (vba.HasBinormal())
{
vba.Binormal<Float3>(curr) = binvec;
}
}
else
{
//.........这里部分代码省略.........
示例2: UpdateModelTangentsUseGeometry
//.........这里部分代码省略.........
}
}
}
// Add N*N^T to W*W^T for numerical stability. In theory 0*0^T is added
// to D*W^T, but of course no update is needed in the implementation.
// Compute the matrix of normal derivatives.
for (i = 0; i < numVertices; ++i)
{
AVector nor = vba.Normal<Float3>(i);
for (row = 0; row < 3; ++row)
{
for (col = 0; col < 3; ++col)
{
wwTrn[i][row][col] =
0.5f*wwTrn[i][row][col] + nor[row]*nor[col];
dwTrn[i][row][col] *= 0.5f;
}
}
wwTrn[i].SetColumn(3, APoint::ORIGIN);
dNormal[i] = dwTrn[i]*wwTrn[i].Inverse();
}
delete1(wwTrn);
delete1(dwTrn);
// If N is a unit-length normal at a vertex, let U and V be unit-length
// tangents so that {U, V, N} is an orthonormal set. Define the matrix
// J = [U | V], a 3-by-2 matrix whose columns are U and V. Define J^T
// to be the transpose of J, a 2-by-3 matrix. Let dN/dX denote the
// matrix of first-order derivatives of the normal vector field. The
// shape matrix is
// S = (J^T * J)^{-1} * J^T * dN/dX * J = J^T * dN/dX * J
// where the superscript of -1 denotes the inverse. (The formula allows
// for J built from non-perpendicular vectors.) The matrix S is 2-by-2.
// The principal curvatures are the eigenvalues of S. If k is a principal
// curvature and W is the 2-by-1 eigenvector corresponding to it, then
// S*W = k*W (by definition). The corresponding 3-by-1 tangent vector at
// the vertex is called the principal direction for k, and is J*W. The
// principal direction for the minimum principal curvature is stored as
// the mesh tangent. The principal direction for the maximum principal
// curvature is stored as the mesh bitangent.
for (i = 0; i < numVertices; ++i)
{
// Compute U and V given N.
AVector norvec = vba.Normal<Float3>(i);
AVector uvec, vvec;
AVector::GenerateComplementBasis(uvec, vvec, norvec);
// Compute S = J^T * dN/dX * J. In theory S is symmetric, but
// because we have estimated dN/dX, we must slightly adjust our
// calculations to make sure S is symmetric.
float s01 = uvec.Dot(dNormal[i]*vvec);
float s10 = vvec.Dot(dNormal[i]*uvec);
float sAvr = 0.5f*(s01 + s10);
float smat[2][2] =
{
{ uvec.Dot(dNormal[i]*uvec), sAvr },
{ sAvr, vvec.Dot(dNormal[i]*vvec) }
};
// Compute the eigenvalues of S (min and max curvatures).
float trace = smat[0][0] + smat[1][1];
float det = smat[0][0]*smat[1][1] - smat[0][1]*smat[1][0];
float discr = trace*trace - 4.0f*det;
float rootDiscr = Mathf::Sqrt(Mathf::FAbs(discr));
float minCurvature = 0.5f*(trace - rootDiscr);
// float maxCurvature = 0.5f*(trace + rootDiscr);
// Compute the eigenvectors of S.
AVector evec0(smat[0][1], minCurvature - smat[0][0], 0.0f);
AVector evec1(minCurvature - smat[1][1], smat[1][0], 0.0f);
AVector tanvec, binvec;
if (evec0.SquaredLength() >= evec1.SquaredLength())
{
evec0.Normalize();
tanvec = evec0.X()*uvec + evec0.Y()*vvec;
binvec = norvec.Cross(tanvec);
}
else
{
evec1.Normalize();
tanvec = evec1.X()*uvec + evec1.Y()*vvec;
binvec = norvec.Cross(tanvec);
}
if (vba.HasTangent())
{
vba.Tangent<Float3>(i) = tanvec;
}
if (vba.HasBinormal())
{
vba.Binormal<Float3>(i) = binvec;
}
}
delete1(dNormal);
}