Просмотр исходного кода

Fixed group selection and transform in 2d editor

Ivan Safrin 13 лет назад
Родитель
Сommit
6d258776c5

+ 6 - 0
IDE/Contents/Include/PolycodeScreenEditor.h

@@ -118,6 +118,8 @@ class PolycodeScreenEditorMain : public UIElement {
 		void createParticleRef(ScreenParticleEmitter *target);
 		void createSoundRef(ScreenSound *target);
 		void createEntityRef(ScreenEntity *entity);
+		
+		void getCenterAndSizeForSelected(Vector2 *center, Number *width, Number *height);
 	
 		void handleMouseDown(Vector2 position);
 		void handleMouseMove(Vector2 position);
@@ -216,6 +218,10 @@ class PolycodeScreenEditorMain : public UIElement {
 		
 		Vector2 mouseBase;
 		std::vector<Vector2> baseEntityPositions;
+		std::vector<Vector2> baseEntityScales;
+		std::vector<Number> baseRotateAngles;
+		Vector2 groupCenterPoint;
+		Number groupRoll;
 		Number baseAngle;
 	
 		ScreenShape *placingShape;	

+ 94 - 35
IDE/Contents/Source/PolycodeScreenEditor.cpp

@@ -793,7 +793,31 @@ void PolycodeScreenEditorMain::syncTransformToSelected() {
 		
 		screenTransform->rotation.roll = selectedEntity->getCombinedRoll();
 	} else {
+			
+		Vector2 center;
+		Number width;
+		Number height;
+		getCenterAndSizeForSelected(&center, &width, &height);
+		
+		screenTransform->setPosition(center.x, center.y);
+		screenTransformShape->setShapeSize(width, height);
+		screenTransformShape->setPosition(center);
+		
+		screenTransform->rotation.roll = groupRoll * TODEGREES;
+
+//		screenTransformShape->setShapeSize(selectedEntity->getWidth(),selectedEntity->getHeight());	
+//		Matrix4 final = selectedEntity->getConcatenatedMatrixRelativeTo(baseEntity);
+//		screenTransform->setPosition(final.getPosition());			
+//		screenTransformShape->matrixDirty = false;
+//		screenTransformShape->setTransformByMatrixPure(final);		
+		
+	}
+	
+	screenTransform->rebuildTransformMatrix();
 	
+}
+
+void PolycodeScreenEditorMain::getCenterAndSizeForSelected(Vector2 *center, Number *width, Number *height) {
 		// Calculate corners transformed into base entity space and get center and 
 		// transformed bounding vertices
 		
@@ -838,27 +862,16 @@ void PolycodeScreenEditorMain::syncTransformToSelected() {
 			}						
 		}						
 		
-		Number width = fabs(max.x - min.x);
-		Number height = fabs(max.y - min.y);
-				
-		Vector3 center = Vector3(min.x + (width/2.0), min.y + (height/2.0), 0.0);
-						
-		screenTransform->setPosition(center);
-		screenTransformShape->setShapeSize(width, height);
-		screenTransformShape->setPosition(center);
-					
-//		screenTransformShape->setShapeSize(selectedEntity->getWidth(),selectedEntity->getHeight());	
-//		Matrix4 final = selectedEntity->getConcatenatedMatrixRelativeTo(baseEntity);
-//		screenTransform->setPosition(final.getPosition());			
-//		screenTransformShape->matrixDirty = false;
-//		screenTransformShape->setTransformByMatrixPure(final);		
+		*width = fabs(max.x - min.x);
+		*height = fabs(max.y - min.y);
+
+		center->x = min.x + (*width/2.0);
+		center->y = min.y + (*height/2.0);
+
 		
-	}
-	
-	screenTransform->rebuildTransformMatrix();
-	
 }
 
