Package artofillusion

Source Code of artofillusion.MoveScaleRotateMeshTool

/* Copyright (C) 2006-2007 by Peter Eastman

   This program is free software; you can redistribute it and/or modify it under the
   terms of the GNU General Public License as published by the Free Software
   Foundation; either version 2 of the License, or (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. */

package artofillusion;

import artofillusion.ui.*;
import artofillusion.ui.Compound3DManipulator.*;
import artofillusion.math.*;
import artofillusion.object.*;

import java.awt.event.*;

import buoy.event.*;
import buoy.widget.*;

/**
* This editing tool presents as a compound interface for move, scale, and rotating parts of
* a mesh.
*/

public class MoveScaleRotateMeshTool extends MeshEditingTool
{
  private boolean dragInProgress;
  private Vec3 baseVertPos[];
  private UndoRecord undo;
  private final Compound3DManipulator manipulator;
  private boolean tooltipsEnabled, tooltipsAdded;

  private static BToolTip ROTATE_TIP = new BToolTip(Translate.text("moveScaleRotateMeshTool.rotateTipText"));
  private static BToolTip MOVE_TIP = new BToolTip(Translate.text("moveScaleRotateMeshTool.moveTipText"));
  private static BToolTip SCALE_TIP = new BToolTip(Translate.text("moveScaleRotateMeshTool.scaleTipText"));

  public MoveScaleRotateMeshTool(EditingWindow fr, MeshEditController controller)
  {
    super(fr, controller);
    initButton("moveScaleRotate");
    manipulator = new Compound3DManipulator();
    manipulator.addEventLink(HandlePressedEvent.class, this, "handlePressed");
    manipulator.addEventLink(HandleDraggedEvent.class, this, "handleDragged");
    manipulator.addEventLink(HandleReleasedEvent.class, this, "handleReleased");
  }

  public int whichClicks()
  {
    return ALL_CLICKS+HANDLE_CLICKS;
  }

  public boolean allowSelectionChanges()
  {
    return !dragInProgress;
  }

  public String getToolTipText()
  {
    return Translate.text("moveScaleRotateMeshTool.tipText");
  }

  public void drawOverlay(ViewerCanvas view)
  {
    BoundingBox selectionBounds = findSelectionBounds(view.getCamera());
    if (!dragInProgress && manipulator.getViewMode() == Compound3DManipulator.NPQ_MODE && selectionBounds != null)
    {
      // Calculate the axis directions.

      Vec3 avgNorm = new Vec3();
      int selection[] = controller.getSelectionDistance();
      Mesh mesh = (Mesh) controller.getObject().getObject();
      Vec3 normal[] = mesh.getNormals();
      for (int i = 0; i < selection.length; i++)
        if (selection[i] == 0)
          avgNorm.add(normal[i]);
      avgNorm.normalize();
      if (avgNorm.length2() == 0.0)
        avgNorm = Vec3.vx();
      Vec3 updir = Vec3.vx();
      if (Math.abs(updir.dot(avgNorm)) < 0.9)
        updir = avgNorm.cross(updir);
      else
        updir = avgNorm.cross(Vec3.vy());
      updir.normalize();
      manipulator.setNPQAxes(avgNorm, updir, avgNorm.cross(updir));
    }
    manipulator.draw(view, selectionBounds);
    if (!dragInProgress)
    {
      if (selectionBounds != null)
        theWindow.setHelpText(Translate.text("moveScaleRotateMeshTool.helpText"));
      else
        theWindow.setHelpText(Translate.text("moveScaleRotateMeshTool.errorText"));
    }
  }

  public void mousePressed(WidgetMouseEvent e, ViewerCanvas view)
  {
    BoundingBox selectionBounds = findSelectionBounds(view.getCamera());
    dragInProgress = false;
    if (selectionBounds != null)
      dragInProgress = manipulator.mousePressed(e, view, selectionBounds);
  }

  public void mousePressedOnHandle(WidgetMouseEvent e, ViewerCanvas view, int obj, int handle)
  {
    Mesh mesh = (Mesh) controller.getObject().getObject();
    Vec3 vert = mesh.getVertices()[handle].r;
    BoundingBox selectionBounds = findSelectionBounds(view.getCamera());
    if (selectionBounds != null)
    {
      manipulator.mousePressedOnHandle(e, view, selectionBounds, vert);
      dragInProgress = true;
    }
  }

  public void mouseDragged(WidgetMouseEvent e, ViewerCanvas view)
  {
    manipulator.mouseDragged(e, view);
  }

  public void mouseReleased(WidgetMouseEvent e, ViewerCanvas view)
  {
    manipulator.mouseReleased(e, view);
  }

  protected void handlePressed(HandlePressedEvent ev)
  {
    Mesh mesh = (Mesh) controller.getObject().getObject();
    baseVertPos = mesh.getVertexPositions();
  }

  protected void handleDragged(HandleDraggedEvent ev)
  {
    if (undo == null)
    {
      Mesh mesh = (Mesh) controller.getObject().getObject();
      undo = new UndoRecord(theWindow, false, UndoRecord.COPY_VERTEX_POSITIONS, new Object [] {mesh, mesh.getVertexPositions()});
    }

    transformMesh(ev.getTransform());
    theWindow.updateImage();
    if (ev.getHandleType() == Compound3DManipulator.MOVE)
    {
      Vec3 drag = ev.getTransform().times(new Vec3());
      theWindow.setHelpText(Translate.text("reshapeMeshTool.dragText",
          Math.round(drag.x*1e5)/1e5+", "+Math.round(drag.y*1e5)/1e5+", "+Math.round(drag.z*1e5)/1e5));
    }
    else if (ev.getHandleType() == Compound3DManipulator.ROTATE)
      theWindow.setHelpText(Translate.text("rotateMeshTool.dragText", Double.toString(Math.round(ev.getRotationAngle()*1e5*180.0/Math.PI)/1e5)));
    else if (ev.getAxis() == Compound3DManipulator.UV && !ev.getMouseEvent().isShiftDown())
      theWindow.setHelpText(Translate.text("scaleMeshTool.dragText", Math.round(ev.getPrimaryScale()*1e5)/1e5+", "+Math.round(ev.getSecondaryScale()*1e5)/1e5));
    else
      theWindow.setHelpText(Translate.text("scaleMeshTool.dragText", Double.toString(Math.round(ev.getPrimaryScale()*1e5)/1e5)));
  }

