Skip to content

Commit 2b7b9c2

Browse files
committed
bug fix ConvertRotScaleFromCovMat.
Need to check determinant of matrix before converting it to a quaternion, and flip the sign of the matrix by multiplying all axes by -1, for quat convertion to be correct. GaussianClound::ExportPly() seems to work now.
1 parent f8a112b commit 2b7b9c2

File tree

1 file changed

+15
-69
lines changed

1 file changed

+15
-69
lines changed

src/gaussiancloud.cpp

Lines changed: 15 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -97,55 +97,23 @@ static void ComputeRotScaleFromCovMat(const glm::mat3& V, glm::quat& rotOut, glm
9797
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> solver(eigenV);
9898

9999
// Get eigenvectors and eigenvalues
100-
Eigen::Matrix3f eigenR = solver.eigenvectors();
101-
Eigen::Array3f eigenS = solver.eigenvalues();
102-
103-
glm::mat3 R = eigenToGlm(eigenR);
104-
rotOut = glm::normalize(glm::quat(R));
105-
// NOTE: scale is stored in log scale in ply file
106-
scaleOut = glm::vec3(logf(std::sqrt(solver.eigenvalues()(0))),
107-
logf(std::sqrt(solver.eigenvalues()(1))),
108-
logf(std::sqrt(solver.eigenvalues()(2))));
109-
110-
#if 0
111-
// AJT: HACK REMOVE
112-
// now check the result.
113-
static int AJT_Count = 0;
114-
float r[] = {rotOut.w, rotOut.x, rotOut.y, rotOut.z};
115-
float s[] = {scaleOut.x, scaleOut.y, scaleOut.z};
116-
glm::mat3 V2 = ComputeCovMatFromRotScale(r, s);
117-
118-
const float EPSILON = 0.0001f;
119-
if (fabsf(V[0][0] - V2[0][0]) > EPSILON ||
120-
fabsf(V[0][1] - V2[0][1]) > EPSILON ||
121-
fabsf(V[0][2] - V2[0][2]) > EPSILON ||
122-
fabsf(V[1][0] - V2[1][0]) > EPSILON ||
123-
fabsf(V[1][1] - V2[1][1]) > EPSILON ||
124-
fabsf(V[1][2] - V2[1][2]) > EPSILON ||
125-
fabsf(V[2][0] - V2[2][0]) > EPSILON ||
126-
fabsf(V[2][1] - V2[2][1]) > EPSILON ||
127-
fabsf(V[2][2] - V2[2][2]) > EPSILON)
100+
Eigen::Matrix3f eigenVec = solver.eigenvectors();
101+
Eigen::Array3f eigenVal = solver.eigenvalues();
102+
glm::mat3 R = eigenToGlm(eigenVec);
103+
// glm mat3 to quat only works when det is 1.
104+
if (glm::determinant(R) < 0)
128105
{
129-
130-
Log::E("AJT: ComputeRotScaleFromCovMat i = %d\n", AJT_Count);
131-
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
132-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
133-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
134-
Log::E("AJT:\n");
135-
Log::E("AJT: eigenR = | %10.5f %10.5f %10.5f |\n", eigenR(0,0), eigenR(0,1), eigenR(0,2));
136-
Log::E("AJT: | %10.5f %10.5f %10.5f |\n", eigenR(1,0), eigenR(1,1), eigenR(1,2));
137-
Log::E("AJT: | %10.5f %10.5f %10.5f |\n", eigenR(2,0), eigenR(2,1), eigenR(2,2));
138-
Log::E("AJT: eigenS = [%0.5f, %0.5f, %0.5f]\n", eigenS(0), eigenS(1), eigenS(2));
139-
Log::E("AJT:\n");
140-
Log::E("AJT: scaleOut = [%.5f, %.5f, %.5f]\n", scaleOut[0], scaleOut[1], scaleOut[2]);
141-
Log::E("AJT: rotOut = [%.5f, %.5f, %.5f, %.5f]\n", rotOut.w, rotOut.x, rotOut.y, rotOut.z);
142-
Log::E("AJT:\n");
143-
Log::E("AJT: V2 = | %10.5f, %10.5f, %10.5f |\n", V2[0][0], V2[1][0], V2[2][0]);
144-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V2[0][1], V2[1][1], V2[2][1]);
145-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V2[0][2], V2[1][2], V2[2][2]);
106+
R[0] *= -1.0f;
107+
R[1] *= -1.0f;
108+
R[2] *= -1.0f;
146109
}
147-
AJT_Count++;
148-
#endif
110+
rotOut = glm::normalize(glm::quat(R));
111+
// NOTE: scale is stored in log scale in ply file
112+
// Also, the eigenVal is for (S*S^T) we want it for S, so
113+
// take the sqrt of the eigenVal. (or equivalently 1/2 of the log of the eigenVal.)
114+
scaleOut = glm::vec3(logf(eigenVal(0)) / 2.0f,
115+
logf(eigenVal(1)) / 2.0f,
116+
logf(eigenVal(2)) / 2.0f);
149117
}
150118

151119
static float ComputeAlphaFromOpacity(float opacity)
@@ -349,18 +317,6 @@ bool GaussianCloud::ImportPly(const std::string& plyFilename)
349317
gd[i].cov3_col2[0] = V[2][0];
350318
gd[i].cov3_col2[1] = V[2][1];
351319
gd[i].cov3_col2[2] = V[2][2];
352-
353-
// AJT: TODO REMOVE DEBUG
354-
if (i == 0)
355-
{
356-
Log::E("AJT: ImportPly\n");
357-
Log::E("AJT: rot = [%.5f, %.5f, %.5f, %.5f]\n", rot[0], rot[1], rot[2], rot[3]);
358-
Log::E("AJT: scale = [%.5f, %.5f, %.5f]\n", scale[0], scale[1], scale[2]);
359-
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
360-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
361-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
362-
}
363-
364320
i++;
365321
});
366322
}
@@ -496,16 +452,6 @@ bool GaussianCloud::ExportPly(const std::string& plyFilename, bool exportFullSh)
496452
props.rot[2].Write<float>(plyData, rot.y);
497453
props.rot[3].Write<float>(plyData, rot.z);
498454

499-
if (runningSize == 0)
500-
{
501-
Log::E("AJT: ExportPly\n");
502-
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
503-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
504-
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
505-
Log::E("AJT: rot = [%.5f, %.5f, %.5f, %.5f]\n", rot.w, rot.x, rot.y, rot.z);
506-
Log::E("AJT: scale = [%.5f, %.5f, %.5f]\n", scale[0], scale[1], scale[2]);
507-
}
508-
509455
gData += gaussianSize;
510456
runningSize += gaussianSize;
511457
assert(runningSize <= GetTotalSize()); // bad, we went off the end of the data ptr

0 commit comments

Comments
 (0)