static bool F_Hit_Translate_Handle_At_Center( APlaceable* o, const EdSceneViewport& viewport ) { const Ray3D eyeRay = GetEyeRay(viewport); const FLOAT dist = eyeRay.Distance( o->GetOrigin() ); const FLOAT pickingDist = F_Get_Translate_Handle_Radius( eyeRay.origin, o->GetOrigin() ); return dist < pickingDist; }
void CCamera::GetEyeRays(std::vector<Ray>& rays, std::vector<glm::vec2>& samples, uint numRays) { rays.clear(); samples.clear(); glm::vec2 range(m_Width, m_Height); GetStratifiedSamples2D(samples, range, numRays); for(uint i = 0; i < samples.size(); ++i) { rays.push_back(GetEyeRay(samples[i].x, samples[i].y)); } }
inline Vec3D F_Get_Translation_Gizmo_Pick_Point_In_World_Space( const EdSceneViewport& viewport , const Vec2D& xyNDC, const APlaceable* pEntity , const EGizmoAxis eAxis ) { Ray3D gizmoAxisWS = GetGizmoAxisInWorldSpace( pEntity, eAxis ); Ray3D eyeRay = GetEyeRay( viewport, xyNDC ); Vec3D pointOnGizmo, pointOnEyeRay; ELineStatus eLineStatus = IntersectLines( gizmoAxisWS, eyeRay, pointOnGizmo, pointOnEyeRay ); //Assert( eLineStatus != Lines_Parallel ); if( eLineStatus != Lines_Parallel ) { return pointOnGizmo; } return gizmoAxisWS.origin + gizmoAxisWS.direction * GetTranslateGizmoAxisScale( eyeRay.origin, pEntity->GetOrigin() ); }
static void F_Draw_Uniform_Scale_Handle( const EdDrawContext& context, const APlaceable* entity, const FColor* forceColor = nil ) { const EdSceneViewport& viewport = context.viewport; BatchRenderer & batchRenderer = context.renderer; //AHitTesting & hitTesting = context.hitTesting; const Vec3D objPos = entity->GetOrigin(); Ray3D eyeRay = GetEyeRay(viewport); Plane3D gizmoPlane( (eyeRay.origin - objPos).GetNormalized(), objPos ); FLOAT f; gizmoPlane.RayIntersection( eyeRay.origin, eyeRay.direction, f ); Vec3D pickPoint = eyeRay.origin + eyeRay.direction * f; const FColor& color = forceColor ? *forceColor : FColor::YELLOW; batchRenderer.DrawDashedLine( objPos, pickPoint, 1.0f, color, color ); }
void EdGizmo::OnMouseMove( const EdSceneViewport& viewport, const SMouseMoveEvent& args ) { AHitProxy* pHitProxy = viewport.objAtCursor; const bool bHighlightObjects = true; if( bHighlightObjects ) { if( pHitProxy != nil ) { APlaceable* pPlaceable = pHitProxy->IsPlaceable(); m_hightlighted = pPlaceable; HGizmoAxis* pHGizmoAxis = SafeCast<HGizmoAxis>( pHitProxy ); if( pHGizmoAxis != nil ) { m_highlightedAxes = pHGizmoAxis->axis; } else { m_highlightedAxes = EGizmoAxis::GizmoAxis_None; } } else { m_hightlighted = nil; } } if( viewport.IsDraggingMouse() && m_selected != nil ) { // gizmo pick point, in screen space Vec2D pickPosNDC; PointToNDC( viewport, viewport.dragStartPosition.x(), viewport.dragStartPosition.y(), pickPosNDC ); //DBGOUT("pickPosNDC: %f, %f\n",pickPosNDC.x,pickPosNDC.y); Vec2D currPosNDC; PointToNDC( viewport, args.mouseX, args.mouseY, currPosNDC ); //DBGOUT("currPosNDC: %f, %f\n",currPosNDC.x,currPosNDC.y); // we need to convert screen space delta to world space movement Vec2D deltaNDC = currPosNDC - pickPosNDC; //dbgout << "delta=" << deltaNDC << dbgout.NewLine(); switch( m_currentMode ) { case EGizmoMode::Gizmo_Translate : if( m_currentAxis == GizmoAxis_None ) { return; } if( m_currentAxis == GizmoAxis_All ) { L_TranslateAll: const rxView& eye = viewport.GetView(); Ray3D pickRay = GetEyeRay( viewport, currPosNDC ); FLOAT prevDist = (m_oldState.translation - eye.origin).LengthSqr(); if( prevDist < VECTOR_EPSILON ) { return; } prevDist = mxSqrt(prevDist); Vec3D newEntityPos = eye.origin + pickRay.direction * prevDist; m_selected->SetOrigin( newEntityPos ); } else { Vec3D gizmoPickPos = F_Get_Translation_Gizmo_Pick_Point_In_World_Space( viewport, pickPosNDC, m_selected, m_currentAxis ); //Vec3D centerOfGizmo = m_selected->GetOrigin(); Vec3D pointOnGizmo = F_Get_Translation_Gizmo_Pick_Point_In_World_Space( viewport, currPosNDC, m_selected, m_currentAxis ); Vec3D translationDelta = pointOnGizmo - gizmoPickPos; const FLOAT MAX_TRANSLATION_DIST = 100.0f; translationDelta.Clamp(Vec3D(-MAX_TRANSLATION_DIST),Vec3D(MAX_TRANSLATION_DIST)); Vec3D newEntityPos = m_oldState.translation + translationDelta; m_selected->SetOrigin( newEntityPos ); } break; case EGizmoMode::Gizmo_Scale : if( m_currentAxis == GizmoAxis_All ) { goto L_TranslateAll; } else { //dbgout << "Scaling\n"; FLOAT mag = deltaNDC.LengthFast(); FLOAT newEntityScale = m_oldState.scaleFactor + mag * signf(deltaNDC.x); newEntityScale = maxf(newEntityScale,0.01f); m_selected->SetScale( newEntityScale ); } break; case EGizmoMode::Gizmo_Rotate : //if( m_currentAxis == GizmoAxis_None ) //{ // return false; //} if( m_currentAxis == GizmoAxis_All ) { goto L_TranslateAll; } else { //dbgout << "Rotating\n"; mxUNDONE; static FLOAT ROT_ARC_RADIUS = 1.0f; HOT_FLOAT(ROT_ARC_RADIUS); // starting point of rotation arc Vec3D vDownPt = ConvertScreenPointToVector( viewport, viewport.dragStartPosition.x(), viewport.dragStartPosition.y(), ROT_ARC_RADIUS ); // current point of rotation arc Vec3D vCurrPt = ConvertScreenPointToVector( viewport, args.mouseX, args.mouseY, ROT_ARC_RADIUS ); #if 0 Quat qRot = QuatFromBallPoints( vDownPt, vCurrPt ); qRot.Normalize(); #else Vec3D axis = Cross( vDownPt, vCurrPt ); axis.Normalize(); F4 angle = AngleBetween( vDownPt, vCurrPt ); Quat qRot( axis, angle ); qRot.Normalize(); #endif Quat q = qRot * m_oldState.orientation; q.Normalize(); m_selected->SetOrientation(q); } break; mxNO_SWITCH_DEFAULT; } } }
Ray CCamera::GetEyeRay(glm::vec2& pixel) { glm::vec2 range(m_Width, m_Height); pixel = GetUniformSample2D(range); return GetEyeRay(pixel.x, pixel.y); }
Ray CCamera::GetEyeRay() { glm::vec2 range(m_Width, m_Height); glm::vec2 s = GetUniformSample2D(range); return GetEyeRay(s.x, s.y); }