+
 void PolycodeScreenEditorMain::updateCursor() {
 	switch(mode) {
 		case MODE_SELECT:
@@ -961,35 +974,69 @@ void PolycodeScreenEditorMain::handleMouseMove(Vector2 position) {
 				Vector2 diff = CoreServices::getInstance()->getCore()->getInput()->getMousePosition() - screenTransform->getScreenPosition();
 				diff.Normalize();
 				Number newAngle = atan2(diff.x, diff.y);				
-				selectedEntity->setRotation(baseRotateAngle - (TODEGREES * (newAngle-baseAngle)));
+			
+				if(selectedEntities.size() == 1) {
+					selectedEntities[0]->setRotation(baseRotateAngles[0] - (TODEGREES * (newAngle-baseAngle)));
+				} else {
+				
+					groupRoll = -(newAngle-baseAngle);
+					
+					for(int i=0; i < selectedEntities.size(); i++) {
+						Vector3 v3Center = Vector3(groupCenterPoint.x,groupCenterPoint.y,0.0);
+						
+						Vector3 v3CenterRelative = selectedEntities[i]->getParentEntity()->getConcatenatedMatrixRelativeTo(baseEntity).inverse() * v3Center;	
+						
+						selectedEntities[i]->setRotation(baseRotateAngles[i] - (TODEGREES * (newAngle-baseAngle)));						
+						
+						Number s = sin(newAngle-baseAngle);
+						Number c = cos(newAngle-baseAngle);
+
+						Vector2 p = baseEntityPositions[i];
+						p.x -= v3CenterRelative.x;
+						p.y -= v3CenterRelative.y;
+
+						Number xnew = p.x * c + p.y * s;
+						Number ynew = -p.x * s + p.y * c;
+
+						p.x = xnew + v3CenterRelative.x;
+						p.y = ynew + v3CenterRelative.y;																
+						
+						selectedEntities[i]->setPosition(p.x, p.y);
+					}
+				
+				}
 				syncTransformToSelected();			
 			} else if(scalingY) {				
 				
 				
 				Vector2 trans = CoreServices::getInstance()->getCore()->getInput()->getMousePosition() - mouseBase;
-			
-				Vector3 trans3 = Vector3(trans.x, trans.y, 0.0);
+				for(int i=0; i < selectedEntities.size(); i++) {			
+							
+					Vector3 trans3 = Vector3(trans.x, trans.y, 0.0);
 				
-				Quaternion q;								
-				q.fromAxes(0.0, 0.0, -selectedEntity->getCombinedRoll());
-				trans3 = q.applyTo(trans3);
+					Quaternion q;								
+					q.fromAxes(0.0, 0.0, -selectedEntities[i]->getCombinedRoll());
+					trans3 = q.applyTo(trans3);
 								
-				Number scaleMod = 0.04;								
-				selectedEntity->setScaleY(baseScale.y - (trans3.y * scaleMod));				
+					Number scaleMod = 0.04;								
+					selectedEntities[i]->setScaleY(baseEntityScales[i].y - (trans3.y * scaleMod));
+				}
 				syncTransformToSelected();	
 				
 			} else if(scalingX) {				
 				
 				Vector2 trans = CoreServices::getInstance()->getCore()->getInput()->getMousePosition() - mouseBase;
 			
-				Vector3 trans3 = Vector3(trans.x, trans.y, 0.0);
-				Quaternion q;
+				for(int i=0; i < selectedEntities.size(); i++) {			
+					Vector3 trans3 = Vector3(trans.x, trans.y, 0.0);
+					Quaternion q;
 				
-				q.fromAxes(0.0, 0.0, -selectedEntity->getCombinedRoll());
-				trans3 = q.applyTo(trans3);
+					q.fromAxes(0.0, 0.0, -selectedEntities[i]->getCombinedRoll());
+					trans3 = q.applyTo(trans3);
 								
-				Number scaleMod = 0.04;								
-				selectedEntity->setScaleX(baseScale.x + (trans3.x * scaleMod));				
+					Number scaleMod = 0.04;								
+					selectedEntities[i]->setScaleX(baseEntityScales[i].x + (trans3.x * scaleMod));				
+				}
 				syncTransformToSelected();	
 				
 			}  else if(moving) {
@@ -1416,9 +1463,20 @@ bool PolycodeScreenEditorMain::hasSelected(ScreenEntity *entity) {
 
 void PolycodeScreenEditorMain::resetSelectedEntityTransforms() {
 	baseEntityPositions.clear();
+	baseEntityScales.clear();
+	baseRotateAngles.clear();
+	
 	for(int i=0; i < selectedEntities.size(); i++) {
 		baseEntityPositions.push_back(selectedEntities[i]->getPosition2D());	
+		baseEntityScales.push_back(selectedEntities[i]->getScale2D());
+		baseRotateAngles.push_back(selectedEntities[i]->getRotation());
 	}
+	
+	Number width;
+	Number height;
+	getCenterAndSizeForSelected(&groupCenterPoint, &width, &height);					
+	
+	groupRoll = 0;
 }
 
 void PolycodeScreenEditorMain::selectEntity(ScreenEntity *entity) {
@@ -1670,7 +1728,7 @@ void PolycodeScreenEditorMain::handleEvent(Event *event) {
 	if(event->getDispatcher() == transformScalerY) {
 		if(selectedEntity) {
 			scalingY = true;
-			baseScale = selectedEntity->getScale();
+			resetSelectedEntityTransforms();
 			mouseBase = CoreServices::getInstance()->getCore()->getInput()->getMousePosition();			
 		}
 	}
@@ -1678,7 +1736,7 @@ void PolycodeScreenEditorMain::handleEvent(Event *event) {
 	if(event->getDispatcher() == transformScalerX) {
 		if(selectedEntity) {
 			scalingX = true;
-			baseScale = selectedEntity->getScale();
+			resetSelectedEntityTransforms();
 			mouseBase = CoreServices::getInstance()->getCore()->getInput()->getMousePosition();			
 		}
 	}
@@ -1686,11 +1744,12 @@ void PolycodeScreenEditorMain::handleEvent(Event *event) {
 	if(event->getDispatcher() == transformRotator) {
 		if(selectedEntity) {
 			rotating = true;
-			baseRotateAngle = selectedEntity->getRotation();
+			resetSelectedEntityTransforms();
 			mouseBase = CoreServices::getInstance()->getCore()->getInput()->getMousePosition();
 			
 			Vector2 diff = mouseBase - screenTransform->getScreenPosition();
 			baseAngle = atan2(diff.x, diff.y);
+			groupRoll = -baseAngle;
 		}
 	}