/* this function is called from field renderers for all field nodes */ void Renderer::setNodeGlData(const shared_ptr<Node>& n){ bool scaleRotations=(rotScale!=1.0 && scaleOn); bool scaleDisplacements=(dispScale!=Vector3r::Ones() && scaleOn); const bool isPeriodic=scene->isPeriodic; if(!n->hasData<GlData>()) n->setData<GlData>(make_shared<GlData>()); GlData& gld=n->getData<GlData>(); // inside the cell if periodic, same as pos otherwise Vector3r cellPos=(!isPeriodic ? n->pos : scene->cell->canonicalizePt(n->pos,gld.dCellDist)); bool rendered=!pointClipped(cellPos); // this encodes that the node is clipped if(!rendered){ gld.dGlPos=Vector3r(NaN,NaN,NaN); return; } if(setRefNow || isnan(gld.refPos[0])) gld.refPos=n->pos; if(setRefNow || isnan(gld.refOri.x())) gld.refOri=n->ori; const Vector3r& pos=n->pos; const Vector3r& refPos=gld.refPos; const Quaternionr& ori=n->ori; const Quaternionr& refOri=gld.refOri; // if no scaling and no periodic, return quickly if(!(scaleDisplacements||scaleRotations||isPeriodic)){ gld.dGlPos=Vector3r::Zero(); gld.dGlOri=Quaternionr::Identity(); return; } // apply scaling gld.dGlPos=cellPos-n->pos; // add scaled translation to the point of reference if(scaleDisplacements) gld.dGlPos+=((dispScale-Vector3r::Ones()).array()*Vector3r(pos-refPos).array()).matrix(); if(!scaleRotations) gld.dGlOri=Quaternionr::Identity(); else{ Quaternionr relRot=refOri.conjugate()*ori; AngleAxisr aa(relRot); aa.angle()*=rotScale; gld.dGlOri=Quaternionr(aa); } }
void OpenGLRenderer::setBodiesDispInfo(){ if(scene->bodies->size()!=bodyDisp.size()) { bodyDisp.resize(scene->bodies->size()); for (unsigned k=0; k<scene->bodies->size(); k++) bodyDisp[k].hidden=0;} bool scaleRotations=(rotScale!=1.0); bool scaleDisplacements=(dispScale!=Vector3r::Ones()); FOREACH(const shared_ptr<Body>& b, *scene->bodies){ if(!b || !b->state) continue; size_t id=b->getId(); const Vector3r& pos=b->state->pos; const Vector3r& refPos=b->state->refPos; const Quaternionr& ori=b->state->ori; const Quaternionr& refOri=b->state->refOri; Vector3r cellPos=(!scene->isPeriodic ? pos : scene->cell->wrapShearedPt(pos)); // inside the cell if periodic, same as pos otherwise bodyDisp[id].isDisplayed=!pointClipped(cellPos); // if no scaling and no periodic, return quickly if(!(scaleDisplacements||scaleRotations||scene->isPeriodic)){ bodyDisp[id].pos=pos; bodyDisp[id].ori=ori; continue; } // apply scaling bodyDisp[id].pos=cellPos; // point of reference (inside the cell for periodic) if(scaleDisplacements) bodyDisp[id].pos+=dispScale.cwiseProduct(Vector3r(pos-refPos)); // add scaled translation to the point of reference if(!scaleRotations) bodyDisp[id].ori=ori; else{ Quaternionr relRot=refOri.conjugate()*ori; AngleAxisr aa(relRot); aa.angle()*=rotScale; bodyDisp[id].ori=refOri*Quaternionr(aa); } } }