void snap(Matrix& m) { if (csys) C = csys->getWorldMatrix(); if (orientation == POINT) { MatrixLookAt(m, snapP, snapP+Vec3f(prim_o.getPosition()), prim_o.getDirection()); m.multLeft(C); } }
Vec3f local(Vec3f p) { if (csys) { C = csys->getWorldMatrix(); C.invert(); Pnt3f pL; C.mult(p,pL); return Vec3f(pL); } else return p; }
void VRSnappingEngine::update() { for (auto dev : VRSetupManager::getCurrent()->getDevices()) { // get dragged objects VRTransform* obj = dev.second->getDraggedObject(); VRTransform* gobj = dev.second->getDraggedGhost(); if (obj == 0 || gobj == 0) continue; if (objects.count(obj) == 0) continue; Matrix m = gobj->getWorldMatrix(); Vec3f p = Vec3f(m[3]); for (auto ri : rules) { Rule* r = ri.second; if (r->csys == obj) continue; if (anchors.count(obj)) { for (auto a : anchors[obj]) { Matrix maL = a->getMatrix(); Matrix maW = m; maW.mult(maL); Vec3f pa = Vec3f(maW[3]); Vec3f paL = r->local( Vec3f(maW[3]) ); Vec3f psnap = r->getSnapPoint(pa); float D = (psnap-paL).length(); // check distance //cout << "dist " << D << " " << pa[1] << " " << paL[1] << " " << psnap[1] << endl; if (!r->inRange(D)) continue; r->snap(m); maL.invert(); m.mult(maL); event->set(obj, r->csys, m, dev.second); snapSignal->trigger<EventSnap>(event); break; } } else { Vec3f p2 = r->getSnapPoint(p); float D = (p2-p).length(); // check distance if (!r->inRange(D)) continue; r->snap(m); event->set(obj, r->csys, m, dev.second); snapSignal->trigger<EventSnap>(event); } } obj->setWorldMatrix(m); } // update geo if (!hintGeo->isVisible()) return; }