void HeadTrackedStereoCameraDecorator::getViewing(Matrix &result, UInt32 OSG_CHECK_ARG(width ), UInt32 OSG_CHECK_ARG(height)) { Node *pUser = getUser(); if(pUser == NULL) { FWARNING(("HeadTrackedStereoCameraDecorator::getViewing: no user!\n")); Camera *pCamera = getDecoratee(); if(pCamera == NULL) { result.setIdentity(); return; } pCamera->getBeacon()->getToWorld(result); result.invert(); } else { pUser->getToWorld(result); result.invert(); } }
// Obliczanie parametrów prostej regresji dla 5 punktów!! (w naszym przypadku) // Testowa³em TYLKO dla piêciopunktowych!! Parameters Matrix::getLinearEquationParameters(double x[], double y[], int size) { Matrix *m = new Matrix(x,5,1); Matrix *m2 = new Matrix(y,5,1); Matrix X= (*m).invert(); Matrix Y= (*m2).invert(); int sizex = X.getSizeY(); double tab[]= {1.0,1.0,1.0,1.0,1.0}; Matrix *ones = new Matrix(tab,1,5); Matrix Aa = X.join(*ones); Matrix LEFT = (Aa.invert())*Aa; Matrix RIGHT = (Aa.invert())*Y; Parameters ss; if(LEFT.getSizeX() != 2 || LEFT.getSizeY() != 2 || RIGHT.getSizeX() != 1 || RIGHT.getSizeY() != 2) { ss.isError=1; return ss; } Parameters ss2 = Matrix::calculate(LEFT(0,0), LEFT(1,0), RIGHT(0,0), LEFT(0,1), LEFT(1,1), RIGHT(0,1)); return ss2; }
/** * Draw the view frustum. * * @param dc The drawing context. */ void ChunkWatchControl::drawFrustum(CDC &dc) { Matrix view = WorldEditorCamera::instance().currentCamera().view(); view.invert(); float fov = Moo::rc().camera().fov(); float clipDist = Moo::rc().camera().farPlane(); Vector3 userPos = view.applyToOrigin(); Vector3 dir = view.applyToUnitAxisVector(2); Vector2 ndir = Vector2(dir.x, dir.z); float k = ::tanf(0.5f*fov)*clipDist; if (clipDist < SMALL_FRUSTUM) return; float ux, uz; worldToScreen(&ux, &uz, userPos.x, userPos.z); ndir.normalise(); float x1 = userPos.x + ndir.x*clipDist + k*ndir.y; float z1 = userPos.z + ndir.y*clipDist - k*ndir.x; float x2 = userPos.x + ndir.x*clipDist - k*ndir.y; float z2 = userPos.z + ndir.y*clipDist + k*ndir.x; worldToScreen(&x1, &z1, x1, z1); worldToScreen(&x2, &z2, x2, z2); CPen pen(PS_SOLID, 1, CLR_FRUSTUM); CPen *oldPen = dc.SelectObject(&pen); dc.MoveTo((int)ux, (int)uz); dc.LineTo((int)x1, (int)z1); dc.LineTo((int)x2, (int)z2); dc.LineTo((int)ux, (int)uz); dc.SelectObject(oldPen); }
/** * This is called every frame. We use this as an oportunity to RedrawWindow() * the control if the user has moved. */ /*afx_msg*/ void ChunkWatchControl::OnUpdateControl() { // Don't update to frequently. if (lastUpdateTime_ != 0) { uint64 now = timestamp(); if ((now - lastUpdateTime_)/(double)stampsPerSecond() < UPDATE_DELTA) { return; } } lastUpdateTime_ = timestamp(); Matrix view = WorldEditorCamera::instance().currentCamera().view(); view.invert(); Chunk *workingChunk = WorldManager::instance().workingChunk(); if ( !similar(view, drawPos_, MATRICES_COMP_EPSILON) || workingChunk != lastWorkingChunk_ ) { RedrawWindow(); } }
ActionBase::ResultE Joint::intersectEnter(Action *action) { // Use parent class for trivial reject if(Inherited::intersect(action) == Action::Skip) return Action::Skip; // Need to check children IntersectAction *ia = dynamic_cast<IntersectAction *>(action); Matrix m = this->getMatrix(); m.mult(this->getJointTransformation()); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); Real32 length = dir.length(); if(length < TypeTraits<Real32>::getDefaultEps()) SWARNING << "Joint::intersectEnter: Near-zero scale!" << std::endl; ia->setLine(Line(pos, dir), ia->getMaxDist()); ia->scale (length ); return ActionBase::Continue; }
NewActionTypes::ResultE Joint::intersectActorEnter( ActorBase::FunctorArgumentType &funcArg) { IntersectActor *pIA = dynamic_cast<IntersectActor *>( funcArg.getActor()); Matrix matrix = this->getMatrix(); Line transLine; Pnt3f pos; Vec3f dir; matrix.mult(this->getJointTransformation()); matrix.invert(); matrix.multFull(pIA->getRay().getPosition (), pos); matrix.mult (pIA->getRay().getDirection(), dir); transLine.setValue(pos, dir); pIA->beginEditState(); { pIA->setRay (transLine ); pIA->setScaleFactor(pIA->getScaleFactor() / dir.length()); } pIA->endEditState (); pIA->setupChildrenPriorities(); return NewActionTypes::Continue; }
//Similar to above function, but only returning boolean value for one polygon bool Ray::isIntersecting(Polygon * tempPg) { Matrix * paramMatrix; Vector params; Vector intersection; //create matrix paramMatrix = new Matrix (this->dir, tempPg->getEle(0) - tempPg->getEle(1), tempPg->getEle(0) - tempPg->getEle(2)); //calculate parameters paramMatrix->invert(); params = (*paramMatrix) * (tempPg->getEle(0) - this->pos); //check for intersection if (params.getEle(0) != 0) { //check whether it is behind the camera if (params.getEle(0) > 0) { //check whether the intersection is within the area of the polygon if (params.getEle(1) > 0 && params.getEle(2) > 0 && (params.getEle(1) + params.getEle(2)) <= 1) { return true; } //else not within polygon. } //else behind camera. } //else no intersection return false; }
Vec2f VRIntersect_computeTexel(VRIntersection& ins, NodeRecPtr node) { if (!ins.hit) return Vec2f(0,0); if (node == 0) return Vec2f(0,0); GeometryRefPtr geo = dynamic_cast<Geometry*>( node->getCore() ); if (geo == 0) return Vec2f(0,0); auto texcoords = geo->getTexCoords(); if (texcoords == 0) return Vec2f(0,0); TriangleIterator iter = geo->beginTriangles(); iter.seek( ins.triangle ); Matrix m = node->getToWorld(); m.invert(); Pnt3f local_pnt; m.mult(ins.point, local_pnt); Pnt3f p0 = iter.getPosition(0); Pnt3f p1 = iter.getPosition(1); Pnt3f p2 = iter.getPosition(2); Vec3f cr = (p1 - p0).cross(p2 - p0); Vec3f n = cr; n.normalize(); float areaABC = n.dot(cr); float areaPBC = n.dot((p1 - local_pnt).cross(p2 - local_pnt)); float areaPCA = n.dot((p2 - local_pnt).cross(p0 - local_pnt)); float a = areaPBC / areaABC; float b = areaPCA / areaABC; float c = 1.0f - a - b; return iter.getTexCoords(0) * a + iter.getTexCoords(1) * b + iter.getTexCoords(2) * c; }
void Particles::setScale(gmtl::Vec3f scale) { float maxScale; Vec3f position, osgScale; Quaternion orientation, scaleOrientation; beginEditCP(particleTrans); Matrix mOrig = particleTrans->getMatrix(); endEditCP(particleTrans); Matrix mNew = mOrig; mNew.getTransform(position, orientation, osgScale, scaleOrientation); osgScale = Vec3f(scale[0], scale[1], scale[2]); mNew.setTransform(position, orientation, osgScale, scaleOrientation); beginEditCP(particleTrans, Transform::MatrixFieldMask); particleTrans->setMatrix(mNew); endEditCP(particleTrans, Transform::MatrixFieldMask); mOrig.invert(); // mNew.multLeft(mOrig); mNew.mult(mOrig); beginEditCP(particleTransNode); DynamicVolume &v = particleTransNode->getVolume(false); v.transform(mNew); endEditCP(particleTransNode); } // setScale
Matrix osg::computeEyeToLocal(const Matrix& modelview,const NodePath& nodePath, bool ignoreCameras) { Matrix matrix; matrix.invert(modelview); TransformVisitor tv(matrix,TransformVisitor::WORLD_TO_LOCAL,ignoreCameras); tv.accumulate(nodePath); return matrix; }
Vec3f local(Vec3f p) { if (csys) { C = csys->getWorldMatrix(); C.invert(); Pnt3f pL; C.mult(p,pL); return Vec3f(pL); } else return p; }
// Returns a pre-ref'd pointer to the inverse of this matrix, or zero // if the matrix can not be inverted Matrix* Matrix::getInvGJ() const { Matrix* m = nullptr; if (isSquare()) { m = new Matrix(*this); m->invert(); } return m; }
/** * This function checks the state and data of the Action to decide if it is in * a valid state. * To be in a valid state the Action must satisfy the following: * - Have a name * - Reference an animation that exists in the model * - If the Action is a movement action then the referenced animation must * have an overall translation that is non-zero. * * @param model The model that owns the action. The action need not be yet * added to the model. * * @return Returns true if the Action is in a valid state. */ bool ModelAction::valid( const ::Model & model ) const { if (name_.empty()) { //ERROR_MSG( "Invalid Action: of model '%s'\n" // " Action has no name\n", // model.resourceID().c_str()); return false; } int animationIndex = model.getAnimation( animation_ ); if (animationIndex == -1) { //ERROR_MSG( "Invalid Action: '%s' of model '%s'\n" // " Referenced animation '%s' not found\n", // name_.c_str(), // model.resourceID().c_str(), // animation_.c_str()); return false; } SmartPointer<ModelAnimation> modelAnimation = model.animations_[animationIndex]; SmartPointer<Moo::Animation> mooAnimation = modelAnimation->getMooAnim(); if (isMovement_) { Moo::ChannelBinder * channelBinder = mooAnimation->itinerantRoot(); Matrix firstFrameTransform; Matrix finalFrameTransform; channelBinder->channel()->result( 0, firstFrameTransform ); channelBinder->channel()->result( mooAnimation->totalTime(), finalFrameTransform ); finalFrameTransform.invert(); Matrix animationDisplacement; animationDisplacement.multiply( finalFrameTransform, firstFrameTransform ); if (almostZero(animationDisplacement.applyToOrigin().length())) { //ERROR_MSG( "Invalid Action: '%s' of model '%s'\n" // " Action is marked as 'isMovement' but animation\n" // " '%s' has no overall translation of itinerant\n" // " root bone '%s'\n", // name_.c_str(), // model.resourceID().c_str(), // animation_.c_str(), // channelBinder->channel()->identifier().c_str()); return false; } } return true; }
Polygon * Ray::trace(vector<Polygon*> * thePolygons = &allPolygons) { Polygon * nearestPg = new Polygon(); //create nullPolygon (inactive) Polygon * tempPg; Matrix * paramMatrix; //matrix from the dir-vector and two sides of the polygon creating its plane Vector params; //parameters for the line equation (alpha) and the plane equation Vector intersection; //the actual intersection precs shortestDis = 0; precs tempDis = 0; //loop through allPolygons for (int i=0; i < thePolygons->size(); i++) { //set pointer tempPg to the current polygon tempPg = (*thePolygons)[i]; //create matrix (dir, a-b, a-c) paramMatrix = new Matrix (this->dir, tempPg->getEle(0) - tempPg->getEle(1), tempPg->getEle(0) - tempPg->getEle(2)); //calculate parameters: (alpha, beta, gamma) = paramMatrix^-1 * (a - pos) paramMatrix->invert(); params = (*paramMatrix) * (tempPg->getEle(0) - this->pos); //check for intersection if (params.getEle(0) != 0) { //Perform several checks: //check interception with plane. If it is behind the camera, alpha is smaller or equal to zero if (params.getEle(0) > 0) { //check whether the intersection is within the area of the polygon using the calculated parameters for the plane equation - that is faster than the method Vector::isInPolygon(Polygon) uses. if (params.getEle(1) > 0 && params.getEle(2) > 0 && (params.getEle(1) + params.getEle(2)) <= 1) { //now calculate the intersection using the ray equation and the ray parameter intersection = (this->pos) + (this->dir) * params.getEle(0); //check distance to pos tempDis = (intersection - (this->pos)).getLength(); if (tempDis < shortestDis || shortestDis == 0) { shortestDis = tempDis; //All checks successful. Set nearestPg to this polygon nearestPg = tempPg; //intersection.print("New nearest intersection:"); //cout << "Polygon " << i << ": now new nearest polygon with distance = " << shortestDis << endl; } //else cout << "Polygon " << i << ": " << (tempDis-shortestDis) << " farther away than nearest." << endl; } //else cout << "Polygon " << i << ": not within polygon. Plane parameters: (" << params.getEle(1) << ", " << params.getEle(2) << ")" << endl; } //else cout << "Polygon " << i << ": behind camera. Ray parameter: " << params.getEle(0) << endl; } //else cout << "Polygon " << i << ": no intersection." << endl; } return nearestPg; }
/** * This is called when the mouse button is released. * * @param flags The flags which shift-key status etc. * @param point The coordinates of the mouse. */ /*afx_msg*/ void ChunkWatchControl::OnLButtonUp(UINT /*flags*/, CPoint point) { getDrawConstants(); float x, z; if (screenToWorld(point, &x, &z)) { // Find the height at this point float fheight = TerrainUtils::heightAtPos(x, z, true); float y = fheight + Options::getOptionInt( "graphics/farclip", 500 )/10.0f; // Set the view matrix to the new world coords and preserve the // current orientation: Matrix view = WorldEditorCamera::instance().currentCamera().view(); view.invert(); view.translation(Vector3(x, y, z)); view.invert(); WorldEditorCamera::instance().currentCamera().view(view); } }
void VRSnappingEngine::update() { for (auto dev : VRSetupManager::getCurrent()->getDevices()) { // get dragged objects VRTransformPtr obj = dev.second->getDraggedObject(); VRTransformPtr 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]); bool lastEvent = event->snap; event->snap = 0; 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, 1); 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, 1); } } obj->setWorldMatrix(m); if (lastEvent != event->snap) { if (event->snap) snapSignal->trigger<EventSnap>(event); else if (obj == event->o1) snapSignal->trigger<EventSnap>(event); } } // update geo if (!hintGeo->isVisible()) return; }
/** * This method overrides the base class' implementation to return the * appropriate end points for this kind of link, using the start item * and the end point. * * @param s Return parameter for the start point position. * @param index Return parameter for the end point position. * @param absoluteCoords True to use absolute coordinates instead of local. * @return True if successful, false otherwise. */ /*virtual*/ bool EditorChunkPointLink::getEndPoints( Vector3 &s, Vector3 &e, bool absoluteCoords ) const { EditorChunkItem *start = (EditorChunkItem *)startItem().getObject(); // Maybe it's still loading... if ( start == NULL || start->chunk() == NULL) { return false; } Vector3 lStartPt = start->edTransform().applyToOrigin(); s = start->chunk()->transform().applyPoint( lStartPt ); e = endPoint_; // Get the start height, and check if it's in the ground bool foundHeight; float sh = heightAtPos(s.x, s.y + NEXT_HEIGHT_SAMPLE, s.z, &foundHeight); float sd = s.y - sh; if (!foundHeight) sd = 0.0f; bool inAir = fabs(sd) > AIR_THRESHOLD; if ( !inAir ) { // It's in the ground, get height at the middle and interpolate it to // the end using the start height. Vector3 mid = (e - s) / 2.0f + s; float mh = heightAtPos(mid.x, mid.y + NEXT_HEIGHT_SAMPLE, mid.z); float h = (mh-sh) * 2.0f + sh; if ( h > e.y ) { // It's not in the air, and the terrain occluding the link, so // make the end point as high as the terrain at that position. float oldLength = ( e - s ).length(); e.y = h; // Preserve the length Vector3 dir = ( e - s ); dir.normalise(); e = dir * oldLength + s; } } if (!absoluteCoords) { Matrix m = outsideChunk()->transform(); m.invert(); s = m.applyPoint(s); e = m.applyPoint(e); } return true; }
void Camera::getViewing(Matrix &result, UInt32 OSG_CHECK_ARG(width ), UInt32 OSG_CHECK_ARG(height)) { if (getBeacon() == NULL) { SWARNING << "Camera::setup: no beacon!" << std::endl; return; } getBeacon()->getToWorld(result); result.invert(); }
Vector SceneNode::MousePicking(int x, int y) { Matrix projMatrix = g_Camera.getProjectionMatrix(); projMatrix.invert(); float mouseXnorm = (2.0f * ((float)x) / g_WindowWidth) - 1.0f; float mouseYnorm = (2.0f * (float)y / g_WindowHeight) - 1.0f; m_lastMouseX = mouseXnorm; m_lastMouseY = mouseYnorm; mouseYnorm = -mouseYnorm; Vector ray(mouseXnorm, mouseYnorm, 1); ray = projMatrix * ray; ray.normalize(); Matrix inverseViewM = g_Camera.getViewMatrix(); inverseViewM.invert(); //Code-Block von Max Vector directionVec = inverseViewM.transformVec3x3(ray); return directionVec; }
Matrix Matrix::inverted() const { Matrix inv = *this; bool ok = inv.invert(); if (ok) { return inv; } else { Logger::error("inverting singular matrix (determinant == 0)", __FILE__, __LINE__); return Matrix::ZERO; } }
Action::ResultE transformEnter(CNodePtr& node, Action * action) { IntersectAction * ia = dynamic_cast<IntersectAction*>(action); NodePtr n( node ); Transform* core = dynamic_cast<Transform*>(get_pointer(n->getCore())); Matrix m = core->getMatrix(); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(ia->getLine().getPosition (), pos); m.mult (ia->getLine().getDirection(), dir); ia->setLine( Line( pos, dir ), ia->getMaxDist() ); return Action::Continue; }
void rayPickerManager::SetPickedBody (dNewtonBody* const body, const Vec4& handle) { dNewton::ScopeLock scopelock (&m_lock); m_pickedBody = body; if (m_pickedBody) { Matrix matrix; if (m_pickedBody->GetType() == dNewtonBody::m_dynamic) { matrix.invert(((newtonDynamicBody*) body)->GetMatrix()); } else { dAssert (0); } m_localpHandlePoint = handle * matrix; m_globalTarget = handle; } }
int SensorPolar2D::backProject(double data[2]) { Matrix xh(3, 1); xh(0,0) = data[0]; xh(1,0) = data[1]; xh(2,0) = 1.0; Matrix PoseInv = getTransformation(); PoseInv.invert(); xh = PoseInv * xh; double phi = atan2(xh(1,0), xh(0,0)); // ensure angle to lie in valid bounds if(phi<=_phiLowerBound) return -1; if(phi>=_phiUpperBound) return -1; return round((phi-_phiMin) /_angularRes); }
void ShaderShadowMapEngine::calcPointLightMatrices( Matrix &matWorldToLight, Matrix &matEyeToLight, const PointLight *pointL, const Matrix &matEyeToWorld) { if(pointL->getBeacon() != NULL) pointL->getBeacon()->getToWorld(matWorldToLight); Matrix matLightPos; matLightPos .setTranslate(pointL->getPosition()); matWorldToLight.mult (matLightPos ); matWorldToLight.invert ( ); matEyeToLight = matWorldToLight; matEyeToLight.mult(matEyeToWorld); }
bool Rocket::Straw::touchEvent(Touch::TouchEvent evt, int x, int y, unsigned int contactIndex) { Project::Element::touchEvent(evt, x, y, contactIndex); switch(evt) { case Touch::TOUCH_PRESS: { Rocket *rocket = (Rocket*)_project; MyNode *node = getNode(); if(rocket->getTouchNode() == node) { Vector3 trans = rocket->getTouchPoint() - node->getTranslationWorld(); Matrix straw = node->getWorldMatrix(), strawInv; straw.invert(&strawInv); strawInv.transformVector(&trans); float scale = ((rocket->_strawLength/2 - trans.z) / rocket->_strawLength) * node->getScaleZ(); node->setScaleZ(scale); rocket->_strawLength = rocket->_originalStrawLength * scale; } } } }
void Particles::setPosition(Vec3f pos) { Matrix mOrig = particleTrans->getMatrix(); Matrix mNew = mOrig; mNew.setTranslate(pos); beginEditCP(particleTrans, Transform::MatrixFieldMask); particleTrans->setMatrix(mNew); endEditCP(particleTrans, Transform::MatrixFieldMask); mOrig.invert(); // mNew.multLeft(mOrig); mNew.mult(mOrig); beginEditCP(particleTransNode); DynamicVolume &v = particleTransNode->getVolume(false); v.transform(mNew); endEditCP(particleTransNode); } // setPosition
void SensorPolar2D::backProject(Matrix* M, int* indices, Matrix* T) { Timer t; Matrix PoseInv = getTransformation(); PoseInv.invert(); if(T) PoseInv *= *T; Matrix coords2D = Matrix::multiply(PoseInv, *M, false, true); const double angularResInv = 1.0 / _angularRes; for(unsigned int i=0; i<M->getRows(); i++) { const double phi = atan2(coords2D(1,i), coords2D(0,i)); if(phi<=_phiLowerBound) indices[i] = -1; else if(phi>=_phiUpperBound) indices[i] = -1; else indices[i] = round((phi-_phiMin) * angularResInv); } }
/*! Calculates \a matWorldToLight and \a matEyeToLight for a directional light \a dirL and inverse viewing matrix \a matEyeToWorld. */ void ShaderShadowMapEngine::calcDirectionalLightMatrices( Matrix &matWorldToLight, Matrix &matEyeToLight, const DirectionalLight *dirL, const Matrix &matEyeToWorld) { if(dirL->getBeacon() != NULL) dirL->getBeacon()->getToWorld(matWorldToLight); Quaternion rotLightDir (Vec3f(0.f, 0.f, 1.f), dirL->getDirection()); Matrix matLightDir; matLightDir.setRotate(rotLightDir); matWorldToLight.mult (matLightDir); matWorldToLight.invert( ); matEyeToLight = matWorldToLight; matEyeToLight.mult(matEyeToWorld); }
bool Form::projectPoint(int x, int y, Vector3* point) { Scene* scene = _node->getScene(); GP_ASSERT(scene); Camera* camera = scene->getActiveCamera(); if (camera) { // Get info about the form's position. Matrix m = _node->getMatrix(); Vector3 min(0, 0, 0); m.transformPoint(&min); // Unproject point into world space. Ray ray; camera->pickRay(Game::getInstance()->getViewport(), x, y, &ray); // Find the quad's plane. We know its normal is the quad's forward vector. Vector3 normal = _node->getForwardVectorWorld(); // To get the plane's distance from the origin, we'll find the distance from the plane defined // by the quad's forward vector and one of its points to the plane defined by the same vector and the origin. const float& a = normal.x; const float& b = normal.y; const float& c = normal.z; const float d = -(a*min.x) - (b*min.y) - (c*min.z); const float distance = abs(d) / sqrt(a*a + b*b + c*c); Plane plane(normal, -distance); // Check for collision with plane. float collisionDistance = ray.intersects(plane); if (collisionDistance != Ray::INTERSECTS_NONE) { // Multiply the ray's direction vector by collision distance and add that to the ray's origin. point->set(ray.getOrigin() + collisionDistance*ray.getDirection()); // Project this point into the plane. m.invert(); m.transformPoint(point); return true; } } return false; }
bool UIRectangleMouseTransformFunctor::viewportToRenderingSurface(const Pnt2f& ViewportPoint, const Viewport* TheViewport, Pnt2f& Result) const { //Get Viewport to View Space line Line l; if( !TheViewport->getCamera()->calcViewRay( l, ViewportPoint.x(), ViewportPoint.y(), *TheViewport ) ) { return false; } //Transform Line to UIRectangle Space Matrix m ; getParent()->accumulateMatrix(m); m.invert(); Pnt3f pos; Vec3f dir; m.multFull(l.getPosition (), pos); m.mult (l.getDirection(), dir); l.setValue(pos, dir); //ia->scale(dir.length()); //Intersect the Line with the UIRectangle quad Real32 t; if(!intersectLineRect(l,getParent()->getPoint(), getParent()->getPoint() + Vec3f(getParent()->getWidth(),0,0), getParent()->getPoint() + Vec3f(getParent()->getWidth(),getParent()->getHeight(),0), getParent()->getPoint() + Vec3f(0,getParent()->getHeight(),0) ,t)) { return false; } //Return the point on the quad of the intersection if there was one Result.setValues(l.getPosition().x() + t*l.getDirection().x() - getParent()->getPoint().x(), getParent()->getHeight() - l.getPosition().y() - t*l.getDirection().y() + getParent()->getPoint().y()); return true; }