From 15740faf9fe9fe4be08965098bbf2947e096aeeb Mon Sep 17 00:00:00 2001 From: chai Date: Wed, 14 Aug 2019 22:50:43 +0800 Subject: +Unity Runtime code --- Runtime/Geometry/TangentSpaceCalculation.cpp | 534 +++++++++++++++++++++++++++ 1 file changed, 534 insertions(+) create mode 100644 Runtime/Geometry/TangentSpaceCalculation.cpp (limited to 'Runtime/Geometry/TangentSpaceCalculation.cpp') diff --git a/Runtime/Geometry/TangentSpaceCalculation.cpp b/Runtime/Geometry/TangentSpaceCalculation.cpp new file mode 100644 index 0000000..f7b17f1 --- /dev/null +++ b/Runtime/Geometry/TangentSpaceCalculation.cpp @@ -0,0 +1,534 @@ +#include "UnityPrefix.h" +#include "TangentSpaceCalculation.h" +#include "Runtime/Math/Matrix3x3.h" +#include "Runtime/Math/Vector2.h" +#include "Plane.h" +#include + +using std::vector; +/* +void CreateTangentSpaceTangents(const Vector3f* vertex, const Vector2f* texcoord, const Vector3f* normals, Matrix3x3f* avgOrthonormalBases, int vertexCount, const UInt16* indices, int triangleCount) +{ + Vector3f *tan1 = new Vector3f[vertexCount * 2]; + Vector3f *tan2 = tan1 + vertexCount; + memset(tan1, 0, vertexCount * sizeof(Vector3f) * 2); + + for (int a = 0; a < triangleCount; a++) + { + int i1 = indices[0]; + int i2 = indices[1]; + int i3 = indices[2]; + + const Vector3f& v1 = vertex[i1]; + const Vector3f& v2 = vertex[i2]; + const Vector3f& v3 = vertex[i3]; + + const Vector2f& w1 = texcoord[i1]; + const Vector2f& w2 = texcoord[i2]; + const Vector2f& w3 = texcoord[i3]; + + float x1 = v2.x - v1.x; + float x2 = v3.x - v1.x; + float y1 = v2.y - v1.y; + float y2 = v3.y - v1.y; + float z1 = v2.z - v1.z; + float z2 = v3.z - v1.z; + + float s1 = w2.x - w1.x; + float s2 = w3.x - w1.x; + float t1 = w2.y - w1.y; + float t2 = w3.y - w1.y; + + float r = 1.0F / (s1 * t2 - s2 * t1); + Vector3f sdir((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r); + Vector3f tdir((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r); + + tan1[i1] += sdir; + tan1[i2] += sdir; + tan1[i3] += sdir; + + tan2[i1] += tdir; + tan2[i2] += tdir; + tan2[i3] += tdir; + + indices += 3; + } + + + for (long a = 0; a < vertexCount; a++) + { + Vector3f normal = normals[a]; + Vector3f tangent = tan1[a]; + + + // Gram-Schmidt orthogonalize + (tangent - normal * (normal * tangent))); + + // Calculate handedness + //tangent[a].w = (normal % tangent * tan2[a] < 0.0F) ? -1.0F : 1.0F; + + avgOrthonormalBases[a].SetOrthoNormalBasis (tangent, Cross (normal, tangent), normal); + } + + delete[] tan1; +}*/ + +/* +void CreateTangentSpaceTangents (const Vector3f* pPositions, const Vector2f* tex, const Vector3f* normals, Matrix3x3f* avgOrthonormalBases, int vertexCount, const UInt16* indices, int faceCount) +{ + vector sVector, tVector; + vector avgS, avgT; + + avgS.resize (vertexCount); + avgT.resize (vertexCount); + + sVector.reserve (faceCount * 3); + tVector.reserve (faceCount * 3); + + // for each face, calculate its S,T & SxT vector, & store its edges + for (int f = 0; f < faceCount * 3; f += 3 ) + { + Vector3f edge0; + Vector3f edge1; + Vector3f s; + Vector3f t; + + // create an edge out of x, s and t + edge0.x = pPositions[ indices[ f + 1 ] ].x - pPositions[ indices[ f ] ].x; + edge0.y = tex[ indices[ f + 1 ] ].x - tex[ indices[ f ] ].x; + edge0.z = tex[ indices[ f + 1 ] ].y - tex[ indices[ f ] ].y; + + // create an edge out of x, s and t + edge1.x = pPositions[ indices[ f + 2 ] ].x - pPositions[ indices[ f ] ].x; + edge1.y = tex[ indices[ f + 2 ] ].x - tex[ indices[ f ] ].x; + edge1.z = tex[ indices[ f + 2 ] ].y - tex[ indices[ f ] ].y; + + Vector3f sxt = Cross (edge0, edge1); + + float a = sxt.x; + float b = sxt.y; + float c = sxt.z; + + float ds_dx = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + ds_dx = -b / a; + + float dt_dx = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + dt_dx = -c / a; + + // create an edge out of y, s and t + edge0.x = pPositions[ indices[ f + 1 ] ].y - pPositions[ indices[ f ] ].y; + // create an edge out of y, s and t + edge1.x = pPositions[ indices[ f + 2 ] ].y - pPositions[ indices[ f ] ].y; + + sxt = Cross (edge0, edge1); + + a = sxt.x; + b = sxt.y; + c = sxt.z; + + float ds_dy = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + ds_dy = -b / a; + + float dt_dy = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + dt_dy = -c / a; + + // create an edge out of z, s and t + edge0.x = pPositions[ indices[ f + 1 ] ].z - pPositions[ indices[ f ] ].z; + // create an edge out of z, s and t + edge1.x = pPositions[ indices[ f + 2 ] ].z - pPositions[ indices[ f ] ].z; + + sxt = Cross (edge0, edge1); + + a = sxt.x; + b = sxt.y; + c = sxt.z; + + float ds_dz = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + ds_dz = -b / a; + + float dt_dz = 0.0F; + if ( Abs( a ) > Vector3f::epsilon ) + dt_dz = -c / a; + + // generate coordinate frame from the gradients + s = Vector3f( ds_dx, ds_dy, ds_dz ); + t = Vector3f( dt_dx, dt_dy, dt_dz ); + + s = NormalizeSafe (s); + t = NormalizeSafe (t); + + // save vectors for this face + sVector.push_back( s ); + tVector.push_back( t ); + } + + + for ( int p = 0; p < vertexCount; p ++ ) + { + avgS[p] = Vector3f::zero; + avgT[p] = Vector3f::zero; + } + + // go through faces and add up the bases for each vertex + for ( int face = 0; face < faceCount; ++face ) + { + // sum bases, so we smooth the tangent space across edges + avgS[ indices[ face * 3 ] ] += sVector[ face ]; + avgT[ indices[ face * 3 ] ] += tVector[ face ]; + + avgS[ indices[ face * 3 + 1 ] ] += sVector[ face ]; + avgT[ indices[ face * 3 + 1 ] ] += tVector[ face ]; + + avgS[ indices[ face * 3 + 2 ] ] += sVector[ face ]; + avgT[ indices[ face * 3 + 2 ] ] += tVector[ face ]; + } + + // now renormalize + for ( int p = 0; p < vertexCount; p ++ ) + { + Vector3f normal = normals[p]; + + + //OrthoNormalize (&normal, &avgS[p], &avgT[p]); + + avgOrthonormalBases[p].SetOrthoNormalBasis (avgS[p], avgT[p], normal); + + #if DEBUGMODE + float det = avgOrthonormalBases[p].GetDeterminant (); + AssertIf (!CompareApproximately (det, 1.0F,0.001) && !CompareApproximately (det, -1.0F,0.001)); + #endif +// AssertIf (!CompareApproximately (avgOrthonormalBases[p].MultiplyPoint3Transpose (Vector3f (0,0,1)), normal)); + } +}*/ + +/* +void CreateTangentSpaceTangents (const Vector3f* pPositions, const Vector2f* tex, const Vector3f* normals, Matrix3x3f* avgOrthonormalBases, int vertexCount, const UInt16* indices, int faceCount) +{ + + + Vector3f v0,v1,v2, tanu, tanv; + + Vector3f p0,p1,p2; + + Vector3f d1,d2; + + float uv[3][2],det,u,v,l1,l2; + + int i,j,k; + vector sVector, tVector; + vector avgS, avgT; + + avgS.resize (vertexCount); + avgT.resize (vertexCount); + + sVector.reserve (faceCount * 3); + tVector.reserve (faceCount * 3); + + for( i=0;i sVector, tVector; + vector avgS, avgT; + + avgS.resize (vertexCount); + avgT.resize (vertexCount); + + sVector.reserve (faceCount * 3); + tVector.reserve (faceCount * 3); + + for( i=0;i