------------------------------------------------------------------------------------------------ Recursively writes the given node
| 1521 | // ------------------------------------------------------------------------------------------------ |
| 1522 | // Recursively writes the given node |
| 1523 | void ColladaExporter::WriteNode(const aiNode *pNode) { |
| 1524 | // If the node is associated with a bone, it is a joint node (JOINT) |
| 1525 | // otherwise it is a normal node (NODE) |
| 1526 | // Assimp-specific: nodes with no name cannot be associated with bones |
| 1527 | const char *node_type; |
| 1528 | bool is_joint, is_skeleton_root = false; |
| 1529 | if (pNode->mName.length == 0 || nullptr == mScene->findBone(pNode->mName)) { |
| 1530 | node_type = "NODE"; |
| 1531 | is_joint = false; |
| 1532 | } else { |
| 1533 | node_type = "JOINT"; |
| 1534 | is_joint = true; |
| 1535 | if (!pNode->mParent || nullptr == mScene->findBone(pNode->mParent->mName)) { |
| 1536 | is_skeleton_root = true; |
| 1537 | } |
| 1538 | } |
| 1539 | |
| 1540 | const std::string node_id = GetNodeUniqueId(pNode); |
| 1541 | const std::string node_name = GetNodeName(pNode); |
| 1542 | mOutput << startstr << "<node "; |
| 1543 | if (is_skeleton_root) { |
| 1544 | mFoundSkeletonRootNodeID = node_id; // For now, only support one skeleton in a scene. |
| 1545 | } |
| 1546 | mOutput << "id=\"" << node_id << "\" " << (is_joint ? "sid=\"" + node_id + "\" " : ""); |
| 1547 | mOutput << "name=\"" << node_name |
| 1548 | << "\" type=\"" << node_type |
| 1549 | << "\">" << endstr; |
| 1550 | PushTag(); |
| 1551 | |
| 1552 | // write transformation - we can directly put the matrix there |
| 1553 | // TODO: (thom) decompose into scale - rot - quad to allow addressing it by animations afterwards |
| 1554 | aiMatrix4x4 mat = pNode->mTransformation; |
| 1555 | |
| 1556 | // If this node is a Camera node, the camera coordinate system needs to be multiplied in. |
| 1557 | // When importing from Collada, the mLookAt is set to 0, 0, -1, and the node transform is unchanged. |
| 1558 | // When importing from a different format, mLookAt is set to 0, 0, 1. Therefore, the local camera |
| 1559 | // coordinate system must be changed to matche the Collada specification. |
| 1560 | for (size_t i = 0; i < mScene->mNumCameras; i++) { |
| 1561 | if (mScene->mCameras[i]->mName == pNode->mName) { |
| 1562 | aiMatrix4x4 sourceView; |
| 1563 | mScene->mCameras[i]->GetCameraMatrix(sourceView); |
| 1564 | |
| 1565 | aiMatrix4x4 colladaView; |
| 1566 | colladaView.a1 = colladaView.c3 = -1; // move into -z space. |
| 1567 | mat *= (sourceView * colladaView); |
| 1568 | break; |
| 1569 | } |
| 1570 | } |
| 1571 | |
| 1572 | // customized, sid should be 'matrix' to match with loader code. |
| 1573 | mOutput << startstr << "<matrix sid=\"matrix\">"; |
| 1574 | |
| 1575 | mOutput << mat.a1 << " " << mat.a2 << " " << mat.a3 << " " << mat.a4 << " "; |
| 1576 | mOutput << mat.b1 << " " << mat.b2 << " " << mat.b3 << " " << mat.b4 << " "; |
| 1577 | mOutput << mat.c1 << " " << mat.c2 << " " << mat.c3 << " " << mat.c4 << " "; |
| 1578 | mOutput << mat.d1 << " " << mat.d2 << " " << mat.d3 << " " << mat.d4; |
| 1579 | mOutput << "</matrix>" << endstr; |
| 1580 |
nothing calls this directly
no test coverage detected