From 8b5cd5323b5b2cb04fd6bda443f2be52e5602de2 Mon Sep 17 00:00:00 2001 From: Quinn Date: Wed, 28 Aug 2024 23:20:48 -0400 Subject: [PATCH] updated the animaiton tool readme --- tools/animation-tools/README.md | 51 +++++++++++++++++- tools/animation-tools/UI.py | 10 ++-- .../animation-tools/images/open-animator.png | Bin 0 -> 12028 bytes 3 files changed, 55 insertions(+), 6 deletions(-) create mode 100644 tools/animation-tools/images/open-animator.png diff --git a/tools/animation-tools/README.md b/tools/animation-tools/README.md index 789b193..88ade79 100644 --- a/tools/animation-tools/README.md +++ b/tools/animation-tools/README.md @@ -28,4 +28,53 @@ source venv/Scripts/activate 4. Run ``` pip install -r requirements.txt -``` \ No newline at end of file +``` + +# How to Use +The animation tool was made to allow anyone to easily create animaitons without much practice. You can create a sequence of frames in the studio, export them and then copy them over to the firmware + +## Creating a Frame +When you first run the program the window will look like this: + +![Startup](images\open-animator.png) + +### Rotating the view +Press and hold the middle mouse button and move around the mouse to rotate the view. + +### Changing Cube Colors +Click on a cube to select it. Selected cubes will be highlighted in red. All selected cubes will be set to the current color picker color. You can deselect a block by clicking on it again. + +The color picker consists of 3 sliders on the left of the screen. A preview of the color is in a small box underneath the sliders. Move the sliders around to change colors. + +### Fill Options +Fill options tell the board how to color cubes which are set to black in the animator. There are four options: + +#### No Fill +Cubes that are set to black will be off + +#### Closest Color +Cubes that are set to black will become the same color as their closest colored neighbor + +#### Linear +Cubes that are set to black will become a distance weighted average of all of the colored cubes + +#### Square +Same as linear, but the distance weighting is squared. This means a cube that's twice as far away will have only 1/4 the effect. + +### Fade options +The fade options tell the board how to transition between frames + +#### Snap +The colors will remain constant until the delay time for the current frame has passed. At that point, the frame will immediatly switch to the next frame. + +#### Fade +The colors will linearly transition from one frame to the next. This often results in very interesting colors and patterns emerging. + +### Creating more than one frame +An animation isn't really an animation with only one frame. You can add more frames to your animation with the "Next Frame" button. This will create a new frame for you to edit. You'll also notice the frame counter above the next frame button will go up. That shows you the current frame number that you're editing. You can view previous frames but clicking on the last frame button. + +### Exporting your Animation +Now that you're done creating your lovely animation you can export it! Click the save button and C++ code will automatically be generated which describes all of the frames you just created. The code is saved in output.txt in the animation-tools folder. How to use that code is beyond the scope of this README. Reach out to Quinn for more instruction. + +# Future features +Eventually I would like to add the ability to send the animations directly to the board without having to mess with the firmware at all. This will take a pretty big rework though. \ No newline at end of file diff --git a/tools/animation-tools/UI.py b/tools/animation-tools/UI.py index 8426aab..791d1fb 100644 --- a/tools/animation-tools/UI.py +++ b/tools/animation-tools/UI.py @@ -118,8 +118,8 @@ class AnimatorUI: self.sceneManager: SceneManager = SceneManager(window, self.colorPicker) self.save_button: Button = Button(self.window, *self.rel2abs(5, 90, 10, 10), text="Save",onClick=self.sceneManager.save_frame_to_file) - self.next_frame_button: Button = Button(self.window, *self.rel2abs(75, 90, 25, 5), text="Next Frame",onClick=self._next_scene) - self.last_frame_button: Button = Button(self.window, *self.rel2abs(50, 90, 25, 5), text="last Frame",onClick=self._last_scene) + self.next_frame_button: Button = Button(self.window, *self.rel2abs(75, 95, 25, 5), text="Next Frame",onClick=self._next_scene) + self.last_frame_button: Button = Button(self.window, *self.rel2abs(50, 95, 25, 5), text="last Frame",onClick=self._last_scene) self.trackMouseMotion: bool = False self.fill_dropdown: Dropdown = Dropdown(self.window, *self.rel2abs(30, 0, 40, 5), name="Fill Type", @@ -135,7 +135,7 @@ class AnimatorUI: # Make a frame counter as a button but make it not look like a button default_color=(150,150,150) - self.frame_counter_text: Button = Button(self.window, *self.rel2abs(15, 90, 10, 10), text="0", inactiveColour=default_color, hoverColour=default_color, pressedColour=default_color) + self.frame_counter_text: Button = Button(self.window, *self.rel2abs(70, 85, 10, 10), text="0", inactiveColour=default_color, hoverColour=default_color, pressedColour=default_color) def rel2abs(self, x: float, y: float, width: float, height: float) -> tuple[int,int,int,int]: scr_wdt, scr_hgt = self.window.get_size() @@ -161,8 +161,8 @@ class AnimatorUI: elif self.trackMouseMotion and game_event.type == pygame.MOUSEMOTION: mouseMovement = pygame.mouse.get_rel() current_scene = self.sceneManager.get_current_scene() - current_scene.euler_angles[0] -= mouseMovement[1] - current_scene.euler_angles[1] -= mouseMovement[0] + current_scene.scene.euler_angles[0] -= mouseMovement[1] + current_scene.scene.euler_angles[1] -= mouseMovement[0] def draw(self): if self.updateOptions: diff --git a/tools/animation-tools/images/open-animator.png b/tools/animation-tools/images/open-animator.png new file mode 100644 index 0000000000000000000000000000000000000000..27b0a194a594e45b61b62b2c080b3e25366004c5 GIT binary patch literal 12028 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 Ls>l>c8NL4>{bRY- literal 0 HcmV?d00001