/// @todo should use a best fit transformation from one set of points to another void TensegrityModel::rotateAndTranslate(tgStructure& childStructure2, std::vector<btVector3>& structure1RefNodes, std::vector<btVector3>& structure2RefNodes) { btVector3 structure1RefNodesCentroid = tgUtil::getCentroid(structure1RefNodes); btVector3 structure2RefNodesCentroid = tgUtil::getCentroid(structure2RefNodes); btVector3 structure1PlaneNormal = ((structure1RefNodes[1] - structure1RefNodes[0]). cross(structure1RefNodes[2] - structure1RefNodes[0])).normalize(); btVector3 structure2PlaneNormal = ((structure2RefNodes[1] - structure2RefNodes[0]). cross(structure2RefNodes[2] - structure2RefNodes[0])).normalize(); // rotate structure 2 to align normals btVector3 fallBackAxis = (structure2RefNodes[1] - structure2RefNodes[0]).normalize(); childStructure2.addRotation(structure2RefNodesCentroid, tgUtil::getQuaternionBetween(structure2PlaneNormal, structure1PlaneNormal, fallBackAxis)); // rotate structure 2 ref nodes tgUtil::addRotation(structure2RefNodes[0], structure2RefNodesCentroid, tgUtil::getQuaternionBetween(structure2PlaneNormal, structure1PlaneNormal, fallBackAxis)); tgUtil::addRotation(structure2RefNodesCentroid, structure2RefNodesCentroid, tgUtil::getQuaternionBetween(structure2PlaneNormal, structure1PlaneNormal, fallBackAxis)); // translate structure 2 to match up centroid points childStructure2.move(structure1RefNodesCentroid - structure2RefNodesCentroid); // translate structure 2 ref nodes structure2RefNodes[0] += structure1RefNodesCentroid - structure2RefNodesCentroid; structure2RefNodesCentroid += structure1RefNodesCentroid - structure2RefNodesCentroid; // rotate structure 2 around structure1PlaneNormal axis to match up node with edge midpoints childStructure2.addRotation(structure1RefNodesCentroid, tgUtil::getQuaternionBetween(structure2RefNodes[0] - structure1RefNodesCentroid, structure1RefNodes[0] - structure1RefNodesCentroid, structure1PlaneNormal)); }
void TensegrityModel::addChildRotation(tgStructure& childStructure, const Yam& rotation) { if (!rotation) return; Yam reference = rotation["reference"]; Yam axis = rotation["axis"]; Yam angle = rotation["angle"]; if (axis && angle) { double axisX = axis[0].as<double>(); double axisY = axis[1].as<double>(); double axisZ = axis[2].as<double>(); btVector3 axisVector = btVector3(axisX, axisY, axisZ); double angleDegrees = angle.as<double>(); double angleRadians = tgUtil::deg2rad(angleDegrees); btVector3 referenceVector; if (reference) { // rotate child around provided reference point double referenceX = reference[0].as<double>(); double referenceY = reference[1].as<double>(); double referenceZ = reference[2].as<double>(); referenceVector = btVector3(referenceX, referenceY, referenceZ); } else { // rotate child around structure's centroid referenceVector = childStructure.getCentroid(); } childStructure.addRotation(referenceVector, axisVector, angleRadians); } }
// Nodes: center points of opposing faces of rectangles void CraterDeep::addNodes(tgStructure& s) { const int nBoxes = 4; // Accumulating rotation on boxes btVector3 rotationPoint = origin; btVector3 rotationAxis = btVector3(0, 1, 0); // y-axis double rotationAngle = M_PI/2; addBoxNodes(); addBoxNodes(); addBoxNodes(); addBoxNodes(); for(int i=0;i<nodes.size();i+=2) { s.addNode(nodes[i]); s.addNode(nodes[i+1]); s.addRotation(rotationPoint, rotationAxis, rotationAngle); s.addPair(i, i+1, "box"); } s.move(btVector3(0, -5, 0)); // Sink boxes into the ground }
// Nodes: center points of opposing faces of rectangles void tgCraterDeep::addNodes(tgStructure& s) { #if (0) const int nBoxes = 4; #endif // Suppress compiler warning unused variable // Accumulating rotation on boxes btVector3 rotationPoint = origin; btVector3 rotationAxis = btVector3(0, 1, 0); // y-axis double rotationAngle = M_PI/2; addBoxNodes(); addBoxNodes(); addBoxNodes(); addBoxNodes(); for(std::size_t i=0;i<nodes.size();i+=2) { s.addNode(nodes[i]); s.addNode(nodes[i+1]); s.addRotation(rotationPoint, rotationAxis, rotationAngle); s.addPair(i, i+1, "box"); } s.move(btVector3(0, -5, 0)); // Sink boxes into the ground }