SbMatrix tgf::MatrixFromTransform( const Transform& transform ) { Ptr<Matrix4x4> transformMatrix = transform.GetMatrix()->Transpose(); float m00 = float ( transformMatrix->m[0][0] ); float m01 = float ( transformMatrix->m[0][1] ); float m02 = float ( transformMatrix->m[0][2] ); float m03 = float ( transformMatrix->m[0][3] ); float m10 = float ( transformMatrix->m[1][0] ); float m11 = float ( transformMatrix->m[1][1] ); float m12 = float ( transformMatrix->m[1][2] ); float m13 = float ( transformMatrix->m[1][3] ); float m20 = float ( transformMatrix->m[2][0] ); float m21 = float ( transformMatrix->m[2][1] ); float m22 = float ( transformMatrix->m[2][2] ); float m23 = float ( transformMatrix->m[2][3] ); float m30 = float ( transformMatrix->m[3][0] ); float m31 = float ( transformMatrix->m[3][1] ); float m32 = float ( transformMatrix->m[3][2] ); float m33 = float ( transformMatrix->m[3][3] ); SbVec3f axis1( m00, m10, m20 ); SbVec3f axis2( m01, m11, m21 ); //axis2.normalize(); SbVec3f axis3( m02, m12, m22 ); //axis3.normalize(); return SbMatrix( axis1[0], axis2[0], axis3[0], m03, axis1[1], axis2[1], axis3[1], m13, axis1[2], axis2[2], axis3[2], m23, m30, m31, m32, m33 ); }
SbMatrix SbMatrix::identity() { return SbMatrix(1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0); }
SoShaderParameterMatrixArray::SoShaderParameterMatrixArray(void) { SO_NODE_CONSTRUCTOR(SoShaderParameterMatrixArray); SO_NODE_ADD_FIELD(value, (SbMatrix(1,0,0,0, 0,1,0,0, 0,0,1,0, 0,0,0,1))); }
SbMatrix SbMatrix::transpose() const { return SbMatrix(matrix[0][0], matrix[1][0], matrix[2][0], matrix[3][0], matrix[0][1], matrix[1][1], matrix[2][1], matrix[3][1], matrix[0][2], matrix[1][2], matrix[2][2], matrix[3][2], matrix[0][3], matrix[1][3], matrix[2][3], matrix[3][3]); }
SbBool SbMatrix::factor(SbMatrix &r, SbVec3f &s, SbMatrix &u, SbVec3f &t, SbMatrix &proj) const { double det; /* Determinant of matrix A */ double det_sign; /* -1 if det < 0, 1 if det > 0 */ double scratch; int i, j; int junk; SbMatrix a, b, si; float evalues[3]; SbVec3f evectors[3]; a = *this; proj.makeIdentity(); scratch = 1.0; for (i = 0; i < 3; i++) { for (j = 0; j < 3; j++) { a.matrix[i][j] *= scratch; } t[i] = matrix[3][i] * scratch; a.matrix[3][i] = a.matrix[i][3] = 0.0; } a.matrix[3][3] = 1.0; /* (3) Compute det A. If negative, set sign = -1, else sign = 1 */ det = a.det3(); det_sign = (det < 0.0 ? -1.0 : 1.0); if (det_sign * det < 1e-12) return(FALSE); // singular /* (4) B = A * A^ (here A^ means A transpose) */ b = a * a.transpose(); b.jacobi3(evalues, evectors, junk); // find min / max eigenvalues and do ratio test to determine singularity r = SbMatrix(evectors[0][0], evectors[0][1], evectors[0][2], 0.0, evectors[1][0], evectors[1][1], evectors[1][2], 0.0, evectors[2][0], evectors[2][1], evectors[2][2], 0.0, 0.0, 0.0, 0.0, 1.0); /* Compute s = sqrt(evalues), with sign. Set si = s-inverse */ si.makeIdentity(); for (i = 0; i < 3; i++) { s[i] = det_sign * sqrt(evalues[i]); si.matrix[i][i] = 1.0 / s[i]; } /* (5) Compute U = R^ S! R A. */ u = r * si * r.transpose() * a; return(TRUE); }
// Default constructor. SoDecomposeMatrix::SoDecomposeMatrix() { SO_ENGINE_INTERNAL_CONSTRUCTOR(SoDecomposeMatrix); SO_ENGINE_ADD_INPUT(matrix,(SbMatrix())); SO_ENGINE_ADD_INPUT(center,(SbVec3f())); SO_ENGINE_ADD_OUTPUT(translation,SoMFVec3f); SO_ENGINE_ADD_OUTPUT(rotation,SoMFRotation); SO_ENGINE_ADD_OUTPUT(scaleFactor,SoMFVec3f); SO_ENGINE_ADD_OUTPUT(scaleOrientation,SoMFRotation); }
/*! Set matrix elements. */ void SoSFMatrix::setValue(const float a11, const float a12, const float a13, const float a14, const float a21, const float a22, const float a23, const float a24, const float a31, const float a32, const float a33, const float a34, const float a41, const float a42, const float a43, const float a44) { this->setValue(SbMatrix(a11,a12,a13,a14,a21,a22,a23,a24, a31,a32,a33,a34,a41,a42,a43,a44)); }
void SoSFMatrix::setValue(float a11, float a12, float a13, float a14, float a21, float a22, float a23, float a24, float a31, float a32, float a33, float a34, float a41, float a42, float a43, float a44) // //////////////////////////////////////////////////////////////////////// { setValue(SbMatrix(a11, a12, a13, a14, a21, a22, a23, a24, a31, a32, a33, a34, a41, a42, a43, a44)); }
/* *! Used to get the model matrix from the server */ void SoXipRemoteVolume::getModelMatrix() { if(!mStream) return; //send the request for modelMatrix mReqSender.initSender(mStream, GET_VOLUME_MODELMATRIX); mReqSender.send(); // expect the response from the server. mReqReceiver.initReceiver(mStream); mReqReceiver.receive(); // if there is some error or the sorting operation did not result in a valid volume. if( (mReqReceiver.getFirstElementId() != GET_VOLUME_MODELMATRIX)) { SoError::post("RemoteVolume: Server modelMatrix request error!\n"); return; } float *m = (float *)mReqReceiver.getElementContent(GETVOLUMEMMATRIXRESPONSE_MODELMATRIX, 16*sizeof(float)); if(!m) { SoError::post("RemoteVolume: Server modelMatrix request error!\n"); return; } mReqReceiver.rSwapf(m, 16); SO_ENGINE_OUTPUT(modelMatrixOutput, SoSFMatrix, setValue(SbMatrix ( m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8], m[9], m[10], m[11], m[12], m[13], m[14], m[15]))); }
void SoXipImageAttributes::evaluate() { SoXipDataImage *imgData = image.getValue(); if (imgData) { SbXipImage *img = imgData->get(); if (img) { SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(img->getModelMatrix())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(img->getBitsStored())); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(img->getDimStored()[0])); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(img->getDimStored()[1])); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(img->getDimStored()[2])); SbMatrix modelMat = img->getModelMatrix(); SbVec3f t, s; SbRotation r, so; modelMat.getTransform(t, r, s, so); modelMat.multVecMatrix(SbVec3f(0.5, 0.5, 0.5), t); // scale MPR model matrix always to max. individual dimension by default float maxScale = s[0] > s[1] ? s[0] : s[1] > s[2] ? s[1] : s[2]; // modelMat.setTransform(t, r, SbVec3f(maxScale, maxScale, maxScale), so); // when using get/setTransform, the rotation is derived from normal vector // but for gantry tilt, we need to compute normal from row and column vector SbVec3f rot[3]; rot[0] = SbVec3f(modelMat[0][0], modelMat[0][1], modelMat[0][2]); rot[1] = SbVec3f(modelMat[1][0], modelMat[1][1], modelMat[1][2]); rot[2] = rot[0].cross(rot[1]); rot[0].normalize(); rot[1].normalize(); rot[2].normalize(); rot[0] *= maxScale; rot[1] *= maxScale; rot[2] *= maxScale; modelMat = SbMatrix( rot[0][0], rot[0][1], rot[0][2], 0, rot[1][0], rot[1][1], rot[1][2], 0, rot[2][0], rot[2][1], rot[2][2], 0, t[0], t[1], t[2], 1); // update engine outputs SbMatrix tmp = SbMatrix::identity(); // flip default viewing direction tmp.setRotate(SbRotation(SbVec3f(1, 0, 0), M_PI)); SbMatrix defOrient = tmp * modelMat; // adjust so plane falls onto original plane defOrient.getTransform(t, r, s, so); SbVec3f object; modelMat = img->getModelMatrix(); modelMat.inverse().multVecMatrix(t, object); object[0] = int(object[0] * img->getDimStored()[0] + 0.5); object[1] = int(object[1] * img->getDimStored()[1] + 0.5); object[2] = int(object[2] * img->getDimStored()[2] + 0.5); object[0] /= img->getDimStored()[0]; object[1] /= img->getDimStored()[1]; object[2] /= img->getDimStored()[2]; modelMat.multVecMatrix(object, t); defOrient.setTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(defOrient)); SbMatrix ortho1, ortho2, ortho3; int which = XipGeomUtils::orthoOrientations(defOrient, ortho1, ortho2, ortho3); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(which)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(ortho1)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(ortho2)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(ortho3)); defOrient.getTransform(t, r, s, so); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(t)); return; } } SO_ENGINE_OUTPUT(modelMatrix, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(bitsStored, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(width, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(height, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(depth, SoSFShort, setValue(0)); SbMatrix rot1, rot2; SO_ENGINE_OUTPUT(defaultOrientation, SoSFMatrix, setValue(SbMatrix::identity())); SO_ENGINE_OUTPUT(orthoScanOrientation, SoSFShort, setValue(0)); SO_ENGINE_OUTPUT(orthoOrientation1, SoSFMatrix, setValue(SbMatrix::identity())); rot1.setRotate(SbRotation(SbVec3f(1, 0, 0), -M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation2, SoSFMatrix, setValue(rot1)); rot2.setRotate(SbRotation(SbVec3f(0, 1, 0), M_PI / 2.f)); SO_ENGINE_OUTPUT(orthoOrientation3, SoSFMatrix, setValue(rot2 * rot1)); SO_ENGINE_OUTPUT(defaultCenter, SoSFVec3f, setValue(SbVec3f(0.5, 0.5, 0.5))); }
SbMatrix SbMatrix::inverse() const { // Trivial case if (IS_IDENTITY(matrix)) return SbMatrix::identity(); // Affine case... SbMatrix affineAnswer; if ( affine_inverse( SbMatrix(matrix), affineAnswer ) ) return affineAnswer; int index[4]; float d, invmat[4][4], temp; SbMatrix inverse = *this; #ifdef DEBUGGING int i, j; #endif /* DEBUGGING */ if(inverse.LUDecomposition(index, d)) { #ifdef DEBUGGING for(j = 0; j < 4; j++) { for(i = 0; i < 4; i++) invmat[j][i] = 0.0; invmat[j][j] = 1.0; inverse.LUBackSubstitution(index, invmat[j]); } #else invmat[0][0] = 1.0; invmat[0][1] = 0.0; invmat[0][2] = 0.0; invmat[0][3] = 0.0; inverse.LUBackSubstitution(index, invmat[0]); invmat[1][0] = 0.0; invmat[1][1] = 1.0; invmat[1][2] = 0.0; invmat[1][3] = 0.0; inverse.LUBackSubstitution(index, invmat[1]); invmat[2][0] = 0.0; invmat[2][1] = 0.0; invmat[2][2] = 1.0; invmat[2][3] = 0.0; inverse.LUBackSubstitution(index, invmat[2]); invmat[3][0] = 0.0; invmat[3][1] = 0.0; invmat[3][2] = 0.0; invmat[3][3] = 1.0; inverse.LUBackSubstitution(index, invmat[3]); #endif /* DEBUGGING */ #ifdef DEBUGGING // transpose invmat for(j = 0; j < 4; j++) { for(i = 0; i < j; i++) { temp = invmat[i][j]; invmat[i][j] = invmat[j][i]; invmat[j][i] = temp; } } #else #define SWAP(i,j) \ temp = invmat[i][j]; \ invmat[i][j] = invmat[j][i]; \ invmat[j][i] = temp; SWAP(1,0); SWAP(2,0); SWAP(2,1); SWAP(3,0); SWAP(3,1); SWAP(3,2); #undef SWAP #endif /* DEBUGGING */ #ifdef _MSC_VER inverse.setValue((const SbMat &)invmat); #else inverse.setValue(invmat); #endif } return inverse; }