def on_grab(self, states): grabbing = [] # Check both hands for hand in self.hands: thumb_position = hand.thumb.position # Check index and middle fingers as well for finger in (hand.index, hand.middle): # If thumb's and the finger's distance # is beyond the grabbing-release-range if not distance(thumb_position, finger.position) < GRAB_RELEASE_DISTANCE: # Set state and stop checking the other finger hand.set_states(grabbed=False) break # If both fingers are in the range of grabbing-release-range else: # Set state, and collect hand in the grabbing-hands list grabbing.append(hand) hand.set_states(grabbed=True) # If both hands are grabbing try: # Get hands separately left_hand, right_hand = grabbing # Color thumbs and hide other fingers, so it won't confuse the user left_hand.thumb.color = right_hand.thumb.color = COLOR_ROTATE_PINCH_OKAY left_hand.hide_all('thumb') right_hand.hide_all('thumb') # Get the thumb positionS ltp = left_hand.thumb.position rtp = right_hand.thumb.position # Get essentaial informations about the current state curr_grab_vector = Vec3.from_line(ltp[0], ltp[1], ltp[2], rtp[0], rtp[1], rtp[2]) curr_grab_length = curr_grab_vector.length curr_grab_vector = curr_grab_vector.normalize() # If this grab is part of a previous grab-cycle try: rotation = Matrix( tuple( rotation_matrix_from_vectors( self._dual_grab_vector, curr_grab_vector))).to_euler() rotation = -rotation[0], -rotation[1], -rotation[2] # Rotate parent object of all vertices #self.vertex_origo.applyRotation(rotation) self._armature_control.applyRotation(rotation) self._armature.applyRotation(rotation) #self._geometry.applyRotation(rotation) # Scale the parent object try: scale = 1 / (self._dual_grab_length / curr_grab_length) self._zoomed_pick_distance *= scale self.vertex_origo.worldScale = \ [old*new for old, new in zip(self.vertex_origo.worldScale, repeat(scale))] except ZeroDivisionError: pass # Update geometry self.surface.update() # If this grab is a new grab-cycle except TypeError: pass # Store current values as previous ones for the next cycle self._dual_grab_vector = curr_grab_vector self._dual_grab_length = curr_grab_length self._is_dual_grabbed = True except ValueError: # If only one hand is grabbing try: hand = grabbing[0] curr = tuple(hand.thumb.position) prev = self._grab_position hand.hide_all('thumb') hand.thumb.color = COLOR_GRAB_MOVE_OKAY # If this is a mistaken single grab (one hand released accidentaly) if self._is_dual_grabbed: return # If this is the first cycle of a single grab if not self._is_grabbed: self._is_grabbed = True self._grab_start = { id: tuple(v.localPosition) for id, v in self.surface.selected() } # If this grab is part of a previous grab-cycle try: # Calculate vector between previous # and current thumb positions movement = Vec3.from_line(prev[0], prev[1], prev[2], curr[0], curr[1], curr[2]) # Move all selected vertices for _, vertex in self.surface.selected(): vertex.applyMovement(movement) # Update geometry self.surface.update() # If this grab is starting a new grab-cycle except TypeError: pass # Store current position as previous one for the next cycle self._grab_position = curr # If none of the hands are grabbing except IndexError: if not self._is_picked: self.hands.show_all() # If this release is the end of a grab cycle if self._is_grabbed: start = self._grab_start stop = { id: tuple(v.localPosition) for id, v in self.surface.selected() } # Create events @History.event def move_back_vertices(direction, prefix): surface = self.surface # Move all selected vertices for identifier, position in start.items(): # If opponent user is not using them if not surface.is_locked(identifier): surface[identifier].localPosition = position # Update geometry surface.update() self.text.write( '{PREFIX}Vertices moved to position'.format( PREFIX=prefix)) @History.event def move_vertices(direction, prefix): surface = self.surface # Move all selected vertices for identifier, position in stop.items(): # If opponent user is not using them if not surface.is_locked(identifier): surface[identifier].localPosition = position # Update geometry surface.update() self.text.write( '{PREFIX}Vertices moved to position'.format( PREFIX=prefix)) # Save events self._history.push(undo=move_back_vertices, redo=move_vertices) self._grab_position = \ self._dual_grab_vector = \ self._dual_grab_length = None self._is_grabbed = \ self._is_dual_grabbed = False
def on_grab(self, states): grabbing = [] # Check both hands for hand in self.hands: thumb_position = hand.thumb.position # Check index and middle fingers as well for finger in (hand.index, hand.middle): # If thumb's and the finger's distance # is beyond the grabbing-release-range if not distance(thumb_position, finger.position) < GRAB_RELEASE_DISTANCE: # Set state and stop checking the other finger hand.set_states(grabbed=False) break # If both fingers are in the range of grabbing-release-range else: # Set state, and collect hand in the grabbing-hands list grabbing.append(hand) hand.set_states(grabbed=True) # If both hands are grabbing try: # Get hands separately left_hand, right_hand = grabbing # Color thumbs and hide other fingers, so it won't confuse the user left_hand.thumb.color = right_hand.thumb.color = COLOR_ROTATE_PINCH_OKAY left_hand.hide_all('thumb') right_hand.hide_all('thumb') # Get the thumb positionS ltp = left_hand.thumb.position rtp = right_hand.thumb.position # Get essentaial informations about the current state curr_grab_vector = Vec3.from_line(ltp[0], ltp[1], ltp[2], rtp[0], rtp[1], rtp[2]) curr_grab_length = curr_grab_vector.length curr_grab_vector = curr_grab_vector.normalize() # If this grab is part of a previous grab-cycle try: rotation = Matrix(tuple(rotation_matrix_from_vectors(self._dual_grab_vector, curr_grab_vector))).to_euler() rotation = -rotation[0], -rotation[1], -rotation[2] # Rotate parent object of all vertices #self.vertex_origo.applyRotation(rotation) self._armature_control.applyRotation(rotation) self._armature.applyRotation(rotation) #self._geometry.applyRotation(rotation) # Scale the parent object try: scale = 1/(self._dual_grab_length/curr_grab_length) self._zoomed_pick_distance *= scale self.vertex_origo.worldScale = \ [old*new for old, new in zip(self.vertex_origo.worldScale, repeat(scale))] except ZeroDivisionError: pass # Update geometry self.surface.update() # If this grab is a new grab-cycle except TypeError: pass # Store current values as previous ones for the next cycle self._dual_grab_vector = curr_grab_vector self._dual_grab_length = curr_grab_length self._is_dual_grabbed = True except ValueError: # If only one hand is grabbing try: hand = grabbing[0] curr = tuple(hand.thumb.position) prev = self._grab_position hand.hide_all('thumb') hand.thumb.color = COLOR_GRAB_MOVE_OKAY # If this is a mistaken single grab (one hand released accidentaly) if self._is_dual_grabbed: return # If this is the first cycle of a single grab if not self._is_grabbed: self._is_grabbed = True self._grab_start = {id: tuple(v.localPosition) for id, v in self.surface.selected()} # If this grab is part of a previous grab-cycle try: # Calculate vector between previous # and current thumb positions movement = Vec3.from_line(prev[0], prev[1], prev[2], curr[0], curr[1], curr[2]) # Move all selected vertices for _, vertex in self.surface.selected(): vertex.applyMovement(movement) # Update geometry self.surface.update() # If this grab is starting a new grab-cycle except TypeError: pass # Store current position as previous one for the next cycle self._grab_position = curr # If none of the hands are grabbing except IndexError: if not self._is_picked: self.hands.show_all() # If this release is the end of a grab cycle if self._is_grabbed: start = self._grab_start stop = {id: tuple(v.localPosition) for id, v in self.surface.selected()} # Create events @History.event def move_back_vertices(direction, prefix): surface = self.surface # Move all selected vertices for identifier, position in start.items(): # If opponent user is not using them if not surface.is_locked(identifier): surface[identifier].localPosition = position # Update geometry surface.update() self.text.write('{PREFIX}Vertices moved to position'.format(PREFIX=prefix)) @History.event def move_vertices(direction, prefix): surface = self.surface # Move all selected vertices for identifier, position in stop.items(): # If opponent user is not using them if not surface.is_locked(identifier): surface[identifier].localPosition = position # Update geometry surface.update() self.text.write('{PREFIX}Vertices moved to position'.format(PREFIX=prefix)) # Save events self._history.push(undo=move_back_vertices, redo=move_vertices) self._grab_position = \ self._dual_grab_vector = \ self._dual_grab_length = None self._is_grabbed = \ self._is_dual_grabbed = False
## (at your option) any later version. ## ## ## ## This program is distributed in the hope that it will be useful, but ## ## WITHOUT ANY WARRANTY; without even the implied warranty of ## ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. ## ## See the GNU General Public License for more details. ## ## ## ## You should have received a copy of the GNU General Public License ## ## along with this program, most likely a file in the root directory, ## ## called 'LICENSE'. If not, see <http://www.gnu.org/licenses>. ## ## ## ######################################################################## INFO ## from linmath import Vec3, Mat4x4 v1 = Vec3(1, 2, 3) v2 = Vec3(4, 5, 6) print(v1) print(v2) print(v1 + v2) print(*v1) print(*v2) print(tuple(v1), tuple(v2)) for f in v1 + v2: print(f) print(v1, v1.normalize()) print(Vec3.from_line(*(tuple(v1) + tuple(v2))).normalize())
v1 = Vec3(1, 2, 3) v2 = Vec3(4, 5, 6) print(v1) print(v2) print(v1 + v2) print(*v1) print(*v2) print(tuple(v1), tuple(v2)) for f in v1 + v2: print(f) print(v1, v1.normalize()) print(Vec3.from_line(*(tuple(v1) + tuple(v2))).normalize()) print(v1.x, v1.y, v1.z) print(Vec3.from_line(x1=1, y2=1).normalize().length) print(v1.length) print(v1.reflect(v2).normalize() * 2) #------------------------------------------------------------------------------# print('-'*80) m1 = Mat4x4((-2, 5, 88, 0), (56, 17, 9, -1), (-1, -1, 78, 9), ( 7, 3, 8, 1))