Grab the handle with the cursor's ray (origin, unit dir; root frame): its constraint is taken as it is now, and the point's offset from where the ray meets it. False if it isn't draggable.
| Type | Intent | Optional | Attributes | Name | ||
|---|---|---|---|---|---|---|
| class(DragHandle), | intent(inout) | :: | self | |||
| real(kind=wp), | intent(in) | :: | origin(3) |
the cursor's ray (root frame) |
||
| real(kind=wp), | intent(in) | :: | dir(3) |
the cursor's ray (root frame) |
logical function grab(self, origin, dir) result(ok) class(DragHandle), intent(inout) :: self real(wp), intent(in) :: origin(3), dir(3) !! the cursor's ray (root frame) real(wp) :: m(4,4), p(3), h(3), near, far, c(3) ok = .false. if (.not. self%draggable_) return m = self%world_matrix() p = self%handle_point() self%ref_point = p self%ref_axis = self%axis_ select case (self%constraint_) case (HANDLE_FREE) self%ref_axis = matmul(transpose(m(1:3, 1:3)), -dir) ! (facing the camera, now) case (HANDLE_RADIAL) if (norm2(p) > 0.0_wp) self%ref_axis = p / norm2(p) case (HANDLE_SPHERE) self%radius = norm2(p) self%far_side = .false. c = m(1:3, 4) if (ray_sphere(origin, dir, c, self%radius, near, far)) & ! (the side nearer the point) self%far_side = norm2(origin + far * dir - (matmul(m(1:3, 1:3), p) + c)) < & norm2(origin + near * dir - (matmul(m(1:3, 1:3), p) + c)) end select self%offset = 0.0_wp if (constrained(self, origin, dir, m, h)) self%offset = p - h self%dragged_ = .true. call self%show_state() ok = .true. end function grab