  protected void handleReleased(HandleReleasedEvent ev)
  {
    if (undo != null)
      theWindow.setUndoRecord(undo);
    theWindow.updateImage();
    undo = null;
    baseVertPos = null;
    dragInProgress = false;
  }

  /**
   * Apply a transformation to the mesh.
   */

  private void transformMesh(Mat4 transform)
  {
    int selected[] = controller.getSelectionDistance();
    Vec3 v[] = new Vec3 [baseVertPos.length];
    for (int i = 0; i < v.length; i++)
      {
        if (selected[i] == 0)
          v[i] = transform.times(baseVertPos[i]).minus(baseVertPos[i]);
        else
          v[i] = new Vec3();
      }
    if (theFrame instanceof MeshEditorWindow)
      ((MeshEditorWindow) theFrame).adjustDeltas(v);
    for (int i = 0; i < v.length; i++)
      v[i].add(baseVertPos[i]);
    Mesh mesh = (Mesh) controller.getObject().getObject();
    mesh.setVertexPositions(v);
    controller.objectChanged();
  }

  public void keyPressed(KeyPressedEvent e, ViewerCanvas view)
  {
    if (e.getKeyCode() == KeyEvent.VK_W)
    {
      // Change the axis mode.

      ViewMode mode = manipulator.getViewMode();
      if (mode == Compound3DManipulator.XYZ_MODE)
        manipulator.setViewMode(Compound3DManipulator.UV_MODE);
      else if (mode == Compound3DManipulator.UV_MODE)
        manipulator.setViewMode(Compound3DManipulator.NPQ_MODE);
      else
        manipulator.setViewMode(Compound3DManipulator.XYZ_MODE);
      theWindow.updateImage();
      return;
    }
    if (e.getKeyCode() == KeyEvent.VK_F1)
    {
      // Enable tooltips.

      tooltipsEnabled = !tooltipsEnabled;
      if (tooltipsEnabled && !tooltipsAdded)
      {
        ViewerCanvas allViews[] = ((MeshEditorWindow) theWindow).getAllViews();
        for (int i = 0; i < allViews.length; i++)
          allViews[i].addEventLink(ToolTipEvent.class, this, "showToolTip");
        tooltipsAdded = true;
      }
      if (!tooltipsEnabled)
        BToolTip.hide();
      return;
    }

    // Handle arrow keys.

    Mesh mesh = (Mesh) controller.getObject().getObject();
    int i, selectDist[] = controller.getSelectionDistance();
    int key = e.getKeyCode();
    double dx, dy;

    // Pressing an arrow key is equivalent to dragging the first selected point by one pixel.

    if (key == KeyPressedEvent.VK_UP)
    {
      dx = 0;
      dy = -1;
    }
    else if (key == KeyPressedEvent.VK_DOWN)
    {
      dx = 0;
      dy = 1;
    }
    else if (key == KeyPressedEvent.VK_LEFT)
    {
      dx = -1;
      dy = 0;
    }
    else if (key == KeyPressedEvent.VK_RIGHT)
    {
      dx = 1;
      dy = 0;
    }
    else
      return;
    e.consume();
    baseVertPos = mesh.getVertexPositions();
    for (i = 0; i < baseVertPos.length && selectDist[i] != 0; i++);
    if (i == baseVertPos.length)
      return;
    if (view.getSnapToGrid())
    {
      double scale = view.getGridSpacing()*view.getScale();
      if (!e.isAltDown())
        scale /= view.getSnapToSubdivisions();
      dx *= scale;
      dy *= scale;
    }
    else if (e.isAltDown())
    {
      dx *= 10;
      dy *= 10;
    }
    Vec3 drag;
    if (e.isControlDown())
      drag = view.getCamera().getCameraCoordinates().getZDirection().times(-dy*0.01);
    else
      drag = view.getCamera().findDragVector(baseVertPos[i], dx, dy);
    theWindow.setUndoRecord(new UndoRecord(theWindow, false, UndoRecord.COPY_VERTEX_POSITIONS, new Object [] {mesh, baseVertPos}));
    transformMesh(Mat4.translation(drag.x, drag.y, drag.z));
    theWindow.updateImage();
  }

  private void showToolTip(ToolTipEvent ev)
  {
    if (!tooltipsEnabled)
      return;
    ViewerCanvas view = (ViewerCanvas) ev.getWidget();
    HandleType type = manipulator.getHandleTypeAtLocation(ev.getPoint(), view, findSelectionBounds(view.getCamera()));
    if (type == Compound3DManipulator.MOVE)
      MOVE_TIP.processEvent(ev);
    else if (type == Compound3DManipulator.ROTATE)
      ROTATE_TIP.processEvent(ev);
    else if (type == Compound3DManipulator.SCALE)
      SCALE_TIP.processEvent(ev);
    else
      BToolTip.hide();
  }
}
TOP

Related Classes of artofillusion.MoveScaleRotateMeshTool

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.