Browse Source

Added transform shortcuts (blender style) to the entity editor, fixed rotation with transform gizmo

Ivan Safrin 12 years ago
parent
commit
96b724862a
2 changed files with 172 additions and 66 deletions
  1. 10 2
      IDE/Contents/Include/TransformGizmo.h
  2. 162 64
      IDE/Contents/Source/TransformGizmo.cpp

+ 10 - 2
IDE/Contents/Include/TransformGizmo.h

@@ -51,12 +51,16 @@ class TransformGizmo : public Entity {
         void updateOrientationForEntity(Entity *entity);
     
         void setTransformPlane(Number x, Number y, Number z, bool forceGlobal = false);
+        void setTransformPlaneFromView();
     
         void setCenterMode(int centerMode);
 		
 		static const int TRANSFORM_MOVE = 0;
 		static const int TRANSFORM_SCALE = 1;
 		static const int TRANSFORM_ROTATE = 2;
+		static const int TRANSFORM_SCALE_VIEW = 3;
+		static const int TRANSFORM_ROTATE_VIEW = 4;
+		static const int TRANSFORM_MOVE_VIEW = 5;
     
         static const int GIZMO_MODE_3D = 0;
 		static const int GIZMO_MODE_2D = 1;
@@ -75,13 +79,14 @@ class TransformGizmo : public Entity {
         int centerMode;
 	
 		std::vector<Entity*> selectedEntities;
-	
+    
 		Scene *targetScene;
 		Camera *targetCamera;
     
 	
 		CoreInput *coreInput;
 		int mode;
+        int previousMode;
 		bool transforming;
 		
 		Vector3 transformConstraint;
@@ -92,9 +97,12 @@ class TransformGizmo : public Entity {
     
         Matrix4 planeMatrix;
 				
+        Vector3 gizmoPoint;
 		Vector3 startingPoint;
 		Number startingAngle;
-					
+    
+        Number scaleAmount;
+				
 		Entity *trasnformDecorators;
 		Entity *scaleDecorators;
 		Entity *transformAndScaleLines;			

+ 162 - 64
IDE/Contents/Source/TransformGizmo.cpp

@@ -325,14 +325,16 @@ TransformGizmo::TransformGizmo(Scene *targetScene, Camera *targetCamera) : Entit
 		
 	transforming = false;
 	mode = TRANSFORM_MOVE;
-	
+    	
 	visible = false;
 	enabled = false;
 	
 	coreInput = CoreServices::getInstance()->getCore()->getInput();
 	coreInput->addEventListener(this, InputEvent::EVENT_MOUSEMOVE);
-	coreInput->addEventListener(this, InputEvent::EVENT_MOUSEUP);	
-
+	coreInput->addEventListener(this, InputEvent::EVENT_MOUSEUP);
+	coreInput->addEventListener(this, InputEvent::EVENT_MOUSEDOWN);
+	coreInput->addEventListener(this, InputEvent::EVENT_KEYDOWN);
+    
 	gizmoMode = GIZMO_MODE_3D;
 	setTransformMode(TRANSFORM_MOVE);
 }
@@ -341,23 +343,24 @@ void TransformGizmo::setTransformOrientation(int orientation) {
     this->orientation = orientation;
 }
 
+void TransformGizmo::setTransformPlaneFromView() {
+    if(gizmoMode == GIZMO_MODE_2D) {
+        setTransformPlane(0.0, 0.0, 1.0, true);
+    } else {
+        Vector3 camVec =  targetCamera->getConcatenatedMatrix().getPosition() - getConcatenatedMatrix().getPosition();
+        camVec.Normalize();
+        setTransformPlane(camVec.x, camVec.y, camVec.z, true);
+    }
+}
+
 void TransformGizmo::setTransformPlane(Number x, Number y, Number z, bool forceGlobal) {
     planeMatrix = getConcatenatedMatrix();
     
     Vector3 localPlane = Vector3(x,y,z);
     localTransformPlane = localPlane;
-    
 	Number planeDistance = 0;
-    
-	if(transformPlane.x > 0) {
-		planeDistance = getPosition().x;
-	} else if(transformPlane.y > 0.0) {
-		planeDistance = getPosition().y;
-	} else if(transformPlane.z > 0.0) {
-		planeDistance = getPosition().z;
-	}
-    
-    if(orientation == ORIENTATION_GLOBAL || forceGlobal) {
+
+    if(forceGlobal) {
         transformPlane = localPlane;
         transformPlaneDistance = planeDistance;
         planeMatrix.identity();
@@ -365,18 +368,23 @@ void TransformGizmo::setTransformPlane(Number x, Number y, Number z, bool forceG
     }
     
     transformPlane = planeMatrix.rotateVector(localPlane);
-    Vector3 planePoint = localPlane * planeDistance;
-    planePoint = planeMatrix.Inverse().transpose() * planePoint;
-    
+    Vector3 planePoint = planeMatrix.getPosition();
     transformPlaneDistance = planePoint.dot(transformPlane);
+    
+	Ray gizmoRay;
+	gizmoRay.origin = 0.0;
+	gizmoRay.direction = transformPlane * -1;
+    
+	gizmoPoint = gizmoRay.planeIntersectPoint(transformPlane, transformPlaneDistance);
+    gizmoPoint = planeMatrix.Inverse() * gizmoPoint;
+    
 }
 
 Vector3 TransformGizmo::getTransformPlanePosition() {
 
 	Ray ray = targetScene->projectRayFromCameraAndViewportCoordinate(targetCamera, coreInput->getMousePosition());
-    
     Vector3 ret = ray.planeIntersectPoint(transformPlane, transformPlaneDistance);
-	return planeMatrix.Inverse() * ret;
+    return ret;
 }
 
 void TransformGizmo::setTransformMode(int newMode) {
@@ -486,13 +494,14 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
 	for(int i=0; i < selectedEntities.size(); i++) {
         
         
-        if(orientation == ORIENTATION_GLOBAL) {
+        if((orientation == ORIENTATION_GLOBAL && mode != TRANSFORM_SCALE_VIEW) || (ORIENTATION_LOCAL && mode == TRANSFORM_MOVE_VIEW)) {
             selectedEntities[i]->Translate(move);
             
             Quaternion q;
             Quaternion currentRotation = selectedEntities[i]->getRotationQuat();
             Vector3 axisVector = transformConstraint;
             axisVector = currentRotation.Inverse().applyTo(axisVector);
+            axisVector.Normalize();
             q.fromAngleAxis(rotate, axisVector);
             
             
@@ -515,7 +524,7 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
                 selectedEntities[i]->setPosition(globalPosition - selectedEntities[i]->getParentEntity()->getConcatenatedMatrix().getPosition());
                 selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
                 
-                selectedEntities[i]->setScale(selectedEntities[i]->getScale() + newScale);
+                selectedEntities[i]->setScale(selectedEntities[i]->getScale() * (Vector3(1.0, 1.0, 1.0)+newScale));
                 
                 if(newScale.length() > 0.0) {
                     Vector3 scalePosition;
@@ -528,7 +537,7 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
                 
             } else {
                 selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
-                selectedEntities[i]->setScale(selectedEntities[i]->getScale() + newScale);
+                selectedEntities[i]->setScale(selectedEntities[i]->getScale() * (Vector3(1.0, 1.0, 1.0)+newScale));
             }
         } else {
             
@@ -539,9 +548,10 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
             Vector3 axisVector = transformConstraint;
             
             // always global in the 2d view
-            if(gizmoMode == GIZMO_MODE_2D) {
+            if(gizmoMode == GIZMO_MODE_2D || mode == TRANSFORM_ROTATE_VIEW) {
                 axisVector = currentRotation.Inverse().applyTo(axisVector);
             }
+            axisVector.Normalize();
             q.fromAngleAxis(rotate, axisVector);
             
             
@@ -556,7 +566,7 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
                 selectedEntities[i]->setPosition(globalPosition - selectedEntities[i]->getParentEntity()->getConcatenatedMatrix().getPosition());
                 selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
                 
-                selectedEntities[i]->setScale(selectedEntities[i]->getScale() + scale);
+                selectedEntities[i]->setScale(selectedEntities[i]->getScale() * (Vector3(1.0, 1.0, 1.0)+scale));
                 
                 if(scale.length() > 0.0) {
                     Vector3 scalePosition;
@@ -569,7 +579,7 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
                 
             } else {
                 selectedEntities[i]->setRotationByQuaternion(currentRotation * q);
-                selectedEntities[i]->setScale(selectedEntities[i]->getScale() + scale);
+                selectedEntities[i]->setScale(selectedEntities[i]->getScale() * (Vector3(1.0, 1.0, 1.0)+scale));
             }
 
             
@@ -581,12 +591,13 @@ void TransformGizmo::transformSelectedEntities(const Vector3 &move, const Vector
 Number TransformGizmo::getTransformPlaneAngle() {
 	
 	Ray gizmoRay;
-	gizmoRay.origin = 0.0;
-	gizmoRay.direction = transformPlane * -1;
+	gizmoRay.origin = getConcatenatedMatrix().getPosition();
+	gizmoRay.direction = localTransformPlane * -1;
 				
 	Vector3 gizmoIntersect = gizmoRay.planeIntersectPoint(transformPlane, transformPlaneDistance);
     gizmoIntersect = planeMatrix.Inverse() * gizmoIntersect;
-	
+	   
+    
 	Ray ray = targetScene->projectRayFromCameraAndViewportCoordinate(targetCamera, coreInput->getMousePosition());	
 	Vector3 mouseIntersect = ray.planeIntersectPoint(transformPlane, transformPlaneDistance);
     mouseIntersect = planeMatrix.Inverse() * mouseIntersect;
@@ -653,7 +664,6 @@ void TransformGizmo::handleEvent(Event *event) {
 			if(event->getEventCode() == InputEvent::EVENT_MOUSEDOWN) {
 				transforming = true;
 				transformConstraint = Vector3(1.0, 0.0, 0.0);
-                
                 if(gizmoMode == GIZMO_MODE_3D) {
                     setTransformPlane(0.0, 1.0, 0.0);
                 } else {
@@ -678,41 +688,129 @@ void TransformGizmo::handleEvent(Event *event) {
 		}
 	}
 	
-	if(event->getDispatcher() == coreInput && transforming) {
-		switch(event->getEventCode()) {
-			case InputEvent::EVENT_MOUSEMOVE:
-			{
-				switch(mode) {
-					case TRANSFORM_MOVE:
-					{
-						Vector3 newPoint = getTransformPlanePosition();
-						transformSelectedEntities((newPoint-startingPoint) * transformConstraint, Vector3(0.0, 0.0, 0.0), 0.0);
-						startingPoint = newPoint;
-					}
-					break;
-					case TRANSFORM_SCALE:
-					{
-						Vector3 newPoint = getTransformPlanePosition();
-						transformSelectedEntities(Vector3(0.0, 0.0, 0.0), ((newPoint-startingPoint) * transformConstraint), 0.0);
-						startingPoint = newPoint;					
-					}
-					break;
-					case TRANSFORM_ROTATE:
-					{
-						Number newAngle = getTransformPlaneAngle();
-						transformSelectedEntities(Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), newAngle - startingAngle);
-						startingAngle = newAngle;						
-					}
-					break;
-				}
-			}
-			break;
-			case InputEvent::EVENT_MOUSEUP:
-			{
-				transforming = false;
-			}
-			break;
-		}
+	if(event->getDispatcher() == coreInput) {
+        
+        if(event->getEventCode() == InputEvent::EVENT_KEYDOWN) {
+            InputEvent *inputEvent = (InputEvent*) event;
+            switch(inputEvent->key) {
+                case KEY_s:
+                {
+                    transforming = true;
+                    previousMode = mode;
+                    mode = TRANSFORM_SCALE_VIEW;
+                    setTransformPlaneFromView();
+                    startingPoint = getTransformPlanePosition();
+                    
+                }
+                break;
+                case KEY_r:
+                {
+                    previousMode = mode;
+                    mode = TRANSFORM_ROTATE_VIEW;
+                    transforming = true;
+                    setTransformPlaneFromView();
+                    transformConstraint = transformPlane;
+                    if(gizmoMode == GIZMO_MODE_2D) {
+                        transformConstraint = transformConstraint * -1.0;
+                    }
+                    startingAngle = getTransformPlaneAngle();
+                }
+                break;
+                case KEY_g:
+                {
+                    previousMode = mode;
+                    mode = TRANSFORM_MOVE_VIEW;
+                    transforming = true;
+                    setTransformPlaneFromView();
+                    startingPoint = getTransformPlanePosition();
+                }
+                break;
+                case KEY_ESCAPE:
+                {
+                    transforming = false;
+                }
+                break;
+            }
+        }
+        
+        if(transforming) {
+            switch(event->getEventCode()) {
+                case InputEvent::EVENT_MOUSEMOVE:
+                {
+                    switch(mode) {
+                        case TRANSFORM_MOVE:
+                        {
+                            Vector3 newPoint = getTransformPlanePosition();
+                            Vector3 diff = (planeMatrix.Inverse() * newPoint) -(planeMatrix.Inverse() * startingPoint);
+                            diff = diff * getCompoundScale();
+                            transformSelectedEntities(transformConstraint * diff, Vector3(0.0, 0.0, 0.0), 0.0);
+                            startingPoint = newPoint;
+                        }
+                        break;
+                        case TRANSFORM_MOVE_VIEW:
+                        {
+                            Vector3 newPoint = getTransformPlanePosition();
+                            Vector3 diff = newPoint - startingPoint;
+                            
+                            transformSelectedEntities(diff, Vector3(0.0, 0.0, 0.0), 0.0);
+                            startingPoint = newPoint;
+                        }
+                        break;
+                        case TRANSFORM_SCALE_VIEW:
+                        {
+                            Vector3 newPoint = getTransformPlanePosition();
+                            
+                            Number scaleMult = 1.0;
+                            if(newPoint.distance(gizmoPoint) < startingPoint.distance(gizmoPoint)) {
+                                scaleMult = -1.0;
+                            }
+                            
+                            transformSelectedEntities(Vector3(0.0, 0.0, 0.0), (Vector3(1.0, 1.0, 1.0) * (newPoint-startingPoint).length() * scaleMult) / getCompoundScale().x, 0.0);
+                            startingPoint = newPoint;
+                        }
+                        break;
+                        case TRANSFORM_ROTATE_VIEW:
+                        {
+                            Number newAngle = getTransformPlaneAngle();
+                            
+                            Vector3 newPoint = planeMatrix.Inverse() *getTransformPlanePosition();
+                            
+                            transformSelectedEntities(Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), newAngle - startingAngle);
+                            startingAngle = newAngle;
+                        }
+                        break;
+                        case TRANSFORM_SCALE:
+                        {
+                            Vector3 newPoint = getTransformPlanePosition();
+                            
+                            Vector3 diff = (planeMatrix.Inverse() * newPoint) -(planeMatrix.Inverse() * startingPoint);
+                            diff = diff * getCompoundScale();
+                            
+                            
+                            transformSelectedEntities(Vector3(0.0, 0.0, 0.0), (diff * transformConstraint) / getCompoundScale().x, 0.0);
+                            startingPoint = newPoint;					
+                        }
+                        break;
+                        case TRANSFORM_ROTATE:
+                        {
+                            Number newAngle = getTransformPlaneAngle();
+                            transformSelectedEntities(Vector3(0.0, 0.0, 0.0), Vector3(0.0, 0.0, 0.0), newAngle - startingAngle);
+                            startingAngle = newAngle;						
+                        }
+                        break;
+                    }
+                }
+                break;
+                case InputEvent::EVENT_MOUSEUP:
+                {
+                    if(mode == TRANSFORM_SCALE_VIEW || mode == TRANSFORM_ROTATE_VIEW) {
+                        mode = previousMode;
+                    }
+                    transforming = false;
+                }
+                break;
+            }
+        }
 	}
 }