Skip to content

Commit

Permalink
bug fix ConvertRotScaleFromCovMat.
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
hyperlogic committed Jul 2, 2024
1 parent f8a112b commit 2b7b9c2
Showing 1 changed file with 15 additions and 69 deletions.
84 changes: 15 additions & 69 deletions src/gaussiancloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,55 +97,23 @@ static void ComputeRotScaleFromCovMat(const glm::mat3& V, glm::quat& rotOut, glm
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3f> solver(eigenV);

// Get eigenvectors and eigenvalues
Eigen::Matrix3f eigenR = solver.eigenvectors();
Eigen::Array3f eigenS = solver.eigenvalues();

glm::mat3 R = eigenToGlm(eigenR);
rotOut = glm::normalize(glm::quat(R));
// NOTE: scale is stored in log scale in ply file
scaleOut = glm::vec3(logf(std::sqrt(solver.eigenvalues()(0))),
logf(std::sqrt(solver.eigenvalues()(1))),
logf(std::sqrt(solver.eigenvalues()(2))));

#if 0
// AJT: HACK REMOVE
// now check the result.
static int AJT_Count = 0;
float r[] = {rotOut.w, rotOut.x, rotOut.y, rotOut.z};
float s[] = {scaleOut.x, scaleOut.y, scaleOut.z};
glm::mat3 V2 = ComputeCovMatFromRotScale(r, s);

const float EPSILON = 0.0001f;
if (fabsf(V[0][0] - V2[0][0]) > EPSILON ||
fabsf(V[0][1] - V2[0][1]) > EPSILON ||
fabsf(V[0][2] - V2[0][2]) > EPSILON ||
fabsf(V[1][0] - V2[1][0]) > EPSILON ||
fabsf(V[1][1] - V2[1][1]) > EPSILON ||
fabsf(V[1][2] - V2[1][2]) > EPSILON ||
fabsf(V[2][0] - V2[2][0]) > EPSILON ||
fabsf(V[2][1] - V2[2][1]) > EPSILON ||
fabsf(V[2][2] - V2[2][2]) > EPSILON)
Eigen::Matrix3f eigenVec = solver.eigenvectors();
Eigen::Array3f eigenVal = solver.eigenvalues();
glm::mat3 R = eigenToGlm(eigenVec);
// glm mat3 to quat only works when det is 1.
if (glm::determinant(R) < 0)
{

Log::E("AJT: ComputeRotScaleFromCovMat i = %d\n", AJT_Count);
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
Log::E("AJT:\n");
Log::E("AJT: eigenR = | %10.5f %10.5f %10.5f |\n", eigenR(0,0), eigenR(0,1), eigenR(0,2));
Log::E("AJT: | %10.5f %10.5f %10.5f |\n", eigenR(1,0), eigenR(1,1), eigenR(1,2));
Log::E("AJT: | %10.5f %10.5f %10.5f |\n", eigenR(2,0), eigenR(2,1), eigenR(2,2));
Log::E("AJT: eigenS = [%0.5f, %0.5f, %0.5f]\n", eigenS(0), eigenS(1), eigenS(2));
Log::E("AJT:\n");
Log::E("AJT: scaleOut = [%.5f, %.5f, %.5f]\n", scaleOut[0], scaleOut[1], scaleOut[2]);
Log::E("AJT: rotOut = [%.5f, %.5f, %.5f, %.5f]\n", rotOut.w, rotOut.x, rotOut.y, rotOut.z);
Log::E("AJT:\n");
Log::E("AJT: V2 = | %10.5f, %10.5f, %10.5f |\n", V2[0][0], V2[1][0], V2[2][0]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V2[0][1], V2[1][1], V2[2][1]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V2[0][2], V2[1][2], V2[2][2]);
R[0] *= -1.0f;
R[1] *= -1.0f;
R[2] *= -1.0f;
}
AJT_Count++;
#endif
rotOut = glm::normalize(glm::quat(R));
// NOTE: scale is stored in log scale in ply file
// Also, the eigenVal is for (S*S^T) we want it for S, so
// take the sqrt of the eigenVal. (or equivalently 1/2 of the log of the eigenVal.)
scaleOut = glm::vec3(logf(eigenVal(0)) / 2.0f,
logf(eigenVal(1)) / 2.0f,
logf(eigenVal(2)) / 2.0f);
}

static float ComputeAlphaFromOpacity(float opacity)
Expand Down Expand Up @@ -349,18 +317,6 @@ bool GaussianCloud::ImportPly(const std::string& plyFilename)
gd[i].cov3_col2[0] = V[2][0];
gd[i].cov3_col2[1] = V[2][1];
gd[i].cov3_col2[2] = V[2][2];

// AJT: TODO REMOVE DEBUG
if (i == 0)
{
Log::E("AJT: ImportPly\n");
Log::E("AJT: rot = [%.5f, %.5f, %.5f, %.5f]\n", rot[0], rot[1], rot[2], rot[3]);
Log::E("AJT: scale = [%.5f, %.5f, %.5f]\n", scale[0], scale[1], scale[2]);
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
}

i++;
});
}
Expand Down Expand Up @@ -496,16 +452,6 @@ bool GaussianCloud::ExportPly(const std::string& plyFilename, bool exportFullSh)
props.rot[2].Write<float>(plyData, rot.y);
props.rot[3].Write<float>(plyData, rot.z);

if (runningSize == 0)
{
Log::E("AJT: ExportPly\n");
Log::E("AJT: V = | %10.5f, %10.5f, %10.5f |\n", V[0][0], V[1][0], V[2][0]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][1], V[1][1], V[2][1]);
Log::E("AJT: | %10.5f, %10.5f, %10.5f |\n", V[0][2], V[1][2], V[2][2]);
Log::E("AJT: rot = [%.5f, %.5f, %.5f, %.5f]\n", rot.w, rot.x, rot.y, rot.z);
Log::E("AJT: scale = [%.5f, %.5f, %.5f]\n", scale[0], scale[1], scale[2]);
}

gData += gaussianSize;
runningSize += gaussianSize;
assert(runningSize <= GetTotalSize()); // bad, we went off the end of the data ptr
Expand Down

0 comments on commit 2b7b9c2

Please sign in to comment.